blob: 6a92340889f71fdf24b0db122ec4791899ef0004 [file] [log] [blame]
Jeff Johnson295189b2012-06-20 16:38:30 -07001/*
Pankaj Singh33205b82020-06-05 00:27:49 +05302 * Copyright (c) 2012-2020 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>
Rajeev Kumar Sirasanagandlaf8fc27c2018-12-06 14:56:43 +053065#include <vos_nvitem.h>
Jeff Johnson295189b2012-06-20 16:38:30 -070066#include <vos_sched.h>
Jeff Johnson295189b2012-06-20 16:38:30 -070067#include <linux/etherdevice.h>
68#include <linux/firmware.h>
Jeff Johnson295189b2012-06-20 16:38:30 -070069#ifdef ANI_BUS_TYPE_PLATFORM
70#include <linux/wcnss_wlan.h>
71#endif //ANI_BUS_TYPE_PLATFORM
72#ifdef ANI_BUS_TYPE_PCI
73#include "wcnss_wlan.h"
74#endif /* ANI_BUS_TYPE_PCI */
75#include <wlan_hdd_tx_rx.h>
76#include <palTimer.h>
77#include <wniApi.h>
78#include <wlan_nlink_srv.h>
79#include <wlan_btc_svc.h>
80#include <wlan_hdd_cfg.h>
81#include <wlan_ptt_sock_svc.h>
Vinay Krishna Erannad938c422014-03-10 17:14:21 +053082#include <wlan_logging_sock_svc.h>
Jeff Johnson295189b2012-06-20 16:38:30 -070083#include <wlan_hdd_wowl.h>
84#include <wlan_hdd_misc.h>
85#include <wlan_hdd_wext.h>
86#ifdef WLAN_BTAMP_FEATURE
87#include <bap_hdd_main.h>
88#include <bapInternal.h>
89#endif // WLAN_BTAMP_FEATURE
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053090#include "wlan_hdd_trace.h"
91#include "vos_types.h"
92#include "vos_trace.h"
Jeff Johnson295189b2012-06-20 16:38:30 -070093#include <linux/wireless.h>
94#include <net/cfg80211.h>
Vinay Krishna Erannad9cbdb32014-01-16 12:59:10 +053095#include <linux/inetdevice.h>
96#include <net/addrconf.h>
Jeff Johnson295189b2012-06-20 16:38:30 -070097#include "wlan_hdd_cfg80211.h"
98#include "wlan_hdd_p2p.h"
Jeff Johnson295189b2012-06-20 16:38:30 -070099#include <linux/rtnetlink.h>
Jeff Johnson295189b2012-06-20 16:38:30 -0700100int wlan_hdd_ftm_start(hdd_context_t *pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -0700101#include "sapApi.h"
102#include <linux/semaphore.h>
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -0700103#include <linux/ctype.h>
Arun Kumar Khandavalli74fe3032014-03-17 20:35:34 +0530104#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0))
105#include <soc/qcom/subsystem_restart.h>
106#else
Jeff Johnson295189b2012-06-20 16:38:30 -0700107#include <mach/subsystem_restart.h>
Arun Kumar Khandavalli74fe3032014-03-17 20:35:34 +0530108#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700109#include <wlan_hdd_hostapd.h>
110#include <wlan_hdd_softap_tx_rx.h>
Jeff Johnson295189b2012-06-20 16:38:30 -0700111#include "cfgApi.h"
Jeff Johnson295189b2012-06-20 16:38:30 -0700112#include "wlan_hdd_dev_pwr.h"
113#ifdef WLAN_BTAMP_FEATURE
114#include "bap_hdd_misc.h"
115#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700116#include "wlan_qct_pal_trace.h"
Jeff Johnson295189b2012-06-20 16:38:30 -0700117#include "qwlan_version.h"
Yathish9f22e662012-12-10 14:21:35 -0800118#include "wlan_qct_wda.h"
Chilam NG571c65a2013-01-19 12:27:36 +0530119#ifdef FEATURE_WLAN_TDLS
120#include "wlan_hdd_tdls.h"
121#endif
Yue Ma0d4891e2013-08-06 17:01:45 -0700122#include "wlan_hdd_debugfs.h"
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +0530123#include "sapInternal.h"
Hanumanth Reddy Pothula1efcd162018-03-14 14:32:27 +0530124#include "wlan_hdd_request_manager.h"
Jeff Johnson295189b2012-06-20 16:38:30 -0700125
126#ifdef MODULE
127#define WLAN_MODULE_NAME module_name(THIS_MODULE)
128#else
129#define WLAN_MODULE_NAME "wlan"
130#endif
131
132#ifdef TIMER_MANAGER
133#define TIMER_MANAGER_STR " +TIMER_MANAGER"
134#else
135#define TIMER_MANAGER_STR ""
136#endif
137
138#ifdef MEMORY_DEBUG
139#define MEMORY_DEBUG_STR " +MEMORY_DEBUG"
140#else
141#define MEMORY_DEBUG_STR ""
142#endif
Kaushik, Sushant7005e372014-04-08 11:36:54 +0530143#define MAX_WAIT_FOR_ROC_COMPLETION 3
Jeff Johnson295189b2012-06-20 16:38:30 -0700144/* the Android framework expects this param even though we don't use it */
145#define BUF_LEN 20
Jeff Johnson76052702013-04-16 13:55:05 -0700146static char fwpath_buffer[BUF_LEN];
147static struct kparam_string fwpath = {
148 .string = fwpath_buffer,
149 .maxlen = BUF_LEN,
150};
Arif Hussain66559122013-11-21 10:11:40 -0800151
152static char *country_code;
153static int enable_11d = -1;
154static int enable_dfs_chan_scan = -1;
155
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);
Sourav Mohapatra9d963282018-02-08 20:03:05 +0530253void hdd_set_olpc_mode(tHalHandle hHal, bool low_power);
Jeff Johnsone7245742012-09-05 17:12:55 -0700254
Jeff Johnson295189b2012-06-20 16:38:30 -0700255v_U16_t hdd_select_queue(struct net_device *dev,
Anand N Sunkade9adb1b2015-07-29 09:56:45 +0530256 struct sk_buff *skb
257#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,13,0))
258 , void *accel_priv
259#endif
260#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
261 , select_queue_fallback_t fallback
262#endif
263);
Jeff Johnson295189b2012-06-20 16:38:30 -0700264
265#ifdef WLAN_FEATURE_PACKET_FILTERING
266static void hdd_set_multicast_list(struct net_device *dev);
267#endif
268
269void hdd_wlan_initial_scan(hdd_adapter_t *pAdapter);
270
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -0800271#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowdade697412013-02-14 16:31:48 -0800272void hdd_getBand_helper(hdd_context_t *pHddCtx, int *pBand);
273static VOS_STATUS hdd_parse_channellist(tANI_U8 *pValue, tANI_U8 *pChannelList, tANI_U8 *pNumChannels);
Srinivas Girigowda100eb322013-03-15 16:48:20 -0700274static VOS_STATUS hdd_parse_send_action_frame_data(tANI_U8 *pValue, tANI_U8 *pTargetApBssid,
275 tANI_U8 *pChannel, tANI_U8 *pDwellTime,
276 tANI_U8 **pBuf, tANI_U8 *pBufLen);
Selvaraj, Sridhar5aff1ed2016-06-18 01:26:23 +0530277static int hdd_parse_reassoc_command_v1_data(const tANI_U8 *pValue,
278 tANI_U8 *pTargetApBssid, tANI_U8 *pChannel);
Srinivas Girigowdade697412013-02-14 16:31:48 -0800279#endif
Ratheesh S P21280412015-05-19 14:21:52 +0530280
281/* Store WLAN driver info in a global variable such that crash debugger
282 can extract it from driver debug symbol and crashdump for post processing */
283tANI_U8 g_wlan_driver[ ] = "pronto_driver";
284
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -0800285#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
Srinivas Girigowda5cecb202013-10-08 09:13:25 -0700286VOS_STATUS hdd_parse_get_cckm_ie(tANI_U8 *pValue, tANI_U8 **pCckmIe, tANI_U8 *pCckmIeLen);
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -0800287#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -0700288
Mihir Shetee1093ba2014-01-21 20:13:32 +0530289static VOS_STATUS wlan_hdd_init_channels(hdd_context_t *pHddCtx);
Sushant Kaushik8bc7df22014-04-09 17:55:29 +0530290const char * hdd_device_modetoString(v_U8_t device_mode)
291{
292 switch(device_mode)
293 {
294 CASE_RETURN_STRING( WLAN_HDD_INFRA_STATION );
295 CASE_RETURN_STRING( WLAN_HDD_SOFTAP );
296 CASE_RETURN_STRING( WLAN_HDD_P2P_CLIENT );
297 CASE_RETURN_STRING( WLAN_HDD_P2P_GO );
298 CASE_RETURN_STRING( WLAN_HDD_MONITOR);
299 CASE_RETURN_STRING( WLAN_HDD_FTM );
300 CASE_RETURN_STRING( WLAN_HDD_IBSS );
301 CASE_RETURN_STRING( WLAN_HDD_P2P_DEVICE );
302 default:
303 return "device_mode Unknown";
304 }
305}
Mihir Shetee1093ba2014-01-21 20:13:32 +0530306
Mukul Sharmaa78cf6b2015-02-24 16:59:01 +0530307static int __hdd_netdev_notifier_call(struct notifier_block * nb,
Jeff Johnson295189b2012-06-20 16:38:30 -0700308 unsigned long state,
309 void *ndev)
310{
Yeshwanth Sriram Guntukadb04f472019-08-08 16:58:23 +0530311#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 11, 0))
312 struct netdev_notifier_info *info = ndev;
313 struct net_device *dev = info->dev;
314#else
Jeff Johnson295189b2012-06-20 16:38:30 -0700315 struct net_device *dev = ndev;
Yeshwanth Sriram Guntukadb04f472019-08-08 16:58:23 +0530316#endif
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -0700317 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Jeff Johnson27cee452013-03-27 11:10:24 -0700318 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -0700319#ifdef WLAN_BTAMP_FEATURE
320 VOS_STATUS status;
Jeff Johnson295189b2012-06-20 16:38:30 -0700321#endif
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +0530322 long result;
Jeff Johnson295189b2012-06-20 16:38:30 -0700323
324 //Make sure that this callback corresponds to our device.
Jeff Johnson27cee452013-03-27 11:10:24 -0700325 if ((strncmp(dev->name, "wlan", 4)) &&
Amar Singhal4c723bd2013-03-25 18:14:15 -0700326 (strncmp(dev->name, "p2p", 3)))
327 return NOTIFY_DONE;
328
Jeff Johnson295189b2012-06-20 16:38:30 -0700329 if (!dev->ieee80211_ptr)
Jeff Johnson27cee452013-03-27 11:10:24 -0700330 return NOTIFY_DONE;
Jeff Johnson295189b2012-06-20 16:38:30 -0700331
Jeff Johnson27cee452013-03-27 11:10:24 -0700332 if (NULL == pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -0700333 {
Jeff Johnsona8a1a482012-12-12 16:49:33 -0800334 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: HDD Adapter Null Pointer", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700335 VOS_ASSERT(0);
336 return NOTIFY_DONE;
337 }
338
Jeff Johnson27cee452013-03-27 11:10:24 -0700339 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
340 if (NULL == pHddCtx)
341 {
342 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: HDD Context Null Pointer", __func__);
343 VOS_ASSERT(0);
344 return NOTIFY_DONE;
345 }
Sameer Thalappil14067972014-01-23 14:54:54 -0800346 if (pHddCtx->isLogpInProgress)
347 return NOTIFY_DONE;
348
Jeff Johnson27cee452013-03-27 11:10:24 -0700349
350 hddLog(VOS_TRACE_LEVEL_INFO, "%s: %s New Net Device State = %lu",
351 __func__, dev->name, state);
Jeff Johnson295189b2012-06-20 16:38:30 -0700352
353 switch (state) {
354 case NETDEV_REGISTER:
355 break;
356
357 case NETDEV_UNREGISTER:
358 break;
359
360 case NETDEV_UP:
361 break;
362
363 case NETDEV_DOWN:
364 break;
365
366 case NETDEV_CHANGE:
Jeff Johnsone7245742012-09-05 17:12:55 -0700367 if(TRUE == pAdapter->isLinkUpSvcNeeded)
368 complete(&pAdapter->linkup_event_var);
Jeff Johnson295189b2012-06-20 16:38:30 -0700369 break;
370
371 case NETDEV_GOING_DOWN:
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +0530372 result = wlan_hdd_scan_abort(pAdapter);
Girish Gowli4bf7a632014-06-12 13:42:11 +0530373 if (result < 0)
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +0530374 {
375 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
376 "%s: Timeout occurred while waiting for abortscan %ld",
377 __func__, result);
Jeff Johnson295189b2012-06-20 16:38:30 -0700378 }
379 else
380 {
381 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +0530382 "%s: Scan Abort Successful" , __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700383 }
384#ifdef WLAN_BTAMP_FEATURE
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700385 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,"%s: disabling AMP", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700386 status = WLANBAP_StopAmp();
387 if(VOS_STATUS_SUCCESS != status )
388 {
389 pHddCtx->isAmpAllowed = VOS_TRUE;
390 hddLog(VOS_TRACE_LEVEL_FATAL,
391 "%s: Failed to stop AMP", __func__);
392 }
393 else
394 {
395 //a state m/c implementation in PAL is TBD to avoid this delay
396 msleep(500);
Jeff Johnson04dd8a82012-06-29 20:41:40 -0700397 if ( pHddCtx->isAmpAllowed )
398 {
399 WLANBAP_DeregisterFromHCI();
400 pHddCtx->isAmpAllowed = VOS_FALSE;
401 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700402 }
403#endif //WLAN_BTAMP_FEATURE
404 break;
405
406 default:
407 break;
408 }
409
410 return NOTIFY_DONE;
411}
412
Mukul Sharmaa78cf6b2015-02-24 16:59:01 +0530413static int hdd_netdev_notifier_call(struct notifier_block * nb,
414 unsigned long state,
415 void *ndev)
416{
417 int ret;
418 vos_ssr_protect(__func__);
419 ret = __hdd_netdev_notifier_call( nb, state, ndev);
420 vos_ssr_unprotect(__func__);
421 return ret;
422}
423
Jeff Johnson295189b2012-06-20 16:38:30 -0700424struct notifier_block hdd_netdev_notifier = {
425 .notifier_call = hdd_netdev_notifier_call,
426};
427
428/*---------------------------------------------------------------------------
429 * Function definitions
430 *-------------------------------------------------------------------------*/
Jeff Johnson295189b2012-06-20 16:38:30 -0700431void hdd_unregister_mcast_bcast_filter(hdd_context_t *pHddCtx);
432void hdd_register_mcast_bcast_filter(hdd_context_t *pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -0700433//variable to hold the insmod parameters
Madan Mohan Koyyalamudidfd6aa82012-10-18 20:18:43 -0700434static int con_mode;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -0700435#ifndef MODULE
436/* current con_mode - used only for statically linked driver
437 * con_mode is changed by userspace to indicate a mode change which will
438 * result in calling the module exit and init functions. The module
439 * exit function will clean up based on the value of con_mode prior to it
440 * being changed by userspace. So curr_con_mode records the current con_mode
441 * for exit when con_mode becomes the next mode for init
442 */
Madan Mohan Koyyalamudidfd6aa82012-10-18 20:18:43 -0700443static int curr_con_mode;
Jeff Johnson295189b2012-06-20 16:38:30 -0700444#endif
445
Srinivas Girigowda8bf64cb2015-09-30 19:50:09 +0530446#ifdef WLAN_FEATURE_OFFLOAD_PACKETS
447/**
448 * hdd_init_offloaded_packets_ctx() - Initialize offload packets context
449 * @hdd_ctx: hdd global context
450 *
451 * Return: none
452 */
453static void hdd_init_offloaded_packets_ctx(hdd_context_t *hdd_ctx)
454{
455 uint8_t i;
456
457 mutex_init(&hdd_ctx->op_ctx.op_lock);
458 for (i = 0; i < MAXNUM_PERIODIC_TX_PTRNS; i++)
459 {
460 hdd_ctx->op_ctx.op_table[i].request_id = 0;
461 hdd_ctx->op_ctx.op_table[i].pattern_id = i;
462 }
463}
464#else
465static void hdd_init_offloaded_packets_ctx(hdd_context_t *hdd_ctx)
466{
467}
468#endif
469
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -0800470/**---------------------------------------------------------------------------
471
472 \brief hdd_vos_trace_enable() - Configure initial VOS Trace enable
473
474 Called immediately after the cfg.ini is read in order to configure
475 the desired trace levels.
476
477 \param - moduleId - module whose trace level is being configured
478 \param - bitmask - bitmask of log levels to be enabled
479
480 \return - void
481
482 --------------------------------------------------------------------------*/
483static void hdd_vos_trace_enable(VOS_MODULE_ID moduleId, v_U32_t bitmask)
484{
485 wpt_tracelevel level;
486
487 /* if the bitmask is the default value, then a bitmask was not
488 specified in cfg.ini, so leave the logging level alone (it
489 will remain at the "compiled in" default value) */
490 if (CFG_VOS_TRACE_ENABLE_DEFAULT == bitmask)
491 {
492 return;
493 }
494
495 /* a mask was specified. start by disabling all logging */
496 vos_trace_setValue(moduleId, VOS_TRACE_LEVEL_NONE, 0);
497
498 /* now cycle through the bitmask until all "set" bits are serviced */
499 level = VOS_TRACE_LEVEL_FATAL;
500 while (0 != bitmask)
501 {
502 if (bitmask & 1)
503 {
504 vos_trace_setValue(moduleId, level, 1);
505 }
506 level++;
507 bitmask >>= 1;
508 }
509}
510
511
Jeff Johnson295189b2012-06-20 16:38:30 -0700512/**---------------------------------------------------------------------------
513
514 \brief hdd_wdi_trace_enable() - Configure initial WDI Trace enable
515
516 Called immediately after the cfg.ini is read in order to configure
517 the desired trace levels in the WDI.
518
519 \param - moduleId - module whose trace level is being configured
520 \param - bitmask - bitmask of log levels to be enabled
521
522 \return - void
523
524 --------------------------------------------------------------------------*/
525static void hdd_wdi_trace_enable(wpt_moduleid moduleId, v_U32_t bitmask)
526{
527 wpt_tracelevel level;
528
529 /* if the bitmask is the default value, then a bitmask was not
530 specified in cfg.ini, so leave the logging level alone (it
531 will remain at the "compiled in" default value) */
532 if (CFG_WDI_TRACE_ENABLE_DEFAULT == bitmask)
533 {
534 return;
535 }
536
537 /* a mask was specified. start by disabling all logging */
538 wpalTraceSetLevel(moduleId, eWLAN_PAL_TRACE_LEVEL_NONE, 0);
539
540 /* now cycle through the bitmask until all "set" bits are serviced */
541 level = eWLAN_PAL_TRACE_LEVEL_FATAL;
542 while (0 != bitmask)
543 {
544 if (bitmask & 1)
545 {
546 wpalTraceSetLevel(moduleId, level, 1);
547 }
548 level++;
549 bitmask >>= 1;
550 }
551}
Jeff Johnson295189b2012-06-20 16:38:30 -0700552
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +0530553/*
554 * FUNCTION: wlan_hdd_validate_context
555 * This function is used to check the HDD context
556 */
557int wlan_hdd_validate_context(hdd_context_t *pHddCtx)
558{
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +0530559
560 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
561 {
Mahesh A Saptasagar886997a2015-03-04 13:15:51 +0530562 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +0530563 "%s: HDD context is Null", __func__);
564 return -ENODEV;
565 }
566
567 if (pHddCtx->isLogpInProgress)
568 {
Mahesh A Saptasagar886997a2015-03-04 13:15:51 +0530569 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
c_hpothu8adb97b2014-12-08 19:38:20 +0530570 "%s: LOGP %s. Ignore!!", __func__,
571 vos_is_wlan_in_badState(VOS_MODULE_ID_HDD, NULL)
572 ?"failed":"in Progress");
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +0530573 return -EAGAIN;
574 }
575
Mihir Shete18156292014-03-11 15:38:30 +0530576 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +0530577 {
Mahesh A Saptasagar886997a2015-03-04 13:15:51 +0530578 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +0530579 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
580 return -EAGAIN;
581 }
582 return 0;
583}
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -0700584#ifdef CONFIG_ENABLE_LINUX_REG
585void hdd_checkandupdate_phymode( hdd_context_t *pHddCtx)
586{
587 hdd_adapter_t *pAdapter = NULL;
588 hdd_station_ctx_t *pHddStaCtx = NULL;
589 eCsrPhyMode phyMode;
590 hdd_config_t *cfg_param = NULL;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +0530591
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -0700592 if (NULL == pHddCtx)
593 {
594 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
595 "HDD Context is null !!");
596 return ;
597 }
598
599 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION);
600 if (NULL == pAdapter)
601 {
602 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
603 "pAdapter is null !!");
604 return ;
605 }
606
607 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
608 if (NULL == pHddStaCtx)
609 {
610 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
611 "pHddStaCtx is null !!");
612 return ;
613 }
614
615 cfg_param = pHddCtx->cfg_ini;
616 if (NULL == cfg_param)
617 {
618 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
619 "cfg_params not available !!");
620 return ;
621 }
622
623 phyMode = sme_GetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter));
624
625 if (!pHddCtx->isVHT80Allowed)
626 {
627 if ((eCSR_DOT11_MODE_AUTO == phyMode) ||
628 (eCSR_DOT11_MODE_11ac == phyMode) ||
629 (eCSR_DOT11_MODE_11ac_ONLY == phyMode))
630 {
631 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
632 "Setting phymode to 11n!!");
633 sme_SetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter), eCSR_DOT11_MODE_11n);
634 }
635 }
636 else
637 {
638 /*New country Supports 11ac as well resetting value back from .ini*/
639 sme_SetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter),
640 hdd_cfg_xlate_to_csr_phy_mode(cfg_param->dot11Mode));
641 return ;
642 }
643
644 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
645 ((eCSR_CFG_DOT11_MODE_11AC_ONLY == pHddStaCtx->conn_info.dot11Mode) ||
646 (eCSR_CFG_DOT11_MODE_11AC == pHddStaCtx->conn_info.dot11Mode)))
647 {
648 VOS_STATUS vosStatus;
649
650 // need to issue a disconnect to CSR.
651 INIT_COMPLETION(pAdapter->disconnect_comp_var);
652 vosStatus = sme_RoamDisconnect(WLAN_HDD_GET_HAL_CTX(pAdapter),
653 pAdapter->sessionId,
654 eCSR_DISCONNECT_REASON_UNSPECIFIED );
655
656 if (VOS_STATUS_SUCCESS == vosStatus)
c_hpothu6ff1c3c2013-10-01 19:01:57 +0530657 {
658 long ret;
659
660 ret = wait_for_completion_interruptible_timeout(&pAdapter->disconnect_comp_var,
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -0700661 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
c_hpothu6ff1c3c2013-10-01 19:01:57 +0530662 if (0 >= ret)
663 hddLog(LOGE, FL("failure waiting for disconnect_comp_var %ld"),
664 ret);
665 }
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -0700666
667 }
668}
669#else
Gopichand Nakkaladacbcb52013-04-18 16:41:54 +0530670void hdd_checkandupdate_phymode( hdd_adapter_t *pAdapter, char *country_code)
671{
672 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
673 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
674 hdd_config_t *cfg_param;
675 eCsrPhyMode phyMode;
c_hpothu6ff1c3c2013-10-01 19:01:57 +0530676 long ret;
Gopichand Nakkaladacbcb52013-04-18 16:41:54 +0530677
678 if (NULL == pHddCtx)
679 {
680 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
681 "HDD Context is null !!");
682 return ;
683 }
684
685 cfg_param = pHddCtx->cfg_ini;
686
687 if (NULL == cfg_param)
688 {
689 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
690 "cfg_params not available !!");
691 return ;
692 }
693
694 phyMode = sme_GetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter));
695
696 if (NULL != strstr(cfg_param->listOfNon11acCountryCode, country_code))
697 {
698 if ((eCSR_DOT11_MODE_AUTO == phyMode) ||
699 (eCSR_DOT11_MODE_11ac == phyMode) ||
700 (eCSR_DOT11_MODE_11ac_ONLY == phyMode))
701 {
702 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
703 "Setting phymode to 11n!!");
704 sme_SetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter), eCSR_DOT11_MODE_11n);
705 }
706 }
707 else
708 {
709 /*New country Supports 11ac as well resetting value back from .ini*/
710 sme_SetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter),
711 hdd_cfg_xlate_to_csr_phy_mode(cfg_param->dot11Mode));
712 return ;
713 }
714
715 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
716 ((eCSR_CFG_DOT11_MODE_11AC_ONLY == pHddStaCtx->conn_info.dot11Mode) ||
717 (eCSR_CFG_DOT11_MODE_11AC == pHddStaCtx->conn_info.dot11Mode)))
718 {
719 VOS_STATUS vosStatus;
720
721 // need to issue a disconnect to CSR.
722 INIT_COMPLETION(pAdapter->disconnect_comp_var);
723 vosStatus = sme_RoamDisconnect(WLAN_HDD_GET_HAL_CTX(pAdapter),
724 pAdapter->sessionId,
725 eCSR_DISCONNECT_REASON_UNSPECIFIED );
726
727 if (VOS_STATUS_SUCCESS == vosStatus)
c_hpothu6ff1c3c2013-10-01 19:01:57 +0530728 {
729 ret = wait_for_completion_interruptible_timeout(&pAdapter->disconnect_comp_var,
Gopichand Nakkaladacbcb52013-04-18 16:41:54 +0530730 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
c_hpothu6ff1c3c2013-10-01 19:01:57 +0530731 if (ret <= 0)
732 {
733 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
734 "wait on disconnect_comp_var is failed %ld", ret);
735 }
736 }
Gopichand Nakkaladacbcb52013-04-18 16:41:54 +0530737
738 }
739}
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -0700740#endif //CONFIG_ENABLE_LINUX_REG
Gopichand Nakkaladacbcb52013-04-18 16:41:54 +0530741
Tushnim Bhattacharyya9cdf6082013-04-21 16:33:30 -0700742void hdd_checkandupdate_dfssetting( hdd_adapter_t *pAdapter, char *country_code)
743{
744 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
745 hdd_config_t *cfg_param;
746
747 if (NULL == pHddCtx)
748 {
749 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
750 "HDD Context is null !!");
751 return ;
752 }
753
754 cfg_param = pHddCtx->cfg_ini;
755
756 if (NULL == cfg_param)
757 {
758 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
759 "cfg_params not available !!");
760 return ;
761 }
762
Agarwal Ashish738843c2014-09-25 12:27:56 +0530763 if (NULL != strstr(cfg_param->listOfNonDfsCountryCode, country_code) ||
764 pHddCtx->disable_dfs_flag == TRUE)
Tushnim Bhattacharyya9cdf6082013-04-21 16:33:30 -0700765 {
766 /*New country doesn't support DFS */
767 sme_UpdateDfsSetting(WLAN_HDD_GET_HAL_CTX(pAdapter), 0);
768 }
Ashish Kumar Dhanotiya445b3b92018-06-07 12:38:12 +0530769 else
770 {
771 /* New country Supports DFS as well resetting value back from .ini */
772 sme_UpdateDfsSetting(WLAN_HDD_GET_HAL_CTX(pAdapter),
773 cfg_param->enableDFSChnlScan);
774 }
Tushnim Bhattacharyya9cdf6082013-04-21 16:33:30 -0700775
776}
777
Abhishek Singh00b71972016-01-07 10:51:04 +0530778#ifdef WLAN_FEATURE_RMC
779static int hdd_parse_setrmcenable_command(tANI_U8 *pValue, tANI_U8 *pRmcEnable)
780{
781 tANI_U8 *inPtr = pValue;
782 int tempInt;
783 int v = 0;
784 char buf[32];
785 *pRmcEnable = 0;
786
787 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
788 /*no argument after the command*/
789 if (NULL == inPtr)
790 {
791 return 0;
792 }
793
794 /*no space after the command*/
795 else if (SPACE_ASCII_VALUE != *inPtr)
796 {
797 return 0;
798 }
799
800 /*removing empty spaces*/
801 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
802
803 /*no argument followed by spaces*/
804 if ('\0' == *inPtr)
805 {
806 return 0;
807 }
808
809 /* getting the first argument which enables or disables RMC
810 * for input IP v4 address*/
Ashish Kumar Dhanotiya54d31a32017-08-04 17:12:44 +0530811 sscanf(inPtr, "%31s ", buf);
Abhishek Singh00b71972016-01-07 10:51:04 +0530812 v = kstrtos32(buf, 10, &tempInt);
813 if ( v < 0)
814 {
815 return -EINVAL;
816 }
817
818 *pRmcEnable = tempInt;
819
820 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
821 "ucRmcEnable: %d", *pRmcEnable);
822
823 return 0;
824}
825
826/* Function header left blank Intentionally */
827static int hdd_parse_setrmcactionperiod_command(tANI_U8 *pValue,
828 tANI_U32 *pActionPeriod)
829{
830 tANI_U8 *inPtr = pValue;
831 int tempInt;
832 int v = 0;
833 char buf[32];
834 *pActionPeriod = 0;
835
836 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
837 /*no argument after the command*/
838 if (NULL == inPtr)
839 {
840 return -EINVAL;
841 }
842
843 /*no space after the command*/
844 else if (SPACE_ASCII_VALUE != *inPtr)
845 {
846 return -EINVAL;
847 }
848
849 /*removing empty spaces*/
850 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
851
852 /*no argument followed by spaces*/
853 if ('\0' == *inPtr)
854 {
855 return 0;
856 }
857
858 /* getting the first argument which enables or disables RMC
859 * for input IP v4 address*/
Ashish Kumar Dhanotiya54d31a32017-08-04 17:12:44 +0530860 sscanf(inPtr, "%31s ", buf);
Abhishek Singh00b71972016-01-07 10:51:04 +0530861 v = kstrtos32(buf, 10, &tempInt);
862 if ( v < 0)
863 {
864 return -EINVAL;
865 }
866
867 /* Range checking for passed paramter */
868 if (tempInt < WNI_CFG_RMC_ACTION_PERIOD_FREQUENCY_STAMIN ||
869 tempInt > WNI_CFG_RMC_ACTION_PERIOD_FREQUENCY_STAMAX)
870 {
871 return -EINVAL;
872 }
873
874 *pActionPeriod = tempInt;
875
876 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
877 "uActionPeriod: %d", *pActionPeriod);
878
879 return 0;
880}
Sourav Mohapatra9d963282018-02-08 20:03:05 +0530881/*
882 * hdd_set_olpc_mode() - Process the OLPCMODE command and invoke the SME api
883 *
884 * @hHal: context handler
885 * @low_power: Value to be sent as a part of the OLPCMODE command
886 *
887 * Return: void
888 */
889void hdd_set_olpc_mode(tHalHandle hHal, bool low_power)
890{
Sourav Mohapatra6334d0b2020-05-27 12:16:05 +0530891 sme_update_olpc_mode(hHal, low_power);
Sourav Mohapatra9d963282018-02-08 20:03:05 +0530892}
893
Dundi Ravitejae110a042018-04-18 13:11:37 +0530894
895/**
896 * hdd_set_vowifi_mode() - Process VOWIFI command.
897 * @hdd_ctx: context handler
Sourav Mohapatra2416e0e2018-03-05 18:44:21 +0530898 * @enable: Value to be sent as a part of the VOWIFI command
899 *
Dundi Ravitejae110a042018-04-18 13:11:37 +0530900 * Invoke the SME api if station is connected in 2.4 GHz band.
901 * Also start split scan if VOWIFIMODE and dynamic split scan
902 * both are enabled.
903
Sourav Mohapatra2416e0e2018-03-05 18:44:21 +0530904 * Return: void
905 */
906void hdd_set_vowifi_mode(hdd_context_t *hdd_ctx, bool enable)
907{
908 tANI_U8 sta_chan;
909
Dundi Ravitejaab9d3092018-04-05 18:24:40 +0530910 if (!hdd_ctx->cfg_ini) {
911 hddLog(LOGE, "cfg_ini got NULL");
912 return;
913 }
914
Sourav Mohapatra2416e0e2018-03-05 18:44:21 +0530915 sta_chan = hdd_get_operating_channel(hdd_ctx, WLAN_HDD_INFRA_STATION);
916
Dundi Ravitejae110a042018-04-18 13:11:37 +0530917 if (CSR_IS_CHANNEL_24GHZ(sta_chan))
Sourav Mohapatra2416e0e2018-03-05 18:44:21 +0530918 sme_set_vowifi_mode(hdd_ctx->hHal, enable);
Dundi Ravitejae110a042018-04-18 13:11:37 +0530919 else
Sourav Mohapatra2416e0e2018-03-05 18:44:21 +0530920 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
921 "VoWiFi command rejected as not connected in 2.4GHz");
Dundi Ravitejae110a042018-04-18 13:11:37 +0530922
923 if (enable && hdd_ctx->cfg_ini->dynSplitscan) {
924 hdd_ctx->is_vowifi_enabled = true;
925 hdd_ctx->issplitscan_enabled = TRUE;
926 sme_enable_disable_split_scan(hdd_ctx->hHal,
927 hdd_ctx->cfg_ini->nNumStaChanCombinedConc,
928 hdd_ctx->cfg_ini->nNumP2PChanCombinedConc);
929 } else {
930 hdd_ctx->is_vowifi_enabled = false;
Dundi Ravitejaab9d3092018-04-05 18:24:40 +0530931 }
Sourav Mohapatra2416e0e2018-03-05 18:44:21 +0530932}
Abhishek Singh00b71972016-01-07 10:51:04 +0530933
934/* Function header left blank Intentionally */
935static int hdd_parse_setrmcrate_command(tANI_U8 *pValue,
936 tANI_U32 *pRate, tTxrateinfoflags *pTxFlags)
937{
938 tANI_U8 *inPtr = pValue;
939 int tempInt;
940 int v = 0;
941 char buf[32];
942 *pRate = 0;
943 *pTxFlags = 0;
944
945 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
946 /*no argument after the command*/
947 if (NULL == inPtr)
948 {
949 return -EINVAL;
950 }
951
952 /*no space after the command*/
953 else if (SPACE_ASCII_VALUE != *inPtr)
954 {
955 return -EINVAL;
956 }
957
958 /*removing empty spaces*/
959 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
960
961 /*no argument followed by spaces*/
962 if ('\0' == *inPtr)
963 {
964 return 0;
965 }
966
967 /*
968 * getting the first argument which sets multicast rate.
969 */
Ashish Kumar Dhanotiya06f9f202017-08-04 15:26:27 +0530970 sscanf(inPtr, "%31s ", buf);
Abhishek Singh00b71972016-01-07 10:51:04 +0530971 v = kstrtos32(buf, 10, &tempInt);
972 if ( v < 0)
973 {
974 return -EINVAL;
975 }
976
977 /*
978 * Validate the multicast rate.
979 */
980 switch (tempInt)
981 {
982 default:
983 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
984 "Unsupported rate: %d", tempInt);
985 return -EINVAL;
986 case 0:
987 case 6:
988 case 9:
989 case 12:
990 case 18:
991 case 24:
992 case 36:
993 case 48:
994 case 54:
995 *pTxFlags = eHAL_TX_RATE_LEGACY;
996 *pRate = tempInt * 10;
997 break;
998 case 65:
999 *pTxFlags = eHAL_TX_RATE_HT20;
1000 *pRate = tempInt * 10;
1001 break;
1002 case 72:
1003 *pTxFlags = eHAL_TX_RATE_HT20 | eHAL_TX_RATE_SGI;
1004 *pRate = 722; /* fractional rate 72.2 Mbps */
1005 break;
1006 }
1007
1008 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1009 "Rate: %d", *pRate);
1010
1011 return 0;
1012}
1013
1014/**---------------------------------------------------------------------------
1015
1016 \brief hdd_cfg80211_get_ibss_peer_info_cb() - Callback function for IBSS
1017 Peer Info request
1018
1019 This is an asynchronous callback function from SME when the peer info
1020 is received
1021
1022 \pUserData -> Adapter private data
1023 \pPeerInfoRsp -> Peer info response
1024
1025 \return - 0 for success non-zero for failure
1026 --------------------------------------------------------------------------*/
1027static void
1028hdd_cfg80211_get_ibss_peer_info_cb(v_VOID_t *pUserData, v_VOID_t *pPeerInfoRsp)
1029{
1030 hdd_adapter_t *pAdapter = (hdd_adapter_t *)pUserData;
1031 tSirPeerInfoRspParams *pPeerInfo = (tSirPeerInfoRspParams *)pPeerInfoRsp;
1032 hdd_station_ctx_t *pStaCtx;
1033 v_U8_t i;
1034
1035 /*Sanity check*/
1036 if ((NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic))
1037 {
1038 hddLog(LOGE,
1039 FL("invalid adapter or adapter has invalid magic"));
1040 return;
1041 }
1042
1043 pStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
1044 if (NULL != pStaCtx && NULL != pPeerInfo &&
1045 eHAL_STATUS_SUCCESS == pPeerInfo->status)
1046 {
1047 pStaCtx->ibss_peer_info.status = pPeerInfo->status;
1048 pStaCtx->ibss_peer_info.numIBSSPeers = pPeerInfo->numPeers;
1049
1050 /* Paranoia check */
1051 if (pPeerInfo->numPeers < HDD_MAX_NUM_IBSS_STA)
1052 {
1053 for (i = 0; i < pPeerInfo->numPeers; i++)
1054 {
1055 memcpy(&pStaCtx->ibss_peer_info.ibssPeerList[i],
1056 &pPeerInfo->peerInfoParams[i],
1057 sizeof(hdd_ibss_peer_info_params_t));
1058 }
1059 hddLog(LOG1,
1060 FL("Peer Info copied in HDD"));
1061 }
1062 else
1063 {
1064 hddLog(LOGE,
1065 FL(" Number of peers %d returned is more than limit %d"),
1066 pPeerInfo->numPeers, HDD_MAX_NUM_IBSS_STA);
1067 }
1068 }
1069 else
1070 {
1071 hddLog(LOG1,
1072 FL("peerInfo returned is NULL"));
1073 }
1074
1075 complete(&pAdapter->ibss_peer_info_comp);
1076}
1077
1078/**---------------------------------------------------------------------------
1079
1080 \brief hdd_cfg80211_get_ibss_peer_info_all() -
1081
1082 Request function to get IBSS peer info from lower layers
1083
1084 \pAdapter -> Adapter context
1085
1086 \return - 0 for success non-zero for failure
1087 --------------------------------------------------------------------------*/
1088static
1089VOS_STATUS hdd_cfg80211_get_ibss_peer_info_all(hdd_adapter_t *pAdapter)
1090{
1091 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
1092 long status;
1093 VOS_STATUS retStatus = VOS_STATUS_E_FAILURE;
1094
1095 INIT_COMPLETION(pAdapter->ibss_peer_info_comp);
1096
1097 retStatus = sme_RequestIBSSPeerInfo(hHal, pAdapter,
1098 hdd_cfg80211_get_ibss_peer_info_cb,
1099 VOS_TRUE, 0xFF);
1100
1101 if (VOS_STATUS_SUCCESS == retStatus)
1102 {
1103 status = wait_for_completion_interruptible_timeout
1104 (&pAdapter->ibss_peer_info_comp,
1105 msecs_to_jiffies(IBSS_PEER_INFO_REQ_TIMOEUT));
1106
1107 /* status will be 0 if timed out */
1108 if (status <= 0)
1109 {
1110 hddLog(VOS_TRACE_LEVEL_WARN, "%s: Warning: IBSS_PEER_INFO_TIMEOUT %ld",
1111 __func__, status);
1112 retStatus = VOS_STATUS_E_FAILURE;
1113 return retStatus;
1114 }
1115 }
1116 else
1117 {
1118 hddLog(VOS_TRACE_LEVEL_WARN,
1119 "%s: Warning: sme_RequestIBSSPeerInfo Request failed", __func__);
1120 }
1121
1122 return retStatus;
1123}
1124
1125/**---------------------------------------------------------------------------
1126
1127 \brief hdd_cfg80211_get_ibss_peer_info() -
1128
1129 Request function to get IBSS peer info from lower layers
1130
1131 \pAdapter -> Adapter context
1132 \staIdx -> Sta index for which the peer info is requested
1133
1134 \return - 0 for success non-zero for failure
1135 --------------------------------------------------------------------------*/
1136static VOS_STATUS
1137hdd_cfg80211_get_ibss_peer_info(hdd_adapter_t *pAdapter, v_U8_t staIdx)
1138{
1139 long status;
1140 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
1141 VOS_STATUS retStatus = VOS_STATUS_E_FAILURE;
1142
1143 INIT_COMPLETION(pAdapter->ibss_peer_info_comp);
1144
1145 retStatus = sme_RequestIBSSPeerInfo(hHal, pAdapter,
1146 hdd_cfg80211_get_ibss_peer_info_cb,
1147 VOS_FALSE, staIdx);
1148
1149 if (VOS_STATUS_SUCCESS == retStatus)
1150 {
1151 status = wait_for_completion_interruptible_timeout
1152 (&pAdapter->ibss_peer_info_comp,
1153 msecs_to_jiffies(IBSS_PEER_INFO_REQ_TIMOEUT));
1154
1155 /* status = 0 on timeout */
1156 if (status <= 0)
1157 {
1158 hddLog(VOS_TRACE_LEVEL_WARN, "%s: Warning: IBSS_PEER_INFO_TIMEOUT %ld",
1159 __func__, status);
1160 retStatus = VOS_STATUS_E_FAILURE;
1161 return retStatus;
1162 }
1163 }
1164 else
1165 {
1166 hddLog(VOS_TRACE_LEVEL_WARN,
1167 "%s: Warning: sme_RequestIBSSPeerInfo Request failed", __func__);
1168 }
1169
1170 return retStatus;
1171}
1172
1173/* Function header left blank Intentionally */
1174VOS_STATUS
1175hdd_parse_get_ibss_peer_info(tANI_U8 *pValue, v_MACADDR_t *pPeerMacAddr)
1176{
1177 tANI_U8 *inPtr = pValue;
1178 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
1179
1180 /*no argument after the command*/
1181 if (NULL == inPtr)
1182 {
1183 return VOS_STATUS_E_FAILURE;;
1184 }
1185
1186 /*no space after the command*/
1187 else if (SPACE_ASCII_VALUE != *inPtr)
1188 {
1189 return VOS_STATUS_E_FAILURE;;
1190 }
1191
1192 /*removing empty spaces*/
1193 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
1194
1195 /*no argument followed by spaces*/
1196 if ('\0' == *inPtr)
1197 {
1198 return VOS_STATUS_E_FAILURE;;
1199 }
1200
1201 /*getting the first argument ie the peer mac address */
1202 if (inPtr[2] != ':' || inPtr[5] != ':' || inPtr[8] != ':' ||
1203 inPtr[11] != ':' || inPtr[14] != ':')
1204 {
1205 return VOS_STATUS_E_FAILURE;;
1206 }
1207 sscanf(inPtr, "%2x:%2x:%2x:%2x:%2x:%2x",
1208 (unsigned int *)&pPeerMacAddr->bytes[0],
1209 (unsigned int *)&pPeerMacAddr->bytes[1],
1210 (unsigned int *)&pPeerMacAddr->bytes[2],
1211 (unsigned int *)&pPeerMacAddr->bytes[3],
1212 (unsigned int *)&pPeerMacAddr->bytes[4],
1213 (unsigned int *)&pPeerMacAddr->bytes[5]);
1214
1215 /* The command buffer seems to be fine */
1216 return VOS_STATUS_SUCCESS;
1217}
1218
1219/* Function header left blank Intentionally */
1220static int hdd_parse_set_ibss_oui_data_command(tANI_U8 *command, tANI_U8 *ie,
1221 tANI_U32 limit)
1222{
1223 tANI_U8 len;
1224 tANI_U8 data;
1225
1226 /* skip white space */
1227 while ((SPACE_ASCII_VALUE == *command) && ('\0' != *command))
1228 {
1229 command++;
1230 limit--;
1231 }
1232
1233 /* skip element id and element length */
1234 len = 2;
1235
1236 /* extract oui */
1237 while ((SPACE_ASCII_VALUE != *command) && ('\0' != *command) &&
1238 (limit > 1))
1239 {
1240 /* Convert ASCII to decimal */
1241 data = ((*command -'0') << 4) | (*(command + 1) - '0');
1242 ie[len++] = data;
1243 command += 2;
1244 limit -= 2;
1245 }
1246
1247 /* skip white space */
1248 while ((SPACE_ASCII_VALUE == *command) && ('\0' != *command))
1249 {
1250 command++;
1251 limit--;
1252 }
1253
1254 /* extract data */
1255 while ((SPACE_ASCII_VALUE != *command) && ('\0' != *command) &&
1256 (limit > 1))
1257 {
1258 /* Convert ASCII to decimal */
1259 data = ((*command -'0') << 4) | (*(command + 1) - '0');
1260 ie[len++] = data;
1261 command += 2;
1262 limit -= 2;
1263 }
1264
1265 /* fill element id and element length */
1266 ie[0] = IE_EID_VENDOR;
1267 ie[1] = len - 2;
1268
1269 return len;
1270}
1271
1272static tANI_U32 hdd_find_ibss_wpa_ie_pos(tANI_U8 *addIePtr, tANI_U32 addIeLen)
1273{
1274 tANI_U32 ieLenPresent = 0;
1275 int left = addIeLen;
1276 v_U8_t *ptr = addIePtr;
1277 v_U8_t elem_id,elem_len;
1278
1279 while(left >= 2)
1280 {
1281 elem_id = ptr[0];
1282 elem_len = ptr[1];
1283 left -= 2;
1284 if(elem_len > left)
1285 {
1286 hddLog(LOGE,
1287 FL("****Invalid elem_len=%d left=%d*****"),
1288 elem_len,left);
1289 return 0;
1290 }
1291 if ((elem_id == IE_EID_VENDOR) &&
1292 (left >= WPA_OUI_TYPE_SIZE))
1293 {
1294 if (!memcmp(&ptr[2], WPA_OUI_TYPE,
1295 WPA_OUI_TYPE_SIZE))
1296 {
1297 ieLenPresent += elem_len + 2;
1298 return ieLenPresent;
1299 }
1300 }
1301 ieLenPresent += (elem_len + 2);
1302 left -= elem_len;
1303 ptr += (elem_len + 2);
1304 }
1305 return 0;
1306}
1307
1308#endif /* WLAN_FEATURE_RMC */
1309
Rajeev79dbe4c2013-10-05 11:03:42 +05301310#ifdef FEATURE_WLAN_BATCH_SCAN
1311
1312/**---------------------------------------------------------------------------
1313
1314 \brief hdd_extract_assigned_int_from_str() - Extracts assigned integer from
1315 input string
1316
1317 This function extracts assigned integer from string in below format:
1318 "STRING=10" : extracts integer 10 from this string
1319
1320 \param - pInPtr Pointer to input string
1321 \param - base Base for string to int conversion(10 for decimal 16 for hex)
1322 \param - pOutPtr Pointer to variable in which extracted integer needs to be
1323 assigned
1324 \param - pLastArg to tell whether it is last arguement in input string or
1325 not
1326
1327 \return - NULL for failure cases
1328 pointer to next arguement in input string for success cases
1329 --------------------------------------------------------------------------*/
1330static tANI_U8 *
1331hdd_extract_assigned_int_from_str
1332(
1333 tANI_U8 *pInPtr,
1334 tANI_U8 base,
1335 tANI_U32 *pOutPtr,
1336 tANI_U8 *pLastArg
1337)
1338{
1339 int tempInt;
1340 int v = 0;
1341 char buf[32];
1342 int val = 0;
1343 *pLastArg = FALSE;
1344
1345 pInPtr = strnchr(pInPtr, strlen(pInPtr), EQUALS_TO_ASCII_VALUE);
1346 if (NULL == pInPtr)
1347 {
1348 return NULL;
1349 }
1350
1351 pInPtr++;
1352
1353 while ((SPACE_ASCII_VALUE == *pInPtr) && ('\0' != *pInPtr)) pInPtr++;
1354
1355 val = sscanf(pInPtr, "%32s ", buf);
1356 if (val < 0 && val > strlen(pInPtr))
1357 {
1358 return NULL;
1359 }
1360 pInPtr += val;
1361 v = kstrtos32(buf, base, &tempInt);
1362 if (v < 0)
1363 {
1364 return NULL;
1365 }
Rajeev Kumar4d93d842014-01-02 18:31:21 -08001366 if (tempInt < 0)
1367 {
1368 tempInt = 0;
1369 }
Rajeev79dbe4c2013-10-05 11:03:42 +05301370 *pOutPtr = tempInt;
1371
1372 pInPtr = strnchr(pInPtr, strlen(pInPtr), SPACE_ASCII_VALUE);
1373 if (NULL == pInPtr)
1374 {
1375 *pLastArg = TRUE;
1376 return NULL;
1377 }
1378 while ((SPACE_ASCII_VALUE == *pInPtr) && ('\0' != *pInPtr)) pInPtr++;
1379
1380 return pInPtr;
1381}
1382
1383/**---------------------------------------------------------------------------
1384
1385 \brief hdd_extract_assigned_char_from_str() - Extracts assigned char from
1386 input string
1387
1388 This function extracts assigned character from string in below format:
1389 "STRING=A" : extracts char 'A' from this string
1390
1391 \param - pInPtr Pointer to input string
1392 \param - pOutPtr Pointer to variable in which extracted char needs to be
1393 assigned
1394 \param - pLastArg to tell whether it is last arguement in input string or
1395 not
1396
1397 \return - NULL for failure cases
1398 pointer to next arguement in input string for success cases
1399 --------------------------------------------------------------------------*/
1400static tANI_U8 *
1401hdd_extract_assigned_char_from_str
1402(
1403 tANI_U8 *pInPtr,
1404 tANI_U8 *pOutPtr,
1405 tANI_U8 *pLastArg
1406)
1407{
1408 *pLastArg = FALSE;
1409
1410 pInPtr = strnchr(pInPtr, strlen(pInPtr), EQUALS_TO_ASCII_VALUE);
1411 if (NULL == pInPtr)
1412 {
1413 return NULL;
1414 }
1415
1416 pInPtr++;
1417
1418 while ((SPACE_ASCII_VALUE == *pInPtr) && ('\0' != *pInPtr)) pInPtr++;
1419
1420 *pOutPtr = *pInPtr;
1421
1422 pInPtr = strnchr(pInPtr, strlen(pInPtr), SPACE_ASCII_VALUE);
1423 if (NULL == pInPtr)
1424 {
1425 *pLastArg = TRUE;
1426 return NULL;
1427 }
1428 while ((SPACE_ASCII_VALUE == *pInPtr) && ('\0' != *pInPtr)) pInPtr++;
1429
1430 return pInPtr;
1431}
1432
1433
1434/**---------------------------------------------------------------------------
1435
1436 \brief hdd_parse_set_batchscan_command () - HDD parse set batch scan command
1437
1438 This function parses set batch scan command in below format:
1439 WLS_BATCHING_SET <space> followed by below arguements
1440 "SCANFREQ=XX" : Optional defaults to 30 sec
1441 "MSCAN=XX" : Required number of scans to attempt to batch
1442 "BESTN=XX" : Best Network (RSSI) defaults to 16
1443 "CHANNEL=<X,Y>" : optional defaults to all channels, can list 'A'or` B.
1444 A. implies only 5 GHz , B. implies only 2.4GHz
1445 "RTT=X" : optional defaults to 0
1446 returns the MIN of MSCAN or the max # of scans firmware can cache or -1 on
1447 error
1448
1449 For example input commands:
1450 1) WLS_BATCHING_SET SCANFREQ=60 MSCAN=10 BESTN=20 CHANNEL=A RTT=0 -> This is
1451 translated into set batch scan with following parameters:
1452 a) Frequence 60 seconds
1453 b) Batch 10 scans together
1454 c) Best RSSI to be 20
1455 d) 5GHz band only
1456 e) RTT is equal to 0
1457
1458 \param - pValue Pointer to input channel list
1459 \param - pHddSetBatchScanReq Pointer to HDD batch scan request structure
1460
1461 \return - 0 for success non-zero for failure
1462
1463 --------------------------------------------------------------------------*/
1464static int
1465hdd_parse_set_batchscan_command
1466(
1467 tANI_U8 *pValue,
1468 tSirSetBatchScanReq *pHddSetBatchScanReq
1469)
1470{
1471 tANI_U8 *inPtr = pValue;
1472 tANI_U8 val = 0;
1473 tANI_U8 lastArg = 0;
Abhishek Singh00b71972016-01-07 10:51:04 +05301474 tANI_U32 nScanFreq = HDD_SET_BATCH_SCAN_DEFAULT_FREQ;
Rajeev Kumar45e64a72013-11-18 19:48:15 -08001475 tANI_U32 nMscan;
Abhishek Singh00b71972016-01-07 10:51:04 +05301476 tANI_U32 nBestN = HDD_SET_BATCH_SCAN_BEST_NETWORK;
1477 tANI_U8 ucRfBand = HDD_SET_BATCH_SCAN_DEFAULT_BAND;
1478 tANI_U32 nRtt = 0;
Rajeev Kumarc933d982013-11-18 20:04:20 -08001479 tANI_U32 temp;
Rajeev79dbe4c2013-10-05 11:03:42 +05301480
Rajeev79dbe4c2013-10-05 11:03:42 +05301481 /*go to space after WLS_BATCHING_SET command*/
1482 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
1483 /*no argument after the command*/
1484 if (NULL == inPtr)
1485 {
1486 return -EINVAL;
1487 }
1488
1489 /*no space after the command*/
1490 else if (SPACE_ASCII_VALUE != *inPtr)
1491 {
1492 return -EINVAL;
1493 }
1494
1495 /*removing empty spaces*/
1496 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
1497
1498 /*no argument followed by spaces*/
1499 if ('\0' == *inPtr)
1500 {
1501 return -EINVAL;
1502 }
1503
1504 /*check and parse SCANFREQ*/
1505 if ((strncmp(inPtr, "SCANFREQ", 8) == 0))
1506 {
1507 inPtr = hdd_extract_assigned_int_from_str(inPtr, 10,
Rajeev Kumarc933d982013-11-18 20:04:20 -08001508 &temp, &lastArg);
Rajeev Kumar45e64a72013-11-18 19:48:15 -08001509
Rajeev Kumarc933d982013-11-18 20:04:20 -08001510 if (0 != temp)
Rajeev Kumar45e64a72013-11-18 19:48:15 -08001511 {
Rajeev Kumarc933d982013-11-18 20:04:20 -08001512 nScanFreq = temp;
Rajeev Kumar45e64a72013-11-18 19:48:15 -08001513 }
1514
Rajeev79dbe4c2013-10-05 11:03:42 +05301515 if ( (NULL == inPtr) || (TRUE == lastArg))
1516 {
1517 return -EINVAL;
1518 }
1519 }
1520
1521 /*check and parse MSCAN*/
1522 if ((strncmp(inPtr, "MSCAN", 5) == 0))
1523 {
1524 inPtr = hdd_extract_assigned_int_from_str(inPtr, 10,
Rajeev Kumar45e64a72013-11-18 19:48:15 -08001525 &nMscan, &lastArg);
1526
1527 if (0 == nMscan)
1528 {
1529 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1530 "invalid MSCAN=%d", nMscan);
1531 return -EINVAL;
1532 }
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 else
1544 {
1545 return -EINVAL;
1546 }
1547
1548 /*check and parse BESTN*/
1549 if ((strncmp(inPtr, "BESTN", 5) == 0))
1550 {
1551 inPtr = hdd_extract_assigned_int_from_str(inPtr, 10,
Rajeev Kumarc933d982013-11-18 20:04:20 -08001552 &temp, &lastArg);
Rajeev Kumar45e64a72013-11-18 19:48:15 -08001553
Rajeev Kumarc933d982013-11-18 20:04:20 -08001554 if (0 != temp)
Rajeev Kumar45e64a72013-11-18 19:48:15 -08001555 {
Rajeev Kumarc933d982013-11-18 20:04:20 -08001556 nBestN = temp;
Rajeev Kumar45e64a72013-11-18 19:48:15 -08001557 }
1558
Rajeev79dbe4c2013-10-05 11:03:42 +05301559 if (TRUE == lastArg)
1560 {
1561 goto done;
1562 }
1563 else if (NULL == inPtr)
1564 {
1565 return -EINVAL;
1566 }
1567 }
1568
1569 /*check and parse CHANNEL*/
1570 if ((strncmp(inPtr, "CHANNEL", 7) == 0))
1571 {
1572 inPtr = hdd_extract_assigned_char_from_str(inPtr, &val, &lastArg);
Rajeev Kumarc933d982013-11-18 20:04:20 -08001573
Rajeev79dbe4c2013-10-05 11:03:42 +05301574 if (('A' == val) || ('a' == val))
1575 {
c_hpothuebf89732014-02-25 13:00:24 +05301576 ucRfBand = HDD_SET_BATCH_SCAN_5GHz_BAND_ONLY;
Rajeev79dbe4c2013-10-05 11:03:42 +05301577 }
1578 else if (('B' == val) || ('b' == val))
1579 {
c_hpothuebf89732014-02-25 13:00:24 +05301580 ucRfBand = HDD_SET_BATCH_SCAN_24GHz_BAND_ONLY;
Rajeev79dbe4c2013-10-05 11:03:42 +05301581 }
1582 else
1583 {
Rajeev Kumarc933d982013-11-18 20:04:20 -08001584 ucRfBand = HDD_SET_BATCH_SCAN_DEFAULT_BAND;
1585 }
1586
1587 if (TRUE == lastArg)
1588 {
1589 goto done;
1590 }
1591 else if (NULL == inPtr)
1592 {
Rajeev79dbe4c2013-10-05 11:03:42 +05301593 return -EINVAL;
1594 }
1595 }
1596
1597 /*check and parse RTT*/
1598 if ((strncmp(inPtr, "RTT", 3) == 0))
1599 {
1600 inPtr = hdd_extract_assigned_int_from_str(inPtr, 10,
Rajeev Kumar45e64a72013-11-18 19:48:15 -08001601 &nRtt, &lastArg);
Rajeev79dbe4c2013-10-05 11:03:42 +05301602 if (TRUE == lastArg)
1603 {
1604 goto done;
1605 }
1606 if (NULL == inPtr)
1607 {
1608 return -EINVAL;
1609 }
1610 }
1611
1612
1613done:
1614
Rajeev Kumar45e64a72013-11-18 19:48:15 -08001615 pHddSetBatchScanReq->scanFrequency = nScanFreq;
1616 pHddSetBatchScanReq->numberOfScansToBatch = nMscan;
1617 pHddSetBatchScanReq->bestNetwork = nBestN;
1618 pHddSetBatchScanReq->rfBand = ucRfBand;
1619 pHddSetBatchScanReq->rtt = nRtt;
1620
Rajeev79dbe4c2013-10-05 11:03:42 +05301621 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1622 "Received WLS_BATCHING_SET with SCANFREQ=%d "
1623 "MSCAN=%d BESTN=%d CHANNEL=%d RTT=%d",
1624 pHddSetBatchScanReq->scanFrequency,
1625 pHddSetBatchScanReq->numberOfScansToBatch,
1626 pHddSetBatchScanReq->bestNetwork,
1627 pHddSetBatchScanReq->rfBand,
1628 pHddSetBatchScanReq->rtt);
1629
1630 return 0;
1631}/*End of hdd_parse_set_batchscan_command*/
1632
1633/**---------------------------------------------------------------------------
1634
1635 \brief hdd_set_batch_scan_req_callback () - This function is called after
1636 receiving set batch scan response from FW and it saves set batch scan
1637 response data FW to HDD context and sets the completion event on
1638 which hdd_ioctl is waiting
1639
1640 \param - callbackContext Pointer to HDD adapter
1641 \param - pRsp Pointer to set batch scan response data received from FW
1642
1643 \return - nothing
1644
1645 --------------------------------------------------------------------------*/
1646static void hdd_set_batch_scan_req_callback
1647(
1648 void *callbackContext,
1649 tSirSetBatchScanRsp *pRsp
1650)
1651{
1652 hdd_adapter_t* pAdapter = (hdd_adapter_t*)callbackContext;
1653 tSirSetBatchScanRsp *pHddSetBatchScanRsp;
1654
1655 /*sanity check*/
1656 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
1657 {
1658 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1659 "%s: Invalid pAdapter magic", __func__);
1660 VOS_ASSERT(0);
1661 return;
1662 }
1663 pHddSetBatchScanRsp = &pAdapter->hddSetBatchScanRsp;
1664
1665 /*save set batch scan response*/
1666 pHddSetBatchScanRsp->nScansToBatch = pRsp->nScansToBatch;
1667
1668 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
1669 "Received set batch scan rsp from FW with nScansToBatch=%d",
1670 pHddSetBatchScanRsp->nScansToBatch);
1671
1672 pAdapter->hdd_wait_for_set_batch_scan_rsp = FALSE;
1673 complete(&pAdapter->hdd_set_batch_scan_req_var);
1674
1675 return;
1676}/*End of hdd_set_batch_scan_req_callback*/
1677
1678
1679/**---------------------------------------------------------------------------
1680
1681 \brief hdd_populate_batch_scan_rsp_queue () - This function stores AP meta
1682 info in hdd batch scan response queue
1683
1684 \param - pAdapter Pointer to hdd adapter
1685 \param - pAPMetaInfo Pointer to access point meta info
1686 \param - scanId scan ID of batch scan response
1687 \param - isLastAp tells whether AP is last AP in batch scan response or not
1688
1689 \return - nothing
1690
1691 --------------------------------------------------------------------------*/
1692static void hdd_populate_batch_scan_rsp_queue( hdd_adapter_t* pAdapter,
1693 tpSirBatchScanNetworkInfo pApMetaInfo, tANI_U32 scanId, v_BOOL_t isLastAp)
1694{
1695 tHddBatchScanRsp *pHead;
1696 tHddBatchScanRsp *pNode;
1697 tHddBatchScanRsp *pPrev;
1698 tHddBatchScanRsp *pTemp;
1699 tANI_U8 ssidLen;
1700
1701 /*head of hdd batch scan response queue*/
1702 pHead = pAdapter->pBatchScanRsp;
1703
1704 pNode = (tHddBatchScanRsp *)vos_mem_malloc(sizeof(tHddBatchScanRsp));
1705 if (NULL == pNode)
1706 {
1707 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1708 "%s: Could not allocate memory", __func__);
1709 VOS_ASSERT(0);
1710 return;
1711 }
1712
1713 vos_mem_copy(pNode->ApInfo.bssid, pApMetaInfo->bssid,
1714 sizeof(pNode->ApInfo.bssid));
1715 ssidLen = strlen(pApMetaInfo->ssid);
1716 if (SIR_MAX_SSID_SIZE < ssidLen)
1717 {
1718 /*invalid scan result*/
1719 vos_mem_free(pNode);
1720 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1721 "%s: Invalid AP meta info ssidlen %d", __func__, ssidLen);
1722 return;
1723 }
1724 vos_mem_copy(pNode->ApInfo.ssid, pApMetaInfo->ssid, ssidLen);
1725 /*null terminate ssid*/
1726 pNode->ApInfo.ssid[ssidLen] = '\0';
1727 pNode->ApInfo.ch = pApMetaInfo->ch;
1728 pNode->ApInfo.rssi = pApMetaInfo->rssi;
1729 pNode->ApInfo.age = pApMetaInfo->timestamp;
1730 pNode->ApInfo.batchId = scanId;
1731 pNode->ApInfo.isLastAp = isLastAp;
1732
1733 pNode->pNext = NULL;
1734 if (NULL == pHead)
1735 {
1736 pAdapter->pBatchScanRsp = pNode;
1737 }
1738 else
1739 {
1740 pTemp = pHead;
1741 while (NULL != pTemp)
1742 {
1743 pPrev = pTemp;
1744 pTemp = pTemp->pNext;
1745 }
1746 pPrev->pNext = pNode;
1747 }
1748
1749 return;
1750}/*End of hdd_populate_batch_scan_rsp_queue*/
1751
1752/**---------------------------------------------------------------------------
1753
1754 \brief hdd_batch_scan_result_ind_callback () - This function is called after
1755 receiving batch scan response indication from FW. It saves get batch scan
1756 response data in HDD batch scan response queue. This callback sets the
1757 completion event on which hdd_ioctl is waiting only after getting complete
1758 batch scan response data from FW
1759
1760 \param - callbackContext Pointer to HDD adapter
1761 \param - pRsp Pointer to get batch scan response data received from FW
1762
1763 \return - nothing
1764
1765 --------------------------------------------------------------------------*/
1766static void hdd_batch_scan_result_ind_callback
1767(
1768 void *callbackContext,
1769 void *pRsp
1770)
1771{
1772 v_BOOL_t isLastAp;
1773 tANI_U32 numApMetaInfo;
Rajeev Kumarce651e42013-10-21 18:57:15 -07001774 tANI_U32 numNetworkInScanList;
Rajeev79dbe4c2013-10-05 11:03:42 +05301775 tANI_U32 numberScanList;
1776 tANI_U32 nextScanListOffset;
1777 tANI_U32 nextApMetaInfoOffset;
1778 hdd_adapter_t* pAdapter;
1779 tpSirBatchScanList pScanList;
1780 tpSirBatchScanNetworkInfo pApMetaInfo;
1781 tpSirBatchScanResultIndParam pBatchScanRsp;/*batch scan rsp data from FW*/
1782 tSirSetBatchScanReq *pReq;
1783
1784 pAdapter = (hdd_adapter_t *)callbackContext;
1785 /*sanity check*/
Rajeev Kumar5286bb92013-12-05 11:52:10 -08001786 if ((NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic))
Rajeev79dbe4c2013-10-05 11:03:42 +05301787 {
1788 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1789 "%s: Invalid pAdapter magic", __func__);
1790 VOS_ASSERT(0);
1791 return;
1792 }
1793
1794 /*initialize locals*/
1795 pReq = &pAdapter->hddSetBatchScanReq;
1796 pBatchScanRsp = (tpSirBatchScanResultIndParam)pRsp;
1797 isLastAp = FALSE;
1798 numApMetaInfo = 0;
Rajeev Kumarce651e42013-10-21 18:57:15 -07001799 numNetworkInScanList = 0;
Rajeev79dbe4c2013-10-05 11:03:42 +05301800 numberScanList = 0;
1801 nextScanListOffset = 0;
1802 nextApMetaInfoOffset = 0;
1803 pScanList = NULL;
1804 pApMetaInfo = NULL;
1805
1806 if ((NULL == pBatchScanRsp) || (NULL == pReq))
1807 {
1808 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnsonc135a9a2017-09-19 08:37:24 -07001809 "%s: pBatchScanRsp is %pK pReq %pK", __func__, pBatchScanRsp, pReq);
Rajeev79dbe4c2013-10-05 11:03:42 +05301810 isLastAp = TRUE;
1811 goto done;
1812 }
1813
1814 pAdapter->numScanList = numberScanList = pBatchScanRsp->numScanLists;
1815 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1816 "Batch scan rsp: numberScalList %d", numberScanList);
1817
1818 if ((!numberScanList) || (numberScanList > pReq->numberOfScansToBatch))
1819 {
1820 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1821 "%s: numberScanList %d", __func__, numberScanList);
1822 isLastAp = TRUE;
1823 goto done;
1824 }
1825
1826 while (numberScanList)
1827 {
Rajeev Kumarce651e42013-10-21 18:57:15 -07001828 pScanList = (tpSirBatchScanList)((tANI_U8 *)pBatchScanRsp->scanResults +
Rajeev79dbe4c2013-10-05 11:03:42 +05301829 nextScanListOffset);
1830 if (NULL == pScanList)
1831 {
1832 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnsonc135a9a2017-09-19 08:37:24 -07001833 "%s: pScanList is %pK", __func__, pScanList);
Rajeev79dbe4c2013-10-05 11:03:42 +05301834 isLastAp = TRUE;
1835 goto done;
1836 }
Rajeev Kumarce651e42013-10-21 18:57:15 -07001837 numNetworkInScanList = numApMetaInfo = pScanList->numNetworksInScanList;
Rajeev79dbe4c2013-10-05 11:03:42 +05301838 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Rajeev Kumarce651e42013-10-21 18:57:15 -07001839 "Batch scan rsp: numApMetaInfo %d scanId %d",
1840 numApMetaInfo, pScanList->scanId);
Rajeev79dbe4c2013-10-05 11:03:42 +05301841
1842 if ((!numApMetaInfo) || (numApMetaInfo > pReq->bestNetwork))
1843 {
1844 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1845 "%s: numApMetaInfo %d", __func__, numApMetaInfo);
1846 isLastAp = TRUE;
1847 goto done;
1848 }
1849
Rajeev Kumarce651e42013-10-21 18:57:15 -07001850 /*Initialize next AP meta info offset for next scan list*/
1851 nextApMetaInfoOffset = 0;
1852
Rajeev79dbe4c2013-10-05 11:03:42 +05301853 while (numApMetaInfo)
1854 {
1855 pApMetaInfo = (tpSirBatchScanNetworkInfo)(pScanList->scanList +
1856 nextApMetaInfoOffset);
1857 if (NULL == pApMetaInfo)
1858 {
1859 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnsonc135a9a2017-09-19 08:37:24 -07001860 "%s: pApMetaInfo is %pK", __func__, pApMetaInfo);
Rajeev79dbe4c2013-10-05 11:03:42 +05301861 isLastAp = TRUE;
1862 goto done;
1863 }
1864 /*calculate AP age*/
1865 pApMetaInfo->timestamp =
1866 pBatchScanRsp->timestamp - pApMetaInfo->timestamp;
1867
1868 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
Arif Hussaina7c8e412013-11-20 11:06:42 -08001869 "%s: bssId "MAC_ADDRESS_STR
1870 " ch %d rssi %d timestamp %d", __func__,
1871 MAC_ADDR_ARRAY(pApMetaInfo->bssid),
1872 pApMetaInfo->ch, pApMetaInfo->rssi,
1873 pApMetaInfo->timestamp);
Rajeev79dbe4c2013-10-05 11:03:42 +05301874
1875 /*mark last AP in batch scan response*/
1876 if ((TRUE == pBatchScanRsp->isLastResult) &&
1877 (1 == numberScanList) && (1 == numApMetaInfo))
1878 {
1879 isLastAp = TRUE;
1880 }
1881
1882 mutex_lock(&pAdapter->hdd_batch_scan_lock);
1883 /*store batch scan repsonse in hdd queue*/
1884 hdd_populate_batch_scan_rsp_queue(pAdapter, pApMetaInfo,
1885 pScanList->scanId, isLastAp);
1886 mutex_unlock(&pAdapter->hdd_batch_scan_lock);
1887
1888 nextApMetaInfoOffset += sizeof(tSirBatchScanNetworkInfo);
1889 numApMetaInfo--;
1890 }
1891
Rajeev Kumarce651e42013-10-21 18:57:15 -07001892 nextScanListOffset += ((sizeof(tSirBatchScanList) - sizeof(tANI_U8))
1893 + (sizeof(tSirBatchScanNetworkInfo)
1894 * numNetworkInScanList));
Rajeev79dbe4c2013-10-05 11:03:42 +05301895 numberScanList--;
1896 }
1897
1898done:
1899
1900 /*notify hdd_ioctl only if complete batch scan rsp is received and it was
1901 requested from hdd_ioctl*/
1902 if ((TRUE == pAdapter->hdd_wait_for_get_batch_scan_rsp) &&
1903 (TRUE == isLastAp))
1904 {
1905 pAdapter->hdd_wait_for_get_batch_scan_rsp = FALSE;
1906 complete(&pAdapter->hdd_get_batch_scan_req_var);
1907 }
1908
1909 return;
1910}/*End of hdd_batch_scan_result_ind_callback*/
1911
1912/**---------------------------------------------------------------------------
1913
1914 \brief hdd_format_batch_scan_rsp () - This function formats batch scan
1915 response as per batch scan FR request format by putting proper markers
1916
1917 \param - pDest pointer to destination buffer
1918 \param - cur_len current length
1919 \param - tot_len total remaining size which can be written to user space
1920 \param - pApMetaInfo Pointer to get batch scan response AP meta info
1921 \param - pAdapter Pointer to HDD adapter
1922
1923 \return - ret no of characters written
1924
1925 --------------------------------------------------------------------------*/
1926static tANI_U32
1927hdd_format_batch_scan_rsp
1928(
1929 tANI_U8 *pDest,
1930 tANI_U32 cur_len,
1931 tANI_U32 tot_len,
1932 tHddBatchScanRsp *pApMetaInfo,
1933 hdd_adapter_t* pAdapter
1934)
1935{
1936 tANI_U32 ret = 0;
1937 tANI_U32 rem_len = 0;
1938 tANI_U8 temp_len = 0;
1939 tANI_U8 temp_total_len = 0;
1940 tANI_U8 temp[HDD_BATCH_SCAN_AP_META_INFO_SIZE];
1941 tANI_U8 *pTemp = temp;
1942
1943 /*Batch scan reponse needs to be returned to user space in
1944 following format:
1945 "scancount=X\n" where X is the number of scans in current batch
1946 batch
1947 "trunc\n" optional present if current scan truncated
1948 "bssid=XX:XX:XX:XX:XX:XX\n"
1949 "ssid=XXXX\n"
1950 "freq=X\n" frequency in Mhz
1951 "level=XX\n"
1952 "age=X\n" ms
1953 "dist=X\n" cm (-1 if not available)
1954 "errror=X\n" (-1if not available)
1955 "====\n" (end of ap marker)
1956 "####\n" (end of scan marker)
1957 "----\n" (end of results)*/
1958 /*send scan result in above format to user space based on
1959 available length*/
1960 /*The GET response may have more data than the driver can return in its
1961 buffer. In that case the buffer should be filled to the nearest complete
1962 scan, ending with "%%%%".Subsequent callsshould return the remaining data
1963 starting with the next scan (optional .trunc\n., .apcount=X\n., etc).
1964 The final buffer should end with "----\n"*/
1965
1966 /*sanity*/
1967 if (cur_len > tot_len)
1968 {
1969 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1970 "%s: invaid cur_len %d tot_len %d", __func__, cur_len, tot_len);
1971 return 0;
1972 }
1973 else
1974 {
1975 rem_len = (tot_len - cur_len);
1976 }
1977
1978 /*end scan marker*/
1979 if (pApMetaInfo->ApInfo.batchId != pAdapter->prev_batch_id)
1980 {
1981 temp_len = snprintf(pTemp, sizeof(temp), "####\n");
1982 pTemp += temp_len;
1983 temp_total_len += temp_len;
1984 }
1985
1986 /*bssid*/
1987 temp_len = snprintf(pTemp, sizeof(temp),
1988 "bssid=0x%x:0x%x:0x%x:0x%x:0x%x:0x%x\n",
1989 pApMetaInfo->ApInfo.bssid[0], pApMetaInfo->ApInfo.bssid[1],
1990 pApMetaInfo->ApInfo.bssid[2], pApMetaInfo->ApInfo.bssid[3],
1991 pApMetaInfo->ApInfo.bssid[4], pApMetaInfo->ApInfo.bssid[5]);
1992 pTemp += temp_len;
1993 temp_total_len += temp_len;
1994
1995 /*ssid*/
1996 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "ssid=%s\n",
1997 pApMetaInfo->ApInfo.ssid);
1998 pTemp += temp_len;
1999 temp_total_len += temp_len;
2000
2001 /*freq*/
2002 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "freq=%d\n",
Rajeev Kumarc40f7512013-11-04 14:13:23 -08002003 sme_ChnToFreq(pApMetaInfo->ApInfo.ch));
Rajeev79dbe4c2013-10-05 11:03:42 +05302004 pTemp += temp_len;
2005 temp_total_len += temp_len;
2006
2007 /*level*/
2008 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "level=%d\n",
2009 pApMetaInfo->ApInfo.rssi);
2010 pTemp += temp_len;
2011 temp_total_len += temp_len;
2012
2013 /*age*/
Jeff Johnson02797792013-10-26 19:17:13 -07002014 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "age=%d\n",
Rajeev79dbe4c2013-10-05 11:03:42 +05302015 pApMetaInfo->ApInfo.age);
2016 pTemp += temp_len;
2017 temp_total_len += temp_len;
2018
2019 /*dist*/
2020 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "dist=-1\n");
2021 pTemp += temp_len;
2022 temp_total_len += temp_len;
2023
2024 /*error*/
2025 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "error=-1\n");
2026 pTemp += temp_len;
2027 temp_total_len += temp_len;
2028
2029 /*end AP marker*/
2030 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "====\n");
2031 pTemp += temp_len;
2032 temp_total_len += temp_len;
2033
2034 /*last AP in batch scan response*/
2035 if(TRUE == pApMetaInfo->ApInfo.isLastAp)
2036 {
2037 /*end scan marker*/
2038 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "####\n");
2039 pTemp += temp_len;
2040 temp_total_len += temp_len;
2041
2042 /*end batch scan result marker*/
2043 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "----\n");
2044 pTemp += temp_len;
2045 temp_total_len += temp_len;
Kiet Lamaa8e15a2014-02-11 23:30:06 -08002046
Rajeev79dbe4c2013-10-05 11:03:42 +05302047 }
2048
2049 if (temp_total_len < rem_len)
2050 {
2051 ret = temp_total_len + 1;
2052 strlcpy(pDest, temp, ret);
2053 pAdapter->isTruncated = FALSE;
2054 }
2055 else
2056 {
2057 pAdapter->isTruncated = TRUE;
2058 if (rem_len >= strlen("%%%%"))
2059 {
Rajeev Kumarc933d982013-11-18 20:04:20 -08002060 ret = snprintf(pDest, sizeof(temp), "%%%%");
Rajeev79dbe4c2013-10-05 11:03:42 +05302061 }
Rajeev Kumarc933d982013-11-18 20:04:20 -08002062 else
Rajeev79dbe4c2013-10-05 11:03:42 +05302063 {
2064 ret = 0;
2065 }
2066 }
2067
2068 return ret;
2069
2070}/*End of hdd_format_batch_scan_rsp*/
2071
2072/**---------------------------------------------------------------------------
2073
2074 \brief hdd_populate_user_batch_scan_rsp() - This function populates user data
2075 buffer starting with head of hdd batch scan response queue
2076
2077 \param - pAdapter Pointer to HDD adapter
2078 \param - pDest Pointer to user data buffer
2079 \param - cur_len current offset in user buffer
2080 \param - rem_len remaining no of bytes in user buffer
2081
2082 \return - number of bytes written in user buffer
2083
2084 --------------------------------------------------------------------------*/
2085
2086tANI_U32 hdd_populate_user_batch_scan_rsp
2087(
2088 hdd_adapter_t* pAdapter,
2089 tANI_U8 *pDest,
2090 tANI_U32 cur_len,
2091 tANI_U32 rem_len
2092)
2093{
2094 tHddBatchScanRsp *pHead;
2095 tHddBatchScanRsp *pPrev;
2096 tANI_U32 len;
2097
Rajeev79dbe4c2013-10-05 11:03:42 +05302098 pAdapter->isTruncated = FALSE;
2099
2100 /*head of hdd batch scan response queue*/
2101 pHead = pAdapter->pBatchScanRsp;
2102 while (pHead)
2103 {
2104 len = hdd_format_batch_scan_rsp(pDest, cur_len, rem_len, pHead,
2105 pAdapter);
2106 pDest += len;
Rajeev Kumar292d2bb2013-10-23 15:01:44 -07002107 pDest--;
Rajeev79dbe4c2013-10-05 11:03:42 +05302108 cur_len += len;
2109 if(TRUE == pAdapter->isTruncated)
2110 {
2111 /*result is truncated return rest of scan rsp in next req*/
2112 cur_len = rem_len;
2113 break;
2114 }
2115 pPrev = pHead;
2116 pHead = pHead->pNext;
2117 pAdapter->pBatchScanRsp = pHead;
Rajeev Kumarbe17d8b2014-01-10 15:39:45 -08002118 if (TRUE == pPrev->ApInfo.isLastAp)
2119 {
2120 pAdapter->prev_batch_id = 0;
2121 }
2122 else
2123 {
2124 pAdapter->prev_batch_id = pPrev->ApInfo.batchId;
2125 }
Rajeev79dbe4c2013-10-05 11:03:42 +05302126 vos_mem_free(pPrev);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08002127 pPrev = NULL;
Rajeev79dbe4c2013-10-05 11:03:42 +05302128 }
2129
2130 return cur_len;
2131}/*End of hdd_populate_user_batch_scan_rsp*/
2132
2133/**---------------------------------------------------------------------------
2134
2135 \brief hdd_return_batch_scan_rsp_to_user () - This function returns batch
2136 scan response data from HDD queue to user space
2137 It does following in detail:
2138 a) if HDD has enough data in its queue then it 1st copies data to user
2139 space and then send get batch scan indication message to FW. In this
2140 case it does not wait on any event and batch scan response data will
2141 be populated in HDD response queue in MC thread context after receiving
2142 indication from FW
2143 b) else send get batch scan indication message to FW and wait on an event
2144 which will be set once HDD receives complete batch scan response from
2145 FW and then this function returns batch scan response to user space
2146
2147 \param - pAdapter Pointer to HDD adapter
2148 \param - pPrivData Pointer to priv_data
2149
2150 \return - 0 for success -EFAULT for failure
2151
2152 --------------------------------------------------------------------------*/
2153
2154int hdd_return_batch_scan_rsp_to_user
2155(
2156 hdd_adapter_t* pAdapter,
2157 hdd_priv_data_t *pPrivData,
2158 tANI_U8 *command
2159)
2160{
2161 tANI_U8 *pDest;
2162 tANI_U32 count = 0;
2163 tANI_U32 len = 0;
2164 tANI_U32 cur_len = 0;
2165 tANI_U32 rem_len = 0;
2166 eHalStatus halStatus;
2167 unsigned long rc;
2168 tSirTriggerBatchScanResultInd *pReq;
2169
2170 pReq = &pAdapter->hddTriggerBatchScanResultInd;
2171 pReq->param = 0;/*batch scan client*/
2172 pDest = (tANI_U8 *)(command + pPrivData->used_len);
2173 pAdapter->hdd_wait_for_get_batch_scan_rsp = FALSE;
2174
2175 cur_len = pPrivData->used_len;
2176 if (pPrivData->total_len > pPrivData->used_len)
2177 {
2178 rem_len = pPrivData->total_len - pPrivData->used_len;
2179 }
2180 else
2181 {
2182 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2183 "%s: Invalid user data buffer total_len %d used_len %d",
2184 __func__, pPrivData->total_len, pPrivData->used_len);
2185 return -EFAULT;
2186 }
2187
2188 mutex_lock(&pAdapter->hdd_batch_scan_lock);
2189 len = hdd_populate_user_batch_scan_rsp(pAdapter, pDest,
2190 cur_len, rem_len);
2191 mutex_unlock(&pAdapter->hdd_batch_scan_lock);
2192
2193 /*enough scan result available in cache to return to user space or
2194 scan result needs to be fetched 1st from fw and then return*/
Rajeev Kumar99db6262013-11-11 15:23:36 -08002195 if (len == cur_len)
Rajeev79dbe4c2013-10-05 11:03:42 +05302196 {
2197 pAdapter->hdd_wait_for_get_batch_scan_rsp = TRUE;
2198 halStatus = sme_TriggerBatchScanResultInd(
2199 WLAN_HDD_GET_HAL_CTX(pAdapter), pReq,
2200 pAdapter->sessionId, hdd_batch_scan_result_ind_callback,
2201 pAdapter);
2202 if ( eHAL_STATUS_SUCCESS == halStatus )
2203 {
2204 if (TRUE == pAdapter->hdd_wait_for_get_batch_scan_rsp)
2205 {
2206 INIT_COMPLETION(pAdapter->hdd_get_batch_scan_req_var);
2207 rc = wait_for_completion_timeout(
2208 &pAdapter->hdd_get_batch_scan_req_var,
2209 msecs_to_jiffies(HDD_GET_BATCH_SCAN_RSP_TIME_OUT));
Abhishek Singh00b71972016-01-07 10:51:04 +05302210 if (0 >= rc)
Rajeev79dbe4c2013-10-05 11:03:42 +05302211 {
2212 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Abhishek Singh00b71972016-01-07 10:51:04 +05302213 "%s: wait on hdd_get_batch_scan_req_var failed %ld",
2214 __func__, rc);
Rajeev79dbe4c2013-10-05 11:03:42 +05302215 return -EFAULT;
2216 }
2217 }
2218
2219 len = snprintf(pDest, HDD_BATCH_SCAN_AP_META_INFO_SIZE,
Jeff Johnson02797792013-10-26 19:17:13 -07002220 "scancount=%u\n", pAdapter->numScanList);
Rajeev79dbe4c2013-10-05 11:03:42 +05302221 pDest += len;
2222 cur_len += len;
2223
2224 mutex_lock(&pAdapter->hdd_batch_scan_lock);
2225 len = hdd_populate_user_batch_scan_rsp(pAdapter, pDest,
2226 cur_len, rem_len);
2227 mutex_unlock(&pAdapter->hdd_batch_scan_lock);
2228
2229 count = 0;
2230 len = (len - pPrivData->used_len);
2231 pDest = (command + pPrivData->used_len);
2232 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Rajeev Kumar99db6262013-11-11 15:23:36 -08002233 "NEW BATCH SCAN RESULT:");
Rajeev79dbe4c2013-10-05 11:03:42 +05302234 while(count < len)
2235 {
2236 printk("%c", *(pDest + count));
2237 count++;
2238 }
2239 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2240 "%s: copy %d data to user buffer", __func__, len);
2241 if (copy_to_user(pPrivData->buf, pDest, len))
2242 {
2243 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2244 "%s: failed to copy data to user buffer", __func__);
2245 return -EFAULT;
2246 }
2247 }
2248 else
2249 {
2250 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2251 "sme_GetBatchScanScan returned failure halStatus %d",
2252 halStatus);
2253 return -EINVAL;
2254 }
2255 }
2256 else
2257 {
Rajeev79dbe4c2013-10-05 11:03:42 +05302258 count = 0;
2259 len = (len - pPrivData->used_len);
2260 pDest = (command + pPrivData->used_len);
2261 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Rajeev Kumar99db6262013-11-11 15:23:36 -08002262 "REMAINING TRUNCATED BATCH SCAN RESULT:");
Rajeev79dbe4c2013-10-05 11:03:42 +05302263 while(count < len)
2264 {
2265 printk("%c", *(pDest + count));
2266 count++;
2267 }
Rajeev Kumar99db6262013-11-11 15:23:36 -08002268 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2269 "%s: copy %d data to user buffer", __func__, len);
Rajeev79dbe4c2013-10-05 11:03:42 +05302270 if (copy_to_user(pPrivData->buf, pDest, len))
2271 {
2272 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2273 "%s: failed to copy data to user buffer", __func__);
2274 return -EFAULT;
2275 }
Rajeev79dbe4c2013-10-05 11:03:42 +05302276 }
2277
2278 return 0;
2279} /*End of hdd_return_batch_scan_rsp_to_user*/
2280
Rajeev Kumar8b373292014-01-08 20:36:55 -08002281/**---------------------------------------------------------------------------
2282
2283 \brief hdd_handle_batch_scan_ioctl () - This function handles WLS_BATCHING
2284 IOCTLs from user space. Following BATCH SCAN DEV IOCTs are handled:
2285 WLS_BATCHING VERSION
2286 WLS_BATCHING SET
2287 WLS_BATCHING GET
2288 WLS_BATCHING STOP
2289
2290 \param - pAdapter Pointer to HDD adapter
2291 \param - pPrivdata Pointer to priv_data
2292 \param - command Pointer to command
2293
2294 \return - 0 for success -EFAULT for failure
2295
2296 --------------------------------------------------------------------------*/
2297
2298int hdd_handle_batch_scan_ioctl
2299(
2300 hdd_adapter_t *pAdapter,
2301 hdd_priv_data_t *pPrivdata,
2302 tANI_U8 *command
2303)
2304{
2305 int ret = 0;
Yue Mae36e3552014-03-05 17:06:20 -08002306 hdd_context_t *pHddCtx;
2307
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302308 ENTER();
2309
Yue Mae36e3552014-03-05 17:06:20 -08002310 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
2311 ret = wlan_hdd_validate_context(pHddCtx);
2312 if (ret)
2313 {
Yue Mae36e3552014-03-05 17:06:20 -08002314 goto exit;
2315 }
Rajeev Kumar8b373292014-01-08 20:36:55 -08002316
2317 if (strncmp(command, "WLS_BATCHING VERSION", 20) == 0)
2318 {
2319 char extra[32];
2320 tANI_U8 len = 0;
2321 tANI_U8 version = HDD_BATCH_SCAN_VERSION;
2322
2323 if (FALSE == sme_IsFeatureSupportedByFW(BATCH_SCAN))
2324 {
2325 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2326 "%s: Batch scan feature is not supported by FW", __func__);
2327 ret = -EINVAL;
2328 goto exit;
2329 }
2330
2331 len = scnprintf(extra, sizeof(extra), "WLS_BATCHING_VERSION %d",
2332 version);
2333 if (copy_to_user(pPrivdata->buf, &extra, len + 1))
2334 {
2335 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2336 "%s: failed to copy data to user buffer", __func__);
2337 ret = -EFAULT;
2338 goto exit;
2339 }
2340 ret = HDD_BATCH_SCAN_VERSION;
2341 }
2342 else if (strncmp(command, "WLS_BATCHING SET", 16) == 0)
2343 {
2344 int status;
2345 tANI_U8 *value = (command + 16);
2346 eHalStatus halStatus;
2347 unsigned long rc;
2348 tSirSetBatchScanReq *pReq = &pAdapter->hddSetBatchScanReq;
2349 tSirSetBatchScanRsp *pRsp = &pAdapter->hddSetBatchScanRsp;
2350
2351 if (FALSE == sme_IsFeatureSupportedByFW(BATCH_SCAN))
2352 {
2353 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2354 "%s: Batch scan feature is not supported by FW", __func__);
2355 ret = -EINVAL;
2356 goto exit;
2357 }
2358
2359 if ((WLAN_HDD_INFRA_STATION != pAdapter->device_mode) &&
2360 (WLAN_HDD_P2P_CLIENT != pAdapter->device_mode) &&
2361 (WLAN_HDD_P2P_GO != pAdapter->device_mode) &&
2362 (WLAN_HDD_P2P_DEVICE != pAdapter->device_mode))
2363 {
2364 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05302365 "Received WLS_BATCHING SET command in invalid mode %s (%d) "
Rajeev Kumar8b373292014-01-08 20:36:55 -08002366 "WLS_BATCHING_SET is only allowed in infra STA/P2P client mode",
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05302367 hdd_device_modetoString(pAdapter->device_mode),
2368 pAdapter->device_mode);
Rajeev Kumar8b373292014-01-08 20:36:55 -08002369 ret = -EINVAL;
2370 goto exit;
2371 }
2372
2373 status = hdd_parse_set_batchscan_command(value, pReq);
2374 if (status)
2375 {
2376 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2377 "Invalid WLS_BATCHING SET command");
2378 ret = -EINVAL;
2379 goto exit;
2380 }
2381
2382
2383 pAdapter->hdd_wait_for_set_batch_scan_rsp = TRUE;
2384 halStatus = sme_SetBatchScanReq(WLAN_HDD_GET_HAL_CTX(pAdapter), pReq,
2385 pAdapter->sessionId, hdd_set_batch_scan_req_callback,
2386 pAdapter);
2387
2388 if ( eHAL_STATUS_SUCCESS == halStatus )
2389 {
Mahesh A Saptasagar5f568172014-05-14 17:02:33 +05302390 char extra[32];
2391 tANI_U8 len = 0;
2392 tANI_U8 mScan = 0;
2393
Rajeev Kumar8b373292014-01-08 20:36:55 -08002394 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2395 "sme_SetBatchScanReq returned success halStatus %d",
2396 halStatus);
2397 if (TRUE == pAdapter->hdd_wait_for_set_batch_scan_rsp)
2398 {
2399 INIT_COMPLETION(pAdapter->hdd_set_batch_scan_req_var);
2400 rc = wait_for_completion_timeout(
2401 &pAdapter->hdd_set_batch_scan_req_var,
2402 msecs_to_jiffies(HDD_SET_BATCH_SCAN_REQ_TIME_OUT));
2403 if (0 == rc)
2404 {
2405 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2406 "%s: Timeout waiting for set batch scan to complete",
2407 __func__);
2408 ret = -EINVAL;
2409 goto exit;
2410 }
2411 }
2412 if ( !pRsp->nScansToBatch )
2413 {
2414 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2415 "%s: Received set batch scan failure response from FW",
2416 __func__);
2417 ret = -EINVAL;
2418 goto exit;
2419 }
2420 /*As per the Batch Scan Framework API we should return the MIN of
2421 either MSCAN or the max # of scans firmware can cache*/
Mahesh A Saptasagar5f568172014-05-14 17:02:33 +05302422 mScan = MIN(pReq->numberOfScansToBatch , pRsp->nScansToBatch);
Rajeev Kumar8b373292014-01-08 20:36:55 -08002423
2424 pAdapter->batchScanState = eHDD_BATCH_SCAN_STATE_STARTED;
2425
2426 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2427 "%s: request MSCAN %d response MSCAN %d ret %d",
Mahesh A Saptasagar5f568172014-05-14 17:02:33 +05302428 __func__, pReq->numberOfScansToBatch, pRsp->nScansToBatch, mScan);
2429 len = scnprintf(extra, sizeof(extra), "%d", mScan);
2430 if (copy_to_user(pPrivdata->buf, &extra, len + 1))
2431 {
2432 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2433 "%s: failed to copy MSCAN value to user buffer", __func__);
2434 ret = -EFAULT;
2435 goto exit;
2436 }
Rajeev Kumar8b373292014-01-08 20:36:55 -08002437 }
2438 else
2439 {
2440 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2441 "sme_SetBatchScanReq returned failure halStatus %d",
2442 halStatus);
2443 ret = -EINVAL;
2444 goto exit;
2445 }
2446 }
2447 else if (strncmp(command, "WLS_BATCHING STOP", 17) == 0)
2448 {
2449 eHalStatus halStatus;
2450 tSirStopBatchScanInd *pInd = &pAdapter->hddStopBatchScanInd;
2451 pInd->param = 0;
2452
2453 if (FALSE == sme_IsFeatureSupportedByFW(BATCH_SCAN))
2454 {
2455 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2456 "%s: Batch scan feature is not supported by FW", __func__);
2457 ret = -EINVAL;
2458 goto exit;
2459 }
2460
2461 if (eHDD_BATCH_SCAN_STATE_STARTED != pAdapter->batchScanState)
2462 {
Deepthi Gowribfd17132014-11-14 17:59:04 +05302463 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Rajeev Kumar8b373292014-01-08 20:36:55 -08002464 "Batch scan is not yet enabled batch scan state %d",
2465 pAdapter->batchScanState);
2466 ret = -EINVAL;
2467 goto exit;
2468 }
2469
Kiet Lamaa8e15a2014-02-11 23:30:06 -08002470 mutex_lock(&pAdapter->hdd_batch_scan_lock);
2471 hdd_deinit_batch_scan(pAdapter);
2472 mutex_unlock(&pAdapter->hdd_batch_scan_lock);
2473
Rajeev Kumar8b373292014-01-08 20:36:55 -08002474 pAdapter->batchScanState = eHDD_BATCH_SCAN_STATE_STOPPED;
2475
2476 halStatus = sme_StopBatchScanInd(WLAN_HDD_GET_HAL_CTX(pAdapter), pInd,
2477 pAdapter->sessionId);
2478 if ( eHAL_STATUS_SUCCESS == halStatus )
2479 {
2480 ret = 0;
2481 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2482 "sme_StopBatchScanInd returned success halStatus %d",
2483 halStatus);
2484 }
2485 else
2486 {
2487 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2488 "sme_StopBatchScanInd returned failure halStatus %d",
2489 halStatus);
2490 ret = -EINVAL;
2491 goto exit;
2492 }
2493 }
2494 else if (strncmp(command, "WLS_BATCHING GET", 16) == 0)
2495 {
2496 tANI_U32 remain_len;
2497
2498 if (FALSE == sme_IsFeatureSupportedByFW(BATCH_SCAN))
2499 {
2500 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2501 "%s: Batch scan feature is not supported by FW", __func__);
2502 ret = -EINVAL;
2503 goto exit;
2504 }
2505
2506 if (eHDD_BATCH_SCAN_STATE_STARTED != pAdapter->batchScanState)
2507 {
Deepthi Gowribfd17132014-11-14 17:59:04 +05302508 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Rajeev Kumar8b373292014-01-08 20:36:55 -08002509 "Batch scan is not yet enabled could not return results"
2510 "Batch Scan state %d",
2511 pAdapter->batchScanState);
2512 ret = -EINVAL;
2513 goto exit;
2514 }
2515
2516 pPrivdata->used_len = 16;
2517 remain_len = pPrivdata->total_len - pPrivdata->used_len;
2518 if (remain_len < pPrivdata->total_len)
2519 {
2520 /*Clear previous batch scan response data if any*/
2521 vos_mem_zero((tANI_U8 *)(command + pPrivdata->used_len), remain_len);
2522 }
2523 else
2524 {
2525 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2526 "Invalid total length from user space can't fetch batch"
2527 " scan response total_len %d used_len %d remain len %d",
2528 pPrivdata->total_len, pPrivdata->used_len, remain_len);
2529 ret = -EINVAL;
2530 goto exit;
2531 }
2532 ret = hdd_return_batch_scan_rsp_to_user(pAdapter, pPrivdata, command);
2533 }
2534
2535exit:
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302536 EXIT();
Rajeev Kumar8b373292014-01-08 20:36:55 -08002537 return ret;
2538}
2539
2540
Rajeev79dbe4c2013-10-05 11:03:42 +05302541#endif/*End of FEATURE_WLAN_BATCH_SCAN*/
2542
Selvaraj, Sridhar5aff1ed2016-06-18 01:26:23 +05302543#if defined(WLAN_FEATURE_VOWIFI_11R) || defined(FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
2544/**
2545 * hdd_assign_handoff_src_reassoc - Set handoff source as REASSOC
2546 * to Handoff request
2547 * @handoffInfo: Pointer to Handoff request
2548 * @src: enum of handoff_src
2549 * Return: None
2550 */
2551#ifndef QCA_WIFI_ISOC
2552static inline void hdd_assign_handoff_src_reassoc(tCsrHandoffRequest
2553 *handoffInfo, handoff_src src)
2554{
2555 handoffInfo->src = src;
2556}
2557#else
2558static inline void hdd_assign_handoff_src_reassoc(tCsrHandoffRequest
2559 *handoffInfo, handoff_src src)
2560{
2561}
2562#endif
2563
2564/**
Selvaraj, Sridhar4fa15232016-06-18 12:27:25 +05302565 * hdd_reassoc() - perform a user space-directed reassoc
Selvaraj, Sridhar5aff1ed2016-06-18 01:26:23 +05302566 *
2567 * @pAdapter: Adapter upon which the command was received
2568 * @bssid: BSSID with which to reassociate
2569 * @channel: channel upon which to reassociate
Selvaraj, Sridhar4fa15232016-06-18 12:27:25 +05302570 * @src: The source for the trigger of this action
Selvaraj, Sridhar5aff1ed2016-06-18 01:26:23 +05302571 *
2572 * Return: 0 for success non-zero for failure
2573 */
2574#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
Selvaraj, Sridhar8ecb4192016-06-23 17:50:49 +05302575int hdd_reassoc(hdd_adapter_t *pAdapter, const tANI_U8 *bssid,
Selvaraj, Sridhar4fa15232016-06-18 12:27:25 +05302576 const tANI_U8 channel, const handoff_src src)
Selvaraj, Sridhar5aff1ed2016-06-18 01:26:23 +05302577{
2578 hdd_station_ctx_t *pHddStaCtx;
2579 tCsrHandoffRequest handoffInfo;
2580 hdd_context_t *pHddCtx = NULL;
2581 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
2582
2583 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
2584
2585 /* if not associated, no need to proceed with reassoc */
2586 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState) {
2587 hddLog(LOG1, FL("Not associated"));
2588 return -EINVAL;
2589 }
2590
2591 /* if the target bssid is same as currently associated AP,
2592 then no need to proceed with reassoc */
2593 if (!memcmp(bssid, pHddStaCtx->conn_info.bssId, sizeof(tSirMacAddr))) {
2594 hddLog(LOG1, FL("Reassoc BSSID is same as currently associated AP bssid"));
2595 return -EINVAL;
2596 }
2597
2598 /* Check channel number is a valid channel number */
2599 if (VOS_STATUS_SUCCESS !=
2600 wlan_hdd_validate_operation_channel(pAdapter, channel)) {
2601 hddLog(LOGE, FL("Invalid Channel %d"), channel);
2602 return -EINVAL;
2603 }
2604
2605 /* Proceed with reassoc */
2606 handoffInfo.channel = channel;
Selvaraj, Sridhar4fa15232016-06-18 12:27:25 +05302607 hdd_assign_handoff_src_reassoc(&handoffInfo, src);
Selvaraj, Sridhar5aff1ed2016-06-18 01:26:23 +05302608 memcpy(handoffInfo.bssid, bssid, sizeof(tSirMacAddr));
2609 sme_HandoffRequest(pHddCtx->hHal, &handoffInfo);
2610 return 0;
2611}
2612#else
Selvaraj, Sridhar8ecb4192016-06-23 17:50:49 +05302613int hdd_reassoc(hdd_adapter_t *pAdapter, const tANI_U8 *bssid,
Selvaraj, Sridhar4fa15232016-06-18 12:27:25 +05302614 const tANI_U8 channel, const handoff_src src)
Selvaraj, Sridhar5aff1ed2016-06-18 01:26:23 +05302615{
2616 return -EPERM;
2617}
2618#endif
2619
2620/**
2621 * hdd_parse_reassoc_v1() - parse version 1 of the REASSOC command
2622 * This function parses the v1 REASSOC command with the format
2623 * REASSOC xx:xx:xx:xx:xx:xx CH where "xx:xx:xx:xx:xx:xx" is the
2624 * Hex-ASCII representation of the BSSID and CH is the ASCII
2625 * representation of the channel. For example
2626 * REASSOC 00:0a:0b:11:22:33 48
2627 *
2628 * @pAdapter: Adapter upon which the command was received
2629 * @command: ASCII text command that was received
2630 *
2631 * Return: 0 for success non-zero for failure
2632 */
2633static int
2634hdd_parse_reassoc_v1(hdd_adapter_t *pAdapter, const char *command)
2635{
2636 tANI_U8 channel = 0;
2637 tSirMacAddr bssid;
2638 int ret;
2639
2640 ret = hdd_parse_reassoc_command_v1_data(command, bssid, &channel);
2641 if (ret)
2642 hddLog(LOGE, FL("Failed to parse reassoc command data"));
2643 else
Selvaraj, Sridhar4fa15232016-06-18 12:27:25 +05302644 ret = hdd_reassoc(pAdapter, bssid, channel, REASSOC);
Selvaraj, Sridhar5aff1ed2016-06-18 01:26:23 +05302645
2646 return ret;
2647}
2648
2649/**
2650 * hdd_parse_reassoc_v2() - parse version 2 of the REASSOC command
2651 * This function parses the v2 REASSOC command with the format
2652 * REASSOC <android_wifi_reassoc_params>
2653 *
2654 * @pAdapter: Adapter upon which the command was received
2655 * @command: command that was received, ASCII command followed
2656 * by binary data
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05302657 * @total_len: Total length of the command received
Selvaraj, Sridhar5aff1ed2016-06-18 01:26:23 +05302658 *
2659 * Return: 0 for success non-zero for failure
2660 */
2661static int
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05302662hdd_parse_reassoc_v2(hdd_adapter_t *pAdapter, const char *command,
2663 int total_len)
Selvaraj, Sridhar5aff1ed2016-06-18 01:26:23 +05302664{
2665 struct android_wifi_reassoc_params params;
2666 tSirMacAddr bssid;
2667 int ret;
2668
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05302669 if (total_len < sizeof(params) + 8) {
2670 hddLog(LOGE, FL("Invalid command length"));
2671 return -EINVAL;
2672 }
2673
Selvaraj, Sridhar5aff1ed2016-06-18 01:26:23 +05302674 /* The params are located after "REASSOC " */
2675 memcpy(&params, command + 8, sizeof(params));
2676
2677 if (!mac_pton(params.bssid, (u8 *)&bssid)) {
2678 hddLog(LOGE, FL("MAC address parsing failed"));
2679 ret = -EINVAL;
2680 } else {
Selvaraj, Sridhar4fa15232016-06-18 12:27:25 +05302681 ret = hdd_reassoc(pAdapter, bssid, params.channel, REASSOC);
Selvaraj, Sridhar5aff1ed2016-06-18 01:26:23 +05302682 }
2683 return ret;
2684}
2685
2686/**
2687 * hdd_parse_reassoc() - parse the REASSOC command
2688 * There are two different versions of the REASSOC command.Version 1
2689 * of the command contains a parameter list that is ASCII characters
2690 * whereas version 2 contains a combination of ASCII and binary
2691 * payload. Determine if a version 1 or a version 2 command is being
2692 * parsed by examining the parameters, and then dispatch the parser
2693 * that is appropriate for the command.
2694 *
2695 * @pAdapter: Adapter upon which the command was received
2696 * @command: command that was received
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05302697 * @total_len: Total length of the command received
Selvaraj, Sridhar5aff1ed2016-06-18 01:26:23 +05302698 *
2699 * Return: 0 for success non-zero for failure
2700 */
2701static int
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05302702hdd_parse_reassoc(hdd_adapter_t *pAdapter, const char *command, int total_len)
Selvaraj, Sridhar5aff1ed2016-06-18 01:26:23 +05302703{
2704 int ret;
2705
2706 /*
2707 * both versions start with "REASSOC"
2708 * v1 has a bssid and channel # as an ASCII string
2709 * REASSOC xx:xx:xx:xx:xx:xx CH
2710 * v2 has a C struct
2711 * REASSOC <binary c struct>
2712 *
2713 * The first field in the v2 struct is also the bssid in ASCII.
2714 * But in the case of a v2 message the BSSID is NUL-terminated.
2715 * Hence we can peek at that offset to see if this is V1 or V2
2716 * REASSOC xx:xx:xx:xx:xx:xx*
2717 * 1111111111222222
2718 * 01234567890123456789012345
2719 */
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05302720
2721 if (total_len < 26) {
2722 hddLog(LOGE, FL("Invalid command (total_len=%d)"), total_len);
2723 return -EINVAL;
2724 }
2725
Selvaraj, Sridhar5aff1ed2016-06-18 01:26:23 +05302726 if (command[25])
2727 ret = hdd_parse_reassoc_v1(pAdapter, command);
2728 else
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05302729 ret = hdd_parse_reassoc_v2(pAdapter, command, total_len);
Selvaraj, Sridhar5aff1ed2016-06-18 01:26:23 +05302730
2731 return ret;
2732}
2733#endif /* WLAN_FEATURE_VOWIFI_11R || FEATURE_WLAN_ESE FEATURE_WLAN_LFR */
2734
Hanumanth Reddy Pothula7aa4bea2018-04-09 17:19:03 +05302735struct bcn_miss_rate_priv {
2736 int bcn_miss_rate;
2737};
2738
2739/**
2740 * get_bcn_miss_rate_cb() callback invoked on receiving beacon miss
2741 * rate from firmware
2742 * @status: Status of get beacon miss rate operation
2743 * @bcnMissRate: Beacon miss rate
2744 * @context: Context passed while registering callback
2745 *
2746 * This function is invoked by WDA layer on receiving
2747 * WDI_GET_BCN_MISS_RATE_RSP
2748 *
2749 * Return: None
2750 */
2751static void get_bcn_miss_rate_cb(VOS_STATUS status, int bcnMissRate,
2752 void *context)
c_hpothu92367912014-05-01 15:18:17 +05302753{
Hanumanth Reddy Pothula7aa4bea2018-04-09 17:19:03 +05302754 struct hdd_request *request;
2755 struct bcn_miss_rate_priv *priv;
c_hpothu39eb1e32014-06-26 16:31:50 +05302756
Hanumanth Reddy Pothula7aa4bea2018-04-09 17:19:03 +05302757 request = hdd_request_get(context);
2758 if (!request) {
2759 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Obsolete request"));
2760 return;
2761 }
c_hpothu92367912014-05-01 15:18:17 +05302762
Hanumanth Reddy Pothula7aa4bea2018-04-09 17:19:03 +05302763 priv = hdd_request_priv(request);
c_hpothu92367912014-05-01 15:18:17 +05302764
Hanumanth Reddy Pothula7aa4bea2018-04-09 17:19:03 +05302765 if (VOS_STATUS_SUCCESS == status)
2766 priv->bcn_miss_rate = bcnMissRate;
2767 else
2768 hddLog(VOS_TRACE_LEVEL_ERROR, FL("failed to get bcnMissRate"));
c_hpothu92367912014-05-01 15:18:17 +05302769
Hanumanth Reddy Pothula7aa4bea2018-04-09 17:19:03 +05302770 hdd_request_complete(request);
2771 hdd_request_put(request);
Hanumanth Reddy Pothulad0d3c172018-05-02 18:53:05 +05302772
Hanumanth Reddy Pothula7aa4bea2018-04-09 17:19:03 +05302773 return;
c_hpothu92367912014-05-01 15:18:17 +05302774}
2775
Hanumanth Reddy Pothula7aa4bea2018-04-09 17:19:03 +05302776struct fw_stats_priv {
2777 tSirFwStatsResult *fw_stats;
2778};
2779
2780/**
2781 * hdd_fw_stats_cb() callback invoked on receiving firmware stats
2782 * from firmware
2783 * @status: Status of get firmware stats operation
2784 * @fwStatsResult: firmware stats
2785 * @context: Context passed while registering callback
2786 *
2787 * This function is invoked by WDA layer on receiving
2788 * WDI_GET_FW_STATS_RSP
2789 *
2790 * Return: None
2791 */
2792static void hdd_fw_stats_cb(VOS_STATUS status,
2793 tSirFwStatsResult *fwStatsResult, void *context)
Satyanarayana Dash72806012014-12-02 14:30:08 +05302794{
Hanumanth Reddy Pothula7aa4bea2018-04-09 17:19:03 +05302795 struct hdd_request *request;
2796 struct fw_stats_priv *priv;
Satyanarayana Dash72806012014-12-02 14:30:08 +05302797
Hanumanth Reddy Pothula7aa4bea2018-04-09 17:19:03 +05302798 hddLog(VOS_TRACE_LEVEL_INFO, FL("with status = %d"),status);
Satyanarayana Dash72806012014-12-02 14:30:08 +05302799
Hanumanth Reddy Pothula7aa4bea2018-04-09 17:19:03 +05302800 request = hdd_request_get(context);
2801 if (!request) {
2802 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Obsolete request"));
2803 return;
2804 }
2805 priv = hdd_request_priv(request);
2806
2807 if (VOS_STATUS_SUCCESS == status)
2808 *priv->fw_stats = *fwStatsResult;
2809 else
2810 priv->fw_stats = NULL;
2811
2812 hdd_request_complete(request);
2813 hdd_request_put(request);
2814 return;
Satyanarayana Dash72806012014-12-02 14:30:08 +05302815}
2816
jge35567202017-06-21 16:39:38 +08002817/*
2818 *hdd_parse_setmaxtxpower_command() - HDD Parse MAXTXPOWER command
2819 *@pValue Pointer to MAXTXPOWER command
2820 *@pTxPower Pointer to tx power
2821 *
2822 *This function parses the MAXTXPOWER command passed in the format
2823 * MAXTXPOWER<space>X(Tx power in dbm)
2824 * For example input commands:
2825 * 1) MAXTXPOWER -8 -> This is translated into set max TX power to -8 dbm
2826 * 2) MAXTXPOWER -23 -> This is translated into set max TX power to -23 dbm
2827 *
2828 *return - 0 for success non-zero for failure
2829 */
2830static int hdd_parse_setmaxtxpower_command(unsigned char *pValue, int *pTxPower)
2831{
2832 unsigned char *inPtr = pValue;
2833 int tempInt;
2834 int v = 0;
2835 *pTxPower = 0;
2836
2837 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
2838 /* no argument after the command */
2839 if (NULL == inPtr)
2840 return -EINVAL;
2841 /* no space after the command */
2842 else if (SPACE_ASCII_VALUE != *inPtr)
2843 return -EINVAL;
2844
2845 /* removing empty spaces */
2846 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
2847
2848 /* no argument followed by spaces */
2849 if ('\0' == *inPtr)
2850 return 0;
2851
2852 v = kstrtos32(inPtr, 10, &tempInt);
2853
2854 /* Range checking for passed parameter */
2855 if ((tempInt < HDD_MIN_TX_POWER) || (tempInt > HDD_MAX_TX_POWER))
2856 return -EINVAL;
2857
2858 *pTxPower = tempInt;
2859
2860 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2861 "SETMAXTXPOWER: %d", *pTxPower);
2862
2863 return 0;
2864}
2865
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302866static int hdd_get_dwell_time(hdd_config_t *pCfg, tANI_U8 *command, char *extra, tANI_U8 n, tANI_U8 *len)
2867{
2868 int ret = 0;
2869
2870 if (!pCfg || !command || !extra || !len)
2871 {
2872 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2873 "%s: argument passsed for GETDWELLTIME is incorrect", __func__);
2874 ret = -EINVAL;
2875 return ret;
2876 }
2877
2878 if (strncmp(command, "GETDWELLTIME ACTIVE MAX", 23) == 0)
2879 {
2880 *len = scnprintf(extra, n, "GETDWELLTIME ACTIVE MAX %u\n",
2881 (int)pCfg->nActiveMaxChnTime);
2882 return ret;
2883 }
2884 else if (strncmp(command, "GETDWELLTIME ACTIVE MIN", 23) == 0)
2885 {
2886 *len = scnprintf(extra, n, "GETDWELLTIME ACTIVE MIN %u\n",
2887 (int)pCfg->nActiveMinChnTime);
2888 return ret;
2889 }
2890 else if (strncmp(command, "GETDWELLTIME PASSIVE MAX", 24) == 0)
2891 {
2892 *len = scnprintf(extra, n, "GETDWELLTIME PASSIVE MAX %u\n",
2893 (int)pCfg->nPassiveMaxChnTime);
2894 return ret;
2895 }
2896 else if (strncmp(command, "GETDWELLTIME PASSIVE MIN", 24) == 0)
2897 {
2898 *len = scnprintf(extra, n, "GETDWELLTIME PASSIVE MIN %u\n",
2899 (int)pCfg->nPassiveMinChnTime);
2900 return ret;
2901 }
Rajesh Babu Prathipati0fd227e2014-07-05 12:50:00 +05302902 else if (strncmp(command, "GETDWELLTIME", 12) == 0)
2903 {
2904 *len = scnprintf(extra, n, "GETDWELLTIME %u \n",
2905 (int)pCfg->nActiveMaxChnTime);
2906 return ret;
2907 }
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302908 else
2909 {
2910 ret = -EINVAL;
2911 }
2912
2913 return ret;
2914}
2915
Dundi Ravitejaae5adf42018-04-23 20:44:47 +05302916/**
2917 * hdd_btc_get_dwell_time() - Get BTC dwell time parameters
2918 * @pCfg: Pointer to HDD context
2919 * @command: ASCII text command that is received
2920 * @extra: Pointer to copy data sent to user
2921 * @n: size of 'extra' buffer
2922 * @len: length copied to 'extra' buffer
2923 *
2924 * Driver commands:
2925 * wpa_cli DRIVER BTCGETDWELLTIME ESCO MAX
2926 * wpa_cli DRIVER BTCGETDWELLTIME ESCO MIN
2927 * wpa_cli DRIVER BTCGETDWELLTIME SCO MAX
2928 * wpa_cli DRIVER BTCGETDWELLTIME SCO MIN
2929 *
2930 * Return: 0 for success non-zero for failure
2931 */
2932
2933static int hdd_btc_get_dwell_time(hdd_config_t *pCfg, tANI_U8 *command,
2934 char *extra, tANI_U8 n, tANI_U8 *len)
2935{
2936 int ret = 0;
2937
2938 if (!pCfg || !command || !extra || !len)
2939 {
2940 hddLog(LOGE, FL("Argument passsed for BTCGETDWELLTIME is incorrect"));
2941 ret = -EINVAL;
2942 return ret;
2943 }
2944
2945 if (strncmp(command, "BTCGETDWELLTIME ESCO MAX", 24) == 0)
2946 {
2947 *len = scnprintf(extra, n, "BTCGETDWELLTIME ESCO MAX %u\n",
2948 (int)pCfg->max_chntime_btc_esco);
2949 return ret;
2950 }
2951 else if (strncmp(command, "BTCGETDWELLTIME ESCO MIN", 24) == 0)
2952 {
2953 *len = scnprintf(extra, n, "BTCGETDWELLTIME ESCO MIN %u\n",
2954 (int)pCfg->min_chntime_btc_esco);
2955 return ret;
2956 }
2957 else if (strncmp(command, "BTCGETDWELLTIME SCO MAX", 23) == 0)
2958 {
2959 *len = scnprintf(extra, n, "BTCGETDWELLTIME SCO MAX %u\n",
2960 (int)pCfg->max_chntime_btc_sco);
2961 return ret;
2962 }
2963 else if (strncmp(command, "BTCGETDWELLTIME SCO MIN", 23) == 0)
2964 {
2965 *len = scnprintf(extra, n, "BTCGETDWELLTIME SCO MIN %u\n",
2966 (int)pCfg->min_chntime_btc_sco);
2967 return ret;
2968 }
2969 else
2970 {
2971 ret = -EINVAL;
2972 }
2973
2974 return ret;
2975}
2976
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05302977int hdd_drv_cmd_validate(tANI_U8 *command, int len)
2978{
2979 if (command[len] != ' ')
2980 return -EINVAL;
2981
2982 return 0;
2983}
2984
Dundi Ravitejaae5adf42018-04-23 20:44:47 +05302985#ifdef WLAN_AP_STA_CONCURRENCY
2986
2987/**
2988 * hdd_conc_get_dwell_time() - Get concurrency dwell time parameters
2989 * @pCfg: Pointer to HDD context
2990 * @command: ASCII text command that is received
2991 * @extra: Pointer to copy data sent to user
2992 * @n: size of 'extra' buffer
2993 * @len: length copied to 'extra' buffer
2994 *
2995 * Driver commands:
2996 * wpa_cli DRIVER CONCGETDWELLTIME ACTIVE MAX
2997 * wpa_cli DRIVER CONCGETDWELLTIME ACTIVE MIN
2998 * wpa_cli DRIVER CONCGETDWELLTIME PASSIVE MAX
2999 * wpa_cli DRIVER CONCGETDWELLTIME PASSIVE MIN
3000 *
3001 * Return: 0 for success non-zero for failure
3002 */
3003
3004static int hdd_conc_get_dwell_time(hdd_config_t *pCfg, tANI_U8 *command,
3005 char *extra, tANI_U8 n, tANI_U8 *len)
3006{
3007 int ret = 0;
3008
3009 if (!pCfg || !command || !extra || !len)
3010 {
3011 hddLog(LOGE, FL("Argument passsed for CONCGETDWELLTIME is incorrect"));
3012 ret = -EINVAL;
3013 return ret;
3014 }
3015
3016 if (strncmp(command, "CONCGETDWELLTIME ACTIVE MAX", 27) == 0)
3017 {
3018 *len = scnprintf(extra, n, "CONCGETDWELLTIME ACTIVE MAX %u\n",
3019 (int)pCfg->nActiveMaxChnTimeConc);
3020 return ret;
3021 }
3022 else if (strncmp(command, "CONCGETDWELLTIME ACTIVE MIN", 27) == 0)
3023 {
3024 *len = scnprintf(extra, n, "CONCGETDWELLTIME ACTIVE MIN %u\n",
3025 (int)pCfg->nActiveMinChnTimeConc);
3026 return ret;
3027 }
3028 else if (strncmp(command, "CONCGETDWELLTIME PASSIVE MAX", 28) == 0)
3029 {
3030 *len = scnprintf(extra, n, "CONCGETDWELLTIME PASSIVE MAX %u\n",
3031 (int)pCfg->nPassiveMaxChnTimeConc);
3032 return ret;
3033 }
3034 else if (strncmp(command, "CONCGETDWELLTIME PASSIVE MIN", 28) == 0)
3035 {
3036 *len = scnprintf(extra, n, "CONCGETDWELLTIME PASSIVE MIN %u\n",
3037 (int)pCfg->nPassiveMinChnTimeConc);
3038 return ret;
3039 }
3040 else
3041 {
3042 ret = -EINVAL;
3043 }
3044
3045 return ret;
3046}
3047
3048/**
3049 * hdd_conc_set_dwell_time() - Set concurrency dwell time parameters
3050 * @pAdapter: Adapter upon which the command was received
3051 * @command: ASCII text command that is received
3052 *
3053 * Driver commands:
3054 * wpa_cli DRIVER CONCSETDWELLTIME ACTIVE MAX <value>
3055 * wpa_cli DRIVER CONCSETDWELLTIME ACTIVE MIN <value>
3056 * wpa_cli DRIVER CONCSETDWELLTIME PASSIVE MAX <value
3057 * wpa_cli DRIVER CONCSETDWELLTIME PASSIVE MIN <value>
3058 *
3059 * Return: 0 for success non-zero for failure
3060 */
3061
3062static int hdd_conc_set_dwell_time(hdd_adapter_t *pAdapter, tANI_U8 *command)
3063{
3064 tHalHandle hHal;
3065 hdd_config_t *pCfg;
3066 tANI_U8 *value = command;
3067 int val = 0, ret = 0, temp = 0;
3068 tSmeConfigParams smeConfig;
3069
3070 if (!pAdapter || !command || !(pCfg = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini)
3071 || !(hHal = (WLAN_HDD_GET_HAL_CTX(pAdapter))))
3072 {
3073 hddLog(LOGE, FL("Argument passed for CONCSETDWELLTIME is incorrect"));
3074 ret = -EINVAL;
3075 return ret;
3076 }
3077
3078 vos_mem_zero(&smeConfig, sizeof(smeConfig));
3079 sme_GetConfigParam(hHal, &smeConfig);
3080
3081 if (strncmp(command, "CONCSETDWELLTIME ACTIVE MAX", 27) == 0 )
3082 {
3083 if (hdd_drv_cmd_validate(command, 27)) {
3084 hddLog(LOGE, FL("Invalid driver command"));
3085 return -EINVAL;
3086 }
3087
3088 value = value + 28;
3089 temp = kstrtou32(value, 10, &val);
3090 if (temp != 0 || val < CFG_ACTIVE_MAX_CHANNEL_TIME_CONC_MIN ||
3091 val > CFG_ACTIVE_MAX_CHANNEL_TIME_CONC_MAX)
3092 {
3093 hddLog(LOGE, FL("Argument passed for CONCSETDWELLTIME ACTIVE MAX is incorrect"));
3094 ret = -EFAULT;
3095 return ret;
3096 }
3097 pCfg->nActiveMaxChnTimeConc = val;
3098 smeConfig.csrConfig.nActiveMaxChnTimeConc = val;
3099 sme_UpdateConfig(hHal, &smeConfig);
3100 }
3101 else if (strncmp(command, "CONCSETDWELLTIME ACTIVE MIN", 27) == 0)
3102 {
3103 if (hdd_drv_cmd_validate(command, 27)) {
3104 hddLog(LOGE, FL("Invalid driver command"));
3105 return -EINVAL;
3106 }
3107
3108 value = value + 28;
3109 temp = kstrtou32(value, 10, &val);
3110 if (temp !=0 || val < CFG_ACTIVE_MIN_CHANNEL_TIME_CONC_MIN ||
3111 val > CFG_ACTIVE_MIN_CHANNEL_TIME_CONC_MAX)
3112 {
3113 hddLog(LOGE, FL("Argument passsed for CONCSETDWELLTIME ACTIVE MIN is incorrect"));
3114 ret = -EFAULT;
3115 return ret;
3116 }
3117 pCfg->nActiveMinChnTimeConc = val;
3118 smeConfig.csrConfig.nActiveMinChnTimeConc = val;
3119 sme_UpdateConfig(hHal, &smeConfig);
3120 }
3121 else if (strncmp(command, "CONCSETDWELLTIME PASSIVE MAX", 28) == 0)
3122 {
3123 if (hdd_drv_cmd_validate(command, 28)) {
3124 hddLog(LOGE, FL("Invalid driver command"));
3125 return -EINVAL;
3126 }
3127
3128 value = value + 29;
3129 temp = kstrtou32(value, 10, &val);
3130 if (temp != 0 || val < CFG_PASSIVE_MAX_CHANNEL_TIME_CONC_MIN ||
3131 val > CFG_PASSIVE_MAX_CHANNEL_TIME_CONC_MAX)
3132 {
3133 hddLog(LOGE, FL("Argument passed for CONCSETDWELLTIME PASSIVE MAX is incorrect"));
3134 ret = -EFAULT;
3135 return ret;
3136 }
3137 pCfg->nPassiveMaxChnTimeConc = val;
3138 smeConfig.csrConfig.nPassiveMaxChnTimeConc = val;
3139 sme_UpdateConfig(hHal, &smeConfig);
3140 }
3141 else if (strncmp(command, "CONCSETDWELLTIME PASSIVE MIN", 28) == 0)
3142 {
3143 if (hdd_drv_cmd_validate(command, 28)) {
3144 hddLog(LOGE, FL("Invalid driver command"));
3145 return -EINVAL;
3146 }
3147
3148 value = value + 29;
3149 temp = kstrtou32(value, 10, &val);
3150 if (temp != 0 || val < CFG_PASSIVE_MIN_CHANNEL_TIME_CONC_MIN ||
3151 val > CFG_PASSIVE_MIN_CHANNEL_TIME_CONC_MAX )
3152 {
3153 hddLog(LOGE, FL("Argument passed for CONCSETDWELLTIME PASSIVE MIN is incorrect"));
3154 ret = -EFAULT;
3155 return ret;
3156 }
3157 pCfg->nPassiveMinChnTimeConc = val;
3158 smeConfig.csrConfig.nPassiveMinChnTimeConc = val;
3159 sme_UpdateConfig(hHal, &smeConfig);
3160 }
3161 else
3162 {
3163 ret = -EINVAL;
3164 }
3165
3166 return ret;
3167}
3168
3169#endif
3170
3171/**
3172 * hdd_btc_set_dwell_time() - Set BTC dwell time parameters
3173 * @pAdapter: Adapter upon which the command was received
3174 * @command: ASCII text command that is received
3175 *
3176 * Driver commands:
3177 * wpa_cli DRIVER BTCSETDWELLTIME ESCO MAX <value>
3178 * wpa_cli DRIVER BTCSETDWELLTIME ESCO MIN <value>
3179 * wpa_cli DRIVER BTCSETDWELLTIME SCO MAX <value>
3180 * wpa_cli DRIVER BTCSETDWELLTIME SCO MIN <value>
3181 *
3182 * Return: 0 for success non-zero for failure
3183 */
3184
3185static int hdd_btc_set_dwell_time(hdd_adapter_t *pAdapter, tANI_U8 *command)
3186{
3187 tHalHandle hHal;
3188 hdd_config_t *pCfg;
3189 tANI_U8 *value = command;
3190 int val = 0, ret = 0, temp = 0;
3191 tSmeConfigParams smeConfig;
3192
3193 if (!pAdapter || !command || !(pCfg = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini)
3194 || !(hHal = (WLAN_HDD_GET_HAL_CTX(pAdapter))))
3195 {
3196 hddLog(LOGE, FL("Argument passed for BTCSETDWELLTIME is incorrect"));
3197 ret = -EINVAL;
3198 return ret;
3199 }
3200
3201 vos_mem_zero(&smeConfig, sizeof(smeConfig));
3202 sme_GetConfigParam(hHal, &smeConfig);
3203
3204 if (strncmp(command, "BTCSETDWELLTIME ESCO MAX", 24) == 0)
3205 {
3206 if (hdd_drv_cmd_validate(command, 24)) {
3207 hddLog(LOGE, FL("Invalid driver command"));
3208 return -EINVAL;
3209 }
3210
3211 value = value + 25;
3212 temp = kstrtou32(value, 10, &val);
3213 if (temp != 0 || val < CFG_ACTIVE_MAX_CHANNEL_TIME_BTC_MIN ||
3214 val > CFG_ACTIVE_MAX_CHANNEL_TIME_BTC_MAX)
3215 {
3216 hddLog(LOGE, FL("Argument passed for BTCSETDWELLTIME ESCO MAX is incorrect"));
3217 ret = -EFAULT;
3218 return ret;
3219 }
3220 pCfg->max_chntime_btc_esco = val;
3221 smeConfig.csrConfig.max_chntime_btc_esco = val;
3222 sme_UpdateConfig(hHal, &smeConfig);
3223 }
3224 else if (strncmp(command, "BTCSETDWELLTIME ESCO MIN", 24) == 0)
3225 {
3226 if (hdd_drv_cmd_validate(command, 24)) {
3227 hddLog(LOGE, FL("Invalid driver command"));
3228 return -EINVAL;
3229 }
3230
3231 value = value + 25;
3232 temp = kstrtou32(value, 10, &val);
3233 if (temp !=0 || val < CFG_ACTIVE_MIN_CHANNEL_TIME_BTC_MIN ||
3234 val > CFG_ACTIVE_MIN_CHANNEL_TIME_BTC_MAX)
3235 {
3236 hddLog(LOGE, FL("Argument passsed for BTCSETDWELLTIME ESCO MIN is incorrect"));
3237 ret = -EFAULT;
3238 return ret;
3239 }
3240 pCfg->min_chntime_btc_esco = val;
3241 smeConfig.csrConfig.min_chntime_btc_esco = val;
3242 sme_UpdateConfig(hHal, &smeConfig);
3243 }
3244 else if (strncmp(command, "BTCSETDWELLTIME SCO MAX", 23) == 0)
3245 {
3246 if (hdd_drv_cmd_validate(command, 23)) {
3247 hddLog(LOGE, FL("Invalid driver command"));
3248 return -EINVAL;
3249 }
3250
3251 value = value + 24;
3252 temp = kstrtou32(value, 10, &val);
3253 if (temp != 0 || val < CFG_ACTIVE_MAX_CHANNEL_TIME_BTC_SCO_MIN ||
3254 val > CFG_ACTIVE_MAX_CHANNEL_TIME_BTC_SCO_MAX)
3255 {
3256 hddLog(LOGE, FL("Argument passed for BTCSETDWELLTIME SCO MAX is incorrect"));
3257 ret = -EFAULT;
3258 return ret;
3259 }
3260 pCfg->max_chntime_btc_sco = val;
3261 smeConfig.csrConfig.max_chntime_btc_sco = val;
3262 sme_UpdateConfig(hHal, &smeConfig);
3263 }
3264 else if (strncmp(command, "BTCSETDWELLTIME SCO MIN", 23) == 0)
3265 {
3266 if (hdd_drv_cmd_validate(command, 23)) {
3267 hddLog(LOGE, FL("Invalid driver command"));
3268 return -EINVAL;
3269 }
3270
3271 value = value + 24;
3272 temp = kstrtou32(value, 10, &val);
3273 if (temp != 0 || val < CFG_ACTIVE_MIN_CHANNEL_TIME_BTC_SCO_MIN ||
3274 val > CFG_ACTIVE_MIN_CHANNEL_TIME_BTC_SCO_MAX)
3275 {
3276 hddLog(LOGE, FL("Argument passed for BTCSETDWELLTIME SCO MIN is incorrect"));
3277 ret = -EFAULT;
3278 return ret;
3279 }
3280 pCfg->min_chntime_btc_sco = val;
3281 smeConfig.csrConfig.min_chntime_btc_sco = val;
3282 sme_UpdateConfig(hHal, &smeConfig);
3283 }
3284 else
3285 {
3286 ret = -EINVAL;
3287 }
3288
3289 return ret;
3290}
3291
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05303292static int hdd_set_dwell_time(hdd_adapter_t *pAdapter, tANI_U8 *command)
3293{
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05303294 tHalHandle hHal;
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05303295 hdd_config_t *pCfg;
3296 tANI_U8 *value = command;
3297 int val = 0, ret = 0, temp = 0;
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05303298 tSmeConfigParams smeConfig;
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05303299
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05303300 if (!pAdapter || !command || !(pCfg = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini)
3301 || !(hHal = (WLAN_HDD_GET_HAL_CTX(pAdapter))))
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05303302 {
3303 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3304 "%s: argument passed for SETDWELLTIME is incorrect", __func__);
3305 ret = -EINVAL;
3306 return ret;
3307 }
3308
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05303309 vos_mem_zero(&smeConfig, sizeof(smeConfig));
3310 sme_GetConfigParam(hHal, &smeConfig);
3311
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05303312 if (strncmp(command, "SETDWELLTIME ACTIVE MAX", 23) == 0 )
3313 {
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05303314 if (hdd_drv_cmd_validate(command, 23))
3315 return -EINVAL;
3316
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05303317 value = value + 24;
3318 temp = kstrtou32(value, 10, &val);
3319 if (temp != 0 || val < CFG_ACTIVE_MAX_CHANNEL_TIME_MIN ||
3320 val > CFG_ACTIVE_MAX_CHANNEL_TIME_MAX )
3321 {
3322 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3323 "%s: argument passed for SETDWELLTIME ACTIVE MAX is incorrect", __func__);
3324 ret = -EFAULT;
3325 return ret;
3326 }
3327 pCfg->nActiveMaxChnTime = val;
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05303328 smeConfig.csrConfig.nActiveMaxChnTime = val;
3329 sme_UpdateConfig(hHal, &smeConfig);
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05303330 }
3331 else if (strncmp(command, "SETDWELLTIME ACTIVE MIN", 23) == 0)
3332 {
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05303333 if (hdd_drv_cmd_validate(command, 23))
3334 return -EINVAL;
3335
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05303336 value = value + 24;
3337 temp = kstrtou32(value, 10, &val);
3338 if (temp !=0 || val < CFG_ACTIVE_MIN_CHANNEL_TIME_MIN ||
3339 val > CFG_ACTIVE_MIN_CHANNEL_TIME_MAX )
3340 {
3341 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3342 "%s: argument passsed for SETDWELLTIME ACTIVE MIN is incorrect", __func__);
3343 ret = -EFAULT;
3344 return ret;
3345 }
3346 pCfg->nActiveMinChnTime = val;
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05303347 smeConfig.csrConfig.nActiveMinChnTime = val;
3348 sme_UpdateConfig(hHal, &smeConfig);
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05303349 }
3350 else if (strncmp(command, "SETDWELLTIME PASSIVE MAX", 24) == 0)
3351 {
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05303352 if (hdd_drv_cmd_validate(command, 24))
3353 return -EINVAL;
3354
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05303355 value = value + 25;
3356 temp = kstrtou32(value, 10, &val);
3357 if (temp != 0 || val < CFG_PASSIVE_MAX_CHANNEL_TIME_MIN ||
3358 val > CFG_PASSIVE_MAX_CHANNEL_TIME_MAX )
3359 {
3360 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3361 "%s: argument passed for SETDWELLTIME PASSIVE MAX is incorrect", __func__);
3362 ret = -EFAULT;
3363 return ret;
3364 }
3365 pCfg->nPassiveMaxChnTime = val;
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05303366 smeConfig.csrConfig.nPassiveMaxChnTime = val;
3367 sme_UpdateConfig(hHal, &smeConfig);
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05303368 }
3369 else if (strncmp(command, "SETDWELLTIME PASSIVE MIN", 24) == 0)
3370 {
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05303371 if (hdd_drv_cmd_validate(command, 24))
3372 return -EINVAL;
3373
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05303374 value = value + 25;
3375 temp = kstrtou32(value, 10, &val);
3376 if (temp != 0 || val < CFG_PASSIVE_MIN_CHANNEL_TIME_MIN ||
3377 val > CFG_PASSIVE_MIN_CHANNEL_TIME_MAX )
3378 {
3379 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3380 "%s: argument passed for SETDWELLTIME PASSIVE MIN is incorrect", __func__);
3381 ret = -EFAULT;
3382 return ret;
3383 }
3384 pCfg->nPassiveMinChnTime = val;
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05303385 smeConfig.csrConfig.nPassiveMinChnTime = val;
3386 sme_UpdateConfig(hHal, &smeConfig);
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05303387 }
Rajesh Babu Prathipati0fd227e2014-07-05 12:50:00 +05303388 else if (strncmp(command, "SETDWELLTIME", 12) == 0)
3389 {
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05303390 if (hdd_drv_cmd_validate(command, 12))
3391 return -EINVAL;
3392
Rajesh Babu Prathipati0fd227e2014-07-05 12:50:00 +05303393 value = value + 13;
3394 temp = kstrtou32(value, 10, &val);
3395 if (temp != 0 || val < CFG_ACTIVE_MAX_CHANNEL_TIME_MIN ||
3396 val > CFG_ACTIVE_MAX_CHANNEL_TIME_MAX )
3397 {
3398 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3399 "%s: argument passed for SETDWELLTIME is incorrect", __func__);
3400 ret = -EFAULT;
3401 return ret;
3402 }
3403 pCfg->nActiveMaxChnTime = val;
3404 smeConfig.csrConfig.nActiveMaxChnTime = val;
3405 sme_UpdateConfig(hHal, &smeConfig);
3406 }
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05303407 else
3408 {
3409 ret = -EINVAL;
3410 }
3411
3412 return ret;
3413}
Agarwal Ashish8bd53ae2015-06-12 18:03:45 +05303414static int hdd_cmd_setFccChannel(hdd_context_t *pHddCtx, tANI_U8 *cmd,
3415 tANI_U8 cmd_len)
3416{
3417 tANI_U8 *value;
3418 tANI_U8 fcc_constraint;
3419
3420 eHalStatus status;
3421 int ret = 0;
3422 value = cmd + cmd_len + 1;
3423
3424 ret = kstrtou8(value, 10, &fcc_constraint);
3425 if ((ret < 0) || (fcc_constraint > 1)) {
3426 /*
3427 * If the input value is greater than max value of datatype,
3428 * then also it is a failure
3429 */
3430 hddLog(VOS_TRACE_LEVEL_ERROR,
3431 "%s: value out of range", __func__);
3432 return -EINVAL;
3433 }
3434
Agrawal Ashish842eea82016-02-04 17:56:16 +05303435 status = sme_handleSetFccChannel(pHddCtx->hHal, fcc_constraint,
3436 pHddCtx->scan_info.mScanPending);
Agarwal Ashish8bd53ae2015-06-12 18:03:45 +05303437 if (status != eHAL_STATUS_SUCCESS)
3438 ret = -EPERM;
3439
3440 return ret;
3441}
3442
Mahesh A Saptasagarbeca12c2015-09-07 16:21:06 +05303443/**---------------------------------------------------------------------------
Agarwal Ashish8bd53ae2015-06-12 18:03:45 +05303444
Mahesh A Saptasagarbeca12c2015-09-07 16:21:06 +05303445 \brief hdd_enable_disable_ca_event() - When Host sends IOCTL (enabled),
3446 FW will send *ONE* CA ind to Host(even though it is duplicate).
3447 When Host send IOCTL (disable), FW doesn't perform any action.
3448 Whenever any change in CA *and* WLAN is in SAP/P2P-GO mode, FW
3449 sends CA ind to host. (regard less of IOCTL status)
3450 \param - pHddCtx - HDD context
3451 \param - command - command received from framework
3452 \param - cmd_len - len of the command
3453
3454 \return - 0 on success, appropriate error values on failure.
3455
3456 --------------------------------------------------------------------------*/
3457int hdd_enable_disable_ca_event(hdd_context_t *pHddCtx, tANI_U8* command, tANI_U8 cmd_len)
3458{
3459 tANI_U8 set_value;
3460 int ret = 0;
3461 eHalStatus status;
3462
3463 ret = wlan_hdd_validate_context(pHddCtx);
3464 if (0 != ret)
3465 {
3466 ret = -EINVAL;
3467 goto exit;
3468 }
3469
3470 if (pHddCtx->cfg_ini->gOptimizeCAevent == 0)
3471 {
3472 hddLog(VOS_TRACE_LEVEL_ERROR, "Enable gOptimizeCAevent"
3473 " ini param to control channel avooidance indication");
3474 ret = 0;
3475 goto exit;
3476 }
3477
3478 set_value = command[cmd_len + 1] - '0';
3479 status = sme_enableDisableChanAvoidIndEvent(pHddCtx->hHal, set_value);
3480 if (status != eHAL_STATUS_SUCCESS)
3481 {
3482 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Failed to send"
3483 " enableDisableChanAoidance command to SME\n", __func__);
3484 ret = -EINVAL;
3485 }
3486
3487exit:
3488 return ret;
3489}
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05303490
Selvaraj, Sridhar3714c4d2016-06-22 15:19:12 +05303491/**
3492 * wlan_hdd_fastreassoc_handoff_request() - Post Handoff request to SME
3493 * @pHddCtx: Pointer to the HDD context
3494 * @channel: channel to reassociate
3495 * @targetApBssid: Target AP/BSSID to reassociate
3496 *
3497 * Return: None
3498 */
3499#if defined(WLAN_FEATURE_ROAM_SCAN_OFFLOAD) && !defined(QCA_WIFI_ISOC)
3500static void wlan_hdd_fastreassoc_handoff_request(hdd_context_t *pHddCtx,
3501 uint8_t channel, tSirMacAddr targetApBssid)
3502{
3503 tCsrHandoffRequest handoffInfo;
3504 handoffInfo.channel = channel;
3505 handoffInfo.src = FASTREASSOC;
3506 vos_mem_copy(handoffInfo.bssid, targetApBssid, sizeof(tSirMacAddr));
3507 sme_HandoffRequest(pHddCtx->hHal, &handoffInfo);
3508}
3509#else
3510static void wlan_hdd_fastreassoc_handoff_request(hdd_context_t *pHddCtx,
3511 uint8_t channel, tSirMacAddr targetApBssid)
3512{
3513}
3514#endif
3515
3516/**
3517 * csr_fastroam_neighbor_ap_event() - Function to trigger scan/roam
3518 * @pAdapter: Pointer to HDD adapter
3519 * @channel: Channel to scan/roam
3520 * @targetApBssid: BSSID to roam
3521 *
3522 * Return: None
3523 */
3524#ifdef QCA_WIFI_ISOC
3525static void csr_fastroam_neighbor_ap_event(hdd_adapter_t *pAdapter,
3526 uint8_t channel, tSirMacAddr targetApBssid)
3527{
3528 smeIssueFastRoamNeighborAPEvent(WLAN_HDD_GET_HAL_CTX(pAdapter),
3529 &targetApBssid[0], eSME_ROAM_TRIGGER_SCAN, channel);
3530}
3531#else
3532static void csr_fastroam_neighbor_ap_event(hdd_adapter_t *pAdapter,
3533 uint8_t channel, tSirMacAddr targetApBssid)
3534{
3535}
3536#endif
3537
3538/**
3539 * wlan_hdd_handle_fastreassoc() - Handle fastreassoc command
3540 * @pAdapter: pointer to hdd adapter
3541 * @command: pointer to the command received
3542 *
3543 * Return: VOS_STATUS enum
3544 */
3545static VOS_STATUS wlan_hdd_handle_fastreassoc(hdd_adapter_t *pAdapter,
3546 uint8_t *command)
3547{
3548 tANI_U8 *value = command;
3549 tANI_U8 channel = 0;
3550 tSirMacAddr targetApBssid;
Selvaraj, Sridhar3714c4d2016-06-22 15:19:12 +05303551 hdd_station_ctx_t *pHddStaCtx = NULL;
3552 hdd_context_t *pHddCtx = NULL;
Selvaraj, Sridhar5aff1ed2016-06-18 01:26:23 +05303553 int ret;
Selvaraj, Sridhar349b8fe2017-01-18 13:11:25 +05303554 tCsrRoamModifyProfileFields mod_profile_fields;
3555 uint32_t roam_id = 0;
Selvaraj, Sridhar3714c4d2016-06-22 15:19:12 +05303556 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
3557 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
3558
3559 /* if not associated, no need to proceed with reassoc */
3560 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState) {
3561 hddLog(LOG1, FL("Not associated!"));
3562 return eHAL_STATUS_FAILURE;
3563 }
3564
Selvaraj, Sridhar5aff1ed2016-06-18 01:26:23 +05303565 ret = hdd_parse_reassoc_command_v1_data(value, targetApBssid, &channel);
3566 if (ret) {
Selvaraj, Sridhar3714c4d2016-06-22 15:19:12 +05303567 hddLog(LOGE, FL("Failed to parse reassoc command data"));
3568 return eHAL_STATUS_FAILURE;
3569 }
3570
3571 /* if the target bssid is same as currently associated AP,
3572 then no need to proceed with reassoc */
3573 if (vos_mem_compare(targetApBssid,
3574 pHddStaCtx->conn_info.bssId,
3575 sizeof(tSirMacAddr))) {
Selvaraj, Sridhar349b8fe2017-01-18 13:11:25 +05303576 sme_GetModifyProfileFields(pHddCtx->hHal, pAdapter->sessionId,
3577 &mod_profile_fields);
3578 sme_RoamReassoc(pHddCtx->hHal, pAdapter->sessionId, NULL,
3579 mod_profile_fields, &roam_id, 1);
Selvaraj, Sridhar3714c4d2016-06-22 15:19:12 +05303580 hddLog(LOG1, FL("Reassoc BSSID is same as currently associated AP bssid"));
Selvaraj, Sridhar349b8fe2017-01-18 13:11:25 +05303581 return eHAL_STATUS_SUCCESS;
Selvaraj, Sridhar3714c4d2016-06-22 15:19:12 +05303582 }
3583
3584 /* Check channel number is a valid channel number */
3585 if (VOS_STATUS_SUCCESS !=
3586 wlan_hdd_validate_operation_channel(pAdapter, channel)) {
3587 hddLog(LOGE, FL("Invalid Channel [%d]"), channel);
3588 return eHAL_STATUS_FAILURE;
3589 }
3590
3591 /* Proceed with reassoc */
3592 wlan_hdd_fastreassoc_handoff_request(pHddCtx, channel, targetApBssid);
3593
3594 /* Proceed with scan/roam */
3595 csr_fastroam_neighbor_ap_event(pAdapter, channel, targetApBssid);
3596
3597 return eHAL_STATUS_SUCCESS;
3598}
3599
3600/**
3601 * hdd_assign_reassoc_handoff - Set handoff source as REASSOC
3602 * @handoffInfo: Pointer to the csr Handoff Request.
3603 *
3604 * Return: None
3605 */
3606#ifndef QCA_WIFI_ISOC
3607static inline void hdd_assign_reassoc_handoff(tCsrHandoffRequest *handoffInfo)
3608{
3609 handoffInfo->src = REASSOC;
3610}
3611#else
3612static inline void hdd_assign_reassoc_handoff(tCsrHandoffRequest *handoffInfo)
3613{
3614}
3615#endif
3616
Ashish Kumar Dhanotiya6c7969c2020-06-17 12:25:37 +05303617void wlan_hdd_free_cache_channels(hdd_context_t *hdd_ctx)
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +05303618{
Ashish Kumar Dhanotiya19803832018-05-24 19:05:48 +05303619 if(!hdd_ctx || !hdd_ctx->original_channels)
3620 return;
3621
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +05303622 mutex_lock(&hdd_ctx->cache_channel_lock);
Ashish Kumar Dhanotiya95e5bc22018-04-19 17:06:33 +05303623 hdd_ctx->original_channels->num_channels = 0;
3624 vos_mem_free(hdd_ctx->original_channels->channel_info);
3625 hdd_ctx->original_channels->channel_info = NULL;
3626 vos_mem_free(hdd_ctx->original_channels);
3627 hdd_ctx->original_channels = NULL;
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +05303628 mutex_unlock(&hdd_ctx->cache_channel_lock);
3629}
3630
3631/**
3632 * hdd_alloc_chan_cache() - Allocate the memory to cache the channel
3633 * info for the channels received in command SET_DISABLE_CHANNEL_LIST
3634 * @hdd_ctx: Pointer to HDD context
3635 * @num_chan: Number of channels for which memory needs to
3636 * be allocated
3637 *
3638 * Return: 0 on success and error code on failure
3639 */
3640
3641int hdd_alloc_chan_cache(hdd_context_t *hdd_ctx, int num_chan)
3642{
Ashish Kumar Dhanotiya95e5bc22018-04-19 17:06:33 +05303643 hdd_ctx->original_channels =
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +05303644 vos_mem_malloc(sizeof(struct hdd_cache_channels));
Ashish Kumar Dhanotiya95e5bc22018-04-19 17:06:33 +05303645 if (!hdd_ctx->original_channels) {
3646 hddLog(VOS_TRACE_LEVEL_ERROR,
3647 "In %s, VOS_MALLOC_ERR", __func__);
3648 return -EINVAL;
3649 }
3650 hdd_ctx->original_channels->num_channels = num_chan;
3651 hdd_ctx->original_channels->channel_info =
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +05303652 vos_mem_malloc(num_chan *
3653 sizeof(struct hdd_cache_channel_info));
Ashish Kumar Dhanotiya95e5bc22018-04-19 17:06:33 +05303654 if (!hdd_ctx->original_channels->channel_info) {
3655 hddLog(VOS_TRACE_LEVEL_ERROR,
3656 "In %s, VOS_MALLOC_ERR", __func__);
3657 hdd_ctx->original_channels->num_channels = 0;
3658 vos_mem_free(hdd_ctx->original_channels);
3659 hdd_ctx->original_channels = NULL;
3660 return -ENOMEM;
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +05303661 }
3662 return 0;
3663
3664}
3665
3666
3667int hdd_parse_disable_chan_cmd(hdd_adapter_t *adapter, tANI_U8 *ptr)
3668{
3669 v_PVOID_t pvosGCtx = vos_get_global_context(VOS_MODULE_ID_HDD, NULL);
3670 hdd_context_t *hdd_ctx = vos_get_context(VOS_MODULE_ID_HDD, pvosGCtx);
3671 tANI_U8 *param;
Ashish Kumar Dhanotiya95e5bc22018-04-19 17:06:33 +05303672 int j, tempInt, ret = 0, i, num_channels;
3673 int parsed_channels[MAX_CHANNEL];
3674 bool is_command_repeated = false;
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +05303675
3676 if (NULL == pvosGCtx) {
3677 hddLog(VOS_TRACE_LEVEL_FATAL,
3678 "VOS Global Context is NULL");
3679 return -EINVAL;
3680 }
3681
3682 if (NULL == hdd_ctx) {
3683 hddLog(VOS_TRACE_LEVEL_FATAL, "HDD Context is NULL");
3684 return -EINVAL;
3685 }
3686
3687 param = strchr(ptr, ' ');
3688 /*no argument after the command*/
3689 if (NULL == param)
3690 return -EINVAL;
3691
3692 /*no space after the command*/
3693 else if (SPACE_ASCII_VALUE != *param)
3694 return -EINVAL;
3695
3696 param++;
3697
3698 /*removing empty spaces*/
3699 while ((SPACE_ASCII_VALUE == *param) && ('\0' != *param))
3700 param++;
3701
3702 /*no argument followed by spaces*/
3703 if ('\0' == *param)
3704 return -EINVAL;
3705
3706 /*getting the first argument ie the number of channels*/
3707 if (sscanf(param, "%d ", &tempInt) != 1) {
3708 hddLog(VOS_TRACE_LEVEL_ERROR,
3709 "%s: Cannot get number of channels from input",
3710 __func__);
3711 return -EINVAL;
3712 }
3713
3714 if (tempInt < 0 || tempInt > MAX_CHANNEL) {
3715 hddLog(VOS_TRACE_LEVEL_ERROR,
3716 "%s: Invalid Number of channel received", __func__);
3717 return -EINVAL;
3718 }
3719
3720 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
3721 "%s: Number of channel to disable are: %d",
3722 __func__, tempInt);
3723
3724 if (!tempInt) {
Ashish Kumar Dhanotiya6c7969c2020-06-17 12:25:37 +05303725 /*
3726 * Restore and Free the cache channels when the command is
3727 * received with num channels as 0
3728 */
3729 wlan_hdd_restore_channels(hdd_ctx);
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +05303730 return 0;
3731 }
3732
3733 mutex_lock(&hdd_ctx->cache_channel_lock);
Ashish Kumar Dhanotiya95e5bc22018-04-19 17:06:33 +05303734 if (!hdd_ctx->original_channels) {
3735 if (hdd_alloc_chan_cache(hdd_ctx, tempInt)) {
3736 ret = -ENOMEM;
3737 goto mem_alloc_failed;
3738 }
3739 } else if (hdd_ctx->original_channels->num_channels != tempInt) {
3740 hddLog(VOS_TRACE_LEVEL_ERROR,
3741 "%s, Invalid No of channel provided in the list",
3742 __func__);
3743 ret = -EINVAL;
3744 is_command_repeated = true;
3745 goto parse_failed;
3746 } else {
3747 is_command_repeated = true;
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +05303748 }
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +05303749
Ashish Kumar Dhanotiya95e5bc22018-04-19 17:06:33 +05303750 num_channels = tempInt;
3751
3752 for (j = 0; j < num_channels; j++) {
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +05303753 /*
3754 * param pointing to the beginning of first space
3755 * after number of channels
3756 */
3757 param = strpbrk(param, " ");
3758 /*no channel list after the number of channels argument*/
3759 if (NULL == param) {
3760 hddLog(VOS_TRACE_LEVEL_ERROR,
3761 "%s, Invalid No of channel provided in the list",
3762 __func__);
3763 ret = -EINVAL;
Ashish Kumar Dhanotiya95e5bc22018-04-19 17:06:33 +05303764 goto parse_failed;
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +05303765 }
3766
3767 param++;
3768
3769 /*removing empty space*/
3770 while ((SPACE_ASCII_VALUE == *param) && ('\0' != *param))
3771 param++;
3772
3773 if ('\0' == *param) {
3774 hddLog(VOS_TRACE_LEVEL_ERROR,
3775 "%s, No channel is provided in the list",
3776 __func__);
3777 ret = -EINVAL;
Ashish Kumar Dhanotiya95e5bc22018-04-19 17:06:33 +05303778 goto parse_failed;
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +05303779
3780 }
3781
3782 if (sscanf(param, "%d ", &tempInt) != 1) {
3783 hddLog(VOS_TRACE_LEVEL_ERROR,
3784 "%s: Cannot read channel number",
3785 __func__);
3786 ret = -EINVAL;
Ashish Kumar Dhanotiya95e5bc22018-04-19 17:06:33 +05303787 goto parse_failed;
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +05303788
3789 }
3790
3791 if (!IS_CHANNEL_VALID(tempInt)) {
3792 hddLog(VOS_TRACE_LEVEL_ERROR,
3793 "%s: Invalid channel number received",
3794 __func__);
3795 ret = -EINVAL;
Ashish Kumar Dhanotiya95e5bc22018-04-19 17:06:33 +05303796 goto parse_failed;
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +05303797
3798 }
3799
3800 hddLog(VOS_TRACE_LEVEL_INFO, "%s: channel[%d] = %d", __func__,
3801 j, tempInt);
Ashish Kumar Dhanotiya95e5bc22018-04-19 17:06:33 +05303802
3803 parsed_channels[j] = tempInt;
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +05303804 }
3805
3806 /*extra arguments check*/
3807 param = strchr(param, ' ');
3808 if (NULL != param) {
3809 while ((SPACE_ASCII_VALUE == *param) && ('\0' != *param))
3810 param++;
3811
3812 if ('\0' != *param) {
3813 hddLog(VOS_TRACE_LEVEL_ERROR,
3814 "%s: Invalid argument received", __func__);
3815 ret = -EINVAL;
Ashish Kumar Dhanotiya95e5bc22018-04-19 17:06:33 +05303816 goto parse_failed;
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +05303817 }
3818 }
3819
Ashish Kumar Dhanotiya95e5bc22018-04-19 17:06:33 +05303820 /*
3821 * If command is received first time, cache the channels to
3822 * be disabled else compare the channels received in the
3823 * command with the cached channels, if channel list matches
3824 * return success otherewise return failure.
3825 */
3826 if (!is_command_repeated)
3827 for (j = 0; j < num_channels; j++)
3828 hdd_ctx->original_channels->
3829 channel_info[j].channel_num =
3830 parsed_channels[j];
3831 else {
3832 for (i = 0; i < num_channels; i++) {
3833 for (j = 0; j < num_channels; j++)
3834 if (hdd_ctx->original_channels->
3835 channel_info[i].channel_num ==
3836 parsed_channels[j])
3837 break;
3838 if (j == num_channels) {
3839 ret = -EINVAL;
3840 goto parse_failed;
3841 }
3842 }
3843 ret = 0;
3844 }
3845
3846mem_alloc_failed:
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +05303847 mutex_unlock(&hdd_ctx->cache_channel_lock);
Ashish Kumar Dhanotiya1cf97dd2019-03-11 16:59:25 +05303848 /* Disable the channels received in command SET_DISABLE_CHANNEL_LIST*/
3849 if (!is_command_repeated) {
3850 wlan_hdd_disable_channels(hdd_ctx);
3851 hdd_check_and_disconnect_sta_on_invalid_channel(hdd_ctx);
3852 }
3853
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +05303854 EXIT();
3855
3856 return ret;
Ashish Kumar Dhanotiya95e5bc22018-04-19 17:06:33 +05303857
3858parse_failed:
3859 mutex_unlock(&hdd_ctx->cache_channel_lock);
3860 if (!is_command_repeated)
3861 wlan_hdd_free_cache_channels(hdd_ctx);
3862 EXIT();
3863 return ret;
3864
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +05303865}
3866
Hanumanth Reddy Pothula8ae38bb2018-03-07 18:59:30 +05303867int hdd_get_disable_ch_list(hdd_context_t *hdd_ctx, tANI_U8 *buf,
Ashish Kumar Dhanotiya95e5bc22018-04-19 17:06:33 +05303868 uint32_t buf_len)
Hanumanth Reddy Pothula8ae38bb2018-03-07 18:59:30 +05303869{
3870 struct hdd_cache_channel_info *ch_list;
3871 unsigned char i, num_ch;
3872 int len = 0;
3873
3874 mutex_lock(&hdd_ctx->cache_channel_lock);
Ashish Kumar Dhanotiya95e5bc22018-04-19 17:06:33 +05303875 if (hdd_ctx->original_channels &&
3876 hdd_ctx->original_channels->num_channels &&
3877 hdd_ctx->original_channels->channel_info) {
3878 num_ch = hdd_ctx->original_channels->num_channels;
Hanumanth Reddy Pothula8ae38bb2018-03-07 18:59:30 +05303879
3880 len = scnprintf(buf, buf_len, "%s %hhu",
3881 "GET_DISABLE_CHANNEL_LIST", num_ch);
3882
Ashish Kumar Dhanotiya95e5bc22018-04-19 17:06:33 +05303883 ch_list = hdd_ctx->original_channels->channel_info;
Hanumanth Reddy Pothula8ae38bb2018-03-07 18:59:30 +05303884
Ashish Kumar Dhanotiya95e5bc22018-04-19 17:06:33 +05303885 for (i = 0; (i < num_ch) && (len < buf_len-1); i++) {
Hanumanth Reddy Pothula8ae38bb2018-03-07 18:59:30 +05303886 len += scnprintf(buf + len, buf_len - len,
3887 " %d", ch_list[i].channel_num);
3888 }
3889 }
3890 mutex_unlock(&hdd_ctx->cache_channel_lock);
3891
3892 return len;
3893}
3894
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07003895static int hdd_driver_command(hdd_adapter_t *pAdapter,
3896 hdd_priv_data_t *ppriv_data)
Jeff Johnson295189b2012-06-20 16:38:30 -07003897{
Jeff Johnson295189b2012-06-20 16:38:30 -07003898 hdd_priv_data_t priv_data;
3899 tANI_U8 *command = NULL;
Kaushik, Sushant96122442014-10-21 16:40:18 +05303900 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
3901 hdd_scaninfo_t *pScanInfo = NULL;
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07003902 int ret = 0;
Kaushik, Sushant96122442014-10-21 16:40:18 +05303903 int status;
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05303904#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
3905 struct cfg80211_mgmt_tx_params params;
3906#endif
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303907
3908 ENTER();
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07003909 /*
3910 * Note that valid pointers are provided by caller
3911 */
Jeff Johnson295189b2012-06-20 16:38:30 -07003912
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07003913 /* copy to local struct to avoid numerous changes to legacy code */
3914 priv_data = *ppriv_data;
Jeff Johnson295189b2012-06-20 16:38:30 -07003915
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07003916 if (priv_data.total_len <= 0 ||
3917 priv_data.total_len > WLAN_PRIV_DATA_MAX_LEN)
Sameer Thalappil8ef3a0e2013-04-05 14:36:04 -07003918 {
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07003919 hddLog(VOS_TRACE_LEVEL_WARN,
3920 "%s:invalid priv_data.total_len(%d)!!!", __func__,
3921 priv_data.total_len);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07003922 ret = -EINVAL;
3923 goto exit;
3924 }
Kaushik, Sushant96122442014-10-21 16:40:18 +05303925 status = wlan_hdd_validate_context(pHddCtx);
3926 if (0 != status)
3927 {
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303928 ret = -EINVAL;
3929 goto exit;
Kaushik, Sushant96122442014-10-21 16:40:18 +05303930 }
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07003931 /* Allocate +1 for '\0' */
3932 command = kmalloc(priv_data.total_len + 1, GFP_KERNEL);
Jeff Johnson295189b2012-06-20 16:38:30 -07003933 if (!command)
3934 {
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07003935 hddLog(VOS_TRACE_LEVEL_ERROR,
3936 "%s: failed to allocate memory", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07003937 ret = -ENOMEM;
3938 goto exit;
3939 }
3940
3941 if (copy_from_user(command, priv_data.buf, priv_data.total_len))
3942 {
3943 ret = -EFAULT;
3944 goto exit;
3945 }
3946
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07003947 /* Make sure the command is NUL-terminated */
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07003948 command[priv_data.total_len] = '\0';
3949
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07003950 /* at one time the following block of code was conditional. braces
3951 * have been retained to avoid re-indenting the legacy code
3952 */
Jeff Johnson295189b2012-06-20 16:38:30 -07003953 {
3954 hdd_context_t *pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
3955
3956 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudif9bdd4e2012-10-30 18:05:03 -07003957 "%s: Received %s cmd from Wi-Fi GUI***", __func__, command);
Jeff Johnson295189b2012-06-20 16:38:30 -07003958
3959 if (strncmp(command, "P2P_DEV_ADDR", 12) == 0 )
3960 {
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05303961 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
3962 TRACE_CODE_HDD_P2P_DEV_ADDR_IOCTL,
3963 pAdapter->sessionId, (unsigned)
3964 (*(pHddCtx->p2pDeviceAddress.bytes+2)<<24 |
3965 *(pHddCtx->p2pDeviceAddress.bytes+3)<<16 |
3966 *(pHddCtx->p2pDeviceAddress.bytes+4)<<8 |
3967 *(pHddCtx->p2pDeviceAddress.bytes+5))));
Jeff Johnson295189b2012-06-20 16:38:30 -07003968 if (copy_to_user(priv_data.buf, pHddCtx->p2pDeviceAddress.bytes,
3969 sizeof(tSirMacAddr)))
3970 {
3971 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08003972 "%s: failed to copy data to user buffer", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07003973 ret = -EFAULT;
3974 }
3975 }
Amar Singhal0974e402013-02-12 14:27:46 -08003976 else if(strncmp(command, "SETBAND", 7) == 0)
Jeff Johnson295189b2012-06-20 16:38:30 -07003977 {
Amar Singhal0974e402013-02-12 14:27:46 -08003978 tANI_U8 *ptr = command ;
Srinivas Girigowdade697412013-02-14 16:31:48 -08003979
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05303980 ret = hdd_drv_cmd_validate(command, 7);
3981 if (ret)
3982 goto exit;
3983
Jeff Johnson295189b2012-06-20 16:38:30 -07003984 /* Change band request received */
Srinivas Girigowdade697412013-02-14 16:31:48 -08003985
3986 /* First 8 bytes will have "SETBAND " and
Jeff Johnson295189b2012-06-20 16:38:30 -07003987 * 9 byte will have band setting value */
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07003988 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Amar Singhal0974e402013-02-12 14:27:46 -08003989 "%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 +05303990 if(VOS_FTM_MODE != hdd_get_conparam())
3991 {
3992 /* Change band request received */
3993 ret = hdd_setBand_helper(pAdapter->dev, ptr);
3994 if(ret < 0)
3995 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
3996 "%s: failed to set band ret=%d", __func__, ret);
3997 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08003998 }
Kiet Lamf040f472013-11-20 21:15:23 +05303999 else if(strncmp(command, "SETWMMPS", 8) == 0)
4000 {
4001 tANI_U8 *ptr = command;
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05304002
4003 ret = hdd_drv_cmd_validate(command, 8);
4004 if (ret)
4005 goto exit;
4006
Kiet Lamf040f472013-11-20 21:15:23 +05304007 ret = hdd_wmmps_helper(pAdapter, ptr);
4008 }
Agarwal Ashishef54a182014-12-16 15:07:31 +05304009
4010 else if(strncmp(command, "TDLSSCAN", 8) == 0)
4011 {
4012 tANI_U8 *ptr = command;
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05304013
4014 ret = hdd_drv_cmd_validate(command, 8);
4015 if (ret)
4016 goto exit;
4017
Agarwal Ashishef54a182014-12-16 15:07:31 +05304018 ret = hdd_set_tdls_scan_type(pAdapter, ptr);
4019 }
4020
Jeff Johnson32d95a32012-09-10 13:15:23 -07004021 else if ( strncasecmp(command, "COUNTRY", 7) == 0 )
4022 {
4023 char *country_code;
4024
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05304025 ret = hdd_drv_cmd_validate(command, 7);
4026 if (ret)
4027 goto exit;
4028
Jeff Johnson32d95a32012-09-10 13:15:23 -07004029 country_code = command + 8;
Tushnim Bhattacharyya9cdf6082013-04-21 16:33:30 -07004030
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07004031 INIT_COMPLETION(pAdapter->change_country_code);
Tushnim Bhattacharyya9cdf6082013-04-21 16:33:30 -07004032 hdd_checkandupdate_dfssetting(pAdapter, country_code);
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -07004033#ifndef CONFIG_ENABLE_LINUX_REG
Gopichand Nakkaladacbcb52013-04-18 16:41:54 +05304034 hdd_checkandupdate_phymode(pAdapter, country_code);
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -07004035#endif
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07004036 ret = (int)sme_ChangeCountryCode(pHddCtx->hHal,
4037 (void *)(tSmeChangeCountryCallback)
4038 wlan_hdd_change_country_code_callback,
Abhishek Singha306a442013-11-07 18:39:01 +05304039 country_code, pAdapter, pHddCtx->pvosContext, eSIR_TRUE, eSIR_TRUE);
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07004040 if (eHAL_STATUS_SUCCESS == ret)
4041 {
4042 ret = wait_for_completion_interruptible_timeout(
4043 &pAdapter->change_country_code,
4044 msecs_to_jiffies(WLAN_WAIT_TIME_COUNTRY));
4045 if (0 >= ret)
4046 {
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07004047 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: SME while setting country code timed out %d",
c_hpothu6ff1c3c2013-10-01 19:01:57 +05304048 __func__, ret);
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07004049 }
4050 }
4051 else
Jeff Johnson32d95a32012-09-10 13:15:23 -07004052 {
4053 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07004054 "%s: SME Change Country code fail ret=%d", __func__, ret);
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07004055 ret = -EINVAL;
Jeff Johnson32d95a32012-09-10 13:15:23 -07004056 }
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07004057
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07004058 }
4059 /*
4060 command should be a string having format
4061 SET_SAP_CHANNEL_LIST <num of channels> <the channels seperated by spaces>
4062 */
Amar Singhal0974e402013-02-12 14:27:46 -08004063 else if(strncmp(command, "SET_SAP_CHANNEL_LIST", 20) == 0)
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07004064 {
Amar Singhal0974e402013-02-12 14:27:46 -08004065 tANI_U8 *ptr = command;
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07004066
4067 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004068 " Received Command to Set Preferred Channels for SAP in %s", __func__);
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07004069
Mahesh Kumar Kalikot Veetil2aad8d82013-02-07 12:31:28 -08004070 ret = sapSetPreferredChannel(ptr);
Jeff Johnson32d95a32012-09-10 13:15:23 -07004071 }
Sourav Mohapatra2416e0e2018-03-05 18:44:21 +05304072
4073 else if (strncmp(command, "VOWIFIMODE", 10) == 0)
4074 {
4075 tANI_U8 *ptr;
4076
4077 ret = hdd_drv_cmd_validate(command, 10);
4078 if (ret)
4079 goto exit;
4080
4081 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4082 "Received Command for VOWIFI mode in %s", __func__);
4083
4084 ptr = (tANI_U8*)command + 11;
4085 hdd_set_vowifi_mode(pHddCtx, *ptr - '0');
Sourav Mohapatra9d963282018-02-08 20:03:05 +05304086 }
4087
4088 else if (strncmp(command, "OLPCMODE", 8) == 0)
4089 {
4090 tANI_U8 *ptr;
4091
4092 ret = hdd_drv_cmd_validate(command, 8);
4093 if (ret)
4094 goto exit;
4095
4096 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4097 " Received Command to go to low power mode in %s", __func__);
4098
4099 ptr = (tANI_U8*)command + 9;
4100 hdd_set_olpc_mode((tHalHandle)(pHddCtx->hHal), *ptr - '0');
Sourav Mohapatra2416e0e2018-03-05 18:44:21 +05304101 }
4102
Sameer Thalappil45931fb2013-02-01 11:18:05 -08004103 else if(strncmp(command, "SETSUSPENDMODE", 14) == 0)
4104 {
4105 int suspend = 0;
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05304106 tANI_U8 *ptr;
4107
4108 ret = hdd_drv_cmd_validate(command, 14);
4109 if (ret)
4110 goto exit;
4111
4112 ptr = (tANI_U8*)command + 15;
Sameer Thalappil45931fb2013-02-01 11:18:05 -08004113
4114 suspend = *ptr - '0';
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05304115 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
4116 TRACE_CODE_HDD_SETSUSPENDMODE_IOCTL,
4117 pAdapter->sessionId, suspend));
Sameer Thalappil45931fb2013-02-01 11:18:05 -08004118 hdd_set_wlan_suspend_mode(suspend);
4119 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08004120#ifdef WLAN_FEATURE_NEIGHBOR_ROAMING
4121 else if (strncmp(command, "SETROAMTRIGGER", 14) == 0)
4122 {
4123 tANI_U8 *value = command;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07004124 tANI_S8 rssi = 0;
Srinivas Girigowdade697412013-02-14 16:31:48 -08004125 tANI_U8 lookUpThreshold = CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_DEFAULT;
4126 eHalStatus status = eHAL_STATUS_SUCCESS;
4127
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05304128 ret = hdd_drv_cmd_validate(command, 14);
4129 if (ret)
4130 goto exit;
4131
Srinivas Girigowdade697412013-02-14 16:31:48 -08004132 /* Move pointer to ahead of SETROAMTRIGGER<delimiter> */
4133 value = value + 15;
4134
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07004135 /* Convert the value from ascii to integer */
4136 ret = kstrtos8(value, 10, &rssi);
4137 if (ret < 0)
4138 {
4139 /* If the input value is greater than max value of datatype, then also
4140 kstrtou8 fails */
4141 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4142 "%s: kstrtou8 failed Input value may be out of range[%d - %d]",
Srinivas Girigowdafa7157d2013-10-31 10:14:22 -07004143 __func__,
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07004144 CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MIN,
4145 CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MAX);
4146 ret = -EINVAL;
4147 goto exit;
4148 }
4149
Srinivas Girigowdade697412013-02-14 16:31:48 -08004150 lookUpThreshold = abs(rssi);
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07004151
Srinivas Girigowdade697412013-02-14 16:31:48 -08004152 if ((lookUpThreshold < CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MIN) ||
4153 (lookUpThreshold > CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MAX))
4154 {
4155 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4156 "Neighbor lookup threshold value %d is out of range"
4157 " (Min: %d Max: %d)", lookUpThreshold,
4158 CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MIN,
4159 CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MAX);
4160 ret = -EINVAL;
4161 goto exit;
4162 }
4163
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05304164 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
4165 TRACE_CODE_HDD_SETROAMTRIGGER_IOCTL,
4166 pAdapter->sessionId, lookUpThreshold));
Srinivas Girigowdade697412013-02-14 16:31:48 -08004167 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4168 "%s: Received Command to Set Roam trigger"
4169 " (Neighbor lookup threshold) = %d", __func__, lookUpThreshold);
4170
4171 pHddCtx->cfg_ini->nNeighborLookupRssiThreshold = lookUpThreshold;
4172 status = sme_setNeighborLookupRssiThreshold((tHalHandle)(pHddCtx->hHal), lookUpThreshold);
4173 if (eHAL_STATUS_SUCCESS != status)
4174 {
4175 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4176 "%s: Failed to set roam trigger, try again", __func__);
4177 ret = -EPERM;
4178 goto exit;
4179 }
4180
4181 /* Set Reassoc threshold to (lookup rssi threshold + 5 dBm) */
mukul sharmad6e1fdd2014-06-23 19:19:09 +05304182 pHddCtx->cfg_ini->nNeighborReassocRssiThreshold = lookUpThreshold + 5;
Srinivas Girigowdade697412013-02-14 16:31:48 -08004183 sme_setNeighborReassocRssiThreshold((tHalHandle)(pHddCtx->hHal), lookUpThreshold + 5);
4184 }
4185 else if (strncmp(command, "GETROAMTRIGGER", 14) == 0)
4186 {
4187 tANI_U8 lookUpThreshold = sme_getNeighborLookupRssiThreshold((tHalHandle)(pHddCtx->hHal));
4188 int rssi = (-1) * lookUpThreshold;
4189 char extra[32];
4190 tANI_U8 len = 0;
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05304191 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
4192 TRACE_CODE_HDD_GETROAMTRIGGER_IOCTL,
4193 pAdapter->sessionId, lookUpThreshold));
Sameer Thalappilb0a30232013-09-27 15:37:48 -07004194 len = scnprintf(extra, sizeof(extra), "%s %d", command, rssi);
Srinivas Girigowda91719232015-07-13 15:10:10 +05304195 len = VOS_MIN(priv_data.total_len, len + 1);
4196 if (copy_to_user(priv_data.buf, &extra, len))
Srinivas Girigowdade697412013-02-14 16:31:48 -08004197 {
4198 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4199 "%s: failed to copy data to user buffer", __func__);
4200 ret = -EFAULT;
4201 goto exit;
4202 }
4203 }
4204 else if (strncmp(command, "SETROAMSCANPERIOD", 17) == 0)
4205 {
4206 tANI_U8 *value = command;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07004207 tANI_U8 roamScanPeriod = 0;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004208 tANI_U16 neighborEmptyScanRefreshPeriod = CFG_EMPTY_SCAN_REFRESH_PERIOD_DEFAULT;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07004209
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05304210 ret = hdd_drv_cmd_validate(command, 17);
4211 if (ret)
4212 goto exit;
4213
Srinivas Girigowdade697412013-02-14 16:31:48 -08004214 /* input refresh period is in terms of seconds */
4215 /* Move pointer to ahead of SETROAMSCANPERIOD<delimiter> */
4216 value = value + 18;
4217 /* Convert the value from ascii to integer */
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07004218 ret = kstrtou8(value, 10, &roamScanPeriod);
Srinivas Girigowdade697412013-02-14 16:31:48 -08004219 if (ret < 0)
4220 {
4221 /* If the input value is greater than max value of datatype, then also
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07004222 kstrtou8 fails */
Srinivas Girigowdade697412013-02-14 16:31:48 -08004223 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07004224 "%s: kstrtou8 failed Input value may be out of range[%d - %d]",
Srinivas Girigowdade697412013-02-14 16:31:48 -08004225 __func__,
Srinivas Girigowdab8edd1e2013-03-19 11:42:08 -07004226 (CFG_EMPTY_SCAN_REFRESH_PERIOD_MIN/1000),
4227 (CFG_EMPTY_SCAN_REFRESH_PERIOD_MAX/1000));
Srinivas Girigowdade697412013-02-14 16:31:48 -08004228 ret = -EINVAL;
4229 goto exit;
4230 }
4231
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07004232 if ((roamScanPeriod < (CFG_EMPTY_SCAN_REFRESH_PERIOD_MIN/1000)) ||
4233 (roamScanPeriod > (CFG_EMPTY_SCAN_REFRESH_PERIOD_MAX/1000)))
Srinivas Girigowdade697412013-02-14 16:31:48 -08004234 {
4235 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07004236 "Roam scan period value %d is out of range"
4237 " (Min: %d Max: %d)", roamScanPeriod,
Srinivas Girigowdab8edd1e2013-03-19 11:42:08 -07004238 (CFG_EMPTY_SCAN_REFRESH_PERIOD_MIN/1000),
4239 (CFG_EMPTY_SCAN_REFRESH_PERIOD_MAX/1000));
Srinivas Girigowdade697412013-02-14 16:31:48 -08004240 ret = -EINVAL;
4241 goto exit;
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05304242 }
4243 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
4244 TRACE_CODE_HDD_SETROAMSCANPERIOD_IOCTL,
4245 pAdapter->sessionId, roamScanPeriod));
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07004246 neighborEmptyScanRefreshPeriod = roamScanPeriod * 1000;
Srinivas Girigowdade697412013-02-14 16:31:48 -08004247
4248 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4249 "%s: Received Command to Set roam scan period"
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07004250 " (Empty Scan refresh period) = %d", __func__, roamScanPeriod);
Srinivas Girigowdade697412013-02-14 16:31:48 -08004251
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004252 pHddCtx->cfg_ini->nEmptyScanRefreshPeriod = neighborEmptyScanRefreshPeriod;
4253 sme_UpdateEmptyScanRefreshPeriod((tHalHandle)(pHddCtx->hHal), neighborEmptyScanRefreshPeriod);
Srinivas Girigowdade697412013-02-14 16:31:48 -08004254 }
4255 else if (strncmp(command, "GETROAMSCANPERIOD", 17) == 0)
4256 {
4257 tANI_U16 nEmptyScanRefreshPeriod = sme_getEmptyScanRefreshPeriod((tHalHandle)(pHddCtx->hHal));
4258 char extra[32];
4259 tANI_U8 len = 0;
4260
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05304261 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
4262 TRACE_CODE_HDD_GETROAMSCANPERIOD_IOCTL,
4263 pAdapter->sessionId, nEmptyScanRefreshPeriod));
Sameer Thalappilb0a30232013-09-27 15:37:48 -07004264 len = scnprintf(extra, sizeof(extra), "%s %d",
4265 "GETROAMSCANPERIOD", (nEmptyScanRefreshPeriod/1000));
Srinivas Girigowdade697412013-02-14 16:31:48 -08004266 /* Returned value is in units of seconds */
Ratnam Rachuria72ba112015-07-17 13:27:03 +05304267 len = VOS_MIN(priv_data.total_len, len + 1);
4268 if (copy_to_user(priv_data.buf, &extra, len)) {
Srinivas Girigowdade697412013-02-14 16:31:48 -08004269 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4270 "%s: failed to copy data to user buffer", __func__);
4271 ret = -EFAULT;
4272 goto exit;
4273 }
4274 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004275 else if (strncmp(command, "SETROAMSCANREFRESHPERIOD", 24) == 0)
4276 {
4277 tANI_U8 *value = command;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07004278 tANI_U8 roamScanRefreshPeriod = 0;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004279 tANI_U16 neighborScanRefreshPeriod = CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_DEFAULT;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07004280
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05304281 ret = hdd_drv_cmd_validate(command, 24);
4282 if (ret)
4283 goto exit;
4284
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004285 /* input refresh period is in terms of seconds */
4286 /* Move pointer to ahead of SETROAMSCANREFRESHPERIOD<delimiter> */
4287 value = value + 25;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07004288
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004289 /* Convert the value from ascii to integer */
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07004290 ret = kstrtou8(value, 10, &roamScanRefreshPeriod);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004291 if (ret < 0)
4292 {
4293 /* If the input value is greater than max value of datatype, then also
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07004294 kstrtou8 fails */
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004295 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07004296 "%s: kstrtou8 failed Input value may be out of range[%d - %d]",
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004297 __func__,
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004298 (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MIN/1000),
4299 (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MAX/1000));
4300 ret = -EINVAL;
4301 goto exit;
4302 }
4303
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07004304 if ((roamScanRefreshPeriod < (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MIN/1000)) ||
4305 (roamScanRefreshPeriod > (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MAX/1000)))
4306 {
4307 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4308 "Neighbor scan results refresh period value %d is out of range"
4309 " (Min: %d Max: %d)", roamScanRefreshPeriod,
4310 (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MIN/1000),
4311 (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MAX/1000));
4312 ret = -EINVAL;
4313 goto exit;
4314 }
4315 neighborScanRefreshPeriod = roamScanRefreshPeriod * 1000;
4316
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004317 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4318 "%s: Received Command to Set roam scan refresh period"
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07004319 " (Scan refresh period) = %d", __func__, roamScanRefreshPeriod);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004320
4321 pHddCtx->cfg_ini->nNeighborResultsRefreshPeriod = neighborScanRefreshPeriod;
4322 sme_setNeighborScanRefreshPeriod((tHalHandle)(pHddCtx->hHal), neighborScanRefreshPeriod);
4323 }
4324 else if (strncmp(command, "GETROAMSCANREFRESHPERIOD", 24) == 0)
4325 {
4326 tANI_U16 value = sme_getNeighborScanRefreshPeriod((tHalHandle)(pHddCtx->hHal));
4327 char extra[32];
4328 tANI_U8 len = 0;
4329
Sameer Thalappilb0a30232013-09-27 15:37:48 -07004330 len = scnprintf(extra, sizeof(extra), "%s %d",
4331 "GETROAMSCANREFRESHPERIOD", (value/1000));
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004332 /* Returned value is in units of seconds */
Ratnam Rachuri2c9d6702015-07-17 13:25:16 +05304333 len = VOS_MIN(priv_data.total_len, len + 1);
4334 if (copy_to_user(priv_data.buf, &extra, len)) {
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004335 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4336 "%s: failed to copy data to user buffer", __func__);
4337 ret = -EFAULT;
4338 goto exit;
4339 }
4340 }
Varun Reddy Yeturu6d99ac82013-05-08 14:15:35 -07004341#ifdef FEATURE_WLAN_LFR
4342 /* SETROAMMODE */
4343 else if (strncmp(command, "SETROAMMODE", SIZE_OF_SETROAMMODE) == 0)
4344 {
4345 tANI_U8 *value = command;
4346 tANI_BOOLEAN roamMode = CFG_LFR_FEATURE_ENABLED_DEFAULT;
4347
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +05304348 if (pHddCtx->concurrency_mode == VOS_STA_MON) {
4349 hddLog(LOGE,
4350 FL("Roaming is always disabled in STA + MON concurrency"));
4351 ret = -EINVAL;
4352 goto exit;
4353 }
4354
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05304355 ret = hdd_drv_cmd_validate(command, SIZE_OF_SETROAMMODE);
4356 if (ret)
4357 goto exit;
4358
Varun Reddy Yeturu6d99ac82013-05-08 14:15:35 -07004359 /* Move pointer to ahead of SETROAMMODE<delimiter> */
4360 value = value + SIZE_OF_SETROAMMODE + 1;
4361
4362 /* Convert the value from ascii to integer */
4363 ret = kstrtou8(value, SIZE_OF_SETROAMMODE, &roamMode);
4364 if (ret < 0)
4365 {
4366 /* If the input value is greater than max value of datatype, then also
4367 kstrtou8 fails */
4368 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4369 "%s: kstrtou8 failed range [%d - %d]", __func__,
4370 CFG_LFR_FEATURE_ENABLED_MIN,
4371 CFG_LFR_FEATURE_ENABLED_MAX);
4372 ret = -EINVAL;
4373 goto exit;
4374 }
4375 if ((roamMode < CFG_LFR_FEATURE_ENABLED_MIN) ||
4376 (roamMode > CFG_LFR_FEATURE_ENABLED_MAX))
4377 {
4378 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4379 "Roam Mode value %d is out of range"
4380 " (Min: %d Max: %d)", roamMode,
4381 CFG_LFR_FEATURE_ENABLED_MIN,
4382 CFG_LFR_FEATURE_ENABLED_MAX);
4383 ret = -EINVAL;
4384 goto exit;
4385 }
4386
4387 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4388 "%s: Received Command to Set Roam Mode = %d", __func__, roamMode);
4389 /*
4390 * Note that
4391 * SETROAMMODE 0 is to enable LFR while
4392 * SETROAMMODE 1 is to disable LFR, but
4393 * NotifyIsFastRoamIniFeatureEnabled 0/1 is to enable/disable.
4394 * So, we have to invert the value to call sme_UpdateIsFastRoamIniFeatureEnabled.
4395 */
4396 if (CFG_LFR_FEATURE_ENABLED_MIN == roamMode)
4397 roamMode = CFG_LFR_FEATURE_ENABLED_MAX; /* Roam enable */
4398 else
4399 roamMode = CFG_LFR_FEATURE_ENABLED_MIN; /* Roam disable */
4400
4401 pHddCtx->cfg_ini->isFastRoamIniFeatureEnabled = roamMode;
4402 sme_UpdateIsFastRoamIniFeatureEnabled((tHalHandle)(pHddCtx->hHal), roamMode);
4403 }
4404 /* GETROAMMODE */
Mahesh A Saptasagarec7d1092015-04-02 13:41:34 +05304405 else if (strncmp(command, "GETROAMMODE", SIZE_OF_GETROAMMODE) == 0)
Varun Reddy Yeturu6d99ac82013-05-08 14:15:35 -07004406 {
4407 tANI_BOOLEAN roamMode = sme_getIsLfrFeatureEnabled((tHalHandle)(pHddCtx->hHal));
4408 char extra[32];
4409 tANI_U8 len = 0;
4410
4411 /*
4412 * roamMode value shall be inverted because the sementics is different.
4413 */
4414 if (CFG_LFR_FEATURE_ENABLED_MIN == roamMode)
4415 roamMode = CFG_LFR_FEATURE_ENABLED_MAX;
4416 else
4417 roamMode = CFG_LFR_FEATURE_ENABLED_MIN;
4418
Sameer Thalappilb0a30232013-09-27 15:37:48 -07004419 len = scnprintf(extra, sizeof(extra), "%s %d", command, roamMode);
Ratnam Rachuri28693eb2015-07-17 13:23:42 +05304420 len = VOS_MIN(priv_data.total_len, len + 1);
4421 if (copy_to_user(priv_data.buf, &extra, len)) {
Varun Reddy Yeturu6d99ac82013-05-08 14:15:35 -07004422 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4423 "%s: failed to copy data to user buffer", __func__);
4424 ret = -EFAULT;
4425 goto exit;
4426 }
4427 }
4428#endif
Srinivas Girigowdade697412013-02-14 16:31:48 -08004429#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004430#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowdade697412013-02-14 16:31:48 -08004431 else if (strncmp(command, "SETROAMDELTA", 12) == 0)
4432 {
4433 tANI_U8 *value = command;
4434 tANI_U8 roamRssiDiff = CFG_ROAM_RSSI_DIFF_DEFAULT;
4435
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05304436 ret = hdd_drv_cmd_validate(command, 12);
4437 if (ret)
4438 goto exit;
4439
Srinivas Girigowdade697412013-02-14 16:31:48 -08004440 /* Move pointer to ahead of SETROAMDELTA<delimiter> */
4441 value = value + 13;
4442 /* Convert the value from ascii to integer */
4443 ret = kstrtou8(value, 10, &roamRssiDiff);
4444 if (ret < 0)
4445 {
4446 /* If the input value is greater than max value of datatype, then also
4447 kstrtou8 fails */
4448 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4449 "%s: kstrtou8 failed range [%d - %d]", __func__,
4450 CFG_ROAM_RSSI_DIFF_MIN,
4451 CFG_ROAM_RSSI_DIFF_MAX);
4452 ret = -EINVAL;
4453 goto exit;
4454 }
4455
4456 if ((roamRssiDiff < CFG_ROAM_RSSI_DIFF_MIN) ||
4457 (roamRssiDiff > CFG_ROAM_RSSI_DIFF_MAX))
4458 {
4459 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4460 "Roam rssi diff value %d is out of range"
4461 " (Min: %d Max: %d)", roamRssiDiff,
4462 CFG_ROAM_RSSI_DIFF_MIN,
4463 CFG_ROAM_RSSI_DIFF_MAX);
4464 ret = -EINVAL;
4465 goto exit;
4466 }
4467
4468 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4469 "%s: Received Command to Set roam rssi diff = %d", __func__, roamRssiDiff);
4470
4471 pHddCtx->cfg_ini->RoamRssiDiff = roamRssiDiff;
4472 sme_UpdateRoamRssiDiff((tHalHandle)(pHddCtx->hHal), roamRssiDiff);
4473 }
Mahesh A Saptasagarec7d1092015-04-02 13:41:34 +05304474 else if (strncmp(command, "GETROAMDELTA", 12) == 0)
Srinivas Girigowdade697412013-02-14 16:31:48 -08004475 {
4476 tANI_U8 roamRssiDiff = sme_getRoamRssiDiff((tHalHandle)(pHddCtx->hHal));
4477 char extra[32];
4478 tANI_U8 len = 0;
4479
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05304480 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
4481 TRACE_CODE_HDD_GETROAMDELTA_IOCTL,
4482 pAdapter->sessionId, roamRssiDiff));
Sameer Thalappilb0a30232013-09-27 15:37:48 -07004483 len = scnprintf(extra, sizeof(extra), "%s %d",
4484 command, roamRssiDiff);
Ratnam Rachuri22a3b402015-07-17 13:21:49 +05304485 len = VOS_MIN(priv_data.total_len, len + 1);
4486 if (copy_to_user(priv_data.buf, &extra, len)) {
Srinivas Girigowdade697412013-02-14 16:31:48 -08004487 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4488 "%s: failed to copy data to user buffer", __func__);
4489 ret = -EFAULT;
4490 goto exit;
4491 }
4492 }
4493#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004494#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowdade697412013-02-14 16:31:48 -08004495 else if (strncmp(command, "GETBAND", 7) == 0)
4496 {
4497 int band = -1;
4498 char extra[32];
4499 tANI_U8 len = 0;
4500 hdd_getBand_helper(pHddCtx, &band);
4501
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05304502 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
4503 TRACE_CODE_HDD_GETBAND_IOCTL,
4504 pAdapter->sessionId, band));
Sameer Thalappilb0a30232013-09-27 15:37:48 -07004505 len = scnprintf(extra, sizeof(extra), "%s %d", command, band);
Ratnam Rachuri52139592015-07-17 13:17:29 +05304506 len = VOS_MIN(priv_data.total_len, len + 1);
4507 if (copy_to_user(priv_data.buf, &extra, len)) {
Srinivas Girigowdade697412013-02-14 16:31:48 -08004508 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4509 "%s: failed to copy data to user buffer", __func__);
4510 ret = -EFAULT;
4511 goto exit;
4512 }
4513 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08004514 else if (strncmp(command, "SETROAMSCANCHANNELS", 19) == 0)
4515 {
4516 tANI_U8 *value = command;
4517 tANI_U8 ChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
4518 tANI_U8 numChannels = 0;
4519 eHalStatus status = eHAL_STATUS_SUCCESS;
4520
4521 status = hdd_parse_channellist(value, ChannelList, &numChannels);
4522 if (eHAL_STATUS_SUCCESS != status)
4523 {
4524 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4525 "%s: Failed to parse channel list information", __func__);
4526 ret = -EINVAL;
4527 goto exit;
4528 }
4529
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05304530 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
4531 TRACE_CODE_HDD_SETROAMSCANCHANNELS_IOCTL,
4532 pAdapter->sessionId, numChannels));
Srinivas Girigowdade697412013-02-14 16:31:48 -08004533 if (numChannels > WNI_CFG_VALID_CHANNEL_LIST_LEN)
4534 {
4535 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4536 "%s: number of channels (%d) supported exceeded max (%d)", __func__,
4537 numChannels, WNI_CFG_VALID_CHANNEL_LIST_LEN);
4538 ret = -EINVAL;
4539 goto exit;
4540 }
4541 status = sme_ChangeRoamScanChannelList((tHalHandle)(pHddCtx->hHal), ChannelList,
4542 numChannels);
4543 if (eHAL_STATUS_SUCCESS != status)
4544 {
4545 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4546 "%s: Failed to update channel list information", __func__);
4547 ret = -EINVAL;
4548 goto exit;
4549 }
4550 }
4551 else if (strncmp(command, "GETROAMSCANCHANNELS", 19) == 0)
4552 {
4553 tANI_U8 ChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
4554 tANI_U8 numChannels = 0;
Jeff Johnson51b67782013-04-05 12:35:41 -07004555 tANI_U8 j = 0;
Srinivas Girigowdade697412013-02-14 16:31:48 -08004556 char extra[128] = {0};
Jeff Johnson51b67782013-04-05 12:35:41 -07004557 int len;
Srinivas Girigowdade697412013-02-14 16:31:48 -08004558
4559 if (eHAL_STATUS_SUCCESS != sme_getRoamScanChannelList( (tHalHandle)(pHddCtx->hHal),
4560 ChannelList, &numChannels ))
4561 {
4562 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
4563 "%s: failed to get roam scan channel list", __func__);
4564 ret = -EFAULT;
4565 goto exit;
4566 }
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05304567 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
4568 TRACE_CODE_HDD_GETROAMSCANCHANNELS_IOCTL,
4569 pAdapter->sessionId, numChannels));
Srinivas Girigowdade697412013-02-14 16:31:48 -08004570 /* output channel list is of the format
4571 [Number of roam scan channels][Channel1][Channel2]... */
4572 /* copy the number of channels in the 0th index */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07004573 len = scnprintf(extra, sizeof(extra), "%s %d", command, numChannels);
Sushant Kaushika08ca192015-09-16 15:52:04 +05304574 for (j = 0; (j < numChannels) && len <= sizeof(extra); j++)
Srinivas Girigowdade697412013-02-14 16:31:48 -08004575 {
Sameer Thalappilb0a30232013-09-27 15:37:48 -07004576 len += scnprintf(extra + len, sizeof(extra) - len, " %d",
4577 ChannelList[j]);
Srinivas Girigowdade697412013-02-14 16:31:48 -08004578 }
4579
Sushant Kaushikc9b8be52015-07-15 16:41:27 +05304580 len = VOS_MIN(priv_data.total_len, len + 1);
4581 if (copy_to_user(priv_data.buf, &extra, len))
Srinivas Girigowdade697412013-02-14 16:31:48 -08004582 {
4583 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4584 "%s: failed to copy data to user buffer", __func__);
4585 ret = -EFAULT;
4586 goto exit;
4587 }
4588 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004589 else if (strncmp(command, "GETCCXMODE", 10) == 0)
4590 {
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004591 tANI_BOOLEAN eseMode = sme_getIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal));
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004592 char extra[32];
4593 tANI_U8 len = 0;
4594
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004595 /* Check if the features OKC/ESE/11R are supported simultaneously,
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07004596 then this operation is not permitted (return FAILURE) */
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004597 if (eseMode &&
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07004598 hdd_is_okc_mode_enabled(pHddCtx) &&
4599 sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal)))
4600 {
4601 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004602 "%s: OKC/ESE/11R are supported simultaneously"
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07004603 " hence this operation is not permitted!", __func__);
4604 ret = -EPERM;
4605 goto exit;
4606 }
4607
Sameer Thalappilb0a30232013-09-27 15:37:48 -07004608 len = scnprintf(extra, sizeof(extra), "%s %d",
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004609 "GETCCXMODE", eseMode);
Sushant Kaushikf8abd352015-07-15 16:37:49 +05304610 len = VOS_MIN(priv_data.total_len, len + 1);
4611 if (copy_to_user(priv_data.buf, &extra, len))
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004612 {
4613 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4614 "%s: failed to copy data to user buffer", __func__);
4615 ret = -EFAULT;
4616 goto exit;
4617 }
4618 }
4619 else if (strncmp(command, "GETOKCMODE", 10) == 0)
4620 {
4621 tANI_BOOLEAN okcMode = hdd_is_okc_mode_enabled(pHddCtx);
4622 char extra[32];
4623 tANI_U8 len = 0;
4624
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004625 /* Check if the features OKC/ESE/11R are supported simultaneously,
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07004626 then this operation is not permitted (return FAILURE) */
4627 if (okcMode &&
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004628 sme_getIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal)) &&
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07004629 sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal)))
4630 {
4631 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004632 "%s: OKC/ESE/11R are supported simultaneously"
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07004633 " hence this operation is not permitted!", __func__);
4634 ret = -EPERM;
4635 goto exit;
4636 }
4637
Sameer Thalappilb0a30232013-09-27 15:37:48 -07004638 len = scnprintf(extra, sizeof(extra), "%s %d",
4639 "GETOKCMODE", okcMode);
Sushant Kaushikbc2fb5c2015-07-15 16:43:16 +05304640 len = VOS_MIN(priv_data.total_len, len + 1);
4641 if (copy_to_user(priv_data.buf, &extra, len))
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004642 {
4643 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4644 "%s: failed to copy data to user buffer", __func__);
4645 ret = -EFAULT;
4646 goto exit;
4647 }
4648 }
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07004649 else if (strncmp(command, "GETFASTROAM", 11) == 0)
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004650 {
4651 tANI_BOOLEAN lfrMode = sme_getIsLfrFeatureEnabled((tHalHandle)(pHddCtx->hHal));
4652 char extra[32];
4653 tANI_U8 len = 0;
4654
Sameer Thalappilb0a30232013-09-27 15:37:48 -07004655 len = scnprintf(extra, sizeof(extra), "%s %d",
4656 "GETFASTROAM", lfrMode);
Sushant Kaushik4da7ec92015-07-15 16:39:32 +05304657 len = VOS_MIN(priv_data.total_len, len + 1);
4658 if (copy_to_user(priv_data.buf, &extra, len))
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004659 {
4660 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4661 "%s: failed to copy data to user buffer", __func__);
4662 ret = -EFAULT;
4663 goto exit;
4664 }
4665 }
4666 else if (strncmp(command, "GETFASTTRANSITION", 17) == 0)
4667 {
4668 tANI_BOOLEAN ft = sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal));
4669 char extra[32];
4670 tANI_U8 len = 0;
4671
Sameer Thalappilb0a30232013-09-27 15:37:48 -07004672 len = scnprintf(extra, sizeof(extra), "%s %d",
4673 "GETFASTTRANSITION", ft);
Sushant Kaushik231a4452015-07-15 16:23:56 +05304674 len = VOS_MIN(priv_data.total_len, len + 1);
4675 if (copy_to_user(priv_data.buf, &extra, len))
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004676 {
4677 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4678 "%s: failed to copy data to user buffer", __func__);
4679 ret = -EFAULT;
4680 goto exit;
4681 }
4682 }
4683 else if (strncmp(command, "SETROAMSCANCHANNELMINTIME", 25) == 0)
4684 {
4685 tANI_U8 *value = command;
4686 tANI_U8 minTime = CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_DEFAULT;
4687
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05304688 ret = hdd_drv_cmd_validate(command, 25);
4689 if (ret)
4690 goto exit;
4691
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004692 /* Move pointer to ahead of SETROAMSCANCHANNELMINTIME<delimiter> */
4693 value = value + 26;
4694 /* Convert the value from ascii to integer */
4695 ret = kstrtou8(value, 10, &minTime);
4696 if (ret < 0)
4697 {
4698 /* If the input value is greater than max value of datatype, then also
4699 kstrtou8 fails */
4700 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4701 "%s: kstrtou8 failed range [%d - %d]", __func__,
4702 CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MIN,
4703 CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MAX);
4704 ret = -EINVAL;
4705 goto exit;
4706 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004707 if ((minTime < CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MIN) ||
4708 (minTime > CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MAX))
4709 {
4710 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4711 "scan min channel time value %d is out of range"
4712 " (Min: %d Max: %d)", minTime,
4713 CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MIN,
4714 CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MAX);
4715 ret = -EINVAL;
4716 goto exit;
4717 }
4718
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05304719 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
4720 TRACE_CODE_HDD_SETROAMSCANCHANNELMINTIME_IOCTL,
4721 pAdapter->sessionId, minTime));
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004722 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4723 "%s: Received Command to change channel min time = %d", __func__, minTime);
4724
4725 pHddCtx->cfg_ini->nNeighborScanMinChanTime = minTime;
4726 sme_setNeighborScanMinChanTime((tHalHandle)(pHddCtx->hHal), minTime);
4727 }
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004728 else if (strncmp(command, "SENDACTIONFRAME", 15) == 0)
4729 {
4730 tANI_U8 *value = command;
4731 tANI_U8 channel = 0;
4732 tANI_U8 dwellTime = 0;
4733 tANI_U8 bufLen = 0;
4734 tANI_U8 *buf = NULL;
4735 tSirMacAddr targetApBssid;
4736 eHalStatus status = eHAL_STATUS_SUCCESS;
4737 struct ieee80211_channel chan;
4738 tANI_U8 finalLen = 0;
4739 tANI_U8 *finalBuf = NULL;
4740 tANI_U8 temp = 0;
4741 u64 cookie;
4742 hdd_station_ctx_t *pHddStaCtx = NULL;
4743 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4744
4745 /* if not associated, no need to send action frame */
4746 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
4747 {
4748 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s:Not associated!",__func__);
4749 ret = -EINVAL;
4750 goto exit;
4751 }
4752
4753 status = hdd_parse_send_action_frame_data(value, targetApBssid, &channel,
4754 &dwellTime, &buf, &bufLen);
4755 if (eHAL_STATUS_SUCCESS != status)
4756 {
4757 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4758 "%s: Failed to parse send action frame data", __func__);
4759 ret = -EINVAL;
4760 goto exit;
4761 }
4762
4763 /* if the target bssid is different from currently associated AP,
4764 then no need to send action frame */
4765 if (VOS_TRUE != vos_mem_compare(targetApBssid,
4766 pHddStaCtx->conn_info.bssId, sizeof(tSirMacAddr)))
4767 {
4768 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s:STA is not associated to this AP!",__func__);
4769 ret = -EINVAL;
Jeff Johnson11c33152013-04-16 17:52:40 -07004770 vos_mem_free(buf);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08004771 buf = NULL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004772 goto exit;
4773 }
4774
4775 /* if the channel number is different from operating channel then
4776 no need to send action frame */
4777 if (channel != pHddStaCtx->conn_info.operationChannel)
4778 {
4779 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4780 "%s: channel(%d) is different from operating channel(%d)",
4781 __func__, channel, pHddStaCtx->conn_info.operationChannel);
4782 ret = -EINVAL;
Jeff Johnson11c33152013-04-16 17:52:40 -07004783 vos_mem_free(buf);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08004784 buf = NULL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004785 goto exit;
4786 }
4787 chan.center_freq = sme_ChnToFreq(channel);
4788
4789 finalLen = bufLen + 24;
4790 finalBuf = vos_mem_malloc(finalLen);
4791 if (NULL == finalBuf)
4792 {
4793 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "%s:memory allocation failed",__func__);
4794 ret = -ENOMEM;
Jeff Johnson11c33152013-04-16 17:52:40 -07004795 vos_mem_free(buf);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08004796 buf = NULL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004797 goto exit;
4798 }
4799 vos_mem_zero(finalBuf, finalLen);
4800
4801 /* Fill subtype */
4802 temp = SIR_MAC_MGMT_ACTION << 4;
4803 vos_mem_copy(finalBuf + 0, &temp, sizeof(temp));
4804
4805 /* Fill type */
4806 temp = SIR_MAC_MGMT_FRAME;
4807 vos_mem_copy(finalBuf + 2, &temp, sizeof(temp));
4808
4809 /* Fill destination address (bssid of the AP) */
4810 vos_mem_copy(finalBuf + 4, targetApBssid, sizeof(targetApBssid));
4811
Srinivas Girigowdab27c0192013-06-03 10:19:56 -07004812 /* Fill source address (STA mac address) */
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004813 vos_mem_copy(finalBuf + 10, pAdapter->macAddressCurrent.bytes, sizeof(pAdapter->macAddressCurrent.bytes));
4814
Srinivas Girigowdab27c0192013-06-03 10:19:56 -07004815 /* Fill BSSID (AP mac address) */
4816 vos_mem_copy(finalBuf + 16, targetApBssid, sizeof(targetApBssid));
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004817
4818 /* Fill received buffer from 24th address */
4819 vos_mem_copy(finalBuf + 24, buf, bufLen);
4820
Jeff Johnson11c33152013-04-16 17:52:40 -07004821 /* done with the parsed buffer */
4822 vos_mem_free(buf);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08004823 buf = NULL;
Jeff Johnson11c33152013-04-16 17:52:40 -07004824
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05304825#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
4826 params.chan = &chan;
4827 params.offchan = 0;
4828 params.wait = dwellTime;
4829 params.buf = finalBuf;
4830 params.len = finalLen;
4831 params.no_cck = 1;
4832 params.dont_wait_for_ack = 1;
4833 ret = wlan_hdd_mgmt_tx(NULL, &pAdapter->wdev, &params, &cookie);
4834#else
DARAM SUDHA39eede62014-02-12 11:16:40 +05304835 wlan_hdd_mgmt_tx( NULL,
Yue Maf49ba872013-08-19 12:04:25 -07004836#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
4837 &(pAdapter->wdev),
4838#else
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07004839 pAdapter->dev,
Yue Maf49ba872013-08-19 12:04:25 -07004840#endif
4841 &chan, 0,
4842#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0))
4843 NL80211_CHAN_HT20, 1,
4844#endif
4845 dwellTime, finalBuf, finalLen, 1,
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004846 1, &cookie );
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05304847#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0)*/
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004848 vos_mem_free(finalBuf);
4849 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004850 else if (strncmp(command, "GETROAMSCANCHANNELMINTIME", 25) == 0)
4851 {
4852 tANI_U16 val = sme_getNeighborScanMinChanTime((tHalHandle)(pHddCtx->hHal));
4853 char extra[32];
4854 tANI_U8 len = 0;
4855
4856 /* value is interms of msec */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07004857 len = scnprintf(extra, sizeof(extra), "%s %d",
4858 "GETROAMSCANCHANNELMINTIME", val);
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05304859 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
4860 TRACE_CODE_HDD_GETROAMSCANCHANNELMINTIME_IOCTL,
4861 pAdapter->sessionId, val));
Sushant Kaushikbb8c52c2015-07-15 16:36:23 +05304862 len = VOS_MIN(priv_data.total_len, len + 1);
4863 if (copy_to_user(priv_data.buf, &extra, len))
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004864 {
4865 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4866 "%s: failed to copy data to user buffer", __func__);
4867 ret = -EFAULT;
4868 goto exit;
4869 }
4870 }
4871 else if (strncmp(command, "SETSCANCHANNELTIME", 18) == 0)
4872 {
4873 tANI_U8 *value = command;
Varun Reddy Yeturu3885a662013-06-19 07:10:37 -07004874 tANI_U16 maxTime = CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_DEFAULT;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004875
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05304876 ret = hdd_drv_cmd_validate(command, 18);
4877 if (ret)
4878 goto exit;
4879
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004880 /* Move pointer to ahead of SETSCANCHANNELTIME<delimiter> */
4881 value = value + 19;
4882 /* Convert the value from ascii to integer */
Varun Reddy Yeturu3885a662013-06-19 07:10:37 -07004883 ret = kstrtou16(value, 10, &maxTime);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004884 if (ret < 0)
4885 {
4886 /* If the input value is greater than max value of datatype, then also
Varun Reddy Yeturu3885a662013-06-19 07:10:37 -07004887 kstrtou16 fails */
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004888 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Varun Reddy Yeturu3885a662013-06-19 07:10:37 -07004889 "%s: kstrtou16 failed range [%d - %d]", __func__,
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004890 CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MIN,
4891 CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MAX);
4892 ret = -EINVAL;
4893 goto exit;
4894 }
4895
4896 if ((maxTime < CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MIN) ||
4897 (maxTime > CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MAX))
4898 {
4899 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4900 "lfr mode value %d is out of range"
4901 " (Min: %d Max: %d)", maxTime,
4902 CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MIN,
4903 CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MAX);
4904 ret = -EINVAL;
4905 goto exit;
4906 }
4907
4908 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4909 "%s: Received Command to change channel max time = %d", __func__, maxTime);
4910
4911 pHddCtx->cfg_ini->nNeighborScanMaxChanTime = maxTime;
4912 sme_setNeighborScanMaxChanTime((tHalHandle)(pHddCtx->hHal), maxTime);
4913 }
4914 else if (strncmp(command, "GETSCANCHANNELTIME", 18) == 0)
4915 {
4916 tANI_U16 val = sme_getNeighborScanMaxChanTime((tHalHandle)(pHddCtx->hHal));
4917 char extra[32];
4918 tANI_U8 len = 0;
4919
4920 /* value is interms of msec */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07004921 len = scnprintf(extra, sizeof(extra), "%s %d",
4922 "GETSCANCHANNELTIME", val);
Ratheesh S Pacbfa932015-07-16 15:27:18 +05304923 len = VOS_MIN(priv_data.total_len, len + 1);
4924 if (copy_to_user(priv_data.buf, &extra, len))
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004925 {
4926 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4927 "%s: failed to copy data to user buffer", __func__);
4928 ret = -EFAULT;
4929 goto exit;
4930 }
4931 }
4932 else if (strncmp(command, "SETSCANHOMETIME", 15) == 0)
4933 {
4934 tANI_U8 *value = command;
4935 tANI_U16 val = CFG_NEIGHBOR_SCAN_TIMER_PERIOD_DEFAULT;
4936
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05304937 ret = hdd_drv_cmd_validate(command, 15);
4938 if (ret)
4939 goto exit;
4940
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004941 /* Move pointer to ahead of SETSCANHOMETIME<delimiter> */
4942 value = value + 16;
4943 /* Convert the value from ascii to integer */
4944 ret = kstrtou16(value, 10, &val);
4945 if (ret < 0)
4946 {
4947 /* If the input value is greater than max value of datatype, then also
4948 kstrtou16 fails */
4949 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4950 "%s: kstrtou16 failed range [%d - %d]", __func__,
4951 CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MIN,
4952 CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MAX);
4953 ret = -EINVAL;
4954 goto exit;
4955 }
4956
4957 if ((val < CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MIN) ||
4958 (val > CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MAX))
4959 {
4960 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4961 "scan home time value %d is out of range"
4962 " (Min: %d Max: %d)", val,
4963 CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MIN,
4964 CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MAX);
4965 ret = -EINVAL;
4966 goto exit;
4967 }
4968
4969 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4970 "%s: Received Command to change scan home time = %d", __func__, val);
4971
4972 pHddCtx->cfg_ini->nNeighborScanPeriod = val;
4973 sme_setNeighborScanPeriod((tHalHandle)(pHddCtx->hHal), val);
4974 }
4975 else if (strncmp(command, "GETSCANHOMETIME", 15) == 0)
4976 {
4977 tANI_U16 val = sme_getNeighborScanPeriod((tHalHandle)(pHddCtx->hHal));
4978 char extra[32];
4979 tANI_U8 len = 0;
4980
4981 /* value is interms of msec */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07004982 len = scnprintf(extra, sizeof(extra), "%s %d",
4983 "GETSCANHOMETIME", val);
Ratheesh S P728d7c62015-07-16 15:38:58 +05304984 len = VOS_MIN(priv_data.total_len, len + 1);
4985 if (copy_to_user(priv_data.buf, &extra, len))
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004986 {
4987 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4988 "%s: failed to copy data to user buffer", __func__);
4989 ret = -EFAULT;
4990 goto exit;
4991 }
4992 }
4993 else if (strncmp(command, "SETROAMINTRABAND", 16) == 0)
4994 {
4995 tANI_U8 *value = command;
4996 tANI_U8 val = CFG_ROAM_INTRA_BAND_DEFAULT;
4997
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05304998 ret = hdd_drv_cmd_validate(command, 16);
4999 if (ret)
5000 goto exit;
5001
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07005002 /* Move pointer to ahead of SETROAMINTRABAND<delimiter> */
5003 value = value + 17;
5004 /* Convert the value from ascii to integer */
5005 ret = kstrtou8(value, 10, &val);
5006 if (ret < 0)
5007 {
5008 /* If the input value is greater than max value of datatype, then also
5009 kstrtou8 fails */
5010 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5011 "%s: kstrtou8 failed range [%d - %d]", __func__,
5012 CFG_ROAM_INTRA_BAND_MIN,
5013 CFG_ROAM_INTRA_BAND_MAX);
5014 ret = -EINVAL;
5015 goto exit;
5016 }
5017
5018 if ((val < CFG_ROAM_INTRA_BAND_MIN) ||
5019 (val > CFG_ROAM_INTRA_BAND_MAX))
5020 {
5021 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5022 "intra band mode value %d is out of range"
5023 " (Min: %d Max: %d)", val,
5024 CFG_ROAM_INTRA_BAND_MIN,
5025 CFG_ROAM_INTRA_BAND_MAX);
5026 ret = -EINVAL;
5027 goto exit;
5028 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07005029 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
5030 "%s: Received Command to change intra band = %d", __func__, val);
5031
5032 pHddCtx->cfg_ini->nRoamIntraBand = val;
5033 sme_setRoamIntraBand((tHalHandle)(pHddCtx->hHal), val);
5034 }
5035 else if (strncmp(command, "GETROAMINTRABAND", 16) == 0)
5036 {
5037 tANI_U16 val = sme_getRoamIntraBand((tHalHandle)(pHddCtx->hHal));
5038 char extra[32];
5039 tANI_U8 len = 0;
5040
5041 /* value is interms of msec */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07005042 len = scnprintf(extra, sizeof(extra), "%s %d",
5043 "GETROAMINTRABAND", val);
Ratheesh S P2dd2a3e2015-07-16 15:34:23 +05305044 len = VOS_MIN(priv_data.total_len, len + 1);
5045 if (copy_to_user(priv_data.buf, &extra, len))
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07005046 {
5047 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5048 "%s: failed to copy data to user buffer", __func__);
5049 ret = -EFAULT;
5050 goto exit;
5051 }
5052 }
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005053 else if (strncmp(command, "SETSCANNPROBES", 14) == 0)
5054 {
5055 tANI_U8 *value = command;
5056 tANI_U8 nProbes = CFG_ROAM_SCAN_N_PROBES_DEFAULT;
5057
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05305058 ret = hdd_drv_cmd_validate(command, 14);
5059 if (ret)
5060 goto exit;
5061
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005062 /* Move pointer to ahead of SETSCANNPROBES<delimiter> */
5063 value = value + 15;
5064 /* Convert the value from ascii to integer */
5065 ret = kstrtou8(value, 10, &nProbes);
5066 if (ret < 0)
5067 {
5068 /* If the input value is greater than max value of datatype, then also
5069 kstrtou8 fails */
5070 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5071 "%s: kstrtou8 failed range [%d - %d]", __func__,
5072 CFG_ROAM_SCAN_N_PROBES_MIN,
5073 CFG_ROAM_SCAN_N_PROBES_MAX);
5074 ret = -EINVAL;
5075 goto exit;
5076 }
5077
5078 if ((nProbes < CFG_ROAM_SCAN_N_PROBES_MIN) ||
5079 (nProbes > CFG_ROAM_SCAN_N_PROBES_MAX))
5080 {
5081 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5082 "NProbes value %d is out of range"
5083 " (Min: %d Max: %d)", nProbes,
5084 CFG_ROAM_SCAN_N_PROBES_MIN,
5085 CFG_ROAM_SCAN_N_PROBES_MAX);
5086 ret = -EINVAL;
5087 goto exit;
5088 }
5089
5090 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
5091 "%s: Received Command to Set nProbes = %d", __func__, nProbes);
5092
5093 pHddCtx->cfg_ini->nProbes = nProbes;
5094 sme_UpdateRoamScanNProbes((tHalHandle)(pHddCtx->hHal), nProbes);
5095 }
Mahesh A Saptasagarec7d1092015-04-02 13:41:34 +05305096 else if (strncmp(command, "GETSCANNPROBES", 14) == 0)
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005097 {
5098 tANI_U8 val = sme_getRoamScanNProbes((tHalHandle)(pHddCtx->hHal));
5099 char extra[32];
5100 tANI_U8 len = 0;
5101
Sameer Thalappilb0a30232013-09-27 15:37:48 -07005102 len = scnprintf(extra, sizeof(extra), "%s %d", command, val);
Ratnam Rachuri6da525d2015-08-07 13:55:54 +05305103 len = VOS_MIN(priv_data.total_len, len + 1);
5104 if (copy_to_user(priv_data.buf, &extra, len)) {
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005105 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5106 "%s: failed to copy data to user buffer", __func__);
5107 ret = -EFAULT;
5108 goto exit;
5109 }
5110 }
5111 else if (strncmp(command, "SETSCANHOMEAWAYTIME", 19) == 0)
5112 {
5113 tANI_U8 *value = command;
5114 tANI_U16 homeAwayTime = CFG_ROAM_SCAN_HOME_AWAY_TIME_DEFAULT;
5115
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05305116 ret = hdd_drv_cmd_validate(command, 19);
5117 if (ret)
5118 goto exit;
5119
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005120 /* Move pointer to ahead of SETSCANHOMEAWAYTIME<delimiter> */
5121 /* input value is in units of msec */
5122 value = value + 20;
5123 /* Convert the value from ascii to integer */
5124 ret = kstrtou16(value, 10, &homeAwayTime);
5125 if (ret < 0)
5126 {
5127 /* If the input value is greater than max value of datatype, then also
5128 kstrtou8 fails */
5129 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5130 "%s: kstrtou8 failed range [%d - %d]", __func__,
5131 CFG_ROAM_SCAN_HOME_AWAY_TIME_MIN,
5132 CFG_ROAM_SCAN_HOME_AWAY_TIME_MAX);
5133 ret = -EINVAL;
5134 goto exit;
5135 }
5136
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005137 if ((homeAwayTime < CFG_ROAM_SCAN_HOME_AWAY_TIME_MIN) ||
5138 (homeAwayTime > CFG_ROAM_SCAN_HOME_AWAY_TIME_MAX))
5139 {
5140 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5141 "homeAwayTime value %d is out of range"
5142 " (Min: %d Max: %d)", homeAwayTime,
5143 CFG_ROAM_SCAN_HOME_AWAY_TIME_MIN,
5144 CFG_ROAM_SCAN_HOME_AWAY_TIME_MAX);
5145 ret = -EINVAL;
5146 goto exit;
5147 }
5148
5149 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
5150 "%s: Received Command to Set scan away time = %d", __func__, homeAwayTime);
Srinivas Girigowda6cf0b822013-06-27 14:00:20 -07005151 if (pHddCtx->cfg_ini->nRoamScanHomeAwayTime != homeAwayTime)
5152 {
5153 pHddCtx->cfg_ini->nRoamScanHomeAwayTime = homeAwayTime;
5154 sme_UpdateRoamScanHomeAwayTime((tHalHandle)(pHddCtx->hHal), homeAwayTime, eANI_BOOLEAN_TRUE);
5155 }
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005156 }
Mahesh A Saptasagarec7d1092015-04-02 13:41:34 +05305157 else if (strncmp(command, "GETSCANHOMEAWAYTIME", 19) == 0)
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005158 {
5159 tANI_U16 val = sme_getRoamScanHomeAwayTime((tHalHandle)(pHddCtx->hHal));
5160 char extra[32];
5161 tANI_U8 len = 0;
5162
Sameer Thalappilb0a30232013-09-27 15:37:48 -07005163 len = scnprintf(extra, sizeof(extra), "%s %d", command, val);
Ratnam Rachuri51a5ad12015-08-07 14:06:37 +05305164 len = VOS_MIN(priv_data.total_len, len + 1);
5165 if (copy_to_user(priv_data.buf, &extra, len)) {
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005166 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5167 "%s: failed to copy data to user buffer", __func__);
5168 ret = -EFAULT;
5169 goto exit;
5170 }
5171 }
5172 else if (strncmp(command, "REASSOC", 7) == 0)
5173 {
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05305174 ret = hdd_drv_cmd_validate(command, 7);
5175 if (ret)
5176 goto exit;
5177
5178 ret = hdd_parse_reassoc(pAdapter, command, priv_data.total_len);
Selvaraj, Sridhar5aff1ed2016-06-18 01:26:23 +05305179 if (!ret)
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005180 goto exit;
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005181 }
Srinivas Girigowdaad34ca92013-10-22 10:54:29 -07005182 else if (strncmp(command, "SETWESMODE", 10) == 0)
5183 {
5184 tANI_U8 *value = command;
5185 tANI_BOOLEAN wesMode = CFG_ENABLE_WES_MODE_NAME_DEFAULT;
5186
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05305187 ret = hdd_drv_cmd_validate(command, 10);
5188 if (ret)
5189 goto exit;
5190
Srinivas Girigowdaad34ca92013-10-22 10:54:29 -07005191 /* Move pointer to ahead of SETWESMODE<delimiter> */
5192 value = value + 11;
5193 /* Convert the value from ascii to integer */
5194 ret = kstrtou8(value, 10, &wesMode);
5195 if (ret < 0)
5196 {
5197 /* If the input value is greater than max value of datatype, then also
5198 kstrtou8 fails */
5199 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5200 "%s: kstrtou8 failed range [%d - %d]", __func__,
5201 CFG_ENABLE_WES_MODE_NAME_MIN,
5202 CFG_ENABLE_WES_MODE_NAME_MAX);
5203 ret = -EINVAL;
5204 goto exit;
5205 }
5206
5207 if ((wesMode < CFG_ENABLE_WES_MODE_NAME_MIN) ||
5208 (wesMode > CFG_ENABLE_WES_MODE_NAME_MAX))
5209 {
5210 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5211 "WES Mode value %d is out of range"
5212 " (Min: %d Max: %d)", wesMode,
5213 CFG_ENABLE_WES_MODE_NAME_MIN,
5214 CFG_ENABLE_WES_MODE_NAME_MAX);
5215 ret = -EINVAL;
5216 goto exit;
5217 }
5218 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
5219 "%s: Received Command to Set WES Mode rssi diff = %d", __func__, wesMode);
5220
5221 pHddCtx->cfg_ini->isWESModeEnabled = wesMode;
5222 sme_UpdateWESMode((tHalHandle)(pHddCtx->hHal), wesMode);
5223 }
Mahesh A Saptasagarec7d1092015-04-02 13:41:34 +05305224 else if (strncmp(command, "GETWESMODE", 10) == 0)
Srinivas Girigowdaad34ca92013-10-22 10:54:29 -07005225 {
5226 tANI_BOOLEAN wesMode = sme_GetWESMode((tHalHandle)(pHddCtx->hHal));
5227 char extra[32];
5228 tANI_U8 len = 0;
5229
Arif Hussain826d9412013-11-12 16:44:54 -08005230 len = scnprintf(extra, sizeof(extra), "%s %d", command, wesMode);
Ratnam Rachuri8fe90c62015-08-07 14:03:26 +05305231 len = VOS_MIN(priv_data.total_len, len + 1);
5232 if (copy_to_user(priv_data.buf, &extra, len)) {
Srinivas Girigowdaad34ca92013-10-22 10:54:29 -07005233 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5234 "%s: failed to copy data to user buffer", __func__);
5235 ret = -EFAULT;
5236 goto exit;
5237 }
5238 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005239#endif /* WLAN_FEATURE_VOWIFI_11R || FEATURE_WLAN_ESE || FEATURE_WLAN_LFR */
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07005240#ifdef FEATURE_WLAN_LFR
5241 else if (strncmp(command, "SETFASTROAM", 11) == 0)
5242 {
5243 tANI_U8 *value = command;
5244 tANI_U8 lfrMode = CFG_LFR_FEATURE_ENABLED_DEFAULT;
5245
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +05305246 if (pHddCtx->concurrency_mode == VOS_STA_MON) {
5247 hddLog(LOGE,
5248 FL("Roaming is always disabled in STA + MON concurrency"));
5249 ret = -EINVAL;
5250 goto exit;
5251 }
5252
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05305253 ret = hdd_drv_cmd_validate(command, 11);
5254 if (ret)
5255 goto exit;
5256
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07005257 /* Move pointer to ahead of SETFASTROAM<delimiter> */
5258 value = value + 12;
5259 /* Convert the value from ascii to integer */
5260 ret = kstrtou8(value, 10, &lfrMode);
5261 if (ret < 0)
5262 {
5263 /* If the input value is greater than max value of datatype, then also
5264 kstrtou8 fails */
5265 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5266 "%s: kstrtou8 failed range [%d - %d]", __func__,
5267 CFG_LFR_FEATURE_ENABLED_MIN,
5268 CFG_LFR_FEATURE_ENABLED_MAX);
5269 ret = -EINVAL;
5270 goto exit;
5271 }
5272
5273 if ((lfrMode < CFG_LFR_FEATURE_ENABLED_MIN) ||
5274 (lfrMode > CFG_LFR_FEATURE_ENABLED_MAX))
5275 {
5276 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5277 "lfr mode value %d is out of range"
5278 " (Min: %d Max: %d)", lfrMode,
5279 CFG_LFR_FEATURE_ENABLED_MIN,
5280 CFG_LFR_FEATURE_ENABLED_MAX);
5281 ret = -EINVAL;
5282 goto exit;
5283 }
5284
5285 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
5286 "%s: Received Command to change lfr mode = %d", __func__, lfrMode);
5287
5288 pHddCtx->cfg_ini->isFastRoamIniFeatureEnabled = lfrMode;
5289 sme_UpdateIsFastRoamIniFeatureEnabled((tHalHandle)(pHddCtx->hHal), lfrMode);
5290 }
5291#endif
5292#ifdef WLAN_FEATURE_VOWIFI_11R
5293 else if (strncmp(command, "SETFASTTRANSITION", 17) == 0)
5294 {
5295 tANI_U8 *value = command;
5296 tANI_U8 ft = CFG_FAST_TRANSITION_ENABLED_NAME_DEFAULT;
5297
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05305298 ret = hdd_drv_cmd_validate(command, 17);
5299 if (ret)
5300 goto exit;
5301
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07005302 /* Move pointer to ahead of SETFASTROAM<delimiter> */
5303 value = value + 18;
5304 /* Convert the value from ascii to integer */
5305 ret = kstrtou8(value, 10, &ft);
5306 if (ret < 0)
5307 {
5308 /* If the input value is greater than max value of datatype, then also
5309 kstrtou8 fails */
5310 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5311 "%s: kstrtou8 failed range [%d - %d]", __func__,
5312 CFG_FAST_TRANSITION_ENABLED_NAME_MIN,
5313 CFG_FAST_TRANSITION_ENABLED_NAME_MAX);
5314 ret = -EINVAL;
5315 goto exit;
5316 }
5317
5318 if ((ft < CFG_FAST_TRANSITION_ENABLED_NAME_MIN) ||
5319 (ft > CFG_FAST_TRANSITION_ENABLED_NAME_MAX))
5320 {
5321 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5322 "ft mode value %d is out of range"
5323 " (Min: %d Max: %d)", ft,
5324 CFG_FAST_TRANSITION_ENABLED_NAME_MIN,
5325 CFG_FAST_TRANSITION_ENABLED_NAME_MAX);
5326 ret = -EINVAL;
5327 goto exit;
5328 }
5329
5330 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
5331 "%s: Received Command to change ft mode = %d", __func__, ft);
5332
5333 pHddCtx->cfg_ini->isFastTransitionEnabled = ft;
5334 sme_UpdateFastTransitionEnabled((tHalHandle)(pHddCtx->hHal), ft);
5335 }
Padma, Santhosh Kumar778d8382015-03-04 17:41:22 +05305336 else if (strncmp(command, "SETDFSSCANMODE", 14) == 0)
5337 {
5338 tANI_U8 *value = command;
5339 tANI_U8 dfsScanMode = DFS_CHNL_SCAN_ENABLED_NORMAL;
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05305340
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05305341 ret = hdd_drv_cmd_validate(command, 14);
5342 if (ret)
5343 goto exit;
5344
Padma, Santhosh Kumar778d8382015-03-04 17:41:22 +05305345 /* Move pointer to ahead of SETDFSSCANMODE<delimiter> */
5346 value = value + 15;
5347 /* Convert the value from ascii to integer */
5348 ret = kstrtou8(value, 10, &dfsScanMode);
5349 if (ret < 0)
5350 {
5351 /* If the input value is greater than max value of
5352 datatype, then also kstrtou8 fails
5353 */
5354 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5355 "%s: kstrtou8 failed range [%d - %d]", __func__,
5356 CFG_ENABLE_DFS_CHNL_SCAN_MIN,
5357 CFG_ENABLE_DFS_CHNL_SCAN_MAX);
5358 ret = -EINVAL;
5359 goto exit;
5360 }
5361
5362 if ((dfsScanMode < CFG_ENABLE_DFS_CHNL_SCAN_MIN) ||
5363 (dfsScanMode > CFG_ENABLE_DFS_CHNL_SCAN_MAX))
5364 {
5365 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5366 "dfsScanMode value %d is out of range"
5367 " (Min: %d Max: %d)", dfsScanMode,
5368 CFG_ENABLE_DFS_CHNL_SCAN_MIN,
5369 CFG_ENABLE_DFS_CHNL_SCAN_MAX);
5370 ret = -EINVAL;
5371 goto exit;
5372 }
5373 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
5374 "%s: Received Command to Set DFS Scan Mode = %d",
5375 __func__, dfsScanMode);
5376
5377 ret = wlan_hdd_handle_dfs_chan_scan(pHddCtx, dfsScanMode);
5378 }
5379 else if (strncmp(command, "GETDFSSCANMODE", 14) == 0)
5380 {
5381 tANI_U8 dfsScanMode = sme_GetDFSScanMode(pHddCtx->hHal);
5382 char extra[32];
5383 tANI_U8 len = 0;
5384
5385 len = scnprintf(extra, sizeof(extra), "%s %d", command, dfsScanMode);
Ratheesh S P767224e2015-07-16 15:35:51 +05305386 len = VOS_MIN(priv_data.total_len, len + 1);
5387 if (copy_to_user(priv_data.buf, &extra, len))
Padma, Santhosh Kumar778d8382015-03-04 17:41:22 +05305388 {
5389 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5390 "%s: failed to copy data to user buffer", __func__);
5391 ret = -EFAULT;
5392 goto exit;
5393 }
5394 }
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05305395 else if (strncmp(command, "FASTREASSOC", 11) == 0)
5396 {
Selvaraj, Sridhar3714c4d2016-06-22 15:19:12 +05305397 ret = wlan_hdd_handle_fastreassoc(pAdapter, command);
5398 if (!ret)
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05305399 goto exit;
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05305400 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07005401#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005402#ifdef FEATURE_WLAN_ESE
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07005403 else if (strncmp(command, "SETCCXMODE", 10) == 0)
5404 {
5405 tANI_U8 *value = command;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005406 tANI_U8 eseMode = CFG_ESE_FEATURE_ENABLED_DEFAULT;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07005407
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05305408 ret = hdd_drv_cmd_validate(command, 10);
5409 if (ret)
5410 goto exit;
5411
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005412 /* Check if the features OKC/ESE/11R are supported simultaneously,
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07005413 then this operation is not permitted (return FAILURE) */
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005414 if (sme_getIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal)) &&
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07005415 hdd_is_okc_mode_enabled(pHddCtx) &&
5416 sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal)))
5417 {
5418 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005419 "%s: OKC/ESE/11R are supported simultaneously"
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07005420 " hence this operation is not permitted!", __func__);
5421 ret = -EPERM;
5422 goto exit;
5423 }
5424
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07005425 /* Move pointer to ahead of SETCCXMODE<delimiter> */
5426 value = value + 11;
5427 /* Convert the value from ascii to integer */
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005428 ret = kstrtou8(value, 10, &eseMode);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07005429 if (ret < 0)
5430 {
5431 /* If the input value is greater than max value of datatype, then also
5432 kstrtou8 fails */
5433 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5434 "%s: kstrtou8 failed range [%d - %d]", __func__,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005435 CFG_ESE_FEATURE_ENABLED_MIN,
5436 CFG_ESE_FEATURE_ENABLED_MAX);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07005437 ret = -EINVAL;
5438 goto exit;
5439 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005440 if ((eseMode < CFG_ESE_FEATURE_ENABLED_MIN) ||
5441 (eseMode > CFG_ESE_FEATURE_ENABLED_MAX))
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07005442 {
5443 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005444 "Ese mode value %d is out of range"
5445 " (Min: %d Max: %d)", eseMode,
5446 CFG_ESE_FEATURE_ENABLED_MIN,
5447 CFG_ESE_FEATURE_ENABLED_MAX);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07005448 ret = -EINVAL;
5449 goto exit;
5450 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07005451 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005452 "%s: Received Command to change ese mode = %d", __func__, eseMode);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07005453
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005454 pHddCtx->cfg_ini->isEseIniFeatureEnabled = eseMode;
5455 sme_UpdateIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal), eseMode);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07005456 }
5457#endif
Srinivas Girigowda100eb322013-03-15 16:48:20 -07005458 else if (strncmp(command, "SETROAMSCANCONTROL", 18) == 0)
5459 {
5460 tANI_U8 *value = command;
5461 tANI_BOOLEAN roamScanControl = 0;
5462
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05305463 ret = hdd_drv_cmd_validate(command, 18);
5464 if (ret)
5465 goto exit;
5466
Srinivas Girigowda100eb322013-03-15 16:48:20 -07005467 /* Move pointer to ahead of SETROAMSCANCONTROL<delimiter> */
5468 value = value + 19;
5469 /* Convert the value from ascii to integer */
5470 ret = kstrtou8(value, 10, &roamScanControl);
5471 if (ret < 0)
5472 {
5473 /* If the input value is greater than max value of datatype, then also
5474 kstrtou8 fails */
5475 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5476 "%s: kstrtou8 failed ", __func__);
5477 ret = -EINVAL;
5478 goto exit;
5479 }
5480
5481 if (0 != roamScanControl)
5482 {
5483 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5484 "roam scan control invalid value = %d",
5485 roamScanControl);
5486 ret = -EINVAL;
5487 goto exit;
5488 }
5489 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
5490 "%s: Received Command to Set roam scan control = %d", __func__, roamScanControl);
5491
5492 sme_SetRoamScanControl((tHalHandle)(pHddCtx->hHal), roamScanControl);
5493 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07005494#ifdef FEATURE_WLAN_OKC
5495 else if (strncmp(command, "SETOKCMODE", 10) == 0)
5496 {
5497 tANI_U8 *value = command;
5498 tANI_U8 okcMode = CFG_OKC_FEATURE_ENABLED_DEFAULT;
5499
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05305500 ret = hdd_drv_cmd_validate(command, 10);
5501 if (ret)
5502 goto exit;
5503
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005504 /* Check if the features OKC/ESE/11R are supported simultaneously,
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07005505 then this operation is not permitted (return FAILURE) */
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005506 if (sme_getIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal)) &&
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07005507 hdd_is_okc_mode_enabled(pHddCtx) &&
5508 sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal)))
5509 {
5510 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005511 "%s: OKC/ESE/11R are supported simultaneously"
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07005512 " hence this operation is not permitted!", __func__);
5513 ret = -EPERM;
5514 goto exit;
5515 }
5516
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07005517 /* Move pointer to ahead of SETOKCMODE<delimiter> */
5518 value = value + 11;
5519 /* Convert the value from ascii to integer */
5520 ret = kstrtou8(value, 10, &okcMode);
5521 if (ret < 0)
5522 {
5523 /* If the input value is greater than max value of datatype, then also
5524 kstrtou8 fails */
5525 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5526 "%s: kstrtou8 failed range [%d - %d]", __func__,
5527 CFG_OKC_FEATURE_ENABLED_MIN,
5528 CFG_OKC_FEATURE_ENABLED_MAX);
5529 ret = -EINVAL;
5530 goto exit;
5531 }
5532
5533 if ((okcMode < CFG_OKC_FEATURE_ENABLED_MIN) ||
5534 (okcMode > CFG_OKC_FEATURE_ENABLED_MAX))
5535 {
5536 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5537 "Okc mode value %d is out of range"
5538 " (Min: %d Max: %d)", okcMode,
5539 CFG_OKC_FEATURE_ENABLED_MIN,
5540 CFG_OKC_FEATURE_ENABLED_MAX);
5541 ret = -EINVAL;
5542 goto exit;
5543 }
5544
5545 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
5546 "%s: Received Command to change okc mode = %d", __func__, okcMode);
5547
5548 pHddCtx->cfg_ini->isOkcIniFeatureEnabled = okcMode;
5549 }
Srinivas Girigowdaad34ca92013-10-22 10:54:29 -07005550#endif /* FEATURE_WLAN_OKC */
Mahesh A Saptasagarec7d1092015-04-02 13:41:34 +05305551 else if (strncmp(command, "GETROAMSCANCONTROL", 18) == 0)
Srinivas Girigowda100eb322013-03-15 16:48:20 -07005552 {
5553 tANI_BOOLEAN roamScanControl = sme_GetRoamScanControl((tHalHandle)(pHddCtx->hHal));
5554 char extra[32];
5555 tANI_U8 len = 0;
5556
Sameer Thalappilb0a30232013-09-27 15:37:48 -07005557 len = scnprintf(extra, sizeof(extra), "%s %d",
5558 command, roamScanControl);
Ratnam Rachuri083ada82015-08-07 14:01:05 +05305559 len = VOS_MIN(priv_data.total_len, len + 1);
5560 if (copy_to_user(priv_data.buf, &extra, len)) {
Srinivas Girigowda100eb322013-03-15 16:48:20 -07005561 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5562 "%s: failed to copy data to user buffer", __func__);
5563 ret = -EFAULT;
5564 goto exit;
5565 }
5566 }
Gopichand Nakkala227c7f32013-06-26 22:44:57 +05305567#ifdef WLAN_FEATURE_PACKET_FILTERING
5568 else if (strncmp(command, "ENABLE_PKTFILTER_IPV6", 21) == 0)
5569 {
5570 tANI_U8 filterType = 0;
5571 tANI_U8 *value = command;
5572
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05305573 ret = hdd_drv_cmd_validate(command, 21);
5574 if (ret)
5575 goto exit;
5576
Gopichand Nakkala227c7f32013-06-26 22:44:57 +05305577 /* Move pointer to ahead of ENABLE_PKTFILTER_IPV6<delimiter> */
5578 value = value + 22;
5579
5580 /* Convert the value from ascii to integer */
5581 ret = kstrtou8(value, 10, &filterType);
5582 if (ret < 0)
5583 {
5584 /* If the input value is greater than max value of datatype,
5585 * then also kstrtou8 fails
5586 */
5587 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5588 "%s: kstrtou8 failed range ", __func__);
5589 ret = -EINVAL;
5590 goto exit;
5591 }
5592
5593 if (filterType != 0 && filterType != 1)
5594 {
5595 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5596 "%s: Accepted Values are 0 and 1 ", __func__);
5597 ret = -EINVAL;
5598 goto exit;
5599 }
5600 wlan_hdd_setIPv6Filter(WLAN_HDD_GET_CTX(pAdapter), filterType,
5601 pAdapter->sessionId);
5602 }
5603#endif
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05305604 else if (strncmp(command, "BTCOEXMODE", 10) == 0 )
5605 {
Kiet Lamad161252014-07-22 11:23:32 -07005606 char *dhcpPhase;
Satyanarayana Dash1faea4f2014-09-22 16:21:04 +05305607 int ret;
5608
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05305609 ret = hdd_drv_cmd_validate(command, 10);
5610 if (ret)
5611 goto exit;
5612
Kiet Lamad161252014-07-22 11:23:32 -07005613 dhcpPhase = command + 11;
5614 if ('1' == *dhcpPhase)
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05305615 {
Deepthi Gowribfd17132014-11-14 17:59:04 +05305616 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Kiet Lamad161252014-07-22 11:23:32 -07005617 FL("send DHCP START indication"));
c_hpothu9b781ba2013-12-30 20:57:45 +05305618
5619 pHddCtx->btCoexModeSet = TRUE;
Kiet Lamad161252014-07-22 11:23:32 -07005620
Satyanarayana Dash1faea4f2014-09-22 16:21:04 +05305621 ret = wlan_hdd_scan_abort(pAdapter);
5622 if (ret < 0)
5623 {
5624 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5625 FL("failed to abort existing scan %d"), ret);
5626 }
5627
Kiet Lamad161252014-07-22 11:23:32 -07005628 sme_DHCPStartInd(pHddCtx->hHal, pAdapter->device_mode,
5629 pAdapter->sessionId);
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05305630 }
Kiet Lamad161252014-07-22 11:23:32 -07005631 else if ('2' == *dhcpPhase)
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05305632 {
Deepthi Gowribfd17132014-11-14 17:59:04 +05305633 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Kiet Lamad161252014-07-22 11:23:32 -07005634 FL("send DHCP STOP indication"));
c_hpothu9b781ba2013-12-30 20:57:45 +05305635
5636 pHddCtx->btCoexModeSet = FALSE;
Kiet Lamad161252014-07-22 11:23:32 -07005637
5638 sme_DHCPStopInd(pHddCtx->hHal, pAdapter->device_mode,
5639 pAdapter->sessionId);
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05305640 }
5641 }
Jeff Johnsonf54df2c2013-07-24 11:43:39 -07005642 else if (strncmp(command, "SCAN-ACTIVE", 11) == 0)
5643 {
Abhishek Singh58749d62016-02-03 15:27:20 +05305644 hddLog(LOG1,
5645 FL("making default scan to ACTIVE"));
c_hpothudbefd3e2014-04-28 15:59:47 +05305646 pHddCtx->scan_info.scan_mode = eSIR_ACTIVE_SCAN;
Jeff Johnsonf54df2c2013-07-24 11:43:39 -07005647 }
5648 else if (strncmp(command, "SCAN-PASSIVE", 12) == 0)
5649 {
Abhishek Singh58749d62016-02-03 15:27:20 +05305650 hddLog(LOG1,
5651 FL("making default scan to PASSIVE"));
c_hpothudbefd3e2014-04-28 15:59:47 +05305652 pHddCtx->scan_info.scan_mode = eSIR_PASSIVE_SCAN;
Jeff Johnsonf54df2c2013-07-24 11:43:39 -07005653 }
Hanumantha Reddy Pothula212243c2013-08-01 17:28:31 +05305654 else if (strncmp(command, "GETDWELLTIME", 12) == 0)
5655 {
5656 hdd_config_t *pCfg = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
5657 char extra[32];
5658 tANI_U8 len = 0;
5659
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05305660 memset(extra, 0, sizeof(extra));
5661 ret = hdd_get_dwell_time(pCfg, command, extra, sizeof(extra), &len);
Ratnam Rachuri12d5d462015-08-07 14:10:23 +05305662 len = VOS_MIN(priv_data.total_len, len + 1);
5663 if (ret != 0 || copy_to_user(priv_data.buf, &extra, len)) {
Hanumantha Reddy Pothula212243c2013-08-01 17:28:31 +05305664 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5665 "%s: failed to copy data to user buffer", __func__);
5666 ret = -EFAULT;
5667 goto exit;
5668 }
5669 ret = len;
5670 }
5671 else if (strncmp(command, "SETDWELLTIME", 12) == 0)
5672 {
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05305673 ret = hdd_set_dwell_time(pAdapter, command);
Hanumantha Reddy Pothula212243c2013-08-01 17:28:31 +05305674 }
Dundi Ravitejaae5adf42018-04-23 20:44:47 +05305675 else if (strncmp(command, "BTCGETDWELLTIME", 15) == 0)
5676 {
5677 hdd_config_t *pCfg = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
5678 char extra[32];
5679 tANI_U8 len = 0;
5680
5681 if (hdd_drv_cmd_validate(command, 15)) {
5682 hddLog(LOGE, FL("Invalid driver command"));
5683 return -EINVAL;
5684 }
5685
5686 memset(extra, 0, sizeof(extra));
5687 ret = hdd_btc_get_dwell_time(pCfg, command, extra,
5688 sizeof(extra), &len);
5689 len = VOS_MIN(priv_data.total_len, len + 1);
5690 if (ret != 0 || copy_to_user(priv_data.buf, &extra, len)) {
5691 hddLog(LOGE, FL("Failed to copy data to user buffer"));
5692 ret = -EFAULT;
5693 goto exit;
5694 }
5695 ret = len;
5696 }
5697 else if (strncmp(command, "BTCSETDWELLTIME", 15) == 0)
5698 {
5699 if (hdd_drv_cmd_validate(command, 15)) {
5700 hddLog(LOGE, FL("Invalid driver command"));
5701 return -EINVAL;
5702 }
5703 ret = hdd_btc_set_dwell_time(pAdapter, command);
5704 }
5705#ifdef WLAN_AP_STA_CONCURRENCY
5706 else if (strncmp(command, "CONCGETDWELLTIME", 16) == 0)
5707 {
5708 hdd_config_t *pCfg = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
5709 char extra[32];
5710 tANI_U8 len = 0;
5711
5712 if (hdd_drv_cmd_validate(command, 16)) {
5713 hddLog(LOGE, FL("Invalid driver command"));
5714 return -EINVAL;
5715 }
5716
5717 memset(extra, 0, sizeof(extra));
5718 ret = hdd_conc_get_dwell_time(pCfg, command, extra,
5719 sizeof(extra), &len);
5720 len = VOS_MIN(priv_data.total_len, len + 1);
5721 if (ret != 0 || copy_to_user(priv_data.buf, &extra, len)) {
5722 hddLog(LOGE, FL("Failed to copy data to user buffer"));
5723 ret = -EFAULT;
5724 goto exit;
5725 }
5726 ret = len;
5727 }
5728 else if (strncmp(command, "CONCSETDWELLTIME", 16) == 0)
5729 {
5730 if (hdd_drv_cmd_validate(command, 16)) {
5731 hddLog(LOGE, FL("Invalid driver command"));
5732 return -EINVAL;
5733 }
5734 ret = hdd_conc_set_dwell_time(pAdapter, command);
5735 }
5736#endif
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07005737 else if ( strncasecmp(command, "MIRACAST", 8) == 0 )
5738 {
5739 tANI_U8 filterType = 0;
5740 tANI_U8 *value;
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05305741
5742 ret = hdd_drv_cmd_validate(command, 8);
5743 if (ret)
5744 goto exit;
5745
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07005746 value = command + 9;
5747
5748 /* Convert the value from ascii to integer */
5749 ret = kstrtou8(value, 10, &filterType);
5750 if (ret < 0)
5751 {
5752 /* If the input value is greater than max value of datatype,
5753 * then also kstrtou8 fails
5754 */
5755 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5756 "%s: kstrtou8 failed range ", __func__);
5757 ret = -EINVAL;
5758 goto exit;
5759 }
5760 if ((filterType < WLAN_HDD_DRIVER_MIRACAST_CFG_MIN_VAL ) ||
5761 (filterType > WLAN_HDD_DRIVER_MIRACAST_CFG_MAX_VAL))
5762 {
5763 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5764 "%s: Accepted Values are 0 to 2. 0-Disabled, 1-Source,"
5765 " 2-Sink ", __func__);
5766 ret = -EINVAL;
5767 goto exit;
5768 }
5769 //Filtertype value should be either 0-Disabled, 1-Source, 2-sink
5770 pHddCtx->drvr_miracast = filterType;
Kaushik, Sushant96122442014-10-21 16:40:18 +05305771 pScanInfo = &pHddCtx->scan_info;
5772 if (filterType && pScanInfo != NULL &&
5773 pHddCtx->scan_info.mScanPending)
5774 {
5775 /*Miracast Session started. Abort Scan */
5776 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
5777 "%s, Aborting Scan For Miracast",__func__);
5778 hdd_abort_mac_scan(pHddCtx, pScanInfo->sessionId,
5779 eCSR_SCAN_ABORT_DEFAULT);
5780 }
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07005781 hdd_tx_rx_pkt_cnt_stat_timer_handler(pHddCtx);
Ganesh Kondabattini8f6e3b32014-08-25 16:07:54 +05305782 sme_SetMiracastMode(pHddCtx->hHal, pHddCtx->drvr_miracast);
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07005783 }
Leo Chang614d2072013-08-22 14:59:44 -07005784 else if (strncmp(command, "SETMCRATE", 9) == 0)
5785 {
Leo Chang614d2072013-08-22 14:59:44 -07005786 tANI_U8 *value = command;
5787 int targetRate;
Leo Chang1f98cbd2013-10-17 15:03:52 -07005788 tSirRateUpdateInd *rateUpdate;
5789 eHalStatus status;
Leo Chang614d2072013-08-22 14:59:44 -07005790
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05305791 ret = hdd_drv_cmd_validate(command, 9);
5792 if (ret)
5793 goto exit;
5794
Leo Chang614d2072013-08-22 14:59:44 -07005795 /* Only valid for SAP mode */
5796 if (WLAN_HDD_SOFTAP != pAdapter->device_mode)
5797 {
5798 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5799 "%s: SAP mode is not running", __func__);
5800 ret = -EFAULT;
5801 goto exit;
5802 }
5803
5804 /* Move pointer to ahead of SETMCRATE<delimiter> */
5805 /* input value is in units of hundred kbps */
5806 value = value + 10;
5807 /* Convert the value from ascii to integer, decimal base */
5808 ret = kstrtouint(value, 10, &targetRate);
5809
Leo Chang1f98cbd2013-10-17 15:03:52 -07005810 rateUpdate = (tSirRateUpdateInd *)vos_mem_malloc(sizeof(tSirRateUpdateInd));
5811 if (NULL == rateUpdate)
Leo Chang614d2072013-08-22 14:59:44 -07005812 {
Leo Chang1f98cbd2013-10-17 15:03:52 -07005813 hddLog(VOS_TRACE_LEVEL_ERROR,
5814 "%s: SETMCRATE indication alloc fail", __func__);
5815 ret = -EFAULT;
5816 goto exit;
5817 }
5818 vos_mem_zero(rateUpdate, sizeof(tSirRateUpdateInd ));
5819
5820 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
5821 "MC Target rate %d", targetRate);
5822 /* Ignore unicast */
5823 rateUpdate->ucastDataRate = -1;
5824 rateUpdate->mcastDataRate24GHz = targetRate;
5825 rateUpdate->mcastDataRate5GHz = targetRate;
5826 rateUpdate->mcastDataRate24GHzTxFlag = 0;
5827 rateUpdate->mcastDataRate5GHzTxFlag = 0;
5828 status = sme_SendRateUpdateInd(pHddCtx->hHal, rateUpdate);
5829 if (eHAL_STATUS_SUCCESS != status)
5830 {
5831 hddLog(VOS_TRACE_LEVEL_ERROR,
5832 "%s: SET_MC_RATE failed", __func__);
5833 vos_mem_free(rateUpdate);
5834 ret = -EFAULT;
5835 goto exit;
Leo Chang614d2072013-08-22 14:59:44 -07005836 }
5837 }
jge35567202017-06-21 16:39:38 +08005838 else if (strncmp(command, "MAXTXPOWER", 10) == 0)
5839 {
5840 int status;
5841 int txPower;
5842 eHalStatus smeStatus;
5843 tANI_U8 *value = command;
5844 tSirMacAddr bssid = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
5845 tSirMacAddr selfMac = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
5846
5847 status = hdd_parse_setmaxtxpower_command(value, &txPower);
5848 if (status)
5849 {
5850 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5851 "Invalid MAXTXPOWER command ");
5852 ret = -EINVAL;
5853 goto exit;
5854 }
5855
5856 hddLog(VOS_TRACE_LEVEL_INFO, "max tx power %d selfMac: "
5857 MAC_ADDRESS_STR " bssId: " MAC_ADDRESS_STR " ",
5858 txPower, MAC_ADDR_ARRAY(selfMac),
5859 MAC_ADDR_ARRAY(bssid));
5860 smeStatus = sme_SetMaxTxPower((tHalHandle)(pHddCtx->hHal),
5861 bssid, selfMac, txPower) ;
5862 if( smeStatus != eHAL_STATUS_SUCCESS )
5863 {
5864 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:Set max tx power failed",
5865 __func__);
5866 ret = -EINVAL;
5867 goto exit;
5868 }
5869
5870 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Set max tx power success",
5871 __func__);
5872 }
Rajeev79dbe4c2013-10-05 11:03:42 +05305873#ifdef FEATURE_WLAN_BATCH_SCAN
Rajeev Kumar8b373292014-01-08 20:36:55 -08005874 else if (strncmp(command, "WLS_BATCHING", 12) == 0)
Rajeev79dbe4c2013-10-05 11:03:42 +05305875 {
Rajeev Kumar8b373292014-01-08 20:36:55 -08005876 ret = hdd_handle_batch_scan_ioctl(pAdapter, &priv_data, command);
Rajeev79dbe4c2013-10-05 11:03:42 +05305877 }
5878#endif
Abhishek Singh00b71972016-01-07 10:51:04 +05305879#ifdef WLAN_FEATURE_RMC
5880 else if ((strncasecmp(command, "SETIBSSBEACONOUIDATA", 20) == 0) &&
5881 (WLAN_HDD_IBSS == pAdapter->device_mode))
5882 {
5883 int i = 0;
5884 tANI_U8 *ibss_ie;
5885 tANI_U32 command_len;
5886 tANI_U8 *value = command;
5887 tHalHandle hHal = pHddCtx->hHal;
5888 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
5889 tANI_U32 ibss_ie_length;
5890 tANI_U32 len, present;
5891 tANI_U8 *addIE;
5892 tANI_U8 *addIEData;
5893
5894 hddLog(LOG1,
5895 FL(" received command %s"),((char *) value));
5896 /* validate argument of command */
5897 if (strlen(value) <= 21)
5898 {
5899 hddLog(LOGE,
5900 FL("No arguements in command length %zu"), strlen(value));
5901 ret = -EFAULT;
5902 goto exit;
5903 }
5904
5905 /* moving to arguments of commands */
5906 value = value + 21;
5907 command_len = strlen(value);
5908
5909 /* oui_data can't be less than 3 bytes */
5910 if (command_len <= (2 * WLAN_HDD_IBSS_MIN_OUI_DATA_LENGTH))
5911 {
5912 hddLog(LOGE,
5913 FL("Invalid SETIBSSBEACONOUIDATA command length %d"),
5914 command_len);
5915 ret = -EFAULT;
5916 goto exit;
5917 }
5918 ibss_ie = vos_mem_malloc(command_len);
5919 if (!ibss_ie) {
5920 hddLog(LOGE,
5921 FL("Could not allocate memory for command length %d"),
5922 command_len);
5923 ret = -ENOMEM;
5924 goto exit;
5925 }
5926 vos_mem_zero(ibss_ie, command_len);
5927
5928 ibss_ie_length = hdd_parse_set_ibss_oui_data_command(value, ibss_ie,
5929 command_len);
5930 if (ibss_ie_length < (2 * WLAN_HDD_IBSS_MIN_OUI_DATA_LENGTH)) {
5931 hddLog(LOGE, FL("Could not parse command %s return length %d"),
5932 value, ibss_ie_length);
5933 ret = -EFAULT;
5934 vos_mem_free(ibss_ie);
5935 goto exit;
5936 }
5937
5938 hddLog(LOG1, FL("ibss_ie length %d ibss_ie:"), ibss_ie_length);
5939 while (i < ibss_ie_length)
5940 hddLog(LOG1, FL("0x%x"), ibss_ie[i++]);
5941
5942 /* Populate Vendor IE in Beacon */
5943 if ((ccmCfgGetInt(hHal,
5944 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG,
5945 &present)) != eHAL_STATUS_SUCCESS)
5946 {
5947 hddLog(LOGE,
5948 FL("unable to ftch WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG"));
5949 ret = -EFAULT;
5950 vos_mem_free(ibss_ie);
5951 goto exit;
5952 }
5953
5954 addIE = vos_mem_malloc(WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA_LEN);
5955 if (!addIE) {
5956 hddLog(LOGE,
5957 FL("Could not allocate memory for command length %d"),
5958 command_len);
5959 vos_mem_free(ibss_ie);
5960 ret = -ENOMEM;
5961 goto exit;
5962 }
5963 vos_mem_zero(addIE, WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA_LEN);
5964
5965 if (present)
5966 {
5967 if ((wlan_cfgGetStrLen(pMac,
5968 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, &len)) != eSIR_SUCCESS)
5969 {
5970 hddLog(LOGE,
5971 FL("unable to fetch WNI_CFG_PROBE_RSP_BCN_ADDNIE_LEN"));
5972 ret = -EFAULT;
5973 vos_mem_free(ibss_ie);
5974 vos_mem_free(addIE);
5975 goto exit;
5976 }
5977
5978 if (len <= WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA_LEN && len &&
5979 ((len + ibss_ie_length) <=
5980 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA_LEN))
5981 {
5982 if ((ccmCfgGetStr(hHal,
5983 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, addIE, &len))
5984 != eHAL_STATUS_SUCCESS)
5985 {
5986 hddLog(LOGE,
5987 FL("unable to fetch WNI_PROBE_RSP_BCN_ADDNIE_DATA"));
5988 ret = -EFAULT;
5989 vos_mem_free(ibss_ie);
5990 vos_mem_free(addIE);
5991 goto exit;
5992 }
5993 else
5994 {
5995 /* Curruntly only WPA IE is added before Vendor IE
5996 * so we can blindly place the Vendor IE after WPA
5997 * IE. If no WPA IE found replace all with Vendor IE.
5998 */
5999 len = hdd_find_ibss_wpa_ie_pos(addIE, len);
6000 }
6001 }
6002 else
6003 {
6004 hddLog(LOGE,
6005 FL("IE len exceed limit len %d,ibss_ie_length %d "),
6006 len, ibss_ie_length);
6007 ret = -EFAULT;
6008 vos_mem_free(addIE);
6009 vos_mem_free(ibss_ie);
6010 goto exit;
6011 }
6012 }
6013 else {
6014 len = 0;
6015 }
6016
6017 vos_mem_copy (addIE + len , ibss_ie, ibss_ie_length);
6018 len += ibss_ie_length;
6019
6020 if (ccmCfgSetStr(hHal,
6021 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, addIE, len, NULL,
6022 eANI_BOOLEAN_FALSE) != eHAL_STATUS_SUCCESS)
6023 {
6024 hddLog(LOGE,
6025 FL("unable to set WNI_CFG_PRBE_RSP_BCN_ADDNIE_DATA"));
6026 ret = -EFAULT;
6027 vos_mem_free(ibss_ie);
6028 vos_mem_free(addIE);
6029 goto exit;
6030 }
6031 vos_mem_free(addIE);
6032 if (ccmCfgSetInt(hHal,
6033 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 1,NULL,
6034 eANI_BOOLEAN_FALSE) != eHAL_STATUS_SUCCESS)
6035 {
6036 hddLog(LOGE,
6037 FL("unble to set WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG"));
6038 ret = -EFAULT;
6039 vos_mem_free(ibss_ie);
6040 goto exit;
6041 }
6042
6043 /* Populate Vendor IE in probe resp */
6044 if ((ccmCfgGetInt(hHal,
6045 WNI_CFG_PROBE_RSP_ADDNIE_FLAG,
6046 &present)) != eHAL_STATUS_SUCCESS)
6047 {
6048 hddLog(LOGE,
6049 FL("unable to fetch WNI_CFG_PROBE_RSP_ADDNIE_FLAG"));
6050 ret = -EFAULT;
6051 vos_mem_free(ibss_ie);
6052 goto exit;
6053 }
6054
6055 addIEData = vos_mem_malloc(WNI_CFG_PROBE_RSP_ADDNIE_DATA1_LEN);
6056 if (!addIEData) {
6057 hddLog(LOGE,
6058 FL("Could not allocate memory for command length %d"),
6059 command_len);
6060 vos_mem_free(ibss_ie);
6061 ret = -ENOMEM;
6062 goto exit;
6063 }
6064 vos_mem_zero(addIEData, WNI_CFG_PROBE_RSP_ADDNIE_DATA1_LEN);
6065
6066 if (present) {
6067 if (eSIR_SUCCESS != wlan_cfgGetStrLen(pMac,
6068 WNI_CFG_PROBE_RSP_ADDNIE_DATA1, &len)) {
6069 hddLog(LOGE,
6070 FL("unable to fetch WNI_CFG_PROBE_RSP_ADDNIE_DATA1"));
6071 ret = -EFAULT;
6072 vos_mem_free(ibss_ie);
6073 vos_mem_free(addIEData);
6074 goto exit;
6075 }
6076 if (len < WNI_CFG_PROBE_RSP_ADDNIE_DATA1_LEN && len &&
6077 (ibss_ie_length + len) <=
6078 WNI_CFG_PROBE_RSP_ADDNIE_DATA1_LEN) {
6079
6080 if ((ccmCfgGetStr(hHal,
6081 WNI_CFG_PROBE_RSP_ADDNIE_DATA1, addIEData, &len))
6082 != eHAL_STATUS_SUCCESS) {
6083 hddLog(LOGE,
6084 FL("unable fetch WNI_CFG_PROBE_RSP_ADDNIE_DATA1"));
6085 ret = -EFAULT;
6086 vos_mem_free(ibss_ie);
6087 vos_mem_free(addIEData);
6088 goto exit;
6089 }
6090 else {
6091 /* Curruntly only WPA IE is added before Vendor IE
6092 * so we can blindly place the Vendor IE after WPA
6093 * IE. If no WPA IE found replace all with Vendor IE.
6094 */
6095 len = hdd_find_ibss_wpa_ie_pos(addIEData, len);
6096 }
6097 }
6098 else
6099 {
6100 hddLog(LOGE,
6101 FL("IE len exceed limit len %d,ibss_ie_length %d "),
6102 len, ibss_ie_length);
6103 ret = -EFAULT;
6104 vos_mem_free(addIEData);
6105 vos_mem_free(ibss_ie);
6106 goto exit;
6107 }
6108 } /* probe rsp ADD IE present */
6109 else {
6110 /* probe rsp add IE is not present */
6111 len = 0;
6112 }
6113
6114 vos_mem_copy(addIEData +len , ibss_ie, ibss_ie_length);
6115 len += ibss_ie_length;
6116
6117 vos_mem_free(ibss_ie);
6118
6119 if (ccmCfgSetStr(hHal,
6120 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,
6121 (tANI_U8*)(addIEData),
6122 len, NULL,
6123 eANI_BOOLEAN_FALSE)
6124 == eHAL_STATUS_FAILURE) {
6125 hddLog(LOGE,
6126 FL("unable to copy to WNI_CFG_PROBE_RSP_ADDNIE_DATA1"));
6127 ret = -EFAULT;
6128 vos_mem_free(addIEData);
6129 goto exit;
6130 }
6131 vos_mem_free(addIEData);
6132 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
6133 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 1,NULL,
6134 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
6135 {
6136 hddLog(LOGE,
6137 FL("unable to copy WNI_CFG_PROBE_RSP_ADDNIE_FLAG"));
6138 ret = -EFAULT;
6139 goto exit;
6140 }
6141 }
6142 else if (strncasecmp(command, "SETRMCENABLE", 12) == 0)
6143 {
6144 tANI_U8 *value = command;
6145 tANI_U8 ucRmcEnable = 0;
6146 int status;
6147
6148 if ((WLAN_HDD_IBSS != pAdapter->device_mode) &&
6149 (WLAN_HDD_SOFTAP != pAdapter->device_mode))
6150 {
6151 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6152 "Received SETRMCENABLE command in invalid mode %d "
6153 "SETRMCENABLE command is only allowed in IBSS or SOFTAP mode",
6154 pAdapter->device_mode);
6155 ret = -EINVAL;
6156 goto exit;
6157 }
6158
6159 status = hdd_parse_setrmcenable_command(value, &ucRmcEnable);
6160 if (status)
6161 {
6162 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6163 "Invalid SETRMCENABLE command ");
6164 ret = -EINVAL;
6165 goto exit;
6166 }
6167
6168 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6169 "%s: ucRmcEnable %d ", __func__, ucRmcEnable);
6170
6171 if (TRUE == ucRmcEnable)
6172 {
6173 status = sme_EnableRMC( (tHalHandle)(pHddCtx->hHal),
6174 pAdapter->sessionId );
6175 }
6176 else if(FALSE == ucRmcEnable)
6177 {
6178 status = sme_DisableRMC( (tHalHandle)(pHddCtx->hHal),
6179 pAdapter->sessionId );
6180 }
6181 else
6182 {
6183 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6184 "Invalid SETRMCENABLE command %d", ucRmcEnable);
6185 ret = -EINVAL;
6186 goto exit;
6187 }
6188
6189 if (VOS_STATUS_SUCCESS != status)
6190 {
6191 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6192 "%s: SETRMC %d failed status %d", __func__, ucRmcEnable,
6193 status);
6194 ret = -EINVAL;
6195 goto exit;
6196 }
6197 }
6198 else if (strncasecmp(command, "SETRMCACTIONPERIOD", 18) == 0)
6199 {
6200 tANI_U8 *value = command;
6201 tANI_U32 uActionPeriod = 0;
6202 int status;
6203
6204 if ((WLAN_HDD_IBSS != pAdapter->device_mode) &&
6205 (WLAN_HDD_SOFTAP != pAdapter->device_mode))
6206 {
6207 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6208 "Received SETRMC command in invalid mode %d "
6209 "SETRMC command is only allowed in IBSS or SOFTAP mode",
6210 pAdapter->device_mode);
6211 ret = -EINVAL;
6212 goto exit;
6213 }
6214
6215 status = hdd_parse_setrmcactionperiod_command(value, &uActionPeriod);
6216 if (status)
6217 {
6218 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6219 "Invalid SETRMCACTIONPERIOD command ");
6220 ret = -EINVAL;
6221 goto exit;
6222 }
6223
6224 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6225 "%s: uActionPeriod %d ", __func__, uActionPeriod);
6226
6227 if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_RMC_ACTION_PERIOD_FREQUENCY,
6228 uActionPeriod, NULL, eANI_BOOLEAN_FALSE))
6229 {
6230 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6231 "%s: Could not set SETRMCACTIONPERIOD %d", __func__, uActionPeriod);
6232 ret = -EINVAL;
6233 goto exit;
6234 }
6235
6236 }
6237 else if (strncasecmp(command, "GETIBSSPEERINFOALL", 18) == 0)
6238 {
6239 /* Peer Info All Command */
6240 int status = eHAL_STATUS_SUCCESS;
6241 hdd_station_ctx_t *pHddStaCtx = NULL;
6242 char *extra = NULL;
6243 int idx = 0, length = 0;
6244 v_MACADDR_t *macAddr;
6245 v_U32_t txRateMbps = 0, numOfBytestoPrint = 0;
6246
6247 if (WLAN_HDD_IBSS == pAdapter->device_mode)
6248 {
6249 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
6250 }
6251 else
6252 {
6253 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6254 "%s: pAdapter is not valid for this device mode",
6255 __func__);
6256 ret = -EINVAL;
6257 goto exit;
6258 }
6259
6260 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6261 "%s: Received GETIBSSPEERINFOALL Command", __func__);
6262
6263
6264 /* Handle the command */
6265 status = hdd_cfg80211_get_ibss_peer_info_all(pAdapter);
6266 if (VOS_STATUS_SUCCESS == status)
6267 {
6268 /* The variable extra needed to be allocated on the heap since
6269 * amount of memory required to copy the data for 32 devices
6270 * exceeds the size of 1024 bytes of default stack size. On
6271 * 64 bit devices, the default max stack size of 2048 bytes
6272 */
6273 extra = kmalloc(WLAN_MAX_BUF_SIZE, GFP_KERNEL);
6274
6275 if (NULL == extra)
6276 {
6277 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6278 "%s:kmalloc failed", __func__);
6279 ret = -EINVAL;
6280 goto exit;
6281 }
6282
6283 /* Copy number of stations */
6284 length = scnprintf( extra, WLAN_MAX_BUF_SIZE, "%d ",
6285 pHddStaCtx->ibss_peer_info.numIBSSPeers);
6286 numOfBytestoPrint = length;
6287 for (idx = 0; idx < pHddStaCtx->ibss_peer_info.numIBSSPeers; idx++)
6288 {
6289 macAddr =
6290 hdd_wlan_get_ibss_mac_addr_from_staid(pAdapter,
6291 pHddStaCtx->ibss_peer_info.ibssPeerList[idx].staIdx);
6292 if (NULL != macAddr)
6293 {
6294 txRateMbps =
6295 ((pHddStaCtx->ibss_peer_info.ibssPeerList[idx].txRate)*500*1000)/1000000;
6296
6297 length += scnprintf( (extra + length), WLAN_MAX_BUF_SIZE - length,
6298 "%02x:%02x:%02x:%02x:%02x:%02x %d %d ",
6299 macAddr->bytes[0], macAddr->bytes[1], macAddr->bytes[2],
6300 macAddr->bytes[3], macAddr->bytes[4], macAddr->bytes[5],
6301 (int)txRateMbps,
6302 (int)pHddStaCtx->ibss_peer_info.ibssPeerList[idx].rssi);
6303 }
6304 else
6305 {
6306 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6307 "%s: MAC ADDR is NULL for staIdx: %d", __func__,
6308 pHddStaCtx->ibss_peer_info.ibssPeerList[idx].staIdx);
6309 }
6310
6311 /*
6312 * VOS_TRACE() macro has limitation of 512 bytes for the print
6313 * buffer. Hence printing the data in two chunks. The first chunk
6314 * will have the data for 16 devices and the second chunk will
6315 * have the rest.
6316 */
6317 if (idx < NUM_OF_STA_DATA_TO_PRINT)
6318 {
6319 numOfBytestoPrint = length;
6320 }
6321 }
6322
6323 /*
6324 * Copy the data back into buffer, if the data to copy is
6325 * morethan 512 bytes than we will split the data and do
6326 * it in two shots
6327 */
6328 if (copy_to_user(priv_data.buf, extra, numOfBytestoPrint))
6329 {
6330 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6331 "%s: Copy into user data buffer failed ", __func__);
6332 ret = -EFAULT;
6333 kfree(extra);
6334 goto exit;
6335 }
6336 priv_data.buf[numOfBytestoPrint] = '\0';
6337 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_MED,
6338 "%s", priv_data.buf);
6339
6340 if (length > numOfBytestoPrint)
6341 {
6342 if (copy_to_user(priv_data.buf + numOfBytestoPrint,
6343 extra + numOfBytestoPrint,
6344 length - numOfBytestoPrint + 1))
6345 {
6346 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6347 "%s: Copy into user data buffer failed ", __func__);
6348 ret = -EFAULT;
6349 kfree(extra);
6350 goto exit;
6351 }
6352 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_MED,
6353 "%s", &priv_data.buf[numOfBytestoPrint]);
6354 }
6355
6356 /* Free temporary buffer */
6357 kfree(extra);
6358 }
6359
6360 else
6361 {
6362 /* Command failed, log error */
6363 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6364 "%s: GETIBSSPEERINFOALL command failed with status code %d",
6365 __func__, status);
6366 ret = -EINVAL;
6367 goto exit;
6368 }
6369 ret = 0;
6370 }
6371 else if(strncasecmp(command, "GETIBSSPEERINFO", 15) == 0)
6372 {
6373 /* Peer Info <Peer Addr> command */
6374 tANI_U8 *value = command;
6375 VOS_STATUS status;
6376 hdd_station_ctx_t *pHddStaCtx = NULL;
6377 char extra[128] = { 0 };
6378 v_U32_t length = 0;
6379 v_U8_t staIdx = 0;
6380 v_U32_t txRateMbps = 0;
6381 v_MACADDR_t peerMacAddr;
6382
6383 if (WLAN_HDD_IBSS == pAdapter->device_mode)
6384 {
6385 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
6386 }
6387 else
6388 {
6389 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6390 "%s: pAdapter is not valid for this device mode",
6391 __func__);
6392 ret = -EINVAL;
6393 goto exit;
6394 }
6395
6396 /* if there are no peers, no need to continue with the command */
6397 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6398 "%s: Received GETIBSSPEERINFO Command", __func__);
6399
6400 if (eConnectionState_IbssConnected != pHddStaCtx->conn_info.connState)
6401 {
6402 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6403 "%s:No IBSS Peers coalesced", __func__);
6404 ret = -EINVAL;
6405 goto exit;
6406 }
6407
6408 /* Parse the incoming command buffer */
6409 status = hdd_parse_get_ibss_peer_info(value, &peerMacAddr);
6410 if (VOS_STATUS_SUCCESS != status)
6411 {
6412 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6413 "%s: Invalid GETIBSSPEERINFO command", __func__);
6414 ret = -EINVAL;
6415 goto exit;
6416 }
6417
6418 /* Get station index for the peer mac address */
6419 hdd_Ibss_GetStaId(pHddStaCtx, &peerMacAddr, &staIdx);
6420
6421 if (staIdx > HDD_MAX_NUM_IBSS_STA)
6422 {
6423 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6424 "%s: Invalid StaIdx %d returned", __func__, staIdx);
6425 ret = -EINVAL;
6426 goto exit;
6427 }
6428
6429 /* Handle the command */
6430 status = hdd_cfg80211_get_ibss_peer_info(pAdapter, staIdx);
6431 if (VOS_STATUS_SUCCESS == status)
6432 {
6433 v_U32_t txRate = pHddStaCtx->ibss_peer_info.ibssPeerList[0].txRate;
6434 txRateMbps = (txRate * 500 * 1000)/1000000;
6435
6436 length = scnprintf( extra, sizeof(extra), "%d %d", (int)txRateMbps,
6437 (int)pHddStaCtx->ibss_peer_info.ibssPeerList[0].rssi);
6438
6439 /* Copy the data back into buffer */
6440 if (copy_to_user(priv_data.buf, &extra, length+ 1))
6441 {
6442 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6443 "%s: copy data to user buffer failed GETIBSSPEERINFO command",
6444 __func__);
6445 ret = -EFAULT;
6446 goto exit;
6447 }
6448 }
6449 else
6450 {
6451 /* Command failed, log error */
6452 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6453 "%s: GETIBSSPEERINFO command failed with status code %d",
6454 __func__, status);
6455 ret = -EINVAL;
6456 goto exit;
6457 }
6458
6459 /* Success ! */
6460 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_MED,
6461 "%s", priv_data.buf);
6462 ret = 0;
6463 }
6464 else if (strncasecmp(command, "SETRMCTXRATE", 12) == 0)
6465 {
6466 tANI_U8 *value = command;
6467 tANI_U32 uRate = 0;
6468 tTxrateinfoflags txFlags = 0;
6469 tSirRateUpdateInd *rateUpdateParams;
6470 int status;
6471
6472 if ((WLAN_HDD_IBSS != pAdapter->device_mode) &&
6473 (WLAN_HDD_SOFTAP != pAdapter->device_mode))
6474 {
6475 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6476 "Received SETRMCTXRATE command in invalid mode %d "
6477 "SETRMC command is only allowed in IBSS or SOFTAP mode",
6478 pAdapter->device_mode);
6479 ret = -EINVAL;
6480 goto exit;
6481 }
6482
6483 status = hdd_parse_setrmcrate_command(value, &uRate, &txFlags);
6484 if (status)
6485 {
6486 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6487 "Invalid SETRMCTXRATE command ");
6488 ret = -EINVAL;
6489 goto exit;
6490 }
6491
6492 rateUpdateParams = vos_mem_malloc(sizeof(tSirRateUpdateInd));
6493 if (NULL == rateUpdateParams)
6494 {
6495 ret = -EINVAL;
6496 goto exit;
6497 }
6498
6499 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6500 "%s: uRate %d ", __func__, uRate);
6501
6502 vos_mem_zero(rateUpdateParams, sizeof(tSirRateUpdateInd ));
6503
6504 /* -1 implies ignore this param */
6505 rateUpdateParams->ucastDataRate = -1;
6506
6507 /*
6508 * Fill the user specifieed RMC rate param
6509 * and the derived tx flags.
6510 */
6511 rateUpdateParams->rmcDataRate = uRate;
6512 rateUpdateParams->rmcDataRateTxFlag = txFlags;
6513
6514 status = sme_SendRateUpdateInd((tHalHandle)(pHddCtx->hHal), rateUpdateParams);
6515 }
6516 else if (strncasecmp(command, "SETIBSSTXFAILEVENT", 18) == 0 )
6517 {
6518 char *value;
6519 tANI_U8 tx_fail_count = 0;
6520 tANI_U16 pid = 0;
6521
6522 value = command;
6523
6524 ret = hdd_ParseIBSSTXFailEventParams(value, &tx_fail_count, &pid);
6525
6526 if (0 != ret)
6527 {
6528 hddLog(VOS_TRACE_LEVEL_INFO,
6529 "%s: Failed to parse SETIBSSTXFAILEVENT arguments",
6530 __func__);
6531 goto exit;
6532 }
6533
6534 hddLog(VOS_TRACE_LEVEL_INFO, "%s: tx_fail_cnt=%hhu, pid=%hu",
6535 __func__, tx_fail_count, pid);
6536
6537 if (0 == tx_fail_count)
6538 {
6539 // Disable TX Fail Indication
6540 if (eHAL_STATUS_SUCCESS ==
6541 sme_TXFailMonitorStartStopInd(pHddCtx->hHal,
6542 tx_fail_count,
6543 NULL))
6544 {
6545 cesium_pid = 0;
6546 }
6547 else
6548 {
6549 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6550 "%s: failed to disable TX Fail Event ", __func__);
6551 ret = -EINVAL;
6552 }
6553 }
6554 else
6555 {
6556 if (eHAL_STATUS_SUCCESS ==
6557 sme_TXFailMonitorStartStopInd(pHddCtx->hHal,
6558 tx_fail_count,
6559 (void*)hdd_tx_fail_ind_callback))
6560 {
6561 cesium_pid = pid;
6562 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6563 "%s: Registered Cesium pid %u", __func__,
6564 cesium_pid);
6565 }
6566 else
6567 {
6568 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6569 "%s: Failed to enable TX Fail Monitoring", __func__);
6570 ret = -EINVAL;
6571 }
6572 }
6573 }
6574
6575#endif /* WLAN_FEATURE_RMC */
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08006576#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07006577 else if (strncmp(command, "SETCCXROAMSCANCHANNELS", 22) == 0)
6578 {
6579 tANI_U8 *value = command;
6580 tANI_U8 ChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
6581 tANI_U8 numChannels = 0;
6582 eHalStatus status = eHAL_STATUS_SUCCESS;
6583
6584 status = hdd_parse_channellist(value, ChannelList, &numChannels);
6585 if (eHAL_STATUS_SUCCESS != status)
6586 {
6587 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6588 "%s: Failed to parse channel list information", __func__);
6589 ret = -EINVAL;
6590 goto exit;
6591 }
6592
6593 if (numChannels > WNI_CFG_VALID_CHANNEL_LIST_LEN)
6594 {
6595 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6596 "%s: number of channels (%d) supported exceeded max (%d)", __func__,
6597 numChannels, WNI_CFG_VALID_CHANNEL_LIST_LEN);
6598 ret = -EINVAL;
6599 goto exit;
6600 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08006601 status = sme_SetEseRoamScanChannelList((tHalHandle)(pHddCtx->hHal),
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07006602 ChannelList,
6603 numChannels);
6604 if (eHAL_STATUS_SUCCESS != status)
6605 {
6606 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6607 "%s: Failed to update channel list information", __func__);
6608 ret = -EINVAL;
6609 goto exit;
6610 }
6611 }
6612 else if (strncmp(command, "GETTSMSTATS", 11) == 0)
6613 {
6614 tANI_U8 *value = command;
6615 char extra[128] = {0};
6616 int len = 0;
6617 tANI_U8 tid = 0;
6618 hdd_station_ctx_t *pHddStaCtx = NULL;
6619 tAniTrafStrmMetrics tsmMetrics;
6620 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
6621
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05306622 ret = hdd_drv_cmd_validate(command, 11);
6623 if (ret)
6624 goto exit;
6625
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07006626 /* if not associated, return error */
6627 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
6628 {
6629 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "%s:Not associated!",__func__);
6630 ret = -EINVAL;
6631 goto exit;
6632 }
6633
6634 /* Move pointer to ahead of GETTSMSTATS<delimiter> */
6635 value = value + 12;
6636 /* Convert the value from ascii to integer */
6637 ret = kstrtou8(value, 10, &tid);
6638 if (ret < 0)
6639 {
6640 /* If the input value is greater than max value of datatype, then also
6641 kstrtou8 fails */
6642 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6643 "%s: kstrtou8 failed range [%d - %d]", __func__,
6644 TID_MIN_VALUE,
6645 TID_MAX_VALUE);
6646 ret = -EINVAL;
6647 goto exit;
6648 }
6649
6650 if ((tid < TID_MIN_VALUE) || (tid > TID_MAX_VALUE))
6651 {
6652 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6653 "tid value %d is out of range"
6654 " (Min: %d Max: %d)", tid,
6655 TID_MIN_VALUE,
6656 TID_MAX_VALUE);
6657 ret = -EINVAL;
6658 goto exit;
6659 }
6660
6661 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6662 "%s: Received Command to get tsm stats tid = %d", __func__, tid);
6663
6664 if (VOS_STATUS_SUCCESS != hdd_get_tsm_stats(pAdapter, tid, &tsmMetrics))
6665 {
6666 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6667 "%s: failed to get tsm stats", __func__);
6668 ret = -EFAULT;
6669 goto exit;
6670 }
6671
6672 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6673 "UplinkPktQueueDly(%d)\n"
6674 "UplinkPktQueueDlyHist[0](%d)\n"
6675 "UplinkPktQueueDlyHist[1](%d)\n"
6676 "UplinkPktQueueDlyHist[2](%d)\n"
6677 "UplinkPktQueueDlyHist[3](%d)\n"
Arun Kumar Khandavallie8768212014-02-17 16:43:34 +05306678 "UplinkPktTxDly(%u)\n"
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07006679 "UplinkPktLoss(%d)\n"
6680 "UplinkPktCount(%d)\n"
6681 "RoamingCount(%d)\n"
6682 "RoamingDly(%d)", tsmMetrics.UplinkPktQueueDly,
6683 tsmMetrics.UplinkPktQueueDlyHist[0],
6684 tsmMetrics.UplinkPktQueueDlyHist[1],
6685 tsmMetrics.UplinkPktQueueDlyHist[2],
6686 tsmMetrics.UplinkPktQueueDlyHist[3],
6687 tsmMetrics.UplinkPktTxDly, tsmMetrics.UplinkPktLoss,
6688 tsmMetrics.UplinkPktCount, tsmMetrics.RoamingCount, tsmMetrics.RoamingDly);
6689
6690 /* Output TSM stats is of the format
6691 GETTSMSTATS [PktQueueDly] [PktQueueDlyHist[0]]:[PktQueueDlyHist[1]] ...[RoamingDly]
6692 eg., GETTSMSTATS 10 1:0:0:161 20 1 17 8 39800 */
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08006693 len = scnprintf(extra, sizeof(extra), "%s %d %d:%d:%d:%d %u %d %d %d %d", command,
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07006694 tsmMetrics.UplinkPktQueueDly, tsmMetrics.UplinkPktQueueDlyHist[0],
6695 tsmMetrics.UplinkPktQueueDlyHist[1], tsmMetrics.UplinkPktQueueDlyHist[2],
6696 tsmMetrics.UplinkPktQueueDlyHist[3], tsmMetrics.UplinkPktTxDly,
6697 tsmMetrics.UplinkPktLoss, tsmMetrics.UplinkPktCount, tsmMetrics.RoamingCount,
6698 tsmMetrics.RoamingDly);
6699
Ratnam Rachurid53009c2015-08-07 13:59:00 +05306700 len = VOS_MIN(priv_data.total_len, len + 1);
6701 if (copy_to_user(priv_data.buf, &extra, len)) {
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07006702 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6703 "%s: failed to copy data to user buffer", __func__);
6704 ret = -EFAULT;
6705 goto exit;
6706 }
6707 }
6708 else if (strncmp(command, "SETCCKMIE", 9) == 0)
6709 {
6710 tANI_U8 *value = command;
6711 tANI_U8 *cckmIe = NULL;
6712 tANI_U8 cckmIeLen = 0;
6713 eHalStatus status = eHAL_STATUS_SUCCESS;
6714
6715 status = hdd_parse_get_cckm_ie(value, &cckmIe, &cckmIeLen);
6716 if (eHAL_STATUS_SUCCESS != status)
6717 {
6718 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6719 "%s: Failed to parse cckm ie data", __func__);
6720 ret = -EINVAL;
6721 goto exit;
6722 }
6723
6724 if (cckmIeLen > DOT11F_IE_RSN_MAX_LEN)
6725 {
6726 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6727 "%s: CCKM Ie input length is more than max[%d]", __func__,
6728 DOT11F_IE_RSN_MAX_LEN);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08006729 vos_mem_free(cckmIe);
6730 cckmIe = NULL;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07006731 ret = -EINVAL;
6732 goto exit;
6733 }
6734 sme_SetCCKMIe((tHalHandle)(pHddCtx->hHal), pAdapter->sessionId, cckmIe, cckmIeLen);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08006735 vos_mem_free(cckmIe);
6736 cckmIe = NULL;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07006737 }
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08006738 else if (strncmp(command, "CCXBEACONREQ", 12) == 0)
6739 {
6740 tANI_U8 *value = command;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08006741 tCsrEseBeaconReq eseBcnReq;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08006742 eHalStatus status = eHAL_STATUS_SUCCESS;
Srinivas Girigowda0c6d7fe2014-05-28 18:18:10 -07006743
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08006744 status = hdd_parse_ese_beacon_req(value, &eseBcnReq);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08006745 if (eHAL_STATUS_SUCCESS != status)
6746 {
6747 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08006748 "%s: Failed to parse ese beacon req", __func__);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08006749 ret = -EINVAL;
6750 goto exit;
6751 }
Srinivas Girigowda0c6d7fe2014-05-28 18:18:10 -07006752 if (!hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))) {
6753 hddLog(VOS_TRACE_LEVEL_INFO, FL("Not associated"));
6754 hdd_indicateEseBcnReportNoResults (pAdapter,
6755 eseBcnReq.bcnReq[0].measurementToken,
6756 0x02, //BIT(1) set for measurement done
6757 0); // no BSS
6758 goto exit;
6759 }
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08006760
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08006761 status = sme_SetEseBeaconRequest((tHalHandle)(pHddCtx->hHal), pAdapter->sessionId, &eseBcnReq);
6762 if (eHAL_STATUS_SUCCESS != status)
6763 {
6764 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6765 "%s: sme_SetEseBeaconRequest failed (%d)", __func__, status);
6766 ret = -EINVAL;
6767 goto exit;
6768 }
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08006769 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08006770#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
c_hpothu92367912014-05-01 15:18:17 +05306771 else if (strncmp(command, "GETBCNMISSRATE", 14) == 0)
6772 {
6773 eHalStatus status;
6774 char buf[32], len;
Hanumanth Reddy Pothula7aa4bea2018-04-09 17:19:03 +05306775 void *cookie;
6776 struct hdd_request *request;
6777 struct bcn_miss_rate_priv *priv;
6778 static const struct hdd_request_params params = {
6779 .priv_size = sizeof(*priv),
6780 .timeout_ms = WLAN_WAIT_TIME_STATS,
6781 };
c_hpothu92367912014-05-01 15:18:17 +05306782
6783 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
6784
6785 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
6786 {
6787 hddLog(VOS_TRACE_LEVEL_WARN,
6788 FL("GETBCNMISSRATE: STA is not in connected state"));
6789 ret = -1;
6790 goto exit;
6791 }
Hanumanth Reddy Pothula7aa4bea2018-04-09 17:19:03 +05306792 request = hdd_request_alloc(&params);
6793 if (!request) {
6794 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Request allocation failure"));
6795 ret = -ENOMEM;
6796 goto exit;
6797 }
6798 cookie = hdd_request_cookie(request);
6799 priv = hdd_request_priv(request);
6800 priv->bcn_miss_rate = -1;
c_hpothu92367912014-05-01 15:18:17 +05306801
6802 status = sme_getBcnMissRate((tHalHandle)(pHddCtx->hHal),
6803 pAdapter->sessionId,
Hanumanth Reddy Pothula7aa4bea2018-04-09 17:19:03 +05306804 (void *)get_bcn_miss_rate_cb,
6805 cookie);
c_hpothu92367912014-05-01 15:18:17 +05306806 if( eHAL_STATUS_SUCCESS != status)
6807 {
6808 hddLog(VOS_TRACE_LEVEL_INFO,
6809 FL("GETBCNMISSRATE: fail to post WDA cmd"));
6810 ret = -EINVAL;
Hanumanth Reddy Pothula7aa4bea2018-04-09 17:19:03 +05306811 goto free_bcn_miss_rate_req;
c_hpothu92367912014-05-01 15:18:17 +05306812 }
6813
Hanumanth Reddy Pothula7aa4bea2018-04-09 17:19:03 +05306814 ret = hdd_request_wait_for_response(request);
6815 if(ret)
c_hpothu92367912014-05-01 15:18:17 +05306816 {
6817 hddLog(VOS_TRACE_LEVEL_ERROR,
6818 FL("failed to wait on bcnMissRateComp %d"), ret);
6819
c_hpothu92367912014-05-01 15:18:17 +05306820 ret = -EINVAL;
Hanumanth Reddy Pothula7aa4bea2018-04-09 17:19:03 +05306821 goto free_bcn_miss_rate_req;
c_hpothu92367912014-05-01 15:18:17 +05306822 }
6823
6824 hddLog(VOS_TRACE_LEVEL_INFO,
Hanumanth Reddy Pothula7aa4bea2018-04-09 17:19:03 +05306825 FL("GETBCNMISSRATE: bcnMissRate: %d"), priv->bcn_miss_rate);
c_hpothu92367912014-05-01 15:18:17 +05306826
Hanumanth Reddy Pothula7aa4bea2018-04-09 17:19:03 +05306827 if (priv->bcn_miss_rate == -1) {
6828 ret = -EFAULT;
6829 goto free_bcn_miss_rate_req;
6830 }
6831
6832 len = snprintf(buf, sizeof(buf), "GETBCNMISSRATE %d",
6833 priv->bcn_miss_rate);
c_hpothu92367912014-05-01 15:18:17 +05306834 if (copy_to_user(priv_data.buf, &buf, len + 1))
6835 {
6836 hddLog(VOS_TRACE_LEVEL_ERROR,
6837 "%s: failed to copy data to user buffer", __func__);
6838 ret = -EFAULT;
Hanumanth Reddy Pothula7aa4bea2018-04-09 17:19:03 +05306839 goto free_bcn_miss_rate_req;
c_hpothu92367912014-05-01 15:18:17 +05306840 }
6841 ret = len;
Hanumanth Reddy Pothula7aa4bea2018-04-09 17:19:03 +05306842
6843free_bcn_miss_rate_req:
6844 hdd_request_put(request);
c_hpothu92367912014-05-01 15:18:17 +05306845 }
Atul Mittal87ec2422014-09-24 13:12:50 +05306846#ifdef FEATURE_WLAN_TDLS
6847 else if (strncmp(command, "TDLSSECONDARYCHANNELOFFSET", 26) == 0) {
6848 tANI_U8 *value = command;
6849 int set_value;
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05306850
6851 ret = hdd_drv_cmd_validate(command, 26);
6852 if (ret)
6853 goto exit;
6854
Atul Mittal87ec2422014-09-24 13:12:50 +05306855 /* Move pointer to ahead of TDLSOFFCH*/
6856 value += 26;
c_manjeebbc40212015-12-08 13:52:59 +05306857 if (!(sscanf(value, "%d", &set_value))) {
6858 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6859 FL("No input identified"));
6860 ret = -EINVAL;
6861 goto exit;
6862 }
6863
Atul Mittal87ec2422014-09-24 13:12:50 +05306864 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6865 "%s: Tdls offchannel offset:%d",
6866 __func__, set_value);
6867 ret = iw_set_tdlssecoffchanneloffset(pHddCtx, set_value);
6868 if (ret < 0)
6869 {
6870 ret = -EINVAL;
6871 goto exit;
6872 }
6873
6874 } else if (strncmp(command, "TDLSOFFCHANNELMODE", 18) == 0) {
6875 tANI_U8 *value = command;
6876 int set_value;
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05306877
6878 ret = hdd_drv_cmd_validate(command, 18);
6879 if (ret)
6880 goto exit;
6881
Atul Mittal87ec2422014-09-24 13:12:50 +05306882 /* Move pointer to ahead of tdlsoffchnmode*/
6883 value += 18;
c_manjee82323892015-12-08 12:40:34 +05306884 ret = sscanf(value, "%d", &set_value);
6885 if (ret != 1) {
6886 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6887 FL("No input identified"));
6888 ret = -EINVAL;
6889 goto exit;
6890 }
Atul Mittal87ec2422014-09-24 13:12:50 +05306891 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6892 "%s: Tdls offchannel mode:%d",
6893 __func__, set_value);
6894 ret = iw_set_tdlsoffchannelmode(pAdapter, set_value);
6895 if (ret < 0)
6896 {
6897 ret = -EINVAL;
6898 goto exit;
6899 }
6900 } else if (strncmp(command, "TDLSOFFCHANNEL", 14) == 0) {
6901 tANI_U8 *value = command;
6902 int set_value;
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05306903
6904 ret = hdd_drv_cmd_validate(command, 14);
6905 if (ret)
6906 goto exit;
6907
Atul Mittal87ec2422014-09-24 13:12:50 +05306908 /* Move pointer to ahead of TDLSOFFCH*/
6909 value += 14;
c_manjeef6ccaf52015-12-08 11:52:11 +05306910 ret = sscanf(value, "%d", &set_value);
6911 if (ret != 1) {
6912 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6913 "Wrong value is given for hdd_set_tdls_offchannel");
6914 ret = -EINVAL;
6915 goto exit;
6916 }
6917
Atul Mittal87ec2422014-09-24 13:12:50 +05306918 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6919 "%s: Tdls offchannel num: %d",
6920 __func__, set_value);
6921 ret = iw_set_tdlsoffchannel(pHddCtx, set_value);
6922 if (ret < 0)
6923 {
6924 ret = -EINVAL;
6925 goto exit;
6926 }
6927 }
6928#endif
Satyanarayana Dash72806012014-12-02 14:30:08 +05306929 else if (strncmp(command, "GETFWSTATS", 10) == 0)
6930 {
6931 eHalStatus status;
6932 char *buf = NULL;
6933 char len;
Hanumanth Reddy Pothula7aa4bea2018-04-09 17:19:03 +05306934 tSirFwStatsResult *fwStatsRsp = &(pAdapter->fwStatsRsp),
6935 *fw_stats_result;
Satyanarayana Dash72806012014-12-02 14:30:08 +05306936 tANI_U8 *ptr = command;
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05306937 int stats;
Hanumanth Reddy Pothula7aa4bea2018-04-09 17:19:03 +05306938 void *cookie;
6939 struct hdd_request *request;
6940 struct fw_stats_priv *priv;
6941 static const struct hdd_request_params params = {
6942 .priv_size = sizeof(*priv),
6943 .timeout_ms = WLAN_WAIT_TIME_STATS,
6944 };
Satyanarayana Dash72806012014-12-02 14:30:08 +05306945
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05306946 ret = hdd_drv_cmd_validate(command, 10);
6947 if (ret)
6948 goto exit;
6949
6950 stats = *(ptr + 11) - '0';
Satyanarayana Dash72806012014-12-02 14:30:08 +05306951 hddLog(VOS_TRACE_LEVEL_INFO, FL("stats = %d "),stats);
6952 if (!IS_FEATURE_FW_STATS_ENABLE)
6953 {
6954 hddLog(VOS_TRACE_LEVEL_INFO,
6955 FL("Get Firmware stats feature not supported"));
6956 ret = -EINVAL;
6957 goto exit;
6958 }
6959
6960 if (FW_STATS_MAX <= stats || 0 >= stats)
6961 {
6962 hddLog(VOS_TRACE_LEVEL_INFO,
6963 FL(" stats %d not supported"),stats);
6964 ret = -EINVAL;
6965 goto exit;
6966 }
6967
Hanumanth Reddy Pothula7aa4bea2018-04-09 17:19:03 +05306968 request = hdd_request_alloc(&params);
6969 if (!request) {
6970 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Request allocation failure"));
6971 ret = -ENOMEM;
6972 goto exit;
6973 }
6974 cookie = hdd_request_cookie(request);
6975
Satyanarayana Dash72806012014-12-02 14:30:08 +05306976 status = sme_GetFwStats( (tHalHandle)pHddCtx->hHal, stats,
Hanumanth Reddy Pothula7aa4bea2018-04-09 17:19:03 +05306977 cookie, hdd_fw_stats_cb);
Satyanarayana Dash72806012014-12-02 14:30:08 +05306978 if (eHAL_STATUS_SUCCESS != status)
6979 {
6980 hddLog(VOS_TRACE_LEVEL_ERROR,
6981 FL(" fail to post WDA cmd status = %d"), status);
6982 ret = -EINVAL;
Hanumanth Reddy Pothula7aa4bea2018-04-09 17:19:03 +05306983 hdd_request_put(request);
Satyanarayana Dash72806012014-12-02 14:30:08 +05306984 goto exit;
6985 }
Hanumanth Reddy Pothula7aa4bea2018-04-09 17:19:03 +05306986 ret = hdd_request_wait_for_response(request);
6987 if (ret)
Satyanarayana Dash72806012014-12-02 14:30:08 +05306988 {
6989 hddLog(VOS_TRACE_LEVEL_ERROR,
6990 FL("failed to wait on GwtFwstats"));
Satyanarayana Dash72806012014-12-02 14:30:08 +05306991 ret = -EINVAL;
Hanumanth Reddy Pothula7aa4bea2018-04-09 17:19:03 +05306992 hdd_request_put(request);
Satyanarayana Dash72806012014-12-02 14:30:08 +05306993 goto exit;
6994 }
Hanumanth Reddy Pothula7aa4bea2018-04-09 17:19:03 +05306995
6996 priv = hdd_request_priv(request);
6997 fw_stats_result = priv->fw_stats;
6998 fwStatsRsp->type = 0;
6999 if (NULL != fw_stats_result)
7000 {
7001 switch (fw_stats_result->type )
7002 {
7003 case FW_UBSP_STATS:
7004 {
7005 tSirUbspFwStats *stats =
7006 &fwStatsRsp->fwStatsData.ubspStats;
7007 memcpy(fwStatsRsp, fw_stats_result,
7008 sizeof(tSirFwStatsResult));
7009 hddLog(VOS_TRACE_LEVEL_INFO,
7010 FL("ubsp_enter_cnt = %d ubsp_jump_ddr_cnt = %d"),
7011 stats->ubsp_enter_cnt,
7012 stats->ubsp_jump_ddr_cnt);
7013 }
7014 break;
7015
7016 default:
7017 {
7018 hddLog(VOS_TRACE_LEVEL_ERROR,
7019 FL("No handling for stats type %d"),
7020 fw_stats_result->type);
7021 }
7022 }
7023 }
7024 hdd_request_put(request);
7025
Satyanarayana Dash72806012014-12-02 14:30:08 +05307026 if (fwStatsRsp->type)
7027 {
7028 buf = kmalloc(FW_STATE_RSP_LEN, GFP_KERNEL);
7029 if (!buf)
7030 {
7031 hddLog(VOS_TRACE_LEVEL_ERROR,
7032 FL(" failed to allocate memory"));
7033 ret = -ENOMEM;
7034 goto exit;
7035 }
7036 switch( fwStatsRsp->type )
7037 {
7038 case FW_UBSP_STATS:
7039 {
7040 len = snprintf(buf, FW_STATE_RSP_LEN,
7041 "GETFWSTATS: ubsp_enter_cnt %d ubsp_jump_ddr_cnt %d",
Abhishek Singh08aa7762014-12-16 13:59:03 +05307042 fwStatsRsp->fwStatsData.ubspStats.ubsp_enter_cnt,
7043 fwStatsRsp->fwStatsData.ubspStats.ubsp_jump_ddr_cnt);
Satyanarayana Dash72806012014-12-02 14:30:08 +05307044 }
7045 break;
7046 default:
7047 {
7048 hddLog(VOS_TRACE_LEVEL_ERROR, FL( "No handling for stats type %d"),fwStatsRsp->type);
7049 ret = -EFAULT;
7050 kfree(buf);
7051 goto exit;
7052 }
7053 }
7054 if (copy_to_user(priv_data.buf, buf, len + 1))
7055 {
7056 hddLog(VOS_TRACE_LEVEL_ERROR,
7057 FL(" failed to copy data to user buffer"));
7058 ret = -EFAULT;
7059 kfree(buf);
7060 goto exit;
7061 }
7062 ret = len;
7063 kfree(buf);
7064 }
7065 else
7066 {
7067 hddLog(VOS_TRACE_LEVEL_ERROR,
7068 FL("failed to fetch the stats"));
7069 ret = -EFAULT;
7070 goto exit;
7071 }
Satyanarayana Dash72806012014-12-02 14:30:08 +05307072 }
Agarwal Ashish8bd53ae2015-06-12 18:03:45 +05307073 else if (strncasecmp(command, "SET_FCC_CHANNEL", 15) == 0)
7074 {
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05307075 ret = hdd_drv_cmd_validate(command, 15);
7076 if (ret)
7077 goto exit;
7078
Agarwal Ashish8bd53ae2015-06-12 18:03:45 +05307079 /*
7080 * this command wld be called by user-space when it detects WLAN
7081 * ON after airplane mode is set. When APM is set, WLAN turns off.
7082 * But it can be turned back on. Otherwise; when APM is turned back
7083 * off, WLAN wld turn back on. So at that point the command is
7084 * expected to come down. 0 means disable, 1 means enable. The
7085 * constraint is removed when parameter 1 is set or different
7086 * country code is set
7087 */
7088 ret = hdd_cmd_setFccChannel(pHddCtx, command, 15);
7089 }
Mahesh A Saptasagarbeca12c2015-09-07 16:21:06 +05307090 else if (strncasecmp(command, "DISABLE_CA_EVENT", 16) == 0)
7091 {
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05307092 ret = hdd_drv_cmd_validate(command, 16);
7093 if (ret)
7094 goto exit;
7095
Mahesh A Saptasagarbeca12c2015-09-07 16:21:06 +05307096 ret = hdd_enable_disable_ca_event(pHddCtx, command, 16);
7097 }
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +05307098 /*
7099 * command should be a string having format
7100 * SET_DISABLE_CHANNEL_LIST <num of channels>
7101 * <channels separated by spaces>
7102 */
7103 else if (strncmp(command, "SET_DISABLE_CHANNEL_LIST", 24) == 0) {
7104 tANI_U8 *ptr = command;
7105 ret = hdd_drv_cmd_validate(command, 24);
7106 if (ret)
7107 goto exit;
7108
7109 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
7110 " Received Command to disable Channels %s",
7111 __func__);
7112 ret = hdd_parse_disable_chan_cmd(pAdapter, ptr);
7113 if (ret)
7114 goto exit;
7115 }
Hanumanth Reddy Pothula8ae38bb2018-03-07 18:59:30 +05307116 else if (strncmp(command, "GET_DISABLE_CHANNEL_LIST", 24) == 0) {
Ashish Kumar Dhanotiya95e5bc22018-04-19 17:06:33 +05307117 char extra[512] = {0};
7118 int max_len, copied_length;
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +05307119
Ashish Kumar Dhanotiya95e5bc22018-04-19 17:06:33 +05307120 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Hanumanth Reddy Pothula8ae38bb2018-03-07 18:59:30 +05307121 " Received Command to get disable Channels list %s",
7122 __func__);
7123
Ashish Kumar Dhanotiya95e5bc22018-04-19 17:06:33 +05307124 max_len = VOS_MIN(priv_data.total_len, sizeof(extra));
7125 copied_length = hdd_get_disable_ch_list(pHddCtx, extra, max_len);
7126 if (copied_length == 0) {
7127 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Hanumanth Reddy Pothula8ae38bb2018-03-07 18:59:30 +05307128 FL("disable channel list are not yet programed"));
7129 ret = -EINVAL;
7130 goto exit;
7131 }
7132
Ashish Kumar Dhanotiya95e5bc22018-04-19 17:06:33 +05307133 if (copy_to_user(priv_data.buf, &extra, copied_length + 1)) {
7134 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7135 "%s: failed to copy data to user buffer", __func__);
Hanumanth Reddy Pothula8ae38bb2018-03-07 18:59:30 +05307136 ret = -EFAULT;
7137 goto exit;
7138 }
7139
7140 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
7141 FL("data:%s"), extra);
7142 }
Madan Mohan Koyyalamudif9bdd4e2012-10-30 18:05:03 -07007143 else {
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307144 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
7145 TRACE_CODE_HDD_UNSUPPORTED_IOCTL,
7146 pAdapter->sessionId, 0));
Satyanarayana Dash72806012014-12-02 14:30:08 +05307147 hddLog( VOS_TRACE_LEVEL_WARN, FL("Unsupported GUI command %s"),
7148 command);
Madan Mohan Koyyalamudif9bdd4e2012-10-30 18:05:03 -07007149 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007150 }
7151exit:
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05307152 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07007153 if (command)
7154 {
7155 kfree(command);
7156 }
7157 return ret;
7158}
7159
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07007160#ifdef CONFIG_COMPAT
7161static int hdd_driver_compat_ioctl(hdd_adapter_t *pAdapter, struct ifreq *ifr)
7162{
7163 struct {
7164 compat_uptr_t buf;
7165 int used_len;
7166 int total_len;
7167 } compat_priv_data;
7168 hdd_priv_data_t priv_data;
7169 int ret = 0;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07007170
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07007171 /*
7172 * Note that pAdapter and ifr have already been verified by caller,
7173 * and HDD context has also been validated
7174 */
7175 if (copy_from_user(&compat_priv_data, ifr->ifr_data,
7176 sizeof(compat_priv_data))) {
7177 ret = -EFAULT;
7178 goto exit;
7179 }
7180 priv_data.buf = compat_ptr(compat_priv_data.buf);
7181 priv_data.used_len = compat_priv_data.used_len;
7182 priv_data.total_len = compat_priv_data.total_len;
7183 ret = hdd_driver_command(pAdapter, &priv_data);
7184 exit:
7185 return ret;
7186}
7187#else /* CONFIG_COMPAT */
7188static int hdd_driver_compat_ioctl(hdd_adapter_t *pAdapter, struct ifreq *ifr)
7189{
7190 /* will never be invoked */
7191 return 0;
7192}
7193#endif /* CONFIG_COMPAT */
7194
7195static int hdd_driver_ioctl(hdd_adapter_t *pAdapter, struct ifreq *ifr)
7196{
7197 hdd_priv_data_t priv_data;
7198 int ret = 0;
7199
7200 /*
7201 * Note that pAdapter and ifr have already been verified by caller,
7202 * and HDD context has also been validated
7203 */
7204 if (copy_from_user(&priv_data, ifr->ifr_data, sizeof(priv_data))) {
7205 ret = -EFAULT;
7206 } else {
7207 ret = hdd_driver_command(pAdapter, &priv_data);
7208 }
7209 return ret;
7210}
7211
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05307212int __hdd_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07007213{
7214 hdd_adapter_t *pAdapter;
7215 hdd_context_t *pHddCtx;
7216 int ret;
7217
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05307218 ENTER();
7219
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07007220 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
7221 if (NULL == pAdapter) {
7222 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
7223 "%s: HDD adapter context is Null", __func__);
7224 ret = -ENODEV;
7225 goto exit;
7226 }
7227 if (dev != pAdapter->dev) {
7228 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
7229 "%s: HDD adapter/dev inconsistency", __func__);
7230 ret = -ENODEV;
7231 goto exit;
7232 }
7233
7234 if ((!ifr) || (!ifr->ifr_data)) {
7235 ret = -EINVAL;
7236 goto exit;
7237 }
7238
7239 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7240 ret = wlan_hdd_validate_context(pHddCtx);
7241 if (ret) {
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07007242 ret = -EBUSY;
7243 goto exit;
7244 }
7245
7246 switch (cmd) {
7247 case (SIOCDEVPRIVATE + 1):
7248 if (is_compat_task())
7249 ret = hdd_driver_compat_ioctl(pAdapter, ifr);
7250 else
7251 ret = hdd_driver_ioctl(pAdapter, ifr);
7252 break;
7253 default:
7254 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unknown ioctl %d",
7255 __func__, cmd);
7256 ret = -EINVAL;
7257 break;
7258 }
7259 exit:
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05307260 EXIT();
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07007261 return ret;
7262}
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07007263
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05307264int hdd_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
7265{
7266 int ret;
7267
7268 vos_ssr_protect(__func__);
7269 ret = __hdd_ioctl(dev, ifr, cmd);
7270 vos_ssr_unprotect(__func__);
7271
7272 return ret;
7273}
7274
Katya Nigame7b69a82015-04-28 15:24:06 +05307275int hdd_mon_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
7276{
7277 return 0;
7278}
7279
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08007280#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08007281/**---------------------------------------------------------------------------
7282
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08007283 \brief hdd_parse_ese_beacon_req() - Parse ese beacon request
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08007284
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08007285 This function parses the ese beacon request passed in the format
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08007286 CCXBEACONREQ<space><Number of fields><space><Measurement token>
7287 <space>Channel 1<space>Scan Mode <space>Meas Duration<space>Channel N
7288 <space>Scan Mode N<space>Meas Duration N
7289 if the Number of bcn req fields (N) does not match with the actual number of fields passed
7290 then take N.
7291 <Meas Token><Channel><Scan Mode> and <Meas Duration> are treated as one pair
7292 For example, CCXBEACONREQ 2 1 1 1 30 2 44 0 40.
7293 This function does not take care of removing duplicate channels from the list
7294
7295 \param - pValue Pointer to data
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08007296 \param - pEseBcnReq output pointer to store parsed ie information
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08007297
7298 \return - 0 for success non-zero for failure
7299
7300 --------------------------------------------------------------------------*/
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08007301static VOS_STATUS hdd_parse_ese_beacon_req(tANI_U8 *pValue,
7302 tCsrEseBeaconReq *pEseBcnReq)
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08007303{
7304 tANI_U8 *inPtr = pValue;
Arun Khandavalli9f3b4832016-06-30 16:58:38 +05307305 uint8_t input = 0;
7306 uint32_t tempInt = 0;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08007307 int j = 0, i = 0, v = 0;
7308 char buf[32];
7309
7310 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
7311 /*no argument after the command*/
7312 if (NULL == inPtr)
7313 {
7314 return -EINVAL;
7315 }
7316 /*no space after the command*/
7317 else if (SPACE_ASCII_VALUE != *inPtr)
7318 {
7319 return -EINVAL;
7320 }
7321
7322 /*removing empty spaces*/
7323 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
7324
7325 /*no argument followed by spaces*/
7326 if ('\0' == *inPtr) return -EINVAL;
7327
7328 /*getting the first argument ie measurement token*/
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08007329 v = sscanf(inPtr, "%31s ", buf);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08007330 if (1 != v) return -EINVAL;
7331
Arun Khandavalli9f3b4832016-06-30 16:58:38 +05307332 v = kstrtos8(buf, 10, &input);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08007333 if ( v < 0) return -EINVAL;
7334
Arun Khandavalli9f3b4832016-06-30 16:58:38 +05307335 input = VOS_MIN(input, SIR_ESE_MAX_MEAS_IE_REQS);
7336 pEseBcnReq->numBcnReqIe = input;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08007337
Srinivas Girigowda725a88e2016-03-31 19:24:25 +05307338 hddLog(LOG1, "Number of Bcn Req Ie fields: %d", pEseBcnReq->numBcnReqIe);
7339
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08007340
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08007341 for (j = 0; j < (pEseBcnReq->numBcnReqIe); j++)
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08007342 {
7343 for (i = 0; i < 4; i++)
7344 {
7345 /*inPtr pointing to the beginning of first space after number of ie fields*/
7346 inPtr = strpbrk( inPtr, " " );
7347 /*no ie data after the number of ie fields argument*/
7348 if (NULL == inPtr) return -EINVAL;
7349
7350 /*removing empty space*/
7351 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
7352
7353 /*no ie data after the number of ie fields argument and spaces*/
7354 if ( '\0' == *inPtr ) return -EINVAL;
7355
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08007356 v = sscanf(inPtr, "%31s ", buf);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08007357 if (1 != v) return -EINVAL;
7358
Arun Khandavalli9f3b4832016-06-30 16:58:38 +05307359 v = kstrtou32(buf, 10, &tempInt);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08007360 if (v < 0) return -EINVAL;
7361
7362 switch (i)
7363 {
7364 case 0: /* Measurement token */
Arun Khandavalli9f3b4832016-06-30 16:58:38 +05307365 if (!tempInt)
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08007366 {
7367 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arun Khandavalli9f3b4832016-06-30 16:58:38 +05307368 "Invalid Measurement Token: %u", tempInt);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08007369 return -EINVAL;
7370 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08007371 pEseBcnReq->bcnReq[j].measurementToken = tempInt;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08007372 break;
7373
7374 case 1: /* Channel number */
Arun Khandavalli9f3b4832016-06-30 16:58:38 +05307375 if ((!tempInt) ||
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08007376 (tempInt > WNI_CFG_CURRENT_CHANNEL_STAMAX))
7377 {
7378 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arun Khandavalli9f3b4832016-06-30 16:58:38 +05307379 "Invalid Channel Number: %u", tempInt);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08007380 return -EINVAL;
7381 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08007382 pEseBcnReq->bcnReq[j].channel = tempInt;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08007383 break;
7384
7385 case 2: /* Scan mode */
Varun Reddy Yeturu0b18d5a2013-12-04 11:42:23 -08007386 if ((tempInt < eSIR_PASSIVE_SCAN) || (tempInt > eSIR_BEACON_TABLE))
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08007387 {
7388 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arun Khandavalli9f3b4832016-06-30 16:58:38 +05307389 "Invalid Scan Mode(%u) Expected{0|1|2}", tempInt);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08007390 return -EINVAL;
7391 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08007392 pEseBcnReq->bcnReq[j].scanMode= tempInt;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08007393 break;
7394
7395 case 3: /* Measurement duration */
Arun Khandavalli9f3b4832016-06-30 16:58:38 +05307396 if (((!tempInt) && (pEseBcnReq->bcnReq[j].scanMode != eSIR_BEACON_TABLE)) ||
7397 ((pEseBcnReq->bcnReq[j].scanMode == eSIR_BEACON_TABLE)))
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08007398 {
7399 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arun Khandavalli9f3b4832016-06-30 16:58:38 +05307400 "Invalid Measurement Duration: %u", tempInt);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08007401 return -EINVAL;
7402 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08007403 pEseBcnReq->bcnReq[j].measurementDuration = tempInt;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08007404 break;
7405 }
7406 }
7407 }
7408
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08007409 for (j = 0; j < pEseBcnReq->numBcnReqIe; j++)
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08007410 {
7411 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Arun Kumar Khandavallie8768212014-02-17 16:43:34 +05307412 "Index(%d) Measurement Token(%u)Channel(%u) Scan Mode(%u) Measurement Duration(%u)\n",
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08007413 j,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08007414 pEseBcnReq->bcnReq[j].measurementToken,
7415 pEseBcnReq->bcnReq[j].channel,
7416 pEseBcnReq->bcnReq[j].scanMode,
7417 pEseBcnReq->bcnReq[j].measurementDuration);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08007418 }
7419
7420 return VOS_STATUS_SUCCESS;
7421}
7422
Hanumanth Reddy Pothula1ceb7032018-04-05 19:35:55 +05307423struct tsm_priv {
7424 tAniTrafStrmMetrics tsm_metrics;
7425};
7426
7427static void hdd_get_tsm_stats_cb(tAniTrafStrmMetrics tsm_metrics,
7428 const tANI_U32 sta_id, void *context )
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07007429{
Hanumanth Reddy Pothula1ceb7032018-04-05 19:35:55 +05307430 struct hdd_request *request;
7431 struct tsm_priv *priv;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07007432
Hanumanth Reddy Pothula1ceb7032018-04-05 19:35:55 +05307433 ENTER();
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07007434
Hanumanth Reddy Pothula1ceb7032018-04-05 19:35:55 +05307435 request = hdd_request_get(context);
7436 if (!request) {
7437 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Obsolete request"));
7438 return;
7439 }
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07007440
Hanumanth Reddy Pothula1ceb7032018-04-05 19:35:55 +05307441 priv = hdd_request_priv(request);
7442 priv->tsm_metrics = tsm_metrics;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07007443
Hanumanth Reddy Pothula1ceb7032018-04-05 19:35:55 +05307444 hdd_request_complete(request);
7445 hdd_request_put(request);
Jeff Johnson72a40512013-12-19 10:14:15 -08007446
Hanumanth Reddy Pothula1ceb7032018-04-05 19:35:55 +05307447 EXIT();
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07007448}
7449
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07007450static VOS_STATUS hdd_get_tsm_stats(hdd_adapter_t *pAdapter, const tANI_U8 tid,
7451 tAniTrafStrmMetrics* pTsmMetrics)
7452{
7453 hdd_station_ctx_t *pHddStaCtx = NULL;
7454 eHalStatus hstatus;
Jeff Johnson72a40512013-12-19 10:14:15 -08007455 VOS_STATUS vstatus = VOS_STATUS_SUCCESS;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07007456 hdd_context_t *pHddCtx = NULL;
Hanumanth Reddy Pothula1ceb7032018-04-05 19:35:55 +05307457 int ret;
7458 void *cookie;
7459 struct hdd_request *request;
7460 struct tsm_priv *priv;
7461 static const struct hdd_request_params params = {
7462 .priv_size = sizeof(*priv),
7463 .timeout_ms = WLAN_WAIT_TIME_STATS,
7464 };
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07007465
7466 if (NULL == pAdapter)
7467 {
7468 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: pAdapter is NULL", __func__);
7469 return VOS_STATUS_E_FAULT;
7470 }
7471
7472 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7473 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7474
Hanumanth Reddy Pothula1ceb7032018-04-05 19:35:55 +05307475 request = hdd_request_alloc(&params);
7476 if (!request) {
7477 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Request allocation failure"));
7478 return VOS_STATUS_E_NOMEM;
7479 }
7480 cookie = hdd_request_cookie(request);
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07007481
7482 /* query tsm stats */
Hanumanth Reddy Pothula1ceb7032018-04-05 19:35:55 +05307483 hstatus = sme_GetTsmStats(pHddCtx->hHal, hdd_get_tsm_stats_cb,
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07007484 pHddStaCtx->conn_info.staId[ 0 ],
7485 pHddStaCtx->conn_info.bssId,
Hanumanth Reddy Pothula1ceb7032018-04-05 19:35:55 +05307486 cookie, pHddCtx->pvosContext, tid);
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07007487
7488 if (eHAL_STATUS_SUCCESS != hstatus)
7489 {
Jeff Johnson72a40512013-12-19 10:14:15 -08007490 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unable to retrieve statistics",
7491 __func__);
7492 vstatus = VOS_STATUS_E_FAULT;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07007493 }
7494 else
7495 {
7496 /* request was sent -- wait for the response */
Hanumanth Reddy Pothula1ceb7032018-04-05 19:35:55 +05307497 ret = hdd_request_wait_for_response(request);
7498 if (ret) {
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07007499 hddLog(VOS_TRACE_LEVEL_ERROR,
Hanumanth Reddy Pothula1ceb7032018-04-05 19:35:55 +05307500 "SME timeout while retrieving statistics");
Jeff Johnson72a40512013-12-19 10:14:15 -08007501 vstatus = VOS_STATUS_E_TIMEOUT;
Hanumanth Reddy Pothula1ceb7032018-04-05 19:35:55 +05307502 } else {
7503 priv = hdd_request_priv(request);
7504 *pTsmMetrics = priv->tsm_metrics;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07007505 }
7506 }
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07007507
Hanumanth Reddy Pothula1ceb7032018-04-05 19:35:55 +05307508 hdd_request_put(request);
Jeff Johnson72a40512013-12-19 10:14:15 -08007509
Jeff Johnson72a40512013-12-19 10:14:15 -08007510 return vstatus;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07007511}
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08007512#endif /*FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07007513
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08007514#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowdade697412013-02-14 16:31:48 -08007515void hdd_getBand_helper(hdd_context_t *pHddCtx, int *pBand)
7516{
7517 eCsrBand band = -1;
7518 sme_GetFreqBand((tHalHandle)(pHddCtx->hHal), &band);
7519 switch (band)
7520 {
7521 case eCSR_BAND_ALL:
7522 *pBand = WLAN_HDD_UI_BAND_AUTO;
7523 break;
7524
7525 case eCSR_BAND_24:
7526 *pBand = WLAN_HDD_UI_BAND_2_4_GHZ;
7527 break;
7528
7529 case eCSR_BAND_5G:
7530 *pBand = WLAN_HDD_UI_BAND_5_GHZ;
7531 break;
7532
7533 default:
7534 hddLog( VOS_TRACE_LEVEL_WARN, "%s: Invalid Band %d", __func__, band);
7535 *pBand = -1;
7536 break;
7537 }
7538}
7539
7540/**---------------------------------------------------------------------------
7541
Srinivas Girigowda100eb322013-03-15 16:48:20 -07007542 \brief hdd_parse_send_action_frame_data() - HDD Parse send action frame data
7543
7544 This function parses the send action frame data passed in the format
7545 SENDACTIONFRAME<space><bssid><space><channel><space><dwelltime><space><data>
7546
Srinivas Girigowda56076852013-08-20 14:00:50 -07007547 \param - pValue Pointer to input data
Srinivas Girigowda100eb322013-03-15 16:48:20 -07007548 \param - pTargetApBssid Pointer to target Ap bssid
7549 \param - pChannel Pointer to the Target AP channel
7550 \param - pDwellTime Pointer to the time to stay off-channel after transmitting action frame
7551 \param - pBuf Pointer to data
7552 \param - pBufLen Pointer to data length
7553
7554 \return - 0 for success non-zero for failure
7555
7556 --------------------------------------------------------------------------*/
7557VOS_STATUS hdd_parse_send_action_frame_data(tANI_U8 *pValue, tANI_U8 *pTargetApBssid, tANI_U8 *pChannel,
7558 tANI_U8 *pDwellTime, tANI_U8 **pBuf, tANI_U8 *pBufLen)
7559{
7560 tANI_U8 *inPtr = pValue;
7561 tANI_U8 *dataEnd;
7562 int tempInt;
7563 int j = 0;
7564 int i = 0;
7565 int v = 0;
7566 tANI_U8 tempBuf[32];
7567 tANI_U8 tempByte = 0;
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08007568 /* 12 hexa decimal digits, 5 ':' and '\0' */
7569 tANI_U8 macAddress[18];
Srinivas Girigowda100eb322013-03-15 16:48:20 -07007570
7571 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
7572 /*no argument after the command*/
7573 if (NULL == inPtr)
7574 {
7575 return -EINVAL;
7576 }
7577
7578 /*no space after the command*/
7579 else if (SPACE_ASCII_VALUE != *inPtr)
7580 {
7581 return -EINVAL;
7582 }
7583
7584 /*removing empty spaces*/
7585 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
7586
7587 /*no argument followed by spaces*/
7588 if ('\0' == *inPtr)
7589 {
7590 return -EINVAL;
7591 }
7592
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07007593 v = sscanf(inPtr, "%17s", macAddress);
7594 if (!((1 == v) && hdd_is_valid_mac_address(macAddress)))
Srinivas Girigowda100eb322013-03-15 16:48:20 -07007595 {
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07007596 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7597 "Invalid MAC address or All hex inputs are not read (%d)", v);
7598 return -EINVAL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07007599 }
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07007600
7601 pTargetApBssid[0] = hdd_parse_hex(macAddress[0]) << 4 | hdd_parse_hex(macAddress[1]);
7602 pTargetApBssid[1] = hdd_parse_hex(macAddress[3]) << 4 | hdd_parse_hex(macAddress[4]);
7603 pTargetApBssid[2] = hdd_parse_hex(macAddress[6]) << 4 | hdd_parse_hex(macAddress[7]);
7604 pTargetApBssid[3] = hdd_parse_hex(macAddress[9]) << 4 | hdd_parse_hex(macAddress[10]);
7605 pTargetApBssid[4] = hdd_parse_hex(macAddress[12]) << 4 | hdd_parse_hex(macAddress[13]);
7606 pTargetApBssid[5] = hdd_parse_hex(macAddress[15]) << 4 | hdd_parse_hex(macAddress[16]);
Srinivas Girigowda100eb322013-03-15 16:48:20 -07007607
7608 /* point to the next argument */
7609 inPtr = strnchr(inPtr, strlen(inPtr), SPACE_ASCII_VALUE);
7610 /*no argument after the command*/
7611 if (NULL == inPtr) return -EINVAL;
7612
7613 /*removing empty spaces*/
7614 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
7615
7616 /*no argument followed by spaces*/
7617 if ('\0' == *inPtr)
7618 {
7619 return -EINVAL;
7620 }
7621
7622 /*getting the next argument ie the channel number */
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08007623 v = sscanf(inPtr, "%31s ", tempBuf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07007624 if (1 != v) return -EINVAL;
7625
Srinivas Girigowda100eb322013-03-15 16:48:20 -07007626 v = kstrtos32(tempBuf, 10, &tempInt);
Agarwal Ashish353b3a82014-04-08 14:55:11 +05307627 if ( v < 0 || tempInt <= 0 || tempInt > WNI_CFG_CURRENT_CHANNEL_STAMAX )
Kiet Lambe150c22013-11-21 16:30:32 +05307628 return -EINVAL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07007629
7630 *pChannel = tempInt;
7631
7632 /* point to the next argument */
7633 inPtr = strnchr(inPtr, strlen(inPtr), SPACE_ASCII_VALUE);
7634 /*no argument after the command*/
7635 if (NULL == inPtr) return -EINVAL;
7636 /*removing empty spaces*/
7637 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
7638
7639 /*no argument followed by spaces*/
7640 if ('\0' == *inPtr)
7641 {
7642 return -EINVAL;
7643 }
7644
7645 /*getting the next argument ie the dwell time */
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08007646 v = sscanf(inPtr, "%31s ", tempBuf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07007647 if (1 != v) return -EINVAL;
7648
Srinivas Girigowda100eb322013-03-15 16:48:20 -07007649 v = kstrtos32(tempBuf, 10, &tempInt);
Srinivas Girigowda5a6e0672014-01-09 14:42:57 -08007650 if ( v < 0 || tempInt < 0) return -EINVAL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07007651
7652 *pDwellTime = tempInt;
7653
7654 /* point to the next argument */
7655 inPtr = strnchr(inPtr, strlen(inPtr), SPACE_ASCII_VALUE);
7656 /*no argument after the command*/
7657 if (NULL == inPtr) return -EINVAL;
7658 /*removing empty spaces*/
7659 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
7660
7661 /*no argument followed by spaces*/
7662 if ('\0' == *inPtr)
7663 {
7664 return -EINVAL;
7665 }
7666
7667 /* find the length of data */
7668 dataEnd = inPtr;
7669 while(('\0' != *dataEnd) )
7670 {
7671 dataEnd++;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07007672 }
Kiet Lambe150c22013-11-21 16:30:32 +05307673 *pBufLen = dataEnd - inPtr ;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07007674 if ( *pBufLen <= 0) return -EINVAL;
7675
Srinivas Girigowdab5ae85d2013-06-03 10:51:45 -07007676 /* Allocate the number of bytes based on the number of input characters
7677 whether it is even or odd.
7678 if the number of input characters are even, then we need N/2 byte.
7679 if the number of input characters are odd, then we need do (N+1)/2 to
7680 compensate rounding off.
7681 For example, if N = 18, then (18 + 1)/2 = 9 bytes are enough.
7682 If N = 19, then we need 10 bytes, hence (19 + 1)/2 = 10 bytes */
7683 *pBuf = vos_mem_malloc((*pBufLen + 1)/2);
Srinivas Girigowda100eb322013-03-15 16:48:20 -07007684 if (NULL == *pBuf)
7685 {
7686 hddLog(VOS_TRACE_LEVEL_FATAL,
7687 "%s: vos_mem_alloc failed ", __func__);
7688 return -EINVAL;
7689 }
7690
7691 /* the buffer received from the upper layer is character buffer,
7692 we need to prepare the buffer taking 2 characters in to a U8 hex decimal number
7693 for example 7f0000f0...form a buffer to contain 7f in 0th location, 00 in 1st
7694 and f0 in 3rd location */
7695 for (i = 0, j = 0; j < *pBufLen; j += 2)
7696 {
Kiet Lambe150c22013-11-21 16:30:32 +05307697 if( j+1 == *pBufLen)
7698 {
7699 tempByte = hdd_parse_hex(inPtr[j]);
7700 }
7701 else
7702 {
7703 tempByte = (hdd_parse_hex(inPtr[j]) << 4) | (hdd_parse_hex(inPtr[j + 1]));
7704 }
Srinivas Girigowda100eb322013-03-15 16:48:20 -07007705 (*pBuf)[i++] = tempByte;
7706 }
7707 *pBufLen = i;
7708 return VOS_STATUS_SUCCESS;
7709}
7710
Srinivas Girigowda100eb322013-03-15 16:48:20 -07007711/**---------------------------------------------------------------------------
7712
Srinivas Girigowdade697412013-02-14 16:31:48 -08007713 \brief hdd_parse_channellist() - HDD Parse channel list
7714
7715 This function parses the channel list passed in the format
7716 SETROAMSCANCHANNELS<space><Number of channels><space>Channel 1<space>Channel 2<space>Channel N
Srinivas Girigowdacf9a9b42013-03-21 11:55:24 -07007717 if the Number of channels (N) does not match with the actual number of channels passed
7718 then take the minimum of N and count of (Ch1, Ch2, ...Ch M)
7719 For example, if SETROAMSCANCHANNELS 3 36 40 44 48, only 36, 40 and 44 shall be taken.
7720 If SETROAMSCANCHANNELS 5 36 40 44 48, ignore 5 and take 36, 40, 44 and 48.
7721 This function does not take care of removing duplicate channels from the list
Srinivas Girigowdade697412013-02-14 16:31:48 -08007722
7723 \param - pValue Pointer to input channel list
7724 \param - ChannelList Pointer to local output array to record channel list
7725 \param - pNumChannels Pointer to number of roam scan channels
7726
7727 \return - 0 for success non-zero for failure
7728
7729 --------------------------------------------------------------------------*/
7730VOS_STATUS hdd_parse_channellist(tANI_U8 *pValue, tANI_U8 *pChannelList, tANI_U8 *pNumChannels)
7731{
7732 tANI_U8 *inPtr = pValue;
7733 int tempInt;
7734 int j = 0;
7735 int v = 0;
7736 char buf[32];
7737
7738 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
7739 /*no argument after the command*/
7740 if (NULL == inPtr)
7741 {
7742 return -EINVAL;
7743 }
7744
7745 /*no space after the command*/
7746 else if (SPACE_ASCII_VALUE != *inPtr)
7747 {
7748 return -EINVAL;
7749 }
7750
7751 /*removing empty spaces*/
Jeff Johnsona1f9afb2013-04-03 09:13:31 -07007752 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
Srinivas Girigowdade697412013-02-14 16:31:48 -08007753
7754 /*no argument followed by spaces*/
7755 if ('\0' == *inPtr)
7756 {
7757 return -EINVAL;
7758 }
7759
7760 /*getting the first argument ie the number of channels*/
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08007761 v = sscanf(inPtr, "%31s ", buf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07007762 if (1 != v) return -EINVAL;
7763
Srinivas Girigowdade697412013-02-14 16:31:48 -08007764 v = kstrtos32(buf, 10, &tempInt);
Jeff Johnsona1f9afb2013-04-03 09:13:31 -07007765 if ((v < 0) ||
7766 (tempInt <= 0) ||
7767 (tempInt > WNI_CFG_VALID_CHANNEL_LIST_LEN))
7768 {
7769 return -EINVAL;
7770 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08007771
7772 *pNumChannels = tempInt;
7773
7774 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
7775 "Number of channels are: %d", *pNumChannels);
7776
7777 for (j = 0; j < (*pNumChannels); j++)
7778 {
7779 /*inPtr pointing to the beginning of first space after number of channels*/
7780 inPtr = strpbrk( inPtr, " " );
7781 /*no channel list after the number of channels argument*/
7782 if (NULL == inPtr)
7783 {
Srinivas Girigowdacf9a9b42013-03-21 11:55:24 -07007784 if (0 != j)
7785 {
7786 *pNumChannels = j;
7787 return VOS_STATUS_SUCCESS;
7788 }
7789 else
7790 {
7791 return -EINVAL;
7792 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08007793 }
7794
7795 /*removing empty space*/
Jeff Johnsona1f9afb2013-04-03 09:13:31 -07007796 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
Srinivas Girigowdade697412013-02-14 16:31:48 -08007797
7798 /*no channel list after the number of channels argument and spaces*/
7799 if ( '\0' == *inPtr )
7800 {
Srinivas Girigowdacf9a9b42013-03-21 11:55:24 -07007801 if (0 != j)
7802 {
7803 *pNumChannels = j;
7804 return VOS_STATUS_SUCCESS;
7805 }
7806 else
7807 {
7808 return -EINVAL;
7809 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08007810 }
7811
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08007812 v = sscanf(inPtr, "%31s ", buf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07007813 if (1 != v) return -EINVAL;
7814
Srinivas Girigowdade697412013-02-14 16:31:48 -08007815 v = kstrtos32(buf, 10, &tempInt);
Jeff Johnsona1f9afb2013-04-03 09:13:31 -07007816 if ((v < 0) ||
7817 (tempInt <= 0) ||
7818 (tempInt > WNI_CFG_CURRENT_CHANNEL_STAMAX))
7819 {
7820 return -EINVAL;
7821 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08007822 pChannelList[j] = tempInt;
7823
7824 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
7825 "Channel %d added to preferred channel list",
7826 pChannelList[j] );
7827 }
7828
Srinivas Girigowdade697412013-02-14 16:31:48 -08007829 return VOS_STATUS_SUCCESS;
7830}
7831
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07007832
Selvaraj, Sridhar5aff1ed2016-06-18 01:26:23 +05307833/**
7834 * hdd_parse_reassoc_command_v1_data() - HDD Parse reassoc command data
7835 * This function parses the reasoc command data passed in the format
7836 * REASSOC<space><bssid><space><channel>
7837 *
7838 * @pValue: Pointer to input data (its a NUL terminated string)
7839 * @pTargetApBssid: Pointer to target Ap bssid
7840 * @pChannel: Pointer to the Target AP channel
7841 *
7842 * Return: 0 for success non-zero for failure
7843 */
7844static int hdd_parse_reassoc_command_v1_data(const tANI_U8 *pValue,
7845 tANI_U8 *pTargetApBssid, tANI_U8 *pChannel)
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07007846{
Selvaraj, Sridhar5aff1ed2016-06-18 01:26:23 +05307847 const tANI_U8 *inPtr = pValue;
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07007848 int tempInt;
7849 int v = 0;
7850 tANI_U8 tempBuf[32];
Kiet Lamaa8e15a2014-02-11 23:30:06 -08007851 /* 12 hexa decimal digits, 5 ':' and '\0' */
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08007852 tANI_U8 macAddress[18];
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07007853
7854 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
7855 /*no argument after the command*/
7856 if (NULL == inPtr)
7857 {
7858 return -EINVAL;
7859 }
7860
7861 /*no space after the command*/
7862 else if (SPACE_ASCII_VALUE != *inPtr)
7863 {
7864 return -EINVAL;
7865 }
7866
7867 /*removing empty spaces*/
7868 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
7869
7870 /*no argument followed by spaces*/
7871 if ('\0' == *inPtr)
7872 {
7873 return -EINVAL;
7874 }
7875
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07007876 v = sscanf(inPtr, "%17s", macAddress);
7877 if (!((1 == v) && hdd_is_valid_mac_address(macAddress)))
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07007878 {
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07007879 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7880 "Invalid MAC address or All hex inputs are not read (%d)", v);
7881 return -EINVAL;
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07007882 }
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07007883
7884 pTargetApBssid[0] = hdd_parse_hex(macAddress[0]) << 4 | hdd_parse_hex(macAddress[1]);
7885 pTargetApBssid[1] = hdd_parse_hex(macAddress[3]) << 4 | hdd_parse_hex(macAddress[4]);
7886 pTargetApBssid[2] = hdd_parse_hex(macAddress[6]) << 4 | hdd_parse_hex(macAddress[7]);
7887 pTargetApBssid[3] = hdd_parse_hex(macAddress[9]) << 4 | hdd_parse_hex(macAddress[10]);
7888 pTargetApBssid[4] = hdd_parse_hex(macAddress[12]) << 4 | hdd_parse_hex(macAddress[13]);
7889 pTargetApBssid[5] = hdd_parse_hex(macAddress[15]) << 4 | hdd_parse_hex(macAddress[16]);
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07007890
7891 /* point to the next argument */
7892 inPtr = strnchr(inPtr, strlen(inPtr), SPACE_ASCII_VALUE);
7893 /*no argument after the command*/
7894 if (NULL == inPtr) return -EINVAL;
7895
7896 /*removing empty spaces*/
7897 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
7898
7899 /*no argument followed by spaces*/
7900 if ('\0' == *inPtr)
7901 {
7902 return -EINVAL;
7903 }
7904
7905 /*getting the next argument ie the channel number */
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08007906 v = sscanf(inPtr, "%31s ", tempBuf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07007907 if (1 != v) return -EINVAL;
7908
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07007909 v = kstrtos32(tempBuf, 10, &tempInt);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07007910 if ((v < 0) ||
Padma, Santhosh Kumar0fa809b2014-11-13 14:56:56 +05307911 (tempInt < 0) ||
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07007912 (tempInt > WNI_CFG_CURRENT_CHANNEL_STAMAX))
7913 {
7914 return -EINVAL;
7915 }
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07007916
7917 *pChannel = tempInt;
7918 return VOS_STATUS_SUCCESS;
7919}
7920
7921#endif
7922
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08007923#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07007924/**---------------------------------------------------------------------------
7925
7926 \brief hdd_parse_get_cckm_ie() - HDD Parse and fetch the CCKM IE
7927
7928 This function parses the SETCCKM IE command
7929 SETCCKMIE<space><ie data>
7930
7931 \param - pValue Pointer to input data
7932 \param - pCckmIe Pointer to output cckm Ie
7933 \param - pCckmIeLen Pointer to output cckm ie length
7934
7935 \return - 0 for success non-zero for failure
7936
7937 --------------------------------------------------------------------------*/
7938VOS_STATUS hdd_parse_get_cckm_ie(tANI_U8 *pValue, tANI_U8 **pCckmIe,
7939 tANI_U8 *pCckmIeLen)
7940{
7941 tANI_U8 *inPtr = pValue;
7942 tANI_U8 *dataEnd;
7943 int j = 0;
7944 int i = 0;
7945 tANI_U8 tempByte = 0;
7946
7947 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
7948 /*no argument after the command*/
7949 if (NULL == inPtr)
7950 {
7951 return -EINVAL;
7952 }
7953
7954 /*no space after the command*/
7955 else if (SPACE_ASCII_VALUE != *inPtr)
7956 {
7957 return -EINVAL;
7958 }
7959
7960 /*removing empty spaces*/
7961 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
7962
7963 /*no argument followed by spaces*/
7964 if ('\0' == *inPtr)
7965 {
7966 return -EINVAL;
7967 }
7968
7969 /* find the length of data */
7970 dataEnd = inPtr;
7971 while(('\0' != *dataEnd) )
7972 {
7973 dataEnd++;
7974 ++(*pCckmIeLen);
7975 }
7976 if ( *pCckmIeLen <= 0) return -EINVAL;
7977
7978 /* Allocate the number of bytes based on the number of input characters
7979 whether it is even or odd.
7980 if the number of input characters are even, then we need N/2 byte.
7981 if the number of input characters are odd, then we need do (N+1)/2 to
7982 compensate rounding off.
7983 For example, if N = 18, then (18 + 1)/2 = 9 bytes are enough.
7984 If N = 19, then we need 10 bytes, hence (19 + 1)/2 = 10 bytes */
7985 *pCckmIe = vos_mem_malloc((*pCckmIeLen + 1)/2);
7986 if (NULL == *pCckmIe)
7987 {
7988 hddLog(VOS_TRACE_LEVEL_FATAL,
7989 "%s: vos_mem_alloc failed ", __func__);
7990 return -EINVAL;
7991 }
7992 vos_mem_zero(*pCckmIe, (*pCckmIeLen + 1)/2);
7993 /* the buffer received from the upper layer is character buffer,
7994 we need to prepare the buffer taking 2 characters in to a U8 hex decimal number
7995 for example 7f0000f0...form a buffer to contain 7f in 0th location, 00 in 1st
7996 and f0 in 3rd location */
7997 for (i = 0, j = 0; j < *pCckmIeLen; j += 2)
7998 {
7999 tempByte = (hdd_parse_hex(inPtr[j]) << 4) | (hdd_parse_hex(inPtr[j + 1]));
8000 (*pCckmIe)[i++] = tempByte;
8001 }
8002 *pCckmIeLen = i;
8003
8004 return VOS_STATUS_SUCCESS;
8005}
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08008006#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07008007
Jeff Johnson295189b2012-06-20 16:38:30 -07008008/**---------------------------------------------------------------------------
8009
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07008010 \brief hdd_is_valid_mac_address() - Validate MAC address
8011
8012 This function validates whether the given MAC address is valid or not
8013 Expected MAC address is of the format XX:XX:XX:XX:XX:XX
8014 where X is the hexa decimal digit character and separated by ':'
8015 This algorithm works even if MAC address is not separated by ':'
8016
8017 This code checks given input string mac contains exactly 12 hexadecimal digits.
8018 and a separator colon : appears in the input string only after
8019 an even number of hex digits.
8020
8021 \param - pMacAddr pointer to the input MAC address
8022 \return - 1 for valid and 0 for invalid
8023
8024 --------------------------------------------------------------------------*/
8025
8026v_BOOL_t hdd_is_valid_mac_address(const tANI_U8 *pMacAddr)
8027{
8028 int xdigit = 0;
8029 int separator = 0;
8030 while (*pMacAddr)
8031 {
8032 if (isxdigit(*pMacAddr))
8033 {
8034 xdigit++;
8035 }
8036 else if (':' == *pMacAddr)
8037 {
8038 if (0 == xdigit || ((xdigit / 2) - 1) != separator)
8039 break;
8040
8041 ++separator;
8042 }
8043 else
8044 {
8045 separator = -1;
8046 /* Invalid MAC found */
8047 return 0;
8048 }
8049 ++pMacAddr;
8050 }
8051 return (xdigit == 12 && (separator == 5 || separator == 0));
8052}
8053
8054/**---------------------------------------------------------------------------
8055
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05308056 \brief __hdd_open() - HDD Open function
Jeff Johnson295189b2012-06-20 16:38:30 -07008057
8058 \param - dev Pointer to net_device structure
8059
8060 \return - 0 for success non-zero for failure
8061
8062 --------------------------------------------------------------------------*/
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05308063int __hdd_open(struct net_device *dev)
Jeff Johnson295189b2012-06-20 16:38:30 -07008064{
8065 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
8066 hdd_context_t *pHddCtx;
8067 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
8068 VOS_STATUS status;
8069 v_BOOL_t in_standby = TRUE;
8070
Arun Kumar Khandavalli2225e3b2020-08-03 10:23:22 +05308071 if (NULL == pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07008072 {
8073 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Agarwal Ashish971c2882013-10-30 20:11:12 +05308074 "%s: pAdapter is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07008075 return -ENODEV;
8076 }
Arun Kumar Khandavalli2225e3b2020-08-03 10:23:22 +05308077
Jeff Johnson295189b2012-06-20 16:38:30 -07008078 pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05308079 MTRACE(vos_trace(VOS_MODULE_ID_HDD, TRACE_CODE_HDD_OPEN_REQUEST,
8080 pAdapter->sessionId, pAdapter->device_mode));
Jeff Johnson295189b2012-06-20 16:38:30 -07008081 if (NULL == pHddCtx)
8082 {
8083 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008084 "%s: HDD context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07008085 return -ENODEV;
8086 }
8087
Arun Kumar Khandavalli2225e3b2020-08-03 10:23:22 +05308088
Arun Kumar Khandavalli9113aee2020-02-26 10:54:02 +05308089 if (test_bit(DEVICE_IFACE_OPENED, &pAdapter->event_flags)) {
8090 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: session already opened for the adapter",
8091 __func__);
8092 return 0;
8093 }
8094
Jeff Johnson295189b2012-06-20 16:38:30 -07008095 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
8096 while ( (NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status) )
8097 {
Jeff Johnson6a81ca42013-04-05 10:37:08 -07008098 if (test_bit(DEVICE_IFACE_OPENED, &pAdapterNode->pAdapter->event_flags))
8099 {
8100 hddLog(VOS_TRACE_LEVEL_INFO, "%s: chip already out of standby",
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05308101 __func__);
Jeff Johnson6a81ca42013-04-05 10:37:08 -07008102 in_standby = FALSE;
8103 break;
8104 }
8105 else
8106 {
8107 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
8108 pAdapterNode = pNext;
8109 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008110 }
8111
8112 if (TRUE == in_standby)
8113 {
8114 if (VOS_STATUS_SUCCESS != wlan_hdd_exit_lowpower(pHddCtx, pAdapter))
8115 {
8116 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Failed to bring "
8117 "wlan out of power save", __func__);
8118 return -EINVAL;
8119 }
8120 }
Arun Kumar Khandavalli9113aee2020-02-26 10:54:02 +05308121
8122 status = hdd_init_station_mode( pAdapter );
8123 if( VOS_STATUS_SUCCESS != status ) {
8124 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Failed to create session for station mode",
8125 __func__);
8126 return -EINVAL;
8127 }
8128
Jeff Johnson6a81ca42013-04-05 10:37:08 -07008129 set_bit(DEVICE_IFACE_OPENED, &pAdapter->event_flags);
Jeff Johnson295189b2012-06-20 16:38:30 -07008130 if (hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter)))
8131 {
8132 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008133 "%s: Enabling Tx Queues", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07008134 /* Enable TX queues only when we are connected */
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +05308135 hddLog(VOS_TRACE_LEVEL_INFO, FL("Enabling queues"));
Jeff Johnson295189b2012-06-20 16:38:30 -07008136 netif_tx_start_all_queues(dev);
8137 }
8138
8139 return 0;
8140}
8141
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05308142/**---------------------------------------------------------------------------
8143
8144 \brief hdd_open() - Wrapper function for __hdd_open to protect it from SSR
8145
8146 This is called in response to ifconfig up
8147
8148 \param - dev Pointer to net_device structure
8149
8150 \return - 0 for success non-zero for failure
8151
8152 --------------------------------------------------------------------------*/
8153int hdd_open(struct net_device *dev)
8154{
8155 int ret;
8156
8157 vos_ssr_protect(__func__);
8158 ret = __hdd_open(dev);
8159 vos_ssr_unprotect(__func__);
8160
8161 return ret;
8162}
8163
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05308164int __hdd_mon_open (struct net_device *dev)
Jeff Johnson295189b2012-06-20 16:38:30 -07008165{
8166 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +05308167 hdd_adapter_t *sta_adapter;
8168 hdd_context_t *hdd_ctx;
Jeff Johnson295189b2012-06-20 16:38:30 -07008169
8170 if(pAdapter == NULL) {
8171 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008172 "%s: HDD adapter context is Null", __func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08008173 return -EINVAL;
Jeff Johnson295189b2012-06-20 16:38:30 -07008174 }
8175
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +05308176 if (vos_get_concurrency_mode() != VOS_STA_MON)
8177 return 0;
8178
8179 hdd_ctx = WLAN_HDD_GET_CTX(pAdapter);
8180 if (wlan_hdd_validate_context(hdd_ctx))
8181 return -EINVAL;
8182
8183 sta_adapter = hdd_get_adapter(hdd_ctx, WLAN_HDD_INFRA_STATION);
8184 if (!sta_adapter) {
8185 hddLog(LOGE, FL("No valid STA interface"));
8186 return -EINVAL;
8187 }
8188
8189 if (!test_bit(DEVICE_IFACE_OPENED, &sta_adapter->event_flags)) {
8190 hddLog(LOGE, FL("STA Interface is not OPENED"));
8191 return -EINVAL;
8192 }
8193
8194 set_bit(DEVICE_IFACE_OPENED, &pAdapter->event_flags);
8195
Arun Kumar Khandavalli2225e3b2020-08-03 10:23:22 +05308196 /* Action frame registered in one adapter which will
8197 * applicable to all interfaces
8198 */
8199 wlan_hdd_cfg80211_register_frames(pAdapter);
8200
Jeff Johnson295189b2012-06-20 16:38:30 -07008201 return 0;
8202}
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05308203
8204int hdd_mon_open (struct net_device *dev)
8205{
8206 int ret;
8207
8208 vos_ssr_protect(__func__);
8209 ret = __hdd_mon_open(dev);
8210 vos_ssr_unprotect(__func__);
8211
8212 return ret;
8213}
8214
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +05308215int __hdd_mon_stop (struct net_device *dev)
8216{
8217 hdd_adapter_t *mon_adapter = WLAN_HDD_GET_PRIV_PTR(dev);
8218 hdd_context_t *hdd_ctx;
8219
8220 if (vos_get_concurrency_mode() != VOS_STA_MON)
8221 return 0;
8222
8223 if(!mon_adapter) {
8224 hddLog(LOGE, FL("HDD adapter is Null"));
8225 return -EINVAL;
8226 }
8227
8228 hdd_ctx = WLAN_HDD_GET_CTX(mon_adapter);
8229 if (wlan_hdd_validate_context(hdd_ctx))
8230 return -EINVAL;
8231
8232 if (!test_bit(DEVICE_IFACE_OPENED, &mon_adapter->event_flags)) {
8233 hddLog(LOGE, FL("NETDEV Interface is not OPENED"));
8234 return -ENODEV;
8235 }
8236
8237 clear_bit(DEVICE_IFACE_OPENED, &mon_adapter->event_flags);
8238 hdd_stop_adapter(hdd_ctx, mon_adapter, VOS_FALSE);
8239
8240 return 0;
8241}
8242
Katya Nigame7b69a82015-04-28 15:24:06 +05308243int hdd_mon_stop(struct net_device *dev)
8244{
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +05308245 int ret;
8246
8247 vos_ssr_protect(__func__);
8248 ret = __hdd_mon_stop(dev);
8249 vos_ssr_unprotect(__func__);
8250
8251 return ret;
Katya Nigame7b69a82015-04-28 15:24:06 +05308252}
8253
Jeff Johnson295189b2012-06-20 16:38:30 -07008254/**---------------------------------------------------------------------------
8255
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05308256 \brief __hdd_stop() - HDD stop function
Jeff Johnson295189b2012-06-20 16:38:30 -07008257
8258 \param - dev Pointer to net_device structure
8259
8260 \return - 0 for success non-zero for failure
8261
8262 --------------------------------------------------------------------------*/
8263
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05308264int __hdd_stop (struct net_device *dev)
Jeff Johnson295189b2012-06-20 16:38:30 -07008265{
Vinay Krishna Eranna90f43532014-10-27 16:45:54 +05308266 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07008267 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
8268 hdd_context_t *pHddCtx;
8269 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
8270 VOS_STATUS status;
8271 v_BOOL_t enter_standby = TRUE;
8272
8273 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07008274 if (NULL == pAdapter)
8275 {
8276 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Agarwal Ashish971c2882013-10-30 20:11:12 +05308277 "%s: pAdapter is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07008278 return -ENODEV;
8279 }
Sachin Ahuja9b4958f2015-01-15 21:37:00 +05308280 MTRACE(vos_trace(VOS_MODULE_ID_HDD, TRACE_CODE_HDD_STOP_REQUEST,
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05308281 pAdapter->sessionId, pAdapter->device_mode));
Vinay Krishna Eranna90f43532014-10-27 16:45:54 +05308282
8283 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8284 ret = wlan_hdd_validate_context(pHddCtx);
8285 if (ret)
Jeff Johnson295189b2012-06-20 16:38:30 -07008286 {
Vinay Krishna Eranna90f43532014-10-27 16:45:54 +05308287 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07008288 }
8289
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05308290 /* Nothing to be done if the interface is not opened */
8291 if (VOS_FALSE == test_bit(DEVICE_IFACE_OPENED, &pAdapter->event_flags))
8292 {
8293 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8294 "%s: NETDEV Interface is not OPENED", __func__);
8295 return -ENODEV;
8296 }
8297
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +05308298 if (pHddCtx->concurrency_mode == VOS_STA_MON) {
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +05308299 /*
Rajeev Kumar Sirasanagandlaa74e1222018-01-09 17:38:55 +05308300 * In STA + Monitor mode concurrency, no point in running
8301 * capture on monitor interface, when STA interface is stopped
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +05308302 */
Rajeev Kumar Sirasanagandlaa74e1222018-01-09 17:38:55 +05308303 wlan_hdd_stop_mon(pHddCtx, true);
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +05308304 }
8305
Jeff Johnson295189b2012-06-20 16:38:30 -07008306 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Disabling OS Tx queues", __func__);
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05308307
8308 /* Disable TX on the interface, after this hard_start_xmit() will not
8309 * be called on that interface
8310 */
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +05308311 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Jeff Johnson295189b2012-06-20 16:38:30 -07008312 netif_tx_disable(pAdapter->dev);
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05308313
8314 /* Mark the interface status as "down" for outside world */
Jeff Johnson295189b2012-06-20 16:38:30 -07008315 netif_carrier_off(pAdapter->dev);
8316
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05308317 /* The interface is marked as down for outside world (aka kernel)
8318 * But the driver is pretty much alive inside. The driver needs to
8319 * tear down the existing connection on the netdev (session)
8320 * cleanup the data pipes and wait until the control plane is stabilized
8321 * for this interface. The call also needs to wait until the above
8322 * mentioned actions are completed before returning to the caller.
8323 * Notice that the hdd_stop_adapter is requested not to close the session
8324 * That is intentional to be able to scan if it is a STA/P2P interface
8325 */
Arun Kumar Khandavalli9113aee2020-02-26 10:54:02 +05308326 hdd_stop_adapter(pHddCtx, pAdapter, VOS_TRUE);
8327 clear_bit(DEVICE_IFACE_OPENED, &pAdapter->event_flags);
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05308328#ifdef FEATURE_WLAN_TDLS
8329 mutex_lock(&pHddCtx->tdls_lock);
8330#endif
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05308331 /* DeInit the adapter. This ensures datapath cleanup as well */
c_hpothu002231a2015-02-05 14:58:51 +05308332 hdd_deinit_adapter(pHddCtx, pAdapter, TRUE);
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05308333#ifdef FEATURE_WLAN_TDLS
8334 mutex_unlock(&pHddCtx->tdls_lock);
8335#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008336 /* SoftAP ifaces should never go in power save mode
8337 making sure same here. */
8338 if ( (WLAN_HDD_SOFTAP == pAdapter->device_mode )
Jeff Johnson295189b2012-06-20 16:38:30 -07008339 || (WLAN_HDD_P2P_GO == pAdapter->device_mode )
Jeff Johnson295189b2012-06-20 16:38:30 -07008340 )
8341 {
8342 /* SoftAP mode, so return from here */
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308343 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8344 "%s: In SAP MODE", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07008345 EXIT();
8346 return 0;
8347 }
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05308348 /* Find if any iface is up. If any iface is up then can't put device to
8349 * sleep/power save mode
8350 */
Jeff Johnson295189b2012-06-20 16:38:30 -07008351 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
8352 while ( (NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status) )
8353 {
Jeff Johnson6a81ca42013-04-05 10:37:08 -07008354 if (test_bit(DEVICE_IFACE_OPENED, &pAdapterNode->pAdapter->event_flags))
8355 {
8356 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Still other ifaces are up cannot "
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05308357 "put device to sleep", __func__);
Jeff Johnson6a81ca42013-04-05 10:37:08 -07008358 enter_standby = FALSE;
8359 break;
8360 }
8361 else
8362 {
8363 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
8364 pAdapterNode = pNext;
8365 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008366 }
8367
8368 if (TRUE == enter_standby)
8369 {
8370 hddLog(VOS_TRACE_LEVEL_INFO, "%s: All Interfaces are Down "
8371 "entering standby", __func__);
8372 if (VOS_STATUS_SUCCESS != wlan_hdd_enter_lowpower(pHddCtx))
8373 {
8374 /*log and return success*/
8375 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Failed to put "
8376 "wlan in power save", __func__);
8377 }
8378 }
Hanumanth Reddy Pothula972e1df2018-06-14 13:33:47 +05308379
Arun Kumar Khandavalli9113aee2020-02-26 10:54:02 +05308380 pAdapter->dev->wireless_handlers = NULL;
8381
Hanumanth Reddy Pothula972e1df2018-06-14 13:33:47 +05308382 /*
8383 * Upon wifi turn off, DUT has to flush the scan results so if
8384 * this is the last cli iface, flush the scan database.
8385 */
8386 if (!hdd_is_cli_iface_up(pHddCtx))
8387 sme_ScanFlushResult(pHddCtx->hHal, 0);
Arun Kumar Khandavalli9113aee2020-02-26 10:54:02 +05308388
Jeff Johnson295189b2012-06-20 16:38:30 -07008389 EXIT();
8390 return 0;
8391}
8392
8393/**---------------------------------------------------------------------------
8394
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05308395 \brief hdd_stop() - wrapper_function for __hdd_stop to protect it from SSR
Jeff Johnson295189b2012-06-20 16:38:30 -07008396
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05308397 This is called in response to ifconfig down
8398
8399 \param - dev Pointer to net_device structure
8400
8401 \return - 0 for success non-zero for failure
8402-----------------------------------------------------------------------------*/
8403int hdd_stop (struct net_device *dev)
8404{
8405 int ret;
8406
8407 vos_ssr_protect(__func__);
8408 ret = __hdd_stop(dev);
8409 vos_ssr_unprotect(__func__);
8410
8411 return ret;
8412}
8413
8414/**---------------------------------------------------------------------------
8415
8416 \brief __hdd_uninit() - HDD uninit function
Jeff Johnson295189b2012-06-20 16:38:30 -07008417
8418 \param - dev Pointer to net_device structure
8419
8420 \return - void
8421
8422 --------------------------------------------------------------------------*/
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05308423static void __hdd_uninit (struct net_device *dev)
Jeff Johnson295189b2012-06-20 16:38:30 -07008424{
8425 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05308426 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07008427 ENTER();
8428
8429 do
8430 {
8431 if (NULL == pAdapter)
8432 {
8433 hddLog(VOS_TRACE_LEVEL_FATAL,
8434 "%s: NULL pAdapter", __func__);
8435 break;
8436 }
8437
8438 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
8439 {
8440 hddLog(VOS_TRACE_LEVEL_FATAL,
8441 "%s: Invalid magic", __func__);
8442 break;
8443 }
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05308444 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8445 if (NULL == pHddCtx)
Jeff Johnson295189b2012-06-20 16:38:30 -07008446 {
8447 hddLog(VOS_TRACE_LEVEL_FATAL,
8448 "%s: NULL pHddCtx", __func__);
8449 break;
8450 }
8451
8452 if (dev != pAdapter->dev)
8453 {
8454 hddLog(VOS_TRACE_LEVEL_FATAL,
8455 "%s: Invalid device reference", __func__);
8456 /* we haven't validated all cases so let this go for now */
8457 }
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05308458#ifdef FEATURE_WLAN_TDLS
8459 mutex_lock(&pHddCtx->tdls_lock);
8460#endif
c_hpothu002231a2015-02-05 14:58:51 +05308461 hdd_deinit_adapter(pHddCtx, pAdapter, TRUE);
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05308462#ifdef FEATURE_WLAN_TDLS
8463 mutex_unlock(&pHddCtx->tdls_lock);
8464#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008465
8466 /* after uninit our adapter structure will no longer be valid */
8467 pAdapter->dev = NULL;
8468 pAdapter->magic = 0;
Manjeet Singh47ee8472016-04-11 11:57:18 +05308469 pAdapter->pHddCtx = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07008470 } while (0);
8471
8472 EXIT();
8473}
8474
8475/**---------------------------------------------------------------------------
8476
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05308477 \brief hdd_uninit() - Wrapper function to protect __hdd_uninit from SSR
8478
8479 This is called during the netdev unregister to uninitialize all data
8480associated with the device
8481
8482 \param - dev Pointer to net_device structure
8483
8484 \return - void
8485
8486 --------------------------------------------------------------------------*/
8487static void hdd_uninit (struct net_device *dev)
8488{
8489 vos_ssr_protect(__func__);
8490 __hdd_uninit(dev);
8491 vos_ssr_unprotect(__func__);
8492}
8493
8494/**---------------------------------------------------------------------------
8495
Jeff Johnson295189b2012-06-20 16:38:30 -07008496 \brief hdd_release_firmware() -
8497
8498 This function calls the release firmware API to free the firmware buffer.
8499
8500 \param - pFileName Pointer to the File Name.
8501 pCtx - Pointer to the adapter .
8502
8503
8504 \return - 0 for success, non zero for failure
8505
8506 --------------------------------------------------------------------------*/
8507
8508VOS_STATUS hdd_release_firmware(char *pFileName,v_VOID_t *pCtx)
8509{
8510 VOS_STATUS status = VOS_STATUS_SUCCESS;
8511 hdd_context_t *pHddCtx = (hdd_context_t*)pCtx;
8512 ENTER();
8513
8514
8515 if (!strcmp(WLAN_FW_FILE, pFileName)) {
8516
8517 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,"%s: Loaded firmware file is %s",__func__,pFileName);
8518
8519 if(pHddCtx->fw) {
8520 release_firmware(pHddCtx->fw);
8521 pHddCtx->fw = NULL;
8522 }
8523 else
8524 status = VOS_STATUS_E_FAILURE;
8525 }
8526 else if (!strcmp(WLAN_NV_FILE,pFileName)) {
8527 if(pHddCtx->nv) {
8528 release_firmware(pHddCtx->nv);
8529 pHddCtx->nv = NULL;
8530 }
8531 else
8532 status = VOS_STATUS_E_FAILURE;
8533
8534 }
8535
8536 EXIT();
8537 return status;
8538}
8539
8540/**---------------------------------------------------------------------------
8541
8542 \brief hdd_request_firmware() -
8543
8544 This function reads the firmware file using the request firmware
8545 API and returns the the firmware data and the firmware file size.
8546
8547 \param - pfileName - Pointer to the file name.
8548 - pCtx - Pointer to the adapter .
8549 - ppfw_data - Pointer to the pointer of the firmware data.
8550 - pSize - Pointer to the file size.
8551
8552 \return - VOS_STATUS_SUCCESS for success, VOS_STATUS_E_FAILURE for failure
8553
8554 --------------------------------------------------------------------------*/
8555
8556
8557VOS_STATUS hdd_request_firmware(char *pfileName,v_VOID_t *pCtx,v_VOID_t **ppfw_data, v_SIZE_t *pSize)
8558{
8559 int status;
8560 VOS_STATUS retval = VOS_STATUS_SUCCESS;
8561 hdd_context_t *pHddCtx = (hdd_context_t*)pCtx;
8562 ENTER();
8563
8564 if( (!strcmp(WLAN_FW_FILE, pfileName)) ) {
8565
8566 status = request_firmware(&pHddCtx->fw, pfileName, pHddCtx->parent_dev);
8567
8568 if(status || !pHddCtx->fw || !pHddCtx->fw->data) {
8569 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Firmware %s download failed",
8570 __func__, pfileName);
8571 retval = VOS_STATUS_E_FAILURE;
8572 }
8573
8574 else {
8575 *ppfw_data = (v_VOID_t *)pHddCtx->fw->data;
8576 *pSize = pHddCtx->fw->size;
8577 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Firmware size = %d",
8578 __func__, *pSize);
8579 }
8580 }
8581 else if(!strcmp(WLAN_NV_FILE, pfileName)) {
8582
8583 status = request_firmware(&pHddCtx->nv, pfileName, pHddCtx->parent_dev);
8584
8585 if(status || !pHddCtx->nv || !pHddCtx->nv->data) {
8586 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: nv %s download failed",
8587 __func__, pfileName);
8588 retval = VOS_STATUS_E_FAILURE;
8589 }
8590
8591 else {
8592 *ppfw_data = (v_VOID_t *)pHddCtx->nv->data;
8593 *pSize = pHddCtx->nv->size;
8594 hddLog(VOS_TRACE_LEVEL_INFO, "%s: nv file size = %d",
8595 __func__, *pSize);
8596 }
8597 }
8598
8599 EXIT();
8600 return retval;
8601}
8602/**---------------------------------------------------------------------------
8603 \brief hdd_full_pwr_cbk() - HDD full power callbackfunction
8604
8605 This is the function invoked by SME to inform the result of a full power
8606 request issued by HDD
8607
8608 \param - callbackcontext - Pointer to cookie
8609 status - result of request
8610
8611 \return - None
8612
8613--------------------------------------------------------------------------*/
8614void hdd_full_pwr_cbk(void *callbackContext, eHalStatus status)
8615{
8616 hdd_context_t *pHddCtx = (hdd_context_t*)callbackContext;
8617
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07008618 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,"HDD full Power callback status = %d", status);
Jeff Johnson295189b2012-06-20 16:38:30 -07008619 if(&pHddCtx->full_pwr_comp_var)
8620 {
8621 complete(&pHddCtx->full_pwr_comp_var);
8622 }
8623}
8624
Abhishek Singh00b71972016-01-07 10:51:04 +05308625#ifdef WLAN_FEATURE_RMC
8626static void hdd_tx_fail_ind_callback(v_U8_t *MacAddr, v_U8_t seqNo)
8627{
8628 int payload_len;
8629 struct sk_buff *skb;
8630 struct nlmsghdr *nlh;
8631 v_U8_t *data;
8632
8633 payload_len = ETH_ALEN;
8634
8635 if (0 == cesium_pid)
8636 {
8637 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: cesium process not registered",
8638 __func__);
8639 return;
8640 }
8641
8642 if ((skb = nlmsg_new(payload_len,GFP_ATOMIC)) == NULL)
8643 {
8644 hddLog(VOS_TRACE_LEVEL_ERROR,
8645 "%s: nlmsg_new() failed for msg size[%d]",
8646 __func__, NLMSG_SPACE(payload_len));
8647 return;
8648 }
8649
8650 nlh = nlmsg_put(skb, cesium_pid, seqNo, 0, payload_len, NLM_F_REQUEST);
8651
8652 if (NULL == nlh)
8653 {
8654 hddLog(VOS_TRACE_LEVEL_ERROR,
8655 "%s: nlmsg_put() failed for msg size[%d]",
8656 __func__, NLMSG_SPACE(payload_len));
8657
8658 kfree_skb(skb);
8659 return;
8660 }
8661
8662 data = nlmsg_data(nlh);
8663 memcpy(data, MacAddr, ETH_ALEN);
8664
8665 if (nlmsg_unicast(cesium_nl_srv_sock, skb, cesium_pid) < 0)
8666 {
8667 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: nlmsg_unicast() failed for msg size[%d]",
8668 __func__, NLMSG_SPACE(payload_len));
8669 }
8670
8671 return;
8672}
8673
8674/**---------------------------------------------------------------------------
8675 \brief hdd_ParseuserParams - return a pointer to the next argument
8676
8677 \return - status
8678
8679--------------------------------------------------------------------------*/
8680static int hdd_ParseUserParams(tANI_U8 *pValue, tANI_U8 **ppArg)
8681{
8682 tANI_U8 *pVal;
8683
8684 pVal = strchr(pValue, ' ');
8685
8686 if (NULL == pVal)
8687 {
8688 /* no argument remains */
8689 return -EINVAL;
8690 }
8691 else if (SPACE_ASCII_VALUE != *pVal)
8692 {
8693 /* no space after the current argument */
8694 return -EINVAL;
8695 }
8696
8697 pVal++;
8698
8699 /* remove empty spaces */
8700 while ((SPACE_ASCII_VALUE == *pVal) && ('\0' != *pVal))
8701 {
8702 pVal++;
8703 }
8704
8705 /* no argument followed by spaces */
8706 if ('\0' == *pVal)
8707 {
8708 return -EINVAL;
8709 }
8710
8711 *ppArg = pVal;
8712
8713 return 0;
8714}
8715
8716/**----------------------------------------------------------------------------
8717 \brief hdd_ParseIBSSTXFailEventParams - Parse params for SETIBSSTXFAILEVENT
8718
8719 \return - status
8720
8721------------------------------------------------------------------------------*/
8722static int hdd_ParseIBSSTXFailEventParams(tANI_U8 *pValue,
8723 tANI_U8 *tx_fail_count,
8724 tANI_U16 *pid)
8725{
8726 tANI_U8 *param = NULL;
8727 int ret;
8728
8729 ret = hdd_ParseUserParams(pValue, &param);
8730
8731 if (0 == ret && NULL != param)
8732 {
8733 if (1 != sscanf(param, "%hhu", tx_fail_count))
8734 {
8735 ret = -EINVAL;
8736 goto done;
8737 }
8738 }
8739 else
8740 {
8741 goto done;
8742 }
8743
8744 if (0 == *tx_fail_count)
8745 {
8746 *pid = 0;
8747 goto done;
8748 }
8749
8750 pValue = param;
8751 pValue++;
8752
8753 ret = hdd_ParseUserParams(pValue, &param);
8754
8755 if (0 == ret)
8756 {
8757 if (1 != sscanf(param, "%hu", pid))
8758 {
8759 ret = -EINVAL;
8760 goto done;
8761 }
8762 }
8763 else
8764 {
8765 goto done;
8766 }
8767
8768done:
8769 return ret;
8770}
8771
8772static int hdd_open_cesium_nl_sock()
8773{
8774#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
8775 struct netlink_kernel_cfg cfg = {
8776 .groups = WLAN_NLINK_MCAST_GRP_ID,
8777 .input = NULL
8778 };
8779#endif
8780 int ret = 0;
8781
8782#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
8783 cesium_nl_srv_sock = netlink_kernel_create(&init_net, WLAN_NLINK_CESIUM,
8784#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,7,0))
8785 THIS_MODULE,
8786#endif
8787 &cfg);
8788#else
8789 cesium_nl_srv_sock = netlink_kernel_create(&init_net, WLAN_NLINK_CESIUM,
8790 WLAN_NLINK_MCAST_GRP_ID, NULL, NULL, THIS_MODULE);
8791#endif
8792
8793 if (cesium_nl_srv_sock == NULL)
8794 {
8795 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8796 "NLINK: cesium netlink_kernel_create failed");
8797 ret = -ECONNREFUSED;
8798 }
8799
8800 return ret;
8801}
8802
8803static void hdd_close_cesium_nl_sock()
8804{
8805 if (NULL != cesium_nl_srv_sock)
8806 {
8807 netlink_kernel_release(cesium_nl_srv_sock);
8808 cesium_nl_srv_sock = NULL;
8809 }
8810}
8811#endif /* WLAN_FEATURE_RMC */
Jeff Johnson295189b2012-06-20 16:38:30 -07008812/**---------------------------------------------------------------------------
8813
8814 \brief hdd_req_bmps_cbk() - HDD Request BMPS callback function
8815
8816 This is the function invoked by SME to inform the result of BMPS
8817 request issued by HDD
8818
8819 \param - callbackcontext - Pointer to cookie
8820 status - result of request
8821
8822 \return - None
8823
8824--------------------------------------------------------------------------*/
8825void hdd_req_bmps_cbk(void *callbackContext, eHalStatus status)
8826{
8827
8828 struct completion *completion_var = (struct completion*) callbackContext;
8829
Arif Hussain6d2a3322013-11-17 19:50:10 -08008830 hddLog(VOS_TRACE_LEVEL_ERROR, "HDD BMPS request Callback, status = %d", status);
Jeff Johnson295189b2012-06-20 16:38:30 -07008831 if(completion_var != NULL)
8832 {
8833 complete(completion_var);
8834 }
8835}
8836
8837/**---------------------------------------------------------------------------
8838
8839 \brief hdd_get_cfg_file_size() -
8840
8841 This function reads the configuration file using the request firmware
8842 API and returns the configuration file size.
8843
8844 \param - pCtx - Pointer to the adapter .
8845 - pFileName - Pointer to the file name.
8846 - pBufSize - Pointer to the buffer size.
8847
8848 \return - 0 for success, non zero for failure
8849
8850 --------------------------------------------------------------------------*/
8851
8852VOS_STATUS hdd_get_cfg_file_size(v_VOID_t *pCtx, char *pFileName, v_SIZE_t *pBufSize)
8853{
8854 int status;
8855 hdd_context_t *pHddCtx = (hdd_context_t*)pCtx;
8856
8857 ENTER();
8858
8859 status = request_firmware(&pHddCtx->fw, pFileName, pHddCtx->parent_dev);
8860
8861 if(status || !pHddCtx->fw || !pHddCtx->fw->data) {
8862 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: CFG download failed",__func__);
8863 status = VOS_STATUS_E_FAILURE;
8864 }
8865 else {
8866 *pBufSize = pHddCtx->fw->size;
8867 hddLog(VOS_TRACE_LEVEL_INFO, "%s: CFG size = %d", __func__, *pBufSize);
8868 release_firmware(pHddCtx->fw);
8869 pHddCtx->fw = NULL;
8870 }
8871
8872 EXIT();
8873 return VOS_STATUS_SUCCESS;
8874}
8875
8876/**---------------------------------------------------------------------------
8877
8878 \brief hdd_read_cfg_file() -
8879
8880 This function reads the configuration file using the request firmware
8881 API and returns the cfg data and the buffer size of the configuration file.
8882
8883 \param - pCtx - Pointer to the adapter .
8884 - pFileName - Pointer to the file name.
8885 - pBuffer - Pointer to the data buffer.
8886 - pBufSize - Pointer to the buffer size.
8887
8888 \return - 0 for success, non zero for failure
8889
8890 --------------------------------------------------------------------------*/
8891
8892VOS_STATUS hdd_read_cfg_file(v_VOID_t *pCtx, char *pFileName,
8893 v_VOID_t *pBuffer, v_SIZE_t *pBufSize)
8894{
8895 int status;
8896 hdd_context_t *pHddCtx = (hdd_context_t*)pCtx;
8897
8898 ENTER();
8899
8900 status = request_firmware(&pHddCtx->fw, pFileName, pHddCtx->parent_dev);
8901
8902 if(status || !pHddCtx->fw || !pHddCtx->fw->data) {
8903 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: CFG download failed",__func__);
8904 return VOS_STATUS_E_FAILURE;
8905 }
8906 else {
8907 if(*pBufSize != pHddCtx->fw->size) {
8908 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Caller sets invalid CFG "
8909 "file size", __func__);
8910 release_firmware(pHddCtx->fw);
8911 pHddCtx->fw = NULL;
8912 return VOS_STATUS_E_FAILURE;
8913 }
8914 else {
8915 if(pBuffer) {
8916 vos_mem_copy(pBuffer,pHddCtx->fw->data,*pBufSize);
8917 }
8918 release_firmware(pHddCtx->fw);
8919 pHddCtx->fw = NULL;
8920 }
8921 }
8922
8923 EXIT();
8924
8925 return VOS_STATUS_SUCCESS;
8926}
8927
8928/**---------------------------------------------------------------------------
8929
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05308930 \brief __hdd_set_mac_address() -
Jeff Johnson295189b2012-06-20 16:38:30 -07008931
8932 This function sets the user specified mac address using
8933 the command ifconfig wlanX hw ether <mac adress>.
8934
8935 \param - dev - Pointer to the net device.
8936 - addr - Pointer to the sockaddr.
8937 \return - 0 for success, non zero for failure
8938
8939 --------------------------------------------------------------------------*/
8940
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05308941static int __hdd_set_mac_address(struct net_device *dev, void *addr)
Jeff Johnson295189b2012-06-20 16:38:30 -07008942{
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05308943 hdd_adapter_t *pAdapter;
Arun Kumar Khandavalli18303eb2020-01-22 20:44:09 +05308944 hdd_adapter_t *adapter_temp;
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05308945 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07008946 struct sockaddr *psta_mac_addr = addr;
Arun Kumar Khandavalli18303eb2020-01-22 20:44:09 +05308947 int ret = 0, i;
8948 v_MACADDR_t mac_addr;
Jeff Johnson295189b2012-06-20 16:38:30 -07008949
8950 ENTER();
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05308951 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
8952 if (NULL == pAdapter)
8953 {
8954 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8955 "%s: Adapter is NULL",__func__);
8956 return -EINVAL;
8957 }
8958 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8959 ret = wlan_hdd_validate_context(pHddCtx);
8960 if (0 != ret)
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05308961 return ret;
Arun Kumar Khandavalli18303eb2020-01-22 20:44:09 +05308962
8963 memcpy(&mac_addr, psta_mac_addr->sa_data, sizeof(mac_addr));
8964 if(vos_is_macaddr_zero(&mac_addr)) {
8965 hddLog(VOS_TRACE_LEVEL_ERROR, "Zero Mac address");
8966 return -EINVAL;
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05308967 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008968
Arun Kumar Khandavalli18303eb2020-01-22 20:44:09 +05308969 if (vos_is_macaddr_broadcast(&mac_addr)) {
8970 hddLog(VOS_TRACE_LEVEL_ERROR,"MAC is Broadcast");
8971 return -EINVAL;
8972 }
8973
8974 if (vos_is_macaddr_multicast(&mac_addr)) {
8975 hddLog(VOS_TRACE_LEVEL_ERROR, "Multicast Mac address");
8976 return -EINVAL;
8977 }
8978 adapter_temp = hdd_get_adapter_by_macaddr(pHddCtx, mac_addr.bytes);
8979 if (adapter_temp) {
8980 if (!strcmp(adapter_temp->dev->name, dev->name))
8981 return 0;
8982 hddLog(VOS_TRACE_LEVEL_ERROR,
8983 "%s: WLAN Mac Addr: "
8984 MAC_ADDRESS_STR, __func__,
8985 MAC_ADDR_ARRAY(mac_addr.bytes));
8986 return -EINVAL;
8987 }
8988
8989 for (i = 0; i < VOS_MAX_CONCURRENCY_PERSONA; i++) {
8990 if (!vos_mem_compare(&pAdapter->macAddressCurrent.bytes,
8991 &pHddCtx->cfg_ini->intfMacAddr[i].bytes[0], VOS_MAC_ADDR_SIZE)) {
8992 memcpy(&pHddCtx->cfg_ini->intfMacAddr[i].bytes[0], mac_addr.bytes,
8993 VOS_MAC_ADDR_SIZE);
8994 break;
8995 }
8996 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008997 memcpy(&pAdapter->macAddressCurrent, psta_mac_addr->sa_data, ETH_ALEN);
Jeff Johnson295189b2012-06-20 16:38:30 -07008998 memcpy(dev->dev_addr, psta_mac_addr->sa_data, ETH_ALEN);
8999
9000 EXIT();
Arun Kumar Khandavalli18303eb2020-01-22 20:44:09 +05309001 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07009002}
9003
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05309004/**---------------------------------------------------------------------------
9005
9006 \brief hdd_set_mac_address() -
9007
9008 Wrapper function to protect __hdd_set_mac_address() function from ssr
9009
9010 \param - dev - Pointer to the net device.
9011 - addr - Pointer to the sockaddr.
9012 \return - 0 for success, non zero for failure
9013
9014 --------------------------------------------------------------------------*/
9015static int hdd_set_mac_address(struct net_device *dev, void *addr)
9016{
9017 int ret;
9018
9019 vos_ssr_protect(__func__);
9020 ret = __hdd_set_mac_address(dev, addr);
9021 vos_ssr_unprotect(__func__);
9022
9023 return ret;
9024}
9025
Jeff Johnson295189b2012-06-20 16:38:30 -07009026tANI_U8* wlan_hdd_get_intf_addr(hdd_context_t* pHddCtx)
9027{
9028 int i;
9029 for ( i = 0; i < VOS_MAX_CONCURRENCY_PERSONA; i++)
9030 {
Abhishek Singheb183782014-02-06 13:37:21 +05309031 if( 0 == ((pHddCtx->cfg_ini->intfAddrMask) & (1 << i)) )
Jeff Johnson295189b2012-06-20 16:38:30 -07009032 break;
9033 }
9034
9035 if( VOS_MAX_CONCURRENCY_PERSONA == i)
9036 return NULL;
9037
9038 pHddCtx->cfg_ini->intfAddrMask |= (1 << i);
9039 return &pHddCtx->cfg_ini->intfMacAddr[i].bytes[0];
9040}
9041
9042void wlan_hdd_release_intf_addr(hdd_context_t* pHddCtx, tANI_U8* releaseAddr)
9043{
9044 int i;
9045 for ( i = 0; i < VOS_MAX_CONCURRENCY_PERSONA; i++)
9046 {
9047 if ( !memcmp(releaseAddr, &pHddCtx->cfg_ini->intfMacAddr[i].bytes[0], 6) )
9048 {
9049 pHddCtx->cfg_ini->intfAddrMask &= ~(1 << i);
9050 break;
9051 }
9052 }
9053 return;
9054}
9055
9056#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29))
9057 static struct net_device_ops wlan_drv_ops = {
9058 .ndo_open = hdd_open,
9059 .ndo_stop = hdd_stop,
9060 .ndo_uninit = hdd_uninit,
9061 .ndo_start_xmit = hdd_hard_start_xmit,
9062 .ndo_tx_timeout = hdd_tx_timeout,
9063 .ndo_get_stats = hdd_stats,
9064 .ndo_do_ioctl = hdd_ioctl,
9065 .ndo_set_mac_address = hdd_set_mac_address,
9066 .ndo_select_queue = hdd_select_queue,
9067#ifdef WLAN_FEATURE_PACKET_FILTERING
9068#if (LINUX_VERSION_CODE > KERNEL_VERSION(3,1,0))
9069 .ndo_set_rx_mode = hdd_set_multicast_list,
9070#else
9071 .ndo_set_multicast_list = hdd_set_multicast_list,
9072#endif //LINUX_VERSION_CODE
9073#endif
9074 };
Jeff Johnson295189b2012-06-20 16:38:30 -07009075 static struct net_device_ops wlan_mon_drv_ops = {
9076 .ndo_open = hdd_mon_open,
Katya Nigame7b69a82015-04-28 15:24:06 +05309077 .ndo_stop = hdd_mon_stop,
Jeff Johnson295189b2012-06-20 16:38:30 -07009078 .ndo_uninit = hdd_uninit,
9079 .ndo_start_xmit = hdd_mon_hard_start_xmit,
9080 .ndo_tx_timeout = hdd_tx_timeout,
9081 .ndo_get_stats = hdd_stats,
Katya Nigame7b69a82015-04-28 15:24:06 +05309082 .ndo_do_ioctl = hdd_mon_ioctl,
Jeff Johnson295189b2012-06-20 16:38:30 -07009083 .ndo_set_mac_address = hdd_set_mac_address,
9084 };
Mahesh A Saptasagar305e2632015-03-04 12:57:33 +05309085
Jeff Johnson295189b2012-06-20 16:38:30 -07009086#endif
9087
9088void hdd_set_station_ops( struct net_device *pWlanDev )
9089{
9090#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29))
Jeff Johnson295189b2012-06-20 16:38:30 -07009091 pWlanDev->netdev_ops = &wlan_drv_ops;
9092#else
9093 pWlanDev->open = hdd_open;
9094 pWlanDev->stop = hdd_stop;
9095 pWlanDev->uninit = hdd_uninit;
9096 pWlanDev->hard_start_xmit = NULL;
9097 pWlanDev->tx_timeout = hdd_tx_timeout;
9098 pWlanDev->get_stats = hdd_stats;
9099 pWlanDev->do_ioctl = hdd_ioctl;
Jeff Johnson295189b2012-06-20 16:38:30 -07009100 pWlanDev->set_mac_address = hdd_set_mac_address;
9101#endif
9102}
9103
Katya Nigam1fd24402015-02-16 14:52:19 +05309104void hdd_set_ibss_ops( hdd_adapter_t *pAdapter )
9105{
9106 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29))
9107 wlan_drv_ops.ndo_start_xmit = hdd_ibss_hard_start_xmit;
9108 #else
9109 pAdapter->dev->hard_start_xmit = hdd_ibss_hard_start_xmit;
9110 #endif
9111}
9112
Jeff Johnsoneed415b2013-01-18 16:11:20 -08009113static hdd_adapter_t* hdd_alloc_station_adapter( hdd_context_t *pHddCtx, tSirMacAddr macAddr, const char* name )
Jeff Johnson295189b2012-06-20 16:38:30 -07009114{
9115 struct net_device *pWlanDev = NULL;
9116 hdd_adapter_t *pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07009117 /*
9118 * cfg80211 initialization and registration....
9119 */
Anand N Sunkadc34abbd2015-07-29 09:52:59 +05309120 pWlanDev = alloc_netdev_mq(sizeof( hdd_adapter_t ), name,
9121#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,17,0))
9122 NET_NAME_UNKNOWN,
9123#endif
9124 ether_setup, NUM_TX_QUEUES);
Jeff Johnson295189b2012-06-20 16:38:30 -07009125 if(pWlanDev != NULL)
9126 {
9127
9128 //Save the pointer to the net_device in the HDD adapter
9129 pAdapter = (hdd_adapter_t*) netdev_priv( pWlanDev );
9130
Jeff Johnson295189b2012-06-20 16:38:30 -07009131 vos_mem_zero( pAdapter, sizeof( hdd_adapter_t ) );
9132
9133 pAdapter->dev = pWlanDev;
9134 pAdapter->pHddCtx = pHddCtx;
9135 pAdapter->magic = WLAN_HDD_ADAPTER_MAGIC;
Agarwal Ashish47d18112014-08-04 19:55:07 +05309136 spin_lock_init(&pAdapter->lock_for_active_session);
Jeff Johnson295189b2012-06-20 16:38:30 -07009137
Rajeev79dbe4c2013-10-05 11:03:42 +05309138#ifdef FEATURE_WLAN_BATCH_SCAN
Rajeev79dbe4c2013-10-05 11:03:42 +05309139 pAdapter->pBatchScanRsp = NULL;
9140 pAdapter->numScanList = 0;
Rajeev Kumar20140c12013-10-21 19:39:02 -07009141 pAdapter->batchScanState = eHDD_BATCH_SCAN_STATE_STOPPED;
Kiet Lamaa8e15a2014-02-11 23:30:06 -08009142 pAdapter->prev_batch_id = 0;
Rajeev79dbe4c2013-10-05 11:03:42 +05309143 mutex_init(&pAdapter->hdd_batch_scan_lock);
9144#endif
9145
Jeff Johnson295189b2012-06-20 16:38:30 -07009146 pAdapter->isLinkUpSvcNeeded = FALSE;
9147 pAdapter->higherDtimTransition = eANI_BOOLEAN_TRUE;
9148 //Init the net_device structure
9149 strlcpy(pWlanDev->name, name, IFNAMSIZ);
9150
9151 vos_mem_copy(pWlanDev->dev_addr, (void *)macAddr, sizeof(tSirMacAddr));
9152 vos_mem_copy( pAdapter->macAddressCurrent.bytes, macAddr, sizeof(tSirMacAddr));
9153 pWlanDev->watchdog_timeo = HDD_TX_TIMEOUT;
Alok Kumar84458542018-05-14 15:03:08 +05309154
9155 pWlanDev->needed_headroom = LIBRA_HW_NEEDED_HEADROOM;
Jeff Johnson295189b2012-06-20 16:38:30 -07009156
9157 hdd_set_station_ops( pAdapter->dev );
9158
Ramanasarvesh Sadulacab51182020-05-20 17:44:27 +05309159 hdd_dev_setup_destructor(pWlanDev);
Jeff Johnson295189b2012-06-20 16:38:30 -07009160 pWlanDev->ieee80211_ptr = &pAdapter->wdev ;
9161 pAdapter->wdev.wiphy = pHddCtx->wiphy;
9162 pAdapter->wdev.netdev = pWlanDev;
Jeff Johnson295189b2012-06-20 16:38:30 -07009163 /* set pWlanDev's parent to underlying device */
9164 SET_NETDEV_DEV(pWlanDev, pHddCtx->parent_dev);
Kumar Anand82c009f2014-05-29 00:29:42 -07009165
9166 hdd_wmm_init( pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -07009167 }
9168
9169 return pAdapter;
9170}
9171
9172VOS_STATUS hdd_register_interface( hdd_adapter_t *pAdapter, tANI_U8 rtnl_lock_held )
9173{
9174 struct net_device *pWlanDev = pAdapter->dev;
9175 //hdd_station_ctx_t *pHddStaCtx = &pAdapter->sessionCtx.station;
9176 //hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
9177 //eHalStatus halStatus = eHAL_STATUS_SUCCESS;
9178
9179 if( rtnl_lock_held )
9180 {
Madan Mohan Koyyalamudid8ac8662012-11-06 19:04:56 -08009181 if (strnchr(pWlanDev->name, strlen(pWlanDev->name), '%')) {
Jeff Johnson295189b2012-06-20 16:38:30 -07009182 if( dev_alloc_name(pWlanDev, pWlanDev->name) < 0 )
9183 {
9184 hddLog(VOS_TRACE_LEVEL_ERROR,"%s:Failed:dev_alloc_name",__func__);
9185 return VOS_STATUS_E_FAILURE;
9186 }
9187 }
9188 if (register_netdevice(pWlanDev))
9189 {
9190 hddLog(VOS_TRACE_LEVEL_ERROR,"%s:Failed:register_netdev",__func__);
9191 return VOS_STATUS_E_FAILURE;
9192 }
9193 }
9194 else
9195 {
9196 if(register_netdev(pWlanDev))
9197 {
9198 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Failed:register_netdev",__func__);
9199 return VOS_STATUS_E_FAILURE;
9200 }
9201 }
9202 set_bit(NET_DEVICE_REGISTERED, &pAdapter->event_flags);
9203
9204 return VOS_STATUS_SUCCESS;
9205}
9206
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07009207static eHalStatus hdd_smeCloseSessionCallback(void *pContext)
Jeff Johnson295189b2012-06-20 16:38:30 -07009208{
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07009209 hdd_adapter_t *pAdapter = pContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07009210
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07009211 if (NULL == pAdapter)
9212 {
9213 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: NULL pAdapter", __func__);
9214 return eHAL_STATUS_INVALID_PARAMETER;
Jeff Johnson295189b2012-06-20 16:38:30 -07009215 }
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07009216
9217 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
9218 {
9219 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Invalid magic", __func__);
9220 return eHAL_STATUS_NOT_INITIALIZED;
9221 }
9222
9223 clear_bit(SME_SESSION_OPENED, &pAdapter->event_flags);
9224
Sameer Thalappilbee426e2013-10-30 10:30:30 -07009225#ifndef WLAN_OPEN_SOURCE
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07009226 /* need to make sure all of our scheduled work has completed.
9227 * This callback is called from MC thread context, so it is safe to
9228 * to call below flush workqueue API from here.
Sameer Thalappilbee426e2013-10-30 10:30:30 -07009229 *
9230 * Even though this is called from MC thread context, if there is a faulty
9231 * work item in the system, that can hang this call forever. So flushing
9232 * this global work queue is not safe; and now we make sure that
9233 * individual work queues are stopped correctly. But the cancel work queue
9234 * is a GPL only API, so the proprietary version of the driver would still
9235 * rely on the global work queue flush.
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07009236 */
9237 flush_scheduled_work();
Sameer Thalappilbee426e2013-10-30 10:30:30 -07009238#endif
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07009239
9240 /* We can be blocked while waiting for scheduled work to be
9241 * flushed, and the adapter structure can potentially be freed, in
9242 * which case the magic will have been reset. So make sure the
9243 * magic is still good, and hence the adapter structure is still
9244 * valid, before signaling completion */
9245 if (WLAN_HDD_ADAPTER_MAGIC == pAdapter->magic)
9246 {
9247 complete(&pAdapter->session_close_comp_var);
9248 }
9249
Jeff Johnson295189b2012-06-20 16:38:30 -07009250 return eHAL_STATUS_SUCCESS;
9251}
Manjeet Singh47ee8472016-04-11 11:57:18 +05309252/**
9253 * hdd_close_tx_queues() - close tx queues
9254 * @hdd_ctx: hdd global context
9255 *
9256 * Return: None
9257 */
9258static void hdd_close_tx_queues(hdd_context_t *hdd_ctx)
9259{
9260 VOS_STATUS status;
9261 hdd_adapter_t *adapter;
9262 hdd_adapter_list_node_t *adapter_node = NULL, *next_adapter = NULL;
9263 /* Not validating hdd_ctx as it's already done by the caller */
9264 ENTER();
9265 status = hdd_get_front_adapter(hdd_ctx, &adapter_node);
9266 while (NULL != adapter_node && VOS_STATUS_SUCCESS == status) {
9267 adapter = adapter_node->pAdapter;
9268 if (adapter && adapter->dev) {
9269 netif_tx_disable (adapter->dev);
9270 netif_carrier_off(adapter->dev);
9271 }
9272 status = hdd_get_next_adapter(hdd_ctx, adapter_node,
9273 &next_adapter);
9274 adapter_node = next_adapter;
9275 }
9276 EXIT();
9277}
Jeff Johnson295189b2012-06-20 16:38:30 -07009278
9279VOS_STATUS hdd_init_station_mode( hdd_adapter_t *pAdapter )
9280{
9281 struct net_device *pWlanDev = pAdapter->dev;
9282 hdd_station_ctx_t *pHddStaCtx = &pAdapter->sessionCtx.station;
9283 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
9284 eHalStatus halStatus = eHAL_STATUS_SUCCESS;
9285 VOS_STATUS status = VOS_STATUS_E_FAILURE;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309286 long rc = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07009287
Nirav Shah7e3c8132015-06-22 23:51:42 +05309288 spin_lock_init( &pAdapter->sta_hash_lock);
9289 pAdapter->is_sta_id_hash_initialized = VOS_FALSE;
9290
Jeff Johnson295189b2012-06-20 16:38:30 -07009291 INIT_COMPLETION(pAdapter->session_open_comp_var);
Kiran Kumar Lokere0ad5cd32013-06-25 11:26:22 -07009292 sme_SetCurrDeviceMode(pHddCtx->hHal, pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07009293 //Open a SME session for future operation
9294 halStatus = sme_OpenSession( pHddCtx->hHal, hdd_smeRoamCallback, pAdapter,
Kiran Kumar Lokere0ad5cd32013-06-25 11:26:22 -07009295 (tANI_U8 *)&pAdapter->macAddressCurrent, &pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07009296 if ( !HAL_STATUS_SUCCESS( halStatus ) )
9297 {
9298 hddLog(VOS_TRACE_LEVEL_FATAL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07009299 "sme_OpenSession() failed with status code %08d [x%08x]",
Jeff Johnson295189b2012-06-20 16:38:30 -07009300 halStatus, halStatus );
9301 status = VOS_STATUS_E_FAILURE;
9302 goto error_sme_open;
9303 }
9304
9305 //Block on a completion variable. Can't wait forever though.
Vinay Krishna Eranna0fe2e7c2014-04-09 21:32:08 +05309306 rc = wait_for_completion_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -07009307 &pAdapter->session_open_comp_var,
9308 msecs_to_jiffies(WLAN_WAIT_TIME_SESSIONOPENCLOSE));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309309 if (rc <= 0)
Jeff Johnson295189b2012-06-20 16:38:30 -07009310 {
9311 hddLog(VOS_TRACE_LEVEL_FATAL,
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309312 "Session is not opened within timeout period code %ld", rc );
Jeff Johnson295189b2012-06-20 16:38:30 -07009313 status = VOS_STATUS_E_FAILURE;
9314 goto error_sme_open;
9315 }
9316
9317 // Register wireless extensions
9318 if( eHAL_STATUS_SUCCESS != (halStatus = hdd_register_wext(pWlanDev)))
9319 {
9320 hddLog(VOS_TRACE_LEVEL_FATAL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07009321 "hdd_register_wext() failed with status code %08d [x%08x]",
Jeff Johnson295189b2012-06-20 16:38:30 -07009322 halStatus, halStatus );
9323 status = VOS_STATUS_E_FAILURE;
9324 goto error_register_wext;
9325 }
Katya Nigam1fd24402015-02-16 14:52:19 +05309326
Jeff Johnson295189b2012-06-20 16:38:30 -07009327 //Safe to register the hard_start_xmit function again
Katya Nigam1fd24402015-02-16 14:52:19 +05309328 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29))
9329 wlan_drv_ops.ndo_start_xmit = hdd_hard_start_xmit;
9330 #else
9331 pWlanDev->hard_start_xmit = hdd_hard_start_xmit;
9332 #endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009333
9334 //Set the Connection State to Not Connected
Abhishek Singhf4669da2014-05-26 15:07:49 +05309335 hddLog(VOS_TRACE_LEVEL_INFO,
9336 "%s: Set HDD connState to eConnectionState_NotConnected",
9337 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009338 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
9339
9340 //Set the default operation channel
9341 pHddStaCtx->conn_info.operationChannel = pHddCtx->cfg_ini->OperatingChannel;
9342
9343 /* Make the default Auth Type as OPEN*/
9344 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_OPEN_SYSTEM;
9345
9346 if( VOS_STATUS_SUCCESS != ( status = hdd_init_tx_rx( pAdapter ) ) )
9347 {
9348 hddLog(VOS_TRACE_LEVEL_FATAL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07009349 "hdd_init_tx_rx() failed with status code %08d [x%08x]",
Jeff Johnson295189b2012-06-20 16:38:30 -07009350 status, status );
9351 goto error_init_txrx;
9352 }
9353
9354 set_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
9355
9356 if( VOS_STATUS_SUCCESS != ( status = hdd_wmm_adapter_init( pAdapter ) ) )
9357 {
9358 hddLog(VOS_TRACE_LEVEL_FATAL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07009359 "hdd_wmm_adapter_init() failed with status code %08d [x%08x]",
Jeff Johnson295189b2012-06-20 16:38:30 -07009360 status, status );
9361 goto error_wmm_init;
9362 }
9363
9364 set_bit(WMM_INIT_DONE, &pAdapter->event_flags);
Arun Kumar Khandavalli2225e3b2020-08-03 10:23:22 +05309365 /* Action frame registered in one adapter which will
9366 * applicable to all interfaces
9367 */
9368 wlan_hdd_cfg80211_register_frames(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07009369
9370 return VOS_STATUS_SUCCESS;
9371
9372error_wmm_init:
9373 clear_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
9374 hdd_deinit_tx_rx(pAdapter);
9375error_init_txrx:
9376 hdd_UnregisterWext(pWlanDev);
9377error_register_wext:
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07009378 if (test_bit(SME_SESSION_OPENED, &pAdapter->event_flags))
Jeff Johnson295189b2012-06-20 16:38:30 -07009379 {
9380 INIT_COMPLETION(pAdapter->session_close_comp_var);
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07009381 if (eHAL_STATUS_SUCCESS == sme_CloseSession(pHddCtx->hHal,
Agrawal Ashish5a3522c2016-03-02 15:08:28 +05309382 pAdapter->sessionId, FALSE, VOS_TRUE,
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07009383 hdd_smeCloseSessionCallback, pAdapter))
Jeff Johnson295189b2012-06-20 16:38:30 -07009384 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309385 unsigned long rc;
9386
Jeff Johnson295189b2012-06-20 16:38:30 -07009387 //Block on a completion variable. Can't wait forever though.
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309388 rc = wait_for_completion_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -07009389 &pAdapter->session_close_comp_var,
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07009390 msecs_to_jiffies(WLAN_WAIT_TIME_SESSIONOPENCLOSE));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309391 if (rc <= 0)
9392 hddLog(VOS_TRACE_LEVEL_ERROR,
9393 FL("Session is not opened within timeout period code %ld"), rc);
Jeff Johnson295189b2012-06-20 16:38:30 -07009394 }
9395}
9396error_sme_open:
9397 return status;
9398}
9399
Jeff Johnson295189b2012-06-20 16:38:30 -07009400void hdd_cleanup_actionframe( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter )
9401{
9402 hdd_cfg80211_state_t *cfgState;
9403
9404 cfgState = WLAN_HDD_GET_CFG_STATE_PTR( pAdapter );
9405
9406 if( NULL != cfgState->buf )
9407 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309408 long rc;
Jeff Johnson295189b2012-06-20 16:38:30 -07009409 INIT_COMPLETION(pAdapter->tx_action_cnf_event);
9410 rc = wait_for_completion_interruptible_timeout(
9411 &pAdapter->tx_action_cnf_event,
9412 msecs_to_jiffies(ACTION_FRAME_TX_TIMEOUT));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309413 if (rc <= 0)
Jeff Johnson295189b2012-06-20 16:38:30 -07009414 {
Deepthi Gowri91b3e9c2015-08-25 13:14:58 +05309415 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9416 "%s ERROR: HDD Wait for Action Confirmation Failed!! %ld"
9417 , __func__, rc);
9418
9419 // Inform tx status as FAILURE to upper layer and free cfgState->buf
9420 hdd_sendActionCnf( pAdapter, FALSE );
Jeff Johnson295189b2012-06-20 16:38:30 -07009421 }
9422 }
9423 return;
9424}
Jeff Johnson295189b2012-06-20 16:38:30 -07009425
c_hpothu002231a2015-02-05 14:58:51 +05309426void hdd_deinit_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter, tANI_U8 rtnl_held )
Jeff Johnson295189b2012-06-20 16:38:30 -07009427{
9428 ENTER();
9429 switch ( pAdapter->device_mode )
9430 {
Katya Nigam1fd24402015-02-16 14:52:19 +05309431 case WLAN_HDD_IBSS:
9432 {
9433 if(test_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags))
9434 {
9435 hdd_ibss_deinit_tx_rx( pAdapter );
9436 clear_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
9437 }
9438 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009439 case WLAN_HDD_INFRA_STATION:
9440 case WLAN_HDD_P2P_CLIENT:
Jeff Johnsone7245742012-09-05 17:12:55 -07009441 case WLAN_HDD_P2P_DEVICE:
Jeff Johnson295189b2012-06-20 16:38:30 -07009442 {
9443 if(test_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags))
9444 {
9445 hdd_deinit_tx_rx( pAdapter );
9446 clear_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
9447 }
9448
9449 if(test_bit(WMM_INIT_DONE, &pAdapter->event_flags))
9450 {
9451 hdd_wmm_adapter_close( pAdapter );
9452 clear_bit(WMM_INIT_DONE, &pAdapter->event_flags);
9453 }
9454
Jeff Johnson295189b2012-06-20 16:38:30 -07009455 hdd_cleanup_actionframe(pHddCtx, pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07009456 break;
9457 }
9458
9459 case WLAN_HDD_SOFTAP:
9460 case WLAN_HDD_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07009461 {
Madan Mohan Koyyalamudi8c6dec82013-09-26 15:56:13 +05309462
9463 if (test_bit(WMM_INIT_DONE, &pAdapter->event_flags))
9464 {
9465 hdd_wmm_adapter_close( pAdapter );
9466 clear_bit(WMM_INIT_DONE, &pAdapter->event_flags);
9467 }
9468
Jeff Johnson295189b2012-06-20 16:38:30 -07009469 hdd_cleanup_actionframe(pHddCtx, pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07009470
c_hpothu002231a2015-02-05 14:58:51 +05309471 hdd_unregister_hostapd(pAdapter, rtnl_held);
Agrawal Ashisha0584d42016-09-29 13:03:45 +05309472 /* set con_mode to STA only when no SAP concurrency mode */
9473 if (!(hdd_get_concurrency_mode() & (VOS_SAP | VOS_P2P_GO)))
9474 hdd_set_conparam(0);
Jeff Johnson295189b2012-06-20 16:38:30 -07009475 break;
9476 }
9477
9478 case WLAN_HDD_MONITOR:
9479 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009480 if(test_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags))
9481 {
9482 hdd_deinit_tx_rx( pAdapter );
9483 clear_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
9484 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009485 break;
9486 }
9487
9488
9489 default:
9490 break;
9491 }
9492
9493 EXIT();
9494}
9495
9496void hdd_cleanup_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter, tANI_U8 rtnl_held )
9497{
Mingcheng Zhu87f22fc2014-01-30 19:23:32 -08009498 struct net_device *pWlanDev = NULL;
Srinivas, Dasari693dfc52013-12-27 17:29:09 +05309499
9500 ENTER();
9501 if (NULL == pAdapter)
9502 {
9503 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9504 "%s: HDD adapter is Null", __func__);
9505 return;
9506 }
9507
9508 pWlanDev = pAdapter->dev;
Jeff Johnson295189b2012-06-20 16:38:30 -07009509
Rajeev79dbe4c2013-10-05 11:03:42 +05309510#ifdef FEATURE_WLAN_BATCH_SCAN
Srinivas, Dasari693dfc52013-12-27 17:29:09 +05309511 if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
9512 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Rajeev Kumarf999e582014-01-09 17:33:29 -08009513 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Srinivas, Dasari693dfc52013-12-27 17:29:09 +05309514 || (pAdapter->device_mode == WLAN_HDD_P2P_DEVICE)
9515 )
9516 {
Rajeev Kumarf999e582014-01-09 17:33:29 -08009517 if (pAdapter)
Rajeev79dbe4c2013-10-05 11:03:42 +05309518 {
Rajeev Kumarf999e582014-01-09 17:33:29 -08009519 if (eHDD_BATCH_SCAN_STATE_STARTED == pAdapter->batchScanState)
9520 {
9521 hdd_deinit_batch_scan(pAdapter);
9522 }
Rajeev79dbe4c2013-10-05 11:03:42 +05309523 }
Rajeev Kumarf999e582014-01-09 17:33:29 -08009524 }
Rajeev79dbe4c2013-10-05 11:03:42 +05309525#endif
9526
Jeff Johnson295189b2012-06-20 16:38:30 -07009527 if(test_bit(NET_DEVICE_REGISTERED, &pAdapter->event_flags)) {
9528 if( rtnl_held )
9529 {
9530 unregister_netdevice(pWlanDev);
9531 }
9532 else
9533 {
9534 unregister_netdev(pWlanDev);
9535 }
9536 // note that the pAdapter is no longer valid at this point
9537 // since the memory has been reclaimed
9538 }
9539
Srinivas, Dasari693dfc52013-12-27 17:29:09 +05309540 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07009541}
9542
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08009543void hdd_set_pwrparams(hdd_context_t *pHddCtx)
9544{
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05309545 VOS_STATUS status;
9546 hdd_adapter_t *pAdapter = NULL;
9547 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08009548
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05309549 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08009550
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05309551 /*loop through all adapters.*/
9552 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08009553 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05309554 pAdapter = pAdapterNode->pAdapter;
9555 if ( (WLAN_HDD_INFRA_STATION != pAdapter->device_mode)
9556 && (WLAN_HDD_P2P_CLIENT != pAdapter->device_mode) )
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08009557
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05309558 { // we skip this registration for modes other than STA and P2P client modes.
9559 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
9560 pAdapterNode = pNext;
9561 continue;
9562 }
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08009563
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05309564 //Apply Dynamic DTIM For P2P
9565 //Only if ignoreDynamicDtimInP2pMode is not set in ini
9566 if ((pHddCtx->cfg_ini->enableDynamicDTIM ||
9567 pHddCtx->cfg_ini->enableModulatedDTIM) &&
9568 ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
9569 ((WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) &&
9570 !(pHddCtx->cfg_ini->ignoreDynamicDtimInP2pMode))) &&
9571 (eANI_BOOLEAN_TRUE == pAdapter->higherDtimTransition) &&
9572 (eConnectionState_Associated ==
9573 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState) &&
9574 (pHddCtx->cfg_ini->fIsBmpsEnabled))
9575 {
9576 tSirSetPowerParamsReq powerRequest = { 0 };
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08009577
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05309578 powerRequest.uIgnoreDTIM = 1;
9579 powerRequest.uMaxLIModulatedDTIM = pHddCtx->cfg_ini->fMaxLIModulatedDTIM;
9580
9581 if (pHddCtx->cfg_ini->enableModulatedDTIM)
9582 {
9583 powerRequest.uDTIMPeriod = pHddCtx->cfg_ini->enableModulatedDTIM;
9584 powerRequest.uListenInterval = pHddCtx->hdd_actual_LI_value;
9585 }
9586 else
9587 {
9588 powerRequest.uListenInterval = pHddCtx->cfg_ini->enableDynamicDTIM;
9589 }
9590
9591 /* Update ignoreDTIM and ListedInterval in CFG to remain at the DTIM
9592 * specified during Enter/Exit BMPS when LCD off*/
9593 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IGNORE_DTIM, powerRequest.uIgnoreDTIM,
9594 NULL, eANI_BOOLEAN_FALSE);
9595 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_LISTEN_INTERVAL, powerRequest.uListenInterval,
9596 NULL, eANI_BOOLEAN_FALSE);
9597
9598 /* switch to the DTIM specified in cfg.ini */
9599 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Abhishek Singh1e390cf2015-10-27 13:45:17 +05309600 "Switch to DTIM %d Listen interval %d",
9601 powerRequest.uDTIMPeriod,
9602 powerRequest.uListenInterval);
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05309603 sme_SetPowerParams( pHddCtx->hHal, &powerRequest, TRUE);
9604 break;
9605
9606 }
9607
9608 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
9609 pAdapterNode = pNext;
9610 }
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08009611}
9612
9613void hdd_reset_pwrparams(hdd_context_t *pHddCtx)
9614{
9615 /*Switch back to DTIM 1*/
9616 tSirSetPowerParamsReq powerRequest = { 0 };
9617
9618 powerRequest.uIgnoreDTIM = pHddCtx->hdd_actual_ignore_DTIM_value;
9619 powerRequest.uListenInterval = pHddCtx->hdd_actual_LI_value;
Yue Mac24062f2013-05-13 17:01:29 -07009620 powerRequest.uMaxLIModulatedDTIM = pHddCtx->cfg_ini->fMaxLIModulatedDTIM;
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08009621
9622 /* Update ignoreDTIM and ListedInterval in CFG with default values */
9623 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IGNORE_DTIM, powerRequest.uIgnoreDTIM,
9624 NULL, eANI_BOOLEAN_FALSE);
9625 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_LISTEN_INTERVAL, powerRequest.uListenInterval,
9626 NULL, eANI_BOOLEAN_FALSE);
9627
9628 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
9629 "Switch to DTIM%d",powerRequest.uListenInterval);
9630 sme_SetPowerParams( pHddCtx->hHal, &powerRequest, TRUE);
9631
9632}
9633
Jeff Johnson295189b2012-06-20 16:38:30 -07009634VOS_STATUS hdd_enable_bmps_imps(hdd_context_t *pHddCtx)
9635{
9636 VOS_STATUS status = VOS_STATUS_SUCCESS;
Sushant Kaushik4928e542014-12-29 15:25:54 +05309637 if (WLAN_HDD_IS_UNLOAD_IN_PROGRESS(pHddCtx))
9638 {
9639 hddLog( LOGE, FL("Wlan Unload in progress"));
9640 return VOS_STATUS_E_PERM;
9641 }
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +05309642
9643 if (wlan_hdd_check_monitor_state(pHddCtx)) {
9644 hddLog(LOG1, FL("Monitor mode is started, cannot enable BMPS"));
9645 return VOS_STATUS_SUCCESS;
9646 }
9647
Jeff Johnson295189b2012-06-20 16:38:30 -07009648 if(pHddCtx->cfg_ini->fIsBmpsEnabled)
9649 {
9650 sme_EnablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
9651 }
9652
9653 if(pHddCtx->cfg_ini->fIsAutoBmpsTimerEnabled)
9654 {
9655 sme_StartAutoBmpsTimer(pHddCtx->hHal);
9656 }
9657
9658 if (pHddCtx->cfg_ini->fIsImpsEnabled)
9659 {
9660 sme_EnablePowerSave (pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
9661 }
9662
9663 return status;
9664}
9665
9666VOS_STATUS hdd_disable_bmps_imps(hdd_context_t *pHddCtx, tANI_U8 session_type)
9667{
9668 hdd_adapter_t *pAdapter = NULL;
9669 eHalStatus halStatus;
9670 VOS_STATUS status = VOS_STATUS_E_INVAL;
9671 v_BOOL_t disableBmps = FALSE;
9672 v_BOOL_t disableImps = FALSE;
9673
9674 switch(session_type)
9675 {
9676 case WLAN_HDD_INFRA_STATION:
9677 case WLAN_HDD_SOFTAP:
Jeff Johnson295189b2012-06-20 16:38:30 -07009678 case WLAN_HDD_P2P_CLIENT:
9679 case WLAN_HDD_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07009680 //Exit BMPS -> Is Sta/P2P Client is already connected
9681 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION);
9682 if((NULL != pAdapter)&&
9683 hdd_connIsConnected( WLAN_HDD_GET_STATION_CTX_PTR(pAdapter)))
9684 {
9685 disableBmps = TRUE;
9686 }
9687
9688 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_CLIENT);
9689 if((NULL != pAdapter)&&
9690 hdd_connIsConnected( WLAN_HDD_GET_STATION_CTX_PTR(pAdapter)))
9691 {
9692 disableBmps = TRUE;
9693 }
9694
9695 //Exit both Bmps and Imps incase of Go/SAP Mode
9696 if((WLAN_HDD_SOFTAP == session_type) ||
9697 (WLAN_HDD_P2P_GO == session_type))
9698 {
9699 disableBmps = TRUE;
9700 disableImps = TRUE;
9701 }
9702
9703 if(TRUE == disableImps)
9704 {
9705 if (pHddCtx->cfg_ini->fIsImpsEnabled)
9706 {
9707 sme_DisablePowerSave (pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
9708 }
9709 }
9710
9711 if(TRUE == disableBmps)
9712 {
9713 if(pHddCtx->cfg_ini->fIsBmpsEnabled)
9714 {
9715 halStatus = sme_DisablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
9716
9717 if(eHAL_STATUS_SUCCESS != halStatus)
9718 {
9719 status = VOS_STATUS_E_FAILURE;
Arif Hussain6d2a3322013-11-17 19:50:10 -08009720 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Fail to Disable Power Save", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009721 VOS_ASSERT(0);
9722 return status;
9723 }
9724 }
9725
9726 if(pHddCtx->cfg_ini->fIsAutoBmpsTimerEnabled)
9727 {
9728 halStatus = sme_StopAutoBmpsTimer(pHddCtx->hHal);
9729
9730 if(eHAL_STATUS_SUCCESS != halStatus)
9731 {
9732 status = VOS_STATUS_E_FAILURE;
Arif Hussain6d2a3322013-11-17 19:50:10 -08009733 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Fail to Stop Auto Bmps Timer", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009734 VOS_ASSERT(0);
9735 return status;
9736 }
9737 }
9738 }
9739
9740 if((TRUE == disableBmps) ||
9741 (TRUE == disableImps))
9742 {
9743 /* Now, get the chip into Full Power now */
9744 INIT_COMPLETION(pHddCtx->full_pwr_comp_var);
9745 halStatus = sme_RequestFullPower(pHddCtx->hHal, hdd_full_pwr_cbk,
9746 pHddCtx, eSME_FULL_PWR_NEEDED_BY_HDD);
9747
9748 if(halStatus != eHAL_STATUS_SUCCESS)
9749 {
9750 if(halStatus == eHAL_STATUS_PMC_PENDING)
9751 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309752 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07009753 //Block on a completion variable. Can't wait forever though
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309754 ret = wait_for_completion_interruptible_timeout(
9755 &pHddCtx->full_pwr_comp_var,
9756 msecs_to_jiffies(1000));
9757 if (ret <= 0)
9758 {
9759 hddLog(VOS_TRACE_LEVEL_ERROR,
9760 "%s: wait on full_pwr_comp_var failed %ld",
9761 __func__, ret);
9762 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009763 }
9764 else
9765 {
9766 status = VOS_STATUS_E_FAILURE;
Arif Hussain6d2a3322013-11-17 19:50:10 -08009767 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Request for Full Power failed", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009768 VOS_ASSERT(0);
9769 return status;
9770 }
9771 }
9772
9773 status = VOS_STATUS_SUCCESS;
9774 }
9775
9776 break;
9777 }
9778 return status;
9779}
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +05309780
Hanumanth Reddy Pothulab8be9ab2018-04-12 20:03:05 +05309781void hdd_mon_post_msg_cb(void *context)
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +05309782{
Hanumanth Reddy Pothulab8be9ab2018-04-12 20:03:05 +05309783 struct hdd_request *request;
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +05309784
Hanumanth Reddy Pothulab8be9ab2018-04-12 20:03:05 +05309785 request = hdd_request_get(context);
9786 if (!request) {
9787 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Obsolete request"));
9788 return;
9789 }
9790
9791 hdd_request_complete(request);
9792 hdd_request_put(request);
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +05309793}
9794
Hanumanth Reddy Pothulab8be9ab2018-04-12 20:03:05 +05309795
Katya Nigame7b69a82015-04-28 15:24:06 +05309796void hdd_init_mon_mode (hdd_adapter_t *pAdapter)
9797 {
9798 hdd_mon_ctx_t *pMonCtx = NULL;
Katya Nigame7b69a82015-04-28 15:24:06 +05309799
Rajeev Kumar Sirasanagandla54447612018-03-06 15:49:56 +05309800 spin_lock_init(&pAdapter->sta_hash_lock);
9801 pAdapter->is_sta_id_hash_initialized = VOS_FALSE;
9802
9803 pMonCtx = WLAN_HDD_GET_MONITOR_CTX_PTR(pAdapter);
Katya Nigame7b69a82015-04-28 15:24:06 +05309804 pMonCtx->state = 0;
9805 pMonCtx->ChannelNo = 1;
9806 pMonCtx->ChannelBW = 20;
Katya Nigamd7d3a1f2015-06-11 14:04:24 +05309807 pMonCtx->crcCheckEnabled = 1;
9808 pMonCtx->typeSubtypeBitmap = 0xFFFF00000000;
9809 pMonCtx->is80211to803ConReq = 1;
Katya Nigame7b69a82015-04-28 15:24:06 +05309810 pMonCtx->numOfMacFilters = 0;
9811 }
9812
Jeff Johnson295189b2012-06-20 16:38:30 -07009813
9814hdd_adapter_t* hdd_open_adapter( hdd_context_t *pHddCtx, tANI_U8 session_type,
Jeff Johnsoneed415b2013-01-18 16:11:20 -08009815 const char *iface_name, tSirMacAddr macAddr,
Jeff Johnson295189b2012-06-20 16:38:30 -07009816 tANI_U8 rtnl_held )
9817{
9818 hdd_adapter_t *pAdapter = NULL;
9819 hdd_adapter_list_node_t *pHddAdapterNode = NULL;
9820 VOS_STATUS status = VOS_STATUS_E_FAILURE;
9821 VOS_STATUS exitbmpsStatus;
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +05309822 v_CONTEXT_t pVosContext = NULL;
9823
9824 /* No need to check for NULL, reaching this step
9825 * means vos context is initialized
9826 */
9827 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
Jeff Johnson295189b2012-06-20 16:38:30 -07009828
Arif Hussain6d2a3322013-11-17 19:50:10 -08009829 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s iface =%s type = %d",__func__,iface_name,session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07009830
Nirav Shah436658f2014-02-28 17:05:45 +05309831 if(macAddr == NULL)
9832 {
9833 /* Not received valid macAddr */
9834 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9835 "%s:Unable to add virtual intf: Not able to get"
9836 "valid mac address",__func__);
9837 return NULL;
9838 }
9839
Jeff Johnson295189b2012-06-20 16:38:30 -07009840 //Disable BMPS incase of Concurrency
9841 exitbmpsStatus = hdd_disable_bmps_imps(pHddCtx, session_type);
9842
9843 if(VOS_STATUS_E_FAILURE == exitbmpsStatus)
9844 {
9845 //Fail to Exit BMPS
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309846 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Fail to Exit BMPS", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009847 VOS_ASSERT(0);
9848 return NULL;
9849 }
9850
9851 switch(session_type)
9852 {
9853 case WLAN_HDD_INFRA_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -07009854 case WLAN_HDD_P2P_CLIENT:
Jeff Johnsone7245742012-09-05 17:12:55 -07009855 case WLAN_HDD_P2P_DEVICE:
Jeff Johnson295189b2012-06-20 16:38:30 -07009856 {
9857 pAdapter = hdd_alloc_station_adapter( pHddCtx, macAddr, iface_name );
9858
9859 if( NULL == pAdapter )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309860 {
9861 hddLog(VOS_TRACE_LEVEL_FATAL,
9862 FL("failed to allocate adapter for session %d"), session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07009863 return NULL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309864 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009865
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05309866#ifdef FEATURE_WLAN_TDLS
9867 /* A Mutex Lock is introduced while changing/initializing the mode to
9868 * protect the concurrent access for the Adapters by TDLS module.
9869 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05309870 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05309871#endif
9872
Jeff Johnsone7245742012-09-05 17:12:55 -07009873 pAdapter->wdev.iftype = (session_type == WLAN_HDD_P2P_CLIENT) ?
9874 NL80211_IFTYPE_P2P_CLIENT:
9875 NL80211_IFTYPE_STATION;
Jeff Johnson295189b2012-06-20 16:38:30 -07009876
Jeff Johnson295189b2012-06-20 16:38:30 -07009877 pAdapter->device_mode = session_type;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05309878#ifdef FEATURE_WLAN_TDLS
9879 mutex_unlock(&pHddCtx->tdls_lock);
9880#endif
Sunil Dutt66485cb2013-12-19 19:05:03 +05309881
Mahesh A Saptasagar67ab9222015-10-21 15:38:41 +05309882 hdd_initialize_adapter_common(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07009883
9884 status = hdd_register_interface( pAdapter, rtnl_held );
9885 if( VOS_STATUS_SUCCESS != status )
9886 {
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05309887#ifdef FEATURE_WLAN_TDLS
9888 mutex_lock(&pHddCtx->tdls_lock);
9889#endif
c_hpothu002231a2015-02-05 14:58:51 +05309890 hdd_deinit_adapter(pHddCtx, pAdapter, rtnl_held);
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05309891#ifdef FEATURE_WLAN_TDLS
9892 mutex_unlock(&pHddCtx->tdls_lock);
9893#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009894 goto err_free_netdev;
9895 }
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05309896
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +05309897 // Workqueue which gets scheduled in IPv4 notification callback.
Anand N Sunkaddc63c792015-06-03 14:33:24 +05309898 vos_init_work(&pAdapter->ipv4NotifierWorkQueue, hdd_ipv4_notifier_work_queue);
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +05309899
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05309900#ifdef WLAN_NS_OFFLOAD
9901 // Workqueue which gets scheduled in IPv6 notification callback.
Anand N Sunkaddc63c792015-06-03 14:33:24 +05309902 vos_init_work(&pAdapter->ipv6NotifierWorkQueue, hdd_ipv6_notifier_work_queue);
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05309903#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009904 //Stop the Interface TX queue.
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +05309905 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Jeff Johnson295189b2012-06-20 16:38:30 -07009906 netif_tx_disable(pAdapter->dev);
9907 //netif_tx_disable(pWlanDev);
9908 netif_carrier_off(pAdapter->dev);
9909
Ganesh Kondabattinibabfb492014-12-17 20:25:29 +05309910 if (WLAN_HDD_P2P_CLIENT == session_type ||
9911 WLAN_HDD_P2P_DEVICE == session_type)
9912 {
9913 /* Initialize the work queue to defer the
9914 * back to back RoC request */
Anand N Sunkaddc63c792015-06-03 14:33:24 +05309915 vos_init_delayed_work(&pAdapter->roc_work,
Ganesh Kondabattinibabfb492014-12-17 20:25:29 +05309916 hdd_p2p_roc_work_queue);
9917 }
9918
Jeff Johnson295189b2012-06-20 16:38:30 -07009919 break;
9920 }
9921
Jeff Johnson295189b2012-06-20 16:38:30 -07009922 case WLAN_HDD_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07009923 case WLAN_HDD_SOFTAP:
9924 {
9925 pAdapter = hdd_wlan_create_ap_dev( pHddCtx, macAddr, (tANI_U8 *)iface_name );
9926 if( NULL == pAdapter )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309927 {
9928 hddLog(VOS_TRACE_LEVEL_FATAL,
9929 FL("failed to allocate adapter for session %d"), session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07009930 return NULL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309931 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009932
Jeff Johnson295189b2012-06-20 16:38:30 -07009933 pAdapter->wdev.iftype = (session_type == WLAN_HDD_SOFTAP) ?
9934 NL80211_IFTYPE_AP:
9935 NL80211_IFTYPE_P2P_GO;
Jeff Johnson295189b2012-06-20 16:38:30 -07009936 pAdapter->device_mode = session_type;
9937
Mahesh A Saptasagar67ab9222015-10-21 15:38:41 +05309938 hdd_initialize_adapter_common(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07009939
Nirav Shah7e3c8132015-06-22 23:51:42 +05309940 status = hdd_sta_id_hash_attach(pAdapter);
9941 if (VOS_STATUS_SUCCESS != status)
9942 {
9943 hddLog(VOS_TRACE_LEVEL_FATAL,
9944 FL("failed to attach hash for session %d"), session_type);
Nirav Shah7e3c8132015-06-22 23:51:42 +05309945 goto err_free_netdev;
9946 }
9947
Jeff Johnson295189b2012-06-20 16:38:30 -07009948 status = hdd_register_hostapd( pAdapter, rtnl_held );
9949 if( VOS_STATUS_SUCCESS != status )
9950 {
c_hpothu002231a2015-02-05 14:58:51 +05309951 hdd_deinit_adapter(pHddCtx, pAdapter, rtnl_held);
Jeff Johnson295189b2012-06-20 16:38:30 -07009952 goto err_free_netdev;
9953 }
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +05309954 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Jeff Johnson295189b2012-06-20 16:38:30 -07009955 netif_tx_disable(pAdapter->dev);
9956 netif_carrier_off(pAdapter->dev);
9957
9958 hdd_set_conparam( 1 );
Ganesh Kondabattinibabfb492014-12-17 20:25:29 +05309959
Hanumanth Reddy Pothulab4537b82018-03-02 12:20:38 +05309960 // Workqueue which gets scheduled in IPv4 notification callback.
9961 vos_init_work(&pAdapter->ipv4NotifierWorkQueue,
9962 hdd_ipv4_notifier_work_queue);
9963
9964#ifdef WLAN_NS_OFFLOAD
9965 // Workqueue which gets scheduled in IPv6 notification callback.
9966 vos_init_work(&pAdapter->ipv6NotifierWorkQueue,
9967 hdd_ipv6_notifier_work_queue);
9968#endif
9969
Ganesh Kondabattinibabfb492014-12-17 20:25:29 +05309970 if (WLAN_HDD_P2P_GO == session_type)
9971 {
9972 /* Initialize the work queue to
9973 * defer the back to back RoC request */
9974 INIT_DELAYED_WORK(&pAdapter->roc_work,
9975 hdd_p2p_roc_work_queue);
9976 }
Bhargav Shahd0715912015-10-01 18:17:37 +05309977
Jeff Johnson295189b2012-06-20 16:38:30 -07009978 break;
9979 }
9980 case WLAN_HDD_MONITOR:
9981 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009982 pAdapter = hdd_alloc_station_adapter( pHddCtx, macAddr, iface_name );
9983 if( NULL == pAdapter )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309984 {
9985 hddLog(VOS_TRACE_LEVEL_FATAL,
9986 FL("failed to allocate adapter for session %d"), session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07009987 return NULL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309988 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009989
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +05309990 pAdapter->device_mode = session_type;
9991 pAdapter->wdev.iftype = NL80211_IFTYPE_MONITOR;
9992
Katya Nigame7b69a82015-04-28 15:24:06 +05309993 // Register wireless extensions
9994 if( VOS_STATUS_SUCCESS != (status = hdd_register_wext(pAdapter->dev)))
9995 {
9996 hddLog(VOS_TRACE_LEVEL_FATAL,
9997 "hdd_register_wext() failed with status code %08d [x%08x]",
9998 status, status );
9999 status = VOS_STATUS_E_FAILURE;
10000 }
10001
Jeff Johnson295189b2012-06-20 16:38:30 -070010002#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29)
10003 pAdapter->dev->netdev_ops = &wlan_mon_drv_ops;
10004#else
10005 pAdapter->dev->open = hdd_mon_open;
10006 pAdapter->dev->hard_start_xmit = hdd_mon_hard_start_xmit;
Katya Nigame7b69a82015-04-28 15:24:06 +053010007 pAdapter->dev->stop = hdd_mon_stop;
10008 pAdapter->dev->do_ioctl = hdd_mon_ioctl;
Jeff Johnson295189b2012-06-20 16:38:30 -070010009#endif
Katya Nigame7b69a82015-04-28 15:24:06 +053010010 hdd_init_mon_mode( pAdapter );
Mahesh A Saptasagar67ab9222015-10-21 15:38:41 +053010011 hdd_initialize_adapter_common(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070010012 hdd_init_tx_rx( pAdapter );
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +053010013
10014 if (VOS_MONITOR_MODE != hdd_get_conparam())
10015 WLANTL_SetMonRxCbk( pVosContext, hdd_rx_packet_monitor_cbk );
10016
Jeff Johnson295189b2012-06-20 16:38:30 -070010017 set_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +053010018 status = hdd_register_interface( pAdapter, rtnl_held );
Katya Nigame7b69a82015-04-28 15:24:06 +053010019 //Stop the Interface TX queue.
10020 netif_tx_disable(pAdapter->dev);
10021 netif_carrier_off(pAdapter->dev);
Jeff Johnson295189b2012-06-20 16:38:30 -070010022 }
10023 break;
Jeff Johnson295189b2012-06-20 16:38:30 -070010024 case WLAN_HDD_FTM:
10025 {
10026 pAdapter = hdd_alloc_station_adapter( pHddCtx, macAddr, iface_name );
10027
10028 if( NULL == pAdapter )
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010029 {
10030 hddLog(VOS_TRACE_LEVEL_FATAL,
10031 FL("failed to allocate adapter for session %d"), session_type);
10032 return NULL;
10033 }
10034
Jeff Johnson295189b2012-06-20 16:38:30 -070010035 /* Assign NL80211_IFTYPE_STATION as interface type to resolve Kernel Warning
10036 * message while loading driver in FTM mode. */
10037 pAdapter->wdev.iftype = NL80211_IFTYPE_STATION;
10038 pAdapter->device_mode = session_type;
10039 status = hdd_register_interface( pAdapter, rtnl_held );
Madan Mohan Koyyalamudif89ac9f2013-09-19 16:58:12 +053010040
Mahesh A Saptasagar67ab9222015-10-21 15:38:41 +053010041 hdd_initialize_adapter_common(pAdapter);
Madan Mohan Koyyalamudif89ac9f2013-09-19 16:58:12 +053010042 hdd_init_tx_rx( pAdapter );
10043
10044 //Stop the Interface TX queue.
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +053010045 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Madan Mohan Koyyalamudif89ac9f2013-09-19 16:58:12 +053010046 netif_tx_disable(pAdapter->dev);
10047 netif_carrier_off(pAdapter->dev);
Jeff Johnson295189b2012-06-20 16:38:30 -070010048 }
10049 break;
Jeff Johnson295189b2012-06-20 16:38:30 -070010050 default:
10051 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010052 hddLog(VOS_TRACE_LEVEL_FATAL,"%s Invalid session type %d",
10053 __func__, session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -070010054 VOS_ASSERT(0);
10055 return NULL;
10056 }
10057 }
10058
Jeff Johnson295189b2012-06-20 16:38:30 -070010059 if( VOS_STATUS_SUCCESS == status )
10060 {
Mahesh A Saptasagar67ab9222015-10-21 15:38:41 +053010061 //Add it to the hdd's session list.
Jeff Johnson295189b2012-06-20 16:38:30 -070010062 pHddAdapterNode = vos_mem_malloc( sizeof( hdd_adapter_list_node_t ) );
10063 if( NULL == pHddAdapterNode )
10064 {
10065 status = VOS_STATUS_E_NOMEM;
10066 }
10067 else
10068 {
10069 pHddAdapterNode->pAdapter = pAdapter;
10070 status = hdd_add_adapter_back ( pHddCtx,
10071 pHddAdapterNode );
10072 }
10073 }
10074
10075 if( VOS_STATUS_SUCCESS != status )
10076 {
10077 if( NULL != pAdapter )
10078 {
10079 hdd_cleanup_adapter( pHddCtx, pAdapter, rtnl_held );
10080 pAdapter = NULL;
10081 }
10082 if( NULL != pHddAdapterNode )
10083 {
10084 vos_mem_free( pHddAdapterNode );
10085 }
10086
10087 goto resume_bmps;
10088 }
10089
10090 if(VOS_STATUS_SUCCESS == status)
10091 {
10092 wlan_hdd_set_concurrency_mode(pHddCtx, session_type);
Madan Mohan Koyyalamudi96dd30d2012-10-05 17:24:51 -070010093 //Initialize the WoWL service
10094 if(!hdd_init_wowl(pAdapter))
10095 {
10096 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hdd_init_wowl failed",__func__);
10097 goto err_free_netdev;
10098 }
Manjeet Singh3ed79242017-01-11 19:04:32 +053010099 //Initialize the TSF capture data
10100 wlan_hdd_tsf_init(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070010101 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010102 return pAdapter;
10103
10104err_free_netdev:
Jeff Johnson295189b2012-06-20 16:38:30 -070010105 wlan_hdd_release_intf_addr( pHddCtx,
10106 pAdapter->macAddressCurrent.bytes );
Hanumanth Reddy Pothulaab8e1942018-05-24 18:10:39 +053010107 free_netdev(pAdapter->dev);
Jeff Johnson295189b2012-06-20 16:38:30 -070010108
10109resume_bmps:
10110 //If bmps disabled enable it
10111 if(VOS_STATUS_SUCCESS == exitbmpsStatus)
10112 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +053010113 if (pHddCtx->hdd_wlan_suspended)
10114 {
10115 hdd_set_pwrparams(pHddCtx);
10116 }
10117 hdd_enable_bmps_imps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -070010118 }
10119 return NULL;
10120}
10121
10122VOS_STATUS hdd_close_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter,
10123 tANI_U8 rtnl_held )
10124{
10125 hdd_adapter_list_node_t *pAdapterNode, *pCurrent, *pNext;
10126 VOS_STATUS status;
10127
10128 status = hdd_get_front_adapter ( pHddCtx, &pCurrent );
10129 if( VOS_STATUS_SUCCESS != status )
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010130 {
10131 hddLog(VOS_TRACE_LEVEL_WARN,"%s: adapter list empty %d",
10132 __func__, status);
Jeff Johnson295189b2012-06-20 16:38:30 -070010133 return status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010134 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010135
10136 while ( pCurrent->pAdapter != pAdapter )
10137 {
10138 status = hdd_get_next_adapter ( pHddCtx, pCurrent, &pNext );
10139 if( VOS_STATUS_SUCCESS != status )
10140 break;
10141
10142 pCurrent = pNext;
10143 }
10144 pAdapterNode = pCurrent;
10145 if( VOS_STATUS_SUCCESS == status )
10146 {
10147 wlan_hdd_clear_concurrency_mode(pHddCtx, pAdapter->device_mode);
10148 hdd_cleanup_adapter( pHddCtx, pAdapterNode->pAdapter, rtnl_held );
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053010149
10150#ifdef FEATURE_WLAN_TDLS
10151
10152 /* A Mutex Lock is introduced while changing/initializing the mode to
10153 * protect the concurrent access for the Adapters by TDLS module.
10154 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053010155 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053010156#endif
10157
Jeff Johnson295189b2012-06-20 16:38:30 -070010158 hdd_remove_adapter( pHddCtx, pAdapterNode );
10159 vos_mem_free( pAdapterNode );
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -080010160 pAdapterNode = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070010161
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053010162#ifdef FEATURE_WLAN_TDLS
10163 mutex_unlock(&pHddCtx->tdls_lock);
10164#endif
10165
Jeff Johnson295189b2012-06-20 16:38:30 -070010166
10167 /* If there is a single session of STA/P2P client, re-enable BMPS */
Agarwal Ashish51325b52014-06-16 16:50:49 +053010168 if ((!vos_concurrent_open_sessions_running()) &&
10169 ((pHddCtx->no_of_open_sessions[VOS_STA_MODE] >= 1) ||
10170 (pHddCtx->no_of_open_sessions[VOS_P2P_CLIENT_MODE] >= 1)))
Jeff Johnson295189b2012-06-20 16:38:30 -070010171 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +053010172 if (pHddCtx->hdd_wlan_suspended)
10173 {
10174 hdd_set_pwrparams(pHddCtx);
10175 }
10176 hdd_enable_bmps_imps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -070010177 }
10178
10179 return VOS_STATUS_SUCCESS;
10180 }
10181
10182 return VOS_STATUS_E_FAILURE;
10183}
10184
10185VOS_STATUS hdd_close_all_adapters( hdd_context_t *pHddCtx )
10186{
10187 hdd_adapter_list_node_t *pHddAdapterNode;
10188 VOS_STATUS status;
10189
10190 ENTER();
10191
10192 do
10193 {
10194 status = hdd_remove_front_adapter( pHddCtx, &pHddAdapterNode );
10195 if( pHddAdapterNode && VOS_STATUS_SUCCESS == status )
10196 {
10197 hdd_cleanup_adapter( pHddCtx, pHddAdapterNode->pAdapter, FALSE );
10198 vos_mem_free( pHddAdapterNode );
10199 }
10200 }while( NULL != pHddAdapterNode && VOS_STATUS_E_EMPTY != status );
10201
10202 EXIT();
10203
10204 return VOS_STATUS_SUCCESS;
10205}
10206
10207void wlan_hdd_reset_prob_rspies(hdd_adapter_t* pHostapdAdapter)
10208{
10209 v_U8_t addIE[1] = {0};
10210
10211 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
10212 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,(tANI_U8*)addIE, 0, NULL,
10213 eANI_BOOLEAN_FALSE) )
10214 {
10215 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010216 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -070010217 }
10218
10219 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
10220 WNI_CFG_PROBE_RSP_ADDNIE_DATA2, (tANI_U8*)addIE, 0, NULL,
10221 eANI_BOOLEAN_FALSE) )
10222 {
10223 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010224 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -070010225 }
10226
10227 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
10228 WNI_CFG_PROBE_RSP_ADDNIE_DATA3, (tANI_U8*)addIE, 0, NULL,
10229 eANI_BOOLEAN_FALSE) )
10230 {
10231 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010232 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -070010233 }
10234}
10235
Anurag Chouhan83026002016-12-13 22:46:21 +053010236VOS_STATUS hdd_cleanup_ap_events(hdd_adapter_t *adapter)
10237{
10238#ifdef DHCP_SERVER_OFFLOAD
10239 vos_event_destroy(&adapter->dhcp_status.vos_event);
10240#endif
Anurag Chouhan0b29de02016-12-16 13:18:40 +053010241#ifdef MDNS_OFFLOAD
10242 vos_event_destroy(&adapter->mdns_status.vos_event);
10243#endif
Anurag Chouhan83026002016-12-13 22:46:21 +053010244 return VOS_STATUS_SUCCESS;
10245}
10246
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +053010247int wlan_hdd_stop_mon(hdd_context_t *hdd_ctx, bool wait)
10248{
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +053010249 hdd_adapter_t *adapter;
Hanumanth Reddy Pothulab8be9ab2018-04-12 20:03:05 +053010250 hdd_mon_ctx_t *mon_ctx;
10251 void (*func_ptr)(void *context) = NULL;
10252 int ret = 0;
10253 void *cookie = NULL;
10254 struct hdd_request *request;
10255 static const struct hdd_request_params params = {
10256 .priv_size = 0,
10257 .timeout_ms = MON_MODE_MSG_TIMEOUT,
10258 };
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +053010259
10260 adapter = hdd_get_adapter(hdd_ctx, WLAN_HDD_MONITOR);
10261 if (!adapter) {
10262 hddLog(LOGE, FL("Invalid STA + MON mode"));
10263 return -EINVAL;
10264 }
10265
10266 mon_ctx = WLAN_HDD_GET_MONITOR_CTX_PTR(adapter);
10267 if (!mon_ctx)
10268 return 0;
10269
10270 if (mon_ctx->state != MON_MODE_START)
10271 return 0;
10272
10273 mon_ctx->state = MON_MODE_STOP;
10274 if (wait) {
Hanumanth Reddy Pothulab8be9ab2018-04-12 20:03:05 +053010275 func_ptr = hdd_mon_post_msg_cb;
10276 request = hdd_request_alloc(&params);
10277 if (!request) {
10278 hddLog(VOS_TRACE_LEVEL_ERROR,
10279 FL("Request allocation failure"));
10280 return -ENOMEM;
10281 }
10282 cookie = hdd_request_cookie(request);
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +053010283 }
10284
Hanumanth Reddy Pothulab8be9ab2018-04-12 20:03:05 +053010285 /*
10286 * If func_ptr is NULL, on receiving WDI_MON_START_RSP or
10287 * WDI_MON_STOP_RSP hdd_mon_post_msg_cb() won't be invoked
10288 * and so uninitialized cookie won't be accessed.
10289 */
10290 if (VOS_STATUS_SUCCESS != wlan_hdd_mon_postMsg(cookie,
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +053010291 mon_ctx,
Hanumanth Reddy Pothulab8be9ab2018-04-12 20:03:05 +053010292 func_ptr)) {
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +053010293 hddLog(LOGE, FL("failed to stop MON MODE"));
Hanumanth Reddy Pothulab8be9ab2018-04-12 20:03:05 +053010294 ret = -EINVAL;
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +053010295 }
10296
10297 if (!wait)
10298 goto bmps_roaming;
10299
Hanumanth Reddy Pothulab8be9ab2018-04-12 20:03:05 +053010300 if (!ret)
10301 ret = hdd_request_wait_for_response(request);
10302 hdd_request_put(request);
10303 if (ret) {
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +053010304 hddLog(LOGE,
Hanumanth Reddy Pothulab8be9ab2018-04-12 20:03:05 +053010305 FL("timeout on stop monitor mode completion %d"), ret);
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +053010306 return -EINVAL;
10307 }
10308
10309bmps_roaming:
10310 hddLog(LOG1, FL("Enable BMPS"));
10311 hdd_enable_bmps_imps(hdd_ctx);
10312 hdd_restore_roaming(hdd_ctx);
10313
10314 return 0;
10315}
10316
10317bool wlan_hdd_check_monitor_state(hdd_context_t *hdd_ctx)
10318{
10319 hdd_adapter_t *mon_adapter;
10320 hdd_mon_ctx_t *mon_ctx;
10321
10322 if (hdd_ctx->concurrency_mode != VOS_STA_MON)
10323 return false;
10324
10325 mon_adapter = hdd_get_adapter(hdd_ctx, WLAN_HDD_MONITOR);
10326 if (!mon_adapter) {
10327 hddLog(LOGE, FL("Invalid concurrency mode"));
10328 return false;
10329 }
10330
10331 mon_ctx = WLAN_HDD_GET_MONITOR_CTX_PTR(mon_adapter);
10332 if (mon_ctx->state == MON_MODE_START)
10333 return true;
10334
10335 return false;
10336}
10337
10338int wlan_hdd_check_and_stop_mon(hdd_adapter_t *sta_adapter, bool wait)
10339{
10340 hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(sta_adapter);
10341
10342 if ((sta_adapter->device_mode != WLAN_HDD_INFRA_STATION) ||
10343 !wlan_hdd_check_monitor_state(hdd_ctx))
10344 return 0;
10345
10346 if (wlan_hdd_stop_mon(hdd_ctx, wait))
10347 return -EINVAL;
10348
10349 return 0;
10350}
10351
10352void hdd_disable_roaming(hdd_context_t *hdd_ctx)
10353{
10354 if (!hdd_ctx)
10355 return;
10356
10357 if (!hdd_ctx->cfg_ini->isFastRoamIniFeatureEnabled) {
10358 hdd_ctx->roaming_ini_original = CFG_LFR_FEATURE_ENABLED_MIN;
10359 return;
10360 }
10361
10362 hddLog(LOG1, FL("Disable driver and firmware roaming"));
10363
10364 hdd_ctx->roaming_ini_original =
10365 hdd_ctx->cfg_ini->isFastRoamIniFeatureEnabled;
10366
10367 hdd_ctx->cfg_ini->isFastRoamIniFeatureEnabled =
10368 CFG_LFR_FEATURE_ENABLED_MIN;
10369
10370 sme_UpdateIsFastRoamIniFeatureEnabled(hdd_ctx->hHal,
10371 CFG_LFR_FEATURE_ENABLED_MIN);
10372}
10373
10374void hdd_restore_roaming(hdd_context_t *hdd_ctx)
10375{
10376 if (!hdd_ctx->roaming_ini_original)
10377 return;
10378
10379 hddLog(LOG1, FL("Enable driver and firmware roaming"));
10380
10381 hdd_ctx->cfg_ini->isFastRoamIniFeatureEnabled =
10382 CFG_LFR_FEATURE_ENABLED_MAX;
10383
10384 hdd_ctx->roaming_ini_original = CFG_LFR_FEATURE_ENABLED_MIN;
10385
10386 sme_UpdateIsFastRoamIniFeatureEnabled(hdd_ctx->hHal,
10387 CFG_LFR_FEATURE_ENABLED_MAX);
10388}
Anurag Chouhan83026002016-12-13 22:46:21 +053010389
Agarwal Ashish3a38bd12014-06-12 15:16:52 +053010390VOS_STATUS hdd_stop_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter,
10391 const v_BOOL_t bCloseSession )
Jeff Johnson295189b2012-06-20 16:38:30 -070010392{
10393 eHalStatus halStatus = eHAL_STATUS_SUCCESS;
10394 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Kaushik, Sushant4975a572014-10-21 16:07:48 +053010395 hdd_scaninfo_t *pScanInfo = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070010396 union iwreq_data wrqu;
Kaushik, Sushant7005e372014-04-08 11:36:54 +053010397 v_U8_t retry = 0;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010398 long ret;
Nirav Shah7e3c8132015-06-22 23:51:42 +053010399 VOS_STATUS status;
Jeff Johnson295189b2012-06-20 16:38:30 -070010400
Anand N Sunkad26d71b92014-12-24 18:08:22 +053010401 if (pHddCtx->isLogpInProgress) {
10402 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
10403 "%s:LOGP in Progress. Ignore!!!",__func__);
10404 return VOS_STATUS_E_FAILURE;
10405 }
10406
Jeff Johnson295189b2012-06-20 16:38:30 -070010407 ENTER();
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +053010408
Arun Kumar Khandavalli2225e3b2020-08-03 10:23:22 +053010409 wlan_hdd_cfg80211_deregister_frames(pAdapter);
Kaushik, Sushant4975a572014-10-21 16:07:48 +053010410 pScanInfo = &pHddCtx->scan_info;
Jeff Johnson295189b2012-06-20 16:38:30 -070010411 switch(pAdapter->device_mode)
10412 {
Nirav Shah0cf4d892015-11-05 16:27:27 +053010413 case WLAN_HDD_IBSS:
10414 if ( VOS_TRUE == bCloseSession )
10415 {
10416 status = hdd_sta_id_hash_detach(pAdapter);
10417 if (status != VOS_STATUS_SUCCESS)
10418 hddLog(VOS_TRACE_LEVEL_ERROR,
10419 FL("sta id hash detach failed"));
10420 }
10421
Jeff Johnson295189b2012-06-20 16:38:30 -070010422 case WLAN_HDD_INFRA_STATION:
10423 case WLAN_HDD_P2P_CLIENT:
Jeff Johnsone7245742012-09-05 17:12:55 -070010424 case WLAN_HDD_P2P_DEVICE:
Vinay Krishna Erannab09d3e72014-03-26 21:23:55 +053010425 {
10426 hdd_station_ctx_t *pstation = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Mahesh A Saptasagare4d05d42015-07-02 16:17:20 +053010427#ifdef FEATURE_WLAN_TDLS
10428 mutex_lock(&pHddCtx->tdls_lock);
10429 wlan_hdd_tdls_exit(pAdapter, TRUE);
10430 mutex_unlock(&pHddCtx->tdls_lock);
10431#endif
Abhinav Kumare548f1e2018-07-12 16:40:43 +053010432 if(hdd_connIsConnected(pstation) ||
10433 (pstation->conn_info.connState == eConnectionState_Connecting))
Jeff Johnson295189b2012-06-20 16:38:30 -070010434 {
10435 if (pWextState->roamProfile.BSSType == eCSR_BSS_TYPE_START_IBSS)
Abhinav Kumare548f1e2018-07-12 16:40:43 +053010436 {
10437 INIT_COMPLETION(pAdapter->disconnect_comp_var);
Jeff Johnson295189b2012-06-20 16:38:30 -070010438 halStatus = sme_RoamDisconnect(pHddCtx->hHal,
10439 pAdapter->sessionId,
10440 eCSR_DISCONNECT_REASON_IBSS_LEAVE);
Abhinav Kumare548f1e2018-07-12 16:40:43 +053010441 /* Success implies disconnect command got queued up successfully
10442 * Or cmd not queued as scan for SSID is in progress
10443 */
10444 if((eHAL_STATUS_SUCCESS == halStatus) ||
10445 (eHAL_STATUS_CMD_NOT_QUEUED == halStatus))
10446 {
10447 ret = wait_for_completion_timeout(
10448 &pAdapter->disconnect_comp_var,
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010449 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
Abhinav Kumare548f1e2018-07-12 16:40:43 +053010450 if (ret <= 0 &&
10451 (eHAL_STATUS_CMD_NOT_QUEUED != halStatus))
10452 {
10453 hddLog(VOS_TRACE_LEVEL_ERROR,
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010454 "%s: wait on disconnect_comp_var failed %ld",
10455 __func__, ret);
Abhinav Kumare548f1e2018-07-12 16:40:43 +053010456 }
10457 }
10458 else
10459 {
10460 hddLog(LOGE, "%s: failed to post disconnect event to SME",
10461 __func__);
10462 }
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010463 }
10464 else
10465 {
Abhinav Kumare548f1e2018-07-12 16:40:43 +053010466 wlan_hdd_disconnect(pAdapter, eCSR_DISCONNECT_REASON_DEAUTH);
Jeff Johnson295189b2012-06-20 16:38:30 -070010467 }
10468 memset(&wrqu, '\0', sizeof(wrqu));
10469 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
10470 memset(wrqu.ap_addr.sa_data,'\0',ETH_ALEN);
10471 wireless_send_event(pAdapter->dev, SIOCGIWAP, &wrqu, NULL);
10472 }
Vinay Krishna Erannab09d3e72014-03-26 21:23:55 +053010473 else if(pstation->conn_info.connState ==
10474 eConnectionState_Disconnecting)
10475 {
10476 ret = wait_for_completion_interruptible_timeout(
10477 &pAdapter->disconnect_comp_var,
10478 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
10479 if (ret <= 0)
10480 {
10481 hddLog(VOS_TRACE_LEVEL_ERROR,
10482 FL("wait on disconnect_comp_var failed %ld"), ret);
10483 }
10484 }
Sachin Ahuja27dd2402016-08-01 20:30:31 +053010485 if(pScanInfo != NULL && pHddCtx->scan_info.mScanPending)
Jeff Johnson295189b2012-06-20 16:38:30 -070010486 {
Mahesh A Saptasagar0b61dcc2016-02-15 14:23:38 +053010487 wlan_hdd_scan_abort(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070010488 }
Abhishek Singh3ac179b2015-09-21 10:01:34 +053010489 if ((pAdapter->device_mode != WLAN_HDD_INFRA_STATION) &&
10490 (pAdapter->device_mode != WLAN_HDD_IBSS))
Kaushik, Sushant7005e372014-04-08 11:36:54 +053010491 {
10492 while (pAdapter->is_roc_inprogress)
10493 {
10494 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10495 "%s: ROC in progress for session %d!!!",
10496 __func__, pAdapter->sessionId);
10497 // waiting for ROC to expire
10498 msleep(500);
10499 /* In GO present case , if retry exceeds 3,
10500 it means something went wrong. */
10501 if ( retry++ > MAX_WAIT_FOR_ROC_COMPLETION )
10502 {
10503 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10504 "%s: ROC completion is not received.!!!", __func__);
Deepthi Gowri70498252015-01-20 15:56:45 +053010505 if (eHAL_STATUS_SUCCESS !=
10506 sme_CancelRemainOnChannel( WLAN_HDD_GET_HAL_CTX( pAdapter),
10507 pAdapter->sessionId ))
10508 {
10509 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10510 FL("Failed to Cancel Remain on Channel"));
10511 }
Kaushik, Sushant7005e372014-04-08 11:36:54 +053010512 wait_for_completion_interruptible_timeout(
10513 &pAdapter->cancel_rem_on_chan_var,
10514 msecs_to_jiffies(WAIT_CANCEL_REM_CHAN));
10515 break;
10516 }
10517 }
Anand N Sunkaddc63c792015-06-03 14:33:24 +053010518 vos_flush_delayed_work(&pAdapter->roc_work);
Kaushik, Sushant7005e372014-04-08 11:36:54 +053010519 }
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +053010520#ifdef WLAN_NS_OFFLOAD
Anand N Sunkaddc63c792015-06-03 14:33:24 +053010521 vos_flush_work(&pAdapter->ipv6NotifierWorkQueue);
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +053010522#endif
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +053010523
Anand N Sunkaddc63c792015-06-03 14:33:24 +053010524 vos_flush_work(&pAdapter->ipv4NotifierWorkQueue);
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +053010525
Agarwal Ashish3a38bd12014-06-12 15:16:52 +053010526 /* It is possible that the caller of this function does not
10527 * wish to close the session
10528 */
10529 if (VOS_TRUE == bCloseSession &&
10530 test_bit(SME_SESSION_OPENED, &pAdapter->event_flags))
Jeff Johnson295189b2012-06-20 16:38:30 -070010531 {
10532 INIT_COMPLETION(pAdapter->session_close_comp_var);
10533 if (eHAL_STATUS_SUCCESS ==
Agrawal Ashish5a3522c2016-03-02 15:08:28 +053010534 sme_CloseSession(pHddCtx->hHal, pAdapter->sessionId, FALSE,
10535 VOS_FALSE, hdd_smeCloseSessionCallback, pAdapter))
Jeff Johnson295189b2012-06-20 16:38:30 -070010536 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010537 unsigned long ret;
10538
Jeff Johnson295189b2012-06-20 16:38:30 -070010539 //Block on a completion variable. Can't wait forever though.
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010540 ret = wait_for_completion_timeout(
Agarwal Ashish3a38bd12014-06-12 15:16:52 +053010541 &pAdapter->session_close_comp_var,
10542 msecs_to_jiffies(WLAN_WAIT_TIME_SESSIONOPENCLOSE));
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010543 if ( 0 >= ret)
10544 {
10545 hddLog(LOGE, "%s: failure waiting for session_close_comp_var %ld",
Agarwal Ashish3a38bd12014-06-12 15:16:52 +053010546 __func__, ret);
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010547 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010548 }
10549 }
Vinay Krishna Erannab09d3e72014-03-26 21:23:55 +053010550 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010551 break;
10552
10553 case WLAN_HDD_SOFTAP:
Abhishek Singh3dc4c972019-05-09 11:04:24 +053010554 /* Delete all associated STAs before stopping AP */
10555 if (test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
10556 hdd_del_all_sta(pAdapter);
Liangwei Donge5598952020-08-07 10:55:53 +053010557
10558 /* Flush the PMKID cache in CSR */
10559 if (eHAL_STATUS_SUCCESS != sme_RoamDelPMKIDfromCache(pHddCtx->hHal,
10560 pAdapter->sessionId, NULL, TRUE))
10561 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Cannot flush PMKIDCache"));
Abhishek Singh3dc4c972019-05-09 11:04:24 +053010562 /* Fall through */
Jeff Johnson295189b2012-06-20 16:38:30 -070010563 case WLAN_HDD_P2P_GO:
Abhishek Singh3dc4c972019-05-09 11:04:24 +053010564
Nirav Shah0cf4d892015-11-05 16:27:27 +053010565 if ( VOS_TRUE == bCloseSession )
10566 {
10567 status = hdd_sta_id_hash_detach(pAdapter);
10568 if (status != VOS_STATUS_SUCCESS)
10569 hddLog(VOS_TRACE_LEVEL_ERROR,
10570 FL("sta id hash detach failed"));
10571 }
10572
Jeff Johnson295189b2012-06-20 16:38:30 -070010573 //Any softap specific cleanup here...
Anurag Chouhan83026002016-12-13 22:46:21 +053010574 hdd_cleanup_ap_events(pAdapter);
Kaushik, Sushant7005e372014-04-08 11:36:54 +053010575 if (pAdapter->device_mode == WLAN_HDD_P2P_GO) {
10576 while (pAdapter->is_roc_inprogress) {
10577 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10578 "%s: ROC in progress for session %d!!!",
10579 __func__, pAdapter->sessionId);
10580 msleep(500);
10581 if ( retry++ > MAX_WAIT_FOR_ROC_COMPLETION ) {
10582 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10583 "%s: ROC completion is not received.!!!", __func__);
10584 WLANSAP_CancelRemainOnChannel(
10585 (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
10586 wait_for_completion_interruptible_timeout(
10587 &pAdapter->cancel_rem_on_chan_var,
10588 msecs_to_jiffies(WAIT_CANCEL_REM_CHAN));
10589 break;
10590 }
10591 }
Ganesh Kondabattinibabfb492014-12-17 20:25:29 +053010592
Anand N Sunkaddc63c792015-06-03 14:33:24 +053010593 vos_flush_delayed_work(&pAdapter->roc_work);
Kaushik, Sushant7005e372014-04-08 11:36:54 +053010594 }
Agrawal Ashish17ef5082016-10-17 18:33:21 +053010595#ifdef SAP_AUTH_OFFLOAD
10596 if (pHddCtx->cfg_ini->enable_sap_auth_offload)
10597 hdd_set_sap_auth_offload(pAdapter, FALSE);
10598#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010599 mutex_lock(&pHddCtx->sap_lock);
10600 if (test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
10601 {
10602 VOS_STATUS status;
10603 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Hanumanth Reddy Pothula74ba68c2018-06-22 17:52:09 +053010604 hdd_hostapd_state_t *pHostapdState =
10605 WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070010606
Hanumanth Reddy Pothula74ba68c2018-06-22 17:52:09 +053010607 vos_event_reset(&pHostapdState->vosEvent);
Jeff Johnson295189b2012-06-20 16:38:30 -070010608 //Stop Bss.
10609 status = WLANSAP_StopBss(pHddCtx->pvosContext);
10610 if (VOS_IS_STATUS_SUCCESS(status))
10611 {
Jeff Johnson295189b2012-06-20 16:38:30 -070010612 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
10613
10614 if (!VOS_IS_STATUS_SUCCESS(status))
10615 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010616 hddLog(LOGE, "%s: failure waiting for WLANSAP_StopBss %d",
10617 __func__, status);
Jeff Johnson295189b2012-06-20 16:38:30 -070010618 }
10619 }
10620 else
10621 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070010622 hddLog(LOGE, "%s: failure in WLANSAP_StopBss", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070010623 }
10624 clear_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags);
Agarwal Ashish51325b52014-06-16 16:50:49 +053010625 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070010626
10627 if (eHAL_STATUS_FAILURE ==
10628 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG,
10629 0, NULL, eANI_BOOLEAN_FALSE))
10630 {
10631 hddLog(LOGE,
10632 "%s: Failed to set WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070010633 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070010634 }
10635
10636 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt((WLAN_HDD_GET_CTX(pAdapter))->hHal,
10637 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
10638 eANI_BOOLEAN_FALSE) )
10639 {
10640 hddLog(LOGE,
10641 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
10642 }
10643
10644 // Reset WNI_CFG_PROBE_RSP Flags
10645 wlan_hdd_reset_prob_rspies(pAdapter);
10646 kfree(pAdapter->sessionCtx.ap.beacon);
10647 pAdapter->sessionCtx.ap.beacon = NULL;
10648 }
10649 mutex_unlock(&pHddCtx->sap_lock);
Hanumanth Reddy Pothulab4537b82018-03-02 12:20:38 +053010650
10651#ifdef WLAN_NS_OFFLOAD
10652 vos_flush_work(&pAdapter->ipv6NotifierWorkQueue);
10653#endif
10654 vos_flush_work(&pAdapter->ipv4NotifierWorkQueue);
10655
Jeff Johnson295189b2012-06-20 16:38:30 -070010656 break;
Sameer Thalappilbee426e2013-10-30 10:30:30 -070010657
Jeff Johnson295189b2012-06-20 16:38:30 -070010658 case WLAN_HDD_MONITOR:
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +053010659 if (VOS_MONITOR_MODE != hdd_get_conparam())
10660 wlan_hdd_stop_mon(pHddCtx, true);
10661 break;
Sameer Thalappilbee426e2013-10-30 10:30:30 -070010662
Jeff Johnson295189b2012-06-20 16:38:30 -070010663 default:
10664 break;
10665 }
10666
10667 EXIT();
10668 return VOS_STATUS_SUCCESS;
10669}
10670
Kapil Gupta137ef892016-12-13 19:38:00 +053010671/**
10672 * wlan_hdd_restart_sap() - to restart SAP in driver internally
10673 * @ap_adapter: - Pointer to SAP hdd_adapter_t structure
10674 *
10675 * wlan_hdd_restart_sap first delete SAP and do cleanup.
10676 * After that WLANSAP_StartBss start re-start process of SAP.
10677 *
10678 * Return: None
10679 */
10680static void wlan_hdd_restart_sap(hdd_adapter_t *ap_adapter)
10681{
10682 hdd_ap_ctx_t *pHddApCtx;
10683 hdd_hostapd_state_t *pHostapdState;
10684 VOS_STATUS vos_status;
10685 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(ap_adapter);
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053010686#ifdef USE_CFG80211_DEL_STA_V2
Kapil Gupta137ef892016-12-13 19:38:00 +053010687 struct station_del_parameters delStaParams;
10688#endif
10689 tsap_Config_t *pConfig;
10690
10691 pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(ap_adapter);
10692 pConfig = &pHddApCtx->sapConfig;
10693
10694 mutex_lock(&pHddCtx->sap_lock);
10695 if (test_bit(SOFTAP_BSS_STARTED, &ap_adapter->event_flags)) {
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053010696#ifdef USE_CFG80211_DEL_STA_V2
Kapil Gupta137ef892016-12-13 19:38:00 +053010697 delStaParams.mac = NULL;
10698 delStaParams.subtype = SIR_MAC_MGMT_DEAUTH >> 4;
10699 delStaParams.reason_code = eCsrForcedDeauthSta;
10700 wlan_hdd_cfg80211_del_station(ap_adapter->wdev.wiphy, ap_adapter->dev,
10701 &delStaParams);
10702#else
10703 wlan_hdd_cfg80211_del_station(ap_adapter->wdev.wiphy, ap_adapter->dev,
10704 NULL);
10705#endif
10706 hdd_cleanup_actionframe(pHddCtx, ap_adapter);
10707
10708 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(ap_adapter);
10709 vos_event_reset(&pHostapdState->vosEvent);
10710
10711 if (VOS_STATUS_SUCCESS == WLANSAP_StopBss(pHddCtx->pvosContext)) {
10712 vos_status = vos_wait_single_event(&pHostapdState->vosEvent,
10713 10000);
10714 if (!VOS_IS_STATUS_SUCCESS(vos_status)) {
10715 hddLog(LOGE, FL("SAP Stop Failed"));
10716 goto end;
10717 }
10718 }
10719 clear_bit(SOFTAP_BSS_STARTED, &ap_adapter->event_flags);
10720 wlan_hdd_decr_active_session(pHddCtx, ap_adapter->device_mode);
10721 hddLog(LOG1, FL("SAP Stop Success"));
10722
10723 if (0 != wlan_hdd_cfg80211_update_apies(ap_adapter)) {
10724 hddLog(LOGE, FL("SAP Not able to set AP IEs"));
10725 goto end;
10726 }
10727
Hanumanth Reddy Pothula74ba68c2018-06-22 17:52:09 +053010728 vos_event_reset(&pHostapdState->vosEvent);
Kapil Gupta137ef892016-12-13 19:38:00 +053010729 if (WLANSAP_StartBss(pHddCtx->pvosContext, hdd_hostapd_SAPEventCB,
10730 pConfig, (v_PVOID_t)ap_adapter->dev) != VOS_STATUS_SUCCESS) {
10731 hddLog(LOGE, FL("SAP Start Bss fail"));
10732 goto end;
10733 }
10734
10735 hddLog(LOG1, FL("Waiting for SAP to start"));
10736 vos_status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
10737 if (!VOS_IS_STATUS_SUCCESS(vos_status)) {
10738 hddLog(LOGE, FL("SAP Start failed"));
10739 goto end;
10740 }
10741 hddLog(LOG1, FL("SAP Start Success"));
10742 set_bit(SOFTAP_BSS_STARTED, &ap_adapter->event_flags);
10743 wlan_hdd_incr_active_session(pHddCtx, ap_adapter->device_mode);
10744 pHostapdState->bCommit = TRUE;
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053010745 if (!VOS_IS_STATUS_SUCCESS(hdd_dhcp_mdns_offload(ap_adapter))) {
10746 hddLog(VOS_TRACE_LEVEL_ERROR, FL("DHCP/MDNS offload Failed!!"));
10747 vos_event_reset(&pHostapdState->vosEvent);
10748 if (VOS_STATUS_SUCCESS == WLANSAP_StopBss(pHddCtx->pvosContext)) {
10749 vos_status = vos_wait_single_event(&pHostapdState->vosEvent,
10750 10000);
10751 if (!VOS_IS_STATUS_SUCCESS(vos_status)) {
10752 hddLog(LOGE, FL("SAP Stop Failed"));
10753 goto end;
10754 }
10755 }
10756 }
Kapil Gupta137ef892016-12-13 19:38:00 +053010757 }
10758end:
10759 mutex_unlock(&pHddCtx->sap_lock);
10760 return;
10761}
10762
10763/**
10764 * __hdd_sap_restart_handle() - to handle restarting of SAP
10765 * @work: name of the work
10766 *
10767 * Purpose of this function is to trigger sap start. this function
10768 * will be called from workqueue.
10769 *
10770 * Return: void.
10771 */
10772static void __hdd_sap_restart_handle(struct work_struct *work)
10773{
10774 hdd_adapter_t *sap_adapter;
10775 hdd_context_t *hdd_ctx = container_of(work,
10776 hdd_context_t,
10777 sap_start_work);
10778 if (0 != wlan_hdd_validate_context(hdd_ctx)) {
10779 vos_ssr_unprotect(__func__);
10780 return;
10781 }
10782 sap_adapter = hdd_get_adapter(hdd_ctx,
10783 WLAN_HDD_SOFTAP);
10784 if (sap_adapter == NULL) {
10785 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10786 FL("sap_adapter is NULL"));
10787 vos_ssr_unprotect(__func__);
10788 return;
10789 }
10790
10791 if (hdd_ctx->is_ch_avoid_in_progress) {
10792 sap_adapter->sessionCtx.ap.sapConfig.channel = AUTO_CHANNEL_SELECT;
10793 wlan_hdd_restart_sap(sap_adapter);
10794 hdd_change_ch_avoidance_status(hdd_ctx, false);
10795 }
Agrawal Ashish574b3e62017-02-09 18:58:34 +053010796 if (hdd_ctx->cfg_ini->enable_sap_auth_offload)
10797 wlan_hdd_restart_sap(sap_adapter);
Kapil Gupta137ef892016-12-13 19:38:00 +053010798}
10799
10800/**
10801 * hdd_sap_restart_handle() - to handle restarting of SAP
10802 * @work: name of the work
10803 *
10804 * Purpose of this function is to trigger sap start. this function
10805 * will be called from workqueue.
10806 *
10807 * Return: void.
10808 */
10809static void hdd_sap_restart_handle(struct work_struct *work)
10810{
10811 vos_ssr_protect(__func__);
10812 __hdd_sap_restart_handle(work);
10813 vos_ssr_unprotect(__func__);
10814}
10815
10816
Abhishek Singh78c691f2017-11-30 13:48:44 +053010817/**
10818 * __hdd_force_scc_with_ecsa_handle() - to handle force scc using ecsa
10819 * @work: name of the work
10820 *
10821 * Purpose of this function is to force SCC using ECSA. This function
10822 * will be called from workqueue.
10823 *
10824 * Return: void.
10825 */
10826static void
10827__hdd_force_scc_with_ecsa_handle(struct work_struct *work)
10828{
10829 hdd_adapter_t *sap_adapter;
10830 hdd_station_ctx_t *sta_ctx;
10831 hdd_adapter_t *sta_adapter;
Ganesh Kondabattini3655a6d2018-01-08 20:25:39 +053010832 ptSapContext sap_ctx = NULL;
10833 v_CONTEXT_t vos_ctx;
10834 tANI_U8 target_channel;
10835 tsap_Config_t *sap_config;
10836 bool sta_sap_scc_on_dfs_chan;
10837 eNVChannelEnabledType chan_state;
Abhishek Singh78c691f2017-11-30 13:48:44 +053010838 hdd_context_t *hdd_ctx = container_of(to_delayed_work(work),
10839 hdd_context_t,
10840 ecsa_chan_change_work);
10841
10842 if (wlan_hdd_validate_context(hdd_ctx))
10843 return;
10844
10845 sap_adapter = hdd_get_adapter(hdd_ctx,
10846 WLAN_HDD_SOFTAP);
10847 if (!sap_adapter) {
10848 hddLog(LOGE, FL("sap_adapter is NULL"));
10849 return;
10850 }
10851
Ganesh Kondabattini3655a6d2018-01-08 20:25:39 +053010852 vos_ctx = hdd_ctx->pvosContext;
10853 if (!vos_ctx) {
10854 hddLog(LOGE, FL("vos_ctx is NULL"));
10855 return;
10856 }
10857
10858 sap_ctx = VOS_GET_SAP_CB(vos_ctx);
10859 if (!sap_ctx) {
10860 hddLog(LOGE, FL("sap_ctx is NULL"));
10861 return;
10862 }
10863
10864 sap_config = &sap_adapter->sessionCtx.ap.sapConfig;
10865
10866 sta_sap_scc_on_dfs_chan = hdd_is_sta_sap_scc_allowed_on_dfs_chan(hdd_ctx);
10867
Abhishek Singh78c691f2017-11-30 13:48:44 +053010868 sta_adapter = hdd_get_adapter(hdd_ctx,
10869 WLAN_HDD_INFRA_STATION);
10870 if (!sta_adapter) {
10871 hddLog(LOGE, FL("sta_adapter is NULL"));
10872 return;
10873 }
Abhishek Singh78c691f2017-11-30 13:48:44 +053010874
Abhishek Singh10e17cf2018-03-12 14:34:22 +053010875 if (wlansap_chk_n_set_chan_change_in_progress(sap_ctx))
Abhishek Singh78c691f2017-11-30 13:48:44 +053010876 return;
Abhishek Singh10e17cf2018-03-12 14:34:22 +053010877 INIT_COMPLETION(sap_ctx->ecsa_info.chan_switch_comp);
10878
10879 sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(sta_adapter);
10880 if (sta_ctx->conn_info.connState != eConnectionState_Associated) {
10881 if (sta_ctx->conn_info.connState == eConnectionState_NotConnected) {
10882 chan_state = vos_nv_getChannelEnabledState(sap_ctx->channel);
10883 hddLog(LOG1, FL("sta not in connected state %d, sta_sap_scc_on_dfs_chan %d, chan_state %d"),
10884 sta_ctx->conn_info.connState, sta_sap_scc_on_dfs_chan,
10885 chan_state);
10886 if (sta_sap_scc_on_dfs_chan &&
10887 (chan_state == NV_CHANNEL_DFS)) {
10888 hddLog(LOGE, FL("Switch SAP to user configured channel"));
10889 target_channel = sap_config->user_config_channel;
10890 goto switch_channel;
10891 }
10892 }
10893 goto abort;
Abhishek Singh78c691f2017-11-30 13:48:44 +053010894 }
10895
Ganesh Kondabattini3655a6d2018-01-08 20:25:39 +053010896 target_channel = sta_ctx->conn_info.operationChannel;
10897switch_channel:
10898 hddLog(LOGE, FL("Switch SAP to %d channel"),
10899 target_channel);
Abhishek Singh10e17cf2018-03-12 14:34:22 +053010900 if (!wlansap_set_channel_change(vos_ctx, target_channel, true))
10901 return;
10902
10903abort:
10904 wlansap_reset_chan_change_in_progress(sap_ctx);
10905 complete(&sap_ctx->ecsa_info.chan_switch_comp);
Abhishek Singh78c691f2017-11-30 13:48:44 +053010906}
10907
10908/**
10909 * hdd_force_scc_with_ecsa_handle() - to handle force scc using ecsa
10910 * @work: name of the work
10911 *
10912 * Purpose of this function is to force SCC using ECSA. This function
10913 * will be called from workqueue.
10914 *
10915 * Return: void.
10916 */
10917static void
10918hdd_force_scc_with_ecsa_handle(struct work_struct *work)
10919{
10920 vos_ssr_protect(__func__);
10921 __hdd_force_scc_with_ecsa_handle(work);
10922 vos_ssr_unprotect(__func__);
10923}
10924
Abhishek Singh10e17cf2018-03-12 14:34:22 +053010925int hdd_wait_for_ecsa_complete(hdd_context_t *hdd_ctx)
10926{
10927 int ret;
10928 ptSapContext sap_ctx = NULL;
10929 v_CONTEXT_t vos_ctx;
10930
10931 vos_ctx = hdd_ctx->pvosContext;
10932 if (!vos_ctx) {
10933 hddLog(LOGE, FL("vos_ctx is NULL"));
10934 return 0;
10935 }
10936
10937 sap_ctx = VOS_GET_SAP_CB(vos_ctx);
10938 if (!sap_ctx) {
10939 hddLog(LOG1, FL("sap_ctx is NULL"));
10940 return 0;
10941 }
10942 if(!sap_ctx->isSapSessionOpen) {
10943 hddLog(LOG1, FL("sap session not opened, SAP in state %d"),
10944 sap_ctx->sapsMachine);
10945 return 0;
10946 }
10947
10948 if (!wlansap_get_change_in_progress(sap_ctx)) {
10949 hddLog(LOG1, FL("channel switch not in progress"));
10950 return 0;
10951 }
10952 ret = wait_for_completion_timeout(&sap_ctx->ecsa_info.chan_switch_comp,
10953 msecs_to_jiffies(HDD_SAP_CHAN_CNG_WAIT_TIME));
10954 if (!ret)
10955 {
10956 hddLog(LOGE, FL("Timeout waiting for SAP channel switch"));
10957 return ret;
10958 }
10959
10960 return 0;
10961}
10962
10963
Ganesh Kondabattini3655a6d2018-01-08 20:25:39 +053010964/**
10965 * hdd_is_sta_sap_scc_allowed_on_dfs_chan() - check if sta+sap scc allowed on
10966 * dfs chan
10967 * @hdd_ctx: pointer to hdd context
10968 *
10969 * This function used to check if sta+sap scc allowed on DFS channel.
10970 *
10971 * Return: None
10972 */
10973bool hdd_is_sta_sap_scc_allowed_on_dfs_chan(hdd_context_t *hdd_ctx)
10974{
10975 if (hdd_ctx->cfg_ini->force_scc_with_ecsa &&
10976 hdd_ctx->cfg_ini->sta_sap_scc_on_dfs_chan)
10977 return true;
10978 else
10979 return false;
10980}
10981
Jeff Johnson295189b2012-06-20 16:38:30 -070010982VOS_STATUS hdd_stop_all_adapters( hdd_context_t *pHddCtx )
10983{
10984 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
10985 VOS_STATUS status;
10986 hdd_adapter_t *pAdapter;
10987
10988 ENTER();
10989
10990 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
10991
10992 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
10993 {
10994 pAdapter = pAdapterNode->pAdapter;
Jeff Johnson295189b2012-06-20 16:38:30 -070010995
Agarwal Ashish3a38bd12014-06-12 15:16:52 +053010996 hdd_stop_adapter( pHddCtx, pAdapter, VOS_TRUE );
Jeff Johnson295189b2012-06-20 16:38:30 -070010997
10998 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
10999 pAdapterNode = pNext;
11000 }
11001
11002 EXIT();
11003
11004 return VOS_STATUS_SUCCESS;
11005}
11006
Rajeev Kumarf999e582014-01-09 17:33:29 -080011007
11008#ifdef FEATURE_WLAN_BATCH_SCAN
11009/**---------------------------------------------------------------------------
11010
11011 \brief hdd_deinit_batch_scan () - This function cleans up batch scan data
11012 structures
11013
11014 \param - pAdapter Pointer to HDD adapter
11015
11016 \return - None
11017
11018 --------------------------------------------------------------------------*/
11019void hdd_deinit_batch_scan(hdd_adapter_t *pAdapter)
11020{
11021 tHddBatchScanRsp *pNode;
11022 tHddBatchScanRsp *pPrev;
11023
Siddharth Bhalb3e9b792014-02-24 15:14:16 +053011024 if (NULL == pAdapter)
Rajeev Kumarf999e582014-01-09 17:33:29 -080011025 {
Siddharth Bhalb3e9b792014-02-24 15:14:16 +053011026 hddLog(VOS_TRACE_LEVEL_ERROR,
11027 "%s: Adapter context is Null", __func__);
11028 return;
11029 }
11030
11031 pNode = pAdapter->pBatchScanRsp;
11032 while (pNode)
11033 {
11034 pPrev = pNode;
11035 pNode = pNode->pNext;
11036 vos_mem_free((v_VOID_t * )pPrev);
Rajeev Kumarf999e582014-01-09 17:33:29 -080011037 }
11038
11039 pAdapter->pBatchScanRsp = NULL;
11040 pAdapter->numScanList = 0;
11041 pAdapter->batchScanState = eHDD_BATCH_SCAN_STATE_STOPPED;
11042 pAdapter->prev_batch_id = 0;
11043
11044 return;
11045}
11046#endif
11047
11048
Jeff Johnson295189b2012-06-20 16:38:30 -070011049VOS_STATUS hdd_reset_all_adapters( hdd_context_t *pHddCtx )
11050{
11051 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
11052 VOS_STATUS status;
11053 hdd_adapter_t *pAdapter;
11054
11055 ENTER();
11056
11057 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
11058
11059 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
11060 {
11061 pAdapter = pAdapterNode->pAdapter;
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +053011062 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Jeff Johnson295189b2012-06-20 16:38:30 -070011063 netif_tx_disable(pAdapter->dev);
Hanumanth Reddy Pothulad864f312017-01-18 16:16:08 +053011064
11065 if (pHddCtx->cfg_ini->sap_internal_restart &&
11066 pAdapter->device_mode == WLAN_HDD_SOFTAP) {
11067 hddLog(LOG1, FL("driver supports sap restart"));
11068 vos_flush_work(&pHddCtx->sap_start_work);
11069 hdd_sap_indicate_disconnect_for_sta(pAdapter);
11070 hdd_cleanup_actionframe(pHddCtx, pAdapter);
Hanumanth Reddy Pothula15bc0fa2017-02-03 17:24:17 +053011071 hdd_softap_deinit_tx_rx(pAdapter, true);
11072 hdd_sap_destroy_timers(pAdapter);
Hanumanth Reddy Pothulad864f312017-01-18 16:16:08 +053011073 } else {
11074 netif_carrier_off(pAdapter->dev);
11075 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011076
Srinivas Girigowda66c05eb2013-07-14 13:06:01 -070011077 pAdapter->sessionCtx.station.hdd_ReassocScenario = VOS_FALSE;
Hanumanth Reddy Pothulada449f12018-03-13 18:19:19 +053011078
11079 if (pAdapter->device_mode == WLAN_HDD_MONITOR)
11080 pAdapter->sessionCtx.monitor.state = MON_MODE_STOP;
Srinivas Girigowda66c05eb2013-07-14 13:06:01 -070011081
Surabhi Vishnoia0be8f52020-07-08 17:43:16 +053011082 if (test_bit(DEVICE_IFACE_OPENED, &pAdapterNode->pAdapter->event_flags))
11083 hdd_deinit_tx_rx(pAdapter);
Agarwal Ashish6267caa2014-08-06 19:16:21 +053011084
Katya Nigam1fd24402015-02-16 14:52:19 +053011085 if(pAdapter->device_mode == WLAN_HDD_IBSS )
11086 hdd_ibss_deinit_tx_rx(pAdapter);
11087
Surabhi Vishnoia0be8f52020-07-08 17:43:16 +053011088 if (test_bit(DEVICE_IFACE_OPENED, &pAdapterNode->pAdapter->event_flags)) {
11089 status = hdd_sta_id_hash_detach(pAdapter);
11090 if (status != VOS_STATUS_SUCCESS)
11091 hddLog(VOS_TRACE_LEVEL_ERROR,
11092 FL("sta id hash detach failed for session id %d"),
11093 pAdapter->sessionId);
11094 }
Nirav Shah7e3c8132015-06-22 23:51:42 +053011095
Agarwal Ashish6267caa2014-08-06 19:16:21 +053011096 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
11097
Madan Mohan Koyyalamudi8c6dec82013-09-26 15:56:13 +053011098 if (test_bit(WMM_INIT_DONE, &pAdapter->event_flags))
11099 {
11100 hdd_wmm_adapter_close( pAdapter );
11101 clear_bit(WMM_INIT_DONE, &pAdapter->event_flags);
11102 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011103
Siddharth Bhal2db319d2014-12-03 12:37:18 +053011104 if (test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
11105 {
11106 clear_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags);
11107 }
11108
Rajeev Kumarf999e582014-01-09 17:33:29 -080011109#ifdef FEATURE_WLAN_BATCH_SCAN
11110 if (eHDD_BATCH_SCAN_STATE_STARTED == pAdapter->batchScanState)
11111 {
11112 hdd_deinit_batch_scan(pAdapter);
11113 }
11114#endif
11115
Mahesh A Saptasagarf5b8eff2015-01-31 01:07:07 +053011116#ifdef FEATURE_WLAN_TDLS
11117 mutex_lock(&pHddCtx->tdls_lock);
Pradeep Reddy POTTETI2d4d5c42015-03-03 14:34:19 +053011118 wlan_hdd_tdls_exit(pAdapter, TRUE);
Mahesh A Saptasagarf5b8eff2015-01-31 01:07:07 +053011119 mutex_unlock(&pHddCtx->tdls_lock);
11120#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070011121 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
11122 pAdapterNode = pNext;
11123 }
11124
11125 EXIT();
11126
11127 return VOS_STATUS_SUCCESS;
11128}
11129
Abhishek Singhbbe0b2a2016-12-05 11:57:36 +053011130/**
Abhishek Singh5a597e62016-12-05 15:16:30 +053011131 * hdd_get_bss_entry() - Get the bss entry matching the chan, bssid and ssid
11132 * @wiphy: wiphy
11133 * @channel: channel of the BSS to find
11134 * @bssid: bssid of the BSS to find
11135 * @ssid: ssid of the BSS to find
11136 * @ssid_len: ssid len of of the BSS to find
11137 *
11138 * The API is a wrapper to get bss from kernel matching the chan,
11139 * bssid and ssid
11140 *
11141 * Return: Void
11142 */
11143#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 1, 0)) \
11144 && !defined(WITH_BACKPORTS) && !defined(IEEE80211_PRIVACY)
11145
11146struct cfg80211_bss* hdd_get_bss_entry(struct wiphy *wiphy,
11147 struct ieee80211_channel *channel,
11148 const u8 *bssid,
11149 const u8 *ssid, size_t ssid_len)
11150{
11151 return cfg80211_get_bss(wiphy, channel, bssid,
11152 ssid, ssid_len,
11153 WLAN_CAPABILITY_ESS,
11154 WLAN_CAPABILITY_ESS);
11155}
11156#else
11157struct cfg80211_bss* hdd_get_bss_entry(struct wiphy *wiphy,
11158 struct ieee80211_channel *channel,
11159 const u8 *bssid,
11160 const u8 *ssid, size_t ssid_len)
11161{
11162 return cfg80211_get_bss(wiphy, channel, bssid,
11163 ssid, ssid_len,
11164 IEEE80211_BSS_TYPE_ESS,
11165 IEEE80211_PRIVACY_ANY);
11166}
11167#endif
11168
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053011169#if defined(CFG80211_CONNECT_BSS) || \
11170 (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 7, 0))
11171
11172#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 11, 0) || \
11173 defined (CFG80211_CONNECT_TIMEOUT_REASON_CODE)
11174/**
11175 * hdd_connect_bss() - helper function to send connection status to supplicant
11176 * @dev: network device
11177 * @bssid: bssid to which we want to associate
11178 * @bss: information about connected bss
11179 * @req_ie: Request Information Element
11180 * @req_ie_len: len of the req IE
11181 * @resp_ie: Response IE
11182 * @resp_ie_len: len of ht response IE
11183 * @status: status
11184 * @gfp: Kernel Flag
11185 *
11186 * This is a helper function to send connection status to supplicant
11187 * and gets invoked from wrapper API
11188 *
11189 * Return: Void
11190 */
11191static void hdd_connect_bss(struct net_device *dev,
11192 const u8 *bssid,
11193 struct cfg80211_bss *bss,
11194 const u8 *req_ie,
11195 size_t req_ie_len,
11196 const u8 *resp_ie,
11197 size_t resp_ie_len,
11198 u16 status,
11199 gfp_t gfp)
11200{
11201 cfg80211_connect_bss(dev, bssid, bss, req_ie, req_ie_len,
11202 resp_ie, resp_ie_len, status, gfp, NL80211_TIMEOUT_UNSPECIFIED);
11203}
11204#else
11205/**
11206 * hdd_connect_bss() - helper function to send connection status to supplicant
11207 * @dev: network device
11208 * @bssid: bssid to which we want to associate
11209 * @bss: information about connected bss
11210 * @req_ie: Request Information Element
11211 * @req_ie_len: len of the req IE
11212 * @resp_ie: Response IE
11213 * @resp_ie_len: len of ht response IE
11214 * @status: status
11215 * @gfp: Kernel Flag
11216 *
11217 * This is a helper function to send connection status to supplicant
11218 * and gets invoked from wrapper API
11219 *
11220 * Return: Void
11221 */
11222static void hdd_connect_bss(struct net_device *dev,
11223 const u8 *bssid,
11224 struct cfg80211_bss *bss,
11225 const u8 *req_ie,
11226 size_t req_ie_len,
11227 const u8 *resp_ie,
11228 size_t resp_ie_len,
11229 u16 status,
11230 gfp_t gfp)
11231{
11232 cfg80211_connect_bss(dev, bssid, bss, req_ie, req_ie_len,
11233 resp_ie, resp_ie_len, status, gfp);
11234}
11235#endif
11236
Abhishek Singh5a597e62016-12-05 15:16:30 +053011237/**
Abhishek Singhbbe0b2a2016-12-05 11:57:36 +053011238 * hdd_connect_result() - API to send connection status to supplicant
11239 * @dev: network device
11240 * @bssid: bssid to which we want to associate
11241 * @roam_info: information about connected bss
11242 * @req_ie: Request Information Element
11243 * @req_ie_len: len of the req IE
11244 * @resp_ie: Response IE
11245 * @resp_ie_len: len of ht response IE
11246 * @status: status
11247 * @gfp: Kernel Flag
11248 *
11249 * The API is a wrapper to send connection status to supplicant
11250 *
11251 * Return: Void
11252 */
Abhishek Singhbbe0b2a2016-12-05 11:57:36 +053011253void hdd_connect_result(struct net_device *dev,
11254 const u8 *bssid,
11255 tCsrRoamInfo *roam_info,
11256 const u8 *req_ie,
11257 size_t req_ie_len,
11258 const u8 *resp_ie,
11259 size_t resp_ie_len,
11260 u16 status,
11261 gfp_t gfp)
11262{
11263 hdd_adapter_t *padapter = (hdd_adapter_t *) netdev_priv(dev);
11264 struct cfg80211_bss *bss = NULL;
11265
11266 if (WLAN_STATUS_SUCCESS == status) {
11267 struct ieee80211_channel *chan;
11268 int freq;
11269 int chan_no = roam_info->pBssDesc->channelId;;
11270
11271 if (chan_no <= 14)
11272 freq = ieee80211_channel_to_frequency(chan_no,
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053011273 HDD_NL80211_BAND_2GHZ);
Abhishek Singhbbe0b2a2016-12-05 11:57:36 +053011274 else
11275 freq = ieee80211_channel_to_frequency(chan_no,
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053011276 HDD_NL80211_BAND_5GHZ);
Abhishek Singhbbe0b2a2016-12-05 11:57:36 +053011277
11278 chan = ieee80211_get_channel(padapter->wdev.wiphy, freq);
Abhishek Singh5a597e62016-12-05 15:16:30 +053011279 bss = hdd_get_bss_entry(padapter->wdev.wiphy,
11280 chan, bssid,
11281 roam_info->u.pConnectedProfile->SSID.ssId,
11282 roam_info->u.pConnectedProfile->SSID.length);
Abhishek Singhbbe0b2a2016-12-05 11:57:36 +053011283 }
11284
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053011285 hdd_connect_bss(dev, bssid, bss, req_ie, req_ie_len, resp_ie, resp_ie_len,
11286 status, gfp);
Abhishek Singhbbe0b2a2016-12-05 11:57:36 +053011287}
11288#else
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053011289/**
11290 * hdd_connect_result() - API to send connection status to supplicant
11291 * @dev: network device
11292 * @bssid: bssid to which we want to associate
11293 * @roam_info: information about connected bss
11294 * @req_ie: Request Information Element
11295 * @req_ie_len: len of the req IE
11296 * @resp_ie: Response IE
11297 * @resp_ie_len: len of ht response IE
11298 * @status: status
11299 * @gfp: Kernel Flag
11300 *
11301 * The API is a wrapper to send connection status to supplicant
11302 *
11303 * Return: Void
11304 */
Abhishek Singhbbe0b2a2016-12-05 11:57:36 +053011305void hdd_connect_result(struct net_device *dev,
11306 const u8 *bssid,
11307 tCsrRoamInfo *roam_info,
11308 const u8 *req_ie,
11309 size_t req_ie_len,
11310 const u8 * resp_ie,
11311 size_t resp_ie_len,
11312 u16 status,
11313 gfp_t gfp)
11314{
11315 cfg80211_connect_result(dev, bssid, req_ie, req_ie_len,
11316 resp_ie, resp_ie_len, status, gfp);
11317}
11318#endif
11319
Jeff Johnson295189b2012-06-20 16:38:30 -070011320VOS_STATUS hdd_start_all_adapters( hdd_context_t *pHddCtx )
11321{
11322 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
11323 VOS_STATUS status;
11324 hdd_adapter_t *pAdapter;
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +053011325 eConnectionState connState;
Hanumanth Reddy Pothulada449f12018-03-13 18:19:19 +053011326 v_CONTEXT_t pVosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -070011327
11328 ENTER();
11329
11330 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
11331
11332 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
11333 {
11334 pAdapter = pAdapterNode->pAdapter;
11335
Kumar Anand82c009f2014-05-29 00:29:42 -070011336 hdd_wmm_init( pAdapter );
11337
Jeff Johnson295189b2012-06-20 16:38:30 -070011338 switch(pAdapter->device_mode)
11339 {
11340 case WLAN_HDD_INFRA_STATION:
11341 case WLAN_HDD_P2P_CLIENT:
Jeff Johnsone7245742012-09-05 17:12:55 -070011342 case WLAN_HDD_P2P_DEVICE:
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +053011343
11344 connState = (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState;
11345
Jeff Johnson295189b2012-06-20 16:38:30 -070011346 hdd_init_station_mode(pAdapter);
11347 /* Open the gates for HDD to receive Wext commands */
11348 pAdapter->isLinkUpSvcNeeded = FALSE;
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070011349 pHddCtx->scan_info.mScanPending = FALSE;
11350 pHddCtx->scan_info.waitScanResult = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070011351
11352 //Trigger the initial scan
Mukul Sharmae74e42c2015-08-06 23:55:49 +053011353 if (!pHddCtx->isLogpInProgress)
11354 hdd_wlan_initial_scan(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070011355
11356 //Indicate disconnect event to supplicant if associated previously
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +053011357 if (eConnectionState_Associated == connState ||
11358 eConnectionState_IbssConnected == connState )
Jeff Johnson295189b2012-06-20 16:38:30 -070011359 {
11360 union iwreq_data wrqu;
11361 memset(&wrqu, '\0', sizeof(wrqu));
11362 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
11363 memset(wrqu.ap_addr.sa_data,'\0',ETH_ALEN);
11364 wireless_send_event(pAdapter->dev, SIOCGIWAP, &wrqu, NULL);
Srinivas Girigowda66c05eb2013-07-14 13:06:01 -070011365 pAdapter->sessionCtx.station.hdd_ReassocScenario = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070011366
Jeff Johnson295189b2012-06-20 16:38:30 -070011367 /* indicate disconnected event to nl80211 */
Mahesh A Saptasagar9ff4bcc2016-06-01 17:17:50 +053011368 wlan_hdd_cfg80211_indicate_disconnect(pAdapter->dev, false,
Mahesh A Saptasagarb5a15142016-05-25 11:27:43 +053011369 WLAN_REASON_UNSPECIFIED);
Jeff Johnson295189b2012-06-20 16:38:30 -070011370 }
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +053011371 else if (eConnectionState_Connecting == connState)
11372 {
11373 /*
11374 * Indicate connect failure to supplicant if we were in the
11375 * process of connecting
11376 */
Abhishek Singhbbe0b2a2016-12-05 11:57:36 +053011377 hdd_connect_result(pAdapter->dev, NULL, NULL,
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +053011378 NULL, 0, NULL, 0,
11379 WLAN_STATUS_ASSOC_DENIED_UNSPEC,
11380 GFP_KERNEL);
11381 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011382 break;
11383
11384 case WLAN_HDD_SOFTAP:
Hanumanth Reddy Pothulad864f312017-01-18 16:16:08 +053011385 if (pHddCtx->cfg_ini->sap_internal_restart) {
Hanumanth Reddy Pothula15bc0fa2017-02-03 17:24:17 +053011386 hdd_init_ap_mode(pAdapter, true);
Hanumanth Reddy Pothulad864f312017-01-18 16:16:08 +053011387 status = hdd_sta_id_hash_attach(pAdapter);
11388 if (VOS_STATUS_SUCCESS != status)
11389 {
11390 hddLog(VOS_TRACE_LEVEL_FATAL,
11391 FL("failed to attach hash for"));
11392 }
11393 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011394 break;
11395
11396 case WLAN_HDD_P2P_GO:
Sameer Thalappiledf0d792013-08-09 14:31:03 -070011397 hddLog(VOS_TRACE_LEVEL_ERROR, "%s [SSR] send stop ap to supplicant",
Jeff Johnson295189b2012-06-20 16:38:30 -070011398 __func__);
Sameer Thalappiledf0d792013-08-09 14:31:03 -070011399 cfg80211_ap_stopped(pAdapter->dev, GFP_KERNEL);
Jeff Johnson295189b2012-06-20 16:38:30 -070011400 break;
11401
11402 case WLAN_HDD_MONITOR:
Hanumanth Reddy Pothulada449f12018-03-13 18:19:19 +053011403 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
11404
11405 hddLog(VOS_TRACE_LEVEL_INFO, FL("[SSR] monitor mode"));
11406 if (!pVosContext) {
11407 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos context is NULL"));
11408 break;
11409 }
11410
11411 hdd_init_tx_rx(pAdapter);
11412 WLANTL_SetMonRxCbk( pVosContext, hdd_rx_packet_monitor_cbk);
Jeff Johnson295189b2012-06-20 16:38:30 -070011413 break;
Hanumanth Reddy Pothulada449f12018-03-13 18:19:19 +053011414
Jeff Johnson295189b2012-06-20 16:38:30 -070011415 default:
11416 break;
11417 }
11418
11419 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
11420 pAdapterNode = pNext;
11421 }
11422
11423 EXIT();
11424
11425 return VOS_STATUS_SUCCESS;
11426}
11427
11428VOS_STATUS hdd_reconnect_all_adapters( hdd_context_t *pHddCtx )
11429{
11430 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
11431 hdd_adapter_t *pAdapter;
11432 VOS_STATUS status;
11433 v_U32_t roamId;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011434 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070011435
11436 ENTER();
11437
11438 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
11439
11440 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
11441 {
11442 pAdapter = pAdapterNode->pAdapter;
11443
11444 if( (WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
11445 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
11446 {
11447 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
11448 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
11449
Abhishek Singhf4669da2014-05-26 15:07:49 +053011450 hddLog(VOS_TRACE_LEVEL_INFO,
11451 "%s: Set HDD connState to eConnectionState_NotConnected",
11452 __func__);
Ganesh Kondabattini04338412015-09-14 15:39:09 +053011453 spin_lock_bh(&pAdapter->lock_for_active_session);
11454 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState)
11455 {
11456 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
11457 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011458 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
Ganesh Kondabattini04338412015-09-14 15:39:09 +053011459 spin_unlock_bh(&pAdapter->lock_for_active_session);
Jeff Johnson295189b2012-06-20 16:38:30 -070011460 init_completion(&pAdapter->disconnect_comp_var);
11461 sme_RoamDisconnect(pHddCtx->hHal, pAdapter->sessionId,
11462 eCSR_DISCONNECT_REASON_UNSPECIFIED);
11463
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011464 ret = wait_for_completion_interruptible_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -070011465 &pAdapter->disconnect_comp_var,
11466 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011467 if (0 >= ret)
11468 hddLog(LOGE, "%s: failure waiting for disconnect_comp_var %ld",
11469 __func__, ret);
Jeff Johnson295189b2012-06-20 16:38:30 -070011470
11471 pWextState->roamProfile.csrPersona = pAdapter->device_mode;
11472 pHddCtx->isAmpAllowed = VOS_FALSE;
11473 sme_RoamConnect(pHddCtx->hHal,
11474 pAdapter->sessionId, &(pWextState->roamProfile),
11475 &roamId);
11476 }
11477
11478 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
11479 pAdapterNode = pNext;
11480 }
11481
11482 EXIT();
11483
11484 return VOS_STATUS_SUCCESS;
11485}
11486
Sudhir Sattayappa Kohalli90e4c752013-03-21 14:25:04 -070011487void hdd_dump_concurrency_info(hdd_context_t *pHddCtx)
11488{
11489 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
11490 VOS_STATUS status;
11491 hdd_adapter_t *pAdapter;
11492 hdd_station_ctx_t *pHddStaCtx;
11493 hdd_ap_ctx_t *pHddApCtx;
11494 hdd_hostapd_state_t * pHostapdState;
11495 tCsrBssid staBssid = { 0 }, p2pBssid = { 0 }, apBssid = { 0 };
11496 v_U8_t staChannel = 0, p2pChannel = 0, apChannel = 0;
11497 const char *p2pMode = "DEV";
11498 const char *ccMode = "Standalone";
Sudhir Sattayappa Kohalli90e4c752013-03-21 14:25:04 -070011499
11500 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
11501 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
11502 {
11503 pAdapter = pAdapterNode->pAdapter;
11504 switch (pAdapter->device_mode) {
11505 case WLAN_HDD_INFRA_STATION:
11506 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
11507 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState) {
11508 staChannel = pHddStaCtx->conn_info.operationChannel;
11509 memcpy(staBssid, pHddStaCtx->conn_info.bssId, sizeof(staBssid));
11510 }
11511 break;
11512 case WLAN_HDD_P2P_CLIENT:
11513 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
11514 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState) {
11515 p2pChannel = pHddStaCtx->conn_info.operationChannel;
11516 memcpy(p2pBssid, pHddStaCtx->conn_info.bssId, sizeof(p2pBssid));
11517 p2pMode = "CLI";
11518 }
11519 break;
11520 case WLAN_HDD_P2P_GO:
11521 pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
11522 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
11523 if (pHostapdState->bssState == BSS_START && pHostapdState->vosStatus==VOS_STATUS_SUCCESS) {
11524 p2pChannel = pHddApCtx->operatingChannel;
11525 memcpy(p2pBssid, pAdapter->macAddressCurrent.bytes, sizeof(p2pBssid));
11526 }
11527 p2pMode = "GO";
11528 break;
11529 case WLAN_HDD_SOFTAP:
11530 pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
11531 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
11532 if (pHostapdState->bssState == BSS_START && pHostapdState->vosStatus==VOS_STATUS_SUCCESS) {
11533 apChannel = pHddApCtx->operatingChannel;
11534 memcpy(apBssid, pAdapter->macAddressCurrent.bytes, sizeof(apBssid));
11535 }
11536 break;
11537 default:
11538 break;
11539 }
11540 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
11541 pAdapterNode = pNext;
11542 }
11543 if (staChannel > 0 && (apChannel > 0 || p2pChannel > 0)) {
11544 ccMode = (p2pChannel==staChannel||apChannel==staChannel) ? "SCC" : "MCC";
11545 }
Yeshwanth Sriram Guntuka0004c0b2017-12-06 14:43:49 +053011546 hddLog(VOS_TRACE_LEVEL_ERROR, "wlan(%d) " MAC_ADDRESS_STR " %s",
11547 staChannel, MAC_ADDR_ARRAY(staBssid), ccMode);
Sudhir Sattayappa Kohalli90e4c752013-03-21 14:25:04 -070011548 if (p2pChannel > 0) {
Sushant Kaushikdc3184b2015-10-09 12:00:21 +053011549 hddLog(VOS_TRACE_LEVEL_ERROR, "p2p-%s(%d) " MAC_ADDRESS_STR,
Sudhir Sattayappa Kohalli90e4c752013-03-21 14:25:04 -070011550 p2pMode, p2pChannel, MAC_ADDR_ARRAY(p2pBssid));
11551 }
11552 if (apChannel > 0) {
Sushant Kaushikdc3184b2015-10-09 12:00:21 +053011553 hddLog(VOS_TRACE_LEVEL_ERROR, "AP(%d) " MAC_ADDRESS_STR,
Sudhir Sattayappa Kohalli90e4c752013-03-21 14:25:04 -070011554 apChannel, MAC_ADDR_ARRAY(apBssid));
11555 }
11556
11557 if (p2pChannel > 0 && apChannel > 0) {
11558 hddLog(VOS_TRACE_LEVEL_ERROR, "Error concurrent SAP %d and P2P %d which is not support", apChannel, p2pChannel);
11559 }
11560}
11561
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -070011562bool hdd_is_ssr_required( void)
Jeff Johnson295189b2012-06-20 16:38:30 -070011563{
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -070011564 return (isSsrRequired == HDD_SSR_REQUIRED);
Jeff Johnson295189b2012-06-20 16:38:30 -070011565}
11566
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -070011567/* Once SSR is disabled then it cannot be set. */
11568void hdd_set_ssr_required( e_hdd_ssr_required value)
Jeff Johnson295189b2012-06-20 16:38:30 -070011569{
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -070011570 if (HDD_SSR_DISABLED == isSsrRequired)
11571 return;
11572
Jeff Johnson295189b2012-06-20 16:38:30 -070011573 isSsrRequired = value;
11574}
11575
Hema Aparna Medicharla6b4d4f32015-06-23 04:09:12 +053011576void hdd_set_pre_close( hdd_context_t *pHddCtx)
11577{
11578 sme_PreClose(pHddCtx->hHal);
11579}
11580
Jeff Johnson295189b2012-06-20 16:38:30 -070011581VOS_STATUS hdd_get_front_adapter( hdd_context_t *pHddCtx,
11582 hdd_adapter_list_node_t** ppAdapterNode)
11583{
11584 VOS_STATUS status;
Mukul Sharmaae1266d2015-06-26 15:29:53 +053011585 spin_lock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -070011586 status = hdd_list_peek_front ( &pHddCtx->hddAdapters,
11587 (hdd_list_node_t**) ppAdapterNode );
Mukul Sharmaae1266d2015-06-26 15:29:53 +053011588 spin_unlock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -070011589 return status;
11590}
11591
11592VOS_STATUS hdd_get_next_adapter( hdd_context_t *pHddCtx,
11593 hdd_adapter_list_node_t* pAdapterNode,
11594 hdd_adapter_list_node_t** pNextAdapterNode)
11595{
11596 VOS_STATUS status;
Mukul Sharmaae1266d2015-06-26 15:29:53 +053011597 spin_lock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -070011598 status = hdd_list_peek_next ( &pHddCtx->hddAdapters,
11599 (hdd_list_node_t*) pAdapterNode,
11600 (hdd_list_node_t**)pNextAdapterNode );
11601
Mukul Sharmaae1266d2015-06-26 15:29:53 +053011602 spin_unlock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -070011603 return status;
11604}
11605
11606VOS_STATUS hdd_remove_adapter( hdd_context_t *pHddCtx,
11607 hdd_adapter_list_node_t* pAdapterNode)
11608{
11609 VOS_STATUS status;
Mukul Sharmaae1266d2015-06-26 15:29:53 +053011610 spin_lock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -070011611 status = hdd_list_remove_node ( &pHddCtx->hddAdapters,
11612 &pAdapterNode->node );
Mukul Sharmaae1266d2015-06-26 15:29:53 +053011613 spin_unlock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -070011614 return status;
11615}
11616
11617VOS_STATUS hdd_remove_front_adapter( hdd_context_t *pHddCtx,
11618 hdd_adapter_list_node_t** ppAdapterNode)
11619{
11620 VOS_STATUS status;
Mukul Sharmaae1266d2015-06-26 15:29:53 +053011621 spin_lock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -070011622 status = hdd_list_remove_front( &pHddCtx->hddAdapters,
11623 (hdd_list_node_t**) ppAdapterNode );
Mukul Sharmaae1266d2015-06-26 15:29:53 +053011624 spin_unlock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -070011625 return status;
11626}
11627
11628VOS_STATUS hdd_add_adapter_back( hdd_context_t *pHddCtx,
11629 hdd_adapter_list_node_t* pAdapterNode)
11630{
11631 VOS_STATUS status;
Mukul Sharmaae1266d2015-06-26 15:29:53 +053011632 spin_lock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -070011633 status = hdd_list_insert_back ( &pHddCtx->hddAdapters,
11634 (hdd_list_node_t*) pAdapterNode );
Mukul Sharmaae1266d2015-06-26 15:29:53 +053011635 spin_unlock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -070011636 return status;
11637}
11638
11639VOS_STATUS hdd_add_adapter_front( hdd_context_t *pHddCtx,
11640 hdd_adapter_list_node_t* pAdapterNode)
11641{
11642 VOS_STATUS status;
Mukul Sharmaae1266d2015-06-26 15:29:53 +053011643 spin_lock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -070011644 status = hdd_list_insert_front ( &pHddCtx->hddAdapters,
11645 (hdd_list_node_t*) pAdapterNode );
Mukul Sharmaae1266d2015-06-26 15:29:53 +053011646 spin_unlock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -070011647 return status;
11648}
11649
11650hdd_adapter_t * hdd_get_adapter_by_macaddr( hdd_context_t *pHddCtx,
11651 tSirMacAddr macAddr )
11652{
11653 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
11654 hdd_adapter_t *pAdapter;
11655 VOS_STATUS status;
11656
11657 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
11658
11659 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
11660 {
11661 pAdapter = pAdapterNode->pAdapter;
11662
11663 if( pAdapter && vos_mem_compare( pAdapter->macAddressCurrent.bytes,
11664 macAddr, sizeof(tSirMacAddr) ) )
11665 {
11666 return pAdapter;
11667 }
11668 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
11669 pAdapterNode = pNext;
11670 }
11671
11672 return NULL;
11673
11674}
11675
11676hdd_adapter_t * hdd_get_adapter_by_name( hdd_context_t *pHddCtx, tANI_U8 *name )
11677{
11678 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
11679 hdd_adapter_t *pAdapter;
11680 VOS_STATUS status;
11681
11682 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
11683
11684 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
11685 {
11686 pAdapter = pAdapterNode->pAdapter;
11687
11688 if( pAdapter && !strncmp( pAdapter->dev->name, (const char *)name,
11689 IFNAMSIZ ) )
11690 {
11691 return pAdapter;
11692 }
11693 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
11694 pAdapterNode = pNext;
11695 }
11696
11697 return NULL;
11698
11699}
11700
Ganesh Kondabattinicbfdc392015-09-11 19:12:59 +053011701hdd_adapter_t *hdd_get_adapter_by_sme_session_id( hdd_context_t *pHddCtx,
11702 tANI_U32 sme_session_id )
11703{
11704 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
11705 hdd_adapter_t *pAdapter;
11706 VOS_STATUS vos_status;
11707
11708
11709 vos_status = hdd_get_front_adapter( pHddCtx, &pAdapterNode);
11710
11711 while ((NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == vos_status))
11712 {
11713 pAdapter = pAdapterNode->pAdapter;
11714
11715 if (pAdapter->sessionId == sme_session_id)
11716 return pAdapter;
11717
11718 vos_status = hdd_get_next_adapter(pHddCtx, pAdapterNode, &pNext);
11719 pAdapterNode = pNext;
11720 }
11721
11722 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11723 "%s: sme_session_id %d does not exist with host",
11724 __func__, sme_session_id);
11725
11726 return NULL;
11727}
11728
Jeff Johnson295189b2012-06-20 16:38:30 -070011729hdd_adapter_t * hdd_get_adapter( hdd_context_t *pHddCtx, device_mode_t mode )
11730{
11731 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
11732 hdd_adapter_t *pAdapter;
11733 VOS_STATUS status;
11734
11735 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
11736
11737 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
11738 {
11739 pAdapter = pAdapterNode->pAdapter;
11740
11741 if( pAdapter && (mode == pAdapter->device_mode) )
11742 {
11743 return pAdapter;
11744 }
11745 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
11746 pAdapterNode = pNext;
11747 }
11748
11749 return NULL;
11750
11751}
11752
11753//Remove this function later
11754hdd_adapter_t * hdd_get_mon_adapter( hdd_context_t *pHddCtx )
11755{
11756 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
11757 hdd_adapter_t *pAdapter;
11758 VOS_STATUS status;
11759
11760 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
11761
11762 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
11763 {
11764 pAdapter = pAdapterNode->pAdapter;
11765
11766 if( pAdapter && WLAN_HDD_MONITOR == pAdapter->device_mode )
11767 {
11768 return pAdapter;
11769 }
11770
11771 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
11772 pAdapterNode = pNext;
11773 }
11774
11775 return NULL;
11776
11777}
11778
Jeff Johnson295189b2012-06-20 16:38:30 -070011779/**---------------------------------------------------------------------------
11780
Mahesh A Saptasgar64534612014-09-23 13:13:33 +053011781 \brief hdd_get_operating_channel() -
Jeff Johnson295189b2012-06-20 16:38:30 -070011782
11783 This API returns the operating channel of the requested device mode
11784
11785 \param - pHddCtx - Pointer to the HDD context.
11786 - mode - Device mode for which operating channel is required
11787 suported modes - WLAN_HDD_INFRA_STATION, WLAN_HDD_P2P_CLIENT
11788 WLAN_HDD_SOFTAP, WLAN_HDD_P2P_GO.
11789 \return - channel number. "0" id the requested device is not found OR it is not connected.
11790 --------------------------------------------------------------------------*/
11791v_U8_t hdd_get_operating_channel( hdd_context_t *pHddCtx, device_mode_t mode )
11792{
11793 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
11794 VOS_STATUS status;
11795 hdd_adapter_t *pAdapter;
11796 v_U8_t operatingChannel = 0;
11797
11798 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
11799
11800 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
11801 {
11802 pAdapter = pAdapterNode->pAdapter;
11803
11804 if( mode == pAdapter->device_mode )
11805 {
11806 switch(pAdapter->device_mode)
11807 {
11808 case WLAN_HDD_INFRA_STATION:
11809 case WLAN_HDD_P2P_CLIENT:
11810 if( hdd_connIsConnected( WLAN_HDD_GET_STATION_CTX_PTR( pAdapter )) )
11811 operatingChannel = (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.operationChannel;
11812 break;
11813 case WLAN_HDD_SOFTAP:
11814 case WLAN_HDD_P2P_GO:
11815 /*softap connection info */
11816 if(test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
11817 operatingChannel = (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->operatingChannel;
11818 break;
11819 default:
11820 break;
11821 }
11822
11823 break; //Found the device of interest. break the loop
11824 }
11825
11826 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
11827 pAdapterNode = pNext;
11828 }
11829 return operatingChannel;
11830}
11831
11832#ifdef WLAN_FEATURE_PACKET_FILTERING
11833/**---------------------------------------------------------------------------
11834
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053011835 \brief __hdd_set_multicast_list() -
Jeff Johnson295189b2012-06-20 16:38:30 -070011836
11837 This used to set the multicast address list.
11838
11839 \param - dev - Pointer to the WLAN device.
11840 - skb - Pointer to OS packet (sk_buff).
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053011841 \return - success/fail
Jeff Johnson295189b2012-06-20 16:38:30 -070011842
11843 --------------------------------------------------------------------------*/
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053011844static void __hdd_set_multicast_list(struct net_device *dev)
Jeff Johnson295189b2012-06-20 16:38:30 -070011845{
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053011846 hdd_adapter_t *pAdapter;
11847 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070011848 int mc_count;
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053011849 int i = 0, ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070011850 struct netdev_hw_addr *ha;
Gopichand Nakkala0f276812013-02-24 14:45:51 +053011851
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053011852 ENTER();
11853
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053011854 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkala0f276812013-02-24 14:45:51 +053011855 if (NULL == pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -070011856 {
11857 hddLog(VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala0f276812013-02-24 14:45:51 +053011858 "%s: Adapter context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070011859 return;
11860 }
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053011861 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
11862 ret = wlan_hdd_validate_context(pHddCtx);
11863 if (0 != ret)
11864 {
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053011865 return;
11866 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011867 if (dev->flags & IFF_ALLMULTI)
11868 {
11869 hddLog(VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070011870 "%s: allow all multicast frames", __func__);
Gopichand Nakkala0f276812013-02-24 14:45:51 +053011871 pAdapter->mc_addr_list.mc_cnt = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070011872 }
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053011873 else
Jeff Johnson295189b2012-06-20 16:38:30 -070011874 {
11875 mc_count = netdev_mc_count(dev);
11876 hddLog(VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070011877 "%s: mc_count = %u", __func__, mc_count);
Jeff Johnson295189b2012-06-20 16:38:30 -070011878 if (mc_count > WLAN_HDD_MAX_MC_ADDR_LIST)
11879 {
11880 hddLog(VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070011881 "%s: No free filter available; allow all multicast frames", __func__);
Gopichand Nakkala0f276812013-02-24 14:45:51 +053011882 pAdapter->mc_addr_list.mc_cnt = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070011883 return;
11884 }
11885
Gopichand Nakkala0f276812013-02-24 14:45:51 +053011886 pAdapter->mc_addr_list.mc_cnt = mc_count;
Jeff Johnson295189b2012-06-20 16:38:30 -070011887
11888 netdev_for_each_mc_addr(ha, dev) {
11889 if (i == mc_count)
11890 break;
Gopichand Nakkala0f276812013-02-24 14:45:51 +053011891 memset(&(pAdapter->mc_addr_list.addr[i][0]), 0, ETH_ALEN);
11892 memcpy(&(pAdapter->mc_addr_list.addr[i][0]), ha->addr, ETH_ALEN);
Arif Hussain6d2a3322013-11-17 19:50:10 -080011893 hddLog(VOS_TRACE_LEVEL_INFO, "%s: mlist[%d] = "MAC_ADDRESS_STR,
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053011894 __func__, i,
Gopichand Nakkala0f276812013-02-24 14:45:51 +053011895 MAC_ADDR_ARRAY(pAdapter->mc_addr_list.addr[i]));
Jeff Johnson295189b2012-06-20 16:38:30 -070011896 i++;
11897 }
11898 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053011899
Ganesh Kondabattinifb37e652015-10-09 15:46:47 +053011900 if (pHddCtx->hdd_wlan_suspended)
11901 {
11902 /*
11903 * Configure the Mcast address list to FW
11904 * If wlan is already in suspend mode
11905 */
11906 wlan_hdd_set_mc_addr_list(pAdapter, TRUE);
11907 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053011908 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070011909 return;
11910}
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053011911
11912static void hdd_set_multicast_list(struct net_device *dev)
11913{
11914 vos_ssr_protect(__func__);
11915 __hdd_set_multicast_list(dev);
11916 vos_ssr_unprotect(__func__);
11917}
Jeff Johnson295189b2012-06-20 16:38:30 -070011918#endif
11919
11920/**---------------------------------------------------------------------------
11921
11922 \brief hdd_select_queue() -
11923
11924 This function is registered with the Linux OS for network
11925 core to decide which queue to use first.
11926
11927 \param - dev - Pointer to the WLAN device.
11928 - skb - Pointer to OS packet (sk_buff).
11929 \return - ac, Queue Index/access category corresponding to UP in IP header
11930
11931 --------------------------------------------------------------------------*/
11932v_U16_t hdd_select_queue(struct net_device *dev,
Anand N Sunkade9adb1b2015-07-29 09:56:45 +053011933 struct sk_buff *skb
11934#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,13,0))
11935 , void *accel_priv
11936#endif
11937#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
11938 , select_queue_fallback_t fallback
11939#endif
11940)
Jeff Johnson295189b2012-06-20 16:38:30 -070011941{
11942 return hdd_wmm_select_queue(dev, skb);
11943}
11944
11945
11946/**---------------------------------------------------------------------------
11947
11948 \brief hdd_wlan_initial_scan() -
11949
11950 This function triggers the initial scan
11951
11952 \param - pAdapter - Pointer to the HDD adapter.
11953
11954 --------------------------------------------------------------------------*/
11955void hdd_wlan_initial_scan(hdd_adapter_t *pAdapter)
11956{
11957 tCsrScanRequest scanReq;
11958 tCsrChannelInfo channelInfo;
11959 eHalStatus halStatus;
Jeff Johnson02797792013-10-26 19:17:13 -070011960 tANI_U32 scanId;
Jeff Johnson295189b2012-06-20 16:38:30 -070011961 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
11962
11963 vos_mem_zero(&scanReq, sizeof(tCsrScanRequest));
11964 vos_mem_set(&scanReq.bssid, sizeof(tCsrBssid), 0xff);
11965 scanReq.BSSType = eCSR_BSS_TYPE_ANY;
11966
11967 if(sme_Is11dSupported(pHddCtx->hHal))
11968 {
11969 halStatus = sme_ScanGetBaseChannels( pHddCtx->hHal, &channelInfo );
11970 if ( HAL_STATUS_SUCCESS( halStatus ) )
11971 {
11972 scanReq.ChannelInfo.ChannelList = vos_mem_malloc(channelInfo.numOfChannels);
11973 if( !scanReq.ChannelInfo.ChannelList )
11974 {
11975 hddLog(VOS_TRACE_LEVEL_ERROR, "%s kmalloc failed", __func__);
11976 vos_mem_free(channelInfo.ChannelList);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -080011977 channelInfo.ChannelList = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070011978 return;
11979 }
11980 vos_mem_copy(scanReq.ChannelInfo.ChannelList, channelInfo.ChannelList,
11981 channelInfo.numOfChannels);
11982 scanReq.ChannelInfo.numOfChannels = channelInfo.numOfChannels;
11983 vos_mem_free(channelInfo.ChannelList);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -080011984 channelInfo.ChannelList = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070011985 }
11986
11987 scanReq.scanType = eSIR_PASSIVE_SCAN;
11988 scanReq.requestType = eCSR_SCAN_REQUEST_11D_SCAN;
11989 scanReq.maxChnTime = pHddCtx->cfg_ini->nPassiveMaxChnTime;
11990 scanReq.minChnTime = pHddCtx->cfg_ini->nPassiveMinChnTime;
11991 }
11992 else
11993 {
11994 scanReq.scanType = eSIR_ACTIVE_SCAN;
11995 scanReq.requestType = eCSR_SCAN_REQUEST_FULL_SCAN;
11996 scanReq.maxChnTime = pHddCtx->cfg_ini->nActiveMaxChnTime;
11997 scanReq.minChnTime = pHddCtx->cfg_ini->nActiveMinChnTime;
11998 }
11999
12000 halStatus = sme_ScanRequest(pHddCtx->hHal, pAdapter->sessionId, &scanReq, &scanId, NULL, NULL);
12001 if ( !HAL_STATUS_SUCCESS( halStatus ) )
12002 {
12003 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: sme_ScanRequest failed status code %d",
12004 __func__, halStatus );
12005 }
12006
12007 if(sme_Is11dSupported(pHddCtx->hHal))
12008 vos_mem_free(scanReq.ChannelInfo.ChannelList);
12009}
12010
Jeff Johnson295189b2012-06-20 16:38:30 -070012011/**---------------------------------------------------------------------------
12012
12013 \brief hdd_full_power_callback() - HDD full power callback function
12014
12015 This is the function invoked by SME to inform the result of a full power
12016 request issued by HDD
12017
12018 \param - callbackcontext - Pointer to cookie
12019 \param - status - result of request
12020
12021 \return - None
12022
12023 --------------------------------------------------------------------------*/
12024static void hdd_full_power_callback(void *callbackContext, eHalStatus status)
12025{
Jeff Johnson72a40512013-12-19 10:14:15 -080012026 struct statsContext *pContext = callbackContext;
Jeff Johnson295189b2012-06-20 16:38:30 -070012027
12028 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnsonc135a9a2017-09-19 08:37:24 -070012029 "%s: context = %pK, status = %d", __func__, pContext, status);
Jeff Johnson295189b2012-06-20 16:38:30 -070012030
12031 if (NULL == callbackContext)
12032 {
12033 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnsonc135a9a2017-09-19 08:37:24 -070012034 "%s: Bad param, context [%pK]",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070012035 __func__, callbackContext);
Jeff Johnson295189b2012-06-20 16:38:30 -070012036 return;
12037 }
12038
Jeff Johnson72a40512013-12-19 10:14:15 -080012039 /* there is a race condition that exists between this callback
12040 function and the caller since the caller could time out either
12041 before or while this code is executing. we use a spinlock to
12042 serialize these actions */
12043 spin_lock(&hdd_context_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -070012044
12045 if (POWER_CONTEXT_MAGIC != pContext->magic)
12046 {
12047 /* the caller presumably timed out so there is nothing we can do */
Jeff Johnson72a40512013-12-19 10:14:15 -080012048 spin_unlock(&hdd_context_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -070012049 hddLog(VOS_TRACE_LEVEL_WARN,
12050 "%s: Invalid context, magic [%08x]",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070012051 __func__, pContext->magic);
Jeff Johnson295189b2012-06-20 16:38:30 -070012052 return;
12053 }
12054
Jeff Johnson72a40512013-12-19 10:14:15 -080012055 /* context is valid so caller is still waiting */
12056
12057 /* paranoia: invalidate the magic */
12058 pContext->magic = 0;
12059
12060 /* notify the caller */
Jeff Johnson295189b2012-06-20 16:38:30 -070012061 complete(&pContext->completion);
Jeff Johnson72a40512013-12-19 10:14:15 -080012062
12063 /* serialization is complete */
12064 spin_unlock(&hdd_context_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -070012065}
12066
Katya Nigamf0511f62015-05-05 16:40:57 +053012067void wlan_hdd_mon_set_typesubtype( hdd_mon_ctx_t *pMonCtx,int type)
12068{
12069 pMonCtx->typeSubtypeBitmap = 0;
12070 if( type%10 ) /* Management Packets */
12071 pMonCtx->typeSubtypeBitmap |= 0xFFFF;
12072 type/=10;
12073 if( type%10 ) /* Control Packets */
12074 pMonCtx->typeSubtypeBitmap |= 0xFFFF0000;
12075 type/=10;
12076 if( type%10 ) /* Data Packets */
12077 pMonCtx->typeSubtypeBitmap |= 0xFFFF00000000;
12078}
12079
Hanumanth Reddy Pothulab8be9ab2018-04-12 20:03:05 +053012080VOS_STATUS wlan_hdd_mon_postMsg(void *context, hdd_mon_ctx_t *pMonCtx,
12081 void* callback)
Katya Nigamf0511f62015-05-05 16:40:57 +053012082{
12083 vos_msg_t monMsg;
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +053012084 tSirMonModeReq *pMonModeReq;
Katya Nigamf0511f62015-05-05 16:40:57 +053012085
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +053012086 if (MON_MODE_START == pMonCtx->state)
12087 monMsg.type = WDA_MON_START_REQ;
12088 else if (MON_MODE_STOP == pMonCtx->state)
12089 monMsg.type = WDA_MON_STOP_REQ;
12090 else {
12091 hddLog(VOS_TRACE_LEVEL_ERROR,
12092 FL("invalid monitor state %d"), pMonCtx->state);
Katya Nigamf0511f62015-05-05 16:40:57 +053012093 return VOS_STATUS_E_FAILURE;
12094 }
12095
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +053012096 pMonModeReq = vos_mem_malloc(sizeof(tSirMonModeReq));
12097 if (pMonModeReq == NULL) {
12098 hddLog(VOS_TRACE_LEVEL_ERROR,
12099 FL("fail to allocate memory for monitor mode req"));
12100 return VOS_STATUS_E_FAILURE;
12101 }
Katya Nigamf0511f62015-05-05 16:40:57 +053012102
Hanumanth Reddy Pothulab8be9ab2018-04-12 20:03:05 +053012103 pMonModeReq->context = context;
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +053012104 pMonModeReq->data = pMonCtx;
12105 pMonModeReq->callback = callback;
Katya Nigamf0511f62015-05-05 16:40:57 +053012106
Katya Nigamf0511f62015-05-05 16:40:57 +053012107 monMsg.reserved = 0;
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +053012108 monMsg.bodyptr = pMonModeReq;
Katya Nigamf0511f62015-05-05 16:40:57 +053012109 monMsg.bodyval = 0;
12110
12111 if (VOS_STATUS_SUCCESS != vos_mq_post_message(
12112 VOS_MODULE_ID_WDA,(vos_msg_t *)&monMsg)) {
12113 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: : Failed to post Msg to HAL",__func__);
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +053012114 vos_mem_free(pMonModeReq);
Katya Nigamf0511f62015-05-05 16:40:57 +053012115 }
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +053012116 return VOS_STATUS_SUCCESS;
Katya Nigamf0511f62015-05-05 16:40:57 +053012117}
12118
Katya Nigame7b69a82015-04-28 15:24:06 +053012119void wlan_hdd_mon_close(hdd_context_t *pHddCtx)
12120{
12121 VOS_STATUS vosStatus;
12122 v_CONTEXT_t pVosContext = pHddCtx->pvosContext;
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +053012123 hdd_mon_ctx_t *pMonCtx = NULL;
Hanumanth Reddy Pothulab8be9ab2018-04-12 20:03:05 +053012124 int ret;
12125 void *cookie;
12126 struct hdd_request *request;
12127 static const struct hdd_request_params params = {
12128 .priv_size = 0,
12129 .timeout_ms = MON_MODE_MSG_TIMEOUT,
12130 };
Hanumantha Reddy Pothulac99bc062015-09-08 14:59:26 +053012131
Katya Nigame7b69a82015-04-28 15:24:06 +053012132 hdd_adapter_t *pAdapter = hdd_get_adapter(pHddCtx,WLAN_HDD_MONITOR);
12133 if(pAdapter == NULL || pVosContext == NULL)
12134 {
12135 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, "%s:pAdapter is NULL",__func__);
12136 return ;
12137 }
Katya Nigamf0511f62015-05-05 16:40:57 +053012138
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +053012139 pMonCtx = WLAN_HDD_GET_MONITOR_CTX_PTR(pAdapter);
12140 if (pMonCtx!= NULL && pMonCtx->state == MON_MODE_START) {
12141 pMonCtx->state = MON_MODE_STOP;
Hanumanth Reddy Pothulab8be9ab2018-04-12 20:03:05 +053012142 request = hdd_request_alloc(&params);
12143 if (!request) {
12144 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Request allocation failure"));
12145 return;
12146 }
12147 cookie = hdd_request_cookie(request);
12148
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +053012149 if (VOS_STATUS_SUCCESS !=
Hanumanth Reddy Pothulab8be9ab2018-04-12 20:03:05 +053012150 wlan_hdd_mon_postMsg(cookie, pMonCtx,
12151 hdd_mon_post_msg_cb)) {
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +053012152 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12153 FL("failed to post MON MODE REQ"));
12154 pMonCtx->state = MON_MODE_START;
Hanumanth Reddy Pothulab8be9ab2018-04-12 20:03:05 +053012155 goto req_put;
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +053012156 }
Hanumanth Reddy Pothulab8be9ab2018-04-12 20:03:05 +053012157
12158 ret = hdd_request_wait_for_response(request);
12159 if (ret)
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +053012160 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Hanumanth Reddy Pothulab8be9ab2018-04-12 20:03:05 +053012161 FL("timeout on monitor mode completion %d"), ret);
12162
12163req_put:
12164 hdd_request_put(request);
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +053012165 }
12166
Katya Nigame7b69a82015-04-28 15:24:06 +053012167 hdd_UnregisterWext(pAdapter->dev);
12168
12169 vos_mon_stop( pVosContext );
12170
12171 vosStatus = vos_sched_close( pVosContext );
12172 if (!VOS_IS_STATUS_SUCCESS(vosStatus)) {
12173 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
12174 "%s: Failed to close VOSS Scheduler",__func__);
12175 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
12176 }
12177
12178 vosStatus = vos_nv_close();
12179 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
12180 {
12181 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
12182 "%s: Failed to close NV", __func__);
12183 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
12184 }
12185
12186 vos_close(pVosContext);
12187
12188 #ifdef WLAN_KD_READY_NOTIFIER
12189 nl_srv_exit(pHddCtx->ptt_pid);
12190 #else
12191 nl_srv_exit();
12192 #endif
12193
Katya Nigame7b69a82015-04-28 15:24:06 +053012194 hdd_close_all_adapters( pHddCtx );
Katya Nigame7b69a82015-04-28 15:24:06 +053012195}
Agrawal Ashish33ec71e2015-11-26 20:20:58 +053012196/**
12197 * hdd_wlan_free_wiphy_channels - free Channel pointer for wiphy
12198 * @ wiphy: the wiphy to validate against
12199 *
12200 * Return: void
12201 */
12202void hdd_wlan_free_wiphy_channels(struct wiphy *wiphy)
12203{
12204 int i =0;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053012205 for (i = 0; i < HDD_NUM_NL80211_BANDS; i++)
Agrawal Ashish33ec71e2015-11-26 20:20:58 +053012206 {
12207 if (NULL != wiphy->bands[i] &&
12208 (NULL != wiphy->bands[i]->channels))
12209 {
12210 vos_mem_free(wiphy->bands[i]->channels);
12211 wiphy->bands[i]->channels = NULL;
12212 }
12213 }
12214}
Jeff Johnson295189b2012-06-20 16:38:30 -070012215/**---------------------------------------------------------------------------
12216
12217 \brief hdd_wlan_exit() - HDD WLAN exit function
12218
12219 This is the driver exit point (invoked during rmmod)
12220
12221 \param - pHddCtx - Pointer to the HDD Context
12222
12223 \return - None
12224
12225 --------------------------------------------------------------------------*/
12226void hdd_wlan_exit(hdd_context_t *pHddCtx)
12227{
12228 eHalStatus halStatus;
12229 v_CONTEXT_t pVosContext = pHddCtx->pvosContext;
12230 VOS_STATUS vosStatus;
Gopichand Nakkala66923aa2013-03-06 23:17:24 +053012231 struct wiphy *wiphy = pHddCtx->wiphy;
Mingcheng Zhu87f22fc2014-01-30 19:23:32 -080012232 hdd_adapter_t* pAdapter = NULL;
Jeff Johnson72a40512013-12-19 10:14:15 -080012233 struct statsContext powerContext;
Jeff Johnson295189b2012-06-20 16:38:30 -070012234 long lrc;
c_hpothu5ab05e92014-06-13 17:34:05 +053012235 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070012236
12237 ENTER();
12238
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +053012239
Katya Nigame7b69a82015-04-28 15:24:06 +053012240 if (VOS_MONITOR_MODE == hdd_get_conparam())
12241 {
12242 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: MONITOR MODE",__func__);
12243 wlan_hdd_mon_close(pHddCtx);
Hanumantha Reddy Pothulac99bc062015-09-08 14:59:26 +053012244 goto free_hdd_ctx;
Katya Nigame7b69a82015-04-28 15:24:06 +053012245 }
12246 else if (VOS_FTM_MODE != hdd_get_conparam())
Jeff Johnson88ba7742013-02-27 14:36:02 -080012247 {
12248 // Unloading, restart logic is no more required.
12249 wlan_hdd_restart_deinit(pHddCtx);
Jeff Johnsone7245742012-09-05 17:12:55 -070012250
Agarwal Ashishb20e0ff2014-12-17 22:50:19 +053012251#ifdef FEATURE_WLAN_TDLS
12252 /* At the time of driver unloading; if tdls connection is present;
12253 * hdd_rx_packet_cbk calls wlan_hdd_tdls_find_peer.
12254 * wlan_hdd_tdls_find_peer always checks for valid context;
12255 * as load/unload in progress there can be a race condition.
12256 * hdd_rx_packet_cbk calls wlan_hdd_tdls_find_peer only
12257 * when tdls state is enabled.
12258 * As soon as driver set load/unload flag; tdls flag also needs
12259 * to be disabled so that hdd_rx_packet_cbk won't call
12260 * wlan_hdd_tdls_find_peer.
12261 */
Masti, Narayanraddi20494af2015-12-17 20:56:42 +053012262 wlan_hdd_tdls_set_mode(pHddCtx, eTDLS_SUPPORT_DISABLED, FALSE,
12263 HDD_SET_TDLS_MODE_SOURCE_USER);
Agarwal Ashishb20e0ff2014-12-17 22:50:19 +053012264#endif
12265
c_hpothu5ab05e92014-06-13 17:34:05 +053012266 vosStatus = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
12267 while (NULL != pAdapterNode && VOS_STATUS_E_EMPTY != vosStatus)
Jeff Johnson295189b2012-06-20 16:38:30 -070012268 {
c_hpothu5ab05e92014-06-13 17:34:05 +053012269 pAdapter = pAdapterNode->pAdapter;
12270 if (NULL != pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -070012271 {
Mahesh A Saptasagar305e2632015-03-04 12:57:33 +053012272 /* Disable TX on the interface, after this hard_start_xmit() will
12273 * not be called on that interface
12274 */
12275 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
12276 netif_tx_disable(pAdapter->dev);
12277
12278 /* Mark the interface status as "down" for outside world */
12279 netif_carrier_off(pAdapter->dev);
12280
Agarwal Ashish9ffa5b92014-11-18 21:07:02 +053012281 /* DeInit the adapter. This ensures that all data packets
12282 * are freed.
12283 */
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +053012284#ifdef FEATURE_WLAN_TDLS
12285 mutex_lock(&pHddCtx->tdls_lock);
12286#endif
c_hpothu002231a2015-02-05 14:58:51 +053012287 hdd_deinit_adapter(pHddCtx, pAdapter, FALSE);
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +053012288#ifdef FEATURE_WLAN_TDLS
12289 mutex_unlock(&pHddCtx->tdls_lock);
12290#endif
Masti, Narayanraddi26378462016-01-05 18:20:28 +053012291 vos_flush_delayed_work(&pHddCtx->scan_ctxt.scan_work);
12292
12293 wlan_hdd_init_deinit_defer_scan_context(&pHddCtx->scan_ctxt);
Agarwal Ashish9ffa5b92014-11-18 21:07:02 +053012294
c_hpothu5ab05e92014-06-13 17:34:05 +053012295 if (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +053012296 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode ||
12297 WLAN_HDD_MONITOR == pAdapter->device_mode)
c_hpothu5ab05e92014-06-13 17:34:05 +053012298 {
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +053012299 if (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
12300 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode)
12301 wlan_hdd_cfg80211_deregister_frames(pAdapter);
12302
c_hpothu5ab05e92014-06-13 17:34:05 +053012303 hdd_UnregisterWext(pAdapter->dev);
12304 }
Kaushik, Sushant4975a572014-10-21 16:07:48 +053012305
Jeff Johnson295189b2012-06-20 16:38:30 -070012306 }
c_hpothu5ab05e92014-06-13 17:34:05 +053012307 vosStatus = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
12308 pAdapterNode = pNext;
Jeff Johnson295189b2012-06-20 16:38:30 -070012309 }
mukul sharmabab477d2015-06-11 17:14:55 +053012310
Kaushik, Sushant4975a572014-10-21 16:07:48 +053012311 // Cancel any outstanding scan requests. We are about to close all
12312 // of our adapters, but an adapter structure is what SME passes back
12313 // to our callback function. Hence if there are any outstanding scan
12314 // requests then there is a race condition between when the adapter
12315 // is closed and when the callback is invoked.We try to resolve that
12316 // race condition here by canceling any outstanding scans before we
12317 // close the adapters.
12318 // Note that the scans may be cancelled in an asynchronous manner,
12319 // so ideally there needs to be some kind of synchronization. Rather
12320 // than introduce a new synchronization here, we will utilize the
12321 // fact that we are about to Request Full Power, and since that is
12322 // synchronized, the expectation is that by the time Request Full
12323 // Power has completed all scans will be cancelled.
12324 if (pHddCtx->scan_info.mScanPending)
12325 {
Hema Aparna Medicharlaf05f6cd2015-01-21 14:44:19 +053012326 if(NULL != pAdapter)
12327 {
12328 hddLog(VOS_TRACE_LEVEL_INFO,
12329 FL("abort scan mode: %d sessionId: %d"),
12330 pAdapter->device_mode,
12331 pAdapter->sessionId);
12332 }
12333 hdd_abort_mac_scan(pHddCtx,
12334 pHddCtx->scan_info.sessionId,
12335 eCSR_SCAN_ABORT_DEFAULT);
Kaushik, Sushant4975a572014-10-21 16:07:48 +053012336 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012337 }
c_hpothu5ab05e92014-06-13 17:34:05 +053012338 else
Jeff Johnson88ba7742013-02-27 14:36:02 -080012339 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012340 hddLog(VOS_TRACE_LEVEL_INFO,"%s: FTM MODE",__func__);
Hanumantha Reddy Pothula45af96b2015-02-12 16:07:58 +053012341 if (pHddCtx->ftm.ftm_state == WLAN_FTM_STARTING)
12342 {
12343 INIT_COMPLETION(pHddCtx->ftm.startCmpVar);
12344 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
12345 "%s: in middle of FTM START", __func__);
12346 lrc = wait_for_completion_timeout(&pHddCtx->ftm.startCmpVar,
12347 msecs_to_jiffies(20000));
12348 if(!lrc)
12349 {
12350 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
12351 "%s: timedout on ftmStartCmpVar fatal error", __func__);
12352 }
12353 }
Jeff Johnson88ba7742013-02-27 14:36:02 -080012354 wlan_hdd_ftm_close(pHddCtx);
12355 goto free_hdd_ctx;
12356 }
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012357
Jeff Johnson295189b2012-06-20 16:38:30 -070012358 /* DeRegister with platform driver as client for Suspend/Resume */
12359 vosStatus = hddDeregisterPmOps(pHddCtx);
12360 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
12361 {
12362 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddDeregisterPmOps failed",__func__);
12363 VOS_ASSERT(0);
12364 }
12365
12366 vosStatus = hddDevTmUnregisterNotifyCallback(pHddCtx);
12367 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
12368 {
12369 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddDevTmUnregisterNotifyCallback failed",__func__);
12370 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012371
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -070012372 //Stop the traffic monitor timer
Mahesh A Saptasagard461e432016-07-20 15:01:40 +053012373 if ((pHddCtx->cfg_ini->dynSplitscan) && (VOS_TIMER_STATE_RUNNING ==
12374 vos_timer_getCurrentState(&pHddCtx->tx_rx_trafficTmr)))
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -070012375 {
12376 vos_timer_stop(&pHddCtx->tx_rx_trafficTmr);
12377 }
12378
12379 // Destroy the traffic monitor timer
Mahesh A Saptasagard461e432016-07-20 15:01:40 +053012380 if ((pHddCtx->cfg_ini->dynSplitscan) &&
12381 (!VOS_IS_STATUS_SUCCESS(vos_timer_destroy(
12382 &pHddCtx->tx_rx_trafficTmr))))
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -070012383 {
12384 hddLog(VOS_TRACE_LEVEL_ERROR,
12385 "%s: Cannot deallocate Traffic monitor timer", __func__);
12386 }
12387
Bhargav Shahd0715912015-10-01 18:17:37 +053012388 if (VOS_TIMER_STATE_RUNNING ==
12389 vos_timer_getCurrentState(&pHddCtx->delack_timer)) {
12390 vos_timer_stop(&pHddCtx->delack_timer);
12391 }
12392
12393 if (!VOS_IS_STATUS_SUCCESS(vos_timer_destroy(
12394 &pHddCtx->delack_timer))) {
12395 hddLog(VOS_TRACE_LEVEL_ERROR,
12396 "%s: Cannot deallocate Bus bandwidth timer", __func__);
12397 }
12398
Masti, Narayanraddi44b0db02015-12-22 11:54:35 +053012399 if (VOS_TIMER_STATE_RUNNING ==
12400 vos_timer_getCurrentState(&pHddCtx->tdls_source_timer)) {
12401 vos_timer_stop(&pHddCtx->tdls_source_timer);
12402 }
12403
Abhishek Singh8a3e4dc2017-01-02 10:39:18 +053012404 vos_set_snoc_high_freq_voting(false);
12405
Masti, Narayanraddi44b0db02015-12-22 11:54:35 +053012406 vos_timer_destroy(&pHddCtx->tdls_source_timer);
12407
Jeff Johnson295189b2012-06-20 16:38:30 -070012408 //Disable IMPS/BMPS as we do not want the device to enter any power
12409 //save mode during shutdown
12410 sme_DisablePowerSave(pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
12411 sme_DisablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
12412 sme_DisablePowerSave(pHddCtx->hHal, ePMC_UAPSD_MODE_POWER_SAVE);
12413
12414 //Ensure that device is in full power as we will touch H/W during vos_Stop
12415 init_completion(&powerContext.completion);
12416 powerContext.magic = POWER_CONTEXT_MAGIC;
12417
12418 halStatus = sme_RequestFullPower(pHddCtx->hHal, hdd_full_power_callback,
12419 &powerContext, eSME_FULL_PWR_NEEDED_BY_HDD);
12420
12421 if (eHAL_STATUS_SUCCESS != halStatus)
12422 {
12423 if (eHAL_STATUS_PMC_PENDING == halStatus)
12424 {
12425 /* request was sent -- wait for the response */
12426 lrc = wait_for_completion_interruptible_timeout(
12427 &powerContext.completion,
12428 msecs_to_jiffies(WLAN_WAIT_TIME_POWER));
Jeff Johnson295189b2012-06-20 16:38:30 -070012429 if (lrc <= 0)
12430 {
12431 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: %s while requesting full power",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070012432 __func__, (0 == lrc) ? "timeout" : "interrupt");
Jeff Johnson295189b2012-06-20 16:38:30 -070012433 }
12434 }
12435 else
12436 {
12437 hddLog(VOS_TRACE_LEVEL_ERROR,
12438 "%s: Request for Full Power failed, status %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070012439 __func__, halStatus);
Jeff Johnson295189b2012-06-20 16:38:30 -070012440 /* continue -- need to clean up as much as possible */
12441 }
12442 }
Hanumantha Reddy Pothula81b42b22015-05-12 13:52:00 +053012443 if ((eHAL_STATUS_SUCCESS == halStatus) ||
12444 (eHAL_STATUS_PMC_PENDING == halStatus && lrc > 0))
12445 {
12446 /* This will issue a dump command which will clean up
12447 BTQM queues and unblock MC thread */
12448 vos_fwDumpReq(274, 0, 0, 0, 0, 1);
12449 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012450
Jeff Johnson72a40512013-12-19 10:14:15 -080012451 /* either we never sent a request, we sent a request and received a
12452 response or we sent a request and timed out. if we never sent a
12453 request or if we sent a request and got a response, we want to
12454 clear the magic out of paranoia. if we timed out there is a
12455 race condition such that the callback function could be
12456 executing at the same time we are. of primary concern is if the
12457 callback function had already verified the "magic" but had not
12458 yet set the completion variable when a timeout occurred. we
12459 serialize these activities by invalidating the magic while
12460 holding a shared spinlock which will cause us to block if the
12461 callback is currently executing */
12462 spin_lock(&hdd_context_lock);
12463 powerContext.magic = 0;
12464 spin_unlock(&hdd_context_lock);
12465
Hema Aparna Medicharlaa6cf65e2015-06-01 16:23:28 +053012466 /* If Device is shutdown, no point for SME to wait for responses
12467 from device. Pre Close SME */
12468 if(wcnss_device_is_shutdown())
12469 {
12470 sme_PreClose(pHddCtx->hHal);
12471 }
Yue Ma0d4891e2013-08-06 17:01:45 -070012472 hdd_debugfs_exit(pHddCtx);
12473
Ratheesh S P35ed8b12015-04-27 14:01:07 +053012474#ifdef WLAN_NS_OFFLOAD
Ratheesh S P36dbc932015-08-07 14:28:57 +053012475 hddLog(LOG1, FL("Unregister IPv6 notifier"));
Ratheesh S P35ed8b12015-04-27 14:01:07 +053012476 unregister_inet6addr_notifier(&pHddCtx->ipv6_notifier);
12477#endif
Ratheesh S P36dbc932015-08-07 14:28:57 +053012478 hddLog(LOG1, FL("Unregister IPv4 notifier"));
Ratheesh S P35ed8b12015-04-27 14:01:07 +053012479 unregister_inetaddr_notifier(&pHddCtx->ipv4_notifier);
12480
Jeff Johnson295189b2012-06-20 16:38:30 -070012481 // Unregister the Net Device Notifier
12482 unregister_netdevice_notifier(&hdd_netdev_notifier);
12483
Jeff Johnson295189b2012-06-20 16:38:30 -070012484 hdd_stop_all_adapters( pHddCtx );
12485
Jeff Johnson295189b2012-06-20 16:38:30 -070012486#ifdef WLAN_BTAMP_FEATURE
12487 vosStatus = WLANBAP_Stop(pVosContext);
12488 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
12489 {
12490 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
12491 "%s: Failed to stop BAP",__func__);
12492 }
12493#endif //WLAN_BTAMP_FEATURE
12494
12495 //Stop all the modules
12496 vosStatus = vos_stop( pVosContext );
12497 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
12498 {
12499 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
12500 "%s: Failed to stop VOSS",__func__);
12501 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
Hanumantha Reddy Pothulabd9601a2016-02-12 13:22:27 +053012502 if (isSsrPanicOnFailure())
12503 VOS_BUG(0);
Jeff Johnson295189b2012-06-20 16:38:30 -070012504 }
12505
Jeff Johnson295189b2012-06-20 16:38:30 -070012506 //This requires pMac access, Call this before vos_close().
Jeff Johnson295189b2012-06-20 16:38:30 -070012507 hdd_unregister_mcast_bcast_filter(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -070012508
12509 //Close the scheduler before calling vos_close to make sure no thread is
12510 // scheduled after the each module close is called i.e after all the data
12511 // structures are freed.
12512 vosStatus = vos_sched_close( pVosContext );
12513 if (!VOS_IS_STATUS_SUCCESS(vosStatus)) {
12514 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
12515 "%s: Failed to close VOSS Scheduler",__func__);
12516 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
12517 }
Jeff Johnsone7245742012-09-05 17:12:55 -070012518#ifdef WLAN_FEATURE_HOLD_RX_WAKELOCK
12519 /* Destroy the wake lock */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053012520 vos_wake_lock_destroy(&pHddCtx->rx_wake_lock);
Jeff Johnsone7245742012-09-05 17:12:55 -070012521#endif
Madan Mohan Koyyalamudi69fc3ad2012-11-28 16:04:56 -080012522 /* Destroy the wake lock */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053012523 vos_wake_lock_destroy(&pHddCtx->sap_wake_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -070012524
Mihir Shete7a24b5f2013-12-21 12:18:31 +053012525#ifdef CONFIG_ENABLE_LINUX_REG
12526 vosStatus = vos_nv_close();
12527 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
12528 {
12529 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
12530 "%s: Failed to close NV", __func__);
12531 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
12532 }
12533#endif
12534
Jeff Johnson295189b2012-06-20 16:38:30 -070012535 //Close VOSS
12536 //This frees pMac(HAL) context. There should not be any call that requires pMac access after this.
12537 vos_close(pVosContext);
12538
Jeff Johnson295189b2012-06-20 16:38:30 -070012539 //Close Watchdog
12540 if(pHddCtx->cfg_ini->fIsLogpEnabled)
12541 vos_watchdog_close(pVosContext);
12542
Gopichand Nakkalaa0358482013-06-12 17:05:47 +053012543 //Clean up HDD Nlink Service
12544 send_btc_nlink_msg(WLAN_MODULE_DOWN_IND, 0);
Gopichand Nakkalaa0358482013-06-12 17:05:47 +053012545
Manjeet Singh47ee8472016-04-11 11:57:18 +053012546 hdd_close_tx_queues(pHddCtx);
c_manjeecfd1efb2015-09-25 19:32:34 +053012547 wlan_free_fwr_mem_dump_buffer();
c_manjeecfd1efb2015-09-25 19:32:34 +053012548
Vinay Krishna Erannad938c422014-03-10 17:14:21 +053012549#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +053012550 if (pHddCtx->cfg_ini->wlanLoggingEnable)
Vinay Krishna Erannad938c422014-03-10 17:14:21 +053012551 {
12552 wlan_logging_sock_deactivate_svc();
12553 }
12554#endif
12555
Vinay Krishna Erannaef30b522014-08-26 17:48:16 +053012556#ifdef WLAN_KD_READY_NOTIFIER
12557 nl_srv_exit(pHddCtx->ptt_pid);
12558#else
12559 nl_srv_exit();
12560#endif /* WLAN_KD_READY_NOTIFIER */
12561
Abhishek Singh00b71972016-01-07 10:51:04 +053012562#ifdef WLAN_FEATURE_RMC
12563 hdd_close_cesium_nl_sock();
12564#endif /* WLAN_FEATURE_RMC */
Vinay Krishna Erannaef30b522014-08-26 17:48:16 +053012565
Jeff Johnson295189b2012-06-20 16:38:30 -070012566 hdd_close_all_adapters( pHddCtx );
12567
Padma, Santhosh Kumar9cd38332015-11-17 12:18:10 +053012568 vos_flush_delayed_work(&pHddCtx->spoof_mac_addr_work);
Abhishek Singh78c691f2017-11-30 13:48:44 +053012569 vos_flush_delayed_work(&pHddCtx->ecsa_chan_change_work);
Kapil Gupta137ef892016-12-13 19:38:00 +053012570 vos_flush_work(&pHddCtx->sap_start_work);
Padma, Santhosh Kumar9cd38332015-11-17 12:18:10 +053012571
Hanumantha Reddy Pothula97f9bc92015-08-10 17:21:20 +053012572free_hdd_ctx:
Jeff Johnson295189b2012-06-20 16:38:30 -070012573 /* free the power on lock from platform driver */
12574 if (free_riva_power_on_lock("wlan"))
12575 {
12576 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to free power on lock",
12577 __func__);
12578 }
12579
Ashish Kumar Dhanotiya95e5bc22018-04-19 17:06:33 +053012580 /* Free the cache channels of the command SET_DISABLE_CHANNEL_LIST */
12581 wlan_hdd_free_cache_channels(pHddCtx);
12582
c_hpothu78c7b602014-05-17 17:35:49 +053012583 //Free up dynamically allocated members inside HDD Adapter
12584 if (pHddCtx->cfg_ini)
12585 {
12586 kfree(pHddCtx->cfg_ini);
12587 pHddCtx->cfg_ini= NULL;
12588 }
12589
Hanumanth Reddy Pothula1efcd162018-03-14 14:32:27 +053012590 hdd_request_manager_deinit();
12591
Hanumantha Reddy Pothula6fe221c2016-01-28 15:01:09 +053012592 /* FTM/MONITOR mode, WIPHY did not registered
Leo Changf04ddad2013-09-18 13:46:38 -070012593 If un-register here, system crash will happen */
Hanumantha Reddy Pothula6fe221c2016-01-28 15:01:09 +053012594 if (!(VOS_FTM_MODE == hdd_get_conparam() ||
12595 VOS_MONITOR_MODE == hdd_get_conparam()))
Leo Changf04ddad2013-09-18 13:46:38 -070012596 {
12597 wiphy_unregister(wiphy) ;
Agrawal Ashish33ec71e2015-11-26 20:20:58 +053012598 hdd_wlan_free_wiphy_channels(wiphy);
Leo Changf04ddad2013-09-18 13:46:38 -070012599 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012600 wiphy_free(wiphy) ;
Jeff Johnson295189b2012-06-20 16:38:30 -070012601 if (hdd_is_ssr_required())
12602 {
12603 /* WDI timeout had happened during unload, so SSR is needed here */
Madan Mohan Koyyalamudi3246f5b2012-10-15 15:40:02 -070012604 subsystem_restart("wcnss");
Jeff Johnson295189b2012-06-20 16:38:30 -070012605 msleep(5000);
12606 }
12607 hdd_set_ssr_required (VOS_FALSE);
12608}
12609
12610
12611/**---------------------------------------------------------------------------
12612
12613 \brief hdd_update_config_from_nv() - Function to update the contents of
12614 the running configuration with parameters taken from NV storage
12615
12616 \param - pHddCtx - Pointer to the HDD global context
12617
12618 \return - VOS_STATUS_SUCCESS if successful
12619
12620 --------------------------------------------------------------------------*/
12621static VOS_STATUS hdd_update_config_from_nv(hdd_context_t* pHddCtx)
12622{
Jeff Johnson295189b2012-06-20 16:38:30 -070012623 v_BOOL_t itemIsValid = VOS_FALSE;
12624 VOS_STATUS status;
12625 v_MACADDR_t macFromNV[VOS_MAX_CONCURRENCY_PERSONA];
12626 v_U8_t macLoop;
12627
12628 /*If the NV is valid then get the macaddress from nv else get it from qcom_cfg.ini*/
12629 status = vos_nv_getValidity(VNV_FIELD_IMAGE, &itemIsValid);
12630 if(status != VOS_STATUS_SUCCESS)
12631 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080012632 hddLog(VOS_TRACE_LEVEL_ERROR," vos_nv_getValidity() failed");
Jeff Johnson295189b2012-06-20 16:38:30 -070012633 return VOS_STATUS_E_FAILURE;
12634 }
12635
12636 if (itemIsValid == VOS_TRUE)
12637 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080012638 hddLog(VOS_TRACE_LEVEL_INFO_HIGH," Reading the Macaddress from NV");
Jeff Johnson295189b2012-06-20 16:38:30 -070012639 status = vos_nv_readMultiMacAddress((v_U8_t *)&macFromNV[0].bytes[0],
12640 VOS_MAX_CONCURRENCY_PERSONA);
12641 if(status != VOS_STATUS_SUCCESS)
12642 {
12643 /* Get MAC from NV fail, not update CFG info
12644 * INI MAC value will be used for MAC setting */
Arif Hussain6d2a3322013-11-17 19:50:10 -080012645 hddLog(VOS_TRACE_LEVEL_ERROR," vos_nv_readMacAddress() failed");
Jeff Johnson295189b2012-06-20 16:38:30 -070012646 return VOS_STATUS_E_FAILURE;
12647 }
12648
12649 /* If first MAC is not valid, treat all others are not valid
12650 * Then all MACs will be got from ini file */
12651 if(vos_is_macaddr_zero(&macFromNV[0]))
12652 {
12653 /* MAC address in NV file is not configured yet */
12654 hddLog(VOS_TRACE_LEVEL_WARN, "Invalid MAC in NV file");
12655 return VOS_STATUS_E_INVAL;
12656 }
12657
12658 /* Get MAC address from NV, update CFG info */
12659 for(macLoop = 0; macLoop < VOS_MAX_CONCURRENCY_PERSONA; macLoop++)
12660 {
12661 if(vos_is_macaddr_zero(&macFromNV[macLoop]))
12662 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012663 hddLog(VOS_TRACE_LEVEL_ERROR,"not valid MAC from NV for %d", macLoop);
Jeff Johnson295189b2012-06-20 16:38:30 -070012664 /* This MAC is not valid, skip it
12665 * This MAC will be got from ini file */
12666 }
12667 else
12668 {
12669 vos_mem_copy((v_U8_t *)&pHddCtx->cfg_ini->intfMacAddr[macLoop].bytes[0],
12670 (v_U8_t *)&macFromNV[macLoop].bytes[0],
12671 VOS_MAC_ADDR_SIZE);
12672 }
12673 }
12674 }
12675 else
12676 {
12677 hddLog(VOS_TRACE_LEVEL_ERROR, "NV ITEM, MAC Not valid");
12678 return VOS_STATUS_E_FAILURE;
12679 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012680
Jeff Johnson295189b2012-06-20 16:38:30 -070012681
12682 return VOS_STATUS_SUCCESS;
12683}
12684
12685/**---------------------------------------------------------------------------
12686
12687 \brief hdd_post_voss_start_config() - HDD post voss start config helper
12688
12689 \param - pAdapter - Pointer to the HDD
12690
12691 \return - None
12692
12693 --------------------------------------------------------------------------*/
12694VOS_STATUS hdd_post_voss_start_config(hdd_context_t* pHddCtx)
12695{
12696 eHalStatus halStatus;
12697 v_U32_t listenInterval;
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +053012698 tANI_U32 ignoreDtim;
Jeff Johnson295189b2012-06-20 16:38:30 -070012699
Jeff Johnson295189b2012-06-20 16:38:30 -070012700
12701 // Send ready indication to the HDD. This will kick off the MAC
12702 // into a 'running' state and should kick off an initial scan.
12703 halStatus = sme_HDDReadyInd( pHddCtx->hHal );
12704 if ( !HAL_STATUS_SUCCESS( halStatus ) )
12705 {
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +053012706 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: sme_HDDReadyInd() failed with status "
Jeff Johnson295189b2012-06-20 16:38:30 -070012707 "code %08d [x%08x]",__func__, halStatus, halStatus );
12708 return VOS_STATUS_E_FAILURE;
12709 }
12710
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +053012711 // Set default LI and ignoreDtim into HDD context,
Jeff Johnson295189b2012-06-20 16:38:30 -070012712 // otherwise under some race condition, HDD will set 0 LI value into RIVA,
12713 // And RIVA will crash
12714 wlan_cfgGetInt(pHddCtx->hHal, WNI_CFG_LISTEN_INTERVAL, &listenInterval);
12715 pHddCtx->hdd_actual_LI_value = listenInterval;
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +053012716 wlan_cfgGetInt(pHddCtx->hHal, WNI_CFG_IGNORE_DTIM, &ignoreDtim);
12717 pHddCtx->hdd_actual_ignore_DTIM_value = ignoreDtim;
12718
12719
Jeff Johnson295189b2012-06-20 16:38:30 -070012720 return VOS_STATUS_SUCCESS;
12721}
12722
Jeff Johnson295189b2012-06-20 16:38:30 -070012723/* wake lock APIs for HDD */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053012724void hdd_prevent_suspend(uint32_t reason)
Jeff Johnson295189b2012-06-20 16:38:30 -070012725{
Sushant Kaushik83392fa2015-05-05 17:44:40 +053012726
12727 vos_wake_lock_acquire(&wlan_wake_lock, reason);
12728
Jeff Johnson295189b2012-06-20 16:38:30 -070012729}
12730
Sushant Kaushik83392fa2015-05-05 17:44:40 +053012731void hdd_allow_suspend(uint32_t reason)
Jeff Johnson295189b2012-06-20 16:38:30 -070012732{
Sushant Kaushik83392fa2015-05-05 17:44:40 +053012733
12734 vos_wake_lock_release(&wlan_wake_lock, reason);
12735
Jeff Johnson295189b2012-06-20 16:38:30 -070012736}
12737
Sushant Kaushik83392fa2015-05-05 17:44:40 +053012738void hdd_prevent_suspend_timeout(v_U32_t timeout, uint32_t reason)
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -070012739{
Sushant Kaushik83392fa2015-05-05 17:44:40 +053012740
12741 vos_wake_lock_timeout_release(&wlan_wake_lock, timeout,
12742 reason);
12743
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -070012744}
12745
Rajeev Kumar Sirasanagandla4c068d42019-02-22 21:39:36 +053012746/**
12747 * hdd_get_feature_caps_cb() - Callback invoked from WDA
12748 * @cookie: to identify HDD request to firmware
12749 *
12750 * This function is invoked from WDA when feature capabilities response
12751 * is received from firmware.
12752 *
12753 * Return: None
12754 */
12755static void hdd_get_feature_caps_cb(void *cookie)
12756{
12757 struct hdd_request *request;
12758
12759 request = hdd_request_get(cookie);
12760 if (!request) {
12761 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Obsolete request"));
12762 return;
12763 }
12764
12765 pr_info("%s: Firmware feature capabilities received\n", __func__);
12766
12767 hdd_request_complete(request);
12768 hdd_request_put(request);
12769}
12770
12771/**
12772 * hdd_get_feature_caps() - Get features supported by firmware
12773 * @hdd_ctx: Pointer to HDD context
12774 *
12775 * This function uses request manager framework to get the feature
12776 * capabilities from firmware.
12777 *
12778 * Return: None
12779 */
12780static void hdd_get_feature_caps(hdd_context_t *hdd_ctx)
12781{
12782 VOS_STATUS status;
12783 void *cookie;
12784 int ret;
12785 struct hdd_request *request;
12786 static const struct hdd_request_params params = {
12787 .priv_size = 0,
12788 .timeout_ms = WLAN_WAIT_TIME_FEATURE_CAPS,
12789 };
12790 struct sir_feature_caps_params caps_params = {0};
12791
12792 request = hdd_request_alloc(&params);
12793 if (!request) {
12794 pr_err("%s: Request allocation failure\n", __func__);
12795 return;
12796 }
12797
12798 cookie = hdd_request_cookie(request);
12799 caps_params.user_data = cookie;
12800 caps_params.feature_caps_cb = hdd_get_feature_caps_cb;
12801
12802 status = sme_featureCapsExchange(&caps_params);
12803 if (status != VOS_STATUS_SUCCESS) {
12804 pr_err("%s: Unable to get feature caps\n", __func__);
12805 goto end;
12806 }
12807
12808 /* request was sent -- wait for the response */
12809 ret = hdd_request_wait_for_response(request);
12810 if (ret) {
12811 pr_err("%s: SME timeout while retrieving feature caps\n",
12812 __func__);
12813 goto end;
12814 }
12815
12816end:
12817 hdd_request_put(request);
12818}
12819
Jeff Johnson295189b2012-06-20 16:38:30 -070012820/**---------------------------------------------------------------------------
12821
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -070012822 \brief hdd_exchange_version_and_caps() - HDD function to exchange version and capability
12823 information between Host and Riva
12824
12825 This function gets reported version of FW
12826 It also finds the version of Riva headers used to compile the host
12827 It compares the above two and prints a warning if they are different
12828 It gets the SW and HW version string
12829 Finally, it exchanges capabilities between host and Riva i.e. host and riva exchange a msg
12830 indicating the features they support through a bitmap
12831
12832 \param - pHddCtx - Pointer to HDD context
12833
12834 \return - void
12835
12836 --------------------------------------------------------------------------*/
12837
12838void hdd_exchange_version_and_caps(hdd_context_t *pHddCtx)
12839{
12840
12841 tSirVersionType versionCompiled;
12842 tSirVersionType versionReported;
12843 tSirVersionString versionString;
12844 tANI_U8 fwFeatCapsMsgSupported = 0;
12845 VOS_STATUS vstatus;
12846
Mingcheng Zhu87f22fc2014-01-30 19:23:32 -080012847 memset(&versionCompiled, 0, sizeof(versionCompiled));
12848 memset(&versionReported, 0, sizeof(versionReported));
12849
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -070012850 /* retrieve and display WCNSS version information */
12851 do {
12852
12853 vstatus = sme_GetWcnssWlanCompiledVersion(pHddCtx->hHal,
12854 &versionCompiled);
12855 if (!VOS_IS_STATUS_SUCCESS(vstatus))
12856 {
12857 hddLog(VOS_TRACE_LEVEL_FATAL,
12858 "%s: unable to retrieve WCNSS WLAN compiled version",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070012859 __func__);
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -070012860 break;
12861 }
12862
12863 vstatus = sme_GetWcnssWlanReportedVersion(pHddCtx->hHal,
12864 &versionReported);
12865 if (!VOS_IS_STATUS_SUCCESS(vstatus))
12866 {
12867 hddLog(VOS_TRACE_LEVEL_FATAL,
12868 "%s: unable to retrieve WCNSS WLAN reported version",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070012869 __func__);
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -070012870 break;
12871 }
12872
12873 if ((versionCompiled.major != versionReported.major) ||
12874 (versionCompiled.minor != versionReported.minor) ||
12875 (versionCompiled.version != versionReported.version) ||
12876 (versionCompiled.revision != versionReported.revision))
12877 {
12878 pr_err("%s: WCNSS WLAN Version %u.%u.%u.%u, "
12879 "Host expected %u.%u.%u.%u\n",
12880 WLAN_MODULE_NAME,
12881 (int)versionReported.major,
12882 (int)versionReported.minor,
12883 (int)versionReported.version,
12884 (int)versionReported.revision,
12885 (int)versionCompiled.major,
12886 (int)versionCompiled.minor,
12887 (int)versionCompiled.version,
12888 (int)versionCompiled.revision);
12889 }
12890 else
12891 {
12892 pr_info("%s: WCNSS WLAN version %u.%u.%u.%u\n",
12893 WLAN_MODULE_NAME,
12894 (int)versionReported.major,
12895 (int)versionReported.minor,
12896 (int)versionReported.version,
12897 (int)versionReported.revision);
12898 }
12899
12900 vstatus = sme_GetWcnssSoftwareVersion(pHddCtx->hHal,
12901 versionString,
12902 sizeof(versionString));
12903 if (!VOS_IS_STATUS_SUCCESS(vstatus))
12904 {
12905 hddLog(VOS_TRACE_LEVEL_FATAL,
12906 "%s: unable to retrieve WCNSS software version string",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070012907 __func__);
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -070012908 break;
12909 }
12910
12911 pr_info("%s: WCNSS software version %s\n",
12912 WLAN_MODULE_NAME, versionString);
Sushant Kaushik084f6592015-09-10 13:11:56 +053012913 vos_mem_copy(pHddCtx->fw_Version, versionString, sizeof(versionString));
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -070012914
12915 vstatus = sme_GetWcnssHardwareVersion(pHddCtx->hHal,
12916 versionString,
12917 sizeof(versionString));
12918 if (!VOS_IS_STATUS_SUCCESS(vstatus))
12919 {
12920 hddLog(VOS_TRACE_LEVEL_FATAL,
12921 "%s: unable to retrieve WCNSS hardware version string",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070012922 __func__);
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -070012923 break;
12924 }
12925
12926 pr_info("%s: WCNSS hardware version %s\n",
12927 WLAN_MODULE_NAME, versionString);
12928
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -070012929 /* 1.Check if FW version is greater than 0.1.1.0. Only then send host-FW capability exchange message
12930 2.Host-FW capability exchange message is only present on riva 1.1 so
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -070012931 send the message only if it the riva is 1.1
12932 minor numbers for different riva branches:
12933 0 -> (1.0)Mainline Build
12934 1 -> (1.1)Mainline Build
12935 2->(1.04) Stability Build
12936 */
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -070012937 if (((versionReported.major>0) || (versionReported.minor>1) ||
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -070012938 ((versionReported.minor>=1) && (versionReported.version>=1)))
12939 && ((versionReported.major == 1) && (versionReported.minor >= 1)))
12940 fwFeatCapsMsgSupported = 1;
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -070012941
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -070012942 if (fwFeatCapsMsgSupported)
Yathish9f22e662012-12-10 14:21:35 -080012943 {
12944#ifdef WLAN_ACTIVEMODE_OFFLOAD_FEATURE
12945 if(!pHddCtx->cfg_ini->fEnableActiveModeOffload)
12946 sme_disableFeatureCapablity(WLANACTIVE_OFFLOAD);
12947#endif
Ravi Joshid2ca7c42013-07-23 08:37:49 -070012948 /* Indicate if IBSS heartbeat monitoring needs to be offloaded */
12949 if (!pHddCtx->cfg_ini->enableIbssHeartBeatOffload)
12950 {
12951 sme_disableFeatureCapablity(IBSS_HEARTBEAT_OFFLOAD);
12952 }
12953
Rajeev Kumar Sirasanagandla4c068d42019-02-22 21:39:36 +053012954 hdd_get_feature_caps(pHddCtx);
Yathish9f22e662012-12-10 14:21:35 -080012955 }
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -070012956
12957 } while (0);
12958
12959}
Rajeev Kumar Sirasanagandla4c068d42019-02-22 21:39:36 +053012960
Neelansh Mittaledafed22014-09-04 18:54:39 +053012961void wlan_hdd_send_svc_nlink_msg(int type, void *data, int len)
12962{
12963 struct sk_buff *skb;
12964 struct nlmsghdr *nlh;
12965 tAniMsgHdr *ani_hdr;
Hanumantha Reddy Pothulacf2c7ea2015-04-27 14:50:47 +053012966 int flags = GFP_KERNEL;
Bhargav shah23c94942015-10-13 12:48:35 +053012967 void *nl_data = NULL;
Neelansh Mittaledafed22014-09-04 18:54:39 +053012968
Hanumantha Reddy Pothulacf2c7ea2015-04-27 14:50:47 +053012969 if (in_interrupt() || irqs_disabled() || in_atomic())
12970 flags = GFP_ATOMIC;
12971
12972 skb = alloc_skb(NLMSG_SPACE(WLAN_NL_MAX_PAYLOAD), flags);
Neelansh Mittaledafed22014-09-04 18:54:39 +053012973
12974 if(skb == NULL) {
12975 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12976 "%s: alloc_skb failed", __func__);
12977 return;
12978 }
12979
12980 nlh = (struct nlmsghdr *)skb->data;
12981 nlh->nlmsg_pid = 0; /* from kernel */
12982 nlh->nlmsg_flags = 0;
12983 nlh->nlmsg_seq = 0;
12984 nlh->nlmsg_type = WLAN_NL_MSG_SVC;
12985
12986 ani_hdr = NLMSG_DATA(nlh);
12987 ani_hdr->type = type;
12988
12989 switch(type) {
12990 case WLAN_SVC_SAP_RESTART_IND:
12991 ani_hdr->length = 0;
12992 nlh->nlmsg_len = NLMSG_LENGTH((sizeof(tAniMsgHdr)));
12993 skb_put(skb, NLMSG_SPACE(sizeof(tAniMsgHdr)));
12994 break;
Bhargav Shahd0715912015-10-01 18:17:37 +053012995 case WLAN_SVC_WLAN_TP_IND:
12996 ani_hdr->length = len;
12997 nlh->nlmsg_len = NLMSG_LENGTH((sizeof(tAniMsgHdr)
12998 + len));
12999 nl_data = (char *)ani_hdr + sizeof(tAniMsgHdr);
13000 memcpy(nl_data, data, len);
13001 skb_put(skb, NLMSG_SPACE(sizeof(tAniMsgHdr) + len));
13002 break;
Bhargav shah23c94942015-10-13 12:48:35 +053013003 case WLAN_MSG_RPS_ENABLE_IND:
13004 ani_hdr->length = len;
13005 nlh->nlmsg_len = NLMSG_LENGTH((sizeof(tAniMsgHdr) + len));
13006 nl_data = (char *)ani_hdr + sizeof(tAniMsgHdr);
13007 memcpy(nl_data, data, len);
13008 skb_put(skb, NLMSG_SPACE(sizeof(tAniMsgHdr) + len));
13009 break;
Neelansh Mittaledafed22014-09-04 18:54:39 +053013010 default:
13011 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13012 "Attempt to send unknown nlink message %d", type);
13013 kfree_skb(skb);
13014 return;
13015 }
13016
13017 nl_srv_bcast(skb);
13018
13019 return;
13020}
13021
Bhargav Shahd0715912015-10-01 18:17:37 +053013022/**
13023 * hdd_request_tcp_delack() - Find the Delack value based on RX packet
13024 * @pHddCtx: Valid Global HDD context pointer
13025 * @rx_packets: Number of RX packet in perticular time
13026 *
13027 * Based on the RX packet this function calculate next value of tcp delack.
13028 * This function compare rx packet value to high and low threshold limit.
13029 *
13030 * Return: void
13031 */
13032void hdd_request_tcp_delack(hdd_context_t *pHddCtx, uint64_t rx_packets)
13033{
13034 /* average of rx_packets and prev_rx is taken so that
13035 bus width doesnot fluctuate much */
13036 uint64_t temp_rx = (rx_packets + pHddCtx->prev_rx)/2;
Alok Kumarf3724462018-04-05 15:18:54 +053013037 enum wlan_tp_level next_rx_level = pHddCtx->cur_rx_level;
Neelansh Mittaledafed22014-09-04 18:54:39 +053013038
Bhargav Shahd0715912015-10-01 18:17:37 +053013039 pHddCtx->prev_rx = rx_packets;
13040 if (temp_rx > pHddCtx->cfg_ini->tcpDelAckThresholdHigh)
Alok Kumarf3724462018-04-05 15:18:54 +053013041 next_rx_level = WLAN_SVC_TP_HIGH;
Bhargav Shahd0715912015-10-01 18:17:37 +053013042 else if (temp_rx <= pHddCtx->cfg_ini->tcpDelAckThresholdLow)
Alok Kumarf3724462018-04-05 15:18:54 +053013043 next_rx_level = WLAN_SVC_TP_LOW;
Bhargav Shahd0715912015-10-01 18:17:37 +053013044
13045 hdd_set_delack_value(pHddCtx, next_rx_level);
13046}
13047
13048#define HDD_BW_GET_DIFF(x, y) ((x) >= (y) ? (x) - (y) : (ULONG_MAX - (y) + (x)))
13049
13050/**
13051 * hdd_tcp_delack_compute_function() - get link status
13052 * @priv: Valid Global HDD context pointer
13053 *
13054 * This function find number of RX packet during timer life span.
13055 * It request tcp delack with number of RX packet and re-configure delack timer
13056 * for tcpDelAckComputeInterval timer interval.
13057 *
13058 * Return: void
13059 */
13060void hdd_tcp_delack_compute_function(void *priv)
13061{
13062 hdd_context_t *pHddCtx = (hdd_context_t *)priv;
13063 hdd_adapter_t *pAdapter = NULL;
13064 v_U32_t rx_packets = 0;
13065 hdd_adapter_list_node_t *pAdapterNode = NULL;
13066 VOS_STATUS status = 0;
13067
13068 for (status = hdd_get_front_adapter(pHddCtx, &pAdapterNode);
13069 NULL != pAdapterNode && VOS_STATUS_SUCCESS == status;
13070 status = hdd_get_next_adapter(pHddCtx, pAdapterNode, &pAdapterNode)) {
13071 if ((pAdapter = pAdapterNode->pAdapter) == NULL)
13072 continue;
13073
13074 rx_packets += HDD_BW_GET_DIFF(pAdapter->stats.rx_packets,
13075 pAdapter->prev_rx_packets);
13076 pAdapter->prev_rx_packets = pAdapter->stats.rx_packets;
13077 }
13078
13079 hdd_request_tcp_delack(pHddCtx, rx_packets);
13080
13081 vos_timer_start(&pHddCtx->delack_timer,
13082 pHddCtx->cfg_ini->tcpDelAckComputeInterval);
13083}
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -070013084
13085/**---------------------------------------------------------------------------
13086
Gopichand Nakkalafce506f2013-07-03 23:55:16 +053013087 \brief hdd_is_5g_supported() - HDD function to know if hardware supports 5GHz
13088
13089 \param - pHddCtx - Pointer to the hdd context
13090
13091 \return - true if hardware supports 5GHz
13092
13093 --------------------------------------------------------------------------*/
Vinay Krishna Erannafacf5e22014-02-24 13:16:25 +053013094boolean hdd_is_5g_supported(hdd_context_t * pHddCtx)
Gopichand Nakkalafce506f2013-07-03 23:55:16 +053013095{
13096 /* If wcnss_wlan_iris_xo_mode() returns WCNSS_XO_48MHZ(1);
13097 * then hardware support 5Ghz.
13098 */
13099 if (WCNSS_XO_48MHZ == wcnss_wlan_iris_xo_mode())
13100 {
Ratheesh S P36dbc932015-08-07 14:28:57 +053013101 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Hardware supports 5Ghz", __func__);
Gopichand Nakkalafce506f2013-07-03 23:55:16 +053013102 return true;
13103 }
13104 else
13105 {
Ratheesh S P36dbc932015-08-07 14:28:57 +053013106 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Hardware doesn't supports 5Ghz",
Gopichand Nakkalafce506f2013-07-03 23:55:16 +053013107 __func__);
13108 return false;
13109 }
13110}
13111
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +053013112/**---------------------------------------------------------------------------
13113
13114 \brief hdd_generate_iface_mac_addr_auto() - HDD Mac Interface Auto
13115 generate function
13116
13117 This is generate the random mac address for WLAN interface
13118
13119 \param - pHddCtx - Pointer to HDD context
13120 idx - Start interface index to get auto
13121 generated mac addr.
13122 mac_addr - Mac address
13123
13124 \return - 0 for success, < 0 for failure
13125
13126 --------------------------------------------------------------------------*/
13127
13128static int hdd_generate_iface_mac_addr_auto(hdd_context_t *pHddCtx,
13129 int idx, v_MACADDR_t mac_addr)
13130{
13131 int i;
13132 unsigned int serialno;
13133 serialno = wcnss_get_serial_number();
13134
13135 if (0 != serialno)
13136 {
13137 /* MAC address has 3 bytes of OUI so we have a maximum of 3
13138 bytes of the serial number that can be used to generate
13139 the other 3 bytes of the MAC address. Mask off all but
13140 the lower 3 bytes (this will also make sure we don't
13141 overflow in the next step) */
13142 serialno &= 0x00FFFFFF;
13143
13144 /* we need a unique address for each session */
13145 serialno *= VOS_MAX_CONCURRENCY_PERSONA;
13146
13147 /* autogen other Mac addresses */
13148 for (i = idx; i < VOS_MAX_CONCURRENCY_PERSONA; i++)
13149 {
13150 /* start with the entire default address */
13151 pHddCtx->cfg_ini->intfMacAddr[i] = mac_addr;
13152 /* then replace the lower 3 bytes */
13153 pHddCtx->cfg_ini->intfMacAddr[i].bytes[3] = (serialno >> 16) & 0xFF;
13154 pHddCtx->cfg_ini->intfMacAddr[i].bytes[4] = (serialno >> 8) & 0xFF;
13155 pHddCtx->cfg_ini->intfMacAddr[i].bytes[5] = serialno & 0xFF;
13156
Nachiket Kukadede2e24f2017-09-25 16:24:27 +053013157 if (0 == memcmp(&pHddCtx->cfg_ini->intfMacAddr[i].bytes[0],
13158 &mac_addr.bytes[0], VOS_MAC_ADDR_SIZE))
13159 pHddCtx->cfg_ini->intfMacAddr[i].bytes[5] +=
13160 VOS_MAX_CONCURRENCY_PERSONA;
13161
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +053013162 serialno++;
13163 hddLog(VOS_TRACE_LEVEL_ERROR,
13164 "%s: Derived Mac Addr: "
13165 MAC_ADDRESS_STR, __func__,
13166 MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[i].bytes));
13167 }
13168
13169 }
13170 else
13171 {
13172 hddLog(LOGE, FL("Failed to Get Serial NO"));
13173 return -1;
13174 }
13175 return 0;
13176}
Gopichand Nakkalafce506f2013-07-03 23:55:16 +053013177
Katya Nigame7b69a82015-04-28 15:24:06 +053013178int wlan_hdd_mon_open(hdd_context_t *pHddCtx)
13179{
13180 VOS_STATUS status;
13181 v_CONTEXT_t pVosContext= NULL;
13182 hdd_adapter_t *pAdapter= NULL;
13183
13184 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
13185
13186 if (NULL == pVosContext)
13187 {
13188 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13189 "%s: Trying to open VOSS without a PreOpen", __func__);
13190 VOS_ASSERT(0);
13191 return VOS_STATUS_E_FAILURE;
13192 }
13193
13194 status = vos_nv_open();
13195 if (!VOS_IS_STATUS_SUCCESS(status))
13196 {
13197 /* NV module cannot be initialized */
13198 hddLog( VOS_TRACE_LEVEL_FATAL,
13199 "%s: vos_nv_open failed", __func__);
13200 return VOS_STATUS_E_FAILURE;
13201 }
13202
13203 status = vos_init_wiphy_from_nv_bin();
13204 if (!VOS_IS_STATUS_SUCCESS(status))
13205 {
13206 /* NV module cannot be initialized */
13207 hddLog( VOS_TRACE_LEVEL_FATAL,
13208 "%s: vos_init_wiphy failed", __func__);
13209 goto err_vos_nv_close;
13210 }
13211
13212 status = vos_open( &pVosContext, pHddCtx->parent_dev);
13213 if ( !VOS_IS_STATUS_SUCCESS( status ))
13214 {
13215 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: vos_open failed", __func__);
13216 goto err_vos_nv_close;
13217 }
13218
13219 status = vos_mon_start( pVosContext );
13220 if ( !VOS_IS_STATUS_SUCCESS( status ) )
13221 {
13222 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: vos_start failed",__func__);
13223 goto err_vosclose;
13224 }
13225
13226 WLANTL_SetMonRxCbk( pVosContext, hdd_rx_packet_monitor_cbk );
Rajeev Kumar Sirasanagandla4c068d42019-02-22 21:39:36 +053013227 sme_featureCapsExchange(NULL);
Katya Nigame7b69a82015-04-28 15:24:06 +053013228 wcnss_wlan_set_drvdata(pHddCtx->parent_dev, pHddCtx);
13229
13230 pAdapter = hdd_open_adapter( pHddCtx, WLAN_HDD_MONITOR, "wlan%d",
13231 wlan_hdd_get_intf_addr(pHddCtx), FALSE );
13232 if( pAdapter == NULL )
13233 {
13234 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: hdd_open_adapter failed", __func__);
13235 goto err_close_adapter;
13236 }
13237
13238 //Initialize the nlink service
13239 if(nl_srv_init() != 0)
13240 {
13241 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: nl_srv_init failed", __func__);
13242 goto err_close_adapter;
13243 }
13244 return VOS_STATUS_SUCCESS;
13245
13246err_close_adapter:
13247 hdd_close_all_adapters( pHddCtx );
13248 vos_mon_stop( pVosContext );
13249err_vosclose:
13250 status = vos_sched_close( pVosContext );
13251 if (!VOS_IS_STATUS_SUCCESS(status)) {
13252 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
13253 "%s: Failed to close VOSS Scheduler", __func__);
13254 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( status ) );
13255 }
13256 vos_close(pVosContext );
13257
13258err_vos_nv_close:
13259 vos_nv_close();
13260
13261return status;
13262}
Gopichand Nakkalafce506f2013-07-03 23:55:16 +053013263/**---------------------------------------------------------------------------
13264
Mihir Shetefc7ff5b2014-01-27 11:30:05 +053013265 \brief hdd_11d_scan_done - callback to be executed when 11d scan is
13266 completed to flush out the scan results
13267
13268 11d scan is done during driver load and is a passive scan on all
13269 channels supported by the device, 11d scans may find some APs on
13270 frequencies which are forbidden to be used in the regulatory domain
13271 the device is operating in. If these APs are notified to the supplicant
13272 it may try to connect to these APs, thus flush out all the scan results
13273 which are present in SME after 11d scan is done.
13274
13275 \return - eHalStatus
13276
13277 --------------------------------------------------------------------------*/
13278static eHalStatus hdd_11d_scan_done(tHalHandle halHandle, void *pContext,
13279 tANI_U32 scanId, eCsrScanStatus status)
13280{
13281 ENTER();
13282
13283 sme_ScanFlushResult(halHandle, 0);
13284
13285 EXIT();
13286
13287 return eHAL_STATUS_SUCCESS;
13288}
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053013289/**---------------------------------------------------------------------------
13290
13291 \brief hdd_init_frame_logging_done - callback to be executed when mgmt frame
13292 logging is completed successfully.
13293
13294 \return - None
13295
13296 --------------------------------------------------------------------------*/
c_manjeecfd1efb2015-09-25 19:32:34 +053013297void hdd_init_frame_logging_done(void *fwlogInitCbContext, tAniLoggingInitRsp *pRsp)
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053013298{
Siddharth Bhald1be97f2015-05-27 22:39:59 +053013299 hdd_context_t* pHddCtx = (hdd_context_t*)fwlogInitCbContext;
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053013300
13301 if (NULL == pHddCtx)
13302 {
13303 hddLog(VOS_TRACE_LEVEL_ERROR,
13304 "%s: HDD context is NULL",__func__);
13305 return;
13306 }
13307
c_manjeecfd1efb2015-09-25 19:32:34 +053013308 if ((pRsp->status == VOS_STATUS_SUCCESS) &&
Mahesh A Saptasagarfabb1a02015-06-29 12:17:04 +053013309 (TRUE == pHddCtx->cfg_ini->enableMgmtLogging))
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053013310 {
13311 hddLog(VOS_TRACE_LEVEL_INFO, FL("Mgmt Frame Logging init successful"));
13312 pHddCtx->mgmt_frame_logging = TRUE;
13313 }
13314 else
13315 {
13316 hddLog(VOS_TRACE_LEVEL_INFO, FL("Mgmt Frame Logging init not success"));
13317 pHddCtx->mgmt_frame_logging = FALSE;
c_manjeecfd1efb2015-09-25 19:32:34 +053013318 return;
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053013319 }
13320
c_manjeecfd1efb2015-09-25 19:32:34 +053013321 /*Check feature supported by FW*/
13322 if(TRUE == sme_IsFeatureSupportedByFW(MEMORY_DUMP_SUPPORTED))
13323 {
13324 //Store fwr mem dump size given by firmware.
13325 wlan_store_fwr_mem_dump_size(pRsp->fw_mem_dump_max_size);
13326 }
13327 else
13328 {
13329 wlan_store_fwr_mem_dump_size(0);
13330 }
13331
13332
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053013333}
13334/**---------------------------------------------------------------------------
13335
13336 \brief hdd_init_frame_logging - function to initialize frame logging.
13337 Currently only Mgmt Frames are logged in both TX
13338 and Rx direction and are sent to userspace
13339 application using logger thread when queried.
13340
13341 \return - None
13342
13343 --------------------------------------------------------------------------*/
Siddharth Bhald1be97f2015-05-27 22:39:59 +053013344void hdd_init_frame_logging(hdd_context_t* pHddCtx)
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053013345{
13346 eHalStatus halStatus = eHAL_STATUS_FAILURE;
Sreelakshmi Konamkid8784d92016-04-14 14:59:13 +053013347 tSirFWLoggingInitParam wlanFWLoggingInitParam = {0};
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053013348
Siddharth Bhald1be97f2015-05-27 22:39:59 +053013349 if (TRUE != sme_IsFeatureSupportedByFW(MGMT_FRAME_LOGGING) &&
13350 TRUE != sme_IsFeatureSupportedByFW(LOGGING_ENHANCEMENT))
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053013351 {
13352 hddLog(VOS_TRACE_LEVEL_INFO, FL("MGMT_FRAME_LOGGING not supp by FW"));
13353 return;
13354 }
13355
sheenam monga1a0202d2020-01-03 15:20:57 +053013356 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Configuring %s %s %s Logging",__func__,
Siddharth Bhald1be97f2015-05-27 22:39:59 +053013357 pHddCtx->cfg_ini->enableFWLogging?"FW Log,":"",
13358 pHddCtx->cfg_ini->enableContFWLogging ? "Cont FW log,":"",
sheenam monga1a0202d2020-01-03 15:20:57 +053013359 pHddCtx->cfg_ini->enableMgmtLogging ? "Mgmt Pkt Log":"");
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053013360
Siddharth Bhald1be97f2015-05-27 22:39:59 +053013361 if (pHddCtx->cfg_ini->enableFWLogging ||
13362 pHddCtx->cfg_ini->enableContFWLogging)
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053013363 {
Sreelakshmi Konamkid8784d92016-04-14 14:59:13 +053013364 wlanFWLoggingInitParam.enableFlag |= WLAN_QXDM_LOG_EN;
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053013365 }
13366
Sushant Kaushik46804902015-07-08 14:46:03 +053013367 if (pHddCtx->cfg_ini->enableMgmtLogging)
13368 {
Sreelakshmi Konamkid8784d92016-04-14 14:59:13 +053013369 wlanFWLoggingInitParam.enableFlag |= WLAN_FRAME_LOG_EN;
Sushant Kaushik46804902015-07-08 14:46:03 +053013370 }
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053013371 if (pHddCtx->cfg_ini->enableBMUHWtracing)
13372 {
Sreelakshmi Konamkid8784d92016-04-14 14:59:13 +053013373 wlanFWLoggingInitParam.enableFlag |= WLAN_BMUHW_TRACE_LOG_EN;
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053013374 }
Sreelakshmi Konamkid8784d92016-04-14 14:59:13 +053013375 if( wlanFWLoggingInitParam.enableFlag == 0 )
c_manjeecfd1efb2015-09-25 19:32:34 +053013376 {
13377 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Logging not enabled", __func__);
13378 return;
13379 }
Sreelakshmi Konamkid8784d92016-04-14 14:59:13 +053013380 wlanFWLoggingInitParam.frameType = WLAN_FRAME_LOGGING_FRAMETYPE_MGMT;
13381 wlanFWLoggingInitParam.frameSize = WLAN_MGMT_LOGGING_FRAMESIZE_128BYTES;
13382 wlanFWLoggingInitParam.bufferMode = WLAN_FRAME_LOGGING_BUFFERMODE_CIRCULAR;
13383 wlanFWLoggingInitParam.continuousFrameLogging =
Siddharth Bhald1be97f2015-05-27 22:39:59 +053013384 pHddCtx->cfg_ini->enableContFWLogging;
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053013385
Sreelakshmi Konamkid8784d92016-04-14 14:59:13 +053013386 wlanFWLoggingInitParam.enableFlag &= ~WLAN_DPU_TXP_LOG_EN;
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053013387
Sreelakshmi Konamkid8784d92016-04-14 14:59:13 +053013388 wlanFWLoggingInitParam.minLogBufferSize =
Siddharth Bhald1be97f2015-05-27 22:39:59 +053013389 pHddCtx->cfg_ini->minLoggingBufferSize;
Sreelakshmi Konamkid8784d92016-04-14 14:59:13 +053013390 wlanFWLoggingInitParam.maxLogBufferSize =
Siddharth Bhald1be97f2015-05-27 22:39:59 +053013391 pHddCtx->cfg_ini->maxLoggingBufferSize;
Sreelakshmi Konamkid8784d92016-04-14 14:59:13 +053013392 wlanFWLoggingInitParam.fwlogInitCallback = hdd_init_frame_logging_done;
13393 wlanFWLoggingInitParam.fwlogInitCbContext= pHddCtx;
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053013394
Sreelakshmi Konamkid8784d92016-04-14 14:59:13 +053013395 halStatus = sme_InitMgmtFrameLogging(pHddCtx->hHal, &wlanFWLoggingInitParam);
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053013396
13397 if (eHAL_STATUS_SUCCESS != halStatus)
13398 {
Sreelakshmi Konamkid8784d92016-04-14 14:59:13 +053013399 hddLog(LOGE, FL("sme_InitMgmtFrameLogging failed, returned %d"),
13400 halStatus);
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053013401 }
13402
13403 return;
13404}
Mihir Shetefc7ff5b2014-01-27 11:30:05 +053013405
Bhargav shah23c94942015-10-13 12:48:35 +053013406static void hdd_dp_util_send_rps_ind(hdd_context_t *hdd_ctxt)
13407{
13408 hdd_adapter_t *adapter;
13409 hdd_adapter_list_node_t *adapter_node, *next;
13410 VOS_STATUS status = VOS_STATUS_SUCCESS;
13411 struct wlan_rps_data rps_data;
13412 int count;
13413
13414 if(!hdd_ctxt->cfg_ini->rps_mask)
13415 {
13416 return;
13417 }
13418
13419 for (count=0; count < WLAN_SVC_IFACE_NUM_QUEUES; count++)
13420 {
13421 rps_data.cpu_map[count] = hdd_ctxt->cfg_ini->rps_mask;
13422 }
13423
13424 rps_data.num_queues = WLAN_SVC_IFACE_NUM_QUEUES;
13425
13426 hddLog(LOG1, FL("0x%x 0x%x 0x%x 0x%x 0x%x 0x%x"),
13427 rps_data.cpu_map[0], rps_data.cpu_map[1],rps_data.cpu_map[2],
13428 rps_data.cpu_map[3], rps_data.cpu_map[4], rps_data.cpu_map[5]);
13429
13430 status = hdd_get_front_adapter (hdd_ctxt, &adapter_node);
13431
13432 while (NULL != adapter_node && VOS_STATUS_SUCCESS == status)
13433 {
13434 adapter = adapter_node->pAdapter;
13435 if (NULL != adapter) {
13436 strlcpy(rps_data.ifname, adapter->dev->name,
13437 sizeof(rps_data.ifname));
13438 wlan_hdd_send_svc_nlink_msg(WLAN_MSG_RPS_ENABLE_IND,
13439 (void *)&rps_data,sizeof(rps_data));
13440 }
13441 status = hdd_get_next_adapter (hdd_ctxt, adapter_node, &next);
13442 adapter_node = next;
13443 }
13444}
13445
Masti, Narayanraddi26378462016-01-05 18:20:28 +053013446void wlan_hdd_schedule_defer_scan(struct work_struct *work)
13447{
13448 scan_context_t *scan_ctx =
13449 container_of(work, scan_context_t, scan_work.work);
13450
13451 if (NULL == scan_ctx)
13452 {
13453 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13454 FL("scan_ctx is NULL"));
13455 return;
13456 }
13457
13458 if (unlikely(TDLS_CTX_MAGIC != scan_ctx->magic))
13459 return;
13460
13461 scan_ctx->attempt++;
13462
13463 wlan_hdd_cfg80211_scan(scan_ctx->wiphy,
13464#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
13465 scan_ctx->dev,
13466#endif
13467 scan_ctx->scan_request);
13468}
13469
13470int wlan_hdd_copy_defer_scan_context(hdd_context_t *pHddCtx,
13471 struct wiphy *wiphy,
13472#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
13473 struct net_device *dev,
13474#endif
13475 struct cfg80211_scan_request *request)
13476{
13477 scan_context_t *scan_ctx;
13478
13479 ENTER();
13480 if (0 != (wlan_hdd_validate_context(pHddCtx)))
13481 {
13482 return -1;
13483 }
13484
13485 scan_ctx = &pHddCtx->scan_ctxt;
13486
13487 scan_ctx->wiphy = wiphy;
13488#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
13489 scan_ctx->dev = dev;
13490#endif
13491
13492 scan_ctx->scan_request = request;
13493
13494 EXIT();
13495 return 0;
13496}
13497
13498void wlan_hdd_defer_scan_init_work(hdd_context_t *pHddCtx,
13499 struct wiphy *wiphy,
13500#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
13501 struct net_device *dev,
13502#endif
13503 struct cfg80211_scan_request *request,
13504 unsigned long delay)
13505{
13506 if (TDLS_CTX_MAGIC != pHddCtx->scan_ctxt.magic)
13507 {
13508#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
13509 wlan_hdd_copy_defer_scan_context(pHddCtx, wiphy, dev, request);
13510#else
13511 wlan_hdd_copy_defer_scan_context(pHddCtx, wiphy, request);
13512#endif
13513 pHddCtx->scan_ctxt.attempt = 0;
13514 pHddCtx->scan_ctxt.magic = TDLS_CTX_MAGIC;
13515 }
13516 schedule_delayed_work(&pHddCtx->scan_ctxt.scan_work, delay);
13517}
13518
13519void wlan_hdd_init_deinit_defer_scan_context(scan_context_t *scan_ctx)
13520{
13521 scan_ctx->magic = 0;
13522 scan_ctx->attempt = 0;
13523 scan_ctx->reject = 0;
13524 scan_ctx->scan_request = NULL;
13525
13526 return;
13527}
13528
Mihir Shetefc7ff5b2014-01-27 11:30:05 +053013529/**---------------------------------------------------------------------------
13530
Jeff Johnson295189b2012-06-20 16:38:30 -070013531 \brief hdd_wlan_startup() - HDD init function
13532
13533 This is the driver startup code executed once a WLAN device has been detected
13534
13535 \param - dev - Pointer to the underlying device
13536
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -080013537 \return - 0 for success, < 0 for failure
Jeff Johnson295189b2012-06-20 16:38:30 -070013538
13539 --------------------------------------------------------------------------*/
13540
13541int hdd_wlan_startup(struct device *dev )
13542{
13543 VOS_STATUS status;
13544 hdd_adapter_t *pAdapter = NULL;
Jeff Johnsone7245742012-09-05 17:12:55 -070013545 hdd_adapter_t *pP2pAdapter = NULL;
Arunk Khandavalli95608be2019-01-22 13:12:54 +053013546 hdd_adapter_t *softapAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070013547 hdd_context_t *pHddCtx = NULL;
13548 v_CONTEXT_t pVosContext= NULL;
13549#ifdef WLAN_BTAMP_FEATURE
13550 VOS_STATUS vStatus = VOS_STATUS_SUCCESS;
13551 WLANBAP_ConfigType btAmpConfig;
13552 hdd_config_t *pConfig;
13553#endif
13554 int ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070013555 struct wiphy *wiphy;
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +053013556 v_MACADDR_t mac_addr;
Jeff Johnson295189b2012-06-20 16:38:30 -070013557
13558 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -070013559 /*
13560 * cfg80211: wiphy allocation
13561 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +053013562 wiphy = wlan_hdd_cfg80211_wiphy_alloc(sizeof(hdd_context_t)) ;
Jeff Johnson295189b2012-06-20 16:38:30 -070013563
13564 if(wiphy == NULL)
13565 {
13566 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: cfg80211 init failed", __func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -080013567 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -070013568 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013569 pHddCtx = wiphy_priv(wiphy);
13570
Jeff Johnson295189b2012-06-20 16:38:30 -070013571 //Initialize the adapter context to zeros.
13572 vos_mem_zero(pHddCtx, sizeof( hdd_context_t ));
13573
Jeff Johnson295189b2012-06-20 16:38:30 -070013574 pHddCtx->wiphy = wiphy;
Sushant Kaushik83392fa2015-05-05 17:44:40 +053013575 hdd_prevent_suspend(WIFI_POWER_EVENT_WAKELOCK_DRIVER_INIT);
Mihir Shete18156292014-03-11 15:38:30 +053013576 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_LOAD_IN_PROGRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -070013577
13578 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, TRUE);
13579
Siddharth Bhalcd92b782015-06-29 12:25:40 +053013580 /* register for riva power on lock to platform driver
13581 * Locking power early to ensure FW doesn't reset by kernel while
13582 * host driver is busy initializing itself */
13583 if (req_riva_power_on_lock("wlan"))
13584 {
13585 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: req riva power on lock failed",
13586 __func__);
13587 goto err_free_hdd_context;
13588 }
13589
Jeff Johnson295189b2012-06-20 16:38:30 -070013590 /*Get vos context here bcoz vos_open requires it*/
13591 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
13592
Madan Mohan Koyyalamudi0b78e152012-11-28 15:46:51 -080013593 if(pVosContext == NULL)
13594 {
13595 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Failed vos_get_global_context",__func__);
13596 goto err_free_hdd_context;
13597 }
13598
Jeff Johnson295189b2012-06-20 16:38:30 -070013599 //Save the Global VOSS context in adapter context for future.
13600 pHddCtx->pvosContext = pVosContext;
13601
13602 //Save the adapter context in global context for future.
13603 ((VosContextType*)(pVosContext))->pHDDContext = (v_VOID_t*)pHddCtx;
13604
Jeff Johnson295189b2012-06-20 16:38:30 -070013605 pHddCtx->parent_dev = dev;
Sreelakshmi Konamkif0646d52016-12-09 12:35:31 +053013606 pHddCtx->last_scan_reject_session_id = 0xFF;
13607 pHddCtx->last_scan_reject_reason = 0;
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053013608 pHddCtx->last_scan_reject_timestamp = 0;
Abhishek Singhe4b12562017-06-20 16:53:39 +053013609 pHddCtx->scan_reject_cnt = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070013610
13611 init_completion(&pHddCtx->full_pwr_comp_var);
13612 init_completion(&pHddCtx->standby_comp_var);
13613 init_completion(&pHddCtx->req_bmps_comp_var);
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070013614 init_completion(&pHddCtx->scan_info.scan_req_completion_event);
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -080013615 init_completion(&pHddCtx->scan_info.abortscan_event_var);
Kiet Lam46b8e4e2013-11-06 21:49:53 +053013616 init_completion(&pHddCtx->wiphy_channel_update_event);
Arun Kumar Khandavallie0b046d2014-03-01 21:54:25 +053013617 init_completion(&pHddCtx->ssr_comp_var);
Mahesh A Saptasagar67ab9222015-10-21 15:38:41 +053013618 init_completion(&pHddCtx->mc_sus_event_var);
13619 init_completion(&pHddCtx->tx_sus_event_var);
13620 init_completion(&pHddCtx->rx_sus_event_var);
13621
Amar Singhala49cbc52013-10-08 18:37:44 -070013622
mukul sharma4bd8d2e2015-08-13 20:33:25 +053013623 hdd_init_ll_stats_ctx(pHddCtx);
Anurag Chouhan6ee81542017-02-09 18:09:27 +053013624 hdd_init_nud_stats_ctx(pHddCtx);
mukul sharma4bd8d2e2015-08-13 20:33:25 +053013625
Amar Singhala49cbc52013-10-08 18:37:44 -070013626#ifdef CONFIG_ENABLE_LINUX_REG
Amar Singhalfddc28c2013-09-05 13:03:40 -070013627 init_completion(&pHddCtx->linux_reg_req);
Amar Singhala49cbc52013-10-08 18:37:44 -070013628#else
13629 init_completion(&pHddCtx->driver_crda_req);
13630#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070013631
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +053013632#ifdef WLAN_FEATURE_EXTSCAN
13633 init_completion(&pHddCtx->ext_scan_context.response_event);
13634#endif /* WLAN_FEATURE_EXTSCAN */
13635
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053013636 spin_lock_init(&pHddCtx->schedScan_lock);
Kapil Gupta137ef892016-12-13 19:38:00 +053013637 vos_spin_lock_init(&pHddCtx->sap_update_info_lock);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053013638
Jeff Johnson295189b2012-06-20 16:38:30 -070013639 hdd_list_init( &pHddCtx->hddAdapters, MAX_NUMBER_OF_ADAPTERS );
13640
Padma, Santhosh Kumar9cd38332015-11-17 12:18:10 +053013641 vos_init_delayed_work(&pHddCtx->spoof_mac_addr_work,
13642 hdd_processSpoofMacAddrRequest);
Kapil Gupta137ef892016-12-13 19:38:00 +053013643 vos_init_work(&pHddCtx->sap_start_work, hdd_sap_restart_handle);
Abhishek Singh78c691f2017-11-30 13:48:44 +053013644 vos_init_delayed_work(&pHddCtx->ecsa_chan_change_work,
13645 hdd_force_scc_with_ecsa_handle);
Padma, Santhosh Kumar9cd38332015-11-17 12:18:10 +053013646
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053013647#ifdef FEATURE_WLAN_TDLS
13648 /* tdls_lock is initialized before an hdd_open_adapter ( which is
13649 * invoked by other instances also) to protect the concurrent
13650 * access for the Adapters by TDLS module.
13651 */
13652 mutex_init(&pHddCtx->tdls_lock);
13653#endif
Siddharth Bhal76972212014-10-15 16:22:51 +053013654 mutex_init(&pHddCtx->spoofMacAddr.macSpoofingLock);
Mukul Sharma1fd6efd2015-02-14 00:29:14 +053013655 mutex_init(&pHddCtx->wmmLock);
13656
Srinivas Girigowda8bf64cb2015-09-30 19:50:09 +053013657 hdd_init_offloaded_packets_ctx(pHddCtx);
Agarwal Ashish1f422872014-07-22 00:11:55 +053013658 /* By default Strict Regulatory For FCC should be false */
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053013659
Agarwal Ashish1f422872014-07-22 00:11:55 +053013660 pHddCtx->nEnableStrictRegulatoryForFCC = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070013661 // Load all config first as TL config is needed during vos_open
13662 pHddCtx->cfg_ini = (hdd_config_t*) kmalloc(sizeof(hdd_config_t), GFP_KERNEL);
13663 if(pHddCtx->cfg_ini == NULL)
13664 {
13665 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Failed kmalloc hdd_config_t",__func__);
13666 goto err_free_hdd_context;
13667 }
13668
Hanumanth Reddy Pothula1efcd162018-03-14 14:32:27 +053013669 hdd_request_manager_init();
13670
Jeff Johnson295189b2012-06-20 16:38:30 -070013671 vos_mem_zero(pHddCtx->cfg_ini, sizeof( hdd_config_t ));
13672
13673 // Read and parse the qcom_cfg.ini file
13674 status = hdd_parse_config_ini( pHddCtx );
13675 if ( VOS_STATUS_SUCCESS != status )
13676 {
13677 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: error parsing %s",
13678 __func__, WLAN_INI_FILE);
13679 goto err_config;
13680 }
Arif Hussaind5218912013-12-05 01:10:55 -080013681#ifdef MEMORY_DEBUG
13682 if (pHddCtx->cfg_ini->IsMemoryDebugSupportEnabled)
13683 vos_mem_init();
13684
13685 hddLog(VOS_TRACE_LEVEL_INFO, "%s: gEnableMemoryDebug=%d",
13686 __func__, pHddCtx->cfg_ini->IsMemoryDebugSupportEnabled);
13687#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070013688
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +053013689 /* INI has been read, initialise the configuredMcastBcastFilter with
13690 * INI value as this will serve as the default value
13691 */
13692 pHddCtx->configuredMcastBcastFilter = pHddCtx->cfg_ini->mcastBcastFilterSetting;
13693 hddLog(VOS_TRACE_LEVEL_INFO, "Setting configuredMcastBcastFilter: %d",
13694 pHddCtx->cfg_ini->mcastBcastFilterSetting);
Gopichand Nakkalafce506f2013-07-03 23:55:16 +053013695
13696 if (false == hdd_is_5g_supported(pHddCtx))
13697 {
13698 //5Ghz is not supported.
13699 if (1 != pHddCtx->cfg_ini->nBandCapability)
13700 {
13701 hddLog(VOS_TRACE_LEVEL_INFO,
13702 "%s: Setting pHddCtx->cfg_ini->nBandCapability = 1", __func__);
13703 pHddCtx->cfg_ini->nBandCapability = 1;
13704 }
13705 }
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053013706
13707 /* If SNR Monitoring is enabled, FW has to parse all beacons
13708 * for calcaluting and storing the average SNR, so set Nth beacon
13709 * filter to 1 to enable FW to parse all the beaocons
13710 */
13711 if (1 == pHddCtx->cfg_ini->fEnableSNRMonitoring)
13712 {
13713 /* The log level is deliberately set to WARN as overriding
13714 * nthBeaconFilter to 1 will increase power cosumption and this
13715 * might just prove helpful to detect the power issue.
13716 */
13717 hddLog(VOS_TRACE_LEVEL_WARN,
13718 "%s: Setting pHddCtx->cfg_ini->nthBeaconFilter = 1", __func__);
13719 pHddCtx->cfg_ini->nthBeaconFilter = 1;
13720 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013721 /*
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +053013722 * cfg80211: Initialization ...
Jeff Johnson295189b2012-06-20 16:38:30 -070013723 */
Manjeet Singh61016fa2016-12-02 11:10:19 +053013724 if (0 < wlan_hdd_cfg80211_init(dev, wiphy, pHddCtx->cfg_ini))
Jeff Johnson295189b2012-06-20 16:38:30 -070013725 {
Manjeet Singh61016fa2016-12-02 11:10:19 +053013726 hddLog(VOS_TRACE_LEVEL_FATAL,
13727 "%s: wlan_hdd_cfg80211_init return failure", __func__);
13728 goto err_config;
Jeff Johnson295189b2012-06-20 16:38:30 -070013729 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013730
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -080013731 // Update VOS trace levels based upon the cfg.ini
13732 hdd_vos_trace_enable(VOS_MODULE_ID_BAP,
13733 pHddCtx->cfg_ini->vosTraceEnableBAP);
13734 hdd_vos_trace_enable(VOS_MODULE_ID_TL,
13735 pHddCtx->cfg_ini->vosTraceEnableTL);
13736 hdd_vos_trace_enable(VOS_MODULE_ID_WDI,
13737 pHddCtx->cfg_ini->vosTraceEnableWDI);
13738 hdd_vos_trace_enable(VOS_MODULE_ID_HDD,
13739 pHddCtx->cfg_ini->vosTraceEnableHDD);
13740 hdd_vos_trace_enable(VOS_MODULE_ID_SME,
13741 pHddCtx->cfg_ini->vosTraceEnableSME);
13742 hdd_vos_trace_enable(VOS_MODULE_ID_PE,
13743 pHddCtx->cfg_ini->vosTraceEnablePE);
Katya Nigam70d68332013-09-16 16:49:45 +053013744 hdd_vos_trace_enable(VOS_MODULE_ID_PMC,
13745 pHddCtx->cfg_ini->vosTraceEnablePMC);
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -080013746 hdd_vos_trace_enable(VOS_MODULE_ID_WDA,
13747 pHddCtx->cfg_ini->vosTraceEnableWDA);
13748 hdd_vos_trace_enable(VOS_MODULE_ID_SYS,
13749 pHddCtx->cfg_ini->vosTraceEnableSYS);
13750 hdd_vos_trace_enable(VOS_MODULE_ID_VOSS,
13751 pHddCtx->cfg_ini->vosTraceEnableVOSS);
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -080013752 hdd_vos_trace_enable(VOS_MODULE_ID_SAP,
13753 pHddCtx->cfg_ini->vosTraceEnableSAP);
13754 hdd_vos_trace_enable(VOS_MODULE_ID_HDD_SOFTAP,
13755 pHddCtx->cfg_ini->vosTraceEnableHDDSAP);
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -080013756
Jeff Johnson295189b2012-06-20 16:38:30 -070013757 // Update WDI trace levels based upon the cfg.ini
13758 hdd_wdi_trace_enable(eWLAN_MODULE_DAL,
13759 pHddCtx->cfg_ini->wdiTraceEnableDAL);
13760 hdd_wdi_trace_enable(eWLAN_MODULE_DAL_CTRL,
13761 pHddCtx->cfg_ini->wdiTraceEnableCTL);
13762 hdd_wdi_trace_enable(eWLAN_MODULE_DAL_DATA,
13763 pHddCtx->cfg_ini->wdiTraceEnableDAT);
13764 hdd_wdi_trace_enable(eWLAN_MODULE_PAL,
13765 pHddCtx->cfg_ini->wdiTraceEnablePAL);
Jeff Johnson295189b2012-06-20 16:38:30 -070013766
Jeff Johnson88ba7742013-02-27 14:36:02 -080013767 if (VOS_FTM_MODE == hdd_get_conparam())
13768 {
Jeff Johnson295189b2012-06-20 16:38:30 -070013769 if ( VOS_STATUS_SUCCESS != wlan_hdd_ftm_open(pHddCtx) )
13770 {
13771 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: wlan_hdd_ftm_open Failed",__func__);
13772 goto err_free_hdd_context;
13773 }
13774 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: FTM driver loaded success fully",__func__);
Sachin Ahuja38ef5e02015-03-13 17:31:16 +053013775 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_NO_LOAD_UNLOAD_IN_PROGRESS;
c_hpothu2de0ef62014-04-15 16:16:15 +053013776 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, FALSE);
Jeff Johnson295189b2012-06-20 16:38:30 -070013777 return VOS_STATUS_SUCCESS;
Jeff Johnson88ba7742013-02-27 14:36:02 -080013778 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013779
Katya Nigame7b69a82015-04-28 15:24:06 +053013780 if( VOS_MONITOR_MODE == hdd_get_conparam())
13781 {
13782 if ( VOS_STATUS_SUCCESS != wlan_hdd_mon_open(pHddCtx))
13783 {
13784 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: wlan_hdd_mon_open Failed",__func__);
13785 goto err_free_hdd_context;
13786 }
13787 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Driver loaded in Monitor Mode",__func__);
13788 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_NO_LOAD_UNLOAD_IN_PROGRESS;
13789 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, FALSE);
13790 return VOS_STATUS_SUCCESS;
13791 }
13792
Jeff Johnson88ba7742013-02-27 14:36:02 -080013793 //Open watchdog module
Jeff Johnson295189b2012-06-20 16:38:30 -070013794 if(pHddCtx->cfg_ini->fIsLogpEnabled)
13795 {
13796 status = vos_watchdog_open(pVosContext,
13797 &((VosContextType*)pVosContext)->vosWatchdog, sizeof(VosWatchdogContext));
13798
13799 if(!VOS_IS_STATUS_SUCCESS( status ))
13800 {
13801 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: vos_watchdog_open failed",__func__);
Ashish Kumar Dhanotiya532bdef2017-05-09 17:31:59 +053013802 goto err_config;
Jeff Johnson295189b2012-06-20 16:38:30 -070013803 }
13804 }
13805
13806 pHddCtx->isLogpInProgress = FALSE;
13807 vos_set_logp_in_progress(VOS_MODULE_ID_VOSS, FALSE);
13808
Amar Singhala49cbc52013-10-08 18:37:44 -070013809#ifdef CONFIG_ENABLE_LINUX_REG
Amar Singhal0a402232013-10-11 20:57:16 -070013810 /* initialize the NV module. This is required so that
13811 we can initialize the channel information in wiphy
13812 from the NV.bin data. The channel information in
13813 wiphy needs to be initialized before wiphy registration */
13814
13815 status = vos_nv_open();
13816 if (!VOS_IS_STATUS_SUCCESS(status))
13817 {
13818 /* NV module cannot be initialized */
13819 hddLog( VOS_TRACE_LEVEL_FATAL,
13820 "%s: vos_nv_open failed", __func__);
Vinay Krishna Eranna2025d892014-09-18 16:51:42 +053013821 goto err_wdclose;
Amar Singhal0a402232013-10-11 20:57:16 -070013822 }
13823
13824 status = vos_init_wiphy_from_nv_bin();
13825 if (!VOS_IS_STATUS_SUCCESS(status))
13826 {
13827 /* NV module cannot be initialized */
13828 hddLog( VOS_TRACE_LEVEL_FATAL,
13829 "%s: vos_init_wiphy failed", __func__);
13830 goto err_vos_nv_close;
13831 }
13832
Amar Singhala49cbc52013-10-08 18:37:44 -070013833#endif
Mahesh A Saptasagarc3ed0122016-01-19 16:45:11 +053013834 //Initialize the nlink service
13835 if(nl_srv_init() != 0)
13836 {
13837 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: nl_srv_init failed", __func__);
13838 goto err_vos_nv_close;
13839 }
13840
13841#ifdef WLAN_KD_READY_NOTIFIER
13842 pHddCtx->kd_nl_init = 1;
13843#endif /* WLAN_KD_READY_NOTIFIER */
13844
Girish Gowlibf0e1ab2015-01-19 16:05:16 +053013845 vos_set_roam_delay_stats_enabled(pHddCtx->cfg_ini->gEnableRoamDelayStats);
Arun Kumar Khandavalliebb19482014-03-25 13:56:53 +053013846 status = vos_open( &pVosContext, pHddCtx->parent_dev);
Jeff Johnson295189b2012-06-20 16:38:30 -070013847 if ( !VOS_IS_STATUS_SUCCESS( status ))
13848 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -080013849 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: vos_open failed", __func__);
Mahesh A Saptasagarc3ed0122016-01-19 16:45:11 +053013850 goto err_nl_srv;
Jeff Johnson295189b2012-06-20 16:38:30 -070013851 }
13852
Jeff Johnson295189b2012-06-20 16:38:30 -070013853 pHddCtx->hHal = (tHalHandle)vos_get_context( VOS_MODULE_ID_SME, pVosContext );
13854
13855 if ( NULL == pHddCtx->hHal )
13856 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -080013857 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: HAL context is null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070013858 goto err_vosclose;
13859 }
13860
Jeff Johnsonbc676b42013-02-14 16:04:08 -080013861 status = vos_preStart( pHddCtx->pvosContext );
13862 if ( !VOS_IS_STATUS_SUCCESS( status ) )
13863 {
13864 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: vos_preStart failed", __func__);
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053013865 goto err_vosclose;
Jeff Johnsonbc676b42013-02-14 16:04:08 -080013866 }
Jeff Johnsone7245742012-09-05 17:12:55 -070013867
Arif Hussaineaf68602013-12-30 23:10:44 -080013868 if (0 == enable_dfs_chan_scan || 1 == enable_dfs_chan_scan)
13869 {
13870 pHddCtx->cfg_ini->enableDFSChnlScan = enable_dfs_chan_scan;
13871 hddLog(VOS_TRACE_LEVEL_INFO, "%s: module enable_dfs_chan_scan set to %d",
13872 __func__, enable_dfs_chan_scan);
13873 }
13874 if (0 == enable_11d || 1 == enable_11d)
13875 {
13876 pHddCtx->cfg_ini->Is11dSupportEnabled = enable_11d;
13877 hddLog(VOS_TRACE_LEVEL_INFO, "%s: module enable_11d set to %d",
13878 __func__, enable_11d);
13879 }
13880
Jeff Johnsonbc676b42013-02-14 16:04:08 -080013881 /* Note that the vos_preStart() sequence triggers the cfg download.
13882 The cfg download must occur before we update the SME config
13883 since the SME config operation must access the cfg database */
Jeff Johnson295189b2012-06-20 16:38:30 -070013884 status = hdd_set_sme_config( pHddCtx );
13885
13886 if ( VOS_STATUS_SUCCESS != status )
13887 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -080013888 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Failed hdd_set_sme_config", __func__);
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053013889 goto err_vosclose;
Jeff Johnsonbc676b42013-02-14 16:04:08 -080013890 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013891
Jeff Johnson295189b2012-06-20 16:38:30 -070013892 /* In the integrated architecture we update the configuration from
13893 the INI file and from NV before vOSS has been started so that
13894 the final contents are available to send down to the cCPU */
13895
13896 // Apply the cfg.ini to cfg.dat
13897 if (FALSE == hdd_update_config_dat(pHddCtx))
13898 {
13899 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: config update failed",__func__ );
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053013900 goto err_vosclose;
Jeff Johnson295189b2012-06-20 16:38:30 -070013901 }
13902
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +053013903 // Get mac addr from platform driver
13904 ret = wcnss_get_wlan_mac_address((char*)&mac_addr.bytes);
13905
13906 if ((0 == ret) && (!vos_is_macaddr_zero(&mac_addr)))
Jeff Johnson295189b2012-06-20 16:38:30 -070013907 {
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +053013908 /* Store the mac addr for first interface */
13909 pHddCtx->cfg_ini->intfMacAddr[0] = mac_addr;
13910
13911 hddLog(VOS_TRACE_LEVEL_ERROR,
13912 "%s: WLAN Mac Addr: "
13913 MAC_ADDRESS_STR, __func__,
13914 MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[0].bytes));
13915
13916 /* Here, passing Arg2 as 1 because we do not want to change the
13917 last 3 bytes (means non OUI bytes) of first interface mac
13918 addr.
13919 */
13920 if (0 != hdd_generate_iface_mac_addr_auto(pHddCtx, 1, mac_addr))
13921 {
13922 hddLog(VOS_TRACE_LEVEL_ERROR,
13923 "%s: Failed to generate wlan interface mac addr "
13924 "using MAC from ini file ", __func__);
13925 }
13926 }
13927 else if (VOS_STATUS_SUCCESS != hdd_update_config_from_nv(pHddCtx))
13928 {
13929 // Apply the NV to cfg.dat
13930 /* Prima Update MAC address only at here */
Jeff Johnson295189b2012-06-20 16:38:30 -070013931#ifdef WLAN_AUTOGEN_MACADDR_FEATURE
13932 /* There was not a valid set of MAC Addresses in NV. See if the
13933 default addresses were modified by the cfg.ini settings. If so,
13934 we'll use them, but if not, we'll autogenerate a set of MAC
13935 addresses based upon the device serial number */
13936
13937 static const v_MACADDR_t default_address =
13938 {{0x00, 0x0A, 0xF5, 0x89, 0x89, 0xFF}};
Jeff Johnson295189b2012-06-20 16:38:30 -070013939
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +053013940 if (0 == memcmp(&default_address, &pHddCtx->cfg_ini->intfMacAddr[0],
13941 sizeof(default_address)))
Jeff Johnson295189b2012-06-20 16:38:30 -070013942 {
13943 /* cfg.ini has the default address, invoke autogen logic */
13944
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +053013945 /* Here, passing Arg2 as 0 because we want to change the
13946 last 3 bytes (means non OUI bytes) of all the interfaces
13947 mac addr.
13948 */
13949 if (0 != hdd_generate_iface_mac_addr_auto(pHddCtx, 0,
13950 default_address))
Jeff Johnson295189b2012-06-20 16:38:30 -070013951 {
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +053013952 hddLog(VOS_TRACE_LEVEL_ERROR,
13953 "%s: Failed to generate wlan interface mac addr "
13954 "using MAC from ini file " MAC_ADDRESS_STR, __func__,
13955 MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[0].bytes));
Jeff Johnson295189b2012-06-20 16:38:30 -070013956 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013957 }
13958 else
13959#endif //WLAN_AUTOGEN_MACADDR_FEATURE
13960 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -080013961 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070013962 "%s: Invalid MAC address in NV, using MAC from ini file "
13963 MAC_ADDRESS_STR, __func__,
13964 MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[0].bytes));
13965 }
13966 }
13967 {
13968 eHalStatus halStatus;
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +053013969
13970 /* Set the MAC Address Currently this is used by HAL to
13971 * add self sta. Remove this once self sta is added as
13972 * part of session open.
13973 */
Jeff Johnson295189b2012-06-20 16:38:30 -070013974 halStatus = cfgSetStr( pHddCtx->hHal, WNI_CFG_STA_ID,
13975 (v_U8_t *)&pHddCtx->cfg_ini->intfMacAddr[0],
13976 sizeof( pHddCtx->cfg_ini->intfMacAddr[0]) );
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +053013977
Jeff Johnson295189b2012-06-20 16:38:30 -070013978 if (!HAL_STATUS_SUCCESS( halStatus ))
13979 {
13980 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Failed to set MAC Address. "
13981 "HALStatus is %08d [x%08x]",__func__, halStatus, halStatus );
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053013982 goto err_vosclose;
Jeff Johnson295189b2012-06-20 16:38:30 -070013983 }
13984 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013985
13986 /*Start VOSS which starts up the SME/MAC/HAL modules and everything else
13987 Note: Firmware image will be read and downloaded inside vos_start API */
13988 status = vos_start( pHddCtx->pvosContext );
13989 if ( !VOS_IS_STATUS_SUCCESS( status ) )
13990 {
13991 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: vos_start failed",__func__);
Hanumantha Reddy Pothulabd9601a2016-02-12 13:22:27 +053013992 if (isSsrPanicOnFailure())
13993 VOS_BUG(0);
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053013994 goto err_vosclose;
Jeff Johnson295189b2012-06-20 16:38:30 -070013995 }
13996
Leo Chang6cec3e22014-01-21 15:33:49 -080013997#ifdef FEATURE_WLAN_CH_AVOID
13998 /* Plug in avoid channel notification callback
13999 * This should happen before ADD_SELF_STA
14000 * FW will send first IND with ADD_SELF_STA REQ from host */
Pradeep Reddy POTTETI5c2e16d2014-06-27 16:47:38 +053014001
14002 /* check the Channel Avoidance is enabled */
14003 if (TRUE == pHddCtx->cfg_ini->fenableCHAvoidance)
14004 {
14005 sme_AddChAvoidCallback(pHddCtx->hHal,
14006 hdd_hostapd_ch_avoid_cb);
14007 }
Leo Chang6cec3e22014-01-21 15:33:49 -080014008#endif /* FEATURE_WLAN_CH_AVOID */
14009
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -070014010 /* Exchange capability info between Host and FW and also get versioning info from FW */
14011 hdd_exchange_version_and_caps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -070014012
Agarwal Ashishad9281b2014-06-10 14:57:30 +053014013#ifdef CONFIG_ENABLE_LINUX_REG
14014 status = wlan_hdd_init_channels(pHddCtx);
14015 if ( !VOS_IS_STATUS_SUCCESS( status ) )
14016 {
14017 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: wlan_hdd_init_channels failed",
14018 __func__);
14019 goto err_vosstop;
14020 }
14021#endif
14022
Jeff Johnson295189b2012-06-20 16:38:30 -070014023 status = hdd_post_voss_start_config( pHddCtx );
14024 if ( !VOS_IS_STATUS_SUCCESS( status ) )
14025 {
14026 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hdd_post_voss_start_config failed",
14027 __func__);
14028 goto err_vosstop;
14029 }
Amar Singhala49cbc52013-10-08 18:37:44 -070014030
Rajeev Kumar Sirasanagandla2bb30b82019-01-07 22:30:16 +053014031 wlan_hdd_cfg80211_scan_randomization_init(wiphy);
14032
Amar Singhala49cbc52013-10-08 18:37:44 -070014033#ifndef CONFIG_ENABLE_LINUX_REG
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +053014034 wlan_hdd_cfg80211_update_reg_info( wiphy );
14035
14036 /* registration of wiphy dev with cfg80211 */
14037 if (0 > wlan_hdd_cfg80211_register(wiphy))
14038 {
14039 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy register failed", __func__);
14040 goto err_vosstop;
14041 }
Amar Singhala49cbc52013-10-08 18:37:44 -070014042#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070014043
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053014044#ifdef CONFIG_ENABLE_LINUX_REG
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053014045 /* registration of wiphy dev with cfg80211 */
14046 if (0 > wlan_hdd_cfg80211_register(wiphy))
14047 {
14048 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy register failed", __func__);
14049 goto err_vosstop;
14050 }
14051
Agarwal Ashish6db9d532014-09-30 18:19:10 +053014052 status = wlan_hdd_init_channels_for_cc(pHddCtx, INIT);
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053014053 if ( !VOS_IS_STATUS_SUCCESS( status ) )
14054 {
14055 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: wlan_hdd_init_channels_for_cc failed",
14056 __func__);
14057 goto err_unregister_wiphy;
14058 }
14059#endif
14060
c_hpothu4a298be2014-12-22 21:12:51 +053014061 wcnss_wlan_set_drvdata(pHddCtx->parent_dev, pHddCtx);
14062
Rajeev Kumar Sirasanagandla4c068d42019-02-22 21:39:36 +053014063#ifdef SAP_AUTH_OFFLOAD
14064 if (!sme_IsFeatureSupportedByFW(SAP_OFFLOADS))
14065 {
14066 hddLog(VOS_TRACE_LEVEL_INFO, FL(" SAP AUTH OFFLOAD not supp by FW"));
14067 pHddCtx->cfg_ini->enable_sap_auth_offload = 0;
14068 }
14069#endif
14070
Jeff Johnson295189b2012-06-20 16:38:30 -070014071 if (VOS_STA_SAP_MODE == hdd_get_conparam())
14072 {
14073 pAdapter = hdd_open_adapter( pHddCtx, WLAN_HDD_SOFTAP, "softap.%d",
14074 wlan_hdd_get_intf_addr(pHddCtx), FALSE );
14075 }
14076 else
14077 {
Jeff Johnson295189b2012-06-20 16:38:30 -070014078 pAdapter = hdd_open_adapter( pHddCtx, WLAN_HDD_INFRA_STATION, "wlan%d",
14079 wlan_hdd_get_intf_addr(pHddCtx), FALSE );
14080 if (pAdapter != NULL)
14081 {
Katya Nigama7d81d72014-11-12 12:44:34 +053014082 if (pHddCtx->cfg_ini->isP2pDeviceAddrAdministrated && !(pHddCtx->cfg_ini->intfMacAddr[0].bytes[0] & 0x02))
Jeff Johnson295189b2012-06-20 16:38:30 -070014083 {
Gopichand Nakkala49f96f62013-02-06 14:38:17 +053014084 vos_mem_copy( pHddCtx->p2pDeviceAddress.bytes,
14085 pHddCtx->cfg_ini->intfMacAddr[0].bytes,
14086 sizeof(tSirMacAddr));
Madan Mohan Koyyalamudiedfc1b72012-10-18 20:25:55 -070014087
Gopichand Nakkala49f96f62013-02-06 14:38:17 +053014088 /* Generate the P2P Device Address. This consists of the device's
14089 * primary MAC address with the locally administered bit set.
14090 */
14091 pHddCtx->p2pDeviceAddress.bytes[0] |= 0x02;
Jeff Johnsone7245742012-09-05 17:12:55 -070014092 }
14093 else
14094 {
Gopichand Nakkala49f96f62013-02-06 14:38:17 +053014095 tANI_U8* p2p_dev_addr = wlan_hdd_get_intf_addr(pHddCtx);
14096 if (p2p_dev_addr != NULL)
14097 {
14098 vos_mem_copy(&pHddCtx->p2pDeviceAddress.bytes[0],
14099 p2p_dev_addr, VOS_MAC_ADDR_SIZE);
14100 }
14101 else
14102 {
14103 hddLog(VOS_TRACE_LEVEL_FATAL,
14104 "%s: Failed to allocate mac_address for p2p_device",
14105 __func__);
14106 goto err_close_adapter;
14107 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014108 }
Jeff Johnsone7245742012-09-05 17:12:55 -070014109
14110 pP2pAdapter = hdd_open_adapter( pHddCtx, WLAN_HDD_P2P_DEVICE, "p2p%d",
14111 &pHddCtx->p2pDeviceAddress.bytes[0], FALSE );
14112 if ( NULL == pP2pAdapter )
14113 {
14114 hddLog(VOS_TRACE_LEVEL_FATAL,
14115 "%s: Failed to do hdd_open_adapter for P2P Device Interface",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070014116 __func__);
Jeff Johnsone7245742012-09-05 17:12:55 -070014117 goto err_close_adapter;
14118 }
Jeff Johnsone7245742012-09-05 17:12:55 -070014119 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014120 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014121
14122 if( pAdapter == NULL )
14123 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -080014124 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: hdd_open_adapter failed", __func__);
14125 goto err_close_adapter;
Jeff Johnson295189b2012-06-20 16:38:30 -070014126 }
Jeff Johnsone7245742012-09-05 17:12:55 -070014127
Ashish Kumar Dhanotiya3ac85a22019-02-12 19:10:14 +053014128 if ((strlen(pHddCtx->cfg_ini->enabledefaultSAP) != 0) &&
14129 (strcmp(pHddCtx->cfg_ini->enabledefaultSAP, "") != 0)) {
Arunk Khandavalli95608be2019-01-22 13:12:54 +053014130 softapAdapter = hdd_open_adapter( pHddCtx, WLAN_HDD_SOFTAP,
14131 pHddCtx->cfg_ini->enabledefaultSAP,
14132 wlan_hdd_get_intf_addr(pHddCtx), FALSE);
14133 if (!softapAdapter) {
14134 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: hdd_open_adapter failed", __func__);
14135 goto err_close_adapter;
14136 }
14137 }
14138
Arif Hussain66559122013-11-21 10:11:40 -080014139 if (country_code)
14140 {
14141 eHalStatus ret;
Arif Hussaincb607082013-12-20 11:57:42 -080014142 INIT_COMPLETION(pAdapter->change_country_code);
Arif Hussain66559122013-11-21 10:11:40 -080014143 hdd_checkandupdate_dfssetting(pAdapter, country_code);
14144#ifndef CONFIG_ENABLE_LINUX_REG
14145 hdd_checkandupdate_phymode(pAdapter, country_code);
14146#endif
Arif Hussaineaf68602013-12-30 23:10:44 -080014147 ret = sme_ChangeCountryCode(pHddCtx->hHal,
14148 (void *)(tSmeChangeCountryCallback)
14149 wlan_hdd_change_country_code_callback,
Arif Hussain66559122013-11-21 10:11:40 -080014150 country_code,
14151 pAdapter, pHddCtx->pvosContext,
Abhishek Singha306a442013-11-07 18:39:01 +053014152 eSIR_TRUE, eSIR_TRUE);
Arif Hussain66559122013-11-21 10:11:40 -080014153 if (eHAL_STATUS_SUCCESS == ret)
14154 {
Arif Hussaincb607082013-12-20 11:57:42 -080014155 ret = wait_for_completion_interruptible_timeout(
14156 &pAdapter->change_country_code,
14157 msecs_to_jiffies(WLAN_WAIT_TIME_COUNTRY));
14158
14159 if (0 >= ret)
14160 {
14161 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
14162 "%s: SME while setting country code timed out", __func__);
14163 }
Arif Hussain66559122013-11-21 10:11:40 -080014164 }
14165 else
14166 {
Arif Hussaincb607082013-12-20 11:57:42 -080014167 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
14168 "%s: SME Change Country code from module param fail ret=%d",
14169 __func__, ret);
Arif Hussain66559122013-11-21 10:11:40 -080014170 }
14171 }
14172
Jeff Johnson295189b2012-06-20 16:38:30 -070014173#ifdef WLAN_BTAMP_FEATURE
14174 vStatus = WLANBAP_Open(pVosContext);
14175 if(!VOS_IS_STATUS_SUCCESS(vStatus))
14176 {
14177 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
14178 "%s: Failed to open BAP",__func__);
Jeff Johnsone7245742012-09-05 17:12:55 -070014179 goto err_close_adapter;
Jeff Johnson295189b2012-06-20 16:38:30 -070014180 }
14181
14182 vStatus = BSL_Init(pVosContext);
14183 if(!VOS_IS_STATUS_SUCCESS(vStatus))
14184 {
14185 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
14186 "%s: Failed to Init BSL",__func__);
14187 goto err_bap_close;
14188 }
14189 vStatus = WLANBAP_Start(pVosContext);
14190 if (!VOS_IS_STATUS_SUCCESS(vStatus))
14191 {
14192 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
14193 "%s: Failed to start TL",__func__);
14194 goto err_bap_close;
14195 }
14196
14197 pConfig = pHddCtx->cfg_ini;
14198 btAmpConfig.ucPreferredChannel = pConfig->preferredChannel;
14199 status = WLANBAP_SetConfig(&btAmpConfig);
14200
14201#endif //WLAN_BTAMP_FEATURE
Jeff Johnsone7245742012-09-05 17:12:55 -070014202
Mihir Shete9c238772014-10-15 14:35:16 +053014203 /*
14204 * UapsdMask is 0xf if U-APSD is enbaled for all AC's...
14205 * The value of CFG_QOS_WMM_UAPSD_MASK_DEFAULT is 0xaa(Magic Value)
14206 * which is greater than 0xf. So the below check is safe to make
14207 * sure that there is no entry for UapsdMask in the ini
14208 */
14209 if (CFG_QOS_WMM_UAPSD_MASK_DEFAULT == pHddCtx->cfg_ini->UapsdMask)
14210 {
14211 if(IS_DYNAMIC_WMM_PS_ENABLED)
14212 {
14213 hddLog(VOS_TRACE_LEVEL_DEBUG,"%s: Enable UAPSD for VI & VO",
14214 __func__);
14215 pHddCtx->cfg_ini->UapsdMask =
14216 CFG_QOS_WMM_UAPSD_MASK_DYMANIC_WMM_PS_DEFAULT;
14217 }
14218 else
14219 {
14220 hddLog(VOS_TRACE_LEVEL_DEBUG,"%s: Do not enable UAPSD",
14221 __func__);
14222 pHddCtx->cfg_ini->UapsdMask =
14223 CFG_QOS_WMM_UAPSD_MASK_LEGACY_WMM_PS_DEFAULT;
14224 }
14225 }
14226
Varun Reddy Yeturud0a3f252013-04-15 21:58:13 -070014227#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
14228 if(!(IS_ROAM_SCAN_OFFLOAD_FEATURE_ENABLE))
14229 {
14230 hddLog(VOS_TRACE_LEVEL_DEBUG,"%s: ROAM_SCAN_OFFLOAD Feature not supported",__func__);
14231 pHddCtx->cfg_ini->isRoamOffloadScanEnabled = 0;
14232 sme_UpdateRoamScanOffloadEnabled((tHalHandle)(pHddCtx->hHal),
14233 pHddCtx->cfg_ini->isRoamOffloadScanEnabled);
14234 }
14235#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070014236
Agarwal Ashish4b87f922014-06-18 03:03:21 +053014237 wlan_hdd_tdls_init(pHddCtx);
14238
Masti, Narayanraddi26378462016-01-05 18:20:28 +053014239 wlan_hdd_init_deinit_defer_scan_context(&pHddCtx->scan_ctxt);
14240
14241 vos_init_delayed_work(&pHddCtx->scan_ctxt.scan_work,
14242 wlan_hdd_schedule_defer_scan);
14243
Mihir Shetefc7ff5b2014-01-27 11:30:05 +053014244 sme_Register11dScanDoneCallback(pHddCtx->hHal, hdd_11d_scan_done);
14245
Jeff Johnson295189b2012-06-20 16:38:30 -070014246 /* Register with platform driver as client for Suspend/Resume */
14247 status = hddRegisterPmOps(pHddCtx);
14248 if ( !VOS_IS_STATUS_SUCCESS( status ) )
14249 {
14250 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddRegisterPmOps failed",__func__);
14251#ifdef WLAN_BTAMP_FEATURE
14252 goto err_bap_stop;
14253#else
Jeff Johnsone7245742012-09-05 17:12:55 -070014254 goto err_close_adapter;
Jeff Johnson295189b2012-06-20 16:38:30 -070014255#endif //WLAN_BTAMP_FEATURE
14256 }
14257
Yue Ma0d4891e2013-08-06 17:01:45 -070014258 /* Open debugfs interface */
14259 if (VOS_STATUS_SUCCESS != hdd_debugfs_init(pAdapter))
14260 {
14261 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
14262 "%s: hdd_debugfs_init failed!", __func__);
Yue Ma0d4891e2013-08-06 17:01:45 -070014263 }
14264
Jeff Johnson295189b2012-06-20 16:38:30 -070014265 /* Register TM level change handler function to the platform */
14266 status = hddDevTmRegisterNotifyCallback(pHddCtx);
14267 if ( !VOS_IS_STATUS_SUCCESS( status ) )
14268 {
14269 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddDevTmRegisterNotifyCallback failed",__func__);
14270 goto err_unregister_pmops;
14271 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014272
Jeff Johnson295189b2012-06-20 16:38:30 -070014273 // register net device notifier for device change notification
14274 ret = register_netdevice_notifier(&hdd_netdev_notifier);
14275
14276 if(ret < 0)
14277 {
14278 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: register_netdevice_notifier failed",__func__);
Siddharth Bhalcd92b782015-06-29 12:25:40 +053014279 goto err_unregister_pmops;
Jeff Johnson295189b2012-06-20 16:38:30 -070014280 }
14281
Jeff Johnson295189b2012-06-20 16:38:30 -070014282 //Initialize the BTC service
14283 if(btc_activate_service(pHddCtx) != 0)
14284 {
14285 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: btc_activate_service failed",__func__);
Mahesh A Saptasagarc3ed0122016-01-19 16:45:11 +053014286 goto err_reg_netdev;
Jeff Johnson295189b2012-06-20 16:38:30 -070014287 }
14288
Padma, Santhosh Kumar2762e9d2015-10-20 15:02:57 +053014289#ifdef FEATURE_OEM_DATA_SUPPORT
14290 //Initialize the OEM service
14291 if (oem_activate_service(pHddCtx) != 0)
14292 {
14293 hddLog(VOS_TRACE_LEVEL_FATAL,
14294 "%s: oem_activate_service failed", __func__);
Hanumanth Reddy Pothula13789c42017-09-12 15:18:13 +053014295 goto err_btc_activate_service;
Padma, Santhosh Kumar2762e9d2015-10-20 15:02:57 +053014296 }
14297#endif
14298
Jeff Johnson295189b2012-06-20 16:38:30 -070014299#ifdef PTT_SOCK_SVC_ENABLE
14300 //Initialize the PTT service
14301 if(ptt_sock_activate_svc(pHddCtx) != 0)
14302 {
14303 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: ptt_sock_activate_svc failed",__func__);
Hanumanth Reddy Pothula13789c42017-09-12 15:18:13 +053014304 goto err_oem_activate_service;
Jeff Johnson295189b2012-06-20 16:38:30 -070014305 }
14306#endif
14307
Abhishek Singh00b71972016-01-07 10:51:04 +053014308#ifdef WLAN_FEATURE_RMC
14309 if (hdd_open_cesium_nl_sock() < 0)
14310 {
14311 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hdd_open_cesium_nl_sock failed", __func__);
Hanumanth Reddy Pothula13789c42017-09-12 15:18:13 +053014312 goto err_ptt_sock_activate_svc;
Abhishek Singh00b71972016-01-07 10:51:04 +053014313 }
14314#endif
14315
Vinay Krishna Erannad938c422014-03-10 17:14:21 +053014316#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
14317 if(pHddCtx->cfg_ini && pHddCtx->cfg_ini->wlanLoggingEnable)
14318 {
Deepthi Gowri78083a32014-11-04 12:55:51 +053014319 if(wlan_logging_sock_activate_svc(
14320 pHddCtx->cfg_ini->wlanLoggingFEToConsole,
Sushant Kaushik33200572015-08-05 16:46:20 +053014321 pHddCtx->cfg_ini->wlanLoggingNumBuf,
14322 pHddCtx->cfg_ini->wlanPerPktStatsLogEnable,
14323 pHddCtx->cfg_ini->wlanPerPktStatsNumBuf))
Deepthi Gowri78083a32014-11-04 12:55:51 +053014324 {
14325 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wlan_logging_sock_activate_svc"
14326 " failed", __func__);
Hanumanth Reddy Pothula13789c42017-09-12 15:18:13 +053014327 goto err_open_cesium_nl_sock;
Deepthi Gowri78083a32014-11-04 12:55:51 +053014328 }
14329 //TODO: To Remove enableDhcpDebug and use gEnableDebugLog for
14330 //EAPOL and DHCP
Sachin Ahuja8c65f382014-12-12 15:34:21 +053014331 if (!pHddCtx->cfg_ini->gEnableDebugLog)
14332 pHddCtx->cfg_ini->gEnableDebugLog =
Sushant Kaushik6e4e2bc2015-10-05 17:23:07 +053014333 VOS_PKT_PROTO_TYPE_EAPOL | VOS_PKT_PROTO_TYPE_DHCP |
14334 VOS_PKT_PROTO_TYPE_ARP;
Vinay Krishna Erannad938c422014-03-10 17:14:21 +053014335 }
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053014336
Siddharth Bhald1be97f2015-05-27 22:39:59 +053014337 if (pHddCtx->cfg_ini->wlanLoggingEnable &&
14338 (pHddCtx->cfg_ini->enableFWLogging ||
Siddharth Bhaldb963232015-06-25 19:34:35 +053014339 pHddCtx->cfg_ini->enableMgmtLogging ||
sheenam monga1a0202d2020-01-03 15:20:57 +053014340 pHddCtx->cfg_ini->enableContFWLogging))
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053014341 {
Siddharth Bhald1be97f2015-05-27 22:39:59 +053014342 hdd_init_frame_logging(pHddCtx);
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053014343 }
14344 else
14345 {
Siddharth Bhald1be97f2015-05-27 22:39:59 +053014346 hddLog(VOS_TRACE_LEVEL_INFO, FL("Logging disabled in ini"));
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053014347 }
14348
Vinay Krishna Erannad938c422014-03-10 17:14:21 +053014349#endif
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053014350
Sushant Kaushik215778f2015-05-21 14:05:36 +053014351 if (vos_is_multicast_logging())
14352 wlan_logging_set_log_level();
14353
Jeff Johnson295189b2012-06-20 16:38:30 -070014354 hdd_register_mcast_bcast_filter(pHddCtx);
Bala Venkateshe65810a2019-02-18 20:32:36 +053014355
Jeff Johnson295189b2012-06-20 16:38:30 -070014356 mutex_init(&pHddCtx->sap_lock);
Mahesh A Saptasagar60627942014-10-13 13:55:14 +053014357 mutex_init(&pHddCtx->roc_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -070014358
Jeff Johnsone7245742012-09-05 17:12:55 -070014359#ifdef WLAN_FEATURE_HOLD_RX_WAKELOCK
14360 /* Initialize the wake lcok */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053014361 vos_wake_lock_init(&pHddCtx->rx_wake_lock,
Jeff Johnsone7245742012-09-05 17:12:55 -070014362 "qcom_rx_wakelock");
Sushant Kaushik83392fa2015-05-05 17:44:40 +053014363
Jeff Johnsone7245742012-09-05 17:12:55 -070014364#endif
Madan Mohan Koyyalamudi69fc3ad2012-11-28 16:04:56 -080014365 /* Initialize the wake lcok */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053014366 vos_wake_lock_init(&pHddCtx->sap_wake_lock,
Madan Mohan Koyyalamudi69fc3ad2012-11-28 16:04:56 -080014367 "qcom_sap_wakelock");
Sushant Kaushik83392fa2015-05-05 17:44:40 +053014368
Jeff Johnsone7245742012-09-05 17:12:55 -070014369
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070014370 vos_event_init(&pHddCtx->scan_info.scan_finished_event);
14371 pHddCtx->scan_info.scan_pending_option = WEXT_SCAN_PENDING_GIVEUP;
Jeff Johnson295189b2012-06-20 16:38:30 -070014372
Katya Nigam5c306ea2014-06-19 15:39:54 +053014373 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_NO_LOAD_UNLOAD_IN_PROGRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -070014374 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, FALSE);
Sushant Kaushik83392fa2015-05-05 17:44:40 +053014375 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_DRIVER_INIT);
Katya Nigam5c306ea2014-06-19 15:39:54 +053014376
14377#ifdef FEATURE_WLAN_SCAN_PNO
14378 /*SME must send channel update configuration to RIVA*/
14379 sme_UpdateChannelConfig(pHddCtx->hHal);
14380#endif
Abhishek Singhf644b272014-08-21 02:59:39 +053014381 /* Send the update default channel list to the FW*/
14382 sme_UpdateChannelList(pHddCtx->hHal);
Mukul Sharma45063942015-04-01 20:07:59 +053014383
14384 /* Fwr capabilities received, Set the Dot11 mode */
Abhishek Singh41ebce12016-02-03 10:43:21 +053014385 sme_SetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter),
14386 hdd_cfg_xlate_to_csr_phy_mode(pHddCtx->cfg_ini->dot11Mode));
Mukul Sharma45063942015-04-01 20:07:59 +053014387 sme_SetDefDot11Mode(pHddCtx->hHal);
14388
Abhishek Singha306a442013-11-07 18:39:01 +053014389#ifndef CONFIG_ENABLE_LINUX_REG
14390 /*updating wiphy so that regulatory user hints can be processed*/
14391 if (wiphy)
14392 {
14393 regulatory_hint(wiphy, "00");
14394 }
14395#endif
Jeff Johnsone7245742012-09-05 17:12:55 -070014396 // Initialize the restart logic
14397 wlan_hdd_restart_init(pHddCtx);
Chilam NG571c65a2013-01-19 12:27:36 +053014398
Hanumanth Reddy Pothula146bca42016-11-08 12:01:07 +053014399 if (pHddCtx->cfg_ini->fIsLogpEnabled) {
14400 vos_wdthread_init_timer_work(vos_process_wd_timer);
14401 /* Initialize the timer to detect thread stuck issues */
14402 vos_thread_stuck_timer_init(
14403 &((VosContextType*)pVosContext)->vosWatchdog);
14404 }
14405
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -070014406 //Register the traffic monitor timer now
14407 if ( pHddCtx->cfg_ini->dynSplitscan)
14408 {
14409 vos_timer_init(&pHddCtx->tx_rx_trafficTmr,
14410 VOS_TIMER_TYPE_SW,
14411 hdd_tx_rx_pkt_cnt_stat_timer_handler,
14412 (void *)pHddCtx);
14413 }
Srinivas Dasari030bad32015-02-18 23:23:54 +053014414 wlan_hdd_cfg80211_nan_init(pHddCtx);
14415
Bhargav Shahd0715912015-10-01 18:17:37 +053014416 mutex_init(&pHddCtx->cur_rx_level_lock);
14417 vos_timer_init(&pHddCtx->delack_timer, VOS_TIMER_TYPE_SW,
14418 hdd_tcp_delack_compute_function,(void *)pHddCtx);
Masti, Narayanraddi44b0db02015-12-22 11:54:35 +053014419 vos_timer_init(&pHddCtx->tdls_source_timer, VOS_TIMER_TYPE_SW,
14420 wlan_hdd_change_tdls_mode, (void *)pHddCtx);
Bhargav Shahd0715912015-10-01 18:17:37 +053014421
Dino Mycle6fb96c12014-06-10 11:52:40 +053014422#ifdef WLAN_FEATURE_EXTSCAN
14423 sme_EXTScanRegisterCallback(pHddCtx->hHal,
14424 wlan_hdd_cfg80211_extscan_callback,
14425 pHddCtx);
14426#endif /* WLAN_FEATURE_EXTSCAN */
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +053014427
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053014428#ifdef FEATURE_OEM_DATA_SUPPORT
14429 sme_OemDataRegisterCallback(pHddCtx->hHal,
14430 wlan_hdd_cfg80211_oemdata_callback,
14431 pHddCtx);
14432#endif /* FEATURE_OEM_DATA_SUPPORT */
14433
Gupta, Kapil7c34b322015-09-30 13:12:35 +053014434 sme_set_rssi_threshold_breached_cb(pHddCtx->hHal, hdd_rssi_threshold_breached_cb);
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +053014435#ifdef WLAN_NS_OFFLOAD
14436 // Register IPv6 notifier to notify if any change in IP
14437 // So that we can reconfigure the offload parameters
14438 pHddCtx->ipv6_notifier.notifier_call = wlan_hdd_ipv6_changed;
14439 ret = register_inet6addr_notifier(&pHddCtx->ipv6_notifier);
14440 if (ret)
14441 {
Ratheesh S P36dbc932015-08-07 14:28:57 +053014442 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to register IPv6 notifier"));
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +053014443 }
14444 else
14445 {
Ratheesh S P36dbc932015-08-07 14:28:57 +053014446 hddLog(VOS_TRACE_LEVEL_INFO, FL("Registered IPv6 notifier"));
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +053014447 }
14448#endif
14449
Sravan Kumar Kairamb0edc612016-10-26 13:55:24 +053014450 vos_mem_set((uint8_t *)&pHddCtx->bad_sta, HDD_MAX_STA_COUNT, 0);
14451
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +053014452 // Register IPv4 notifier to notify if any change in IP
14453 // So that we can reconfigure the offload parameters
14454 pHddCtx->ipv4_notifier.notifier_call = wlan_hdd_ipv4_changed;
14455 ret = register_inetaddr_notifier(&pHddCtx->ipv4_notifier);
14456 if (ret)
14457 {
Ratheesh S P36dbc932015-08-07 14:28:57 +053014458 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to register IPv4 notifier"));
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +053014459 }
14460 else
14461 {
Ratheesh S P36dbc932015-08-07 14:28:57 +053014462 hddLog(VOS_TRACE_LEVEL_INFO, FL("Registered IPv4 notifier"));
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +053014463 }
Bhargav shah23c94942015-10-13 12:48:35 +053014464 hdd_dp_util_send_rps_ind(pHddCtx);
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +053014465
Nishank Aggarwalc11826c2016-12-15 18:54:10 +053014466 pHddCtx->is_ap_mode_wow_supported =
14467 sme_IsFeatureSupportedByFW(SAP_MODE_WOW);
Sravan Kumar Kairam091e5b62017-01-23 14:14:20 +053014468
Hanumanth Reddy Pothulae92bcc12017-05-19 13:56:35 +053014469 pHddCtx->is_fatal_event_log_sup =
14470 sme_IsFeatureSupportedByFW(FATAL_EVENT_LOGGING);
14471 hddLog(VOS_TRACE_LEVEL_INFO, FL("FATAL_EVENT_LOGGING: %d"),
14472 pHddCtx->is_fatal_event_log_sup);
14473
Sravan Kumar Kairam091e5b62017-01-23 14:14:20 +053014474 hdd_assoc_registerFwdEapolCB(pVosContext);
14475
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +053014476 mutex_init(&pHddCtx->cache_channel_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -070014477 goto success;
14478
Hanumanth Reddy Pothula13789c42017-09-12 15:18:13 +053014479err_open_cesium_nl_sock:
14480#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
14481 hdd_close_cesium_nl_sock();
14482#endif
14483
14484err_ptt_sock_activate_svc:
14485#ifdef PTT_SOCK_SVC_ENABLE
14486 ptt_sock_deactivate_svc(pHddCtx);
14487#endif
14488
14489err_oem_activate_service:
14490#ifdef FEATURE_OEM_DATA_SUPPORT
14491 oem_deactivate_service();
14492#endif
14493
14494err_btc_activate_service:
14495 btc_deactivate_service();
14496
Jeff Johnson295189b2012-06-20 16:38:30 -070014497err_reg_netdev:
14498 unregister_netdevice_notifier(&hdd_netdev_notifier);
14499
Jeff Johnson295189b2012-06-20 16:38:30 -070014500err_unregister_pmops:
14501 hddDevTmUnregisterNotifyCallback(pHddCtx);
14502 hddDeregisterPmOps(pHddCtx);
14503
Yue Ma0d4891e2013-08-06 17:01:45 -070014504 hdd_debugfs_exit(pHddCtx);
14505
Jeff Johnson295189b2012-06-20 16:38:30 -070014506#ifdef WLAN_BTAMP_FEATURE
14507err_bap_stop:
14508 WLANBAP_Stop(pVosContext);
14509#endif
14510
14511#ifdef WLAN_BTAMP_FEATURE
14512err_bap_close:
14513 WLANBAP_Close(pVosContext);
14514#endif
14515
Jeff Johnson295189b2012-06-20 16:38:30 -070014516err_close_adapter:
14517 hdd_close_all_adapters( pHddCtx );
Mahesh A Saptasagar9ecefe42014-07-15 18:43:49 +053014518#ifdef CONFIG_ENABLE_LINUX_REG
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053014519err_unregister_wiphy:
Mahesh A Saptasagar9ecefe42014-07-15 18:43:49 +053014520#endif
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +053014521 wiphy_unregister(wiphy) ;
Agrawal Ashish33ec71e2015-11-26 20:20:58 +053014522 hdd_wlan_free_wiphy_channels(wiphy);
14523
Jeff Johnson295189b2012-06-20 16:38:30 -070014524err_vosstop:
14525 vos_stop(pVosContext);
14526
Amar Singhala49cbc52013-10-08 18:37:44 -070014527err_vosclose:
Jeff Johnson295189b2012-06-20 16:38:30 -070014528 status = vos_sched_close( pVosContext );
14529 if (!VOS_IS_STATUS_SUCCESS(status)) {
14530 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
14531 "%s: Failed to close VOSS Scheduler", __func__);
14532 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( status ) );
14533 }
Amar Singhala49cbc52013-10-08 18:37:44 -070014534 vos_close(pVosContext );
14535
Mahesh A Saptasagarc3ed0122016-01-19 16:45:11 +053014536err_nl_srv:
14537#ifdef WLAN_KD_READY_NOTIFIER
14538 nl_srv_exit(pHddCtx->ptt_pid);
14539#else
14540 nl_srv_exit();
14541#endif /* WLAN_KD_READY_NOTIFIER */
Amar Singhal0a402232013-10-11 20:57:16 -070014542err_vos_nv_close:
14543
c_hpothue6a36282014-03-19 12:27:38 +053014544#ifdef CONFIG_ENABLE_LINUX_REG
Amar Singhal0a402232013-10-11 20:57:16 -070014545 vos_nv_close();
14546
c_hpothu70f8d812014-03-22 22:59:23 +053014547#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070014548
14549err_wdclose:
14550 if(pHddCtx->cfg_ini->fIsLogpEnabled)
14551 vos_watchdog_close(pVosContext);
14552
Jeff Johnson295189b2012-06-20 16:38:30 -070014553err_config:
Hanumanth Reddy Pothula1efcd162018-03-14 14:32:27 +053014554 hdd_request_manager_deinit();
Jeff Johnson295189b2012-06-20 16:38:30 -070014555 kfree(pHddCtx->cfg_ini);
14556 pHddCtx->cfg_ini= NULL;
14557
14558err_free_hdd_context:
Sushant Kaushik83392fa2015-05-05 17:44:40 +053014559 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_DRIVER_INIT);
Siddharth Bhalcd92b782015-06-29 12:25:40 +053014560 free_riva_power_on_lock("wlan");
Jeff Johnson295189b2012-06-20 16:38:30 -070014561 wiphy_free(wiphy) ;
14562 //kfree(wdev) ;
Jeff Johnson295189b2012-06-20 16:38:30 -070014563 VOS_BUG(1);
14564
Madan Mohan Koyyalamudid57ae632012-11-06 18:42:48 -080014565 if (hdd_is_ssr_required())
14566 {
14567 /* WDI timeout had happened during load, so SSR is needed here */
14568 subsystem_restart("wcnss");
14569 msleep(5000);
14570 }
14571 hdd_set_ssr_required (VOS_FALSE);
14572
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -080014573 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -070014574
14575success:
14576 EXIT();
14577 return 0;
14578}
14579
14580/**---------------------------------------------------------------------------
14581
Jeff Johnson32d95a32012-09-10 13:15:23 -070014582 \brief hdd_driver_init() - Core Driver Init Function
Jeff Johnson295189b2012-06-20 16:38:30 -070014583
Jeff Johnson32d95a32012-09-10 13:15:23 -070014584 This is the driver entry point - called in different timeline depending
14585 on whether the driver is statically or dynamically linked
Jeff Johnson295189b2012-06-20 16:38:30 -070014586
14587 \param - None
14588
14589 \return - 0 for success, non zero for failure
14590
14591 --------------------------------------------------------------------------*/
Jeff Johnson32d95a32012-09-10 13:15:23 -070014592static int hdd_driver_init( void)
Jeff Johnson295189b2012-06-20 16:38:30 -070014593{
14594 VOS_STATUS status;
14595 v_CONTEXT_t pVosContext = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070014596 struct device *dev = NULL;
14597 int ret_status = 0;
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -070014598#ifdef HAVE_WCNSS_CAL_DOWNLOAD
14599 int max_retries = 0;
14600#endif
Siddharth Bhalc7e79b62014-10-10 22:37:38 +053014601#ifdef HAVE_CBC_DONE
14602 int max_cbc_retries = 0;
14603#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070014604
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +053014605#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
14606 wlan_logging_sock_init_svc();
14607#endif
14608
Jeff Johnson295189b2012-06-20 16:38:30 -070014609 ENTER();
14610
Sushant Kaushik83392fa2015-05-05 17:44:40 +053014611 vos_wake_lock_init(&wlan_wake_lock, "wlan");
Jeff Johnson295189b2012-06-20 16:38:30 -070014612
14613 pr_info("%s: loading driver v%s\n", WLAN_MODULE_NAME,
14614 QWLAN_VERSIONSTR TIMER_MANAGER_STR MEMORY_DEBUG_STR);
14615
Jeff Johnson295189b2012-06-20 16:38:30 -070014616#ifdef ANI_BUS_TYPE_PCI
14617
14618 dev = wcnss_wlan_get_device();
14619
14620#endif // ANI_BUS_TYPE_PCI
14621
14622#ifdef ANI_BUS_TYPE_PLATFORM
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -070014623
14624#ifdef HAVE_WCNSS_CAL_DOWNLOAD
14625 /* wait until WCNSS driver downloads NV */
Ravi Kumar Bokka7a139e62016-11-17 21:32:55 +053014626 while (!wcnss_device_ready() && 10 >= ++max_retries) {
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -070014627 msleep(1000);
14628 }
Siddharth Bhalc7e79b62014-10-10 22:37:38 +053014629
Ravi Kumar Bokka7a139e62016-11-17 21:32:55 +053014630 if (max_retries >= 10) {
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -070014631 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: WCNSS driver not ready", __func__);
Sushant Kaushik83392fa2015-05-05 17:44:40 +053014632 vos_wake_lock_destroy(&wlan_wake_lock);
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +053014633#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
14634 wlan_logging_sock_deinit_svc();
14635#endif
14636
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -070014637 return -ENODEV;
14638 }
14639#endif
14640
Siddharth Bhalc7e79b62014-10-10 22:37:38 +053014641#ifdef HAVE_CBC_DONE
14642 while (!wcnss_cbc_complete() && 10 >= ++max_cbc_retries) {
14643 msleep(1000);
14644 }
14645 if (max_cbc_retries >= 10) {
14646 hddLog(VOS_TRACE_LEVEL_FATAL, "%s:CBC not completed", __func__);
14647 }
14648#endif
14649
Jeff Johnson295189b2012-06-20 16:38:30 -070014650 dev = wcnss_wlan_get_device();
14651#endif // ANI_BUS_TYPE_PLATFORM
14652
14653
14654 do {
14655 if (NULL == dev) {
14656 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: WLAN device not found!!",__func__);
14657 ret_status = -1;
14658 break;
14659 }
14660
Jeff Johnson295189b2012-06-20 16:38:30 -070014661#ifdef TIMER_MANAGER
14662 vos_timer_manager_init();
14663#endif
14664
14665 /* Preopen VOSS so that it is ready to start at least SAL */
14666 status = vos_preOpen(&pVosContext);
14667
14668 if (!VOS_IS_STATUS_SUCCESS(status))
14669 {
14670 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Failed to preOpen VOSS", __func__);
14671 ret_status = -1;
14672 break;
14673 }
14674
Sushant Kaushik02beb352015-06-04 15:15:01 +053014675 hddTraceInit();
Padma, Santhosh Kumar9093b202015-07-21 15:37:38 +053014676 hdd_register_debug_callback();
14677
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070014678#ifndef MODULE
14679 /* For statically linked driver, call hdd_set_conparam to update curr_con_mode
14680 */
14681 hdd_set_conparam((v_UINT_t)con_mode);
14682#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070014683
14684 // Call our main init function
Jeff Johnsonbc676b42013-02-14 16:04:08 -080014685 if (hdd_wlan_startup(dev))
14686 {
Jeff Johnson295189b2012-06-20 16:38:30 -070014687 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: WLAN Driver Initialization failed",
Jeff Johnsonbc676b42013-02-14 16:04:08 -080014688 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070014689 vos_preClose( &pVosContext );
14690 ret_status = -1;
14691 break;
14692 }
14693
Jeff Johnson295189b2012-06-20 16:38:30 -070014694 } while (0);
14695
14696 if (0 != ret_status)
14697 {
Jeff Johnson295189b2012-06-20 16:38:30 -070014698#ifdef TIMER_MANAGER
14699 vos_timer_exit();
14700#endif
14701#ifdef MEMORY_DEBUG
14702 vos_mem_exit();
14703#endif
Sushant Kaushik83392fa2015-05-05 17:44:40 +053014704 vos_wake_lock_destroy(&wlan_wake_lock);
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +053014705#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
14706 wlan_logging_sock_deinit_svc();
14707#endif
14708
Jeff Johnson295189b2012-06-20 16:38:30 -070014709 pr_err("%s: driver load failure\n", WLAN_MODULE_NAME);
14710 }
14711 else
14712 {
14713 //Send WLAN UP indication to Nlink Service
14714 send_btc_nlink_msg(WLAN_MODULE_UP_IND, 0);
14715
14716 pr_info("%s: driver loaded\n", WLAN_MODULE_NAME);
Jeff Johnson295189b2012-06-20 16:38:30 -070014717 }
14718
14719 EXIT();
14720
14721 return ret_status;
14722}
14723
Jeff Johnson32d95a32012-09-10 13:15:23 -070014724/**---------------------------------------------------------------------------
14725
14726 \brief hdd_module_init() - Init Function
14727
14728 This is the driver entry point (invoked when module is loaded using insmod)
14729
14730 \param - None
14731
14732 \return - 0 for success, non zero for failure
14733
14734 --------------------------------------------------------------------------*/
14735#ifdef MODULE
14736static int __init hdd_module_init ( void)
14737{
14738 return hdd_driver_init();
14739}
Jeff Johnson32d95a32012-09-10 13:15:23 -070014740#else /* #ifdef MODULE */
14741static int __init hdd_module_init ( void)
14742{
14743 /* Driver initialization is delayed to fwpath_changed_handler */
14744 return 0;
14745}
Jeff Johnson32d95a32012-09-10 13:15:23 -070014746#endif /* #ifdef MODULE */
14747
Jeff Johnson295189b2012-06-20 16:38:30 -070014748
14749/**---------------------------------------------------------------------------
14750
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070014751 \brief hdd_driver_exit() - Exit function
Jeff Johnson295189b2012-06-20 16:38:30 -070014752
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070014753 This is the driver exit point (invoked when module is unloaded using rmmod
14754 or con_mode was changed by userspace)
Jeff Johnson295189b2012-06-20 16:38:30 -070014755
14756 \param - None
14757
14758 \return - None
14759
14760 --------------------------------------------------------------------------*/
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070014761static void hdd_driver_exit(void)
Jeff Johnson295189b2012-06-20 16:38:30 -070014762{
14763 hdd_context_t *pHddCtx = NULL;
14764 v_CONTEXT_t pVosContext = NULL;
Agarwal Ashish5e414792014-06-08 15:25:23 +053014765 v_REGDOMAIN_t regId;
Arun Kumar Khandavallie0b046d2014-03-01 21:54:25 +053014766 unsigned long rc = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070014767
14768 pr_info("%s: unloading driver v%s\n", WLAN_MODULE_NAME, QWLAN_VERSIONSTR);
14769
14770 //Get the global vos context
14771 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
14772
14773 if(!pVosContext)
14774 {
14775 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Global VOS context is Null", __func__);
14776 goto done;
14777 }
14778
14779 //Get the HDD context.
14780 pHddCtx = (hdd_context_t *)vos_get_context(VOS_MODULE_ID_HDD, pVosContext );
14781
14782 if(!pHddCtx)
14783 {
14784 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: module exit called before probe",__func__);
14785 }
Katya Nigame7b69a82015-04-28 15:24:06 +053014786 else if (VOS_MONITOR_MODE == hdd_get_conparam())
14787 {
14788 hddLog(VOS_TRACE_LEVEL_INFO,"%s: MONITOR MODE",__func__);
14789 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_UNLOAD_IN_PROGRESS;
14790 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, TRUE);
14791 hdd_wlan_exit(pHddCtx);
14792 vos_preClose( &pVosContext );
14793 goto done;
14794 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014795 else
14796 {
Siddharth Bhal2e5871b2015-03-24 16:20:51 +053014797 /* We wait for active entry threads to exit from driver
14798 * by waiting until rtnl_lock is available.
14799 */
14800 rtnl_lock();
14801 rtnl_unlock();
14802
Siddharth Bhal3c29dca2015-02-19 00:41:40 +053014803 INIT_COMPLETION(pHddCtx->ssr_comp_var);
14804 if ((pHddCtx->isLogpInProgress) && (FALSE ==
14805 vos_is_wlan_in_badState(VOS_MODULE_ID_HDD, NULL)))
14806 {
Siddharth Bhala204f572015-01-17 02:03:36 +053014807 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Siddharth Bhal3c29dca2015-02-19 00:41:40 +053014808 "%s:SSR in Progress; block rmmod !!!", __func__);
Siddharth Bhala204f572015-01-17 02:03:36 +053014809 rc = wait_for_completion_timeout(&pHddCtx->ssr_comp_var,
14810 msecs_to_jiffies(30000));
14811 if(!rc)
14812 {
14813 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
14814 "%s:SSR timedout, fatal error", __func__);
14815 VOS_BUG(0);
14816 }
14817 }
14818
Siddharth Bhal3c29dca2015-02-19 00:41:40 +053014819 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_UNLOAD_IN_PROGRESS;
14820 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, TRUE);
Jeff Johnson295189b2012-06-20 16:38:30 -070014821
c_hpothu8adb97b2014-12-08 19:38:20 +053014822 /* Driver Need to send country code 00 in below condition
14823 * 1) If gCountryCodePriority is set to 1; and last country
14824 * code set is through 11d. This needs to be done in case
14825 * when NV country code is 00.
14826 * This Needs to be done as when kernel store last country
14827 * code and if stored country code is not through 11d,
14828 * in sme_HandleChangeCountryCodeByUser we will disable 11d
14829 * in next load/unload as soon as we get any country through
14830 * 11d. In sme_HandleChangeCountryCodeByUser
14831 * pMsg->countryCode will be last countryCode and
14832 * pMac->scan.countryCode11d will be country through 11d so
14833 * due to mismatch driver will disable 11d.
14834 *
14835 */
Agarwal Ashish8db39882014-07-30 21:56:07 +053014836
c_hpothu8adb97b2014-12-08 19:38:20 +053014837 if ((eANI_BOOLEAN_TRUE == sme_Is11dCountrycode(pHddCtx->hHal) &&
Agarwal Ashish8dcd2862014-07-25 11:58:52 +053014838 pHddCtx->cfg_ini->fSupplicantCountryCodeHasPriority &&
Abhishek Singh2a705962014-10-30 14:47:28 +053014839 sme_Is11dSupported(pHddCtx->hHal)))
c_hpothu8adb97b2014-12-08 19:38:20 +053014840 {
14841 hddLog(VOS_TRACE_LEVEL_INFO,
Agarwal Ashish8dcd2862014-07-25 11:58:52 +053014842 FL("CountryCode 00 is being set while unloading driver"));
c_hpothu8adb97b2014-12-08 19:38:20 +053014843 vos_nv_getRegDomainFromCountryCode(&regId , "00", COUNTRY_USER);
14844 }
Agarwal Ashish5e414792014-06-08 15:25:23 +053014845
c_hpothu8adb97b2014-12-08 19:38:20 +053014846 //Do all the cleanup before deregistering the driver
14847 hdd_wlan_exit(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -070014848 }
14849
Jeff Johnson295189b2012-06-20 16:38:30 -070014850 vos_preClose( &pVosContext );
14851
14852#ifdef TIMER_MANAGER
14853 vos_timer_exit();
14854#endif
14855#ifdef MEMORY_DEBUG
14856 vos_mem_exit();
14857#endif
14858
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +053014859#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
14860 wlan_logging_sock_deinit_svc();
14861#endif
14862
Jeff Johnson295189b2012-06-20 16:38:30 -070014863done:
Sushant Kaushik83392fa2015-05-05 17:44:40 +053014864 vos_wake_lock_destroy(&wlan_wake_lock);
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +053014865
Jeff Johnson295189b2012-06-20 16:38:30 -070014866 pr_info("%s: driver unloaded\n", WLAN_MODULE_NAME);
14867}
14868
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070014869/**---------------------------------------------------------------------------
14870
14871 \brief hdd_module_exit() - Exit function
14872
14873 This is the driver exit point (invoked when module is unloaded using rmmod)
14874
14875 \param - None
14876
14877 \return - None
14878
14879 --------------------------------------------------------------------------*/
14880static void __exit hdd_module_exit(void)
14881{
14882 hdd_driver_exit();
14883}
14884
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070014885#ifdef MODULE
14886static int fwpath_changed_handler(const char *kmessage,
Ashish Kumar Dhanotiyafb3fd972018-04-30 12:46:52 +053014887 const struct kernel_param *kp)
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070014888{
Jeff Johnson76052702013-04-16 13:55:05 -070014889 return param_set_copystring(kmessage, kp);
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070014890}
14891
14892static int con_mode_handler(const char *kmessage,
Ashish Kumar Dhanotiyafb3fd972018-04-30 12:46:52 +053014893 const struct kernel_param *kp)
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070014894{
Madan Mohan Koyyalamudif2f8d8b2012-10-11 17:06:59 -070014895 return param_set_int(kmessage, kp);
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070014896}
14897#else /* #ifdef MODULE */
14898/**---------------------------------------------------------------------------
14899
Jeff Johnson76052702013-04-16 13:55:05 -070014900 \brief kickstart_driver
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070014901
Jeff Johnson76052702013-04-16 13:55:05 -070014902 This is the driver entry point
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070014903 - delayed driver initialization when driver is statically linked
Jeff Johnson76052702013-04-16 13:55:05 -070014904 - invoked when module parameter fwpath is modified from userspace to signal
14905 initializing the WLAN driver or when con_mode is modified from userspace
14906 to signal a switch in operating mode
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070014907
14908 \return - 0 for success, non zero for failure
14909
14910 --------------------------------------------------------------------------*/
Jeff Johnson76052702013-04-16 13:55:05 -070014911static int kickstart_driver(void)
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070014912{
Madan Mohan Koyyalamudi62e60052012-10-05 14:27:22 -070014913 int ret_status;
14914
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070014915 if (!wlan_hdd_inited) {
Madan Mohan Koyyalamudi62e60052012-10-05 14:27:22 -070014916 ret_status = hdd_driver_init();
14917 wlan_hdd_inited = ret_status ? 0 : 1;
14918 return ret_status;
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070014919 }
14920
14921 hdd_driver_exit();
Jeff Johnson76052702013-04-16 13:55:05 -070014922
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070014923 msleep(200);
Jeff Johnson76052702013-04-16 13:55:05 -070014924
Madan Mohan Koyyalamudi62e60052012-10-05 14:27:22 -070014925 ret_status = hdd_driver_init();
14926 wlan_hdd_inited = ret_status ? 0 : 1;
14927 return ret_status;
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070014928}
14929
Jeff Johnson295189b2012-06-20 16:38:30 -070014930/**---------------------------------------------------------------------------
14931
Jeff Johnson76052702013-04-16 13:55:05 -070014932 \brief fwpath_changed_handler() - Handler Function
14933
14934 Handle changes to the fwpath parameter
14935
14936 \return - 0 for success, non zero for failure
14937
14938 --------------------------------------------------------------------------*/
14939static int fwpath_changed_handler(const char *kmessage,
Ashish Kumar Dhanotiyafb3fd972018-04-30 12:46:52 +053014940 const struct kernel_param *kp)
Jeff Johnson76052702013-04-16 13:55:05 -070014941{
14942 int ret;
14943
14944 ret = param_set_copystring(kmessage, kp);
14945 if (0 == ret)
14946 ret = kickstart_driver();
14947 return ret;
14948}
14949
14950/**---------------------------------------------------------------------------
14951
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070014952 \brief con_mode_handler() -
14953
14954 Handler function for module param con_mode when it is changed by userspace
14955 Dynamically linked - do nothing
14956 Statically linked - exit and init driver, as in rmmod and insmod
14957
Jeff Johnson76052702013-04-16 13:55:05 -070014958 \param -
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070014959
Jeff Johnson76052702013-04-16 13:55:05 -070014960 \return -
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070014961
14962 --------------------------------------------------------------------------*/
Ashish Kumar Dhanotiyafb3fd972018-04-30 12:46:52 +053014963static int con_mode_handler(const char *kmessage,
14964 const struct kernel_param *kp)
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070014965{
Jeff Johnson76052702013-04-16 13:55:05 -070014966 int ret;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070014967
Jeff Johnson76052702013-04-16 13:55:05 -070014968 ret = param_set_int(kmessage, kp);
14969 if (0 == ret)
14970 ret = kickstart_driver();
14971 return ret;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070014972}
14973#endif /* #ifdef MODULE */
14974
14975/**---------------------------------------------------------------------------
14976
Jeff Johnson295189b2012-06-20 16:38:30 -070014977 \brief hdd_get_conparam() -
14978
14979 This is the driver exit point (invoked when module is unloaded using rmmod)
14980
14981 \param - None
14982
14983 \return - tVOS_CON_MODE
14984
14985 --------------------------------------------------------------------------*/
14986tVOS_CON_MODE hdd_get_conparam ( void )
14987{
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070014988#ifdef MODULE
Jeff Johnson295189b2012-06-20 16:38:30 -070014989 return (tVOS_CON_MODE)con_mode;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070014990#else
14991 return (tVOS_CON_MODE)curr_con_mode;
14992#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070014993}
14994void hdd_set_conparam ( v_UINT_t newParam )
14995{
14996 con_mode = newParam;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070014997#ifndef MODULE
14998 curr_con_mode = con_mode;
14999#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070015000}
15001/**---------------------------------------------------------------------------
15002
15003 \brief hdd_softap_sta_deauth() - function
15004
15005 This to take counter measure to handle deauth req from HDD
15006
15007 \param - pAdapter - Pointer to the HDD
15008
15009 \param - enable - boolean value
15010
15011 \return - None
15012
15013 --------------------------------------------------------------------------*/
15014
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053015015VOS_STATUS hdd_softap_sta_deauth(hdd_adapter_t *pAdapter,
15016 struct tagCsrDelStaParams *pDelStaParams)
Jeff Johnson295189b2012-06-20 16:38:30 -070015017{
Jeff Johnson295189b2012-06-20 16:38:30 -070015018 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080015019 VOS_STATUS vosStatus = VOS_STATUS_E_FAULT;
Hanumanth Reddy Pothula57323632017-12-06 17:55:09 +053015020 struct hdd_cache_sta_info *cache_sta_info;
15021 ptSapContext pSapCtx = VOS_GET_SAP_CB(pVosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -070015022
15023 ENTER();
15024
Jeff Johnsonc135a9a2017-09-19 08:37:24 -070015025 hddLog(LOG1, "hdd_softap_sta_deauth:(%pK, false)",
Rajesh Chauhan18488fc2013-08-22 10:15:03 -070015026 (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -070015027
Hanumanth Reddy Pothula57323632017-12-06 17:55:09 +053015028 if (!pSapCtx) {
15029 hddLog(LOGE, "sap context is NULL");
15030 return vosStatus;
15031 }
15032
15033 cache_sta_info = hdd_get_cache_stainfo(pSapCtx->cache_sta_info,
15034 pDelStaParams->peerMacAddr);
15035 if (cache_sta_info) {
15036 cache_sta_info->reason_code = pDelStaParams->reason_code;
15037 cache_sta_info->rx_rate =
15038 wlan_tl_get_sta_rx_rate(pVosContext, cache_sta_info->ucSTAId);
15039 WLANTL_GetSAPStaRSSi(pVosContext, cache_sta_info->ucSTAId,
15040 &cache_sta_info->rssi);
15041 }
15042
Jeff Johnson295189b2012-06-20 16:38:30 -070015043 //Ignore request to deauth bcmc station
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053015044 if (pDelStaParams->peerMacAddr[0] & 0x1)
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080015045 return vosStatus;
Jeff Johnson295189b2012-06-20 16:38:30 -070015046
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053015047 vosStatus = WLANSAP_DeauthSta(pVosContext, pDelStaParams);
Jeff Johnson295189b2012-06-20 16:38:30 -070015048
15049 EXIT();
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080015050 return vosStatus;
Jeff Johnson295189b2012-06-20 16:38:30 -070015051}
15052
15053/**---------------------------------------------------------------------------
15054
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +053015055 \brief hdd_del_all_sta() - function
15056
15057 This function removes all the stations associated on stopping AP/P2P GO.
15058
15059 \param - pAdapter - Pointer to the HDD
15060
15061 \return - None
15062
15063 --------------------------------------------------------------------------*/
15064
15065int hdd_del_all_sta(hdd_adapter_t *pAdapter)
15066{
15067 v_U16_t i;
15068 VOS_STATUS vos_status;
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053015069 v_CONTEXT_t pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
15070 ptSapContext pSapCtx = NULL;
15071 pSapCtx = VOS_GET_SAP_CB(pVosContext);
15072 if(pSapCtx == NULL){
15073 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15074 FL("psapCtx is NULL"));
15075 return 1;
15076 }
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +053015077 ENTER();
15078
15079 hddLog(VOS_TRACE_LEVEL_INFO,
15080 "%s: Delete all STAs associated.",__func__);
15081 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
15082 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
15083 )
15084 {
15085 for(i = 0; i < WLAN_MAX_STA_COUNT; i++)
15086 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053015087 if ((pSapCtx->aStaInfo[i].isUsed) &&
15088 (!pSapCtx->aStaInfo[i].isDeauthInProgress))
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +053015089 {
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053015090 struct tagCsrDelStaParams delStaParams;
15091
15092 WLANSAP_PopulateDelStaParams(
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053015093 pSapCtx->aStaInfo[i].macAddrSTA.bytes,
Sushant Kaushik4cd28f62014-12-26 14:23:50 +053015094 eSIR_MAC_DEAUTH_LEAVING_BSS_REASON,
15095 SIR_MAC_MGMT_DEAUTH >> 4,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053015096 &delStaParams);
15097 vos_status = hdd_softap_sta_deauth(pAdapter, &delStaParams);
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +053015098 if (VOS_IS_STATUS_SUCCESS(vos_status))
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053015099 pSapCtx->aStaInfo[i].isDeauthInProgress = TRUE;
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +053015100 }
15101 }
15102 }
15103
15104 EXIT();
15105 return 0;
15106}
15107
15108/**---------------------------------------------------------------------------
15109
Jeff Johnson295189b2012-06-20 16:38:30 -070015110 \brief hdd_softap_sta_disassoc() - function
15111
15112 This to take counter measure to handle deauth req from HDD
15113
15114 \param - pAdapter - Pointer to the HDD
15115
15116 \param - enable - boolean value
15117
15118 \return - None
15119
15120 --------------------------------------------------------------------------*/
15121
15122void hdd_softap_sta_disassoc(hdd_adapter_t *pAdapter,v_U8_t *pDestMacAddress)
15123{
Hanumanth Reddy Pothula57323632017-12-06 17:55:09 +053015124 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
15125 struct hdd_cache_sta_info *cache_sta_info;
15126 ptSapContext pSapCtx = VOS_GET_SAP_CB(pVosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -070015127
15128 ENTER();
15129
Jeff Johnsonc135a9a2017-09-19 08:37:24 -070015130 hddLog( LOGE, "hdd_softap_sta_disassoc:(%pK, false)", (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -070015131
Hanumanth Reddy Pothula57323632017-12-06 17:55:09 +053015132 if (!pSapCtx) {
15133 hddLog(LOGE, "sap context is NULL");
15134 return ;
15135 }
15136
Jeff Johnson295189b2012-06-20 16:38:30 -070015137 //Ignore request to disassoc bcmc station
15138 if( pDestMacAddress[0] & 0x1 )
15139 return;
15140
Hanumanth Reddy Pothula57323632017-12-06 17:55:09 +053015141 cache_sta_info = hdd_get_cache_stainfo(pSapCtx->cache_sta_info,
15142 pDestMacAddress);
15143 if (cache_sta_info) {
15144 cache_sta_info->reason_code = eSIR_MAC_DEAUTH_LEAVING_BSS_REASON;
15145 cache_sta_info->rx_rate =
15146 wlan_tl_get_sta_rx_rate(pVosContext, cache_sta_info->ucSTAId);
15147 WLANTL_GetSAPStaRSSi(pVosContext, cache_sta_info->ucSTAId,
15148 &cache_sta_info->rssi);
15149 }
15150
Jeff Johnson295189b2012-06-20 16:38:30 -070015151 WLANSAP_DisassocSta(pVosContext,pDestMacAddress);
15152}
15153
15154void hdd_softap_tkip_mic_fail_counter_measure(hdd_adapter_t *pAdapter,v_BOOL_t enable)
15155{
15156 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
15157
15158 ENTER();
15159
Jeff Johnsonc135a9a2017-09-19 08:37:24 -070015160 hddLog( LOGE, "hdd_softap_tkip_mic_fail_counter_measure:(%pK, false)", (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -070015161
15162 WLANSAP_SetCounterMeasure(pVosContext, (v_BOOL_t)enable);
15163}
15164
Jeff Johnson295189b2012-06-20 16:38:30 -070015165/**---------------------------------------------------------------------------
15166 *
15167 * \brief hdd_get__concurrency_mode() -
15168 *
15169 *
15170 * \param - None
15171 *
15172 * \return - CONCURRENCY MODE
15173 *
15174 * --------------------------------------------------------------------------*/
15175tVOS_CONCURRENCY_MODE hdd_get_concurrency_mode ( void )
15176{
15177 v_CONTEXT_t pVosContext = vos_get_global_context( VOS_MODULE_ID_HDD, NULL );
15178 hdd_context_t *pHddCtx;
15179
15180 if (NULL != pVosContext)
15181 {
15182 pHddCtx = vos_get_context( VOS_MODULE_ID_HDD, pVosContext);
15183 if (NULL != pHddCtx)
15184 {
15185 return (tVOS_CONCURRENCY_MODE)pHddCtx->concurrency_mode;
15186 }
15187 }
15188
15189 /* we are in an invalid state :( */
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070015190 hddLog(LOGE, "%s: Invalid context", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070015191 return VOS_STA;
15192}
Sushant Kaushikabb7ee62014-07-18 16:20:12 +053015193v_BOOL_t
15194wlan_hdd_is_GO_power_collapse_allowed (hdd_context_t* pHddCtx)
15195{
15196 hdd_adapter_t *pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070015197
Sushant Kaushikabb7ee62014-07-18 16:20:12 +053015198 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_GO);
15199 if (pAdapter == NULL)
15200 {
15201 hddLog(VOS_TRACE_LEVEL_INFO,
15202 FL("GO doesn't exist"));
15203 return TRUE;
15204 }
15205 if (test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
15206 {
15207 hddLog(VOS_TRACE_LEVEL_INFO,
15208 FL("GO started"));
15209 return TRUE;
15210 }
15211 else
15212 /* wait till GO changes its interface to p2p device */
15213 hddLog(VOS_TRACE_LEVEL_INFO,
15214 FL("Del_bss called, avoid apps suspend"));
15215 return FALSE;
15216
15217}
Jeff Johnson295189b2012-06-20 16:38:30 -070015218/* Decide whether to allow/not the apps power collapse.
15219 * Allow apps power collapse if we are in connected state.
15220 * if not, allow only if we are in IMPS */
15221v_BOOL_t hdd_is_apps_power_collapse_allowed(hdd_context_t* pHddCtx)
15222{
15223 tPmcState pmcState = pmcGetPmcState(pHddCtx->hHal);
Srikant Kuppafef66a72013-01-30 17:32:44 -080015224 tANI_BOOLEAN scanRspPending = csrNeighborRoamScanRspPending(pHddCtx->hHal);
Srinivas Girigowdaa553c462013-03-07 19:42:52 -080015225 tANI_BOOLEAN inMiddleOfRoaming = csrNeighborMiddleOfRoaming(pHddCtx->hHal);
Jeff Johnson295189b2012-06-20 16:38:30 -070015226 hdd_config_t *pConfig = pHddCtx->cfg_ini;
15227 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
15228 hdd_adapter_t *pAdapter = NULL;
15229 VOS_STATUS status;
Yathish9f22e662012-12-10 14:21:35 -080015230 tVOS_CONCURRENCY_MODE concurrent_state = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070015231
Jeff Johnson295189b2012-06-20 16:38:30 -070015232 if (VOS_STA_SAP_MODE == hdd_get_conparam())
15233 return TRUE;
Jeff Johnson295189b2012-06-20 16:38:30 -070015234
Yathish9f22e662012-12-10 14:21:35 -080015235 concurrent_state = hdd_get_concurrency_mode();
15236
Sushant Kaushikabb7ee62014-07-18 16:20:12 +053015237 if ((concurrent_state == (VOS_STA | VOS_P2P_GO)) &&
15238 !(wlan_hdd_is_GO_power_collapse_allowed(pHddCtx)))
15239 return FALSE;
Yathish9f22e662012-12-10 14:21:35 -080015240#ifdef WLAN_ACTIVEMODE_OFFLOAD_FEATURE
Sushant Kaushikabb7ee62014-07-18 16:20:12 +053015241
Yathish9f22e662012-12-10 14:21:35 -080015242 if(((concurrent_state == (VOS_STA | VOS_P2P_CLIENT)) ||
Sushant Kaushikabb7ee62014-07-18 16:20:12 +053015243 (concurrent_state == (VOS_STA | VOS_P2P_GO)))&&
Yathish9f22e662012-12-10 14:21:35 -080015244 (IS_ACTIVEMODE_OFFLOAD_FEATURE_ENABLE))
15245 return TRUE;
15246#endif
15247
Jeff Johnson295189b2012-06-20 16:38:30 -070015248 /*loop through all adapters. TBD fix for Concurrency */
15249 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
15250 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
15251 {
15252 pAdapter = pAdapterNode->pAdapter;
15253 if ( (WLAN_HDD_INFRA_STATION == pAdapter->device_mode)
15254 || (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
15255 {
Srikant Kuppafef66a72013-01-30 17:32:44 -080015256 if (((pConfig->fIsImpsEnabled || pConfig->fIsBmpsEnabled)
c_hpothu4e8faac2014-05-16 17:38:44 +053015257 && (pmcState != IMPS && pmcState != BMPS && pmcState != UAPSD
c_hpothu1c6957d2015-01-06 18:19:47 +053015258 && pmcState != STOPPED && pmcState != STANDBY &&
15259 pmcState != WOWL)) ||
Srinivas Girigowdaa553c462013-03-07 19:42:52 -080015260 (eANI_BOOLEAN_TRUE == scanRspPending) ||
15261 (eANI_BOOLEAN_TRUE == inMiddleOfRoaming))
Jeff Johnson295189b2012-06-20 16:38:30 -070015262 {
Mukul Sharma4be88422015-03-09 20:29:07 +053015263 if(pmcState == FULL_POWER &&
15264 sme_IsCoexScoIndicationSet(pHddCtx->hHal))
15265 {
15266 /*
15267 * When SCO indication comes from Coex module , host will
15268 * enter in to full power mode, but this should not prevent
15269 * apps processor power collapse.
15270 */
15271 hddLog(LOG1,
15272 FL("Allow apps power collapse"
15273 "even when sco indication is set"));
15274 return TRUE;
15275 }
Srikant Kuppafef66a72013-01-30 17:32:44 -080015276 hddLog( LOGE, "%s: do not allow APPS power collapse-"
Deepthi Gowri03a979f2016-11-03 15:20:19 +053015277 "pmcState = %d scanRspPending = %d "
15278 "inMiddleOfRoaming = %d connected = %d",
15279 __func__, pmcState, scanRspPending,
15280 inMiddleOfRoaming, hdd_connIsConnected(
15281 WLAN_HDD_GET_STATION_CTX_PTR( pAdapter )));
15282 wlan_hdd_get_tdls_stats(pAdapter);
15283 return FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070015284 }
15285 }
15286 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
15287 pAdapterNode = pNext;
15288 }
15289 return TRUE;
15290}
15291
Madan Mohan Koyyalamudic72a4d62012-11-08 14:59:34 -080015292/* Decides whether to send suspend notification to Riva
15293 * if any adapter is in BMPS; then it is required */
15294v_BOOL_t hdd_is_suspend_notify_allowed(hdd_context_t* pHddCtx)
15295{
15296 tPmcState pmcState = pmcGetPmcState(pHddCtx->hHal);
15297 hdd_config_t *pConfig = pHddCtx->cfg_ini;
15298
15299 if (pConfig->fIsBmpsEnabled && (pmcState == BMPS))
15300 {
15301 return TRUE;
15302 }
15303 return FALSE;
15304}
15305
Jeff Johnson295189b2012-06-20 16:38:30 -070015306void wlan_hdd_set_concurrency_mode(hdd_context_t *pHddCtx, tVOS_CON_MODE mode)
15307{
15308 switch(mode)
15309 {
Chilam Ngc4244af2013-04-01 15:37:32 -070015310 case VOS_STA_MODE:
15311 case VOS_P2P_CLIENT_MODE:
15312 case VOS_P2P_GO_MODE:
15313 case VOS_STA_SAP_MODE:
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +053015314 case VOS_MONITOR_MODE:
Jeff Johnsone7245742012-09-05 17:12:55 -070015315 pHddCtx->concurrency_mode |= (1 << mode);
Agarwal Ashish51325b52014-06-16 16:50:49 +053015316 pHddCtx->no_of_open_sessions[mode]++;
Jeff Johnson295189b2012-06-20 16:38:30 -070015317 break;
15318 default:
15319 break;
Jeff Johnson295189b2012-06-20 16:38:30 -070015320 }
Agarwal Ashish51325b52014-06-16 16:50:49 +053015321 hddLog(VOS_TRACE_LEVEL_INFO, FL("concurrency_mode = 0x%x "
15322 "Number of open sessions for mode %d = %d"),
15323 pHddCtx->concurrency_mode, mode,
15324 pHddCtx->no_of_open_sessions[mode]);
Jeff Johnson295189b2012-06-20 16:38:30 -070015325}
15326
15327
15328void wlan_hdd_clear_concurrency_mode(hdd_context_t *pHddCtx, tVOS_CON_MODE mode)
15329{
15330 switch(mode)
15331 {
Chilam Ngc4244af2013-04-01 15:37:32 -070015332 case VOS_STA_MODE:
15333 case VOS_P2P_CLIENT_MODE:
15334 case VOS_P2P_GO_MODE:
15335 case VOS_STA_SAP_MODE:
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +053015336 case VOS_MONITOR_MODE:
Agarwal Ashish51325b52014-06-16 16:50:49 +053015337 pHddCtx->no_of_open_sessions[mode]--;
15338 if (!(pHddCtx->no_of_open_sessions[mode]))
15339 pHddCtx->concurrency_mode &= (~(1 << mode));
Jeff Johnson295189b2012-06-20 16:38:30 -070015340 break;
15341 default:
15342 break;
15343 }
Agarwal Ashish51325b52014-06-16 16:50:49 +053015344 hddLog(VOS_TRACE_LEVEL_INFO, FL("concurrency_mode = 0x%x "
15345 "Number of open sessions for mode %d = %d"),
15346 pHddCtx->concurrency_mode, mode, pHddCtx->no_of_open_sessions[mode]);
15347
15348}
15349/**---------------------------------------------------------------------------
15350 *
15351 * \brief wlan_hdd_incr_active_session()
15352 *
15353 * This function increments the number of active sessions
15354 * maintained per device mode
15355 * Incase of STA/P2P CLI/IBSS upon connection indication it is incremented
15356 * Incase of SAP/P2P GO upon bss start it is incremented
15357 *
15358 * \param pHddCtx - HDD Context
15359 * \param mode - device mode
15360 *
15361 * \return - None
15362 *
15363 * --------------------------------------------------------------------------*/
15364void wlan_hdd_incr_active_session(hdd_context_t *pHddCtx, tVOS_CON_MODE mode)
15365{
15366 switch (mode) {
15367 case VOS_STA_MODE:
15368 case VOS_P2P_CLIENT_MODE:
15369 case VOS_P2P_GO_MODE:
15370 case VOS_STA_SAP_MODE:
15371 pHddCtx->no_of_active_sessions[mode]++;
15372 break;
15373 default:
15374 hddLog(VOS_TRACE_LEVEL_INFO, FL("Not Expected Mode %d"), mode);
15375 break;
15376 }
15377 hddLog(VOS_TRACE_LEVEL_INFO, FL("No.# of active sessions for mode %d = %d"),
15378 mode,
15379 pHddCtx->no_of_active_sessions[mode]);
15380}
15381
15382/**---------------------------------------------------------------------------
15383 *
15384 * \brief wlan_hdd_decr_active_session()
15385 *
15386 * This function decrements the number of active sessions
15387 * maintained per device mode
15388 * Incase of STA/P2P CLI/IBSS upon disconnection it is decremented
15389 * Incase of SAP/P2P GO upon bss stop it is decremented
15390 *
15391 * \param pHddCtx - HDD Context
15392 * \param mode - device mode
15393 *
15394 * \return - None
15395 *
15396 * --------------------------------------------------------------------------*/
15397void wlan_hdd_decr_active_session(hdd_context_t *pHddCtx, tVOS_CON_MODE mode)
15398{
Bhargav Shahd0715912015-10-01 18:17:37 +053015399
Agarwal Ashish51325b52014-06-16 16:50:49 +053015400 switch (mode) {
15401 case VOS_STA_MODE:
15402 case VOS_P2P_CLIENT_MODE:
15403 case VOS_P2P_GO_MODE:
15404 case VOS_STA_SAP_MODE:
Agarwal Ashish5325f522014-08-06 00:58:44 +053015405 if (pHddCtx->no_of_active_sessions[mode] > 0)
15406 pHddCtx->no_of_active_sessions[mode]--;
15407 else
15408 hddLog(VOS_TRACE_LEVEL_INFO, FL(" No.# of Active sessions"
15409 "is already Zero"));
Agarwal Ashish51325b52014-06-16 16:50:49 +053015410 break;
15411 default:
15412 hddLog(VOS_TRACE_LEVEL_INFO, FL("Not Expected Mode %d"), mode);
15413 break;
15414 }
15415 hddLog(VOS_TRACE_LEVEL_INFO, FL("No.# of active sessions for mode %d = %d"),
15416 mode,
15417 pHddCtx->no_of_active_sessions[mode]);
Jeff Johnson295189b2012-06-20 16:38:30 -070015418}
15419
Jeff Johnsone7245742012-09-05 17:12:55 -070015420/**---------------------------------------------------------------------------
15421 *
15422 * \brief wlan_hdd_restart_init
15423 *
15424 * This function initalizes restart timer/flag. An internal function.
15425 *
15426 * \param - pHddCtx
15427 *
15428 * \return - None
15429 *
15430 * --------------------------------------------------------------------------*/
15431
15432static void wlan_hdd_restart_init(hdd_context_t *pHddCtx)
15433{
15434 /* Initialize */
15435 pHddCtx->hdd_restart_retries = 0;
15436 atomic_set(&pHddCtx->isRestartInProgress, 0);
15437 vos_timer_init(&pHddCtx->hdd_restart_timer,
15438 VOS_TIMER_TYPE_SW,
15439 wlan_hdd_restart_timer_cb,
15440 pHddCtx);
15441}
15442/**---------------------------------------------------------------------------
15443 *
15444 * \brief wlan_hdd_restart_deinit
15445 *
15446 * This function cleans up the resources used. An internal function.
15447 *
15448 * \param - pHddCtx
15449 *
15450 * \return - None
15451 *
15452 * --------------------------------------------------------------------------*/
15453
15454static void wlan_hdd_restart_deinit(hdd_context_t* pHddCtx)
15455{
15456
15457 VOS_STATUS vos_status;
15458 /* Block any further calls */
15459 atomic_set(&pHddCtx->isRestartInProgress, 1);
15460 /* Cleanup */
15461 vos_status = vos_timer_stop( &pHddCtx->hdd_restart_timer );
15462 if (!VOS_IS_STATUS_SUCCESS(vos_status))
c_hpothu6ff1c3c2013-10-01 19:01:57 +053015463 hddLog(LOGE, FL("Failed to stop HDD restart timer"));
Jeff Johnsone7245742012-09-05 17:12:55 -070015464 vos_status = vos_timer_destroy(&pHddCtx->hdd_restart_timer);
15465 if (!VOS_IS_STATUS_SUCCESS(vos_status))
c_hpothu6ff1c3c2013-10-01 19:01:57 +053015466 hddLog(LOGE, FL("Failed to destroy HDD restart timer"));
Jeff Johnsone7245742012-09-05 17:12:55 -070015467
15468}
15469
15470/**---------------------------------------------------------------------------
15471 *
15472 * \brief wlan_hdd_framework_restart
15473 *
15474 * This function uses a cfg80211 API to start a framework initiated WLAN
15475 * driver module unload/load.
15476 *
15477 * Also this API keep retrying (WLAN_HDD_RESTART_RETRY_MAX_CNT).
15478 *
15479 *
15480 * \param - pHddCtx
15481 *
15482 * \return - VOS_STATUS_SUCCESS: Success
15483 * VOS_STATUS_E_EMPTY: Adapter is Empty
15484 * VOS_STATUS_E_NOMEM: No memory
15485
15486 * --------------------------------------------------------------------------*/
15487
15488static VOS_STATUS wlan_hdd_framework_restart(hdd_context_t *pHddCtx)
15489{
15490 VOS_STATUS status = VOS_STATUS_SUCCESS;
15491 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
Madan Mohan Koyyalamudifc19e442013-05-09 18:24:08 -070015492 int len = (sizeof (struct ieee80211_mgmt));
15493 struct ieee80211_mgmt *mgmt = NULL;
15494
15495 /* Prepare the DEAUTH managment frame with reason code */
15496 mgmt = kzalloc(len, GFP_KERNEL);
15497 if(mgmt == NULL)
15498 {
15499 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
15500 "%s: memory allocation failed (%d bytes)", __func__, len);
15501 return VOS_STATUS_E_NOMEM;
15502 }
15503 mgmt->u.deauth.reason_code = WLAN_REASON_DISASSOC_LOW_ACK;
Jeff Johnsone7245742012-09-05 17:12:55 -070015504
15505 /* Iterate over all adapters/devices */
15506 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
Hanumantha Reddy Pothulada0fe362015-02-27 18:37:03 +053015507 if ((NULL == pAdapterNode) || (VOS_STATUS_SUCCESS != status))
15508 {
15509 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnsonc135a9a2017-09-19 08:37:24 -070015510 FL("fail to get adapter: %pK %d"), pAdapterNode, status);
Hanumantha Reddy Pothulada0fe362015-02-27 18:37:03 +053015511 goto end;
15512 }
15513
Jeff Johnsone7245742012-09-05 17:12:55 -070015514 do
15515 {
Hanumantha Reddy Pothulada0fe362015-02-27 18:37:03 +053015516 if(pAdapterNode->pAdapter &&
15517 WLAN_HDD_ADAPTER_MAGIC == pAdapterNode->pAdapter->magic)
Jeff Johnsone7245742012-09-05 17:12:55 -070015518 {
15519 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
15520 "restarting the driver(intf:\'%s\' mode:%d :try %d)",
15521 pAdapterNode->pAdapter->dev->name,
15522 pAdapterNode->pAdapter->device_mode,
15523 pHddCtx->hdd_restart_retries + 1);
Madan Mohan Koyyalamudifc19e442013-05-09 18:24:08 -070015524 /*
15525 * CFG80211 event to restart the driver
15526 *
15527 * 'cfg80211_send_unprot_deauth' sends a
15528 * NL80211_CMD_UNPROT_DEAUTHENTICATE event to supplicant at any state
15529 * of SME(Linux Kernel) state machine.
15530 *
15531 * Reason code WLAN_REASON_DISASSOC_LOW_ACK is currently used to restart
15532 * the driver.
15533 *
15534 */
Abhishek Singh00b71972016-01-07 10:51:04 +053015535
Anand N Sunkade9adb1b2015-07-29 09:56:45 +053015536#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 11, 0))
15537 cfg80211_rx_unprot_mlme_mgmt(pAdapterNode->pAdapter->dev, (u_int8_t*)mgmt, len);
15538#else
Madan Mohan Koyyalamudifc19e442013-05-09 18:24:08 -070015539 cfg80211_send_unprot_deauth(pAdapterNode->pAdapter->dev, (u_int8_t*)mgmt, len );
Anand N Sunkade9adb1b2015-07-29 09:56:45 +053015540#endif
Jeff Johnsone7245742012-09-05 17:12:55 -070015541 }
15542 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
15543 pAdapterNode = pNext;
15544 } while((NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status));
15545
Hanumantha Reddy Pothulada0fe362015-02-27 18:37:03 +053015546 end:
Madan Mohan Koyyalamudifc19e442013-05-09 18:24:08 -070015547 /* Free the allocated management frame */
15548 kfree(mgmt);
15549
Jeff Johnsone7245742012-09-05 17:12:55 -070015550 /* Retry until we unload or reach max count */
15551 if(++pHddCtx->hdd_restart_retries < WLAN_HDD_RESTART_RETRY_MAX_CNT)
15552 vos_timer_start(&pHddCtx->hdd_restart_timer, WLAN_HDD_RESTART_RETRY_DELAY_MS);
15553
15554 return status;
15555
15556}
15557/**---------------------------------------------------------------------------
15558 *
15559 * \brief wlan_hdd_restart_timer_cb
15560 *
15561 * Restart timer callback. An internal function.
15562 *
15563 * \param - User data:
15564 *
15565 * \return - None
15566 *
15567 * --------------------------------------------------------------------------*/
15568
15569void wlan_hdd_restart_timer_cb(v_PVOID_t usrDataForCallback)
15570{
15571 hdd_context_t *pHddCtx = usrDataForCallback;
15572 wlan_hdd_framework_restart(pHddCtx);
15573 return;
15574
15575}
15576
15577
15578/**---------------------------------------------------------------------------
15579 *
15580 * \brief wlan_hdd_restart_driver
15581 *
15582 * This function sends an event to supplicant to restart the WLAN driver.
15583 *
15584 * This function is called from vos_wlanRestart.
15585 *
15586 * \param - pHddCtx
15587 *
15588 * \return - VOS_STATUS_SUCCESS: Success
15589 * VOS_STATUS_E_EMPTY: Adapter is Empty
15590 * VOS_STATUS_E_ALREADY: Request already in progress
15591
15592 * --------------------------------------------------------------------------*/
15593VOS_STATUS wlan_hdd_restart_driver(hdd_context_t *pHddCtx)
15594{
15595 VOS_STATUS status = VOS_STATUS_SUCCESS;
15596
15597 /* A tight check to make sure reentrancy */
15598 if(atomic_xchg(&pHddCtx->isRestartInProgress, 1))
15599 {
Mihir Shetefd528652014-06-23 19:07:50 +053015600 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnsone7245742012-09-05 17:12:55 -070015601 "%s: WLAN restart is already in progress", __func__);
15602
15603 return VOS_STATUS_E_ALREADY;
15604 }
Sameer Thalappil0c164f52013-03-28 15:27:56 -070015605 /* Send reset FIQ to WCNSS to invoke SSR. */
Madan Mohan Koyyalamudie388b342012-11-08 15:03:16 -080015606#ifdef HAVE_WCNSS_RESET_INTR
Siddharth Bhal864e7e82015-04-07 20:07:24 +053015607 wcnss_reset_fiq(TRUE);
Madan Mohan Koyyalamudibb8f0172012-09-28 15:36:06 -070015608#endif
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -070015609
Jeff Johnsone7245742012-09-05 17:12:55 -070015610 return status;
15611}
15612
Bhargav Shahd0715912015-10-01 18:17:37 +053015613/**
15614 * hdd_get_total_sessions() - provide total number of active sessions
15615 * @pHddCtx: Valid Global HDD context pointer
15616 *
15617 * This function iterates through pAdaptors and find the number of all active
15618 * sessions. This active sessions includes connected sta, p2p client and number
15619 * of client connected to sap/p2p go.
15620 *
15621 * Return: Total number of active sessions.
15622 */
15623v_U8_t hdd_get_total_sessions(hdd_context_t *pHddCtx)
15624{
15625 v_U8_t active_session = 0;
15626 hdd_station_ctx_t *pHddStaCtx;
15627 hdd_adapter_list_node_t *pAdapterNode, *pNext;
15628 hdd_adapter_t *pAdapter;
15629 VOS_STATUS status;
15630
15631 status = hdd_get_front_adapter(pHddCtx, &pAdapterNode);
15632 while (NULL != pAdapterNode && VOS_STATUS_SUCCESS == status) {
15633 pAdapter = pAdapterNode->pAdapter;
15634 switch (pAdapter->device_mode) {
15635 case VOS_STA_MODE:
15636 case VOS_P2P_CLIENT_MODE:
15637 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
15638 if(eConnectionState_Associated == pHddStaCtx->conn_info.connState)
15639 active_session += 1;
15640 break;
15641 case VOS_STA_SAP_MODE:
15642 case VOS_P2P_GO_MODE:
15643 active_session += hdd_softap_get_connected_sta(pAdapter);
15644 break;
15645 default:
15646 break;
15647 }
15648
15649 status = hdd_get_next_adapter(pHddCtx, pAdapterNode, &pNext);
15650 pAdapterNode = pNext;
15651 }
15652
15653 return active_session;
15654}
15655
15656/**
15657 * hdd_set_delack_value() - Set delack value
15658 * @pHddCtx: Valid Global HDD context pointer
15659 * @next_rx_level: Value to set for delack
15660 *
15661 * This function compare present value and next value of delack. If the both
15662 * are diffrent then it sets next value .
15663 *
15664 * Return: void.
15665 */
15666void hdd_set_delack_value(hdd_context_t *pHddCtx, v_U32_t next_rx_level)
15667{
15668 if (pHddCtx->cur_rx_level != next_rx_level) {
Alok Kumarf3724462018-04-05 15:18:54 +053015669 struct wlan_rx_tp_data rx_tp_data = {0};
15670
Bhargav Shahd0715912015-10-01 18:17:37 +053015671 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_DEBUG,
15672 "%s: TCP DELACK trigger level %d",
15673 __func__, next_rx_level);
15674 mutex_lock(&pHddCtx->cur_rx_level_lock);
15675 pHddCtx->cur_rx_level = next_rx_level;
15676 mutex_unlock(&pHddCtx->cur_rx_level_lock);
Alok Kumarf3724462018-04-05 15:18:54 +053015677
15678 rx_tp_data.rx_tp_flags |= TCP_DEL_ACK_IND;
15679 rx_tp_data.level = next_rx_level;
15680
15681 wlan_hdd_send_svc_nlink_msg(WLAN_SVC_WLAN_TP_IND, &rx_tp_data,
15682 sizeof(rx_tp_data));
Bhargav Shahd0715912015-10-01 18:17:37 +053015683 }
15684}
15685
15686/**
15687 * hdd_set_default_stop_delack_timer() - Start delack timer
15688 * @pHddCtx: Valid Global HDD context pointer
15689 *
15690 * This function stop delack timer and set delack value to default..
15691 *
15692 * Return: void.
15693 */
15694
15695void hdd_set_default_stop_delack_timer(hdd_context_t *pHddCtx)
15696{
15697 if (VOS_TIMER_STATE_RUNNING !=
15698 vos_timer_getCurrentState(&pHddCtx->delack_timer)) {
15699 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_DEBUG,
15700 "%s: Can not stop timer", __func__);
15701 return;
15702 }
15703
15704 vos_timer_stop(&pHddCtx->delack_timer);
Alok Kumarf3724462018-04-05 15:18:54 +053015705 hdd_set_delack_value(pHddCtx, WLAN_SVC_TP_LOW);
Bhargav Shahd0715912015-10-01 18:17:37 +053015706}
15707
15708/**
15709 * hdd_start_delack_timer() - Start delack timer
15710 * @pHddCtx: Valid Global HDD context pointer
15711 *
15712 * This function starts the delack timer for tcpDelAckComputeInterval time
15713 * interval.The default timer value is 2 second.
15714 *
15715 * Return: void.
15716 */
15717void hdd_start_delack_timer(hdd_context_t *pHddCtx)
15718{
15719 if (VOS_TIMER_STATE_RUNNING ==
15720 vos_timer_getCurrentState(&pHddCtx->delack_timer)) {
15721 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_DEBUG,
15722 "%s: Timer is already running", __func__);
15723 return;
15724 }
15725
15726 vos_timer_start(&pHddCtx->delack_timer,
15727 pHddCtx->cfg_ini->tcpDelAckComputeInterval);
15728}
15729
15730/**
15731 * hdd_update_prev_rx_packet_count() - Update previous rx packet count
15732 * @pHddCtx: Valid Global HDD context pointer
15733 *
15734 * This function updates the prev_rx_packets count from the corresponding
15735 * pAdapter states. This prev_rx_packets will diffed with the packet count
15736 * at the end of delack timer. That can give number of RX packet is spacific
15737 * time.
15738 *
15739 * Return: void.
15740 */
15741void hdd_update_prev_rx_packet_count(hdd_context_t *pHddCtx)
15742{
15743 hdd_adapter_list_node_t *pAdapterNode, *pNext;
15744 hdd_adapter_t *pAdapter;
15745 VOS_STATUS status;
15746
15747 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
15748 while (NULL != pAdapterNode && VOS_STATUS_SUCCESS == status) {
15749 pAdapter = pAdapterNode->pAdapter;
15750 pAdapter->prev_rx_packets = pAdapter->stats.rx_packets;
15751 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
15752 pAdapterNode = pNext;
15753 }
15754}
15755
15756/**
15757 * hdd_manage_delack_timer() - start\stop delack timer
15758 * @pHddCtx: Valid Global HDD context pointer
15759 *
15760 * This function check the number of concerent session present, it starts the
15761 * delack timer if only one session is present.
15762 * In the case of BT_COEX and TDLS mode it blindly stop delack functionality.
15763 *
15764 * Return: void.
15765 */
15766void hdd_manage_delack_timer(hdd_context_t *pHddCtx)
15767{
15768 uint8_t sessions;
15769
15770 if (!pHddCtx->cfg_ini->enable_delack) {
15771 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_DEBUG,
15772 "%s: TCP DELACK is not enabled", __func__);
15773 return;
15774 }
15775
15776 /* Blindly stop timer of BTCOEX and TDLS Session is up */
15777 if (pHddCtx->mode != 0) {
15778 hdd_set_default_stop_delack_timer(pHddCtx);
15779 return;
15780 }
15781
15782 sessions = hdd_get_total_sessions(pHddCtx);
15783 if (sessions == 1) {
15784 hdd_update_prev_rx_packet_count(pHddCtx);
15785 hdd_start_delack_timer(pHddCtx);
15786 } else {
15787 hdd_set_default_stop_delack_timer(pHddCtx);
15788 }
15789}
15790
Mihir Shetee1093ba2014-01-21 20:13:32 +053015791/**---------------------------------------------------------------------------
15792 *
15793 * \brief wlan_hdd_init_channels
15794 *
15795 * This function is used to initialize the channel list in CSR
15796 *
15797 * This function is called from hdd_wlan_startup
15798 *
15799 * \param - pHddCtx: HDD context
15800 *
15801 * \return - VOS_STATUS_SUCCESS: Success
15802 * VOS_STATUS_E_FAULT: Failure reported by SME
15803
15804 * --------------------------------------------------------------------------*/
15805static VOS_STATUS wlan_hdd_init_channels(hdd_context_t *pHddCtx)
15806{
15807 eHalStatus status;
15808
15809 status = sme_InitChannels(pHddCtx->hHal);
15810 if (HAL_STATUS_SUCCESS(status))
15811 {
15812 return VOS_STATUS_SUCCESS;
15813 }
15814 else
15815 {
15816 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Channel initialization failed(%d)",
15817 __func__, status);
15818 return VOS_STATUS_E_FAULT;
15819 }
15820}
15821
Mihir Shete04206452014-11-20 17:50:58 +053015822#ifdef CONFIG_ENABLE_LINUX_REG
Agarwal Ashish6db9d532014-09-30 18:19:10 +053015823VOS_STATUS wlan_hdd_init_channels_for_cc(hdd_context_t *pHddCtx, driver_load_type init )
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053015824{
15825 eHalStatus status;
15826
Rajeev Kumar Sirasanagandlaf8fc27c2018-12-06 14:56:43 +053015827 if (init == INIT && init_by_reg_core_user) {
15828 init_by_reg_core_user = false;
15829 pr_info("driver regulatory hint is not required");
15830
15831 return VOS_STATUS_SUCCESS;
15832 }
15833
Agarwal Ashish6db9d532014-09-30 18:19:10 +053015834 status = sme_InitChannelsForCC(pHddCtx->hHal, init);
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053015835 if (HAL_STATUS_SUCCESS(status))
15836 {
15837 return VOS_STATUS_SUCCESS;
15838 }
15839 else
15840 {
15841 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Issue reg hint failed(%d)",
15842 __func__, status);
15843 return VOS_STATUS_E_FAULT;
15844 }
15845}
Mihir Shete04206452014-11-20 17:50:58 +053015846#endif
Sudhir Sattayappa Kohallib1d8c3a2013-06-18 14:47:20 -070015847/*
15848 * API to find if there is any STA or P2P-Client is connected
15849 */
15850VOS_STATUS hdd_issta_p2p_clientconnected(hdd_context_t *pHddCtx)
15851{
15852 return sme_isSta_p2p_clientConnected(pHddCtx->hHal);
15853}
Jeff Johnsone7245742012-09-05 17:12:55 -070015854
Mihir Shetee2ae82a2015-03-16 14:08:49 +053015855
15856/*
15857 * API to find if the firmware will send logs using DXE channel
15858 */
15859v_U8_t hdd_is_fw_logging_enabled(void)
15860{
15861 hdd_context_t *pHddCtx;
15862
15863 pHddCtx = vos_get_context(VOS_MODULE_ID_HDD,
15864 vos_get_global_context(VOS_MODULE_ID_HDD, NULL));
15865
Sravan Kumar Kairam1d5bf8e2019-03-21 00:33:56 +053015866 return (pHddCtx && pHddCtx->cfg_ini->wlanLoggingEnable &&
15867 pHddCtx->cfg_ini->enableMgmtLogging);
Mihir Shetee2ae82a2015-03-16 14:08:49 +053015868}
15869
Agarwal Ashish57e84372014-12-05 18:26:53 +053015870/*
Mihir Shetebe94ebb2015-05-26 12:07:14 +053015871 * API to find if the firmware will send trace logs using DXE channel
15872 */
15873v_U8_t hdd_is_fw_ev_logging_enabled(void)
15874{
15875 hdd_context_t *pHddCtx;
15876
15877 pHddCtx = vos_get_context(VOS_MODULE_ID_HDD,
15878 vos_get_global_context(VOS_MODULE_ID_HDD, NULL));
15879
Sravan Kumar Kairam1d5bf8e2019-03-21 00:33:56 +053015880 return (pHddCtx && pHddCtx->cfg_ini->wlanLoggingEnable &&
15881 pHddCtx->cfg_ini->enableFWLogging);
Mihir Shetebe94ebb2015-05-26 12:07:14 +053015882}
Sravan Kumar Kairam1d5bf8e2019-03-21 00:33:56 +053015883
Mihir Shetebe94ebb2015-05-26 12:07:14 +053015884/*
Agarwal Ashish57e84372014-12-05 18:26:53 +053015885 * API to find if there is any session connected
15886 */
15887VOS_STATUS hdd_is_any_session_connected(hdd_context_t *pHddCtx)
15888{
15889 return sme_is_any_session_connected(pHddCtx->hHal);
15890}
15891
15892
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053015893int wlan_hdd_scan_abort(hdd_adapter_t *pAdapter)
15894{
15895 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
15896 hdd_scaninfo_t *pScanInfo = NULL;
Girish Gowli4bf7a632014-06-12 13:42:11 +053015897 long status = 0;
c_hpothua3d45d52015-01-05 14:11:17 +053015898 tSirAbortScanStatus abortScanStatus;
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053015899
15900 pScanInfo = &pHddCtx->scan_info;
Ratnam Rachuric7681132015-06-30 10:35:13 +053015901 INIT_COMPLETION(pScanInfo->abortscan_event_var);
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053015902 if (pScanInfo->mScanPending)
15903 {
c_hpothua3d45d52015-01-05 14:11:17 +053015904 abortScanStatus = hdd_abort_mac_scan(pHddCtx, pScanInfo->sessionId,
15905 eCSR_SCAN_ABORT_DEFAULT);
15906 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15907 FL("abortScanStatus: %d"), abortScanStatus);
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053015908
c_hpothua3d45d52015-01-05 14:11:17 +053015909 /* If there is active scan command lets wait for the completion else
15910 * there is no need to wait as scan command might be in the SME pending
15911 * command list.
15912 */
15913 if (abortScanStatus == eSIR_ABORT_ACTIVE_SCAN_LIST_NOT_EMPTY)
15914 {
Mukul Sharmab392b642017-08-17 17:45:29 +053015915 status = wait_for_completion_timeout(
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053015916 &pScanInfo->abortscan_event_var,
15917 msecs_to_jiffies(5000));
c_hpothua3d45d52015-01-05 14:11:17 +053015918 if (0 >= status)
15919 {
15920 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Girish Gowli4bf7a632014-06-12 13:42:11 +053015921 "%s: Timeout or Interrupt occurred while waiting for abort"
15922 "scan, status- %ld", __func__, status);
c_hpothua3d45d52015-01-05 14:11:17 +053015923 return -ETIMEDOUT;
15924 }
15925 }
15926 else if (abortScanStatus == eSIR_ABORT_SCAN_FAILURE)
15927 {
15928 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15929 FL("hdd_abort_mac_scan failed"));
15930 return -VOS_STATUS_E_FAILURE;
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053015931 }
15932 }
Girish Gowli4bf7a632014-06-12 13:42:11 +053015933 return 0;
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053015934}
15935
Abhishek Singh7d624e12015-11-30 14:29:27 +053015936/**
15937 * hdd_indicate_mgmt_frame() - Wrapper to indicate management frame to
15938 * user space
15939 * @frame_ind: Management frame data to be informed.
15940 *
15941 * This function is used to indicate management frame to
15942 * user space
15943 *
15944 * Return: None
15945 *
15946 */
15947void hdd_indicate_mgmt_frame(tSirSmeMgmtFrameInd *frame_ind)
15948{
15949 hdd_context_t *hdd_ctx = NULL;
15950 hdd_adapter_t *adapter = NULL;
15951 v_CONTEXT_t vos_context = NULL;
Pragaspathi Thilagaraj4aa58d52019-05-27 18:35:26 +053015952 struct ieee80211_mgmt *mgmt =
15953 (struct ieee80211_mgmt *)frame_ind->frameBuf;
Abhishek Singh7d624e12015-11-30 14:29:27 +053015954
15955 /* Get the global VOSS context.*/
15956 vos_context = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
15957 if (!vos_context) {
15958 hddLog(LOGE, FL("Global VOS context is Null"));
15959 return;
15960 }
15961 /* Get the HDD context.*/
15962 hdd_ctx =
15963 (hdd_context_t *)vos_get_context(VOS_MODULE_ID_HDD, vos_context );
15964
15965 if (0 != wlan_hdd_validate_context(hdd_ctx))
15966 {
15967 return;
15968 }
Pragaspathi Thilagaraj4aa58d52019-05-27 18:35:26 +053015969
15970 if (frame_ind->frameLen < ieee80211_hdrlen(mgmt->frame_control)) {
15971 hddLog(LOGE, FL(" Invalid frame length"));
15972 return;
15973 }
15974
Abhishek Singh7d624e12015-11-30 14:29:27 +053015975 adapter = hdd_get_adapter_by_sme_session_id(hdd_ctx,
15976 frame_ind->sessionId);
15977
15978 if ((NULL != adapter) &&
15979 (WLAN_HDD_ADAPTER_MAGIC == adapter->magic))
15980 __hdd_indicate_mgmt_frame(adapter,
15981 frame_ind->frameLen,
15982 frame_ind->frameBuf,
15983 frame_ind->frameType,
15984 frame_ind->rxChan,
Pankaj Singh33205b82020-06-05 00:27:49 +053015985 frame_ind->rxRssi,
15986 frame_ind->rx_flags);
Abhishek Singh7d624e12015-11-30 14:29:27 +053015987 return;
15988
15989}
15990
c_hpothu225aa7c2014-10-22 17:45:13 +053015991VOS_STATUS wlan_hdd_cancel_remain_on_channel(hdd_context_t *pHddCtx)
15992{
15993 hdd_adapter_t *pAdapter;
15994 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
15995 VOS_STATUS vosStatus;
15996
15997 vosStatus = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
15998 while (NULL != pAdapterNode && VOS_STATUS_E_EMPTY != vosStatus)
15999 {
16000 pAdapter = pAdapterNode->pAdapter;
16001 if (NULL != pAdapter)
16002 {
16003 if (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode ||
16004 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode ||
16005 WLAN_HDD_P2P_GO == pAdapter->device_mode)
16006 {
16007 hddLog(LOG1, FL("abort ROC deviceMode: %d"),
16008 pAdapter->device_mode);
16009 if (VOS_STATUS_SUCCESS !=
16010 wlan_hdd_cancel_existing_remain_on_channel(pAdapter))
16011 {
16012 hddLog(LOGE, FL("failed to abort ROC"));
16013 return VOS_STATUS_E_FAILURE;
16014 }
16015 }
16016 }
16017 vosStatus = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
16018 pAdapterNode = pNext;
16019 }
16020 return VOS_STATUS_SUCCESS;
16021}
Mahesh A Saptasagard477b092015-02-06 15:12:16 +053016022
Mihir Shete0be28772015-02-17 18:42:14 +053016023hdd_remain_on_chan_ctx_t *hdd_get_remain_on_channel_ctx(hdd_context_t *pHddCtx)
16024{
16025 hdd_adapter_t *pAdapter;
16026 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
16027 hdd_cfg80211_state_t *cfgState;
16028 hdd_remain_on_chan_ctx_t *pRemainChanCtx = NULL;
16029 VOS_STATUS vosStatus;
16030
16031 vosStatus = hdd_get_front_adapter (pHddCtx, &pAdapterNode);
16032 while (NULL != pAdapterNode && VOS_STATUS_E_EMPTY != vosStatus)
16033 {
16034 pAdapter = pAdapterNode->pAdapter;
16035 if (NULL != pAdapter)
16036 {
16037 cfgState = WLAN_HDD_GET_CFG_STATE_PTR(pAdapter);
16038 pRemainChanCtx = cfgState->remain_on_chan_ctx;
16039 if (pRemainChanCtx)
16040 break;
16041 }
16042 vosStatus = hdd_get_next_adapter (pHddCtx, pAdapterNode, &pNext);
16043 pAdapterNode = pNext;
16044 }
16045 return pRemainChanCtx;
16046}
16047
Padma, Santhosh Kumar778d8382015-03-04 17:41:22 +053016048/**
16049 * wlan_hdd_handle_dfs_chan_scan () - handles disable/enable DFS channels
16050 *
16051 * @pHddCtx: HDD context within host driver
16052 * @dfsScanMode: dfsScanMode passed from ioctl
16053 *
16054 */
16055
16056VOS_STATUS wlan_hdd_handle_dfs_chan_scan(hdd_context_t *pHddCtx,
16057 tANI_U8 dfsScanMode)
16058{
16059 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
16060 hdd_adapter_t *pAdapter;
16061 VOS_STATUS vosStatus;
16062 hdd_station_ctx_t *pHddStaCtx;
16063 eHalStatus status = eHAL_STATUS_SUCCESS;
16064
16065 if(!pHddCtx)
16066 {
16067 hddLog(LOGE, FL("HDD context is Null"));
16068 return eHAL_STATUS_FAILURE;
16069 }
16070
16071 if (pHddCtx->scan_info.mScanPending)
16072 {
16073 hddLog(LOG1, FL("Aborting scan for sessionId: %d"),
16074 pHddCtx->scan_info.sessionId);
16075 hdd_abort_mac_scan(pHddCtx,
16076 pHddCtx->scan_info.sessionId,
16077 eCSR_SCAN_ABORT_DEFAULT);
16078 }
16079
16080 if (!dfsScanMode)
16081 {
16082 vosStatus = hdd_get_front_adapter( pHddCtx, &pAdapterNode);
16083 while ((NULL != pAdapterNode) &&
16084 (VOS_STATUS_SUCCESS == vosStatus))
16085 {
16086 pAdapter = pAdapterNode->pAdapter;
16087
16088 if (WLAN_HDD_INFRA_STATION == pAdapter->device_mode)
16089 {
16090 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
16091
16092 if(!pHddStaCtx)
16093 {
16094 hddLog(LOGE, FL("HDD STA context is Null"));
16095 return eHAL_STATUS_FAILURE;
16096 }
16097
16098 /* if STA is already connected on DFS channel,
16099 disconnect immediately*/
16100 if (hdd_connIsConnected(pHddStaCtx) &&
16101 (NV_CHANNEL_DFS ==
16102 vos_nv_getChannelEnabledState(
16103 pHddStaCtx->conn_info.operationChannel)))
16104 {
16105 status = sme_RoamDisconnect(pHddCtx->hHal,
16106 pAdapter->sessionId,
16107 eCSR_DISCONNECT_REASON_UNSPECIFIED);
16108 hddLog(LOG1, FL("Client connected on DFS channel %d,"
16109 "sme_RoamDisconnect returned with status: %d"
16110 "for sessionid: %d"), pHddStaCtx->conn_info.
16111 operationChannel, status, pAdapter->sessionId);
16112 }
16113 }
16114
16115 vosStatus = hdd_get_next_adapter(pHddCtx, pAdapterNode,
16116 &pNext);
16117 pAdapterNode = pNext;
16118 }
16119 }
16120
16121 sme_UpdateDFSScanMode(pHddCtx->hHal, dfsScanMode);
16122 sme_UpdateDFSRoamMode(pHddCtx->hHal,
16123 (dfsScanMode != DFS_CHNL_SCAN_DISABLED));
16124
16125 status = sme_HandleDFSChanScan(pHddCtx->hHal);
16126 if (!HAL_STATUS_SUCCESS(status))
16127 {
16128 hddLog(LOGE,
16129 FL("Failed in sme_HandleDFSChanScan (err=%d)"), status);
16130 return status;
16131 }
16132
16133 return status;
16134}
16135
Nirav Shah7e3c8132015-06-22 23:51:42 +053016136static int hdd_log2_ceil(unsigned value)
16137{
16138 /* need to switch to unsigned math so that negative values
16139 * will right-shift towards 0 instead of -1
16140 */
16141 unsigned tmp = value;
16142 int log2 = -1;
16143
16144 if (value == 0)
16145 return 0;
16146
16147 while (tmp) {
16148 log2++;
16149 tmp >>= 1;
16150 }
16151 if (1U << log2 != value)
16152 log2++;
16153
16154 return log2;
16155}
16156
16157/**
16158 * hdd_sta_id_hash_attach() - initialize sta id to macaddr hash
16159 * @pAdapter: adapter handle
16160 *
16161 * Return: vos status
16162 */
16163VOS_STATUS hdd_sta_id_hash_attach(hdd_adapter_t *pAdapter)
16164{
16165 int hash_elem, log2, i;
16166
16167 spin_lock_bh( &pAdapter->sta_hash_lock);
16168 if (pAdapter->is_sta_id_hash_initialized == VOS_TRUE) {
16169 spin_unlock_bh( &pAdapter->sta_hash_lock);
16170 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16171 "%s: hash already attached for session id %d",
16172 __func__, pAdapter->sessionId);
16173 return VOS_STATUS_SUCCESS;
16174 }
16175 spin_unlock_bh( &pAdapter->sta_hash_lock);
16176
16177 hash_elem = WLAN_MAX_STA_COUNT;
16178 hash_elem *= HDD_STA_ID_HASH_MULTIPLIER;
16179 log2 = hdd_log2_ceil(hash_elem);
16180 hash_elem = 1 << log2;
16181
16182 pAdapter->sta_id_hash.mask = hash_elem - 1;
16183 pAdapter->sta_id_hash.idx_bits = log2;
16184 pAdapter->sta_id_hash.bins =
16185 vos_mem_malloc(hash_elem *sizeof(hdd_list_t));
16186 if (!pAdapter->sta_id_hash.bins) {
16187 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16188 "%s: malloc failed for session %d",
16189 __func__, pAdapter->sessionId);
16190 return VOS_STATUS_E_NOMEM;
16191 }
16192
16193 for (i = 0; i < hash_elem; i++)
16194 hdd_list_init(&pAdapter->sta_id_hash.bins[i], WLAN_MAX_STA_COUNT);
16195
16196 spin_lock_bh( &pAdapter->sta_hash_lock);
16197 pAdapter->is_sta_id_hash_initialized = VOS_TRUE;
16198 spin_unlock_bh( &pAdapter->sta_hash_lock);
16199 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16200 "%s: Station ID Hash attached for session id %d",
16201 __func__, pAdapter->sessionId);
16202
16203 return VOS_STATUS_SUCCESS;
16204}
16205
16206/**
16207 * hdd_sta_id_hash_detach() - deinit sta_id to macaddr hash
16208 * @pAdapter: adapter handle
16209 *
16210 * Return: vos status
16211 */
16212VOS_STATUS hdd_sta_id_hash_detach(hdd_adapter_t *pAdapter)
16213{
16214 int hash_elem, i;
16215 v_SIZE_t size;
16216
16217 spin_lock_bh( &pAdapter->sta_hash_lock);
16218 if (pAdapter->is_sta_id_hash_initialized != VOS_TRUE) {
16219 spin_unlock_bh( &pAdapter->sta_hash_lock);
16220 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16221 "%s: hash not initialized for session id %d",
16222 __func__, pAdapter->sessionId);
16223 return VOS_STATUS_SUCCESS;
16224 }
16225
16226 pAdapter->is_sta_id_hash_initialized = VOS_FALSE;
16227 spin_unlock_bh( &pAdapter->sta_hash_lock);
16228
16229 hash_elem = 1 << pAdapter->sta_id_hash.idx_bits;
16230
16231 /* free all station info*/
16232 for (i = 0; i < hash_elem; i++) {
16233 hdd_list_size(&pAdapter->sta_id_hash.bins[i], &size);
16234 if (size != 0) {
16235 VOS_STATUS status;
16236 hdd_staid_hash_node_t *sta_info_node = NULL;
16237 hdd_staid_hash_node_t *next_node = NULL;
16238 status = hdd_list_peek_front ( &pAdapter->sta_id_hash.bins[i],
16239 (hdd_list_node_t**) &sta_info_node );
16240
16241 while ( NULL != sta_info_node && VOS_STATUS_SUCCESS == status )
16242 {
16243 status = hdd_list_remove_node( &pAdapter->sta_id_hash.bins[i],
16244 &sta_info_node->node);
16245 vos_mem_free(sta_info_node);
16246
16247 status = hdd_list_peek_next (&pAdapter->sta_id_hash.bins[i],
16248 (hdd_list_node_t*)sta_info_node,
16249 (hdd_list_node_t**)&next_node);
16250 sta_info_node = next_node;
16251 }
16252 }
16253 }
16254
16255 vos_mem_free(pAdapter->sta_id_hash.bins);
16256 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16257 "%s: Station ID Hash detached for session id %d",
16258 __func__, pAdapter->sessionId);
16259 return VOS_STATUS_SUCCESS;
16260}
16261
16262/**
16263 * hdd_sta_id_hash_calculate_index() - derive index from macaddr
16264 * @pAdapter: adapter handle
16265 * @mac_addr_in: input mac address
16266 *
16267 * Return: index derived from mac address
16268 */
16269int hdd_sta_id_hash_calculate_index(hdd_adapter_t *pAdapter,
16270 v_MACADDR_t *mac_addr_in)
16271{
16272 uint16 index;
16273 struct hdd_align_mac_addr_t * mac_addr =
16274 (struct hdd_align_mac_addr_t *)mac_addr_in;
16275
16276 index = mac_addr->bytes_ab ^
16277 mac_addr->bytes_cd ^ mac_addr->bytes_ef;
16278 index ^= index >> pAdapter->sta_id_hash.idx_bits;
16279 index &= pAdapter->sta_id_hash.mask;
16280 return index;
16281}
16282
16283/**
16284 * hdd_sta_id_hash_add_entry() - add entry in hash
16285 * @pAdapter: adapter handle
16286 * @sta_id: station id
16287 * @mac_addr: mac address
16288 *
16289 * Return: vos status
16290 */
16291VOS_STATUS hdd_sta_id_hash_add_entry(hdd_adapter_t *pAdapter,
16292 v_U8_t sta_id, v_MACADDR_t *mac_addr)
16293{
16294 uint16 index;
16295 hdd_staid_hash_node_t *sta_info_node = NULL;
16296
Nirav Shah7e3c8132015-06-22 23:51:42 +053016297 index = hdd_sta_id_hash_calculate_index(pAdapter, mac_addr);
16298 sta_info_node = vos_mem_malloc(sizeof(hdd_staid_hash_node_t));
16299 if (!sta_info_node) {
Nirav Shah7e3c8132015-06-22 23:51:42 +053016300 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16301 "%s: malloc failed", __func__);
16302 return VOS_STATUS_E_NOMEM;
16303 }
16304
16305 sta_info_node->sta_id = sta_id;
16306 vos_mem_copy(&sta_info_node->mac_addr, mac_addr, sizeof(v_MACADDR_t));
16307
Nirav Shah303ed5c2015-08-24 10:29:25 +053016308 spin_lock_bh( &pAdapter->sta_hash_lock);
16309 if (pAdapter->is_sta_id_hash_initialized != VOS_TRUE) {
16310 spin_unlock_bh( &pAdapter->sta_hash_lock);
16311 vos_mem_free(sta_info_node);
16312 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16313 "%s: hash is not initialized for session id %d",
16314 __func__, pAdapter->sessionId);
16315 return VOS_STATUS_E_FAILURE;
16316 }
16317
Nirav Shah7e3c8132015-06-22 23:51:42 +053016318 hdd_list_insert_back ( &pAdapter->sta_id_hash.bins[index],
16319 (hdd_list_node_t*) sta_info_node );
16320 spin_unlock_bh( &pAdapter->sta_hash_lock);
16321 return VOS_STATUS_SUCCESS;
16322}
16323
16324/**
16325 * hdd_sta_id_hash_remove_entry() - remove entry from hash
16326 * @pAdapter: adapter handle
16327 * @sta_id: station id
16328 * @mac_addr: mac address
16329 *
16330 * Return: vos status
16331 */
16332VOS_STATUS hdd_sta_id_hash_remove_entry(hdd_adapter_t *pAdapter,
16333 v_U8_t sta_id, v_MACADDR_t *mac_addr)
16334{
16335 uint16 index;
16336 VOS_STATUS status;
16337 hdd_staid_hash_node_t *sta_info_node = NULL;
16338 hdd_staid_hash_node_t *next_node = NULL;
16339
16340 spin_lock_bh( &pAdapter->sta_hash_lock);
16341 if (pAdapter->is_sta_id_hash_initialized != VOS_TRUE) {
16342 spin_unlock_bh( &pAdapter->sta_hash_lock);
16343 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16344 "%s: hash is not initialized for session id %d",
16345 __func__, pAdapter->sessionId);
16346 return VOS_STATUS_E_FAILURE;
16347 }
16348
16349 index = hdd_sta_id_hash_calculate_index(pAdapter, mac_addr);
16350 status = hdd_list_peek_front ( &pAdapter->sta_id_hash.bins[index],
16351 (hdd_list_node_t**) &sta_info_node );
16352
16353 while ( NULL != sta_info_node && VOS_STATUS_SUCCESS == status )
16354 {
16355 if (sta_info_node->sta_id == sta_id) {
16356 status = hdd_list_remove_node( &pAdapter->sta_id_hash.bins[index],
16357 &sta_info_node->node);
16358 vos_mem_free(sta_info_node);
16359 break;
16360 }
16361 status = hdd_list_peek_next (&pAdapter->sta_id_hash.bins[index],
16362 (hdd_list_node_t*)sta_info_node, (hdd_list_node_t**)&next_node);
16363 sta_info_node = next_node;
16364 }
16365 spin_unlock_bh( &pAdapter->sta_hash_lock);
16366 return status;
16367}
16368
16369/**
16370 * hdd_sta_id_find_from_mac_addr() - find sta id from mac address
16371 * @pAdapter: adapter handle
16372 * @mac_addr_in: mac address
16373 *
16374 * Return: station id
16375 */
16376int hdd_sta_id_find_from_mac_addr(hdd_adapter_t *pAdapter,
16377 v_MACADDR_t *mac_addr_in)
16378{
16379 uint8 is_found = 0;
16380 uint8 sta_id = HDD_WLAN_INVALID_STA_ID;
16381 uint16 index;
16382 VOS_STATUS status;
16383 hdd_staid_hash_node_t *sta_info_node = NULL;
16384 hdd_staid_hash_node_t *next_node = NULL;
16385
16386 spin_lock_bh( &pAdapter->sta_hash_lock);
16387 if (pAdapter->is_sta_id_hash_initialized != VOS_TRUE) {
16388 spin_unlock_bh( &pAdapter->sta_hash_lock);
Bhargav Shahce3b32c2015-08-10 12:29:24 +053016389 hddLog(VOS_TRACE_LEVEL_INFO,
Nirav Shah7e3c8132015-06-22 23:51:42 +053016390 FL("hash is not initialized for session id %d"),
16391 pAdapter->sessionId);
16392 return HDD_WLAN_INVALID_STA_ID;
16393 }
16394
16395 index = hdd_sta_id_hash_calculate_index(pAdapter, mac_addr_in);
16396 status = hdd_list_peek_front ( &pAdapter->sta_id_hash.bins[index],
16397 (hdd_list_node_t**) &sta_info_node );
16398
16399 while ( NULL != sta_info_node && VOS_STATUS_SUCCESS == status )
16400 {
16401 if (vos_mem_compare(&sta_info_node->mac_addr,
16402 mac_addr_in, sizeof(v_MACADDR_t))) {
16403 is_found = 1;
16404 sta_id = sta_info_node->sta_id;
16405 break;
16406 }
16407 status = hdd_list_peek_next (&pAdapter->sta_id_hash.bins[index],
16408 (hdd_list_node_t*)sta_info_node,
16409 (hdd_list_node_t**)&next_node);
16410 sta_info_node = next_node;
16411 }
16412 spin_unlock_bh( &pAdapter->sta_hash_lock);
16413 return sta_id;
16414}
16415
Mahesh A Saptasagar67ab9222015-10-21 15:38:41 +053016416void hdd_initialize_adapter_common(hdd_adapter_t *pAdapter)
16417{
16418 if (NULL == pAdapter)
16419 {
16420 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: pAdapter is NULL ", __func__);
16421 return;
16422 }
16423 init_completion(&pAdapter->session_open_comp_var);
16424 init_completion(&pAdapter->session_close_comp_var);
16425 init_completion(&pAdapter->disconnect_comp_var);
16426 init_completion(&pAdapter->linkup_event_var);
16427 init_completion(&pAdapter->cancel_rem_on_chan_var);
16428 init_completion(&pAdapter->rem_on_chan_ready_event);
16429 init_completion(&pAdapter->pno_comp_var);
16430#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
16431 init_completion(&pAdapter->offchannel_tx_event);
16432#endif
16433 init_completion(&pAdapter->tx_action_cnf_event);
16434#ifdef FEATURE_WLAN_TDLS
16435 init_completion(&pAdapter->tdls_add_station_comp);
16436 init_completion(&pAdapter->tdls_del_station_comp);
16437 init_completion(&pAdapter->tdls_mgmt_comp);
16438 init_completion(&pAdapter->tdls_link_establish_req_comp);
16439#endif
16440
16441#ifdef WLAN_FEATURE_RMC
16442 init_completion(&pAdapter->ibss_peer_info_comp);
16443#endif /* WLAN_FEATURE_RMC */
16444 init_completion(&pAdapter->ula_complete);
16445 init_completion(&pAdapter->change_country_code);
16446
16447#ifdef FEATURE_WLAN_BATCH_SCAN
16448 init_completion(&pAdapter->hdd_set_batch_scan_req_var);
16449 init_completion(&pAdapter->hdd_get_batch_scan_req_var);
16450#endif
Kapil Gupta2b44acb2016-12-30 16:49:51 +053016451 init_completion(&pAdapter->wlan_suspend_comp_var);
Mahesh A Saptasagar67ab9222015-10-21 15:38:41 +053016452
16453 return;
16454}
c_manjeecfd1efb2015-09-25 19:32:34 +053016455
Anurag Chouhan0b29de02016-12-16 13:18:40 +053016456#ifdef MDNS_OFFLOAD
16457
16458/**
16459 * hdd_mdns_enable_offload_done() - mdns enable offload response api
16460 * @padapter: holds adapter
16461 * @status: response status
16462 *
16463 * Return - None
16464 */
16465void hdd_mdns_enable_offload_done(void *padapter, VOS_STATUS status)
16466{
16467 hdd_adapter_t* adapter = (hdd_adapter_t*) padapter;
16468
16469 ENTER();
16470
16471 if (NULL == adapter)
16472 {
16473 hddLog(VOS_TRACE_LEVEL_ERROR,
16474 "%s: adapter is NULL",__func__);
16475 return;
16476 }
16477
16478 adapter->mdns_status.mdns_enable_status = status;
16479 vos_event_set(&adapter->mdns_status.vos_event);
16480 return;
16481}
16482
16483/**
16484 * hdd_mdns_fqdn_offload_done() - mdns fqdn offload response api
16485 * @padapter: holds adapter
16486 * @status: responce status
16487 *
16488 * Return - None
16489 */
16490void hdd_mdns_fqdn_offload_done(void *padapter, VOS_STATUS status)
16491{
16492 hdd_adapter_t* adapter = (hdd_adapter_t*) padapter;
16493
16494 ENTER();
16495
16496 if (NULL == adapter)
16497 {
16498 hddLog(VOS_TRACE_LEVEL_ERROR,
16499 "%s: adapter is NULL",__func__);
16500 return;
16501 }
16502
16503 adapter->mdns_status.mdns_fqdn_status = status;
16504 return;
16505}
16506
16507/**
16508 * hdd_mdns_resp_offload_done() - mdns resp offload response api
16509 * @padapter: holds adapter
16510 * @status: responce status
16511 *
16512 * Return - None
16513 */
16514void hdd_mdns_resp_offload_done(void *padapter, VOS_STATUS status)
16515{
16516 hdd_adapter_t* adapter = (hdd_adapter_t*) padapter;
16517
16518 ENTER();
16519
16520 if (NULL == adapter)
16521 {
16522 hddLog(VOS_TRACE_LEVEL_ERROR,
16523 "%s: adapter is NULL",__func__);
16524 return;
16525 }
16526
16527 adapter->mdns_status.mdns_resp_status = status;
16528 return;
16529}
16530
16531/**
16532 * wlan_hdd_mdns_process_response_dname() - Process mDNS domain name
16533 * @response: Pointer to a struct hdd_mdns_resp_info
16534 * @resp_info: Pointer to a struct tSirMDNSResponseInfo
16535 *
16536 * This function will pack the whole domain name without compression. It will
16537 * add the leading len for each field and add zero length octet to terminate
16538 * the domain name.
16539 *
16540 * Return: Return boolean. TRUE for success, FALSE for fail.
16541 */
16542static bool
16543wlan_hdd_mdns_process_response_dname(struct hdd_mdns_resp_info *response,
16544 sir_mdns_resp_info resp_info)
16545{
16546 uint8_t num;
16547 uint16_t idx;
16548 uint8_t len = 0;
16549
16550 if ((response == NULL) || (response->data == NULL) ||
16551 (response->offset == NULL)) {
16552 hddLog(LOGE, FL("Either data or offset in response is NULL!"));
16553 return FALSE;
16554 }
16555
16556 if ((resp_info == NULL) ||
16557 (resp_info->resp_len >= MAX_MDNS_RESP_LEN)) {
16558 hddLog(LOGE, FL("resp_len exceeds %d!"), MAX_MDNS_RESP_LEN);
16559 return FALSE;
16560 }
16561
16562 for (num = 0; num < response->num_entries; num++) {
16563 response->offset[num] =
16564 resp_info->resp_len + MDNS_HEADER_LEN;
16565 idx = num * MAX_LEN_DOMAINNAME_FIELD;
16566 len = strlen((char *)&response->data[idx]);
16567 if ((resp_info->resp_len + len + 1) >= MAX_MDNS_RESP_LEN) {
16568 hddLog(LOGE, FL("resp_len exceeds %d!"),
16569 MAX_MDNS_RESP_LEN);
16570 return FALSE;
16571 }
16572 resp_info->resp_data[resp_info->resp_len] = len;
16573 resp_info->resp_len++;
16574 vos_mem_copy(&resp_info->resp_data[resp_info->resp_len],
16575 &response->data[idx], len);
16576 resp_info->resp_len += len;
16577 }
16578
16579 /* The domain name terminates with the zero length octet */
16580 if (num == response->num_entries) {
16581 if (resp_info->resp_len >= MAX_MDNS_RESP_LEN) {
16582 hddLog(LOGE, FL("resp_len exceeds %d!"),
16583 MAX_MDNS_RESP_LEN);
16584 return FALSE;
16585 }
16586 resp_info->resp_data[resp_info->resp_len] = 0;
16587 resp_info->resp_len++;
16588 }
16589
16590 return TRUE;
16591}
16592
16593/**
16594 * wlan_hdd_mdns_format_response_u16() - Form uint16_t response data
16595 * @value: The uint16_t value is formed to the struct tSirMDNSResponseInfo
16596 * @resp_info: Pointer to a struct tSirMDNSResponseInfo
16597 *
16598 * Return: None
16599 */
16600static void wlan_hdd_mdns_format_response_u16(uint16_t value,
16601 sir_mdns_resp_info resp_info)
16602{
16603 uint8_t val_u8;
16604
16605 if ((resp_info == NULL) || (resp_info->resp_data == NULL))
16606 return;
16607 val_u8 = (value & 0xff00) >> 8;
16608 resp_info->resp_data[resp_info->resp_len++] = val_u8;
16609 val_u8 = value & 0xff;
16610 resp_info->resp_data[resp_info->resp_len++] = val_u8;
16611}
16612
16613/**
16614 * wlan_hdd_mdns_format_response_u32() - Form uint32_t response data
16615 * @value: The uint32_t value is formed to the struct tSirMDNSResponseInfo
16616 * @resp_info: Pointer to a struct tSirMDNSResponseInfo
16617 *
16618 * Return: None
16619 */
16620static void wlan_hdd_mdns_format_response_u32(uint32_t value,
16621 sir_mdns_resp_info resp_info)
16622{
16623 uint8_t val_u8;
16624
16625 if ((resp_info == NULL) || (resp_info->resp_data == NULL))
16626 return;
16627 val_u8 = (value & 0xff000000) >> 24;
16628 resp_info->resp_data[resp_info->resp_len++] = val_u8;
16629 val_u8 = (value & 0xff0000) >> 16;
16630 resp_info->resp_data[resp_info->resp_len++] = val_u8;
16631 val_u8 = (value & 0xff00) >> 8;
16632 resp_info->resp_data[resp_info->resp_len++] = val_u8;
16633 val_u8 = value & 0xff;
16634 resp_info->resp_data[resp_info->resp_len++] = val_u8;
16635}
16636
16637/**
16638 * wlan_hdd_mdns_process_response_misc() - Process misc info in mDNS response
16639 * @resp_type: Response type for mDNS
16640 * @resp_info: Pointer to a struct tSirMDNSResponseInfo
16641 *
16642 * This function will pack the response type, class and TTL (Time To Live).
16643 *
16644 * Return: Return boolean. TRUE for success, FALSE for fail.
16645 */
16646static bool wlan_hdd_mdns_process_response_misc(uint16_t resp_type,
16647 sir_mdns_resp_info resp_info)
16648{
16649 uint16_t len;
16650
16651 if (resp_info == NULL) {
16652 hddLog(LOGE, FL("resp_info is NULL!"));
16653 return FALSE;
16654 }
16655
16656 len = resp_info->resp_len + (2 * sizeof(uint16_t) + sizeof(uint32_t));
16657 if (len >= MAX_MDNS_RESP_LEN) {
16658 hddLog(LOGE, FL("resp_len exceeds %d!"), MAX_MDNS_RESP_LEN);
16659 return FALSE;
16660 }
16661
16662 /* Fill Type, Class, TTL */
16663 wlan_hdd_mdns_format_response_u16(resp_type, resp_info);
16664 wlan_hdd_mdns_format_response_u16(MDNS_CLASS, resp_info);
16665 wlan_hdd_mdns_format_response_u32(MDNS_TTL, resp_info);
16666
16667 return TRUE;
16668}
16669
16670/**
16671 * wlan_hdd_mdns_compress_data() - Compress the domain name in mDNS response
16672 * @resp_info: Pointer to a struct tSirMDNSResponseInfo
16673 * @response_dst: The response which domain name is compressed.
16674 * @response_src: The response which domain name is matched with response_dst.
16675 * Its offset is used for data compression.
16676 * @num_matched: The number of matched entries between response_dst and
16677 * response_src
16678 *
16679 * This function will form the different fields of domain name in response_dst
16680 * if any. Then use the offset of the matched domain name in response_src to
16681 * compress the matched domain name.
16682 *
16683 * Return: Return boolean. TRUE for success, FALSE for fail.
16684 */
16685static bool
16686wlan_hdd_mdns_compress_data(sir_mdns_resp_info resp_info,
16687 struct hdd_mdns_resp_info *response_dst,
16688 struct hdd_mdns_resp_info *response_src,
16689 uint8_t num_matched)
16690{
16691 uint8_t num, num_diff;
16692 uint16_t value, idx;
16693 uint8_t len = 0;
16694
16695 if ((response_src == NULL) || (response_dst == NULL) ||
16696 (resp_info == NULL)) {
16697 hddLog(LOGE, FL("response info is NULL!"));
16698 return FALSE;
16699 }
16700
16701 if (response_dst->num_entries < num_matched) {
16702 hddLog(LOGE, FL("num_entries is less than num_matched!"));
16703 return FALSE;
16704 }
16705
16706 if (resp_info->resp_len >= MAX_MDNS_RESP_LEN) {
16707 hddLog(LOGE, FL("resp_len exceeds %d!"), MAX_MDNS_RESP_LEN);
16708 return FALSE;
16709 }
16710
16711 num_diff = response_dst->num_entries - num_matched;
16712 if ((num_diff > 0) && (response_dst->data == NULL)) {
16713 hddLog(LOGE, FL("response_dst->data is NULL!"));
16714 return FALSE;
16715 }
16716
16717 /*
16718 * Handle the unmatched string at the beginning
16719 * Store the length of octets and the octets
16720 */
16721 for (num = 0; num < num_diff; num++) {
16722 response_dst->offset[num] =
16723 resp_info->resp_len + MDNS_HEADER_LEN;
16724 idx = num * MAX_LEN_DOMAINNAME_FIELD;
16725 len = strlen((char *)&response_dst->data[idx]);
16726 if ((resp_info->resp_len + len + 1) >= MAX_MDNS_RESP_LEN) {
16727 hddLog(LOGE, FL("resp_len exceeds %d!"),
16728 MAX_MDNS_RESP_LEN);
16729 return FALSE;
16730 }
16731 resp_info->resp_data[resp_info->resp_len] = len;
16732 resp_info->resp_len++;
16733 vos_mem_copy(&resp_info->resp_data[resp_info->resp_len],
16734 &response_dst->data[idx], len);
16735 resp_info->resp_len += len;
16736 }
16737 /*
16738 * Handle the matched string from the end
16739 * Just keep the offset and mask the leading two bit
16740 */
16741 if (response_src->num_entries >= num_matched) {
16742 num_diff = response_src->num_entries - num_matched;
16743 value = response_src->offset[num_diff];
16744 if (value > 0) {
16745 value |= 0xc000;
16746 if ((resp_info->resp_len + sizeof(uint16_t)) >=
16747 MAX_MDNS_RESP_LEN) {
16748 hddLog(LOGE, FL("resp_len exceeds %d!"),
16749 MAX_MDNS_RESP_LEN);
16750 return FALSE;
16751 }
16752 wlan_hdd_mdns_format_response_u16(value, resp_info);
16753 return TRUE;
16754 }
16755 }
16756 return FALSE;
16757}
16758
16759/**
16760 * wlan_hdd_mdns_reset_response() - Reset the response info
16761 * @response: The response which info is reset.
16762 *
16763 * Return: None
16764 */
16765static void wlan_hdd_mdns_reset_response(struct hdd_mdns_resp_info *response)
16766{
16767 if (response == NULL)
16768 return;
16769 response->num_entries = 0;
16770 response->data = NULL;
16771 response->offset = NULL;
16772}
16773
16774/**
16775 * wlan_hdd_mdns_init_response() - Initialize the response info
16776 * @response: The response which info is initiatized.
16777 * @resp_dname: The domain name string which might be tokenized.
16778 *
16779 * This function will allocate the memory for both response->data and
16780 * response->offset. Besides, it will also tokenize the domain name to some
16781 * entries and fill response->num_entries with the num of entries.
16782 *
16783 * Return: Return boolean. TRUE for success, FALSE for fail.
16784 */
16785static bool wlan_hdd_mdns_init_response(struct hdd_mdns_resp_info *response,
16786 uint8_t *resp_dname, char separator)
16787{
16788 uint16_t size;
16789
16790 if ((resp_dname == NULL) || (response == NULL)) {
16791 hddLog(LOGE, FL("resp_dname or response is NULL!"));
16792 return FALSE;
16793 }
16794
16795 size = MAX_NUM_FIELD_DOMAINNAME * MAX_LEN_DOMAINNAME_FIELD;
16796 response->data = vos_mem_malloc(size);
16797 if (response->data) {
16798 vos_mem_zero(response->data, size);
16799 if (VOS_STATUS_SUCCESS !=
16800 hdd_string_to_string_array((char *)resp_dname,
16801 response->data,
16802 separator,
16803 &response->num_entries,
16804 MAX_NUM_FIELD_DOMAINNAME,
16805 MAX_LEN_DOMAINNAME_FIELD)) {
16806 hddLog(LOGE, FL("hdd_string_to_string_array fail!"));
16807 goto err_init_resp;
16808 }
16809
16810 if ((response->num_entries > 0) &&
16811 (strlen((char *)&response->data[0]) > 0)) {
16812 size = sizeof(uint16_t) * response->num_entries;
16813 response->offset = vos_mem_malloc(size);
16814 if (response->offset) {
16815 vos_mem_zero(response->offset, size);
16816 return TRUE;
16817 }
16818 }
16819 }
16820
16821err_init_resp:
16822 if (response->data)
16823 vos_mem_free(response->data);
16824 wlan_hdd_mdns_reset_response(response);
16825 return FALSE;
16826}
16827
16828/**
16829 * wlan_hdd_mdns_find_entries_from_end() - Find the matched entries
16830 * @response1: The response info is used to be compared.
16831 * @response2: The response info is used to be compared.
16832 *
16833 * This function will find the matched entries from the end.
16834 *
16835 * Return: Return the number of the matched entries.
16836 */
16837static uint8_t
16838wlan_hdd_mdns_find_entries_from_end(struct hdd_mdns_resp_info *response1,
16839 struct hdd_mdns_resp_info *response2)
16840{
16841 uint8_t min, len1, i;
16842 uint16_t num1, num2;
16843 uint8_t num_matched = 0;
16844
16845 min = VOS_MIN(response1->num_entries, response2->num_entries);
16846
16847 for (i = 1; i <= min; i++) {
16848 num1 = (response1->num_entries - i);
16849 num1 *= MAX_LEN_DOMAINNAME_FIELD;
16850 num2 = (response2->num_entries - i);
16851 num2 *= MAX_LEN_DOMAINNAME_FIELD;
16852 len1 = strlen((char *)&response1->data[num1]);
16853
16854 if ((len1 == 0) ||
16855 (len1 != strlen((char *)&response2->data[num2])))
16856 break;
16857 if (memcmp(&response1->data[num1],
16858 &response2->data[num2], len1))
16859 break;
16860 else
16861 num_matched++;
16862 }
16863
16864 return num_matched;
16865}
16866
16867/**
16868 * wlan_hdd_mdns_find_max() - Find the maximum number of the matched entries
16869 * @matchedlist: Pointer to the array of struct hdd_mdns_resp_matched
16870 * @numlist: The number of the elements in the array matchedlist.
16871 *
16872 * Find the max number of the matched entries among the array matchedlist.
16873 *
16874 * Return: None
16875 */
16876static void wlan_hdd_mdns_find_max(struct hdd_mdns_resp_matched *matchedlist,
16877 uint8_t numlist)
16878{
16879 int j;
16880 struct hdd_mdns_resp_matched tmp;
16881
16882 /* At least two values are used for sorting */
16883 if ((numlist < 2) || (matchedlist == NULL)) {
16884 hddLog(LOGE, FL("At least two values are used for sorting!"));
16885 return;
16886 }
16887
16888 for (j = 0; j < numlist-1; j++) {
16889 if (matchedlist[j].num_matched >
16890 matchedlist[j+1].num_matched) {
16891 vos_mem_copy(&tmp, &matchedlist[j],
16892 sizeof(struct hdd_mdns_resp_matched));
16893 vos_mem_copy(&matchedlist[j], &matchedlist[j+1],
16894 sizeof(struct hdd_mdns_resp_matched));
16895 vos_mem_copy(&matchedlist[j+1], &tmp,
16896 sizeof(struct hdd_mdns_resp_matched));
16897 }
16898 }
16899}
16900
16901/**
16902 * wlan_hdd_mdns_pack_response_type_a() - Pack Type A response
16903 * @ini_config: Pointer to the struct hdd_config_t
16904 * @resp_info: Pointer to the struct tSirMDNSResponseInfo
16905 * @resptype_a: Pointer to the struct hdd_mdns_resp_info of Type A
16906 *
16907 * Type A response include QName, response type, class, TTL and Ipv4.
16908 *
16909 * Return: Return boolean. TRUE for success, FALSE for fail.
16910 */
16911static bool
16912wlan_hdd_mdns_pack_response_type_a(hdd_config_t *ini_config,
16913 sir_mdns_resp_info resp_info,
16914 struct hdd_mdns_resp_info *resptype_a)
16915{
16916 uint16_t value;
16917 uint32_t len;
16918
16919 ENTER();
16920 if ((ini_config == NULL) || (resp_info == NULL) ||
16921 (resptype_a == NULL)) {
16922 hddLog(LOGE, FL("ini_config or response info is NULL!"));
16923 return FALSE;
16924 }
16925
16926 /* No Type A response */
16927 if (strlen((char *)ini_config->mdns_resp_type_a) <= 0)
16928 return TRUE;
16929
16930 /* Wrong response is assigned, just ignore this response */
16931 if (!wlan_hdd_mdns_init_response(resptype_a,
16932 ini_config->mdns_resp_type_a, '.'))
16933 return TRUE;
16934
16935 /* Process response domain name */
16936 if (!wlan_hdd_mdns_process_response_dname(resptype_a, resp_info)) {
16937 hddLog(LOGE, FL("Fail to process mDNS response (%d)!"),
16938 MDNS_TYPE_A);
16939 return FALSE;
16940 }
16941
16942 /* Process response Type, Class, TTL */
16943 if (!wlan_hdd_mdns_process_response_misc(MDNS_TYPE_A, resp_info)) {
16944 hddLog(LOGE, FL("Fail to process mDNS misc response (%d)!"),
16945 MDNS_TYPE_A);
16946 return FALSE;
16947 }
16948
16949 /* Process response RDLength, RData */
16950 len = sizeof(uint16_t) + sizeof(uint32_t);
16951 len += resp_info->resp_len;
16952 if (len >= MAX_MDNS_RESP_LEN) {
16953 hddLog(LOGE, FL("resp_len exceeds %d!"), MAX_MDNS_RESP_LEN);
16954 return FALSE;
16955 }
16956 value = sizeof(uint32_t);
16957 wlan_hdd_mdns_format_response_u16(value, resp_info);
16958 wlan_hdd_mdns_format_response_u32(ini_config->mdns_resp_type_a_ipv4,
16959 resp_info);
16960
16961 EXIT();
16962 return TRUE;
16963}
16964
16965/**
16966 * wlan_hdd_mdns_pack_response_type_txt() - Pack Type Txt response
16967 * @ini_config: Pointer to the struct hdd_config_t
16968 * @resp_info: Pointer to the struct tSirMDNSResponseInfo
16969 * @resptype_txt: Pointer to the struct hdd_mdns_resp_info of Type txt
16970 * @resptype_a: Pointer to the struct hdd_mdns_resp_info of Type A
16971 *
16972 * Type Txt response include QName, response type, class, TTL and text content.
16973 * Also, it will find the matched QName from resptype_A and compress the data.
16974 *
16975 * Return: Return boolean. TRUE for success, FALSE for fail.
16976 */
16977static bool
16978wlan_hdd_mdns_pack_response_type_txt(hdd_config_t *ini_config,
16979 sir_mdns_resp_info resp_info,
16980 struct hdd_mdns_resp_info *resptype_txt,
16981 struct hdd_mdns_resp_info *resptype_a)
16982{
16983 uint8_t num_matched;
16984 uint8_t num;
16985 uint16_t idx;
16986 uint16_t value = 0;
16987 uint32_t len;
16988 uint32_t total_len;
16989 bool status;
16990 struct hdd_mdns_resp_info resptype_content;
16991
16992 ENTER();
16993
16994 if ((ini_config == NULL) || (resp_info == NULL) ||
16995 (resptype_txt == NULL)) {
16996 hddLog(LOGE, FL("ini_config or response info is NULL!"));
16997 return FALSE;
16998 }
16999
17000 /* No Type Txt response */
17001 if (strlen((char *)ini_config->mdns_resp_type_txt) <= 0)
17002 return TRUE;
17003
17004 /* Wrong response is assigned, just ignore this response */
17005 if (!wlan_hdd_mdns_init_response(resptype_txt,
17006 ini_config->mdns_resp_type_txt, '.'))
17007 return TRUE;
17008
17009 /*
17010 * For data compression
17011 * Check if any strings are matched with Type A response
17012 */
17013 if (resptype_a && (resptype_a->num_entries > 0)) {
17014 num_matched = wlan_hdd_mdns_find_entries_from_end(resptype_txt,
17015 resptype_a);
17016 if (num_matched > 0) {
17017 if (!wlan_hdd_mdns_compress_data(resp_info,
17018 resptype_txt, resptype_a, num_matched)) {
17019 hddLog(LOGE, FL("Fail to compress mDNS "
17020 "response (%d)!"), MDNS_TYPE_TXT);
17021 return FALSE;
17022 }
17023 } else {
17024 /*
17025 * num_matched is zero. Error!
17026 * At least ".local" is needed.
17027 */
17028 hddLog(LOGE, FL("No matched string! Fail to pack mDNS "
17029 "response (%d)!"), MDNS_TYPE_TXT);
17030 return FALSE;
17031 }
17032 } else {
17033 /* no TypeA response, so show the whole data */
17034 if (!wlan_hdd_mdns_process_response_dname(resptype_txt,
17035 resp_info)) {
17036 hddLog(LOGE, FL("Fail to process mDNS response (%d)!"),
17037 MDNS_TYPE_TXT);
17038 return FALSE;
17039 }
17040 }
17041
17042 /* Process response Type, Class, TTL */
17043 if (!wlan_hdd_mdns_process_response_misc(MDNS_TYPE_TXT, resp_info)) {
17044 hddLog(LOGE, FL("Fail to process mDNS misc response (%d)!"),
17045 MDNS_TYPE_TXT);
17046 return FALSE;
17047 }
17048
17049 /*
17050 * Process response RDLength, RData.
17051 * TypeTxt RData include len.
17052 */
17053 status = wlan_hdd_mdns_init_response(&resptype_content,
17054 ini_config->mdns_resp_type_txt_content,
17055 '/');
17056 if (status == FALSE) {
17057 hddLog(LOGE, FL("wlan_hdd_mdns_init_response FAIL"));
17058 return FALSE;
17059 }
17060
17061 for (num = 0; num < resptype_content.num_entries; num++) {
17062 idx = num * MAX_LEN_DOMAINNAME_FIELD;
17063 value += strlen((char *)&resptype_content.data[idx]);
17064 }
17065
17066 /* content len is uint16_t */
17067 total_len = sizeof(uint16_t);
17068 total_len += resp_info->resp_len + value +
17069 resptype_content.num_entries;
17070
17071 if (total_len >= MAX_MDNS_RESP_LEN) {
17072 hddLog(LOGE, FL("resp_len exceeds %d!"), MAX_MDNS_RESP_LEN);
17073 return FALSE;
17074 }
17075 wlan_hdd_mdns_format_response_u16(value + resptype_content.num_entries,
17076 resp_info);
17077
17078 for (num = 0; num < resptype_content.num_entries; num++) {
17079 idx = num * MAX_LEN_DOMAINNAME_FIELD;
17080 len = strlen((char *)&resptype_content.data[idx]);
17081 resp_info->resp_data[resp_info->resp_len] = len;
17082 resp_info->resp_len++;
17083
17084 vos_mem_copy(&resp_info->resp_data[resp_info->resp_len],
17085 &resptype_content.data[idx], len);
17086
17087 resp_info->resp_len += len;
17088 hddLog(LOG1, FL("index = %d, len = %d, str = %s"),
17089 num, len, &resptype_content.data[idx]);
17090 }
17091
17092 EXIT();
17093 return TRUE;
17094}
17095
17096/**
17097 * wlan_hdd_mdns_pack_response_type_ptr_dname() - Pack Type PTR domain name
17098 * @ini_config: Pointer to the struct hdd_config_t
17099 * @resp_info: Pointer to the struct tSirMDNSResponseInfo
17100 * @resptype_ptr_dn: Pointer to the struct hdd_mdns_resp_info of Type Ptr
17101 * domain name
17102 * @resptype_ptr: Pointer to the struct hdd_mdns_resp_info of Type Ptr
17103 * @resptype_txt: Pointer to the struct hdd_mdns_resp_info of Type Txt
17104 * @resptype_a: Pointer to the struct hdd_mdns_resp_info of Type A
17105 *
17106 * The Type Ptr response include Type PTR domain name in its data field.
17107 * Also, it will find the matched QName from the existing resptype_ptr,
17108 * resptype_txt, resptype_a and then compress the data.
17109 *
17110 * Return: Return boolean. TRUE for success, FALSE for fail.
17111 */
17112static bool
17113wlan_hdd_mdns_pack_response_type_ptr_dname(hdd_config_t *ini_config,
17114 sir_mdns_resp_info resp_info,
17115 struct hdd_mdns_resp_info *resptype_ptr_dn,
17116 struct hdd_mdns_resp_info *resptype_ptr,
17117 struct hdd_mdns_resp_info *resptype_txt,
17118 struct hdd_mdns_resp_info *resptype_a)
17119{
17120 uint8_t num_matched, numlist, size;
17121 struct hdd_mdns_resp_matched matchedlist[MAX_MDNS_RESP_TYPE-1];
17122 struct hdd_mdns_resp_info *resp;
17123
17124 if ((ini_config == NULL) || (resp_info == NULL) ||
17125 (resptype_ptr == NULL) || (resptype_ptr_dn == NULL)) {
17126 hddLog(LOGE, FL("ini_config or response info is NULL!"));
17127 return FALSE;
17128 }
17129
17130 /* No Type Ptr domain name response */
17131 if (strlen((char *)ini_config->mdns_resp_type_ptr_dname) <= 0)
17132 return TRUE;
17133
17134 /* Wrong response is assigned, just ignore this response */
17135 if (!wlan_hdd_mdns_init_response(resptype_ptr_dn,
17136 ini_config->mdns_resp_type_ptr_dname, '.'))
17137 return TRUE;
17138
17139 /*
17140 * For data compression
17141 * Check if any strings are matched with previous
17142 * response.
17143 */
17144 numlist = 0;
17145 size = (MAX_MDNS_RESP_TYPE-1);
17146 size *= sizeof(struct hdd_mdns_resp_matched);
17147 vos_mem_zero(matchedlist, size);
17148 num_matched = wlan_hdd_mdns_find_entries_from_end(resptype_ptr_dn,
17149 resptype_ptr);
17150 if (num_matched > 0) {
17151 matchedlist[numlist].num_matched = num_matched;
17152 matchedlist[numlist].type = MDNS_TYPE_PTR;
17153 numlist++;
17154 }
17155 if (resptype_txt && (resptype_txt->num_entries > 0)) {
17156 num_matched = wlan_hdd_mdns_find_entries_from_end(
17157 resptype_ptr_dn, resptype_txt);
17158 if (num_matched > 0) {
17159 matchedlist[numlist].num_matched = num_matched;
17160 matchedlist[numlist].type = MDNS_TYPE_TXT;
17161 numlist++;
17162 }
17163 }
17164 if (resptype_a && (resptype_a->num_entries > 0)) {
17165 num_matched = wlan_hdd_mdns_find_entries_from_end(
17166 resptype_ptr_dn,resptype_a);
17167 if (num_matched > 0) {
17168 matchedlist[numlist].num_matched = num_matched;
17169 matchedlist[numlist].type = MDNS_TYPE_A;
17170 numlist++;
17171 }
17172 }
17173 if (numlist > 0) {
17174 if (numlist > 1)
17175 wlan_hdd_mdns_find_max(matchedlist, numlist);
17176 resp = NULL;
17177 switch (matchedlist[numlist-1].type) {
17178 case MDNS_TYPE_A:
17179 resp = resptype_a;
17180 break;
17181 case MDNS_TYPE_TXT:
17182 resp = resptype_txt;
17183 break;
17184 case MDNS_TYPE_PTR:
17185 resp = resptype_ptr;
17186 break;
17187 default:
17188 hddLog(LOGE, FL("Fail to compress mDNS response "
17189 "(%d)!"), MDNS_TYPE_PTR_DNAME);
17190 return FALSE;
17191 }
17192 num_matched = matchedlist[numlist-1].num_matched;
17193 if (!wlan_hdd_mdns_compress_data(resp_info, resptype_ptr_dn,
17194 resp, num_matched)) {
17195 hddLog(LOGE, FL("Fail to compress mDNS response "
17196 "(%d)!"), MDNS_TYPE_PTR_DNAME);
17197 return FALSE;
17198 }
17199 } else {
17200 /* num = 0 -> no matched string */
17201 if (!wlan_hdd_mdns_process_response_dname(resptype_ptr_dn,
17202 resp_info)) {
17203 hddLog(LOGE, FL("Fail to process mDNS response (%d)!"),
17204 MDNS_TYPE_PTR_DNAME);
17205 return FALSE;
17206 }
17207 }
17208
17209 return TRUE;
17210}
17211
17212/**
17213 * wlan_hdd_mdns_pack_response_type_ptr() - Pack Type PTR response
17214 * @ini_config: Pointer to the struct hdd_config_t
17215 * @resp_info: Pointer to the struct tSirMDNSResponseInfo
17216 * @resptype_ptr: Pointer to the struct hdd_mdns_resp_info of Type Ptr
17217 * @resptype_ptr_dn: Pointer to the struct hdd_mdns_resp_info of Type Ptr
17218 * domain name
17219 * @resptype_txt: Pointer to the struct hdd_mdns_resp_info of Type Txt
17220 * @resptype_a: Pointer to the struct hdd_mdns_resp_info of Type A
17221 *
17222 * The Type Ptr response include QName, response type, class, TTL and
17223 * Type PTR domain name. Also, it will find the matched QName from the
17224 * existing resptype_txt, resptype_a and then compress the data.
17225 *
17226 * Return: Return boolean. TRUE for success, FALSE for fail.
17227 */
17228static bool
17229wlan_hdd_mdns_pack_response_type_ptr(hdd_config_t *ini_config,
17230 sir_mdns_resp_info resp_info,
17231 struct hdd_mdns_resp_info *resptype_ptr,
17232 struct hdd_mdns_resp_info *resptype_ptr_dn,
17233 struct hdd_mdns_resp_info *resptype_txt,
17234 struct hdd_mdns_resp_info *resptype_a)
17235{
17236 uint8_t num_matched, num_matched1;
17237 uint16_t value;
17238 uint8_t val_u8;
17239 uint32_t offset_data_len, len;
17240
17241 ENTER();
17242 if ((ini_config == NULL) || (resp_info == NULL) ||
17243 (resptype_ptr == NULL) || (resptype_ptr_dn == NULL)) {
17244 hddLog(LOGE, FL("ini_config or response info is NULL!"));
17245 return FALSE;
17246 }
17247
17248 /* No Type Ptr response */
17249 if (strlen((char *)ini_config->mdns_resp_type_ptr) <= 0)
17250 return TRUE;
17251
17252 /* Wrong response is assigned, just ignore this response */
17253 if (!wlan_hdd_mdns_init_response(resptype_ptr,
17254 ini_config->mdns_resp_type_ptr, '.'))
17255 return TRUE;
17256
17257 /*
17258 * For data compression
17259 * Check if any strings are matched with Type A response
17260 */
17261 num_matched = 0;
17262 num_matched1 = 0;
17263 if (resptype_a && (resptype_a->num_entries > 0)) {
17264 num_matched = wlan_hdd_mdns_find_entries_from_end(resptype_ptr,
17265 resptype_a);
17266 }
17267 if (resptype_txt && (resptype_txt->num_entries > 0)) {
17268 num_matched1 = wlan_hdd_mdns_find_entries_from_end(
17269 resptype_ptr, resptype_txt);
17270 }
17271 if ((num_matched != num_matched1) ||
17272 ((num_matched > 0) && (num_matched1 > 0))) {
17273 if (num_matched >= num_matched1) {
17274 if (!wlan_hdd_mdns_compress_data(resp_info,
17275 resptype_ptr, resptype_a, num_matched)) {
17276 hddLog(LOGE, FL("Fail to compress mDNS "
17277 "response (%d)!"), MDNS_TYPE_PTR);
17278 return FALSE;
17279 }
17280 } else {
17281 /* num_matched is less than num_matched1 */
17282 if (!wlan_hdd_mdns_compress_data(resp_info,
17283 resptype_ptr, resptype_txt, num_matched1)) {
17284 hddLog(LOGE, FL("Fail to compress mDNS "
17285 "response (%d)!"), MDNS_TYPE_PTR);
17286 return FALSE;
17287 }
17288 }
17289 } else {
17290 /*
17291 * Both num_matched and num_matched1 are zero.
17292 * no TypeA & TypeTxt
17293 */
17294 if (!wlan_hdd_mdns_process_response_dname(resptype_ptr,
17295 resp_info)) {
17296 hddLog(LOGE, FL("Fail to process mDNS response (%d)!"),
17297 MDNS_TYPE_PTR);
17298 return FALSE;
17299 }
17300 }
17301
17302 /* Process response Type, Class, TTL */
17303 if (!wlan_hdd_mdns_process_response_misc(MDNS_TYPE_PTR, resp_info)) {
17304 hddLog(LOGE, FL("Fail to process mDNS misc response (%d)!"),
17305 MDNS_TYPE_PTR);
17306 return FALSE;
17307 }
17308
17309 /*
17310 * Process response RDLength, RData (Ptr domain name)
17311 * Save the offset of RData length
17312 */
17313 offset_data_len = resp_info->resp_len;
17314 resp_info->resp_len += sizeof(uint16_t);
17315
17316 if (!wlan_hdd_mdns_pack_response_type_ptr_dname(ini_config, resp_info,
17317 resptype_ptr_dn, resptype_ptr,
17318 resptype_txt, resptype_a)) {
17319 return FALSE;
17320 }
17321 /* Set the RData length */
17322 len = offset_data_len + sizeof(uint16_t);
17323 if ((resptype_ptr_dn->num_entries > 0) &&
17324 (resp_info->resp_len > len)) {
17325 value = resp_info->resp_len - len;
17326 val_u8 = (value & 0xff00) >> 8;
17327 resp_info->resp_data[offset_data_len] = val_u8;
17328 val_u8 = value & 0xff;
17329 resp_info->resp_data[offset_data_len+1] = val_u8;
17330 } else {
17331 hddLog(LOGE, FL("Fail to process mDNS response (%d)!"),
17332 MDNS_TYPE_PTR);
17333 return FALSE;
17334 }
17335
17336 EXIT();
17337 return TRUE;
17338}
17339
17340/**
17341 * wlan_hdd_mdns_pack_response_type_srv_target()- Pack Type Service Target
17342 * @ini_config: Pointer to the struct hdd_config_t
17343 * @resp_info: Pointer to the struct tSirMDNSResponseInfo
17344 * @resptype_srv_tgt: Pointer to the struct hdd_mdns_resp_info of Type Srv
17345 * target
17346 * @resptype_srv: Pointer to the struct hdd_mdns_resp_info of Type Srv
17347 * @resptype_ptr: Pointer to the struct hdd_mdns_resp_info of Type Ptr
17348 * @resptype_ptr_dn: Pointer to the struct hdd_mdns_resp_info of Type Ptr
17349 * domain name
17350 * @resptype_txt: Pointer to the struct hdd_mdns_resp_info of Type Txt
17351 * @resptype_a: Pointer to the struct hdd_mdns_resp_info of Type A
17352 *
17353 * The Type service target is one of the data field in the Type SRV response.
17354 * Also, it will find the matched QName from the existing resptype_srv,
17355 * resptype_ptr, resptype_ptr_dn, resptype_txt, resptype_a and then compress
17356 * the data.
17357 *
17358 * Return: Return boolean. TRUE for success, FALSE for fail.
17359 */
17360static bool
17361wlan_hdd_mdns_pack_response_type_srv_target(hdd_config_t *ini_config,
17362 sir_mdns_resp_info resp_info,
17363 struct hdd_mdns_resp_info *resptype_srv_tgt,
17364 struct hdd_mdns_resp_info *resptype_srv,
17365 struct hdd_mdns_resp_info *resptype_ptr,
17366 struct hdd_mdns_resp_info *resptype_ptr_dn,
17367 struct hdd_mdns_resp_info *resptype_txt,
17368 struct hdd_mdns_resp_info *resptype_a)
17369{
17370 uint8_t num_matched, num, size;
17371 struct hdd_mdns_resp_matched matchedlist[MAX_MDNS_RESP_TYPE-1];
17372 struct hdd_mdns_resp_info *resp;
17373
17374 if ((ini_config == NULL) || (resp_info == NULL) ||
17375 (resptype_srv == NULL) || (resptype_srv_tgt == NULL)) {
17376 hddLog(LOGE, FL("ini_config or response info is NULL!"));
17377 return FALSE;
17378 }
17379
17380 /* No Type Srv Target response */
17381 if (strlen((char *)ini_config->mdns_resp_type_srv_target) <= 0)
17382 return TRUE;
17383
17384 /* Wrong response is assigned, just ignore this response */
17385 if (!wlan_hdd_mdns_init_response(resptype_srv_tgt,
17386 ini_config->mdns_resp_type_srv_target, '.'))
17387 return TRUE;
17388
17389 /*
17390 * For data compression
17391 * Check if any strings are matched with previous response.
17392 */
17393 num = 0;
17394 size = (MAX_MDNS_RESP_TYPE-1);
17395 size *= sizeof(struct hdd_mdns_resp_matched);
17396 vos_mem_zero(matchedlist, size);
17397 num_matched = wlan_hdd_mdns_find_entries_from_end(resptype_srv_tgt,
17398 resptype_srv);
17399 if (num_matched > 0) {
17400 matchedlist[num].num_matched = num_matched;
17401 matchedlist[num].type = MDNS_TYPE_SRV;
17402 num++;
17403 }
17404 if (resptype_ptr && (resptype_ptr->num_entries > 0)) {
17405 if (resptype_ptr_dn && (resptype_ptr_dn->num_entries > 0)) {
17406 num_matched = wlan_hdd_mdns_find_entries_from_end(
17407 resptype_srv_tgt, resptype_ptr_dn);
17408 if (num_matched > 0) {
17409 matchedlist[num].num_matched = num_matched;
17410 matchedlist[num].type = MDNS_TYPE_PTR_DNAME;
17411 num++;
17412 }
17413 }
17414 num_matched = wlan_hdd_mdns_find_entries_from_end(
17415 resptype_srv_tgt, resptype_ptr);
17416 if (num_matched > 0) {
17417 matchedlist[num].num_matched = num_matched;
17418 matchedlist[num].type = MDNS_TYPE_PTR;
17419 num++;
17420 }
17421 }
17422 if (resptype_txt && (resptype_txt->num_entries > 0)) {
17423 num_matched = wlan_hdd_mdns_find_entries_from_end(
17424 resptype_srv_tgt, resptype_txt);
17425 if (num_matched > 0) {
17426 matchedlist[num].num_matched = num_matched;
17427 matchedlist[num].type = MDNS_TYPE_TXT;
17428 num++;
17429 }
17430 }
17431 if (resptype_a && (resptype_a->num_entries > 0)) {
17432 num_matched = wlan_hdd_mdns_find_entries_from_end(
17433 resptype_srv_tgt, resptype_a);
17434 if (num_matched > 0) {
17435 matchedlist[num].num_matched = num_matched;
17436 matchedlist[num].type = MDNS_TYPE_A;
17437 num++;
17438 }
17439 }
17440 if (num > 0) {
17441 if (num > 1)
17442 wlan_hdd_mdns_find_max(matchedlist, num);
17443 resp = NULL;
17444 switch (matchedlist[num-1].type) {
17445 case MDNS_TYPE_A:
17446 resp = resptype_a;
17447 break;
17448 case MDNS_TYPE_TXT:
17449 resp = resptype_txt;
17450 break;
17451 case MDNS_TYPE_PTR:
17452 resp = resptype_ptr;
17453 break;
17454 case MDNS_TYPE_PTR_DNAME:
17455 resp = resptype_ptr_dn;
17456 break;
17457 case MDNS_TYPE_SRV:
17458 resp = resptype_srv;
17459 break;
17460 default:
17461 hddLog(LOGE, FL("Fail to compress mDNS response "
17462 "(%d)!"), MDNS_TYPE_SRV_TARGET);
17463 return FALSE;
17464 }
17465 num_matched = matchedlist[num-1].num_matched;
17466 if (!wlan_hdd_mdns_compress_data(resp_info, resptype_srv_tgt,
17467 resp, num_matched)) {
17468 hddLog(LOGE, FL("Fail to compress mDNS response "
17469 "(%d)!"), MDNS_TYPE_SRV_TARGET);
17470 return FALSE;
17471 }
17472 } else {
17473 /* num = 0 -> no matched string */
17474 if (!wlan_hdd_mdns_process_response_dname(resptype_srv_tgt,
17475 resp_info)) {
17476 hddLog(LOGE, FL("Fail to process mDNS response (%d)!"),
17477 MDNS_TYPE_SRV_TARGET);
17478 return FALSE;
17479 }
17480 }
17481
17482 return TRUE;
17483}
17484
17485/**
17486 * wlan_hdd_mdns_pack_response_type_srv()- Pack Type Service response
17487 * @ini_config: Pointer to the struct hdd_config_t
17488 * @resp_info: Pointer to the struct tSirMDNSResponseInfo
17489 * @resptype_srv: Pointer to the struct hdd_mdns_resp_info of Type Srv
17490 * @resptype_srv_tgt: Pointer to the struct hdd_mdns_resp_info of Type Srv
17491 * target
17492 * @resptype_ptr: Pointer to the struct hdd_mdns_resp_info of Type Ptr
17493 * @resptype_ptr_dn: Pointer to the struct hdd_mdns_resp_info of Type Ptr
17494 * domain name
17495 * @resptype_txt: Pointer to the struct hdd_mdns_resp_info of Type Txt
17496 * @resptype_a: Pointer to the struct hdd_mdns_resp_info of Type A
17497 *
17498 * The Type SRV (Service) response include QName, response type, class, TTL
17499 * and four kinds of data fields. Also, it will find the matched QName from
17500 * the existing resptype_ptr, resptype_ptr_dn, resptype_txt, resptype_a and
17501 * then compress the data.
17502 *
17503 * Return: Return boolean. TRUE for success, FALSE for fail.
17504 */
17505static bool
17506wlan_hdd_mdns_pack_response_type_srv(hdd_config_t *ini_config,
17507 sir_mdns_resp_info resp_info,
17508 struct hdd_mdns_resp_info *resptype_srv,
17509 struct hdd_mdns_resp_info *resptype_srv_tgt,
17510 struct hdd_mdns_resp_info *resptype_ptr,
17511 struct hdd_mdns_resp_info *resptype_ptr_dn,
17512 struct hdd_mdns_resp_info *resptype_txt,
17513 struct hdd_mdns_resp_info *resptype_a)
17514{
17515 uint8_t num_matched, num, size;
17516 uint16_t value;
17517 uint8_t val_u8;
17518 uint32_t offset_data_len, len;
17519 struct hdd_mdns_resp_info *resp;
17520 struct hdd_mdns_resp_matched matchedlist[MAX_MDNS_RESP_TYPE-1];
17521
17522 ENTER();
17523
17524 if ((ini_config == NULL) || (resp_info == NULL) ||
17525 (resptype_srv == NULL) || (resptype_srv_tgt == NULL)) {
17526 hddLog(LOGE, FL("ini_config or response info is NULL!"));
17527 return FALSE;
17528 }
17529
17530 /* No Type Srv response */
17531 if (strlen((char *)ini_config->mdns_resp_type_srv) <= 0)
17532 return TRUE;
17533
17534 /* Wrong response is assigned, just ignore this response */
17535 if (!wlan_hdd_mdns_init_response(resptype_srv,
17536 ini_config->mdns_resp_type_srv, '.'))
17537 return TRUE;
17538
17539 /*
17540 * For data compression
17541 * Check if any strings are matched with Type A response
17542 */
17543 num = 0;
17544 size = (MAX_MDNS_RESP_TYPE-1);
17545 size *= sizeof(struct hdd_mdns_resp_matched);
17546 vos_mem_zero(matchedlist, size);
17547 if (resptype_ptr && (resptype_ptr->num_entries > 0)) {
17548 if (resptype_ptr_dn && (resptype_ptr_dn->num_entries > 0)) {
17549 num_matched = wlan_hdd_mdns_find_entries_from_end(
17550 resptype_srv,
17551 resptype_ptr_dn);
17552 if (num_matched > 0) {
17553 matchedlist[num].num_matched = num_matched;
17554 matchedlist[num].type = MDNS_TYPE_PTR_DNAME;
17555 num++;
17556 }
17557 }
17558 num_matched = wlan_hdd_mdns_find_entries_from_end(resptype_srv,
17559 resptype_ptr);
17560 if (num_matched > 0) {
17561 matchedlist[num].num_matched = num_matched;
17562 matchedlist[num].type = MDNS_TYPE_PTR;
17563 num++;
17564 }
17565 }
17566 if (resptype_txt && (resptype_txt->num_entries > 0)) {
17567 num_matched = wlan_hdd_mdns_find_entries_from_end(resptype_srv,
17568 resptype_txt);
17569 if (num_matched > 0) {
17570 matchedlist[num].num_matched =num_matched;
17571 matchedlist[num].type = MDNS_TYPE_TXT;
17572 num++;
17573 }
17574 }
17575 if (resptype_a && (resptype_a->num_entries > 0)) {
17576 num_matched = wlan_hdd_mdns_find_entries_from_end(resptype_srv,
17577 resptype_a);
17578 if (num_matched > 0) {
17579 matchedlist[num].num_matched = num_matched;
17580 matchedlist[num].type = MDNS_TYPE_A;
17581 num++;
17582 }
17583 }
17584 if (num > 0) {
17585 if (num > 1)
17586 wlan_hdd_mdns_find_max(matchedlist, num);
17587 resp = NULL;
17588 switch (matchedlist[num-1].type) {
17589 case MDNS_TYPE_A:
17590 resp = resptype_a;
17591 break;
17592 case MDNS_TYPE_TXT:
17593 resp = resptype_txt;
17594 break;
17595 case MDNS_TYPE_PTR:
17596 resp = resptype_ptr;
17597 break;
17598 case MDNS_TYPE_PTR_DNAME:
17599 resp = resptype_ptr_dn;
17600 break;
17601 default:
17602 hddLog(LOGE, FL("Fail to compress mDNS response "
17603 "(%d)!"), MDNS_TYPE_SRV);
17604 return FALSE;
17605 }
17606 num_matched = matchedlist[num-1].num_matched;
17607 if (!wlan_hdd_mdns_compress_data(resp_info, resptype_srv,
17608 resp, num_matched)) {
17609 hddLog(LOGE, FL("Fail to compress mDNS response "
17610 "(%d)!"), MDNS_TYPE_SRV);
17611 return FALSE;
17612 }
17613 } else {
17614 /* num = 0 -> no matched string */
17615 if (!wlan_hdd_mdns_process_response_dname(resptype_srv,
17616 resp_info)) {
17617 hddLog(LOGE, FL("Fail to process mDNS response (%d)!"),
17618 MDNS_TYPE_SRV);
17619 return FALSE;
17620 }
17621 }
17622
17623 /* Process response Type, Class, TTL */
17624 if (!wlan_hdd_mdns_process_response_misc(MDNS_TYPE_SRV, resp_info)) {
17625 hddLog(LOGE, FL("Fail to process mDNS misc response (%d)!"),
17626 MDNS_TYPE_SRV);
17627 return FALSE;
17628 }
17629
17630 /*
17631 * Process response RDLength, RData (Srv target name)
17632 * Save the offset of RData length
17633 */
17634 offset_data_len = resp_info->resp_len;
17635 resp_info->resp_len += sizeof(uint16_t);
17636
17637 len = resp_info->resp_len + (3 * sizeof(uint16_t));
17638 if (len >= MAX_MDNS_RESP_LEN) {
17639 hddLog(LOGE, FL("resp_len exceeds %d!"), MAX_MDNS_RESP_LEN);
17640 return FALSE;
17641 }
17642
17643 /* set Srv Priority */
17644 value = ini_config->mdns_resp_type_srv_priority;
17645 wlan_hdd_mdns_format_response_u16(value, resp_info);
17646 /* set Srv Weight */
17647 value = ini_config->mdns_resp_type_srv_weight;
17648 wlan_hdd_mdns_format_response_u16(value, resp_info);
17649 /* set Srv Port */
17650 value = ini_config->mdns_resp_type_srv_port;
17651 wlan_hdd_mdns_format_response_u16(value, resp_info);
17652
17653 if (!wlan_hdd_mdns_pack_response_type_srv_target(ini_config, resp_info,
17654 resptype_srv_tgt, resptype_srv,
17655 resptype_ptr, resptype_ptr_dn,
17656 resptype_txt, resptype_a)) {
17657 return FALSE;
17658 }
17659 /* Set the RData length */
17660 len = offset_data_len + sizeof(uint16_t);
17661 if ((resptype_srv_tgt->num_entries > 0) &&
17662 (resp_info->resp_len > len)) {
17663 value = resp_info->resp_len - len;
17664 val_u8 = (value & 0xff00) >> 8;
17665 resp_info->resp_data[offset_data_len] = val_u8;
17666 val_u8 = value & 0xff;
17667 resp_info->resp_data[offset_data_len+1] = val_u8;
17668 } else {
17669 hddLog(LOGE, FL("Fail to process mDNS response (%d)!"),
17670 MDNS_TYPE_SRV);
17671 return FALSE;
17672 }
17673
17674 EXIT();
17675 return TRUE;
17676}
17677
17678/**
17679 * wlan_hdd_mdns_free_mem() - Free the allocated memory
17680 * @response: Pointer to the struct hdd_mdns_resp_info
17681 *
17682 * Return: None
17683 */
17684static void wlan_hdd_mdns_free_mem(struct hdd_mdns_resp_info *response)
17685{
17686 if (response && response->data)
17687 vos_mem_free(response->data);
17688 if (response && response->offset)
17689 vos_mem_free(response->offset);
17690}
17691
17692/**
17693 * wlan_hdd_mdns_pack_response() - Pack mDNS response
17694 * @ini_config: Pointer to the struct hdd_config_t
17695 * @resp_info: Pointer to the struct tSirMDNSResponseInfo
17696 *
17697 * This function will pack four types of responses (Type A, Type Txt, Type Ptr
17698 * and Type Service). Each response contains QName, response type, class, TTL
17699 * and data fields.
17700 *
17701 * Return: Return boolean. TRUE for success, FALSE for fail.
17702 */
17703static bool wlan_hdd_mdns_pack_response(hdd_config_t *ini_config,
17704 sir_mdns_resp_info resp_info)
17705{
17706 struct hdd_mdns_resp_info resptype_a, resptype_txt;
17707 struct hdd_mdns_resp_info resptype_ptr, resptype_ptr_dn;
17708 struct hdd_mdns_resp_info resptype_srv, resptype_srv_tgt;
17709 uint32_t num_res_records = 0;
17710 bool status = FALSE;
17711
17712 ENTER();
17713
17714 wlan_hdd_mdns_reset_response(&resptype_a);
17715 wlan_hdd_mdns_reset_response(&resptype_txt);
17716 wlan_hdd_mdns_reset_response(&resptype_ptr);
17717 wlan_hdd_mdns_reset_response(&resptype_ptr_dn);
17718 wlan_hdd_mdns_reset_response(&resptype_srv);
17719 wlan_hdd_mdns_reset_response(&resptype_srv_tgt);
17720
17721 resp_info->resp_len = 0;
17722
17723 /* Process Type A response */
17724 if (!wlan_hdd_mdns_pack_response_type_a(ini_config, resp_info,
17725 &resptype_a))
17726 goto err_resptype_a;
17727
17728 if ((resptype_a.num_entries > 0) &&
17729 (strlen((char *)&resptype_a.data[0]) > 0))
17730 num_res_records++;
17731
17732 /* Process Type TXT response */
17733 if (!wlan_hdd_mdns_pack_response_type_txt(ini_config, resp_info,
17734 &resptype_txt, &resptype_a))
17735 goto err_resptype_txt;
17736
17737 if ((resptype_txt.num_entries > 0) &&
17738 (strlen((char *)&resptype_txt.data[0]) > 0))
17739 num_res_records++;
17740
17741 /* Process Type PTR response */
17742 if (!wlan_hdd_mdns_pack_response_type_ptr(ini_config, resp_info,
17743 &resptype_ptr, &resptype_ptr_dn,
17744 &resptype_txt, &resptype_a))
17745 goto err_resptype_ptr;
17746
17747 if ((resptype_ptr.num_entries > 0) &&
17748 (strlen((char *)&resptype_ptr.data[0]) > 0))
17749 num_res_records++;
17750
17751 /* Process Type SRV response */
17752 if (!wlan_hdd_mdns_pack_response_type_srv(ini_config, resp_info,
17753 &resptype_srv, &resptype_srv_tgt,
17754 &resptype_ptr, &resptype_ptr_dn,
17755 &resptype_txt, &resptype_a))
17756 goto err_resptype_srv;
17757
17758 if ((resptype_srv.num_entries > 0) &&
17759 (strlen((char *)&resptype_srv.data[0]) > 0))
17760 num_res_records++;
17761
17762 resp_info->resourceRecord_count = num_res_records;
17763 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
17764 "%s: Pack mDNS response data successfully!", __func__);
17765 status = TRUE;
17766
17767err_resptype_srv:
17768 wlan_hdd_mdns_free_mem(&resptype_srv);
17769 wlan_hdd_mdns_free_mem(&resptype_srv_tgt);
17770
17771err_resptype_ptr:
17772 wlan_hdd_mdns_free_mem(&resptype_ptr);
17773 wlan_hdd_mdns_free_mem(&resptype_ptr_dn);
17774
17775err_resptype_txt:
17776 wlan_hdd_mdns_free_mem(&resptype_txt);
17777
17778err_resptype_a:
17779 wlan_hdd_mdns_free_mem(&resptype_a);
17780
17781 EXIT();
17782 return status;
17783}
17784
17785/**
17786 * wlan_hdd_set_mdns_offload() - Enable mDNS offload
17787 * @hostapd_adapter: Pointer to the struct hdd_adapter_t
17788 *
17789 * This function will set FQDN/unique FQDN (full qualified domain name)
17790 * and the mDNS response. Then send them to SME.
17791 *
17792 * Return: Return boolean. TRUE for success, FALSE for fail.
17793 */
17794bool wlan_hdd_set_mdns_offload(hdd_adapter_t *hostapd_adapter)
17795{
17796 hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(hostapd_adapter);
17797 sir_mdns_offload_info mdns_offload_info;
17798 sir_mdns_fqdn_info mdns_fqdn_info;
17799 sir_mdns_resp_info mdns_resp_info;
17800 uint32_t fqdn_len, ufqdn_len;
17801
17802 ENTER();
17803
17804 /* 1. Prepare the MDNS fqdn request to send to SME */
17805 fqdn_len = strlen(hdd_ctx->cfg_ini->mdns_fqdn);
17806 ufqdn_len = strlen(hdd_ctx->cfg_ini->mdns_uniquefqdn);
17807 if ((fqdn_len == 0) && (ufqdn_len == 0)) {
17808 hddLog(LOGE, FL("No mDNS FQDN or UFQDN is assigned fqdn_len %d,"
17809 "ufqdn_len %d!"), fqdn_len, ufqdn_len);
17810 return FALSE;
17811 }
17812
17813 mdns_fqdn_info = vos_mem_malloc(sizeof(*mdns_fqdn_info));
17814 if (NULL == mdns_fqdn_info) {
17815 hddLog(LOGE, FL("could not allocate tSirMDNSFqdnInfo!"));
17816 return FALSE;
17817 }
17818 /* MDNS fqdn request */
17819 if (fqdn_len > 0) {
17820 vos_mem_zero(mdns_fqdn_info, sizeof(*mdns_fqdn_info));
17821 mdns_fqdn_info->bss_idx = hostapd_adapter->sessionId;
17822 mdns_fqdn_info->fqdn_type = MDNS_FQDN_TYPE_GENERAL;
17823 mdns_fqdn_info->fqdn_len = fqdn_len;
17824 mdns_fqdn_info->mdns_fqdn_callback = hdd_mdns_fqdn_offload_done;
17825 mdns_fqdn_info->mdns_fqdn_cb_context = hostapd_adapter;
17826 vos_mem_copy(mdns_fqdn_info->fqdn_data,
17827 hdd_ctx->cfg_ini->mdns_fqdn,
17828 mdns_fqdn_info->fqdn_len);
17829
17830 if (eHAL_STATUS_SUCCESS !=
17831 sme_set_mdns_fqdn(hdd_ctx->hHal, mdns_fqdn_info)) {
17832 hddLog(LOGE, FL("sme_set_mdns_fqdn fail!"));
17833 vos_mem_free(mdns_fqdn_info);
17834 return FALSE;
17835 }
17836 }
17837 /* MDNS unique fqdn request */
17838 if (ufqdn_len > 0) {
17839 vos_mem_zero(mdns_fqdn_info, sizeof(*mdns_fqdn_info));
17840 mdns_fqdn_info->bss_idx = hostapd_adapter->sessionId;
17841 mdns_fqdn_info->fqdn_type = MDNS_FQDN_TYPE_UNIQUE;
17842 mdns_fqdn_info->fqdn_len = ufqdn_len;
17843 mdns_fqdn_info->mdns_fqdn_callback = hdd_mdns_fqdn_offload_done;
17844 mdns_fqdn_info->mdns_fqdn_cb_context = hostapd_adapter;
17845 vos_mem_copy(mdns_fqdn_info->fqdn_data,
17846 hdd_ctx->cfg_ini->mdns_uniquefqdn,
17847 mdns_fqdn_info->fqdn_len);
17848 if (eHAL_STATUS_SUCCESS !=
17849 sme_set_mdns_fqdn(hdd_ctx->hHal, mdns_fqdn_info)) {
17850 hddLog(LOGE, FL("sme_set_mdns_fqdn fail!"));
17851 vos_mem_free(mdns_fqdn_info);
17852 return FALSE;
17853 }
17854 }
17855 vos_mem_free(mdns_fqdn_info);
17856
17857 /* 2. Prepare the MDNS response request to send to SME */
17858 mdns_resp_info = vos_mem_malloc(sizeof(*mdns_resp_info));
17859 if (NULL == mdns_resp_info) {
17860 hddLog(LOGE, FL("could not allocate tSirMDNSResponseInfo!"));
17861 return FALSE;
17862 }
17863
17864 vos_mem_zero(mdns_resp_info, sizeof(*mdns_resp_info));
17865 mdns_resp_info->bss_idx = hostapd_adapter->sessionId;
17866 mdns_resp_info->mdns_resp_callback = hdd_mdns_resp_offload_done;
17867 mdns_resp_info->mdns_resp_cb_context = hostapd_adapter;
17868 if (!wlan_hdd_mdns_pack_response(hdd_ctx->cfg_ini, mdns_resp_info)) {
17869 hddLog(LOGE, FL("wlan_hdd_pack_mdns_response fail!"));
17870 vos_mem_free(mdns_resp_info);
17871 return FALSE;
17872 }
17873 if (eHAL_STATUS_SUCCESS !=
17874 sme_set_mdns_resp(hdd_ctx->hHal, mdns_resp_info)) {
17875 hddLog(LOGE, FL("sme_set_mdns_resp fail!"));
17876 vos_mem_free(mdns_resp_info);
17877 return FALSE;
17878 }
17879 vos_mem_free(mdns_resp_info);
17880
17881 /* 3. Prepare the MDNS Enable request to send to SME */
17882 mdns_offload_info = vos_mem_malloc(sizeof(*mdns_offload_info));
17883 if (NULL == mdns_offload_info) {
17884 hddLog(LOGE, FL("could not allocate tSirMDNSOffloadInfo!"));
17885 return FALSE;
17886 }
17887
17888 vos_mem_zero(mdns_offload_info, sizeof(*mdns_offload_info));
17889
17890 mdns_offload_info->bss_idx = hostapd_adapter->sessionId;
17891 mdns_offload_info->enable = hdd_ctx->cfg_ini->enable_mdns_offload;
17892 mdns_offload_info->mdns_enable_callback = hdd_mdns_enable_offload_done;
17893 mdns_offload_info->mdns_enable_cb_context = hostapd_adapter;
17894 if (eHAL_STATUS_SUCCESS !=
17895 sme_set_mdns_offload(hdd_ctx->hHal, mdns_offload_info)) {
17896 hddLog(LOGE, FL("sme_set_mdns_offload fail!"));
17897 vos_mem_free(mdns_offload_info);
17898 return FALSE;
17899 }
17900
17901 vos_mem_free(mdns_offload_info);
17902 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
17903 "%s: enable mDNS offload successfully!", __func__);
17904 return TRUE;
17905}
Manjeet Singh3ed79242017-01-11 19:04:32 +053017906
17907
Anurag Chouhan0b29de02016-12-16 13:18:40 +053017908#endif /* MDNS_OFFLOAD */
c_manjeecfd1efb2015-09-25 19:32:34 +053017909
Hanumanth Reddy Pothulad864f312017-01-18 16:16:08 +053017910/**
17911 * wlan_hdd_start_sap() - This function starts bss of SAP.
17912 * @ap_adapter: SAP adapter
17913 *
17914 * This function will process the starting of sap adapter.
17915 *
17916 * Return: void.
17917 */
17918void wlan_hdd_start_sap(hdd_adapter_t *ap_adapter)
17919{
17920 hdd_ap_ctx_t *hdd_ap_ctx;
17921 hdd_hostapd_state_t *hostapd_state;
17922 VOS_STATUS vos_status;
17923 hdd_context_t *hdd_ctx;
17924 tsap_Config_t *pConfig;
17925
17926 if (NULL == ap_adapter) {
17927 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17928 FL("ap_adapter is NULL here"));
17929 return;
17930 }
17931
17932 hdd_ctx = WLAN_HDD_GET_CTX(ap_adapter);
17933 hdd_ap_ctx = WLAN_HDD_GET_AP_CTX_PTR(ap_adapter);
17934 hostapd_state = WLAN_HDD_GET_HOSTAP_STATE_PTR(ap_adapter);
17935 pConfig = &ap_adapter->sessionCtx.ap.sapConfig;
17936
17937 mutex_lock(&hdd_ctx->sap_lock);
17938 if (test_bit(SOFTAP_BSS_STARTED, &ap_adapter->event_flags))
17939 goto end;
17940
17941 if (0 != wlan_hdd_cfg80211_update_apies(ap_adapter)) {
17942 hddLog(LOGE, FL("SAP Not able to set AP IEs"));
17943 goto end;
17944 }
17945
17946 vos_event_reset(&hostapd_state->vosEvent);
17947 if (WLANSAP_StartBss(hdd_ctx->pvosContext, hdd_hostapd_SAPEventCB,
17948 &hdd_ap_ctx->sapConfig, (v_PVOID_t)ap_adapter->dev)
17949 != VOS_STATUS_SUCCESS) {
17950 goto end;
17951 }
17952
17953 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
17954 FL("Waiting for SAP to start"));
17955 vos_status = vos_wait_single_event(&hostapd_state->vosEvent, 10000);
17956 if (!VOS_IS_STATUS_SUCCESS(vos_status)) {
17957 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17958 FL("SAP Start failed"));
17959 goto end;
17960 }
17961 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
17962 FL("SAP Start Success"));
17963 set_bit(SOFTAP_BSS_STARTED, &ap_adapter->event_flags);
17964
17965 wlan_hdd_incr_active_session(hdd_ctx, ap_adapter->device_mode);
17966 hostapd_state->bCommit = TRUE;
17967
17968end:
17969 mutex_unlock(&hdd_ctx->sap_lock);
17970 return;
17971}
17972
Manjeet Singh3ed79242017-01-11 19:04:32 +053017973#ifdef WLAN_FEATURE_TSF
17974
17975/**
17976 * hdd_tsf_cb() - handle tsf request callback
17977 *
17978 * @pcb_cxt: pointer to the hdd_contex
17979 * @ptsf: pointer to struct stsf
17980 *
17981 * Based on the request sent .
17982 *
17983 * Return: Describe the execute result of this routine
17984 */
17985static int hdd_tsf_cb(void *pcb_ctx, struct stsf *ptsf)
17986{
17987 hdd_context_t *hddctx;
17988 int status;
17989 hdd_adapter_t* adapter = (hdd_adapter_t*)pcb_ctx;
17990
17991 if (pcb_ctx == NULL || ptsf == NULL) {
17992 hddLog(VOS_TRACE_LEVEL_ERROR,
17993 FL("HDD context is not valid"));
17994 return -EINVAL;
17995 }
17996
17997 hddctx = (hdd_context_t *)pcb_ctx;
17998 status = wlan_hdd_validate_context(hddctx);
17999 if (0 != status)
18000 return -EINVAL;
18001
18002 if (NULL == adapter) {
18003 hddLog(VOS_TRACE_LEVEL_ERROR,
18004 FL("failed to find adapter"));
18005 return -EINVAL;
18006 }
18007
18008 hddLog(VOS_TRACE_LEVEL_INFO,
18009 FL("tsf cb handle event, device_mode is %d"),
18010 adapter->device_mode);
18011
18012 /* copy the return value to hdd_tsf_ctx in adapter*/
18013 if (ptsf->tsf_req_status) {
18014
18015 vos_spin_lock_acquire(&adapter->tsf_cap_ctx.tsf_lock);
18016 adapter->tsf_cap_ctx.tsf_get_state = TSF_NOT_RETURNED_BY_FW;
18017 adapter->tsf_cap_ctx.tsf_capture_state = TSF_IDLE;
18018 vos_event_set (&adapter->tsf_cap_ctx.tsf_capture_done_event);
18019 vos_spin_lock_release(&adapter->tsf_cap_ctx.tsf_lock);
18020
18021 hddLog(VOS_TRACE_LEVEL_ERROR, FL("tsf req failure :%d"),
18022 ptsf->tsf_req_status);
18023 return ptsf->tsf_req_status;
18024 }
18025 /* If this is a get request.Store the tsf values in adapter. */
18026 if (!ptsf->set_tsf_req) {
18027 vos_spin_lock_acquire(&adapter->tsf_cap_ctx.tsf_lock);
18028 adapter->tsf_cap_ctx.tsf_low = ptsf->tsf_low;
18029 adapter->tsf_cap_ctx.tsf_high = ptsf->tsf_high;
18030 adapter->tsf_cap_ctx.tsf_get_state = TSF_RETURN;
18031 adapter->tsf_cap_ctx.tsf_capture_state = TSF_IDLE;
18032 vos_spin_lock_release(&adapter->tsf_cap_ctx.tsf_lock);
18033
18034 hddLog(VOS_TRACE_LEVEL_INFO,
18035 FL("hdd_get_tsf_cb sta=%u, tsf_low=%u, tsf_high=%u"),
18036 adapter->sessionId, ptsf->tsf_low, ptsf->tsf_high);
18037 }
18038 else {
18039 vos_spin_lock_acquire(&adapter->tsf_cap_ctx.tsf_lock);
18040 adapter->tsf_cap_ctx.tsf_capture_state = TSF_CAP_STATE;
18041 adapter->tsf_cap_ctx.tsf_get_state = TSF_CURRENT_IN_CAP_STATE;
18042 vos_spin_lock_release(&adapter->tsf_cap_ctx.tsf_lock);
18043 }
18044 vos_spin_lock_acquire(&adapter->tsf_cap_ctx.tsf_lock);
18045 vos_event_set (&adapter->tsf_cap_ctx.tsf_capture_done_event);
18046 vos_spin_lock_release(&adapter->tsf_cap_ctx.tsf_lock);
18047
18048 /* free allocated mem */
18049 vos_mem_free(ptsf);
18050
18051 return 0;
18052}
18053
18054/**
18055 * hdd_capture_tsf() - capture tsf
18056 *
18057 * @adapter: pointer to adapter
18058 * @buf: pointer to upper layer buf
18059 * @len : the length of buf
18060 *
18061 * This function returns tsf value to uplayer.
18062 *
18063 * Return: Describe the execute result of this routine
18064 */
18065int hdd_capture_tsf(hdd_adapter_t *adapter, uint32_t *buf, int len)
18066{
18067 int ret = 0;
18068 hdd_station_ctx_t *hdd_sta_ctx;
18069 hdd_context_t *hdd_ctx;
18070 tSirCapTsfParams cap_tsf_params;
18071 VOS_STATUS status;
18072
18073 if (adapter == NULL || buf == NULL) {
18074 hddLog(VOS_TRACE_LEVEL_ERROR,
18075 FL("invalid pointer"));
18076 return -EINVAL;
18077 }
18078 if (len != 1)
18079 return -EINVAL;
18080
18081 hdd_ctx = WLAN_HDD_GET_CTX(adapter);
18082
18083 if (wlan_hdd_validate_context(hdd_ctx)) {
18084 hddLog(VOS_TRACE_LEVEL_ERROR,
18085 FL("invalid hdd ctx"));
18086 return -EINVAL;
18087 }
18088 if (adapter->device_mode == WLAN_HDD_INFRA_STATION ||
18089 adapter->device_mode == WLAN_HDD_P2P_CLIENT) {
18090 hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
18091 if (hdd_sta_ctx->conn_info.connState !=
18092 eConnectionState_Associated) {
18093
18094 hddLog(VOS_TRACE_LEVEL_INFO,
18095 FL("failed to cap tsf, not connect with ap"));
18096 buf[0] = TSF_STA_NOT_CONNECTED_NO_TSF;
18097 return ret;
18098 }
18099 }
18100 if ((adapter->device_mode == WLAN_HDD_SOFTAP ||
18101 adapter->device_mode == WLAN_HDD_P2P_GO) &&
18102 !(test_bit(SOFTAP_BSS_STARTED, &adapter->event_flags))) {
18103 hddLog(VOS_TRACE_LEVEL_INFO,
18104 FL("Soft AP / P2p GO not beaconing"));
18105 buf[0] = TSF_SAP_NOT_STARTED_NO_TSF;
18106 return ret;
18107 }
18108 if (adapter->tsf_cap_ctx.tsf_capture_state == TSF_CAP_STATE) {
18109 hddLog(VOS_TRACE_LEVEL_INFO,
18110 FL("current in capture state, pls reset"));
18111 buf[0] = TSF_CURRENT_IN_CAP_STATE;
18112 } else {
18113 hddLog(VOS_TRACE_LEVEL_INFO, FL("ioctl issue cap tsf cmd"));
18114 buf[0] = TSF_RETURN;
18115 cap_tsf_params.session_id = adapter->sessionId;
18116 cap_tsf_params.tsf_rsp_cb_func = hdd_tsf_cb;
18117 cap_tsf_params.tsf_rsp_cb_ctx = adapter;
18118
18119 vos_spin_lock_acquire(&adapter->tsf_cap_ctx.tsf_lock);
18120 adapter->tsf_cap_ctx.tsf_capture_state = TSF_CAP_STATE;
18121 adapter->tsf_cap_ctx.tsf_get_state = TSF_CURRENT_IN_CAP_STATE;
18122 vos_spin_lock_release(&adapter->tsf_cap_ctx.tsf_lock);
18123
18124 ret = sme_capture_tsf_req(hdd_ctx->hHal, cap_tsf_params);
18125
18126 if (ret != VOS_STATUS_SUCCESS) {
18127 hddLog(VOS_TRACE_LEVEL_ERROR, FL("capture fail"));
18128 buf[0] = TSF_CAPTURE_FAIL;
18129 vos_spin_lock_acquire(&adapter->tsf_cap_ctx.tsf_lock);
18130 adapter->tsf_cap_ctx.tsf_capture_state = TSF_IDLE;
18131 vos_spin_lock_release(&adapter->tsf_cap_ctx.tsf_lock);
18132 return -EINVAL;
18133 }
18134 /* wait till we get a response from fw */
18135 status = vos_wait_single_event(&adapter->tsf_cap_ctx.
18136 tsf_capture_done_event,
18137 HDD_TSF_CAP_REQ_TIMEOUT);
18138
18139 if (!VOS_IS_STATUS_SUCCESS(status)) {
18140 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18141 ("capture tsf vos wait for single_event failed!! %d"),
18142 adapter->tsf_cap_ctx.tsf_get_state);
18143
18144 vos_spin_lock_acquire(&adapter->tsf_cap_ctx.tsf_lock);
18145 adapter->tsf_cap_ctx.tsf_capture_state = TSF_IDLE;
18146 vos_spin_lock_release(&adapter->tsf_cap_ctx.tsf_lock);
18147
18148 return -EINVAL;
18149 }
18150 }
18151 buf[0] = TSF_RETURN;
18152 hddLog(VOS_TRACE_LEVEL_INFO,
18153 FL("ioctl return cap tsf cmd, ret = %d"), ret);
18154 return ret;
18155}
18156
18157/**
18158 * hdd_indicate_tsf() - return tsf to uplayer
18159 *
18160 * @adapter: pointer to adapter
18161 * @buf: pointer to uplayer buf
18162 * @len : the length of buf
18163 *
18164 * This function returns tsf value to uplayer.
18165 *
18166 * Return: Describe the execute result of this routine
18167 */
18168int hdd_indicate_tsf(hdd_adapter_t *adapter, uint32_t *buf, int len)
18169{
18170 int ret = 0;
18171 hdd_station_ctx_t *hdd_sta_ctx;
18172 hdd_context_t *hdd_ctx;
18173 tSirCapTsfParams cap_tsf_params;
18174 VOS_STATUS status;
18175
18176 if (adapter == NULL || buf == NULL) {
18177 hddLog(VOS_TRACE_LEVEL_ERROR,
18178 FL("invalid pointer"));
18179 return -EINVAL;
18180 }
18181 if (len != 3)
18182 return -EINVAL;
18183
18184 buf [1] = 0;
18185 buf [2] = 0;
18186 hdd_ctx = WLAN_HDD_GET_CTX(adapter);
18187
18188 if (wlan_hdd_validate_context(hdd_ctx)) {
18189 hddLog(VOS_TRACE_LEVEL_ERROR,
18190 FL("invalid hdd ctx"));
18191 return -EINVAL;
18192 }
18193 if (adapter->device_mode == WLAN_HDD_INFRA_STATION ||
18194 adapter->device_mode == WLAN_HDD_P2P_CLIENT) {
18195 hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
18196 if (hdd_sta_ctx->conn_info.connState !=
18197 eConnectionState_Associated) {
18198
18199 hddLog(VOS_TRACE_LEVEL_INFO,
18200 FL("failed to cap tsf, not connect with ap"));
18201 buf[0] = TSF_STA_NOT_CONNECTED_NO_TSF;
18202 return ret;
18203 }
18204 }
18205 if ((adapter->device_mode == WLAN_HDD_SOFTAP ||
18206 adapter->device_mode == WLAN_HDD_P2P_GO) &&
18207 !(test_bit(SOFTAP_BSS_STARTED, &adapter->event_flags))) {
18208 hddLog(VOS_TRACE_LEVEL_INFO,
18209 FL("Soft AP / P2p GO not beaconing"));
18210 buf[0] = TSF_SAP_NOT_STARTED_NO_TSF;
18211 return ret;
18212 }
18213
18214 if (adapter->tsf_cap_ctx.tsf_capture_state != TSF_CAP_STATE ||
18215 adapter->tsf_cap_ctx.tsf_get_state != TSF_CURRENT_IN_CAP_STATE ) {
18216 hddLog(VOS_TRACE_LEVEL_INFO,
18217 FL("Not in capture state,Enter capture state first"));
18218 buf[0] = TSF_GET_FAIL;
18219 } else {
18220 hddLog(VOS_TRACE_LEVEL_INFO, FL("ioctl issue cap tsf cmd"));
18221 cap_tsf_params.session_id = adapter->sessionId;
18222 cap_tsf_params.tsf_rsp_cb_func = hdd_tsf_cb;
18223 cap_tsf_params.tsf_rsp_cb_ctx = adapter;
18224
18225 ret = sme_get_tsf_req(hdd_ctx->hHal, cap_tsf_params);
18226
18227 if (ret != VOS_STATUS_SUCCESS) {
18228 hddLog(VOS_TRACE_LEVEL_ERROR, FL("capture fail"));
18229 buf[0] = TSF_CAPTURE_FAIL;
18230 vos_spin_lock_acquire(&adapter->tsf_cap_ctx.tsf_lock);
18231 adapter->tsf_cap_ctx.tsf_capture_state = TSF_IDLE;
18232 vos_spin_lock_release(&adapter->tsf_cap_ctx.tsf_lock);
18233 return -EINVAL;
18234 }
18235 /* wait till we get a response from fw */
18236 status = vos_wait_single_event(&adapter->tsf_cap_ctx.
18237 tsf_capture_done_event,
18238 HDD_TSF_GET_REQ_TIMEOUT);
18239
18240 if (!VOS_IS_STATUS_SUCCESS(status)) {
18241 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18242 ("capture tsf vos wait for single_event failed!! %d"),
18243 status);
18244
18245 vos_spin_lock_acquire(&adapter->tsf_cap_ctx.tsf_lock);
18246 adapter->tsf_cap_ctx.tsf_capture_state = TSF_IDLE;
18247 vos_spin_lock_release(&adapter->tsf_cap_ctx.tsf_lock);
18248 return status;
18249 }
18250 buf[1] = adapter->tsf_cap_ctx.tsf_low;
18251 buf[2] = adapter->tsf_cap_ctx.tsf_high;
18252
18253 hddLog(VOS_TRACE_LEVEL_INFO,
18254 FL("get tsf cmd,status=%u, tsf_low=%u, tsf_high=%u"),
18255 buf[0], buf[1], buf[2]);
18256 }
18257 hddLog(VOS_TRACE_LEVEL_INFO,
18258 FL("ioctl return cap tsf cmd, ret = %d"), ret);
18259 return ret;
18260}
18261
18262void wlan_hdd_tsf_init(hdd_adapter_t *adapter)
18263{
18264
18265 if (adapter == NULL) {
18266 hddLog(VOS_TRACE_LEVEL_ERROR,
18267 FL("TSF init on a null adapter!"));
18268 return;
18269 }
18270
18271 adapter->tsf_cap_ctx.tsf_get_state = TSF_RETURN;
18272 adapter->tsf_cap_ctx.tsf_capture_state = TSF_IDLE;
18273 vos_event_init(&adapter->tsf_cap_ctx.tsf_capture_done_event);
18274 vos_spin_lock_init(&adapter->tsf_cap_ctx.tsf_lock);
18275 adapter->tsf_cap_ctx.tsf_high = 0;
18276 adapter->tsf_cap_ctx.tsf_low = 0;
18277}
18278
18279#endif
18280
Hanumanth Reddy Pothula972e1df2018-06-14 13:33:47 +053018281bool hdd_is_cli_iface_up(hdd_context_t *hdd_ctx)
18282{
18283 hdd_adapter_list_node_t *adapter_node = NULL, *next = NULL;
18284 hdd_adapter_t *adapter;
18285 VOS_STATUS status;
18286
18287 status = hdd_get_front_adapter(hdd_ctx, &adapter_node);
18288 while (NULL != adapter_node && VOS_STATUS_SUCCESS == status) {
18289 adapter = adapter_node->pAdapter;
18290 if ((adapter->device_mode == WLAN_HDD_INFRA_STATION ||
18291 adapter->device_mode == WLAN_HDD_P2P_CLIENT) &&
18292 test_bit(DEVICE_IFACE_OPENED,
18293 &adapter->event_flags)){
18294 return true;
18295 }
18296 status = hdd_get_next_adapter(hdd_ctx, adapter_node, &next);
18297 adapter_node = next;
18298 }
18299
18300 return false;
18301}
18302
Jeff Johnson295189b2012-06-20 16:38:30 -070018303//Register the module init/exit functions
18304module_init(hdd_module_init);
18305module_exit(hdd_module_exit);
18306
18307MODULE_LICENSE("Dual BSD/GPL");
18308MODULE_AUTHOR("Qualcomm Atheros, Inc.");
18309MODULE_DESCRIPTION("WLAN HOST DEVICE DRIVER");
18310
Ashish Kumar Dhanotiyafb3fd972018-04-30 12:46:52 +053018311static const struct kernel_param_ops con_mode_ops = {
18312 .set = con_mode_handler,
18313 .get = param_get_int,
18314};
18315
18316static const struct kernel_param_ops fwpath_ops = {
18317 .set = fwpath_changed_handler,
18318 .get = param_get_string,
18319};
18320
Hanumanth Reddy Pothula99219872018-06-08 14:45:18 +053018321#ifdef MODULE
18322module_param(con_mode, int, 0);
18323#else
Ashish Kumar Dhanotiyafb3fd972018-04-30 12:46:52 +053018324module_param_cb(con_mode, &con_mode_ops, &con_mode,
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070018325 S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
Hanumanth Reddy Pothula99219872018-06-08 14:45:18 +053018326#endif
Jeff Johnson32d95a32012-09-10 13:15:23 -070018327
Ashish Kumar Dhanotiyafb3fd972018-04-30 12:46:52 +053018328module_param_cb(fwpath, &fwpath_ops, &fwpath,
Jeff Johnson32d95a32012-09-10 13:15:23 -070018329 S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
Arif Hussain66559122013-11-21 10:11:40 -080018330
18331module_param(enable_dfs_chan_scan, int,
18332 S_IRUSR | S_IRGRP | S_IROTH);
18333
18334module_param(enable_11d, int,
18335 S_IRUSR | S_IRGRP | S_IROTH);
18336
18337module_param(country_code, charp,
18338 S_IRUSR | S_IRGRP | S_IROTH);