blob: 6f1854c5a8c56b0cafed5ad033215b15606a5f6a [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{
Ashish Kumar Dhanotiya19803832018-05-24 19:05:48 +05303600 if(!hdd_ctx || !hdd_ctx->original_channels)
3601 return;
3602
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +05303603 mutex_lock(&hdd_ctx->cache_channel_lock);
Ashish Kumar Dhanotiya95e5bc22018-04-19 17:06:33 +05303604 hdd_ctx->original_channels->num_channels = 0;
3605 vos_mem_free(hdd_ctx->original_channels->channel_info);
3606 hdd_ctx->original_channels->channel_info = NULL;
3607 vos_mem_free(hdd_ctx->original_channels);
3608 hdd_ctx->original_channels = NULL;
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +05303609 mutex_unlock(&hdd_ctx->cache_channel_lock);
3610}
3611
3612/**
3613 * hdd_alloc_chan_cache() - Allocate the memory to cache the channel
3614 * info for the channels received in command SET_DISABLE_CHANNEL_LIST
3615 * @hdd_ctx: Pointer to HDD context
3616 * @num_chan: Number of channels for which memory needs to
3617 * be allocated
3618 *
3619 * Return: 0 on success and error code on failure
3620 */
3621
3622int hdd_alloc_chan_cache(hdd_context_t *hdd_ctx, int num_chan)
3623{
Ashish Kumar Dhanotiya95e5bc22018-04-19 17:06:33 +05303624 hdd_ctx->original_channels =
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +05303625 vos_mem_malloc(sizeof(struct hdd_cache_channels));
Ashish Kumar Dhanotiya95e5bc22018-04-19 17:06:33 +05303626 if (!hdd_ctx->original_channels) {
3627 hddLog(VOS_TRACE_LEVEL_ERROR,
3628 "In %s, VOS_MALLOC_ERR", __func__);
3629 return -EINVAL;
3630 }
3631 hdd_ctx->original_channels->num_channels = num_chan;
3632 hdd_ctx->original_channels->channel_info =
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +05303633 vos_mem_malloc(num_chan *
3634 sizeof(struct hdd_cache_channel_info));
Ashish Kumar Dhanotiya95e5bc22018-04-19 17:06:33 +05303635 if (!hdd_ctx->original_channels->channel_info) {
3636 hddLog(VOS_TRACE_LEVEL_ERROR,
3637 "In %s, VOS_MALLOC_ERR", __func__);
3638 hdd_ctx->original_channels->num_channels = 0;
3639 vos_mem_free(hdd_ctx->original_channels);
3640 hdd_ctx->original_channels = NULL;
3641 return -ENOMEM;
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +05303642 }
3643 return 0;
3644
3645}
3646
3647
3648int hdd_parse_disable_chan_cmd(hdd_adapter_t *adapter, tANI_U8 *ptr)
3649{
3650 v_PVOID_t pvosGCtx = vos_get_global_context(VOS_MODULE_ID_HDD, NULL);
3651 hdd_context_t *hdd_ctx = vos_get_context(VOS_MODULE_ID_HDD, pvosGCtx);
3652 tANI_U8 *param;
Ashish Kumar Dhanotiya95e5bc22018-04-19 17:06:33 +05303653 int j, tempInt, ret = 0, i, num_channels;
3654 int parsed_channels[MAX_CHANNEL];
3655 bool is_command_repeated = false;
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +05303656
3657 if (NULL == pvosGCtx) {
3658 hddLog(VOS_TRACE_LEVEL_FATAL,
3659 "VOS Global Context is NULL");
3660 return -EINVAL;
3661 }
3662
3663 if (NULL == hdd_ctx) {
3664 hddLog(VOS_TRACE_LEVEL_FATAL, "HDD Context is NULL");
3665 return -EINVAL;
3666 }
3667
3668 param = strchr(ptr, ' ');
3669 /*no argument after the command*/
3670 if (NULL == param)
3671 return -EINVAL;
3672
3673 /*no space after the command*/
3674 else if (SPACE_ASCII_VALUE != *param)
3675 return -EINVAL;
3676
3677 param++;
3678
3679 /*removing empty spaces*/
3680 while ((SPACE_ASCII_VALUE == *param) && ('\0' != *param))
3681 param++;
3682
3683 /*no argument followed by spaces*/
3684 if ('\0' == *param)
3685 return -EINVAL;
3686
3687 /*getting the first argument ie the number of channels*/
3688 if (sscanf(param, "%d ", &tempInt) != 1) {
3689 hddLog(VOS_TRACE_LEVEL_ERROR,
3690 "%s: Cannot get number of channels from input",
3691 __func__);
3692 return -EINVAL;
3693 }
3694
3695 if (tempInt < 0 || tempInt > MAX_CHANNEL) {
3696 hddLog(VOS_TRACE_LEVEL_ERROR,
3697 "%s: Invalid Number of channel received", __func__);
3698 return -EINVAL;
3699 }
3700
3701 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
3702 "%s: Number of channel to disable are: %d",
3703 __func__, tempInt);
3704
3705 if (!tempInt) {
3706 if (!wlan_hdd_restore_channels(hdd_ctx)) {
3707 /*
3708 * Free the cache channels only when the command is
3709 * received with num channels as 0
3710 */
3711 wlan_hdd_free_cache_channels(hdd_ctx);
3712 }
3713 return 0;
3714 }
3715
3716 mutex_lock(&hdd_ctx->cache_channel_lock);
Ashish Kumar Dhanotiya95e5bc22018-04-19 17:06:33 +05303717 if (!hdd_ctx->original_channels) {
3718 if (hdd_alloc_chan_cache(hdd_ctx, tempInt)) {
3719 ret = -ENOMEM;
3720 goto mem_alloc_failed;
3721 }
3722 } else if (hdd_ctx->original_channels->num_channels != tempInt) {
3723 hddLog(VOS_TRACE_LEVEL_ERROR,
3724 "%s, Invalid No of channel provided in the list",
3725 __func__);
3726 ret = -EINVAL;
3727 is_command_repeated = true;
3728 goto parse_failed;
3729 } else {
3730 is_command_repeated = true;
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +05303731 }
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +05303732
Ashish Kumar Dhanotiya95e5bc22018-04-19 17:06:33 +05303733 num_channels = tempInt;
3734
3735 for (j = 0; j < num_channels; j++) {
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +05303736 /*
3737 * param pointing to the beginning of first space
3738 * after number of channels
3739 */
3740 param = strpbrk(param, " ");
3741 /*no channel list after the number of channels argument*/
3742 if (NULL == param) {
3743 hddLog(VOS_TRACE_LEVEL_ERROR,
3744 "%s, Invalid No of channel provided in the list",
3745 __func__);
3746 ret = -EINVAL;
Ashish Kumar Dhanotiya95e5bc22018-04-19 17:06:33 +05303747 goto parse_failed;
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +05303748 }
3749
3750 param++;
3751
3752 /*removing empty space*/
3753 while ((SPACE_ASCII_VALUE == *param) && ('\0' != *param))
3754 param++;
3755
3756 if ('\0' == *param) {
3757 hddLog(VOS_TRACE_LEVEL_ERROR,
3758 "%s, No channel is provided in the list",
3759 __func__);
3760 ret = -EINVAL;
Ashish Kumar Dhanotiya95e5bc22018-04-19 17:06:33 +05303761 goto parse_failed;
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +05303762
3763 }
3764
3765 if (sscanf(param, "%d ", &tempInt) != 1) {
3766 hddLog(VOS_TRACE_LEVEL_ERROR,
3767 "%s: Cannot read channel number",
3768 __func__);
3769 ret = -EINVAL;
Ashish Kumar Dhanotiya95e5bc22018-04-19 17:06:33 +05303770 goto parse_failed;
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +05303771
3772 }
3773
3774 if (!IS_CHANNEL_VALID(tempInt)) {
3775 hddLog(VOS_TRACE_LEVEL_ERROR,
3776 "%s: Invalid channel number received",
3777 __func__);
3778 ret = -EINVAL;
Ashish Kumar Dhanotiya95e5bc22018-04-19 17:06:33 +05303779 goto parse_failed;
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +05303780
3781 }
3782
3783 hddLog(VOS_TRACE_LEVEL_INFO, "%s: channel[%d] = %d", __func__,
3784 j, tempInt);
Ashish Kumar Dhanotiya95e5bc22018-04-19 17:06:33 +05303785
3786 parsed_channels[j] = tempInt;
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +05303787 }
3788
3789 /*extra arguments check*/
3790 param = strchr(param, ' ');
3791 if (NULL != param) {
3792 while ((SPACE_ASCII_VALUE == *param) && ('\0' != *param))
3793 param++;
3794
3795 if ('\0' != *param) {
3796 hddLog(VOS_TRACE_LEVEL_ERROR,
3797 "%s: Invalid argument received", __func__);
3798 ret = -EINVAL;
Ashish Kumar Dhanotiya95e5bc22018-04-19 17:06:33 +05303799 goto parse_failed;
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +05303800 }
3801 }
3802
Ashish Kumar Dhanotiya95e5bc22018-04-19 17:06:33 +05303803 /*
3804 * If command is received first time, cache the channels to
3805 * be disabled else compare the channels received in the
3806 * command with the cached channels, if channel list matches
3807 * return success otherewise return failure.
3808 */
3809 if (!is_command_repeated)
3810 for (j = 0; j < num_channels; j++)
3811 hdd_ctx->original_channels->
3812 channel_info[j].channel_num =
3813 parsed_channels[j];
3814 else {
3815 for (i = 0; i < num_channels; i++) {
3816 for (j = 0; j < num_channels; j++)
3817 if (hdd_ctx->original_channels->
3818 channel_info[i].channel_num ==
3819 parsed_channels[j])
3820 break;
3821 if (j == num_channels) {
3822 ret = -EINVAL;
3823 goto parse_failed;
3824 }
3825 }
3826 ret = 0;
3827 }
3828
3829mem_alloc_failed:
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +05303830 mutex_unlock(&hdd_ctx->cache_channel_lock);
3831 EXIT();
3832
3833 return ret;
Ashish Kumar Dhanotiya95e5bc22018-04-19 17:06:33 +05303834
3835parse_failed:
3836 mutex_unlock(&hdd_ctx->cache_channel_lock);
3837 if (!is_command_repeated)
3838 wlan_hdd_free_cache_channels(hdd_ctx);
3839 EXIT();
3840 return ret;
3841
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +05303842}
3843
Hanumanth Reddy Pothula8ae38bb2018-03-07 18:59:30 +05303844int hdd_get_disable_ch_list(hdd_context_t *hdd_ctx, tANI_U8 *buf,
Ashish Kumar Dhanotiya95e5bc22018-04-19 17:06:33 +05303845 uint32_t buf_len)
Hanumanth Reddy Pothula8ae38bb2018-03-07 18:59:30 +05303846{
3847 struct hdd_cache_channel_info *ch_list;
3848 unsigned char i, num_ch;
3849 int len = 0;
3850
3851 mutex_lock(&hdd_ctx->cache_channel_lock);
Ashish Kumar Dhanotiya95e5bc22018-04-19 17:06:33 +05303852 if (hdd_ctx->original_channels &&
3853 hdd_ctx->original_channels->num_channels &&
3854 hdd_ctx->original_channels->channel_info) {
3855 num_ch = hdd_ctx->original_channels->num_channels;
Hanumanth Reddy Pothula8ae38bb2018-03-07 18:59:30 +05303856
3857 len = scnprintf(buf, buf_len, "%s %hhu",
3858 "GET_DISABLE_CHANNEL_LIST", num_ch);
3859
Ashish Kumar Dhanotiya95e5bc22018-04-19 17:06:33 +05303860 ch_list = hdd_ctx->original_channels->channel_info;
Hanumanth Reddy Pothula8ae38bb2018-03-07 18:59:30 +05303861
Ashish Kumar Dhanotiya95e5bc22018-04-19 17:06:33 +05303862 for (i = 0; (i < num_ch) && (len < buf_len-1); i++) {
Hanumanth Reddy Pothula8ae38bb2018-03-07 18:59:30 +05303863 len += scnprintf(buf + len, buf_len - len,
3864 " %d", ch_list[i].channel_num);
3865 }
3866 }
3867 mutex_unlock(&hdd_ctx->cache_channel_lock);
3868
3869 return len;
3870}
3871
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07003872static int hdd_driver_command(hdd_adapter_t *pAdapter,
3873 hdd_priv_data_t *ppriv_data)
Jeff Johnson295189b2012-06-20 16:38:30 -07003874{
Jeff Johnson295189b2012-06-20 16:38:30 -07003875 hdd_priv_data_t priv_data;
3876 tANI_U8 *command = NULL;
Kaushik, Sushant96122442014-10-21 16:40:18 +05303877 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
3878 hdd_scaninfo_t *pScanInfo = NULL;
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07003879 int ret = 0;
Kaushik, Sushant96122442014-10-21 16:40:18 +05303880 int status;
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05303881#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
3882 struct cfg80211_mgmt_tx_params params;
3883#endif
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303884
3885 ENTER();
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07003886 /*
3887 * Note that valid pointers are provided by caller
3888 */
Jeff Johnson295189b2012-06-20 16:38:30 -07003889
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07003890 /* copy to local struct to avoid numerous changes to legacy code */
3891 priv_data = *ppriv_data;
Jeff Johnson295189b2012-06-20 16:38:30 -07003892
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07003893 if (priv_data.total_len <= 0 ||
3894 priv_data.total_len > WLAN_PRIV_DATA_MAX_LEN)
Sameer Thalappil8ef3a0e2013-04-05 14:36:04 -07003895 {
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07003896 hddLog(VOS_TRACE_LEVEL_WARN,
3897 "%s:invalid priv_data.total_len(%d)!!!", __func__,
3898 priv_data.total_len);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07003899 ret = -EINVAL;
3900 goto exit;
3901 }
Kaushik, Sushant96122442014-10-21 16:40:18 +05303902 status = wlan_hdd_validate_context(pHddCtx);
3903 if (0 != status)
3904 {
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303905 ret = -EINVAL;
3906 goto exit;
Kaushik, Sushant96122442014-10-21 16:40:18 +05303907 }
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07003908 /* Allocate +1 for '\0' */
3909 command = kmalloc(priv_data.total_len + 1, GFP_KERNEL);
Jeff Johnson295189b2012-06-20 16:38:30 -07003910 if (!command)
3911 {
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07003912 hddLog(VOS_TRACE_LEVEL_ERROR,
3913 "%s: failed to allocate memory", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07003914 ret = -ENOMEM;
3915 goto exit;
3916 }
3917
3918 if (copy_from_user(command, priv_data.buf, priv_data.total_len))
3919 {
3920 ret = -EFAULT;
3921 goto exit;
3922 }
3923
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07003924 /* Make sure the command is NUL-terminated */
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07003925 command[priv_data.total_len] = '\0';
3926
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07003927 /* at one time the following block of code was conditional. braces
3928 * have been retained to avoid re-indenting the legacy code
3929 */
Jeff Johnson295189b2012-06-20 16:38:30 -07003930 {
3931 hdd_context_t *pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
3932
3933 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudif9bdd4e2012-10-30 18:05:03 -07003934 "%s: Received %s cmd from Wi-Fi GUI***", __func__, command);
Jeff Johnson295189b2012-06-20 16:38:30 -07003935
3936 if (strncmp(command, "P2P_DEV_ADDR", 12) == 0 )
3937 {
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05303938 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
3939 TRACE_CODE_HDD_P2P_DEV_ADDR_IOCTL,
3940 pAdapter->sessionId, (unsigned)
3941 (*(pHddCtx->p2pDeviceAddress.bytes+2)<<24 |
3942 *(pHddCtx->p2pDeviceAddress.bytes+3)<<16 |
3943 *(pHddCtx->p2pDeviceAddress.bytes+4)<<8 |
3944 *(pHddCtx->p2pDeviceAddress.bytes+5))));
Jeff Johnson295189b2012-06-20 16:38:30 -07003945 if (copy_to_user(priv_data.buf, pHddCtx->p2pDeviceAddress.bytes,
3946 sizeof(tSirMacAddr)))
3947 {
3948 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08003949 "%s: failed to copy data to user buffer", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07003950 ret = -EFAULT;
3951 }
3952 }
Amar Singhal0974e402013-02-12 14:27:46 -08003953 else if(strncmp(command, "SETBAND", 7) == 0)
Jeff Johnson295189b2012-06-20 16:38:30 -07003954 {
Amar Singhal0974e402013-02-12 14:27:46 -08003955 tANI_U8 *ptr = command ;
Srinivas Girigowdade697412013-02-14 16:31:48 -08003956
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05303957 ret = hdd_drv_cmd_validate(command, 7);
3958 if (ret)
3959 goto exit;
3960
Jeff Johnson295189b2012-06-20 16:38:30 -07003961 /* Change band request received */
Srinivas Girigowdade697412013-02-14 16:31:48 -08003962
3963 /* First 8 bytes will have "SETBAND " and
Jeff Johnson295189b2012-06-20 16:38:30 -07003964 * 9 byte will have band setting value */
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07003965 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Amar Singhal0974e402013-02-12 14:27:46 -08003966 "%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 +05303967 if(VOS_FTM_MODE != hdd_get_conparam())
3968 {
3969 /* Change band request received */
3970 ret = hdd_setBand_helper(pAdapter->dev, ptr);
3971 if(ret < 0)
3972 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
3973 "%s: failed to set band ret=%d", __func__, ret);
3974 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08003975 }
Kiet Lamf040f472013-11-20 21:15:23 +05303976 else if(strncmp(command, "SETWMMPS", 8) == 0)
3977 {
3978 tANI_U8 *ptr = command;
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05303979
3980 ret = hdd_drv_cmd_validate(command, 8);
3981 if (ret)
3982 goto exit;
3983
Kiet Lamf040f472013-11-20 21:15:23 +05303984 ret = hdd_wmmps_helper(pAdapter, ptr);
3985 }
Agarwal Ashishef54a182014-12-16 15:07:31 +05303986
3987 else if(strncmp(command, "TDLSSCAN", 8) == 0)
3988 {
3989 tANI_U8 *ptr = command;
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05303990
3991 ret = hdd_drv_cmd_validate(command, 8);
3992 if (ret)
3993 goto exit;
3994
Agarwal Ashishef54a182014-12-16 15:07:31 +05303995 ret = hdd_set_tdls_scan_type(pAdapter, ptr);
3996 }
3997
Jeff Johnson32d95a32012-09-10 13:15:23 -07003998 else if ( strncasecmp(command, "COUNTRY", 7) == 0 )
3999 {
4000 char *country_code;
4001
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05304002 ret = hdd_drv_cmd_validate(command, 7);
4003 if (ret)
4004 goto exit;
4005
Jeff Johnson32d95a32012-09-10 13:15:23 -07004006 country_code = command + 8;
Tushnim Bhattacharyya9cdf6082013-04-21 16:33:30 -07004007
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07004008 INIT_COMPLETION(pAdapter->change_country_code);
Tushnim Bhattacharyya9cdf6082013-04-21 16:33:30 -07004009 hdd_checkandupdate_dfssetting(pAdapter, country_code);
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -07004010#ifndef CONFIG_ENABLE_LINUX_REG
Gopichand Nakkaladacbcb52013-04-18 16:41:54 +05304011 hdd_checkandupdate_phymode(pAdapter, country_code);
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -07004012#endif
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07004013 ret = (int)sme_ChangeCountryCode(pHddCtx->hHal,
4014 (void *)(tSmeChangeCountryCallback)
4015 wlan_hdd_change_country_code_callback,
Abhishek Singha306a442013-11-07 18:39:01 +05304016 country_code, pAdapter, pHddCtx->pvosContext, eSIR_TRUE, eSIR_TRUE);
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07004017 if (eHAL_STATUS_SUCCESS == ret)
4018 {
4019 ret = wait_for_completion_interruptible_timeout(
4020 &pAdapter->change_country_code,
4021 msecs_to_jiffies(WLAN_WAIT_TIME_COUNTRY));
4022 if (0 >= ret)
4023 {
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07004024 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: SME while setting country code timed out %d",
c_hpothu6ff1c3c2013-10-01 19:01:57 +05304025 __func__, ret);
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07004026 }
4027 }
4028 else
Jeff Johnson32d95a32012-09-10 13:15:23 -07004029 {
4030 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07004031 "%s: SME Change Country code fail ret=%d", __func__, ret);
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07004032 ret = -EINVAL;
Jeff Johnson32d95a32012-09-10 13:15:23 -07004033 }
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07004034
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07004035 }
4036 /*
4037 command should be a string having format
4038 SET_SAP_CHANNEL_LIST <num of channels> <the channels seperated by spaces>
4039 */
Amar Singhal0974e402013-02-12 14:27:46 -08004040 else if(strncmp(command, "SET_SAP_CHANNEL_LIST", 20) == 0)
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07004041 {
Amar Singhal0974e402013-02-12 14:27:46 -08004042 tANI_U8 *ptr = command;
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07004043
4044 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004045 " Received Command to Set Preferred Channels for SAP in %s", __func__);
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07004046
Mahesh Kumar Kalikot Veetil2aad8d82013-02-07 12:31:28 -08004047 ret = sapSetPreferredChannel(ptr);
Jeff Johnson32d95a32012-09-10 13:15:23 -07004048 }
Sourav Mohapatra2416e0e2018-03-05 18:44:21 +05304049
4050 else if (strncmp(command, "VOWIFIMODE", 10) == 0)
4051 {
4052 tANI_U8 *ptr;
4053
4054 ret = hdd_drv_cmd_validate(command, 10);
4055 if (ret)
4056 goto exit;
4057
4058 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4059 "Received Command for VOWIFI mode in %s", __func__);
4060
4061 ptr = (tANI_U8*)command + 11;
4062 hdd_set_vowifi_mode(pHddCtx, *ptr - '0');
4063 }
4064
Sameer Thalappil45931fb2013-02-01 11:18:05 -08004065 else if(strncmp(command, "SETSUSPENDMODE", 14) == 0)
4066 {
4067 int suspend = 0;
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05304068 tANI_U8 *ptr;
4069
4070 ret = hdd_drv_cmd_validate(command, 14);
4071 if (ret)
4072 goto exit;
4073
4074 ptr = (tANI_U8*)command + 15;
Sameer Thalappil45931fb2013-02-01 11:18:05 -08004075
4076 suspend = *ptr - '0';
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05304077 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
4078 TRACE_CODE_HDD_SETSUSPENDMODE_IOCTL,
4079 pAdapter->sessionId, suspend));
Sameer Thalappil45931fb2013-02-01 11:18:05 -08004080 hdd_set_wlan_suspend_mode(suspend);
4081 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08004082#ifdef WLAN_FEATURE_NEIGHBOR_ROAMING
4083 else if (strncmp(command, "SETROAMTRIGGER", 14) == 0)
4084 {
4085 tANI_U8 *value = command;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07004086 tANI_S8 rssi = 0;
Srinivas Girigowdade697412013-02-14 16:31:48 -08004087 tANI_U8 lookUpThreshold = CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_DEFAULT;
4088 eHalStatus status = eHAL_STATUS_SUCCESS;
4089
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05304090 ret = hdd_drv_cmd_validate(command, 14);
4091 if (ret)
4092 goto exit;
4093
Srinivas Girigowdade697412013-02-14 16:31:48 -08004094 /* Move pointer to ahead of SETROAMTRIGGER<delimiter> */
4095 value = value + 15;
4096
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07004097 /* Convert the value from ascii to integer */
4098 ret = kstrtos8(value, 10, &rssi);
4099 if (ret < 0)
4100 {
4101 /* If the input value is greater than max value of datatype, then also
4102 kstrtou8 fails */
4103 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4104 "%s: kstrtou8 failed Input value may be out of range[%d - %d]",
Srinivas Girigowdafa7157d2013-10-31 10:14:22 -07004105 __func__,
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07004106 CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MIN,
4107 CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MAX);
4108 ret = -EINVAL;
4109 goto exit;
4110 }
4111
Srinivas Girigowdade697412013-02-14 16:31:48 -08004112 lookUpThreshold = abs(rssi);
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07004113
Srinivas Girigowdade697412013-02-14 16:31:48 -08004114 if ((lookUpThreshold < CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MIN) ||
4115 (lookUpThreshold > CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MAX))
4116 {
4117 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4118 "Neighbor lookup threshold value %d is out of range"
4119 " (Min: %d Max: %d)", lookUpThreshold,
4120 CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MIN,
4121 CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MAX);
4122 ret = -EINVAL;
4123 goto exit;
4124 }
4125
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05304126 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
4127 TRACE_CODE_HDD_SETROAMTRIGGER_IOCTL,
4128 pAdapter->sessionId, lookUpThreshold));
Srinivas Girigowdade697412013-02-14 16:31:48 -08004129 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4130 "%s: Received Command to Set Roam trigger"
4131 " (Neighbor lookup threshold) = %d", __func__, lookUpThreshold);
4132
4133 pHddCtx->cfg_ini->nNeighborLookupRssiThreshold = lookUpThreshold;
4134 status = sme_setNeighborLookupRssiThreshold((tHalHandle)(pHddCtx->hHal), lookUpThreshold);
4135 if (eHAL_STATUS_SUCCESS != status)
4136 {
4137 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4138 "%s: Failed to set roam trigger, try again", __func__);
4139 ret = -EPERM;
4140 goto exit;
4141 }
4142
4143 /* Set Reassoc threshold to (lookup rssi threshold + 5 dBm) */
mukul sharmad6e1fdd2014-06-23 19:19:09 +05304144 pHddCtx->cfg_ini->nNeighborReassocRssiThreshold = lookUpThreshold + 5;
Srinivas Girigowdade697412013-02-14 16:31:48 -08004145 sme_setNeighborReassocRssiThreshold((tHalHandle)(pHddCtx->hHal), lookUpThreshold + 5);
4146 }
4147 else if (strncmp(command, "GETROAMTRIGGER", 14) == 0)
4148 {
4149 tANI_U8 lookUpThreshold = sme_getNeighborLookupRssiThreshold((tHalHandle)(pHddCtx->hHal));
4150 int rssi = (-1) * lookUpThreshold;
4151 char extra[32];
4152 tANI_U8 len = 0;
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05304153 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
4154 TRACE_CODE_HDD_GETROAMTRIGGER_IOCTL,
4155 pAdapter->sessionId, lookUpThreshold));
Sameer Thalappilb0a30232013-09-27 15:37:48 -07004156 len = scnprintf(extra, sizeof(extra), "%s %d", command, rssi);
Srinivas Girigowda91719232015-07-13 15:10:10 +05304157 len = VOS_MIN(priv_data.total_len, len + 1);
4158 if (copy_to_user(priv_data.buf, &extra, len))
Srinivas Girigowdade697412013-02-14 16:31:48 -08004159 {
4160 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4161 "%s: failed to copy data to user buffer", __func__);
4162 ret = -EFAULT;
4163 goto exit;
4164 }
4165 }
4166 else if (strncmp(command, "SETROAMSCANPERIOD", 17) == 0)
4167 {
4168 tANI_U8 *value = command;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07004169 tANI_U8 roamScanPeriod = 0;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004170 tANI_U16 neighborEmptyScanRefreshPeriod = CFG_EMPTY_SCAN_REFRESH_PERIOD_DEFAULT;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07004171
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05304172 ret = hdd_drv_cmd_validate(command, 17);
4173 if (ret)
4174 goto exit;
4175
Srinivas Girigowdade697412013-02-14 16:31:48 -08004176 /* input refresh period is in terms of seconds */
4177 /* Move pointer to ahead of SETROAMSCANPERIOD<delimiter> */
4178 value = value + 18;
4179 /* Convert the value from ascii to integer */
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07004180 ret = kstrtou8(value, 10, &roamScanPeriod);
Srinivas Girigowdade697412013-02-14 16:31:48 -08004181 if (ret < 0)
4182 {
4183 /* If the input value is greater than max value of datatype, then also
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07004184 kstrtou8 fails */
Srinivas Girigowdade697412013-02-14 16:31:48 -08004185 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07004186 "%s: kstrtou8 failed Input value may be out of range[%d - %d]",
Srinivas Girigowdade697412013-02-14 16:31:48 -08004187 __func__,
Srinivas Girigowdab8edd1e2013-03-19 11:42:08 -07004188 (CFG_EMPTY_SCAN_REFRESH_PERIOD_MIN/1000),
4189 (CFG_EMPTY_SCAN_REFRESH_PERIOD_MAX/1000));
Srinivas Girigowdade697412013-02-14 16:31:48 -08004190 ret = -EINVAL;
4191 goto exit;
4192 }
4193
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07004194 if ((roamScanPeriod < (CFG_EMPTY_SCAN_REFRESH_PERIOD_MIN/1000)) ||
4195 (roamScanPeriod > (CFG_EMPTY_SCAN_REFRESH_PERIOD_MAX/1000)))
Srinivas Girigowdade697412013-02-14 16:31:48 -08004196 {
4197 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07004198 "Roam scan period value %d is out of range"
4199 " (Min: %d Max: %d)", roamScanPeriod,
Srinivas Girigowdab8edd1e2013-03-19 11:42:08 -07004200 (CFG_EMPTY_SCAN_REFRESH_PERIOD_MIN/1000),
4201 (CFG_EMPTY_SCAN_REFRESH_PERIOD_MAX/1000));
Srinivas Girigowdade697412013-02-14 16:31:48 -08004202 ret = -EINVAL;
4203 goto exit;
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05304204 }
4205 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
4206 TRACE_CODE_HDD_SETROAMSCANPERIOD_IOCTL,
4207 pAdapter->sessionId, roamScanPeriod));
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07004208 neighborEmptyScanRefreshPeriod = roamScanPeriod * 1000;
Srinivas Girigowdade697412013-02-14 16:31:48 -08004209
4210 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4211 "%s: Received Command to Set roam scan period"
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07004212 " (Empty Scan refresh period) = %d", __func__, roamScanPeriod);
Srinivas Girigowdade697412013-02-14 16:31:48 -08004213
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004214 pHddCtx->cfg_ini->nEmptyScanRefreshPeriod = neighborEmptyScanRefreshPeriod;
4215 sme_UpdateEmptyScanRefreshPeriod((tHalHandle)(pHddCtx->hHal), neighborEmptyScanRefreshPeriod);
Srinivas Girigowdade697412013-02-14 16:31:48 -08004216 }
4217 else if (strncmp(command, "GETROAMSCANPERIOD", 17) == 0)
4218 {
4219 tANI_U16 nEmptyScanRefreshPeriod = sme_getEmptyScanRefreshPeriod((tHalHandle)(pHddCtx->hHal));
4220 char extra[32];
4221 tANI_U8 len = 0;
4222
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05304223 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
4224 TRACE_CODE_HDD_GETROAMSCANPERIOD_IOCTL,
4225 pAdapter->sessionId, nEmptyScanRefreshPeriod));
Sameer Thalappilb0a30232013-09-27 15:37:48 -07004226 len = scnprintf(extra, sizeof(extra), "%s %d",
4227 "GETROAMSCANPERIOD", (nEmptyScanRefreshPeriod/1000));
Srinivas Girigowdade697412013-02-14 16:31:48 -08004228 /* Returned value is in units of seconds */
Ratnam Rachuria72ba112015-07-17 13:27:03 +05304229 len = VOS_MIN(priv_data.total_len, len + 1);
4230 if (copy_to_user(priv_data.buf, &extra, len)) {
Srinivas Girigowdade697412013-02-14 16:31:48 -08004231 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4232 "%s: failed to copy data to user buffer", __func__);
4233 ret = -EFAULT;
4234 goto exit;
4235 }
4236 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004237 else if (strncmp(command, "SETROAMSCANREFRESHPERIOD", 24) == 0)
4238 {
4239 tANI_U8 *value = command;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07004240 tANI_U8 roamScanRefreshPeriod = 0;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004241 tANI_U16 neighborScanRefreshPeriod = CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_DEFAULT;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07004242
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05304243 ret = hdd_drv_cmd_validate(command, 24);
4244 if (ret)
4245 goto exit;
4246
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004247 /* input refresh period is in terms of seconds */
4248 /* Move pointer to ahead of SETROAMSCANREFRESHPERIOD<delimiter> */
4249 value = value + 25;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07004250
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004251 /* Convert the value from ascii to integer */
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07004252 ret = kstrtou8(value, 10, &roamScanRefreshPeriod);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004253 if (ret < 0)
4254 {
4255 /* If the input value is greater than max value of datatype, then also
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07004256 kstrtou8 fails */
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004257 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07004258 "%s: kstrtou8 failed Input value may be out of range[%d - %d]",
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004259 __func__,
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004260 (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MIN/1000),
4261 (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MAX/1000));
4262 ret = -EINVAL;
4263 goto exit;
4264 }
4265
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07004266 if ((roamScanRefreshPeriod < (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MIN/1000)) ||
4267 (roamScanRefreshPeriod > (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MAX/1000)))
4268 {
4269 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4270 "Neighbor scan results refresh period value %d is out of range"
4271 " (Min: %d Max: %d)", roamScanRefreshPeriod,
4272 (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MIN/1000),
4273 (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MAX/1000));
4274 ret = -EINVAL;
4275 goto exit;
4276 }
4277 neighborScanRefreshPeriod = roamScanRefreshPeriod * 1000;
4278
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004279 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4280 "%s: Received Command to Set roam scan refresh period"
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07004281 " (Scan refresh period) = %d", __func__, roamScanRefreshPeriod);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004282
4283 pHddCtx->cfg_ini->nNeighborResultsRefreshPeriod = neighborScanRefreshPeriod;
4284 sme_setNeighborScanRefreshPeriod((tHalHandle)(pHddCtx->hHal), neighborScanRefreshPeriod);
4285 }
4286 else if (strncmp(command, "GETROAMSCANREFRESHPERIOD", 24) == 0)
4287 {
4288 tANI_U16 value = sme_getNeighborScanRefreshPeriod((tHalHandle)(pHddCtx->hHal));
4289 char extra[32];
4290 tANI_U8 len = 0;
4291
Sameer Thalappilb0a30232013-09-27 15:37:48 -07004292 len = scnprintf(extra, sizeof(extra), "%s %d",
4293 "GETROAMSCANREFRESHPERIOD", (value/1000));
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004294 /* Returned value is in units of seconds */
Ratnam Rachuri2c9d6702015-07-17 13:25:16 +05304295 len = VOS_MIN(priv_data.total_len, len + 1);
4296 if (copy_to_user(priv_data.buf, &extra, len)) {
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004297 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4298 "%s: failed to copy data to user buffer", __func__);
4299 ret = -EFAULT;
4300 goto exit;
4301 }
4302 }
Varun Reddy Yeturu6d99ac82013-05-08 14:15:35 -07004303#ifdef FEATURE_WLAN_LFR
4304 /* SETROAMMODE */
4305 else if (strncmp(command, "SETROAMMODE", SIZE_OF_SETROAMMODE) == 0)
4306 {
4307 tANI_U8 *value = command;
4308 tANI_BOOLEAN roamMode = CFG_LFR_FEATURE_ENABLED_DEFAULT;
4309
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +05304310 if (pHddCtx->concurrency_mode == VOS_STA_MON) {
4311 hddLog(LOGE,
4312 FL("Roaming is always disabled in STA + MON concurrency"));
4313 ret = -EINVAL;
4314 goto exit;
4315 }
4316
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05304317 ret = hdd_drv_cmd_validate(command, SIZE_OF_SETROAMMODE);
4318 if (ret)
4319 goto exit;
4320
Varun Reddy Yeturu6d99ac82013-05-08 14:15:35 -07004321 /* Move pointer to ahead of SETROAMMODE<delimiter> */
4322 value = value + SIZE_OF_SETROAMMODE + 1;
4323
4324 /* Convert the value from ascii to integer */
4325 ret = kstrtou8(value, SIZE_OF_SETROAMMODE, &roamMode);
4326 if (ret < 0)
4327 {
4328 /* If the input value is greater than max value of datatype, then also
4329 kstrtou8 fails */
4330 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4331 "%s: kstrtou8 failed range [%d - %d]", __func__,
4332 CFG_LFR_FEATURE_ENABLED_MIN,
4333 CFG_LFR_FEATURE_ENABLED_MAX);
4334 ret = -EINVAL;
4335 goto exit;
4336 }
4337 if ((roamMode < CFG_LFR_FEATURE_ENABLED_MIN) ||
4338 (roamMode > CFG_LFR_FEATURE_ENABLED_MAX))
4339 {
4340 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4341 "Roam Mode value %d is out of range"
4342 " (Min: %d Max: %d)", roamMode,
4343 CFG_LFR_FEATURE_ENABLED_MIN,
4344 CFG_LFR_FEATURE_ENABLED_MAX);
4345 ret = -EINVAL;
4346 goto exit;
4347 }
4348
4349 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4350 "%s: Received Command to Set Roam Mode = %d", __func__, roamMode);
4351 /*
4352 * Note that
4353 * SETROAMMODE 0 is to enable LFR while
4354 * SETROAMMODE 1 is to disable LFR, but
4355 * NotifyIsFastRoamIniFeatureEnabled 0/1 is to enable/disable.
4356 * So, we have to invert the value to call sme_UpdateIsFastRoamIniFeatureEnabled.
4357 */
4358 if (CFG_LFR_FEATURE_ENABLED_MIN == roamMode)
4359 roamMode = CFG_LFR_FEATURE_ENABLED_MAX; /* Roam enable */
4360 else
4361 roamMode = CFG_LFR_FEATURE_ENABLED_MIN; /* Roam disable */
4362
4363 pHddCtx->cfg_ini->isFastRoamIniFeatureEnabled = roamMode;
4364 sme_UpdateIsFastRoamIniFeatureEnabled((tHalHandle)(pHddCtx->hHal), roamMode);
4365 }
4366 /* GETROAMMODE */
Mahesh A Saptasagarec7d1092015-04-02 13:41:34 +05304367 else if (strncmp(command, "GETROAMMODE", SIZE_OF_GETROAMMODE) == 0)
Varun Reddy Yeturu6d99ac82013-05-08 14:15:35 -07004368 {
4369 tANI_BOOLEAN roamMode = sme_getIsLfrFeatureEnabled((tHalHandle)(pHddCtx->hHal));
4370 char extra[32];
4371 tANI_U8 len = 0;
4372
4373 /*
4374 * roamMode value shall be inverted because the sementics is different.
4375 */
4376 if (CFG_LFR_FEATURE_ENABLED_MIN == roamMode)
4377 roamMode = CFG_LFR_FEATURE_ENABLED_MAX;
4378 else
4379 roamMode = CFG_LFR_FEATURE_ENABLED_MIN;
4380
Sameer Thalappilb0a30232013-09-27 15:37:48 -07004381 len = scnprintf(extra, sizeof(extra), "%s %d", command, roamMode);
Ratnam Rachuri28693eb2015-07-17 13:23:42 +05304382 len = VOS_MIN(priv_data.total_len, len + 1);
4383 if (copy_to_user(priv_data.buf, &extra, len)) {
Varun Reddy Yeturu6d99ac82013-05-08 14:15:35 -07004384 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4385 "%s: failed to copy data to user buffer", __func__);
4386 ret = -EFAULT;
4387 goto exit;
4388 }
4389 }
4390#endif
Srinivas Girigowdade697412013-02-14 16:31:48 -08004391#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004392#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowdade697412013-02-14 16:31:48 -08004393 else if (strncmp(command, "SETROAMDELTA", 12) == 0)
4394 {
4395 tANI_U8 *value = command;
4396 tANI_U8 roamRssiDiff = CFG_ROAM_RSSI_DIFF_DEFAULT;
4397
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05304398 ret = hdd_drv_cmd_validate(command, 12);
4399 if (ret)
4400 goto exit;
4401
Srinivas Girigowdade697412013-02-14 16:31:48 -08004402 /* Move pointer to ahead of SETROAMDELTA<delimiter> */
4403 value = value + 13;
4404 /* Convert the value from ascii to integer */
4405 ret = kstrtou8(value, 10, &roamRssiDiff);
4406 if (ret < 0)
4407 {
4408 /* If the input value is greater than max value of datatype, then also
4409 kstrtou8 fails */
4410 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4411 "%s: kstrtou8 failed range [%d - %d]", __func__,
4412 CFG_ROAM_RSSI_DIFF_MIN,
4413 CFG_ROAM_RSSI_DIFF_MAX);
4414 ret = -EINVAL;
4415 goto exit;
4416 }
4417
4418 if ((roamRssiDiff < CFG_ROAM_RSSI_DIFF_MIN) ||
4419 (roamRssiDiff > CFG_ROAM_RSSI_DIFF_MAX))
4420 {
4421 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4422 "Roam rssi diff value %d is out of range"
4423 " (Min: %d Max: %d)", roamRssiDiff,
4424 CFG_ROAM_RSSI_DIFF_MIN,
4425 CFG_ROAM_RSSI_DIFF_MAX);
4426 ret = -EINVAL;
4427 goto exit;
4428 }
4429
4430 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4431 "%s: Received Command to Set roam rssi diff = %d", __func__, roamRssiDiff);
4432
4433 pHddCtx->cfg_ini->RoamRssiDiff = roamRssiDiff;
4434 sme_UpdateRoamRssiDiff((tHalHandle)(pHddCtx->hHal), roamRssiDiff);
4435 }
Mahesh A Saptasagarec7d1092015-04-02 13:41:34 +05304436 else if (strncmp(command, "GETROAMDELTA", 12) == 0)
Srinivas Girigowdade697412013-02-14 16:31:48 -08004437 {
4438 tANI_U8 roamRssiDiff = sme_getRoamRssiDiff((tHalHandle)(pHddCtx->hHal));
4439 char extra[32];
4440 tANI_U8 len = 0;
4441
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05304442 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
4443 TRACE_CODE_HDD_GETROAMDELTA_IOCTL,
4444 pAdapter->sessionId, roamRssiDiff));
Sameer Thalappilb0a30232013-09-27 15:37:48 -07004445 len = scnprintf(extra, sizeof(extra), "%s %d",
4446 command, roamRssiDiff);
Ratnam Rachuri22a3b402015-07-17 13:21:49 +05304447 len = VOS_MIN(priv_data.total_len, len + 1);
4448 if (copy_to_user(priv_data.buf, &extra, len)) {
Srinivas Girigowdade697412013-02-14 16:31:48 -08004449 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4450 "%s: failed to copy data to user buffer", __func__);
4451 ret = -EFAULT;
4452 goto exit;
4453 }
4454 }
4455#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004456#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowdade697412013-02-14 16:31:48 -08004457 else if (strncmp(command, "GETBAND", 7) == 0)
4458 {
4459 int band = -1;
4460 char extra[32];
4461 tANI_U8 len = 0;
4462 hdd_getBand_helper(pHddCtx, &band);
4463
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05304464 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
4465 TRACE_CODE_HDD_GETBAND_IOCTL,
4466 pAdapter->sessionId, band));
Sameer Thalappilb0a30232013-09-27 15:37:48 -07004467 len = scnprintf(extra, sizeof(extra), "%s %d", command, band);
Ratnam Rachuri52139592015-07-17 13:17:29 +05304468 len = VOS_MIN(priv_data.total_len, len + 1);
4469 if (copy_to_user(priv_data.buf, &extra, len)) {
Srinivas Girigowdade697412013-02-14 16:31:48 -08004470 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4471 "%s: failed to copy data to user buffer", __func__);
4472 ret = -EFAULT;
4473 goto exit;
4474 }
4475 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08004476 else if (strncmp(command, "SETROAMSCANCHANNELS", 19) == 0)
4477 {
4478 tANI_U8 *value = command;
4479 tANI_U8 ChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
4480 tANI_U8 numChannels = 0;
4481 eHalStatus status = eHAL_STATUS_SUCCESS;
4482
4483 status = hdd_parse_channellist(value, ChannelList, &numChannels);
4484 if (eHAL_STATUS_SUCCESS != status)
4485 {
4486 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4487 "%s: Failed to parse channel list information", __func__);
4488 ret = -EINVAL;
4489 goto exit;
4490 }
4491
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05304492 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
4493 TRACE_CODE_HDD_SETROAMSCANCHANNELS_IOCTL,
4494 pAdapter->sessionId, numChannels));
Srinivas Girigowdade697412013-02-14 16:31:48 -08004495 if (numChannels > WNI_CFG_VALID_CHANNEL_LIST_LEN)
4496 {
4497 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4498 "%s: number of channels (%d) supported exceeded max (%d)", __func__,
4499 numChannels, WNI_CFG_VALID_CHANNEL_LIST_LEN);
4500 ret = -EINVAL;
4501 goto exit;
4502 }
4503 status = sme_ChangeRoamScanChannelList((tHalHandle)(pHddCtx->hHal), ChannelList,
4504 numChannels);
4505 if (eHAL_STATUS_SUCCESS != status)
4506 {
4507 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4508 "%s: Failed to update channel list information", __func__);
4509 ret = -EINVAL;
4510 goto exit;
4511 }
4512 }
4513 else if (strncmp(command, "GETROAMSCANCHANNELS", 19) == 0)
4514 {
4515 tANI_U8 ChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
4516 tANI_U8 numChannels = 0;
Jeff Johnson51b67782013-04-05 12:35:41 -07004517 tANI_U8 j = 0;
Srinivas Girigowdade697412013-02-14 16:31:48 -08004518 char extra[128] = {0};
Jeff Johnson51b67782013-04-05 12:35:41 -07004519 int len;
Srinivas Girigowdade697412013-02-14 16:31:48 -08004520
4521 if (eHAL_STATUS_SUCCESS != sme_getRoamScanChannelList( (tHalHandle)(pHddCtx->hHal),
4522 ChannelList, &numChannels ))
4523 {
4524 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
4525 "%s: failed to get roam scan channel list", __func__);
4526 ret = -EFAULT;
4527 goto exit;
4528 }
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05304529 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
4530 TRACE_CODE_HDD_GETROAMSCANCHANNELS_IOCTL,
4531 pAdapter->sessionId, numChannels));
Srinivas Girigowdade697412013-02-14 16:31:48 -08004532 /* output channel list is of the format
4533 [Number of roam scan channels][Channel1][Channel2]... */
4534 /* copy the number of channels in the 0th index */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07004535 len = scnprintf(extra, sizeof(extra), "%s %d", command, numChannels);
Sushant Kaushika08ca192015-09-16 15:52:04 +05304536 for (j = 0; (j < numChannels) && len <= sizeof(extra); j++)
Srinivas Girigowdade697412013-02-14 16:31:48 -08004537 {
Sameer Thalappilb0a30232013-09-27 15:37:48 -07004538 len += scnprintf(extra + len, sizeof(extra) - len, " %d",
4539 ChannelList[j]);
Srinivas Girigowdade697412013-02-14 16:31:48 -08004540 }
4541
Sushant Kaushikc9b8be52015-07-15 16:41:27 +05304542 len = VOS_MIN(priv_data.total_len, len + 1);
4543 if (copy_to_user(priv_data.buf, &extra, len))
Srinivas Girigowdade697412013-02-14 16:31:48 -08004544 {
4545 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4546 "%s: failed to copy data to user buffer", __func__);
4547 ret = -EFAULT;
4548 goto exit;
4549 }
4550 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004551 else if (strncmp(command, "GETCCXMODE", 10) == 0)
4552 {
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004553 tANI_BOOLEAN eseMode = sme_getIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal));
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004554 char extra[32];
4555 tANI_U8 len = 0;
4556
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004557 /* Check if the features OKC/ESE/11R are supported simultaneously,
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07004558 then this operation is not permitted (return FAILURE) */
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004559 if (eseMode &&
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07004560 hdd_is_okc_mode_enabled(pHddCtx) &&
4561 sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal)))
4562 {
4563 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004564 "%s: OKC/ESE/11R are supported simultaneously"
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07004565 " hence this operation is not permitted!", __func__);
4566 ret = -EPERM;
4567 goto exit;
4568 }
4569
Sameer Thalappilb0a30232013-09-27 15:37:48 -07004570 len = scnprintf(extra, sizeof(extra), "%s %d",
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004571 "GETCCXMODE", eseMode);
Sushant Kaushikf8abd352015-07-15 16:37:49 +05304572 len = VOS_MIN(priv_data.total_len, len + 1);
4573 if (copy_to_user(priv_data.buf, &extra, len))
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004574 {
4575 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4576 "%s: failed to copy data to user buffer", __func__);
4577 ret = -EFAULT;
4578 goto exit;
4579 }
4580 }
4581 else if (strncmp(command, "GETOKCMODE", 10) == 0)
4582 {
4583 tANI_BOOLEAN okcMode = hdd_is_okc_mode_enabled(pHddCtx);
4584 char extra[32];
4585 tANI_U8 len = 0;
4586
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004587 /* Check if the features OKC/ESE/11R are supported simultaneously,
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07004588 then this operation is not permitted (return FAILURE) */
4589 if (okcMode &&
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004590 sme_getIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal)) &&
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07004591 sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal)))
4592 {
4593 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004594 "%s: OKC/ESE/11R are supported simultaneously"
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07004595 " hence this operation is not permitted!", __func__);
4596 ret = -EPERM;
4597 goto exit;
4598 }
4599
Sameer Thalappilb0a30232013-09-27 15:37:48 -07004600 len = scnprintf(extra, sizeof(extra), "%s %d",
4601 "GETOKCMODE", okcMode);
Sushant Kaushikbc2fb5c2015-07-15 16:43:16 +05304602 len = VOS_MIN(priv_data.total_len, len + 1);
4603 if (copy_to_user(priv_data.buf, &extra, len))
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004604 {
4605 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4606 "%s: failed to copy data to user buffer", __func__);
4607 ret = -EFAULT;
4608 goto exit;
4609 }
4610 }
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07004611 else if (strncmp(command, "GETFASTROAM", 11) == 0)
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004612 {
4613 tANI_BOOLEAN lfrMode = sme_getIsLfrFeatureEnabled((tHalHandle)(pHddCtx->hHal));
4614 char extra[32];
4615 tANI_U8 len = 0;
4616
Sameer Thalappilb0a30232013-09-27 15:37:48 -07004617 len = scnprintf(extra, sizeof(extra), "%s %d",
4618 "GETFASTROAM", lfrMode);
Sushant Kaushik4da7ec92015-07-15 16:39:32 +05304619 len = VOS_MIN(priv_data.total_len, len + 1);
4620 if (copy_to_user(priv_data.buf, &extra, len))
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004621 {
4622 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4623 "%s: failed to copy data to user buffer", __func__);
4624 ret = -EFAULT;
4625 goto exit;
4626 }
4627 }
4628 else if (strncmp(command, "GETFASTTRANSITION", 17) == 0)
4629 {
4630 tANI_BOOLEAN ft = sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal));
4631 char extra[32];
4632 tANI_U8 len = 0;
4633
Sameer Thalappilb0a30232013-09-27 15:37:48 -07004634 len = scnprintf(extra, sizeof(extra), "%s %d",
4635 "GETFASTTRANSITION", ft);
Sushant Kaushik231a4452015-07-15 16:23:56 +05304636 len = VOS_MIN(priv_data.total_len, len + 1);
4637 if (copy_to_user(priv_data.buf, &extra, len))
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004638 {
4639 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4640 "%s: failed to copy data to user buffer", __func__);
4641 ret = -EFAULT;
4642 goto exit;
4643 }
4644 }
4645 else if (strncmp(command, "SETROAMSCANCHANNELMINTIME", 25) == 0)
4646 {
4647 tANI_U8 *value = command;
4648 tANI_U8 minTime = CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_DEFAULT;
4649
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05304650 ret = hdd_drv_cmd_validate(command, 25);
4651 if (ret)
4652 goto exit;
4653
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004654 /* Move pointer to ahead of SETROAMSCANCHANNELMINTIME<delimiter> */
4655 value = value + 26;
4656 /* Convert the value from ascii to integer */
4657 ret = kstrtou8(value, 10, &minTime);
4658 if (ret < 0)
4659 {
4660 /* If the input value is greater than max value of datatype, then also
4661 kstrtou8 fails */
4662 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4663 "%s: kstrtou8 failed range [%d - %d]", __func__,
4664 CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MIN,
4665 CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MAX);
4666 ret = -EINVAL;
4667 goto exit;
4668 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004669 if ((minTime < CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MIN) ||
4670 (minTime > CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MAX))
4671 {
4672 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4673 "scan min channel time value %d is out of range"
4674 " (Min: %d Max: %d)", minTime,
4675 CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MIN,
4676 CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MAX);
4677 ret = -EINVAL;
4678 goto exit;
4679 }
4680
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05304681 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
4682 TRACE_CODE_HDD_SETROAMSCANCHANNELMINTIME_IOCTL,
4683 pAdapter->sessionId, minTime));
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004684 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4685 "%s: Received Command to change channel min time = %d", __func__, minTime);
4686
4687 pHddCtx->cfg_ini->nNeighborScanMinChanTime = minTime;
4688 sme_setNeighborScanMinChanTime((tHalHandle)(pHddCtx->hHal), minTime);
4689 }
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004690 else if (strncmp(command, "SENDACTIONFRAME", 15) == 0)
4691 {
4692 tANI_U8 *value = command;
4693 tANI_U8 channel = 0;
4694 tANI_U8 dwellTime = 0;
4695 tANI_U8 bufLen = 0;
4696 tANI_U8 *buf = NULL;
4697 tSirMacAddr targetApBssid;
4698 eHalStatus status = eHAL_STATUS_SUCCESS;
4699 struct ieee80211_channel chan;
4700 tANI_U8 finalLen = 0;
4701 tANI_U8 *finalBuf = NULL;
4702 tANI_U8 temp = 0;
4703 u64 cookie;
4704 hdd_station_ctx_t *pHddStaCtx = NULL;
4705 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4706
4707 /* if not associated, no need to send action frame */
4708 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
4709 {
4710 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s:Not associated!",__func__);
4711 ret = -EINVAL;
4712 goto exit;
4713 }
4714
4715 status = hdd_parse_send_action_frame_data(value, targetApBssid, &channel,
4716 &dwellTime, &buf, &bufLen);
4717 if (eHAL_STATUS_SUCCESS != status)
4718 {
4719 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4720 "%s: Failed to parse send action frame data", __func__);
4721 ret = -EINVAL;
4722 goto exit;
4723 }
4724
4725 /* if the target bssid is different from currently associated AP,
4726 then no need to send action frame */
4727 if (VOS_TRUE != vos_mem_compare(targetApBssid,
4728 pHddStaCtx->conn_info.bssId, sizeof(tSirMacAddr)))
4729 {
4730 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s:STA is not associated to this AP!",__func__);
4731 ret = -EINVAL;
Jeff Johnson11c33152013-04-16 17:52:40 -07004732 vos_mem_free(buf);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08004733 buf = NULL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004734 goto exit;
4735 }
4736
4737 /* if the channel number is different from operating channel then
4738 no need to send action frame */
4739 if (channel != pHddStaCtx->conn_info.operationChannel)
4740 {
4741 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4742 "%s: channel(%d) is different from operating channel(%d)",
4743 __func__, channel, pHddStaCtx->conn_info.operationChannel);
4744 ret = -EINVAL;
Jeff Johnson11c33152013-04-16 17:52:40 -07004745 vos_mem_free(buf);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08004746 buf = NULL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004747 goto exit;
4748 }
4749 chan.center_freq = sme_ChnToFreq(channel);
4750
4751 finalLen = bufLen + 24;
4752 finalBuf = vos_mem_malloc(finalLen);
4753 if (NULL == finalBuf)
4754 {
4755 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "%s:memory allocation failed",__func__);
4756 ret = -ENOMEM;
Jeff Johnson11c33152013-04-16 17:52:40 -07004757 vos_mem_free(buf);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08004758 buf = NULL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004759 goto exit;
4760 }
4761 vos_mem_zero(finalBuf, finalLen);
4762
4763 /* Fill subtype */
4764 temp = SIR_MAC_MGMT_ACTION << 4;
4765 vos_mem_copy(finalBuf + 0, &temp, sizeof(temp));
4766
4767 /* Fill type */
4768 temp = SIR_MAC_MGMT_FRAME;
4769 vos_mem_copy(finalBuf + 2, &temp, sizeof(temp));
4770
4771 /* Fill destination address (bssid of the AP) */
4772 vos_mem_copy(finalBuf + 4, targetApBssid, sizeof(targetApBssid));
4773
Srinivas Girigowdab27c0192013-06-03 10:19:56 -07004774 /* Fill source address (STA mac address) */
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004775 vos_mem_copy(finalBuf + 10, pAdapter->macAddressCurrent.bytes, sizeof(pAdapter->macAddressCurrent.bytes));
4776
Srinivas Girigowdab27c0192013-06-03 10:19:56 -07004777 /* Fill BSSID (AP mac address) */
4778 vos_mem_copy(finalBuf + 16, targetApBssid, sizeof(targetApBssid));
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004779
4780 /* Fill received buffer from 24th address */
4781 vos_mem_copy(finalBuf + 24, buf, bufLen);
4782
Jeff Johnson11c33152013-04-16 17:52:40 -07004783 /* done with the parsed buffer */
4784 vos_mem_free(buf);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08004785 buf = NULL;
Jeff Johnson11c33152013-04-16 17:52:40 -07004786
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05304787#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
4788 params.chan = &chan;
4789 params.offchan = 0;
4790 params.wait = dwellTime;
4791 params.buf = finalBuf;
4792 params.len = finalLen;
4793 params.no_cck = 1;
4794 params.dont_wait_for_ack = 1;
4795 ret = wlan_hdd_mgmt_tx(NULL, &pAdapter->wdev, &params, &cookie);
4796#else
DARAM SUDHA39eede62014-02-12 11:16:40 +05304797 wlan_hdd_mgmt_tx( NULL,
Yue Maf49ba872013-08-19 12:04:25 -07004798#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
4799 &(pAdapter->wdev),
4800#else
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07004801 pAdapter->dev,
Yue Maf49ba872013-08-19 12:04:25 -07004802#endif
4803 &chan, 0,
4804#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0))
4805 NL80211_CHAN_HT20, 1,
4806#endif
4807 dwellTime, finalBuf, finalLen, 1,
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004808 1, &cookie );
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05304809#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0)*/
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004810 vos_mem_free(finalBuf);
4811 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004812 else if (strncmp(command, "GETROAMSCANCHANNELMINTIME", 25) == 0)
4813 {
4814 tANI_U16 val = sme_getNeighborScanMinChanTime((tHalHandle)(pHddCtx->hHal));
4815 char extra[32];
4816 tANI_U8 len = 0;
4817
4818 /* value is interms of msec */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07004819 len = scnprintf(extra, sizeof(extra), "%s %d",
4820 "GETROAMSCANCHANNELMINTIME", val);
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05304821 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
4822 TRACE_CODE_HDD_GETROAMSCANCHANNELMINTIME_IOCTL,
4823 pAdapter->sessionId, val));
Sushant Kaushikbb8c52c2015-07-15 16:36:23 +05304824 len = VOS_MIN(priv_data.total_len, len + 1);
4825 if (copy_to_user(priv_data.buf, &extra, len))
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004826 {
4827 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4828 "%s: failed to copy data to user buffer", __func__);
4829 ret = -EFAULT;
4830 goto exit;
4831 }
4832 }
4833 else if (strncmp(command, "SETSCANCHANNELTIME", 18) == 0)
4834 {
4835 tANI_U8 *value = command;
Varun Reddy Yeturu3885a662013-06-19 07:10:37 -07004836 tANI_U16 maxTime = CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_DEFAULT;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004837
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05304838 ret = hdd_drv_cmd_validate(command, 18);
4839 if (ret)
4840 goto exit;
4841
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004842 /* Move pointer to ahead of SETSCANCHANNELTIME<delimiter> */
4843 value = value + 19;
4844 /* Convert the value from ascii to integer */
Varun Reddy Yeturu3885a662013-06-19 07:10:37 -07004845 ret = kstrtou16(value, 10, &maxTime);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004846 if (ret < 0)
4847 {
4848 /* If the input value is greater than max value of datatype, then also
Varun Reddy Yeturu3885a662013-06-19 07:10:37 -07004849 kstrtou16 fails */
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004850 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Varun Reddy Yeturu3885a662013-06-19 07:10:37 -07004851 "%s: kstrtou16 failed range [%d - %d]", __func__,
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004852 CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MIN,
4853 CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MAX);
4854 ret = -EINVAL;
4855 goto exit;
4856 }
4857
4858 if ((maxTime < CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MIN) ||
4859 (maxTime > CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MAX))
4860 {
4861 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4862 "lfr mode value %d is out of range"
4863 " (Min: %d Max: %d)", maxTime,
4864 CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MIN,
4865 CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MAX);
4866 ret = -EINVAL;
4867 goto exit;
4868 }
4869
4870 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4871 "%s: Received Command to change channel max time = %d", __func__, maxTime);
4872
4873 pHddCtx->cfg_ini->nNeighborScanMaxChanTime = maxTime;
4874 sme_setNeighborScanMaxChanTime((tHalHandle)(pHddCtx->hHal), maxTime);
4875 }
4876 else if (strncmp(command, "GETSCANCHANNELTIME", 18) == 0)
4877 {
4878 tANI_U16 val = sme_getNeighborScanMaxChanTime((tHalHandle)(pHddCtx->hHal));
4879 char extra[32];
4880 tANI_U8 len = 0;
4881
4882 /* value is interms of msec */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07004883 len = scnprintf(extra, sizeof(extra), "%s %d",
4884 "GETSCANCHANNELTIME", val);
Ratheesh S Pacbfa932015-07-16 15:27:18 +05304885 len = VOS_MIN(priv_data.total_len, len + 1);
4886 if (copy_to_user(priv_data.buf, &extra, len))
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004887 {
4888 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4889 "%s: failed to copy data to user buffer", __func__);
4890 ret = -EFAULT;
4891 goto exit;
4892 }
4893 }
4894 else if (strncmp(command, "SETSCANHOMETIME", 15) == 0)
4895 {
4896 tANI_U8 *value = command;
4897 tANI_U16 val = CFG_NEIGHBOR_SCAN_TIMER_PERIOD_DEFAULT;
4898
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05304899 ret = hdd_drv_cmd_validate(command, 15);
4900 if (ret)
4901 goto exit;
4902
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004903 /* Move pointer to ahead of SETSCANHOMETIME<delimiter> */
4904 value = value + 16;
4905 /* Convert the value from ascii to integer */
4906 ret = kstrtou16(value, 10, &val);
4907 if (ret < 0)
4908 {
4909 /* If the input value is greater than max value of datatype, then also
4910 kstrtou16 fails */
4911 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4912 "%s: kstrtou16 failed range [%d - %d]", __func__,
4913 CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MIN,
4914 CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MAX);
4915 ret = -EINVAL;
4916 goto exit;
4917 }
4918
4919 if ((val < CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MIN) ||
4920 (val > CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MAX))
4921 {
4922 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4923 "scan home time value %d is out of range"
4924 " (Min: %d Max: %d)", val,
4925 CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MIN,
4926 CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MAX);
4927 ret = -EINVAL;
4928 goto exit;
4929 }
4930
4931 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4932 "%s: Received Command to change scan home time = %d", __func__, val);
4933
4934 pHddCtx->cfg_ini->nNeighborScanPeriod = val;
4935 sme_setNeighborScanPeriod((tHalHandle)(pHddCtx->hHal), val);
4936 }
4937 else if (strncmp(command, "GETSCANHOMETIME", 15) == 0)
4938 {
4939 tANI_U16 val = sme_getNeighborScanPeriod((tHalHandle)(pHddCtx->hHal));
4940 char extra[32];
4941 tANI_U8 len = 0;
4942
4943 /* value is interms of msec */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07004944 len = scnprintf(extra, sizeof(extra), "%s %d",
4945 "GETSCANHOMETIME", val);
Ratheesh S P728d7c62015-07-16 15:38:58 +05304946 len = VOS_MIN(priv_data.total_len, len + 1);
4947 if (copy_to_user(priv_data.buf, &extra, len))
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004948 {
4949 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4950 "%s: failed to copy data to user buffer", __func__);
4951 ret = -EFAULT;
4952 goto exit;
4953 }
4954 }
4955 else if (strncmp(command, "SETROAMINTRABAND", 16) == 0)
4956 {
4957 tANI_U8 *value = command;
4958 tANI_U8 val = CFG_ROAM_INTRA_BAND_DEFAULT;
4959
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05304960 ret = hdd_drv_cmd_validate(command, 16);
4961 if (ret)
4962 goto exit;
4963
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004964 /* Move pointer to ahead of SETROAMINTRABAND<delimiter> */
4965 value = value + 17;
4966 /* Convert the value from ascii to integer */
4967 ret = kstrtou8(value, 10, &val);
4968 if (ret < 0)
4969 {
4970 /* If the input value is greater than max value of datatype, then also
4971 kstrtou8 fails */
4972 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4973 "%s: kstrtou8 failed range [%d - %d]", __func__,
4974 CFG_ROAM_INTRA_BAND_MIN,
4975 CFG_ROAM_INTRA_BAND_MAX);
4976 ret = -EINVAL;
4977 goto exit;
4978 }
4979
4980 if ((val < CFG_ROAM_INTRA_BAND_MIN) ||
4981 (val > CFG_ROAM_INTRA_BAND_MAX))
4982 {
4983 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4984 "intra band mode value %d is out of range"
4985 " (Min: %d Max: %d)", val,
4986 CFG_ROAM_INTRA_BAND_MIN,
4987 CFG_ROAM_INTRA_BAND_MAX);
4988 ret = -EINVAL;
4989 goto exit;
4990 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004991 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4992 "%s: Received Command to change intra band = %d", __func__, val);
4993
4994 pHddCtx->cfg_ini->nRoamIntraBand = val;
4995 sme_setRoamIntraBand((tHalHandle)(pHddCtx->hHal), val);
4996 }
4997 else if (strncmp(command, "GETROAMINTRABAND", 16) == 0)
4998 {
4999 tANI_U16 val = sme_getRoamIntraBand((tHalHandle)(pHddCtx->hHal));
5000 char extra[32];
5001 tANI_U8 len = 0;
5002
5003 /* value is interms of msec */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07005004 len = scnprintf(extra, sizeof(extra), "%s %d",
5005 "GETROAMINTRABAND", val);
Ratheesh S P2dd2a3e2015-07-16 15:34:23 +05305006 len = VOS_MIN(priv_data.total_len, len + 1);
5007 if (copy_to_user(priv_data.buf, &extra, len))
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07005008 {
5009 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5010 "%s: failed to copy data to user buffer", __func__);
5011 ret = -EFAULT;
5012 goto exit;
5013 }
5014 }
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005015 else if (strncmp(command, "SETSCANNPROBES", 14) == 0)
5016 {
5017 tANI_U8 *value = command;
5018 tANI_U8 nProbes = CFG_ROAM_SCAN_N_PROBES_DEFAULT;
5019
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05305020 ret = hdd_drv_cmd_validate(command, 14);
5021 if (ret)
5022 goto exit;
5023
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005024 /* Move pointer to ahead of SETSCANNPROBES<delimiter> */
5025 value = value + 15;
5026 /* Convert the value from ascii to integer */
5027 ret = kstrtou8(value, 10, &nProbes);
5028 if (ret < 0)
5029 {
5030 /* If the input value is greater than max value of datatype, then also
5031 kstrtou8 fails */
5032 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5033 "%s: kstrtou8 failed range [%d - %d]", __func__,
5034 CFG_ROAM_SCAN_N_PROBES_MIN,
5035 CFG_ROAM_SCAN_N_PROBES_MAX);
5036 ret = -EINVAL;
5037 goto exit;
5038 }
5039
5040 if ((nProbes < CFG_ROAM_SCAN_N_PROBES_MIN) ||
5041 (nProbes > CFG_ROAM_SCAN_N_PROBES_MAX))
5042 {
5043 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5044 "NProbes value %d is out of range"
5045 " (Min: %d Max: %d)", nProbes,
5046 CFG_ROAM_SCAN_N_PROBES_MIN,
5047 CFG_ROAM_SCAN_N_PROBES_MAX);
5048 ret = -EINVAL;
5049 goto exit;
5050 }
5051
5052 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
5053 "%s: Received Command to Set nProbes = %d", __func__, nProbes);
5054
5055 pHddCtx->cfg_ini->nProbes = nProbes;
5056 sme_UpdateRoamScanNProbes((tHalHandle)(pHddCtx->hHal), nProbes);
5057 }
Mahesh A Saptasagarec7d1092015-04-02 13:41:34 +05305058 else if (strncmp(command, "GETSCANNPROBES", 14) == 0)
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005059 {
5060 tANI_U8 val = sme_getRoamScanNProbes((tHalHandle)(pHddCtx->hHal));
5061 char extra[32];
5062 tANI_U8 len = 0;
5063
Sameer Thalappilb0a30232013-09-27 15:37:48 -07005064 len = scnprintf(extra, sizeof(extra), "%s %d", command, val);
Ratnam Rachuri6da525d2015-08-07 13:55:54 +05305065 len = VOS_MIN(priv_data.total_len, len + 1);
5066 if (copy_to_user(priv_data.buf, &extra, len)) {
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005067 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5068 "%s: failed to copy data to user buffer", __func__);
5069 ret = -EFAULT;
5070 goto exit;
5071 }
5072 }
5073 else if (strncmp(command, "SETSCANHOMEAWAYTIME", 19) == 0)
5074 {
5075 tANI_U8 *value = command;
5076 tANI_U16 homeAwayTime = CFG_ROAM_SCAN_HOME_AWAY_TIME_DEFAULT;
5077
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05305078 ret = hdd_drv_cmd_validate(command, 19);
5079 if (ret)
5080 goto exit;
5081
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005082 /* Move pointer to ahead of SETSCANHOMEAWAYTIME<delimiter> */
5083 /* input value is in units of msec */
5084 value = value + 20;
5085 /* Convert the value from ascii to integer */
5086 ret = kstrtou16(value, 10, &homeAwayTime);
5087 if (ret < 0)
5088 {
5089 /* If the input value is greater than max value of datatype, then also
5090 kstrtou8 fails */
5091 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5092 "%s: kstrtou8 failed range [%d - %d]", __func__,
5093 CFG_ROAM_SCAN_HOME_AWAY_TIME_MIN,
5094 CFG_ROAM_SCAN_HOME_AWAY_TIME_MAX);
5095 ret = -EINVAL;
5096 goto exit;
5097 }
5098
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005099 if ((homeAwayTime < CFG_ROAM_SCAN_HOME_AWAY_TIME_MIN) ||
5100 (homeAwayTime > CFG_ROAM_SCAN_HOME_AWAY_TIME_MAX))
5101 {
5102 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5103 "homeAwayTime value %d is out of range"
5104 " (Min: %d Max: %d)", homeAwayTime,
5105 CFG_ROAM_SCAN_HOME_AWAY_TIME_MIN,
5106 CFG_ROAM_SCAN_HOME_AWAY_TIME_MAX);
5107 ret = -EINVAL;
5108 goto exit;
5109 }
5110
5111 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
5112 "%s: Received Command to Set scan away time = %d", __func__, homeAwayTime);
Srinivas Girigowda6cf0b822013-06-27 14:00:20 -07005113 if (pHddCtx->cfg_ini->nRoamScanHomeAwayTime != homeAwayTime)
5114 {
5115 pHddCtx->cfg_ini->nRoamScanHomeAwayTime = homeAwayTime;
5116 sme_UpdateRoamScanHomeAwayTime((tHalHandle)(pHddCtx->hHal), homeAwayTime, eANI_BOOLEAN_TRUE);
5117 }
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005118 }
Mahesh A Saptasagarec7d1092015-04-02 13:41:34 +05305119 else if (strncmp(command, "GETSCANHOMEAWAYTIME", 19) == 0)
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005120 {
5121 tANI_U16 val = sme_getRoamScanHomeAwayTime((tHalHandle)(pHddCtx->hHal));
5122 char extra[32];
5123 tANI_U8 len = 0;
5124
Sameer Thalappilb0a30232013-09-27 15:37:48 -07005125 len = scnprintf(extra, sizeof(extra), "%s %d", command, val);
Ratnam Rachuri51a5ad12015-08-07 14:06:37 +05305126 len = VOS_MIN(priv_data.total_len, len + 1);
5127 if (copy_to_user(priv_data.buf, &extra, len)) {
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005128 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5129 "%s: failed to copy data to user buffer", __func__);
5130 ret = -EFAULT;
5131 goto exit;
5132 }
5133 }
5134 else if (strncmp(command, "REASSOC", 7) == 0)
5135 {
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05305136 ret = hdd_drv_cmd_validate(command, 7);
5137 if (ret)
5138 goto exit;
5139
5140 ret = hdd_parse_reassoc(pAdapter, command, priv_data.total_len);
Selvaraj, Sridhar5aff1ed2016-06-18 01:26:23 +05305141 if (!ret)
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005142 goto exit;
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005143 }
Srinivas Girigowdaad34ca92013-10-22 10:54:29 -07005144 else if (strncmp(command, "SETWESMODE", 10) == 0)
5145 {
5146 tANI_U8 *value = command;
5147 tANI_BOOLEAN wesMode = CFG_ENABLE_WES_MODE_NAME_DEFAULT;
5148
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05305149 ret = hdd_drv_cmd_validate(command, 10);
5150 if (ret)
5151 goto exit;
5152
Srinivas Girigowdaad34ca92013-10-22 10:54:29 -07005153 /* Move pointer to ahead of SETWESMODE<delimiter> */
5154 value = value + 11;
5155 /* Convert the value from ascii to integer */
5156 ret = kstrtou8(value, 10, &wesMode);
5157 if (ret < 0)
5158 {
5159 /* If the input value is greater than max value of datatype, then also
5160 kstrtou8 fails */
5161 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5162 "%s: kstrtou8 failed range [%d - %d]", __func__,
5163 CFG_ENABLE_WES_MODE_NAME_MIN,
5164 CFG_ENABLE_WES_MODE_NAME_MAX);
5165 ret = -EINVAL;
5166 goto exit;
5167 }
5168
5169 if ((wesMode < CFG_ENABLE_WES_MODE_NAME_MIN) ||
5170 (wesMode > CFG_ENABLE_WES_MODE_NAME_MAX))
5171 {
5172 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5173 "WES Mode value %d is out of range"
5174 " (Min: %d Max: %d)", wesMode,
5175 CFG_ENABLE_WES_MODE_NAME_MIN,
5176 CFG_ENABLE_WES_MODE_NAME_MAX);
5177 ret = -EINVAL;
5178 goto exit;
5179 }
5180 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
5181 "%s: Received Command to Set WES Mode rssi diff = %d", __func__, wesMode);
5182
5183 pHddCtx->cfg_ini->isWESModeEnabled = wesMode;
5184 sme_UpdateWESMode((tHalHandle)(pHddCtx->hHal), wesMode);
5185 }
Mahesh A Saptasagarec7d1092015-04-02 13:41:34 +05305186 else if (strncmp(command, "GETWESMODE", 10) == 0)
Srinivas Girigowdaad34ca92013-10-22 10:54:29 -07005187 {
5188 tANI_BOOLEAN wesMode = sme_GetWESMode((tHalHandle)(pHddCtx->hHal));
5189 char extra[32];
5190 tANI_U8 len = 0;
5191
Arif Hussain826d9412013-11-12 16:44:54 -08005192 len = scnprintf(extra, sizeof(extra), "%s %d", command, wesMode);
Ratnam Rachuri8fe90c62015-08-07 14:03:26 +05305193 len = VOS_MIN(priv_data.total_len, len + 1);
5194 if (copy_to_user(priv_data.buf, &extra, len)) {
Srinivas Girigowdaad34ca92013-10-22 10:54:29 -07005195 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5196 "%s: failed to copy data to user buffer", __func__);
5197 ret = -EFAULT;
5198 goto exit;
5199 }
5200 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005201#endif /* WLAN_FEATURE_VOWIFI_11R || FEATURE_WLAN_ESE || FEATURE_WLAN_LFR */
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07005202#ifdef FEATURE_WLAN_LFR
5203 else if (strncmp(command, "SETFASTROAM", 11) == 0)
5204 {
5205 tANI_U8 *value = command;
5206 tANI_U8 lfrMode = CFG_LFR_FEATURE_ENABLED_DEFAULT;
5207
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +05305208 if (pHddCtx->concurrency_mode == VOS_STA_MON) {
5209 hddLog(LOGE,
5210 FL("Roaming is always disabled in STA + MON concurrency"));
5211 ret = -EINVAL;
5212 goto exit;
5213 }
5214
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05305215 ret = hdd_drv_cmd_validate(command, 11);
5216 if (ret)
5217 goto exit;
5218
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07005219 /* Move pointer to ahead of SETFASTROAM<delimiter> */
5220 value = value + 12;
5221 /* Convert the value from ascii to integer */
5222 ret = kstrtou8(value, 10, &lfrMode);
5223 if (ret < 0)
5224 {
5225 /* If the input value is greater than max value of datatype, then also
5226 kstrtou8 fails */
5227 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5228 "%s: kstrtou8 failed range [%d - %d]", __func__,
5229 CFG_LFR_FEATURE_ENABLED_MIN,
5230 CFG_LFR_FEATURE_ENABLED_MAX);
5231 ret = -EINVAL;
5232 goto exit;
5233 }
5234
5235 if ((lfrMode < CFG_LFR_FEATURE_ENABLED_MIN) ||
5236 (lfrMode > CFG_LFR_FEATURE_ENABLED_MAX))
5237 {
5238 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5239 "lfr mode value %d is out of range"
5240 " (Min: %d Max: %d)", lfrMode,
5241 CFG_LFR_FEATURE_ENABLED_MIN,
5242 CFG_LFR_FEATURE_ENABLED_MAX);
5243 ret = -EINVAL;
5244 goto exit;
5245 }
5246
5247 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
5248 "%s: Received Command to change lfr mode = %d", __func__, lfrMode);
5249
5250 pHddCtx->cfg_ini->isFastRoamIniFeatureEnabled = lfrMode;
5251 sme_UpdateIsFastRoamIniFeatureEnabled((tHalHandle)(pHddCtx->hHal), lfrMode);
5252 }
5253#endif
5254#ifdef WLAN_FEATURE_VOWIFI_11R
5255 else if (strncmp(command, "SETFASTTRANSITION", 17) == 0)
5256 {
5257 tANI_U8 *value = command;
5258 tANI_U8 ft = CFG_FAST_TRANSITION_ENABLED_NAME_DEFAULT;
5259
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05305260 ret = hdd_drv_cmd_validate(command, 17);
5261 if (ret)
5262 goto exit;
5263
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07005264 /* Move pointer to ahead of SETFASTROAM<delimiter> */
5265 value = value + 18;
5266 /* Convert the value from ascii to integer */
5267 ret = kstrtou8(value, 10, &ft);
5268 if (ret < 0)
5269 {
5270 /* If the input value is greater than max value of datatype, then also
5271 kstrtou8 fails */
5272 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5273 "%s: kstrtou8 failed range [%d - %d]", __func__,
5274 CFG_FAST_TRANSITION_ENABLED_NAME_MIN,
5275 CFG_FAST_TRANSITION_ENABLED_NAME_MAX);
5276 ret = -EINVAL;
5277 goto exit;
5278 }
5279
5280 if ((ft < CFG_FAST_TRANSITION_ENABLED_NAME_MIN) ||
5281 (ft > CFG_FAST_TRANSITION_ENABLED_NAME_MAX))
5282 {
5283 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5284 "ft mode value %d is out of range"
5285 " (Min: %d Max: %d)", ft,
5286 CFG_FAST_TRANSITION_ENABLED_NAME_MIN,
5287 CFG_FAST_TRANSITION_ENABLED_NAME_MAX);
5288 ret = -EINVAL;
5289 goto exit;
5290 }
5291
5292 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
5293 "%s: Received Command to change ft mode = %d", __func__, ft);
5294
5295 pHddCtx->cfg_ini->isFastTransitionEnabled = ft;
5296 sme_UpdateFastTransitionEnabled((tHalHandle)(pHddCtx->hHal), ft);
5297 }
Padma, Santhosh Kumar778d8382015-03-04 17:41:22 +05305298 else if (strncmp(command, "SETDFSSCANMODE", 14) == 0)
5299 {
5300 tANI_U8 *value = command;
5301 tANI_U8 dfsScanMode = DFS_CHNL_SCAN_ENABLED_NORMAL;
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05305302
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05305303 ret = hdd_drv_cmd_validate(command, 14);
5304 if (ret)
5305 goto exit;
5306
Padma, Santhosh Kumar778d8382015-03-04 17:41:22 +05305307 /* Move pointer to ahead of SETDFSSCANMODE<delimiter> */
5308 value = value + 15;
5309 /* Convert the value from ascii to integer */
5310 ret = kstrtou8(value, 10, &dfsScanMode);
5311 if (ret < 0)
5312 {
5313 /* If the input value is greater than max value of
5314 datatype, then also kstrtou8 fails
5315 */
5316 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5317 "%s: kstrtou8 failed range [%d - %d]", __func__,
5318 CFG_ENABLE_DFS_CHNL_SCAN_MIN,
5319 CFG_ENABLE_DFS_CHNL_SCAN_MAX);
5320 ret = -EINVAL;
5321 goto exit;
5322 }
5323
5324 if ((dfsScanMode < CFG_ENABLE_DFS_CHNL_SCAN_MIN) ||
5325 (dfsScanMode > CFG_ENABLE_DFS_CHNL_SCAN_MAX))
5326 {
5327 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5328 "dfsScanMode value %d is out of range"
5329 " (Min: %d Max: %d)", dfsScanMode,
5330 CFG_ENABLE_DFS_CHNL_SCAN_MIN,
5331 CFG_ENABLE_DFS_CHNL_SCAN_MAX);
5332 ret = -EINVAL;
5333 goto exit;
5334 }
5335 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
5336 "%s: Received Command to Set DFS Scan Mode = %d",
5337 __func__, dfsScanMode);
5338
5339 ret = wlan_hdd_handle_dfs_chan_scan(pHddCtx, dfsScanMode);
5340 }
5341 else if (strncmp(command, "GETDFSSCANMODE", 14) == 0)
5342 {
5343 tANI_U8 dfsScanMode = sme_GetDFSScanMode(pHddCtx->hHal);
5344 char extra[32];
5345 tANI_U8 len = 0;
5346
5347 len = scnprintf(extra, sizeof(extra), "%s %d", command, dfsScanMode);
Ratheesh S P767224e2015-07-16 15:35:51 +05305348 len = VOS_MIN(priv_data.total_len, len + 1);
5349 if (copy_to_user(priv_data.buf, &extra, len))
Padma, Santhosh Kumar778d8382015-03-04 17:41:22 +05305350 {
5351 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5352 "%s: failed to copy data to user buffer", __func__);
5353 ret = -EFAULT;
5354 goto exit;
5355 }
5356 }
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05305357 else if (strncmp(command, "FASTREASSOC", 11) == 0)
5358 {
Selvaraj, Sridhar3714c4d2016-06-22 15:19:12 +05305359 ret = wlan_hdd_handle_fastreassoc(pAdapter, command);
5360 if (!ret)
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05305361 goto exit;
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05305362 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07005363#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005364#ifdef FEATURE_WLAN_ESE
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07005365 else if (strncmp(command, "SETCCXMODE", 10) == 0)
5366 {
5367 tANI_U8 *value = command;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005368 tANI_U8 eseMode = CFG_ESE_FEATURE_ENABLED_DEFAULT;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07005369
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05305370 ret = hdd_drv_cmd_validate(command, 10);
5371 if (ret)
5372 goto exit;
5373
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005374 /* Check if the features OKC/ESE/11R are supported simultaneously,
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07005375 then this operation is not permitted (return FAILURE) */
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005376 if (sme_getIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal)) &&
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07005377 hdd_is_okc_mode_enabled(pHddCtx) &&
5378 sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal)))
5379 {
5380 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005381 "%s: OKC/ESE/11R are supported simultaneously"
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07005382 " hence this operation is not permitted!", __func__);
5383 ret = -EPERM;
5384 goto exit;
5385 }
5386
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07005387 /* Move pointer to ahead of SETCCXMODE<delimiter> */
5388 value = value + 11;
5389 /* Convert the value from ascii to integer */
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005390 ret = kstrtou8(value, 10, &eseMode);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07005391 if (ret < 0)
5392 {
5393 /* If the input value is greater than max value of datatype, then also
5394 kstrtou8 fails */
5395 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5396 "%s: kstrtou8 failed range [%d - %d]", __func__,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005397 CFG_ESE_FEATURE_ENABLED_MIN,
5398 CFG_ESE_FEATURE_ENABLED_MAX);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07005399 ret = -EINVAL;
5400 goto exit;
5401 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005402 if ((eseMode < CFG_ESE_FEATURE_ENABLED_MIN) ||
5403 (eseMode > CFG_ESE_FEATURE_ENABLED_MAX))
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07005404 {
5405 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005406 "Ese mode value %d is out of range"
5407 " (Min: %d Max: %d)", eseMode,
5408 CFG_ESE_FEATURE_ENABLED_MIN,
5409 CFG_ESE_FEATURE_ENABLED_MAX);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07005410 ret = -EINVAL;
5411 goto exit;
5412 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07005413 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005414 "%s: Received Command to change ese mode = %d", __func__, eseMode);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07005415
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005416 pHddCtx->cfg_ini->isEseIniFeatureEnabled = eseMode;
5417 sme_UpdateIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal), eseMode);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07005418 }
5419#endif
Srinivas Girigowda100eb322013-03-15 16:48:20 -07005420 else if (strncmp(command, "SETROAMSCANCONTROL", 18) == 0)
5421 {
5422 tANI_U8 *value = command;
5423 tANI_BOOLEAN roamScanControl = 0;
5424
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05305425 ret = hdd_drv_cmd_validate(command, 18);
5426 if (ret)
5427 goto exit;
5428
Srinivas Girigowda100eb322013-03-15 16:48:20 -07005429 /* Move pointer to ahead of SETROAMSCANCONTROL<delimiter> */
5430 value = value + 19;
5431 /* Convert the value from ascii to integer */
5432 ret = kstrtou8(value, 10, &roamScanControl);
5433 if (ret < 0)
5434 {
5435 /* If the input value is greater than max value of datatype, then also
5436 kstrtou8 fails */
5437 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5438 "%s: kstrtou8 failed ", __func__);
5439 ret = -EINVAL;
5440 goto exit;
5441 }
5442
5443 if (0 != roamScanControl)
5444 {
5445 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5446 "roam scan control invalid value = %d",
5447 roamScanControl);
5448 ret = -EINVAL;
5449 goto exit;
5450 }
5451 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
5452 "%s: Received Command to Set roam scan control = %d", __func__, roamScanControl);
5453
5454 sme_SetRoamScanControl((tHalHandle)(pHddCtx->hHal), roamScanControl);
5455 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07005456#ifdef FEATURE_WLAN_OKC
5457 else if (strncmp(command, "SETOKCMODE", 10) == 0)
5458 {
5459 tANI_U8 *value = command;
5460 tANI_U8 okcMode = CFG_OKC_FEATURE_ENABLED_DEFAULT;
5461
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05305462 ret = hdd_drv_cmd_validate(command, 10);
5463 if (ret)
5464 goto exit;
5465
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005466 /* Check if the features OKC/ESE/11R are supported simultaneously,
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07005467 then this operation is not permitted (return FAILURE) */
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005468 if (sme_getIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal)) &&
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07005469 hdd_is_okc_mode_enabled(pHddCtx) &&
5470 sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal)))
5471 {
5472 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005473 "%s: OKC/ESE/11R are supported simultaneously"
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07005474 " hence this operation is not permitted!", __func__);
5475 ret = -EPERM;
5476 goto exit;
5477 }
5478
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07005479 /* Move pointer to ahead of SETOKCMODE<delimiter> */
5480 value = value + 11;
5481 /* Convert the value from ascii to integer */
5482 ret = kstrtou8(value, 10, &okcMode);
5483 if (ret < 0)
5484 {
5485 /* If the input value is greater than max value of datatype, then also
5486 kstrtou8 fails */
5487 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5488 "%s: kstrtou8 failed range [%d - %d]", __func__,
5489 CFG_OKC_FEATURE_ENABLED_MIN,
5490 CFG_OKC_FEATURE_ENABLED_MAX);
5491 ret = -EINVAL;
5492 goto exit;
5493 }
5494
5495 if ((okcMode < CFG_OKC_FEATURE_ENABLED_MIN) ||
5496 (okcMode > CFG_OKC_FEATURE_ENABLED_MAX))
5497 {
5498 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5499 "Okc mode value %d is out of range"
5500 " (Min: %d Max: %d)", okcMode,
5501 CFG_OKC_FEATURE_ENABLED_MIN,
5502 CFG_OKC_FEATURE_ENABLED_MAX);
5503 ret = -EINVAL;
5504 goto exit;
5505 }
5506
5507 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
5508 "%s: Received Command to change okc mode = %d", __func__, okcMode);
5509
5510 pHddCtx->cfg_ini->isOkcIniFeatureEnabled = okcMode;
5511 }
Srinivas Girigowdaad34ca92013-10-22 10:54:29 -07005512#endif /* FEATURE_WLAN_OKC */
Mahesh A Saptasagarec7d1092015-04-02 13:41:34 +05305513 else if (strncmp(command, "GETROAMSCANCONTROL", 18) == 0)
Srinivas Girigowda100eb322013-03-15 16:48:20 -07005514 {
5515 tANI_BOOLEAN roamScanControl = sme_GetRoamScanControl((tHalHandle)(pHddCtx->hHal));
5516 char extra[32];
5517 tANI_U8 len = 0;
5518
Sameer Thalappilb0a30232013-09-27 15:37:48 -07005519 len = scnprintf(extra, sizeof(extra), "%s %d",
5520 command, roamScanControl);
Ratnam Rachuri083ada82015-08-07 14:01:05 +05305521 len = VOS_MIN(priv_data.total_len, len + 1);
5522 if (copy_to_user(priv_data.buf, &extra, len)) {
Srinivas Girigowda100eb322013-03-15 16:48:20 -07005523 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5524 "%s: failed to copy data to user buffer", __func__);
5525 ret = -EFAULT;
5526 goto exit;
5527 }
5528 }
Gopichand Nakkala227c7f32013-06-26 22:44:57 +05305529#ifdef WLAN_FEATURE_PACKET_FILTERING
5530 else if (strncmp(command, "ENABLE_PKTFILTER_IPV6", 21) == 0)
5531 {
5532 tANI_U8 filterType = 0;
5533 tANI_U8 *value = command;
5534
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05305535 ret = hdd_drv_cmd_validate(command, 21);
5536 if (ret)
5537 goto exit;
5538
Gopichand Nakkala227c7f32013-06-26 22:44:57 +05305539 /* Move pointer to ahead of ENABLE_PKTFILTER_IPV6<delimiter> */
5540 value = value + 22;
5541
5542 /* Convert the value from ascii to integer */
5543 ret = kstrtou8(value, 10, &filterType);
5544 if (ret < 0)
5545 {
5546 /* If the input value is greater than max value of datatype,
5547 * then also kstrtou8 fails
5548 */
5549 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5550 "%s: kstrtou8 failed range ", __func__);
5551 ret = -EINVAL;
5552 goto exit;
5553 }
5554
5555 if (filterType != 0 && filterType != 1)
5556 {
5557 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5558 "%s: Accepted Values are 0 and 1 ", __func__);
5559 ret = -EINVAL;
5560 goto exit;
5561 }
5562 wlan_hdd_setIPv6Filter(WLAN_HDD_GET_CTX(pAdapter), filterType,
5563 pAdapter->sessionId);
5564 }
5565#endif
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05305566 else if (strncmp(command, "BTCOEXMODE", 10) == 0 )
5567 {
Kiet Lamad161252014-07-22 11:23:32 -07005568 char *dhcpPhase;
Satyanarayana Dash1faea4f2014-09-22 16:21:04 +05305569 int ret;
5570
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05305571 ret = hdd_drv_cmd_validate(command, 10);
5572 if (ret)
5573 goto exit;
5574
Kiet Lamad161252014-07-22 11:23:32 -07005575 dhcpPhase = command + 11;
5576 if ('1' == *dhcpPhase)
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05305577 {
Deepthi Gowribfd17132014-11-14 17:59:04 +05305578 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Kiet Lamad161252014-07-22 11:23:32 -07005579 FL("send DHCP START indication"));
c_hpothu9b781ba2013-12-30 20:57:45 +05305580
5581 pHddCtx->btCoexModeSet = TRUE;
Kiet Lamad161252014-07-22 11:23:32 -07005582
Satyanarayana Dash1faea4f2014-09-22 16:21:04 +05305583 ret = wlan_hdd_scan_abort(pAdapter);
5584 if (ret < 0)
5585 {
5586 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5587 FL("failed to abort existing scan %d"), ret);
5588 }
5589
Kiet Lamad161252014-07-22 11:23:32 -07005590 sme_DHCPStartInd(pHddCtx->hHal, pAdapter->device_mode,
5591 pAdapter->sessionId);
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05305592 }
Kiet Lamad161252014-07-22 11:23:32 -07005593 else if ('2' == *dhcpPhase)
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05305594 {
Deepthi Gowribfd17132014-11-14 17:59:04 +05305595 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Kiet Lamad161252014-07-22 11:23:32 -07005596 FL("send DHCP STOP indication"));
c_hpothu9b781ba2013-12-30 20:57:45 +05305597
5598 pHddCtx->btCoexModeSet = FALSE;
Kiet Lamad161252014-07-22 11:23:32 -07005599
5600 sme_DHCPStopInd(pHddCtx->hHal, pAdapter->device_mode,
5601 pAdapter->sessionId);
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05305602 }
5603 }
Jeff Johnsonf54df2c2013-07-24 11:43:39 -07005604 else if (strncmp(command, "SCAN-ACTIVE", 11) == 0)
5605 {
Abhishek Singh58749d62016-02-03 15:27:20 +05305606 hddLog(LOG1,
5607 FL("making default scan to ACTIVE"));
c_hpothudbefd3e2014-04-28 15:59:47 +05305608 pHddCtx->scan_info.scan_mode = eSIR_ACTIVE_SCAN;
Jeff Johnsonf54df2c2013-07-24 11:43:39 -07005609 }
5610 else if (strncmp(command, "SCAN-PASSIVE", 12) == 0)
5611 {
Abhishek Singh58749d62016-02-03 15:27:20 +05305612 hddLog(LOG1,
5613 FL("making default scan to PASSIVE"));
c_hpothudbefd3e2014-04-28 15:59:47 +05305614 pHddCtx->scan_info.scan_mode = eSIR_PASSIVE_SCAN;
Jeff Johnsonf54df2c2013-07-24 11:43:39 -07005615 }
Hanumantha Reddy Pothula212243c2013-08-01 17:28:31 +05305616 else if (strncmp(command, "GETDWELLTIME", 12) == 0)
5617 {
5618 hdd_config_t *pCfg = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
5619 char extra[32];
5620 tANI_U8 len = 0;
5621
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05305622 memset(extra, 0, sizeof(extra));
5623 ret = hdd_get_dwell_time(pCfg, command, extra, sizeof(extra), &len);
Ratnam Rachuri12d5d462015-08-07 14:10:23 +05305624 len = VOS_MIN(priv_data.total_len, len + 1);
5625 if (ret != 0 || copy_to_user(priv_data.buf, &extra, len)) {
Hanumantha Reddy Pothula212243c2013-08-01 17:28:31 +05305626 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5627 "%s: failed to copy data to user buffer", __func__);
5628 ret = -EFAULT;
5629 goto exit;
5630 }
5631 ret = len;
5632 }
5633 else if (strncmp(command, "SETDWELLTIME", 12) == 0)
5634 {
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05305635 ret = hdd_set_dwell_time(pAdapter, command);
Hanumantha Reddy Pothula212243c2013-08-01 17:28:31 +05305636 }
Dundi Ravitejaae5adf42018-04-23 20:44:47 +05305637 else if (strncmp(command, "BTCGETDWELLTIME", 15) == 0)
5638 {
5639 hdd_config_t *pCfg = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
5640 char extra[32];
5641 tANI_U8 len = 0;
5642
5643 if (hdd_drv_cmd_validate(command, 15)) {
5644 hddLog(LOGE, FL("Invalid driver command"));
5645 return -EINVAL;
5646 }
5647
5648 memset(extra, 0, sizeof(extra));
5649 ret = hdd_btc_get_dwell_time(pCfg, command, extra,
5650 sizeof(extra), &len);
5651 len = VOS_MIN(priv_data.total_len, len + 1);
5652 if (ret != 0 || copy_to_user(priv_data.buf, &extra, len)) {
5653 hddLog(LOGE, FL("Failed to copy data to user buffer"));
5654 ret = -EFAULT;
5655 goto exit;
5656 }
5657 ret = len;
5658 }
5659 else if (strncmp(command, "BTCSETDWELLTIME", 15) == 0)
5660 {
5661 if (hdd_drv_cmd_validate(command, 15)) {
5662 hddLog(LOGE, FL("Invalid driver command"));
5663 return -EINVAL;
5664 }
5665 ret = hdd_btc_set_dwell_time(pAdapter, command);
5666 }
5667#ifdef WLAN_AP_STA_CONCURRENCY
5668 else if (strncmp(command, "CONCGETDWELLTIME", 16) == 0)
5669 {
5670 hdd_config_t *pCfg = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
5671 char extra[32];
5672 tANI_U8 len = 0;
5673
5674 if (hdd_drv_cmd_validate(command, 16)) {
5675 hddLog(LOGE, FL("Invalid driver command"));
5676 return -EINVAL;
5677 }
5678
5679 memset(extra, 0, sizeof(extra));
5680 ret = hdd_conc_get_dwell_time(pCfg, command, extra,
5681 sizeof(extra), &len);
5682 len = VOS_MIN(priv_data.total_len, len + 1);
5683 if (ret != 0 || copy_to_user(priv_data.buf, &extra, len)) {
5684 hddLog(LOGE, FL("Failed to copy data to user buffer"));
5685 ret = -EFAULT;
5686 goto exit;
5687 }
5688 ret = len;
5689 }
5690 else if (strncmp(command, "CONCSETDWELLTIME", 16) == 0)
5691 {
5692 if (hdd_drv_cmd_validate(command, 16)) {
5693 hddLog(LOGE, FL("Invalid driver command"));
5694 return -EINVAL;
5695 }
5696 ret = hdd_conc_set_dwell_time(pAdapter, command);
5697 }
5698#endif
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07005699 else if ( strncasecmp(command, "MIRACAST", 8) == 0 )
5700 {
5701 tANI_U8 filterType = 0;
5702 tANI_U8 *value;
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05305703
5704 ret = hdd_drv_cmd_validate(command, 8);
5705 if (ret)
5706 goto exit;
5707
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07005708 value = command + 9;
5709
5710 /* Convert the value from ascii to integer */
5711 ret = kstrtou8(value, 10, &filterType);
5712 if (ret < 0)
5713 {
5714 /* If the input value is greater than max value of datatype,
5715 * then also kstrtou8 fails
5716 */
5717 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5718 "%s: kstrtou8 failed range ", __func__);
5719 ret = -EINVAL;
5720 goto exit;
5721 }
5722 if ((filterType < WLAN_HDD_DRIVER_MIRACAST_CFG_MIN_VAL ) ||
5723 (filterType > WLAN_HDD_DRIVER_MIRACAST_CFG_MAX_VAL))
5724 {
5725 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5726 "%s: Accepted Values are 0 to 2. 0-Disabled, 1-Source,"
5727 " 2-Sink ", __func__);
5728 ret = -EINVAL;
5729 goto exit;
5730 }
5731 //Filtertype value should be either 0-Disabled, 1-Source, 2-sink
5732 pHddCtx->drvr_miracast = filterType;
Kaushik, Sushant96122442014-10-21 16:40:18 +05305733 pScanInfo = &pHddCtx->scan_info;
5734 if (filterType && pScanInfo != NULL &&
5735 pHddCtx->scan_info.mScanPending)
5736 {
5737 /*Miracast Session started. Abort Scan */
5738 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
5739 "%s, Aborting Scan For Miracast",__func__);
5740 hdd_abort_mac_scan(pHddCtx, pScanInfo->sessionId,
5741 eCSR_SCAN_ABORT_DEFAULT);
5742 }
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07005743 hdd_tx_rx_pkt_cnt_stat_timer_handler(pHddCtx);
Ganesh Kondabattini8f6e3b32014-08-25 16:07:54 +05305744 sme_SetMiracastMode(pHddCtx->hHal, pHddCtx->drvr_miracast);
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07005745 }
Leo Chang614d2072013-08-22 14:59:44 -07005746 else if (strncmp(command, "SETMCRATE", 9) == 0)
5747 {
Leo Chang614d2072013-08-22 14:59:44 -07005748 tANI_U8 *value = command;
5749 int targetRate;
Leo Chang1f98cbd2013-10-17 15:03:52 -07005750 tSirRateUpdateInd *rateUpdate;
5751 eHalStatus status;
Leo Chang614d2072013-08-22 14:59:44 -07005752
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05305753 ret = hdd_drv_cmd_validate(command, 9);
5754 if (ret)
5755 goto exit;
5756
Leo Chang614d2072013-08-22 14:59:44 -07005757 /* Only valid for SAP mode */
5758 if (WLAN_HDD_SOFTAP != pAdapter->device_mode)
5759 {
5760 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5761 "%s: SAP mode is not running", __func__);
5762 ret = -EFAULT;
5763 goto exit;
5764 }
5765
5766 /* Move pointer to ahead of SETMCRATE<delimiter> */
5767 /* input value is in units of hundred kbps */
5768 value = value + 10;
5769 /* Convert the value from ascii to integer, decimal base */
5770 ret = kstrtouint(value, 10, &targetRate);
5771
Leo Chang1f98cbd2013-10-17 15:03:52 -07005772 rateUpdate = (tSirRateUpdateInd *)vos_mem_malloc(sizeof(tSirRateUpdateInd));
5773 if (NULL == rateUpdate)
Leo Chang614d2072013-08-22 14:59:44 -07005774 {
Leo Chang1f98cbd2013-10-17 15:03:52 -07005775 hddLog(VOS_TRACE_LEVEL_ERROR,
5776 "%s: SETMCRATE indication alloc fail", __func__);
5777 ret = -EFAULT;
5778 goto exit;
5779 }
5780 vos_mem_zero(rateUpdate, sizeof(tSirRateUpdateInd ));
5781
5782 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
5783 "MC Target rate %d", targetRate);
5784 /* Ignore unicast */
5785 rateUpdate->ucastDataRate = -1;
5786 rateUpdate->mcastDataRate24GHz = targetRate;
5787 rateUpdate->mcastDataRate5GHz = targetRate;
5788 rateUpdate->mcastDataRate24GHzTxFlag = 0;
5789 rateUpdate->mcastDataRate5GHzTxFlag = 0;
5790 status = sme_SendRateUpdateInd(pHddCtx->hHal, rateUpdate);
5791 if (eHAL_STATUS_SUCCESS != status)
5792 {
5793 hddLog(VOS_TRACE_LEVEL_ERROR,
5794 "%s: SET_MC_RATE failed", __func__);
5795 vos_mem_free(rateUpdate);
5796 ret = -EFAULT;
5797 goto exit;
Leo Chang614d2072013-08-22 14:59:44 -07005798 }
5799 }
jge35567202017-06-21 16:39:38 +08005800 else if (strncmp(command, "MAXTXPOWER", 10) == 0)
5801 {
5802 int status;
5803 int txPower;
5804 eHalStatus smeStatus;
5805 tANI_U8 *value = command;
5806 tSirMacAddr bssid = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
5807 tSirMacAddr selfMac = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
5808
5809 status = hdd_parse_setmaxtxpower_command(value, &txPower);
5810 if (status)
5811 {
5812 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5813 "Invalid MAXTXPOWER command ");
5814 ret = -EINVAL;
5815 goto exit;
5816 }
5817
5818 hddLog(VOS_TRACE_LEVEL_INFO, "max tx power %d selfMac: "
5819 MAC_ADDRESS_STR " bssId: " MAC_ADDRESS_STR " ",
5820 txPower, MAC_ADDR_ARRAY(selfMac),
5821 MAC_ADDR_ARRAY(bssid));
5822 smeStatus = sme_SetMaxTxPower((tHalHandle)(pHddCtx->hHal),
5823 bssid, selfMac, txPower) ;
5824 if( smeStatus != eHAL_STATUS_SUCCESS )
5825 {
5826 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:Set max tx power failed",
5827 __func__);
5828 ret = -EINVAL;
5829 goto exit;
5830 }
5831
5832 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Set max tx power success",
5833 __func__);
5834 }
Rajeev79dbe4c2013-10-05 11:03:42 +05305835#ifdef FEATURE_WLAN_BATCH_SCAN
Rajeev Kumar8b373292014-01-08 20:36:55 -08005836 else if (strncmp(command, "WLS_BATCHING", 12) == 0)
Rajeev79dbe4c2013-10-05 11:03:42 +05305837 {
Rajeev Kumar8b373292014-01-08 20:36:55 -08005838 ret = hdd_handle_batch_scan_ioctl(pAdapter, &priv_data, command);
Rajeev79dbe4c2013-10-05 11:03:42 +05305839 }
5840#endif
Abhishek Singh00b71972016-01-07 10:51:04 +05305841#ifdef WLAN_FEATURE_RMC
5842 else if ((strncasecmp(command, "SETIBSSBEACONOUIDATA", 20) == 0) &&
5843 (WLAN_HDD_IBSS == pAdapter->device_mode))
5844 {
5845 int i = 0;
5846 tANI_U8 *ibss_ie;
5847 tANI_U32 command_len;
5848 tANI_U8 *value = command;
5849 tHalHandle hHal = pHddCtx->hHal;
5850 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
5851 tANI_U32 ibss_ie_length;
5852 tANI_U32 len, present;
5853 tANI_U8 *addIE;
5854 tANI_U8 *addIEData;
5855
5856 hddLog(LOG1,
5857 FL(" received command %s"),((char *) value));
5858 /* validate argument of command */
5859 if (strlen(value) <= 21)
5860 {
5861 hddLog(LOGE,
5862 FL("No arguements in command length %zu"), strlen(value));
5863 ret = -EFAULT;
5864 goto exit;
5865 }
5866
5867 /* moving to arguments of commands */
5868 value = value + 21;
5869 command_len = strlen(value);
5870
5871 /* oui_data can't be less than 3 bytes */
5872 if (command_len <= (2 * WLAN_HDD_IBSS_MIN_OUI_DATA_LENGTH))
5873 {
5874 hddLog(LOGE,
5875 FL("Invalid SETIBSSBEACONOUIDATA command length %d"),
5876 command_len);
5877 ret = -EFAULT;
5878 goto exit;
5879 }
5880 ibss_ie = vos_mem_malloc(command_len);
5881 if (!ibss_ie) {
5882 hddLog(LOGE,
5883 FL("Could not allocate memory for command length %d"),
5884 command_len);
5885 ret = -ENOMEM;
5886 goto exit;
5887 }
5888 vos_mem_zero(ibss_ie, command_len);
5889
5890 ibss_ie_length = hdd_parse_set_ibss_oui_data_command(value, ibss_ie,
5891 command_len);
5892 if (ibss_ie_length < (2 * WLAN_HDD_IBSS_MIN_OUI_DATA_LENGTH)) {
5893 hddLog(LOGE, FL("Could not parse command %s return length %d"),
5894 value, ibss_ie_length);
5895 ret = -EFAULT;
5896 vos_mem_free(ibss_ie);
5897 goto exit;
5898 }
5899
5900 hddLog(LOG1, FL("ibss_ie length %d ibss_ie:"), ibss_ie_length);
5901 while (i < ibss_ie_length)
5902 hddLog(LOG1, FL("0x%x"), ibss_ie[i++]);
5903
5904 /* Populate Vendor IE in Beacon */
5905 if ((ccmCfgGetInt(hHal,
5906 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG,
5907 &present)) != eHAL_STATUS_SUCCESS)
5908 {
5909 hddLog(LOGE,
5910 FL("unable to ftch WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG"));
5911 ret = -EFAULT;
5912 vos_mem_free(ibss_ie);
5913 goto exit;
5914 }
5915
5916 addIE = vos_mem_malloc(WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA_LEN);
5917 if (!addIE) {
5918 hddLog(LOGE,
5919 FL("Could not allocate memory for command length %d"),
5920 command_len);
5921 vos_mem_free(ibss_ie);
5922 ret = -ENOMEM;
5923 goto exit;
5924 }
5925 vos_mem_zero(addIE, WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA_LEN);
5926
5927 if (present)
5928 {
5929 if ((wlan_cfgGetStrLen(pMac,
5930 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, &len)) != eSIR_SUCCESS)
5931 {
5932 hddLog(LOGE,
5933 FL("unable to fetch WNI_CFG_PROBE_RSP_BCN_ADDNIE_LEN"));
5934 ret = -EFAULT;
5935 vos_mem_free(ibss_ie);
5936 vos_mem_free(addIE);
5937 goto exit;
5938 }
5939
5940 if (len <= WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA_LEN && len &&
5941 ((len + ibss_ie_length) <=
5942 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA_LEN))
5943 {
5944 if ((ccmCfgGetStr(hHal,
5945 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, addIE, &len))
5946 != eHAL_STATUS_SUCCESS)
5947 {
5948 hddLog(LOGE,
5949 FL("unable to fetch WNI_PROBE_RSP_BCN_ADDNIE_DATA"));
5950 ret = -EFAULT;
5951 vos_mem_free(ibss_ie);
5952 vos_mem_free(addIE);
5953 goto exit;
5954 }
5955 else
5956 {
5957 /* Curruntly only WPA IE is added before Vendor IE
5958 * so we can blindly place the Vendor IE after WPA
5959 * IE. If no WPA IE found replace all with Vendor IE.
5960 */
5961 len = hdd_find_ibss_wpa_ie_pos(addIE, len);
5962 }
5963 }
5964 else
5965 {
5966 hddLog(LOGE,
5967 FL("IE len exceed limit len %d,ibss_ie_length %d "),
5968 len, ibss_ie_length);
5969 ret = -EFAULT;
5970 vos_mem_free(addIE);
5971 vos_mem_free(ibss_ie);
5972 goto exit;
5973 }
5974 }
5975 else {
5976 len = 0;
5977 }
5978
5979 vos_mem_copy (addIE + len , ibss_ie, ibss_ie_length);
5980 len += ibss_ie_length;
5981
5982 if (ccmCfgSetStr(hHal,
5983 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, addIE, len, NULL,
5984 eANI_BOOLEAN_FALSE) != eHAL_STATUS_SUCCESS)
5985 {
5986 hddLog(LOGE,
5987 FL("unable to set WNI_CFG_PRBE_RSP_BCN_ADDNIE_DATA"));
5988 ret = -EFAULT;
5989 vos_mem_free(ibss_ie);
5990 vos_mem_free(addIE);
5991 goto exit;
5992 }
5993 vos_mem_free(addIE);
5994 if (ccmCfgSetInt(hHal,
5995 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 1,NULL,
5996 eANI_BOOLEAN_FALSE) != eHAL_STATUS_SUCCESS)
5997 {
5998 hddLog(LOGE,
5999 FL("unble to set WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG"));
6000 ret = -EFAULT;
6001 vos_mem_free(ibss_ie);
6002 goto exit;
6003 }
6004
6005 /* Populate Vendor IE in probe resp */
6006 if ((ccmCfgGetInt(hHal,
6007 WNI_CFG_PROBE_RSP_ADDNIE_FLAG,
6008 &present)) != eHAL_STATUS_SUCCESS)
6009 {
6010 hddLog(LOGE,
6011 FL("unable to fetch WNI_CFG_PROBE_RSP_ADDNIE_FLAG"));
6012 ret = -EFAULT;
6013 vos_mem_free(ibss_ie);
6014 goto exit;
6015 }
6016
6017 addIEData = vos_mem_malloc(WNI_CFG_PROBE_RSP_ADDNIE_DATA1_LEN);
6018 if (!addIEData) {
6019 hddLog(LOGE,
6020 FL("Could not allocate memory for command length %d"),
6021 command_len);
6022 vos_mem_free(ibss_ie);
6023 ret = -ENOMEM;
6024 goto exit;
6025 }
6026 vos_mem_zero(addIEData, WNI_CFG_PROBE_RSP_ADDNIE_DATA1_LEN);
6027
6028 if (present) {
6029 if (eSIR_SUCCESS != wlan_cfgGetStrLen(pMac,
6030 WNI_CFG_PROBE_RSP_ADDNIE_DATA1, &len)) {
6031 hddLog(LOGE,
6032 FL("unable to fetch WNI_CFG_PROBE_RSP_ADDNIE_DATA1"));
6033 ret = -EFAULT;
6034 vos_mem_free(ibss_ie);
6035 vos_mem_free(addIEData);
6036 goto exit;
6037 }
6038 if (len < WNI_CFG_PROBE_RSP_ADDNIE_DATA1_LEN && len &&
6039 (ibss_ie_length + len) <=
6040 WNI_CFG_PROBE_RSP_ADDNIE_DATA1_LEN) {
6041
6042 if ((ccmCfgGetStr(hHal,
6043 WNI_CFG_PROBE_RSP_ADDNIE_DATA1, addIEData, &len))
6044 != eHAL_STATUS_SUCCESS) {
6045 hddLog(LOGE,
6046 FL("unable fetch WNI_CFG_PROBE_RSP_ADDNIE_DATA1"));
6047 ret = -EFAULT;
6048 vos_mem_free(ibss_ie);
6049 vos_mem_free(addIEData);
6050 goto exit;
6051 }
6052 else {
6053 /* Curruntly only WPA IE is added before Vendor IE
6054 * so we can blindly place the Vendor IE after WPA
6055 * IE. If no WPA IE found replace all with Vendor IE.
6056 */
6057 len = hdd_find_ibss_wpa_ie_pos(addIEData, len);
6058 }
6059 }
6060 else
6061 {
6062 hddLog(LOGE,
6063 FL("IE len exceed limit len %d,ibss_ie_length %d "),
6064 len, ibss_ie_length);
6065 ret = -EFAULT;
6066 vos_mem_free(addIEData);
6067 vos_mem_free(ibss_ie);
6068 goto exit;
6069 }
6070 } /* probe rsp ADD IE present */
6071 else {
6072 /* probe rsp add IE is not present */
6073 len = 0;
6074 }
6075
6076 vos_mem_copy(addIEData +len , ibss_ie, ibss_ie_length);
6077 len += ibss_ie_length;
6078
6079 vos_mem_free(ibss_ie);
6080
6081 if (ccmCfgSetStr(hHal,
6082 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,
6083 (tANI_U8*)(addIEData),
6084 len, NULL,
6085 eANI_BOOLEAN_FALSE)
6086 == eHAL_STATUS_FAILURE) {
6087 hddLog(LOGE,
6088 FL("unable to copy to WNI_CFG_PROBE_RSP_ADDNIE_DATA1"));
6089 ret = -EFAULT;
6090 vos_mem_free(addIEData);
6091 goto exit;
6092 }
6093 vos_mem_free(addIEData);
6094 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
6095 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 1,NULL,
6096 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
6097 {
6098 hddLog(LOGE,
6099 FL("unable to copy WNI_CFG_PROBE_RSP_ADDNIE_FLAG"));
6100 ret = -EFAULT;
6101 goto exit;
6102 }
6103 }
6104 else if (strncasecmp(command, "SETRMCENABLE", 12) == 0)
6105 {
6106 tANI_U8 *value = command;
6107 tANI_U8 ucRmcEnable = 0;
6108 int status;
6109
6110 if ((WLAN_HDD_IBSS != pAdapter->device_mode) &&
6111 (WLAN_HDD_SOFTAP != pAdapter->device_mode))
6112 {
6113 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6114 "Received SETRMCENABLE command in invalid mode %d "
6115 "SETRMCENABLE command is only allowed in IBSS or SOFTAP mode",
6116 pAdapter->device_mode);
6117 ret = -EINVAL;
6118 goto exit;
6119 }
6120
6121 status = hdd_parse_setrmcenable_command(value, &ucRmcEnable);
6122 if (status)
6123 {
6124 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6125 "Invalid SETRMCENABLE command ");
6126 ret = -EINVAL;
6127 goto exit;
6128 }
6129
6130 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6131 "%s: ucRmcEnable %d ", __func__, ucRmcEnable);
6132
6133 if (TRUE == ucRmcEnable)
6134 {
6135 status = sme_EnableRMC( (tHalHandle)(pHddCtx->hHal),
6136 pAdapter->sessionId );
6137 }
6138 else if(FALSE == ucRmcEnable)
6139 {
6140 status = sme_DisableRMC( (tHalHandle)(pHddCtx->hHal),
6141 pAdapter->sessionId );
6142 }
6143 else
6144 {
6145 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6146 "Invalid SETRMCENABLE command %d", ucRmcEnable);
6147 ret = -EINVAL;
6148 goto exit;
6149 }
6150
6151 if (VOS_STATUS_SUCCESS != status)
6152 {
6153 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6154 "%s: SETRMC %d failed status %d", __func__, ucRmcEnable,
6155 status);
6156 ret = -EINVAL;
6157 goto exit;
6158 }
6159 }
6160 else if (strncasecmp(command, "SETRMCACTIONPERIOD", 18) == 0)
6161 {
6162 tANI_U8 *value = command;
6163 tANI_U32 uActionPeriod = 0;
6164 int status;
6165
6166 if ((WLAN_HDD_IBSS != pAdapter->device_mode) &&
6167 (WLAN_HDD_SOFTAP != pAdapter->device_mode))
6168 {
6169 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6170 "Received SETRMC command in invalid mode %d "
6171 "SETRMC command is only allowed in IBSS or SOFTAP mode",
6172 pAdapter->device_mode);
6173 ret = -EINVAL;
6174 goto exit;
6175 }
6176
6177 status = hdd_parse_setrmcactionperiod_command(value, &uActionPeriod);
6178 if (status)
6179 {
6180 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6181 "Invalid SETRMCACTIONPERIOD command ");
6182 ret = -EINVAL;
6183 goto exit;
6184 }
6185
6186 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6187 "%s: uActionPeriod %d ", __func__, uActionPeriod);
6188
6189 if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_RMC_ACTION_PERIOD_FREQUENCY,
6190 uActionPeriod, NULL, eANI_BOOLEAN_FALSE))
6191 {
6192 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6193 "%s: Could not set SETRMCACTIONPERIOD %d", __func__, uActionPeriod);
6194 ret = -EINVAL;
6195 goto exit;
6196 }
6197
6198 }
6199 else if (strncasecmp(command, "GETIBSSPEERINFOALL", 18) == 0)
6200 {
6201 /* Peer Info All Command */
6202 int status = eHAL_STATUS_SUCCESS;
6203 hdd_station_ctx_t *pHddStaCtx = NULL;
6204 char *extra = NULL;
6205 int idx = 0, length = 0;
6206 v_MACADDR_t *macAddr;
6207 v_U32_t txRateMbps = 0, numOfBytestoPrint = 0;
6208
6209 if (WLAN_HDD_IBSS == pAdapter->device_mode)
6210 {
6211 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
6212 }
6213 else
6214 {
6215 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6216 "%s: pAdapter is not valid for this device mode",
6217 __func__);
6218 ret = -EINVAL;
6219 goto exit;
6220 }
6221
6222 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6223 "%s: Received GETIBSSPEERINFOALL Command", __func__);
6224
6225
6226 /* Handle the command */
6227 status = hdd_cfg80211_get_ibss_peer_info_all(pAdapter);
6228 if (VOS_STATUS_SUCCESS == status)
6229 {
6230 /* The variable extra needed to be allocated on the heap since
6231 * amount of memory required to copy the data for 32 devices
6232 * exceeds the size of 1024 bytes of default stack size. On
6233 * 64 bit devices, the default max stack size of 2048 bytes
6234 */
6235 extra = kmalloc(WLAN_MAX_BUF_SIZE, GFP_KERNEL);
6236
6237 if (NULL == extra)
6238 {
6239 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6240 "%s:kmalloc failed", __func__);
6241 ret = -EINVAL;
6242 goto exit;
6243 }
6244
6245 /* Copy number of stations */
6246 length = scnprintf( extra, WLAN_MAX_BUF_SIZE, "%d ",
6247 pHddStaCtx->ibss_peer_info.numIBSSPeers);
6248 numOfBytestoPrint = length;
6249 for (idx = 0; idx < pHddStaCtx->ibss_peer_info.numIBSSPeers; idx++)
6250 {
6251 macAddr =
6252 hdd_wlan_get_ibss_mac_addr_from_staid(pAdapter,
6253 pHddStaCtx->ibss_peer_info.ibssPeerList[idx].staIdx);
6254 if (NULL != macAddr)
6255 {
6256 txRateMbps =
6257 ((pHddStaCtx->ibss_peer_info.ibssPeerList[idx].txRate)*500*1000)/1000000;
6258
6259 length += scnprintf( (extra + length), WLAN_MAX_BUF_SIZE - length,
6260 "%02x:%02x:%02x:%02x:%02x:%02x %d %d ",
6261 macAddr->bytes[0], macAddr->bytes[1], macAddr->bytes[2],
6262 macAddr->bytes[3], macAddr->bytes[4], macAddr->bytes[5],
6263 (int)txRateMbps,
6264 (int)pHddStaCtx->ibss_peer_info.ibssPeerList[idx].rssi);
6265 }
6266 else
6267 {
6268 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6269 "%s: MAC ADDR is NULL for staIdx: %d", __func__,
6270 pHddStaCtx->ibss_peer_info.ibssPeerList[idx].staIdx);
6271 }
6272
6273 /*
6274 * VOS_TRACE() macro has limitation of 512 bytes for the print
6275 * buffer. Hence printing the data in two chunks. The first chunk
6276 * will have the data for 16 devices and the second chunk will
6277 * have the rest.
6278 */
6279 if (idx < NUM_OF_STA_DATA_TO_PRINT)
6280 {
6281 numOfBytestoPrint = length;
6282 }
6283 }
6284
6285 /*
6286 * Copy the data back into buffer, if the data to copy is
6287 * morethan 512 bytes than we will split the data and do
6288 * it in two shots
6289 */
6290 if (copy_to_user(priv_data.buf, extra, numOfBytestoPrint))
6291 {
6292 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6293 "%s: Copy into user data buffer failed ", __func__);
6294 ret = -EFAULT;
6295 kfree(extra);
6296 goto exit;
6297 }
6298 priv_data.buf[numOfBytestoPrint] = '\0';
6299 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_MED,
6300 "%s", priv_data.buf);
6301
6302 if (length > numOfBytestoPrint)
6303 {
6304 if (copy_to_user(priv_data.buf + numOfBytestoPrint,
6305 extra + numOfBytestoPrint,
6306 length - numOfBytestoPrint + 1))
6307 {
6308 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6309 "%s: Copy into user data buffer failed ", __func__);
6310 ret = -EFAULT;
6311 kfree(extra);
6312 goto exit;
6313 }
6314 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_MED,
6315 "%s", &priv_data.buf[numOfBytestoPrint]);
6316 }
6317
6318 /* Free temporary buffer */
6319 kfree(extra);
6320 }
6321
6322 else
6323 {
6324 /* Command failed, log error */
6325 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6326 "%s: GETIBSSPEERINFOALL command failed with status code %d",
6327 __func__, status);
6328 ret = -EINVAL;
6329 goto exit;
6330 }
6331 ret = 0;
6332 }
6333 else if(strncasecmp(command, "GETIBSSPEERINFO", 15) == 0)
6334 {
6335 /* Peer Info <Peer Addr> command */
6336 tANI_U8 *value = command;
6337 VOS_STATUS status;
6338 hdd_station_ctx_t *pHddStaCtx = NULL;
6339 char extra[128] = { 0 };
6340 v_U32_t length = 0;
6341 v_U8_t staIdx = 0;
6342 v_U32_t txRateMbps = 0;
6343 v_MACADDR_t peerMacAddr;
6344
6345 if (WLAN_HDD_IBSS == pAdapter->device_mode)
6346 {
6347 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
6348 }
6349 else
6350 {
6351 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6352 "%s: pAdapter is not valid for this device mode",
6353 __func__);
6354 ret = -EINVAL;
6355 goto exit;
6356 }
6357
6358 /* if there are no peers, no need to continue with the command */
6359 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6360 "%s: Received GETIBSSPEERINFO Command", __func__);
6361
6362 if (eConnectionState_IbssConnected != pHddStaCtx->conn_info.connState)
6363 {
6364 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6365 "%s:No IBSS Peers coalesced", __func__);
6366 ret = -EINVAL;
6367 goto exit;
6368 }
6369
6370 /* Parse the incoming command buffer */
6371 status = hdd_parse_get_ibss_peer_info(value, &peerMacAddr);
6372 if (VOS_STATUS_SUCCESS != status)
6373 {
6374 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6375 "%s: Invalid GETIBSSPEERINFO command", __func__);
6376 ret = -EINVAL;
6377 goto exit;
6378 }
6379
6380 /* Get station index for the peer mac address */
6381 hdd_Ibss_GetStaId(pHddStaCtx, &peerMacAddr, &staIdx);
6382
6383 if (staIdx > HDD_MAX_NUM_IBSS_STA)
6384 {
6385 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6386 "%s: Invalid StaIdx %d returned", __func__, staIdx);
6387 ret = -EINVAL;
6388 goto exit;
6389 }
6390
6391 /* Handle the command */
6392 status = hdd_cfg80211_get_ibss_peer_info(pAdapter, staIdx);
6393 if (VOS_STATUS_SUCCESS == status)
6394 {
6395 v_U32_t txRate = pHddStaCtx->ibss_peer_info.ibssPeerList[0].txRate;
6396 txRateMbps = (txRate * 500 * 1000)/1000000;
6397
6398 length = scnprintf( extra, sizeof(extra), "%d %d", (int)txRateMbps,
6399 (int)pHddStaCtx->ibss_peer_info.ibssPeerList[0].rssi);
6400
6401 /* Copy the data back into buffer */
6402 if (copy_to_user(priv_data.buf, &extra, length+ 1))
6403 {
6404 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6405 "%s: copy data to user buffer failed GETIBSSPEERINFO command",
6406 __func__);
6407 ret = -EFAULT;
6408 goto exit;
6409 }
6410 }
6411 else
6412 {
6413 /* Command failed, log error */
6414 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6415 "%s: GETIBSSPEERINFO command failed with status code %d",
6416 __func__, status);
6417 ret = -EINVAL;
6418 goto exit;
6419 }
6420
6421 /* Success ! */
6422 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_MED,
6423 "%s", priv_data.buf);
6424 ret = 0;
6425 }
6426 else if (strncasecmp(command, "SETRMCTXRATE", 12) == 0)
6427 {
6428 tANI_U8 *value = command;
6429 tANI_U32 uRate = 0;
6430 tTxrateinfoflags txFlags = 0;
6431 tSirRateUpdateInd *rateUpdateParams;
6432 int status;
6433
6434 if ((WLAN_HDD_IBSS != pAdapter->device_mode) &&
6435 (WLAN_HDD_SOFTAP != pAdapter->device_mode))
6436 {
6437 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6438 "Received SETRMCTXRATE command in invalid mode %d "
6439 "SETRMC command is only allowed in IBSS or SOFTAP mode",
6440 pAdapter->device_mode);
6441 ret = -EINVAL;
6442 goto exit;
6443 }
6444
6445 status = hdd_parse_setrmcrate_command(value, &uRate, &txFlags);
6446 if (status)
6447 {
6448 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6449 "Invalid SETRMCTXRATE command ");
6450 ret = -EINVAL;
6451 goto exit;
6452 }
6453
6454 rateUpdateParams = vos_mem_malloc(sizeof(tSirRateUpdateInd));
6455 if (NULL == rateUpdateParams)
6456 {
6457 ret = -EINVAL;
6458 goto exit;
6459 }
6460
6461 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6462 "%s: uRate %d ", __func__, uRate);
6463
6464 vos_mem_zero(rateUpdateParams, sizeof(tSirRateUpdateInd ));
6465
6466 /* -1 implies ignore this param */
6467 rateUpdateParams->ucastDataRate = -1;
6468
6469 /*
6470 * Fill the user specifieed RMC rate param
6471 * and the derived tx flags.
6472 */
6473 rateUpdateParams->rmcDataRate = uRate;
6474 rateUpdateParams->rmcDataRateTxFlag = txFlags;
6475
6476 status = sme_SendRateUpdateInd((tHalHandle)(pHddCtx->hHal), rateUpdateParams);
6477 }
6478 else if (strncasecmp(command, "SETIBSSTXFAILEVENT", 18) == 0 )
6479 {
6480 char *value;
6481 tANI_U8 tx_fail_count = 0;
6482 tANI_U16 pid = 0;
6483
6484 value = command;
6485
6486 ret = hdd_ParseIBSSTXFailEventParams(value, &tx_fail_count, &pid);
6487
6488 if (0 != ret)
6489 {
6490 hddLog(VOS_TRACE_LEVEL_INFO,
6491 "%s: Failed to parse SETIBSSTXFAILEVENT arguments",
6492 __func__);
6493 goto exit;
6494 }
6495
6496 hddLog(VOS_TRACE_LEVEL_INFO, "%s: tx_fail_cnt=%hhu, pid=%hu",
6497 __func__, tx_fail_count, pid);
6498
6499 if (0 == tx_fail_count)
6500 {
6501 // Disable TX Fail Indication
6502 if (eHAL_STATUS_SUCCESS ==
6503 sme_TXFailMonitorStartStopInd(pHddCtx->hHal,
6504 tx_fail_count,
6505 NULL))
6506 {
6507 cesium_pid = 0;
6508 }
6509 else
6510 {
6511 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6512 "%s: failed to disable TX Fail Event ", __func__);
6513 ret = -EINVAL;
6514 }
6515 }
6516 else
6517 {
6518 if (eHAL_STATUS_SUCCESS ==
6519 sme_TXFailMonitorStartStopInd(pHddCtx->hHal,
6520 tx_fail_count,
6521 (void*)hdd_tx_fail_ind_callback))
6522 {
6523 cesium_pid = pid;
6524 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6525 "%s: Registered Cesium pid %u", __func__,
6526 cesium_pid);
6527 }
6528 else
6529 {
6530 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6531 "%s: Failed to enable TX Fail Monitoring", __func__);
6532 ret = -EINVAL;
6533 }
6534 }
6535 }
6536
6537#endif /* WLAN_FEATURE_RMC */
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08006538#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07006539 else if (strncmp(command, "SETCCXROAMSCANCHANNELS", 22) == 0)
6540 {
6541 tANI_U8 *value = command;
6542 tANI_U8 ChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
6543 tANI_U8 numChannels = 0;
6544 eHalStatus status = eHAL_STATUS_SUCCESS;
6545
6546 status = hdd_parse_channellist(value, ChannelList, &numChannels);
6547 if (eHAL_STATUS_SUCCESS != status)
6548 {
6549 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6550 "%s: Failed to parse channel list information", __func__);
6551 ret = -EINVAL;
6552 goto exit;
6553 }
6554
6555 if (numChannels > WNI_CFG_VALID_CHANNEL_LIST_LEN)
6556 {
6557 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6558 "%s: number of channels (%d) supported exceeded max (%d)", __func__,
6559 numChannels, WNI_CFG_VALID_CHANNEL_LIST_LEN);
6560 ret = -EINVAL;
6561 goto exit;
6562 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08006563 status = sme_SetEseRoamScanChannelList((tHalHandle)(pHddCtx->hHal),
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07006564 ChannelList,
6565 numChannels);
6566 if (eHAL_STATUS_SUCCESS != status)
6567 {
6568 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6569 "%s: Failed to update channel list information", __func__);
6570 ret = -EINVAL;
6571 goto exit;
6572 }
6573 }
6574 else if (strncmp(command, "GETTSMSTATS", 11) == 0)
6575 {
6576 tANI_U8 *value = command;
6577 char extra[128] = {0};
6578 int len = 0;
6579 tANI_U8 tid = 0;
6580 hdd_station_ctx_t *pHddStaCtx = NULL;
6581 tAniTrafStrmMetrics tsmMetrics;
6582 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
6583
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05306584 ret = hdd_drv_cmd_validate(command, 11);
6585 if (ret)
6586 goto exit;
6587
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07006588 /* if not associated, return error */
6589 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
6590 {
6591 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "%s:Not associated!",__func__);
6592 ret = -EINVAL;
6593 goto exit;
6594 }
6595
6596 /* Move pointer to ahead of GETTSMSTATS<delimiter> */
6597 value = value + 12;
6598 /* Convert the value from ascii to integer */
6599 ret = kstrtou8(value, 10, &tid);
6600 if (ret < 0)
6601 {
6602 /* If the input value is greater than max value of datatype, then also
6603 kstrtou8 fails */
6604 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6605 "%s: kstrtou8 failed range [%d - %d]", __func__,
6606 TID_MIN_VALUE,
6607 TID_MAX_VALUE);
6608 ret = -EINVAL;
6609 goto exit;
6610 }
6611
6612 if ((tid < TID_MIN_VALUE) || (tid > TID_MAX_VALUE))
6613 {
6614 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6615 "tid value %d is out of range"
6616 " (Min: %d Max: %d)", tid,
6617 TID_MIN_VALUE,
6618 TID_MAX_VALUE);
6619 ret = -EINVAL;
6620 goto exit;
6621 }
6622
6623 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6624 "%s: Received Command to get tsm stats tid = %d", __func__, tid);
6625
6626 if (VOS_STATUS_SUCCESS != hdd_get_tsm_stats(pAdapter, tid, &tsmMetrics))
6627 {
6628 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6629 "%s: failed to get tsm stats", __func__);
6630 ret = -EFAULT;
6631 goto exit;
6632 }
6633
6634 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6635 "UplinkPktQueueDly(%d)\n"
6636 "UplinkPktQueueDlyHist[0](%d)\n"
6637 "UplinkPktQueueDlyHist[1](%d)\n"
6638 "UplinkPktQueueDlyHist[2](%d)\n"
6639 "UplinkPktQueueDlyHist[3](%d)\n"
Arun Kumar Khandavallie8768212014-02-17 16:43:34 +05306640 "UplinkPktTxDly(%u)\n"
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07006641 "UplinkPktLoss(%d)\n"
6642 "UplinkPktCount(%d)\n"
6643 "RoamingCount(%d)\n"
6644 "RoamingDly(%d)", tsmMetrics.UplinkPktQueueDly,
6645 tsmMetrics.UplinkPktQueueDlyHist[0],
6646 tsmMetrics.UplinkPktQueueDlyHist[1],
6647 tsmMetrics.UplinkPktQueueDlyHist[2],
6648 tsmMetrics.UplinkPktQueueDlyHist[3],
6649 tsmMetrics.UplinkPktTxDly, tsmMetrics.UplinkPktLoss,
6650 tsmMetrics.UplinkPktCount, tsmMetrics.RoamingCount, tsmMetrics.RoamingDly);
6651
6652 /* Output TSM stats is of the format
6653 GETTSMSTATS [PktQueueDly] [PktQueueDlyHist[0]]:[PktQueueDlyHist[1]] ...[RoamingDly]
6654 eg., GETTSMSTATS 10 1:0:0:161 20 1 17 8 39800 */
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08006655 len = scnprintf(extra, sizeof(extra), "%s %d %d:%d:%d:%d %u %d %d %d %d", command,
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07006656 tsmMetrics.UplinkPktQueueDly, tsmMetrics.UplinkPktQueueDlyHist[0],
6657 tsmMetrics.UplinkPktQueueDlyHist[1], tsmMetrics.UplinkPktQueueDlyHist[2],
6658 tsmMetrics.UplinkPktQueueDlyHist[3], tsmMetrics.UplinkPktTxDly,
6659 tsmMetrics.UplinkPktLoss, tsmMetrics.UplinkPktCount, tsmMetrics.RoamingCount,
6660 tsmMetrics.RoamingDly);
6661
Ratnam Rachurid53009c2015-08-07 13:59:00 +05306662 len = VOS_MIN(priv_data.total_len, len + 1);
6663 if (copy_to_user(priv_data.buf, &extra, len)) {
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07006664 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6665 "%s: failed to copy data to user buffer", __func__);
6666 ret = -EFAULT;
6667 goto exit;
6668 }
6669 }
6670 else if (strncmp(command, "SETCCKMIE", 9) == 0)
6671 {
6672 tANI_U8 *value = command;
6673 tANI_U8 *cckmIe = NULL;
6674 tANI_U8 cckmIeLen = 0;
6675 eHalStatus status = eHAL_STATUS_SUCCESS;
6676
6677 status = hdd_parse_get_cckm_ie(value, &cckmIe, &cckmIeLen);
6678 if (eHAL_STATUS_SUCCESS != status)
6679 {
6680 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6681 "%s: Failed to parse cckm ie data", __func__);
6682 ret = -EINVAL;
6683 goto exit;
6684 }
6685
6686 if (cckmIeLen > DOT11F_IE_RSN_MAX_LEN)
6687 {
6688 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6689 "%s: CCKM Ie input length is more than max[%d]", __func__,
6690 DOT11F_IE_RSN_MAX_LEN);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08006691 vos_mem_free(cckmIe);
6692 cckmIe = NULL;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07006693 ret = -EINVAL;
6694 goto exit;
6695 }
6696 sme_SetCCKMIe((tHalHandle)(pHddCtx->hHal), pAdapter->sessionId, cckmIe, cckmIeLen);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08006697 vos_mem_free(cckmIe);
6698 cckmIe = NULL;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07006699 }
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08006700 else if (strncmp(command, "CCXBEACONREQ", 12) == 0)
6701 {
6702 tANI_U8 *value = command;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08006703 tCsrEseBeaconReq eseBcnReq;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08006704 eHalStatus status = eHAL_STATUS_SUCCESS;
Srinivas Girigowda0c6d7fe2014-05-28 18:18:10 -07006705
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08006706 status = hdd_parse_ese_beacon_req(value, &eseBcnReq);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08006707 if (eHAL_STATUS_SUCCESS != status)
6708 {
6709 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08006710 "%s: Failed to parse ese beacon req", __func__);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08006711 ret = -EINVAL;
6712 goto exit;
6713 }
Srinivas Girigowda0c6d7fe2014-05-28 18:18:10 -07006714 if (!hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))) {
6715 hddLog(VOS_TRACE_LEVEL_INFO, FL("Not associated"));
6716 hdd_indicateEseBcnReportNoResults (pAdapter,
6717 eseBcnReq.bcnReq[0].measurementToken,
6718 0x02, //BIT(1) set for measurement done
6719 0); // no BSS
6720 goto exit;
6721 }
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08006722
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08006723 status = sme_SetEseBeaconRequest((tHalHandle)(pHddCtx->hHal), pAdapter->sessionId, &eseBcnReq);
6724 if (eHAL_STATUS_SUCCESS != status)
6725 {
6726 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6727 "%s: sme_SetEseBeaconRequest failed (%d)", __func__, status);
6728 ret = -EINVAL;
6729 goto exit;
6730 }
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08006731 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08006732#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
c_hpothu92367912014-05-01 15:18:17 +05306733 else if (strncmp(command, "GETBCNMISSRATE", 14) == 0)
6734 {
6735 eHalStatus status;
6736 char buf[32], len;
Hanumanth Reddy Pothula7aa4bea2018-04-09 17:19:03 +05306737 void *cookie;
6738 struct hdd_request *request;
6739 struct bcn_miss_rate_priv *priv;
6740 static const struct hdd_request_params params = {
6741 .priv_size = sizeof(*priv),
6742 .timeout_ms = WLAN_WAIT_TIME_STATS,
6743 };
c_hpothu92367912014-05-01 15:18:17 +05306744
6745 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
6746
6747 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
6748 {
6749 hddLog(VOS_TRACE_LEVEL_WARN,
6750 FL("GETBCNMISSRATE: STA is not in connected state"));
6751 ret = -1;
6752 goto exit;
6753 }
Hanumanth Reddy Pothula7aa4bea2018-04-09 17:19:03 +05306754 request = hdd_request_alloc(&params);
6755 if (!request) {
6756 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Request allocation failure"));
6757 ret = -ENOMEM;
6758 goto exit;
6759 }
6760 cookie = hdd_request_cookie(request);
6761 priv = hdd_request_priv(request);
6762 priv->bcn_miss_rate = -1;
c_hpothu92367912014-05-01 15:18:17 +05306763
6764 status = sme_getBcnMissRate((tHalHandle)(pHddCtx->hHal),
6765 pAdapter->sessionId,
Hanumanth Reddy Pothula7aa4bea2018-04-09 17:19:03 +05306766 (void *)get_bcn_miss_rate_cb,
6767 cookie);
c_hpothu92367912014-05-01 15:18:17 +05306768 if( eHAL_STATUS_SUCCESS != status)
6769 {
6770 hddLog(VOS_TRACE_LEVEL_INFO,
6771 FL("GETBCNMISSRATE: fail to post WDA cmd"));
6772 ret = -EINVAL;
Hanumanth Reddy Pothula7aa4bea2018-04-09 17:19:03 +05306773 goto free_bcn_miss_rate_req;
c_hpothu92367912014-05-01 15:18:17 +05306774 }
6775
Hanumanth Reddy Pothula7aa4bea2018-04-09 17:19:03 +05306776 ret = hdd_request_wait_for_response(request);
6777 if(ret)
c_hpothu92367912014-05-01 15:18:17 +05306778 {
6779 hddLog(VOS_TRACE_LEVEL_ERROR,
6780 FL("failed to wait on bcnMissRateComp %d"), ret);
6781
c_hpothu92367912014-05-01 15:18:17 +05306782 ret = -EINVAL;
Hanumanth Reddy Pothula7aa4bea2018-04-09 17:19:03 +05306783 goto free_bcn_miss_rate_req;
c_hpothu92367912014-05-01 15:18:17 +05306784 }
6785
6786 hddLog(VOS_TRACE_LEVEL_INFO,
Hanumanth Reddy Pothula7aa4bea2018-04-09 17:19:03 +05306787 FL("GETBCNMISSRATE: bcnMissRate: %d"), priv->bcn_miss_rate);
c_hpothu92367912014-05-01 15:18:17 +05306788
Hanumanth Reddy Pothula7aa4bea2018-04-09 17:19:03 +05306789 if (priv->bcn_miss_rate == -1) {
6790 ret = -EFAULT;
6791 goto free_bcn_miss_rate_req;
6792 }
6793
6794 len = snprintf(buf, sizeof(buf), "GETBCNMISSRATE %d",
6795 priv->bcn_miss_rate);
c_hpothu92367912014-05-01 15:18:17 +05306796 if (copy_to_user(priv_data.buf, &buf, len + 1))
6797 {
6798 hddLog(VOS_TRACE_LEVEL_ERROR,
6799 "%s: failed to copy data to user buffer", __func__);
6800 ret = -EFAULT;
Hanumanth Reddy Pothula7aa4bea2018-04-09 17:19:03 +05306801 goto free_bcn_miss_rate_req;
c_hpothu92367912014-05-01 15:18:17 +05306802 }
6803 ret = len;
Hanumanth Reddy Pothula7aa4bea2018-04-09 17:19:03 +05306804
6805free_bcn_miss_rate_req:
6806 hdd_request_put(request);
c_hpothu92367912014-05-01 15:18:17 +05306807 }
Atul Mittal87ec2422014-09-24 13:12:50 +05306808#ifdef FEATURE_WLAN_TDLS
6809 else if (strncmp(command, "TDLSSECONDARYCHANNELOFFSET", 26) == 0) {
6810 tANI_U8 *value = command;
6811 int set_value;
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05306812
6813 ret = hdd_drv_cmd_validate(command, 26);
6814 if (ret)
6815 goto exit;
6816
Atul Mittal87ec2422014-09-24 13:12:50 +05306817 /* Move pointer to ahead of TDLSOFFCH*/
6818 value += 26;
c_manjeebbc40212015-12-08 13:52:59 +05306819 if (!(sscanf(value, "%d", &set_value))) {
6820 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6821 FL("No input identified"));
6822 ret = -EINVAL;
6823 goto exit;
6824 }
6825
Atul Mittal87ec2422014-09-24 13:12:50 +05306826 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6827 "%s: Tdls offchannel offset:%d",
6828 __func__, set_value);
6829 ret = iw_set_tdlssecoffchanneloffset(pHddCtx, set_value);
6830 if (ret < 0)
6831 {
6832 ret = -EINVAL;
6833 goto exit;
6834 }
6835
6836 } else if (strncmp(command, "TDLSOFFCHANNELMODE", 18) == 0) {
6837 tANI_U8 *value = command;
6838 int set_value;
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05306839
6840 ret = hdd_drv_cmd_validate(command, 18);
6841 if (ret)
6842 goto exit;
6843
Atul Mittal87ec2422014-09-24 13:12:50 +05306844 /* Move pointer to ahead of tdlsoffchnmode*/
6845 value += 18;
c_manjee82323892015-12-08 12:40:34 +05306846 ret = sscanf(value, "%d", &set_value);
6847 if (ret != 1) {
6848 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6849 FL("No input identified"));
6850 ret = -EINVAL;
6851 goto exit;
6852 }
Atul Mittal87ec2422014-09-24 13:12:50 +05306853 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6854 "%s: Tdls offchannel mode:%d",
6855 __func__, set_value);
6856 ret = iw_set_tdlsoffchannelmode(pAdapter, set_value);
6857 if (ret < 0)
6858 {
6859 ret = -EINVAL;
6860 goto exit;
6861 }
6862 } else if (strncmp(command, "TDLSOFFCHANNEL", 14) == 0) {
6863 tANI_U8 *value = command;
6864 int set_value;
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05306865
6866 ret = hdd_drv_cmd_validate(command, 14);
6867 if (ret)
6868 goto exit;
6869
Atul Mittal87ec2422014-09-24 13:12:50 +05306870 /* Move pointer to ahead of TDLSOFFCH*/
6871 value += 14;
c_manjeef6ccaf52015-12-08 11:52:11 +05306872 ret = sscanf(value, "%d", &set_value);
6873 if (ret != 1) {
6874 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6875 "Wrong value is given for hdd_set_tdls_offchannel");
6876 ret = -EINVAL;
6877 goto exit;
6878 }
6879
Atul Mittal87ec2422014-09-24 13:12:50 +05306880 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6881 "%s: Tdls offchannel num: %d",
6882 __func__, set_value);
6883 ret = iw_set_tdlsoffchannel(pHddCtx, set_value);
6884 if (ret < 0)
6885 {
6886 ret = -EINVAL;
6887 goto exit;
6888 }
6889 }
6890#endif
Satyanarayana Dash72806012014-12-02 14:30:08 +05306891 else if (strncmp(command, "GETFWSTATS", 10) == 0)
6892 {
6893 eHalStatus status;
6894 char *buf = NULL;
6895 char len;
Hanumanth Reddy Pothula7aa4bea2018-04-09 17:19:03 +05306896 tSirFwStatsResult *fwStatsRsp = &(pAdapter->fwStatsRsp),
6897 *fw_stats_result;
Satyanarayana Dash72806012014-12-02 14:30:08 +05306898 tANI_U8 *ptr = command;
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05306899 int stats;
Hanumanth Reddy Pothula7aa4bea2018-04-09 17:19:03 +05306900 void *cookie;
6901 struct hdd_request *request;
6902 struct fw_stats_priv *priv;
6903 static const struct hdd_request_params params = {
6904 .priv_size = sizeof(*priv),
6905 .timeout_ms = WLAN_WAIT_TIME_STATS,
6906 };
Satyanarayana Dash72806012014-12-02 14:30:08 +05306907
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05306908 ret = hdd_drv_cmd_validate(command, 10);
6909 if (ret)
6910 goto exit;
6911
6912 stats = *(ptr + 11) - '0';
Satyanarayana Dash72806012014-12-02 14:30:08 +05306913 hddLog(VOS_TRACE_LEVEL_INFO, FL("stats = %d "),stats);
6914 if (!IS_FEATURE_FW_STATS_ENABLE)
6915 {
6916 hddLog(VOS_TRACE_LEVEL_INFO,
6917 FL("Get Firmware stats feature not supported"));
6918 ret = -EINVAL;
6919 goto exit;
6920 }
6921
6922 if (FW_STATS_MAX <= stats || 0 >= stats)
6923 {
6924 hddLog(VOS_TRACE_LEVEL_INFO,
6925 FL(" stats %d not supported"),stats);
6926 ret = -EINVAL;
6927 goto exit;
6928 }
6929
Hanumanth Reddy Pothula7aa4bea2018-04-09 17:19:03 +05306930 request = hdd_request_alloc(&params);
6931 if (!request) {
6932 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Request allocation failure"));
6933 ret = -ENOMEM;
6934 goto exit;
6935 }
6936 cookie = hdd_request_cookie(request);
6937
Satyanarayana Dash72806012014-12-02 14:30:08 +05306938 status = sme_GetFwStats( (tHalHandle)pHddCtx->hHal, stats,
Hanumanth Reddy Pothula7aa4bea2018-04-09 17:19:03 +05306939 cookie, hdd_fw_stats_cb);
Satyanarayana Dash72806012014-12-02 14:30:08 +05306940 if (eHAL_STATUS_SUCCESS != status)
6941 {
6942 hddLog(VOS_TRACE_LEVEL_ERROR,
6943 FL(" fail to post WDA cmd status = %d"), status);
6944 ret = -EINVAL;
Hanumanth Reddy Pothula7aa4bea2018-04-09 17:19:03 +05306945 hdd_request_put(request);
Satyanarayana Dash72806012014-12-02 14:30:08 +05306946 goto exit;
6947 }
Hanumanth Reddy Pothula7aa4bea2018-04-09 17:19:03 +05306948 ret = hdd_request_wait_for_response(request);
6949 if (ret)
Satyanarayana Dash72806012014-12-02 14:30:08 +05306950 {
6951 hddLog(VOS_TRACE_LEVEL_ERROR,
6952 FL("failed to wait on GwtFwstats"));
Satyanarayana Dash72806012014-12-02 14:30:08 +05306953 ret = -EINVAL;
Hanumanth Reddy Pothula7aa4bea2018-04-09 17:19:03 +05306954 hdd_request_put(request);
Satyanarayana Dash72806012014-12-02 14:30:08 +05306955 goto exit;
6956 }
Hanumanth Reddy Pothula7aa4bea2018-04-09 17:19:03 +05306957
6958 priv = hdd_request_priv(request);
6959 fw_stats_result = priv->fw_stats;
6960 fwStatsRsp->type = 0;
6961 if (NULL != fw_stats_result)
6962 {
6963 switch (fw_stats_result->type )
6964 {
6965 case FW_UBSP_STATS:
6966 {
6967 tSirUbspFwStats *stats =
6968 &fwStatsRsp->fwStatsData.ubspStats;
6969 memcpy(fwStatsRsp, fw_stats_result,
6970 sizeof(tSirFwStatsResult));
6971 hddLog(VOS_TRACE_LEVEL_INFO,
6972 FL("ubsp_enter_cnt = %d ubsp_jump_ddr_cnt = %d"),
6973 stats->ubsp_enter_cnt,
6974 stats->ubsp_jump_ddr_cnt);
6975 }
6976 break;
6977
6978 default:
6979 {
6980 hddLog(VOS_TRACE_LEVEL_ERROR,
6981 FL("No handling for stats type %d"),
6982 fw_stats_result->type);
6983 }
6984 }
6985 }
6986 hdd_request_put(request);
6987
Satyanarayana Dash72806012014-12-02 14:30:08 +05306988 if (fwStatsRsp->type)
6989 {
6990 buf = kmalloc(FW_STATE_RSP_LEN, GFP_KERNEL);
6991 if (!buf)
6992 {
6993 hddLog(VOS_TRACE_LEVEL_ERROR,
6994 FL(" failed to allocate memory"));
6995 ret = -ENOMEM;
6996 goto exit;
6997 }
6998 switch( fwStatsRsp->type )
6999 {
7000 case FW_UBSP_STATS:
7001 {
7002 len = snprintf(buf, FW_STATE_RSP_LEN,
7003 "GETFWSTATS: ubsp_enter_cnt %d ubsp_jump_ddr_cnt %d",
Abhishek Singh08aa7762014-12-16 13:59:03 +05307004 fwStatsRsp->fwStatsData.ubspStats.ubsp_enter_cnt,
7005 fwStatsRsp->fwStatsData.ubspStats.ubsp_jump_ddr_cnt);
Satyanarayana Dash72806012014-12-02 14:30:08 +05307006 }
7007 break;
7008 default:
7009 {
7010 hddLog(VOS_TRACE_LEVEL_ERROR, FL( "No handling for stats type %d"),fwStatsRsp->type);
7011 ret = -EFAULT;
7012 kfree(buf);
7013 goto exit;
7014 }
7015 }
7016 if (copy_to_user(priv_data.buf, buf, len + 1))
7017 {
7018 hddLog(VOS_TRACE_LEVEL_ERROR,
7019 FL(" failed to copy data to user buffer"));
7020 ret = -EFAULT;
7021 kfree(buf);
7022 goto exit;
7023 }
7024 ret = len;
7025 kfree(buf);
7026 }
7027 else
7028 {
7029 hddLog(VOS_TRACE_LEVEL_ERROR,
7030 FL("failed to fetch the stats"));
7031 ret = -EFAULT;
7032 goto exit;
7033 }
Satyanarayana Dash72806012014-12-02 14:30:08 +05307034 }
Agarwal Ashish8bd53ae2015-06-12 18:03:45 +05307035 else if (strncasecmp(command, "SET_FCC_CHANNEL", 15) == 0)
7036 {
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05307037 ret = hdd_drv_cmd_validate(command, 15);
7038 if (ret)
7039 goto exit;
7040
Agarwal Ashish8bd53ae2015-06-12 18:03:45 +05307041 /*
7042 * this command wld be called by user-space when it detects WLAN
7043 * ON after airplane mode is set. When APM is set, WLAN turns off.
7044 * But it can be turned back on. Otherwise; when APM is turned back
7045 * off, WLAN wld turn back on. So at that point the command is
7046 * expected to come down. 0 means disable, 1 means enable. The
7047 * constraint is removed when parameter 1 is set or different
7048 * country code is set
7049 */
7050 ret = hdd_cmd_setFccChannel(pHddCtx, command, 15);
7051 }
Mahesh A Saptasagarbeca12c2015-09-07 16:21:06 +05307052 else if (strncasecmp(command, "DISABLE_CA_EVENT", 16) == 0)
7053 {
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05307054 ret = hdd_drv_cmd_validate(command, 16);
7055 if (ret)
7056 goto exit;
7057
Mahesh A Saptasagarbeca12c2015-09-07 16:21:06 +05307058 ret = hdd_enable_disable_ca_event(pHddCtx, command, 16);
7059 }
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +05307060 /*
7061 * command should be a string having format
7062 * SET_DISABLE_CHANNEL_LIST <num of channels>
7063 * <channels separated by spaces>
7064 */
7065 else if (strncmp(command, "SET_DISABLE_CHANNEL_LIST", 24) == 0) {
7066 tANI_U8 *ptr = command;
7067 ret = hdd_drv_cmd_validate(command, 24);
7068 if (ret)
7069 goto exit;
7070
7071 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
7072 " Received Command to disable Channels %s",
7073 __func__);
7074 ret = hdd_parse_disable_chan_cmd(pAdapter, ptr);
7075 if (ret)
7076 goto exit;
7077 }
Hanumanth Reddy Pothula8ae38bb2018-03-07 18:59:30 +05307078 else if (strncmp(command, "GET_DISABLE_CHANNEL_LIST", 24) == 0) {
Ashish Kumar Dhanotiya95e5bc22018-04-19 17:06:33 +05307079 char extra[512] = {0};
7080 int max_len, copied_length;
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +05307081
Ashish Kumar Dhanotiya95e5bc22018-04-19 17:06:33 +05307082 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Hanumanth Reddy Pothula8ae38bb2018-03-07 18:59:30 +05307083 " Received Command to get disable Channels list %s",
7084 __func__);
7085
Ashish Kumar Dhanotiya95e5bc22018-04-19 17:06:33 +05307086 max_len = VOS_MIN(priv_data.total_len, sizeof(extra));
7087 copied_length = hdd_get_disable_ch_list(pHddCtx, extra, max_len);
7088 if (copied_length == 0) {
7089 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Hanumanth Reddy Pothula8ae38bb2018-03-07 18:59:30 +05307090 FL("disable channel list are not yet programed"));
7091 ret = -EINVAL;
7092 goto exit;
7093 }
7094
Ashish Kumar Dhanotiya95e5bc22018-04-19 17:06:33 +05307095 if (copy_to_user(priv_data.buf, &extra, copied_length + 1)) {
7096 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7097 "%s: failed to copy data to user buffer", __func__);
Hanumanth Reddy Pothula8ae38bb2018-03-07 18:59:30 +05307098 ret = -EFAULT;
7099 goto exit;
7100 }
7101
7102 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
7103 FL("data:%s"), extra);
7104 }
Madan Mohan Koyyalamudif9bdd4e2012-10-30 18:05:03 -07007105 else {
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307106 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
7107 TRACE_CODE_HDD_UNSUPPORTED_IOCTL,
7108 pAdapter->sessionId, 0));
Satyanarayana Dash72806012014-12-02 14:30:08 +05307109 hddLog( VOS_TRACE_LEVEL_WARN, FL("Unsupported GUI command %s"),
7110 command);
Madan Mohan Koyyalamudif9bdd4e2012-10-30 18:05:03 -07007111 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007112 }
7113exit:
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05307114 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07007115 if (command)
7116 {
7117 kfree(command);
7118 }
7119 return ret;
7120}
7121
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07007122#ifdef CONFIG_COMPAT
7123static int hdd_driver_compat_ioctl(hdd_adapter_t *pAdapter, struct ifreq *ifr)
7124{
7125 struct {
7126 compat_uptr_t buf;
7127 int used_len;
7128 int total_len;
7129 } compat_priv_data;
7130 hdd_priv_data_t priv_data;
7131 int ret = 0;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07007132
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07007133 /*
7134 * Note that pAdapter and ifr have already been verified by caller,
7135 * and HDD context has also been validated
7136 */
7137 if (copy_from_user(&compat_priv_data, ifr->ifr_data,
7138 sizeof(compat_priv_data))) {
7139 ret = -EFAULT;
7140 goto exit;
7141 }
7142 priv_data.buf = compat_ptr(compat_priv_data.buf);
7143 priv_data.used_len = compat_priv_data.used_len;
7144 priv_data.total_len = compat_priv_data.total_len;
7145 ret = hdd_driver_command(pAdapter, &priv_data);
7146 exit:
7147 return ret;
7148}
7149#else /* CONFIG_COMPAT */
7150static int hdd_driver_compat_ioctl(hdd_adapter_t *pAdapter, struct ifreq *ifr)
7151{
7152 /* will never be invoked */
7153 return 0;
7154}
7155#endif /* CONFIG_COMPAT */
7156
7157static int hdd_driver_ioctl(hdd_adapter_t *pAdapter, struct ifreq *ifr)
7158{
7159 hdd_priv_data_t priv_data;
7160 int ret = 0;
7161
7162 /*
7163 * Note that pAdapter and ifr have already been verified by caller,
7164 * and HDD context has also been validated
7165 */
7166 if (copy_from_user(&priv_data, ifr->ifr_data, sizeof(priv_data))) {
7167 ret = -EFAULT;
7168 } else {
7169 ret = hdd_driver_command(pAdapter, &priv_data);
7170 }
7171 return ret;
7172}
7173
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05307174int __hdd_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07007175{
7176 hdd_adapter_t *pAdapter;
7177 hdd_context_t *pHddCtx;
7178 int ret;
7179
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05307180 ENTER();
7181
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07007182 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
7183 if (NULL == pAdapter) {
7184 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
7185 "%s: HDD adapter context is Null", __func__);
7186 ret = -ENODEV;
7187 goto exit;
7188 }
7189 if (dev != pAdapter->dev) {
7190 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
7191 "%s: HDD adapter/dev inconsistency", __func__);
7192 ret = -ENODEV;
7193 goto exit;
7194 }
7195
7196 if ((!ifr) || (!ifr->ifr_data)) {
7197 ret = -EINVAL;
7198 goto exit;
7199 }
7200
7201 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7202 ret = wlan_hdd_validate_context(pHddCtx);
7203 if (ret) {
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07007204 ret = -EBUSY;
7205 goto exit;
7206 }
7207
7208 switch (cmd) {
7209 case (SIOCDEVPRIVATE + 1):
7210 if (is_compat_task())
7211 ret = hdd_driver_compat_ioctl(pAdapter, ifr);
7212 else
7213 ret = hdd_driver_ioctl(pAdapter, ifr);
7214 break;
7215 default:
7216 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unknown ioctl %d",
7217 __func__, cmd);
7218 ret = -EINVAL;
7219 break;
7220 }
7221 exit:
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05307222 EXIT();
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07007223 return ret;
7224}
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07007225
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05307226int hdd_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
7227{
7228 int ret;
7229
7230 vos_ssr_protect(__func__);
7231 ret = __hdd_ioctl(dev, ifr, cmd);
7232 vos_ssr_unprotect(__func__);
7233
7234 return ret;
7235}
7236
Katya Nigame7b69a82015-04-28 15:24:06 +05307237int hdd_mon_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
7238{
7239 return 0;
7240}
7241
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08007242#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08007243/**---------------------------------------------------------------------------
7244
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08007245 \brief hdd_parse_ese_beacon_req() - Parse ese beacon request
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08007246
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08007247 This function parses the ese beacon request passed in the format
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08007248 CCXBEACONREQ<space><Number of fields><space><Measurement token>
7249 <space>Channel 1<space>Scan Mode <space>Meas Duration<space>Channel N
7250 <space>Scan Mode N<space>Meas Duration N
7251 if the Number of bcn req fields (N) does not match with the actual number of fields passed
7252 then take N.
7253 <Meas Token><Channel><Scan Mode> and <Meas Duration> are treated as one pair
7254 For example, CCXBEACONREQ 2 1 1 1 30 2 44 0 40.
7255 This function does not take care of removing duplicate channels from the list
7256
7257 \param - pValue Pointer to data
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08007258 \param - pEseBcnReq output pointer to store parsed ie information
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08007259
7260 \return - 0 for success non-zero for failure
7261
7262 --------------------------------------------------------------------------*/
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08007263static VOS_STATUS hdd_parse_ese_beacon_req(tANI_U8 *pValue,
7264 tCsrEseBeaconReq *pEseBcnReq)
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08007265{
7266 tANI_U8 *inPtr = pValue;
Arun Khandavalli9f3b4832016-06-30 16:58:38 +05307267 uint8_t input = 0;
7268 uint32_t tempInt = 0;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08007269 int j = 0, i = 0, v = 0;
7270 char buf[32];
7271
7272 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
7273 /*no argument after the command*/
7274 if (NULL == inPtr)
7275 {
7276 return -EINVAL;
7277 }
7278 /*no space after the command*/
7279 else if (SPACE_ASCII_VALUE != *inPtr)
7280 {
7281 return -EINVAL;
7282 }
7283
7284 /*removing empty spaces*/
7285 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
7286
7287 /*no argument followed by spaces*/
7288 if ('\0' == *inPtr) return -EINVAL;
7289
7290 /*getting the first argument ie measurement token*/
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08007291 v = sscanf(inPtr, "%31s ", buf);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08007292 if (1 != v) return -EINVAL;
7293
Arun Khandavalli9f3b4832016-06-30 16:58:38 +05307294 v = kstrtos8(buf, 10, &input);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08007295 if ( v < 0) return -EINVAL;
7296
Arun Khandavalli9f3b4832016-06-30 16:58:38 +05307297 input = VOS_MIN(input, SIR_ESE_MAX_MEAS_IE_REQS);
7298 pEseBcnReq->numBcnReqIe = input;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08007299
Srinivas Girigowda725a88e2016-03-31 19:24:25 +05307300 hddLog(LOG1, "Number of Bcn Req Ie fields: %d", pEseBcnReq->numBcnReqIe);
7301
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08007302
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08007303 for (j = 0; j < (pEseBcnReq->numBcnReqIe); j++)
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08007304 {
7305 for (i = 0; i < 4; i++)
7306 {
7307 /*inPtr pointing to the beginning of first space after number of ie fields*/
7308 inPtr = strpbrk( inPtr, " " );
7309 /*no ie data after the number of ie fields argument*/
7310 if (NULL == inPtr) return -EINVAL;
7311
7312 /*removing empty space*/
7313 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
7314
7315 /*no ie data after the number of ie fields argument and spaces*/
7316 if ( '\0' == *inPtr ) return -EINVAL;
7317
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08007318 v = sscanf(inPtr, "%31s ", buf);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08007319 if (1 != v) return -EINVAL;
7320
Arun Khandavalli9f3b4832016-06-30 16:58:38 +05307321 v = kstrtou32(buf, 10, &tempInt);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08007322 if (v < 0) return -EINVAL;
7323
7324 switch (i)
7325 {
7326 case 0: /* Measurement token */
Arun Khandavalli9f3b4832016-06-30 16:58:38 +05307327 if (!tempInt)
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08007328 {
7329 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arun Khandavalli9f3b4832016-06-30 16:58:38 +05307330 "Invalid Measurement Token: %u", tempInt);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08007331 return -EINVAL;
7332 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08007333 pEseBcnReq->bcnReq[j].measurementToken = tempInt;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08007334 break;
7335
7336 case 1: /* Channel number */
Arun Khandavalli9f3b4832016-06-30 16:58:38 +05307337 if ((!tempInt) ||
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08007338 (tempInt > WNI_CFG_CURRENT_CHANNEL_STAMAX))
7339 {
7340 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arun Khandavalli9f3b4832016-06-30 16:58:38 +05307341 "Invalid Channel Number: %u", tempInt);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08007342 return -EINVAL;
7343 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08007344 pEseBcnReq->bcnReq[j].channel = tempInt;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08007345 break;
7346
7347 case 2: /* Scan mode */
Varun Reddy Yeturu0b18d5a2013-12-04 11:42:23 -08007348 if ((tempInt < eSIR_PASSIVE_SCAN) || (tempInt > eSIR_BEACON_TABLE))
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08007349 {
7350 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arun Khandavalli9f3b4832016-06-30 16:58:38 +05307351 "Invalid Scan Mode(%u) Expected{0|1|2}", tempInt);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08007352 return -EINVAL;
7353 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08007354 pEseBcnReq->bcnReq[j].scanMode= tempInt;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08007355 break;
7356
7357 case 3: /* Measurement duration */
Arun Khandavalli9f3b4832016-06-30 16:58:38 +05307358 if (((!tempInt) && (pEseBcnReq->bcnReq[j].scanMode != eSIR_BEACON_TABLE)) ||
7359 ((pEseBcnReq->bcnReq[j].scanMode == eSIR_BEACON_TABLE)))
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08007360 {
7361 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arun Khandavalli9f3b4832016-06-30 16:58:38 +05307362 "Invalid Measurement Duration: %u", tempInt);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08007363 return -EINVAL;
7364 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08007365 pEseBcnReq->bcnReq[j].measurementDuration = tempInt;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08007366 break;
7367 }
7368 }
7369 }
7370
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08007371 for (j = 0; j < pEseBcnReq->numBcnReqIe; j++)
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08007372 {
7373 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Arun Kumar Khandavallie8768212014-02-17 16:43:34 +05307374 "Index(%d) Measurement Token(%u)Channel(%u) Scan Mode(%u) Measurement Duration(%u)\n",
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08007375 j,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08007376 pEseBcnReq->bcnReq[j].measurementToken,
7377 pEseBcnReq->bcnReq[j].channel,
7378 pEseBcnReq->bcnReq[j].scanMode,
7379 pEseBcnReq->bcnReq[j].measurementDuration);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08007380 }
7381
7382 return VOS_STATUS_SUCCESS;
7383}
7384
Hanumanth Reddy Pothula1ceb7032018-04-05 19:35:55 +05307385struct tsm_priv {
7386 tAniTrafStrmMetrics tsm_metrics;
7387};
7388
7389static void hdd_get_tsm_stats_cb(tAniTrafStrmMetrics tsm_metrics,
7390 const tANI_U32 sta_id, void *context )
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07007391{
Hanumanth Reddy Pothula1ceb7032018-04-05 19:35:55 +05307392 struct hdd_request *request;
7393 struct tsm_priv *priv;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07007394
Hanumanth Reddy Pothula1ceb7032018-04-05 19:35:55 +05307395 ENTER();
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07007396
Hanumanth Reddy Pothula1ceb7032018-04-05 19:35:55 +05307397 request = hdd_request_get(context);
7398 if (!request) {
7399 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Obsolete request"));
7400 return;
7401 }
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07007402
Hanumanth Reddy Pothula1ceb7032018-04-05 19:35:55 +05307403 priv = hdd_request_priv(request);
7404 priv->tsm_metrics = tsm_metrics;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07007405
Hanumanth Reddy Pothula1ceb7032018-04-05 19:35:55 +05307406 hdd_request_complete(request);
7407 hdd_request_put(request);
Jeff Johnson72a40512013-12-19 10:14:15 -08007408
Hanumanth Reddy Pothula1ceb7032018-04-05 19:35:55 +05307409 EXIT();
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07007410}
7411
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07007412static VOS_STATUS hdd_get_tsm_stats(hdd_adapter_t *pAdapter, const tANI_U8 tid,
7413 tAniTrafStrmMetrics* pTsmMetrics)
7414{
7415 hdd_station_ctx_t *pHddStaCtx = NULL;
7416 eHalStatus hstatus;
Jeff Johnson72a40512013-12-19 10:14:15 -08007417 VOS_STATUS vstatus = VOS_STATUS_SUCCESS;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07007418 hdd_context_t *pHddCtx = NULL;
Hanumanth Reddy Pothula1ceb7032018-04-05 19:35:55 +05307419 int ret;
7420 void *cookie;
7421 struct hdd_request *request;
7422 struct tsm_priv *priv;
7423 static const struct hdd_request_params params = {
7424 .priv_size = sizeof(*priv),
7425 .timeout_ms = WLAN_WAIT_TIME_STATS,
7426 };
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07007427
7428 if (NULL == pAdapter)
7429 {
7430 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: pAdapter is NULL", __func__);
7431 return VOS_STATUS_E_FAULT;
7432 }
7433
7434 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7435 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7436
Hanumanth Reddy Pothula1ceb7032018-04-05 19:35:55 +05307437 request = hdd_request_alloc(&params);
7438 if (!request) {
7439 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Request allocation failure"));
7440 return VOS_STATUS_E_NOMEM;
7441 }
7442 cookie = hdd_request_cookie(request);
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07007443
7444 /* query tsm stats */
Hanumanth Reddy Pothula1ceb7032018-04-05 19:35:55 +05307445 hstatus = sme_GetTsmStats(pHddCtx->hHal, hdd_get_tsm_stats_cb,
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07007446 pHddStaCtx->conn_info.staId[ 0 ],
7447 pHddStaCtx->conn_info.bssId,
Hanumanth Reddy Pothula1ceb7032018-04-05 19:35:55 +05307448 cookie, pHddCtx->pvosContext, tid);
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07007449
7450 if (eHAL_STATUS_SUCCESS != hstatus)
7451 {
Jeff Johnson72a40512013-12-19 10:14:15 -08007452 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unable to retrieve statistics",
7453 __func__);
7454 vstatus = VOS_STATUS_E_FAULT;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07007455 }
7456 else
7457 {
7458 /* request was sent -- wait for the response */
Hanumanth Reddy Pothula1ceb7032018-04-05 19:35:55 +05307459 ret = hdd_request_wait_for_response(request);
7460 if (ret) {
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07007461 hddLog(VOS_TRACE_LEVEL_ERROR,
Hanumanth Reddy Pothula1ceb7032018-04-05 19:35:55 +05307462 "SME timeout while retrieving statistics");
Jeff Johnson72a40512013-12-19 10:14:15 -08007463 vstatus = VOS_STATUS_E_TIMEOUT;
Hanumanth Reddy Pothula1ceb7032018-04-05 19:35:55 +05307464 } else {
7465 priv = hdd_request_priv(request);
7466 *pTsmMetrics = priv->tsm_metrics;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07007467 }
7468 }
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07007469
Hanumanth Reddy Pothula1ceb7032018-04-05 19:35:55 +05307470 hdd_request_put(request);
Jeff Johnson72a40512013-12-19 10:14:15 -08007471
Jeff Johnson72a40512013-12-19 10:14:15 -08007472 return vstatus;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07007473}
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08007474#endif /*FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07007475
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08007476#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowdade697412013-02-14 16:31:48 -08007477void hdd_getBand_helper(hdd_context_t *pHddCtx, int *pBand)
7478{
7479 eCsrBand band = -1;
7480 sme_GetFreqBand((tHalHandle)(pHddCtx->hHal), &band);
7481 switch (band)
7482 {
7483 case eCSR_BAND_ALL:
7484 *pBand = WLAN_HDD_UI_BAND_AUTO;
7485 break;
7486
7487 case eCSR_BAND_24:
7488 *pBand = WLAN_HDD_UI_BAND_2_4_GHZ;
7489 break;
7490
7491 case eCSR_BAND_5G:
7492 *pBand = WLAN_HDD_UI_BAND_5_GHZ;
7493 break;
7494
7495 default:
7496 hddLog( VOS_TRACE_LEVEL_WARN, "%s: Invalid Band %d", __func__, band);
7497 *pBand = -1;
7498 break;
7499 }
7500}
7501
7502/**---------------------------------------------------------------------------
7503
Srinivas Girigowda100eb322013-03-15 16:48:20 -07007504 \brief hdd_parse_send_action_frame_data() - HDD Parse send action frame data
7505
7506 This function parses the send action frame data passed in the format
7507 SENDACTIONFRAME<space><bssid><space><channel><space><dwelltime><space><data>
7508
Srinivas Girigowda56076852013-08-20 14:00:50 -07007509 \param - pValue Pointer to input data
Srinivas Girigowda100eb322013-03-15 16:48:20 -07007510 \param - pTargetApBssid Pointer to target Ap bssid
7511 \param - pChannel Pointer to the Target AP channel
7512 \param - pDwellTime Pointer to the time to stay off-channel after transmitting action frame
7513 \param - pBuf Pointer to data
7514 \param - pBufLen Pointer to data length
7515
7516 \return - 0 for success non-zero for failure
7517
7518 --------------------------------------------------------------------------*/
7519VOS_STATUS hdd_parse_send_action_frame_data(tANI_U8 *pValue, tANI_U8 *pTargetApBssid, tANI_U8 *pChannel,
7520 tANI_U8 *pDwellTime, tANI_U8 **pBuf, tANI_U8 *pBufLen)
7521{
7522 tANI_U8 *inPtr = pValue;
7523 tANI_U8 *dataEnd;
7524 int tempInt;
7525 int j = 0;
7526 int i = 0;
7527 int v = 0;
7528 tANI_U8 tempBuf[32];
7529 tANI_U8 tempByte = 0;
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08007530 /* 12 hexa decimal digits, 5 ':' and '\0' */
7531 tANI_U8 macAddress[18];
Srinivas Girigowda100eb322013-03-15 16:48:20 -07007532
7533 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
7534 /*no argument after the command*/
7535 if (NULL == inPtr)
7536 {
7537 return -EINVAL;
7538 }
7539
7540 /*no space after the command*/
7541 else if (SPACE_ASCII_VALUE != *inPtr)
7542 {
7543 return -EINVAL;
7544 }
7545
7546 /*removing empty spaces*/
7547 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
7548
7549 /*no argument followed by spaces*/
7550 if ('\0' == *inPtr)
7551 {
7552 return -EINVAL;
7553 }
7554
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07007555 v = sscanf(inPtr, "%17s", macAddress);
7556 if (!((1 == v) && hdd_is_valid_mac_address(macAddress)))
Srinivas Girigowda100eb322013-03-15 16:48:20 -07007557 {
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07007558 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7559 "Invalid MAC address or All hex inputs are not read (%d)", v);
7560 return -EINVAL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07007561 }
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07007562
7563 pTargetApBssid[0] = hdd_parse_hex(macAddress[0]) << 4 | hdd_parse_hex(macAddress[1]);
7564 pTargetApBssid[1] = hdd_parse_hex(macAddress[3]) << 4 | hdd_parse_hex(macAddress[4]);
7565 pTargetApBssid[2] = hdd_parse_hex(macAddress[6]) << 4 | hdd_parse_hex(macAddress[7]);
7566 pTargetApBssid[3] = hdd_parse_hex(macAddress[9]) << 4 | hdd_parse_hex(macAddress[10]);
7567 pTargetApBssid[4] = hdd_parse_hex(macAddress[12]) << 4 | hdd_parse_hex(macAddress[13]);
7568 pTargetApBssid[5] = hdd_parse_hex(macAddress[15]) << 4 | hdd_parse_hex(macAddress[16]);
Srinivas Girigowda100eb322013-03-15 16:48:20 -07007569
7570 /* point to the next argument */
7571 inPtr = strnchr(inPtr, strlen(inPtr), SPACE_ASCII_VALUE);
7572 /*no argument after the command*/
7573 if (NULL == inPtr) return -EINVAL;
7574
7575 /*removing empty spaces*/
7576 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
7577
7578 /*no argument followed by spaces*/
7579 if ('\0' == *inPtr)
7580 {
7581 return -EINVAL;
7582 }
7583
7584 /*getting the next argument ie the channel number */
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08007585 v = sscanf(inPtr, "%31s ", tempBuf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07007586 if (1 != v) return -EINVAL;
7587
Srinivas Girigowda100eb322013-03-15 16:48:20 -07007588 v = kstrtos32(tempBuf, 10, &tempInt);
Agarwal Ashish353b3a82014-04-08 14:55:11 +05307589 if ( v < 0 || tempInt <= 0 || tempInt > WNI_CFG_CURRENT_CHANNEL_STAMAX )
Kiet Lambe150c22013-11-21 16:30:32 +05307590 return -EINVAL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07007591
7592 *pChannel = tempInt;
7593
7594 /* point to the next argument */
7595 inPtr = strnchr(inPtr, strlen(inPtr), SPACE_ASCII_VALUE);
7596 /*no argument after the command*/
7597 if (NULL == inPtr) return -EINVAL;
7598 /*removing empty spaces*/
7599 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
7600
7601 /*no argument followed by spaces*/
7602 if ('\0' == *inPtr)
7603 {
7604 return -EINVAL;
7605 }
7606
7607 /*getting the next argument ie the dwell time */
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08007608 v = sscanf(inPtr, "%31s ", tempBuf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07007609 if (1 != v) return -EINVAL;
7610
Srinivas Girigowda100eb322013-03-15 16:48:20 -07007611 v = kstrtos32(tempBuf, 10, &tempInt);
Srinivas Girigowda5a6e0672014-01-09 14:42:57 -08007612 if ( v < 0 || tempInt < 0) return -EINVAL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07007613
7614 *pDwellTime = tempInt;
7615
7616 /* point to the next argument */
7617 inPtr = strnchr(inPtr, strlen(inPtr), SPACE_ASCII_VALUE);
7618 /*no argument after the command*/
7619 if (NULL == inPtr) return -EINVAL;
7620 /*removing empty spaces*/
7621 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
7622
7623 /*no argument followed by spaces*/
7624 if ('\0' == *inPtr)
7625 {
7626 return -EINVAL;
7627 }
7628
7629 /* find the length of data */
7630 dataEnd = inPtr;
7631 while(('\0' != *dataEnd) )
7632 {
7633 dataEnd++;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07007634 }
Kiet Lambe150c22013-11-21 16:30:32 +05307635 *pBufLen = dataEnd - inPtr ;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07007636 if ( *pBufLen <= 0) return -EINVAL;
7637
Srinivas Girigowdab5ae85d2013-06-03 10:51:45 -07007638 /* Allocate the number of bytes based on the number of input characters
7639 whether it is even or odd.
7640 if the number of input characters are even, then we need N/2 byte.
7641 if the number of input characters are odd, then we need do (N+1)/2 to
7642 compensate rounding off.
7643 For example, if N = 18, then (18 + 1)/2 = 9 bytes are enough.
7644 If N = 19, then we need 10 bytes, hence (19 + 1)/2 = 10 bytes */
7645 *pBuf = vos_mem_malloc((*pBufLen + 1)/2);
Srinivas Girigowda100eb322013-03-15 16:48:20 -07007646 if (NULL == *pBuf)
7647 {
7648 hddLog(VOS_TRACE_LEVEL_FATAL,
7649 "%s: vos_mem_alloc failed ", __func__);
7650 return -EINVAL;
7651 }
7652
7653 /* the buffer received from the upper layer is character buffer,
7654 we need to prepare the buffer taking 2 characters in to a U8 hex decimal number
7655 for example 7f0000f0...form a buffer to contain 7f in 0th location, 00 in 1st
7656 and f0 in 3rd location */
7657 for (i = 0, j = 0; j < *pBufLen; j += 2)
7658 {
Kiet Lambe150c22013-11-21 16:30:32 +05307659 if( j+1 == *pBufLen)
7660 {
7661 tempByte = hdd_parse_hex(inPtr[j]);
7662 }
7663 else
7664 {
7665 tempByte = (hdd_parse_hex(inPtr[j]) << 4) | (hdd_parse_hex(inPtr[j + 1]));
7666 }
Srinivas Girigowda100eb322013-03-15 16:48:20 -07007667 (*pBuf)[i++] = tempByte;
7668 }
7669 *pBufLen = i;
7670 return VOS_STATUS_SUCCESS;
7671}
7672
Srinivas Girigowda100eb322013-03-15 16:48:20 -07007673/**---------------------------------------------------------------------------
7674
Srinivas Girigowdade697412013-02-14 16:31:48 -08007675 \brief hdd_parse_channellist() - HDD Parse channel list
7676
7677 This function parses the channel list passed in the format
7678 SETROAMSCANCHANNELS<space><Number of channels><space>Channel 1<space>Channel 2<space>Channel N
Srinivas Girigowdacf9a9b42013-03-21 11:55:24 -07007679 if the Number of channels (N) does not match with the actual number of channels passed
7680 then take the minimum of N and count of (Ch1, Ch2, ...Ch M)
7681 For example, if SETROAMSCANCHANNELS 3 36 40 44 48, only 36, 40 and 44 shall be taken.
7682 If SETROAMSCANCHANNELS 5 36 40 44 48, ignore 5 and take 36, 40, 44 and 48.
7683 This function does not take care of removing duplicate channels from the list
Srinivas Girigowdade697412013-02-14 16:31:48 -08007684
7685 \param - pValue Pointer to input channel list
7686 \param - ChannelList Pointer to local output array to record channel list
7687 \param - pNumChannels Pointer to number of roam scan channels
7688
7689 \return - 0 for success non-zero for failure
7690
7691 --------------------------------------------------------------------------*/
7692VOS_STATUS hdd_parse_channellist(tANI_U8 *pValue, tANI_U8 *pChannelList, tANI_U8 *pNumChannels)
7693{
7694 tANI_U8 *inPtr = pValue;
7695 int tempInt;
7696 int j = 0;
7697 int v = 0;
7698 char buf[32];
7699
7700 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
7701 /*no argument after the command*/
7702 if (NULL == inPtr)
7703 {
7704 return -EINVAL;
7705 }
7706
7707 /*no space after the command*/
7708 else if (SPACE_ASCII_VALUE != *inPtr)
7709 {
7710 return -EINVAL;
7711 }
7712
7713 /*removing empty spaces*/
Jeff Johnsona1f9afb2013-04-03 09:13:31 -07007714 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
Srinivas Girigowdade697412013-02-14 16:31:48 -08007715
7716 /*no argument followed by spaces*/
7717 if ('\0' == *inPtr)
7718 {
7719 return -EINVAL;
7720 }
7721
7722 /*getting the first argument ie the number of channels*/
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08007723 v = sscanf(inPtr, "%31s ", buf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07007724 if (1 != v) return -EINVAL;
7725
Srinivas Girigowdade697412013-02-14 16:31:48 -08007726 v = kstrtos32(buf, 10, &tempInt);
Jeff Johnsona1f9afb2013-04-03 09:13:31 -07007727 if ((v < 0) ||
7728 (tempInt <= 0) ||
7729 (tempInt > WNI_CFG_VALID_CHANNEL_LIST_LEN))
7730 {
7731 return -EINVAL;
7732 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08007733
7734 *pNumChannels = tempInt;
7735
7736 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
7737 "Number of channels are: %d", *pNumChannels);
7738
7739 for (j = 0; j < (*pNumChannels); j++)
7740 {
7741 /*inPtr pointing to the beginning of first space after number of channels*/
7742 inPtr = strpbrk( inPtr, " " );
7743 /*no channel list after the number of channels argument*/
7744 if (NULL == inPtr)
7745 {
Srinivas Girigowdacf9a9b42013-03-21 11:55:24 -07007746 if (0 != j)
7747 {
7748 *pNumChannels = j;
7749 return VOS_STATUS_SUCCESS;
7750 }
7751 else
7752 {
7753 return -EINVAL;
7754 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08007755 }
7756
7757 /*removing empty space*/
Jeff Johnsona1f9afb2013-04-03 09:13:31 -07007758 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
Srinivas Girigowdade697412013-02-14 16:31:48 -08007759
7760 /*no channel list after the number of channels argument and spaces*/
7761 if ( '\0' == *inPtr )
7762 {
Srinivas Girigowdacf9a9b42013-03-21 11:55:24 -07007763 if (0 != j)
7764 {
7765 *pNumChannels = j;
7766 return VOS_STATUS_SUCCESS;
7767 }
7768 else
7769 {
7770 return -EINVAL;
7771 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08007772 }
7773
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08007774 v = sscanf(inPtr, "%31s ", buf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07007775 if (1 != v) return -EINVAL;
7776
Srinivas Girigowdade697412013-02-14 16:31:48 -08007777 v = kstrtos32(buf, 10, &tempInt);
Jeff Johnsona1f9afb2013-04-03 09:13:31 -07007778 if ((v < 0) ||
7779 (tempInt <= 0) ||
7780 (tempInt > WNI_CFG_CURRENT_CHANNEL_STAMAX))
7781 {
7782 return -EINVAL;
7783 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08007784 pChannelList[j] = tempInt;
7785
7786 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
7787 "Channel %d added to preferred channel list",
7788 pChannelList[j] );
7789 }
7790
Srinivas Girigowdade697412013-02-14 16:31:48 -08007791 return VOS_STATUS_SUCCESS;
7792}
7793
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07007794
Selvaraj, Sridhar5aff1ed2016-06-18 01:26:23 +05307795/**
7796 * hdd_parse_reassoc_command_v1_data() - HDD Parse reassoc command data
7797 * This function parses the reasoc command data passed in the format
7798 * REASSOC<space><bssid><space><channel>
7799 *
7800 * @pValue: Pointer to input data (its a NUL terminated string)
7801 * @pTargetApBssid: Pointer to target Ap bssid
7802 * @pChannel: Pointer to the Target AP channel
7803 *
7804 * Return: 0 for success non-zero for failure
7805 */
7806static int hdd_parse_reassoc_command_v1_data(const tANI_U8 *pValue,
7807 tANI_U8 *pTargetApBssid, tANI_U8 *pChannel)
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07007808{
Selvaraj, Sridhar5aff1ed2016-06-18 01:26:23 +05307809 const tANI_U8 *inPtr = pValue;
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07007810 int tempInt;
7811 int v = 0;
7812 tANI_U8 tempBuf[32];
Kiet Lamaa8e15a2014-02-11 23:30:06 -08007813 /* 12 hexa decimal digits, 5 ':' and '\0' */
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08007814 tANI_U8 macAddress[18];
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07007815
7816 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
7817 /*no argument after the command*/
7818 if (NULL == inPtr)
7819 {
7820 return -EINVAL;
7821 }
7822
7823 /*no space after the command*/
7824 else if (SPACE_ASCII_VALUE != *inPtr)
7825 {
7826 return -EINVAL;
7827 }
7828
7829 /*removing empty spaces*/
7830 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
7831
7832 /*no argument followed by spaces*/
7833 if ('\0' == *inPtr)
7834 {
7835 return -EINVAL;
7836 }
7837
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07007838 v = sscanf(inPtr, "%17s", macAddress);
7839 if (!((1 == v) && hdd_is_valid_mac_address(macAddress)))
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07007840 {
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07007841 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7842 "Invalid MAC address or All hex inputs are not read (%d)", v);
7843 return -EINVAL;
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07007844 }
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07007845
7846 pTargetApBssid[0] = hdd_parse_hex(macAddress[0]) << 4 | hdd_parse_hex(macAddress[1]);
7847 pTargetApBssid[1] = hdd_parse_hex(macAddress[3]) << 4 | hdd_parse_hex(macAddress[4]);
7848 pTargetApBssid[2] = hdd_parse_hex(macAddress[6]) << 4 | hdd_parse_hex(macAddress[7]);
7849 pTargetApBssid[3] = hdd_parse_hex(macAddress[9]) << 4 | hdd_parse_hex(macAddress[10]);
7850 pTargetApBssid[4] = hdd_parse_hex(macAddress[12]) << 4 | hdd_parse_hex(macAddress[13]);
7851 pTargetApBssid[5] = hdd_parse_hex(macAddress[15]) << 4 | hdd_parse_hex(macAddress[16]);
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07007852
7853 /* point to the next argument */
7854 inPtr = strnchr(inPtr, strlen(inPtr), SPACE_ASCII_VALUE);
7855 /*no argument after the command*/
7856 if (NULL == inPtr) return -EINVAL;
7857
7858 /*removing empty spaces*/
7859 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
7860
7861 /*no argument followed by spaces*/
7862 if ('\0' == *inPtr)
7863 {
7864 return -EINVAL;
7865 }
7866
7867 /*getting the next argument ie the channel number */
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08007868 v = sscanf(inPtr, "%31s ", tempBuf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07007869 if (1 != v) return -EINVAL;
7870
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07007871 v = kstrtos32(tempBuf, 10, &tempInt);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07007872 if ((v < 0) ||
Padma, Santhosh Kumar0fa809b2014-11-13 14:56:56 +05307873 (tempInt < 0) ||
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07007874 (tempInt > WNI_CFG_CURRENT_CHANNEL_STAMAX))
7875 {
7876 return -EINVAL;
7877 }
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07007878
7879 *pChannel = tempInt;
7880 return VOS_STATUS_SUCCESS;
7881}
7882
7883#endif
7884
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08007885#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07007886/**---------------------------------------------------------------------------
7887
7888 \brief hdd_parse_get_cckm_ie() - HDD Parse and fetch the CCKM IE
7889
7890 This function parses the SETCCKM IE command
7891 SETCCKMIE<space><ie data>
7892
7893 \param - pValue Pointer to input data
7894 \param - pCckmIe Pointer to output cckm Ie
7895 \param - pCckmIeLen Pointer to output cckm ie length
7896
7897 \return - 0 for success non-zero for failure
7898
7899 --------------------------------------------------------------------------*/
7900VOS_STATUS hdd_parse_get_cckm_ie(tANI_U8 *pValue, tANI_U8 **pCckmIe,
7901 tANI_U8 *pCckmIeLen)
7902{
7903 tANI_U8 *inPtr = pValue;
7904 tANI_U8 *dataEnd;
7905 int j = 0;
7906 int i = 0;
7907 tANI_U8 tempByte = 0;
7908
7909 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
7910 /*no argument after the command*/
7911 if (NULL == inPtr)
7912 {
7913 return -EINVAL;
7914 }
7915
7916 /*no space after the command*/
7917 else if (SPACE_ASCII_VALUE != *inPtr)
7918 {
7919 return -EINVAL;
7920 }
7921
7922 /*removing empty spaces*/
7923 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
7924
7925 /*no argument followed by spaces*/
7926 if ('\0' == *inPtr)
7927 {
7928 return -EINVAL;
7929 }
7930
7931 /* find the length of data */
7932 dataEnd = inPtr;
7933 while(('\0' != *dataEnd) )
7934 {
7935 dataEnd++;
7936 ++(*pCckmIeLen);
7937 }
7938 if ( *pCckmIeLen <= 0) return -EINVAL;
7939
7940 /* Allocate the number of bytes based on the number of input characters
7941 whether it is even or odd.
7942 if the number of input characters are even, then we need N/2 byte.
7943 if the number of input characters are odd, then we need do (N+1)/2 to
7944 compensate rounding off.
7945 For example, if N = 18, then (18 + 1)/2 = 9 bytes are enough.
7946 If N = 19, then we need 10 bytes, hence (19 + 1)/2 = 10 bytes */
7947 *pCckmIe = vos_mem_malloc((*pCckmIeLen + 1)/2);
7948 if (NULL == *pCckmIe)
7949 {
7950 hddLog(VOS_TRACE_LEVEL_FATAL,
7951 "%s: vos_mem_alloc failed ", __func__);
7952 return -EINVAL;
7953 }
7954 vos_mem_zero(*pCckmIe, (*pCckmIeLen + 1)/2);
7955 /* the buffer received from the upper layer is character buffer,
7956 we need to prepare the buffer taking 2 characters in to a U8 hex decimal number
7957 for example 7f0000f0...form a buffer to contain 7f in 0th location, 00 in 1st
7958 and f0 in 3rd location */
7959 for (i = 0, j = 0; j < *pCckmIeLen; j += 2)
7960 {
7961 tempByte = (hdd_parse_hex(inPtr[j]) << 4) | (hdd_parse_hex(inPtr[j + 1]));
7962 (*pCckmIe)[i++] = tempByte;
7963 }
7964 *pCckmIeLen = i;
7965
7966 return VOS_STATUS_SUCCESS;
7967}
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08007968#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07007969
Jeff Johnson295189b2012-06-20 16:38:30 -07007970/**---------------------------------------------------------------------------
7971
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07007972 \brief hdd_is_valid_mac_address() - Validate MAC address
7973
7974 This function validates whether the given MAC address is valid or not
7975 Expected MAC address is of the format XX:XX:XX:XX:XX:XX
7976 where X is the hexa decimal digit character and separated by ':'
7977 This algorithm works even if MAC address is not separated by ':'
7978
7979 This code checks given input string mac contains exactly 12 hexadecimal digits.
7980 and a separator colon : appears in the input string only after
7981 an even number of hex digits.
7982
7983 \param - pMacAddr pointer to the input MAC address
7984 \return - 1 for valid and 0 for invalid
7985
7986 --------------------------------------------------------------------------*/
7987
7988v_BOOL_t hdd_is_valid_mac_address(const tANI_U8 *pMacAddr)
7989{
7990 int xdigit = 0;
7991 int separator = 0;
7992 while (*pMacAddr)
7993 {
7994 if (isxdigit(*pMacAddr))
7995 {
7996 xdigit++;
7997 }
7998 else if (':' == *pMacAddr)
7999 {
8000 if (0 == xdigit || ((xdigit / 2) - 1) != separator)
8001 break;
8002
8003 ++separator;
8004 }
8005 else
8006 {
8007 separator = -1;
8008 /* Invalid MAC found */
8009 return 0;
8010 }
8011 ++pMacAddr;
8012 }
8013 return (xdigit == 12 && (separator == 5 || separator == 0));
8014}
8015
8016/**---------------------------------------------------------------------------
8017
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05308018 \brief __hdd_open() - HDD Open function
Jeff Johnson295189b2012-06-20 16:38:30 -07008019
8020 \param - dev Pointer to net_device structure
8021
8022 \return - 0 for success non-zero for failure
8023
8024 --------------------------------------------------------------------------*/
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05308025int __hdd_open(struct net_device *dev)
Jeff Johnson295189b2012-06-20 16:38:30 -07008026{
8027 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
8028 hdd_context_t *pHddCtx;
8029 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
8030 VOS_STATUS status;
8031 v_BOOL_t in_standby = TRUE;
8032
8033 if (NULL == pAdapter)
8034 {
8035 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Agarwal Ashish971c2882013-10-30 20:11:12 +05308036 "%s: pAdapter is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07008037 return -ENODEV;
8038 }
8039
8040 pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05308041 MTRACE(vos_trace(VOS_MODULE_ID_HDD, TRACE_CODE_HDD_OPEN_REQUEST,
8042 pAdapter->sessionId, pAdapter->device_mode));
Jeff Johnson295189b2012-06-20 16:38:30 -07008043 if (NULL == pHddCtx)
8044 {
8045 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008046 "%s: HDD context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07008047 return -ENODEV;
8048 }
8049
8050 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
8051 while ( (NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status) )
8052 {
Jeff Johnson6a81ca42013-04-05 10:37:08 -07008053 if (test_bit(DEVICE_IFACE_OPENED, &pAdapterNode->pAdapter->event_flags))
8054 {
8055 hddLog(VOS_TRACE_LEVEL_INFO, "%s: chip already out of standby",
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05308056 __func__);
Jeff Johnson6a81ca42013-04-05 10:37:08 -07008057 in_standby = FALSE;
8058 break;
8059 }
8060 else
8061 {
8062 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
8063 pAdapterNode = pNext;
8064 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008065 }
8066
8067 if (TRUE == in_standby)
8068 {
8069 if (VOS_STATUS_SUCCESS != wlan_hdd_exit_lowpower(pHddCtx, pAdapter))
8070 {
8071 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Failed to bring "
8072 "wlan out of power save", __func__);
8073 return -EINVAL;
8074 }
8075 }
8076
Jeff Johnson6a81ca42013-04-05 10:37:08 -07008077 set_bit(DEVICE_IFACE_OPENED, &pAdapter->event_flags);
Jeff Johnson295189b2012-06-20 16:38:30 -07008078 if (hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter)))
8079 {
8080 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008081 "%s: Enabling Tx Queues", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07008082 /* Enable TX queues only when we are connected */
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +05308083 hddLog(VOS_TRACE_LEVEL_INFO, FL("Enabling queues"));
Jeff Johnson295189b2012-06-20 16:38:30 -07008084 netif_tx_start_all_queues(dev);
8085 }
8086
8087 return 0;
8088}
8089
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05308090/**---------------------------------------------------------------------------
8091
8092 \brief hdd_open() - Wrapper function for __hdd_open to protect it from SSR
8093
8094 This is called in response to ifconfig up
8095
8096 \param - dev Pointer to net_device structure
8097
8098 \return - 0 for success non-zero for failure
8099
8100 --------------------------------------------------------------------------*/
8101int hdd_open(struct net_device *dev)
8102{
8103 int ret;
8104
8105 vos_ssr_protect(__func__);
8106 ret = __hdd_open(dev);
8107 vos_ssr_unprotect(__func__);
8108
8109 return ret;
8110}
8111
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05308112int __hdd_mon_open (struct net_device *dev)
Jeff Johnson295189b2012-06-20 16:38:30 -07008113{
8114 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +05308115 hdd_adapter_t *sta_adapter;
8116 hdd_context_t *hdd_ctx;
Jeff Johnson295189b2012-06-20 16:38:30 -07008117
8118 if(pAdapter == NULL) {
8119 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008120 "%s: HDD adapter context is Null", __func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08008121 return -EINVAL;
Jeff Johnson295189b2012-06-20 16:38:30 -07008122 }
8123
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +05308124 if (vos_get_concurrency_mode() != VOS_STA_MON)
8125 return 0;
8126
8127 hdd_ctx = WLAN_HDD_GET_CTX(pAdapter);
8128 if (wlan_hdd_validate_context(hdd_ctx))
8129 return -EINVAL;
8130
8131 sta_adapter = hdd_get_adapter(hdd_ctx, WLAN_HDD_INFRA_STATION);
8132 if (!sta_adapter) {
8133 hddLog(LOGE, FL("No valid STA interface"));
8134 return -EINVAL;
8135 }
8136
8137 if (!test_bit(DEVICE_IFACE_OPENED, &sta_adapter->event_flags)) {
8138 hddLog(LOGE, FL("STA Interface is not OPENED"));
8139 return -EINVAL;
8140 }
8141
8142 set_bit(DEVICE_IFACE_OPENED, &pAdapter->event_flags);
8143
Jeff Johnson295189b2012-06-20 16:38:30 -07008144 return 0;
8145}
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05308146
8147int hdd_mon_open (struct net_device *dev)
8148{
8149 int ret;
8150
8151 vos_ssr_protect(__func__);
8152 ret = __hdd_mon_open(dev);
8153 vos_ssr_unprotect(__func__);
8154
8155 return ret;
8156}
8157
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +05308158int __hdd_mon_stop (struct net_device *dev)
8159{
8160 hdd_adapter_t *mon_adapter = WLAN_HDD_GET_PRIV_PTR(dev);
8161 hdd_context_t *hdd_ctx;
8162
8163 if (vos_get_concurrency_mode() != VOS_STA_MON)
8164 return 0;
8165
8166 if(!mon_adapter) {
8167 hddLog(LOGE, FL("HDD adapter is Null"));
8168 return -EINVAL;
8169 }
8170
8171 hdd_ctx = WLAN_HDD_GET_CTX(mon_adapter);
8172 if (wlan_hdd_validate_context(hdd_ctx))
8173 return -EINVAL;
8174
8175 if (!test_bit(DEVICE_IFACE_OPENED, &mon_adapter->event_flags)) {
8176 hddLog(LOGE, FL("NETDEV Interface is not OPENED"));
8177 return -ENODEV;
8178 }
8179
8180 clear_bit(DEVICE_IFACE_OPENED, &mon_adapter->event_flags);
8181 hdd_stop_adapter(hdd_ctx, mon_adapter, VOS_FALSE);
8182
8183 return 0;
8184}
8185
Katya Nigame7b69a82015-04-28 15:24:06 +05308186int hdd_mon_stop(struct net_device *dev)
8187{
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +05308188 int ret;
8189
8190 vos_ssr_protect(__func__);
8191 ret = __hdd_mon_stop(dev);
8192 vos_ssr_unprotect(__func__);
8193
8194 return ret;
Katya Nigame7b69a82015-04-28 15:24:06 +05308195}
8196
Jeff Johnson295189b2012-06-20 16:38:30 -07008197/**---------------------------------------------------------------------------
8198
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05308199 \brief __hdd_stop() - HDD stop function
Jeff Johnson295189b2012-06-20 16:38:30 -07008200
8201 \param - dev Pointer to net_device structure
8202
8203 \return - 0 for success non-zero for failure
8204
8205 --------------------------------------------------------------------------*/
8206
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05308207int __hdd_stop (struct net_device *dev)
Jeff Johnson295189b2012-06-20 16:38:30 -07008208{
Vinay Krishna Eranna90f43532014-10-27 16:45:54 +05308209 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07008210 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
8211 hdd_context_t *pHddCtx;
8212 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
8213 VOS_STATUS status;
8214 v_BOOL_t enter_standby = TRUE;
8215
8216 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07008217 if (NULL == pAdapter)
8218 {
8219 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Agarwal Ashish971c2882013-10-30 20:11:12 +05308220 "%s: pAdapter is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07008221 return -ENODEV;
8222 }
Sachin Ahuja9b4958f2015-01-15 21:37:00 +05308223 MTRACE(vos_trace(VOS_MODULE_ID_HDD, TRACE_CODE_HDD_STOP_REQUEST,
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05308224 pAdapter->sessionId, pAdapter->device_mode));
Vinay Krishna Eranna90f43532014-10-27 16:45:54 +05308225
8226 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8227 ret = wlan_hdd_validate_context(pHddCtx);
8228 if (ret)
Jeff Johnson295189b2012-06-20 16:38:30 -07008229 {
Vinay Krishna Eranna90f43532014-10-27 16:45:54 +05308230 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07008231 }
8232
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05308233 /* Nothing to be done if the interface is not opened */
8234 if (VOS_FALSE == test_bit(DEVICE_IFACE_OPENED, &pAdapter->event_flags))
8235 {
8236 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8237 "%s: NETDEV Interface is not OPENED", __func__);
8238 return -ENODEV;
8239 }
8240
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +05308241 if (pHddCtx->concurrency_mode == VOS_STA_MON) {
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +05308242 /*
Rajeev Kumar Sirasanagandlaa74e1222018-01-09 17:38:55 +05308243 * In STA + Monitor mode concurrency, no point in running
8244 * capture on monitor interface, when STA interface is stopped
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +05308245 */
Rajeev Kumar Sirasanagandlaa74e1222018-01-09 17:38:55 +05308246 wlan_hdd_stop_mon(pHddCtx, true);
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +05308247 }
8248
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05308249 /* Make sure the interface is marked as closed */
Jeff Johnson6a81ca42013-04-05 10:37:08 -07008250 clear_bit(DEVICE_IFACE_OPENED, &pAdapter->event_flags);
Jeff Johnson295189b2012-06-20 16:38:30 -07008251 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Disabling OS Tx queues", __func__);
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05308252
8253 /* Disable TX on the interface, after this hard_start_xmit() will not
8254 * be called on that interface
8255 */
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +05308256 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Jeff Johnson295189b2012-06-20 16:38:30 -07008257 netif_tx_disable(pAdapter->dev);
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05308258
8259 /* Mark the interface status as "down" for outside world */
Jeff Johnson295189b2012-06-20 16:38:30 -07008260 netif_carrier_off(pAdapter->dev);
8261
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05308262 /* The interface is marked as down for outside world (aka kernel)
8263 * But the driver is pretty much alive inside. The driver needs to
8264 * tear down the existing connection on the netdev (session)
8265 * cleanup the data pipes and wait until the control plane is stabilized
8266 * for this interface. The call also needs to wait until the above
8267 * mentioned actions are completed before returning to the caller.
8268 * Notice that the hdd_stop_adapter is requested not to close the session
8269 * That is intentional to be able to scan if it is a STA/P2P interface
8270 */
8271 hdd_stop_adapter(pHddCtx, pAdapter, VOS_FALSE);
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05308272#ifdef FEATURE_WLAN_TDLS
8273 mutex_lock(&pHddCtx->tdls_lock);
8274#endif
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05308275 /* DeInit the adapter. This ensures datapath cleanup as well */
c_hpothu002231a2015-02-05 14:58:51 +05308276 hdd_deinit_adapter(pHddCtx, pAdapter, TRUE);
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05308277#ifdef FEATURE_WLAN_TDLS
8278 mutex_unlock(&pHddCtx->tdls_lock);
8279#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008280 /* SoftAP ifaces should never go in power save mode
8281 making sure same here. */
8282 if ( (WLAN_HDD_SOFTAP == pAdapter->device_mode )
Jeff Johnson295189b2012-06-20 16:38:30 -07008283 || (WLAN_HDD_P2P_GO == pAdapter->device_mode )
Jeff Johnson295189b2012-06-20 16:38:30 -07008284 )
8285 {
8286 /* SoftAP mode, so return from here */
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308287 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8288 "%s: In SAP MODE", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07008289 EXIT();
8290 return 0;
8291 }
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05308292 /* Find if any iface is up. If any iface is up then can't put device to
8293 * sleep/power save mode
8294 */
Jeff Johnson295189b2012-06-20 16:38:30 -07008295 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
8296 while ( (NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status) )
8297 {
Jeff Johnson6a81ca42013-04-05 10:37:08 -07008298 if (test_bit(DEVICE_IFACE_OPENED, &pAdapterNode->pAdapter->event_flags))
8299 {
8300 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Still other ifaces are up cannot "
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05308301 "put device to sleep", __func__);
Jeff Johnson6a81ca42013-04-05 10:37:08 -07008302 enter_standby = FALSE;
8303 break;
8304 }
8305 else
8306 {
8307 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
8308 pAdapterNode = pNext;
8309 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008310 }
8311
8312 if (TRUE == enter_standby)
8313 {
8314 hddLog(VOS_TRACE_LEVEL_INFO, "%s: All Interfaces are Down "
8315 "entering standby", __func__);
8316 if (VOS_STATUS_SUCCESS != wlan_hdd_enter_lowpower(pHddCtx))
8317 {
8318 /*log and return success*/
8319 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Failed to put "
8320 "wlan in power save", __func__);
8321 }
8322 }
Hanumanth Reddy Pothula972e1df2018-06-14 13:33:47 +05308323
8324 /*
8325 * Upon wifi turn off, DUT has to flush the scan results so if
8326 * this is the last cli iface, flush the scan database.
8327 */
8328 if (!hdd_is_cli_iface_up(pHddCtx))
8329 sme_ScanFlushResult(pHddCtx->hHal, 0);
Jeff Johnson295189b2012-06-20 16:38:30 -07008330
8331 EXIT();
8332 return 0;
8333}
8334
8335/**---------------------------------------------------------------------------
8336
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05308337 \brief hdd_stop() - wrapper_function for __hdd_stop to protect it from SSR
Jeff Johnson295189b2012-06-20 16:38:30 -07008338
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05308339 This is called in response to ifconfig down
8340
8341 \param - dev Pointer to net_device structure
8342
8343 \return - 0 for success non-zero for failure
8344-----------------------------------------------------------------------------*/
8345int hdd_stop (struct net_device *dev)
8346{
8347 int ret;
8348
8349 vos_ssr_protect(__func__);
8350 ret = __hdd_stop(dev);
8351 vos_ssr_unprotect(__func__);
8352
8353 return ret;
8354}
8355
8356/**---------------------------------------------------------------------------
8357
8358 \brief __hdd_uninit() - HDD uninit function
Jeff Johnson295189b2012-06-20 16:38:30 -07008359
8360 \param - dev Pointer to net_device structure
8361
8362 \return - void
8363
8364 --------------------------------------------------------------------------*/
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05308365static void __hdd_uninit (struct net_device *dev)
Jeff Johnson295189b2012-06-20 16:38:30 -07008366{
8367 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05308368 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07008369 ENTER();
8370
8371 do
8372 {
8373 if (NULL == pAdapter)
8374 {
8375 hddLog(VOS_TRACE_LEVEL_FATAL,
8376 "%s: NULL pAdapter", __func__);
8377 break;
8378 }
8379
8380 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
8381 {
8382 hddLog(VOS_TRACE_LEVEL_FATAL,
8383 "%s: Invalid magic", __func__);
8384 break;
8385 }
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05308386 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8387 if (NULL == pHddCtx)
Jeff Johnson295189b2012-06-20 16:38:30 -07008388 {
8389 hddLog(VOS_TRACE_LEVEL_FATAL,
8390 "%s: NULL pHddCtx", __func__);
8391 break;
8392 }
8393
8394 if (dev != pAdapter->dev)
8395 {
8396 hddLog(VOS_TRACE_LEVEL_FATAL,
8397 "%s: Invalid device reference", __func__);
8398 /* we haven't validated all cases so let this go for now */
8399 }
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05308400#ifdef FEATURE_WLAN_TDLS
8401 mutex_lock(&pHddCtx->tdls_lock);
8402#endif
c_hpothu002231a2015-02-05 14:58:51 +05308403 hdd_deinit_adapter(pHddCtx, pAdapter, TRUE);
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05308404#ifdef FEATURE_WLAN_TDLS
8405 mutex_unlock(&pHddCtx->tdls_lock);
8406#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008407
8408 /* after uninit our adapter structure will no longer be valid */
8409 pAdapter->dev = NULL;
8410 pAdapter->magic = 0;
Manjeet Singh47ee8472016-04-11 11:57:18 +05308411 pAdapter->pHddCtx = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07008412 } while (0);
8413
8414 EXIT();
8415}
8416
8417/**---------------------------------------------------------------------------
8418
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05308419 \brief hdd_uninit() - Wrapper function to protect __hdd_uninit from SSR
8420
8421 This is called during the netdev unregister to uninitialize all data
8422associated with the device
8423
8424 \param - dev Pointer to net_device structure
8425
8426 \return - void
8427
8428 --------------------------------------------------------------------------*/
8429static void hdd_uninit (struct net_device *dev)
8430{
8431 vos_ssr_protect(__func__);
8432 __hdd_uninit(dev);
8433 vos_ssr_unprotect(__func__);
8434}
8435
8436/**---------------------------------------------------------------------------
8437
Jeff Johnson295189b2012-06-20 16:38:30 -07008438 \brief hdd_release_firmware() -
8439
8440 This function calls the release firmware API to free the firmware buffer.
8441
8442 \param - pFileName Pointer to the File Name.
8443 pCtx - Pointer to the adapter .
8444
8445
8446 \return - 0 for success, non zero for failure
8447
8448 --------------------------------------------------------------------------*/
8449
8450VOS_STATUS hdd_release_firmware(char *pFileName,v_VOID_t *pCtx)
8451{
8452 VOS_STATUS status = VOS_STATUS_SUCCESS;
8453 hdd_context_t *pHddCtx = (hdd_context_t*)pCtx;
8454 ENTER();
8455
8456
8457 if (!strcmp(WLAN_FW_FILE, pFileName)) {
8458
8459 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,"%s: Loaded firmware file is %s",__func__,pFileName);
8460
8461 if(pHddCtx->fw) {
8462 release_firmware(pHddCtx->fw);
8463 pHddCtx->fw = NULL;
8464 }
8465 else
8466 status = VOS_STATUS_E_FAILURE;
8467 }
8468 else if (!strcmp(WLAN_NV_FILE,pFileName)) {
8469 if(pHddCtx->nv) {
8470 release_firmware(pHddCtx->nv);
8471 pHddCtx->nv = NULL;
8472 }
8473 else
8474 status = VOS_STATUS_E_FAILURE;
8475
8476 }
8477
8478 EXIT();
8479 return status;
8480}
8481
8482/**---------------------------------------------------------------------------
8483
8484 \brief hdd_request_firmware() -
8485
8486 This function reads the firmware file using the request firmware
8487 API and returns the the firmware data and the firmware file size.
8488
8489 \param - pfileName - Pointer to the file name.
8490 - pCtx - Pointer to the adapter .
8491 - ppfw_data - Pointer to the pointer of the firmware data.
8492 - pSize - Pointer to the file size.
8493
8494 \return - VOS_STATUS_SUCCESS for success, VOS_STATUS_E_FAILURE for failure
8495
8496 --------------------------------------------------------------------------*/
8497
8498
8499VOS_STATUS hdd_request_firmware(char *pfileName,v_VOID_t *pCtx,v_VOID_t **ppfw_data, v_SIZE_t *pSize)
8500{
8501 int status;
8502 VOS_STATUS retval = VOS_STATUS_SUCCESS;
8503 hdd_context_t *pHddCtx = (hdd_context_t*)pCtx;
8504 ENTER();
8505
8506 if( (!strcmp(WLAN_FW_FILE, pfileName)) ) {
8507
8508 status = request_firmware(&pHddCtx->fw, pfileName, pHddCtx->parent_dev);
8509
8510 if(status || !pHddCtx->fw || !pHddCtx->fw->data) {
8511 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Firmware %s download failed",
8512 __func__, pfileName);
8513 retval = VOS_STATUS_E_FAILURE;
8514 }
8515
8516 else {
8517 *ppfw_data = (v_VOID_t *)pHddCtx->fw->data;
8518 *pSize = pHddCtx->fw->size;
8519 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Firmware size = %d",
8520 __func__, *pSize);
8521 }
8522 }
8523 else if(!strcmp(WLAN_NV_FILE, pfileName)) {
8524
8525 status = request_firmware(&pHddCtx->nv, pfileName, pHddCtx->parent_dev);
8526
8527 if(status || !pHddCtx->nv || !pHddCtx->nv->data) {
8528 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: nv %s download failed",
8529 __func__, pfileName);
8530 retval = VOS_STATUS_E_FAILURE;
8531 }
8532
8533 else {
8534 *ppfw_data = (v_VOID_t *)pHddCtx->nv->data;
8535 *pSize = pHddCtx->nv->size;
8536 hddLog(VOS_TRACE_LEVEL_INFO, "%s: nv file size = %d",
8537 __func__, *pSize);
8538 }
8539 }
8540
8541 EXIT();
8542 return retval;
8543}
8544/**---------------------------------------------------------------------------
8545 \brief hdd_full_pwr_cbk() - HDD full power callbackfunction
8546
8547 This is the function invoked by SME to inform the result of a full power
8548 request issued by HDD
8549
8550 \param - callbackcontext - Pointer to cookie
8551 status - result of request
8552
8553 \return - None
8554
8555--------------------------------------------------------------------------*/
8556void hdd_full_pwr_cbk(void *callbackContext, eHalStatus status)
8557{
8558 hdd_context_t *pHddCtx = (hdd_context_t*)callbackContext;
8559
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07008560 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,"HDD full Power callback status = %d", status);
Jeff Johnson295189b2012-06-20 16:38:30 -07008561 if(&pHddCtx->full_pwr_comp_var)
8562 {
8563 complete(&pHddCtx->full_pwr_comp_var);
8564 }
8565}
8566
Abhishek Singh00b71972016-01-07 10:51:04 +05308567#ifdef WLAN_FEATURE_RMC
8568static void hdd_tx_fail_ind_callback(v_U8_t *MacAddr, v_U8_t seqNo)
8569{
8570 int payload_len;
8571 struct sk_buff *skb;
8572 struct nlmsghdr *nlh;
8573 v_U8_t *data;
8574
8575 payload_len = ETH_ALEN;
8576
8577 if (0 == cesium_pid)
8578 {
8579 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: cesium process not registered",
8580 __func__);
8581 return;
8582 }
8583
8584 if ((skb = nlmsg_new(payload_len,GFP_ATOMIC)) == NULL)
8585 {
8586 hddLog(VOS_TRACE_LEVEL_ERROR,
8587 "%s: nlmsg_new() failed for msg size[%d]",
8588 __func__, NLMSG_SPACE(payload_len));
8589 return;
8590 }
8591
8592 nlh = nlmsg_put(skb, cesium_pid, seqNo, 0, payload_len, NLM_F_REQUEST);
8593
8594 if (NULL == nlh)
8595 {
8596 hddLog(VOS_TRACE_LEVEL_ERROR,
8597 "%s: nlmsg_put() failed for msg size[%d]",
8598 __func__, NLMSG_SPACE(payload_len));
8599
8600 kfree_skb(skb);
8601 return;
8602 }
8603
8604 data = nlmsg_data(nlh);
8605 memcpy(data, MacAddr, ETH_ALEN);
8606
8607 if (nlmsg_unicast(cesium_nl_srv_sock, skb, cesium_pid) < 0)
8608 {
8609 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: nlmsg_unicast() failed for msg size[%d]",
8610 __func__, NLMSG_SPACE(payload_len));
8611 }
8612
8613 return;
8614}
8615
8616/**---------------------------------------------------------------------------
8617 \brief hdd_ParseuserParams - return a pointer to the next argument
8618
8619 \return - status
8620
8621--------------------------------------------------------------------------*/
8622static int hdd_ParseUserParams(tANI_U8 *pValue, tANI_U8 **ppArg)
8623{
8624 tANI_U8 *pVal;
8625
8626 pVal = strchr(pValue, ' ');
8627
8628 if (NULL == pVal)
8629 {
8630 /* no argument remains */
8631 return -EINVAL;
8632 }
8633 else if (SPACE_ASCII_VALUE != *pVal)
8634 {
8635 /* no space after the current argument */
8636 return -EINVAL;
8637 }
8638
8639 pVal++;
8640
8641 /* remove empty spaces */
8642 while ((SPACE_ASCII_VALUE == *pVal) && ('\0' != *pVal))
8643 {
8644 pVal++;
8645 }
8646
8647 /* no argument followed by spaces */
8648 if ('\0' == *pVal)
8649 {
8650 return -EINVAL;
8651 }
8652
8653 *ppArg = pVal;
8654
8655 return 0;
8656}
8657
8658/**----------------------------------------------------------------------------
8659 \brief hdd_ParseIBSSTXFailEventParams - Parse params for SETIBSSTXFAILEVENT
8660
8661 \return - status
8662
8663------------------------------------------------------------------------------*/
8664static int hdd_ParseIBSSTXFailEventParams(tANI_U8 *pValue,
8665 tANI_U8 *tx_fail_count,
8666 tANI_U16 *pid)
8667{
8668 tANI_U8 *param = NULL;
8669 int ret;
8670
8671 ret = hdd_ParseUserParams(pValue, &param);
8672
8673 if (0 == ret && NULL != param)
8674 {
8675 if (1 != sscanf(param, "%hhu", tx_fail_count))
8676 {
8677 ret = -EINVAL;
8678 goto done;
8679 }
8680 }
8681 else
8682 {
8683 goto done;
8684 }
8685
8686 if (0 == *tx_fail_count)
8687 {
8688 *pid = 0;
8689 goto done;
8690 }
8691
8692 pValue = param;
8693 pValue++;
8694
8695 ret = hdd_ParseUserParams(pValue, &param);
8696
8697 if (0 == ret)
8698 {
8699 if (1 != sscanf(param, "%hu", pid))
8700 {
8701 ret = -EINVAL;
8702 goto done;
8703 }
8704 }
8705 else
8706 {
8707 goto done;
8708 }
8709
8710done:
8711 return ret;
8712}
8713
8714static int hdd_open_cesium_nl_sock()
8715{
8716#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
8717 struct netlink_kernel_cfg cfg = {
8718 .groups = WLAN_NLINK_MCAST_GRP_ID,
8719 .input = NULL
8720 };
8721#endif
8722 int ret = 0;
8723
8724#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
8725 cesium_nl_srv_sock = netlink_kernel_create(&init_net, WLAN_NLINK_CESIUM,
8726#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,7,0))
8727 THIS_MODULE,
8728#endif
8729 &cfg);
8730#else
8731 cesium_nl_srv_sock = netlink_kernel_create(&init_net, WLAN_NLINK_CESIUM,
8732 WLAN_NLINK_MCAST_GRP_ID, NULL, NULL, THIS_MODULE);
8733#endif
8734
8735 if (cesium_nl_srv_sock == NULL)
8736 {
8737 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8738 "NLINK: cesium netlink_kernel_create failed");
8739 ret = -ECONNREFUSED;
8740 }
8741
8742 return ret;
8743}
8744
8745static void hdd_close_cesium_nl_sock()
8746{
8747 if (NULL != cesium_nl_srv_sock)
8748 {
8749 netlink_kernel_release(cesium_nl_srv_sock);
8750 cesium_nl_srv_sock = NULL;
8751 }
8752}
8753#endif /* WLAN_FEATURE_RMC */
Jeff Johnson295189b2012-06-20 16:38:30 -07008754/**---------------------------------------------------------------------------
8755
8756 \brief hdd_req_bmps_cbk() - HDD Request BMPS callback function
8757
8758 This is the function invoked by SME to inform the result of BMPS
8759 request issued by HDD
8760
8761 \param - callbackcontext - Pointer to cookie
8762 status - result of request
8763
8764 \return - None
8765
8766--------------------------------------------------------------------------*/
8767void hdd_req_bmps_cbk(void *callbackContext, eHalStatus status)
8768{
8769
8770 struct completion *completion_var = (struct completion*) callbackContext;
8771
Arif Hussain6d2a3322013-11-17 19:50:10 -08008772 hddLog(VOS_TRACE_LEVEL_ERROR, "HDD BMPS request Callback, status = %d", status);
Jeff Johnson295189b2012-06-20 16:38:30 -07008773 if(completion_var != NULL)
8774 {
8775 complete(completion_var);
8776 }
8777}
8778
8779/**---------------------------------------------------------------------------
8780
8781 \brief hdd_get_cfg_file_size() -
8782
8783 This function reads the configuration file using the request firmware
8784 API and returns the configuration file size.
8785
8786 \param - pCtx - Pointer to the adapter .
8787 - pFileName - Pointer to the file name.
8788 - pBufSize - Pointer to the buffer size.
8789
8790 \return - 0 for success, non zero for failure
8791
8792 --------------------------------------------------------------------------*/
8793
8794VOS_STATUS hdd_get_cfg_file_size(v_VOID_t *pCtx, char *pFileName, v_SIZE_t *pBufSize)
8795{
8796 int status;
8797 hdd_context_t *pHddCtx = (hdd_context_t*)pCtx;
8798
8799 ENTER();
8800
8801 status = request_firmware(&pHddCtx->fw, pFileName, pHddCtx->parent_dev);
8802
8803 if(status || !pHddCtx->fw || !pHddCtx->fw->data) {
8804 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: CFG download failed",__func__);
8805 status = VOS_STATUS_E_FAILURE;
8806 }
8807 else {
8808 *pBufSize = pHddCtx->fw->size;
8809 hddLog(VOS_TRACE_LEVEL_INFO, "%s: CFG size = %d", __func__, *pBufSize);
8810 release_firmware(pHddCtx->fw);
8811 pHddCtx->fw = NULL;
8812 }
8813
8814 EXIT();
8815 return VOS_STATUS_SUCCESS;
8816}
8817
8818/**---------------------------------------------------------------------------
8819
8820 \brief hdd_read_cfg_file() -
8821
8822 This function reads the configuration file using the request firmware
8823 API and returns the cfg data and the buffer size of the configuration file.
8824
8825 \param - pCtx - Pointer to the adapter .
8826 - pFileName - Pointer to the file name.
8827 - pBuffer - Pointer to the data buffer.
8828 - pBufSize - Pointer to the buffer size.
8829
8830 \return - 0 for success, non zero for failure
8831
8832 --------------------------------------------------------------------------*/
8833
8834VOS_STATUS hdd_read_cfg_file(v_VOID_t *pCtx, char *pFileName,
8835 v_VOID_t *pBuffer, v_SIZE_t *pBufSize)
8836{
8837 int status;
8838 hdd_context_t *pHddCtx = (hdd_context_t*)pCtx;
8839
8840 ENTER();
8841
8842 status = request_firmware(&pHddCtx->fw, pFileName, pHddCtx->parent_dev);
8843
8844 if(status || !pHddCtx->fw || !pHddCtx->fw->data) {
8845 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: CFG download failed",__func__);
8846 return VOS_STATUS_E_FAILURE;
8847 }
8848 else {
8849 if(*pBufSize != pHddCtx->fw->size) {
8850 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Caller sets invalid CFG "
8851 "file size", __func__);
8852 release_firmware(pHddCtx->fw);
8853 pHddCtx->fw = NULL;
8854 return VOS_STATUS_E_FAILURE;
8855 }
8856 else {
8857 if(pBuffer) {
8858 vos_mem_copy(pBuffer,pHddCtx->fw->data,*pBufSize);
8859 }
8860 release_firmware(pHddCtx->fw);
8861 pHddCtx->fw = NULL;
8862 }
8863 }
8864
8865 EXIT();
8866
8867 return VOS_STATUS_SUCCESS;
8868}
8869
8870/**---------------------------------------------------------------------------
8871
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05308872 \brief __hdd_set_mac_address() -
Jeff Johnson295189b2012-06-20 16:38:30 -07008873
8874 This function sets the user specified mac address using
8875 the command ifconfig wlanX hw ether <mac adress>.
8876
8877 \param - dev - Pointer to the net device.
8878 - addr - Pointer to the sockaddr.
8879 \return - 0 for success, non zero for failure
8880
8881 --------------------------------------------------------------------------*/
8882
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05308883static int __hdd_set_mac_address(struct net_device *dev, void *addr)
Jeff Johnson295189b2012-06-20 16:38:30 -07008884{
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05308885 hdd_adapter_t *pAdapter;
8886 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07008887 struct sockaddr *psta_mac_addr = addr;
8888 eHalStatus halStatus = eHAL_STATUS_SUCCESS;
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05308889 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07008890
8891 ENTER();
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05308892 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
8893 if (NULL == pAdapter)
8894 {
8895 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8896 "%s: Adapter is NULL",__func__);
8897 return -EINVAL;
8898 }
8899 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8900 ret = wlan_hdd_validate_context(pHddCtx);
8901 if (0 != ret)
8902 {
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05308903 return ret;
8904 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008905
8906 memcpy(&pAdapter->macAddressCurrent, psta_mac_addr->sa_data, ETH_ALEN);
Jeff Johnson295189b2012-06-20 16:38:30 -07008907 memcpy(dev->dev_addr, psta_mac_addr->sa_data, ETH_ALEN);
8908
8909 EXIT();
8910 return halStatus;
8911}
8912
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05308913/**---------------------------------------------------------------------------
8914
8915 \brief hdd_set_mac_address() -
8916
8917 Wrapper function to protect __hdd_set_mac_address() function from ssr
8918
8919 \param - dev - Pointer to the net device.
8920 - addr - Pointer to the sockaddr.
8921 \return - 0 for success, non zero for failure
8922
8923 --------------------------------------------------------------------------*/
8924static int hdd_set_mac_address(struct net_device *dev, void *addr)
8925{
8926 int ret;
8927
8928 vos_ssr_protect(__func__);
8929 ret = __hdd_set_mac_address(dev, addr);
8930 vos_ssr_unprotect(__func__);
8931
8932 return ret;
8933}
8934
Jeff Johnson295189b2012-06-20 16:38:30 -07008935tANI_U8* wlan_hdd_get_intf_addr(hdd_context_t* pHddCtx)
8936{
8937 int i;
8938 for ( i = 0; i < VOS_MAX_CONCURRENCY_PERSONA; i++)
8939 {
Abhishek Singheb183782014-02-06 13:37:21 +05308940 if( 0 == ((pHddCtx->cfg_ini->intfAddrMask) & (1 << i)) )
Jeff Johnson295189b2012-06-20 16:38:30 -07008941 break;
8942 }
8943
8944 if( VOS_MAX_CONCURRENCY_PERSONA == i)
8945 return NULL;
8946
8947 pHddCtx->cfg_ini->intfAddrMask |= (1 << i);
8948 return &pHddCtx->cfg_ini->intfMacAddr[i].bytes[0];
8949}
8950
8951void wlan_hdd_release_intf_addr(hdd_context_t* pHddCtx, tANI_U8* releaseAddr)
8952{
8953 int i;
8954 for ( i = 0; i < VOS_MAX_CONCURRENCY_PERSONA; i++)
8955 {
8956 if ( !memcmp(releaseAddr, &pHddCtx->cfg_ini->intfMacAddr[i].bytes[0], 6) )
8957 {
8958 pHddCtx->cfg_ini->intfAddrMask &= ~(1 << i);
8959 break;
8960 }
8961 }
8962 return;
8963}
8964
8965#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29))
8966 static struct net_device_ops wlan_drv_ops = {
8967 .ndo_open = hdd_open,
8968 .ndo_stop = hdd_stop,
8969 .ndo_uninit = hdd_uninit,
8970 .ndo_start_xmit = hdd_hard_start_xmit,
8971 .ndo_tx_timeout = hdd_tx_timeout,
8972 .ndo_get_stats = hdd_stats,
8973 .ndo_do_ioctl = hdd_ioctl,
8974 .ndo_set_mac_address = hdd_set_mac_address,
8975 .ndo_select_queue = hdd_select_queue,
8976#ifdef WLAN_FEATURE_PACKET_FILTERING
8977#if (LINUX_VERSION_CODE > KERNEL_VERSION(3,1,0))
8978 .ndo_set_rx_mode = hdd_set_multicast_list,
8979#else
8980 .ndo_set_multicast_list = hdd_set_multicast_list,
8981#endif //LINUX_VERSION_CODE
8982#endif
8983 };
Jeff Johnson295189b2012-06-20 16:38:30 -07008984 static struct net_device_ops wlan_mon_drv_ops = {
8985 .ndo_open = hdd_mon_open,
Katya Nigame7b69a82015-04-28 15:24:06 +05308986 .ndo_stop = hdd_mon_stop,
Jeff Johnson295189b2012-06-20 16:38:30 -07008987 .ndo_uninit = hdd_uninit,
8988 .ndo_start_xmit = hdd_mon_hard_start_xmit,
8989 .ndo_tx_timeout = hdd_tx_timeout,
8990 .ndo_get_stats = hdd_stats,
Katya Nigame7b69a82015-04-28 15:24:06 +05308991 .ndo_do_ioctl = hdd_mon_ioctl,
Jeff Johnson295189b2012-06-20 16:38:30 -07008992 .ndo_set_mac_address = hdd_set_mac_address,
8993 };
Mahesh A Saptasagar305e2632015-03-04 12:57:33 +05308994
Jeff Johnson295189b2012-06-20 16:38:30 -07008995#endif
8996
8997void hdd_set_station_ops( struct net_device *pWlanDev )
8998{
8999#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29))
Jeff Johnson295189b2012-06-20 16:38:30 -07009000 pWlanDev->netdev_ops = &wlan_drv_ops;
9001#else
9002 pWlanDev->open = hdd_open;
9003 pWlanDev->stop = hdd_stop;
9004 pWlanDev->uninit = hdd_uninit;
9005 pWlanDev->hard_start_xmit = NULL;
9006 pWlanDev->tx_timeout = hdd_tx_timeout;
9007 pWlanDev->get_stats = hdd_stats;
9008 pWlanDev->do_ioctl = hdd_ioctl;
Jeff Johnson295189b2012-06-20 16:38:30 -07009009 pWlanDev->set_mac_address = hdd_set_mac_address;
9010#endif
9011}
9012
Katya Nigam1fd24402015-02-16 14:52:19 +05309013void hdd_set_ibss_ops( hdd_adapter_t *pAdapter )
9014{
9015 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29))
9016 wlan_drv_ops.ndo_start_xmit = hdd_ibss_hard_start_xmit;
9017 #else
9018 pAdapter->dev->hard_start_xmit = hdd_ibss_hard_start_xmit;
9019 #endif
9020}
9021
Jeff Johnsoneed415b2013-01-18 16:11:20 -08009022static hdd_adapter_t* hdd_alloc_station_adapter( hdd_context_t *pHddCtx, tSirMacAddr macAddr, const char* name )
Jeff Johnson295189b2012-06-20 16:38:30 -07009023{
9024 struct net_device *pWlanDev = NULL;
9025 hdd_adapter_t *pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07009026 /*
9027 * cfg80211 initialization and registration....
9028 */
Anand N Sunkadc34abbd2015-07-29 09:52:59 +05309029 pWlanDev = alloc_netdev_mq(sizeof( hdd_adapter_t ), name,
9030#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,17,0))
9031 NET_NAME_UNKNOWN,
9032#endif
9033 ether_setup, NUM_TX_QUEUES);
Jeff Johnson295189b2012-06-20 16:38:30 -07009034 if(pWlanDev != NULL)
9035 {
9036
9037 //Save the pointer to the net_device in the HDD adapter
9038 pAdapter = (hdd_adapter_t*) netdev_priv( pWlanDev );
9039
Jeff Johnson295189b2012-06-20 16:38:30 -07009040 vos_mem_zero( pAdapter, sizeof( hdd_adapter_t ) );
9041
9042 pAdapter->dev = pWlanDev;
9043 pAdapter->pHddCtx = pHddCtx;
9044 pAdapter->magic = WLAN_HDD_ADAPTER_MAGIC;
Agarwal Ashish47d18112014-08-04 19:55:07 +05309045 spin_lock_init(&pAdapter->lock_for_active_session);
Jeff Johnson295189b2012-06-20 16:38:30 -07009046
Rajeev79dbe4c2013-10-05 11:03:42 +05309047#ifdef FEATURE_WLAN_BATCH_SCAN
Rajeev79dbe4c2013-10-05 11:03:42 +05309048 pAdapter->pBatchScanRsp = NULL;
9049 pAdapter->numScanList = 0;
Rajeev Kumar20140c12013-10-21 19:39:02 -07009050 pAdapter->batchScanState = eHDD_BATCH_SCAN_STATE_STOPPED;
Kiet Lamaa8e15a2014-02-11 23:30:06 -08009051 pAdapter->prev_batch_id = 0;
Rajeev79dbe4c2013-10-05 11:03:42 +05309052 mutex_init(&pAdapter->hdd_batch_scan_lock);
9053#endif
9054
Jeff Johnson295189b2012-06-20 16:38:30 -07009055 pAdapter->isLinkUpSvcNeeded = FALSE;
9056 pAdapter->higherDtimTransition = eANI_BOOLEAN_TRUE;
9057 //Init the net_device structure
9058 strlcpy(pWlanDev->name, name, IFNAMSIZ);
9059
9060 vos_mem_copy(pWlanDev->dev_addr, (void *)macAddr, sizeof(tSirMacAddr));
9061 vos_mem_copy( pAdapter->macAddressCurrent.bytes, macAddr, sizeof(tSirMacAddr));
9062 pWlanDev->watchdog_timeo = HDD_TX_TIMEOUT;
Alok Kumar84458542018-05-14 15:03:08 +05309063
9064 pWlanDev->needed_headroom = LIBRA_HW_NEEDED_HEADROOM;
Jeff Johnson295189b2012-06-20 16:38:30 -07009065
9066 hdd_set_station_ops( pAdapter->dev );
9067
9068 pWlanDev->destructor = free_netdev;
Jeff Johnson295189b2012-06-20 16:38:30 -07009069 pWlanDev->ieee80211_ptr = &pAdapter->wdev ;
9070 pAdapter->wdev.wiphy = pHddCtx->wiphy;
9071 pAdapter->wdev.netdev = pWlanDev;
Jeff Johnson295189b2012-06-20 16:38:30 -07009072 /* set pWlanDev's parent to underlying device */
9073 SET_NETDEV_DEV(pWlanDev, pHddCtx->parent_dev);
Kumar Anand82c009f2014-05-29 00:29:42 -07009074
9075 hdd_wmm_init( pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -07009076 }
9077
9078 return pAdapter;
9079}
9080
9081VOS_STATUS hdd_register_interface( hdd_adapter_t *pAdapter, tANI_U8 rtnl_lock_held )
9082{
9083 struct net_device *pWlanDev = pAdapter->dev;
9084 //hdd_station_ctx_t *pHddStaCtx = &pAdapter->sessionCtx.station;
9085 //hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
9086 //eHalStatus halStatus = eHAL_STATUS_SUCCESS;
9087
9088 if( rtnl_lock_held )
9089 {
Madan Mohan Koyyalamudid8ac8662012-11-06 19:04:56 -08009090 if (strnchr(pWlanDev->name, strlen(pWlanDev->name), '%')) {
Jeff Johnson295189b2012-06-20 16:38:30 -07009091 if( dev_alloc_name(pWlanDev, pWlanDev->name) < 0 )
9092 {
9093 hddLog(VOS_TRACE_LEVEL_ERROR,"%s:Failed:dev_alloc_name",__func__);
9094 return VOS_STATUS_E_FAILURE;
9095 }
9096 }
9097 if (register_netdevice(pWlanDev))
9098 {
9099 hddLog(VOS_TRACE_LEVEL_ERROR,"%s:Failed:register_netdev",__func__);
9100 return VOS_STATUS_E_FAILURE;
9101 }
9102 }
9103 else
9104 {
9105 if(register_netdev(pWlanDev))
9106 {
9107 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Failed:register_netdev",__func__);
9108 return VOS_STATUS_E_FAILURE;
9109 }
9110 }
9111 set_bit(NET_DEVICE_REGISTERED, &pAdapter->event_flags);
9112
9113 return VOS_STATUS_SUCCESS;
9114}
9115
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07009116static eHalStatus hdd_smeCloseSessionCallback(void *pContext)
Jeff Johnson295189b2012-06-20 16:38:30 -07009117{
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07009118 hdd_adapter_t *pAdapter = pContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07009119
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07009120 if (NULL == pAdapter)
9121 {
9122 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: NULL pAdapter", __func__);
9123 return eHAL_STATUS_INVALID_PARAMETER;
Jeff Johnson295189b2012-06-20 16:38:30 -07009124 }
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07009125
9126 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
9127 {
9128 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Invalid magic", __func__);
9129 return eHAL_STATUS_NOT_INITIALIZED;
9130 }
9131
9132 clear_bit(SME_SESSION_OPENED, &pAdapter->event_flags);
9133
Sameer Thalappilbee426e2013-10-30 10:30:30 -07009134#ifndef WLAN_OPEN_SOURCE
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07009135 /* need to make sure all of our scheduled work has completed.
9136 * This callback is called from MC thread context, so it is safe to
9137 * to call below flush workqueue API from here.
Sameer Thalappilbee426e2013-10-30 10:30:30 -07009138 *
9139 * Even though this is called from MC thread context, if there is a faulty
9140 * work item in the system, that can hang this call forever. So flushing
9141 * this global work queue is not safe; and now we make sure that
9142 * individual work queues are stopped correctly. But the cancel work queue
9143 * is a GPL only API, so the proprietary version of the driver would still
9144 * rely on the global work queue flush.
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07009145 */
9146 flush_scheduled_work();
Sameer Thalappilbee426e2013-10-30 10:30:30 -07009147#endif
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07009148
9149 /* We can be blocked while waiting for scheduled work to be
9150 * flushed, and the adapter structure can potentially be freed, in
9151 * which case the magic will have been reset. So make sure the
9152 * magic is still good, and hence the adapter structure is still
9153 * valid, before signaling completion */
9154 if (WLAN_HDD_ADAPTER_MAGIC == pAdapter->magic)
9155 {
9156 complete(&pAdapter->session_close_comp_var);
9157 }
9158
Jeff Johnson295189b2012-06-20 16:38:30 -07009159 return eHAL_STATUS_SUCCESS;
9160}
Manjeet Singh47ee8472016-04-11 11:57:18 +05309161/**
9162 * hdd_close_tx_queues() - close tx queues
9163 * @hdd_ctx: hdd global context
9164 *
9165 * Return: None
9166 */
9167static void hdd_close_tx_queues(hdd_context_t *hdd_ctx)
9168{
9169 VOS_STATUS status;
9170 hdd_adapter_t *adapter;
9171 hdd_adapter_list_node_t *adapter_node = NULL, *next_adapter = NULL;
9172 /* Not validating hdd_ctx as it's already done by the caller */
9173 ENTER();
9174 status = hdd_get_front_adapter(hdd_ctx, &adapter_node);
9175 while (NULL != adapter_node && VOS_STATUS_SUCCESS == status) {
9176 adapter = adapter_node->pAdapter;
9177 if (adapter && adapter->dev) {
9178 netif_tx_disable (adapter->dev);
9179 netif_carrier_off(adapter->dev);
9180 }
9181 status = hdd_get_next_adapter(hdd_ctx, adapter_node,
9182 &next_adapter);
9183 adapter_node = next_adapter;
9184 }
9185 EXIT();
9186}
Jeff Johnson295189b2012-06-20 16:38:30 -07009187
9188VOS_STATUS hdd_init_station_mode( hdd_adapter_t *pAdapter )
9189{
9190 struct net_device *pWlanDev = pAdapter->dev;
9191 hdd_station_ctx_t *pHddStaCtx = &pAdapter->sessionCtx.station;
9192 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
9193 eHalStatus halStatus = eHAL_STATUS_SUCCESS;
9194 VOS_STATUS status = VOS_STATUS_E_FAILURE;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309195 long rc = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07009196
Nirav Shah7e3c8132015-06-22 23:51:42 +05309197 spin_lock_init( &pAdapter->sta_hash_lock);
9198 pAdapter->is_sta_id_hash_initialized = VOS_FALSE;
9199
Jeff Johnson295189b2012-06-20 16:38:30 -07009200 INIT_COMPLETION(pAdapter->session_open_comp_var);
Kiran Kumar Lokere0ad5cd32013-06-25 11:26:22 -07009201 sme_SetCurrDeviceMode(pHddCtx->hHal, pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07009202 //Open a SME session for future operation
9203 halStatus = sme_OpenSession( pHddCtx->hHal, hdd_smeRoamCallback, pAdapter,
Kiran Kumar Lokere0ad5cd32013-06-25 11:26:22 -07009204 (tANI_U8 *)&pAdapter->macAddressCurrent, &pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07009205 if ( !HAL_STATUS_SUCCESS( halStatus ) )
9206 {
9207 hddLog(VOS_TRACE_LEVEL_FATAL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07009208 "sme_OpenSession() failed with status code %08d [x%08x]",
Jeff Johnson295189b2012-06-20 16:38:30 -07009209 halStatus, halStatus );
9210 status = VOS_STATUS_E_FAILURE;
9211 goto error_sme_open;
9212 }
9213
9214 //Block on a completion variable. Can't wait forever though.
Vinay Krishna Eranna0fe2e7c2014-04-09 21:32:08 +05309215 rc = wait_for_completion_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -07009216 &pAdapter->session_open_comp_var,
9217 msecs_to_jiffies(WLAN_WAIT_TIME_SESSIONOPENCLOSE));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309218 if (rc <= 0)
Jeff Johnson295189b2012-06-20 16:38:30 -07009219 {
9220 hddLog(VOS_TRACE_LEVEL_FATAL,
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309221 "Session is not opened within timeout period code %ld", rc );
Jeff Johnson295189b2012-06-20 16:38:30 -07009222 status = VOS_STATUS_E_FAILURE;
9223 goto error_sme_open;
9224 }
9225
9226 // Register wireless extensions
9227 if( eHAL_STATUS_SUCCESS != (halStatus = hdd_register_wext(pWlanDev)))
9228 {
9229 hddLog(VOS_TRACE_LEVEL_FATAL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07009230 "hdd_register_wext() failed with status code %08d [x%08x]",
Jeff Johnson295189b2012-06-20 16:38:30 -07009231 halStatus, halStatus );
9232 status = VOS_STATUS_E_FAILURE;
9233 goto error_register_wext;
9234 }
Katya Nigam1fd24402015-02-16 14:52:19 +05309235
Jeff Johnson295189b2012-06-20 16:38:30 -07009236 //Safe to register the hard_start_xmit function again
Katya Nigam1fd24402015-02-16 14:52:19 +05309237 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29))
9238 wlan_drv_ops.ndo_start_xmit = hdd_hard_start_xmit;
9239 #else
9240 pWlanDev->hard_start_xmit = hdd_hard_start_xmit;
9241 #endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009242
9243 //Set the Connection State to Not Connected
Abhishek Singhf4669da2014-05-26 15:07:49 +05309244 hddLog(VOS_TRACE_LEVEL_INFO,
9245 "%s: Set HDD connState to eConnectionState_NotConnected",
9246 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009247 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
9248
9249 //Set the default operation channel
9250 pHddStaCtx->conn_info.operationChannel = pHddCtx->cfg_ini->OperatingChannel;
9251
9252 /* Make the default Auth Type as OPEN*/
9253 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_OPEN_SYSTEM;
9254
9255 if( VOS_STATUS_SUCCESS != ( status = hdd_init_tx_rx( pAdapter ) ) )
9256 {
9257 hddLog(VOS_TRACE_LEVEL_FATAL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07009258 "hdd_init_tx_rx() failed with status code %08d [x%08x]",
Jeff Johnson295189b2012-06-20 16:38:30 -07009259 status, status );
9260 goto error_init_txrx;
9261 }
9262
9263 set_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
9264
9265 if( VOS_STATUS_SUCCESS != ( status = hdd_wmm_adapter_init( pAdapter ) ) )
9266 {
9267 hddLog(VOS_TRACE_LEVEL_FATAL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07009268 "hdd_wmm_adapter_init() failed with status code %08d [x%08x]",
Jeff Johnson295189b2012-06-20 16:38:30 -07009269 status, status );
9270 goto error_wmm_init;
9271 }
9272
9273 set_bit(WMM_INIT_DONE, &pAdapter->event_flags);
9274
9275 return VOS_STATUS_SUCCESS;
9276
9277error_wmm_init:
9278 clear_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
9279 hdd_deinit_tx_rx(pAdapter);
9280error_init_txrx:
9281 hdd_UnregisterWext(pWlanDev);
9282error_register_wext:
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07009283 if (test_bit(SME_SESSION_OPENED, &pAdapter->event_flags))
Jeff Johnson295189b2012-06-20 16:38:30 -07009284 {
9285 INIT_COMPLETION(pAdapter->session_close_comp_var);
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07009286 if (eHAL_STATUS_SUCCESS == sme_CloseSession(pHddCtx->hHal,
Agrawal Ashish5a3522c2016-03-02 15:08:28 +05309287 pAdapter->sessionId, FALSE, VOS_TRUE,
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07009288 hdd_smeCloseSessionCallback, pAdapter))
Jeff Johnson295189b2012-06-20 16:38:30 -07009289 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309290 unsigned long rc;
9291
Jeff Johnson295189b2012-06-20 16:38:30 -07009292 //Block on a completion variable. Can't wait forever though.
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309293 rc = wait_for_completion_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -07009294 &pAdapter->session_close_comp_var,
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07009295 msecs_to_jiffies(WLAN_WAIT_TIME_SESSIONOPENCLOSE));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309296 if (rc <= 0)
9297 hddLog(VOS_TRACE_LEVEL_ERROR,
9298 FL("Session is not opened within timeout period code %ld"), rc);
Jeff Johnson295189b2012-06-20 16:38:30 -07009299 }
9300}
9301error_sme_open:
9302 return status;
9303}
9304
Jeff Johnson295189b2012-06-20 16:38:30 -07009305void hdd_cleanup_actionframe( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter )
9306{
9307 hdd_cfg80211_state_t *cfgState;
9308
9309 cfgState = WLAN_HDD_GET_CFG_STATE_PTR( pAdapter );
9310
9311 if( NULL != cfgState->buf )
9312 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309313 long rc;
Jeff Johnson295189b2012-06-20 16:38:30 -07009314 INIT_COMPLETION(pAdapter->tx_action_cnf_event);
9315 rc = wait_for_completion_interruptible_timeout(
9316 &pAdapter->tx_action_cnf_event,
9317 msecs_to_jiffies(ACTION_FRAME_TX_TIMEOUT));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309318 if (rc <= 0)
Jeff Johnson295189b2012-06-20 16:38:30 -07009319 {
Deepthi Gowri91b3e9c2015-08-25 13:14:58 +05309320 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9321 "%s ERROR: HDD Wait for Action Confirmation Failed!! %ld"
9322 , __func__, rc);
9323
9324 // Inform tx status as FAILURE to upper layer and free cfgState->buf
9325 hdd_sendActionCnf( pAdapter, FALSE );
Jeff Johnson295189b2012-06-20 16:38:30 -07009326 }
9327 }
9328 return;
9329}
Jeff Johnson295189b2012-06-20 16:38:30 -07009330
c_hpothu002231a2015-02-05 14:58:51 +05309331void hdd_deinit_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter, tANI_U8 rtnl_held )
Jeff Johnson295189b2012-06-20 16:38:30 -07009332{
9333 ENTER();
9334 switch ( pAdapter->device_mode )
9335 {
Katya Nigam1fd24402015-02-16 14:52:19 +05309336 case WLAN_HDD_IBSS:
9337 {
9338 if(test_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags))
9339 {
9340 hdd_ibss_deinit_tx_rx( pAdapter );
9341 clear_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
9342 }
9343 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009344 case WLAN_HDD_INFRA_STATION:
9345 case WLAN_HDD_P2P_CLIENT:
Jeff Johnsone7245742012-09-05 17:12:55 -07009346 case WLAN_HDD_P2P_DEVICE:
Jeff Johnson295189b2012-06-20 16:38:30 -07009347 {
9348 if(test_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags))
9349 {
9350 hdd_deinit_tx_rx( pAdapter );
9351 clear_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
9352 }
9353
9354 if(test_bit(WMM_INIT_DONE, &pAdapter->event_flags))
9355 {
9356 hdd_wmm_adapter_close( pAdapter );
9357 clear_bit(WMM_INIT_DONE, &pAdapter->event_flags);
9358 }
9359
Jeff Johnson295189b2012-06-20 16:38:30 -07009360 hdd_cleanup_actionframe(pHddCtx, pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07009361 break;
9362 }
9363
9364 case WLAN_HDD_SOFTAP:
9365 case WLAN_HDD_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07009366 {
Madan Mohan Koyyalamudi8c6dec82013-09-26 15:56:13 +05309367
9368 if (test_bit(WMM_INIT_DONE, &pAdapter->event_flags))
9369 {
9370 hdd_wmm_adapter_close( pAdapter );
9371 clear_bit(WMM_INIT_DONE, &pAdapter->event_flags);
9372 }
9373
Jeff Johnson295189b2012-06-20 16:38:30 -07009374 hdd_cleanup_actionframe(pHddCtx, pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07009375
c_hpothu002231a2015-02-05 14:58:51 +05309376 hdd_unregister_hostapd(pAdapter, rtnl_held);
Agrawal Ashisha0584d42016-09-29 13:03:45 +05309377 /* set con_mode to STA only when no SAP concurrency mode */
9378 if (!(hdd_get_concurrency_mode() & (VOS_SAP | VOS_P2P_GO)))
9379 hdd_set_conparam(0);
Jeff Johnson295189b2012-06-20 16:38:30 -07009380 break;
9381 }
9382
9383 case WLAN_HDD_MONITOR:
9384 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009385 if(test_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags))
9386 {
9387 hdd_deinit_tx_rx( pAdapter );
9388 clear_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
9389 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009390 break;
9391 }
9392
9393
9394 default:
9395 break;
9396 }
9397
9398 EXIT();
9399}
9400
9401void hdd_cleanup_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter, tANI_U8 rtnl_held )
9402{
Mingcheng Zhu87f22fc2014-01-30 19:23:32 -08009403 struct net_device *pWlanDev = NULL;
Srinivas, Dasari693dfc52013-12-27 17:29:09 +05309404
9405 ENTER();
9406 if (NULL == pAdapter)
9407 {
9408 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9409 "%s: HDD adapter is Null", __func__);
9410 return;
9411 }
9412
9413 pWlanDev = pAdapter->dev;
Jeff Johnson295189b2012-06-20 16:38:30 -07009414
Rajeev79dbe4c2013-10-05 11:03:42 +05309415#ifdef FEATURE_WLAN_BATCH_SCAN
Srinivas, Dasari693dfc52013-12-27 17:29:09 +05309416 if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
9417 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Rajeev Kumarf999e582014-01-09 17:33:29 -08009418 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Srinivas, Dasari693dfc52013-12-27 17:29:09 +05309419 || (pAdapter->device_mode == WLAN_HDD_P2P_DEVICE)
9420 )
9421 {
Rajeev Kumarf999e582014-01-09 17:33:29 -08009422 if (pAdapter)
Rajeev79dbe4c2013-10-05 11:03:42 +05309423 {
Rajeev Kumarf999e582014-01-09 17:33:29 -08009424 if (eHDD_BATCH_SCAN_STATE_STARTED == pAdapter->batchScanState)
9425 {
9426 hdd_deinit_batch_scan(pAdapter);
9427 }
Rajeev79dbe4c2013-10-05 11:03:42 +05309428 }
Rajeev Kumarf999e582014-01-09 17:33:29 -08009429 }
Rajeev79dbe4c2013-10-05 11:03:42 +05309430#endif
9431
Jeff Johnson295189b2012-06-20 16:38:30 -07009432 if(test_bit(NET_DEVICE_REGISTERED, &pAdapter->event_flags)) {
9433 if( rtnl_held )
9434 {
9435 unregister_netdevice(pWlanDev);
9436 }
9437 else
9438 {
9439 unregister_netdev(pWlanDev);
9440 }
9441 // note that the pAdapter is no longer valid at this point
9442 // since the memory has been reclaimed
9443 }
9444
Srinivas, Dasari693dfc52013-12-27 17:29:09 +05309445 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07009446}
9447
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08009448void hdd_set_pwrparams(hdd_context_t *pHddCtx)
9449{
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05309450 VOS_STATUS status;
9451 hdd_adapter_t *pAdapter = NULL;
9452 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08009453
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05309454 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08009455
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05309456 /*loop through all adapters.*/
9457 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08009458 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05309459 pAdapter = pAdapterNode->pAdapter;
9460 if ( (WLAN_HDD_INFRA_STATION != pAdapter->device_mode)
9461 && (WLAN_HDD_P2P_CLIENT != pAdapter->device_mode) )
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08009462
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05309463 { // we skip this registration for modes other than STA and P2P client modes.
9464 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
9465 pAdapterNode = pNext;
9466 continue;
9467 }
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08009468
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05309469 //Apply Dynamic DTIM For P2P
9470 //Only if ignoreDynamicDtimInP2pMode is not set in ini
9471 if ((pHddCtx->cfg_ini->enableDynamicDTIM ||
9472 pHddCtx->cfg_ini->enableModulatedDTIM) &&
9473 ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
9474 ((WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) &&
9475 !(pHddCtx->cfg_ini->ignoreDynamicDtimInP2pMode))) &&
9476 (eANI_BOOLEAN_TRUE == pAdapter->higherDtimTransition) &&
9477 (eConnectionState_Associated ==
9478 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState) &&
9479 (pHddCtx->cfg_ini->fIsBmpsEnabled))
9480 {
9481 tSirSetPowerParamsReq powerRequest = { 0 };
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08009482
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05309483 powerRequest.uIgnoreDTIM = 1;
9484 powerRequest.uMaxLIModulatedDTIM = pHddCtx->cfg_ini->fMaxLIModulatedDTIM;
9485
9486 if (pHddCtx->cfg_ini->enableModulatedDTIM)
9487 {
9488 powerRequest.uDTIMPeriod = pHddCtx->cfg_ini->enableModulatedDTIM;
9489 powerRequest.uListenInterval = pHddCtx->hdd_actual_LI_value;
9490 }
9491 else
9492 {
9493 powerRequest.uListenInterval = pHddCtx->cfg_ini->enableDynamicDTIM;
9494 }
9495
9496 /* Update ignoreDTIM and ListedInterval in CFG to remain at the DTIM
9497 * specified during Enter/Exit BMPS when LCD off*/
9498 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IGNORE_DTIM, powerRequest.uIgnoreDTIM,
9499 NULL, eANI_BOOLEAN_FALSE);
9500 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_LISTEN_INTERVAL, powerRequest.uListenInterval,
9501 NULL, eANI_BOOLEAN_FALSE);
9502
9503 /* switch to the DTIM specified in cfg.ini */
9504 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Abhishek Singh1e390cf2015-10-27 13:45:17 +05309505 "Switch to DTIM %d Listen interval %d",
9506 powerRequest.uDTIMPeriod,
9507 powerRequest.uListenInterval);
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05309508 sme_SetPowerParams( pHddCtx->hHal, &powerRequest, TRUE);
9509 break;
9510
9511 }
9512
9513 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
9514 pAdapterNode = pNext;
9515 }
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08009516}
9517
9518void hdd_reset_pwrparams(hdd_context_t *pHddCtx)
9519{
9520 /*Switch back to DTIM 1*/
9521 tSirSetPowerParamsReq powerRequest = { 0 };
9522
9523 powerRequest.uIgnoreDTIM = pHddCtx->hdd_actual_ignore_DTIM_value;
9524 powerRequest.uListenInterval = pHddCtx->hdd_actual_LI_value;
Yue Mac24062f2013-05-13 17:01:29 -07009525 powerRequest.uMaxLIModulatedDTIM = pHddCtx->cfg_ini->fMaxLIModulatedDTIM;
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08009526
9527 /* Update ignoreDTIM and ListedInterval in CFG with default values */
9528 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IGNORE_DTIM, powerRequest.uIgnoreDTIM,
9529 NULL, eANI_BOOLEAN_FALSE);
9530 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_LISTEN_INTERVAL, powerRequest.uListenInterval,
9531 NULL, eANI_BOOLEAN_FALSE);
9532
9533 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
9534 "Switch to DTIM%d",powerRequest.uListenInterval);
9535 sme_SetPowerParams( pHddCtx->hHal, &powerRequest, TRUE);
9536
9537}
9538
Jeff Johnson295189b2012-06-20 16:38:30 -07009539VOS_STATUS hdd_enable_bmps_imps(hdd_context_t *pHddCtx)
9540{
9541 VOS_STATUS status = VOS_STATUS_SUCCESS;
Sushant Kaushik4928e542014-12-29 15:25:54 +05309542 if (WLAN_HDD_IS_UNLOAD_IN_PROGRESS(pHddCtx))
9543 {
9544 hddLog( LOGE, FL("Wlan Unload in progress"));
9545 return VOS_STATUS_E_PERM;
9546 }
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +05309547
9548 if (wlan_hdd_check_monitor_state(pHddCtx)) {
9549 hddLog(LOG1, FL("Monitor mode is started, cannot enable BMPS"));
9550 return VOS_STATUS_SUCCESS;
9551 }
9552
Jeff Johnson295189b2012-06-20 16:38:30 -07009553 if(pHddCtx->cfg_ini->fIsBmpsEnabled)
9554 {
9555 sme_EnablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
9556 }
9557
9558 if(pHddCtx->cfg_ini->fIsAutoBmpsTimerEnabled)
9559 {
9560 sme_StartAutoBmpsTimer(pHddCtx->hHal);
9561 }
9562
9563 if (pHddCtx->cfg_ini->fIsImpsEnabled)
9564 {
9565 sme_EnablePowerSave (pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
9566 }
9567
9568 return status;
9569}
9570
9571VOS_STATUS hdd_disable_bmps_imps(hdd_context_t *pHddCtx, tANI_U8 session_type)
9572{
9573 hdd_adapter_t *pAdapter = NULL;
9574 eHalStatus halStatus;
9575 VOS_STATUS status = VOS_STATUS_E_INVAL;
9576 v_BOOL_t disableBmps = FALSE;
9577 v_BOOL_t disableImps = FALSE;
9578
9579 switch(session_type)
9580 {
9581 case WLAN_HDD_INFRA_STATION:
9582 case WLAN_HDD_SOFTAP:
Jeff Johnson295189b2012-06-20 16:38:30 -07009583 case WLAN_HDD_P2P_CLIENT:
9584 case WLAN_HDD_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07009585 //Exit BMPS -> Is Sta/P2P Client is already connected
9586 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION);
9587 if((NULL != pAdapter)&&
9588 hdd_connIsConnected( WLAN_HDD_GET_STATION_CTX_PTR(pAdapter)))
9589 {
9590 disableBmps = TRUE;
9591 }
9592
9593 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_CLIENT);
9594 if((NULL != pAdapter)&&
9595 hdd_connIsConnected( WLAN_HDD_GET_STATION_CTX_PTR(pAdapter)))
9596 {
9597 disableBmps = TRUE;
9598 }
9599
9600 //Exit both Bmps and Imps incase of Go/SAP Mode
9601 if((WLAN_HDD_SOFTAP == session_type) ||
9602 (WLAN_HDD_P2P_GO == session_type))
9603 {
9604 disableBmps = TRUE;
9605 disableImps = TRUE;
9606 }
9607
9608 if(TRUE == disableImps)
9609 {
9610 if (pHddCtx->cfg_ini->fIsImpsEnabled)
9611 {
9612 sme_DisablePowerSave (pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
9613 }
9614 }
9615
9616 if(TRUE == disableBmps)
9617 {
9618 if(pHddCtx->cfg_ini->fIsBmpsEnabled)
9619 {
9620 halStatus = sme_DisablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
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 Disable Power Save", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009626 VOS_ASSERT(0);
9627 return status;
9628 }
9629 }
9630
9631 if(pHddCtx->cfg_ini->fIsAutoBmpsTimerEnabled)
9632 {
9633 halStatus = sme_StopAutoBmpsTimer(pHddCtx->hHal);
9634
9635 if(eHAL_STATUS_SUCCESS != halStatus)
9636 {
9637 status = VOS_STATUS_E_FAILURE;
Arif Hussain6d2a3322013-11-17 19:50:10 -08009638 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Fail to Stop Auto Bmps Timer", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009639 VOS_ASSERT(0);
9640 return status;
9641 }
9642 }
9643 }
9644
9645 if((TRUE == disableBmps) ||
9646 (TRUE == disableImps))
9647 {
9648 /* Now, get the chip into Full Power now */
9649 INIT_COMPLETION(pHddCtx->full_pwr_comp_var);
9650 halStatus = sme_RequestFullPower(pHddCtx->hHal, hdd_full_pwr_cbk,
9651 pHddCtx, eSME_FULL_PWR_NEEDED_BY_HDD);
9652
9653 if(halStatus != eHAL_STATUS_SUCCESS)
9654 {
9655 if(halStatus == eHAL_STATUS_PMC_PENDING)
9656 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309657 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07009658 //Block on a completion variable. Can't wait forever though
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309659 ret = wait_for_completion_interruptible_timeout(
9660 &pHddCtx->full_pwr_comp_var,
9661 msecs_to_jiffies(1000));
9662 if (ret <= 0)
9663 {
9664 hddLog(VOS_TRACE_LEVEL_ERROR,
9665 "%s: wait on full_pwr_comp_var failed %ld",
9666 __func__, ret);
9667 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009668 }
9669 else
9670 {
9671 status = VOS_STATUS_E_FAILURE;
Arif Hussain6d2a3322013-11-17 19:50:10 -08009672 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Request for Full Power failed", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009673 VOS_ASSERT(0);
9674 return status;
9675 }
9676 }
9677
9678 status = VOS_STATUS_SUCCESS;
9679 }
9680
9681 break;
9682 }
9683 return status;
9684}
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +05309685
Hanumanth Reddy Pothulab8be9ab2018-04-12 20:03:05 +05309686void hdd_mon_post_msg_cb(void *context)
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +05309687{
Hanumanth Reddy Pothulab8be9ab2018-04-12 20:03:05 +05309688 struct hdd_request *request;
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +05309689
Hanumanth Reddy Pothulab8be9ab2018-04-12 20:03:05 +05309690 request = hdd_request_get(context);
9691 if (!request) {
9692 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Obsolete request"));
9693 return;
9694 }
9695
9696 hdd_request_complete(request);
9697 hdd_request_put(request);
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +05309698}
9699
Hanumanth Reddy Pothulab8be9ab2018-04-12 20:03:05 +05309700
Katya Nigame7b69a82015-04-28 15:24:06 +05309701void hdd_init_mon_mode (hdd_adapter_t *pAdapter)
9702 {
9703 hdd_mon_ctx_t *pMonCtx = NULL;
Katya Nigame7b69a82015-04-28 15:24:06 +05309704
Rajeev Kumar Sirasanagandla54447612018-03-06 15:49:56 +05309705 spin_lock_init(&pAdapter->sta_hash_lock);
9706 pAdapter->is_sta_id_hash_initialized = VOS_FALSE;
9707
9708 pMonCtx = WLAN_HDD_GET_MONITOR_CTX_PTR(pAdapter);
Katya Nigame7b69a82015-04-28 15:24:06 +05309709 pMonCtx->state = 0;
9710 pMonCtx->ChannelNo = 1;
9711 pMonCtx->ChannelBW = 20;
Katya Nigamd7d3a1f2015-06-11 14:04:24 +05309712 pMonCtx->crcCheckEnabled = 1;
9713 pMonCtx->typeSubtypeBitmap = 0xFFFF00000000;
9714 pMonCtx->is80211to803ConReq = 1;
Katya Nigame7b69a82015-04-28 15:24:06 +05309715 pMonCtx->numOfMacFilters = 0;
9716 }
9717
Jeff Johnson295189b2012-06-20 16:38:30 -07009718
9719hdd_adapter_t* hdd_open_adapter( hdd_context_t *pHddCtx, tANI_U8 session_type,
Jeff Johnsoneed415b2013-01-18 16:11:20 -08009720 const char *iface_name, tSirMacAddr macAddr,
Jeff Johnson295189b2012-06-20 16:38:30 -07009721 tANI_U8 rtnl_held )
9722{
9723 hdd_adapter_t *pAdapter = NULL;
9724 hdd_adapter_list_node_t *pHddAdapterNode = NULL;
9725 VOS_STATUS status = VOS_STATUS_E_FAILURE;
9726 VOS_STATUS exitbmpsStatus;
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +05309727 v_CONTEXT_t pVosContext = NULL;
9728
9729 /* No need to check for NULL, reaching this step
9730 * means vos context is initialized
9731 */
9732 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
Jeff Johnson295189b2012-06-20 16:38:30 -07009733
Arif Hussain6d2a3322013-11-17 19:50:10 -08009734 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s iface =%s type = %d",__func__,iface_name,session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07009735
Nirav Shah436658f2014-02-28 17:05:45 +05309736 if(macAddr == NULL)
9737 {
9738 /* Not received valid macAddr */
9739 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9740 "%s:Unable to add virtual intf: Not able to get"
9741 "valid mac address",__func__);
9742 return NULL;
9743 }
9744
Jeff Johnson295189b2012-06-20 16:38:30 -07009745 //Disable BMPS incase of Concurrency
9746 exitbmpsStatus = hdd_disable_bmps_imps(pHddCtx, session_type);
9747
9748 if(VOS_STATUS_E_FAILURE == exitbmpsStatus)
9749 {
9750 //Fail to Exit BMPS
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309751 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Fail to Exit BMPS", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009752 VOS_ASSERT(0);
9753 return NULL;
9754 }
9755
9756 switch(session_type)
9757 {
9758 case WLAN_HDD_INFRA_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -07009759 case WLAN_HDD_P2P_CLIENT:
Jeff Johnsone7245742012-09-05 17:12:55 -07009760 case WLAN_HDD_P2P_DEVICE:
Jeff Johnson295189b2012-06-20 16:38:30 -07009761 {
9762 pAdapter = hdd_alloc_station_adapter( pHddCtx, macAddr, iface_name );
9763
9764 if( NULL == pAdapter )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309765 {
9766 hddLog(VOS_TRACE_LEVEL_FATAL,
9767 FL("failed to allocate adapter for session %d"), session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07009768 return NULL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309769 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009770
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05309771#ifdef FEATURE_WLAN_TDLS
9772 /* A Mutex Lock is introduced while changing/initializing the mode to
9773 * protect the concurrent access for the Adapters by TDLS module.
9774 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05309775 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05309776#endif
9777
Jeff Johnsone7245742012-09-05 17:12:55 -07009778 pAdapter->wdev.iftype = (session_type == WLAN_HDD_P2P_CLIENT) ?
9779 NL80211_IFTYPE_P2P_CLIENT:
9780 NL80211_IFTYPE_STATION;
Jeff Johnson295189b2012-06-20 16:38:30 -07009781
Jeff Johnson295189b2012-06-20 16:38:30 -07009782 pAdapter->device_mode = session_type;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05309783#ifdef FEATURE_WLAN_TDLS
9784 mutex_unlock(&pHddCtx->tdls_lock);
9785#endif
Sunil Dutt66485cb2013-12-19 19:05:03 +05309786
Mahesh A Saptasagar67ab9222015-10-21 15:38:41 +05309787 hdd_initialize_adapter_common(pAdapter);
Sunil Dutt66485cb2013-12-19 19:05:03 +05309788 status = hdd_init_station_mode( pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -07009789 if( VOS_STATUS_SUCCESS != status )
9790 goto err_free_netdev;
9791
9792 status = hdd_register_interface( pAdapter, rtnl_held );
9793 if( VOS_STATUS_SUCCESS != status )
9794 {
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05309795#ifdef FEATURE_WLAN_TDLS
9796 mutex_lock(&pHddCtx->tdls_lock);
9797#endif
c_hpothu002231a2015-02-05 14:58:51 +05309798 hdd_deinit_adapter(pHddCtx, pAdapter, rtnl_held);
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05309799#ifdef FEATURE_WLAN_TDLS
9800 mutex_unlock(&pHddCtx->tdls_lock);
9801#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009802 goto err_free_netdev;
9803 }
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05309804
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +05309805 // Workqueue which gets scheduled in IPv4 notification callback.
Anand N Sunkaddc63c792015-06-03 14:33:24 +05309806 vos_init_work(&pAdapter->ipv4NotifierWorkQueue, hdd_ipv4_notifier_work_queue);
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +05309807
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05309808#ifdef WLAN_NS_OFFLOAD
9809 // Workqueue which gets scheduled in IPv6 notification callback.
Anand N Sunkaddc63c792015-06-03 14:33:24 +05309810 vos_init_work(&pAdapter->ipv6NotifierWorkQueue, hdd_ipv6_notifier_work_queue);
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05309811#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009812 //Stop the Interface TX queue.
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +05309813 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Jeff Johnson295189b2012-06-20 16:38:30 -07009814 netif_tx_disable(pAdapter->dev);
9815 //netif_tx_disable(pWlanDev);
9816 netif_carrier_off(pAdapter->dev);
9817
Ganesh Kondabattinibabfb492014-12-17 20:25:29 +05309818 if (WLAN_HDD_P2P_CLIENT == session_type ||
9819 WLAN_HDD_P2P_DEVICE == session_type)
9820 {
9821 /* Initialize the work queue to defer the
9822 * back to back RoC request */
Anand N Sunkaddc63c792015-06-03 14:33:24 +05309823 vos_init_delayed_work(&pAdapter->roc_work,
Ganesh Kondabattinibabfb492014-12-17 20:25:29 +05309824 hdd_p2p_roc_work_queue);
9825 }
9826
Jeff Johnson295189b2012-06-20 16:38:30 -07009827 break;
9828 }
9829
Jeff Johnson295189b2012-06-20 16:38:30 -07009830 case WLAN_HDD_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07009831 case WLAN_HDD_SOFTAP:
9832 {
9833 pAdapter = hdd_wlan_create_ap_dev( pHddCtx, macAddr, (tANI_U8 *)iface_name );
9834 if( NULL == pAdapter )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309835 {
9836 hddLog(VOS_TRACE_LEVEL_FATAL,
9837 FL("failed to allocate adapter for session %d"), session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07009838 return NULL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309839 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009840
Jeff Johnson295189b2012-06-20 16:38:30 -07009841 pAdapter->wdev.iftype = (session_type == WLAN_HDD_SOFTAP) ?
9842 NL80211_IFTYPE_AP:
9843 NL80211_IFTYPE_P2P_GO;
Jeff Johnson295189b2012-06-20 16:38:30 -07009844 pAdapter->device_mode = session_type;
9845
Mahesh A Saptasagar67ab9222015-10-21 15:38:41 +05309846 hdd_initialize_adapter_common(pAdapter);
Hanumanth Reddy Pothula15bc0fa2017-02-03 17:24:17 +05309847 status = hdd_init_ap_mode(pAdapter, false);
Jeff Johnson295189b2012-06-20 16:38:30 -07009848 if( VOS_STATUS_SUCCESS != status )
9849 goto err_free_netdev;
9850
Nirav Shah7e3c8132015-06-22 23:51:42 +05309851 status = hdd_sta_id_hash_attach(pAdapter);
9852 if (VOS_STATUS_SUCCESS != status)
9853 {
9854 hddLog(VOS_TRACE_LEVEL_FATAL,
9855 FL("failed to attach hash for session %d"), session_type);
9856 hdd_deinit_adapter(pHddCtx, pAdapter, rtnl_held);
9857 goto err_free_netdev;
9858 }
9859
Jeff Johnson295189b2012-06-20 16:38:30 -07009860 status = hdd_register_hostapd( pAdapter, rtnl_held );
9861 if( VOS_STATUS_SUCCESS != status )
9862 {
c_hpothu002231a2015-02-05 14:58:51 +05309863 hdd_deinit_adapter(pHddCtx, pAdapter, rtnl_held);
Jeff Johnson295189b2012-06-20 16:38:30 -07009864 goto err_free_netdev;
9865 }
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +05309866 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Jeff Johnson295189b2012-06-20 16:38:30 -07009867 netif_tx_disable(pAdapter->dev);
9868 netif_carrier_off(pAdapter->dev);
9869
9870 hdd_set_conparam( 1 );
Ganesh Kondabattinibabfb492014-12-17 20:25:29 +05309871
Hanumanth Reddy Pothulab4537b82018-03-02 12:20:38 +05309872 // Workqueue which gets scheduled in IPv4 notification callback.
9873 vos_init_work(&pAdapter->ipv4NotifierWorkQueue,
9874 hdd_ipv4_notifier_work_queue);
9875
9876#ifdef WLAN_NS_OFFLOAD
9877 // Workqueue which gets scheduled in IPv6 notification callback.
9878 vos_init_work(&pAdapter->ipv6NotifierWorkQueue,
9879 hdd_ipv6_notifier_work_queue);
9880#endif
9881
Ganesh Kondabattinibabfb492014-12-17 20:25:29 +05309882 if (WLAN_HDD_P2P_GO == session_type)
9883 {
9884 /* Initialize the work queue to
9885 * defer the back to back RoC request */
9886 INIT_DELAYED_WORK(&pAdapter->roc_work,
9887 hdd_p2p_roc_work_queue);
9888 }
Bhargav Shahd0715912015-10-01 18:17:37 +05309889
Jeff Johnson295189b2012-06-20 16:38:30 -07009890 break;
9891 }
9892 case WLAN_HDD_MONITOR:
9893 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009894 pAdapter = hdd_alloc_station_adapter( pHddCtx, macAddr, iface_name );
9895 if( NULL == pAdapter )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309896 {
9897 hddLog(VOS_TRACE_LEVEL_FATAL,
9898 FL("failed to allocate adapter for session %d"), session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07009899 return NULL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309900 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009901
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +05309902 pAdapter->device_mode = session_type;
9903 pAdapter->wdev.iftype = NL80211_IFTYPE_MONITOR;
9904
Katya Nigame7b69a82015-04-28 15:24:06 +05309905 // Register wireless extensions
9906 if( VOS_STATUS_SUCCESS != (status = hdd_register_wext(pAdapter->dev)))
9907 {
9908 hddLog(VOS_TRACE_LEVEL_FATAL,
9909 "hdd_register_wext() failed with status code %08d [x%08x]",
9910 status, status );
9911 status = VOS_STATUS_E_FAILURE;
9912 }
9913
Jeff Johnson295189b2012-06-20 16:38:30 -07009914#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29)
9915 pAdapter->dev->netdev_ops = &wlan_mon_drv_ops;
9916#else
9917 pAdapter->dev->open = hdd_mon_open;
9918 pAdapter->dev->hard_start_xmit = hdd_mon_hard_start_xmit;
Katya Nigame7b69a82015-04-28 15:24:06 +05309919 pAdapter->dev->stop = hdd_mon_stop;
9920 pAdapter->dev->do_ioctl = hdd_mon_ioctl;
Jeff Johnson295189b2012-06-20 16:38:30 -07009921#endif
Katya Nigame7b69a82015-04-28 15:24:06 +05309922 hdd_init_mon_mode( pAdapter );
Mahesh A Saptasagar67ab9222015-10-21 15:38:41 +05309923 hdd_initialize_adapter_common(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07009924 hdd_init_tx_rx( pAdapter );
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +05309925
9926 if (VOS_MONITOR_MODE != hdd_get_conparam())
9927 WLANTL_SetMonRxCbk( pVosContext, hdd_rx_packet_monitor_cbk );
9928
Jeff Johnson295189b2012-06-20 16:38:30 -07009929 set_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +05309930 status = hdd_register_interface( pAdapter, rtnl_held );
Katya Nigame7b69a82015-04-28 15:24:06 +05309931 //Stop the Interface TX queue.
9932 netif_tx_disable(pAdapter->dev);
9933 netif_carrier_off(pAdapter->dev);
Jeff Johnson295189b2012-06-20 16:38:30 -07009934 }
9935 break;
Jeff Johnson295189b2012-06-20 16:38:30 -07009936 case WLAN_HDD_FTM:
9937 {
9938 pAdapter = hdd_alloc_station_adapter( pHddCtx, macAddr, iface_name );
9939
9940 if( NULL == pAdapter )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309941 {
9942 hddLog(VOS_TRACE_LEVEL_FATAL,
9943 FL("failed to allocate adapter for session %d"), session_type);
9944 return NULL;
9945 }
9946
Jeff Johnson295189b2012-06-20 16:38:30 -07009947 /* Assign NL80211_IFTYPE_STATION as interface type to resolve Kernel Warning
9948 * message while loading driver in FTM mode. */
9949 pAdapter->wdev.iftype = NL80211_IFTYPE_STATION;
9950 pAdapter->device_mode = session_type;
9951 status = hdd_register_interface( pAdapter, rtnl_held );
Madan Mohan Koyyalamudif89ac9f2013-09-19 16:58:12 +05309952
Mahesh A Saptasagar67ab9222015-10-21 15:38:41 +05309953 hdd_initialize_adapter_common(pAdapter);
Madan Mohan Koyyalamudif89ac9f2013-09-19 16:58:12 +05309954 hdd_init_tx_rx( pAdapter );
9955
9956 //Stop the Interface TX queue.
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +05309957 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Madan Mohan Koyyalamudif89ac9f2013-09-19 16:58:12 +05309958 netif_tx_disable(pAdapter->dev);
9959 netif_carrier_off(pAdapter->dev);
Jeff Johnson295189b2012-06-20 16:38:30 -07009960 }
9961 break;
Jeff Johnson295189b2012-06-20 16:38:30 -07009962 default:
9963 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309964 hddLog(VOS_TRACE_LEVEL_FATAL,"%s Invalid session type %d",
9965 __func__, session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07009966 VOS_ASSERT(0);
9967 return NULL;
9968 }
9969 }
9970
Jeff Johnson295189b2012-06-20 16:38:30 -07009971 if( VOS_STATUS_SUCCESS == status )
9972 {
Mahesh A Saptasagar67ab9222015-10-21 15:38:41 +05309973 //Add it to the hdd's session list.
Jeff Johnson295189b2012-06-20 16:38:30 -07009974 pHddAdapterNode = vos_mem_malloc( sizeof( hdd_adapter_list_node_t ) );
9975 if( NULL == pHddAdapterNode )
9976 {
9977 status = VOS_STATUS_E_NOMEM;
9978 }
9979 else
9980 {
9981 pHddAdapterNode->pAdapter = pAdapter;
9982 status = hdd_add_adapter_back ( pHddCtx,
9983 pHddAdapterNode );
9984 }
9985 }
9986
9987 if( VOS_STATUS_SUCCESS != status )
9988 {
9989 if( NULL != pAdapter )
9990 {
9991 hdd_cleanup_adapter( pHddCtx, pAdapter, rtnl_held );
9992 pAdapter = NULL;
9993 }
9994 if( NULL != pHddAdapterNode )
9995 {
9996 vos_mem_free( pHddAdapterNode );
9997 }
9998
9999 goto resume_bmps;
10000 }
10001
10002 if(VOS_STATUS_SUCCESS == status)
10003 {
10004 wlan_hdd_set_concurrency_mode(pHddCtx, session_type);
Madan Mohan Koyyalamudi96dd30d2012-10-05 17:24:51 -070010005 //Initialize the WoWL service
10006 if(!hdd_init_wowl(pAdapter))
10007 {
10008 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hdd_init_wowl failed",__func__);
10009 goto err_free_netdev;
10010 }
Manjeet Singh3ed79242017-01-11 19:04:32 +053010011 //Initialize the TSF capture data
10012 wlan_hdd_tsf_init(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070010013 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010014 return pAdapter;
10015
10016err_free_netdev:
Jeff Johnson295189b2012-06-20 16:38:30 -070010017 wlan_hdd_release_intf_addr( pHddCtx,
10018 pAdapter->macAddressCurrent.bytes );
Hanumanth Reddy Pothulaab8e1942018-05-24 18:10:39 +053010019 free_netdev(pAdapter->dev);
Jeff Johnson295189b2012-06-20 16:38:30 -070010020
10021resume_bmps:
10022 //If bmps disabled enable it
10023 if(VOS_STATUS_SUCCESS == exitbmpsStatus)
10024 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +053010025 if (pHddCtx->hdd_wlan_suspended)
10026 {
10027 hdd_set_pwrparams(pHddCtx);
10028 }
10029 hdd_enable_bmps_imps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -070010030 }
10031 return NULL;
10032}
10033
10034VOS_STATUS hdd_close_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter,
10035 tANI_U8 rtnl_held )
10036{
10037 hdd_adapter_list_node_t *pAdapterNode, *pCurrent, *pNext;
10038 VOS_STATUS status;
10039
10040 status = hdd_get_front_adapter ( pHddCtx, &pCurrent );
10041 if( VOS_STATUS_SUCCESS != status )
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010042 {
10043 hddLog(VOS_TRACE_LEVEL_WARN,"%s: adapter list empty %d",
10044 __func__, status);
Jeff Johnson295189b2012-06-20 16:38:30 -070010045 return status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010046 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010047
10048 while ( pCurrent->pAdapter != pAdapter )
10049 {
10050 status = hdd_get_next_adapter ( pHddCtx, pCurrent, &pNext );
10051 if( VOS_STATUS_SUCCESS != status )
10052 break;
10053
10054 pCurrent = pNext;
10055 }
10056 pAdapterNode = pCurrent;
10057 if( VOS_STATUS_SUCCESS == status )
10058 {
10059 wlan_hdd_clear_concurrency_mode(pHddCtx, pAdapter->device_mode);
10060 hdd_cleanup_adapter( pHddCtx, pAdapterNode->pAdapter, rtnl_held );
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053010061
10062#ifdef FEATURE_WLAN_TDLS
10063
10064 /* A Mutex Lock is introduced while changing/initializing the mode to
10065 * protect the concurrent access for the Adapters by TDLS module.
10066 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053010067 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053010068#endif
10069
Jeff Johnson295189b2012-06-20 16:38:30 -070010070 hdd_remove_adapter( pHddCtx, pAdapterNode );
10071 vos_mem_free( pAdapterNode );
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -080010072 pAdapterNode = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070010073
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053010074#ifdef FEATURE_WLAN_TDLS
10075 mutex_unlock(&pHddCtx->tdls_lock);
10076#endif
10077
Jeff Johnson295189b2012-06-20 16:38:30 -070010078
10079 /* If there is a single session of STA/P2P client, re-enable BMPS */
Agarwal Ashish51325b52014-06-16 16:50:49 +053010080 if ((!vos_concurrent_open_sessions_running()) &&
10081 ((pHddCtx->no_of_open_sessions[VOS_STA_MODE] >= 1) ||
10082 (pHddCtx->no_of_open_sessions[VOS_P2P_CLIENT_MODE] >= 1)))
Jeff Johnson295189b2012-06-20 16:38:30 -070010083 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +053010084 if (pHddCtx->hdd_wlan_suspended)
10085 {
10086 hdd_set_pwrparams(pHddCtx);
10087 }
10088 hdd_enable_bmps_imps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -070010089 }
10090
10091 return VOS_STATUS_SUCCESS;
10092 }
10093
10094 return VOS_STATUS_E_FAILURE;
10095}
10096
10097VOS_STATUS hdd_close_all_adapters( hdd_context_t *pHddCtx )
10098{
10099 hdd_adapter_list_node_t *pHddAdapterNode;
10100 VOS_STATUS status;
10101
10102 ENTER();
10103
10104 do
10105 {
10106 status = hdd_remove_front_adapter( pHddCtx, &pHddAdapterNode );
10107 if( pHddAdapterNode && VOS_STATUS_SUCCESS == status )
10108 {
10109 hdd_cleanup_adapter( pHddCtx, pHddAdapterNode->pAdapter, FALSE );
10110 vos_mem_free( pHddAdapterNode );
10111 }
10112 }while( NULL != pHddAdapterNode && VOS_STATUS_E_EMPTY != status );
10113
10114 EXIT();
10115
10116 return VOS_STATUS_SUCCESS;
10117}
10118
10119void wlan_hdd_reset_prob_rspies(hdd_adapter_t* pHostapdAdapter)
10120{
10121 v_U8_t addIE[1] = {0};
10122
10123 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
10124 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,(tANI_U8*)addIE, 0, NULL,
10125 eANI_BOOLEAN_FALSE) )
10126 {
10127 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010128 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -070010129 }
10130
10131 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
10132 WNI_CFG_PROBE_RSP_ADDNIE_DATA2, (tANI_U8*)addIE, 0, NULL,
10133 eANI_BOOLEAN_FALSE) )
10134 {
10135 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010136 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -070010137 }
10138
10139 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
10140 WNI_CFG_PROBE_RSP_ADDNIE_DATA3, (tANI_U8*)addIE, 0, NULL,
10141 eANI_BOOLEAN_FALSE) )
10142 {
10143 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010144 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -070010145 }
10146}
10147
Anurag Chouhan83026002016-12-13 22:46:21 +053010148VOS_STATUS hdd_cleanup_ap_events(hdd_adapter_t *adapter)
10149{
10150#ifdef DHCP_SERVER_OFFLOAD
10151 vos_event_destroy(&adapter->dhcp_status.vos_event);
10152#endif
Anurag Chouhan0b29de02016-12-16 13:18:40 +053010153#ifdef MDNS_OFFLOAD
10154 vos_event_destroy(&adapter->mdns_status.vos_event);
10155#endif
Anurag Chouhan83026002016-12-13 22:46:21 +053010156 return VOS_STATUS_SUCCESS;
10157}
10158
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +053010159int wlan_hdd_stop_mon(hdd_context_t *hdd_ctx, bool wait)
10160{
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +053010161 hdd_adapter_t *adapter;
Hanumanth Reddy Pothulab8be9ab2018-04-12 20:03:05 +053010162 hdd_mon_ctx_t *mon_ctx;
10163 void (*func_ptr)(void *context) = NULL;
10164 int ret = 0;
10165 void *cookie = NULL;
10166 struct hdd_request *request;
10167 static const struct hdd_request_params params = {
10168 .priv_size = 0,
10169 .timeout_ms = MON_MODE_MSG_TIMEOUT,
10170 };
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +053010171
10172 adapter = hdd_get_adapter(hdd_ctx, WLAN_HDD_MONITOR);
10173 if (!adapter) {
10174 hddLog(LOGE, FL("Invalid STA + MON mode"));
10175 return -EINVAL;
10176 }
10177
10178 mon_ctx = WLAN_HDD_GET_MONITOR_CTX_PTR(adapter);
10179 if (!mon_ctx)
10180 return 0;
10181
10182 if (mon_ctx->state != MON_MODE_START)
10183 return 0;
10184
10185 mon_ctx->state = MON_MODE_STOP;
10186 if (wait) {
Hanumanth Reddy Pothulab8be9ab2018-04-12 20:03:05 +053010187 func_ptr = hdd_mon_post_msg_cb;
10188 request = hdd_request_alloc(&params);
10189 if (!request) {
10190 hddLog(VOS_TRACE_LEVEL_ERROR,
10191 FL("Request allocation failure"));
10192 return -ENOMEM;
10193 }
10194 cookie = hdd_request_cookie(request);
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +053010195 }
10196
Hanumanth Reddy Pothulab8be9ab2018-04-12 20:03:05 +053010197 /*
10198 * If func_ptr is NULL, on receiving WDI_MON_START_RSP or
10199 * WDI_MON_STOP_RSP hdd_mon_post_msg_cb() won't be invoked
10200 * and so uninitialized cookie won't be accessed.
10201 */
10202 if (VOS_STATUS_SUCCESS != wlan_hdd_mon_postMsg(cookie,
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +053010203 mon_ctx,
Hanumanth Reddy Pothulab8be9ab2018-04-12 20:03:05 +053010204 func_ptr)) {
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +053010205 hddLog(LOGE, FL("failed to stop MON MODE"));
Hanumanth Reddy Pothulab8be9ab2018-04-12 20:03:05 +053010206 ret = -EINVAL;
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +053010207 }
10208
10209 if (!wait)
10210 goto bmps_roaming;
10211
Hanumanth Reddy Pothulab8be9ab2018-04-12 20:03:05 +053010212 if (!ret)
10213 ret = hdd_request_wait_for_response(request);
10214 hdd_request_put(request);
10215 if (ret) {
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +053010216 hddLog(LOGE,
Hanumanth Reddy Pothulab8be9ab2018-04-12 20:03:05 +053010217 FL("timeout on stop monitor mode completion %d"), ret);
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +053010218 return -EINVAL;
10219 }
10220
10221bmps_roaming:
10222 hddLog(LOG1, FL("Enable BMPS"));
10223 hdd_enable_bmps_imps(hdd_ctx);
10224 hdd_restore_roaming(hdd_ctx);
10225
10226 return 0;
10227}
10228
10229bool wlan_hdd_check_monitor_state(hdd_context_t *hdd_ctx)
10230{
10231 hdd_adapter_t *mon_adapter;
10232 hdd_mon_ctx_t *mon_ctx;
10233
10234 if (hdd_ctx->concurrency_mode != VOS_STA_MON)
10235 return false;
10236
10237 mon_adapter = hdd_get_adapter(hdd_ctx, WLAN_HDD_MONITOR);
10238 if (!mon_adapter) {
10239 hddLog(LOGE, FL("Invalid concurrency mode"));
10240 return false;
10241 }
10242
10243 mon_ctx = WLAN_HDD_GET_MONITOR_CTX_PTR(mon_adapter);
10244 if (mon_ctx->state == MON_MODE_START)
10245 return true;
10246
10247 return false;
10248}
10249
10250int wlan_hdd_check_and_stop_mon(hdd_adapter_t *sta_adapter, bool wait)
10251{
10252 hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(sta_adapter);
10253
10254 if ((sta_adapter->device_mode != WLAN_HDD_INFRA_STATION) ||
10255 !wlan_hdd_check_monitor_state(hdd_ctx))
10256 return 0;
10257
10258 if (wlan_hdd_stop_mon(hdd_ctx, wait))
10259 return -EINVAL;
10260
10261 return 0;
10262}
10263
10264void hdd_disable_roaming(hdd_context_t *hdd_ctx)
10265{
10266 if (!hdd_ctx)
10267 return;
10268
10269 if (!hdd_ctx->cfg_ini->isFastRoamIniFeatureEnabled) {
10270 hdd_ctx->roaming_ini_original = CFG_LFR_FEATURE_ENABLED_MIN;
10271 return;
10272 }
10273
10274 hddLog(LOG1, FL("Disable driver and firmware roaming"));
10275
10276 hdd_ctx->roaming_ini_original =
10277 hdd_ctx->cfg_ini->isFastRoamIniFeatureEnabled;
10278
10279 hdd_ctx->cfg_ini->isFastRoamIniFeatureEnabled =
10280 CFG_LFR_FEATURE_ENABLED_MIN;
10281
10282 sme_UpdateIsFastRoamIniFeatureEnabled(hdd_ctx->hHal,
10283 CFG_LFR_FEATURE_ENABLED_MIN);
10284}
10285
10286void hdd_restore_roaming(hdd_context_t *hdd_ctx)
10287{
10288 if (!hdd_ctx->roaming_ini_original)
10289 return;
10290
10291 hddLog(LOG1, FL("Enable driver and firmware roaming"));
10292
10293 hdd_ctx->cfg_ini->isFastRoamIniFeatureEnabled =
10294 CFG_LFR_FEATURE_ENABLED_MAX;
10295
10296 hdd_ctx->roaming_ini_original = CFG_LFR_FEATURE_ENABLED_MIN;
10297
10298 sme_UpdateIsFastRoamIniFeatureEnabled(hdd_ctx->hHal,
10299 CFG_LFR_FEATURE_ENABLED_MAX);
10300}
Anurag Chouhan83026002016-12-13 22:46:21 +053010301
Agarwal Ashish3a38bd12014-06-12 15:16:52 +053010302VOS_STATUS hdd_stop_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter,
10303 const v_BOOL_t bCloseSession )
Jeff Johnson295189b2012-06-20 16:38:30 -070010304{
10305 eHalStatus halStatus = eHAL_STATUS_SUCCESS;
10306 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Kaushik, Sushant4975a572014-10-21 16:07:48 +053010307 hdd_scaninfo_t *pScanInfo = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070010308 union iwreq_data wrqu;
Kaushik, Sushant7005e372014-04-08 11:36:54 +053010309 v_U8_t retry = 0;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010310 long ret;
Nirav Shah7e3c8132015-06-22 23:51:42 +053010311 VOS_STATUS status;
Jeff Johnson295189b2012-06-20 16:38:30 -070010312
Anand N Sunkad26d71b92014-12-24 18:08:22 +053010313 if (pHddCtx->isLogpInProgress) {
10314 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
10315 "%s:LOGP in Progress. Ignore!!!",__func__);
10316 return VOS_STATUS_E_FAILURE;
10317 }
10318
Jeff Johnson295189b2012-06-20 16:38:30 -070010319 ENTER();
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +053010320
Kaushik, Sushant4975a572014-10-21 16:07:48 +053010321 pScanInfo = &pHddCtx->scan_info;
Jeff Johnson295189b2012-06-20 16:38:30 -070010322 switch(pAdapter->device_mode)
10323 {
Nirav Shah0cf4d892015-11-05 16:27:27 +053010324 case WLAN_HDD_IBSS:
10325 if ( VOS_TRUE == bCloseSession )
10326 {
10327 status = hdd_sta_id_hash_detach(pAdapter);
10328 if (status != VOS_STATUS_SUCCESS)
10329 hddLog(VOS_TRACE_LEVEL_ERROR,
10330 FL("sta id hash detach failed"));
10331 }
10332
Jeff Johnson295189b2012-06-20 16:38:30 -070010333 case WLAN_HDD_INFRA_STATION:
10334 case WLAN_HDD_P2P_CLIENT:
Jeff Johnsone7245742012-09-05 17:12:55 -070010335 case WLAN_HDD_P2P_DEVICE:
Vinay Krishna Erannab09d3e72014-03-26 21:23:55 +053010336 {
10337 hdd_station_ctx_t *pstation = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Mahesh A Saptasagare4d05d42015-07-02 16:17:20 +053010338#ifdef FEATURE_WLAN_TDLS
10339 mutex_lock(&pHddCtx->tdls_lock);
10340 wlan_hdd_tdls_exit(pAdapter, TRUE);
10341 mutex_unlock(&pHddCtx->tdls_lock);
10342#endif
Vinay Krishna Erannab09d3e72014-03-26 21:23:55 +053010343 if( hdd_connIsConnected(pstation) ||
10344 (pstation->conn_info.connState == eConnectionState_Connecting) )
Jeff Johnson295189b2012-06-20 16:38:30 -070010345 {
Abhishek Singhe21a5212017-06-09 09:42:58 +053010346 /*
10347 * Indicate sme of disconnect so that in progress connection
10348 * or preauth can be aborted.
10349 */
10350 sme_abortConnection(WLAN_HDD_GET_HAL_CTX(pAdapter),
10351 pAdapter->sessionId);
Abhishek Singh99f17b82017-02-06 16:57:56 +053010352 INIT_COMPLETION(pAdapter->disconnect_comp_var);
Jeff Johnson295189b2012-06-20 16:38:30 -070010353 if (pWextState->roamProfile.BSSType == eCSR_BSS_TYPE_START_IBSS)
10354 halStatus = sme_RoamDisconnect(pHddCtx->hHal,
10355 pAdapter->sessionId,
10356 eCSR_DISCONNECT_REASON_IBSS_LEAVE);
10357 else
10358 halStatus = sme_RoamDisconnect(pHddCtx->hHal,
10359 pAdapter->sessionId,
10360 eCSR_DISCONNECT_REASON_UNSPECIFIED);
Abhishek Singh7b52ed52016-02-11 17:45:54 +053010361 /* Success implies disconnect command got queued up successfully
10362 * Or cmd not queued as scan for SSID is in progress
10363 */
10364 if((eHAL_STATUS_SUCCESS == halStatus) ||
10365 (eHAL_STATUS_CMD_NOT_QUEUED == halStatus))
Jeff Johnson295189b2012-06-20 16:38:30 -070010366 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010367 ret = wait_for_completion_interruptible_timeout(
10368 &pAdapter->disconnect_comp_var,
10369 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
Abhishek Singh7b52ed52016-02-11 17:45:54 +053010370 if (ret <= 0 &&
10371 (eHAL_STATUS_CMD_NOT_QUEUED != halStatus))
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010372 {
10373 hddLog(VOS_TRACE_LEVEL_ERROR,
10374 "%s: wait on disconnect_comp_var failed %ld",
10375 __func__, ret);
10376 }
10377 }
10378 else
10379 {
10380 hddLog(LOGE, "%s: failed to post disconnect event to SME",
10381 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070010382 }
10383 memset(&wrqu, '\0', sizeof(wrqu));
10384 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
10385 memset(wrqu.ap_addr.sa_data,'\0',ETH_ALEN);
10386 wireless_send_event(pAdapter->dev, SIOCGIWAP, &wrqu, NULL);
10387 }
Vinay Krishna Erannab09d3e72014-03-26 21:23:55 +053010388 else if(pstation->conn_info.connState ==
10389 eConnectionState_Disconnecting)
10390 {
10391 ret = wait_for_completion_interruptible_timeout(
10392 &pAdapter->disconnect_comp_var,
10393 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
10394 if (ret <= 0)
10395 {
10396 hddLog(VOS_TRACE_LEVEL_ERROR,
10397 FL("wait on disconnect_comp_var failed %ld"), ret);
10398 }
10399 }
Sachin Ahuja27dd2402016-08-01 20:30:31 +053010400 if(pScanInfo != NULL && pHddCtx->scan_info.mScanPending)
Jeff Johnson295189b2012-06-20 16:38:30 -070010401 {
Mahesh A Saptasagar0b61dcc2016-02-15 14:23:38 +053010402 wlan_hdd_scan_abort(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070010403 }
Abhishek Singh3ac179b2015-09-21 10:01:34 +053010404 if ((pAdapter->device_mode != WLAN_HDD_INFRA_STATION) &&
10405 (pAdapter->device_mode != WLAN_HDD_IBSS))
Kaushik, Sushant7005e372014-04-08 11:36:54 +053010406 {
10407 while (pAdapter->is_roc_inprogress)
10408 {
10409 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10410 "%s: ROC in progress for session %d!!!",
10411 __func__, pAdapter->sessionId);
10412 // waiting for ROC to expire
10413 msleep(500);
10414 /* In GO present case , if retry exceeds 3,
10415 it means something went wrong. */
10416 if ( retry++ > MAX_WAIT_FOR_ROC_COMPLETION )
10417 {
10418 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10419 "%s: ROC completion is not received.!!!", __func__);
Deepthi Gowri70498252015-01-20 15:56:45 +053010420 if (eHAL_STATUS_SUCCESS !=
10421 sme_CancelRemainOnChannel( WLAN_HDD_GET_HAL_CTX( pAdapter),
10422 pAdapter->sessionId ))
10423 {
10424 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10425 FL("Failed to Cancel Remain on Channel"));
10426 }
Kaushik, Sushant7005e372014-04-08 11:36:54 +053010427 wait_for_completion_interruptible_timeout(
10428 &pAdapter->cancel_rem_on_chan_var,
10429 msecs_to_jiffies(WAIT_CANCEL_REM_CHAN));
10430 break;
10431 }
10432 }
Anand N Sunkaddc63c792015-06-03 14:33:24 +053010433 vos_flush_delayed_work(&pAdapter->roc_work);
Kaushik, Sushant7005e372014-04-08 11:36:54 +053010434 }
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +053010435#ifdef WLAN_NS_OFFLOAD
Anand N Sunkaddc63c792015-06-03 14:33:24 +053010436 vos_flush_work(&pAdapter->ipv6NotifierWorkQueue);
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +053010437#endif
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +053010438
Anand N Sunkaddc63c792015-06-03 14:33:24 +053010439 vos_flush_work(&pAdapter->ipv4NotifierWorkQueue);
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +053010440
Agarwal Ashish3a38bd12014-06-12 15:16:52 +053010441 /* It is possible that the caller of this function does not
10442 * wish to close the session
10443 */
10444 if (VOS_TRUE == bCloseSession &&
10445 test_bit(SME_SESSION_OPENED, &pAdapter->event_flags))
Jeff Johnson295189b2012-06-20 16:38:30 -070010446 {
10447 INIT_COMPLETION(pAdapter->session_close_comp_var);
10448 if (eHAL_STATUS_SUCCESS ==
Agrawal Ashish5a3522c2016-03-02 15:08:28 +053010449 sme_CloseSession(pHddCtx->hHal, pAdapter->sessionId, FALSE,
10450 VOS_FALSE, hdd_smeCloseSessionCallback, pAdapter))
Jeff Johnson295189b2012-06-20 16:38:30 -070010451 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010452 unsigned long ret;
10453
Jeff Johnson295189b2012-06-20 16:38:30 -070010454 //Block on a completion variable. Can't wait forever though.
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010455 ret = wait_for_completion_timeout(
Agarwal Ashish3a38bd12014-06-12 15:16:52 +053010456 &pAdapter->session_close_comp_var,
10457 msecs_to_jiffies(WLAN_WAIT_TIME_SESSIONOPENCLOSE));
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010458 if ( 0 >= ret)
10459 {
10460 hddLog(LOGE, "%s: failure waiting for session_close_comp_var %ld",
Agarwal Ashish3a38bd12014-06-12 15:16:52 +053010461 __func__, ret);
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010462 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010463 }
10464 }
Vinay Krishna Erannab09d3e72014-03-26 21:23:55 +053010465 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010466 break;
10467
10468 case WLAN_HDD_SOFTAP:
10469 case WLAN_HDD_P2P_GO:
Nirav Shah0cf4d892015-11-05 16:27:27 +053010470 if ( VOS_TRUE == bCloseSession )
10471 {
10472 status = hdd_sta_id_hash_detach(pAdapter);
10473 if (status != VOS_STATUS_SUCCESS)
10474 hddLog(VOS_TRACE_LEVEL_ERROR,
10475 FL("sta id hash detach failed"));
10476 }
10477
Jeff Johnson295189b2012-06-20 16:38:30 -070010478 //Any softap specific cleanup here...
Anurag Chouhan83026002016-12-13 22:46:21 +053010479 hdd_cleanup_ap_events(pAdapter);
Kaushik, Sushant7005e372014-04-08 11:36:54 +053010480 if (pAdapter->device_mode == WLAN_HDD_P2P_GO) {
10481 while (pAdapter->is_roc_inprogress) {
10482 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10483 "%s: ROC in progress for session %d!!!",
10484 __func__, pAdapter->sessionId);
10485 msleep(500);
10486 if ( retry++ > MAX_WAIT_FOR_ROC_COMPLETION ) {
10487 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10488 "%s: ROC completion is not received.!!!", __func__);
10489 WLANSAP_CancelRemainOnChannel(
10490 (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
10491 wait_for_completion_interruptible_timeout(
10492 &pAdapter->cancel_rem_on_chan_var,
10493 msecs_to_jiffies(WAIT_CANCEL_REM_CHAN));
10494 break;
10495 }
10496 }
Ganesh Kondabattinibabfb492014-12-17 20:25:29 +053010497
Anand N Sunkaddc63c792015-06-03 14:33:24 +053010498 vos_flush_delayed_work(&pAdapter->roc_work);
Kaushik, Sushant7005e372014-04-08 11:36:54 +053010499 }
Agrawal Ashish17ef5082016-10-17 18:33:21 +053010500#ifdef SAP_AUTH_OFFLOAD
10501 if (pHddCtx->cfg_ini->enable_sap_auth_offload)
10502 hdd_set_sap_auth_offload(pAdapter, FALSE);
10503#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010504 mutex_lock(&pHddCtx->sap_lock);
10505 if (test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
10506 {
10507 VOS_STATUS status;
10508 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
10509
10510 //Stop Bss.
10511 status = WLANSAP_StopBss(pHddCtx->pvosContext);
10512 if (VOS_IS_STATUS_SUCCESS(status))
10513 {
10514 hdd_hostapd_state_t *pHostapdState =
10515 WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
10516
10517 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
10518
10519 if (!VOS_IS_STATUS_SUCCESS(status))
10520 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010521 hddLog(LOGE, "%s: failure waiting for WLANSAP_StopBss %d",
10522 __func__, status);
Jeff Johnson295189b2012-06-20 16:38:30 -070010523 }
10524 }
10525 else
10526 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070010527 hddLog(LOGE, "%s: failure in WLANSAP_StopBss", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070010528 }
10529 clear_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags);
Agarwal Ashish51325b52014-06-16 16:50:49 +053010530 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070010531
10532 if (eHAL_STATUS_FAILURE ==
10533 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG,
10534 0, NULL, eANI_BOOLEAN_FALSE))
10535 {
10536 hddLog(LOGE,
10537 "%s: Failed to set WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070010538 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070010539 }
10540
10541 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt((WLAN_HDD_GET_CTX(pAdapter))->hHal,
10542 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
10543 eANI_BOOLEAN_FALSE) )
10544 {
10545 hddLog(LOGE,
10546 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
10547 }
10548
10549 // Reset WNI_CFG_PROBE_RSP Flags
10550 wlan_hdd_reset_prob_rspies(pAdapter);
10551 kfree(pAdapter->sessionCtx.ap.beacon);
10552 pAdapter->sessionCtx.ap.beacon = NULL;
10553 }
10554 mutex_unlock(&pHddCtx->sap_lock);
Hanumanth Reddy Pothulab4537b82018-03-02 12:20:38 +053010555
10556#ifdef WLAN_NS_OFFLOAD
10557 vos_flush_work(&pAdapter->ipv6NotifierWorkQueue);
10558#endif
10559 vos_flush_work(&pAdapter->ipv4NotifierWorkQueue);
10560
Jeff Johnson295189b2012-06-20 16:38:30 -070010561 break;
Sameer Thalappilbee426e2013-10-30 10:30:30 -070010562
Jeff Johnson295189b2012-06-20 16:38:30 -070010563 case WLAN_HDD_MONITOR:
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +053010564 if (VOS_MONITOR_MODE != hdd_get_conparam())
10565 wlan_hdd_stop_mon(pHddCtx, true);
10566 break;
Sameer Thalappilbee426e2013-10-30 10:30:30 -070010567
Jeff Johnson295189b2012-06-20 16:38:30 -070010568 default:
10569 break;
10570 }
10571
10572 EXIT();
10573 return VOS_STATUS_SUCCESS;
10574}
10575
Kapil Gupta137ef892016-12-13 19:38:00 +053010576/**
10577 * wlan_hdd_restart_sap() - to restart SAP in driver internally
10578 * @ap_adapter: - Pointer to SAP hdd_adapter_t structure
10579 *
10580 * wlan_hdd_restart_sap first delete SAP and do cleanup.
10581 * After that WLANSAP_StartBss start re-start process of SAP.
10582 *
10583 * Return: None
10584 */
10585static void wlan_hdd_restart_sap(hdd_adapter_t *ap_adapter)
10586{
10587 hdd_ap_ctx_t *pHddApCtx;
10588 hdd_hostapd_state_t *pHostapdState;
10589 VOS_STATUS vos_status;
10590 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(ap_adapter);
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053010591#ifdef USE_CFG80211_DEL_STA_V2
Kapil Gupta137ef892016-12-13 19:38:00 +053010592 struct station_del_parameters delStaParams;
10593#endif
10594 tsap_Config_t *pConfig;
10595
10596 pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(ap_adapter);
10597 pConfig = &pHddApCtx->sapConfig;
10598
10599 mutex_lock(&pHddCtx->sap_lock);
10600 if (test_bit(SOFTAP_BSS_STARTED, &ap_adapter->event_flags)) {
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053010601#ifdef USE_CFG80211_DEL_STA_V2
Kapil Gupta137ef892016-12-13 19:38:00 +053010602 delStaParams.mac = NULL;
10603 delStaParams.subtype = SIR_MAC_MGMT_DEAUTH >> 4;
10604 delStaParams.reason_code = eCsrForcedDeauthSta;
10605 wlan_hdd_cfg80211_del_station(ap_adapter->wdev.wiphy, ap_adapter->dev,
10606 &delStaParams);
10607#else
10608 wlan_hdd_cfg80211_del_station(ap_adapter->wdev.wiphy, ap_adapter->dev,
10609 NULL);
10610#endif
10611 hdd_cleanup_actionframe(pHddCtx, ap_adapter);
10612
10613 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(ap_adapter);
10614 vos_event_reset(&pHostapdState->vosEvent);
10615
10616 if (VOS_STATUS_SUCCESS == WLANSAP_StopBss(pHddCtx->pvosContext)) {
10617 vos_status = vos_wait_single_event(&pHostapdState->vosEvent,
10618 10000);
10619 if (!VOS_IS_STATUS_SUCCESS(vos_status)) {
10620 hddLog(LOGE, FL("SAP Stop Failed"));
10621 goto end;
10622 }
10623 }
10624 clear_bit(SOFTAP_BSS_STARTED, &ap_adapter->event_flags);
10625 wlan_hdd_decr_active_session(pHddCtx, ap_adapter->device_mode);
10626 hddLog(LOG1, FL("SAP Stop Success"));
10627
10628 if (0 != wlan_hdd_cfg80211_update_apies(ap_adapter)) {
10629 hddLog(LOGE, FL("SAP Not able to set AP IEs"));
10630 goto end;
10631 }
10632
10633 if (WLANSAP_StartBss(pHddCtx->pvosContext, hdd_hostapd_SAPEventCB,
10634 pConfig, (v_PVOID_t)ap_adapter->dev) != VOS_STATUS_SUCCESS) {
10635 hddLog(LOGE, FL("SAP Start Bss fail"));
10636 goto end;
10637 }
10638
10639 hddLog(LOG1, FL("Waiting for SAP to start"));
10640 vos_status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
10641 if (!VOS_IS_STATUS_SUCCESS(vos_status)) {
10642 hddLog(LOGE, FL("SAP Start failed"));
10643 goto end;
10644 }
10645 hddLog(LOG1, FL("SAP Start Success"));
10646 set_bit(SOFTAP_BSS_STARTED, &ap_adapter->event_flags);
10647 wlan_hdd_incr_active_session(pHddCtx, ap_adapter->device_mode);
10648 pHostapdState->bCommit = TRUE;
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053010649 if (!VOS_IS_STATUS_SUCCESS(hdd_dhcp_mdns_offload(ap_adapter))) {
10650 hddLog(VOS_TRACE_LEVEL_ERROR, FL("DHCP/MDNS offload Failed!!"));
10651 vos_event_reset(&pHostapdState->vosEvent);
10652 if (VOS_STATUS_SUCCESS == WLANSAP_StopBss(pHddCtx->pvosContext)) {
10653 vos_status = vos_wait_single_event(&pHostapdState->vosEvent,
10654 10000);
10655 if (!VOS_IS_STATUS_SUCCESS(vos_status)) {
10656 hddLog(LOGE, FL("SAP Stop Failed"));
10657 goto end;
10658 }
10659 }
10660 }
Kapil Gupta137ef892016-12-13 19:38:00 +053010661 }
10662end:
10663 mutex_unlock(&pHddCtx->sap_lock);
10664 return;
10665}
10666
10667/**
10668 * __hdd_sap_restart_handle() - to handle restarting of SAP
10669 * @work: name of the work
10670 *
10671 * Purpose of this function is to trigger sap start. this function
10672 * will be called from workqueue.
10673 *
10674 * Return: void.
10675 */
10676static void __hdd_sap_restart_handle(struct work_struct *work)
10677{
10678 hdd_adapter_t *sap_adapter;
10679 hdd_context_t *hdd_ctx = container_of(work,
10680 hdd_context_t,
10681 sap_start_work);
10682 if (0 != wlan_hdd_validate_context(hdd_ctx)) {
10683 vos_ssr_unprotect(__func__);
10684 return;
10685 }
10686 sap_adapter = hdd_get_adapter(hdd_ctx,
10687 WLAN_HDD_SOFTAP);
10688 if (sap_adapter == NULL) {
10689 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10690 FL("sap_adapter is NULL"));
10691 vos_ssr_unprotect(__func__);
10692 return;
10693 }
10694
10695 if (hdd_ctx->is_ch_avoid_in_progress) {
10696 sap_adapter->sessionCtx.ap.sapConfig.channel = AUTO_CHANNEL_SELECT;
10697 wlan_hdd_restart_sap(sap_adapter);
10698 hdd_change_ch_avoidance_status(hdd_ctx, false);
10699 }
Agrawal Ashish574b3e62017-02-09 18:58:34 +053010700 if (hdd_ctx->cfg_ini->enable_sap_auth_offload)
10701 wlan_hdd_restart_sap(sap_adapter);
Kapil Gupta137ef892016-12-13 19:38:00 +053010702}
10703
10704/**
10705 * hdd_sap_restart_handle() - to handle restarting of SAP
10706 * @work: name of the work
10707 *
10708 * Purpose of this function is to trigger sap start. this function
10709 * will be called from workqueue.
10710 *
10711 * Return: void.
10712 */
10713static void hdd_sap_restart_handle(struct work_struct *work)
10714{
10715 vos_ssr_protect(__func__);
10716 __hdd_sap_restart_handle(work);
10717 vos_ssr_unprotect(__func__);
10718}
10719
10720
Abhishek Singh78c691f2017-11-30 13:48:44 +053010721/**
10722 * __hdd_force_scc_with_ecsa_handle() - to handle force scc using ecsa
10723 * @work: name of the work
10724 *
10725 * Purpose of this function is to force SCC using ECSA. This function
10726 * will be called from workqueue.
10727 *
10728 * Return: void.
10729 */
10730static void
10731__hdd_force_scc_with_ecsa_handle(struct work_struct *work)
10732{
10733 hdd_adapter_t *sap_adapter;
10734 hdd_station_ctx_t *sta_ctx;
10735 hdd_adapter_t *sta_adapter;
Ganesh Kondabattini3655a6d2018-01-08 20:25:39 +053010736 ptSapContext sap_ctx = NULL;
10737 v_CONTEXT_t vos_ctx;
10738 tANI_U8 target_channel;
10739 tsap_Config_t *sap_config;
10740 bool sta_sap_scc_on_dfs_chan;
10741 eNVChannelEnabledType chan_state;
Abhishek Singh78c691f2017-11-30 13:48:44 +053010742 hdd_context_t *hdd_ctx = container_of(to_delayed_work(work),
10743 hdd_context_t,
10744 ecsa_chan_change_work);
10745
10746 if (wlan_hdd_validate_context(hdd_ctx))
10747 return;
10748
10749 sap_adapter = hdd_get_adapter(hdd_ctx,
10750 WLAN_HDD_SOFTAP);
10751 if (!sap_adapter) {
10752 hddLog(LOGE, FL("sap_adapter is NULL"));
10753 return;
10754 }
10755
Ganesh Kondabattini3655a6d2018-01-08 20:25:39 +053010756 vos_ctx = hdd_ctx->pvosContext;
10757 if (!vos_ctx) {
10758 hddLog(LOGE, FL("vos_ctx is NULL"));
10759 return;
10760 }
10761
10762 sap_ctx = VOS_GET_SAP_CB(vos_ctx);
10763 if (!sap_ctx) {
10764 hddLog(LOGE, FL("sap_ctx is NULL"));
10765 return;
10766 }
10767
10768 sap_config = &sap_adapter->sessionCtx.ap.sapConfig;
10769
10770 sta_sap_scc_on_dfs_chan = hdd_is_sta_sap_scc_allowed_on_dfs_chan(hdd_ctx);
10771
Abhishek Singh78c691f2017-11-30 13:48:44 +053010772 sta_adapter = hdd_get_adapter(hdd_ctx,
10773 WLAN_HDD_INFRA_STATION);
10774 if (!sta_adapter) {
10775 hddLog(LOGE, FL("sta_adapter is NULL"));
10776 return;
10777 }
Abhishek Singh78c691f2017-11-30 13:48:44 +053010778
Abhishek Singh10e17cf2018-03-12 14:34:22 +053010779 if (wlansap_chk_n_set_chan_change_in_progress(sap_ctx))
Abhishek Singh78c691f2017-11-30 13:48:44 +053010780 return;
Abhishek Singh10e17cf2018-03-12 14:34:22 +053010781 INIT_COMPLETION(sap_ctx->ecsa_info.chan_switch_comp);
10782
10783 sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(sta_adapter);
10784 if (sta_ctx->conn_info.connState != eConnectionState_Associated) {
10785 if (sta_ctx->conn_info.connState == eConnectionState_NotConnected) {
10786 chan_state = vos_nv_getChannelEnabledState(sap_ctx->channel);
10787 hddLog(LOG1, FL("sta not in connected state %d, sta_sap_scc_on_dfs_chan %d, chan_state %d"),
10788 sta_ctx->conn_info.connState, sta_sap_scc_on_dfs_chan,
10789 chan_state);
10790 if (sta_sap_scc_on_dfs_chan &&
10791 (chan_state == NV_CHANNEL_DFS)) {
10792 hddLog(LOGE, FL("Switch SAP to user configured channel"));
10793 target_channel = sap_config->user_config_channel;
10794 goto switch_channel;
10795 }
10796 }
10797 goto abort;
Abhishek Singh78c691f2017-11-30 13:48:44 +053010798 }
10799
Ganesh Kondabattini3655a6d2018-01-08 20:25:39 +053010800 target_channel = sta_ctx->conn_info.operationChannel;
10801switch_channel:
10802 hddLog(LOGE, FL("Switch SAP to %d channel"),
10803 target_channel);
Abhishek Singh10e17cf2018-03-12 14:34:22 +053010804 if (!wlansap_set_channel_change(vos_ctx, target_channel, true))
10805 return;
10806
10807abort:
10808 wlansap_reset_chan_change_in_progress(sap_ctx);
10809 complete(&sap_ctx->ecsa_info.chan_switch_comp);
Abhishek Singh78c691f2017-11-30 13:48:44 +053010810}
10811
10812/**
10813 * hdd_force_scc_with_ecsa_handle() - to handle force scc using ecsa
10814 * @work: name of the work
10815 *
10816 * Purpose of this function is to force SCC using ECSA. This function
10817 * will be called from workqueue.
10818 *
10819 * Return: void.
10820 */
10821static void
10822hdd_force_scc_with_ecsa_handle(struct work_struct *work)
10823{
10824 vos_ssr_protect(__func__);
10825 __hdd_force_scc_with_ecsa_handle(work);
10826 vos_ssr_unprotect(__func__);
10827}
10828
Abhishek Singh10e17cf2018-03-12 14:34:22 +053010829int hdd_wait_for_ecsa_complete(hdd_context_t *hdd_ctx)
10830{
10831 int ret;
10832 ptSapContext sap_ctx = NULL;
10833 v_CONTEXT_t vos_ctx;
10834
10835 vos_ctx = hdd_ctx->pvosContext;
10836 if (!vos_ctx) {
10837 hddLog(LOGE, FL("vos_ctx is NULL"));
10838 return 0;
10839 }
10840
10841 sap_ctx = VOS_GET_SAP_CB(vos_ctx);
10842 if (!sap_ctx) {
10843 hddLog(LOG1, FL("sap_ctx is NULL"));
10844 return 0;
10845 }
10846 if(!sap_ctx->isSapSessionOpen) {
10847 hddLog(LOG1, FL("sap session not opened, SAP in state %d"),
10848 sap_ctx->sapsMachine);
10849 return 0;
10850 }
10851
10852 if (!wlansap_get_change_in_progress(sap_ctx)) {
10853 hddLog(LOG1, FL("channel switch not in progress"));
10854 return 0;
10855 }
10856 ret = wait_for_completion_timeout(&sap_ctx->ecsa_info.chan_switch_comp,
10857 msecs_to_jiffies(HDD_SAP_CHAN_CNG_WAIT_TIME));
10858 if (!ret)
10859 {
10860 hddLog(LOGE, FL("Timeout waiting for SAP channel switch"));
10861 return ret;
10862 }
10863
10864 return 0;
10865}
10866
10867
Ganesh Kondabattini3655a6d2018-01-08 20:25:39 +053010868/**
10869 * hdd_is_sta_sap_scc_allowed_on_dfs_chan() - check if sta+sap scc allowed on
10870 * dfs chan
10871 * @hdd_ctx: pointer to hdd context
10872 *
10873 * This function used to check if sta+sap scc allowed on DFS channel.
10874 *
10875 * Return: None
10876 */
10877bool hdd_is_sta_sap_scc_allowed_on_dfs_chan(hdd_context_t *hdd_ctx)
10878{
10879 if (hdd_ctx->cfg_ini->force_scc_with_ecsa &&
10880 hdd_ctx->cfg_ini->sta_sap_scc_on_dfs_chan)
10881 return true;
10882 else
10883 return false;
10884}
10885
Jeff Johnson295189b2012-06-20 16:38:30 -070010886VOS_STATUS hdd_stop_all_adapters( hdd_context_t *pHddCtx )
10887{
10888 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
10889 VOS_STATUS status;
10890 hdd_adapter_t *pAdapter;
10891
10892 ENTER();
10893
10894 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
10895
10896 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
10897 {
10898 pAdapter = pAdapterNode->pAdapter;
Jeff Johnson295189b2012-06-20 16:38:30 -070010899
Agarwal Ashish3a38bd12014-06-12 15:16:52 +053010900 hdd_stop_adapter( pHddCtx, pAdapter, VOS_TRUE );
Jeff Johnson295189b2012-06-20 16:38:30 -070010901
10902 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
10903 pAdapterNode = pNext;
10904 }
10905
10906 EXIT();
10907
10908 return VOS_STATUS_SUCCESS;
10909}
10910
Rajeev Kumarf999e582014-01-09 17:33:29 -080010911
10912#ifdef FEATURE_WLAN_BATCH_SCAN
10913/**---------------------------------------------------------------------------
10914
10915 \brief hdd_deinit_batch_scan () - This function cleans up batch scan data
10916 structures
10917
10918 \param - pAdapter Pointer to HDD adapter
10919
10920 \return - None
10921
10922 --------------------------------------------------------------------------*/
10923void hdd_deinit_batch_scan(hdd_adapter_t *pAdapter)
10924{
10925 tHddBatchScanRsp *pNode;
10926 tHddBatchScanRsp *pPrev;
10927
Siddharth Bhalb3e9b792014-02-24 15:14:16 +053010928 if (NULL == pAdapter)
Rajeev Kumarf999e582014-01-09 17:33:29 -080010929 {
Siddharth Bhalb3e9b792014-02-24 15:14:16 +053010930 hddLog(VOS_TRACE_LEVEL_ERROR,
10931 "%s: Adapter context is Null", __func__);
10932 return;
10933 }
10934
10935 pNode = pAdapter->pBatchScanRsp;
10936 while (pNode)
10937 {
10938 pPrev = pNode;
10939 pNode = pNode->pNext;
10940 vos_mem_free((v_VOID_t * )pPrev);
Rajeev Kumarf999e582014-01-09 17:33:29 -080010941 }
10942
10943 pAdapter->pBatchScanRsp = NULL;
10944 pAdapter->numScanList = 0;
10945 pAdapter->batchScanState = eHDD_BATCH_SCAN_STATE_STOPPED;
10946 pAdapter->prev_batch_id = 0;
10947
10948 return;
10949}
10950#endif
10951
10952
Jeff Johnson295189b2012-06-20 16:38:30 -070010953VOS_STATUS hdd_reset_all_adapters( hdd_context_t *pHddCtx )
10954{
10955 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
10956 VOS_STATUS status;
10957 hdd_adapter_t *pAdapter;
10958
10959 ENTER();
10960
10961 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
10962
10963 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
10964 {
10965 pAdapter = pAdapterNode->pAdapter;
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +053010966 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Jeff Johnson295189b2012-06-20 16:38:30 -070010967 netif_tx_disable(pAdapter->dev);
Hanumanth Reddy Pothulad864f312017-01-18 16:16:08 +053010968
10969 if (pHddCtx->cfg_ini->sap_internal_restart &&
10970 pAdapter->device_mode == WLAN_HDD_SOFTAP) {
10971 hddLog(LOG1, FL("driver supports sap restart"));
10972 vos_flush_work(&pHddCtx->sap_start_work);
10973 hdd_sap_indicate_disconnect_for_sta(pAdapter);
10974 hdd_cleanup_actionframe(pHddCtx, pAdapter);
Hanumanth Reddy Pothula15bc0fa2017-02-03 17:24:17 +053010975 hdd_softap_deinit_tx_rx(pAdapter, true);
10976 hdd_sap_destroy_timers(pAdapter);
Hanumanth Reddy Pothulad864f312017-01-18 16:16:08 +053010977 } else {
10978 netif_carrier_off(pAdapter->dev);
10979 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010980
Srinivas Girigowda66c05eb2013-07-14 13:06:01 -070010981 pAdapter->sessionCtx.station.hdd_ReassocScenario = VOS_FALSE;
Hanumanth Reddy Pothulada449f12018-03-13 18:19:19 +053010982
10983 if (pAdapter->device_mode == WLAN_HDD_MONITOR)
10984 pAdapter->sessionCtx.monitor.state = MON_MODE_STOP;
Srinivas Girigowda66c05eb2013-07-14 13:06:01 -070010985
Jeff Johnson295189b2012-06-20 16:38:30 -070010986 hdd_deinit_tx_rx(pAdapter);
Agarwal Ashish6267caa2014-08-06 19:16:21 +053010987
Katya Nigam1fd24402015-02-16 14:52:19 +053010988 if(pAdapter->device_mode == WLAN_HDD_IBSS )
10989 hdd_ibss_deinit_tx_rx(pAdapter);
10990
Nirav Shah7e3c8132015-06-22 23:51:42 +053010991 status = hdd_sta_id_hash_detach(pAdapter);
10992 if (status != VOS_STATUS_SUCCESS)
10993 hddLog(VOS_TRACE_LEVEL_ERROR,
10994 FL("sta id hash detach failed for session id %d"),
10995 pAdapter->sessionId);
10996
Agarwal Ashish6267caa2014-08-06 19:16:21 +053010997 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
10998
Madan Mohan Koyyalamudi8c6dec82013-09-26 15:56:13 +053010999 if (test_bit(WMM_INIT_DONE, &pAdapter->event_flags))
11000 {
11001 hdd_wmm_adapter_close( pAdapter );
11002 clear_bit(WMM_INIT_DONE, &pAdapter->event_flags);
11003 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011004
Siddharth Bhal2db319d2014-12-03 12:37:18 +053011005 if (test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
11006 {
11007 clear_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags);
11008 }
11009
Rajeev Kumarf999e582014-01-09 17:33:29 -080011010#ifdef FEATURE_WLAN_BATCH_SCAN
11011 if (eHDD_BATCH_SCAN_STATE_STARTED == pAdapter->batchScanState)
11012 {
11013 hdd_deinit_batch_scan(pAdapter);
11014 }
11015#endif
11016
Mahesh A Saptasagarf5b8eff2015-01-31 01:07:07 +053011017#ifdef FEATURE_WLAN_TDLS
11018 mutex_lock(&pHddCtx->tdls_lock);
Pradeep Reddy POTTETI2d4d5c42015-03-03 14:34:19 +053011019 wlan_hdd_tdls_exit(pAdapter, TRUE);
Mahesh A Saptasagarf5b8eff2015-01-31 01:07:07 +053011020 mutex_unlock(&pHddCtx->tdls_lock);
11021#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070011022 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
11023 pAdapterNode = pNext;
11024 }
11025
11026 EXIT();
11027
11028 return VOS_STATUS_SUCCESS;
11029}
11030
Abhishek Singhbbe0b2a2016-12-05 11:57:36 +053011031/**
Abhishek Singh5a597e62016-12-05 15:16:30 +053011032 * hdd_get_bss_entry() - Get the bss entry matching the chan, bssid and ssid
11033 * @wiphy: wiphy
11034 * @channel: channel of the BSS to find
11035 * @bssid: bssid of the BSS to find
11036 * @ssid: ssid of the BSS to find
11037 * @ssid_len: ssid len of of the BSS to find
11038 *
11039 * The API is a wrapper to get bss from kernel matching the chan,
11040 * bssid and ssid
11041 *
11042 * Return: Void
11043 */
11044#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 1, 0)) \
11045 && !defined(WITH_BACKPORTS) && !defined(IEEE80211_PRIVACY)
11046
11047struct cfg80211_bss* hdd_get_bss_entry(struct wiphy *wiphy,
11048 struct ieee80211_channel *channel,
11049 const u8 *bssid,
11050 const u8 *ssid, size_t ssid_len)
11051{
11052 return cfg80211_get_bss(wiphy, channel, bssid,
11053 ssid, ssid_len,
11054 WLAN_CAPABILITY_ESS,
11055 WLAN_CAPABILITY_ESS);
11056}
11057#else
11058struct cfg80211_bss* hdd_get_bss_entry(struct wiphy *wiphy,
11059 struct ieee80211_channel *channel,
11060 const u8 *bssid,
11061 const u8 *ssid, size_t ssid_len)
11062{
11063 return cfg80211_get_bss(wiphy, channel, bssid,
11064 ssid, ssid_len,
11065 IEEE80211_BSS_TYPE_ESS,
11066 IEEE80211_PRIVACY_ANY);
11067}
11068#endif
11069
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053011070#if defined(CFG80211_CONNECT_BSS) || \
11071 (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 7, 0))
11072
11073#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 11, 0) || \
11074 defined (CFG80211_CONNECT_TIMEOUT_REASON_CODE)
11075/**
11076 * hdd_connect_bss() - helper function to send connection status to supplicant
11077 * @dev: network device
11078 * @bssid: bssid to which we want to associate
11079 * @bss: information about connected bss
11080 * @req_ie: Request Information Element
11081 * @req_ie_len: len of the req IE
11082 * @resp_ie: Response IE
11083 * @resp_ie_len: len of ht response IE
11084 * @status: status
11085 * @gfp: Kernel Flag
11086 *
11087 * This is a helper function to send connection status to supplicant
11088 * and gets invoked from wrapper API
11089 *
11090 * Return: Void
11091 */
11092static void hdd_connect_bss(struct net_device *dev,
11093 const u8 *bssid,
11094 struct cfg80211_bss *bss,
11095 const u8 *req_ie,
11096 size_t req_ie_len,
11097 const u8 *resp_ie,
11098 size_t resp_ie_len,
11099 u16 status,
11100 gfp_t gfp)
11101{
11102 cfg80211_connect_bss(dev, bssid, bss, req_ie, req_ie_len,
11103 resp_ie, resp_ie_len, status, gfp, NL80211_TIMEOUT_UNSPECIFIED);
11104}
11105#else
11106/**
11107 * hdd_connect_bss() - helper function to send connection status to supplicant
11108 * @dev: network device
11109 * @bssid: bssid to which we want to associate
11110 * @bss: information about connected bss
11111 * @req_ie: Request Information Element
11112 * @req_ie_len: len of the req IE
11113 * @resp_ie: Response IE
11114 * @resp_ie_len: len of ht response IE
11115 * @status: status
11116 * @gfp: Kernel Flag
11117 *
11118 * This is a helper function to send connection status to supplicant
11119 * and gets invoked from wrapper API
11120 *
11121 * Return: Void
11122 */
11123static void hdd_connect_bss(struct net_device *dev,
11124 const u8 *bssid,
11125 struct cfg80211_bss *bss,
11126 const u8 *req_ie,
11127 size_t req_ie_len,
11128 const u8 *resp_ie,
11129 size_t resp_ie_len,
11130 u16 status,
11131 gfp_t gfp)
11132{
11133 cfg80211_connect_bss(dev, bssid, bss, req_ie, req_ie_len,
11134 resp_ie, resp_ie_len, status, gfp);
11135}
11136#endif
11137
Abhishek Singh5a597e62016-12-05 15:16:30 +053011138/**
Abhishek Singhbbe0b2a2016-12-05 11:57:36 +053011139 * hdd_connect_result() - API to send connection status to supplicant
11140 * @dev: network device
11141 * @bssid: bssid to which we want to associate
11142 * @roam_info: information about connected bss
11143 * @req_ie: Request Information Element
11144 * @req_ie_len: len of the req IE
11145 * @resp_ie: Response IE
11146 * @resp_ie_len: len of ht response IE
11147 * @status: status
11148 * @gfp: Kernel Flag
11149 *
11150 * The API is a wrapper to send connection status to supplicant
11151 *
11152 * Return: Void
11153 */
Abhishek Singhbbe0b2a2016-12-05 11:57:36 +053011154void hdd_connect_result(struct net_device *dev,
11155 const u8 *bssid,
11156 tCsrRoamInfo *roam_info,
11157 const u8 *req_ie,
11158 size_t req_ie_len,
11159 const u8 *resp_ie,
11160 size_t resp_ie_len,
11161 u16 status,
11162 gfp_t gfp)
11163{
11164 hdd_adapter_t *padapter = (hdd_adapter_t *) netdev_priv(dev);
11165 struct cfg80211_bss *bss = NULL;
11166
11167 if (WLAN_STATUS_SUCCESS == status) {
11168 struct ieee80211_channel *chan;
11169 int freq;
11170 int chan_no = roam_info->pBssDesc->channelId;;
11171
11172 if (chan_no <= 14)
11173 freq = ieee80211_channel_to_frequency(chan_no,
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053011174 HDD_NL80211_BAND_2GHZ);
Abhishek Singhbbe0b2a2016-12-05 11:57:36 +053011175 else
11176 freq = ieee80211_channel_to_frequency(chan_no,
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053011177 HDD_NL80211_BAND_5GHZ);
Abhishek Singhbbe0b2a2016-12-05 11:57:36 +053011178
11179 chan = ieee80211_get_channel(padapter->wdev.wiphy, freq);
Abhishek Singh5a597e62016-12-05 15:16:30 +053011180 bss = hdd_get_bss_entry(padapter->wdev.wiphy,
11181 chan, bssid,
11182 roam_info->u.pConnectedProfile->SSID.ssId,
11183 roam_info->u.pConnectedProfile->SSID.length);
Abhishek Singhbbe0b2a2016-12-05 11:57:36 +053011184 }
11185
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053011186 hdd_connect_bss(dev, bssid, bss, req_ie, req_ie_len, resp_ie, resp_ie_len,
11187 status, gfp);
Abhishek Singhbbe0b2a2016-12-05 11:57:36 +053011188}
11189#else
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053011190/**
11191 * hdd_connect_result() - API to send connection status to supplicant
11192 * @dev: network device
11193 * @bssid: bssid to which we want to associate
11194 * @roam_info: information about connected bss
11195 * @req_ie: Request Information Element
11196 * @req_ie_len: len of the req IE
11197 * @resp_ie: Response IE
11198 * @resp_ie_len: len of ht response IE
11199 * @status: status
11200 * @gfp: Kernel Flag
11201 *
11202 * The API is a wrapper to send connection status to supplicant
11203 *
11204 * Return: Void
11205 */
Abhishek Singhbbe0b2a2016-12-05 11:57:36 +053011206void hdd_connect_result(struct net_device *dev,
11207 const u8 *bssid,
11208 tCsrRoamInfo *roam_info,
11209 const u8 *req_ie,
11210 size_t req_ie_len,
11211 const u8 * resp_ie,
11212 size_t resp_ie_len,
11213 u16 status,
11214 gfp_t gfp)
11215{
11216 cfg80211_connect_result(dev, bssid, req_ie, req_ie_len,
11217 resp_ie, resp_ie_len, status, gfp);
11218}
11219#endif
11220
Jeff Johnson295189b2012-06-20 16:38:30 -070011221VOS_STATUS hdd_start_all_adapters( hdd_context_t *pHddCtx )
11222{
11223 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
11224 VOS_STATUS status;
11225 hdd_adapter_t *pAdapter;
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +053011226 eConnectionState connState;
Hanumanth Reddy Pothulada449f12018-03-13 18:19:19 +053011227 v_CONTEXT_t pVosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -070011228
11229 ENTER();
11230
11231 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
11232
11233 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
11234 {
11235 pAdapter = pAdapterNode->pAdapter;
11236
Kumar Anand82c009f2014-05-29 00:29:42 -070011237 hdd_wmm_init( pAdapter );
11238
Jeff Johnson295189b2012-06-20 16:38:30 -070011239 switch(pAdapter->device_mode)
11240 {
11241 case WLAN_HDD_INFRA_STATION:
11242 case WLAN_HDD_P2P_CLIENT:
Jeff Johnsone7245742012-09-05 17:12:55 -070011243 case WLAN_HDD_P2P_DEVICE:
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +053011244
11245 connState = (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState;
11246
Jeff Johnson295189b2012-06-20 16:38:30 -070011247 hdd_init_station_mode(pAdapter);
11248 /* Open the gates for HDD to receive Wext commands */
11249 pAdapter->isLinkUpSvcNeeded = FALSE;
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070011250 pHddCtx->scan_info.mScanPending = FALSE;
11251 pHddCtx->scan_info.waitScanResult = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070011252
11253 //Trigger the initial scan
Mukul Sharmae74e42c2015-08-06 23:55:49 +053011254 if (!pHddCtx->isLogpInProgress)
11255 hdd_wlan_initial_scan(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070011256
11257 //Indicate disconnect event to supplicant if associated previously
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +053011258 if (eConnectionState_Associated == connState ||
11259 eConnectionState_IbssConnected == connState )
Jeff Johnson295189b2012-06-20 16:38:30 -070011260 {
11261 union iwreq_data wrqu;
11262 memset(&wrqu, '\0', sizeof(wrqu));
11263 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
11264 memset(wrqu.ap_addr.sa_data,'\0',ETH_ALEN);
11265 wireless_send_event(pAdapter->dev, SIOCGIWAP, &wrqu, NULL);
Srinivas Girigowda66c05eb2013-07-14 13:06:01 -070011266 pAdapter->sessionCtx.station.hdd_ReassocScenario = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070011267
Jeff Johnson295189b2012-06-20 16:38:30 -070011268 /* indicate disconnected event to nl80211 */
Mahesh A Saptasagar9ff4bcc2016-06-01 17:17:50 +053011269 wlan_hdd_cfg80211_indicate_disconnect(pAdapter->dev, false,
Mahesh A Saptasagarb5a15142016-05-25 11:27:43 +053011270 WLAN_REASON_UNSPECIFIED);
Jeff Johnson295189b2012-06-20 16:38:30 -070011271 }
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +053011272 else if (eConnectionState_Connecting == connState)
11273 {
11274 /*
11275 * Indicate connect failure to supplicant if we were in the
11276 * process of connecting
11277 */
Abhishek Singhbbe0b2a2016-12-05 11:57:36 +053011278 hdd_connect_result(pAdapter->dev, NULL, NULL,
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +053011279 NULL, 0, NULL, 0,
11280 WLAN_STATUS_ASSOC_DENIED_UNSPEC,
11281 GFP_KERNEL);
11282 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011283 break;
11284
11285 case WLAN_HDD_SOFTAP:
Hanumanth Reddy Pothulad864f312017-01-18 16:16:08 +053011286 if (pHddCtx->cfg_ini->sap_internal_restart) {
Hanumanth Reddy Pothula15bc0fa2017-02-03 17:24:17 +053011287 hdd_init_ap_mode(pAdapter, true);
Hanumanth Reddy Pothulad864f312017-01-18 16:16:08 +053011288 status = hdd_sta_id_hash_attach(pAdapter);
11289 if (VOS_STATUS_SUCCESS != status)
11290 {
11291 hddLog(VOS_TRACE_LEVEL_FATAL,
11292 FL("failed to attach hash for"));
11293 }
11294 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011295 break;
11296
11297 case WLAN_HDD_P2P_GO:
Sameer Thalappiledf0d792013-08-09 14:31:03 -070011298 hddLog(VOS_TRACE_LEVEL_ERROR, "%s [SSR] send stop ap to supplicant",
Jeff Johnson295189b2012-06-20 16:38:30 -070011299 __func__);
Sameer Thalappiledf0d792013-08-09 14:31:03 -070011300 cfg80211_ap_stopped(pAdapter->dev, GFP_KERNEL);
Jeff Johnson295189b2012-06-20 16:38:30 -070011301 break;
11302
11303 case WLAN_HDD_MONITOR:
Hanumanth Reddy Pothulada449f12018-03-13 18:19:19 +053011304 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
11305
11306 hddLog(VOS_TRACE_LEVEL_INFO, FL("[SSR] monitor mode"));
11307 if (!pVosContext) {
11308 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos context is NULL"));
11309 break;
11310 }
11311
11312 hdd_init_tx_rx(pAdapter);
11313 WLANTL_SetMonRxCbk( pVosContext, hdd_rx_packet_monitor_cbk);
Jeff Johnson295189b2012-06-20 16:38:30 -070011314 break;
Hanumanth Reddy Pothulada449f12018-03-13 18:19:19 +053011315
Jeff Johnson295189b2012-06-20 16:38:30 -070011316 default:
11317 break;
11318 }
11319
11320 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
11321 pAdapterNode = pNext;
11322 }
11323
11324 EXIT();
11325
11326 return VOS_STATUS_SUCCESS;
11327}
11328
11329VOS_STATUS hdd_reconnect_all_adapters( hdd_context_t *pHddCtx )
11330{
11331 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
11332 hdd_adapter_t *pAdapter;
11333 VOS_STATUS status;
11334 v_U32_t roamId;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011335 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070011336
11337 ENTER();
11338
11339 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
11340
11341 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
11342 {
11343 pAdapter = pAdapterNode->pAdapter;
11344
11345 if( (WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
11346 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
11347 {
11348 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
11349 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
11350
Abhishek Singhf4669da2014-05-26 15:07:49 +053011351 hddLog(VOS_TRACE_LEVEL_INFO,
11352 "%s: Set HDD connState to eConnectionState_NotConnected",
11353 __func__);
Ganesh Kondabattini04338412015-09-14 15:39:09 +053011354 spin_lock_bh(&pAdapter->lock_for_active_session);
11355 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState)
11356 {
11357 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
11358 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011359 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
Ganesh Kondabattini04338412015-09-14 15:39:09 +053011360 spin_unlock_bh(&pAdapter->lock_for_active_session);
Jeff Johnson295189b2012-06-20 16:38:30 -070011361 init_completion(&pAdapter->disconnect_comp_var);
11362 sme_RoamDisconnect(pHddCtx->hHal, pAdapter->sessionId,
11363 eCSR_DISCONNECT_REASON_UNSPECIFIED);
11364
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011365 ret = wait_for_completion_interruptible_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -070011366 &pAdapter->disconnect_comp_var,
11367 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011368 if (0 >= ret)
11369 hddLog(LOGE, "%s: failure waiting for disconnect_comp_var %ld",
11370 __func__, ret);
Jeff Johnson295189b2012-06-20 16:38:30 -070011371
11372 pWextState->roamProfile.csrPersona = pAdapter->device_mode;
11373 pHddCtx->isAmpAllowed = VOS_FALSE;
11374 sme_RoamConnect(pHddCtx->hHal,
11375 pAdapter->sessionId, &(pWextState->roamProfile),
11376 &roamId);
11377 }
11378
11379 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
11380 pAdapterNode = pNext;
11381 }
11382
11383 EXIT();
11384
11385 return VOS_STATUS_SUCCESS;
11386}
11387
Sudhir Sattayappa Kohalli90e4c752013-03-21 14:25:04 -070011388void hdd_dump_concurrency_info(hdd_context_t *pHddCtx)
11389{
11390 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
11391 VOS_STATUS status;
11392 hdd_adapter_t *pAdapter;
11393 hdd_station_ctx_t *pHddStaCtx;
11394 hdd_ap_ctx_t *pHddApCtx;
11395 hdd_hostapd_state_t * pHostapdState;
11396 tCsrBssid staBssid = { 0 }, p2pBssid = { 0 }, apBssid = { 0 };
11397 v_U8_t staChannel = 0, p2pChannel = 0, apChannel = 0;
11398 const char *p2pMode = "DEV";
11399 const char *ccMode = "Standalone";
Sudhir Sattayappa Kohalli90e4c752013-03-21 14:25:04 -070011400
11401 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
11402 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
11403 {
11404 pAdapter = pAdapterNode->pAdapter;
11405 switch (pAdapter->device_mode) {
11406 case WLAN_HDD_INFRA_STATION:
11407 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
11408 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState) {
11409 staChannel = pHddStaCtx->conn_info.operationChannel;
11410 memcpy(staBssid, pHddStaCtx->conn_info.bssId, sizeof(staBssid));
11411 }
11412 break;
11413 case WLAN_HDD_P2P_CLIENT:
11414 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
11415 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState) {
11416 p2pChannel = pHddStaCtx->conn_info.operationChannel;
11417 memcpy(p2pBssid, pHddStaCtx->conn_info.bssId, sizeof(p2pBssid));
11418 p2pMode = "CLI";
11419 }
11420 break;
11421 case WLAN_HDD_P2P_GO:
11422 pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
11423 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
11424 if (pHostapdState->bssState == BSS_START && pHostapdState->vosStatus==VOS_STATUS_SUCCESS) {
11425 p2pChannel = pHddApCtx->operatingChannel;
11426 memcpy(p2pBssid, pAdapter->macAddressCurrent.bytes, sizeof(p2pBssid));
11427 }
11428 p2pMode = "GO";
11429 break;
11430 case WLAN_HDD_SOFTAP:
11431 pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
11432 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
11433 if (pHostapdState->bssState == BSS_START && pHostapdState->vosStatus==VOS_STATUS_SUCCESS) {
11434 apChannel = pHddApCtx->operatingChannel;
11435 memcpy(apBssid, pAdapter->macAddressCurrent.bytes, sizeof(apBssid));
11436 }
11437 break;
11438 default:
11439 break;
11440 }
11441 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
11442 pAdapterNode = pNext;
11443 }
11444 if (staChannel > 0 && (apChannel > 0 || p2pChannel > 0)) {
11445 ccMode = (p2pChannel==staChannel||apChannel==staChannel) ? "SCC" : "MCC";
11446 }
Yeshwanth Sriram Guntuka0004c0b2017-12-06 14:43:49 +053011447 hddLog(VOS_TRACE_LEVEL_ERROR, "wlan(%d) " MAC_ADDRESS_STR " %s",
11448 staChannel, MAC_ADDR_ARRAY(staBssid), ccMode);
Sudhir Sattayappa Kohalli90e4c752013-03-21 14:25:04 -070011449 if (p2pChannel > 0) {
Sushant Kaushikdc3184b2015-10-09 12:00:21 +053011450 hddLog(VOS_TRACE_LEVEL_ERROR, "p2p-%s(%d) " MAC_ADDRESS_STR,
Sudhir Sattayappa Kohalli90e4c752013-03-21 14:25:04 -070011451 p2pMode, p2pChannel, MAC_ADDR_ARRAY(p2pBssid));
11452 }
11453 if (apChannel > 0) {
Sushant Kaushikdc3184b2015-10-09 12:00:21 +053011454 hddLog(VOS_TRACE_LEVEL_ERROR, "AP(%d) " MAC_ADDRESS_STR,
Sudhir Sattayappa Kohalli90e4c752013-03-21 14:25:04 -070011455 apChannel, MAC_ADDR_ARRAY(apBssid));
11456 }
11457
11458 if (p2pChannel > 0 && apChannel > 0) {
11459 hddLog(VOS_TRACE_LEVEL_ERROR, "Error concurrent SAP %d and P2P %d which is not support", apChannel, p2pChannel);
11460 }
11461}
11462
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -070011463bool hdd_is_ssr_required( void)
Jeff Johnson295189b2012-06-20 16:38:30 -070011464{
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -070011465 return (isSsrRequired == HDD_SSR_REQUIRED);
Jeff Johnson295189b2012-06-20 16:38:30 -070011466}
11467
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -070011468/* Once SSR is disabled then it cannot be set. */
11469void hdd_set_ssr_required( e_hdd_ssr_required value)
Jeff Johnson295189b2012-06-20 16:38:30 -070011470{
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -070011471 if (HDD_SSR_DISABLED == isSsrRequired)
11472 return;
11473
Jeff Johnson295189b2012-06-20 16:38:30 -070011474 isSsrRequired = value;
11475}
11476
Hema Aparna Medicharla6b4d4f32015-06-23 04:09:12 +053011477void hdd_set_pre_close( hdd_context_t *pHddCtx)
11478{
11479 sme_PreClose(pHddCtx->hHal);
11480}
11481
Jeff Johnson295189b2012-06-20 16:38:30 -070011482VOS_STATUS hdd_get_front_adapter( hdd_context_t *pHddCtx,
11483 hdd_adapter_list_node_t** ppAdapterNode)
11484{
11485 VOS_STATUS status;
Mukul Sharmaae1266d2015-06-26 15:29:53 +053011486 spin_lock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -070011487 status = hdd_list_peek_front ( &pHddCtx->hddAdapters,
11488 (hdd_list_node_t**) ppAdapterNode );
Mukul Sharmaae1266d2015-06-26 15:29:53 +053011489 spin_unlock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -070011490 return status;
11491}
11492
11493VOS_STATUS hdd_get_next_adapter( hdd_context_t *pHddCtx,
11494 hdd_adapter_list_node_t* pAdapterNode,
11495 hdd_adapter_list_node_t** pNextAdapterNode)
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_peek_next ( &pHddCtx->hddAdapters,
11500 (hdd_list_node_t*) pAdapterNode,
11501 (hdd_list_node_t**)pNextAdapterNode );
11502
Mukul Sharmaae1266d2015-06-26 15:29:53 +053011503 spin_unlock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -070011504 return status;
11505}
11506
11507VOS_STATUS hdd_remove_adapter( hdd_context_t *pHddCtx,
11508 hdd_adapter_list_node_t* pAdapterNode)
11509{
11510 VOS_STATUS status;
Mukul Sharmaae1266d2015-06-26 15:29:53 +053011511 spin_lock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -070011512 status = hdd_list_remove_node ( &pHddCtx->hddAdapters,
11513 &pAdapterNode->node );
Mukul Sharmaae1266d2015-06-26 15:29:53 +053011514 spin_unlock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -070011515 return status;
11516}
11517
11518VOS_STATUS hdd_remove_front_adapter( hdd_context_t *pHddCtx,
11519 hdd_adapter_list_node_t** ppAdapterNode)
11520{
11521 VOS_STATUS status;
Mukul Sharmaae1266d2015-06-26 15:29:53 +053011522 spin_lock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -070011523 status = hdd_list_remove_front( &pHddCtx->hddAdapters,
11524 (hdd_list_node_t**) ppAdapterNode );
Mukul Sharmaae1266d2015-06-26 15:29:53 +053011525 spin_unlock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -070011526 return status;
11527}
11528
11529VOS_STATUS hdd_add_adapter_back( hdd_context_t *pHddCtx,
11530 hdd_adapter_list_node_t* pAdapterNode)
11531{
11532 VOS_STATUS status;
Mukul Sharmaae1266d2015-06-26 15:29:53 +053011533 spin_lock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -070011534 status = hdd_list_insert_back ( &pHddCtx->hddAdapters,
11535 (hdd_list_node_t*) pAdapterNode );
Mukul Sharmaae1266d2015-06-26 15:29:53 +053011536 spin_unlock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -070011537 return status;
11538}
11539
11540VOS_STATUS hdd_add_adapter_front( hdd_context_t *pHddCtx,
11541 hdd_adapter_list_node_t* pAdapterNode)
11542{
11543 VOS_STATUS status;
Mukul Sharmaae1266d2015-06-26 15:29:53 +053011544 spin_lock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -070011545 status = hdd_list_insert_front ( &pHddCtx->hddAdapters,
11546 (hdd_list_node_t*) pAdapterNode );
Mukul Sharmaae1266d2015-06-26 15:29:53 +053011547 spin_unlock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -070011548 return status;
11549}
11550
11551hdd_adapter_t * hdd_get_adapter_by_macaddr( hdd_context_t *pHddCtx,
11552 tSirMacAddr macAddr )
11553{
11554 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
11555 hdd_adapter_t *pAdapter;
11556 VOS_STATUS status;
11557
11558 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
11559
11560 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
11561 {
11562 pAdapter = pAdapterNode->pAdapter;
11563
11564 if( pAdapter && vos_mem_compare( pAdapter->macAddressCurrent.bytes,
11565 macAddr, sizeof(tSirMacAddr) ) )
11566 {
11567 return pAdapter;
11568 }
11569 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
11570 pAdapterNode = pNext;
11571 }
11572
11573 return NULL;
11574
11575}
11576
11577hdd_adapter_t * hdd_get_adapter_by_name( hdd_context_t *pHddCtx, tANI_U8 *name )
11578{
11579 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
11580 hdd_adapter_t *pAdapter;
11581 VOS_STATUS status;
11582
11583 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
11584
11585 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
11586 {
11587 pAdapter = pAdapterNode->pAdapter;
11588
11589 if( pAdapter && !strncmp( pAdapter->dev->name, (const char *)name,
11590 IFNAMSIZ ) )
11591 {
11592 return pAdapter;
11593 }
11594 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
11595 pAdapterNode = pNext;
11596 }
11597
11598 return NULL;
11599
11600}
11601
Ganesh Kondabattinicbfdc392015-09-11 19:12:59 +053011602hdd_adapter_t *hdd_get_adapter_by_sme_session_id( hdd_context_t *pHddCtx,
11603 tANI_U32 sme_session_id )
11604{
11605 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
11606 hdd_adapter_t *pAdapter;
11607 VOS_STATUS vos_status;
11608
11609
11610 vos_status = hdd_get_front_adapter( pHddCtx, &pAdapterNode);
11611
11612 while ((NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == vos_status))
11613 {
11614 pAdapter = pAdapterNode->pAdapter;
11615
11616 if (pAdapter->sessionId == sme_session_id)
11617 return pAdapter;
11618
11619 vos_status = hdd_get_next_adapter(pHddCtx, pAdapterNode, &pNext);
11620 pAdapterNode = pNext;
11621 }
11622
11623 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11624 "%s: sme_session_id %d does not exist with host",
11625 __func__, sme_session_id);
11626
11627 return NULL;
11628}
11629
Jeff Johnson295189b2012-06-20 16:38:30 -070011630hdd_adapter_t * hdd_get_adapter( hdd_context_t *pHddCtx, device_mode_t mode )
11631{
11632 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
11633 hdd_adapter_t *pAdapter;
11634 VOS_STATUS status;
11635
11636 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
11637
11638 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
11639 {
11640 pAdapter = pAdapterNode->pAdapter;
11641
11642 if( pAdapter && (mode == pAdapter->device_mode) )
11643 {
11644 return pAdapter;
11645 }
11646 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
11647 pAdapterNode = pNext;
11648 }
11649
11650 return NULL;
11651
11652}
11653
11654//Remove this function later
11655hdd_adapter_t * hdd_get_mon_adapter( hdd_context_t *pHddCtx )
11656{
11657 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
11658 hdd_adapter_t *pAdapter;
11659 VOS_STATUS status;
11660
11661 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
11662
11663 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
11664 {
11665 pAdapter = pAdapterNode->pAdapter;
11666
11667 if( pAdapter && WLAN_HDD_MONITOR == pAdapter->device_mode )
11668 {
11669 return pAdapter;
11670 }
11671
11672 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
11673 pAdapterNode = pNext;
11674 }
11675
11676 return NULL;
11677
11678}
11679
Jeff Johnson295189b2012-06-20 16:38:30 -070011680/**---------------------------------------------------------------------------
11681
Mahesh A Saptasgar64534612014-09-23 13:13:33 +053011682 \brief hdd_get_operating_channel() -
Jeff Johnson295189b2012-06-20 16:38:30 -070011683
11684 This API returns the operating channel of the requested device mode
11685
11686 \param - pHddCtx - Pointer to the HDD context.
11687 - mode - Device mode for which operating channel is required
11688 suported modes - WLAN_HDD_INFRA_STATION, WLAN_HDD_P2P_CLIENT
11689 WLAN_HDD_SOFTAP, WLAN_HDD_P2P_GO.
11690 \return - channel number. "0" id the requested device is not found OR it is not connected.
11691 --------------------------------------------------------------------------*/
11692v_U8_t hdd_get_operating_channel( hdd_context_t *pHddCtx, device_mode_t mode )
11693{
11694 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
11695 VOS_STATUS status;
11696 hdd_adapter_t *pAdapter;
11697 v_U8_t operatingChannel = 0;
11698
11699 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
11700
11701 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
11702 {
11703 pAdapter = pAdapterNode->pAdapter;
11704
11705 if( mode == pAdapter->device_mode )
11706 {
11707 switch(pAdapter->device_mode)
11708 {
11709 case WLAN_HDD_INFRA_STATION:
11710 case WLAN_HDD_P2P_CLIENT:
11711 if( hdd_connIsConnected( WLAN_HDD_GET_STATION_CTX_PTR( pAdapter )) )
11712 operatingChannel = (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.operationChannel;
11713 break;
11714 case WLAN_HDD_SOFTAP:
11715 case WLAN_HDD_P2P_GO:
11716 /*softap connection info */
11717 if(test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
11718 operatingChannel = (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->operatingChannel;
11719 break;
11720 default:
11721 break;
11722 }
11723
11724 break; //Found the device of interest. break the loop
11725 }
11726
11727 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
11728 pAdapterNode = pNext;
11729 }
11730 return operatingChannel;
11731}
11732
11733#ifdef WLAN_FEATURE_PACKET_FILTERING
11734/**---------------------------------------------------------------------------
11735
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053011736 \brief __hdd_set_multicast_list() -
Jeff Johnson295189b2012-06-20 16:38:30 -070011737
11738 This used to set the multicast address list.
11739
11740 \param - dev - Pointer to the WLAN device.
11741 - skb - Pointer to OS packet (sk_buff).
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053011742 \return - success/fail
Jeff Johnson295189b2012-06-20 16:38:30 -070011743
11744 --------------------------------------------------------------------------*/
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053011745static void __hdd_set_multicast_list(struct net_device *dev)
Jeff Johnson295189b2012-06-20 16:38:30 -070011746{
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053011747 hdd_adapter_t *pAdapter;
11748 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070011749 int mc_count;
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053011750 int i = 0, ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070011751 struct netdev_hw_addr *ha;
Gopichand Nakkala0f276812013-02-24 14:45:51 +053011752
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053011753 ENTER();
11754
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053011755 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkala0f276812013-02-24 14:45:51 +053011756 if (NULL == pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -070011757 {
11758 hddLog(VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala0f276812013-02-24 14:45:51 +053011759 "%s: Adapter context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070011760 return;
11761 }
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053011762 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
11763 ret = wlan_hdd_validate_context(pHddCtx);
11764 if (0 != ret)
11765 {
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053011766 return;
11767 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011768 if (dev->flags & IFF_ALLMULTI)
11769 {
11770 hddLog(VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070011771 "%s: allow all multicast frames", __func__);
Gopichand Nakkala0f276812013-02-24 14:45:51 +053011772 pAdapter->mc_addr_list.mc_cnt = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070011773 }
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053011774 else
Jeff Johnson295189b2012-06-20 16:38:30 -070011775 {
11776 mc_count = netdev_mc_count(dev);
11777 hddLog(VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070011778 "%s: mc_count = %u", __func__, mc_count);
Jeff Johnson295189b2012-06-20 16:38:30 -070011779 if (mc_count > WLAN_HDD_MAX_MC_ADDR_LIST)
11780 {
11781 hddLog(VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070011782 "%s: No free filter available; allow all multicast frames", __func__);
Gopichand Nakkala0f276812013-02-24 14:45:51 +053011783 pAdapter->mc_addr_list.mc_cnt = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070011784 return;
11785 }
11786
Gopichand Nakkala0f276812013-02-24 14:45:51 +053011787 pAdapter->mc_addr_list.mc_cnt = mc_count;
Jeff Johnson295189b2012-06-20 16:38:30 -070011788
11789 netdev_for_each_mc_addr(ha, dev) {
11790 if (i == mc_count)
11791 break;
Gopichand Nakkala0f276812013-02-24 14:45:51 +053011792 memset(&(pAdapter->mc_addr_list.addr[i][0]), 0, ETH_ALEN);
11793 memcpy(&(pAdapter->mc_addr_list.addr[i][0]), ha->addr, ETH_ALEN);
Arif Hussain6d2a3322013-11-17 19:50:10 -080011794 hddLog(VOS_TRACE_LEVEL_INFO, "%s: mlist[%d] = "MAC_ADDRESS_STR,
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053011795 __func__, i,
Gopichand Nakkala0f276812013-02-24 14:45:51 +053011796 MAC_ADDR_ARRAY(pAdapter->mc_addr_list.addr[i]));
Jeff Johnson295189b2012-06-20 16:38:30 -070011797 i++;
11798 }
11799 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053011800
Ganesh Kondabattinifb37e652015-10-09 15:46:47 +053011801 if (pHddCtx->hdd_wlan_suspended)
11802 {
11803 /*
11804 * Configure the Mcast address list to FW
11805 * If wlan is already in suspend mode
11806 */
11807 wlan_hdd_set_mc_addr_list(pAdapter, TRUE);
11808 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053011809 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070011810 return;
11811}
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053011812
11813static void hdd_set_multicast_list(struct net_device *dev)
11814{
11815 vos_ssr_protect(__func__);
11816 __hdd_set_multicast_list(dev);
11817 vos_ssr_unprotect(__func__);
11818}
Jeff Johnson295189b2012-06-20 16:38:30 -070011819#endif
11820
11821/**---------------------------------------------------------------------------
11822
11823 \brief hdd_select_queue() -
11824
11825 This function is registered with the Linux OS for network
11826 core to decide which queue to use first.
11827
11828 \param - dev - Pointer to the WLAN device.
11829 - skb - Pointer to OS packet (sk_buff).
11830 \return - ac, Queue Index/access category corresponding to UP in IP header
11831
11832 --------------------------------------------------------------------------*/
11833v_U16_t hdd_select_queue(struct net_device *dev,
Anand N Sunkade9adb1b2015-07-29 09:56:45 +053011834 struct sk_buff *skb
11835#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,13,0))
11836 , void *accel_priv
11837#endif
11838#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
11839 , select_queue_fallback_t fallback
11840#endif
11841)
Jeff Johnson295189b2012-06-20 16:38:30 -070011842{
11843 return hdd_wmm_select_queue(dev, skb);
11844}
11845
11846
11847/**---------------------------------------------------------------------------
11848
11849 \brief hdd_wlan_initial_scan() -
11850
11851 This function triggers the initial scan
11852
11853 \param - pAdapter - Pointer to the HDD adapter.
11854
11855 --------------------------------------------------------------------------*/
11856void hdd_wlan_initial_scan(hdd_adapter_t *pAdapter)
11857{
11858 tCsrScanRequest scanReq;
11859 tCsrChannelInfo channelInfo;
11860 eHalStatus halStatus;
Jeff Johnson02797792013-10-26 19:17:13 -070011861 tANI_U32 scanId;
Jeff Johnson295189b2012-06-20 16:38:30 -070011862 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
11863
11864 vos_mem_zero(&scanReq, sizeof(tCsrScanRequest));
11865 vos_mem_set(&scanReq.bssid, sizeof(tCsrBssid), 0xff);
11866 scanReq.BSSType = eCSR_BSS_TYPE_ANY;
11867
11868 if(sme_Is11dSupported(pHddCtx->hHal))
11869 {
11870 halStatus = sme_ScanGetBaseChannels( pHddCtx->hHal, &channelInfo );
11871 if ( HAL_STATUS_SUCCESS( halStatus ) )
11872 {
11873 scanReq.ChannelInfo.ChannelList = vos_mem_malloc(channelInfo.numOfChannels);
11874 if( !scanReq.ChannelInfo.ChannelList )
11875 {
11876 hddLog(VOS_TRACE_LEVEL_ERROR, "%s kmalloc failed", __func__);
11877 vos_mem_free(channelInfo.ChannelList);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -080011878 channelInfo.ChannelList = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070011879 return;
11880 }
11881 vos_mem_copy(scanReq.ChannelInfo.ChannelList, channelInfo.ChannelList,
11882 channelInfo.numOfChannels);
11883 scanReq.ChannelInfo.numOfChannels = channelInfo.numOfChannels;
11884 vos_mem_free(channelInfo.ChannelList);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -080011885 channelInfo.ChannelList = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070011886 }
11887
11888 scanReq.scanType = eSIR_PASSIVE_SCAN;
11889 scanReq.requestType = eCSR_SCAN_REQUEST_11D_SCAN;
11890 scanReq.maxChnTime = pHddCtx->cfg_ini->nPassiveMaxChnTime;
11891 scanReq.minChnTime = pHddCtx->cfg_ini->nPassiveMinChnTime;
11892 }
11893 else
11894 {
11895 scanReq.scanType = eSIR_ACTIVE_SCAN;
11896 scanReq.requestType = eCSR_SCAN_REQUEST_FULL_SCAN;
11897 scanReq.maxChnTime = pHddCtx->cfg_ini->nActiveMaxChnTime;
11898 scanReq.minChnTime = pHddCtx->cfg_ini->nActiveMinChnTime;
11899 }
11900
11901 halStatus = sme_ScanRequest(pHddCtx->hHal, pAdapter->sessionId, &scanReq, &scanId, NULL, NULL);
11902 if ( !HAL_STATUS_SUCCESS( halStatus ) )
11903 {
11904 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: sme_ScanRequest failed status code %d",
11905 __func__, halStatus );
11906 }
11907
11908 if(sme_Is11dSupported(pHddCtx->hHal))
11909 vos_mem_free(scanReq.ChannelInfo.ChannelList);
11910}
11911
Jeff Johnson295189b2012-06-20 16:38:30 -070011912/**---------------------------------------------------------------------------
11913
11914 \brief hdd_full_power_callback() - HDD full power callback function
11915
11916 This is the function invoked by SME to inform the result of a full power
11917 request issued by HDD
11918
11919 \param - callbackcontext - Pointer to cookie
11920 \param - status - result of request
11921
11922 \return - None
11923
11924 --------------------------------------------------------------------------*/
11925static void hdd_full_power_callback(void *callbackContext, eHalStatus status)
11926{
Jeff Johnson72a40512013-12-19 10:14:15 -080011927 struct statsContext *pContext = callbackContext;
Jeff Johnson295189b2012-06-20 16:38:30 -070011928
11929 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnsonc135a9a2017-09-19 08:37:24 -070011930 "%s: context = %pK, status = %d", __func__, pContext, status);
Jeff Johnson295189b2012-06-20 16:38:30 -070011931
11932 if (NULL == callbackContext)
11933 {
11934 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnsonc135a9a2017-09-19 08:37:24 -070011935 "%s: Bad param, context [%pK]",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070011936 __func__, callbackContext);
Jeff Johnson295189b2012-06-20 16:38:30 -070011937 return;
11938 }
11939
Jeff Johnson72a40512013-12-19 10:14:15 -080011940 /* there is a race condition that exists between this callback
11941 function and the caller since the caller could time out either
11942 before or while this code is executing. we use a spinlock to
11943 serialize these actions */
11944 spin_lock(&hdd_context_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -070011945
11946 if (POWER_CONTEXT_MAGIC != pContext->magic)
11947 {
11948 /* the caller presumably timed out so there is nothing we can do */
Jeff Johnson72a40512013-12-19 10:14:15 -080011949 spin_unlock(&hdd_context_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -070011950 hddLog(VOS_TRACE_LEVEL_WARN,
11951 "%s: Invalid context, magic [%08x]",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070011952 __func__, pContext->magic);
Jeff Johnson295189b2012-06-20 16:38:30 -070011953 return;
11954 }
11955
Jeff Johnson72a40512013-12-19 10:14:15 -080011956 /* context is valid so caller is still waiting */
11957
11958 /* paranoia: invalidate the magic */
11959 pContext->magic = 0;
11960
11961 /* notify the caller */
Jeff Johnson295189b2012-06-20 16:38:30 -070011962 complete(&pContext->completion);
Jeff Johnson72a40512013-12-19 10:14:15 -080011963
11964 /* serialization is complete */
11965 spin_unlock(&hdd_context_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -070011966}
11967
Katya Nigamf0511f62015-05-05 16:40:57 +053011968void wlan_hdd_mon_set_typesubtype( hdd_mon_ctx_t *pMonCtx,int type)
11969{
11970 pMonCtx->typeSubtypeBitmap = 0;
11971 if( type%10 ) /* Management Packets */
11972 pMonCtx->typeSubtypeBitmap |= 0xFFFF;
11973 type/=10;
11974 if( type%10 ) /* Control Packets */
11975 pMonCtx->typeSubtypeBitmap |= 0xFFFF0000;
11976 type/=10;
11977 if( type%10 ) /* Data Packets */
11978 pMonCtx->typeSubtypeBitmap |= 0xFFFF00000000;
11979}
11980
Hanumanth Reddy Pothulab8be9ab2018-04-12 20:03:05 +053011981VOS_STATUS wlan_hdd_mon_postMsg(void *context, hdd_mon_ctx_t *pMonCtx,
11982 void* callback)
Katya Nigamf0511f62015-05-05 16:40:57 +053011983{
11984 vos_msg_t monMsg;
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +053011985 tSirMonModeReq *pMonModeReq;
Katya Nigamf0511f62015-05-05 16:40:57 +053011986
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +053011987 if (MON_MODE_START == pMonCtx->state)
11988 monMsg.type = WDA_MON_START_REQ;
11989 else if (MON_MODE_STOP == pMonCtx->state)
11990 monMsg.type = WDA_MON_STOP_REQ;
11991 else {
11992 hddLog(VOS_TRACE_LEVEL_ERROR,
11993 FL("invalid monitor state %d"), pMonCtx->state);
Katya Nigamf0511f62015-05-05 16:40:57 +053011994 return VOS_STATUS_E_FAILURE;
11995 }
11996
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +053011997 pMonModeReq = vos_mem_malloc(sizeof(tSirMonModeReq));
11998 if (pMonModeReq == NULL) {
11999 hddLog(VOS_TRACE_LEVEL_ERROR,
12000 FL("fail to allocate memory for monitor mode req"));
12001 return VOS_STATUS_E_FAILURE;
12002 }
Katya Nigamf0511f62015-05-05 16:40:57 +053012003
Hanumanth Reddy Pothulab8be9ab2018-04-12 20:03:05 +053012004 pMonModeReq->context = context;
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +053012005 pMonModeReq->data = pMonCtx;
12006 pMonModeReq->callback = callback;
Katya Nigamf0511f62015-05-05 16:40:57 +053012007
Katya Nigamf0511f62015-05-05 16:40:57 +053012008 monMsg.reserved = 0;
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +053012009 monMsg.bodyptr = pMonModeReq;
Katya Nigamf0511f62015-05-05 16:40:57 +053012010 monMsg.bodyval = 0;
12011
12012 if (VOS_STATUS_SUCCESS != vos_mq_post_message(
12013 VOS_MODULE_ID_WDA,(vos_msg_t *)&monMsg)) {
12014 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: : Failed to post Msg to HAL",__func__);
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +053012015 vos_mem_free(pMonModeReq);
Katya Nigamf0511f62015-05-05 16:40:57 +053012016 }
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +053012017 return VOS_STATUS_SUCCESS;
Katya Nigamf0511f62015-05-05 16:40:57 +053012018}
12019
Katya Nigame7b69a82015-04-28 15:24:06 +053012020void wlan_hdd_mon_close(hdd_context_t *pHddCtx)
12021{
12022 VOS_STATUS vosStatus;
12023 v_CONTEXT_t pVosContext = pHddCtx->pvosContext;
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +053012024 hdd_mon_ctx_t *pMonCtx = NULL;
Hanumanth Reddy Pothulab8be9ab2018-04-12 20:03:05 +053012025 int ret;
12026 void *cookie;
12027 struct hdd_request *request;
12028 static const struct hdd_request_params params = {
12029 .priv_size = 0,
12030 .timeout_ms = MON_MODE_MSG_TIMEOUT,
12031 };
Hanumantha Reddy Pothulac99bc062015-09-08 14:59:26 +053012032
Katya Nigame7b69a82015-04-28 15:24:06 +053012033 hdd_adapter_t *pAdapter = hdd_get_adapter(pHddCtx,WLAN_HDD_MONITOR);
12034 if(pAdapter == NULL || pVosContext == NULL)
12035 {
12036 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, "%s:pAdapter is NULL",__func__);
12037 return ;
12038 }
Katya Nigamf0511f62015-05-05 16:40:57 +053012039
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +053012040 pMonCtx = WLAN_HDD_GET_MONITOR_CTX_PTR(pAdapter);
12041 if (pMonCtx!= NULL && pMonCtx->state == MON_MODE_START) {
12042 pMonCtx->state = MON_MODE_STOP;
Hanumanth Reddy Pothulab8be9ab2018-04-12 20:03:05 +053012043 request = hdd_request_alloc(&params);
12044 if (!request) {
12045 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Request allocation failure"));
12046 return;
12047 }
12048 cookie = hdd_request_cookie(request);
12049
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +053012050 if (VOS_STATUS_SUCCESS !=
Hanumanth Reddy Pothulab8be9ab2018-04-12 20:03:05 +053012051 wlan_hdd_mon_postMsg(cookie, pMonCtx,
12052 hdd_mon_post_msg_cb)) {
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +053012053 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12054 FL("failed to post MON MODE REQ"));
12055 pMonCtx->state = MON_MODE_START;
Hanumanth Reddy Pothulab8be9ab2018-04-12 20:03:05 +053012056 goto req_put;
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +053012057 }
Hanumanth Reddy Pothulab8be9ab2018-04-12 20:03:05 +053012058
12059 ret = hdd_request_wait_for_response(request);
12060 if (ret)
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +053012061 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Hanumanth Reddy Pothulab8be9ab2018-04-12 20:03:05 +053012062 FL("timeout on monitor mode completion %d"), ret);
12063
12064req_put:
12065 hdd_request_put(request);
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +053012066 }
12067
Katya Nigame7b69a82015-04-28 15:24:06 +053012068 hdd_UnregisterWext(pAdapter->dev);
12069
12070 vos_mon_stop( pVosContext );
12071
12072 vosStatus = vos_sched_close( pVosContext );
12073 if (!VOS_IS_STATUS_SUCCESS(vosStatus)) {
12074 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
12075 "%s: Failed to close VOSS Scheduler",__func__);
12076 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
12077 }
12078
12079 vosStatus = vos_nv_close();
12080 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
12081 {
12082 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
12083 "%s: Failed to close NV", __func__);
12084 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
12085 }
12086
12087 vos_close(pVosContext);
12088
12089 #ifdef WLAN_KD_READY_NOTIFIER
12090 nl_srv_exit(pHddCtx->ptt_pid);
12091 #else
12092 nl_srv_exit();
12093 #endif
12094
Katya Nigame7b69a82015-04-28 15:24:06 +053012095 hdd_close_all_adapters( pHddCtx );
Katya Nigame7b69a82015-04-28 15:24:06 +053012096}
Agrawal Ashish33ec71e2015-11-26 20:20:58 +053012097/**
12098 * hdd_wlan_free_wiphy_channels - free Channel pointer for wiphy
12099 * @ wiphy: the wiphy to validate against
12100 *
12101 * Return: void
12102 */
12103void hdd_wlan_free_wiphy_channels(struct wiphy *wiphy)
12104{
12105 int i =0;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053012106 for (i = 0; i < HDD_NUM_NL80211_BANDS; i++)
Agrawal Ashish33ec71e2015-11-26 20:20:58 +053012107 {
12108 if (NULL != wiphy->bands[i] &&
12109 (NULL != wiphy->bands[i]->channels))
12110 {
12111 vos_mem_free(wiphy->bands[i]->channels);
12112 wiphy->bands[i]->channels = NULL;
12113 }
12114 }
12115}
Jeff Johnson295189b2012-06-20 16:38:30 -070012116/**---------------------------------------------------------------------------
12117
12118 \brief hdd_wlan_exit() - HDD WLAN exit function
12119
12120 This is the driver exit point (invoked during rmmod)
12121
12122 \param - pHddCtx - Pointer to the HDD Context
12123
12124 \return - None
12125
12126 --------------------------------------------------------------------------*/
12127void hdd_wlan_exit(hdd_context_t *pHddCtx)
12128{
12129 eHalStatus halStatus;
12130 v_CONTEXT_t pVosContext = pHddCtx->pvosContext;
12131 VOS_STATUS vosStatus;
Gopichand Nakkala66923aa2013-03-06 23:17:24 +053012132 struct wiphy *wiphy = pHddCtx->wiphy;
Mingcheng Zhu87f22fc2014-01-30 19:23:32 -080012133 hdd_adapter_t* pAdapter = NULL;
Jeff Johnson72a40512013-12-19 10:14:15 -080012134 struct statsContext powerContext;
Jeff Johnson295189b2012-06-20 16:38:30 -070012135 long lrc;
c_hpothu5ab05e92014-06-13 17:34:05 +053012136 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070012137
12138 ENTER();
12139
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +053012140
Katya Nigame7b69a82015-04-28 15:24:06 +053012141 if (VOS_MONITOR_MODE == hdd_get_conparam())
12142 {
12143 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: MONITOR MODE",__func__);
12144 wlan_hdd_mon_close(pHddCtx);
Hanumantha Reddy Pothulac99bc062015-09-08 14:59:26 +053012145 goto free_hdd_ctx;
Katya Nigame7b69a82015-04-28 15:24:06 +053012146 }
12147 else if (VOS_FTM_MODE != hdd_get_conparam())
Jeff Johnson88ba7742013-02-27 14:36:02 -080012148 {
12149 // Unloading, restart logic is no more required.
12150 wlan_hdd_restart_deinit(pHddCtx);
Jeff Johnsone7245742012-09-05 17:12:55 -070012151
Agarwal Ashishb20e0ff2014-12-17 22:50:19 +053012152#ifdef FEATURE_WLAN_TDLS
12153 /* At the time of driver unloading; if tdls connection is present;
12154 * hdd_rx_packet_cbk calls wlan_hdd_tdls_find_peer.
12155 * wlan_hdd_tdls_find_peer always checks for valid context;
12156 * as load/unload in progress there can be a race condition.
12157 * hdd_rx_packet_cbk calls wlan_hdd_tdls_find_peer only
12158 * when tdls state is enabled.
12159 * As soon as driver set load/unload flag; tdls flag also needs
12160 * to be disabled so that hdd_rx_packet_cbk won't call
12161 * wlan_hdd_tdls_find_peer.
12162 */
Masti, Narayanraddi20494af2015-12-17 20:56:42 +053012163 wlan_hdd_tdls_set_mode(pHddCtx, eTDLS_SUPPORT_DISABLED, FALSE,
12164 HDD_SET_TDLS_MODE_SOURCE_USER);
Agarwal Ashishb20e0ff2014-12-17 22:50:19 +053012165#endif
12166
c_hpothu5ab05e92014-06-13 17:34:05 +053012167 vosStatus = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
12168 while (NULL != pAdapterNode && VOS_STATUS_E_EMPTY != vosStatus)
Jeff Johnson295189b2012-06-20 16:38:30 -070012169 {
c_hpothu5ab05e92014-06-13 17:34:05 +053012170 pAdapter = pAdapterNode->pAdapter;
12171 if (NULL != pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -070012172 {
Mahesh A Saptasagar305e2632015-03-04 12:57:33 +053012173 /* Disable TX on the interface, after this hard_start_xmit() will
12174 * not be called on that interface
12175 */
12176 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
12177 netif_tx_disable(pAdapter->dev);
12178
12179 /* Mark the interface status as "down" for outside world */
12180 netif_carrier_off(pAdapter->dev);
12181
Agarwal Ashish9ffa5b92014-11-18 21:07:02 +053012182 /* DeInit the adapter. This ensures that all data packets
12183 * are freed.
12184 */
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +053012185#ifdef FEATURE_WLAN_TDLS
12186 mutex_lock(&pHddCtx->tdls_lock);
12187#endif
c_hpothu002231a2015-02-05 14:58:51 +053012188 hdd_deinit_adapter(pHddCtx, pAdapter, FALSE);
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +053012189#ifdef FEATURE_WLAN_TDLS
12190 mutex_unlock(&pHddCtx->tdls_lock);
12191#endif
Masti, Narayanraddi26378462016-01-05 18:20:28 +053012192 vos_flush_delayed_work(&pHddCtx->scan_ctxt.scan_work);
12193
12194 wlan_hdd_init_deinit_defer_scan_context(&pHddCtx->scan_ctxt);
Agarwal Ashish9ffa5b92014-11-18 21:07:02 +053012195
c_hpothu5ab05e92014-06-13 17:34:05 +053012196 if (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +053012197 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode ||
12198 WLAN_HDD_MONITOR == pAdapter->device_mode)
c_hpothu5ab05e92014-06-13 17:34:05 +053012199 {
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +053012200 if (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
12201 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode)
12202 wlan_hdd_cfg80211_deregister_frames(pAdapter);
12203
c_hpothu5ab05e92014-06-13 17:34:05 +053012204 hdd_UnregisterWext(pAdapter->dev);
12205 }
Kaushik, Sushant4975a572014-10-21 16:07:48 +053012206
Jeff Johnson295189b2012-06-20 16:38:30 -070012207 }
c_hpothu5ab05e92014-06-13 17:34:05 +053012208 vosStatus = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
12209 pAdapterNode = pNext;
Jeff Johnson295189b2012-06-20 16:38:30 -070012210 }
mukul sharmabab477d2015-06-11 17:14:55 +053012211
Kaushik, Sushant4975a572014-10-21 16:07:48 +053012212 // Cancel any outstanding scan requests. We are about to close all
12213 // of our adapters, but an adapter structure is what SME passes back
12214 // to our callback function. Hence if there are any outstanding scan
12215 // requests then there is a race condition between when the adapter
12216 // is closed and when the callback is invoked.We try to resolve that
12217 // race condition here by canceling any outstanding scans before we
12218 // close the adapters.
12219 // Note that the scans may be cancelled in an asynchronous manner,
12220 // so ideally there needs to be some kind of synchronization. Rather
12221 // than introduce a new synchronization here, we will utilize the
12222 // fact that we are about to Request Full Power, and since that is
12223 // synchronized, the expectation is that by the time Request Full
12224 // Power has completed all scans will be cancelled.
12225 if (pHddCtx->scan_info.mScanPending)
12226 {
Hema Aparna Medicharlaf05f6cd2015-01-21 14:44:19 +053012227 if(NULL != pAdapter)
12228 {
12229 hddLog(VOS_TRACE_LEVEL_INFO,
12230 FL("abort scan mode: %d sessionId: %d"),
12231 pAdapter->device_mode,
12232 pAdapter->sessionId);
12233 }
12234 hdd_abort_mac_scan(pHddCtx,
12235 pHddCtx->scan_info.sessionId,
12236 eCSR_SCAN_ABORT_DEFAULT);
Kaushik, Sushant4975a572014-10-21 16:07:48 +053012237 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012238 }
c_hpothu5ab05e92014-06-13 17:34:05 +053012239 else
Jeff Johnson88ba7742013-02-27 14:36:02 -080012240 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012241 hddLog(VOS_TRACE_LEVEL_INFO,"%s: FTM MODE",__func__);
Hanumantha Reddy Pothula45af96b2015-02-12 16:07:58 +053012242 if (pHddCtx->ftm.ftm_state == WLAN_FTM_STARTING)
12243 {
12244 INIT_COMPLETION(pHddCtx->ftm.startCmpVar);
12245 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
12246 "%s: in middle of FTM START", __func__);
12247 lrc = wait_for_completion_timeout(&pHddCtx->ftm.startCmpVar,
12248 msecs_to_jiffies(20000));
12249 if(!lrc)
12250 {
12251 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
12252 "%s: timedout on ftmStartCmpVar fatal error", __func__);
12253 }
12254 }
Jeff Johnson88ba7742013-02-27 14:36:02 -080012255 wlan_hdd_ftm_close(pHddCtx);
12256 goto free_hdd_ctx;
12257 }
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012258
Jeff Johnson295189b2012-06-20 16:38:30 -070012259 /* DeRegister with platform driver as client for Suspend/Resume */
12260 vosStatus = hddDeregisterPmOps(pHddCtx);
12261 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
12262 {
12263 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddDeregisterPmOps failed",__func__);
12264 VOS_ASSERT(0);
12265 }
12266
12267 vosStatus = hddDevTmUnregisterNotifyCallback(pHddCtx);
12268 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
12269 {
12270 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddDevTmUnregisterNotifyCallback failed",__func__);
12271 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012272
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -070012273 //Stop the traffic monitor timer
Mahesh A Saptasagard461e432016-07-20 15:01:40 +053012274 if ((pHddCtx->cfg_ini->dynSplitscan) && (VOS_TIMER_STATE_RUNNING ==
12275 vos_timer_getCurrentState(&pHddCtx->tx_rx_trafficTmr)))
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -070012276 {
12277 vos_timer_stop(&pHddCtx->tx_rx_trafficTmr);
12278 }
12279
12280 // Destroy the traffic monitor timer
Mahesh A Saptasagard461e432016-07-20 15:01:40 +053012281 if ((pHddCtx->cfg_ini->dynSplitscan) &&
12282 (!VOS_IS_STATUS_SUCCESS(vos_timer_destroy(
12283 &pHddCtx->tx_rx_trafficTmr))))
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -070012284 {
12285 hddLog(VOS_TRACE_LEVEL_ERROR,
12286 "%s: Cannot deallocate Traffic monitor timer", __func__);
12287 }
12288
Bhargav Shahd0715912015-10-01 18:17:37 +053012289 if (VOS_TIMER_STATE_RUNNING ==
12290 vos_timer_getCurrentState(&pHddCtx->delack_timer)) {
12291 vos_timer_stop(&pHddCtx->delack_timer);
12292 }
12293
12294 if (!VOS_IS_STATUS_SUCCESS(vos_timer_destroy(
12295 &pHddCtx->delack_timer))) {
12296 hddLog(VOS_TRACE_LEVEL_ERROR,
12297 "%s: Cannot deallocate Bus bandwidth timer", __func__);
12298 }
12299
Masti, Narayanraddi44b0db02015-12-22 11:54:35 +053012300 if (VOS_TIMER_STATE_RUNNING ==
12301 vos_timer_getCurrentState(&pHddCtx->tdls_source_timer)) {
12302 vos_timer_stop(&pHddCtx->tdls_source_timer);
12303 }
12304
Abhishek Singh8a3e4dc2017-01-02 10:39:18 +053012305 vos_set_snoc_high_freq_voting(false);
12306
Masti, Narayanraddi44b0db02015-12-22 11:54:35 +053012307 vos_timer_destroy(&pHddCtx->tdls_source_timer);
12308
Jeff Johnson295189b2012-06-20 16:38:30 -070012309 //Disable IMPS/BMPS as we do not want the device to enter any power
12310 //save mode during shutdown
12311 sme_DisablePowerSave(pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
12312 sme_DisablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
12313 sme_DisablePowerSave(pHddCtx->hHal, ePMC_UAPSD_MODE_POWER_SAVE);
12314
12315 //Ensure that device is in full power as we will touch H/W during vos_Stop
12316 init_completion(&powerContext.completion);
12317 powerContext.magic = POWER_CONTEXT_MAGIC;
12318
12319 halStatus = sme_RequestFullPower(pHddCtx->hHal, hdd_full_power_callback,
12320 &powerContext, eSME_FULL_PWR_NEEDED_BY_HDD);
12321
12322 if (eHAL_STATUS_SUCCESS != halStatus)
12323 {
12324 if (eHAL_STATUS_PMC_PENDING == halStatus)
12325 {
12326 /* request was sent -- wait for the response */
12327 lrc = wait_for_completion_interruptible_timeout(
12328 &powerContext.completion,
12329 msecs_to_jiffies(WLAN_WAIT_TIME_POWER));
Jeff Johnson295189b2012-06-20 16:38:30 -070012330 if (lrc <= 0)
12331 {
12332 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: %s while requesting full power",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070012333 __func__, (0 == lrc) ? "timeout" : "interrupt");
Jeff Johnson295189b2012-06-20 16:38:30 -070012334 }
12335 }
12336 else
12337 {
12338 hddLog(VOS_TRACE_LEVEL_ERROR,
12339 "%s: Request for Full Power failed, status %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070012340 __func__, halStatus);
Jeff Johnson295189b2012-06-20 16:38:30 -070012341 /* continue -- need to clean up as much as possible */
12342 }
12343 }
Hanumantha Reddy Pothula81b42b22015-05-12 13:52:00 +053012344 if ((eHAL_STATUS_SUCCESS == halStatus) ||
12345 (eHAL_STATUS_PMC_PENDING == halStatus && lrc > 0))
12346 {
12347 /* This will issue a dump command which will clean up
12348 BTQM queues and unblock MC thread */
12349 vos_fwDumpReq(274, 0, 0, 0, 0, 1);
12350 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012351
Jeff Johnson72a40512013-12-19 10:14:15 -080012352 /* either we never sent a request, we sent a request and received a
12353 response or we sent a request and timed out. if we never sent a
12354 request or if we sent a request and got a response, we want to
12355 clear the magic out of paranoia. if we timed out there is a
12356 race condition such that the callback function could be
12357 executing at the same time we are. of primary concern is if the
12358 callback function had already verified the "magic" but had not
12359 yet set the completion variable when a timeout occurred. we
12360 serialize these activities by invalidating the magic while
12361 holding a shared spinlock which will cause us to block if the
12362 callback is currently executing */
12363 spin_lock(&hdd_context_lock);
12364 powerContext.magic = 0;
12365 spin_unlock(&hdd_context_lock);
12366
Hema Aparna Medicharlaa6cf65e2015-06-01 16:23:28 +053012367 /* If Device is shutdown, no point for SME to wait for responses
12368 from device. Pre Close SME */
12369 if(wcnss_device_is_shutdown())
12370 {
12371 sme_PreClose(pHddCtx->hHal);
12372 }
Yue Ma0d4891e2013-08-06 17:01:45 -070012373 hdd_debugfs_exit(pHddCtx);
12374
Ratheesh S P35ed8b12015-04-27 14:01:07 +053012375#ifdef WLAN_NS_OFFLOAD
Ratheesh S P36dbc932015-08-07 14:28:57 +053012376 hddLog(LOG1, FL("Unregister IPv6 notifier"));
Ratheesh S P35ed8b12015-04-27 14:01:07 +053012377 unregister_inet6addr_notifier(&pHddCtx->ipv6_notifier);
12378#endif
Ratheesh S P36dbc932015-08-07 14:28:57 +053012379 hddLog(LOG1, FL("Unregister IPv4 notifier"));
Ratheesh S P35ed8b12015-04-27 14:01:07 +053012380 unregister_inetaddr_notifier(&pHddCtx->ipv4_notifier);
12381
Jeff Johnson295189b2012-06-20 16:38:30 -070012382 // Unregister the Net Device Notifier
12383 unregister_netdevice_notifier(&hdd_netdev_notifier);
12384
Jeff Johnson295189b2012-06-20 16:38:30 -070012385 hdd_stop_all_adapters( pHddCtx );
12386
Jeff Johnson295189b2012-06-20 16:38:30 -070012387#ifdef WLAN_BTAMP_FEATURE
12388 vosStatus = WLANBAP_Stop(pVosContext);
12389 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
12390 {
12391 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
12392 "%s: Failed to stop BAP",__func__);
12393 }
12394#endif //WLAN_BTAMP_FEATURE
12395
12396 //Stop all the modules
12397 vosStatus = vos_stop( pVosContext );
12398 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
12399 {
12400 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
12401 "%s: Failed to stop VOSS",__func__);
12402 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
Hanumantha Reddy Pothulabd9601a2016-02-12 13:22:27 +053012403 if (isSsrPanicOnFailure())
12404 VOS_BUG(0);
Jeff Johnson295189b2012-06-20 16:38:30 -070012405 }
12406
Jeff Johnson295189b2012-06-20 16:38:30 -070012407 //This requires pMac access, Call this before vos_close().
Jeff Johnson295189b2012-06-20 16:38:30 -070012408 hdd_unregister_mcast_bcast_filter(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -070012409
12410 //Close the scheduler before calling vos_close to make sure no thread is
12411 // scheduled after the each module close is called i.e after all the data
12412 // structures are freed.
12413 vosStatus = vos_sched_close( pVosContext );
12414 if (!VOS_IS_STATUS_SUCCESS(vosStatus)) {
12415 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
12416 "%s: Failed to close VOSS Scheduler",__func__);
12417 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
12418 }
Jeff Johnsone7245742012-09-05 17:12:55 -070012419#ifdef WLAN_FEATURE_HOLD_RX_WAKELOCK
12420 /* Destroy the wake lock */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053012421 vos_wake_lock_destroy(&pHddCtx->rx_wake_lock);
Jeff Johnsone7245742012-09-05 17:12:55 -070012422#endif
Madan Mohan Koyyalamudi69fc3ad2012-11-28 16:04:56 -080012423 /* Destroy the wake lock */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053012424 vos_wake_lock_destroy(&pHddCtx->sap_wake_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -070012425
Mihir Shete7a24b5f2013-12-21 12:18:31 +053012426#ifdef CONFIG_ENABLE_LINUX_REG
12427 vosStatus = vos_nv_close();
12428 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
12429 {
12430 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
12431 "%s: Failed to close NV", __func__);
12432 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
12433 }
12434#endif
12435
Jeff Johnson295189b2012-06-20 16:38:30 -070012436 //Close VOSS
12437 //This frees pMac(HAL) context. There should not be any call that requires pMac access after this.
12438 vos_close(pVosContext);
12439
Jeff Johnson295189b2012-06-20 16:38:30 -070012440 //Close Watchdog
12441 if(pHddCtx->cfg_ini->fIsLogpEnabled)
12442 vos_watchdog_close(pVosContext);
12443
Gopichand Nakkalaa0358482013-06-12 17:05:47 +053012444 //Clean up HDD Nlink Service
12445 send_btc_nlink_msg(WLAN_MODULE_DOWN_IND, 0);
Gopichand Nakkalaa0358482013-06-12 17:05:47 +053012446
Manjeet Singh47ee8472016-04-11 11:57:18 +053012447 hdd_close_tx_queues(pHddCtx);
c_manjeecfd1efb2015-09-25 19:32:34 +053012448 wlan_free_fwr_mem_dump_buffer();
12449 memdump_deinit();
12450
Vinay Krishna Erannad938c422014-03-10 17:14:21 +053012451#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +053012452 if (pHddCtx->cfg_ini->wlanLoggingEnable)
Vinay Krishna Erannad938c422014-03-10 17:14:21 +053012453 {
12454 wlan_logging_sock_deactivate_svc();
12455 }
12456#endif
12457
Vinay Krishna Erannaef30b522014-08-26 17:48:16 +053012458#ifdef WLAN_KD_READY_NOTIFIER
12459 nl_srv_exit(pHddCtx->ptt_pid);
12460#else
12461 nl_srv_exit();
12462#endif /* WLAN_KD_READY_NOTIFIER */
12463
Abhishek Singh00b71972016-01-07 10:51:04 +053012464#ifdef WLAN_FEATURE_RMC
12465 hdd_close_cesium_nl_sock();
12466#endif /* WLAN_FEATURE_RMC */
Vinay Krishna Erannaef30b522014-08-26 17:48:16 +053012467
Jeff Johnson295189b2012-06-20 16:38:30 -070012468 hdd_close_all_adapters( pHddCtx );
12469
Padma, Santhosh Kumar9cd38332015-11-17 12:18:10 +053012470 vos_flush_delayed_work(&pHddCtx->spoof_mac_addr_work);
Abhishek Singh78c691f2017-11-30 13:48:44 +053012471 vos_flush_delayed_work(&pHddCtx->ecsa_chan_change_work);
Kapil Gupta137ef892016-12-13 19:38:00 +053012472 vos_flush_work(&pHddCtx->sap_start_work);
Padma, Santhosh Kumar9cd38332015-11-17 12:18:10 +053012473
Hanumantha Reddy Pothula97f9bc92015-08-10 17:21:20 +053012474free_hdd_ctx:
Jeff Johnson295189b2012-06-20 16:38:30 -070012475 /* free the power on lock from platform driver */
12476 if (free_riva_power_on_lock("wlan"))
12477 {
12478 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to free power on lock",
12479 __func__);
12480 }
12481
Ashish Kumar Dhanotiya95e5bc22018-04-19 17:06:33 +053012482 /* Free the cache channels of the command SET_DISABLE_CHANNEL_LIST */
12483 wlan_hdd_free_cache_channels(pHddCtx);
12484
c_hpothu78c7b602014-05-17 17:35:49 +053012485 //Free up dynamically allocated members inside HDD Adapter
12486 if (pHddCtx->cfg_ini)
12487 {
12488 kfree(pHddCtx->cfg_ini);
12489 pHddCtx->cfg_ini= NULL;
12490 }
12491
Hanumanth Reddy Pothula1efcd162018-03-14 14:32:27 +053012492 hdd_request_manager_deinit();
12493
Hanumantha Reddy Pothula6fe221c2016-01-28 15:01:09 +053012494 /* FTM/MONITOR mode, WIPHY did not registered
Leo Changf04ddad2013-09-18 13:46:38 -070012495 If un-register here, system crash will happen */
Hanumantha Reddy Pothula6fe221c2016-01-28 15:01:09 +053012496 if (!(VOS_FTM_MODE == hdd_get_conparam() ||
12497 VOS_MONITOR_MODE == hdd_get_conparam()))
Leo Changf04ddad2013-09-18 13:46:38 -070012498 {
12499 wiphy_unregister(wiphy) ;
Agrawal Ashish33ec71e2015-11-26 20:20:58 +053012500 hdd_wlan_free_wiphy_channels(wiphy);
Leo Changf04ddad2013-09-18 13:46:38 -070012501 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012502 wiphy_free(wiphy) ;
Jeff Johnson295189b2012-06-20 16:38:30 -070012503 if (hdd_is_ssr_required())
12504 {
12505 /* WDI timeout had happened during unload, so SSR is needed here */
Madan Mohan Koyyalamudi3246f5b2012-10-15 15:40:02 -070012506 subsystem_restart("wcnss");
Jeff Johnson295189b2012-06-20 16:38:30 -070012507 msleep(5000);
12508 }
12509 hdd_set_ssr_required (VOS_FALSE);
12510}
12511
12512
12513/**---------------------------------------------------------------------------
12514
12515 \brief hdd_update_config_from_nv() - Function to update the contents of
12516 the running configuration with parameters taken from NV storage
12517
12518 \param - pHddCtx - Pointer to the HDD global context
12519
12520 \return - VOS_STATUS_SUCCESS if successful
12521
12522 --------------------------------------------------------------------------*/
12523static VOS_STATUS hdd_update_config_from_nv(hdd_context_t* pHddCtx)
12524{
Jeff Johnson295189b2012-06-20 16:38:30 -070012525 v_BOOL_t itemIsValid = VOS_FALSE;
12526 VOS_STATUS status;
12527 v_MACADDR_t macFromNV[VOS_MAX_CONCURRENCY_PERSONA];
12528 v_U8_t macLoop;
12529
12530 /*If the NV is valid then get the macaddress from nv else get it from qcom_cfg.ini*/
12531 status = vos_nv_getValidity(VNV_FIELD_IMAGE, &itemIsValid);
12532 if(status != VOS_STATUS_SUCCESS)
12533 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080012534 hddLog(VOS_TRACE_LEVEL_ERROR," vos_nv_getValidity() failed");
Jeff Johnson295189b2012-06-20 16:38:30 -070012535 return VOS_STATUS_E_FAILURE;
12536 }
12537
12538 if (itemIsValid == VOS_TRUE)
12539 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080012540 hddLog(VOS_TRACE_LEVEL_INFO_HIGH," Reading the Macaddress from NV");
Jeff Johnson295189b2012-06-20 16:38:30 -070012541 status = vos_nv_readMultiMacAddress((v_U8_t *)&macFromNV[0].bytes[0],
12542 VOS_MAX_CONCURRENCY_PERSONA);
12543 if(status != VOS_STATUS_SUCCESS)
12544 {
12545 /* Get MAC from NV fail, not update CFG info
12546 * INI MAC value will be used for MAC setting */
Arif Hussain6d2a3322013-11-17 19:50:10 -080012547 hddLog(VOS_TRACE_LEVEL_ERROR," vos_nv_readMacAddress() failed");
Jeff Johnson295189b2012-06-20 16:38:30 -070012548 return VOS_STATUS_E_FAILURE;
12549 }
12550
12551 /* If first MAC is not valid, treat all others are not valid
12552 * Then all MACs will be got from ini file */
12553 if(vos_is_macaddr_zero(&macFromNV[0]))
12554 {
12555 /* MAC address in NV file is not configured yet */
12556 hddLog(VOS_TRACE_LEVEL_WARN, "Invalid MAC in NV file");
12557 return VOS_STATUS_E_INVAL;
12558 }
12559
12560 /* Get MAC address from NV, update CFG info */
12561 for(macLoop = 0; macLoop < VOS_MAX_CONCURRENCY_PERSONA; macLoop++)
12562 {
12563 if(vos_is_macaddr_zero(&macFromNV[macLoop]))
12564 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012565 hddLog(VOS_TRACE_LEVEL_ERROR,"not valid MAC from NV for %d", macLoop);
Jeff Johnson295189b2012-06-20 16:38:30 -070012566 /* This MAC is not valid, skip it
12567 * This MAC will be got from ini file */
12568 }
12569 else
12570 {
12571 vos_mem_copy((v_U8_t *)&pHddCtx->cfg_ini->intfMacAddr[macLoop].bytes[0],
12572 (v_U8_t *)&macFromNV[macLoop].bytes[0],
12573 VOS_MAC_ADDR_SIZE);
12574 }
12575 }
12576 }
12577 else
12578 {
12579 hddLog(VOS_TRACE_LEVEL_ERROR, "NV ITEM, MAC Not valid");
12580 return VOS_STATUS_E_FAILURE;
12581 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012582
Jeff Johnson295189b2012-06-20 16:38:30 -070012583
12584 return VOS_STATUS_SUCCESS;
12585}
12586
12587/**---------------------------------------------------------------------------
12588
12589 \brief hdd_post_voss_start_config() - HDD post voss start config helper
12590
12591 \param - pAdapter - Pointer to the HDD
12592
12593 \return - None
12594
12595 --------------------------------------------------------------------------*/
12596VOS_STATUS hdd_post_voss_start_config(hdd_context_t* pHddCtx)
12597{
12598 eHalStatus halStatus;
12599 v_U32_t listenInterval;
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +053012600 tANI_U32 ignoreDtim;
Jeff Johnson295189b2012-06-20 16:38:30 -070012601
Jeff Johnson295189b2012-06-20 16:38:30 -070012602
12603 // Send ready indication to the HDD. This will kick off the MAC
12604 // into a 'running' state and should kick off an initial scan.
12605 halStatus = sme_HDDReadyInd( pHddCtx->hHal );
12606 if ( !HAL_STATUS_SUCCESS( halStatus ) )
12607 {
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +053012608 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: sme_HDDReadyInd() failed with status "
Jeff Johnson295189b2012-06-20 16:38:30 -070012609 "code %08d [x%08x]",__func__, halStatus, halStatus );
12610 return VOS_STATUS_E_FAILURE;
12611 }
12612
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +053012613 // Set default LI and ignoreDtim into HDD context,
Jeff Johnson295189b2012-06-20 16:38:30 -070012614 // otherwise under some race condition, HDD will set 0 LI value into RIVA,
12615 // And RIVA will crash
12616 wlan_cfgGetInt(pHddCtx->hHal, WNI_CFG_LISTEN_INTERVAL, &listenInterval);
12617 pHddCtx->hdd_actual_LI_value = listenInterval;
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +053012618 wlan_cfgGetInt(pHddCtx->hHal, WNI_CFG_IGNORE_DTIM, &ignoreDtim);
12619 pHddCtx->hdd_actual_ignore_DTIM_value = ignoreDtim;
12620
12621
Jeff Johnson295189b2012-06-20 16:38:30 -070012622 return VOS_STATUS_SUCCESS;
12623}
12624
Jeff Johnson295189b2012-06-20 16:38:30 -070012625/* wake lock APIs for HDD */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053012626void hdd_prevent_suspend(uint32_t reason)
Jeff Johnson295189b2012-06-20 16:38:30 -070012627{
Sushant Kaushik83392fa2015-05-05 17:44:40 +053012628
12629 vos_wake_lock_acquire(&wlan_wake_lock, reason);
12630
Jeff Johnson295189b2012-06-20 16:38:30 -070012631}
12632
Sushant Kaushik83392fa2015-05-05 17:44:40 +053012633void hdd_allow_suspend(uint32_t reason)
Jeff Johnson295189b2012-06-20 16:38:30 -070012634{
Sushant Kaushik83392fa2015-05-05 17:44:40 +053012635
12636 vos_wake_lock_release(&wlan_wake_lock, reason);
12637
Jeff Johnson295189b2012-06-20 16:38:30 -070012638}
12639
Sushant Kaushik83392fa2015-05-05 17:44:40 +053012640void hdd_prevent_suspend_timeout(v_U32_t timeout, uint32_t reason)
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -070012641{
Sushant Kaushik83392fa2015-05-05 17:44:40 +053012642
12643 vos_wake_lock_timeout_release(&wlan_wake_lock, timeout,
12644 reason);
12645
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -070012646}
12647
Jeff Johnson295189b2012-06-20 16:38:30 -070012648/**---------------------------------------------------------------------------
12649
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -070012650 \brief hdd_exchange_version_and_caps() - HDD function to exchange version and capability
12651 information between Host and Riva
12652
12653 This function gets reported version of FW
12654 It also finds the version of Riva headers used to compile the host
12655 It compares the above two and prints a warning if they are different
12656 It gets the SW and HW version string
12657 Finally, it exchanges capabilities between host and Riva i.e. host and riva exchange a msg
12658 indicating the features they support through a bitmap
12659
12660 \param - pHddCtx - Pointer to HDD context
12661
12662 \return - void
12663
12664 --------------------------------------------------------------------------*/
12665
12666void hdd_exchange_version_and_caps(hdd_context_t *pHddCtx)
12667{
12668
12669 tSirVersionType versionCompiled;
12670 tSirVersionType versionReported;
12671 tSirVersionString versionString;
12672 tANI_U8 fwFeatCapsMsgSupported = 0;
12673 VOS_STATUS vstatus;
12674
Mingcheng Zhu87f22fc2014-01-30 19:23:32 -080012675 memset(&versionCompiled, 0, sizeof(versionCompiled));
12676 memset(&versionReported, 0, sizeof(versionReported));
12677
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -070012678 /* retrieve and display WCNSS version information */
12679 do {
12680
12681 vstatus = sme_GetWcnssWlanCompiledVersion(pHddCtx->hHal,
12682 &versionCompiled);
12683 if (!VOS_IS_STATUS_SUCCESS(vstatus))
12684 {
12685 hddLog(VOS_TRACE_LEVEL_FATAL,
12686 "%s: unable to retrieve WCNSS WLAN compiled version",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070012687 __func__);
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -070012688 break;
12689 }
12690
12691 vstatus = sme_GetWcnssWlanReportedVersion(pHddCtx->hHal,
12692 &versionReported);
12693 if (!VOS_IS_STATUS_SUCCESS(vstatus))
12694 {
12695 hddLog(VOS_TRACE_LEVEL_FATAL,
12696 "%s: unable to retrieve WCNSS WLAN reported version",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070012697 __func__);
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -070012698 break;
12699 }
12700
12701 if ((versionCompiled.major != versionReported.major) ||
12702 (versionCompiled.minor != versionReported.minor) ||
12703 (versionCompiled.version != versionReported.version) ||
12704 (versionCompiled.revision != versionReported.revision))
12705 {
12706 pr_err("%s: WCNSS WLAN Version %u.%u.%u.%u, "
12707 "Host expected %u.%u.%u.%u\n",
12708 WLAN_MODULE_NAME,
12709 (int)versionReported.major,
12710 (int)versionReported.minor,
12711 (int)versionReported.version,
12712 (int)versionReported.revision,
12713 (int)versionCompiled.major,
12714 (int)versionCompiled.minor,
12715 (int)versionCompiled.version,
12716 (int)versionCompiled.revision);
12717 }
12718 else
12719 {
12720 pr_info("%s: WCNSS WLAN version %u.%u.%u.%u\n",
12721 WLAN_MODULE_NAME,
12722 (int)versionReported.major,
12723 (int)versionReported.minor,
12724 (int)versionReported.version,
12725 (int)versionReported.revision);
12726 }
12727
12728 vstatus = sme_GetWcnssSoftwareVersion(pHddCtx->hHal,
12729 versionString,
12730 sizeof(versionString));
12731 if (!VOS_IS_STATUS_SUCCESS(vstatus))
12732 {
12733 hddLog(VOS_TRACE_LEVEL_FATAL,
12734 "%s: unable to retrieve WCNSS software version string",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070012735 __func__);
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -070012736 break;
12737 }
12738
12739 pr_info("%s: WCNSS software version %s\n",
12740 WLAN_MODULE_NAME, versionString);
Sushant Kaushik084f6592015-09-10 13:11:56 +053012741 vos_mem_copy(pHddCtx->fw_Version, versionString, sizeof(versionString));
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -070012742
12743 vstatus = sme_GetWcnssHardwareVersion(pHddCtx->hHal,
12744 versionString,
12745 sizeof(versionString));
12746 if (!VOS_IS_STATUS_SUCCESS(vstatus))
12747 {
12748 hddLog(VOS_TRACE_LEVEL_FATAL,
12749 "%s: unable to retrieve WCNSS hardware version string",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070012750 __func__);
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -070012751 break;
12752 }
12753
12754 pr_info("%s: WCNSS hardware version %s\n",
12755 WLAN_MODULE_NAME, versionString);
12756
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -070012757 /* 1.Check if FW version is greater than 0.1.1.0. Only then send host-FW capability exchange message
12758 2.Host-FW capability exchange message is only present on riva 1.1 so
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -070012759 send the message only if it the riva is 1.1
12760 minor numbers for different riva branches:
12761 0 -> (1.0)Mainline Build
12762 1 -> (1.1)Mainline Build
12763 2->(1.04) Stability Build
12764 */
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -070012765 if (((versionReported.major>0) || (versionReported.minor>1) ||
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -070012766 ((versionReported.minor>=1) && (versionReported.version>=1)))
12767 && ((versionReported.major == 1) && (versionReported.minor >= 1)))
12768 fwFeatCapsMsgSupported = 1;
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -070012769
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -070012770 if (fwFeatCapsMsgSupported)
Yathish9f22e662012-12-10 14:21:35 -080012771 {
12772#ifdef WLAN_ACTIVEMODE_OFFLOAD_FEATURE
12773 if(!pHddCtx->cfg_ini->fEnableActiveModeOffload)
12774 sme_disableFeatureCapablity(WLANACTIVE_OFFLOAD);
12775#endif
Ravi Joshid2ca7c42013-07-23 08:37:49 -070012776 /* Indicate if IBSS heartbeat monitoring needs to be offloaded */
12777 if (!pHddCtx->cfg_ini->enableIbssHeartBeatOffload)
12778 {
12779 sme_disableFeatureCapablity(IBSS_HEARTBEAT_OFFLOAD);
12780 }
12781
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -070012782 sme_featureCapsExchange(pHddCtx->hHal);
Yathish9f22e662012-12-10 14:21:35 -080012783 }
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -070012784
12785 } while (0);
12786
12787}
Neelansh Mittaledafed22014-09-04 18:54:39 +053012788void wlan_hdd_send_svc_nlink_msg(int type, void *data, int len)
12789{
12790 struct sk_buff *skb;
12791 struct nlmsghdr *nlh;
12792 tAniMsgHdr *ani_hdr;
Hanumantha Reddy Pothulacf2c7ea2015-04-27 14:50:47 +053012793 int flags = GFP_KERNEL;
Bhargav shah23c94942015-10-13 12:48:35 +053012794 void *nl_data = NULL;
Neelansh Mittaledafed22014-09-04 18:54:39 +053012795
Hanumantha Reddy Pothulacf2c7ea2015-04-27 14:50:47 +053012796 if (in_interrupt() || irqs_disabled() || in_atomic())
12797 flags = GFP_ATOMIC;
12798
12799 skb = alloc_skb(NLMSG_SPACE(WLAN_NL_MAX_PAYLOAD), flags);
Neelansh Mittaledafed22014-09-04 18:54:39 +053012800
12801 if(skb == NULL) {
12802 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12803 "%s: alloc_skb failed", __func__);
12804 return;
12805 }
12806
12807 nlh = (struct nlmsghdr *)skb->data;
12808 nlh->nlmsg_pid = 0; /* from kernel */
12809 nlh->nlmsg_flags = 0;
12810 nlh->nlmsg_seq = 0;
12811 nlh->nlmsg_type = WLAN_NL_MSG_SVC;
12812
12813 ani_hdr = NLMSG_DATA(nlh);
12814 ani_hdr->type = type;
12815
12816 switch(type) {
12817 case WLAN_SVC_SAP_RESTART_IND:
12818 ani_hdr->length = 0;
12819 nlh->nlmsg_len = NLMSG_LENGTH((sizeof(tAniMsgHdr)));
12820 skb_put(skb, NLMSG_SPACE(sizeof(tAniMsgHdr)));
12821 break;
Bhargav Shahd0715912015-10-01 18:17:37 +053012822 case WLAN_SVC_WLAN_TP_IND:
12823 ani_hdr->length = len;
12824 nlh->nlmsg_len = NLMSG_LENGTH((sizeof(tAniMsgHdr)
12825 + len));
12826 nl_data = (char *)ani_hdr + sizeof(tAniMsgHdr);
12827 memcpy(nl_data, data, len);
12828 skb_put(skb, NLMSG_SPACE(sizeof(tAniMsgHdr) + len));
12829 break;
Bhargav shah23c94942015-10-13 12:48:35 +053012830 case WLAN_MSG_RPS_ENABLE_IND:
12831 ani_hdr->length = len;
12832 nlh->nlmsg_len = NLMSG_LENGTH((sizeof(tAniMsgHdr) + len));
12833 nl_data = (char *)ani_hdr + sizeof(tAniMsgHdr);
12834 memcpy(nl_data, data, len);
12835 skb_put(skb, NLMSG_SPACE(sizeof(tAniMsgHdr) + len));
12836 break;
Neelansh Mittaledafed22014-09-04 18:54:39 +053012837 default:
12838 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12839 "Attempt to send unknown nlink message %d", type);
12840 kfree_skb(skb);
12841 return;
12842 }
12843
12844 nl_srv_bcast(skb);
12845
12846 return;
12847}
12848
Bhargav Shahd0715912015-10-01 18:17:37 +053012849/**
12850 * hdd_request_tcp_delack() - Find the Delack value based on RX packet
12851 * @pHddCtx: Valid Global HDD context pointer
12852 * @rx_packets: Number of RX packet in perticular time
12853 *
12854 * Based on the RX packet this function calculate next value of tcp delack.
12855 * This function compare rx packet value to high and low threshold limit.
12856 *
12857 * Return: void
12858 */
12859void hdd_request_tcp_delack(hdd_context_t *pHddCtx, uint64_t rx_packets)
12860{
12861 /* average of rx_packets and prev_rx is taken so that
12862 bus width doesnot fluctuate much */
12863 uint64_t temp_rx = (rx_packets + pHddCtx->prev_rx)/2;
12864 TP_IND_TYPE next_rx_level = pHddCtx->cur_rx_level;
Neelansh Mittaledafed22014-09-04 18:54:39 +053012865
Bhargav Shahd0715912015-10-01 18:17:37 +053012866 pHddCtx->prev_rx = rx_packets;
12867 if (temp_rx > pHddCtx->cfg_ini->tcpDelAckThresholdHigh)
12868 next_rx_level = TP_IND_HIGH;
12869 else if (temp_rx <= pHddCtx->cfg_ini->tcpDelAckThresholdLow)
12870 next_rx_level = TP_IND_LOW;
12871
12872 hdd_set_delack_value(pHddCtx, next_rx_level);
12873}
12874
12875#define HDD_BW_GET_DIFF(x, y) ((x) >= (y) ? (x) - (y) : (ULONG_MAX - (y) + (x)))
12876
12877/**
12878 * hdd_tcp_delack_compute_function() - get link status
12879 * @priv: Valid Global HDD context pointer
12880 *
12881 * This function find number of RX packet during timer life span.
12882 * It request tcp delack with number of RX packet and re-configure delack timer
12883 * for tcpDelAckComputeInterval timer interval.
12884 *
12885 * Return: void
12886 */
12887void hdd_tcp_delack_compute_function(void *priv)
12888{
12889 hdd_context_t *pHddCtx = (hdd_context_t *)priv;
12890 hdd_adapter_t *pAdapter = NULL;
12891 v_U32_t rx_packets = 0;
12892 hdd_adapter_list_node_t *pAdapterNode = NULL;
12893 VOS_STATUS status = 0;
12894
12895 for (status = hdd_get_front_adapter(pHddCtx, &pAdapterNode);
12896 NULL != pAdapterNode && VOS_STATUS_SUCCESS == status;
12897 status = hdd_get_next_adapter(pHddCtx, pAdapterNode, &pAdapterNode)) {
12898 if ((pAdapter = pAdapterNode->pAdapter) == NULL)
12899 continue;
12900
12901 rx_packets += HDD_BW_GET_DIFF(pAdapter->stats.rx_packets,
12902 pAdapter->prev_rx_packets);
12903 pAdapter->prev_rx_packets = pAdapter->stats.rx_packets;
12904 }
12905
12906 hdd_request_tcp_delack(pHddCtx, rx_packets);
12907
12908 vos_timer_start(&pHddCtx->delack_timer,
12909 pHddCtx->cfg_ini->tcpDelAckComputeInterval);
12910}
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -070012911
12912/**---------------------------------------------------------------------------
12913
Gopichand Nakkalafce506f2013-07-03 23:55:16 +053012914 \brief hdd_is_5g_supported() - HDD function to know if hardware supports 5GHz
12915
12916 \param - pHddCtx - Pointer to the hdd context
12917
12918 \return - true if hardware supports 5GHz
12919
12920 --------------------------------------------------------------------------*/
Vinay Krishna Erannafacf5e22014-02-24 13:16:25 +053012921boolean hdd_is_5g_supported(hdd_context_t * pHddCtx)
Gopichand Nakkalafce506f2013-07-03 23:55:16 +053012922{
12923 /* If wcnss_wlan_iris_xo_mode() returns WCNSS_XO_48MHZ(1);
12924 * then hardware support 5Ghz.
12925 */
12926 if (WCNSS_XO_48MHZ == wcnss_wlan_iris_xo_mode())
12927 {
Ratheesh S P36dbc932015-08-07 14:28:57 +053012928 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Hardware supports 5Ghz", __func__);
Gopichand Nakkalafce506f2013-07-03 23:55:16 +053012929 return true;
12930 }
12931 else
12932 {
Ratheesh S P36dbc932015-08-07 14:28:57 +053012933 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Hardware doesn't supports 5Ghz",
Gopichand Nakkalafce506f2013-07-03 23:55:16 +053012934 __func__);
12935 return false;
12936 }
12937}
12938
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +053012939/**---------------------------------------------------------------------------
12940
12941 \brief hdd_generate_iface_mac_addr_auto() - HDD Mac Interface Auto
12942 generate function
12943
12944 This is generate the random mac address for WLAN interface
12945
12946 \param - pHddCtx - Pointer to HDD context
12947 idx - Start interface index to get auto
12948 generated mac addr.
12949 mac_addr - Mac address
12950
12951 \return - 0 for success, < 0 for failure
12952
12953 --------------------------------------------------------------------------*/
12954
12955static int hdd_generate_iface_mac_addr_auto(hdd_context_t *pHddCtx,
12956 int idx, v_MACADDR_t mac_addr)
12957{
12958 int i;
12959 unsigned int serialno;
12960 serialno = wcnss_get_serial_number();
12961
12962 if (0 != serialno)
12963 {
12964 /* MAC address has 3 bytes of OUI so we have a maximum of 3
12965 bytes of the serial number that can be used to generate
12966 the other 3 bytes of the MAC address. Mask off all but
12967 the lower 3 bytes (this will also make sure we don't
12968 overflow in the next step) */
12969 serialno &= 0x00FFFFFF;
12970
12971 /* we need a unique address for each session */
12972 serialno *= VOS_MAX_CONCURRENCY_PERSONA;
12973
12974 /* autogen other Mac addresses */
12975 for (i = idx; i < VOS_MAX_CONCURRENCY_PERSONA; i++)
12976 {
12977 /* start with the entire default address */
12978 pHddCtx->cfg_ini->intfMacAddr[i] = mac_addr;
12979 /* then replace the lower 3 bytes */
12980 pHddCtx->cfg_ini->intfMacAddr[i].bytes[3] = (serialno >> 16) & 0xFF;
12981 pHddCtx->cfg_ini->intfMacAddr[i].bytes[4] = (serialno >> 8) & 0xFF;
12982 pHddCtx->cfg_ini->intfMacAddr[i].bytes[5] = serialno & 0xFF;
12983
Nachiket Kukadede2e24f2017-09-25 16:24:27 +053012984 if (0 == memcmp(&pHddCtx->cfg_ini->intfMacAddr[i].bytes[0],
12985 &mac_addr.bytes[0], VOS_MAC_ADDR_SIZE))
12986 pHddCtx->cfg_ini->intfMacAddr[i].bytes[5] +=
12987 VOS_MAX_CONCURRENCY_PERSONA;
12988
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +053012989 serialno++;
12990 hddLog(VOS_TRACE_LEVEL_ERROR,
12991 "%s: Derived Mac Addr: "
12992 MAC_ADDRESS_STR, __func__,
12993 MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[i].bytes));
12994 }
12995
12996 }
12997 else
12998 {
12999 hddLog(LOGE, FL("Failed to Get Serial NO"));
13000 return -1;
13001 }
13002 return 0;
13003}
Gopichand Nakkalafce506f2013-07-03 23:55:16 +053013004
Katya Nigame7b69a82015-04-28 15:24:06 +053013005int wlan_hdd_mon_open(hdd_context_t *pHddCtx)
13006{
13007 VOS_STATUS status;
13008 v_CONTEXT_t pVosContext= NULL;
13009 hdd_adapter_t *pAdapter= NULL;
13010
13011 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
13012
13013 if (NULL == pVosContext)
13014 {
13015 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13016 "%s: Trying to open VOSS without a PreOpen", __func__);
13017 VOS_ASSERT(0);
13018 return VOS_STATUS_E_FAILURE;
13019 }
13020
13021 status = vos_nv_open();
13022 if (!VOS_IS_STATUS_SUCCESS(status))
13023 {
13024 /* NV module cannot be initialized */
13025 hddLog( VOS_TRACE_LEVEL_FATAL,
13026 "%s: vos_nv_open failed", __func__);
13027 return VOS_STATUS_E_FAILURE;
13028 }
13029
13030 status = vos_init_wiphy_from_nv_bin();
13031 if (!VOS_IS_STATUS_SUCCESS(status))
13032 {
13033 /* NV module cannot be initialized */
13034 hddLog( VOS_TRACE_LEVEL_FATAL,
13035 "%s: vos_init_wiphy failed", __func__);
13036 goto err_vos_nv_close;
13037 }
13038
13039 status = vos_open( &pVosContext, pHddCtx->parent_dev);
13040 if ( !VOS_IS_STATUS_SUCCESS( status ))
13041 {
13042 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: vos_open failed", __func__);
13043 goto err_vos_nv_close;
13044 }
13045
13046 status = vos_mon_start( pVosContext );
13047 if ( !VOS_IS_STATUS_SUCCESS( status ) )
13048 {
13049 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: vos_start failed",__func__);
13050 goto err_vosclose;
13051 }
13052
13053 WLANTL_SetMonRxCbk( pVosContext, hdd_rx_packet_monitor_cbk );
13054 WDA_featureCapsExchange(pVosContext);
13055 wcnss_wlan_set_drvdata(pHddCtx->parent_dev, pHddCtx);
13056
13057 pAdapter = hdd_open_adapter( pHddCtx, WLAN_HDD_MONITOR, "wlan%d",
13058 wlan_hdd_get_intf_addr(pHddCtx), FALSE );
13059 if( pAdapter == NULL )
13060 {
13061 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: hdd_open_adapter failed", __func__);
13062 goto err_close_adapter;
13063 }
13064
13065 //Initialize the nlink service
13066 if(nl_srv_init() != 0)
13067 {
13068 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: nl_srv_init failed", __func__);
13069 goto err_close_adapter;
13070 }
13071 return VOS_STATUS_SUCCESS;
13072
13073err_close_adapter:
13074 hdd_close_all_adapters( pHddCtx );
13075 vos_mon_stop( pVosContext );
13076err_vosclose:
13077 status = vos_sched_close( pVosContext );
13078 if (!VOS_IS_STATUS_SUCCESS(status)) {
13079 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
13080 "%s: Failed to close VOSS Scheduler", __func__);
13081 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( status ) );
13082 }
13083 vos_close(pVosContext );
13084
13085err_vos_nv_close:
13086 vos_nv_close();
13087
13088return status;
13089}
Gopichand Nakkalafce506f2013-07-03 23:55:16 +053013090/**---------------------------------------------------------------------------
13091
Mihir Shetefc7ff5b2014-01-27 11:30:05 +053013092 \brief hdd_11d_scan_done - callback to be executed when 11d scan is
13093 completed to flush out the scan results
13094
13095 11d scan is done during driver load and is a passive scan on all
13096 channels supported by the device, 11d scans may find some APs on
13097 frequencies which are forbidden to be used in the regulatory domain
13098 the device is operating in. If these APs are notified to the supplicant
13099 it may try to connect to these APs, thus flush out all the scan results
13100 which are present in SME after 11d scan is done.
13101
13102 \return - eHalStatus
13103
13104 --------------------------------------------------------------------------*/
13105static eHalStatus hdd_11d_scan_done(tHalHandle halHandle, void *pContext,
13106 tANI_U32 scanId, eCsrScanStatus status)
13107{
13108 ENTER();
13109
13110 sme_ScanFlushResult(halHandle, 0);
13111
13112 EXIT();
13113
13114 return eHAL_STATUS_SUCCESS;
13115}
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053013116/**---------------------------------------------------------------------------
13117
13118 \brief hdd_init_frame_logging_done - callback to be executed when mgmt frame
13119 logging is completed successfully.
13120
13121 \return - None
13122
13123 --------------------------------------------------------------------------*/
c_manjeecfd1efb2015-09-25 19:32:34 +053013124void hdd_init_frame_logging_done(void *fwlogInitCbContext, tAniLoggingInitRsp *pRsp)
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053013125{
Siddharth Bhald1be97f2015-05-27 22:39:59 +053013126 hdd_context_t* pHddCtx = (hdd_context_t*)fwlogInitCbContext;
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053013127
13128 if (NULL == pHddCtx)
13129 {
13130 hddLog(VOS_TRACE_LEVEL_ERROR,
13131 "%s: HDD context is NULL",__func__);
13132 return;
13133 }
13134
c_manjeecfd1efb2015-09-25 19:32:34 +053013135 if ((pRsp->status == VOS_STATUS_SUCCESS) &&
Mahesh A Saptasagarfabb1a02015-06-29 12:17:04 +053013136 (TRUE == pHddCtx->cfg_ini->enableMgmtLogging))
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053013137 {
13138 hddLog(VOS_TRACE_LEVEL_INFO, FL("Mgmt Frame Logging init successful"));
13139 pHddCtx->mgmt_frame_logging = TRUE;
13140 }
13141 else
13142 {
13143 hddLog(VOS_TRACE_LEVEL_INFO, FL("Mgmt Frame Logging init not success"));
13144 pHddCtx->mgmt_frame_logging = FALSE;
c_manjeecfd1efb2015-09-25 19:32:34 +053013145 return;
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053013146 }
13147
c_manjeecfd1efb2015-09-25 19:32:34 +053013148 /*Check feature supported by FW*/
13149 if(TRUE == sme_IsFeatureSupportedByFW(MEMORY_DUMP_SUPPORTED))
13150 {
13151 //Store fwr mem dump size given by firmware.
13152 wlan_store_fwr_mem_dump_size(pRsp->fw_mem_dump_max_size);
13153 }
13154 else
13155 {
13156 wlan_store_fwr_mem_dump_size(0);
13157 }
13158
13159
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053013160}
13161/**---------------------------------------------------------------------------
13162
13163 \brief hdd_init_frame_logging - function to initialize frame logging.
13164 Currently only Mgmt Frames are logged in both TX
13165 and Rx direction and are sent to userspace
13166 application using logger thread when queried.
13167
13168 \return - None
13169
13170 --------------------------------------------------------------------------*/
Siddharth Bhald1be97f2015-05-27 22:39:59 +053013171void hdd_init_frame_logging(hdd_context_t* pHddCtx)
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053013172{
13173 eHalStatus halStatus = eHAL_STATUS_FAILURE;
Sreelakshmi Konamkid8784d92016-04-14 14:59:13 +053013174 tSirFWLoggingInitParam wlanFWLoggingInitParam = {0};
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053013175
Siddharth Bhald1be97f2015-05-27 22:39:59 +053013176 if (TRUE != sme_IsFeatureSupportedByFW(MGMT_FRAME_LOGGING) &&
13177 TRUE != sme_IsFeatureSupportedByFW(LOGGING_ENHANCEMENT))
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053013178 {
13179 hddLog(VOS_TRACE_LEVEL_INFO, FL("MGMT_FRAME_LOGGING not supp by FW"));
13180 return;
13181 }
13182
c_manjeecfd1efb2015-09-25 19:32:34 +053013183 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Configuring %s %s %s %s Logging",__func__,
Siddharth Bhald1be97f2015-05-27 22:39:59 +053013184 pHddCtx->cfg_ini->enableFWLogging?"FW Log,":"",
13185 pHddCtx->cfg_ini->enableContFWLogging ? "Cont FW log,":"",
c_manjeecfd1efb2015-09-25 19:32:34 +053013186 pHddCtx->cfg_ini->enableMgmtLogging ? "Mgmt Pkt Log":"",
13187 pHddCtx->cfg_ini->enableFwrMemDump ? "Fw Mem dump":"");
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053013188
Siddharth Bhald1be97f2015-05-27 22:39:59 +053013189 if (pHddCtx->cfg_ini->enableFWLogging ||
13190 pHddCtx->cfg_ini->enableContFWLogging)
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053013191 {
Sreelakshmi Konamkid8784d92016-04-14 14:59:13 +053013192 wlanFWLoggingInitParam.enableFlag |= WLAN_QXDM_LOG_EN;
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053013193 }
13194
Sushant Kaushik46804902015-07-08 14:46:03 +053013195 if (pHddCtx->cfg_ini->enableMgmtLogging)
13196 {
Sreelakshmi Konamkid8784d92016-04-14 14:59:13 +053013197 wlanFWLoggingInitParam.enableFlag |= WLAN_FRAME_LOG_EN;
Sushant Kaushik46804902015-07-08 14:46:03 +053013198 }
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053013199 if (pHddCtx->cfg_ini->enableBMUHWtracing)
13200 {
Sreelakshmi Konamkid8784d92016-04-14 14:59:13 +053013201 wlanFWLoggingInitParam.enableFlag |= WLAN_BMUHW_TRACE_LOG_EN;
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053013202 }
c_manjeecfd1efb2015-09-25 19:32:34 +053013203 if(pHddCtx->cfg_ini->enableFwrMemDump &&
13204 (TRUE == sme_IsFeatureSupportedByFW(MEMORY_DUMP_SUPPORTED)))
13205 {
Sreelakshmi Konamkid8784d92016-04-14 14:59:13 +053013206 wlanFWLoggingInitParam.enableFlag |= WLAN_FW_MEM_DUMP_EN;
c_manjeecfd1efb2015-09-25 19:32:34 +053013207 }
Sreelakshmi Konamkid8784d92016-04-14 14:59:13 +053013208 if( wlanFWLoggingInitParam.enableFlag == 0 )
c_manjeecfd1efb2015-09-25 19:32:34 +053013209 {
13210 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Logging not enabled", __func__);
13211 return;
13212 }
Sreelakshmi Konamkid8784d92016-04-14 14:59:13 +053013213 wlanFWLoggingInitParam.frameType = WLAN_FRAME_LOGGING_FRAMETYPE_MGMT;
13214 wlanFWLoggingInitParam.frameSize = WLAN_MGMT_LOGGING_FRAMESIZE_128BYTES;
13215 wlanFWLoggingInitParam.bufferMode = WLAN_FRAME_LOGGING_BUFFERMODE_CIRCULAR;
13216 wlanFWLoggingInitParam.continuousFrameLogging =
Siddharth Bhald1be97f2015-05-27 22:39:59 +053013217 pHddCtx->cfg_ini->enableContFWLogging;
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053013218
Sreelakshmi Konamkid8784d92016-04-14 14:59:13 +053013219 wlanFWLoggingInitParam.enableFlag &= ~WLAN_DPU_TXP_LOG_EN;
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053013220
Sreelakshmi Konamkid8784d92016-04-14 14:59:13 +053013221 wlanFWLoggingInitParam.minLogBufferSize =
Siddharth Bhald1be97f2015-05-27 22:39:59 +053013222 pHddCtx->cfg_ini->minLoggingBufferSize;
Sreelakshmi Konamkid8784d92016-04-14 14:59:13 +053013223 wlanFWLoggingInitParam.maxLogBufferSize =
Siddharth Bhald1be97f2015-05-27 22:39:59 +053013224 pHddCtx->cfg_ini->maxLoggingBufferSize;
Sreelakshmi Konamkid8784d92016-04-14 14:59:13 +053013225 wlanFWLoggingInitParam.fwlogInitCallback = hdd_init_frame_logging_done;
13226 wlanFWLoggingInitParam.fwlogInitCbContext= pHddCtx;
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053013227
Sreelakshmi Konamkid8784d92016-04-14 14:59:13 +053013228 halStatus = sme_InitMgmtFrameLogging(pHddCtx->hHal, &wlanFWLoggingInitParam);
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053013229
13230 if (eHAL_STATUS_SUCCESS != halStatus)
13231 {
Sreelakshmi Konamkid8784d92016-04-14 14:59:13 +053013232 hddLog(LOGE, FL("sme_InitMgmtFrameLogging failed, returned %d"),
13233 halStatus);
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053013234 }
13235
13236 return;
13237}
Mihir Shetefc7ff5b2014-01-27 11:30:05 +053013238
Bhargav shah23c94942015-10-13 12:48:35 +053013239static void hdd_dp_util_send_rps_ind(hdd_context_t *hdd_ctxt)
13240{
13241 hdd_adapter_t *adapter;
13242 hdd_adapter_list_node_t *adapter_node, *next;
13243 VOS_STATUS status = VOS_STATUS_SUCCESS;
13244 struct wlan_rps_data rps_data;
13245 int count;
13246
13247 if(!hdd_ctxt->cfg_ini->rps_mask)
13248 {
13249 return;
13250 }
13251
13252 for (count=0; count < WLAN_SVC_IFACE_NUM_QUEUES; count++)
13253 {
13254 rps_data.cpu_map[count] = hdd_ctxt->cfg_ini->rps_mask;
13255 }
13256
13257 rps_data.num_queues = WLAN_SVC_IFACE_NUM_QUEUES;
13258
13259 hddLog(LOG1, FL("0x%x 0x%x 0x%x 0x%x 0x%x 0x%x"),
13260 rps_data.cpu_map[0], rps_data.cpu_map[1],rps_data.cpu_map[2],
13261 rps_data.cpu_map[3], rps_data.cpu_map[4], rps_data.cpu_map[5]);
13262
13263 status = hdd_get_front_adapter (hdd_ctxt, &adapter_node);
13264
13265 while (NULL != adapter_node && VOS_STATUS_SUCCESS == status)
13266 {
13267 adapter = adapter_node->pAdapter;
13268 if (NULL != adapter) {
13269 strlcpy(rps_data.ifname, adapter->dev->name,
13270 sizeof(rps_data.ifname));
13271 wlan_hdd_send_svc_nlink_msg(WLAN_MSG_RPS_ENABLE_IND,
13272 (void *)&rps_data,sizeof(rps_data));
13273 }
13274 status = hdd_get_next_adapter (hdd_ctxt, adapter_node, &next);
13275 adapter_node = next;
13276 }
13277}
13278
Masti, Narayanraddi26378462016-01-05 18:20:28 +053013279void wlan_hdd_schedule_defer_scan(struct work_struct *work)
13280{
13281 scan_context_t *scan_ctx =
13282 container_of(work, scan_context_t, scan_work.work);
13283
13284 if (NULL == scan_ctx)
13285 {
13286 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13287 FL("scan_ctx is NULL"));
13288 return;
13289 }
13290
13291 if (unlikely(TDLS_CTX_MAGIC != scan_ctx->magic))
13292 return;
13293
13294 scan_ctx->attempt++;
13295
13296 wlan_hdd_cfg80211_scan(scan_ctx->wiphy,
13297#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
13298 scan_ctx->dev,
13299#endif
13300 scan_ctx->scan_request);
13301}
13302
13303int wlan_hdd_copy_defer_scan_context(hdd_context_t *pHddCtx,
13304 struct wiphy *wiphy,
13305#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
13306 struct net_device *dev,
13307#endif
13308 struct cfg80211_scan_request *request)
13309{
13310 scan_context_t *scan_ctx;
13311
13312 ENTER();
13313 if (0 != (wlan_hdd_validate_context(pHddCtx)))
13314 {
13315 return -1;
13316 }
13317
13318 scan_ctx = &pHddCtx->scan_ctxt;
13319
13320 scan_ctx->wiphy = wiphy;
13321#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
13322 scan_ctx->dev = dev;
13323#endif
13324
13325 scan_ctx->scan_request = request;
13326
13327 EXIT();
13328 return 0;
13329}
13330
13331void wlan_hdd_defer_scan_init_work(hdd_context_t *pHddCtx,
13332 struct wiphy *wiphy,
13333#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
13334 struct net_device *dev,
13335#endif
13336 struct cfg80211_scan_request *request,
13337 unsigned long delay)
13338{
13339 if (TDLS_CTX_MAGIC != pHddCtx->scan_ctxt.magic)
13340 {
13341#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
13342 wlan_hdd_copy_defer_scan_context(pHddCtx, wiphy, dev, request);
13343#else
13344 wlan_hdd_copy_defer_scan_context(pHddCtx, wiphy, request);
13345#endif
13346 pHddCtx->scan_ctxt.attempt = 0;
13347 pHddCtx->scan_ctxt.magic = TDLS_CTX_MAGIC;
13348 }
13349 schedule_delayed_work(&pHddCtx->scan_ctxt.scan_work, delay);
13350}
13351
13352void wlan_hdd_init_deinit_defer_scan_context(scan_context_t *scan_ctx)
13353{
13354 scan_ctx->magic = 0;
13355 scan_ctx->attempt = 0;
13356 scan_ctx->reject = 0;
13357 scan_ctx->scan_request = NULL;
13358
13359 return;
13360}
13361
Mihir Shetefc7ff5b2014-01-27 11:30:05 +053013362/**---------------------------------------------------------------------------
13363
Jeff Johnson295189b2012-06-20 16:38:30 -070013364 \brief hdd_wlan_startup() - HDD init function
13365
13366 This is the driver startup code executed once a WLAN device has been detected
13367
13368 \param - dev - Pointer to the underlying device
13369
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -080013370 \return - 0 for success, < 0 for failure
Jeff Johnson295189b2012-06-20 16:38:30 -070013371
13372 --------------------------------------------------------------------------*/
13373
13374int hdd_wlan_startup(struct device *dev )
13375{
13376 VOS_STATUS status;
13377 hdd_adapter_t *pAdapter = NULL;
Jeff Johnsone7245742012-09-05 17:12:55 -070013378 hdd_adapter_t *pP2pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070013379 hdd_context_t *pHddCtx = NULL;
13380 v_CONTEXT_t pVosContext= NULL;
13381#ifdef WLAN_BTAMP_FEATURE
13382 VOS_STATUS vStatus = VOS_STATUS_SUCCESS;
13383 WLANBAP_ConfigType btAmpConfig;
13384 hdd_config_t *pConfig;
13385#endif
13386 int ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070013387 struct wiphy *wiphy;
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +053013388 v_MACADDR_t mac_addr;
Jeff Johnson295189b2012-06-20 16:38:30 -070013389
13390 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -070013391 /*
13392 * cfg80211: wiphy allocation
13393 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +053013394 wiphy = wlan_hdd_cfg80211_wiphy_alloc(sizeof(hdd_context_t)) ;
Jeff Johnson295189b2012-06-20 16:38:30 -070013395
13396 if(wiphy == NULL)
13397 {
13398 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: cfg80211 init failed", __func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -080013399 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -070013400 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013401 pHddCtx = wiphy_priv(wiphy);
13402
Jeff Johnson295189b2012-06-20 16:38:30 -070013403 //Initialize the adapter context to zeros.
13404 vos_mem_zero(pHddCtx, sizeof( hdd_context_t ));
13405
Jeff Johnson295189b2012-06-20 16:38:30 -070013406 pHddCtx->wiphy = wiphy;
Sushant Kaushik83392fa2015-05-05 17:44:40 +053013407 hdd_prevent_suspend(WIFI_POWER_EVENT_WAKELOCK_DRIVER_INIT);
Mihir Shete18156292014-03-11 15:38:30 +053013408 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_LOAD_IN_PROGRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -070013409
13410 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, TRUE);
13411
Siddharth Bhalcd92b782015-06-29 12:25:40 +053013412 /* register for riva power on lock to platform driver
13413 * Locking power early to ensure FW doesn't reset by kernel while
13414 * host driver is busy initializing itself */
13415 if (req_riva_power_on_lock("wlan"))
13416 {
13417 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: req riva power on lock failed",
13418 __func__);
13419 goto err_free_hdd_context;
13420 }
13421
Jeff Johnson295189b2012-06-20 16:38:30 -070013422 /*Get vos context here bcoz vos_open requires it*/
13423 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
13424
Madan Mohan Koyyalamudi0b78e152012-11-28 15:46:51 -080013425 if(pVosContext == NULL)
13426 {
13427 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Failed vos_get_global_context",__func__);
13428 goto err_free_hdd_context;
13429 }
13430
Jeff Johnson295189b2012-06-20 16:38:30 -070013431 //Save the Global VOSS context in adapter context for future.
13432 pHddCtx->pvosContext = pVosContext;
13433
13434 //Save the adapter context in global context for future.
13435 ((VosContextType*)(pVosContext))->pHDDContext = (v_VOID_t*)pHddCtx;
13436
Jeff Johnson295189b2012-06-20 16:38:30 -070013437 pHddCtx->parent_dev = dev;
Sreelakshmi Konamkif0646d52016-12-09 12:35:31 +053013438 pHddCtx->last_scan_reject_session_id = 0xFF;
13439 pHddCtx->last_scan_reject_reason = 0;
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053013440 pHddCtx->last_scan_reject_timestamp = 0;
Abhishek Singhe4b12562017-06-20 16:53:39 +053013441 pHddCtx->scan_reject_cnt = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070013442
13443 init_completion(&pHddCtx->full_pwr_comp_var);
13444 init_completion(&pHddCtx->standby_comp_var);
13445 init_completion(&pHddCtx->req_bmps_comp_var);
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070013446 init_completion(&pHddCtx->scan_info.scan_req_completion_event);
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -080013447 init_completion(&pHddCtx->scan_info.abortscan_event_var);
Kiet Lam46b8e4e2013-11-06 21:49:53 +053013448 init_completion(&pHddCtx->wiphy_channel_update_event);
Arun Kumar Khandavallie0b046d2014-03-01 21:54:25 +053013449 init_completion(&pHddCtx->ssr_comp_var);
Mahesh A Saptasagar67ab9222015-10-21 15:38:41 +053013450 init_completion(&pHddCtx->mc_sus_event_var);
13451 init_completion(&pHddCtx->tx_sus_event_var);
13452 init_completion(&pHddCtx->rx_sus_event_var);
13453
Amar Singhala49cbc52013-10-08 18:37:44 -070013454
mukul sharma4bd8d2e2015-08-13 20:33:25 +053013455 hdd_init_ll_stats_ctx(pHddCtx);
Anurag Chouhan6ee81542017-02-09 18:09:27 +053013456 hdd_init_nud_stats_ctx(pHddCtx);
mukul sharma4bd8d2e2015-08-13 20:33:25 +053013457
Amar Singhala49cbc52013-10-08 18:37:44 -070013458#ifdef CONFIG_ENABLE_LINUX_REG
Amar Singhalfddc28c2013-09-05 13:03:40 -070013459 init_completion(&pHddCtx->linux_reg_req);
Amar Singhala49cbc52013-10-08 18:37:44 -070013460#else
13461 init_completion(&pHddCtx->driver_crda_req);
13462#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070013463
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +053013464#ifdef WLAN_FEATURE_EXTSCAN
13465 init_completion(&pHddCtx->ext_scan_context.response_event);
13466#endif /* WLAN_FEATURE_EXTSCAN */
13467
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053013468 spin_lock_init(&pHddCtx->schedScan_lock);
Kapil Gupta137ef892016-12-13 19:38:00 +053013469 vos_spin_lock_init(&pHddCtx->sap_update_info_lock);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053013470
Jeff Johnson295189b2012-06-20 16:38:30 -070013471 hdd_list_init( &pHddCtx->hddAdapters, MAX_NUMBER_OF_ADAPTERS );
13472
Padma, Santhosh Kumar9cd38332015-11-17 12:18:10 +053013473 vos_init_delayed_work(&pHddCtx->spoof_mac_addr_work,
13474 hdd_processSpoofMacAddrRequest);
Kapil Gupta137ef892016-12-13 19:38:00 +053013475 vos_init_work(&pHddCtx->sap_start_work, hdd_sap_restart_handle);
Abhishek Singh78c691f2017-11-30 13:48:44 +053013476 vos_init_delayed_work(&pHddCtx->ecsa_chan_change_work,
13477 hdd_force_scc_with_ecsa_handle);
Padma, Santhosh Kumar9cd38332015-11-17 12:18:10 +053013478
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053013479#ifdef FEATURE_WLAN_TDLS
13480 /* tdls_lock is initialized before an hdd_open_adapter ( which is
13481 * invoked by other instances also) to protect the concurrent
13482 * access for the Adapters by TDLS module.
13483 */
13484 mutex_init(&pHddCtx->tdls_lock);
13485#endif
Siddharth Bhal76972212014-10-15 16:22:51 +053013486 mutex_init(&pHddCtx->spoofMacAddr.macSpoofingLock);
Mukul Sharma1fd6efd2015-02-14 00:29:14 +053013487 mutex_init(&pHddCtx->wmmLock);
13488
Srinivas Girigowda8bf64cb2015-09-30 19:50:09 +053013489 hdd_init_offloaded_packets_ctx(pHddCtx);
Agarwal Ashish1f422872014-07-22 00:11:55 +053013490 /* By default Strict Regulatory For FCC should be false */
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053013491
Agarwal Ashish1f422872014-07-22 00:11:55 +053013492 pHddCtx->nEnableStrictRegulatoryForFCC = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070013493 // Load all config first as TL config is needed during vos_open
13494 pHddCtx->cfg_ini = (hdd_config_t*) kmalloc(sizeof(hdd_config_t), GFP_KERNEL);
13495 if(pHddCtx->cfg_ini == NULL)
13496 {
13497 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Failed kmalloc hdd_config_t",__func__);
13498 goto err_free_hdd_context;
13499 }
13500
Hanumanth Reddy Pothula1efcd162018-03-14 14:32:27 +053013501 hdd_request_manager_init();
13502
Jeff Johnson295189b2012-06-20 16:38:30 -070013503 vos_mem_zero(pHddCtx->cfg_ini, sizeof( hdd_config_t ));
13504
13505 // Read and parse the qcom_cfg.ini file
13506 status = hdd_parse_config_ini( pHddCtx );
13507 if ( VOS_STATUS_SUCCESS != status )
13508 {
13509 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: error parsing %s",
13510 __func__, WLAN_INI_FILE);
13511 goto err_config;
13512 }
Arif Hussaind5218912013-12-05 01:10:55 -080013513#ifdef MEMORY_DEBUG
13514 if (pHddCtx->cfg_ini->IsMemoryDebugSupportEnabled)
13515 vos_mem_init();
13516
13517 hddLog(VOS_TRACE_LEVEL_INFO, "%s: gEnableMemoryDebug=%d",
13518 __func__, pHddCtx->cfg_ini->IsMemoryDebugSupportEnabled);
13519#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070013520
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +053013521 /* INI has been read, initialise the configuredMcastBcastFilter with
13522 * INI value as this will serve as the default value
13523 */
13524 pHddCtx->configuredMcastBcastFilter = pHddCtx->cfg_ini->mcastBcastFilterSetting;
13525 hddLog(VOS_TRACE_LEVEL_INFO, "Setting configuredMcastBcastFilter: %d",
13526 pHddCtx->cfg_ini->mcastBcastFilterSetting);
Gopichand Nakkalafce506f2013-07-03 23:55:16 +053013527
13528 if (false == hdd_is_5g_supported(pHddCtx))
13529 {
13530 //5Ghz is not supported.
13531 if (1 != pHddCtx->cfg_ini->nBandCapability)
13532 {
13533 hddLog(VOS_TRACE_LEVEL_INFO,
13534 "%s: Setting pHddCtx->cfg_ini->nBandCapability = 1", __func__);
13535 pHddCtx->cfg_ini->nBandCapability = 1;
13536 }
13537 }
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053013538
13539 /* If SNR Monitoring is enabled, FW has to parse all beacons
13540 * for calcaluting and storing the average SNR, so set Nth beacon
13541 * filter to 1 to enable FW to parse all the beaocons
13542 */
13543 if (1 == pHddCtx->cfg_ini->fEnableSNRMonitoring)
13544 {
13545 /* The log level is deliberately set to WARN as overriding
13546 * nthBeaconFilter to 1 will increase power cosumption and this
13547 * might just prove helpful to detect the power issue.
13548 */
13549 hddLog(VOS_TRACE_LEVEL_WARN,
13550 "%s: Setting pHddCtx->cfg_ini->nthBeaconFilter = 1", __func__);
13551 pHddCtx->cfg_ini->nthBeaconFilter = 1;
13552 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013553 /*
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +053013554 * cfg80211: Initialization ...
Jeff Johnson295189b2012-06-20 16:38:30 -070013555 */
Manjeet Singh61016fa2016-12-02 11:10:19 +053013556 if (0 < wlan_hdd_cfg80211_init(dev, wiphy, pHddCtx->cfg_ini))
Jeff Johnson295189b2012-06-20 16:38:30 -070013557 {
Manjeet Singh61016fa2016-12-02 11:10:19 +053013558 hddLog(VOS_TRACE_LEVEL_FATAL,
13559 "%s: wlan_hdd_cfg80211_init return failure", __func__);
13560 goto err_config;
Jeff Johnson295189b2012-06-20 16:38:30 -070013561 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013562
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -080013563 // Update VOS trace levels based upon the cfg.ini
13564 hdd_vos_trace_enable(VOS_MODULE_ID_BAP,
13565 pHddCtx->cfg_ini->vosTraceEnableBAP);
13566 hdd_vos_trace_enable(VOS_MODULE_ID_TL,
13567 pHddCtx->cfg_ini->vosTraceEnableTL);
13568 hdd_vos_trace_enable(VOS_MODULE_ID_WDI,
13569 pHddCtx->cfg_ini->vosTraceEnableWDI);
13570 hdd_vos_trace_enable(VOS_MODULE_ID_HDD,
13571 pHddCtx->cfg_ini->vosTraceEnableHDD);
13572 hdd_vos_trace_enable(VOS_MODULE_ID_SME,
13573 pHddCtx->cfg_ini->vosTraceEnableSME);
13574 hdd_vos_trace_enable(VOS_MODULE_ID_PE,
13575 pHddCtx->cfg_ini->vosTraceEnablePE);
Katya Nigam70d68332013-09-16 16:49:45 +053013576 hdd_vos_trace_enable(VOS_MODULE_ID_PMC,
13577 pHddCtx->cfg_ini->vosTraceEnablePMC);
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -080013578 hdd_vos_trace_enable(VOS_MODULE_ID_WDA,
13579 pHddCtx->cfg_ini->vosTraceEnableWDA);
13580 hdd_vos_trace_enable(VOS_MODULE_ID_SYS,
13581 pHddCtx->cfg_ini->vosTraceEnableSYS);
13582 hdd_vos_trace_enable(VOS_MODULE_ID_VOSS,
13583 pHddCtx->cfg_ini->vosTraceEnableVOSS);
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -080013584 hdd_vos_trace_enable(VOS_MODULE_ID_SAP,
13585 pHddCtx->cfg_ini->vosTraceEnableSAP);
13586 hdd_vos_trace_enable(VOS_MODULE_ID_HDD_SOFTAP,
13587 pHddCtx->cfg_ini->vosTraceEnableHDDSAP);
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -080013588
Jeff Johnson295189b2012-06-20 16:38:30 -070013589 // Update WDI trace levels based upon the cfg.ini
13590 hdd_wdi_trace_enable(eWLAN_MODULE_DAL,
13591 pHddCtx->cfg_ini->wdiTraceEnableDAL);
13592 hdd_wdi_trace_enable(eWLAN_MODULE_DAL_CTRL,
13593 pHddCtx->cfg_ini->wdiTraceEnableCTL);
13594 hdd_wdi_trace_enable(eWLAN_MODULE_DAL_DATA,
13595 pHddCtx->cfg_ini->wdiTraceEnableDAT);
13596 hdd_wdi_trace_enable(eWLAN_MODULE_PAL,
13597 pHddCtx->cfg_ini->wdiTraceEnablePAL);
Jeff Johnson295189b2012-06-20 16:38:30 -070013598
Jeff Johnson88ba7742013-02-27 14:36:02 -080013599 if (VOS_FTM_MODE == hdd_get_conparam())
13600 {
Jeff Johnson295189b2012-06-20 16:38:30 -070013601 if ( VOS_STATUS_SUCCESS != wlan_hdd_ftm_open(pHddCtx) )
13602 {
13603 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: wlan_hdd_ftm_open Failed",__func__);
13604 goto err_free_hdd_context;
13605 }
13606 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: FTM driver loaded success fully",__func__);
Sachin Ahuja38ef5e02015-03-13 17:31:16 +053013607 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_NO_LOAD_UNLOAD_IN_PROGRESS;
c_hpothu2de0ef62014-04-15 16:16:15 +053013608 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, FALSE);
Jeff Johnson295189b2012-06-20 16:38:30 -070013609 return VOS_STATUS_SUCCESS;
Jeff Johnson88ba7742013-02-27 14:36:02 -080013610 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013611
Katya Nigame7b69a82015-04-28 15:24:06 +053013612 if( VOS_MONITOR_MODE == hdd_get_conparam())
13613 {
13614 if ( VOS_STATUS_SUCCESS != wlan_hdd_mon_open(pHddCtx))
13615 {
13616 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: wlan_hdd_mon_open Failed",__func__);
13617 goto err_free_hdd_context;
13618 }
13619 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Driver loaded in Monitor Mode",__func__);
13620 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_NO_LOAD_UNLOAD_IN_PROGRESS;
13621 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, FALSE);
13622 return VOS_STATUS_SUCCESS;
13623 }
13624
Jeff Johnson88ba7742013-02-27 14:36:02 -080013625 //Open watchdog module
Jeff Johnson295189b2012-06-20 16:38:30 -070013626 if(pHddCtx->cfg_ini->fIsLogpEnabled)
13627 {
13628 status = vos_watchdog_open(pVosContext,
13629 &((VosContextType*)pVosContext)->vosWatchdog, sizeof(VosWatchdogContext));
13630
13631 if(!VOS_IS_STATUS_SUCCESS( status ))
13632 {
13633 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: vos_watchdog_open failed",__func__);
Ashish Kumar Dhanotiya532bdef2017-05-09 17:31:59 +053013634 goto err_config;
Jeff Johnson295189b2012-06-20 16:38:30 -070013635 }
13636 }
13637
13638 pHddCtx->isLogpInProgress = FALSE;
13639 vos_set_logp_in_progress(VOS_MODULE_ID_VOSS, FALSE);
13640
Amar Singhala49cbc52013-10-08 18:37:44 -070013641#ifdef CONFIG_ENABLE_LINUX_REG
Amar Singhal0a402232013-10-11 20:57:16 -070013642 /* initialize the NV module. This is required so that
13643 we can initialize the channel information in wiphy
13644 from the NV.bin data. The channel information in
13645 wiphy needs to be initialized before wiphy registration */
13646
13647 status = vos_nv_open();
13648 if (!VOS_IS_STATUS_SUCCESS(status))
13649 {
13650 /* NV module cannot be initialized */
13651 hddLog( VOS_TRACE_LEVEL_FATAL,
13652 "%s: vos_nv_open failed", __func__);
Vinay Krishna Eranna2025d892014-09-18 16:51:42 +053013653 goto err_wdclose;
Amar Singhal0a402232013-10-11 20:57:16 -070013654 }
13655
13656 status = vos_init_wiphy_from_nv_bin();
13657 if (!VOS_IS_STATUS_SUCCESS(status))
13658 {
13659 /* NV module cannot be initialized */
13660 hddLog( VOS_TRACE_LEVEL_FATAL,
13661 "%s: vos_init_wiphy failed", __func__);
13662 goto err_vos_nv_close;
13663 }
13664
Amar Singhala49cbc52013-10-08 18:37:44 -070013665#endif
Mahesh A Saptasagarc3ed0122016-01-19 16:45:11 +053013666 //Initialize the nlink service
13667 if(nl_srv_init() != 0)
13668 {
13669 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: nl_srv_init failed", __func__);
13670 goto err_vos_nv_close;
13671 }
13672
13673#ifdef WLAN_KD_READY_NOTIFIER
13674 pHddCtx->kd_nl_init = 1;
13675#endif /* WLAN_KD_READY_NOTIFIER */
13676
Girish Gowlibf0e1ab2015-01-19 16:05:16 +053013677 vos_set_roam_delay_stats_enabled(pHddCtx->cfg_ini->gEnableRoamDelayStats);
Arun Kumar Khandavalliebb19482014-03-25 13:56:53 +053013678 status = vos_open( &pVosContext, pHddCtx->parent_dev);
Jeff Johnson295189b2012-06-20 16:38:30 -070013679 if ( !VOS_IS_STATUS_SUCCESS( status ))
13680 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -080013681 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: vos_open failed", __func__);
Mahesh A Saptasagarc3ed0122016-01-19 16:45:11 +053013682 goto err_nl_srv;
Jeff Johnson295189b2012-06-20 16:38:30 -070013683 }
13684
Jeff Johnson295189b2012-06-20 16:38:30 -070013685 pHddCtx->hHal = (tHalHandle)vos_get_context( VOS_MODULE_ID_SME, pVosContext );
13686
13687 if ( NULL == pHddCtx->hHal )
13688 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -080013689 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: HAL context is null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070013690 goto err_vosclose;
13691 }
13692
Jeff Johnsonbc676b42013-02-14 16:04:08 -080013693 status = vos_preStart( pHddCtx->pvosContext );
13694 if ( !VOS_IS_STATUS_SUCCESS( status ) )
13695 {
13696 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: vos_preStart failed", __func__);
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053013697 goto err_vosclose;
Jeff Johnsonbc676b42013-02-14 16:04:08 -080013698 }
Jeff Johnsone7245742012-09-05 17:12:55 -070013699
Arif Hussaineaf68602013-12-30 23:10:44 -080013700 if (0 == enable_dfs_chan_scan || 1 == enable_dfs_chan_scan)
13701 {
13702 pHddCtx->cfg_ini->enableDFSChnlScan = enable_dfs_chan_scan;
13703 hddLog(VOS_TRACE_LEVEL_INFO, "%s: module enable_dfs_chan_scan set to %d",
13704 __func__, enable_dfs_chan_scan);
13705 }
13706 if (0 == enable_11d || 1 == enable_11d)
13707 {
13708 pHddCtx->cfg_ini->Is11dSupportEnabled = enable_11d;
13709 hddLog(VOS_TRACE_LEVEL_INFO, "%s: module enable_11d set to %d",
13710 __func__, enable_11d);
13711 }
13712
Jeff Johnsonbc676b42013-02-14 16:04:08 -080013713 /* Note that the vos_preStart() sequence triggers the cfg download.
13714 The cfg download must occur before we update the SME config
13715 since the SME config operation must access the cfg database */
Jeff Johnson295189b2012-06-20 16:38:30 -070013716 status = hdd_set_sme_config( pHddCtx );
13717
13718 if ( VOS_STATUS_SUCCESS != status )
13719 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -080013720 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Failed hdd_set_sme_config", __func__);
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053013721 goto err_vosclose;
Jeff Johnsonbc676b42013-02-14 16:04:08 -080013722 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013723
Jeff Johnson295189b2012-06-20 16:38:30 -070013724 /* In the integrated architecture we update the configuration from
13725 the INI file and from NV before vOSS has been started so that
13726 the final contents are available to send down to the cCPU */
13727
13728 // Apply the cfg.ini to cfg.dat
13729 if (FALSE == hdd_update_config_dat(pHddCtx))
13730 {
13731 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: config update failed",__func__ );
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053013732 goto err_vosclose;
Jeff Johnson295189b2012-06-20 16:38:30 -070013733 }
13734
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +053013735 // Get mac addr from platform driver
13736 ret = wcnss_get_wlan_mac_address((char*)&mac_addr.bytes);
13737
13738 if ((0 == ret) && (!vos_is_macaddr_zero(&mac_addr)))
Jeff Johnson295189b2012-06-20 16:38:30 -070013739 {
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +053013740 /* Store the mac addr for first interface */
13741 pHddCtx->cfg_ini->intfMacAddr[0] = mac_addr;
13742
13743 hddLog(VOS_TRACE_LEVEL_ERROR,
13744 "%s: WLAN Mac Addr: "
13745 MAC_ADDRESS_STR, __func__,
13746 MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[0].bytes));
13747
13748 /* Here, passing Arg2 as 1 because we do not want to change the
13749 last 3 bytes (means non OUI bytes) of first interface mac
13750 addr.
13751 */
13752 if (0 != hdd_generate_iface_mac_addr_auto(pHddCtx, 1, mac_addr))
13753 {
13754 hddLog(VOS_TRACE_LEVEL_ERROR,
13755 "%s: Failed to generate wlan interface mac addr "
13756 "using MAC from ini file ", __func__);
13757 }
13758 }
13759 else if (VOS_STATUS_SUCCESS != hdd_update_config_from_nv(pHddCtx))
13760 {
13761 // Apply the NV to cfg.dat
13762 /* Prima Update MAC address only at here */
Jeff Johnson295189b2012-06-20 16:38:30 -070013763#ifdef WLAN_AUTOGEN_MACADDR_FEATURE
13764 /* There was not a valid set of MAC Addresses in NV. See if the
13765 default addresses were modified by the cfg.ini settings. If so,
13766 we'll use them, but if not, we'll autogenerate a set of MAC
13767 addresses based upon the device serial number */
13768
13769 static const v_MACADDR_t default_address =
13770 {{0x00, 0x0A, 0xF5, 0x89, 0x89, 0xFF}};
Jeff Johnson295189b2012-06-20 16:38:30 -070013771
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +053013772 if (0 == memcmp(&default_address, &pHddCtx->cfg_ini->intfMacAddr[0],
13773 sizeof(default_address)))
Jeff Johnson295189b2012-06-20 16:38:30 -070013774 {
13775 /* cfg.ini has the default address, invoke autogen logic */
13776
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +053013777 /* Here, passing Arg2 as 0 because we want to change the
13778 last 3 bytes (means non OUI bytes) of all the interfaces
13779 mac addr.
13780 */
13781 if (0 != hdd_generate_iface_mac_addr_auto(pHddCtx, 0,
13782 default_address))
Jeff Johnson295189b2012-06-20 16:38:30 -070013783 {
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +053013784 hddLog(VOS_TRACE_LEVEL_ERROR,
13785 "%s: Failed to generate wlan interface mac addr "
13786 "using MAC from ini file " MAC_ADDRESS_STR, __func__,
13787 MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[0].bytes));
Jeff Johnson295189b2012-06-20 16:38:30 -070013788 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013789 }
13790 else
13791#endif //WLAN_AUTOGEN_MACADDR_FEATURE
13792 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -080013793 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070013794 "%s: Invalid MAC address in NV, using MAC from ini file "
13795 MAC_ADDRESS_STR, __func__,
13796 MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[0].bytes));
13797 }
13798 }
13799 {
13800 eHalStatus halStatus;
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +053013801
13802 /* Set the MAC Address Currently this is used by HAL to
13803 * add self sta. Remove this once self sta is added as
13804 * part of session open.
13805 */
Jeff Johnson295189b2012-06-20 16:38:30 -070013806 halStatus = cfgSetStr( pHddCtx->hHal, WNI_CFG_STA_ID,
13807 (v_U8_t *)&pHddCtx->cfg_ini->intfMacAddr[0],
13808 sizeof( pHddCtx->cfg_ini->intfMacAddr[0]) );
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +053013809
Jeff Johnson295189b2012-06-20 16:38:30 -070013810 if (!HAL_STATUS_SUCCESS( halStatus ))
13811 {
13812 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Failed to set MAC Address. "
13813 "HALStatus is %08d [x%08x]",__func__, halStatus, halStatus );
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053013814 goto err_vosclose;
Jeff Johnson295189b2012-06-20 16:38:30 -070013815 }
13816 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013817
13818 /*Start VOSS which starts up the SME/MAC/HAL modules and everything else
13819 Note: Firmware image will be read and downloaded inside vos_start API */
13820 status = vos_start( pHddCtx->pvosContext );
13821 if ( !VOS_IS_STATUS_SUCCESS( status ) )
13822 {
13823 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: vos_start failed",__func__);
Hanumantha Reddy Pothulabd9601a2016-02-12 13:22:27 +053013824 if (isSsrPanicOnFailure())
13825 VOS_BUG(0);
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053013826 goto err_vosclose;
Jeff Johnson295189b2012-06-20 16:38:30 -070013827 }
13828
Leo Chang6cec3e22014-01-21 15:33:49 -080013829#ifdef FEATURE_WLAN_CH_AVOID
13830 /* Plug in avoid channel notification callback
13831 * This should happen before ADD_SELF_STA
13832 * FW will send first IND with ADD_SELF_STA REQ from host */
Pradeep Reddy POTTETI5c2e16d2014-06-27 16:47:38 +053013833
13834 /* check the Channel Avoidance is enabled */
13835 if (TRUE == pHddCtx->cfg_ini->fenableCHAvoidance)
13836 {
13837 sme_AddChAvoidCallback(pHddCtx->hHal,
13838 hdd_hostapd_ch_avoid_cb);
13839 }
Leo Chang6cec3e22014-01-21 15:33:49 -080013840#endif /* FEATURE_WLAN_CH_AVOID */
13841
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -070013842 /* Exchange capability info between Host and FW and also get versioning info from FW */
13843 hdd_exchange_version_and_caps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -070013844
Agarwal Ashishad9281b2014-06-10 14:57:30 +053013845#ifdef CONFIG_ENABLE_LINUX_REG
13846 status = wlan_hdd_init_channels(pHddCtx);
13847 if ( !VOS_IS_STATUS_SUCCESS( status ) )
13848 {
13849 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: wlan_hdd_init_channels failed",
13850 __func__);
13851 goto err_vosstop;
13852 }
13853#endif
13854
Jeff Johnson295189b2012-06-20 16:38:30 -070013855 status = hdd_post_voss_start_config( pHddCtx );
13856 if ( !VOS_IS_STATUS_SUCCESS( status ) )
13857 {
13858 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hdd_post_voss_start_config failed",
13859 __func__);
13860 goto err_vosstop;
13861 }
Amar Singhala49cbc52013-10-08 18:37:44 -070013862
13863#ifndef CONFIG_ENABLE_LINUX_REG
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +053013864 wlan_hdd_cfg80211_update_reg_info( wiphy );
13865
13866 /* registration of wiphy dev with cfg80211 */
13867 if (0 > wlan_hdd_cfg80211_register(wiphy))
13868 {
13869 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy register failed", __func__);
13870 goto err_vosstop;
13871 }
Amar Singhala49cbc52013-10-08 18:37:44 -070013872#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070013873
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053013874#ifdef CONFIG_ENABLE_LINUX_REG
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053013875 /* registration of wiphy dev with cfg80211 */
13876 if (0 > wlan_hdd_cfg80211_register(wiphy))
13877 {
13878 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy register failed", __func__);
13879 goto err_vosstop;
13880 }
13881
Agarwal Ashish6db9d532014-09-30 18:19:10 +053013882 status = wlan_hdd_init_channels_for_cc(pHddCtx, INIT);
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053013883 if ( !VOS_IS_STATUS_SUCCESS( status ) )
13884 {
13885 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: wlan_hdd_init_channels_for_cc failed",
13886 __func__);
13887 goto err_unregister_wiphy;
13888 }
13889#endif
13890
c_hpothu4a298be2014-12-22 21:12:51 +053013891 wcnss_wlan_set_drvdata(pHddCtx->parent_dev, pHddCtx);
13892
Jeff Johnson295189b2012-06-20 16:38:30 -070013893 if (VOS_STA_SAP_MODE == hdd_get_conparam())
13894 {
13895 pAdapter = hdd_open_adapter( pHddCtx, WLAN_HDD_SOFTAP, "softap.%d",
13896 wlan_hdd_get_intf_addr(pHddCtx), FALSE );
13897 }
13898 else
13899 {
Jeff Johnson295189b2012-06-20 16:38:30 -070013900 pAdapter = hdd_open_adapter( pHddCtx, WLAN_HDD_INFRA_STATION, "wlan%d",
13901 wlan_hdd_get_intf_addr(pHddCtx), FALSE );
13902 if (pAdapter != NULL)
13903 {
Katya Nigama7d81d72014-11-12 12:44:34 +053013904 if (pHddCtx->cfg_ini->isP2pDeviceAddrAdministrated && !(pHddCtx->cfg_ini->intfMacAddr[0].bytes[0] & 0x02))
Jeff Johnson295189b2012-06-20 16:38:30 -070013905 {
Gopichand Nakkala49f96f62013-02-06 14:38:17 +053013906 vos_mem_copy( pHddCtx->p2pDeviceAddress.bytes,
13907 pHddCtx->cfg_ini->intfMacAddr[0].bytes,
13908 sizeof(tSirMacAddr));
Madan Mohan Koyyalamudiedfc1b72012-10-18 20:25:55 -070013909
Gopichand Nakkala49f96f62013-02-06 14:38:17 +053013910 /* Generate the P2P Device Address. This consists of the device's
13911 * primary MAC address with the locally administered bit set.
13912 */
13913 pHddCtx->p2pDeviceAddress.bytes[0] |= 0x02;
Jeff Johnsone7245742012-09-05 17:12:55 -070013914 }
13915 else
13916 {
Gopichand Nakkala49f96f62013-02-06 14:38:17 +053013917 tANI_U8* p2p_dev_addr = wlan_hdd_get_intf_addr(pHddCtx);
13918 if (p2p_dev_addr != NULL)
13919 {
13920 vos_mem_copy(&pHddCtx->p2pDeviceAddress.bytes[0],
13921 p2p_dev_addr, VOS_MAC_ADDR_SIZE);
13922 }
13923 else
13924 {
13925 hddLog(VOS_TRACE_LEVEL_FATAL,
13926 "%s: Failed to allocate mac_address for p2p_device",
13927 __func__);
13928 goto err_close_adapter;
13929 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013930 }
Jeff Johnsone7245742012-09-05 17:12:55 -070013931
13932 pP2pAdapter = hdd_open_adapter( pHddCtx, WLAN_HDD_P2P_DEVICE, "p2p%d",
13933 &pHddCtx->p2pDeviceAddress.bytes[0], FALSE );
13934 if ( NULL == pP2pAdapter )
13935 {
13936 hddLog(VOS_TRACE_LEVEL_FATAL,
13937 "%s: Failed to do hdd_open_adapter for P2P Device Interface",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070013938 __func__);
Jeff Johnsone7245742012-09-05 17:12:55 -070013939 goto err_close_adapter;
13940 }
Jeff Johnsone7245742012-09-05 17:12:55 -070013941 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013942 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013943
13944 if( pAdapter == NULL )
13945 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -080013946 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: hdd_open_adapter failed", __func__);
13947 goto err_close_adapter;
Jeff Johnson295189b2012-06-20 16:38:30 -070013948 }
Jeff Johnsone7245742012-09-05 17:12:55 -070013949
Arif Hussain66559122013-11-21 10:11:40 -080013950 if (country_code)
13951 {
13952 eHalStatus ret;
Arif Hussaincb607082013-12-20 11:57:42 -080013953 INIT_COMPLETION(pAdapter->change_country_code);
Arif Hussain66559122013-11-21 10:11:40 -080013954 hdd_checkandupdate_dfssetting(pAdapter, country_code);
13955#ifndef CONFIG_ENABLE_LINUX_REG
13956 hdd_checkandupdate_phymode(pAdapter, country_code);
13957#endif
Arif Hussaineaf68602013-12-30 23:10:44 -080013958 ret = sme_ChangeCountryCode(pHddCtx->hHal,
13959 (void *)(tSmeChangeCountryCallback)
13960 wlan_hdd_change_country_code_callback,
Arif Hussain66559122013-11-21 10:11:40 -080013961 country_code,
13962 pAdapter, pHddCtx->pvosContext,
Abhishek Singha306a442013-11-07 18:39:01 +053013963 eSIR_TRUE, eSIR_TRUE);
Arif Hussain66559122013-11-21 10:11:40 -080013964 if (eHAL_STATUS_SUCCESS == ret)
13965 {
Arif Hussaincb607082013-12-20 11:57:42 -080013966 ret = wait_for_completion_interruptible_timeout(
13967 &pAdapter->change_country_code,
13968 msecs_to_jiffies(WLAN_WAIT_TIME_COUNTRY));
13969
13970 if (0 >= ret)
13971 {
13972 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
13973 "%s: SME while setting country code timed out", __func__);
13974 }
Arif Hussain66559122013-11-21 10:11:40 -080013975 }
13976 else
13977 {
Arif Hussaincb607082013-12-20 11:57:42 -080013978 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
13979 "%s: SME Change Country code from module param fail ret=%d",
13980 __func__, ret);
Arif Hussain66559122013-11-21 10:11:40 -080013981 }
13982 }
13983
Jeff Johnson295189b2012-06-20 16:38:30 -070013984#ifdef WLAN_BTAMP_FEATURE
13985 vStatus = WLANBAP_Open(pVosContext);
13986 if(!VOS_IS_STATUS_SUCCESS(vStatus))
13987 {
13988 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
13989 "%s: Failed to open BAP",__func__);
Jeff Johnsone7245742012-09-05 17:12:55 -070013990 goto err_close_adapter;
Jeff Johnson295189b2012-06-20 16:38:30 -070013991 }
13992
13993 vStatus = BSL_Init(pVosContext);
13994 if(!VOS_IS_STATUS_SUCCESS(vStatus))
13995 {
13996 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
13997 "%s: Failed to Init BSL",__func__);
13998 goto err_bap_close;
13999 }
14000 vStatus = WLANBAP_Start(pVosContext);
14001 if (!VOS_IS_STATUS_SUCCESS(vStatus))
14002 {
14003 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
14004 "%s: Failed to start TL",__func__);
14005 goto err_bap_close;
14006 }
14007
14008 pConfig = pHddCtx->cfg_ini;
14009 btAmpConfig.ucPreferredChannel = pConfig->preferredChannel;
14010 status = WLANBAP_SetConfig(&btAmpConfig);
14011
14012#endif //WLAN_BTAMP_FEATURE
Jeff Johnsone7245742012-09-05 17:12:55 -070014013
Mihir Shete9c238772014-10-15 14:35:16 +053014014 /*
14015 * UapsdMask is 0xf if U-APSD is enbaled for all AC's...
14016 * The value of CFG_QOS_WMM_UAPSD_MASK_DEFAULT is 0xaa(Magic Value)
14017 * which is greater than 0xf. So the below check is safe to make
14018 * sure that there is no entry for UapsdMask in the ini
14019 */
14020 if (CFG_QOS_WMM_UAPSD_MASK_DEFAULT == pHddCtx->cfg_ini->UapsdMask)
14021 {
14022 if(IS_DYNAMIC_WMM_PS_ENABLED)
14023 {
14024 hddLog(VOS_TRACE_LEVEL_DEBUG,"%s: Enable UAPSD for VI & VO",
14025 __func__);
14026 pHddCtx->cfg_ini->UapsdMask =
14027 CFG_QOS_WMM_UAPSD_MASK_DYMANIC_WMM_PS_DEFAULT;
14028 }
14029 else
14030 {
14031 hddLog(VOS_TRACE_LEVEL_DEBUG,"%s: Do not enable UAPSD",
14032 __func__);
14033 pHddCtx->cfg_ini->UapsdMask =
14034 CFG_QOS_WMM_UAPSD_MASK_LEGACY_WMM_PS_DEFAULT;
14035 }
14036 }
14037
Varun Reddy Yeturud0a3f252013-04-15 21:58:13 -070014038#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
14039 if(!(IS_ROAM_SCAN_OFFLOAD_FEATURE_ENABLE))
14040 {
14041 hddLog(VOS_TRACE_LEVEL_DEBUG,"%s: ROAM_SCAN_OFFLOAD Feature not supported",__func__);
14042 pHddCtx->cfg_ini->isRoamOffloadScanEnabled = 0;
14043 sme_UpdateRoamScanOffloadEnabled((tHalHandle)(pHddCtx->hHal),
14044 pHddCtx->cfg_ini->isRoamOffloadScanEnabled);
14045 }
14046#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070014047
Agarwal Ashish4b87f922014-06-18 03:03:21 +053014048 wlan_hdd_tdls_init(pHddCtx);
14049
Masti, Narayanraddi26378462016-01-05 18:20:28 +053014050 wlan_hdd_init_deinit_defer_scan_context(&pHddCtx->scan_ctxt);
14051
14052 vos_init_delayed_work(&pHddCtx->scan_ctxt.scan_work,
14053 wlan_hdd_schedule_defer_scan);
14054
Mihir Shetefc7ff5b2014-01-27 11:30:05 +053014055 sme_Register11dScanDoneCallback(pHddCtx->hHal, hdd_11d_scan_done);
14056
Jeff Johnson295189b2012-06-20 16:38:30 -070014057 /* Register with platform driver as client for Suspend/Resume */
14058 status = hddRegisterPmOps(pHddCtx);
14059 if ( !VOS_IS_STATUS_SUCCESS( status ) )
14060 {
14061 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddRegisterPmOps failed",__func__);
14062#ifdef WLAN_BTAMP_FEATURE
14063 goto err_bap_stop;
14064#else
Jeff Johnsone7245742012-09-05 17:12:55 -070014065 goto err_close_adapter;
Jeff Johnson295189b2012-06-20 16:38:30 -070014066#endif //WLAN_BTAMP_FEATURE
14067 }
14068
Yue Ma0d4891e2013-08-06 17:01:45 -070014069 /* Open debugfs interface */
14070 if (VOS_STATUS_SUCCESS != hdd_debugfs_init(pAdapter))
14071 {
14072 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
14073 "%s: hdd_debugfs_init failed!", __func__);
Yue Ma0d4891e2013-08-06 17:01:45 -070014074 }
14075
Jeff Johnson295189b2012-06-20 16:38:30 -070014076 /* Register TM level change handler function to the platform */
14077 status = hddDevTmRegisterNotifyCallback(pHddCtx);
14078 if ( !VOS_IS_STATUS_SUCCESS( status ) )
14079 {
14080 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddDevTmRegisterNotifyCallback failed",__func__);
14081 goto err_unregister_pmops;
14082 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014083
Jeff Johnson295189b2012-06-20 16:38:30 -070014084 // register net device notifier for device change notification
14085 ret = register_netdevice_notifier(&hdd_netdev_notifier);
14086
14087 if(ret < 0)
14088 {
14089 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: register_netdevice_notifier failed",__func__);
Siddharth Bhalcd92b782015-06-29 12:25:40 +053014090 goto err_unregister_pmops;
Jeff Johnson295189b2012-06-20 16:38:30 -070014091 }
14092
Jeff Johnson295189b2012-06-20 16:38:30 -070014093 //Initialize the BTC service
14094 if(btc_activate_service(pHddCtx) != 0)
14095 {
14096 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: btc_activate_service failed",__func__);
Mahesh A Saptasagarc3ed0122016-01-19 16:45:11 +053014097 goto err_reg_netdev;
Jeff Johnson295189b2012-06-20 16:38:30 -070014098 }
14099
Padma, Santhosh Kumar2762e9d2015-10-20 15:02:57 +053014100#ifdef FEATURE_OEM_DATA_SUPPORT
14101 //Initialize the OEM service
14102 if (oem_activate_service(pHddCtx) != 0)
14103 {
14104 hddLog(VOS_TRACE_LEVEL_FATAL,
14105 "%s: oem_activate_service failed", __func__);
Hanumanth Reddy Pothula13789c42017-09-12 15:18:13 +053014106 goto err_btc_activate_service;
Padma, Santhosh Kumar2762e9d2015-10-20 15:02:57 +053014107 }
14108#endif
14109
Jeff Johnson295189b2012-06-20 16:38:30 -070014110#ifdef PTT_SOCK_SVC_ENABLE
14111 //Initialize the PTT service
14112 if(ptt_sock_activate_svc(pHddCtx) != 0)
14113 {
14114 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: ptt_sock_activate_svc failed",__func__);
Hanumanth Reddy Pothula13789c42017-09-12 15:18:13 +053014115 goto err_oem_activate_service;
Jeff Johnson295189b2012-06-20 16:38:30 -070014116 }
14117#endif
14118
Abhishek Singh00b71972016-01-07 10:51:04 +053014119#ifdef WLAN_FEATURE_RMC
14120 if (hdd_open_cesium_nl_sock() < 0)
14121 {
14122 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hdd_open_cesium_nl_sock failed", __func__);
Hanumanth Reddy Pothula13789c42017-09-12 15:18:13 +053014123 goto err_ptt_sock_activate_svc;
Abhishek Singh00b71972016-01-07 10:51:04 +053014124 }
14125#endif
14126
Vinay Krishna Erannad938c422014-03-10 17:14:21 +053014127#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
14128 if(pHddCtx->cfg_ini && pHddCtx->cfg_ini->wlanLoggingEnable)
14129 {
Deepthi Gowri78083a32014-11-04 12:55:51 +053014130 if(wlan_logging_sock_activate_svc(
14131 pHddCtx->cfg_ini->wlanLoggingFEToConsole,
Sushant Kaushik33200572015-08-05 16:46:20 +053014132 pHddCtx->cfg_ini->wlanLoggingNumBuf,
14133 pHddCtx->cfg_ini->wlanPerPktStatsLogEnable,
14134 pHddCtx->cfg_ini->wlanPerPktStatsNumBuf))
Deepthi Gowri78083a32014-11-04 12:55:51 +053014135 {
14136 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wlan_logging_sock_activate_svc"
14137 " failed", __func__);
Hanumanth Reddy Pothula13789c42017-09-12 15:18:13 +053014138 goto err_open_cesium_nl_sock;
Deepthi Gowri78083a32014-11-04 12:55:51 +053014139 }
14140 //TODO: To Remove enableDhcpDebug and use gEnableDebugLog for
14141 //EAPOL and DHCP
Sachin Ahuja8c65f382014-12-12 15:34:21 +053014142 if (!pHddCtx->cfg_ini->gEnableDebugLog)
14143 pHddCtx->cfg_ini->gEnableDebugLog =
Sushant Kaushik6e4e2bc2015-10-05 17:23:07 +053014144 VOS_PKT_PROTO_TYPE_EAPOL | VOS_PKT_PROTO_TYPE_DHCP |
14145 VOS_PKT_PROTO_TYPE_ARP;
Vinay Krishna Erannad938c422014-03-10 17:14:21 +053014146 }
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053014147
Siddharth Bhald1be97f2015-05-27 22:39:59 +053014148 if (pHddCtx->cfg_ini->wlanLoggingEnable &&
14149 (pHddCtx->cfg_ini->enableFWLogging ||
Siddharth Bhaldb963232015-06-25 19:34:35 +053014150 pHddCtx->cfg_ini->enableMgmtLogging ||
c_manjeecfd1efb2015-09-25 19:32:34 +053014151 pHddCtx->cfg_ini->enableContFWLogging ||
14152 pHddCtx->cfg_ini->enableFwrMemDump )
14153 )
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053014154 {
Siddharth Bhald1be97f2015-05-27 22:39:59 +053014155 hdd_init_frame_logging(pHddCtx);
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053014156 }
14157 else
14158 {
Siddharth Bhald1be97f2015-05-27 22:39:59 +053014159 hddLog(VOS_TRACE_LEVEL_INFO, FL("Logging disabled in ini"));
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053014160 }
14161
Vinay Krishna Erannad938c422014-03-10 17:14:21 +053014162#endif
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053014163
Agrawal Ashish17ef5082016-10-17 18:33:21 +053014164#ifdef SAP_AUTH_OFFLOAD
14165 if (!sme_IsFeatureSupportedByFW(SAP_OFFLOADS))
14166 {
14167 hddLog(VOS_TRACE_LEVEL_INFO, FL(" SAP AUTH OFFLOAD not supp by FW"));
14168 pHddCtx->cfg_ini->enable_sap_auth_offload = 0;
14169 }
14170#endif
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053014171
Sushant Kaushik215778f2015-05-21 14:05:36 +053014172 if (vos_is_multicast_logging())
14173 wlan_logging_set_log_level();
14174
Jeff Johnson295189b2012-06-20 16:38:30 -070014175 hdd_register_mcast_bcast_filter(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -070014176 if (VOS_STA_SAP_MODE != hdd_get_conparam())
Jeff Johnson295189b2012-06-20 16:38:30 -070014177 {
Madan Mohan Koyyalamudic537df22012-10-22 15:07:08 -070014178 /* Action frame registered in one adapter which will
14179 * applicable to all interfaces
14180 */
Agarwal Ashish8fa0e9a2014-05-23 00:40:12 +053014181 wlan_hdd_cfg80211_register_frames(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070014182 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014183
14184 mutex_init(&pHddCtx->sap_lock);
Mahesh A Saptasagar60627942014-10-13 13:55:14 +053014185 mutex_init(&pHddCtx->roc_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -070014186
Jeff Johnsone7245742012-09-05 17:12:55 -070014187#ifdef WLAN_FEATURE_HOLD_RX_WAKELOCK
14188 /* Initialize the wake lcok */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053014189 vos_wake_lock_init(&pHddCtx->rx_wake_lock,
Jeff Johnsone7245742012-09-05 17:12:55 -070014190 "qcom_rx_wakelock");
Sushant Kaushik83392fa2015-05-05 17:44:40 +053014191
Jeff Johnsone7245742012-09-05 17:12:55 -070014192#endif
Madan Mohan Koyyalamudi69fc3ad2012-11-28 16:04:56 -080014193 /* Initialize the wake lcok */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053014194 vos_wake_lock_init(&pHddCtx->sap_wake_lock,
Madan Mohan Koyyalamudi69fc3ad2012-11-28 16:04:56 -080014195 "qcom_sap_wakelock");
Sushant Kaushik83392fa2015-05-05 17:44:40 +053014196
Jeff Johnsone7245742012-09-05 17:12:55 -070014197
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070014198 vos_event_init(&pHddCtx->scan_info.scan_finished_event);
14199 pHddCtx->scan_info.scan_pending_option = WEXT_SCAN_PENDING_GIVEUP;
Jeff Johnson295189b2012-06-20 16:38:30 -070014200
Katya Nigam5c306ea2014-06-19 15:39:54 +053014201 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_NO_LOAD_UNLOAD_IN_PROGRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -070014202 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, FALSE);
Sushant Kaushik83392fa2015-05-05 17:44:40 +053014203 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_DRIVER_INIT);
Katya Nigam5c306ea2014-06-19 15:39:54 +053014204
14205#ifdef FEATURE_WLAN_SCAN_PNO
14206 /*SME must send channel update configuration to RIVA*/
14207 sme_UpdateChannelConfig(pHddCtx->hHal);
14208#endif
Abhishek Singhf644b272014-08-21 02:59:39 +053014209 /* Send the update default channel list to the FW*/
14210 sme_UpdateChannelList(pHddCtx->hHal);
Mukul Sharma45063942015-04-01 20:07:59 +053014211
14212 /* Fwr capabilities received, Set the Dot11 mode */
Abhishek Singh41ebce12016-02-03 10:43:21 +053014213 sme_SetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter),
14214 hdd_cfg_xlate_to_csr_phy_mode(pHddCtx->cfg_ini->dot11Mode));
Mukul Sharma45063942015-04-01 20:07:59 +053014215 sme_SetDefDot11Mode(pHddCtx->hHal);
14216
Abhishek Singha306a442013-11-07 18:39:01 +053014217#ifndef CONFIG_ENABLE_LINUX_REG
14218 /*updating wiphy so that regulatory user hints can be processed*/
14219 if (wiphy)
14220 {
14221 regulatory_hint(wiphy, "00");
14222 }
14223#endif
Jeff Johnsone7245742012-09-05 17:12:55 -070014224 // Initialize the restart logic
14225 wlan_hdd_restart_init(pHddCtx);
Chilam NG571c65a2013-01-19 12:27:36 +053014226
Hanumanth Reddy Pothula146bca42016-11-08 12:01:07 +053014227 if (pHddCtx->cfg_ini->fIsLogpEnabled) {
14228 vos_wdthread_init_timer_work(vos_process_wd_timer);
14229 /* Initialize the timer to detect thread stuck issues */
14230 vos_thread_stuck_timer_init(
14231 &((VosContextType*)pVosContext)->vosWatchdog);
14232 }
14233
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -070014234 //Register the traffic monitor timer now
14235 if ( pHddCtx->cfg_ini->dynSplitscan)
14236 {
14237 vos_timer_init(&pHddCtx->tx_rx_trafficTmr,
14238 VOS_TIMER_TYPE_SW,
14239 hdd_tx_rx_pkt_cnt_stat_timer_handler,
14240 (void *)pHddCtx);
14241 }
Srinivas Dasari030bad32015-02-18 23:23:54 +053014242 wlan_hdd_cfg80211_nan_init(pHddCtx);
14243
Bhargav Shahd0715912015-10-01 18:17:37 +053014244 mutex_init(&pHddCtx->cur_rx_level_lock);
14245 vos_timer_init(&pHddCtx->delack_timer, VOS_TIMER_TYPE_SW,
14246 hdd_tcp_delack_compute_function,(void *)pHddCtx);
Masti, Narayanraddi44b0db02015-12-22 11:54:35 +053014247 vos_timer_init(&pHddCtx->tdls_source_timer, VOS_TIMER_TYPE_SW,
14248 wlan_hdd_change_tdls_mode, (void *)pHddCtx);
Bhargav Shahd0715912015-10-01 18:17:37 +053014249
Dino Mycle6fb96c12014-06-10 11:52:40 +053014250#ifdef WLAN_FEATURE_EXTSCAN
14251 sme_EXTScanRegisterCallback(pHddCtx->hHal,
14252 wlan_hdd_cfg80211_extscan_callback,
14253 pHddCtx);
14254#endif /* WLAN_FEATURE_EXTSCAN */
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +053014255
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053014256#ifdef FEATURE_OEM_DATA_SUPPORT
14257 sme_OemDataRegisterCallback(pHddCtx->hHal,
14258 wlan_hdd_cfg80211_oemdata_callback,
14259 pHddCtx);
14260#endif /* FEATURE_OEM_DATA_SUPPORT */
14261
Gupta, Kapil7c34b322015-09-30 13:12:35 +053014262 sme_set_rssi_threshold_breached_cb(pHddCtx->hHal, hdd_rssi_threshold_breached_cb);
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +053014263#ifdef WLAN_NS_OFFLOAD
14264 // Register IPv6 notifier to notify if any change in IP
14265 // So that we can reconfigure the offload parameters
14266 pHddCtx->ipv6_notifier.notifier_call = wlan_hdd_ipv6_changed;
14267 ret = register_inet6addr_notifier(&pHddCtx->ipv6_notifier);
14268 if (ret)
14269 {
Ratheesh S P36dbc932015-08-07 14:28:57 +053014270 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to register IPv6 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 IPv6 notifier"));
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +053014275 }
14276#endif
14277
Sravan Kumar Kairamb0edc612016-10-26 13:55:24 +053014278 vos_mem_set((uint8_t *)&pHddCtx->bad_sta, HDD_MAX_STA_COUNT, 0);
14279
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +053014280 // Register IPv4 notifier to notify if any change in IP
14281 // So that we can reconfigure the offload parameters
14282 pHddCtx->ipv4_notifier.notifier_call = wlan_hdd_ipv4_changed;
14283 ret = register_inetaddr_notifier(&pHddCtx->ipv4_notifier);
14284 if (ret)
14285 {
Ratheesh S P36dbc932015-08-07 14:28:57 +053014286 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to register IPv4 notifier"));
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +053014287 }
14288 else
14289 {
Ratheesh S P36dbc932015-08-07 14:28:57 +053014290 hddLog(VOS_TRACE_LEVEL_INFO, FL("Registered IPv4 notifier"));
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +053014291 }
c_manjeecfd1efb2015-09-25 19:32:34 +053014292 /*Fw mem dump procfs initialization*/
14293 memdump_init();
Bhargav shah23c94942015-10-13 12:48:35 +053014294 hdd_dp_util_send_rps_ind(pHddCtx);
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +053014295
Nishank Aggarwalc11826c2016-12-15 18:54:10 +053014296 pHddCtx->is_ap_mode_wow_supported =
14297 sme_IsFeatureSupportedByFW(SAP_MODE_WOW);
Sravan Kumar Kairam091e5b62017-01-23 14:14:20 +053014298
Hanumanth Reddy Pothulae92bcc12017-05-19 13:56:35 +053014299 pHddCtx->is_fatal_event_log_sup =
14300 sme_IsFeatureSupportedByFW(FATAL_EVENT_LOGGING);
14301 hddLog(VOS_TRACE_LEVEL_INFO, FL("FATAL_EVENT_LOGGING: %d"),
14302 pHddCtx->is_fatal_event_log_sup);
14303
Sravan Kumar Kairam091e5b62017-01-23 14:14:20 +053014304 hdd_assoc_registerFwdEapolCB(pVosContext);
14305
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +053014306 mutex_init(&pHddCtx->cache_channel_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -070014307 goto success;
14308
Hanumanth Reddy Pothula13789c42017-09-12 15:18:13 +053014309err_open_cesium_nl_sock:
14310#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
14311 hdd_close_cesium_nl_sock();
14312#endif
14313
14314err_ptt_sock_activate_svc:
14315#ifdef PTT_SOCK_SVC_ENABLE
14316 ptt_sock_deactivate_svc(pHddCtx);
14317#endif
14318
14319err_oem_activate_service:
14320#ifdef FEATURE_OEM_DATA_SUPPORT
14321 oem_deactivate_service();
14322#endif
14323
14324err_btc_activate_service:
14325 btc_deactivate_service();
14326
Jeff Johnson295189b2012-06-20 16:38:30 -070014327err_reg_netdev:
14328 unregister_netdevice_notifier(&hdd_netdev_notifier);
14329
Jeff Johnson295189b2012-06-20 16:38:30 -070014330err_unregister_pmops:
14331 hddDevTmUnregisterNotifyCallback(pHddCtx);
14332 hddDeregisterPmOps(pHddCtx);
14333
Yue Ma0d4891e2013-08-06 17:01:45 -070014334 hdd_debugfs_exit(pHddCtx);
14335
Jeff Johnson295189b2012-06-20 16:38:30 -070014336#ifdef WLAN_BTAMP_FEATURE
14337err_bap_stop:
14338 WLANBAP_Stop(pVosContext);
14339#endif
14340
14341#ifdef WLAN_BTAMP_FEATURE
14342err_bap_close:
14343 WLANBAP_Close(pVosContext);
14344#endif
14345
Jeff Johnson295189b2012-06-20 16:38:30 -070014346err_close_adapter:
14347 hdd_close_all_adapters( pHddCtx );
Mahesh A Saptasagar9ecefe42014-07-15 18:43:49 +053014348#ifdef CONFIG_ENABLE_LINUX_REG
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053014349err_unregister_wiphy:
Mahesh A Saptasagar9ecefe42014-07-15 18:43:49 +053014350#endif
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +053014351 wiphy_unregister(wiphy) ;
Agrawal Ashish33ec71e2015-11-26 20:20:58 +053014352 hdd_wlan_free_wiphy_channels(wiphy);
14353
Jeff Johnson295189b2012-06-20 16:38:30 -070014354err_vosstop:
14355 vos_stop(pVosContext);
14356
Amar Singhala49cbc52013-10-08 18:37:44 -070014357err_vosclose:
Jeff Johnson295189b2012-06-20 16:38:30 -070014358 status = vos_sched_close( pVosContext );
14359 if (!VOS_IS_STATUS_SUCCESS(status)) {
14360 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
14361 "%s: Failed to close VOSS Scheduler", __func__);
14362 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( status ) );
14363 }
Amar Singhala49cbc52013-10-08 18:37:44 -070014364 vos_close(pVosContext );
14365
Mahesh A Saptasagarc3ed0122016-01-19 16:45:11 +053014366err_nl_srv:
14367#ifdef WLAN_KD_READY_NOTIFIER
14368 nl_srv_exit(pHddCtx->ptt_pid);
14369#else
14370 nl_srv_exit();
14371#endif /* WLAN_KD_READY_NOTIFIER */
Amar Singhal0a402232013-10-11 20:57:16 -070014372err_vos_nv_close:
14373
c_hpothue6a36282014-03-19 12:27:38 +053014374#ifdef CONFIG_ENABLE_LINUX_REG
Amar Singhal0a402232013-10-11 20:57:16 -070014375 vos_nv_close();
14376
c_hpothu70f8d812014-03-22 22:59:23 +053014377#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070014378
14379err_wdclose:
14380 if(pHddCtx->cfg_ini->fIsLogpEnabled)
14381 vos_watchdog_close(pVosContext);
14382
Jeff Johnson295189b2012-06-20 16:38:30 -070014383err_config:
Hanumanth Reddy Pothula1efcd162018-03-14 14:32:27 +053014384 hdd_request_manager_deinit();
Jeff Johnson295189b2012-06-20 16:38:30 -070014385 kfree(pHddCtx->cfg_ini);
14386 pHddCtx->cfg_ini= NULL;
14387
14388err_free_hdd_context:
Sushant Kaushik83392fa2015-05-05 17:44:40 +053014389 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_DRIVER_INIT);
Siddharth Bhalcd92b782015-06-29 12:25:40 +053014390 free_riva_power_on_lock("wlan");
Jeff Johnson295189b2012-06-20 16:38:30 -070014391 wiphy_free(wiphy) ;
14392 //kfree(wdev) ;
Jeff Johnson295189b2012-06-20 16:38:30 -070014393 VOS_BUG(1);
14394
Madan Mohan Koyyalamudid57ae632012-11-06 18:42:48 -080014395 if (hdd_is_ssr_required())
14396 {
14397 /* WDI timeout had happened during load, so SSR is needed here */
14398 subsystem_restart("wcnss");
14399 msleep(5000);
14400 }
14401 hdd_set_ssr_required (VOS_FALSE);
14402
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -080014403 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -070014404
14405success:
14406 EXIT();
14407 return 0;
14408}
14409
14410/**---------------------------------------------------------------------------
14411
Jeff Johnson32d95a32012-09-10 13:15:23 -070014412 \brief hdd_driver_init() - Core Driver Init Function
Jeff Johnson295189b2012-06-20 16:38:30 -070014413
Jeff Johnson32d95a32012-09-10 13:15:23 -070014414 This is the driver entry point - called in different timeline depending
14415 on whether the driver is statically or dynamically linked
Jeff Johnson295189b2012-06-20 16:38:30 -070014416
14417 \param - None
14418
14419 \return - 0 for success, non zero for failure
14420
14421 --------------------------------------------------------------------------*/
Jeff Johnson32d95a32012-09-10 13:15:23 -070014422static int hdd_driver_init( void)
Jeff Johnson295189b2012-06-20 16:38:30 -070014423{
14424 VOS_STATUS status;
14425 v_CONTEXT_t pVosContext = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070014426 struct device *dev = NULL;
14427 int ret_status = 0;
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -070014428#ifdef HAVE_WCNSS_CAL_DOWNLOAD
14429 int max_retries = 0;
14430#endif
Siddharth Bhalc7e79b62014-10-10 22:37:38 +053014431#ifdef HAVE_CBC_DONE
14432 int max_cbc_retries = 0;
14433#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070014434
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +053014435#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
14436 wlan_logging_sock_init_svc();
14437#endif
14438
Jeff Johnson295189b2012-06-20 16:38:30 -070014439 ENTER();
14440
Sushant Kaushik83392fa2015-05-05 17:44:40 +053014441 vos_wake_lock_init(&wlan_wake_lock, "wlan");
Jeff Johnson295189b2012-06-20 16:38:30 -070014442
14443 pr_info("%s: loading driver v%s\n", WLAN_MODULE_NAME,
14444 QWLAN_VERSIONSTR TIMER_MANAGER_STR MEMORY_DEBUG_STR);
14445
Jeff Johnson295189b2012-06-20 16:38:30 -070014446#ifdef ANI_BUS_TYPE_PCI
14447
14448 dev = wcnss_wlan_get_device();
14449
14450#endif // ANI_BUS_TYPE_PCI
14451
14452#ifdef ANI_BUS_TYPE_PLATFORM
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -070014453
14454#ifdef HAVE_WCNSS_CAL_DOWNLOAD
14455 /* wait until WCNSS driver downloads NV */
Ravi Kumar Bokka7a139e62016-11-17 21:32:55 +053014456 while (!wcnss_device_ready() && 10 >= ++max_retries) {
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -070014457 msleep(1000);
14458 }
Siddharth Bhalc7e79b62014-10-10 22:37:38 +053014459
Ravi Kumar Bokka7a139e62016-11-17 21:32:55 +053014460 if (max_retries >= 10) {
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -070014461 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: WCNSS driver not ready", __func__);
Sushant Kaushik83392fa2015-05-05 17:44:40 +053014462 vos_wake_lock_destroy(&wlan_wake_lock);
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +053014463#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
14464 wlan_logging_sock_deinit_svc();
14465#endif
14466
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -070014467 return -ENODEV;
14468 }
14469#endif
14470
Siddharth Bhalc7e79b62014-10-10 22:37:38 +053014471#ifdef HAVE_CBC_DONE
14472 while (!wcnss_cbc_complete() && 10 >= ++max_cbc_retries) {
14473 msleep(1000);
14474 }
14475 if (max_cbc_retries >= 10) {
14476 hddLog(VOS_TRACE_LEVEL_FATAL, "%s:CBC not completed", __func__);
14477 }
14478#endif
14479
Jeff Johnson295189b2012-06-20 16:38:30 -070014480 dev = wcnss_wlan_get_device();
14481#endif // ANI_BUS_TYPE_PLATFORM
14482
14483
14484 do {
14485 if (NULL == dev) {
14486 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: WLAN device not found!!",__func__);
14487 ret_status = -1;
14488 break;
14489 }
14490
Jeff Johnson295189b2012-06-20 16:38:30 -070014491#ifdef TIMER_MANAGER
14492 vos_timer_manager_init();
14493#endif
14494
14495 /* Preopen VOSS so that it is ready to start at least SAL */
14496 status = vos_preOpen(&pVosContext);
14497
14498 if (!VOS_IS_STATUS_SUCCESS(status))
14499 {
14500 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Failed to preOpen VOSS", __func__);
14501 ret_status = -1;
14502 break;
14503 }
14504
Sushant Kaushik02beb352015-06-04 15:15:01 +053014505 hddTraceInit();
Padma, Santhosh Kumar9093b202015-07-21 15:37:38 +053014506 hdd_register_debug_callback();
14507
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070014508#ifndef MODULE
14509 /* For statically linked driver, call hdd_set_conparam to update curr_con_mode
14510 */
14511 hdd_set_conparam((v_UINT_t)con_mode);
14512#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070014513
14514 // Call our main init function
Jeff Johnsonbc676b42013-02-14 16:04:08 -080014515 if (hdd_wlan_startup(dev))
14516 {
Jeff Johnson295189b2012-06-20 16:38:30 -070014517 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: WLAN Driver Initialization failed",
Jeff Johnsonbc676b42013-02-14 16:04:08 -080014518 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070014519 vos_preClose( &pVosContext );
14520 ret_status = -1;
14521 break;
14522 }
14523
Jeff Johnson295189b2012-06-20 16:38:30 -070014524 } while (0);
14525
14526 if (0 != ret_status)
14527 {
Jeff Johnson295189b2012-06-20 16:38:30 -070014528#ifdef TIMER_MANAGER
14529 vos_timer_exit();
14530#endif
14531#ifdef MEMORY_DEBUG
14532 vos_mem_exit();
14533#endif
Sushant Kaushik83392fa2015-05-05 17:44:40 +053014534 vos_wake_lock_destroy(&wlan_wake_lock);
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +053014535#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
14536 wlan_logging_sock_deinit_svc();
14537#endif
14538
Jeff Johnson295189b2012-06-20 16:38:30 -070014539 pr_err("%s: driver load failure\n", WLAN_MODULE_NAME);
14540 }
14541 else
14542 {
14543 //Send WLAN UP indication to Nlink Service
14544 send_btc_nlink_msg(WLAN_MODULE_UP_IND, 0);
14545
14546 pr_info("%s: driver loaded\n", WLAN_MODULE_NAME);
Jeff Johnson295189b2012-06-20 16:38:30 -070014547 }
14548
14549 EXIT();
14550
14551 return ret_status;
14552}
14553
Jeff Johnson32d95a32012-09-10 13:15:23 -070014554/**---------------------------------------------------------------------------
14555
14556 \brief hdd_module_init() - Init Function
14557
14558 This is the driver entry point (invoked when module is loaded using insmod)
14559
14560 \param - None
14561
14562 \return - 0 for success, non zero for failure
14563
14564 --------------------------------------------------------------------------*/
14565#ifdef MODULE
14566static int __init hdd_module_init ( void)
14567{
14568 return hdd_driver_init();
14569}
Jeff Johnson32d95a32012-09-10 13:15:23 -070014570#else /* #ifdef MODULE */
14571static int __init hdd_module_init ( void)
14572{
14573 /* Driver initialization is delayed to fwpath_changed_handler */
14574 return 0;
14575}
Jeff Johnson32d95a32012-09-10 13:15:23 -070014576#endif /* #ifdef MODULE */
14577
Jeff Johnson295189b2012-06-20 16:38:30 -070014578
14579/**---------------------------------------------------------------------------
14580
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070014581 \brief hdd_driver_exit() - Exit function
Jeff Johnson295189b2012-06-20 16:38:30 -070014582
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070014583 This is the driver exit point (invoked when module is unloaded using rmmod
14584 or con_mode was changed by userspace)
Jeff Johnson295189b2012-06-20 16:38:30 -070014585
14586 \param - None
14587
14588 \return - None
14589
14590 --------------------------------------------------------------------------*/
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070014591static void hdd_driver_exit(void)
Jeff Johnson295189b2012-06-20 16:38:30 -070014592{
14593 hdd_context_t *pHddCtx = NULL;
14594 v_CONTEXT_t pVosContext = NULL;
Agarwal Ashish5e414792014-06-08 15:25:23 +053014595 v_REGDOMAIN_t regId;
Arun Kumar Khandavallie0b046d2014-03-01 21:54:25 +053014596 unsigned long rc = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070014597
14598 pr_info("%s: unloading driver v%s\n", WLAN_MODULE_NAME, QWLAN_VERSIONSTR);
14599
14600 //Get the global vos context
14601 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
14602
14603 if(!pVosContext)
14604 {
14605 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Global VOS context is Null", __func__);
14606 goto done;
14607 }
14608
14609 //Get the HDD context.
14610 pHddCtx = (hdd_context_t *)vos_get_context(VOS_MODULE_ID_HDD, pVosContext );
14611
14612 if(!pHddCtx)
14613 {
14614 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: module exit called before probe",__func__);
14615 }
Katya Nigame7b69a82015-04-28 15:24:06 +053014616 else if (VOS_MONITOR_MODE == hdd_get_conparam())
14617 {
14618 hddLog(VOS_TRACE_LEVEL_INFO,"%s: MONITOR MODE",__func__);
14619 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_UNLOAD_IN_PROGRESS;
14620 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, TRUE);
14621 hdd_wlan_exit(pHddCtx);
14622 vos_preClose( &pVosContext );
14623 goto done;
14624 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014625 else
14626 {
Siddharth Bhal2e5871b2015-03-24 16:20:51 +053014627 /* We wait for active entry threads to exit from driver
14628 * by waiting until rtnl_lock is available.
14629 */
14630 rtnl_lock();
14631 rtnl_unlock();
14632
Siddharth Bhal3c29dca2015-02-19 00:41:40 +053014633 INIT_COMPLETION(pHddCtx->ssr_comp_var);
14634 if ((pHddCtx->isLogpInProgress) && (FALSE ==
14635 vos_is_wlan_in_badState(VOS_MODULE_ID_HDD, NULL)))
14636 {
Siddharth Bhala204f572015-01-17 02:03:36 +053014637 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Siddharth Bhal3c29dca2015-02-19 00:41:40 +053014638 "%s:SSR in Progress; block rmmod !!!", __func__);
Siddharth Bhala204f572015-01-17 02:03:36 +053014639 rc = wait_for_completion_timeout(&pHddCtx->ssr_comp_var,
14640 msecs_to_jiffies(30000));
14641 if(!rc)
14642 {
14643 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
14644 "%s:SSR timedout, fatal error", __func__);
14645 VOS_BUG(0);
14646 }
14647 }
14648
Siddharth Bhal3c29dca2015-02-19 00:41:40 +053014649 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_UNLOAD_IN_PROGRESS;
14650 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, TRUE);
Jeff Johnson295189b2012-06-20 16:38:30 -070014651
c_hpothu8adb97b2014-12-08 19:38:20 +053014652 /* Driver Need to send country code 00 in below condition
14653 * 1) If gCountryCodePriority is set to 1; and last country
14654 * code set is through 11d. This needs to be done in case
14655 * when NV country code is 00.
14656 * This Needs to be done as when kernel store last country
14657 * code and if stored country code is not through 11d,
14658 * in sme_HandleChangeCountryCodeByUser we will disable 11d
14659 * in next load/unload as soon as we get any country through
14660 * 11d. In sme_HandleChangeCountryCodeByUser
14661 * pMsg->countryCode will be last countryCode and
14662 * pMac->scan.countryCode11d will be country through 11d so
14663 * due to mismatch driver will disable 11d.
14664 *
14665 */
Agarwal Ashish8db39882014-07-30 21:56:07 +053014666
c_hpothu8adb97b2014-12-08 19:38:20 +053014667 if ((eANI_BOOLEAN_TRUE == sme_Is11dCountrycode(pHddCtx->hHal) &&
Agarwal Ashish8dcd2862014-07-25 11:58:52 +053014668 pHddCtx->cfg_ini->fSupplicantCountryCodeHasPriority &&
Abhishek Singh2a705962014-10-30 14:47:28 +053014669 sme_Is11dSupported(pHddCtx->hHal)))
c_hpothu8adb97b2014-12-08 19:38:20 +053014670 {
14671 hddLog(VOS_TRACE_LEVEL_INFO,
Agarwal Ashish8dcd2862014-07-25 11:58:52 +053014672 FL("CountryCode 00 is being set while unloading driver"));
c_hpothu8adb97b2014-12-08 19:38:20 +053014673 vos_nv_getRegDomainFromCountryCode(&regId , "00", COUNTRY_USER);
14674 }
Agarwal Ashish5e414792014-06-08 15:25:23 +053014675
c_hpothu8adb97b2014-12-08 19:38:20 +053014676 //Do all the cleanup before deregistering the driver
14677 hdd_wlan_exit(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -070014678 }
14679
Jeff Johnson295189b2012-06-20 16:38:30 -070014680 vos_preClose( &pVosContext );
14681
14682#ifdef TIMER_MANAGER
14683 vos_timer_exit();
14684#endif
14685#ifdef MEMORY_DEBUG
14686 vos_mem_exit();
14687#endif
14688
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +053014689#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
14690 wlan_logging_sock_deinit_svc();
14691#endif
14692
Jeff Johnson295189b2012-06-20 16:38:30 -070014693done:
Sushant Kaushik83392fa2015-05-05 17:44:40 +053014694 vos_wake_lock_destroy(&wlan_wake_lock);
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +053014695
Jeff Johnson295189b2012-06-20 16:38:30 -070014696 pr_info("%s: driver unloaded\n", WLAN_MODULE_NAME);
14697}
14698
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070014699/**---------------------------------------------------------------------------
14700
14701 \brief hdd_module_exit() - Exit function
14702
14703 This is the driver exit point (invoked when module is unloaded using rmmod)
14704
14705 \param - None
14706
14707 \return - None
14708
14709 --------------------------------------------------------------------------*/
14710static void __exit hdd_module_exit(void)
14711{
14712 hdd_driver_exit();
14713}
14714
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070014715#ifdef MODULE
14716static int fwpath_changed_handler(const char *kmessage,
Ashish Kumar Dhanotiyafb3fd972018-04-30 12:46:52 +053014717 const struct kernel_param *kp)
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070014718{
Jeff Johnson76052702013-04-16 13:55:05 -070014719 return param_set_copystring(kmessage, kp);
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070014720}
14721
14722static int con_mode_handler(const char *kmessage,
Ashish Kumar Dhanotiyafb3fd972018-04-30 12:46:52 +053014723 const struct kernel_param *kp)
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070014724{
Madan Mohan Koyyalamudif2f8d8b2012-10-11 17:06:59 -070014725 return param_set_int(kmessage, kp);
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070014726}
14727#else /* #ifdef MODULE */
14728/**---------------------------------------------------------------------------
14729
Jeff Johnson76052702013-04-16 13:55:05 -070014730 \brief kickstart_driver
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070014731
Jeff Johnson76052702013-04-16 13:55:05 -070014732 This is the driver entry point
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070014733 - delayed driver initialization when driver is statically linked
Jeff Johnson76052702013-04-16 13:55:05 -070014734 - invoked when module parameter fwpath is modified from userspace to signal
14735 initializing the WLAN driver or when con_mode is modified from userspace
14736 to signal a switch in operating mode
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070014737
14738 \return - 0 for success, non zero for failure
14739
14740 --------------------------------------------------------------------------*/
Jeff Johnson76052702013-04-16 13:55:05 -070014741static int kickstart_driver(void)
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070014742{
Madan Mohan Koyyalamudi62e60052012-10-05 14:27:22 -070014743 int ret_status;
14744
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070014745 if (!wlan_hdd_inited) {
Madan Mohan Koyyalamudi62e60052012-10-05 14:27:22 -070014746 ret_status = hdd_driver_init();
14747 wlan_hdd_inited = ret_status ? 0 : 1;
14748 return ret_status;
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070014749 }
14750
14751 hdd_driver_exit();
Jeff Johnson76052702013-04-16 13:55:05 -070014752
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070014753 msleep(200);
Jeff Johnson76052702013-04-16 13:55:05 -070014754
Madan Mohan Koyyalamudi62e60052012-10-05 14:27:22 -070014755 ret_status = hdd_driver_init();
14756 wlan_hdd_inited = ret_status ? 0 : 1;
14757 return ret_status;
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070014758}
14759
Jeff Johnson295189b2012-06-20 16:38:30 -070014760/**---------------------------------------------------------------------------
14761
Jeff Johnson76052702013-04-16 13:55:05 -070014762 \brief fwpath_changed_handler() - Handler Function
14763
14764 Handle changes to the fwpath parameter
14765
14766 \return - 0 for success, non zero for failure
14767
14768 --------------------------------------------------------------------------*/
14769static int fwpath_changed_handler(const char *kmessage,
Ashish Kumar Dhanotiyafb3fd972018-04-30 12:46:52 +053014770 const struct kernel_param *kp)
Jeff Johnson76052702013-04-16 13:55:05 -070014771{
14772 int ret;
14773
14774 ret = param_set_copystring(kmessage, kp);
14775 if (0 == ret)
14776 ret = kickstart_driver();
14777 return ret;
14778}
14779
14780/**---------------------------------------------------------------------------
14781
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070014782 \brief con_mode_handler() -
14783
14784 Handler function for module param con_mode when it is changed by userspace
14785 Dynamically linked - do nothing
14786 Statically linked - exit and init driver, as in rmmod and insmod
14787
Jeff Johnson76052702013-04-16 13:55:05 -070014788 \param -
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070014789
Jeff Johnson76052702013-04-16 13:55:05 -070014790 \return -
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070014791
14792 --------------------------------------------------------------------------*/
Ashish Kumar Dhanotiyafb3fd972018-04-30 12:46:52 +053014793static int con_mode_handler(const char *kmessage,
14794 const struct kernel_param *kp)
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070014795{
Jeff Johnson76052702013-04-16 13:55:05 -070014796 int ret;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070014797
Jeff Johnson76052702013-04-16 13:55:05 -070014798 ret = param_set_int(kmessage, kp);
14799 if (0 == ret)
14800 ret = kickstart_driver();
14801 return ret;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070014802}
14803#endif /* #ifdef MODULE */
14804
14805/**---------------------------------------------------------------------------
14806
Jeff Johnson295189b2012-06-20 16:38:30 -070014807 \brief hdd_get_conparam() -
14808
14809 This is the driver exit point (invoked when module is unloaded using rmmod)
14810
14811 \param - None
14812
14813 \return - tVOS_CON_MODE
14814
14815 --------------------------------------------------------------------------*/
14816tVOS_CON_MODE hdd_get_conparam ( void )
14817{
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070014818#ifdef MODULE
Jeff Johnson295189b2012-06-20 16:38:30 -070014819 return (tVOS_CON_MODE)con_mode;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070014820#else
14821 return (tVOS_CON_MODE)curr_con_mode;
14822#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070014823}
14824void hdd_set_conparam ( v_UINT_t newParam )
14825{
14826 con_mode = newParam;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070014827#ifndef MODULE
14828 curr_con_mode = con_mode;
14829#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070014830}
14831/**---------------------------------------------------------------------------
14832
14833 \brief hdd_softap_sta_deauth() - function
14834
14835 This to take counter measure to handle deauth req from HDD
14836
14837 \param - pAdapter - Pointer to the HDD
14838
14839 \param - enable - boolean value
14840
14841 \return - None
14842
14843 --------------------------------------------------------------------------*/
14844
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053014845VOS_STATUS hdd_softap_sta_deauth(hdd_adapter_t *pAdapter,
14846 struct tagCsrDelStaParams *pDelStaParams)
Jeff Johnson295189b2012-06-20 16:38:30 -070014847{
Jeff Johnson295189b2012-06-20 16:38:30 -070014848 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080014849 VOS_STATUS vosStatus = VOS_STATUS_E_FAULT;
Hanumanth Reddy Pothula57323632017-12-06 17:55:09 +053014850 struct hdd_cache_sta_info *cache_sta_info;
14851 ptSapContext pSapCtx = VOS_GET_SAP_CB(pVosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -070014852
14853 ENTER();
14854
Jeff Johnsonc135a9a2017-09-19 08:37:24 -070014855 hddLog(LOG1, "hdd_softap_sta_deauth:(%pK, false)",
Rajesh Chauhan18488fc2013-08-22 10:15:03 -070014856 (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -070014857
Hanumanth Reddy Pothula57323632017-12-06 17:55:09 +053014858 if (!pSapCtx) {
14859 hddLog(LOGE, "sap context is NULL");
14860 return vosStatus;
14861 }
14862
14863 cache_sta_info = hdd_get_cache_stainfo(pSapCtx->cache_sta_info,
14864 pDelStaParams->peerMacAddr);
14865 if (cache_sta_info) {
14866 cache_sta_info->reason_code = pDelStaParams->reason_code;
14867 cache_sta_info->rx_rate =
14868 wlan_tl_get_sta_rx_rate(pVosContext, cache_sta_info->ucSTAId);
14869 WLANTL_GetSAPStaRSSi(pVosContext, cache_sta_info->ucSTAId,
14870 &cache_sta_info->rssi);
14871 }
14872
Jeff Johnson295189b2012-06-20 16:38:30 -070014873 //Ignore request to deauth bcmc station
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053014874 if (pDelStaParams->peerMacAddr[0] & 0x1)
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080014875 return vosStatus;
Jeff Johnson295189b2012-06-20 16:38:30 -070014876
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053014877 vosStatus = WLANSAP_DeauthSta(pVosContext, pDelStaParams);
Jeff Johnson295189b2012-06-20 16:38:30 -070014878
14879 EXIT();
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080014880 return vosStatus;
Jeff Johnson295189b2012-06-20 16:38:30 -070014881}
14882
14883/**---------------------------------------------------------------------------
14884
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +053014885 \brief hdd_del_all_sta() - function
14886
14887 This function removes all the stations associated on stopping AP/P2P GO.
14888
14889 \param - pAdapter - Pointer to the HDD
14890
14891 \return - None
14892
14893 --------------------------------------------------------------------------*/
14894
14895int hdd_del_all_sta(hdd_adapter_t *pAdapter)
14896{
14897 v_U16_t i;
14898 VOS_STATUS vos_status;
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053014899 v_CONTEXT_t pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
14900 ptSapContext pSapCtx = NULL;
14901 pSapCtx = VOS_GET_SAP_CB(pVosContext);
14902 if(pSapCtx == NULL){
14903 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14904 FL("psapCtx is NULL"));
14905 return 1;
14906 }
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +053014907 ENTER();
14908
14909 hddLog(VOS_TRACE_LEVEL_INFO,
14910 "%s: Delete all STAs associated.",__func__);
14911 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
14912 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
14913 )
14914 {
14915 for(i = 0; i < WLAN_MAX_STA_COUNT; i++)
14916 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053014917 if ((pSapCtx->aStaInfo[i].isUsed) &&
14918 (!pSapCtx->aStaInfo[i].isDeauthInProgress))
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +053014919 {
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053014920 struct tagCsrDelStaParams delStaParams;
14921
14922 WLANSAP_PopulateDelStaParams(
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053014923 pSapCtx->aStaInfo[i].macAddrSTA.bytes,
Sushant Kaushik4cd28f62014-12-26 14:23:50 +053014924 eSIR_MAC_DEAUTH_LEAVING_BSS_REASON,
14925 SIR_MAC_MGMT_DEAUTH >> 4,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053014926 &delStaParams);
14927 vos_status = hdd_softap_sta_deauth(pAdapter, &delStaParams);
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +053014928 if (VOS_IS_STATUS_SUCCESS(vos_status))
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053014929 pSapCtx->aStaInfo[i].isDeauthInProgress = TRUE;
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +053014930 }
14931 }
14932 }
14933
14934 EXIT();
14935 return 0;
14936}
14937
14938/**---------------------------------------------------------------------------
14939
Jeff Johnson295189b2012-06-20 16:38:30 -070014940 \brief hdd_softap_sta_disassoc() - function
14941
14942 This to take counter measure to handle deauth req from HDD
14943
14944 \param - pAdapter - Pointer to the HDD
14945
14946 \param - enable - boolean value
14947
14948 \return - None
14949
14950 --------------------------------------------------------------------------*/
14951
14952void hdd_softap_sta_disassoc(hdd_adapter_t *pAdapter,v_U8_t *pDestMacAddress)
14953{
Hanumanth Reddy Pothula57323632017-12-06 17:55:09 +053014954 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
14955 struct hdd_cache_sta_info *cache_sta_info;
14956 ptSapContext pSapCtx = VOS_GET_SAP_CB(pVosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -070014957
14958 ENTER();
14959
Jeff Johnsonc135a9a2017-09-19 08:37:24 -070014960 hddLog( LOGE, "hdd_softap_sta_disassoc:(%pK, false)", (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -070014961
Hanumanth Reddy Pothula57323632017-12-06 17:55:09 +053014962 if (!pSapCtx) {
14963 hddLog(LOGE, "sap context is NULL");
14964 return ;
14965 }
14966
Jeff Johnson295189b2012-06-20 16:38:30 -070014967 //Ignore request to disassoc bcmc station
14968 if( pDestMacAddress[0] & 0x1 )
14969 return;
14970
Hanumanth Reddy Pothula57323632017-12-06 17:55:09 +053014971 cache_sta_info = hdd_get_cache_stainfo(pSapCtx->cache_sta_info,
14972 pDestMacAddress);
14973 if (cache_sta_info) {
14974 cache_sta_info->reason_code = eSIR_MAC_DEAUTH_LEAVING_BSS_REASON;
14975 cache_sta_info->rx_rate =
14976 wlan_tl_get_sta_rx_rate(pVosContext, cache_sta_info->ucSTAId);
14977 WLANTL_GetSAPStaRSSi(pVosContext, cache_sta_info->ucSTAId,
14978 &cache_sta_info->rssi);
14979 }
14980
Jeff Johnson295189b2012-06-20 16:38:30 -070014981 WLANSAP_DisassocSta(pVosContext,pDestMacAddress);
14982}
14983
14984void hdd_softap_tkip_mic_fail_counter_measure(hdd_adapter_t *pAdapter,v_BOOL_t enable)
14985{
14986 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
14987
14988 ENTER();
14989
Jeff Johnsonc135a9a2017-09-19 08:37:24 -070014990 hddLog( LOGE, "hdd_softap_tkip_mic_fail_counter_measure:(%pK, false)", (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -070014991
14992 WLANSAP_SetCounterMeasure(pVosContext, (v_BOOL_t)enable);
14993}
14994
Jeff Johnson295189b2012-06-20 16:38:30 -070014995/**---------------------------------------------------------------------------
14996 *
14997 * \brief hdd_get__concurrency_mode() -
14998 *
14999 *
15000 * \param - None
15001 *
15002 * \return - CONCURRENCY MODE
15003 *
15004 * --------------------------------------------------------------------------*/
15005tVOS_CONCURRENCY_MODE hdd_get_concurrency_mode ( void )
15006{
15007 v_CONTEXT_t pVosContext = vos_get_global_context( VOS_MODULE_ID_HDD, NULL );
15008 hdd_context_t *pHddCtx;
15009
15010 if (NULL != pVosContext)
15011 {
15012 pHddCtx = vos_get_context( VOS_MODULE_ID_HDD, pVosContext);
15013 if (NULL != pHddCtx)
15014 {
15015 return (tVOS_CONCURRENCY_MODE)pHddCtx->concurrency_mode;
15016 }
15017 }
15018
15019 /* we are in an invalid state :( */
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070015020 hddLog(LOGE, "%s: Invalid context", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070015021 return VOS_STA;
15022}
Sushant Kaushikabb7ee62014-07-18 16:20:12 +053015023v_BOOL_t
15024wlan_hdd_is_GO_power_collapse_allowed (hdd_context_t* pHddCtx)
15025{
15026 hdd_adapter_t *pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070015027
Sushant Kaushikabb7ee62014-07-18 16:20:12 +053015028 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_GO);
15029 if (pAdapter == NULL)
15030 {
15031 hddLog(VOS_TRACE_LEVEL_INFO,
15032 FL("GO doesn't exist"));
15033 return TRUE;
15034 }
15035 if (test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
15036 {
15037 hddLog(VOS_TRACE_LEVEL_INFO,
15038 FL("GO started"));
15039 return TRUE;
15040 }
15041 else
15042 /* wait till GO changes its interface to p2p device */
15043 hddLog(VOS_TRACE_LEVEL_INFO,
15044 FL("Del_bss called, avoid apps suspend"));
15045 return FALSE;
15046
15047}
Jeff Johnson295189b2012-06-20 16:38:30 -070015048/* Decide whether to allow/not the apps power collapse.
15049 * Allow apps power collapse if we are in connected state.
15050 * if not, allow only if we are in IMPS */
15051v_BOOL_t hdd_is_apps_power_collapse_allowed(hdd_context_t* pHddCtx)
15052{
15053 tPmcState pmcState = pmcGetPmcState(pHddCtx->hHal);
Srikant Kuppafef66a72013-01-30 17:32:44 -080015054 tANI_BOOLEAN scanRspPending = csrNeighborRoamScanRspPending(pHddCtx->hHal);
Srinivas Girigowdaa553c462013-03-07 19:42:52 -080015055 tANI_BOOLEAN inMiddleOfRoaming = csrNeighborMiddleOfRoaming(pHddCtx->hHal);
Jeff Johnson295189b2012-06-20 16:38:30 -070015056 hdd_config_t *pConfig = pHddCtx->cfg_ini;
15057 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
15058 hdd_adapter_t *pAdapter = NULL;
15059 VOS_STATUS status;
Yathish9f22e662012-12-10 14:21:35 -080015060 tVOS_CONCURRENCY_MODE concurrent_state = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070015061
Jeff Johnson295189b2012-06-20 16:38:30 -070015062 if (VOS_STA_SAP_MODE == hdd_get_conparam())
15063 return TRUE;
Jeff Johnson295189b2012-06-20 16:38:30 -070015064
Yathish9f22e662012-12-10 14:21:35 -080015065 concurrent_state = hdd_get_concurrency_mode();
15066
Sushant Kaushikabb7ee62014-07-18 16:20:12 +053015067 if ((concurrent_state == (VOS_STA | VOS_P2P_GO)) &&
15068 !(wlan_hdd_is_GO_power_collapse_allowed(pHddCtx)))
15069 return FALSE;
Yathish9f22e662012-12-10 14:21:35 -080015070#ifdef WLAN_ACTIVEMODE_OFFLOAD_FEATURE
Sushant Kaushikabb7ee62014-07-18 16:20:12 +053015071
Yathish9f22e662012-12-10 14:21:35 -080015072 if(((concurrent_state == (VOS_STA | VOS_P2P_CLIENT)) ||
Sushant Kaushikabb7ee62014-07-18 16:20:12 +053015073 (concurrent_state == (VOS_STA | VOS_P2P_GO)))&&
Yathish9f22e662012-12-10 14:21:35 -080015074 (IS_ACTIVEMODE_OFFLOAD_FEATURE_ENABLE))
15075 return TRUE;
15076#endif
15077
Jeff Johnson295189b2012-06-20 16:38:30 -070015078 /*loop through all adapters. TBD fix for Concurrency */
15079 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
15080 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
15081 {
15082 pAdapter = pAdapterNode->pAdapter;
15083 if ( (WLAN_HDD_INFRA_STATION == pAdapter->device_mode)
15084 || (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
15085 {
Srikant Kuppafef66a72013-01-30 17:32:44 -080015086 if (((pConfig->fIsImpsEnabled || pConfig->fIsBmpsEnabled)
c_hpothu4e8faac2014-05-16 17:38:44 +053015087 && (pmcState != IMPS && pmcState != BMPS && pmcState != UAPSD
c_hpothu1c6957d2015-01-06 18:19:47 +053015088 && pmcState != STOPPED && pmcState != STANDBY &&
15089 pmcState != WOWL)) ||
Srinivas Girigowdaa553c462013-03-07 19:42:52 -080015090 (eANI_BOOLEAN_TRUE == scanRspPending) ||
15091 (eANI_BOOLEAN_TRUE == inMiddleOfRoaming))
Jeff Johnson295189b2012-06-20 16:38:30 -070015092 {
Mukul Sharma4be88422015-03-09 20:29:07 +053015093 if(pmcState == FULL_POWER &&
15094 sme_IsCoexScoIndicationSet(pHddCtx->hHal))
15095 {
15096 /*
15097 * When SCO indication comes from Coex module , host will
15098 * enter in to full power mode, but this should not prevent
15099 * apps processor power collapse.
15100 */
15101 hddLog(LOG1,
15102 FL("Allow apps power collapse"
15103 "even when sco indication is set"));
15104 return TRUE;
15105 }
Srikant Kuppafef66a72013-01-30 17:32:44 -080015106 hddLog( LOGE, "%s: do not allow APPS power collapse-"
Deepthi Gowri03a979f2016-11-03 15:20:19 +053015107 "pmcState = %d scanRspPending = %d "
15108 "inMiddleOfRoaming = %d connected = %d",
15109 __func__, pmcState, scanRspPending,
15110 inMiddleOfRoaming, hdd_connIsConnected(
15111 WLAN_HDD_GET_STATION_CTX_PTR( pAdapter )));
15112 wlan_hdd_get_tdls_stats(pAdapter);
15113 return FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070015114 }
15115 }
15116 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
15117 pAdapterNode = pNext;
15118 }
15119 return TRUE;
15120}
15121
Madan Mohan Koyyalamudic72a4d62012-11-08 14:59:34 -080015122/* Decides whether to send suspend notification to Riva
15123 * if any adapter is in BMPS; then it is required */
15124v_BOOL_t hdd_is_suspend_notify_allowed(hdd_context_t* pHddCtx)
15125{
15126 tPmcState pmcState = pmcGetPmcState(pHddCtx->hHal);
15127 hdd_config_t *pConfig = pHddCtx->cfg_ini;
15128
15129 if (pConfig->fIsBmpsEnabled && (pmcState == BMPS))
15130 {
15131 return TRUE;
15132 }
15133 return FALSE;
15134}
15135
Jeff Johnson295189b2012-06-20 16:38:30 -070015136void wlan_hdd_set_concurrency_mode(hdd_context_t *pHddCtx, tVOS_CON_MODE mode)
15137{
15138 switch(mode)
15139 {
Chilam Ngc4244af2013-04-01 15:37:32 -070015140 case VOS_STA_MODE:
15141 case VOS_P2P_CLIENT_MODE:
15142 case VOS_P2P_GO_MODE:
15143 case VOS_STA_SAP_MODE:
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +053015144 case VOS_MONITOR_MODE:
Jeff Johnsone7245742012-09-05 17:12:55 -070015145 pHddCtx->concurrency_mode |= (1 << mode);
Agarwal Ashish51325b52014-06-16 16:50:49 +053015146 pHddCtx->no_of_open_sessions[mode]++;
Jeff Johnson295189b2012-06-20 16:38:30 -070015147 break;
15148 default:
15149 break;
Jeff Johnson295189b2012-06-20 16:38:30 -070015150 }
Agarwal Ashish51325b52014-06-16 16:50:49 +053015151 hddLog(VOS_TRACE_LEVEL_INFO, FL("concurrency_mode = 0x%x "
15152 "Number of open sessions for mode %d = %d"),
15153 pHddCtx->concurrency_mode, mode,
15154 pHddCtx->no_of_open_sessions[mode]);
Jeff Johnson295189b2012-06-20 16:38:30 -070015155}
15156
15157
15158void wlan_hdd_clear_concurrency_mode(hdd_context_t *pHddCtx, tVOS_CON_MODE mode)
15159{
15160 switch(mode)
15161 {
Chilam Ngc4244af2013-04-01 15:37:32 -070015162 case VOS_STA_MODE:
15163 case VOS_P2P_CLIENT_MODE:
15164 case VOS_P2P_GO_MODE:
15165 case VOS_STA_SAP_MODE:
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +053015166 case VOS_MONITOR_MODE:
Agarwal Ashish51325b52014-06-16 16:50:49 +053015167 pHddCtx->no_of_open_sessions[mode]--;
15168 if (!(pHddCtx->no_of_open_sessions[mode]))
15169 pHddCtx->concurrency_mode &= (~(1 << mode));
Jeff Johnson295189b2012-06-20 16:38:30 -070015170 break;
15171 default:
15172 break;
15173 }
Agarwal Ashish51325b52014-06-16 16:50:49 +053015174 hddLog(VOS_TRACE_LEVEL_INFO, FL("concurrency_mode = 0x%x "
15175 "Number of open sessions for mode %d = %d"),
15176 pHddCtx->concurrency_mode, mode, pHddCtx->no_of_open_sessions[mode]);
15177
15178}
15179/**---------------------------------------------------------------------------
15180 *
15181 * \brief wlan_hdd_incr_active_session()
15182 *
15183 * This function increments the number of active sessions
15184 * maintained per device mode
15185 * Incase of STA/P2P CLI/IBSS upon connection indication it is incremented
15186 * Incase of SAP/P2P GO upon bss start it is incremented
15187 *
15188 * \param pHddCtx - HDD Context
15189 * \param mode - device mode
15190 *
15191 * \return - None
15192 *
15193 * --------------------------------------------------------------------------*/
15194void wlan_hdd_incr_active_session(hdd_context_t *pHddCtx, tVOS_CON_MODE mode)
15195{
15196 switch (mode) {
15197 case VOS_STA_MODE:
15198 case VOS_P2P_CLIENT_MODE:
15199 case VOS_P2P_GO_MODE:
15200 case VOS_STA_SAP_MODE:
15201 pHddCtx->no_of_active_sessions[mode]++;
15202 break;
15203 default:
15204 hddLog(VOS_TRACE_LEVEL_INFO, FL("Not Expected Mode %d"), mode);
15205 break;
15206 }
15207 hddLog(VOS_TRACE_LEVEL_INFO, FL("No.# of active sessions for mode %d = %d"),
15208 mode,
15209 pHddCtx->no_of_active_sessions[mode]);
15210}
15211
15212/**---------------------------------------------------------------------------
15213 *
15214 * \brief wlan_hdd_decr_active_session()
15215 *
15216 * This function decrements the number of active sessions
15217 * maintained per device mode
15218 * Incase of STA/P2P CLI/IBSS upon disconnection it is decremented
15219 * Incase of SAP/P2P GO upon bss stop it is decremented
15220 *
15221 * \param pHddCtx - HDD Context
15222 * \param mode - device mode
15223 *
15224 * \return - None
15225 *
15226 * --------------------------------------------------------------------------*/
15227void wlan_hdd_decr_active_session(hdd_context_t *pHddCtx, tVOS_CON_MODE mode)
15228{
Bhargav Shahd0715912015-10-01 18:17:37 +053015229
Agarwal Ashish51325b52014-06-16 16:50:49 +053015230 switch (mode) {
15231 case VOS_STA_MODE:
15232 case VOS_P2P_CLIENT_MODE:
15233 case VOS_P2P_GO_MODE:
15234 case VOS_STA_SAP_MODE:
Agarwal Ashish5325f522014-08-06 00:58:44 +053015235 if (pHddCtx->no_of_active_sessions[mode] > 0)
15236 pHddCtx->no_of_active_sessions[mode]--;
15237 else
15238 hddLog(VOS_TRACE_LEVEL_INFO, FL(" No.# of Active sessions"
15239 "is already Zero"));
Agarwal Ashish51325b52014-06-16 16:50:49 +053015240 break;
15241 default:
15242 hddLog(VOS_TRACE_LEVEL_INFO, FL("Not Expected Mode %d"), mode);
15243 break;
15244 }
15245 hddLog(VOS_TRACE_LEVEL_INFO, FL("No.# of active sessions for mode %d = %d"),
15246 mode,
15247 pHddCtx->no_of_active_sessions[mode]);
Jeff Johnson295189b2012-06-20 16:38:30 -070015248}
15249
Jeff Johnsone7245742012-09-05 17:12:55 -070015250/**---------------------------------------------------------------------------
15251 *
15252 * \brief wlan_hdd_restart_init
15253 *
15254 * This function initalizes restart timer/flag. An internal function.
15255 *
15256 * \param - pHddCtx
15257 *
15258 * \return - None
15259 *
15260 * --------------------------------------------------------------------------*/
15261
15262static void wlan_hdd_restart_init(hdd_context_t *pHddCtx)
15263{
15264 /* Initialize */
15265 pHddCtx->hdd_restart_retries = 0;
15266 atomic_set(&pHddCtx->isRestartInProgress, 0);
15267 vos_timer_init(&pHddCtx->hdd_restart_timer,
15268 VOS_TIMER_TYPE_SW,
15269 wlan_hdd_restart_timer_cb,
15270 pHddCtx);
15271}
15272/**---------------------------------------------------------------------------
15273 *
15274 * \brief wlan_hdd_restart_deinit
15275 *
15276 * This function cleans up the resources used. An internal function.
15277 *
15278 * \param - pHddCtx
15279 *
15280 * \return - None
15281 *
15282 * --------------------------------------------------------------------------*/
15283
15284static void wlan_hdd_restart_deinit(hdd_context_t* pHddCtx)
15285{
15286
15287 VOS_STATUS vos_status;
15288 /* Block any further calls */
15289 atomic_set(&pHddCtx->isRestartInProgress, 1);
15290 /* Cleanup */
15291 vos_status = vos_timer_stop( &pHddCtx->hdd_restart_timer );
15292 if (!VOS_IS_STATUS_SUCCESS(vos_status))
c_hpothu6ff1c3c2013-10-01 19:01:57 +053015293 hddLog(LOGE, FL("Failed to stop HDD restart timer"));
Jeff Johnsone7245742012-09-05 17:12:55 -070015294 vos_status = vos_timer_destroy(&pHddCtx->hdd_restart_timer);
15295 if (!VOS_IS_STATUS_SUCCESS(vos_status))
c_hpothu6ff1c3c2013-10-01 19:01:57 +053015296 hddLog(LOGE, FL("Failed to destroy HDD restart timer"));
Jeff Johnsone7245742012-09-05 17:12:55 -070015297
15298}
15299
15300/**---------------------------------------------------------------------------
15301 *
15302 * \brief wlan_hdd_framework_restart
15303 *
15304 * This function uses a cfg80211 API to start a framework initiated WLAN
15305 * driver module unload/load.
15306 *
15307 * Also this API keep retrying (WLAN_HDD_RESTART_RETRY_MAX_CNT).
15308 *
15309 *
15310 * \param - pHddCtx
15311 *
15312 * \return - VOS_STATUS_SUCCESS: Success
15313 * VOS_STATUS_E_EMPTY: Adapter is Empty
15314 * VOS_STATUS_E_NOMEM: No memory
15315
15316 * --------------------------------------------------------------------------*/
15317
15318static VOS_STATUS wlan_hdd_framework_restart(hdd_context_t *pHddCtx)
15319{
15320 VOS_STATUS status = VOS_STATUS_SUCCESS;
15321 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
Madan Mohan Koyyalamudifc19e442013-05-09 18:24:08 -070015322 int len = (sizeof (struct ieee80211_mgmt));
15323 struct ieee80211_mgmt *mgmt = NULL;
15324
15325 /* Prepare the DEAUTH managment frame with reason code */
15326 mgmt = kzalloc(len, GFP_KERNEL);
15327 if(mgmt == NULL)
15328 {
15329 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
15330 "%s: memory allocation failed (%d bytes)", __func__, len);
15331 return VOS_STATUS_E_NOMEM;
15332 }
15333 mgmt->u.deauth.reason_code = WLAN_REASON_DISASSOC_LOW_ACK;
Jeff Johnsone7245742012-09-05 17:12:55 -070015334
15335 /* Iterate over all adapters/devices */
15336 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
Hanumantha Reddy Pothulada0fe362015-02-27 18:37:03 +053015337 if ((NULL == pAdapterNode) || (VOS_STATUS_SUCCESS != status))
15338 {
15339 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnsonc135a9a2017-09-19 08:37:24 -070015340 FL("fail to get adapter: %pK %d"), pAdapterNode, status);
Hanumantha Reddy Pothulada0fe362015-02-27 18:37:03 +053015341 goto end;
15342 }
15343
Jeff Johnsone7245742012-09-05 17:12:55 -070015344 do
15345 {
Hanumantha Reddy Pothulada0fe362015-02-27 18:37:03 +053015346 if(pAdapterNode->pAdapter &&
15347 WLAN_HDD_ADAPTER_MAGIC == pAdapterNode->pAdapter->magic)
Jeff Johnsone7245742012-09-05 17:12:55 -070015348 {
15349 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
15350 "restarting the driver(intf:\'%s\' mode:%d :try %d)",
15351 pAdapterNode->pAdapter->dev->name,
15352 pAdapterNode->pAdapter->device_mode,
15353 pHddCtx->hdd_restart_retries + 1);
Madan Mohan Koyyalamudifc19e442013-05-09 18:24:08 -070015354 /*
15355 * CFG80211 event to restart the driver
15356 *
15357 * 'cfg80211_send_unprot_deauth' sends a
15358 * NL80211_CMD_UNPROT_DEAUTHENTICATE event to supplicant at any state
15359 * of SME(Linux Kernel) state machine.
15360 *
15361 * Reason code WLAN_REASON_DISASSOC_LOW_ACK is currently used to restart
15362 * the driver.
15363 *
15364 */
Abhishek Singh00b71972016-01-07 10:51:04 +053015365
Anand N Sunkade9adb1b2015-07-29 09:56:45 +053015366#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 11, 0))
15367 cfg80211_rx_unprot_mlme_mgmt(pAdapterNode->pAdapter->dev, (u_int8_t*)mgmt, len);
15368#else
Madan Mohan Koyyalamudifc19e442013-05-09 18:24:08 -070015369 cfg80211_send_unprot_deauth(pAdapterNode->pAdapter->dev, (u_int8_t*)mgmt, len );
Anand N Sunkade9adb1b2015-07-29 09:56:45 +053015370#endif
Jeff Johnsone7245742012-09-05 17:12:55 -070015371 }
15372 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
15373 pAdapterNode = pNext;
15374 } while((NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status));
15375
Hanumantha Reddy Pothulada0fe362015-02-27 18:37:03 +053015376 end:
Madan Mohan Koyyalamudifc19e442013-05-09 18:24:08 -070015377 /* Free the allocated management frame */
15378 kfree(mgmt);
15379
Jeff Johnsone7245742012-09-05 17:12:55 -070015380 /* Retry until we unload or reach max count */
15381 if(++pHddCtx->hdd_restart_retries < WLAN_HDD_RESTART_RETRY_MAX_CNT)
15382 vos_timer_start(&pHddCtx->hdd_restart_timer, WLAN_HDD_RESTART_RETRY_DELAY_MS);
15383
15384 return status;
15385
15386}
15387/**---------------------------------------------------------------------------
15388 *
15389 * \brief wlan_hdd_restart_timer_cb
15390 *
15391 * Restart timer callback. An internal function.
15392 *
15393 * \param - User data:
15394 *
15395 * \return - None
15396 *
15397 * --------------------------------------------------------------------------*/
15398
15399void wlan_hdd_restart_timer_cb(v_PVOID_t usrDataForCallback)
15400{
15401 hdd_context_t *pHddCtx = usrDataForCallback;
15402 wlan_hdd_framework_restart(pHddCtx);
15403 return;
15404
15405}
15406
15407
15408/**---------------------------------------------------------------------------
15409 *
15410 * \brief wlan_hdd_restart_driver
15411 *
15412 * This function sends an event to supplicant to restart the WLAN driver.
15413 *
15414 * This function is called from vos_wlanRestart.
15415 *
15416 * \param - pHddCtx
15417 *
15418 * \return - VOS_STATUS_SUCCESS: Success
15419 * VOS_STATUS_E_EMPTY: Adapter is Empty
15420 * VOS_STATUS_E_ALREADY: Request already in progress
15421
15422 * --------------------------------------------------------------------------*/
15423VOS_STATUS wlan_hdd_restart_driver(hdd_context_t *pHddCtx)
15424{
15425 VOS_STATUS status = VOS_STATUS_SUCCESS;
15426
15427 /* A tight check to make sure reentrancy */
15428 if(atomic_xchg(&pHddCtx->isRestartInProgress, 1))
15429 {
Mihir Shetefd528652014-06-23 19:07:50 +053015430 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnsone7245742012-09-05 17:12:55 -070015431 "%s: WLAN restart is already in progress", __func__);
15432
15433 return VOS_STATUS_E_ALREADY;
15434 }
Sameer Thalappil0c164f52013-03-28 15:27:56 -070015435 /* Send reset FIQ to WCNSS to invoke SSR. */
Madan Mohan Koyyalamudie388b342012-11-08 15:03:16 -080015436#ifdef HAVE_WCNSS_RESET_INTR
Siddharth Bhal864e7e82015-04-07 20:07:24 +053015437 wcnss_reset_fiq(TRUE);
Madan Mohan Koyyalamudibb8f0172012-09-28 15:36:06 -070015438#endif
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -070015439
Jeff Johnsone7245742012-09-05 17:12:55 -070015440 return status;
15441}
15442
Bhargav Shahd0715912015-10-01 18:17:37 +053015443/**
15444 * hdd_get_total_sessions() - provide total number of active sessions
15445 * @pHddCtx: Valid Global HDD context pointer
15446 *
15447 * This function iterates through pAdaptors and find the number of all active
15448 * sessions. This active sessions includes connected sta, p2p client and number
15449 * of client connected to sap/p2p go.
15450 *
15451 * Return: Total number of active sessions.
15452 */
15453v_U8_t hdd_get_total_sessions(hdd_context_t *pHddCtx)
15454{
15455 v_U8_t active_session = 0;
15456 hdd_station_ctx_t *pHddStaCtx;
15457 hdd_adapter_list_node_t *pAdapterNode, *pNext;
15458 hdd_adapter_t *pAdapter;
15459 VOS_STATUS status;
15460
15461 status = hdd_get_front_adapter(pHddCtx, &pAdapterNode);
15462 while (NULL != pAdapterNode && VOS_STATUS_SUCCESS == status) {
15463 pAdapter = pAdapterNode->pAdapter;
15464 switch (pAdapter->device_mode) {
15465 case VOS_STA_MODE:
15466 case VOS_P2P_CLIENT_MODE:
15467 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
15468 if(eConnectionState_Associated == pHddStaCtx->conn_info.connState)
15469 active_session += 1;
15470 break;
15471 case VOS_STA_SAP_MODE:
15472 case VOS_P2P_GO_MODE:
15473 active_session += hdd_softap_get_connected_sta(pAdapter);
15474 break;
15475 default:
15476 break;
15477 }
15478
15479 status = hdd_get_next_adapter(pHddCtx, pAdapterNode, &pNext);
15480 pAdapterNode = pNext;
15481 }
15482
15483 return active_session;
15484}
15485
15486/**
15487 * hdd_set_delack_value() - Set delack value
15488 * @pHddCtx: Valid Global HDD context pointer
15489 * @next_rx_level: Value to set for delack
15490 *
15491 * This function compare present value and next value of delack. If the both
15492 * are diffrent then it sets next value .
15493 *
15494 * Return: void.
15495 */
15496void hdd_set_delack_value(hdd_context_t *pHddCtx, v_U32_t next_rx_level)
15497{
15498 if (pHddCtx->cur_rx_level != next_rx_level) {
15499 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_DEBUG,
15500 "%s: TCP DELACK trigger level %d",
15501 __func__, next_rx_level);
15502 mutex_lock(&pHddCtx->cur_rx_level_lock);
15503 pHddCtx->cur_rx_level = next_rx_level;
15504 mutex_unlock(&pHddCtx->cur_rx_level_lock);
15505 wlan_hdd_send_svc_nlink_msg(WLAN_SVC_WLAN_TP_IND, &next_rx_level,
15506 sizeof(next_rx_level));
15507 }
15508}
15509
15510/**
15511 * hdd_set_default_stop_delack_timer() - Start delack timer
15512 * @pHddCtx: Valid Global HDD context pointer
15513 *
15514 * This function stop delack timer and set delack value to default..
15515 *
15516 * Return: void.
15517 */
15518
15519void hdd_set_default_stop_delack_timer(hdd_context_t *pHddCtx)
15520{
15521 if (VOS_TIMER_STATE_RUNNING !=
15522 vos_timer_getCurrentState(&pHddCtx->delack_timer)) {
15523 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_DEBUG,
15524 "%s: Can not stop timer", __func__);
15525 return;
15526 }
15527
15528 vos_timer_stop(&pHddCtx->delack_timer);
15529 hdd_set_delack_value(pHddCtx, TP_IND_LOW);
15530}
15531
15532/**
15533 * hdd_start_delack_timer() - Start delack timer
15534 * @pHddCtx: Valid Global HDD context pointer
15535 *
15536 * This function starts the delack timer for tcpDelAckComputeInterval time
15537 * interval.The default timer value is 2 second.
15538 *
15539 * Return: void.
15540 */
15541void hdd_start_delack_timer(hdd_context_t *pHddCtx)
15542{
15543 if (VOS_TIMER_STATE_RUNNING ==
15544 vos_timer_getCurrentState(&pHddCtx->delack_timer)) {
15545 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_DEBUG,
15546 "%s: Timer is already running", __func__);
15547 return;
15548 }
15549
15550 vos_timer_start(&pHddCtx->delack_timer,
15551 pHddCtx->cfg_ini->tcpDelAckComputeInterval);
15552}
15553
15554/**
15555 * hdd_update_prev_rx_packet_count() - Update previous rx packet count
15556 * @pHddCtx: Valid Global HDD context pointer
15557 *
15558 * This function updates the prev_rx_packets count from the corresponding
15559 * pAdapter states. This prev_rx_packets will diffed with the packet count
15560 * at the end of delack timer. That can give number of RX packet is spacific
15561 * time.
15562 *
15563 * Return: void.
15564 */
15565void hdd_update_prev_rx_packet_count(hdd_context_t *pHddCtx)
15566{
15567 hdd_adapter_list_node_t *pAdapterNode, *pNext;
15568 hdd_adapter_t *pAdapter;
15569 VOS_STATUS status;
15570
15571 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
15572 while (NULL != pAdapterNode && VOS_STATUS_SUCCESS == status) {
15573 pAdapter = pAdapterNode->pAdapter;
15574 pAdapter->prev_rx_packets = pAdapter->stats.rx_packets;
15575 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
15576 pAdapterNode = pNext;
15577 }
15578}
15579
15580/**
15581 * hdd_manage_delack_timer() - start\stop delack timer
15582 * @pHddCtx: Valid Global HDD context pointer
15583 *
15584 * This function check the number of concerent session present, it starts the
15585 * delack timer if only one session is present.
15586 * In the case of BT_COEX and TDLS mode it blindly stop delack functionality.
15587 *
15588 * Return: void.
15589 */
15590void hdd_manage_delack_timer(hdd_context_t *pHddCtx)
15591{
15592 uint8_t sessions;
15593
15594 if (!pHddCtx->cfg_ini->enable_delack) {
15595 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_DEBUG,
15596 "%s: TCP DELACK is not enabled", __func__);
15597 return;
15598 }
15599
15600 /* Blindly stop timer of BTCOEX and TDLS Session is up */
15601 if (pHddCtx->mode != 0) {
15602 hdd_set_default_stop_delack_timer(pHddCtx);
15603 return;
15604 }
15605
15606 sessions = hdd_get_total_sessions(pHddCtx);
15607 if (sessions == 1) {
15608 hdd_update_prev_rx_packet_count(pHddCtx);
15609 hdd_start_delack_timer(pHddCtx);
15610 } else {
15611 hdd_set_default_stop_delack_timer(pHddCtx);
15612 }
15613}
15614
Mihir Shetee1093ba2014-01-21 20:13:32 +053015615/**---------------------------------------------------------------------------
15616 *
15617 * \brief wlan_hdd_init_channels
15618 *
15619 * This function is used to initialize the channel list in CSR
15620 *
15621 * This function is called from hdd_wlan_startup
15622 *
15623 * \param - pHddCtx: HDD context
15624 *
15625 * \return - VOS_STATUS_SUCCESS: Success
15626 * VOS_STATUS_E_FAULT: Failure reported by SME
15627
15628 * --------------------------------------------------------------------------*/
15629static VOS_STATUS wlan_hdd_init_channels(hdd_context_t *pHddCtx)
15630{
15631 eHalStatus status;
15632
15633 status = sme_InitChannels(pHddCtx->hHal);
15634 if (HAL_STATUS_SUCCESS(status))
15635 {
15636 return VOS_STATUS_SUCCESS;
15637 }
15638 else
15639 {
15640 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Channel initialization failed(%d)",
15641 __func__, status);
15642 return VOS_STATUS_E_FAULT;
15643 }
15644}
15645
Mihir Shete04206452014-11-20 17:50:58 +053015646#ifdef CONFIG_ENABLE_LINUX_REG
Agarwal Ashish6db9d532014-09-30 18:19:10 +053015647VOS_STATUS wlan_hdd_init_channels_for_cc(hdd_context_t *pHddCtx, driver_load_type init )
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053015648{
15649 eHalStatus status;
15650
Agarwal Ashish6db9d532014-09-30 18:19:10 +053015651 status = sme_InitChannelsForCC(pHddCtx->hHal, init);
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053015652 if (HAL_STATUS_SUCCESS(status))
15653 {
15654 return VOS_STATUS_SUCCESS;
15655 }
15656 else
15657 {
15658 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Issue reg hint failed(%d)",
15659 __func__, status);
15660 return VOS_STATUS_E_FAULT;
15661 }
15662}
Mihir Shete04206452014-11-20 17:50:58 +053015663#endif
Sudhir Sattayappa Kohallib1d8c3a2013-06-18 14:47:20 -070015664/*
15665 * API to find if there is any STA or P2P-Client is connected
15666 */
15667VOS_STATUS hdd_issta_p2p_clientconnected(hdd_context_t *pHddCtx)
15668{
15669 return sme_isSta_p2p_clientConnected(pHddCtx->hHal);
15670}
Jeff Johnsone7245742012-09-05 17:12:55 -070015671
Mihir Shetee2ae82a2015-03-16 14:08:49 +053015672
15673/*
15674 * API to find if the firmware will send logs using DXE channel
15675 */
15676v_U8_t hdd_is_fw_logging_enabled(void)
15677{
15678 hdd_context_t *pHddCtx;
15679
15680 pHddCtx = vos_get_context(VOS_MODULE_ID_HDD,
15681 vos_get_global_context(VOS_MODULE_ID_HDD, NULL));
15682
Sachin Ahuja084313e2015-05-21 17:57:10 +053015683 return (pHddCtx && pHddCtx->cfg_ini->enableMgmtLogging);
Mihir Shetee2ae82a2015-03-16 14:08:49 +053015684}
15685
Agarwal Ashish57e84372014-12-05 18:26:53 +053015686/*
Mihir Shetebe94ebb2015-05-26 12:07:14 +053015687 * API to find if the firmware will send trace logs using DXE channel
15688 */
15689v_U8_t hdd_is_fw_ev_logging_enabled(void)
15690{
15691 hdd_context_t *pHddCtx;
15692
15693 pHddCtx = vos_get_context(VOS_MODULE_ID_HDD,
15694 vos_get_global_context(VOS_MODULE_ID_HDD, NULL));
15695
15696 return (pHddCtx && pHddCtx->cfg_ini->enableFWLogging);
15697}
15698/*
Agarwal Ashish57e84372014-12-05 18:26:53 +053015699 * API to find if there is any session connected
15700 */
15701VOS_STATUS hdd_is_any_session_connected(hdd_context_t *pHddCtx)
15702{
15703 return sme_is_any_session_connected(pHddCtx->hHal);
15704}
15705
15706
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053015707int wlan_hdd_scan_abort(hdd_adapter_t *pAdapter)
15708{
15709 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
15710 hdd_scaninfo_t *pScanInfo = NULL;
Girish Gowli4bf7a632014-06-12 13:42:11 +053015711 long status = 0;
c_hpothua3d45d52015-01-05 14:11:17 +053015712 tSirAbortScanStatus abortScanStatus;
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053015713
15714 pScanInfo = &pHddCtx->scan_info;
Ratnam Rachuric7681132015-06-30 10:35:13 +053015715 INIT_COMPLETION(pScanInfo->abortscan_event_var);
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053015716 if (pScanInfo->mScanPending)
15717 {
c_hpothua3d45d52015-01-05 14:11:17 +053015718 abortScanStatus = hdd_abort_mac_scan(pHddCtx, pScanInfo->sessionId,
15719 eCSR_SCAN_ABORT_DEFAULT);
15720 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15721 FL("abortScanStatus: %d"), abortScanStatus);
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053015722
c_hpothua3d45d52015-01-05 14:11:17 +053015723 /* If there is active scan command lets wait for the completion else
15724 * there is no need to wait as scan command might be in the SME pending
15725 * command list.
15726 */
15727 if (abortScanStatus == eSIR_ABORT_ACTIVE_SCAN_LIST_NOT_EMPTY)
15728 {
Mukul Sharmab392b642017-08-17 17:45:29 +053015729 status = wait_for_completion_timeout(
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053015730 &pScanInfo->abortscan_event_var,
15731 msecs_to_jiffies(5000));
c_hpothua3d45d52015-01-05 14:11:17 +053015732 if (0 >= status)
15733 {
15734 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Girish Gowli4bf7a632014-06-12 13:42:11 +053015735 "%s: Timeout or Interrupt occurred while waiting for abort"
15736 "scan, status- %ld", __func__, status);
c_hpothua3d45d52015-01-05 14:11:17 +053015737 return -ETIMEDOUT;
15738 }
15739 }
15740 else if (abortScanStatus == eSIR_ABORT_SCAN_FAILURE)
15741 {
15742 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15743 FL("hdd_abort_mac_scan failed"));
15744 return -VOS_STATUS_E_FAILURE;
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053015745 }
15746 }
Girish Gowli4bf7a632014-06-12 13:42:11 +053015747 return 0;
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053015748}
15749
Abhishek Singh7d624e12015-11-30 14:29:27 +053015750/**
15751 * hdd_indicate_mgmt_frame() - Wrapper to indicate management frame to
15752 * user space
15753 * @frame_ind: Management frame data to be informed.
15754 *
15755 * This function is used to indicate management frame to
15756 * user space
15757 *
15758 * Return: None
15759 *
15760 */
15761void hdd_indicate_mgmt_frame(tSirSmeMgmtFrameInd *frame_ind)
15762{
15763 hdd_context_t *hdd_ctx = NULL;
15764 hdd_adapter_t *adapter = NULL;
15765 v_CONTEXT_t vos_context = NULL;
15766
15767 /* Get the global VOSS context.*/
15768 vos_context = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
15769 if (!vos_context) {
15770 hddLog(LOGE, FL("Global VOS context is Null"));
15771 return;
15772 }
15773 /* Get the HDD context.*/
15774 hdd_ctx =
15775 (hdd_context_t *)vos_get_context(VOS_MODULE_ID_HDD, vos_context );
15776
15777 if (0 != wlan_hdd_validate_context(hdd_ctx))
15778 {
15779 return;
15780 }
15781 adapter = hdd_get_adapter_by_sme_session_id(hdd_ctx,
15782 frame_ind->sessionId);
15783
15784 if ((NULL != adapter) &&
15785 (WLAN_HDD_ADAPTER_MAGIC == adapter->magic))
15786 __hdd_indicate_mgmt_frame(adapter,
15787 frame_ind->frameLen,
15788 frame_ind->frameBuf,
15789 frame_ind->frameType,
15790 frame_ind->rxChan,
15791 frame_ind->rxRssi);
15792 return;
15793
15794}
15795
c_hpothu225aa7c2014-10-22 17:45:13 +053015796VOS_STATUS wlan_hdd_cancel_remain_on_channel(hdd_context_t *pHddCtx)
15797{
15798 hdd_adapter_t *pAdapter;
15799 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
15800 VOS_STATUS vosStatus;
15801
15802 vosStatus = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
15803 while (NULL != pAdapterNode && VOS_STATUS_E_EMPTY != vosStatus)
15804 {
15805 pAdapter = pAdapterNode->pAdapter;
15806 if (NULL != pAdapter)
15807 {
15808 if (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode ||
15809 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode ||
15810 WLAN_HDD_P2P_GO == pAdapter->device_mode)
15811 {
15812 hddLog(LOG1, FL("abort ROC deviceMode: %d"),
15813 pAdapter->device_mode);
15814 if (VOS_STATUS_SUCCESS !=
15815 wlan_hdd_cancel_existing_remain_on_channel(pAdapter))
15816 {
15817 hddLog(LOGE, FL("failed to abort ROC"));
15818 return VOS_STATUS_E_FAILURE;
15819 }
15820 }
15821 }
15822 vosStatus = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
15823 pAdapterNode = pNext;
15824 }
15825 return VOS_STATUS_SUCCESS;
15826}
Mahesh A Saptasagard477b092015-02-06 15:12:16 +053015827
Mihir Shete0be28772015-02-17 18:42:14 +053015828hdd_remain_on_chan_ctx_t *hdd_get_remain_on_channel_ctx(hdd_context_t *pHddCtx)
15829{
15830 hdd_adapter_t *pAdapter;
15831 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
15832 hdd_cfg80211_state_t *cfgState;
15833 hdd_remain_on_chan_ctx_t *pRemainChanCtx = NULL;
15834 VOS_STATUS vosStatus;
15835
15836 vosStatus = hdd_get_front_adapter (pHddCtx, &pAdapterNode);
15837 while (NULL != pAdapterNode && VOS_STATUS_E_EMPTY != vosStatus)
15838 {
15839 pAdapter = pAdapterNode->pAdapter;
15840 if (NULL != pAdapter)
15841 {
15842 cfgState = WLAN_HDD_GET_CFG_STATE_PTR(pAdapter);
15843 pRemainChanCtx = cfgState->remain_on_chan_ctx;
15844 if (pRemainChanCtx)
15845 break;
15846 }
15847 vosStatus = hdd_get_next_adapter (pHddCtx, pAdapterNode, &pNext);
15848 pAdapterNode = pNext;
15849 }
15850 return pRemainChanCtx;
15851}
15852
Padma, Santhosh Kumar778d8382015-03-04 17:41:22 +053015853/**
15854 * wlan_hdd_handle_dfs_chan_scan () - handles disable/enable DFS channels
15855 *
15856 * @pHddCtx: HDD context within host driver
15857 * @dfsScanMode: dfsScanMode passed from ioctl
15858 *
15859 */
15860
15861VOS_STATUS wlan_hdd_handle_dfs_chan_scan(hdd_context_t *pHddCtx,
15862 tANI_U8 dfsScanMode)
15863{
15864 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
15865 hdd_adapter_t *pAdapter;
15866 VOS_STATUS vosStatus;
15867 hdd_station_ctx_t *pHddStaCtx;
15868 eHalStatus status = eHAL_STATUS_SUCCESS;
15869
15870 if(!pHddCtx)
15871 {
15872 hddLog(LOGE, FL("HDD context is Null"));
15873 return eHAL_STATUS_FAILURE;
15874 }
15875
15876 if (pHddCtx->scan_info.mScanPending)
15877 {
15878 hddLog(LOG1, FL("Aborting scan for sessionId: %d"),
15879 pHddCtx->scan_info.sessionId);
15880 hdd_abort_mac_scan(pHddCtx,
15881 pHddCtx->scan_info.sessionId,
15882 eCSR_SCAN_ABORT_DEFAULT);
15883 }
15884
15885 if (!dfsScanMode)
15886 {
15887 vosStatus = hdd_get_front_adapter( pHddCtx, &pAdapterNode);
15888 while ((NULL != pAdapterNode) &&
15889 (VOS_STATUS_SUCCESS == vosStatus))
15890 {
15891 pAdapter = pAdapterNode->pAdapter;
15892
15893 if (WLAN_HDD_INFRA_STATION == pAdapter->device_mode)
15894 {
15895 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
15896
15897 if(!pHddStaCtx)
15898 {
15899 hddLog(LOGE, FL("HDD STA context is Null"));
15900 return eHAL_STATUS_FAILURE;
15901 }
15902
15903 /* if STA is already connected on DFS channel,
15904 disconnect immediately*/
15905 if (hdd_connIsConnected(pHddStaCtx) &&
15906 (NV_CHANNEL_DFS ==
15907 vos_nv_getChannelEnabledState(
15908 pHddStaCtx->conn_info.operationChannel)))
15909 {
15910 status = sme_RoamDisconnect(pHddCtx->hHal,
15911 pAdapter->sessionId,
15912 eCSR_DISCONNECT_REASON_UNSPECIFIED);
15913 hddLog(LOG1, FL("Client connected on DFS channel %d,"
15914 "sme_RoamDisconnect returned with status: %d"
15915 "for sessionid: %d"), pHddStaCtx->conn_info.
15916 operationChannel, status, pAdapter->sessionId);
15917 }
15918 }
15919
15920 vosStatus = hdd_get_next_adapter(pHddCtx, pAdapterNode,
15921 &pNext);
15922 pAdapterNode = pNext;
15923 }
15924 }
15925
15926 sme_UpdateDFSScanMode(pHddCtx->hHal, dfsScanMode);
15927 sme_UpdateDFSRoamMode(pHddCtx->hHal,
15928 (dfsScanMode != DFS_CHNL_SCAN_DISABLED));
15929
15930 status = sme_HandleDFSChanScan(pHddCtx->hHal);
15931 if (!HAL_STATUS_SUCCESS(status))
15932 {
15933 hddLog(LOGE,
15934 FL("Failed in sme_HandleDFSChanScan (err=%d)"), status);
15935 return status;
15936 }
15937
15938 return status;
15939}
15940
Nirav Shah7e3c8132015-06-22 23:51:42 +053015941static int hdd_log2_ceil(unsigned value)
15942{
15943 /* need to switch to unsigned math so that negative values
15944 * will right-shift towards 0 instead of -1
15945 */
15946 unsigned tmp = value;
15947 int log2 = -1;
15948
15949 if (value == 0)
15950 return 0;
15951
15952 while (tmp) {
15953 log2++;
15954 tmp >>= 1;
15955 }
15956 if (1U << log2 != value)
15957 log2++;
15958
15959 return log2;
15960}
15961
15962/**
15963 * hdd_sta_id_hash_attach() - initialize sta id to macaddr hash
15964 * @pAdapter: adapter handle
15965 *
15966 * Return: vos status
15967 */
15968VOS_STATUS hdd_sta_id_hash_attach(hdd_adapter_t *pAdapter)
15969{
15970 int hash_elem, log2, i;
15971
15972 spin_lock_bh( &pAdapter->sta_hash_lock);
15973 if (pAdapter->is_sta_id_hash_initialized == VOS_TRUE) {
15974 spin_unlock_bh( &pAdapter->sta_hash_lock);
15975 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15976 "%s: hash already attached for session id %d",
15977 __func__, pAdapter->sessionId);
15978 return VOS_STATUS_SUCCESS;
15979 }
15980 spin_unlock_bh( &pAdapter->sta_hash_lock);
15981
15982 hash_elem = WLAN_MAX_STA_COUNT;
15983 hash_elem *= HDD_STA_ID_HASH_MULTIPLIER;
15984 log2 = hdd_log2_ceil(hash_elem);
15985 hash_elem = 1 << log2;
15986
15987 pAdapter->sta_id_hash.mask = hash_elem - 1;
15988 pAdapter->sta_id_hash.idx_bits = log2;
15989 pAdapter->sta_id_hash.bins =
15990 vos_mem_malloc(hash_elem *sizeof(hdd_list_t));
15991 if (!pAdapter->sta_id_hash.bins) {
15992 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15993 "%s: malloc failed for session %d",
15994 __func__, pAdapter->sessionId);
15995 return VOS_STATUS_E_NOMEM;
15996 }
15997
15998 for (i = 0; i < hash_elem; i++)
15999 hdd_list_init(&pAdapter->sta_id_hash.bins[i], WLAN_MAX_STA_COUNT);
16000
16001 spin_lock_bh( &pAdapter->sta_hash_lock);
16002 pAdapter->is_sta_id_hash_initialized = VOS_TRUE;
16003 spin_unlock_bh( &pAdapter->sta_hash_lock);
16004 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16005 "%s: Station ID Hash attached for session id %d",
16006 __func__, pAdapter->sessionId);
16007
16008 return VOS_STATUS_SUCCESS;
16009}
16010
16011/**
16012 * hdd_sta_id_hash_detach() - deinit sta_id to macaddr hash
16013 * @pAdapter: adapter handle
16014 *
16015 * Return: vos status
16016 */
16017VOS_STATUS hdd_sta_id_hash_detach(hdd_adapter_t *pAdapter)
16018{
16019 int hash_elem, i;
16020 v_SIZE_t size;
16021
16022 spin_lock_bh( &pAdapter->sta_hash_lock);
16023 if (pAdapter->is_sta_id_hash_initialized != VOS_TRUE) {
16024 spin_unlock_bh( &pAdapter->sta_hash_lock);
16025 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16026 "%s: hash not initialized for session id %d",
16027 __func__, pAdapter->sessionId);
16028 return VOS_STATUS_SUCCESS;
16029 }
16030
16031 pAdapter->is_sta_id_hash_initialized = VOS_FALSE;
16032 spin_unlock_bh( &pAdapter->sta_hash_lock);
16033
16034 hash_elem = 1 << pAdapter->sta_id_hash.idx_bits;
16035
16036 /* free all station info*/
16037 for (i = 0; i < hash_elem; i++) {
16038 hdd_list_size(&pAdapter->sta_id_hash.bins[i], &size);
16039 if (size != 0) {
16040 VOS_STATUS status;
16041 hdd_staid_hash_node_t *sta_info_node = NULL;
16042 hdd_staid_hash_node_t *next_node = NULL;
16043 status = hdd_list_peek_front ( &pAdapter->sta_id_hash.bins[i],
16044 (hdd_list_node_t**) &sta_info_node );
16045
16046 while ( NULL != sta_info_node && VOS_STATUS_SUCCESS == status )
16047 {
16048 status = hdd_list_remove_node( &pAdapter->sta_id_hash.bins[i],
16049 &sta_info_node->node);
16050 vos_mem_free(sta_info_node);
16051
16052 status = hdd_list_peek_next (&pAdapter->sta_id_hash.bins[i],
16053 (hdd_list_node_t*)sta_info_node,
16054 (hdd_list_node_t**)&next_node);
16055 sta_info_node = next_node;
16056 }
16057 }
16058 }
16059
16060 vos_mem_free(pAdapter->sta_id_hash.bins);
16061 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16062 "%s: Station ID Hash detached for session id %d",
16063 __func__, pAdapter->sessionId);
16064 return VOS_STATUS_SUCCESS;
16065}
16066
16067/**
16068 * hdd_sta_id_hash_calculate_index() - derive index from macaddr
16069 * @pAdapter: adapter handle
16070 * @mac_addr_in: input mac address
16071 *
16072 * Return: index derived from mac address
16073 */
16074int hdd_sta_id_hash_calculate_index(hdd_adapter_t *pAdapter,
16075 v_MACADDR_t *mac_addr_in)
16076{
16077 uint16 index;
16078 struct hdd_align_mac_addr_t * mac_addr =
16079 (struct hdd_align_mac_addr_t *)mac_addr_in;
16080
16081 index = mac_addr->bytes_ab ^
16082 mac_addr->bytes_cd ^ mac_addr->bytes_ef;
16083 index ^= index >> pAdapter->sta_id_hash.idx_bits;
16084 index &= pAdapter->sta_id_hash.mask;
16085 return index;
16086}
16087
16088/**
16089 * hdd_sta_id_hash_add_entry() - add entry in hash
16090 * @pAdapter: adapter handle
16091 * @sta_id: station id
16092 * @mac_addr: mac address
16093 *
16094 * Return: vos status
16095 */
16096VOS_STATUS hdd_sta_id_hash_add_entry(hdd_adapter_t *pAdapter,
16097 v_U8_t sta_id, v_MACADDR_t *mac_addr)
16098{
16099 uint16 index;
16100 hdd_staid_hash_node_t *sta_info_node = NULL;
16101
Nirav Shah7e3c8132015-06-22 23:51:42 +053016102 index = hdd_sta_id_hash_calculate_index(pAdapter, mac_addr);
16103 sta_info_node = vos_mem_malloc(sizeof(hdd_staid_hash_node_t));
16104 if (!sta_info_node) {
Nirav Shah7e3c8132015-06-22 23:51:42 +053016105 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16106 "%s: malloc failed", __func__);
16107 return VOS_STATUS_E_NOMEM;
16108 }
16109
16110 sta_info_node->sta_id = sta_id;
16111 vos_mem_copy(&sta_info_node->mac_addr, mac_addr, sizeof(v_MACADDR_t));
16112
Nirav Shah303ed5c2015-08-24 10:29:25 +053016113 spin_lock_bh( &pAdapter->sta_hash_lock);
16114 if (pAdapter->is_sta_id_hash_initialized != VOS_TRUE) {
16115 spin_unlock_bh( &pAdapter->sta_hash_lock);
16116 vos_mem_free(sta_info_node);
16117 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16118 "%s: hash is not initialized for session id %d",
16119 __func__, pAdapter->sessionId);
16120 return VOS_STATUS_E_FAILURE;
16121 }
16122
Nirav Shah7e3c8132015-06-22 23:51:42 +053016123 hdd_list_insert_back ( &pAdapter->sta_id_hash.bins[index],
16124 (hdd_list_node_t*) sta_info_node );
16125 spin_unlock_bh( &pAdapter->sta_hash_lock);
16126 return VOS_STATUS_SUCCESS;
16127}
16128
16129/**
16130 * hdd_sta_id_hash_remove_entry() - remove entry from hash
16131 * @pAdapter: adapter handle
16132 * @sta_id: station id
16133 * @mac_addr: mac address
16134 *
16135 * Return: vos status
16136 */
16137VOS_STATUS hdd_sta_id_hash_remove_entry(hdd_adapter_t *pAdapter,
16138 v_U8_t sta_id, v_MACADDR_t *mac_addr)
16139{
16140 uint16 index;
16141 VOS_STATUS status;
16142 hdd_staid_hash_node_t *sta_info_node = NULL;
16143 hdd_staid_hash_node_t *next_node = NULL;
16144
16145 spin_lock_bh( &pAdapter->sta_hash_lock);
16146 if (pAdapter->is_sta_id_hash_initialized != VOS_TRUE) {
16147 spin_unlock_bh( &pAdapter->sta_hash_lock);
16148 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16149 "%s: hash is not initialized for session id %d",
16150 __func__, pAdapter->sessionId);
16151 return VOS_STATUS_E_FAILURE;
16152 }
16153
16154 index = hdd_sta_id_hash_calculate_index(pAdapter, mac_addr);
16155 status = hdd_list_peek_front ( &pAdapter->sta_id_hash.bins[index],
16156 (hdd_list_node_t**) &sta_info_node );
16157
16158 while ( NULL != sta_info_node && VOS_STATUS_SUCCESS == status )
16159 {
16160 if (sta_info_node->sta_id == sta_id) {
16161 status = hdd_list_remove_node( &pAdapter->sta_id_hash.bins[index],
16162 &sta_info_node->node);
16163 vos_mem_free(sta_info_node);
16164 break;
16165 }
16166 status = hdd_list_peek_next (&pAdapter->sta_id_hash.bins[index],
16167 (hdd_list_node_t*)sta_info_node, (hdd_list_node_t**)&next_node);
16168 sta_info_node = next_node;
16169 }
16170 spin_unlock_bh( &pAdapter->sta_hash_lock);
16171 return status;
16172}
16173
16174/**
16175 * hdd_sta_id_find_from_mac_addr() - find sta id from mac address
16176 * @pAdapter: adapter handle
16177 * @mac_addr_in: mac address
16178 *
16179 * Return: station id
16180 */
16181int hdd_sta_id_find_from_mac_addr(hdd_adapter_t *pAdapter,
16182 v_MACADDR_t *mac_addr_in)
16183{
16184 uint8 is_found = 0;
16185 uint8 sta_id = HDD_WLAN_INVALID_STA_ID;
16186 uint16 index;
16187 VOS_STATUS status;
16188 hdd_staid_hash_node_t *sta_info_node = NULL;
16189 hdd_staid_hash_node_t *next_node = NULL;
16190
16191 spin_lock_bh( &pAdapter->sta_hash_lock);
16192 if (pAdapter->is_sta_id_hash_initialized != VOS_TRUE) {
16193 spin_unlock_bh( &pAdapter->sta_hash_lock);
Bhargav Shahce3b32c2015-08-10 12:29:24 +053016194 hddLog(VOS_TRACE_LEVEL_INFO,
Nirav Shah7e3c8132015-06-22 23:51:42 +053016195 FL("hash is not initialized for session id %d"),
16196 pAdapter->sessionId);
16197 return HDD_WLAN_INVALID_STA_ID;
16198 }
16199
16200 index = hdd_sta_id_hash_calculate_index(pAdapter, mac_addr_in);
16201 status = hdd_list_peek_front ( &pAdapter->sta_id_hash.bins[index],
16202 (hdd_list_node_t**) &sta_info_node );
16203
16204 while ( NULL != sta_info_node && VOS_STATUS_SUCCESS == status )
16205 {
16206 if (vos_mem_compare(&sta_info_node->mac_addr,
16207 mac_addr_in, sizeof(v_MACADDR_t))) {
16208 is_found = 1;
16209 sta_id = sta_info_node->sta_id;
16210 break;
16211 }
16212 status = hdd_list_peek_next (&pAdapter->sta_id_hash.bins[index],
16213 (hdd_list_node_t*)sta_info_node,
16214 (hdd_list_node_t**)&next_node);
16215 sta_info_node = next_node;
16216 }
16217 spin_unlock_bh( &pAdapter->sta_hash_lock);
16218 return sta_id;
16219}
16220
c_manjeecfd1efb2015-09-25 19:32:34 +053016221/*FW memory dump feature*/
16222/**
16223 * This structure hold information about the /proc file
16224 *
16225 */
16226static struct proc_dir_entry *proc_file, *proc_dir;
16227
16228/**
16229 * memdump_read() - perform read operation in memory dump proc file
16230 *
16231 * @file - handle for the proc file.
16232 * @buf - pointer to user space buffer.
16233 * @count - number of bytes to be read.
16234 * @pos - offset in the from buffer.
16235 *
16236 * This function performs read operation for the memory dump proc file.
16237 *
16238 * Return: number of bytes read on success, error code otherwise.
16239 */
16240static ssize_t memdump_read(struct file *file, char __user *buf,
16241 size_t count, loff_t *pos)
16242{
16243 int status;
16244 hdd_context_t *hdd_ctx = (hdd_context_t *)PDE_DATA(file_inode(file));
16245 size_t ret_count;
c_manjeef1495642015-10-13 18:35:01 +053016246 loff_t bytes_left;
c_manjeecfd1efb2015-09-25 19:32:34 +053016247 ENTER();
16248
16249 hddLog(LOG1, FL("Read req for size:%zu pos:%llu"), count, *pos);
16250 status = wlan_hdd_validate_context(hdd_ctx);
16251 if (0 != status) {
16252 return -EINVAL;
16253 }
16254
16255 if (!wlan_fwr_mem_dump_test_and_set_read_allowed_bit()) {
16256 hddLog(LOGE, FL("Current mem dump request timed out/failed"));
16257 return -EINVAL;
16258 }
16259
16260 /* run fs_read_handler in an atomic context*/
16261 vos_ssr_protect(__func__);
c_manjeef1495642015-10-13 18:35:01 +053016262 ret_count = wlan_fwr_mem_dump_fsread_handler( buf, count, pos, &bytes_left);
16263 if(bytes_left == 0)
c_manjeecfd1efb2015-09-25 19:32:34 +053016264 {
16265 /*Free the fwr mem dump buffer */
16266 wlan_free_fwr_mem_dump_buffer();
16267 wlan_set_fwr_mem_dump_state(FW_MEM_DUMP_IDLE);
c_manjeef1495642015-10-13 18:35:01 +053016268 ret_count=0;
c_manjeecfd1efb2015-09-25 19:32:34 +053016269 }
16270 /*if SSR/unload code is waiting for memdump_read to finish,signal it*/
16271 vos_ssr_unprotect(__func__);
16272 EXIT();
16273 return ret_count;
16274}
16275
16276/**
16277 * struct memdump_fops - file operations for memory dump feature
16278 * @read - read function for memory dump operation.
16279 *
16280 * This structure initialize the file operation handle for memory
16281 * dump feature
16282 */
16283static const struct file_operations memdump_fops = {
16284 read: memdump_read
16285};
16286
Hanumanth Reddy Pothulae856bc22018-04-11 15:35:36 +053016287struct fw_mem_dump_priv {
16288 uint32_t status;
16289};
16290
c_manjeecfd1efb2015-09-25 19:32:34 +053016291/*
16292* wlan_hdd_fw_mem_dump_cb : callback for Fw mem dump request
16293* To be passed by HDD to WDA and called upon receiving of response
16294* from firmware
16295* @fwMemDumpReqContext : memory dump request context
16296* @dump_rsp : dump response from HAL
16297* Returns none
16298*/
Hanumanth Reddy Pothulae856bc22018-04-11 15:35:36 +053016299void wlan_hdd_fw_mem_dump_cb(void *context,
c_manjeecfd1efb2015-09-25 19:32:34 +053016300 tAniFwrDumpRsp *dump_rsp)
16301{
Hanumanth Reddy Pothulae856bc22018-04-11 15:35:36 +053016302 struct hdd_request *request;
16303 struct fw_mem_dump_priv *priv;
c_manjeecfd1efb2015-09-25 19:32:34 +053016304
Hanumanth Reddy Pothulae856bc22018-04-11 15:35:36 +053016305 request = hdd_request_get(context);
16306 if (!request) {
16307 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Obsolete request"));
16308 return;
16309 }
c_manjeecfd1efb2015-09-25 19:32:34 +053016310
Hanumanth Reddy Pothulae856bc22018-04-11 15:35:36 +053016311 ENTER();
16312
16313 priv = hdd_request_priv(request);
16314 priv->status = dump_rsp->dump_status;
16315
16316 /* report the status to requesting function and free mem.*/
16317 if (dump_rsp->dump_status != eHAL_STATUS_SUCCESS) {
16318 hddLog(LOGE, FL("fw dump request declined by fwr"));
16319 //set the request completion variable
16320 hdd_request_complete(request);
16321 //Free the allocated fwr dump
16322 wlan_free_fwr_mem_dump_buffer();
16323 wlan_set_fwr_mem_dump_state(FW_MEM_DUMP_IDLE);
16324 } else {
16325 hddLog(LOG1, FL("fw dump request accepted by fwr"));
16326 /* register the HDD callback which will be called by SVC */
16327 wlan_set_svc_fw_mem_dump_req_cb(
16328 (void*)wlan_hdd_fw_mem_dump_req_cb,
16329 context);
16330 }
16331
16332 hdd_request_put(request);
16333
16334 EXIT();
c_manjeecfd1efb2015-09-25 19:32:34 +053016335}
16336
16337/**
16338 * memdump_procfs_remove() - Remove file/dir under procfs for memory dump
16339 *
16340 * This function removes file/dir under proc file system that was
16341 * processing firmware memory dump
16342 *
16343 * Return: None
16344 */
16345static void memdump_procfs_remove(void)
16346{
16347 remove_proc_entry(PROCFS_MEMDUMP_NAME, proc_dir);
16348 hddLog(LOG1 , FL("/proc/%s/%s removed\n"),
16349 PROCFS_MEMDUMP_DIR, PROCFS_MEMDUMP_NAME);
16350 remove_proc_entry(PROCFS_MEMDUMP_DIR, NULL);
16351 hddLog(LOG1 , FL("/proc/%s removed\n"), PROCFS_MEMDUMP_DIR);
16352}
16353
16354/**
16355 * memdump_procfs_init() - Initialize procfs for memory dump
16356 *
16357 * @vos_ctx - Global vos context.
16358 *
16359 * This function create file under proc file system to be used later for
16360 * processing firmware memory dump
16361 *
16362 * Return: 0 on success, error code otherwise.
16363 */
16364static int memdump_procfs_init(void *vos_ctx)
16365{
16366 hdd_context_t *hdd_ctx;
16367
16368 hdd_ctx = vos_get_context(VOS_MODULE_ID_HDD, vos_ctx);
16369 if (!hdd_ctx) {
16370 hddLog(LOGE , FL("Invalid HDD context"));
16371 return -EINVAL;
16372 }
16373
16374 proc_dir = proc_mkdir(PROCFS_MEMDUMP_DIR, NULL);
16375 if (proc_dir == NULL) {
16376 remove_proc_entry(PROCFS_MEMDUMP_DIR, NULL);
16377 hddLog(LOGE , FL("Error: Could not initialize /proc/%s"),
16378 PROCFS_MEMDUMP_DIR);
16379 return -ENOMEM;
16380 }
16381
16382 proc_file = proc_create_data(PROCFS_MEMDUMP_NAME,
16383 S_IRUSR | S_IWUSR, proc_dir,
16384 &memdump_fops, hdd_ctx);
16385 if (proc_file == NULL) {
16386 remove_proc_entry(PROCFS_MEMDUMP_NAME, proc_dir);
16387 hddLog(LOGE , FL("Error: Could not initialize /proc/%s"),
16388 PROCFS_MEMDUMP_NAME);
16389 return -ENOMEM;
16390 }
16391
16392 hddLog(LOG1 , FL("/proc/%s/%s created"),
16393 PROCFS_MEMDUMP_DIR, PROCFS_MEMDUMP_NAME);
16394
16395 return 0;
16396}
16397
16398/**
16399 * memdump_init() - Initialization function for memory dump feature
16400 *
16401 * This function creates proc file for memdump feature and registers
16402 * HDD callback function with SME.
16403 *
16404 * Return - 0 on success, error otherwise
16405 */
16406int memdump_init(void)
16407{
16408 hdd_context_t *hdd_ctx;
16409 void *vos_ctx;
16410 int status = 0;
16411
16412 vos_ctx = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
16413 if (!vos_ctx) {
16414 hddLog(LOGE, FL("Invalid VOS context"));
16415 return -EINVAL;
16416 }
16417
16418 hdd_ctx = vos_get_context(VOS_MODULE_ID_HDD, vos_ctx);
16419 if (!hdd_ctx) {
16420 hddLog(LOGE , FL("Invalid HDD context"));
16421 return -EINVAL;
16422 }
16423
16424 status = memdump_procfs_init(vos_ctx);
16425 if (status) {
16426 hddLog(LOGE , FL("Failed to create proc file"));
16427 return status;
16428 }
16429
16430 return 0;
16431}
16432
16433/**
16434 * memdump_deinit() - De initialize memdump feature
16435 *
16436 * This function removes proc file created for memdump feature.
16437 *
16438 * Return: None
16439 */
16440int memdump_deinit(void)
16441{
16442 hdd_context_t *hdd_ctx;
16443 void *vos_ctx;
16444
16445 vos_ctx = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
16446 if (!vos_ctx) {
16447 hddLog(LOGE, FL("Invalid VOS context"));
16448 return -EINVAL;
16449 }
16450
16451 hdd_ctx = vos_get_context(VOS_MODULE_ID_HDD, vos_ctx);
16452 if(!hdd_ctx) {
16453 hddLog(LOGE , FL("Invalid HDD context"));
16454 return -EINVAL;
16455 }
16456
16457 memdump_procfs_remove();
16458 return 0;
16459}
16460
16461/**
16462 * wlan_hdd_fw_mem_dump_req(pHddCtx) - common API(cfg80211/ioctl) for requesting fw mem dump to SME
16463 * Return: HAL status
16464 */
16465
16466int wlan_hdd_fw_mem_dump_req(hdd_context_t * pHddCtx)
16467{
16468 tAniFwrDumpReq fw_mem_dump_req={0};
16469 eHalStatus status = eHAL_STATUS_FAILURE;
Hanumanth Reddy Pothulae856bc22018-04-11 15:35:36 +053016470 int ret=0, dump_status;
16471 void *cookie;
16472 struct hdd_request *request;
16473 struct fw_mem_dump_priv *priv;
16474 static const struct hdd_request_params params = {
16475 .priv_size = sizeof(*priv),
16476 .timeout_ms = FW_MEM_DUMP_TIMEOUT_MS,
16477 };
16478
c_manjeecfd1efb2015-09-25 19:32:34 +053016479 ENTER();
c_manjeef1495642015-10-13 18:35:01 +053016480
c_manjeecfd1efb2015-09-25 19:32:34 +053016481 /*Check whether a dump request is already going on
16482 *Caution this function will free previously held memory if new dump request is allowed*/
16483 if (!wlan_fwr_mem_dump_test_and_set_write_allowed_bit()) {
16484 hddLog(LOGE, FL("Fw memdump already in progress"));
16485 return -EBUSY;
16486 }
16487 //Allocate memory for fw mem dump buffer
16488 ret = wlan_fwr_mem_dump_buffer_allocation();
16489 if(ret == -EFAULT)
16490 {
16491 hddLog(LOGE, FL("Fwr mem dump not supported by FW"));
16492 return ret;
16493 }
16494 if (0 != ret) {
16495 hddLog(LOGE, FL("Fwr mem Allocation failed"));
16496 return -ENOMEM;
16497 }
Hanumanth Reddy Pothulae856bc22018-04-11 15:35:36 +053016498
16499 request = hdd_request_alloc(&params);
16500 if (!request) {
16501 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Request allocation failure"));
16502 return VOS_STATUS_E_NOMEM;
16503 }
16504 cookie = hdd_request_cookie(request);
c_manjeef1495642015-10-13 18:35:01 +053016505
c_manjeecfd1efb2015-09-25 19:32:34 +053016506 fw_mem_dump_req.fwMemDumpReqCallback = wlan_hdd_fw_mem_dump_cb;
Hanumanth Reddy Pothulae856bc22018-04-11 15:35:36 +053016507 fw_mem_dump_req.fwMemDumpReqContext = cookie;
c_manjeecfd1efb2015-09-25 19:32:34 +053016508 status = sme_FwMemDumpReq(pHddCtx->hHal, &fw_mem_dump_req);
16509 if(eHAL_STATUS_SUCCESS != status)
16510 {
16511 hddLog(VOS_TRACE_LEVEL_ERROR,
16512 "%s: fw_mem_dump_req failed ", __func__);
16513 wlan_free_fwr_mem_dump_buffer();
c_manjeef1495642015-10-13 18:35:01 +053016514 ret = -EFAULT;
16515 goto cleanup;
c_manjeecfd1efb2015-09-25 19:32:34 +053016516 }
c_manjeef1495642015-10-13 18:35:01 +053016517 /*wait for fw mem dump completion to send event to userspace*/
Hanumanth Reddy Pothulae856bc22018-04-11 15:35:36 +053016518 ret = hdd_request_wait_for_response(request);
16519 if (ret)
c_manjeef1495642015-10-13 18:35:01 +053016520 {
16521 hddLog(VOS_TRACE_LEVEL_ERROR,
Hanumanth Reddy Pothulae856bc22018-04-11 15:35:36 +053016522 "%s: fw_mem_dump_req timeout %d ", __func__,ret);
Abhishek Singh4eca9822015-12-09 18:07:34 +053016523 ret = -ETIMEDOUT;
Hanumanth Reddy Pothulae856bc22018-04-11 15:35:36 +053016524 }else {
16525 priv = hdd_request_priv(request);
16526 dump_status = priv->status;
c_manjeef1495642015-10-13 18:35:01 +053016527 }
16528cleanup:
Hanumanth Reddy Pothulae856bc22018-04-11 15:35:36 +053016529 hdd_request_put(request);
16530 if(!ret && !dump_status)
Abhishek Singh4eca9822015-12-09 18:07:34 +053016531 ret = -EFAULT;
c_manjeecfd1efb2015-09-25 19:32:34 +053016532
c_manjeef1495642015-10-13 18:35:01 +053016533 EXIT();
Abhishek Singh4eca9822015-12-09 18:07:34 +053016534 return ret;
c_manjeef1495642015-10-13 18:35:01 +053016535}
16536
16537/**
16538 * HDD callback which will be called by SVC to indicate mem dump completion.
16539 */
Hanumanth Reddy Pothulae856bc22018-04-11 15:35:36 +053016540void wlan_hdd_fw_mem_dump_req_cb(void *context)
c_manjeef1495642015-10-13 18:35:01 +053016541{
Hanumanth Reddy Pothulae856bc22018-04-11 15:35:36 +053016542 struct hdd_request *request;
16543 struct fw_mem_dump_priv *priv;
16544
16545 request = hdd_request_get(context);
16546 if (!request) {
16547 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Obsolete request"));
16548 return;
16549 }
16550
16551 priv = hdd_request_priv(request);
16552 priv->status = true;
16553
16554 hdd_request_complete(request);
16555 hdd_request_put(request);
c_manjeecfd1efb2015-09-25 19:32:34 +053016556}
16557
Mahesh A Saptasagar67ab9222015-10-21 15:38:41 +053016558void hdd_initialize_adapter_common(hdd_adapter_t *pAdapter)
16559{
16560 if (NULL == pAdapter)
16561 {
16562 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: pAdapter is NULL ", __func__);
16563 return;
16564 }
16565 init_completion(&pAdapter->session_open_comp_var);
16566 init_completion(&pAdapter->session_close_comp_var);
16567 init_completion(&pAdapter->disconnect_comp_var);
16568 init_completion(&pAdapter->linkup_event_var);
16569 init_completion(&pAdapter->cancel_rem_on_chan_var);
16570 init_completion(&pAdapter->rem_on_chan_ready_event);
16571 init_completion(&pAdapter->pno_comp_var);
16572#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
16573 init_completion(&pAdapter->offchannel_tx_event);
16574#endif
16575 init_completion(&pAdapter->tx_action_cnf_event);
16576#ifdef FEATURE_WLAN_TDLS
16577 init_completion(&pAdapter->tdls_add_station_comp);
16578 init_completion(&pAdapter->tdls_del_station_comp);
16579 init_completion(&pAdapter->tdls_mgmt_comp);
16580 init_completion(&pAdapter->tdls_link_establish_req_comp);
16581#endif
16582
16583#ifdef WLAN_FEATURE_RMC
16584 init_completion(&pAdapter->ibss_peer_info_comp);
16585#endif /* WLAN_FEATURE_RMC */
16586 init_completion(&pAdapter->ula_complete);
16587 init_completion(&pAdapter->change_country_code);
16588
16589#ifdef FEATURE_WLAN_BATCH_SCAN
16590 init_completion(&pAdapter->hdd_set_batch_scan_req_var);
16591 init_completion(&pAdapter->hdd_get_batch_scan_req_var);
16592#endif
Kapil Gupta2b44acb2016-12-30 16:49:51 +053016593 init_completion(&pAdapter->wlan_suspend_comp_var);
Mahesh A Saptasagar67ab9222015-10-21 15:38:41 +053016594
16595 return;
16596}
c_manjeecfd1efb2015-09-25 19:32:34 +053016597
Anurag Chouhan0b29de02016-12-16 13:18:40 +053016598#ifdef MDNS_OFFLOAD
16599
16600/**
16601 * hdd_mdns_enable_offload_done() - mdns enable offload response api
16602 * @padapter: holds adapter
16603 * @status: response status
16604 *
16605 * Return - None
16606 */
16607void hdd_mdns_enable_offload_done(void *padapter, VOS_STATUS status)
16608{
16609 hdd_adapter_t* adapter = (hdd_adapter_t*) padapter;
16610
16611 ENTER();
16612
16613 if (NULL == adapter)
16614 {
16615 hddLog(VOS_TRACE_LEVEL_ERROR,
16616 "%s: adapter is NULL",__func__);
16617 return;
16618 }
16619
16620 adapter->mdns_status.mdns_enable_status = status;
16621 vos_event_set(&adapter->mdns_status.vos_event);
16622 return;
16623}
16624
16625/**
16626 * hdd_mdns_fqdn_offload_done() - mdns fqdn offload response api
16627 * @padapter: holds adapter
16628 * @status: responce status
16629 *
16630 * Return - None
16631 */
16632void hdd_mdns_fqdn_offload_done(void *padapter, VOS_STATUS status)
16633{
16634 hdd_adapter_t* adapter = (hdd_adapter_t*) padapter;
16635
16636 ENTER();
16637
16638 if (NULL == adapter)
16639 {
16640 hddLog(VOS_TRACE_LEVEL_ERROR,
16641 "%s: adapter is NULL",__func__);
16642 return;
16643 }
16644
16645 adapter->mdns_status.mdns_fqdn_status = status;
16646 return;
16647}
16648
16649/**
16650 * hdd_mdns_resp_offload_done() - mdns resp offload response api
16651 * @padapter: holds adapter
16652 * @status: responce status
16653 *
16654 * Return - None
16655 */
16656void hdd_mdns_resp_offload_done(void *padapter, VOS_STATUS status)
16657{
16658 hdd_adapter_t* adapter = (hdd_adapter_t*) padapter;
16659
16660 ENTER();
16661
16662 if (NULL == adapter)
16663 {
16664 hddLog(VOS_TRACE_LEVEL_ERROR,
16665 "%s: adapter is NULL",__func__);
16666 return;
16667 }
16668
16669 adapter->mdns_status.mdns_resp_status = status;
16670 return;
16671}
16672
16673/**
16674 * wlan_hdd_mdns_process_response_dname() - Process mDNS domain name
16675 * @response: Pointer to a struct hdd_mdns_resp_info
16676 * @resp_info: Pointer to a struct tSirMDNSResponseInfo
16677 *
16678 * This function will pack the whole domain name without compression. It will
16679 * add the leading len for each field and add zero length octet to terminate
16680 * the domain name.
16681 *
16682 * Return: Return boolean. TRUE for success, FALSE for fail.
16683 */
16684static bool
16685wlan_hdd_mdns_process_response_dname(struct hdd_mdns_resp_info *response,
16686 sir_mdns_resp_info resp_info)
16687{
16688 uint8_t num;
16689 uint16_t idx;
16690 uint8_t len = 0;
16691
16692 if ((response == NULL) || (response->data == NULL) ||
16693 (response->offset == NULL)) {
16694 hddLog(LOGE, FL("Either data or offset in response is NULL!"));
16695 return FALSE;
16696 }
16697
16698 if ((resp_info == NULL) ||
16699 (resp_info->resp_len >= MAX_MDNS_RESP_LEN)) {
16700 hddLog(LOGE, FL("resp_len exceeds %d!"), MAX_MDNS_RESP_LEN);
16701 return FALSE;
16702 }
16703
16704 for (num = 0; num < response->num_entries; num++) {
16705 response->offset[num] =
16706 resp_info->resp_len + MDNS_HEADER_LEN;
16707 idx = num * MAX_LEN_DOMAINNAME_FIELD;
16708 len = strlen((char *)&response->data[idx]);
16709 if ((resp_info->resp_len + len + 1) >= MAX_MDNS_RESP_LEN) {
16710 hddLog(LOGE, FL("resp_len exceeds %d!"),
16711 MAX_MDNS_RESP_LEN);
16712 return FALSE;
16713 }
16714 resp_info->resp_data[resp_info->resp_len] = len;
16715 resp_info->resp_len++;
16716 vos_mem_copy(&resp_info->resp_data[resp_info->resp_len],
16717 &response->data[idx], len);
16718 resp_info->resp_len += len;
16719 }
16720
16721 /* The domain name terminates with the zero length octet */
16722 if (num == response->num_entries) {
16723 if (resp_info->resp_len >= MAX_MDNS_RESP_LEN) {
16724 hddLog(LOGE, FL("resp_len exceeds %d!"),
16725 MAX_MDNS_RESP_LEN);
16726 return FALSE;
16727 }
16728 resp_info->resp_data[resp_info->resp_len] = 0;
16729 resp_info->resp_len++;
16730 }
16731
16732 return TRUE;
16733}
16734
16735/**
16736 * wlan_hdd_mdns_format_response_u16() - Form uint16_t response data
16737 * @value: The uint16_t value is formed to the struct tSirMDNSResponseInfo
16738 * @resp_info: Pointer to a struct tSirMDNSResponseInfo
16739 *
16740 * Return: None
16741 */
16742static void wlan_hdd_mdns_format_response_u16(uint16_t value,
16743 sir_mdns_resp_info resp_info)
16744{
16745 uint8_t val_u8;
16746
16747 if ((resp_info == NULL) || (resp_info->resp_data == NULL))
16748 return;
16749 val_u8 = (value & 0xff00) >> 8;
16750 resp_info->resp_data[resp_info->resp_len++] = val_u8;
16751 val_u8 = value & 0xff;
16752 resp_info->resp_data[resp_info->resp_len++] = val_u8;
16753}
16754
16755/**
16756 * wlan_hdd_mdns_format_response_u32() - Form uint32_t response data
16757 * @value: The uint32_t value is formed to the struct tSirMDNSResponseInfo
16758 * @resp_info: Pointer to a struct tSirMDNSResponseInfo
16759 *
16760 * Return: None
16761 */
16762static void wlan_hdd_mdns_format_response_u32(uint32_t value,
16763 sir_mdns_resp_info resp_info)
16764{
16765 uint8_t val_u8;
16766
16767 if ((resp_info == NULL) || (resp_info->resp_data == NULL))
16768 return;
16769 val_u8 = (value & 0xff000000) >> 24;
16770 resp_info->resp_data[resp_info->resp_len++] = val_u8;
16771 val_u8 = (value & 0xff0000) >> 16;
16772 resp_info->resp_data[resp_info->resp_len++] = val_u8;
16773 val_u8 = (value & 0xff00) >> 8;
16774 resp_info->resp_data[resp_info->resp_len++] = val_u8;
16775 val_u8 = value & 0xff;
16776 resp_info->resp_data[resp_info->resp_len++] = val_u8;
16777}
16778
16779/**
16780 * wlan_hdd_mdns_process_response_misc() - Process misc info in mDNS response
16781 * @resp_type: Response type for mDNS
16782 * @resp_info: Pointer to a struct tSirMDNSResponseInfo
16783 *
16784 * This function will pack the response type, class and TTL (Time To Live).
16785 *
16786 * Return: Return boolean. TRUE for success, FALSE for fail.
16787 */
16788static bool wlan_hdd_mdns_process_response_misc(uint16_t resp_type,
16789 sir_mdns_resp_info resp_info)
16790{
16791 uint16_t len;
16792
16793 if (resp_info == NULL) {
16794 hddLog(LOGE, FL("resp_info is NULL!"));
16795 return FALSE;
16796 }
16797
16798 len = resp_info->resp_len + (2 * sizeof(uint16_t) + sizeof(uint32_t));
16799 if (len >= MAX_MDNS_RESP_LEN) {
16800 hddLog(LOGE, FL("resp_len exceeds %d!"), MAX_MDNS_RESP_LEN);
16801 return FALSE;
16802 }
16803
16804 /* Fill Type, Class, TTL */
16805 wlan_hdd_mdns_format_response_u16(resp_type, resp_info);
16806 wlan_hdd_mdns_format_response_u16(MDNS_CLASS, resp_info);
16807 wlan_hdd_mdns_format_response_u32(MDNS_TTL, resp_info);
16808
16809 return TRUE;
16810}
16811
16812/**
16813 * wlan_hdd_mdns_compress_data() - Compress the domain name in mDNS response
16814 * @resp_info: Pointer to a struct tSirMDNSResponseInfo
16815 * @response_dst: The response which domain name is compressed.
16816 * @response_src: The response which domain name is matched with response_dst.
16817 * Its offset is used for data compression.
16818 * @num_matched: The number of matched entries between response_dst and
16819 * response_src
16820 *
16821 * This function will form the different fields of domain name in response_dst
16822 * if any. Then use the offset of the matched domain name in response_src to
16823 * compress the matched domain name.
16824 *
16825 * Return: Return boolean. TRUE for success, FALSE for fail.
16826 */
16827static bool
16828wlan_hdd_mdns_compress_data(sir_mdns_resp_info resp_info,
16829 struct hdd_mdns_resp_info *response_dst,
16830 struct hdd_mdns_resp_info *response_src,
16831 uint8_t num_matched)
16832{
16833 uint8_t num, num_diff;
16834 uint16_t value, idx;
16835 uint8_t len = 0;
16836
16837 if ((response_src == NULL) || (response_dst == NULL) ||
16838 (resp_info == NULL)) {
16839 hddLog(LOGE, FL("response info is NULL!"));
16840 return FALSE;
16841 }
16842
16843 if (response_dst->num_entries < num_matched) {
16844 hddLog(LOGE, FL("num_entries is less than num_matched!"));
16845 return FALSE;
16846 }
16847
16848 if (resp_info->resp_len >= MAX_MDNS_RESP_LEN) {
16849 hddLog(LOGE, FL("resp_len exceeds %d!"), MAX_MDNS_RESP_LEN);
16850 return FALSE;
16851 }
16852
16853 num_diff = response_dst->num_entries - num_matched;
16854 if ((num_diff > 0) && (response_dst->data == NULL)) {
16855 hddLog(LOGE, FL("response_dst->data is NULL!"));
16856 return FALSE;
16857 }
16858
16859 /*
16860 * Handle the unmatched string at the beginning
16861 * Store the length of octets and the octets
16862 */
16863 for (num = 0; num < num_diff; num++) {
16864 response_dst->offset[num] =
16865 resp_info->resp_len + MDNS_HEADER_LEN;
16866 idx = num * MAX_LEN_DOMAINNAME_FIELD;
16867 len = strlen((char *)&response_dst->data[idx]);
16868 if ((resp_info->resp_len + len + 1) >= MAX_MDNS_RESP_LEN) {
16869 hddLog(LOGE, FL("resp_len exceeds %d!"),
16870 MAX_MDNS_RESP_LEN);
16871 return FALSE;
16872 }
16873 resp_info->resp_data[resp_info->resp_len] = len;
16874 resp_info->resp_len++;
16875 vos_mem_copy(&resp_info->resp_data[resp_info->resp_len],
16876 &response_dst->data[idx], len);
16877 resp_info->resp_len += len;
16878 }
16879 /*
16880 * Handle the matched string from the end
16881 * Just keep the offset and mask the leading two bit
16882 */
16883 if (response_src->num_entries >= num_matched) {
16884 num_diff = response_src->num_entries - num_matched;
16885 value = response_src->offset[num_diff];
16886 if (value > 0) {
16887 value |= 0xc000;
16888 if ((resp_info->resp_len + sizeof(uint16_t)) >=
16889 MAX_MDNS_RESP_LEN) {
16890 hddLog(LOGE, FL("resp_len exceeds %d!"),
16891 MAX_MDNS_RESP_LEN);
16892 return FALSE;
16893 }
16894 wlan_hdd_mdns_format_response_u16(value, resp_info);
16895 return TRUE;
16896 }
16897 }
16898 return FALSE;
16899}
16900
16901/**
16902 * wlan_hdd_mdns_reset_response() - Reset the response info
16903 * @response: The response which info is reset.
16904 *
16905 * Return: None
16906 */
16907static void wlan_hdd_mdns_reset_response(struct hdd_mdns_resp_info *response)
16908{
16909 if (response == NULL)
16910 return;
16911 response->num_entries = 0;
16912 response->data = NULL;
16913 response->offset = NULL;
16914}
16915
16916/**
16917 * wlan_hdd_mdns_init_response() - Initialize the response info
16918 * @response: The response which info is initiatized.
16919 * @resp_dname: The domain name string which might be tokenized.
16920 *
16921 * This function will allocate the memory for both response->data and
16922 * response->offset. Besides, it will also tokenize the domain name to some
16923 * entries and fill response->num_entries with the num of entries.
16924 *
16925 * Return: Return boolean. TRUE for success, FALSE for fail.
16926 */
16927static bool wlan_hdd_mdns_init_response(struct hdd_mdns_resp_info *response,
16928 uint8_t *resp_dname, char separator)
16929{
16930 uint16_t size;
16931
16932 if ((resp_dname == NULL) || (response == NULL)) {
16933 hddLog(LOGE, FL("resp_dname or response is NULL!"));
16934 return FALSE;
16935 }
16936
16937 size = MAX_NUM_FIELD_DOMAINNAME * MAX_LEN_DOMAINNAME_FIELD;
16938 response->data = vos_mem_malloc(size);
16939 if (response->data) {
16940 vos_mem_zero(response->data, size);
16941 if (VOS_STATUS_SUCCESS !=
16942 hdd_string_to_string_array((char *)resp_dname,
16943 response->data,
16944 separator,
16945 &response->num_entries,
16946 MAX_NUM_FIELD_DOMAINNAME,
16947 MAX_LEN_DOMAINNAME_FIELD)) {
16948 hddLog(LOGE, FL("hdd_string_to_string_array fail!"));
16949 goto err_init_resp;
16950 }
16951
16952 if ((response->num_entries > 0) &&
16953 (strlen((char *)&response->data[0]) > 0)) {
16954 size = sizeof(uint16_t) * response->num_entries;
16955 response->offset = vos_mem_malloc(size);
16956 if (response->offset) {
16957 vos_mem_zero(response->offset, size);
16958 return TRUE;
16959 }
16960 }
16961 }
16962
16963err_init_resp:
16964 if (response->data)
16965 vos_mem_free(response->data);
16966 wlan_hdd_mdns_reset_response(response);
16967 return FALSE;
16968}
16969
16970/**
16971 * wlan_hdd_mdns_find_entries_from_end() - Find the matched entries
16972 * @response1: The response info is used to be compared.
16973 * @response2: The response info is used to be compared.
16974 *
16975 * This function will find the matched entries from the end.
16976 *
16977 * Return: Return the number of the matched entries.
16978 */
16979static uint8_t
16980wlan_hdd_mdns_find_entries_from_end(struct hdd_mdns_resp_info *response1,
16981 struct hdd_mdns_resp_info *response2)
16982{
16983 uint8_t min, len1, i;
16984 uint16_t num1, num2;
16985 uint8_t num_matched = 0;
16986
16987 min = VOS_MIN(response1->num_entries, response2->num_entries);
16988
16989 for (i = 1; i <= min; i++) {
16990 num1 = (response1->num_entries - i);
16991 num1 *= MAX_LEN_DOMAINNAME_FIELD;
16992 num2 = (response2->num_entries - i);
16993 num2 *= MAX_LEN_DOMAINNAME_FIELD;
16994 len1 = strlen((char *)&response1->data[num1]);
16995
16996 if ((len1 == 0) ||
16997 (len1 != strlen((char *)&response2->data[num2])))
16998 break;
16999 if (memcmp(&response1->data[num1],
17000 &response2->data[num2], len1))
17001 break;
17002 else
17003 num_matched++;
17004 }
17005
17006 return num_matched;
17007}
17008
17009/**
17010 * wlan_hdd_mdns_find_max() - Find the maximum number of the matched entries
17011 * @matchedlist: Pointer to the array of struct hdd_mdns_resp_matched
17012 * @numlist: The number of the elements in the array matchedlist.
17013 *
17014 * Find the max number of the matched entries among the array matchedlist.
17015 *
17016 * Return: None
17017 */
17018static void wlan_hdd_mdns_find_max(struct hdd_mdns_resp_matched *matchedlist,
17019 uint8_t numlist)
17020{
17021 int j;
17022 struct hdd_mdns_resp_matched tmp;
17023
17024 /* At least two values are used for sorting */
17025 if ((numlist < 2) || (matchedlist == NULL)) {
17026 hddLog(LOGE, FL("At least two values are used for sorting!"));
17027 return;
17028 }
17029
17030 for (j = 0; j < numlist-1; j++) {
17031 if (matchedlist[j].num_matched >
17032 matchedlist[j+1].num_matched) {
17033 vos_mem_copy(&tmp, &matchedlist[j],
17034 sizeof(struct hdd_mdns_resp_matched));
17035 vos_mem_copy(&matchedlist[j], &matchedlist[j+1],
17036 sizeof(struct hdd_mdns_resp_matched));
17037 vos_mem_copy(&matchedlist[j+1], &tmp,
17038 sizeof(struct hdd_mdns_resp_matched));
17039 }
17040 }
17041}
17042
17043/**
17044 * wlan_hdd_mdns_pack_response_type_a() - Pack Type A response
17045 * @ini_config: Pointer to the struct hdd_config_t
17046 * @resp_info: Pointer to the struct tSirMDNSResponseInfo
17047 * @resptype_a: Pointer to the struct hdd_mdns_resp_info of Type A
17048 *
17049 * Type A response include QName, response type, class, TTL and Ipv4.
17050 *
17051 * Return: Return boolean. TRUE for success, FALSE for fail.
17052 */
17053static bool
17054wlan_hdd_mdns_pack_response_type_a(hdd_config_t *ini_config,
17055 sir_mdns_resp_info resp_info,
17056 struct hdd_mdns_resp_info *resptype_a)
17057{
17058 uint16_t value;
17059 uint32_t len;
17060
17061 ENTER();
17062 if ((ini_config == NULL) || (resp_info == NULL) ||
17063 (resptype_a == NULL)) {
17064 hddLog(LOGE, FL("ini_config or response info is NULL!"));
17065 return FALSE;
17066 }
17067
17068 /* No Type A response */
17069 if (strlen((char *)ini_config->mdns_resp_type_a) <= 0)
17070 return TRUE;
17071
17072 /* Wrong response is assigned, just ignore this response */
17073 if (!wlan_hdd_mdns_init_response(resptype_a,
17074 ini_config->mdns_resp_type_a, '.'))
17075 return TRUE;
17076
17077 /* Process response domain name */
17078 if (!wlan_hdd_mdns_process_response_dname(resptype_a, resp_info)) {
17079 hddLog(LOGE, FL("Fail to process mDNS response (%d)!"),
17080 MDNS_TYPE_A);
17081 return FALSE;
17082 }
17083
17084 /* Process response Type, Class, TTL */
17085 if (!wlan_hdd_mdns_process_response_misc(MDNS_TYPE_A, resp_info)) {
17086 hddLog(LOGE, FL("Fail to process mDNS misc response (%d)!"),
17087 MDNS_TYPE_A);
17088 return FALSE;
17089 }
17090
17091 /* Process response RDLength, RData */
17092 len = sizeof(uint16_t) + sizeof(uint32_t);
17093 len += resp_info->resp_len;
17094 if (len >= MAX_MDNS_RESP_LEN) {
17095 hddLog(LOGE, FL("resp_len exceeds %d!"), MAX_MDNS_RESP_LEN);
17096 return FALSE;
17097 }
17098 value = sizeof(uint32_t);
17099 wlan_hdd_mdns_format_response_u16(value, resp_info);
17100 wlan_hdd_mdns_format_response_u32(ini_config->mdns_resp_type_a_ipv4,
17101 resp_info);
17102
17103 EXIT();
17104 return TRUE;
17105}
17106
17107/**
17108 * wlan_hdd_mdns_pack_response_type_txt() - Pack Type Txt response
17109 * @ini_config: Pointer to the struct hdd_config_t
17110 * @resp_info: Pointer to the struct tSirMDNSResponseInfo
17111 * @resptype_txt: Pointer to the struct hdd_mdns_resp_info of Type txt
17112 * @resptype_a: Pointer to the struct hdd_mdns_resp_info of Type A
17113 *
17114 * Type Txt response include QName, response type, class, TTL and text content.
17115 * Also, it will find the matched QName from resptype_A and compress the data.
17116 *
17117 * Return: Return boolean. TRUE for success, FALSE for fail.
17118 */
17119static bool
17120wlan_hdd_mdns_pack_response_type_txt(hdd_config_t *ini_config,
17121 sir_mdns_resp_info resp_info,
17122 struct hdd_mdns_resp_info *resptype_txt,
17123 struct hdd_mdns_resp_info *resptype_a)
17124{
17125 uint8_t num_matched;
17126 uint8_t num;
17127 uint16_t idx;
17128 uint16_t value = 0;
17129 uint32_t len;
17130 uint32_t total_len;
17131 bool status;
17132 struct hdd_mdns_resp_info resptype_content;
17133
17134 ENTER();
17135
17136 if ((ini_config == NULL) || (resp_info == NULL) ||
17137 (resptype_txt == NULL)) {
17138 hddLog(LOGE, FL("ini_config or response info is NULL!"));
17139 return FALSE;
17140 }
17141
17142 /* No Type Txt response */
17143 if (strlen((char *)ini_config->mdns_resp_type_txt) <= 0)
17144 return TRUE;
17145
17146 /* Wrong response is assigned, just ignore this response */
17147 if (!wlan_hdd_mdns_init_response(resptype_txt,
17148 ini_config->mdns_resp_type_txt, '.'))
17149 return TRUE;
17150
17151 /*
17152 * For data compression
17153 * Check if any strings are matched with Type A response
17154 */
17155 if (resptype_a && (resptype_a->num_entries > 0)) {
17156 num_matched = wlan_hdd_mdns_find_entries_from_end(resptype_txt,
17157 resptype_a);
17158 if (num_matched > 0) {
17159 if (!wlan_hdd_mdns_compress_data(resp_info,
17160 resptype_txt, resptype_a, num_matched)) {
17161 hddLog(LOGE, FL("Fail to compress mDNS "
17162 "response (%d)!"), MDNS_TYPE_TXT);
17163 return FALSE;
17164 }
17165 } else {
17166 /*
17167 * num_matched is zero. Error!
17168 * At least ".local" is needed.
17169 */
17170 hddLog(LOGE, FL("No matched string! Fail to pack mDNS "
17171 "response (%d)!"), MDNS_TYPE_TXT);
17172 return FALSE;
17173 }
17174 } else {
17175 /* no TypeA response, so show the whole data */
17176 if (!wlan_hdd_mdns_process_response_dname(resptype_txt,
17177 resp_info)) {
17178 hddLog(LOGE, FL("Fail to process mDNS response (%d)!"),
17179 MDNS_TYPE_TXT);
17180 return FALSE;
17181 }
17182 }
17183
17184 /* Process response Type, Class, TTL */
17185 if (!wlan_hdd_mdns_process_response_misc(MDNS_TYPE_TXT, resp_info)) {
17186 hddLog(LOGE, FL("Fail to process mDNS misc response (%d)!"),
17187 MDNS_TYPE_TXT);
17188 return FALSE;
17189 }
17190
17191 /*
17192 * Process response RDLength, RData.
17193 * TypeTxt RData include len.
17194 */
17195 status = wlan_hdd_mdns_init_response(&resptype_content,
17196 ini_config->mdns_resp_type_txt_content,
17197 '/');
17198 if (status == FALSE) {
17199 hddLog(LOGE, FL("wlan_hdd_mdns_init_response FAIL"));
17200 return FALSE;
17201 }
17202
17203 for (num = 0; num < resptype_content.num_entries; num++) {
17204 idx = num * MAX_LEN_DOMAINNAME_FIELD;
17205 value += strlen((char *)&resptype_content.data[idx]);
17206 }
17207
17208 /* content len is uint16_t */
17209 total_len = sizeof(uint16_t);
17210 total_len += resp_info->resp_len + value +
17211 resptype_content.num_entries;
17212
17213 if (total_len >= MAX_MDNS_RESP_LEN) {
17214 hddLog(LOGE, FL("resp_len exceeds %d!"), MAX_MDNS_RESP_LEN);
17215 return FALSE;
17216 }
17217 wlan_hdd_mdns_format_response_u16(value + resptype_content.num_entries,
17218 resp_info);
17219
17220 for (num = 0; num < resptype_content.num_entries; num++) {
17221 idx = num * MAX_LEN_DOMAINNAME_FIELD;
17222 len = strlen((char *)&resptype_content.data[idx]);
17223 resp_info->resp_data[resp_info->resp_len] = len;
17224 resp_info->resp_len++;
17225
17226 vos_mem_copy(&resp_info->resp_data[resp_info->resp_len],
17227 &resptype_content.data[idx], len);
17228
17229 resp_info->resp_len += len;
17230 hddLog(LOG1, FL("index = %d, len = %d, str = %s"),
17231 num, len, &resptype_content.data[idx]);
17232 }
17233
17234 EXIT();
17235 return TRUE;
17236}
17237
17238/**
17239 * wlan_hdd_mdns_pack_response_type_ptr_dname() - Pack Type PTR domain name
17240 * @ini_config: Pointer to the struct hdd_config_t
17241 * @resp_info: Pointer to the struct tSirMDNSResponseInfo
17242 * @resptype_ptr_dn: Pointer to the struct hdd_mdns_resp_info of Type Ptr
17243 * domain name
17244 * @resptype_ptr: Pointer to the struct hdd_mdns_resp_info of Type Ptr
17245 * @resptype_txt: Pointer to the struct hdd_mdns_resp_info of Type Txt
17246 * @resptype_a: Pointer to the struct hdd_mdns_resp_info of Type A
17247 *
17248 * The Type Ptr response include Type PTR domain name in its data field.
17249 * Also, it will find the matched QName from the existing resptype_ptr,
17250 * resptype_txt, resptype_a and then compress the data.
17251 *
17252 * Return: Return boolean. TRUE for success, FALSE for fail.
17253 */
17254static bool
17255wlan_hdd_mdns_pack_response_type_ptr_dname(hdd_config_t *ini_config,
17256 sir_mdns_resp_info resp_info,
17257 struct hdd_mdns_resp_info *resptype_ptr_dn,
17258 struct hdd_mdns_resp_info *resptype_ptr,
17259 struct hdd_mdns_resp_info *resptype_txt,
17260 struct hdd_mdns_resp_info *resptype_a)
17261{
17262 uint8_t num_matched, numlist, size;
17263 struct hdd_mdns_resp_matched matchedlist[MAX_MDNS_RESP_TYPE-1];
17264 struct hdd_mdns_resp_info *resp;
17265
17266 if ((ini_config == NULL) || (resp_info == NULL) ||
17267 (resptype_ptr == NULL) || (resptype_ptr_dn == NULL)) {
17268 hddLog(LOGE, FL("ini_config or response info is NULL!"));
17269 return FALSE;
17270 }
17271
17272 /* No Type Ptr domain name response */
17273 if (strlen((char *)ini_config->mdns_resp_type_ptr_dname) <= 0)
17274 return TRUE;
17275
17276 /* Wrong response is assigned, just ignore this response */
17277 if (!wlan_hdd_mdns_init_response(resptype_ptr_dn,
17278 ini_config->mdns_resp_type_ptr_dname, '.'))
17279 return TRUE;
17280
17281 /*
17282 * For data compression
17283 * Check if any strings are matched with previous
17284 * response.
17285 */
17286 numlist = 0;
17287 size = (MAX_MDNS_RESP_TYPE-1);
17288 size *= sizeof(struct hdd_mdns_resp_matched);
17289 vos_mem_zero(matchedlist, size);
17290 num_matched = wlan_hdd_mdns_find_entries_from_end(resptype_ptr_dn,
17291 resptype_ptr);
17292 if (num_matched > 0) {
17293 matchedlist[numlist].num_matched = num_matched;
17294 matchedlist[numlist].type = MDNS_TYPE_PTR;
17295 numlist++;
17296 }
17297 if (resptype_txt && (resptype_txt->num_entries > 0)) {
17298 num_matched = wlan_hdd_mdns_find_entries_from_end(
17299 resptype_ptr_dn, resptype_txt);
17300 if (num_matched > 0) {
17301 matchedlist[numlist].num_matched = num_matched;
17302 matchedlist[numlist].type = MDNS_TYPE_TXT;
17303 numlist++;
17304 }
17305 }
17306 if (resptype_a && (resptype_a->num_entries > 0)) {
17307 num_matched = wlan_hdd_mdns_find_entries_from_end(
17308 resptype_ptr_dn,resptype_a);
17309 if (num_matched > 0) {
17310 matchedlist[numlist].num_matched = num_matched;
17311 matchedlist[numlist].type = MDNS_TYPE_A;
17312 numlist++;
17313 }
17314 }
17315 if (numlist > 0) {
17316 if (numlist > 1)
17317 wlan_hdd_mdns_find_max(matchedlist, numlist);
17318 resp = NULL;
17319 switch (matchedlist[numlist-1].type) {
17320 case MDNS_TYPE_A:
17321 resp = resptype_a;
17322 break;
17323 case MDNS_TYPE_TXT:
17324 resp = resptype_txt;
17325 break;
17326 case MDNS_TYPE_PTR:
17327 resp = resptype_ptr;
17328 break;
17329 default:
17330 hddLog(LOGE, FL("Fail to compress mDNS response "
17331 "(%d)!"), MDNS_TYPE_PTR_DNAME);
17332 return FALSE;
17333 }
17334 num_matched = matchedlist[numlist-1].num_matched;
17335 if (!wlan_hdd_mdns_compress_data(resp_info, resptype_ptr_dn,
17336 resp, num_matched)) {
17337 hddLog(LOGE, FL("Fail to compress mDNS response "
17338 "(%d)!"), MDNS_TYPE_PTR_DNAME);
17339 return FALSE;
17340 }
17341 } else {
17342 /* num = 0 -> no matched string */
17343 if (!wlan_hdd_mdns_process_response_dname(resptype_ptr_dn,
17344 resp_info)) {
17345 hddLog(LOGE, FL("Fail to process mDNS response (%d)!"),
17346 MDNS_TYPE_PTR_DNAME);
17347 return FALSE;
17348 }
17349 }
17350
17351 return TRUE;
17352}
17353
17354/**
17355 * wlan_hdd_mdns_pack_response_type_ptr() - Pack Type PTR response
17356 * @ini_config: Pointer to the struct hdd_config_t
17357 * @resp_info: Pointer to the struct tSirMDNSResponseInfo
17358 * @resptype_ptr: Pointer to the struct hdd_mdns_resp_info of Type Ptr
17359 * @resptype_ptr_dn: Pointer to the struct hdd_mdns_resp_info of Type Ptr
17360 * domain name
17361 * @resptype_txt: Pointer to the struct hdd_mdns_resp_info of Type Txt
17362 * @resptype_a: Pointer to the struct hdd_mdns_resp_info of Type A
17363 *
17364 * The Type Ptr response include QName, response type, class, TTL and
17365 * Type PTR domain name. Also, it will find the matched QName from the
17366 * existing resptype_txt, resptype_a and then compress the data.
17367 *
17368 * Return: Return boolean. TRUE for success, FALSE for fail.
17369 */
17370static bool
17371wlan_hdd_mdns_pack_response_type_ptr(hdd_config_t *ini_config,
17372 sir_mdns_resp_info resp_info,
17373 struct hdd_mdns_resp_info *resptype_ptr,
17374 struct hdd_mdns_resp_info *resptype_ptr_dn,
17375 struct hdd_mdns_resp_info *resptype_txt,
17376 struct hdd_mdns_resp_info *resptype_a)
17377{
17378 uint8_t num_matched, num_matched1;
17379 uint16_t value;
17380 uint8_t val_u8;
17381 uint32_t offset_data_len, len;
17382
17383 ENTER();
17384 if ((ini_config == NULL) || (resp_info == NULL) ||
17385 (resptype_ptr == NULL) || (resptype_ptr_dn == NULL)) {
17386 hddLog(LOGE, FL("ini_config or response info is NULL!"));
17387 return FALSE;
17388 }
17389
17390 /* No Type Ptr response */
17391 if (strlen((char *)ini_config->mdns_resp_type_ptr) <= 0)
17392 return TRUE;
17393
17394 /* Wrong response is assigned, just ignore this response */
17395 if (!wlan_hdd_mdns_init_response(resptype_ptr,
17396 ini_config->mdns_resp_type_ptr, '.'))
17397 return TRUE;
17398
17399 /*
17400 * For data compression
17401 * Check if any strings are matched with Type A response
17402 */
17403 num_matched = 0;
17404 num_matched1 = 0;
17405 if (resptype_a && (resptype_a->num_entries > 0)) {
17406 num_matched = wlan_hdd_mdns_find_entries_from_end(resptype_ptr,
17407 resptype_a);
17408 }
17409 if (resptype_txt && (resptype_txt->num_entries > 0)) {
17410 num_matched1 = wlan_hdd_mdns_find_entries_from_end(
17411 resptype_ptr, resptype_txt);
17412 }
17413 if ((num_matched != num_matched1) ||
17414 ((num_matched > 0) && (num_matched1 > 0))) {
17415 if (num_matched >= num_matched1) {
17416 if (!wlan_hdd_mdns_compress_data(resp_info,
17417 resptype_ptr, resptype_a, num_matched)) {
17418 hddLog(LOGE, FL("Fail to compress mDNS "
17419 "response (%d)!"), MDNS_TYPE_PTR);
17420 return FALSE;
17421 }
17422 } else {
17423 /* num_matched is less than num_matched1 */
17424 if (!wlan_hdd_mdns_compress_data(resp_info,
17425 resptype_ptr, resptype_txt, num_matched1)) {
17426 hddLog(LOGE, FL("Fail to compress mDNS "
17427 "response (%d)!"), MDNS_TYPE_PTR);
17428 return FALSE;
17429 }
17430 }
17431 } else {
17432 /*
17433 * Both num_matched and num_matched1 are zero.
17434 * no TypeA & TypeTxt
17435 */
17436 if (!wlan_hdd_mdns_process_response_dname(resptype_ptr,
17437 resp_info)) {
17438 hddLog(LOGE, FL("Fail to process mDNS response (%d)!"),
17439 MDNS_TYPE_PTR);
17440 return FALSE;
17441 }
17442 }
17443
17444 /* Process response Type, Class, TTL */
17445 if (!wlan_hdd_mdns_process_response_misc(MDNS_TYPE_PTR, resp_info)) {
17446 hddLog(LOGE, FL("Fail to process mDNS misc response (%d)!"),
17447 MDNS_TYPE_PTR);
17448 return FALSE;
17449 }
17450
17451 /*
17452 * Process response RDLength, RData (Ptr domain name)
17453 * Save the offset of RData length
17454 */
17455 offset_data_len = resp_info->resp_len;
17456 resp_info->resp_len += sizeof(uint16_t);
17457
17458 if (!wlan_hdd_mdns_pack_response_type_ptr_dname(ini_config, resp_info,
17459 resptype_ptr_dn, resptype_ptr,
17460 resptype_txt, resptype_a)) {
17461 return FALSE;
17462 }
17463 /* Set the RData length */
17464 len = offset_data_len + sizeof(uint16_t);
17465 if ((resptype_ptr_dn->num_entries > 0) &&
17466 (resp_info->resp_len > len)) {
17467 value = resp_info->resp_len - len;
17468 val_u8 = (value & 0xff00) >> 8;
17469 resp_info->resp_data[offset_data_len] = val_u8;
17470 val_u8 = value & 0xff;
17471 resp_info->resp_data[offset_data_len+1] = val_u8;
17472 } else {
17473 hddLog(LOGE, FL("Fail to process mDNS response (%d)!"),
17474 MDNS_TYPE_PTR);
17475 return FALSE;
17476 }
17477
17478 EXIT();
17479 return TRUE;
17480}
17481
17482/**
17483 * wlan_hdd_mdns_pack_response_type_srv_target()- Pack Type Service Target
17484 * @ini_config: Pointer to the struct hdd_config_t
17485 * @resp_info: Pointer to the struct tSirMDNSResponseInfo
17486 * @resptype_srv_tgt: Pointer to the struct hdd_mdns_resp_info of Type Srv
17487 * target
17488 * @resptype_srv: Pointer to the struct hdd_mdns_resp_info of Type Srv
17489 * @resptype_ptr: Pointer to the struct hdd_mdns_resp_info of Type Ptr
17490 * @resptype_ptr_dn: Pointer to the struct hdd_mdns_resp_info of Type Ptr
17491 * domain name
17492 * @resptype_txt: Pointer to the struct hdd_mdns_resp_info of Type Txt
17493 * @resptype_a: Pointer to the struct hdd_mdns_resp_info of Type A
17494 *
17495 * The Type service target is one of the data field in the Type SRV response.
17496 * Also, it will find the matched QName from the existing resptype_srv,
17497 * resptype_ptr, resptype_ptr_dn, resptype_txt, resptype_a and then compress
17498 * the data.
17499 *
17500 * Return: Return boolean. TRUE for success, FALSE for fail.
17501 */
17502static bool
17503wlan_hdd_mdns_pack_response_type_srv_target(hdd_config_t *ini_config,
17504 sir_mdns_resp_info resp_info,
17505 struct hdd_mdns_resp_info *resptype_srv_tgt,
17506 struct hdd_mdns_resp_info *resptype_srv,
17507 struct hdd_mdns_resp_info *resptype_ptr,
17508 struct hdd_mdns_resp_info *resptype_ptr_dn,
17509 struct hdd_mdns_resp_info *resptype_txt,
17510 struct hdd_mdns_resp_info *resptype_a)
17511{
17512 uint8_t num_matched, num, size;
17513 struct hdd_mdns_resp_matched matchedlist[MAX_MDNS_RESP_TYPE-1];
17514 struct hdd_mdns_resp_info *resp;
17515
17516 if ((ini_config == NULL) || (resp_info == NULL) ||
17517 (resptype_srv == NULL) || (resptype_srv_tgt == NULL)) {
17518 hddLog(LOGE, FL("ini_config or response info is NULL!"));
17519 return FALSE;
17520 }
17521
17522 /* No Type Srv Target response */
17523 if (strlen((char *)ini_config->mdns_resp_type_srv_target) <= 0)
17524 return TRUE;
17525
17526 /* Wrong response is assigned, just ignore this response */
17527 if (!wlan_hdd_mdns_init_response(resptype_srv_tgt,
17528 ini_config->mdns_resp_type_srv_target, '.'))
17529 return TRUE;
17530
17531 /*
17532 * For data compression
17533 * Check if any strings are matched with previous response.
17534 */
17535 num = 0;
17536 size = (MAX_MDNS_RESP_TYPE-1);
17537 size *= sizeof(struct hdd_mdns_resp_matched);
17538 vos_mem_zero(matchedlist, size);
17539 num_matched = wlan_hdd_mdns_find_entries_from_end(resptype_srv_tgt,
17540 resptype_srv);
17541 if (num_matched > 0) {
17542 matchedlist[num].num_matched = num_matched;
17543 matchedlist[num].type = MDNS_TYPE_SRV;
17544 num++;
17545 }
17546 if (resptype_ptr && (resptype_ptr->num_entries > 0)) {
17547 if (resptype_ptr_dn && (resptype_ptr_dn->num_entries > 0)) {
17548 num_matched = wlan_hdd_mdns_find_entries_from_end(
17549 resptype_srv_tgt, resptype_ptr_dn);
17550 if (num_matched > 0) {
17551 matchedlist[num].num_matched = num_matched;
17552 matchedlist[num].type = MDNS_TYPE_PTR_DNAME;
17553 num++;
17554 }
17555 }
17556 num_matched = wlan_hdd_mdns_find_entries_from_end(
17557 resptype_srv_tgt, resptype_ptr);
17558 if (num_matched > 0) {
17559 matchedlist[num].num_matched = num_matched;
17560 matchedlist[num].type = MDNS_TYPE_PTR;
17561 num++;
17562 }
17563 }
17564 if (resptype_txt && (resptype_txt->num_entries > 0)) {
17565 num_matched = wlan_hdd_mdns_find_entries_from_end(
17566 resptype_srv_tgt, resptype_txt);
17567 if (num_matched > 0) {
17568 matchedlist[num].num_matched = num_matched;
17569 matchedlist[num].type = MDNS_TYPE_TXT;
17570 num++;
17571 }
17572 }
17573 if (resptype_a && (resptype_a->num_entries > 0)) {
17574 num_matched = wlan_hdd_mdns_find_entries_from_end(
17575 resptype_srv_tgt, resptype_a);
17576 if (num_matched > 0) {
17577 matchedlist[num].num_matched = num_matched;
17578 matchedlist[num].type = MDNS_TYPE_A;
17579 num++;
17580 }
17581 }
17582 if (num > 0) {
17583 if (num > 1)
17584 wlan_hdd_mdns_find_max(matchedlist, num);
17585 resp = NULL;
17586 switch (matchedlist[num-1].type) {
17587 case MDNS_TYPE_A:
17588 resp = resptype_a;
17589 break;
17590 case MDNS_TYPE_TXT:
17591 resp = resptype_txt;
17592 break;
17593 case MDNS_TYPE_PTR:
17594 resp = resptype_ptr;
17595 break;
17596 case MDNS_TYPE_PTR_DNAME:
17597 resp = resptype_ptr_dn;
17598 break;
17599 case MDNS_TYPE_SRV:
17600 resp = resptype_srv;
17601 break;
17602 default:
17603 hddLog(LOGE, FL("Fail to compress mDNS response "
17604 "(%d)!"), MDNS_TYPE_SRV_TARGET);
17605 return FALSE;
17606 }
17607 num_matched = matchedlist[num-1].num_matched;
17608 if (!wlan_hdd_mdns_compress_data(resp_info, resptype_srv_tgt,
17609 resp, num_matched)) {
17610 hddLog(LOGE, FL("Fail to compress mDNS response "
17611 "(%d)!"), MDNS_TYPE_SRV_TARGET);
17612 return FALSE;
17613 }
17614 } else {
17615 /* num = 0 -> no matched string */
17616 if (!wlan_hdd_mdns_process_response_dname(resptype_srv_tgt,
17617 resp_info)) {
17618 hddLog(LOGE, FL("Fail to process mDNS response (%d)!"),
17619 MDNS_TYPE_SRV_TARGET);
17620 return FALSE;
17621 }
17622 }
17623
17624 return TRUE;
17625}
17626
17627/**
17628 * wlan_hdd_mdns_pack_response_type_srv()- Pack Type Service response
17629 * @ini_config: Pointer to the struct hdd_config_t
17630 * @resp_info: Pointer to the struct tSirMDNSResponseInfo
17631 * @resptype_srv: Pointer to the struct hdd_mdns_resp_info of Type Srv
17632 * @resptype_srv_tgt: Pointer to the struct hdd_mdns_resp_info of Type Srv
17633 * target
17634 * @resptype_ptr: Pointer to the struct hdd_mdns_resp_info of Type Ptr
17635 * @resptype_ptr_dn: Pointer to the struct hdd_mdns_resp_info of Type Ptr
17636 * domain name
17637 * @resptype_txt: Pointer to the struct hdd_mdns_resp_info of Type Txt
17638 * @resptype_a: Pointer to the struct hdd_mdns_resp_info of Type A
17639 *
17640 * The Type SRV (Service) response include QName, response type, class, TTL
17641 * and four kinds of data fields. Also, it will find the matched QName from
17642 * the existing resptype_ptr, resptype_ptr_dn, resptype_txt, resptype_a and
17643 * then compress the data.
17644 *
17645 * Return: Return boolean. TRUE for success, FALSE for fail.
17646 */
17647static bool
17648wlan_hdd_mdns_pack_response_type_srv(hdd_config_t *ini_config,
17649 sir_mdns_resp_info resp_info,
17650 struct hdd_mdns_resp_info *resptype_srv,
17651 struct hdd_mdns_resp_info *resptype_srv_tgt,
17652 struct hdd_mdns_resp_info *resptype_ptr,
17653 struct hdd_mdns_resp_info *resptype_ptr_dn,
17654 struct hdd_mdns_resp_info *resptype_txt,
17655 struct hdd_mdns_resp_info *resptype_a)
17656{
17657 uint8_t num_matched, num, size;
17658 uint16_t value;
17659 uint8_t val_u8;
17660 uint32_t offset_data_len, len;
17661 struct hdd_mdns_resp_info *resp;
17662 struct hdd_mdns_resp_matched matchedlist[MAX_MDNS_RESP_TYPE-1];
17663
17664 ENTER();
17665
17666 if ((ini_config == NULL) || (resp_info == NULL) ||
17667 (resptype_srv == NULL) || (resptype_srv_tgt == NULL)) {
17668 hddLog(LOGE, FL("ini_config or response info is NULL!"));
17669 return FALSE;
17670 }
17671
17672 /* No Type Srv response */
17673 if (strlen((char *)ini_config->mdns_resp_type_srv) <= 0)
17674 return TRUE;
17675
17676 /* Wrong response is assigned, just ignore this response */
17677 if (!wlan_hdd_mdns_init_response(resptype_srv,
17678 ini_config->mdns_resp_type_srv, '.'))
17679 return TRUE;
17680
17681 /*
17682 * For data compression
17683 * Check if any strings are matched with Type A response
17684 */
17685 num = 0;
17686 size = (MAX_MDNS_RESP_TYPE-1);
17687 size *= sizeof(struct hdd_mdns_resp_matched);
17688 vos_mem_zero(matchedlist, size);
17689 if (resptype_ptr && (resptype_ptr->num_entries > 0)) {
17690 if (resptype_ptr_dn && (resptype_ptr_dn->num_entries > 0)) {
17691 num_matched = wlan_hdd_mdns_find_entries_from_end(
17692 resptype_srv,
17693 resptype_ptr_dn);
17694 if (num_matched > 0) {
17695 matchedlist[num].num_matched = num_matched;
17696 matchedlist[num].type = MDNS_TYPE_PTR_DNAME;
17697 num++;
17698 }
17699 }
17700 num_matched = wlan_hdd_mdns_find_entries_from_end(resptype_srv,
17701 resptype_ptr);
17702 if (num_matched > 0) {
17703 matchedlist[num].num_matched = num_matched;
17704 matchedlist[num].type = MDNS_TYPE_PTR;
17705 num++;
17706 }
17707 }
17708 if (resptype_txt && (resptype_txt->num_entries > 0)) {
17709 num_matched = wlan_hdd_mdns_find_entries_from_end(resptype_srv,
17710 resptype_txt);
17711 if (num_matched > 0) {
17712 matchedlist[num].num_matched =num_matched;
17713 matchedlist[num].type = MDNS_TYPE_TXT;
17714 num++;
17715 }
17716 }
17717 if (resptype_a && (resptype_a->num_entries > 0)) {
17718 num_matched = wlan_hdd_mdns_find_entries_from_end(resptype_srv,
17719 resptype_a);
17720 if (num_matched > 0) {
17721 matchedlist[num].num_matched = num_matched;
17722 matchedlist[num].type = MDNS_TYPE_A;
17723 num++;
17724 }
17725 }
17726 if (num > 0) {
17727 if (num > 1)
17728 wlan_hdd_mdns_find_max(matchedlist, num);
17729 resp = NULL;
17730 switch (matchedlist[num-1].type) {
17731 case MDNS_TYPE_A:
17732 resp = resptype_a;
17733 break;
17734 case MDNS_TYPE_TXT:
17735 resp = resptype_txt;
17736 break;
17737 case MDNS_TYPE_PTR:
17738 resp = resptype_ptr;
17739 break;
17740 case MDNS_TYPE_PTR_DNAME:
17741 resp = resptype_ptr_dn;
17742 break;
17743 default:
17744 hddLog(LOGE, FL("Fail to compress mDNS response "
17745 "(%d)!"), MDNS_TYPE_SRV);
17746 return FALSE;
17747 }
17748 num_matched = matchedlist[num-1].num_matched;
17749 if (!wlan_hdd_mdns_compress_data(resp_info, resptype_srv,
17750 resp, num_matched)) {
17751 hddLog(LOGE, FL("Fail to compress mDNS response "
17752 "(%d)!"), MDNS_TYPE_SRV);
17753 return FALSE;
17754 }
17755 } else {
17756 /* num = 0 -> no matched string */
17757 if (!wlan_hdd_mdns_process_response_dname(resptype_srv,
17758 resp_info)) {
17759 hddLog(LOGE, FL("Fail to process mDNS response (%d)!"),
17760 MDNS_TYPE_SRV);
17761 return FALSE;
17762 }
17763 }
17764
17765 /* Process response Type, Class, TTL */
17766 if (!wlan_hdd_mdns_process_response_misc(MDNS_TYPE_SRV, resp_info)) {
17767 hddLog(LOGE, FL("Fail to process mDNS misc response (%d)!"),
17768 MDNS_TYPE_SRV);
17769 return FALSE;
17770 }
17771
17772 /*
17773 * Process response RDLength, RData (Srv target name)
17774 * Save the offset of RData length
17775 */
17776 offset_data_len = resp_info->resp_len;
17777 resp_info->resp_len += sizeof(uint16_t);
17778
17779 len = resp_info->resp_len + (3 * sizeof(uint16_t));
17780 if (len >= MAX_MDNS_RESP_LEN) {
17781 hddLog(LOGE, FL("resp_len exceeds %d!"), MAX_MDNS_RESP_LEN);
17782 return FALSE;
17783 }
17784
17785 /* set Srv Priority */
17786 value = ini_config->mdns_resp_type_srv_priority;
17787 wlan_hdd_mdns_format_response_u16(value, resp_info);
17788 /* set Srv Weight */
17789 value = ini_config->mdns_resp_type_srv_weight;
17790 wlan_hdd_mdns_format_response_u16(value, resp_info);
17791 /* set Srv Port */
17792 value = ini_config->mdns_resp_type_srv_port;
17793 wlan_hdd_mdns_format_response_u16(value, resp_info);
17794
17795 if (!wlan_hdd_mdns_pack_response_type_srv_target(ini_config, resp_info,
17796 resptype_srv_tgt, resptype_srv,
17797 resptype_ptr, resptype_ptr_dn,
17798 resptype_txt, resptype_a)) {
17799 return FALSE;
17800 }
17801 /* Set the RData length */
17802 len = offset_data_len + sizeof(uint16_t);
17803 if ((resptype_srv_tgt->num_entries > 0) &&
17804 (resp_info->resp_len > len)) {
17805 value = resp_info->resp_len - len;
17806 val_u8 = (value & 0xff00) >> 8;
17807 resp_info->resp_data[offset_data_len] = val_u8;
17808 val_u8 = value & 0xff;
17809 resp_info->resp_data[offset_data_len+1] = val_u8;
17810 } else {
17811 hddLog(LOGE, FL("Fail to process mDNS response (%d)!"),
17812 MDNS_TYPE_SRV);
17813 return FALSE;
17814 }
17815
17816 EXIT();
17817 return TRUE;
17818}
17819
17820/**
17821 * wlan_hdd_mdns_free_mem() - Free the allocated memory
17822 * @response: Pointer to the struct hdd_mdns_resp_info
17823 *
17824 * Return: None
17825 */
17826static void wlan_hdd_mdns_free_mem(struct hdd_mdns_resp_info *response)
17827{
17828 if (response && response->data)
17829 vos_mem_free(response->data);
17830 if (response && response->offset)
17831 vos_mem_free(response->offset);
17832}
17833
17834/**
17835 * wlan_hdd_mdns_pack_response() - Pack mDNS response
17836 * @ini_config: Pointer to the struct hdd_config_t
17837 * @resp_info: Pointer to the struct tSirMDNSResponseInfo
17838 *
17839 * This function will pack four types of responses (Type A, Type Txt, Type Ptr
17840 * and Type Service). Each response contains QName, response type, class, TTL
17841 * and data fields.
17842 *
17843 * Return: Return boolean. TRUE for success, FALSE for fail.
17844 */
17845static bool wlan_hdd_mdns_pack_response(hdd_config_t *ini_config,
17846 sir_mdns_resp_info resp_info)
17847{
17848 struct hdd_mdns_resp_info resptype_a, resptype_txt;
17849 struct hdd_mdns_resp_info resptype_ptr, resptype_ptr_dn;
17850 struct hdd_mdns_resp_info resptype_srv, resptype_srv_tgt;
17851 uint32_t num_res_records = 0;
17852 bool status = FALSE;
17853
17854 ENTER();
17855
17856 wlan_hdd_mdns_reset_response(&resptype_a);
17857 wlan_hdd_mdns_reset_response(&resptype_txt);
17858 wlan_hdd_mdns_reset_response(&resptype_ptr);
17859 wlan_hdd_mdns_reset_response(&resptype_ptr_dn);
17860 wlan_hdd_mdns_reset_response(&resptype_srv);
17861 wlan_hdd_mdns_reset_response(&resptype_srv_tgt);
17862
17863 resp_info->resp_len = 0;
17864
17865 /* Process Type A response */
17866 if (!wlan_hdd_mdns_pack_response_type_a(ini_config, resp_info,
17867 &resptype_a))
17868 goto err_resptype_a;
17869
17870 if ((resptype_a.num_entries > 0) &&
17871 (strlen((char *)&resptype_a.data[0]) > 0))
17872 num_res_records++;
17873
17874 /* Process Type TXT response */
17875 if (!wlan_hdd_mdns_pack_response_type_txt(ini_config, resp_info,
17876 &resptype_txt, &resptype_a))
17877 goto err_resptype_txt;
17878
17879 if ((resptype_txt.num_entries > 0) &&
17880 (strlen((char *)&resptype_txt.data[0]) > 0))
17881 num_res_records++;
17882
17883 /* Process Type PTR response */
17884 if (!wlan_hdd_mdns_pack_response_type_ptr(ini_config, resp_info,
17885 &resptype_ptr, &resptype_ptr_dn,
17886 &resptype_txt, &resptype_a))
17887 goto err_resptype_ptr;
17888
17889 if ((resptype_ptr.num_entries > 0) &&
17890 (strlen((char *)&resptype_ptr.data[0]) > 0))
17891 num_res_records++;
17892
17893 /* Process Type SRV response */
17894 if (!wlan_hdd_mdns_pack_response_type_srv(ini_config, resp_info,
17895 &resptype_srv, &resptype_srv_tgt,
17896 &resptype_ptr, &resptype_ptr_dn,
17897 &resptype_txt, &resptype_a))
17898 goto err_resptype_srv;
17899
17900 if ((resptype_srv.num_entries > 0) &&
17901 (strlen((char *)&resptype_srv.data[0]) > 0))
17902 num_res_records++;
17903
17904 resp_info->resourceRecord_count = num_res_records;
17905 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
17906 "%s: Pack mDNS response data successfully!", __func__);
17907 status = TRUE;
17908
17909err_resptype_srv:
17910 wlan_hdd_mdns_free_mem(&resptype_srv);
17911 wlan_hdd_mdns_free_mem(&resptype_srv_tgt);
17912
17913err_resptype_ptr:
17914 wlan_hdd_mdns_free_mem(&resptype_ptr);
17915 wlan_hdd_mdns_free_mem(&resptype_ptr_dn);
17916
17917err_resptype_txt:
17918 wlan_hdd_mdns_free_mem(&resptype_txt);
17919
17920err_resptype_a:
17921 wlan_hdd_mdns_free_mem(&resptype_a);
17922
17923 EXIT();
17924 return status;
17925}
17926
17927/**
17928 * wlan_hdd_set_mdns_offload() - Enable mDNS offload
17929 * @hostapd_adapter: Pointer to the struct hdd_adapter_t
17930 *
17931 * This function will set FQDN/unique FQDN (full qualified domain name)
17932 * and the mDNS response. Then send them to SME.
17933 *
17934 * Return: Return boolean. TRUE for success, FALSE for fail.
17935 */
17936bool wlan_hdd_set_mdns_offload(hdd_adapter_t *hostapd_adapter)
17937{
17938 hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(hostapd_adapter);
17939 sir_mdns_offload_info mdns_offload_info;
17940 sir_mdns_fqdn_info mdns_fqdn_info;
17941 sir_mdns_resp_info mdns_resp_info;
17942 uint32_t fqdn_len, ufqdn_len;
17943
17944 ENTER();
17945
17946 /* 1. Prepare the MDNS fqdn request to send to SME */
17947 fqdn_len = strlen(hdd_ctx->cfg_ini->mdns_fqdn);
17948 ufqdn_len = strlen(hdd_ctx->cfg_ini->mdns_uniquefqdn);
17949 if ((fqdn_len == 0) && (ufqdn_len == 0)) {
17950 hddLog(LOGE, FL("No mDNS FQDN or UFQDN is assigned fqdn_len %d,"
17951 "ufqdn_len %d!"), fqdn_len, ufqdn_len);
17952 return FALSE;
17953 }
17954
17955 mdns_fqdn_info = vos_mem_malloc(sizeof(*mdns_fqdn_info));
17956 if (NULL == mdns_fqdn_info) {
17957 hddLog(LOGE, FL("could not allocate tSirMDNSFqdnInfo!"));
17958 return FALSE;
17959 }
17960 /* MDNS fqdn request */
17961 if (fqdn_len > 0) {
17962 vos_mem_zero(mdns_fqdn_info, sizeof(*mdns_fqdn_info));
17963 mdns_fqdn_info->bss_idx = hostapd_adapter->sessionId;
17964 mdns_fqdn_info->fqdn_type = MDNS_FQDN_TYPE_GENERAL;
17965 mdns_fqdn_info->fqdn_len = fqdn_len;
17966 mdns_fqdn_info->mdns_fqdn_callback = hdd_mdns_fqdn_offload_done;
17967 mdns_fqdn_info->mdns_fqdn_cb_context = hostapd_adapter;
17968 vos_mem_copy(mdns_fqdn_info->fqdn_data,
17969 hdd_ctx->cfg_ini->mdns_fqdn,
17970 mdns_fqdn_info->fqdn_len);
17971
17972 if (eHAL_STATUS_SUCCESS !=
17973 sme_set_mdns_fqdn(hdd_ctx->hHal, mdns_fqdn_info)) {
17974 hddLog(LOGE, FL("sme_set_mdns_fqdn fail!"));
17975 vos_mem_free(mdns_fqdn_info);
17976 return FALSE;
17977 }
17978 }
17979 /* MDNS unique fqdn request */
17980 if (ufqdn_len > 0) {
17981 vos_mem_zero(mdns_fqdn_info, sizeof(*mdns_fqdn_info));
17982 mdns_fqdn_info->bss_idx = hostapd_adapter->sessionId;
17983 mdns_fqdn_info->fqdn_type = MDNS_FQDN_TYPE_UNIQUE;
17984 mdns_fqdn_info->fqdn_len = ufqdn_len;
17985 mdns_fqdn_info->mdns_fqdn_callback = hdd_mdns_fqdn_offload_done;
17986 mdns_fqdn_info->mdns_fqdn_cb_context = hostapd_adapter;
17987 vos_mem_copy(mdns_fqdn_info->fqdn_data,
17988 hdd_ctx->cfg_ini->mdns_uniquefqdn,
17989 mdns_fqdn_info->fqdn_len);
17990 if (eHAL_STATUS_SUCCESS !=
17991 sme_set_mdns_fqdn(hdd_ctx->hHal, mdns_fqdn_info)) {
17992 hddLog(LOGE, FL("sme_set_mdns_fqdn fail!"));
17993 vos_mem_free(mdns_fqdn_info);
17994 return FALSE;
17995 }
17996 }
17997 vos_mem_free(mdns_fqdn_info);
17998
17999 /* 2. Prepare the MDNS response request to send to SME */
18000 mdns_resp_info = vos_mem_malloc(sizeof(*mdns_resp_info));
18001 if (NULL == mdns_resp_info) {
18002 hddLog(LOGE, FL("could not allocate tSirMDNSResponseInfo!"));
18003 return FALSE;
18004 }
18005
18006 vos_mem_zero(mdns_resp_info, sizeof(*mdns_resp_info));
18007 mdns_resp_info->bss_idx = hostapd_adapter->sessionId;
18008 mdns_resp_info->mdns_resp_callback = hdd_mdns_resp_offload_done;
18009 mdns_resp_info->mdns_resp_cb_context = hostapd_adapter;
18010 if (!wlan_hdd_mdns_pack_response(hdd_ctx->cfg_ini, mdns_resp_info)) {
18011 hddLog(LOGE, FL("wlan_hdd_pack_mdns_response fail!"));
18012 vos_mem_free(mdns_resp_info);
18013 return FALSE;
18014 }
18015 if (eHAL_STATUS_SUCCESS !=
18016 sme_set_mdns_resp(hdd_ctx->hHal, mdns_resp_info)) {
18017 hddLog(LOGE, FL("sme_set_mdns_resp fail!"));
18018 vos_mem_free(mdns_resp_info);
18019 return FALSE;
18020 }
18021 vos_mem_free(mdns_resp_info);
18022
18023 /* 3. Prepare the MDNS Enable request to send to SME */
18024 mdns_offload_info = vos_mem_malloc(sizeof(*mdns_offload_info));
18025 if (NULL == mdns_offload_info) {
18026 hddLog(LOGE, FL("could not allocate tSirMDNSOffloadInfo!"));
18027 return FALSE;
18028 }
18029
18030 vos_mem_zero(mdns_offload_info, sizeof(*mdns_offload_info));
18031
18032 mdns_offload_info->bss_idx = hostapd_adapter->sessionId;
18033 mdns_offload_info->enable = hdd_ctx->cfg_ini->enable_mdns_offload;
18034 mdns_offload_info->mdns_enable_callback = hdd_mdns_enable_offload_done;
18035 mdns_offload_info->mdns_enable_cb_context = hostapd_adapter;
18036 if (eHAL_STATUS_SUCCESS !=
18037 sme_set_mdns_offload(hdd_ctx->hHal, mdns_offload_info)) {
18038 hddLog(LOGE, FL("sme_set_mdns_offload fail!"));
18039 vos_mem_free(mdns_offload_info);
18040 return FALSE;
18041 }
18042
18043 vos_mem_free(mdns_offload_info);
18044 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
18045 "%s: enable mDNS offload successfully!", __func__);
18046 return TRUE;
18047}
Manjeet Singh3ed79242017-01-11 19:04:32 +053018048
18049
Anurag Chouhan0b29de02016-12-16 13:18:40 +053018050#endif /* MDNS_OFFLOAD */
c_manjeecfd1efb2015-09-25 19:32:34 +053018051
Hanumanth Reddy Pothulad864f312017-01-18 16:16:08 +053018052/**
18053 * wlan_hdd_start_sap() - This function starts bss of SAP.
18054 * @ap_adapter: SAP adapter
18055 *
18056 * This function will process the starting of sap adapter.
18057 *
18058 * Return: void.
18059 */
18060void wlan_hdd_start_sap(hdd_adapter_t *ap_adapter)
18061{
18062 hdd_ap_ctx_t *hdd_ap_ctx;
18063 hdd_hostapd_state_t *hostapd_state;
18064 VOS_STATUS vos_status;
18065 hdd_context_t *hdd_ctx;
18066 tsap_Config_t *pConfig;
18067
18068 if (NULL == ap_adapter) {
18069 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18070 FL("ap_adapter is NULL here"));
18071 return;
18072 }
18073
18074 hdd_ctx = WLAN_HDD_GET_CTX(ap_adapter);
18075 hdd_ap_ctx = WLAN_HDD_GET_AP_CTX_PTR(ap_adapter);
18076 hostapd_state = WLAN_HDD_GET_HOSTAP_STATE_PTR(ap_adapter);
18077 pConfig = &ap_adapter->sessionCtx.ap.sapConfig;
18078
18079 mutex_lock(&hdd_ctx->sap_lock);
18080 if (test_bit(SOFTAP_BSS_STARTED, &ap_adapter->event_flags))
18081 goto end;
18082
18083 if (0 != wlan_hdd_cfg80211_update_apies(ap_adapter)) {
18084 hddLog(LOGE, FL("SAP Not able to set AP IEs"));
18085 goto end;
18086 }
18087
18088 vos_event_reset(&hostapd_state->vosEvent);
18089 if (WLANSAP_StartBss(hdd_ctx->pvosContext, hdd_hostapd_SAPEventCB,
18090 &hdd_ap_ctx->sapConfig, (v_PVOID_t)ap_adapter->dev)
18091 != VOS_STATUS_SUCCESS) {
18092 goto end;
18093 }
18094
18095 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
18096 FL("Waiting for SAP to start"));
18097 vos_status = vos_wait_single_event(&hostapd_state->vosEvent, 10000);
18098 if (!VOS_IS_STATUS_SUCCESS(vos_status)) {
18099 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18100 FL("SAP Start failed"));
18101 goto end;
18102 }
18103 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
18104 FL("SAP Start Success"));
18105 set_bit(SOFTAP_BSS_STARTED, &ap_adapter->event_flags);
18106
18107 wlan_hdd_incr_active_session(hdd_ctx, ap_adapter->device_mode);
18108 hostapd_state->bCommit = TRUE;
18109
18110end:
18111 mutex_unlock(&hdd_ctx->sap_lock);
18112 return;
18113}
18114
Manjeet Singh3ed79242017-01-11 19:04:32 +053018115#ifdef WLAN_FEATURE_TSF
18116
18117/**
18118 * hdd_tsf_cb() - handle tsf request callback
18119 *
18120 * @pcb_cxt: pointer to the hdd_contex
18121 * @ptsf: pointer to struct stsf
18122 *
18123 * Based on the request sent .
18124 *
18125 * Return: Describe the execute result of this routine
18126 */
18127static int hdd_tsf_cb(void *pcb_ctx, struct stsf *ptsf)
18128{
18129 hdd_context_t *hddctx;
18130 int status;
18131 hdd_adapter_t* adapter = (hdd_adapter_t*)pcb_ctx;
18132
18133 if (pcb_ctx == NULL || ptsf == NULL) {
18134 hddLog(VOS_TRACE_LEVEL_ERROR,
18135 FL("HDD context is not valid"));
18136 return -EINVAL;
18137 }
18138
18139 hddctx = (hdd_context_t *)pcb_ctx;
18140 status = wlan_hdd_validate_context(hddctx);
18141 if (0 != status)
18142 return -EINVAL;
18143
18144 if (NULL == adapter) {
18145 hddLog(VOS_TRACE_LEVEL_ERROR,
18146 FL("failed to find adapter"));
18147 return -EINVAL;
18148 }
18149
18150 hddLog(VOS_TRACE_LEVEL_INFO,
18151 FL("tsf cb handle event, device_mode is %d"),
18152 adapter->device_mode);
18153
18154 /* copy the return value to hdd_tsf_ctx in adapter*/
18155 if (ptsf->tsf_req_status) {
18156
18157 vos_spin_lock_acquire(&adapter->tsf_cap_ctx.tsf_lock);
18158 adapter->tsf_cap_ctx.tsf_get_state = TSF_NOT_RETURNED_BY_FW;
18159 adapter->tsf_cap_ctx.tsf_capture_state = TSF_IDLE;
18160 vos_event_set (&adapter->tsf_cap_ctx.tsf_capture_done_event);
18161 vos_spin_lock_release(&adapter->tsf_cap_ctx.tsf_lock);
18162
18163 hddLog(VOS_TRACE_LEVEL_ERROR, FL("tsf req failure :%d"),
18164 ptsf->tsf_req_status);
18165 return ptsf->tsf_req_status;
18166 }
18167 /* If this is a get request.Store the tsf values in adapter. */
18168 if (!ptsf->set_tsf_req) {
18169 vos_spin_lock_acquire(&adapter->tsf_cap_ctx.tsf_lock);
18170 adapter->tsf_cap_ctx.tsf_low = ptsf->tsf_low;
18171 adapter->tsf_cap_ctx.tsf_high = ptsf->tsf_high;
18172 adapter->tsf_cap_ctx.tsf_get_state = TSF_RETURN;
18173 adapter->tsf_cap_ctx.tsf_capture_state = TSF_IDLE;
18174 vos_spin_lock_release(&adapter->tsf_cap_ctx.tsf_lock);
18175
18176 hddLog(VOS_TRACE_LEVEL_INFO,
18177 FL("hdd_get_tsf_cb sta=%u, tsf_low=%u, tsf_high=%u"),
18178 adapter->sessionId, ptsf->tsf_low, ptsf->tsf_high);
18179 }
18180 else {
18181 vos_spin_lock_acquire(&adapter->tsf_cap_ctx.tsf_lock);
18182 adapter->tsf_cap_ctx.tsf_capture_state = TSF_CAP_STATE;
18183 adapter->tsf_cap_ctx.tsf_get_state = TSF_CURRENT_IN_CAP_STATE;
18184 vos_spin_lock_release(&adapter->tsf_cap_ctx.tsf_lock);
18185 }
18186 vos_spin_lock_acquire(&adapter->tsf_cap_ctx.tsf_lock);
18187 vos_event_set (&adapter->tsf_cap_ctx.tsf_capture_done_event);
18188 vos_spin_lock_release(&adapter->tsf_cap_ctx.tsf_lock);
18189
18190 /* free allocated mem */
18191 vos_mem_free(ptsf);
18192
18193 return 0;
18194}
18195
18196/**
18197 * hdd_capture_tsf() - capture tsf
18198 *
18199 * @adapter: pointer to adapter
18200 * @buf: pointer to upper layer buf
18201 * @len : the length of buf
18202 *
18203 * This function returns tsf value to uplayer.
18204 *
18205 * Return: Describe the execute result of this routine
18206 */
18207int hdd_capture_tsf(hdd_adapter_t *adapter, uint32_t *buf, int len)
18208{
18209 int ret = 0;
18210 hdd_station_ctx_t *hdd_sta_ctx;
18211 hdd_context_t *hdd_ctx;
18212 tSirCapTsfParams cap_tsf_params;
18213 VOS_STATUS status;
18214
18215 if (adapter == NULL || buf == NULL) {
18216 hddLog(VOS_TRACE_LEVEL_ERROR,
18217 FL("invalid pointer"));
18218 return -EINVAL;
18219 }
18220 if (len != 1)
18221 return -EINVAL;
18222
18223 hdd_ctx = WLAN_HDD_GET_CTX(adapter);
18224
18225 if (wlan_hdd_validate_context(hdd_ctx)) {
18226 hddLog(VOS_TRACE_LEVEL_ERROR,
18227 FL("invalid hdd ctx"));
18228 return -EINVAL;
18229 }
18230 if (adapter->device_mode == WLAN_HDD_INFRA_STATION ||
18231 adapter->device_mode == WLAN_HDD_P2P_CLIENT) {
18232 hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
18233 if (hdd_sta_ctx->conn_info.connState !=
18234 eConnectionState_Associated) {
18235
18236 hddLog(VOS_TRACE_LEVEL_INFO,
18237 FL("failed to cap tsf, not connect with ap"));
18238 buf[0] = TSF_STA_NOT_CONNECTED_NO_TSF;
18239 return ret;
18240 }
18241 }
18242 if ((adapter->device_mode == WLAN_HDD_SOFTAP ||
18243 adapter->device_mode == WLAN_HDD_P2P_GO) &&
18244 !(test_bit(SOFTAP_BSS_STARTED, &adapter->event_flags))) {
18245 hddLog(VOS_TRACE_LEVEL_INFO,
18246 FL("Soft AP / P2p GO not beaconing"));
18247 buf[0] = TSF_SAP_NOT_STARTED_NO_TSF;
18248 return ret;
18249 }
18250 if (adapter->tsf_cap_ctx.tsf_capture_state == TSF_CAP_STATE) {
18251 hddLog(VOS_TRACE_LEVEL_INFO,
18252 FL("current in capture state, pls reset"));
18253 buf[0] = TSF_CURRENT_IN_CAP_STATE;
18254 } else {
18255 hddLog(VOS_TRACE_LEVEL_INFO, FL("ioctl issue cap tsf cmd"));
18256 buf[0] = TSF_RETURN;
18257 cap_tsf_params.session_id = adapter->sessionId;
18258 cap_tsf_params.tsf_rsp_cb_func = hdd_tsf_cb;
18259 cap_tsf_params.tsf_rsp_cb_ctx = adapter;
18260
18261 vos_spin_lock_acquire(&adapter->tsf_cap_ctx.tsf_lock);
18262 adapter->tsf_cap_ctx.tsf_capture_state = TSF_CAP_STATE;
18263 adapter->tsf_cap_ctx.tsf_get_state = TSF_CURRENT_IN_CAP_STATE;
18264 vos_spin_lock_release(&adapter->tsf_cap_ctx.tsf_lock);
18265
18266 ret = sme_capture_tsf_req(hdd_ctx->hHal, cap_tsf_params);
18267
18268 if (ret != VOS_STATUS_SUCCESS) {
18269 hddLog(VOS_TRACE_LEVEL_ERROR, FL("capture fail"));
18270 buf[0] = TSF_CAPTURE_FAIL;
18271 vos_spin_lock_acquire(&adapter->tsf_cap_ctx.tsf_lock);
18272 adapter->tsf_cap_ctx.tsf_capture_state = TSF_IDLE;
18273 vos_spin_lock_release(&adapter->tsf_cap_ctx.tsf_lock);
18274 return -EINVAL;
18275 }
18276 /* wait till we get a response from fw */
18277 status = vos_wait_single_event(&adapter->tsf_cap_ctx.
18278 tsf_capture_done_event,
18279 HDD_TSF_CAP_REQ_TIMEOUT);
18280
18281 if (!VOS_IS_STATUS_SUCCESS(status)) {
18282 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18283 ("capture tsf vos wait for single_event failed!! %d"),
18284 adapter->tsf_cap_ctx.tsf_get_state);
18285
18286 vos_spin_lock_acquire(&adapter->tsf_cap_ctx.tsf_lock);
18287 adapter->tsf_cap_ctx.tsf_capture_state = TSF_IDLE;
18288 vos_spin_lock_release(&adapter->tsf_cap_ctx.tsf_lock);
18289
18290 return -EINVAL;
18291 }
18292 }
18293 buf[0] = TSF_RETURN;
18294 hddLog(VOS_TRACE_LEVEL_INFO,
18295 FL("ioctl return cap tsf cmd, ret = %d"), ret);
18296 return ret;
18297}
18298
18299/**
18300 * hdd_indicate_tsf() - return tsf to uplayer
18301 *
18302 * @adapter: pointer to adapter
18303 * @buf: pointer to uplayer buf
18304 * @len : the length of buf
18305 *
18306 * This function returns tsf value to uplayer.
18307 *
18308 * Return: Describe the execute result of this routine
18309 */
18310int hdd_indicate_tsf(hdd_adapter_t *adapter, uint32_t *buf, int len)
18311{
18312 int ret = 0;
18313 hdd_station_ctx_t *hdd_sta_ctx;
18314 hdd_context_t *hdd_ctx;
18315 tSirCapTsfParams cap_tsf_params;
18316 VOS_STATUS status;
18317
18318 if (adapter == NULL || buf == NULL) {
18319 hddLog(VOS_TRACE_LEVEL_ERROR,
18320 FL("invalid pointer"));
18321 return -EINVAL;
18322 }
18323 if (len != 3)
18324 return -EINVAL;
18325
18326 buf [1] = 0;
18327 buf [2] = 0;
18328 hdd_ctx = WLAN_HDD_GET_CTX(adapter);
18329
18330 if (wlan_hdd_validate_context(hdd_ctx)) {
18331 hddLog(VOS_TRACE_LEVEL_ERROR,
18332 FL("invalid hdd ctx"));
18333 return -EINVAL;
18334 }
18335 if (adapter->device_mode == WLAN_HDD_INFRA_STATION ||
18336 adapter->device_mode == WLAN_HDD_P2P_CLIENT) {
18337 hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
18338 if (hdd_sta_ctx->conn_info.connState !=
18339 eConnectionState_Associated) {
18340
18341 hddLog(VOS_TRACE_LEVEL_INFO,
18342 FL("failed to cap tsf, not connect with ap"));
18343 buf[0] = TSF_STA_NOT_CONNECTED_NO_TSF;
18344 return ret;
18345 }
18346 }
18347 if ((adapter->device_mode == WLAN_HDD_SOFTAP ||
18348 adapter->device_mode == WLAN_HDD_P2P_GO) &&
18349 !(test_bit(SOFTAP_BSS_STARTED, &adapter->event_flags))) {
18350 hddLog(VOS_TRACE_LEVEL_INFO,
18351 FL("Soft AP / P2p GO not beaconing"));
18352 buf[0] = TSF_SAP_NOT_STARTED_NO_TSF;
18353 return ret;
18354 }
18355
18356 if (adapter->tsf_cap_ctx.tsf_capture_state != TSF_CAP_STATE ||
18357 adapter->tsf_cap_ctx.tsf_get_state != TSF_CURRENT_IN_CAP_STATE ) {
18358 hddLog(VOS_TRACE_LEVEL_INFO,
18359 FL("Not in capture state,Enter capture state first"));
18360 buf[0] = TSF_GET_FAIL;
18361 } else {
18362 hddLog(VOS_TRACE_LEVEL_INFO, FL("ioctl issue cap tsf cmd"));
18363 cap_tsf_params.session_id = adapter->sessionId;
18364 cap_tsf_params.tsf_rsp_cb_func = hdd_tsf_cb;
18365 cap_tsf_params.tsf_rsp_cb_ctx = adapter;
18366
18367 ret = sme_get_tsf_req(hdd_ctx->hHal, cap_tsf_params);
18368
18369 if (ret != VOS_STATUS_SUCCESS) {
18370 hddLog(VOS_TRACE_LEVEL_ERROR, FL("capture fail"));
18371 buf[0] = TSF_CAPTURE_FAIL;
18372 vos_spin_lock_acquire(&adapter->tsf_cap_ctx.tsf_lock);
18373 adapter->tsf_cap_ctx.tsf_capture_state = TSF_IDLE;
18374 vos_spin_lock_release(&adapter->tsf_cap_ctx.tsf_lock);
18375 return -EINVAL;
18376 }
18377 /* wait till we get a response from fw */
18378 status = vos_wait_single_event(&adapter->tsf_cap_ctx.
18379 tsf_capture_done_event,
18380 HDD_TSF_GET_REQ_TIMEOUT);
18381
18382 if (!VOS_IS_STATUS_SUCCESS(status)) {
18383 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18384 ("capture tsf vos wait for single_event failed!! %d"),
18385 status);
18386
18387 vos_spin_lock_acquire(&adapter->tsf_cap_ctx.tsf_lock);
18388 adapter->tsf_cap_ctx.tsf_capture_state = TSF_IDLE;
18389 vos_spin_lock_release(&adapter->tsf_cap_ctx.tsf_lock);
18390 return status;
18391 }
18392 buf[1] = adapter->tsf_cap_ctx.tsf_low;
18393 buf[2] = adapter->tsf_cap_ctx.tsf_high;
18394
18395 hddLog(VOS_TRACE_LEVEL_INFO,
18396 FL("get tsf cmd,status=%u, tsf_low=%u, tsf_high=%u"),
18397 buf[0], buf[1], buf[2]);
18398 }
18399 hddLog(VOS_TRACE_LEVEL_INFO,
18400 FL("ioctl return cap tsf cmd, ret = %d"), ret);
18401 return ret;
18402}
18403
18404void wlan_hdd_tsf_init(hdd_adapter_t *adapter)
18405{
18406
18407 if (adapter == NULL) {
18408 hddLog(VOS_TRACE_LEVEL_ERROR,
18409 FL("TSF init on a null adapter!"));
18410 return;
18411 }
18412
18413 adapter->tsf_cap_ctx.tsf_get_state = TSF_RETURN;
18414 adapter->tsf_cap_ctx.tsf_capture_state = TSF_IDLE;
18415 vos_event_init(&adapter->tsf_cap_ctx.tsf_capture_done_event);
18416 vos_spin_lock_init(&adapter->tsf_cap_ctx.tsf_lock);
18417 adapter->tsf_cap_ctx.tsf_high = 0;
18418 adapter->tsf_cap_ctx.tsf_low = 0;
18419}
18420
18421#endif
18422
Hanumanth Reddy Pothula49c3f902018-02-16 16:01:13 +053018423bool hdd_is_memdump_supported(void)
18424{
18425#ifdef WLAN_FEATURE_MEMDUMP
18426 return true;
18427#endif
18428 return false;
18429}
18430
Hanumanth Reddy Pothula972e1df2018-06-14 13:33:47 +053018431bool hdd_is_cli_iface_up(hdd_context_t *hdd_ctx)
18432{
18433 hdd_adapter_list_node_t *adapter_node = NULL, *next = NULL;
18434 hdd_adapter_t *adapter;
18435 VOS_STATUS status;
18436
18437 status = hdd_get_front_adapter(hdd_ctx, &adapter_node);
18438 while (NULL != adapter_node && VOS_STATUS_SUCCESS == status) {
18439 adapter = adapter_node->pAdapter;
18440 if ((adapter->device_mode == WLAN_HDD_INFRA_STATION ||
18441 adapter->device_mode == WLAN_HDD_P2P_CLIENT) &&
18442 test_bit(DEVICE_IFACE_OPENED,
18443 &adapter->event_flags)){
18444 return true;
18445 }
18446 status = hdd_get_next_adapter(hdd_ctx, adapter_node, &next);
18447 adapter_node = next;
18448 }
18449
18450 return false;
18451}
18452
Jeff Johnson295189b2012-06-20 16:38:30 -070018453//Register the module init/exit functions
18454module_init(hdd_module_init);
18455module_exit(hdd_module_exit);
18456
18457MODULE_LICENSE("Dual BSD/GPL");
18458MODULE_AUTHOR("Qualcomm Atheros, Inc.");
18459MODULE_DESCRIPTION("WLAN HOST DEVICE DRIVER");
18460
Ashish Kumar Dhanotiyafb3fd972018-04-30 12:46:52 +053018461static const struct kernel_param_ops con_mode_ops = {
18462 .set = con_mode_handler,
18463 .get = param_get_int,
18464};
18465
18466static const struct kernel_param_ops fwpath_ops = {
18467 .set = fwpath_changed_handler,
18468 .get = param_get_string,
18469};
18470
Hanumanth Reddy Pothula99219872018-06-08 14:45:18 +053018471#ifdef MODULE
18472module_param(con_mode, int, 0);
18473#else
Ashish Kumar Dhanotiyafb3fd972018-04-30 12:46:52 +053018474module_param_cb(con_mode, &con_mode_ops, &con_mode,
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070018475 S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
Hanumanth Reddy Pothula99219872018-06-08 14:45:18 +053018476#endif
Jeff Johnson32d95a32012-09-10 13:15:23 -070018477
Ashish Kumar Dhanotiyafb3fd972018-04-30 12:46:52 +053018478module_param_cb(fwpath, &fwpath_ops, &fwpath,
Jeff Johnson32d95a32012-09-10 13:15:23 -070018479 S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
Arif Hussain66559122013-11-21 10:11:40 -080018480
18481module_param(enable_dfs_chan_scan, int,
18482 S_IRUSR | S_IRGRP | S_IROTH);
18483
18484module_param(enable_11d, int,
18485 S_IRUSR | S_IRGRP | S_IROTH);
18486
18487module_param(country_code, charp,
18488 S_IRUSR | S_IRGRP | S_IROTH);