blob: 8abcdcd8796ca424e6c25f220a8acf8a1ee95147 [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;
c_hpothu92367912014-05-01 15:18:17 +0530154static int gbcnMissRate = -1;
Arif Hussain66559122013-11-21 10:11:40 -0800155
Madan Mohan Koyyalamudi05f313c2012-09-18 19:19:15 -0700156#ifndef MODULE
Madan Mohan Koyyalamudidfd6aa82012-10-18 20:18:43 -0700157static int wlan_hdd_inited;
Madan Mohan Koyyalamudi05f313c2012-09-18 19:19:15 -0700158#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700159
Jeff Johnsone7245742012-09-05 17:12:55 -0700160/*
Jeff Johnson72a40512013-12-19 10:14:15 -0800161 * spinlock for synchronizing asynchronous request/response
162 * (full description of use in wlan_hdd_main.h)
163 */
164DEFINE_SPINLOCK(hdd_context_lock);
165
166/*
Jeff Johnsone7245742012-09-05 17:12:55 -0700167 * The rate at which the driver sends RESTART event to supplicant
168 * once the function 'vos_wlanRestart()' is called
169 *
170 */
171#define WLAN_HDD_RESTART_RETRY_DELAY_MS 5000 /* 5 second */
172#define WLAN_HDD_RESTART_RETRY_MAX_CNT 5 /* 5 retries */
Varun Reddy Yeturu6d99ac82013-05-08 14:15:35 -0700173
174/*
175 * Size of Driver command strings from upper layer
176 */
177#define SIZE_OF_SETROAMMODE 11 /* size of SETROAMMODE */
178#define SIZE_OF_GETROAMMODE 11 /* size of GETROAMMODE */
179
Abhishek Singh00b71972016-01-07 10:51:04 +0530180#ifdef WLAN_FEATURE_RMC
181/*
182 * Ibss prop IE from command will be of size:
183 * size = sizeof(oui) + sizeof(oui_data) + 1(Element ID) + 1(EID Length)
184 * OUI_DATA should be at least 3 bytes long
185 */
186#define WLAN_HDD_IBSS_MIN_OUI_DATA_LENGTH (3)
187#endif
188
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -0800189#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
Srinivas Girigowda5cecb202013-10-08 09:13:25 -0700190#define TID_MIN_VALUE 0
191#define TID_MAX_VALUE 15
192static VOS_STATUS hdd_get_tsm_stats(hdd_adapter_t *pAdapter, const tANI_U8 tid,
193 tAniTrafStrmMetrics* pTsmMetrics);
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -0800194static VOS_STATUS hdd_parse_ese_beacon_req(tANI_U8 *pValue,
195 tCsrEseBeaconReq *pEseBcnReq);
196#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -0700197
Atul Mittal1d722422014-03-19 11:15:07 +0530198/*
199 * Maximum buffer size used for returning the data back to user space
200 */
201#define WLAN_MAX_BUF_SIZE 1024
202#define WLAN_PRIV_DATA_MAX_LEN 8192
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -0700203
Abhishek Singh00b71972016-01-07 10:51:04 +0530204/*
205 * When ever we need to print IBSSPEERINFOALL for morethan 16 STA
206 * we will split the printing.
207 */
208#define NUM_OF_STA_DATA_TO_PRINT 16
209
210#ifdef WLAN_FEATURE_RMC
211#define WLAN_NLINK_CESIUM 30
212#endif
213
c_hpothu92367912014-05-01 15:18:17 +0530214//wait time for beacon miss rate.
215#define BCN_MISS_RATE_TIME 500
216
Selvaraj, Sridhar5aff1ed2016-06-18 01:26:23 +0530217/*
218 * Android DRIVER command structures
219 */
220struct android_wifi_reassoc_params {
221 unsigned char bssid[18];
222 int channel;
223};
224
Sushant Kaushik83392fa2015-05-05 17:44:40 +0530225static vos_wake_lock_t wlan_wake_lock;
226
Jeff Johnson295189b2012-06-20 16:38:30 -0700227/* set when SSR is needed after unload */
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -0700228static e_hdd_ssr_required isSsrRequired = HDD_SSR_NOT_REQUIRED;
Jeff Johnson295189b2012-06-20 16:38:30 -0700229
230//internal function declaration
Jeff Johnsone7245742012-09-05 17:12:55 -0700231static VOS_STATUS wlan_hdd_framework_restart(hdd_context_t *pHddCtx);
232static void wlan_hdd_restart_init(hdd_context_t *pHddCtx);
233static void wlan_hdd_restart_deinit(hdd_context_t *pHddCtx);
Abhishek Singh00b71972016-01-07 10:51:04 +0530234
235#ifdef WLAN_FEATURE_RMC
236static void hdd_tx_fail_ind_callback(v_U8_t *MacAddr, v_U8_t seqNo);
237
238static int hdd_open_cesium_nl_sock(void);
239static void hdd_close_cesium_nl_sock(void);
240static struct sock *cesium_nl_srv_sock;
241static v_U16_t cesium_pid;
242
243static int hdd_ParseIBSSTXFailEventParams(tANI_U8 *pValue,
244 tANI_U8 *tx_fail_count,
245 tANI_U16 *pid);
246
247static int hdd_ParseUserParams(tANI_U8 *pValue, tANI_U8 **ppArg);
248
249#endif /* WLAN_FEATURE_RMC */
Jeff Johnsone7245742012-09-05 17:12:55 -0700250void wlan_hdd_restart_timer_cb(v_PVOID_t usrDataForCallback);
Sameer Thalappil45931fb2013-02-01 11:18:05 -0800251void hdd_set_wlan_suspend_mode(bool suspend);
Sourav Mohapatra2416e0e2018-03-05 18:44:21 +0530252void hdd_set_vowifi_mode(hdd_context_t *hdd_ctx, bool enable);
Jeff Johnsone7245742012-09-05 17:12:55 -0700253
Jeff Johnson295189b2012-06-20 16:38:30 -0700254v_U16_t hdd_select_queue(struct net_device *dev,
Anand N Sunkade9adb1b2015-07-29 09:56:45 +0530255 struct sk_buff *skb
256#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,13,0))
257 , void *accel_priv
258#endif
259#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
260 , select_queue_fallback_t fallback
261#endif
262);
Jeff Johnson295189b2012-06-20 16:38:30 -0700263
264#ifdef WLAN_FEATURE_PACKET_FILTERING
265static void hdd_set_multicast_list(struct net_device *dev);
266#endif
267
268void hdd_wlan_initial_scan(hdd_adapter_t *pAdapter);
269
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -0800270#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowdade697412013-02-14 16:31:48 -0800271void hdd_getBand_helper(hdd_context_t *pHddCtx, int *pBand);
272static VOS_STATUS hdd_parse_channellist(tANI_U8 *pValue, tANI_U8 *pChannelList, tANI_U8 *pNumChannels);
Srinivas Girigowda100eb322013-03-15 16:48:20 -0700273static VOS_STATUS hdd_parse_send_action_frame_data(tANI_U8 *pValue, tANI_U8 *pTargetApBssid,
274 tANI_U8 *pChannel, tANI_U8 *pDwellTime,
275 tANI_U8 **pBuf, tANI_U8 *pBufLen);
Selvaraj, Sridhar5aff1ed2016-06-18 01:26:23 +0530276static int hdd_parse_reassoc_command_v1_data(const tANI_U8 *pValue,
277 tANI_U8 *pTargetApBssid, tANI_U8 *pChannel);
Srinivas Girigowdade697412013-02-14 16:31:48 -0800278#endif
Ratheesh S P21280412015-05-19 14:21:52 +0530279
280/* Store WLAN driver info in a global variable such that crash debugger
281 can extract it from driver debug symbol and crashdump for post processing */
282tANI_U8 g_wlan_driver[ ] = "pronto_driver";
283
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -0800284#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
Srinivas Girigowda5cecb202013-10-08 09:13:25 -0700285VOS_STATUS hdd_parse_get_cckm_ie(tANI_U8 *pValue, tANI_U8 **pCckmIe, tANI_U8 *pCckmIeLen);
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -0800286#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -0700287
Mihir Shetee1093ba2014-01-21 20:13:32 +0530288static VOS_STATUS wlan_hdd_init_channels(hdd_context_t *pHddCtx);
Sushant Kaushik8bc7df22014-04-09 17:55:29 +0530289const char * hdd_device_modetoString(v_U8_t device_mode)
290{
291 switch(device_mode)
292 {
293 CASE_RETURN_STRING( WLAN_HDD_INFRA_STATION );
294 CASE_RETURN_STRING( WLAN_HDD_SOFTAP );
295 CASE_RETURN_STRING( WLAN_HDD_P2P_CLIENT );
296 CASE_RETURN_STRING( WLAN_HDD_P2P_GO );
297 CASE_RETURN_STRING( WLAN_HDD_MONITOR);
298 CASE_RETURN_STRING( WLAN_HDD_FTM );
299 CASE_RETURN_STRING( WLAN_HDD_IBSS );
300 CASE_RETURN_STRING( WLAN_HDD_P2P_DEVICE );
301 default:
302 return "device_mode Unknown";
303 }
304}
Mihir Shetee1093ba2014-01-21 20:13:32 +0530305
Mukul Sharmaa78cf6b2015-02-24 16:59:01 +0530306static int __hdd_netdev_notifier_call(struct notifier_block * nb,
Jeff Johnson295189b2012-06-20 16:38:30 -0700307 unsigned long state,
308 void *ndev)
309{
310 struct net_device *dev = ndev;
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -0700311 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Jeff Johnson27cee452013-03-27 11:10:24 -0700312 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -0700313#ifdef WLAN_BTAMP_FEATURE
314 VOS_STATUS status;
Jeff Johnson295189b2012-06-20 16:38:30 -0700315#endif
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +0530316 long result;
Jeff Johnson295189b2012-06-20 16:38:30 -0700317
318 //Make sure that this callback corresponds to our device.
Jeff Johnson27cee452013-03-27 11:10:24 -0700319 if ((strncmp(dev->name, "wlan", 4)) &&
Amar Singhal4c723bd2013-03-25 18:14:15 -0700320 (strncmp(dev->name, "p2p", 3)))
321 return NOTIFY_DONE;
322
Jeff Johnson295189b2012-06-20 16:38:30 -0700323 if (!dev->ieee80211_ptr)
Jeff Johnson27cee452013-03-27 11:10:24 -0700324 return NOTIFY_DONE;
Jeff Johnson295189b2012-06-20 16:38:30 -0700325
Jeff Johnson27cee452013-03-27 11:10:24 -0700326 if (NULL == pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -0700327 {
Jeff Johnsona8a1a482012-12-12 16:49:33 -0800328 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: HDD Adapter Null Pointer", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700329 VOS_ASSERT(0);
330 return NOTIFY_DONE;
331 }
332
Jeff Johnson27cee452013-03-27 11:10:24 -0700333 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
334 if (NULL == pHddCtx)
335 {
336 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: HDD Context Null Pointer", __func__);
337 VOS_ASSERT(0);
338 return NOTIFY_DONE;
339 }
Sameer Thalappil14067972014-01-23 14:54:54 -0800340 if (pHddCtx->isLogpInProgress)
341 return NOTIFY_DONE;
342
Jeff Johnson27cee452013-03-27 11:10:24 -0700343
344 hddLog(VOS_TRACE_LEVEL_INFO, "%s: %s New Net Device State = %lu",
345 __func__, dev->name, state);
Jeff Johnson295189b2012-06-20 16:38:30 -0700346
347 switch (state) {
348 case NETDEV_REGISTER:
349 break;
350
351 case NETDEV_UNREGISTER:
352 break;
353
354 case NETDEV_UP:
355 break;
356
357 case NETDEV_DOWN:
358 break;
359
360 case NETDEV_CHANGE:
Jeff Johnsone7245742012-09-05 17:12:55 -0700361 if(TRUE == pAdapter->isLinkUpSvcNeeded)
362 complete(&pAdapter->linkup_event_var);
Jeff Johnson295189b2012-06-20 16:38:30 -0700363 break;
364
365 case NETDEV_GOING_DOWN:
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +0530366 result = wlan_hdd_scan_abort(pAdapter);
Girish Gowli4bf7a632014-06-12 13:42:11 +0530367 if (result < 0)
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +0530368 {
369 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
370 "%s: Timeout occurred while waiting for abortscan %ld",
371 __func__, result);
Jeff Johnson295189b2012-06-20 16:38:30 -0700372 }
373 else
374 {
375 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +0530376 "%s: Scan Abort Successful" , __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700377 }
378#ifdef WLAN_BTAMP_FEATURE
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700379 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,"%s: disabling AMP", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700380 status = WLANBAP_StopAmp();
381 if(VOS_STATUS_SUCCESS != status )
382 {
383 pHddCtx->isAmpAllowed = VOS_TRUE;
384 hddLog(VOS_TRACE_LEVEL_FATAL,
385 "%s: Failed to stop AMP", __func__);
386 }
387 else
388 {
389 //a state m/c implementation in PAL is TBD to avoid this delay
390 msleep(500);
Jeff Johnson04dd8a82012-06-29 20:41:40 -0700391 if ( pHddCtx->isAmpAllowed )
392 {
393 WLANBAP_DeregisterFromHCI();
394 pHddCtx->isAmpAllowed = VOS_FALSE;
395 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700396 }
397#endif //WLAN_BTAMP_FEATURE
398 break;
399
400 default:
401 break;
402 }
403
404 return NOTIFY_DONE;
405}
406
Mukul Sharmaa78cf6b2015-02-24 16:59:01 +0530407static int hdd_netdev_notifier_call(struct notifier_block * nb,
408 unsigned long state,
409 void *ndev)
410{
411 int ret;
412 vos_ssr_protect(__func__);
413 ret = __hdd_netdev_notifier_call( nb, state, ndev);
414 vos_ssr_unprotect(__func__);
415 return ret;
416}
417
Jeff Johnson295189b2012-06-20 16:38:30 -0700418struct notifier_block hdd_netdev_notifier = {
419 .notifier_call = hdd_netdev_notifier_call,
420};
421
422/*---------------------------------------------------------------------------
423 * Function definitions
424 *-------------------------------------------------------------------------*/
Jeff Johnson295189b2012-06-20 16:38:30 -0700425void hdd_unregister_mcast_bcast_filter(hdd_context_t *pHddCtx);
426void hdd_register_mcast_bcast_filter(hdd_context_t *pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -0700427//variable to hold the insmod parameters
Madan Mohan Koyyalamudidfd6aa82012-10-18 20:18:43 -0700428static int con_mode;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -0700429#ifndef MODULE
430/* current con_mode - used only for statically linked driver
431 * con_mode is changed by userspace to indicate a mode change which will
432 * result in calling the module exit and init functions. The module
433 * exit function will clean up based on the value of con_mode prior to it
434 * being changed by userspace. So curr_con_mode records the current con_mode
435 * for exit when con_mode becomes the next mode for init
436 */
Madan Mohan Koyyalamudidfd6aa82012-10-18 20:18:43 -0700437static int curr_con_mode;
Jeff Johnson295189b2012-06-20 16:38:30 -0700438#endif
439
Srinivas Girigowda8bf64cb2015-09-30 19:50:09 +0530440#ifdef WLAN_FEATURE_OFFLOAD_PACKETS
441/**
442 * hdd_init_offloaded_packets_ctx() - Initialize offload packets context
443 * @hdd_ctx: hdd global context
444 *
445 * Return: none
446 */
447static void hdd_init_offloaded_packets_ctx(hdd_context_t *hdd_ctx)
448{
449 uint8_t i;
450
451 mutex_init(&hdd_ctx->op_ctx.op_lock);
452 for (i = 0; i < MAXNUM_PERIODIC_TX_PTRNS; i++)
453 {
454 hdd_ctx->op_ctx.op_table[i].request_id = 0;
455 hdd_ctx->op_ctx.op_table[i].pattern_id = i;
456 }
457}
458#else
459static void hdd_init_offloaded_packets_ctx(hdd_context_t *hdd_ctx)
460{
461}
462#endif
463
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -0800464/**---------------------------------------------------------------------------
465
466 \brief hdd_vos_trace_enable() - Configure initial VOS Trace enable
467
468 Called immediately after the cfg.ini is read in order to configure
469 the desired trace levels.
470
471 \param - moduleId - module whose trace level is being configured
472 \param - bitmask - bitmask of log levels to be enabled
473
474 \return - void
475
476 --------------------------------------------------------------------------*/
477static void hdd_vos_trace_enable(VOS_MODULE_ID moduleId, v_U32_t bitmask)
478{
479 wpt_tracelevel level;
480
481 /* if the bitmask is the default value, then a bitmask was not
482 specified in cfg.ini, so leave the logging level alone (it
483 will remain at the "compiled in" default value) */
484 if (CFG_VOS_TRACE_ENABLE_DEFAULT == bitmask)
485 {
486 return;
487 }
488
489 /* a mask was specified. start by disabling all logging */
490 vos_trace_setValue(moduleId, VOS_TRACE_LEVEL_NONE, 0);
491
492 /* now cycle through the bitmask until all "set" bits are serviced */
493 level = VOS_TRACE_LEVEL_FATAL;
494 while (0 != bitmask)
495 {
496 if (bitmask & 1)
497 {
498 vos_trace_setValue(moduleId, level, 1);
499 }
500 level++;
501 bitmask >>= 1;
502 }
503}
504
505
Jeff Johnson295189b2012-06-20 16:38:30 -0700506/**---------------------------------------------------------------------------
507
508 \brief hdd_wdi_trace_enable() - Configure initial WDI Trace enable
509
510 Called immediately after the cfg.ini is read in order to configure
511 the desired trace levels in the WDI.
512
513 \param - moduleId - module whose trace level is being configured
514 \param - bitmask - bitmask of log levels to be enabled
515
516 \return - void
517
518 --------------------------------------------------------------------------*/
519static void hdd_wdi_trace_enable(wpt_moduleid moduleId, v_U32_t bitmask)
520{
521 wpt_tracelevel level;
522
523 /* if the bitmask is the default value, then a bitmask was not
524 specified in cfg.ini, so leave the logging level alone (it
525 will remain at the "compiled in" default value) */
526 if (CFG_WDI_TRACE_ENABLE_DEFAULT == bitmask)
527 {
528 return;
529 }
530
531 /* a mask was specified. start by disabling all logging */
532 wpalTraceSetLevel(moduleId, eWLAN_PAL_TRACE_LEVEL_NONE, 0);
533
534 /* now cycle through the bitmask until all "set" bits are serviced */
535 level = eWLAN_PAL_TRACE_LEVEL_FATAL;
536 while (0 != bitmask)
537 {
538 if (bitmask & 1)
539 {
540 wpalTraceSetLevel(moduleId, level, 1);
541 }
542 level++;
543 bitmask >>= 1;
544 }
545}
Jeff Johnson295189b2012-06-20 16:38:30 -0700546
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +0530547/*
548 * FUNCTION: wlan_hdd_validate_context
549 * This function is used to check the HDD context
550 */
551int wlan_hdd_validate_context(hdd_context_t *pHddCtx)
552{
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +0530553
554 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
555 {
Mahesh A Saptasagar886997a2015-03-04 13:15:51 +0530556 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +0530557 "%s: HDD context is Null", __func__);
558 return -ENODEV;
559 }
560
561 if (pHddCtx->isLogpInProgress)
562 {
Mahesh A Saptasagar886997a2015-03-04 13:15:51 +0530563 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
c_hpothu8adb97b2014-12-08 19:38:20 +0530564 "%s: LOGP %s. Ignore!!", __func__,
565 vos_is_wlan_in_badState(VOS_MODULE_ID_HDD, NULL)
566 ?"failed":"in Progress");
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +0530567 return -EAGAIN;
568 }
569
Mihir Shete18156292014-03-11 15:38:30 +0530570 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +0530571 {
Mahesh A Saptasagar886997a2015-03-04 13:15:51 +0530572 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +0530573 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
574 return -EAGAIN;
575 }
576 return 0;
577}
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -0700578#ifdef CONFIG_ENABLE_LINUX_REG
579void hdd_checkandupdate_phymode( hdd_context_t *pHddCtx)
580{
581 hdd_adapter_t *pAdapter = NULL;
582 hdd_station_ctx_t *pHddStaCtx = NULL;
583 eCsrPhyMode phyMode;
584 hdd_config_t *cfg_param = NULL;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +0530585
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -0700586 if (NULL == pHddCtx)
587 {
588 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
589 "HDD Context is null !!");
590 return ;
591 }
592
593 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION);
594 if (NULL == pAdapter)
595 {
596 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
597 "pAdapter is null !!");
598 return ;
599 }
600
601 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
602 if (NULL == pHddStaCtx)
603 {
604 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
605 "pHddStaCtx is null !!");
606 return ;
607 }
608
609 cfg_param = pHddCtx->cfg_ini;
610 if (NULL == cfg_param)
611 {
612 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
613 "cfg_params not available !!");
614 return ;
615 }
616
617 phyMode = sme_GetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter));
618
619 if (!pHddCtx->isVHT80Allowed)
620 {
621 if ((eCSR_DOT11_MODE_AUTO == phyMode) ||
622 (eCSR_DOT11_MODE_11ac == phyMode) ||
623 (eCSR_DOT11_MODE_11ac_ONLY == phyMode))
624 {
625 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
626 "Setting phymode to 11n!!");
627 sme_SetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter), eCSR_DOT11_MODE_11n);
628 }
629 }
630 else
631 {
632 /*New country Supports 11ac as well resetting value back from .ini*/
633 sme_SetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter),
634 hdd_cfg_xlate_to_csr_phy_mode(cfg_param->dot11Mode));
635 return ;
636 }
637
638 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
639 ((eCSR_CFG_DOT11_MODE_11AC_ONLY == pHddStaCtx->conn_info.dot11Mode) ||
640 (eCSR_CFG_DOT11_MODE_11AC == pHddStaCtx->conn_info.dot11Mode)))
641 {
642 VOS_STATUS vosStatus;
643
644 // need to issue a disconnect to CSR.
645 INIT_COMPLETION(pAdapter->disconnect_comp_var);
646 vosStatus = sme_RoamDisconnect(WLAN_HDD_GET_HAL_CTX(pAdapter),
647 pAdapter->sessionId,
648 eCSR_DISCONNECT_REASON_UNSPECIFIED );
649
650 if (VOS_STATUS_SUCCESS == vosStatus)
c_hpothu6ff1c3c2013-10-01 19:01:57 +0530651 {
652 long ret;
653
654 ret = wait_for_completion_interruptible_timeout(&pAdapter->disconnect_comp_var,
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -0700655 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
c_hpothu6ff1c3c2013-10-01 19:01:57 +0530656 if (0 >= ret)
657 hddLog(LOGE, FL("failure waiting for disconnect_comp_var %ld"),
658 ret);
659 }
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -0700660
661 }
662}
663#else
Gopichand Nakkaladacbcb52013-04-18 16:41:54 +0530664void hdd_checkandupdate_phymode( hdd_adapter_t *pAdapter, char *country_code)
665{
666 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
667 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
668 hdd_config_t *cfg_param;
669 eCsrPhyMode phyMode;
c_hpothu6ff1c3c2013-10-01 19:01:57 +0530670 long ret;
Gopichand Nakkaladacbcb52013-04-18 16:41:54 +0530671
672 if (NULL == pHddCtx)
673 {
674 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
675 "HDD Context is null !!");
676 return ;
677 }
678
679 cfg_param = pHddCtx->cfg_ini;
680
681 if (NULL == cfg_param)
682 {
683 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
684 "cfg_params not available !!");
685 return ;
686 }
687
688 phyMode = sme_GetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter));
689
690 if (NULL != strstr(cfg_param->listOfNon11acCountryCode, country_code))
691 {
692 if ((eCSR_DOT11_MODE_AUTO == phyMode) ||
693 (eCSR_DOT11_MODE_11ac == phyMode) ||
694 (eCSR_DOT11_MODE_11ac_ONLY == phyMode))
695 {
696 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
697 "Setting phymode to 11n!!");
698 sme_SetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter), eCSR_DOT11_MODE_11n);
699 }
700 }
701 else
702 {
703 /*New country Supports 11ac as well resetting value back from .ini*/
704 sme_SetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter),
705 hdd_cfg_xlate_to_csr_phy_mode(cfg_param->dot11Mode));
706 return ;
707 }
708
709 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
710 ((eCSR_CFG_DOT11_MODE_11AC_ONLY == pHddStaCtx->conn_info.dot11Mode) ||
711 (eCSR_CFG_DOT11_MODE_11AC == pHddStaCtx->conn_info.dot11Mode)))
712 {
713 VOS_STATUS vosStatus;
714
715 // need to issue a disconnect to CSR.
716 INIT_COMPLETION(pAdapter->disconnect_comp_var);
717 vosStatus = sme_RoamDisconnect(WLAN_HDD_GET_HAL_CTX(pAdapter),
718 pAdapter->sessionId,
719 eCSR_DISCONNECT_REASON_UNSPECIFIED );
720
721 if (VOS_STATUS_SUCCESS == vosStatus)
c_hpothu6ff1c3c2013-10-01 19:01:57 +0530722 {
723 ret = wait_for_completion_interruptible_timeout(&pAdapter->disconnect_comp_var,
Gopichand Nakkaladacbcb52013-04-18 16:41:54 +0530724 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
c_hpothu6ff1c3c2013-10-01 19:01:57 +0530725 if (ret <= 0)
726 {
727 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
728 "wait on disconnect_comp_var is failed %ld", ret);
729 }
730 }
Gopichand Nakkaladacbcb52013-04-18 16:41:54 +0530731
732 }
733}
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -0700734#endif //CONFIG_ENABLE_LINUX_REG
Gopichand Nakkaladacbcb52013-04-18 16:41:54 +0530735
Tushnim Bhattacharyya9cdf6082013-04-21 16:33:30 -0700736void hdd_checkandupdate_dfssetting( hdd_adapter_t *pAdapter, char *country_code)
737{
738 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
739 hdd_config_t *cfg_param;
740
741 if (NULL == pHddCtx)
742 {
743 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
744 "HDD Context is null !!");
745 return ;
746 }
747
748 cfg_param = pHddCtx->cfg_ini;
749
750 if (NULL == cfg_param)
751 {
752 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
753 "cfg_params not available !!");
754 return ;
755 }
756
Agarwal Ashish738843c2014-09-25 12:27:56 +0530757 if (NULL != strstr(cfg_param->listOfNonDfsCountryCode, country_code) ||
758 pHddCtx->disable_dfs_flag == TRUE)
Tushnim Bhattacharyya9cdf6082013-04-21 16:33:30 -0700759 {
760 /*New country doesn't support DFS */
761 sme_UpdateDfsSetting(WLAN_HDD_GET_HAL_CTX(pAdapter), 0);
762 }
Tushnim Bhattacharyya9cdf6082013-04-21 16:33:30 -0700763
764}
765
Abhishek Singh00b71972016-01-07 10:51:04 +0530766#ifdef WLAN_FEATURE_RMC
767static int hdd_parse_setrmcenable_command(tANI_U8 *pValue, tANI_U8 *pRmcEnable)
768{
769 tANI_U8 *inPtr = pValue;
770 int tempInt;
771 int v = 0;
772 char buf[32];
773 *pRmcEnable = 0;
774
775 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
776 /*no argument after the command*/
777 if (NULL == inPtr)
778 {
779 return 0;
780 }
781
782 /*no space after the command*/
783 else if (SPACE_ASCII_VALUE != *inPtr)
784 {
785 return 0;
786 }
787
788 /*removing empty spaces*/
789 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
790
791 /*no argument followed by spaces*/
792 if ('\0' == *inPtr)
793 {
794 return 0;
795 }
796
797 /* getting the first argument which enables or disables RMC
798 * for input IP v4 address*/
Ashish Kumar Dhanotiya54d31a32017-08-04 17:12:44 +0530799 sscanf(inPtr, "%31s ", buf);
Abhishek Singh00b71972016-01-07 10:51:04 +0530800 v = kstrtos32(buf, 10, &tempInt);
801 if ( v < 0)
802 {
803 return -EINVAL;
804 }
805
806 *pRmcEnable = tempInt;
807
808 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
809 "ucRmcEnable: %d", *pRmcEnable);
810
811 return 0;
812}
813
814/* Function header left blank Intentionally */
815static int hdd_parse_setrmcactionperiod_command(tANI_U8 *pValue,
816 tANI_U32 *pActionPeriod)
817{
818 tANI_U8 *inPtr = pValue;
819 int tempInt;
820 int v = 0;
821 char buf[32];
822 *pActionPeriod = 0;
823
824 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
825 /*no argument after the command*/
826 if (NULL == inPtr)
827 {
828 return -EINVAL;
829 }
830
831 /*no space after the command*/
832 else if (SPACE_ASCII_VALUE != *inPtr)
833 {
834 return -EINVAL;
835 }
836
837 /*removing empty spaces*/
838 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
839
840 /*no argument followed by spaces*/
841 if ('\0' == *inPtr)
842 {
843 return 0;
844 }
845
846 /* getting the first argument which enables or disables RMC
847 * for input IP v4 address*/
Ashish Kumar Dhanotiya54d31a32017-08-04 17:12:44 +0530848 sscanf(inPtr, "%31s ", buf);
Abhishek Singh00b71972016-01-07 10:51:04 +0530849 v = kstrtos32(buf, 10, &tempInt);
850 if ( v < 0)
851 {
852 return -EINVAL;
853 }
854
855 /* Range checking for passed paramter */
856 if (tempInt < WNI_CFG_RMC_ACTION_PERIOD_FREQUENCY_STAMIN ||
857 tempInt > WNI_CFG_RMC_ACTION_PERIOD_FREQUENCY_STAMAX)
858 {
859 return -EINVAL;
860 }
861
862 *pActionPeriod = tempInt;
863
864 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
865 "uActionPeriod: %d", *pActionPeriod);
866
867 return 0;
868}
Dundi Ravitejae110a042018-04-18 13:11:37 +0530869
870/**
871 * hdd_set_vowifi_mode() - Process VOWIFI command.
872 * @hdd_ctx: context handler
Sourav Mohapatra2416e0e2018-03-05 18:44:21 +0530873 * @enable: Value to be sent as a part of the VOWIFI command
874 *
Dundi Ravitejae110a042018-04-18 13:11:37 +0530875 * Invoke the SME api if station is connected in 2.4 GHz band.
876 * Also start split scan if VOWIFIMODE and dynamic split scan
877 * both are enabled.
878
Sourav Mohapatra2416e0e2018-03-05 18:44:21 +0530879 * Return: void
880 */
881void hdd_set_vowifi_mode(hdd_context_t *hdd_ctx, bool enable)
882{
883 tANI_U8 sta_chan;
884
Dundi Ravitejaab9d3092018-04-05 18:24:40 +0530885 if (!hdd_ctx->cfg_ini) {
886 hddLog(LOGE, "cfg_ini got NULL");
887 return;
888 }
889
Sourav Mohapatra2416e0e2018-03-05 18:44:21 +0530890 sta_chan = hdd_get_operating_channel(hdd_ctx, WLAN_HDD_INFRA_STATION);
891
Dundi Ravitejae110a042018-04-18 13:11:37 +0530892 if (CSR_IS_CHANNEL_24GHZ(sta_chan))
Sourav Mohapatra2416e0e2018-03-05 18:44:21 +0530893 sme_set_vowifi_mode(hdd_ctx->hHal, enable);
Dundi Ravitejae110a042018-04-18 13:11:37 +0530894 else
Sourav Mohapatra2416e0e2018-03-05 18:44:21 +0530895 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
896 "VoWiFi command rejected as not connected in 2.4GHz");
Dundi Ravitejae110a042018-04-18 13:11:37 +0530897
898 if (enable && hdd_ctx->cfg_ini->dynSplitscan) {
899 hdd_ctx->is_vowifi_enabled = true;
900 hdd_ctx->issplitscan_enabled = TRUE;
901 sme_enable_disable_split_scan(hdd_ctx->hHal,
902 hdd_ctx->cfg_ini->nNumStaChanCombinedConc,
903 hdd_ctx->cfg_ini->nNumP2PChanCombinedConc);
904 } else {
905 hdd_ctx->is_vowifi_enabled = false;
Dundi Ravitejaab9d3092018-04-05 18:24:40 +0530906 }
Sourav Mohapatra2416e0e2018-03-05 18:44:21 +0530907}
Abhishek Singh00b71972016-01-07 10:51:04 +0530908
909/* Function header left blank Intentionally */
910static int hdd_parse_setrmcrate_command(tANI_U8 *pValue,
911 tANI_U32 *pRate, tTxrateinfoflags *pTxFlags)
912{
913 tANI_U8 *inPtr = pValue;
914 int tempInt;
915 int v = 0;
916 char buf[32];
917 *pRate = 0;
918 *pTxFlags = 0;
919
920 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
921 /*no argument after the command*/
922 if (NULL == inPtr)
923 {
924 return -EINVAL;
925 }
926
927 /*no space after the command*/
928 else if (SPACE_ASCII_VALUE != *inPtr)
929 {
930 return -EINVAL;
931 }
932
933 /*removing empty spaces*/
934 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
935
936 /*no argument followed by spaces*/
937 if ('\0' == *inPtr)
938 {
939 return 0;
940 }
941
942 /*
943 * getting the first argument which sets multicast rate.
944 */
Ashish Kumar Dhanotiya06f9f202017-08-04 15:26:27 +0530945 sscanf(inPtr, "%31s ", buf);
Abhishek Singh00b71972016-01-07 10:51:04 +0530946 v = kstrtos32(buf, 10, &tempInt);
947 if ( v < 0)
948 {
949 return -EINVAL;
950 }
951
952 /*
953 * Validate the multicast rate.
954 */
955 switch (tempInt)
956 {
957 default:
958 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
959 "Unsupported rate: %d", tempInt);
960 return -EINVAL;
961 case 0:
962 case 6:
963 case 9:
964 case 12:
965 case 18:
966 case 24:
967 case 36:
968 case 48:
969 case 54:
970 *pTxFlags = eHAL_TX_RATE_LEGACY;
971 *pRate = tempInt * 10;
972 break;
973 case 65:
974 *pTxFlags = eHAL_TX_RATE_HT20;
975 *pRate = tempInt * 10;
976 break;
977 case 72:
978 *pTxFlags = eHAL_TX_RATE_HT20 | eHAL_TX_RATE_SGI;
979 *pRate = 722; /* fractional rate 72.2 Mbps */
980 break;
981 }
982
983 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
984 "Rate: %d", *pRate);
985
986 return 0;
987}
988
989/**---------------------------------------------------------------------------
990
991 \brief hdd_cfg80211_get_ibss_peer_info_cb() - Callback function for IBSS
992 Peer Info request
993
994 This is an asynchronous callback function from SME when the peer info
995 is received
996
997 \pUserData -> Adapter private data
998 \pPeerInfoRsp -> Peer info response
999
1000 \return - 0 for success non-zero for failure
1001 --------------------------------------------------------------------------*/
1002static void
1003hdd_cfg80211_get_ibss_peer_info_cb(v_VOID_t *pUserData, v_VOID_t *pPeerInfoRsp)
1004{
1005 hdd_adapter_t *pAdapter = (hdd_adapter_t *)pUserData;
1006 tSirPeerInfoRspParams *pPeerInfo = (tSirPeerInfoRspParams *)pPeerInfoRsp;
1007 hdd_station_ctx_t *pStaCtx;
1008 v_U8_t i;
1009
1010 /*Sanity check*/
1011 if ((NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic))
1012 {
1013 hddLog(LOGE,
1014 FL("invalid adapter or adapter has invalid magic"));
1015 return;
1016 }
1017
1018 pStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
1019 if (NULL != pStaCtx && NULL != pPeerInfo &&
1020 eHAL_STATUS_SUCCESS == pPeerInfo->status)
1021 {
1022 pStaCtx->ibss_peer_info.status = pPeerInfo->status;
1023 pStaCtx->ibss_peer_info.numIBSSPeers = pPeerInfo->numPeers;
1024
1025 /* Paranoia check */
1026 if (pPeerInfo->numPeers < HDD_MAX_NUM_IBSS_STA)
1027 {
1028 for (i = 0; i < pPeerInfo->numPeers; i++)
1029 {
1030 memcpy(&pStaCtx->ibss_peer_info.ibssPeerList[i],
1031 &pPeerInfo->peerInfoParams[i],
1032 sizeof(hdd_ibss_peer_info_params_t));
1033 }
1034 hddLog(LOG1,
1035 FL("Peer Info copied in HDD"));
1036 }
1037 else
1038 {
1039 hddLog(LOGE,
1040 FL(" Number of peers %d returned is more than limit %d"),
1041 pPeerInfo->numPeers, HDD_MAX_NUM_IBSS_STA);
1042 }
1043 }
1044 else
1045 {
1046 hddLog(LOG1,
1047 FL("peerInfo returned is NULL"));
1048 }
1049
1050 complete(&pAdapter->ibss_peer_info_comp);
1051}
1052
1053/**---------------------------------------------------------------------------
1054
1055 \brief hdd_cfg80211_get_ibss_peer_info_all() -
1056
1057 Request function to get IBSS peer info from lower layers
1058
1059 \pAdapter -> Adapter context
1060
1061 \return - 0 for success non-zero for failure
1062 --------------------------------------------------------------------------*/
1063static
1064VOS_STATUS hdd_cfg80211_get_ibss_peer_info_all(hdd_adapter_t *pAdapter)
1065{
1066 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
1067 long status;
1068 VOS_STATUS retStatus = VOS_STATUS_E_FAILURE;
1069
1070 INIT_COMPLETION(pAdapter->ibss_peer_info_comp);
1071
1072 retStatus = sme_RequestIBSSPeerInfo(hHal, pAdapter,
1073 hdd_cfg80211_get_ibss_peer_info_cb,
1074 VOS_TRUE, 0xFF);
1075
1076 if (VOS_STATUS_SUCCESS == retStatus)
1077 {
1078 status = wait_for_completion_interruptible_timeout
1079 (&pAdapter->ibss_peer_info_comp,
1080 msecs_to_jiffies(IBSS_PEER_INFO_REQ_TIMOEUT));
1081
1082 /* status will be 0 if timed out */
1083 if (status <= 0)
1084 {
1085 hddLog(VOS_TRACE_LEVEL_WARN, "%s: Warning: IBSS_PEER_INFO_TIMEOUT %ld",
1086 __func__, status);
1087 retStatus = VOS_STATUS_E_FAILURE;
1088 return retStatus;
1089 }
1090 }
1091 else
1092 {
1093 hddLog(VOS_TRACE_LEVEL_WARN,
1094 "%s: Warning: sme_RequestIBSSPeerInfo Request failed", __func__);
1095 }
1096
1097 return retStatus;
1098}
1099
1100/**---------------------------------------------------------------------------
1101
1102 \brief hdd_cfg80211_get_ibss_peer_info() -
1103
1104 Request function to get IBSS peer info from lower layers
1105
1106 \pAdapter -> Adapter context
1107 \staIdx -> Sta index for which the peer info is requested
1108
1109 \return - 0 for success non-zero for failure
1110 --------------------------------------------------------------------------*/
1111static VOS_STATUS
1112hdd_cfg80211_get_ibss_peer_info(hdd_adapter_t *pAdapter, v_U8_t staIdx)
1113{
1114 long status;
1115 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
1116 VOS_STATUS retStatus = VOS_STATUS_E_FAILURE;
1117
1118 INIT_COMPLETION(pAdapter->ibss_peer_info_comp);
1119
1120 retStatus = sme_RequestIBSSPeerInfo(hHal, pAdapter,
1121 hdd_cfg80211_get_ibss_peer_info_cb,
1122 VOS_FALSE, staIdx);
1123
1124 if (VOS_STATUS_SUCCESS == retStatus)
1125 {
1126 status = wait_for_completion_interruptible_timeout
1127 (&pAdapter->ibss_peer_info_comp,
1128 msecs_to_jiffies(IBSS_PEER_INFO_REQ_TIMOEUT));
1129
1130 /* status = 0 on timeout */
1131 if (status <= 0)
1132 {
1133 hddLog(VOS_TRACE_LEVEL_WARN, "%s: Warning: IBSS_PEER_INFO_TIMEOUT %ld",
1134 __func__, status);
1135 retStatus = VOS_STATUS_E_FAILURE;
1136 return retStatus;
1137 }
1138 }
1139 else
1140 {
1141 hddLog(VOS_TRACE_LEVEL_WARN,
1142 "%s: Warning: sme_RequestIBSSPeerInfo Request failed", __func__);
1143 }
1144
1145 return retStatus;
1146}
1147
1148/* Function header left blank Intentionally */
1149VOS_STATUS
1150hdd_parse_get_ibss_peer_info(tANI_U8 *pValue, v_MACADDR_t *pPeerMacAddr)
1151{
1152 tANI_U8 *inPtr = pValue;
1153 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
1154
1155 /*no argument after the command*/
1156 if (NULL == inPtr)
1157 {
1158 return VOS_STATUS_E_FAILURE;;
1159 }
1160
1161 /*no space after the command*/
1162 else if (SPACE_ASCII_VALUE != *inPtr)
1163 {
1164 return VOS_STATUS_E_FAILURE;;
1165 }
1166
1167 /*removing empty spaces*/
1168 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
1169
1170 /*no argument followed by spaces*/
1171 if ('\0' == *inPtr)
1172 {
1173 return VOS_STATUS_E_FAILURE;;
1174 }
1175
1176 /*getting the first argument ie the peer mac address */
1177 if (inPtr[2] != ':' || inPtr[5] != ':' || inPtr[8] != ':' ||
1178 inPtr[11] != ':' || inPtr[14] != ':')
1179 {
1180 return VOS_STATUS_E_FAILURE;;
1181 }
1182 sscanf(inPtr, "%2x:%2x:%2x:%2x:%2x:%2x",
1183 (unsigned int *)&pPeerMacAddr->bytes[0],
1184 (unsigned int *)&pPeerMacAddr->bytes[1],
1185 (unsigned int *)&pPeerMacAddr->bytes[2],
1186 (unsigned int *)&pPeerMacAddr->bytes[3],
1187 (unsigned int *)&pPeerMacAddr->bytes[4],
1188 (unsigned int *)&pPeerMacAddr->bytes[5]);
1189
1190 /* The command buffer seems to be fine */
1191 return VOS_STATUS_SUCCESS;
1192}
1193
1194/* Function header left blank Intentionally */
1195static int hdd_parse_set_ibss_oui_data_command(tANI_U8 *command, tANI_U8 *ie,
1196 tANI_U32 limit)
1197{
1198 tANI_U8 len;
1199 tANI_U8 data;
1200
1201 /* skip white space */
1202 while ((SPACE_ASCII_VALUE == *command) && ('\0' != *command))
1203 {
1204 command++;
1205 limit--;
1206 }
1207
1208 /* skip element id and element length */
1209 len = 2;
1210
1211 /* extract oui */
1212 while ((SPACE_ASCII_VALUE != *command) && ('\0' != *command) &&
1213 (limit > 1))
1214 {
1215 /* Convert ASCII to decimal */
1216 data = ((*command -'0') << 4) | (*(command + 1) - '0');
1217 ie[len++] = data;
1218 command += 2;
1219 limit -= 2;
1220 }
1221
1222 /* skip white space */
1223 while ((SPACE_ASCII_VALUE == *command) && ('\0' != *command))
1224 {
1225 command++;
1226 limit--;
1227 }
1228
1229 /* extract data */
1230 while ((SPACE_ASCII_VALUE != *command) && ('\0' != *command) &&
1231 (limit > 1))
1232 {
1233 /* Convert ASCII to decimal */
1234 data = ((*command -'0') << 4) | (*(command + 1) - '0');
1235 ie[len++] = data;
1236 command += 2;
1237 limit -= 2;
1238 }
1239
1240 /* fill element id and element length */
1241 ie[0] = IE_EID_VENDOR;
1242 ie[1] = len - 2;
1243
1244 return len;
1245}
1246
1247static tANI_U32 hdd_find_ibss_wpa_ie_pos(tANI_U8 *addIePtr, tANI_U32 addIeLen)
1248{
1249 tANI_U32 ieLenPresent = 0;
1250 int left = addIeLen;
1251 v_U8_t *ptr = addIePtr;
1252 v_U8_t elem_id,elem_len;
1253
1254 while(left >= 2)
1255 {
1256 elem_id = ptr[0];
1257 elem_len = ptr[1];
1258 left -= 2;
1259 if(elem_len > left)
1260 {
1261 hddLog(LOGE,
1262 FL("****Invalid elem_len=%d left=%d*****"),
1263 elem_len,left);
1264 return 0;
1265 }
1266 if ((elem_id == IE_EID_VENDOR) &&
1267 (left >= WPA_OUI_TYPE_SIZE))
1268 {
1269 if (!memcmp(&ptr[2], WPA_OUI_TYPE,
1270 WPA_OUI_TYPE_SIZE))
1271 {
1272 ieLenPresent += elem_len + 2;
1273 return ieLenPresent;
1274 }
1275 }
1276 ieLenPresent += (elem_len + 2);
1277 left -= elem_len;
1278 ptr += (elem_len + 2);
1279 }
1280 return 0;
1281}
1282
1283#endif /* WLAN_FEATURE_RMC */
1284
Rajeev79dbe4c2013-10-05 11:03:42 +05301285#ifdef FEATURE_WLAN_BATCH_SCAN
1286
1287/**---------------------------------------------------------------------------
1288
1289 \brief hdd_extract_assigned_int_from_str() - Extracts assigned integer from
1290 input string
1291
1292 This function extracts assigned integer from string in below format:
1293 "STRING=10" : extracts integer 10 from this string
1294
1295 \param - pInPtr Pointer to input string
1296 \param - base Base for string to int conversion(10 for decimal 16 for hex)
1297 \param - pOutPtr Pointer to variable in which extracted integer needs to be
1298 assigned
1299 \param - pLastArg to tell whether it is last arguement in input string or
1300 not
1301
1302 \return - NULL for failure cases
1303 pointer to next arguement in input string for success cases
1304 --------------------------------------------------------------------------*/
1305static tANI_U8 *
1306hdd_extract_assigned_int_from_str
1307(
1308 tANI_U8 *pInPtr,
1309 tANI_U8 base,
1310 tANI_U32 *pOutPtr,
1311 tANI_U8 *pLastArg
1312)
1313{
1314 int tempInt;
1315 int v = 0;
1316 char buf[32];
1317 int val = 0;
1318 *pLastArg = FALSE;
1319
1320 pInPtr = strnchr(pInPtr, strlen(pInPtr), EQUALS_TO_ASCII_VALUE);
1321 if (NULL == pInPtr)
1322 {
1323 return NULL;
1324 }
1325
1326 pInPtr++;
1327
1328 while ((SPACE_ASCII_VALUE == *pInPtr) && ('\0' != *pInPtr)) pInPtr++;
1329
1330 val = sscanf(pInPtr, "%32s ", buf);
1331 if (val < 0 && val > strlen(pInPtr))
1332 {
1333 return NULL;
1334 }
1335 pInPtr += val;
1336 v = kstrtos32(buf, base, &tempInt);
1337 if (v < 0)
1338 {
1339 return NULL;
1340 }
Rajeev Kumar4d93d842014-01-02 18:31:21 -08001341 if (tempInt < 0)
1342 {
1343 tempInt = 0;
1344 }
Rajeev79dbe4c2013-10-05 11:03:42 +05301345 *pOutPtr = tempInt;
1346
1347 pInPtr = strnchr(pInPtr, strlen(pInPtr), SPACE_ASCII_VALUE);
1348 if (NULL == pInPtr)
1349 {
1350 *pLastArg = TRUE;
1351 return NULL;
1352 }
1353 while ((SPACE_ASCII_VALUE == *pInPtr) && ('\0' != *pInPtr)) pInPtr++;
1354
1355 return pInPtr;
1356}
1357
1358/**---------------------------------------------------------------------------
1359
1360 \brief hdd_extract_assigned_char_from_str() - Extracts assigned char from
1361 input string
1362
1363 This function extracts assigned character from string in below format:
1364 "STRING=A" : extracts char 'A' from this string
1365
1366 \param - pInPtr Pointer to input string
1367 \param - pOutPtr Pointer to variable in which extracted char needs to be
1368 assigned
1369 \param - pLastArg to tell whether it is last arguement in input string or
1370 not
1371
1372 \return - NULL for failure cases
1373 pointer to next arguement in input string for success cases
1374 --------------------------------------------------------------------------*/
1375static tANI_U8 *
1376hdd_extract_assigned_char_from_str
1377(
1378 tANI_U8 *pInPtr,
1379 tANI_U8 *pOutPtr,
1380 tANI_U8 *pLastArg
1381)
1382{
1383 *pLastArg = FALSE;
1384
1385 pInPtr = strnchr(pInPtr, strlen(pInPtr), EQUALS_TO_ASCII_VALUE);
1386 if (NULL == pInPtr)
1387 {
1388 return NULL;
1389 }
1390
1391 pInPtr++;
1392
1393 while ((SPACE_ASCII_VALUE == *pInPtr) && ('\0' != *pInPtr)) pInPtr++;
1394
1395 *pOutPtr = *pInPtr;
1396
1397 pInPtr = strnchr(pInPtr, strlen(pInPtr), SPACE_ASCII_VALUE);
1398 if (NULL == pInPtr)
1399 {
1400 *pLastArg = TRUE;
1401 return NULL;
1402 }
1403 while ((SPACE_ASCII_VALUE == *pInPtr) && ('\0' != *pInPtr)) pInPtr++;
1404
1405 return pInPtr;
1406}
1407
1408
1409/**---------------------------------------------------------------------------
1410
1411 \brief hdd_parse_set_batchscan_command () - HDD parse set batch scan command
1412
1413 This function parses set batch scan command in below format:
1414 WLS_BATCHING_SET <space> followed by below arguements
1415 "SCANFREQ=XX" : Optional defaults to 30 sec
1416 "MSCAN=XX" : Required number of scans to attempt to batch
1417 "BESTN=XX" : Best Network (RSSI) defaults to 16
1418 "CHANNEL=<X,Y>" : optional defaults to all channels, can list 'A'or` B.
1419 A. implies only 5 GHz , B. implies only 2.4GHz
1420 "RTT=X" : optional defaults to 0
1421 returns the MIN of MSCAN or the max # of scans firmware can cache or -1 on
1422 error
1423
1424 For example input commands:
1425 1) WLS_BATCHING_SET SCANFREQ=60 MSCAN=10 BESTN=20 CHANNEL=A RTT=0 -> This is
1426 translated into set batch scan with following parameters:
1427 a) Frequence 60 seconds
1428 b) Batch 10 scans together
1429 c) Best RSSI to be 20
1430 d) 5GHz band only
1431 e) RTT is equal to 0
1432
1433 \param - pValue Pointer to input channel list
1434 \param - pHddSetBatchScanReq Pointer to HDD batch scan request structure
1435
1436 \return - 0 for success non-zero for failure
1437
1438 --------------------------------------------------------------------------*/
1439static int
1440hdd_parse_set_batchscan_command
1441(
1442 tANI_U8 *pValue,
1443 tSirSetBatchScanReq *pHddSetBatchScanReq
1444)
1445{
1446 tANI_U8 *inPtr = pValue;
1447 tANI_U8 val = 0;
1448 tANI_U8 lastArg = 0;
Abhishek Singh00b71972016-01-07 10:51:04 +05301449 tANI_U32 nScanFreq = HDD_SET_BATCH_SCAN_DEFAULT_FREQ;
Rajeev Kumar45e64a72013-11-18 19:48:15 -08001450 tANI_U32 nMscan;
Abhishek Singh00b71972016-01-07 10:51:04 +05301451 tANI_U32 nBestN = HDD_SET_BATCH_SCAN_BEST_NETWORK;
1452 tANI_U8 ucRfBand = HDD_SET_BATCH_SCAN_DEFAULT_BAND;
1453 tANI_U32 nRtt = 0;
Rajeev Kumarc933d982013-11-18 20:04:20 -08001454 tANI_U32 temp;
Rajeev79dbe4c2013-10-05 11:03:42 +05301455
Rajeev79dbe4c2013-10-05 11:03:42 +05301456 /*go to space after WLS_BATCHING_SET command*/
1457 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
1458 /*no argument after the command*/
1459 if (NULL == inPtr)
1460 {
1461 return -EINVAL;
1462 }
1463
1464 /*no space after the command*/
1465 else if (SPACE_ASCII_VALUE != *inPtr)
1466 {
1467 return -EINVAL;
1468 }
1469
1470 /*removing empty spaces*/
1471 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
1472
1473 /*no argument followed by spaces*/
1474 if ('\0' == *inPtr)
1475 {
1476 return -EINVAL;
1477 }
1478
1479 /*check and parse SCANFREQ*/
1480 if ((strncmp(inPtr, "SCANFREQ", 8) == 0))
1481 {
1482 inPtr = hdd_extract_assigned_int_from_str(inPtr, 10,
Rajeev Kumarc933d982013-11-18 20:04:20 -08001483 &temp, &lastArg);
Rajeev Kumar45e64a72013-11-18 19:48:15 -08001484
Rajeev Kumarc933d982013-11-18 20:04:20 -08001485 if (0 != temp)
Rajeev Kumar45e64a72013-11-18 19:48:15 -08001486 {
Rajeev Kumarc933d982013-11-18 20:04:20 -08001487 nScanFreq = temp;
Rajeev Kumar45e64a72013-11-18 19:48:15 -08001488 }
1489
Rajeev79dbe4c2013-10-05 11:03:42 +05301490 if ( (NULL == inPtr) || (TRUE == lastArg))
1491 {
1492 return -EINVAL;
1493 }
1494 }
1495
1496 /*check and parse MSCAN*/
1497 if ((strncmp(inPtr, "MSCAN", 5) == 0))
1498 {
1499 inPtr = hdd_extract_assigned_int_from_str(inPtr, 10,
Rajeev Kumar45e64a72013-11-18 19:48:15 -08001500 &nMscan, &lastArg);
1501
1502 if (0 == nMscan)
1503 {
1504 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1505 "invalid MSCAN=%d", nMscan);
1506 return -EINVAL;
1507 }
1508
Rajeev79dbe4c2013-10-05 11:03:42 +05301509 if (TRUE == lastArg)
1510 {
1511 goto done;
1512 }
1513 else if (NULL == inPtr)
1514 {
1515 return -EINVAL;
1516 }
1517 }
1518 else
1519 {
1520 return -EINVAL;
1521 }
1522
1523 /*check and parse BESTN*/
1524 if ((strncmp(inPtr, "BESTN", 5) == 0))
1525 {
1526 inPtr = hdd_extract_assigned_int_from_str(inPtr, 10,
Rajeev Kumarc933d982013-11-18 20:04:20 -08001527 &temp, &lastArg);
Rajeev Kumar45e64a72013-11-18 19:48:15 -08001528
Rajeev Kumarc933d982013-11-18 20:04:20 -08001529 if (0 != temp)
Rajeev Kumar45e64a72013-11-18 19:48:15 -08001530 {
Rajeev Kumarc933d982013-11-18 20:04:20 -08001531 nBestN = temp;
Rajeev Kumar45e64a72013-11-18 19:48:15 -08001532 }
1533
Rajeev79dbe4c2013-10-05 11:03:42 +05301534 if (TRUE == lastArg)
1535 {
1536 goto done;
1537 }
1538 else if (NULL == inPtr)
1539 {
1540 return -EINVAL;
1541 }
1542 }
1543
1544 /*check and parse CHANNEL*/
1545 if ((strncmp(inPtr, "CHANNEL", 7) == 0))
1546 {
1547 inPtr = hdd_extract_assigned_char_from_str(inPtr, &val, &lastArg);
Rajeev Kumarc933d982013-11-18 20:04:20 -08001548
Rajeev79dbe4c2013-10-05 11:03:42 +05301549 if (('A' == val) || ('a' == val))
1550 {
c_hpothuebf89732014-02-25 13:00:24 +05301551 ucRfBand = HDD_SET_BATCH_SCAN_5GHz_BAND_ONLY;
Rajeev79dbe4c2013-10-05 11:03:42 +05301552 }
1553 else if (('B' == val) || ('b' == val))
1554 {
c_hpothuebf89732014-02-25 13:00:24 +05301555 ucRfBand = HDD_SET_BATCH_SCAN_24GHz_BAND_ONLY;
Rajeev79dbe4c2013-10-05 11:03:42 +05301556 }
1557 else
1558 {
Rajeev Kumarc933d982013-11-18 20:04:20 -08001559 ucRfBand = HDD_SET_BATCH_SCAN_DEFAULT_BAND;
1560 }
1561
1562 if (TRUE == lastArg)
1563 {
1564 goto done;
1565 }
1566 else if (NULL == inPtr)
1567 {
Rajeev79dbe4c2013-10-05 11:03:42 +05301568 return -EINVAL;
1569 }
1570 }
1571
1572 /*check and parse RTT*/
1573 if ((strncmp(inPtr, "RTT", 3) == 0))
1574 {
1575 inPtr = hdd_extract_assigned_int_from_str(inPtr, 10,
Rajeev Kumar45e64a72013-11-18 19:48:15 -08001576 &nRtt, &lastArg);
Rajeev79dbe4c2013-10-05 11:03:42 +05301577 if (TRUE == lastArg)
1578 {
1579 goto done;
1580 }
1581 if (NULL == inPtr)
1582 {
1583 return -EINVAL;
1584 }
1585 }
1586
1587
1588done:
1589
Rajeev Kumar45e64a72013-11-18 19:48:15 -08001590 pHddSetBatchScanReq->scanFrequency = nScanFreq;
1591 pHddSetBatchScanReq->numberOfScansToBatch = nMscan;
1592 pHddSetBatchScanReq->bestNetwork = nBestN;
1593 pHddSetBatchScanReq->rfBand = ucRfBand;
1594 pHddSetBatchScanReq->rtt = nRtt;
1595
Rajeev79dbe4c2013-10-05 11:03:42 +05301596 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1597 "Received WLS_BATCHING_SET with SCANFREQ=%d "
1598 "MSCAN=%d BESTN=%d CHANNEL=%d RTT=%d",
1599 pHddSetBatchScanReq->scanFrequency,
1600 pHddSetBatchScanReq->numberOfScansToBatch,
1601 pHddSetBatchScanReq->bestNetwork,
1602 pHddSetBatchScanReq->rfBand,
1603 pHddSetBatchScanReq->rtt);
1604
1605 return 0;
1606}/*End of hdd_parse_set_batchscan_command*/
1607
1608/**---------------------------------------------------------------------------
1609
1610 \brief hdd_set_batch_scan_req_callback () - This function is called after
1611 receiving set batch scan response from FW and it saves set batch scan
1612 response data FW to HDD context and sets the completion event on
1613 which hdd_ioctl is waiting
1614
1615 \param - callbackContext Pointer to HDD adapter
1616 \param - pRsp Pointer to set batch scan response data received from FW
1617
1618 \return - nothing
1619
1620 --------------------------------------------------------------------------*/
1621static void hdd_set_batch_scan_req_callback
1622(
1623 void *callbackContext,
1624 tSirSetBatchScanRsp *pRsp
1625)
1626{
1627 hdd_adapter_t* pAdapter = (hdd_adapter_t*)callbackContext;
1628 tSirSetBatchScanRsp *pHddSetBatchScanRsp;
1629
1630 /*sanity check*/
1631 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
1632 {
1633 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1634 "%s: Invalid pAdapter magic", __func__);
1635 VOS_ASSERT(0);
1636 return;
1637 }
1638 pHddSetBatchScanRsp = &pAdapter->hddSetBatchScanRsp;
1639
1640 /*save set batch scan response*/
1641 pHddSetBatchScanRsp->nScansToBatch = pRsp->nScansToBatch;
1642
1643 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
1644 "Received set batch scan rsp from FW with nScansToBatch=%d",
1645 pHddSetBatchScanRsp->nScansToBatch);
1646
1647 pAdapter->hdd_wait_for_set_batch_scan_rsp = FALSE;
1648 complete(&pAdapter->hdd_set_batch_scan_req_var);
1649
1650 return;
1651}/*End of hdd_set_batch_scan_req_callback*/
1652
1653
1654/**---------------------------------------------------------------------------
1655
1656 \brief hdd_populate_batch_scan_rsp_queue () - This function stores AP meta
1657 info in hdd batch scan response queue
1658
1659 \param - pAdapter Pointer to hdd adapter
1660 \param - pAPMetaInfo Pointer to access point meta info
1661 \param - scanId scan ID of batch scan response
1662 \param - isLastAp tells whether AP is last AP in batch scan response or not
1663
1664 \return - nothing
1665
1666 --------------------------------------------------------------------------*/
1667static void hdd_populate_batch_scan_rsp_queue( hdd_adapter_t* pAdapter,
1668 tpSirBatchScanNetworkInfo pApMetaInfo, tANI_U32 scanId, v_BOOL_t isLastAp)
1669{
1670 tHddBatchScanRsp *pHead;
1671 tHddBatchScanRsp *pNode;
1672 tHddBatchScanRsp *pPrev;
1673 tHddBatchScanRsp *pTemp;
1674 tANI_U8 ssidLen;
1675
1676 /*head of hdd batch scan response queue*/
1677 pHead = pAdapter->pBatchScanRsp;
1678
1679 pNode = (tHddBatchScanRsp *)vos_mem_malloc(sizeof(tHddBatchScanRsp));
1680 if (NULL == pNode)
1681 {
1682 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1683 "%s: Could not allocate memory", __func__);
1684 VOS_ASSERT(0);
1685 return;
1686 }
1687
1688 vos_mem_copy(pNode->ApInfo.bssid, pApMetaInfo->bssid,
1689 sizeof(pNode->ApInfo.bssid));
1690 ssidLen = strlen(pApMetaInfo->ssid);
1691 if (SIR_MAX_SSID_SIZE < ssidLen)
1692 {
1693 /*invalid scan result*/
1694 vos_mem_free(pNode);
1695 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1696 "%s: Invalid AP meta info ssidlen %d", __func__, ssidLen);
1697 return;
1698 }
1699 vos_mem_copy(pNode->ApInfo.ssid, pApMetaInfo->ssid, ssidLen);
1700 /*null terminate ssid*/
1701 pNode->ApInfo.ssid[ssidLen] = '\0';
1702 pNode->ApInfo.ch = pApMetaInfo->ch;
1703 pNode->ApInfo.rssi = pApMetaInfo->rssi;
1704 pNode->ApInfo.age = pApMetaInfo->timestamp;
1705 pNode->ApInfo.batchId = scanId;
1706 pNode->ApInfo.isLastAp = isLastAp;
1707
1708 pNode->pNext = NULL;
1709 if (NULL == pHead)
1710 {
1711 pAdapter->pBatchScanRsp = pNode;
1712 }
1713 else
1714 {
1715 pTemp = pHead;
1716 while (NULL != pTemp)
1717 {
1718 pPrev = pTemp;
1719 pTemp = pTemp->pNext;
1720 }
1721 pPrev->pNext = pNode;
1722 }
1723
1724 return;
1725}/*End of hdd_populate_batch_scan_rsp_queue*/
1726
1727/**---------------------------------------------------------------------------
1728
1729 \brief hdd_batch_scan_result_ind_callback () - This function is called after
1730 receiving batch scan response indication from FW. It saves get batch scan
1731 response data in HDD batch scan response queue. This callback sets the
1732 completion event on which hdd_ioctl is waiting only after getting complete
1733 batch scan response data from FW
1734
1735 \param - callbackContext Pointer to HDD adapter
1736 \param - pRsp Pointer to get batch scan response data received from FW
1737
1738 \return - nothing
1739
1740 --------------------------------------------------------------------------*/
1741static void hdd_batch_scan_result_ind_callback
1742(
1743 void *callbackContext,
1744 void *pRsp
1745)
1746{
1747 v_BOOL_t isLastAp;
1748 tANI_U32 numApMetaInfo;
Rajeev Kumarce651e42013-10-21 18:57:15 -07001749 tANI_U32 numNetworkInScanList;
Rajeev79dbe4c2013-10-05 11:03:42 +05301750 tANI_U32 numberScanList;
1751 tANI_U32 nextScanListOffset;
1752 tANI_U32 nextApMetaInfoOffset;
1753 hdd_adapter_t* pAdapter;
1754 tpSirBatchScanList pScanList;
1755 tpSirBatchScanNetworkInfo pApMetaInfo;
1756 tpSirBatchScanResultIndParam pBatchScanRsp;/*batch scan rsp data from FW*/
1757 tSirSetBatchScanReq *pReq;
1758
1759 pAdapter = (hdd_adapter_t *)callbackContext;
1760 /*sanity check*/
Rajeev Kumar5286bb92013-12-05 11:52:10 -08001761 if ((NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic))
Rajeev79dbe4c2013-10-05 11:03:42 +05301762 {
1763 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1764 "%s: Invalid pAdapter magic", __func__);
1765 VOS_ASSERT(0);
1766 return;
1767 }
1768
1769 /*initialize locals*/
1770 pReq = &pAdapter->hddSetBatchScanReq;
1771 pBatchScanRsp = (tpSirBatchScanResultIndParam)pRsp;
1772 isLastAp = FALSE;
1773 numApMetaInfo = 0;
Rajeev Kumarce651e42013-10-21 18:57:15 -07001774 numNetworkInScanList = 0;
Rajeev79dbe4c2013-10-05 11:03:42 +05301775 numberScanList = 0;
1776 nextScanListOffset = 0;
1777 nextApMetaInfoOffset = 0;
1778 pScanList = NULL;
1779 pApMetaInfo = NULL;
1780
1781 if ((NULL == pBatchScanRsp) || (NULL == pReq))
1782 {
1783 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnsonc135a9a2017-09-19 08:37:24 -07001784 "%s: pBatchScanRsp is %pK pReq %pK", __func__, pBatchScanRsp, pReq);
Rajeev79dbe4c2013-10-05 11:03:42 +05301785 isLastAp = TRUE;
1786 goto done;
1787 }
1788
1789 pAdapter->numScanList = numberScanList = pBatchScanRsp->numScanLists;
1790 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1791 "Batch scan rsp: numberScalList %d", numberScanList);
1792
1793 if ((!numberScanList) || (numberScanList > pReq->numberOfScansToBatch))
1794 {
1795 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1796 "%s: numberScanList %d", __func__, numberScanList);
1797 isLastAp = TRUE;
1798 goto done;
1799 }
1800
1801 while (numberScanList)
1802 {
Rajeev Kumarce651e42013-10-21 18:57:15 -07001803 pScanList = (tpSirBatchScanList)((tANI_U8 *)pBatchScanRsp->scanResults +
Rajeev79dbe4c2013-10-05 11:03:42 +05301804 nextScanListOffset);
1805 if (NULL == pScanList)
1806 {
1807 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnsonc135a9a2017-09-19 08:37:24 -07001808 "%s: pScanList is %pK", __func__, pScanList);
Rajeev79dbe4c2013-10-05 11:03:42 +05301809 isLastAp = TRUE;
1810 goto done;
1811 }
Rajeev Kumarce651e42013-10-21 18:57:15 -07001812 numNetworkInScanList = numApMetaInfo = pScanList->numNetworksInScanList;
Rajeev79dbe4c2013-10-05 11:03:42 +05301813 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Rajeev Kumarce651e42013-10-21 18:57:15 -07001814 "Batch scan rsp: numApMetaInfo %d scanId %d",
1815 numApMetaInfo, pScanList->scanId);
Rajeev79dbe4c2013-10-05 11:03:42 +05301816
1817 if ((!numApMetaInfo) || (numApMetaInfo > pReq->bestNetwork))
1818 {
1819 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1820 "%s: numApMetaInfo %d", __func__, numApMetaInfo);
1821 isLastAp = TRUE;
1822 goto done;
1823 }
1824
Rajeev Kumarce651e42013-10-21 18:57:15 -07001825 /*Initialize next AP meta info offset for next scan list*/
1826 nextApMetaInfoOffset = 0;
1827
Rajeev79dbe4c2013-10-05 11:03:42 +05301828 while (numApMetaInfo)
1829 {
1830 pApMetaInfo = (tpSirBatchScanNetworkInfo)(pScanList->scanList +
1831 nextApMetaInfoOffset);
1832 if (NULL == pApMetaInfo)
1833 {
1834 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnsonc135a9a2017-09-19 08:37:24 -07001835 "%s: pApMetaInfo is %pK", __func__, pApMetaInfo);
Rajeev79dbe4c2013-10-05 11:03:42 +05301836 isLastAp = TRUE;
1837 goto done;
1838 }
1839 /*calculate AP age*/
1840 pApMetaInfo->timestamp =
1841 pBatchScanRsp->timestamp - pApMetaInfo->timestamp;
1842
1843 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
Arif Hussaina7c8e412013-11-20 11:06:42 -08001844 "%s: bssId "MAC_ADDRESS_STR
1845 " ch %d rssi %d timestamp %d", __func__,
1846 MAC_ADDR_ARRAY(pApMetaInfo->bssid),
1847 pApMetaInfo->ch, pApMetaInfo->rssi,
1848 pApMetaInfo->timestamp);
Rajeev79dbe4c2013-10-05 11:03:42 +05301849
1850 /*mark last AP in batch scan response*/
1851 if ((TRUE == pBatchScanRsp->isLastResult) &&
1852 (1 == numberScanList) && (1 == numApMetaInfo))
1853 {
1854 isLastAp = TRUE;
1855 }
1856
1857 mutex_lock(&pAdapter->hdd_batch_scan_lock);
1858 /*store batch scan repsonse in hdd queue*/
1859 hdd_populate_batch_scan_rsp_queue(pAdapter, pApMetaInfo,
1860 pScanList->scanId, isLastAp);
1861 mutex_unlock(&pAdapter->hdd_batch_scan_lock);
1862
1863 nextApMetaInfoOffset += sizeof(tSirBatchScanNetworkInfo);
1864 numApMetaInfo--;
1865 }
1866
Rajeev Kumarce651e42013-10-21 18:57:15 -07001867 nextScanListOffset += ((sizeof(tSirBatchScanList) - sizeof(tANI_U8))
1868 + (sizeof(tSirBatchScanNetworkInfo)
1869 * numNetworkInScanList));
Rajeev79dbe4c2013-10-05 11:03:42 +05301870 numberScanList--;
1871 }
1872
1873done:
1874
1875 /*notify hdd_ioctl only if complete batch scan rsp is received and it was
1876 requested from hdd_ioctl*/
1877 if ((TRUE == pAdapter->hdd_wait_for_get_batch_scan_rsp) &&
1878 (TRUE == isLastAp))
1879 {
1880 pAdapter->hdd_wait_for_get_batch_scan_rsp = FALSE;
1881 complete(&pAdapter->hdd_get_batch_scan_req_var);
1882 }
1883
1884 return;
1885}/*End of hdd_batch_scan_result_ind_callback*/
1886
1887/**---------------------------------------------------------------------------
1888
1889 \brief hdd_format_batch_scan_rsp () - This function formats batch scan
1890 response as per batch scan FR request format by putting proper markers
1891
1892 \param - pDest pointer to destination buffer
1893 \param - cur_len current length
1894 \param - tot_len total remaining size which can be written to user space
1895 \param - pApMetaInfo Pointer to get batch scan response AP meta info
1896 \param - pAdapter Pointer to HDD adapter
1897
1898 \return - ret no of characters written
1899
1900 --------------------------------------------------------------------------*/
1901static tANI_U32
1902hdd_format_batch_scan_rsp
1903(
1904 tANI_U8 *pDest,
1905 tANI_U32 cur_len,
1906 tANI_U32 tot_len,
1907 tHddBatchScanRsp *pApMetaInfo,
1908 hdd_adapter_t* pAdapter
1909)
1910{
1911 tANI_U32 ret = 0;
1912 tANI_U32 rem_len = 0;
1913 tANI_U8 temp_len = 0;
1914 tANI_U8 temp_total_len = 0;
1915 tANI_U8 temp[HDD_BATCH_SCAN_AP_META_INFO_SIZE];
1916 tANI_U8 *pTemp = temp;
1917
1918 /*Batch scan reponse needs to be returned to user space in
1919 following format:
1920 "scancount=X\n" where X is the number of scans in current batch
1921 batch
1922 "trunc\n" optional present if current scan truncated
1923 "bssid=XX:XX:XX:XX:XX:XX\n"
1924 "ssid=XXXX\n"
1925 "freq=X\n" frequency in Mhz
1926 "level=XX\n"
1927 "age=X\n" ms
1928 "dist=X\n" cm (-1 if not available)
1929 "errror=X\n" (-1if not available)
1930 "====\n" (end of ap marker)
1931 "####\n" (end of scan marker)
1932 "----\n" (end of results)*/
1933 /*send scan result in above format to user space based on
1934 available length*/
1935 /*The GET response may have more data than the driver can return in its
1936 buffer. In that case the buffer should be filled to the nearest complete
1937 scan, ending with "%%%%".Subsequent callsshould return the remaining data
1938 starting with the next scan (optional .trunc\n., .apcount=X\n., etc).
1939 The final buffer should end with "----\n"*/
1940
1941 /*sanity*/
1942 if (cur_len > tot_len)
1943 {
1944 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1945 "%s: invaid cur_len %d tot_len %d", __func__, cur_len, tot_len);
1946 return 0;
1947 }
1948 else
1949 {
1950 rem_len = (tot_len - cur_len);
1951 }
1952
1953 /*end scan marker*/
1954 if (pApMetaInfo->ApInfo.batchId != pAdapter->prev_batch_id)
1955 {
1956 temp_len = snprintf(pTemp, sizeof(temp), "####\n");
1957 pTemp += temp_len;
1958 temp_total_len += temp_len;
1959 }
1960
1961 /*bssid*/
1962 temp_len = snprintf(pTemp, sizeof(temp),
1963 "bssid=0x%x:0x%x:0x%x:0x%x:0x%x:0x%x\n",
1964 pApMetaInfo->ApInfo.bssid[0], pApMetaInfo->ApInfo.bssid[1],
1965 pApMetaInfo->ApInfo.bssid[2], pApMetaInfo->ApInfo.bssid[3],
1966 pApMetaInfo->ApInfo.bssid[4], pApMetaInfo->ApInfo.bssid[5]);
1967 pTemp += temp_len;
1968 temp_total_len += temp_len;
1969
1970 /*ssid*/
1971 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "ssid=%s\n",
1972 pApMetaInfo->ApInfo.ssid);
1973 pTemp += temp_len;
1974 temp_total_len += temp_len;
1975
1976 /*freq*/
1977 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "freq=%d\n",
Rajeev Kumarc40f7512013-11-04 14:13:23 -08001978 sme_ChnToFreq(pApMetaInfo->ApInfo.ch));
Rajeev79dbe4c2013-10-05 11:03:42 +05301979 pTemp += temp_len;
1980 temp_total_len += temp_len;
1981
1982 /*level*/
1983 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "level=%d\n",
1984 pApMetaInfo->ApInfo.rssi);
1985 pTemp += temp_len;
1986 temp_total_len += temp_len;
1987
1988 /*age*/
Jeff Johnson02797792013-10-26 19:17:13 -07001989 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "age=%d\n",
Rajeev79dbe4c2013-10-05 11:03:42 +05301990 pApMetaInfo->ApInfo.age);
1991 pTemp += temp_len;
1992 temp_total_len += temp_len;
1993
1994 /*dist*/
1995 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "dist=-1\n");
1996 pTemp += temp_len;
1997 temp_total_len += temp_len;
1998
1999 /*error*/
2000 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "error=-1\n");
2001 pTemp += temp_len;
2002 temp_total_len += temp_len;
2003
2004 /*end AP marker*/
2005 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "====\n");
2006 pTemp += temp_len;
2007 temp_total_len += temp_len;
2008
2009 /*last AP in batch scan response*/
2010 if(TRUE == pApMetaInfo->ApInfo.isLastAp)
2011 {
2012 /*end scan marker*/
2013 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "####\n");
2014 pTemp += temp_len;
2015 temp_total_len += temp_len;
2016
2017 /*end batch scan result marker*/
2018 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "----\n");
2019 pTemp += temp_len;
2020 temp_total_len += temp_len;
Kiet Lamaa8e15a2014-02-11 23:30:06 -08002021
Rajeev79dbe4c2013-10-05 11:03:42 +05302022 }
2023
2024 if (temp_total_len < rem_len)
2025 {
2026 ret = temp_total_len + 1;
2027 strlcpy(pDest, temp, ret);
2028 pAdapter->isTruncated = FALSE;
2029 }
2030 else
2031 {
2032 pAdapter->isTruncated = TRUE;
2033 if (rem_len >= strlen("%%%%"))
2034 {
Rajeev Kumarc933d982013-11-18 20:04:20 -08002035 ret = snprintf(pDest, sizeof(temp), "%%%%");
Rajeev79dbe4c2013-10-05 11:03:42 +05302036 }
Rajeev Kumarc933d982013-11-18 20:04:20 -08002037 else
Rajeev79dbe4c2013-10-05 11:03:42 +05302038 {
2039 ret = 0;
2040 }
2041 }
2042
2043 return ret;
2044
2045}/*End of hdd_format_batch_scan_rsp*/
2046
2047/**---------------------------------------------------------------------------
2048
2049 \brief hdd_populate_user_batch_scan_rsp() - This function populates user data
2050 buffer starting with head of hdd batch scan response queue
2051
2052 \param - pAdapter Pointer to HDD adapter
2053 \param - pDest Pointer to user data buffer
2054 \param - cur_len current offset in user buffer
2055 \param - rem_len remaining no of bytes in user buffer
2056
2057 \return - number of bytes written in user buffer
2058
2059 --------------------------------------------------------------------------*/
2060
2061tANI_U32 hdd_populate_user_batch_scan_rsp
2062(
2063 hdd_adapter_t* pAdapter,
2064 tANI_U8 *pDest,
2065 tANI_U32 cur_len,
2066 tANI_U32 rem_len
2067)
2068{
2069 tHddBatchScanRsp *pHead;
2070 tHddBatchScanRsp *pPrev;
2071 tANI_U32 len;
2072
Rajeev79dbe4c2013-10-05 11:03:42 +05302073 pAdapter->isTruncated = FALSE;
2074
2075 /*head of hdd batch scan response queue*/
2076 pHead = pAdapter->pBatchScanRsp;
2077 while (pHead)
2078 {
2079 len = hdd_format_batch_scan_rsp(pDest, cur_len, rem_len, pHead,
2080 pAdapter);
2081 pDest += len;
Rajeev Kumar292d2bb2013-10-23 15:01:44 -07002082 pDest--;
Rajeev79dbe4c2013-10-05 11:03:42 +05302083 cur_len += len;
2084 if(TRUE == pAdapter->isTruncated)
2085 {
2086 /*result is truncated return rest of scan rsp in next req*/
2087 cur_len = rem_len;
2088 break;
2089 }
2090 pPrev = pHead;
2091 pHead = pHead->pNext;
2092 pAdapter->pBatchScanRsp = pHead;
Rajeev Kumarbe17d8b2014-01-10 15:39:45 -08002093 if (TRUE == pPrev->ApInfo.isLastAp)
2094 {
2095 pAdapter->prev_batch_id = 0;
2096 }
2097 else
2098 {
2099 pAdapter->prev_batch_id = pPrev->ApInfo.batchId;
2100 }
Rajeev79dbe4c2013-10-05 11:03:42 +05302101 vos_mem_free(pPrev);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08002102 pPrev = NULL;
Rajeev79dbe4c2013-10-05 11:03:42 +05302103 }
2104
2105 return cur_len;
2106}/*End of hdd_populate_user_batch_scan_rsp*/
2107
2108/**---------------------------------------------------------------------------
2109
2110 \brief hdd_return_batch_scan_rsp_to_user () - This function returns batch
2111 scan response data from HDD queue to user space
2112 It does following in detail:
2113 a) if HDD has enough data in its queue then it 1st copies data to user
2114 space and then send get batch scan indication message to FW. In this
2115 case it does not wait on any event and batch scan response data will
2116 be populated in HDD response queue in MC thread context after receiving
2117 indication from FW
2118 b) else send get batch scan indication message to FW and wait on an event
2119 which will be set once HDD receives complete batch scan response from
2120 FW and then this function returns batch scan response to user space
2121
2122 \param - pAdapter Pointer to HDD adapter
2123 \param - pPrivData Pointer to priv_data
2124
2125 \return - 0 for success -EFAULT for failure
2126
2127 --------------------------------------------------------------------------*/
2128
2129int hdd_return_batch_scan_rsp_to_user
2130(
2131 hdd_adapter_t* pAdapter,
2132 hdd_priv_data_t *pPrivData,
2133 tANI_U8 *command
2134)
2135{
2136 tANI_U8 *pDest;
2137 tANI_U32 count = 0;
2138 tANI_U32 len = 0;
2139 tANI_U32 cur_len = 0;
2140 tANI_U32 rem_len = 0;
2141 eHalStatus halStatus;
2142 unsigned long rc;
2143 tSirTriggerBatchScanResultInd *pReq;
2144
2145 pReq = &pAdapter->hddTriggerBatchScanResultInd;
2146 pReq->param = 0;/*batch scan client*/
2147 pDest = (tANI_U8 *)(command + pPrivData->used_len);
2148 pAdapter->hdd_wait_for_get_batch_scan_rsp = FALSE;
2149
2150 cur_len = pPrivData->used_len;
2151 if (pPrivData->total_len > pPrivData->used_len)
2152 {
2153 rem_len = pPrivData->total_len - pPrivData->used_len;
2154 }
2155 else
2156 {
2157 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2158 "%s: Invalid user data buffer total_len %d used_len %d",
2159 __func__, pPrivData->total_len, pPrivData->used_len);
2160 return -EFAULT;
2161 }
2162
2163 mutex_lock(&pAdapter->hdd_batch_scan_lock);
2164 len = hdd_populate_user_batch_scan_rsp(pAdapter, pDest,
2165 cur_len, rem_len);
2166 mutex_unlock(&pAdapter->hdd_batch_scan_lock);
2167
2168 /*enough scan result available in cache to return to user space or
2169 scan result needs to be fetched 1st from fw and then return*/
Rajeev Kumar99db6262013-11-11 15:23:36 -08002170 if (len == cur_len)
Rajeev79dbe4c2013-10-05 11:03:42 +05302171 {
2172 pAdapter->hdd_wait_for_get_batch_scan_rsp = TRUE;
2173 halStatus = sme_TriggerBatchScanResultInd(
2174 WLAN_HDD_GET_HAL_CTX(pAdapter), pReq,
2175 pAdapter->sessionId, hdd_batch_scan_result_ind_callback,
2176 pAdapter);
2177 if ( eHAL_STATUS_SUCCESS == halStatus )
2178 {
2179 if (TRUE == pAdapter->hdd_wait_for_get_batch_scan_rsp)
2180 {
2181 INIT_COMPLETION(pAdapter->hdd_get_batch_scan_req_var);
2182 rc = wait_for_completion_timeout(
2183 &pAdapter->hdd_get_batch_scan_req_var,
2184 msecs_to_jiffies(HDD_GET_BATCH_SCAN_RSP_TIME_OUT));
Abhishek Singh00b71972016-01-07 10:51:04 +05302185 if (0 >= rc)
Rajeev79dbe4c2013-10-05 11:03:42 +05302186 {
2187 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Abhishek Singh00b71972016-01-07 10:51:04 +05302188 "%s: wait on hdd_get_batch_scan_req_var failed %ld",
2189 __func__, rc);
Rajeev79dbe4c2013-10-05 11:03:42 +05302190 return -EFAULT;
2191 }
2192 }
2193
2194 len = snprintf(pDest, HDD_BATCH_SCAN_AP_META_INFO_SIZE,
Jeff Johnson02797792013-10-26 19:17:13 -07002195 "scancount=%u\n", pAdapter->numScanList);
Rajeev79dbe4c2013-10-05 11:03:42 +05302196 pDest += len;
2197 cur_len += len;
2198
2199 mutex_lock(&pAdapter->hdd_batch_scan_lock);
2200 len = hdd_populate_user_batch_scan_rsp(pAdapter, pDest,
2201 cur_len, rem_len);
2202 mutex_unlock(&pAdapter->hdd_batch_scan_lock);
2203
2204 count = 0;
2205 len = (len - pPrivData->used_len);
2206 pDest = (command + pPrivData->used_len);
2207 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Rajeev Kumar99db6262013-11-11 15:23:36 -08002208 "NEW BATCH SCAN RESULT:");
Rajeev79dbe4c2013-10-05 11:03:42 +05302209 while(count < len)
2210 {
2211 printk("%c", *(pDest + count));
2212 count++;
2213 }
2214 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2215 "%s: copy %d data to user buffer", __func__, len);
2216 if (copy_to_user(pPrivData->buf, pDest, len))
2217 {
2218 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2219 "%s: failed to copy data to user buffer", __func__);
2220 return -EFAULT;
2221 }
2222 }
2223 else
2224 {
2225 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2226 "sme_GetBatchScanScan returned failure halStatus %d",
2227 halStatus);
2228 return -EINVAL;
2229 }
2230 }
2231 else
2232 {
Rajeev79dbe4c2013-10-05 11:03:42 +05302233 count = 0;
2234 len = (len - pPrivData->used_len);
2235 pDest = (command + pPrivData->used_len);
2236 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Rajeev Kumar99db6262013-11-11 15:23:36 -08002237 "REMAINING TRUNCATED BATCH SCAN RESULT:");
Rajeev79dbe4c2013-10-05 11:03:42 +05302238 while(count < len)
2239 {
2240 printk("%c", *(pDest + count));
2241 count++;
2242 }
Rajeev Kumar99db6262013-11-11 15:23:36 -08002243 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2244 "%s: copy %d data to user buffer", __func__, len);
Rajeev79dbe4c2013-10-05 11:03:42 +05302245 if (copy_to_user(pPrivData->buf, pDest, len))
2246 {
2247 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2248 "%s: failed to copy data to user buffer", __func__);
2249 return -EFAULT;
2250 }
Rajeev79dbe4c2013-10-05 11:03:42 +05302251 }
2252
2253 return 0;
2254} /*End of hdd_return_batch_scan_rsp_to_user*/
2255
Rajeev Kumar8b373292014-01-08 20:36:55 -08002256/**---------------------------------------------------------------------------
2257
2258 \brief hdd_handle_batch_scan_ioctl () - This function handles WLS_BATCHING
2259 IOCTLs from user space. Following BATCH SCAN DEV IOCTs are handled:
2260 WLS_BATCHING VERSION
2261 WLS_BATCHING SET
2262 WLS_BATCHING GET
2263 WLS_BATCHING STOP
2264
2265 \param - pAdapter Pointer to HDD adapter
2266 \param - pPrivdata Pointer to priv_data
2267 \param - command Pointer to command
2268
2269 \return - 0 for success -EFAULT for failure
2270
2271 --------------------------------------------------------------------------*/
2272
2273int hdd_handle_batch_scan_ioctl
2274(
2275 hdd_adapter_t *pAdapter,
2276 hdd_priv_data_t *pPrivdata,
2277 tANI_U8 *command
2278)
2279{
2280 int ret = 0;
Yue Mae36e3552014-03-05 17:06:20 -08002281 hdd_context_t *pHddCtx;
2282
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302283 ENTER();
2284
Yue Mae36e3552014-03-05 17:06:20 -08002285 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
2286 ret = wlan_hdd_validate_context(pHddCtx);
2287 if (ret)
2288 {
Yue Mae36e3552014-03-05 17:06:20 -08002289 goto exit;
2290 }
Rajeev Kumar8b373292014-01-08 20:36:55 -08002291
2292 if (strncmp(command, "WLS_BATCHING VERSION", 20) == 0)
2293 {
2294 char extra[32];
2295 tANI_U8 len = 0;
2296 tANI_U8 version = HDD_BATCH_SCAN_VERSION;
2297
2298 if (FALSE == sme_IsFeatureSupportedByFW(BATCH_SCAN))
2299 {
2300 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2301 "%s: Batch scan feature is not supported by FW", __func__);
2302 ret = -EINVAL;
2303 goto exit;
2304 }
2305
2306 len = scnprintf(extra, sizeof(extra), "WLS_BATCHING_VERSION %d",
2307 version);
2308 if (copy_to_user(pPrivdata->buf, &extra, len + 1))
2309 {
2310 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2311 "%s: failed to copy data to user buffer", __func__);
2312 ret = -EFAULT;
2313 goto exit;
2314 }
2315 ret = HDD_BATCH_SCAN_VERSION;
2316 }
2317 else if (strncmp(command, "WLS_BATCHING SET", 16) == 0)
2318 {
2319 int status;
2320 tANI_U8 *value = (command + 16);
2321 eHalStatus halStatus;
2322 unsigned long rc;
2323 tSirSetBatchScanReq *pReq = &pAdapter->hddSetBatchScanReq;
2324 tSirSetBatchScanRsp *pRsp = &pAdapter->hddSetBatchScanRsp;
2325
2326 if (FALSE == sme_IsFeatureSupportedByFW(BATCH_SCAN))
2327 {
2328 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2329 "%s: Batch scan feature is not supported by FW", __func__);
2330 ret = -EINVAL;
2331 goto exit;
2332 }
2333
2334 if ((WLAN_HDD_INFRA_STATION != pAdapter->device_mode) &&
2335 (WLAN_HDD_P2P_CLIENT != pAdapter->device_mode) &&
2336 (WLAN_HDD_P2P_GO != pAdapter->device_mode) &&
2337 (WLAN_HDD_P2P_DEVICE != pAdapter->device_mode))
2338 {
2339 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05302340 "Received WLS_BATCHING SET command in invalid mode %s (%d) "
Rajeev Kumar8b373292014-01-08 20:36:55 -08002341 "WLS_BATCHING_SET is only allowed in infra STA/P2P client mode",
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05302342 hdd_device_modetoString(pAdapter->device_mode),
2343 pAdapter->device_mode);
Rajeev Kumar8b373292014-01-08 20:36:55 -08002344 ret = -EINVAL;
2345 goto exit;
2346 }
2347
2348 status = hdd_parse_set_batchscan_command(value, pReq);
2349 if (status)
2350 {
2351 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2352 "Invalid WLS_BATCHING SET command");
2353 ret = -EINVAL;
2354 goto exit;
2355 }
2356
2357
2358 pAdapter->hdd_wait_for_set_batch_scan_rsp = TRUE;
2359 halStatus = sme_SetBatchScanReq(WLAN_HDD_GET_HAL_CTX(pAdapter), pReq,
2360 pAdapter->sessionId, hdd_set_batch_scan_req_callback,
2361 pAdapter);
2362
2363 if ( eHAL_STATUS_SUCCESS == halStatus )
2364 {
Mahesh A Saptasagar5f568172014-05-14 17:02:33 +05302365 char extra[32];
2366 tANI_U8 len = 0;
2367 tANI_U8 mScan = 0;
2368
Rajeev Kumar8b373292014-01-08 20:36:55 -08002369 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2370 "sme_SetBatchScanReq returned success halStatus %d",
2371 halStatus);
2372 if (TRUE == pAdapter->hdd_wait_for_set_batch_scan_rsp)
2373 {
2374 INIT_COMPLETION(pAdapter->hdd_set_batch_scan_req_var);
2375 rc = wait_for_completion_timeout(
2376 &pAdapter->hdd_set_batch_scan_req_var,
2377 msecs_to_jiffies(HDD_SET_BATCH_SCAN_REQ_TIME_OUT));
2378 if (0 == rc)
2379 {
2380 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2381 "%s: Timeout waiting for set batch scan to complete",
2382 __func__);
2383 ret = -EINVAL;
2384 goto exit;
2385 }
2386 }
2387 if ( !pRsp->nScansToBatch )
2388 {
2389 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2390 "%s: Received set batch scan failure response from FW",
2391 __func__);
2392 ret = -EINVAL;
2393 goto exit;
2394 }
2395 /*As per the Batch Scan Framework API we should return the MIN of
2396 either MSCAN or the max # of scans firmware can cache*/
Mahesh A Saptasagar5f568172014-05-14 17:02:33 +05302397 mScan = MIN(pReq->numberOfScansToBatch , pRsp->nScansToBatch);
Rajeev Kumar8b373292014-01-08 20:36:55 -08002398
2399 pAdapter->batchScanState = eHDD_BATCH_SCAN_STATE_STARTED;
2400
2401 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2402 "%s: request MSCAN %d response MSCAN %d ret %d",
Mahesh A Saptasagar5f568172014-05-14 17:02:33 +05302403 __func__, pReq->numberOfScansToBatch, pRsp->nScansToBatch, mScan);
2404 len = scnprintf(extra, sizeof(extra), "%d", mScan);
2405 if (copy_to_user(pPrivdata->buf, &extra, len + 1))
2406 {
2407 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2408 "%s: failed to copy MSCAN value to user buffer", __func__);
2409 ret = -EFAULT;
2410 goto exit;
2411 }
Rajeev Kumar8b373292014-01-08 20:36:55 -08002412 }
2413 else
2414 {
2415 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2416 "sme_SetBatchScanReq returned failure halStatus %d",
2417 halStatus);
2418 ret = -EINVAL;
2419 goto exit;
2420 }
2421 }
2422 else if (strncmp(command, "WLS_BATCHING STOP", 17) == 0)
2423 {
2424 eHalStatus halStatus;
2425 tSirStopBatchScanInd *pInd = &pAdapter->hddStopBatchScanInd;
2426 pInd->param = 0;
2427
2428 if (FALSE == sme_IsFeatureSupportedByFW(BATCH_SCAN))
2429 {
2430 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2431 "%s: Batch scan feature is not supported by FW", __func__);
2432 ret = -EINVAL;
2433 goto exit;
2434 }
2435
2436 if (eHDD_BATCH_SCAN_STATE_STARTED != pAdapter->batchScanState)
2437 {
Deepthi Gowribfd17132014-11-14 17:59:04 +05302438 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Rajeev Kumar8b373292014-01-08 20:36:55 -08002439 "Batch scan is not yet enabled batch scan state %d",
2440 pAdapter->batchScanState);
2441 ret = -EINVAL;
2442 goto exit;
2443 }
2444
Kiet Lamaa8e15a2014-02-11 23:30:06 -08002445 mutex_lock(&pAdapter->hdd_batch_scan_lock);
2446 hdd_deinit_batch_scan(pAdapter);
2447 mutex_unlock(&pAdapter->hdd_batch_scan_lock);
2448
Rajeev Kumar8b373292014-01-08 20:36:55 -08002449 pAdapter->batchScanState = eHDD_BATCH_SCAN_STATE_STOPPED;
2450
2451 halStatus = sme_StopBatchScanInd(WLAN_HDD_GET_HAL_CTX(pAdapter), pInd,
2452 pAdapter->sessionId);
2453 if ( eHAL_STATUS_SUCCESS == halStatus )
2454 {
2455 ret = 0;
2456 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2457 "sme_StopBatchScanInd returned success halStatus %d",
2458 halStatus);
2459 }
2460 else
2461 {
2462 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2463 "sme_StopBatchScanInd returned failure halStatus %d",
2464 halStatus);
2465 ret = -EINVAL;
2466 goto exit;
2467 }
2468 }
2469 else if (strncmp(command, "WLS_BATCHING GET", 16) == 0)
2470 {
2471 tANI_U32 remain_len;
2472
2473 if (FALSE == sme_IsFeatureSupportedByFW(BATCH_SCAN))
2474 {
2475 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2476 "%s: Batch scan feature is not supported by FW", __func__);
2477 ret = -EINVAL;
2478 goto exit;
2479 }
2480
2481 if (eHDD_BATCH_SCAN_STATE_STARTED != pAdapter->batchScanState)
2482 {
Deepthi Gowribfd17132014-11-14 17:59:04 +05302483 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Rajeev Kumar8b373292014-01-08 20:36:55 -08002484 "Batch scan is not yet enabled could not return results"
2485 "Batch Scan state %d",
2486 pAdapter->batchScanState);
2487 ret = -EINVAL;
2488 goto exit;
2489 }
2490
2491 pPrivdata->used_len = 16;
2492 remain_len = pPrivdata->total_len - pPrivdata->used_len;
2493 if (remain_len < pPrivdata->total_len)
2494 {
2495 /*Clear previous batch scan response data if any*/
2496 vos_mem_zero((tANI_U8 *)(command + pPrivdata->used_len), remain_len);
2497 }
2498 else
2499 {
2500 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2501 "Invalid total length from user space can't fetch batch"
2502 " scan response total_len %d used_len %d remain len %d",
2503 pPrivdata->total_len, pPrivdata->used_len, remain_len);
2504 ret = -EINVAL;
2505 goto exit;
2506 }
2507 ret = hdd_return_batch_scan_rsp_to_user(pAdapter, pPrivdata, command);
2508 }
2509
2510exit:
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302511 EXIT();
Rajeev Kumar8b373292014-01-08 20:36:55 -08002512 return ret;
2513}
2514
2515
Rajeev79dbe4c2013-10-05 11:03:42 +05302516#endif/*End of FEATURE_WLAN_BATCH_SCAN*/
2517
Selvaraj, Sridhar5aff1ed2016-06-18 01:26:23 +05302518#if defined(WLAN_FEATURE_VOWIFI_11R) || defined(FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
2519/**
2520 * hdd_assign_handoff_src_reassoc - Set handoff source as REASSOC
2521 * to Handoff request
2522 * @handoffInfo: Pointer to Handoff request
2523 * @src: enum of handoff_src
2524 * Return: None
2525 */
2526#ifndef QCA_WIFI_ISOC
2527static inline void hdd_assign_handoff_src_reassoc(tCsrHandoffRequest
2528 *handoffInfo, handoff_src src)
2529{
2530 handoffInfo->src = src;
2531}
2532#else
2533static inline void hdd_assign_handoff_src_reassoc(tCsrHandoffRequest
2534 *handoffInfo, handoff_src src)
2535{
2536}
2537#endif
2538
2539/**
Selvaraj, Sridhar4fa15232016-06-18 12:27:25 +05302540 * hdd_reassoc() - perform a user space-directed reassoc
Selvaraj, Sridhar5aff1ed2016-06-18 01:26:23 +05302541 *
2542 * @pAdapter: Adapter upon which the command was received
2543 * @bssid: BSSID with which to reassociate
2544 * @channel: channel upon which to reassociate
Selvaraj, Sridhar4fa15232016-06-18 12:27:25 +05302545 * @src: The source for the trigger of this action
Selvaraj, Sridhar5aff1ed2016-06-18 01:26:23 +05302546 *
2547 * Return: 0 for success non-zero for failure
2548 */
2549#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
Selvaraj, Sridhar8ecb4192016-06-23 17:50:49 +05302550int hdd_reassoc(hdd_adapter_t *pAdapter, const tANI_U8 *bssid,
Selvaraj, Sridhar4fa15232016-06-18 12:27:25 +05302551 const tANI_U8 channel, const handoff_src src)
Selvaraj, Sridhar5aff1ed2016-06-18 01:26:23 +05302552{
2553 hdd_station_ctx_t *pHddStaCtx;
2554 tCsrHandoffRequest handoffInfo;
2555 hdd_context_t *pHddCtx = NULL;
2556 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
2557
2558 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
2559
2560 /* if not associated, no need to proceed with reassoc */
2561 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState) {
2562 hddLog(LOG1, FL("Not associated"));
2563 return -EINVAL;
2564 }
2565
2566 /* if the target bssid is same as currently associated AP,
2567 then no need to proceed with reassoc */
2568 if (!memcmp(bssid, pHddStaCtx->conn_info.bssId, sizeof(tSirMacAddr))) {
2569 hddLog(LOG1, FL("Reassoc BSSID is same as currently associated AP bssid"));
2570 return -EINVAL;
2571 }
2572
2573 /* Check channel number is a valid channel number */
2574 if (VOS_STATUS_SUCCESS !=
2575 wlan_hdd_validate_operation_channel(pAdapter, channel)) {
2576 hddLog(LOGE, FL("Invalid Channel %d"), channel);
2577 return -EINVAL;
2578 }
2579
2580 /* Proceed with reassoc */
2581 handoffInfo.channel = channel;
Selvaraj, Sridhar4fa15232016-06-18 12:27:25 +05302582 hdd_assign_handoff_src_reassoc(&handoffInfo, src);
Selvaraj, Sridhar5aff1ed2016-06-18 01:26:23 +05302583 memcpy(handoffInfo.bssid, bssid, sizeof(tSirMacAddr));
2584 sme_HandoffRequest(pHddCtx->hHal, &handoffInfo);
2585 return 0;
2586}
2587#else
Selvaraj, Sridhar8ecb4192016-06-23 17:50:49 +05302588int hdd_reassoc(hdd_adapter_t *pAdapter, const tANI_U8 *bssid,
Selvaraj, Sridhar4fa15232016-06-18 12:27:25 +05302589 const tANI_U8 channel, const handoff_src src)
Selvaraj, Sridhar5aff1ed2016-06-18 01:26:23 +05302590{
2591 return -EPERM;
2592}
2593#endif
2594
2595/**
2596 * hdd_parse_reassoc_v1() - parse version 1 of the REASSOC command
2597 * This function parses the v1 REASSOC command with the format
2598 * REASSOC xx:xx:xx:xx:xx:xx CH where "xx:xx:xx:xx:xx:xx" is the
2599 * Hex-ASCII representation of the BSSID and CH is the ASCII
2600 * representation of the channel. For example
2601 * REASSOC 00:0a:0b:11:22:33 48
2602 *
2603 * @pAdapter: Adapter upon which the command was received
2604 * @command: ASCII text command that was received
2605 *
2606 * Return: 0 for success non-zero for failure
2607 */
2608static int
2609hdd_parse_reassoc_v1(hdd_adapter_t *pAdapter, const char *command)
2610{
2611 tANI_U8 channel = 0;
2612 tSirMacAddr bssid;
2613 int ret;
2614
2615 ret = hdd_parse_reassoc_command_v1_data(command, bssid, &channel);
2616 if (ret)
2617 hddLog(LOGE, FL("Failed to parse reassoc command data"));
2618 else
Selvaraj, Sridhar4fa15232016-06-18 12:27:25 +05302619 ret = hdd_reassoc(pAdapter, bssid, channel, REASSOC);
Selvaraj, Sridhar5aff1ed2016-06-18 01:26:23 +05302620
2621 return ret;
2622}
2623
2624/**
2625 * hdd_parse_reassoc_v2() - parse version 2 of the REASSOC command
2626 * This function parses the v2 REASSOC command with the format
2627 * REASSOC <android_wifi_reassoc_params>
2628 *
2629 * @pAdapter: Adapter upon which the command was received
2630 * @command: command that was received, ASCII command followed
2631 * by binary data
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05302632 * @total_len: Total length of the command received
Selvaraj, Sridhar5aff1ed2016-06-18 01:26:23 +05302633 *
2634 * Return: 0 for success non-zero for failure
2635 */
2636static int
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05302637hdd_parse_reassoc_v2(hdd_adapter_t *pAdapter, const char *command,
2638 int total_len)
Selvaraj, Sridhar5aff1ed2016-06-18 01:26:23 +05302639{
2640 struct android_wifi_reassoc_params params;
2641 tSirMacAddr bssid;
2642 int ret;
2643
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05302644 if (total_len < sizeof(params) + 8) {
2645 hddLog(LOGE, FL("Invalid command length"));
2646 return -EINVAL;
2647 }
2648
Selvaraj, Sridhar5aff1ed2016-06-18 01:26:23 +05302649 /* The params are located after "REASSOC " */
2650 memcpy(&params, command + 8, sizeof(params));
2651
2652 if (!mac_pton(params.bssid, (u8 *)&bssid)) {
2653 hddLog(LOGE, FL("MAC address parsing failed"));
2654 ret = -EINVAL;
2655 } else {
Selvaraj, Sridhar4fa15232016-06-18 12:27:25 +05302656 ret = hdd_reassoc(pAdapter, bssid, params.channel, REASSOC);
Selvaraj, Sridhar5aff1ed2016-06-18 01:26:23 +05302657 }
2658 return ret;
2659}
2660
2661/**
2662 * hdd_parse_reassoc() - parse the REASSOC command
2663 * There are two different versions of the REASSOC command.Version 1
2664 * of the command contains a parameter list that is ASCII characters
2665 * whereas version 2 contains a combination of ASCII and binary
2666 * payload. Determine if a version 1 or a version 2 command is being
2667 * parsed by examining the parameters, and then dispatch the parser
2668 * that is appropriate for the command.
2669 *
2670 * @pAdapter: Adapter upon which the command was received
2671 * @command: command that was received
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05302672 * @total_len: Total length of the command received
Selvaraj, Sridhar5aff1ed2016-06-18 01:26:23 +05302673 *
2674 * Return: 0 for success non-zero for failure
2675 */
2676static int
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05302677hdd_parse_reassoc(hdd_adapter_t *pAdapter, const char *command, int total_len)
Selvaraj, Sridhar5aff1ed2016-06-18 01:26:23 +05302678{
2679 int ret;
2680
2681 /*
2682 * both versions start with "REASSOC"
2683 * v1 has a bssid and channel # as an ASCII string
2684 * REASSOC xx:xx:xx:xx:xx:xx CH
2685 * v2 has a C struct
2686 * REASSOC <binary c struct>
2687 *
2688 * The first field in the v2 struct is also the bssid in ASCII.
2689 * But in the case of a v2 message the BSSID is NUL-terminated.
2690 * Hence we can peek at that offset to see if this is V1 or V2
2691 * REASSOC xx:xx:xx:xx:xx:xx*
2692 * 1111111111222222
2693 * 01234567890123456789012345
2694 */
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05302695
2696 if (total_len < 26) {
2697 hddLog(LOGE, FL("Invalid command (total_len=%d)"), total_len);
2698 return -EINVAL;
2699 }
2700
Selvaraj, Sridhar5aff1ed2016-06-18 01:26:23 +05302701 if (command[25])
2702 ret = hdd_parse_reassoc_v1(pAdapter, command);
2703 else
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05302704 ret = hdd_parse_reassoc_v2(pAdapter, command, total_len);
Selvaraj, Sridhar5aff1ed2016-06-18 01:26:23 +05302705
2706 return ret;
2707}
2708#endif /* WLAN_FEATURE_VOWIFI_11R || FEATURE_WLAN_ESE FEATURE_WLAN_LFR */
2709
Hanumanth Reddy Pothula1b8dd4f2018-04-09 17:19:03 +05302710static void get_bcn_miss_rate_cb(VOS_STATUS status, int bcnMissRate, void *data)
c_hpothu92367912014-05-01 15:18:17 +05302711{
Hanumanth Reddy Pothula1b8dd4f2018-04-09 17:19:03 +05302712 struct hdd_request *request;
c_hpothu39eb1e32014-06-26 16:31:50 +05302713
Hanumanth Reddy Pothula1b8dd4f2018-04-09 17:19:03 +05302714 request = hdd_request_get(data);
2715 if (!request) {
2716 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Obsolete request"));
2717 return;
2718 }
c_hpothu92367912014-05-01 15:18:17 +05302719
Hanumanth Reddy Pothula1b8dd4f2018-04-09 17:19:03 +05302720 if (VOS_STATUS_SUCCESS == status)
2721 gbcnMissRate = bcnMissRate;
2722 else
2723 hddLog(VOS_TRACE_LEVEL_ERROR, FL("failed to get bcnMissRate"));
c_hpothu92367912014-05-01 15:18:17 +05302724
Hanumanth Reddy Pothula1b8dd4f2018-04-09 17:19:03 +05302725 hdd_request_complete(request);
2726 hdd_request_put(request);
c_hpothu92367912014-05-01 15:18:17 +05302727
Hanumanth Reddy Pothula1b8dd4f2018-04-09 17:19:03 +05302728 return;
c_hpothu92367912014-05-01 15:18:17 +05302729}
2730
Hanumanth Reddy Pothula1b8dd4f2018-04-09 17:19:03 +05302731struct fw_stats_priv {
2732 tSirFwStatsResult *fw_stats;
2733};
2734
2735void hdd_fw_statis_cb(VOS_STATUS status,
2736 tSirFwStatsResult *fwStatsResult, void *context)
Satyanarayana Dash72806012014-12-02 14:30:08 +05302737{
Hanumanth Reddy Pothula1b8dd4f2018-04-09 17:19:03 +05302738 struct hdd_request *request;
2739 struct fw_stats_priv *priv;
Satyanarayana Dash72806012014-12-02 14:30:08 +05302740
Hanumanth Reddy Pothula1b8dd4f2018-04-09 17:19:03 +05302741 hddLog(VOS_TRACE_LEVEL_INFO, FL("with status = %d"),status);
Satyanarayana Dash72806012014-12-02 14:30:08 +05302742
Hanumanth Reddy Pothula1b8dd4f2018-04-09 17:19:03 +05302743 request = hdd_request_get(context);
2744 if (!request) {
2745 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Obsolete request"));
2746 return;
2747 }
2748 priv = hdd_request_priv(request);
2749
2750 if (VOS_STATUS_SUCCESS != status)
2751 *priv->fw_stats = *fwStatsResult;
2752 else
2753 priv->fw_stats = NULL;
2754
2755 hdd_request_complete(request);
2756 hdd_request_put(request);
2757 return;
Satyanarayana Dash72806012014-12-02 14:30:08 +05302758}
2759
jge35567202017-06-21 16:39:38 +08002760/*
2761 *hdd_parse_setmaxtxpower_command() - HDD Parse MAXTXPOWER command
2762 *@pValue Pointer to MAXTXPOWER command
2763 *@pTxPower Pointer to tx power
2764 *
2765 *This function parses the MAXTXPOWER command passed in the format
2766 * MAXTXPOWER<space>X(Tx power in dbm)
2767 * For example input commands:
2768 * 1) MAXTXPOWER -8 -> This is translated into set max TX power to -8 dbm
2769 * 2) MAXTXPOWER -23 -> This is translated into set max TX power to -23 dbm
2770 *
2771 *return - 0 for success non-zero for failure
2772 */
2773static int hdd_parse_setmaxtxpower_command(unsigned char *pValue, int *pTxPower)
2774{
2775 unsigned char *inPtr = pValue;
2776 int tempInt;
2777 int v = 0;
2778 *pTxPower = 0;
2779
2780 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
2781 /* no argument after the command */
2782 if (NULL == inPtr)
2783 return -EINVAL;
2784 /* no space after the command */
2785 else if (SPACE_ASCII_VALUE != *inPtr)
2786 return -EINVAL;
2787
2788 /* removing empty spaces */
2789 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
2790
2791 /* no argument followed by spaces */
2792 if ('\0' == *inPtr)
2793 return 0;
2794
2795 v = kstrtos32(inPtr, 10, &tempInt);
2796
2797 /* Range checking for passed parameter */
2798 if ((tempInt < HDD_MIN_TX_POWER) || (tempInt > HDD_MAX_TX_POWER))
2799 return -EINVAL;
2800
2801 *pTxPower = tempInt;
2802
2803 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2804 "SETMAXTXPOWER: %d", *pTxPower);
2805
2806 return 0;
2807}
2808
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302809static int hdd_get_dwell_time(hdd_config_t *pCfg, tANI_U8 *command, char *extra, tANI_U8 n, tANI_U8 *len)
2810{
2811 int ret = 0;
2812
2813 if (!pCfg || !command || !extra || !len)
2814 {
2815 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2816 "%s: argument passsed for GETDWELLTIME is incorrect", __func__);
2817 ret = -EINVAL;
2818 return ret;
2819 }
2820
2821 if (strncmp(command, "GETDWELLTIME ACTIVE MAX", 23) == 0)
2822 {
2823 *len = scnprintf(extra, n, "GETDWELLTIME ACTIVE MAX %u\n",
2824 (int)pCfg->nActiveMaxChnTime);
2825 return ret;
2826 }
2827 else if (strncmp(command, "GETDWELLTIME ACTIVE MIN", 23) == 0)
2828 {
2829 *len = scnprintf(extra, n, "GETDWELLTIME ACTIVE MIN %u\n",
2830 (int)pCfg->nActiveMinChnTime);
2831 return ret;
2832 }
2833 else if (strncmp(command, "GETDWELLTIME PASSIVE MAX", 24) == 0)
2834 {
2835 *len = scnprintf(extra, n, "GETDWELLTIME PASSIVE MAX %u\n",
2836 (int)pCfg->nPassiveMaxChnTime);
2837 return ret;
2838 }
2839 else if (strncmp(command, "GETDWELLTIME PASSIVE MIN", 24) == 0)
2840 {
2841 *len = scnprintf(extra, n, "GETDWELLTIME PASSIVE MIN %u\n",
2842 (int)pCfg->nPassiveMinChnTime);
2843 return ret;
2844 }
Rajesh Babu Prathipati0fd227e2014-07-05 12:50:00 +05302845 else if (strncmp(command, "GETDWELLTIME", 12) == 0)
2846 {
2847 *len = scnprintf(extra, n, "GETDWELLTIME %u \n",
2848 (int)pCfg->nActiveMaxChnTime);
2849 return ret;
2850 }
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302851 else
2852 {
2853 ret = -EINVAL;
2854 }
2855
2856 return ret;
2857}
2858
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05302859int hdd_drv_cmd_validate(tANI_U8 *command, int len)
2860{
2861 if (command[len] != ' ')
2862 return -EINVAL;
2863
2864 return 0;
2865}
2866
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302867static int hdd_set_dwell_time(hdd_adapter_t *pAdapter, tANI_U8 *command)
2868{
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05302869 tHalHandle hHal;
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302870 hdd_config_t *pCfg;
2871 tANI_U8 *value = command;
2872 int val = 0, ret = 0, temp = 0;
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05302873 tSmeConfigParams smeConfig;
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302874
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05302875 if (!pAdapter || !command || !(pCfg = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini)
2876 || !(hHal = (WLAN_HDD_GET_HAL_CTX(pAdapter))))
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302877 {
2878 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2879 "%s: argument passed for SETDWELLTIME is incorrect", __func__);
2880 ret = -EINVAL;
2881 return ret;
2882 }
2883
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05302884 vos_mem_zero(&smeConfig, sizeof(smeConfig));
2885 sme_GetConfigParam(hHal, &smeConfig);
2886
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302887 if (strncmp(command, "SETDWELLTIME ACTIVE MAX", 23) == 0 )
2888 {
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05302889 if (hdd_drv_cmd_validate(command, 23))
2890 return -EINVAL;
2891
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302892 value = value + 24;
2893 temp = kstrtou32(value, 10, &val);
2894 if (temp != 0 || val < CFG_ACTIVE_MAX_CHANNEL_TIME_MIN ||
2895 val > CFG_ACTIVE_MAX_CHANNEL_TIME_MAX )
2896 {
2897 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2898 "%s: argument passed for SETDWELLTIME ACTIVE MAX is incorrect", __func__);
2899 ret = -EFAULT;
2900 return ret;
2901 }
2902 pCfg->nActiveMaxChnTime = val;
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05302903 smeConfig.csrConfig.nActiveMaxChnTime = val;
2904 sme_UpdateConfig(hHal, &smeConfig);
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302905 }
2906 else if (strncmp(command, "SETDWELLTIME ACTIVE MIN", 23) == 0)
2907 {
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05302908 if (hdd_drv_cmd_validate(command, 23))
2909 return -EINVAL;
2910
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302911 value = value + 24;
2912 temp = kstrtou32(value, 10, &val);
2913 if (temp !=0 || val < CFG_ACTIVE_MIN_CHANNEL_TIME_MIN ||
2914 val > CFG_ACTIVE_MIN_CHANNEL_TIME_MAX )
2915 {
2916 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2917 "%s: argument passsed for SETDWELLTIME ACTIVE MIN is incorrect", __func__);
2918 ret = -EFAULT;
2919 return ret;
2920 }
2921 pCfg->nActiveMinChnTime = val;
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05302922 smeConfig.csrConfig.nActiveMinChnTime = val;
2923 sme_UpdateConfig(hHal, &smeConfig);
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302924 }
2925 else if (strncmp(command, "SETDWELLTIME PASSIVE MAX", 24) == 0)
2926 {
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05302927 if (hdd_drv_cmd_validate(command, 24))
2928 return -EINVAL;
2929
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302930 value = value + 25;
2931 temp = kstrtou32(value, 10, &val);
2932 if (temp != 0 || val < CFG_PASSIVE_MAX_CHANNEL_TIME_MIN ||
2933 val > CFG_PASSIVE_MAX_CHANNEL_TIME_MAX )
2934 {
2935 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2936 "%s: argument passed for SETDWELLTIME PASSIVE MAX is incorrect", __func__);
2937 ret = -EFAULT;
2938 return ret;
2939 }
2940 pCfg->nPassiveMaxChnTime = val;
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05302941 smeConfig.csrConfig.nPassiveMaxChnTime = val;
2942 sme_UpdateConfig(hHal, &smeConfig);
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302943 }
2944 else if (strncmp(command, "SETDWELLTIME PASSIVE MIN", 24) == 0)
2945 {
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05302946 if (hdd_drv_cmd_validate(command, 24))
2947 return -EINVAL;
2948
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302949 value = value + 25;
2950 temp = kstrtou32(value, 10, &val);
2951 if (temp != 0 || val < CFG_PASSIVE_MIN_CHANNEL_TIME_MIN ||
2952 val > CFG_PASSIVE_MIN_CHANNEL_TIME_MAX )
2953 {
2954 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2955 "%s: argument passed for SETDWELLTIME PASSIVE MIN is incorrect", __func__);
2956 ret = -EFAULT;
2957 return ret;
2958 }
2959 pCfg->nPassiveMinChnTime = val;
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05302960 smeConfig.csrConfig.nPassiveMinChnTime = val;
2961 sme_UpdateConfig(hHal, &smeConfig);
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302962 }
Rajesh Babu Prathipati0fd227e2014-07-05 12:50:00 +05302963 else if (strncmp(command, "SETDWELLTIME", 12) == 0)
2964 {
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05302965 if (hdd_drv_cmd_validate(command, 12))
2966 return -EINVAL;
2967
Rajesh Babu Prathipati0fd227e2014-07-05 12:50:00 +05302968 value = value + 13;
2969 temp = kstrtou32(value, 10, &val);
2970 if (temp != 0 || val < CFG_ACTIVE_MAX_CHANNEL_TIME_MIN ||
2971 val > CFG_ACTIVE_MAX_CHANNEL_TIME_MAX )
2972 {
2973 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2974 "%s: argument passed for SETDWELLTIME is incorrect", __func__);
2975 ret = -EFAULT;
2976 return ret;
2977 }
2978 pCfg->nActiveMaxChnTime = val;
2979 smeConfig.csrConfig.nActiveMaxChnTime = val;
2980 sme_UpdateConfig(hHal, &smeConfig);
2981 }
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302982 else
2983 {
2984 ret = -EINVAL;
2985 }
2986
2987 return ret;
2988}
Agarwal Ashish8bd53ae2015-06-12 18:03:45 +05302989static int hdd_cmd_setFccChannel(hdd_context_t *pHddCtx, tANI_U8 *cmd,
2990 tANI_U8 cmd_len)
2991{
2992 tANI_U8 *value;
2993 tANI_U8 fcc_constraint;
2994
2995 eHalStatus status;
2996 int ret = 0;
2997 value = cmd + cmd_len + 1;
2998
2999 ret = kstrtou8(value, 10, &fcc_constraint);
3000 if ((ret < 0) || (fcc_constraint > 1)) {
3001 /*
3002 * If the input value is greater than max value of datatype,
3003 * then also it is a failure
3004 */
3005 hddLog(VOS_TRACE_LEVEL_ERROR,
3006 "%s: value out of range", __func__);
3007 return -EINVAL;
3008 }
3009
Agrawal Ashish842eea82016-02-04 17:56:16 +05303010 status = sme_handleSetFccChannel(pHddCtx->hHal, fcc_constraint,
3011 pHddCtx->scan_info.mScanPending);
Agarwal Ashish8bd53ae2015-06-12 18:03:45 +05303012 if (status != eHAL_STATUS_SUCCESS)
3013 ret = -EPERM;
3014
3015 return ret;
3016}
3017
Mahesh A Saptasagarbeca12c2015-09-07 16:21:06 +05303018/**---------------------------------------------------------------------------
Agarwal Ashish8bd53ae2015-06-12 18:03:45 +05303019
Mahesh A Saptasagarbeca12c2015-09-07 16:21:06 +05303020 \brief hdd_enable_disable_ca_event() - When Host sends IOCTL (enabled),
3021 FW will send *ONE* CA ind to Host(even though it is duplicate).
3022 When Host send IOCTL (disable), FW doesn't perform any action.
3023 Whenever any change in CA *and* WLAN is in SAP/P2P-GO mode, FW
3024 sends CA ind to host. (regard less of IOCTL status)
3025 \param - pHddCtx - HDD context
3026 \param - command - command received from framework
3027 \param - cmd_len - len of the command
3028
3029 \return - 0 on success, appropriate error values on failure.
3030
3031 --------------------------------------------------------------------------*/
3032int hdd_enable_disable_ca_event(hdd_context_t *pHddCtx, tANI_U8* command, tANI_U8 cmd_len)
3033{
3034 tANI_U8 set_value;
3035 int ret = 0;
3036 eHalStatus status;
3037
3038 ret = wlan_hdd_validate_context(pHddCtx);
3039 if (0 != ret)
3040 {
3041 ret = -EINVAL;
3042 goto exit;
3043 }
3044
3045 if (pHddCtx->cfg_ini->gOptimizeCAevent == 0)
3046 {
3047 hddLog(VOS_TRACE_LEVEL_ERROR, "Enable gOptimizeCAevent"
3048 " ini param to control channel avooidance indication");
3049 ret = 0;
3050 goto exit;
3051 }
3052
3053 set_value = command[cmd_len + 1] - '0';
3054 status = sme_enableDisableChanAvoidIndEvent(pHddCtx->hHal, set_value);
3055 if (status != eHAL_STATUS_SUCCESS)
3056 {
3057 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Failed to send"
3058 " enableDisableChanAoidance command to SME\n", __func__);
3059 ret = -EINVAL;
3060 }
3061
3062exit:
3063 return ret;
3064}
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05303065
Selvaraj, Sridhar3714c4d2016-06-22 15:19:12 +05303066/**
3067 * wlan_hdd_fastreassoc_handoff_request() - Post Handoff request to SME
3068 * @pHddCtx: Pointer to the HDD context
3069 * @channel: channel to reassociate
3070 * @targetApBssid: Target AP/BSSID to reassociate
3071 *
3072 * Return: None
3073 */
3074#if defined(WLAN_FEATURE_ROAM_SCAN_OFFLOAD) && !defined(QCA_WIFI_ISOC)
3075static void wlan_hdd_fastreassoc_handoff_request(hdd_context_t *pHddCtx,
3076 uint8_t channel, tSirMacAddr targetApBssid)
3077{
3078 tCsrHandoffRequest handoffInfo;
3079 handoffInfo.channel = channel;
3080 handoffInfo.src = FASTREASSOC;
3081 vos_mem_copy(handoffInfo.bssid, targetApBssid, sizeof(tSirMacAddr));
3082 sme_HandoffRequest(pHddCtx->hHal, &handoffInfo);
3083}
3084#else
3085static void wlan_hdd_fastreassoc_handoff_request(hdd_context_t *pHddCtx,
3086 uint8_t channel, tSirMacAddr targetApBssid)
3087{
3088}
3089#endif
3090
3091/**
3092 * csr_fastroam_neighbor_ap_event() - Function to trigger scan/roam
3093 * @pAdapter: Pointer to HDD adapter
3094 * @channel: Channel to scan/roam
3095 * @targetApBssid: BSSID to roam
3096 *
3097 * Return: None
3098 */
3099#ifdef QCA_WIFI_ISOC
3100static void csr_fastroam_neighbor_ap_event(hdd_adapter_t *pAdapter,
3101 uint8_t channel, tSirMacAddr targetApBssid)
3102{
3103 smeIssueFastRoamNeighborAPEvent(WLAN_HDD_GET_HAL_CTX(pAdapter),
3104 &targetApBssid[0], eSME_ROAM_TRIGGER_SCAN, channel);
3105}
3106#else
3107static void csr_fastroam_neighbor_ap_event(hdd_adapter_t *pAdapter,
3108 uint8_t channel, tSirMacAddr targetApBssid)
3109{
3110}
3111#endif
3112
3113/**
3114 * wlan_hdd_handle_fastreassoc() - Handle fastreassoc command
3115 * @pAdapter: pointer to hdd adapter
3116 * @command: pointer to the command received
3117 *
3118 * Return: VOS_STATUS enum
3119 */
3120static VOS_STATUS wlan_hdd_handle_fastreassoc(hdd_adapter_t *pAdapter,
3121 uint8_t *command)
3122{
3123 tANI_U8 *value = command;
3124 tANI_U8 channel = 0;
3125 tSirMacAddr targetApBssid;
Selvaraj, Sridhar3714c4d2016-06-22 15:19:12 +05303126 hdd_station_ctx_t *pHddStaCtx = NULL;
3127 hdd_context_t *pHddCtx = NULL;
Selvaraj, Sridhar5aff1ed2016-06-18 01:26:23 +05303128 int ret;
Selvaraj, Sridhar349b8fe2017-01-18 13:11:25 +05303129 tCsrRoamModifyProfileFields mod_profile_fields;
3130 uint32_t roam_id = 0;
Selvaraj, Sridhar3714c4d2016-06-22 15:19:12 +05303131 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
3132 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
3133
3134 /* if not associated, no need to proceed with reassoc */
3135 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState) {
3136 hddLog(LOG1, FL("Not associated!"));
3137 return eHAL_STATUS_FAILURE;
3138 }
3139
Selvaraj, Sridhar5aff1ed2016-06-18 01:26:23 +05303140 ret = hdd_parse_reassoc_command_v1_data(value, targetApBssid, &channel);
3141 if (ret) {
Selvaraj, Sridhar3714c4d2016-06-22 15:19:12 +05303142 hddLog(LOGE, FL("Failed to parse reassoc command data"));
3143 return eHAL_STATUS_FAILURE;
3144 }
3145
3146 /* if the target bssid is same as currently associated AP,
3147 then no need to proceed with reassoc */
3148 if (vos_mem_compare(targetApBssid,
3149 pHddStaCtx->conn_info.bssId,
3150 sizeof(tSirMacAddr))) {
Selvaraj, Sridhar349b8fe2017-01-18 13:11:25 +05303151 sme_GetModifyProfileFields(pHddCtx->hHal, pAdapter->sessionId,
3152 &mod_profile_fields);
3153 sme_RoamReassoc(pHddCtx->hHal, pAdapter->sessionId, NULL,
3154 mod_profile_fields, &roam_id, 1);
Selvaraj, Sridhar3714c4d2016-06-22 15:19:12 +05303155 hddLog(LOG1, FL("Reassoc BSSID is same as currently associated AP bssid"));
Selvaraj, Sridhar349b8fe2017-01-18 13:11:25 +05303156 return eHAL_STATUS_SUCCESS;
Selvaraj, Sridhar3714c4d2016-06-22 15:19:12 +05303157 }
3158
3159 /* Check channel number is a valid channel number */
3160 if (VOS_STATUS_SUCCESS !=
3161 wlan_hdd_validate_operation_channel(pAdapter, channel)) {
3162 hddLog(LOGE, FL("Invalid Channel [%d]"), channel);
3163 return eHAL_STATUS_FAILURE;
3164 }
3165
3166 /* Proceed with reassoc */
3167 wlan_hdd_fastreassoc_handoff_request(pHddCtx, channel, targetApBssid);
3168
3169 /* Proceed with scan/roam */
3170 csr_fastroam_neighbor_ap_event(pAdapter, channel, targetApBssid);
3171
3172 return eHAL_STATUS_SUCCESS;
3173}
3174
3175/**
3176 * hdd_assign_reassoc_handoff - Set handoff source as REASSOC
3177 * @handoffInfo: Pointer to the csr Handoff Request.
3178 *
3179 * Return: None
3180 */
3181#ifndef QCA_WIFI_ISOC
3182static inline void hdd_assign_reassoc_handoff(tCsrHandoffRequest *handoffInfo)
3183{
3184 handoffInfo->src = REASSOC;
3185}
3186#else
3187static inline void hdd_assign_reassoc_handoff(tCsrHandoffRequest *handoffInfo)
3188{
3189}
3190#endif
3191
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +05303192/**
3193 * wlan_hdd_free_cache_channels() - Free the cache channels list
3194 * @hdd_ctx: Pointer to HDD context
3195 *
3196 * Return: None
3197 */
3198
3199static void wlan_hdd_free_cache_channels(hdd_context_t *hdd_ctx)
3200{
3201 mutex_lock(&hdd_ctx->cache_channel_lock);
3202 hdd_ctx->orginal_channels->num_channels = 0;
3203 vos_mem_free(hdd_ctx->orginal_channels->channel_info);
3204 hdd_ctx->orginal_channels->channel_info = NULL;
3205 vos_mem_free(hdd_ctx->orginal_channels);
3206 hdd_ctx->orginal_channels = NULL;
3207 mutex_unlock(&hdd_ctx->cache_channel_lock);
3208}
3209
3210/**
3211 * hdd_alloc_chan_cache() - Allocate the memory to cache the channel
3212 * info for the channels received in command SET_DISABLE_CHANNEL_LIST
3213 * @hdd_ctx: Pointer to HDD context
3214 * @num_chan: Number of channels for which memory needs to
3215 * be allocated
3216 *
3217 * Return: 0 on success and error code on failure
3218 */
3219
3220int hdd_alloc_chan_cache(hdd_context_t *hdd_ctx, int num_chan)
3221{
3222 if (NULL == hdd_ctx->orginal_channels) {
3223 hdd_ctx->orginal_channels =
3224 vos_mem_malloc(sizeof(struct hdd_cache_channels));
3225 if (NULL == hdd_ctx->orginal_channels) {
3226 hddLog(VOS_TRACE_LEVEL_ERROR,
3227 "In %s, VOS_MALLOC_ERR", __func__);
3228 return -EINVAL;
3229 }
3230 hdd_ctx->orginal_channels->num_channels = num_chan;
3231 hdd_ctx->orginal_channels->channel_info =
3232 vos_mem_malloc(num_chan *
3233 sizeof(struct hdd_cache_channel_info));
3234 if (NULL == hdd_ctx->orginal_channels->channel_info) {
3235 hddLog(VOS_TRACE_LEVEL_ERROR,
3236 "In %s, VOS_MALLOC_ERR", __func__);
3237 hdd_ctx->orginal_channels->num_channels = 0;
3238 vos_mem_free(hdd_ctx->orginal_channels);
3239 hdd_ctx->orginal_channels = NULL;
3240 return -EINVAL;
3241 }
3242 } else {
3243 /* Same command comes multiple times */
3244 struct hdd_cache_channel_info *temp_chan_info;
3245
3246 if (hdd_ctx->orginal_channels->num_channels + num_chan >
3247 MAX_CHANNEL) {
3248 hddLog(VOS_TRACE_LEVEL_ERROR,
3249 "%s: Invalid Number of channel received",
3250 __func__);
3251 return -EINVAL;
3252 }
3253
3254 temp_chan_info = vos_mem_malloc((
3255 hdd_ctx->orginal_channels->
3256 num_channels + num_chan) *
3257 sizeof(struct hdd_cache_channel_info));
3258 if (NULL == temp_chan_info) {
3259 hddLog(VOS_TRACE_LEVEL_ERROR,
3260 "In %s, VOS_MALLOC_ERR",
3261 __func__);
3262 return -EINVAL;
3263 }
3264
3265 vos_mem_copy(temp_chan_info, hdd_ctx->orginal_channels->
3266 channel_info, hdd_ctx->orginal_channels->
3267 num_channels *
3268 sizeof(struct hdd_cache_channel_info));
3269
3270 hdd_ctx->orginal_channels->num_channels += num_chan;
3271 vos_mem_free(hdd_ctx->orginal_channels->channel_info);
3272 hdd_ctx->orginal_channels->channel_info = temp_chan_info;
3273 temp_chan_info = NULL;
3274 }
3275 return 0;
3276
3277}
3278
3279
3280int hdd_parse_disable_chan_cmd(hdd_adapter_t *adapter, tANI_U8 *ptr)
3281{
3282 v_PVOID_t pvosGCtx = vos_get_global_context(VOS_MODULE_ID_HDD, NULL);
3283 hdd_context_t *hdd_ctx = vos_get_context(VOS_MODULE_ID_HDD, pvosGCtx);
3284 tANI_U8 *param;
3285 int j, tempInt, index = 0, ret = 0;
3286
3287 if (NULL == pvosGCtx) {
3288 hddLog(VOS_TRACE_LEVEL_FATAL,
3289 "VOS Global Context is NULL");
3290 return -EINVAL;
3291 }
3292
3293 if (NULL == hdd_ctx) {
3294 hddLog(VOS_TRACE_LEVEL_FATAL, "HDD Context is NULL");
3295 return -EINVAL;
3296 }
3297
3298 param = strchr(ptr, ' ');
3299 /*no argument after the command*/
3300 if (NULL == param)
3301 return -EINVAL;
3302
3303 /*no space after the command*/
3304 else if (SPACE_ASCII_VALUE != *param)
3305 return -EINVAL;
3306
3307 param++;
3308
3309 /*removing empty spaces*/
3310 while ((SPACE_ASCII_VALUE == *param) && ('\0' != *param))
3311 param++;
3312
3313 /*no argument followed by spaces*/
3314 if ('\0' == *param)
3315 return -EINVAL;
3316
3317 /*getting the first argument ie the number of channels*/
3318 if (sscanf(param, "%d ", &tempInt) != 1) {
3319 hddLog(VOS_TRACE_LEVEL_ERROR,
3320 "%s: Cannot get number of channels from input",
3321 __func__);
3322 return -EINVAL;
3323 }
3324
3325 if (tempInt < 0 || tempInt > MAX_CHANNEL) {
3326 hddLog(VOS_TRACE_LEVEL_ERROR,
3327 "%s: Invalid Number of channel received", __func__);
3328 return -EINVAL;
3329 }
3330
3331 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
3332 "%s: Number of channel to disable are: %d",
3333 __func__, tempInt);
3334
3335 if (!tempInt) {
3336 if (!wlan_hdd_restore_channels(hdd_ctx)) {
3337 /*
3338 * Free the cache channels only when the command is
3339 * received with num channels as 0
3340 */
3341 wlan_hdd_free_cache_channels(hdd_ctx);
3342 }
3343 return 0;
3344 }
3345
3346 mutex_lock(&hdd_ctx->cache_channel_lock);
3347 if (hdd_alloc_chan_cache(hdd_ctx, tempInt)) {
3348 ret = -ENOMEM;
3349 goto parse_done;
3350 }
3351 index = hdd_ctx->orginal_channels->num_channels - tempInt;
3352
3353 for (j = index; j < hdd_ctx->orginal_channels->num_channels; j++) {
3354 /*
3355 * param pointing to the beginning of first space
3356 * after number of channels
3357 */
3358 param = strpbrk(param, " ");
3359 /*no channel list after the number of channels argument*/
3360 if (NULL == param) {
3361 hddLog(VOS_TRACE_LEVEL_ERROR,
3362 "%s, Invalid No of channel provided in the list",
3363 __func__);
3364 ret = -EINVAL;
3365 goto parse_done;
3366 }
3367
3368 param++;
3369
3370 /*removing empty space*/
3371 while ((SPACE_ASCII_VALUE == *param) && ('\0' != *param))
3372 param++;
3373
3374 if ('\0' == *param) {
3375 hddLog(VOS_TRACE_LEVEL_ERROR,
3376 "%s, No channel is provided in the list",
3377 __func__);
3378 ret = -EINVAL;
3379 goto parse_done;
3380
3381 }
3382
3383 if (sscanf(param, "%d ", &tempInt) != 1) {
3384 hddLog(VOS_TRACE_LEVEL_ERROR,
3385 "%s: Cannot read channel number",
3386 __func__);
3387 ret = -EINVAL;
3388 goto parse_done;
3389
3390 }
3391
3392 if (!IS_CHANNEL_VALID(tempInt)) {
3393 hddLog(VOS_TRACE_LEVEL_ERROR,
3394 "%s: Invalid channel number received",
3395 __func__);
3396 ret = -EINVAL;
3397 goto parse_done;
3398
3399 }
3400
3401 hddLog(VOS_TRACE_LEVEL_INFO, "%s: channel[%d] = %d", __func__,
3402 j, tempInt);
3403 hdd_ctx->orginal_channels->channel_info[j].channel_num =
3404 tempInt;
3405 }
3406
3407 /*extra arguments check*/
3408 param = strchr(param, ' ');
3409 if (NULL != param) {
3410 while ((SPACE_ASCII_VALUE == *param) && ('\0' != *param))
3411 param++;
3412
3413 if ('\0' != *param) {
3414 hddLog(VOS_TRACE_LEVEL_ERROR,
3415 "%s: Invalid argument received", __func__);
3416 ret = -EINVAL;
3417 goto parse_done;
3418 }
3419 }
3420
3421parse_done:
3422 mutex_unlock(&hdd_ctx->cache_channel_lock);
3423 EXIT();
3424
3425 return ret;
3426}
3427
Hanumanth Reddy Pothula8ae38bb2018-03-07 18:59:30 +05303428int hdd_get_disable_ch_list(hdd_context_t *hdd_ctx, tANI_U8 *buf,
3429 tANI_U8 buf_len)
3430{
3431 struct hdd_cache_channel_info *ch_list;
3432 unsigned char i, num_ch;
3433 int len = 0;
3434
3435 mutex_lock(&hdd_ctx->cache_channel_lock);
3436 if (hdd_ctx->orginal_channels &&
3437 hdd_ctx->orginal_channels->num_channels) {
3438 num_ch = hdd_ctx->orginal_channels->num_channels;
3439
3440 if (num_ch == 0) {
3441 mutex_unlock(&hdd_ctx->cache_channel_lock);
3442 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3443 FL("no disable channels programed"));
3444 return 0;
3445 }
3446
3447 len = scnprintf(buf, buf_len, "%s %hhu",
3448 "GET_DISABLE_CHANNEL_LIST", num_ch);
3449
3450 ch_list = hdd_ctx->orginal_channels->channel_info;
3451 if (!ch_list) {
3452 mutex_unlock(&hdd_ctx->cache_channel_lock);
3453 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3454 FL("disable channel list is NULL"));
3455 return 0;
3456 }
3457
3458 for (i = 0; (i < num_ch) && len <= buf_len; i++) {
3459 len += scnprintf(buf + len, buf_len - len,
3460 " %d", ch_list[i].channel_num);
3461 }
3462 }
3463 mutex_unlock(&hdd_ctx->cache_channel_lock);
3464
3465 return len;
3466}
3467
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07003468static int hdd_driver_command(hdd_adapter_t *pAdapter,
3469 hdd_priv_data_t *ppriv_data)
Jeff Johnson295189b2012-06-20 16:38:30 -07003470{
Jeff Johnson295189b2012-06-20 16:38:30 -07003471 hdd_priv_data_t priv_data;
3472 tANI_U8 *command = NULL;
Kaushik, Sushant96122442014-10-21 16:40:18 +05303473 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
3474 hdd_scaninfo_t *pScanInfo = NULL;
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07003475 int ret = 0;
Kaushik, Sushant96122442014-10-21 16:40:18 +05303476 int status;
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05303477#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
3478 struct cfg80211_mgmt_tx_params params;
3479#endif
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303480
3481 ENTER();
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07003482 /*
3483 * Note that valid pointers are provided by caller
3484 */
Jeff Johnson295189b2012-06-20 16:38:30 -07003485
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07003486 /* copy to local struct to avoid numerous changes to legacy code */
3487 priv_data = *ppriv_data;
Jeff Johnson295189b2012-06-20 16:38:30 -07003488
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07003489 if (priv_data.total_len <= 0 ||
3490 priv_data.total_len > WLAN_PRIV_DATA_MAX_LEN)
Sameer Thalappil8ef3a0e2013-04-05 14:36:04 -07003491 {
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07003492 hddLog(VOS_TRACE_LEVEL_WARN,
3493 "%s:invalid priv_data.total_len(%d)!!!", __func__,
3494 priv_data.total_len);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07003495 ret = -EINVAL;
3496 goto exit;
3497 }
Kaushik, Sushant96122442014-10-21 16:40:18 +05303498 status = wlan_hdd_validate_context(pHddCtx);
3499 if (0 != status)
3500 {
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303501 ret = -EINVAL;
3502 goto exit;
Kaushik, Sushant96122442014-10-21 16:40:18 +05303503 }
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07003504 /* Allocate +1 for '\0' */
3505 command = kmalloc(priv_data.total_len + 1, GFP_KERNEL);
Jeff Johnson295189b2012-06-20 16:38:30 -07003506 if (!command)
3507 {
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07003508 hddLog(VOS_TRACE_LEVEL_ERROR,
3509 "%s: failed to allocate memory", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07003510 ret = -ENOMEM;
3511 goto exit;
3512 }
3513
3514 if (copy_from_user(command, priv_data.buf, priv_data.total_len))
3515 {
3516 ret = -EFAULT;
3517 goto exit;
3518 }
3519
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07003520 /* Make sure the command is NUL-terminated */
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07003521 command[priv_data.total_len] = '\0';
3522
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07003523 /* at one time the following block of code was conditional. braces
3524 * have been retained to avoid re-indenting the legacy code
3525 */
Jeff Johnson295189b2012-06-20 16:38:30 -07003526 {
3527 hdd_context_t *pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
3528
3529 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudif9bdd4e2012-10-30 18:05:03 -07003530 "%s: Received %s cmd from Wi-Fi GUI***", __func__, command);
Jeff Johnson295189b2012-06-20 16:38:30 -07003531
3532 if (strncmp(command, "P2P_DEV_ADDR", 12) == 0 )
3533 {
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05303534 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
3535 TRACE_CODE_HDD_P2P_DEV_ADDR_IOCTL,
3536 pAdapter->sessionId, (unsigned)
3537 (*(pHddCtx->p2pDeviceAddress.bytes+2)<<24 |
3538 *(pHddCtx->p2pDeviceAddress.bytes+3)<<16 |
3539 *(pHddCtx->p2pDeviceAddress.bytes+4)<<8 |
3540 *(pHddCtx->p2pDeviceAddress.bytes+5))));
Jeff Johnson295189b2012-06-20 16:38:30 -07003541 if (copy_to_user(priv_data.buf, pHddCtx->p2pDeviceAddress.bytes,
3542 sizeof(tSirMacAddr)))
3543 {
3544 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08003545 "%s: failed to copy data to user buffer", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07003546 ret = -EFAULT;
3547 }
3548 }
Amar Singhal0974e402013-02-12 14:27:46 -08003549 else if(strncmp(command, "SETBAND", 7) == 0)
Jeff Johnson295189b2012-06-20 16:38:30 -07003550 {
Amar Singhal0974e402013-02-12 14:27:46 -08003551 tANI_U8 *ptr = command ;
Srinivas Girigowdade697412013-02-14 16:31:48 -08003552
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05303553 ret = hdd_drv_cmd_validate(command, 7);
3554 if (ret)
3555 goto exit;
3556
Jeff Johnson295189b2012-06-20 16:38:30 -07003557 /* Change band request received */
Srinivas Girigowdade697412013-02-14 16:31:48 -08003558
3559 /* First 8 bytes will have "SETBAND " and
Jeff Johnson295189b2012-06-20 16:38:30 -07003560 * 9 byte will have band setting value */
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07003561 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Amar Singhal0974e402013-02-12 14:27:46 -08003562 "%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 +05303563 if(VOS_FTM_MODE != hdd_get_conparam())
3564 {
3565 /* Change band request received */
3566 ret = hdd_setBand_helper(pAdapter->dev, ptr);
3567 if(ret < 0)
3568 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
3569 "%s: failed to set band ret=%d", __func__, ret);
3570 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08003571 }
Kiet Lamf040f472013-11-20 21:15:23 +05303572 else if(strncmp(command, "SETWMMPS", 8) == 0)
3573 {
3574 tANI_U8 *ptr = command;
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05303575
3576 ret = hdd_drv_cmd_validate(command, 8);
3577 if (ret)
3578 goto exit;
3579
Kiet Lamf040f472013-11-20 21:15:23 +05303580 ret = hdd_wmmps_helper(pAdapter, ptr);
3581 }
Agarwal Ashishef54a182014-12-16 15:07:31 +05303582
3583 else if(strncmp(command, "TDLSSCAN", 8) == 0)
3584 {
3585 tANI_U8 *ptr = command;
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05303586
3587 ret = hdd_drv_cmd_validate(command, 8);
3588 if (ret)
3589 goto exit;
3590
Agarwal Ashishef54a182014-12-16 15:07:31 +05303591 ret = hdd_set_tdls_scan_type(pAdapter, ptr);
3592 }
3593
Jeff Johnson32d95a32012-09-10 13:15:23 -07003594 else if ( strncasecmp(command, "COUNTRY", 7) == 0 )
3595 {
3596 char *country_code;
3597
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05303598 ret = hdd_drv_cmd_validate(command, 7);
3599 if (ret)
3600 goto exit;
3601
Jeff Johnson32d95a32012-09-10 13:15:23 -07003602 country_code = command + 8;
Tushnim Bhattacharyya9cdf6082013-04-21 16:33:30 -07003603
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07003604 INIT_COMPLETION(pAdapter->change_country_code);
Tushnim Bhattacharyya9cdf6082013-04-21 16:33:30 -07003605 hdd_checkandupdate_dfssetting(pAdapter, country_code);
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -07003606#ifndef CONFIG_ENABLE_LINUX_REG
Gopichand Nakkaladacbcb52013-04-18 16:41:54 +05303607 hdd_checkandupdate_phymode(pAdapter, country_code);
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -07003608#endif
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07003609 ret = (int)sme_ChangeCountryCode(pHddCtx->hHal,
3610 (void *)(tSmeChangeCountryCallback)
3611 wlan_hdd_change_country_code_callback,
Abhishek Singha306a442013-11-07 18:39:01 +05303612 country_code, pAdapter, pHddCtx->pvosContext, eSIR_TRUE, eSIR_TRUE);
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07003613 if (eHAL_STATUS_SUCCESS == ret)
3614 {
3615 ret = wait_for_completion_interruptible_timeout(
3616 &pAdapter->change_country_code,
3617 msecs_to_jiffies(WLAN_WAIT_TIME_COUNTRY));
3618 if (0 >= ret)
3619 {
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07003620 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: SME while setting country code timed out %d",
c_hpothu6ff1c3c2013-10-01 19:01:57 +05303621 __func__, ret);
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07003622 }
3623 }
3624 else
Jeff Johnson32d95a32012-09-10 13:15:23 -07003625 {
3626 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07003627 "%s: SME Change Country code fail ret=%d", __func__, ret);
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07003628 ret = -EINVAL;
Jeff Johnson32d95a32012-09-10 13:15:23 -07003629 }
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07003630
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07003631 }
3632 /*
3633 command should be a string having format
3634 SET_SAP_CHANNEL_LIST <num of channels> <the channels seperated by spaces>
3635 */
Amar Singhal0974e402013-02-12 14:27:46 -08003636 else if(strncmp(command, "SET_SAP_CHANNEL_LIST", 20) == 0)
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07003637 {
Amar Singhal0974e402013-02-12 14:27:46 -08003638 tANI_U8 *ptr = command;
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07003639
3640 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07003641 " Received Command to Set Preferred Channels for SAP in %s", __func__);
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07003642
Mahesh Kumar Kalikot Veetil2aad8d82013-02-07 12:31:28 -08003643 ret = sapSetPreferredChannel(ptr);
Jeff Johnson32d95a32012-09-10 13:15:23 -07003644 }
Sourav Mohapatra2416e0e2018-03-05 18:44:21 +05303645
3646 else if (strncmp(command, "VOWIFIMODE", 10) == 0)
3647 {
3648 tANI_U8 *ptr;
3649
3650 ret = hdd_drv_cmd_validate(command, 10);
3651 if (ret)
3652 goto exit;
3653
3654 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3655 "Received Command for VOWIFI mode in %s", __func__);
3656
3657 ptr = (tANI_U8*)command + 11;
3658 hdd_set_vowifi_mode(pHddCtx, *ptr - '0');
3659 }
3660
Sameer Thalappil45931fb2013-02-01 11:18:05 -08003661 else if(strncmp(command, "SETSUSPENDMODE", 14) == 0)
3662 {
3663 int suspend = 0;
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05303664 tANI_U8 *ptr;
3665
3666 ret = hdd_drv_cmd_validate(command, 14);
3667 if (ret)
3668 goto exit;
3669
3670 ptr = (tANI_U8*)command + 15;
Sameer Thalappil45931fb2013-02-01 11:18:05 -08003671
3672 suspend = *ptr - '0';
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05303673 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
3674 TRACE_CODE_HDD_SETSUSPENDMODE_IOCTL,
3675 pAdapter->sessionId, suspend));
Sameer Thalappil45931fb2013-02-01 11:18:05 -08003676 hdd_set_wlan_suspend_mode(suspend);
3677 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08003678#ifdef WLAN_FEATURE_NEIGHBOR_ROAMING
3679 else if (strncmp(command, "SETROAMTRIGGER", 14) == 0)
3680 {
3681 tANI_U8 *value = command;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07003682 tANI_S8 rssi = 0;
Srinivas Girigowdade697412013-02-14 16:31:48 -08003683 tANI_U8 lookUpThreshold = CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_DEFAULT;
3684 eHalStatus status = eHAL_STATUS_SUCCESS;
3685
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05303686 ret = hdd_drv_cmd_validate(command, 14);
3687 if (ret)
3688 goto exit;
3689
Srinivas Girigowdade697412013-02-14 16:31:48 -08003690 /* Move pointer to ahead of SETROAMTRIGGER<delimiter> */
3691 value = value + 15;
3692
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07003693 /* Convert the value from ascii to integer */
3694 ret = kstrtos8(value, 10, &rssi);
3695 if (ret < 0)
3696 {
3697 /* If the input value is greater than max value of datatype, then also
3698 kstrtou8 fails */
3699 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3700 "%s: kstrtou8 failed Input value may be out of range[%d - %d]",
Srinivas Girigowdafa7157d2013-10-31 10:14:22 -07003701 __func__,
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07003702 CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MIN,
3703 CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MAX);
3704 ret = -EINVAL;
3705 goto exit;
3706 }
3707
Srinivas Girigowdade697412013-02-14 16:31:48 -08003708 lookUpThreshold = abs(rssi);
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07003709
Srinivas Girigowdade697412013-02-14 16:31:48 -08003710 if ((lookUpThreshold < CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MIN) ||
3711 (lookUpThreshold > CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MAX))
3712 {
3713 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3714 "Neighbor lookup threshold value %d is out of range"
3715 " (Min: %d Max: %d)", lookUpThreshold,
3716 CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MIN,
3717 CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MAX);
3718 ret = -EINVAL;
3719 goto exit;
3720 }
3721
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05303722 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
3723 TRACE_CODE_HDD_SETROAMTRIGGER_IOCTL,
3724 pAdapter->sessionId, lookUpThreshold));
Srinivas Girigowdade697412013-02-14 16:31:48 -08003725 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3726 "%s: Received Command to Set Roam trigger"
3727 " (Neighbor lookup threshold) = %d", __func__, lookUpThreshold);
3728
3729 pHddCtx->cfg_ini->nNeighborLookupRssiThreshold = lookUpThreshold;
3730 status = sme_setNeighborLookupRssiThreshold((tHalHandle)(pHddCtx->hHal), lookUpThreshold);
3731 if (eHAL_STATUS_SUCCESS != status)
3732 {
3733 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3734 "%s: Failed to set roam trigger, try again", __func__);
3735 ret = -EPERM;
3736 goto exit;
3737 }
3738
3739 /* Set Reassoc threshold to (lookup rssi threshold + 5 dBm) */
mukul sharmad6e1fdd2014-06-23 19:19:09 +05303740 pHddCtx->cfg_ini->nNeighborReassocRssiThreshold = lookUpThreshold + 5;
Srinivas Girigowdade697412013-02-14 16:31:48 -08003741 sme_setNeighborReassocRssiThreshold((tHalHandle)(pHddCtx->hHal), lookUpThreshold + 5);
3742 }
3743 else if (strncmp(command, "GETROAMTRIGGER", 14) == 0)
3744 {
3745 tANI_U8 lookUpThreshold = sme_getNeighborLookupRssiThreshold((tHalHandle)(pHddCtx->hHal));
3746 int rssi = (-1) * lookUpThreshold;
3747 char extra[32];
3748 tANI_U8 len = 0;
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05303749 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
3750 TRACE_CODE_HDD_GETROAMTRIGGER_IOCTL,
3751 pAdapter->sessionId, lookUpThreshold));
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003752 len = scnprintf(extra, sizeof(extra), "%s %d", command, rssi);
Srinivas Girigowda91719232015-07-13 15:10:10 +05303753 len = VOS_MIN(priv_data.total_len, len + 1);
3754 if (copy_to_user(priv_data.buf, &extra, len))
Srinivas Girigowdade697412013-02-14 16:31:48 -08003755 {
3756 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3757 "%s: failed to copy data to user buffer", __func__);
3758 ret = -EFAULT;
3759 goto exit;
3760 }
3761 }
3762 else if (strncmp(command, "SETROAMSCANPERIOD", 17) == 0)
3763 {
3764 tANI_U8 *value = command;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07003765 tANI_U8 roamScanPeriod = 0;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003766 tANI_U16 neighborEmptyScanRefreshPeriod = CFG_EMPTY_SCAN_REFRESH_PERIOD_DEFAULT;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07003767
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05303768 ret = hdd_drv_cmd_validate(command, 17);
3769 if (ret)
3770 goto exit;
3771
Srinivas Girigowdade697412013-02-14 16:31:48 -08003772 /* input refresh period is in terms of seconds */
3773 /* Move pointer to ahead of SETROAMSCANPERIOD<delimiter> */
3774 value = value + 18;
3775 /* Convert the value from ascii to integer */
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07003776 ret = kstrtou8(value, 10, &roamScanPeriod);
Srinivas Girigowdade697412013-02-14 16:31:48 -08003777 if (ret < 0)
3778 {
3779 /* If the input value is greater than max value of datatype, then also
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07003780 kstrtou8 fails */
Srinivas Girigowdade697412013-02-14 16:31:48 -08003781 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07003782 "%s: kstrtou8 failed Input value may be out of range[%d - %d]",
Srinivas Girigowdade697412013-02-14 16:31:48 -08003783 __func__,
Srinivas Girigowdab8edd1e2013-03-19 11:42:08 -07003784 (CFG_EMPTY_SCAN_REFRESH_PERIOD_MIN/1000),
3785 (CFG_EMPTY_SCAN_REFRESH_PERIOD_MAX/1000));
Srinivas Girigowdade697412013-02-14 16:31:48 -08003786 ret = -EINVAL;
3787 goto exit;
3788 }
3789
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07003790 if ((roamScanPeriod < (CFG_EMPTY_SCAN_REFRESH_PERIOD_MIN/1000)) ||
3791 (roamScanPeriod > (CFG_EMPTY_SCAN_REFRESH_PERIOD_MAX/1000)))
Srinivas Girigowdade697412013-02-14 16:31:48 -08003792 {
3793 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07003794 "Roam scan period value %d is out of range"
3795 " (Min: %d Max: %d)", roamScanPeriod,
Srinivas Girigowdab8edd1e2013-03-19 11:42:08 -07003796 (CFG_EMPTY_SCAN_REFRESH_PERIOD_MIN/1000),
3797 (CFG_EMPTY_SCAN_REFRESH_PERIOD_MAX/1000));
Srinivas Girigowdade697412013-02-14 16:31:48 -08003798 ret = -EINVAL;
3799 goto exit;
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05303800 }
3801 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
3802 TRACE_CODE_HDD_SETROAMSCANPERIOD_IOCTL,
3803 pAdapter->sessionId, roamScanPeriod));
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07003804 neighborEmptyScanRefreshPeriod = roamScanPeriod * 1000;
Srinivas Girigowdade697412013-02-14 16:31:48 -08003805
3806 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3807 "%s: Received Command to Set roam scan period"
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07003808 " (Empty Scan refresh period) = %d", __func__, roamScanPeriod);
Srinivas Girigowdade697412013-02-14 16:31:48 -08003809
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003810 pHddCtx->cfg_ini->nEmptyScanRefreshPeriod = neighborEmptyScanRefreshPeriod;
3811 sme_UpdateEmptyScanRefreshPeriod((tHalHandle)(pHddCtx->hHal), neighborEmptyScanRefreshPeriod);
Srinivas Girigowdade697412013-02-14 16:31:48 -08003812 }
3813 else if (strncmp(command, "GETROAMSCANPERIOD", 17) == 0)
3814 {
3815 tANI_U16 nEmptyScanRefreshPeriod = sme_getEmptyScanRefreshPeriod((tHalHandle)(pHddCtx->hHal));
3816 char extra[32];
3817 tANI_U8 len = 0;
3818
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05303819 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
3820 TRACE_CODE_HDD_GETROAMSCANPERIOD_IOCTL,
3821 pAdapter->sessionId, nEmptyScanRefreshPeriod));
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003822 len = scnprintf(extra, sizeof(extra), "%s %d",
3823 "GETROAMSCANPERIOD", (nEmptyScanRefreshPeriod/1000));
Srinivas Girigowdade697412013-02-14 16:31:48 -08003824 /* Returned value is in units of seconds */
Ratnam Rachuria72ba112015-07-17 13:27:03 +05303825 len = VOS_MIN(priv_data.total_len, len + 1);
3826 if (copy_to_user(priv_data.buf, &extra, len)) {
Srinivas Girigowdade697412013-02-14 16:31:48 -08003827 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3828 "%s: failed to copy data to user buffer", __func__);
3829 ret = -EFAULT;
3830 goto exit;
3831 }
3832 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003833 else if (strncmp(command, "SETROAMSCANREFRESHPERIOD", 24) == 0)
3834 {
3835 tANI_U8 *value = command;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07003836 tANI_U8 roamScanRefreshPeriod = 0;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003837 tANI_U16 neighborScanRefreshPeriod = CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_DEFAULT;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07003838
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05303839 ret = hdd_drv_cmd_validate(command, 24);
3840 if (ret)
3841 goto exit;
3842
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003843 /* input refresh period is in terms of seconds */
3844 /* Move pointer to ahead of SETROAMSCANREFRESHPERIOD<delimiter> */
3845 value = value + 25;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07003846
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003847 /* Convert the value from ascii to integer */
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07003848 ret = kstrtou8(value, 10, &roamScanRefreshPeriod);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003849 if (ret < 0)
3850 {
3851 /* If the input value is greater than max value of datatype, then also
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07003852 kstrtou8 fails */
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003853 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07003854 "%s: kstrtou8 failed Input value may be out of range[%d - %d]",
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003855 __func__,
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003856 (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MIN/1000),
3857 (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MAX/1000));
3858 ret = -EINVAL;
3859 goto exit;
3860 }
3861
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07003862 if ((roamScanRefreshPeriod < (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MIN/1000)) ||
3863 (roamScanRefreshPeriod > (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MAX/1000)))
3864 {
3865 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3866 "Neighbor scan results refresh period value %d is out of range"
3867 " (Min: %d Max: %d)", roamScanRefreshPeriod,
3868 (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MIN/1000),
3869 (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MAX/1000));
3870 ret = -EINVAL;
3871 goto exit;
3872 }
3873 neighborScanRefreshPeriod = roamScanRefreshPeriod * 1000;
3874
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003875 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3876 "%s: Received Command to Set roam scan refresh period"
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07003877 " (Scan refresh period) = %d", __func__, roamScanRefreshPeriod);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003878
3879 pHddCtx->cfg_ini->nNeighborResultsRefreshPeriod = neighborScanRefreshPeriod;
3880 sme_setNeighborScanRefreshPeriod((tHalHandle)(pHddCtx->hHal), neighborScanRefreshPeriod);
3881 }
3882 else if (strncmp(command, "GETROAMSCANREFRESHPERIOD", 24) == 0)
3883 {
3884 tANI_U16 value = sme_getNeighborScanRefreshPeriod((tHalHandle)(pHddCtx->hHal));
3885 char extra[32];
3886 tANI_U8 len = 0;
3887
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003888 len = scnprintf(extra, sizeof(extra), "%s %d",
3889 "GETROAMSCANREFRESHPERIOD", (value/1000));
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003890 /* Returned value is in units of seconds */
Ratnam Rachuri2c9d6702015-07-17 13:25:16 +05303891 len = VOS_MIN(priv_data.total_len, len + 1);
3892 if (copy_to_user(priv_data.buf, &extra, len)) {
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003893 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3894 "%s: failed to copy data to user buffer", __func__);
3895 ret = -EFAULT;
3896 goto exit;
3897 }
3898 }
Varun Reddy Yeturu6d99ac82013-05-08 14:15:35 -07003899#ifdef FEATURE_WLAN_LFR
3900 /* SETROAMMODE */
3901 else if (strncmp(command, "SETROAMMODE", SIZE_OF_SETROAMMODE) == 0)
3902 {
3903 tANI_U8 *value = command;
3904 tANI_BOOLEAN roamMode = CFG_LFR_FEATURE_ENABLED_DEFAULT;
3905
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +05303906 if (pHddCtx->concurrency_mode == VOS_STA_MON) {
3907 hddLog(LOGE,
3908 FL("Roaming is always disabled in STA + MON concurrency"));
3909 ret = -EINVAL;
3910 goto exit;
3911 }
3912
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05303913 ret = hdd_drv_cmd_validate(command, SIZE_OF_SETROAMMODE);
3914 if (ret)
3915 goto exit;
3916
Varun Reddy Yeturu6d99ac82013-05-08 14:15:35 -07003917 /* Move pointer to ahead of SETROAMMODE<delimiter> */
3918 value = value + SIZE_OF_SETROAMMODE + 1;
3919
3920 /* Convert the value from ascii to integer */
3921 ret = kstrtou8(value, SIZE_OF_SETROAMMODE, &roamMode);
3922 if (ret < 0)
3923 {
3924 /* If the input value is greater than max value of datatype, then also
3925 kstrtou8 fails */
3926 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3927 "%s: kstrtou8 failed range [%d - %d]", __func__,
3928 CFG_LFR_FEATURE_ENABLED_MIN,
3929 CFG_LFR_FEATURE_ENABLED_MAX);
3930 ret = -EINVAL;
3931 goto exit;
3932 }
3933 if ((roamMode < CFG_LFR_FEATURE_ENABLED_MIN) ||
3934 (roamMode > CFG_LFR_FEATURE_ENABLED_MAX))
3935 {
3936 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3937 "Roam Mode value %d is out of range"
3938 " (Min: %d Max: %d)", roamMode,
3939 CFG_LFR_FEATURE_ENABLED_MIN,
3940 CFG_LFR_FEATURE_ENABLED_MAX);
3941 ret = -EINVAL;
3942 goto exit;
3943 }
3944
3945 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3946 "%s: Received Command to Set Roam Mode = %d", __func__, roamMode);
3947 /*
3948 * Note that
3949 * SETROAMMODE 0 is to enable LFR while
3950 * SETROAMMODE 1 is to disable LFR, but
3951 * NotifyIsFastRoamIniFeatureEnabled 0/1 is to enable/disable.
3952 * So, we have to invert the value to call sme_UpdateIsFastRoamIniFeatureEnabled.
3953 */
3954 if (CFG_LFR_FEATURE_ENABLED_MIN == roamMode)
3955 roamMode = CFG_LFR_FEATURE_ENABLED_MAX; /* Roam enable */
3956 else
3957 roamMode = CFG_LFR_FEATURE_ENABLED_MIN; /* Roam disable */
3958
3959 pHddCtx->cfg_ini->isFastRoamIniFeatureEnabled = roamMode;
3960 sme_UpdateIsFastRoamIniFeatureEnabled((tHalHandle)(pHddCtx->hHal), roamMode);
3961 }
3962 /* GETROAMMODE */
Mahesh A Saptasagarec7d1092015-04-02 13:41:34 +05303963 else if (strncmp(command, "GETROAMMODE", SIZE_OF_GETROAMMODE) == 0)
Varun Reddy Yeturu6d99ac82013-05-08 14:15:35 -07003964 {
3965 tANI_BOOLEAN roamMode = sme_getIsLfrFeatureEnabled((tHalHandle)(pHddCtx->hHal));
3966 char extra[32];
3967 tANI_U8 len = 0;
3968
3969 /*
3970 * roamMode value shall be inverted because the sementics is different.
3971 */
3972 if (CFG_LFR_FEATURE_ENABLED_MIN == roamMode)
3973 roamMode = CFG_LFR_FEATURE_ENABLED_MAX;
3974 else
3975 roamMode = CFG_LFR_FEATURE_ENABLED_MIN;
3976
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003977 len = scnprintf(extra, sizeof(extra), "%s %d", command, roamMode);
Ratnam Rachuri28693eb2015-07-17 13:23:42 +05303978 len = VOS_MIN(priv_data.total_len, len + 1);
3979 if (copy_to_user(priv_data.buf, &extra, len)) {
Varun Reddy Yeturu6d99ac82013-05-08 14:15:35 -07003980 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3981 "%s: failed to copy data to user buffer", __func__);
3982 ret = -EFAULT;
3983 goto exit;
3984 }
3985 }
3986#endif
Srinivas Girigowdade697412013-02-14 16:31:48 -08003987#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003988#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowdade697412013-02-14 16:31:48 -08003989 else if (strncmp(command, "SETROAMDELTA", 12) == 0)
3990 {
3991 tANI_U8 *value = command;
3992 tANI_U8 roamRssiDiff = CFG_ROAM_RSSI_DIFF_DEFAULT;
3993
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05303994 ret = hdd_drv_cmd_validate(command, 12);
3995 if (ret)
3996 goto exit;
3997
Srinivas Girigowdade697412013-02-14 16:31:48 -08003998 /* Move pointer to ahead of SETROAMDELTA<delimiter> */
3999 value = value + 13;
4000 /* Convert the value from ascii to integer */
4001 ret = kstrtou8(value, 10, &roamRssiDiff);
4002 if (ret < 0)
4003 {
4004 /* If the input value is greater than max value of datatype, then also
4005 kstrtou8 fails */
4006 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4007 "%s: kstrtou8 failed range [%d - %d]", __func__,
4008 CFG_ROAM_RSSI_DIFF_MIN,
4009 CFG_ROAM_RSSI_DIFF_MAX);
4010 ret = -EINVAL;
4011 goto exit;
4012 }
4013
4014 if ((roamRssiDiff < CFG_ROAM_RSSI_DIFF_MIN) ||
4015 (roamRssiDiff > CFG_ROAM_RSSI_DIFF_MAX))
4016 {
4017 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4018 "Roam rssi diff value %d is out of range"
4019 " (Min: %d Max: %d)", roamRssiDiff,
4020 CFG_ROAM_RSSI_DIFF_MIN,
4021 CFG_ROAM_RSSI_DIFF_MAX);
4022 ret = -EINVAL;
4023 goto exit;
4024 }
4025
4026 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4027 "%s: Received Command to Set roam rssi diff = %d", __func__, roamRssiDiff);
4028
4029 pHddCtx->cfg_ini->RoamRssiDiff = roamRssiDiff;
4030 sme_UpdateRoamRssiDiff((tHalHandle)(pHddCtx->hHal), roamRssiDiff);
4031 }
Mahesh A Saptasagarec7d1092015-04-02 13:41:34 +05304032 else if (strncmp(command, "GETROAMDELTA", 12) == 0)
Srinivas Girigowdade697412013-02-14 16:31:48 -08004033 {
4034 tANI_U8 roamRssiDiff = sme_getRoamRssiDiff((tHalHandle)(pHddCtx->hHal));
4035 char extra[32];
4036 tANI_U8 len = 0;
4037
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05304038 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
4039 TRACE_CODE_HDD_GETROAMDELTA_IOCTL,
4040 pAdapter->sessionId, roamRssiDiff));
Sameer Thalappilb0a30232013-09-27 15:37:48 -07004041 len = scnprintf(extra, sizeof(extra), "%s %d",
4042 command, roamRssiDiff);
Ratnam Rachuri22a3b402015-07-17 13:21:49 +05304043 len = VOS_MIN(priv_data.total_len, len + 1);
4044 if (copy_to_user(priv_data.buf, &extra, len)) {
Srinivas Girigowdade697412013-02-14 16:31:48 -08004045 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4046 "%s: failed to copy data to user buffer", __func__);
4047 ret = -EFAULT;
4048 goto exit;
4049 }
4050 }
4051#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004052#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowdade697412013-02-14 16:31:48 -08004053 else if (strncmp(command, "GETBAND", 7) == 0)
4054 {
4055 int band = -1;
4056 char extra[32];
4057 tANI_U8 len = 0;
4058 hdd_getBand_helper(pHddCtx, &band);
4059
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05304060 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
4061 TRACE_CODE_HDD_GETBAND_IOCTL,
4062 pAdapter->sessionId, band));
Sameer Thalappilb0a30232013-09-27 15:37:48 -07004063 len = scnprintf(extra, sizeof(extra), "%s %d", command, band);
Ratnam Rachuri52139592015-07-17 13:17:29 +05304064 len = VOS_MIN(priv_data.total_len, len + 1);
4065 if (copy_to_user(priv_data.buf, &extra, len)) {
Srinivas Girigowdade697412013-02-14 16:31:48 -08004066 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4067 "%s: failed to copy data to user buffer", __func__);
4068 ret = -EFAULT;
4069 goto exit;
4070 }
4071 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08004072 else if (strncmp(command, "SETROAMSCANCHANNELS", 19) == 0)
4073 {
4074 tANI_U8 *value = command;
4075 tANI_U8 ChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
4076 tANI_U8 numChannels = 0;
4077 eHalStatus status = eHAL_STATUS_SUCCESS;
4078
4079 status = hdd_parse_channellist(value, ChannelList, &numChannels);
4080 if (eHAL_STATUS_SUCCESS != status)
4081 {
4082 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4083 "%s: Failed to parse channel list information", __func__);
4084 ret = -EINVAL;
4085 goto exit;
4086 }
4087
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05304088 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
4089 TRACE_CODE_HDD_SETROAMSCANCHANNELS_IOCTL,
4090 pAdapter->sessionId, numChannels));
Srinivas Girigowdade697412013-02-14 16:31:48 -08004091 if (numChannels > WNI_CFG_VALID_CHANNEL_LIST_LEN)
4092 {
4093 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4094 "%s: number of channels (%d) supported exceeded max (%d)", __func__,
4095 numChannels, WNI_CFG_VALID_CHANNEL_LIST_LEN);
4096 ret = -EINVAL;
4097 goto exit;
4098 }
4099 status = sme_ChangeRoamScanChannelList((tHalHandle)(pHddCtx->hHal), ChannelList,
4100 numChannels);
4101 if (eHAL_STATUS_SUCCESS != status)
4102 {
4103 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4104 "%s: Failed to update channel list information", __func__);
4105 ret = -EINVAL;
4106 goto exit;
4107 }
4108 }
4109 else if (strncmp(command, "GETROAMSCANCHANNELS", 19) == 0)
4110 {
4111 tANI_U8 ChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
4112 tANI_U8 numChannels = 0;
Jeff Johnson51b67782013-04-05 12:35:41 -07004113 tANI_U8 j = 0;
Srinivas Girigowdade697412013-02-14 16:31:48 -08004114 char extra[128] = {0};
Jeff Johnson51b67782013-04-05 12:35:41 -07004115 int len;
Srinivas Girigowdade697412013-02-14 16:31:48 -08004116
4117 if (eHAL_STATUS_SUCCESS != sme_getRoamScanChannelList( (tHalHandle)(pHddCtx->hHal),
4118 ChannelList, &numChannels ))
4119 {
4120 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
4121 "%s: failed to get roam scan channel list", __func__);
4122 ret = -EFAULT;
4123 goto exit;
4124 }
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05304125 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
4126 TRACE_CODE_HDD_GETROAMSCANCHANNELS_IOCTL,
4127 pAdapter->sessionId, numChannels));
Srinivas Girigowdade697412013-02-14 16:31:48 -08004128 /* output channel list is of the format
4129 [Number of roam scan channels][Channel1][Channel2]... */
4130 /* copy the number of channels in the 0th index */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07004131 len = scnprintf(extra, sizeof(extra), "%s %d", command, numChannels);
Sushant Kaushika08ca192015-09-16 15:52:04 +05304132 for (j = 0; (j < numChannels) && len <= sizeof(extra); j++)
Srinivas Girigowdade697412013-02-14 16:31:48 -08004133 {
Sameer Thalappilb0a30232013-09-27 15:37:48 -07004134 len += scnprintf(extra + len, sizeof(extra) - len, " %d",
4135 ChannelList[j]);
Srinivas Girigowdade697412013-02-14 16:31:48 -08004136 }
4137
Sushant Kaushikc9b8be52015-07-15 16:41:27 +05304138 len = VOS_MIN(priv_data.total_len, len + 1);
4139 if (copy_to_user(priv_data.buf, &extra, len))
Srinivas Girigowdade697412013-02-14 16:31:48 -08004140 {
4141 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4142 "%s: failed to copy data to user buffer", __func__);
4143 ret = -EFAULT;
4144 goto exit;
4145 }
4146 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004147 else if (strncmp(command, "GETCCXMODE", 10) == 0)
4148 {
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004149 tANI_BOOLEAN eseMode = sme_getIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal));
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004150 char extra[32];
4151 tANI_U8 len = 0;
4152
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004153 /* Check if the features OKC/ESE/11R are supported simultaneously,
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07004154 then this operation is not permitted (return FAILURE) */
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004155 if (eseMode &&
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07004156 hdd_is_okc_mode_enabled(pHddCtx) &&
4157 sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal)))
4158 {
4159 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004160 "%s: OKC/ESE/11R are supported simultaneously"
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07004161 " hence this operation is not permitted!", __func__);
4162 ret = -EPERM;
4163 goto exit;
4164 }
4165
Sameer Thalappilb0a30232013-09-27 15:37:48 -07004166 len = scnprintf(extra, sizeof(extra), "%s %d",
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004167 "GETCCXMODE", eseMode);
Sushant Kaushikf8abd352015-07-15 16:37:49 +05304168 len = VOS_MIN(priv_data.total_len, len + 1);
4169 if (copy_to_user(priv_data.buf, &extra, len))
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004170 {
4171 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4172 "%s: failed to copy data to user buffer", __func__);
4173 ret = -EFAULT;
4174 goto exit;
4175 }
4176 }
4177 else if (strncmp(command, "GETOKCMODE", 10) == 0)
4178 {
4179 tANI_BOOLEAN okcMode = hdd_is_okc_mode_enabled(pHddCtx);
4180 char extra[32];
4181 tANI_U8 len = 0;
4182
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004183 /* Check if the features OKC/ESE/11R are supported simultaneously,
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07004184 then this operation is not permitted (return FAILURE) */
4185 if (okcMode &&
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004186 sme_getIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal)) &&
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07004187 sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal)))
4188 {
4189 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004190 "%s: OKC/ESE/11R are supported simultaneously"
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07004191 " hence this operation is not permitted!", __func__);
4192 ret = -EPERM;
4193 goto exit;
4194 }
4195
Sameer Thalappilb0a30232013-09-27 15:37:48 -07004196 len = scnprintf(extra, sizeof(extra), "%s %d",
4197 "GETOKCMODE", okcMode);
Sushant Kaushikbc2fb5c2015-07-15 16:43:16 +05304198 len = VOS_MIN(priv_data.total_len, len + 1);
4199 if (copy_to_user(priv_data.buf, &extra, len))
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004200 {
4201 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4202 "%s: failed to copy data to user buffer", __func__);
4203 ret = -EFAULT;
4204 goto exit;
4205 }
4206 }
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07004207 else if (strncmp(command, "GETFASTROAM", 11) == 0)
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004208 {
4209 tANI_BOOLEAN lfrMode = sme_getIsLfrFeatureEnabled((tHalHandle)(pHddCtx->hHal));
4210 char extra[32];
4211 tANI_U8 len = 0;
4212
Sameer Thalappilb0a30232013-09-27 15:37:48 -07004213 len = scnprintf(extra, sizeof(extra), "%s %d",
4214 "GETFASTROAM", lfrMode);
Sushant Kaushik4da7ec92015-07-15 16:39:32 +05304215 len = VOS_MIN(priv_data.total_len, len + 1);
4216 if (copy_to_user(priv_data.buf, &extra, len))
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004217 {
4218 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4219 "%s: failed to copy data to user buffer", __func__);
4220 ret = -EFAULT;
4221 goto exit;
4222 }
4223 }
4224 else if (strncmp(command, "GETFASTTRANSITION", 17) == 0)
4225 {
4226 tANI_BOOLEAN ft = sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal));
4227 char extra[32];
4228 tANI_U8 len = 0;
4229
Sameer Thalappilb0a30232013-09-27 15:37:48 -07004230 len = scnprintf(extra, sizeof(extra), "%s %d",
4231 "GETFASTTRANSITION", ft);
Sushant Kaushik231a4452015-07-15 16:23:56 +05304232 len = VOS_MIN(priv_data.total_len, len + 1);
4233 if (copy_to_user(priv_data.buf, &extra, len))
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004234 {
4235 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4236 "%s: failed to copy data to user buffer", __func__);
4237 ret = -EFAULT;
4238 goto exit;
4239 }
4240 }
4241 else if (strncmp(command, "SETROAMSCANCHANNELMINTIME", 25) == 0)
4242 {
4243 tANI_U8 *value = command;
4244 tANI_U8 minTime = CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_DEFAULT;
4245
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05304246 ret = hdd_drv_cmd_validate(command, 25);
4247 if (ret)
4248 goto exit;
4249
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004250 /* Move pointer to ahead of SETROAMSCANCHANNELMINTIME<delimiter> */
4251 value = value + 26;
4252 /* Convert the value from ascii to integer */
4253 ret = kstrtou8(value, 10, &minTime);
4254 if (ret < 0)
4255 {
4256 /* If the input value is greater than max value of datatype, then also
4257 kstrtou8 fails */
4258 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4259 "%s: kstrtou8 failed range [%d - %d]", __func__,
4260 CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MIN,
4261 CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MAX);
4262 ret = -EINVAL;
4263 goto exit;
4264 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004265 if ((minTime < CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MIN) ||
4266 (minTime > CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MAX))
4267 {
4268 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4269 "scan min channel time value %d is out of range"
4270 " (Min: %d Max: %d)", minTime,
4271 CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MIN,
4272 CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MAX);
4273 ret = -EINVAL;
4274 goto exit;
4275 }
4276
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05304277 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
4278 TRACE_CODE_HDD_SETROAMSCANCHANNELMINTIME_IOCTL,
4279 pAdapter->sessionId, minTime));
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004280 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4281 "%s: Received Command to change channel min time = %d", __func__, minTime);
4282
4283 pHddCtx->cfg_ini->nNeighborScanMinChanTime = minTime;
4284 sme_setNeighborScanMinChanTime((tHalHandle)(pHddCtx->hHal), minTime);
4285 }
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004286 else if (strncmp(command, "SENDACTIONFRAME", 15) == 0)
4287 {
4288 tANI_U8 *value = command;
4289 tANI_U8 channel = 0;
4290 tANI_U8 dwellTime = 0;
4291 tANI_U8 bufLen = 0;
4292 tANI_U8 *buf = NULL;
4293 tSirMacAddr targetApBssid;
4294 eHalStatus status = eHAL_STATUS_SUCCESS;
4295 struct ieee80211_channel chan;
4296 tANI_U8 finalLen = 0;
4297 tANI_U8 *finalBuf = NULL;
4298 tANI_U8 temp = 0;
4299 u64 cookie;
4300 hdd_station_ctx_t *pHddStaCtx = NULL;
4301 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4302
4303 /* if not associated, no need to send action frame */
4304 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
4305 {
4306 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s:Not associated!",__func__);
4307 ret = -EINVAL;
4308 goto exit;
4309 }
4310
4311 status = hdd_parse_send_action_frame_data(value, targetApBssid, &channel,
4312 &dwellTime, &buf, &bufLen);
4313 if (eHAL_STATUS_SUCCESS != status)
4314 {
4315 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4316 "%s: Failed to parse send action frame data", __func__);
4317 ret = -EINVAL;
4318 goto exit;
4319 }
4320
4321 /* if the target bssid is different from currently associated AP,
4322 then no need to send action frame */
4323 if (VOS_TRUE != vos_mem_compare(targetApBssid,
4324 pHddStaCtx->conn_info.bssId, sizeof(tSirMacAddr)))
4325 {
4326 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s:STA is not associated to this AP!",__func__);
4327 ret = -EINVAL;
Jeff Johnson11c33152013-04-16 17:52:40 -07004328 vos_mem_free(buf);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08004329 buf = NULL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004330 goto exit;
4331 }
4332
4333 /* if the channel number is different from operating channel then
4334 no need to send action frame */
4335 if (channel != pHddStaCtx->conn_info.operationChannel)
4336 {
4337 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4338 "%s: channel(%d) is different from operating channel(%d)",
4339 __func__, channel, pHddStaCtx->conn_info.operationChannel);
4340 ret = -EINVAL;
Jeff Johnson11c33152013-04-16 17:52:40 -07004341 vos_mem_free(buf);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08004342 buf = NULL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004343 goto exit;
4344 }
4345 chan.center_freq = sme_ChnToFreq(channel);
4346
4347 finalLen = bufLen + 24;
4348 finalBuf = vos_mem_malloc(finalLen);
4349 if (NULL == finalBuf)
4350 {
4351 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "%s:memory allocation failed",__func__);
4352 ret = -ENOMEM;
Jeff Johnson11c33152013-04-16 17:52:40 -07004353 vos_mem_free(buf);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08004354 buf = NULL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004355 goto exit;
4356 }
4357 vos_mem_zero(finalBuf, finalLen);
4358
4359 /* Fill subtype */
4360 temp = SIR_MAC_MGMT_ACTION << 4;
4361 vos_mem_copy(finalBuf + 0, &temp, sizeof(temp));
4362
4363 /* Fill type */
4364 temp = SIR_MAC_MGMT_FRAME;
4365 vos_mem_copy(finalBuf + 2, &temp, sizeof(temp));
4366
4367 /* Fill destination address (bssid of the AP) */
4368 vos_mem_copy(finalBuf + 4, targetApBssid, sizeof(targetApBssid));
4369
Srinivas Girigowdab27c0192013-06-03 10:19:56 -07004370 /* Fill source address (STA mac address) */
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004371 vos_mem_copy(finalBuf + 10, pAdapter->macAddressCurrent.bytes, sizeof(pAdapter->macAddressCurrent.bytes));
4372
Srinivas Girigowdab27c0192013-06-03 10:19:56 -07004373 /* Fill BSSID (AP mac address) */
4374 vos_mem_copy(finalBuf + 16, targetApBssid, sizeof(targetApBssid));
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004375
4376 /* Fill received buffer from 24th address */
4377 vos_mem_copy(finalBuf + 24, buf, bufLen);
4378
Jeff Johnson11c33152013-04-16 17:52:40 -07004379 /* done with the parsed buffer */
4380 vos_mem_free(buf);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08004381 buf = NULL;
Jeff Johnson11c33152013-04-16 17:52:40 -07004382
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05304383#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
4384 params.chan = &chan;
4385 params.offchan = 0;
4386 params.wait = dwellTime;
4387 params.buf = finalBuf;
4388 params.len = finalLen;
4389 params.no_cck = 1;
4390 params.dont_wait_for_ack = 1;
4391 ret = wlan_hdd_mgmt_tx(NULL, &pAdapter->wdev, &params, &cookie);
4392#else
DARAM SUDHA39eede62014-02-12 11:16:40 +05304393 wlan_hdd_mgmt_tx( NULL,
Yue Maf49ba872013-08-19 12:04:25 -07004394#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
4395 &(pAdapter->wdev),
4396#else
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07004397 pAdapter->dev,
Yue Maf49ba872013-08-19 12:04:25 -07004398#endif
4399 &chan, 0,
4400#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0))
4401 NL80211_CHAN_HT20, 1,
4402#endif
4403 dwellTime, finalBuf, finalLen, 1,
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004404 1, &cookie );
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05304405#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0)*/
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004406 vos_mem_free(finalBuf);
4407 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004408 else if (strncmp(command, "GETROAMSCANCHANNELMINTIME", 25) == 0)
4409 {
4410 tANI_U16 val = sme_getNeighborScanMinChanTime((tHalHandle)(pHddCtx->hHal));
4411 char extra[32];
4412 tANI_U8 len = 0;
4413
4414 /* value is interms of msec */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07004415 len = scnprintf(extra, sizeof(extra), "%s %d",
4416 "GETROAMSCANCHANNELMINTIME", val);
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05304417 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
4418 TRACE_CODE_HDD_GETROAMSCANCHANNELMINTIME_IOCTL,
4419 pAdapter->sessionId, val));
Sushant Kaushikbb8c52c2015-07-15 16:36:23 +05304420 len = VOS_MIN(priv_data.total_len, len + 1);
4421 if (copy_to_user(priv_data.buf, &extra, len))
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004422 {
4423 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4424 "%s: failed to copy data to user buffer", __func__);
4425 ret = -EFAULT;
4426 goto exit;
4427 }
4428 }
4429 else if (strncmp(command, "SETSCANCHANNELTIME", 18) == 0)
4430 {
4431 tANI_U8 *value = command;
Varun Reddy Yeturu3885a662013-06-19 07:10:37 -07004432 tANI_U16 maxTime = CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_DEFAULT;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004433
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05304434 ret = hdd_drv_cmd_validate(command, 18);
4435 if (ret)
4436 goto exit;
4437
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004438 /* Move pointer to ahead of SETSCANCHANNELTIME<delimiter> */
4439 value = value + 19;
4440 /* Convert the value from ascii to integer */
Varun Reddy Yeturu3885a662013-06-19 07:10:37 -07004441 ret = kstrtou16(value, 10, &maxTime);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004442 if (ret < 0)
4443 {
4444 /* If the input value is greater than max value of datatype, then also
Varun Reddy Yeturu3885a662013-06-19 07:10:37 -07004445 kstrtou16 fails */
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004446 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Varun Reddy Yeturu3885a662013-06-19 07:10:37 -07004447 "%s: kstrtou16 failed range [%d - %d]", __func__,
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004448 CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MIN,
4449 CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MAX);
4450 ret = -EINVAL;
4451 goto exit;
4452 }
4453
4454 if ((maxTime < CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MIN) ||
4455 (maxTime > CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MAX))
4456 {
4457 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4458 "lfr mode value %d is out of range"
4459 " (Min: %d Max: %d)", maxTime,
4460 CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MIN,
4461 CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MAX);
4462 ret = -EINVAL;
4463 goto exit;
4464 }
4465
4466 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4467 "%s: Received Command to change channel max time = %d", __func__, maxTime);
4468
4469 pHddCtx->cfg_ini->nNeighborScanMaxChanTime = maxTime;
4470 sme_setNeighborScanMaxChanTime((tHalHandle)(pHddCtx->hHal), maxTime);
4471 }
4472 else if (strncmp(command, "GETSCANCHANNELTIME", 18) == 0)
4473 {
4474 tANI_U16 val = sme_getNeighborScanMaxChanTime((tHalHandle)(pHddCtx->hHal));
4475 char extra[32];
4476 tANI_U8 len = 0;
4477
4478 /* value is interms of msec */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07004479 len = scnprintf(extra, sizeof(extra), "%s %d",
4480 "GETSCANCHANNELTIME", val);
Ratheesh S Pacbfa932015-07-16 15:27:18 +05304481 len = VOS_MIN(priv_data.total_len, len + 1);
4482 if (copy_to_user(priv_data.buf, &extra, len))
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004483 {
4484 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4485 "%s: failed to copy data to user buffer", __func__);
4486 ret = -EFAULT;
4487 goto exit;
4488 }
4489 }
4490 else if (strncmp(command, "SETSCANHOMETIME", 15) == 0)
4491 {
4492 tANI_U8 *value = command;
4493 tANI_U16 val = CFG_NEIGHBOR_SCAN_TIMER_PERIOD_DEFAULT;
4494
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05304495 ret = hdd_drv_cmd_validate(command, 15);
4496 if (ret)
4497 goto exit;
4498
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004499 /* Move pointer to ahead of SETSCANHOMETIME<delimiter> */
4500 value = value + 16;
4501 /* Convert the value from ascii to integer */
4502 ret = kstrtou16(value, 10, &val);
4503 if (ret < 0)
4504 {
4505 /* If the input value is greater than max value of datatype, then also
4506 kstrtou16 fails */
4507 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4508 "%s: kstrtou16 failed range [%d - %d]", __func__,
4509 CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MIN,
4510 CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MAX);
4511 ret = -EINVAL;
4512 goto exit;
4513 }
4514
4515 if ((val < CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MIN) ||
4516 (val > CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MAX))
4517 {
4518 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4519 "scan home time value %d is out of range"
4520 " (Min: %d Max: %d)", val,
4521 CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MIN,
4522 CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MAX);
4523 ret = -EINVAL;
4524 goto exit;
4525 }
4526
4527 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4528 "%s: Received Command to change scan home time = %d", __func__, val);
4529
4530 pHddCtx->cfg_ini->nNeighborScanPeriod = val;
4531 sme_setNeighborScanPeriod((tHalHandle)(pHddCtx->hHal), val);
4532 }
4533 else if (strncmp(command, "GETSCANHOMETIME", 15) == 0)
4534 {
4535 tANI_U16 val = sme_getNeighborScanPeriod((tHalHandle)(pHddCtx->hHal));
4536 char extra[32];
4537 tANI_U8 len = 0;
4538
4539 /* value is interms of msec */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07004540 len = scnprintf(extra, sizeof(extra), "%s %d",
4541 "GETSCANHOMETIME", val);
Ratheesh S P728d7c62015-07-16 15:38:58 +05304542 len = VOS_MIN(priv_data.total_len, len + 1);
4543 if (copy_to_user(priv_data.buf, &extra, len))
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004544 {
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 }
4551 else if (strncmp(command, "SETROAMINTRABAND", 16) == 0)
4552 {
4553 tANI_U8 *value = command;
4554 tANI_U8 val = CFG_ROAM_INTRA_BAND_DEFAULT;
4555
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05304556 ret = hdd_drv_cmd_validate(command, 16);
4557 if (ret)
4558 goto exit;
4559
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004560 /* Move pointer to ahead of SETROAMINTRABAND<delimiter> */
4561 value = value + 17;
4562 /* Convert the value from ascii to integer */
4563 ret = kstrtou8(value, 10, &val);
4564 if (ret < 0)
4565 {
4566 /* If the input value is greater than max value of datatype, then also
4567 kstrtou8 fails */
4568 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4569 "%s: kstrtou8 failed range [%d - %d]", __func__,
4570 CFG_ROAM_INTRA_BAND_MIN,
4571 CFG_ROAM_INTRA_BAND_MAX);
4572 ret = -EINVAL;
4573 goto exit;
4574 }
4575
4576 if ((val < CFG_ROAM_INTRA_BAND_MIN) ||
4577 (val > CFG_ROAM_INTRA_BAND_MAX))
4578 {
4579 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4580 "intra band mode value %d is out of range"
4581 " (Min: %d Max: %d)", val,
4582 CFG_ROAM_INTRA_BAND_MIN,
4583 CFG_ROAM_INTRA_BAND_MAX);
4584 ret = -EINVAL;
4585 goto exit;
4586 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004587 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4588 "%s: Received Command to change intra band = %d", __func__, val);
4589
4590 pHddCtx->cfg_ini->nRoamIntraBand = val;
4591 sme_setRoamIntraBand((tHalHandle)(pHddCtx->hHal), val);
4592 }
4593 else if (strncmp(command, "GETROAMINTRABAND", 16) == 0)
4594 {
4595 tANI_U16 val = sme_getRoamIntraBand((tHalHandle)(pHddCtx->hHal));
4596 char extra[32];
4597 tANI_U8 len = 0;
4598
4599 /* value is interms of msec */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07004600 len = scnprintf(extra, sizeof(extra), "%s %d",
4601 "GETROAMINTRABAND", val);
Ratheesh S P2dd2a3e2015-07-16 15:34:23 +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 }
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07004611 else if (strncmp(command, "SETSCANNPROBES", 14) == 0)
4612 {
4613 tANI_U8 *value = command;
4614 tANI_U8 nProbes = CFG_ROAM_SCAN_N_PROBES_DEFAULT;
4615
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05304616 ret = hdd_drv_cmd_validate(command, 14);
4617 if (ret)
4618 goto exit;
4619
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07004620 /* Move pointer to ahead of SETSCANNPROBES<delimiter> */
4621 value = value + 15;
4622 /* Convert the value from ascii to integer */
4623 ret = kstrtou8(value, 10, &nProbes);
4624 if (ret < 0)
4625 {
4626 /* If the input value is greater than max value of datatype, then also
4627 kstrtou8 fails */
4628 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4629 "%s: kstrtou8 failed range [%d - %d]", __func__,
4630 CFG_ROAM_SCAN_N_PROBES_MIN,
4631 CFG_ROAM_SCAN_N_PROBES_MAX);
4632 ret = -EINVAL;
4633 goto exit;
4634 }
4635
4636 if ((nProbes < CFG_ROAM_SCAN_N_PROBES_MIN) ||
4637 (nProbes > CFG_ROAM_SCAN_N_PROBES_MAX))
4638 {
4639 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4640 "NProbes value %d is out of range"
4641 " (Min: %d Max: %d)", nProbes,
4642 CFG_ROAM_SCAN_N_PROBES_MIN,
4643 CFG_ROAM_SCAN_N_PROBES_MAX);
4644 ret = -EINVAL;
4645 goto exit;
4646 }
4647
4648 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4649 "%s: Received Command to Set nProbes = %d", __func__, nProbes);
4650
4651 pHddCtx->cfg_ini->nProbes = nProbes;
4652 sme_UpdateRoamScanNProbes((tHalHandle)(pHddCtx->hHal), nProbes);
4653 }
Mahesh A Saptasagarec7d1092015-04-02 13:41:34 +05304654 else if (strncmp(command, "GETSCANNPROBES", 14) == 0)
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07004655 {
4656 tANI_U8 val = sme_getRoamScanNProbes((tHalHandle)(pHddCtx->hHal));
4657 char extra[32];
4658 tANI_U8 len = 0;
4659
Sameer Thalappilb0a30232013-09-27 15:37:48 -07004660 len = scnprintf(extra, sizeof(extra), "%s %d", command, val);
Ratnam Rachuri6da525d2015-08-07 13:55:54 +05304661 len = VOS_MIN(priv_data.total_len, len + 1);
4662 if (copy_to_user(priv_data.buf, &extra, len)) {
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07004663 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4664 "%s: failed to copy data to user buffer", __func__);
4665 ret = -EFAULT;
4666 goto exit;
4667 }
4668 }
4669 else if (strncmp(command, "SETSCANHOMEAWAYTIME", 19) == 0)
4670 {
4671 tANI_U8 *value = command;
4672 tANI_U16 homeAwayTime = CFG_ROAM_SCAN_HOME_AWAY_TIME_DEFAULT;
4673
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05304674 ret = hdd_drv_cmd_validate(command, 19);
4675 if (ret)
4676 goto exit;
4677
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07004678 /* Move pointer to ahead of SETSCANHOMEAWAYTIME<delimiter> */
4679 /* input value is in units of msec */
4680 value = value + 20;
4681 /* Convert the value from ascii to integer */
4682 ret = kstrtou16(value, 10, &homeAwayTime);
4683 if (ret < 0)
4684 {
4685 /* If the input value is greater than max value of datatype, then also
4686 kstrtou8 fails */
4687 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4688 "%s: kstrtou8 failed range [%d - %d]", __func__,
4689 CFG_ROAM_SCAN_HOME_AWAY_TIME_MIN,
4690 CFG_ROAM_SCAN_HOME_AWAY_TIME_MAX);
4691 ret = -EINVAL;
4692 goto exit;
4693 }
4694
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07004695 if ((homeAwayTime < CFG_ROAM_SCAN_HOME_AWAY_TIME_MIN) ||
4696 (homeAwayTime > CFG_ROAM_SCAN_HOME_AWAY_TIME_MAX))
4697 {
4698 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4699 "homeAwayTime value %d is out of range"
4700 " (Min: %d Max: %d)", homeAwayTime,
4701 CFG_ROAM_SCAN_HOME_AWAY_TIME_MIN,
4702 CFG_ROAM_SCAN_HOME_AWAY_TIME_MAX);
4703 ret = -EINVAL;
4704 goto exit;
4705 }
4706
4707 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4708 "%s: Received Command to Set scan away time = %d", __func__, homeAwayTime);
Srinivas Girigowda6cf0b822013-06-27 14:00:20 -07004709 if (pHddCtx->cfg_ini->nRoamScanHomeAwayTime != homeAwayTime)
4710 {
4711 pHddCtx->cfg_ini->nRoamScanHomeAwayTime = homeAwayTime;
4712 sme_UpdateRoamScanHomeAwayTime((tHalHandle)(pHddCtx->hHal), homeAwayTime, eANI_BOOLEAN_TRUE);
4713 }
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07004714 }
Mahesh A Saptasagarec7d1092015-04-02 13:41:34 +05304715 else if (strncmp(command, "GETSCANHOMEAWAYTIME", 19) == 0)
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07004716 {
4717 tANI_U16 val = sme_getRoamScanHomeAwayTime((tHalHandle)(pHddCtx->hHal));
4718 char extra[32];
4719 tANI_U8 len = 0;
4720
Sameer Thalappilb0a30232013-09-27 15:37:48 -07004721 len = scnprintf(extra, sizeof(extra), "%s %d", command, val);
Ratnam Rachuri51a5ad12015-08-07 14:06:37 +05304722 len = VOS_MIN(priv_data.total_len, len + 1);
4723 if (copy_to_user(priv_data.buf, &extra, len)) {
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07004724 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4725 "%s: failed to copy data to user buffer", __func__);
4726 ret = -EFAULT;
4727 goto exit;
4728 }
4729 }
4730 else if (strncmp(command, "REASSOC", 7) == 0)
4731 {
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05304732 ret = hdd_drv_cmd_validate(command, 7);
4733 if (ret)
4734 goto exit;
4735
4736 ret = hdd_parse_reassoc(pAdapter, command, priv_data.total_len);
Selvaraj, Sridhar5aff1ed2016-06-18 01:26:23 +05304737 if (!ret)
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07004738 goto exit;
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07004739 }
Srinivas Girigowdaad34ca92013-10-22 10:54:29 -07004740 else if (strncmp(command, "SETWESMODE", 10) == 0)
4741 {
4742 tANI_U8 *value = command;
4743 tANI_BOOLEAN wesMode = CFG_ENABLE_WES_MODE_NAME_DEFAULT;
4744
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05304745 ret = hdd_drv_cmd_validate(command, 10);
4746 if (ret)
4747 goto exit;
4748
Srinivas Girigowdaad34ca92013-10-22 10:54:29 -07004749 /* Move pointer to ahead of SETWESMODE<delimiter> */
4750 value = value + 11;
4751 /* Convert the value from ascii to integer */
4752 ret = kstrtou8(value, 10, &wesMode);
4753 if (ret < 0)
4754 {
4755 /* If the input value is greater than max value of datatype, then also
4756 kstrtou8 fails */
4757 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4758 "%s: kstrtou8 failed range [%d - %d]", __func__,
4759 CFG_ENABLE_WES_MODE_NAME_MIN,
4760 CFG_ENABLE_WES_MODE_NAME_MAX);
4761 ret = -EINVAL;
4762 goto exit;
4763 }
4764
4765 if ((wesMode < CFG_ENABLE_WES_MODE_NAME_MIN) ||
4766 (wesMode > CFG_ENABLE_WES_MODE_NAME_MAX))
4767 {
4768 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4769 "WES Mode value %d is out of range"
4770 " (Min: %d Max: %d)", wesMode,
4771 CFG_ENABLE_WES_MODE_NAME_MIN,
4772 CFG_ENABLE_WES_MODE_NAME_MAX);
4773 ret = -EINVAL;
4774 goto exit;
4775 }
4776 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4777 "%s: Received Command to Set WES Mode rssi diff = %d", __func__, wesMode);
4778
4779 pHddCtx->cfg_ini->isWESModeEnabled = wesMode;
4780 sme_UpdateWESMode((tHalHandle)(pHddCtx->hHal), wesMode);
4781 }
Mahesh A Saptasagarec7d1092015-04-02 13:41:34 +05304782 else if (strncmp(command, "GETWESMODE", 10) == 0)
Srinivas Girigowdaad34ca92013-10-22 10:54:29 -07004783 {
4784 tANI_BOOLEAN wesMode = sme_GetWESMode((tHalHandle)(pHddCtx->hHal));
4785 char extra[32];
4786 tANI_U8 len = 0;
4787
Arif Hussain826d9412013-11-12 16:44:54 -08004788 len = scnprintf(extra, sizeof(extra), "%s %d", command, wesMode);
Ratnam Rachuri8fe90c62015-08-07 14:03:26 +05304789 len = VOS_MIN(priv_data.total_len, len + 1);
4790 if (copy_to_user(priv_data.buf, &extra, len)) {
Srinivas Girigowdaad34ca92013-10-22 10:54:29 -07004791 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4792 "%s: failed to copy data to user buffer", __func__);
4793 ret = -EFAULT;
4794 goto exit;
4795 }
4796 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004797#endif /* WLAN_FEATURE_VOWIFI_11R || FEATURE_WLAN_ESE || FEATURE_WLAN_LFR */
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004798#ifdef FEATURE_WLAN_LFR
4799 else if (strncmp(command, "SETFASTROAM", 11) == 0)
4800 {
4801 tANI_U8 *value = command;
4802 tANI_U8 lfrMode = CFG_LFR_FEATURE_ENABLED_DEFAULT;
4803
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +05304804 if (pHddCtx->concurrency_mode == VOS_STA_MON) {
4805 hddLog(LOGE,
4806 FL("Roaming is always disabled in STA + MON concurrency"));
4807 ret = -EINVAL;
4808 goto exit;
4809 }
4810
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05304811 ret = hdd_drv_cmd_validate(command, 11);
4812 if (ret)
4813 goto exit;
4814
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004815 /* Move pointer to ahead of SETFASTROAM<delimiter> */
4816 value = value + 12;
4817 /* Convert the value from ascii to integer */
4818 ret = kstrtou8(value, 10, &lfrMode);
4819 if (ret < 0)
4820 {
4821 /* If the input value is greater than max value of datatype, then also
4822 kstrtou8 fails */
4823 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4824 "%s: kstrtou8 failed range [%d - %d]", __func__,
4825 CFG_LFR_FEATURE_ENABLED_MIN,
4826 CFG_LFR_FEATURE_ENABLED_MAX);
4827 ret = -EINVAL;
4828 goto exit;
4829 }
4830
4831 if ((lfrMode < CFG_LFR_FEATURE_ENABLED_MIN) ||
4832 (lfrMode > CFG_LFR_FEATURE_ENABLED_MAX))
4833 {
4834 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4835 "lfr mode value %d is out of range"
4836 " (Min: %d Max: %d)", lfrMode,
4837 CFG_LFR_FEATURE_ENABLED_MIN,
4838 CFG_LFR_FEATURE_ENABLED_MAX);
4839 ret = -EINVAL;
4840 goto exit;
4841 }
4842
4843 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4844 "%s: Received Command to change lfr mode = %d", __func__, lfrMode);
4845
4846 pHddCtx->cfg_ini->isFastRoamIniFeatureEnabled = lfrMode;
4847 sme_UpdateIsFastRoamIniFeatureEnabled((tHalHandle)(pHddCtx->hHal), lfrMode);
4848 }
4849#endif
4850#ifdef WLAN_FEATURE_VOWIFI_11R
4851 else if (strncmp(command, "SETFASTTRANSITION", 17) == 0)
4852 {
4853 tANI_U8 *value = command;
4854 tANI_U8 ft = CFG_FAST_TRANSITION_ENABLED_NAME_DEFAULT;
4855
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05304856 ret = hdd_drv_cmd_validate(command, 17);
4857 if (ret)
4858 goto exit;
4859
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004860 /* Move pointer to ahead of SETFASTROAM<delimiter> */
4861 value = value + 18;
4862 /* Convert the value from ascii to integer */
4863 ret = kstrtou8(value, 10, &ft);
4864 if (ret < 0)
4865 {
4866 /* If the input value is greater than max value of datatype, then also
4867 kstrtou8 fails */
4868 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4869 "%s: kstrtou8 failed range [%d - %d]", __func__,
4870 CFG_FAST_TRANSITION_ENABLED_NAME_MIN,
4871 CFG_FAST_TRANSITION_ENABLED_NAME_MAX);
4872 ret = -EINVAL;
4873 goto exit;
4874 }
4875
4876 if ((ft < CFG_FAST_TRANSITION_ENABLED_NAME_MIN) ||
4877 (ft > CFG_FAST_TRANSITION_ENABLED_NAME_MAX))
4878 {
4879 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4880 "ft mode value %d is out of range"
4881 " (Min: %d Max: %d)", ft,
4882 CFG_FAST_TRANSITION_ENABLED_NAME_MIN,
4883 CFG_FAST_TRANSITION_ENABLED_NAME_MAX);
4884 ret = -EINVAL;
4885 goto exit;
4886 }
4887
4888 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4889 "%s: Received Command to change ft mode = %d", __func__, ft);
4890
4891 pHddCtx->cfg_ini->isFastTransitionEnabled = ft;
4892 sme_UpdateFastTransitionEnabled((tHalHandle)(pHddCtx->hHal), ft);
4893 }
Padma, Santhosh Kumar778d8382015-03-04 17:41:22 +05304894 else if (strncmp(command, "SETDFSSCANMODE", 14) == 0)
4895 {
4896 tANI_U8 *value = command;
4897 tANI_U8 dfsScanMode = DFS_CHNL_SCAN_ENABLED_NORMAL;
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05304898
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05304899 ret = hdd_drv_cmd_validate(command, 14);
4900 if (ret)
4901 goto exit;
4902
Padma, Santhosh Kumar778d8382015-03-04 17:41:22 +05304903 /* Move pointer to ahead of SETDFSSCANMODE<delimiter> */
4904 value = value + 15;
4905 /* Convert the value from ascii to integer */
4906 ret = kstrtou8(value, 10, &dfsScanMode);
4907 if (ret < 0)
4908 {
4909 /* If the input value is greater than max value of
4910 datatype, then also kstrtou8 fails
4911 */
4912 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4913 "%s: kstrtou8 failed range [%d - %d]", __func__,
4914 CFG_ENABLE_DFS_CHNL_SCAN_MIN,
4915 CFG_ENABLE_DFS_CHNL_SCAN_MAX);
4916 ret = -EINVAL;
4917 goto exit;
4918 }
4919
4920 if ((dfsScanMode < CFG_ENABLE_DFS_CHNL_SCAN_MIN) ||
4921 (dfsScanMode > CFG_ENABLE_DFS_CHNL_SCAN_MAX))
4922 {
4923 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4924 "dfsScanMode value %d is out of range"
4925 " (Min: %d Max: %d)", dfsScanMode,
4926 CFG_ENABLE_DFS_CHNL_SCAN_MIN,
4927 CFG_ENABLE_DFS_CHNL_SCAN_MAX);
4928 ret = -EINVAL;
4929 goto exit;
4930 }
4931 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4932 "%s: Received Command to Set DFS Scan Mode = %d",
4933 __func__, dfsScanMode);
4934
4935 ret = wlan_hdd_handle_dfs_chan_scan(pHddCtx, dfsScanMode);
4936 }
4937 else if (strncmp(command, "GETDFSSCANMODE", 14) == 0)
4938 {
4939 tANI_U8 dfsScanMode = sme_GetDFSScanMode(pHddCtx->hHal);
4940 char extra[32];
4941 tANI_U8 len = 0;
4942
4943 len = scnprintf(extra, sizeof(extra), "%s %d", command, dfsScanMode);
Ratheesh S P767224e2015-07-16 15:35:51 +05304944 len = VOS_MIN(priv_data.total_len, len + 1);
4945 if (copy_to_user(priv_data.buf, &extra, len))
Padma, Santhosh Kumar778d8382015-03-04 17:41:22 +05304946 {
4947 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4948 "%s: failed to copy data to user buffer", __func__);
4949 ret = -EFAULT;
4950 goto exit;
4951 }
4952 }
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05304953 else if (strncmp(command, "FASTREASSOC", 11) == 0)
4954 {
Selvaraj, Sridhar3714c4d2016-06-22 15:19:12 +05304955 ret = wlan_hdd_handle_fastreassoc(pAdapter, command);
4956 if (!ret)
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05304957 goto exit;
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05304958 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004959#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004960#ifdef FEATURE_WLAN_ESE
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004961 else if (strncmp(command, "SETCCXMODE", 10) == 0)
4962 {
4963 tANI_U8 *value = command;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004964 tANI_U8 eseMode = CFG_ESE_FEATURE_ENABLED_DEFAULT;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004965
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05304966 ret = hdd_drv_cmd_validate(command, 10);
4967 if (ret)
4968 goto exit;
4969
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004970 /* Check if the features OKC/ESE/11R are supported simultaneously,
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07004971 then this operation is not permitted (return FAILURE) */
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004972 if (sme_getIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal)) &&
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07004973 hdd_is_okc_mode_enabled(pHddCtx) &&
4974 sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal)))
4975 {
4976 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004977 "%s: OKC/ESE/11R are supported simultaneously"
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07004978 " hence this operation is not permitted!", __func__);
4979 ret = -EPERM;
4980 goto exit;
4981 }
4982
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004983 /* Move pointer to ahead of SETCCXMODE<delimiter> */
4984 value = value + 11;
4985 /* Convert the value from ascii to integer */
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004986 ret = kstrtou8(value, 10, &eseMode);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004987 if (ret < 0)
4988 {
4989 /* If the input value is greater than max value of datatype, then also
4990 kstrtou8 fails */
4991 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4992 "%s: kstrtou8 failed range [%d - %d]", __func__,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004993 CFG_ESE_FEATURE_ENABLED_MIN,
4994 CFG_ESE_FEATURE_ENABLED_MAX);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004995 ret = -EINVAL;
4996 goto exit;
4997 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004998 if ((eseMode < CFG_ESE_FEATURE_ENABLED_MIN) ||
4999 (eseMode > CFG_ESE_FEATURE_ENABLED_MAX))
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07005000 {
5001 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005002 "Ese mode value %d is out of range"
5003 " (Min: %d Max: %d)", eseMode,
5004 CFG_ESE_FEATURE_ENABLED_MIN,
5005 CFG_ESE_FEATURE_ENABLED_MAX);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07005006 ret = -EINVAL;
5007 goto exit;
5008 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07005009 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005010 "%s: Received Command to change ese mode = %d", __func__, eseMode);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07005011
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005012 pHddCtx->cfg_ini->isEseIniFeatureEnabled = eseMode;
5013 sme_UpdateIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal), eseMode);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07005014 }
5015#endif
Srinivas Girigowda100eb322013-03-15 16:48:20 -07005016 else if (strncmp(command, "SETROAMSCANCONTROL", 18) == 0)
5017 {
5018 tANI_U8 *value = command;
5019 tANI_BOOLEAN roamScanControl = 0;
5020
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05305021 ret = hdd_drv_cmd_validate(command, 18);
5022 if (ret)
5023 goto exit;
5024
Srinivas Girigowda100eb322013-03-15 16:48:20 -07005025 /* Move pointer to ahead of SETROAMSCANCONTROL<delimiter> */
5026 value = value + 19;
5027 /* Convert the value from ascii to integer */
5028 ret = kstrtou8(value, 10, &roamScanControl);
5029 if (ret < 0)
5030 {
5031 /* If the input value is greater than max value of datatype, then also
5032 kstrtou8 fails */
5033 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5034 "%s: kstrtou8 failed ", __func__);
5035 ret = -EINVAL;
5036 goto exit;
5037 }
5038
5039 if (0 != roamScanControl)
5040 {
5041 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5042 "roam scan control invalid value = %d",
5043 roamScanControl);
5044 ret = -EINVAL;
5045 goto exit;
5046 }
5047 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
5048 "%s: Received Command to Set roam scan control = %d", __func__, roamScanControl);
5049
5050 sme_SetRoamScanControl((tHalHandle)(pHddCtx->hHal), roamScanControl);
5051 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07005052#ifdef FEATURE_WLAN_OKC
5053 else if (strncmp(command, "SETOKCMODE", 10) == 0)
5054 {
5055 tANI_U8 *value = command;
5056 tANI_U8 okcMode = CFG_OKC_FEATURE_ENABLED_DEFAULT;
5057
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05305058 ret = hdd_drv_cmd_validate(command, 10);
5059 if (ret)
5060 goto exit;
5061
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005062 /* Check if the features OKC/ESE/11R are supported simultaneously,
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07005063 then this operation is not permitted (return FAILURE) */
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005064 if (sme_getIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal)) &&
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07005065 hdd_is_okc_mode_enabled(pHddCtx) &&
5066 sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal)))
5067 {
5068 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005069 "%s: OKC/ESE/11R are supported simultaneously"
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07005070 " hence this operation is not permitted!", __func__);
5071 ret = -EPERM;
5072 goto exit;
5073 }
5074
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07005075 /* Move pointer to ahead of SETOKCMODE<delimiter> */
5076 value = value + 11;
5077 /* Convert the value from ascii to integer */
5078 ret = kstrtou8(value, 10, &okcMode);
5079 if (ret < 0)
5080 {
5081 /* If the input value is greater than max value of datatype, then also
5082 kstrtou8 fails */
5083 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5084 "%s: kstrtou8 failed range [%d - %d]", __func__,
5085 CFG_OKC_FEATURE_ENABLED_MIN,
5086 CFG_OKC_FEATURE_ENABLED_MAX);
5087 ret = -EINVAL;
5088 goto exit;
5089 }
5090
5091 if ((okcMode < CFG_OKC_FEATURE_ENABLED_MIN) ||
5092 (okcMode > CFG_OKC_FEATURE_ENABLED_MAX))
5093 {
5094 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5095 "Okc mode value %d is out of range"
5096 " (Min: %d Max: %d)", okcMode,
5097 CFG_OKC_FEATURE_ENABLED_MIN,
5098 CFG_OKC_FEATURE_ENABLED_MAX);
5099 ret = -EINVAL;
5100 goto exit;
5101 }
5102
5103 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
5104 "%s: Received Command to change okc mode = %d", __func__, okcMode);
5105
5106 pHddCtx->cfg_ini->isOkcIniFeatureEnabled = okcMode;
5107 }
Srinivas Girigowdaad34ca92013-10-22 10:54:29 -07005108#endif /* FEATURE_WLAN_OKC */
Mahesh A Saptasagarec7d1092015-04-02 13:41:34 +05305109 else if (strncmp(command, "GETROAMSCANCONTROL", 18) == 0)
Srinivas Girigowda100eb322013-03-15 16:48:20 -07005110 {
5111 tANI_BOOLEAN roamScanControl = sme_GetRoamScanControl((tHalHandle)(pHddCtx->hHal));
5112 char extra[32];
5113 tANI_U8 len = 0;
5114
Sameer Thalappilb0a30232013-09-27 15:37:48 -07005115 len = scnprintf(extra, sizeof(extra), "%s %d",
5116 command, roamScanControl);
Ratnam Rachuri083ada82015-08-07 14:01:05 +05305117 len = VOS_MIN(priv_data.total_len, len + 1);
5118 if (copy_to_user(priv_data.buf, &extra, len)) {
Srinivas Girigowda100eb322013-03-15 16:48:20 -07005119 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5120 "%s: failed to copy data to user buffer", __func__);
5121 ret = -EFAULT;
5122 goto exit;
5123 }
5124 }
Gopichand Nakkala227c7f32013-06-26 22:44:57 +05305125#ifdef WLAN_FEATURE_PACKET_FILTERING
5126 else if (strncmp(command, "ENABLE_PKTFILTER_IPV6", 21) == 0)
5127 {
5128 tANI_U8 filterType = 0;
5129 tANI_U8 *value = command;
5130
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05305131 ret = hdd_drv_cmd_validate(command, 21);
5132 if (ret)
5133 goto exit;
5134
Gopichand Nakkala227c7f32013-06-26 22:44:57 +05305135 /* Move pointer to ahead of ENABLE_PKTFILTER_IPV6<delimiter> */
5136 value = value + 22;
5137
5138 /* Convert the value from ascii to integer */
5139 ret = kstrtou8(value, 10, &filterType);
5140 if (ret < 0)
5141 {
5142 /* If the input value is greater than max value of datatype,
5143 * then also kstrtou8 fails
5144 */
5145 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5146 "%s: kstrtou8 failed range ", __func__);
5147 ret = -EINVAL;
5148 goto exit;
5149 }
5150
5151 if (filterType != 0 && filterType != 1)
5152 {
5153 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5154 "%s: Accepted Values are 0 and 1 ", __func__);
5155 ret = -EINVAL;
5156 goto exit;
5157 }
5158 wlan_hdd_setIPv6Filter(WLAN_HDD_GET_CTX(pAdapter), filterType,
5159 pAdapter->sessionId);
5160 }
5161#endif
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05305162 else if (strncmp(command, "BTCOEXMODE", 10) == 0 )
5163 {
Kiet Lamad161252014-07-22 11:23:32 -07005164 char *dhcpPhase;
Satyanarayana Dash1faea4f2014-09-22 16:21:04 +05305165 int ret;
5166
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05305167 ret = hdd_drv_cmd_validate(command, 10);
5168 if (ret)
5169 goto exit;
5170
Kiet Lamad161252014-07-22 11:23:32 -07005171 dhcpPhase = command + 11;
5172 if ('1' == *dhcpPhase)
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05305173 {
Deepthi Gowribfd17132014-11-14 17:59:04 +05305174 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Kiet Lamad161252014-07-22 11:23:32 -07005175 FL("send DHCP START indication"));
c_hpothu9b781ba2013-12-30 20:57:45 +05305176
5177 pHddCtx->btCoexModeSet = TRUE;
Kiet Lamad161252014-07-22 11:23:32 -07005178
Satyanarayana Dash1faea4f2014-09-22 16:21:04 +05305179 ret = wlan_hdd_scan_abort(pAdapter);
5180 if (ret < 0)
5181 {
5182 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5183 FL("failed to abort existing scan %d"), ret);
5184 }
5185
Kiet Lamad161252014-07-22 11:23:32 -07005186 sme_DHCPStartInd(pHddCtx->hHal, pAdapter->device_mode,
5187 pAdapter->sessionId);
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05305188 }
Kiet Lamad161252014-07-22 11:23:32 -07005189 else if ('2' == *dhcpPhase)
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05305190 {
Deepthi Gowribfd17132014-11-14 17:59:04 +05305191 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Kiet Lamad161252014-07-22 11:23:32 -07005192 FL("send DHCP STOP indication"));
c_hpothu9b781ba2013-12-30 20:57:45 +05305193
5194 pHddCtx->btCoexModeSet = FALSE;
Kiet Lamad161252014-07-22 11:23:32 -07005195
5196 sme_DHCPStopInd(pHddCtx->hHal, pAdapter->device_mode,
5197 pAdapter->sessionId);
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05305198 }
5199 }
Jeff Johnsonf54df2c2013-07-24 11:43:39 -07005200 else if (strncmp(command, "SCAN-ACTIVE", 11) == 0)
5201 {
Abhishek Singh58749d62016-02-03 15:27:20 +05305202 hddLog(LOG1,
5203 FL("making default scan to ACTIVE"));
c_hpothudbefd3e2014-04-28 15:59:47 +05305204 pHddCtx->scan_info.scan_mode = eSIR_ACTIVE_SCAN;
Jeff Johnsonf54df2c2013-07-24 11:43:39 -07005205 }
5206 else if (strncmp(command, "SCAN-PASSIVE", 12) == 0)
5207 {
Abhishek Singh58749d62016-02-03 15:27:20 +05305208 hddLog(LOG1,
5209 FL("making default scan to PASSIVE"));
c_hpothudbefd3e2014-04-28 15:59:47 +05305210 pHddCtx->scan_info.scan_mode = eSIR_PASSIVE_SCAN;
Jeff Johnsonf54df2c2013-07-24 11:43:39 -07005211 }
Hanumantha Reddy Pothula212243c2013-08-01 17:28:31 +05305212 else if (strncmp(command, "GETDWELLTIME", 12) == 0)
5213 {
5214 hdd_config_t *pCfg = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
5215 char extra[32];
5216 tANI_U8 len = 0;
5217
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05305218 memset(extra, 0, sizeof(extra));
5219 ret = hdd_get_dwell_time(pCfg, command, extra, sizeof(extra), &len);
Ratnam Rachuri12d5d462015-08-07 14:10:23 +05305220 len = VOS_MIN(priv_data.total_len, len + 1);
5221 if (ret != 0 || copy_to_user(priv_data.buf, &extra, len)) {
Hanumantha Reddy Pothula212243c2013-08-01 17:28:31 +05305222 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5223 "%s: failed to copy data to user buffer", __func__);
5224 ret = -EFAULT;
5225 goto exit;
5226 }
5227 ret = len;
5228 }
5229 else if (strncmp(command, "SETDWELLTIME", 12) == 0)
5230 {
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05305231 ret = hdd_set_dwell_time(pAdapter, command);
Hanumantha Reddy Pothula212243c2013-08-01 17:28:31 +05305232 }
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07005233 else if ( strncasecmp(command, "MIRACAST", 8) == 0 )
5234 {
5235 tANI_U8 filterType = 0;
5236 tANI_U8 *value;
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05305237
5238 ret = hdd_drv_cmd_validate(command, 8);
5239 if (ret)
5240 goto exit;
5241
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07005242 value = command + 9;
5243
5244 /* Convert the value from ascii to integer */
5245 ret = kstrtou8(value, 10, &filterType);
5246 if (ret < 0)
5247 {
5248 /* If the input value is greater than max value of datatype,
5249 * then also kstrtou8 fails
5250 */
5251 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5252 "%s: kstrtou8 failed range ", __func__);
5253 ret = -EINVAL;
5254 goto exit;
5255 }
5256 if ((filterType < WLAN_HDD_DRIVER_MIRACAST_CFG_MIN_VAL ) ||
5257 (filterType > WLAN_HDD_DRIVER_MIRACAST_CFG_MAX_VAL))
5258 {
5259 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5260 "%s: Accepted Values are 0 to 2. 0-Disabled, 1-Source,"
5261 " 2-Sink ", __func__);
5262 ret = -EINVAL;
5263 goto exit;
5264 }
5265 //Filtertype value should be either 0-Disabled, 1-Source, 2-sink
5266 pHddCtx->drvr_miracast = filterType;
Kaushik, Sushant96122442014-10-21 16:40:18 +05305267 pScanInfo = &pHddCtx->scan_info;
5268 if (filterType && pScanInfo != NULL &&
5269 pHddCtx->scan_info.mScanPending)
5270 {
5271 /*Miracast Session started. Abort Scan */
5272 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
5273 "%s, Aborting Scan For Miracast",__func__);
5274 hdd_abort_mac_scan(pHddCtx, pScanInfo->sessionId,
5275 eCSR_SCAN_ABORT_DEFAULT);
5276 }
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07005277 hdd_tx_rx_pkt_cnt_stat_timer_handler(pHddCtx);
Ganesh Kondabattini8f6e3b32014-08-25 16:07:54 +05305278 sme_SetMiracastMode(pHddCtx->hHal, pHddCtx->drvr_miracast);
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07005279 }
Leo Chang614d2072013-08-22 14:59:44 -07005280 else if (strncmp(command, "SETMCRATE", 9) == 0)
5281 {
Leo Chang614d2072013-08-22 14:59:44 -07005282 tANI_U8 *value = command;
5283 int targetRate;
Leo Chang1f98cbd2013-10-17 15:03:52 -07005284 tSirRateUpdateInd *rateUpdate;
5285 eHalStatus status;
Leo Chang614d2072013-08-22 14:59:44 -07005286
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05305287 ret = hdd_drv_cmd_validate(command, 9);
5288 if (ret)
5289 goto exit;
5290
Leo Chang614d2072013-08-22 14:59:44 -07005291 /* Only valid for SAP mode */
5292 if (WLAN_HDD_SOFTAP != pAdapter->device_mode)
5293 {
5294 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5295 "%s: SAP mode is not running", __func__);
5296 ret = -EFAULT;
5297 goto exit;
5298 }
5299
5300 /* Move pointer to ahead of SETMCRATE<delimiter> */
5301 /* input value is in units of hundred kbps */
5302 value = value + 10;
5303 /* Convert the value from ascii to integer, decimal base */
5304 ret = kstrtouint(value, 10, &targetRate);
5305
Leo Chang1f98cbd2013-10-17 15:03:52 -07005306 rateUpdate = (tSirRateUpdateInd *)vos_mem_malloc(sizeof(tSirRateUpdateInd));
5307 if (NULL == rateUpdate)
Leo Chang614d2072013-08-22 14:59:44 -07005308 {
Leo Chang1f98cbd2013-10-17 15:03:52 -07005309 hddLog(VOS_TRACE_LEVEL_ERROR,
5310 "%s: SETMCRATE indication alloc fail", __func__);
5311 ret = -EFAULT;
5312 goto exit;
5313 }
5314 vos_mem_zero(rateUpdate, sizeof(tSirRateUpdateInd ));
5315
5316 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
5317 "MC Target rate %d", targetRate);
5318 /* Ignore unicast */
5319 rateUpdate->ucastDataRate = -1;
5320 rateUpdate->mcastDataRate24GHz = targetRate;
5321 rateUpdate->mcastDataRate5GHz = targetRate;
5322 rateUpdate->mcastDataRate24GHzTxFlag = 0;
5323 rateUpdate->mcastDataRate5GHzTxFlag = 0;
5324 status = sme_SendRateUpdateInd(pHddCtx->hHal, rateUpdate);
5325 if (eHAL_STATUS_SUCCESS != status)
5326 {
5327 hddLog(VOS_TRACE_LEVEL_ERROR,
5328 "%s: SET_MC_RATE failed", __func__);
5329 vos_mem_free(rateUpdate);
5330 ret = -EFAULT;
5331 goto exit;
Leo Chang614d2072013-08-22 14:59:44 -07005332 }
5333 }
jge35567202017-06-21 16:39:38 +08005334 else if (strncmp(command, "MAXTXPOWER", 10) == 0)
5335 {
5336 int status;
5337 int txPower;
5338 eHalStatus smeStatus;
5339 tANI_U8 *value = command;
5340 tSirMacAddr bssid = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
5341 tSirMacAddr selfMac = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
5342
5343 status = hdd_parse_setmaxtxpower_command(value, &txPower);
5344 if (status)
5345 {
5346 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5347 "Invalid MAXTXPOWER command ");
5348 ret = -EINVAL;
5349 goto exit;
5350 }
5351
5352 hddLog(VOS_TRACE_LEVEL_INFO, "max tx power %d selfMac: "
5353 MAC_ADDRESS_STR " bssId: " MAC_ADDRESS_STR " ",
5354 txPower, MAC_ADDR_ARRAY(selfMac),
5355 MAC_ADDR_ARRAY(bssid));
5356 smeStatus = sme_SetMaxTxPower((tHalHandle)(pHddCtx->hHal),
5357 bssid, selfMac, txPower) ;
5358 if( smeStatus != eHAL_STATUS_SUCCESS )
5359 {
5360 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:Set max tx power failed",
5361 __func__);
5362 ret = -EINVAL;
5363 goto exit;
5364 }
5365
5366 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Set max tx power success",
5367 __func__);
5368 }
Rajeev79dbe4c2013-10-05 11:03:42 +05305369#ifdef FEATURE_WLAN_BATCH_SCAN
Rajeev Kumar8b373292014-01-08 20:36:55 -08005370 else if (strncmp(command, "WLS_BATCHING", 12) == 0)
Rajeev79dbe4c2013-10-05 11:03:42 +05305371 {
Rajeev Kumar8b373292014-01-08 20:36:55 -08005372 ret = hdd_handle_batch_scan_ioctl(pAdapter, &priv_data, command);
Rajeev79dbe4c2013-10-05 11:03:42 +05305373 }
5374#endif
Abhishek Singh00b71972016-01-07 10:51:04 +05305375#ifdef WLAN_FEATURE_RMC
5376 else if ((strncasecmp(command, "SETIBSSBEACONOUIDATA", 20) == 0) &&
5377 (WLAN_HDD_IBSS == pAdapter->device_mode))
5378 {
5379 int i = 0;
5380 tANI_U8 *ibss_ie;
5381 tANI_U32 command_len;
5382 tANI_U8 *value = command;
5383 tHalHandle hHal = pHddCtx->hHal;
5384 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
5385 tANI_U32 ibss_ie_length;
5386 tANI_U32 len, present;
5387 tANI_U8 *addIE;
5388 tANI_U8 *addIEData;
5389
5390 hddLog(LOG1,
5391 FL(" received command %s"),((char *) value));
5392 /* validate argument of command */
5393 if (strlen(value) <= 21)
5394 {
5395 hddLog(LOGE,
5396 FL("No arguements in command length %zu"), strlen(value));
5397 ret = -EFAULT;
5398 goto exit;
5399 }
5400
5401 /* moving to arguments of commands */
5402 value = value + 21;
5403 command_len = strlen(value);
5404
5405 /* oui_data can't be less than 3 bytes */
5406 if (command_len <= (2 * WLAN_HDD_IBSS_MIN_OUI_DATA_LENGTH))
5407 {
5408 hddLog(LOGE,
5409 FL("Invalid SETIBSSBEACONOUIDATA command length %d"),
5410 command_len);
5411 ret = -EFAULT;
5412 goto exit;
5413 }
5414 ibss_ie = vos_mem_malloc(command_len);
5415 if (!ibss_ie) {
5416 hddLog(LOGE,
5417 FL("Could not allocate memory for command length %d"),
5418 command_len);
5419 ret = -ENOMEM;
5420 goto exit;
5421 }
5422 vos_mem_zero(ibss_ie, command_len);
5423
5424 ibss_ie_length = hdd_parse_set_ibss_oui_data_command(value, ibss_ie,
5425 command_len);
5426 if (ibss_ie_length < (2 * WLAN_HDD_IBSS_MIN_OUI_DATA_LENGTH)) {
5427 hddLog(LOGE, FL("Could not parse command %s return length %d"),
5428 value, ibss_ie_length);
5429 ret = -EFAULT;
5430 vos_mem_free(ibss_ie);
5431 goto exit;
5432 }
5433
5434 hddLog(LOG1, FL("ibss_ie length %d ibss_ie:"), ibss_ie_length);
5435 while (i < ibss_ie_length)
5436 hddLog(LOG1, FL("0x%x"), ibss_ie[i++]);
5437
5438 /* Populate Vendor IE in Beacon */
5439 if ((ccmCfgGetInt(hHal,
5440 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG,
5441 &present)) != eHAL_STATUS_SUCCESS)
5442 {
5443 hddLog(LOGE,
5444 FL("unable to ftch WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG"));
5445 ret = -EFAULT;
5446 vos_mem_free(ibss_ie);
5447 goto exit;
5448 }
5449
5450 addIE = vos_mem_malloc(WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA_LEN);
5451 if (!addIE) {
5452 hddLog(LOGE,
5453 FL("Could not allocate memory for command length %d"),
5454 command_len);
5455 vos_mem_free(ibss_ie);
5456 ret = -ENOMEM;
5457 goto exit;
5458 }
5459 vos_mem_zero(addIE, WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA_LEN);
5460
5461 if (present)
5462 {
5463 if ((wlan_cfgGetStrLen(pMac,
5464 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, &len)) != eSIR_SUCCESS)
5465 {
5466 hddLog(LOGE,
5467 FL("unable to fetch WNI_CFG_PROBE_RSP_BCN_ADDNIE_LEN"));
5468 ret = -EFAULT;
5469 vos_mem_free(ibss_ie);
5470 vos_mem_free(addIE);
5471 goto exit;
5472 }
5473
5474 if (len <= WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA_LEN && len &&
5475 ((len + ibss_ie_length) <=
5476 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA_LEN))
5477 {
5478 if ((ccmCfgGetStr(hHal,
5479 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, addIE, &len))
5480 != eHAL_STATUS_SUCCESS)
5481 {
5482 hddLog(LOGE,
5483 FL("unable to fetch WNI_PROBE_RSP_BCN_ADDNIE_DATA"));
5484 ret = -EFAULT;
5485 vos_mem_free(ibss_ie);
5486 vos_mem_free(addIE);
5487 goto exit;
5488 }
5489 else
5490 {
5491 /* Curruntly only WPA IE is added before Vendor IE
5492 * so we can blindly place the Vendor IE after WPA
5493 * IE. If no WPA IE found replace all with Vendor IE.
5494 */
5495 len = hdd_find_ibss_wpa_ie_pos(addIE, len);
5496 }
5497 }
5498 else
5499 {
5500 hddLog(LOGE,
5501 FL("IE len exceed limit len %d,ibss_ie_length %d "),
5502 len, ibss_ie_length);
5503 ret = -EFAULT;
5504 vos_mem_free(addIE);
5505 vos_mem_free(ibss_ie);
5506 goto exit;
5507 }
5508 }
5509 else {
5510 len = 0;
5511 }
5512
5513 vos_mem_copy (addIE + len , ibss_ie, ibss_ie_length);
5514 len += ibss_ie_length;
5515
5516 if (ccmCfgSetStr(hHal,
5517 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, addIE, len, NULL,
5518 eANI_BOOLEAN_FALSE) != eHAL_STATUS_SUCCESS)
5519 {
5520 hddLog(LOGE,
5521 FL("unable to set WNI_CFG_PRBE_RSP_BCN_ADDNIE_DATA"));
5522 ret = -EFAULT;
5523 vos_mem_free(ibss_ie);
5524 vos_mem_free(addIE);
5525 goto exit;
5526 }
5527 vos_mem_free(addIE);
5528 if (ccmCfgSetInt(hHal,
5529 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 1,NULL,
5530 eANI_BOOLEAN_FALSE) != eHAL_STATUS_SUCCESS)
5531 {
5532 hddLog(LOGE,
5533 FL("unble to set WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG"));
5534 ret = -EFAULT;
5535 vos_mem_free(ibss_ie);
5536 goto exit;
5537 }
5538
5539 /* Populate Vendor IE in probe resp */
5540 if ((ccmCfgGetInt(hHal,
5541 WNI_CFG_PROBE_RSP_ADDNIE_FLAG,
5542 &present)) != eHAL_STATUS_SUCCESS)
5543 {
5544 hddLog(LOGE,
5545 FL("unable to fetch WNI_CFG_PROBE_RSP_ADDNIE_FLAG"));
5546 ret = -EFAULT;
5547 vos_mem_free(ibss_ie);
5548 goto exit;
5549 }
5550
5551 addIEData = vos_mem_malloc(WNI_CFG_PROBE_RSP_ADDNIE_DATA1_LEN);
5552 if (!addIEData) {
5553 hddLog(LOGE,
5554 FL("Could not allocate memory for command length %d"),
5555 command_len);
5556 vos_mem_free(ibss_ie);
5557 ret = -ENOMEM;
5558 goto exit;
5559 }
5560 vos_mem_zero(addIEData, WNI_CFG_PROBE_RSP_ADDNIE_DATA1_LEN);
5561
5562 if (present) {
5563 if (eSIR_SUCCESS != wlan_cfgGetStrLen(pMac,
5564 WNI_CFG_PROBE_RSP_ADDNIE_DATA1, &len)) {
5565 hddLog(LOGE,
5566 FL("unable to fetch WNI_CFG_PROBE_RSP_ADDNIE_DATA1"));
5567 ret = -EFAULT;
5568 vos_mem_free(ibss_ie);
5569 vos_mem_free(addIEData);
5570 goto exit;
5571 }
5572 if (len < WNI_CFG_PROBE_RSP_ADDNIE_DATA1_LEN && len &&
5573 (ibss_ie_length + len) <=
5574 WNI_CFG_PROBE_RSP_ADDNIE_DATA1_LEN) {
5575
5576 if ((ccmCfgGetStr(hHal,
5577 WNI_CFG_PROBE_RSP_ADDNIE_DATA1, addIEData, &len))
5578 != eHAL_STATUS_SUCCESS) {
5579 hddLog(LOGE,
5580 FL("unable fetch WNI_CFG_PROBE_RSP_ADDNIE_DATA1"));
5581 ret = -EFAULT;
5582 vos_mem_free(ibss_ie);
5583 vos_mem_free(addIEData);
5584 goto exit;
5585 }
5586 else {
5587 /* Curruntly only WPA IE is added before Vendor IE
5588 * so we can blindly place the Vendor IE after WPA
5589 * IE. If no WPA IE found replace all with Vendor IE.
5590 */
5591 len = hdd_find_ibss_wpa_ie_pos(addIEData, len);
5592 }
5593 }
5594 else
5595 {
5596 hddLog(LOGE,
5597 FL("IE len exceed limit len %d,ibss_ie_length %d "),
5598 len, ibss_ie_length);
5599 ret = -EFAULT;
5600 vos_mem_free(addIEData);
5601 vos_mem_free(ibss_ie);
5602 goto exit;
5603 }
5604 } /* probe rsp ADD IE present */
5605 else {
5606 /* probe rsp add IE is not present */
5607 len = 0;
5608 }
5609
5610 vos_mem_copy(addIEData +len , ibss_ie, ibss_ie_length);
5611 len += ibss_ie_length;
5612
5613 vos_mem_free(ibss_ie);
5614
5615 if (ccmCfgSetStr(hHal,
5616 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,
5617 (tANI_U8*)(addIEData),
5618 len, NULL,
5619 eANI_BOOLEAN_FALSE)
5620 == eHAL_STATUS_FAILURE) {
5621 hddLog(LOGE,
5622 FL("unable to copy to WNI_CFG_PROBE_RSP_ADDNIE_DATA1"));
5623 ret = -EFAULT;
5624 vos_mem_free(addIEData);
5625 goto exit;
5626 }
5627 vos_mem_free(addIEData);
5628 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
5629 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 1,NULL,
5630 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
5631 {
5632 hddLog(LOGE,
5633 FL("unable to copy WNI_CFG_PROBE_RSP_ADDNIE_FLAG"));
5634 ret = -EFAULT;
5635 goto exit;
5636 }
5637 }
5638 else if (strncasecmp(command, "SETRMCENABLE", 12) == 0)
5639 {
5640 tANI_U8 *value = command;
5641 tANI_U8 ucRmcEnable = 0;
5642 int status;
5643
5644 if ((WLAN_HDD_IBSS != pAdapter->device_mode) &&
5645 (WLAN_HDD_SOFTAP != pAdapter->device_mode))
5646 {
5647 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5648 "Received SETRMCENABLE command in invalid mode %d "
5649 "SETRMCENABLE command is only allowed in IBSS or SOFTAP mode",
5650 pAdapter->device_mode);
5651 ret = -EINVAL;
5652 goto exit;
5653 }
5654
5655 status = hdd_parse_setrmcenable_command(value, &ucRmcEnable);
5656 if (status)
5657 {
5658 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5659 "Invalid SETRMCENABLE command ");
5660 ret = -EINVAL;
5661 goto exit;
5662 }
5663
5664 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
5665 "%s: ucRmcEnable %d ", __func__, ucRmcEnable);
5666
5667 if (TRUE == ucRmcEnable)
5668 {
5669 status = sme_EnableRMC( (tHalHandle)(pHddCtx->hHal),
5670 pAdapter->sessionId );
5671 }
5672 else if(FALSE == ucRmcEnable)
5673 {
5674 status = sme_DisableRMC( (tHalHandle)(pHddCtx->hHal),
5675 pAdapter->sessionId );
5676 }
5677 else
5678 {
5679 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5680 "Invalid SETRMCENABLE command %d", ucRmcEnable);
5681 ret = -EINVAL;
5682 goto exit;
5683 }
5684
5685 if (VOS_STATUS_SUCCESS != status)
5686 {
5687 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5688 "%s: SETRMC %d failed status %d", __func__, ucRmcEnable,
5689 status);
5690 ret = -EINVAL;
5691 goto exit;
5692 }
5693 }
5694 else if (strncasecmp(command, "SETRMCACTIONPERIOD", 18) == 0)
5695 {
5696 tANI_U8 *value = command;
5697 tANI_U32 uActionPeriod = 0;
5698 int status;
5699
5700 if ((WLAN_HDD_IBSS != pAdapter->device_mode) &&
5701 (WLAN_HDD_SOFTAP != pAdapter->device_mode))
5702 {
5703 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5704 "Received SETRMC command in invalid mode %d "
5705 "SETRMC command is only allowed in IBSS or SOFTAP mode",
5706 pAdapter->device_mode);
5707 ret = -EINVAL;
5708 goto exit;
5709 }
5710
5711 status = hdd_parse_setrmcactionperiod_command(value, &uActionPeriod);
5712 if (status)
5713 {
5714 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5715 "Invalid SETRMCACTIONPERIOD command ");
5716 ret = -EINVAL;
5717 goto exit;
5718 }
5719
5720 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
5721 "%s: uActionPeriod %d ", __func__, uActionPeriod);
5722
5723 if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_RMC_ACTION_PERIOD_FREQUENCY,
5724 uActionPeriod, NULL, eANI_BOOLEAN_FALSE))
5725 {
5726 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5727 "%s: Could not set SETRMCACTIONPERIOD %d", __func__, uActionPeriod);
5728 ret = -EINVAL;
5729 goto exit;
5730 }
5731
5732 }
5733 else if (strncasecmp(command, "GETIBSSPEERINFOALL", 18) == 0)
5734 {
5735 /* Peer Info All Command */
5736 int status = eHAL_STATUS_SUCCESS;
5737 hdd_station_ctx_t *pHddStaCtx = NULL;
5738 char *extra = NULL;
5739 int idx = 0, length = 0;
5740 v_MACADDR_t *macAddr;
5741 v_U32_t txRateMbps = 0, numOfBytestoPrint = 0;
5742
5743 if (WLAN_HDD_IBSS == pAdapter->device_mode)
5744 {
5745 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
5746 }
5747 else
5748 {
5749 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
5750 "%s: pAdapter is not valid for this device mode",
5751 __func__);
5752 ret = -EINVAL;
5753 goto exit;
5754 }
5755
5756 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
5757 "%s: Received GETIBSSPEERINFOALL Command", __func__);
5758
5759
5760 /* Handle the command */
5761 status = hdd_cfg80211_get_ibss_peer_info_all(pAdapter);
5762 if (VOS_STATUS_SUCCESS == status)
5763 {
5764 /* The variable extra needed to be allocated on the heap since
5765 * amount of memory required to copy the data for 32 devices
5766 * exceeds the size of 1024 bytes of default stack size. On
5767 * 64 bit devices, the default max stack size of 2048 bytes
5768 */
5769 extra = kmalloc(WLAN_MAX_BUF_SIZE, GFP_KERNEL);
5770
5771 if (NULL == extra)
5772 {
5773 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5774 "%s:kmalloc failed", __func__);
5775 ret = -EINVAL;
5776 goto exit;
5777 }
5778
5779 /* Copy number of stations */
5780 length = scnprintf( extra, WLAN_MAX_BUF_SIZE, "%d ",
5781 pHddStaCtx->ibss_peer_info.numIBSSPeers);
5782 numOfBytestoPrint = length;
5783 for (idx = 0; idx < pHddStaCtx->ibss_peer_info.numIBSSPeers; idx++)
5784 {
5785 macAddr =
5786 hdd_wlan_get_ibss_mac_addr_from_staid(pAdapter,
5787 pHddStaCtx->ibss_peer_info.ibssPeerList[idx].staIdx);
5788 if (NULL != macAddr)
5789 {
5790 txRateMbps =
5791 ((pHddStaCtx->ibss_peer_info.ibssPeerList[idx].txRate)*500*1000)/1000000;
5792
5793 length += scnprintf( (extra + length), WLAN_MAX_BUF_SIZE - length,
5794 "%02x:%02x:%02x:%02x:%02x:%02x %d %d ",
5795 macAddr->bytes[0], macAddr->bytes[1], macAddr->bytes[2],
5796 macAddr->bytes[3], macAddr->bytes[4], macAddr->bytes[5],
5797 (int)txRateMbps,
5798 (int)pHddStaCtx->ibss_peer_info.ibssPeerList[idx].rssi);
5799 }
5800 else
5801 {
5802 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5803 "%s: MAC ADDR is NULL for staIdx: %d", __func__,
5804 pHddStaCtx->ibss_peer_info.ibssPeerList[idx].staIdx);
5805 }
5806
5807 /*
5808 * VOS_TRACE() macro has limitation of 512 bytes for the print
5809 * buffer. Hence printing the data in two chunks. The first chunk
5810 * will have the data for 16 devices and the second chunk will
5811 * have the rest.
5812 */
5813 if (idx < NUM_OF_STA_DATA_TO_PRINT)
5814 {
5815 numOfBytestoPrint = length;
5816 }
5817 }
5818
5819 /*
5820 * Copy the data back into buffer, if the data to copy is
5821 * morethan 512 bytes than we will split the data and do
5822 * it in two shots
5823 */
5824 if (copy_to_user(priv_data.buf, extra, numOfBytestoPrint))
5825 {
5826 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5827 "%s: Copy into user data buffer failed ", __func__);
5828 ret = -EFAULT;
5829 kfree(extra);
5830 goto exit;
5831 }
5832 priv_data.buf[numOfBytestoPrint] = '\0';
5833 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_MED,
5834 "%s", priv_data.buf);
5835
5836 if (length > numOfBytestoPrint)
5837 {
5838 if (copy_to_user(priv_data.buf + numOfBytestoPrint,
5839 extra + numOfBytestoPrint,
5840 length - numOfBytestoPrint + 1))
5841 {
5842 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5843 "%s: Copy into user data buffer failed ", __func__);
5844 ret = -EFAULT;
5845 kfree(extra);
5846 goto exit;
5847 }
5848 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_MED,
5849 "%s", &priv_data.buf[numOfBytestoPrint]);
5850 }
5851
5852 /* Free temporary buffer */
5853 kfree(extra);
5854 }
5855
5856 else
5857 {
5858 /* Command failed, log error */
5859 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5860 "%s: GETIBSSPEERINFOALL command failed with status code %d",
5861 __func__, status);
5862 ret = -EINVAL;
5863 goto exit;
5864 }
5865 ret = 0;
5866 }
5867 else if(strncasecmp(command, "GETIBSSPEERINFO", 15) == 0)
5868 {
5869 /* Peer Info <Peer Addr> command */
5870 tANI_U8 *value = command;
5871 VOS_STATUS status;
5872 hdd_station_ctx_t *pHddStaCtx = NULL;
5873 char extra[128] = { 0 };
5874 v_U32_t length = 0;
5875 v_U8_t staIdx = 0;
5876 v_U32_t txRateMbps = 0;
5877 v_MACADDR_t peerMacAddr;
5878
5879 if (WLAN_HDD_IBSS == pAdapter->device_mode)
5880 {
5881 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
5882 }
5883 else
5884 {
5885 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
5886 "%s: pAdapter is not valid for this device mode",
5887 __func__);
5888 ret = -EINVAL;
5889 goto exit;
5890 }
5891
5892 /* if there are no peers, no need to continue with the command */
5893 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
5894 "%s: Received GETIBSSPEERINFO Command", __func__);
5895
5896 if (eConnectionState_IbssConnected != pHddStaCtx->conn_info.connState)
5897 {
5898 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
5899 "%s:No IBSS Peers coalesced", __func__);
5900 ret = -EINVAL;
5901 goto exit;
5902 }
5903
5904 /* Parse the incoming command buffer */
5905 status = hdd_parse_get_ibss_peer_info(value, &peerMacAddr);
5906 if (VOS_STATUS_SUCCESS != status)
5907 {
5908 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5909 "%s: Invalid GETIBSSPEERINFO command", __func__);
5910 ret = -EINVAL;
5911 goto exit;
5912 }
5913
5914 /* Get station index for the peer mac address */
5915 hdd_Ibss_GetStaId(pHddStaCtx, &peerMacAddr, &staIdx);
5916
5917 if (staIdx > HDD_MAX_NUM_IBSS_STA)
5918 {
5919 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5920 "%s: Invalid StaIdx %d returned", __func__, staIdx);
5921 ret = -EINVAL;
5922 goto exit;
5923 }
5924
5925 /* Handle the command */
5926 status = hdd_cfg80211_get_ibss_peer_info(pAdapter, staIdx);
5927 if (VOS_STATUS_SUCCESS == status)
5928 {
5929 v_U32_t txRate = pHddStaCtx->ibss_peer_info.ibssPeerList[0].txRate;
5930 txRateMbps = (txRate * 500 * 1000)/1000000;
5931
5932 length = scnprintf( extra, sizeof(extra), "%d %d", (int)txRateMbps,
5933 (int)pHddStaCtx->ibss_peer_info.ibssPeerList[0].rssi);
5934
5935 /* Copy the data back into buffer */
5936 if (copy_to_user(priv_data.buf, &extra, length+ 1))
5937 {
5938 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5939 "%s: copy data to user buffer failed GETIBSSPEERINFO command",
5940 __func__);
5941 ret = -EFAULT;
5942 goto exit;
5943 }
5944 }
5945 else
5946 {
5947 /* Command failed, log error */
5948 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5949 "%s: GETIBSSPEERINFO command failed with status code %d",
5950 __func__, status);
5951 ret = -EINVAL;
5952 goto exit;
5953 }
5954
5955 /* Success ! */
5956 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_MED,
5957 "%s", priv_data.buf);
5958 ret = 0;
5959 }
5960 else if (strncasecmp(command, "SETRMCTXRATE", 12) == 0)
5961 {
5962 tANI_U8 *value = command;
5963 tANI_U32 uRate = 0;
5964 tTxrateinfoflags txFlags = 0;
5965 tSirRateUpdateInd *rateUpdateParams;
5966 int status;
5967
5968 if ((WLAN_HDD_IBSS != pAdapter->device_mode) &&
5969 (WLAN_HDD_SOFTAP != pAdapter->device_mode))
5970 {
5971 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5972 "Received SETRMCTXRATE command in invalid mode %d "
5973 "SETRMC command is only allowed in IBSS or SOFTAP mode",
5974 pAdapter->device_mode);
5975 ret = -EINVAL;
5976 goto exit;
5977 }
5978
5979 status = hdd_parse_setrmcrate_command(value, &uRate, &txFlags);
5980 if (status)
5981 {
5982 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5983 "Invalid SETRMCTXRATE command ");
5984 ret = -EINVAL;
5985 goto exit;
5986 }
5987
5988 rateUpdateParams = vos_mem_malloc(sizeof(tSirRateUpdateInd));
5989 if (NULL == rateUpdateParams)
5990 {
5991 ret = -EINVAL;
5992 goto exit;
5993 }
5994
5995 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
5996 "%s: uRate %d ", __func__, uRate);
5997
5998 vos_mem_zero(rateUpdateParams, sizeof(tSirRateUpdateInd ));
5999
6000 /* -1 implies ignore this param */
6001 rateUpdateParams->ucastDataRate = -1;
6002
6003 /*
6004 * Fill the user specifieed RMC rate param
6005 * and the derived tx flags.
6006 */
6007 rateUpdateParams->rmcDataRate = uRate;
6008 rateUpdateParams->rmcDataRateTxFlag = txFlags;
6009
6010 status = sme_SendRateUpdateInd((tHalHandle)(pHddCtx->hHal), rateUpdateParams);
6011 }
6012 else if (strncasecmp(command, "SETIBSSTXFAILEVENT", 18) == 0 )
6013 {
6014 char *value;
6015 tANI_U8 tx_fail_count = 0;
6016 tANI_U16 pid = 0;
6017
6018 value = command;
6019
6020 ret = hdd_ParseIBSSTXFailEventParams(value, &tx_fail_count, &pid);
6021
6022 if (0 != ret)
6023 {
6024 hddLog(VOS_TRACE_LEVEL_INFO,
6025 "%s: Failed to parse SETIBSSTXFAILEVENT arguments",
6026 __func__);
6027 goto exit;
6028 }
6029
6030 hddLog(VOS_TRACE_LEVEL_INFO, "%s: tx_fail_cnt=%hhu, pid=%hu",
6031 __func__, tx_fail_count, pid);
6032
6033 if (0 == tx_fail_count)
6034 {
6035 // Disable TX Fail Indication
6036 if (eHAL_STATUS_SUCCESS ==
6037 sme_TXFailMonitorStartStopInd(pHddCtx->hHal,
6038 tx_fail_count,
6039 NULL))
6040 {
6041 cesium_pid = 0;
6042 }
6043 else
6044 {
6045 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6046 "%s: failed to disable TX Fail Event ", __func__);
6047 ret = -EINVAL;
6048 }
6049 }
6050 else
6051 {
6052 if (eHAL_STATUS_SUCCESS ==
6053 sme_TXFailMonitorStartStopInd(pHddCtx->hHal,
6054 tx_fail_count,
6055 (void*)hdd_tx_fail_ind_callback))
6056 {
6057 cesium_pid = pid;
6058 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6059 "%s: Registered Cesium pid %u", __func__,
6060 cesium_pid);
6061 }
6062 else
6063 {
6064 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6065 "%s: Failed to enable TX Fail Monitoring", __func__);
6066 ret = -EINVAL;
6067 }
6068 }
6069 }
6070
6071#endif /* WLAN_FEATURE_RMC */
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08006072#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07006073 else if (strncmp(command, "SETCCXROAMSCANCHANNELS", 22) == 0)
6074 {
6075 tANI_U8 *value = command;
6076 tANI_U8 ChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
6077 tANI_U8 numChannels = 0;
6078 eHalStatus status = eHAL_STATUS_SUCCESS;
6079
6080 status = hdd_parse_channellist(value, ChannelList, &numChannels);
6081 if (eHAL_STATUS_SUCCESS != status)
6082 {
6083 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6084 "%s: Failed to parse channel list information", __func__);
6085 ret = -EINVAL;
6086 goto exit;
6087 }
6088
6089 if (numChannels > WNI_CFG_VALID_CHANNEL_LIST_LEN)
6090 {
6091 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6092 "%s: number of channels (%d) supported exceeded max (%d)", __func__,
6093 numChannels, WNI_CFG_VALID_CHANNEL_LIST_LEN);
6094 ret = -EINVAL;
6095 goto exit;
6096 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08006097 status = sme_SetEseRoamScanChannelList((tHalHandle)(pHddCtx->hHal),
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07006098 ChannelList,
6099 numChannels);
6100 if (eHAL_STATUS_SUCCESS != status)
6101 {
6102 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6103 "%s: Failed to update channel list information", __func__);
6104 ret = -EINVAL;
6105 goto exit;
6106 }
6107 }
6108 else if (strncmp(command, "GETTSMSTATS", 11) == 0)
6109 {
6110 tANI_U8 *value = command;
6111 char extra[128] = {0};
6112 int len = 0;
6113 tANI_U8 tid = 0;
6114 hdd_station_ctx_t *pHddStaCtx = NULL;
6115 tAniTrafStrmMetrics tsmMetrics;
6116 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
6117
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05306118 ret = hdd_drv_cmd_validate(command, 11);
6119 if (ret)
6120 goto exit;
6121
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07006122 /* if not associated, return error */
6123 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
6124 {
6125 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "%s:Not associated!",__func__);
6126 ret = -EINVAL;
6127 goto exit;
6128 }
6129
6130 /* Move pointer to ahead of GETTSMSTATS<delimiter> */
6131 value = value + 12;
6132 /* Convert the value from ascii to integer */
6133 ret = kstrtou8(value, 10, &tid);
6134 if (ret < 0)
6135 {
6136 /* If the input value is greater than max value of datatype, then also
6137 kstrtou8 fails */
6138 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6139 "%s: kstrtou8 failed range [%d - %d]", __func__,
6140 TID_MIN_VALUE,
6141 TID_MAX_VALUE);
6142 ret = -EINVAL;
6143 goto exit;
6144 }
6145
6146 if ((tid < TID_MIN_VALUE) || (tid > TID_MAX_VALUE))
6147 {
6148 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6149 "tid value %d is out of range"
6150 " (Min: %d Max: %d)", tid,
6151 TID_MIN_VALUE,
6152 TID_MAX_VALUE);
6153 ret = -EINVAL;
6154 goto exit;
6155 }
6156
6157 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6158 "%s: Received Command to get tsm stats tid = %d", __func__, tid);
6159
6160 if (VOS_STATUS_SUCCESS != hdd_get_tsm_stats(pAdapter, tid, &tsmMetrics))
6161 {
6162 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6163 "%s: failed to get tsm stats", __func__);
6164 ret = -EFAULT;
6165 goto exit;
6166 }
6167
6168 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6169 "UplinkPktQueueDly(%d)\n"
6170 "UplinkPktQueueDlyHist[0](%d)\n"
6171 "UplinkPktQueueDlyHist[1](%d)\n"
6172 "UplinkPktQueueDlyHist[2](%d)\n"
6173 "UplinkPktQueueDlyHist[3](%d)\n"
Arun Kumar Khandavallie8768212014-02-17 16:43:34 +05306174 "UplinkPktTxDly(%u)\n"
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07006175 "UplinkPktLoss(%d)\n"
6176 "UplinkPktCount(%d)\n"
6177 "RoamingCount(%d)\n"
6178 "RoamingDly(%d)", tsmMetrics.UplinkPktQueueDly,
6179 tsmMetrics.UplinkPktQueueDlyHist[0],
6180 tsmMetrics.UplinkPktQueueDlyHist[1],
6181 tsmMetrics.UplinkPktQueueDlyHist[2],
6182 tsmMetrics.UplinkPktQueueDlyHist[3],
6183 tsmMetrics.UplinkPktTxDly, tsmMetrics.UplinkPktLoss,
6184 tsmMetrics.UplinkPktCount, tsmMetrics.RoamingCount, tsmMetrics.RoamingDly);
6185
6186 /* Output TSM stats is of the format
6187 GETTSMSTATS [PktQueueDly] [PktQueueDlyHist[0]]:[PktQueueDlyHist[1]] ...[RoamingDly]
6188 eg., GETTSMSTATS 10 1:0:0:161 20 1 17 8 39800 */
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08006189 len = scnprintf(extra, sizeof(extra), "%s %d %d:%d:%d:%d %u %d %d %d %d", command,
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07006190 tsmMetrics.UplinkPktQueueDly, tsmMetrics.UplinkPktQueueDlyHist[0],
6191 tsmMetrics.UplinkPktQueueDlyHist[1], tsmMetrics.UplinkPktQueueDlyHist[2],
6192 tsmMetrics.UplinkPktQueueDlyHist[3], tsmMetrics.UplinkPktTxDly,
6193 tsmMetrics.UplinkPktLoss, tsmMetrics.UplinkPktCount, tsmMetrics.RoamingCount,
6194 tsmMetrics.RoamingDly);
6195
Ratnam Rachurid53009c2015-08-07 13:59:00 +05306196 len = VOS_MIN(priv_data.total_len, len + 1);
6197 if (copy_to_user(priv_data.buf, &extra, len)) {
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07006198 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6199 "%s: failed to copy data to user buffer", __func__);
6200 ret = -EFAULT;
6201 goto exit;
6202 }
6203 }
6204 else if (strncmp(command, "SETCCKMIE", 9) == 0)
6205 {
6206 tANI_U8 *value = command;
6207 tANI_U8 *cckmIe = NULL;
6208 tANI_U8 cckmIeLen = 0;
6209 eHalStatus status = eHAL_STATUS_SUCCESS;
6210
6211 status = hdd_parse_get_cckm_ie(value, &cckmIe, &cckmIeLen);
6212 if (eHAL_STATUS_SUCCESS != status)
6213 {
6214 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6215 "%s: Failed to parse cckm ie data", __func__);
6216 ret = -EINVAL;
6217 goto exit;
6218 }
6219
6220 if (cckmIeLen > DOT11F_IE_RSN_MAX_LEN)
6221 {
6222 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6223 "%s: CCKM Ie input length is more than max[%d]", __func__,
6224 DOT11F_IE_RSN_MAX_LEN);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08006225 vos_mem_free(cckmIe);
6226 cckmIe = NULL;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07006227 ret = -EINVAL;
6228 goto exit;
6229 }
6230 sme_SetCCKMIe((tHalHandle)(pHddCtx->hHal), pAdapter->sessionId, cckmIe, cckmIeLen);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08006231 vos_mem_free(cckmIe);
6232 cckmIe = NULL;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07006233 }
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08006234 else if (strncmp(command, "CCXBEACONREQ", 12) == 0)
6235 {
6236 tANI_U8 *value = command;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08006237 tCsrEseBeaconReq eseBcnReq;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08006238 eHalStatus status = eHAL_STATUS_SUCCESS;
Srinivas Girigowda0c6d7fe2014-05-28 18:18:10 -07006239
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08006240 status = hdd_parse_ese_beacon_req(value, &eseBcnReq);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08006241 if (eHAL_STATUS_SUCCESS != status)
6242 {
6243 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08006244 "%s: Failed to parse ese beacon req", __func__);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08006245 ret = -EINVAL;
6246 goto exit;
6247 }
Srinivas Girigowda0c6d7fe2014-05-28 18:18:10 -07006248 if (!hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))) {
6249 hddLog(VOS_TRACE_LEVEL_INFO, FL("Not associated"));
6250 hdd_indicateEseBcnReportNoResults (pAdapter,
6251 eseBcnReq.bcnReq[0].measurementToken,
6252 0x02, //BIT(1) set for measurement done
6253 0); // no BSS
6254 goto exit;
6255 }
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08006256
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08006257 status = sme_SetEseBeaconRequest((tHalHandle)(pHddCtx->hHal), pAdapter->sessionId, &eseBcnReq);
6258 if (eHAL_STATUS_SUCCESS != status)
6259 {
6260 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6261 "%s: sme_SetEseBeaconRequest failed (%d)", __func__, status);
6262 ret = -EINVAL;
6263 goto exit;
6264 }
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08006265 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08006266#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
c_hpothu92367912014-05-01 15:18:17 +05306267 else if (strncmp(command, "GETBCNMISSRATE", 14) == 0)
6268 {
6269 eHalStatus status;
6270 char buf[32], len;
Hanumanth Reddy Pothula1b8dd4f2018-04-09 17:19:03 +05306271 void *cookie;
6272 struct hdd_request *request;
6273 static const struct hdd_request_params params = {
6274 .priv_size = 0,
6275 .timeout_ms = WLAN_WAIT_TIME_STATS,
6276 };
c_hpothu92367912014-05-01 15:18:17 +05306277
6278 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
6279
6280 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
6281 {
6282 hddLog(VOS_TRACE_LEVEL_WARN,
6283 FL("GETBCNMISSRATE: STA is not in connected state"));
6284 ret = -1;
6285 goto exit;
6286 }
Hanumanth Reddy Pothula1b8dd4f2018-04-09 17:19:03 +05306287 request = hdd_request_alloc(&params);
6288 if (!request) {
6289 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Request allocation failure"));
6290 ret = -ENOMEM;
6291 goto exit;
6292 }
6293 cookie = hdd_request_cookie(request);
c_hpothu92367912014-05-01 15:18:17 +05306294
6295 status = sme_getBcnMissRate((tHalHandle)(pHddCtx->hHal),
6296 pAdapter->sessionId,
Hanumanth Reddy Pothula1b8dd4f2018-04-09 17:19:03 +05306297 (void *)get_bcn_miss_rate_cb,
6298 cookie);
c_hpothu92367912014-05-01 15:18:17 +05306299 if( eHAL_STATUS_SUCCESS != status)
6300 {
6301 hddLog(VOS_TRACE_LEVEL_INFO,
6302 FL("GETBCNMISSRATE: fail to post WDA cmd"));
6303 ret = -EINVAL;
Hanumanth Reddy Pothula1b8dd4f2018-04-09 17:19:03 +05306304 goto free_bcn_miss_rate_req;
c_hpothu92367912014-05-01 15:18:17 +05306305 }
6306
Hanumanth Reddy Pothula1b8dd4f2018-04-09 17:19:03 +05306307 ret = hdd_request_wait_for_response(request);
6308 if(ret)
c_hpothu92367912014-05-01 15:18:17 +05306309 {
6310 hddLog(VOS_TRACE_LEVEL_ERROR,
6311 FL("failed to wait on bcnMissRateComp %d"), ret);
6312
c_hpothu92367912014-05-01 15:18:17 +05306313 ret = -EINVAL;
Hanumanth Reddy Pothula1b8dd4f2018-04-09 17:19:03 +05306314 goto free_bcn_miss_rate_req;
c_hpothu92367912014-05-01 15:18:17 +05306315 }
6316
6317 hddLog(VOS_TRACE_LEVEL_INFO,
6318 FL("GETBCNMISSRATE: bcnMissRate: %d"), gbcnMissRate);
6319
6320 len = snprintf(buf, sizeof(buf), "GETBCNMISSRATE %d", gbcnMissRate);
6321 if (copy_to_user(priv_data.buf, &buf, len + 1))
6322 {
6323 hddLog(VOS_TRACE_LEVEL_ERROR,
6324 "%s: failed to copy data to user buffer", __func__);
6325 ret = -EFAULT;
Hanumanth Reddy Pothula1b8dd4f2018-04-09 17:19:03 +05306326 goto free_bcn_miss_rate_req;
c_hpothu92367912014-05-01 15:18:17 +05306327 }
6328 ret = len;
Hanumanth Reddy Pothula1b8dd4f2018-04-09 17:19:03 +05306329
6330free_bcn_miss_rate_req:
6331 hdd_request_put(request);
c_hpothu92367912014-05-01 15:18:17 +05306332 }
Atul Mittal87ec2422014-09-24 13:12:50 +05306333#ifdef FEATURE_WLAN_TDLS
6334 else if (strncmp(command, "TDLSSECONDARYCHANNELOFFSET", 26) == 0) {
6335 tANI_U8 *value = command;
6336 int set_value;
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05306337
6338 ret = hdd_drv_cmd_validate(command, 26);
6339 if (ret)
6340 goto exit;
6341
Atul Mittal87ec2422014-09-24 13:12:50 +05306342 /* Move pointer to ahead of TDLSOFFCH*/
6343 value += 26;
c_manjeebbc40212015-12-08 13:52:59 +05306344 if (!(sscanf(value, "%d", &set_value))) {
6345 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6346 FL("No input identified"));
6347 ret = -EINVAL;
6348 goto exit;
6349 }
6350
Atul Mittal87ec2422014-09-24 13:12:50 +05306351 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6352 "%s: Tdls offchannel offset:%d",
6353 __func__, set_value);
6354 ret = iw_set_tdlssecoffchanneloffset(pHddCtx, set_value);
6355 if (ret < 0)
6356 {
6357 ret = -EINVAL;
6358 goto exit;
6359 }
6360
6361 } else if (strncmp(command, "TDLSOFFCHANNELMODE", 18) == 0) {
6362 tANI_U8 *value = command;
6363 int set_value;
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05306364
6365 ret = hdd_drv_cmd_validate(command, 18);
6366 if (ret)
6367 goto exit;
6368
Atul Mittal87ec2422014-09-24 13:12:50 +05306369 /* Move pointer to ahead of tdlsoffchnmode*/
6370 value += 18;
c_manjee82323892015-12-08 12:40:34 +05306371 ret = sscanf(value, "%d", &set_value);
6372 if (ret != 1) {
6373 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6374 FL("No input identified"));
6375 ret = -EINVAL;
6376 goto exit;
6377 }
Atul Mittal87ec2422014-09-24 13:12:50 +05306378 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6379 "%s: Tdls offchannel mode:%d",
6380 __func__, set_value);
6381 ret = iw_set_tdlsoffchannelmode(pAdapter, set_value);
6382 if (ret < 0)
6383 {
6384 ret = -EINVAL;
6385 goto exit;
6386 }
6387 } else if (strncmp(command, "TDLSOFFCHANNEL", 14) == 0) {
6388 tANI_U8 *value = command;
6389 int set_value;
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05306390
6391 ret = hdd_drv_cmd_validate(command, 14);
6392 if (ret)
6393 goto exit;
6394
Atul Mittal87ec2422014-09-24 13:12:50 +05306395 /* Move pointer to ahead of TDLSOFFCH*/
6396 value += 14;
c_manjeef6ccaf52015-12-08 11:52:11 +05306397 ret = sscanf(value, "%d", &set_value);
6398 if (ret != 1) {
6399 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6400 "Wrong value is given for hdd_set_tdls_offchannel");
6401 ret = -EINVAL;
6402 goto exit;
6403 }
6404
Atul Mittal87ec2422014-09-24 13:12:50 +05306405 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6406 "%s: Tdls offchannel num: %d",
6407 __func__, set_value);
6408 ret = iw_set_tdlsoffchannel(pHddCtx, set_value);
6409 if (ret < 0)
6410 {
6411 ret = -EINVAL;
6412 goto exit;
6413 }
6414 }
6415#endif
Satyanarayana Dash72806012014-12-02 14:30:08 +05306416 else if (strncmp(command, "GETFWSTATS", 10) == 0)
6417 {
6418 eHalStatus status;
6419 char *buf = NULL;
6420 char len;
Hanumanth Reddy Pothula1b8dd4f2018-04-09 17:19:03 +05306421 tSirFwStatsResult *fwStatsRsp = &(pAdapter->fwStatsRsp),
6422 *fw_stats_result;
Satyanarayana Dash72806012014-12-02 14:30:08 +05306423 tANI_U8 *ptr = command;
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05306424 int stats;
Hanumanth Reddy Pothula1b8dd4f2018-04-09 17:19:03 +05306425 void *cookie;
6426 struct hdd_request *request;
6427 struct fw_stats_priv *priv;
6428 static const struct hdd_request_params params = {
6429 .priv_size = sizeof(*priv),
6430 .timeout_ms = WLAN_WAIT_TIME_STATS,
6431 };
Satyanarayana Dash72806012014-12-02 14:30:08 +05306432
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05306433 ret = hdd_drv_cmd_validate(command, 10);
6434 if (ret)
6435 goto exit;
6436
6437 stats = *(ptr + 11) - '0';
Satyanarayana Dash72806012014-12-02 14:30:08 +05306438 hddLog(VOS_TRACE_LEVEL_INFO, FL("stats = %d "),stats);
6439 if (!IS_FEATURE_FW_STATS_ENABLE)
6440 {
6441 hddLog(VOS_TRACE_LEVEL_INFO,
6442 FL("Get Firmware stats feature not supported"));
6443 ret = -EINVAL;
6444 goto exit;
6445 }
6446
6447 if (FW_STATS_MAX <= stats || 0 >= stats)
6448 {
6449 hddLog(VOS_TRACE_LEVEL_INFO,
6450 FL(" stats %d not supported"),stats);
6451 ret = -EINVAL;
6452 goto exit;
6453 }
6454
Hanumanth Reddy Pothula1b8dd4f2018-04-09 17:19:03 +05306455 request = hdd_request_alloc(&params);
6456 if (!request) {
6457 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Request allocation failure"));
6458 ret = -ENOMEM;
6459 goto exit;
6460 }
6461
Satyanarayana Dash72806012014-12-02 14:30:08 +05306462 status = sme_GetFwStats( (tHalHandle)pHddCtx->hHal, stats,
Hanumanth Reddy Pothula1b8dd4f2018-04-09 17:19:03 +05306463 cookie, hdd_fw_statis_cb);
Satyanarayana Dash72806012014-12-02 14:30:08 +05306464 if (eHAL_STATUS_SUCCESS != status)
6465 {
6466 hddLog(VOS_TRACE_LEVEL_ERROR,
6467 FL(" fail to post WDA cmd status = %d"), status);
6468 ret = -EINVAL;
Hanumanth Reddy Pothula1b8dd4f2018-04-09 17:19:03 +05306469 hdd_request_put(request);
Satyanarayana Dash72806012014-12-02 14:30:08 +05306470 goto exit;
6471 }
Hanumanth Reddy Pothula1b8dd4f2018-04-09 17:19:03 +05306472 ret = hdd_request_wait_for_response(request);
6473 if (ret)
Satyanarayana Dash72806012014-12-02 14:30:08 +05306474 {
6475 hddLog(VOS_TRACE_LEVEL_ERROR,
6476 FL("failed to wait on GwtFwstats"));
Satyanarayana Dash72806012014-12-02 14:30:08 +05306477 ret = -EINVAL;
Hanumanth Reddy Pothula1b8dd4f2018-04-09 17:19:03 +05306478 hdd_request_put(request);
Satyanarayana Dash72806012014-12-02 14:30:08 +05306479 goto exit;
6480 }
Hanumanth Reddy Pothula1b8dd4f2018-04-09 17:19:03 +05306481
6482 priv = hdd_request_priv(request);
6483 fw_stats_result = priv->fw_stats;
6484 fwStatsRsp->type = 0;
6485 if (NULL != fw_stats_result)
6486 {
6487 switch (fw_stats_result->type )
6488 {
6489 case FW_UBSP_STATS:
6490 {
6491 tSirUbspFwStats *stats =
6492 &fwStatsRsp->fwStatsData.ubspStats;
6493 memcpy(fwStatsRsp, fw_stats_result,
6494 sizeof(tSirFwStatsResult));
6495 hddLog(VOS_TRACE_LEVEL_INFO,
6496 FL("ubsp_enter_cnt = %d ubsp_jump_ddr_cnt = %d"),
6497 stats->ubsp_enter_cnt,
6498 stats->ubsp_jump_ddr_cnt);
6499 }
6500 break;
6501
6502 default:
6503 {
6504 hddLog(VOS_TRACE_LEVEL_ERROR,
6505 FL("No handling for stats type %d"),
6506 fw_stats_result->type);
6507 }
6508 }
6509 }
6510 hdd_request_put(request);
6511
Satyanarayana Dash72806012014-12-02 14:30:08 +05306512 if (fwStatsRsp->type)
6513 {
6514 buf = kmalloc(FW_STATE_RSP_LEN, GFP_KERNEL);
6515 if (!buf)
6516 {
6517 hddLog(VOS_TRACE_LEVEL_ERROR,
6518 FL(" failed to allocate memory"));
6519 ret = -ENOMEM;
6520 goto exit;
6521 }
6522 switch( fwStatsRsp->type )
6523 {
6524 case FW_UBSP_STATS:
6525 {
6526 len = snprintf(buf, FW_STATE_RSP_LEN,
6527 "GETFWSTATS: ubsp_enter_cnt %d ubsp_jump_ddr_cnt %d",
Abhishek Singh08aa7762014-12-16 13:59:03 +05306528 fwStatsRsp->fwStatsData.ubspStats.ubsp_enter_cnt,
6529 fwStatsRsp->fwStatsData.ubspStats.ubsp_jump_ddr_cnt);
Satyanarayana Dash72806012014-12-02 14:30:08 +05306530 }
6531 break;
6532 default:
6533 {
6534 hddLog(VOS_TRACE_LEVEL_ERROR, FL( "No handling for stats type %d"),fwStatsRsp->type);
6535 ret = -EFAULT;
6536 kfree(buf);
6537 goto exit;
6538 }
6539 }
6540 if (copy_to_user(priv_data.buf, buf, len + 1))
6541 {
6542 hddLog(VOS_TRACE_LEVEL_ERROR,
6543 FL(" failed to copy data to user buffer"));
6544 ret = -EFAULT;
6545 kfree(buf);
6546 goto exit;
6547 }
6548 ret = len;
6549 kfree(buf);
6550 }
6551 else
6552 {
6553 hddLog(VOS_TRACE_LEVEL_ERROR,
6554 FL("failed to fetch the stats"));
6555 ret = -EFAULT;
6556 goto exit;
6557 }
Satyanarayana Dash72806012014-12-02 14:30:08 +05306558 }
Agarwal Ashish8bd53ae2015-06-12 18:03:45 +05306559 else if (strncasecmp(command, "SET_FCC_CHANNEL", 15) == 0)
6560 {
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05306561 ret = hdd_drv_cmd_validate(command, 15);
6562 if (ret)
6563 goto exit;
6564
Agarwal Ashish8bd53ae2015-06-12 18:03:45 +05306565 /*
6566 * this command wld be called by user-space when it detects WLAN
6567 * ON after airplane mode is set. When APM is set, WLAN turns off.
6568 * But it can be turned back on. Otherwise; when APM is turned back
6569 * off, WLAN wld turn back on. So at that point the command is
6570 * expected to come down. 0 means disable, 1 means enable. The
6571 * constraint is removed when parameter 1 is set or different
6572 * country code is set
6573 */
6574 ret = hdd_cmd_setFccChannel(pHddCtx, command, 15);
6575 }
Mahesh A Saptasagarbeca12c2015-09-07 16:21:06 +05306576 else if (strncasecmp(command, "DISABLE_CA_EVENT", 16) == 0)
6577 {
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05306578 ret = hdd_drv_cmd_validate(command, 16);
6579 if (ret)
6580 goto exit;
6581
Mahesh A Saptasagarbeca12c2015-09-07 16:21:06 +05306582 ret = hdd_enable_disable_ca_event(pHddCtx, command, 16);
6583 }
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +05306584 /*
6585 * command should be a string having format
6586 * SET_DISABLE_CHANNEL_LIST <num of channels>
6587 * <channels separated by spaces>
6588 */
6589 else if (strncmp(command, "SET_DISABLE_CHANNEL_LIST", 24) == 0) {
6590 tANI_U8 *ptr = command;
6591 ret = hdd_drv_cmd_validate(command, 24);
6592 if (ret)
6593 goto exit;
6594
6595 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6596 " Received Command to disable Channels %s",
6597 __func__);
6598 ret = hdd_parse_disable_chan_cmd(pAdapter, ptr);
6599 if (ret)
6600 goto exit;
6601 }
Hanumanth Reddy Pothula8ae38bb2018-03-07 18:59:30 +05306602 else if (strncmp(command, "GET_DISABLE_CHANNEL_LIST", 24) == 0) {
6603 char extra[128] = {0};
6604 int len;
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +05306605
Hanumanth Reddy Pothula8ae38bb2018-03-07 18:59:30 +05306606 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6607 " Received Command to get disable Channels list %s",
6608 __func__);
6609
6610 len = hdd_get_disable_ch_list(pHddCtx, extra, sizeof(extra));
6611 if (len == 0) {
6612 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6613 FL("disable channel list are not yet programed"));
6614 ret = -EINVAL;
6615 goto exit;
6616 }
6617
6618 len = VOS_MIN(priv_data.total_len, len + 1);
6619 if (copy_to_user(priv_data.buf, &extra, len)) {
6620 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6621 "%s: failed to copy data to user buffer", __func__);
6622 ret = -EFAULT;
6623 goto exit;
6624 }
6625
6626 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6627 FL("data:%s"), extra);
6628 }
Madan Mohan Koyyalamudif9bdd4e2012-10-30 18:05:03 -07006629 else {
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05306630 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
6631 TRACE_CODE_HDD_UNSUPPORTED_IOCTL,
6632 pAdapter->sessionId, 0));
Satyanarayana Dash72806012014-12-02 14:30:08 +05306633 hddLog( VOS_TRACE_LEVEL_WARN, FL("Unsupported GUI command %s"),
6634 command);
Madan Mohan Koyyalamudif9bdd4e2012-10-30 18:05:03 -07006635 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006636 }
6637exit:
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05306638 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07006639 if (command)
6640 {
6641 kfree(command);
6642 }
6643 return ret;
6644}
6645
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07006646#ifdef CONFIG_COMPAT
6647static int hdd_driver_compat_ioctl(hdd_adapter_t *pAdapter, struct ifreq *ifr)
6648{
6649 struct {
6650 compat_uptr_t buf;
6651 int used_len;
6652 int total_len;
6653 } compat_priv_data;
6654 hdd_priv_data_t priv_data;
6655 int ret = 0;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07006656
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07006657 /*
6658 * Note that pAdapter and ifr have already been verified by caller,
6659 * and HDD context has also been validated
6660 */
6661 if (copy_from_user(&compat_priv_data, ifr->ifr_data,
6662 sizeof(compat_priv_data))) {
6663 ret = -EFAULT;
6664 goto exit;
6665 }
6666 priv_data.buf = compat_ptr(compat_priv_data.buf);
6667 priv_data.used_len = compat_priv_data.used_len;
6668 priv_data.total_len = compat_priv_data.total_len;
6669 ret = hdd_driver_command(pAdapter, &priv_data);
6670 exit:
6671 return ret;
6672}
6673#else /* CONFIG_COMPAT */
6674static int hdd_driver_compat_ioctl(hdd_adapter_t *pAdapter, struct ifreq *ifr)
6675{
6676 /* will never be invoked */
6677 return 0;
6678}
6679#endif /* CONFIG_COMPAT */
6680
6681static int hdd_driver_ioctl(hdd_adapter_t *pAdapter, struct ifreq *ifr)
6682{
6683 hdd_priv_data_t priv_data;
6684 int ret = 0;
6685
6686 /*
6687 * Note that pAdapter and ifr have already been verified by caller,
6688 * and HDD context has also been validated
6689 */
6690 if (copy_from_user(&priv_data, ifr->ifr_data, sizeof(priv_data))) {
6691 ret = -EFAULT;
6692 } else {
6693 ret = hdd_driver_command(pAdapter, &priv_data);
6694 }
6695 return ret;
6696}
6697
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05306698int __hdd_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07006699{
6700 hdd_adapter_t *pAdapter;
6701 hdd_context_t *pHddCtx;
6702 int ret;
6703
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05306704 ENTER();
6705
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07006706 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6707 if (NULL == pAdapter) {
6708 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
6709 "%s: HDD adapter context is Null", __func__);
6710 ret = -ENODEV;
6711 goto exit;
6712 }
6713 if (dev != pAdapter->dev) {
6714 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
6715 "%s: HDD adapter/dev inconsistency", __func__);
6716 ret = -ENODEV;
6717 goto exit;
6718 }
6719
6720 if ((!ifr) || (!ifr->ifr_data)) {
6721 ret = -EINVAL;
6722 goto exit;
6723 }
6724
6725 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
6726 ret = wlan_hdd_validate_context(pHddCtx);
6727 if (ret) {
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07006728 ret = -EBUSY;
6729 goto exit;
6730 }
6731
6732 switch (cmd) {
6733 case (SIOCDEVPRIVATE + 1):
6734 if (is_compat_task())
6735 ret = hdd_driver_compat_ioctl(pAdapter, ifr);
6736 else
6737 ret = hdd_driver_ioctl(pAdapter, ifr);
6738 break;
6739 default:
6740 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unknown ioctl %d",
6741 __func__, cmd);
6742 ret = -EINVAL;
6743 break;
6744 }
6745 exit:
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05306746 EXIT();
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07006747 return ret;
6748}
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07006749
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05306750int hdd_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
6751{
6752 int ret;
6753
6754 vos_ssr_protect(__func__);
6755 ret = __hdd_ioctl(dev, ifr, cmd);
6756 vos_ssr_unprotect(__func__);
6757
6758 return ret;
6759}
6760
Katya Nigame7b69a82015-04-28 15:24:06 +05306761int hdd_mon_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
6762{
6763 return 0;
6764}
6765
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08006766#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08006767/**---------------------------------------------------------------------------
6768
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08006769 \brief hdd_parse_ese_beacon_req() - Parse ese beacon request
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08006770
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08006771 This function parses the ese beacon request passed in the format
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08006772 CCXBEACONREQ<space><Number of fields><space><Measurement token>
6773 <space>Channel 1<space>Scan Mode <space>Meas Duration<space>Channel N
6774 <space>Scan Mode N<space>Meas Duration N
6775 if the Number of bcn req fields (N) does not match with the actual number of fields passed
6776 then take N.
6777 <Meas Token><Channel><Scan Mode> and <Meas Duration> are treated as one pair
6778 For example, CCXBEACONREQ 2 1 1 1 30 2 44 0 40.
6779 This function does not take care of removing duplicate channels from the list
6780
6781 \param - pValue Pointer to data
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08006782 \param - pEseBcnReq output pointer to store parsed ie information
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08006783
6784 \return - 0 for success non-zero for failure
6785
6786 --------------------------------------------------------------------------*/
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08006787static VOS_STATUS hdd_parse_ese_beacon_req(tANI_U8 *pValue,
6788 tCsrEseBeaconReq *pEseBcnReq)
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08006789{
6790 tANI_U8 *inPtr = pValue;
Arun Khandavalli9f3b4832016-06-30 16:58:38 +05306791 uint8_t input = 0;
6792 uint32_t tempInt = 0;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08006793 int j = 0, i = 0, v = 0;
6794 char buf[32];
6795
6796 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
6797 /*no argument after the command*/
6798 if (NULL == inPtr)
6799 {
6800 return -EINVAL;
6801 }
6802 /*no space after the command*/
6803 else if (SPACE_ASCII_VALUE != *inPtr)
6804 {
6805 return -EINVAL;
6806 }
6807
6808 /*removing empty spaces*/
6809 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
6810
6811 /*no argument followed by spaces*/
6812 if ('\0' == *inPtr) return -EINVAL;
6813
6814 /*getting the first argument ie measurement token*/
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08006815 v = sscanf(inPtr, "%31s ", buf);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08006816 if (1 != v) return -EINVAL;
6817
Arun Khandavalli9f3b4832016-06-30 16:58:38 +05306818 v = kstrtos8(buf, 10, &input);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08006819 if ( v < 0) return -EINVAL;
6820
Arun Khandavalli9f3b4832016-06-30 16:58:38 +05306821 input = VOS_MIN(input, SIR_ESE_MAX_MEAS_IE_REQS);
6822 pEseBcnReq->numBcnReqIe = input;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08006823
Srinivas Girigowda725a88e2016-03-31 19:24:25 +05306824 hddLog(LOG1, "Number of Bcn Req Ie fields: %d", pEseBcnReq->numBcnReqIe);
6825
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08006826
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08006827 for (j = 0; j < (pEseBcnReq->numBcnReqIe); j++)
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08006828 {
6829 for (i = 0; i < 4; i++)
6830 {
6831 /*inPtr pointing to the beginning of first space after number of ie fields*/
6832 inPtr = strpbrk( inPtr, " " );
6833 /*no ie data after the number of ie fields argument*/
6834 if (NULL == inPtr) return -EINVAL;
6835
6836 /*removing empty space*/
6837 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
6838
6839 /*no ie data after the number of ie fields argument and spaces*/
6840 if ( '\0' == *inPtr ) return -EINVAL;
6841
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08006842 v = sscanf(inPtr, "%31s ", buf);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08006843 if (1 != v) return -EINVAL;
6844
Arun Khandavalli9f3b4832016-06-30 16:58:38 +05306845 v = kstrtou32(buf, 10, &tempInt);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08006846 if (v < 0) return -EINVAL;
6847
6848 switch (i)
6849 {
6850 case 0: /* Measurement token */
Arun Khandavalli9f3b4832016-06-30 16:58:38 +05306851 if (!tempInt)
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08006852 {
6853 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arun Khandavalli9f3b4832016-06-30 16:58:38 +05306854 "Invalid Measurement Token: %u", tempInt);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08006855 return -EINVAL;
6856 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08006857 pEseBcnReq->bcnReq[j].measurementToken = tempInt;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08006858 break;
6859
6860 case 1: /* Channel number */
Arun Khandavalli9f3b4832016-06-30 16:58:38 +05306861 if ((!tempInt) ||
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08006862 (tempInt > WNI_CFG_CURRENT_CHANNEL_STAMAX))
6863 {
6864 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arun Khandavalli9f3b4832016-06-30 16:58:38 +05306865 "Invalid Channel Number: %u", tempInt);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08006866 return -EINVAL;
6867 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08006868 pEseBcnReq->bcnReq[j].channel = tempInt;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08006869 break;
6870
6871 case 2: /* Scan mode */
Varun Reddy Yeturu0b18d5a2013-12-04 11:42:23 -08006872 if ((tempInt < eSIR_PASSIVE_SCAN) || (tempInt > eSIR_BEACON_TABLE))
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08006873 {
6874 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arun Khandavalli9f3b4832016-06-30 16:58:38 +05306875 "Invalid Scan Mode(%u) Expected{0|1|2}", tempInt);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08006876 return -EINVAL;
6877 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08006878 pEseBcnReq->bcnReq[j].scanMode= tempInt;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08006879 break;
6880
6881 case 3: /* Measurement duration */
Arun Khandavalli9f3b4832016-06-30 16:58:38 +05306882 if (((!tempInt) && (pEseBcnReq->bcnReq[j].scanMode != eSIR_BEACON_TABLE)) ||
6883 ((pEseBcnReq->bcnReq[j].scanMode == eSIR_BEACON_TABLE)))
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08006884 {
6885 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arun Khandavalli9f3b4832016-06-30 16:58:38 +05306886 "Invalid Measurement Duration: %u", tempInt);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08006887 return -EINVAL;
6888 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08006889 pEseBcnReq->bcnReq[j].measurementDuration = tempInt;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08006890 break;
6891 }
6892 }
6893 }
6894
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08006895 for (j = 0; j < pEseBcnReq->numBcnReqIe; j++)
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08006896 {
6897 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Arun Kumar Khandavallie8768212014-02-17 16:43:34 +05306898 "Index(%d) Measurement Token(%u)Channel(%u) Scan Mode(%u) Measurement Duration(%u)\n",
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08006899 j,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08006900 pEseBcnReq->bcnReq[j].measurementToken,
6901 pEseBcnReq->bcnReq[j].channel,
6902 pEseBcnReq->bcnReq[j].scanMode,
6903 pEseBcnReq->bcnReq[j].measurementDuration);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08006904 }
6905
6906 return VOS_STATUS_SUCCESS;
6907}
6908
Hanumanth Reddy Pothula1ceb7032018-04-05 19:35:55 +05306909struct tsm_priv {
6910 tAniTrafStrmMetrics tsm_metrics;
6911};
6912
6913static void hdd_get_tsm_stats_cb(tAniTrafStrmMetrics tsm_metrics,
6914 const tANI_U32 sta_id, void *context )
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07006915{
Hanumanth Reddy Pothula1ceb7032018-04-05 19:35:55 +05306916 struct hdd_request *request;
6917 struct tsm_priv *priv;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07006918
Hanumanth Reddy Pothula1ceb7032018-04-05 19:35:55 +05306919 ENTER();
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07006920
Hanumanth Reddy Pothula1ceb7032018-04-05 19:35:55 +05306921 request = hdd_request_get(context);
6922 if (!request) {
6923 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Obsolete request"));
6924 return;
6925 }
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07006926
Hanumanth Reddy Pothula1ceb7032018-04-05 19:35:55 +05306927 priv = hdd_request_priv(request);
6928 priv->tsm_metrics = tsm_metrics;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07006929
Hanumanth Reddy Pothula1ceb7032018-04-05 19:35:55 +05306930 hdd_request_complete(request);
6931 hdd_request_put(request);
Jeff Johnson72a40512013-12-19 10:14:15 -08006932
Hanumanth Reddy Pothula1ceb7032018-04-05 19:35:55 +05306933 EXIT();
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07006934}
6935
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07006936static VOS_STATUS hdd_get_tsm_stats(hdd_adapter_t *pAdapter, const tANI_U8 tid,
6937 tAniTrafStrmMetrics* pTsmMetrics)
6938{
6939 hdd_station_ctx_t *pHddStaCtx = NULL;
6940 eHalStatus hstatus;
Jeff Johnson72a40512013-12-19 10:14:15 -08006941 VOS_STATUS vstatus = VOS_STATUS_SUCCESS;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07006942 hdd_context_t *pHddCtx = NULL;
Hanumanth Reddy Pothula1ceb7032018-04-05 19:35:55 +05306943 int ret;
6944 void *cookie;
6945 struct hdd_request *request;
6946 struct tsm_priv *priv;
6947 static const struct hdd_request_params params = {
6948 .priv_size = sizeof(*priv),
6949 .timeout_ms = WLAN_WAIT_TIME_STATS,
6950 };
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07006951
6952 if (NULL == pAdapter)
6953 {
6954 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: pAdapter is NULL", __func__);
6955 return VOS_STATUS_E_FAULT;
6956 }
6957
6958 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
6959 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
6960
Hanumanth Reddy Pothula1ceb7032018-04-05 19:35:55 +05306961 request = hdd_request_alloc(&params);
6962 if (!request) {
6963 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Request allocation failure"));
6964 return VOS_STATUS_E_NOMEM;
6965 }
6966 cookie = hdd_request_cookie(request);
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07006967
6968 /* query tsm stats */
Hanumanth Reddy Pothula1ceb7032018-04-05 19:35:55 +05306969 hstatus = sme_GetTsmStats(pHddCtx->hHal, hdd_get_tsm_stats_cb,
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07006970 pHddStaCtx->conn_info.staId[ 0 ],
6971 pHddStaCtx->conn_info.bssId,
Hanumanth Reddy Pothula1ceb7032018-04-05 19:35:55 +05306972 cookie, pHddCtx->pvosContext, tid);
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07006973
6974 if (eHAL_STATUS_SUCCESS != hstatus)
6975 {
Jeff Johnson72a40512013-12-19 10:14:15 -08006976 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unable to retrieve statistics",
6977 __func__);
6978 vstatus = VOS_STATUS_E_FAULT;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07006979 }
6980 else
6981 {
6982 /* request was sent -- wait for the response */
Hanumanth Reddy Pothula1ceb7032018-04-05 19:35:55 +05306983 ret = hdd_request_wait_for_response(request);
6984 if (ret) {
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07006985 hddLog(VOS_TRACE_LEVEL_ERROR,
Hanumanth Reddy Pothula1ceb7032018-04-05 19:35:55 +05306986 "SME timeout while retrieving statistics");
Jeff Johnson72a40512013-12-19 10:14:15 -08006987 vstatus = VOS_STATUS_E_TIMEOUT;
Hanumanth Reddy Pothula1ceb7032018-04-05 19:35:55 +05306988 } else {
6989 priv = hdd_request_priv(request);
6990 *pTsmMetrics = priv->tsm_metrics;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07006991 }
6992 }
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07006993
Hanumanth Reddy Pothula1ceb7032018-04-05 19:35:55 +05306994 hdd_request_put(request);
Jeff Johnson72a40512013-12-19 10:14:15 -08006995
Jeff Johnson72a40512013-12-19 10:14:15 -08006996 return vstatus;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07006997}
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08006998#endif /*FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07006999
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08007000#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowdade697412013-02-14 16:31:48 -08007001void hdd_getBand_helper(hdd_context_t *pHddCtx, int *pBand)
7002{
7003 eCsrBand band = -1;
7004 sme_GetFreqBand((tHalHandle)(pHddCtx->hHal), &band);
7005 switch (band)
7006 {
7007 case eCSR_BAND_ALL:
7008 *pBand = WLAN_HDD_UI_BAND_AUTO;
7009 break;
7010
7011 case eCSR_BAND_24:
7012 *pBand = WLAN_HDD_UI_BAND_2_4_GHZ;
7013 break;
7014
7015 case eCSR_BAND_5G:
7016 *pBand = WLAN_HDD_UI_BAND_5_GHZ;
7017 break;
7018
7019 default:
7020 hddLog( VOS_TRACE_LEVEL_WARN, "%s: Invalid Band %d", __func__, band);
7021 *pBand = -1;
7022 break;
7023 }
7024}
7025
7026/**---------------------------------------------------------------------------
7027
Srinivas Girigowda100eb322013-03-15 16:48:20 -07007028 \brief hdd_parse_send_action_frame_data() - HDD Parse send action frame data
7029
7030 This function parses the send action frame data passed in the format
7031 SENDACTIONFRAME<space><bssid><space><channel><space><dwelltime><space><data>
7032
Srinivas Girigowda56076852013-08-20 14:00:50 -07007033 \param - pValue Pointer to input data
Srinivas Girigowda100eb322013-03-15 16:48:20 -07007034 \param - pTargetApBssid Pointer to target Ap bssid
7035 \param - pChannel Pointer to the Target AP channel
7036 \param - pDwellTime Pointer to the time to stay off-channel after transmitting action frame
7037 \param - pBuf Pointer to data
7038 \param - pBufLen Pointer to data length
7039
7040 \return - 0 for success non-zero for failure
7041
7042 --------------------------------------------------------------------------*/
7043VOS_STATUS hdd_parse_send_action_frame_data(tANI_U8 *pValue, tANI_U8 *pTargetApBssid, tANI_U8 *pChannel,
7044 tANI_U8 *pDwellTime, tANI_U8 **pBuf, tANI_U8 *pBufLen)
7045{
7046 tANI_U8 *inPtr = pValue;
7047 tANI_U8 *dataEnd;
7048 int tempInt;
7049 int j = 0;
7050 int i = 0;
7051 int v = 0;
7052 tANI_U8 tempBuf[32];
7053 tANI_U8 tempByte = 0;
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08007054 /* 12 hexa decimal digits, 5 ':' and '\0' */
7055 tANI_U8 macAddress[18];
Srinivas Girigowda100eb322013-03-15 16:48:20 -07007056
7057 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
7058 /*no argument after the command*/
7059 if (NULL == inPtr)
7060 {
7061 return -EINVAL;
7062 }
7063
7064 /*no space after the command*/
7065 else if (SPACE_ASCII_VALUE != *inPtr)
7066 {
7067 return -EINVAL;
7068 }
7069
7070 /*removing empty spaces*/
7071 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
7072
7073 /*no argument followed by spaces*/
7074 if ('\0' == *inPtr)
7075 {
7076 return -EINVAL;
7077 }
7078
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07007079 v = sscanf(inPtr, "%17s", macAddress);
7080 if (!((1 == v) && hdd_is_valid_mac_address(macAddress)))
Srinivas Girigowda100eb322013-03-15 16:48:20 -07007081 {
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07007082 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7083 "Invalid MAC address or All hex inputs are not read (%d)", v);
7084 return -EINVAL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07007085 }
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07007086
7087 pTargetApBssid[0] = hdd_parse_hex(macAddress[0]) << 4 | hdd_parse_hex(macAddress[1]);
7088 pTargetApBssid[1] = hdd_parse_hex(macAddress[3]) << 4 | hdd_parse_hex(macAddress[4]);
7089 pTargetApBssid[2] = hdd_parse_hex(macAddress[6]) << 4 | hdd_parse_hex(macAddress[7]);
7090 pTargetApBssid[3] = hdd_parse_hex(macAddress[9]) << 4 | hdd_parse_hex(macAddress[10]);
7091 pTargetApBssid[4] = hdd_parse_hex(macAddress[12]) << 4 | hdd_parse_hex(macAddress[13]);
7092 pTargetApBssid[5] = hdd_parse_hex(macAddress[15]) << 4 | hdd_parse_hex(macAddress[16]);
Srinivas Girigowda100eb322013-03-15 16:48:20 -07007093
7094 /* point to the next argument */
7095 inPtr = strnchr(inPtr, strlen(inPtr), SPACE_ASCII_VALUE);
7096 /*no argument after the command*/
7097 if (NULL == inPtr) return -EINVAL;
7098
7099 /*removing empty spaces*/
7100 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
7101
7102 /*no argument followed by spaces*/
7103 if ('\0' == *inPtr)
7104 {
7105 return -EINVAL;
7106 }
7107
7108 /*getting the next argument ie the channel number */
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08007109 v = sscanf(inPtr, "%31s ", tempBuf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07007110 if (1 != v) return -EINVAL;
7111
Srinivas Girigowda100eb322013-03-15 16:48:20 -07007112 v = kstrtos32(tempBuf, 10, &tempInt);
Agarwal Ashish353b3a82014-04-08 14:55:11 +05307113 if ( v < 0 || tempInt <= 0 || tempInt > WNI_CFG_CURRENT_CHANNEL_STAMAX )
Kiet Lambe150c22013-11-21 16:30:32 +05307114 return -EINVAL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07007115
7116 *pChannel = tempInt;
7117
7118 /* point to the next argument */
7119 inPtr = strnchr(inPtr, strlen(inPtr), SPACE_ASCII_VALUE);
7120 /*no argument after the command*/
7121 if (NULL == inPtr) return -EINVAL;
7122 /*removing empty spaces*/
7123 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
7124
7125 /*no argument followed by spaces*/
7126 if ('\0' == *inPtr)
7127 {
7128 return -EINVAL;
7129 }
7130
7131 /*getting the next argument ie the dwell time */
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08007132 v = sscanf(inPtr, "%31s ", tempBuf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07007133 if (1 != v) return -EINVAL;
7134
Srinivas Girigowda100eb322013-03-15 16:48:20 -07007135 v = kstrtos32(tempBuf, 10, &tempInt);
Srinivas Girigowda5a6e0672014-01-09 14:42:57 -08007136 if ( v < 0 || tempInt < 0) return -EINVAL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07007137
7138 *pDwellTime = tempInt;
7139
7140 /* point to the next argument */
7141 inPtr = strnchr(inPtr, strlen(inPtr), SPACE_ASCII_VALUE);
7142 /*no argument after the command*/
7143 if (NULL == inPtr) return -EINVAL;
7144 /*removing empty spaces*/
7145 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
7146
7147 /*no argument followed by spaces*/
7148 if ('\0' == *inPtr)
7149 {
7150 return -EINVAL;
7151 }
7152
7153 /* find the length of data */
7154 dataEnd = inPtr;
7155 while(('\0' != *dataEnd) )
7156 {
7157 dataEnd++;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07007158 }
Kiet Lambe150c22013-11-21 16:30:32 +05307159 *pBufLen = dataEnd - inPtr ;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07007160 if ( *pBufLen <= 0) return -EINVAL;
7161
Srinivas Girigowdab5ae85d2013-06-03 10:51:45 -07007162 /* Allocate the number of bytes based on the number of input characters
7163 whether it is even or odd.
7164 if the number of input characters are even, then we need N/2 byte.
7165 if the number of input characters are odd, then we need do (N+1)/2 to
7166 compensate rounding off.
7167 For example, if N = 18, then (18 + 1)/2 = 9 bytes are enough.
7168 If N = 19, then we need 10 bytes, hence (19 + 1)/2 = 10 bytes */
7169 *pBuf = vos_mem_malloc((*pBufLen + 1)/2);
Srinivas Girigowda100eb322013-03-15 16:48:20 -07007170 if (NULL == *pBuf)
7171 {
7172 hddLog(VOS_TRACE_LEVEL_FATAL,
7173 "%s: vos_mem_alloc failed ", __func__);
7174 return -EINVAL;
7175 }
7176
7177 /* the buffer received from the upper layer is character buffer,
7178 we need to prepare the buffer taking 2 characters in to a U8 hex decimal number
7179 for example 7f0000f0...form a buffer to contain 7f in 0th location, 00 in 1st
7180 and f0 in 3rd location */
7181 for (i = 0, j = 0; j < *pBufLen; j += 2)
7182 {
Kiet Lambe150c22013-11-21 16:30:32 +05307183 if( j+1 == *pBufLen)
7184 {
7185 tempByte = hdd_parse_hex(inPtr[j]);
7186 }
7187 else
7188 {
7189 tempByte = (hdd_parse_hex(inPtr[j]) << 4) | (hdd_parse_hex(inPtr[j + 1]));
7190 }
Srinivas Girigowda100eb322013-03-15 16:48:20 -07007191 (*pBuf)[i++] = tempByte;
7192 }
7193 *pBufLen = i;
7194 return VOS_STATUS_SUCCESS;
7195}
7196
Srinivas Girigowda100eb322013-03-15 16:48:20 -07007197/**---------------------------------------------------------------------------
7198
Srinivas Girigowdade697412013-02-14 16:31:48 -08007199 \brief hdd_parse_channellist() - HDD Parse channel list
7200
7201 This function parses the channel list passed in the format
7202 SETROAMSCANCHANNELS<space><Number of channels><space>Channel 1<space>Channel 2<space>Channel N
Srinivas Girigowdacf9a9b42013-03-21 11:55:24 -07007203 if the Number of channels (N) does not match with the actual number of channels passed
7204 then take the minimum of N and count of (Ch1, Ch2, ...Ch M)
7205 For example, if SETROAMSCANCHANNELS 3 36 40 44 48, only 36, 40 and 44 shall be taken.
7206 If SETROAMSCANCHANNELS 5 36 40 44 48, ignore 5 and take 36, 40, 44 and 48.
7207 This function does not take care of removing duplicate channels from the list
Srinivas Girigowdade697412013-02-14 16:31:48 -08007208
7209 \param - pValue Pointer to input channel list
7210 \param - ChannelList Pointer to local output array to record channel list
7211 \param - pNumChannels Pointer to number of roam scan channels
7212
7213 \return - 0 for success non-zero for failure
7214
7215 --------------------------------------------------------------------------*/
7216VOS_STATUS hdd_parse_channellist(tANI_U8 *pValue, tANI_U8 *pChannelList, tANI_U8 *pNumChannels)
7217{
7218 tANI_U8 *inPtr = pValue;
7219 int tempInt;
7220 int j = 0;
7221 int v = 0;
7222 char buf[32];
7223
7224 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
7225 /*no argument after the command*/
7226 if (NULL == inPtr)
7227 {
7228 return -EINVAL;
7229 }
7230
7231 /*no space after the command*/
7232 else if (SPACE_ASCII_VALUE != *inPtr)
7233 {
7234 return -EINVAL;
7235 }
7236
7237 /*removing empty spaces*/
Jeff Johnsona1f9afb2013-04-03 09:13:31 -07007238 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
Srinivas Girigowdade697412013-02-14 16:31:48 -08007239
7240 /*no argument followed by spaces*/
7241 if ('\0' == *inPtr)
7242 {
7243 return -EINVAL;
7244 }
7245
7246 /*getting the first argument ie the number of channels*/
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08007247 v = sscanf(inPtr, "%31s ", buf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07007248 if (1 != v) return -EINVAL;
7249
Srinivas Girigowdade697412013-02-14 16:31:48 -08007250 v = kstrtos32(buf, 10, &tempInt);
Jeff Johnsona1f9afb2013-04-03 09:13:31 -07007251 if ((v < 0) ||
7252 (tempInt <= 0) ||
7253 (tempInt > WNI_CFG_VALID_CHANNEL_LIST_LEN))
7254 {
7255 return -EINVAL;
7256 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08007257
7258 *pNumChannels = tempInt;
7259
7260 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
7261 "Number of channels are: %d", *pNumChannels);
7262
7263 for (j = 0; j < (*pNumChannels); j++)
7264 {
7265 /*inPtr pointing to the beginning of first space after number of channels*/
7266 inPtr = strpbrk( inPtr, " " );
7267 /*no channel list after the number of channels argument*/
7268 if (NULL == inPtr)
7269 {
Srinivas Girigowdacf9a9b42013-03-21 11:55:24 -07007270 if (0 != j)
7271 {
7272 *pNumChannels = j;
7273 return VOS_STATUS_SUCCESS;
7274 }
7275 else
7276 {
7277 return -EINVAL;
7278 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08007279 }
7280
7281 /*removing empty space*/
Jeff Johnsona1f9afb2013-04-03 09:13:31 -07007282 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
Srinivas Girigowdade697412013-02-14 16:31:48 -08007283
7284 /*no channel list after the number of channels argument and spaces*/
7285 if ( '\0' == *inPtr )
7286 {
Srinivas Girigowdacf9a9b42013-03-21 11:55:24 -07007287 if (0 != j)
7288 {
7289 *pNumChannels = j;
7290 return VOS_STATUS_SUCCESS;
7291 }
7292 else
7293 {
7294 return -EINVAL;
7295 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08007296 }
7297
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08007298 v = sscanf(inPtr, "%31s ", buf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07007299 if (1 != v) return -EINVAL;
7300
Srinivas Girigowdade697412013-02-14 16:31:48 -08007301 v = kstrtos32(buf, 10, &tempInt);
Jeff Johnsona1f9afb2013-04-03 09:13:31 -07007302 if ((v < 0) ||
7303 (tempInt <= 0) ||
7304 (tempInt > WNI_CFG_CURRENT_CHANNEL_STAMAX))
7305 {
7306 return -EINVAL;
7307 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08007308 pChannelList[j] = tempInt;
7309
7310 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
7311 "Channel %d added to preferred channel list",
7312 pChannelList[j] );
7313 }
7314
Srinivas Girigowdade697412013-02-14 16:31:48 -08007315 return VOS_STATUS_SUCCESS;
7316}
7317
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07007318
Selvaraj, Sridhar5aff1ed2016-06-18 01:26:23 +05307319/**
7320 * hdd_parse_reassoc_command_v1_data() - HDD Parse reassoc command data
7321 * This function parses the reasoc command data passed in the format
7322 * REASSOC<space><bssid><space><channel>
7323 *
7324 * @pValue: Pointer to input data (its a NUL terminated string)
7325 * @pTargetApBssid: Pointer to target Ap bssid
7326 * @pChannel: Pointer to the Target AP channel
7327 *
7328 * Return: 0 for success non-zero for failure
7329 */
7330static int hdd_parse_reassoc_command_v1_data(const tANI_U8 *pValue,
7331 tANI_U8 *pTargetApBssid, tANI_U8 *pChannel)
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07007332{
Selvaraj, Sridhar5aff1ed2016-06-18 01:26:23 +05307333 const tANI_U8 *inPtr = pValue;
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07007334 int tempInt;
7335 int v = 0;
7336 tANI_U8 tempBuf[32];
Kiet Lamaa8e15a2014-02-11 23:30:06 -08007337 /* 12 hexa decimal digits, 5 ':' and '\0' */
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08007338 tANI_U8 macAddress[18];
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07007339
7340 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
7341 /*no argument after the command*/
7342 if (NULL == inPtr)
7343 {
7344 return -EINVAL;
7345 }
7346
7347 /*no space after the command*/
7348 else if (SPACE_ASCII_VALUE != *inPtr)
7349 {
7350 return -EINVAL;
7351 }
7352
7353 /*removing empty spaces*/
7354 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
7355
7356 /*no argument followed by spaces*/
7357 if ('\0' == *inPtr)
7358 {
7359 return -EINVAL;
7360 }
7361
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07007362 v = sscanf(inPtr, "%17s", macAddress);
7363 if (!((1 == v) && hdd_is_valid_mac_address(macAddress)))
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07007364 {
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07007365 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7366 "Invalid MAC address or All hex inputs are not read (%d)", v);
7367 return -EINVAL;
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07007368 }
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07007369
7370 pTargetApBssid[0] = hdd_parse_hex(macAddress[0]) << 4 | hdd_parse_hex(macAddress[1]);
7371 pTargetApBssid[1] = hdd_parse_hex(macAddress[3]) << 4 | hdd_parse_hex(macAddress[4]);
7372 pTargetApBssid[2] = hdd_parse_hex(macAddress[6]) << 4 | hdd_parse_hex(macAddress[7]);
7373 pTargetApBssid[3] = hdd_parse_hex(macAddress[9]) << 4 | hdd_parse_hex(macAddress[10]);
7374 pTargetApBssid[4] = hdd_parse_hex(macAddress[12]) << 4 | hdd_parse_hex(macAddress[13]);
7375 pTargetApBssid[5] = hdd_parse_hex(macAddress[15]) << 4 | hdd_parse_hex(macAddress[16]);
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07007376
7377 /* point to the next argument */
7378 inPtr = strnchr(inPtr, strlen(inPtr), SPACE_ASCII_VALUE);
7379 /*no argument after the command*/
7380 if (NULL == inPtr) return -EINVAL;
7381
7382 /*removing empty spaces*/
7383 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
7384
7385 /*no argument followed by spaces*/
7386 if ('\0' == *inPtr)
7387 {
7388 return -EINVAL;
7389 }
7390
7391 /*getting the next argument ie the channel number */
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08007392 v = sscanf(inPtr, "%31s ", tempBuf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07007393 if (1 != v) return -EINVAL;
7394
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07007395 v = kstrtos32(tempBuf, 10, &tempInt);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07007396 if ((v < 0) ||
Padma, Santhosh Kumar0fa809b2014-11-13 14:56:56 +05307397 (tempInt < 0) ||
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07007398 (tempInt > WNI_CFG_CURRENT_CHANNEL_STAMAX))
7399 {
7400 return -EINVAL;
7401 }
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07007402
7403 *pChannel = tempInt;
7404 return VOS_STATUS_SUCCESS;
7405}
7406
7407#endif
7408
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08007409#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07007410/**---------------------------------------------------------------------------
7411
7412 \brief hdd_parse_get_cckm_ie() - HDD Parse and fetch the CCKM IE
7413
7414 This function parses the SETCCKM IE command
7415 SETCCKMIE<space><ie data>
7416
7417 \param - pValue Pointer to input data
7418 \param - pCckmIe Pointer to output cckm Ie
7419 \param - pCckmIeLen Pointer to output cckm ie length
7420
7421 \return - 0 for success non-zero for failure
7422
7423 --------------------------------------------------------------------------*/
7424VOS_STATUS hdd_parse_get_cckm_ie(tANI_U8 *pValue, tANI_U8 **pCckmIe,
7425 tANI_U8 *pCckmIeLen)
7426{
7427 tANI_U8 *inPtr = pValue;
7428 tANI_U8 *dataEnd;
7429 int j = 0;
7430 int i = 0;
7431 tANI_U8 tempByte = 0;
7432
7433 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
7434 /*no argument after the command*/
7435 if (NULL == inPtr)
7436 {
7437 return -EINVAL;
7438 }
7439
7440 /*no space after the command*/
7441 else if (SPACE_ASCII_VALUE != *inPtr)
7442 {
7443 return -EINVAL;
7444 }
7445
7446 /*removing empty spaces*/
7447 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
7448
7449 /*no argument followed by spaces*/
7450 if ('\0' == *inPtr)
7451 {
7452 return -EINVAL;
7453 }
7454
7455 /* find the length of data */
7456 dataEnd = inPtr;
7457 while(('\0' != *dataEnd) )
7458 {
7459 dataEnd++;
7460 ++(*pCckmIeLen);
7461 }
7462 if ( *pCckmIeLen <= 0) return -EINVAL;
7463
7464 /* Allocate the number of bytes based on the number of input characters
7465 whether it is even or odd.
7466 if the number of input characters are even, then we need N/2 byte.
7467 if the number of input characters are odd, then we need do (N+1)/2 to
7468 compensate rounding off.
7469 For example, if N = 18, then (18 + 1)/2 = 9 bytes are enough.
7470 If N = 19, then we need 10 bytes, hence (19 + 1)/2 = 10 bytes */
7471 *pCckmIe = vos_mem_malloc((*pCckmIeLen + 1)/2);
7472 if (NULL == *pCckmIe)
7473 {
7474 hddLog(VOS_TRACE_LEVEL_FATAL,
7475 "%s: vos_mem_alloc failed ", __func__);
7476 return -EINVAL;
7477 }
7478 vos_mem_zero(*pCckmIe, (*pCckmIeLen + 1)/2);
7479 /* the buffer received from the upper layer is character buffer,
7480 we need to prepare the buffer taking 2 characters in to a U8 hex decimal number
7481 for example 7f0000f0...form a buffer to contain 7f in 0th location, 00 in 1st
7482 and f0 in 3rd location */
7483 for (i = 0, j = 0; j < *pCckmIeLen; j += 2)
7484 {
7485 tempByte = (hdd_parse_hex(inPtr[j]) << 4) | (hdd_parse_hex(inPtr[j + 1]));
7486 (*pCckmIe)[i++] = tempByte;
7487 }
7488 *pCckmIeLen = i;
7489
7490 return VOS_STATUS_SUCCESS;
7491}
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08007492#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07007493
Jeff Johnson295189b2012-06-20 16:38:30 -07007494/**---------------------------------------------------------------------------
7495
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07007496 \brief hdd_is_valid_mac_address() - Validate MAC address
7497
7498 This function validates whether the given MAC address is valid or not
7499 Expected MAC address is of the format XX:XX:XX:XX:XX:XX
7500 where X is the hexa decimal digit character and separated by ':'
7501 This algorithm works even if MAC address is not separated by ':'
7502
7503 This code checks given input string mac contains exactly 12 hexadecimal digits.
7504 and a separator colon : appears in the input string only after
7505 an even number of hex digits.
7506
7507 \param - pMacAddr pointer to the input MAC address
7508 \return - 1 for valid and 0 for invalid
7509
7510 --------------------------------------------------------------------------*/
7511
7512v_BOOL_t hdd_is_valid_mac_address(const tANI_U8 *pMacAddr)
7513{
7514 int xdigit = 0;
7515 int separator = 0;
7516 while (*pMacAddr)
7517 {
7518 if (isxdigit(*pMacAddr))
7519 {
7520 xdigit++;
7521 }
7522 else if (':' == *pMacAddr)
7523 {
7524 if (0 == xdigit || ((xdigit / 2) - 1) != separator)
7525 break;
7526
7527 ++separator;
7528 }
7529 else
7530 {
7531 separator = -1;
7532 /* Invalid MAC found */
7533 return 0;
7534 }
7535 ++pMacAddr;
7536 }
7537 return (xdigit == 12 && (separator == 5 || separator == 0));
7538}
7539
7540/**---------------------------------------------------------------------------
7541
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05307542 \brief __hdd_open() - HDD Open function
Jeff Johnson295189b2012-06-20 16:38:30 -07007543
7544 \param - dev Pointer to net_device structure
7545
7546 \return - 0 for success non-zero for failure
7547
7548 --------------------------------------------------------------------------*/
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05307549int __hdd_open(struct net_device *dev)
Jeff Johnson295189b2012-06-20 16:38:30 -07007550{
7551 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
7552 hdd_context_t *pHddCtx;
7553 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7554 VOS_STATUS status;
7555 v_BOOL_t in_standby = TRUE;
7556
7557 if (NULL == pAdapter)
7558 {
7559 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Agarwal Ashish971c2882013-10-30 20:11:12 +05307560 "%s: pAdapter is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007561 return -ENODEV;
7562 }
7563
7564 pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307565 MTRACE(vos_trace(VOS_MODULE_ID_HDD, TRACE_CODE_HDD_OPEN_REQUEST,
7566 pAdapter->sessionId, pAdapter->device_mode));
Jeff Johnson295189b2012-06-20 16:38:30 -07007567 if (NULL == pHddCtx)
7568 {
7569 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007570 "%s: HDD context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007571 return -ENODEV;
7572 }
7573
7574 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7575 while ( (NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status) )
7576 {
Jeff Johnson6a81ca42013-04-05 10:37:08 -07007577 if (test_bit(DEVICE_IFACE_OPENED, &pAdapterNode->pAdapter->event_flags))
7578 {
7579 hddLog(VOS_TRACE_LEVEL_INFO, "%s: chip already out of standby",
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05307580 __func__);
Jeff Johnson6a81ca42013-04-05 10:37:08 -07007581 in_standby = FALSE;
7582 break;
7583 }
7584 else
7585 {
7586 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7587 pAdapterNode = pNext;
7588 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007589 }
7590
7591 if (TRUE == in_standby)
7592 {
7593 if (VOS_STATUS_SUCCESS != wlan_hdd_exit_lowpower(pHddCtx, pAdapter))
7594 {
7595 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Failed to bring "
7596 "wlan out of power save", __func__);
7597 return -EINVAL;
7598 }
7599 }
7600
Jeff Johnson6a81ca42013-04-05 10:37:08 -07007601 set_bit(DEVICE_IFACE_OPENED, &pAdapter->event_flags);
Jeff Johnson295189b2012-06-20 16:38:30 -07007602 if (hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter)))
7603 {
7604 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007605 "%s: Enabling Tx Queues", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007606 /* Enable TX queues only when we are connected */
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +05307607 hddLog(VOS_TRACE_LEVEL_INFO, FL("Enabling queues"));
Jeff Johnson295189b2012-06-20 16:38:30 -07007608 netif_tx_start_all_queues(dev);
7609 }
7610
7611 return 0;
7612}
7613
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05307614/**---------------------------------------------------------------------------
7615
7616 \brief hdd_open() - Wrapper function for __hdd_open to protect it from SSR
7617
7618 This is called in response to ifconfig up
7619
7620 \param - dev Pointer to net_device structure
7621
7622 \return - 0 for success non-zero for failure
7623
7624 --------------------------------------------------------------------------*/
7625int hdd_open(struct net_device *dev)
7626{
7627 int ret;
7628
7629 vos_ssr_protect(__func__);
7630 ret = __hdd_open(dev);
7631 vos_ssr_unprotect(__func__);
7632
7633 return ret;
7634}
7635
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05307636int __hdd_mon_open (struct net_device *dev)
Jeff Johnson295189b2012-06-20 16:38:30 -07007637{
7638 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +05307639 hdd_adapter_t *sta_adapter;
7640 hdd_context_t *hdd_ctx;
Jeff Johnson295189b2012-06-20 16:38:30 -07007641
7642 if(pAdapter == NULL) {
7643 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007644 "%s: HDD adapter context is Null", __func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08007645 return -EINVAL;
Jeff Johnson295189b2012-06-20 16:38:30 -07007646 }
7647
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +05307648 if (vos_get_concurrency_mode() != VOS_STA_MON)
7649 return 0;
7650
7651 hdd_ctx = WLAN_HDD_GET_CTX(pAdapter);
7652 if (wlan_hdd_validate_context(hdd_ctx))
7653 return -EINVAL;
7654
7655 sta_adapter = hdd_get_adapter(hdd_ctx, WLAN_HDD_INFRA_STATION);
7656 if (!sta_adapter) {
7657 hddLog(LOGE, FL("No valid STA interface"));
7658 return -EINVAL;
7659 }
7660
7661 if (!test_bit(DEVICE_IFACE_OPENED, &sta_adapter->event_flags)) {
7662 hddLog(LOGE, FL("STA Interface is not OPENED"));
7663 return -EINVAL;
7664 }
7665
7666 set_bit(DEVICE_IFACE_OPENED, &pAdapter->event_flags);
7667
Jeff Johnson295189b2012-06-20 16:38:30 -07007668 return 0;
7669}
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05307670
7671int hdd_mon_open (struct net_device *dev)
7672{
7673 int ret;
7674
7675 vos_ssr_protect(__func__);
7676 ret = __hdd_mon_open(dev);
7677 vos_ssr_unprotect(__func__);
7678
7679 return ret;
7680}
7681
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +05307682int __hdd_mon_stop (struct net_device *dev)
7683{
7684 hdd_adapter_t *mon_adapter = WLAN_HDD_GET_PRIV_PTR(dev);
7685 hdd_context_t *hdd_ctx;
7686
7687 if (vos_get_concurrency_mode() != VOS_STA_MON)
7688 return 0;
7689
7690 if(!mon_adapter) {
7691 hddLog(LOGE, FL("HDD adapter is Null"));
7692 return -EINVAL;
7693 }
7694
7695 hdd_ctx = WLAN_HDD_GET_CTX(mon_adapter);
7696 if (wlan_hdd_validate_context(hdd_ctx))
7697 return -EINVAL;
7698
7699 if (!test_bit(DEVICE_IFACE_OPENED, &mon_adapter->event_flags)) {
7700 hddLog(LOGE, FL("NETDEV Interface is not OPENED"));
7701 return -ENODEV;
7702 }
7703
7704 clear_bit(DEVICE_IFACE_OPENED, &mon_adapter->event_flags);
7705 hdd_stop_adapter(hdd_ctx, mon_adapter, VOS_FALSE);
7706
7707 return 0;
7708}
7709
Katya Nigame7b69a82015-04-28 15:24:06 +05307710int hdd_mon_stop(struct net_device *dev)
7711{
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +05307712 int ret;
7713
7714 vos_ssr_protect(__func__);
7715 ret = __hdd_mon_stop(dev);
7716 vos_ssr_unprotect(__func__);
7717
7718 return ret;
Katya Nigame7b69a82015-04-28 15:24:06 +05307719}
7720
Jeff Johnson295189b2012-06-20 16:38:30 -07007721/**---------------------------------------------------------------------------
7722
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05307723 \brief __hdd_stop() - HDD stop function
Jeff Johnson295189b2012-06-20 16:38:30 -07007724
7725 \param - dev Pointer to net_device structure
7726
7727 \return - 0 for success non-zero for failure
7728
7729 --------------------------------------------------------------------------*/
7730
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05307731int __hdd_stop (struct net_device *dev)
Jeff Johnson295189b2012-06-20 16:38:30 -07007732{
Vinay Krishna Eranna90f43532014-10-27 16:45:54 +05307733 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07007734 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
7735 hdd_context_t *pHddCtx;
7736 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7737 VOS_STATUS status;
7738 v_BOOL_t enter_standby = TRUE;
7739
7740 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07007741 if (NULL == pAdapter)
7742 {
7743 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Agarwal Ashish971c2882013-10-30 20:11:12 +05307744 "%s: pAdapter is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007745 return -ENODEV;
7746 }
Sachin Ahuja9b4958f2015-01-15 21:37:00 +05307747 MTRACE(vos_trace(VOS_MODULE_ID_HDD, TRACE_CODE_HDD_STOP_REQUEST,
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307748 pAdapter->sessionId, pAdapter->device_mode));
Vinay Krishna Eranna90f43532014-10-27 16:45:54 +05307749
7750 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7751 ret = wlan_hdd_validate_context(pHddCtx);
7752 if (ret)
Jeff Johnson295189b2012-06-20 16:38:30 -07007753 {
Vinay Krishna Eranna90f43532014-10-27 16:45:54 +05307754 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07007755 }
7756
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05307757 /* Nothing to be done if the interface is not opened */
7758 if (VOS_FALSE == test_bit(DEVICE_IFACE_OPENED, &pAdapter->event_flags))
7759 {
7760 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7761 "%s: NETDEV Interface is not OPENED", __func__);
7762 return -ENODEV;
7763 }
7764
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +05307765 if (pHddCtx->concurrency_mode == VOS_STA_MON) {
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +05307766 /*
Rajeev Kumar Sirasanagandlaa74e1222018-01-09 17:38:55 +05307767 * In STA + Monitor mode concurrency, no point in running
7768 * capture on monitor interface, when STA interface is stopped
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +05307769 */
Rajeev Kumar Sirasanagandlaa74e1222018-01-09 17:38:55 +05307770 wlan_hdd_stop_mon(pHddCtx, true);
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +05307771 }
7772
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05307773 /* Make sure the interface is marked as closed */
Jeff Johnson6a81ca42013-04-05 10:37:08 -07007774 clear_bit(DEVICE_IFACE_OPENED, &pAdapter->event_flags);
Jeff Johnson295189b2012-06-20 16:38:30 -07007775 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Disabling OS Tx queues", __func__);
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05307776
7777 /* Disable TX on the interface, after this hard_start_xmit() will not
7778 * be called on that interface
7779 */
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +05307780 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Jeff Johnson295189b2012-06-20 16:38:30 -07007781 netif_tx_disable(pAdapter->dev);
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05307782
7783 /* Mark the interface status as "down" for outside world */
Jeff Johnson295189b2012-06-20 16:38:30 -07007784 netif_carrier_off(pAdapter->dev);
7785
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05307786 /* The interface is marked as down for outside world (aka kernel)
7787 * But the driver is pretty much alive inside. The driver needs to
7788 * tear down the existing connection on the netdev (session)
7789 * cleanup the data pipes and wait until the control plane is stabilized
7790 * for this interface. The call also needs to wait until the above
7791 * mentioned actions are completed before returning to the caller.
7792 * Notice that the hdd_stop_adapter is requested not to close the session
7793 * That is intentional to be able to scan if it is a STA/P2P interface
7794 */
7795 hdd_stop_adapter(pHddCtx, pAdapter, VOS_FALSE);
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05307796#ifdef FEATURE_WLAN_TDLS
7797 mutex_lock(&pHddCtx->tdls_lock);
7798#endif
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05307799 /* DeInit the adapter. This ensures datapath cleanup as well */
c_hpothu002231a2015-02-05 14:58:51 +05307800 hdd_deinit_adapter(pHddCtx, pAdapter, TRUE);
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05307801#ifdef FEATURE_WLAN_TDLS
7802 mutex_unlock(&pHddCtx->tdls_lock);
7803#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007804 /* SoftAP ifaces should never go in power save mode
7805 making sure same here. */
7806 if ( (WLAN_HDD_SOFTAP == pAdapter->device_mode )
Jeff Johnson295189b2012-06-20 16:38:30 -07007807 || (WLAN_HDD_P2P_GO == pAdapter->device_mode )
Jeff Johnson295189b2012-06-20 16:38:30 -07007808 )
7809 {
7810 /* SoftAP mode, so return from here */
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307811 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
7812 "%s: In SAP MODE", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007813 EXIT();
7814 return 0;
7815 }
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05307816 /* Find if any iface is up. If any iface is up then can't put device to
7817 * sleep/power save mode
7818 */
Jeff Johnson295189b2012-06-20 16:38:30 -07007819 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7820 while ( (NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status) )
7821 {
Jeff Johnson6a81ca42013-04-05 10:37:08 -07007822 if (test_bit(DEVICE_IFACE_OPENED, &pAdapterNode->pAdapter->event_flags))
7823 {
7824 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Still other ifaces are up cannot "
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05307825 "put device to sleep", __func__);
Jeff Johnson6a81ca42013-04-05 10:37:08 -07007826 enter_standby = FALSE;
7827 break;
7828 }
7829 else
7830 {
7831 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7832 pAdapterNode = pNext;
7833 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007834 }
7835
7836 if (TRUE == enter_standby)
7837 {
7838 hddLog(VOS_TRACE_LEVEL_INFO, "%s: All Interfaces are Down "
7839 "entering standby", __func__);
7840 if (VOS_STATUS_SUCCESS != wlan_hdd_enter_lowpower(pHddCtx))
7841 {
7842 /*log and return success*/
7843 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Failed to put "
7844 "wlan in power save", __func__);
7845 }
7846 }
7847
7848 EXIT();
7849 return 0;
7850}
7851
7852/**---------------------------------------------------------------------------
7853
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05307854 \brief hdd_stop() - wrapper_function for __hdd_stop to protect it from SSR
Jeff Johnson295189b2012-06-20 16:38:30 -07007855
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05307856 This is called in response to ifconfig down
7857
7858 \param - dev Pointer to net_device structure
7859
7860 \return - 0 for success non-zero for failure
7861-----------------------------------------------------------------------------*/
7862int hdd_stop (struct net_device *dev)
7863{
7864 int ret;
7865
7866 vos_ssr_protect(__func__);
7867 ret = __hdd_stop(dev);
7868 vos_ssr_unprotect(__func__);
7869
7870 return ret;
7871}
7872
7873/**---------------------------------------------------------------------------
7874
7875 \brief __hdd_uninit() - HDD uninit function
Jeff Johnson295189b2012-06-20 16:38:30 -07007876
7877 \param - dev Pointer to net_device structure
7878
7879 \return - void
7880
7881 --------------------------------------------------------------------------*/
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05307882static void __hdd_uninit (struct net_device *dev)
Jeff Johnson295189b2012-06-20 16:38:30 -07007883{
7884 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05307885 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07007886 ENTER();
7887
7888 do
7889 {
7890 if (NULL == pAdapter)
7891 {
7892 hddLog(VOS_TRACE_LEVEL_FATAL,
7893 "%s: NULL pAdapter", __func__);
7894 break;
7895 }
7896
7897 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
7898 {
7899 hddLog(VOS_TRACE_LEVEL_FATAL,
7900 "%s: Invalid magic", __func__);
7901 break;
7902 }
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05307903 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7904 if (NULL == pHddCtx)
Jeff Johnson295189b2012-06-20 16:38:30 -07007905 {
7906 hddLog(VOS_TRACE_LEVEL_FATAL,
7907 "%s: NULL pHddCtx", __func__);
7908 break;
7909 }
7910
7911 if (dev != pAdapter->dev)
7912 {
7913 hddLog(VOS_TRACE_LEVEL_FATAL,
7914 "%s: Invalid device reference", __func__);
7915 /* we haven't validated all cases so let this go for now */
7916 }
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05307917#ifdef FEATURE_WLAN_TDLS
7918 mutex_lock(&pHddCtx->tdls_lock);
7919#endif
c_hpothu002231a2015-02-05 14:58:51 +05307920 hdd_deinit_adapter(pHddCtx, pAdapter, TRUE);
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05307921#ifdef FEATURE_WLAN_TDLS
7922 mutex_unlock(&pHddCtx->tdls_lock);
7923#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007924
7925 /* after uninit our adapter structure will no longer be valid */
7926 pAdapter->dev = NULL;
7927 pAdapter->magic = 0;
Manjeet Singh47ee8472016-04-11 11:57:18 +05307928 pAdapter->pHddCtx = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07007929 } while (0);
7930
7931 EXIT();
7932}
7933
7934/**---------------------------------------------------------------------------
7935
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05307936 \brief hdd_uninit() - Wrapper function to protect __hdd_uninit from SSR
7937
7938 This is called during the netdev unregister to uninitialize all data
7939associated with the device
7940
7941 \param - dev Pointer to net_device structure
7942
7943 \return - void
7944
7945 --------------------------------------------------------------------------*/
7946static void hdd_uninit (struct net_device *dev)
7947{
7948 vos_ssr_protect(__func__);
7949 __hdd_uninit(dev);
7950 vos_ssr_unprotect(__func__);
7951}
7952
7953/**---------------------------------------------------------------------------
7954
Jeff Johnson295189b2012-06-20 16:38:30 -07007955 \brief hdd_release_firmware() -
7956
7957 This function calls the release firmware API to free the firmware buffer.
7958
7959 \param - pFileName Pointer to the File Name.
7960 pCtx - Pointer to the adapter .
7961
7962
7963 \return - 0 for success, non zero for failure
7964
7965 --------------------------------------------------------------------------*/
7966
7967VOS_STATUS hdd_release_firmware(char *pFileName,v_VOID_t *pCtx)
7968{
7969 VOS_STATUS status = VOS_STATUS_SUCCESS;
7970 hdd_context_t *pHddCtx = (hdd_context_t*)pCtx;
7971 ENTER();
7972
7973
7974 if (!strcmp(WLAN_FW_FILE, pFileName)) {
7975
7976 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,"%s: Loaded firmware file is %s",__func__,pFileName);
7977
7978 if(pHddCtx->fw) {
7979 release_firmware(pHddCtx->fw);
7980 pHddCtx->fw = NULL;
7981 }
7982 else
7983 status = VOS_STATUS_E_FAILURE;
7984 }
7985 else if (!strcmp(WLAN_NV_FILE,pFileName)) {
7986 if(pHddCtx->nv) {
7987 release_firmware(pHddCtx->nv);
7988 pHddCtx->nv = NULL;
7989 }
7990 else
7991 status = VOS_STATUS_E_FAILURE;
7992
7993 }
7994
7995 EXIT();
7996 return status;
7997}
7998
7999/**---------------------------------------------------------------------------
8000
8001 \brief hdd_request_firmware() -
8002
8003 This function reads the firmware file using the request firmware
8004 API and returns the the firmware data and the firmware file size.
8005
8006 \param - pfileName - Pointer to the file name.
8007 - pCtx - Pointer to the adapter .
8008 - ppfw_data - Pointer to the pointer of the firmware data.
8009 - pSize - Pointer to the file size.
8010
8011 \return - VOS_STATUS_SUCCESS for success, VOS_STATUS_E_FAILURE for failure
8012
8013 --------------------------------------------------------------------------*/
8014
8015
8016VOS_STATUS hdd_request_firmware(char *pfileName,v_VOID_t *pCtx,v_VOID_t **ppfw_data, v_SIZE_t *pSize)
8017{
8018 int status;
8019 VOS_STATUS retval = VOS_STATUS_SUCCESS;
8020 hdd_context_t *pHddCtx = (hdd_context_t*)pCtx;
8021 ENTER();
8022
8023 if( (!strcmp(WLAN_FW_FILE, pfileName)) ) {
8024
8025 status = request_firmware(&pHddCtx->fw, pfileName, pHddCtx->parent_dev);
8026
8027 if(status || !pHddCtx->fw || !pHddCtx->fw->data) {
8028 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Firmware %s download failed",
8029 __func__, pfileName);
8030 retval = VOS_STATUS_E_FAILURE;
8031 }
8032
8033 else {
8034 *ppfw_data = (v_VOID_t *)pHddCtx->fw->data;
8035 *pSize = pHddCtx->fw->size;
8036 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Firmware size = %d",
8037 __func__, *pSize);
8038 }
8039 }
8040 else if(!strcmp(WLAN_NV_FILE, pfileName)) {
8041
8042 status = request_firmware(&pHddCtx->nv, pfileName, pHddCtx->parent_dev);
8043
8044 if(status || !pHddCtx->nv || !pHddCtx->nv->data) {
8045 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: nv %s download failed",
8046 __func__, pfileName);
8047 retval = VOS_STATUS_E_FAILURE;
8048 }
8049
8050 else {
8051 *ppfw_data = (v_VOID_t *)pHddCtx->nv->data;
8052 *pSize = pHddCtx->nv->size;
8053 hddLog(VOS_TRACE_LEVEL_INFO, "%s: nv file size = %d",
8054 __func__, *pSize);
8055 }
8056 }
8057
8058 EXIT();
8059 return retval;
8060}
8061/**---------------------------------------------------------------------------
8062 \brief hdd_full_pwr_cbk() - HDD full power callbackfunction
8063
8064 This is the function invoked by SME to inform the result of a full power
8065 request issued by HDD
8066
8067 \param - callbackcontext - Pointer to cookie
8068 status - result of request
8069
8070 \return - None
8071
8072--------------------------------------------------------------------------*/
8073void hdd_full_pwr_cbk(void *callbackContext, eHalStatus status)
8074{
8075 hdd_context_t *pHddCtx = (hdd_context_t*)callbackContext;
8076
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07008077 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,"HDD full Power callback status = %d", status);
Jeff Johnson295189b2012-06-20 16:38:30 -07008078 if(&pHddCtx->full_pwr_comp_var)
8079 {
8080 complete(&pHddCtx->full_pwr_comp_var);
8081 }
8082}
8083
Abhishek Singh00b71972016-01-07 10:51:04 +05308084#ifdef WLAN_FEATURE_RMC
8085static void hdd_tx_fail_ind_callback(v_U8_t *MacAddr, v_U8_t seqNo)
8086{
8087 int payload_len;
8088 struct sk_buff *skb;
8089 struct nlmsghdr *nlh;
8090 v_U8_t *data;
8091
8092 payload_len = ETH_ALEN;
8093
8094 if (0 == cesium_pid)
8095 {
8096 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: cesium process not registered",
8097 __func__);
8098 return;
8099 }
8100
8101 if ((skb = nlmsg_new(payload_len,GFP_ATOMIC)) == NULL)
8102 {
8103 hddLog(VOS_TRACE_LEVEL_ERROR,
8104 "%s: nlmsg_new() failed for msg size[%d]",
8105 __func__, NLMSG_SPACE(payload_len));
8106 return;
8107 }
8108
8109 nlh = nlmsg_put(skb, cesium_pid, seqNo, 0, payload_len, NLM_F_REQUEST);
8110
8111 if (NULL == nlh)
8112 {
8113 hddLog(VOS_TRACE_LEVEL_ERROR,
8114 "%s: nlmsg_put() failed for msg size[%d]",
8115 __func__, NLMSG_SPACE(payload_len));
8116
8117 kfree_skb(skb);
8118 return;
8119 }
8120
8121 data = nlmsg_data(nlh);
8122 memcpy(data, MacAddr, ETH_ALEN);
8123
8124 if (nlmsg_unicast(cesium_nl_srv_sock, skb, cesium_pid) < 0)
8125 {
8126 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: nlmsg_unicast() failed for msg size[%d]",
8127 __func__, NLMSG_SPACE(payload_len));
8128 }
8129
8130 return;
8131}
8132
8133/**---------------------------------------------------------------------------
8134 \brief hdd_ParseuserParams - return a pointer to the next argument
8135
8136 \return - status
8137
8138--------------------------------------------------------------------------*/
8139static int hdd_ParseUserParams(tANI_U8 *pValue, tANI_U8 **ppArg)
8140{
8141 tANI_U8 *pVal;
8142
8143 pVal = strchr(pValue, ' ');
8144
8145 if (NULL == pVal)
8146 {
8147 /* no argument remains */
8148 return -EINVAL;
8149 }
8150 else if (SPACE_ASCII_VALUE != *pVal)
8151 {
8152 /* no space after the current argument */
8153 return -EINVAL;
8154 }
8155
8156 pVal++;
8157
8158 /* remove empty spaces */
8159 while ((SPACE_ASCII_VALUE == *pVal) && ('\0' != *pVal))
8160 {
8161 pVal++;
8162 }
8163
8164 /* no argument followed by spaces */
8165 if ('\0' == *pVal)
8166 {
8167 return -EINVAL;
8168 }
8169
8170 *ppArg = pVal;
8171
8172 return 0;
8173}
8174
8175/**----------------------------------------------------------------------------
8176 \brief hdd_ParseIBSSTXFailEventParams - Parse params for SETIBSSTXFAILEVENT
8177
8178 \return - status
8179
8180------------------------------------------------------------------------------*/
8181static int hdd_ParseIBSSTXFailEventParams(tANI_U8 *pValue,
8182 tANI_U8 *tx_fail_count,
8183 tANI_U16 *pid)
8184{
8185 tANI_U8 *param = NULL;
8186 int ret;
8187
8188 ret = hdd_ParseUserParams(pValue, &param);
8189
8190 if (0 == ret && NULL != param)
8191 {
8192 if (1 != sscanf(param, "%hhu", tx_fail_count))
8193 {
8194 ret = -EINVAL;
8195 goto done;
8196 }
8197 }
8198 else
8199 {
8200 goto done;
8201 }
8202
8203 if (0 == *tx_fail_count)
8204 {
8205 *pid = 0;
8206 goto done;
8207 }
8208
8209 pValue = param;
8210 pValue++;
8211
8212 ret = hdd_ParseUserParams(pValue, &param);
8213
8214 if (0 == ret)
8215 {
8216 if (1 != sscanf(param, "%hu", pid))
8217 {
8218 ret = -EINVAL;
8219 goto done;
8220 }
8221 }
8222 else
8223 {
8224 goto done;
8225 }
8226
8227done:
8228 return ret;
8229}
8230
8231static int hdd_open_cesium_nl_sock()
8232{
8233#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
8234 struct netlink_kernel_cfg cfg = {
8235 .groups = WLAN_NLINK_MCAST_GRP_ID,
8236 .input = NULL
8237 };
8238#endif
8239 int ret = 0;
8240
8241#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
8242 cesium_nl_srv_sock = netlink_kernel_create(&init_net, WLAN_NLINK_CESIUM,
8243#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,7,0))
8244 THIS_MODULE,
8245#endif
8246 &cfg);
8247#else
8248 cesium_nl_srv_sock = netlink_kernel_create(&init_net, WLAN_NLINK_CESIUM,
8249 WLAN_NLINK_MCAST_GRP_ID, NULL, NULL, THIS_MODULE);
8250#endif
8251
8252 if (cesium_nl_srv_sock == NULL)
8253 {
8254 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8255 "NLINK: cesium netlink_kernel_create failed");
8256 ret = -ECONNREFUSED;
8257 }
8258
8259 return ret;
8260}
8261
8262static void hdd_close_cesium_nl_sock()
8263{
8264 if (NULL != cesium_nl_srv_sock)
8265 {
8266 netlink_kernel_release(cesium_nl_srv_sock);
8267 cesium_nl_srv_sock = NULL;
8268 }
8269}
8270#endif /* WLAN_FEATURE_RMC */
Jeff Johnson295189b2012-06-20 16:38:30 -07008271/**---------------------------------------------------------------------------
8272
8273 \brief hdd_req_bmps_cbk() - HDD Request BMPS callback function
8274
8275 This is the function invoked by SME to inform the result of BMPS
8276 request issued by HDD
8277
8278 \param - callbackcontext - Pointer to cookie
8279 status - result of request
8280
8281 \return - None
8282
8283--------------------------------------------------------------------------*/
8284void hdd_req_bmps_cbk(void *callbackContext, eHalStatus status)
8285{
8286
8287 struct completion *completion_var = (struct completion*) callbackContext;
8288
Arif Hussain6d2a3322013-11-17 19:50:10 -08008289 hddLog(VOS_TRACE_LEVEL_ERROR, "HDD BMPS request Callback, status = %d", status);
Jeff Johnson295189b2012-06-20 16:38:30 -07008290 if(completion_var != NULL)
8291 {
8292 complete(completion_var);
8293 }
8294}
8295
8296/**---------------------------------------------------------------------------
8297
8298 \brief hdd_get_cfg_file_size() -
8299
8300 This function reads the configuration file using the request firmware
8301 API and returns the configuration file size.
8302
8303 \param - pCtx - Pointer to the adapter .
8304 - pFileName - Pointer to the file name.
8305 - pBufSize - Pointer to the buffer size.
8306
8307 \return - 0 for success, non zero for failure
8308
8309 --------------------------------------------------------------------------*/
8310
8311VOS_STATUS hdd_get_cfg_file_size(v_VOID_t *pCtx, char *pFileName, v_SIZE_t *pBufSize)
8312{
8313 int status;
8314 hdd_context_t *pHddCtx = (hdd_context_t*)pCtx;
8315
8316 ENTER();
8317
8318 status = request_firmware(&pHddCtx->fw, pFileName, pHddCtx->parent_dev);
8319
8320 if(status || !pHddCtx->fw || !pHddCtx->fw->data) {
8321 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: CFG download failed",__func__);
8322 status = VOS_STATUS_E_FAILURE;
8323 }
8324 else {
8325 *pBufSize = pHddCtx->fw->size;
8326 hddLog(VOS_TRACE_LEVEL_INFO, "%s: CFG size = %d", __func__, *pBufSize);
8327 release_firmware(pHddCtx->fw);
8328 pHddCtx->fw = NULL;
8329 }
8330
8331 EXIT();
8332 return VOS_STATUS_SUCCESS;
8333}
8334
8335/**---------------------------------------------------------------------------
8336
8337 \brief hdd_read_cfg_file() -
8338
8339 This function reads the configuration file using the request firmware
8340 API and returns the cfg data and the buffer size of the configuration file.
8341
8342 \param - pCtx - Pointer to the adapter .
8343 - pFileName - Pointer to the file name.
8344 - pBuffer - Pointer to the data buffer.
8345 - pBufSize - Pointer to the buffer size.
8346
8347 \return - 0 for success, non zero for failure
8348
8349 --------------------------------------------------------------------------*/
8350
8351VOS_STATUS hdd_read_cfg_file(v_VOID_t *pCtx, char *pFileName,
8352 v_VOID_t *pBuffer, v_SIZE_t *pBufSize)
8353{
8354 int status;
8355 hdd_context_t *pHddCtx = (hdd_context_t*)pCtx;
8356
8357 ENTER();
8358
8359 status = request_firmware(&pHddCtx->fw, pFileName, pHddCtx->parent_dev);
8360
8361 if(status || !pHddCtx->fw || !pHddCtx->fw->data) {
8362 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: CFG download failed",__func__);
8363 return VOS_STATUS_E_FAILURE;
8364 }
8365 else {
8366 if(*pBufSize != pHddCtx->fw->size) {
8367 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Caller sets invalid CFG "
8368 "file size", __func__);
8369 release_firmware(pHddCtx->fw);
8370 pHddCtx->fw = NULL;
8371 return VOS_STATUS_E_FAILURE;
8372 }
8373 else {
8374 if(pBuffer) {
8375 vos_mem_copy(pBuffer,pHddCtx->fw->data,*pBufSize);
8376 }
8377 release_firmware(pHddCtx->fw);
8378 pHddCtx->fw = NULL;
8379 }
8380 }
8381
8382 EXIT();
8383
8384 return VOS_STATUS_SUCCESS;
8385}
8386
8387/**---------------------------------------------------------------------------
8388
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05308389 \brief __hdd_set_mac_address() -
Jeff Johnson295189b2012-06-20 16:38:30 -07008390
8391 This function sets the user specified mac address using
8392 the command ifconfig wlanX hw ether <mac adress>.
8393
8394 \param - dev - Pointer to the net device.
8395 - addr - Pointer to the sockaddr.
8396 \return - 0 for success, non zero for failure
8397
8398 --------------------------------------------------------------------------*/
8399
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05308400static int __hdd_set_mac_address(struct net_device *dev, void *addr)
Jeff Johnson295189b2012-06-20 16:38:30 -07008401{
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05308402 hdd_adapter_t *pAdapter;
8403 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07008404 struct sockaddr *psta_mac_addr = addr;
8405 eHalStatus halStatus = eHAL_STATUS_SUCCESS;
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05308406 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07008407
8408 ENTER();
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05308409 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
8410 if (NULL == pAdapter)
8411 {
8412 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8413 "%s: Adapter is NULL",__func__);
8414 return -EINVAL;
8415 }
8416 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8417 ret = wlan_hdd_validate_context(pHddCtx);
8418 if (0 != ret)
8419 {
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05308420 return ret;
8421 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008422
8423 memcpy(&pAdapter->macAddressCurrent, psta_mac_addr->sa_data, ETH_ALEN);
Jeff Johnson295189b2012-06-20 16:38:30 -07008424 memcpy(dev->dev_addr, psta_mac_addr->sa_data, ETH_ALEN);
8425
8426 EXIT();
8427 return halStatus;
8428}
8429
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05308430/**---------------------------------------------------------------------------
8431
8432 \brief hdd_set_mac_address() -
8433
8434 Wrapper function to protect __hdd_set_mac_address() function from ssr
8435
8436 \param - dev - Pointer to the net device.
8437 - addr - Pointer to the sockaddr.
8438 \return - 0 for success, non zero for failure
8439
8440 --------------------------------------------------------------------------*/
8441static int hdd_set_mac_address(struct net_device *dev, void *addr)
8442{
8443 int ret;
8444
8445 vos_ssr_protect(__func__);
8446 ret = __hdd_set_mac_address(dev, addr);
8447 vos_ssr_unprotect(__func__);
8448
8449 return ret;
8450}
8451
Jeff Johnson295189b2012-06-20 16:38:30 -07008452tANI_U8* wlan_hdd_get_intf_addr(hdd_context_t* pHddCtx)
8453{
8454 int i;
8455 for ( i = 0; i < VOS_MAX_CONCURRENCY_PERSONA; i++)
8456 {
Abhishek Singheb183782014-02-06 13:37:21 +05308457 if( 0 == ((pHddCtx->cfg_ini->intfAddrMask) & (1 << i)) )
Jeff Johnson295189b2012-06-20 16:38:30 -07008458 break;
8459 }
8460
8461 if( VOS_MAX_CONCURRENCY_PERSONA == i)
8462 return NULL;
8463
8464 pHddCtx->cfg_ini->intfAddrMask |= (1 << i);
8465 return &pHddCtx->cfg_ini->intfMacAddr[i].bytes[0];
8466}
8467
8468void wlan_hdd_release_intf_addr(hdd_context_t* pHddCtx, tANI_U8* releaseAddr)
8469{
8470 int i;
8471 for ( i = 0; i < VOS_MAX_CONCURRENCY_PERSONA; i++)
8472 {
8473 if ( !memcmp(releaseAddr, &pHddCtx->cfg_ini->intfMacAddr[i].bytes[0], 6) )
8474 {
8475 pHddCtx->cfg_ini->intfAddrMask &= ~(1 << i);
8476 break;
8477 }
8478 }
8479 return;
8480}
8481
8482#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29))
8483 static struct net_device_ops wlan_drv_ops = {
8484 .ndo_open = hdd_open,
8485 .ndo_stop = hdd_stop,
8486 .ndo_uninit = hdd_uninit,
8487 .ndo_start_xmit = hdd_hard_start_xmit,
8488 .ndo_tx_timeout = hdd_tx_timeout,
8489 .ndo_get_stats = hdd_stats,
8490 .ndo_do_ioctl = hdd_ioctl,
8491 .ndo_set_mac_address = hdd_set_mac_address,
8492 .ndo_select_queue = hdd_select_queue,
8493#ifdef WLAN_FEATURE_PACKET_FILTERING
8494#if (LINUX_VERSION_CODE > KERNEL_VERSION(3,1,0))
8495 .ndo_set_rx_mode = hdd_set_multicast_list,
8496#else
8497 .ndo_set_multicast_list = hdd_set_multicast_list,
8498#endif //LINUX_VERSION_CODE
8499#endif
8500 };
Jeff Johnson295189b2012-06-20 16:38:30 -07008501 static struct net_device_ops wlan_mon_drv_ops = {
8502 .ndo_open = hdd_mon_open,
Katya Nigame7b69a82015-04-28 15:24:06 +05308503 .ndo_stop = hdd_mon_stop,
Jeff Johnson295189b2012-06-20 16:38:30 -07008504 .ndo_uninit = hdd_uninit,
8505 .ndo_start_xmit = hdd_mon_hard_start_xmit,
8506 .ndo_tx_timeout = hdd_tx_timeout,
8507 .ndo_get_stats = hdd_stats,
Katya Nigame7b69a82015-04-28 15:24:06 +05308508 .ndo_do_ioctl = hdd_mon_ioctl,
Jeff Johnson295189b2012-06-20 16:38:30 -07008509 .ndo_set_mac_address = hdd_set_mac_address,
8510 };
Mahesh A Saptasagar305e2632015-03-04 12:57:33 +05308511
Jeff Johnson295189b2012-06-20 16:38:30 -07008512#endif
8513
8514void hdd_set_station_ops( struct net_device *pWlanDev )
8515{
8516#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29))
Jeff Johnson295189b2012-06-20 16:38:30 -07008517 pWlanDev->netdev_ops = &wlan_drv_ops;
8518#else
8519 pWlanDev->open = hdd_open;
8520 pWlanDev->stop = hdd_stop;
8521 pWlanDev->uninit = hdd_uninit;
8522 pWlanDev->hard_start_xmit = NULL;
8523 pWlanDev->tx_timeout = hdd_tx_timeout;
8524 pWlanDev->get_stats = hdd_stats;
8525 pWlanDev->do_ioctl = hdd_ioctl;
Jeff Johnson295189b2012-06-20 16:38:30 -07008526 pWlanDev->set_mac_address = hdd_set_mac_address;
8527#endif
8528}
8529
Katya Nigam1fd24402015-02-16 14:52:19 +05308530void hdd_set_ibss_ops( hdd_adapter_t *pAdapter )
8531{
8532 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29))
8533 wlan_drv_ops.ndo_start_xmit = hdd_ibss_hard_start_xmit;
8534 #else
8535 pAdapter->dev->hard_start_xmit = hdd_ibss_hard_start_xmit;
8536 #endif
8537}
8538
Jeff Johnsoneed415b2013-01-18 16:11:20 -08008539static hdd_adapter_t* hdd_alloc_station_adapter( hdd_context_t *pHddCtx, tSirMacAddr macAddr, const char* name )
Jeff Johnson295189b2012-06-20 16:38:30 -07008540{
8541 struct net_device *pWlanDev = NULL;
8542 hdd_adapter_t *pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07008543 /*
8544 * cfg80211 initialization and registration....
8545 */
Anand N Sunkadc34abbd2015-07-29 09:52:59 +05308546 pWlanDev = alloc_netdev_mq(sizeof( hdd_adapter_t ), name,
8547#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,17,0))
8548 NET_NAME_UNKNOWN,
8549#endif
8550 ether_setup, NUM_TX_QUEUES);
Jeff Johnson295189b2012-06-20 16:38:30 -07008551 if(pWlanDev != NULL)
8552 {
8553
8554 //Save the pointer to the net_device in the HDD adapter
8555 pAdapter = (hdd_adapter_t*) netdev_priv( pWlanDev );
8556
Jeff Johnson295189b2012-06-20 16:38:30 -07008557 vos_mem_zero( pAdapter, sizeof( hdd_adapter_t ) );
8558
8559 pAdapter->dev = pWlanDev;
8560 pAdapter->pHddCtx = pHddCtx;
8561 pAdapter->magic = WLAN_HDD_ADAPTER_MAGIC;
Agarwal Ashish47d18112014-08-04 19:55:07 +05308562 spin_lock_init(&pAdapter->lock_for_active_session);
Jeff Johnson295189b2012-06-20 16:38:30 -07008563
Rajeev79dbe4c2013-10-05 11:03:42 +05308564#ifdef FEATURE_WLAN_BATCH_SCAN
Rajeev79dbe4c2013-10-05 11:03:42 +05308565 pAdapter->pBatchScanRsp = NULL;
8566 pAdapter->numScanList = 0;
Rajeev Kumar20140c12013-10-21 19:39:02 -07008567 pAdapter->batchScanState = eHDD_BATCH_SCAN_STATE_STOPPED;
Kiet Lamaa8e15a2014-02-11 23:30:06 -08008568 pAdapter->prev_batch_id = 0;
Rajeev79dbe4c2013-10-05 11:03:42 +05308569 mutex_init(&pAdapter->hdd_batch_scan_lock);
8570#endif
8571
Jeff Johnson295189b2012-06-20 16:38:30 -07008572 pAdapter->isLinkUpSvcNeeded = FALSE;
8573 pAdapter->higherDtimTransition = eANI_BOOLEAN_TRUE;
8574 //Init the net_device structure
8575 strlcpy(pWlanDev->name, name, IFNAMSIZ);
8576
8577 vos_mem_copy(pWlanDev->dev_addr, (void *)macAddr, sizeof(tSirMacAddr));
8578 vos_mem_copy( pAdapter->macAddressCurrent.bytes, macAddr, sizeof(tSirMacAddr));
8579 pWlanDev->watchdog_timeo = HDD_TX_TIMEOUT;
8580 pWlanDev->hard_header_len += LIBRA_HW_NEEDED_HEADROOM;
8581
8582 hdd_set_station_ops( pAdapter->dev );
8583
8584 pWlanDev->destructor = free_netdev;
Jeff Johnson295189b2012-06-20 16:38:30 -07008585 pWlanDev->ieee80211_ptr = &pAdapter->wdev ;
8586 pAdapter->wdev.wiphy = pHddCtx->wiphy;
8587 pAdapter->wdev.netdev = pWlanDev;
Jeff Johnson295189b2012-06-20 16:38:30 -07008588 /* set pWlanDev's parent to underlying device */
8589 SET_NETDEV_DEV(pWlanDev, pHddCtx->parent_dev);
Kumar Anand82c009f2014-05-29 00:29:42 -07008590
8591 hdd_wmm_init( pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -07008592 }
8593
8594 return pAdapter;
8595}
8596
8597VOS_STATUS hdd_register_interface( hdd_adapter_t *pAdapter, tANI_U8 rtnl_lock_held )
8598{
8599 struct net_device *pWlanDev = pAdapter->dev;
8600 //hdd_station_ctx_t *pHddStaCtx = &pAdapter->sessionCtx.station;
8601 //hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
8602 //eHalStatus halStatus = eHAL_STATUS_SUCCESS;
8603
8604 if( rtnl_lock_held )
8605 {
Madan Mohan Koyyalamudid8ac8662012-11-06 19:04:56 -08008606 if (strnchr(pWlanDev->name, strlen(pWlanDev->name), '%')) {
Jeff Johnson295189b2012-06-20 16:38:30 -07008607 if( dev_alloc_name(pWlanDev, pWlanDev->name) < 0 )
8608 {
8609 hddLog(VOS_TRACE_LEVEL_ERROR,"%s:Failed:dev_alloc_name",__func__);
8610 return VOS_STATUS_E_FAILURE;
8611 }
8612 }
8613 if (register_netdevice(pWlanDev))
8614 {
8615 hddLog(VOS_TRACE_LEVEL_ERROR,"%s:Failed:register_netdev",__func__);
8616 return VOS_STATUS_E_FAILURE;
8617 }
8618 }
8619 else
8620 {
8621 if(register_netdev(pWlanDev))
8622 {
8623 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Failed:register_netdev",__func__);
8624 return VOS_STATUS_E_FAILURE;
8625 }
8626 }
8627 set_bit(NET_DEVICE_REGISTERED, &pAdapter->event_flags);
8628
8629 return VOS_STATUS_SUCCESS;
8630}
8631
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07008632static eHalStatus hdd_smeCloseSessionCallback(void *pContext)
Jeff Johnson295189b2012-06-20 16:38:30 -07008633{
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07008634 hdd_adapter_t *pAdapter = pContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07008635
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07008636 if (NULL == pAdapter)
8637 {
8638 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: NULL pAdapter", __func__);
8639 return eHAL_STATUS_INVALID_PARAMETER;
Jeff Johnson295189b2012-06-20 16:38:30 -07008640 }
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07008641
8642 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
8643 {
8644 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Invalid magic", __func__);
8645 return eHAL_STATUS_NOT_INITIALIZED;
8646 }
8647
8648 clear_bit(SME_SESSION_OPENED, &pAdapter->event_flags);
8649
Sameer Thalappilbee426e2013-10-30 10:30:30 -07008650#ifndef WLAN_OPEN_SOURCE
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07008651 /* need to make sure all of our scheduled work has completed.
8652 * This callback is called from MC thread context, so it is safe to
8653 * to call below flush workqueue API from here.
Sameer Thalappilbee426e2013-10-30 10:30:30 -07008654 *
8655 * Even though this is called from MC thread context, if there is a faulty
8656 * work item in the system, that can hang this call forever. So flushing
8657 * this global work queue is not safe; and now we make sure that
8658 * individual work queues are stopped correctly. But the cancel work queue
8659 * is a GPL only API, so the proprietary version of the driver would still
8660 * rely on the global work queue flush.
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07008661 */
8662 flush_scheduled_work();
Sameer Thalappilbee426e2013-10-30 10:30:30 -07008663#endif
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07008664
8665 /* We can be blocked while waiting for scheduled work to be
8666 * flushed, and the adapter structure can potentially be freed, in
8667 * which case the magic will have been reset. So make sure the
8668 * magic is still good, and hence the adapter structure is still
8669 * valid, before signaling completion */
8670 if (WLAN_HDD_ADAPTER_MAGIC == pAdapter->magic)
8671 {
8672 complete(&pAdapter->session_close_comp_var);
8673 }
8674
Jeff Johnson295189b2012-06-20 16:38:30 -07008675 return eHAL_STATUS_SUCCESS;
8676}
Manjeet Singh47ee8472016-04-11 11:57:18 +05308677/**
8678 * hdd_close_tx_queues() - close tx queues
8679 * @hdd_ctx: hdd global context
8680 *
8681 * Return: None
8682 */
8683static void hdd_close_tx_queues(hdd_context_t *hdd_ctx)
8684{
8685 VOS_STATUS status;
8686 hdd_adapter_t *adapter;
8687 hdd_adapter_list_node_t *adapter_node = NULL, *next_adapter = NULL;
8688 /* Not validating hdd_ctx as it's already done by the caller */
8689 ENTER();
8690 status = hdd_get_front_adapter(hdd_ctx, &adapter_node);
8691 while (NULL != adapter_node && VOS_STATUS_SUCCESS == status) {
8692 adapter = adapter_node->pAdapter;
8693 if (adapter && adapter->dev) {
8694 netif_tx_disable (adapter->dev);
8695 netif_carrier_off(adapter->dev);
8696 }
8697 status = hdd_get_next_adapter(hdd_ctx, adapter_node,
8698 &next_adapter);
8699 adapter_node = next_adapter;
8700 }
8701 EXIT();
8702}
Jeff Johnson295189b2012-06-20 16:38:30 -07008703
8704VOS_STATUS hdd_init_station_mode( hdd_adapter_t *pAdapter )
8705{
8706 struct net_device *pWlanDev = pAdapter->dev;
8707 hdd_station_ctx_t *pHddStaCtx = &pAdapter->sessionCtx.station;
8708 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
8709 eHalStatus halStatus = eHAL_STATUS_SUCCESS;
8710 VOS_STATUS status = VOS_STATUS_E_FAILURE;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308711 long rc = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07008712
Nirav Shah7e3c8132015-06-22 23:51:42 +05308713 spin_lock_init( &pAdapter->sta_hash_lock);
8714 pAdapter->is_sta_id_hash_initialized = VOS_FALSE;
8715
Jeff Johnson295189b2012-06-20 16:38:30 -07008716 INIT_COMPLETION(pAdapter->session_open_comp_var);
Kiran Kumar Lokere0ad5cd32013-06-25 11:26:22 -07008717 sme_SetCurrDeviceMode(pHddCtx->hHal, pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07008718 //Open a SME session for future operation
8719 halStatus = sme_OpenSession( pHddCtx->hHal, hdd_smeRoamCallback, pAdapter,
Kiran Kumar Lokere0ad5cd32013-06-25 11:26:22 -07008720 (tANI_U8 *)&pAdapter->macAddressCurrent, &pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07008721 if ( !HAL_STATUS_SUCCESS( halStatus ) )
8722 {
8723 hddLog(VOS_TRACE_LEVEL_FATAL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07008724 "sme_OpenSession() failed with status code %08d [x%08x]",
Jeff Johnson295189b2012-06-20 16:38:30 -07008725 halStatus, halStatus );
8726 status = VOS_STATUS_E_FAILURE;
8727 goto error_sme_open;
8728 }
8729
8730 //Block on a completion variable. Can't wait forever though.
Vinay Krishna Eranna0fe2e7c2014-04-09 21:32:08 +05308731 rc = wait_for_completion_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -07008732 &pAdapter->session_open_comp_var,
8733 msecs_to_jiffies(WLAN_WAIT_TIME_SESSIONOPENCLOSE));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308734 if (rc <= 0)
Jeff Johnson295189b2012-06-20 16:38:30 -07008735 {
8736 hddLog(VOS_TRACE_LEVEL_FATAL,
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308737 "Session is not opened within timeout period code %ld", rc );
Jeff Johnson295189b2012-06-20 16:38:30 -07008738 status = VOS_STATUS_E_FAILURE;
8739 goto error_sme_open;
8740 }
8741
8742 // Register wireless extensions
8743 if( eHAL_STATUS_SUCCESS != (halStatus = hdd_register_wext(pWlanDev)))
8744 {
8745 hddLog(VOS_TRACE_LEVEL_FATAL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07008746 "hdd_register_wext() failed with status code %08d [x%08x]",
Jeff Johnson295189b2012-06-20 16:38:30 -07008747 halStatus, halStatus );
8748 status = VOS_STATUS_E_FAILURE;
8749 goto error_register_wext;
8750 }
Katya Nigam1fd24402015-02-16 14:52:19 +05308751
Jeff Johnson295189b2012-06-20 16:38:30 -07008752 //Safe to register the hard_start_xmit function again
Katya Nigam1fd24402015-02-16 14:52:19 +05308753 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29))
8754 wlan_drv_ops.ndo_start_xmit = hdd_hard_start_xmit;
8755 #else
8756 pWlanDev->hard_start_xmit = hdd_hard_start_xmit;
8757 #endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008758
8759 //Set the Connection State to Not Connected
Abhishek Singhf4669da2014-05-26 15:07:49 +05308760 hddLog(VOS_TRACE_LEVEL_INFO,
8761 "%s: Set HDD connState to eConnectionState_NotConnected",
8762 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07008763 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
8764
8765 //Set the default operation channel
8766 pHddStaCtx->conn_info.operationChannel = pHddCtx->cfg_ini->OperatingChannel;
8767
8768 /* Make the default Auth Type as OPEN*/
8769 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_OPEN_SYSTEM;
8770
8771 if( VOS_STATUS_SUCCESS != ( status = hdd_init_tx_rx( pAdapter ) ) )
8772 {
8773 hddLog(VOS_TRACE_LEVEL_FATAL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07008774 "hdd_init_tx_rx() failed with status code %08d [x%08x]",
Jeff Johnson295189b2012-06-20 16:38:30 -07008775 status, status );
8776 goto error_init_txrx;
8777 }
8778
8779 set_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
8780
8781 if( VOS_STATUS_SUCCESS != ( status = hdd_wmm_adapter_init( pAdapter ) ) )
8782 {
8783 hddLog(VOS_TRACE_LEVEL_FATAL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07008784 "hdd_wmm_adapter_init() failed with status code %08d [x%08x]",
Jeff Johnson295189b2012-06-20 16:38:30 -07008785 status, status );
8786 goto error_wmm_init;
8787 }
8788
8789 set_bit(WMM_INIT_DONE, &pAdapter->event_flags);
8790
8791 return VOS_STATUS_SUCCESS;
8792
8793error_wmm_init:
8794 clear_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
8795 hdd_deinit_tx_rx(pAdapter);
8796error_init_txrx:
8797 hdd_UnregisterWext(pWlanDev);
8798error_register_wext:
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07008799 if (test_bit(SME_SESSION_OPENED, &pAdapter->event_flags))
Jeff Johnson295189b2012-06-20 16:38:30 -07008800 {
8801 INIT_COMPLETION(pAdapter->session_close_comp_var);
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07008802 if (eHAL_STATUS_SUCCESS == sme_CloseSession(pHddCtx->hHal,
Agrawal Ashish5a3522c2016-03-02 15:08:28 +05308803 pAdapter->sessionId, FALSE, VOS_TRUE,
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07008804 hdd_smeCloseSessionCallback, pAdapter))
Jeff Johnson295189b2012-06-20 16:38:30 -07008805 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308806 unsigned long rc;
8807
Jeff Johnson295189b2012-06-20 16:38:30 -07008808 //Block on a completion variable. Can't wait forever though.
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308809 rc = wait_for_completion_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -07008810 &pAdapter->session_close_comp_var,
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07008811 msecs_to_jiffies(WLAN_WAIT_TIME_SESSIONOPENCLOSE));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308812 if (rc <= 0)
8813 hddLog(VOS_TRACE_LEVEL_ERROR,
8814 FL("Session is not opened within timeout period code %ld"), rc);
Jeff Johnson295189b2012-06-20 16:38:30 -07008815 }
8816}
8817error_sme_open:
8818 return status;
8819}
8820
Jeff Johnson295189b2012-06-20 16:38:30 -07008821void hdd_cleanup_actionframe( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter )
8822{
8823 hdd_cfg80211_state_t *cfgState;
8824
8825 cfgState = WLAN_HDD_GET_CFG_STATE_PTR( pAdapter );
8826
8827 if( NULL != cfgState->buf )
8828 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308829 long rc;
Jeff Johnson295189b2012-06-20 16:38:30 -07008830 INIT_COMPLETION(pAdapter->tx_action_cnf_event);
8831 rc = wait_for_completion_interruptible_timeout(
8832 &pAdapter->tx_action_cnf_event,
8833 msecs_to_jiffies(ACTION_FRAME_TX_TIMEOUT));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308834 if (rc <= 0)
Jeff Johnson295189b2012-06-20 16:38:30 -07008835 {
Deepthi Gowri91b3e9c2015-08-25 13:14:58 +05308836 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8837 "%s ERROR: HDD Wait for Action Confirmation Failed!! %ld"
8838 , __func__, rc);
8839
8840 // Inform tx status as FAILURE to upper layer and free cfgState->buf
8841 hdd_sendActionCnf( pAdapter, FALSE );
Jeff Johnson295189b2012-06-20 16:38:30 -07008842 }
8843 }
8844 return;
8845}
Jeff Johnson295189b2012-06-20 16:38:30 -07008846
c_hpothu002231a2015-02-05 14:58:51 +05308847void hdd_deinit_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter, tANI_U8 rtnl_held )
Jeff Johnson295189b2012-06-20 16:38:30 -07008848{
8849 ENTER();
8850 switch ( pAdapter->device_mode )
8851 {
Katya Nigam1fd24402015-02-16 14:52:19 +05308852 case WLAN_HDD_IBSS:
8853 {
8854 if(test_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags))
8855 {
8856 hdd_ibss_deinit_tx_rx( pAdapter );
8857 clear_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
8858 }
8859 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008860 case WLAN_HDD_INFRA_STATION:
8861 case WLAN_HDD_P2P_CLIENT:
Jeff Johnsone7245742012-09-05 17:12:55 -07008862 case WLAN_HDD_P2P_DEVICE:
Jeff Johnson295189b2012-06-20 16:38:30 -07008863 {
8864 if(test_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags))
8865 {
8866 hdd_deinit_tx_rx( pAdapter );
8867 clear_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
8868 }
8869
8870 if(test_bit(WMM_INIT_DONE, &pAdapter->event_flags))
8871 {
8872 hdd_wmm_adapter_close( pAdapter );
8873 clear_bit(WMM_INIT_DONE, &pAdapter->event_flags);
8874 }
8875
Jeff Johnson295189b2012-06-20 16:38:30 -07008876 hdd_cleanup_actionframe(pHddCtx, pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07008877 break;
8878 }
8879
8880 case WLAN_HDD_SOFTAP:
8881 case WLAN_HDD_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07008882 {
Madan Mohan Koyyalamudi8c6dec82013-09-26 15:56:13 +05308883
8884 if (test_bit(WMM_INIT_DONE, &pAdapter->event_flags))
8885 {
8886 hdd_wmm_adapter_close( pAdapter );
8887 clear_bit(WMM_INIT_DONE, &pAdapter->event_flags);
8888 }
8889
Jeff Johnson295189b2012-06-20 16:38:30 -07008890 hdd_cleanup_actionframe(pHddCtx, pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07008891
c_hpothu002231a2015-02-05 14:58:51 +05308892 hdd_unregister_hostapd(pAdapter, rtnl_held);
Agrawal Ashisha0584d42016-09-29 13:03:45 +05308893 /* set con_mode to STA only when no SAP concurrency mode */
8894 if (!(hdd_get_concurrency_mode() & (VOS_SAP | VOS_P2P_GO)))
8895 hdd_set_conparam(0);
Jeff Johnson295189b2012-06-20 16:38:30 -07008896 break;
8897 }
8898
8899 case WLAN_HDD_MONITOR:
8900 {
Jeff Johnson295189b2012-06-20 16:38:30 -07008901 if(test_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags))
8902 {
8903 hdd_deinit_tx_rx( pAdapter );
8904 clear_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
8905 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008906 break;
8907 }
8908
8909
8910 default:
8911 break;
8912 }
8913
8914 EXIT();
8915}
8916
8917void hdd_cleanup_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter, tANI_U8 rtnl_held )
8918{
Mingcheng Zhu87f22fc2014-01-30 19:23:32 -08008919 struct net_device *pWlanDev = NULL;
Srinivas, Dasari693dfc52013-12-27 17:29:09 +05308920
8921 ENTER();
8922 if (NULL == pAdapter)
8923 {
8924 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8925 "%s: HDD adapter is Null", __func__);
8926 return;
8927 }
8928
8929 pWlanDev = pAdapter->dev;
Jeff Johnson295189b2012-06-20 16:38:30 -07008930
Rajeev79dbe4c2013-10-05 11:03:42 +05308931#ifdef FEATURE_WLAN_BATCH_SCAN
Srinivas, Dasari693dfc52013-12-27 17:29:09 +05308932 if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
8933 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Rajeev Kumarf999e582014-01-09 17:33:29 -08008934 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Srinivas, Dasari693dfc52013-12-27 17:29:09 +05308935 || (pAdapter->device_mode == WLAN_HDD_P2P_DEVICE)
8936 )
8937 {
Rajeev Kumarf999e582014-01-09 17:33:29 -08008938 if (pAdapter)
Rajeev79dbe4c2013-10-05 11:03:42 +05308939 {
Rajeev Kumarf999e582014-01-09 17:33:29 -08008940 if (eHDD_BATCH_SCAN_STATE_STARTED == pAdapter->batchScanState)
8941 {
8942 hdd_deinit_batch_scan(pAdapter);
8943 }
Rajeev79dbe4c2013-10-05 11:03:42 +05308944 }
Rajeev Kumarf999e582014-01-09 17:33:29 -08008945 }
Rajeev79dbe4c2013-10-05 11:03:42 +05308946#endif
8947
Jeff Johnson295189b2012-06-20 16:38:30 -07008948 if(test_bit(NET_DEVICE_REGISTERED, &pAdapter->event_flags)) {
8949 if( rtnl_held )
8950 {
8951 unregister_netdevice(pWlanDev);
8952 }
8953 else
8954 {
8955 unregister_netdev(pWlanDev);
8956 }
8957 // note that the pAdapter is no longer valid at this point
8958 // since the memory has been reclaimed
8959 }
8960
Srinivas, Dasari693dfc52013-12-27 17:29:09 +05308961 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07008962}
8963
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08008964void hdd_set_pwrparams(hdd_context_t *pHddCtx)
8965{
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05308966 VOS_STATUS status;
8967 hdd_adapter_t *pAdapter = NULL;
8968 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08008969
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05308970 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08008971
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05308972 /*loop through all adapters.*/
8973 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08008974 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05308975 pAdapter = pAdapterNode->pAdapter;
8976 if ( (WLAN_HDD_INFRA_STATION != pAdapter->device_mode)
8977 && (WLAN_HDD_P2P_CLIENT != pAdapter->device_mode) )
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08008978
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05308979 { // we skip this registration for modes other than STA and P2P client modes.
8980 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
8981 pAdapterNode = pNext;
8982 continue;
8983 }
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08008984
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05308985 //Apply Dynamic DTIM For P2P
8986 //Only if ignoreDynamicDtimInP2pMode is not set in ini
8987 if ((pHddCtx->cfg_ini->enableDynamicDTIM ||
8988 pHddCtx->cfg_ini->enableModulatedDTIM) &&
8989 ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
8990 ((WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) &&
8991 !(pHddCtx->cfg_ini->ignoreDynamicDtimInP2pMode))) &&
8992 (eANI_BOOLEAN_TRUE == pAdapter->higherDtimTransition) &&
8993 (eConnectionState_Associated ==
8994 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState) &&
8995 (pHddCtx->cfg_ini->fIsBmpsEnabled))
8996 {
8997 tSirSetPowerParamsReq powerRequest = { 0 };
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08008998
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05308999 powerRequest.uIgnoreDTIM = 1;
9000 powerRequest.uMaxLIModulatedDTIM = pHddCtx->cfg_ini->fMaxLIModulatedDTIM;
9001
9002 if (pHddCtx->cfg_ini->enableModulatedDTIM)
9003 {
9004 powerRequest.uDTIMPeriod = pHddCtx->cfg_ini->enableModulatedDTIM;
9005 powerRequest.uListenInterval = pHddCtx->hdd_actual_LI_value;
9006 }
9007 else
9008 {
9009 powerRequest.uListenInterval = pHddCtx->cfg_ini->enableDynamicDTIM;
9010 }
9011
9012 /* Update ignoreDTIM and ListedInterval in CFG to remain at the DTIM
9013 * specified during Enter/Exit BMPS when LCD off*/
9014 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IGNORE_DTIM, powerRequest.uIgnoreDTIM,
9015 NULL, eANI_BOOLEAN_FALSE);
9016 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_LISTEN_INTERVAL, powerRequest.uListenInterval,
9017 NULL, eANI_BOOLEAN_FALSE);
9018
9019 /* switch to the DTIM specified in cfg.ini */
9020 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Abhishek Singh1e390cf2015-10-27 13:45:17 +05309021 "Switch to DTIM %d Listen interval %d",
9022 powerRequest.uDTIMPeriod,
9023 powerRequest.uListenInterval);
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05309024 sme_SetPowerParams( pHddCtx->hHal, &powerRequest, TRUE);
9025 break;
9026
9027 }
9028
9029 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
9030 pAdapterNode = pNext;
9031 }
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08009032}
9033
9034void hdd_reset_pwrparams(hdd_context_t *pHddCtx)
9035{
9036 /*Switch back to DTIM 1*/
9037 tSirSetPowerParamsReq powerRequest = { 0 };
9038
9039 powerRequest.uIgnoreDTIM = pHddCtx->hdd_actual_ignore_DTIM_value;
9040 powerRequest.uListenInterval = pHddCtx->hdd_actual_LI_value;
Yue Mac24062f2013-05-13 17:01:29 -07009041 powerRequest.uMaxLIModulatedDTIM = pHddCtx->cfg_ini->fMaxLIModulatedDTIM;
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08009042
9043 /* Update ignoreDTIM and ListedInterval in CFG with default values */
9044 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IGNORE_DTIM, powerRequest.uIgnoreDTIM,
9045 NULL, eANI_BOOLEAN_FALSE);
9046 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_LISTEN_INTERVAL, powerRequest.uListenInterval,
9047 NULL, eANI_BOOLEAN_FALSE);
9048
9049 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
9050 "Switch to DTIM%d",powerRequest.uListenInterval);
9051 sme_SetPowerParams( pHddCtx->hHal, &powerRequest, TRUE);
9052
9053}
9054
Jeff Johnson295189b2012-06-20 16:38:30 -07009055VOS_STATUS hdd_enable_bmps_imps(hdd_context_t *pHddCtx)
9056{
9057 VOS_STATUS status = VOS_STATUS_SUCCESS;
Sushant Kaushik4928e542014-12-29 15:25:54 +05309058 if (WLAN_HDD_IS_UNLOAD_IN_PROGRESS(pHddCtx))
9059 {
9060 hddLog( LOGE, FL("Wlan Unload in progress"));
9061 return VOS_STATUS_E_PERM;
9062 }
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +05309063
9064 if (wlan_hdd_check_monitor_state(pHddCtx)) {
9065 hddLog(LOG1, FL("Monitor mode is started, cannot enable BMPS"));
9066 return VOS_STATUS_SUCCESS;
9067 }
9068
Jeff Johnson295189b2012-06-20 16:38:30 -07009069 if(pHddCtx->cfg_ini->fIsBmpsEnabled)
9070 {
9071 sme_EnablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
9072 }
9073
9074 if(pHddCtx->cfg_ini->fIsAutoBmpsTimerEnabled)
9075 {
9076 sme_StartAutoBmpsTimer(pHddCtx->hHal);
9077 }
9078
9079 if (pHddCtx->cfg_ini->fIsImpsEnabled)
9080 {
9081 sme_EnablePowerSave (pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
9082 }
9083
9084 return status;
9085}
9086
9087VOS_STATUS hdd_disable_bmps_imps(hdd_context_t *pHddCtx, tANI_U8 session_type)
9088{
9089 hdd_adapter_t *pAdapter = NULL;
9090 eHalStatus halStatus;
9091 VOS_STATUS status = VOS_STATUS_E_INVAL;
9092 v_BOOL_t disableBmps = FALSE;
9093 v_BOOL_t disableImps = FALSE;
9094
9095 switch(session_type)
9096 {
9097 case WLAN_HDD_INFRA_STATION:
9098 case WLAN_HDD_SOFTAP:
Jeff Johnson295189b2012-06-20 16:38:30 -07009099 case WLAN_HDD_P2P_CLIENT:
9100 case WLAN_HDD_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07009101 //Exit BMPS -> Is Sta/P2P Client is already connected
9102 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION);
9103 if((NULL != pAdapter)&&
9104 hdd_connIsConnected( WLAN_HDD_GET_STATION_CTX_PTR(pAdapter)))
9105 {
9106 disableBmps = TRUE;
9107 }
9108
9109 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_CLIENT);
9110 if((NULL != pAdapter)&&
9111 hdd_connIsConnected( WLAN_HDD_GET_STATION_CTX_PTR(pAdapter)))
9112 {
9113 disableBmps = TRUE;
9114 }
9115
9116 //Exit both Bmps and Imps incase of Go/SAP Mode
9117 if((WLAN_HDD_SOFTAP == session_type) ||
9118 (WLAN_HDD_P2P_GO == session_type))
9119 {
9120 disableBmps = TRUE;
9121 disableImps = TRUE;
9122 }
9123
9124 if(TRUE == disableImps)
9125 {
9126 if (pHddCtx->cfg_ini->fIsImpsEnabled)
9127 {
9128 sme_DisablePowerSave (pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
9129 }
9130 }
9131
9132 if(TRUE == disableBmps)
9133 {
9134 if(pHddCtx->cfg_ini->fIsBmpsEnabled)
9135 {
9136 halStatus = sme_DisablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
9137
9138 if(eHAL_STATUS_SUCCESS != halStatus)
9139 {
9140 status = VOS_STATUS_E_FAILURE;
Arif Hussain6d2a3322013-11-17 19:50:10 -08009141 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Fail to Disable Power Save", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009142 VOS_ASSERT(0);
9143 return status;
9144 }
9145 }
9146
9147 if(pHddCtx->cfg_ini->fIsAutoBmpsTimerEnabled)
9148 {
9149 halStatus = sme_StopAutoBmpsTimer(pHddCtx->hHal);
9150
9151 if(eHAL_STATUS_SUCCESS != halStatus)
9152 {
9153 status = VOS_STATUS_E_FAILURE;
Arif Hussain6d2a3322013-11-17 19:50:10 -08009154 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Fail to Stop Auto Bmps Timer", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009155 VOS_ASSERT(0);
9156 return status;
9157 }
9158 }
9159 }
9160
9161 if((TRUE == disableBmps) ||
9162 (TRUE == disableImps))
9163 {
9164 /* Now, get the chip into Full Power now */
9165 INIT_COMPLETION(pHddCtx->full_pwr_comp_var);
9166 halStatus = sme_RequestFullPower(pHddCtx->hHal, hdd_full_pwr_cbk,
9167 pHddCtx, eSME_FULL_PWR_NEEDED_BY_HDD);
9168
9169 if(halStatus != eHAL_STATUS_SUCCESS)
9170 {
9171 if(halStatus == eHAL_STATUS_PMC_PENDING)
9172 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309173 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07009174 //Block on a completion variable. Can't wait forever though
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309175 ret = wait_for_completion_interruptible_timeout(
9176 &pHddCtx->full_pwr_comp_var,
9177 msecs_to_jiffies(1000));
9178 if (ret <= 0)
9179 {
9180 hddLog(VOS_TRACE_LEVEL_ERROR,
9181 "%s: wait on full_pwr_comp_var failed %ld",
9182 __func__, ret);
9183 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009184 }
9185 else
9186 {
9187 status = VOS_STATUS_E_FAILURE;
Arif Hussain6d2a3322013-11-17 19:50:10 -08009188 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Request for Full Power failed", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009189 VOS_ASSERT(0);
9190 return status;
9191 }
9192 }
9193
9194 status = VOS_STATUS_SUCCESS;
9195 }
9196
9197 break;
9198 }
9199 return status;
9200}
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +05309201
9202void hdd_monPostMsgCb(tANI_U32 *magic, struct completion *cmpVar)
9203{
9204 if (magic == NULL || cmpVar == NULL) {
9205 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnsonc135a9a2017-09-19 08:37:24 -07009206 FL("invalid arguments %pK %pK"), magic, cmpVar);
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +05309207 return;
9208 }
9209 if (*magic != MON_MODE_MSG_MAGIC) {
9210 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9211 FL("maic: %x"), *magic);
9212 return;
9213 }
9214
9215 complete(cmpVar);
9216 return;
9217}
9218
Katya Nigame7b69a82015-04-28 15:24:06 +05309219void hdd_init_mon_mode (hdd_adapter_t *pAdapter)
9220 {
9221 hdd_mon_ctx_t *pMonCtx = NULL;
Katya Nigame7b69a82015-04-28 15:24:06 +05309222
Rajeev Kumar Sirasanagandla54447612018-03-06 15:49:56 +05309223 spin_lock_init(&pAdapter->sta_hash_lock);
9224 pAdapter->is_sta_id_hash_initialized = VOS_FALSE;
9225
9226 pMonCtx = WLAN_HDD_GET_MONITOR_CTX_PTR(pAdapter);
Katya Nigame7b69a82015-04-28 15:24:06 +05309227 pMonCtx->state = 0;
9228 pMonCtx->ChannelNo = 1;
9229 pMonCtx->ChannelBW = 20;
Katya Nigamd7d3a1f2015-06-11 14:04:24 +05309230 pMonCtx->crcCheckEnabled = 1;
9231 pMonCtx->typeSubtypeBitmap = 0xFFFF00000000;
9232 pMonCtx->is80211to803ConReq = 1;
Katya Nigame7b69a82015-04-28 15:24:06 +05309233 pMonCtx->numOfMacFilters = 0;
9234 }
9235
Jeff Johnson295189b2012-06-20 16:38:30 -07009236
9237hdd_adapter_t* hdd_open_adapter( hdd_context_t *pHddCtx, tANI_U8 session_type,
Jeff Johnsoneed415b2013-01-18 16:11:20 -08009238 const char *iface_name, tSirMacAddr macAddr,
Jeff Johnson295189b2012-06-20 16:38:30 -07009239 tANI_U8 rtnl_held )
9240{
9241 hdd_adapter_t *pAdapter = NULL;
9242 hdd_adapter_list_node_t *pHddAdapterNode = NULL;
9243 VOS_STATUS status = VOS_STATUS_E_FAILURE;
9244 VOS_STATUS exitbmpsStatus;
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +05309245 v_CONTEXT_t pVosContext = NULL;
9246
9247 /* No need to check for NULL, reaching this step
9248 * means vos context is initialized
9249 */
9250 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
Jeff Johnson295189b2012-06-20 16:38:30 -07009251
Arif Hussain6d2a3322013-11-17 19:50:10 -08009252 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s iface =%s type = %d",__func__,iface_name,session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07009253
Nirav Shah436658f2014-02-28 17:05:45 +05309254 if(macAddr == NULL)
9255 {
9256 /* Not received valid macAddr */
9257 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9258 "%s:Unable to add virtual intf: Not able to get"
9259 "valid mac address",__func__);
9260 return NULL;
9261 }
9262
Jeff Johnson295189b2012-06-20 16:38:30 -07009263 //Disable BMPS incase of Concurrency
9264 exitbmpsStatus = hdd_disable_bmps_imps(pHddCtx, session_type);
9265
9266 if(VOS_STATUS_E_FAILURE == exitbmpsStatus)
9267 {
9268 //Fail to Exit BMPS
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309269 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Fail to Exit BMPS", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009270 VOS_ASSERT(0);
9271 return NULL;
9272 }
9273
9274 switch(session_type)
9275 {
9276 case WLAN_HDD_INFRA_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -07009277 case WLAN_HDD_P2P_CLIENT:
Jeff Johnsone7245742012-09-05 17:12:55 -07009278 case WLAN_HDD_P2P_DEVICE:
Jeff Johnson295189b2012-06-20 16:38:30 -07009279 {
9280 pAdapter = hdd_alloc_station_adapter( pHddCtx, macAddr, iface_name );
9281
9282 if( NULL == pAdapter )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309283 {
9284 hddLog(VOS_TRACE_LEVEL_FATAL,
9285 FL("failed to allocate adapter for session %d"), session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07009286 return NULL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309287 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009288
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05309289#ifdef FEATURE_WLAN_TDLS
9290 /* A Mutex Lock is introduced while changing/initializing the mode to
9291 * protect the concurrent access for the Adapters by TDLS module.
9292 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05309293 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05309294#endif
9295
Jeff Johnsone7245742012-09-05 17:12:55 -07009296 pAdapter->wdev.iftype = (session_type == WLAN_HDD_P2P_CLIENT) ?
9297 NL80211_IFTYPE_P2P_CLIENT:
9298 NL80211_IFTYPE_STATION;
Jeff Johnson295189b2012-06-20 16:38:30 -07009299
Jeff Johnson295189b2012-06-20 16:38:30 -07009300 pAdapter->device_mode = session_type;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05309301#ifdef FEATURE_WLAN_TDLS
9302 mutex_unlock(&pHddCtx->tdls_lock);
9303#endif
Sunil Dutt66485cb2013-12-19 19:05:03 +05309304
Mahesh A Saptasagar67ab9222015-10-21 15:38:41 +05309305 hdd_initialize_adapter_common(pAdapter);
Sunil Dutt66485cb2013-12-19 19:05:03 +05309306 status = hdd_init_station_mode( pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -07009307 if( VOS_STATUS_SUCCESS != status )
9308 goto err_free_netdev;
9309
9310 status = hdd_register_interface( pAdapter, rtnl_held );
9311 if( VOS_STATUS_SUCCESS != status )
9312 {
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05309313#ifdef FEATURE_WLAN_TDLS
9314 mutex_lock(&pHddCtx->tdls_lock);
9315#endif
c_hpothu002231a2015-02-05 14:58:51 +05309316 hdd_deinit_adapter(pHddCtx, pAdapter, rtnl_held);
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05309317#ifdef FEATURE_WLAN_TDLS
9318 mutex_unlock(&pHddCtx->tdls_lock);
9319#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009320 goto err_free_netdev;
9321 }
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05309322
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +05309323 // Workqueue which gets scheduled in IPv4 notification callback.
Anand N Sunkaddc63c792015-06-03 14:33:24 +05309324 vos_init_work(&pAdapter->ipv4NotifierWorkQueue, hdd_ipv4_notifier_work_queue);
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +05309325
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05309326#ifdef WLAN_NS_OFFLOAD
9327 // Workqueue which gets scheduled in IPv6 notification callback.
Anand N Sunkaddc63c792015-06-03 14:33:24 +05309328 vos_init_work(&pAdapter->ipv6NotifierWorkQueue, hdd_ipv6_notifier_work_queue);
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05309329#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009330 //Stop the Interface TX queue.
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +05309331 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Jeff Johnson295189b2012-06-20 16:38:30 -07009332 netif_tx_disable(pAdapter->dev);
9333 //netif_tx_disable(pWlanDev);
9334 netif_carrier_off(pAdapter->dev);
9335
Ganesh Kondabattinibabfb492014-12-17 20:25:29 +05309336 if (WLAN_HDD_P2P_CLIENT == session_type ||
9337 WLAN_HDD_P2P_DEVICE == session_type)
9338 {
9339 /* Initialize the work queue to defer the
9340 * back to back RoC request */
Anand N Sunkaddc63c792015-06-03 14:33:24 +05309341 vos_init_delayed_work(&pAdapter->roc_work,
Ganesh Kondabattinibabfb492014-12-17 20:25:29 +05309342 hdd_p2p_roc_work_queue);
9343 }
9344
Jeff Johnson295189b2012-06-20 16:38:30 -07009345 break;
9346 }
9347
Jeff Johnson295189b2012-06-20 16:38:30 -07009348 case WLAN_HDD_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07009349 case WLAN_HDD_SOFTAP:
9350 {
9351 pAdapter = hdd_wlan_create_ap_dev( pHddCtx, macAddr, (tANI_U8 *)iface_name );
9352 if( NULL == pAdapter )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309353 {
9354 hddLog(VOS_TRACE_LEVEL_FATAL,
9355 FL("failed to allocate adapter for session %d"), session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07009356 return NULL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309357 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009358
Jeff Johnson295189b2012-06-20 16:38:30 -07009359 pAdapter->wdev.iftype = (session_type == WLAN_HDD_SOFTAP) ?
9360 NL80211_IFTYPE_AP:
9361 NL80211_IFTYPE_P2P_GO;
Jeff Johnson295189b2012-06-20 16:38:30 -07009362 pAdapter->device_mode = session_type;
9363
Mahesh A Saptasagar67ab9222015-10-21 15:38:41 +05309364 hdd_initialize_adapter_common(pAdapter);
Hanumanth Reddy Pothula15bc0fa2017-02-03 17:24:17 +05309365 status = hdd_init_ap_mode(pAdapter, false);
Jeff Johnson295189b2012-06-20 16:38:30 -07009366 if( VOS_STATUS_SUCCESS != status )
9367 goto err_free_netdev;
9368
Nirav Shah7e3c8132015-06-22 23:51:42 +05309369 status = hdd_sta_id_hash_attach(pAdapter);
9370 if (VOS_STATUS_SUCCESS != status)
9371 {
9372 hddLog(VOS_TRACE_LEVEL_FATAL,
9373 FL("failed to attach hash for session %d"), session_type);
9374 hdd_deinit_adapter(pHddCtx, pAdapter, rtnl_held);
9375 goto err_free_netdev;
9376 }
9377
Jeff Johnson295189b2012-06-20 16:38:30 -07009378 status = hdd_register_hostapd( pAdapter, rtnl_held );
9379 if( VOS_STATUS_SUCCESS != status )
9380 {
c_hpothu002231a2015-02-05 14:58:51 +05309381 hdd_deinit_adapter(pHddCtx, pAdapter, rtnl_held);
Jeff Johnson295189b2012-06-20 16:38:30 -07009382 goto err_free_netdev;
9383 }
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +05309384 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Jeff Johnson295189b2012-06-20 16:38:30 -07009385 netif_tx_disable(pAdapter->dev);
9386 netif_carrier_off(pAdapter->dev);
9387
9388 hdd_set_conparam( 1 );
Ganesh Kondabattinibabfb492014-12-17 20:25:29 +05309389
Hanumanth Reddy Pothulab4537b82018-03-02 12:20:38 +05309390 // Workqueue which gets scheduled in IPv4 notification callback.
9391 vos_init_work(&pAdapter->ipv4NotifierWorkQueue,
9392 hdd_ipv4_notifier_work_queue);
9393
9394#ifdef WLAN_NS_OFFLOAD
9395 // Workqueue which gets scheduled in IPv6 notification callback.
9396 vos_init_work(&pAdapter->ipv6NotifierWorkQueue,
9397 hdd_ipv6_notifier_work_queue);
9398#endif
9399
Ganesh Kondabattinibabfb492014-12-17 20:25:29 +05309400 if (WLAN_HDD_P2P_GO == session_type)
9401 {
9402 /* Initialize the work queue to
9403 * defer the back to back RoC request */
9404 INIT_DELAYED_WORK(&pAdapter->roc_work,
9405 hdd_p2p_roc_work_queue);
9406 }
Bhargav Shahd0715912015-10-01 18:17:37 +05309407
Jeff Johnson295189b2012-06-20 16:38:30 -07009408 break;
9409 }
9410 case WLAN_HDD_MONITOR:
9411 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009412 pAdapter = hdd_alloc_station_adapter( pHddCtx, macAddr, iface_name );
9413 if( NULL == pAdapter )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309414 {
9415 hddLog(VOS_TRACE_LEVEL_FATAL,
9416 FL("failed to allocate adapter for session %d"), session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07009417 return NULL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309418 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009419
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +05309420 pAdapter->device_mode = session_type;
9421 pAdapter->wdev.iftype = NL80211_IFTYPE_MONITOR;
9422
Katya Nigame7b69a82015-04-28 15:24:06 +05309423 // Register wireless extensions
9424 if( VOS_STATUS_SUCCESS != (status = hdd_register_wext(pAdapter->dev)))
9425 {
9426 hddLog(VOS_TRACE_LEVEL_FATAL,
9427 "hdd_register_wext() failed with status code %08d [x%08x]",
9428 status, status );
9429 status = VOS_STATUS_E_FAILURE;
9430 }
9431
Jeff Johnson295189b2012-06-20 16:38:30 -07009432#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29)
9433 pAdapter->dev->netdev_ops = &wlan_mon_drv_ops;
9434#else
9435 pAdapter->dev->open = hdd_mon_open;
9436 pAdapter->dev->hard_start_xmit = hdd_mon_hard_start_xmit;
Katya Nigame7b69a82015-04-28 15:24:06 +05309437 pAdapter->dev->stop = hdd_mon_stop;
9438 pAdapter->dev->do_ioctl = hdd_mon_ioctl;
Jeff Johnson295189b2012-06-20 16:38:30 -07009439#endif
Katya Nigame7b69a82015-04-28 15:24:06 +05309440 hdd_init_mon_mode( pAdapter );
Mahesh A Saptasagar67ab9222015-10-21 15:38:41 +05309441 hdd_initialize_adapter_common(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07009442 hdd_init_tx_rx( pAdapter );
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +05309443
9444 if (VOS_MONITOR_MODE != hdd_get_conparam())
9445 WLANTL_SetMonRxCbk( pVosContext, hdd_rx_packet_monitor_cbk );
9446
Jeff Johnson295189b2012-06-20 16:38:30 -07009447 set_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +05309448 status = hdd_register_interface( pAdapter, rtnl_held );
Katya Nigame7b69a82015-04-28 15:24:06 +05309449 //Stop the Interface TX queue.
9450 netif_tx_disable(pAdapter->dev);
9451 netif_carrier_off(pAdapter->dev);
Jeff Johnson295189b2012-06-20 16:38:30 -07009452 }
9453 break;
Jeff Johnson295189b2012-06-20 16:38:30 -07009454 case WLAN_HDD_FTM:
9455 {
9456 pAdapter = hdd_alloc_station_adapter( pHddCtx, macAddr, iface_name );
9457
9458 if( NULL == pAdapter )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309459 {
9460 hddLog(VOS_TRACE_LEVEL_FATAL,
9461 FL("failed to allocate adapter for session %d"), session_type);
9462 return NULL;
9463 }
9464
Jeff Johnson295189b2012-06-20 16:38:30 -07009465 /* Assign NL80211_IFTYPE_STATION as interface type to resolve Kernel Warning
9466 * message while loading driver in FTM mode. */
9467 pAdapter->wdev.iftype = NL80211_IFTYPE_STATION;
9468 pAdapter->device_mode = session_type;
9469 status = hdd_register_interface( pAdapter, rtnl_held );
Madan Mohan Koyyalamudif89ac9f2013-09-19 16:58:12 +05309470
Mahesh A Saptasagar67ab9222015-10-21 15:38:41 +05309471 hdd_initialize_adapter_common(pAdapter);
Madan Mohan Koyyalamudif89ac9f2013-09-19 16:58:12 +05309472 hdd_init_tx_rx( pAdapter );
9473
9474 //Stop the Interface TX queue.
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +05309475 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Madan Mohan Koyyalamudif89ac9f2013-09-19 16:58:12 +05309476 netif_tx_disable(pAdapter->dev);
9477 netif_carrier_off(pAdapter->dev);
Jeff Johnson295189b2012-06-20 16:38:30 -07009478 }
9479 break;
Jeff Johnson295189b2012-06-20 16:38:30 -07009480 default:
9481 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309482 hddLog(VOS_TRACE_LEVEL_FATAL,"%s Invalid session type %d",
9483 __func__, session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07009484 VOS_ASSERT(0);
9485 return NULL;
9486 }
9487 }
9488
Jeff Johnson295189b2012-06-20 16:38:30 -07009489 if( VOS_STATUS_SUCCESS == status )
9490 {
Mahesh A Saptasagar67ab9222015-10-21 15:38:41 +05309491 //Add it to the hdd's session list.
Jeff Johnson295189b2012-06-20 16:38:30 -07009492 pHddAdapterNode = vos_mem_malloc( sizeof( hdd_adapter_list_node_t ) );
9493 if( NULL == pHddAdapterNode )
9494 {
9495 status = VOS_STATUS_E_NOMEM;
9496 }
9497 else
9498 {
9499 pHddAdapterNode->pAdapter = pAdapter;
9500 status = hdd_add_adapter_back ( pHddCtx,
9501 pHddAdapterNode );
9502 }
9503 }
9504
9505 if( VOS_STATUS_SUCCESS != status )
9506 {
9507 if( NULL != pAdapter )
9508 {
9509 hdd_cleanup_adapter( pHddCtx, pAdapter, rtnl_held );
9510 pAdapter = NULL;
9511 }
9512 if( NULL != pHddAdapterNode )
9513 {
9514 vos_mem_free( pHddAdapterNode );
9515 }
9516
9517 goto resume_bmps;
9518 }
9519
9520 if(VOS_STATUS_SUCCESS == status)
9521 {
9522 wlan_hdd_set_concurrency_mode(pHddCtx, session_type);
Madan Mohan Koyyalamudi96dd30d2012-10-05 17:24:51 -07009523 //Initialize the WoWL service
9524 if(!hdd_init_wowl(pAdapter))
9525 {
9526 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hdd_init_wowl failed",__func__);
9527 goto err_free_netdev;
9528 }
Manjeet Singh3ed79242017-01-11 19:04:32 +05309529 //Initialize the TSF capture data
9530 wlan_hdd_tsf_init(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07009531 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009532 return pAdapter;
9533
9534err_free_netdev:
9535 free_netdev(pAdapter->dev);
9536 wlan_hdd_release_intf_addr( pHddCtx,
9537 pAdapter->macAddressCurrent.bytes );
9538
9539resume_bmps:
9540 //If bmps disabled enable it
9541 if(VOS_STATUS_SUCCESS == exitbmpsStatus)
9542 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05309543 if (pHddCtx->hdd_wlan_suspended)
9544 {
9545 hdd_set_pwrparams(pHddCtx);
9546 }
9547 hdd_enable_bmps_imps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07009548 }
9549 return NULL;
9550}
9551
9552VOS_STATUS hdd_close_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter,
9553 tANI_U8 rtnl_held )
9554{
9555 hdd_adapter_list_node_t *pAdapterNode, *pCurrent, *pNext;
9556 VOS_STATUS status;
9557
9558 status = hdd_get_front_adapter ( pHddCtx, &pCurrent );
9559 if( VOS_STATUS_SUCCESS != status )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309560 {
9561 hddLog(VOS_TRACE_LEVEL_WARN,"%s: adapter list empty %d",
9562 __func__, status);
Jeff Johnson295189b2012-06-20 16:38:30 -07009563 return status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309564 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009565
9566 while ( pCurrent->pAdapter != pAdapter )
9567 {
9568 status = hdd_get_next_adapter ( pHddCtx, pCurrent, &pNext );
9569 if( VOS_STATUS_SUCCESS != status )
9570 break;
9571
9572 pCurrent = pNext;
9573 }
9574 pAdapterNode = pCurrent;
9575 if( VOS_STATUS_SUCCESS == status )
9576 {
9577 wlan_hdd_clear_concurrency_mode(pHddCtx, pAdapter->device_mode);
9578 hdd_cleanup_adapter( pHddCtx, pAdapterNode->pAdapter, rtnl_held );
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05309579
9580#ifdef FEATURE_WLAN_TDLS
9581
9582 /* A Mutex Lock is introduced while changing/initializing the mode to
9583 * protect the concurrent access for the Adapters by TDLS module.
9584 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05309585 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05309586#endif
9587
Jeff Johnson295189b2012-06-20 16:38:30 -07009588 hdd_remove_adapter( pHddCtx, pAdapterNode );
9589 vos_mem_free( pAdapterNode );
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08009590 pAdapterNode = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07009591
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05309592#ifdef FEATURE_WLAN_TDLS
9593 mutex_unlock(&pHddCtx->tdls_lock);
9594#endif
9595
Jeff Johnson295189b2012-06-20 16:38:30 -07009596
9597 /* If there is a single session of STA/P2P client, re-enable BMPS */
Agarwal Ashish51325b52014-06-16 16:50:49 +05309598 if ((!vos_concurrent_open_sessions_running()) &&
9599 ((pHddCtx->no_of_open_sessions[VOS_STA_MODE] >= 1) ||
9600 (pHddCtx->no_of_open_sessions[VOS_P2P_CLIENT_MODE] >= 1)))
Jeff Johnson295189b2012-06-20 16:38:30 -07009601 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05309602 if (pHddCtx->hdd_wlan_suspended)
9603 {
9604 hdd_set_pwrparams(pHddCtx);
9605 }
9606 hdd_enable_bmps_imps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07009607 }
9608
9609 return VOS_STATUS_SUCCESS;
9610 }
9611
9612 return VOS_STATUS_E_FAILURE;
9613}
9614
9615VOS_STATUS hdd_close_all_adapters( hdd_context_t *pHddCtx )
9616{
9617 hdd_adapter_list_node_t *pHddAdapterNode;
9618 VOS_STATUS status;
9619
9620 ENTER();
9621
9622 do
9623 {
9624 status = hdd_remove_front_adapter( pHddCtx, &pHddAdapterNode );
9625 if( pHddAdapterNode && VOS_STATUS_SUCCESS == status )
9626 {
9627 hdd_cleanup_adapter( pHddCtx, pHddAdapterNode->pAdapter, FALSE );
9628 vos_mem_free( pHddAdapterNode );
9629 }
9630 }while( NULL != pHddAdapterNode && VOS_STATUS_E_EMPTY != status );
9631
9632 EXIT();
9633
9634 return VOS_STATUS_SUCCESS;
9635}
9636
9637void wlan_hdd_reset_prob_rspies(hdd_adapter_t* pHostapdAdapter)
9638{
9639 v_U8_t addIE[1] = {0};
9640
9641 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
9642 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,(tANI_U8*)addIE, 0, NULL,
9643 eANI_BOOLEAN_FALSE) )
9644 {
9645 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009646 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07009647 }
9648
9649 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
9650 WNI_CFG_PROBE_RSP_ADDNIE_DATA2, (tANI_U8*)addIE, 0, NULL,
9651 eANI_BOOLEAN_FALSE) )
9652 {
9653 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009654 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07009655 }
9656
9657 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
9658 WNI_CFG_PROBE_RSP_ADDNIE_DATA3, (tANI_U8*)addIE, 0, NULL,
9659 eANI_BOOLEAN_FALSE) )
9660 {
9661 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009662 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07009663 }
9664}
9665
Anurag Chouhan83026002016-12-13 22:46:21 +05309666VOS_STATUS hdd_cleanup_ap_events(hdd_adapter_t *adapter)
9667{
9668#ifdef DHCP_SERVER_OFFLOAD
9669 vos_event_destroy(&adapter->dhcp_status.vos_event);
9670#endif
Anurag Chouhan0b29de02016-12-16 13:18:40 +05309671#ifdef MDNS_OFFLOAD
9672 vos_event_destroy(&adapter->mdns_status.vos_event);
9673#endif
Anurag Chouhan83026002016-12-13 22:46:21 +05309674 return VOS_STATUS_SUCCESS;
9675}
9676
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +05309677int wlan_hdd_stop_mon(hdd_context_t *hdd_ctx, bool wait)
9678{
9679 hdd_mon_ctx_t *mon_ctx;
9680 long ret;
9681 v_U32_t magic;
9682 struct completion cmp_var;
9683 void (*func_ptr)(tANI_U32 *magic, struct completion *cmpVar) = NULL;
9684 hdd_adapter_t *adapter;
9685
9686 adapter = hdd_get_adapter(hdd_ctx, WLAN_HDD_MONITOR);
9687 if (!adapter) {
9688 hddLog(LOGE, FL("Invalid STA + MON mode"));
9689 return -EINVAL;
9690 }
9691
9692 mon_ctx = WLAN_HDD_GET_MONITOR_CTX_PTR(adapter);
9693 if (!mon_ctx)
9694 return 0;
9695
9696 if (mon_ctx->state != MON_MODE_START)
9697 return 0;
9698
9699 mon_ctx->state = MON_MODE_STOP;
9700 if (wait) {
9701 func_ptr = hdd_monPostMsgCb;
9702 magic = MON_MODE_MSG_MAGIC;
9703 init_completion(&cmp_var);
9704 }
9705
9706 if (VOS_STATUS_SUCCESS != wlan_hdd_mon_postMsg(&magic, &cmp_var,
9707 mon_ctx,
9708 hdd_monPostMsgCb)) {
9709 hddLog(LOGE, FL("failed to stop MON MODE"));
9710 mon_ctx->state = MON_MODE_START;
9711 magic = 0;
9712 return -EINVAL;
9713 }
9714
9715 if (!wait)
9716 goto bmps_roaming;
9717
9718 ret = wait_for_completion_timeout(&cmp_var, MON_MODE_MSG_TIMEOUT);
9719 magic = 0;
9720 if (ret <= 0 ) {
9721 hddLog(LOGE,
9722 FL("timeout on stop monitor mode completion %ld"), ret);
9723 return -EINVAL;
9724 }
9725
9726bmps_roaming:
9727 hddLog(LOG1, FL("Enable BMPS"));
9728 hdd_enable_bmps_imps(hdd_ctx);
9729 hdd_restore_roaming(hdd_ctx);
9730
9731 return 0;
9732}
9733
9734bool wlan_hdd_check_monitor_state(hdd_context_t *hdd_ctx)
9735{
9736 hdd_adapter_t *mon_adapter;
9737 hdd_mon_ctx_t *mon_ctx;
9738
9739 if (hdd_ctx->concurrency_mode != VOS_STA_MON)
9740 return false;
9741
9742 mon_adapter = hdd_get_adapter(hdd_ctx, WLAN_HDD_MONITOR);
9743 if (!mon_adapter) {
9744 hddLog(LOGE, FL("Invalid concurrency mode"));
9745 return false;
9746 }
9747
9748 mon_ctx = WLAN_HDD_GET_MONITOR_CTX_PTR(mon_adapter);
9749 if (mon_ctx->state == MON_MODE_START)
9750 return true;
9751
9752 return false;
9753}
9754
9755int wlan_hdd_check_and_stop_mon(hdd_adapter_t *sta_adapter, bool wait)
9756{
9757 hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(sta_adapter);
9758
9759 if ((sta_adapter->device_mode != WLAN_HDD_INFRA_STATION) ||
9760 !wlan_hdd_check_monitor_state(hdd_ctx))
9761 return 0;
9762
9763 if (wlan_hdd_stop_mon(hdd_ctx, wait))
9764 return -EINVAL;
9765
9766 return 0;
9767}
9768
9769void hdd_disable_roaming(hdd_context_t *hdd_ctx)
9770{
9771 if (!hdd_ctx)
9772 return;
9773
9774 if (!hdd_ctx->cfg_ini->isFastRoamIniFeatureEnabled) {
9775 hdd_ctx->roaming_ini_original = CFG_LFR_FEATURE_ENABLED_MIN;
9776 return;
9777 }
9778
9779 hddLog(LOG1, FL("Disable driver and firmware roaming"));
9780
9781 hdd_ctx->roaming_ini_original =
9782 hdd_ctx->cfg_ini->isFastRoamIniFeatureEnabled;
9783
9784 hdd_ctx->cfg_ini->isFastRoamIniFeatureEnabled =
9785 CFG_LFR_FEATURE_ENABLED_MIN;
9786
9787 sme_UpdateIsFastRoamIniFeatureEnabled(hdd_ctx->hHal,
9788 CFG_LFR_FEATURE_ENABLED_MIN);
9789}
9790
9791void hdd_restore_roaming(hdd_context_t *hdd_ctx)
9792{
9793 if (!hdd_ctx->roaming_ini_original)
9794 return;
9795
9796 hddLog(LOG1, FL("Enable driver and firmware roaming"));
9797
9798 hdd_ctx->cfg_ini->isFastRoamIniFeatureEnabled =
9799 CFG_LFR_FEATURE_ENABLED_MAX;
9800
9801 hdd_ctx->roaming_ini_original = CFG_LFR_FEATURE_ENABLED_MIN;
9802
9803 sme_UpdateIsFastRoamIniFeatureEnabled(hdd_ctx->hHal,
9804 CFG_LFR_FEATURE_ENABLED_MAX);
9805}
Anurag Chouhan83026002016-12-13 22:46:21 +05309806
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05309807VOS_STATUS hdd_stop_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter,
9808 const v_BOOL_t bCloseSession )
Jeff Johnson295189b2012-06-20 16:38:30 -07009809{
9810 eHalStatus halStatus = eHAL_STATUS_SUCCESS;
9811 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Kaushik, Sushant4975a572014-10-21 16:07:48 +05309812 hdd_scaninfo_t *pScanInfo = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07009813 union iwreq_data wrqu;
Kaushik, Sushant7005e372014-04-08 11:36:54 +05309814 v_U8_t retry = 0;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309815 long ret;
Nirav Shah7e3c8132015-06-22 23:51:42 +05309816 VOS_STATUS status;
Jeff Johnson295189b2012-06-20 16:38:30 -07009817
Anand N Sunkad26d71b92014-12-24 18:08:22 +05309818 if (pHddCtx->isLogpInProgress) {
9819 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
9820 "%s:LOGP in Progress. Ignore!!!",__func__);
9821 return VOS_STATUS_E_FAILURE;
9822 }
9823
Jeff Johnson295189b2012-06-20 16:38:30 -07009824 ENTER();
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +05309825
Kaushik, Sushant4975a572014-10-21 16:07:48 +05309826 pScanInfo = &pHddCtx->scan_info;
Jeff Johnson295189b2012-06-20 16:38:30 -07009827 switch(pAdapter->device_mode)
9828 {
Nirav Shah0cf4d892015-11-05 16:27:27 +05309829 case WLAN_HDD_IBSS:
9830 if ( VOS_TRUE == bCloseSession )
9831 {
9832 status = hdd_sta_id_hash_detach(pAdapter);
9833 if (status != VOS_STATUS_SUCCESS)
9834 hddLog(VOS_TRACE_LEVEL_ERROR,
9835 FL("sta id hash detach failed"));
9836 }
9837
Jeff Johnson295189b2012-06-20 16:38:30 -07009838 case WLAN_HDD_INFRA_STATION:
9839 case WLAN_HDD_P2P_CLIENT:
Jeff Johnsone7245742012-09-05 17:12:55 -07009840 case WLAN_HDD_P2P_DEVICE:
Vinay Krishna Erannab09d3e72014-03-26 21:23:55 +05309841 {
9842 hdd_station_ctx_t *pstation = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Mahesh A Saptasagare4d05d42015-07-02 16:17:20 +05309843#ifdef FEATURE_WLAN_TDLS
9844 mutex_lock(&pHddCtx->tdls_lock);
9845 wlan_hdd_tdls_exit(pAdapter, TRUE);
9846 mutex_unlock(&pHddCtx->tdls_lock);
9847#endif
Vinay Krishna Erannab09d3e72014-03-26 21:23:55 +05309848 if( hdd_connIsConnected(pstation) ||
9849 (pstation->conn_info.connState == eConnectionState_Connecting) )
Jeff Johnson295189b2012-06-20 16:38:30 -07009850 {
Abhishek Singhe21a5212017-06-09 09:42:58 +05309851 /*
9852 * Indicate sme of disconnect so that in progress connection
9853 * or preauth can be aborted.
9854 */
9855 sme_abortConnection(WLAN_HDD_GET_HAL_CTX(pAdapter),
9856 pAdapter->sessionId);
Abhishek Singh99f17b82017-02-06 16:57:56 +05309857 INIT_COMPLETION(pAdapter->disconnect_comp_var);
Jeff Johnson295189b2012-06-20 16:38:30 -07009858 if (pWextState->roamProfile.BSSType == eCSR_BSS_TYPE_START_IBSS)
9859 halStatus = sme_RoamDisconnect(pHddCtx->hHal,
9860 pAdapter->sessionId,
9861 eCSR_DISCONNECT_REASON_IBSS_LEAVE);
9862 else
9863 halStatus = sme_RoamDisconnect(pHddCtx->hHal,
9864 pAdapter->sessionId,
9865 eCSR_DISCONNECT_REASON_UNSPECIFIED);
Abhishek Singh7b52ed52016-02-11 17:45:54 +05309866 /* Success implies disconnect command got queued up successfully
9867 * Or cmd not queued as scan for SSID is in progress
9868 */
9869 if((eHAL_STATUS_SUCCESS == halStatus) ||
9870 (eHAL_STATUS_CMD_NOT_QUEUED == halStatus))
Jeff Johnson295189b2012-06-20 16:38:30 -07009871 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309872 ret = wait_for_completion_interruptible_timeout(
9873 &pAdapter->disconnect_comp_var,
9874 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
Abhishek Singh7b52ed52016-02-11 17:45:54 +05309875 if (ret <= 0 &&
9876 (eHAL_STATUS_CMD_NOT_QUEUED != halStatus))
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309877 {
9878 hddLog(VOS_TRACE_LEVEL_ERROR,
9879 "%s: wait on disconnect_comp_var failed %ld",
9880 __func__, ret);
9881 }
9882 }
9883 else
9884 {
9885 hddLog(LOGE, "%s: failed to post disconnect event to SME",
9886 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009887 }
9888 memset(&wrqu, '\0', sizeof(wrqu));
9889 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
9890 memset(wrqu.ap_addr.sa_data,'\0',ETH_ALEN);
9891 wireless_send_event(pAdapter->dev, SIOCGIWAP, &wrqu, NULL);
9892 }
Vinay Krishna Erannab09d3e72014-03-26 21:23:55 +05309893 else if(pstation->conn_info.connState ==
9894 eConnectionState_Disconnecting)
9895 {
9896 ret = wait_for_completion_interruptible_timeout(
9897 &pAdapter->disconnect_comp_var,
9898 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
9899 if (ret <= 0)
9900 {
9901 hddLog(VOS_TRACE_LEVEL_ERROR,
9902 FL("wait on disconnect_comp_var failed %ld"), ret);
9903 }
9904 }
Sachin Ahuja27dd2402016-08-01 20:30:31 +05309905 if(pScanInfo != NULL && pHddCtx->scan_info.mScanPending)
Jeff Johnson295189b2012-06-20 16:38:30 -07009906 {
Mahesh A Saptasagar0b61dcc2016-02-15 14:23:38 +05309907 wlan_hdd_scan_abort(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07009908 }
Abhishek Singh3ac179b2015-09-21 10:01:34 +05309909 if ((pAdapter->device_mode != WLAN_HDD_INFRA_STATION) &&
9910 (pAdapter->device_mode != WLAN_HDD_IBSS))
Kaushik, Sushant7005e372014-04-08 11:36:54 +05309911 {
9912 while (pAdapter->is_roc_inprogress)
9913 {
9914 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9915 "%s: ROC in progress for session %d!!!",
9916 __func__, pAdapter->sessionId);
9917 // waiting for ROC to expire
9918 msleep(500);
9919 /* In GO present case , if retry exceeds 3,
9920 it means something went wrong. */
9921 if ( retry++ > MAX_WAIT_FOR_ROC_COMPLETION )
9922 {
9923 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9924 "%s: ROC completion is not received.!!!", __func__);
Deepthi Gowri70498252015-01-20 15:56:45 +05309925 if (eHAL_STATUS_SUCCESS !=
9926 sme_CancelRemainOnChannel( WLAN_HDD_GET_HAL_CTX( pAdapter),
9927 pAdapter->sessionId ))
9928 {
9929 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9930 FL("Failed to Cancel Remain on Channel"));
9931 }
Kaushik, Sushant7005e372014-04-08 11:36:54 +05309932 wait_for_completion_interruptible_timeout(
9933 &pAdapter->cancel_rem_on_chan_var,
9934 msecs_to_jiffies(WAIT_CANCEL_REM_CHAN));
9935 break;
9936 }
9937 }
Anand N Sunkaddc63c792015-06-03 14:33:24 +05309938 vos_flush_delayed_work(&pAdapter->roc_work);
Kaushik, Sushant7005e372014-04-08 11:36:54 +05309939 }
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05309940#ifdef WLAN_NS_OFFLOAD
Anand N Sunkaddc63c792015-06-03 14:33:24 +05309941 vos_flush_work(&pAdapter->ipv6NotifierWorkQueue);
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05309942#endif
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +05309943
Anand N Sunkaddc63c792015-06-03 14:33:24 +05309944 vos_flush_work(&pAdapter->ipv4NotifierWorkQueue);
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +05309945
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05309946 /* It is possible that the caller of this function does not
9947 * wish to close the session
9948 */
9949 if (VOS_TRUE == bCloseSession &&
9950 test_bit(SME_SESSION_OPENED, &pAdapter->event_flags))
Jeff Johnson295189b2012-06-20 16:38:30 -07009951 {
9952 INIT_COMPLETION(pAdapter->session_close_comp_var);
9953 if (eHAL_STATUS_SUCCESS ==
Agrawal Ashish5a3522c2016-03-02 15:08:28 +05309954 sme_CloseSession(pHddCtx->hHal, pAdapter->sessionId, FALSE,
9955 VOS_FALSE, hdd_smeCloseSessionCallback, pAdapter))
Jeff Johnson295189b2012-06-20 16:38:30 -07009956 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309957 unsigned long ret;
9958
Jeff Johnson295189b2012-06-20 16:38:30 -07009959 //Block on a completion variable. Can't wait forever though.
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309960 ret = wait_for_completion_timeout(
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05309961 &pAdapter->session_close_comp_var,
9962 msecs_to_jiffies(WLAN_WAIT_TIME_SESSIONOPENCLOSE));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309963 if ( 0 >= ret)
9964 {
9965 hddLog(LOGE, "%s: failure waiting for session_close_comp_var %ld",
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05309966 __func__, ret);
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309967 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009968 }
9969 }
Vinay Krishna Erannab09d3e72014-03-26 21:23:55 +05309970 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009971 break;
9972
9973 case WLAN_HDD_SOFTAP:
9974 case WLAN_HDD_P2P_GO:
Nirav Shah0cf4d892015-11-05 16:27:27 +05309975 if ( VOS_TRUE == bCloseSession )
9976 {
9977 status = hdd_sta_id_hash_detach(pAdapter);
9978 if (status != VOS_STATUS_SUCCESS)
9979 hddLog(VOS_TRACE_LEVEL_ERROR,
9980 FL("sta id hash detach failed"));
9981 }
9982
Jeff Johnson295189b2012-06-20 16:38:30 -07009983 //Any softap specific cleanup here...
Anurag Chouhan83026002016-12-13 22:46:21 +05309984 hdd_cleanup_ap_events(pAdapter);
Kaushik, Sushant7005e372014-04-08 11:36:54 +05309985 if (pAdapter->device_mode == WLAN_HDD_P2P_GO) {
9986 while (pAdapter->is_roc_inprogress) {
9987 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9988 "%s: ROC in progress for session %d!!!",
9989 __func__, pAdapter->sessionId);
9990 msleep(500);
9991 if ( retry++ > MAX_WAIT_FOR_ROC_COMPLETION ) {
9992 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9993 "%s: ROC completion is not received.!!!", __func__);
9994 WLANSAP_CancelRemainOnChannel(
9995 (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
9996 wait_for_completion_interruptible_timeout(
9997 &pAdapter->cancel_rem_on_chan_var,
9998 msecs_to_jiffies(WAIT_CANCEL_REM_CHAN));
9999 break;
10000 }
10001 }
Ganesh Kondabattinibabfb492014-12-17 20:25:29 +053010002
Anand N Sunkaddc63c792015-06-03 14:33:24 +053010003 vos_flush_delayed_work(&pAdapter->roc_work);
Kaushik, Sushant7005e372014-04-08 11:36:54 +053010004 }
Agrawal Ashish17ef5082016-10-17 18:33:21 +053010005#ifdef SAP_AUTH_OFFLOAD
10006 if (pHddCtx->cfg_ini->enable_sap_auth_offload)
10007 hdd_set_sap_auth_offload(pAdapter, FALSE);
10008#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010009 mutex_lock(&pHddCtx->sap_lock);
10010 if (test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
10011 {
10012 VOS_STATUS status;
10013 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
10014
10015 //Stop Bss.
10016 status = WLANSAP_StopBss(pHddCtx->pvosContext);
10017 if (VOS_IS_STATUS_SUCCESS(status))
10018 {
10019 hdd_hostapd_state_t *pHostapdState =
10020 WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
10021
10022 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
10023
10024 if (!VOS_IS_STATUS_SUCCESS(status))
10025 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010026 hddLog(LOGE, "%s: failure waiting for WLANSAP_StopBss %d",
10027 __func__, status);
Jeff Johnson295189b2012-06-20 16:38:30 -070010028 }
10029 }
10030 else
10031 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070010032 hddLog(LOGE, "%s: failure in WLANSAP_StopBss", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070010033 }
10034 clear_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags);
Agarwal Ashish51325b52014-06-16 16:50:49 +053010035 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070010036
10037 if (eHAL_STATUS_FAILURE ==
10038 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG,
10039 0, NULL, eANI_BOOLEAN_FALSE))
10040 {
10041 hddLog(LOGE,
10042 "%s: Failed to set WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070010043 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070010044 }
10045
10046 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt((WLAN_HDD_GET_CTX(pAdapter))->hHal,
10047 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
10048 eANI_BOOLEAN_FALSE) )
10049 {
10050 hddLog(LOGE,
10051 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
10052 }
10053
10054 // Reset WNI_CFG_PROBE_RSP Flags
10055 wlan_hdd_reset_prob_rspies(pAdapter);
10056 kfree(pAdapter->sessionCtx.ap.beacon);
10057 pAdapter->sessionCtx.ap.beacon = NULL;
10058 }
10059 mutex_unlock(&pHddCtx->sap_lock);
Hanumanth Reddy Pothulab4537b82018-03-02 12:20:38 +053010060
10061#ifdef WLAN_NS_OFFLOAD
10062 vos_flush_work(&pAdapter->ipv6NotifierWorkQueue);
10063#endif
10064 vos_flush_work(&pAdapter->ipv4NotifierWorkQueue);
10065
Jeff Johnson295189b2012-06-20 16:38:30 -070010066 break;
Sameer Thalappilbee426e2013-10-30 10:30:30 -070010067
Jeff Johnson295189b2012-06-20 16:38:30 -070010068 case WLAN_HDD_MONITOR:
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +053010069 if (VOS_MONITOR_MODE != hdd_get_conparam())
10070 wlan_hdd_stop_mon(pHddCtx, true);
10071 break;
Sameer Thalappilbee426e2013-10-30 10:30:30 -070010072
Jeff Johnson295189b2012-06-20 16:38:30 -070010073 default:
10074 break;
10075 }
10076
10077 EXIT();
10078 return VOS_STATUS_SUCCESS;
10079}
10080
Kapil Gupta137ef892016-12-13 19:38:00 +053010081/**
10082 * wlan_hdd_restart_sap() - to restart SAP in driver internally
10083 * @ap_adapter: - Pointer to SAP hdd_adapter_t structure
10084 *
10085 * wlan_hdd_restart_sap first delete SAP and do cleanup.
10086 * After that WLANSAP_StartBss start re-start process of SAP.
10087 *
10088 * Return: None
10089 */
10090static void wlan_hdd_restart_sap(hdd_adapter_t *ap_adapter)
10091{
10092 hdd_ap_ctx_t *pHddApCtx;
10093 hdd_hostapd_state_t *pHostapdState;
10094 VOS_STATUS vos_status;
10095 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(ap_adapter);
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053010096#ifdef USE_CFG80211_DEL_STA_V2
Kapil Gupta137ef892016-12-13 19:38:00 +053010097 struct station_del_parameters delStaParams;
10098#endif
10099 tsap_Config_t *pConfig;
10100
10101 pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(ap_adapter);
10102 pConfig = &pHddApCtx->sapConfig;
10103
10104 mutex_lock(&pHddCtx->sap_lock);
10105 if (test_bit(SOFTAP_BSS_STARTED, &ap_adapter->event_flags)) {
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053010106#ifdef USE_CFG80211_DEL_STA_V2
Kapil Gupta137ef892016-12-13 19:38:00 +053010107 delStaParams.mac = NULL;
10108 delStaParams.subtype = SIR_MAC_MGMT_DEAUTH >> 4;
10109 delStaParams.reason_code = eCsrForcedDeauthSta;
10110 wlan_hdd_cfg80211_del_station(ap_adapter->wdev.wiphy, ap_adapter->dev,
10111 &delStaParams);
10112#else
10113 wlan_hdd_cfg80211_del_station(ap_adapter->wdev.wiphy, ap_adapter->dev,
10114 NULL);
10115#endif
10116 hdd_cleanup_actionframe(pHddCtx, ap_adapter);
10117
10118 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(ap_adapter);
10119 vos_event_reset(&pHostapdState->vosEvent);
10120
10121 if (VOS_STATUS_SUCCESS == WLANSAP_StopBss(pHddCtx->pvosContext)) {
10122 vos_status = vos_wait_single_event(&pHostapdState->vosEvent,
10123 10000);
10124 if (!VOS_IS_STATUS_SUCCESS(vos_status)) {
10125 hddLog(LOGE, FL("SAP Stop Failed"));
10126 goto end;
10127 }
10128 }
10129 clear_bit(SOFTAP_BSS_STARTED, &ap_adapter->event_flags);
10130 wlan_hdd_decr_active_session(pHddCtx, ap_adapter->device_mode);
10131 hddLog(LOG1, FL("SAP Stop Success"));
10132
10133 if (0 != wlan_hdd_cfg80211_update_apies(ap_adapter)) {
10134 hddLog(LOGE, FL("SAP Not able to set AP IEs"));
10135 goto end;
10136 }
10137
10138 if (WLANSAP_StartBss(pHddCtx->pvosContext, hdd_hostapd_SAPEventCB,
10139 pConfig, (v_PVOID_t)ap_adapter->dev) != VOS_STATUS_SUCCESS) {
10140 hddLog(LOGE, FL("SAP Start Bss fail"));
10141 goto end;
10142 }
10143
10144 hddLog(LOG1, FL("Waiting for SAP to start"));
10145 vos_status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
10146 if (!VOS_IS_STATUS_SUCCESS(vos_status)) {
10147 hddLog(LOGE, FL("SAP Start failed"));
10148 goto end;
10149 }
10150 hddLog(LOG1, FL("SAP Start Success"));
10151 set_bit(SOFTAP_BSS_STARTED, &ap_adapter->event_flags);
10152 wlan_hdd_incr_active_session(pHddCtx, ap_adapter->device_mode);
10153 pHostapdState->bCommit = TRUE;
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053010154 if (!VOS_IS_STATUS_SUCCESS(hdd_dhcp_mdns_offload(ap_adapter))) {
10155 hddLog(VOS_TRACE_LEVEL_ERROR, FL("DHCP/MDNS offload Failed!!"));
10156 vos_event_reset(&pHostapdState->vosEvent);
10157 if (VOS_STATUS_SUCCESS == WLANSAP_StopBss(pHddCtx->pvosContext)) {
10158 vos_status = vos_wait_single_event(&pHostapdState->vosEvent,
10159 10000);
10160 if (!VOS_IS_STATUS_SUCCESS(vos_status)) {
10161 hddLog(LOGE, FL("SAP Stop Failed"));
10162 goto end;
10163 }
10164 }
10165 }
Kapil Gupta137ef892016-12-13 19:38:00 +053010166 }
10167end:
10168 mutex_unlock(&pHddCtx->sap_lock);
10169 return;
10170}
10171
10172/**
10173 * __hdd_sap_restart_handle() - to handle restarting of SAP
10174 * @work: name of the work
10175 *
10176 * Purpose of this function is to trigger sap start. this function
10177 * will be called from workqueue.
10178 *
10179 * Return: void.
10180 */
10181static void __hdd_sap_restart_handle(struct work_struct *work)
10182{
10183 hdd_adapter_t *sap_adapter;
10184 hdd_context_t *hdd_ctx = container_of(work,
10185 hdd_context_t,
10186 sap_start_work);
10187 if (0 != wlan_hdd_validate_context(hdd_ctx)) {
10188 vos_ssr_unprotect(__func__);
10189 return;
10190 }
10191 sap_adapter = hdd_get_adapter(hdd_ctx,
10192 WLAN_HDD_SOFTAP);
10193 if (sap_adapter == NULL) {
10194 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10195 FL("sap_adapter is NULL"));
10196 vos_ssr_unprotect(__func__);
10197 return;
10198 }
10199
10200 if (hdd_ctx->is_ch_avoid_in_progress) {
10201 sap_adapter->sessionCtx.ap.sapConfig.channel = AUTO_CHANNEL_SELECT;
10202 wlan_hdd_restart_sap(sap_adapter);
10203 hdd_change_ch_avoidance_status(hdd_ctx, false);
10204 }
Agrawal Ashish574b3e62017-02-09 18:58:34 +053010205 if (hdd_ctx->cfg_ini->enable_sap_auth_offload)
10206 wlan_hdd_restart_sap(sap_adapter);
Kapil Gupta137ef892016-12-13 19:38:00 +053010207}
10208
10209/**
10210 * hdd_sap_restart_handle() - to handle restarting of SAP
10211 * @work: name of the work
10212 *
10213 * Purpose of this function is to trigger sap start. this function
10214 * will be called from workqueue.
10215 *
10216 * Return: void.
10217 */
10218static void hdd_sap_restart_handle(struct work_struct *work)
10219{
10220 vos_ssr_protect(__func__);
10221 __hdd_sap_restart_handle(work);
10222 vos_ssr_unprotect(__func__);
10223}
10224
10225
Abhishek Singh78c691f2017-11-30 13:48:44 +053010226/**
10227 * __hdd_force_scc_with_ecsa_handle() - to handle force scc using ecsa
10228 * @work: name of the work
10229 *
10230 * Purpose of this function is to force SCC using ECSA. This function
10231 * will be called from workqueue.
10232 *
10233 * Return: void.
10234 */
10235static void
10236__hdd_force_scc_with_ecsa_handle(struct work_struct *work)
10237{
10238 hdd_adapter_t *sap_adapter;
10239 hdd_station_ctx_t *sta_ctx;
10240 hdd_adapter_t *sta_adapter;
Ganesh Kondabattini3655a6d2018-01-08 20:25:39 +053010241 ptSapContext sap_ctx = NULL;
10242 v_CONTEXT_t vos_ctx;
10243 tANI_U8 target_channel;
10244 tsap_Config_t *sap_config;
10245 bool sta_sap_scc_on_dfs_chan;
10246 eNVChannelEnabledType chan_state;
Abhishek Singh78c691f2017-11-30 13:48:44 +053010247 hdd_context_t *hdd_ctx = container_of(to_delayed_work(work),
10248 hdd_context_t,
10249 ecsa_chan_change_work);
10250
10251 if (wlan_hdd_validate_context(hdd_ctx))
10252 return;
10253
10254 sap_adapter = hdd_get_adapter(hdd_ctx,
10255 WLAN_HDD_SOFTAP);
10256 if (!sap_adapter) {
10257 hddLog(LOGE, FL("sap_adapter is NULL"));
10258 return;
10259 }
10260
Ganesh Kondabattini3655a6d2018-01-08 20:25:39 +053010261 vos_ctx = hdd_ctx->pvosContext;
10262 if (!vos_ctx) {
10263 hddLog(LOGE, FL("vos_ctx is NULL"));
10264 return;
10265 }
10266
10267 sap_ctx = VOS_GET_SAP_CB(vos_ctx);
10268 if (!sap_ctx) {
10269 hddLog(LOGE, FL("sap_ctx is NULL"));
10270 return;
10271 }
10272
10273 sap_config = &sap_adapter->sessionCtx.ap.sapConfig;
10274
10275 sta_sap_scc_on_dfs_chan = hdd_is_sta_sap_scc_allowed_on_dfs_chan(hdd_ctx);
10276
Abhishek Singh78c691f2017-11-30 13:48:44 +053010277 sta_adapter = hdd_get_adapter(hdd_ctx,
10278 WLAN_HDD_INFRA_STATION);
10279 if (!sta_adapter) {
10280 hddLog(LOGE, FL("sta_adapter is NULL"));
10281 return;
10282 }
Abhishek Singh78c691f2017-11-30 13:48:44 +053010283
Abhishek Singh10e17cf2018-03-12 14:34:22 +053010284 if (wlansap_chk_n_set_chan_change_in_progress(sap_ctx))
Abhishek Singh78c691f2017-11-30 13:48:44 +053010285 return;
Abhishek Singh10e17cf2018-03-12 14:34:22 +053010286 INIT_COMPLETION(sap_ctx->ecsa_info.chan_switch_comp);
10287
10288 sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(sta_adapter);
10289 if (sta_ctx->conn_info.connState != eConnectionState_Associated) {
10290 if (sta_ctx->conn_info.connState == eConnectionState_NotConnected) {
10291 chan_state = vos_nv_getChannelEnabledState(sap_ctx->channel);
10292 hddLog(LOG1, FL("sta not in connected state %d, sta_sap_scc_on_dfs_chan %d, chan_state %d"),
10293 sta_ctx->conn_info.connState, sta_sap_scc_on_dfs_chan,
10294 chan_state);
10295 if (sta_sap_scc_on_dfs_chan &&
10296 (chan_state == NV_CHANNEL_DFS)) {
10297 hddLog(LOGE, FL("Switch SAP to user configured channel"));
10298 target_channel = sap_config->user_config_channel;
10299 goto switch_channel;
10300 }
10301 }
10302 goto abort;
Abhishek Singh78c691f2017-11-30 13:48:44 +053010303 }
10304
Ganesh Kondabattini3655a6d2018-01-08 20:25:39 +053010305 target_channel = sta_ctx->conn_info.operationChannel;
10306switch_channel:
10307 hddLog(LOGE, FL("Switch SAP to %d channel"),
10308 target_channel);
Abhishek Singh10e17cf2018-03-12 14:34:22 +053010309 if (!wlansap_set_channel_change(vos_ctx, target_channel, true))
10310 return;
10311
10312abort:
10313 wlansap_reset_chan_change_in_progress(sap_ctx);
10314 complete(&sap_ctx->ecsa_info.chan_switch_comp);
Abhishek Singh78c691f2017-11-30 13:48:44 +053010315}
10316
10317/**
10318 * hdd_force_scc_with_ecsa_handle() - to handle force scc using ecsa
10319 * @work: name of the work
10320 *
10321 * Purpose of this function is to force SCC using ECSA. This function
10322 * will be called from workqueue.
10323 *
10324 * Return: void.
10325 */
10326static void
10327hdd_force_scc_with_ecsa_handle(struct work_struct *work)
10328{
10329 vos_ssr_protect(__func__);
10330 __hdd_force_scc_with_ecsa_handle(work);
10331 vos_ssr_unprotect(__func__);
10332}
10333
Abhishek Singh10e17cf2018-03-12 14:34:22 +053010334int hdd_wait_for_ecsa_complete(hdd_context_t *hdd_ctx)
10335{
10336 int ret;
10337 ptSapContext sap_ctx = NULL;
10338 v_CONTEXT_t vos_ctx;
10339
10340 vos_ctx = hdd_ctx->pvosContext;
10341 if (!vos_ctx) {
10342 hddLog(LOGE, FL("vos_ctx is NULL"));
10343 return 0;
10344 }
10345
10346 sap_ctx = VOS_GET_SAP_CB(vos_ctx);
10347 if (!sap_ctx) {
10348 hddLog(LOG1, FL("sap_ctx is NULL"));
10349 return 0;
10350 }
10351 if(!sap_ctx->isSapSessionOpen) {
10352 hddLog(LOG1, FL("sap session not opened, SAP in state %d"),
10353 sap_ctx->sapsMachine);
10354 return 0;
10355 }
10356
10357 if (!wlansap_get_change_in_progress(sap_ctx)) {
10358 hddLog(LOG1, FL("channel switch not in progress"));
10359 return 0;
10360 }
10361 ret = wait_for_completion_timeout(&sap_ctx->ecsa_info.chan_switch_comp,
10362 msecs_to_jiffies(HDD_SAP_CHAN_CNG_WAIT_TIME));
10363 if (!ret)
10364 {
10365 hddLog(LOGE, FL("Timeout waiting for SAP channel switch"));
10366 return ret;
10367 }
10368
10369 return 0;
10370}
10371
10372
Ganesh Kondabattini3655a6d2018-01-08 20:25:39 +053010373/**
10374 * hdd_is_sta_sap_scc_allowed_on_dfs_chan() - check if sta+sap scc allowed on
10375 * dfs chan
10376 * @hdd_ctx: pointer to hdd context
10377 *
10378 * This function used to check if sta+sap scc allowed on DFS channel.
10379 *
10380 * Return: None
10381 */
10382bool hdd_is_sta_sap_scc_allowed_on_dfs_chan(hdd_context_t *hdd_ctx)
10383{
10384 if (hdd_ctx->cfg_ini->force_scc_with_ecsa &&
10385 hdd_ctx->cfg_ini->sta_sap_scc_on_dfs_chan)
10386 return true;
10387 else
10388 return false;
10389}
10390
Jeff Johnson295189b2012-06-20 16:38:30 -070010391VOS_STATUS hdd_stop_all_adapters( hdd_context_t *pHddCtx )
10392{
10393 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
10394 VOS_STATUS status;
10395 hdd_adapter_t *pAdapter;
10396
10397 ENTER();
10398
10399 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
10400
10401 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
10402 {
10403 pAdapter = pAdapterNode->pAdapter;
Jeff Johnson295189b2012-06-20 16:38:30 -070010404
Agarwal Ashish3a38bd12014-06-12 15:16:52 +053010405 hdd_stop_adapter( pHddCtx, pAdapter, VOS_TRUE );
Jeff Johnson295189b2012-06-20 16:38:30 -070010406
10407 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
10408 pAdapterNode = pNext;
10409 }
10410
10411 EXIT();
10412
10413 return VOS_STATUS_SUCCESS;
10414}
10415
Rajeev Kumarf999e582014-01-09 17:33:29 -080010416
10417#ifdef FEATURE_WLAN_BATCH_SCAN
10418/**---------------------------------------------------------------------------
10419
10420 \brief hdd_deinit_batch_scan () - This function cleans up batch scan data
10421 structures
10422
10423 \param - pAdapter Pointer to HDD adapter
10424
10425 \return - None
10426
10427 --------------------------------------------------------------------------*/
10428void hdd_deinit_batch_scan(hdd_adapter_t *pAdapter)
10429{
10430 tHddBatchScanRsp *pNode;
10431 tHddBatchScanRsp *pPrev;
10432
Siddharth Bhalb3e9b792014-02-24 15:14:16 +053010433 if (NULL == pAdapter)
Rajeev Kumarf999e582014-01-09 17:33:29 -080010434 {
Siddharth Bhalb3e9b792014-02-24 15:14:16 +053010435 hddLog(VOS_TRACE_LEVEL_ERROR,
10436 "%s: Adapter context is Null", __func__);
10437 return;
10438 }
10439
10440 pNode = pAdapter->pBatchScanRsp;
10441 while (pNode)
10442 {
10443 pPrev = pNode;
10444 pNode = pNode->pNext;
10445 vos_mem_free((v_VOID_t * )pPrev);
Rajeev Kumarf999e582014-01-09 17:33:29 -080010446 }
10447
10448 pAdapter->pBatchScanRsp = NULL;
10449 pAdapter->numScanList = 0;
10450 pAdapter->batchScanState = eHDD_BATCH_SCAN_STATE_STOPPED;
10451 pAdapter->prev_batch_id = 0;
10452
10453 return;
10454}
10455#endif
10456
10457
Jeff Johnson295189b2012-06-20 16:38:30 -070010458VOS_STATUS hdd_reset_all_adapters( hdd_context_t *pHddCtx )
10459{
10460 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
10461 VOS_STATUS status;
10462 hdd_adapter_t *pAdapter;
10463
10464 ENTER();
10465
10466 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
10467
10468 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
10469 {
10470 pAdapter = pAdapterNode->pAdapter;
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +053010471 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Jeff Johnson295189b2012-06-20 16:38:30 -070010472 netif_tx_disable(pAdapter->dev);
Hanumanth Reddy Pothulad864f312017-01-18 16:16:08 +053010473
10474 if (pHddCtx->cfg_ini->sap_internal_restart &&
10475 pAdapter->device_mode == WLAN_HDD_SOFTAP) {
10476 hddLog(LOG1, FL("driver supports sap restart"));
10477 vos_flush_work(&pHddCtx->sap_start_work);
10478 hdd_sap_indicate_disconnect_for_sta(pAdapter);
10479 hdd_cleanup_actionframe(pHddCtx, pAdapter);
Hanumanth Reddy Pothula15bc0fa2017-02-03 17:24:17 +053010480 hdd_softap_deinit_tx_rx(pAdapter, true);
10481 hdd_sap_destroy_timers(pAdapter);
Hanumanth Reddy Pothulad864f312017-01-18 16:16:08 +053010482 } else {
10483 netif_carrier_off(pAdapter->dev);
10484 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010485
Srinivas Girigowda66c05eb2013-07-14 13:06:01 -070010486 pAdapter->sessionCtx.station.hdd_ReassocScenario = VOS_FALSE;
Hanumanth Reddy Pothulada449f12018-03-13 18:19:19 +053010487
10488 if (pAdapter->device_mode == WLAN_HDD_MONITOR)
10489 pAdapter->sessionCtx.monitor.state = MON_MODE_STOP;
Srinivas Girigowda66c05eb2013-07-14 13:06:01 -070010490
Jeff Johnson295189b2012-06-20 16:38:30 -070010491 hdd_deinit_tx_rx(pAdapter);
Agarwal Ashish6267caa2014-08-06 19:16:21 +053010492
Katya Nigam1fd24402015-02-16 14:52:19 +053010493 if(pAdapter->device_mode == WLAN_HDD_IBSS )
10494 hdd_ibss_deinit_tx_rx(pAdapter);
10495
Nirav Shah7e3c8132015-06-22 23:51:42 +053010496 status = hdd_sta_id_hash_detach(pAdapter);
10497 if (status != VOS_STATUS_SUCCESS)
10498 hddLog(VOS_TRACE_LEVEL_ERROR,
10499 FL("sta id hash detach failed for session id %d"),
10500 pAdapter->sessionId);
10501
Agarwal Ashish6267caa2014-08-06 19:16:21 +053010502 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
10503
Madan Mohan Koyyalamudi8c6dec82013-09-26 15:56:13 +053010504 if (test_bit(WMM_INIT_DONE, &pAdapter->event_flags))
10505 {
10506 hdd_wmm_adapter_close( pAdapter );
10507 clear_bit(WMM_INIT_DONE, &pAdapter->event_flags);
10508 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010509
Siddharth Bhal2db319d2014-12-03 12:37:18 +053010510 if (test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
10511 {
10512 clear_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags);
10513 }
10514
Rajeev Kumarf999e582014-01-09 17:33:29 -080010515#ifdef FEATURE_WLAN_BATCH_SCAN
10516 if (eHDD_BATCH_SCAN_STATE_STARTED == pAdapter->batchScanState)
10517 {
10518 hdd_deinit_batch_scan(pAdapter);
10519 }
10520#endif
10521
Mahesh A Saptasagarf5b8eff2015-01-31 01:07:07 +053010522#ifdef FEATURE_WLAN_TDLS
10523 mutex_lock(&pHddCtx->tdls_lock);
Pradeep Reddy POTTETI2d4d5c42015-03-03 14:34:19 +053010524 wlan_hdd_tdls_exit(pAdapter, TRUE);
Mahesh A Saptasagarf5b8eff2015-01-31 01:07:07 +053010525 mutex_unlock(&pHddCtx->tdls_lock);
10526#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010527 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
10528 pAdapterNode = pNext;
10529 }
10530
10531 EXIT();
10532
10533 return VOS_STATUS_SUCCESS;
10534}
10535
Abhishek Singhbbe0b2a2016-12-05 11:57:36 +053010536/**
Abhishek Singh5a597e62016-12-05 15:16:30 +053010537 * hdd_get_bss_entry() - Get the bss entry matching the chan, bssid and ssid
10538 * @wiphy: wiphy
10539 * @channel: channel of the BSS to find
10540 * @bssid: bssid of the BSS to find
10541 * @ssid: ssid of the BSS to find
10542 * @ssid_len: ssid len of of the BSS to find
10543 *
10544 * The API is a wrapper to get bss from kernel matching the chan,
10545 * bssid and ssid
10546 *
10547 * Return: Void
10548 */
10549#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 1, 0)) \
10550 && !defined(WITH_BACKPORTS) && !defined(IEEE80211_PRIVACY)
10551
10552struct cfg80211_bss* hdd_get_bss_entry(struct wiphy *wiphy,
10553 struct ieee80211_channel *channel,
10554 const u8 *bssid,
10555 const u8 *ssid, size_t ssid_len)
10556{
10557 return cfg80211_get_bss(wiphy, channel, bssid,
10558 ssid, ssid_len,
10559 WLAN_CAPABILITY_ESS,
10560 WLAN_CAPABILITY_ESS);
10561}
10562#else
10563struct cfg80211_bss* hdd_get_bss_entry(struct wiphy *wiphy,
10564 struct ieee80211_channel *channel,
10565 const u8 *bssid,
10566 const u8 *ssid, size_t ssid_len)
10567{
10568 return cfg80211_get_bss(wiphy, channel, bssid,
10569 ssid, ssid_len,
10570 IEEE80211_BSS_TYPE_ESS,
10571 IEEE80211_PRIVACY_ANY);
10572}
10573#endif
10574
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053010575#if defined(CFG80211_CONNECT_BSS) || \
10576 (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 7, 0))
10577
10578#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 11, 0) || \
10579 defined (CFG80211_CONNECT_TIMEOUT_REASON_CODE)
10580/**
10581 * hdd_connect_bss() - helper function to send connection status to supplicant
10582 * @dev: network device
10583 * @bssid: bssid to which we want to associate
10584 * @bss: information about connected bss
10585 * @req_ie: Request Information Element
10586 * @req_ie_len: len of the req IE
10587 * @resp_ie: Response IE
10588 * @resp_ie_len: len of ht response IE
10589 * @status: status
10590 * @gfp: Kernel Flag
10591 *
10592 * This is a helper function to send connection status to supplicant
10593 * and gets invoked from wrapper API
10594 *
10595 * Return: Void
10596 */
10597static void hdd_connect_bss(struct net_device *dev,
10598 const u8 *bssid,
10599 struct cfg80211_bss *bss,
10600 const u8 *req_ie,
10601 size_t req_ie_len,
10602 const u8 *resp_ie,
10603 size_t resp_ie_len,
10604 u16 status,
10605 gfp_t gfp)
10606{
10607 cfg80211_connect_bss(dev, bssid, bss, req_ie, req_ie_len,
10608 resp_ie, resp_ie_len, status, gfp, NL80211_TIMEOUT_UNSPECIFIED);
10609}
10610#else
10611/**
10612 * hdd_connect_bss() - helper function to send connection status to supplicant
10613 * @dev: network device
10614 * @bssid: bssid to which we want to associate
10615 * @bss: information about connected bss
10616 * @req_ie: Request Information Element
10617 * @req_ie_len: len of the req IE
10618 * @resp_ie: Response IE
10619 * @resp_ie_len: len of ht response IE
10620 * @status: status
10621 * @gfp: Kernel Flag
10622 *
10623 * This is a helper function to send connection status to supplicant
10624 * and gets invoked from wrapper API
10625 *
10626 * Return: Void
10627 */
10628static void hdd_connect_bss(struct net_device *dev,
10629 const u8 *bssid,
10630 struct cfg80211_bss *bss,
10631 const u8 *req_ie,
10632 size_t req_ie_len,
10633 const u8 *resp_ie,
10634 size_t resp_ie_len,
10635 u16 status,
10636 gfp_t gfp)
10637{
10638 cfg80211_connect_bss(dev, bssid, bss, req_ie, req_ie_len,
10639 resp_ie, resp_ie_len, status, gfp);
10640}
10641#endif
10642
Abhishek Singh5a597e62016-12-05 15:16:30 +053010643/**
Abhishek Singhbbe0b2a2016-12-05 11:57:36 +053010644 * hdd_connect_result() - API to send connection status to supplicant
10645 * @dev: network device
10646 * @bssid: bssid to which we want to associate
10647 * @roam_info: information about connected bss
10648 * @req_ie: Request Information Element
10649 * @req_ie_len: len of the req IE
10650 * @resp_ie: Response IE
10651 * @resp_ie_len: len of ht response IE
10652 * @status: status
10653 * @gfp: Kernel Flag
10654 *
10655 * The API is a wrapper to send connection status to supplicant
10656 *
10657 * Return: Void
10658 */
Abhishek Singhbbe0b2a2016-12-05 11:57:36 +053010659void hdd_connect_result(struct net_device *dev,
10660 const u8 *bssid,
10661 tCsrRoamInfo *roam_info,
10662 const u8 *req_ie,
10663 size_t req_ie_len,
10664 const u8 *resp_ie,
10665 size_t resp_ie_len,
10666 u16 status,
10667 gfp_t gfp)
10668{
10669 hdd_adapter_t *padapter = (hdd_adapter_t *) netdev_priv(dev);
10670 struct cfg80211_bss *bss = NULL;
10671
10672 if (WLAN_STATUS_SUCCESS == status) {
10673 struct ieee80211_channel *chan;
10674 int freq;
10675 int chan_no = roam_info->pBssDesc->channelId;;
10676
10677 if (chan_no <= 14)
10678 freq = ieee80211_channel_to_frequency(chan_no,
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053010679 HDD_NL80211_BAND_2GHZ);
Abhishek Singhbbe0b2a2016-12-05 11:57:36 +053010680 else
10681 freq = ieee80211_channel_to_frequency(chan_no,
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053010682 HDD_NL80211_BAND_5GHZ);
Abhishek Singhbbe0b2a2016-12-05 11:57:36 +053010683
10684 chan = ieee80211_get_channel(padapter->wdev.wiphy, freq);
Abhishek Singh5a597e62016-12-05 15:16:30 +053010685 bss = hdd_get_bss_entry(padapter->wdev.wiphy,
10686 chan, bssid,
10687 roam_info->u.pConnectedProfile->SSID.ssId,
10688 roam_info->u.pConnectedProfile->SSID.length);
Abhishek Singhbbe0b2a2016-12-05 11:57:36 +053010689 }
10690
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053010691 hdd_connect_bss(dev, bssid, bss, req_ie, req_ie_len, resp_ie, resp_ie_len,
10692 status, gfp);
Abhishek Singhbbe0b2a2016-12-05 11:57:36 +053010693}
10694#else
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053010695/**
10696 * hdd_connect_result() - API to send connection status to supplicant
10697 * @dev: network device
10698 * @bssid: bssid to which we want to associate
10699 * @roam_info: information about connected bss
10700 * @req_ie: Request Information Element
10701 * @req_ie_len: len of the req IE
10702 * @resp_ie: Response IE
10703 * @resp_ie_len: len of ht response IE
10704 * @status: status
10705 * @gfp: Kernel Flag
10706 *
10707 * The API is a wrapper to send connection status to supplicant
10708 *
10709 * Return: Void
10710 */
Abhishek Singhbbe0b2a2016-12-05 11:57:36 +053010711void hdd_connect_result(struct net_device *dev,
10712 const u8 *bssid,
10713 tCsrRoamInfo *roam_info,
10714 const u8 *req_ie,
10715 size_t req_ie_len,
10716 const u8 * resp_ie,
10717 size_t resp_ie_len,
10718 u16 status,
10719 gfp_t gfp)
10720{
10721 cfg80211_connect_result(dev, bssid, req_ie, req_ie_len,
10722 resp_ie, resp_ie_len, status, gfp);
10723}
10724#endif
10725
Jeff Johnson295189b2012-06-20 16:38:30 -070010726VOS_STATUS hdd_start_all_adapters( hdd_context_t *pHddCtx )
10727{
10728 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
10729 VOS_STATUS status;
10730 hdd_adapter_t *pAdapter;
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +053010731 eConnectionState connState;
Hanumanth Reddy Pothulada449f12018-03-13 18:19:19 +053010732 v_CONTEXT_t pVosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -070010733
10734 ENTER();
10735
10736 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
10737
10738 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
10739 {
10740 pAdapter = pAdapterNode->pAdapter;
10741
Kumar Anand82c009f2014-05-29 00:29:42 -070010742 hdd_wmm_init( pAdapter );
10743
Jeff Johnson295189b2012-06-20 16:38:30 -070010744 switch(pAdapter->device_mode)
10745 {
10746 case WLAN_HDD_INFRA_STATION:
10747 case WLAN_HDD_P2P_CLIENT:
Jeff Johnsone7245742012-09-05 17:12:55 -070010748 case WLAN_HDD_P2P_DEVICE:
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +053010749
10750 connState = (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState;
10751
Jeff Johnson295189b2012-06-20 16:38:30 -070010752 hdd_init_station_mode(pAdapter);
10753 /* Open the gates for HDD to receive Wext commands */
10754 pAdapter->isLinkUpSvcNeeded = FALSE;
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070010755 pHddCtx->scan_info.mScanPending = FALSE;
10756 pHddCtx->scan_info.waitScanResult = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070010757
10758 //Trigger the initial scan
Mukul Sharmae74e42c2015-08-06 23:55:49 +053010759 if (!pHddCtx->isLogpInProgress)
10760 hdd_wlan_initial_scan(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070010761
10762 //Indicate disconnect event to supplicant if associated previously
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +053010763 if (eConnectionState_Associated == connState ||
10764 eConnectionState_IbssConnected == connState )
Jeff Johnson295189b2012-06-20 16:38:30 -070010765 {
10766 union iwreq_data wrqu;
10767 memset(&wrqu, '\0', sizeof(wrqu));
10768 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
10769 memset(wrqu.ap_addr.sa_data,'\0',ETH_ALEN);
10770 wireless_send_event(pAdapter->dev, SIOCGIWAP, &wrqu, NULL);
Srinivas Girigowda66c05eb2013-07-14 13:06:01 -070010771 pAdapter->sessionCtx.station.hdd_ReassocScenario = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070010772
Jeff Johnson295189b2012-06-20 16:38:30 -070010773 /* indicate disconnected event to nl80211 */
Mahesh A Saptasagar9ff4bcc2016-06-01 17:17:50 +053010774 wlan_hdd_cfg80211_indicate_disconnect(pAdapter->dev, false,
Mahesh A Saptasagarb5a15142016-05-25 11:27:43 +053010775 WLAN_REASON_UNSPECIFIED);
Jeff Johnson295189b2012-06-20 16:38:30 -070010776 }
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +053010777 else if (eConnectionState_Connecting == connState)
10778 {
10779 /*
10780 * Indicate connect failure to supplicant if we were in the
10781 * process of connecting
10782 */
Abhishek Singhbbe0b2a2016-12-05 11:57:36 +053010783 hdd_connect_result(pAdapter->dev, NULL, NULL,
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +053010784 NULL, 0, NULL, 0,
10785 WLAN_STATUS_ASSOC_DENIED_UNSPEC,
10786 GFP_KERNEL);
10787 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010788 break;
10789
10790 case WLAN_HDD_SOFTAP:
Hanumanth Reddy Pothulad864f312017-01-18 16:16:08 +053010791 if (pHddCtx->cfg_ini->sap_internal_restart) {
Hanumanth Reddy Pothula15bc0fa2017-02-03 17:24:17 +053010792 hdd_init_ap_mode(pAdapter, true);
Hanumanth Reddy Pothulad864f312017-01-18 16:16:08 +053010793 status = hdd_sta_id_hash_attach(pAdapter);
10794 if (VOS_STATUS_SUCCESS != status)
10795 {
10796 hddLog(VOS_TRACE_LEVEL_FATAL,
10797 FL("failed to attach hash for"));
10798 }
10799 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010800 break;
10801
10802 case WLAN_HDD_P2P_GO:
Sameer Thalappiledf0d792013-08-09 14:31:03 -070010803 hddLog(VOS_TRACE_LEVEL_ERROR, "%s [SSR] send stop ap to supplicant",
Jeff Johnson295189b2012-06-20 16:38:30 -070010804 __func__);
Sameer Thalappiledf0d792013-08-09 14:31:03 -070010805 cfg80211_ap_stopped(pAdapter->dev, GFP_KERNEL);
Jeff Johnson295189b2012-06-20 16:38:30 -070010806 break;
10807
10808 case WLAN_HDD_MONITOR:
Hanumanth Reddy Pothulada449f12018-03-13 18:19:19 +053010809 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
10810
10811 hddLog(VOS_TRACE_LEVEL_INFO, FL("[SSR] monitor mode"));
10812 if (!pVosContext) {
10813 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos context is NULL"));
10814 break;
10815 }
10816
10817 hdd_init_tx_rx(pAdapter);
10818 WLANTL_SetMonRxCbk( pVosContext, hdd_rx_packet_monitor_cbk);
Jeff Johnson295189b2012-06-20 16:38:30 -070010819 break;
Hanumanth Reddy Pothulada449f12018-03-13 18:19:19 +053010820
Jeff Johnson295189b2012-06-20 16:38:30 -070010821 default:
10822 break;
10823 }
10824
10825 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
10826 pAdapterNode = pNext;
10827 }
10828
10829 EXIT();
10830
10831 return VOS_STATUS_SUCCESS;
10832}
10833
10834VOS_STATUS hdd_reconnect_all_adapters( hdd_context_t *pHddCtx )
10835{
10836 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
10837 hdd_adapter_t *pAdapter;
10838 VOS_STATUS status;
10839 v_U32_t roamId;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010840 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070010841
10842 ENTER();
10843
10844 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
10845
10846 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
10847 {
10848 pAdapter = pAdapterNode->pAdapter;
10849
10850 if( (WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
10851 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
10852 {
10853 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
10854 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
10855
Abhishek Singhf4669da2014-05-26 15:07:49 +053010856 hddLog(VOS_TRACE_LEVEL_INFO,
10857 "%s: Set HDD connState to eConnectionState_NotConnected",
10858 __func__);
Ganesh Kondabattini04338412015-09-14 15:39:09 +053010859 spin_lock_bh(&pAdapter->lock_for_active_session);
10860 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState)
10861 {
10862 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
10863 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010864 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
Ganesh Kondabattini04338412015-09-14 15:39:09 +053010865 spin_unlock_bh(&pAdapter->lock_for_active_session);
Jeff Johnson295189b2012-06-20 16:38:30 -070010866 init_completion(&pAdapter->disconnect_comp_var);
10867 sme_RoamDisconnect(pHddCtx->hHal, pAdapter->sessionId,
10868 eCSR_DISCONNECT_REASON_UNSPECIFIED);
10869
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010870 ret = wait_for_completion_interruptible_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -070010871 &pAdapter->disconnect_comp_var,
10872 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010873 if (0 >= ret)
10874 hddLog(LOGE, "%s: failure waiting for disconnect_comp_var %ld",
10875 __func__, ret);
Jeff Johnson295189b2012-06-20 16:38:30 -070010876
10877 pWextState->roamProfile.csrPersona = pAdapter->device_mode;
10878 pHddCtx->isAmpAllowed = VOS_FALSE;
10879 sme_RoamConnect(pHddCtx->hHal,
10880 pAdapter->sessionId, &(pWextState->roamProfile),
10881 &roamId);
10882 }
10883
10884 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
10885 pAdapterNode = pNext;
10886 }
10887
10888 EXIT();
10889
10890 return VOS_STATUS_SUCCESS;
10891}
10892
Sudhir Sattayappa Kohalli90e4c752013-03-21 14:25:04 -070010893void hdd_dump_concurrency_info(hdd_context_t *pHddCtx)
10894{
10895 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
10896 VOS_STATUS status;
10897 hdd_adapter_t *pAdapter;
10898 hdd_station_ctx_t *pHddStaCtx;
10899 hdd_ap_ctx_t *pHddApCtx;
10900 hdd_hostapd_state_t * pHostapdState;
10901 tCsrBssid staBssid = { 0 }, p2pBssid = { 0 }, apBssid = { 0 };
10902 v_U8_t staChannel = 0, p2pChannel = 0, apChannel = 0;
10903 const char *p2pMode = "DEV";
10904 const char *ccMode = "Standalone";
Sudhir Sattayappa Kohalli90e4c752013-03-21 14:25:04 -070010905
10906 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
10907 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
10908 {
10909 pAdapter = pAdapterNode->pAdapter;
10910 switch (pAdapter->device_mode) {
10911 case WLAN_HDD_INFRA_STATION:
10912 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
10913 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState) {
10914 staChannel = pHddStaCtx->conn_info.operationChannel;
10915 memcpy(staBssid, pHddStaCtx->conn_info.bssId, sizeof(staBssid));
10916 }
10917 break;
10918 case WLAN_HDD_P2P_CLIENT:
10919 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
10920 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState) {
10921 p2pChannel = pHddStaCtx->conn_info.operationChannel;
10922 memcpy(p2pBssid, pHddStaCtx->conn_info.bssId, sizeof(p2pBssid));
10923 p2pMode = "CLI";
10924 }
10925 break;
10926 case WLAN_HDD_P2P_GO:
10927 pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
10928 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
10929 if (pHostapdState->bssState == BSS_START && pHostapdState->vosStatus==VOS_STATUS_SUCCESS) {
10930 p2pChannel = pHddApCtx->operatingChannel;
10931 memcpy(p2pBssid, pAdapter->macAddressCurrent.bytes, sizeof(p2pBssid));
10932 }
10933 p2pMode = "GO";
10934 break;
10935 case WLAN_HDD_SOFTAP:
10936 pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
10937 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
10938 if (pHostapdState->bssState == BSS_START && pHostapdState->vosStatus==VOS_STATUS_SUCCESS) {
10939 apChannel = pHddApCtx->operatingChannel;
10940 memcpy(apBssid, pAdapter->macAddressCurrent.bytes, sizeof(apBssid));
10941 }
10942 break;
10943 default:
10944 break;
10945 }
10946 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
10947 pAdapterNode = pNext;
10948 }
10949 if (staChannel > 0 && (apChannel > 0 || p2pChannel > 0)) {
10950 ccMode = (p2pChannel==staChannel||apChannel==staChannel) ? "SCC" : "MCC";
10951 }
Yeshwanth Sriram Guntuka0004c0b2017-12-06 14:43:49 +053010952 hddLog(VOS_TRACE_LEVEL_ERROR, "wlan(%d) " MAC_ADDRESS_STR " %s",
10953 staChannel, MAC_ADDR_ARRAY(staBssid), ccMode);
Sudhir Sattayappa Kohalli90e4c752013-03-21 14:25:04 -070010954 if (p2pChannel > 0) {
Sushant Kaushikdc3184b2015-10-09 12:00:21 +053010955 hddLog(VOS_TRACE_LEVEL_ERROR, "p2p-%s(%d) " MAC_ADDRESS_STR,
Sudhir Sattayappa Kohalli90e4c752013-03-21 14:25:04 -070010956 p2pMode, p2pChannel, MAC_ADDR_ARRAY(p2pBssid));
10957 }
10958 if (apChannel > 0) {
Sushant Kaushikdc3184b2015-10-09 12:00:21 +053010959 hddLog(VOS_TRACE_LEVEL_ERROR, "AP(%d) " MAC_ADDRESS_STR,
Sudhir Sattayappa Kohalli90e4c752013-03-21 14:25:04 -070010960 apChannel, MAC_ADDR_ARRAY(apBssid));
10961 }
10962
10963 if (p2pChannel > 0 && apChannel > 0) {
10964 hddLog(VOS_TRACE_LEVEL_ERROR, "Error concurrent SAP %d and P2P %d which is not support", apChannel, p2pChannel);
10965 }
10966}
10967
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -070010968bool hdd_is_ssr_required( void)
Jeff Johnson295189b2012-06-20 16:38:30 -070010969{
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -070010970 return (isSsrRequired == HDD_SSR_REQUIRED);
Jeff Johnson295189b2012-06-20 16:38:30 -070010971}
10972
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -070010973/* Once SSR is disabled then it cannot be set. */
10974void hdd_set_ssr_required( e_hdd_ssr_required value)
Jeff Johnson295189b2012-06-20 16:38:30 -070010975{
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -070010976 if (HDD_SSR_DISABLED == isSsrRequired)
10977 return;
10978
Jeff Johnson295189b2012-06-20 16:38:30 -070010979 isSsrRequired = value;
10980}
10981
Hema Aparna Medicharla6b4d4f32015-06-23 04:09:12 +053010982void hdd_set_pre_close( hdd_context_t *pHddCtx)
10983{
10984 sme_PreClose(pHddCtx->hHal);
10985}
10986
Jeff Johnson295189b2012-06-20 16:38:30 -070010987VOS_STATUS hdd_get_front_adapter( hdd_context_t *pHddCtx,
10988 hdd_adapter_list_node_t** ppAdapterNode)
10989{
10990 VOS_STATUS status;
Mukul Sharmaae1266d2015-06-26 15:29:53 +053010991 spin_lock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -070010992 status = hdd_list_peek_front ( &pHddCtx->hddAdapters,
10993 (hdd_list_node_t**) ppAdapterNode );
Mukul Sharmaae1266d2015-06-26 15:29:53 +053010994 spin_unlock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -070010995 return status;
10996}
10997
10998VOS_STATUS hdd_get_next_adapter( hdd_context_t *pHddCtx,
10999 hdd_adapter_list_node_t* pAdapterNode,
11000 hdd_adapter_list_node_t** pNextAdapterNode)
11001{
11002 VOS_STATUS status;
Mukul Sharmaae1266d2015-06-26 15:29:53 +053011003 spin_lock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -070011004 status = hdd_list_peek_next ( &pHddCtx->hddAdapters,
11005 (hdd_list_node_t*) pAdapterNode,
11006 (hdd_list_node_t**)pNextAdapterNode );
11007
Mukul Sharmaae1266d2015-06-26 15:29:53 +053011008 spin_unlock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -070011009 return status;
11010}
11011
11012VOS_STATUS hdd_remove_adapter( hdd_context_t *pHddCtx,
11013 hdd_adapter_list_node_t* pAdapterNode)
11014{
11015 VOS_STATUS status;
Mukul Sharmaae1266d2015-06-26 15:29:53 +053011016 spin_lock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -070011017 status = hdd_list_remove_node ( &pHddCtx->hddAdapters,
11018 &pAdapterNode->node );
Mukul Sharmaae1266d2015-06-26 15:29:53 +053011019 spin_unlock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -070011020 return status;
11021}
11022
11023VOS_STATUS hdd_remove_front_adapter( hdd_context_t *pHddCtx,
11024 hdd_adapter_list_node_t** ppAdapterNode)
11025{
11026 VOS_STATUS status;
Mukul Sharmaae1266d2015-06-26 15:29:53 +053011027 spin_lock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -070011028 status = hdd_list_remove_front( &pHddCtx->hddAdapters,
11029 (hdd_list_node_t**) ppAdapterNode );
Mukul Sharmaae1266d2015-06-26 15:29:53 +053011030 spin_unlock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -070011031 return status;
11032}
11033
11034VOS_STATUS hdd_add_adapter_back( hdd_context_t *pHddCtx,
11035 hdd_adapter_list_node_t* pAdapterNode)
11036{
11037 VOS_STATUS status;
Mukul Sharmaae1266d2015-06-26 15:29:53 +053011038 spin_lock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -070011039 status = hdd_list_insert_back ( &pHddCtx->hddAdapters,
11040 (hdd_list_node_t*) pAdapterNode );
Mukul Sharmaae1266d2015-06-26 15:29:53 +053011041 spin_unlock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -070011042 return status;
11043}
11044
11045VOS_STATUS hdd_add_adapter_front( hdd_context_t *pHddCtx,
11046 hdd_adapter_list_node_t* pAdapterNode)
11047{
11048 VOS_STATUS status;
Mukul Sharmaae1266d2015-06-26 15:29:53 +053011049 spin_lock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -070011050 status = hdd_list_insert_front ( &pHddCtx->hddAdapters,
11051 (hdd_list_node_t*) pAdapterNode );
Mukul Sharmaae1266d2015-06-26 15:29:53 +053011052 spin_unlock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -070011053 return status;
11054}
11055
11056hdd_adapter_t * hdd_get_adapter_by_macaddr( hdd_context_t *pHddCtx,
11057 tSirMacAddr macAddr )
11058{
11059 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
11060 hdd_adapter_t *pAdapter;
11061 VOS_STATUS status;
11062
11063 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
11064
11065 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
11066 {
11067 pAdapter = pAdapterNode->pAdapter;
11068
11069 if( pAdapter && vos_mem_compare( pAdapter->macAddressCurrent.bytes,
11070 macAddr, sizeof(tSirMacAddr) ) )
11071 {
11072 return pAdapter;
11073 }
11074 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
11075 pAdapterNode = pNext;
11076 }
11077
11078 return NULL;
11079
11080}
11081
11082hdd_adapter_t * hdd_get_adapter_by_name( hdd_context_t *pHddCtx, tANI_U8 *name )
11083{
11084 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
11085 hdd_adapter_t *pAdapter;
11086 VOS_STATUS status;
11087
11088 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
11089
11090 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
11091 {
11092 pAdapter = pAdapterNode->pAdapter;
11093
11094 if( pAdapter && !strncmp( pAdapter->dev->name, (const char *)name,
11095 IFNAMSIZ ) )
11096 {
11097 return pAdapter;
11098 }
11099 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
11100 pAdapterNode = pNext;
11101 }
11102
11103 return NULL;
11104
11105}
11106
Ganesh Kondabattinicbfdc392015-09-11 19:12:59 +053011107hdd_adapter_t *hdd_get_adapter_by_sme_session_id( hdd_context_t *pHddCtx,
11108 tANI_U32 sme_session_id )
11109{
11110 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
11111 hdd_adapter_t *pAdapter;
11112 VOS_STATUS vos_status;
11113
11114
11115 vos_status = hdd_get_front_adapter( pHddCtx, &pAdapterNode);
11116
11117 while ((NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == vos_status))
11118 {
11119 pAdapter = pAdapterNode->pAdapter;
11120
11121 if (pAdapter->sessionId == sme_session_id)
11122 return pAdapter;
11123
11124 vos_status = hdd_get_next_adapter(pHddCtx, pAdapterNode, &pNext);
11125 pAdapterNode = pNext;
11126 }
11127
11128 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11129 "%s: sme_session_id %d does not exist with host",
11130 __func__, sme_session_id);
11131
11132 return NULL;
11133}
11134
Jeff Johnson295189b2012-06-20 16:38:30 -070011135hdd_adapter_t * hdd_get_adapter( hdd_context_t *pHddCtx, device_mode_t mode )
11136{
11137 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
11138 hdd_adapter_t *pAdapter;
11139 VOS_STATUS status;
11140
11141 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
11142
11143 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
11144 {
11145 pAdapter = pAdapterNode->pAdapter;
11146
11147 if( pAdapter && (mode == pAdapter->device_mode) )
11148 {
11149 return pAdapter;
11150 }
11151 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
11152 pAdapterNode = pNext;
11153 }
11154
11155 return NULL;
11156
11157}
11158
11159//Remove this function later
11160hdd_adapter_t * hdd_get_mon_adapter( hdd_context_t *pHddCtx )
11161{
11162 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
11163 hdd_adapter_t *pAdapter;
11164 VOS_STATUS status;
11165
11166 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
11167
11168 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
11169 {
11170 pAdapter = pAdapterNode->pAdapter;
11171
11172 if( pAdapter && WLAN_HDD_MONITOR == pAdapter->device_mode )
11173 {
11174 return pAdapter;
11175 }
11176
11177 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
11178 pAdapterNode = pNext;
11179 }
11180
11181 return NULL;
11182
11183}
11184
Jeff Johnson295189b2012-06-20 16:38:30 -070011185/**---------------------------------------------------------------------------
11186
Mahesh A Saptasgar64534612014-09-23 13:13:33 +053011187 \brief hdd_get_operating_channel() -
Jeff Johnson295189b2012-06-20 16:38:30 -070011188
11189 This API returns the operating channel of the requested device mode
11190
11191 \param - pHddCtx - Pointer to the HDD context.
11192 - mode - Device mode for which operating channel is required
11193 suported modes - WLAN_HDD_INFRA_STATION, WLAN_HDD_P2P_CLIENT
11194 WLAN_HDD_SOFTAP, WLAN_HDD_P2P_GO.
11195 \return - channel number. "0" id the requested device is not found OR it is not connected.
11196 --------------------------------------------------------------------------*/
11197v_U8_t hdd_get_operating_channel( hdd_context_t *pHddCtx, device_mode_t mode )
11198{
11199 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
11200 VOS_STATUS status;
11201 hdd_adapter_t *pAdapter;
11202 v_U8_t operatingChannel = 0;
11203
11204 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
11205
11206 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
11207 {
11208 pAdapter = pAdapterNode->pAdapter;
11209
11210 if( mode == pAdapter->device_mode )
11211 {
11212 switch(pAdapter->device_mode)
11213 {
11214 case WLAN_HDD_INFRA_STATION:
11215 case WLAN_HDD_P2P_CLIENT:
11216 if( hdd_connIsConnected( WLAN_HDD_GET_STATION_CTX_PTR( pAdapter )) )
11217 operatingChannel = (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.operationChannel;
11218 break;
11219 case WLAN_HDD_SOFTAP:
11220 case WLAN_HDD_P2P_GO:
11221 /*softap connection info */
11222 if(test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
11223 operatingChannel = (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->operatingChannel;
11224 break;
11225 default:
11226 break;
11227 }
11228
11229 break; //Found the device of interest. break the loop
11230 }
11231
11232 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
11233 pAdapterNode = pNext;
11234 }
11235 return operatingChannel;
11236}
11237
11238#ifdef WLAN_FEATURE_PACKET_FILTERING
11239/**---------------------------------------------------------------------------
11240
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053011241 \brief __hdd_set_multicast_list() -
Jeff Johnson295189b2012-06-20 16:38:30 -070011242
11243 This used to set the multicast address list.
11244
11245 \param - dev - Pointer to the WLAN device.
11246 - skb - Pointer to OS packet (sk_buff).
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053011247 \return - success/fail
Jeff Johnson295189b2012-06-20 16:38:30 -070011248
11249 --------------------------------------------------------------------------*/
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053011250static void __hdd_set_multicast_list(struct net_device *dev)
Jeff Johnson295189b2012-06-20 16:38:30 -070011251{
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053011252 hdd_adapter_t *pAdapter;
11253 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070011254 int mc_count;
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053011255 int i = 0, ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070011256 struct netdev_hw_addr *ha;
Gopichand Nakkala0f276812013-02-24 14:45:51 +053011257
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053011258 ENTER();
11259
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053011260 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkala0f276812013-02-24 14:45:51 +053011261 if (NULL == pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -070011262 {
11263 hddLog(VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala0f276812013-02-24 14:45:51 +053011264 "%s: Adapter context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070011265 return;
11266 }
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053011267 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
11268 ret = wlan_hdd_validate_context(pHddCtx);
11269 if (0 != ret)
11270 {
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053011271 return;
11272 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011273 if (dev->flags & IFF_ALLMULTI)
11274 {
11275 hddLog(VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070011276 "%s: allow all multicast frames", __func__);
Gopichand Nakkala0f276812013-02-24 14:45:51 +053011277 pAdapter->mc_addr_list.mc_cnt = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070011278 }
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053011279 else
Jeff Johnson295189b2012-06-20 16:38:30 -070011280 {
11281 mc_count = netdev_mc_count(dev);
11282 hddLog(VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070011283 "%s: mc_count = %u", __func__, mc_count);
Jeff Johnson295189b2012-06-20 16:38:30 -070011284 if (mc_count > WLAN_HDD_MAX_MC_ADDR_LIST)
11285 {
11286 hddLog(VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070011287 "%s: No free filter available; allow all multicast frames", __func__);
Gopichand Nakkala0f276812013-02-24 14:45:51 +053011288 pAdapter->mc_addr_list.mc_cnt = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070011289 return;
11290 }
11291
Gopichand Nakkala0f276812013-02-24 14:45:51 +053011292 pAdapter->mc_addr_list.mc_cnt = mc_count;
Jeff Johnson295189b2012-06-20 16:38:30 -070011293
11294 netdev_for_each_mc_addr(ha, dev) {
11295 if (i == mc_count)
11296 break;
Gopichand Nakkala0f276812013-02-24 14:45:51 +053011297 memset(&(pAdapter->mc_addr_list.addr[i][0]), 0, ETH_ALEN);
11298 memcpy(&(pAdapter->mc_addr_list.addr[i][0]), ha->addr, ETH_ALEN);
Arif Hussain6d2a3322013-11-17 19:50:10 -080011299 hddLog(VOS_TRACE_LEVEL_INFO, "%s: mlist[%d] = "MAC_ADDRESS_STR,
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053011300 __func__, i,
Gopichand Nakkala0f276812013-02-24 14:45:51 +053011301 MAC_ADDR_ARRAY(pAdapter->mc_addr_list.addr[i]));
Jeff Johnson295189b2012-06-20 16:38:30 -070011302 i++;
11303 }
11304 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053011305
Ganesh Kondabattinifb37e652015-10-09 15:46:47 +053011306 if (pHddCtx->hdd_wlan_suspended)
11307 {
11308 /*
11309 * Configure the Mcast address list to FW
11310 * If wlan is already in suspend mode
11311 */
11312 wlan_hdd_set_mc_addr_list(pAdapter, TRUE);
11313 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053011314 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070011315 return;
11316}
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053011317
11318static void hdd_set_multicast_list(struct net_device *dev)
11319{
11320 vos_ssr_protect(__func__);
11321 __hdd_set_multicast_list(dev);
11322 vos_ssr_unprotect(__func__);
11323}
Jeff Johnson295189b2012-06-20 16:38:30 -070011324#endif
11325
11326/**---------------------------------------------------------------------------
11327
11328 \brief hdd_select_queue() -
11329
11330 This function is registered with the Linux OS for network
11331 core to decide which queue to use first.
11332
11333 \param - dev - Pointer to the WLAN device.
11334 - skb - Pointer to OS packet (sk_buff).
11335 \return - ac, Queue Index/access category corresponding to UP in IP header
11336
11337 --------------------------------------------------------------------------*/
11338v_U16_t hdd_select_queue(struct net_device *dev,
Anand N Sunkade9adb1b2015-07-29 09:56:45 +053011339 struct sk_buff *skb
11340#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,13,0))
11341 , void *accel_priv
11342#endif
11343#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
11344 , select_queue_fallback_t fallback
11345#endif
11346)
Jeff Johnson295189b2012-06-20 16:38:30 -070011347{
11348 return hdd_wmm_select_queue(dev, skb);
11349}
11350
11351
11352/**---------------------------------------------------------------------------
11353
11354 \brief hdd_wlan_initial_scan() -
11355
11356 This function triggers the initial scan
11357
11358 \param - pAdapter - Pointer to the HDD adapter.
11359
11360 --------------------------------------------------------------------------*/
11361void hdd_wlan_initial_scan(hdd_adapter_t *pAdapter)
11362{
11363 tCsrScanRequest scanReq;
11364 tCsrChannelInfo channelInfo;
11365 eHalStatus halStatus;
Jeff Johnson02797792013-10-26 19:17:13 -070011366 tANI_U32 scanId;
Jeff Johnson295189b2012-06-20 16:38:30 -070011367 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
11368
11369 vos_mem_zero(&scanReq, sizeof(tCsrScanRequest));
11370 vos_mem_set(&scanReq.bssid, sizeof(tCsrBssid), 0xff);
11371 scanReq.BSSType = eCSR_BSS_TYPE_ANY;
11372
11373 if(sme_Is11dSupported(pHddCtx->hHal))
11374 {
11375 halStatus = sme_ScanGetBaseChannels( pHddCtx->hHal, &channelInfo );
11376 if ( HAL_STATUS_SUCCESS( halStatus ) )
11377 {
11378 scanReq.ChannelInfo.ChannelList = vos_mem_malloc(channelInfo.numOfChannels);
11379 if( !scanReq.ChannelInfo.ChannelList )
11380 {
11381 hddLog(VOS_TRACE_LEVEL_ERROR, "%s kmalloc failed", __func__);
11382 vos_mem_free(channelInfo.ChannelList);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -080011383 channelInfo.ChannelList = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070011384 return;
11385 }
11386 vos_mem_copy(scanReq.ChannelInfo.ChannelList, channelInfo.ChannelList,
11387 channelInfo.numOfChannels);
11388 scanReq.ChannelInfo.numOfChannels = channelInfo.numOfChannels;
11389 vos_mem_free(channelInfo.ChannelList);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -080011390 channelInfo.ChannelList = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070011391 }
11392
11393 scanReq.scanType = eSIR_PASSIVE_SCAN;
11394 scanReq.requestType = eCSR_SCAN_REQUEST_11D_SCAN;
11395 scanReq.maxChnTime = pHddCtx->cfg_ini->nPassiveMaxChnTime;
11396 scanReq.minChnTime = pHddCtx->cfg_ini->nPassiveMinChnTime;
11397 }
11398 else
11399 {
11400 scanReq.scanType = eSIR_ACTIVE_SCAN;
11401 scanReq.requestType = eCSR_SCAN_REQUEST_FULL_SCAN;
11402 scanReq.maxChnTime = pHddCtx->cfg_ini->nActiveMaxChnTime;
11403 scanReq.minChnTime = pHddCtx->cfg_ini->nActiveMinChnTime;
11404 }
11405
11406 halStatus = sme_ScanRequest(pHddCtx->hHal, pAdapter->sessionId, &scanReq, &scanId, NULL, NULL);
11407 if ( !HAL_STATUS_SUCCESS( halStatus ) )
11408 {
11409 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: sme_ScanRequest failed status code %d",
11410 __func__, halStatus );
11411 }
11412
11413 if(sme_Is11dSupported(pHddCtx->hHal))
11414 vos_mem_free(scanReq.ChannelInfo.ChannelList);
11415}
11416
Jeff Johnson295189b2012-06-20 16:38:30 -070011417/**---------------------------------------------------------------------------
11418
11419 \brief hdd_full_power_callback() - HDD full power callback function
11420
11421 This is the function invoked by SME to inform the result of a full power
11422 request issued by HDD
11423
11424 \param - callbackcontext - Pointer to cookie
11425 \param - status - result of request
11426
11427 \return - None
11428
11429 --------------------------------------------------------------------------*/
11430static void hdd_full_power_callback(void *callbackContext, eHalStatus status)
11431{
Jeff Johnson72a40512013-12-19 10:14:15 -080011432 struct statsContext *pContext = callbackContext;
Jeff Johnson295189b2012-06-20 16:38:30 -070011433
11434 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnsonc135a9a2017-09-19 08:37:24 -070011435 "%s: context = %pK, status = %d", __func__, pContext, status);
Jeff Johnson295189b2012-06-20 16:38:30 -070011436
11437 if (NULL == callbackContext)
11438 {
11439 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnsonc135a9a2017-09-19 08:37:24 -070011440 "%s: Bad param, context [%pK]",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070011441 __func__, callbackContext);
Jeff Johnson295189b2012-06-20 16:38:30 -070011442 return;
11443 }
11444
Jeff Johnson72a40512013-12-19 10:14:15 -080011445 /* there is a race condition that exists between this callback
11446 function and the caller since the caller could time out either
11447 before or while this code is executing. we use a spinlock to
11448 serialize these actions */
11449 spin_lock(&hdd_context_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -070011450
11451 if (POWER_CONTEXT_MAGIC != pContext->magic)
11452 {
11453 /* the caller presumably timed out so there is nothing we can do */
Jeff Johnson72a40512013-12-19 10:14:15 -080011454 spin_unlock(&hdd_context_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -070011455 hddLog(VOS_TRACE_LEVEL_WARN,
11456 "%s: Invalid context, magic [%08x]",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070011457 __func__, pContext->magic);
Jeff Johnson295189b2012-06-20 16:38:30 -070011458 return;
11459 }
11460
Jeff Johnson72a40512013-12-19 10:14:15 -080011461 /* context is valid so caller is still waiting */
11462
11463 /* paranoia: invalidate the magic */
11464 pContext->magic = 0;
11465
11466 /* notify the caller */
Jeff Johnson295189b2012-06-20 16:38:30 -070011467 complete(&pContext->completion);
Jeff Johnson72a40512013-12-19 10:14:15 -080011468
11469 /* serialization is complete */
11470 spin_unlock(&hdd_context_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -070011471}
11472
Katya Nigamf0511f62015-05-05 16:40:57 +053011473void wlan_hdd_mon_set_typesubtype( hdd_mon_ctx_t *pMonCtx,int type)
11474{
11475 pMonCtx->typeSubtypeBitmap = 0;
11476 if( type%10 ) /* Management Packets */
11477 pMonCtx->typeSubtypeBitmap |= 0xFFFF;
11478 type/=10;
11479 if( type%10 ) /* Control Packets */
11480 pMonCtx->typeSubtypeBitmap |= 0xFFFF0000;
11481 type/=10;
11482 if( type%10 ) /* Data Packets */
11483 pMonCtx->typeSubtypeBitmap |= 0xFFFF00000000;
11484}
11485
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +053011486VOS_STATUS wlan_hdd_mon_postMsg(tANI_U32 *magic, struct completion *cmpVar,
11487 hdd_mon_ctx_t *pMonCtx , void* callback)
Katya Nigamf0511f62015-05-05 16:40:57 +053011488{
11489 vos_msg_t monMsg;
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +053011490 tSirMonModeReq *pMonModeReq;
Katya Nigamf0511f62015-05-05 16:40:57 +053011491
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +053011492 if (MON_MODE_START == pMonCtx->state)
11493 monMsg.type = WDA_MON_START_REQ;
11494 else if (MON_MODE_STOP == pMonCtx->state)
11495 monMsg.type = WDA_MON_STOP_REQ;
11496 else {
11497 hddLog(VOS_TRACE_LEVEL_ERROR,
11498 FL("invalid monitor state %d"), pMonCtx->state);
Katya Nigamf0511f62015-05-05 16:40:57 +053011499 return VOS_STATUS_E_FAILURE;
11500 }
11501
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +053011502 pMonModeReq = vos_mem_malloc(sizeof(tSirMonModeReq));
11503 if (pMonModeReq == NULL) {
11504 hddLog(VOS_TRACE_LEVEL_ERROR,
11505 FL("fail to allocate memory for monitor mode req"));
11506 return VOS_STATUS_E_FAILURE;
11507 }
Katya Nigamf0511f62015-05-05 16:40:57 +053011508
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +053011509 pMonModeReq->magic = magic;
11510 pMonModeReq->cmpVar = cmpVar;
11511 pMonModeReq->data = pMonCtx;
11512 pMonModeReq->callback = callback;
Katya Nigamf0511f62015-05-05 16:40:57 +053011513
Katya Nigamf0511f62015-05-05 16:40:57 +053011514 monMsg.reserved = 0;
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +053011515 monMsg.bodyptr = pMonModeReq;
Katya Nigamf0511f62015-05-05 16:40:57 +053011516 monMsg.bodyval = 0;
11517
11518 if (VOS_STATUS_SUCCESS != vos_mq_post_message(
11519 VOS_MODULE_ID_WDA,(vos_msg_t *)&monMsg)) {
11520 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: : Failed to post Msg to HAL",__func__);
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +053011521 vos_mem_free(pMonModeReq);
Katya Nigamf0511f62015-05-05 16:40:57 +053011522 }
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +053011523 return VOS_STATUS_SUCCESS;
Katya Nigamf0511f62015-05-05 16:40:57 +053011524}
11525
Katya Nigame7b69a82015-04-28 15:24:06 +053011526void wlan_hdd_mon_close(hdd_context_t *pHddCtx)
11527{
11528 VOS_STATUS vosStatus;
11529 v_CONTEXT_t pVosContext = pHddCtx->pvosContext;
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +053011530 long ret;
11531 hdd_mon_ctx_t *pMonCtx = NULL;
11532 v_U32_t magic;
11533 struct completion cmpVar;
Hanumantha Reddy Pothulac99bc062015-09-08 14:59:26 +053011534
Katya Nigame7b69a82015-04-28 15:24:06 +053011535 hdd_adapter_t *pAdapter = hdd_get_adapter(pHddCtx,WLAN_HDD_MONITOR);
11536 if(pAdapter == NULL || pVosContext == NULL)
11537 {
11538 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, "%s:pAdapter is NULL",__func__);
11539 return ;
11540 }
Katya Nigamf0511f62015-05-05 16:40:57 +053011541
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +053011542 pMonCtx = WLAN_HDD_GET_MONITOR_CTX_PTR(pAdapter);
11543 if (pMonCtx!= NULL && pMonCtx->state == MON_MODE_START) {
11544 pMonCtx->state = MON_MODE_STOP;
11545 magic = MON_MODE_MSG_MAGIC;
11546 init_completion(&cmpVar);
11547 if (VOS_STATUS_SUCCESS !=
11548 wlan_hdd_mon_postMsg(&magic, &cmpVar,
11549 pMonCtx, hdd_monPostMsgCb)) {
11550 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11551 FL("failed to post MON MODE REQ"));
11552 pMonCtx->state = MON_MODE_START;
11553 magic = 0;
11554 return;
11555 }
11556 ret = wait_for_completion_timeout(&cmpVar, MON_MODE_MSG_TIMEOUT);
11557 magic = 0;
11558 if (ret <= 0 ) {
11559 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11560 FL("timeout on monitor mode completion %ld"), ret);
11561 }
11562 }
11563
Katya Nigame7b69a82015-04-28 15:24:06 +053011564 hdd_UnregisterWext(pAdapter->dev);
11565
11566 vos_mon_stop( pVosContext );
11567
11568 vosStatus = vos_sched_close( pVosContext );
11569 if (!VOS_IS_STATUS_SUCCESS(vosStatus)) {
11570 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
11571 "%s: Failed to close VOSS Scheduler",__func__);
11572 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
11573 }
11574
11575 vosStatus = vos_nv_close();
11576 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
11577 {
11578 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
11579 "%s: Failed to close NV", __func__);
11580 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
11581 }
11582
11583 vos_close(pVosContext);
11584
11585 #ifdef WLAN_KD_READY_NOTIFIER
11586 nl_srv_exit(pHddCtx->ptt_pid);
11587 #else
11588 nl_srv_exit();
11589 #endif
11590
Katya Nigame7b69a82015-04-28 15:24:06 +053011591 hdd_close_all_adapters( pHddCtx );
Katya Nigame7b69a82015-04-28 15:24:06 +053011592}
Agrawal Ashish33ec71e2015-11-26 20:20:58 +053011593/**
11594 * hdd_wlan_free_wiphy_channels - free Channel pointer for wiphy
11595 * @ wiphy: the wiphy to validate against
11596 *
11597 * Return: void
11598 */
11599void hdd_wlan_free_wiphy_channels(struct wiphy *wiphy)
11600{
11601 int i =0;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053011602 for (i = 0; i < HDD_NUM_NL80211_BANDS; i++)
Agrawal Ashish33ec71e2015-11-26 20:20:58 +053011603 {
11604 if (NULL != wiphy->bands[i] &&
11605 (NULL != wiphy->bands[i]->channels))
11606 {
11607 vos_mem_free(wiphy->bands[i]->channels);
11608 wiphy->bands[i]->channels = NULL;
11609 }
11610 }
11611}
Jeff Johnson295189b2012-06-20 16:38:30 -070011612/**---------------------------------------------------------------------------
11613
11614 \brief hdd_wlan_exit() - HDD WLAN exit function
11615
11616 This is the driver exit point (invoked during rmmod)
11617
11618 \param - pHddCtx - Pointer to the HDD Context
11619
11620 \return - None
11621
11622 --------------------------------------------------------------------------*/
11623void hdd_wlan_exit(hdd_context_t *pHddCtx)
11624{
11625 eHalStatus halStatus;
11626 v_CONTEXT_t pVosContext = pHddCtx->pvosContext;
11627 VOS_STATUS vosStatus;
Gopichand Nakkala66923aa2013-03-06 23:17:24 +053011628 struct wiphy *wiphy = pHddCtx->wiphy;
Mingcheng Zhu87f22fc2014-01-30 19:23:32 -080011629 hdd_adapter_t* pAdapter = NULL;
Jeff Johnson72a40512013-12-19 10:14:15 -080011630 struct statsContext powerContext;
Jeff Johnson295189b2012-06-20 16:38:30 -070011631 long lrc;
c_hpothu5ab05e92014-06-13 17:34:05 +053011632 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070011633
11634 ENTER();
11635
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +053011636
Katya Nigame7b69a82015-04-28 15:24:06 +053011637 if (VOS_MONITOR_MODE == hdd_get_conparam())
11638 {
11639 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: MONITOR MODE",__func__);
11640 wlan_hdd_mon_close(pHddCtx);
Hanumantha Reddy Pothulac99bc062015-09-08 14:59:26 +053011641 goto free_hdd_ctx;
Katya Nigame7b69a82015-04-28 15:24:06 +053011642 }
11643 else if (VOS_FTM_MODE != hdd_get_conparam())
Jeff Johnson88ba7742013-02-27 14:36:02 -080011644 {
11645 // Unloading, restart logic is no more required.
11646 wlan_hdd_restart_deinit(pHddCtx);
Jeff Johnsone7245742012-09-05 17:12:55 -070011647
Agarwal Ashishb20e0ff2014-12-17 22:50:19 +053011648#ifdef FEATURE_WLAN_TDLS
11649 /* At the time of driver unloading; if tdls connection is present;
11650 * hdd_rx_packet_cbk calls wlan_hdd_tdls_find_peer.
11651 * wlan_hdd_tdls_find_peer always checks for valid context;
11652 * as load/unload in progress there can be a race condition.
11653 * hdd_rx_packet_cbk calls wlan_hdd_tdls_find_peer only
11654 * when tdls state is enabled.
11655 * As soon as driver set load/unload flag; tdls flag also needs
11656 * to be disabled so that hdd_rx_packet_cbk won't call
11657 * wlan_hdd_tdls_find_peer.
11658 */
Masti, Narayanraddi20494af2015-12-17 20:56:42 +053011659 wlan_hdd_tdls_set_mode(pHddCtx, eTDLS_SUPPORT_DISABLED, FALSE,
11660 HDD_SET_TDLS_MODE_SOURCE_USER);
Agarwal Ashishb20e0ff2014-12-17 22:50:19 +053011661#endif
11662
c_hpothu5ab05e92014-06-13 17:34:05 +053011663 vosStatus = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
11664 while (NULL != pAdapterNode && VOS_STATUS_E_EMPTY != vosStatus)
Jeff Johnson295189b2012-06-20 16:38:30 -070011665 {
c_hpothu5ab05e92014-06-13 17:34:05 +053011666 pAdapter = pAdapterNode->pAdapter;
11667 if (NULL != pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -070011668 {
Mahesh A Saptasagar305e2632015-03-04 12:57:33 +053011669 /* Disable TX on the interface, after this hard_start_xmit() will
11670 * not be called on that interface
11671 */
11672 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
11673 netif_tx_disable(pAdapter->dev);
11674
11675 /* Mark the interface status as "down" for outside world */
11676 netif_carrier_off(pAdapter->dev);
11677
Agarwal Ashish9ffa5b92014-11-18 21:07:02 +053011678 /* DeInit the adapter. This ensures that all data packets
11679 * are freed.
11680 */
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +053011681#ifdef FEATURE_WLAN_TDLS
11682 mutex_lock(&pHddCtx->tdls_lock);
11683#endif
c_hpothu002231a2015-02-05 14:58:51 +053011684 hdd_deinit_adapter(pHddCtx, pAdapter, FALSE);
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +053011685#ifdef FEATURE_WLAN_TDLS
11686 mutex_unlock(&pHddCtx->tdls_lock);
11687#endif
Masti, Narayanraddi26378462016-01-05 18:20:28 +053011688 vos_flush_delayed_work(&pHddCtx->scan_ctxt.scan_work);
11689
11690 wlan_hdd_init_deinit_defer_scan_context(&pHddCtx->scan_ctxt);
Agarwal Ashish9ffa5b92014-11-18 21:07:02 +053011691
c_hpothu5ab05e92014-06-13 17:34:05 +053011692 if (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +053011693 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode ||
11694 WLAN_HDD_MONITOR == pAdapter->device_mode)
c_hpothu5ab05e92014-06-13 17:34:05 +053011695 {
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +053011696 if (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
11697 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode)
11698 wlan_hdd_cfg80211_deregister_frames(pAdapter);
11699
c_hpothu5ab05e92014-06-13 17:34:05 +053011700 hdd_UnregisterWext(pAdapter->dev);
11701 }
Kaushik, Sushant4975a572014-10-21 16:07:48 +053011702
Jeff Johnson295189b2012-06-20 16:38:30 -070011703 }
c_hpothu5ab05e92014-06-13 17:34:05 +053011704 vosStatus = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
11705 pAdapterNode = pNext;
Jeff Johnson295189b2012-06-20 16:38:30 -070011706 }
mukul sharmabab477d2015-06-11 17:14:55 +053011707
Kaushik, Sushant4975a572014-10-21 16:07:48 +053011708 // Cancel any outstanding scan requests. We are about to close all
11709 // of our adapters, but an adapter structure is what SME passes back
11710 // to our callback function. Hence if there are any outstanding scan
11711 // requests then there is a race condition between when the adapter
11712 // is closed and when the callback is invoked.We try to resolve that
11713 // race condition here by canceling any outstanding scans before we
11714 // close the adapters.
11715 // Note that the scans may be cancelled in an asynchronous manner,
11716 // so ideally there needs to be some kind of synchronization. Rather
11717 // than introduce a new synchronization here, we will utilize the
11718 // fact that we are about to Request Full Power, and since that is
11719 // synchronized, the expectation is that by the time Request Full
11720 // Power has completed all scans will be cancelled.
11721 if (pHddCtx->scan_info.mScanPending)
11722 {
Hema Aparna Medicharlaf05f6cd2015-01-21 14:44:19 +053011723 if(NULL != pAdapter)
11724 {
11725 hddLog(VOS_TRACE_LEVEL_INFO,
11726 FL("abort scan mode: %d sessionId: %d"),
11727 pAdapter->device_mode,
11728 pAdapter->sessionId);
11729 }
11730 hdd_abort_mac_scan(pHddCtx,
11731 pHddCtx->scan_info.sessionId,
11732 eCSR_SCAN_ABORT_DEFAULT);
Kaushik, Sushant4975a572014-10-21 16:07:48 +053011733 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011734 }
c_hpothu5ab05e92014-06-13 17:34:05 +053011735 else
Jeff Johnson88ba7742013-02-27 14:36:02 -080011736 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011737 hddLog(VOS_TRACE_LEVEL_INFO,"%s: FTM MODE",__func__);
Hanumantha Reddy Pothula45af96b2015-02-12 16:07:58 +053011738 if (pHddCtx->ftm.ftm_state == WLAN_FTM_STARTING)
11739 {
11740 INIT_COMPLETION(pHddCtx->ftm.startCmpVar);
11741 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
11742 "%s: in middle of FTM START", __func__);
11743 lrc = wait_for_completion_timeout(&pHddCtx->ftm.startCmpVar,
11744 msecs_to_jiffies(20000));
11745 if(!lrc)
11746 {
11747 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
11748 "%s: timedout on ftmStartCmpVar fatal error", __func__);
11749 }
11750 }
Jeff Johnson88ba7742013-02-27 14:36:02 -080011751 wlan_hdd_ftm_close(pHddCtx);
11752 goto free_hdd_ctx;
11753 }
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011754
Jeff Johnson295189b2012-06-20 16:38:30 -070011755 /* DeRegister with platform driver as client for Suspend/Resume */
11756 vosStatus = hddDeregisterPmOps(pHddCtx);
11757 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
11758 {
11759 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddDeregisterPmOps failed",__func__);
11760 VOS_ASSERT(0);
11761 }
11762
11763 vosStatus = hddDevTmUnregisterNotifyCallback(pHddCtx);
11764 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
11765 {
11766 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddDevTmUnregisterNotifyCallback failed",__func__);
11767 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011768
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -070011769 //Stop the traffic monitor timer
Mahesh A Saptasagard461e432016-07-20 15:01:40 +053011770 if ((pHddCtx->cfg_ini->dynSplitscan) && (VOS_TIMER_STATE_RUNNING ==
11771 vos_timer_getCurrentState(&pHddCtx->tx_rx_trafficTmr)))
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -070011772 {
11773 vos_timer_stop(&pHddCtx->tx_rx_trafficTmr);
11774 }
11775
11776 // Destroy the traffic monitor timer
Mahesh A Saptasagard461e432016-07-20 15:01:40 +053011777 if ((pHddCtx->cfg_ini->dynSplitscan) &&
11778 (!VOS_IS_STATUS_SUCCESS(vos_timer_destroy(
11779 &pHddCtx->tx_rx_trafficTmr))))
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -070011780 {
11781 hddLog(VOS_TRACE_LEVEL_ERROR,
11782 "%s: Cannot deallocate Traffic monitor timer", __func__);
11783 }
11784
Bhargav Shahd0715912015-10-01 18:17:37 +053011785 if (VOS_TIMER_STATE_RUNNING ==
11786 vos_timer_getCurrentState(&pHddCtx->delack_timer)) {
11787 vos_timer_stop(&pHddCtx->delack_timer);
11788 }
11789
11790 if (!VOS_IS_STATUS_SUCCESS(vos_timer_destroy(
11791 &pHddCtx->delack_timer))) {
11792 hddLog(VOS_TRACE_LEVEL_ERROR,
11793 "%s: Cannot deallocate Bus bandwidth timer", __func__);
11794 }
11795
Masti, Narayanraddi44b0db02015-12-22 11:54:35 +053011796 if (VOS_TIMER_STATE_RUNNING ==
11797 vos_timer_getCurrentState(&pHddCtx->tdls_source_timer)) {
11798 vos_timer_stop(&pHddCtx->tdls_source_timer);
11799 }
11800
Abhishek Singh8a3e4dc2017-01-02 10:39:18 +053011801 vos_set_snoc_high_freq_voting(false);
11802
Masti, Narayanraddi44b0db02015-12-22 11:54:35 +053011803 vos_timer_destroy(&pHddCtx->tdls_source_timer);
11804
Jeff Johnson295189b2012-06-20 16:38:30 -070011805 //Disable IMPS/BMPS as we do not want the device to enter any power
11806 //save mode during shutdown
11807 sme_DisablePowerSave(pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
11808 sme_DisablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
11809 sme_DisablePowerSave(pHddCtx->hHal, ePMC_UAPSD_MODE_POWER_SAVE);
11810
11811 //Ensure that device is in full power as we will touch H/W during vos_Stop
11812 init_completion(&powerContext.completion);
11813 powerContext.magic = POWER_CONTEXT_MAGIC;
11814
11815 halStatus = sme_RequestFullPower(pHddCtx->hHal, hdd_full_power_callback,
11816 &powerContext, eSME_FULL_PWR_NEEDED_BY_HDD);
11817
11818 if (eHAL_STATUS_SUCCESS != halStatus)
11819 {
11820 if (eHAL_STATUS_PMC_PENDING == halStatus)
11821 {
11822 /* request was sent -- wait for the response */
11823 lrc = wait_for_completion_interruptible_timeout(
11824 &powerContext.completion,
11825 msecs_to_jiffies(WLAN_WAIT_TIME_POWER));
Jeff Johnson295189b2012-06-20 16:38:30 -070011826 if (lrc <= 0)
11827 {
11828 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: %s while requesting full power",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070011829 __func__, (0 == lrc) ? "timeout" : "interrupt");
Jeff Johnson295189b2012-06-20 16:38:30 -070011830 }
11831 }
11832 else
11833 {
11834 hddLog(VOS_TRACE_LEVEL_ERROR,
11835 "%s: Request for Full Power failed, status %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070011836 __func__, halStatus);
Jeff Johnson295189b2012-06-20 16:38:30 -070011837 /* continue -- need to clean up as much as possible */
11838 }
11839 }
Hanumantha Reddy Pothula81b42b22015-05-12 13:52:00 +053011840 if ((eHAL_STATUS_SUCCESS == halStatus) ||
11841 (eHAL_STATUS_PMC_PENDING == halStatus && lrc > 0))
11842 {
11843 /* This will issue a dump command which will clean up
11844 BTQM queues and unblock MC thread */
11845 vos_fwDumpReq(274, 0, 0, 0, 0, 1);
11846 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011847
Jeff Johnson72a40512013-12-19 10:14:15 -080011848 /* either we never sent a request, we sent a request and received a
11849 response or we sent a request and timed out. if we never sent a
11850 request or if we sent a request and got a response, we want to
11851 clear the magic out of paranoia. if we timed out there is a
11852 race condition such that the callback function could be
11853 executing at the same time we are. of primary concern is if the
11854 callback function had already verified the "magic" but had not
11855 yet set the completion variable when a timeout occurred. we
11856 serialize these activities by invalidating the magic while
11857 holding a shared spinlock which will cause us to block if the
11858 callback is currently executing */
11859 spin_lock(&hdd_context_lock);
11860 powerContext.magic = 0;
11861 spin_unlock(&hdd_context_lock);
11862
Hema Aparna Medicharlaa6cf65e2015-06-01 16:23:28 +053011863 /* If Device is shutdown, no point for SME to wait for responses
11864 from device. Pre Close SME */
11865 if(wcnss_device_is_shutdown())
11866 {
11867 sme_PreClose(pHddCtx->hHal);
11868 }
Yue Ma0d4891e2013-08-06 17:01:45 -070011869 hdd_debugfs_exit(pHddCtx);
11870
Ratheesh S P35ed8b12015-04-27 14:01:07 +053011871#ifdef WLAN_NS_OFFLOAD
Ratheesh S P36dbc932015-08-07 14:28:57 +053011872 hddLog(LOG1, FL("Unregister IPv6 notifier"));
Ratheesh S P35ed8b12015-04-27 14:01:07 +053011873 unregister_inet6addr_notifier(&pHddCtx->ipv6_notifier);
11874#endif
Ratheesh S P36dbc932015-08-07 14:28:57 +053011875 hddLog(LOG1, FL("Unregister IPv4 notifier"));
Ratheesh S P35ed8b12015-04-27 14:01:07 +053011876 unregister_inetaddr_notifier(&pHddCtx->ipv4_notifier);
11877
Jeff Johnson295189b2012-06-20 16:38:30 -070011878 // Unregister the Net Device Notifier
11879 unregister_netdevice_notifier(&hdd_netdev_notifier);
11880
Jeff Johnson295189b2012-06-20 16:38:30 -070011881 hdd_stop_all_adapters( pHddCtx );
11882
Jeff Johnson295189b2012-06-20 16:38:30 -070011883#ifdef WLAN_BTAMP_FEATURE
11884 vosStatus = WLANBAP_Stop(pVosContext);
11885 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
11886 {
11887 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
11888 "%s: Failed to stop BAP",__func__);
11889 }
11890#endif //WLAN_BTAMP_FEATURE
11891
11892 //Stop all the modules
11893 vosStatus = vos_stop( pVosContext );
11894 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
11895 {
11896 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
11897 "%s: Failed to stop VOSS",__func__);
11898 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
Hanumantha Reddy Pothulabd9601a2016-02-12 13:22:27 +053011899 if (isSsrPanicOnFailure())
11900 VOS_BUG(0);
Jeff Johnson295189b2012-06-20 16:38:30 -070011901 }
11902
Jeff Johnson295189b2012-06-20 16:38:30 -070011903 //This requires pMac access, Call this before vos_close().
Jeff Johnson295189b2012-06-20 16:38:30 -070011904 hdd_unregister_mcast_bcast_filter(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -070011905
11906 //Close the scheduler before calling vos_close to make sure no thread is
11907 // scheduled after the each module close is called i.e after all the data
11908 // structures are freed.
11909 vosStatus = vos_sched_close( pVosContext );
11910 if (!VOS_IS_STATUS_SUCCESS(vosStatus)) {
11911 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
11912 "%s: Failed to close VOSS Scheduler",__func__);
11913 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
11914 }
Jeff Johnsone7245742012-09-05 17:12:55 -070011915#ifdef WLAN_FEATURE_HOLD_RX_WAKELOCK
11916 /* Destroy the wake lock */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053011917 vos_wake_lock_destroy(&pHddCtx->rx_wake_lock);
Jeff Johnsone7245742012-09-05 17:12:55 -070011918#endif
Madan Mohan Koyyalamudi69fc3ad2012-11-28 16:04:56 -080011919 /* Destroy the wake lock */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053011920 vos_wake_lock_destroy(&pHddCtx->sap_wake_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -070011921
Mihir Shete7a24b5f2013-12-21 12:18:31 +053011922#ifdef CONFIG_ENABLE_LINUX_REG
11923 vosStatus = vos_nv_close();
11924 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
11925 {
11926 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
11927 "%s: Failed to close NV", __func__);
11928 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
11929 }
11930#endif
11931
Jeff Johnson295189b2012-06-20 16:38:30 -070011932 //Close VOSS
11933 //This frees pMac(HAL) context. There should not be any call that requires pMac access after this.
11934 vos_close(pVosContext);
11935
Jeff Johnson295189b2012-06-20 16:38:30 -070011936 //Close Watchdog
11937 if(pHddCtx->cfg_ini->fIsLogpEnabled)
11938 vos_watchdog_close(pVosContext);
11939
Gopichand Nakkalaa0358482013-06-12 17:05:47 +053011940 //Clean up HDD Nlink Service
11941 send_btc_nlink_msg(WLAN_MODULE_DOWN_IND, 0);
Gopichand Nakkalaa0358482013-06-12 17:05:47 +053011942
Manjeet Singh47ee8472016-04-11 11:57:18 +053011943 hdd_close_tx_queues(pHddCtx);
c_manjeecfd1efb2015-09-25 19:32:34 +053011944 wlan_free_fwr_mem_dump_buffer();
11945 memdump_deinit();
11946
Vinay Krishna Erannad938c422014-03-10 17:14:21 +053011947#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +053011948 if (pHddCtx->cfg_ini->wlanLoggingEnable)
Vinay Krishna Erannad938c422014-03-10 17:14:21 +053011949 {
11950 wlan_logging_sock_deactivate_svc();
11951 }
11952#endif
11953
Vinay Krishna Erannaef30b522014-08-26 17:48:16 +053011954#ifdef WLAN_KD_READY_NOTIFIER
11955 nl_srv_exit(pHddCtx->ptt_pid);
11956#else
11957 nl_srv_exit();
11958#endif /* WLAN_KD_READY_NOTIFIER */
11959
Abhishek Singh00b71972016-01-07 10:51:04 +053011960#ifdef WLAN_FEATURE_RMC
11961 hdd_close_cesium_nl_sock();
11962#endif /* WLAN_FEATURE_RMC */
Vinay Krishna Erannaef30b522014-08-26 17:48:16 +053011963
Jeff Johnson295189b2012-06-20 16:38:30 -070011964 hdd_close_all_adapters( pHddCtx );
11965
Padma, Santhosh Kumar9cd38332015-11-17 12:18:10 +053011966 vos_flush_delayed_work(&pHddCtx->spoof_mac_addr_work);
Abhishek Singh78c691f2017-11-30 13:48:44 +053011967 vos_flush_delayed_work(&pHddCtx->ecsa_chan_change_work);
Kapil Gupta137ef892016-12-13 19:38:00 +053011968 vos_flush_work(&pHddCtx->sap_start_work);
Padma, Santhosh Kumar9cd38332015-11-17 12:18:10 +053011969
Hanumantha Reddy Pothula97f9bc92015-08-10 17:21:20 +053011970free_hdd_ctx:
Jeff Johnson295189b2012-06-20 16:38:30 -070011971 /* free the power on lock from platform driver */
11972 if (free_riva_power_on_lock("wlan"))
11973 {
11974 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to free power on lock",
11975 __func__);
11976 }
11977
c_hpothu78c7b602014-05-17 17:35:49 +053011978 //Free up dynamically allocated members inside HDD Adapter
11979 if (pHddCtx->cfg_ini)
11980 {
11981 kfree(pHddCtx->cfg_ini);
11982 pHddCtx->cfg_ini= NULL;
11983 }
11984
Hanumanth Reddy Pothula1efcd162018-03-14 14:32:27 +053011985 hdd_request_manager_deinit();
11986
Hanumantha Reddy Pothula6fe221c2016-01-28 15:01:09 +053011987 /* FTM/MONITOR mode, WIPHY did not registered
Leo Changf04ddad2013-09-18 13:46:38 -070011988 If un-register here, system crash will happen */
Hanumantha Reddy Pothula6fe221c2016-01-28 15:01:09 +053011989 if (!(VOS_FTM_MODE == hdd_get_conparam() ||
11990 VOS_MONITOR_MODE == hdd_get_conparam()))
Leo Changf04ddad2013-09-18 13:46:38 -070011991 {
11992 wiphy_unregister(wiphy) ;
Agrawal Ashish33ec71e2015-11-26 20:20:58 +053011993 hdd_wlan_free_wiphy_channels(wiphy);
Leo Changf04ddad2013-09-18 13:46:38 -070011994 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011995 wiphy_free(wiphy) ;
Jeff Johnson295189b2012-06-20 16:38:30 -070011996 if (hdd_is_ssr_required())
11997 {
11998 /* WDI timeout had happened during unload, so SSR is needed here */
Madan Mohan Koyyalamudi3246f5b2012-10-15 15:40:02 -070011999 subsystem_restart("wcnss");
Jeff Johnson295189b2012-06-20 16:38:30 -070012000 msleep(5000);
12001 }
12002 hdd_set_ssr_required (VOS_FALSE);
12003}
12004
12005
12006/**---------------------------------------------------------------------------
12007
12008 \brief hdd_update_config_from_nv() - Function to update the contents of
12009 the running configuration with parameters taken from NV storage
12010
12011 \param - pHddCtx - Pointer to the HDD global context
12012
12013 \return - VOS_STATUS_SUCCESS if successful
12014
12015 --------------------------------------------------------------------------*/
12016static VOS_STATUS hdd_update_config_from_nv(hdd_context_t* pHddCtx)
12017{
Jeff Johnson295189b2012-06-20 16:38:30 -070012018 v_BOOL_t itemIsValid = VOS_FALSE;
12019 VOS_STATUS status;
12020 v_MACADDR_t macFromNV[VOS_MAX_CONCURRENCY_PERSONA];
12021 v_U8_t macLoop;
12022
12023 /*If the NV is valid then get the macaddress from nv else get it from qcom_cfg.ini*/
12024 status = vos_nv_getValidity(VNV_FIELD_IMAGE, &itemIsValid);
12025 if(status != VOS_STATUS_SUCCESS)
12026 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080012027 hddLog(VOS_TRACE_LEVEL_ERROR," vos_nv_getValidity() failed");
Jeff Johnson295189b2012-06-20 16:38:30 -070012028 return VOS_STATUS_E_FAILURE;
12029 }
12030
12031 if (itemIsValid == VOS_TRUE)
12032 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080012033 hddLog(VOS_TRACE_LEVEL_INFO_HIGH," Reading the Macaddress from NV");
Jeff Johnson295189b2012-06-20 16:38:30 -070012034 status = vos_nv_readMultiMacAddress((v_U8_t *)&macFromNV[0].bytes[0],
12035 VOS_MAX_CONCURRENCY_PERSONA);
12036 if(status != VOS_STATUS_SUCCESS)
12037 {
12038 /* Get MAC from NV fail, not update CFG info
12039 * INI MAC value will be used for MAC setting */
Arif Hussain6d2a3322013-11-17 19:50:10 -080012040 hddLog(VOS_TRACE_LEVEL_ERROR," vos_nv_readMacAddress() failed");
Jeff Johnson295189b2012-06-20 16:38:30 -070012041 return VOS_STATUS_E_FAILURE;
12042 }
12043
12044 /* If first MAC is not valid, treat all others are not valid
12045 * Then all MACs will be got from ini file */
12046 if(vos_is_macaddr_zero(&macFromNV[0]))
12047 {
12048 /* MAC address in NV file is not configured yet */
12049 hddLog(VOS_TRACE_LEVEL_WARN, "Invalid MAC in NV file");
12050 return VOS_STATUS_E_INVAL;
12051 }
12052
12053 /* Get MAC address from NV, update CFG info */
12054 for(macLoop = 0; macLoop < VOS_MAX_CONCURRENCY_PERSONA; macLoop++)
12055 {
12056 if(vos_is_macaddr_zero(&macFromNV[macLoop]))
12057 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012058 hddLog(VOS_TRACE_LEVEL_ERROR,"not valid MAC from NV for %d", macLoop);
Jeff Johnson295189b2012-06-20 16:38:30 -070012059 /* This MAC is not valid, skip it
12060 * This MAC will be got from ini file */
12061 }
12062 else
12063 {
12064 vos_mem_copy((v_U8_t *)&pHddCtx->cfg_ini->intfMacAddr[macLoop].bytes[0],
12065 (v_U8_t *)&macFromNV[macLoop].bytes[0],
12066 VOS_MAC_ADDR_SIZE);
12067 }
12068 }
12069 }
12070 else
12071 {
12072 hddLog(VOS_TRACE_LEVEL_ERROR, "NV ITEM, MAC Not valid");
12073 return VOS_STATUS_E_FAILURE;
12074 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012075
Jeff Johnson295189b2012-06-20 16:38:30 -070012076
12077 return VOS_STATUS_SUCCESS;
12078}
12079
12080/**---------------------------------------------------------------------------
12081
12082 \brief hdd_post_voss_start_config() - HDD post voss start config helper
12083
12084 \param - pAdapter - Pointer to the HDD
12085
12086 \return - None
12087
12088 --------------------------------------------------------------------------*/
12089VOS_STATUS hdd_post_voss_start_config(hdd_context_t* pHddCtx)
12090{
12091 eHalStatus halStatus;
12092 v_U32_t listenInterval;
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +053012093 tANI_U32 ignoreDtim;
Jeff Johnson295189b2012-06-20 16:38:30 -070012094
Jeff Johnson295189b2012-06-20 16:38:30 -070012095
12096 // Send ready indication to the HDD. This will kick off the MAC
12097 // into a 'running' state and should kick off an initial scan.
12098 halStatus = sme_HDDReadyInd( pHddCtx->hHal );
12099 if ( !HAL_STATUS_SUCCESS( halStatus ) )
12100 {
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +053012101 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: sme_HDDReadyInd() failed with status "
Jeff Johnson295189b2012-06-20 16:38:30 -070012102 "code %08d [x%08x]",__func__, halStatus, halStatus );
12103 return VOS_STATUS_E_FAILURE;
12104 }
12105
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +053012106 // Set default LI and ignoreDtim into HDD context,
Jeff Johnson295189b2012-06-20 16:38:30 -070012107 // otherwise under some race condition, HDD will set 0 LI value into RIVA,
12108 // And RIVA will crash
12109 wlan_cfgGetInt(pHddCtx->hHal, WNI_CFG_LISTEN_INTERVAL, &listenInterval);
12110 pHddCtx->hdd_actual_LI_value = listenInterval;
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +053012111 wlan_cfgGetInt(pHddCtx->hHal, WNI_CFG_IGNORE_DTIM, &ignoreDtim);
12112 pHddCtx->hdd_actual_ignore_DTIM_value = ignoreDtim;
12113
12114
Jeff Johnson295189b2012-06-20 16:38:30 -070012115 return VOS_STATUS_SUCCESS;
12116}
12117
Jeff Johnson295189b2012-06-20 16:38:30 -070012118/* wake lock APIs for HDD */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053012119void hdd_prevent_suspend(uint32_t reason)
Jeff Johnson295189b2012-06-20 16:38:30 -070012120{
Sushant Kaushik83392fa2015-05-05 17:44:40 +053012121
12122 vos_wake_lock_acquire(&wlan_wake_lock, reason);
12123
Jeff Johnson295189b2012-06-20 16:38:30 -070012124}
12125
Sushant Kaushik83392fa2015-05-05 17:44:40 +053012126void hdd_allow_suspend(uint32_t reason)
Jeff Johnson295189b2012-06-20 16:38:30 -070012127{
Sushant Kaushik83392fa2015-05-05 17:44:40 +053012128
12129 vos_wake_lock_release(&wlan_wake_lock, reason);
12130
Jeff Johnson295189b2012-06-20 16:38:30 -070012131}
12132
Sushant Kaushik83392fa2015-05-05 17:44:40 +053012133void hdd_prevent_suspend_timeout(v_U32_t timeout, uint32_t reason)
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -070012134{
Sushant Kaushik83392fa2015-05-05 17:44:40 +053012135
12136 vos_wake_lock_timeout_release(&wlan_wake_lock, timeout,
12137 reason);
12138
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -070012139}
12140
Jeff Johnson295189b2012-06-20 16:38:30 -070012141/**---------------------------------------------------------------------------
12142
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -070012143 \brief hdd_exchange_version_and_caps() - HDD function to exchange version and capability
12144 information between Host and Riva
12145
12146 This function gets reported version of FW
12147 It also finds the version of Riva headers used to compile the host
12148 It compares the above two and prints a warning if they are different
12149 It gets the SW and HW version string
12150 Finally, it exchanges capabilities between host and Riva i.e. host and riva exchange a msg
12151 indicating the features they support through a bitmap
12152
12153 \param - pHddCtx - Pointer to HDD context
12154
12155 \return - void
12156
12157 --------------------------------------------------------------------------*/
12158
12159void hdd_exchange_version_and_caps(hdd_context_t *pHddCtx)
12160{
12161
12162 tSirVersionType versionCompiled;
12163 tSirVersionType versionReported;
12164 tSirVersionString versionString;
12165 tANI_U8 fwFeatCapsMsgSupported = 0;
12166 VOS_STATUS vstatus;
12167
Mingcheng Zhu87f22fc2014-01-30 19:23:32 -080012168 memset(&versionCompiled, 0, sizeof(versionCompiled));
12169 memset(&versionReported, 0, sizeof(versionReported));
12170
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -070012171 /* retrieve and display WCNSS version information */
12172 do {
12173
12174 vstatus = sme_GetWcnssWlanCompiledVersion(pHddCtx->hHal,
12175 &versionCompiled);
12176 if (!VOS_IS_STATUS_SUCCESS(vstatus))
12177 {
12178 hddLog(VOS_TRACE_LEVEL_FATAL,
12179 "%s: unable to retrieve WCNSS WLAN compiled version",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070012180 __func__);
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -070012181 break;
12182 }
12183
12184 vstatus = sme_GetWcnssWlanReportedVersion(pHddCtx->hHal,
12185 &versionReported);
12186 if (!VOS_IS_STATUS_SUCCESS(vstatus))
12187 {
12188 hddLog(VOS_TRACE_LEVEL_FATAL,
12189 "%s: unable to retrieve WCNSS WLAN reported version",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070012190 __func__);
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -070012191 break;
12192 }
12193
12194 if ((versionCompiled.major != versionReported.major) ||
12195 (versionCompiled.minor != versionReported.minor) ||
12196 (versionCompiled.version != versionReported.version) ||
12197 (versionCompiled.revision != versionReported.revision))
12198 {
12199 pr_err("%s: WCNSS WLAN Version %u.%u.%u.%u, "
12200 "Host expected %u.%u.%u.%u\n",
12201 WLAN_MODULE_NAME,
12202 (int)versionReported.major,
12203 (int)versionReported.minor,
12204 (int)versionReported.version,
12205 (int)versionReported.revision,
12206 (int)versionCompiled.major,
12207 (int)versionCompiled.minor,
12208 (int)versionCompiled.version,
12209 (int)versionCompiled.revision);
12210 }
12211 else
12212 {
12213 pr_info("%s: WCNSS WLAN version %u.%u.%u.%u\n",
12214 WLAN_MODULE_NAME,
12215 (int)versionReported.major,
12216 (int)versionReported.minor,
12217 (int)versionReported.version,
12218 (int)versionReported.revision);
12219 }
12220
12221 vstatus = sme_GetWcnssSoftwareVersion(pHddCtx->hHal,
12222 versionString,
12223 sizeof(versionString));
12224 if (!VOS_IS_STATUS_SUCCESS(vstatus))
12225 {
12226 hddLog(VOS_TRACE_LEVEL_FATAL,
12227 "%s: unable to retrieve WCNSS software version string",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070012228 __func__);
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -070012229 break;
12230 }
12231
12232 pr_info("%s: WCNSS software version %s\n",
12233 WLAN_MODULE_NAME, versionString);
Sushant Kaushik084f6592015-09-10 13:11:56 +053012234 vos_mem_copy(pHddCtx->fw_Version, versionString, sizeof(versionString));
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -070012235
12236 vstatus = sme_GetWcnssHardwareVersion(pHddCtx->hHal,
12237 versionString,
12238 sizeof(versionString));
12239 if (!VOS_IS_STATUS_SUCCESS(vstatus))
12240 {
12241 hddLog(VOS_TRACE_LEVEL_FATAL,
12242 "%s: unable to retrieve WCNSS hardware version string",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070012243 __func__);
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -070012244 break;
12245 }
12246
12247 pr_info("%s: WCNSS hardware version %s\n",
12248 WLAN_MODULE_NAME, versionString);
12249
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -070012250 /* 1.Check if FW version is greater than 0.1.1.0. Only then send host-FW capability exchange message
12251 2.Host-FW capability exchange message is only present on riva 1.1 so
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -070012252 send the message only if it the riva is 1.1
12253 minor numbers for different riva branches:
12254 0 -> (1.0)Mainline Build
12255 1 -> (1.1)Mainline Build
12256 2->(1.04) Stability Build
12257 */
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -070012258 if (((versionReported.major>0) || (versionReported.minor>1) ||
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -070012259 ((versionReported.minor>=1) && (versionReported.version>=1)))
12260 && ((versionReported.major == 1) && (versionReported.minor >= 1)))
12261 fwFeatCapsMsgSupported = 1;
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -070012262
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -070012263 if (fwFeatCapsMsgSupported)
Yathish9f22e662012-12-10 14:21:35 -080012264 {
12265#ifdef WLAN_ACTIVEMODE_OFFLOAD_FEATURE
12266 if(!pHddCtx->cfg_ini->fEnableActiveModeOffload)
12267 sme_disableFeatureCapablity(WLANACTIVE_OFFLOAD);
12268#endif
Ravi Joshid2ca7c42013-07-23 08:37:49 -070012269 /* Indicate if IBSS heartbeat monitoring needs to be offloaded */
12270 if (!pHddCtx->cfg_ini->enableIbssHeartBeatOffload)
12271 {
12272 sme_disableFeatureCapablity(IBSS_HEARTBEAT_OFFLOAD);
12273 }
12274
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -070012275 sme_featureCapsExchange(pHddCtx->hHal);
Yathish9f22e662012-12-10 14:21:35 -080012276 }
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -070012277
12278 } while (0);
12279
12280}
Neelansh Mittaledafed22014-09-04 18:54:39 +053012281void wlan_hdd_send_svc_nlink_msg(int type, void *data, int len)
12282{
12283 struct sk_buff *skb;
12284 struct nlmsghdr *nlh;
12285 tAniMsgHdr *ani_hdr;
Hanumantha Reddy Pothulacf2c7ea2015-04-27 14:50:47 +053012286 int flags = GFP_KERNEL;
Bhargav shah23c94942015-10-13 12:48:35 +053012287 void *nl_data = NULL;
Neelansh Mittaledafed22014-09-04 18:54:39 +053012288
Hanumantha Reddy Pothulacf2c7ea2015-04-27 14:50:47 +053012289 if (in_interrupt() || irqs_disabled() || in_atomic())
12290 flags = GFP_ATOMIC;
12291
12292 skb = alloc_skb(NLMSG_SPACE(WLAN_NL_MAX_PAYLOAD), flags);
Neelansh Mittaledafed22014-09-04 18:54:39 +053012293
12294 if(skb == NULL) {
12295 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12296 "%s: alloc_skb failed", __func__);
12297 return;
12298 }
12299
12300 nlh = (struct nlmsghdr *)skb->data;
12301 nlh->nlmsg_pid = 0; /* from kernel */
12302 nlh->nlmsg_flags = 0;
12303 nlh->nlmsg_seq = 0;
12304 nlh->nlmsg_type = WLAN_NL_MSG_SVC;
12305
12306 ani_hdr = NLMSG_DATA(nlh);
12307 ani_hdr->type = type;
12308
12309 switch(type) {
12310 case WLAN_SVC_SAP_RESTART_IND:
12311 ani_hdr->length = 0;
12312 nlh->nlmsg_len = NLMSG_LENGTH((sizeof(tAniMsgHdr)));
12313 skb_put(skb, NLMSG_SPACE(sizeof(tAniMsgHdr)));
12314 break;
Bhargav Shahd0715912015-10-01 18:17:37 +053012315 case WLAN_SVC_WLAN_TP_IND:
12316 ani_hdr->length = len;
12317 nlh->nlmsg_len = NLMSG_LENGTH((sizeof(tAniMsgHdr)
12318 + len));
12319 nl_data = (char *)ani_hdr + sizeof(tAniMsgHdr);
12320 memcpy(nl_data, data, len);
12321 skb_put(skb, NLMSG_SPACE(sizeof(tAniMsgHdr) + len));
12322 break;
Bhargav shah23c94942015-10-13 12:48:35 +053012323 case WLAN_MSG_RPS_ENABLE_IND:
12324 ani_hdr->length = len;
12325 nlh->nlmsg_len = NLMSG_LENGTH((sizeof(tAniMsgHdr) + len));
12326 nl_data = (char *)ani_hdr + sizeof(tAniMsgHdr);
12327 memcpy(nl_data, data, len);
12328 skb_put(skb, NLMSG_SPACE(sizeof(tAniMsgHdr) + len));
12329 break;
Neelansh Mittaledafed22014-09-04 18:54:39 +053012330 default:
12331 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12332 "Attempt to send unknown nlink message %d", type);
12333 kfree_skb(skb);
12334 return;
12335 }
12336
12337 nl_srv_bcast(skb);
12338
12339 return;
12340}
12341
Bhargav Shahd0715912015-10-01 18:17:37 +053012342/**
12343 * hdd_request_tcp_delack() - Find the Delack value based on RX packet
12344 * @pHddCtx: Valid Global HDD context pointer
12345 * @rx_packets: Number of RX packet in perticular time
12346 *
12347 * Based on the RX packet this function calculate next value of tcp delack.
12348 * This function compare rx packet value to high and low threshold limit.
12349 *
12350 * Return: void
12351 */
12352void hdd_request_tcp_delack(hdd_context_t *pHddCtx, uint64_t rx_packets)
12353{
12354 /* average of rx_packets and prev_rx is taken so that
12355 bus width doesnot fluctuate much */
12356 uint64_t temp_rx = (rx_packets + pHddCtx->prev_rx)/2;
12357 TP_IND_TYPE next_rx_level = pHddCtx->cur_rx_level;
Neelansh Mittaledafed22014-09-04 18:54:39 +053012358
Bhargav Shahd0715912015-10-01 18:17:37 +053012359 pHddCtx->prev_rx = rx_packets;
12360 if (temp_rx > pHddCtx->cfg_ini->tcpDelAckThresholdHigh)
12361 next_rx_level = TP_IND_HIGH;
12362 else if (temp_rx <= pHddCtx->cfg_ini->tcpDelAckThresholdLow)
12363 next_rx_level = TP_IND_LOW;
12364
12365 hdd_set_delack_value(pHddCtx, next_rx_level);
12366}
12367
12368#define HDD_BW_GET_DIFF(x, y) ((x) >= (y) ? (x) - (y) : (ULONG_MAX - (y) + (x)))
12369
12370/**
12371 * hdd_tcp_delack_compute_function() - get link status
12372 * @priv: Valid Global HDD context pointer
12373 *
12374 * This function find number of RX packet during timer life span.
12375 * It request tcp delack with number of RX packet and re-configure delack timer
12376 * for tcpDelAckComputeInterval timer interval.
12377 *
12378 * Return: void
12379 */
12380void hdd_tcp_delack_compute_function(void *priv)
12381{
12382 hdd_context_t *pHddCtx = (hdd_context_t *)priv;
12383 hdd_adapter_t *pAdapter = NULL;
12384 v_U32_t rx_packets = 0;
12385 hdd_adapter_list_node_t *pAdapterNode = NULL;
12386 VOS_STATUS status = 0;
12387
12388 for (status = hdd_get_front_adapter(pHddCtx, &pAdapterNode);
12389 NULL != pAdapterNode && VOS_STATUS_SUCCESS == status;
12390 status = hdd_get_next_adapter(pHddCtx, pAdapterNode, &pAdapterNode)) {
12391 if ((pAdapter = pAdapterNode->pAdapter) == NULL)
12392 continue;
12393
12394 rx_packets += HDD_BW_GET_DIFF(pAdapter->stats.rx_packets,
12395 pAdapter->prev_rx_packets);
12396 pAdapter->prev_rx_packets = pAdapter->stats.rx_packets;
12397 }
12398
12399 hdd_request_tcp_delack(pHddCtx, rx_packets);
12400
12401 vos_timer_start(&pHddCtx->delack_timer,
12402 pHddCtx->cfg_ini->tcpDelAckComputeInterval);
12403}
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -070012404
12405/**---------------------------------------------------------------------------
12406
Gopichand Nakkalafce506f2013-07-03 23:55:16 +053012407 \brief hdd_is_5g_supported() - HDD function to know if hardware supports 5GHz
12408
12409 \param - pHddCtx - Pointer to the hdd context
12410
12411 \return - true if hardware supports 5GHz
12412
12413 --------------------------------------------------------------------------*/
Vinay Krishna Erannafacf5e22014-02-24 13:16:25 +053012414boolean hdd_is_5g_supported(hdd_context_t * pHddCtx)
Gopichand Nakkalafce506f2013-07-03 23:55:16 +053012415{
12416 /* If wcnss_wlan_iris_xo_mode() returns WCNSS_XO_48MHZ(1);
12417 * then hardware support 5Ghz.
12418 */
12419 if (WCNSS_XO_48MHZ == wcnss_wlan_iris_xo_mode())
12420 {
Ratheesh S P36dbc932015-08-07 14:28:57 +053012421 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Hardware supports 5Ghz", __func__);
Gopichand Nakkalafce506f2013-07-03 23:55:16 +053012422 return true;
12423 }
12424 else
12425 {
Ratheesh S P36dbc932015-08-07 14:28:57 +053012426 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Hardware doesn't supports 5Ghz",
Gopichand Nakkalafce506f2013-07-03 23:55:16 +053012427 __func__);
12428 return false;
12429 }
12430}
12431
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +053012432/**---------------------------------------------------------------------------
12433
12434 \brief hdd_generate_iface_mac_addr_auto() - HDD Mac Interface Auto
12435 generate function
12436
12437 This is generate the random mac address for WLAN interface
12438
12439 \param - pHddCtx - Pointer to HDD context
12440 idx - Start interface index to get auto
12441 generated mac addr.
12442 mac_addr - Mac address
12443
12444 \return - 0 for success, < 0 for failure
12445
12446 --------------------------------------------------------------------------*/
12447
12448static int hdd_generate_iface_mac_addr_auto(hdd_context_t *pHddCtx,
12449 int idx, v_MACADDR_t mac_addr)
12450{
12451 int i;
12452 unsigned int serialno;
12453 serialno = wcnss_get_serial_number();
12454
12455 if (0 != serialno)
12456 {
12457 /* MAC address has 3 bytes of OUI so we have a maximum of 3
12458 bytes of the serial number that can be used to generate
12459 the other 3 bytes of the MAC address. Mask off all but
12460 the lower 3 bytes (this will also make sure we don't
12461 overflow in the next step) */
12462 serialno &= 0x00FFFFFF;
12463
12464 /* we need a unique address for each session */
12465 serialno *= VOS_MAX_CONCURRENCY_PERSONA;
12466
12467 /* autogen other Mac addresses */
12468 for (i = idx; i < VOS_MAX_CONCURRENCY_PERSONA; i++)
12469 {
12470 /* start with the entire default address */
12471 pHddCtx->cfg_ini->intfMacAddr[i] = mac_addr;
12472 /* then replace the lower 3 bytes */
12473 pHddCtx->cfg_ini->intfMacAddr[i].bytes[3] = (serialno >> 16) & 0xFF;
12474 pHddCtx->cfg_ini->intfMacAddr[i].bytes[4] = (serialno >> 8) & 0xFF;
12475 pHddCtx->cfg_ini->intfMacAddr[i].bytes[5] = serialno & 0xFF;
12476
Nachiket Kukadede2e24f2017-09-25 16:24:27 +053012477 if (0 == memcmp(&pHddCtx->cfg_ini->intfMacAddr[i].bytes[0],
12478 &mac_addr.bytes[0], VOS_MAC_ADDR_SIZE))
12479 pHddCtx->cfg_ini->intfMacAddr[i].bytes[5] +=
12480 VOS_MAX_CONCURRENCY_PERSONA;
12481
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +053012482 serialno++;
12483 hddLog(VOS_TRACE_LEVEL_ERROR,
12484 "%s: Derived Mac Addr: "
12485 MAC_ADDRESS_STR, __func__,
12486 MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[i].bytes));
12487 }
12488
12489 }
12490 else
12491 {
12492 hddLog(LOGE, FL("Failed to Get Serial NO"));
12493 return -1;
12494 }
12495 return 0;
12496}
Gopichand Nakkalafce506f2013-07-03 23:55:16 +053012497
Katya Nigame7b69a82015-04-28 15:24:06 +053012498int wlan_hdd_mon_open(hdd_context_t *pHddCtx)
12499{
12500 VOS_STATUS status;
12501 v_CONTEXT_t pVosContext= NULL;
12502 hdd_adapter_t *pAdapter= NULL;
12503
12504 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
12505
12506 if (NULL == pVosContext)
12507 {
12508 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12509 "%s: Trying to open VOSS without a PreOpen", __func__);
12510 VOS_ASSERT(0);
12511 return VOS_STATUS_E_FAILURE;
12512 }
12513
12514 status = vos_nv_open();
12515 if (!VOS_IS_STATUS_SUCCESS(status))
12516 {
12517 /* NV module cannot be initialized */
12518 hddLog( VOS_TRACE_LEVEL_FATAL,
12519 "%s: vos_nv_open failed", __func__);
12520 return VOS_STATUS_E_FAILURE;
12521 }
12522
12523 status = vos_init_wiphy_from_nv_bin();
12524 if (!VOS_IS_STATUS_SUCCESS(status))
12525 {
12526 /* NV module cannot be initialized */
12527 hddLog( VOS_TRACE_LEVEL_FATAL,
12528 "%s: vos_init_wiphy failed", __func__);
12529 goto err_vos_nv_close;
12530 }
12531
12532 status = vos_open( &pVosContext, pHddCtx->parent_dev);
12533 if ( !VOS_IS_STATUS_SUCCESS( status ))
12534 {
12535 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: vos_open failed", __func__);
12536 goto err_vos_nv_close;
12537 }
12538
12539 status = vos_mon_start( pVosContext );
12540 if ( !VOS_IS_STATUS_SUCCESS( status ) )
12541 {
12542 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: vos_start failed",__func__);
12543 goto err_vosclose;
12544 }
12545
12546 WLANTL_SetMonRxCbk( pVosContext, hdd_rx_packet_monitor_cbk );
12547 WDA_featureCapsExchange(pVosContext);
12548 wcnss_wlan_set_drvdata(pHddCtx->parent_dev, pHddCtx);
12549
12550 pAdapter = hdd_open_adapter( pHddCtx, WLAN_HDD_MONITOR, "wlan%d",
12551 wlan_hdd_get_intf_addr(pHddCtx), FALSE );
12552 if( pAdapter == NULL )
12553 {
12554 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: hdd_open_adapter failed", __func__);
12555 goto err_close_adapter;
12556 }
12557
12558 //Initialize the nlink service
12559 if(nl_srv_init() != 0)
12560 {
12561 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: nl_srv_init failed", __func__);
12562 goto err_close_adapter;
12563 }
12564 return VOS_STATUS_SUCCESS;
12565
12566err_close_adapter:
12567 hdd_close_all_adapters( pHddCtx );
12568 vos_mon_stop( pVosContext );
12569err_vosclose:
12570 status = vos_sched_close( pVosContext );
12571 if (!VOS_IS_STATUS_SUCCESS(status)) {
12572 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
12573 "%s: Failed to close VOSS Scheduler", __func__);
12574 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( status ) );
12575 }
12576 vos_close(pVosContext );
12577
12578err_vos_nv_close:
12579 vos_nv_close();
12580
12581return status;
12582}
Gopichand Nakkalafce506f2013-07-03 23:55:16 +053012583/**---------------------------------------------------------------------------
12584
Mihir Shetefc7ff5b2014-01-27 11:30:05 +053012585 \brief hdd_11d_scan_done - callback to be executed when 11d scan is
12586 completed to flush out the scan results
12587
12588 11d scan is done during driver load and is a passive scan on all
12589 channels supported by the device, 11d scans may find some APs on
12590 frequencies which are forbidden to be used in the regulatory domain
12591 the device is operating in. If these APs are notified to the supplicant
12592 it may try to connect to these APs, thus flush out all the scan results
12593 which are present in SME after 11d scan is done.
12594
12595 \return - eHalStatus
12596
12597 --------------------------------------------------------------------------*/
12598static eHalStatus hdd_11d_scan_done(tHalHandle halHandle, void *pContext,
12599 tANI_U32 scanId, eCsrScanStatus status)
12600{
12601 ENTER();
12602
12603 sme_ScanFlushResult(halHandle, 0);
12604
12605 EXIT();
12606
12607 return eHAL_STATUS_SUCCESS;
12608}
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053012609/**---------------------------------------------------------------------------
12610
12611 \brief hdd_init_frame_logging_done - callback to be executed when mgmt frame
12612 logging is completed successfully.
12613
12614 \return - None
12615
12616 --------------------------------------------------------------------------*/
c_manjeecfd1efb2015-09-25 19:32:34 +053012617void hdd_init_frame_logging_done(void *fwlogInitCbContext, tAniLoggingInitRsp *pRsp)
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053012618{
Siddharth Bhald1be97f2015-05-27 22:39:59 +053012619 hdd_context_t* pHddCtx = (hdd_context_t*)fwlogInitCbContext;
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053012620
12621 if (NULL == pHddCtx)
12622 {
12623 hddLog(VOS_TRACE_LEVEL_ERROR,
12624 "%s: HDD context is NULL",__func__);
12625 return;
12626 }
12627
c_manjeecfd1efb2015-09-25 19:32:34 +053012628 if ((pRsp->status == VOS_STATUS_SUCCESS) &&
Mahesh A Saptasagarfabb1a02015-06-29 12:17:04 +053012629 (TRUE == pHddCtx->cfg_ini->enableMgmtLogging))
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053012630 {
12631 hddLog(VOS_TRACE_LEVEL_INFO, FL("Mgmt Frame Logging init successful"));
12632 pHddCtx->mgmt_frame_logging = TRUE;
12633 }
12634 else
12635 {
12636 hddLog(VOS_TRACE_LEVEL_INFO, FL("Mgmt Frame Logging init not success"));
12637 pHddCtx->mgmt_frame_logging = FALSE;
c_manjeecfd1efb2015-09-25 19:32:34 +053012638 return;
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053012639 }
12640
c_manjeecfd1efb2015-09-25 19:32:34 +053012641 /*Check feature supported by FW*/
12642 if(TRUE == sme_IsFeatureSupportedByFW(MEMORY_DUMP_SUPPORTED))
12643 {
12644 //Store fwr mem dump size given by firmware.
12645 wlan_store_fwr_mem_dump_size(pRsp->fw_mem_dump_max_size);
12646 }
12647 else
12648 {
12649 wlan_store_fwr_mem_dump_size(0);
12650 }
12651
12652
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053012653}
12654/**---------------------------------------------------------------------------
12655
12656 \brief hdd_init_frame_logging - function to initialize frame logging.
12657 Currently only Mgmt Frames are logged in both TX
12658 and Rx direction and are sent to userspace
12659 application using logger thread when queried.
12660
12661 \return - None
12662
12663 --------------------------------------------------------------------------*/
Siddharth Bhald1be97f2015-05-27 22:39:59 +053012664void hdd_init_frame_logging(hdd_context_t* pHddCtx)
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053012665{
12666 eHalStatus halStatus = eHAL_STATUS_FAILURE;
Sreelakshmi Konamkid8784d92016-04-14 14:59:13 +053012667 tSirFWLoggingInitParam wlanFWLoggingInitParam = {0};
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053012668
Siddharth Bhald1be97f2015-05-27 22:39:59 +053012669 if (TRUE != sme_IsFeatureSupportedByFW(MGMT_FRAME_LOGGING) &&
12670 TRUE != sme_IsFeatureSupportedByFW(LOGGING_ENHANCEMENT))
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053012671 {
12672 hddLog(VOS_TRACE_LEVEL_INFO, FL("MGMT_FRAME_LOGGING not supp by FW"));
12673 return;
12674 }
12675
c_manjeecfd1efb2015-09-25 19:32:34 +053012676 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Configuring %s %s %s %s Logging",__func__,
Siddharth Bhald1be97f2015-05-27 22:39:59 +053012677 pHddCtx->cfg_ini->enableFWLogging?"FW Log,":"",
12678 pHddCtx->cfg_ini->enableContFWLogging ? "Cont FW log,":"",
c_manjeecfd1efb2015-09-25 19:32:34 +053012679 pHddCtx->cfg_ini->enableMgmtLogging ? "Mgmt Pkt Log":"",
12680 pHddCtx->cfg_ini->enableFwrMemDump ? "Fw Mem dump":"");
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053012681
Siddharth Bhald1be97f2015-05-27 22:39:59 +053012682 if (pHddCtx->cfg_ini->enableFWLogging ||
12683 pHddCtx->cfg_ini->enableContFWLogging)
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053012684 {
Sreelakshmi Konamkid8784d92016-04-14 14:59:13 +053012685 wlanFWLoggingInitParam.enableFlag |= WLAN_QXDM_LOG_EN;
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053012686 }
12687
Sushant Kaushik46804902015-07-08 14:46:03 +053012688 if (pHddCtx->cfg_ini->enableMgmtLogging)
12689 {
Sreelakshmi Konamkid8784d92016-04-14 14:59:13 +053012690 wlanFWLoggingInitParam.enableFlag |= WLAN_FRAME_LOG_EN;
Sushant Kaushik46804902015-07-08 14:46:03 +053012691 }
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053012692 if (pHddCtx->cfg_ini->enableBMUHWtracing)
12693 {
Sreelakshmi Konamkid8784d92016-04-14 14:59:13 +053012694 wlanFWLoggingInitParam.enableFlag |= WLAN_BMUHW_TRACE_LOG_EN;
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053012695 }
c_manjeecfd1efb2015-09-25 19:32:34 +053012696 if(pHddCtx->cfg_ini->enableFwrMemDump &&
12697 (TRUE == sme_IsFeatureSupportedByFW(MEMORY_DUMP_SUPPORTED)))
12698 {
Sreelakshmi Konamkid8784d92016-04-14 14:59:13 +053012699 wlanFWLoggingInitParam.enableFlag |= WLAN_FW_MEM_DUMP_EN;
c_manjeecfd1efb2015-09-25 19:32:34 +053012700 }
Sreelakshmi Konamkid8784d92016-04-14 14:59:13 +053012701 if( wlanFWLoggingInitParam.enableFlag == 0 )
c_manjeecfd1efb2015-09-25 19:32:34 +053012702 {
12703 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Logging not enabled", __func__);
12704 return;
12705 }
Sreelakshmi Konamkid8784d92016-04-14 14:59:13 +053012706 wlanFWLoggingInitParam.frameType = WLAN_FRAME_LOGGING_FRAMETYPE_MGMT;
12707 wlanFWLoggingInitParam.frameSize = WLAN_MGMT_LOGGING_FRAMESIZE_128BYTES;
12708 wlanFWLoggingInitParam.bufferMode = WLAN_FRAME_LOGGING_BUFFERMODE_CIRCULAR;
12709 wlanFWLoggingInitParam.continuousFrameLogging =
Siddharth Bhald1be97f2015-05-27 22:39:59 +053012710 pHddCtx->cfg_ini->enableContFWLogging;
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053012711
Sreelakshmi Konamkid8784d92016-04-14 14:59:13 +053012712 wlanFWLoggingInitParam.enableFlag &= ~WLAN_DPU_TXP_LOG_EN;
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053012713
Sreelakshmi Konamkid8784d92016-04-14 14:59:13 +053012714 wlanFWLoggingInitParam.minLogBufferSize =
Siddharth Bhald1be97f2015-05-27 22:39:59 +053012715 pHddCtx->cfg_ini->minLoggingBufferSize;
Sreelakshmi Konamkid8784d92016-04-14 14:59:13 +053012716 wlanFWLoggingInitParam.maxLogBufferSize =
Siddharth Bhald1be97f2015-05-27 22:39:59 +053012717 pHddCtx->cfg_ini->maxLoggingBufferSize;
Sreelakshmi Konamkid8784d92016-04-14 14:59:13 +053012718 wlanFWLoggingInitParam.fwlogInitCallback = hdd_init_frame_logging_done;
12719 wlanFWLoggingInitParam.fwlogInitCbContext= pHddCtx;
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053012720
Sreelakshmi Konamkid8784d92016-04-14 14:59:13 +053012721 halStatus = sme_InitMgmtFrameLogging(pHddCtx->hHal, &wlanFWLoggingInitParam);
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053012722
12723 if (eHAL_STATUS_SUCCESS != halStatus)
12724 {
Sreelakshmi Konamkid8784d92016-04-14 14:59:13 +053012725 hddLog(LOGE, FL("sme_InitMgmtFrameLogging failed, returned %d"),
12726 halStatus);
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053012727 }
12728
12729 return;
12730}
Mihir Shetefc7ff5b2014-01-27 11:30:05 +053012731
Bhargav shah23c94942015-10-13 12:48:35 +053012732static void hdd_dp_util_send_rps_ind(hdd_context_t *hdd_ctxt)
12733{
12734 hdd_adapter_t *adapter;
12735 hdd_adapter_list_node_t *adapter_node, *next;
12736 VOS_STATUS status = VOS_STATUS_SUCCESS;
12737 struct wlan_rps_data rps_data;
12738 int count;
12739
12740 if(!hdd_ctxt->cfg_ini->rps_mask)
12741 {
12742 return;
12743 }
12744
12745 for (count=0; count < WLAN_SVC_IFACE_NUM_QUEUES; count++)
12746 {
12747 rps_data.cpu_map[count] = hdd_ctxt->cfg_ini->rps_mask;
12748 }
12749
12750 rps_data.num_queues = WLAN_SVC_IFACE_NUM_QUEUES;
12751
12752 hddLog(LOG1, FL("0x%x 0x%x 0x%x 0x%x 0x%x 0x%x"),
12753 rps_data.cpu_map[0], rps_data.cpu_map[1],rps_data.cpu_map[2],
12754 rps_data.cpu_map[3], rps_data.cpu_map[4], rps_data.cpu_map[5]);
12755
12756 status = hdd_get_front_adapter (hdd_ctxt, &adapter_node);
12757
12758 while (NULL != adapter_node && VOS_STATUS_SUCCESS == status)
12759 {
12760 adapter = adapter_node->pAdapter;
12761 if (NULL != adapter) {
12762 strlcpy(rps_data.ifname, adapter->dev->name,
12763 sizeof(rps_data.ifname));
12764 wlan_hdd_send_svc_nlink_msg(WLAN_MSG_RPS_ENABLE_IND,
12765 (void *)&rps_data,sizeof(rps_data));
12766 }
12767 status = hdd_get_next_adapter (hdd_ctxt, adapter_node, &next);
12768 adapter_node = next;
12769 }
12770}
12771
Masti, Narayanraddi26378462016-01-05 18:20:28 +053012772void wlan_hdd_schedule_defer_scan(struct work_struct *work)
12773{
12774 scan_context_t *scan_ctx =
12775 container_of(work, scan_context_t, scan_work.work);
12776
12777 if (NULL == scan_ctx)
12778 {
12779 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12780 FL("scan_ctx is NULL"));
12781 return;
12782 }
12783
12784 if (unlikely(TDLS_CTX_MAGIC != scan_ctx->magic))
12785 return;
12786
12787 scan_ctx->attempt++;
12788
12789 wlan_hdd_cfg80211_scan(scan_ctx->wiphy,
12790#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
12791 scan_ctx->dev,
12792#endif
12793 scan_ctx->scan_request);
12794}
12795
12796int wlan_hdd_copy_defer_scan_context(hdd_context_t *pHddCtx,
12797 struct wiphy *wiphy,
12798#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
12799 struct net_device *dev,
12800#endif
12801 struct cfg80211_scan_request *request)
12802{
12803 scan_context_t *scan_ctx;
12804
12805 ENTER();
12806 if (0 != (wlan_hdd_validate_context(pHddCtx)))
12807 {
12808 return -1;
12809 }
12810
12811 scan_ctx = &pHddCtx->scan_ctxt;
12812
12813 scan_ctx->wiphy = wiphy;
12814#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
12815 scan_ctx->dev = dev;
12816#endif
12817
12818 scan_ctx->scan_request = request;
12819
12820 EXIT();
12821 return 0;
12822}
12823
12824void wlan_hdd_defer_scan_init_work(hdd_context_t *pHddCtx,
12825 struct wiphy *wiphy,
12826#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
12827 struct net_device *dev,
12828#endif
12829 struct cfg80211_scan_request *request,
12830 unsigned long delay)
12831{
12832 if (TDLS_CTX_MAGIC != pHddCtx->scan_ctxt.magic)
12833 {
12834#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
12835 wlan_hdd_copy_defer_scan_context(pHddCtx, wiphy, dev, request);
12836#else
12837 wlan_hdd_copy_defer_scan_context(pHddCtx, wiphy, request);
12838#endif
12839 pHddCtx->scan_ctxt.attempt = 0;
12840 pHddCtx->scan_ctxt.magic = TDLS_CTX_MAGIC;
12841 }
12842 schedule_delayed_work(&pHddCtx->scan_ctxt.scan_work, delay);
12843}
12844
12845void wlan_hdd_init_deinit_defer_scan_context(scan_context_t *scan_ctx)
12846{
12847 scan_ctx->magic = 0;
12848 scan_ctx->attempt = 0;
12849 scan_ctx->reject = 0;
12850 scan_ctx->scan_request = NULL;
12851
12852 return;
12853}
12854
Mihir Shetefc7ff5b2014-01-27 11:30:05 +053012855/**---------------------------------------------------------------------------
12856
Jeff Johnson295189b2012-06-20 16:38:30 -070012857 \brief hdd_wlan_startup() - HDD init function
12858
12859 This is the driver startup code executed once a WLAN device has been detected
12860
12861 \param - dev - Pointer to the underlying device
12862
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -080012863 \return - 0 for success, < 0 for failure
Jeff Johnson295189b2012-06-20 16:38:30 -070012864
12865 --------------------------------------------------------------------------*/
12866
12867int hdd_wlan_startup(struct device *dev )
12868{
12869 VOS_STATUS status;
12870 hdd_adapter_t *pAdapter = NULL;
Jeff Johnsone7245742012-09-05 17:12:55 -070012871 hdd_adapter_t *pP2pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070012872 hdd_context_t *pHddCtx = NULL;
12873 v_CONTEXT_t pVosContext= NULL;
12874#ifdef WLAN_BTAMP_FEATURE
12875 VOS_STATUS vStatus = VOS_STATUS_SUCCESS;
12876 WLANBAP_ConfigType btAmpConfig;
12877 hdd_config_t *pConfig;
12878#endif
12879 int ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070012880 struct wiphy *wiphy;
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +053012881 v_MACADDR_t mac_addr;
Jeff Johnson295189b2012-06-20 16:38:30 -070012882
12883 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -070012884 /*
12885 * cfg80211: wiphy allocation
12886 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +053012887 wiphy = wlan_hdd_cfg80211_wiphy_alloc(sizeof(hdd_context_t)) ;
Jeff Johnson295189b2012-06-20 16:38:30 -070012888
12889 if(wiphy == NULL)
12890 {
12891 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: cfg80211 init failed", __func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -080012892 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -070012893 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012894 pHddCtx = wiphy_priv(wiphy);
12895
Jeff Johnson295189b2012-06-20 16:38:30 -070012896 //Initialize the adapter context to zeros.
12897 vos_mem_zero(pHddCtx, sizeof( hdd_context_t ));
12898
Jeff Johnson295189b2012-06-20 16:38:30 -070012899 pHddCtx->wiphy = wiphy;
Sushant Kaushik83392fa2015-05-05 17:44:40 +053012900 hdd_prevent_suspend(WIFI_POWER_EVENT_WAKELOCK_DRIVER_INIT);
Mihir Shete18156292014-03-11 15:38:30 +053012901 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_LOAD_IN_PROGRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -070012902
12903 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, TRUE);
12904
Siddharth Bhalcd92b782015-06-29 12:25:40 +053012905 /* register for riva power on lock to platform driver
12906 * Locking power early to ensure FW doesn't reset by kernel while
12907 * host driver is busy initializing itself */
12908 if (req_riva_power_on_lock("wlan"))
12909 {
12910 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: req riva power on lock failed",
12911 __func__);
12912 goto err_free_hdd_context;
12913 }
12914
Jeff Johnson295189b2012-06-20 16:38:30 -070012915 /*Get vos context here bcoz vos_open requires it*/
12916 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
12917
Madan Mohan Koyyalamudi0b78e152012-11-28 15:46:51 -080012918 if(pVosContext == NULL)
12919 {
12920 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Failed vos_get_global_context",__func__);
12921 goto err_free_hdd_context;
12922 }
12923
Jeff Johnson295189b2012-06-20 16:38:30 -070012924 //Save the Global VOSS context in adapter context for future.
12925 pHddCtx->pvosContext = pVosContext;
12926
12927 //Save the adapter context in global context for future.
12928 ((VosContextType*)(pVosContext))->pHDDContext = (v_VOID_t*)pHddCtx;
12929
Jeff Johnson295189b2012-06-20 16:38:30 -070012930 pHddCtx->parent_dev = dev;
Sreelakshmi Konamkif0646d52016-12-09 12:35:31 +053012931 pHddCtx->last_scan_reject_session_id = 0xFF;
12932 pHddCtx->last_scan_reject_reason = 0;
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053012933 pHddCtx->last_scan_reject_timestamp = 0;
Abhishek Singhe4b12562017-06-20 16:53:39 +053012934 pHddCtx->scan_reject_cnt = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070012935
12936 init_completion(&pHddCtx->full_pwr_comp_var);
12937 init_completion(&pHddCtx->standby_comp_var);
12938 init_completion(&pHddCtx->req_bmps_comp_var);
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070012939 init_completion(&pHddCtx->scan_info.scan_req_completion_event);
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -080012940 init_completion(&pHddCtx->scan_info.abortscan_event_var);
Kiet Lam46b8e4e2013-11-06 21:49:53 +053012941 init_completion(&pHddCtx->wiphy_channel_update_event);
Arun Kumar Khandavallie0b046d2014-03-01 21:54:25 +053012942 init_completion(&pHddCtx->ssr_comp_var);
Mahesh A Saptasagar67ab9222015-10-21 15:38:41 +053012943 init_completion(&pHddCtx->mc_sus_event_var);
12944 init_completion(&pHddCtx->tx_sus_event_var);
12945 init_completion(&pHddCtx->rx_sus_event_var);
12946
Amar Singhala49cbc52013-10-08 18:37:44 -070012947
mukul sharma4bd8d2e2015-08-13 20:33:25 +053012948 hdd_init_ll_stats_ctx(pHddCtx);
Anurag Chouhan6ee81542017-02-09 18:09:27 +053012949 hdd_init_nud_stats_ctx(pHddCtx);
mukul sharma4bd8d2e2015-08-13 20:33:25 +053012950
Amar Singhala49cbc52013-10-08 18:37:44 -070012951#ifdef CONFIG_ENABLE_LINUX_REG
Amar Singhalfddc28c2013-09-05 13:03:40 -070012952 init_completion(&pHddCtx->linux_reg_req);
Amar Singhala49cbc52013-10-08 18:37:44 -070012953#else
12954 init_completion(&pHddCtx->driver_crda_req);
12955#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070012956
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +053012957#ifdef WLAN_FEATURE_EXTSCAN
12958 init_completion(&pHddCtx->ext_scan_context.response_event);
12959#endif /* WLAN_FEATURE_EXTSCAN */
12960
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053012961 spin_lock_init(&pHddCtx->schedScan_lock);
Kapil Gupta137ef892016-12-13 19:38:00 +053012962 vos_spin_lock_init(&pHddCtx->sap_update_info_lock);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053012963
Jeff Johnson295189b2012-06-20 16:38:30 -070012964 hdd_list_init( &pHddCtx->hddAdapters, MAX_NUMBER_OF_ADAPTERS );
12965
Padma, Santhosh Kumar9cd38332015-11-17 12:18:10 +053012966 vos_init_delayed_work(&pHddCtx->spoof_mac_addr_work,
12967 hdd_processSpoofMacAddrRequest);
Kapil Gupta137ef892016-12-13 19:38:00 +053012968 vos_init_work(&pHddCtx->sap_start_work, hdd_sap_restart_handle);
Abhishek Singh78c691f2017-11-30 13:48:44 +053012969 vos_init_delayed_work(&pHddCtx->ecsa_chan_change_work,
12970 hdd_force_scc_with_ecsa_handle);
Padma, Santhosh Kumar9cd38332015-11-17 12:18:10 +053012971
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053012972#ifdef FEATURE_WLAN_TDLS
12973 /* tdls_lock is initialized before an hdd_open_adapter ( which is
12974 * invoked by other instances also) to protect the concurrent
12975 * access for the Adapters by TDLS module.
12976 */
12977 mutex_init(&pHddCtx->tdls_lock);
12978#endif
Siddharth Bhal76972212014-10-15 16:22:51 +053012979 mutex_init(&pHddCtx->spoofMacAddr.macSpoofingLock);
Mukul Sharma1fd6efd2015-02-14 00:29:14 +053012980 mutex_init(&pHddCtx->wmmLock);
12981
Srinivas Girigowda8bf64cb2015-09-30 19:50:09 +053012982 hdd_init_offloaded_packets_ctx(pHddCtx);
Agarwal Ashish1f422872014-07-22 00:11:55 +053012983 /* By default Strict Regulatory For FCC should be false */
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053012984
Agarwal Ashish1f422872014-07-22 00:11:55 +053012985 pHddCtx->nEnableStrictRegulatoryForFCC = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070012986 // Load all config first as TL config is needed during vos_open
12987 pHddCtx->cfg_ini = (hdd_config_t*) kmalloc(sizeof(hdd_config_t), GFP_KERNEL);
12988 if(pHddCtx->cfg_ini == NULL)
12989 {
12990 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Failed kmalloc hdd_config_t",__func__);
12991 goto err_free_hdd_context;
12992 }
12993
Hanumanth Reddy Pothula1efcd162018-03-14 14:32:27 +053012994 hdd_request_manager_init();
12995
Jeff Johnson295189b2012-06-20 16:38:30 -070012996 vos_mem_zero(pHddCtx->cfg_ini, sizeof( hdd_config_t ));
12997
12998 // Read and parse the qcom_cfg.ini file
12999 status = hdd_parse_config_ini( pHddCtx );
13000 if ( VOS_STATUS_SUCCESS != status )
13001 {
13002 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: error parsing %s",
13003 __func__, WLAN_INI_FILE);
13004 goto err_config;
13005 }
Arif Hussaind5218912013-12-05 01:10:55 -080013006#ifdef MEMORY_DEBUG
13007 if (pHddCtx->cfg_ini->IsMemoryDebugSupportEnabled)
13008 vos_mem_init();
13009
13010 hddLog(VOS_TRACE_LEVEL_INFO, "%s: gEnableMemoryDebug=%d",
13011 __func__, pHddCtx->cfg_ini->IsMemoryDebugSupportEnabled);
13012#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070013013
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +053013014 /* INI has been read, initialise the configuredMcastBcastFilter with
13015 * INI value as this will serve as the default value
13016 */
13017 pHddCtx->configuredMcastBcastFilter = pHddCtx->cfg_ini->mcastBcastFilterSetting;
13018 hddLog(VOS_TRACE_LEVEL_INFO, "Setting configuredMcastBcastFilter: %d",
13019 pHddCtx->cfg_ini->mcastBcastFilterSetting);
Gopichand Nakkalafce506f2013-07-03 23:55:16 +053013020
13021 if (false == hdd_is_5g_supported(pHddCtx))
13022 {
13023 //5Ghz is not supported.
13024 if (1 != pHddCtx->cfg_ini->nBandCapability)
13025 {
13026 hddLog(VOS_TRACE_LEVEL_INFO,
13027 "%s: Setting pHddCtx->cfg_ini->nBandCapability = 1", __func__);
13028 pHddCtx->cfg_ini->nBandCapability = 1;
13029 }
13030 }
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053013031
13032 /* If SNR Monitoring is enabled, FW has to parse all beacons
13033 * for calcaluting and storing the average SNR, so set Nth beacon
13034 * filter to 1 to enable FW to parse all the beaocons
13035 */
13036 if (1 == pHddCtx->cfg_ini->fEnableSNRMonitoring)
13037 {
13038 /* The log level is deliberately set to WARN as overriding
13039 * nthBeaconFilter to 1 will increase power cosumption and this
13040 * might just prove helpful to detect the power issue.
13041 */
13042 hddLog(VOS_TRACE_LEVEL_WARN,
13043 "%s: Setting pHddCtx->cfg_ini->nthBeaconFilter = 1", __func__);
13044 pHddCtx->cfg_ini->nthBeaconFilter = 1;
13045 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013046 /*
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +053013047 * cfg80211: Initialization ...
Jeff Johnson295189b2012-06-20 16:38:30 -070013048 */
Manjeet Singh61016fa2016-12-02 11:10:19 +053013049 if (0 < wlan_hdd_cfg80211_init(dev, wiphy, pHddCtx->cfg_ini))
Jeff Johnson295189b2012-06-20 16:38:30 -070013050 {
Manjeet Singh61016fa2016-12-02 11:10:19 +053013051 hddLog(VOS_TRACE_LEVEL_FATAL,
13052 "%s: wlan_hdd_cfg80211_init return failure", __func__);
13053 goto err_config;
Jeff Johnson295189b2012-06-20 16:38:30 -070013054 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013055
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -080013056 // Update VOS trace levels based upon the cfg.ini
13057 hdd_vos_trace_enable(VOS_MODULE_ID_BAP,
13058 pHddCtx->cfg_ini->vosTraceEnableBAP);
13059 hdd_vos_trace_enable(VOS_MODULE_ID_TL,
13060 pHddCtx->cfg_ini->vosTraceEnableTL);
13061 hdd_vos_trace_enable(VOS_MODULE_ID_WDI,
13062 pHddCtx->cfg_ini->vosTraceEnableWDI);
13063 hdd_vos_trace_enable(VOS_MODULE_ID_HDD,
13064 pHddCtx->cfg_ini->vosTraceEnableHDD);
13065 hdd_vos_trace_enable(VOS_MODULE_ID_SME,
13066 pHddCtx->cfg_ini->vosTraceEnableSME);
13067 hdd_vos_trace_enable(VOS_MODULE_ID_PE,
13068 pHddCtx->cfg_ini->vosTraceEnablePE);
Katya Nigam70d68332013-09-16 16:49:45 +053013069 hdd_vos_trace_enable(VOS_MODULE_ID_PMC,
13070 pHddCtx->cfg_ini->vosTraceEnablePMC);
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -080013071 hdd_vos_trace_enable(VOS_MODULE_ID_WDA,
13072 pHddCtx->cfg_ini->vosTraceEnableWDA);
13073 hdd_vos_trace_enable(VOS_MODULE_ID_SYS,
13074 pHddCtx->cfg_ini->vosTraceEnableSYS);
13075 hdd_vos_trace_enable(VOS_MODULE_ID_VOSS,
13076 pHddCtx->cfg_ini->vosTraceEnableVOSS);
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -080013077 hdd_vos_trace_enable(VOS_MODULE_ID_SAP,
13078 pHddCtx->cfg_ini->vosTraceEnableSAP);
13079 hdd_vos_trace_enable(VOS_MODULE_ID_HDD_SOFTAP,
13080 pHddCtx->cfg_ini->vosTraceEnableHDDSAP);
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -080013081
Jeff Johnson295189b2012-06-20 16:38:30 -070013082 // Update WDI trace levels based upon the cfg.ini
13083 hdd_wdi_trace_enable(eWLAN_MODULE_DAL,
13084 pHddCtx->cfg_ini->wdiTraceEnableDAL);
13085 hdd_wdi_trace_enable(eWLAN_MODULE_DAL_CTRL,
13086 pHddCtx->cfg_ini->wdiTraceEnableCTL);
13087 hdd_wdi_trace_enable(eWLAN_MODULE_DAL_DATA,
13088 pHddCtx->cfg_ini->wdiTraceEnableDAT);
13089 hdd_wdi_trace_enable(eWLAN_MODULE_PAL,
13090 pHddCtx->cfg_ini->wdiTraceEnablePAL);
Jeff Johnson295189b2012-06-20 16:38:30 -070013091
Jeff Johnson88ba7742013-02-27 14:36:02 -080013092 if (VOS_FTM_MODE == hdd_get_conparam())
13093 {
Jeff Johnson295189b2012-06-20 16:38:30 -070013094 if ( VOS_STATUS_SUCCESS != wlan_hdd_ftm_open(pHddCtx) )
13095 {
13096 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: wlan_hdd_ftm_open Failed",__func__);
13097 goto err_free_hdd_context;
13098 }
13099 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: FTM driver loaded success fully",__func__);
Sachin Ahuja38ef5e02015-03-13 17:31:16 +053013100 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_NO_LOAD_UNLOAD_IN_PROGRESS;
c_hpothu2de0ef62014-04-15 16:16:15 +053013101 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, FALSE);
Jeff Johnson295189b2012-06-20 16:38:30 -070013102 return VOS_STATUS_SUCCESS;
Jeff Johnson88ba7742013-02-27 14:36:02 -080013103 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013104
Katya Nigame7b69a82015-04-28 15:24:06 +053013105 if( VOS_MONITOR_MODE == hdd_get_conparam())
13106 {
13107 if ( VOS_STATUS_SUCCESS != wlan_hdd_mon_open(pHddCtx))
13108 {
13109 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: wlan_hdd_mon_open Failed",__func__);
13110 goto err_free_hdd_context;
13111 }
13112 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Driver loaded in Monitor Mode",__func__);
13113 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_NO_LOAD_UNLOAD_IN_PROGRESS;
13114 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, FALSE);
13115 return VOS_STATUS_SUCCESS;
13116 }
13117
Jeff Johnson88ba7742013-02-27 14:36:02 -080013118 //Open watchdog module
Jeff Johnson295189b2012-06-20 16:38:30 -070013119 if(pHddCtx->cfg_ini->fIsLogpEnabled)
13120 {
13121 status = vos_watchdog_open(pVosContext,
13122 &((VosContextType*)pVosContext)->vosWatchdog, sizeof(VosWatchdogContext));
13123
13124 if(!VOS_IS_STATUS_SUCCESS( status ))
13125 {
13126 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: vos_watchdog_open failed",__func__);
Ashish Kumar Dhanotiya532bdef2017-05-09 17:31:59 +053013127 goto err_config;
Jeff Johnson295189b2012-06-20 16:38:30 -070013128 }
13129 }
13130
13131 pHddCtx->isLogpInProgress = FALSE;
13132 vos_set_logp_in_progress(VOS_MODULE_ID_VOSS, FALSE);
13133
Amar Singhala49cbc52013-10-08 18:37:44 -070013134#ifdef CONFIG_ENABLE_LINUX_REG
Amar Singhal0a402232013-10-11 20:57:16 -070013135 /* initialize the NV module. This is required so that
13136 we can initialize the channel information in wiphy
13137 from the NV.bin data. The channel information in
13138 wiphy needs to be initialized before wiphy registration */
13139
13140 status = vos_nv_open();
13141 if (!VOS_IS_STATUS_SUCCESS(status))
13142 {
13143 /* NV module cannot be initialized */
13144 hddLog( VOS_TRACE_LEVEL_FATAL,
13145 "%s: vos_nv_open failed", __func__);
Vinay Krishna Eranna2025d892014-09-18 16:51:42 +053013146 goto err_wdclose;
Amar Singhal0a402232013-10-11 20:57:16 -070013147 }
13148
13149 status = vos_init_wiphy_from_nv_bin();
13150 if (!VOS_IS_STATUS_SUCCESS(status))
13151 {
13152 /* NV module cannot be initialized */
13153 hddLog( VOS_TRACE_LEVEL_FATAL,
13154 "%s: vos_init_wiphy failed", __func__);
13155 goto err_vos_nv_close;
13156 }
13157
Amar Singhala49cbc52013-10-08 18:37:44 -070013158#endif
Mahesh A Saptasagarc3ed0122016-01-19 16:45:11 +053013159 //Initialize the nlink service
13160 if(nl_srv_init() != 0)
13161 {
13162 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: nl_srv_init failed", __func__);
13163 goto err_vos_nv_close;
13164 }
13165
13166#ifdef WLAN_KD_READY_NOTIFIER
13167 pHddCtx->kd_nl_init = 1;
13168#endif /* WLAN_KD_READY_NOTIFIER */
13169
Girish Gowlibf0e1ab2015-01-19 16:05:16 +053013170 vos_set_roam_delay_stats_enabled(pHddCtx->cfg_ini->gEnableRoamDelayStats);
Arun Kumar Khandavalliebb19482014-03-25 13:56:53 +053013171 status = vos_open( &pVosContext, pHddCtx->parent_dev);
Jeff Johnson295189b2012-06-20 16:38:30 -070013172 if ( !VOS_IS_STATUS_SUCCESS( status ))
13173 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -080013174 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: vos_open failed", __func__);
Mahesh A Saptasagarc3ed0122016-01-19 16:45:11 +053013175 goto err_nl_srv;
Jeff Johnson295189b2012-06-20 16:38:30 -070013176 }
13177
Jeff Johnson295189b2012-06-20 16:38:30 -070013178 pHddCtx->hHal = (tHalHandle)vos_get_context( VOS_MODULE_ID_SME, pVosContext );
13179
13180 if ( NULL == pHddCtx->hHal )
13181 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -080013182 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: HAL context is null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070013183 goto err_vosclose;
13184 }
13185
Jeff Johnsonbc676b42013-02-14 16:04:08 -080013186 status = vos_preStart( pHddCtx->pvosContext );
13187 if ( !VOS_IS_STATUS_SUCCESS( status ) )
13188 {
13189 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: vos_preStart failed", __func__);
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053013190 goto err_vosclose;
Jeff Johnsonbc676b42013-02-14 16:04:08 -080013191 }
Jeff Johnsone7245742012-09-05 17:12:55 -070013192
Arif Hussaineaf68602013-12-30 23:10:44 -080013193 if (0 == enable_dfs_chan_scan || 1 == enable_dfs_chan_scan)
13194 {
13195 pHddCtx->cfg_ini->enableDFSChnlScan = enable_dfs_chan_scan;
13196 hddLog(VOS_TRACE_LEVEL_INFO, "%s: module enable_dfs_chan_scan set to %d",
13197 __func__, enable_dfs_chan_scan);
13198 }
13199 if (0 == enable_11d || 1 == enable_11d)
13200 {
13201 pHddCtx->cfg_ini->Is11dSupportEnabled = enable_11d;
13202 hddLog(VOS_TRACE_LEVEL_INFO, "%s: module enable_11d set to %d",
13203 __func__, enable_11d);
13204 }
13205
Jeff Johnsonbc676b42013-02-14 16:04:08 -080013206 /* Note that the vos_preStart() sequence triggers the cfg download.
13207 The cfg download must occur before we update the SME config
13208 since the SME config operation must access the cfg database */
Jeff Johnson295189b2012-06-20 16:38:30 -070013209 status = hdd_set_sme_config( pHddCtx );
13210
13211 if ( VOS_STATUS_SUCCESS != status )
13212 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -080013213 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Failed hdd_set_sme_config", __func__);
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053013214 goto err_vosclose;
Jeff Johnsonbc676b42013-02-14 16:04:08 -080013215 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013216
Jeff Johnson295189b2012-06-20 16:38:30 -070013217 /* In the integrated architecture we update the configuration from
13218 the INI file and from NV before vOSS has been started so that
13219 the final contents are available to send down to the cCPU */
13220
13221 // Apply the cfg.ini to cfg.dat
13222 if (FALSE == hdd_update_config_dat(pHddCtx))
13223 {
13224 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: config update failed",__func__ );
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053013225 goto err_vosclose;
Jeff Johnson295189b2012-06-20 16:38:30 -070013226 }
13227
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +053013228 // Get mac addr from platform driver
13229 ret = wcnss_get_wlan_mac_address((char*)&mac_addr.bytes);
13230
13231 if ((0 == ret) && (!vos_is_macaddr_zero(&mac_addr)))
Jeff Johnson295189b2012-06-20 16:38:30 -070013232 {
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +053013233 /* Store the mac addr for first interface */
13234 pHddCtx->cfg_ini->intfMacAddr[0] = mac_addr;
13235
13236 hddLog(VOS_TRACE_LEVEL_ERROR,
13237 "%s: WLAN Mac Addr: "
13238 MAC_ADDRESS_STR, __func__,
13239 MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[0].bytes));
13240
13241 /* Here, passing Arg2 as 1 because we do not want to change the
13242 last 3 bytes (means non OUI bytes) of first interface mac
13243 addr.
13244 */
13245 if (0 != hdd_generate_iface_mac_addr_auto(pHddCtx, 1, mac_addr))
13246 {
13247 hddLog(VOS_TRACE_LEVEL_ERROR,
13248 "%s: Failed to generate wlan interface mac addr "
13249 "using MAC from ini file ", __func__);
13250 }
13251 }
13252 else if (VOS_STATUS_SUCCESS != hdd_update_config_from_nv(pHddCtx))
13253 {
13254 // Apply the NV to cfg.dat
13255 /* Prima Update MAC address only at here */
Jeff Johnson295189b2012-06-20 16:38:30 -070013256#ifdef WLAN_AUTOGEN_MACADDR_FEATURE
13257 /* There was not a valid set of MAC Addresses in NV. See if the
13258 default addresses were modified by the cfg.ini settings. If so,
13259 we'll use them, but if not, we'll autogenerate a set of MAC
13260 addresses based upon the device serial number */
13261
13262 static const v_MACADDR_t default_address =
13263 {{0x00, 0x0A, 0xF5, 0x89, 0x89, 0xFF}};
Jeff Johnson295189b2012-06-20 16:38:30 -070013264
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +053013265 if (0 == memcmp(&default_address, &pHddCtx->cfg_ini->intfMacAddr[0],
13266 sizeof(default_address)))
Jeff Johnson295189b2012-06-20 16:38:30 -070013267 {
13268 /* cfg.ini has the default address, invoke autogen logic */
13269
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +053013270 /* Here, passing Arg2 as 0 because we want to change the
13271 last 3 bytes (means non OUI bytes) of all the interfaces
13272 mac addr.
13273 */
13274 if (0 != hdd_generate_iface_mac_addr_auto(pHddCtx, 0,
13275 default_address))
Jeff Johnson295189b2012-06-20 16:38:30 -070013276 {
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +053013277 hddLog(VOS_TRACE_LEVEL_ERROR,
13278 "%s: Failed to generate wlan interface mac addr "
13279 "using MAC from ini file " MAC_ADDRESS_STR, __func__,
13280 MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[0].bytes));
Jeff Johnson295189b2012-06-20 16:38:30 -070013281 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013282 }
13283 else
13284#endif //WLAN_AUTOGEN_MACADDR_FEATURE
13285 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -080013286 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070013287 "%s: Invalid MAC address in NV, using MAC from ini file "
13288 MAC_ADDRESS_STR, __func__,
13289 MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[0].bytes));
13290 }
13291 }
13292 {
13293 eHalStatus halStatus;
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +053013294
13295 /* Set the MAC Address Currently this is used by HAL to
13296 * add self sta. Remove this once self sta is added as
13297 * part of session open.
13298 */
Jeff Johnson295189b2012-06-20 16:38:30 -070013299 halStatus = cfgSetStr( pHddCtx->hHal, WNI_CFG_STA_ID,
13300 (v_U8_t *)&pHddCtx->cfg_ini->intfMacAddr[0],
13301 sizeof( pHddCtx->cfg_ini->intfMacAddr[0]) );
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +053013302
Jeff Johnson295189b2012-06-20 16:38:30 -070013303 if (!HAL_STATUS_SUCCESS( halStatus ))
13304 {
13305 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Failed to set MAC Address. "
13306 "HALStatus is %08d [x%08x]",__func__, halStatus, halStatus );
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053013307 goto err_vosclose;
Jeff Johnson295189b2012-06-20 16:38:30 -070013308 }
13309 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013310
13311 /*Start VOSS which starts up the SME/MAC/HAL modules and everything else
13312 Note: Firmware image will be read and downloaded inside vos_start API */
13313 status = vos_start( pHddCtx->pvosContext );
13314 if ( !VOS_IS_STATUS_SUCCESS( status ) )
13315 {
13316 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: vos_start failed",__func__);
Hanumantha Reddy Pothulabd9601a2016-02-12 13:22:27 +053013317 if (isSsrPanicOnFailure())
13318 VOS_BUG(0);
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053013319 goto err_vosclose;
Jeff Johnson295189b2012-06-20 16:38:30 -070013320 }
13321
Leo Chang6cec3e22014-01-21 15:33:49 -080013322#ifdef FEATURE_WLAN_CH_AVOID
13323 /* Plug in avoid channel notification callback
13324 * This should happen before ADD_SELF_STA
13325 * FW will send first IND with ADD_SELF_STA REQ from host */
Pradeep Reddy POTTETI5c2e16d2014-06-27 16:47:38 +053013326
13327 /* check the Channel Avoidance is enabled */
13328 if (TRUE == pHddCtx->cfg_ini->fenableCHAvoidance)
13329 {
13330 sme_AddChAvoidCallback(pHddCtx->hHal,
13331 hdd_hostapd_ch_avoid_cb);
13332 }
Leo Chang6cec3e22014-01-21 15:33:49 -080013333#endif /* FEATURE_WLAN_CH_AVOID */
13334
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -070013335 /* Exchange capability info between Host and FW and also get versioning info from FW */
13336 hdd_exchange_version_and_caps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -070013337
Agarwal Ashishad9281b2014-06-10 14:57:30 +053013338#ifdef CONFIG_ENABLE_LINUX_REG
13339 status = wlan_hdd_init_channels(pHddCtx);
13340 if ( !VOS_IS_STATUS_SUCCESS( status ) )
13341 {
13342 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: wlan_hdd_init_channels failed",
13343 __func__);
13344 goto err_vosstop;
13345 }
13346#endif
13347
Jeff Johnson295189b2012-06-20 16:38:30 -070013348 status = hdd_post_voss_start_config( pHddCtx );
13349 if ( !VOS_IS_STATUS_SUCCESS( status ) )
13350 {
13351 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hdd_post_voss_start_config failed",
13352 __func__);
13353 goto err_vosstop;
13354 }
Amar Singhala49cbc52013-10-08 18:37:44 -070013355
13356#ifndef CONFIG_ENABLE_LINUX_REG
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +053013357 wlan_hdd_cfg80211_update_reg_info( wiphy );
13358
13359 /* registration of wiphy dev with cfg80211 */
13360 if (0 > wlan_hdd_cfg80211_register(wiphy))
13361 {
13362 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy register failed", __func__);
13363 goto err_vosstop;
13364 }
Amar Singhala49cbc52013-10-08 18:37:44 -070013365#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070013366
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053013367#ifdef CONFIG_ENABLE_LINUX_REG
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053013368 /* registration of wiphy dev with cfg80211 */
13369 if (0 > wlan_hdd_cfg80211_register(wiphy))
13370 {
13371 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy register failed", __func__);
13372 goto err_vosstop;
13373 }
13374
Agarwal Ashish6db9d532014-09-30 18:19:10 +053013375 status = wlan_hdd_init_channels_for_cc(pHddCtx, INIT);
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053013376 if ( !VOS_IS_STATUS_SUCCESS( status ) )
13377 {
13378 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: wlan_hdd_init_channels_for_cc failed",
13379 __func__);
13380 goto err_unregister_wiphy;
13381 }
13382#endif
13383
c_hpothu4a298be2014-12-22 21:12:51 +053013384 wcnss_wlan_set_drvdata(pHddCtx->parent_dev, pHddCtx);
13385
Jeff Johnson295189b2012-06-20 16:38:30 -070013386 if (VOS_STA_SAP_MODE == hdd_get_conparam())
13387 {
13388 pAdapter = hdd_open_adapter( pHddCtx, WLAN_HDD_SOFTAP, "softap.%d",
13389 wlan_hdd_get_intf_addr(pHddCtx), FALSE );
13390 }
13391 else
13392 {
Jeff Johnson295189b2012-06-20 16:38:30 -070013393 pAdapter = hdd_open_adapter( pHddCtx, WLAN_HDD_INFRA_STATION, "wlan%d",
13394 wlan_hdd_get_intf_addr(pHddCtx), FALSE );
13395 if (pAdapter != NULL)
13396 {
Katya Nigama7d81d72014-11-12 12:44:34 +053013397 if (pHddCtx->cfg_ini->isP2pDeviceAddrAdministrated && !(pHddCtx->cfg_ini->intfMacAddr[0].bytes[0] & 0x02))
Jeff Johnson295189b2012-06-20 16:38:30 -070013398 {
Gopichand Nakkala49f96f62013-02-06 14:38:17 +053013399 vos_mem_copy( pHddCtx->p2pDeviceAddress.bytes,
13400 pHddCtx->cfg_ini->intfMacAddr[0].bytes,
13401 sizeof(tSirMacAddr));
Madan Mohan Koyyalamudiedfc1b72012-10-18 20:25:55 -070013402
Gopichand Nakkala49f96f62013-02-06 14:38:17 +053013403 /* Generate the P2P Device Address. This consists of the device's
13404 * primary MAC address with the locally administered bit set.
13405 */
13406 pHddCtx->p2pDeviceAddress.bytes[0] |= 0x02;
Jeff Johnsone7245742012-09-05 17:12:55 -070013407 }
13408 else
13409 {
Gopichand Nakkala49f96f62013-02-06 14:38:17 +053013410 tANI_U8* p2p_dev_addr = wlan_hdd_get_intf_addr(pHddCtx);
13411 if (p2p_dev_addr != NULL)
13412 {
13413 vos_mem_copy(&pHddCtx->p2pDeviceAddress.bytes[0],
13414 p2p_dev_addr, VOS_MAC_ADDR_SIZE);
13415 }
13416 else
13417 {
13418 hddLog(VOS_TRACE_LEVEL_FATAL,
13419 "%s: Failed to allocate mac_address for p2p_device",
13420 __func__);
13421 goto err_close_adapter;
13422 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013423 }
Jeff Johnsone7245742012-09-05 17:12:55 -070013424
13425 pP2pAdapter = hdd_open_adapter( pHddCtx, WLAN_HDD_P2P_DEVICE, "p2p%d",
13426 &pHddCtx->p2pDeviceAddress.bytes[0], FALSE );
13427 if ( NULL == pP2pAdapter )
13428 {
13429 hddLog(VOS_TRACE_LEVEL_FATAL,
13430 "%s: Failed to do hdd_open_adapter for P2P Device Interface",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070013431 __func__);
Jeff Johnsone7245742012-09-05 17:12:55 -070013432 goto err_close_adapter;
13433 }
Jeff Johnsone7245742012-09-05 17:12:55 -070013434 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013435 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013436
13437 if( pAdapter == NULL )
13438 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -080013439 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: hdd_open_adapter failed", __func__);
13440 goto err_close_adapter;
Jeff Johnson295189b2012-06-20 16:38:30 -070013441 }
Jeff Johnsone7245742012-09-05 17:12:55 -070013442
Arif Hussain66559122013-11-21 10:11:40 -080013443 if (country_code)
13444 {
13445 eHalStatus ret;
Arif Hussaincb607082013-12-20 11:57:42 -080013446 INIT_COMPLETION(pAdapter->change_country_code);
Arif Hussain66559122013-11-21 10:11:40 -080013447 hdd_checkandupdate_dfssetting(pAdapter, country_code);
13448#ifndef CONFIG_ENABLE_LINUX_REG
13449 hdd_checkandupdate_phymode(pAdapter, country_code);
13450#endif
Arif Hussaineaf68602013-12-30 23:10:44 -080013451 ret = sme_ChangeCountryCode(pHddCtx->hHal,
13452 (void *)(tSmeChangeCountryCallback)
13453 wlan_hdd_change_country_code_callback,
Arif Hussain66559122013-11-21 10:11:40 -080013454 country_code,
13455 pAdapter, pHddCtx->pvosContext,
Abhishek Singha306a442013-11-07 18:39:01 +053013456 eSIR_TRUE, eSIR_TRUE);
Arif Hussain66559122013-11-21 10:11:40 -080013457 if (eHAL_STATUS_SUCCESS == ret)
13458 {
Arif Hussaincb607082013-12-20 11:57:42 -080013459 ret = wait_for_completion_interruptible_timeout(
13460 &pAdapter->change_country_code,
13461 msecs_to_jiffies(WLAN_WAIT_TIME_COUNTRY));
13462
13463 if (0 >= ret)
13464 {
13465 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
13466 "%s: SME while setting country code timed out", __func__);
13467 }
Arif Hussain66559122013-11-21 10:11:40 -080013468 }
13469 else
13470 {
Arif Hussaincb607082013-12-20 11:57:42 -080013471 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
13472 "%s: SME Change Country code from module param fail ret=%d",
13473 __func__, ret);
Arif Hussain66559122013-11-21 10:11:40 -080013474 }
13475 }
13476
Jeff Johnson295189b2012-06-20 16:38:30 -070013477#ifdef WLAN_BTAMP_FEATURE
13478 vStatus = WLANBAP_Open(pVosContext);
13479 if(!VOS_IS_STATUS_SUCCESS(vStatus))
13480 {
13481 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
13482 "%s: Failed to open BAP",__func__);
Jeff Johnsone7245742012-09-05 17:12:55 -070013483 goto err_close_adapter;
Jeff Johnson295189b2012-06-20 16:38:30 -070013484 }
13485
13486 vStatus = BSL_Init(pVosContext);
13487 if(!VOS_IS_STATUS_SUCCESS(vStatus))
13488 {
13489 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
13490 "%s: Failed to Init BSL",__func__);
13491 goto err_bap_close;
13492 }
13493 vStatus = WLANBAP_Start(pVosContext);
13494 if (!VOS_IS_STATUS_SUCCESS(vStatus))
13495 {
13496 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
13497 "%s: Failed to start TL",__func__);
13498 goto err_bap_close;
13499 }
13500
13501 pConfig = pHddCtx->cfg_ini;
13502 btAmpConfig.ucPreferredChannel = pConfig->preferredChannel;
13503 status = WLANBAP_SetConfig(&btAmpConfig);
13504
13505#endif //WLAN_BTAMP_FEATURE
Jeff Johnsone7245742012-09-05 17:12:55 -070013506
Mihir Shete9c238772014-10-15 14:35:16 +053013507 /*
13508 * UapsdMask is 0xf if U-APSD is enbaled for all AC's...
13509 * The value of CFG_QOS_WMM_UAPSD_MASK_DEFAULT is 0xaa(Magic Value)
13510 * which is greater than 0xf. So the below check is safe to make
13511 * sure that there is no entry for UapsdMask in the ini
13512 */
13513 if (CFG_QOS_WMM_UAPSD_MASK_DEFAULT == pHddCtx->cfg_ini->UapsdMask)
13514 {
13515 if(IS_DYNAMIC_WMM_PS_ENABLED)
13516 {
13517 hddLog(VOS_TRACE_LEVEL_DEBUG,"%s: Enable UAPSD for VI & VO",
13518 __func__);
13519 pHddCtx->cfg_ini->UapsdMask =
13520 CFG_QOS_WMM_UAPSD_MASK_DYMANIC_WMM_PS_DEFAULT;
13521 }
13522 else
13523 {
13524 hddLog(VOS_TRACE_LEVEL_DEBUG,"%s: Do not enable UAPSD",
13525 __func__);
13526 pHddCtx->cfg_ini->UapsdMask =
13527 CFG_QOS_WMM_UAPSD_MASK_LEGACY_WMM_PS_DEFAULT;
13528 }
13529 }
13530
Varun Reddy Yeturud0a3f252013-04-15 21:58:13 -070013531#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
13532 if(!(IS_ROAM_SCAN_OFFLOAD_FEATURE_ENABLE))
13533 {
13534 hddLog(VOS_TRACE_LEVEL_DEBUG,"%s: ROAM_SCAN_OFFLOAD Feature not supported",__func__);
13535 pHddCtx->cfg_ini->isRoamOffloadScanEnabled = 0;
13536 sme_UpdateRoamScanOffloadEnabled((tHalHandle)(pHddCtx->hHal),
13537 pHddCtx->cfg_ini->isRoamOffloadScanEnabled);
13538 }
13539#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070013540
Agarwal Ashish4b87f922014-06-18 03:03:21 +053013541 wlan_hdd_tdls_init(pHddCtx);
13542
Masti, Narayanraddi26378462016-01-05 18:20:28 +053013543 wlan_hdd_init_deinit_defer_scan_context(&pHddCtx->scan_ctxt);
13544
13545 vos_init_delayed_work(&pHddCtx->scan_ctxt.scan_work,
13546 wlan_hdd_schedule_defer_scan);
13547
Mihir Shetefc7ff5b2014-01-27 11:30:05 +053013548 sme_Register11dScanDoneCallback(pHddCtx->hHal, hdd_11d_scan_done);
13549
Jeff Johnson295189b2012-06-20 16:38:30 -070013550 /* Register with platform driver as client for Suspend/Resume */
13551 status = hddRegisterPmOps(pHddCtx);
13552 if ( !VOS_IS_STATUS_SUCCESS( status ) )
13553 {
13554 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddRegisterPmOps failed",__func__);
13555#ifdef WLAN_BTAMP_FEATURE
13556 goto err_bap_stop;
13557#else
Jeff Johnsone7245742012-09-05 17:12:55 -070013558 goto err_close_adapter;
Jeff Johnson295189b2012-06-20 16:38:30 -070013559#endif //WLAN_BTAMP_FEATURE
13560 }
13561
Yue Ma0d4891e2013-08-06 17:01:45 -070013562 /* Open debugfs interface */
13563 if (VOS_STATUS_SUCCESS != hdd_debugfs_init(pAdapter))
13564 {
13565 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
13566 "%s: hdd_debugfs_init failed!", __func__);
Yue Ma0d4891e2013-08-06 17:01:45 -070013567 }
13568
Jeff Johnson295189b2012-06-20 16:38:30 -070013569 /* Register TM level change handler function to the platform */
13570 status = hddDevTmRegisterNotifyCallback(pHddCtx);
13571 if ( !VOS_IS_STATUS_SUCCESS( status ) )
13572 {
13573 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddDevTmRegisterNotifyCallback failed",__func__);
13574 goto err_unregister_pmops;
13575 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013576
Jeff Johnson295189b2012-06-20 16:38:30 -070013577 // register net device notifier for device change notification
13578 ret = register_netdevice_notifier(&hdd_netdev_notifier);
13579
13580 if(ret < 0)
13581 {
13582 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: register_netdevice_notifier failed",__func__);
Siddharth Bhalcd92b782015-06-29 12:25:40 +053013583 goto err_unregister_pmops;
Jeff Johnson295189b2012-06-20 16:38:30 -070013584 }
13585
Jeff Johnson295189b2012-06-20 16:38:30 -070013586 //Initialize the BTC service
13587 if(btc_activate_service(pHddCtx) != 0)
13588 {
13589 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: btc_activate_service failed",__func__);
Mahesh A Saptasagarc3ed0122016-01-19 16:45:11 +053013590 goto err_reg_netdev;
Jeff Johnson295189b2012-06-20 16:38:30 -070013591 }
13592
Padma, Santhosh Kumar2762e9d2015-10-20 15:02:57 +053013593#ifdef FEATURE_OEM_DATA_SUPPORT
13594 //Initialize the OEM service
13595 if (oem_activate_service(pHddCtx) != 0)
13596 {
13597 hddLog(VOS_TRACE_LEVEL_FATAL,
13598 "%s: oem_activate_service failed", __func__);
Hanumanth Reddy Pothula13789c42017-09-12 15:18:13 +053013599 goto err_btc_activate_service;
Padma, Santhosh Kumar2762e9d2015-10-20 15:02:57 +053013600 }
13601#endif
13602
Jeff Johnson295189b2012-06-20 16:38:30 -070013603#ifdef PTT_SOCK_SVC_ENABLE
13604 //Initialize the PTT service
13605 if(ptt_sock_activate_svc(pHddCtx) != 0)
13606 {
13607 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: ptt_sock_activate_svc failed",__func__);
Hanumanth Reddy Pothula13789c42017-09-12 15:18:13 +053013608 goto err_oem_activate_service;
Jeff Johnson295189b2012-06-20 16:38:30 -070013609 }
13610#endif
13611
Abhishek Singh00b71972016-01-07 10:51:04 +053013612#ifdef WLAN_FEATURE_RMC
13613 if (hdd_open_cesium_nl_sock() < 0)
13614 {
13615 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hdd_open_cesium_nl_sock failed", __func__);
Hanumanth Reddy Pothula13789c42017-09-12 15:18:13 +053013616 goto err_ptt_sock_activate_svc;
Abhishek Singh00b71972016-01-07 10:51:04 +053013617 }
13618#endif
13619
Vinay Krishna Erannad938c422014-03-10 17:14:21 +053013620#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
13621 if(pHddCtx->cfg_ini && pHddCtx->cfg_ini->wlanLoggingEnable)
13622 {
Deepthi Gowri78083a32014-11-04 12:55:51 +053013623 if(wlan_logging_sock_activate_svc(
13624 pHddCtx->cfg_ini->wlanLoggingFEToConsole,
Sushant Kaushik33200572015-08-05 16:46:20 +053013625 pHddCtx->cfg_ini->wlanLoggingNumBuf,
13626 pHddCtx->cfg_ini->wlanPerPktStatsLogEnable,
13627 pHddCtx->cfg_ini->wlanPerPktStatsNumBuf))
Deepthi Gowri78083a32014-11-04 12:55:51 +053013628 {
13629 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wlan_logging_sock_activate_svc"
13630 " failed", __func__);
Hanumanth Reddy Pothula13789c42017-09-12 15:18:13 +053013631 goto err_open_cesium_nl_sock;
Deepthi Gowri78083a32014-11-04 12:55:51 +053013632 }
13633 //TODO: To Remove enableDhcpDebug and use gEnableDebugLog for
13634 //EAPOL and DHCP
Sachin Ahuja8c65f382014-12-12 15:34:21 +053013635 if (!pHddCtx->cfg_ini->gEnableDebugLog)
13636 pHddCtx->cfg_ini->gEnableDebugLog =
Sushant Kaushik6e4e2bc2015-10-05 17:23:07 +053013637 VOS_PKT_PROTO_TYPE_EAPOL | VOS_PKT_PROTO_TYPE_DHCP |
13638 VOS_PKT_PROTO_TYPE_ARP;
Vinay Krishna Erannad938c422014-03-10 17:14:21 +053013639 }
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053013640
Siddharth Bhald1be97f2015-05-27 22:39:59 +053013641 if (pHddCtx->cfg_ini->wlanLoggingEnable &&
13642 (pHddCtx->cfg_ini->enableFWLogging ||
Siddharth Bhaldb963232015-06-25 19:34:35 +053013643 pHddCtx->cfg_ini->enableMgmtLogging ||
c_manjeecfd1efb2015-09-25 19:32:34 +053013644 pHddCtx->cfg_ini->enableContFWLogging ||
13645 pHddCtx->cfg_ini->enableFwrMemDump )
13646 )
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053013647 {
Siddharth Bhald1be97f2015-05-27 22:39:59 +053013648 hdd_init_frame_logging(pHddCtx);
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053013649 }
13650 else
13651 {
Siddharth Bhald1be97f2015-05-27 22:39:59 +053013652 hddLog(VOS_TRACE_LEVEL_INFO, FL("Logging disabled in ini"));
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053013653 }
13654
Vinay Krishna Erannad938c422014-03-10 17:14:21 +053013655#endif
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053013656
Agrawal Ashish17ef5082016-10-17 18:33:21 +053013657#ifdef SAP_AUTH_OFFLOAD
13658 if (!sme_IsFeatureSupportedByFW(SAP_OFFLOADS))
13659 {
13660 hddLog(VOS_TRACE_LEVEL_INFO, FL(" SAP AUTH OFFLOAD not supp by FW"));
13661 pHddCtx->cfg_ini->enable_sap_auth_offload = 0;
13662 }
13663#endif
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053013664
Sushant Kaushik215778f2015-05-21 14:05:36 +053013665 if (vos_is_multicast_logging())
13666 wlan_logging_set_log_level();
13667
Jeff Johnson295189b2012-06-20 16:38:30 -070013668 hdd_register_mcast_bcast_filter(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -070013669 if (VOS_STA_SAP_MODE != hdd_get_conparam())
Jeff Johnson295189b2012-06-20 16:38:30 -070013670 {
Madan Mohan Koyyalamudic537df22012-10-22 15:07:08 -070013671 /* Action frame registered in one adapter which will
13672 * applicable to all interfaces
13673 */
Agarwal Ashish8fa0e9a2014-05-23 00:40:12 +053013674 wlan_hdd_cfg80211_register_frames(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070013675 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013676
13677 mutex_init(&pHddCtx->sap_lock);
Mahesh A Saptasagar60627942014-10-13 13:55:14 +053013678 mutex_init(&pHddCtx->roc_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -070013679
Jeff Johnsone7245742012-09-05 17:12:55 -070013680#ifdef WLAN_FEATURE_HOLD_RX_WAKELOCK
13681 /* Initialize the wake lcok */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053013682 vos_wake_lock_init(&pHddCtx->rx_wake_lock,
Jeff Johnsone7245742012-09-05 17:12:55 -070013683 "qcom_rx_wakelock");
Sushant Kaushik83392fa2015-05-05 17:44:40 +053013684
Jeff Johnsone7245742012-09-05 17:12:55 -070013685#endif
Madan Mohan Koyyalamudi69fc3ad2012-11-28 16:04:56 -080013686 /* Initialize the wake lcok */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053013687 vos_wake_lock_init(&pHddCtx->sap_wake_lock,
Madan Mohan Koyyalamudi69fc3ad2012-11-28 16:04:56 -080013688 "qcom_sap_wakelock");
Sushant Kaushik83392fa2015-05-05 17:44:40 +053013689
Jeff Johnsone7245742012-09-05 17:12:55 -070013690
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070013691 vos_event_init(&pHddCtx->scan_info.scan_finished_event);
13692 pHddCtx->scan_info.scan_pending_option = WEXT_SCAN_PENDING_GIVEUP;
Jeff Johnson295189b2012-06-20 16:38:30 -070013693
Katya Nigam5c306ea2014-06-19 15:39:54 +053013694 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_NO_LOAD_UNLOAD_IN_PROGRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -070013695 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, FALSE);
Sushant Kaushik83392fa2015-05-05 17:44:40 +053013696 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_DRIVER_INIT);
Katya Nigam5c306ea2014-06-19 15:39:54 +053013697
13698#ifdef FEATURE_WLAN_SCAN_PNO
13699 /*SME must send channel update configuration to RIVA*/
13700 sme_UpdateChannelConfig(pHddCtx->hHal);
13701#endif
Abhishek Singhf644b272014-08-21 02:59:39 +053013702 /* Send the update default channel list to the FW*/
13703 sme_UpdateChannelList(pHddCtx->hHal);
Mukul Sharma45063942015-04-01 20:07:59 +053013704
13705 /* Fwr capabilities received, Set the Dot11 mode */
Abhishek Singh41ebce12016-02-03 10:43:21 +053013706 sme_SetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter),
13707 hdd_cfg_xlate_to_csr_phy_mode(pHddCtx->cfg_ini->dot11Mode));
Mukul Sharma45063942015-04-01 20:07:59 +053013708 sme_SetDefDot11Mode(pHddCtx->hHal);
13709
Abhishek Singha306a442013-11-07 18:39:01 +053013710#ifndef CONFIG_ENABLE_LINUX_REG
13711 /*updating wiphy so that regulatory user hints can be processed*/
13712 if (wiphy)
13713 {
13714 regulatory_hint(wiphy, "00");
13715 }
13716#endif
Jeff Johnsone7245742012-09-05 17:12:55 -070013717 // Initialize the restart logic
13718 wlan_hdd_restart_init(pHddCtx);
Chilam NG571c65a2013-01-19 12:27:36 +053013719
Hanumanth Reddy Pothula146bca42016-11-08 12:01:07 +053013720 if (pHddCtx->cfg_ini->fIsLogpEnabled) {
13721 vos_wdthread_init_timer_work(vos_process_wd_timer);
13722 /* Initialize the timer to detect thread stuck issues */
13723 vos_thread_stuck_timer_init(
13724 &((VosContextType*)pVosContext)->vosWatchdog);
13725 }
13726
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -070013727 //Register the traffic monitor timer now
13728 if ( pHddCtx->cfg_ini->dynSplitscan)
13729 {
13730 vos_timer_init(&pHddCtx->tx_rx_trafficTmr,
13731 VOS_TIMER_TYPE_SW,
13732 hdd_tx_rx_pkt_cnt_stat_timer_handler,
13733 (void *)pHddCtx);
13734 }
Srinivas Dasari030bad32015-02-18 23:23:54 +053013735 wlan_hdd_cfg80211_nan_init(pHddCtx);
13736
Bhargav Shahd0715912015-10-01 18:17:37 +053013737 mutex_init(&pHddCtx->cur_rx_level_lock);
13738 vos_timer_init(&pHddCtx->delack_timer, VOS_TIMER_TYPE_SW,
13739 hdd_tcp_delack_compute_function,(void *)pHddCtx);
Masti, Narayanraddi44b0db02015-12-22 11:54:35 +053013740 vos_timer_init(&pHddCtx->tdls_source_timer, VOS_TIMER_TYPE_SW,
13741 wlan_hdd_change_tdls_mode, (void *)pHddCtx);
Bhargav Shahd0715912015-10-01 18:17:37 +053013742
Dino Mycle6fb96c12014-06-10 11:52:40 +053013743#ifdef WLAN_FEATURE_EXTSCAN
13744 sme_EXTScanRegisterCallback(pHddCtx->hHal,
13745 wlan_hdd_cfg80211_extscan_callback,
13746 pHddCtx);
13747#endif /* WLAN_FEATURE_EXTSCAN */
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +053013748
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053013749#ifdef FEATURE_OEM_DATA_SUPPORT
13750 sme_OemDataRegisterCallback(pHddCtx->hHal,
13751 wlan_hdd_cfg80211_oemdata_callback,
13752 pHddCtx);
13753#endif /* FEATURE_OEM_DATA_SUPPORT */
13754
Gupta, Kapil7c34b322015-09-30 13:12:35 +053013755 sme_set_rssi_threshold_breached_cb(pHddCtx->hHal, hdd_rssi_threshold_breached_cb);
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +053013756#ifdef WLAN_NS_OFFLOAD
13757 // Register IPv6 notifier to notify if any change in IP
13758 // So that we can reconfigure the offload parameters
13759 pHddCtx->ipv6_notifier.notifier_call = wlan_hdd_ipv6_changed;
13760 ret = register_inet6addr_notifier(&pHddCtx->ipv6_notifier);
13761 if (ret)
13762 {
Ratheesh S P36dbc932015-08-07 14:28:57 +053013763 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to register IPv6 notifier"));
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +053013764 }
13765 else
13766 {
Ratheesh S P36dbc932015-08-07 14:28:57 +053013767 hddLog(VOS_TRACE_LEVEL_INFO, FL("Registered IPv6 notifier"));
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +053013768 }
13769#endif
13770
Sravan Kumar Kairamb0edc612016-10-26 13:55:24 +053013771 vos_mem_set((uint8_t *)&pHddCtx->bad_sta, HDD_MAX_STA_COUNT, 0);
13772
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +053013773 // Register IPv4 notifier to notify if any change in IP
13774 // So that we can reconfigure the offload parameters
13775 pHddCtx->ipv4_notifier.notifier_call = wlan_hdd_ipv4_changed;
13776 ret = register_inetaddr_notifier(&pHddCtx->ipv4_notifier);
13777 if (ret)
13778 {
Ratheesh S P36dbc932015-08-07 14:28:57 +053013779 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to register IPv4 notifier"));
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +053013780 }
13781 else
13782 {
Ratheesh S P36dbc932015-08-07 14:28:57 +053013783 hddLog(VOS_TRACE_LEVEL_INFO, FL("Registered IPv4 notifier"));
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +053013784 }
c_manjeecfd1efb2015-09-25 19:32:34 +053013785 /*Fw mem dump procfs initialization*/
13786 memdump_init();
Bhargav shah23c94942015-10-13 12:48:35 +053013787 hdd_dp_util_send_rps_ind(pHddCtx);
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +053013788
Nishank Aggarwalc11826c2016-12-15 18:54:10 +053013789 pHddCtx->is_ap_mode_wow_supported =
13790 sme_IsFeatureSupportedByFW(SAP_MODE_WOW);
Sravan Kumar Kairam091e5b62017-01-23 14:14:20 +053013791
Hanumanth Reddy Pothulae92bcc12017-05-19 13:56:35 +053013792 pHddCtx->is_fatal_event_log_sup =
13793 sme_IsFeatureSupportedByFW(FATAL_EVENT_LOGGING);
13794 hddLog(VOS_TRACE_LEVEL_INFO, FL("FATAL_EVENT_LOGGING: %d"),
13795 pHddCtx->is_fatal_event_log_sup);
13796
Sravan Kumar Kairam091e5b62017-01-23 14:14:20 +053013797 hdd_assoc_registerFwdEapolCB(pVosContext);
13798
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +053013799 mutex_init(&pHddCtx->cache_channel_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -070013800 goto success;
13801
Hanumanth Reddy Pothula13789c42017-09-12 15:18:13 +053013802err_open_cesium_nl_sock:
13803#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
13804 hdd_close_cesium_nl_sock();
13805#endif
13806
13807err_ptt_sock_activate_svc:
13808#ifdef PTT_SOCK_SVC_ENABLE
13809 ptt_sock_deactivate_svc(pHddCtx);
13810#endif
13811
13812err_oem_activate_service:
13813#ifdef FEATURE_OEM_DATA_SUPPORT
13814 oem_deactivate_service();
13815#endif
13816
13817err_btc_activate_service:
13818 btc_deactivate_service();
13819
Jeff Johnson295189b2012-06-20 16:38:30 -070013820err_reg_netdev:
13821 unregister_netdevice_notifier(&hdd_netdev_notifier);
13822
Jeff Johnson295189b2012-06-20 16:38:30 -070013823err_unregister_pmops:
13824 hddDevTmUnregisterNotifyCallback(pHddCtx);
13825 hddDeregisterPmOps(pHddCtx);
13826
Yue Ma0d4891e2013-08-06 17:01:45 -070013827 hdd_debugfs_exit(pHddCtx);
13828
Jeff Johnson295189b2012-06-20 16:38:30 -070013829#ifdef WLAN_BTAMP_FEATURE
13830err_bap_stop:
13831 WLANBAP_Stop(pVosContext);
13832#endif
13833
13834#ifdef WLAN_BTAMP_FEATURE
13835err_bap_close:
13836 WLANBAP_Close(pVosContext);
13837#endif
13838
Jeff Johnson295189b2012-06-20 16:38:30 -070013839err_close_adapter:
13840 hdd_close_all_adapters( pHddCtx );
Mahesh A Saptasagar9ecefe42014-07-15 18:43:49 +053013841#ifdef CONFIG_ENABLE_LINUX_REG
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053013842err_unregister_wiphy:
Mahesh A Saptasagar9ecefe42014-07-15 18:43:49 +053013843#endif
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +053013844 wiphy_unregister(wiphy) ;
Agrawal Ashish33ec71e2015-11-26 20:20:58 +053013845 hdd_wlan_free_wiphy_channels(wiphy);
13846
Jeff Johnson295189b2012-06-20 16:38:30 -070013847err_vosstop:
13848 vos_stop(pVosContext);
13849
Amar Singhala49cbc52013-10-08 18:37:44 -070013850err_vosclose:
Jeff Johnson295189b2012-06-20 16:38:30 -070013851 status = vos_sched_close( pVosContext );
13852 if (!VOS_IS_STATUS_SUCCESS(status)) {
13853 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
13854 "%s: Failed to close VOSS Scheduler", __func__);
13855 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( status ) );
13856 }
Amar Singhala49cbc52013-10-08 18:37:44 -070013857 vos_close(pVosContext );
13858
Mahesh A Saptasagarc3ed0122016-01-19 16:45:11 +053013859err_nl_srv:
13860#ifdef WLAN_KD_READY_NOTIFIER
13861 nl_srv_exit(pHddCtx->ptt_pid);
13862#else
13863 nl_srv_exit();
13864#endif /* WLAN_KD_READY_NOTIFIER */
Amar Singhal0a402232013-10-11 20:57:16 -070013865err_vos_nv_close:
13866
c_hpothue6a36282014-03-19 12:27:38 +053013867#ifdef CONFIG_ENABLE_LINUX_REG
Amar Singhal0a402232013-10-11 20:57:16 -070013868 vos_nv_close();
13869
c_hpothu70f8d812014-03-22 22:59:23 +053013870#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070013871
13872err_wdclose:
13873 if(pHddCtx->cfg_ini->fIsLogpEnabled)
13874 vos_watchdog_close(pVosContext);
13875
Jeff Johnson295189b2012-06-20 16:38:30 -070013876err_config:
Hanumanth Reddy Pothula1efcd162018-03-14 14:32:27 +053013877 hdd_request_manager_deinit();
Jeff Johnson295189b2012-06-20 16:38:30 -070013878 kfree(pHddCtx->cfg_ini);
13879 pHddCtx->cfg_ini= NULL;
13880
13881err_free_hdd_context:
Sushant Kaushik83392fa2015-05-05 17:44:40 +053013882 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_DRIVER_INIT);
Siddharth Bhalcd92b782015-06-29 12:25:40 +053013883 free_riva_power_on_lock("wlan");
Jeff Johnson295189b2012-06-20 16:38:30 -070013884 wiphy_free(wiphy) ;
13885 //kfree(wdev) ;
Jeff Johnson295189b2012-06-20 16:38:30 -070013886 VOS_BUG(1);
13887
Madan Mohan Koyyalamudid57ae632012-11-06 18:42:48 -080013888 if (hdd_is_ssr_required())
13889 {
13890 /* WDI timeout had happened during load, so SSR is needed here */
13891 subsystem_restart("wcnss");
13892 msleep(5000);
13893 }
13894 hdd_set_ssr_required (VOS_FALSE);
13895
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -080013896 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -070013897
13898success:
13899 EXIT();
13900 return 0;
13901}
13902
13903/**---------------------------------------------------------------------------
13904
Jeff Johnson32d95a32012-09-10 13:15:23 -070013905 \brief hdd_driver_init() - Core Driver Init Function
Jeff Johnson295189b2012-06-20 16:38:30 -070013906
Jeff Johnson32d95a32012-09-10 13:15:23 -070013907 This is the driver entry point - called in different timeline depending
13908 on whether the driver is statically or dynamically linked
Jeff Johnson295189b2012-06-20 16:38:30 -070013909
13910 \param - None
13911
13912 \return - 0 for success, non zero for failure
13913
13914 --------------------------------------------------------------------------*/
Jeff Johnson32d95a32012-09-10 13:15:23 -070013915static int hdd_driver_init( void)
Jeff Johnson295189b2012-06-20 16:38:30 -070013916{
13917 VOS_STATUS status;
13918 v_CONTEXT_t pVosContext = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070013919 struct device *dev = NULL;
13920 int ret_status = 0;
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -070013921#ifdef HAVE_WCNSS_CAL_DOWNLOAD
13922 int max_retries = 0;
13923#endif
Siddharth Bhalc7e79b62014-10-10 22:37:38 +053013924#ifdef HAVE_CBC_DONE
13925 int max_cbc_retries = 0;
13926#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070013927
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +053013928#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
13929 wlan_logging_sock_init_svc();
13930#endif
13931
Jeff Johnson295189b2012-06-20 16:38:30 -070013932 ENTER();
13933
Sushant Kaushik83392fa2015-05-05 17:44:40 +053013934 vos_wake_lock_init(&wlan_wake_lock, "wlan");
Jeff Johnson295189b2012-06-20 16:38:30 -070013935
13936 pr_info("%s: loading driver v%s\n", WLAN_MODULE_NAME,
13937 QWLAN_VERSIONSTR TIMER_MANAGER_STR MEMORY_DEBUG_STR);
13938
Jeff Johnson295189b2012-06-20 16:38:30 -070013939#ifdef ANI_BUS_TYPE_PCI
13940
13941 dev = wcnss_wlan_get_device();
13942
13943#endif // ANI_BUS_TYPE_PCI
13944
13945#ifdef ANI_BUS_TYPE_PLATFORM
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -070013946
13947#ifdef HAVE_WCNSS_CAL_DOWNLOAD
13948 /* wait until WCNSS driver downloads NV */
Ravi Kumar Bokka7a139e62016-11-17 21:32:55 +053013949 while (!wcnss_device_ready() && 10 >= ++max_retries) {
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -070013950 msleep(1000);
13951 }
Siddharth Bhalc7e79b62014-10-10 22:37:38 +053013952
Ravi Kumar Bokka7a139e62016-11-17 21:32:55 +053013953 if (max_retries >= 10) {
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -070013954 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: WCNSS driver not ready", __func__);
Sushant Kaushik83392fa2015-05-05 17:44:40 +053013955 vos_wake_lock_destroy(&wlan_wake_lock);
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +053013956#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
13957 wlan_logging_sock_deinit_svc();
13958#endif
13959
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -070013960 return -ENODEV;
13961 }
13962#endif
13963
Siddharth Bhalc7e79b62014-10-10 22:37:38 +053013964#ifdef HAVE_CBC_DONE
13965 while (!wcnss_cbc_complete() && 10 >= ++max_cbc_retries) {
13966 msleep(1000);
13967 }
13968 if (max_cbc_retries >= 10) {
13969 hddLog(VOS_TRACE_LEVEL_FATAL, "%s:CBC not completed", __func__);
13970 }
13971#endif
13972
Jeff Johnson295189b2012-06-20 16:38:30 -070013973 dev = wcnss_wlan_get_device();
13974#endif // ANI_BUS_TYPE_PLATFORM
13975
13976
13977 do {
13978 if (NULL == dev) {
13979 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: WLAN device not found!!",__func__);
13980 ret_status = -1;
13981 break;
13982 }
13983
Jeff Johnson295189b2012-06-20 16:38:30 -070013984#ifdef TIMER_MANAGER
13985 vos_timer_manager_init();
13986#endif
13987
13988 /* Preopen VOSS so that it is ready to start at least SAL */
13989 status = vos_preOpen(&pVosContext);
13990
13991 if (!VOS_IS_STATUS_SUCCESS(status))
13992 {
13993 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Failed to preOpen VOSS", __func__);
13994 ret_status = -1;
13995 break;
13996 }
13997
Sushant Kaushik02beb352015-06-04 15:15:01 +053013998 hddTraceInit();
Padma, Santhosh Kumar9093b202015-07-21 15:37:38 +053013999 hdd_register_debug_callback();
14000
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070014001#ifndef MODULE
14002 /* For statically linked driver, call hdd_set_conparam to update curr_con_mode
14003 */
14004 hdd_set_conparam((v_UINT_t)con_mode);
14005#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070014006
14007 // Call our main init function
Jeff Johnsonbc676b42013-02-14 16:04:08 -080014008 if (hdd_wlan_startup(dev))
14009 {
Jeff Johnson295189b2012-06-20 16:38:30 -070014010 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: WLAN Driver Initialization failed",
Jeff Johnsonbc676b42013-02-14 16:04:08 -080014011 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070014012 vos_preClose( &pVosContext );
14013 ret_status = -1;
14014 break;
14015 }
14016
Jeff Johnson295189b2012-06-20 16:38:30 -070014017 } while (0);
14018
14019 if (0 != ret_status)
14020 {
Jeff Johnson295189b2012-06-20 16:38:30 -070014021#ifdef TIMER_MANAGER
14022 vos_timer_exit();
14023#endif
14024#ifdef MEMORY_DEBUG
14025 vos_mem_exit();
14026#endif
Sushant Kaushik83392fa2015-05-05 17:44:40 +053014027 vos_wake_lock_destroy(&wlan_wake_lock);
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +053014028#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
14029 wlan_logging_sock_deinit_svc();
14030#endif
14031
Jeff Johnson295189b2012-06-20 16:38:30 -070014032 pr_err("%s: driver load failure\n", WLAN_MODULE_NAME);
14033 }
14034 else
14035 {
14036 //Send WLAN UP indication to Nlink Service
14037 send_btc_nlink_msg(WLAN_MODULE_UP_IND, 0);
14038
14039 pr_info("%s: driver loaded\n", WLAN_MODULE_NAME);
Jeff Johnson295189b2012-06-20 16:38:30 -070014040 }
14041
14042 EXIT();
14043
14044 return ret_status;
14045}
14046
Jeff Johnson32d95a32012-09-10 13:15:23 -070014047/**---------------------------------------------------------------------------
14048
14049 \brief hdd_module_init() - Init Function
14050
14051 This is the driver entry point (invoked when module is loaded using insmod)
14052
14053 \param - None
14054
14055 \return - 0 for success, non zero for failure
14056
14057 --------------------------------------------------------------------------*/
14058#ifdef MODULE
14059static int __init hdd_module_init ( void)
14060{
14061 return hdd_driver_init();
14062}
Jeff Johnson32d95a32012-09-10 13:15:23 -070014063#else /* #ifdef MODULE */
14064static int __init hdd_module_init ( void)
14065{
14066 /* Driver initialization is delayed to fwpath_changed_handler */
14067 return 0;
14068}
Jeff Johnson32d95a32012-09-10 13:15:23 -070014069#endif /* #ifdef MODULE */
14070
Jeff Johnson295189b2012-06-20 16:38:30 -070014071
14072/**---------------------------------------------------------------------------
14073
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070014074 \brief hdd_driver_exit() - Exit function
Jeff Johnson295189b2012-06-20 16:38:30 -070014075
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070014076 This is the driver exit point (invoked when module is unloaded using rmmod
14077 or con_mode was changed by userspace)
Jeff Johnson295189b2012-06-20 16:38:30 -070014078
14079 \param - None
14080
14081 \return - None
14082
14083 --------------------------------------------------------------------------*/
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070014084static void hdd_driver_exit(void)
Jeff Johnson295189b2012-06-20 16:38:30 -070014085{
14086 hdd_context_t *pHddCtx = NULL;
14087 v_CONTEXT_t pVosContext = NULL;
Agarwal Ashish5e414792014-06-08 15:25:23 +053014088 v_REGDOMAIN_t regId;
Arun Kumar Khandavallie0b046d2014-03-01 21:54:25 +053014089 unsigned long rc = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070014090
14091 pr_info("%s: unloading driver v%s\n", WLAN_MODULE_NAME, QWLAN_VERSIONSTR);
14092
14093 //Get the global vos context
14094 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
14095
14096 if(!pVosContext)
14097 {
14098 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Global VOS context is Null", __func__);
14099 goto done;
14100 }
14101
14102 //Get the HDD context.
14103 pHddCtx = (hdd_context_t *)vos_get_context(VOS_MODULE_ID_HDD, pVosContext );
14104
14105 if(!pHddCtx)
14106 {
14107 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: module exit called before probe",__func__);
14108 }
Katya Nigame7b69a82015-04-28 15:24:06 +053014109 else if (VOS_MONITOR_MODE == hdd_get_conparam())
14110 {
14111 hddLog(VOS_TRACE_LEVEL_INFO,"%s: MONITOR MODE",__func__);
14112 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_UNLOAD_IN_PROGRESS;
14113 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, TRUE);
14114 hdd_wlan_exit(pHddCtx);
14115 vos_preClose( &pVosContext );
14116 goto done;
14117 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014118 else
14119 {
Siddharth Bhal2e5871b2015-03-24 16:20:51 +053014120 /* We wait for active entry threads to exit from driver
14121 * by waiting until rtnl_lock is available.
14122 */
14123 rtnl_lock();
14124 rtnl_unlock();
14125
Siddharth Bhal3c29dca2015-02-19 00:41:40 +053014126 INIT_COMPLETION(pHddCtx->ssr_comp_var);
14127 if ((pHddCtx->isLogpInProgress) && (FALSE ==
14128 vos_is_wlan_in_badState(VOS_MODULE_ID_HDD, NULL)))
14129 {
Siddharth Bhala204f572015-01-17 02:03:36 +053014130 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Siddharth Bhal3c29dca2015-02-19 00:41:40 +053014131 "%s:SSR in Progress; block rmmod !!!", __func__);
Siddharth Bhala204f572015-01-17 02:03:36 +053014132 rc = wait_for_completion_timeout(&pHddCtx->ssr_comp_var,
14133 msecs_to_jiffies(30000));
14134 if(!rc)
14135 {
14136 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
14137 "%s:SSR timedout, fatal error", __func__);
14138 VOS_BUG(0);
14139 }
14140 }
14141
Siddharth Bhal3c29dca2015-02-19 00:41:40 +053014142 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_UNLOAD_IN_PROGRESS;
14143 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, TRUE);
Jeff Johnson295189b2012-06-20 16:38:30 -070014144
c_hpothu8adb97b2014-12-08 19:38:20 +053014145 /* Driver Need to send country code 00 in below condition
14146 * 1) If gCountryCodePriority is set to 1; and last country
14147 * code set is through 11d. This needs to be done in case
14148 * when NV country code is 00.
14149 * This Needs to be done as when kernel store last country
14150 * code and if stored country code is not through 11d,
14151 * in sme_HandleChangeCountryCodeByUser we will disable 11d
14152 * in next load/unload as soon as we get any country through
14153 * 11d. In sme_HandleChangeCountryCodeByUser
14154 * pMsg->countryCode will be last countryCode and
14155 * pMac->scan.countryCode11d will be country through 11d so
14156 * due to mismatch driver will disable 11d.
14157 *
14158 */
Agarwal Ashish8db39882014-07-30 21:56:07 +053014159
c_hpothu8adb97b2014-12-08 19:38:20 +053014160 if ((eANI_BOOLEAN_TRUE == sme_Is11dCountrycode(pHddCtx->hHal) &&
Agarwal Ashish8dcd2862014-07-25 11:58:52 +053014161 pHddCtx->cfg_ini->fSupplicantCountryCodeHasPriority &&
Abhishek Singh2a705962014-10-30 14:47:28 +053014162 sme_Is11dSupported(pHddCtx->hHal)))
c_hpothu8adb97b2014-12-08 19:38:20 +053014163 {
14164 hddLog(VOS_TRACE_LEVEL_INFO,
Agarwal Ashish8dcd2862014-07-25 11:58:52 +053014165 FL("CountryCode 00 is being set while unloading driver"));
c_hpothu8adb97b2014-12-08 19:38:20 +053014166 vos_nv_getRegDomainFromCountryCode(&regId , "00", COUNTRY_USER);
14167 }
Agarwal Ashish5e414792014-06-08 15:25:23 +053014168
c_hpothu8adb97b2014-12-08 19:38:20 +053014169 //Do all the cleanup before deregistering the driver
14170 hdd_wlan_exit(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -070014171 }
14172
Jeff Johnson295189b2012-06-20 16:38:30 -070014173 vos_preClose( &pVosContext );
14174
14175#ifdef TIMER_MANAGER
14176 vos_timer_exit();
14177#endif
14178#ifdef MEMORY_DEBUG
14179 vos_mem_exit();
14180#endif
14181
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +053014182#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
14183 wlan_logging_sock_deinit_svc();
14184#endif
14185
Jeff Johnson295189b2012-06-20 16:38:30 -070014186done:
Sushant Kaushik83392fa2015-05-05 17:44:40 +053014187 vos_wake_lock_destroy(&wlan_wake_lock);
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +053014188
Jeff Johnson295189b2012-06-20 16:38:30 -070014189 pr_info("%s: driver unloaded\n", WLAN_MODULE_NAME);
14190}
14191
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070014192/**---------------------------------------------------------------------------
14193
14194 \brief hdd_module_exit() - Exit function
14195
14196 This is the driver exit point (invoked when module is unloaded using rmmod)
14197
14198 \param - None
14199
14200 \return - None
14201
14202 --------------------------------------------------------------------------*/
14203static void __exit hdd_module_exit(void)
14204{
14205 hdd_driver_exit();
14206}
14207
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070014208#ifdef MODULE
14209static int fwpath_changed_handler(const char *kmessage,
Ashish Kumar Dhanotiyafb3fd972018-04-30 12:46:52 +053014210 const struct kernel_param *kp)
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070014211{
Jeff Johnson76052702013-04-16 13:55:05 -070014212 return param_set_copystring(kmessage, kp);
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070014213}
14214
14215static int con_mode_handler(const char *kmessage,
Ashish Kumar Dhanotiyafb3fd972018-04-30 12:46:52 +053014216 const struct kernel_param *kp)
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070014217{
Madan Mohan Koyyalamudif2f8d8b2012-10-11 17:06:59 -070014218 return param_set_int(kmessage, kp);
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070014219}
14220#else /* #ifdef MODULE */
14221/**---------------------------------------------------------------------------
14222
Jeff Johnson76052702013-04-16 13:55:05 -070014223 \brief kickstart_driver
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070014224
Jeff Johnson76052702013-04-16 13:55:05 -070014225 This is the driver entry point
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070014226 - delayed driver initialization when driver is statically linked
Jeff Johnson76052702013-04-16 13:55:05 -070014227 - invoked when module parameter fwpath is modified from userspace to signal
14228 initializing the WLAN driver or when con_mode is modified from userspace
14229 to signal a switch in operating mode
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070014230
14231 \return - 0 for success, non zero for failure
14232
14233 --------------------------------------------------------------------------*/
Jeff Johnson76052702013-04-16 13:55:05 -070014234static int kickstart_driver(void)
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070014235{
Madan Mohan Koyyalamudi62e60052012-10-05 14:27:22 -070014236 int ret_status;
14237
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070014238 if (!wlan_hdd_inited) {
Madan Mohan Koyyalamudi62e60052012-10-05 14:27:22 -070014239 ret_status = hdd_driver_init();
14240 wlan_hdd_inited = ret_status ? 0 : 1;
14241 return ret_status;
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070014242 }
14243
14244 hdd_driver_exit();
Jeff Johnson76052702013-04-16 13:55:05 -070014245
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070014246 msleep(200);
Jeff Johnson76052702013-04-16 13:55:05 -070014247
Madan Mohan Koyyalamudi62e60052012-10-05 14:27:22 -070014248 ret_status = hdd_driver_init();
14249 wlan_hdd_inited = ret_status ? 0 : 1;
14250 return ret_status;
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070014251}
14252
Jeff Johnson295189b2012-06-20 16:38:30 -070014253/**---------------------------------------------------------------------------
14254
Jeff Johnson76052702013-04-16 13:55:05 -070014255 \brief fwpath_changed_handler() - Handler Function
14256
14257 Handle changes to the fwpath parameter
14258
14259 \return - 0 for success, non zero for failure
14260
14261 --------------------------------------------------------------------------*/
14262static int fwpath_changed_handler(const char *kmessage,
Ashish Kumar Dhanotiyafb3fd972018-04-30 12:46:52 +053014263 const struct kernel_param *kp)
Jeff Johnson76052702013-04-16 13:55:05 -070014264{
14265 int ret;
14266
14267 ret = param_set_copystring(kmessage, kp);
14268 if (0 == ret)
14269 ret = kickstart_driver();
14270 return ret;
14271}
14272
14273/**---------------------------------------------------------------------------
14274
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070014275 \brief con_mode_handler() -
14276
14277 Handler function for module param con_mode when it is changed by userspace
14278 Dynamically linked - do nothing
14279 Statically linked - exit and init driver, as in rmmod and insmod
14280
Jeff Johnson76052702013-04-16 13:55:05 -070014281 \param -
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070014282
Jeff Johnson76052702013-04-16 13:55:05 -070014283 \return -
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070014284
14285 --------------------------------------------------------------------------*/
Ashish Kumar Dhanotiyafb3fd972018-04-30 12:46:52 +053014286static int con_mode_handler(const char *kmessage,
14287 const struct kernel_param *kp)
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070014288{
Jeff Johnson76052702013-04-16 13:55:05 -070014289 int ret;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070014290
Jeff Johnson76052702013-04-16 13:55:05 -070014291 ret = param_set_int(kmessage, kp);
14292 if (0 == ret)
14293 ret = kickstart_driver();
14294 return ret;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070014295}
14296#endif /* #ifdef MODULE */
14297
14298/**---------------------------------------------------------------------------
14299
Jeff Johnson295189b2012-06-20 16:38:30 -070014300 \brief hdd_get_conparam() -
14301
14302 This is the driver exit point (invoked when module is unloaded using rmmod)
14303
14304 \param - None
14305
14306 \return - tVOS_CON_MODE
14307
14308 --------------------------------------------------------------------------*/
14309tVOS_CON_MODE hdd_get_conparam ( void )
14310{
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070014311#ifdef MODULE
Jeff Johnson295189b2012-06-20 16:38:30 -070014312 return (tVOS_CON_MODE)con_mode;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070014313#else
14314 return (tVOS_CON_MODE)curr_con_mode;
14315#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070014316}
14317void hdd_set_conparam ( v_UINT_t newParam )
14318{
14319 con_mode = newParam;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070014320#ifndef MODULE
14321 curr_con_mode = con_mode;
14322#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070014323}
14324/**---------------------------------------------------------------------------
14325
14326 \brief hdd_softap_sta_deauth() - function
14327
14328 This to take counter measure to handle deauth req from HDD
14329
14330 \param - pAdapter - Pointer to the HDD
14331
14332 \param - enable - boolean value
14333
14334 \return - None
14335
14336 --------------------------------------------------------------------------*/
14337
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053014338VOS_STATUS hdd_softap_sta_deauth(hdd_adapter_t *pAdapter,
14339 struct tagCsrDelStaParams *pDelStaParams)
Jeff Johnson295189b2012-06-20 16:38:30 -070014340{
Jeff Johnson295189b2012-06-20 16:38:30 -070014341 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080014342 VOS_STATUS vosStatus = VOS_STATUS_E_FAULT;
Hanumanth Reddy Pothula57323632017-12-06 17:55:09 +053014343 struct hdd_cache_sta_info *cache_sta_info;
14344 ptSapContext pSapCtx = VOS_GET_SAP_CB(pVosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -070014345
14346 ENTER();
14347
Jeff Johnsonc135a9a2017-09-19 08:37:24 -070014348 hddLog(LOG1, "hdd_softap_sta_deauth:(%pK, false)",
Rajesh Chauhan18488fc2013-08-22 10:15:03 -070014349 (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -070014350
Hanumanth Reddy Pothula57323632017-12-06 17:55:09 +053014351 if (!pSapCtx) {
14352 hddLog(LOGE, "sap context is NULL");
14353 return vosStatus;
14354 }
14355
14356 cache_sta_info = hdd_get_cache_stainfo(pSapCtx->cache_sta_info,
14357 pDelStaParams->peerMacAddr);
14358 if (cache_sta_info) {
14359 cache_sta_info->reason_code = pDelStaParams->reason_code;
14360 cache_sta_info->rx_rate =
14361 wlan_tl_get_sta_rx_rate(pVosContext, cache_sta_info->ucSTAId);
14362 WLANTL_GetSAPStaRSSi(pVosContext, cache_sta_info->ucSTAId,
14363 &cache_sta_info->rssi);
14364 }
14365
Jeff Johnson295189b2012-06-20 16:38:30 -070014366 //Ignore request to deauth bcmc station
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053014367 if (pDelStaParams->peerMacAddr[0] & 0x1)
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080014368 return vosStatus;
Jeff Johnson295189b2012-06-20 16:38:30 -070014369
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053014370 vosStatus = WLANSAP_DeauthSta(pVosContext, pDelStaParams);
Jeff Johnson295189b2012-06-20 16:38:30 -070014371
14372 EXIT();
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080014373 return vosStatus;
Jeff Johnson295189b2012-06-20 16:38:30 -070014374}
14375
14376/**---------------------------------------------------------------------------
14377
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +053014378 \brief hdd_del_all_sta() - function
14379
14380 This function removes all the stations associated on stopping AP/P2P GO.
14381
14382 \param - pAdapter - Pointer to the HDD
14383
14384 \return - None
14385
14386 --------------------------------------------------------------------------*/
14387
14388int hdd_del_all_sta(hdd_adapter_t *pAdapter)
14389{
14390 v_U16_t i;
14391 VOS_STATUS vos_status;
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053014392 v_CONTEXT_t pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
14393 ptSapContext pSapCtx = NULL;
14394 pSapCtx = VOS_GET_SAP_CB(pVosContext);
14395 if(pSapCtx == NULL){
14396 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14397 FL("psapCtx is NULL"));
14398 return 1;
14399 }
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +053014400 ENTER();
14401
14402 hddLog(VOS_TRACE_LEVEL_INFO,
14403 "%s: Delete all STAs associated.",__func__);
14404 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
14405 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
14406 )
14407 {
14408 for(i = 0; i < WLAN_MAX_STA_COUNT; i++)
14409 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053014410 if ((pSapCtx->aStaInfo[i].isUsed) &&
14411 (!pSapCtx->aStaInfo[i].isDeauthInProgress))
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +053014412 {
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053014413 struct tagCsrDelStaParams delStaParams;
14414
14415 WLANSAP_PopulateDelStaParams(
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053014416 pSapCtx->aStaInfo[i].macAddrSTA.bytes,
Sushant Kaushik4cd28f62014-12-26 14:23:50 +053014417 eSIR_MAC_DEAUTH_LEAVING_BSS_REASON,
14418 SIR_MAC_MGMT_DEAUTH >> 4,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053014419 &delStaParams);
14420 vos_status = hdd_softap_sta_deauth(pAdapter, &delStaParams);
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +053014421 if (VOS_IS_STATUS_SUCCESS(vos_status))
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053014422 pSapCtx->aStaInfo[i].isDeauthInProgress = TRUE;
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +053014423 }
14424 }
14425 }
14426
14427 EXIT();
14428 return 0;
14429}
14430
14431/**---------------------------------------------------------------------------
14432
Jeff Johnson295189b2012-06-20 16:38:30 -070014433 \brief hdd_softap_sta_disassoc() - function
14434
14435 This to take counter measure to handle deauth req from HDD
14436
14437 \param - pAdapter - Pointer to the HDD
14438
14439 \param - enable - boolean value
14440
14441 \return - None
14442
14443 --------------------------------------------------------------------------*/
14444
14445void hdd_softap_sta_disassoc(hdd_adapter_t *pAdapter,v_U8_t *pDestMacAddress)
14446{
Hanumanth Reddy Pothula57323632017-12-06 17:55:09 +053014447 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
14448 struct hdd_cache_sta_info *cache_sta_info;
14449 ptSapContext pSapCtx = VOS_GET_SAP_CB(pVosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -070014450
14451 ENTER();
14452
Jeff Johnsonc135a9a2017-09-19 08:37:24 -070014453 hddLog( LOGE, "hdd_softap_sta_disassoc:(%pK, false)", (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -070014454
Hanumanth Reddy Pothula57323632017-12-06 17:55:09 +053014455 if (!pSapCtx) {
14456 hddLog(LOGE, "sap context is NULL");
14457 return ;
14458 }
14459
Jeff Johnson295189b2012-06-20 16:38:30 -070014460 //Ignore request to disassoc bcmc station
14461 if( pDestMacAddress[0] & 0x1 )
14462 return;
14463
Hanumanth Reddy Pothula57323632017-12-06 17:55:09 +053014464 cache_sta_info = hdd_get_cache_stainfo(pSapCtx->cache_sta_info,
14465 pDestMacAddress);
14466 if (cache_sta_info) {
14467 cache_sta_info->reason_code = eSIR_MAC_DEAUTH_LEAVING_BSS_REASON;
14468 cache_sta_info->rx_rate =
14469 wlan_tl_get_sta_rx_rate(pVosContext, cache_sta_info->ucSTAId);
14470 WLANTL_GetSAPStaRSSi(pVosContext, cache_sta_info->ucSTAId,
14471 &cache_sta_info->rssi);
14472 }
14473
Jeff Johnson295189b2012-06-20 16:38:30 -070014474 WLANSAP_DisassocSta(pVosContext,pDestMacAddress);
14475}
14476
14477void hdd_softap_tkip_mic_fail_counter_measure(hdd_adapter_t *pAdapter,v_BOOL_t enable)
14478{
14479 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
14480
14481 ENTER();
14482
Jeff Johnsonc135a9a2017-09-19 08:37:24 -070014483 hddLog( LOGE, "hdd_softap_tkip_mic_fail_counter_measure:(%pK, false)", (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -070014484
14485 WLANSAP_SetCounterMeasure(pVosContext, (v_BOOL_t)enable);
14486}
14487
Jeff Johnson295189b2012-06-20 16:38:30 -070014488/**---------------------------------------------------------------------------
14489 *
14490 * \brief hdd_get__concurrency_mode() -
14491 *
14492 *
14493 * \param - None
14494 *
14495 * \return - CONCURRENCY MODE
14496 *
14497 * --------------------------------------------------------------------------*/
14498tVOS_CONCURRENCY_MODE hdd_get_concurrency_mode ( void )
14499{
14500 v_CONTEXT_t pVosContext = vos_get_global_context( VOS_MODULE_ID_HDD, NULL );
14501 hdd_context_t *pHddCtx;
14502
14503 if (NULL != pVosContext)
14504 {
14505 pHddCtx = vos_get_context( VOS_MODULE_ID_HDD, pVosContext);
14506 if (NULL != pHddCtx)
14507 {
14508 return (tVOS_CONCURRENCY_MODE)pHddCtx->concurrency_mode;
14509 }
14510 }
14511
14512 /* we are in an invalid state :( */
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070014513 hddLog(LOGE, "%s: Invalid context", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070014514 return VOS_STA;
14515}
Sushant Kaushikabb7ee62014-07-18 16:20:12 +053014516v_BOOL_t
14517wlan_hdd_is_GO_power_collapse_allowed (hdd_context_t* pHddCtx)
14518{
14519 hdd_adapter_t *pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070014520
Sushant Kaushikabb7ee62014-07-18 16:20:12 +053014521 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_GO);
14522 if (pAdapter == NULL)
14523 {
14524 hddLog(VOS_TRACE_LEVEL_INFO,
14525 FL("GO doesn't exist"));
14526 return TRUE;
14527 }
14528 if (test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
14529 {
14530 hddLog(VOS_TRACE_LEVEL_INFO,
14531 FL("GO started"));
14532 return TRUE;
14533 }
14534 else
14535 /* wait till GO changes its interface to p2p device */
14536 hddLog(VOS_TRACE_LEVEL_INFO,
14537 FL("Del_bss called, avoid apps suspend"));
14538 return FALSE;
14539
14540}
Jeff Johnson295189b2012-06-20 16:38:30 -070014541/* Decide whether to allow/not the apps power collapse.
14542 * Allow apps power collapse if we are in connected state.
14543 * if not, allow only if we are in IMPS */
14544v_BOOL_t hdd_is_apps_power_collapse_allowed(hdd_context_t* pHddCtx)
14545{
14546 tPmcState pmcState = pmcGetPmcState(pHddCtx->hHal);
Srikant Kuppafef66a72013-01-30 17:32:44 -080014547 tANI_BOOLEAN scanRspPending = csrNeighborRoamScanRspPending(pHddCtx->hHal);
Srinivas Girigowdaa553c462013-03-07 19:42:52 -080014548 tANI_BOOLEAN inMiddleOfRoaming = csrNeighborMiddleOfRoaming(pHddCtx->hHal);
Jeff Johnson295189b2012-06-20 16:38:30 -070014549 hdd_config_t *pConfig = pHddCtx->cfg_ini;
14550 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
14551 hdd_adapter_t *pAdapter = NULL;
14552 VOS_STATUS status;
Yathish9f22e662012-12-10 14:21:35 -080014553 tVOS_CONCURRENCY_MODE concurrent_state = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070014554
Jeff Johnson295189b2012-06-20 16:38:30 -070014555 if (VOS_STA_SAP_MODE == hdd_get_conparam())
14556 return TRUE;
Jeff Johnson295189b2012-06-20 16:38:30 -070014557
Yathish9f22e662012-12-10 14:21:35 -080014558 concurrent_state = hdd_get_concurrency_mode();
14559
Sushant Kaushikabb7ee62014-07-18 16:20:12 +053014560 if ((concurrent_state == (VOS_STA | VOS_P2P_GO)) &&
14561 !(wlan_hdd_is_GO_power_collapse_allowed(pHddCtx)))
14562 return FALSE;
Yathish9f22e662012-12-10 14:21:35 -080014563#ifdef WLAN_ACTIVEMODE_OFFLOAD_FEATURE
Sushant Kaushikabb7ee62014-07-18 16:20:12 +053014564
Yathish9f22e662012-12-10 14:21:35 -080014565 if(((concurrent_state == (VOS_STA | VOS_P2P_CLIENT)) ||
Sushant Kaushikabb7ee62014-07-18 16:20:12 +053014566 (concurrent_state == (VOS_STA | VOS_P2P_GO)))&&
Yathish9f22e662012-12-10 14:21:35 -080014567 (IS_ACTIVEMODE_OFFLOAD_FEATURE_ENABLE))
14568 return TRUE;
14569#endif
14570
Jeff Johnson295189b2012-06-20 16:38:30 -070014571 /*loop through all adapters. TBD fix for Concurrency */
14572 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
14573 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
14574 {
14575 pAdapter = pAdapterNode->pAdapter;
14576 if ( (WLAN_HDD_INFRA_STATION == pAdapter->device_mode)
14577 || (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
14578 {
Srikant Kuppafef66a72013-01-30 17:32:44 -080014579 if (((pConfig->fIsImpsEnabled || pConfig->fIsBmpsEnabled)
c_hpothu4e8faac2014-05-16 17:38:44 +053014580 && (pmcState != IMPS && pmcState != BMPS && pmcState != UAPSD
c_hpothu1c6957d2015-01-06 18:19:47 +053014581 && pmcState != STOPPED && pmcState != STANDBY &&
14582 pmcState != WOWL)) ||
Srinivas Girigowdaa553c462013-03-07 19:42:52 -080014583 (eANI_BOOLEAN_TRUE == scanRspPending) ||
14584 (eANI_BOOLEAN_TRUE == inMiddleOfRoaming))
Jeff Johnson295189b2012-06-20 16:38:30 -070014585 {
Mukul Sharma4be88422015-03-09 20:29:07 +053014586 if(pmcState == FULL_POWER &&
14587 sme_IsCoexScoIndicationSet(pHddCtx->hHal))
14588 {
14589 /*
14590 * When SCO indication comes from Coex module , host will
14591 * enter in to full power mode, but this should not prevent
14592 * apps processor power collapse.
14593 */
14594 hddLog(LOG1,
14595 FL("Allow apps power collapse"
14596 "even when sco indication is set"));
14597 return TRUE;
14598 }
Srikant Kuppafef66a72013-01-30 17:32:44 -080014599 hddLog( LOGE, "%s: do not allow APPS power collapse-"
Deepthi Gowri03a979f2016-11-03 15:20:19 +053014600 "pmcState = %d scanRspPending = %d "
14601 "inMiddleOfRoaming = %d connected = %d",
14602 __func__, pmcState, scanRspPending,
14603 inMiddleOfRoaming, hdd_connIsConnected(
14604 WLAN_HDD_GET_STATION_CTX_PTR( pAdapter )));
14605 wlan_hdd_get_tdls_stats(pAdapter);
14606 return FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070014607 }
14608 }
14609 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
14610 pAdapterNode = pNext;
14611 }
14612 return TRUE;
14613}
14614
Madan Mohan Koyyalamudic72a4d62012-11-08 14:59:34 -080014615/* Decides whether to send suspend notification to Riva
14616 * if any adapter is in BMPS; then it is required */
14617v_BOOL_t hdd_is_suspend_notify_allowed(hdd_context_t* pHddCtx)
14618{
14619 tPmcState pmcState = pmcGetPmcState(pHddCtx->hHal);
14620 hdd_config_t *pConfig = pHddCtx->cfg_ini;
14621
14622 if (pConfig->fIsBmpsEnabled && (pmcState == BMPS))
14623 {
14624 return TRUE;
14625 }
14626 return FALSE;
14627}
14628
Jeff Johnson295189b2012-06-20 16:38:30 -070014629void wlan_hdd_set_concurrency_mode(hdd_context_t *pHddCtx, tVOS_CON_MODE mode)
14630{
14631 switch(mode)
14632 {
Chilam Ngc4244af2013-04-01 15:37:32 -070014633 case VOS_STA_MODE:
14634 case VOS_P2P_CLIENT_MODE:
14635 case VOS_P2P_GO_MODE:
14636 case VOS_STA_SAP_MODE:
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +053014637 case VOS_MONITOR_MODE:
Jeff Johnsone7245742012-09-05 17:12:55 -070014638 pHddCtx->concurrency_mode |= (1 << mode);
Agarwal Ashish51325b52014-06-16 16:50:49 +053014639 pHddCtx->no_of_open_sessions[mode]++;
Jeff Johnson295189b2012-06-20 16:38:30 -070014640 break;
14641 default:
14642 break;
Jeff Johnson295189b2012-06-20 16:38:30 -070014643 }
Agarwal Ashish51325b52014-06-16 16:50:49 +053014644 hddLog(VOS_TRACE_LEVEL_INFO, FL("concurrency_mode = 0x%x "
14645 "Number of open sessions for mode %d = %d"),
14646 pHddCtx->concurrency_mode, mode,
14647 pHddCtx->no_of_open_sessions[mode]);
Jeff Johnson295189b2012-06-20 16:38:30 -070014648}
14649
14650
14651void wlan_hdd_clear_concurrency_mode(hdd_context_t *pHddCtx, tVOS_CON_MODE mode)
14652{
14653 switch(mode)
14654 {
Chilam Ngc4244af2013-04-01 15:37:32 -070014655 case VOS_STA_MODE:
14656 case VOS_P2P_CLIENT_MODE:
14657 case VOS_P2P_GO_MODE:
14658 case VOS_STA_SAP_MODE:
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +053014659 case VOS_MONITOR_MODE:
Agarwal Ashish51325b52014-06-16 16:50:49 +053014660 pHddCtx->no_of_open_sessions[mode]--;
14661 if (!(pHddCtx->no_of_open_sessions[mode]))
14662 pHddCtx->concurrency_mode &= (~(1 << mode));
Jeff Johnson295189b2012-06-20 16:38:30 -070014663 break;
14664 default:
14665 break;
14666 }
Agarwal Ashish51325b52014-06-16 16:50:49 +053014667 hddLog(VOS_TRACE_LEVEL_INFO, FL("concurrency_mode = 0x%x "
14668 "Number of open sessions for mode %d = %d"),
14669 pHddCtx->concurrency_mode, mode, pHddCtx->no_of_open_sessions[mode]);
14670
14671}
14672/**---------------------------------------------------------------------------
14673 *
14674 * \brief wlan_hdd_incr_active_session()
14675 *
14676 * This function increments the number of active sessions
14677 * maintained per device mode
14678 * Incase of STA/P2P CLI/IBSS upon connection indication it is incremented
14679 * Incase of SAP/P2P GO upon bss start it is incremented
14680 *
14681 * \param pHddCtx - HDD Context
14682 * \param mode - device mode
14683 *
14684 * \return - None
14685 *
14686 * --------------------------------------------------------------------------*/
14687void wlan_hdd_incr_active_session(hdd_context_t *pHddCtx, tVOS_CON_MODE mode)
14688{
14689 switch (mode) {
14690 case VOS_STA_MODE:
14691 case VOS_P2P_CLIENT_MODE:
14692 case VOS_P2P_GO_MODE:
14693 case VOS_STA_SAP_MODE:
14694 pHddCtx->no_of_active_sessions[mode]++;
14695 break;
14696 default:
14697 hddLog(VOS_TRACE_LEVEL_INFO, FL("Not Expected Mode %d"), mode);
14698 break;
14699 }
14700 hddLog(VOS_TRACE_LEVEL_INFO, FL("No.# of active sessions for mode %d = %d"),
14701 mode,
14702 pHddCtx->no_of_active_sessions[mode]);
14703}
14704
14705/**---------------------------------------------------------------------------
14706 *
14707 * \brief wlan_hdd_decr_active_session()
14708 *
14709 * This function decrements the number of active sessions
14710 * maintained per device mode
14711 * Incase of STA/P2P CLI/IBSS upon disconnection it is decremented
14712 * Incase of SAP/P2P GO upon bss stop it is decremented
14713 *
14714 * \param pHddCtx - HDD Context
14715 * \param mode - device mode
14716 *
14717 * \return - None
14718 *
14719 * --------------------------------------------------------------------------*/
14720void wlan_hdd_decr_active_session(hdd_context_t *pHddCtx, tVOS_CON_MODE mode)
14721{
Bhargav Shahd0715912015-10-01 18:17:37 +053014722
Agarwal Ashish51325b52014-06-16 16:50:49 +053014723 switch (mode) {
14724 case VOS_STA_MODE:
14725 case VOS_P2P_CLIENT_MODE:
14726 case VOS_P2P_GO_MODE:
14727 case VOS_STA_SAP_MODE:
Agarwal Ashish5325f522014-08-06 00:58:44 +053014728 if (pHddCtx->no_of_active_sessions[mode] > 0)
14729 pHddCtx->no_of_active_sessions[mode]--;
14730 else
14731 hddLog(VOS_TRACE_LEVEL_INFO, FL(" No.# of Active sessions"
14732 "is already Zero"));
Agarwal Ashish51325b52014-06-16 16:50:49 +053014733 break;
14734 default:
14735 hddLog(VOS_TRACE_LEVEL_INFO, FL("Not Expected Mode %d"), mode);
14736 break;
14737 }
14738 hddLog(VOS_TRACE_LEVEL_INFO, FL("No.# of active sessions for mode %d = %d"),
14739 mode,
14740 pHddCtx->no_of_active_sessions[mode]);
Jeff Johnson295189b2012-06-20 16:38:30 -070014741}
14742
Jeff Johnsone7245742012-09-05 17:12:55 -070014743/**---------------------------------------------------------------------------
14744 *
14745 * \brief wlan_hdd_restart_init
14746 *
14747 * This function initalizes restart timer/flag. An internal function.
14748 *
14749 * \param - pHddCtx
14750 *
14751 * \return - None
14752 *
14753 * --------------------------------------------------------------------------*/
14754
14755static void wlan_hdd_restart_init(hdd_context_t *pHddCtx)
14756{
14757 /* Initialize */
14758 pHddCtx->hdd_restart_retries = 0;
14759 atomic_set(&pHddCtx->isRestartInProgress, 0);
14760 vos_timer_init(&pHddCtx->hdd_restart_timer,
14761 VOS_TIMER_TYPE_SW,
14762 wlan_hdd_restart_timer_cb,
14763 pHddCtx);
14764}
14765/**---------------------------------------------------------------------------
14766 *
14767 * \brief wlan_hdd_restart_deinit
14768 *
14769 * This function cleans up the resources used. An internal function.
14770 *
14771 * \param - pHddCtx
14772 *
14773 * \return - None
14774 *
14775 * --------------------------------------------------------------------------*/
14776
14777static void wlan_hdd_restart_deinit(hdd_context_t* pHddCtx)
14778{
14779
14780 VOS_STATUS vos_status;
14781 /* Block any further calls */
14782 atomic_set(&pHddCtx->isRestartInProgress, 1);
14783 /* Cleanup */
14784 vos_status = vos_timer_stop( &pHddCtx->hdd_restart_timer );
14785 if (!VOS_IS_STATUS_SUCCESS(vos_status))
c_hpothu6ff1c3c2013-10-01 19:01:57 +053014786 hddLog(LOGE, FL("Failed to stop HDD restart timer"));
Jeff Johnsone7245742012-09-05 17:12:55 -070014787 vos_status = vos_timer_destroy(&pHddCtx->hdd_restart_timer);
14788 if (!VOS_IS_STATUS_SUCCESS(vos_status))
c_hpothu6ff1c3c2013-10-01 19:01:57 +053014789 hddLog(LOGE, FL("Failed to destroy HDD restart timer"));
Jeff Johnsone7245742012-09-05 17:12:55 -070014790
14791}
14792
14793/**---------------------------------------------------------------------------
14794 *
14795 * \brief wlan_hdd_framework_restart
14796 *
14797 * This function uses a cfg80211 API to start a framework initiated WLAN
14798 * driver module unload/load.
14799 *
14800 * Also this API keep retrying (WLAN_HDD_RESTART_RETRY_MAX_CNT).
14801 *
14802 *
14803 * \param - pHddCtx
14804 *
14805 * \return - VOS_STATUS_SUCCESS: Success
14806 * VOS_STATUS_E_EMPTY: Adapter is Empty
14807 * VOS_STATUS_E_NOMEM: No memory
14808
14809 * --------------------------------------------------------------------------*/
14810
14811static VOS_STATUS wlan_hdd_framework_restart(hdd_context_t *pHddCtx)
14812{
14813 VOS_STATUS status = VOS_STATUS_SUCCESS;
14814 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
Madan Mohan Koyyalamudifc19e442013-05-09 18:24:08 -070014815 int len = (sizeof (struct ieee80211_mgmt));
14816 struct ieee80211_mgmt *mgmt = NULL;
14817
14818 /* Prepare the DEAUTH managment frame with reason code */
14819 mgmt = kzalloc(len, GFP_KERNEL);
14820 if(mgmt == NULL)
14821 {
14822 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
14823 "%s: memory allocation failed (%d bytes)", __func__, len);
14824 return VOS_STATUS_E_NOMEM;
14825 }
14826 mgmt->u.deauth.reason_code = WLAN_REASON_DISASSOC_LOW_ACK;
Jeff Johnsone7245742012-09-05 17:12:55 -070014827
14828 /* Iterate over all adapters/devices */
14829 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
Hanumantha Reddy Pothulada0fe362015-02-27 18:37:03 +053014830 if ((NULL == pAdapterNode) || (VOS_STATUS_SUCCESS != status))
14831 {
14832 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnsonc135a9a2017-09-19 08:37:24 -070014833 FL("fail to get adapter: %pK %d"), pAdapterNode, status);
Hanumantha Reddy Pothulada0fe362015-02-27 18:37:03 +053014834 goto end;
14835 }
14836
Jeff Johnsone7245742012-09-05 17:12:55 -070014837 do
14838 {
Hanumantha Reddy Pothulada0fe362015-02-27 18:37:03 +053014839 if(pAdapterNode->pAdapter &&
14840 WLAN_HDD_ADAPTER_MAGIC == pAdapterNode->pAdapter->magic)
Jeff Johnsone7245742012-09-05 17:12:55 -070014841 {
14842 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
14843 "restarting the driver(intf:\'%s\' mode:%d :try %d)",
14844 pAdapterNode->pAdapter->dev->name,
14845 pAdapterNode->pAdapter->device_mode,
14846 pHddCtx->hdd_restart_retries + 1);
Madan Mohan Koyyalamudifc19e442013-05-09 18:24:08 -070014847 /*
14848 * CFG80211 event to restart the driver
14849 *
14850 * 'cfg80211_send_unprot_deauth' sends a
14851 * NL80211_CMD_UNPROT_DEAUTHENTICATE event to supplicant at any state
14852 * of SME(Linux Kernel) state machine.
14853 *
14854 * Reason code WLAN_REASON_DISASSOC_LOW_ACK is currently used to restart
14855 * the driver.
14856 *
14857 */
Abhishek Singh00b71972016-01-07 10:51:04 +053014858
Anand N Sunkade9adb1b2015-07-29 09:56:45 +053014859#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 11, 0))
14860 cfg80211_rx_unprot_mlme_mgmt(pAdapterNode->pAdapter->dev, (u_int8_t*)mgmt, len);
14861#else
Madan Mohan Koyyalamudifc19e442013-05-09 18:24:08 -070014862 cfg80211_send_unprot_deauth(pAdapterNode->pAdapter->dev, (u_int8_t*)mgmt, len );
Anand N Sunkade9adb1b2015-07-29 09:56:45 +053014863#endif
Jeff Johnsone7245742012-09-05 17:12:55 -070014864 }
14865 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
14866 pAdapterNode = pNext;
14867 } while((NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status));
14868
Hanumantha Reddy Pothulada0fe362015-02-27 18:37:03 +053014869 end:
Madan Mohan Koyyalamudifc19e442013-05-09 18:24:08 -070014870 /* Free the allocated management frame */
14871 kfree(mgmt);
14872
Jeff Johnsone7245742012-09-05 17:12:55 -070014873 /* Retry until we unload or reach max count */
14874 if(++pHddCtx->hdd_restart_retries < WLAN_HDD_RESTART_RETRY_MAX_CNT)
14875 vos_timer_start(&pHddCtx->hdd_restart_timer, WLAN_HDD_RESTART_RETRY_DELAY_MS);
14876
14877 return status;
14878
14879}
14880/**---------------------------------------------------------------------------
14881 *
14882 * \brief wlan_hdd_restart_timer_cb
14883 *
14884 * Restart timer callback. An internal function.
14885 *
14886 * \param - User data:
14887 *
14888 * \return - None
14889 *
14890 * --------------------------------------------------------------------------*/
14891
14892void wlan_hdd_restart_timer_cb(v_PVOID_t usrDataForCallback)
14893{
14894 hdd_context_t *pHddCtx = usrDataForCallback;
14895 wlan_hdd_framework_restart(pHddCtx);
14896 return;
14897
14898}
14899
14900
14901/**---------------------------------------------------------------------------
14902 *
14903 * \brief wlan_hdd_restart_driver
14904 *
14905 * This function sends an event to supplicant to restart the WLAN driver.
14906 *
14907 * This function is called from vos_wlanRestart.
14908 *
14909 * \param - pHddCtx
14910 *
14911 * \return - VOS_STATUS_SUCCESS: Success
14912 * VOS_STATUS_E_EMPTY: Adapter is Empty
14913 * VOS_STATUS_E_ALREADY: Request already in progress
14914
14915 * --------------------------------------------------------------------------*/
14916VOS_STATUS wlan_hdd_restart_driver(hdd_context_t *pHddCtx)
14917{
14918 VOS_STATUS status = VOS_STATUS_SUCCESS;
14919
14920 /* A tight check to make sure reentrancy */
14921 if(atomic_xchg(&pHddCtx->isRestartInProgress, 1))
14922 {
Mihir Shetefd528652014-06-23 19:07:50 +053014923 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnsone7245742012-09-05 17:12:55 -070014924 "%s: WLAN restart is already in progress", __func__);
14925
14926 return VOS_STATUS_E_ALREADY;
14927 }
Sameer Thalappil0c164f52013-03-28 15:27:56 -070014928 /* Send reset FIQ to WCNSS to invoke SSR. */
Madan Mohan Koyyalamudie388b342012-11-08 15:03:16 -080014929#ifdef HAVE_WCNSS_RESET_INTR
Siddharth Bhal864e7e82015-04-07 20:07:24 +053014930 wcnss_reset_fiq(TRUE);
Madan Mohan Koyyalamudibb8f0172012-09-28 15:36:06 -070014931#endif
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -070014932
Jeff Johnsone7245742012-09-05 17:12:55 -070014933 return status;
14934}
14935
Bhargav Shahd0715912015-10-01 18:17:37 +053014936/**
14937 * hdd_get_total_sessions() - provide total number of active sessions
14938 * @pHddCtx: Valid Global HDD context pointer
14939 *
14940 * This function iterates through pAdaptors and find the number of all active
14941 * sessions. This active sessions includes connected sta, p2p client and number
14942 * of client connected to sap/p2p go.
14943 *
14944 * Return: Total number of active sessions.
14945 */
14946v_U8_t hdd_get_total_sessions(hdd_context_t *pHddCtx)
14947{
14948 v_U8_t active_session = 0;
14949 hdd_station_ctx_t *pHddStaCtx;
14950 hdd_adapter_list_node_t *pAdapterNode, *pNext;
14951 hdd_adapter_t *pAdapter;
14952 VOS_STATUS status;
14953
14954 status = hdd_get_front_adapter(pHddCtx, &pAdapterNode);
14955 while (NULL != pAdapterNode && VOS_STATUS_SUCCESS == status) {
14956 pAdapter = pAdapterNode->pAdapter;
14957 switch (pAdapter->device_mode) {
14958 case VOS_STA_MODE:
14959 case VOS_P2P_CLIENT_MODE:
14960 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
14961 if(eConnectionState_Associated == pHddStaCtx->conn_info.connState)
14962 active_session += 1;
14963 break;
14964 case VOS_STA_SAP_MODE:
14965 case VOS_P2P_GO_MODE:
14966 active_session += hdd_softap_get_connected_sta(pAdapter);
14967 break;
14968 default:
14969 break;
14970 }
14971
14972 status = hdd_get_next_adapter(pHddCtx, pAdapterNode, &pNext);
14973 pAdapterNode = pNext;
14974 }
14975
14976 return active_session;
14977}
14978
14979/**
14980 * hdd_set_delack_value() - Set delack value
14981 * @pHddCtx: Valid Global HDD context pointer
14982 * @next_rx_level: Value to set for delack
14983 *
14984 * This function compare present value and next value of delack. If the both
14985 * are diffrent then it sets next value .
14986 *
14987 * Return: void.
14988 */
14989void hdd_set_delack_value(hdd_context_t *pHddCtx, v_U32_t next_rx_level)
14990{
14991 if (pHddCtx->cur_rx_level != next_rx_level) {
14992 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_DEBUG,
14993 "%s: TCP DELACK trigger level %d",
14994 __func__, next_rx_level);
14995 mutex_lock(&pHddCtx->cur_rx_level_lock);
14996 pHddCtx->cur_rx_level = next_rx_level;
14997 mutex_unlock(&pHddCtx->cur_rx_level_lock);
14998 wlan_hdd_send_svc_nlink_msg(WLAN_SVC_WLAN_TP_IND, &next_rx_level,
14999 sizeof(next_rx_level));
15000 }
15001}
15002
15003/**
15004 * hdd_set_default_stop_delack_timer() - Start delack timer
15005 * @pHddCtx: Valid Global HDD context pointer
15006 *
15007 * This function stop delack timer and set delack value to default..
15008 *
15009 * Return: void.
15010 */
15011
15012void hdd_set_default_stop_delack_timer(hdd_context_t *pHddCtx)
15013{
15014 if (VOS_TIMER_STATE_RUNNING !=
15015 vos_timer_getCurrentState(&pHddCtx->delack_timer)) {
15016 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_DEBUG,
15017 "%s: Can not stop timer", __func__);
15018 return;
15019 }
15020
15021 vos_timer_stop(&pHddCtx->delack_timer);
15022 hdd_set_delack_value(pHddCtx, TP_IND_LOW);
15023}
15024
15025/**
15026 * hdd_start_delack_timer() - Start delack timer
15027 * @pHddCtx: Valid Global HDD context pointer
15028 *
15029 * This function starts the delack timer for tcpDelAckComputeInterval time
15030 * interval.The default timer value is 2 second.
15031 *
15032 * Return: void.
15033 */
15034void hdd_start_delack_timer(hdd_context_t *pHddCtx)
15035{
15036 if (VOS_TIMER_STATE_RUNNING ==
15037 vos_timer_getCurrentState(&pHddCtx->delack_timer)) {
15038 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_DEBUG,
15039 "%s: Timer is already running", __func__);
15040 return;
15041 }
15042
15043 vos_timer_start(&pHddCtx->delack_timer,
15044 pHddCtx->cfg_ini->tcpDelAckComputeInterval);
15045}
15046
15047/**
15048 * hdd_update_prev_rx_packet_count() - Update previous rx packet count
15049 * @pHddCtx: Valid Global HDD context pointer
15050 *
15051 * This function updates the prev_rx_packets count from the corresponding
15052 * pAdapter states. This prev_rx_packets will diffed with the packet count
15053 * at the end of delack timer. That can give number of RX packet is spacific
15054 * time.
15055 *
15056 * Return: void.
15057 */
15058void hdd_update_prev_rx_packet_count(hdd_context_t *pHddCtx)
15059{
15060 hdd_adapter_list_node_t *pAdapterNode, *pNext;
15061 hdd_adapter_t *pAdapter;
15062 VOS_STATUS status;
15063
15064 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
15065 while (NULL != pAdapterNode && VOS_STATUS_SUCCESS == status) {
15066 pAdapter = pAdapterNode->pAdapter;
15067 pAdapter->prev_rx_packets = pAdapter->stats.rx_packets;
15068 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
15069 pAdapterNode = pNext;
15070 }
15071}
15072
15073/**
15074 * hdd_manage_delack_timer() - start\stop delack timer
15075 * @pHddCtx: Valid Global HDD context pointer
15076 *
15077 * This function check the number of concerent session present, it starts the
15078 * delack timer if only one session is present.
15079 * In the case of BT_COEX and TDLS mode it blindly stop delack functionality.
15080 *
15081 * Return: void.
15082 */
15083void hdd_manage_delack_timer(hdd_context_t *pHddCtx)
15084{
15085 uint8_t sessions;
15086
15087 if (!pHddCtx->cfg_ini->enable_delack) {
15088 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_DEBUG,
15089 "%s: TCP DELACK is not enabled", __func__);
15090 return;
15091 }
15092
15093 /* Blindly stop timer of BTCOEX and TDLS Session is up */
15094 if (pHddCtx->mode != 0) {
15095 hdd_set_default_stop_delack_timer(pHddCtx);
15096 return;
15097 }
15098
15099 sessions = hdd_get_total_sessions(pHddCtx);
15100 if (sessions == 1) {
15101 hdd_update_prev_rx_packet_count(pHddCtx);
15102 hdd_start_delack_timer(pHddCtx);
15103 } else {
15104 hdd_set_default_stop_delack_timer(pHddCtx);
15105 }
15106}
15107
Mihir Shetee1093ba2014-01-21 20:13:32 +053015108/**---------------------------------------------------------------------------
15109 *
15110 * \brief wlan_hdd_init_channels
15111 *
15112 * This function is used to initialize the channel list in CSR
15113 *
15114 * This function is called from hdd_wlan_startup
15115 *
15116 * \param - pHddCtx: HDD context
15117 *
15118 * \return - VOS_STATUS_SUCCESS: Success
15119 * VOS_STATUS_E_FAULT: Failure reported by SME
15120
15121 * --------------------------------------------------------------------------*/
15122static VOS_STATUS wlan_hdd_init_channels(hdd_context_t *pHddCtx)
15123{
15124 eHalStatus status;
15125
15126 status = sme_InitChannels(pHddCtx->hHal);
15127 if (HAL_STATUS_SUCCESS(status))
15128 {
15129 return VOS_STATUS_SUCCESS;
15130 }
15131 else
15132 {
15133 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Channel initialization failed(%d)",
15134 __func__, status);
15135 return VOS_STATUS_E_FAULT;
15136 }
15137}
15138
Mihir Shete04206452014-11-20 17:50:58 +053015139#ifdef CONFIG_ENABLE_LINUX_REG
Agarwal Ashish6db9d532014-09-30 18:19:10 +053015140VOS_STATUS wlan_hdd_init_channels_for_cc(hdd_context_t *pHddCtx, driver_load_type init )
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053015141{
15142 eHalStatus status;
15143
Agarwal Ashish6db9d532014-09-30 18:19:10 +053015144 status = sme_InitChannelsForCC(pHddCtx->hHal, init);
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053015145 if (HAL_STATUS_SUCCESS(status))
15146 {
15147 return VOS_STATUS_SUCCESS;
15148 }
15149 else
15150 {
15151 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Issue reg hint failed(%d)",
15152 __func__, status);
15153 return VOS_STATUS_E_FAULT;
15154 }
15155}
Mihir Shete04206452014-11-20 17:50:58 +053015156#endif
Sudhir Sattayappa Kohallib1d8c3a2013-06-18 14:47:20 -070015157/*
15158 * API to find if there is any STA or P2P-Client is connected
15159 */
15160VOS_STATUS hdd_issta_p2p_clientconnected(hdd_context_t *pHddCtx)
15161{
15162 return sme_isSta_p2p_clientConnected(pHddCtx->hHal);
15163}
Jeff Johnsone7245742012-09-05 17:12:55 -070015164
Mihir Shetee2ae82a2015-03-16 14:08:49 +053015165
15166/*
15167 * API to find if the firmware will send logs using DXE channel
15168 */
15169v_U8_t hdd_is_fw_logging_enabled(void)
15170{
15171 hdd_context_t *pHddCtx;
15172
15173 pHddCtx = vos_get_context(VOS_MODULE_ID_HDD,
15174 vos_get_global_context(VOS_MODULE_ID_HDD, NULL));
15175
Sachin Ahuja084313e2015-05-21 17:57:10 +053015176 return (pHddCtx && pHddCtx->cfg_ini->enableMgmtLogging);
Mihir Shetee2ae82a2015-03-16 14:08:49 +053015177}
15178
Agarwal Ashish57e84372014-12-05 18:26:53 +053015179/*
Mihir Shetebe94ebb2015-05-26 12:07:14 +053015180 * API to find if the firmware will send trace logs using DXE channel
15181 */
15182v_U8_t hdd_is_fw_ev_logging_enabled(void)
15183{
15184 hdd_context_t *pHddCtx;
15185
15186 pHddCtx = vos_get_context(VOS_MODULE_ID_HDD,
15187 vos_get_global_context(VOS_MODULE_ID_HDD, NULL));
15188
15189 return (pHddCtx && pHddCtx->cfg_ini->enableFWLogging);
15190}
15191/*
Agarwal Ashish57e84372014-12-05 18:26:53 +053015192 * API to find if there is any session connected
15193 */
15194VOS_STATUS hdd_is_any_session_connected(hdd_context_t *pHddCtx)
15195{
15196 return sme_is_any_session_connected(pHddCtx->hHal);
15197}
15198
15199
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053015200int wlan_hdd_scan_abort(hdd_adapter_t *pAdapter)
15201{
15202 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
15203 hdd_scaninfo_t *pScanInfo = NULL;
Girish Gowli4bf7a632014-06-12 13:42:11 +053015204 long status = 0;
c_hpothua3d45d52015-01-05 14:11:17 +053015205 tSirAbortScanStatus abortScanStatus;
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053015206
15207 pScanInfo = &pHddCtx->scan_info;
Ratnam Rachuric7681132015-06-30 10:35:13 +053015208 INIT_COMPLETION(pScanInfo->abortscan_event_var);
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053015209 if (pScanInfo->mScanPending)
15210 {
c_hpothua3d45d52015-01-05 14:11:17 +053015211 abortScanStatus = hdd_abort_mac_scan(pHddCtx, pScanInfo->sessionId,
15212 eCSR_SCAN_ABORT_DEFAULT);
15213 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15214 FL("abortScanStatus: %d"), abortScanStatus);
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053015215
c_hpothua3d45d52015-01-05 14:11:17 +053015216 /* If there is active scan command lets wait for the completion else
15217 * there is no need to wait as scan command might be in the SME pending
15218 * command list.
15219 */
15220 if (abortScanStatus == eSIR_ABORT_ACTIVE_SCAN_LIST_NOT_EMPTY)
15221 {
Mukul Sharmab392b642017-08-17 17:45:29 +053015222 status = wait_for_completion_timeout(
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053015223 &pScanInfo->abortscan_event_var,
15224 msecs_to_jiffies(5000));
c_hpothua3d45d52015-01-05 14:11:17 +053015225 if (0 >= status)
15226 {
15227 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Girish Gowli4bf7a632014-06-12 13:42:11 +053015228 "%s: Timeout or Interrupt occurred while waiting for abort"
15229 "scan, status- %ld", __func__, status);
c_hpothua3d45d52015-01-05 14:11:17 +053015230 return -ETIMEDOUT;
15231 }
15232 }
15233 else if (abortScanStatus == eSIR_ABORT_SCAN_FAILURE)
15234 {
15235 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15236 FL("hdd_abort_mac_scan failed"));
15237 return -VOS_STATUS_E_FAILURE;
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053015238 }
15239 }
Girish Gowli4bf7a632014-06-12 13:42:11 +053015240 return 0;
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053015241}
15242
Abhishek Singh7d624e12015-11-30 14:29:27 +053015243/**
15244 * hdd_indicate_mgmt_frame() - Wrapper to indicate management frame to
15245 * user space
15246 * @frame_ind: Management frame data to be informed.
15247 *
15248 * This function is used to indicate management frame to
15249 * user space
15250 *
15251 * Return: None
15252 *
15253 */
15254void hdd_indicate_mgmt_frame(tSirSmeMgmtFrameInd *frame_ind)
15255{
15256 hdd_context_t *hdd_ctx = NULL;
15257 hdd_adapter_t *adapter = NULL;
15258 v_CONTEXT_t vos_context = NULL;
15259
15260 /* Get the global VOSS context.*/
15261 vos_context = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
15262 if (!vos_context) {
15263 hddLog(LOGE, FL("Global VOS context is Null"));
15264 return;
15265 }
15266 /* Get the HDD context.*/
15267 hdd_ctx =
15268 (hdd_context_t *)vos_get_context(VOS_MODULE_ID_HDD, vos_context );
15269
15270 if (0 != wlan_hdd_validate_context(hdd_ctx))
15271 {
15272 return;
15273 }
15274 adapter = hdd_get_adapter_by_sme_session_id(hdd_ctx,
15275 frame_ind->sessionId);
15276
15277 if ((NULL != adapter) &&
15278 (WLAN_HDD_ADAPTER_MAGIC == adapter->magic))
15279 __hdd_indicate_mgmt_frame(adapter,
15280 frame_ind->frameLen,
15281 frame_ind->frameBuf,
15282 frame_ind->frameType,
15283 frame_ind->rxChan,
15284 frame_ind->rxRssi);
15285 return;
15286
15287}
15288
c_hpothu225aa7c2014-10-22 17:45:13 +053015289VOS_STATUS wlan_hdd_cancel_remain_on_channel(hdd_context_t *pHddCtx)
15290{
15291 hdd_adapter_t *pAdapter;
15292 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
15293 VOS_STATUS vosStatus;
15294
15295 vosStatus = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
15296 while (NULL != pAdapterNode && VOS_STATUS_E_EMPTY != vosStatus)
15297 {
15298 pAdapter = pAdapterNode->pAdapter;
15299 if (NULL != pAdapter)
15300 {
15301 if (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode ||
15302 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode ||
15303 WLAN_HDD_P2P_GO == pAdapter->device_mode)
15304 {
15305 hddLog(LOG1, FL("abort ROC deviceMode: %d"),
15306 pAdapter->device_mode);
15307 if (VOS_STATUS_SUCCESS !=
15308 wlan_hdd_cancel_existing_remain_on_channel(pAdapter))
15309 {
15310 hddLog(LOGE, FL("failed to abort ROC"));
15311 return VOS_STATUS_E_FAILURE;
15312 }
15313 }
15314 }
15315 vosStatus = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
15316 pAdapterNode = pNext;
15317 }
15318 return VOS_STATUS_SUCCESS;
15319}
Mahesh A Saptasagard477b092015-02-06 15:12:16 +053015320
Mihir Shete0be28772015-02-17 18:42:14 +053015321hdd_remain_on_chan_ctx_t *hdd_get_remain_on_channel_ctx(hdd_context_t *pHddCtx)
15322{
15323 hdd_adapter_t *pAdapter;
15324 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
15325 hdd_cfg80211_state_t *cfgState;
15326 hdd_remain_on_chan_ctx_t *pRemainChanCtx = NULL;
15327 VOS_STATUS vosStatus;
15328
15329 vosStatus = hdd_get_front_adapter (pHddCtx, &pAdapterNode);
15330 while (NULL != pAdapterNode && VOS_STATUS_E_EMPTY != vosStatus)
15331 {
15332 pAdapter = pAdapterNode->pAdapter;
15333 if (NULL != pAdapter)
15334 {
15335 cfgState = WLAN_HDD_GET_CFG_STATE_PTR(pAdapter);
15336 pRemainChanCtx = cfgState->remain_on_chan_ctx;
15337 if (pRemainChanCtx)
15338 break;
15339 }
15340 vosStatus = hdd_get_next_adapter (pHddCtx, pAdapterNode, &pNext);
15341 pAdapterNode = pNext;
15342 }
15343 return pRemainChanCtx;
15344}
15345
Padma, Santhosh Kumar778d8382015-03-04 17:41:22 +053015346/**
15347 * wlan_hdd_handle_dfs_chan_scan () - handles disable/enable DFS channels
15348 *
15349 * @pHddCtx: HDD context within host driver
15350 * @dfsScanMode: dfsScanMode passed from ioctl
15351 *
15352 */
15353
15354VOS_STATUS wlan_hdd_handle_dfs_chan_scan(hdd_context_t *pHddCtx,
15355 tANI_U8 dfsScanMode)
15356{
15357 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
15358 hdd_adapter_t *pAdapter;
15359 VOS_STATUS vosStatus;
15360 hdd_station_ctx_t *pHddStaCtx;
15361 eHalStatus status = eHAL_STATUS_SUCCESS;
15362
15363 if(!pHddCtx)
15364 {
15365 hddLog(LOGE, FL("HDD context is Null"));
15366 return eHAL_STATUS_FAILURE;
15367 }
15368
15369 if (pHddCtx->scan_info.mScanPending)
15370 {
15371 hddLog(LOG1, FL("Aborting scan for sessionId: %d"),
15372 pHddCtx->scan_info.sessionId);
15373 hdd_abort_mac_scan(pHddCtx,
15374 pHddCtx->scan_info.sessionId,
15375 eCSR_SCAN_ABORT_DEFAULT);
15376 }
15377
15378 if (!dfsScanMode)
15379 {
15380 vosStatus = hdd_get_front_adapter( pHddCtx, &pAdapterNode);
15381 while ((NULL != pAdapterNode) &&
15382 (VOS_STATUS_SUCCESS == vosStatus))
15383 {
15384 pAdapter = pAdapterNode->pAdapter;
15385
15386 if (WLAN_HDD_INFRA_STATION == pAdapter->device_mode)
15387 {
15388 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
15389
15390 if(!pHddStaCtx)
15391 {
15392 hddLog(LOGE, FL("HDD STA context is Null"));
15393 return eHAL_STATUS_FAILURE;
15394 }
15395
15396 /* if STA is already connected on DFS channel,
15397 disconnect immediately*/
15398 if (hdd_connIsConnected(pHddStaCtx) &&
15399 (NV_CHANNEL_DFS ==
15400 vos_nv_getChannelEnabledState(
15401 pHddStaCtx->conn_info.operationChannel)))
15402 {
15403 status = sme_RoamDisconnect(pHddCtx->hHal,
15404 pAdapter->sessionId,
15405 eCSR_DISCONNECT_REASON_UNSPECIFIED);
15406 hddLog(LOG1, FL("Client connected on DFS channel %d,"
15407 "sme_RoamDisconnect returned with status: %d"
15408 "for sessionid: %d"), pHddStaCtx->conn_info.
15409 operationChannel, status, pAdapter->sessionId);
15410 }
15411 }
15412
15413 vosStatus = hdd_get_next_adapter(pHddCtx, pAdapterNode,
15414 &pNext);
15415 pAdapterNode = pNext;
15416 }
15417 }
15418
15419 sme_UpdateDFSScanMode(pHddCtx->hHal, dfsScanMode);
15420 sme_UpdateDFSRoamMode(pHddCtx->hHal,
15421 (dfsScanMode != DFS_CHNL_SCAN_DISABLED));
15422
15423 status = sme_HandleDFSChanScan(pHddCtx->hHal);
15424 if (!HAL_STATUS_SUCCESS(status))
15425 {
15426 hddLog(LOGE,
15427 FL("Failed in sme_HandleDFSChanScan (err=%d)"), status);
15428 return status;
15429 }
15430
15431 return status;
15432}
15433
Nirav Shah7e3c8132015-06-22 23:51:42 +053015434static int hdd_log2_ceil(unsigned value)
15435{
15436 /* need to switch to unsigned math so that negative values
15437 * will right-shift towards 0 instead of -1
15438 */
15439 unsigned tmp = value;
15440 int log2 = -1;
15441
15442 if (value == 0)
15443 return 0;
15444
15445 while (tmp) {
15446 log2++;
15447 tmp >>= 1;
15448 }
15449 if (1U << log2 != value)
15450 log2++;
15451
15452 return log2;
15453}
15454
15455/**
15456 * hdd_sta_id_hash_attach() - initialize sta id to macaddr hash
15457 * @pAdapter: adapter handle
15458 *
15459 * Return: vos status
15460 */
15461VOS_STATUS hdd_sta_id_hash_attach(hdd_adapter_t *pAdapter)
15462{
15463 int hash_elem, log2, i;
15464
15465 spin_lock_bh( &pAdapter->sta_hash_lock);
15466 if (pAdapter->is_sta_id_hash_initialized == VOS_TRUE) {
15467 spin_unlock_bh( &pAdapter->sta_hash_lock);
15468 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15469 "%s: hash already attached for session id %d",
15470 __func__, pAdapter->sessionId);
15471 return VOS_STATUS_SUCCESS;
15472 }
15473 spin_unlock_bh( &pAdapter->sta_hash_lock);
15474
15475 hash_elem = WLAN_MAX_STA_COUNT;
15476 hash_elem *= HDD_STA_ID_HASH_MULTIPLIER;
15477 log2 = hdd_log2_ceil(hash_elem);
15478 hash_elem = 1 << log2;
15479
15480 pAdapter->sta_id_hash.mask = hash_elem - 1;
15481 pAdapter->sta_id_hash.idx_bits = log2;
15482 pAdapter->sta_id_hash.bins =
15483 vos_mem_malloc(hash_elem *sizeof(hdd_list_t));
15484 if (!pAdapter->sta_id_hash.bins) {
15485 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15486 "%s: malloc failed for session %d",
15487 __func__, pAdapter->sessionId);
15488 return VOS_STATUS_E_NOMEM;
15489 }
15490
15491 for (i = 0; i < hash_elem; i++)
15492 hdd_list_init(&pAdapter->sta_id_hash.bins[i], WLAN_MAX_STA_COUNT);
15493
15494 spin_lock_bh( &pAdapter->sta_hash_lock);
15495 pAdapter->is_sta_id_hash_initialized = VOS_TRUE;
15496 spin_unlock_bh( &pAdapter->sta_hash_lock);
15497 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15498 "%s: Station ID Hash attached for session id %d",
15499 __func__, pAdapter->sessionId);
15500
15501 return VOS_STATUS_SUCCESS;
15502}
15503
15504/**
15505 * hdd_sta_id_hash_detach() - deinit sta_id to macaddr hash
15506 * @pAdapter: adapter handle
15507 *
15508 * Return: vos status
15509 */
15510VOS_STATUS hdd_sta_id_hash_detach(hdd_adapter_t *pAdapter)
15511{
15512 int hash_elem, i;
15513 v_SIZE_t size;
15514
15515 spin_lock_bh( &pAdapter->sta_hash_lock);
15516 if (pAdapter->is_sta_id_hash_initialized != VOS_TRUE) {
15517 spin_unlock_bh( &pAdapter->sta_hash_lock);
15518 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15519 "%s: hash not initialized for session id %d",
15520 __func__, pAdapter->sessionId);
15521 return VOS_STATUS_SUCCESS;
15522 }
15523
15524 pAdapter->is_sta_id_hash_initialized = VOS_FALSE;
15525 spin_unlock_bh( &pAdapter->sta_hash_lock);
15526
15527 hash_elem = 1 << pAdapter->sta_id_hash.idx_bits;
15528
15529 /* free all station info*/
15530 for (i = 0; i < hash_elem; i++) {
15531 hdd_list_size(&pAdapter->sta_id_hash.bins[i], &size);
15532 if (size != 0) {
15533 VOS_STATUS status;
15534 hdd_staid_hash_node_t *sta_info_node = NULL;
15535 hdd_staid_hash_node_t *next_node = NULL;
15536 status = hdd_list_peek_front ( &pAdapter->sta_id_hash.bins[i],
15537 (hdd_list_node_t**) &sta_info_node );
15538
15539 while ( NULL != sta_info_node && VOS_STATUS_SUCCESS == status )
15540 {
15541 status = hdd_list_remove_node( &pAdapter->sta_id_hash.bins[i],
15542 &sta_info_node->node);
15543 vos_mem_free(sta_info_node);
15544
15545 status = hdd_list_peek_next (&pAdapter->sta_id_hash.bins[i],
15546 (hdd_list_node_t*)sta_info_node,
15547 (hdd_list_node_t**)&next_node);
15548 sta_info_node = next_node;
15549 }
15550 }
15551 }
15552
15553 vos_mem_free(pAdapter->sta_id_hash.bins);
15554 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15555 "%s: Station ID Hash detached for session id %d",
15556 __func__, pAdapter->sessionId);
15557 return VOS_STATUS_SUCCESS;
15558}
15559
15560/**
15561 * hdd_sta_id_hash_calculate_index() - derive index from macaddr
15562 * @pAdapter: adapter handle
15563 * @mac_addr_in: input mac address
15564 *
15565 * Return: index derived from mac address
15566 */
15567int hdd_sta_id_hash_calculate_index(hdd_adapter_t *pAdapter,
15568 v_MACADDR_t *mac_addr_in)
15569{
15570 uint16 index;
15571 struct hdd_align_mac_addr_t * mac_addr =
15572 (struct hdd_align_mac_addr_t *)mac_addr_in;
15573
15574 index = mac_addr->bytes_ab ^
15575 mac_addr->bytes_cd ^ mac_addr->bytes_ef;
15576 index ^= index >> pAdapter->sta_id_hash.idx_bits;
15577 index &= pAdapter->sta_id_hash.mask;
15578 return index;
15579}
15580
15581/**
15582 * hdd_sta_id_hash_add_entry() - add entry in hash
15583 * @pAdapter: adapter handle
15584 * @sta_id: station id
15585 * @mac_addr: mac address
15586 *
15587 * Return: vos status
15588 */
15589VOS_STATUS hdd_sta_id_hash_add_entry(hdd_adapter_t *pAdapter,
15590 v_U8_t sta_id, v_MACADDR_t *mac_addr)
15591{
15592 uint16 index;
15593 hdd_staid_hash_node_t *sta_info_node = NULL;
15594
Nirav Shah7e3c8132015-06-22 23:51:42 +053015595 index = hdd_sta_id_hash_calculate_index(pAdapter, mac_addr);
15596 sta_info_node = vos_mem_malloc(sizeof(hdd_staid_hash_node_t));
15597 if (!sta_info_node) {
Nirav Shah7e3c8132015-06-22 23:51:42 +053015598 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15599 "%s: malloc failed", __func__);
15600 return VOS_STATUS_E_NOMEM;
15601 }
15602
15603 sta_info_node->sta_id = sta_id;
15604 vos_mem_copy(&sta_info_node->mac_addr, mac_addr, sizeof(v_MACADDR_t));
15605
Nirav Shah303ed5c2015-08-24 10:29:25 +053015606 spin_lock_bh( &pAdapter->sta_hash_lock);
15607 if (pAdapter->is_sta_id_hash_initialized != VOS_TRUE) {
15608 spin_unlock_bh( &pAdapter->sta_hash_lock);
15609 vos_mem_free(sta_info_node);
15610 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15611 "%s: hash is not initialized for session id %d",
15612 __func__, pAdapter->sessionId);
15613 return VOS_STATUS_E_FAILURE;
15614 }
15615
Nirav Shah7e3c8132015-06-22 23:51:42 +053015616 hdd_list_insert_back ( &pAdapter->sta_id_hash.bins[index],
15617 (hdd_list_node_t*) sta_info_node );
15618 spin_unlock_bh( &pAdapter->sta_hash_lock);
15619 return VOS_STATUS_SUCCESS;
15620}
15621
15622/**
15623 * hdd_sta_id_hash_remove_entry() - remove entry from hash
15624 * @pAdapter: adapter handle
15625 * @sta_id: station id
15626 * @mac_addr: mac address
15627 *
15628 * Return: vos status
15629 */
15630VOS_STATUS hdd_sta_id_hash_remove_entry(hdd_adapter_t *pAdapter,
15631 v_U8_t sta_id, v_MACADDR_t *mac_addr)
15632{
15633 uint16 index;
15634 VOS_STATUS status;
15635 hdd_staid_hash_node_t *sta_info_node = NULL;
15636 hdd_staid_hash_node_t *next_node = NULL;
15637
15638 spin_lock_bh( &pAdapter->sta_hash_lock);
15639 if (pAdapter->is_sta_id_hash_initialized != VOS_TRUE) {
15640 spin_unlock_bh( &pAdapter->sta_hash_lock);
15641 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15642 "%s: hash is not initialized for session id %d",
15643 __func__, pAdapter->sessionId);
15644 return VOS_STATUS_E_FAILURE;
15645 }
15646
15647 index = hdd_sta_id_hash_calculate_index(pAdapter, mac_addr);
15648 status = hdd_list_peek_front ( &pAdapter->sta_id_hash.bins[index],
15649 (hdd_list_node_t**) &sta_info_node );
15650
15651 while ( NULL != sta_info_node && VOS_STATUS_SUCCESS == status )
15652 {
15653 if (sta_info_node->sta_id == sta_id) {
15654 status = hdd_list_remove_node( &pAdapter->sta_id_hash.bins[index],
15655 &sta_info_node->node);
15656 vos_mem_free(sta_info_node);
15657 break;
15658 }
15659 status = hdd_list_peek_next (&pAdapter->sta_id_hash.bins[index],
15660 (hdd_list_node_t*)sta_info_node, (hdd_list_node_t**)&next_node);
15661 sta_info_node = next_node;
15662 }
15663 spin_unlock_bh( &pAdapter->sta_hash_lock);
15664 return status;
15665}
15666
15667/**
15668 * hdd_sta_id_find_from_mac_addr() - find sta id from mac address
15669 * @pAdapter: adapter handle
15670 * @mac_addr_in: mac address
15671 *
15672 * Return: station id
15673 */
15674int hdd_sta_id_find_from_mac_addr(hdd_adapter_t *pAdapter,
15675 v_MACADDR_t *mac_addr_in)
15676{
15677 uint8 is_found = 0;
15678 uint8 sta_id = HDD_WLAN_INVALID_STA_ID;
15679 uint16 index;
15680 VOS_STATUS status;
15681 hdd_staid_hash_node_t *sta_info_node = NULL;
15682 hdd_staid_hash_node_t *next_node = NULL;
15683
15684 spin_lock_bh( &pAdapter->sta_hash_lock);
15685 if (pAdapter->is_sta_id_hash_initialized != VOS_TRUE) {
15686 spin_unlock_bh( &pAdapter->sta_hash_lock);
Bhargav Shahce3b32c2015-08-10 12:29:24 +053015687 hddLog(VOS_TRACE_LEVEL_INFO,
Nirav Shah7e3c8132015-06-22 23:51:42 +053015688 FL("hash is not initialized for session id %d"),
15689 pAdapter->sessionId);
15690 return HDD_WLAN_INVALID_STA_ID;
15691 }
15692
15693 index = hdd_sta_id_hash_calculate_index(pAdapter, mac_addr_in);
15694 status = hdd_list_peek_front ( &pAdapter->sta_id_hash.bins[index],
15695 (hdd_list_node_t**) &sta_info_node );
15696
15697 while ( NULL != sta_info_node && VOS_STATUS_SUCCESS == status )
15698 {
15699 if (vos_mem_compare(&sta_info_node->mac_addr,
15700 mac_addr_in, sizeof(v_MACADDR_t))) {
15701 is_found = 1;
15702 sta_id = sta_info_node->sta_id;
15703 break;
15704 }
15705 status = hdd_list_peek_next (&pAdapter->sta_id_hash.bins[index],
15706 (hdd_list_node_t*)sta_info_node,
15707 (hdd_list_node_t**)&next_node);
15708 sta_info_node = next_node;
15709 }
15710 spin_unlock_bh( &pAdapter->sta_hash_lock);
15711 return sta_id;
15712}
15713
c_manjeecfd1efb2015-09-25 19:32:34 +053015714/*FW memory dump feature*/
15715/**
15716 * This structure hold information about the /proc file
15717 *
15718 */
15719static struct proc_dir_entry *proc_file, *proc_dir;
15720
15721/**
15722 * memdump_read() - perform read operation in memory dump proc file
15723 *
15724 * @file - handle for the proc file.
15725 * @buf - pointer to user space buffer.
15726 * @count - number of bytes to be read.
15727 * @pos - offset in the from buffer.
15728 *
15729 * This function performs read operation for the memory dump proc file.
15730 *
15731 * Return: number of bytes read on success, error code otherwise.
15732 */
15733static ssize_t memdump_read(struct file *file, char __user *buf,
15734 size_t count, loff_t *pos)
15735{
15736 int status;
15737 hdd_context_t *hdd_ctx = (hdd_context_t *)PDE_DATA(file_inode(file));
15738 size_t ret_count;
c_manjeef1495642015-10-13 18:35:01 +053015739 loff_t bytes_left;
c_manjeecfd1efb2015-09-25 19:32:34 +053015740 ENTER();
15741
15742 hddLog(LOG1, FL("Read req for size:%zu pos:%llu"), count, *pos);
15743 status = wlan_hdd_validate_context(hdd_ctx);
15744 if (0 != status) {
15745 return -EINVAL;
15746 }
15747
15748 if (!wlan_fwr_mem_dump_test_and_set_read_allowed_bit()) {
15749 hddLog(LOGE, FL("Current mem dump request timed out/failed"));
15750 return -EINVAL;
15751 }
15752
15753 /* run fs_read_handler in an atomic context*/
15754 vos_ssr_protect(__func__);
c_manjeef1495642015-10-13 18:35:01 +053015755 ret_count = wlan_fwr_mem_dump_fsread_handler( buf, count, pos, &bytes_left);
15756 if(bytes_left == 0)
c_manjeecfd1efb2015-09-25 19:32:34 +053015757 {
15758 /*Free the fwr mem dump buffer */
15759 wlan_free_fwr_mem_dump_buffer();
15760 wlan_set_fwr_mem_dump_state(FW_MEM_DUMP_IDLE);
c_manjeef1495642015-10-13 18:35:01 +053015761 ret_count=0;
c_manjeecfd1efb2015-09-25 19:32:34 +053015762 }
15763 /*if SSR/unload code is waiting for memdump_read to finish,signal it*/
15764 vos_ssr_unprotect(__func__);
15765 EXIT();
15766 return ret_count;
15767}
15768
15769/**
15770 * struct memdump_fops - file operations for memory dump feature
15771 * @read - read function for memory dump operation.
15772 *
15773 * This structure initialize the file operation handle for memory
15774 * dump feature
15775 */
15776static const struct file_operations memdump_fops = {
15777 read: memdump_read
15778};
15779
Hanumanth Reddy Pothulae856bc22018-04-11 15:35:36 +053015780struct fw_mem_dump_priv {
15781 uint32_t status;
15782};
15783
c_manjeecfd1efb2015-09-25 19:32:34 +053015784/*
15785* wlan_hdd_fw_mem_dump_cb : callback for Fw mem dump request
15786* To be passed by HDD to WDA and called upon receiving of response
15787* from firmware
15788* @fwMemDumpReqContext : memory dump request context
15789* @dump_rsp : dump response from HAL
15790* Returns none
15791*/
Hanumanth Reddy Pothulae856bc22018-04-11 15:35:36 +053015792void wlan_hdd_fw_mem_dump_cb(void *context,
c_manjeecfd1efb2015-09-25 19:32:34 +053015793 tAniFwrDumpRsp *dump_rsp)
15794{
Hanumanth Reddy Pothulae856bc22018-04-11 15:35:36 +053015795 struct hdd_request *request;
15796 struct fw_mem_dump_priv *priv;
c_manjeecfd1efb2015-09-25 19:32:34 +053015797
Hanumanth Reddy Pothulae856bc22018-04-11 15:35:36 +053015798 request = hdd_request_get(context);
15799 if (!request) {
15800 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Obsolete request"));
15801 return;
15802 }
c_manjeecfd1efb2015-09-25 19:32:34 +053015803
Hanumanth Reddy Pothulae856bc22018-04-11 15:35:36 +053015804 ENTER();
15805
15806 priv = hdd_request_priv(request);
15807 priv->status = dump_rsp->dump_status;
15808
15809 /* report the status to requesting function and free mem.*/
15810 if (dump_rsp->dump_status != eHAL_STATUS_SUCCESS) {
15811 hddLog(LOGE, FL("fw dump request declined by fwr"));
15812 //set the request completion variable
15813 hdd_request_complete(request);
15814 //Free the allocated fwr dump
15815 wlan_free_fwr_mem_dump_buffer();
15816 wlan_set_fwr_mem_dump_state(FW_MEM_DUMP_IDLE);
15817 } else {
15818 hddLog(LOG1, FL("fw dump request accepted by fwr"));
15819 /* register the HDD callback which will be called by SVC */
15820 wlan_set_svc_fw_mem_dump_req_cb(
15821 (void*)wlan_hdd_fw_mem_dump_req_cb,
15822 context);
15823 }
15824
15825 hdd_request_put(request);
15826
15827 EXIT();
c_manjeecfd1efb2015-09-25 19:32:34 +053015828}
15829
15830/**
15831 * memdump_procfs_remove() - Remove file/dir under procfs for memory dump
15832 *
15833 * This function removes file/dir under proc file system that was
15834 * processing firmware memory dump
15835 *
15836 * Return: None
15837 */
15838static void memdump_procfs_remove(void)
15839{
15840 remove_proc_entry(PROCFS_MEMDUMP_NAME, proc_dir);
15841 hddLog(LOG1 , FL("/proc/%s/%s removed\n"),
15842 PROCFS_MEMDUMP_DIR, PROCFS_MEMDUMP_NAME);
15843 remove_proc_entry(PROCFS_MEMDUMP_DIR, NULL);
15844 hddLog(LOG1 , FL("/proc/%s removed\n"), PROCFS_MEMDUMP_DIR);
15845}
15846
15847/**
15848 * memdump_procfs_init() - Initialize procfs for memory dump
15849 *
15850 * @vos_ctx - Global vos context.
15851 *
15852 * This function create file under proc file system to be used later for
15853 * processing firmware memory dump
15854 *
15855 * Return: 0 on success, error code otherwise.
15856 */
15857static int memdump_procfs_init(void *vos_ctx)
15858{
15859 hdd_context_t *hdd_ctx;
15860
15861 hdd_ctx = vos_get_context(VOS_MODULE_ID_HDD, vos_ctx);
15862 if (!hdd_ctx) {
15863 hddLog(LOGE , FL("Invalid HDD context"));
15864 return -EINVAL;
15865 }
15866
15867 proc_dir = proc_mkdir(PROCFS_MEMDUMP_DIR, NULL);
15868 if (proc_dir == NULL) {
15869 remove_proc_entry(PROCFS_MEMDUMP_DIR, NULL);
15870 hddLog(LOGE , FL("Error: Could not initialize /proc/%s"),
15871 PROCFS_MEMDUMP_DIR);
15872 return -ENOMEM;
15873 }
15874
15875 proc_file = proc_create_data(PROCFS_MEMDUMP_NAME,
15876 S_IRUSR | S_IWUSR, proc_dir,
15877 &memdump_fops, hdd_ctx);
15878 if (proc_file == NULL) {
15879 remove_proc_entry(PROCFS_MEMDUMP_NAME, proc_dir);
15880 hddLog(LOGE , FL("Error: Could not initialize /proc/%s"),
15881 PROCFS_MEMDUMP_NAME);
15882 return -ENOMEM;
15883 }
15884
15885 hddLog(LOG1 , FL("/proc/%s/%s created"),
15886 PROCFS_MEMDUMP_DIR, PROCFS_MEMDUMP_NAME);
15887
15888 return 0;
15889}
15890
15891/**
15892 * memdump_init() - Initialization function for memory dump feature
15893 *
15894 * This function creates proc file for memdump feature and registers
15895 * HDD callback function with SME.
15896 *
15897 * Return - 0 on success, error otherwise
15898 */
15899int memdump_init(void)
15900{
15901 hdd_context_t *hdd_ctx;
15902 void *vos_ctx;
15903 int status = 0;
15904
15905 vos_ctx = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
15906 if (!vos_ctx) {
15907 hddLog(LOGE, FL("Invalid VOS context"));
15908 return -EINVAL;
15909 }
15910
15911 hdd_ctx = vos_get_context(VOS_MODULE_ID_HDD, vos_ctx);
15912 if (!hdd_ctx) {
15913 hddLog(LOGE , FL("Invalid HDD context"));
15914 return -EINVAL;
15915 }
15916
15917 status = memdump_procfs_init(vos_ctx);
15918 if (status) {
15919 hddLog(LOGE , FL("Failed to create proc file"));
15920 return status;
15921 }
15922
15923 return 0;
15924}
15925
15926/**
15927 * memdump_deinit() - De initialize memdump feature
15928 *
15929 * This function removes proc file created for memdump feature.
15930 *
15931 * Return: None
15932 */
15933int memdump_deinit(void)
15934{
15935 hdd_context_t *hdd_ctx;
15936 void *vos_ctx;
15937
15938 vos_ctx = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
15939 if (!vos_ctx) {
15940 hddLog(LOGE, FL("Invalid VOS context"));
15941 return -EINVAL;
15942 }
15943
15944 hdd_ctx = vos_get_context(VOS_MODULE_ID_HDD, vos_ctx);
15945 if(!hdd_ctx) {
15946 hddLog(LOGE , FL("Invalid HDD context"));
15947 return -EINVAL;
15948 }
15949
15950 memdump_procfs_remove();
15951 return 0;
15952}
15953
15954/**
15955 * wlan_hdd_fw_mem_dump_req(pHddCtx) - common API(cfg80211/ioctl) for requesting fw mem dump to SME
15956 * Return: HAL status
15957 */
15958
15959int wlan_hdd_fw_mem_dump_req(hdd_context_t * pHddCtx)
15960{
15961 tAniFwrDumpReq fw_mem_dump_req={0};
15962 eHalStatus status = eHAL_STATUS_FAILURE;
Hanumanth Reddy Pothulae856bc22018-04-11 15:35:36 +053015963 int ret=0, dump_status;
15964 void *cookie;
15965 struct hdd_request *request;
15966 struct fw_mem_dump_priv *priv;
15967 static const struct hdd_request_params params = {
15968 .priv_size = sizeof(*priv),
15969 .timeout_ms = FW_MEM_DUMP_TIMEOUT_MS,
15970 };
15971
c_manjeecfd1efb2015-09-25 19:32:34 +053015972 ENTER();
c_manjeef1495642015-10-13 18:35:01 +053015973
c_manjeecfd1efb2015-09-25 19:32:34 +053015974 /*Check whether a dump request is already going on
15975 *Caution this function will free previously held memory if new dump request is allowed*/
15976 if (!wlan_fwr_mem_dump_test_and_set_write_allowed_bit()) {
15977 hddLog(LOGE, FL("Fw memdump already in progress"));
15978 return -EBUSY;
15979 }
15980 //Allocate memory for fw mem dump buffer
15981 ret = wlan_fwr_mem_dump_buffer_allocation();
15982 if(ret == -EFAULT)
15983 {
15984 hddLog(LOGE, FL("Fwr mem dump not supported by FW"));
15985 return ret;
15986 }
15987 if (0 != ret) {
15988 hddLog(LOGE, FL("Fwr mem Allocation failed"));
15989 return -ENOMEM;
15990 }
Hanumanth Reddy Pothulae856bc22018-04-11 15:35:36 +053015991
15992 request = hdd_request_alloc(&params);
15993 if (!request) {
15994 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Request allocation failure"));
15995 return VOS_STATUS_E_NOMEM;
15996 }
15997 cookie = hdd_request_cookie(request);
c_manjeef1495642015-10-13 18:35:01 +053015998
c_manjeecfd1efb2015-09-25 19:32:34 +053015999 fw_mem_dump_req.fwMemDumpReqCallback = wlan_hdd_fw_mem_dump_cb;
Hanumanth Reddy Pothulae856bc22018-04-11 15:35:36 +053016000 fw_mem_dump_req.fwMemDumpReqContext = cookie;
c_manjeecfd1efb2015-09-25 19:32:34 +053016001 status = sme_FwMemDumpReq(pHddCtx->hHal, &fw_mem_dump_req);
16002 if(eHAL_STATUS_SUCCESS != status)
16003 {
16004 hddLog(VOS_TRACE_LEVEL_ERROR,
16005 "%s: fw_mem_dump_req failed ", __func__);
16006 wlan_free_fwr_mem_dump_buffer();
c_manjeef1495642015-10-13 18:35:01 +053016007 ret = -EFAULT;
16008 goto cleanup;
c_manjeecfd1efb2015-09-25 19:32:34 +053016009 }
c_manjeef1495642015-10-13 18:35:01 +053016010 /*wait for fw mem dump completion to send event to userspace*/
Hanumanth Reddy Pothulae856bc22018-04-11 15:35:36 +053016011 ret = hdd_request_wait_for_response(request);
16012 if (ret)
c_manjeef1495642015-10-13 18:35:01 +053016013 {
16014 hddLog(VOS_TRACE_LEVEL_ERROR,
Hanumanth Reddy Pothulae856bc22018-04-11 15:35:36 +053016015 "%s: fw_mem_dump_req timeout %d ", __func__,ret);
Abhishek Singh4eca9822015-12-09 18:07:34 +053016016 ret = -ETIMEDOUT;
Hanumanth Reddy Pothulae856bc22018-04-11 15:35:36 +053016017 }else {
16018 priv = hdd_request_priv(request);
16019 dump_status = priv->status;
c_manjeef1495642015-10-13 18:35:01 +053016020 }
16021cleanup:
Hanumanth Reddy Pothulae856bc22018-04-11 15:35:36 +053016022 hdd_request_put(request);
16023 if(!ret && !dump_status)
Abhishek Singh4eca9822015-12-09 18:07:34 +053016024 ret = -EFAULT;
c_manjeecfd1efb2015-09-25 19:32:34 +053016025
c_manjeef1495642015-10-13 18:35:01 +053016026 EXIT();
Abhishek Singh4eca9822015-12-09 18:07:34 +053016027 return ret;
c_manjeef1495642015-10-13 18:35:01 +053016028}
16029
16030/**
16031 * HDD callback which will be called by SVC to indicate mem dump completion.
16032 */
Hanumanth Reddy Pothulae856bc22018-04-11 15:35:36 +053016033void wlan_hdd_fw_mem_dump_req_cb(void *context)
c_manjeef1495642015-10-13 18:35:01 +053016034{
Hanumanth Reddy Pothulae856bc22018-04-11 15:35:36 +053016035 struct hdd_request *request;
16036 struct fw_mem_dump_priv *priv;
16037
16038 request = hdd_request_get(context);
16039 if (!request) {
16040 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Obsolete request"));
16041 return;
16042 }
16043
16044 priv = hdd_request_priv(request);
16045 priv->status = true;
16046
16047 hdd_request_complete(request);
16048 hdd_request_put(request);
c_manjeecfd1efb2015-09-25 19:32:34 +053016049}
16050
Mahesh A Saptasagar67ab9222015-10-21 15:38:41 +053016051void hdd_initialize_adapter_common(hdd_adapter_t *pAdapter)
16052{
16053 if (NULL == pAdapter)
16054 {
16055 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: pAdapter is NULL ", __func__);
16056 return;
16057 }
16058 init_completion(&pAdapter->session_open_comp_var);
16059 init_completion(&pAdapter->session_close_comp_var);
16060 init_completion(&pAdapter->disconnect_comp_var);
16061 init_completion(&pAdapter->linkup_event_var);
16062 init_completion(&pAdapter->cancel_rem_on_chan_var);
16063 init_completion(&pAdapter->rem_on_chan_ready_event);
16064 init_completion(&pAdapter->pno_comp_var);
16065#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
16066 init_completion(&pAdapter->offchannel_tx_event);
16067#endif
16068 init_completion(&pAdapter->tx_action_cnf_event);
16069#ifdef FEATURE_WLAN_TDLS
16070 init_completion(&pAdapter->tdls_add_station_comp);
16071 init_completion(&pAdapter->tdls_del_station_comp);
16072 init_completion(&pAdapter->tdls_mgmt_comp);
16073 init_completion(&pAdapter->tdls_link_establish_req_comp);
16074#endif
16075
16076#ifdef WLAN_FEATURE_RMC
16077 init_completion(&pAdapter->ibss_peer_info_comp);
16078#endif /* WLAN_FEATURE_RMC */
16079 init_completion(&pAdapter->ula_complete);
16080 init_completion(&pAdapter->change_country_code);
16081
16082#ifdef FEATURE_WLAN_BATCH_SCAN
16083 init_completion(&pAdapter->hdd_set_batch_scan_req_var);
16084 init_completion(&pAdapter->hdd_get_batch_scan_req_var);
16085#endif
Kapil Gupta2b44acb2016-12-30 16:49:51 +053016086 init_completion(&pAdapter->wlan_suspend_comp_var);
Mahesh A Saptasagar67ab9222015-10-21 15:38:41 +053016087
16088 return;
16089}
c_manjeecfd1efb2015-09-25 19:32:34 +053016090
Anurag Chouhan0b29de02016-12-16 13:18:40 +053016091#ifdef MDNS_OFFLOAD
16092
16093/**
16094 * hdd_mdns_enable_offload_done() - mdns enable offload response api
16095 * @padapter: holds adapter
16096 * @status: response status
16097 *
16098 * Return - None
16099 */
16100void hdd_mdns_enable_offload_done(void *padapter, VOS_STATUS status)
16101{
16102 hdd_adapter_t* adapter = (hdd_adapter_t*) padapter;
16103
16104 ENTER();
16105
16106 if (NULL == adapter)
16107 {
16108 hddLog(VOS_TRACE_LEVEL_ERROR,
16109 "%s: adapter is NULL",__func__);
16110 return;
16111 }
16112
16113 adapter->mdns_status.mdns_enable_status = status;
16114 vos_event_set(&adapter->mdns_status.vos_event);
16115 return;
16116}
16117
16118/**
16119 * hdd_mdns_fqdn_offload_done() - mdns fqdn offload response api
16120 * @padapter: holds adapter
16121 * @status: responce status
16122 *
16123 * Return - None
16124 */
16125void hdd_mdns_fqdn_offload_done(void *padapter, VOS_STATUS status)
16126{
16127 hdd_adapter_t* adapter = (hdd_adapter_t*) padapter;
16128
16129 ENTER();
16130
16131 if (NULL == adapter)
16132 {
16133 hddLog(VOS_TRACE_LEVEL_ERROR,
16134 "%s: adapter is NULL",__func__);
16135 return;
16136 }
16137
16138 adapter->mdns_status.mdns_fqdn_status = status;
16139 return;
16140}
16141
16142/**
16143 * hdd_mdns_resp_offload_done() - mdns resp offload response api
16144 * @padapter: holds adapter
16145 * @status: responce status
16146 *
16147 * Return - None
16148 */
16149void hdd_mdns_resp_offload_done(void *padapter, VOS_STATUS status)
16150{
16151 hdd_adapter_t* adapter = (hdd_adapter_t*) padapter;
16152
16153 ENTER();
16154
16155 if (NULL == adapter)
16156 {
16157 hddLog(VOS_TRACE_LEVEL_ERROR,
16158 "%s: adapter is NULL",__func__);
16159 return;
16160 }
16161
16162 adapter->mdns_status.mdns_resp_status = status;
16163 return;
16164}
16165
16166/**
16167 * wlan_hdd_mdns_process_response_dname() - Process mDNS domain name
16168 * @response: Pointer to a struct hdd_mdns_resp_info
16169 * @resp_info: Pointer to a struct tSirMDNSResponseInfo
16170 *
16171 * This function will pack the whole domain name without compression. It will
16172 * add the leading len for each field and add zero length octet to terminate
16173 * the domain name.
16174 *
16175 * Return: Return boolean. TRUE for success, FALSE for fail.
16176 */
16177static bool
16178wlan_hdd_mdns_process_response_dname(struct hdd_mdns_resp_info *response,
16179 sir_mdns_resp_info resp_info)
16180{
16181 uint8_t num;
16182 uint16_t idx;
16183 uint8_t len = 0;
16184
16185 if ((response == NULL) || (response->data == NULL) ||
16186 (response->offset == NULL)) {
16187 hddLog(LOGE, FL("Either data or offset in response is NULL!"));
16188 return FALSE;
16189 }
16190
16191 if ((resp_info == NULL) ||
16192 (resp_info->resp_len >= MAX_MDNS_RESP_LEN)) {
16193 hddLog(LOGE, FL("resp_len exceeds %d!"), MAX_MDNS_RESP_LEN);
16194 return FALSE;
16195 }
16196
16197 for (num = 0; num < response->num_entries; num++) {
16198 response->offset[num] =
16199 resp_info->resp_len + MDNS_HEADER_LEN;
16200 idx = num * MAX_LEN_DOMAINNAME_FIELD;
16201 len = strlen((char *)&response->data[idx]);
16202 if ((resp_info->resp_len + len + 1) >= MAX_MDNS_RESP_LEN) {
16203 hddLog(LOGE, FL("resp_len exceeds %d!"),
16204 MAX_MDNS_RESP_LEN);
16205 return FALSE;
16206 }
16207 resp_info->resp_data[resp_info->resp_len] = len;
16208 resp_info->resp_len++;
16209 vos_mem_copy(&resp_info->resp_data[resp_info->resp_len],
16210 &response->data[idx], len);
16211 resp_info->resp_len += len;
16212 }
16213
16214 /* The domain name terminates with the zero length octet */
16215 if (num == response->num_entries) {
16216 if (resp_info->resp_len >= MAX_MDNS_RESP_LEN) {
16217 hddLog(LOGE, FL("resp_len exceeds %d!"),
16218 MAX_MDNS_RESP_LEN);
16219 return FALSE;
16220 }
16221 resp_info->resp_data[resp_info->resp_len] = 0;
16222 resp_info->resp_len++;
16223 }
16224
16225 return TRUE;
16226}
16227
16228/**
16229 * wlan_hdd_mdns_format_response_u16() - Form uint16_t response data
16230 * @value: The uint16_t value is formed to the struct tSirMDNSResponseInfo
16231 * @resp_info: Pointer to a struct tSirMDNSResponseInfo
16232 *
16233 * Return: None
16234 */
16235static void wlan_hdd_mdns_format_response_u16(uint16_t value,
16236 sir_mdns_resp_info resp_info)
16237{
16238 uint8_t val_u8;
16239
16240 if ((resp_info == NULL) || (resp_info->resp_data == NULL))
16241 return;
16242 val_u8 = (value & 0xff00) >> 8;
16243 resp_info->resp_data[resp_info->resp_len++] = val_u8;
16244 val_u8 = value & 0xff;
16245 resp_info->resp_data[resp_info->resp_len++] = val_u8;
16246}
16247
16248/**
16249 * wlan_hdd_mdns_format_response_u32() - Form uint32_t response data
16250 * @value: The uint32_t value is formed to the struct tSirMDNSResponseInfo
16251 * @resp_info: Pointer to a struct tSirMDNSResponseInfo
16252 *
16253 * Return: None
16254 */
16255static void wlan_hdd_mdns_format_response_u32(uint32_t value,
16256 sir_mdns_resp_info resp_info)
16257{
16258 uint8_t val_u8;
16259
16260 if ((resp_info == NULL) || (resp_info->resp_data == NULL))
16261 return;
16262 val_u8 = (value & 0xff000000) >> 24;
16263 resp_info->resp_data[resp_info->resp_len++] = val_u8;
16264 val_u8 = (value & 0xff0000) >> 16;
16265 resp_info->resp_data[resp_info->resp_len++] = val_u8;
16266 val_u8 = (value & 0xff00) >> 8;
16267 resp_info->resp_data[resp_info->resp_len++] = val_u8;
16268 val_u8 = value & 0xff;
16269 resp_info->resp_data[resp_info->resp_len++] = val_u8;
16270}
16271
16272/**
16273 * wlan_hdd_mdns_process_response_misc() - Process misc info in mDNS response
16274 * @resp_type: Response type for mDNS
16275 * @resp_info: Pointer to a struct tSirMDNSResponseInfo
16276 *
16277 * This function will pack the response type, class and TTL (Time To Live).
16278 *
16279 * Return: Return boolean. TRUE for success, FALSE for fail.
16280 */
16281static bool wlan_hdd_mdns_process_response_misc(uint16_t resp_type,
16282 sir_mdns_resp_info resp_info)
16283{
16284 uint16_t len;
16285
16286 if (resp_info == NULL) {
16287 hddLog(LOGE, FL("resp_info is NULL!"));
16288 return FALSE;
16289 }
16290
16291 len = resp_info->resp_len + (2 * sizeof(uint16_t) + sizeof(uint32_t));
16292 if (len >= MAX_MDNS_RESP_LEN) {
16293 hddLog(LOGE, FL("resp_len exceeds %d!"), MAX_MDNS_RESP_LEN);
16294 return FALSE;
16295 }
16296
16297 /* Fill Type, Class, TTL */
16298 wlan_hdd_mdns_format_response_u16(resp_type, resp_info);
16299 wlan_hdd_mdns_format_response_u16(MDNS_CLASS, resp_info);
16300 wlan_hdd_mdns_format_response_u32(MDNS_TTL, resp_info);
16301
16302 return TRUE;
16303}
16304
16305/**
16306 * wlan_hdd_mdns_compress_data() - Compress the domain name in mDNS response
16307 * @resp_info: Pointer to a struct tSirMDNSResponseInfo
16308 * @response_dst: The response which domain name is compressed.
16309 * @response_src: The response which domain name is matched with response_dst.
16310 * Its offset is used for data compression.
16311 * @num_matched: The number of matched entries between response_dst and
16312 * response_src
16313 *
16314 * This function will form the different fields of domain name in response_dst
16315 * if any. Then use the offset of the matched domain name in response_src to
16316 * compress the matched domain name.
16317 *
16318 * Return: Return boolean. TRUE for success, FALSE for fail.
16319 */
16320static bool
16321wlan_hdd_mdns_compress_data(sir_mdns_resp_info resp_info,
16322 struct hdd_mdns_resp_info *response_dst,
16323 struct hdd_mdns_resp_info *response_src,
16324 uint8_t num_matched)
16325{
16326 uint8_t num, num_diff;
16327 uint16_t value, idx;
16328 uint8_t len = 0;
16329
16330 if ((response_src == NULL) || (response_dst == NULL) ||
16331 (resp_info == NULL)) {
16332 hddLog(LOGE, FL("response info is NULL!"));
16333 return FALSE;
16334 }
16335
16336 if (response_dst->num_entries < num_matched) {
16337 hddLog(LOGE, FL("num_entries is less than num_matched!"));
16338 return FALSE;
16339 }
16340
16341 if (resp_info->resp_len >= MAX_MDNS_RESP_LEN) {
16342 hddLog(LOGE, FL("resp_len exceeds %d!"), MAX_MDNS_RESP_LEN);
16343 return FALSE;
16344 }
16345
16346 num_diff = response_dst->num_entries - num_matched;
16347 if ((num_diff > 0) && (response_dst->data == NULL)) {
16348 hddLog(LOGE, FL("response_dst->data is NULL!"));
16349 return FALSE;
16350 }
16351
16352 /*
16353 * Handle the unmatched string at the beginning
16354 * Store the length of octets and the octets
16355 */
16356 for (num = 0; num < num_diff; num++) {
16357 response_dst->offset[num] =
16358 resp_info->resp_len + MDNS_HEADER_LEN;
16359 idx = num * MAX_LEN_DOMAINNAME_FIELD;
16360 len = strlen((char *)&response_dst->data[idx]);
16361 if ((resp_info->resp_len + len + 1) >= MAX_MDNS_RESP_LEN) {
16362 hddLog(LOGE, FL("resp_len exceeds %d!"),
16363 MAX_MDNS_RESP_LEN);
16364 return FALSE;
16365 }
16366 resp_info->resp_data[resp_info->resp_len] = len;
16367 resp_info->resp_len++;
16368 vos_mem_copy(&resp_info->resp_data[resp_info->resp_len],
16369 &response_dst->data[idx], len);
16370 resp_info->resp_len += len;
16371 }
16372 /*
16373 * Handle the matched string from the end
16374 * Just keep the offset and mask the leading two bit
16375 */
16376 if (response_src->num_entries >= num_matched) {
16377 num_diff = response_src->num_entries - num_matched;
16378 value = response_src->offset[num_diff];
16379 if (value > 0) {
16380 value |= 0xc000;
16381 if ((resp_info->resp_len + sizeof(uint16_t)) >=
16382 MAX_MDNS_RESP_LEN) {
16383 hddLog(LOGE, FL("resp_len exceeds %d!"),
16384 MAX_MDNS_RESP_LEN);
16385 return FALSE;
16386 }
16387 wlan_hdd_mdns_format_response_u16(value, resp_info);
16388 return TRUE;
16389 }
16390 }
16391 return FALSE;
16392}
16393
16394/**
16395 * wlan_hdd_mdns_reset_response() - Reset the response info
16396 * @response: The response which info is reset.
16397 *
16398 * Return: None
16399 */
16400static void wlan_hdd_mdns_reset_response(struct hdd_mdns_resp_info *response)
16401{
16402 if (response == NULL)
16403 return;
16404 response->num_entries = 0;
16405 response->data = NULL;
16406 response->offset = NULL;
16407}
16408
16409/**
16410 * wlan_hdd_mdns_init_response() - Initialize the response info
16411 * @response: The response which info is initiatized.
16412 * @resp_dname: The domain name string which might be tokenized.
16413 *
16414 * This function will allocate the memory for both response->data and
16415 * response->offset. Besides, it will also tokenize the domain name to some
16416 * entries and fill response->num_entries with the num of entries.
16417 *
16418 * Return: Return boolean. TRUE for success, FALSE for fail.
16419 */
16420static bool wlan_hdd_mdns_init_response(struct hdd_mdns_resp_info *response,
16421 uint8_t *resp_dname, char separator)
16422{
16423 uint16_t size;
16424
16425 if ((resp_dname == NULL) || (response == NULL)) {
16426 hddLog(LOGE, FL("resp_dname or response is NULL!"));
16427 return FALSE;
16428 }
16429
16430 size = MAX_NUM_FIELD_DOMAINNAME * MAX_LEN_DOMAINNAME_FIELD;
16431 response->data = vos_mem_malloc(size);
16432 if (response->data) {
16433 vos_mem_zero(response->data, size);
16434 if (VOS_STATUS_SUCCESS !=
16435 hdd_string_to_string_array((char *)resp_dname,
16436 response->data,
16437 separator,
16438 &response->num_entries,
16439 MAX_NUM_FIELD_DOMAINNAME,
16440 MAX_LEN_DOMAINNAME_FIELD)) {
16441 hddLog(LOGE, FL("hdd_string_to_string_array fail!"));
16442 goto err_init_resp;
16443 }
16444
16445 if ((response->num_entries > 0) &&
16446 (strlen((char *)&response->data[0]) > 0)) {
16447 size = sizeof(uint16_t) * response->num_entries;
16448 response->offset = vos_mem_malloc(size);
16449 if (response->offset) {
16450 vos_mem_zero(response->offset, size);
16451 return TRUE;
16452 }
16453 }
16454 }
16455
16456err_init_resp:
16457 if (response->data)
16458 vos_mem_free(response->data);
16459 wlan_hdd_mdns_reset_response(response);
16460 return FALSE;
16461}
16462
16463/**
16464 * wlan_hdd_mdns_find_entries_from_end() - Find the matched entries
16465 * @response1: The response info is used to be compared.
16466 * @response2: The response info is used to be compared.
16467 *
16468 * This function will find the matched entries from the end.
16469 *
16470 * Return: Return the number of the matched entries.
16471 */
16472static uint8_t
16473wlan_hdd_mdns_find_entries_from_end(struct hdd_mdns_resp_info *response1,
16474 struct hdd_mdns_resp_info *response2)
16475{
16476 uint8_t min, len1, i;
16477 uint16_t num1, num2;
16478 uint8_t num_matched = 0;
16479
16480 min = VOS_MIN(response1->num_entries, response2->num_entries);
16481
16482 for (i = 1; i <= min; i++) {
16483 num1 = (response1->num_entries - i);
16484 num1 *= MAX_LEN_DOMAINNAME_FIELD;
16485 num2 = (response2->num_entries - i);
16486 num2 *= MAX_LEN_DOMAINNAME_FIELD;
16487 len1 = strlen((char *)&response1->data[num1]);
16488
16489 if ((len1 == 0) ||
16490 (len1 != strlen((char *)&response2->data[num2])))
16491 break;
16492 if (memcmp(&response1->data[num1],
16493 &response2->data[num2], len1))
16494 break;
16495 else
16496 num_matched++;
16497 }
16498
16499 return num_matched;
16500}
16501
16502/**
16503 * wlan_hdd_mdns_find_max() - Find the maximum number of the matched entries
16504 * @matchedlist: Pointer to the array of struct hdd_mdns_resp_matched
16505 * @numlist: The number of the elements in the array matchedlist.
16506 *
16507 * Find the max number of the matched entries among the array matchedlist.
16508 *
16509 * Return: None
16510 */
16511static void wlan_hdd_mdns_find_max(struct hdd_mdns_resp_matched *matchedlist,
16512 uint8_t numlist)
16513{
16514 int j;
16515 struct hdd_mdns_resp_matched tmp;
16516
16517 /* At least two values are used for sorting */
16518 if ((numlist < 2) || (matchedlist == NULL)) {
16519 hddLog(LOGE, FL("At least two values are used for sorting!"));
16520 return;
16521 }
16522
16523 for (j = 0; j < numlist-1; j++) {
16524 if (matchedlist[j].num_matched >
16525 matchedlist[j+1].num_matched) {
16526 vos_mem_copy(&tmp, &matchedlist[j],
16527 sizeof(struct hdd_mdns_resp_matched));
16528 vos_mem_copy(&matchedlist[j], &matchedlist[j+1],
16529 sizeof(struct hdd_mdns_resp_matched));
16530 vos_mem_copy(&matchedlist[j+1], &tmp,
16531 sizeof(struct hdd_mdns_resp_matched));
16532 }
16533 }
16534}
16535
16536/**
16537 * wlan_hdd_mdns_pack_response_type_a() - Pack Type A response
16538 * @ini_config: Pointer to the struct hdd_config_t
16539 * @resp_info: Pointer to the struct tSirMDNSResponseInfo
16540 * @resptype_a: Pointer to the struct hdd_mdns_resp_info of Type A
16541 *
16542 * Type A response include QName, response type, class, TTL and Ipv4.
16543 *
16544 * Return: Return boolean. TRUE for success, FALSE for fail.
16545 */
16546static bool
16547wlan_hdd_mdns_pack_response_type_a(hdd_config_t *ini_config,
16548 sir_mdns_resp_info resp_info,
16549 struct hdd_mdns_resp_info *resptype_a)
16550{
16551 uint16_t value;
16552 uint32_t len;
16553
16554 ENTER();
16555 if ((ini_config == NULL) || (resp_info == NULL) ||
16556 (resptype_a == NULL)) {
16557 hddLog(LOGE, FL("ini_config or response info is NULL!"));
16558 return FALSE;
16559 }
16560
16561 /* No Type A response */
16562 if (strlen((char *)ini_config->mdns_resp_type_a) <= 0)
16563 return TRUE;
16564
16565 /* Wrong response is assigned, just ignore this response */
16566 if (!wlan_hdd_mdns_init_response(resptype_a,
16567 ini_config->mdns_resp_type_a, '.'))
16568 return TRUE;
16569
16570 /* Process response domain name */
16571 if (!wlan_hdd_mdns_process_response_dname(resptype_a, resp_info)) {
16572 hddLog(LOGE, FL("Fail to process mDNS response (%d)!"),
16573 MDNS_TYPE_A);
16574 return FALSE;
16575 }
16576
16577 /* Process response Type, Class, TTL */
16578 if (!wlan_hdd_mdns_process_response_misc(MDNS_TYPE_A, resp_info)) {
16579 hddLog(LOGE, FL("Fail to process mDNS misc response (%d)!"),
16580 MDNS_TYPE_A);
16581 return FALSE;
16582 }
16583
16584 /* Process response RDLength, RData */
16585 len = sizeof(uint16_t) + sizeof(uint32_t);
16586 len += resp_info->resp_len;
16587 if (len >= MAX_MDNS_RESP_LEN) {
16588 hddLog(LOGE, FL("resp_len exceeds %d!"), MAX_MDNS_RESP_LEN);
16589 return FALSE;
16590 }
16591 value = sizeof(uint32_t);
16592 wlan_hdd_mdns_format_response_u16(value, resp_info);
16593 wlan_hdd_mdns_format_response_u32(ini_config->mdns_resp_type_a_ipv4,
16594 resp_info);
16595
16596 EXIT();
16597 return TRUE;
16598}
16599
16600/**
16601 * wlan_hdd_mdns_pack_response_type_txt() - Pack Type Txt response
16602 * @ini_config: Pointer to the struct hdd_config_t
16603 * @resp_info: Pointer to the struct tSirMDNSResponseInfo
16604 * @resptype_txt: Pointer to the struct hdd_mdns_resp_info of Type txt
16605 * @resptype_a: Pointer to the struct hdd_mdns_resp_info of Type A
16606 *
16607 * Type Txt response include QName, response type, class, TTL and text content.
16608 * Also, it will find the matched QName from resptype_A and compress the data.
16609 *
16610 * Return: Return boolean. TRUE for success, FALSE for fail.
16611 */
16612static bool
16613wlan_hdd_mdns_pack_response_type_txt(hdd_config_t *ini_config,
16614 sir_mdns_resp_info resp_info,
16615 struct hdd_mdns_resp_info *resptype_txt,
16616 struct hdd_mdns_resp_info *resptype_a)
16617{
16618 uint8_t num_matched;
16619 uint8_t num;
16620 uint16_t idx;
16621 uint16_t value = 0;
16622 uint32_t len;
16623 uint32_t total_len;
16624 bool status;
16625 struct hdd_mdns_resp_info resptype_content;
16626
16627 ENTER();
16628
16629 if ((ini_config == NULL) || (resp_info == NULL) ||
16630 (resptype_txt == NULL)) {
16631 hddLog(LOGE, FL("ini_config or response info is NULL!"));
16632 return FALSE;
16633 }
16634
16635 /* No Type Txt response */
16636 if (strlen((char *)ini_config->mdns_resp_type_txt) <= 0)
16637 return TRUE;
16638
16639 /* Wrong response is assigned, just ignore this response */
16640 if (!wlan_hdd_mdns_init_response(resptype_txt,
16641 ini_config->mdns_resp_type_txt, '.'))
16642 return TRUE;
16643
16644 /*
16645 * For data compression
16646 * Check if any strings are matched with Type A response
16647 */
16648 if (resptype_a && (resptype_a->num_entries > 0)) {
16649 num_matched = wlan_hdd_mdns_find_entries_from_end(resptype_txt,
16650 resptype_a);
16651 if (num_matched > 0) {
16652 if (!wlan_hdd_mdns_compress_data(resp_info,
16653 resptype_txt, resptype_a, num_matched)) {
16654 hddLog(LOGE, FL("Fail to compress mDNS "
16655 "response (%d)!"), MDNS_TYPE_TXT);
16656 return FALSE;
16657 }
16658 } else {
16659 /*
16660 * num_matched is zero. Error!
16661 * At least ".local" is needed.
16662 */
16663 hddLog(LOGE, FL("No matched string! Fail to pack mDNS "
16664 "response (%d)!"), MDNS_TYPE_TXT);
16665 return FALSE;
16666 }
16667 } else {
16668 /* no TypeA response, so show the whole data */
16669 if (!wlan_hdd_mdns_process_response_dname(resptype_txt,
16670 resp_info)) {
16671 hddLog(LOGE, FL("Fail to process mDNS response (%d)!"),
16672 MDNS_TYPE_TXT);
16673 return FALSE;
16674 }
16675 }
16676
16677 /* Process response Type, Class, TTL */
16678 if (!wlan_hdd_mdns_process_response_misc(MDNS_TYPE_TXT, resp_info)) {
16679 hddLog(LOGE, FL("Fail to process mDNS misc response (%d)!"),
16680 MDNS_TYPE_TXT);
16681 return FALSE;
16682 }
16683
16684 /*
16685 * Process response RDLength, RData.
16686 * TypeTxt RData include len.
16687 */
16688 status = wlan_hdd_mdns_init_response(&resptype_content,
16689 ini_config->mdns_resp_type_txt_content,
16690 '/');
16691 if (status == FALSE) {
16692 hddLog(LOGE, FL("wlan_hdd_mdns_init_response FAIL"));
16693 return FALSE;
16694 }
16695
16696 for (num = 0; num < resptype_content.num_entries; num++) {
16697 idx = num * MAX_LEN_DOMAINNAME_FIELD;
16698 value += strlen((char *)&resptype_content.data[idx]);
16699 }
16700
16701 /* content len is uint16_t */
16702 total_len = sizeof(uint16_t);
16703 total_len += resp_info->resp_len + value +
16704 resptype_content.num_entries;
16705
16706 if (total_len >= MAX_MDNS_RESP_LEN) {
16707 hddLog(LOGE, FL("resp_len exceeds %d!"), MAX_MDNS_RESP_LEN);
16708 return FALSE;
16709 }
16710 wlan_hdd_mdns_format_response_u16(value + resptype_content.num_entries,
16711 resp_info);
16712
16713 for (num = 0; num < resptype_content.num_entries; num++) {
16714 idx = num * MAX_LEN_DOMAINNAME_FIELD;
16715 len = strlen((char *)&resptype_content.data[idx]);
16716 resp_info->resp_data[resp_info->resp_len] = len;
16717 resp_info->resp_len++;
16718
16719 vos_mem_copy(&resp_info->resp_data[resp_info->resp_len],
16720 &resptype_content.data[idx], len);
16721
16722 resp_info->resp_len += len;
16723 hddLog(LOG1, FL("index = %d, len = %d, str = %s"),
16724 num, len, &resptype_content.data[idx]);
16725 }
16726
16727 EXIT();
16728 return TRUE;
16729}
16730
16731/**
16732 * wlan_hdd_mdns_pack_response_type_ptr_dname() - Pack Type PTR domain name
16733 * @ini_config: Pointer to the struct hdd_config_t
16734 * @resp_info: Pointer to the struct tSirMDNSResponseInfo
16735 * @resptype_ptr_dn: Pointer to the struct hdd_mdns_resp_info of Type Ptr
16736 * domain name
16737 * @resptype_ptr: Pointer to the struct hdd_mdns_resp_info of Type Ptr
16738 * @resptype_txt: Pointer to the struct hdd_mdns_resp_info of Type Txt
16739 * @resptype_a: Pointer to the struct hdd_mdns_resp_info of Type A
16740 *
16741 * The Type Ptr response include Type PTR domain name in its data field.
16742 * Also, it will find the matched QName from the existing resptype_ptr,
16743 * resptype_txt, resptype_a and then compress the data.
16744 *
16745 * Return: Return boolean. TRUE for success, FALSE for fail.
16746 */
16747static bool
16748wlan_hdd_mdns_pack_response_type_ptr_dname(hdd_config_t *ini_config,
16749 sir_mdns_resp_info resp_info,
16750 struct hdd_mdns_resp_info *resptype_ptr_dn,
16751 struct hdd_mdns_resp_info *resptype_ptr,
16752 struct hdd_mdns_resp_info *resptype_txt,
16753 struct hdd_mdns_resp_info *resptype_a)
16754{
16755 uint8_t num_matched, numlist, size;
16756 struct hdd_mdns_resp_matched matchedlist[MAX_MDNS_RESP_TYPE-1];
16757 struct hdd_mdns_resp_info *resp;
16758
16759 if ((ini_config == NULL) || (resp_info == NULL) ||
16760 (resptype_ptr == NULL) || (resptype_ptr_dn == NULL)) {
16761 hddLog(LOGE, FL("ini_config or response info is NULL!"));
16762 return FALSE;
16763 }
16764
16765 /* No Type Ptr domain name response */
16766 if (strlen((char *)ini_config->mdns_resp_type_ptr_dname) <= 0)
16767 return TRUE;
16768
16769 /* Wrong response is assigned, just ignore this response */
16770 if (!wlan_hdd_mdns_init_response(resptype_ptr_dn,
16771 ini_config->mdns_resp_type_ptr_dname, '.'))
16772 return TRUE;
16773
16774 /*
16775 * For data compression
16776 * Check if any strings are matched with previous
16777 * response.
16778 */
16779 numlist = 0;
16780 size = (MAX_MDNS_RESP_TYPE-1);
16781 size *= sizeof(struct hdd_mdns_resp_matched);
16782 vos_mem_zero(matchedlist, size);
16783 num_matched = wlan_hdd_mdns_find_entries_from_end(resptype_ptr_dn,
16784 resptype_ptr);
16785 if (num_matched > 0) {
16786 matchedlist[numlist].num_matched = num_matched;
16787 matchedlist[numlist].type = MDNS_TYPE_PTR;
16788 numlist++;
16789 }
16790 if (resptype_txt && (resptype_txt->num_entries > 0)) {
16791 num_matched = wlan_hdd_mdns_find_entries_from_end(
16792 resptype_ptr_dn, resptype_txt);
16793 if (num_matched > 0) {
16794 matchedlist[numlist].num_matched = num_matched;
16795 matchedlist[numlist].type = MDNS_TYPE_TXT;
16796 numlist++;
16797 }
16798 }
16799 if (resptype_a && (resptype_a->num_entries > 0)) {
16800 num_matched = wlan_hdd_mdns_find_entries_from_end(
16801 resptype_ptr_dn,resptype_a);
16802 if (num_matched > 0) {
16803 matchedlist[numlist].num_matched = num_matched;
16804 matchedlist[numlist].type = MDNS_TYPE_A;
16805 numlist++;
16806 }
16807 }
16808 if (numlist > 0) {
16809 if (numlist > 1)
16810 wlan_hdd_mdns_find_max(matchedlist, numlist);
16811 resp = NULL;
16812 switch (matchedlist[numlist-1].type) {
16813 case MDNS_TYPE_A:
16814 resp = resptype_a;
16815 break;
16816 case MDNS_TYPE_TXT:
16817 resp = resptype_txt;
16818 break;
16819 case MDNS_TYPE_PTR:
16820 resp = resptype_ptr;
16821 break;
16822 default:
16823 hddLog(LOGE, FL("Fail to compress mDNS response "
16824 "(%d)!"), MDNS_TYPE_PTR_DNAME);
16825 return FALSE;
16826 }
16827 num_matched = matchedlist[numlist-1].num_matched;
16828 if (!wlan_hdd_mdns_compress_data(resp_info, resptype_ptr_dn,
16829 resp, num_matched)) {
16830 hddLog(LOGE, FL("Fail to compress mDNS response "
16831 "(%d)!"), MDNS_TYPE_PTR_DNAME);
16832 return FALSE;
16833 }
16834 } else {
16835 /* num = 0 -> no matched string */
16836 if (!wlan_hdd_mdns_process_response_dname(resptype_ptr_dn,
16837 resp_info)) {
16838 hddLog(LOGE, FL("Fail to process mDNS response (%d)!"),
16839 MDNS_TYPE_PTR_DNAME);
16840 return FALSE;
16841 }
16842 }
16843
16844 return TRUE;
16845}
16846
16847/**
16848 * wlan_hdd_mdns_pack_response_type_ptr() - Pack Type PTR response
16849 * @ini_config: Pointer to the struct hdd_config_t
16850 * @resp_info: Pointer to the struct tSirMDNSResponseInfo
16851 * @resptype_ptr: Pointer to the struct hdd_mdns_resp_info of Type Ptr
16852 * @resptype_ptr_dn: Pointer to the struct hdd_mdns_resp_info of Type Ptr
16853 * domain name
16854 * @resptype_txt: Pointer to the struct hdd_mdns_resp_info of Type Txt
16855 * @resptype_a: Pointer to the struct hdd_mdns_resp_info of Type A
16856 *
16857 * The Type Ptr response include QName, response type, class, TTL and
16858 * Type PTR domain name. Also, it will find the matched QName from the
16859 * existing resptype_txt, resptype_a and then compress the data.
16860 *
16861 * Return: Return boolean. TRUE for success, FALSE for fail.
16862 */
16863static bool
16864wlan_hdd_mdns_pack_response_type_ptr(hdd_config_t *ini_config,
16865 sir_mdns_resp_info resp_info,
16866 struct hdd_mdns_resp_info *resptype_ptr,
16867 struct hdd_mdns_resp_info *resptype_ptr_dn,
16868 struct hdd_mdns_resp_info *resptype_txt,
16869 struct hdd_mdns_resp_info *resptype_a)
16870{
16871 uint8_t num_matched, num_matched1;
16872 uint16_t value;
16873 uint8_t val_u8;
16874 uint32_t offset_data_len, len;
16875
16876 ENTER();
16877 if ((ini_config == NULL) || (resp_info == NULL) ||
16878 (resptype_ptr == NULL) || (resptype_ptr_dn == NULL)) {
16879 hddLog(LOGE, FL("ini_config or response info is NULL!"));
16880 return FALSE;
16881 }
16882
16883 /* No Type Ptr response */
16884 if (strlen((char *)ini_config->mdns_resp_type_ptr) <= 0)
16885 return TRUE;
16886
16887 /* Wrong response is assigned, just ignore this response */
16888 if (!wlan_hdd_mdns_init_response(resptype_ptr,
16889 ini_config->mdns_resp_type_ptr, '.'))
16890 return TRUE;
16891
16892 /*
16893 * For data compression
16894 * Check if any strings are matched with Type A response
16895 */
16896 num_matched = 0;
16897 num_matched1 = 0;
16898 if (resptype_a && (resptype_a->num_entries > 0)) {
16899 num_matched = wlan_hdd_mdns_find_entries_from_end(resptype_ptr,
16900 resptype_a);
16901 }
16902 if (resptype_txt && (resptype_txt->num_entries > 0)) {
16903 num_matched1 = wlan_hdd_mdns_find_entries_from_end(
16904 resptype_ptr, resptype_txt);
16905 }
16906 if ((num_matched != num_matched1) ||
16907 ((num_matched > 0) && (num_matched1 > 0))) {
16908 if (num_matched >= num_matched1) {
16909 if (!wlan_hdd_mdns_compress_data(resp_info,
16910 resptype_ptr, resptype_a, num_matched)) {
16911 hddLog(LOGE, FL("Fail to compress mDNS "
16912 "response (%d)!"), MDNS_TYPE_PTR);
16913 return FALSE;
16914 }
16915 } else {
16916 /* num_matched is less than num_matched1 */
16917 if (!wlan_hdd_mdns_compress_data(resp_info,
16918 resptype_ptr, resptype_txt, num_matched1)) {
16919 hddLog(LOGE, FL("Fail to compress mDNS "
16920 "response (%d)!"), MDNS_TYPE_PTR);
16921 return FALSE;
16922 }
16923 }
16924 } else {
16925 /*
16926 * Both num_matched and num_matched1 are zero.
16927 * no TypeA & TypeTxt
16928 */
16929 if (!wlan_hdd_mdns_process_response_dname(resptype_ptr,
16930 resp_info)) {
16931 hddLog(LOGE, FL("Fail to process mDNS response (%d)!"),
16932 MDNS_TYPE_PTR);
16933 return FALSE;
16934 }
16935 }
16936
16937 /* Process response Type, Class, TTL */
16938 if (!wlan_hdd_mdns_process_response_misc(MDNS_TYPE_PTR, resp_info)) {
16939 hddLog(LOGE, FL("Fail to process mDNS misc response (%d)!"),
16940 MDNS_TYPE_PTR);
16941 return FALSE;
16942 }
16943
16944 /*
16945 * Process response RDLength, RData (Ptr domain name)
16946 * Save the offset of RData length
16947 */
16948 offset_data_len = resp_info->resp_len;
16949 resp_info->resp_len += sizeof(uint16_t);
16950
16951 if (!wlan_hdd_mdns_pack_response_type_ptr_dname(ini_config, resp_info,
16952 resptype_ptr_dn, resptype_ptr,
16953 resptype_txt, resptype_a)) {
16954 return FALSE;
16955 }
16956 /* Set the RData length */
16957 len = offset_data_len + sizeof(uint16_t);
16958 if ((resptype_ptr_dn->num_entries > 0) &&
16959 (resp_info->resp_len > len)) {
16960 value = resp_info->resp_len - len;
16961 val_u8 = (value & 0xff00) >> 8;
16962 resp_info->resp_data[offset_data_len] = val_u8;
16963 val_u8 = value & 0xff;
16964 resp_info->resp_data[offset_data_len+1] = val_u8;
16965 } else {
16966 hddLog(LOGE, FL("Fail to process mDNS response (%d)!"),
16967 MDNS_TYPE_PTR);
16968 return FALSE;
16969 }
16970
16971 EXIT();
16972 return TRUE;
16973}
16974
16975/**
16976 * wlan_hdd_mdns_pack_response_type_srv_target()- Pack Type Service Target
16977 * @ini_config: Pointer to the struct hdd_config_t
16978 * @resp_info: Pointer to the struct tSirMDNSResponseInfo
16979 * @resptype_srv_tgt: Pointer to the struct hdd_mdns_resp_info of Type Srv
16980 * target
16981 * @resptype_srv: Pointer to the struct hdd_mdns_resp_info of Type Srv
16982 * @resptype_ptr: Pointer to the struct hdd_mdns_resp_info of Type Ptr
16983 * @resptype_ptr_dn: Pointer to the struct hdd_mdns_resp_info of Type Ptr
16984 * domain name
16985 * @resptype_txt: Pointer to the struct hdd_mdns_resp_info of Type Txt
16986 * @resptype_a: Pointer to the struct hdd_mdns_resp_info of Type A
16987 *
16988 * The Type service target is one of the data field in the Type SRV response.
16989 * Also, it will find the matched QName from the existing resptype_srv,
16990 * resptype_ptr, resptype_ptr_dn, resptype_txt, resptype_a and then compress
16991 * the data.
16992 *
16993 * Return: Return boolean. TRUE for success, FALSE for fail.
16994 */
16995static bool
16996wlan_hdd_mdns_pack_response_type_srv_target(hdd_config_t *ini_config,
16997 sir_mdns_resp_info resp_info,
16998 struct hdd_mdns_resp_info *resptype_srv_tgt,
16999 struct hdd_mdns_resp_info *resptype_srv,
17000 struct hdd_mdns_resp_info *resptype_ptr,
17001 struct hdd_mdns_resp_info *resptype_ptr_dn,
17002 struct hdd_mdns_resp_info *resptype_txt,
17003 struct hdd_mdns_resp_info *resptype_a)
17004{
17005 uint8_t num_matched, num, size;
17006 struct hdd_mdns_resp_matched matchedlist[MAX_MDNS_RESP_TYPE-1];
17007 struct hdd_mdns_resp_info *resp;
17008
17009 if ((ini_config == NULL) || (resp_info == NULL) ||
17010 (resptype_srv == NULL) || (resptype_srv_tgt == NULL)) {
17011 hddLog(LOGE, FL("ini_config or response info is NULL!"));
17012 return FALSE;
17013 }
17014
17015 /* No Type Srv Target response */
17016 if (strlen((char *)ini_config->mdns_resp_type_srv_target) <= 0)
17017 return TRUE;
17018
17019 /* Wrong response is assigned, just ignore this response */
17020 if (!wlan_hdd_mdns_init_response(resptype_srv_tgt,
17021 ini_config->mdns_resp_type_srv_target, '.'))
17022 return TRUE;
17023
17024 /*
17025 * For data compression
17026 * Check if any strings are matched with previous response.
17027 */
17028 num = 0;
17029 size = (MAX_MDNS_RESP_TYPE-1);
17030 size *= sizeof(struct hdd_mdns_resp_matched);
17031 vos_mem_zero(matchedlist, size);
17032 num_matched = wlan_hdd_mdns_find_entries_from_end(resptype_srv_tgt,
17033 resptype_srv);
17034 if (num_matched > 0) {
17035 matchedlist[num].num_matched = num_matched;
17036 matchedlist[num].type = MDNS_TYPE_SRV;
17037 num++;
17038 }
17039 if (resptype_ptr && (resptype_ptr->num_entries > 0)) {
17040 if (resptype_ptr_dn && (resptype_ptr_dn->num_entries > 0)) {
17041 num_matched = wlan_hdd_mdns_find_entries_from_end(
17042 resptype_srv_tgt, resptype_ptr_dn);
17043 if (num_matched > 0) {
17044 matchedlist[num].num_matched = num_matched;
17045 matchedlist[num].type = MDNS_TYPE_PTR_DNAME;
17046 num++;
17047 }
17048 }
17049 num_matched = wlan_hdd_mdns_find_entries_from_end(
17050 resptype_srv_tgt, resptype_ptr);
17051 if (num_matched > 0) {
17052 matchedlist[num].num_matched = num_matched;
17053 matchedlist[num].type = MDNS_TYPE_PTR;
17054 num++;
17055 }
17056 }
17057 if (resptype_txt && (resptype_txt->num_entries > 0)) {
17058 num_matched = wlan_hdd_mdns_find_entries_from_end(
17059 resptype_srv_tgt, resptype_txt);
17060 if (num_matched > 0) {
17061 matchedlist[num].num_matched = num_matched;
17062 matchedlist[num].type = MDNS_TYPE_TXT;
17063 num++;
17064 }
17065 }
17066 if (resptype_a && (resptype_a->num_entries > 0)) {
17067 num_matched = wlan_hdd_mdns_find_entries_from_end(
17068 resptype_srv_tgt, resptype_a);
17069 if (num_matched > 0) {
17070 matchedlist[num].num_matched = num_matched;
17071 matchedlist[num].type = MDNS_TYPE_A;
17072 num++;
17073 }
17074 }
17075 if (num > 0) {
17076 if (num > 1)
17077 wlan_hdd_mdns_find_max(matchedlist, num);
17078 resp = NULL;
17079 switch (matchedlist[num-1].type) {
17080 case MDNS_TYPE_A:
17081 resp = resptype_a;
17082 break;
17083 case MDNS_TYPE_TXT:
17084 resp = resptype_txt;
17085 break;
17086 case MDNS_TYPE_PTR:
17087 resp = resptype_ptr;
17088 break;
17089 case MDNS_TYPE_PTR_DNAME:
17090 resp = resptype_ptr_dn;
17091 break;
17092 case MDNS_TYPE_SRV:
17093 resp = resptype_srv;
17094 break;
17095 default:
17096 hddLog(LOGE, FL("Fail to compress mDNS response "
17097 "(%d)!"), MDNS_TYPE_SRV_TARGET);
17098 return FALSE;
17099 }
17100 num_matched = matchedlist[num-1].num_matched;
17101 if (!wlan_hdd_mdns_compress_data(resp_info, resptype_srv_tgt,
17102 resp, num_matched)) {
17103 hddLog(LOGE, FL("Fail to compress mDNS response "
17104 "(%d)!"), MDNS_TYPE_SRV_TARGET);
17105 return FALSE;
17106 }
17107 } else {
17108 /* num = 0 -> no matched string */
17109 if (!wlan_hdd_mdns_process_response_dname(resptype_srv_tgt,
17110 resp_info)) {
17111 hddLog(LOGE, FL("Fail to process mDNS response (%d)!"),
17112 MDNS_TYPE_SRV_TARGET);
17113 return FALSE;
17114 }
17115 }
17116
17117 return TRUE;
17118}
17119
17120/**
17121 * wlan_hdd_mdns_pack_response_type_srv()- Pack Type Service response
17122 * @ini_config: Pointer to the struct hdd_config_t
17123 * @resp_info: Pointer to the struct tSirMDNSResponseInfo
17124 * @resptype_srv: Pointer to the struct hdd_mdns_resp_info of Type Srv
17125 * @resptype_srv_tgt: Pointer to the struct hdd_mdns_resp_info of Type Srv
17126 * target
17127 * @resptype_ptr: Pointer to the struct hdd_mdns_resp_info of Type Ptr
17128 * @resptype_ptr_dn: Pointer to the struct hdd_mdns_resp_info of Type Ptr
17129 * domain name
17130 * @resptype_txt: Pointer to the struct hdd_mdns_resp_info of Type Txt
17131 * @resptype_a: Pointer to the struct hdd_mdns_resp_info of Type A
17132 *
17133 * The Type SRV (Service) response include QName, response type, class, TTL
17134 * and four kinds of data fields. Also, it will find the matched QName from
17135 * the existing resptype_ptr, resptype_ptr_dn, resptype_txt, resptype_a and
17136 * then compress the data.
17137 *
17138 * Return: Return boolean. TRUE for success, FALSE for fail.
17139 */
17140static bool
17141wlan_hdd_mdns_pack_response_type_srv(hdd_config_t *ini_config,
17142 sir_mdns_resp_info resp_info,
17143 struct hdd_mdns_resp_info *resptype_srv,
17144 struct hdd_mdns_resp_info *resptype_srv_tgt,
17145 struct hdd_mdns_resp_info *resptype_ptr,
17146 struct hdd_mdns_resp_info *resptype_ptr_dn,
17147 struct hdd_mdns_resp_info *resptype_txt,
17148 struct hdd_mdns_resp_info *resptype_a)
17149{
17150 uint8_t num_matched, num, size;
17151 uint16_t value;
17152 uint8_t val_u8;
17153 uint32_t offset_data_len, len;
17154 struct hdd_mdns_resp_info *resp;
17155 struct hdd_mdns_resp_matched matchedlist[MAX_MDNS_RESP_TYPE-1];
17156
17157 ENTER();
17158
17159 if ((ini_config == NULL) || (resp_info == NULL) ||
17160 (resptype_srv == NULL) || (resptype_srv_tgt == NULL)) {
17161 hddLog(LOGE, FL("ini_config or response info is NULL!"));
17162 return FALSE;
17163 }
17164
17165 /* No Type Srv response */
17166 if (strlen((char *)ini_config->mdns_resp_type_srv) <= 0)
17167 return TRUE;
17168
17169 /* Wrong response is assigned, just ignore this response */
17170 if (!wlan_hdd_mdns_init_response(resptype_srv,
17171 ini_config->mdns_resp_type_srv, '.'))
17172 return TRUE;
17173
17174 /*
17175 * For data compression
17176 * Check if any strings are matched with Type A response
17177 */
17178 num = 0;
17179 size = (MAX_MDNS_RESP_TYPE-1);
17180 size *= sizeof(struct hdd_mdns_resp_matched);
17181 vos_mem_zero(matchedlist, size);
17182 if (resptype_ptr && (resptype_ptr->num_entries > 0)) {
17183 if (resptype_ptr_dn && (resptype_ptr_dn->num_entries > 0)) {
17184 num_matched = wlan_hdd_mdns_find_entries_from_end(
17185 resptype_srv,
17186 resptype_ptr_dn);
17187 if (num_matched > 0) {
17188 matchedlist[num].num_matched = num_matched;
17189 matchedlist[num].type = MDNS_TYPE_PTR_DNAME;
17190 num++;
17191 }
17192 }
17193 num_matched = wlan_hdd_mdns_find_entries_from_end(resptype_srv,
17194 resptype_ptr);
17195 if (num_matched > 0) {
17196 matchedlist[num].num_matched = num_matched;
17197 matchedlist[num].type = MDNS_TYPE_PTR;
17198 num++;
17199 }
17200 }
17201 if (resptype_txt && (resptype_txt->num_entries > 0)) {
17202 num_matched = wlan_hdd_mdns_find_entries_from_end(resptype_srv,
17203 resptype_txt);
17204 if (num_matched > 0) {
17205 matchedlist[num].num_matched =num_matched;
17206 matchedlist[num].type = MDNS_TYPE_TXT;
17207 num++;
17208 }
17209 }
17210 if (resptype_a && (resptype_a->num_entries > 0)) {
17211 num_matched = wlan_hdd_mdns_find_entries_from_end(resptype_srv,
17212 resptype_a);
17213 if (num_matched > 0) {
17214 matchedlist[num].num_matched = num_matched;
17215 matchedlist[num].type = MDNS_TYPE_A;
17216 num++;
17217 }
17218 }
17219 if (num > 0) {
17220 if (num > 1)
17221 wlan_hdd_mdns_find_max(matchedlist, num);
17222 resp = NULL;
17223 switch (matchedlist[num-1].type) {
17224 case MDNS_TYPE_A:
17225 resp = resptype_a;
17226 break;
17227 case MDNS_TYPE_TXT:
17228 resp = resptype_txt;
17229 break;
17230 case MDNS_TYPE_PTR:
17231 resp = resptype_ptr;
17232 break;
17233 case MDNS_TYPE_PTR_DNAME:
17234 resp = resptype_ptr_dn;
17235 break;
17236 default:
17237 hddLog(LOGE, FL("Fail to compress mDNS response "
17238 "(%d)!"), MDNS_TYPE_SRV);
17239 return FALSE;
17240 }
17241 num_matched = matchedlist[num-1].num_matched;
17242 if (!wlan_hdd_mdns_compress_data(resp_info, resptype_srv,
17243 resp, num_matched)) {
17244 hddLog(LOGE, FL("Fail to compress mDNS response "
17245 "(%d)!"), MDNS_TYPE_SRV);
17246 return FALSE;
17247 }
17248 } else {
17249 /* num = 0 -> no matched string */
17250 if (!wlan_hdd_mdns_process_response_dname(resptype_srv,
17251 resp_info)) {
17252 hddLog(LOGE, FL("Fail to process mDNS response (%d)!"),
17253 MDNS_TYPE_SRV);
17254 return FALSE;
17255 }
17256 }
17257
17258 /* Process response Type, Class, TTL */
17259 if (!wlan_hdd_mdns_process_response_misc(MDNS_TYPE_SRV, resp_info)) {
17260 hddLog(LOGE, FL("Fail to process mDNS misc response (%d)!"),
17261 MDNS_TYPE_SRV);
17262 return FALSE;
17263 }
17264
17265 /*
17266 * Process response RDLength, RData (Srv target name)
17267 * Save the offset of RData length
17268 */
17269 offset_data_len = resp_info->resp_len;
17270 resp_info->resp_len += sizeof(uint16_t);
17271
17272 len = resp_info->resp_len + (3 * sizeof(uint16_t));
17273 if (len >= MAX_MDNS_RESP_LEN) {
17274 hddLog(LOGE, FL("resp_len exceeds %d!"), MAX_MDNS_RESP_LEN);
17275 return FALSE;
17276 }
17277
17278 /* set Srv Priority */
17279 value = ini_config->mdns_resp_type_srv_priority;
17280 wlan_hdd_mdns_format_response_u16(value, resp_info);
17281 /* set Srv Weight */
17282 value = ini_config->mdns_resp_type_srv_weight;
17283 wlan_hdd_mdns_format_response_u16(value, resp_info);
17284 /* set Srv Port */
17285 value = ini_config->mdns_resp_type_srv_port;
17286 wlan_hdd_mdns_format_response_u16(value, resp_info);
17287
17288 if (!wlan_hdd_mdns_pack_response_type_srv_target(ini_config, resp_info,
17289 resptype_srv_tgt, resptype_srv,
17290 resptype_ptr, resptype_ptr_dn,
17291 resptype_txt, resptype_a)) {
17292 return FALSE;
17293 }
17294 /* Set the RData length */
17295 len = offset_data_len + sizeof(uint16_t);
17296 if ((resptype_srv_tgt->num_entries > 0) &&
17297 (resp_info->resp_len > len)) {
17298 value = resp_info->resp_len - len;
17299 val_u8 = (value & 0xff00) >> 8;
17300 resp_info->resp_data[offset_data_len] = val_u8;
17301 val_u8 = value & 0xff;
17302 resp_info->resp_data[offset_data_len+1] = val_u8;
17303 } else {
17304 hddLog(LOGE, FL("Fail to process mDNS response (%d)!"),
17305 MDNS_TYPE_SRV);
17306 return FALSE;
17307 }
17308
17309 EXIT();
17310 return TRUE;
17311}
17312
17313/**
17314 * wlan_hdd_mdns_free_mem() - Free the allocated memory
17315 * @response: Pointer to the struct hdd_mdns_resp_info
17316 *
17317 * Return: None
17318 */
17319static void wlan_hdd_mdns_free_mem(struct hdd_mdns_resp_info *response)
17320{
17321 if (response && response->data)
17322 vos_mem_free(response->data);
17323 if (response && response->offset)
17324 vos_mem_free(response->offset);
17325}
17326
17327/**
17328 * wlan_hdd_mdns_pack_response() - Pack mDNS response
17329 * @ini_config: Pointer to the struct hdd_config_t
17330 * @resp_info: Pointer to the struct tSirMDNSResponseInfo
17331 *
17332 * This function will pack four types of responses (Type A, Type Txt, Type Ptr
17333 * and Type Service). Each response contains QName, response type, class, TTL
17334 * and data fields.
17335 *
17336 * Return: Return boolean. TRUE for success, FALSE for fail.
17337 */
17338static bool wlan_hdd_mdns_pack_response(hdd_config_t *ini_config,
17339 sir_mdns_resp_info resp_info)
17340{
17341 struct hdd_mdns_resp_info resptype_a, resptype_txt;
17342 struct hdd_mdns_resp_info resptype_ptr, resptype_ptr_dn;
17343 struct hdd_mdns_resp_info resptype_srv, resptype_srv_tgt;
17344 uint32_t num_res_records = 0;
17345 bool status = FALSE;
17346
17347 ENTER();
17348
17349 wlan_hdd_mdns_reset_response(&resptype_a);
17350 wlan_hdd_mdns_reset_response(&resptype_txt);
17351 wlan_hdd_mdns_reset_response(&resptype_ptr);
17352 wlan_hdd_mdns_reset_response(&resptype_ptr_dn);
17353 wlan_hdd_mdns_reset_response(&resptype_srv);
17354 wlan_hdd_mdns_reset_response(&resptype_srv_tgt);
17355
17356 resp_info->resp_len = 0;
17357
17358 /* Process Type A response */
17359 if (!wlan_hdd_mdns_pack_response_type_a(ini_config, resp_info,
17360 &resptype_a))
17361 goto err_resptype_a;
17362
17363 if ((resptype_a.num_entries > 0) &&
17364 (strlen((char *)&resptype_a.data[0]) > 0))
17365 num_res_records++;
17366
17367 /* Process Type TXT response */
17368 if (!wlan_hdd_mdns_pack_response_type_txt(ini_config, resp_info,
17369 &resptype_txt, &resptype_a))
17370 goto err_resptype_txt;
17371
17372 if ((resptype_txt.num_entries > 0) &&
17373 (strlen((char *)&resptype_txt.data[0]) > 0))
17374 num_res_records++;
17375
17376 /* Process Type PTR response */
17377 if (!wlan_hdd_mdns_pack_response_type_ptr(ini_config, resp_info,
17378 &resptype_ptr, &resptype_ptr_dn,
17379 &resptype_txt, &resptype_a))
17380 goto err_resptype_ptr;
17381
17382 if ((resptype_ptr.num_entries > 0) &&
17383 (strlen((char *)&resptype_ptr.data[0]) > 0))
17384 num_res_records++;
17385
17386 /* Process Type SRV response */
17387 if (!wlan_hdd_mdns_pack_response_type_srv(ini_config, resp_info,
17388 &resptype_srv, &resptype_srv_tgt,
17389 &resptype_ptr, &resptype_ptr_dn,
17390 &resptype_txt, &resptype_a))
17391 goto err_resptype_srv;
17392
17393 if ((resptype_srv.num_entries > 0) &&
17394 (strlen((char *)&resptype_srv.data[0]) > 0))
17395 num_res_records++;
17396
17397 resp_info->resourceRecord_count = num_res_records;
17398 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
17399 "%s: Pack mDNS response data successfully!", __func__);
17400 status = TRUE;
17401
17402err_resptype_srv:
17403 wlan_hdd_mdns_free_mem(&resptype_srv);
17404 wlan_hdd_mdns_free_mem(&resptype_srv_tgt);
17405
17406err_resptype_ptr:
17407 wlan_hdd_mdns_free_mem(&resptype_ptr);
17408 wlan_hdd_mdns_free_mem(&resptype_ptr_dn);
17409
17410err_resptype_txt:
17411 wlan_hdd_mdns_free_mem(&resptype_txt);
17412
17413err_resptype_a:
17414 wlan_hdd_mdns_free_mem(&resptype_a);
17415
17416 EXIT();
17417 return status;
17418}
17419
17420/**
17421 * wlan_hdd_set_mdns_offload() - Enable mDNS offload
17422 * @hostapd_adapter: Pointer to the struct hdd_adapter_t
17423 *
17424 * This function will set FQDN/unique FQDN (full qualified domain name)
17425 * and the mDNS response. Then send them to SME.
17426 *
17427 * Return: Return boolean. TRUE for success, FALSE for fail.
17428 */
17429bool wlan_hdd_set_mdns_offload(hdd_adapter_t *hostapd_adapter)
17430{
17431 hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(hostapd_adapter);
17432 sir_mdns_offload_info mdns_offload_info;
17433 sir_mdns_fqdn_info mdns_fqdn_info;
17434 sir_mdns_resp_info mdns_resp_info;
17435 uint32_t fqdn_len, ufqdn_len;
17436
17437 ENTER();
17438
17439 /* 1. Prepare the MDNS fqdn request to send to SME */
17440 fqdn_len = strlen(hdd_ctx->cfg_ini->mdns_fqdn);
17441 ufqdn_len = strlen(hdd_ctx->cfg_ini->mdns_uniquefqdn);
17442 if ((fqdn_len == 0) && (ufqdn_len == 0)) {
17443 hddLog(LOGE, FL("No mDNS FQDN or UFQDN is assigned fqdn_len %d,"
17444 "ufqdn_len %d!"), fqdn_len, ufqdn_len);
17445 return FALSE;
17446 }
17447
17448 mdns_fqdn_info = vos_mem_malloc(sizeof(*mdns_fqdn_info));
17449 if (NULL == mdns_fqdn_info) {
17450 hddLog(LOGE, FL("could not allocate tSirMDNSFqdnInfo!"));
17451 return FALSE;
17452 }
17453 /* MDNS fqdn request */
17454 if (fqdn_len > 0) {
17455 vos_mem_zero(mdns_fqdn_info, sizeof(*mdns_fqdn_info));
17456 mdns_fqdn_info->bss_idx = hostapd_adapter->sessionId;
17457 mdns_fqdn_info->fqdn_type = MDNS_FQDN_TYPE_GENERAL;
17458 mdns_fqdn_info->fqdn_len = fqdn_len;
17459 mdns_fqdn_info->mdns_fqdn_callback = hdd_mdns_fqdn_offload_done;
17460 mdns_fqdn_info->mdns_fqdn_cb_context = hostapd_adapter;
17461 vos_mem_copy(mdns_fqdn_info->fqdn_data,
17462 hdd_ctx->cfg_ini->mdns_fqdn,
17463 mdns_fqdn_info->fqdn_len);
17464
17465 if (eHAL_STATUS_SUCCESS !=
17466 sme_set_mdns_fqdn(hdd_ctx->hHal, mdns_fqdn_info)) {
17467 hddLog(LOGE, FL("sme_set_mdns_fqdn fail!"));
17468 vos_mem_free(mdns_fqdn_info);
17469 return FALSE;
17470 }
17471 }
17472 /* MDNS unique fqdn request */
17473 if (ufqdn_len > 0) {
17474 vos_mem_zero(mdns_fqdn_info, sizeof(*mdns_fqdn_info));
17475 mdns_fqdn_info->bss_idx = hostapd_adapter->sessionId;
17476 mdns_fqdn_info->fqdn_type = MDNS_FQDN_TYPE_UNIQUE;
17477 mdns_fqdn_info->fqdn_len = ufqdn_len;
17478 mdns_fqdn_info->mdns_fqdn_callback = hdd_mdns_fqdn_offload_done;
17479 mdns_fqdn_info->mdns_fqdn_cb_context = hostapd_adapter;
17480 vos_mem_copy(mdns_fqdn_info->fqdn_data,
17481 hdd_ctx->cfg_ini->mdns_uniquefqdn,
17482 mdns_fqdn_info->fqdn_len);
17483 if (eHAL_STATUS_SUCCESS !=
17484 sme_set_mdns_fqdn(hdd_ctx->hHal, mdns_fqdn_info)) {
17485 hddLog(LOGE, FL("sme_set_mdns_fqdn fail!"));
17486 vos_mem_free(mdns_fqdn_info);
17487 return FALSE;
17488 }
17489 }
17490 vos_mem_free(mdns_fqdn_info);
17491
17492 /* 2. Prepare the MDNS response request to send to SME */
17493 mdns_resp_info = vos_mem_malloc(sizeof(*mdns_resp_info));
17494 if (NULL == mdns_resp_info) {
17495 hddLog(LOGE, FL("could not allocate tSirMDNSResponseInfo!"));
17496 return FALSE;
17497 }
17498
17499 vos_mem_zero(mdns_resp_info, sizeof(*mdns_resp_info));
17500 mdns_resp_info->bss_idx = hostapd_adapter->sessionId;
17501 mdns_resp_info->mdns_resp_callback = hdd_mdns_resp_offload_done;
17502 mdns_resp_info->mdns_resp_cb_context = hostapd_adapter;
17503 if (!wlan_hdd_mdns_pack_response(hdd_ctx->cfg_ini, mdns_resp_info)) {
17504 hddLog(LOGE, FL("wlan_hdd_pack_mdns_response fail!"));
17505 vos_mem_free(mdns_resp_info);
17506 return FALSE;
17507 }
17508 if (eHAL_STATUS_SUCCESS !=
17509 sme_set_mdns_resp(hdd_ctx->hHal, mdns_resp_info)) {
17510 hddLog(LOGE, FL("sme_set_mdns_resp fail!"));
17511 vos_mem_free(mdns_resp_info);
17512 return FALSE;
17513 }
17514 vos_mem_free(mdns_resp_info);
17515
17516 /* 3. Prepare the MDNS Enable request to send to SME */
17517 mdns_offload_info = vos_mem_malloc(sizeof(*mdns_offload_info));
17518 if (NULL == mdns_offload_info) {
17519 hddLog(LOGE, FL("could not allocate tSirMDNSOffloadInfo!"));
17520 return FALSE;
17521 }
17522
17523 vos_mem_zero(mdns_offload_info, sizeof(*mdns_offload_info));
17524
17525 mdns_offload_info->bss_idx = hostapd_adapter->sessionId;
17526 mdns_offload_info->enable = hdd_ctx->cfg_ini->enable_mdns_offload;
17527 mdns_offload_info->mdns_enable_callback = hdd_mdns_enable_offload_done;
17528 mdns_offload_info->mdns_enable_cb_context = hostapd_adapter;
17529 if (eHAL_STATUS_SUCCESS !=
17530 sme_set_mdns_offload(hdd_ctx->hHal, mdns_offload_info)) {
17531 hddLog(LOGE, FL("sme_set_mdns_offload fail!"));
17532 vos_mem_free(mdns_offload_info);
17533 return FALSE;
17534 }
17535
17536 vos_mem_free(mdns_offload_info);
17537 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
17538 "%s: enable mDNS offload successfully!", __func__);
17539 return TRUE;
17540}
Manjeet Singh3ed79242017-01-11 19:04:32 +053017541
17542
Anurag Chouhan0b29de02016-12-16 13:18:40 +053017543#endif /* MDNS_OFFLOAD */
c_manjeecfd1efb2015-09-25 19:32:34 +053017544
Hanumanth Reddy Pothulad864f312017-01-18 16:16:08 +053017545/**
17546 * wlan_hdd_start_sap() - This function starts bss of SAP.
17547 * @ap_adapter: SAP adapter
17548 *
17549 * This function will process the starting of sap adapter.
17550 *
17551 * Return: void.
17552 */
17553void wlan_hdd_start_sap(hdd_adapter_t *ap_adapter)
17554{
17555 hdd_ap_ctx_t *hdd_ap_ctx;
17556 hdd_hostapd_state_t *hostapd_state;
17557 VOS_STATUS vos_status;
17558 hdd_context_t *hdd_ctx;
17559 tsap_Config_t *pConfig;
17560
17561 if (NULL == ap_adapter) {
17562 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17563 FL("ap_adapter is NULL here"));
17564 return;
17565 }
17566
17567 hdd_ctx = WLAN_HDD_GET_CTX(ap_adapter);
17568 hdd_ap_ctx = WLAN_HDD_GET_AP_CTX_PTR(ap_adapter);
17569 hostapd_state = WLAN_HDD_GET_HOSTAP_STATE_PTR(ap_adapter);
17570 pConfig = &ap_adapter->sessionCtx.ap.sapConfig;
17571
17572 mutex_lock(&hdd_ctx->sap_lock);
17573 if (test_bit(SOFTAP_BSS_STARTED, &ap_adapter->event_flags))
17574 goto end;
17575
17576 if (0 != wlan_hdd_cfg80211_update_apies(ap_adapter)) {
17577 hddLog(LOGE, FL("SAP Not able to set AP IEs"));
17578 goto end;
17579 }
17580
17581 vos_event_reset(&hostapd_state->vosEvent);
17582 if (WLANSAP_StartBss(hdd_ctx->pvosContext, hdd_hostapd_SAPEventCB,
17583 &hdd_ap_ctx->sapConfig, (v_PVOID_t)ap_adapter->dev)
17584 != VOS_STATUS_SUCCESS) {
17585 goto end;
17586 }
17587
17588 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
17589 FL("Waiting for SAP to start"));
17590 vos_status = vos_wait_single_event(&hostapd_state->vosEvent, 10000);
17591 if (!VOS_IS_STATUS_SUCCESS(vos_status)) {
17592 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17593 FL("SAP Start failed"));
17594 goto end;
17595 }
17596 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
17597 FL("SAP Start Success"));
17598 set_bit(SOFTAP_BSS_STARTED, &ap_adapter->event_flags);
17599
17600 wlan_hdd_incr_active_session(hdd_ctx, ap_adapter->device_mode);
17601 hostapd_state->bCommit = TRUE;
17602
17603end:
17604 mutex_unlock(&hdd_ctx->sap_lock);
17605 return;
17606}
17607
Manjeet Singh3ed79242017-01-11 19:04:32 +053017608#ifdef WLAN_FEATURE_TSF
17609
17610/**
17611 * hdd_tsf_cb() - handle tsf request callback
17612 *
17613 * @pcb_cxt: pointer to the hdd_contex
17614 * @ptsf: pointer to struct stsf
17615 *
17616 * Based on the request sent .
17617 *
17618 * Return: Describe the execute result of this routine
17619 */
17620static int hdd_tsf_cb(void *pcb_ctx, struct stsf *ptsf)
17621{
17622 hdd_context_t *hddctx;
17623 int status;
17624 hdd_adapter_t* adapter = (hdd_adapter_t*)pcb_ctx;
17625
17626 if (pcb_ctx == NULL || ptsf == NULL) {
17627 hddLog(VOS_TRACE_LEVEL_ERROR,
17628 FL("HDD context is not valid"));
17629 return -EINVAL;
17630 }
17631
17632 hddctx = (hdd_context_t *)pcb_ctx;
17633 status = wlan_hdd_validate_context(hddctx);
17634 if (0 != status)
17635 return -EINVAL;
17636
17637 if (NULL == adapter) {
17638 hddLog(VOS_TRACE_LEVEL_ERROR,
17639 FL("failed to find adapter"));
17640 return -EINVAL;
17641 }
17642
17643 hddLog(VOS_TRACE_LEVEL_INFO,
17644 FL("tsf cb handle event, device_mode is %d"),
17645 adapter->device_mode);
17646
17647 /* copy the return value to hdd_tsf_ctx in adapter*/
17648 if (ptsf->tsf_req_status) {
17649
17650 vos_spin_lock_acquire(&adapter->tsf_cap_ctx.tsf_lock);
17651 adapter->tsf_cap_ctx.tsf_get_state = TSF_NOT_RETURNED_BY_FW;
17652 adapter->tsf_cap_ctx.tsf_capture_state = TSF_IDLE;
17653 vos_event_set (&adapter->tsf_cap_ctx.tsf_capture_done_event);
17654 vos_spin_lock_release(&adapter->tsf_cap_ctx.tsf_lock);
17655
17656 hddLog(VOS_TRACE_LEVEL_ERROR, FL("tsf req failure :%d"),
17657 ptsf->tsf_req_status);
17658 return ptsf->tsf_req_status;
17659 }
17660 /* If this is a get request.Store the tsf values in adapter. */
17661 if (!ptsf->set_tsf_req) {
17662 vos_spin_lock_acquire(&adapter->tsf_cap_ctx.tsf_lock);
17663 adapter->tsf_cap_ctx.tsf_low = ptsf->tsf_low;
17664 adapter->tsf_cap_ctx.tsf_high = ptsf->tsf_high;
17665 adapter->tsf_cap_ctx.tsf_get_state = TSF_RETURN;
17666 adapter->tsf_cap_ctx.tsf_capture_state = TSF_IDLE;
17667 vos_spin_lock_release(&adapter->tsf_cap_ctx.tsf_lock);
17668
17669 hddLog(VOS_TRACE_LEVEL_INFO,
17670 FL("hdd_get_tsf_cb sta=%u, tsf_low=%u, tsf_high=%u"),
17671 adapter->sessionId, ptsf->tsf_low, ptsf->tsf_high);
17672 }
17673 else {
17674 vos_spin_lock_acquire(&adapter->tsf_cap_ctx.tsf_lock);
17675 adapter->tsf_cap_ctx.tsf_capture_state = TSF_CAP_STATE;
17676 adapter->tsf_cap_ctx.tsf_get_state = TSF_CURRENT_IN_CAP_STATE;
17677 vos_spin_lock_release(&adapter->tsf_cap_ctx.tsf_lock);
17678 }
17679 vos_spin_lock_acquire(&adapter->tsf_cap_ctx.tsf_lock);
17680 vos_event_set (&adapter->tsf_cap_ctx.tsf_capture_done_event);
17681 vos_spin_lock_release(&adapter->tsf_cap_ctx.tsf_lock);
17682
17683 /* free allocated mem */
17684 vos_mem_free(ptsf);
17685
17686 return 0;
17687}
17688
17689/**
17690 * hdd_capture_tsf() - capture tsf
17691 *
17692 * @adapter: pointer to adapter
17693 * @buf: pointer to upper layer buf
17694 * @len : the length of buf
17695 *
17696 * This function returns tsf value to uplayer.
17697 *
17698 * Return: Describe the execute result of this routine
17699 */
17700int hdd_capture_tsf(hdd_adapter_t *adapter, uint32_t *buf, int len)
17701{
17702 int ret = 0;
17703 hdd_station_ctx_t *hdd_sta_ctx;
17704 hdd_context_t *hdd_ctx;
17705 tSirCapTsfParams cap_tsf_params;
17706 VOS_STATUS status;
17707
17708 if (adapter == NULL || buf == NULL) {
17709 hddLog(VOS_TRACE_LEVEL_ERROR,
17710 FL("invalid pointer"));
17711 return -EINVAL;
17712 }
17713 if (len != 1)
17714 return -EINVAL;
17715
17716 hdd_ctx = WLAN_HDD_GET_CTX(adapter);
17717
17718 if (wlan_hdd_validate_context(hdd_ctx)) {
17719 hddLog(VOS_TRACE_LEVEL_ERROR,
17720 FL("invalid hdd ctx"));
17721 return -EINVAL;
17722 }
17723 if (adapter->device_mode == WLAN_HDD_INFRA_STATION ||
17724 adapter->device_mode == WLAN_HDD_P2P_CLIENT) {
17725 hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
17726 if (hdd_sta_ctx->conn_info.connState !=
17727 eConnectionState_Associated) {
17728
17729 hddLog(VOS_TRACE_LEVEL_INFO,
17730 FL("failed to cap tsf, not connect with ap"));
17731 buf[0] = TSF_STA_NOT_CONNECTED_NO_TSF;
17732 return ret;
17733 }
17734 }
17735 if ((adapter->device_mode == WLAN_HDD_SOFTAP ||
17736 adapter->device_mode == WLAN_HDD_P2P_GO) &&
17737 !(test_bit(SOFTAP_BSS_STARTED, &adapter->event_flags))) {
17738 hddLog(VOS_TRACE_LEVEL_INFO,
17739 FL("Soft AP / P2p GO not beaconing"));
17740 buf[0] = TSF_SAP_NOT_STARTED_NO_TSF;
17741 return ret;
17742 }
17743 if (adapter->tsf_cap_ctx.tsf_capture_state == TSF_CAP_STATE) {
17744 hddLog(VOS_TRACE_LEVEL_INFO,
17745 FL("current in capture state, pls reset"));
17746 buf[0] = TSF_CURRENT_IN_CAP_STATE;
17747 } else {
17748 hddLog(VOS_TRACE_LEVEL_INFO, FL("ioctl issue cap tsf cmd"));
17749 buf[0] = TSF_RETURN;
17750 cap_tsf_params.session_id = adapter->sessionId;
17751 cap_tsf_params.tsf_rsp_cb_func = hdd_tsf_cb;
17752 cap_tsf_params.tsf_rsp_cb_ctx = adapter;
17753
17754 vos_spin_lock_acquire(&adapter->tsf_cap_ctx.tsf_lock);
17755 adapter->tsf_cap_ctx.tsf_capture_state = TSF_CAP_STATE;
17756 adapter->tsf_cap_ctx.tsf_get_state = TSF_CURRENT_IN_CAP_STATE;
17757 vos_spin_lock_release(&adapter->tsf_cap_ctx.tsf_lock);
17758
17759 ret = sme_capture_tsf_req(hdd_ctx->hHal, cap_tsf_params);
17760
17761 if (ret != VOS_STATUS_SUCCESS) {
17762 hddLog(VOS_TRACE_LEVEL_ERROR, FL("capture fail"));
17763 buf[0] = TSF_CAPTURE_FAIL;
17764 vos_spin_lock_acquire(&adapter->tsf_cap_ctx.tsf_lock);
17765 adapter->tsf_cap_ctx.tsf_capture_state = TSF_IDLE;
17766 vos_spin_lock_release(&adapter->tsf_cap_ctx.tsf_lock);
17767 return -EINVAL;
17768 }
17769 /* wait till we get a response from fw */
17770 status = vos_wait_single_event(&adapter->tsf_cap_ctx.
17771 tsf_capture_done_event,
17772 HDD_TSF_CAP_REQ_TIMEOUT);
17773
17774 if (!VOS_IS_STATUS_SUCCESS(status)) {
17775 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17776 ("capture tsf vos wait for single_event failed!! %d"),
17777 adapter->tsf_cap_ctx.tsf_get_state);
17778
17779 vos_spin_lock_acquire(&adapter->tsf_cap_ctx.tsf_lock);
17780 adapter->tsf_cap_ctx.tsf_capture_state = TSF_IDLE;
17781 vos_spin_lock_release(&adapter->tsf_cap_ctx.tsf_lock);
17782
17783 return -EINVAL;
17784 }
17785 }
17786 buf[0] = TSF_RETURN;
17787 hddLog(VOS_TRACE_LEVEL_INFO,
17788 FL("ioctl return cap tsf cmd, ret = %d"), ret);
17789 return ret;
17790}
17791
17792/**
17793 * hdd_indicate_tsf() - return tsf to uplayer
17794 *
17795 * @adapter: pointer to adapter
17796 * @buf: pointer to uplayer buf
17797 * @len : the length of buf
17798 *
17799 * This function returns tsf value to uplayer.
17800 *
17801 * Return: Describe the execute result of this routine
17802 */
17803int hdd_indicate_tsf(hdd_adapter_t *adapter, uint32_t *buf, int len)
17804{
17805 int ret = 0;
17806 hdd_station_ctx_t *hdd_sta_ctx;
17807 hdd_context_t *hdd_ctx;
17808 tSirCapTsfParams cap_tsf_params;
17809 VOS_STATUS status;
17810
17811 if (adapter == NULL || buf == NULL) {
17812 hddLog(VOS_TRACE_LEVEL_ERROR,
17813 FL("invalid pointer"));
17814 return -EINVAL;
17815 }
17816 if (len != 3)
17817 return -EINVAL;
17818
17819 buf [1] = 0;
17820 buf [2] = 0;
17821 hdd_ctx = WLAN_HDD_GET_CTX(adapter);
17822
17823 if (wlan_hdd_validate_context(hdd_ctx)) {
17824 hddLog(VOS_TRACE_LEVEL_ERROR,
17825 FL("invalid hdd ctx"));
17826 return -EINVAL;
17827 }
17828 if (adapter->device_mode == WLAN_HDD_INFRA_STATION ||
17829 adapter->device_mode == WLAN_HDD_P2P_CLIENT) {
17830 hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
17831 if (hdd_sta_ctx->conn_info.connState !=
17832 eConnectionState_Associated) {
17833
17834 hddLog(VOS_TRACE_LEVEL_INFO,
17835 FL("failed to cap tsf, not connect with ap"));
17836 buf[0] = TSF_STA_NOT_CONNECTED_NO_TSF;
17837 return ret;
17838 }
17839 }
17840 if ((adapter->device_mode == WLAN_HDD_SOFTAP ||
17841 adapter->device_mode == WLAN_HDD_P2P_GO) &&
17842 !(test_bit(SOFTAP_BSS_STARTED, &adapter->event_flags))) {
17843 hddLog(VOS_TRACE_LEVEL_INFO,
17844 FL("Soft AP / P2p GO not beaconing"));
17845 buf[0] = TSF_SAP_NOT_STARTED_NO_TSF;
17846 return ret;
17847 }
17848
17849 if (adapter->tsf_cap_ctx.tsf_capture_state != TSF_CAP_STATE ||
17850 adapter->tsf_cap_ctx.tsf_get_state != TSF_CURRENT_IN_CAP_STATE ) {
17851 hddLog(VOS_TRACE_LEVEL_INFO,
17852 FL("Not in capture state,Enter capture state first"));
17853 buf[0] = TSF_GET_FAIL;
17854 } else {
17855 hddLog(VOS_TRACE_LEVEL_INFO, FL("ioctl issue cap tsf cmd"));
17856 cap_tsf_params.session_id = adapter->sessionId;
17857 cap_tsf_params.tsf_rsp_cb_func = hdd_tsf_cb;
17858 cap_tsf_params.tsf_rsp_cb_ctx = adapter;
17859
17860 ret = sme_get_tsf_req(hdd_ctx->hHal, cap_tsf_params);
17861
17862 if (ret != VOS_STATUS_SUCCESS) {
17863 hddLog(VOS_TRACE_LEVEL_ERROR, FL("capture fail"));
17864 buf[0] = TSF_CAPTURE_FAIL;
17865 vos_spin_lock_acquire(&adapter->tsf_cap_ctx.tsf_lock);
17866 adapter->tsf_cap_ctx.tsf_capture_state = TSF_IDLE;
17867 vos_spin_lock_release(&adapter->tsf_cap_ctx.tsf_lock);
17868 return -EINVAL;
17869 }
17870 /* wait till we get a response from fw */
17871 status = vos_wait_single_event(&adapter->tsf_cap_ctx.
17872 tsf_capture_done_event,
17873 HDD_TSF_GET_REQ_TIMEOUT);
17874
17875 if (!VOS_IS_STATUS_SUCCESS(status)) {
17876 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17877 ("capture tsf vos wait for single_event failed!! %d"),
17878 status);
17879
17880 vos_spin_lock_acquire(&adapter->tsf_cap_ctx.tsf_lock);
17881 adapter->tsf_cap_ctx.tsf_capture_state = TSF_IDLE;
17882 vos_spin_lock_release(&adapter->tsf_cap_ctx.tsf_lock);
17883 return status;
17884 }
17885 buf[1] = adapter->tsf_cap_ctx.tsf_low;
17886 buf[2] = adapter->tsf_cap_ctx.tsf_high;
17887
17888 hddLog(VOS_TRACE_LEVEL_INFO,
17889 FL("get tsf cmd,status=%u, tsf_low=%u, tsf_high=%u"),
17890 buf[0], buf[1], buf[2]);
17891 }
17892 hddLog(VOS_TRACE_LEVEL_INFO,
17893 FL("ioctl return cap tsf cmd, ret = %d"), ret);
17894 return ret;
17895}
17896
17897void wlan_hdd_tsf_init(hdd_adapter_t *adapter)
17898{
17899
17900 if (adapter == NULL) {
17901 hddLog(VOS_TRACE_LEVEL_ERROR,
17902 FL("TSF init on a null adapter!"));
17903 return;
17904 }
17905
17906 adapter->tsf_cap_ctx.tsf_get_state = TSF_RETURN;
17907 adapter->tsf_cap_ctx.tsf_capture_state = TSF_IDLE;
17908 vos_event_init(&adapter->tsf_cap_ctx.tsf_capture_done_event);
17909 vos_spin_lock_init(&adapter->tsf_cap_ctx.tsf_lock);
17910 adapter->tsf_cap_ctx.tsf_high = 0;
17911 adapter->tsf_cap_ctx.tsf_low = 0;
17912}
17913
17914#endif
17915
Hanumanth Reddy Pothula49c3f902018-02-16 16:01:13 +053017916bool hdd_is_memdump_supported(void)
17917{
17918#ifdef WLAN_FEATURE_MEMDUMP
17919 return true;
17920#endif
17921 return false;
17922}
17923
Jeff Johnson295189b2012-06-20 16:38:30 -070017924//Register the module init/exit functions
17925module_init(hdd_module_init);
17926module_exit(hdd_module_exit);
17927
17928MODULE_LICENSE("Dual BSD/GPL");
17929MODULE_AUTHOR("Qualcomm Atheros, Inc.");
17930MODULE_DESCRIPTION("WLAN HOST DEVICE DRIVER");
17931
Ashish Kumar Dhanotiyafb3fd972018-04-30 12:46:52 +053017932static const struct kernel_param_ops con_mode_ops = {
17933 .set = con_mode_handler,
17934 .get = param_get_int,
17935};
17936
17937static const struct kernel_param_ops fwpath_ops = {
17938 .set = fwpath_changed_handler,
17939 .get = param_get_string,
17940};
17941
17942module_param_cb(con_mode, &con_mode_ops, &con_mode,
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070017943 S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
Jeff Johnson32d95a32012-09-10 13:15:23 -070017944
Ashish Kumar Dhanotiyafb3fd972018-04-30 12:46:52 +053017945module_param_cb(fwpath, &fwpath_ops, &fwpath,
Jeff Johnson32d95a32012-09-10 13:15:23 -070017946 S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
Arif Hussain66559122013-11-21 10:11:40 -080017947
17948module_param(enable_dfs_chan_scan, int,
17949 S_IRUSR | S_IRGRP | S_IROTH);
17950
17951module_param(enable_11d, int,
17952 S_IRUSR | S_IRGRP | S_IROTH);
17953
17954module_param(country_code, charp,
17955 S_IRUSR | S_IRGRP | S_IROTH);