blob: 6e55d3d3564419d95e2aa2018fccd6a569caee97 [file] [log] [blame]
Jeff Johnson295189b2012-06-20 16:38:30 -07001/*
Arunk Khandavalli95608be2019-01-22 13:12:54 +05302 * Copyright (c) 2012-2019 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);
Jeff Johnsone7245742012-09-05 17:12:55 -0700253
Jeff Johnson295189b2012-06-20 16:38:30 -0700254v_U16_t hdd_select_queue(struct net_device *dev,
Anand N Sunkade9adb1b2015-07-29 09:56:45 +0530255 struct sk_buff *skb
256#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,13,0))
257 , void *accel_priv
258#endif
259#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
260 , select_queue_fallback_t fallback
261#endif
262);
Jeff Johnson295189b2012-06-20 16:38:30 -0700263
264#ifdef WLAN_FEATURE_PACKET_FILTERING
265static void hdd_set_multicast_list(struct net_device *dev);
266#endif
267
268void hdd_wlan_initial_scan(hdd_adapter_t *pAdapter);
269
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -0800270#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowdade697412013-02-14 16:31:48 -0800271void hdd_getBand_helper(hdd_context_t *pHddCtx, int *pBand);
272static VOS_STATUS hdd_parse_channellist(tANI_U8 *pValue, tANI_U8 *pChannelList, tANI_U8 *pNumChannels);
Srinivas Girigowda100eb322013-03-15 16:48:20 -0700273static VOS_STATUS hdd_parse_send_action_frame_data(tANI_U8 *pValue, tANI_U8 *pTargetApBssid,
274 tANI_U8 *pChannel, tANI_U8 *pDwellTime,
275 tANI_U8 **pBuf, tANI_U8 *pBufLen);
Selvaraj, Sridhar5aff1ed2016-06-18 01:26:23 +0530276static int hdd_parse_reassoc_command_v1_data(const tANI_U8 *pValue,
277 tANI_U8 *pTargetApBssid, tANI_U8 *pChannel);
Srinivas Girigowdade697412013-02-14 16:31:48 -0800278#endif
Ratheesh S P21280412015-05-19 14:21:52 +0530279
280/* Store WLAN driver info in a global variable such that crash debugger
281 can extract it from driver debug symbol and crashdump for post processing */
282tANI_U8 g_wlan_driver[ ] = "pronto_driver";
283
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -0800284#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
Srinivas Girigowda5cecb202013-10-08 09:13:25 -0700285VOS_STATUS hdd_parse_get_cckm_ie(tANI_U8 *pValue, tANI_U8 **pCckmIe, tANI_U8 *pCckmIeLen);
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -0800286#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -0700287
Mihir Shetee1093ba2014-01-21 20:13:32 +0530288static VOS_STATUS wlan_hdd_init_channels(hdd_context_t *pHddCtx);
Sushant Kaushik8bc7df22014-04-09 17:55:29 +0530289const char * hdd_device_modetoString(v_U8_t device_mode)
290{
291 switch(device_mode)
292 {
293 CASE_RETURN_STRING( WLAN_HDD_INFRA_STATION );
294 CASE_RETURN_STRING( WLAN_HDD_SOFTAP );
295 CASE_RETURN_STRING( WLAN_HDD_P2P_CLIENT );
296 CASE_RETURN_STRING( WLAN_HDD_P2P_GO );
297 CASE_RETURN_STRING( WLAN_HDD_MONITOR);
298 CASE_RETURN_STRING( WLAN_HDD_FTM );
299 CASE_RETURN_STRING( WLAN_HDD_IBSS );
300 CASE_RETURN_STRING( WLAN_HDD_P2P_DEVICE );
301 default:
302 return "device_mode Unknown";
303 }
304}
Mihir Shetee1093ba2014-01-21 20:13:32 +0530305
Mukul Sharmaa78cf6b2015-02-24 16:59:01 +0530306static int __hdd_netdev_notifier_call(struct notifier_block * nb,
Jeff Johnson295189b2012-06-20 16:38:30 -0700307 unsigned long state,
308 void *ndev)
309{
Yeshwanth Sriram Guntukadb04f472019-08-08 16:58:23 +0530310#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 11, 0))
311 struct netdev_notifier_info *info = ndev;
312 struct net_device *dev = info->dev;
313#else
Jeff Johnson295189b2012-06-20 16:38:30 -0700314 struct net_device *dev = ndev;
Yeshwanth Sriram Guntukadb04f472019-08-08 16:58:23 +0530315#endif
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -0700316 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Jeff Johnson27cee452013-03-27 11:10:24 -0700317 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -0700318#ifdef WLAN_BTAMP_FEATURE
319 VOS_STATUS status;
Jeff Johnson295189b2012-06-20 16:38:30 -0700320#endif
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +0530321 long result;
Jeff Johnson295189b2012-06-20 16:38:30 -0700322
323 //Make sure that this callback corresponds to our device.
Jeff Johnson27cee452013-03-27 11:10:24 -0700324 if ((strncmp(dev->name, "wlan", 4)) &&
Amar Singhal4c723bd2013-03-25 18:14:15 -0700325 (strncmp(dev->name, "p2p", 3)))
326 return NOTIFY_DONE;
327
Jeff Johnson295189b2012-06-20 16:38:30 -0700328 if (!dev->ieee80211_ptr)
Jeff Johnson27cee452013-03-27 11:10:24 -0700329 return NOTIFY_DONE;
Jeff Johnson295189b2012-06-20 16:38:30 -0700330
Jeff Johnson27cee452013-03-27 11:10:24 -0700331 if (NULL == pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -0700332 {
Jeff Johnsona8a1a482012-12-12 16:49:33 -0800333 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: HDD Adapter Null Pointer", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700334 VOS_ASSERT(0);
335 return NOTIFY_DONE;
336 }
337
Jeff Johnson27cee452013-03-27 11:10:24 -0700338 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
339 if (NULL == pHddCtx)
340 {
341 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: HDD Context Null Pointer", __func__);
342 VOS_ASSERT(0);
343 return NOTIFY_DONE;
344 }
Sameer Thalappil14067972014-01-23 14:54:54 -0800345 if (pHddCtx->isLogpInProgress)
346 return NOTIFY_DONE;
347
Jeff Johnson27cee452013-03-27 11:10:24 -0700348
349 hddLog(VOS_TRACE_LEVEL_INFO, "%s: %s New Net Device State = %lu",
350 __func__, dev->name, state);
Jeff Johnson295189b2012-06-20 16:38:30 -0700351
352 switch (state) {
353 case NETDEV_REGISTER:
354 break;
355
356 case NETDEV_UNREGISTER:
357 break;
358
359 case NETDEV_UP:
360 break;
361
362 case NETDEV_DOWN:
363 break;
364
365 case NETDEV_CHANGE:
Jeff Johnsone7245742012-09-05 17:12:55 -0700366 if(TRUE == pAdapter->isLinkUpSvcNeeded)
367 complete(&pAdapter->linkup_event_var);
Jeff Johnson295189b2012-06-20 16:38:30 -0700368 break;
369
370 case NETDEV_GOING_DOWN:
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +0530371 result = wlan_hdd_scan_abort(pAdapter);
Girish Gowli4bf7a632014-06-12 13:42:11 +0530372 if (result < 0)
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +0530373 {
374 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
375 "%s: Timeout occurred while waiting for abortscan %ld",
376 __func__, result);
Jeff Johnson295189b2012-06-20 16:38:30 -0700377 }
378 else
379 {
380 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +0530381 "%s: Scan Abort Successful" , __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700382 }
383#ifdef WLAN_BTAMP_FEATURE
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700384 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,"%s: disabling AMP", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700385 status = WLANBAP_StopAmp();
386 if(VOS_STATUS_SUCCESS != status )
387 {
388 pHddCtx->isAmpAllowed = VOS_TRUE;
389 hddLog(VOS_TRACE_LEVEL_FATAL,
390 "%s: Failed to stop AMP", __func__);
391 }
392 else
393 {
394 //a state m/c implementation in PAL is TBD to avoid this delay
395 msleep(500);
Jeff Johnson04dd8a82012-06-29 20:41:40 -0700396 if ( pHddCtx->isAmpAllowed )
397 {
398 WLANBAP_DeregisterFromHCI();
399 pHddCtx->isAmpAllowed = VOS_FALSE;
400 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700401 }
402#endif //WLAN_BTAMP_FEATURE
403 break;
404
405 default:
406 break;
407 }
408
409 return NOTIFY_DONE;
410}
411
Mukul Sharmaa78cf6b2015-02-24 16:59:01 +0530412static int hdd_netdev_notifier_call(struct notifier_block * nb,
413 unsigned long state,
414 void *ndev)
415{
416 int ret;
417 vos_ssr_protect(__func__);
418 ret = __hdd_netdev_notifier_call( nb, state, ndev);
419 vos_ssr_unprotect(__func__);
420 return ret;
421}
422
Jeff Johnson295189b2012-06-20 16:38:30 -0700423struct notifier_block hdd_netdev_notifier = {
424 .notifier_call = hdd_netdev_notifier_call,
425};
426
427/*---------------------------------------------------------------------------
428 * Function definitions
429 *-------------------------------------------------------------------------*/
Jeff Johnson295189b2012-06-20 16:38:30 -0700430void hdd_unregister_mcast_bcast_filter(hdd_context_t *pHddCtx);
431void hdd_register_mcast_bcast_filter(hdd_context_t *pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -0700432//variable to hold the insmod parameters
Madan Mohan Koyyalamudidfd6aa82012-10-18 20:18:43 -0700433static int con_mode;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -0700434#ifndef MODULE
435/* current con_mode - used only for statically linked driver
436 * con_mode is changed by userspace to indicate a mode change which will
437 * result in calling the module exit and init functions. The module
438 * exit function will clean up based on the value of con_mode prior to it
439 * being changed by userspace. So curr_con_mode records the current con_mode
440 * for exit when con_mode becomes the next mode for init
441 */
Madan Mohan Koyyalamudidfd6aa82012-10-18 20:18:43 -0700442static int curr_con_mode;
Jeff Johnson295189b2012-06-20 16:38:30 -0700443#endif
444
Srinivas Girigowda8bf64cb2015-09-30 19:50:09 +0530445#ifdef WLAN_FEATURE_OFFLOAD_PACKETS
446/**
447 * hdd_init_offloaded_packets_ctx() - Initialize offload packets context
448 * @hdd_ctx: hdd global context
449 *
450 * Return: none
451 */
452static void hdd_init_offloaded_packets_ctx(hdd_context_t *hdd_ctx)
453{
454 uint8_t i;
455
456 mutex_init(&hdd_ctx->op_ctx.op_lock);
457 for (i = 0; i < MAXNUM_PERIODIC_TX_PTRNS; i++)
458 {
459 hdd_ctx->op_ctx.op_table[i].request_id = 0;
460 hdd_ctx->op_ctx.op_table[i].pattern_id = i;
461 }
462}
463#else
464static void hdd_init_offloaded_packets_ctx(hdd_context_t *hdd_ctx)
465{
466}
467#endif
468
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -0800469/**---------------------------------------------------------------------------
470
471 \brief hdd_vos_trace_enable() - Configure initial VOS Trace enable
472
473 Called immediately after the cfg.ini is read in order to configure
474 the desired trace levels.
475
476 \param - moduleId - module whose trace level is being configured
477 \param - bitmask - bitmask of log levels to be enabled
478
479 \return - void
480
481 --------------------------------------------------------------------------*/
482static void hdd_vos_trace_enable(VOS_MODULE_ID moduleId, v_U32_t bitmask)
483{
484 wpt_tracelevel level;
485
486 /* if the bitmask is the default value, then a bitmask was not
487 specified in cfg.ini, so leave the logging level alone (it
488 will remain at the "compiled in" default value) */
489 if (CFG_VOS_TRACE_ENABLE_DEFAULT == bitmask)
490 {
491 return;
492 }
493
494 /* a mask was specified. start by disabling all logging */
495 vos_trace_setValue(moduleId, VOS_TRACE_LEVEL_NONE, 0);
496
497 /* now cycle through the bitmask until all "set" bits are serviced */
498 level = VOS_TRACE_LEVEL_FATAL;
499 while (0 != bitmask)
500 {
501 if (bitmask & 1)
502 {
503 vos_trace_setValue(moduleId, level, 1);
504 }
505 level++;
506 bitmask >>= 1;
507 }
508}
509
510
Jeff Johnson295189b2012-06-20 16:38:30 -0700511/**---------------------------------------------------------------------------
512
513 \brief hdd_wdi_trace_enable() - Configure initial WDI Trace enable
514
515 Called immediately after the cfg.ini is read in order to configure
516 the desired trace levels in the WDI.
517
518 \param - moduleId - module whose trace level is being configured
519 \param - bitmask - bitmask of log levels to be enabled
520
521 \return - void
522
523 --------------------------------------------------------------------------*/
524static void hdd_wdi_trace_enable(wpt_moduleid moduleId, v_U32_t bitmask)
525{
526 wpt_tracelevel level;
527
528 /* if the bitmask is the default value, then a bitmask was not
529 specified in cfg.ini, so leave the logging level alone (it
530 will remain at the "compiled in" default value) */
531 if (CFG_WDI_TRACE_ENABLE_DEFAULT == bitmask)
532 {
533 return;
534 }
535
536 /* a mask was specified. start by disabling all logging */
537 wpalTraceSetLevel(moduleId, eWLAN_PAL_TRACE_LEVEL_NONE, 0);
538
539 /* now cycle through the bitmask until all "set" bits are serviced */
540 level = eWLAN_PAL_TRACE_LEVEL_FATAL;
541 while (0 != bitmask)
542 {
543 if (bitmask & 1)
544 {
545 wpalTraceSetLevel(moduleId, level, 1);
546 }
547 level++;
548 bitmask >>= 1;
549 }
550}
Jeff Johnson295189b2012-06-20 16:38:30 -0700551
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +0530552/*
553 * FUNCTION: wlan_hdd_validate_context
554 * This function is used to check the HDD context
555 */
556int wlan_hdd_validate_context(hdd_context_t *pHddCtx)
557{
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +0530558
559 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
560 {
Mahesh A Saptasagar886997a2015-03-04 13:15:51 +0530561 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +0530562 "%s: HDD context is Null", __func__);
563 return -ENODEV;
564 }
565
566 if (pHddCtx->isLogpInProgress)
567 {
Mahesh A Saptasagar886997a2015-03-04 13:15:51 +0530568 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
c_hpothu8adb97b2014-12-08 19:38:20 +0530569 "%s: LOGP %s. Ignore!!", __func__,
570 vos_is_wlan_in_badState(VOS_MODULE_ID_HDD, NULL)
571 ?"failed":"in Progress");
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +0530572 return -EAGAIN;
573 }
574
Mihir Shete18156292014-03-11 15:38:30 +0530575 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +0530576 {
Mahesh A Saptasagar886997a2015-03-04 13:15:51 +0530577 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +0530578 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
579 return -EAGAIN;
580 }
581 return 0;
582}
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -0700583#ifdef CONFIG_ENABLE_LINUX_REG
584void hdd_checkandupdate_phymode( hdd_context_t *pHddCtx)
585{
586 hdd_adapter_t *pAdapter = NULL;
587 hdd_station_ctx_t *pHddStaCtx = NULL;
588 eCsrPhyMode phyMode;
589 hdd_config_t *cfg_param = NULL;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +0530590
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -0700591 if (NULL == pHddCtx)
592 {
593 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
594 "HDD Context is null !!");
595 return ;
596 }
597
598 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION);
599 if (NULL == pAdapter)
600 {
601 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
602 "pAdapter is null !!");
603 return ;
604 }
605
606 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
607 if (NULL == pHddStaCtx)
608 {
609 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
610 "pHddStaCtx is null !!");
611 return ;
612 }
613
614 cfg_param = pHddCtx->cfg_ini;
615 if (NULL == cfg_param)
616 {
617 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
618 "cfg_params not available !!");
619 return ;
620 }
621
622 phyMode = sme_GetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter));
623
624 if (!pHddCtx->isVHT80Allowed)
625 {
626 if ((eCSR_DOT11_MODE_AUTO == phyMode) ||
627 (eCSR_DOT11_MODE_11ac == phyMode) ||
628 (eCSR_DOT11_MODE_11ac_ONLY == phyMode))
629 {
630 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
631 "Setting phymode to 11n!!");
632 sme_SetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter), eCSR_DOT11_MODE_11n);
633 }
634 }
635 else
636 {
637 /*New country Supports 11ac as well resetting value back from .ini*/
638 sme_SetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter),
639 hdd_cfg_xlate_to_csr_phy_mode(cfg_param->dot11Mode));
640 return ;
641 }
642
643 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
644 ((eCSR_CFG_DOT11_MODE_11AC_ONLY == pHddStaCtx->conn_info.dot11Mode) ||
645 (eCSR_CFG_DOT11_MODE_11AC == pHddStaCtx->conn_info.dot11Mode)))
646 {
647 VOS_STATUS vosStatus;
648
649 // need to issue a disconnect to CSR.
650 INIT_COMPLETION(pAdapter->disconnect_comp_var);
651 vosStatus = sme_RoamDisconnect(WLAN_HDD_GET_HAL_CTX(pAdapter),
652 pAdapter->sessionId,
653 eCSR_DISCONNECT_REASON_UNSPECIFIED );
654
655 if (VOS_STATUS_SUCCESS == vosStatus)
c_hpothu6ff1c3c2013-10-01 19:01:57 +0530656 {
657 long ret;
658
659 ret = wait_for_completion_interruptible_timeout(&pAdapter->disconnect_comp_var,
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -0700660 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
c_hpothu6ff1c3c2013-10-01 19:01:57 +0530661 if (0 >= ret)
662 hddLog(LOGE, FL("failure waiting for disconnect_comp_var %ld"),
663 ret);
664 }
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -0700665
666 }
667}
668#else
Gopichand Nakkaladacbcb52013-04-18 16:41:54 +0530669void hdd_checkandupdate_phymode( hdd_adapter_t *pAdapter, char *country_code)
670{
671 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
672 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
673 hdd_config_t *cfg_param;
674 eCsrPhyMode phyMode;
c_hpothu6ff1c3c2013-10-01 19:01:57 +0530675 long ret;
Gopichand Nakkaladacbcb52013-04-18 16:41:54 +0530676
677 if (NULL == pHddCtx)
678 {
679 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
680 "HDD Context is null !!");
681 return ;
682 }
683
684 cfg_param = pHddCtx->cfg_ini;
685
686 if (NULL == cfg_param)
687 {
688 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
689 "cfg_params not available !!");
690 return ;
691 }
692
693 phyMode = sme_GetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter));
694
695 if (NULL != strstr(cfg_param->listOfNon11acCountryCode, country_code))
696 {
697 if ((eCSR_DOT11_MODE_AUTO == phyMode) ||
698 (eCSR_DOT11_MODE_11ac == phyMode) ||
699 (eCSR_DOT11_MODE_11ac_ONLY == phyMode))
700 {
701 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
702 "Setting phymode to 11n!!");
703 sme_SetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter), eCSR_DOT11_MODE_11n);
704 }
705 }
706 else
707 {
708 /*New country Supports 11ac as well resetting value back from .ini*/
709 sme_SetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter),
710 hdd_cfg_xlate_to_csr_phy_mode(cfg_param->dot11Mode));
711 return ;
712 }
713
714 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
715 ((eCSR_CFG_DOT11_MODE_11AC_ONLY == pHddStaCtx->conn_info.dot11Mode) ||
716 (eCSR_CFG_DOT11_MODE_11AC == pHddStaCtx->conn_info.dot11Mode)))
717 {
718 VOS_STATUS vosStatus;
719
720 // need to issue a disconnect to CSR.
721 INIT_COMPLETION(pAdapter->disconnect_comp_var);
722 vosStatus = sme_RoamDisconnect(WLAN_HDD_GET_HAL_CTX(pAdapter),
723 pAdapter->sessionId,
724 eCSR_DISCONNECT_REASON_UNSPECIFIED );
725
726 if (VOS_STATUS_SUCCESS == vosStatus)
c_hpothu6ff1c3c2013-10-01 19:01:57 +0530727 {
728 ret = wait_for_completion_interruptible_timeout(&pAdapter->disconnect_comp_var,
Gopichand Nakkaladacbcb52013-04-18 16:41:54 +0530729 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
c_hpothu6ff1c3c2013-10-01 19:01:57 +0530730 if (ret <= 0)
731 {
732 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
733 "wait on disconnect_comp_var is failed %ld", ret);
734 }
735 }
Gopichand Nakkaladacbcb52013-04-18 16:41:54 +0530736
737 }
738}
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -0700739#endif //CONFIG_ENABLE_LINUX_REG
Gopichand Nakkaladacbcb52013-04-18 16:41:54 +0530740
Tushnim Bhattacharyya9cdf6082013-04-21 16:33:30 -0700741void hdd_checkandupdate_dfssetting( hdd_adapter_t *pAdapter, char *country_code)
742{
743 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
744 hdd_config_t *cfg_param;
745
746 if (NULL == pHddCtx)
747 {
748 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
749 "HDD Context is null !!");
750 return ;
751 }
752
753 cfg_param = pHddCtx->cfg_ini;
754
755 if (NULL == cfg_param)
756 {
757 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
758 "cfg_params not available !!");
759 return ;
760 }
761
Agarwal Ashish738843c2014-09-25 12:27:56 +0530762 if (NULL != strstr(cfg_param->listOfNonDfsCountryCode, country_code) ||
763 pHddCtx->disable_dfs_flag == TRUE)
Tushnim Bhattacharyya9cdf6082013-04-21 16:33:30 -0700764 {
765 /*New country doesn't support DFS */
766 sme_UpdateDfsSetting(WLAN_HDD_GET_HAL_CTX(pAdapter), 0);
767 }
Ashish Kumar Dhanotiya445b3b92018-06-07 12:38:12 +0530768 else
769 {
770 /* New country Supports DFS as well resetting value back from .ini */
771 sme_UpdateDfsSetting(WLAN_HDD_GET_HAL_CTX(pAdapter),
772 cfg_param->enableDFSChnlScan);
773 }
Tushnim Bhattacharyya9cdf6082013-04-21 16:33:30 -0700774
775}
776
Abhishek Singh00b71972016-01-07 10:51:04 +0530777#ifdef WLAN_FEATURE_RMC
778static int hdd_parse_setrmcenable_command(tANI_U8 *pValue, tANI_U8 *pRmcEnable)
779{
780 tANI_U8 *inPtr = pValue;
781 int tempInt;
782 int v = 0;
783 char buf[32];
784 *pRmcEnable = 0;
785
786 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
787 /*no argument after the command*/
788 if (NULL == inPtr)
789 {
790 return 0;
791 }
792
793 /*no space after the command*/
794 else if (SPACE_ASCII_VALUE != *inPtr)
795 {
796 return 0;
797 }
798
799 /*removing empty spaces*/
800 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
801
802 /*no argument followed by spaces*/
803 if ('\0' == *inPtr)
804 {
805 return 0;
806 }
807
808 /* getting the first argument which enables or disables RMC
809 * for input IP v4 address*/
Ashish Kumar Dhanotiya54d31a32017-08-04 17:12:44 +0530810 sscanf(inPtr, "%31s ", buf);
Abhishek Singh00b71972016-01-07 10:51:04 +0530811 v = kstrtos32(buf, 10, &tempInt);
812 if ( v < 0)
813 {
814 return -EINVAL;
815 }
816
817 *pRmcEnable = tempInt;
818
819 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
820 "ucRmcEnable: %d", *pRmcEnable);
821
822 return 0;
823}
824
825/* Function header left blank Intentionally */
826static int hdd_parse_setrmcactionperiod_command(tANI_U8 *pValue,
827 tANI_U32 *pActionPeriod)
828{
829 tANI_U8 *inPtr = pValue;
830 int tempInt;
831 int v = 0;
832 char buf[32];
833 *pActionPeriod = 0;
834
835 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
836 /*no argument after the command*/
837 if (NULL == inPtr)
838 {
839 return -EINVAL;
840 }
841
842 /*no space after the command*/
843 else if (SPACE_ASCII_VALUE != *inPtr)
844 {
845 return -EINVAL;
846 }
847
848 /*removing empty spaces*/
849 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
850
851 /*no argument followed by spaces*/
852 if ('\0' == *inPtr)
853 {
854 return 0;
855 }
856
857 /* getting the first argument which enables or disables RMC
858 * for input IP v4 address*/
Ashish Kumar Dhanotiya54d31a32017-08-04 17:12:44 +0530859 sscanf(inPtr, "%31s ", buf);
Abhishek Singh00b71972016-01-07 10:51:04 +0530860 v = kstrtos32(buf, 10, &tempInt);
861 if ( v < 0)
862 {
863 return -EINVAL;
864 }
865
866 /* Range checking for passed paramter */
867 if (tempInt < WNI_CFG_RMC_ACTION_PERIOD_FREQUENCY_STAMIN ||
868 tempInt > WNI_CFG_RMC_ACTION_PERIOD_FREQUENCY_STAMAX)
869 {
870 return -EINVAL;
871 }
872
873 *pActionPeriod = tempInt;
874
875 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
876 "uActionPeriod: %d", *pActionPeriod);
877
878 return 0;
879}
Dundi Ravitejae110a042018-04-18 13:11:37 +0530880
881/**
882 * hdd_set_vowifi_mode() - Process VOWIFI command.
883 * @hdd_ctx: context handler
Sourav Mohapatra2416e0e2018-03-05 18:44:21 +0530884 * @enable: Value to be sent as a part of the VOWIFI command
885 *
Dundi Ravitejae110a042018-04-18 13:11:37 +0530886 * Invoke the SME api if station is connected in 2.4 GHz band.
887 * Also start split scan if VOWIFIMODE and dynamic split scan
888 * both are enabled.
889
Sourav Mohapatra2416e0e2018-03-05 18:44:21 +0530890 * Return: void
891 */
892void hdd_set_vowifi_mode(hdd_context_t *hdd_ctx, bool enable)
893{
894 tANI_U8 sta_chan;
895
Dundi Ravitejaab9d3092018-04-05 18:24:40 +0530896 if (!hdd_ctx->cfg_ini) {
897 hddLog(LOGE, "cfg_ini got NULL");
898 return;
899 }
900
Sourav Mohapatra2416e0e2018-03-05 18:44:21 +0530901 sta_chan = hdd_get_operating_channel(hdd_ctx, WLAN_HDD_INFRA_STATION);
902
Dundi Ravitejae110a042018-04-18 13:11:37 +0530903 if (CSR_IS_CHANNEL_24GHZ(sta_chan))
Sourav Mohapatra2416e0e2018-03-05 18:44:21 +0530904 sme_set_vowifi_mode(hdd_ctx->hHal, enable);
Dundi Ravitejae110a042018-04-18 13:11:37 +0530905 else
Sourav Mohapatra2416e0e2018-03-05 18:44:21 +0530906 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
907 "VoWiFi command rejected as not connected in 2.4GHz");
Dundi Ravitejae110a042018-04-18 13:11:37 +0530908
909 if (enable && hdd_ctx->cfg_ini->dynSplitscan) {
910 hdd_ctx->is_vowifi_enabled = true;
911 hdd_ctx->issplitscan_enabled = TRUE;
912 sme_enable_disable_split_scan(hdd_ctx->hHal,
913 hdd_ctx->cfg_ini->nNumStaChanCombinedConc,
914 hdd_ctx->cfg_ini->nNumP2PChanCombinedConc);
915 } else {
916 hdd_ctx->is_vowifi_enabled = false;
Dundi Ravitejaab9d3092018-04-05 18:24:40 +0530917 }
Sourav Mohapatra2416e0e2018-03-05 18:44:21 +0530918}
Abhishek Singh00b71972016-01-07 10:51:04 +0530919
920/* Function header left blank Intentionally */
921static int hdd_parse_setrmcrate_command(tANI_U8 *pValue,
922 tANI_U32 *pRate, tTxrateinfoflags *pTxFlags)
923{
924 tANI_U8 *inPtr = pValue;
925 int tempInt;
926 int v = 0;
927 char buf[32];
928 *pRate = 0;
929 *pTxFlags = 0;
930
931 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
932 /*no argument after the command*/
933 if (NULL == inPtr)
934 {
935 return -EINVAL;
936 }
937
938 /*no space after the command*/
939 else if (SPACE_ASCII_VALUE != *inPtr)
940 {
941 return -EINVAL;
942 }
943
944 /*removing empty spaces*/
945 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
946
947 /*no argument followed by spaces*/
948 if ('\0' == *inPtr)
949 {
950 return 0;
951 }
952
953 /*
954 * getting the first argument which sets multicast rate.
955 */
Ashish Kumar Dhanotiya06f9f202017-08-04 15:26:27 +0530956 sscanf(inPtr, "%31s ", buf);
Abhishek Singh00b71972016-01-07 10:51:04 +0530957 v = kstrtos32(buf, 10, &tempInt);
958 if ( v < 0)
959 {
960 return -EINVAL;
961 }
962
963 /*
964 * Validate the multicast rate.
965 */
966 switch (tempInt)
967 {
968 default:
969 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
970 "Unsupported rate: %d", tempInt);
971 return -EINVAL;
972 case 0:
973 case 6:
974 case 9:
975 case 12:
976 case 18:
977 case 24:
978 case 36:
979 case 48:
980 case 54:
981 *pTxFlags = eHAL_TX_RATE_LEGACY;
982 *pRate = tempInt * 10;
983 break;
984 case 65:
985 *pTxFlags = eHAL_TX_RATE_HT20;
986 *pRate = tempInt * 10;
987 break;
988 case 72:
989 *pTxFlags = eHAL_TX_RATE_HT20 | eHAL_TX_RATE_SGI;
990 *pRate = 722; /* fractional rate 72.2 Mbps */
991 break;
992 }
993
994 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
995 "Rate: %d", *pRate);
996
997 return 0;
998}
999
1000/**---------------------------------------------------------------------------
1001
1002 \brief hdd_cfg80211_get_ibss_peer_info_cb() - Callback function for IBSS
1003 Peer Info request
1004
1005 This is an asynchronous callback function from SME when the peer info
1006 is received
1007
1008 \pUserData -> Adapter private data
1009 \pPeerInfoRsp -> Peer info response
1010
1011 \return - 0 for success non-zero for failure
1012 --------------------------------------------------------------------------*/
1013static void
1014hdd_cfg80211_get_ibss_peer_info_cb(v_VOID_t *pUserData, v_VOID_t *pPeerInfoRsp)
1015{
1016 hdd_adapter_t *pAdapter = (hdd_adapter_t *)pUserData;
1017 tSirPeerInfoRspParams *pPeerInfo = (tSirPeerInfoRspParams *)pPeerInfoRsp;
1018 hdd_station_ctx_t *pStaCtx;
1019 v_U8_t i;
1020
1021 /*Sanity check*/
1022 if ((NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic))
1023 {
1024 hddLog(LOGE,
1025 FL("invalid adapter or adapter has invalid magic"));
1026 return;
1027 }
1028
1029 pStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
1030 if (NULL != pStaCtx && NULL != pPeerInfo &&
1031 eHAL_STATUS_SUCCESS == pPeerInfo->status)
1032 {
1033 pStaCtx->ibss_peer_info.status = pPeerInfo->status;
1034 pStaCtx->ibss_peer_info.numIBSSPeers = pPeerInfo->numPeers;
1035
1036 /* Paranoia check */
1037 if (pPeerInfo->numPeers < HDD_MAX_NUM_IBSS_STA)
1038 {
1039 for (i = 0; i < pPeerInfo->numPeers; i++)
1040 {
1041 memcpy(&pStaCtx->ibss_peer_info.ibssPeerList[i],
1042 &pPeerInfo->peerInfoParams[i],
1043 sizeof(hdd_ibss_peer_info_params_t));
1044 }
1045 hddLog(LOG1,
1046 FL("Peer Info copied in HDD"));
1047 }
1048 else
1049 {
1050 hddLog(LOGE,
1051 FL(" Number of peers %d returned is more than limit %d"),
1052 pPeerInfo->numPeers, HDD_MAX_NUM_IBSS_STA);
1053 }
1054 }
1055 else
1056 {
1057 hddLog(LOG1,
1058 FL("peerInfo returned is NULL"));
1059 }
1060
1061 complete(&pAdapter->ibss_peer_info_comp);
1062}
1063
1064/**---------------------------------------------------------------------------
1065
1066 \brief hdd_cfg80211_get_ibss_peer_info_all() -
1067
1068 Request function to get IBSS peer info from lower layers
1069
1070 \pAdapter -> Adapter context
1071
1072 \return - 0 for success non-zero for failure
1073 --------------------------------------------------------------------------*/
1074static
1075VOS_STATUS hdd_cfg80211_get_ibss_peer_info_all(hdd_adapter_t *pAdapter)
1076{
1077 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
1078 long status;
1079 VOS_STATUS retStatus = VOS_STATUS_E_FAILURE;
1080
1081 INIT_COMPLETION(pAdapter->ibss_peer_info_comp);
1082
1083 retStatus = sme_RequestIBSSPeerInfo(hHal, pAdapter,
1084 hdd_cfg80211_get_ibss_peer_info_cb,
1085 VOS_TRUE, 0xFF);
1086
1087 if (VOS_STATUS_SUCCESS == retStatus)
1088 {
1089 status = wait_for_completion_interruptible_timeout
1090 (&pAdapter->ibss_peer_info_comp,
1091 msecs_to_jiffies(IBSS_PEER_INFO_REQ_TIMOEUT));
1092
1093 /* status will be 0 if timed out */
1094 if (status <= 0)
1095 {
1096 hddLog(VOS_TRACE_LEVEL_WARN, "%s: Warning: IBSS_PEER_INFO_TIMEOUT %ld",
1097 __func__, status);
1098 retStatus = VOS_STATUS_E_FAILURE;
1099 return retStatus;
1100 }
1101 }
1102 else
1103 {
1104 hddLog(VOS_TRACE_LEVEL_WARN,
1105 "%s: Warning: sme_RequestIBSSPeerInfo Request failed", __func__);
1106 }
1107
1108 return retStatus;
1109}
1110
1111/**---------------------------------------------------------------------------
1112
1113 \brief hdd_cfg80211_get_ibss_peer_info() -
1114
1115 Request function to get IBSS peer info from lower layers
1116
1117 \pAdapter -> Adapter context
1118 \staIdx -> Sta index for which the peer info is requested
1119
1120 \return - 0 for success non-zero for failure
1121 --------------------------------------------------------------------------*/
1122static VOS_STATUS
1123hdd_cfg80211_get_ibss_peer_info(hdd_adapter_t *pAdapter, v_U8_t staIdx)
1124{
1125 long status;
1126 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
1127 VOS_STATUS retStatus = VOS_STATUS_E_FAILURE;
1128
1129 INIT_COMPLETION(pAdapter->ibss_peer_info_comp);
1130
1131 retStatus = sme_RequestIBSSPeerInfo(hHal, pAdapter,
1132 hdd_cfg80211_get_ibss_peer_info_cb,
1133 VOS_FALSE, staIdx);
1134
1135 if (VOS_STATUS_SUCCESS == retStatus)
1136 {
1137 status = wait_for_completion_interruptible_timeout
1138 (&pAdapter->ibss_peer_info_comp,
1139 msecs_to_jiffies(IBSS_PEER_INFO_REQ_TIMOEUT));
1140
1141 /* status = 0 on timeout */
1142 if (status <= 0)
1143 {
1144 hddLog(VOS_TRACE_LEVEL_WARN, "%s: Warning: IBSS_PEER_INFO_TIMEOUT %ld",
1145 __func__, status);
1146 retStatus = VOS_STATUS_E_FAILURE;
1147 return retStatus;
1148 }
1149 }
1150 else
1151 {
1152 hddLog(VOS_TRACE_LEVEL_WARN,
1153 "%s: Warning: sme_RequestIBSSPeerInfo Request failed", __func__);
1154 }
1155
1156 return retStatus;
1157}
1158
1159/* Function header left blank Intentionally */
1160VOS_STATUS
1161hdd_parse_get_ibss_peer_info(tANI_U8 *pValue, v_MACADDR_t *pPeerMacAddr)
1162{
1163 tANI_U8 *inPtr = pValue;
1164 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
1165
1166 /*no argument after the command*/
1167 if (NULL == inPtr)
1168 {
1169 return VOS_STATUS_E_FAILURE;;
1170 }
1171
1172 /*no space after the command*/
1173 else if (SPACE_ASCII_VALUE != *inPtr)
1174 {
1175 return VOS_STATUS_E_FAILURE;;
1176 }
1177
1178 /*removing empty spaces*/
1179 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
1180
1181 /*no argument followed by spaces*/
1182 if ('\0' == *inPtr)
1183 {
1184 return VOS_STATUS_E_FAILURE;;
1185 }
1186
1187 /*getting the first argument ie the peer mac address */
1188 if (inPtr[2] != ':' || inPtr[5] != ':' || inPtr[8] != ':' ||
1189 inPtr[11] != ':' || inPtr[14] != ':')
1190 {
1191 return VOS_STATUS_E_FAILURE;;
1192 }
1193 sscanf(inPtr, "%2x:%2x:%2x:%2x:%2x:%2x",
1194 (unsigned int *)&pPeerMacAddr->bytes[0],
1195 (unsigned int *)&pPeerMacAddr->bytes[1],
1196 (unsigned int *)&pPeerMacAddr->bytes[2],
1197 (unsigned int *)&pPeerMacAddr->bytes[3],
1198 (unsigned int *)&pPeerMacAddr->bytes[4],
1199 (unsigned int *)&pPeerMacAddr->bytes[5]);
1200
1201 /* The command buffer seems to be fine */
1202 return VOS_STATUS_SUCCESS;
1203}
1204
1205/* Function header left blank Intentionally */
1206static int hdd_parse_set_ibss_oui_data_command(tANI_U8 *command, tANI_U8 *ie,
1207 tANI_U32 limit)
1208{
1209 tANI_U8 len;
1210 tANI_U8 data;
1211
1212 /* skip white space */
1213 while ((SPACE_ASCII_VALUE == *command) && ('\0' != *command))
1214 {
1215 command++;
1216 limit--;
1217 }
1218
1219 /* skip element id and element length */
1220 len = 2;
1221
1222 /* extract oui */
1223 while ((SPACE_ASCII_VALUE != *command) && ('\0' != *command) &&
1224 (limit > 1))
1225 {
1226 /* Convert ASCII to decimal */
1227 data = ((*command -'0') << 4) | (*(command + 1) - '0');
1228 ie[len++] = data;
1229 command += 2;
1230 limit -= 2;
1231 }
1232
1233 /* skip white space */
1234 while ((SPACE_ASCII_VALUE == *command) && ('\0' != *command))
1235 {
1236 command++;
1237 limit--;
1238 }
1239
1240 /* extract data */
1241 while ((SPACE_ASCII_VALUE != *command) && ('\0' != *command) &&
1242 (limit > 1))
1243 {
1244 /* Convert ASCII to decimal */
1245 data = ((*command -'0') << 4) | (*(command + 1) - '0');
1246 ie[len++] = data;
1247 command += 2;
1248 limit -= 2;
1249 }
1250
1251 /* fill element id and element length */
1252 ie[0] = IE_EID_VENDOR;
1253 ie[1] = len - 2;
1254
1255 return len;
1256}
1257
1258static tANI_U32 hdd_find_ibss_wpa_ie_pos(tANI_U8 *addIePtr, tANI_U32 addIeLen)
1259{
1260 tANI_U32 ieLenPresent = 0;
1261 int left = addIeLen;
1262 v_U8_t *ptr = addIePtr;
1263 v_U8_t elem_id,elem_len;
1264
1265 while(left >= 2)
1266 {
1267 elem_id = ptr[0];
1268 elem_len = ptr[1];
1269 left -= 2;
1270 if(elem_len > left)
1271 {
1272 hddLog(LOGE,
1273 FL("****Invalid elem_len=%d left=%d*****"),
1274 elem_len,left);
1275 return 0;
1276 }
1277 if ((elem_id == IE_EID_VENDOR) &&
1278 (left >= WPA_OUI_TYPE_SIZE))
1279 {
1280 if (!memcmp(&ptr[2], WPA_OUI_TYPE,
1281 WPA_OUI_TYPE_SIZE))
1282 {
1283 ieLenPresent += elem_len + 2;
1284 return ieLenPresent;
1285 }
1286 }
1287 ieLenPresent += (elem_len + 2);
1288 left -= elem_len;
1289 ptr += (elem_len + 2);
1290 }
1291 return 0;
1292}
1293
1294#endif /* WLAN_FEATURE_RMC */
1295
Rajeev79dbe4c2013-10-05 11:03:42 +05301296#ifdef FEATURE_WLAN_BATCH_SCAN
1297
1298/**---------------------------------------------------------------------------
1299
1300 \brief hdd_extract_assigned_int_from_str() - Extracts assigned integer from
1301 input string
1302
1303 This function extracts assigned integer from string in below format:
1304 "STRING=10" : extracts integer 10 from this string
1305
1306 \param - pInPtr Pointer to input string
1307 \param - base Base for string to int conversion(10 for decimal 16 for hex)
1308 \param - pOutPtr Pointer to variable in which extracted integer needs to be
1309 assigned
1310 \param - pLastArg to tell whether it is last arguement in input string or
1311 not
1312
1313 \return - NULL for failure cases
1314 pointer to next arguement in input string for success cases
1315 --------------------------------------------------------------------------*/
1316static tANI_U8 *
1317hdd_extract_assigned_int_from_str
1318(
1319 tANI_U8 *pInPtr,
1320 tANI_U8 base,
1321 tANI_U32 *pOutPtr,
1322 tANI_U8 *pLastArg
1323)
1324{
1325 int tempInt;
1326 int v = 0;
1327 char buf[32];
1328 int val = 0;
1329 *pLastArg = FALSE;
1330
1331 pInPtr = strnchr(pInPtr, strlen(pInPtr), EQUALS_TO_ASCII_VALUE);
1332 if (NULL == pInPtr)
1333 {
1334 return NULL;
1335 }
1336
1337 pInPtr++;
1338
1339 while ((SPACE_ASCII_VALUE == *pInPtr) && ('\0' != *pInPtr)) pInPtr++;
1340
1341 val = sscanf(pInPtr, "%32s ", buf);
1342 if (val < 0 && val > strlen(pInPtr))
1343 {
1344 return NULL;
1345 }
1346 pInPtr += val;
1347 v = kstrtos32(buf, base, &tempInt);
1348 if (v < 0)
1349 {
1350 return NULL;
1351 }
Rajeev Kumar4d93d842014-01-02 18:31:21 -08001352 if (tempInt < 0)
1353 {
1354 tempInt = 0;
1355 }
Rajeev79dbe4c2013-10-05 11:03:42 +05301356 *pOutPtr = tempInt;
1357
1358 pInPtr = strnchr(pInPtr, strlen(pInPtr), SPACE_ASCII_VALUE);
1359 if (NULL == pInPtr)
1360 {
1361 *pLastArg = TRUE;
1362 return NULL;
1363 }
1364 while ((SPACE_ASCII_VALUE == *pInPtr) && ('\0' != *pInPtr)) pInPtr++;
1365
1366 return pInPtr;
1367}
1368
1369/**---------------------------------------------------------------------------
1370
1371 \brief hdd_extract_assigned_char_from_str() - Extracts assigned char from
1372 input string
1373
1374 This function extracts assigned character from string in below format:
1375 "STRING=A" : extracts char 'A' from this string
1376
1377 \param - pInPtr Pointer to input string
1378 \param - pOutPtr Pointer to variable in which extracted char needs to be
1379 assigned
1380 \param - pLastArg to tell whether it is last arguement in input string or
1381 not
1382
1383 \return - NULL for failure cases
1384 pointer to next arguement in input string for success cases
1385 --------------------------------------------------------------------------*/
1386static tANI_U8 *
1387hdd_extract_assigned_char_from_str
1388(
1389 tANI_U8 *pInPtr,
1390 tANI_U8 *pOutPtr,
1391 tANI_U8 *pLastArg
1392)
1393{
1394 *pLastArg = FALSE;
1395
1396 pInPtr = strnchr(pInPtr, strlen(pInPtr), EQUALS_TO_ASCII_VALUE);
1397 if (NULL == pInPtr)
1398 {
1399 return NULL;
1400 }
1401
1402 pInPtr++;
1403
1404 while ((SPACE_ASCII_VALUE == *pInPtr) && ('\0' != *pInPtr)) pInPtr++;
1405
1406 *pOutPtr = *pInPtr;
1407
1408 pInPtr = strnchr(pInPtr, strlen(pInPtr), SPACE_ASCII_VALUE);
1409 if (NULL == pInPtr)
1410 {
1411 *pLastArg = TRUE;
1412 return NULL;
1413 }
1414 while ((SPACE_ASCII_VALUE == *pInPtr) && ('\0' != *pInPtr)) pInPtr++;
1415
1416 return pInPtr;
1417}
1418
1419
1420/**---------------------------------------------------------------------------
1421
1422 \brief hdd_parse_set_batchscan_command () - HDD parse set batch scan command
1423
1424 This function parses set batch scan command in below format:
1425 WLS_BATCHING_SET <space> followed by below arguements
1426 "SCANFREQ=XX" : Optional defaults to 30 sec
1427 "MSCAN=XX" : Required number of scans to attempt to batch
1428 "BESTN=XX" : Best Network (RSSI) defaults to 16
1429 "CHANNEL=<X,Y>" : optional defaults to all channels, can list 'A'or` B.
1430 A. implies only 5 GHz , B. implies only 2.4GHz
1431 "RTT=X" : optional defaults to 0
1432 returns the MIN of MSCAN or the max # of scans firmware can cache or -1 on
1433 error
1434
1435 For example input commands:
1436 1) WLS_BATCHING_SET SCANFREQ=60 MSCAN=10 BESTN=20 CHANNEL=A RTT=0 -> This is
1437 translated into set batch scan with following parameters:
1438 a) Frequence 60 seconds
1439 b) Batch 10 scans together
1440 c) Best RSSI to be 20
1441 d) 5GHz band only
1442 e) RTT is equal to 0
1443
1444 \param - pValue Pointer to input channel list
1445 \param - pHddSetBatchScanReq Pointer to HDD batch scan request structure
1446
1447 \return - 0 for success non-zero for failure
1448
1449 --------------------------------------------------------------------------*/
1450static int
1451hdd_parse_set_batchscan_command
1452(
1453 tANI_U8 *pValue,
1454 tSirSetBatchScanReq *pHddSetBatchScanReq
1455)
1456{
1457 tANI_U8 *inPtr = pValue;
1458 tANI_U8 val = 0;
1459 tANI_U8 lastArg = 0;
Abhishek Singh00b71972016-01-07 10:51:04 +05301460 tANI_U32 nScanFreq = HDD_SET_BATCH_SCAN_DEFAULT_FREQ;
Rajeev Kumar45e64a72013-11-18 19:48:15 -08001461 tANI_U32 nMscan;
Abhishek Singh00b71972016-01-07 10:51:04 +05301462 tANI_U32 nBestN = HDD_SET_BATCH_SCAN_BEST_NETWORK;
1463 tANI_U8 ucRfBand = HDD_SET_BATCH_SCAN_DEFAULT_BAND;
1464 tANI_U32 nRtt = 0;
Rajeev Kumarc933d982013-11-18 20:04:20 -08001465 tANI_U32 temp;
Rajeev79dbe4c2013-10-05 11:03:42 +05301466
Rajeev79dbe4c2013-10-05 11:03:42 +05301467 /*go to space after WLS_BATCHING_SET command*/
1468 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
1469 /*no argument after the command*/
1470 if (NULL == inPtr)
1471 {
1472 return -EINVAL;
1473 }
1474
1475 /*no space after the command*/
1476 else if (SPACE_ASCII_VALUE != *inPtr)
1477 {
1478 return -EINVAL;
1479 }
1480
1481 /*removing empty spaces*/
1482 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
1483
1484 /*no argument followed by spaces*/
1485 if ('\0' == *inPtr)
1486 {
1487 return -EINVAL;
1488 }
1489
1490 /*check and parse SCANFREQ*/
1491 if ((strncmp(inPtr, "SCANFREQ", 8) == 0))
1492 {
1493 inPtr = hdd_extract_assigned_int_from_str(inPtr, 10,
Rajeev Kumarc933d982013-11-18 20:04:20 -08001494 &temp, &lastArg);
Rajeev Kumar45e64a72013-11-18 19:48:15 -08001495
Rajeev Kumarc933d982013-11-18 20:04:20 -08001496 if (0 != temp)
Rajeev Kumar45e64a72013-11-18 19:48:15 -08001497 {
Rajeev Kumarc933d982013-11-18 20:04:20 -08001498 nScanFreq = temp;
Rajeev Kumar45e64a72013-11-18 19:48:15 -08001499 }
1500
Rajeev79dbe4c2013-10-05 11:03:42 +05301501 if ( (NULL == inPtr) || (TRUE == lastArg))
1502 {
1503 return -EINVAL;
1504 }
1505 }
1506
1507 /*check and parse MSCAN*/
1508 if ((strncmp(inPtr, "MSCAN", 5) == 0))
1509 {
1510 inPtr = hdd_extract_assigned_int_from_str(inPtr, 10,
Rajeev Kumar45e64a72013-11-18 19:48:15 -08001511 &nMscan, &lastArg);
1512
1513 if (0 == nMscan)
1514 {
1515 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1516 "invalid MSCAN=%d", nMscan);
1517 return -EINVAL;
1518 }
1519
Rajeev79dbe4c2013-10-05 11:03:42 +05301520 if (TRUE == lastArg)
1521 {
1522 goto done;
1523 }
1524 else if (NULL == inPtr)
1525 {
1526 return -EINVAL;
1527 }
1528 }
1529 else
1530 {
1531 return -EINVAL;
1532 }
1533
1534 /*check and parse BESTN*/
1535 if ((strncmp(inPtr, "BESTN", 5) == 0))
1536 {
1537 inPtr = hdd_extract_assigned_int_from_str(inPtr, 10,
Rajeev Kumarc933d982013-11-18 20:04:20 -08001538 &temp, &lastArg);
Rajeev Kumar45e64a72013-11-18 19:48:15 -08001539
Rajeev Kumarc933d982013-11-18 20:04:20 -08001540 if (0 != temp)
Rajeev Kumar45e64a72013-11-18 19:48:15 -08001541 {
Rajeev Kumarc933d982013-11-18 20:04:20 -08001542 nBestN = temp;
Rajeev Kumar45e64a72013-11-18 19:48:15 -08001543 }
1544
Rajeev79dbe4c2013-10-05 11:03:42 +05301545 if (TRUE == lastArg)
1546 {
1547 goto done;
1548 }
1549 else if (NULL == inPtr)
1550 {
1551 return -EINVAL;
1552 }
1553 }
1554
1555 /*check and parse CHANNEL*/
1556 if ((strncmp(inPtr, "CHANNEL", 7) == 0))
1557 {
1558 inPtr = hdd_extract_assigned_char_from_str(inPtr, &val, &lastArg);
Rajeev Kumarc933d982013-11-18 20:04:20 -08001559
Rajeev79dbe4c2013-10-05 11:03:42 +05301560 if (('A' == val) || ('a' == val))
1561 {
c_hpothuebf89732014-02-25 13:00:24 +05301562 ucRfBand = HDD_SET_BATCH_SCAN_5GHz_BAND_ONLY;
Rajeev79dbe4c2013-10-05 11:03:42 +05301563 }
1564 else if (('B' == val) || ('b' == val))
1565 {
c_hpothuebf89732014-02-25 13:00:24 +05301566 ucRfBand = HDD_SET_BATCH_SCAN_24GHz_BAND_ONLY;
Rajeev79dbe4c2013-10-05 11:03:42 +05301567 }
1568 else
1569 {
Rajeev Kumarc933d982013-11-18 20:04:20 -08001570 ucRfBand = HDD_SET_BATCH_SCAN_DEFAULT_BAND;
1571 }
1572
1573 if (TRUE == lastArg)
1574 {
1575 goto done;
1576 }
1577 else if (NULL == inPtr)
1578 {
Rajeev79dbe4c2013-10-05 11:03:42 +05301579 return -EINVAL;
1580 }
1581 }
1582
1583 /*check and parse RTT*/
1584 if ((strncmp(inPtr, "RTT", 3) == 0))
1585 {
1586 inPtr = hdd_extract_assigned_int_from_str(inPtr, 10,
Rajeev Kumar45e64a72013-11-18 19:48:15 -08001587 &nRtt, &lastArg);
Rajeev79dbe4c2013-10-05 11:03:42 +05301588 if (TRUE == lastArg)
1589 {
1590 goto done;
1591 }
1592 if (NULL == inPtr)
1593 {
1594 return -EINVAL;
1595 }
1596 }
1597
1598
1599done:
1600
Rajeev Kumar45e64a72013-11-18 19:48:15 -08001601 pHddSetBatchScanReq->scanFrequency = nScanFreq;
1602 pHddSetBatchScanReq->numberOfScansToBatch = nMscan;
1603 pHddSetBatchScanReq->bestNetwork = nBestN;
1604 pHddSetBatchScanReq->rfBand = ucRfBand;
1605 pHddSetBatchScanReq->rtt = nRtt;
1606
Rajeev79dbe4c2013-10-05 11:03:42 +05301607 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1608 "Received WLS_BATCHING_SET with SCANFREQ=%d "
1609 "MSCAN=%d BESTN=%d CHANNEL=%d RTT=%d",
1610 pHddSetBatchScanReq->scanFrequency,
1611 pHddSetBatchScanReq->numberOfScansToBatch,
1612 pHddSetBatchScanReq->bestNetwork,
1613 pHddSetBatchScanReq->rfBand,
1614 pHddSetBatchScanReq->rtt);
1615
1616 return 0;
1617}/*End of hdd_parse_set_batchscan_command*/
1618
1619/**---------------------------------------------------------------------------
1620
1621 \brief hdd_set_batch_scan_req_callback () - This function is called after
1622 receiving set batch scan response from FW and it saves set batch scan
1623 response data FW to HDD context and sets the completion event on
1624 which hdd_ioctl is waiting
1625
1626 \param - callbackContext Pointer to HDD adapter
1627 \param - pRsp Pointer to set batch scan response data received from FW
1628
1629 \return - nothing
1630
1631 --------------------------------------------------------------------------*/
1632static void hdd_set_batch_scan_req_callback
1633(
1634 void *callbackContext,
1635 tSirSetBatchScanRsp *pRsp
1636)
1637{
1638 hdd_adapter_t* pAdapter = (hdd_adapter_t*)callbackContext;
1639 tSirSetBatchScanRsp *pHddSetBatchScanRsp;
1640
1641 /*sanity check*/
1642 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
1643 {
1644 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1645 "%s: Invalid pAdapter magic", __func__);
1646 VOS_ASSERT(0);
1647 return;
1648 }
1649 pHddSetBatchScanRsp = &pAdapter->hddSetBatchScanRsp;
1650
1651 /*save set batch scan response*/
1652 pHddSetBatchScanRsp->nScansToBatch = pRsp->nScansToBatch;
1653
1654 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
1655 "Received set batch scan rsp from FW with nScansToBatch=%d",
1656 pHddSetBatchScanRsp->nScansToBatch);
1657
1658 pAdapter->hdd_wait_for_set_batch_scan_rsp = FALSE;
1659 complete(&pAdapter->hdd_set_batch_scan_req_var);
1660
1661 return;
1662}/*End of hdd_set_batch_scan_req_callback*/
1663
1664
1665/**---------------------------------------------------------------------------
1666
1667 \brief hdd_populate_batch_scan_rsp_queue () - This function stores AP meta
1668 info in hdd batch scan response queue
1669
1670 \param - pAdapter Pointer to hdd adapter
1671 \param - pAPMetaInfo Pointer to access point meta info
1672 \param - scanId scan ID of batch scan response
1673 \param - isLastAp tells whether AP is last AP in batch scan response or not
1674
1675 \return - nothing
1676
1677 --------------------------------------------------------------------------*/
1678static void hdd_populate_batch_scan_rsp_queue( hdd_adapter_t* pAdapter,
1679 tpSirBatchScanNetworkInfo pApMetaInfo, tANI_U32 scanId, v_BOOL_t isLastAp)
1680{
1681 tHddBatchScanRsp *pHead;
1682 tHddBatchScanRsp *pNode;
1683 tHddBatchScanRsp *pPrev;
1684 tHddBatchScanRsp *pTemp;
1685 tANI_U8 ssidLen;
1686
1687 /*head of hdd batch scan response queue*/
1688 pHead = pAdapter->pBatchScanRsp;
1689
1690 pNode = (tHddBatchScanRsp *)vos_mem_malloc(sizeof(tHddBatchScanRsp));
1691 if (NULL == pNode)
1692 {
1693 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1694 "%s: Could not allocate memory", __func__);
1695 VOS_ASSERT(0);
1696 return;
1697 }
1698
1699 vos_mem_copy(pNode->ApInfo.bssid, pApMetaInfo->bssid,
1700 sizeof(pNode->ApInfo.bssid));
1701 ssidLen = strlen(pApMetaInfo->ssid);
1702 if (SIR_MAX_SSID_SIZE < ssidLen)
1703 {
1704 /*invalid scan result*/
1705 vos_mem_free(pNode);
1706 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1707 "%s: Invalid AP meta info ssidlen %d", __func__, ssidLen);
1708 return;
1709 }
1710 vos_mem_copy(pNode->ApInfo.ssid, pApMetaInfo->ssid, ssidLen);
1711 /*null terminate ssid*/
1712 pNode->ApInfo.ssid[ssidLen] = '\0';
1713 pNode->ApInfo.ch = pApMetaInfo->ch;
1714 pNode->ApInfo.rssi = pApMetaInfo->rssi;
1715 pNode->ApInfo.age = pApMetaInfo->timestamp;
1716 pNode->ApInfo.batchId = scanId;
1717 pNode->ApInfo.isLastAp = isLastAp;
1718
1719 pNode->pNext = NULL;
1720 if (NULL == pHead)
1721 {
1722 pAdapter->pBatchScanRsp = pNode;
1723 }
1724 else
1725 {
1726 pTemp = pHead;
1727 while (NULL != pTemp)
1728 {
1729 pPrev = pTemp;
1730 pTemp = pTemp->pNext;
1731 }
1732 pPrev->pNext = pNode;
1733 }
1734
1735 return;
1736}/*End of hdd_populate_batch_scan_rsp_queue*/
1737
1738/**---------------------------------------------------------------------------
1739
1740 \brief hdd_batch_scan_result_ind_callback () - This function is called after
1741 receiving batch scan response indication from FW. It saves get batch scan
1742 response data in HDD batch scan response queue. This callback sets the
1743 completion event on which hdd_ioctl is waiting only after getting complete
1744 batch scan response data from FW
1745
1746 \param - callbackContext Pointer to HDD adapter
1747 \param - pRsp Pointer to get batch scan response data received from FW
1748
1749 \return - nothing
1750
1751 --------------------------------------------------------------------------*/
1752static void hdd_batch_scan_result_ind_callback
1753(
1754 void *callbackContext,
1755 void *pRsp
1756)
1757{
1758 v_BOOL_t isLastAp;
1759 tANI_U32 numApMetaInfo;
Rajeev Kumarce651e42013-10-21 18:57:15 -07001760 tANI_U32 numNetworkInScanList;
Rajeev79dbe4c2013-10-05 11:03:42 +05301761 tANI_U32 numberScanList;
1762 tANI_U32 nextScanListOffset;
1763 tANI_U32 nextApMetaInfoOffset;
1764 hdd_adapter_t* pAdapter;
1765 tpSirBatchScanList pScanList;
1766 tpSirBatchScanNetworkInfo pApMetaInfo;
1767 tpSirBatchScanResultIndParam pBatchScanRsp;/*batch scan rsp data from FW*/
1768 tSirSetBatchScanReq *pReq;
1769
1770 pAdapter = (hdd_adapter_t *)callbackContext;
1771 /*sanity check*/
Rajeev Kumar5286bb92013-12-05 11:52:10 -08001772 if ((NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic))
Rajeev79dbe4c2013-10-05 11:03:42 +05301773 {
1774 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1775 "%s: Invalid pAdapter magic", __func__);
1776 VOS_ASSERT(0);
1777 return;
1778 }
1779
1780 /*initialize locals*/
1781 pReq = &pAdapter->hddSetBatchScanReq;
1782 pBatchScanRsp = (tpSirBatchScanResultIndParam)pRsp;
1783 isLastAp = FALSE;
1784 numApMetaInfo = 0;
Rajeev Kumarce651e42013-10-21 18:57:15 -07001785 numNetworkInScanList = 0;
Rajeev79dbe4c2013-10-05 11:03:42 +05301786 numberScanList = 0;
1787 nextScanListOffset = 0;
1788 nextApMetaInfoOffset = 0;
1789 pScanList = NULL;
1790 pApMetaInfo = NULL;
1791
1792 if ((NULL == pBatchScanRsp) || (NULL == pReq))
1793 {
1794 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnsonc135a9a2017-09-19 08:37:24 -07001795 "%s: pBatchScanRsp is %pK pReq %pK", __func__, pBatchScanRsp, pReq);
Rajeev79dbe4c2013-10-05 11:03:42 +05301796 isLastAp = TRUE;
1797 goto done;
1798 }
1799
1800 pAdapter->numScanList = numberScanList = pBatchScanRsp->numScanLists;
1801 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1802 "Batch scan rsp: numberScalList %d", numberScanList);
1803
1804 if ((!numberScanList) || (numberScanList > pReq->numberOfScansToBatch))
1805 {
1806 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1807 "%s: numberScanList %d", __func__, numberScanList);
1808 isLastAp = TRUE;
1809 goto done;
1810 }
1811
1812 while (numberScanList)
1813 {
Rajeev Kumarce651e42013-10-21 18:57:15 -07001814 pScanList = (tpSirBatchScanList)((tANI_U8 *)pBatchScanRsp->scanResults +
Rajeev79dbe4c2013-10-05 11:03:42 +05301815 nextScanListOffset);
1816 if (NULL == pScanList)
1817 {
1818 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnsonc135a9a2017-09-19 08:37:24 -07001819 "%s: pScanList is %pK", __func__, pScanList);
Rajeev79dbe4c2013-10-05 11:03:42 +05301820 isLastAp = TRUE;
1821 goto done;
1822 }
Rajeev Kumarce651e42013-10-21 18:57:15 -07001823 numNetworkInScanList = numApMetaInfo = pScanList->numNetworksInScanList;
Rajeev79dbe4c2013-10-05 11:03:42 +05301824 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Rajeev Kumarce651e42013-10-21 18:57:15 -07001825 "Batch scan rsp: numApMetaInfo %d scanId %d",
1826 numApMetaInfo, pScanList->scanId);
Rajeev79dbe4c2013-10-05 11:03:42 +05301827
1828 if ((!numApMetaInfo) || (numApMetaInfo > pReq->bestNetwork))
1829 {
1830 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1831 "%s: numApMetaInfo %d", __func__, numApMetaInfo);
1832 isLastAp = TRUE;
1833 goto done;
1834 }
1835
Rajeev Kumarce651e42013-10-21 18:57:15 -07001836 /*Initialize next AP meta info offset for next scan list*/
1837 nextApMetaInfoOffset = 0;
1838
Rajeev79dbe4c2013-10-05 11:03:42 +05301839 while (numApMetaInfo)
1840 {
1841 pApMetaInfo = (tpSirBatchScanNetworkInfo)(pScanList->scanList +
1842 nextApMetaInfoOffset);
1843 if (NULL == pApMetaInfo)
1844 {
1845 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnsonc135a9a2017-09-19 08:37:24 -07001846 "%s: pApMetaInfo is %pK", __func__, pApMetaInfo);
Rajeev79dbe4c2013-10-05 11:03:42 +05301847 isLastAp = TRUE;
1848 goto done;
1849 }
1850 /*calculate AP age*/
1851 pApMetaInfo->timestamp =
1852 pBatchScanRsp->timestamp - pApMetaInfo->timestamp;
1853
1854 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
Arif Hussaina7c8e412013-11-20 11:06:42 -08001855 "%s: bssId "MAC_ADDRESS_STR
1856 " ch %d rssi %d timestamp %d", __func__,
1857 MAC_ADDR_ARRAY(pApMetaInfo->bssid),
1858 pApMetaInfo->ch, pApMetaInfo->rssi,
1859 pApMetaInfo->timestamp);
Rajeev79dbe4c2013-10-05 11:03:42 +05301860
1861 /*mark last AP in batch scan response*/
1862 if ((TRUE == pBatchScanRsp->isLastResult) &&
1863 (1 == numberScanList) && (1 == numApMetaInfo))
1864 {
1865 isLastAp = TRUE;
1866 }
1867
1868 mutex_lock(&pAdapter->hdd_batch_scan_lock);
1869 /*store batch scan repsonse in hdd queue*/
1870 hdd_populate_batch_scan_rsp_queue(pAdapter, pApMetaInfo,
1871 pScanList->scanId, isLastAp);
1872 mutex_unlock(&pAdapter->hdd_batch_scan_lock);
1873
1874 nextApMetaInfoOffset += sizeof(tSirBatchScanNetworkInfo);
1875 numApMetaInfo--;
1876 }
1877
Rajeev Kumarce651e42013-10-21 18:57:15 -07001878 nextScanListOffset += ((sizeof(tSirBatchScanList) - sizeof(tANI_U8))
1879 + (sizeof(tSirBatchScanNetworkInfo)
1880 * numNetworkInScanList));
Rajeev79dbe4c2013-10-05 11:03:42 +05301881 numberScanList--;
1882 }
1883
1884done:
1885
1886 /*notify hdd_ioctl only if complete batch scan rsp is received and it was
1887 requested from hdd_ioctl*/
1888 if ((TRUE == pAdapter->hdd_wait_for_get_batch_scan_rsp) &&
1889 (TRUE == isLastAp))
1890 {
1891 pAdapter->hdd_wait_for_get_batch_scan_rsp = FALSE;
1892 complete(&pAdapter->hdd_get_batch_scan_req_var);
1893 }
1894
1895 return;
1896}/*End of hdd_batch_scan_result_ind_callback*/
1897
1898/**---------------------------------------------------------------------------
1899
1900 \brief hdd_format_batch_scan_rsp () - This function formats batch scan
1901 response as per batch scan FR request format by putting proper markers
1902
1903 \param - pDest pointer to destination buffer
1904 \param - cur_len current length
1905 \param - tot_len total remaining size which can be written to user space
1906 \param - pApMetaInfo Pointer to get batch scan response AP meta info
1907 \param - pAdapter Pointer to HDD adapter
1908
1909 \return - ret no of characters written
1910
1911 --------------------------------------------------------------------------*/
1912static tANI_U32
1913hdd_format_batch_scan_rsp
1914(
1915 tANI_U8 *pDest,
1916 tANI_U32 cur_len,
1917 tANI_U32 tot_len,
1918 tHddBatchScanRsp *pApMetaInfo,
1919 hdd_adapter_t* pAdapter
1920)
1921{
1922 tANI_U32 ret = 0;
1923 tANI_U32 rem_len = 0;
1924 tANI_U8 temp_len = 0;
1925 tANI_U8 temp_total_len = 0;
1926 tANI_U8 temp[HDD_BATCH_SCAN_AP_META_INFO_SIZE];
1927 tANI_U8 *pTemp = temp;
1928
1929 /*Batch scan reponse needs to be returned to user space in
1930 following format:
1931 "scancount=X\n" where X is the number of scans in current batch
1932 batch
1933 "trunc\n" optional present if current scan truncated
1934 "bssid=XX:XX:XX:XX:XX:XX\n"
1935 "ssid=XXXX\n"
1936 "freq=X\n" frequency in Mhz
1937 "level=XX\n"
1938 "age=X\n" ms
1939 "dist=X\n" cm (-1 if not available)
1940 "errror=X\n" (-1if not available)
1941 "====\n" (end of ap marker)
1942 "####\n" (end of scan marker)
1943 "----\n" (end of results)*/
1944 /*send scan result in above format to user space based on
1945 available length*/
1946 /*The GET response may have more data than the driver can return in its
1947 buffer. In that case the buffer should be filled to the nearest complete
1948 scan, ending with "%%%%".Subsequent callsshould return the remaining data
1949 starting with the next scan (optional .trunc\n., .apcount=X\n., etc).
1950 The final buffer should end with "----\n"*/
1951
1952 /*sanity*/
1953 if (cur_len > tot_len)
1954 {
1955 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1956 "%s: invaid cur_len %d tot_len %d", __func__, cur_len, tot_len);
1957 return 0;
1958 }
1959 else
1960 {
1961 rem_len = (tot_len - cur_len);
1962 }
1963
1964 /*end scan marker*/
1965 if (pApMetaInfo->ApInfo.batchId != pAdapter->prev_batch_id)
1966 {
1967 temp_len = snprintf(pTemp, sizeof(temp), "####\n");
1968 pTemp += temp_len;
1969 temp_total_len += temp_len;
1970 }
1971
1972 /*bssid*/
1973 temp_len = snprintf(pTemp, sizeof(temp),
1974 "bssid=0x%x:0x%x:0x%x:0x%x:0x%x:0x%x\n",
1975 pApMetaInfo->ApInfo.bssid[0], pApMetaInfo->ApInfo.bssid[1],
1976 pApMetaInfo->ApInfo.bssid[2], pApMetaInfo->ApInfo.bssid[3],
1977 pApMetaInfo->ApInfo.bssid[4], pApMetaInfo->ApInfo.bssid[5]);
1978 pTemp += temp_len;
1979 temp_total_len += temp_len;
1980
1981 /*ssid*/
1982 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "ssid=%s\n",
1983 pApMetaInfo->ApInfo.ssid);
1984 pTemp += temp_len;
1985 temp_total_len += temp_len;
1986
1987 /*freq*/
1988 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "freq=%d\n",
Rajeev Kumarc40f7512013-11-04 14:13:23 -08001989 sme_ChnToFreq(pApMetaInfo->ApInfo.ch));
Rajeev79dbe4c2013-10-05 11:03:42 +05301990 pTemp += temp_len;
1991 temp_total_len += temp_len;
1992
1993 /*level*/
1994 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "level=%d\n",
1995 pApMetaInfo->ApInfo.rssi);
1996 pTemp += temp_len;
1997 temp_total_len += temp_len;
1998
1999 /*age*/
Jeff Johnson02797792013-10-26 19:17:13 -07002000 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "age=%d\n",
Rajeev79dbe4c2013-10-05 11:03:42 +05302001 pApMetaInfo->ApInfo.age);
2002 pTemp += temp_len;
2003 temp_total_len += temp_len;
2004
2005 /*dist*/
2006 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "dist=-1\n");
2007 pTemp += temp_len;
2008 temp_total_len += temp_len;
2009
2010 /*error*/
2011 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "error=-1\n");
2012 pTemp += temp_len;
2013 temp_total_len += temp_len;
2014
2015 /*end AP marker*/
2016 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "====\n");
2017 pTemp += temp_len;
2018 temp_total_len += temp_len;
2019
2020 /*last AP in batch scan response*/
2021 if(TRUE == pApMetaInfo->ApInfo.isLastAp)
2022 {
2023 /*end scan marker*/
2024 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "####\n");
2025 pTemp += temp_len;
2026 temp_total_len += temp_len;
2027
2028 /*end batch scan result marker*/
2029 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "----\n");
2030 pTemp += temp_len;
2031 temp_total_len += temp_len;
Kiet Lamaa8e15a2014-02-11 23:30:06 -08002032
Rajeev79dbe4c2013-10-05 11:03:42 +05302033 }
2034
2035 if (temp_total_len < rem_len)
2036 {
2037 ret = temp_total_len + 1;
2038 strlcpy(pDest, temp, ret);
2039 pAdapter->isTruncated = FALSE;
2040 }
2041 else
2042 {
2043 pAdapter->isTruncated = TRUE;
2044 if (rem_len >= strlen("%%%%"))
2045 {
Rajeev Kumarc933d982013-11-18 20:04:20 -08002046 ret = snprintf(pDest, sizeof(temp), "%%%%");
Rajeev79dbe4c2013-10-05 11:03:42 +05302047 }
Rajeev Kumarc933d982013-11-18 20:04:20 -08002048 else
Rajeev79dbe4c2013-10-05 11:03:42 +05302049 {
2050 ret = 0;
2051 }
2052 }
2053
2054 return ret;
2055
2056}/*End of hdd_format_batch_scan_rsp*/
2057
2058/**---------------------------------------------------------------------------
2059
2060 \brief hdd_populate_user_batch_scan_rsp() - This function populates user data
2061 buffer starting with head of hdd batch scan response queue
2062
2063 \param - pAdapter Pointer to HDD adapter
2064 \param - pDest Pointer to user data buffer
2065 \param - cur_len current offset in user buffer
2066 \param - rem_len remaining no of bytes in user buffer
2067
2068 \return - number of bytes written in user buffer
2069
2070 --------------------------------------------------------------------------*/
2071
2072tANI_U32 hdd_populate_user_batch_scan_rsp
2073(
2074 hdd_adapter_t* pAdapter,
2075 tANI_U8 *pDest,
2076 tANI_U32 cur_len,
2077 tANI_U32 rem_len
2078)
2079{
2080 tHddBatchScanRsp *pHead;
2081 tHddBatchScanRsp *pPrev;
2082 tANI_U32 len;
2083
Rajeev79dbe4c2013-10-05 11:03:42 +05302084 pAdapter->isTruncated = FALSE;
2085
2086 /*head of hdd batch scan response queue*/
2087 pHead = pAdapter->pBatchScanRsp;
2088 while (pHead)
2089 {
2090 len = hdd_format_batch_scan_rsp(pDest, cur_len, rem_len, pHead,
2091 pAdapter);
2092 pDest += len;
Rajeev Kumar292d2bb2013-10-23 15:01:44 -07002093 pDest--;
Rajeev79dbe4c2013-10-05 11:03:42 +05302094 cur_len += len;
2095 if(TRUE == pAdapter->isTruncated)
2096 {
2097 /*result is truncated return rest of scan rsp in next req*/
2098 cur_len = rem_len;
2099 break;
2100 }
2101 pPrev = pHead;
2102 pHead = pHead->pNext;
2103 pAdapter->pBatchScanRsp = pHead;
Rajeev Kumarbe17d8b2014-01-10 15:39:45 -08002104 if (TRUE == pPrev->ApInfo.isLastAp)
2105 {
2106 pAdapter->prev_batch_id = 0;
2107 }
2108 else
2109 {
2110 pAdapter->prev_batch_id = pPrev->ApInfo.batchId;
2111 }
Rajeev79dbe4c2013-10-05 11:03:42 +05302112 vos_mem_free(pPrev);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08002113 pPrev = NULL;
Rajeev79dbe4c2013-10-05 11:03:42 +05302114 }
2115
2116 return cur_len;
2117}/*End of hdd_populate_user_batch_scan_rsp*/
2118
2119/**---------------------------------------------------------------------------
2120
2121 \brief hdd_return_batch_scan_rsp_to_user () - This function returns batch
2122 scan response data from HDD queue to user space
2123 It does following in detail:
2124 a) if HDD has enough data in its queue then it 1st copies data to user
2125 space and then send get batch scan indication message to FW. In this
2126 case it does not wait on any event and batch scan response data will
2127 be populated in HDD response queue in MC thread context after receiving
2128 indication from FW
2129 b) else send get batch scan indication message to FW and wait on an event
2130 which will be set once HDD receives complete batch scan response from
2131 FW and then this function returns batch scan response to user space
2132
2133 \param - pAdapter Pointer to HDD adapter
2134 \param - pPrivData Pointer to priv_data
2135
2136 \return - 0 for success -EFAULT for failure
2137
2138 --------------------------------------------------------------------------*/
2139
2140int hdd_return_batch_scan_rsp_to_user
2141(
2142 hdd_adapter_t* pAdapter,
2143 hdd_priv_data_t *pPrivData,
2144 tANI_U8 *command
2145)
2146{
2147 tANI_U8 *pDest;
2148 tANI_U32 count = 0;
2149 tANI_U32 len = 0;
2150 tANI_U32 cur_len = 0;
2151 tANI_U32 rem_len = 0;
2152 eHalStatus halStatus;
2153 unsigned long rc;
2154 tSirTriggerBatchScanResultInd *pReq;
2155
2156 pReq = &pAdapter->hddTriggerBatchScanResultInd;
2157 pReq->param = 0;/*batch scan client*/
2158 pDest = (tANI_U8 *)(command + pPrivData->used_len);
2159 pAdapter->hdd_wait_for_get_batch_scan_rsp = FALSE;
2160
2161 cur_len = pPrivData->used_len;
2162 if (pPrivData->total_len > pPrivData->used_len)
2163 {
2164 rem_len = pPrivData->total_len - pPrivData->used_len;
2165 }
2166 else
2167 {
2168 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2169 "%s: Invalid user data buffer total_len %d used_len %d",
2170 __func__, pPrivData->total_len, pPrivData->used_len);
2171 return -EFAULT;
2172 }
2173
2174 mutex_lock(&pAdapter->hdd_batch_scan_lock);
2175 len = hdd_populate_user_batch_scan_rsp(pAdapter, pDest,
2176 cur_len, rem_len);
2177 mutex_unlock(&pAdapter->hdd_batch_scan_lock);
2178
2179 /*enough scan result available in cache to return to user space or
2180 scan result needs to be fetched 1st from fw and then return*/
Rajeev Kumar99db6262013-11-11 15:23:36 -08002181 if (len == cur_len)
Rajeev79dbe4c2013-10-05 11:03:42 +05302182 {
2183 pAdapter->hdd_wait_for_get_batch_scan_rsp = TRUE;
2184 halStatus = sme_TriggerBatchScanResultInd(
2185 WLAN_HDD_GET_HAL_CTX(pAdapter), pReq,
2186 pAdapter->sessionId, hdd_batch_scan_result_ind_callback,
2187 pAdapter);
2188 if ( eHAL_STATUS_SUCCESS == halStatus )
2189 {
2190 if (TRUE == pAdapter->hdd_wait_for_get_batch_scan_rsp)
2191 {
2192 INIT_COMPLETION(pAdapter->hdd_get_batch_scan_req_var);
2193 rc = wait_for_completion_timeout(
2194 &pAdapter->hdd_get_batch_scan_req_var,
2195 msecs_to_jiffies(HDD_GET_BATCH_SCAN_RSP_TIME_OUT));
Abhishek Singh00b71972016-01-07 10:51:04 +05302196 if (0 >= rc)
Rajeev79dbe4c2013-10-05 11:03:42 +05302197 {
2198 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Abhishek Singh00b71972016-01-07 10:51:04 +05302199 "%s: wait on hdd_get_batch_scan_req_var failed %ld",
2200 __func__, rc);
Rajeev79dbe4c2013-10-05 11:03:42 +05302201 return -EFAULT;
2202 }
2203 }
2204
2205 len = snprintf(pDest, HDD_BATCH_SCAN_AP_META_INFO_SIZE,
Jeff Johnson02797792013-10-26 19:17:13 -07002206 "scancount=%u\n", pAdapter->numScanList);
Rajeev79dbe4c2013-10-05 11:03:42 +05302207 pDest += len;
2208 cur_len += len;
2209
2210 mutex_lock(&pAdapter->hdd_batch_scan_lock);
2211 len = hdd_populate_user_batch_scan_rsp(pAdapter, pDest,
2212 cur_len, rem_len);
2213 mutex_unlock(&pAdapter->hdd_batch_scan_lock);
2214
2215 count = 0;
2216 len = (len - pPrivData->used_len);
2217 pDest = (command + pPrivData->used_len);
2218 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Rajeev Kumar99db6262013-11-11 15:23:36 -08002219 "NEW BATCH SCAN RESULT:");
Rajeev79dbe4c2013-10-05 11:03:42 +05302220 while(count < len)
2221 {
2222 printk("%c", *(pDest + count));
2223 count++;
2224 }
2225 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2226 "%s: copy %d data to user buffer", __func__, len);
2227 if (copy_to_user(pPrivData->buf, pDest, len))
2228 {
2229 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2230 "%s: failed to copy data to user buffer", __func__);
2231 return -EFAULT;
2232 }
2233 }
2234 else
2235 {
2236 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2237 "sme_GetBatchScanScan returned failure halStatus %d",
2238 halStatus);
2239 return -EINVAL;
2240 }
2241 }
2242 else
2243 {
Rajeev79dbe4c2013-10-05 11:03:42 +05302244 count = 0;
2245 len = (len - pPrivData->used_len);
2246 pDest = (command + pPrivData->used_len);
2247 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Rajeev Kumar99db6262013-11-11 15:23:36 -08002248 "REMAINING TRUNCATED BATCH SCAN RESULT:");
Rajeev79dbe4c2013-10-05 11:03:42 +05302249 while(count < len)
2250 {
2251 printk("%c", *(pDest + count));
2252 count++;
2253 }
Rajeev Kumar99db6262013-11-11 15:23:36 -08002254 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2255 "%s: copy %d data to user buffer", __func__, len);
Rajeev79dbe4c2013-10-05 11:03:42 +05302256 if (copy_to_user(pPrivData->buf, pDest, len))
2257 {
2258 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2259 "%s: failed to copy data to user buffer", __func__);
2260 return -EFAULT;
2261 }
Rajeev79dbe4c2013-10-05 11:03:42 +05302262 }
2263
2264 return 0;
2265} /*End of hdd_return_batch_scan_rsp_to_user*/
2266
Rajeev Kumar8b373292014-01-08 20:36:55 -08002267/**---------------------------------------------------------------------------
2268
2269 \brief hdd_handle_batch_scan_ioctl () - This function handles WLS_BATCHING
2270 IOCTLs from user space. Following BATCH SCAN DEV IOCTs are handled:
2271 WLS_BATCHING VERSION
2272 WLS_BATCHING SET
2273 WLS_BATCHING GET
2274 WLS_BATCHING STOP
2275
2276 \param - pAdapter Pointer to HDD adapter
2277 \param - pPrivdata Pointer to priv_data
2278 \param - command Pointer to command
2279
2280 \return - 0 for success -EFAULT for failure
2281
2282 --------------------------------------------------------------------------*/
2283
2284int hdd_handle_batch_scan_ioctl
2285(
2286 hdd_adapter_t *pAdapter,
2287 hdd_priv_data_t *pPrivdata,
2288 tANI_U8 *command
2289)
2290{
2291 int ret = 0;
Yue Mae36e3552014-03-05 17:06:20 -08002292 hdd_context_t *pHddCtx;
2293
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302294 ENTER();
2295
Yue Mae36e3552014-03-05 17:06:20 -08002296 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
2297 ret = wlan_hdd_validate_context(pHddCtx);
2298 if (ret)
2299 {
Yue Mae36e3552014-03-05 17:06:20 -08002300 goto exit;
2301 }
Rajeev Kumar8b373292014-01-08 20:36:55 -08002302
2303 if (strncmp(command, "WLS_BATCHING VERSION", 20) == 0)
2304 {
2305 char extra[32];
2306 tANI_U8 len = 0;
2307 tANI_U8 version = HDD_BATCH_SCAN_VERSION;
2308
2309 if (FALSE == sme_IsFeatureSupportedByFW(BATCH_SCAN))
2310 {
2311 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2312 "%s: Batch scan feature is not supported by FW", __func__);
2313 ret = -EINVAL;
2314 goto exit;
2315 }
2316
2317 len = scnprintf(extra, sizeof(extra), "WLS_BATCHING_VERSION %d",
2318 version);
2319 if (copy_to_user(pPrivdata->buf, &extra, len + 1))
2320 {
2321 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2322 "%s: failed to copy data to user buffer", __func__);
2323 ret = -EFAULT;
2324 goto exit;
2325 }
2326 ret = HDD_BATCH_SCAN_VERSION;
2327 }
2328 else if (strncmp(command, "WLS_BATCHING SET", 16) == 0)
2329 {
2330 int status;
2331 tANI_U8 *value = (command + 16);
2332 eHalStatus halStatus;
2333 unsigned long rc;
2334 tSirSetBatchScanReq *pReq = &pAdapter->hddSetBatchScanReq;
2335 tSirSetBatchScanRsp *pRsp = &pAdapter->hddSetBatchScanRsp;
2336
2337 if (FALSE == sme_IsFeatureSupportedByFW(BATCH_SCAN))
2338 {
2339 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2340 "%s: Batch scan feature is not supported by FW", __func__);
2341 ret = -EINVAL;
2342 goto exit;
2343 }
2344
2345 if ((WLAN_HDD_INFRA_STATION != pAdapter->device_mode) &&
2346 (WLAN_HDD_P2P_CLIENT != pAdapter->device_mode) &&
2347 (WLAN_HDD_P2P_GO != pAdapter->device_mode) &&
2348 (WLAN_HDD_P2P_DEVICE != pAdapter->device_mode))
2349 {
2350 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05302351 "Received WLS_BATCHING SET command in invalid mode %s (%d) "
Rajeev Kumar8b373292014-01-08 20:36:55 -08002352 "WLS_BATCHING_SET is only allowed in infra STA/P2P client mode",
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05302353 hdd_device_modetoString(pAdapter->device_mode),
2354 pAdapter->device_mode);
Rajeev Kumar8b373292014-01-08 20:36:55 -08002355 ret = -EINVAL;
2356 goto exit;
2357 }
2358
2359 status = hdd_parse_set_batchscan_command(value, pReq);
2360 if (status)
2361 {
2362 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2363 "Invalid WLS_BATCHING SET command");
2364 ret = -EINVAL;
2365 goto exit;
2366 }
2367
2368
2369 pAdapter->hdd_wait_for_set_batch_scan_rsp = TRUE;
2370 halStatus = sme_SetBatchScanReq(WLAN_HDD_GET_HAL_CTX(pAdapter), pReq,
2371 pAdapter->sessionId, hdd_set_batch_scan_req_callback,
2372 pAdapter);
2373
2374 if ( eHAL_STATUS_SUCCESS == halStatus )
2375 {
Mahesh A Saptasagar5f568172014-05-14 17:02:33 +05302376 char extra[32];
2377 tANI_U8 len = 0;
2378 tANI_U8 mScan = 0;
2379
Rajeev Kumar8b373292014-01-08 20:36:55 -08002380 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2381 "sme_SetBatchScanReq returned success halStatus %d",
2382 halStatus);
2383 if (TRUE == pAdapter->hdd_wait_for_set_batch_scan_rsp)
2384 {
2385 INIT_COMPLETION(pAdapter->hdd_set_batch_scan_req_var);
2386 rc = wait_for_completion_timeout(
2387 &pAdapter->hdd_set_batch_scan_req_var,
2388 msecs_to_jiffies(HDD_SET_BATCH_SCAN_REQ_TIME_OUT));
2389 if (0 == rc)
2390 {
2391 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2392 "%s: Timeout waiting for set batch scan to complete",
2393 __func__);
2394 ret = -EINVAL;
2395 goto exit;
2396 }
2397 }
2398 if ( !pRsp->nScansToBatch )
2399 {
2400 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2401 "%s: Received set batch scan failure response from FW",
2402 __func__);
2403 ret = -EINVAL;
2404 goto exit;
2405 }
2406 /*As per the Batch Scan Framework API we should return the MIN of
2407 either MSCAN or the max # of scans firmware can cache*/
Mahesh A Saptasagar5f568172014-05-14 17:02:33 +05302408 mScan = MIN(pReq->numberOfScansToBatch , pRsp->nScansToBatch);
Rajeev Kumar8b373292014-01-08 20:36:55 -08002409
2410 pAdapter->batchScanState = eHDD_BATCH_SCAN_STATE_STARTED;
2411
2412 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2413 "%s: request MSCAN %d response MSCAN %d ret %d",
Mahesh A Saptasagar5f568172014-05-14 17:02:33 +05302414 __func__, pReq->numberOfScansToBatch, pRsp->nScansToBatch, mScan);
2415 len = scnprintf(extra, sizeof(extra), "%d", mScan);
2416 if (copy_to_user(pPrivdata->buf, &extra, len + 1))
2417 {
2418 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2419 "%s: failed to copy MSCAN value to user buffer", __func__);
2420 ret = -EFAULT;
2421 goto exit;
2422 }
Rajeev Kumar8b373292014-01-08 20:36:55 -08002423 }
2424 else
2425 {
2426 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2427 "sme_SetBatchScanReq returned failure halStatus %d",
2428 halStatus);
2429 ret = -EINVAL;
2430 goto exit;
2431 }
2432 }
2433 else if (strncmp(command, "WLS_BATCHING STOP", 17) == 0)
2434 {
2435 eHalStatus halStatus;
2436 tSirStopBatchScanInd *pInd = &pAdapter->hddStopBatchScanInd;
2437 pInd->param = 0;
2438
2439 if (FALSE == sme_IsFeatureSupportedByFW(BATCH_SCAN))
2440 {
2441 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2442 "%s: Batch scan feature is not supported by FW", __func__);
2443 ret = -EINVAL;
2444 goto exit;
2445 }
2446
2447 if (eHDD_BATCH_SCAN_STATE_STARTED != pAdapter->batchScanState)
2448 {
Deepthi Gowribfd17132014-11-14 17:59:04 +05302449 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Rajeev Kumar8b373292014-01-08 20:36:55 -08002450 "Batch scan is not yet enabled batch scan state %d",
2451 pAdapter->batchScanState);
2452 ret = -EINVAL;
2453 goto exit;
2454 }
2455
Kiet Lamaa8e15a2014-02-11 23:30:06 -08002456 mutex_lock(&pAdapter->hdd_batch_scan_lock);
2457 hdd_deinit_batch_scan(pAdapter);
2458 mutex_unlock(&pAdapter->hdd_batch_scan_lock);
2459
Rajeev Kumar8b373292014-01-08 20:36:55 -08002460 pAdapter->batchScanState = eHDD_BATCH_SCAN_STATE_STOPPED;
2461
2462 halStatus = sme_StopBatchScanInd(WLAN_HDD_GET_HAL_CTX(pAdapter), pInd,
2463 pAdapter->sessionId);
2464 if ( eHAL_STATUS_SUCCESS == halStatus )
2465 {
2466 ret = 0;
2467 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2468 "sme_StopBatchScanInd returned success halStatus %d",
2469 halStatus);
2470 }
2471 else
2472 {
2473 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2474 "sme_StopBatchScanInd returned failure halStatus %d",
2475 halStatus);
2476 ret = -EINVAL;
2477 goto exit;
2478 }
2479 }
2480 else if (strncmp(command, "WLS_BATCHING GET", 16) == 0)
2481 {
2482 tANI_U32 remain_len;
2483
2484 if (FALSE == sme_IsFeatureSupportedByFW(BATCH_SCAN))
2485 {
2486 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2487 "%s: Batch scan feature is not supported by FW", __func__);
2488 ret = -EINVAL;
2489 goto exit;
2490 }
2491
2492 if (eHDD_BATCH_SCAN_STATE_STARTED != pAdapter->batchScanState)
2493 {
Deepthi Gowribfd17132014-11-14 17:59:04 +05302494 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Rajeev Kumar8b373292014-01-08 20:36:55 -08002495 "Batch scan is not yet enabled could not return results"
2496 "Batch Scan state %d",
2497 pAdapter->batchScanState);
2498 ret = -EINVAL;
2499 goto exit;
2500 }
2501
2502 pPrivdata->used_len = 16;
2503 remain_len = pPrivdata->total_len - pPrivdata->used_len;
2504 if (remain_len < pPrivdata->total_len)
2505 {
2506 /*Clear previous batch scan response data if any*/
2507 vos_mem_zero((tANI_U8 *)(command + pPrivdata->used_len), remain_len);
2508 }
2509 else
2510 {
2511 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2512 "Invalid total length from user space can't fetch batch"
2513 " scan response total_len %d used_len %d remain len %d",
2514 pPrivdata->total_len, pPrivdata->used_len, remain_len);
2515 ret = -EINVAL;
2516 goto exit;
2517 }
2518 ret = hdd_return_batch_scan_rsp_to_user(pAdapter, pPrivdata, command);
2519 }
2520
2521exit:
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302522 EXIT();
Rajeev Kumar8b373292014-01-08 20:36:55 -08002523 return ret;
2524}
2525
2526
Rajeev79dbe4c2013-10-05 11:03:42 +05302527#endif/*End of FEATURE_WLAN_BATCH_SCAN*/
2528
Selvaraj, Sridhar5aff1ed2016-06-18 01:26:23 +05302529#if defined(WLAN_FEATURE_VOWIFI_11R) || defined(FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
2530/**
2531 * hdd_assign_handoff_src_reassoc - Set handoff source as REASSOC
2532 * to Handoff request
2533 * @handoffInfo: Pointer to Handoff request
2534 * @src: enum of handoff_src
2535 * Return: None
2536 */
2537#ifndef QCA_WIFI_ISOC
2538static inline void hdd_assign_handoff_src_reassoc(tCsrHandoffRequest
2539 *handoffInfo, handoff_src src)
2540{
2541 handoffInfo->src = src;
2542}
2543#else
2544static inline void hdd_assign_handoff_src_reassoc(tCsrHandoffRequest
2545 *handoffInfo, handoff_src src)
2546{
2547}
2548#endif
2549
2550/**
Selvaraj, Sridhar4fa15232016-06-18 12:27:25 +05302551 * hdd_reassoc() - perform a user space-directed reassoc
Selvaraj, Sridhar5aff1ed2016-06-18 01:26:23 +05302552 *
2553 * @pAdapter: Adapter upon which the command was received
2554 * @bssid: BSSID with which to reassociate
2555 * @channel: channel upon which to reassociate
Selvaraj, Sridhar4fa15232016-06-18 12:27:25 +05302556 * @src: The source for the trigger of this action
Selvaraj, Sridhar5aff1ed2016-06-18 01:26:23 +05302557 *
2558 * Return: 0 for success non-zero for failure
2559 */
2560#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
Selvaraj, Sridhar8ecb4192016-06-23 17:50:49 +05302561int hdd_reassoc(hdd_adapter_t *pAdapter, const tANI_U8 *bssid,
Selvaraj, Sridhar4fa15232016-06-18 12:27:25 +05302562 const tANI_U8 channel, const handoff_src src)
Selvaraj, Sridhar5aff1ed2016-06-18 01:26:23 +05302563{
2564 hdd_station_ctx_t *pHddStaCtx;
2565 tCsrHandoffRequest handoffInfo;
2566 hdd_context_t *pHddCtx = NULL;
2567 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
2568
2569 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
2570
2571 /* if not associated, no need to proceed with reassoc */
2572 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState) {
2573 hddLog(LOG1, FL("Not associated"));
2574 return -EINVAL;
2575 }
2576
2577 /* if the target bssid is same as currently associated AP,
2578 then no need to proceed with reassoc */
2579 if (!memcmp(bssid, pHddStaCtx->conn_info.bssId, sizeof(tSirMacAddr))) {
2580 hddLog(LOG1, FL("Reassoc BSSID is same as currently associated AP bssid"));
2581 return -EINVAL;
2582 }
2583
2584 /* Check channel number is a valid channel number */
2585 if (VOS_STATUS_SUCCESS !=
2586 wlan_hdd_validate_operation_channel(pAdapter, channel)) {
2587 hddLog(LOGE, FL("Invalid Channel %d"), channel);
2588 return -EINVAL;
2589 }
2590
2591 /* Proceed with reassoc */
2592 handoffInfo.channel = channel;
Selvaraj, Sridhar4fa15232016-06-18 12:27:25 +05302593 hdd_assign_handoff_src_reassoc(&handoffInfo, src);
Selvaraj, Sridhar5aff1ed2016-06-18 01:26:23 +05302594 memcpy(handoffInfo.bssid, bssid, sizeof(tSirMacAddr));
2595 sme_HandoffRequest(pHddCtx->hHal, &handoffInfo);
2596 return 0;
2597}
2598#else
Selvaraj, Sridhar8ecb4192016-06-23 17:50:49 +05302599int hdd_reassoc(hdd_adapter_t *pAdapter, const tANI_U8 *bssid,
Selvaraj, Sridhar4fa15232016-06-18 12:27:25 +05302600 const tANI_U8 channel, const handoff_src src)
Selvaraj, Sridhar5aff1ed2016-06-18 01:26:23 +05302601{
2602 return -EPERM;
2603}
2604#endif
2605
2606/**
2607 * hdd_parse_reassoc_v1() - parse version 1 of the REASSOC command
2608 * This function parses the v1 REASSOC command with the format
2609 * REASSOC xx:xx:xx:xx:xx:xx CH where "xx:xx:xx:xx:xx:xx" is the
2610 * Hex-ASCII representation of the BSSID and CH is the ASCII
2611 * representation of the channel. For example
2612 * REASSOC 00:0a:0b:11:22:33 48
2613 *
2614 * @pAdapter: Adapter upon which the command was received
2615 * @command: ASCII text command that was received
2616 *
2617 * Return: 0 for success non-zero for failure
2618 */
2619static int
2620hdd_parse_reassoc_v1(hdd_adapter_t *pAdapter, const char *command)
2621{
2622 tANI_U8 channel = 0;
2623 tSirMacAddr bssid;
2624 int ret;
2625
2626 ret = hdd_parse_reassoc_command_v1_data(command, bssid, &channel);
2627 if (ret)
2628 hddLog(LOGE, FL("Failed to parse reassoc command data"));
2629 else
Selvaraj, Sridhar4fa15232016-06-18 12:27:25 +05302630 ret = hdd_reassoc(pAdapter, bssid, channel, REASSOC);
Selvaraj, Sridhar5aff1ed2016-06-18 01:26:23 +05302631
2632 return ret;
2633}
2634
2635/**
2636 * hdd_parse_reassoc_v2() - parse version 2 of the REASSOC command
2637 * This function parses the v2 REASSOC command with the format
2638 * REASSOC <android_wifi_reassoc_params>
2639 *
2640 * @pAdapter: Adapter upon which the command was received
2641 * @command: command that was received, ASCII command followed
2642 * by binary data
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05302643 * @total_len: Total length of the command received
Selvaraj, Sridhar5aff1ed2016-06-18 01:26:23 +05302644 *
2645 * Return: 0 for success non-zero for failure
2646 */
2647static int
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05302648hdd_parse_reassoc_v2(hdd_adapter_t *pAdapter, const char *command,
2649 int total_len)
Selvaraj, Sridhar5aff1ed2016-06-18 01:26:23 +05302650{
2651 struct android_wifi_reassoc_params params;
2652 tSirMacAddr bssid;
2653 int ret;
2654
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05302655 if (total_len < sizeof(params) + 8) {
2656 hddLog(LOGE, FL("Invalid command length"));
2657 return -EINVAL;
2658 }
2659
Selvaraj, Sridhar5aff1ed2016-06-18 01:26:23 +05302660 /* The params are located after "REASSOC " */
2661 memcpy(&params, command + 8, sizeof(params));
2662
2663 if (!mac_pton(params.bssid, (u8 *)&bssid)) {
2664 hddLog(LOGE, FL("MAC address parsing failed"));
2665 ret = -EINVAL;
2666 } else {
Selvaraj, Sridhar4fa15232016-06-18 12:27:25 +05302667 ret = hdd_reassoc(pAdapter, bssid, params.channel, REASSOC);
Selvaraj, Sridhar5aff1ed2016-06-18 01:26:23 +05302668 }
2669 return ret;
2670}
2671
2672/**
2673 * hdd_parse_reassoc() - parse the REASSOC command
2674 * There are two different versions of the REASSOC command.Version 1
2675 * of the command contains a parameter list that is ASCII characters
2676 * whereas version 2 contains a combination of ASCII and binary
2677 * payload. Determine if a version 1 or a version 2 command is being
2678 * parsed by examining the parameters, and then dispatch the parser
2679 * that is appropriate for the command.
2680 *
2681 * @pAdapter: Adapter upon which the command was received
2682 * @command: command that was received
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05302683 * @total_len: Total length of the command received
Selvaraj, Sridhar5aff1ed2016-06-18 01:26:23 +05302684 *
2685 * Return: 0 for success non-zero for failure
2686 */
2687static int
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05302688hdd_parse_reassoc(hdd_adapter_t *pAdapter, const char *command, int total_len)
Selvaraj, Sridhar5aff1ed2016-06-18 01:26:23 +05302689{
2690 int ret;
2691
2692 /*
2693 * both versions start with "REASSOC"
2694 * v1 has a bssid and channel # as an ASCII string
2695 * REASSOC xx:xx:xx:xx:xx:xx CH
2696 * v2 has a C struct
2697 * REASSOC <binary c struct>
2698 *
2699 * The first field in the v2 struct is also the bssid in ASCII.
2700 * But in the case of a v2 message the BSSID is NUL-terminated.
2701 * Hence we can peek at that offset to see if this is V1 or V2
2702 * REASSOC xx:xx:xx:xx:xx:xx*
2703 * 1111111111222222
2704 * 01234567890123456789012345
2705 */
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05302706
2707 if (total_len < 26) {
2708 hddLog(LOGE, FL("Invalid command (total_len=%d)"), total_len);
2709 return -EINVAL;
2710 }
2711
Selvaraj, Sridhar5aff1ed2016-06-18 01:26:23 +05302712 if (command[25])
2713 ret = hdd_parse_reassoc_v1(pAdapter, command);
2714 else
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05302715 ret = hdd_parse_reassoc_v2(pAdapter, command, total_len);
Selvaraj, Sridhar5aff1ed2016-06-18 01:26:23 +05302716
2717 return ret;
2718}
2719#endif /* WLAN_FEATURE_VOWIFI_11R || FEATURE_WLAN_ESE FEATURE_WLAN_LFR */
2720
Hanumanth Reddy Pothula7aa4bea2018-04-09 17:19:03 +05302721struct bcn_miss_rate_priv {
2722 int bcn_miss_rate;
2723};
2724
2725/**
2726 * get_bcn_miss_rate_cb() callback invoked on receiving beacon miss
2727 * rate from firmware
2728 * @status: Status of get beacon miss rate operation
2729 * @bcnMissRate: Beacon miss rate
2730 * @context: Context passed while registering callback
2731 *
2732 * This function is invoked by WDA layer on receiving
2733 * WDI_GET_BCN_MISS_RATE_RSP
2734 *
2735 * Return: None
2736 */
2737static void get_bcn_miss_rate_cb(VOS_STATUS status, int bcnMissRate,
2738 void *context)
c_hpothu92367912014-05-01 15:18:17 +05302739{
Hanumanth Reddy Pothula7aa4bea2018-04-09 17:19:03 +05302740 struct hdd_request *request;
2741 struct bcn_miss_rate_priv *priv;
c_hpothu39eb1e32014-06-26 16:31:50 +05302742
Hanumanth Reddy Pothula7aa4bea2018-04-09 17:19:03 +05302743 request = hdd_request_get(context);
2744 if (!request) {
2745 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Obsolete request"));
2746 return;
2747 }
c_hpothu92367912014-05-01 15:18:17 +05302748
Hanumanth Reddy Pothula7aa4bea2018-04-09 17:19:03 +05302749 priv = hdd_request_priv(request);
c_hpothu92367912014-05-01 15:18:17 +05302750
Hanumanth Reddy Pothula7aa4bea2018-04-09 17:19:03 +05302751 if (VOS_STATUS_SUCCESS == status)
2752 priv->bcn_miss_rate = bcnMissRate;
2753 else
2754 hddLog(VOS_TRACE_LEVEL_ERROR, FL("failed to get bcnMissRate"));
c_hpothu92367912014-05-01 15:18:17 +05302755
Hanumanth Reddy Pothula7aa4bea2018-04-09 17:19:03 +05302756 hdd_request_complete(request);
2757 hdd_request_put(request);
Hanumanth Reddy Pothulad0d3c172018-05-02 18:53:05 +05302758
Hanumanth Reddy Pothula7aa4bea2018-04-09 17:19:03 +05302759 return;
c_hpothu92367912014-05-01 15:18:17 +05302760}
2761
Hanumanth Reddy Pothula7aa4bea2018-04-09 17:19:03 +05302762struct fw_stats_priv {
2763 tSirFwStatsResult *fw_stats;
2764};
2765
2766/**
2767 * hdd_fw_stats_cb() callback invoked on receiving firmware stats
2768 * from firmware
2769 * @status: Status of get firmware stats operation
2770 * @fwStatsResult: firmware stats
2771 * @context: Context passed while registering callback
2772 *
2773 * This function is invoked by WDA layer on receiving
2774 * WDI_GET_FW_STATS_RSP
2775 *
2776 * Return: None
2777 */
2778static void hdd_fw_stats_cb(VOS_STATUS status,
2779 tSirFwStatsResult *fwStatsResult, void *context)
Satyanarayana Dash72806012014-12-02 14:30:08 +05302780{
Hanumanth Reddy Pothula7aa4bea2018-04-09 17:19:03 +05302781 struct hdd_request *request;
2782 struct fw_stats_priv *priv;
Satyanarayana Dash72806012014-12-02 14:30:08 +05302783
Hanumanth Reddy Pothula7aa4bea2018-04-09 17:19:03 +05302784 hddLog(VOS_TRACE_LEVEL_INFO, FL("with status = %d"),status);
Satyanarayana Dash72806012014-12-02 14:30:08 +05302785
Hanumanth Reddy Pothula7aa4bea2018-04-09 17:19:03 +05302786 request = hdd_request_get(context);
2787 if (!request) {
2788 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Obsolete request"));
2789 return;
2790 }
2791 priv = hdd_request_priv(request);
2792
2793 if (VOS_STATUS_SUCCESS == status)
2794 *priv->fw_stats = *fwStatsResult;
2795 else
2796 priv->fw_stats = NULL;
2797
2798 hdd_request_complete(request);
2799 hdd_request_put(request);
2800 return;
Satyanarayana Dash72806012014-12-02 14:30:08 +05302801}
2802
jge35567202017-06-21 16:39:38 +08002803/*
2804 *hdd_parse_setmaxtxpower_command() - HDD Parse MAXTXPOWER command
2805 *@pValue Pointer to MAXTXPOWER command
2806 *@pTxPower Pointer to tx power
2807 *
2808 *This function parses the MAXTXPOWER command passed in the format
2809 * MAXTXPOWER<space>X(Tx power in dbm)
2810 * For example input commands:
2811 * 1) MAXTXPOWER -8 -> This is translated into set max TX power to -8 dbm
2812 * 2) MAXTXPOWER -23 -> This is translated into set max TX power to -23 dbm
2813 *
2814 *return - 0 for success non-zero for failure
2815 */
2816static int hdd_parse_setmaxtxpower_command(unsigned char *pValue, int *pTxPower)
2817{
2818 unsigned char *inPtr = pValue;
2819 int tempInt;
2820 int v = 0;
2821 *pTxPower = 0;
2822
2823 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
2824 /* no argument after the command */
2825 if (NULL == inPtr)
2826 return -EINVAL;
2827 /* no space after the command */
2828 else if (SPACE_ASCII_VALUE != *inPtr)
2829 return -EINVAL;
2830
2831 /* removing empty spaces */
2832 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
2833
2834 /* no argument followed by spaces */
2835 if ('\0' == *inPtr)
2836 return 0;
2837
2838 v = kstrtos32(inPtr, 10, &tempInt);
2839
2840 /* Range checking for passed parameter */
2841 if ((tempInt < HDD_MIN_TX_POWER) || (tempInt > HDD_MAX_TX_POWER))
2842 return -EINVAL;
2843
2844 *pTxPower = tempInt;
2845
2846 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2847 "SETMAXTXPOWER: %d", *pTxPower);
2848
2849 return 0;
2850}
2851
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302852static int hdd_get_dwell_time(hdd_config_t *pCfg, tANI_U8 *command, char *extra, tANI_U8 n, tANI_U8 *len)
2853{
2854 int ret = 0;
2855
2856 if (!pCfg || !command || !extra || !len)
2857 {
2858 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2859 "%s: argument passsed for GETDWELLTIME is incorrect", __func__);
2860 ret = -EINVAL;
2861 return ret;
2862 }
2863
2864 if (strncmp(command, "GETDWELLTIME ACTIVE MAX", 23) == 0)
2865 {
2866 *len = scnprintf(extra, n, "GETDWELLTIME ACTIVE MAX %u\n",
2867 (int)pCfg->nActiveMaxChnTime);
2868 return ret;
2869 }
2870 else if (strncmp(command, "GETDWELLTIME ACTIVE MIN", 23) == 0)
2871 {
2872 *len = scnprintf(extra, n, "GETDWELLTIME ACTIVE MIN %u\n",
2873 (int)pCfg->nActiveMinChnTime);
2874 return ret;
2875 }
2876 else if (strncmp(command, "GETDWELLTIME PASSIVE MAX", 24) == 0)
2877 {
2878 *len = scnprintf(extra, n, "GETDWELLTIME PASSIVE MAX %u\n",
2879 (int)pCfg->nPassiveMaxChnTime);
2880 return ret;
2881 }
2882 else if (strncmp(command, "GETDWELLTIME PASSIVE MIN", 24) == 0)
2883 {
2884 *len = scnprintf(extra, n, "GETDWELLTIME PASSIVE MIN %u\n",
2885 (int)pCfg->nPassiveMinChnTime);
2886 return ret;
2887 }
Rajesh Babu Prathipati0fd227e2014-07-05 12:50:00 +05302888 else if (strncmp(command, "GETDWELLTIME", 12) == 0)
2889 {
2890 *len = scnprintf(extra, n, "GETDWELLTIME %u \n",
2891 (int)pCfg->nActiveMaxChnTime);
2892 return ret;
2893 }
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302894 else
2895 {
2896 ret = -EINVAL;
2897 }
2898
2899 return ret;
2900}
2901
Dundi Ravitejaae5adf42018-04-23 20:44:47 +05302902/**
2903 * hdd_btc_get_dwell_time() - Get BTC dwell time parameters
2904 * @pCfg: Pointer to HDD context
2905 * @command: ASCII text command that is received
2906 * @extra: Pointer to copy data sent to user
2907 * @n: size of 'extra' buffer
2908 * @len: length copied to 'extra' buffer
2909 *
2910 * Driver commands:
2911 * wpa_cli DRIVER BTCGETDWELLTIME ESCO MAX
2912 * wpa_cli DRIVER BTCGETDWELLTIME ESCO MIN
2913 * wpa_cli DRIVER BTCGETDWELLTIME SCO MAX
2914 * wpa_cli DRIVER BTCGETDWELLTIME SCO MIN
2915 *
2916 * Return: 0 for success non-zero for failure
2917 */
2918
2919static int hdd_btc_get_dwell_time(hdd_config_t *pCfg, tANI_U8 *command,
2920 char *extra, tANI_U8 n, tANI_U8 *len)
2921{
2922 int ret = 0;
2923
2924 if (!pCfg || !command || !extra || !len)
2925 {
2926 hddLog(LOGE, FL("Argument passsed for BTCGETDWELLTIME is incorrect"));
2927 ret = -EINVAL;
2928 return ret;
2929 }
2930
2931 if (strncmp(command, "BTCGETDWELLTIME ESCO MAX", 24) == 0)
2932 {
2933 *len = scnprintf(extra, n, "BTCGETDWELLTIME ESCO MAX %u\n",
2934 (int)pCfg->max_chntime_btc_esco);
2935 return ret;
2936 }
2937 else if (strncmp(command, "BTCGETDWELLTIME ESCO MIN", 24) == 0)
2938 {
2939 *len = scnprintf(extra, n, "BTCGETDWELLTIME ESCO MIN %u\n",
2940 (int)pCfg->min_chntime_btc_esco);
2941 return ret;
2942 }
2943 else if (strncmp(command, "BTCGETDWELLTIME SCO MAX", 23) == 0)
2944 {
2945 *len = scnprintf(extra, n, "BTCGETDWELLTIME SCO MAX %u\n",
2946 (int)pCfg->max_chntime_btc_sco);
2947 return ret;
2948 }
2949 else if (strncmp(command, "BTCGETDWELLTIME SCO MIN", 23) == 0)
2950 {
2951 *len = scnprintf(extra, n, "BTCGETDWELLTIME SCO MIN %u\n",
2952 (int)pCfg->min_chntime_btc_sco);
2953 return ret;
2954 }
2955 else
2956 {
2957 ret = -EINVAL;
2958 }
2959
2960 return ret;
2961}
2962
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05302963int hdd_drv_cmd_validate(tANI_U8 *command, int len)
2964{
2965 if (command[len] != ' ')
2966 return -EINVAL;
2967
2968 return 0;
2969}
2970
Dundi Ravitejaae5adf42018-04-23 20:44:47 +05302971#ifdef WLAN_AP_STA_CONCURRENCY
2972
2973/**
2974 * hdd_conc_get_dwell_time() - Get concurrency dwell time parameters
2975 * @pCfg: Pointer to HDD context
2976 * @command: ASCII text command that is received
2977 * @extra: Pointer to copy data sent to user
2978 * @n: size of 'extra' buffer
2979 * @len: length copied to 'extra' buffer
2980 *
2981 * Driver commands:
2982 * wpa_cli DRIVER CONCGETDWELLTIME ACTIVE MAX
2983 * wpa_cli DRIVER CONCGETDWELLTIME ACTIVE MIN
2984 * wpa_cli DRIVER CONCGETDWELLTIME PASSIVE MAX
2985 * wpa_cli DRIVER CONCGETDWELLTIME PASSIVE MIN
2986 *
2987 * Return: 0 for success non-zero for failure
2988 */
2989
2990static int hdd_conc_get_dwell_time(hdd_config_t *pCfg, tANI_U8 *command,
2991 char *extra, tANI_U8 n, tANI_U8 *len)
2992{
2993 int ret = 0;
2994
2995 if (!pCfg || !command || !extra || !len)
2996 {
2997 hddLog(LOGE, FL("Argument passsed for CONCGETDWELLTIME is incorrect"));
2998 ret = -EINVAL;
2999 return ret;
3000 }
3001
3002 if (strncmp(command, "CONCGETDWELLTIME ACTIVE MAX", 27) == 0)
3003 {
3004 *len = scnprintf(extra, n, "CONCGETDWELLTIME ACTIVE MAX %u\n",
3005 (int)pCfg->nActiveMaxChnTimeConc);
3006 return ret;
3007 }
3008 else if (strncmp(command, "CONCGETDWELLTIME ACTIVE MIN", 27) == 0)
3009 {
3010 *len = scnprintf(extra, n, "CONCGETDWELLTIME ACTIVE MIN %u\n",
3011 (int)pCfg->nActiveMinChnTimeConc);
3012 return ret;
3013 }
3014 else if (strncmp(command, "CONCGETDWELLTIME PASSIVE MAX", 28) == 0)
3015 {
3016 *len = scnprintf(extra, n, "CONCGETDWELLTIME PASSIVE MAX %u\n",
3017 (int)pCfg->nPassiveMaxChnTimeConc);
3018 return ret;
3019 }
3020 else if (strncmp(command, "CONCGETDWELLTIME PASSIVE MIN", 28) == 0)
3021 {
3022 *len = scnprintf(extra, n, "CONCGETDWELLTIME PASSIVE MIN %u\n",
3023 (int)pCfg->nPassiveMinChnTimeConc);
3024 return ret;
3025 }
3026 else
3027 {
3028 ret = -EINVAL;
3029 }
3030
3031 return ret;
3032}
3033
3034/**
3035 * hdd_conc_set_dwell_time() - Set concurrency dwell time parameters
3036 * @pAdapter: Adapter upon which the command was received
3037 * @command: ASCII text command that is received
3038 *
3039 * Driver commands:
3040 * wpa_cli DRIVER CONCSETDWELLTIME ACTIVE MAX <value>
3041 * wpa_cli DRIVER CONCSETDWELLTIME ACTIVE MIN <value>
3042 * wpa_cli DRIVER CONCSETDWELLTIME PASSIVE MAX <value
3043 * wpa_cli DRIVER CONCSETDWELLTIME PASSIVE MIN <value>
3044 *
3045 * Return: 0 for success non-zero for failure
3046 */
3047
3048static int hdd_conc_set_dwell_time(hdd_adapter_t *pAdapter, tANI_U8 *command)
3049{
3050 tHalHandle hHal;
3051 hdd_config_t *pCfg;
3052 tANI_U8 *value = command;
3053 int val = 0, ret = 0, temp = 0;
3054 tSmeConfigParams smeConfig;
3055
3056 if (!pAdapter || !command || !(pCfg = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini)
3057 || !(hHal = (WLAN_HDD_GET_HAL_CTX(pAdapter))))
3058 {
3059 hddLog(LOGE, FL("Argument passed for CONCSETDWELLTIME is incorrect"));
3060 ret = -EINVAL;
3061 return ret;
3062 }
3063
3064 vos_mem_zero(&smeConfig, sizeof(smeConfig));
3065 sme_GetConfigParam(hHal, &smeConfig);
3066
3067 if (strncmp(command, "CONCSETDWELLTIME ACTIVE MAX", 27) == 0 )
3068 {
3069 if (hdd_drv_cmd_validate(command, 27)) {
3070 hddLog(LOGE, FL("Invalid driver command"));
3071 return -EINVAL;
3072 }
3073
3074 value = value + 28;
3075 temp = kstrtou32(value, 10, &val);
3076 if (temp != 0 || val < CFG_ACTIVE_MAX_CHANNEL_TIME_CONC_MIN ||
3077 val > CFG_ACTIVE_MAX_CHANNEL_TIME_CONC_MAX)
3078 {
3079 hddLog(LOGE, FL("Argument passed for CONCSETDWELLTIME ACTIVE MAX is incorrect"));
3080 ret = -EFAULT;
3081 return ret;
3082 }
3083 pCfg->nActiveMaxChnTimeConc = val;
3084 smeConfig.csrConfig.nActiveMaxChnTimeConc = val;
3085 sme_UpdateConfig(hHal, &smeConfig);
3086 }
3087 else if (strncmp(command, "CONCSETDWELLTIME ACTIVE MIN", 27) == 0)
3088 {
3089 if (hdd_drv_cmd_validate(command, 27)) {
3090 hddLog(LOGE, FL("Invalid driver command"));
3091 return -EINVAL;
3092 }
3093
3094 value = value + 28;
3095 temp = kstrtou32(value, 10, &val);
3096 if (temp !=0 || val < CFG_ACTIVE_MIN_CHANNEL_TIME_CONC_MIN ||
3097 val > CFG_ACTIVE_MIN_CHANNEL_TIME_CONC_MAX)
3098 {
3099 hddLog(LOGE, FL("Argument passsed for CONCSETDWELLTIME ACTIVE MIN is incorrect"));
3100 ret = -EFAULT;
3101 return ret;
3102 }
3103 pCfg->nActiveMinChnTimeConc = val;
3104 smeConfig.csrConfig.nActiveMinChnTimeConc = val;
3105 sme_UpdateConfig(hHal, &smeConfig);
3106 }
3107 else if (strncmp(command, "CONCSETDWELLTIME PASSIVE MAX", 28) == 0)
3108 {
3109 if (hdd_drv_cmd_validate(command, 28)) {
3110 hddLog(LOGE, FL("Invalid driver command"));
3111 return -EINVAL;
3112 }
3113
3114 value = value + 29;
3115 temp = kstrtou32(value, 10, &val);
3116 if (temp != 0 || val < CFG_PASSIVE_MAX_CHANNEL_TIME_CONC_MIN ||
3117 val > CFG_PASSIVE_MAX_CHANNEL_TIME_CONC_MAX)
3118 {
3119 hddLog(LOGE, FL("Argument passed for CONCSETDWELLTIME PASSIVE MAX is incorrect"));
3120 ret = -EFAULT;
3121 return ret;
3122 }
3123 pCfg->nPassiveMaxChnTimeConc = val;
3124 smeConfig.csrConfig.nPassiveMaxChnTimeConc = val;
3125 sme_UpdateConfig(hHal, &smeConfig);
3126 }
3127 else if (strncmp(command, "CONCSETDWELLTIME PASSIVE MIN", 28) == 0)
3128 {
3129 if (hdd_drv_cmd_validate(command, 28)) {
3130 hddLog(LOGE, FL("Invalid driver command"));
3131 return -EINVAL;
3132 }
3133
3134 value = value + 29;
3135 temp = kstrtou32(value, 10, &val);
3136 if (temp != 0 || val < CFG_PASSIVE_MIN_CHANNEL_TIME_CONC_MIN ||
3137 val > CFG_PASSIVE_MIN_CHANNEL_TIME_CONC_MAX )
3138 {
3139 hddLog(LOGE, FL("Argument passed for CONCSETDWELLTIME PASSIVE MIN is incorrect"));
3140 ret = -EFAULT;
3141 return ret;
3142 }
3143 pCfg->nPassiveMinChnTimeConc = val;
3144 smeConfig.csrConfig.nPassiveMinChnTimeConc = val;
3145 sme_UpdateConfig(hHal, &smeConfig);
3146 }
3147 else
3148 {
3149 ret = -EINVAL;
3150 }
3151
3152 return ret;
3153}
3154
3155#endif
3156
3157/**
3158 * hdd_btc_set_dwell_time() - Set BTC dwell time parameters
3159 * @pAdapter: Adapter upon which the command was received
3160 * @command: ASCII text command that is received
3161 *
3162 * Driver commands:
3163 * wpa_cli DRIVER BTCSETDWELLTIME ESCO MAX <value>
3164 * wpa_cli DRIVER BTCSETDWELLTIME ESCO MIN <value>
3165 * wpa_cli DRIVER BTCSETDWELLTIME SCO MAX <value>
3166 * wpa_cli DRIVER BTCSETDWELLTIME SCO MIN <value>
3167 *
3168 * Return: 0 for success non-zero for failure
3169 */
3170
3171static int hdd_btc_set_dwell_time(hdd_adapter_t *pAdapter, tANI_U8 *command)
3172{
3173 tHalHandle hHal;
3174 hdd_config_t *pCfg;
3175 tANI_U8 *value = command;
3176 int val = 0, ret = 0, temp = 0;
3177 tSmeConfigParams smeConfig;
3178
3179 if (!pAdapter || !command || !(pCfg = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini)
3180 || !(hHal = (WLAN_HDD_GET_HAL_CTX(pAdapter))))
3181 {
3182 hddLog(LOGE, FL("Argument passed for BTCSETDWELLTIME is incorrect"));
3183 ret = -EINVAL;
3184 return ret;
3185 }
3186
3187 vos_mem_zero(&smeConfig, sizeof(smeConfig));
3188 sme_GetConfigParam(hHal, &smeConfig);
3189
3190 if (strncmp(command, "BTCSETDWELLTIME ESCO MAX", 24) == 0)
3191 {
3192 if (hdd_drv_cmd_validate(command, 24)) {
3193 hddLog(LOGE, FL("Invalid driver command"));
3194 return -EINVAL;
3195 }
3196
3197 value = value + 25;
3198 temp = kstrtou32(value, 10, &val);
3199 if (temp != 0 || val < CFG_ACTIVE_MAX_CHANNEL_TIME_BTC_MIN ||
3200 val > CFG_ACTIVE_MAX_CHANNEL_TIME_BTC_MAX)
3201 {
3202 hddLog(LOGE, FL("Argument passed for BTCSETDWELLTIME ESCO MAX is incorrect"));
3203 ret = -EFAULT;
3204 return ret;
3205 }
3206 pCfg->max_chntime_btc_esco = val;
3207 smeConfig.csrConfig.max_chntime_btc_esco = val;
3208 sme_UpdateConfig(hHal, &smeConfig);
3209 }
3210 else if (strncmp(command, "BTCSETDWELLTIME ESCO MIN", 24) == 0)
3211 {
3212 if (hdd_drv_cmd_validate(command, 24)) {
3213 hddLog(LOGE, FL("Invalid driver command"));
3214 return -EINVAL;
3215 }
3216
3217 value = value + 25;
3218 temp = kstrtou32(value, 10, &val);
3219 if (temp !=0 || val < CFG_ACTIVE_MIN_CHANNEL_TIME_BTC_MIN ||
3220 val > CFG_ACTIVE_MIN_CHANNEL_TIME_BTC_MAX)
3221 {
3222 hddLog(LOGE, FL("Argument passsed for BTCSETDWELLTIME ESCO MIN is incorrect"));
3223 ret = -EFAULT;
3224 return ret;
3225 }
3226 pCfg->min_chntime_btc_esco = val;
3227 smeConfig.csrConfig.min_chntime_btc_esco = val;
3228 sme_UpdateConfig(hHal, &smeConfig);
3229 }
3230 else if (strncmp(command, "BTCSETDWELLTIME SCO MAX", 23) == 0)
3231 {
3232 if (hdd_drv_cmd_validate(command, 23)) {
3233 hddLog(LOGE, FL("Invalid driver command"));
3234 return -EINVAL;
3235 }
3236
3237 value = value + 24;
3238 temp = kstrtou32(value, 10, &val);
3239 if (temp != 0 || val < CFG_ACTIVE_MAX_CHANNEL_TIME_BTC_SCO_MIN ||
3240 val > CFG_ACTIVE_MAX_CHANNEL_TIME_BTC_SCO_MAX)
3241 {
3242 hddLog(LOGE, FL("Argument passed for BTCSETDWELLTIME SCO MAX is incorrect"));
3243 ret = -EFAULT;
3244 return ret;
3245 }
3246 pCfg->max_chntime_btc_sco = val;
3247 smeConfig.csrConfig.max_chntime_btc_sco = val;
3248 sme_UpdateConfig(hHal, &smeConfig);
3249 }
3250 else if (strncmp(command, "BTCSETDWELLTIME SCO MIN", 23) == 0)
3251 {
3252 if (hdd_drv_cmd_validate(command, 23)) {
3253 hddLog(LOGE, FL("Invalid driver command"));
3254 return -EINVAL;
3255 }
3256
3257 value = value + 24;
3258 temp = kstrtou32(value, 10, &val);
3259 if (temp != 0 || val < CFG_ACTIVE_MIN_CHANNEL_TIME_BTC_SCO_MIN ||
3260 val > CFG_ACTIVE_MIN_CHANNEL_TIME_BTC_SCO_MAX)
3261 {
3262 hddLog(LOGE, FL("Argument passed for BTCSETDWELLTIME SCO MIN is incorrect"));
3263 ret = -EFAULT;
3264 return ret;
3265 }
3266 pCfg->min_chntime_btc_sco = val;
3267 smeConfig.csrConfig.min_chntime_btc_sco = val;
3268 sme_UpdateConfig(hHal, &smeConfig);
3269 }
3270 else
3271 {
3272 ret = -EINVAL;
3273 }
3274
3275 return ret;
3276}
3277
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05303278static int hdd_set_dwell_time(hdd_adapter_t *pAdapter, tANI_U8 *command)
3279{
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05303280 tHalHandle hHal;
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05303281 hdd_config_t *pCfg;
3282 tANI_U8 *value = command;
3283 int val = 0, ret = 0, temp = 0;
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05303284 tSmeConfigParams smeConfig;
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05303285
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05303286 if (!pAdapter || !command || !(pCfg = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini)
3287 || !(hHal = (WLAN_HDD_GET_HAL_CTX(pAdapter))))
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05303288 {
3289 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3290 "%s: argument passed for SETDWELLTIME is incorrect", __func__);
3291 ret = -EINVAL;
3292 return ret;
3293 }
3294
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05303295 vos_mem_zero(&smeConfig, sizeof(smeConfig));
3296 sme_GetConfigParam(hHal, &smeConfig);
3297
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05303298 if (strncmp(command, "SETDWELLTIME ACTIVE MAX", 23) == 0 )
3299 {
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05303300 if (hdd_drv_cmd_validate(command, 23))
3301 return -EINVAL;
3302
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05303303 value = value + 24;
3304 temp = kstrtou32(value, 10, &val);
3305 if (temp != 0 || val < CFG_ACTIVE_MAX_CHANNEL_TIME_MIN ||
3306 val > CFG_ACTIVE_MAX_CHANNEL_TIME_MAX )
3307 {
3308 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3309 "%s: argument passed for SETDWELLTIME ACTIVE MAX is incorrect", __func__);
3310 ret = -EFAULT;
3311 return ret;
3312 }
3313 pCfg->nActiveMaxChnTime = val;
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05303314 smeConfig.csrConfig.nActiveMaxChnTime = val;
3315 sme_UpdateConfig(hHal, &smeConfig);
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05303316 }
3317 else if (strncmp(command, "SETDWELLTIME ACTIVE MIN", 23) == 0)
3318 {
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05303319 if (hdd_drv_cmd_validate(command, 23))
3320 return -EINVAL;
3321
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05303322 value = value + 24;
3323 temp = kstrtou32(value, 10, &val);
3324 if (temp !=0 || val < CFG_ACTIVE_MIN_CHANNEL_TIME_MIN ||
3325 val > CFG_ACTIVE_MIN_CHANNEL_TIME_MAX )
3326 {
3327 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3328 "%s: argument passsed for SETDWELLTIME ACTIVE MIN is incorrect", __func__);
3329 ret = -EFAULT;
3330 return ret;
3331 }
3332 pCfg->nActiveMinChnTime = val;
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05303333 smeConfig.csrConfig.nActiveMinChnTime = val;
3334 sme_UpdateConfig(hHal, &smeConfig);
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05303335 }
3336 else if (strncmp(command, "SETDWELLTIME PASSIVE MAX", 24) == 0)
3337 {
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05303338 if (hdd_drv_cmd_validate(command, 24))
3339 return -EINVAL;
3340
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05303341 value = value + 25;
3342 temp = kstrtou32(value, 10, &val);
3343 if (temp != 0 || val < CFG_PASSIVE_MAX_CHANNEL_TIME_MIN ||
3344 val > CFG_PASSIVE_MAX_CHANNEL_TIME_MAX )
3345 {
3346 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3347 "%s: argument passed for SETDWELLTIME PASSIVE MAX is incorrect", __func__);
3348 ret = -EFAULT;
3349 return ret;
3350 }
3351 pCfg->nPassiveMaxChnTime = val;
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05303352 smeConfig.csrConfig.nPassiveMaxChnTime = val;
3353 sme_UpdateConfig(hHal, &smeConfig);
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05303354 }
3355 else if (strncmp(command, "SETDWELLTIME PASSIVE MIN", 24) == 0)
3356 {
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05303357 if (hdd_drv_cmd_validate(command, 24))
3358 return -EINVAL;
3359
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05303360 value = value + 25;
3361 temp = kstrtou32(value, 10, &val);
3362 if (temp != 0 || val < CFG_PASSIVE_MIN_CHANNEL_TIME_MIN ||
3363 val > CFG_PASSIVE_MIN_CHANNEL_TIME_MAX )
3364 {
3365 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3366 "%s: argument passed for SETDWELLTIME PASSIVE MIN is incorrect", __func__);
3367 ret = -EFAULT;
3368 return ret;
3369 }
3370 pCfg->nPassiveMinChnTime = val;
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05303371 smeConfig.csrConfig.nPassiveMinChnTime = val;
3372 sme_UpdateConfig(hHal, &smeConfig);
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05303373 }
Rajesh Babu Prathipati0fd227e2014-07-05 12:50:00 +05303374 else if (strncmp(command, "SETDWELLTIME", 12) == 0)
3375 {
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05303376 if (hdd_drv_cmd_validate(command, 12))
3377 return -EINVAL;
3378
Rajesh Babu Prathipati0fd227e2014-07-05 12:50:00 +05303379 value = value + 13;
3380 temp = kstrtou32(value, 10, &val);
3381 if (temp != 0 || val < CFG_ACTIVE_MAX_CHANNEL_TIME_MIN ||
3382 val > CFG_ACTIVE_MAX_CHANNEL_TIME_MAX )
3383 {
3384 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3385 "%s: argument passed for SETDWELLTIME is incorrect", __func__);
3386 ret = -EFAULT;
3387 return ret;
3388 }
3389 pCfg->nActiveMaxChnTime = val;
3390 smeConfig.csrConfig.nActiveMaxChnTime = val;
3391 sme_UpdateConfig(hHal, &smeConfig);
3392 }
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05303393 else
3394 {
3395 ret = -EINVAL;
3396 }
3397
3398 return ret;
3399}
Agarwal Ashish8bd53ae2015-06-12 18:03:45 +05303400static int hdd_cmd_setFccChannel(hdd_context_t *pHddCtx, tANI_U8 *cmd,
3401 tANI_U8 cmd_len)
3402{
3403 tANI_U8 *value;
3404 tANI_U8 fcc_constraint;
3405
3406 eHalStatus status;
3407 int ret = 0;
3408 value = cmd + cmd_len + 1;
3409
3410 ret = kstrtou8(value, 10, &fcc_constraint);
3411 if ((ret < 0) || (fcc_constraint > 1)) {
3412 /*
3413 * If the input value is greater than max value of datatype,
3414 * then also it is a failure
3415 */
3416 hddLog(VOS_TRACE_LEVEL_ERROR,
3417 "%s: value out of range", __func__);
3418 return -EINVAL;
3419 }
3420
Agrawal Ashish842eea82016-02-04 17:56:16 +05303421 status = sme_handleSetFccChannel(pHddCtx->hHal, fcc_constraint,
3422 pHddCtx->scan_info.mScanPending);
Agarwal Ashish8bd53ae2015-06-12 18:03:45 +05303423 if (status != eHAL_STATUS_SUCCESS)
3424 ret = -EPERM;
3425
3426 return ret;
3427}
3428
Mahesh A Saptasagarbeca12c2015-09-07 16:21:06 +05303429/**---------------------------------------------------------------------------
Agarwal Ashish8bd53ae2015-06-12 18:03:45 +05303430
Mahesh A Saptasagarbeca12c2015-09-07 16:21:06 +05303431 \brief hdd_enable_disable_ca_event() - When Host sends IOCTL (enabled),
3432 FW will send *ONE* CA ind to Host(even though it is duplicate).
3433 When Host send IOCTL (disable), FW doesn't perform any action.
3434 Whenever any change in CA *and* WLAN is in SAP/P2P-GO mode, FW
3435 sends CA ind to host. (regard less of IOCTL status)
3436 \param - pHddCtx - HDD context
3437 \param - command - command received from framework
3438 \param - cmd_len - len of the command
3439
3440 \return - 0 on success, appropriate error values on failure.
3441
3442 --------------------------------------------------------------------------*/
3443int hdd_enable_disable_ca_event(hdd_context_t *pHddCtx, tANI_U8* command, tANI_U8 cmd_len)
3444{
3445 tANI_U8 set_value;
3446 int ret = 0;
3447 eHalStatus status;
3448
3449 ret = wlan_hdd_validate_context(pHddCtx);
3450 if (0 != ret)
3451 {
3452 ret = -EINVAL;
3453 goto exit;
3454 }
3455
3456 if (pHddCtx->cfg_ini->gOptimizeCAevent == 0)
3457 {
3458 hddLog(VOS_TRACE_LEVEL_ERROR, "Enable gOptimizeCAevent"
3459 " ini param to control channel avooidance indication");
3460 ret = 0;
3461 goto exit;
3462 }
3463
3464 set_value = command[cmd_len + 1] - '0';
3465 status = sme_enableDisableChanAvoidIndEvent(pHddCtx->hHal, set_value);
3466 if (status != eHAL_STATUS_SUCCESS)
3467 {
3468 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Failed to send"
3469 " enableDisableChanAoidance command to SME\n", __func__);
3470 ret = -EINVAL;
3471 }
3472
3473exit:
3474 return ret;
3475}
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05303476
Selvaraj, Sridhar3714c4d2016-06-22 15:19:12 +05303477/**
3478 * wlan_hdd_fastreassoc_handoff_request() - Post Handoff request to SME
3479 * @pHddCtx: Pointer to the HDD context
3480 * @channel: channel to reassociate
3481 * @targetApBssid: Target AP/BSSID to reassociate
3482 *
3483 * Return: None
3484 */
3485#if defined(WLAN_FEATURE_ROAM_SCAN_OFFLOAD) && !defined(QCA_WIFI_ISOC)
3486static void wlan_hdd_fastreassoc_handoff_request(hdd_context_t *pHddCtx,
3487 uint8_t channel, tSirMacAddr targetApBssid)
3488{
3489 tCsrHandoffRequest handoffInfo;
3490 handoffInfo.channel = channel;
3491 handoffInfo.src = FASTREASSOC;
3492 vos_mem_copy(handoffInfo.bssid, targetApBssid, sizeof(tSirMacAddr));
3493 sme_HandoffRequest(pHddCtx->hHal, &handoffInfo);
3494}
3495#else
3496static void wlan_hdd_fastreassoc_handoff_request(hdd_context_t *pHddCtx,
3497 uint8_t channel, tSirMacAddr targetApBssid)
3498{
3499}
3500#endif
3501
3502/**
3503 * csr_fastroam_neighbor_ap_event() - Function to trigger scan/roam
3504 * @pAdapter: Pointer to HDD adapter
3505 * @channel: Channel to scan/roam
3506 * @targetApBssid: BSSID to roam
3507 *
3508 * Return: None
3509 */
3510#ifdef QCA_WIFI_ISOC
3511static void csr_fastroam_neighbor_ap_event(hdd_adapter_t *pAdapter,
3512 uint8_t channel, tSirMacAddr targetApBssid)
3513{
3514 smeIssueFastRoamNeighborAPEvent(WLAN_HDD_GET_HAL_CTX(pAdapter),
3515 &targetApBssid[0], eSME_ROAM_TRIGGER_SCAN, channel);
3516}
3517#else
3518static void csr_fastroam_neighbor_ap_event(hdd_adapter_t *pAdapter,
3519 uint8_t channel, tSirMacAddr targetApBssid)
3520{
3521}
3522#endif
3523
3524/**
3525 * wlan_hdd_handle_fastreassoc() - Handle fastreassoc command
3526 * @pAdapter: pointer to hdd adapter
3527 * @command: pointer to the command received
3528 *
3529 * Return: VOS_STATUS enum
3530 */
3531static VOS_STATUS wlan_hdd_handle_fastreassoc(hdd_adapter_t *pAdapter,
3532 uint8_t *command)
3533{
3534 tANI_U8 *value = command;
3535 tANI_U8 channel = 0;
3536 tSirMacAddr targetApBssid;
Selvaraj, Sridhar3714c4d2016-06-22 15:19:12 +05303537 hdd_station_ctx_t *pHddStaCtx = NULL;
3538 hdd_context_t *pHddCtx = NULL;
Selvaraj, Sridhar5aff1ed2016-06-18 01:26:23 +05303539 int ret;
Selvaraj, Sridhar349b8fe2017-01-18 13:11:25 +05303540 tCsrRoamModifyProfileFields mod_profile_fields;
3541 uint32_t roam_id = 0;
Selvaraj, Sridhar3714c4d2016-06-22 15:19:12 +05303542 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
3543 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
3544
3545 /* if not associated, no need to proceed with reassoc */
3546 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState) {
3547 hddLog(LOG1, FL("Not associated!"));
3548 return eHAL_STATUS_FAILURE;
3549 }
3550
Selvaraj, Sridhar5aff1ed2016-06-18 01:26:23 +05303551 ret = hdd_parse_reassoc_command_v1_data(value, targetApBssid, &channel);
3552 if (ret) {
Selvaraj, Sridhar3714c4d2016-06-22 15:19:12 +05303553 hddLog(LOGE, FL("Failed to parse reassoc command data"));
3554 return eHAL_STATUS_FAILURE;
3555 }
3556
3557 /* if the target bssid is same as currently associated AP,
3558 then no need to proceed with reassoc */
3559 if (vos_mem_compare(targetApBssid,
3560 pHddStaCtx->conn_info.bssId,
3561 sizeof(tSirMacAddr))) {
Selvaraj, Sridhar349b8fe2017-01-18 13:11:25 +05303562 sme_GetModifyProfileFields(pHddCtx->hHal, pAdapter->sessionId,
3563 &mod_profile_fields);
3564 sme_RoamReassoc(pHddCtx->hHal, pAdapter->sessionId, NULL,
3565 mod_profile_fields, &roam_id, 1);
Selvaraj, Sridhar3714c4d2016-06-22 15:19:12 +05303566 hddLog(LOG1, FL("Reassoc BSSID is same as currently associated AP bssid"));
Selvaraj, Sridhar349b8fe2017-01-18 13:11:25 +05303567 return eHAL_STATUS_SUCCESS;
Selvaraj, Sridhar3714c4d2016-06-22 15:19:12 +05303568 }
3569
3570 /* Check channel number is a valid channel number */
3571 if (VOS_STATUS_SUCCESS !=
3572 wlan_hdd_validate_operation_channel(pAdapter, channel)) {
3573 hddLog(LOGE, FL("Invalid Channel [%d]"), channel);
3574 return eHAL_STATUS_FAILURE;
3575 }
3576
3577 /* Proceed with reassoc */
3578 wlan_hdd_fastreassoc_handoff_request(pHddCtx, channel, targetApBssid);
3579
3580 /* Proceed with scan/roam */
3581 csr_fastroam_neighbor_ap_event(pAdapter, channel, targetApBssid);
3582
3583 return eHAL_STATUS_SUCCESS;
3584}
3585
3586/**
3587 * hdd_assign_reassoc_handoff - Set handoff source as REASSOC
3588 * @handoffInfo: Pointer to the csr Handoff Request.
3589 *
3590 * Return: None
3591 */
3592#ifndef QCA_WIFI_ISOC
3593static inline void hdd_assign_reassoc_handoff(tCsrHandoffRequest *handoffInfo)
3594{
3595 handoffInfo->src = REASSOC;
3596}
3597#else
3598static inline void hdd_assign_reassoc_handoff(tCsrHandoffRequest *handoffInfo)
3599{
3600}
3601#endif
3602
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +05303603/**
3604 * wlan_hdd_free_cache_channels() - Free the cache channels list
3605 * @hdd_ctx: Pointer to HDD context
3606 *
3607 * Return: None
3608 */
3609
3610static void wlan_hdd_free_cache_channels(hdd_context_t *hdd_ctx)
3611{
Ashish Kumar Dhanotiya19803832018-05-24 19:05:48 +05303612 if(!hdd_ctx || !hdd_ctx->original_channels)
3613 return;
3614
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +05303615 mutex_lock(&hdd_ctx->cache_channel_lock);
Ashish Kumar Dhanotiya95e5bc22018-04-19 17:06:33 +05303616 hdd_ctx->original_channels->num_channels = 0;
3617 vos_mem_free(hdd_ctx->original_channels->channel_info);
3618 hdd_ctx->original_channels->channel_info = NULL;
3619 vos_mem_free(hdd_ctx->original_channels);
3620 hdd_ctx->original_channels = NULL;
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +05303621 mutex_unlock(&hdd_ctx->cache_channel_lock);
3622}
3623
3624/**
3625 * hdd_alloc_chan_cache() - Allocate the memory to cache the channel
3626 * info for the channels received in command SET_DISABLE_CHANNEL_LIST
3627 * @hdd_ctx: Pointer to HDD context
3628 * @num_chan: Number of channels for which memory needs to
3629 * be allocated
3630 *
3631 * Return: 0 on success and error code on failure
3632 */
3633
3634int hdd_alloc_chan_cache(hdd_context_t *hdd_ctx, int num_chan)
3635{
Ashish Kumar Dhanotiya95e5bc22018-04-19 17:06:33 +05303636 hdd_ctx->original_channels =
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +05303637 vos_mem_malloc(sizeof(struct hdd_cache_channels));
Ashish Kumar Dhanotiya95e5bc22018-04-19 17:06:33 +05303638 if (!hdd_ctx->original_channels) {
3639 hddLog(VOS_TRACE_LEVEL_ERROR,
3640 "In %s, VOS_MALLOC_ERR", __func__);
3641 return -EINVAL;
3642 }
3643 hdd_ctx->original_channels->num_channels = num_chan;
3644 hdd_ctx->original_channels->channel_info =
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +05303645 vos_mem_malloc(num_chan *
3646 sizeof(struct hdd_cache_channel_info));
Ashish Kumar Dhanotiya95e5bc22018-04-19 17:06:33 +05303647 if (!hdd_ctx->original_channels->channel_info) {
3648 hddLog(VOS_TRACE_LEVEL_ERROR,
3649 "In %s, VOS_MALLOC_ERR", __func__);
3650 hdd_ctx->original_channels->num_channels = 0;
3651 vos_mem_free(hdd_ctx->original_channels);
3652 hdd_ctx->original_channels = NULL;
3653 return -ENOMEM;
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +05303654 }
3655 return 0;
3656
3657}
3658
3659
3660int hdd_parse_disable_chan_cmd(hdd_adapter_t *adapter, tANI_U8 *ptr)
3661{
3662 v_PVOID_t pvosGCtx = vos_get_global_context(VOS_MODULE_ID_HDD, NULL);
3663 hdd_context_t *hdd_ctx = vos_get_context(VOS_MODULE_ID_HDD, pvosGCtx);
3664 tANI_U8 *param;
Ashish Kumar Dhanotiya95e5bc22018-04-19 17:06:33 +05303665 int j, tempInt, ret = 0, i, num_channels;
3666 int parsed_channels[MAX_CHANNEL];
3667 bool is_command_repeated = false;
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +05303668
3669 if (NULL == pvosGCtx) {
3670 hddLog(VOS_TRACE_LEVEL_FATAL,
3671 "VOS Global Context is NULL");
3672 return -EINVAL;
3673 }
3674
3675 if (NULL == hdd_ctx) {
3676 hddLog(VOS_TRACE_LEVEL_FATAL, "HDD Context is NULL");
3677 return -EINVAL;
3678 }
3679
3680 param = strchr(ptr, ' ');
3681 /*no argument after the command*/
3682 if (NULL == param)
3683 return -EINVAL;
3684
3685 /*no space after the command*/
3686 else if (SPACE_ASCII_VALUE != *param)
3687 return -EINVAL;
3688
3689 param++;
3690
3691 /*removing empty spaces*/
3692 while ((SPACE_ASCII_VALUE == *param) && ('\0' != *param))
3693 param++;
3694
3695 /*no argument followed by spaces*/
3696 if ('\0' == *param)
3697 return -EINVAL;
3698
3699 /*getting the first argument ie the number of channels*/
3700 if (sscanf(param, "%d ", &tempInt) != 1) {
3701 hddLog(VOS_TRACE_LEVEL_ERROR,
3702 "%s: Cannot get number of channels from input",
3703 __func__);
3704 return -EINVAL;
3705 }
3706
3707 if (tempInt < 0 || tempInt > MAX_CHANNEL) {
3708 hddLog(VOS_TRACE_LEVEL_ERROR,
3709 "%s: Invalid Number of channel received", __func__);
3710 return -EINVAL;
3711 }
3712
3713 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
3714 "%s: Number of channel to disable are: %d",
3715 __func__, tempInt);
3716
3717 if (!tempInt) {
3718 if (!wlan_hdd_restore_channels(hdd_ctx)) {
3719 /*
3720 * Free the cache channels only when the command is
3721 * received with num channels as 0
3722 */
3723 wlan_hdd_free_cache_channels(hdd_ctx);
3724 }
3725 return 0;
3726 }
3727
3728 mutex_lock(&hdd_ctx->cache_channel_lock);
Ashish Kumar Dhanotiya95e5bc22018-04-19 17:06:33 +05303729 if (!hdd_ctx->original_channels) {
3730 if (hdd_alloc_chan_cache(hdd_ctx, tempInt)) {
3731 ret = -ENOMEM;
3732 goto mem_alloc_failed;
3733 }
3734 } else if (hdd_ctx->original_channels->num_channels != tempInt) {
3735 hddLog(VOS_TRACE_LEVEL_ERROR,
3736 "%s, Invalid No of channel provided in the list",
3737 __func__);
3738 ret = -EINVAL;
3739 is_command_repeated = true;
3740 goto parse_failed;
3741 } else {
3742 is_command_repeated = true;
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +05303743 }
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +05303744
Ashish Kumar Dhanotiya95e5bc22018-04-19 17:06:33 +05303745 num_channels = tempInt;
3746
3747 for (j = 0; j < num_channels; j++) {
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +05303748 /*
3749 * param pointing to the beginning of first space
3750 * after number of channels
3751 */
3752 param = strpbrk(param, " ");
3753 /*no channel list after the number of channels argument*/
3754 if (NULL == param) {
3755 hddLog(VOS_TRACE_LEVEL_ERROR,
3756 "%s, Invalid No of channel provided in the list",
3757 __func__);
3758 ret = -EINVAL;
Ashish Kumar Dhanotiya95e5bc22018-04-19 17:06:33 +05303759 goto parse_failed;
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +05303760 }
3761
3762 param++;
3763
3764 /*removing empty space*/
3765 while ((SPACE_ASCII_VALUE == *param) && ('\0' != *param))
3766 param++;
3767
3768 if ('\0' == *param) {
3769 hddLog(VOS_TRACE_LEVEL_ERROR,
3770 "%s, No channel is provided in the list",
3771 __func__);
3772 ret = -EINVAL;
Ashish Kumar Dhanotiya95e5bc22018-04-19 17:06:33 +05303773 goto parse_failed;
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +05303774
3775 }
3776
3777 if (sscanf(param, "%d ", &tempInt) != 1) {
3778 hddLog(VOS_TRACE_LEVEL_ERROR,
3779 "%s: Cannot read channel number",
3780 __func__);
3781 ret = -EINVAL;
Ashish Kumar Dhanotiya95e5bc22018-04-19 17:06:33 +05303782 goto parse_failed;
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +05303783
3784 }
3785
3786 if (!IS_CHANNEL_VALID(tempInt)) {
3787 hddLog(VOS_TRACE_LEVEL_ERROR,
3788 "%s: Invalid channel number received",
3789 __func__);
3790 ret = -EINVAL;
Ashish Kumar Dhanotiya95e5bc22018-04-19 17:06:33 +05303791 goto parse_failed;
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +05303792
3793 }
3794
3795 hddLog(VOS_TRACE_LEVEL_INFO, "%s: channel[%d] = %d", __func__,
3796 j, tempInt);
Ashish Kumar Dhanotiya95e5bc22018-04-19 17:06:33 +05303797
3798 parsed_channels[j] = tempInt;
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +05303799 }
3800
3801 /*extra arguments check*/
3802 param = strchr(param, ' ');
3803 if (NULL != param) {
3804 while ((SPACE_ASCII_VALUE == *param) && ('\0' != *param))
3805 param++;
3806
3807 if ('\0' != *param) {
3808 hddLog(VOS_TRACE_LEVEL_ERROR,
3809 "%s: Invalid argument received", __func__);
3810 ret = -EINVAL;
Ashish Kumar Dhanotiya95e5bc22018-04-19 17:06:33 +05303811 goto parse_failed;
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +05303812 }
3813 }
3814
Ashish Kumar Dhanotiya95e5bc22018-04-19 17:06:33 +05303815 /*
3816 * If command is received first time, cache the channels to
3817 * be disabled else compare the channels received in the
3818 * command with the cached channels, if channel list matches
3819 * return success otherewise return failure.
3820 */
3821 if (!is_command_repeated)
3822 for (j = 0; j < num_channels; j++)
3823 hdd_ctx->original_channels->
3824 channel_info[j].channel_num =
3825 parsed_channels[j];
3826 else {
3827 for (i = 0; i < num_channels; i++) {
3828 for (j = 0; j < num_channels; j++)
3829 if (hdd_ctx->original_channels->
3830 channel_info[i].channel_num ==
3831 parsed_channels[j])
3832 break;
3833 if (j == num_channels) {
3834 ret = -EINVAL;
3835 goto parse_failed;
3836 }
3837 }
3838 ret = 0;
3839 }
3840
3841mem_alloc_failed:
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +05303842 mutex_unlock(&hdd_ctx->cache_channel_lock);
Ashish Kumar Dhanotiya1cf97dd2019-03-11 16:59:25 +05303843 /* Disable the channels received in command SET_DISABLE_CHANNEL_LIST*/
3844 if (!is_command_repeated) {
3845 wlan_hdd_disable_channels(hdd_ctx);
3846 hdd_check_and_disconnect_sta_on_invalid_channel(hdd_ctx);
3847 }
3848
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +05303849 EXIT();
3850
3851 return ret;
Ashish Kumar Dhanotiya95e5bc22018-04-19 17:06:33 +05303852
3853parse_failed:
3854 mutex_unlock(&hdd_ctx->cache_channel_lock);
3855 if (!is_command_repeated)
3856 wlan_hdd_free_cache_channels(hdd_ctx);
3857 EXIT();
3858 return ret;
3859
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +05303860}
3861
Hanumanth Reddy Pothula8ae38bb2018-03-07 18:59:30 +05303862int hdd_get_disable_ch_list(hdd_context_t *hdd_ctx, tANI_U8 *buf,
Ashish Kumar Dhanotiya95e5bc22018-04-19 17:06:33 +05303863 uint32_t buf_len)
Hanumanth Reddy Pothula8ae38bb2018-03-07 18:59:30 +05303864{
3865 struct hdd_cache_channel_info *ch_list;
3866 unsigned char i, num_ch;
3867 int len = 0;
3868
3869 mutex_lock(&hdd_ctx->cache_channel_lock);
Ashish Kumar Dhanotiya95e5bc22018-04-19 17:06:33 +05303870 if (hdd_ctx->original_channels &&
3871 hdd_ctx->original_channels->num_channels &&
3872 hdd_ctx->original_channels->channel_info) {
3873 num_ch = hdd_ctx->original_channels->num_channels;
Hanumanth Reddy Pothula8ae38bb2018-03-07 18:59:30 +05303874
3875 len = scnprintf(buf, buf_len, "%s %hhu",
3876 "GET_DISABLE_CHANNEL_LIST", num_ch);
3877
Ashish Kumar Dhanotiya95e5bc22018-04-19 17:06:33 +05303878 ch_list = hdd_ctx->original_channels->channel_info;
Hanumanth Reddy Pothula8ae38bb2018-03-07 18:59:30 +05303879
Ashish Kumar Dhanotiya95e5bc22018-04-19 17:06:33 +05303880 for (i = 0; (i < num_ch) && (len < buf_len-1); i++) {
Hanumanth Reddy Pothula8ae38bb2018-03-07 18:59:30 +05303881 len += scnprintf(buf + len, buf_len - len,
3882 " %d", ch_list[i].channel_num);
3883 }
3884 }
3885 mutex_unlock(&hdd_ctx->cache_channel_lock);
3886
3887 return len;
3888}
3889
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07003890static int hdd_driver_command(hdd_adapter_t *pAdapter,
3891 hdd_priv_data_t *ppriv_data)
Jeff Johnson295189b2012-06-20 16:38:30 -07003892{
Jeff Johnson295189b2012-06-20 16:38:30 -07003893 hdd_priv_data_t priv_data;
3894 tANI_U8 *command = NULL;
Kaushik, Sushant96122442014-10-21 16:40:18 +05303895 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
3896 hdd_scaninfo_t *pScanInfo = NULL;
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07003897 int ret = 0;
Kaushik, Sushant96122442014-10-21 16:40:18 +05303898 int status;
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05303899#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
3900 struct cfg80211_mgmt_tx_params params;
3901#endif
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303902
3903 ENTER();
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07003904 /*
3905 * Note that valid pointers are provided by caller
3906 */
Jeff Johnson295189b2012-06-20 16:38:30 -07003907
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07003908 /* copy to local struct to avoid numerous changes to legacy code */
3909 priv_data = *ppriv_data;
Jeff Johnson295189b2012-06-20 16:38:30 -07003910
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07003911 if (priv_data.total_len <= 0 ||
3912 priv_data.total_len > WLAN_PRIV_DATA_MAX_LEN)
Sameer Thalappil8ef3a0e2013-04-05 14:36:04 -07003913 {
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07003914 hddLog(VOS_TRACE_LEVEL_WARN,
3915 "%s:invalid priv_data.total_len(%d)!!!", __func__,
3916 priv_data.total_len);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07003917 ret = -EINVAL;
3918 goto exit;
3919 }
Kaushik, Sushant96122442014-10-21 16:40:18 +05303920 status = wlan_hdd_validate_context(pHddCtx);
3921 if (0 != status)
3922 {
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303923 ret = -EINVAL;
3924 goto exit;
Kaushik, Sushant96122442014-10-21 16:40:18 +05303925 }
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07003926 /* Allocate +1 for '\0' */
3927 command = kmalloc(priv_data.total_len + 1, GFP_KERNEL);
Jeff Johnson295189b2012-06-20 16:38:30 -07003928 if (!command)
3929 {
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07003930 hddLog(VOS_TRACE_LEVEL_ERROR,
3931 "%s: failed to allocate memory", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07003932 ret = -ENOMEM;
3933 goto exit;
3934 }
3935
3936 if (copy_from_user(command, priv_data.buf, priv_data.total_len))
3937 {
3938 ret = -EFAULT;
3939 goto exit;
3940 }
3941
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07003942 /* Make sure the command is NUL-terminated */
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07003943 command[priv_data.total_len] = '\0';
3944
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07003945 /* at one time the following block of code was conditional. braces
3946 * have been retained to avoid re-indenting the legacy code
3947 */
Jeff Johnson295189b2012-06-20 16:38:30 -07003948 {
3949 hdd_context_t *pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
3950
3951 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudif9bdd4e2012-10-30 18:05:03 -07003952 "%s: Received %s cmd from Wi-Fi GUI***", __func__, command);
Jeff Johnson295189b2012-06-20 16:38:30 -07003953
3954 if (strncmp(command, "P2P_DEV_ADDR", 12) == 0 )
3955 {
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05303956 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
3957 TRACE_CODE_HDD_P2P_DEV_ADDR_IOCTL,
3958 pAdapter->sessionId, (unsigned)
3959 (*(pHddCtx->p2pDeviceAddress.bytes+2)<<24 |
3960 *(pHddCtx->p2pDeviceAddress.bytes+3)<<16 |
3961 *(pHddCtx->p2pDeviceAddress.bytes+4)<<8 |
3962 *(pHddCtx->p2pDeviceAddress.bytes+5))));
Jeff Johnson295189b2012-06-20 16:38:30 -07003963 if (copy_to_user(priv_data.buf, pHddCtx->p2pDeviceAddress.bytes,
3964 sizeof(tSirMacAddr)))
3965 {
3966 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08003967 "%s: failed to copy data to user buffer", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07003968 ret = -EFAULT;
3969 }
3970 }
Amar Singhal0974e402013-02-12 14:27:46 -08003971 else if(strncmp(command, "SETBAND", 7) == 0)
Jeff Johnson295189b2012-06-20 16:38:30 -07003972 {
Amar Singhal0974e402013-02-12 14:27:46 -08003973 tANI_U8 *ptr = command ;
Srinivas Girigowdade697412013-02-14 16:31:48 -08003974
guanglunyang(177503)cd6d7cc2020-04-30 10:02:56 +08003975 // FEATURE: Select frequency band. BEGIN
3976 printk(KERN_DEBUG"Receive SETBAND command from framework.\n");
3977 // FEATURE: Select frequency band. END
3978
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05303979 ret = hdd_drv_cmd_validate(command, 7);
3980 if (ret)
3981 goto exit;
3982
Jeff Johnson295189b2012-06-20 16:38:30 -07003983 /* Change band request received */
Srinivas Girigowdade697412013-02-14 16:31:48 -08003984
3985 /* First 8 bytes will have "SETBAND " and
Jeff Johnson295189b2012-06-20 16:38:30 -07003986 * 9 byte will have band setting value */
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07003987 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Amar Singhal0974e402013-02-12 14:27:46 -08003988 "%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 +05303989 if(VOS_FTM_MODE != hdd_get_conparam())
3990 {
3991 /* Change band request received */
3992 ret = hdd_setBand_helper(pAdapter->dev, ptr);
3993 if(ret < 0)
3994 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
3995 "%s: failed to set band ret=%d", __func__, ret);
3996 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08003997 }
Kiet Lamf040f472013-11-20 21:15:23 +05303998 else if(strncmp(command, "SETWMMPS", 8) == 0)
3999 {
4000 tANI_U8 *ptr = command;
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05304001
4002 ret = hdd_drv_cmd_validate(command, 8);
4003 if (ret)
4004 goto exit;
4005
Kiet Lamf040f472013-11-20 21:15:23 +05304006 ret = hdd_wmmps_helper(pAdapter, ptr);
4007 }
Agarwal Ashishef54a182014-12-16 15:07:31 +05304008
4009 else if(strncmp(command, "TDLSSCAN", 8) == 0)
4010 {
4011 tANI_U8 *ptr = command;
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05304012
4013 ret = hdd_drv_cmd_validate(command, 8);
4014 if (ret)
4015 goto exit;
4016
Agarwal Ashishef54a182014-12-16 15:07:31 +05304017 ret = hdd_set_tdls_scan_type(pAdapter, ptr);
4018 }
4019
Jeff Johnson32d95a32012-09-10 13:15:23 -07004020 else if ( strncasecmp(command, "COUNTRY", 7) == 0 )
4021 {
4022 char *country_code;
4023
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05304024 ret = hdd_drv_cmd_validate(command, 7);
4025 if (ret)
4026 goto exit;
4027
Jeff Johnson32d95a32012-09-10 13:15:23 -07004028 country_code = command + 8;
Tushnim Bhattacharyya9cdf6082013-04-21 16:33:30 -07004029
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07004030 INIT_COMPLETION(pAdapter->change_country_code);
Tushnim Bhattacharyya9cdf6082013-04-21 16:33:30 -07004031 hdd_checkandupdate_dfssetting(pAdapter, country_code);
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -07004032#ifndef CONFIG_ENABLE_LINUX_REG
Gopichand Nakkaladacbcb52013-04-18 16:41:54 +05304033 hdd_checkandupdate_phymode(pAdapter, country_code);
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -07004034#endif
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07004035 ret = (int)sme_ChangeCountryCode(pHddCtx->hHal,
4036 (void *)(tSmeChangeCountryCallback)
4037 wlan_hdd_change_country_code_callback,
Abhishek Singha306a442013-11-07 18:39:01 +05304038 country_code, pAdapter, pHddCtx->pvosContext, eSIR_TRUE, eSIR_TRUE);
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07004039 if (eHAL_STATUS_SUCCESS == ret)
4040 {
4041 ret = wait_for_completion_interruptible_timeout(
4042 &pAdapter->change_country_code,
4043 msecs_to_jiffies(WLAN_WAIT_TIME_COUNTRY));
4044 if (0 >= ret)
4045 {
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07004046 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: SME while setting country code timed out %d",
c_hpothu6ff1c3c2013-10-01 19:01:57 +05304047 __func__, ret);
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07004048 }
4049 }
4050 else
Jeff Johnson32d95a32012-09-10 13:15:23 -07004051 {
4052 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07004053 "%s: SME Change Country code fail ret=%d", __func__, ret);
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07004054 ret = -EINVAL;
Jeff Johnson32d95a32012-09-10 13:15:23 -07004055 }
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07004056
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07004057 }
4058 /*
4059 command should be a string having format
4060 SET_SAP_CHANNEL_LIST <num of channels> <the channels seperated by spaces>
4061 */
Amar Singhal0974e402013-02-12 14:27:46 -08004062 else if(strncmp(command, "SET_SAP_CHANNEL_LIST", 20) == 0)
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07004063 {
Amar Singhal0974e402013-02-12 14:27:46 -08004064 tANI_U8 *ptr = command;
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07004065
4066 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004067 " Received Command to Set Preferred Channels for SAP in %s", __func__);
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07004068
Mahesh Kumar Kalikot Veetil2aad8d82013-02-07 12:31:28 -08004069 ret = sapSetPreferredChannel(ptr);
Jeff Johnson32d95a32012-09-10 13:15:23 -07004070 }
Sourav Mohapatra2416e0e2018-03-05 18:44:21 +05304071
4072 else if (strncmp(command, "VOWIFIMODE", 10) == 0)
4073 {
4074 tANI_U8 *ptr;
4075
4076 ret = hdd_drv_cmd_validate(command, 10);
4077 if (ret)
4078 goto exit;
4079
4080 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4081 "Received Command for VOWIFI mode in %s", __func__);
4082
4083 ptr = (tANI_U8*)command + 11;
4084 hdd_set_vowifi_mode(pHddCtx, *ptr - '0');
4085 }
4086
Sameer Thalappil45931fb2013-02-01 11:18:05 -08004087 else if(strncmp(command, "SETSUSPENDMODE", 14) == 0)
4088 {
4089 int suspend = 0;
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05304090 tANI_U8 *ptr;
4091
4092 ret = hdd_drv_cmd_validate(command, 14);
4093 if (ret)
4094 goto exit;
4095
4096 ptr = (tANI_U8*)command + 15;
Sameer Thalappil45931fb2013-02-01 11:18:05 -08004097
4098 suspend = *ptr - '0';
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05304099 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
4100 TRACE_CODE_HDD_SETSUSPENDMODE_IOCTL,
4101 pAdapter->sessionId, suspend));
Sameer Thalappil45931fb2013-02-01 11:18:05 -08004102 hdd_set_wlan_suspend_mode(suspend);
4103 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08004104#ifdef WLAN_FEATURE_NEIGHBOR_ROAMING
4105 else if (strncmp(command, "SETROAMTRIGGER", 14) == 0)
4106 {
4107 tANI_U8 *value = command;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07004108 tANI_S8 rssi = 0;
Srinivas Girigowdade697412013-02-14 16:31:48 -08004109 tANI_U8 lookUpThreshold = CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_DEFAULT;
4110 eHalStatus status = eHAL_STATUS_SUCCESS;
4111
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05304112 ret = hdd_drv_cmd_validate(command, 14);
4113 if (ret)
4114 goto exit;
4115
Srinivas Girigowdade697412013-02-14 16:31:48 -08004116 /* Move pointer to ahead of SETROAMTRIGGER<delimiter> */
4117 value = value + 15;
4118
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07004119 /* Convert the value from ascii to integer */
4120 ret = kstrtos8(value, 10, &rssi);
4121 if (ret < 0)
4122 {
4123 /* If the input value is greater than max value of datatype, then also
4124 kstrtou8 fails */
4125 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4126 "%s: kstrtou8 failed Input value may be out of range[%d - %d]",
Srinivas Girigowdafa7157d2013-10-31 10:14:22 -07004127 __func__,
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07004128 CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MIN,
4129 CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MAX);
4130 ret = -EINVAL;
4131 goto exit;
4132 }
4133
Srinivas Girigowdade697412013-02-14 16:31:48 -08004134 lookUpThreshold = abs(rssi);
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07004135
Srinivas Girigowdade697412013-02-14 16:31:48 -08004136 if ((lookUpThreshold < CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MIN) ||
4137 (lookUpThreshold > CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MAX))
4138 {
4139 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4140 "Neighbor lookup threshold value %d is out of range"
4141 " (Min: %d Max: %d)", lookUpThreshold,
4142 CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MIN,
4143 CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MAX);
4144 ret = -EINVAL;
4145 goto exit;
4146 }
4147
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05304148 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
4149 TRACE_CODE_HDD_SETROAMTRIGGER_IOCTL,
4150 pAdapter->sessionId, lookUpThreshold));
Srinivas Girigowdade697412013-02-14 16:31:48 -08004151 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4152 "%s: Received Command to Set Roam trigger"
4153 " (Neighbor lookup threshold) = %d", __func__, lookUpThreshold);
4154
4155 pHddCtx->cfg_ini->nNeighborLookupRssiThreshold = lookUpThreshold;
4156 status = sme_setNeighborLookupRssiThreshold((tHalHandle)(pHddCtx->hHal), lookUpThreshold);
4157 if (eHAL_STATUS_SUCCESS != status)
4158 {
4159 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4160 "%s: Failed to set roam trigger, try again", __func__);
4161 ret = -EPERM;
4162 goto exit;
4163 }
4164
4165 /* Set Reassoc threshold to (lookup rssi threshold + 5 dBm) */
mukul sharmad6e1fdd2014-06-23 19:19:09 +05304166 pHddCtx->cfg_ini->nNeighborReassocRssiThreshold = lookUpThreshold + 5;
Srinivas Girigowdade697412013-02-14 16:31:48 -08004167 sme_setNeighborReassocRssiThreshold((tHalHandle)(pHddCtx->hHal), lookUpThreshold + 5);
4168 }
4169 else if (strncmp(command, "GETROAMTRIGGER", 14) == 0)
4170 {
4171 tANI_U8 lookUpThreshold = sme_getNeighborLookupRssiThreshold((tHalHandle)(pHddCtx->hHal));
4172 int rssi = (-1) * lookUpThreshold;
4173 char extra[32];
4174 tANI_U8 len = 0;
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05304175 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
4176 TRACE_CODE_HDD_GETROAMTRIGGER_IOCTL,
4177 pAdapter->sessionId, lookUpThreshold));
Sameer Thalappilb0a30232013-09-27 15:37:48 -07004178 len = scnprintf(extra, sizeof(extra), "%s %d", command, rssi);
Srinivas Girigowda91719232015-07-13 15:10:10 +05304179 len = VOS_MIN(priv_data.total_len, len + 1);
4180 if (copy_to_user(priv_data.buf, &extra, len))
Srinivas Girigowdade697412013-02-14 16:31:48 -08004181 {
4182 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4183 "%s: failed to copy data to user buffer", __func__);
4184 ret = -EFAULT;
4185 goto exit;
4186 }
4187 }
4188 else if (strncmp(command, "SETROAMSCANPERIOD", 17) == 0)
4189 {
4190 tANI_U8 *value = command;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07004191 tANI_U8 roamScanPeriod = 0;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004192 tANI_U16 neighborEmptyScanRefreshPeriod = CFG_EMPTY_SCAN_REFRESH_PERIOD_DEFAULT;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07004193
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05304194 ret = hdd_drv_cmd_validate(command, 17);
4195 if (ret)
4196 goto exit;
4197
Srinivas Girigowdade697412013-02-14 16:31:48 -08004198 /* input refresh period is in terms of seconds */
4199 /* Move pointer to ahead of SETROAMSCANPERIOD<delimiter> */
4200 value = value + 18;
4201 /* Convert the value from ascii to integer */
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07004202 ret = kstrtou8(value, 10, &roamScanPeriod);
Srinivas Girigowdade697412013-02-14 16:31:48 -08004203 if (ret < 0)
4204 {
4205 /* If the input value is greater than max value of datatype, then also
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07004206 kstrtou8 fails */
Srinivas Girigowdade697412013-02-14 16:31:48 -08004207 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07004208 "%s: kstrtou8 failed Input value may be out of range[%d - %d]",
Srinivas Girigowdade697412013-02-14 16:31:48 -08004209 __func__,
Srinivas Girigowdab8edd1e2013-03-19 11:42:08 -07004210 (CFG_EMPTY_SCAN_REFRESH_PERIOD_MIN/1000),
4211 (CFG_EMPTY_SCAN_REFRESH_PERIOD_MAX/1000));
Srinivas Girigowdade697412013-02-14 16:31:48 -08004212 ret = -EINVAL;
4213 goto exit;
4214 }
4215
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07004216 if ((roamScanPeriod < (CFG_EMPTY_SCAN_REFRESH_PERIOD_MIN/1000)) ||
4217 (roamScanPeriod > (CFG_EMPTY_SCAN_REFRESH_PERIOD_MAX/1000)))
Srinivas Girigowdade697412013-02-14 16:31:48 -08004218 {
4219 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07004220 "Roam scan period value %d is out of range"
4221 " (Min: %d Max: %d)", roamScanPeriod,
Srinivas Girigowdab8edd1e2013-03-19 11:42:08 -07004222 (CFG_EMPTY_SCAN_REFRESH_PERIOD_MIN/1000),
4223 (CFG_EMPTY_SCAN_REFRESH_PERIOD_MAX/1000));
Srinivas Girigowdade697412013-02-14 16:31:48 -08004224 ret = -EINVAL;
4225 goto exit;
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05304226 }
4227 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
4228 TRACE_CODE_HDD_SETROAMSCANPERIOD_IOCTL,
4229 pAdapter->sessionId, roamScanPeriod));
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07004230 neighborEmptyScanRefreshPeriod = roamScanPeriod * 1000;
Srinivas Girigowdade697412013-02-14 16:31:48 -08004231
4232 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4233 "%s: Received Command to Set roam scan period"
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07004234 " (Empty Scan refresh period) = %d", __func__, roamScanPeriod);
Srinivas Girigowdade697412013-02-14 16:31:48 -08004235
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004236 pHddCtx->cfg_ini->nEmptyScanRefreshPeriod = neighborEmptyScanRefreshPeriod;
4237 sme_UpdateEmptyScanRefreshPeriod((tHalHandle)(pHddCtx->hHal), neighborEmptyScanRefreshPeriod);
Srinivas Girigowdade697412013-02-14 16:31:48 -08004238 }
4239 else if (strncmp(command, "GETROAMSCANPERIOD", 17) == 0)
4240 {
4241 tANI_U16 nEmptyScanRefreshPeriod = sme_getEmptyScanRefreshPeriod((tHalHandle)(pHddCtx->hHal));
4242 char extra[32];
4243 tANI_U8 len = 0;
4244
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05304245 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
4246 TRACE_CODE_HDD_GETROAMSCANPERIOD_IOCTL,
4247 pAdapter->sessionId, nEmptyScanRefreshPeriod));
Sameer Thalappilb0a30232013-09-27 15:37:48 -07004248 len = scnprintf(extra, sizeof(extra), "%s %d",
4249 "GETROAMSCANPERIOD", (nEmptyScanRefreshPeriod/1000));
Srinivas Girigowdade697412013-02-14 16:31:48 -08004250 /* Returned value is in units of seconds */
Ratnam Rachuria72ba112015-07-17 13:27:03 +05304251 len = VOS_MIN(priv_data.total_len, len + 1);
4252 if (copy_to_user(priv_data.buf, &extra, len)) {
Srinivas Girigowdade697412013-02-14 16:31:48 -08004253 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4254 "%s: failed to copy data to user buffer", __func__);
4255 ret = -EFAULT;
4256 goto exit;
4257 }
4258 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004259 else if (strncmp(command, "SETROAMSCANREFRESHPERIOD", 24) == 0)
4260 {
4261 tANI_U8 *value = command;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07004262 tANI_U8 roamScanRefreshPeriod = 0;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004263 tANI_U16 neighborScanRefreshPeriod = CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_DEFAULT;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07004264
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05304265 ret = hdd_drv_cmd_validate(command, 24);
4266 if (ret)
4267 goto exit;
4268
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004269 /* input refresh period is in terms of seconds */
4270 /* Move pointer to ahead of SETROAMSCANREFRESHPERIOD<delimiter> */
4271 value = value + 25;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07004272
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004273 /* Convert the value from ascii to integer */
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07004274 ret = kstrtou8(value, 10, &roamScanRefreshPeriod);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004275 if (ret < 0)
4276 {
4277 /* If the input value is greater than max value of datatype, then also
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07004278 kstrtou8 fails */
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004279 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07004280 "%s: kstrtou8 failed Input value may be out of range[%d - %d]",
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004281 __func__,
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004282 (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MIN/1000),
4283 (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MAX/1000));
4284 ret = -EINVAL;
4285 goto exit;
4286 }
4287
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07004288 if ((roamScanRefreshPeriod < (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MIN/1000)) ||
4289 (roamScanRefreshPeriod > (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MAX/1000)))
4290 {
4291 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4292 "Neighbor scan results refresh period value %d is out of range"
4293 " (Min: %d Max: %d)", roamScanRefreshPeriod,
4294 (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MIN/1000),
4295 (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MAX/1000));
4296 ret = -EINVAL;
4297 goto exit;
4298 }
4299 neighborScanRefreshPeriod = roamScanRefreshPeriod * 1000;
4300
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004301 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4302 "%s: Received Command to Set roam scan refresh period"
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07004303 " (Scan refresh period) = %d", __func__, roamScanRefreshPeriod);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004304
4305 pHddCtx->cfg_ini->nNeighborResultsRefreshPeriod = neighborScanRefreshPeriod;
4306 sme_setNeighborScanRefreshPeriod((tHalHandle)(pHddCtx->hHal), neighborScanRefreshPeriod);
4307 }
4308 else if (strncmp(command, "GETROAMSCANREFRESHPERIOD", 24) == 0)
4309 {
4310 tANI_U16 value = sme_getNeighborScanRefreshPeriod((tHalHandle)(pHddCtx->hHal));
4311 char extra[32];
4312 tANI_U8 len = 0;
4313
Sameer Thalappilb0a30232013-09-27 15:37:48 -07004314 len = scnprintf(extra, sizeof(extra), "%s %d",
4315 "GETROAMSCANREFRESHPERIOD", (value/1000));
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004316 /* Returned value is in units of seconds */
Ratnam Rachuri2c9d6702015-07-17 13:25:16 +05304317 len = VOS_MIN(priv_data.total_len, len + 1);
4318 if (copy_to_user(priv_data.buf, &extra, len)) {
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004319 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4320 "%s: failed to copy data to user buffer", __func__);
4321 ret = -EFAULT;
4322 goto exit;
4323 }
4324 }
Varun Reddy Yeturu6d99ac82013-05-08 14:15:35 -07004325#ifdef FEATURE_WLAN_LFR
4326 /* SETROAMMODE */
4327 else if (strncmp(command, "SETROAMMODE", SIZE_OF_SETROAMMODE) == 0)
4328 {
4329 tANI_U8 *value = command;
4330 tANI_BOOLEAN roamMode = CFG_LFR_FEATURE_ENABLED_DEFAULT;
4331
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +05304332 if (pHddCtx->concurrency_mode == VOS_STA_MON) {
4333 hddLog(LOGE,
4334 FL("Roaming is always disabled in STA + MON concurrency"));
4335 ret = -EINVAL;
4336 goto exit;
4337 }
4338
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05304339 ret = hdd_drv_cmd_validate(command, SIZE_OF_SETROAMMODE);
4340 if (ret)
4341 goto exit;
4342
Varun Reddy Yeturu6d99ac82013-05-08 14:15:35 -07004343 /* Move pointer to ahead of SETROAMMODE<delimiter> */
4344 value = value + SIZE_OF_SETROAMMODE + 1;
4345
4346 /* Convert the value from ascii to integer */
4347 ret = kstrtou8(value, SIZE_OF_SETROAMMODE, &roamMode);
4348 if (ret < 0)
4349 {
4350 /* If the input value is greater than max value of datatype, then also
4351 kstrtou8 fails */
4352 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4353 "%s: kstrtou8 failed range [%d - %d]", __func__,
4354 CFG_LFR_FEATURE_ENABLED_MIN,
4355 CFG_LFR_FEATURE_ENABLED_MAX);
4356 ret = -EINVAL;
4357 goto exit;
4358 }
4359 if ((roamMode < CFG_LFR_FEATURE_ENABLED_MIN) ||
4360 (roamMode > CFG_LFR_FEATURE_ENABLED_MAX))
4361 {
4362 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4363 "Roam Mode value %d is out of range"
4364 " (Min: %d Max: %d)", roamMode,
4365 CFG_LFR_FEATURE_ENABLED_MIN,
4366 CFG_LFR_FEATURE_ENABLED_MAX);
4367 ret = -EINVAL;
4368 goto exit;
4369 }
4370
4371 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4372 "%s: Received Command to Set Roam Mode = %d", __func__, roamMode);
4373 /*
4374 * Note that
4375 * SETROAMMODE 0 is to enable LFR while
4376 * SETROAMMODE 1 is to disable LFR, but
4377 * NotifyIsFastRoamIniFeatureEnabled 0/1 is to enable/disable.
4378 * So, we have to invert the value to call sme_UpdateIsFastRoamIniFeatureEnabled.
4379 */
4380 if (CFG_LFR_FEATURE_ENABLED_MIN == roamMode)
4381 roamMode = CFG_LFR_FEATURE_ENABLED_MAX; /* Roam enable */
4382 else
4383 roamMode = CFG_LFR_FEATURE_ENABLED_MIN; /* Roam disable */
4384
4385 pHddCtx->cfg_ini->isFastRoamIniFeatureEnabled = roamMode;
4386 sme_UpdateIsFastRoamIniFeatureEnabled((tHalHandle)(pHddCtx->hHal), roamMode);
4387 }
4388 /* GETROAMMODE */
Mahesh A Saptasagarec7d1092015-04-02 13:41:34 +05304389 else if (strncmp(command, "GETROAMMODE", SIZE_OF_GETROAMMODE) == 0)
Varun Reddy Yeturu6d99ac82013-05-08 14:15:35 -07004390 {
4391 tANI_BOOLEAN roamMode = sme_getIsLfrFeatureEnabled((tHalHandle)(pHddCtx->hHal));
4392 char extra[32];
4393 tANI_U8 len = 0;
4394
4395 /*
4396 * roamMode value shall be inverted because the sementics is different.
4397 */
4398 if (CFG_LFR_FEATURE_ENABLED_MIN == roamMode)
4399 roamMode = CFG_LFR_FEATURE_ENABLED_MAX;
4400 else
4401 roamMode = CFG_LFR_FEATURE_ENABLED_MIN;
4402
Sameer Thalappilb0a30232013-09-27 15:37:48 -07004403 len = scnprintf(extra, sizeof(extra), "%s %d", command, roamMode);
Ratnam Rachuri28693eb2015-07-17 13:23:42 +05304404 len = VOS_MIN(priv_data.total_len, len + 1);
4405 if (copy_to_user(priv_data.buf, &extra, len)) {
Varun Reddy Yeturu6d99ac82013-05-08 14:15:35 -07004406 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4407 "%s: failed to copy data to user buffer", __func__);
4408 ret = -EFAULT;
4409 goto exit;
4410 }
4411 }
4412#endif
Srinivas Girigowdade697412013-02-14 16:31:48 -08004413#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004414#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowdade697412013-02-14 16:31:48 -08004415 else if (strncmp(command, "SETROAMDELTA", 12) == 0)
4416 {
4417 tANI_U8 *value = command;
4418 tANI_U8 roamRssiDiff = CFG_ROAM_RSSI_DIFF_DEFAULT;
4419
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05304420 ret = hdd_drv_cmd_validate(command, 12);
4421 if (ret)
4422 goto exit;
4423
Srinivas Girigowdade697412013-02-14 16:31:48 -08004424 /* Move pointer to ahead of SETROAMDELTA<delimiter> */
4425 value = value + 13;
4426 /* Convert the value from ascii to integer */
4427 ret = kstrtou8(value, 10, &roamRssiDiff);
4428 if (ret < 0)
4429 {
4430 /* If the input value is greater than max value of datatype, then also
4431 kstrtou8 fails */
4432 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4433 "%s: kstrtou8 failed range [%d - %d]", __func__,
4434 CFG_ROAM_RSSI_DIFF_MIN,
4435 CFG_ROAM_RSSI_DIFF_MAX);
4436 ret = -EINVAL;
4437 goto exit;
4438 }
4439
4440 if ((roamRssiDiff < CFG_ROAM_RSSI_DIFF_MIN) ||
4441 (roamRssiDiff > CFG_ROAM_RSSI_DIFF_MAX))
4442 {
4443 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4444 "Roam rssi diff value %d is out of range"
4445 " (Min: %d Max: %d)", roamRssiDiff,
4446 CFG_ROAM_RSSI_DIFF_MIN,
4447 CFG_ROAM_RSSI_DIFF_MAX);
4448 ret = -EINVAL;
4449 goto exit;
4450 }
4451
4452 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4453 "%s: Received Command to Set roam rssi diff = %d", __func__, roamRssiDiff);
4454
4455 pHddCtx->cfg_ini->RoamRssiDiff = roamRssiDiff;
4456 sme_UpdateRoamRssiDiff((tHalHandle)(pHddCtx->hHal), roamRssiDiff);
4457 }
Mahesh A Saptasagarec7d1092015-04-02 13:41:34 +05304458 else if (strncmp(command, "GETROAMDELTA", 12) == 0)
Srinivas Girigowdade697412013-02-14 16:31:48 -08004459 {
4460 tANI_U8 roamRssiDiff = sme_getRoamRssiDiff((tHalHandle)(pHddCtx->hHal));
4461 char extra[32];
4462 tANI_U8 len = 0;
4463
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05304464 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
4465 TRACE_CODE_HDD_GETROAMDELTA_IOCTL,
4466 pAdapter->sessionId, roamRssiDiff));
Sameer Thalappilb0a30232013-09-27 15:37:48 -07004467 len = scnprintf(extra, sizeof(extra), "%s %d",
4468 command, roamRssiDiff);
Ratnam Rachuri22a3b402015-07-17 13:21:49 +05304469 len = VOS_MIN(priv_data.total_len, len + 1);
4470 if (copy_to_user(priv_data.buf, &extra, len)) {
Srinivas Girigowdade697412013-02-14 16:31:48 -08004471 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4472 "%s: failed to copy data to user buffer", __func__);
4473 ret = -EFAULT;
4474 goto exit;
4475 }
4476 }
4477#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004478#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowdade697412013-02-14 16:31:48 -08004479 else if (strncmp(command, "GETBAND", 7) == 0)
4480 {
4481 int band = -1;
4482 char extra[32];
4483 tANI_U8 len = 0;
4484 hdd_getBand_helper(pHddCtx, &band);
4485
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05304486 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
4487 TRACE_CODE_HDD_GETBAND_IOCTL,
4488 pAdapter->sessionId, band));
Sameer Thalappilb0a30232013-09-27 15:37:48 -07004489 len = scnprintf(extra, sizeof(extra), "%s %d", command, band);
Ratnam Rachuri52139592015-07-17 13:17:29 +05304490 len = VOS_MIN(priv_data.total_len, len + 1);
4491 if (copy_to_user(priv_data.buf, &extra, len)) {
Srinivas Girigowdade697412013-02-14 16:31:48 -08004492 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4493 "%s: failed to copy data to user buffer", __func__);
4494 ret = -EFAULT;
4495 goto exit;
4496 }
4497 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08004498 else if (strncmp(command, "SETROAMSCANCHANNELS", 19) == 0)
4499 {
4500 tANI_U8 *value = command;
4501 tANI_U8 ChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
4502 tANI_U8 numChannels = 0;
4503 eHalStatus status = eHAL_STATUS_SUCCESS;
4504
4505 status = hdd_parse_channellist(value, ChannelList, &numChannels);
4506 if (eHAL_STATUS_SUCCESS != status)
4507 {
4508 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4509 "%s: Failed to parse channel list information", __func__);
4510 ret = -EINVAL;
4511 goto exit;
4512 }
4513
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05304514 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
4515 TRACE_CODE_HDD_SETROAMSCANCHANNELS_IOCTL,
4516 pAdapter->sessionId, numChannels));
Srinivas Girigowdade697412013-02-14 16:31:48 -08004517 if (numChannels > WNI_CFG_VALID_CHANNEL_LIST_LEN)
4518 {
4519 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4520 "%s: number of channels (%d) supported exceeded max (%d)", __func__,
4521 numChannels, WNI_CFG_VALID_CHANNEL_LIST_LEN);
4522 ret = -EINVAL;
4523 goto exit;
4524 }
4525 status = sme_ChangeRoamScanChannelList((tHalHandle)(pHddCtx->hHal), ChannelList,
4526 numChannels);
4527 if (eHAL_STATUS_SUCCESS != status)
4528 {
4529 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4530 "%s: Failed to update channel list information", __func__);
4531 ret = -EINVAL;
4532 goto exit;
4533 }
4534 }
4535 else if (strncmp(command, "GETROAMSCANCHANNELS", 19) == 0)
4536 {
4537 tANI_U8 ChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
4538 tANI_U8 numChannels = 0;
Jeff Johnson51b67782013-04-05 12:35:41 -07004539 tANI_U8 j = 0;
Srinivas Girigowdade697412013-02-14 16:31:48 -08004540 char extra[128] = {0};
Jeff Johnson51b67782013-04-05 12:35:41 -07004541 int len;
Srinivas Girigowdade697412013-02-14 16:31:48 -08004542
4543 if (eHAL_STATUS_SUCCESS != sme_getRoamScanChannelList( (tHalHandle)(pHddCtx->hHal),
4544 ChannelList, &numChannels ))
4545 {
4546 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
4547 "%s: failed to get roam scan channel list", __func__);
4548 ret = -EFAULT;
4549 goto exit;
4550 }
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05304551 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
4552 TRACE_CODE_HDD_GETROAMSCANCHANNELS_IOCTL,
4553 pAdapter->sessionId, numChannels));
Srinivas Girigowdade697412013-02-14 16:31:48 -08004554 /* output channel list is of the format
4555 [Number of roam scan channels][Channel1][Channel2]... */
4556 /* copy the number of channels in the 0th index */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07004557 len = scnprintf(extra, sizeof(extra), "%s %d", command, numChannels);
Sushant Kaushika08ca192015-09-16 15:52:04 +05304558 for (j = 0; (j < numChannels) && len <= sizeof(extra); j++)
Srinivas Girigowdade697412013-02-14 16:31:48 -08004559 {
Sameer Thalappilb0a30232013-09-27 15:37:48 -07004560 len += scnprintf(extra + len, sizeof(extra) - len, " %d",
4561 ChannelList[j]);
Srinivas Girigowdade697412013-02-14 16:31:48 -08004562 }
4563
Sushant Kaushikc9b8be52015-07-15 16:41:27 +05304564 len = VOS_MIN(priv_data.total_len, len + 1);
4565 if (copy_to_user(priv_data.buf, &extra, len))
Srinivas Girigowdade697412013-02-14 16:31:48 -08004566 {
4567 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4568 "%s: failed to copy data to user buffer", __func__);
4569 ret = -EFAULT;
4570 goto exit;
4571 }
4572 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004573 else if (strncmp(command, "GETCCXMODE", 10) == 0)
4574 {
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004575 tANI_BOOLEAN eseMode = sme_getIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal));
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004576 char extra[32];
4577 tANI_U8 len = 0;
4578
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004579 /* Check if the features OKC/ESE/11R are supported simultaneously,
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07004580 then this operation is not permitted (return FAILURE) */
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004581 if (eseMode &&
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07004582 hdd_is_okc_mode_enabled(pHddCtx) &&
4583 sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal)))
4584 {
4585 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004586 "%s: OKC/ESE/11R are supported simultaneously"
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07004587 " hence this operation is not permitted!", __func__);
4588 ret = -EPERM;
4589 goto exit;
4590 }
4591
Sameer Thalappilb0a30232013-09-27 15:37:48 -07004592 len = scnprintf(extra, sizeof(extra), "%s %d",
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004593 "GETCCXMODE", eseMode);
Sushant Kaushikf8abd352015-07-15 16:37:49 +05304594 len = VOS_MIN(priv_data.total_len, len + 1);
4595 if (copy_to_user(priv_data.buf, &extra, len))
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004596 {
4597 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4598 "%s: failed to copy data to user buffer", __func__);
4599 ret = -EFAULT;
4600 goto exit;
4601 }
4602 }
4603 else if (strncmp(command, "GETOKCMODE", 10) == 0)
4604 {
4605 tANI_BOOLEAN okcMode = hdd_is_okc_mode_enabled(pHddCtx);
4606 char extra[32];
4607 tANI_U8 len = 0;
4608
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004609 /* Check if the features OKC/ESE/11R are supported simultaneously,
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07004610 then this operation is not permitted (return FAILURE) */
4611 if (okcMode &&
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004612 sme_getIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal)) &&
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07004613 sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal)))
4614 {
4615 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004616 "%s: OKC/ESE/11R are supported simultaneously"
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07004617 " hence this operation is not permitted!", __func__);
4618 ret = -EPERM;
4619 goto exit;
4620 }
4621
Sameer Thalappilb0a30232013-09-27 15:37:48 -07004622 len = scnprintf(extra, sizeof(extra), "%s %d",
4623 "GETOKCMODE", okcMode);
Sushant Kaushikbc2fb5c2015-07-15 16:43:16 +05304624 len = VOS_MIN(priv_data.total_len, len + 1);
4625 if (copy_to_user(priv_data.buf, &extra, len))
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004626 {
4627 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4628 "%s: failed to copy data to user buffer", __func__);
4629 ret = -EFAULT;
4630 goto exit;
4631 }
4632 }
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07004633 else if (strncmp(command, "GETFASTROAM", 11) == 0)
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004634 {
4635 tANI_BOOLEAN lfrMode = sme_getIsLfrFeatureEnabled((tHalHandle)(pHddCtx->hHal));
4636 char extra[32];
4637 tANI_U8 len = 0;
4638
Sameer Thalappilb0a30232013-09-27 15:37:48 -07004639 len = scnprintf(extra, sizeof(extra), "%s %d",
4640 "GETFASTROAM", lfrMode);
Sushant Kaushik4da7ec92015-07-15 16:39:32 +05304641 len = VOS_MIN(priv_data.total_len, len + 1);
4642 if (copy_to_user(priv_data.buf, &extra, len))
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004643 {
4644 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4645 "%s: failed to copy data to user buffer", __func__);
4646 ret = -EFAULT;
4647 goto exit;
4648 }
4649 }
4650 else if (strncmp(command, "GETFASTTRANSITION", 17) == 0)
4651 {
4652 tANI_BOOLEAN ft = sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal));
4653 char extra[32];
4654 tANI_U8 len = 0;
4655
Sameer Thalappilb0a30232013-09-27 15:37:48 -07004656 len = scnprintf(extra, sizeof(extra), "%s %d",
4657 "GETFASTTRANSITION", ft);
Sushant Kaushik231a4452015-07-15 16:23:56 +05304658 len = VOS_MIN(priv_data.total_len, len + 1);
4659 if (copy_to_user(priv_data.buf, &extra, len))
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004660 {
4661 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4662 "%s: failed to copy data to user buffer", __func__);
4663 ret = -EFAULT;
4664 goto exit;
4665 }
4666 }
4667 else if (strncmp(command, "SETROAMSCANCHANNELMINTIME", 25) == 0)
4668 {
4669 tANI_U8 *value = command;
4670 tANI_U8 minTime = CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_DEFAULT;
4671
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05304672 ret = hdd_drv_cmd_validate(command, 25);
4673 if (ret)
4674 goto exit;
4675
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004676 /* Move pointer to ahead of SETROAMSCANCHANNELMINTIME<delimiter> */
4677 value = value + 26;
4678 /* Convert the value from ascii to integer */
4679 ret = kstrtou8(value, 10, &minTime);
4680 if (ret < 0)
4681 {
4682 /* If the input value is greater than max value of datatype, then also
4683 kstrtou8 fails */
4684 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4685 "%s: kstrtou8 failed range [%d - %d]", __func__,
4686 CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MIN,
4687 CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MAX);
4688 ret = -EINVAL;
4689 goto exit;
4690 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004691 if ((minTime < CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MIN) ||
4692 (minTime > CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MAX))
4693 {
4694 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4695 "scan min channel time value %d is out of range"
4696 " (Min: %d Max: %d)", minTime,
4697 CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MIN,
4698 CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MAX);
4699 ret = -EINVAL;
4700 goto exit;
4701 }
4702
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05304703 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
4704 TRACE_CODE_HDD_SETROAMSCANCHANNELMINTIME_IOCTL,
4705 pAdapter->sessionId, minTime));
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004706 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4707 "%s: Received Command to change channel min time = %d", __func__, minTime);
4708
4709 pHddCtx->cfg_ini->nNeighborScanMinChanTime = minTime;
4710 sme_setNeighborScanMinChanTime((tHalHandle)(pHddCtx->hHal), minTime);
4711 }
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004712 else if (strncmp(command, "SENDACTIONFRAME", 15) == 0)
4713 {
4714 tANI_U8 *value = command;
4715 tANI_U8 channel = 0;
4716 tANI_U8 dwellTime = 0;
4717 tANI_U8 bufLen = 0;
4718 tANI_U8 *buf = NULL;
4719 tSirMacAddr targetApBssid;
4720 eHalStatus status = eHAL_STATUS_SUCCESS;
4721 struct ieee80211_channel chan;
4722 tANI_U8 finalLen = 0;
4723 tANI_U8 *finalBuf = NULL;
4724 tANI_U8 temp = 0;
4725 u64 cookie;
4726 hdd_station_ctx_t *pHddStaCtx = NULL;
4727 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4728
4729 /* if not associated, no need to send action frame */
4730 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
4731 {
4732 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s:Not associated!",__func__);
4733 ret = -EINVAL;
4734 goto exit;
4735 }
4736
4737 status = hdd_parse_send_action_frame_data(value, targetApBssid, &channel,
4738 &dwellTime, &buf, &bufLen);
4739 if (eHAL_STATUS_SUCCESS != status)
4740 {
4741 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4742 "%s: Failed to parse send action frame data", __func__);
4743 ret = -EINVAL;
4744 goto exit;
4745 }
4746
4747 /* if the target bssid is different from currently associated AP,
4748 then no need to send action frame */
4749 if (VOS_TRUE != vos_mem_compare(targetApBssid,
4750 pHddStaCtx->conn_info.bssId, sizeof(tSirMacAddr)))
4751 {
4752 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s:STA is not associated to this AP!",__func__);
4753 ret = -EINVAL;
Jeff Johnson11c33152013-04-16 17:52:40 -07004754 vos_mem_free(buf);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08004755 buf = NULL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004756 goto exit;
4757 }
4758
4759 /* if the channel number is different from operating channel then
4760 no need to send action frame */
4761 if (channel != pHddStaCtx->conn_info.operationChannel)
4762 {
4763 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4764 "%s: channel(%d) is different from operating channel(%d)",
4765 __func__, channel, pHddStaCtx->conn_info.operationChannel);
4766 ret = -EINVAL;
Jeff Johnson11c33152013-04-16 17:52:40 -07004767 vos_mem_free(buf);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08004768 buf = NULL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004769 goto exit;
4770 }
4771 chan.center_freq = sme_ChnToFreq(channel);
4772
4773 finalLen = bufLen + 24;
4774 finalBuf = vos_mem_malloc(finalLen);
4775 if (NULL == finalBuf)
4776 {
4777 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "%s:memory allocation failed",__func__);
4778 ret = -ENOMEM;
Jeff Johnson11c33152013-04-16 17:52:40 -07004779 vos_mem_free(buf);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08004780 buf = NULL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004781 goto exit;
4782 }
4783 vos_mem_zero(finalBuf, finalLen);
4784
4785 /* Fill subtype */
4786 temp = SIR_MAC_MGMT_ACTION << 4;
4787 vos_mem_copy(finalBuf + 0, &temp, sizeof(temp));
4788
4789 /* Fill type */
4790 temp = SIR_MAC_MGMT_FRAME;
4791 vos_mem_copy(finalBuf + 2, &temp, sizeof(temp));
4792
4793 /* Fill destination address (bssid of the AP) */
4794 vos_mem_copy(finalBuf + 4, targetApBssid, sizeof(targetApBssid));
4795
Srinivas Girigowdab27c0192013-06-03 10:19:56 -07004796 /* Fill source address (STA mac address) */
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004797 vos_mem_copy(finalBuf + 10, pAdapter->macAddressCurrent.bytes, sizeof(pAdapter->macAddressCurrent.bytes));
4798
Srinivas Girigowdab27c0192013-06-03 10:19:56 -07004799 /* Fill BSSID (AP mac address) */
4800 vos_mem_copy(finalBuf + 16, targetApBssid, sizeof(targetApBssid));
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004801
4802 /* Fill received buffer from 24th address */
4803 vos_mem_copy(finalBuf + 24, buf, bufLen);
4804
Jeff Johnson11c33152013-04-16 17:52:40 -07004805 /* done with the parsed buffer */
4806 vos_mem_free(buf);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08004807 buf = NULL;
Jeff Johnson11c33152013-04-16 17:52:40 -07004808
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05304809#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
4810 params.chan = &chan;
4811 params.offchan = 0;
4812 params.wait = dwellTime;
4813 params.buf = finalBuf;
4814 params.len = finalLen;
4815 params.no_cck = 1;
4816 params.dont_wait_for_ack = 1;
4817 ret = wlan_hdd_mgmt_tx(NULL, &pAdapter->wdev, &params, &cookie);
4818#else
DARAM SUDHA39eede62014-02-12 11:16:40 +05304819 wlan_hdd_mgmt_tx( NULL,
Yue Maf49ba872013-08-19 12:04:25 -07004820#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
4821 &(pAdapter->wdev),
4822#else
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07004823 pAdapter->dev,
Yue Maf49ba872013-08-19 12:04:25 -07004824#endif
4825 &chan, 0,
4826#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0))
4827 NL80211_CHAN_HT20, 1,
4828#endif
4829 dwellTime, finalBuf, finalLen, 1,
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004830 1, &cookie );
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05304831#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0)*/
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004832 vos_mem_free(finalBuf);
4833 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004834 else if (strncmp(command, "GETROAMSCANCHANNELMINTIME", 25) == 0)
4835 {
4836 tANI_U16 val = sme_getNeighborScanMinChanTime((tHalHandle)(pHddCtx->hHal));
4837 char extra[32];
4838 tANI_U8 len = 0;
4839
4840 /* value is interms of msec */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07004841 len = scnprintf(extra, sizeof(extra), "%s %d",
4842 "GETROAMSCANCHANNELMINTIME", val);
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05304843 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
4844 TRACE_CODE_HDD_GETROAMSCANCHANNELMINTIME_IOCTL,
4845 pAdapter->sessionId, val));
Sushant Kaushikbb8c52c2015-07-15 16:36:23 +05304846 len = VOS_MIN(priv_data.total_len, len + 1);
4847 if (copy_to_user(priv_data.buf, &extra, len))
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004848 {
4849 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4850 "%s: failed to copy data to user buffer", __func__);
4851 ret = -EFAULT;
4852 goto exit;
4853 }
4854 }
4855 else if (strncmp(command, "SETSCANCHANNELTIME", 18) == 0)
4856 {
4857 tANI_U8 *value = command;
Varun Reddy Yeturu3885a662013-06-19 07:10:37 -07004858 tANI_U16 maxTime = CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_DEFAULT;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004859
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05304860 ret = hdd_drv_cmd_validate(command, 18);
4861 if (ret)
4862 goto exit;
4863
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004864 /* Move pointer to ahead of SETSCANCHANNELTIME<delimiter> */
4865 value = value + 19;
4866 /* Convert the value from ascii to integer */
Varun Reddy Yeturu3885a662013-06-19 07:10:37 -07004867 ret = kstrtou16(value, 10, &maxTime);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004868 if (ret < 0)
4869 {
4870 /* If the input value is greater than max value of datatype, then also
Varun Reddy Yeturu3885a662013-06-19 07:10:37 -07004871 kstrtou16 fails */
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004872 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Varun Reddy Yeturu3885a662013-06-19 07:10:37 -07004873 "%s: kstrtou16 failed range [%d - %d]", __func__,
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004874 CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MIN,
4875 CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MAX);
4876 ret = -EINVAL;
4877 goto exit;
4878 }
4879
4880 if ((maxTime < CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MIN) ||
4881 (maxTime > CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MAX))
4882 {
4883 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4884 "lfr mode value %d is out of range"
4885 " (Min: %d Max: %d)", maxTime,
4886 CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MIN,
4887 CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MAX);
4888 ret = -EINVAL;
4889 goto exit;
4890 }
4891
4892 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4893 "%s: Received Command to change channel max time = %d", __func__, maxTime);
4894
4895 pHddCtx->cfg_ini->nNeighborScanMaxChanTime = maxTime;
4896 sme_setNeighborScanMaxChanTime((tHalHandle)(pHddCtx->hHal), maxTime);
4897 }
4898 else if (strncmp(command, "GETSCANCHANNELTIME", 18) == 0)
4899 {
4900 tANI_U16 val = sme_getNeighborScanMaxChanTime((tHalHandle)(pHddCtx->hHal));
4901 char extra[32];
4902 tANI_U8 len = 0;
4903
4904 /* value is interms of msec */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07004905 len = scnprintf(extra, sizeof(extra), "%s %d",
4906 "GETSCANCHANNELTIME", val);
Ratheesh S Pacbfa932015-07-16 15:27:18 +05304907 len = VOS_MIN(priv_data.total_len, len + 1);
4908 if (copy_to_user(priv_data.buf, &extra, len))
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004909 {
4910 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4911 "%s: failed to copy data to user buffer", __func__);
4912 ret = -EFAULT;
4913 goto exit;
4914 }
4915 }
4916 else if (strncmp(command, "SETSCANHOMETIME", 15) == 0)
4917 {
4918 tANI_U8 *value = command;
4919 tANI_U16 val = CFG_NEIGHBOR_SCAN_TIMER_PERIOD_DEFAULT;
4920
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05304921 ret = hdd_drv_cmd_validate(command, 15);
4922 if (ret)
4923 goto exit;
4924
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004925 /* Move pointer to ahead of SETSCANHOMETIME<delimiter> */
4926 value = value + 16;
4927 /* Convert the value from ascii to integer */
4928 ret = kstrtou16(value, 10, &val);
4929 if (ret < 0)
4930 {
4931 /* If the input value is greater than max value of datatype, then also
4932 kstrtou16 fails */
4933 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4934 "%s: kstrtou16 failed range [%d - %d]", __func__,
4935 CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MIN,
4936 CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MAX);
4937 ret = -EINVAL;
4938 goto exit;
4939 }
4940
4941 if ((val < CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MIN) ||
4942 (val > CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MAX))
4943 {
4944 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4945 "scan home time value %d is out of range"
4946 " (Min: %d Max: %d)", val,
4947 CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MIN,
4948 CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MAX);
4949 ret = -EINVAL;
4950 goto exit;
4951 }
4952
4953 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4954 "%s: Received Command to change scan home time = %d", __func__, val);
4955
4956 pHddCtx->cfg_ini->nNeighborScanPeriod = val;
4957 sme_setNeighborScanPeriod((tHalHandle)(pHddCtx->hHal), val);
4958 }
4959 else if (strncmp(command, "GETSCANHOMETIME", 15) == 0)
4960 {
4961 tANI_U16 val = sme_getNeighborScanPeriod((tHalHandle)(pHddCtx->hHal));
4962 char extra[32];
4963 tANI_U8 len = 0;
4964
4965 /* value is interms of msec */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07004966 len = scnprintf(extra, sizeof(extra), "%s %d",
4967 "GETSCANHOMETIME", val);
Ratheesh S P728d7c62015-07-16 15:38:58 +05304968 len = VOS_MIN(priv_data.total_len, len + 1);
4969 if (copy_to_user(priv_data.buf, &extra, len))
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004970 {
4971 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4972 "%s: failed to copy data to user buffer", __func__);
4973 ret = -EFAULT;
4974 goto exit;
4975 }
4976 }
4977 else if (strncmp(command, "SETROAMINTRABAND", 16) == 0)
4978 {
4979 tANI_U8 *value = command;
4980 tANI_U8 val = CFG_ROAM_INTRA_BAND_DEFAULT;
4981
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05304982 ret = hdd_drv_cmd_validate(command, 16);
4983 if (ret)
4984 goto exit;
4985
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004986 /* Move pointer to ahead of SETROAMINTRABAND<delimiter> */
4987 value = value + 17;
4988 /* Convert the value from ascii to integer */
4989 ret = kstrtou8(value, 10, &val);
4990 if (ret < 0)
4991 {
4992 /* If the input value is greater than max value of datatype, then also
4993 kstrtou8 fails */
4994 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4995 "%s: kstrtou8 failed range [%d - %d]", __func__,
4996 CFG_ROAM_INTRA_BAND_MIN,
4997 CFG_ROAM_INTRA_BAND_MAX);
4998 ret = -EINVAL;
4999 goto exit;
5000 }
5001
5002 if ((val < CFG_ROAM_INTRA_BAND_MIN) ||
5003 (val > CFG_ROAM_INTRA_BAND_MAX))
5004 {
5005 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5006 "intra band mode value %d is out of range"
5007 " (Min: %d Max: %d)", val,
5008 CFG_ROAM_INTRA_BAND_MIN,
5009 CFG_ROAM_INTRA_BAND_MAX);
5010 ret = -EINVAL;
5011 goto exit;
5012 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07005013 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
5014 "%s: Received Command to change intra band = %d", __func__, val);
5015
5016 pHddCtx->cfg_ini->nRoamIntraBand = val;
5017 sme_setRoamIntraBand((tHalHandle)(pHddCtx->hHal), val);
5018 }
5019 else if (strncmp(command, "GETROAMINTRABAND", 16) == 0)
5020 {
5021 tANI_U16 val = sme_getRoamIntraBand((tHalHandle)(pHddCtx->hHal));
5022 char extra[32];
5023 tANI_U8 len = 0;
5024
5025 /* value is interms of msec */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07005026 len = scnprintf(extra, sizeof(extra), "%s %d",
5027 "GETROAMINTRABAND", val);
Ratheesh S P2dd2a3e2015-07-16 15:34:23 +05305028 len = VOS_MIN(priv_data.total_len, len + 1);
5029 if (copy_to_user(priv_data.buf, &extra, len))
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07005030 {
5031 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5032 "%s: failed to copy data to user buffer", __func__);
5033 ret = -EFAULT;
5034 goto exit;
5035 }
5036 }
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005037 else if (strncmp(command, "SETSCANNPROBES", 14) == 0)
5038 {
5039 tANI_U8 *value = command;
5040 tANI_U8 nProbes = CFG_ROAM_SCAN_N_PROBES_DEFAULT;
5041
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05305042 ret = hdd_drv_cmd_validate(command, 14);
5043 if (ret)
5044 goto exit;
5045
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005046 /* Move pointer to ahead of SETSCANNPROBES<delimiter> */
5047 value = value + 15;
5048 /* Convert the value from ascii to integer */
5049 ret = kstrtou8(value, 10, &nProbes);
5050 if (ret < 0)
5051 {
5052 /* If the input value is greater than max value of datatype, then also
5053 kstrtou8 fails */
5054 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5055 "%s: kstrtou8 failed range [%d - %d]", __func__,
5056 CFG_ROAM_SCAN_N_PROBES_MIN,
5057 CFG_ROAM_SCAN_N_PROBES_MAX);
5058 ret = -EINVAL;
5059 goto exit;
5060 }
5061
5062 if ((nProbes < CFG_ROAM_SCAN_N_PROBES_MIN) ||
5063 (nProbes > CFG_ROAM_SCAN_N_PROBES_MAX))
5064 {
5065 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5066 "NProbes value %d is out of range"
5067 " (Min: %d Max: %d)", nProbes,
5068 CFG_ROAM_SCAN_N_PROBES_MIN,
5069 CFG_ROAM_SCAN_N_PROBES_MAX);
5070 ret = -EINVAL;
5071 goto exit;
5072 }
5073
5074 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
5075 "%s: Received Command to Set nProbes = %d", __func__, nProbes);
5076
5077 pHddCtx->cfg_ini->nProbes = nProbes;
5078 sme_UpdateRoamScanNProbes((tHalHandle)(pHddCtx->hHal), nProbes);
5079 }
Mahesh A Saptasagarec7d1092015-04-02 13:41:34 +05305080 else if (strncmp(command, "GETSCANNPROBES", 14) == 0)
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005081 {
5082 tANI_U8 val = sme_getRoamScanNProbes((tHalHandle)(pHddCtx->hHal));
5083 char extra[32];
5084 tANI_U8 len = 0;
5085
Sameer Thalappilb0a30232013-09-27 15:37:48 -07005086 len = scnprintf(extra, sizeof(extra), "%s %d", command, val);
Ratnam Rachuri6da525d2015-08-07 13:55:54 +05305087 len = VOS_MIN(priv_data.total_len, len + 1);
5088 if (copy_to_user(priv_data.buf, &extra, len)) {
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005089 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5090 "%s: failed to copy data to user buffer", __func__);
5091 ret = -EFAULT;
5092 goto exit;
5093 }
5094 }
5095 else if (strncmp(command, "SETSCANHOMEAWAYTIME", 19) == 0)
5096 {
5097 tANI_U8 *value = command;
5098 tANI_U16 homeAwayTime = CFG_ROAM_SCAN_HOME_AWAY_TIME_DEFAULT;
5099
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05305100 ret = hdd_drv_cmd_validate(command, 19);
5101 if (ret)
5102 goto exit;
5103
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005104 /* Move pointer to ahead of SETSCANHOMEAWAYTIME<delimiter> */
5105 /* input value is in units of msec */
5106 value = value + 20;
5107 /* Convert the value from ascii to integer */
5108 ret = kstrtou16(value, 10, &homeAwayTime);
5109 if (ret < 0)
5110 {
5111 /* If the input value is greater than max value of datatype, then also
5112 kstrtou8 fails */
5113 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5114 "%s: kstrtou8 failed range [%d - %d]", __func__,
5115 CFG_ROAM_SCAN_HOME_AWAY_TIME_MIN,
5116 CFG_ROAM_SCAN_HOME_AWAY_TIME_MAX);
5117 ret = -EINVAL;
5118 goto exit;
5119 }
5120
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005121 if ((homeAwayTime < CFG_ROAM_SCAN_HOME_AWAY_TIME_MIN) ||
5122 (homeAwayTime > CFG_ROAM_SCAN_HOME_AWAY_TIME_MAX))
5123 {
5124 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5125 "homeAwayTime value %d is out of range"
5126 " (Min: %d Max: %d)", homeAwayTime,
5127 CFG_ROAM_SCAN_HOME_AWAY_TIME_MIN,
5128 CFG_ROAM_SCAN_HOME_AWAY_TIME_MAX);
5129 ret = -EINVAL;
5130 goto exit;
5131 }
5132
5133 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
5134 "%s: Received Command to Set scan away time = %d", __func__, homeAwayTime);
Srinivas Girigowda6cf0b822013-06-27 14:00:20 -07005135 if (pHddCtx->cfg_ini->nRoamScanHomeAwayTime != homeAwayTime)
5136 {
5137 pHddCtx->cfg_ini->nRoamScanHomeAwayTime = homeAwayTime;
5138 sme_UpdateRoamScanHomeAwayTime((tHalHandle)(pHddCtx->hHal), homeAwayTime, eANI_BOOLEAN_TRUE);
5139 }
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005140 }
Mahesh A Saptasagarec7d1092015-04-02 13:41:34 +05305141 else if (strncmp(command, "GETSCANHOMEAWAYTIME", 19) == 0)
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005142 {
5143 tANI_U16 val = sme_getRoamScanHomeAwayTime((tHalHandle)(pHddCtx->hHal));
5144 char extra[32];
5145 tANI_U8 len = 0;
5146
Sameer Thalappilb0a30232013-09-27 15:37:48 -07005147 len = scnprintf(extra, sizeof(extra), "%s %d", command, val);
Ratnam Rachuri51a5ad12015-08-07 14:06:37 +05305148 len = VOS_MIN(priv_data.total_len, len + 1);
5149 if (copy_to_user(priv_data.buf, &extra, len)) {
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005150 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5151 "%s: failed to copy data to user buffer", __func__);
5152 ret = -EFAULT;
5153 goto exit;
5154 }
5155 }
5156 else if (strncmp(command, "REASSOC", 7) == 0)
5157 {
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05305158 ret = hdd_drv_cmd_validate(command, 7);
5159 if (ret)
5160 goto exit;
5161
5162 ret = hdd_parse_reassoc(pAdapter, command, priv_data.total_len);
Selvaraj, Sridhar5aff1ed2016-06-18 01:26:23 +05305163 if (!ret)
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005164 goto exit;
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005165 }
Srinivas Girigowdaad34ca92013-10-22 10:54:29 -07005166 else if (strncmp(command, "SETWESMODE", 10) == 0)
5167 {
5168 tANI_U8 *value = command;
5169 tANI_BOOLEAN wesMode = CFG_ENABLE_WES_MODE_NAME_DEFAULT;
5170
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05305171 ret = hdd_drv_cmd_validate(command, 10);
5172 if (ret)
5173 goto exit;
5174
Srinivas Girigowdaad34ca92013-10-22 10:54:29 -07005175 /* Move pointer to ahead of SETWESMODE<delimiter> */
5176 value = value + 11;
5177 /* Convert the value from ascii to integer */
5178 ret = kstrtou8(value, 10, &wesMode);
5179 if (ret < 0)
5180 {
5181 /* If the input value is greater than max value of datatype, then also
5182 kstrtou8 fails */
5183 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5184 "%s: kstrtou8 failed range [%d - %d]", __func__,
5185 CFG_ENABLE_WES_MODE_NAME_MIN,
5186 CFG_ENABLE_WES_MODE_NAME_MAX);
5187 ret = -EINVAL;
5188 goto exit;
5189 }
5190
5191 if ((wesMode < CFG_ENABLE_WES_MODE_NAME_MIN) ||
5192 (wesMode > CFG_ENABLE_WES_MODE_NAME_MAX))
5193 {
5194 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5195 "WES Mode value %d is out of range"
5196 " (Min: %d Max: %d)", wesMode,
5197 CFG_ENABLE_WES_MODE_NAME_MIN,
5198 CFG_ENABLE_WES_MODE_NAME_MAX);
5199 ret = -EINVAL;
5200 goto exit;
5201 }
5202 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
5203 "%s: Received Command to Set WES Mode rssi diff = %d", __func__, wesMode);
5204
5205 pHddCtx->cfg_ini->isWESModeEnabled = wesMode;
5206 sme_UpdateWESMode((tHalHandle)(pHddCtx->hHal), wesMode);
5207 }
Mahesh A Saptasagarec7d1092015-04-02 13:41:34 +05305208 else if (strncmp(command, "GETWESMODE", 10) == 0)
Srinivas Girigowdaad34ca92013-10-22 10:54:29 -07005209 {
5210 tANI_BOOLEAN wesMode = sme_GetWESMode((tHalHandle)(pHddCtx->hHal));
5211 char extra[32];
5212 tANI_U8 len = 0;
5213
Arif Hussain826d9412013-11-12 16:44:54 -08005214 len = scnprintf(extra, sizeof(extra), "%s %d", command, wesMode);
Ratnam Rachuri8fe90c62015-08-07 14:03:26 +05305215 len = VOS_MIN(priv_data.total_len, len + 1);
5216 if (copy_to_user(priv_data.buf, &extra, len)) {
Srinivas Girigowdaad34ca92013-10-22 10:54:29 -07005217 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5218 "%s: failed to copy data to user buffer", __func__);
5219 ret = -EFAULT;
5220 goto exit;
5221 }
5222 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005223#endif /* WLAN_FEATURE_VOWIFI_11R || FEATURE_WLAN_ESE || FEATURE_WLAN_LFR */
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07005224#ifdef FEATURE_WLAN_LFR
5225 else if (strncmp(command, "SETFASTROAM", 11) == 0)
5226 {
5227 tANI_U8 *value = command;
5228 tANI_U8 lfrMode = CFG_LFR_FEATURE_ENABLED_DEFAULT;
5229
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +05305230 if (pHddCtx->concurrency_mode == VOS_STA_MON) {
5231 hddLog(LOGE,
5232 FL("Roaming is always disabled in STA + MON concurrency"));
5233 ret = -EINVAL;
5234 goto exit;
5235 }
5236
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05305237 ret = hdd_drv_cmd_validate(command, 11);
5238 if (ret)
5239 goto exit;
5240
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07005241 /* Move pointer to ahead of SETFASTROAM<delimiter> */
5242 value = value + 12;
5243 /* Convert the value from ascii to integer */
5244 ret = kstrtou8(value, 10, &lfrMode);
5245 if (ret < 0)
5246 {
5247 /* If the input value is greater than max value of datatype, then also
5248 kstrtou8 fails */
5249 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5250 "%s: kstrtou8 failed range [%d - %d]", __func__,
5251 CFG_LFR_FEATURE_ENABLED_MIN,
5252 CFG_LFR_FEATURE_ENABLED_MAX);
5253 ret = -EINVAL;
5254 goto exit;
5255 }
5256
5257 if ((lfrMode < CFG_LFR_FEATURE_ENABLED_MIN) ||
5258 (lfrMode > CFG_LFR_FEATURE_ENABLED_MAX))
5259 {
5260 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5261 "lfr mode value %d is out of range"
5262 " (Min: %d Max: %d)", lfrMode,
5263 CFG_LFR_FEATURE_ENABLED_MIN,
5264 CFG_LFR_FEATURE_ENABLED_MAX);
5265 ret = -EINVAL;
5266 goto exit;
5267 }
5268
5269 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
5270 "%s: Received Command to change lfr mode = %d", __func__, lfrMode);
5271
5272 pHddCtx->cfg_ini->isFastRoamIniFeatureEnabled = lfrMode;
5273 sme_UpdateIsFastRoamIniFeatureEnabled((tHalHandle)(pHddCtx->hHal), lfrMode);
5274 }
5275#endif
5276#ifdef WLAN_FEATURE_VOWIFI_11R
5277 else if (strncmp(command, "SETFASTTRANSITION", 17) == 0)
5278 {
5279 tANI_U8 *value = command;
5280 tANI_U8 ft = CFG_FAST_TRANSITION_ENABLED_NAME_DEFAULT;
5281
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05305282 ret = hdd_drv_cmd_validate(command, 17);
5283 if (ret)
5284 goto exit;
5285
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07005286 /* Move pointer to ahead of SETFASTROAM<delimiter> */
5287 value = value + 18;
5288 /* Convert the value from ascii to integer */
5289 ret = kstrtou8(value, 10, &ft);
5290 if (ret < 0)
5291 {
5292 /* If the input value is greater than max value of datatype, then also
5293 kstrtou8 fails */
5294 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5295 "%s: kstrtou8 failed range [%d - %d]", __func__,
5296 CFG_FAST_TRANSITION_ENABLED_NAME_MIN,
5297 CFG_FAST_TRANSITION_ENABLED_NAME_MAX);
5298 ret = -EINVAL;
5299 goto exit;
5300 }
5301
5302 if ((ft < CFG_FAST_TRANSITION_ENABLED_NAME_MIN) ||
5303 (ft > CFG_FAST_TRANSITION_ENABLED_NAME_MAX))
5304 {
5305 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5306 "ft mode value %d is out of range"
5307 " (Min: %d Max: %d)", ft,
5308 CFG_FAST_TRANSITION_ENABLED_NAME_MIN,
5309 CFG_FAST_TRANSITION_ENABLED_NAME_MAX);
5310 ret = -EINVAL;
5311 goto exit;
5312 }
5313
5314 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
5315 "%s: Received Command to change ft mode = %d", __func__, ft);
5316
5317 pHddCtx->cfg_ini->isFastTransitionEnabled = ft;
5318 sme_UpdateFastTransitionEnabled((tHalHandle)(pHddCtx->hHal), ft);
5319 }
Padma, Santhosh Kumar778d8382015-03-04 17:41:22 +05305320 else if (strncmp(command, "SETDFSSCANMODE", 14) == 0)
5321 {
5322 tANI_U8 *value = command;
5323 tANI_U8 dfsScanMode = DFS_CHNL_SCAN_ENABLED_NORMAL;
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05305324
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05305325 ret = hdd_drv_cmd_validate(command, 14);
5326 if (ret)
5327 goto exit;
5328
Padma, Santhosh Kumar778d8382015-03-04 17:41:22 +05305329 /* Move pointer to ahead of SETDFSSCANMODE<delimiter> */
5330 value = value + 15;
5331 /* Convert the value from ascii to integer */
5332 ret = kstrtou8(value, 10, &dfsScanMode);
5333 if (ret < 0)
5334 {
5335 /* If the input value is greater than max value of
5336 datatype, then also kstrtou8 fails
5337 */
5338 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5339 "%s: kstrtou8 failed range [%d - %d]", __func__,
5340 CFG_ENABLE_DFS_CHNL_SCAN_MIN,
5341 CFG_ENABLE_DFS_CHNL_SCAN_MAX);
5342 ret = -EINVAL;
5343 goto exit;
5344 }
5345
5346 if ((dfsScanMode < CFG_ENABLE_DFS_CHNL_SCAN_MIN) ||
5347 (dfsScanMode > CFG_ENABLE_DFS_CHNL_SCAN_MAX))
5348 {
5349 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5350 "dfsScanMode value %d is out of range"
5351 " (Min: %d Max: %d)", dfsScanMode,
5352 CFG_ENABLE_DFS_CHNL_SCAN_MIN,
5353 CFG_ENABLE_DFS_CHNL_SCAN_MAX);
5354 ret = -EINVAL;
5355 goto exit;
5356 }
5357 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
5358 "%s: Received Command to Set DFS Scan Mode = %d",
5359 __func__, dfsScanMode);
5360
5361 ret = wlan_hdd_handle_dfs_chan_scan(pHddCtx, dfsScanMode);
5362 }
5363 else if (strncmp(command, "GETDFSSCANMODE", 14) == 0)
5364 {
5365 tANI_U8 dfsScanMode = sme_GetDFSScanMode(pHddCtx->hHal);
5366 char extra[32];
5367 tANI_U8 len = 0;
5368
5369 len = scnprintf(extra, sizeof(extra), "%s %d", command, dfsScanMode);
Ratheesh S P767224e2015-07-16 15:35:51 +05305370 len = VOS_MIN(priv_data.total_len, len + 1);
5371 if (copy_to_user(priv_data.buf, &extra, len))
Padma, Santhosh Kumar778d8382015-03-04 17:41:22 +05305372 {
5373 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5374 "%s: failed to copy data to user buffer", __func__);
5375 ret = -EFAULT;
5376 goto exit;
5377 }
5378 }
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05305379 else if (strncmp(command, "FASTREASSOC", 11) == 0)
5380 {
Selvaraj, Sridhar3714c4d2016-06-22 15:19:12 +05305381 ret = wlan_hdd_handle_fastreassoc(pAdapter, command);
5382 if (!ret)
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05305383 goto exit;
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05305384 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07005385#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005386#ifdef FEATURE_WLAN_ESE
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07005387 else if (strncmp(command, "SETCCXMODE", 10) == 0)
5388 {
5389 tANI_U8 *value = command;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005390 tANI_U8 eseMode = CFG_ESE_FEATURE_ENABLED_DEFAULT;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07005391
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05305392 ret = hdd_drv_cmd_validate(command, 10);
5393 if (ret)
5394 goto exit;
5395
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005396 /* Check if the features OKC/ESE/11R are supported simultaneously,
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07005397 then this operation is not permitted (return FAILURE) */
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005398 if (sme_getIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal)) &&
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07005399 hdd_is_okc_mode_enabled(pHddCtx) &&
5400 sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal)))
5401 {
5402 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005403 "%s: OKC/ESE/11R are supported simultaneously"
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07005404 " hence this operation is not permitted!", __func__);
5405 ret = -EPERM;
5406 goto exit;
5407 }
5408
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07005409 /* Move pointer to ahead of SETCCXMODE<delimiter> */
5410 value = value + 11;
5411 /* Convert the value from ascii to integer */
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005412 ret = kstrtou8(value, 10, &eseMode);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07005413 if (ret < 0)
5414 {
5415 /* If the input value is greater than max value of datatype, then also
5416 kstrtou8 fails */
5417 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5418 "%s: kstrtou8 failed range [%d - %d]", __func__,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005419 CFG_ESE_FEATURE_ENABLED_MIN,
5420 CFG_ESE_FEATURE_ENABLED_MAX);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07005421 ret = -EINVAL;
5422 goto exit;
5423 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005424 if ((eseMode < CFG_ESE_FEATURE_ENABLED_MIN) ||
5425 (eseMode > CFG_ESE_FEATURE_ENABLED_MAX))
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07005426 {
5427 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005428 "Ese mode value %d is out of range"
5429 " (Min: %d Max: %d)", eseMode,
5430 CFG_ESE_FEATURE_ENABLED_MIN,
5431 CFG_ESE_FEATURE_ENABLED_MAX);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07005432 ret = -EINVAL;
5433 goto exit;
5434 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07005435 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005436 "%s: Received Command to change ese mode = %d", __func__, eseMode);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07005437
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005438 pHddCtx->cfg_ini->isEseIniFeatureEnabled = eseMode;
5439 sme_UpdateIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal), eseMode);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07005440 }
5441#endif
Srinivas Girigowda100eb322013-03-15 16:48:20 -07005442 else if (strncmp(command, "SETROAMSCANCONTROL", 18) == 0)
5443 {
5444 tANI_U8 *value = command;
5445 tANI_BOOLEAN roamScanControl = 0;
5446
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05305447 ret = hdd_drv_cmd_validate(command, 18);
5448 if (ret)
5449 goto exit;
5450
Srinivas Girigowda100eb322013-03-15 16:48:20 -07005451 /* Move pointer to ahead of SETROAMSCANCONTROL<delimiter> */
5452 value = value + 19;
5453 /* Convert the value from ascii to integer */
5454 ret = kstrtou8(value, 10, &roamScanControl);
5455 if (ret < 0)
5456 {
5457 /* If the input value is greater than max value of datatype, then also
5458 kstrtou8 fails */
5459 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5460 "%s: kstrtou8 failed ", __func__);
5461 ret = -EINVAL;
5462 goto exit;
5463 }
5464
5465 if (0 != roamScanControl)
5466 {
5467 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5468 "roam scan control invalid value = %d",
5469 roamScanControl);
5470 ret = -EINVAL;
5471 goto exit;
5472 }
5473 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
5474 "%s: Received Command to Set roam scan control = %d", __func__, roamScanControl);
5475
5476 sme_SetRoamScanControl((tHalHandle)(pHddCtx->hHal), roamScanControl);
5477 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07005478#ifdef FEATURE_WLAN_OKC
5479 else if (strncmp(command, "SETOKCMODE", 10) == 0)
5480 {
5481 tANI_U8 *value = command;
5482 tANI_U8 okcMode = CFG_OKC_FEATURE_ENABLED_DEFAULT;
5483
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05305484 ret = hdd_drv_cmd_validate(command, 10);
5485 if (ret)
5486 goto exit;
5487
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005488 /* Check if the features OKC/ESE/11R are supported simultaneously,
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07005489 then this operation is not permitted (return FAILURE) */
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005490 if (sme_getIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal)) &&
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07005491 hdd_is_okc_mode_enabled(pHddCtx) &&
5492 sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal)))
5493 {
5494 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005495 "%s: OKC/ESE/11R are supported simultaneously"
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07005496 " hence this operation is not permitted!", __func__);
5497 ret = -EPERM;
5498 goto exit;
5499 }
5500
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07005501 /* Move pointer to ahead of SETOKCMODE<delimiter> */
5502 value = value + 11;
5503 /* Convert the value from ascii to integer */
5504 ret = kstrtou8(value, 10, &okcMode);
5505 if (ret < 0)
5506 {
5507 /* If the input value is greater than max value of datatype, then also
5508 kstrtou8 fails */
5509 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5510 "%s: kstrtou8 failed range [%d - %d]", __func__,
5511 CFG_OKC_FEATURE_ENABLED_MIN,
5512 CFG_OKC_FEATURE_ENABLED_MAX);
5513 ret = -EINVAL;
5514 goto exit;
5515 }
5516
5517 if ((okcMode < CFG_OKC_FEATURE_ENABLED_MIN) ||
5518 (okcMode > CFG_OKC_FEATURE_ENABLED_MAX))
5519 {
5520 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5521 "Okc mode value %d is out of range"
5522 " (Min: %d Max: %d)", okcMode,
5523 CFG_OKC_FEATURE_ENABLED_MIN,
5524 CFG_OKC_FEATURE_ENABLED_MAX);
5525 ret = -EINVAL;
5526 goto exit;
5527 }
5528
5529 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
5530 "%s: Received Command to change okc mode = %d", __func__, okcMode);
5531
5532 pHddCtx->cfg_ini->isOkcIniFeatureEnabled = okcMode;
5533 }
Srinivas Girigowdaad34ca92013-10-22 10:54:29 -07005534#endif /* FEATURE_WLAN_OKC */
Mahesh A Saptasagarec7d1092015-04-02 13:41:34 +05305535 else if (strncmp(command, "GETROAMSCANCONTROL", 18) == 0)
Srinivas Girigowda100eb322013-03-15 16:48:20 -07005536 {
5537 tANI_BOOLEAN roamScanControl = sme_GetRoamScanControl((tHalHandle)(pHddCtx->hHal));
5538 char extra[32];
5539 tANI_U8 len = 0;
5540
Sameer Thalappilb0a30232013-09-27 15:37:48 -07005541 len = scnprintf(extra, sizeof(extra), "%s %d",
5542 command, roamScanControl);
Ratnam Rachuri083ada82015-08-07 14:01:05 +05305543 len = VOS_MIN(priv_data.total_len, len + 1);
5544 if (copy_to_user(priv_data.buf, &extra, len)) {
Srinivas Girigowda100eb322013-03-15 16:48:20 -07005545 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5546 "%s: failed to copy data to user buffer", __func__);
5547 ret = -EFAULT;
5548 goto exit;
5549 }
5550 }
Gopichand Nakkala227c7f32013-06-26 22:44:57 +05305551#ifdef WLAN_FEATURE_PACKET_FILTERING
5552 else if (strncmp(command, "ENABLE_PKTFILTER_IPV6", 21) == 0)
5553 {
5554 tANI_U8 filterType = 0;
5555 tANI_U8 *value = command;
5556
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05305557 ret = hdd_drv_cmd_validate(command, 21);
5558 if (ret)
5559 goto exit;
5560
Gopichand Nakkala227c7f32013-06-26 22:44:57 +05305561 /* Move pointer to ahead of ENABLE_PKTFILTER_IPV6<delimiter> */
5562 value = value + 22;
5563
5564 /* Convert the value from ascii to integer */
5565 ret = kstrtou8(value, 10, &filterType);
5566 if (ret < 0)
5567 {
5568 /* If the input value is greater than max value of datatype,
5569 * then also kstrtou8 fails
5570 */
5571 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5572 "%s: kstrtou8 failed range ", __func__);
5573 ret = -EINVAL;
5574 goto exit;
5575 }
5576
5577 if (filterType != 0 && filterType != 1)
5578 {
5579 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5580 "%s: Accepted Values are 0 and 1 ", __func__);
5581 ret = -EINVAL;
5582 goto exit;
5583 }
5584 wlan_hdd_setIPv6Filter(WLAN_HDD_GET_CTX(pAdapter), filterType,
5585 pAdapter->sessionId);
5586 }
5587#endif
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05305588 else if (strncmp(command, "BTCOEXMODE", 10) == 0 )
5589 {
Kiet Lamad161252014-07-22 11:23:32 -07005590 char *dhcpPhase;
Satyanarayana Dash1faea4f2014-09-22 16:21:04 +05305591 int ret;
5592
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05305593 ret = hdd_drv_cmd_validate(command, 10);
5594 if (ret)
5595 goto exit;
5596
Kiet Lamad161252014-07-22 11:23:32 -07005597 dhcpPhase = command + 11;
5598 if ('1' == *dhcpPhase)
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05305599 {
Deepthi Gowribfd17132014-11-14 17:59:04 +05305600 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Kiet Lamad161252014-07-22 11:23:32 -07005601 FL("send DHCP START indication"));
c_hpothu9b781ba2013-12-30 20:57:45 +05305602
5603 pHddCtx->btCoexModeSet = TRUE;
Kiet Lamad161252014-07-22 11:23:32 -07005604
Satyanarayana Dash1faea4f2014-09-22 16:21:04 +05305605 ret = wlan_hdd_scan_abort(pAdapter);
5606 if (ret < 0)
5607 {
5608 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5609 FL("failed to abort existing scan %d"), ret);
5610 }
5611
Kiet Lamad161252014-07-22 11:23:32 -07005612 sme_DHCPStartInd(pHddCtx->hHal, pAdapter->device_mode,
5613 pAdapter->sessionId);
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05305614 }
Kiet Lamad161252014-07-22 11:23:32 -07005615 else if ('2' == *dhcpPhase)
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05305616 {
Deepthi Gowribfd17132014-11-14 17:59:04 +05305617 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Kiet Lamad161252014-07-22 11:23:32 -07005618 FL("send DHCP STOP indication"));
c_hpothu9b781ba2013-12-30 20:57:45 +05305619
5620 pHddCtx->btCoexModeSet = FALSE;
Kiet Lamad161252014-07-22 11:23:32 -07005621
5622 sme_DHCPStopInd(pHddCtx->hHal, pAdapter->device_mode,
5623 pAdapter->sessionId);
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05305624 }
5625 }
Jeff Johnsonf54df2c2013-07-24 11:43:39 -07005626 else if (strncmp(command, "SCAN-ACTIVE", 11) == 0)
5627 {
Abhishek Singh58749d62016-02-03 15:27:20 +05305628 hddLog(LOG1,
5629 FL("making default scan to ACTIVE"));
c_hpothudbefd3e2014-04-28 15:59:47 +05305630 pHddCtx->scan_info.scan_mode = eSIR_ACTIVE_SCAN;
Jeff Johnsonf54df2c2013-07-24 11:43:39 -07005631 }
5632 else if (strncmp(command, "SCAN-PASSIVE", 12) == 0)
5633 {
Abhishek Singh58749d62016-02-03 15:27:20 +05305634 hddLog(LOG1,
5635 FL("making default scan to PASSIVE"));
c_hpothudbefd3e2014-04-28 15:59:47 +05305636 pHddCtx->scan_info.scan_mode = eSIR_PASSIVE_SCAN;
Jeff Johnsonf54df2c2013-07-24 11:43:39 -07005637 }
Hanumantha Reddy Pothula212243c2013-08-01 17:28:31 +05305638 else if (strncmp(command, "GETDWELLTIME", 12) == 0)
5639 {
5640 hdd_config_t *pCfg = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
5641 char extra[32];
5642 tANI_U8 len = 0;
5643
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05305644 memset(extra, 0, sizeof(extra));
5645 ret = hdd_get_dwell_time(pCfg, command, extra, sizeof(extra), &len);
Ratnam Rachuri12d5d462015-08-07 14:10:23 +05305646 len = VOS_MIN(priv_data.total_len, len + 1);
5647 if (ret != 0 || copy_to_user(priv_data.buf, &extra, len)) {
Hanumantha Reddy Pothula212243c2013-08-01 17:28:31 +05305648 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5649 "%s: failed to copy data to user buffer", __func__);
5650 ret = -EFAULT;
5651 goto exit;
5652 }
5653 ret = len;
5654 }
5655 else if (strncmp(command, "SETDWELLTIME", 12) == 0)
5656 {
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05305657 ret = hdd_set_dwell_time(pAdapter, command);
Hanumantha Reddy Pothula212243c2013-08-01 17:28:31 +05305658 }
Dundi Ravitejaae5adf42018-04-23 20:44:47 +05305659 else if (strncmp(command, "BTCGETDWELLTIME", 15) == 0)
5660 {
5661 hdd_config_t *pCfg = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
5662 char extra[32];
5663 tANI_U8 len = 0;
5664
5665 if (hdd_drv_cmd_validate(command, 15)) {
5666 hddLog(LOGE, FL("Invalid driver command"));
5667 return -EINVAL;
5668 }
5669
5670 memset(extra, 0, sizeof(extra));
5671 ret = hdd_btc_get_dwell_time(pCfg, command, extra,
5672 sizeof(extra), &len);
5673 len = VOS_MIN(priv_data.total_len, len + 1);
5674 if (ret != 0 || copy_to_user(priv_data.buf, &extra, len)) {
5675 hddLog(LOGE, FL("Failed to copy data to user buffer"));
5676 ret = -EFAULT;
5677 goto exit;
5678 }
5679 ret = len;
5680 }
5681 else if (strncmp(command, "BTCSETDWELLTIME", 15) == 0)
5682 {
5683 if (hdd_drv_cmd_validate(command, 15)) {
5684 hddLog(LOGE, FL("Invalid driver command"));
5685 return -EINVAL;
5686 }
5687 ret = hdd_btc_set_dwell_time(pAdapter, command);
5688 }
5689#ifdef WLAN_AP_STA_CONCURRENCY
5690 else if (strncmp(command, "CONCGETDWELLTIME", 16) == 0)
5691 {
5692 hdd_config_t *pCfg = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
5693 char extra[32];
5694 tANI_U8 len = 0;
5695
5696 if (hdd_drv_cmd_validate(command, 16)) {
5697 hddLog(LOGE, FL("Invalid driver command"));
5698 return -EINVAL;
5699 }
5700
5701 memset(extra, 0, sizeof(extra));
5702 ret = hdd_conc_get_dwell_time(pCfg, command, extra,
5703 sizeof(extra), &len);
5704 len = VOS_MIN(priv_data.total_len, len + 1);
5705 if (ret != 0 || copy_to_user(priv_data.buf, &extra, len)) {
5706 hddLog(LOGE, FL("Failed to copy data to user buffer"));
5707 ret = -EFAULT;
5708 goto exit;
5709 }
5710 ret = len;
5711 }
5712 else if (strncmp(command, "CONCSETDWELLTIME", 16) == 0)
5713 {
5714 if (hdd_drv_cmd_validate(command, 16)) {
5715 hddLog(LOGE, FL("Invalid driver command"));
5716 return -EINVAL;
5717 }
5718 ret = hdd_conc_set_dwell_time(pAdapter, command);
5719 }
5720#endif
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07005721 else if ( strncasecmp(command, "MIRACAST", 8) == 0 )
5722 {
5723 tANI_U8 filterType = 0;
5724 tANI_U8 *value;
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05305725
5726 ret = hdd_drv_cmd_validate(command, 8);
5727 if (ret)
5728 goto exit;
5729
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07005730 value = command + 9;
5731
5732 /* Convert the value from ascii to integer */
5733 ret = kstrtou8(value, 10, &filterType);
5734 if (ret < 0)
5735 {
5736 /* If the input value is greater than max value of datatype,
5737 * then also kstrtou8 fails
5738 */
5739 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5740 "%s: kstrtou8 failed range ", __func__);
5741 ret = -EINVAL;
5742 goto exit;
5743 }
5744 if ((filterType < WLAN_HDD_DRIVER_MIRACAST_CFG_MIN_VAL ) ||
5745 (filterType > WLAN_HDD_DRIVER_MIRACAST_CFG_MAX_VAL))
5746 {
5747 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5748 "%s: Accepted Values are 0 to 2. 0-Disabled, 1-Source,"
5749 " 2-Sink ", __func__);
5750 ret = -EINVAL;
5751 goto exit;
5752 }
5753 //Filtertype value should be either 0-Disabled, 1-Source, 2-sink
5754 pHddCtx->drvr_miracast = filterType;
Kaushik, Sushant96122442014-10-21 16:40:18 +05305755 pScanInfo = &pHddCtx->scan_info;
5756 if (filterType && pScanInfo != NULL &&
5757 pHddCtx->scan_info.mScanPending)
5758 {
5759 /*Miracast Session started. Abort Scan */
5760 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
5761 "%s, Aborting Scan For Miracast",__func__);
5762 hdd_abort_mac_scan(pHddCtx, pScanInfo->sessionId,
5763 eCSR_SCAN_ABORT_DEFAULT);
5764 }
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07005765 hdd_tx_rx_pkt_cnt_stat_timer_handler(pHddCtx);
Ganesh Kondabattini8f6e3b32014-08-25 16:07:54 +05305766 sme_SetMiracastMode(pHddCtx->hHal, pHddCtx->drvr_miracast);
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07005767 }
Leo Chang614d2072013-08-22 14:59:44 -07005768 else if (strncmp(command, "SETMCRATE", 9) == 0)
5769 {
Leo Chang614d2072013-08-22 14:59:44 -07005770 tANI_U8 *value = command;
5771 int targetRate;
Leo Chang1f98cbd2013-10-17 15:03:52 -07005772 tSirRateUpdateInd *rateUpdate;
5773 eHalStatus status;
Leo Chang614d2072013-08-22 14:59:44 -07005774
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05305775 ret = hdd_drv_cmd_validate(command, 9);
5776 if (ret)
5777 goto exit;
5778
Leo Chang614d2072013-08-22 14:59:44 -07005779 /* Only valid for SAP mode */
5780 if (WLAN_HDD_SOFTAP != pAdapter->device_mode)
5781 {
5782 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5783 "%s: SAP mode is not running", __func__);
5784 ret = -EFAULT;
5785 goto exit;
5786 }
5787
5788 /* Move pointer to ahead of SETMCRATE<delimiter> */
5789 /* input value is in units of hundred kbps */
5790 value = value + 10;
5791 /* Convert the value from ascii to integer, decimal base */
5792 ret = kstrtouint(value, 10, &targetRate);
5793
Leo Chang1f98cbd2013-10-17 15:03:52 -07005794 rateUpdate = (tSirRateUpdateInd *)vos_mem_malloc(sizeof(tSirRateUpdateInd));
5795 if (NULL == rateUpdate)
Leo Chang614d2072013-08-22 14:59:44 -07005796 {
Leo Chang1f98cbd2013-10-17 15:03:52 -07005797 hddLog(VOS_TRACE_LEVEL_ERROR,
5798 "%s: SETMCRATE indication alloc fail", __func__);
5799 ret = -EFAULT;
5800 goto exit;
5801 }
5802 vos_mem_zero(rateUpdate, sizeof(tSirRateUpdateInd ));
5803
5804 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
5805 "MC Target rate %d", targetRate);
5806 /* Ignore unicast */
5807 rateUpdate->ucastDataRate = -1;
5808 rateUpdate->mcastDataRate24GHz = targetRate;
5809 rateUpdate->mcastDataRate5GHz = targetRate;
5810 rateUpdate->mcastDataRate24GHzTxFlag = 0;
5811 rateUpdate->mcastDataRate5GHzTxFlag = 0;
5812 status = sme_SendRateUpdateInd(pHddCtx->hHal, rateUpdate);
5813 if (eHAL_STATUS_SUCCESS != status)
5814 {
5815 hddLog(VOS_TRACE_LEVEL_ERROR,
5816 "%s: SET_MC_RATE failed", __func__);
5817 vos_mem_free(rateUpdate);
5818 ret = -EFAULT;
5819 goto exit;
Leo Chang614d2072013-08-22 14:59:44 -07005820 }
5821 }
jge35567202017-06-21 16:39:38 +08005822 else if (strncmp(command, "MAXTXPOWER", 10) == 0)
5823 {
5824 int status;
5825 int txPower;
5826 eHalStatus smeStatus;
5827 tANI_U8 *value = command;
5828 tSirMacAddr bssid = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
5829 tSirMacAddr selfMac = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
5830
5831 status = hdd_parse_setmaxtxpower_command(value, &txPower);
5832 if (status)
5833 {
5834 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5835 "Invalid MAXTXPOWER command ");
5836 ret = -EINVAL;
5837 goto exit;
5838 }
5839
5840 hddLog(VOS_TRACE_LEVEL_INFO, "max tx power %d selfMac: "
5841 MAC_ADDRESS_STR " bssId: " MAC_ADDRESS_STR " ",
5842 txPower, MAC_ADDR_ARRAY(selfMac),
5843 MAC_ADDR_ARRAY(bssid));
5844 smeStatus = sme_SetMaxTxPower((tHalHandle)(pHddCtx->hHal),
5845 bssid, selfMac, txPower) ;
5846 if( smeStatus != eHAL_STATUS_SUCCESS )
5847 {
5848 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:Set max tx power failed",
5849 __func__);
5850 ret = -EINVAL;
5851 goto exit;
5852 }
5853
5854 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Set max tx power success",
5855 __func__);
5856 }
Rajeev79dbe4c2013-10-05 11:03:42 +05305857#ifdef FEATURE_WLAN_BATCH_SCAN
Rajeev Kumar8b373292014-01-08 20:36:55 -08005858 else if (strncmp(command, "WLS_BATCHING", 12) == 0)
Rajeev79dbe4c2013-10-05 11:03:42 +05305859 {
Rajeev Kumar8b373292014-01-08 20:36:55 -08005860 ret = hdd_handle_batch_scan_ioctl(pAdapter, &priv_data, command);
Rajeev79dbe4c2013-10-05 11:03:42 +05305861 }
5862#endif
Abhishek Singh00b71972016-01-07 10:51:04 +05305863#ifdef WLAN_FEATURE_RMC
5864 else if ((strncasecmp(command, "SETIBSSBEACONOUIDATA", 20) == 0) &&
5865 (WLAN_HDD_IBSS == pAdapter->device_mode))
5866 {
5867 int i = 0;
5868 tANI_U8 *ibss_ie;
5869 tANI_U32 command_len;
5870 tANI_U8 *value = command;
5871 tHalHandle hHal = pHddCtx->hHal;
5872 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
5873 tANI_U32 ibss_ie_length;
5874 tANI_U32 len, present;
5875 tANI_U8 *addIE;
5876 tANI_U8 *addIEData;
5877
5878 hddLog(LOG1,
5879 FL(" received command %s"),((char *) value));
5880 /* validate argument of command */
5881 if (strlen(value) <= 21)
5882 {
5883 hddLog(LOGE,
5884 FL("No arguements in command length %zu"), strlen(value));
5885 ret = -EFAULT;
5886 goto exit;
5887 }
5888
5889 /* moving to arguments of commands */
5890 value = value + 21;
5891 command_len = strlen(value);
5892
5893 /* oui_data can't be less than 3 bytes */
5894 if (command_len <= (2 * WLAN_HDD_IBSS_MIN_OUI_DATA_LENGTH))
5895 {
5896 hddLog(LOGE,
5897 FL("Invalid SETIBSSBEACONOUIDATA command length %d"),
5898 command_len);
5899 ret = -EFAULT;
5900 goto exit;
5901 }
5902 ibss_ie = vos_mem_malloc(command_len);
5903 if (!ibss_ie) {
5904 hddLog(LOGE,
5905 FL("Could not allocate memory for command length %d"),
5906 command_len);
5907 ret = -ENOMEM;
5908 goto exit;
5909 }
5910 vos_mem_zero(ibss_ie, command_len);
5911
5912 ibss_ie_length = hdd_parse_set_ibss_oui_data_command(value, ibss_ie,
5913 command_len);
5914 if (ibss_ie_length < (2 * WLAN_HDD_IBSS_MIN_OUI_DATA_LENGTH)) {
5915 hddLog(LOGE, FL("Could not parse command %s return length %d"),
5916 value, ibss_ie_length);
5917 ret = -EFAULT;
5918 vos_mem_free(ibss_ie);
5919 goto exit;
5920 }
5921
5922 hddLog(LOG1, FL("ibss_ie length %d ibss_ie:"), ibss_ie_length);
5923 while (i < ibss_ie_length)
5924 hddLog(LOG1, FL("0x%x"), ibss_ie[i++]);
5925
5926 /* Populate Vendor IE in Beacon */
5927 if ((ccmCfgGetInt(hHal,
5928 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG,
5929 &present)) != eHAL_STATUS_SUCCESS)
5930 {
5931 hddLog(LOGE,
5932 FL("unable to ftch WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG"));
5933 ret = -EFAULT;
5934 vos_mem_free(ibss_ie);
5935 goto exit;
5936 }
5937
5938 addIE = vos_mem_malloc(WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA_LEN);
5939 if (!addIE) {
5940 hddLog(LOGE,
5941 FL("Could not allocate memory for command length %d"),
5942 command_len);
5943 vos_mem_free(ibss_ie);
5944 ret = -ENOMEM;
5945 goto exit;
5946 }
5947 vos_mem_zero(addIE, WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA_LEN);
5948
5949 if (present)
5950 {
5951 if ((wlan_cfgGetStrLen(pMac,
5952 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, &len)) != eSIR_SUCCESS)
5953 {
5954 hddLog(LOGE,
5955 FL("unable to fetch WNI_CFG_PROBE_RSP_BCN_ADDNIE_LEN"));
5956 ret = -EFAULT;
5957 vos_mem_free(ibss_ie);
5958 vos_mem_free(addIE);
5959 goto exit;
5960 }
5961
5962 if (len <= WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA_LEN && len &&
5963 ((len + ibss_ie_length) <=
5964 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA_LEN))
5965 {
5966 if ((ccmCfgGetStr(hHal,
5967 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, addIE, &len))
5968 != eHAL_STATUS_SUCCESS)
5969 {
5970 hddLog(LOGE,
5971 FL("unable to fetch WNI_PROBE_RSP_BCN_ADDNIE_DATA"));
5972 ret = -EFAULT;
5973 vos_mem_free(ibss_ie);
5974 vos_mem_free(addIE);
5975 goto exit;
5976 }
5977 else
5978 {
5979 /* Curruntly only WPA IE is added before Vendor IE
5980 * so we can blindly place the Vendor IE after WPA
5981 * IE. If no WPA IE found replace all with Vendor IE.
5982 */
5983 len = hdd_find_ibss_wpa_ie_pos(addIE, len);
5984 }
5985 }
5986 else
5987 {
5988 hddLog(LOGE,
5989 FL("IE len exceed limit len %d,ibss_ie_length %d "),
5990 len, ibss_ie_length);
5991 ret = -EFAULT;
5992 vos_mem_free(addIE);
5993 vos_mem_free(ibss_ie);
5994 goto exit;
5995 }
5996 }
5997 else {
5998 len = 0;
5999 }
6000
6001 vos_mem_copy (addIE + len , ibss_ie, ibss_ie_length);
6002 len += ibss_ie_length;
6003
6004 if (ccmCfgSetStr(hHal,
6005 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, addIE, len, NULL,
6006 eANI_BOOLEAN_FALSE) != eHAL_STATUS_SUCCESS)
6007 {
6008 hddLog(LOGE,
6009 FL("unable to set WNI_CFG_PRBE_RSP_BCN_ADDNIE_DATA"));
6010 ret = -EFAULT;
6011 vos_mem_free(ibss_ie);
6012 vos_mem_free(addIE);
6013 goto exit;
6014 }
6015 vos_mem_free(addIE);
6016 if (ccmCfgSetInt(hHal,
6017 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 1,NULL,
6018 eANI_BOOLEAN_FALSE) != eHAL_STATUS_SUCCESS)
6019 {
6020 hddLog(LOGE,
6021 FL("unble to set WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG"));
6022 ret = -EFAULT;
6023 vos_mem_free(ibss_ie);
6024 goto exit;
6025 }
6026
6027 /* Populate Vendor IE in probe resp */
6028 if ((ccmCfgGetInt(hHal,
6029 WNI_CFG_PROBE_RSP_ADDNIE_FLAG,
6030 &present)) != eHAL_STATUS_SUCCESS)
6031 {
6032 hddLog(LOGE,
6033 FL("unable to fetch WNI_CFG_PROBE_RSP_ADDNIE_FLAG"));
6034 ret = -EFAULT;
6035 vos_mem_free(ibss_ie);
6036 goto exit;
6037 }
6038
6039 addIEData = vos_mem_malloc(WNI_CFG_PROBE_RSP_ADDNIE_DATA1_LEN);
6040 if (!addIEData) {
6041 hddLog(LOGE,
6042 FL("Could not allocate memory for command length %d"),
6043 command_len);
6044 vos_mem_free(ibss_ie);
6045 ret = -ENOMEM;
6046 goto exit;
6047 }
6048 vos_mem_zero(addIEData, WNI_CFG_PROBE_RSP_ADDNIE_DATA1_LEN);
6049
6050 if (present) {
6051 if (eSIR_SUCCESS != wlan_cfgGetStrLen(pMac,
6052 WNI_CFG_PROBE_RSP_ADDNIE_DATA1, &len)) {
6053 hddLog(LOGE,
6054 FL("unable to fetch WNI_CFG_PROBE_RSP_ADDNIE_DATA1"));
6055 ret = -EFAULT;
6056 vos_mem_free(ibss_ie);
6057 vos_mem_free(addIEData);
6058 goto exit;
6059 }
6060 if (len < WNI_CFG_PROBE_RSP_ADDNIE_DATA1_LEN && len &&
6061 (ibss_ie_length + len) <=
6062 WNI_CFG_PROBE_RSP_ADDNIE_DATA1_LEN) {
6063
6064 if ((ccmCfgGetStr(hHal,
6065 WNI_CFG_PROBE_RSP_ADDNIE_DATA1, addIEData, &len))
6066 != eHAL_STATUS_SUCCESS) {
6067 hddLog(LOGE,
6068 FL("unable fetch WNI_CFG_PROBE_RSP_ADDNIE_DATA1"));
6069 ret = -EFAULT;
6070 vos_mem_free(ibss_ie);
6071 vos_mem_free(addIEData);
6072 goto exit;
6073 }
6074 else {
6075 /* Curruntly only WPA IE is added before Vendor IE
6076 * so we can blindly place the Vendor IE after WPA
6077 * IE. If no WPA IE found replace all with Vendor IE.
6078 */
6079 len = hdd_find_ibss_wpa_ie_pos(addIEData, len);
6080 }
6081 }
6082 else
6083 {
6084 hddLog(LOGE,
6085 FL("IE len exceed limit len %d,ibss_ie_length %d "),
6086 len, ibss_ie_length);
6087 ret = -EFAULT;
6088 vos_mem_free(addIEData);
6089 vos_mem_free(ibss_ie);
6090 goto exit;
6091 }
6092 } /* probe rsp ADD IE present */
6093 else {
6094 /* probe rsp add IE is not present */
6095 len = 0;
6096 }
6097
6098 vos_mem_copy(addIEData +len , ibss_ie, ibss_ie_length);
6099 len += ibss_ie_length;
6100
6101 vos_mem_free(ibss_ie);
6102
6103 if (ccmCfgSetStr(hHal,
6104 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,
6105 (tANI_U8*)(addIEData),
6106 len, NULL,
6107 eANI_BOOLEAN_FALSE)
6108 == eHAL_STATUS_FAILURE) {
6109 hddLog(LOGE,
6110 FL("unable to copy to WNI_CFG_PROBE_RSP_ADDNIE_DATA1"));
6111 ret = -EFAULT;
6112 vos_mem_free(addIEData);
6113 goto exit;
6114 }
6115 vos_mem_free(addIEData);
6116 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
6117 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 1,NULL,
6118 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
6119 {
6120 hddLog(LOGE,
6121 FL("unable to copy WNI_CFG_PROBE_RSP_ADDNIE_FLAG"));
6122 ret = -EFAULT;
6123 goto exit;
6124 }
6125 }
6126 else if (strncasecmp(command, "SETRMCENABLE", 12) == 0)
6127 {
6128 tANI_U8 *value = command;
6129 tANI_U8 ucRmcEnable = 0;
6130 int status;
6131
6132 if ((WLAN_HDD_IBSS != pAdapter->device_mode) &&
6133 (WLAN_HDD_SOFTAP != pAdapter->device_mode))
6134 {
6135 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6136 "Received SETRMCENABLE command in invalid mode %d "
6137 "SETRMCENABLE command is only allowed in IBSS or SOFTAP mode",
6138 pAdapter->device_mode);
6139 ret = -EINVAL;
6140 goto exit;
6141 }
6142
6143 status = hdd_parse_setrmcenable_command(value, &ucRmcEnable);
6144 if (status)
6145 {
6146 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6147 "Invalid SETRMCENABLE command ");
6148 ret = -EINVAL;
6149 goto exit;
6150 }
6151
6152 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6153 "%s: ucRmcEnable %d ", __func__, ucRmcEnable);
6154
6155 if (TRUE == ucRmcEnable)
6156 {
6157 status = sme_EnableRMC( (tHalHandle)(pHddCtx->hHal),
6158 pAdapter->sessionId );
6159 }
6160 else if(FALSE == ucRmcEnable)
6161 {
6162 status = sme_DisableRMC( (tHalHandle)(pHddCtx->hHal),
6163 pAdapter->sessionId );
6164 }
6165 else
6166 {
6167 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6168 "Invalid SETRMCENABLE command %d", ucRmcEnable);
6169 ret = -EINVAL;
6170 goto exit;
6171 }
6172
6173 if (VOS_STATUS_SUCCESS != status)
6174 {
6175 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6176 "%s: SETRMC %d failed status %d", __func__, ucRmcEnable,
6177 status);
6178 ret = -EINVAL;
6179 goto exit;
6180 }
6181 }
6182 else if (strncasecmp(command, "SETRMCACTIONPERIOD", 18) == 0)
6183 {
6184 tANI_U8 *value = command;
6185 tANI_U32 uActionPeriod = 0;
6186 int status;
6187
6188 if ((WLAN_HDD_IBSS != pAdapter->device_mode) &&
6189 (WLAN_HDD_SOFTAP != pAdapter->device_mode))
6190 {
6191 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6192 "Received SETRMC command in invalid mode %d "
6193 "SETRMC command is only allowed in IBSS or SOFTAP mode",
6194 pAdapter->device_mode);
6195 ret = -EINVAL;
6196 goto exit;
6197 }
6198
6199 status = hdd_parse_setrmcactionperiod_command(value, &uActionPeriod);
6200 if (status)
6201 {
6202 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6203 "Invalid SETRMCACTIONPERIOD command ");
6204 ret = -EINVAL;
6205 goto exit;
6206 }
6207
6208 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6209 "%s: uActionPeriod %d ", __func__, uActionPeriod);
6210
6211 if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_RMC_ACTION_PERIOD_FREQUENCY,
6212 uActionPeriod, NULL, eANI_BOOLEAN_FALSE))
6213 {
6214 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6215 "%s: Could not set SETRMCACTIONPERIOD %d", __func__, uActionPeriod);
6216 ret = -EINVAL;
6217 goto exit;
6218 }
6219
6220 }
6221 else if (strncasecmp(command, "GETIBSSPEERINFOALL", 18) == 0)
6222 {
6223 /* Peer Info All Command */
6224 int status = eHAL_STATUS_SUCCESS;
6225 hdd_station_ctx_t *pHddStaCtx = NULL;
6226 char *extra = NULL;
6227 int idx = 0, length = 0;
6228 v_MACADDR_t *macAddr;
6229 v_U32_t txRateMbps = 0, numOfBytestoPrint = 0;
6230
6231 if (WLAN_HDD_IBSS == pAdapter->device_mode)
6232 {
6233 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
6234 }
6235 else
6236 {
6237 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6238 "%s: pAdapter is not valid for this device mode",
6239 __func__);
6240 ret = -EINVAL;
6241 goto exit;
6242 }
6243
6244 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6245 "%s: Received GETIBSSPEERINFOALL Command", __func__);
6246
6247
6248 /* Handle the command */
6249 status = hdd_cfg80211_get_ibss_peer_info_all(pAdapter);
6250 if (VOS_STATUS_SUCCESS == status)
6251 {
6252 /* The variable extra needed to be allocated on the heap since
6253 * amount of memory required to copy the data for 32 devices
6254 * exceeds the size of 1024 bytes of default stack size. On
6255 * 64 bit devices, the default max stack size of 2048 bytes
6256 */
6257 extra = kmalloc(WLAN_MAX_BUF_SIZE, GFP_KERNEL);
6258
6259 if (NULL == extra)
6260 {
6261 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6262 "%s:kmalloc failed", __func__);
6263 ret = -EINVAL;
6264 goto exit;
6265 }
6266
6267 /* Copy number of stations */
6268 length = scnprintf( extra, WLAN_MAX_BUF_SIZE, "%d ",
6269 pHddStaCtx->ibss_peer_info.numIBSSPeers);
6270 numOfBytestoPrint = length;
6271 for (idx = 0; idx < pHddStaCtx->ibss_peer_info.numIBSSPeers; idx++)
6272 {
6273 macAddr =
6274 hdd_wlan_get_ibss_mac_addr_from_staid(pAdapter,
6275 pHddStaCtx->ibss_peer_info.ibssPeerList[idx].staIdx);
6276 if (NULL != macAddr)
6277 {
6278 txRateMbps =
6279 ((pHddStaCtx->ibss_peer_info.ibssPeerList[idx].txRate)*500*1000)/1000000;
6280
6281 length += scnprintf( (extra + length), WLAN_MAX_BUF_SIZE - length,
6282 "%02x:%02x:%02x:%02x:%02x:%02x %d %d ",
6283 macAddr->bytes[0], macAddr->bytes[1], macAddr->bytes[2],
6284 macAddr->bytes[3], macAddr->bytes[4], macAddr->bytes[5],
6285 (int)txRateMbps,
6286 (int)pHddStaCtx->ibss_peer_info.ibssPeerList[idx].rssi);
6287 }
6288 else
6289 {
6290 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6291 "%s: MAC ADDR is NULL for staIdx: %d", __func__,
6292 pHddStaCtx->ibss_peer_info.ibssPeerList[idx].staIdx);
6293 }
6294
6295 /*
6296 * VOS_TRACE() macro has limitation of 512 bytes for the print
6297 * buffer. Hence printing the data in two chunks. The first chunk
6298 * will have the data for 16 devices and the second chunk will
6299 * have the rest.
6300 */
6301 if (idx < NUM_OF_STA_DATA_TO_PRINT)
6302 {
6303 numOfBytestoPrint = length;
6304 }
6305 }
6306
6307 /*
6308 * Copy the data back into buffer, if the data to copy is
6309 * morethan 512 bytes than we will split the data and do
6310 * it in two shots
6311 */
6312 if (copy_to_user(priv_data.buf, extra, numOfBytestoPrint))
6313 {
6314 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6315 "%s: Copy into user data buffer failed ", __func__);
6316 ret = -EFAULT;
6317 kfree(extra);
6318 goto exit;
6319 }
6320 priv_data.buf[numOfBytestoPrint] = '\0';
6321 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_MED,
6322 "%s", priv_data.buf);
6323
6324 if (length > numOfBytestoPrint)
6325 {
6326 if (copy_to_user(priv_data.buf + numOfBytestoPrint,
6327 extra + numOfBytestoPrint,
6328 length - numOfBytestoPrint + 1))
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 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_MED,
6337 "%s", &priv_data.buf[numOfBytestoPrint]);
6338 }
6339
6340 /* Free temporary buffer */
6341 kfree(extra);
6342 }
6343
6344 else
6345 {
6346 /* Command failed, log error */
6347 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6348 "%s: GETIBSSPEERINFOALL command failed with status code %d",
6349 __func__, status);
6350 ret = -EINVAL;
6351 goto exit;
6352 }
6353 ret = 0;
6354 }
6355 else if(strncasecmp(command, "GETIBSSPEERINFO", 15) == 0)
6356 {
6357 /* Peer Info <Peer Addr> command */
6358 tANI_U8 *value = command;
6359 VOS_STATUS status;
6360 hdd_station_ctx_t *pHddStaCtx = NULL;
6361 char extra[128] = { 0 };
6362 v_U32_t length = 0;
6363 v_U8_t staIdx = 0;
6364 v_U32_t txRateMbps = 0;
6365 v_MACADDR_t peerMacAddr;
6366
6367 if (WLAN_HDD_IBSS == pAdapter->device_mode)
6368 {
6369 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
6370 }
6371 else
6372 {
6373 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6374 "%s: pAdapter is not valid for this device mode",
6375 __func__);
6376 ret = -EINVAL;
6377 goto exit;
6378 }
6379
6380 /* if there are no peers, no need to continue with the command */
6381 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6382 "%s: Received GETIBSSPEERINFO Command", __func__);
6383
6384 if (eConnectionState_IbssConnected != pHddStaCtx->conn_info.connState)
6385 {
6386 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6387 "%s:No IBSS Peers coalesced", __func__);
6388 ret = -EINVAL;
6389 goto exit;
6390 }
6391
6392 /* Parse the incoming command buffer */
6393 status = hdd_parse_get_ibss_peer_info(value, &peerMacAddr);
6394 if (VOS_STATUS_SUCCESS != status)
6395 {
6396 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6397 "%s: Invalid GETIBSSPEERINFO command", __func__);
6398 ret = -EINVAL;
6399 goto exit;
6400 }
6401
6402 /* Get station index for the peer mac address */
6403 hdd_Ibss_GetStaId(pHddStaCtx, &peerMacAddr, &staIdx);
6404
6405 if (staIdx > HDD_MAX_NUM_IBSS_STA)
6406 {
6407 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6408 "%s: Invalid StaIdx %d returned", __func__, staIdx);
6409 ret = -EINVAL;
6410 goto exit;
6411 }
6412
6413 /* Handle the command */
6414 status = hdd_cfg80211_get_ibss_peer_info(pAdapter, staIdx);
6415 if (VOS_STATUS_SUCCESS == status)
6416 {
6417 v_U32_t txRate = pHddStaCtx->ibss_peer_info.ibssPeerList[0].txRate;
6418 txRateMbps = (txRate * 500 * 1000)/1000000;
6419
6420 length = scnprintf( extra, sizeof(extra), "%d %d", (int)txRateMbps,
6421 (int)pHddStaCtx->ibss_peer_info.ibssPeerList[0].rssi);
6422
6423 /* Copy the data back into buffer */
6424 if (copy_to_user(priv_data.buf, &extra, length+ 1))
6425 {
6426 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6427 "%s: copy data to user buffer failed GETIBSSPEERINFO command",
6428 __func__);
6429 ret = -EFAULT;
6430 goto exit;
6431 }
6432 }
6433 else
6434 {
6435 /* Command failed, log error */
6436 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6437 "%s: GETIBSSPEERINFO command failed with status code %d",
6438 __func__, status);
6439 ret = -EINVAL;
6440 goto exit;
6441 }
6442
6443 /* Success ! */
6444 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_MED,
6445 "%s", priv_data.buf);
6446 ret = 0;
6447 }
6448 else if (strncasecmp(command, "SETRMCTXRATE", 12) == 0)
6449 {
6450 tANI_U8 *value = command;
6451 tANI_U32 uRate = 0;
6452 tTxrateinfoflags txFlags = 0;
6453 tSirRateUpdateInd *rateUpdateParams;
6454 int status;
6455
6456 if ((WLAN_HDD_IBSS != pAdapter->device_mode) &&
6457 (WLAN_HDD_SOFTAP != pAdapter->device_mode))
6458 {
6459 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6460 "Received SETRMCTXRATE command in invalid mode %d "
6461 "SETRMC command is only allowed in IBSS or SOFTAP mode",
6462 pAdapter->device_mode);
6463 ret = -EINVAL;
6464 goto exit;
6465 }
6466
6467 status = hdd_parse_setrmcrate_command(value, &uRate, &txFlags);
6468 if (status)
6469 {
6470 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6471 "Invalid SETRMCTXRATE command ");
6472 ret = -EINVAL;
6473 goto exit;
6474 }
6475
6476 rateUpdateParams = vos_mem_malloc(sizeof(tSirRateUpdateInd));
6477 if (NULL == rateUpdateParams)
6478 {
6479 ret = -EINVAL;
6480 goto exit;
6481 }
6482
6483 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6484 "%s: uRate %d ", __func__, uRate);
6485
6486 vos_mem_zero(rateUpdateParams, sizeof(tSirRateUpdateInd ));
6487
6488 /* -1 implies ignore this param */
6489 rateUpdateParams->ucastDataRate = -1;
6490
6491 /*
6492 * Fill the user specifieed RMC rate param
6493 * and the derived tx flags.
6494 */
6495 rateUpdateParams->rmcDataRate = uRate;
6496 rateUpdateParams->rmcDataRateTxFlag = txFlags;
6497
6498 status = sme_SendRateUpdateInd((tHalHandle)(pHddCtx->hHal), rateUpdateParams);
6499 }
6500 else if (strncasecmp(command, "SETIBSSTXFAILEVENT", 18) == 0 )
6501 {
6502 char *value;
6503 tANI_U8 tx_fail_count = 0;
6504 tANI_U16 pid = 0;
6505
6506 value = command;
6507
6508 ret = hdd_ParseIBSSTXFailEventParams(value, &tx_fail_count, &pid);
6509
6510 if (0 != ret)
6511 {
6512 hddLog(VOS_TRACE_LEVEL_INFO,
6513 "%s: Failed to parse SETIBSSTXFAILEVENT arguments",
6514 __func__);
6515 goto exit;
6516 }
6517
6518 hddLog(VOS_TRACE_LEVEL_INFO, "%s: tx_fail_cnt=%hhu, pid=%hu",
6519 __func__, tx_fail_count, pid);
6520
6521 if (0 == tx_fail_count)
6522 {
6523 // Disable TX Fail Indication
6524 if (eHAL_STATUS_SUCCESS ==
6525 sme_TXFailMonitorStartStopInd(pHddCtx->hHal,
6526 tx_fail_count,
6527 NULL))
6528 {
6529 cesium_pid = 0;
6530 }
6531 else
6532 {
6533 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6534 "%s: failed to disable TX Fail Event ", __func__);
6535 ret = -EINVAL;
6536 }
6537 }
6538 else
6539 {
6540 if (eHAL_STATUS_SUCCESS ==
6541 sme_TXFailMonitorStartStopInd(pHddCtx->hHal,
6542 tx_fail_count,
6543 (void*)hdd_tx_fail_ind_callback))
6544 {
6545 cesium_pid = pid;
6546 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6547 "%s: Registered Cesium pid %u", __func__,
6548 cesium_pid);
6549 }
6550 else
6551 {
6552 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6553 "%s: Failed to enable TX Fail Monitoring", __func__);
6554 ret = -EINVAL;
6555 }
6556 }
6557 }
6558
6559#endif /* WLAN_FEATURE_RMC */
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08006560#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07006561 else if (strncmp(command, "SETCCXROAMSCANCHANNELS", 22) == 0)
6562 {
6563 tANI_U8 *value = command;
6564 tANI_U8 ChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
6565 tANI_U8 numChannels = 0;
6566 eHalStatus status = eHAL_STATUS_SUCCESS;
6567
6568 status = hdd_parse_channellist(value, ChannelList, &numChannels);
6569 if (eHAL_STATUS_SUCCESS != status)
6570 {
6571 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6572 "%s: Failed to parse channel list information", __func__);
6573 ret = -EINVAL;
6574 goto exit;
6575 }
6576
6577 if (numChannels > WNI_CFG_VALID_CHANNEL_LIST_LEN)
6578 {
6579 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6580 "%s: number of channels (%d) supported exceeded max (%d)", __func__,
6581 numChannels, WNI_CFG_VALID_CHANNEL_LIST_LEN);
6582 ret = -EINVAL;
6583 goto exit;
6584 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08006585 status = sme_SetEseRoamScanChannelList((tHalHandle)(pHddCtx->hHal),
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07006586 ChannelList,
6587 numChannels);
6588 if (eHAL_STATUS_SUCCESS != status)
6589 {
6590 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6591 "%s: Failed to update channel list information", __func__);
6592 ret = -EINVAL;
6593 goto exit;
6594 }
6595 }
6596 else if (strncmp(command, "GETTSMSTATS", 11) == 0)
6597 {
6598 tANI_U8 *value = command;
6599 char extra[128] = {0};
6600 int len = 0;
6601 tANI_U8 tid = 0;
6602 hdd_station_ctx_t *pHddStaCtx = NULL;
6603 tAniTrafStrmMetrics tsmMetrics;
6604 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
6605
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05306606 ret = hdd_drv_cmd_validate(command, 11);
6607 if (ret)
6608 goto exit;
6609
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07006610 /* if not associated, return error */
6611 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
6612 {
6613 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "%s:Not associated!",__func__);
6614 ret = -EINVAL;
6615 goto exit;
6616 }
6617
6618 /* Move pointer to ahead of GETTSMSTATS<delimiter> */
6619 value = value + 12;
6620 /* Convert the value from ascii to integer */
6621 ret = kstrtou8(value, 10, &tid);
6622 if (ret < 0)
6623 {
6624 /* If the input value is greater than max value of datatype, then also
6625 kstrtou8 fails */
6626 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6627 "%s: kstrtou8 failed range [%d - %d]", __func__,
6628 TID_MIN_VALUE,
6629 TID_MAX_VALUE);
6630 ret = -EINVAL;
6631 goto exit;
6632 }
6633
6634 if ((tid < TID_MIN_VALUE) || (tid > TID_MAX_VALUE))
6635 {
6636 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6637 "tid value %d is out of range"
6638 " (Min: %d Max: %d)", tid,
6639 TID_MIN_VALUE,
6640 TID_MAX_VALUE);
6641 ret = -EINVAL;
6642 goto exit;
6643 }
6644
6645 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6646 "%s: Received Command to get tsm stats tid = %d", __func__, tid);
6647
6648 if (VOS_STATUS_SUCCESS != hdd_get_tsm_stats(pAdapter, tid, &tsmMetrics))
6649 {
6650 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6651 "%s: failed to get tsm stats", __func__);
6652 ret = -EFAULT;
6653 goto exit;
6654 }
6655
6656 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6657 "UplinkPktQueueDly(%d)\n"
6658 "UplinkPktQueueDlyHist[0](%d)\n"
6659 "UplinkPktQueueDlyHist[1](%d)\n"
6660 "UplinkPktQueueDlyHist[2](%d)\n"
6661 "UplinkPktQueueDlyHist[3](%d)\n"
Arun Kumar Khandavallie8768212014-02-17 16:43:34 +05306662 "UplinkPktTxDly(%u)\n"
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07006663 "UplinkPktLoss(%d)\n"
6664 "UplinkPktCount(%d)\n"
6665 "RoamingCount(%d)\n"
6666 "RoamingDly(%d)", tsmMetrics.UplinkPktQueueDly,
6667 tsmMetrics.UplinkPktQueueDlyHist[0],
6668 tsmMetrics.UplinkPktQueueDlyHist[1],
6669 tsmMetrics.UplinkPktQueueDlyHist[2],
6670 tsmMetrics.UplinkPktQueueDlyHist[3],
6671 tsmMetrics.UplinkPktTxDly, tsmMetrics.UplinkPktLoss,
6672 tsmMetrics.UplinkPktCount, tsmMetrics.RoamingCount, tsmMetrics.RoamingDly);
6673
6674 /* Output TSM stats is of the format
6675 GETTSMSTATS [PktQueueDly] [PktQueueDlyHist[0]]:[PktQueueDlyHist[1]] ...[RoamingDly]
6676 eg., GETTSMSTATS 10 1:0:0:161 20 1 17 8 39800 */
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08006677 len = scnprintf(extra, sizeof(extra), "%s %d %d:%d:%d:%d %u %d %d %d %d", command,
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07006678 tsmMetrics.UplinkPktQueueDly, tsmMetrics.UplinkPktQueueDlyHist[0],
6679 tsmMetrics.UplinkPktQueueDlyHist[1], tsmMetrics.UplinkPktQueueDlyHist[2],
6680 tsmMetrics.UplinkPktQueueDlyHist[3], tsmMetrics.UplinkPktTxDly,
6681 tsmMetrics.UplinkPktLoss, tsmMetrics.UplinkPktCount, tsmMetrics.RoamingCount,
6682 tsmMetrics.RoamingDly);
6683
Ratnam Rachurid53009c2015-08-07 13:59:00 +05306684 len = VOS_MIN(priv_data.total_len, len + 1);
6685 if (copy_to_user(priv_data.buf, &extra, len)) {
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07006686 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6687 "%s: failed to copy data to user buffer", __func__);
6688 ret = -EFAULT;
6689 goto exit;
6690 }
6691 }
6692 else if (strncmp(command, "SETCCKMIE", 9) == 0)
6693 {
6694 tANI_U8 *value = command;
6695 tANI_U8 *cckmIe = NULL;
6696 tANI_U8 cckmIeLen = 0;
6697 eHalStatus status = eHAL_STATUS_SUCCESS;
6698
6699 status = hdd_parse_get_cckm_ie(value, &cckmIe, &cckmIeLen);
6700 if (eHAL_STATUS_SUCCESS != status)
6701 {
6702 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6703 "%s: Failed to parse cckm ie data", __func__);
6704 ret = -EINVAL;
6705 goto exit;
6706 }
6707
6708 if (cckmIeLen > DOT11F_IE_RSN_MAX_LEN)
6709 {
6710 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6711 "%s: CCKM Ie input length is more than max[%d]", __func__,
6712 DOT11F_IE_RSN_MAX_LEN);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08006713 vos_mem_free(cckmIe);
6714 cckmIe = NULL;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07006715 ret = -EINVAL;
6716 goto exit;
6717 }
6718 sme_SetCCKMIe((tHalHandle)(pHddCtx->hHal), pAdapter->sessionId, cckmIe, cckmIeLen);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08006719 vos_mem_free(cckmIe);
6720 cckmIe = NULL;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07006721 }
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08006722 else if (strncmp(command, "CCXBEACONREQ", 12) == 0)
6723 {
6724 tANI_U8 *value = command;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08006725 tCsrEseBeaconReq eseBcnReq;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08006726 eHalStatus status = eHAL_STATUS_SUCCESS;
Srinivas Girigowda0c6d7fe2014-05-28 18:18:10 -07006727
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08006728 status = hdd_parse_ese_beacon_req(value, &eseBcnReq);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08006729 if (eHAL_STATUS_SUCCESS != status)
6730 {
6731 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08006732 "%s: Failed to parse ese beacon req", __func__);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08006733 ret = -EINVAL;
6734 goto exit;
6735 }
Srinivas Girigowda0c6d7fe2014-05-28 18:18:10 -07006736 if (!hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))) {
6737 hddLog(VOS_TRACE_LEVEL_INFO, FL("Not associated"));
6738 hdd_indicateEseBcnReportNoResults (pAdapter,
6739 eseBcnReq.bcnReq[0].measurementToken,
6740 0x02, //BIT(1) set for measurement done
6741 0); // no BSS
6742 goto exit;
6743 }
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08006744
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08006745 status = sme_SetEseBeaconRequest((tHalHandle)(pHddCtx->hHal), pAdapter->sessionId, &eseBcnReq);
6746 if (eHAL_STATUS_SUCCESS != status)
6747 {
6748 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6749 "%s: sme_SetEseBeaconRequest failed (%d)", __func__, status);
6750 ret = -EINVAL;
6751 goto exit;
6752 }
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08006753 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08006754#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
c_hpothu92367912014-05-01 15:18:17 +05306755 else if (strncmp(command, "GETBCNMISSRATE", 14) == 0)
6756 {
6757 eHalStatus status;
6758 char buf[32], len;
Hanumanth Reddy Pothula7aa4bea2018-04-09 17:19:03 +05306759 void *cookie;
6760 struct hdd_request *request;
6761 struct bcn_miss_rate_priv *priv;
6762 static const struct hdd_request_params params = {
6763 .priv_size = sizeof(*priv),
6764 .timeout_ms = WLAN_WAIT_TIME_STATS,
6765 };
c_hpothu92367912014-05-01 15:18:17 +05306766
6767 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
6768
6769 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
6770 {
6771 hddLog(VOS_TRACE_LEVEL_WARN,
6772 FL("GETBCNMISSRATE: STA is not in connected state"));
6773 ret = -1;
6774 goto exit;
6775 }
Hanumanth Reddy Pothula7aa4bea2018-04-09 17:19:03 +05306776 request = hdd_request_alloc(&params);
6777 if (!request) {
6778 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Request allocation failure"));
6779 ret = -ENOMEM;
6780 goto exit;
6781 }
6782 cookie = hdd_request_cookie(request);
6783 priv = hdd_request_priv(request);
6784 priv->bcn_miss_rate = -1;
c_hpothu92367912014-05-01 15:18:17 +05306785
6786 status = sme_getBcnMissRate((tHalHandle)(pHddCtx->hHal),
6787 pAdapter->sessionId,
Hanumanth Reddy Pothula7aa4bea2018-04-09 17:19:03 +05306788 (void *)get_bcn_miss_rate_cb,
6789 cookie);
c_hpothu92367912014-05-01 15:18:17 +05306790 if( eHAL_STATUS_SUCCESS != status)
6791 {
6792 hddLog(VOS_TRACE_LEVEL_INFO,
6793 FL("GETBCNMISSRATE: fail to post WDA cmd"));
6794 ret = -EINVAL;
Hanumanth Reddy Pothula7aa4bea2018-04-09 17:19:03 +05306795 goto free_bcn_miss_rate_req;
c_hpothu92367912014-05-01 15:18:17 +05306796 }
6797
Hanumanth Reddy Pothula7aa4bea2018-04-09 17:19:03 +05306798 ret = hdd_request_wait_for_response(request);
6799 if(ret)
c_hpothu92367912014-05-01 15:18:17 +05306800 {
6801 hddLog(VOS_TRACE_LEVEL_ERROR,
6802 FL("failed to wait on bcnMissRateComp %d"), ret);
6803
c_hpothu92367912014-05-01 15:18:17 +05306804 ret = -EINVAL;
Hanumanth Reddy Pothula7aa4bea2018-04-09 17:19:03 +05306805 goto free_bcn_miss_rate_req;
c_hpothu92367912014-05-01 15:18:17 +05306806 }
6807
6808 hddLog(VOS_TRACE_LEVEL_INFO,
Hanumanth Reddy Pothula7aa4bea2018-04-09 17:19:03 +05306809 FL("GETBCNMISSRATE: bcnMissRate: %d"), priv->bcn_miss_rate);
c_hpothu92367912014-05-01 15:18:17 +05306810
Hanumanth Reddy Pothula7aa4bea2018-04-09 17:19:03 +05306811 if (priv->bcn_miss_rate == -1) {
6812 ret = -EFAULT;
6813 goto free_bcn_miss_rate_req;
6814 }
6815
6816 len = snprintf(buf, sizeof(buf), "GETBCNMISSRATE %d",
6817 priv->bcn_miss_rate);
c_hpothu92367912014-05-01 15:18:17 +05306818 if (copy_to_user(priv_data.buf, &buf, len + 1))
6819 {
6820 hddLog(VOS_TRACE_LEVEL_ERROR,
6821 "%s: failed to copy data to user buffer", __func__);
6822 ret = -EFAULT;
Hanumanth Reddy Pothula7aa4bea2018-04-09 17:19:03 +05306823 goto free_bcn_miss_rate_req;
c_hpothu92367912014-05-01 15:18:17 +05306824 }
6825 ret = len;
Hanumanth Reddy Pothula7aa4bea2018-04-09 17:19:03 +05306826
6827free_bcn_miss_rate_req:
6828 hdd_request_put(request);
c_hpothu92367912014-05-01 15:18:17 +05306829 }
Atul Mittal87ec2422014-09-24 13:12:50 +05306830#ifdef FEATURE_WLAN_TDLS
6831 else if (strncmp(command, "TDLSSECONDARYCHANNELOFFSET", 26) == 0) {
6832 tANI_U8 *value = command;
6833 int set_value;
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05306834
6835 ret = hdd_drv_cmd_validate(command, 26);
6836 if (ret)
6837 goto exit;
6838
Atul Mittal87ec2422014-09-24 13:12:50 +05306839 /* Move pointer to ahead of TDLSOFFCH*/
6840 value += 26;
c_manjeebbc40212015-12-08 13:52:59 +05306841 if (!(sscanf(value, "%d", &set_value))) {
6842 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6843 FL("No input identified"));
6844 ret = -EINVAL;
6845 goto exit;
6846 }
6847
Atul Mittal87ec2422014-09-24 13:12:50 +05306848 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6849 "%s: Tdls offchannel offset:%d",
6850 __func__, set_value);
6851 ret = iw_set_tdlssecoffchanneloffset(pHddCtx, set_value);
6852 if (ret < 0)
6853 {
6854 ret = -EINVAL;
6855 goto exit;
6856 }
6857
6858 } else if (strncmp(command, "TDLSOFFCHANNELMODE", 18) == 0) {
6859 tANI_U8 *value = command;
6860 int set_value;
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05306861
6862 ret = hdd_drv_cmd_validate(command, 18);
6863 if (ret)
6864 goto exit;
6865
Atul Mittal87ec2422014-09-24 13:12:50 +05306866 /* Move pointer to ahead of tdlsoffchnmode*/
6867 value += 18;
c_manjee82323892015-12-08 12:40:34 +05306868 ret = sscanf(value, "%d", &set_value);
6869 if (ret != 1) {
6870 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6871 FL("No input identified"));
6872 ret = -EINVAL;
6873 goto exit;
6874 }
Atul Mittal87ec2422014-09-24 13:12:50 +05306875 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6876 "%s: Tdls offchannel mode:%d",
6877 __func__, set_value);
6878 ret = iw_set_tdlsoffchannelmode(pAdapter, set_value);
6879 if (ret < 0)
6880 {
6881 ret = -EINVAL;
6882 goto exit;
6883 }
6884 } else if (strncmp(command, "TDLSOFFCHANNEL", 14) == 0) {
6885 tANI_U8 *value = command;
6886 int set_value;
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05306887
6888 ret = hdd_drv_cmd_validate(command, 14);
6889 if (ret)
6890 goto exit;
6891
Atul Mittal87ec2422014-09-24 13:12:50 +05306892 /* Move pointer to ahead of TDLSOFFCH*/
6893 value += 14;
c_manjeef6ccaf52015-12-08 11:52:11 +05306894 ret = sscanf(value, "%d", &set_value);
6895 if (ret != 1) {
6896 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6897 "Wrong value is given for hdd_set_tdls_offchannel");
6898 ret = -EINVAL;
6899 goto exit;
6900 }
6901
Atul Mittal87ec2422014-09-24 13:12:50 +05306902 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6903 "%s: Tdls offchannel num: %d",
6904 __func__, set_value);
6905 ret = iw_set_tdlsoffchannel(pHddCtx, set_value);
6906 if (ret < 0)
6907 {
6908 ret = -EINVAL;
6909 goto exit;
6910 }
6911 }
6912#endif
Satyanarayana Dash72806012014-12-02 14:30:08 +05306913 else if (strncmp(command, "GETFWSTATS", 10) == 0)
6914 {
6915 eHalStatus status;
6916 char *buf = NULL;
6917 char len;
Hanumanth Reddy Pothula7aa4bea2018-04-09 17:19:03 +05306918 tSirFwStatsResult *fwStatsRsp = &(pAdapter->fwStatsRsp),
6919 *fw_stats_result;
Satyanarayana Dash72806012014-12-02 14:30:08 +05306920 tANI_U8 *ptr = command;
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05306921 int stats;
Hanumanth Reddy Pothula7aa4bea2018-04-09 17:19:03 +05306922 void *cookie;
6923 struct hdd_request *request;
6924 struct fw_stats_priv *priv;
6925 static const struct hdd_request_params params = {
6926 .priv_size = sizeof(*priv),
6927 .timeout_ms = WLAN_WAIT_TIME_STATS,
6928 };
Satyanarayana Dash72806012014-12-02 14:30:08 +05306929
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05306930 ret = hdd_drv_cmd_validate(command, 10);
6931 if (ret)
6932 goto exit;
6933
6934 stats = *(ptr + 11) - '0';
Satyanarayana Dash72806012014-12-02 14:30:08 +05306935 hddLog(VOS_TRACE_LEVEL_INFO, FL("stats = %d "),stats);
6936 if (!IS_FEATURE_FW_STATS_ENABLE)
6937 {
6938 hddLog(VOS_TRACE_LEVEL_INFO,
6939 FL("Get Firmware stats feature not supported"));
6940 ret = -EINVAL;
6941 goto exit;
6942 }
6943
6944 if (FW_STATS_MAX <= stats || 0 >= stats)
6945 {
6946 hddLog(VOS_TRACE_LEVEL_INFO,
6947 FL(" stats %d not supported"),stats);
6948 ret = -EINVAL;
6949 goto exit;
6950 }
6951
Hanumanth Reddy Pothula7aa4bea2018-04-09 17:19:03 +05306952 request = hdd_request_alloc(&params);
6953 if (!request) {
6954 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Request allocation failure"));
6955 ret = -ENOMEM;
6956 goto exit;
6957 }
6958 cookie = hdd_request_cookie(request);
6959
Satyanarayana Dash72806012014-12-02 14:30:08 +05306960 status = sme_GetFwStats( (tHalHandle)pHddCtx->hHal, stats,
Hanumanth Reddy Pothula7aa4bea2018-04-09 17:19:03 +05306961 cookie, hdd_fw_stats_cb);
Satyanarayana Dash72806012014-12-02 14:30:08 +05306962 if (eHAL_STATUS_SUCCESS != status)
6963 {
6964 hddLog(VOS_TRACE_LEVEL_ERROR,
6965 FL(" fail to post WDA cmd status = %d"), status);
6966 ret = -EINVAL;
Hanumanth Reddy Pothula7aa4bea2018-04-09 17:19:03 +05306967 hdd_request_put(request);
Satyanarayana Dash72806012014-12-02 14:30:08 +05306968 goto exit;
6969 }
Hanumanth Reddy Pothula7aa4bea2018-04-09 17:19:03 +05306970 ret = hdd_request_wait_for_response(request);
6971 if (ret)
Satyanarayana Dash72806012014-12-02 14:30:08 +05306972 {
6973 hddLog(VOS_TRACE_LEVEL_ERROR,
6974 FL("failed to wait on GwtFwstats"));
Satyanarayana Dash72806012014-12-02 14:30:08 +05306975 ret = -EINVAL;
Hanumanth Reddy Pothula7aa4bea2018-04-09 17:19:03 +05306976 hdd_request_put(request);
Satyanarayana Dash72806012014-12-02 14:30:08 +05306977 goto exit;
6978 }
Hanumanth Reddy Pothula7aa4bea2018-04-09 17:19:03 +05306979
6980 priv = hdd_request_priv(request);
6981 fw_stats_result = priv->fw_stats;
6982 fwStatsRsp->type = 0;
6983 if (NULL != fw_stats_result)
6984 {
6985 switch (fw_stats_result->type )
6986 {
6987 case FW_UBSP_STATS:
6988 {
6989 tSirUbspFwStats *stats =
6990 &fwStatsRsp->fwStatsData.ubspStats;
6991 memcpy(fwStatsRsp, fw_stats_result,
6992 sizeof(tSirFwStatsResult));
6993 hddLog(VOS_TRACE_LEVEL_INFO,
6994 FL("ubsp_enter_cnt = %d ubsp_jump_ddr_cnt = %d"),
6995 stats->ubsp_enter_cnt,
6996 stats->ubsp_jump_ddr_cnt);
6997 }
6998 break;
6999
7000 default:
7001 {
7002 hddLog(VOS_TRACE_LEVEL_ERROR,
7003 FL("No handling for stats type %d"),
7004 fw_stats_result->type);
7005 }
7006 }
7007 }
7008 hdd_request_put(request);
7009
Satyanarayana Dash72806012014-12-02 14:30:08 +05307010 if (fwStatsRsp->type)
7011 {
7012 buf = kmalloc(FW_STATE_RSP_LEN, GFP_KERNEL);
7013 if (!buf)
7014 {
7015 hddLog(VOS_TRACE_LEVEL_ERROR,
7016 FL(" failed to allocate memory"));
7017 ret = -ENOMEM;
7018 goto exit;
7019 }
7020 switch( fwStatsRsp->type )
7021 {
7022 case FW_UBSP_STATS:
7023 {
7024 len = snprintf(buf, FW_STATE_RSP_LEN,
7025 "GETFWSTATS: ubsp_enter_cnt %d ubsp_jump_ddr_cnt %d",
Abhishek Singh08aa7762014-12-16 13:59:03 +05307026 fwStatsRsp->fwStatsData.ubspStats.ubsp_enter_cnt,
7027 fwStatsRsp->fwStatsData.ubspStats.ubsp_jump_ddr_cnt);
Satyanarayana Dash72806012014-12-02 14:30:08 +05307028 }
7029 break;
7030 default:
7031 {
7032 hddLog(VOS_TRACE_LEVEL_ERROR, FL( "No handling for stats type %d"),fwStatsRsp->type);
7033 ret = -EFAULT;
7034 kfree(buf);
7035 goto exit;
7036 }
7037 }
7038 if (copy_to_user(priv_data.buf, buf, len + 1))
7039 {
7040 hddLog(VOS_TRACE_LEVEL_ERROR,
7041 FL(" failed to copy data to user buffer"));
7042 ret = -EFAULT;
7043 kfree(buf);
7044 goto exit;
7045 }
7046 ret = len;
7047 kfree(buf);
7048 }
7049 else
7050 {
7051 hddLog(VOS_TRACE_LEVEL_ERROR,
7052 FL("failed to fetch the stats"));
7053 ret = -EFAULT;
7054 goto exit;
7055 }
Satyanarayana Dash72806012014-12-02 14:30:08 +05307056 }
Agarwal Ashish8bd53ae2015-06-12 18:03:45 +05307057 else if (strncasecmp(command, "SET_FCC_CHANNEL", 15) == 0)
7058 {
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05307059 ret = hdd_drv_cmd_validate(command, 15);
7060 if (ret)
7061 goto exit;
7062
Agarwal Ashish8bd53ae2015-06-12 18:03:45 +05307063 /*
7064 * this command wld be called by user-space when it detects WLAN
7065 * ON after airplane mode is set. When APM is set, WLAN turns off.
7066 * But it can be turned back on. Otherwise; when APM is turned back
7067 * off, WLAN wld turn back on. So at that point the command is
7068 * expected to come down. 0 means disable, 1 means enable. The
7069 * constraint is removed when parameter 1 is set or different
7070 * country code is set
7071 */
7072 ret = hdd_cmd_setFccChannel(pHddCtx, command, 15);
7073 }
Mahesh A Saptasagarbeca12c2015-09-07 16:21:06 +05307074 else if (strncasecmp(command, "DISABLE_CA_EVENT", 16) == 0)
7075 {
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05307076 ret = hdd_drv_cmd_validate(command, 16);
7077 if (ret)
7078 goto exit;
7079
Mahesh A Saptasagarbeca12c2015-09-07 16:21:06 +05307080 ret = hdd_enable_disable_ca_event(pHddCtx, command, 16);
7081 }
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +05307082 /*
7083 * command should be a string having format
7084 * SET_DISABLE_CHANNEL_LIST <num of channels>
7085 * <channels separated by spaces>
7086 */
7087 else if (strncmp(command, "SET_DISABLE_CHANNEL_LIST", 24) == 0) {
7088 tANI_U8 *ptr = command;
7089 ret = hdd_drv_cmd_validate(command, 24);
7090 if (ret)
7091 goto exit;
7092
7093 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
7094 " Received Command to disable Channels %s",
7095 __func__);
7096 ret = hdd_parse_disable_chan_cmd(pAdapter, ptr);
7097 if (ret)
7098 goto exit;
7099 }
Hanumanth Reddy Pothula8ae38bb2018-03-07 18:59:30 +05307100 else if (strncmp(command, "GET_DISABLE_CHANNEL_LIST", 24) == 0) {
Ashish Kumar Dhanotiya95e5bc22018-04-19 17:06:33 +05307101 char extra[512] = {0};
7102 int max_len, copied_length;
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +05307103
Ashish Kumar Dhanotiya95e5bc22018-04-19 17:06:33 +05307104 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Hanumanth Reddy Pothula8ae38bb2018-03-07 18:59:30 +05307105 " Received Command to get disable Channels list %s",
7106 __func__);
7107
Ashish Kumar Dhanotiya95e5bc22018-04-19 17:06:33 +05307108 max_len = VOS_MIN(priv_data.total_len, sizeof(extra));
7109 copied_length = hdd_get_disable_ch_list(pHddCtx, extra, max_len);
7110 if (copied_length == 0) {
7111 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Hanumanth Reddy Pothula8ae38bb2018-03-07 18:59:30 +05307112 FL("disable channel list are not yet programed"));
7113 ret = -EINVAL;
7114 goto exit;
7115 }
7116
Ashish Kumar Dhanotiya95e5bc22018-04-19 17:06:33 +05307117 if (copy_to_user(priv_data.buf, &extra, copied_length + 1)) {
7118 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7119 "%s: failed to copy data to user buffer", __func__);
Hanumanth Reddy Pothula8ae38bb2018-03-07 18:59:30 +05307120 ret = -EFAULT;
7121 goto exit;
7122 }
7123
7124 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
7125 FL("data:%s"), extra);
7126 }
Madan Mohan Koyyalamudif9bdd4e2012-10-30 18:05:03 -07007127 else {
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307128 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
7129 TRACE_CODE_HDD_UNSUPPORTED_IOCTL,
7130 pAdapter->sessionId, 0));
Satyanarayana Dash72806012014-12-02 14:30:08 +05307131 hddLog( VOS_TRACE_LEVEL_WARN, FL("Unsupported GUI command %s"),
7132 command);
Madan Mohan Koyyalamudif9bdd4e2012-10-30 18:05:03 -07007133 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007134 }
7135exit:
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05307136 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07007137 if (command)
7138 {
7139 kfree(command);
7140 }
7141 return ret;
7142}
7143
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07007144#ifdef CONFIG_COMPAT
7145static int hdd_driver_compat_ioctl(hdd_adapter_t *pAdapter, struct ifreq *ifr)
7146{
7147 struct {
7148 compat_uptr_t buf;
7149 int used_len;
7150 int total_len;
7151 } compat_priv_data;
7152 hdd_priv_data_t priv_data;
7153 int ret = 0;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07007154
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07007155 /*
7156 * Note that pAdapter and ifr have already been verified by caller,
7157 * and HDD context has also been validated
7158 */
7159 if (copy_from_user(&compat_priv_data, ifr->ifr_data,
7160 sizeof(compat_priv_data))) {
7161 ret = -EFAULT;
7162 goto exit;
7163 }
7164 priv_data.buf = compat_ptr(compat_priv_data.buf);
7165 priv_data.used_len = compat_priv_data.used_len;
7166 priv_data.total_len = compat_priv_data.total_len;
7167 ret = hdd_driver_command(pAdapter, &priv_data);
7168 exit:
7169 return ret;
7170}
7171#else /* CONFIG_COMPAT */
7172static int hdd_driver_compat_ioctl(hdd_adapter_t *pAdapter, struct ifreq *ifr)
7173{
7174 /* will never be invoked */
7175 return 0;
7176}
7177#endif /* CONFIG_COMPAT */
7178
7179static int hdd_driver_ioctl(hdd_adapter_t *pAdapter, struct ifreq *ifr)
7180{
7181 hdd_priv_data_t priv_data;
7182 int ret = 0;
7183
7184 /*
7185 * Note that pAdapter and ifr have already been verified by caller,
7186 * and HDD context has also been validated
7187 */
7188 if (copy_from_user(&priv_data, ifr->ifr_data, sizeof(priv_data))) {
7189 ret = -EFAULT;
7190 } else {
7191 ret = hdd_driver_command(pAdapter, &priv_data);
7192 }
7193 return ret;
7194}
7195
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05307196int __hdd_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07007197{
7198 hdd_adapter_t *pAdapter;
7199 hdd_context_t *pHddCtx;
7200 int ret;
7201
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05307202 ENTER();
7203
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07007204 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
7205 if (NULL == pAdapter) {
7206 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
7207 "%s: HDD adapter context is Null", __func__);
7208 ret = -ENODEV;
7209 goto exit;
7210 }
7211 if (dev != pAdapter->dev) {
7212 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
7213 "%s: HDD adapter/dev inconsistency", __func__);
7214 ret = -ENODEV;
7215 goto exit;
7216 }
7217
7218 if ((!ifr) || (!ifr->ifr_data)) {
7219 ret = -EINVAL;
7220 goto exit;
7221 }
7222
7223 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7224 ret = wlan_hdd_validate_context(pHddCtx);
7225 if (ret) {
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07007226 ret = -EBUSY;
7227 goto exit;
7228 }
7229
7230 switch (cmd) {
7231 case (SIOCDEVPRIVATE + 1):
7232 if (is_compat_task())
7233 ret = hdd_driver_compat_ioctl(pAdapter, ifr);
7234 else
7235 ret = hdd_driver_ioctl(pAdapter, ifr);
7236 break;
7237 default:
7238 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unknown ioctl %d",
7239 __func__, cmd);
7240 ret = -EINVAL;
7241 break;
7242 }
7243 exit:
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05307244 EXIT();
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07007245 return ret;
7246}
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07007247
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05307248int hdd_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
7249{
7250 int ret;
7251
7252 vos_ssr_protect(__func__);
7253 ret = __hdd_ioctl(dev, ifr, cmd);
7254 vos_ssr_unprotect(__func__);
7255
7256 return ret;
7257}
7258
Katya Nigame7b69a82015-04-28 15:24:06 +05307259int hdd_mon_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
7260{
7261 return 0;
7262}
7263
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08007264#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08007265/**---------------------------------------------------------------------------
7266
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08007267 \brief hdd_parse_ese_beacon_req() - Parse ese beacon request
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08007268
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08007269 This function parses the ese beacon request passed in the format
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08007270 CCXBEACONREQ<space><Number of fields><space><Measurement token>
7271 <space>Channel 1<space>Scan Mode <space>Meas Duration<space>Channel N
7272 <space>Scan Mode N<space>Meas Duration N
7273 if the Number of bcn req fields (N) does not match with the actual number of fields passed
7274 then take N.
7275 <Meas Token><Channel><Scan Mode> and <Meas Duration> are treated as one pair
7276 For example, CCXBEACONREQ 2 1 1 1 30 2 44 0 40.
7277 This function does not take care of removing duplicate channels from the list
7278
7279 \param - pValue Pointer to data
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08007280 \param - pEseBcnReq output pointer to store parsed ie information
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08007281
7282 \return - 0 for success non-zero for failure
7283
7284 --------------------------------------------------------------------------*/
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08007285static VOS_STATUS hdd_parse_ese_beacon_req(tANI_U8 *pValue,
7286 tCsrEseBeaconReq *pEseBcnReq)
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08007287{
7288 tANI_U8 *inPtr = pValue;
Arun Khandavalli9f3b4832016-06-30 16:58:38 +05307289 uint8_t input = 0;
7290 uint32_t tempInt = 0;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08007291 int j = 0, i = 0, v = 0;
7292 char buf[32];
7293
7294 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
7295 /*no argument after the command*/
7296 if (NULL == inPtr)
7297 {
7298 return -EINVAL;
7299 }
7300 /*no space after the command*/
7301 else if (SPACE_ASCII_VALUE != *inPtr)
7302 {
7303 return -EINVAL;
7304 }
7305
7306 /*removing empty spaces*/
7307 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
7308
7309 /*no argument followed by spaces*/
7310 if ('\0' == *inPtr) return -EINVAL;
7311
7312 /*getting the first argument ie measurement token*/
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08007313 v = sscanf(inPtr, "%31s ", buf);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08007314 if (1 != v) return -EINVAL;
7315
Arun Khandavalli9f3b4832016-06-30 16:58:38 +05307316 v = kstrtos8(buf, 10, &input);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08007317 if ( v < 0) return -EINVAL;
7318
Arun Khandavalli9f3b4832016-06-30 16:58:38 +05307319 input = VOS_MIN(input, SIR_ESE_MAX_MEAS_IE_REQS);
7320 pEseBcnReq->numBcnReqIe = input;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08007321
Srinivas Girigowda725a88e2016-03-31 19:24:25 +05307322 hddLog(LOG1, "Number of Bcn Req Ie fields: %d", pEseBcnReq->numBcnReqIe);
7323
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08007324
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08007325 for (j = 0; j < (pEseBcnReq->numBcnReqIe); j++)
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08007326 {
7327 for (i = 0; i < 4; i++)
7328 {
7329 /*inPtr pointing to the beginning of first space after number of ie fields*/
7330 inPtr = strpbrk( inPtr, " " );
7331 /*no ie data after the number of ie fields argument*/
7332 if (NULL == inPtr) return -EINVAL;
7333
7334 /*removing empty space*/
7335 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
7336
7337 /*no ie data after the number of ie fields argument and spaces*/
7338 if ( '\0' == *inPtr ) return -EINVAL;
7339
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08007340 v = sscanf(inPtr, "%31s ", buf);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08007341 if (1 != v) return -EINVAL;
7342
Arun Khandavalli9f3b4832016-06-30 16:58:38 +05307343 v = kstrtou32(buf, 10, &tempInt);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08007344 if (v < 0) return -EINVAL;
7345
7346 switch (i)
7347 {
7348 case 0: /* Measurement token */
Arun Khandavalli9f3b4832016-06-30 16:58:38 +05307349 if (!tempInt)
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08007350 {
7351 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arun Khandavalli9f3b4832016-06-30 16:58:38 +05307352 "Invalid Measurement Token: %u", tempInt);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08007353 return -EINVAL;
7354 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08007355 pEseBcnReq->bcnReq[j].measurementToken = tempInt;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08007356 break;
7357
7358 case 1: /* Channel number */
Arun Khandavalli9f3b4832016-06-30 16:58:38 +05307359 if ((!tempInt) ||
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08007360 (tempInt > WNI_CFG_CURRENT_CHANNEL_STAMAX))
7361 {
7362 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arun Khandavalli9f3b4832016-06-30 16:58:38 +05307363 "Invalid Channel Number: %u", tempInt);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08007364 return -EINVAL;
7365 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08007366 pEseBcnReq->bcnReq[j].channel = tempInt;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08007367 break;
7368
7369 case 2: /* Scan mode */
Varun Reddy Yeturu0b18d5a2013-12-04 11:42:23 -08007370 if ((tempInt < eSIR_PASSIVE_SCAN) || (tempInt > eSIR_BEACON_TABLE))
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08007371 {
7372 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arun Khandavalli9f3b4832016-06-30 16:58:38 +05307373 "Invalid Scan Mode(%u) Expected{0|1|2}", tempInt);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08007374 return -EINVAL;
7375 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08007376 pEseBcnReq->bcnReq[j].scanMode= tempInt;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08007377 break;
7378
7379 case 3: /* Measurement duration */
Arun Khandavalli9f3b4832016-06-30 16:58:38 +05307380 if (((!tempInt) && (pEseBcnReq->bcnReq[j].scanMode != eSIR_BEACON_TABLE)) ||
7381 ((pEseBcnReq->bcnReq[j].scanMode == eSIR_BEACON_TABLE)))
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08007382 {
7383 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arun Khandavalli9f3b4832016-06-30 16:58:38 +05307384 "Invalid Measurement Duration: %u", tempInt);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08007385 return -EINVAL;
7386 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08007387 pEseBcnReq->bcnReq[j].measurementDuration = tempInt;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08007388 break;
7389 }
7390 }
7391 }
7392
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08007393 for (j = 0; j < pEseBcnReq->numBcnReqIe; j++)
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08007394 {
7395 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Arun Kumar Khandavallie8768212014-02-17 16:43:34 +05307396 "Index(%d) Measurement Token(%u)Channel(%u) Scan Mode(%u) Measurement Duration(%u)\n",
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08007397 j,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08007398 pEseBcnReq->bcnReq[j].measurementToken,
7399 pEseBcnReq->bcnReq[j].channel,
7400 pEseBcnReq->bcnReq[j].scanMode,
7401 pEseBcnReq->bcnReq[j].measurementDuration);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08007402 }
7403
7404 return VOS_STATUS_SUCCESS;
7405}
7406
Hanumanth Reddy Pothula1ceb7032018-04-05 19:35:55 +05307407struct tsm_priv {
7408 tAniTrafStrmMetrics tsm_metrics;
7409};
7410
7411static void hdd_get_tsm_stats_cb(tAniTrafStrmMetrics tsm_metrics,
7412 const tANI_U32 sta_id, void *context )
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07007413{
Hanumanth Reddy Pothula1ceb7032018-04-05 19:35:55 +05307414 struct hdd_request *request;
7415 struct tsm_priv *priv;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07007416
Hanumanth Reddy Pothula1ceb7032018-04-05 19:35:55 +05307417 ENTER();
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07007418
Hanumanth Reddy Pothula1ceb7032018-04-05 19:35:55 +05307419 request = hdd_request_get(context);
7420 if (!request) {
7421 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Obsolete request"));
7422 return;
7423 }
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07007424
Hanumanth Reddy Pothula1ceb7032018-04-05 19:35:55 +05307425 priv = hdd_request_priv(request);
7426 priv->tsm_metrics = tsm_metrics;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07007427
Hanumanth Reddy Pothula1ceb7032018-04-05 19:35:55 +05307428 hdd_request_complete(request);
7429 hdd_request_put(request);
Jeff Johnson72a40512013-12-19 10:14:15 -08007430
Hanumanth Reddy Pothula1ceb7032018-04-05 19:35:55 +05307431 EXIT();
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07007432}
7433
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07007434static VOS_STATUS hdd_get_tsm_stats(hdd_adapter_t *pAdapter, const tANI_U8 tid,
7435 tAniTrafStrmMetrics* pTsmMetrics)
7436{
7437 hdd_station_ctx_t *pHddStaCtx = NULL;
7438 eHalStatus hstatus;
Jeff Johnson72a40512013-12-19 10:14:15 -08007439 VOS_STATUS vstatus = VOS_STATUS_SUCCESS;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07007440 hdd_context_t *pHddCtx = NULL;
Hanumanth Reddy Pothula1ceb7032018-04-05 19:35:55 +05307441 int ret;
7442 void *cookie;
7443 struct hdd_request *request;
7444 struct tsm_priv *priv;
7445 static const struct hdd_request_params params = {
7446 .priv_size = sizeof(*priv),
7447 .timeout_ms = WLAN_WAIT_TIME_STATS,
7448 };
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07007449
7450 if (NULL == pAdapter)
7451 {
7452 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: pAdapter is NULL", __func__);
7453 return VOS_STATUS_E_FAULT;
7454 }
7455
7456 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7457 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7458
Hanumanth Reddy Pothula1ceb7032018-04-05 19:35:55 +05307459 request = hdd_request_alloc(&params);
7460 if (!request) {
7461 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Request allocation failure"));
7462 return VOS_STATUS_E_NOMEM;
7463 }
7464 cookie = hdd_request_cookie(request);
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07007465
7466 /* query tsm stats */
Hanumanth Reddy Pothula1ceb7032018-04-05 19:35:55 +05307467 hstatus = sme_GetTsmStats(pHddCtx->hHal, hdd_get_tsm_stats_cb,
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07007468 pHddStaCtx->conn_info.staId[ 0 ],
7469 pHddStaCtx->conn_info.bssId,
Hanumanth Reddy Pothula1ceb7032018-04-05 19:35:55 +05307470 cookie, pHddCtx->pvosContext, tid);
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07007471
7472 if (eHAL_STATUS_SUCCESS != hstatus)
7473 {
Jeff Johnson72a40512013-12-19 10:14:15 -08007474 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unable to retrieve statistics",
7475 __func__);
7476 vstatus = VOS_STATUS_E_FAULT;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07007477 }
7478 else
7479 {
7480 /* request was sent -- wait for the response */
Hanumanth Reddy Pothula1ceb7032018-04-05 19:35:55 +05307481 ret = hdd_request_wait_for_response(request);
7482 if (ret) {
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07007483 hddLog(VOS_TRACE_LEVEL_ERROR,
Hanumanth Reddy Pothula1ceb7032018-04-05 19:35:55 +05307484 "SME timeout while retrieving statistics");
Jeff Johnson72a40512013-12-19 10:14:15 -08007485 vstatus = VOS_STATUS_E_TIMEOUT;
Hanumanth Reddy Pothula1ceb7032018-04-05 19:35:55 +05307486 } else {
7487 priv = hdd_request_priv(request);
7488 *pTsmMetrics = priv->tsm_metrics;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07007489 }
7490 }
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07007491
Hanumanth Reddy Pothula1ceb7032018-04-05 19:35:55 +05307492 hdd_request_put(request);
Jeff Johnson72a40512013-12-19 10:14:15 -08007493
Jeff Johnson72a40512013-12-19 10:14:15 -08007494 return vstatus;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07007495}
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08007496#endif /*FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07007497
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08007498#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowdade697412013-02-14 16:31:48 -08007499void hdd_getBand_helper(hdd_context_t *pHddCtx, int *pBand)
7500{
7501 eCsrBand band = -1;
7502 sme_GetFreqBand((tHalHandle)(pHddCtx->hHal), &band);
7503 switch (band)
7504 {
7505 case eCSR_BAND_ALL:
7506 *pBand = WLAN_HDD_UI_BAND_AUTO;
7507 break;
7508
7509 case eCSR_BAND_24:
7510 *pBand = WLAN_HDD_UI_BAND_2_4_GHZ;
7511 break;
7512
7513 case eCSR_BAND_5G:
7514 *pBand = WLAN_HDD_UI_BAND_5_GHZ;
7515 break;
7516
7517 default:
7518 hddLog( VOS_TRACE_LEVEL_WARN, "%s: Invalid Band %d", __func__, band);
7519 *pBand = -1;
7520 break;
7521 }
7522}
7523
7524/**---------------------------------------------------------------------------
7525
Srinivas Girigowda100eb322013-03-15 16:48:20 -07007526 \brief hdd_parse_send_action_frame_data() - HDD Parse send action frame data
7527
7528 This function parses the send action frame data passed in the format
7529 SENDACTIONFRAME<space><bssid><space><channel><space><dwelltime><space><data>
7530
Srinivas Girigowda56076852013-08-20 14:00:50 -07007531 \param - pValue Pointer to input data
Srinivas Girigowda100eb322013-03-15 16:48:20 -07007532 \param - pTargetApBssid Pointer to target Ap bssid
7533 \param - pChannel Pointer to the Target AP channel
7534 \param - pDwellTime Pointer to the time to stay off-channel after transmitting action frame
7535 \param - pBuf Pointer to data
7536 \param - pBufLen Pointer to data length
7537
7538 \return - 0 for success non-zero for failure
7539
7540 --------------------------------------------------------------------------*/
7541VOS_STATUS hdd_parse_send_action_frame_data(tANI_U8 *pValue, tANI_U8 *pTargetApBssid, tANI_U8 *pChannel,
7542 tANI_U8 *pDwellTime, tANI_U8 **pBuf, tANI_U8 *pBufLen)
7543{
7544 tANI_U8 *inPtr = pValue;
7545 tANI_U8 *dataEnd;
7546 int tempInt;
7547 int j = 0;
7548 int i = 0;
7549 int v = 0;
7550 tANI_U8 tempBuf[32];
7551 tANI_U8 tempByte = 0;
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08007552 /* 12 hexa decimal digits, 5 ':' and '\0' */
7553 tANI_U8 macAddress[18];
Srinivas Girigowda100eb322013-03-15 16:48:20 -07007554
7555 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
7556 /*no argument after the command*/
7557 if (NULL == inPtr)
7558 {
7559 return -EINVAL;
7560 }
7561
7562 /*no space after the command*/
7563 else if (SPACE_ASCII_VALUE != *inPtr)
7564 {
7565 return -EINVAL;
7566 }
7567
7568 /*removing empty spaces*/
7569 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
7570
7571 /*no argument followed by spaces*/
7572 if ('\0' == *inPtr)
7573 {
7574 return -EINVAL;
7575 }
7576
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07007577 v = sscanf(inPtr, "%17s", macAddress);
7578 if (!((1 == v) && hdd_is_valid_mac_address(macAddress)))
Srinivas Girigowda100eb322013-03-15 16:48:20 -07007579 {
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07007580 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7581 "Invalid MAC address or All hex inputs are not read (%d)", v);
7582 return -EINVAL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07007583 }
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07007584
7585 pTargetApBssid[0] = hdd_parse_hex(macAddress[0]) << 4 | hdd_parse_hex(macAddress[1]);
7586 pTargetApBssid[1] = hdd_parse_hex(macAddress[3]) << 4 | hdd_parse_hex(macAddress[4]);
7587 pTargetApBssid[2] = hdd_parse_hex(macAddress[6]) << 4 | hdd_parse_hex(macAddress[7]);
7588 pTargetApBssid[3] = hdd_parse_hex(macAddress[9]) << 4 | hdd_parse_hex(macAddress[10]);
7589 pTargetApBssid[4] = hdd_parse_hex(macAddress[12]) << 4 | hdd_parse_hex(macAddress[13]);
7590 pTargetApBssid[5] = hdd_parse_hex(macAddress[15]) << 4 | hdd_parse_hex(macAddress[16]);
Srinivas Girigowda100eb322013-03-15 16:48:20 -07007591
7592 /* point to the next argument */
7593 inPtr = strnchr(inPtr, strlen(inPtr), SPACE_ASCII_VALUE);
7594 /*no argument after the command*/
7595 if (NULL == inPtr) return -EINVAL;
7596
7597 /*removing empty spaces*/
7598 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
7599
7600 /*no argument followed by spaces*/
7601 if ('\0' == *inPtr)
7602 {
7603 return -EINVAL;
7604 }
7605
7606 /*getting the next argument ie the channel number */
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08007607 v = sscanf(inPtr, "%31s ", tempBuf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07007608 if (1 != v) return -EINVAL;
7609
Srinivas Girigowda100eb322013-03-15 16:48:20 -07007610 v = kstrtos32(tempBuf, 10, &tempInt);
Agarwal Ashish353b3a82014-04-08 14:55:11 +05307611 if ( v < 0 || tempInt <= 0 || tempInt > WNI_CFG_CURRENT_CHANNEL_STAMAX )
Kiet Lambe150c22013-11-21 16:30:32 +05307612 return -EINVAL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07007613
7614 *pChannel = tempInt;
7615
7616 /* point to the next argument */
7617 inPtr = strnchr(inPtr, strlen(inPtr), SPACE_ASCII_VALUE);
7618 /*no argument after the command*/
7619 if (NULL == inPtr) return -EINVAL;
7620 /*removing empty spaces*/
7621 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
7622
7623 /*no argument followed by spaces*/
7624 if ('\0' == *inPtr)
7625 {
7626 return -EINVAL;
7627 }
7628
7629 /*getting the next argument ie the dwell time */
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08007630 v = sscanf(inPtr, "%31s ", tempBuf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07007631 if (1 != v) return -EINVAL;
7632
Srinivas Girigowda100eb322013-03-15 16:48:20 -07007633 v = kstrtos32(tempBuf, 10, &tempInt);
Srinivas Girigowda5a6e0672014-01-09 14:42:57 -08007634 if ( v < 0 || tempInt < 0) return -EINVAL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07007635
7636 *pDwellTime = tempInt;
7637
7638 /* point to the next argument */
7639 inPtr = strnchr(inPtr, strlen(inPtr), SPACE_ASCII_VALUE);
7640 /*no argument after the command*/
7641 if (NULL == inPtr) return -EINVAL;
7642 /*removing empty spaces*/
7643 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
7644
7645 /*no argument followed by spaces*/
7646 if ('\0' == *inPtr)
7647 {
7648 return -EINVAL;
7649 }
7650
7651 /* find the length of data */
7652 dataEnd = inPtr;
7653 while(('\0' != *dataEnd) )
7654 {
7655 dataEnd++;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07007656 }
Kiet Lambe150c22013-11-21 16:30:32 +05307657 *pBufLen = dataEnd - inPtr ;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07007658 if ( *pBufLen <= 0) return -EINVAL;
7659
Srinivas Girigowdab5ae85d2013-06-03 10:51:45 -07007660 /* Allocate the number of bytes based on the number of input characters
7661 whether it is even or odd.
7662 if the number of input characters are even, then we need N/2 byte.
7663 if the number of input characters are odd, then we need do (N+1)/2 to
7664 compensate rounding off.
7665 For example, if N = 18, then (18 + 1)/2 = 9 bytes are enough.
7666 If N = 19, then we need 10 bytes, hence (19 + 1)/2 = 10 bytes */
7667 *pBuf = vos_mem_malloc((*pBufLen + 1)/2);
Srinivas Girigowda100eb322013-03-15 16:48:20 -07007668 if (NULL == *pBuf)
7669 {
7670 hddLog(VOS_TRACE_LEVEL_FATAL,
7671 "%s: vos_mem_alloc failed ", __func__);
7672 return -EINVAL;
7673 }
7674
7675 /* the buffer received from the upper layer is character buffer,
7676 we need to prepare the buffer taking 2 characters in to a U8 hex decimal number
7677 for example 7f0000f0...form a buffer to contain 7f in 0th location, 00 in 1st
7678 and f0 in 3rd location */
7679 for (i = 0, j = 0; j < *pBufLen; j += 2)
7680 {
Kiet Lambe150c22013-11-21 16:30:32 +05307681 if( j+1 == *pBufLen)
7682 {
7683 tempByte = hdd_parse_hex(inPtr[j]);
7684 }
7685 else
7686 {
7687 tempByte = (hdd_parse_hex(inPtr[j]) << 4) | (hdd_parse_hex(inPtr[j + 1]));
7688 }
Srinivas Girigowda100eb322013-03-15 16:48:20 -07007689 (*pBuf)[i++] = tempByte;
7690 }
7691 *pBufLen = i;
7692 return VOS_STATUS_SUCCESS;
7693}
7694
Srinivas Girigowda100eb322013-03-15 16:48:20 -07007695/**---------------------------------------------------------------------------
7696
Srinivas Girigowdade697412013-02-14 16:31:48 -08007697 \brief hdd_parse_channellist() - HDD Parse channel list
7698
7699 This function parses the channel list passed in the format
7700 SETROAMSCANCHANNELS<space><Number of channels><space>Channel 1<space>Channel 2<space>Channel N
Srinivas Girigowdacf9a9b42013-03-21 11:55:24 -07007701 if the Number of channels (N) does not match with the actual number of channels passed
7702 then take the minimum of N and count of (Ch1, Ch2, ...Ch M)
7703 For example, if SETROAMSCANCHANNELS 3 36 40 44 48, only 36, 40 and 44 shall be taken.
7704 If SETROAMSCANCHANNELS 5 36 40 44 48, ignore 5 and take 36, 40, 44 and 48.
7705 This function does not take care of removing duplicate channels from the list
Srinivas Girigowdade697412013-02-14 16:31:48 -08007706
7707 \param - pValue Pointer to input channel list
7708 \param - ChannelList Pointer to local output array to record channel list
7709 \param - pNumChannels Pointer to number of roam scan channels
7710
7711 \return - 0 for success non-zero for failure
7712
7713 --------------------------------------------------------------------------*/
7714VOS_STATUS hdd_parse_channellist(tANI_U8 *pValue, tANI_U8 *pChannelList, tANI_U8 *pNumChannels)
7715{
7716 tANI_U8 *inPtr = pValue;
7717 int tempInt;
7718 int j = 0;
7719 int v = 0;
7720 char buf[32];
7721
7722 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
7723 /*no argument after the command*/
7724 if (NULL == inPtr)
7725 {
7726 return -EINVAL;
7727 }
7728
7729 /*no space after the command*/
7730 else if (SPACE_ASCII_VALUE != *inPtr)
7731 {
7732 return -EINVAL;
7733 }
7734
7735 /*removing empty spaces*/
Jeff Johnsona1f9afb2013-04-03 09:13:31 -07007736 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
Srinivas Girigowdade697412013-02-14 16:31:48 -08007737
7738 /*no argument followed by spaces*/
7739 if ('\0' == *inPtr)
7740 {
7741 return -EINVAL;
7742 }
7743
7744 /*getting the first argument ie the number of channels*/
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08007745 v = sscanf(inPtr, "%31s ", buf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07007746 if (1 != v) return -EINVAL;
7747
Srinivas Girigowdade697412013-02-14 16:31:48 -08007748 v = kstrtos32(buf, 10, &tempInt);
Jeff Johnsona1f9afb2013-04-03 09:13:31 -07007749 if ((v < 0) ||
7750 (tempInt <= 0) ||
7751 (tempInt > WNI_CFG_VALID_CHANNEL_LIST_LEN))
7752 {
7753 return -EINVAL;
7754 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08007755
7756 *pNumChannels = tempInt;
7757
7758 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
7759 "Number of channels are: %d", *pNumChannels);
7760
7761 for (j = 0; j < (*pNumChannels); j++)
7762 {
7763 /*inPtr pointing to the beginning of first space after number of channels*/
7764 inPtr = strpbrk( inPtr, " " );
7765 /*no channel list after the number of channels argument*/
7766 if (NULL == inPtr)
7767 {
Srinivas Girigowdacf9a9b42013-03-21 11:55:24 -07007768 if (0 != j)
7769 {
7770 *pNumChannels = j;
7771 return VOS_STATUS_SUCCESS;
7772 }
7773 else
7774 {
7775 return -EINVAL;
7776 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08007777 }
7778
7779 /*removing empty space*/
Jeff Johnsona1f9afb2013-04-03 09:13:31 -07007780 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
Srinivas Girigowdade697412013-02-14 16:31:48 -08007781
7782 /*no channel list after the number of channels argument and spaces*/
7783 if ( '\0' == *inPtr )
7784 {
Srinivas Girigowdacf9a9b42013-03-21 11:55:24 -07007785 if (0 != j)
7786 {
7787 *pNumChannels = j;
7788 return VOS_STATUS_SUCCESS;
7789 }
7790 else
7791 {
7792 return -EINVAL;
7793 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08007794 }
7795
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08007796 v = sscanf(inPtr, "%31s ", buf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07007797 if (1 != v) return -EINVAL;
7798
Srinivas Girigowdade697412013-02-14 16:31:48 -08007799 v = kstrtos32(buf, 10, &tempInt);
Jeff Johnsona1f9afb2013-04-03 09:13:31 -07007800 if ((v < 0) ||
7801 (tempInt <= 0) ||
7802 (tempInt > WNI_CFG_CURRENT_CHANNEL_STAMAX))
7803 {
7804 return -EINVAL;
7805 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08007806 pChannelList[j] = tempInt;
7807
7808 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
7809 "Channel %d added to preferred channel list",
7810 pChannelList[j] );
7811 }
7812
Srinivas Girigowdade697412013-02-14 16:31:48 -08007813 return VOS_STATUS_SUCCESS;
7814}
7815
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07007816
Selvaraj, Sridhar5aff1ed2016-06-18 01:26:23 +05307817/**
7818 * hdd_parse_reassoc_command_v1_data() - HDD Parse reassoc command data
7819 * This function parses the reasoc command data passed in the format
7820 * REASSOC<space><bssid><space><channel>
7821 *
7822 * @pValue: Pointer to input data (its a NUL terminated string)
7823 * @pTargetApBssid: Pointer to target Ap bssid
7824 * @pChannel: Pointer to the Target AP channel
7825 *
7826 * Return: 0 for success non-zero for failure
7827 */
7828static int hdd_parse_reassoc_command_v1_data(const tANI_U8 *pValue,
7829 tANI_U8 *pTargetApBssid, tANI_U8 *pChannel)
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07007830{
Selvaraj, Sridhar5aff1ed2016-06-18 01:26:23 +05307831 const tANI_U8 *inPtr = pValue;
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07007832 int tempInt;
7833 int v = 0;
7834 tANI_U8 tempBuf[32];
Kiet Lamaa8e15a2014-02-11 23:30:06 -08007835 /* 12 hexa decimal digits, 5 ':' and '\0' */
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08007836 tANI_U8 macAddress[18];
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07007837
7838 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
7839 /*no argument after the command*/
7840 if (NULL == inPtr)
7841 {
7842 return -EINVAL;
7843 }
7844
7845 /*no space after the command*/
7846 else if (SPACE_ASCII_VALUE != *inPtr)
7847 {
7848 return -EINVAL;
7849 }
7850
7851 /*removing empty spaces*/
7852 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
7853
7854 /*no argument followed by spaces*/
7855 if ('\0' == *inPtr)
7856 {
7857 return -EINVAL;
7858 }
7859
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07007860 v = sscanf(inPtr, "%17s", macAddress);
7861 if (!((1 == v) && hdd_is_valid_mac_address(macAddress)))
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07007862 {
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07007863 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7864 "Invalid MAC address or All hex inputs are not read (%d)", v);
7865 return -EINVAL;
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07007866 }
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07007867
7868 pTargetApBssid[0] = hdd_parse_hex(macAddress[0]) << 4 | hdd_parse_hex(macAddress[1]);
7869 pTargetApBssid[1] = hdd_parse_hex(macAddress[3]) << 4 | hdd_parse_hex(macAddress[4]);
7870 pTargetApBssid[2] = hdd_parse_hex(macAddress[6]) << 4 | hdd_parse_hex(macAddress[7]);
7871 pTargetApBssid[3] = hdd_parse_hex(macAddress[9]) << 4 | hdd_parse_hex(macAddress[10]);
7872 pTargetApBssid[4] = hdd_parse_hex(macAddress[12]) << 4 | hdd_parse_hex(macAddress[13]);
7873 pTargetApBssid[5] = hdd_parse_hex(macAddress[15]) << 4 | hdd_parse_hex(macAddress[16]);
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07007874
7875 /* point to the next argument */
7876 inPtr = strnchr(inPtr, strlen(inPtr), SPACE_ASCII_VALUE);
7877 /*no argument after the command*/
7878 if (NULL == inPtr) return -EINVAL;
7879
7880 /*removing empty spaces*/
7881 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
7882
7883 /*no argument followed by spaces*/
7884 if ('\0' == *inPtr)
7885 {
7886 return -EINVAL;
7887 }
7888
7889 /*getting the next argument ie the channel number */
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08007890 v = sscanf(inPtr, "%31s ", tempBuf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07007891 if (1 != v) return -EINVAL;
7892
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07007893 v = kstrtos32(tempBuf, 10, &tempInt);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07007894 if ((v < 0) ||
Padma, Santhosh Kumar0fa809b2014-11-13 14:56:56 +05307895 (tempInt < 0) ||
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07007896 (tempInt > WNI_CFG_CURRENT_CHANNEL_STAMAX))
7897 {
7898 return -EINVAL;
7899 }
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07007900
7901 *pChannel = tempInt;
7902 return VOS_STATUS_SUCCESS;
7903}
7904
7905#endif
7906
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08007907#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07007908/**---------------------------------------------------------------------------
7909
7910 \brief hdd_parse_get_cckm_ie() - HDD Parse and fetch the CCKM IE
7911
7912 This function parses the SETCCKM IE command
7913 SETCCKMIE<space><ie data>
7914
7915 \param - pValue Pointer to input data
7916 \param - pCckmIe Pointer to output cckm Ie
7917 \param - pCckmIeLen Pointer to output cckm ie length
7918
7919 \return - 0 for success non-zero for failure
7920
7921 --------------------------------------------------------------------------*/
7922VOS_STATUS hdd_parse_get_cckm_ie(tANI_U8 *pValue, tANI_U8 **pCckmIe,
7923 tANI_U8 *pCckmIeLen)
7924{
7925 tANI_U8 *inPtr = pValue;
7926 tANI_U8 *dataEnd;
7927 int j = 0;
7928 int i = 0;
7929 tANI_U8 tempByte = 0;
7930
7931 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
7932 /*no argument after the command*/
7933 if (NULL == inPtr)
7934 {
7935 return -EINVAL;
7936 }
7937
7938 /*no space after the command*/
7939 else if (SPACE_ASCII_VALUE != *inPtr)
7940 {
7941 return -EINVAL;
7942 }
7943
7944 /*removing empty spaces*/
7945 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
7946
7947 /*no argument followed by spaces*/
7948 if ('\0' == *inPtr)
7949 {
7950 return -EINVAL;
7951 }
7952
7953 /* find the length of data */
7954 dataEnd = inPtr;
7955 while(('\0' != *dataEnd) )
7956 {
7957 dataEnd++;
7958 ++(*pCckmIeLen);
7959 }
7960 if ( *pCckmIeLen <= 0) return -EINVAL;
7961
7962 /* Allocate the number of bytes based on the number of input characters
7963 whether it is even or odd.
7964 if the number of input characters are even, then we need N/2 byte.
7965 if the number of input characters are odd, then we need do (N+1)/2 to
7966 compensate rounding off.
7967 For example, if N = 18, then (18 + 1)/2 = 9 bytes are enough.
7968 If N = 19, then we need 10 bytes, hence (19 + 1)/2 = 10 bytes */
7969 *pCckmIe = vos_mem_malloc((*pCckmIeLen + 1)/2);
7970 if (NULL == *pCckmIe)
7971 {
7972 hddLog(VOS_TRACE_LEVEL_FATAL,
7973 "%s: vos_mem_alloc failed ", __func__);
7974 return -EINVAL;
7975 }
7976 vos_mem_zero(*pCckmIe, (*pCckmIeLen + 1)/2);
7977 /* the buffer received from the upper layer is character buffer,
7978 we need to prepare the buffer taking 2 characters in to a U8 hex decimal number
7979 for example 7f0000f0...form a buffer to contain 7f in 0th location, 00 in 1st
7980 and f0 in 3rd location */
7981 for (i = 0, j = 0; j < *pCckmIeLen; j += 2)
7982 {
7983 tempByte = (hdd_parse_hex(inPtr[j]) << 4) | (hdd_parse_hex(inPtr[j + 1]));
7984 (*pCckmIe)[i++] = tempByte;
7985 }
7986 *pCckmIeLen = i;
7987
7988 return VOS_STATUS_SUCCESS;
7989}
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08007990#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07007991
Jeff Johnson295189b2012-06-20 16:38:30 -07007992/**---------------------------------------------------------------------------
7993
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07007994 \brief hdd_is_valid_mac_address() - Validate MAC address
7995
7996 This function validates whether the given MAC address is valid or not
7997 Expected MAC address is of the format XX:XX:XX:XX:XX:XX
7998 where X is the hexa decimal digit character and separated by ':'
7999 This algorithm works even if MAC address is not separated by ':'
8000
8001 This code checks given input string mac contains exactly 12 hexadecimal digits.
8002 and a separator colon : appears in the input string only after
8003 an even number of hex digits.
8004
8005 \param - pMacAddr pointer to the input MAC address
8006 \return - 1 for valid and 0 for invalid
8007
8008 --------------------------------------------------------------------------*/
8009
8010v_BOOL_t hdd_is_valid_mac_address(const tANI_U8 *pMacAddr)
8011{
8012 int xdigit = 0;
8013 int separator = 0;
8014 while (*pMacAddr)
8015 {
8016 if (isxdigit(*pMacAddr))
8017 {
8018 xdigit++;
8019 }
8020 else if (':' == *pMacAddr)
8021 {
8022 if (0 == xdigit || ((xdigit / 2) - 1) != separator)
8023 break;
8024
8025 ++separator;
8026 }
8027 else
8028 {
8029 separator = -1;
8030 /* Invalid MAC found */
8031 return 0;
8032 }
8033 ++pMacAddr;
8034 }
8035 return (xdigit == 12 && (separator == 5 || separator == 0));
8036}
8037
8038/**---------------------------------------------------------------------------
8039
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05308040 \brief __hdd_open() - HDD Open function
Jeff Johnson295189b2012-06-20 16:38:30 -07008041
8042 \param - dev Pointer to net_device structure
8043
8044 \return - 0 for success non-zero for failure
8045
8046 --------------------------------------------------------------------------*/
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05308047int __hdd_open(struct net_device *dev)
Jeff Johnson295189b2012-06-20 16:38:30 -07008048{
8049 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
8050 hdd_context_t *pHddCtx;
8051 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
8052 VOS_STATUS status;
8053 v_BOOL_t in_standby = TRUE;
8054
8055 if (NULL == pAdapter)
8056 {
8057 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Agarwal Ashish971c2882013-10-30 20:11:12 +05308058 "%s: pAdapter is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07008059 return -ENODEV;
8060 }
8061
8062 pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05308063 MTRACE(vos_trace(VOS_MODULE_ID_HDD, TRACE_CODE_HDD_OPEN_REQUEST,
8064 pAdapter->sessionId, pAdapter->device_mode));
Jeff Johnson295189b2012-06-20 16:38:30 -07008065 if (NULL == pHddCtx)
8066 {
8067 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008068 "%s: HDD context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07008069 return -ENODEV;
8070 }
8071
8072 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
8073 while ( (NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status) )
8074 {
Jeff Johnson6a81ca42013-04-05 10:37:08 -07008075 if (test_bit(DEVICE_IFACE_OPENED, &pAdapterNode->pAdapter->event_flags))
8076 {
8077 hddLog(VOS_TRACE_LEVEL_INFO, "%s: chip already out of standby",
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05308078 __func__);
Jeff Johnson6a81ca42013-04-05 10:37:08 -07008079 in_standby = FALSE;
8080 break;
8081 }
8082 else
8083 {
8084 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
8085 pAdapterNode = pNext;
8086 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008087 }
8088
8089 if (TRUE == in_standby)
8090 {
8091 if (VOS_STATUS_SUCCESS != wlan_hdd_exit_lowpower(pHddCtx, pAdapter))
8092 {
8093 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Failed to bring "
8094 "wlan out of power save", __func__);
8095 return -EINVAL;
8096 }
8097 }
louisliu462edac2020-06-30 13:33:56 +08008098
Jeff Johnson6a81ca42013-04-05 10:37:08 -07008099 set_bit(DEVICE_IFACE_OPENED, &pAdapter->event_flags);
Jeff Johnson295189b2012-06-20 16:38:30 -07008100 if (hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter)))
8101 {
8102 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008103 "%s: Enabling Tx Queues", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07008104 /* Enable TX queues only when we are connected */
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +05308105 hddLog(VOS_TRACE_LEVEL_INFO, FL("Enabling queues"));
Jeff Johnson295189b2012-06-20 16:38:30 -07008106 netif_tx_start_all_queues(dev);
8107 }
8108
8109 return 0;
8110}
8111
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05308112/**---------------------------------------------------------------------------
8113
8114 \brief hdd_open() - Wrapper function for __hdd_open to protect it from SSR
8115
8116 This is called in response to ifconfig up
8117
8118 \param - dev Pointer to net_device structure
8119
8120 \return - 0 for success non-zero for failure
8121
8122 --------------------------------------------------------------------------*/
8123int hdd_open(struct net_device *dev)
8124{
8125 int ret;
8126
8127 vos_ssr_protect(__func__);
8128 ret = __hdd_open(dev);
8129 vos_ssr_unprotect(__func__);
8130
8131 return ret;
8132}
8133
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05308134int __hdd_mon_open (struct net_device *dev)
Jeff Johnson295189b2012-06-20 16:38:30 -07008135{
8136 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +05308137 hdd_adapter_t *sta_adapter;
8138 hdd_context_t *hdd_ctx;
Jeff Johnson295189b2012-06-20 16:38:30 -07008139
8140 if(pAdapter == NULL) {
8141 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008142 "%s: HDD adapter context is Null", __func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08008143 return -EINVAL;
Jeff Johnson295189b2012-06-20 16:38:30 -07008144 }
8145
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +05308146 if (vos_get_concurrency_mode() != VOS_STA_MON)
8147 return 0;
8148
8149 hdd_ctx = WLAN_HDD_GET_CTX(pAdapter);
8150 if (wlan_hdd_validate_context(hdd_ctx))
8151 return -EINVAL;
8152
8153 sta_adapter = hdd_get_adapter(hdd_ctx, WLAN_HDD_INFRA_STATION);
8154 if (!sta_adapter) {
8155 hddLog(LOGE, FL("No valid STA interface"));
8156 return -EINVAL;
8157 }
8158
8159 if (!test_bit(DEVICE_IFACE_OPENED, &sta_adapter->event_flags)) {
8160 hddLog(LOGE, FL("STA Interface is not OPENED"));
8161 return -EINVAL;
8162 }
8163
8164 set_bit(DEVICE_IFACE_OPENED, &pAdapter->event_flags);
8165
Jeff Johnson295189b2012-06-20 16:38:30 -07008166 return 0;
8167}
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05308168
8169int hdd_mon_open (struct net_device *dev)
8170{
8171 int ret;
8172
8173 vos_ssr_protect(__func__);
8174 ret = __hdd_mon_open(dev);
8175 vos_ssr_unprotect(__func__);
8176
8177 return ret;
8178}
8179
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +05308180int __hdd_mon_stop (struct net_device *dev)
8181{
8182 hdd_adapter_t *mon_adapter = WLAN_HDD_GET_PRIV_PTR(dev);
8183 hdd_context_t *hdd_ctx;
8184
8185 if (vos_get_concurrency_mode() != VOS_STA_MON)
8186 return 0;
8187
8188 if(!mon_adapter) {
8189 hddLog(LOGE, FL("HDD adapter is Null"));
8190 return -EINVAL;
8191 }
8192
8193 hdd_ctx = WLAN_HDD_GET_CTX(mon_adapter);
8194 if (wlan_hdd_validate_context(hdd_ctx))
8195 return -EINVAL;
8196
8197 if (!test_bit(DEVICE_IFACE_OPENED, &mon_adapter->event_flags)) {
8198 hddLog(LOGE, FL("NETDEV Interface is not OPENED"));
8199 return -ENODEV;
8200 }
8201
8202 clear_bit(DEVICE_IFACE_OPENED, &mon_adapter->event_flags);
8203 hdd_stop_adapter(hdd_ctx, mon_adapter, VOS_FALSE);
8204
8205 return 0;
8206}
8207
Katya Nigame7b69a82015-04-28 15:24:06 +05308208int hdd_mon_stop(struct net_device *dev)
8209{
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +05308210 int ret;
8211
8212 vos_ssr_protect(__func__);
8213 ret = __hdd_mon_stop(dev);
8214 vos_ssr_unprotect(__func__);
8215
8216 return ret;
Katya Nigame7b69a82015-04-28 15:24:06 +05308217}
8218
Jeff Johnson295189b2012-06-20 16:38:30 -07008219/**---------------------------------------------------------------------------
8220
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05308221 \brief __hdd_stop() - HDD stop function
Jeff Johnson295189b2012-06-20 16:38:30 -07008222
8223 \param - dev Pointer to net_device structure
8224
8225 \return - 0 for success non-zero for failure
8226
8227 --------------------------------------------------------------------------*/
8228
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05308229int __hdd_stop (struct net_device *dev)
Jeff Johnson295189b2012-06-20 16:38:30 -07008230{
Vinay Krishna Eranna90f43532014-10-27 16:45:54 +05308231 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07008232 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
8233 hdd_context_t *pHddCtx;
8234 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
8235 VOS_STATUS status;
8236 v_BOOL_t enter_standby = TRUE;
8237
8238 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07008239 if (NULL == pAdapter)
8240 {
8241 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Agarwal Ashish971c2882013-10-30 20:11:12 +05308242 "%s: pAdapter is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07008243 return -ENODEV;
8244 }
Sachin Ahuja9b4958f2015-01-15 21:37:00 +05308245 MTRACE(vos_trace(VOS_MODULE_ID_HDD, TRACE_CODE_HDD_STOP_REQUEST,
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05308246 pAdapter->sessionId, pAdapter->device_mode));
Vinay Krishna Eranna90f43532014-10-27 16:45:54 +05308247
8248 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8249 ret = wlan_hdd_validate_context(pHddCtx);
8250 if (ret)
Jeff Johnson295189b2012-06-20 16:38:30 -07008251 {
Vinay Krishna Eranna90f43532014-10-27 16:45:54 +05308252 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07008253 }
8254
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05308255 /* Nothing to be done if the interface is not opened */
8256 if (VOS_FALSE == test_bit(DEVICE_IFACE_OPENED, &pAdapter->event_flags))
8257 {
8258 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8259 "%s: NETDEV Interface is not OPENED", __func__);
8260 return -ENODEV;
8261 }
8262
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +05308263 if (pHddCtx->concurrency_mode == VOS_STA_MON) {
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +05308264 /*
Rajeev Kumar Sirasanagandlaa74e1222018-01-09 17:38:55 +05308265 * In STA + Monitor mode concurrency, no point in running
8266 * capture on monitor interface, when STA interface is stopped
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +05308267 */
Rajeev Kumar Sirasanagandlaa74e1222018-01-09 17:38:55 +05308268 wlan_hdd_stop_mon(pHddCtx, true);
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +05308269 }
8270
louisliu462edac2020-06-30 13:33:56 +08008271 /* Make sure the interface is marked as closed */
8272 clear_bit(DEVICE_IFACE_OPENED, &pAdapter->event_flags);
Jeff Johnson295189b2012-06-20 16:38:30 -07008273 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Disabling OS Tx queues", __func__);
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05308274
8275 /* Disable TX on the interface, after this hard_start_xmit() will not
8276 * be called on that interface
8277 */
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +05308278 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Jeff Johnson295189b2012-06-20 16:38:30 -07008279 netif_tx_disable(pAdapter->dev);
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05308280
8281 /* Mark the interface status as "down" for outside world */
Jeff Johnson295189b2012-06-20 16:38:30 -07008282 netif_carrier_off(pAdapter->dev);
8283
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05308284 /* The interface is marked as down for outside world (aka kernel)
8285 * But the driver is pretty much alive inside. The driver needs to
8286 * tear down the existing connection on the netdev (session)
8287 * cleanup the data pipes and wait until the control plane is stabilized
8288 * for this interface. The call also needs to wait until the above
8289 * mentioned actions are completed before returning to the caller.
8290 * Notice that the hdd_stop_adapter is requested not to close the session
8291 * That is intentional to be able to scan if it is a STA/P2P interface
8292 */
louisliu462edac2020-06-30 13:33:56 +08008293 hdd_stop_adapter(pHddCtx, pAdapter, VOS_FALSE);
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05308294#ifdef FEATURE_WLAN_TDLS
8295 mutex_lock(&pHddCtx->tdls_lock);
8296#endif
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05308297 /* DeInit the adapter. This ensures datapath cleanup as well */
c_hpothu002231a2015-02-05 14:58:51 +05308298 hdd_deinit_adapter(pHddCtx, pAdapter, TRUE);
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05308299#ifdef FEATURE_WLAN_TDLS
8300 mutex_unlock(&pHddCtx->tdls_lock);
8301#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008302 /* SoftAP ifaces should never go in power save mode
8303 making sure same here. */
8304 if ( (WLAN_HDD_SOFTAP == pAdapter->device_mode )
Jeff Johnson295189b2012-06-20 16:38:30 -07008305 || (WLAN_HDD_P2P_GO == pAdapter->device_mode )
Jeff Johnson295189b2012-06-20 16:38:30 -07008306 )
8307 {
8308 /* SoftAP mode, so return from here */
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308309 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8310 "%s: In SAP MODE", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07008311 EXIT();
8312 return 0;
8313 }
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05308314 /* Find if any iface is up. If any iface is up then can't put device to
8315 * sleep/power save mode
8316 */
Jeff Johnson295189b2012-06-20 16:38:30 -07008317 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
8318 while ( (NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status) )
8319 {
Jeff Johnson6a81ca42013-04-05 10:37:08 -07008320 if (test_bit(DEVICE_IFACE_OPENED, &pAdapterNode->pAdapter->event_flags))
8321 {
8322 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Still other ifaces are up cannot "
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05308323 "put device to sleep", __func__);
Jeff Johnson6a81ca42013-04-05 10:37:08 -07008324 enter_standby = FALSE;
8325 break;
8326 }
8327 else
8328 {
8329 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
8330 pAdapterNode = pNext;
8331 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008332 }
8333
8334 if (TRUE == enter_standby)
8335 {
8336 hddLog(VOS_TRACE_LEVEL_INFO, "%s: All Interfaces are Down "
8337 "entering standby", __func__);
8338 if (VOS_STATUS_SUCCESS != wlan_hdd_enter_lowpower(pHddCtx))
8339 {
8340 /*log and return success*/
8341 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Failed to put "
8342 "wlan in power save", __func__);
8343 }
8344 }
Hanumanth Reddy Pothula972e1df2018-06-14 13:33:47 +05308345
8346 /*
8347 * Upon wifi turn off, DUT has to flush the scan results so if
8348 * this is the last cli iface, flush the scan database.
8349 */
8350 if (!hdd_is_cli_iface_up(pHddCtx))
8351 sme_ScanFlushResult(pHddCtx->hHal, 0);
louisliu462edac2020-06-30 13:33:56 +08008352
Jeff Johnson295189b2012-06-20 16:38:30 -07008353 EXIT();
8354 return 0;
8355}
8356
8357/**---------------------------------------------------------------------------
8358
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05308359 \brief hdd_stop() - wrapper_function for __hdd_stop to protect it from SSR
Jeff Johnson295189b2012-06-20 16:38:30 -07008360
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05308361 This is called in response to ifconfig down
8362
8363 \param - dev Pointer to net_device structure
8364
8365 \return - 0 for success non-zero for failure
8366-----------------------------------------------------------------------------*/
8367int hdd_stop (struct net_device *dev)
8368{
8369 int ret;
8370
8371 vos_ssr_protect(__func__);
8372 ret = __hdd_stop(dev);
8373 vos_ssr_unprotect(__func__);
8374
8375 return ret;
8376}
8377
8378/**---------------------------------------------------------------------------
8379
8380 \brief __hdd_uninit() - HDD uninit function
Jeff Johnson295189b2012-06-20 16:38:30 -07008381
8382 \param - dev Pointer to net_device structure
8383
8384 \return - void
8385
8386 --------------------------------------------------------------------------*/
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05308387static void __hdd_uninit (struct net_device *dev)
Jeff Johnson295189b2012-06-20 16:38:30 -07008388{
8389 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05308390 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07008391 ENTER();
8392
8393 do
8394 {
8395 if (NULL == pAdapter)
8396 {
8397 hddLog(VOS_TRACE_LEVEL_FATAL,
8398 "%s: NULL pAdapter", __func__);
8399 break;
8400 }
8401
8402 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
8403 {
8404 hddLog(VOS_TRACE_LEVEL_FATAL,
8405 "%s: Invalid magic", __func__);
8406 break;
8407 }
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05308408 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8409 if (NULL == pHddCtx)
Jeff Johnson295189b2012-06-20 16:38:30 -07008410 {
8411 hddLog(VOS_TRACE_LEVEL_FATAL,
8412 "%s: NULL pHddCtx", __func__);
8413 break;
8414 }
8415
8416 if (dev != pAdapter->dev)
8417 {
8418 hddLog(VOS_TRACE_LEVEL_FATAL,
8419 "%s: Invalid device reference", __func__);
8420 /* we haven't validated all cases so let this go for now */
8421 }
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05308422#ifdef FEATURE_WLAN_TDLS
8423 mutex_lock(&pHddCtx->tdls_lock);
8424#endif
c_hpothu002231a2015-02-05 14:58:51 +05308425 hdd_deinit_adapter(pHddCtx, pAdapter, TRUE);
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05308426#ifdef FEATURE_WLAN_TDLS
8427 mutex_unlock(&pHddCtx->tdls_lock);
8428#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008429
8430 /* after uninit our adapter structure will no longer be valid */
8431 pAdapter->dev = NULL;
8432 pAdapter->magic = 0;
Manjeet Singh47ee8472016-04-11 11:57:18 +05308433 pAdapter->pHddCtx = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07008434 } while (0);
8435
8436 EXIT();
8437}
8438
8439/**---------------------------------------------------------------------------
8440
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05308441 \brief hdd_uninit() - Wrapper function to protect __hdd_uninit from SSR
8442
8443 This is called during the netdev unregister to uninitialize all data
8444associated with the device
8445
8446 \param - dev Pointer to net_device structure
8447
8448 \return - void
8449
8450 --------------------------------------------------------------------------*/
8451static void hdd_uninit (struct net_device *dev)
8452{
8453 vos_ssr_protect(__func__);
8454 __hdd_uninit(dev);
8455 vos_ssr_unprotect(__func__);
8456}
8457
8458/**---------------------------------------------------------------------------
8459
Jeff Johnson295189b2012-06-20 16:38:30 -07008460 \brief hdd_release_firmware() -
8461
8462 This function calls the release firmware API to free the firmware buffer.
8463
8464 \param - pFileName Pointer to the File Name.
8465 pCtx - Pointer to the adapter .
8466
8467
8468 \return - 0 for success, non zero for failure
8469
8470 --------------------------------------------------------------------------*/
8471
8472VOS_STATUS hdd_release_firmware(char *pFileName,v_VOID_t *pCtx)
8473{
8474 VOS_STATUS status = VOS_STATUS_SUCCESS;
8475 hdd_context_t *pHddCtx = (hdd_context_t*)pCtx;
8476 ENTER();
8477
8478
8479 if (!strcmp(WLAN_FW_FILE, pFileName)) {
8480
8481 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,"%s: Loaded firmware file is %s",__func__,pFileName);
8482
8483 if(pHddCtx->fw) {
8484 release_firmware(pHddCtx->fw);
8485 pHddCtx->fw = NULL;
8486 }
8487 else
8488 status = VOS_STATUS_E_FAILURE;
8489 }
8490 else if (!strcmp(WLAN_NV_FILE,pFileName)) {
8491 if(pHddCtx->nv) {
8492 release_firmware(pHddCtx->nv);
8493 pHddCtx->nv = NULL;
8494 }
8495 else
8496 status = VOS_STATUS_E_FAILURE;
8497
8498 }
8499
8500 EXIT();
8501 return status;
8502}
8503
8504/**---------------------------------------------------------------------------
8505
8506 \brief hdd_request_firmware() -
8507
8508 This function reads the firmware file using the request firmware
8509 API and returns the the firmware data and the firmware file size.
8510
8511 \param - pfileName - Pointer to the file name.
8512 - pCtx - Pointer to the adapter .
8513 - ppfw_data - Pointer to the pointer of the firmware data.
8514 - pSize - Pointer to the file size.
8515
8516 \return - VOS_STATUS_SUCCESS for success, VOS_STATUS_E_FAILURE for failure
8517
8518 --------------------------------------------------------------------------*/
8519
8520
8521VOS_STATUS hdd_request_firmware(char *pfileName,v_VOID_t *pCtx,v_VOID_t **ppfw_data, v_SIZE_t *pSize)
8522{
8523 int status;
8524 VOS_STATUS retval = VOS_STATUS_SUCCESS;
8525 hdd_context_t *pHddCtx = (hdd_context_t*)pCtx;
8526 ENTER();
8527
8528 if( (!strcmp(WLAN_FW_FILE, pfileName)) ) {
8529
8530 status = request_firmware(&pHddCtx->fw, pfileName, pHddCtx->parent_dev);
8531
8532 if(status || !pHddCtx->fw || !pHddCtx->fw->data) {
8533 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Firmware %s download failed",
8534 __func__, pfileName);
8535 retval = VOS_STATUS_E_FAILURE;
8536 }
8537
8538 else {
8539 *ppfw_data = (v_VOID_t *)pHddCtx->fw->data;
8540 *pSize = pHddCtx->fw->size;
8541 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Firmware size = %d",
8542 __func__, *pSize);
8543 }
8544 }
8545 else if(!strcmp(WLAN_NV_FILE, pfileName)) {
8546
8547 status = request_firmware(&pHddCtx->nv, pfileName, pHddCtx->parent_dev);
8548
8549 if(status || !pHddCtx->nv || !pHddCtx->nv->data) {
8550 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: nv %s download failed",
8551 __func__, pfileName);
8552 retval = VOS_STATUS_E_FAILURE;
8553 }
8554
8555 else {
8556 *ppfw_data = (v_VOID_t *)pHddCtx->nv->data;
8557 *pSize = pHddCtx->nv->size;
8558 hddLog(VOS_TRACE_LEVEL_INFO, "%s: nv file size = %d",
8559 __func__, *pSize);
8560 }
8561 }
8562
8563 EXIT();
8564 return retval;
8565}
8566/**---------------------------------------------------------------------------
8567 \brief hdd_full_pwr_cbk() - HDD full power callbackfunction
8568
8569 This is the function invoked by SME to inform the result of a full power
8570 request issued by HDD
8571
8572 \param - callbackcontext - Pointer to cookie
8573 status - result of request
8574
8575 \return - None
8576
8577--------------------------------------------------------------------------*/
8578void hdd_full_pwr_cbk(void *callbackContext, eHalStatus status)
8579{
8580 hdd_context_t *pHddCtx = (hdd_context_t*)callbackContext;
8581
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07008582 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,"HDD full Power callback status = %d", status);
Jeff Johnson295189b2012-06-20 16:38:30 -07008583 if(&pHddCtx->full_pwr_comp_var)
8584 {
8585 complete(&pHddCtx->full_pwr_comp_var);
8586 }
8587}
8588
Abhishek Singh00b71972016-01-07 10:51:04 +05308589#ifdef WLAN_FEATURE_RMC
8590static void hdd_tx_fail_ind_callback(v_U8_t *MacAddr, v_U8_t seqNo)
8591{
8592 int payload_len;
8593 struct sk_buff *skb;
8594 struct nlmsghdr *nlh;
8595 v_U8_t *data;
8596
8597 payload_len = ETH_ALEN;
8598
8599 if (0 == cesium_pid)
8600 {
8601 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: cesium process not registered",
8602 __func__);
8603 return;
8604 }
8605
8606 if ((skb = nlmsg_new(payload_len,GFP_ATOMIC)) == NULL)
8607 {
8608 hddLog(VOS_TRACE_LEVEL_ERROR,
8609 "%s: nlmsg_new() failed for msg size[%d]",
8610 __func__, NLMSG_SPACE(payload_len));
8611 return;
8612 }
8613
8614 nlh = nlmsg_put(skb, cesium_pid, seqNo, 0, payload_len, NLM_F_REQUEST);
8615
8616 if (NULL == nlh)
8617 {
8618 hddLog(VOS_TRACE_LEVEL_ERROR,
8619 "%s: nlmsg_put() failed for msg size[%d]",
8620 __func__, NLMSG_SPACE(payload_len));
8621
8622 kfree_skb(skb);
8623 return;
8624 }
8625
8626 data = nlmsg_data(nlh);
8627 memcpy(data, MacAddr, ETH_ALEN);
8628
8629 if (nlmsg_unicast(cesium_nl_srv_sock, skb, cesium_pid) < 0)
8630 {
8631 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: nlmsg_unicast() failed for msg size[%d]",
8632 __func__, NLMSG_SPACE(payload_len));
8633 }
8634
8635 return;
8636}
8637
8638/**---------------------------------------------------------------------------
8639 \brief hdd_ParseuserParams - return a pointer to the next argument
8640
8641 \return - status
8642
8643--------------------------------------------------------------------------*/
8644static int hdd_ParseUserParams(tANI_U8 *pValue, tANI_U8 **ppArg)
8645{
8646 tANI_U8 *pVal;
8647
8648 pVal = strchr(pValue, ' ');
8649
8650 if (NULL == pVal)
8651 {
8652 /* no argument remains */
8653 return -EINVAL;
8654 }
8655 else if (SPACE_ASCII_VALUE != *pVal)
8656 {
8657 /* no space after the current argument */
8658 return -EINVAL;
8659 }
8660
8661 pVal++;
8662
8663 /* remove empty spaces */
8664 while ((SPACE_ASCII_VALUE == *pVal) && ('\0' != *pVal))
8665 {
8666 pVal++;
8667 }
8668
8669 /* no argument followed by spaces */
8670 if ('\0' == *pVal)
8671 {
8672 return -EINVAL;
8673 }
8674
8675 *ppArg = pVal;
8676
8677 return 0;
8678}
8679
8680/**----------------------------------------------------------------------------
8681 \brief hdd_ParseIBSSTXFailEventParams - Parse params for SETIBSSTXFAILEVENT
8682
8683 \return - status
8684
8685------------------------------------------------------------------------------*/
8686static int hdd_ParseIBSSTXFailEventParams(tANI_U8 *pValue,
8687 tANI_U8 *tx_fail_count,
8688 tANI_U16 *pid)
8689{
8690 tANI_U8 *param = NULL;
8691 int ret;
8692
8693 ret = hdd_ParseUserParams(pValue, &param);
8694
8695 if (0 == ret && NULL != param)
8696 {
8697 if (1 != sscanf(param, "%hhu", tx_fail_count))
8698 {
8699 ret = -EINVAL;
8700 goto done;
8701 }
8702 }
8703 else
8704 {
8705 goto done;
8706 }
8707
8708 if (0 == *tx_fail_count)
8709 {
8710 *pid = 0;
8711 goto done;
8712 }
8713
8714 pValue = param;
8715 pValue++;
8716
8717 ret = hdd_ParseUserParams(pValue, &param);
8718
8719 if (0 == ret)
8720 {
8721 if (1 != sscanf(param, "%hu", pid))
8722 {
8723 ret = -EINVAL;
8724 goto done;
8725 }
8726 }
8727 else
8728 {
8729 goto done;
8730 }
8731
8732done:
8733 return ret;
8734}
8735
8736static int hdd_open_cesium_nl_sock()
8737{
8738#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
8739 struct netlink_kernel_cfg cfg = {
8740 .groups = WLAN_NLINK_MCAST_GRP_ID,
8741 .input = NULL
8742 };
8743#endif
8744 int ret = 0;
8745
8746#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
8747 cesium_nl_srv_sock = netlink_kernel_create(&init_net, WLAN_NLINK_CESIUM,
8748#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,7,0))
8749 THIS_MODULE,
8750#endif
8751 &cfg);
8752#else
8753 cesium_nl_srv_sock = netlink_kernel_create(&init_net, WLAN_NLINK_CESIUM,
8754 WLAN_NLINK_MCAST_GRP_ID, NULL, NULL, THIS_MODULE);
8755#endif
8756
8757 if (cesium_nl_srv_sock == NULL)
8758 {
8759 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8760 "NLINK: cesium netlink_kernel_create failed");
8761 ret = -ECONNREFUSED;
8762 }
8763
8764 return ret;
8765}
8766
8767static void hdd_close_cesium_nl_sock()
8768{
8769 if (NULL != cesium_nl_srv_sock)
8770 {
8771 netlink_kernel_release(cesium_nl_srv_sock);
8772 cesium_nl_srv_sock = NULL;
8773 }
8774}
8775#endif /* WLAN_FEATURE_RMC */
Jeff Johnson295189b2012-06-20 16:38:30 -07008776/**---------------------------------------------------------------------------
8777
8778 \brief hdd_req_bmps_cbk() - HDD Request BMPS callback function
8779
8780 This is the function invoked by SME to inform the result of BMPS
8781 request issued by HDD
8782
8783 \param - callbackcontext - Pointer to cookie
8784 status - result of request
8785
8786 \return - None
8787
8788--------------------------------------------------------------------------*/
8789void hdd_req_bmps_cbk(void *callbackContext, eHalStatus status)
8790{
8791
8792 struct completion *completion_var = (struct completion*) callbackContext;
8793
Arif Hussain6d2a3322013-11-17 19:50:10 -08008794 hddLog(VOS_TRACE_LEVEL_ERROR, "HDD BMPS request Callback, status = %d", status);
Jeff Johnson295189b2012-06-20 16:38:30 -07008795 if(completion_var != NULL)
8796 {
8797 complete(completion_var);
8798 }
8799}
8800
8801/**---------------------------------------------------------------------------
8802
8803 \brief hdd_get_cfg_file_size() -
8804
8805 This function reads the configuration file using the request firmware
8806 API and returns the configuration file size.
8807
8808 \param - pCtx - Pointer to the adapter .
8809 - pFileName - Pointer to the file name.
8810 - pBufSize - Pointer to the buffer size.
8811
8812 \return - 0 for success, non zero for failure
8813
8814 --------------------------------------------------------------------------*/
8815
8816VOS_STATUS hdd_get_cfg_file_size(v_VOID_t *pCtx, char *pFileName, v_SIZE_t *pBufSize)
8817{
8818 int status;
8819 hdd_context_t *pHddCtx = (hdd_context_t*)pCtx;
8820
8821 ENTER();
8822
8823 status = request_firmware(&pHddCtx->fw, pFileName, pHddCtx->parent_dev);
8824
8825 if(status || !pHddCtx->fw || !pHddCtx->fw->data) {
8826 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: CFG download failed",__func__);
8827 status = VOS_STATUS_E_FAILURE;
8828 }
8829 else {
8830 *pBufSize = pHddCtx->fw->size;
8831 hddLog(VOS_TRACE_LEVEL_INFO, "%s: CFG size = %d", __func__, *pBufSize);
8832 release_firmware(pHddCtx->fw);
8833 pHddCtx->fw = NULL;
8834 }
8835
8836 EXIT();
8837 return VOS_STATUS_SUCCESS;
8838}
8839
8840/**---------------------------------------------------------------------------
8841
8842 \brief hdd_read_cfg_file() -
8843
8844 This function reads the configuration file using the request firmware
8845 API and returns the cfg data and the buffer size of the configuration file.
8846
8847 \param - pCtx - Pointer to the adapter .
8848 - pFileName - Pointer to the file name.
8849 - pBuffer - Pointer to the data buffer.
8850 - pBufSize - Pointer to the buffer size.
8851
8852 \return - 0 for success, non zero for failure
8853
8854 --------------------------------------------------------------------------*/
8855
8856VOS_STATUS hdd_read_cfg_file(v_VOID_t *pCtx, char *pFileName,
8857 v_VOID_t *pBuffer, v_SIZE_t *pBufSize)
8858{
8859 int status;
8860 hdd_context_t *pHddCtx = (hdd_context_t*)pCtx;
8861
8862 ENTER();
8863
8864 status = request_firmware(&pHddCtx->fw, pFileName, pHddCtx->parent_dev);
8865
8866 if(status || !pHddCtx->fw || !pHddCtx->fw->data) {
8867 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: CFG download failed",__func__);
8868 return VOS_STATUS_E_FAILURE;
8869 }
8870 else {
8871 if(*pBufSize != pHddCtx->fw->size) {
8872 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Caller sets invalid CFG "
8873 "file size", __func__);
8874 release_firmware(pHddCtx->fw);
8875 pHddCtx->fw = NULL;
8876 return VOS_STATUS_E_FAILURE;
8877 }
8878 else {
8879 if(pBuffer) {
8880 vos_mem_copy(pBuffer,pHddCtx->fw->data,*pBufSize);
8881 }
8882 release_firmware(pHddCtx->fw);
8883 pHddCtx->fw = NULL;
8884 }
8885 }
8886
8887 EXIT();
8888
8889 return VOS_STATUS_SUCCESS;
8890}
8891
8892/**---------------------------------------------------------------------------
8893
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05308894 \brief __hdd_set_mac_address() -
Jeff Johnson295189b2012-06-20 16:38:30 -07008895
8896 This function sets the user specified mac address using
8897 the command ifconfig wlanX hw ether <mac adress>.
8898
8899 \param - dev - Pointer to the net device.
8900 - addr - Pointer to the sockaddr.
8901 \return - 0 for success, non zero for failure
8902
8903 --------------------------------------------------------------------------*/
8904
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05308905static int __hdd_set_mac_address(struct net_device *dev, void *addr)
Jeff Johnson295189b2012-06-20 16:38:30 -07008906{
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05308907 hdd_adapter_t *pAdapter;
Arun Kumar Khandavalli18303eb2020-01-22 20:44:09 +05308908 hdd_adapter_t *adapter_temp;
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05308909 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07008910 struct sockaddr *psta_mac_addr = addr;
Arun Kumar Khandavalli18303eb2020-01-22 20:44:09 +05308911 int ret = 0, i;
8912 v_MACADDR_t mac_addr;
Jeff Johnson295189b2012-06-20 16:38:30 -07008913
8914 ENTER();
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05308915 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
8916 if (NULL == pAdapter)
8917 {
8918 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8919 "%s: Adapter is NULL",__func__);
8920 return -EINVAL;
8921 }
8922 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8923 ret = wlan_hdd_validate_context(pHddCtx);
8924 if (0 != ret)
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05308925 return ret;
Arun Kumar Khandavalli18303eb2020-01-22 20:44:09 +05308926
8927 memcpy(&mac_addr, psta_mac_addr->sa_data, sizeof(mac_addr));
8928 if(vos_is_macaddr_zero(&mac_addr)) {
8929 hddLog(VOS_TRACE_LEVEL_ERROR, "Zero Mac address");
8930 return -EINVAL;
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05308931 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008932
Arun Kumar Khandavalli18303eb2020-01-22 20:44:09 +05308933 if (vos_is_macaddr_broadcast(&mac_addr)) {
8934 hddLog(VOS_TRACE_LEVEL_ERROR,"MAC is Broadcast");
8935 return -EINVAL;
8936 }
8937
8938 if (vos_is_macaddr_multicast(&mac_addr)) {
8939 hddLog(VOS_TRACE_LEVEL_ERROR, "Multicast Mac address");
8940 return -EINVAL;
8941 }
8942 adapter_temp = hdd_get_adapter_by_macaddr(pHddCtx, mac_addr.bytes);
8943 if (adapter_temp) {
8944 if (!strcmp(adapter_temp->dev->name, dev->name))
8945 return 0;
8946 hddLog(VOS_TRACE_LEVEL_ERROR,
8947 "%s: WLAN Mac Addr: "
8948 MAC_ADDRESS_STR, __func__,
8949 MAC_ADDR_ARRAY(mac_addr.bytes));
8950 return -EINVAL;
8951 }
8952
8953 for (i = 0; i < VOS_MAX_CONCURRENCY_PERSONA; i++) {
8954 if (!vos_mem_compare(&pAdapter->macAddressCurrent.bytes,
8955 &pHddCtx->cfg_ini->intfMacAddr[i].bytes[0], VOS_MAC_ADDR_SIZE)) {
8956 memcpy(&pHddCtx->cfg_ini->intfMacAddr[i].bytes[0], mac_addr.bytes,
8957 VOS_MAC_ADDR_SIZE);
8958 break;
8959 }
8960 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008961 memcpy(&pAdapter->macAddressCurrent, psta_mac_addr->sa_data, ETH_ALEN);
Jeff Johnson295189b2012-06-20 16:38:30 -07008962 memcpy(dev->dev_addr, psta_mac_addr->sa_data, ETH_ALEN);
8963
8964 EXIT();
Arun Kumar Khandavalli18303eb2020-01-22 20:44:09 +05308965 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07008966}
8967
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05308968/**---------------------------------------------------------------------------
8969
8970 \brief hdd_set_mac_address() -
8971
8972 Wrapper function to protect __hdd_set_mac_address() function from ssr
8973
8974 \param - dev - Pointer to the net device.
8975 - addr - Pointer to the sockaddr.
8976 \return - 0 for success, non zero for failure
8977
8978 --------------------------------------------------------------------------*/
8979static int hdd_set_mac_address(struct net_device *dev, void *addr)
8980{
8981 int ret;
8982
8983 vos_ssr_protect(__func__);
8984 ret = __hdd_set_mac_address(dev, addr);
8985 vos_ssr_unprotect(__func__);
8986
8987 return ret;
8988}
8989
Jeff Johnson295189b2012-06-20 16:38:30 -07008990tANI_U8* wlan_hdd_get_intf_addr(hdd_context_t* pHddCtx)
8991{
8992 int i;
8993 for ( i = 0; i < VOS_MAX_CONCURRENCY_PERSONA; i++)
8994 {
Abhishek Singheb183782014-02-06 13:37:21 +05308995 if( 0 == ((pHddCtx->cfg_ini->intfAddrMask) & (1 << i)) )
Jeff Johnson295189b2012-06-20 16:38:30 -07008996 break;
8997 }
8998
8999 if( VOS_MAX_CONCURRENCY_PERSONA == i)
9000 return NULL;
9001
9002 pHddCtx->cfg_ini->intfAddrMask |= (1 << i);
9003 return &pHddCtx->cfg_ini->intfMacAddr[i].bytes[0];
9004}
9005
9006void wlan_hdd_release_intf_addr(hdd_context_t* pHddCtx, tANI_U8* releaseAddr)
9007{
9008 int i;
9009 for ( i = 0; i < VOS_MAX_CONCURRENCY_PERSONA; i++)
9010 {
9011 if ( !memcmp(releaseAddr, &pHddCtx->cfg_ini->intfMacAddr[i].bytes[0], 6) )
9012 {
9013 pHddCtx->cfg_ini->intfAddrMask &= ~(1 << i);
9014 break;
9015 }
9016 }
9017 return;
9018}
9019
9020#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29))
9021 static struct net_device_ops wlan_drv_ops = {
9022 .ndo_open = hdd_open,
9023 .ndo_stop = hdd_stop,
9024 .ndo_uninit = hdd_uninit,
9025 .ndo_start_xmit = hdd_hard_start_xmit,
9026 .ndo_tx_timeout = hdd_tx_timeout,
9027 .ndo_get_stats = hdd_stats,
9028 .ndo_do_ioctl = hdd_ioctl,
9029 .ndo_set_mac_address = hdd_set_mac_address,
9030 .ndo_select_queue = hdd_select_queue,
9031#ifdef WLAN_FEATURE_PACKET_FILTERING
9032#if (LINUX_VERSION_CODE > KERNEL_VERSION(3,1,0))
9033 .ndo_set_rx_mode = hdd_set_multicast_list,
9034#else
9035 .ndo_set_multicast_list = hdd_set_multicast_list,
9036#endif //LINUX_VERSION_CODE
9037#endif
9038 };
Jeff Johnson295189b2012-06-20 16:38:30 -07009039 static struct net_device_ops wlan_mon_drv_ops = {
9040 .ndo_open = hdd_mon_open,
Katya Nigame7b69a82015-04-28 15:24:06 +05309041 .ndo_stop = hdd_mon_stop,
Jeff Johnson295189b2012-06-20 16:38:30 -07009042 .ndo_uninit = hdd_uninit,
9043 .ndo_start_xmit = hdd_mon_hard_start_xmit,
9044 .ndo_tx_timeout = hdd_tx_timeout,
9045 .ndo_get_stats = hdd_stats,
Katya Nigame7b69a82015-04-28 15:24:06 +05309046 .ndo_do_ioctl = hdd_mon_ioctl,
Jeff Johnson295189b2012-06-20 16:38:30 -07009047 .ndo_set_mac_address = hdd_set_mac_address,
9048 };
Mahesh A Saptasagar305e2632015-03-04 12:57:33 +05309049
Jeff Johnson295189b2012-06-20 16:38:30 -07009050#endif
9051
9052void hdd_set_station_ops( struct net_device *pWlanDev )
9053{
9054#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29))
Jeff Johnson295189b2012-06-20 16:38:30 -07009055 pWlanDev->netdev_ops = &wlan_drv_ops;
9056#else
9057 pWlanDev->open = hdd_open;
9058 pWlanDev->stop = hdd_stop;
9059 pWlanDev->uninit = hdd_uninit;
9060 pWlanDev->hard_start_xmit = NULL;
9061 pWlanDev->tx_timeout = hdd_tx_timeout;
9062 pWlanDev->get_stats = hdd_stats;
9063 pWlanDev->do_ioctl = hdd_ioctl;
Jeff Johnson295189b2012-06-20 16:38:30 -07009064 pWlanDev->set_mac_address = hdd_set_mac_address;
9065#endif
9066}
9067
Katya Nigam1fd24402015-02-16 14:52:19 +05309068void hdd_set_ibss_ops( hdd_adapter_t *pAdapter )
9069{
9070 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29))
9071 wlan_drv_ops.ndo_start_xmit = hdd_ibss_hard_start_xmit;
9072 #else
9073 pAdapter->dev->hard_start_xmit = hdd_ibss_hard_start_xmit;
9074 #endif
9075}
9076
Jeff Johnsoneed415b2013-01-18 16:11:20 -08009077static hdd_adapter_t* hdd_alloc_station_adapter( hdd_context_t *pHddCtx, tSirMacAddr macAddr, const char* name )
Jeff Johnson295189b2012-06-20 16:38:30 -07009078{
9079 struct net_device *pWlanDev = NULL;
9080 hdd_adapter_t *pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07009081 /*
9082 * cfg80211 initialization and registration....
9083 */
Anand N Sunkadc34abbd2015-07-29 09:52:59 +05309084 pWlanDev = alloc_netdev_mq(sizeof( hdd_adapter_t ), name,
9085#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,17,0))
9086 NET_NAME_UNKNOWN,
9087#endif
9088 ether_setup, NUM_TX_QUEUES);
Jeff Johnson295189b2012-06-20 16:38:30 -07009089 if(pWlanDev != NULL)
9090 {
9091
9092 //Save the pointer to the net_device in the HDD adapter
9093 pAdapter = (hdd_adapter_t*) netdev_priv( pWlanDev );
9094
Jeff Johnson295189b2012-06-20 16:38:30 -07009095 vos_mem_zero( pAdapter, sizeof( hdd_adapter_t ) );
9096
9097 pAdapter->dev = pWlanDev;
9098 pAdapter->pHddCtx = pHddCtx;
9099 pAdapter->magic = WLAN_HDD_ADAPTER_MAGIC;
Agarwal Ashish47d18112014-08-04 19:55:07 +05309100 spin_lock_init(&pAdapter->lock_for_active_session);
Jeff Johnson295189b2012-06-20 16:38:30 -07009101
Rajeev79dbe4c2013-10-05 11:03:42 +05309102#ifdef FEATURE_WLAN_BATCH_SCAN
Rajeev79dbe4c2013-10-05 11:03:42 +05309103 pAdapter->pBatchScanRsp = NULL;
9104 pAdapter->numScanList = 0;
Rajeev Kumar20140c12013-10-21 19:39:02 -07009105 pAdapter->batchScanState = eHDD_BATCH_SCAN_STATE_STOPPED;
Kiet Lamaa8e15a2014-02-11 23:30:06 -08009106 pAdapter->prev_batch_id = 0;
Rajeev79dbe4c2013-10-05 11:03:42 +05309107 mutex_init(&pAdapter->hdd_batch_scan_lock);
9108#endif
9109
Jeff Johnson295189b2012-06-20 16:38:30 -07009110 pAdapter->isLinkUpSvcNeeded = FALSE;
9111 pAdapter->higherDtimTransition = eANI_BOOLEAN_TRUE;
9112 //Init the net_device structure
9113 strlcpy(pWlanDev->name, name, IFNAMSIZ);
9114
9115 vos_mem_copy(pWlanDev->dev_addr, (void *)macAddr, sizeof(tSirMacAddr));
9116 vos_mem_copy( pAdapter->macAddressCurrent.bytes, macAddr, sizeof(tSirMacAddr));
9117 pWlanDev->watchdog_timeo = HDD_TX_TIMEOUT;
Alok Kumar84458542018-05-14 15:03:08 +05309118
9119 pWlanDev->needed_headroom = LIBRA_HW_NEEDED_HEADROOM;
Jeff Johnson295189b2012-06-20 16:38:30 -07009120
9121 hdd_set_station_ops( pAdapter->dev );
9122
9123 pWlanDev->destructor = free_netdev;
Jeff Johnson295189b2012-06-20 16:38:30 -07009124 pWlanDev->ieee80211_ptr = &pAdapter->wdev ;
9125 pAdapter->wdev.wiphy = pHddCtx->wiphy;
9126 pAdapter->wdev.netdev = pWlanDev;
Jeff Johnson295189b2012-06-20 16:38:30 -07009127 /* set pWlanDev's parent to underlying device */
9128 SET_NETDEV_DEV(pWlanDev, pHddCtx->parent_dev);
Kumar Anand82c009f2014-05-29 00:29:42 -07009129
9130 hdd_wmm_init( pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -07009131 }
9132
9133 return pAdapter;
9134}
9135
9136VOS_STATUS hdd_register_interface( hdd_adapter_t *pAdapter, tANI_U8 rtnl_lock_held )
9137{
9138 struct net_device *pWlanDev = pAdapter->dev;
9139 //hdd_station_ctx_t *pHddStaCtx = &pAdapter->sessionCtx.station;
9140 //hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
9141 //eHalStatus halStatus = eHAL_STATUS_SUCCESS;
9142
9143 if( rtnl_lock_held )
9144 {
Madan Mohan Koyyalamudid8ac8662012-11-06 19:04:56 -08009145 if (strnchr(pWlanDev->name, strlen(pWlanDev->name), '%')) {
Jeff Johnson295189b2012-06-20 16:38:30 -07009146 if( dev_alloc_name(pWlanDev, pWlanDev->name) < 0 )
9147 {
9148 hddLog(VOS_TRACE_LEVEL_ERROR,"%s:Failed:dev_alloc_name",__func__);
9149 return VOS_STATUS_E_FAILURE;
9150 }
9151 }
9152 if (register_netdevice(pWlanDev))
9153 {
9154 hddLog(VOS_TRACE_LEVEL_ERROR,"%s:Failed:register_netdev",__func__);
9155 return VOS_STATUS_E_FAILURE;
9156 }
9157 }
9158 else
9159 {
9160 if(register_netdev(pWlanDev))
9161 {
9162 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Failed:register_netdev",__func__);
9163 return VOS_STATUS_E_FAILURE;
9164 }
9165 }
9166 set_bit(NET_DEVICE_REGISTERED, &pAdapter->event_flags);
9167
9168 return VOS_STATUS_SUCCESS;
9169}
9170
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07009171static eHalStatus hdd_smeCloseSessionCallback(void *pContext)
Jeff Johnson295189b2012-06-20 16:38:30 -07009172{
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07009173 hdd_adapter_t *pAdapter = pContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07009174
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07009175 if (NULL == pAdapter)
9176 {
9177 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: NULL pAdapter", __func__);
9178 return eHAL_STATUS_INVALID_PARAMETER;
Jeff Johnson295189b2012-06-20 16:38:30 -07009179 }
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07009180
9181 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
9182 {
9183 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Invalid magic", __func__);
9184 return eHAL_STATUS_NOT_INITIALIZED;
9185 }
9186
9187 clear_bit(SME_SESSION_OPENED, &pAdapter->event_flags);
9188
Sameer Thalappilbee426e2013-10-30 10:30:30 -07009189#ifndef WLAN_OPEN_SOURCE
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07009190 /* need to make sure all of our scheduled work has completed.
9191 * This callback is called from MC thread context, so it is safe to
9192 * to call below flush workqueue API from here.
Sameer Thalappilbee426e2013-10-30 10:30:30 -07009193 *
9194 * Even though this is called from MC thread context, if there is a faulty
9195 * work item in the system, that can hang this call forever. So flushing
9196 * this global work queue is not safe; and now we make sure that
9197 * individual work queues are stopped correctly. But the cancel work queue
9198 * is a GPL only API, so the proprietary version of the driver would still
9199 * rely on the global work queue flush.
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07009200 */
9201 flush_scheduled_work();
Sameer Thalappilbee426e2013-10-30 10:30:30 -07009202#endif
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07009203
9204 /* We can be blocked while waiting for scheduled work to be
9205 * flushed, and the adapter structure can potentially be freed, in
9206 * which case the magic will have been reset. So make sure the
9207 * magic is still good, and hence the adapter structure is still
9208 * valid, before signaling completion */
9209 if (WLAN_HDD_ADAPTER_MAGIC == pAdapter->magic)
9210 {
9211 complete(&pAdapter->session_close_comp_var);
9212 }
9213
Jeff Johnson295189b2012-06-20 16:38:30 -07009214 return eHAL_STATUS_SUCCESS;
9215}
Manjeet Singh47ee8472016-04-11 11:57:18 +05309216/**
9217 * hdd_close_tx_queues() - close tx queues
9218 * @hdd_ctx: hdd global context
9219 *
9220 * Return: None
9221 */
9222static void hdd_close_tx_queues(hdd_context_t *hdd_ctx)
9223{
9224 VOS_STATUS status;
9225 hdd_adapter_t *adapter;
9226 hdd_adapter_list_node_t *adapter_node = NULL, *next_adapter = NULL;
9227 /* Not validating hdd_ctx as it's already done by the caller */
9228 ENTER();
9229 status = hdd_get_front_adapter(hdd_ctx, &adapter_node);
9230 while (NULL != adapter_node && VOS_STATUS_SUCCESS == status) {
9231 adapter = adapter_node->pAdapter;
9232 if (adapter && adapter->dev) {
9233 netif_tx_disable (adapter->dev);
9234 netif_carrier_off(adapter->dev);
9235 }
9236 status = hdd_get_next_adapter(hdd_ctx, adapter_node,
9237 &next_adapter);
9238 adapter_node = next_adapter;
9239 }
9240 EXIT();
9241}
Jeff Johnson295189b2012-06-20 16:38:30 -07009242
9243VOS_STATUS hdd_init_station_mode( hdd_adapter_t *pAdapter )
9244{
9245 struct net_device *pWlanDev = pAdapter->dev;
9246 hdd_station_ctx_t *pHddStaCtx = &pAdapter->sessionCtx.station;
9247 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
9248 eHalStatus halStatus = eHAL_STATUS_SUCCESS;
9249 VOS_STATUS status = VOS_STATUS_E_FAILURE;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309250 long rc = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07009251
Nirav Shah7e3c8132015-06-22 23:51:42 +05309252 spin_lock_init( &pAdapter->sta_hash_lock);
9253 pAdapter->is_sta_id_hash_initialized = VOS_FALSE;
9254
Jeff Johnson295189b2012-06-20 16:38:30 -07009255 INIT_COMPLETION(pAdapter->session_open_comp_var);
Kiran Kumar Lokere0ad5cd32013-06-25 11:26:22 -07009256 sme_SetCurrDeviceMode(pHddCtx->hHal, pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07009257 //Open a SME session for future operation
9258 halStatus = sme_OpenSession( pHddCtx->hHal, hdd_smeRoamCallback, pAdapter,
Kiran Kumar Lokere0ad5cd32013-06-25 11:26:22 -07009259 (tANI_U8 *)&pAdapter->macAddressCurrent, &pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07009260 if ( !HAL_STATUS_SUCCESS( halStatus ) )
9261 {
9262 hddLog(VOS_TRACE_LEVEL_FATAL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07009263 "sme_OpenSession() failed with status code %08d [x%08x]",
Jeff Johnson295189b2012-06-20 16:38:30 -07009264 halStatus, halStatus );
9265 status = VOS_STATUS_E_FAILURE;
9266 goto error_sme_open;
9267 }
9268
9269 //Block on a completion variable. Can't wait forever though.
Vinay Krishna Eranna0fe2e7c2014-04-09 21:32:08 +05309270 rc = wait_for_completion_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -07009271 &pAdapter->session_open_comp_var,
9272 msecs_to_jiffies(WLAN_WAIT_TIME_SESSIONOPENCLOSE));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309273 if (rc <= 0)
Jeff Johnson295189b2012-06-20 16:38:30 -07009274 {
9275 hddLog(VOS_TRACE_LEVEL_FATAL,
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309276 "Session is not opened within timeout period code %ld", rc );
Jeff Johnson295189b2012-06-20 16:38:30 -07009277 status = VOS_STATUS_E_FAILURE;
9278 goto error_sme_open;
9279 }
9280
9281 // Register wireless extensions
9282 if( eHAL_STATUS_SUCCESS != (halStatus = hdd_register_wext(pWlanDev)))
9283 {
9284 hddLog(VOS_TRACE_LEVEL_FATAL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07009285 "hdd_register_wext() failed with status code %08d [x%08x]",
Jeff Johnson295189b2012-06-20 16:38:30 -07009286 halStatus, halStatus );
9287 status = VOS_STATUS_E_FAILURE;
9288 goto error_register_wext;
9289 }
Katya Nigam1fd24402015-02-16 14:52:19 +05309290
Jeff Johnson295189b2012-06-20 16:38:30 -07009291 //Safe to register the hard_start_xmit function again
Katya Nigam1fd24402015-02-16 14:52:19 +05309292 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29))
9293 wlan_drv_ops.ndo_start_xmit = hdd_hard_start_xmit;
9294 #else
9295 pWlanDev->hard_start_xmit = hdd_hard_start_xmit;
9296 #endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009297
9298 //Set the Connection State to Not Connected
Abhishek Singhf4669da2014-05-26 15:07:49 +05309299 hddLog(VOS_TRACE_LEVEL_INFO,
9300 "%s: Set HDD connState to eConnectionState_NotConnected",
9301 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009302 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
9303
9304 //Set the default operation channel
9305 pHddStaCtx->conn_info.operationChannel = pHddCtx->cfg_ini->OperatingChannel;
9306
9307 /* Make the default Auth Type as OPEN*/
9308 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_OPEN_SYSTEM;
9309
9310 if( VOS_STATUS_SUCCESS != ( status = hdd_init_tx_rx( pAdapter ) ) )
9311 {
9312 hddLog(VOS_TRACE_LEVEL_FATAL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07009313 "hdd_init_tx_rx() failed with status code %08d [x%08x]",
Jeff Johnson295189b2012-06-20 16:38:30 -07009314 status, status );
9315 goto error_init_txrx;
9316 }
9317
9318 set_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
9319
9320 if( VOS_STATUS_SUCCESS != ( status = hdd_wmm_adapter_init( pAdapter ) ) )
9321 {
9322 hddLog(VOS_TRACE_LEVEL_FATAL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07009323 "hdd_wmm_adapter_init() failed with status code %08d [x%08x]",
Jeff Johnson295189b2012-06-20 16:38:30 -07009324 status, status );
9325 goto error_wmm_init;
9326 }
9327
9328 set_bit(WMM_INIT_DONE, &pAdapter->event_flags);
9329
9330 return VOS_STATUS_SUCCESS;
9331
9332error_wmm_init:
9333 clear_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
9334 hdd_deinit_tx_rx(pAdapter);
9335error_init_txrx:
9336 hdd_UnregisterWext(pWlanDev);
9337error_register_wext:
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07009338 if (test_bit(SME_SESSION_OPENED, &pAdapter->event_flags))
Jeff Johnson295189b2012-06-20 16:38:30 -07009339 {
9340 INIT_COMPLETION(pAdapter->session_close_comp_var);
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07009341 if (eHAL_STATUS_SUCCESS == sme_CloseSession(pHddCtx->hHal,
Agrawal Ashish5a3522c2016-03-02 15:08:28 +05309342 pAdapter->sessionId, FALSE, VOS_TRUE,
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07009343 hdd_smeCloseSessionCallback, pAdapter))
Jeff Johnson295189b2012-06-20 16:38:30 -07009344 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309345 unsigned long rc;
9346
Jeff Johnson295189b2012-06-20 16:38:30 -07009347 //Block on a completion variable. Can't wait forever though.
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309348 rc = wait_for_completion_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -07009349 &pAdapter->session_close_comp_var,
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07009350 msecs_to_jiffies(WLAN_WAIT_TIME_SESSIONOPENCLOSE));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309351 if (rc <= 0)
9352 hddLog(VOS_TRACE_LEVEL_ERROR,
9353 FL("Session is not opened within timeout period code %ld"), rc);
Jeff Johnson295189b2012-06-20 16:38:30 -07009354 }
9355}
9356error_sme_open:
9357 return status;
9358}
9359
Jeff Johnson295189b2012-06-20 16:38:30 -07009360void hdd_cleanup_actionframe( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter )
9361{
9362 hdd_cfg80211_state_t *cfgState;
9363
9364 cfgState = WLAN_HDD_GET_CFG_STATE_PTR( pAdapter );
9365
9366 if( NULL != cfgState->buf )
9367 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309368 long rc;
Jeff Johnson295189b2012-06-20 16:38:30 -07009369 INIT_COMPLETION(pAdapter->tx_action_cnf_event);
9370 rc = wait_for_completion_interruptible_timeout(
9371 &pAdapter->tx_action_cnf_event,
9372 msecs_to_jiffies(ACTION_FRAME_TX_TIMEOUT));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309373 if (rc <= 0)
Jeff Johnson295189b2012-06-20 16:38:30 -07009374 {
Deepthi Gowri91b3e9c2015-08-25 13:14:58 +05309375 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9376 "%s ERROR: HDD Wait for Action Confirmation Failed!! %ld"
9377 , __func__, rc);
9378
9379 // Inform tx status as FAILURE to upper layer and free cfgState->buf
9380 hdd_sendActionCnf( pAdapter, FALSE );
Jeff Johnson295189b2012-06-20 16:38:30 -07009381 }
9382 }
9383 return;
9384}
Jeff Johnson295189b2012-06-20 16:38:30 -07009385
c_hpothu002231a2015-02-05 14:58:51 +05309386void hdd_deinit_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter, tANI_U8 rtnl_held )
Jeff Johnson295189b2012-06-20 16:38:30 -07009387{
9388 ENTER();
9389 switch ( pAdapter->device_mode )
9390 {
Katya Nigam1fd24402015-02-16 14:52:19 +05309391 case WLAN_HDD_IBSS:
9392 {
9393 if(test_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags))
9394 {
9395 hdd_ibss_deinit_tx_rx( pAdapter );
9396 clear_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
9397 }
9398 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009399 case WLAN_HDD_INFRA_STATION:
9400 case WLAN_HDD_P2P_CLIENT:
Jeff Johnsone7245742012-09-05 17:12:55 -07009401 case WLAN_HDD_P2P_DEVICE:
Jeff Johnson295189b2012-06-20 16:38:30 -07009402 {
9403 if(test_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags))
9404 {
9405 hdd_deinit_tx_rx( pAdapter );
9406 clear_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
9407 }
9408
9409 if(test_bit(WMM_INIT_DONE, &pAdapter->event_flags))
9410 {
9411 hdd_wmm_adapter_close( pAdapter );
9412 clear_bit(WMM_INIT_DONE, &pAdapter->event_flags);
9413 }
9414
Jeff Johnson295189b2012-06-20 16:38:30 -07009415 hdd_cleanup_actionframe(pHddCtx, pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07009416 break;
9417 }
9418
9419 case WLAN_HDD_SOFTAP:
9420 case WLAN_HDD_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07009421 {
Madan Mohan Koyyalamudi8c6dec82013-09-26 15:56:13 +05309422
9423 if (test_bit(WMM_INIT_DONE, &pAdapter->event_flags))
9424 {
9425 hdd_wmm_adapter_close( pAdapter );
9426 clear_bit(WMM_INIT_DONE, &pAdapter->event_flags);
9427 }
9428
Jeff Johnson295189b2012-06-20 16:38:30 -07009429 hdd_cleanup_actionframe(pHddCtx, pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07009430
c_hpothu002231a2015-02-05 14:58:51 +05309431 hdd_unregister_hostapd(pAdapter, rtnl_held);
Agrawal Ashisha0584d42016-09-29 13:03:45 +05309432 /* set con_mode to STA only when no SAP concurrency mode */
9433 if (!(hdd_get_concurrency_mode() & (VOS_SAP | VOS_P2P_GO)))
9434 hdd_set_conparam(0);
Jeff Johnson295189b2012-06-20 16:38:30 -07009435 break;
9436 }
9437
9438 case WLAN_HDD_MONITOR:
9439 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009440 if(test_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags))
9441 {
9442 hdd_deinit_tx_rx( pAdapter );
9443 clear_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
9444 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009445 break;
9446 }
9447
9448
9449 default:
9450 break;
9451 }
9452
9453 EXIT();
9454}
9455
9456void hdd_cleanup_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter, tANI_U8 rtnl_held )
9457{
Mingcheng Zhu87f22fc2014-01-30 19:23:32 -08009458 struct net_device *pWlanDev = NULL;
Srinivas, Dasari693dfc52013-12-27 17:29:09 +05309459
9460 ENTER();
9461 if (NULL == pAdapter)
9462 {
9463 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9464 "%s: HDD adapter is Null", __func__);
9465 return;
9466 }
9467
9468 pWlanDev = pAdapter->dev;
Jeff Johnson295189b2012-06-20 16:38:30 -07009469
Rajeev79dbe4c2013-10-05 11:03:42 +05309470#ifdef FEATURE_WLAN_BATCH_SCAN
Srinivas, Dasari693dfc52013-12-27 17:29:09 +05309471 if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
9472 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Rajeev Kumarf999e582014-01-09 17:33:29 -08009473 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Srinivas, Dasari693dfc52013-12-27 17:29:09 +05309474 || (pAdapter->device_mode == WLAN_HDD_P2P_DEVICE)
9475 )
9476 {
Rajeev Kumarf999e582014-01-09 17:33:29 -08009477 if (pAdapter)
Rajeev79dbe4c2013-10-05 11:03:42 +05309478 {
Rajeev Kumarf999e582014-01-09 17:33:29 -08009479 if (eHDD_BATCH_SCAN_STATE_STARTED == pAdapter->batchScanState)
9480 {
9481 hdd_deinit_batch_scan(pAdapter);
9482 }
Rajeev79dbe4c2013-10-05 11:03:42 +05309483 }
Rajeev Kumarf999e582014-01-09 17:33:29 -08009484 }
Rajeev79dbe4c2013-10-05 11:03:42 +05309485#endif
9486
Jeff Johnson295189b2012-06-20 16:38:30 -07009487 if(test_bit(NET_DEVICE_REGISTERED, &pAdapter->event_flags)) {
9488 if( rtnl_held )
9489 {
9490 unregister_netdevice(pWlanDev);
9491 }
9492 else
9493 {
9494 unregister_netdev(pWlanDev);
9495 }
9496 // note that the pAdapter is no longer valid at this point
9497 // since the memory has been reclaimed
9498 }
9499
Srinivas, Dasari693dfc52013-12-27 17:29:09 +05309500 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07009501}
9502
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08009503void hdd_set_pwrparams(hdd_context_t *pHddCtx)
9504{
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05309505 VOS_STATUS status;
9506 hdd_adapter_t *pAdapter = NULL;
9507 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08009508
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05309509 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08009510
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05309511 /*loop through all adapters.*/
9512 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08009513 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05309514 pAdapter = pAdapterNode->pAdapter;
9515 if ( (WLAN_HDD_INFRA_STATION != pAdapter->device_mode)
9516 && (WLAN_HDD_P2P_CLIENT != pAdapter->device_mode) )
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08009517
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05309518 { // we skip this registration for modes other than STA and P2P client modes.
9519 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
9520 pAdapterNode = pNext;
9521 continue;
9522 }
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08009523
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05309524 //Apply Dynamic DTIM For P2P
9525 //Only if ignoreDynamicDtimInP2pMode is not set in ini
9526 if ((pHddCtx->cfg_ini->enableDynamicDTIM ||
9527 pHddCtx->cfg_ini->enableModulatedDTIM) &&
9528 ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
9529 ((WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) &&
9530 !(pHddCtx->cfg_ini->ignoreDynamicDtimInP2pMode))) &&
9531 (eANI_BOOLEAN_TRUE == pAdapter->higherDtimTransition) &&
9532 (eConnectionState_Associated ==
9533 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState) &&
9534 (pHddCtx->cfg_ini->fIsBmpsEnabled))
9535 {
9536 tSirSetPowerParamsReq powerRequest = { 0 };
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08009537
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05309538 powerRequest.uIgnoreDTIM = 1;
9539 powerRequest.uMaxLIModulatedDTIM = pHddCtx->cfg_ini->fMaxLIModulatedDTIM;
9540
9541 if (pHddCtx->cfg_ini->enableModulatedDTIM)
9542 {
9543 powerRequest.uDTIMPeriod = pHddCtx->cfg_ini->enableModulatedDTIM;
9544 powerRequest.uListenInterval = pHddCtx->hdd_actual_LI_value;
9545 }
9546 else
9547 {
9548 powerRequest.uListenInterval = pHddCtx->cfg_ini->enableDynamicDTIM;
9549 }
9550
9551 /* Update ignoreDTIM and ListedInterval in CFG to remain at the DTIM
9552 * specified during Enter/Exit BMPS when LCD off*/
9553 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IGNORE_DTIM, powerRequest.uIgnoreDTIM,
9554 NULL, eANI_BOOLEAN_FALSE);
9555 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_LISTEN_INTERVAL, powerRequest.uListenInterval,
9556 NULL, eANI_BOOLEAN_FALSE);
9557
9558 /* switch to the DTIM specified in cfg.ini */
9559 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Abhishek Singh1e390cf2015-10-27 13:45:17 +05309560 "Switch to DTIM %d Listen interval %d",
9561 powerRequest.uDTIMPeriod,
9562 powerRequest.uListenInterval);
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05309563 sme_SetPowerParams( pHddCtx->hHal, &powerRequest, TRUE);
9564 break;
9565
9566 }
9567
9568 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
9569 pAdapterNode = pNext;
9570 }
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08009571}
9572
9573void hdd_reset_pwrparams(hdd_context_t *pHddCtx)
9574{
9575 /*Switch back to DTIM 1*/
9576 tSirSetPowerParamsReq powerRequest = { 0 };
9577
9578 powerRequest.uIgnoreDTIM = pHddCtx->hdd_actual_ignore_DTIM_value;
9579 powerRequest.uListenInterval = pHddCtx->hdd_actual_LI_value;
Yue Mac24062f2013-05-13 17:01:29 -07009580 powerRequest.uMaxLIModulatedDTIM = pHddCtx->cfg_ini->fMaxLIModulatedDTIM;
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08009581
9582 /* Update ignoreDTIM and ListedInterval in CFG with default values */
9583 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IGNORE_DTIM, powerRequest.uIgnoreDTIM,
9584 NULL, eANI_BOOLEAN_FALSE);
9585 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_LISTEN_INTERVAL, powerRequest.uListenInterval,
9586 NULL, eANI_BOOLEAN_FALSE);
9587
9588 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
9589 "Switch to DTIM%d",powerRequest.uListenInterval);
9590 sme_SetPowerParams( pHddCtx->hHal, &powerRequest, TRUE);
9591
9592}
9593
Jeff Johnson295189b2012-06-20 16:38:30 -07009594VOS_STATUS hdd_enable_bmps_imps(hdd_context_t *pHddCtx)
9595{
9596 VOS_STATUS status = VOS_STATUS_SUCCESS;
Sushant Kaushik4928e542014-12-29 15:25:54 +05309597 if (WLAN_HDD_IS_UNLOAD_IN_PROGRESS(pHddCtx))
9598 {
9599 hddLog( LOGE, FL("Wlan Unload in progress"));
9600 return VOS_STATUS_E_PERM;
9601 }
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +05309602
9603 if (wlan_hdd_check_monitor_state(pHddCtx)) {
9604 hddLog(LOG1, FL("Monitor mode is started, cannot enable BMPS"));
9605 return VOS_STATUS_SUCCESS;
9606 }
9607
Jeff Johnson295189b2012-06-20 16:38:30 -07009608 if(pHddCtx->cfg_ini->fIsBmpsEnabled)
9609 {
9610 sme_EnablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
9611 }
9612
9613 if(pHddCtx->cfg_ini->fIsAutoBmpsTimerEnabled)
9614 {
9615 sme_StartAutoBmpsTimer(pHddCtx->hHal);
9616 }
9617
9618 if (pHddCtx->cfg_ini->fIsImpsEnabled)
9619 {
9620 sme_EnablePowerSave (pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
9621 }
9622
9623 return status;
9624}
9625
9626VOS_STATUS hdd_disable_bmps_imps(hdd_context_t *pHddCtx, tANI_U8 session_type)
9627{
9628 hdd_adapter_t *pAdapter = NULL;
9629 eHalStatus halStatus;
9630 VOS_STATUS status = VOS_STATUS_E_INVAL;
9631 v_BOOL_t disableBmps = FALSE;
9632 v_BOOL_t disableImps = FALSE;
9633
9634 switch(session_type)
9635 {
9636 case WLAN_HDD_INFRA_STATION:
9637 case WLAN_HDD_SOFTAP:
Jeff Johnson295189b2012-06-20 16:38:30 -07009638 case WLAN_HDD_P2P_CLIENT:
9639 case WLAN_HDD_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07009640 //Exit BMPS -> Is Sta/P2P Client is already connected
9641 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION);
9642 if((NULL != pAdapter)&&
9643 hdd_connIsConnected( WLAN_HDD_GET_STATION_CTX_PTR(pAdapter)))
9644 {
9645 disableBmps = TRUE;
9646 }
9647
9648 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_CLIENT);
9649 if((NULL != pAdapter)&&
9650 hdd_connIsConnected( WLAN_HDD_GET_STATION_CTX_PTR(pAdapter)))
9651 {
9652 disableBmps = TRUE;
9653 }
9654
9655 //Exit both Bmps and Imps incase of Go/SAP Mode
9656 if((WLAN_HDD_SOFTAP == session_type) ||
9657 (WLAN_HDD_P2P_GO == session_type))
9658 {
9659 disableBmps = TRUE;
9660 disableImps = TRUE;
9661 }
9662
9663 if(TRUE == disableImps)
9664 {
9665 if (pHddCtx->cfg_ini->fIsImpsEnabled)
9666 {
9667 sme_DisablePowerSave (pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
9668 }
9669 }
9670
9671 if(TRUE == disableBmps)
9672 {
9673 if(pHddCtx->cfg_ini->fIsBmpsEnabled)
9674 {
9675 halStatus = sme_DisablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
9676
9677 if(eHAL_STATUS_SUCCESS != halStatus)
9678 {
9679 status = VOS_STATUS_E_FAILURE;
Arif Hussain6d2a3322013-11-17 19:50:10 -08009680 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Fail to Disable Power Save", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009681 VOS_ASSERT(0);
9682 return status;
9683 }
9684 }
9685
9686 if(pHddCtx->cfg_ini->fIsAutoBmpsTimerEnabled)
9687 {
9688 halStatus = sme_StopAutoBmpsTimer(pHddCtx->hHal);
9689
9690 if(eHAL_STATUS_SUCCESS != halStatus)
9691 {
9692 status = VOS_STATUS_E_FAILURE;
Arif Hussain6d2a3322013-11-17 19:50:10 -08009693 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Fail to Stop Auto Bmps Timer", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009694 VOS_ASSERT(0);
9695 return status;
9696 }
9697 }
9698 }
9699
9700 if((TRUE == disableBmps) ||
9701 (TRUE == disableImps))
9702 {
9703 /* Now, get the chip into Full Power now */
9704 INIT_COMPLETION(pHddCtx->full_pwr_comp_var);
9705 halStatus = sme_RequestFullPower(pHddCtx->hHal, hdd_full_pwr_cbk,
9706 pHddCtx, eSME_FULL_PWR_NEEDED_BY_HDD);
9707
9708 if(halStatus != eHAL_STATUS_SUCCESS)
9709 {
9710 if(halStatus == eHAL_STATUS_PMC_PENDING)
9711 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309712 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07009713 //Block on a completion variable. Can't wait forever though
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309714 ret = wait_for_completion_interruptible_timeout(
9715 &pHddCtx->full_pwr_comp_var,
9716 msecs_to_jiffies(1000));
9717 if (ret <= 0)
9718 {
9719 hddLog(VOS_TRACE_LEVEL_ERROR,
9720 "%s: wait on full_pwr_comp_var failed %ld",
9721 __func__, ret);
9722 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009723 }
9724 else
9725 {
9726 status = VOS_STATUS_E_FAILURE;
Arif Hussain6d2a3322013-11-17 19:50:10 -08009727 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Request for Full Power failed", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009728 VOS_ASSERT(0);
9729 return status;
9730 }
9731 }
9732
9733 status = VOS_STATUS_SUCCESS;
9734 }
9735
9736 break;
9737 }
9738 return status;
9739}
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +05309740
Hanumanth Reddy Pothulab8be9ab2018-04-12 20:03:05 +05309741void hdd_mon_post_msg_cb(void *context)
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +05309742{
Hanumanth Reddy Pothulab8be9ab2018-04-12 20:03:05 +05309743 struct hdd_request *request;
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +05309744
Hanumanth Reddy Pothulab8be9ab2018-04-12 20:03:05 +05309745 request = hdd_request_get(context);
9746 if (!request) {
9747 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Obsolete request"));
9748 return;
9749 }
9750
9751 hdd_request_complete(request);
9752 hdd_request_put(request);
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +05309753}
9754
Hanumanth Reddy Pothulab8be9ab2018-04-12 20:03:05 +05309755
Katya Nigame7b69a82015-04-28 15:24:06 +05309756void hdd_init_mon_mode (hdd_adapter_t *pAdapter)
9757 {
9758 hdd_mon_ctx_t *pMonCtx = NULL;
Katya Nigame7b69a82015-04-28 15:24:06 +05309759
Rajeev Kumar Sirasanagandla54447612018-03-06 15:49:56 +05309760 spin_lock_init(&pAdapter->sta_hash_lock);
9761 pAdapter->is_sta_id_hash_initialized = VOS_FALSE;
9762
9763 pMonCtx = WLAN_HDD_GET_MONITOR_CTX_PTR(pAdapter);
Katya Nigame7b69a82015-04-28 15:24:06 +05309764 pMonCtx->state = 0;
9765 pMonCtx->ChannelNo = 1;
9766 pMonCtx->ChannelBW = 20;
Katya Nigamd7d3a1f2015-06-11 14:04:24 +05309767 pMonCtx->crcCheckEnabled = 1;
9768 pMonCtx->typeSubtypeBitmap = 0xFFFF00000000;
9769 pMonCtx->is80211to803ConReq = 1;
Katya Nigame7b69a82015-04-28 15:24:06 +05309770 pMonCtx->numOfMacFilters = 0;
9771 }
9772
Jeff Johnson295189b2012-06-20 16:38:30 -07009773
9774hdd_adapter_t* hdd_open_adapter( hdd_context_t *pHddCtx, tANI_U8 session_type,
Jeff Johnsoneed415b2013-01-18 16:11:20 -08009775 const char *iface_name, tSirMacAddr macAddr,
Jeff Johnson295189b2012-06-20 16:38:30 -07009776 tANI_U8 rtnl_held )
9777{
9778 hdd_adapter_t *pAdapter = NULL;
9779 hdd_adapter_list_node_t *pHddAdapterNode = NULL;
9780 VOS_STATUS status = VOS_STATUS_E_FAILURE;
9781 VOS_STATUS exitbmpsStatus;
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +05309782 v_CONTEXT_t pVosContext = NULL;
9783
9784 /* No need to check for NULL, reaching this step
9785 * means vos context is initialized
9786 */
9787 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
Jeff Johnson295189b2012-06-20 16:38:30 -07009788
Arif Hussain6d2a3322013-11-17 19:50:10 -08009789 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s iface =%s type = %d",__func__,iface_name,session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07009790
Nirav Shah436658f2014-02-28 17:05:45 +05309791 if(macAddr == NULL)
9792 {
9793 /* Not received valid macAddr */
9794 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9795 "%s:Unable to add virtual intf: Not able to get"
9796 "valid mac address",__func__);
9797 return NULL;
9798 }
9799
Jeff Johnson295189b2012-06-20 16:38:30 -07009800 //Disable BMPS incase of Concurrency
9801 exitbmpsStatus = hdd_disable_bmps_imps(pHddCtx, session_type);
9802
9803 if(VOS_STATUS_E_FAILURE == exitbmpsStatus)
9804 {
9805 //Fail to Exit BMPS
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309806 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Fail to Exit BMPS", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009807 VOS_ASSERT(0);
9808 return NULL;
9809 }
9810
9811 switch(session_type)
9812 {
9813 case WLAN_HDD_INFRA_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -07009814 case WLAN_HDD_P2P_CLIENT:
Jeff Johnsone7245742012-09-05 17:12:55 -07009815 case WLAN_HDD_P2P_DEVICE:
Jeff Johnson295189b2012-06-20 16:38:30 -07009816 {
9817 pAdapter = hdd_alloc_station_adapter( pHddCtx, macAddr, iface_name );
9818
9819 if( NULL == pAdapter )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309820 {
9821 hddLog(VOS_TRACE_LEVEL_FATAL,
9822 FL("failed to allocate adapter for session %d"), session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07009823 return NULL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309824 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009825
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05309826#ifdef FEATURE_WLAN_TDLS
9827 /* A Mutex Lock is introduced while changing/initializing the mode to
9828 * protect the concurrent access for the Adapters by TDLS module.
9829 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05309830 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05309831#endif
9832
Jeff Johnsone7245742012-09-05 17:12:55 -07009833 pAdapter->wdev.iftype = (session_type == WLAN_HDD_P2P_CLIENT) ?
9834 NL80211_IFTYPE_P2P_CLIENT:
9835 NL80211_IFTYPE_STATION;
Jeff Johnson295189b2012-06-20 16:38:30 -07009836
Jeff Johnson295189b2012-06-20 16:38:30 -07009837 pAdapter->device_mode = session_type;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05309838#ifdef FEATURE_WLAN_TDLS
9839 mutex_unlock(&pHddCtx->tdls_lock);
9840#endif
Sunil Dutt66485cb2013-12-19 19:05:03 +05309841
Mahesh A Saptasagar67ab9222015-10-21 15:38:41 +05309842 hdd_initialize_adapter_common(pAdapter);
louisliu462edac2020-06-30 13:33:56 +08009843 status = hdd_init_station_mode( pAdapter );
9844 if( VOS_STATUS_SUCCESS != status )
9845 goto err_free_netdev;
Jeff Johnson295189b2012-06-20 16:38:30 -07009846
9847 status = hdd_register_interface( pAdapter, rtnl_held );
9848 if( VOS_STATUS_SUCCESS != status )
9849 {
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05309850#ifdef FEATURE_WLAN_TDLS
9851 mutex_lock(&pHddCtx->tdls_lock);
9852#endif
c_hpothu002231a2015-02-05 14:58:51 +05309853 hdd_deinit_adapter(pHddCtx, pAdapter, rtnl_held);
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05309854#ifdef FEATURE_WLAN_TDLS
9855 mutex_unlock(&pHddCtx->tdls_lock);
9856#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009857 goto err_free_netdev;
9858 }
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05309859
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +05309860 // Workqueue which gets scheduled in IPv4 notification callback.
Anand N Sunkaddc63c792015-06-03 14:33:24 +05309861 vos_init_work(&pAdapter->ipv4NotifierWorkQueue, hdd_ipv4_notifier_work_queue);
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +05309862
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05309863#ifdef WLAN_NS_OFFLOAD
9864 // Workqueue which gets scheduled in IPv6 notification callback.
Anand N Sunkaddc63c792015-06-03 14:33:24 +05309865 vos_init_work(&pAdapter->ipv6NotifierWorkQueue, hdd_ipv6_notifier_work_queue);
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05309866#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009867 //Stop the Interface TX queue.
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +05309868 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Jeff Johnson295189b2012-06-20 16:38:30 -07009869 netif_tx_disable(pAdapter->dev);
9870 //netif_tx_disable(pWlanDev);
9871 netif_carrier_off(pAdapter->dev);
9872
Ganesh Kondabattinibabfb492014-12-17 20:25:29 +05309873 if (WLAN_HDD_P2P_CLIENT == session_type ||
9874 WLAN_HDD_P2P_DEVICE == session_type)
9875 {
9876 /* Initialize the work queue to defer the
9877 * back to back RoC request */
Anand N Sunkaddc63c792015-06-03 14:33:24 +05309878 vos_init_delayed_work(&pAdapter->roc_work,
Ganesh Kondabattinibabfb492014-12-17 20:25:29 +05309879 hdd_p2p_roc_work_queue);
9880 }
9881
Jeff Johnson295189b2012-06-20 16:38:30 -07009882 break;
9883 }
9884
Jeff Johnson295189b2012-06-20 16:38:30 -07009885 case WLAN_HDD_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07009886 case WLAN_HDD_SOFTAP:
9887 {
9888 pAdapter = hdd_wlan_create_ap_dev( pHddCtx, macAddr, (tANI_U8 *)iface_name );
9889 if( NULL == pAdapter )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309890 {
9891 hddLog(VOS_TRACE_LEVEL_FATAL,
9892 FL("failed to allocate adapter for session %d"), session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07009893 return NULL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309894 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009895
Jeff Johnson295189b2012-06-20 16:38:30 -07009896 pAdapter->wdev.iftype = (session_type == WLAN_HDD_SOFTAP) ?
9897 NL80211_IFTYPE_AP:
9898 NL80211_IFTYPE_P2P_GO;
Jeff Johnson295189b2012-06-20 16:38:30 -07009899 pAdapter->device_mode = session_type;
9900
Mahesh A Saptasagar67ab9222015-10-21 15:38:41 +05309901 hdd_initialize_adapter_common(pAdapter);
louisliu462edac2020-06-30 13:33:56 +08009902 status = hdd_init_ap_mode(pAdapter, false);
9903 if( VOS_STATUS_SUCCESS != status )
9904 goto err_free_netdev;
Jeff Johnson295189b2012-06-20 16:38:30 -07009905
Nirav Shah7e3c8132015-06-22 23:51:42 +05309906 status = hdd_sta_id_hash_attach(pAdapter);
9907 if (VOS_STATUS_SUCCESS != status)
9908 {
9909 hddLog(VOS_TRACE_LEVEL_FATAL,
9910 FL("failed to attach hash for session %d"), session_type);
louisliu462edac2020-06-30 13:33:56 +08009911 hdd_deinit_adapter(pHddCtx, pAdapter, rtnl_held);
Nirav Shah7e3c8132015-06-22 23:51:42 +05309912 goto err_free_netdev;
9913 }
9914
Jeff Johnson295189b2012-06-20 16:38:30 -07009915 status = hdd_register_hostapd( pAdapter, rtnl_held );
9916 if( VOS_STATUS_SUCCESS != status )
9917 {
c_hpothu002231a2015-02-05 14:58:51 +05309918 hdd_deinit_adapter(pHddCtx, pAdapter, rtnl_held);
Jeff Johnson295189b2012-06-20 16:38:30 -07009919 goto err_free_netdev;
9920 }
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +05309921 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Jeff Johnson295189b2012-06-20 16:38:30 -07009922 netif_tx_disable(pAdapter->dev);
9923 netif_carrier_off(pAdapter->dev);
9924
9925 hdd_set_conparam( 1 );
Ganesh Kondabattinibabfb492014-12-17 20:25:29 +05309926
Hanumanth Reddy Pothulab4537b82018-03-02 12:20:38 +05309927 // Workqueue which gets scheduled in IPv4 notification callback.
9928 vos_init_work(&pAdapter->ipv4NotifierWorkQueue,
9929 hdd_ipv4_notifier_work_queue);
9930
9931#ifdef WLAN_NS_OFFLOAD
9932 // Workqueue which gets scheduled in IPv6 notification callback.
9933 vos_init_work(&pAdapter->ipv6NotifierWorkQueue,
9934 hdd_ipv6_notifier_work_queue);
9935#endif
9936
Ganesh Kondabattinibabfb492014-12-17 20:25:29 +05309937 if (WLAN_HDD_P2P_GO == session_type)
9938 {
9939 /* Initialize the work queue to
9940 * defer the back to back RoC request */
9941 INIT_DELAYED_WORK(&pAdapter->roc_work,
9942 hdd_p2p_roc_work_queue);
9943 }
Bhargav Shahd0715912015-10-01 18:17:37 +05309944
Jeff Johnson295189b2012-06-20 16:38:30 -07009945 break;
9946 }
9947 case WLAN_HDD_MONITOR:
9948 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009949 pAdapter = hdd_alloc_station_adapter( pHddCtx, macAddr, iface_name );
9950 if( NULL == pAdapter )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309951 {
9952 hddLog(VOS_TRACE_LEVEL_FATAL,
9953 FL("failed to allocate adapter for session %d"), session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07009954 return NULL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309955 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009956
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +05309957 pAdapter->device_mode = session_type;
9958 pAdapter->wdev.iftype = NL80211_IFTYPE_MONITOR;
9959
Katya Nigame7b69a82015-04-28 15:24:06 +05309960 // Register wireless extensions
9961 if( VOS_STATUS_SUCCESS != (status = hdd_register_wext(pAdapter->dev)))
9962 {
9963 hddLog(VOS_TRACE_LEVEL_FATAL,
9964 "hdd_register_wext() failed with status code %08d [x%08x]",
9965 status, status );
9966 status = VOS_STATUS_E_FAILURE;
9967 }
9968
Jeff Johnson295189b2012-06-20 16:38:30 -07009969#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29)
9970 pAdapter->dev->netdev_ops = &wlan_mon_drv_ops;
9971#else
9972 pAdapter->dev->open = hdd_mon_open;
9973 pAdapter->dev->hard_start_xmit = hdd_mon_hard_start_xmit;
Katya Nigame7b69a82015-04-28 15:24:06 +05309974 pAdapter->dev->stop = hdd_mon_stop;
9975 pAdapter->dev->do_ioctl = hdd_mon_ioctl;
Jeff Johnson295189b2012-06-20 16:38:30 -07009976#endif
Katya Nigame7b69a82015-04-28 15:24:06 +05309977 hdd_init_mon_mode( pAdapter );
Mahesh A Saptasagar67ab9222015-10-21 15:38:41 +05309978 hdd_initialize_adapter_common(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07009979 hdd_init_tx_rx( pAdapter );
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +05309980
9981 if (VOS_MONITOR_MODE != hdd_get_conparam())
9982 WLANTL_SetMonRxCbk( pVosContext, hdd_rx_packet_monitor_cbk );
9983
Jeff Johnson295189b2012-06-20 16:38:30 -07009984 set_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +05309985 status = hdd_register_interface( pAdapter, rtnl_held );
Katya Nigame7b69a82015-04-28 15:24:06 +05309986 //Stop the Interface TX queue.
9987 netif_tx_disable(pAdapter->dev);
9988 netif_carrier_off(pAdapter->dev);
Jeff Johnson295189b2012-06-20 16:38:30 -07009989 }
9990 break;
Jeff Johnson295189b2012-06-20 16:38:30 -07009991 case WLAN_HDD_FTM:
9992 {
9993 pAdapter = hdd_alloc_station_adapter( pHddCtx, macAddr, iface_name );
9994
9995 if( NULL == pAdapter )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309996 {
9997 hddLog(VOS_TRACE_LEVEL_FATAL,
9998 FL("failed to allocate adapter for session %d"), session_type);
9999 return NULL;
10000 }
10001
Jeff Johnson295189b2012-06-20 16:38:30 -070010002 /* Assign NL80211_IFTYPE_STATION as interface type to resolve Kernel Warning
10003 * message while loading driver in FTM mode. */
10004 pAdapter->wdev.iftype = NL80211_IFTYPE_STATION;
10005 pAdapter->device_mode = session_type;
10006 status = hdd_register_interface( pAdapter, rtnl_held );
Madan Mohan Koyyalamudif89ac9f2013-09-19 16:58:12 +053010007
Mahesh A Saptasagar67ab9222015-10-21 15:38:41 +053010008 hdd_initialize_adapter_common(pAdapter);
Madan Mohan Koyyalamudif89ac9f2013-09-19 16:58:12 +053010009 hdd_init_tx_rx( pAdapter );
10010
10011 //Stop the Interface TX queue.
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +053010012 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Madan Mohan Koyyalamudif89ac9f2013-09-19 16:58:12 +053010013 netif_tx_disable(pAdapter->dev);
10014 netif_carrier_off(pAdapter->dev);
Jeff Johnson295189b2012-06-20 16:38:30 -070010015 }
10016 break;
Jeff Johnson295189b2012-06-20 16:38:30 -070010017 default:
10018 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010019 hddLog(VOS_TRACE_LEVEL_FATAL,"%s Invalid session type %d",
10020 __func__, session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -070010021 VOS_ASSERT(0);
10022 return NULL;
10023 }
10024 }
10025
Jeff Johnson295189b2012-06-20 16:38:30 -070010026 if( VOS_STATUS_SUCCESS == status )
10027 {
Mahesh A Saptasagar67ab9222015-10-21 15:38:41 +053010028 //Add it to the hdd's session list.
Jeff Johnson295189b2012-06-20 16:38:30 -070010029 pHddAdapterNode = vos_mem_malloc( sizeof( hdd_adapter_list_node_t ) );
10030 if( NULL == pHddAdapterNode )
10031 {
10032 status = VOS_STATUS_E_NOMEM;
10033 }
10034 else
10035 {
10036 pHddAdapterNode->pAdapter = pAdapter;
10037 status = hdd_add_adapter_back ( pHddCtx,
10038 pHddAdapterNode );
10039 }
10040 }
10041
10042 if( VOS_STATUS_SUCCESS != status )
10043 {
10044 if( NULL != pAdapter )
10045 {
10046 hdd_cleanup_adapter( pHddCtx, pAdapter, rtnl_held );
10047 pAdapter = NULL;
10048 }
10049 if( NULL != pHddAdapterNode )
10050 {
10051 vos_mem_free( pHddAdapterNode );
10052 }
10053
10054 goto resume_bmps;
10055 }
10056
10057 if(VOS_STATUS_SUCCESS == status)
10058 {
10059 wlan_hdd_set_concurrency_mode(pHddCtx, session_type);
Madan Mohan Koyyalamudi96dd30d2012-10-05 17:24:51 -070010060 //Initialize the WoWL service
10061 if(!hdd_init_wowl(pAdapter))
10062 {
10063 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hdd_init_wowl failed",__func__);
10064 goto err_free_netdev;
10065 }
Manjeet Singh3ed79242017-01-11 19:04:32 +053010066 //Initialize the TSF capture data
10067 wlan_hdd_tsf_init(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070010068 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010069 return pAdapter;
10070
10071err_free_netdev:
Jeff Johnson295189b2012-06-20 16:38:30 -070010072 wlan_hdd_release_intf_addr( pHddCtx,
10073 pAdapter->macAddressCurrent.bytes );
Hanumanth Reddy Pothulaab8e1942018-05-24 18:10:39 +053010074 free_netdev(pAdapter->dev);
Jeff Johnson295189b2012-06-20 16:38:30 -070010075
10076resume_bmps:
10077 //If bmps disabled enable it
10078 if(VOS_STATUS_SUCCESS == exitbmpsStatus)
10079 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +053010080 if (pHddCtx->hdd_wlan_suspended)
10081 {
10082 hdd_set_pwrparams(pHddCtx);
10083 }
10084 hdd_enable_bmps_imps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -070010085 }
10086 return NULL;
10087}
10088
10089VOS_STATUS hdd_close_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter,
10090 tANI_U8 rtnl_held )
10091{
10092 hdd_adapter_list_node_t *pAdapterNode, *pCurrent, *pNext;
10093 VOS_STATUS status;
10094
10095 status = hdd_get_front_adapter ( pHddCtx, &pCurrent );
10096 if( VOS_STATUS_SUCCESS != status )
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010097 {
10098 hddLog(VOS_TRACE_LEVEL_WARN,"%s: adapter list empty %d",
10099 __func__, status);
Jeff Johnson295189b2012-06-20 16:38:30 -070010100 return status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010101 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010102
10103 while ( pCurrent->pAdapter != pAdapter )
10104 {
10105 status = hdd_get_next_adapter ( pHddCtx, pCurrent, &pNext );
10106 if( VOS_STATUS_SUCCESS != status )
10107 break;
10108
10109 pCurrent = pNext;
10110 }
10111 pAdapterNode = pCurrent;
10112 if( VOS_STATUS_SUCCESS == status )
10113 {
10114 wlan_hdd_clear_concurrency_mode(pHddCtx, pAdapter->device_mode);
10115 hdd_cleanup_adapter( pHddCtx, pAdapterNode->pAdapter, rtnl_held );
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053010116
10117#ifdef FEATURE_WLAN_TDLS
10118
10119 /* A Mutex Lock is introduced while changing/initializing the mode to
10120 * protect the concurrent access for the Adapters by TDLS module.
10121 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053010122 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053010123#endif
10124
Jeff Johnson295189b2012-06-20 16:38:30 -070010125 hdd_remove_adapter( pHddCtx, pAdapterNode );
10126 vos_mem_free( pAdapterNode );
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -080010127 pAdapterNode = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070010128
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053010129#ifdef FEATURE_WLAN_TDLS
10130 mutex_unlock(&pHddCtx->tdls_lock);
10131#endif
10132
Jeff Johnson295189b2012-06-20 16:38:30 -070010133
10134 /* If there is a single session of STA/P2P client, re-enable BMPS */
Agarwal Ashish51325b52014-06-16 16:50:49 +053010135 if ((!vos_concurrent_open_sessions_running()) &&
10136 ((pHddCtx->no_of_open_sessions[VOS_STA_MODE] >= 1) ||
10137 (pHddCtx->no_of_open_sessions[VOS_P2P_CLIENT_MODE] >= 1)))
Jeff Johnson295189b2012-06-20 16:38:30 -070010138 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +053010139 if (pHddCtx->hdd_wlan_suspended)
10140 {
10141 hdd_set_pwrparams(pHddCtx);
10142 }
10143 hdd_enable_bmps_imps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -070010144 }
10145
10146 return VOS_STATUS_SUCCESS;
10147 }
10148
10149 return VOS_STATUS_E_FAILURE;
10150}
10151
10152VOS_STATUS hdd_close_all_adapters( hdd_context_t *pHddCtx )
10153{
10154 hdd_adapter_list_node_t *pHddAdapterNode;
10155 VOS_STATUS status;
10156
10157 ENTER();
10158
10159 do
10160 {
10161 status = hdd_remove_front_adapter( pHddCtx, &pHddAdapterNode );
10162 if( pHddAdapterNode && VOS_STATUS_SUCCESS == status )
10163 {
10164 hdd_cleanup_adapter( pHddCtx, pHddAdapterNode->pAdapter, FALSE );
10165 vos_mem_free( pHddAdapterNode );
10166 }
10167 }while( NULL != pHddAdapterNode && VOS_STATUS_E_EMPTY != status );
10168
10169 EXIT();
10170
10171 return VOS_STATUS_SUCCESS;
10172}
10173
10174void wlan_hdd_reset_prob_rspies(hdd_adapter_t* pHostapdAdapter)
10175{
10176 v_U8_t addIE[1] = {0};
10177
10178 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
10179 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,(tANI_U8*)addIE, 0, NULL,
10180 eANI_BOOLEAN_FALSE) )
10181 {
10182 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010183 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -070010184 }
10185
10186 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
10187 WNI_CFG_PROBE_RSP_ADDNIE_DATA2, (tANI_U8*)addIE, 0, NULL,
10188 eANI_BOOLEAN_FALSE) )
10189 {
10190 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010191 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -070010192 }
10193
10194 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
10195 WNI_CFG_PROBE_RSP_ADDNIE_DATA3, (tANI_U8*)addIE, 0, NULL,
10196 eANI_BOOLEAN_FALSE) )
10197 {
10198 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010199 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -070010200 }
10201}
10202
Anurag Chouhan83026002016-12-13 22:46:21 +053010203VOS_STATUS hdd_cleanup_ap_events(hdd_adapter_t *adapter)
10204{
10205#ifdef DHCP_SERVER_OFFLOAD
10206 vos_event_destroy(&adapter->dhcp_status.vos_event);
10207#endif
Anurag Chouhan0b29de02016-12-16 13:18:40 +053010208#ifdef MDNS_OFFLOAD
10209 vos_event_destroy(&adapter->mdns_status.vos_event);
10210#endif
Anurag Chouhan83026002016-12-13 22:46:21 +053010211 return VOS_STATUS_SUCCESS;
10212}
10213
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +053010214int wlan_hdd_stop_mon(hdd_context_t *hdd_ctx, bool wait)
10215{
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +053010216 hdd_adapter_t *adapter;
Hanumanth Reddy Pothulab8be9ab2018-04-12 20:03:05 +053010217 hdd_mon_ctx_t *mon_ctx;
10218 void (*func_ptr)(void *context) = NULL;
10219 int ret = 0;
10220 void *cookie = NULL;
10221 struct hdd_request *request;
10222 static const struct hdd_request_params params = {
10223 .priv_size = 0,
10224 .timeout_ms = MON_MODE_MSG_TIMEOUT,
10225 };
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +053010226
10227 adapter = hdd_get_adapter(hdd_ctx, WLAN_HDD_MONITOR);
10228 if (!adapter) {
10229 hddLog(LOGE, FL("Invalid STA + MON mode"));
10230 return -EINVAL;
10231 }
10232
10233 mon_ctx = WLAN_HDD_GET_MONITOR_CTX_PTR(adapter);
10234 if (!mon_ctx)
10235 return 0;
10236
10237 if (mon_ctx->state != MON_MODE_START)
10238 return 0;
10239
10240 mon_ctx->state = MON_MODE_STOP;
10241 if (wait) {
Hanumanth Reddy Pothulab8be9ab2018-04-12 20:03:05 +053010242 func_ptr = hdd_mon_post_msg_cb;
10243 request = hdd_request_alloc(&params);
10244 if (!request) {
10245 hddLog(VOS_TRACE_LEVEL_ERROR,
10246 FL("Request allocation failure"));
10247 return -ENOMEM;
10248 }
10249 cookie = hdd_request_cookie(request);
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +053010250 }
10251
Hanumanth Reddy Pothulab8be9ab2018-04-12 20:03:05 +053010252 /*
10253 * If func_ptr is NULL, on receiving WDI_MON_START_RSP or
10254 * WDI_MON_STOP_RSP hdd_mon_post_msg_cb() won't be invoked
10255 * and so uninitialized cookie won't be accessed.
10256 */
10257 if (VOS_STATUS_SUCCESS != wlan_hdd_mon_postMsg(cookie,
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +053010258 mon_ctx,
Hanumanth Reddy Pothulab8be9ab2018-04-12 20:03:05 +053010259 func_ptr)) {
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +053010260 hddLog(LOGE, FL("failed to stop MON MODE"));
Hanumanth Reddy Pothulab8be9ab2018-04-12 20:03:05 +053010261 ret = -EINVAL;
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +053010262 }
10263
10264 if (!wait)
10265 goto bmps_roaming;
10266
Hanumanth Reddy Pothulab8be9ab2018-04-12 20:03:05 +053010267 if (!ret)
10268 ret = hdd_request_wait_for_response(request);
10269 hdd_request_put(request);
10270 if (ret) {
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +053010271 hddLog(LOGE,
Hanumanth Reddy Pothulab8be9ab2018-04-12 20:03:05 +053010272 FL("timeout on stop monitor mode completion %d"), ret);
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +053010273 return -EINVAL;
10274 }
10275
10276bmps_roaming:
10277 hddLog(LOG1, FL("Enable BMPS"));
10278 hdd_enable_bmps_imps(hdd_ctx);
10279 hdd_restore_roaming(hdd_ctx);
10280
10281 return 0;
10282}
10283
10284bool wlan_hdd_check_monitor_state(hdd_context_t *hdd_ctx)
10285{
10286 hdd_adapter_t *mon_adapter;
10287 hdd_mon_ctx_t *mon_ctx;
10288
10289 if (hdd_ctx->concurrency_mode != VOS_STA_MON)
10290 return false;
10291
10292 mon_adapter = hdd_get_adapter(hdd_ctx, WLAN_HDD_MONITOR);
10293 if (!mon_adapter) {
10294 hddLog(LOGE, FL("Invalid concurrency mode"));
10295 return false;
10296 }
10297
10298 mon_ctx = WLAN_HDD_GET_MONITOR_CTX_PTR(mon_adapter);
10299 if (mon_ctx->state == MON_MODE_START)
10300 return true;
10301
10302 return false;
10303}
10304
10305int wlan_hdd_check_and_stop_mon(hdd_adapter_t *sta_adapter, bool wait)
10306{
10307 hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(sta_adapter);
10308
10309 if ((sta_adapter->device_mode != WLAN_HDD_INFRA_STATION) ||
10310 !wlan_hdd_check_monitor_state(hdd_ctx))
10311 return 0;
10312
10313 if (wlan_hdd_stop_mon(hdd_ctx, wait))
10314 return -EINVAL;
10315
10316 return 0;
10317}
10318
10319void hdd_disable_roaming(hdd_context_t *hdd_ctx)
10320{
10321 if (!hdd_ctx)
10322 return;
10323
10324 if (!hdd_ctx->cfg_ini->isFastRoamIniFeatureEnabled) {
10325 hdd_ctx->roaming_ini_original = CFG_LFR_FEATURE_ENABLED_MIN;
10326 return;
10327 }
10328
10329 hddLog(LOG1, FL("Disable driver and firmware roaming"));
10330
10331 hdd_ctx->roaming_ini_original =
10332 hdd_ctx->cfg_ini->isFastRoamIniFeatureEnabled;
10333
10334 hdd_ctx->cfg_ini->isFastRoamIniFeatureEnabled =
10335 CFG_LFR_FEATURE_ENABLED_MIN;
10336
10337 sme_UpdateIsFastRoamIniFeatureEnabled(hdd_ctx->hHal,
10338 CFG_LFR_FEATURE_ENABLED_MIN);
10339}
10340
10341void hdd_restore_roaming(hdd_context_t *hdd_ctx)
10342{
10343 if (!hdd_ctx->roaming_ini_original)
10344 return;
10345
10346 hddLog(LOG1, FL("Enable driver and firmware roaming"));
10347
10348 hdd_ctx->cfg_ini->isFastRoamIniFeatureEnabled =
10349 CFG_LFR_FEATURE_ENABLED_MAX;
10350
10351 hdd_ctx->roaming_ini_original = CFG_LFR_FEATURE_ENABLED_MIN;
10352
10353 sme_UpdateIsFastRoamIniFeatureEnabled(hdd_ctx->hHal,
10354 CFG_LFR_FEATURE_ENABLED_MAX);
10355}
Anurag Chouhan83026002016-12-13 22:46:21 +053010356
Agarwal Ashish3a38bd12014-06-12 15:16:52 +053010357VOS_STATUS hdd_stop_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter,
10358 const v_BOOL_t bCloseSession )
Jeff Johnson295189b2012-06-20 16:38:30 -070010359{
10360 eHalStatus halStatus = eHAL_STATUS_SUCCESS;
10361 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Kaushik, Sushant4975a572014-10-21 16:07:48 +053010362 hdd_scaninfo_t *pScanInfo = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070010363 union iwreq_data wrqu;
Kaushik, Sushant7005e372014-04-08 11:36:54 +053010364 v_U8_t retry = 0;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010365 long ret;
Nirav Shah7e3c8132015-06-22 23:51:42 +053010366 VOS_STATUS status;
Jeff Johnson295189b2012-06-20 16:38:30 -070010367
Anand N Sunkad26d71b92014-12-24 18:08:22 +053010368 if (pHddCtx->isLogpInProgress) {
10369 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
10370 "%s:LOGP in Progress. Ignore!!!",__func__);
10371 return VOS_STATUS_E_FAILURE;
10372 }
10373
Jeff Johnson295189b2012-06-20 16:38:30 -070010374 ENTER();
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +053010375
Kaushik, Sushant4975a572014-10-21 16:07:48 +053010376 pScanInfo = &pHddCtx->scan_info;
Jeff Johnson295189b2012-06-20 16:38:30 -070010377 switch(pAdapter->device_mode)
10378 {
Nirav Shah0cf4d892015-11-05 16:27:27 +053010379 case WLAN_HDD_IBSS:
10380 if ( VOS_TRUE == bCloseSession )
10381 {
10382 status = hdd_sta_id_hash_detach(pAdapter);
10383 if (status != VOS_STATUS_SUCCESS)
10384 hddLog(VOS_TRACE_LEVEL_ERROR,
10385 FL("sta id hash detach failed"));
10386 }
10387
Jeff Johnson295189b2012-06-20 16:38:30 -070010388 case WLAN_HDD_INFRA_STATION:
10389 case WLAN_HDD_P2P_CLIENT:
Jeff Johnsone7245742012-09-05 17:12:55 -070010390 case WLAN_HDD_P2P_DEVICE:
Vinay Krishna Erannab09d3e72014-03-26 21:23:55 +053010391 {
10392 hdd_station_ctx_t *pstation = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Mahesh A Saptasagare4d05d42015-07-02 16:17:20 +053010393#ifdef FEATURE_WLAN_TDLS
10394 mutex_lock(&pHddCtx->tdls_lock);
10395 wlan_hdd_tdls_exit(pAdapter, TRUE);
10396 mutex_unlock(&pHddCtx->tdls_lock);
10397#endif
Abhinav Kumare548f1e2018-07-12 16:40:43 +053010398 if(hdd_connIsConnected(pstation) ||
10399 (pstation->conn_info.connState == eConnectionState_Connecting))
Jeff Johnson295189b2012-06-20 16:38:30 -070010400 {
10401 if (pWextState->roamProfile.BSSType == eCSR_BSS_TYPE_START_IBSS)
Abhinav Kumare548f1e2018-07-12 16:40:43 +053010402 {
10403 INIT_COMPLETION(pAdapter->disconnect_comp_var);
Jeff Johnson295189b2012-06-20 16:38:30 -070010404 halStatus = sme_RoamDisconnect(pHddCtx->hHal,
10405 pAdapter->sessionId,
10406 eCSR_DISCONNECT_REASON_IBSS_LEAVE);
Abhinav Kumare548f1e2018-07-12 16:40:43 +053010407 /* Success implies disconnect command got queued up successfully
10408 * Or cmd not queued as scan for SSID is in progress
10409 */
10410 if((eHAL_STATUS_SUCCESS == halStatus) ||
10411 (eHAL_STATUS_CMD_NOT_QUEUED == halStatus))
10412 {
10413 ret = wait_for_completion_timeout(
10414 &pAdapter->disconnect_comp_var,
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010415 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
Abhinav Kumare548f1e2018-07-12 16:40:43 +053010416 if (ret <= 0 &&
10417 (eHAL_STATUS_CMD_NOT_QUEUED != halStatus))
10418 {
10419 hddLog(VOS_TRACE_LEVEL_ERROR,
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010420 "%s: wait on disconnect_comp_var failed %ld",
10421 __func__, ret);
Abhinav Kumare548f1e2018-07-12 16:40:43 +053010422 }
10423 }
10424 else
10425 {
10426 hddLog(LOGE, "%s: failed to post disconnect event to SME",
10427 __func__);
10428 }
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010429 }
10430 else
10431 {
Abhinav Kumare548f1e2018-07-12 16:40:43 +053010432 wlan_hdd_disconnect(pAdapter, eCSR_DISCONNECT_REASON_DEAUTH);
Jeff Johnson295189b2012-06-20 16:38:30 -070010433 }
10434 memset(&wrqu, '\0', sizeof(wrqu));
10435 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
10436 memset(wrqu.ap_addr.sa_data,'\0',ETH_ALEN);
10437 wireless_send_event(pAdapter->dev, SIOCGIWAP, &wrqu, NULL);
10438 }
Vinay Krishna Erannab09d3e72014-03-26 21:23:55 +053010439 else if(pstation->conn_info.connState ==
10440 eConnectionState_Disconnecting)
10441 {
10442 ret = wait_for_completion_interruptible_timeout(
10443 &pAdapter->disconnect_comp_var,
10444 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
10445 if (ret <= 0)
10446 {
10447 hddLog(VOS_TRACE_LEVEL_ERROR,
10448 FL("wait on disconnect_comp_var failed %ld"), ret);
10449 }
10450 }
Sachin Ahuja27dd2402016-08-01 20:30:31 +053010451 if(pScanInfo != NULL && pHddCtx->scan_info.mScanPending)
Jeff Johnson295189b2012-06-20 16:38:30 -070010452 {
Mahesh A Saptasagar0b61dcc2016-02-15 14:23:38 +053010453 wlan_hdd_scan_abort(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070010454 }
Abhishek Singh3ac179b2015-09-21 10:01:34 +053010455 if ((pAdapter->device_mode != WLAN_HDD_INFRA_STATION) &&
10456 (pAdapter->device_mode != WLAN_HDD_IBSS))
Kaushik, Sushant7005e372014-04-08 11:36:54 +053010457 {
10458 while (pAdapter->is_roc_inprogress)
10459 {
10460 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10461 "%s: ROC in progress for session %d!!!",
10462 __func__, pAdapter->sessionId);
10463 // waiting for ROC to expire
10464 msleep(500);
10465 /* In GO present case , if retry exceeds 3,
10466 it means something went wrong. */
10467 if ( retry++ > MAX_WAIT_FOR_ROC_COMPLETION )
10468 {
10469 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10470 "%s: ROC completion is not received.!!!", __func__);
Deepthi Gowri70498252015-01-20 15:56:45 +053010471 if (eHAL_STATUS_SUCCESS !=
10472 sme_CancelRemainOnChannel( WLAN_HDD_GET_HAL_CTX( pAdapter),
10473 pAdapter->sessionId ))
10474 {
10475 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10476 FL("Failed to Cancel Remain on Channel"));
10477 }
Kaushik, Sushant7005e372014-04-08 11:36:54 +053010478 wait_for_completion_interruptible_timeout(
10479 &pAdapter->cancel_rem_on_chan_var,
10480 msecs_to_jiffies(WAIT_CANCEL_REM_CHAN));
10481 break;
10482 }
10483 }
Anand N Sunkaddc63c792015-06-03 14:33:24 +053010484 vos_flush_delayed_work(&pAdapter->roc_work);
Kaushik, Sushant7005e372014-04-08 11:36:54 +053010485 }
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +053010486#ifdef WLAN_NS_OFFLOAD
Anand N Sunkaddc63c792015-06-03 14:33:24 +053010487 vos_flush_work(&pAdapter->ipv6NotifierWorkQueue);
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +053010488#endif
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +053010489
Anand N Sunkaddc63c792015-06-03 14:33:24 +053010490 vos_flush_work(&pAdapter->ipv4NotifierWorkQueue);
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +053010491
Agarwal Ashish3a38bd12014-06-12 15:16:52 +053010492 /* It is possible that the caller of this function does not
10493 * wish to close the session
10494 */
10495 if (VOS_TRUE == bCloseSession &&
10496 test_bit(SME_SESSION_OPENED, &pAdapter->event_flags))
Jeff Johnson295189b2012-06-20 16:38:30 -070010497 {
10498 INIT_COMPLETION(pAdapter->session_close_comp_var);
10499 if (eHAL_STATUS_SUCCESS ==
Agrawal Ashish5a3522c2016-03-02 15:08:28 +053010500 sme_CloseSession(pHddCtx->hHal, pAdapter->sessionId, FALSE,
10501 VOS_FALSE, hdd_smeCloseSessionCallback, pAdapter))
Jeff Johnson295189b2012-06-20 16:38:30 -070010502 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010503 unsigned long ret;
10504
Jeff Johnson295189b2012-06-20 16:38:30 -070010505 //Block on a completion variable. Can't wait forever though.
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010506 ret = wait_for_completion_timeout(
Agarwal Ashish3a38bd12014-06-12 15:16:52 +053010507 &pAdapter->session_close_comp_var,
10508 msecs_to_jiffies(WLAN_WAIT_TIME_SESSIONOPENCLOSE));
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010509 if ( 0 >= ret)
10510 {
10511 hddLog(LOGE, "%s: failure waiting for session_close_comp_var %ld",
Agarwal Ashish3a38bd12014-06-12 15:16:52 +053010512 __func__, ret);
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010513 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010514 }
10515 }
Vinay Krishna Erannab09d3e72014-03-26 21:23:55 +053010516 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010517 break;
10518
10519 case WLAN_HDD_SOFTAP:
Abhishek Singh3dc4c972019-05-09 11:04:24 +053010520 /* Delete all associated STAs before stopping AP */
10521 if (test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
10522 hdd_del_all_sta(pAdapter);
10523 /* Fall through */
Jeff Johnson295189b2012-06-20 16:38:30 -070010524 case WLAN_HDD_P2P_GO:
Abhishek Singh3dc4c972019-05-09 11:04:24 +053010525
Nirav Shah0cf4d892015-11-05 16:27:27 +053010526 if ( VOS_TRUE == bCloseSession )
10527 {
10528 status = hdd_sta_id_hash_detach(pAdapter);
10529 if (status != VOS_STATUS_SUCCESS)
10530 hddLog(VOS_TRACE_LEVEL_ERROR,
10531 FL("sta id hash detach failed"));
10532 }
10533
Jeff Johnson295189b2012-06-20 16:38:30 -070010534 //Any softap specific cleanup here...
Anurag Chouhan83026002016-12-13 22:46:21 +053010535 hdd_cleanup_ap_events(pAdapter);
Kaushik, Sushant7005e372014-04-08 11:36:54 +053010536 if (pAdapter->device_mode == WLAN_HDD_P2P_GO) {
10537 while (pAdapter->is_roc_inprogress) {
10538 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10539 "%s: ROC in progress for session %d!!!",
10540 __func__, pAdapter->sessionId);
10541 msleep(500);
10542 if ( retry++ > MAX_WAIT_FOR_ROC_COMPLETION ) {
10543 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10544 "%s: ROC completion is not received.!!!", __func__);
10545 WLANSAP_CancelRemainOnChannel(
10546 (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
10547 wait_for_completion_interruptible_timeout(
10548 &pAdapter->cancel_rem_on_chan_var,
10549 msecs_to_jiffies(WAIT_CANCEL_REM_CHAN));
10550 break;
10551 }
10552 }
Ganesh Kondabattinibabfb492014-12-17 20:25:29 +053010553
Anand N Sunkaddc63c792015-06-03 14:33:24 +053010554 vos_flush_delayed_work(&pAdapter->roc_work);
Kaushik, Sushant7005e372014-04-08 11:36:54 +053010555 }
Agrawal Ashish17ef5082016-10-17 18:33:21 +053010556#ifdef SAP_AUTH_OFFLOAD
10557 if (pHddCtx->cfg_ini->enable_sap_auth_offload)
10558 hdd_set_sap_auth_offload(pAdapter, FALSE);
10559#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010560 mutex_lock(&pHddCtx->sap_lock);
10561 if (test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
10562 {
10563 VOS_STATUS status;
10564 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Hanumanth Reddy Pothula74ba68c2018-06-22 17:52:09 +053010565 hdd_hostapd_state_t *pHostapdState =
10566 WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070010567
Hanumanth Reddy Pothula74ba68c2018-06-22 17:52:09 +053010568 vos_event_reset(&pHostapdState->vosEvent);
Jeff Johnson295189b2012-06-20 16:38:30 -070010569 //Stop Bss.
10570 status = WLANSAP_StopBss(pHddCtx->pvosContext);
10571 if (VOS_IS_STATUS_SUCCESS(status))
10572 {
Jeff Johnson295189b2012-06-20 16:38:30 -070010573 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
10574
10575 if (!VOS_IS_STATUS_SUCCESS(status))
10576 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010577 hddLog(LOGE, "%s: failure waiting for WLANSAP_StopBss %d",
10578 __func__, status);
Jeff Johnson295189b2012-06-20 16:38:30 -070010579 }
10580 }
10581 else
10582 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070010583 hddLog(LOGE, "%s: failure in WLANSAP_StopBss", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070010584 }
10585 clear_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags);
Agarwal Ashish51325b52014-06-16 16:50:49 +053010586 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070010587
10588 if (eHAL_STATUS_FAILURE ==
10589 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG,
10590 0, NULL, eANI_BOOLEAN_FALSE))
10591 {
10592 hddLog(LOGE,
10593 "%s: Failed to set WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070010594 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070010595 }
10596
10597 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt((WLAN_HDD_GET_CTX(pAdapter))->hHal,
10598 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
10599 eANI_BOOLEAN_FALSE) )
10600 {
10601 hddLog(LOGE,
10602 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
10603 }
10604
10605 // Reset WNI_CFG_PROBE_RSP Flags
10606 wlan_hdd_reset_prob_rspies(pAdapter);
10607 kfree(pAdapter->sessionCtx.ap.beacon);
10608 pAdapter->sessionCtx.ap.beacon = NULL;
10609 }
10610 mutex_unlock(&pHddCtx->sap_lock);
Hanumanth Reddy Pothulab4537b82018-03-02 12:20:38 +053010611
10612#ifdef WLAN_NS_OFFLOAD
10613 vos_flush_work(&pAdapter->ipv6NotifierWorkQueue);
10614#endif
10615 vos_flush_work(&pAdapter->ipv4NotifierWorkQueue);
10616
Jeff Johnson295189b2012-06-20 16:38:30 -070010617 break;
Sameer Thalappilbee426e2013-10-30 10:30:30 -070010618
Jeff Johnson295189b2012-06-20 16:38:30 -070010619 case WLAN_HDD_MONITOR:
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +053010620 if (VOS_MONITOR_MODE != hdd_get_conparam())
10621 wlan_hdd_stop_mon(pHddCtx, true);
10622 break;
Sameer Thalappilbee426e2013-10-30 10:30:30 -070010623
Jeff Johnson295189b2012-06-20 16:38:30 -070010624 default:
10625 break;
10626 }
10627
10628 EXIT();
10629 return VOS_STATUS_SUCCESS;
10630}
10631
Kapil Gupta137ef892016-12-13 19:38:00 +053010632/**
10633 * wlan_hdd_restart_sap() - to restart SAP in driver internally
10634 * @ap_adapter: - Pointer to SAP hdd_adapter_t structure
10635 *
10636 * wlan_hdd_restart_sap first delete SAP and do cleanup.
10637 * After that WLANSAP_StartBss start re-start process of SAP.
10638 *
10639 * Return: None
10640 */
10641static void wlan_hdd_restart_sap(hdd_adapter_t *ap_adapter)
10642{
10643 hdd_ap_ctx_t *pHddApCtx;
10644 hdd_hostapd_state_t *pHostapdState;
10645 VOS_STATUS vos_status;
10646 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(ap_adapter);
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053010647#ifdef USE_CFG80211_DEL_STA_V2
Kapil Gupta137ef892016-12-13 19:38:00 +053010648 struct station_del_parameters delStaParams;
10649#endif
10650 tsap_Config_t *pConfig;
10651
10652 pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(ap_adapter);
10653 pConfig = &pHddApCtx->sapConfig;
10654
10655 mutex_lock(&pHddCtx->sap_lock);
10656 if (test_bit(SOFTAP_BSS_STARTED, &ap_adapter->event_flags)) {
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053010657#ifdef USE_CFG80211_DEL_STA_V2
Kapil Gupta137ef892016-12-13 19:38:00 +053010658 delStaParams.mac = NULL;
10659 delStaParams.subtype = SIR_MAC_MGMT_DEAUTH >> 4;
10660 delStaParams.reason_code = eCsrForcedDeauthSta;
10661 wlan_hdd_cfg80211_del_station(ap_adapter->wdev.wiphy, ap_adapter->dev,
10662 &delStaParams);
10663#else
10664 wlan_hdd_cfg80211_del_station(ap_adapter->wdev.wiphy, ap_adapter->dev,
10665 NULL);
10666#endif
10667 hdd_cleanup_actionframe(pHddCtx, ap_adapter);
10668
10669 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(ap_adapter);
10670 vos_event_reset(&pHostapdState->vosEvent);
10671
10672 if (VOS_STATUS_SUCCESS == WLANSAP_StopBss(pHddCtx->pvosContext)) {
10673 vos_status = vos_wait_single_event(&pHostapdState->vosEvent,
10674 10000);
10675 if (!VOS_IS_STATUS_SUCCESS(vos_status)) {
10676 hddLog(LOGE, FL("SAP Stop Failed"));
10677 goto end;
10678 }
10679 }
10680 clear_bit(SOFTAP_BSS_STARTED, &ap_adapter->event_flags);
10681 wlan_hdd_decr_active_session(pHddCtx, ap_adapter->device_mode);
10682 hddLog(LOG1, FL("SAP Stop Success"));
10683
10684 if (0 != wlan_hdd_cfg80211_update_apies(ap_adapter)) {
10685 hddLog(LOGE, FL("SAP Not able to set AP IEs"));
10686 goto end;
10687 }
10688
Hanumanth Reddy Pothula74ba68c2018-06-22 17:52:09 +053010689 vos_event_reset(&pHostapdState->vosEvent);
Kapil Gupta137ef892016-12-13 19:38:00 +053010690 if (WLANSAP_StartBss(pHddCtx->pvosContext, hdd_hostapd_SAPEventCB,
10691 pConfig, (v_PVOID_t)ap_adapter->dev) != VOS_STATUS_SUCCESS) {
10692 hddLog(LOGE, FL("SAP Start Bss fail"));
10693 goto end;
10694 }
10695
10696 hddLog(LOG1, FL("Waiting for SAP to start"));
10697 vos_status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
10698 if (!VOS_IS_STATUS_SUCCESS(vos_status)) {
10699 hddLog(LOGE, FL("SAP Start failed"));
10700 goto end;
10701 }
10702 hddLog(LOG1, FL("SAP Start Success"));
10703 set_bit(SOFTAP_BSS_STARTED, &ap_adapter->event_flags);
10704 wlan_hdd_incr_active_session(pHddCtx, ap_adapter->device_mode);
10705 pHostapdState->bCommit = TRUE;
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053010706 if (!VOS_IS_STATUS_SUCCESS(hdd_dhcp_mdns_offload(ap_adapter))) {
10707 hddLog(VOS_TRACE_LEVEL_ERROR, FL("DHCP/MDNS offload Failed!!"));
10708 vos_event_reset(&pHostapdState->vosEvent);
10709 if (VOS_STATUS_SUCCESS == WLANSAP_StopBss(pHddCtx->pvosContext)) {
10710 vos_status = vos_wait_single_event(&pHostapdState->vosEvent,
10711 10000);
10712 if (!VOS_IS_STATUS_SUCCESS(vos_status)) {
10713 hddLog(LOGE, FL("SAP Stop Failed"));
10714 goto end;
10715 }
10716 }
10717 }
Kapil Gupta137ef892016-12-13 19:38:00 +053010718 }
10719end:
10720 mutex_unlock(&pHddCtx->sap_lock);
10721 return;
10722}
10723
10724/**
10725 * __hdd_sap_restart_handle() - to handle restarting of SAP
10726 * @work: name of the work
10727 *
10728 * Purpose of this function is to trigger sap start. this function
10729 * will be called from workqueue.
10730 *
10731 * Return: void.
10732 */
10733static void __hdd_sap_restart_handle(struct work_struct *work)
10734{
10735 hdd_adapter_t *sap_adapter;
10736 hdd_context_t *hdd_ctx = container_of(work,
10737 hdd_context_t,
10738 sap_start_work);
10739 if (0 != wlan_hdd_validate_context(hdd_ctx)) {
10740 vos_ssr_unprotect(__func__);
10741 return;
10742 }
10743 sap_adapter = hdd_get_adapter(hdd_ctx,
10744 WLAN_HDD_SOFTAP);
10745 if (sap_adapter == NULL) {
10746 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10747 FL("sap_adapter is NULL"));
10748 vos_ssr_unprotect(__func__);
10749 return;
10750 }
10751
10752 if (hdd_ctx->is_ch_avoid_in_progress) {
10753 sap_adapter->sessionCtx.ap.sapConfig.channel = AUTO_CHANNEL_SELECT;
10754 wlan_hdd_restart_sap(sap_adapter);
10755 hdd_change_ch_avoidance_status(hdd_ctx, false);
10756 }
Agrawal Ashish574b3e62017-02-09 18:58:34 +053010757 if (hdd_ctx->cfg_ini->enable_sap_auth_offload)
10758 wlan_hdd_restart_sap(sap_adapter);
Kapil Gupta137ef892016-12-13 19:38:00 +053010759}
10760
10761/**
10762 * hdd_sap_restart_handle() - to handle restarting of SAP
10763 * @work: name of the work
10764 *
10765 * Purpose of this function is to trigger sap start. this function
10766 * will be called from workqueue.
10767 *
10768 * Return: void.
10769 */
10770static void hdd_sap_restart_handle(struct work_struct *work)
10771{
10772 vos_ssr_protect(__func__);
10773 __hdd_sap_restart_handle(work);
10774 vos_ssr_unprotect(__func__);
10775}
10776
10777
Abhishek Singh78c691f2017-11-30 13:48:44 +053010778/**
10779 * __hdd_force_scc_with_ecsa_handle() - to handle force scc using ecsa
10780 * @work: name of the work
10781 *
10782 * Purpose of this function is to force SCC using ECSA. This function
10783 * will be called from workqueue.
10784 *
10785 * Return: void.
10786 */
10787static void
10788__hdd_force_scc_with_ecsa_handle(struct work_struct *work)
10789{
10790 hdd_adapter_t *sap_adapter;
10791 hdd_station_ctx_t *sta_ctx;
10792 hdd_adapter_t *sta_adapter;
Ganesh Kondabattini3655a6d2018-01-08 20:25:39 +053010793 ptSapContext sap_ctx = NULL;
10794 v_CONTEXT_t vos_ctx;
10795 tANI_U8 target_channel;
10796 tsap_Config_t *sap_config;
10797 bool sta_sap_scc_on_dfs_chan;
10798 eNVChannelEnabledType chan_state;
Abhishek Singh78c691f2017-11-30 13:48:44 +053010799 hdd_context_t *hdd_ctx = container_of(to_delayed_work(work),
10800 hdd_context_t,
10801 ecsa_chan_change_work);
10802
10803 if (wlan_hdd_validate_context(hdd_ctx))
10804 return;
10805
10806 sap_adapter = hdd_get_adapter(hdd_ctx,
10807 WLAN_HDD_SOFTAP);
10808 if (!sap_adapter) {
10809 hddLog(LOGE, FL("sap_adapter is NULL"));
10810 return;
10811 }
10812
Ganesh Kondabattini3655a6d2018-01-08 20:25:39 +053010813 vos_ctx = hdd_ctx->pvosContext;
10814 if (!vos_ctx) {
10815 hddLog(LOGE, FL("vos_ctx is NULL"));
10816 return;
10817 }
10818
10819 sap_ctx = VOS_GET_SAP_CB(vos_ctx);
10820 if (!sap_ctx) {
10821 hddLog(LOGE, FL("sap_ctx is NULL"));
10822 return;
10823 }
10824
10825 sap_config = &sap_adapter->sessionCtx.ap.sapConfig;
10826
10827 sta_sap_scc_on_dfs_chan = hdd_is_sta_sap_scc_allowed_on_dfs_chan(hdd_ctx);
10828
Abhishek Singh78c691f2017-11-30 13:48:44 +053010829 sta_adapter = hdd_get_adapter(hdd_ctx,
10830 WLAN_HDD_INFRA_STATION);
10831 if (!sta_adapter) {
10832 hddLog(LOGE, FL("sta_adapter is NULL"));
10833 return;
10834 }
Abhishek Singh78c691f2017-11-30 13:48:44 +053010835
Abhishek Singh10e17cf2018-03-12 14:34:22 +053010836 if (wlansap_chk_n_set_chan_change_in_progress(sap_ctx))
Abhishek Singh78c691f2017-11-30 13:48:44 +053010837 return;
Abhishek Singh10e17cf2018-03-12 14:34:22 +053010838 INIT_COMPLETION(sap_ctx->ecsa_info.chan_switch_comp);
10839
10840 sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(sta_adapter);
10841 if (sta_ctx->conn_info.connState != eConnectionState_Associated) {
10842 if (sta_ctx->conn_info.connState == eConnectionState_NotConnected) {
10843 chan_state = vos_nv_getChannelEnabledState(sap_ctx->channel);
10844 hddLog(LOG1, FL("sta not in connected state %d, sta_sap_scc_on_dfs_chan %d, chan_state %d"),
10845 sta_ctx->conn_info.connState, sta_sap_scc_on_dfs_chan,
10846 chan_state);
10847 if (sta_sap_scc_on_dfs_chan &&
10848 (chan_state == NV_CHANNEL_DFS)) {
10849 hddLog(LOGE, FL("Switch SAP to user configured channel"));
10850 target_channel = sap_config->user_config_channel;
10851 goto switch_channel;
10852 }
10853 }
10854 goto abort;
Abhishek Singh78c691f2017-11-30 13:48:44 +053010855 }
10856
Ganesh Kondabattini3655a6d2018-01-08 20:25:39 +053010857 target_channel = sta_ctx->conn_info.operationChannel;
10858switch_channel:
10859 hddLog(LOGE, FL("Switch SAP to %d channel"),
10860 target_channel);
Abhishek Singh10e17cf2018-03-12 14:34:22 +053010861 if (!wlansap_set_channel_change(vos_ctx, target_channel, true))
10862 return;
10863
10864abort:
10865 wlansap_reset_chan_change_in_progress(sap_ctx);
10866 complete(&sap_ctx->ecsa_info.chan_switch_comp);
Abhishek Singh78c691f2017-11-30 13:48:44 +053010867}
10868
10869/**
10870 * hdd_force_scc_with_ecsa_handle() - to handle force scc using ecsa
10871 * @work: name of the work
10872 *
10873 * Purpose of this function is to force SCC using ECSA. This function
10874 * will be called from workqueue.
10875 *
10876 * Return: void.
10877 */
10878static void
10879hdd_force_scc_with_ecsa_handle(struct work_struct *work)
10880{
10881 vos_ssr_protect(__func__);
10882 __hdd_force_scc_with_ecsa_handle(work);
10883 vos_ssr_unprotect(__func__);
10884}
10885
Abhishek Singh10e17cf2018-03-12 14:34:22 +053010886int hdd_wait_for_ecsa_complete(hdd_context_t *hdd_ctx)
10887{
10888 int ret;
10889 ptSapContext sap_ctx = NULL;
10890 v_CONTEXT_t vos_ctx;
10891
10892 vos_ctx = hdd_ctx->pvosContext;
10893 if (!vos_ctx) {
10894 hddLog(LOGE, FL("vos_ctx is NULL"));
10895 return 0;
10896 }
10897
10898 sap_ctx = VOS_GET_SAP_CB(vos_ctx);
10899 if (!sap_ctx) {
10900 hddLog(LOG1, FL("sap_ctx is NULL"));
10901 return 0;
10902 }
10903 if(!sap_ctx->isSapSessionOpen) {
10904 hddLog(LOG1, FL("sap session not opened, SAP in state %d"),
10905 sap_ctx->sapsMachine);
10906 return 0;
10907 }
10908
10909 if (!wlansap_get_change_in_progress(sap_ctx)) {
10910 hddLog(LOG1, FL("channel switch not in progress"));
10911 return 0;
10912 }
10913 ret = wait_for_completion_timeout(&sap_ctx->ecsa_info.chan_switch_comp,
10914 msecs_to_jiffies(HDD_SAP_CHAN_CNG_WAIT_TIME));
10915 if (!ret)
10916 {
10917 hddLog(LOGE, FL("Timeout waiting for SAP channel switch"));
10918 return ret;
10919 }
10920
10921 return 0;
10922}
10923
10924
Ganesh Kondabattini3655a6d2018-01-08 20:25:39 +053010925/**
10926 * hdd_is_sta_sap_scc_allowed_on_dfs_chan() - check if sta+sap scc allowed on
10927 * dfs chan
10928 * @hdd_ctx: pointer to hdd context
10929 *
10930 * This function used to check if sta+sap scc allowed on DFS channel.
10931 *
10932 * Return: None
10933 */
10934bool hdd_is_sta_sap_scc_allowed_on_dfs_chan(hdd_context_t *hdd_ctx)
10935{
10936 if (hdd_ctx->cfg_ini->force_scc_with_ecsa &&
10937 hdd_ctx->cfg_ini->sta_sap_scc_on_dfs_chan)
10938 return true;
10939 else
10940 return false;
10941}
10942
Jeff Johnson295189b2012-06-20 16:38:30 -070010943VOS_STATUS hdd_stop_all_adapters( hdd_context_t *pHddCtx )
10944{
10945 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
10946 VOS_STATUS status;
10947 hdd_adapter_t *pAdapter;
10948
10949 ENTER();
10950
10951 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
10952
10953 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
10954 {
10955 pAdapter = pAdapterNode->pAdapter;
Jeff Johnson295189b2012-06-20 16:38:30 -070010956
Agarwal Ashish3a38bd12014-06-12 15:16:52 +053010957 hdd_stop_adapter( pHddCtx, pAdapter, VOS_TRUE );
Jeff Johnson295189b2012-06-20 16:38:30 -070010958
10959 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
10960 pAdapterNode = pNext;
10961 }
10962
10963 EXIT();
10964
10965 return VOS_STATUS_SUCCESS;
10966}
10967
Rajeev Kumarf999e582014-01-09 17:33:29 -080010968
10969#ifdef FEATURE_WLAN_BATCH_SCAN
10970/**---------------------------------------------------------------------------
10971
10972 \brief hdd_deinit_batch_scan () - This function cleans up batch scan data
10973 structures
10974
10975 \param - pAdapter Pointer to HDD adapter
10976
10977 \return - None
10978
10979 --------------------------------------------------------------------------*/
10980void hdd_deinit_batch_scan(hdd_adapter_t *pAdapter)
10981{
10982 tHddBatchScanRsp *pNode;
10983 tHddBatchScanRsp *pPrev;
10984
Siddharth Bhalb3e9b792014-02-24 15:14:16 +053010985 if (NULL == pAdapter)
Rajeev Kumarf999e582014-01-09 17:33:29 -080010986 {
Siddharth Bhalb3e9b792014-02-24 15:14:16 +053010987 hddLog(VOS_TRACE_LEVEL_ERROR,
10988 "%s: Adapter context is Null", __func__);
10989 return;
10990 }
10991
10992 pNode = pAdapter->pBatchScanRsp;
10993 while (pNode)
10994 {
10995 pPrev = pNode;
10996 pNode = pNode->pNext;
10997 vos_mem_free((v_VOID_t * )pPrev);
Rajeev Kumarf999e582014-01-09 17:33:29 -080010998 }
10999
11000 pAdapter->pBatchScanRsp = NULL;
11001 pAdapter->numScanList = 0;
11002 pAdapter->batchScanState = eHDD_BATCH_SCAN_STATE_STOPPED;
11003 pAdapter->prev_batch_id = 0;
11004
11005 return;
11006}
11007#endif
11008
11009
Jeff Johnson295189b2012-06-20 16:38:30 -070011010VOS_STATUS hdd_reset_all_adapters( hdd_context_t *pHddCtx )
11011{
11012 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
11013 VOS_STATUS status;
11014 hdd_adapter_t *pAdapter;
11015
11016 ENTER();
11017
11018 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
11019
11020 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
11021 {
11022 pAdapter = pAdapterNode->pAdapter;
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +053011023 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Jeff Johnson295189b2012-06-20 16:38:30 -070011024 netif_tx_disable(pAdapter->dev);
Hanumanth Reddy Pothulad864f312017-01-18 16:16:08 +053011025
11026 if (pHddCtx->cfg_ini->sap_internal_restart &&
11027 pAdapter->device_mode == WLAN_HDD_SOFTAP) {
11028 hddLog(LOG1, FL("driver supports sap restart"));
11029 vos_flush_work(&pHddCtx->sap_start_work);
11030 hdd_sap_indicate_disconnect_for_sta(pAdapter);
11031 hdd_cleanup_actionframe(pHddCtx, pAdapter);
Hanumanth Reddy Pothula15bc0fa2017-02-03 17:24:17 +053011032 hdd_softap_deinit_tx_rx(pAdapter, true);
11033 hdd_sap_destroy_timers(pAdapter);
Hanumanth Reddy Pothulad864f312017-01-18 16:16:08 +053011034 } else {
11035 netif_carrier_off(pAdapter->dev);
11036 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011037
Srinivas Girigowda66c05eb2013-07-14 13:06:01 -070011038 pAdapter->sessionCtx.station.hdd_ReassocScenario = VOS_FALSE;
Hanumanth Reddy Pothulada449f12018-03-13 18:19:19 +053011039
11040 if (pAdapter->device_mode == WLAN_HDD_MONITOR)
11041 pAdapter->sessionCtx.monitor.state = MON_MODE_STOP;
Srinivas Girigowda66c05eb2013-07-14 13:06:01 -070011042
Jeff Johnson295189b2012-06-20 16:38:30 -070011043 hdd_deinit_tx_rx(pAdapter);
Agarwal Ashish6267caa2014-08-06 19:16:21 +053011044
Katya Nigam1fd24402015-02-16 14:52:19 +053011045 if(pAdapter->device_mode == WLAN_HDD_IBSS )
11046 hdd_ibss_deinit_tx_rx(pAdapter);
11047
Nirav Shah7e3c8132015-06-22 23:51:42 +053011048 status = hdd_sta_id_hash_detach(pAdapter);
11049 if (status != VOS_STATUS_SUCCESS)
11050 hddLog(VOS_TRACE_LEVEL_ERROR,
11051 FL("sta id hash detach failed for session id %d"),
11052 pAdapter->sessionId);
11053
Agarwal Ashish6267caa2014-08-06 19:16:21 +053011054 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
11055
Madan Mohan Koyyalamudi8c6dec82013-09-26 15:56:13 +053011056 if (test_bit(WMM_INIT_DONE, &pAdapter->event_flags))
11057 {
11058 hdd_wmm_adapter_close( pAdapter );
11059 clear_bit(WMM_INIT_DONE, &pAdapter->event_flags);
11060 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011061
Siddharth Bhal2db319d2014-12-03 12:37:18 +053011062 if (test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
11063 {
11064 clear_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags);
11065 }
11066
Rajeev Kumarf999e582014-01-09 17:33:29 -080011067#ifdef FEATURE_WLAN_BATCH_SCAN
11068 if (eHDD_BATCH_SCAN_STATE_STARTED == pAdapter->batchScanState)
11069 {
11070 hdd_deinit_batch_scan(pAdapter);
11071 }
11072#endif
11073
Mahesh A Saptasagarf5b8eff2015-01-31 01:07:07 +053011074#ifdef FEATURE_WLAN_TDLS
11075 mutex_lock(&pHddCtx->tdls_lock);
Pradeep Reddy POTTETI2d4d5c42015-03-03 14:34:19 +053011076 wlan_hdd_tdls_exit(pAdapter, TRUE);
Mahesh A Saptasagarf5b8eff2015-01-31 01:07:07 +053011077 mutex_unlock(&pHddCtx->tdls_lock);
11078#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070011079 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
11080 pAdapterNode = pNext;
11081 }
11082
11083 EXIT();
11084
11085 return VOS_STATUS_SUCCESS;
11086}
11087
Abhishek Singhbbe0b2a2016-12-05 11:57:36 +053011088/**
Abhishek Singh5a597e62016-12-05 15:16:30 +053011089 * hdd_get_bss_entry() - Get the bss entry matching the chan, bssid and ssid
11090 * @wiphy: wiphy
11091 * @channel: channel of the BSS to find
11092 * @bssid: bssid of the BSS to find
11093 * @ssid: ssid of the BSS to find
11094 * @ssid_len: ssid len of of the BSS to find
11095 *
11096 * The API is a wrapper to get bss from kernel matching the chan,
11097 * bssid and ssid
11098 *
11099 * Return: Void
11100 */
11101#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 1, 0)) \
11102 && !defined(WITH_BACKPORTS) && !defined(IEEE80211_PRIVACY)
11103
11104struct cfg80211_bss* hdd_get_bss_entry(struct wiphy *wiphy,
11105 struct ieee80211_channel *channel,
11106 const u8 *bssid,
11107 const u8 *ssid, size_t ssid_len)
11108{
11109 return cfg80211_get_bss(wiphy, channel, bssid,
11110 ssid, ssid_len,
11111 WLAN_CAPABILITY_ESS,
11112 WLAN_CAPABILITY_ESS);
11113}
11114#else
11115struct cfg80211_bss* hdd_get_bss_entry(struct wiphy *wiphy,
11116 struct ieee80211_channel *channel,
11117 const u8 *bssid,
11118 const u8 *ssid, size_t ssid_len)
11119{
11120 return cfg80211_get_bss(wiphy, channel, bssid,
11121 ssid, ssid_len,
11122 IEEE80211_BSS_TYPE_ESS,
11123 IEEE80211_PRIVACY_ANY);
11124}
11125#endif
11126
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053011127#if defined(CFG80211_CONNECT_BSS) || \
11128 (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 7, 0))
11129
11130#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 11, 0) || \
11131 defined (CFG80211_CONNECT_TIMEOUT_REASON_CODE)
11132/**
11133 * hdd_connect_bss() - helper function to send connection status to supplicant
11134 * @dev: network device
11135 * @bssid: bssid to which we want to associate
11136 * @bss: information about connected bss
11137 * @req_ie: Request Information Element
11138 * @req_ie_len: len of the req IE
11139 * @resp_ie: Response IE
11140 * @resp_ie_len: len of ht response IE
11141 * @status: status
11142 * @gfp: Kernel Flag
11143 *
11144 * This is a helper function to send connection status to supplicant
11145 * and gets invoked from wrapper API
11146 *
11147 * Return: Void
11148 */
11149static void hdd_connect_bss(struct net_device *dev,
11150 const u8 *bssid,
11151 struct cfg80211_bss *bss,
11152 const u8 *req_ie,
11153 size_t req_ie_len,
11154 const u8 *resp_ie,
11155 size_t resp_ie_len,
11156 u16 status,
11157 gfp_t gfp)
11158{
11159 cfg80211_connect_bss(dev, bssid, bss, req_ie, req_ie_len,
11160 resp_ie, resp_ie_len, status, gfp, NL80211_TIMEOUT_UNSPECIFIED);
11161}
11162#else
11163/**
11164 * hdd_connect_bss() - helper function to send connection status to supplicant
11165 * @dev: network device
11166 * @bssid: bssid to which we want to associate
11167 * @bss: information about connected bss
11168 * @req_ie: Request Information Element
11169 * @req_ie_len: len of the req IE
11170 * @resp_ie: Response IE
11171 * @resp_ie_len: len of ht response IE
11172 * @status: status
11173 * @gfp: Kernel Flag
11174 *
11175 * This is a helper function to send connection status to supplicant
11176 * and gets invoked from wrapper API
11177 *
11178 * Return: Void
11179 */
11180static void hdd_connect_bss(struct net_device *dev,
11181 const u8 *bssid,
11182 struct cfg80211_bss *bss,
11183 const u8 *req_ie,
11184 size_t req_ie_len,
11185 const u8 *resp_ie,
11186 size_t resp_ie_len,
11187 u16 status,
11188 gfp_t gfp)
11189{
11190 cfg80211_connect_bss(dev, bssid, bss, req_ie, req_ie_len,
11191 resp_ie, resp_ie_len, status, gfp);
11192}
11193#endif
11194
Abhishek Singh5a597e62016-12-05 15:16:30 +053011195/**
Abhishek Singhbbe0b2a2016-12-05 11:57:36 +053011196 * hdd_connect_result() - API to send connection status to supplicant
11197 * @dev: network device
11198 * @bssid: bssid to which we want to associate
11199 * @roam_info: information about connected bss
11200 * @req_ie: Request Information Element
11201 * @req_ie_len: len of the req IE
11202 * @resp_ie: Response IE
11203 * @resp_ie_len: len of ht response IE
11204 * @status: status
11205 * @gfp: Kernel Flag
11206 *
11207 * The API is a wrapper to send connection status to supplicant
11208 *
11209 * Return: Void
11210 */
Abhishek Singhbbe0b2a2016-12-05 11:57:36 +053011211void hdd_connect_result(struct net_device *dev,
11212 const u8 *bssid,
11213 tCsrRoamInfo *roam_info,
11214 const u8 *req_ie,
11215 size_t req_ie_len,
11216 const u8 *resp_ie,
11217 size_t resp_ie_len,
11218 u16 status,
11219 gfp_t gfp)
11220{
11221 hdd_adapter_t *padapter = (hdd_adapter_t *) netdev_priv(dev);
11222 struct cfg80211_bss *bss = NULL;
11223
11224 if (WLAN_STATUS_SUCCESS == status) {
11225 struct ieee80211_channel *chan;
11226 int freq;
11227 int chan_no = roam_info->pBssDesc->channelId;;
11228
11229 if (chan_no <= 14)
11230 freq = ieee80211_channel_to_frequency(chan_no,
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053011231 HDD_NL80211_BAND_2GHZ);
Abhishek Singhbbe0b2a2016-12-05 11:57:36 +053011232 else
11233 freq = ieee80211_channel_to_frequency(chan_no,
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053011234 HDD_NL80211_BAND_5GHZ);
Abhishek Singhbbe0b2a2016-12-05 11:57:36 +053011235
11236 chan = ieee80211_get_channel(padapter->wdev.wiphy, freq);
Abhishek Singh5a597e62016-12-05 15:16:30 +053011237 bss = hdd_get_bss_entry(padapter->wdev.wiphy,
11238 chan, bssid,
11239 roam_info->u.pConnectedProfile->SSID.ssId,
11240 roam_info->u.pConnectedProfile->SSID.length);
Abhishek Singhbbe0b2a2016-12-05 11:57:36 +053011241 }
11242
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053011243 hdd_connect_bss(dev, bssid, bss, req_ie, req_ie_len, resp_ie, resp_ie_len,
11244 status, gfp);
Abhishek Singhbbe0b2a2016-12-05 11:57:36 +053011245}
11246#else
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053011247/**
11248 * hdd_connect_result() - API to send connection status to supplicant
11249 * @dev: network device
11250 * @bssid: bssid to which we want to associate
11251 * @roam_info: information about connected bss
11252 * @req_ie: Request Information Element
11253 * @req_ie_len: len of the req IE
11254 * @resp_ie: Response IE
11255 * @resp_ie_len: len of ht response IE
11256 * @status: status
11257 * @gfp: Kernel Flag
11258 *
11259 * The API is a wrapper to send connection status to supplicant
11260 *
11261 * Return: Void
11262 */
Abhishek Singhbbe0b2a2016-12-05 11:57:36 +053011263void hdd_connect_result(struct net_device *dev,
11264 const u8 *bssid,
11265 tCsrRoamInfo *roam_info,
11266 const u8 *req_ie,
11267 size_t req_ie_len,
11268 const u8 * resp_ie,
11269 size_t resp_ie_len,
11270 u16 status,
11271 gfp_t gfp)
11272{
11273 cfg80211_connect_result(dev, bssid, req_ie, req_ie_len,
11274 resp_ie, resp_ie_len, status, gfp);
11275}
11276#endif
11277
Jeff Johnson295189b2012-06-20 16:38:30 -070011278VOS_STATUS hdd_start_all_adapters( hdd_context_t *pHddCtx )
11279{
11280 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
11281 VOS_STATUS status;
11282 hdd_adapter_t *pAdapter;
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +053011283 eConnectionState connState;
Hanumanth Reddy Pothulada449f12018-03-13 18:19:19 +053011284 v_CONTEXT_t pVosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -070011285
11286 ENTER();
11287
11288 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
11289
11290 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
11291 {
11292 pAdapter = pAdapterNode->pAdapter;
11293
Kumar Anand82c009f2014-05-29 00:29:42 -070011294 hdd_wmm_init( pAdapter );
11295
Jeff Johnson295189b2012-06-20 16:38:30 -070011296 switch(pAdapter->device_mode)
11297 {
11298 case WLAN_HDD_INFRA_STATION:
11299 case WLAN_HDD_P2P_CLIENT:
Jeff Johnsone7245742012-09-05 17:12:55 -070011300 case WLAN_HDD_P2P_DEVICE:
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +053011301
11302 connState = (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState;
11303
Jeff Johnson295189b2012-06-20 16:38:30 -070011304 hdd_init_station_mode(pAdapter);
11305 /* Open the gates for HDD to receive Wext commands */
11306 pAdapter->isLinkUpSvcNeeded = FALSE;
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070011307 pHddCtx->scan_info.mScanPending = FALSE;
11308 pHddCtx->scan_info.waitScanResult = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070011309
11310 //Trigger the initial scan
Mukul Sharmae74e42c2015-08-06 23:55:49 +053011311 if (!pHddCtx->isLogpInProgress)
11312 hdd_wlan_initial_scan(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070011313
11314 //Indicate disconnect event to supplicant if associated previously
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +053011315 if (eConnectionState_Associated == connState ||
11316 eConnectionState_IbssConnected == connState )
Jeff Johnson295189b2012-06-20 16:38:30 -070011317 {
11318 union iwreq_data wrqu;
11319 memset(&wrqu, '\0', sizeof(wrqu));
11320 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
11321 memset(wrqu.ap_addr.sa_data,'\0',ETH_ALEN);
11322 wireless_send_event(pAdapter->dev, SIOCGIWAP, &wrqu, NULL);
Srinivas Girigowda66c05eb2013-07-14 13:06:01 -070011323 pAdapter->sessionCtx.station.hdd_ReassocScenario = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070011324
Jeff Johnson295189b2012-06-20 16:38:30 -070011325 /* indicate disconnected event to nl80211 */
Mahesh A Saptasagar9ff4bcc2016-06-01 17:17:50 +053011326 wlan_hdd_cfg80211_indicate_disconnect(pAdapter->dev, false,
Mahesh A Saptasagarb5a15142016-05-25 11:27:43 +053011327 WLAN_REASON_UNSPECIFIED);
Jeff Johnson295189b2012-06-20 16:38:30 -070011328 }
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +053011329 else if (eConnectionState_Connecting == connState)
11330 {
11331 /*
11332 * Indicate connect failure to supplicant if we were in the
11333 * process of connecting
11334 */
Abhishek Singhbbe0b2a2016-12-05 11:57:36 +053011335 hdd_connect_result(pAdapter->dev, NULL, NULL,
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +053011336 NULL, 0, NULL, 0,
11337 WLAN_STATUS_ASSOC_DENIED_UNSPEC,
11338 GFP_KERNEL);
11339 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011340 break;
11341
11342 case WLAN_HDD_SOFTAP:
Hanumanth Reddy Pothulad864f312017-01-18 16:16:08 +053011343 if (pHddCtx->cfg_ini->sap_internal_restart) {
Hanumanth Reddy Pothula15bc0fa2017-02-03 17:24:17 +053011344 hdd_init_ap_mode(pAdapter, true);
Hanumanth Reddy Pothulad864f312017-01-18 16:16:08 +053011345 status = hdd_sta_id_hash_attach(pAdapter);
11346 if (VOS_STATUS_SUCCESS != status)
11347 {
11348 hddLog(VOS_TRACE_LEVEL_FATAL,
11349 FL("failed to attach hash for"));
11350 }
11351 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011352 break;
11353
11354 case WLAN_HDD_P2P_GO:
Sameer Thalappiledf0d792013-08-09 14:31:03 -070011355 hddLog(VOS_TRACE_LEVEL_ERROR, "%s [SSR] send stop ap to supplicant",
Jeff Johnson295189b2012-06-20 16:38:30 -070011356 __func__);
Sameer Thalappiledf0d792013-08-09 14:31:03 -070011357 cfg80211_ap_stopped(pAdapter->dev, GFP_KERNEL);
Jeff Johnson295189b2012-06-20 16:38:30 -070011358 break;
11359
11360 case WLAN_HDD_MONITOR:
Hanumanth Reddy Pothulada449f12018-03-13 18:19:19 +053011361 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
11362
11363 hddLog(VOS_TRACE_LEVEL_INFO, FL("[SSR] monitor mode"));
11364 if (!pVosContext) {
11365 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos context is NULL"));
11366 break;
11367 }
11368
11369 hdd_init_tx_rx(pAdapter);
11370 WLANTL_SetMonRxCbk( pVosContext, hdd_rx_packet_monitor_cbk);
Jeff Johnson295189b2012-06-20 16:38:30 -070011371 break;
Hanumanth Reddy Pothulada449f12018-03-13 18:19:19 +053011372
Jeff Johnson295189b2012-06-20 16:38:30 -070011373 default:
11374 break;
11375 }
11376
11377 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
11378 pAdapterNode = pNext;
11379 }
11380
11381 EXIT();
11382
11383 return VOS_STATUS_SUCCESS;
11384}
11385
11386VOS_STATUS hdd_reconnect_all_adapters( hdd_context_t *pHddCtx )
11387{
11388 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
11389 hdd_adapter_t *pAdapter;
11390 VOS_STATUS status;
11391 v_U32_t roamId;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011392 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070011393
11394 ENTER();
11395
11396 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
11397
11398 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
11399 {
11400 pAdapter = pAdapterNode->pAdapter;
11401
11402 if( (WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
11403 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
11404 {
11405 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
11406 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
11407
Abhishek Singhf4669da2014-05-26 15:07:49 +053011408 hddLog(VOS_TRACE_LEVEL_INFO,
11409 "%s: Set HDD connState to eConnectionState_NotConnected",
11410 __func__);
Ganesh Kondabattini04338412015-09-14 15:39:09 +053011411 spin_lock_bh(&pAdapter->lock_for_active_session);
11412 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState)
11413 {
11414 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
11415 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011416 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
Ganesh Kondabattini04338412015-09-14 15:39:09 +053011417 spin_unlock_bh(&pAdapter->lock_for_active_session);
Jeff Johnson295189b2012-06-20 16:38:30 -070011418 init_completion(&pAdapter->disconnect_comp_var);
11419 sme_RoamDisconnect(pHddCtx->hHal, pAdapter->sessionId,
11420 eCSR_DISCONNECT_REASON_UNSPECIFIED);
11421
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011422 ret = wait_for_completion_interruptible_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -070011423 &pAdapter->disconnect_comp_var,
11424 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011425 if (0 >= ret)
11426 hddLog(LOGE, "%s: failure waiting for disconnect_comp_var %ld",
11427 __func__, ret);
Jeff Johnson295189b2012-06-20 16:38:30 -070011428
11429 pWextState->roamProfile.csrPersona = pAdapter->device_mode;
11430 pHddCtx->isAmpAllowed = VOS_FALSE;
11431 sme_RoamConnect(pHddCtx->hHal,
11432 pAdapter->sessionId, &(pWextState->roamProfile),
11433 &roamId);
11434 }
11435
11436 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
11437 pAdapterNode = pNext;
11438 }
11439
11440 EXIT();
11441
11442 return VOS_STATUS_SUCCESS;
11443}
11444
Sudhir Sattayappa Kohalli90e4c752013-03-21 14:25:04 -070011445void hdd_dump_concurrency_info(hdd_context_t *pHddCtx)
11446{
11447 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
11448 VOS_STATUS status;
11449 hdd_adapter_t *pAdapter;
11450 hdd_station_ctx_t *pHddStaCtx;
11451 hdd_ap_ctx_t *pHddApCtx;
11452 hdd_hostapd_state_t * pHostapdState;
11453 tCsrBssid staBssid = { 0 }, p2pBssid = { 0 }, apBssid = { 0 };
11454 v_U8_t staChannel = 0, p2pChannel = 0, apChannel = 0;
11455 const char *p2pMode = "DEV";
11456 const char *ccMode = "Standalone";
Sudhir Sattayappa Kohalli90e4c752013-03-21 14:25:04 -070011457
11458 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
11459 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
11460 {
11461 pAdapter = pAdapterNode->pAdapter;
11462 switch (pAdapter->device_mode) {
11463 case WLAN_HDD_INFRA_STATION:
11464 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
11465 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState) {
11466 staChannel = pHddStaCtx->conn_info.operationChannel;
11467 memcpy(staBssid, pHddStaCtx->conn_info.bssId, sizeof(staBssid));
11468 }
11469 break;
11470 case WLAN_HDD_P2P_CLIENT:
11471 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
11472 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState) {
11473 p2pChannel = pHddStaCtx->conn_info.operationChannel;
11474 memcpy(p2pBssid, pHddStaCtx->conn_info.bssId, sizeof(p2pBssid));
11475 p2pMode = "CLI";
11476 }
11477 break;
11478 case WLAN_HDD_P2P_GO:
11479 pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
11480 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
11481 if (pHostapdState->bssState == BSS_START && pHostapdState->vosStatus==VOS_STATUS_SUCCESS) {
11482 p2pChannel = pHddApCtx->operatingChannel;
11483 memcpy(p2pBssid, pAdapter->macAddressCurrent.bytes, sizeof(p2pBssid));
11484 }
11485 p2pMode = "GO";
11486 break;
11487 case WLAN_HDD_SOFTAP:
11488 pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
11489 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
11490 if (pHostapdState->bssState == BSS_START && pHostapdState->vosStatus==VOS_STATUS_SUCCESS) {
11491 apChannel = pHddApCtx->operatingChannel;
11492 memcpy(apBssid, pAdapter->macAddressCurrent.bytes, sizeof(apBssid));
11493 }
11494 break;
11495 default:
11496 break;
11497 }
11498 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
11499 pAdapterNode = pNext;
11500 }
11501 if (staChannel > 0 && (apChannel > 0 || p2pChannel > 0)) {
11502 ccMode = (p2pChannel==staChannel||apChannel==staChannel) ? "SCC" : "MCC";
11503 }
Yeshwanth Sriram Guntuka0004c0b2017-12-06 14:43:49 +053011504 hddLog(VOS_TRACE_LEVEL_ERROR, "wlan(%d) " MAC_ADDRESS_STR " %s",
11505 staChannel, MAC_ADDR_ARRAY(staBssid), ccMode);
Sudhir Sattayappa Kohalli90e4c752013-03-21 14:25:04 -070011506 if (p2pChannel > 0) {
Sushant Kaushikdc3184b2015-10-09 12:00:21 +053011507 hddLog(VOS_TRACE_LEVEL_ERROR, "p2p-%s(%d) " MAC_ADDRESS_STR,
Sudhir Sattayappa Kohalli90e4c752013-03-21 14:25:04 -070011508 p2pMode, p2pChannel, MAC_ADDR_ARRAY(p2pBssid));
11509 }
11510 if (apChannel > 0) {
Sushant Kaushikdc3184b2015-10-09 12:00:21 +053011511 hddLog(VOS_TRACE_LEVEL_ERROR, "AP(%d) " MAC_ADDRESS_STR,
Sudhir Sattayappa Kohalli90e4c752013-03-21 14:25:04 -070011512 apChannel, MAC_ADDR_ARRAY(apBssid));
11513 }
11514
11515 if (p2pChannel > 0 && apChannel > 0) {
11516 hddLog(VOS_TRACE_LEVEL_ERROR, "Error concurrent SAP %d and P2P %d which is not support", apChannel, p2pChannel);
11517 }
11518}
11519
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -070011520bool hdd_is_ssr_required( void)
Jeff Johnson295189b2012-06-20 16:38:30 -070011521{
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -070011522 return (isSsrRequired == HDD_SSR_REQUIRED);
Jeff Johnson295189b2012-06-20 16:38:30 -070011523}
11524
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -070011525/* Once SSR is disabled then it cannot be set. */
11526void hdd_set_ssr_required( e_hdd_ssr_required value)
Jeff Johnson295189b2012-06-20 16:38:30 -070011527{
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -070011528 if (HDD_SSR_DISABLED == isSsrRequired)
11529 return;
11530
Jeff Johnson295189b2012-06-20 16:38:30 -070011531 isSsrRequired = value;
11532}
11533
Hema Aparna Medicharla6b4d4f32015-06-23 04:09:12 +053011534void hdd_set_pre_close( hdd_context_t *pHddCtx)
11535{
11536 sme_PreClose(pHddCtx->hHal);
11537}
11538
Jeff Johnson295189b2012-06-20 16:38:30 -070011539VOS_STATUS hdd_get_front_adapter( hdd_context_t *pHddCtx,
11540 hdd_adapter_list_node_t** ppAdapterNode)
11541{
11542 VOS_STATUS status;
Mukul Sharmaae1266d2015-06-26 15:29:53 +053011543 spin_lock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -070011544 status = hdd_list_peek_front ( &pHddCtx->hddAdapters,
11545 (hdd_list_node_t**) ppAdapterNode );
Mukul Sharmaae1266d2015-06-26 15:29:53 +053011546 spin_unlock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -070011547 return status;
11548}
11549
11550VOS_STATUS hdd_get_next_adapter( hdd_context_t *pHddCtx,
11551 hdd_adapter_list_node_t* pAdapterNode,
11552 hdd_adapter_list_node_t** pNextAdapterNode)
11553{
11554 VOS_STATUS status;
Mukul Sharmaae1266d2015-06-26 15:29:53 +053011555 spin_lock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -070011556 status = hdd_list_peek_next ( &pHddCtx->hddAdapters,
11557 (hdd_list_node_t*) pAdapterNode,
11558 (hdd_list_node_t**)pNextAdapterNode );
11559
Mukul Sharmaae1266d2015-06-26 15:29:53 +053011560 spin_unlock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -070011561 return status;
11562}
11563
11564VOS_STATUS hdd_remove_adapter( hdd_context_t *pHddCtx,
11565 hdd_adapter_list_node_t* pAdapterNode)
11566{
11567 VOS_STATUS status;
Mukul Sharmaae1266d2015-06-26 15:29:53 +053011568 spin_lock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -070011569 status = hdd_list_remove_node ( &pHddCtx->hddAdapters,
11570 &pAdapterNode->node );
Mukul Sharmaae1266d2015-06-26 15:29:53 +053011571 spin_unlock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -070011572 return status;
11573}
11574
11575VOS_STATUS hdd_remove_front_adapter( hdd_context_t *pHddCtx,
11576 hdd_adapter_list_node_t** ppAdapterNode)
11577{
11578 VOS_STATUS status;
Mukul Sharmaae1266d2015-06-26 15:29:53 +053011579 spin_lock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -070011580 status = hdd_list_remove_front( &pHddCtx->hddAdapters,
11581 (hdd_list_node_t**) ppAdapterNode );
Mukul Sharmaae1266d2015-06-26 15:29:53 +053011582 spin_unlock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -070011583 return status;
11584}
11585
11586VOS_STATUS hdd_add_adapter_back( hdd_context_t *pHddCtx,
11587 hdd_adapter_list_node_t* pAdapterNode)
11588{
11589 VOS_STATUS status;
Mukul Sharmaae1266d2015-06-26 15:29:53 +053011590 spin_lock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -070011591 status = hdd_list_insert_back ( &pHddCtx->hddAdapters,
11592 (hdd_list_node_t*) pAdapterNode );
Mukul Sharmaae1266d2015-06-26 15:29:53 +053011593 spin_unlock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -070011594 return status;
11595}
11596
11597VOS_STATUS hdd_add_adapter_front( hdd_context_t *pHddCtx,
11598 hdd_adapter_list_node_t* pAdapterNode)
11599{
11600 VOS_STATUS status;
Mukul Sharmaae1266d2015-06-26 15:29:53 +053011601 spin_lock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -070011602 status = hdd_list_insert_front ( &pHddCtx->hddAdapters,
11603 (hdd_list_node_t*) pAdapterNode );
Mukul Sharmaae1266d2015-06-26 15:29:53 +053011604 spin_unlock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -070011605 return status;
11606}
11607
11608hdd_adapter_t * hdd_get_adapter_by_macaddr( hdd_context_t *pHddCtx,
11609 tSirMacAddr macAddr )
11610{
11611 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
11612 hdd_adapter_t *pAdapter;
11613 VOS_STATUS status;
11614
11615 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
11616
11617 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
11618 {
11619 pAdapter = pAdapterNode->pAdapter;
11620
11621 if( pAdapter && vos_mem_compare( pAdapter->macAddressCurrent.bytes,
11622 macAddr, sizeof(tSirMacAddr) ) )
11623 {
11624 return pAdapter;
11625 }
11626 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
11627 pAdapterNode = pNext;
11628 }
11629
11630 return NULL;
11631
11632}
11633
11634hdd_adapter_t * hdd_get_adapter_by_name( hdd_context_t *pHddCtx, tANI_U8 *name )
11635{
11636 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
11637 hdd_adapter_t *pAdapter;
11638 VOS_STATUS status;
11639
11640 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
11641
11642 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
11643 {
11644 pAdapter = pAdapterNode->pAdapter;
11645
11646 if( pAdapter && !strncmp( pAdapter->dev->name, (const char *)name,
11647 IFNAMSIZ ) )
11648 {
11649 return pAdapter;
11650 }
11651 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
11652 pAdapterNode = pNext;
11653 }
11654
11655 return NULL;
11656
11657}
11658
Ganesh Kondabattinicbfdc392015-09-11 19:12:59 +053011659hdd_adapter_t *hdd_get_adapter_by_sme_session_id( hdd_context_t *pHddCtx,
11660 tANI_U32 sme_session_id )
11661{
11662 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
11663 hdd_adapter_t *pAdapter;
11664 VOS_STATUS vos_status;
11665
11666
11667 vos_status = hdd_get_front_adapter( pHddCtx, &pAdapterNode);
11668
11669 while ((NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == vos_status))
11670 {
11671 pAdapter = pAdapterNode->pAdapter;
11672
11673 if (pAdapter->sessionId == sme_session_id)
11674 return pAdapter;
11675
11676 vos_status = hdd_get_next_adapter(pHddCtx, pAdapterNode, &pNext);
11677 pAdapterNode = pNext;
11678 }
11679
11680 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11681 "%s: sme_session_id %d does not exist with host",
11682 __func__, sme_session_id);
11683
11684 return NULL;
11685}
11686
Jeff Johnson295189b2012-06-20 16:38:30 -070011687hdd_adapter_t * hdd_get_adapter( hdd_context_t *pHddCtx, device_mode_t mode )
11688{
11689 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
11690 hdd_adapter_t *pAdapter;
11691 VOS_STATUS status;
11692
11693 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
11694
11695 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
11696 {
11697 pAdapter = pAdapterNode->pAdapter;
11698
11699 if( pAdapter && (mode == pAdapter->device_mode) )
11700 {
11701 return pAdapter;
11702 }
11703 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
11704 pAdapterNode = pNext;
11705 }
11706
11707 return NULL;
11708
11709}
11710
11711//Remove this function later
11712hdd_adapter_t * hdd_get_mon_adapter( hdd_context_t *pHddCtx )
11713{
11714 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
11715 hdd_adapter_t *pAdapter;
11716 VOS_STATUS status;
11717
11718 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
11719
11720 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
11721 {
11722 pAdapter = pAdapterNode->pAdapter;
11723
11724 if( pAdapter && WLAN_HDD_MONITOR == pAdapter->device_mode )
11725 {
11726 return pAdapter;
11727 }
11728
11729 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
11730 pAdapterNode = pNext;
11731 }
11732
11733 return NULL;
11734
11735}
11736
Jeff Johnson295189b2012-06-20 16:38:30 -070011737/**---------------------------------------------------------------------------
11738
Mahesh A Saptasgar64534612014-09-23 13:13:33 +053011739 \brief hdd_get_operating_channel() -
Jeff Johnson295189b2012-06-20 16:38:30 -070011740
11741 This API returns the operating channel of the requested device mode
11742
11743 \param - pHddCtx - Pointer to the HDD context.
11744 - mode - Device mode for which operating channel is required
11745 suported modes - WLAN_HDD_INFRA_STATION, WLAN_HDD_P2P_CLIENT
11746 WLAN_HDD_SOFTAP, WLAN_HDD_P2P_GO.
11747 \return - channel number. "0" id the requested device is not found OR it is not connected.
11748 --------------------------------------------------------------------------*/
11749v_U8_t hdd_get_operating_channel( hdd_context_t *pHddCtx, device_mode_t mode )
11750{
11751 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
11752 VOS_STATUS status;
11753 hdd_adapter_t *pAdapter;
11754 v_U8_t operatingChannel = 0;
11755
11756 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
11757
11758 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
11759 {
11760 pAdapter = pAdapterNode->pAdapter;
11761
11762 if( mode == pAdapter->device_mode )
11763 {
11764 switch(pAdapter->device_mode)
11765 {
11766 case WLAN_HDD_INFRA_STATION:
11767 case WLAN_HDD_P2P_CLIENT:
11768 if( hdd_connIsConnected( WLAN_HDD_GET_STATION_CTX_PTR( pAdapter )) )
11769 operatingChannel = (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.operationChannel;
11770 break;
11771 case WLAN_HDD_SOFTAP:
11772 case WLAN_HDD_P2P_GO:
11773 /*softap connection info */
11774 if(test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
11775 operatingChannel = (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->operatingChannel;
11776 break;
11777 default:
11778 break;
11779 }
11780
11781 break; //Found the device of interest. break the loop
11782 }
11783
11784 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
11785 pAdapterNode = pNext;
11786 }
11787 return operatingChannel;
11788}
11789
11790#ifdef WLAN_FEATURE_PACKET_FILTERING
11791/**---------------------------------------------------------------------------
11792
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053011793 \brief __hdd_set_multicast_list() -
Jeff Johnson295189b2012-06-20 16:38:30 -070011794
11795 This used to set the multicast address list.
11796
11797 \param - dev - Pointer to the WLAN device.
11798 - skb - Pointer to OS packet (sk_buff).
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053011799 \return - success/fail
Jeff Johnson295189b2012-06-20 16:38:30 -070011800
11801 --------------------------------------------------------------------------*/
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053011802static void __hdd_set_multicast_list(struct net_device *dev)
Jeff Johnson295189b2012-06-20 16:38:30 -070011803{
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053011804 hdd_adapter_t *pAdapter;
11805 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070011806 int mc_count;
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053011807 int i = 0, ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070011808 struct netdev_hw_addr *ha;
Gopichand Nakkala0f276812013-02-24 14:45:51 +053011809
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053011810 ENTER();
11811
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053011812 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkala0f276812013-02-24 14:45:51 +053011813 if (NULL == pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -070011814 {
11815 hddLog(VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala0f276812013-02-24 14:45:51 +053011816 "%s: Adapter context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070011817 return;
11818 }
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053011819 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
11820 ret = wlan_hdd_validate_context(pHddCtx);
11821 if (0 != ret)
11822 {
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053011823 return;
11824 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011825 if (dev->flags & IFF_ALLMULTI)
11826 {
11827 hddLog(VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070011828 "%s: allow all multicast frames", __func__);
Gopichand Nakkala0f276812013-02-24 14:45:51 +053011829 pAdapter->mc_addr_list.mc_cnt = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070011830 }
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053011831 else
Jeff Johnson295189b2012-06-20 16:38:30 -070011832 {
11833 mc_count = netdev_mc_count(dev);
11834 hddLog(VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070011835 "%s: mc_count = %u", __func__, mc_count);
Jeff Johnson295189b2012-06-20 16:38:30 -070011836 if (mc_count > WLAN_HDD_MAX_MC_ADDR_LIST)
11837 {
11838 hddLog(VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070011839 "%s: No free filter available; allow all multicast frames", __func__);
Gopichand Nakkala0f276812013-02-24 14:45:51 +053011840 pAdapter->mc_addr_list.mc_cnt = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070011841 return;
11842 }
11843
Gopichand Nakkala0f276812013-02-24 14:45:51 +053011844 pAdapter->mc_addr_list.mc_cnt = mc_count;
Jeff Johnson295189b2012-06-20 16:38:30 -070011845
11846 netdev_for_each_mc_addr(ha, dev) {
11847 if (i == mc_count)
11848 break;
Gopichand Nakkala0f276812013-02-24 14:45:51 +053011849 memset(&(pAdapter->mc_addr_list.addr[i][0]), 0, ETH_ALEN);
11850 memcpy(&(pAdapter->mc_addr_list.addr[i][0]), ha->addr, ETH_ALEN);
Arif Hussain6d2a3322013-11-17 19:50:10 -080011851 hddLog(VOS_TRACE_LEVEL_INFO, "%s: mlist[%d] = "MAC_ADDRESS_STR,
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053011852 __func__, i,
Gopichand Nakkala0f276812013-02-24 14:45:51 +053011853 MAC_ADDR_ARRAY(pAdapter->mc_addr_list.addr[i]));
Jeff Johnson295189b2012-06-20 16:38:30 -070011854 i++;
11855 }
11856 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053011857
Ganesh Kondabattinifb37e652015-10-09 15:46:47 +053011858 if (pHddCtx->hdd_wlan_suspended)
11859 {
11860 /*
11861 * Configure the Mcast address list to FW
11862 * If wlan is already in suspend mode
11863 */
11864 wlan_hdd_set_mc_addr_list(pAdapter, TRUE);
11865 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053011866 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070011867 return;
11868}
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053011869
11870static void hdd_set_multicast_list(struct net_device *dev)
11871{
11872 vos_ssr_protect(__func__);
11873 __hdd_set_multicast_list(dev);
11874 vos_ssr_unprotect(__func__);
11875}
Jeff Johnson295189b2012-06-20 16:38:30 -070011876#endif
11877
11878/**---------------------------------------------------------------------------
11879
11880 \brief hdd_select_queue() -
11881
11882 This function is registered with the Linux OS for network
11883 core to decide which queue to use first.
11884
11885 \param - dev - Pointer to the WLAN device.
11886 - skb - Pointer to OS packet (sk_buff).
11887 \return - ac, Queue Index/access category corresponding to UP in IP header
11888
11889 --------------------------------------------------------------------------*/
11890v_U16_t hdd_select_queue(struct net_device *dev,
Anand N Sunkade9adb1b2015-07-29 09:56:45 +053011891 struct sk_buff *skb
11892#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,13,0))
11893 , void *accel_priv
11894#endif
11895#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
11896 , select_queue_fallback_t fallback
11897#endif
11898)
Jeff Johnson295189b2012-06-20 16:38:30 -070011899{
11900 return hdd_wmm_select_queue(dev, skb);
11901}
11902
11903
11904/**---------------------------------------------------------------------------
11905
11906 \brief hdd_wlan_initial_scan() -
11907
11908 This function triggers the initial scan
11909
11910 \param - pAdapter - Pointer to the HDD adapter.
11911
11912 --------------------------------------------------------------------------*/
11913void hdd_wlan_initial_scan(hdd_adapter_t *pAdapter)
11914{
11915 tCsrScanRequest scanReq;
11916 tCsrChannelInfo channelInfo;
11917 eHalStatus halStatus;
Jeff Johnson02797792013-10-26 19:17:13 -070011918 tANI_U32 scanId;
Jeff Johnson295189b2012-06-20 16:38:30 -070011919 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
11920
11921 vos_mem_zero(&scanReq, sizeof(tCsrScanRequest));
11922 vos_mem_set(&scanReq.bssid, sizeof(tCsrBssid), 0xff);
11923 scanReq.BSSType = eCSR_BSS_TYPE_ANY;
11924
11925 if(sme_Is11dSupported(pHddCtx->hHal))
11926 {
11927 halStatus = sme_ScanGetBaseChannels( pHddCtx->hHal, &channelInfo );
11928 if ( HAL_STATUS_SUCCESS( halStatus ) )
11929 {
11930 scanReq.ChannelInfo.ChannelList = vos_mem_malloc(channelInfo.numOfChannels);
11931 if( !scanReq.ChannelInfo.ChannelList )
11932 {
11933 hddLog(VOS_TRACE_LEVEL_ERROR, "%s kmalloc failed", __func__);
11934 vos_mem_free(channelInfo.ChannelList);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -080011935 channelInfo.ChannelList = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070011936 return;
11937 }
11938 vos_mem_copy(scanReq.ChannelInfo.ChannelList, channelInfo.ChannelList,
11939 channelInfo.numOfChannels);
11940 scanReq.ChannelInfo.numOfChannels = channelInfo.numOfChannels;
11941 vos_mem_free(channelInfo.ChannelList);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -080011942 channelInfo.ChannelList = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070011943 }
11944
11945 scanReq.scanType = eSIR_PASSIVE_SCAN;
11946 scanReq.requestType = eCSR_SCAN_REQUEST_11D_SCAN;
11947 scanReq.maxChnTime = pHddCtx->cfg_ini->nPassiveMaxChnTime;
11948 scanReq.minChnTime = pHddCtx->cfg_ini->nPassiveMinChnTime;
11949 }
11950 else
11951 {
11952 scanReq.scanType = eSIR_ACTIVE_SCAN;
11953 scanReq.requestType = eCSR_SCAN_REQUEST_FULL_SCAN;
11954 scanReq.maxChnTime = pHddCtx->cfg_ini->nActiveMaxChnTime;
11955 scanReq.minChnTime = pHddCtx->cfg_ini->nActiveMinChnTime;
11956 }
11957
11958 halStatus = sme_ScanRequest(pHddCtx->hHal, pAdapter->sessionId, &scanReq, &scanId, NULL, NULL);
11959 if ( !HAL_STATUS_SUCCESS( halStatus ) )
11960 {
11961 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: sme_ScanRequest failed status code %d",
11962 __func__, halStatus );
11963 }
11964
11965 if(sme_Is11dSupported(pHddCtx->hHal))
11966 vos_mem_free(scanReq.ChannelInfo.ChannelList);
11967}
11968
Jeff Johnson295189b2012-06-20 16:38:30 -070011969/**---------------------------------------------------------------------------
11970
11971 \brief hdd_full_power_callback() - HDD full power callback function
11972
11973 This is the function invoked by SME to inform the result of a full power
11974 request issued by HDD
11975
11976 \param - callbackcontext - Pointer to cookie
11977 \param - status - result of request
11978
11979 \return - None
11980
11981 --------------------------------------------------------------------------*/
11982static void hdd_full_power_callback(void *callbackContext, eHalStatus status)
11983{
Jeff Johnson72a40512013-12-19 10:14:15 -080011984 struct statsContext *pContext = callbackContext;
Jeff Johnson295189b2012-06-20 16:38:30 -070011985
11986 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnsonc135a9a2017-09-19 08:37:24 -070011987 "%s: context = %pK, status = %d", __func__, pContext, status);
Jeff Johnson295189b2012-06-20 16:38:30 -070011988
11989 if (NULL == callbackContext)
11990 {
11991 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnsonc135a9a2017-09-19 08:37:24 -070011992 "%s: Bad param, context [%pK]",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070011993 __func__, callbackContext);
Jeff Johnson295189b2012-06-20 16:38:30 -070011994 return;
11995 }
11996
Jeff Johnson72a40512013-12-19 10:14:15 -080011997 /* there is a race condition that exists between this callback
11998 function and the caller since the caller could time out either
11999 before or while this code is executing. we use a spinlock to
12000 serialize these actions */
12001 spin_lock(&hdd_context_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -070012002
12003 if (POWER_CONTEXT_MAGIC != pContext->magic)
12004 {
12005 /* the caller presumably timed out so there is nothing we can do */
Jeff Johnson72a40512013-12-19 10:14:15 -080012006 spin_unlock(&hdd_context_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -070012007 hddLog(VOS_TRACE_LEVEL_WARN,
12008 "%s: Invalid context, magic [%08x]",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070012009 __func__, pContext->magic);
Jeff Johnson295189b2012-06-20 16:38:30 -070012010 return;
12011 }
12012
Jeff Johnson72a40512013-12-19 10:14:15 -080012013 /* context is valid so caller is still waiting */
12014
12015 /* paranoia: invalidate the magic */
12016 pContext->magic = 0;
12017
12018 /* notify the caller */
Jeff Johnson295189b2012-06-20 16:38:30 -070012019 complete(&pContext->completion);
Jeff Johnson72a40512013-12-19 10:14:15 -080012020
12021 /* serialization is complete */
12022 spin_unlock(&hdd_context_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -070012023}
12024
Katya Nigamf0511f62015-05-05 16:40:57 +053012025void wlan_hdd_mon_set_typesubtype( hdd_mon_ctx_t *pMonCtx,int type)
12026{
12027 pMonCtx->typeSubtypeBitmap = 0;
12028 if( type%10 ) /* Management Packets */
12029 pMonCtx->typeSubtypeBitmap |= 0xFFFF;
12030 type/=10;
12031 if( type%10 ) /* Control Packets */
12032 pMonCtx->typeSubtypeBitmap |= 0xFFFF0000;
12033 type/=10;
12034 if( type%10 ) /* Data Packets */
12035 pMonCtx->typeSubtypeBitmap |= 0xFFFF00000000;
12036}
12037
Hanumanth Reddy Pothulab8be9ab2018-04-12 20:03:05 +053012038VOS_STATUS wlan_hdd_mon_postMsg(void *context, hdd_mon_ctx_t *pMonCtx,
12039 void* callback)
Katya Nigamf0511f62015-05-05 16:40:57 +053012040{
12041 vos_msg_t monMsg;
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +053012042 tSirMonModeReq *pMonModeReq;
Katya Nigamf0511f62015-05-05 16:40:57 +053012043
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +053012044 if (MON_MODE_START == pMonCtx->state)
12045 monMsg.type = WDA_MON_START_REQ;
12046 else if (MON_MODE_STOP == pMonCtx->state)
12047 monMsg.type = WDA_MON_STOP_REQ;
12048 else {
12049 hddLog(VOS_TRACE_LEVEL_ERROR,
12050 FL("invalid monitor state %d"), pMonCtx->state);
Katya Nigamf0511f62015-05-05 16:40:57 +053012051 return VOS_STATUS_E_FAILURE;
12052 }
12053
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +053012054 pMonModeReq = vos_mem_malloc(sizeof(tSirMonModeReq));
12055 if (pMonModeReq == NULL) {
12056 hddLog(VOS_TRACE_LEVEL_ERROR,
12057 FL("fail to allocate memory for monitor mode req"));
12058 return VOS_STATUS_E_FAILURE;
12059 }
Katya Nigamf0511f62015-05-05 16:40:57 +053012060
Hanumanth Reddy Pothulab8be9ab2018-04-12 20:03:05 +053012061 pMonModeReq->context = context;
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +053012062 pMonModeReq->data = pMonCtx;
12063 pMonModeReq->callback = callback;
Katya Nigamf0511f62015-05-05 16:40:57 +053012064
Katya Nigamf0511f62015-05-05 16:40:57 +053012065 monMsg.reserved = 0;
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +053012066 monMsg.bodyptr = pMonModeReq;
Katya Nigamf0511f62015-05-05 16:40:57 +053012067 monMsg.bodyval = 0;
12068
12069 if (VOS_STATUS_SUCCESS != vos_mq_post_message(
12070 VOS_MODULE_ID_WDA,(vos_msg_t *)&monMsg)) {
12071 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: : Failed to post Msg to HAL",__func__);
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +053012072 vos_mem_free(pMonModeReq);
Katya Nigamf0511f62015-05-05 16:40:57 +053012073 }
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +053012074 return VOS_STATUS_SUCCESS;
Katya Nigamf0511f62015-05-05 16:40:57 +053012075}
12076
Katya Nigame7b69a82015-04-28 15:24:06 +053012077void wlan_hdd_mon_close(hdd_context_t *pHddCtx)
12078{
12079 VOS_STATUS vosStatus;
12080 v_CONTEXT_t pVosContext = pHddCtx->pvosContext;
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +053012081 hdd_mon_ctx_t *pMonCtx = NULL;
Hanumanth Reddy Pothulab8be9ab2018-04-12 20:03:05 +053012082 int ret;
12083 void *cookie;
12084 struct hdd_request *request;
12085 static const struct hdd_request_params params = {
12086 .priv_size = 0,
12087 .timeout_ms = MON_MODE_MSG_TIMEOUT,
12088 };
Hanumantha Reddy Pothulac99bc062015-09-08 14:59:26 +053012089
Katya Nigame7b69a82015-04-28 15:24:06 +053012090 hdd_adapter_t *pAdapter = hdd_get_adapter(pHddCtx,WLAN_HDD_MONITOR);
12091 if(pAdapter == NULL || pVosContext == NULL)
12092 {
12093 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, "%s:pAdapter is NULL",__func__);
12094 return ;
12095 }
Katya Nigamf0511f62015-05-05 16:40:57 +053012096
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +053012097 pMonCtx = WLAN_HDD_GET_MONITOR_CTX_PTR(pAdapter);
12098 if (pMonCtx!= NULL && pMonCtx->state == MON_MODE_START) {
12099 pMonCtx->state = MON_MODE_STOP;
Hanumanth Reddy Pothulab8be9ab2018-04-12 20:03:05 +053012100 request = hdd_request_alloc(&params);
12101 if (!request) {
12102 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Request allocation failure"));
12103 return;
12104 }
12105 cookie = hdd_request_cookie(request);
12106
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +053012107 if (VOS_STATUS_SUCCESS !=
Hanumanth Reddy Pothulab8be9ab2018-04-12 20:03:05 +053012108 wlan_hdd_mon_postMsg(cookie, pMonCtx,
12109 hdd_mon_post_msg_cb)) {
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +053012110 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12111 FL("failed to post MON MODE REQ"));
12112 pMonCtx->state = MON_MODE_START;
Hanumanth Reddy Pothulab8be9ab2018-04-12 20:03:05 +053012113 goto req_put;
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +053012114 }
Hanumanth Reddy Pothulab8be9ab2018-04-12 20:03:05 +053012115
12116 ret = hdd_request_wait_for_response(request);
12117 if (ret)
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +053012118 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Hanumanth Reddy Pothulab8be9ab2018-04-12 20:03:05 +053012119 FL("timeout on monitor mode completion %d"), ret);
12120
12121req_put:
12122 hdd_request_put(request);
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +053012123 }
12124
Katya Nigame7b69a82015-04-28 15:24:06 +053012125 hdd_UnregisterWext(pAdapter->dev);
12126
12127 vos_mon_stop( pVosContext );
12128
12129 vosStatus = vos_sched_close( pVosContext );
12130 if (!VOS_IS_STATUS_SUCCESS(vosStatus)) {
12131 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
12132 "%s: Failed to close VOSS Scheduler",__func__);
12133 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
12134 }
12135
12136 vosStatus = vos_nv_close();
12137 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
12138 {
12139 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
12140 "%s: Failed to close NV", __func__);
12141 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
12142 }
12143
12144 vos_close(pVosContext);
12145
12146 #ifdef WLAN_KD_READY_NOTIFIER
12147 nl_srv_exit(pHddCtx->ptt_pid);
12148 #else
12149 nl_srv_exit();
12150 #endif
12151
Katya Nigame7b69a82015-04-28 15:24:06 +053012152 hdd_close_all_adapters( pHddCtx );
Katya Nigame7b69a82015-04-28 15:24:06 +053012153}
Agrawal Ashish33ec71e2015-11-26 20:20:58 +053012154/**
12155 * hdd_wlan_free_wiphy_channels - free Channel pointer for wiphy
12156 * @ wiphy: the wiphy to validate against
12157 *
12158 * Return: void
12159 */
12160void hdd_wlan_free_wiphy_channels(struct wiphy *wiphy)
12161{
12162 int i =0;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053012163 for (i = 0; i < HDD_NUM_NL80211_BANDS; i++)
Agrawal Ashish33ec71e2015-11-26 20:20:58 +053012164 {
12165 if (NULL != wiphy->bands[i] &&
12166 (NULL != wiphy->bands[i]->channels))
12167 {
12168 vos_mem_free(wiphy->bands[i]->channels);
12169 wiphy->bands[i]->channels = NULL;
12170 }
12171 }
12172}
Jeff Johnson295189b2012-06-20 16:38:30 -070012173/**---------------------------------------------------------------------------
12174
12175 \brief hdd_wlan_exit() - HDD WLAN exit function
12176
12177 This is the driver exit point (invoked during rmmod)
12178
12179 \param - pHddCtx - Pointer to the HDD Context
12180
12181 \return - None
12182
12183 --------------------------------------------------------------------------*/
12184void hdd_wlan_exit(hdd_context_t *pHddCtx)
12185{
12186 eHalStatus halStatus;
12187 v_CONTEXT_t pVosContext = pHddCtx->pvosContext;
12188 VOS_STATUS vosStatus;
Gopichand Nakkala66923aa2013-03-06 23:17:24 +053012189 struct wiphy *wiphy = pHddCtx->wiphy;
Mingcheng Zhu87f22fc2014-01-30 19:23:32 -080012190 hdd_adapter_t* pAdapter = NULL;
Jeff Johnson72a40512013-12-19 10:14:15 -080012191 struct statsContext powerContext;
Jeff Johnson295189b2012-06-20 16:38:30 -070012192 long lrc;
c_hpothu5ab05e92014-06-13 17:34:05 +053012193 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070012194
12195 ENTER();
12196
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +053012197
Katya Nigame7b69a82015-04-28 15:24:06 +053012198 if (VOS_MONITOR_MODE == hdd_get_conparam())
12199 {
12200 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: MONITOR MODE",__func__);
12201 wlan_hdd_mon_close(pHddCtx);
Hanumantha Reddy Pothulac99bc062015-09-08 14:59:26 +053012202 goto free_hdd_ctx;
Katya Nigame7b69a82015-04-28 15:24:06 +053012203 }
12204 else if (VOS_FTM_MODE != hdd_get_conparam())
Jeff Johnson88ba7742013-02-27 14:36:02 -080012205 {
12206 // Unloading, restart logic is no more required.
12207 wlan_hdd_restart_deinit(pHddCtx);
Jeff Johnsone7245742012-09-05 17:12:55 -070012208
Agarwal Ashishb20e0ff2014-12-17 22:50:19 +053012209#ifdef FEATURE_WLAN_TDLS
12210 /* At the time of driver unloading; if tdls connection is present;
12211 * hdd_rx_packet_cbk calls wlan_hdd_tdls_find_peer.
12212 * wlan_hdd_tdls_find_peer always checks for valid context;
12213 * as load/unload in progress there can be a race condition.
12214 * hdd_rx_packet_cbk calls wlan_hdd_tdls_find_peer only
12215 * when tdls state is enabled.
12216 * As soon as driver set load/unload flag; tdls flag also needs
12217 * to be disabled so that hdd_rx_packet_cbk won't call
12218 * wlan_hdd_tdls_find_peer.
12219 */
Masti, Narayanraddi20494af2015-12-17 20:56:42 +053012220 wlan_hdd_tdls_set_mode(pHddCtx, eTDLS_SUPPORT_DISABLED, FALSE,
12221 HDD_SET_TDLS_MODE_SOURCE_USER);
Agarwal Ashishb20e0ff2014-12-17 22:50:19 +053012222#endif
12223
c_hpothu5ab05e92014-06-13 17:34:05 +053012224 vosStatus = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
12225 while (NULL != pAdapterNode && VOS_STATUS_E_EMPTY != vosStatus)
Jeff Johnson295189b2012-06-20 16:38:30 -070012226 {
c_hpothu5ab05e92014-06-13 17:34:05 +053012227 pAdapter = pAdapterNode->pAdapter;
12228 if (NULL != pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -070012229 {
Mahesh A Saptasagar305e2632015-03-04 12:57:33 +053012230 /* Disable TX on the interface, after this hard_start_xmit() will
12231 * not be called on that interface
12232 */
12233 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
12234 netif_tx_disable(pAdapter->dev);
12235
12236 /* Mark the interface status as "down" for outside world */
12237 netif_carrier_off(pAdapter->dev);
12238
Agarwal Ashish9ffa5b92014-11-18 21:07:02 +053012239 /* DeInit the adapter. This ensures that all data packets
12240 * are freed.
12241 */
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +053012242#ifdef FEATURE_WLAN_TDLS
12243 mutex_lock(&pHddCtx->tdls_lock);
12244#endif
c_hpothu002231a2015-02-05 14:58:51 +053012245 hdd_deinit_adapter(pHddCtx, pAdapter, FALSE);
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +053012246#ifdef FEATURE_WLAN_TDLS
12247 mutex_unlock(&pHddCtx->tdls_lock);
12248#endif
Masti, Narayanraddi26378462016-01-05 18:20:28 +053012249 vos_flush_delayed_work(&pHddCtx->scan_ctxt.scan_work);
12250
12251 wlan_hdd_init_deinit_defer_scan_context(&pHddCtx->scan_ctxt);
Agarwal Ashish9ffa5b92014-11-18 21:07:02 +053012252
c_hpothu5ab05e92014-06-13 17:34:05 +053012253 if (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +053012254 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode ||
12255 WLAN_HDD_MONITOR == pAdapter->device_mode)
c_hpothu5ab05e92014-06-13 17:34:05 +053012256 {
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +053012257 if (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
12258 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode)
12259 wlan_hdd_cfg80211_deregister_frames(pAdapter);
12260
c_hpothu5ab05e92014-06-13 17:34:05 +053012261 hdd_UnregisterWext(pAdapter->dev);
12262 }
Kaushik, Sushant4975a572014-10-21 16:07:48 +053012263
Jeff Johnson295189b2012-06-20 16:38:30 -070012264 }
c_hpothu5ab05e92014-06-13 17:34:05 +053012265 vosStatus = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
12266 pAdapterNode = pNext;
Jeff Johnson295189b2012-06-20 16:38:30 -070012267 }
mukul sharmabab477d2015-06-11 17:14:55 +053012268
Kaushik, Sushant4975a572014-10-21 16:07:48 +053012269 // Cancel any outstanding scan requests. We are about to close all
12270 // of our adapters, but an adapter structure is what SME passes back
12271 // to our callback function. Hence if there are any outstanding scan
12272 // requests then there is a race condition between when the adapter
12273 // is closed and when the callback is invoked.We try to resolve that
12274 // race condition here by canceling any outstanding scans before we
12275 // close the adapters.
12276 // Note that the scans may be cancelled in an asynchronous manner,
12277 // so ideally there needs to be some kind of synchronization. Rather
12278 // than introduce a new synchronization here, we will utilize the
12279 // fact that we are about to Request Full Power, and since that is
12280 // synchronized, the expectation is that by the time Request Full
12281 // Power has completed all scans will be cancelled.
12282 if (pHddCtx->scan_info.mScanPending)
12283 {
Hema Aparna Medicharlaf05f6cd2015-01-21 14:44:19 +053012284 if(NULL != pAdapter)
12285 {
12286 hddLog(VOS_TRACE_LEVEL_INFO,
12287 FL("abort scan mode: %d sessionId: %d"),
12288 pAdapter->device_mode,
12289 pAdapter->sessionId);
12290 }
12291 hdd_abort_mac_scan(pHddCtx,
12292 pHddCtx->scan_info.sessionId,
12293 eCSR_SCAN_ABORT_DEFAULT);
Kaushik, Sushant4975a572014-10-21 16:07:48 +053012294 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012295 }
c_hpothu5ab05e92014-06-13 17:34:05 +053012296 else
Jeff Johnson88ba7742013-02-27 14:36:02 -080012297 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012298 hddLog(VOS_TRACE_LEVEL_INFO,"%s: FTM MODE",__func__);
Hanumantha Reddy Pothula45af96b2015-02-12 16:07:58 +053012299 if (pHddCtx->ftm.ftm_state == WLAN_FTM_STARTING)
12300 {
12301 INIT_COMPLETION(pHddCtx->ftm.startCmpVar);
12302 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
12303 "%s: in middle of FTM START", __func__);
12304 lrc = wait_for_completion_timeout(&pHddCtx->ftm.startCmpVar,
12305 msecs_to_jiffies(20000));
12306 if(!lrc)
12307 {
12308 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
12309 "%s: timedout on ftmStartCmpVar fatal error", __func__);
12310 }
12311 }
Jeff Johnson88ba7742013-02-27 14:36:02 -080012312 wlan_hdd_ftm_close(pHddCtx);
12313 goto free_hdd_ctx;
12314 }
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012315
Jeff Johnson295189b2012-06-20 16:38:30 -070012316 /* DeRegister with platform driver as client for Suspend/Resume */
12317 vosStatus = hddDeregisterPmOps(pHddCtx);
12318 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
12319 {
12320 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddDeregisterPmOps failed",__func__);
12321 VOS_ASSERT(0);
12322 }
12323
12324 vosStatus = hddDevTmUnregisterNotifyCallback(pHddCtx);
12325 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
12326 {
12327 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddDevTmUnregisterNotifyCallback failed",__func__);
12328 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012329
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -070012330 //Stop the traffic monitor timer
Mahesh A Saptasagard461e432016-07-20 15:01:40 +053012331 if ((pHddCtx->cfg_ini->dynSplitscan) && (VOS_TIMER_STATE_RUNNING ==
12332 vos_timer_getCurrentState(&pHddCtx->tx_rx_trafficTmr)))
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -070012333 {
12334 vos_timer_stop(&pHddCtx->tx_rx_trafficTmr);
12335 }
12336
12337 // Destroy the traffic monitor timer
Mahesh A Saptasagard461e432016-07-20 15:01:40 +053012338 if ((pHddCtx->cfg_ini->dynSplitscan) &&
12339 (!VOS_IS_STATUS_SUCCESS(vos_timer_destroy(
12340 &pHddCtx->tx_rx_trafficTmr))))
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -070012341 {
12342 hddLog(VOS_TRACE_LEVEL_ERROR,
12343 "%s: Cannot deallocate Traffic monitor timer", __func__);
12344 }
12345
Bhargav Shahd0715912015-10-01 18:17:37 +053012346 if (VOS_TIMER_STATE_RUNNING ==
12347 vos_timer_getCurrentState(&pHddCtx->delack_timer)) {
12348 vos_timer_stop(&pHddCtx->delack_timer);
12349 }
12350
12351 if (!VOS_IS_STATUS_SUCCESS(vos_timer_destroy(
12352 &pHddCtx->delack_timer))) {
12353 hddLog(VOS_TRACE_LEVEL_ERROR,
12354 "%s: Cannot deallocate Bus bandwidth timer", __func__);
12355 }
12356
Masti, Narayanraddi44b0db02015-12-22 11:54:35 +053012357 if (VOS_TIMER_STATE_RUNNING ==
12358 vos_timer_getCurrentState(&pHddCtx->tdls_source_timer)) {
12359 vos_timer_stop(&pHddCtx->tdls_source_timer);
12360 }
12361
Abhishek Singh8a3e4dc2017-01-02 10:39:18 +053012362 vos_set_snoc_high_freq_voting(false);
12363
Masti, Narayanraddi44b0db02015-12-22 11:54:35 +053012364 vos_timer_destroy(&pHddCtx->tdls_source_timer);
12365
Jeff Johnson295189b2012-06-20 16:38:30 -070012366 //Disable IMPS/BMPS as we do not want the device to enter any power
12367 //save mode during shutdown
12368 sme_DisablePowerSave(pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
12369 sme_DisablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
12370 sme_DisablePowerSave(pHddCtx->hHal, ePMC_UAPSD_MODE_POWER_SAVE);
12371
12372 //Ensure that device is in full power as we will touch H/W during vos_Stop
12373 init_completion(&powerContext.completion);
12374 powerContext.magic = POWER_CONTEXT_MAGIC;
12375
12376 halStatus = sme_RequestFullPower(pHddCtx->hHal, hdd_full_power_callback,
12377 &powerContext, eSME_FULL_PWR_NEEDED_BY_HDD);
12378
12379 if (eHAL_STATUS_SUCCESS != halStatus)
12380 {
12381 if (eHAL_STATUS_PMC_PENDING == halStatus)
12382 {
12383 /* request was sent -- wait for the response */
12384 lrc = wait_for_completion_interruptible_timeout(
12385 &powerContext.completion,
12386 msecs_to_jiffies(WLAN_WAIT_TIME_POWER));
Jeff Johnson295189b2012-06-20 16:38:30 -070012387 if (lrc <= 0)
12388 {
12389 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: %s while requesting full power",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070012390 __func__, (0 == lrc) ? "timeout" : "interrupt");
Jeff Johnson295189b2012-06-20 16:38:30 -070012391 }
12392 }
12393 else
12394 {
12395 hddLog(VOS_TRACE_LEVEL_ERROR,
12396 "%s: Request for Full Power failed, status %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070012397 __func__, halStatus);
Jeff Johnson295189b2012-06-20 16:38:30 -070012398 /* continue -- need to clean up as much as possible */
12399 }
12400 }
Hanumantha Reddy Pothula81b42b22015-05-12 13:52:00 +053012401 if ((eHAL_STATUS_SUCCESS == halStatus) ||
12402 (eHAL_STATUS_PMC_PENDING == halStatus && lrc > 0))
12403 {
12404 /* This will issue a dump command which will clean up
12405 BTQM queues and unblock MC thread */
12406 vos_fwDumpReq(274, 0, 0, 0, 0, 1);
12407 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012408
Jeff Johnson72a40512013-12-19 10:14:15 -080012409 /* either we never sent a request, we sent a request and received a
12410 response or we sent a request and timed out. if we never sent a
12411 request or if we sent a request and got a response, we want to
12412 clear the magic out of paranoia. if we timed out there is a
12413 race condition such that the callback function could be
12414 executing at the same time we are. of primary concern is if the
12415 callback function had already verified the "magic" but had not
12416 yet set the completion variable when a timeout occurred. we
12417 serialize these activities by invalidating the magic while
12418 holding a shared spinlock which will cause us to block if the
12419 callback is currently executing */
12420 spin_lock(&hdd_context_lock);
12421 powerContext.magic = 0;
12422 spin_unlock(&hdd_context_lock);
12423
Hema Aparna Medicharlaa6cf65e2015-06-01 16:23:28 +053012424 /* If Device is shutdown, no point for SME to wait for responses
12425 from device. Pre Close SME */
12426 if(wcnss_device_is_shutdown())
12427 {
12428 sme_PreClose(pHddCtx->hHal);
12429 }
Yue Ma0d4891e2013-08-06 17:01:45 -070012430 hdd_debugfs_exit(pHddCtx);
12431
Ratheesh S P35ed8b12015-04-27 14:01:07 +053012432#ifdef WLAN_NS_OFFLOAD
Ratheesh S P36dbc932015-08-07 14:28:57 +053012433 hddLog(LOG1, FL("Unregister IPv6 notifier"));
Ratheesh S P35ed8b12015-04-27 14:01:07 +053012434 unregister_inet6addr_notifier(&pHddCtx->ipv6_notifier);
12435#endif
Ratheesh S P36dbc932015-08-07 14:28:57 +053012436 hddLog(LOG1, FL("Unregister IPv4 notifier"));
Ratheesh S P35ed8b12015-04-27 14:01:07 +053012437 unregister_inetaddr_notifier(&pHddCtx->ipv4_notifier);
12438
Jeff Johnson295189b2012-06-20 16:38:30 -070012439 // Unregister the Net Device Notifier
12440 unregister_netdevice_notifier(&hdd_netdev_notifier);
12441
Jeff Johnson295189b2012-06-20 16:38:30 -070012442 hdd_stop_all_adapters( pHddCtx );
12443
Jeff Johnson295189b2012-06-20 16:38:30 -070012444#ifdef WLAN_BTAMP_FEATURE
12445 vosStatus = WLANBAP_Stop(pVosContext);
12446 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
12447 {
12448 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
12449 "%s: Failed to stop BAP",__func__);
12450 }
12451#endif //WLAN_BTAMP_FEATURE
12452
12453 //Stop all the modules
12454 vosStatus = vos_stop( pVosContext );
12455 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
12456 {
12457 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
12458 "%s: Failed to stop VOSS",__func__);
12459 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
Hanumantha Reddy Pothulabd9601a2016-02-12 13:22:27 +053012460 if (isSsrPanicOnFailure())
12461 VOS_BUG(0);
Jeff Johnson295189b2012-06-20 16:38:30 -070012462 }
12463
Jeff Johnson295189b2012-06-20 16:38:30 -070012464 //This requires pMac access, Call this before vos_close().
Jeff Johnson295189b2012-06-20 16:38:30 -070012465 hdd_unregister_mcast_bcast_filter(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -070012466
12467 //Close the scheduler before calling vos_close to make sure no thread is
12468 // scheduled after the each module close is called i.e after all the data
12469 // structures are freed.
12470 vosStatus = vos_sched_close( pVosContext );
12471 if (!VOS_IS_STATUS_SUCCESS(vosStatus)) {
12472 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
12473 "%s: Failed to close VOSS Scheduler",__func__);
12474 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
12475 }
Jeff Johnsone7245742012-09-05 17:12:55 -070012476#ifdef WLAN_FEATURE_HOLD_RX_WAKELOCK
12477 /* Destroy the wake lock */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053012478 vos_wake_lock_destroy(&pHddCtx->rx_wake_lock);
Jeff Johnsone7245742012-09-05 17:12:55 -070012479#endif
Madan Mohan Koyyalamudi69fc3ad2012-11-28 16:04:56 -080012480 /* Destroy the wake lock */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053012481 vos_wake_lock_destroy(&pHddCtx->sap_wake_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -070012482
Mihir Shete7a24b5f2013-12-21 12:18:31 +053012483#ifdef CONFIG_ENABLE_LINUX_REG
12484 vosStatus = vos_nv_close();
12485 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
12486 {
12487 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
12488 "%s: Failed to close NV", __func__);
12489 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
12490 }
12491#endif
12492
Jeff Johnson295189b2012-06-20 16:38:30 -070012493 //Close VOSS
12494 //This frees pMac(HAL) context. There should not be any call that requires pMac access after this.
12495 vos_close(pVosContext);
12496
Jeff Johnson295189b2012-06-20 16:38:30 -070012497 //Close Watchdog
12498 if(pHddCtx->cfg_ini->fIsLogpEnabled)
12499 vos_watchdog_close(pVosContext);
12500
Gopichand Nakkalaa0358482013-06-12 17:05:47 +053012501 //Clean up HDD Nlink Service
12502 send_btc_nlink_msg(WLAN_MODULE_DOWN_IND, 0);
Gopichand Nakkalaa0358482013-06-12 17:05:47 +053012503
Manjeet Singh47ee8472016-04-11 11:57:18 +053012504 hdd_close_tx_queues(pHddCtx);
c_manjeecfd1efb2015-09-25 19:32:34 +053012505 wlan_free_fwr_mem_dump_buffer();
c_manjeecfd1efb2015-09-25 19:32:34 +053012506
Vinay Krishna Erannad938c422014-03-10 17:14:21 +053012507#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +053012508 if (pHddCtx->cfg_ini->wlanLoggingEnable)
Vinay Krishna Erannad938c422014-03-10 17:14:21 +053012509 {
12510 wlan_logging_sock_deactivate_svc();
12511 }
12512#endif
12513
Vinay Krishna Erannaef30b522014-08-26 17:48:16 +053012514#ifdef WLAN_KD_READY_NOTIFIER
12515 nl_srv_exit(pHddCtx->ptt_pid);
12516#else
12517 nl_srv_exit();
12518#endif /* WLAN_KD_READY_NOTIFIER */
12519
Abhishek Singh00b71972016-01-07 10:51:04 +053012520#ifdef WLAN_FEATURE_RMC
12521 hdd_close_cesium_nl_sock();
12522#endif /* WLAN_FEATURE_RMC */
Vinay Krishna Erannaef30b522014-08-26 17:48:16 +053012523
Jeff Johnson295189b2012-06-20 16:38:30 -070012524 hdd_close_all_adapters( pHddCtx );
12525
Padma, Santhosh Kumar9cd38332015-11-17 12:18:10 +053012526 vos_flush_delayed_work(&pHddCtx->spoof_mac_addr_work);
Abhishek Singh78c691f2017-11-30 13:48:44 +053012527 vos_flush_delayed_work(&pHddCtx->ecsa_chan_change_work);
Kapil Gupta137ef892016-12-13 19:38:00 +053012528 vos_flush_work(&pHddCtx->sap_start_work);
Padma, Santhosh Kumar9cd38332015-11-17 12:18:10 +053012529
Hanumantha Reddy Pothula97f9bc92015-08-10 17:21:20 +053012530free_hdd_ctx:
Jeff Johnson295189b2012-06-20 16:38:30 -070012531 /* free the power on lock from platform driver */
12532 if (free_riva_power_on_lock("wlan"))
12533 {
12534 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to free power on lock",
12535 __func__);
12536 }
12537
Ashish Kumar Dhanotiya95e5bc22018-04-19 17:06:33 +053012538 /* Free the cache channels of the command SET_DISABLE_CHANNEL_LIST */
12539 wlan_hdd_free_cache_channels(pHddCtx);
12540
c_hpothu78c7b602014-05-17 17:35:49 +053012541 //Free up dynamically allocated members inside HDD Adapter
12542 if (pHddCtx->cfg_ini)
12543 {
12544 kfree(pHddCtx->cfg_ini);
12545 pHddCtx->cfg_ini= NULL;
12546 }
12547
Hanumanth Reddy Pothula1efcd162018-03-14 14:32:27 +053012548 hdd_request_manager_deinit();
12549
Hanumantha Reddy Pothula6fe221c2016-01-28 15:01:09 +053012550 /* FTM/MONITOR mode, WIPHY did not registered
Leo Changf04ddad2013-09-18 13:46:38 -070012551 If un-register here, system crash will happen */
Hanumantha Reddy Pothula6fe221c2016-01-28 15:01:09 +053012552 if (!(VOS_FTM_MODE == hdd_get_conparam() ||
12553 VOS_MONITOR_MODE == hdd_get_conparam()))
Leo Changf04ddad2013-09-18 13:46:38 -070012554 {
12555 wiphy_unregister(wiphy) ;
Agrawal Ashish33ec71e2015-11-26 20:20:58 +053012556 hdd_wlan_free_wiphy_channels(wiphy);
Leo Changf04ddad2013-09-18 13:46:38 -070012557 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012558 wiphy_free(wiphy) ;
Jeff Johnson295189b2012-06-20 16:38:30 -070012559 if (hdd_is_ssr_required())
12560 {
12561 /* WDI timeout had happened during unload, so SSR is needed here */
Madan Mohan Koyyalamudi3246f5b2012-10-15 15:40:02 -070012562 subsystem_restart("wcnss");
Jeff Johnson295189b2012-06-20 16:38:30 -070012563 msleep(5000);
12564 }
12565 hdd_set_ssr_required (VOS_FALSE);
12566}
12567
12568
12569/**---------------------------------------------------------------------------
12570
12571 \brief hdd_update_config_from_nv() - Function to update the contents of
12572 the running configuration with parameters taken from NV storage
12573
12574 \param - pHddCtx - Pointer to the HDD global context
12575
12576 \return - VOS_STATUS_SUCCESS if successful
12577
12578 --------------------------------------------------------------------------*/
12579static VOS_STATUS hdd_update_config_from_nv(hdd_context_t* pHddCtx)
12580{
Jeff Johnson295189b2012-06-20 16:38:30 -070012581 v_BOOL_t itemIsValid = VOS_FALSE;
12582 VOS_STATUS status;
12583 v_MACADDR_t macFromNV[VOS_MAX_CONCURRENCY_PERSONA];
12584 v_U8_t macLoop;
12585
12586 /*If the NV is valid then get the macaddress from nv else get it from qcom_cfg.ini*/
12587 status = vos_nv_getValidity(VNV_FIELD_IMAGE, &itemIsValid);
12588 if(status != VOS_STATUS_SUCCESS)
12589 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080012590 hddLog(VOS_TRACE_LEVEL_ERROR," vos_nv_getValidity() failed");
Jeff Johnson295189b2012-06-20 16:38:30 -070012591 return VOS_STATUS_E_FAILURE;
12592 }
12593
12594 if (itemIsValid == VOS_TRUE)
12595 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080012596 hddLog(VOS_TRACE_LEVEL_INFO_HIGH," Reading the Macaddress from NV");
Jeff Johnson295189b2012-06-20 16:38:30 -070012597 status = vos_nv_readMultiMacAddress((v_U8_t *)&macFromNV[0].bytes[0],
12598 VOS_MAX_CONCURRENCY_PERSONA);
12599 if(status != VOS_STATUS_SUCCESS)
12600 {
12601 /* Get MAC from NV fail, not update CFG info
12602 * INI MAC value will be used for MAC setting */
Arif Hussain6d2a3322013-11-17 19:50:10 -080012603 hddLog(VOS_TRACE_LEVEL_ERROR," vos_nv_readMacAddress() failed");
Jeff Johnson295189b2012-06-20 16:38:30 -070012604 return VOS_STATUS_E_FAILURE;
12605 }
12606
12607 /* If first MAC is not valid, treat all others are not valid
12608 * Then all MACs will be got from ini file */
12609 if(vos_is_macaddr_zero(&macFromNV[0]))
12610 {
12611 /* MAC address in NV file is not configured yet */
12612 hddLog(VOS_TRACE_LEVEL_WARN, "Invalid MAC in NV file");
12613 return VOS_STATUS_E_INVAL;
12614 }
12615
12616 /* Get MAC address from NV, update CFG info */
12617 for(macLoop = 0; macLoop < VOS_MAX_CONCURRENCY_PERSONA; macLoop++)
12618 {
12619 if(vos_is_macaddr_zero(&macFromNV[macLoop]))
12620 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012621 hddLog(VOS_TRACE_LEVEL_ERROR,"not valid MAC from NV for %d", macLoop);
Jeff Johnson295189b2012-06-20 16:38:30 -070012622 /* This MAC is not valid, skip it
12623 * This MAC will be got from ini file */
12624 }
12625 else
12626 {
12627 vos_mem_copy((v_U8_t *)&pHddCtx->cfg_ini->intfMacAddr[macLoop].bytes[0],
12628 (v_U8_t *)&macFromNV[macLoop].bytes[0],
12629 VOS_MAC_ADDR_SIZE);
12630 }
12631 }
12632 }
12633 else
12634 {
12635 hddLog(VOS_TRACE_LEVEL_ERROR, "NV ITEM, MAC Not valid");
12636 return VOS_STATUS_E_FAILURE;
12637 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012638
Jeff Johnson295189b2012-06-20 16:38:30 -070012639
12640 return VOS_STATUS_SUCCESS;
12641}
12642
12643/**---------------------------------------------------------------------------
12644
12645 \brief hdd_post_voss_start_config() - HDD post voss start config helper
12646
12647 \param - pAdapter - Pointer to the HDD
12648
12649 \return - None
12650
12651 --------------------------------------------------------------------------*/
12652VOS_STATUS hdd_post_voss_start_config(hdd_context_t* pHddCtx)
12653{
12654 eHalStatus halStatus;
12655 v_U32_t listenInterval;
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +053012656 tANI_U32 ignoreDtim;
Jeff Johnson295189b2012-06-20 16:38:30 -070012657
Jeff Johnson295189b2012-06-20 16:38:30 -070012658
12659 // Send ready indication to the HDD. This will kick off the MAC
12660 // into a 'running' state and should kick off an initial scan.
12661 halStatus = sme_HDDReadyInd( pHddCtx->hHal );
12662 if ( !HAL_STATUS_SUCCESS( halStatus ) )
12663 {
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +053012664 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: sme_HDDReadyInd() failed with status "
Jeff Johnson295189b2012-06-20 16:38:30 -070012665 "code %08d [x%08x]",__func__, halStatus, halStatus );
12666 return VOS_STATUS_E_FAILURE;
12667 }
12668
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +053012669 // Set default LI and ignoreDtim into HDD context,
Jeff Johnson295189b2012-06-20 16:38:30 -070012670 // otherwise under some race condition, HDD will set 0 LI value into RIVA,
12671 // And RIVA will crash
12672 wlan_cfgGetInt(pHddCtx->hHal, WNI_CFG_LISTEN_INTERVAL, &listenInterval);
12673 pHddCtx->hdd_actual_LI_value = listenInterval;
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +053012674 wlan_cfgGetInt(pHddCtx->hHal, WNI_CFG_IGNORE_DTIM, &ignoreDtim);
12675 pHddCtx->hdd_actual_ignore_DTIM_value = ignoreDtim;
12676
12677
Jeff Johnson295189b2012-06-20 16:38:30 -070012678 return VOS_STATUS_SUCCESS;
12679}
12680
Jeff Johnson295189b2012-06-20 16:38:30 -070012681/* wake lock APIs for HDD */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053012682void hdd_prevent_suspend(uint32_t reason)
Jeff Johnson295189b2012-06-20 16:38:30 -070012683{
Sushant Kaushik83392fa2015-05-05 17:44:40 +053012684
12685 vos_wake_lock_acquire(&wlan_wake_lock, reason);
12686
Jeff Johnson295189b2012-06-20 16:38:30 -070012687}
12688
Sushant Kaushik83392fa2015-05-05 17:44:40 +053012689void hdd_allow_suspend(uint32_t reason)
Jeff Johnson295189b2012-06-20 16:38:30 -070012690{
Sushant Kaushik83392fa2015-05-05 17:44:40 +053012691
12692 vos_wake_lock_release(&wlan_wake_lock, reason);
12693
Jeff Johnson295189b2012-06-20 16:38:30 -070012694}
12695
Sushant Kaushik83392fa2015-05-05 17:44:40 +053012696void hdd_prevent_suspend_timeout(v_U32_t timeout, uint32_t reason)
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -070012697{
Sushant Kaushik83392fa2015-05-05 17:44:40 +053012698
12699 vos_wake_lock_timeout_release(&wlan_wake_lock, timeout,
12700 reason);
12701
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -070012702}
12703
Rajeev Kumar Sirasanagandla4c068d42019-02-22 21:39:36 +053012704/**
12705 * hdd_get_feature_caps_cb() - Callback invoked from WDA
12706 * @cookie: to identify HDD request to firmware
12707 *
12708 * This function is invoked from WDA when feature capabilities response
12709 * is received from firmware.
12710 *
12711 * Return: None
12712 */
12713static void hdd_get_feature_caps_cb(void *cookie)
12714{
12715 struct hdd_request *request;
12716
12717 request = hdd_request_get(cookie);
12718 if (!request) {
12719 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Obsolete request"));
12720 return;
12721 }
12722
12723 pr_info("%s: Firmware feature capabilities received\n", __func__);
12724
12725 hdd_request_complete(request);
12726 hdd_request_put(request);
12727}
12728
12729/**
12730 * hdd_get_feature_caps() - Get features supported by firmware
12731 * @hdd_ctx: Pointer to HDD context
12732 *
12733 * This function uses request manager framework to get the feature
12734 * capabilities from firmware.
12735 *
12736 * Return: None
12737 */
12738static void hdd_get_feature_caps(hdd_context_t *hdd_ctx)
12739{
12740 VOS_STATUS status;
12741 void *cookie;
12742 int ret;
12743 struct hdd_request *request;
12744 static const struct hdd_request_params params = {
12745 .priv_size = 0,
12746 .timeout_ms = WLAN_WAIT_TIME_FEATURE_CAPS,
12747 };
12748 struct sir_feature_caps_params caps_params = {0};
12749
12750 request = hdd_request_alloc(&params);
12751 if (!request) {
12752 pr_err("%s: Request allocation failure\n", __func__);
12753 return;
12754 }
12755
12756 cookie = hdd_request_cookie(request);
12757 caps_params.user_data = cookie;
12758 caps_params.feature_caps_cb = hdd_get_feature_caps_cb;
12759
12760 status = sme_featureCapsExchange(&caps_params);
12761 if (status != VOS_STATUS_SUCCESS) {
12762 pr_err("%s: Unable to get feature caps\n", __func__);
12763 goto end;
12764 }
12765
12766 /* request was sent -- wait for the response */
12767 ret = hdd_request_wait_for_response(request);
12768 if (ret) {
12769 pr_err("%s: SME timeout while retrieving feature caps\n",
12770 __func__);
12771 goto end;
12772 }
12773
12774end:
12775 hdd_request_put(request);
12776}
12777
Jeff Johnson295189b2012-06-20 16:38:30 -070012778/**---------------------------------------------------------------------------
12779
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -070012780 \brief hdd_exchange_version_and_caps() - HDD function to exchange version and capability
12781 information between Host and Riva
12782
12783 This function gets reported version of FW
12784 It also finds the version of Riva headers used to compile the host
12785 It compares the above two and prints a warning if they are different
12786 It gets the SW and HW version string
12787 Finally, it exchanges capabilities between host and Riva i.e. host and riva exchange a msg
12788 indicating the features they support through a bitmap
12789
12790 \param - pHddCtx - Pointer to HDD context
12791
12792 \return - void
12793
12794 --------------------------------------------------------------------------*/
12795
12796void hdd_exchange_version_and_caps(hdd_context_t *pHddCtx)
12797{
12798
12799 tSirVersionType versionCompiled;
12800 tSirVersionType versionReported;
12801 tSirVersionString versionString;
12802 tANI_U8 fwFeatCapsMsgSupported = 0;
12803 VOS_STATUS vstatus;
12804
Mingcheng Zhu87f22fc2014-01-30 19:23:32 -080012805 memset(&versionCompiled, 0, sizeof(versionCompiled));
12806 memset(&versionReported, 0, sizeof(versionReported));
12807
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -070012808 /* retrieve and display WCNSS version information */
12809 do {
12810
12811 vstatus = sme_GetWcnssWlanCompiledVersion(pHddCtx->hHal,
12812 &versionCompiled);
12813 if (!VOS_IS_STATUS_SUCCESS(vstatus))
12814 {
12815 hddLog(VOS_TRACE_LEVEL_FATAL,
12816 "%s: unable to retrieve WCNSS WLAN compiled version",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070012817 __func__);
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -070012818 break;
12819 }
12820
12821 vstatus = sme_GetWcnssWlanReportedVersion(pHddCtx->hHal,
12822 &versionReported);
12823 if (!VOS_IS_STATUS_SUCCESS(vstatus))
12824 {
12825 hddLog(VOS_TRACE_LEVEL_FATAL,
12826 "%s: unable to retrieve WCNSS WLAN reported version",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070012827 __func__);
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -070012828 break;
12829 }
12830
12831 if ((versionCompiled.major != versionReported.major) ||
12832 (versionCompiled.minor != versionReported.minor) ||
12833 (versionCompiled.version != versionReported.version) ||
12834 (versionCompiled.revision != versionReported.revision))
12835 {
12836 pr_err("%s: WCNSS WLAN Version %u.%u.%u.%u, "
12837 "Host expected %u.%u.%u.%u\n",
12838 WLAN_MODULE_NAME,
12839 (int)versionReported.major,
12840 (int)versionReported.minor,
12841 (int)versionReported.version,
12842 (int)versionReported.revision,
12843 (int)versionCompiled.major,
12844 (int)versionCompiled.minor,
12845 (int)versionCompiled.version,
12846 (int)versionCompiled.revision);
12847 }
12848 else
12849 {
12850 pr_info("%s: WCNSS WLAN version %u.%u.%u.%u\n",
12851 WLAN_MODULE_NAME,
12852 (int)versionReported.major,
12853 (int)versionReported.minor,
12854 (int)versionReported.version,
12855 (int)versionReported.revision);
12856 }
12857
12858 vstatus = sme_GetWcnssSoftwareVersion(pHddCtx->hHal,
12859 versionString,
12860 sizeof(versionString));
12861 if (!VOS_IS_STATUS_SUCCESS(vstatus))
12862 {
12863 hddLog(VOS_TRACE_LEVEL_FATAL,
12864 "%s: unable to retrieve WCNSS software version string",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070012865 __func__);
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -070012866 break;
12867 }
12868
12869 pr_info("%s: WCNSS software version %s\n",
12870 WLAN_MODULE_NAME, versionString);
Sushant Kaushik084f6592015-09-10 13:11:56 +053012871 vos_mem_copy(pHddCtx->fw_Version, versionString, sizeof(versionString));
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -070012872
12873 vstatus = sme_GetWcnssHardwareVersion(pHddCtx->hHal,
12874 versionString,
12875 sizeof(versionString));
12876 if (!VOS_IS_STATUS_SUCCESS(vstatus))
12877 {
12878 hddLog(VOS_TRACE_LEVEL_FATAL,
12879 "%s: unable to retrieve WCNSS hardware version string",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070012880 __func__);
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -070012881 break;
12882 }
12883
12884 pr_info("%s: WCNSS hardware version %s\n",
12885 WLAN_MODULE_NAME, versionString);
12886
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -070012887 /* 1.Check if FW version is greater than 0.1.1.0. Only then send host-FW capability exchange message
12888 2.Host-FW capability exchange message is only present on riva 1.1 so
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -070012889 send the message only if it the riva is 1.1
12890 minor numbers for different riva branches:
12891 0 -> (1.0)Mainline Build
12892 1 -> (1.1)Mainline Build
12893 2->(1.04) Stability Build
12894 */
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -070012895 if (((versionReported.major>0) || (versionReported.minor>1) ||
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -070012896 ((versionReported.minor>=1) && (versionReported.version>=1)))
12897 && ((versionReported.major == 1) && (versionReported.minor >= 1)))
12898 fwFeatCapsMsgSupported = 1;
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -070012899
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -070012900 if (fwFeatCapsMsgSupported)
Yathish9f22e662012-12-10 14:21:35 -080012901 {
12902#ifdef WLAN_ACTIVEMODE_OFFLOAD_FEATURE
12903 if(!pHddCtx->cfg_ini->fEnableActiveModeOffload)
12904 sme_disableFeatureCapablity(WLANACTIVE_OFFLOAD);
12905#endif
Ravi Joshid2ca7c42013-07-23 08:37:49 -070012906 /* Indicate if IBSS heartbeat monitoring needs to be offloaded */
12907 if (!pHddCtx->cfg_ini->enableIbssHeartBeatOffload)
12908 {
12909 sme_disableFeatureCapablity(IBSS_HEARTBEAT_OFFLOAD);
12910 }
12911
Rajeev Kumar Sirasanagandla4c068d42019-02-22 21:39:36 +053012912 hdd_get_feature_caps(pHddCtx);
Yathish9f22e662012-12-10 14:21:35 -080012913 }
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -070012914
12915 } while (0);
12916
12917}
Rajeev Kumar Sirasanagandla4c068d42019-02-22 21:39:36 +053012918
Neelansh Mittaledafed22014-09-04 18:54:39 +053012919void wlan_hdd_send_svc_nlink_msg(int type, void *data, int len)
12920{
12921 struct sk_buff *skb;
12922 struct nlmsghdr *nlh;
12923 tAniMsgHdr *ani_hdr;
Hanumantha Reddy Pothulacf2c7ea2015-04-27 14:50:47 +053012924 int flags = GFP_KERNEL;
Bhargav shah23c94942015-10-13 12:48:35 +053012925 void *nl_data = NULL;
Neelansh Mittaledafed22014-09-04 18:54:39 +053012926
Hanumantha Reddy Pothulacf2c7ea2015-04-27 14:50:47 +053012927 if (in_interrupt() || irqs_disabled() || in_atomic())
12928 flags = GFP_ATOMIC;
12929
12930 skb = alloc_skb(NLMSG_SPACE(WLAN_NL_MAX_PAYLOAD), flags);
Neelansh Mittaledafed22014-09-04 18:54:39 +053012931
12932 if(skb == NULL) {
12933 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12934 "%s: alloc_skb failed", __func__);
12935 return;
12936 }
12937
12938 nlh = (struct nlmsghdr *)skb->data;
12939 nlh->nlmsg_pid = 0; /* from kernel */
12940 nlh->nlmsg_flags = 0;
12941 nlh->nlmsg_seq = 0;
12942 nlh->nlmsg_type = WLAN_NL_MSG_SVC;
12943
12944 ani_hdr = NLMSG_DATA(nlh);
12945 ani_hdr->type = type;
12946
12947 switch(type) {
12948 case WLAN_SVC_SAP_RESTART_IND:
12949 ani_hdr->length = 0;
12950 nlh->nlmsg_len = NLMSG_LENGTH((sizeof(tAniMsgHdr)));
12951 skb_put(skb, NLMSG_SPACE(sizeof(tAniMsgHdr)));
12952 break;
Bhargav Shahd0715912015-10-01 18:17:37 +053012953 case WLAN_SVC_WLAN_TP_IND:
12954 ani_hdr->length = len;
12955 nlh->nlmsg_len = NLMSG_LENGTH((sizeof(tAniMsgHdr)
12956 + len));
12957 nl_data = (char *)ani_hdr + sizeof(tAniMsgHdr);
12958 memcpy(nl_data, data, len);
12959 skb_put(skb, NLMSG_SPACE(sizeof(tAniMsgHdr) + len));
12960 break;
Bhargav shah23c94942015-10-13 12:48:35 +053012961 case WLAN_MSG_RPS_ENABLE_IND:
12962 ani_hdr->length = len;
12963 nlh->nlmsg_len = NLMSG_LENGTH((sizeof(tAniMsgHdr) + len));
12964 nl_data = (char *)ani_hdr + sizeof(tAniMsgHdr);
12965 memcpy(nl_data, data, len);
12966 skb_put(skb, NLMSG_SPACE(sizeof(tAniMsgHdr) + len));
12967 break;
Neelansh Mittaledafed22014-09-04 18:54:39 +053012968 default:
12969 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12970 "Attempt to send unknown nlink message %d", type);
12971 kfree_skb(skb);
12972 return;
12973 }
12974
12975 nl_srv_bcast(skb);
12976
12977 return;
12978}
12979
Bhargav Shahd0715912015-10-01 18:17:37 +053012980/**
12981 * hdd_request_tcp_delack() - Find the Delack value based on RX packet
12982 * @pHddCtx: Valid Global HDD context pointer
12983 * @rx_packets: Number of RX packet in perticular time
12984 *
12985 * Based on the RX packet this function calculate next value of tcp delack.
12986 * This function compare rx packet value to high and low threshold limit.
12987 *
12988 * Return: void
12989 */
12990void hdd_request_tcp_delack(hdd_context_t *pHddCtx, uint64_t rx_packets)
12991{
12992 /* average of rx_packets and prev_rx is taken so that
12993 bus width doesnot fluctuate much */
12994 uint64_t temp_rx = (rx_packets + pHddCtx->prev_rx)/2;
Alok Kumarf3724462018-04-05 15:18:54 +053012995 enum wlan_tp_level next_rx_level = pHddCtx->cur_rx_level;
Neelansh Mittaledafed22014-09-04 18:54:39 +053012996
Bhargav Shahd0715912015-10-01 18:17:37 +053012997 pHddCtx->prev_rx = rx_packets;
12998 if (temp_rx > pHddCtx->cfg_ini->tcpDelAckThresholdHigh)
Alok Kumarf3724462018-04-05 15:18:54 +053012999 next_rx_level = WLAN_SVC_TP_HIGH;
Bhargav Shahd0715912015-10-01 18:17:37 +053013000 else if (temp_rx <= pHddCtx->cfg_ini->tcpDelAckThresholdLow)
Alok Kumarf3724462018-04-05 15:18:54 +053013001 next_rx_level = WLAN_SVC_TP_LOW;
Bhargav Shahd0715912015-10-01 18:17:37 +053013002
13003 hdd_set_delack_value(pHddCtx, next_rx_level);
13004}
13005
13006#define HDD_BW_GET_DIFF(x, y) ((x) >= (y) ? (x) - (y) : (ULONG_MAX - (y) + (x)))
13007
13008/**
13009 * hdd_tcp_delack_compute_function() - get link status
13010 * @priv: Valid Global HDD context pointer
13011 *
13012 * This function find number of RX packet during timer life span.
13013 * It request tcp delack with number of RX packet and re-configure delack timer
13014 * for tcpDelAckComputeInterval timer interval.
13015 *
13016 * Return: void
13017 */
13018void hdd_tcp_delack_compute_function(void *priv)
13019{
13020 hdd_context_t *pHddCtx = (hdd_context_t *)priv;
13021 hdd_adapter_t *pAdapter = NULL;
13022 v_U32_t rx_packets = 0;
13023 hdd_adapter_list_node_t *pAdapterNode = NULL;
13024 VOS_STATUS status = 0;
13025
13026 for (status = hdd_get_front_adapter(pHddCtx, &pAdapterNode);
13027 NULL != pAdapterNode && VOS_STATUS_SUCCESS == status;
13028 status = hdd_get_next_adapter(pHddCtx, pAdapterNode, &pAdapterNode)) {
13029 if ((pAdapter = pAdapterNode->pAdapter) == NULL)
13030 continue;
13031
13032 rx_packets += HDD_BW_GET_DIFF(pAdapter->stats.rx_packets,
13033 pAdapter->prev_rx_packets);
13034 pAdapter->prev_rx_packets = pAdapter->stats.rx_packets;
13035 }
13036
13037 hdd_request_tcp_delack(pHddCtx, rx_packets);
13038
13039 vos_timer_start(&pHddCtx->delack_timer,
13040 pHddCtx->cfg_ini->tcpDelAckComputeInterval);
13041}
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -070013042
13043/**---------------------------------------------------------------------------
13044
Gopichand Nakkalafce506f2013-07-03 23:55:16 +053013045 \brief hdd_is_5g_supported() - HDD function to know if hardware supports 5GHz
13046
13047 \param - pHddCtx - Pointer to the hdd context
13048
13049 \return - true if hardware supports 5GHz
13050
13051 --------------------------------------------------------------------------*/
Vinay Krishna Erannafacf5e22014-02-24 13:16:25 +053013052boolean hdd_is_5g_supported(hdd_context_t * pHddCtx)
Gopichand Nakkalafce506f2013-07-03 23:55:16 +053013053{
13054 /* If wcnss_wlan_iris_xo_mode() returns WCNSS_XO_48MHZ(1);
13055 * then hardware support 5Ghz.
13056 */
13057 if (WCNSS_XO_48MHZ == wcnss_wlan_iris_xo_mode())
13058 {
Ratheesh S P36dbc932015-08-07 14:28:57 +053013059 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Hardware supports 5Ghz", __func__);
Gopichand Nakkalafce506f2013-07-03 23:55:16 +053013060 return true;
13061 }
13062 else
13063 {
Ratheesh S P36dbc932015-08-07 14:28:57 +053013064 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Hardware doesn't supports 5Ghz",
Gopichand Nakkalafce506f2013-07-03 23:55:16 +053013065 __func__);
13066 return false;
13067 }
13068}
13069
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +053013070/**---------------------------------------------------------------------------
13071
13072 \brief hdd_generate_iface_mac_addr_auto() - HDD Mac Interface Auto
13073 generate function
13074
13075 This is generate the random mac address for WLAN interface
13076
13077 \param - pHddCtx - Pointer to HDD context
13078 idx - Start interface index to get auto
13079 generated mac addr.
13080 mac_addr - Mac address
13081
13082 \return - 0 for success, < 0 for failure
13083
13084 --------------------------------------------------------------------------*/
13085
13086static int hdd_generate_iface_mac_addr_auto(hdd_context_t *pHddCtx,
13087 int idx, v_MACADDR_t mac_addr)
13088{
13089 int i;
13090 unsigned int serialno;
13091 serialno = wcnss_get_serial_number();
13092
13093 if (0 != serialno)
13094 {
13095 /* MAC address has 3 bytes of OUI so we have a maximum of 3
13096 bytes of the serial number that can be used to generate
13097 the other 3 bytes of the MAC address. Mask off all but
13098 the lower 3 bytes (this will also make sure we don't
13099 overflow in the next step) */
13100 serialno &= 0x00FFFFFF;
13101
13102 /* we need a unique address for each session */
13103 serialno *= VOS_MAX_CONCURRENCY_PERSONA;
13104
13105 /* autogen other Mac addresses */
13106 for (i = idx; i < VOS_MAX_CONCURRENCY_PERSONA; i++)
13107 {
13108 /* start with the entire default address */
13109 pHddCtx->cfg_ini->intfMacAddr[i] = mac_addr;
13110 /* then replace the lower 3 bytes */
13111 pHddCtx->cfg_ini->intfMacAddr[i].bytes[3] = (serialno >> 16) & 0xFF;
13112 pHddCtx->cfg_ini->intfMacAddr[i].bytes[4] = (serialno >> 8) & 0xFF;
13113 pHddCtx->cfg_ini->intfMacAddr[i].bytes[5] = serialno & 0xFF;
13114
Nachiket Kukadede2e24f2017-09-25 16:24:27 +053013115 if (0 == memcmp(&pHddCtx->cfg_ini->intfMacAddr[i].bytes[0],
13116 &mac_addr.bytes[0], VOS_MAC_ADDR_SIZE))
13117 pHddCtx->cfg_ini->intfMacAddr[i].bytes[5] +=
13118 VOS_MAX_CONCURRENCY_PERSONA;
13119
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +053013120 serialno++;
13121 hddLog(VOS_TRACE_LEVEL_ERROR,
13122 "%s: Derived Mac Addr: "
13123 MAC_ADDRESS_STR, __func__,
13124 MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[i].bytes));
13125 }
13126
13127 }
13128 else
13129 {
13130 hddLog(LOGE, FL("Failed to Get Serial NO"));
13131 return -1;
13132 }
13133 return 0;
13134}
Gopichand Nakkalafce506f2013-07-03 23:55:16 +053013135
Katya Nigame7b69a82015-04-28 15:24:06 +053013136int wlan_hdd_mon_open(hdd_context_t *pHddCtx)
13137{
13138 VOS_STATUS status;
13139 v_CONTEXT_t pVosContext= NULL;
13140 hdd_adapter_t *pAdapter= NULL;
13141
13142 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
13143
13144 if (NULL == pVosContext)
13145 {
13146 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13147 "%s: Trying to open VOSS without a PreOpen", __func__);
13148 VOS_ASSERT(0);
13149 return VOS_STATUS_E_FAILURE;
13150 }
13151
13152 status = vos_nv_open();
13153 if (!VOS_IS_STATUS_SUCCESS(status))
13154 {
13155 /* NV module cannot be initialized */
13156 hddLog( VOS_TRACE_LEVEL_FATAL,
13157 "%s: vos_nv_open failed", __func__);
13158 return VOS_STATUS_E_FAILURE;
13159 }
13160
13161 status = vos_init_wiphy_from_nv_bin();
13162 if (!VOS_IS_STATUS_SUCCESS(status))
13163 {
13164 /* NV module cannot be initialized */
13165 hddLog( VOS_TRACE_LEVEL_FATAL,
13166 "%s: vos_init_wiphy failed", __func__);
13167 goto err_vos_nv_close;
13168 }
13169
13170 status = vos_open( &pVosContext, pHddCtx->parent_dev);
13171 if ( !VOS_IS_STATUS_SUCCESS( status ))
13172 {
13173 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: vos_open failed", __func__);
13174 goto err_vos_nv_close;
13175 }
13176
13177 status = vos_mon_start( pVosContext );
13178 if ( !VOS_IS_STATUS_SUCCESS( status ) )
13179 {
13180 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: vos_start failed",__func__);
13181 goto err_vosclose;
13182 }
13183
13184 WLANTL_SetMonRxCbk( pVosContext, hdd_rx_packet_monitor_cbk );
Rajeev Kumar Sirasanagandla4c068d42019-02-22 21:39:36 +053013185 sme_featureCapsExchange(NULL);
Katya Nigame7b69a82015-04-28 15:24:06 +053013186 wcnss_wlan_set_drvdata(pHddCtx->parent_dev, pHddCtx);
13187
13188 pAdapter = hdd_open_adapter( pHddCtx, WLAN_HDD_MONITOR, "wlan%d",
13189 wlan_hdd_get_intf_addr(pHddCtx), FALSE );
13190 if( pAdapter == NULL )
13191 {
13192 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: hdd_open_adapter failed", __func__);
13193 goto err_close_adapter;
13194 }
13195
13196 //Initialize the nlink service
13197 if(nl_srv_init() != 0)
13198 {
13199 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: nl_srv_init failed", __func__);
13200 goto err_close_adapter;
13201 }
13202 return VOS_STATUS_SUCCESS;
13203
13204err_close_adapter:
13205 hdd_close_all_adapters( pHddCtx );
13206 vos_mon_stop( pVosContext );
13207err_vosclose:
13208 status = vos_sched_close( pVosContext );
13209 if (!VOS_IS_STATUS_SUCCESS(status)) {
13210 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
13211 "%s: Failed to close VOSS Scheduler", __func__);
13212 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( status ) );
13213 }
13214 vos_close(pVosContext );
13215
13216err_vos_nv_close:
13217 vos_nv_close();
13218
13219return status;
13220}
Gopichand Nakkalafce506f2013-07-03 23:55:16 +053013221/**---------------------------------------------------------------------------
13222
Mihir Shetefc7ff5b2014-01-27 11:30:05 +053013223 \brief hdd_11d_scan_done - callback to be executed when 11d scan is
13224 completed to flush out the scan results
13225
13226 11d scan is done during driver load and is a passive scan on all
13227 channels supported by the device, 11d scans may find some APs on
13228 frequencies which are forbidden to be used in the regulatory domain
13229 the device is operating in. If these APs are notified to the supplicant
13230 it may try to connect to these APs, thus flush out all the scan results
13231 which are present in SME after 11d scan is done.
13232
13233 \return - eHalStatus
13234
13235 --------------------------------------------------------------------------*/
13236static eHalStatus hdd_11d_scan_done(tHalHandle halHandle, void *pContext,
13237 tANI_U32 scanId, eCsrScanStatus status)
13238{
13239 ENTER();
13240
13241 sme_ScanFlushResult(halHandle, 0);
13242
13243 EXIT();
13244
13245 return eHAL_STATUS_SUCCESS;
13246}
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053013247/**---------------------------------------------------------------------------
13248
13249 \brief hdd_init_frame_logging_done - callback to be executed when mgmt frame
13250 logging is completed successfully.
13251
13252 \return - None
13253
13254 --------------------------------------------------------------------------*/
c_manjeecfd1efb2015-09-25 19:32:34 +053013255void hdd_init_frame_logging_done(void *fwlogInitCbContext, tAniLoggingInitRsp *pRsp)
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053013256{
Siddharth Bhald1be97f2015-05-27 22:39:59 +053013257 hdd_context_t* pHddCtx = (hdd_context_t*)fwlogInitCbContext;
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053013258
13259 if (NULL == pHddCtx)
13260 {
13261 hddLog(VOS_TRACE_LEVEL_ERROR,
13262 "%s: HDD context is NULL",__func__);
13263 return;
13264 }
13265
c_manjeecfd1efb2015-09-25 19:32:34 +053013266 if ((pRsp->status == VOS_STATUS_SUCCESS) &&
Mahesh A Saptasagarfabb1a02015-06-29 12:17:04 +053013267 (TRUE == pHddCtx->cfg_ini->enableMgmtLogging))
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053013268 {
13269 hddLog(VOS_TRACE_LEVEL_INFO, FL("Mgmt Frame Logging init successful"));
13270 pHddCtx->mgmt_frame_logging = TRUE;
13271 }
13272 else
13273 {
13274 hddLog(VOS_TRACE_LEVEL_INFO, FL("Mgmt Frame Logging init not success"));
13275 pHddCtx->mgmt_frame_logging = FALSE;
c_manjeecfd1efb2015-09-25 19:32:34 +053013276 return;
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053013277 }
13278
c_manjeecfd1efb2015-09-25 19:32:34 +053013279 /*Check feature supported by FW*/
13280 if(TRUE == sme_IsFeatureSupportedByFW(MEMORY_DUMP_SUPPORTED))
13281 {
13282 //Store fwr mem dump size given by firmware.
13283 wlan_store_fwr_mem_dump_size(pRsp->fw_mem_dump_max_size);
13284 }
13285 else
13286 {
13287 wlan_store_fwr_mem_dump_size(0);
13288 }
13289
13290
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053013291}
13292/**---------------------------------------------------------------------------
13293
13294 \brief hdd_init_frame_logging - function to initialize frame logging.
13295 Currently only Mgmt Frames are logged in both TX
13296 and Rx direction and are sent to userspace
13297 application using logger thread when queried.
13298
13299 \return - None
13300
13301 --------------------------------------------------------------------------*/
Siddharth Bhald1be97f2015-05-27 22:39:59 +053013302void hdd_init_frame_logging(hdd_context_t* pHddCtx)
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053013303{
13304 eHalStatus halStatus = eHAL_STATUS_FAILURE;
Sreelakshmi Konamkid8784d92016-04-14 14:59:13 +053013305 tSirFWLoggingInitParam wlanFWLoggingInitParam = {0};
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053013306
Siddharth Bhald1be97f2015-05-27 22:39:59 +053013307 if (TRUE != sme_IsFeatureSupportedByFW(MGMT_FRAME_LOGGING) &&
13308 TRUE != sme_IsFeatureSupportedByFW(LOGGING_ENHANCEMENT))
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053013309 {
13310 hddLog(VOS_TRACE_LEVEL_INFO, FL("MGMT_FRAME_LOGGING not supp by FW"));
13311 return;
13312 }
13313
sheenam monga1a0202d2020-01-03 15:20:57 +053013314 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Configuring %s %s %s Logging",__func__,
Siddharth Bhald1be97f2015-05-27 22:39:59 +053013315 pHddCtx->cfg_ini->enableFWLogging?"FW Log,":"",
13316 pHddCtx->cfg_ini->enableContFWLogging ? "Cont FW log,":"",
sheenam monga1a0202d2020-01-03 15:20:57 +053013317 pHddCtx->cfg_ini->enableMgmtLogging ? "Mgmt Pkt Log":"");
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053013318
Siddharth Bhald1be97f2015-05-27 22:39:59 +053013319 if (pHddCtx->cfg_ini->enableFWLogging ||
13320 pHddCtx->cfg_ini->enableContFWLogging)
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053013321 {
Sreelakshmi Konamkid8784d92016-04-14 14:59:13 +053013322 wlanFWLoggingInitParam.enableFlag |= WLAN_QXDM_LOG_EN;
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053013323 }
13324
Sushant Kaushik46804902015-07-08 14:46:03 +053013325 if (pHddCtx->cfg_ini->enableMgmtLogging)
13326 {
Sreelakshmi Konamkid8784d92016-04-14 14:59:13 +053013327 wlanFWLoggingInitParam.enableFlag |= WLAN_FRAME_LOG_EN;
Sushant Kaushik46804902015-07-08 14:46:03 +053013328 }
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053013329 if (pHddCtx->cfg_ini->enableBMUHWtracing)
13330 {
Sreelakshmi Konamkid8784d92016-04-14 14:59:13 +053013331 wlanFWLoggingInitParam.enableFlag |= WLAN_BMUHW_TRACE_LOG_EN;
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053013332 }
Sreelakshmi Konamkid8784d92016-04-14 14:59:13 +053013333 if( wlanFWLoggingInitParam.enableFlag == 0 )
c_manjeecfd1efb2015-09-25 19:32:34 +053013334 {
13335 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Logging not enabled", __func__);
13336 return;
13337 }
Sreelakshmi Konamkid8784d92016-04-14 14:59:13 +053013338 wlanFWLoggingInitParam.frameType = WLAN_FRAME_LOGGING_FRAMETYPE_MGMT;
13339 wlanFWLoggingInitParam.frameSize = WLAN_MGMT_LOGGING_FRAMESIZE_128BYTES;
13340 wlanFWLoggingInitParam.bufferMode = WLAN_FRAME_LOGGING_BUFFERMODE_CIRCULAR;
13341 wlanFWLoggingInitParam.continuousFrameLogging =
Siddharth Bhald1be97f2015-05-27 22:39:59 +053013342 pHddCtx->cfg_ini->enableContFWLogging;
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053013343
Sreelakshmi Konamkid8784d92016-04-14 14:59:13 +053013344 wlanFWLoggingInitParam.enableFlag &= ~WLAN_DPU_TXP_LOG_EN;
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053013345
Sreelakshmi Konamkid8784d92016-04-14 14:59:13 +053013346 wlanFWLoggingInitParam.minLogBufferSize =
Siddharth Bhald1be97f2015-05-27 22:39:59 +053013347 pHddCtx->cfg_ini->minLoggingBufferSize;
Sreelakshmi Konamkid8784d92016-04-14 14:59:13 +053013348 wlanFWLoggingInitParam.maxLogBufferSize =
Siddharth Bhald1be97f2015-05-27 22:39:59 +053013349 pHddCtx->cfg_ini->maxLoggingBufferSize;
Sreelakshmi Konamkid8784d92016-04-14 14:59:13 +053013350 wlanFWLoggingInitParam.fwlogInitCallback = hdd_init_frame_logging_done;
13351 wlanFWLoggingInitParam.fwlogInitCbContext= pHddCtx;
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053013352
Sreelakshmi Konamkid8784d92016-04-14 14:59:13 +053013353 halStatus = sme_InitMgmtFrameLogging(pHddCtx->hHal, &wlanFWLoggingInitParam);
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053013354
13355 if (eHAL_STATUS_SUCCESS != halStatus)
13356 {
Sreelakshmi Konamkid8784d92016-04-14 14:59:13 +053013357 hddLog(LOGE, FL("sme_InitMgmtFrameLogging failed, returned %d"),
13358 halStatus);
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053013359 }
13360
13361 return;
13362}
Mihir Shetefc7ff5b2014-01-27 11:30:05 +053013363
Bhargav shah23c94942015-10-13 12:48:35 +053013364static void hdd_dp_util_send_rps_ind(hdd_context_t *hdd_ctxt)
13365{
13366 hdd_adapter_t *adapter;
13367 hdd_adapter_list_node_t *adapter_node, *next;
13368 VOS_STATUS status = VOS_STATUS_SUCCESS;
13369 struct wlan_rps_data rps_data;
13370 int count;
13371
13372 if(!hdd_ctxt->cfg_ini->rps_mask)
13373 {
13374 return;
13375 }
13376
13377 for (count=0; count < WLAN_SVC_IFACE_NUM_QUEUES; count++)
13378 {
13379 rps_data.cpu_map[count] = hdd_ctxt->cfg_ini->rps_mask;
13380 }
13381
13382 rps_data.num_queues = WLAN_SVC_IFACE_NUM_QUEUES;
13383
13384 hddLog(LOG1, FL("0x%x 0x%x 0x%x 0x%x 0x%x 0x%x"),
13385 rps_data.cpu_map[0], rps_data.cpu_map[1],rps_data.cpu_map[2],
13386 rps_data.cpu_map[3], rps_data.cpu_map[4], rps_data.cpu_map[5]);
13387
13388 status = hdd_get_front_adapter (hdd_ctxt, &adapter_node);
13389
13390 while (NULL != adapter_node && VOS_STATUS_SUCCESS == status)
13391 {
13392 adapter = adapter_node->pAdapter;
13393 if (NULL != adapter) {
13394 strlcpy(rps_data.ifname, adapter->dev->name,
13395 sizeof(rps_data.ifname));
13396 wlan_hdd_send_svc_nlink_msg(WLAN_MSG_RPS_ENABLE_IND,
13397 (void *)&rps_data,sizeof(rps_data));
13398 }
13399 status = hdd_get_next_adapter (hdd_ctxt, adapter_node, &next);
13400 adapter_node = next;
13401 }
13402}
13403
Masti, Narayanraddi26378462016-01-05 18:20:28 +053013404void wlan_hdd_schedule_defer_scan(struct work_struct *work)
13405{
13406 scan_context_t *scan_ctx =
13407 container_of(work, scan_context_t, scan_work.work);
13408
13409 if (NULL == scan_ctx)
13410 {
13411 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13412 FL("scan_ctx is NULL"));
13413 return;
13414 }
13415
13416 if (unlikely(TDLS_CTX_MAGIC != scan_ctx->magic))
13417 return;
13418
13419 scan_ctx->attempt++;
13420
13421 wlan_hdd_cfg80211_scan(scan_ctx->wiphy,
13422#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
13423 scan_ctx->dev,
13424#endif
13425 scan_ctx->scan_request);
13426}
13427
13428int wlan_hdd_copy_defer_scan_context(hdd_context_t *pHddCtx,
13429 struct wiphy *wiphy,
13430#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
13431 struct net_device *dev,
13432#endif
13433 struct cfg80211_scan_request *request)
13434{
13435 scan_context_t *scan_ctx;
13436
13437 ENTER();
13438 if (0 != (wlan_hdd_validate_context(pHddCtx)))
13439 {
13440 return -1;
13441 }
13442
13443 scan_ctx = &pHddCtx->scan_ctxt;
13444
13445 scan_ctx->wiphy = wiphy;
13446#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
13447 scan_ctx->dev = dev;
13448#endif
13449
13450 scan_ctx->scan_request = request;
13451
13452 EXIT();
13453 return 0;
13454}
13455
13456void wlan_hdd_defer_scan_init_work(hdd_context_t *pHddCtx,
13457 struct wiphy *wiphy,
13458#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
13459 struct net_device *dev,
13460#endif
13461 struct cfg80211_scan_request *request,
13462 unsigned long delay)
13463{
13464 if (TDLS_CTX_MAGIC != pHddCtx->scan_ctxt.magic)
13465 {
13466#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
13467 wlan_hdd_copy_defer_scan_context(pHddCtx, wiphy, dev, request);
13468#else
13469 wlan_hdd_copy_defer_scan_context(pHddCtx, wiphy, request);
13470#endif
13471 pHddCtx->scan_ctxt.attempt = 0;
13472 pHddCtx->scan_ctxt.magic = TDLS_CTX_MAGIC;
13473 }
13474 schedule_delayed_work(&pHddCtx->scan_ctxt.scan_work, delay);
13475}
13476
13477void wlan_hdd_init_deinit_defer_scan_context(scan_context_t *scan_ctx)
13478{
13479 scan_ctx->magic = 0;
13480 scan_ctx->attempt = 0;
13481 scan_ctx->reject = 0;
13482 scan_ctx->scan_request = NULL;
13483
13484 return;
13485}
13486
Mihir Shetefc7ff5b2014-01-27 11:30:05 +053013487/**---------------------------------------------------------------------------
13488
Jeff Johnson295189b2012-06-20 16:38:30 -070013489 \brief hdd_wlan_startup() - HDD init function
13490
13491 This is the driver startup code executed once a WLAN device has been detected
13492
13493 \param - dev - Pointer to the underlying device
13494
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -080013495 \return - 0 for success, < 0 for failure
Jeff Johnson295189b2012-06-20 16:38:30 -070013496
13497 --------------------------------------------------------------------------*/
13498
13499int hdd_wlan_startup(struct device *dev )
13500{
13501 VOS_STATUS status;
13502 hdd_adapter_t *pAdapter = NULL;
Jeff Johnsone7245742012-09-05 17:12:55 -070013503 hdd_adapter_t *pP2pAdapter = NULL;
Arunk Khandavalli95608be2019-01-22 13:12:54 +053013504 hdd_adapter_t *softapAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070013505 hdd_context_t *pHddCtx = NULL;
13506 v_CONTEXT_t pVosContext= NULL;
13507#ifdef WLAN_BTAMP_FEATURE
13508 VOS_STATUS vStatus = VOS_STATUS_SUCCESS;
13509 WLANBAP_ConfigType btAmpConfig;
13510 hdd_config_t *pConfig;
13511#endif
13512 int ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070013513 struct wiphy *wiphy;
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +053013514 v_MACADDR_t mac_addr;
Jeff Johnson295189b2012-06-20 16:38:30 -070013515
13516 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -070013517 /*
13518 * cfg80211: wiphy allocation
13519 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +053013520 wiphy = wlan_hdd_cfg80211_wiphy_alloc(sizeof(hdd_context_t)) ;
Jeff Johnson295189b2012-06-20 16:38:30 -070013521
13522 if(wiphy == NULL)
13523 {
13524 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: cfg80211 init failed", __func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -080013525 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -070013526 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013527 pHddCtx = wiphy_priv(wiphy);
13528
Jeff Johnson295189b2012-06-20 16:38:30 -070013529 //Initialize the adapter context to zeros.
13530 vos_mem_zero(pHddCtx, sizeof( hdd_context_t ));
13531
Jeff Johnson295189b2012-06-20 16:38:30 -070013532 pHddCtx->wiphy = wiphy;
Sushant Kaushik83392fa2015-05-05 17:44:40 +053013533 hdd_prevent_suspend(WIFI_POWER_EVENT_WAKELOCK_DRIVER_INIT);
Mihir Shete18156292014-03-11 15:38:30 +053013534 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_LOAD_IN_PROGRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -070013535
13536 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, TRUE);
13537
Siddharth Bhalcd92b782015-06-29 12:25:40 +053013538 /* register for riva power on lock to platform driver
13539 * Locking power early to ensure FW doesn't reset by kernel while
13540 * host driver is busy initializing itself */
13541 if (req_riva_power_on_lock("wlan"))
13542 {
13543 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: req riva power on lock failed",
13544 __func__);
13545 goto err_free_hdd_context;
13546 }
13547
Jeff Johnson295189b2012-06-20 16:38:30 -070013548 /*Get vos context here bcoz vos_open requires it*/
13549 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
13550
Madan Mohan Koyyalamudi0b78e152012-11-28 15:46:51 -080013551 if(pVosContext == NULL)
13552 {
13553 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Failed vos_get_global_context",__func__);
13554 goto err_free_hdd_context;
13555 }
13556
Jeff Johnson295189b2012-06-20 16:38:30 -070013557 //Save the Global VOSS context in adapter context for future.
13558 pHddCtx->pvosContext = pVosContext;
13559
13560 //Save the adapter context in global context for future.
13561 ((VosContextType*)(pVosContext))->pHDDContext = (v_VOID_t*)pHddCtx;
13562
Jeff Johnson295189b2012-06-20 16:38:30 -070013563 pHddCtx->parent_dev = dev;
Sreelakshmi Konamkif0646d52016-12-09 12:35:31 +053013564 pHddCtx->last_scan_reject_session_id = 0xFF;
13565 pHddCtx->last_scan_reject_reason = 0;
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053013566 pHddCtx->last_scan_reject_timestamp = 0;
Abhishek Singhe4b12562017-06-20 16:53:39 +053013567 pHddCtx->scan_reject_cnt = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070013568
13569 init_completion(&pHddCtx->full_pwr_comp_var);
13570 init_completion(&pHddCtx->standby_comp_var);
13571 init_completion(&pHddCtx->req_bmps_comp_var);
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070013572 init_completion(&pHddCtx->scan_info.scan_req_completion_event);
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -080013573 init_completion(&pHddCtx->scan_info.abortscan_event_var);
Kiet Lam46b8e4e2013-11-06 21:49:53 +053013574 init_completion(&pHddCtx->wiphy_channel_update_event);
Arun Kumar Khandavallie0b046d2014-03-01 21:54:25 +053013575 init_completion(&pHddCtx->ssr_comp_var);
Mahesh A Saptasagar67ab9222015-10-21 15:38:41 +053013576 init_completion(&pHddCtx->mc_sus_event_var);
13577 init_completion(&pHddCtx->tx_sus_event_var);
13578 init_completion(&pHddCtx->rx_sus_event_var);
13579
Amar Singhala49cbc52013-10-08 18:37:44 -070013580
mukul sharma4bd8d2e2015-08-13 20:33:25 +053013581 hdd_init_ll_stats_ctx(pHddCtx);
Anurag Chouhan6ee81542017-02-09 18:09:27 +053013582 hdd_init_nud_stats_ctx(pHddCtx);
mukul sharma4bd8d2e2015-08-13 20:33:25 +053013583
Amar Singhala49cbc52013-10-08 18:37:44 -070013584#ifdef CONFIG_ENABLE_LINUX_REG
Amar Singhalfddc28c2013-09-05 13:03:40 -070013585 init_completion(&pHddCtx->linux_reg_req);
Amar Singhala49cbc52013-10-08 18:37:44 -070013586#else
13587 init_completion(&pHddCtx->driver_crda_req);
13588#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070013589
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +053013590#ifdef WLAN_FEATURE_EXTSCAN
13591 init_completion(&pHddCtx->ext_scan_context.response_event);
13592#endif /* WLAN_FEATURE_EXTSCAN */
13593
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053013594 spin_lock_init(&pHddCtx->schedScan_lock);
Kapil Gupta137ef892016-12-13 19:38:00 +053013595 vos_spin_lock_init(&pHddCtx->sap_update_info_lock);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053013596
Jeff Johnson295189b2012-06-20 16:38:30 -070013597 hdd_list_init( &pHddCtx->hddAdapters, MAX_NUMBER_OF_ADAPTERS );
13598
Padma, Santhosh Kumar9cd38332015-11-17 12:18:10 +053013599 vos_init_delayed_work(&pHddCtx->spoof_mac_addr_work,
13600 hdd_processSpoofMacAddrRequest);
Kapil Gupta137ef892016-12-13 19:38:00 +053013601 vos_init_work(&pHddCtx->sap_start_work, hdd_sap_restart_handle);
Abhishek Singh78c691f2017-11-30 13:48:44 +053013602 vos_init_delayed_work(&pHddCtx->ecsa_chan_change_work,
13603 hdd_force_scc_with_ecsa_handle);
Padma, Santhosh Kumar9cd38332015-11-17 12:18:10 +053013604
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053013605#ifdef FEATURE_WLAN_TDLS
13606 /* tdls_lock is initialized before an hdd_open_adapter ( which is
13607 * invoked by other instances also) to protect the concurrent
13608 * access for the Adapters by TDLS module.
13609 */
13610 mutex_init(&pHddCtx->tdls_lock);
13611#endif
Siddharth Bhal76972212014-10-15 16:22:51 +053013612 mutex_init(&pHddCtx->spoofMacAddr.macSpoofingLock);
Mukul Sharma1fd6efd2015-02-14 00:29:14 +053013613 mutex_init(&pHddCtx->wmmLock);
13614
Srinivas Girigowda8bf64cb2015-09-30 19:50:09 +053013615 hdd_init_offloaded_packets_ctx(pHddCtx);
Agarwal Ashish1f422872014-07-22 00:11:55 +053013616 /* By default Strict Regulatory For FCC should be false */
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053013617
Agarwal Ashish1f422872014-07-22 00:11:55 +053013618 pHddCtx->nEnableStrictRegulatoryForFCC = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070013619 // Load all config first as TL config is needed during vos_open
13620 pHddCtx->cfg_ini = (hdd_config_t*) kmalloc(sizeof(hdd_config_t), GFP_KERNEL);
13621 if(pHddCtx->cfg_ini == NULL)
13622 {
13623 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Failed kmalloc hdd_config_t",__func__);
13624 goto err_free_hdd_context;
13625 }
13626
Hanumanth Reddy Pothula1efcd162018-03-14 14:32:27 +053013627 hdd_request_manager_init();
13628
Jeff Johnson295189b2012-06-20 16:38:30 -070013629 vos_mem_zero(pHddCtx->cfg_ini, sizeof( hdd_config_t ));
13630
13631 // Read and parse the qcom_cfg.ini file
13632 status = hdd_parse_config_ini( pHddCtx );
13633 if ( VOS_STATUS_SUCCESS != status )
13634 {
13635 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: error parsing %s",
13636 __func__, WLAN_INI_FILE);
13637 goto err_config;
13638 }
Arif Hussaind5218912013-12-05 01:10:55 -080013639#ifdef MEMORY_DEBUG
13640 if (pHddCtx->cfg_ini->IsMemoryDebugSupportEnabled)
13641 vos_mem_init();
13642
13643 hddLog(VOS_TRACE_LEVEL_INFO, "%s: gEnableMemoryDebug=%d",
13644 __func__, pHddCtx->cfg_ini->IsMemoryDebugSupportEnabled);
13645#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070013646
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +053013647 /* INI has been read, initialise the configuredMcastBcastFilter with
13648 * INI value as this will serve as the default value
13649 */
13650 pHddCtx->configuredMcastBcastFilter = pHddCtx->cfg_ini->mcastBcastFilterSetting;
13651 hddLog(VOS_TRACE_LEVEL_INFO, "Setting configuredMcastBcastFilter: %d",
13652 pHddCtx->cfg_ini->mcastBcastFilterSetting);
Gopichand Nakkalafce506f2013-07-03 23:55:16 +053013653
13654 if (false == hdd_is_5g_supported(pHddCtx))
13655 {
13656 //5Ghz is not supported.
13657 if (1 != pHddCtx->cfg_ini->nBandCapability)
13658 {
13659 hddLog(VOS_TRACE_LEVEL_INFO,
13660 "%s: Setting pHddCtx->cfg_ini->nBandCapability = 1", __func__);
13661 pHddCtx->cfg_ini->nBandCapability = 1;
13662 }
13663 }
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053013664
13665 /* If SNR Monitoring is enabled, FW has to parse all beacons
13666 * for calcaluting and storing the average SNR, so set Nth beacon
13667 * filter to 1 to enable FW to parse all the beaocons
13668 */
13669 if (1 == pHddCtx->cfg_ini->fEnableSNRMonitoring)
13670 {
13671 /* The log level is deliberately set to WARN as overriding
13672 * nthBeaconFilter to 1 will increase power cosumption and this
13673 * might just prove helpful to detect the power issue.
13674 */
13675 hddLog(VOS_TRACE_LEVEL_WARN,
13676 "%s: Setting pHddCtx->cfg_ini->nthBeaconFilter = 1", __func__);
13677 pHddCtx->cfg_ini->nthBeaconFilter = 1;
13678 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013679 /*
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +053013680 * cfg80211: Initialization ...
Jeff Johnson295189b2012-06-20 16:38:30 -070013681 */
Manjeet Singh61016fa2016-12-02 11:10:19 +053013682 if (0 < wlan_hdd_cfg80211_init(dev, wiphy, pHddCtx->cfg_ini))
Jeff Johnson295189b2012-06-20 16:38:30 -070013683 {
Manjeet Singh61016fa2016-12-02 11:10:19 +053013684 hddLog(VOS_TRACE_LEVEL_FATAL,
13685 "%s: wlan_hdd_cfg80211_init return failure", __func__);
13686 goto err_config;
Jeff Johnson295189b2012-06-20 16:38:30 -070013687 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013688
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -080013689 // Update VOS trace levels based upon the cfg.ini
13690 hdd_vos_trace_enable(VOS_MODULE_ID_BAP,
13691 pHddCtx->cfg_ini->vosTraceEnableBAP);
13692 hdd_vos_trace_enable(VOS_MODULE_ID_TL,
13693 pHddCtx->cfg_ini->vosTraceEnableTL);
13694 hdd_vos_trace_enable(VOS_MODULE_ID_WDI,
13695 pHddCtx->cfg_ini->vosTraceEnableWDI);
13696 hdd_vos_trace_enable(VOS_MODULE_ID_HDD,
13697 pHddCtx->cfg_ini->vosTraceEnableHDD);
13698 hdd_vos_trace_enable(VOS_MODULE_ID_SME,
13699 pHddCtx->cfg_ini->vosTraceEnableSME);
13700 hdd_vos_trace_enable(VOS_MODULE_ID_PE,
13701 pHddCtx->cfg_ini->vosTraceEnablePE);
Katya Nigam70d68332013-09-16 16:49:45 +053013702 hdd_vos_trace_enable(VOS_MODULE_ID_PMC,
13703 pHddCtx->cfg_ini->vosTraceEnablePMC);
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -080013704 hdd_vos_trace_enable(VOS_MODULE_ID_WDA,
13705 pHddCtx->cfg_ini->vosTraceEnableWDA);
13706 hdd_vos_trace_enable(VOS_MODULE_ID_SYS,
13707 pHddCtx->cfg_ini->vosTraceEnableSYS);
13708 hdd_vos_trace_enable(VOS_MODULE_ID_VOSS,
13709 pHddCtx->cfg_ini->vosTraceEnableVOSS);
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -080013710 hdd_vos_trace_enable(VOS_MODULE_ID_SAP,
13711 pHddCtx->cfg_ini->vosTraceEnableSAP);
13712 hdd_vos_trace_enable(VOS_MODULE_ID_HDD_SOFTAP,
13713 pHddCtx->cfg_ini->vosTraceEnableHDDSAP);
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -080013714
Jeff Johnson295189b2012-06-20 16:38:30 -070013715 // Update WDI trace levels based upon the cfg.ini
13716 hdd_wdi_trace_enable(eWLAN_MODULE_DAL,
13717 pHddCtx->cfg_ini->wdiTraceEnableDAL);
13718 hdd_wdi_trace_enable(eWLAN_MODULE_DAL_CTRL,
13719 pHddCtx->cfg_ini->wdiTraceEnableCTL);
13720 hdd_wdi_trace_enable(eWLAN_MODULE_DAL_DATA,
13721 pHddCtx->cfg_ini->wdiTraceEnableDAT);
13722 hdd_wdi_trace_enable(eWLAN_MODULE_PAL,
13723 pHddCtx->cfg_ini->wdiTraceEnablePAL);
Jeff Johnson295189b2012-06-20 16:38:30 -070013724
Jeff Johnson88ba7742013-02-27 14:36:02 -080013725 if (VOS_FTM_MODE == hdd_get_conparam())
13726 {
Jeff Johnson295189b2012-06-20 16:38:30 -070013727 if ( VOS_STATUS_SUCCESS != wlan_hdd_ftm_open(pHddCtx) )
13728 {
13729 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: wlan_hdd_ftm_open Failed",__func__);
13730 goto err_free_hdd_context;
13731 }
13732 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: FTM driver loaded success fully",__func__);
Sachin Ahuja38ef5e02015-03-13 17:31:16 +053013733 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_NO_LOAD_UNLOAD_IN_PROGRESS;
c_hpothu2de0ef62014-04-15 16:16:15 +053013734 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, FALSE);
Jeff Johnson295189b2012-06-20 16:38:30 -070013735 return VOS_STATUS_SUCCESS;
Jeff Johnson88ba7742013-02-27 14:36:02 -080013736 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013737
Katya Nigame7b69a82015-04-28 15:24:06 +053013738 if( VOS_MONITOR_MODE == hdd_get_conparam())
13739 {
13740 if ( VOS_STATUS_SUCCESS != wlan_hdd_mon_open(pHddCtx))
13741 {
13742 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: wlan_hdd_mon_open Failed",__func__);
13743 goto err_free_hdd_context;
13744 }
13745 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Driver loaded in Monitor Mode",__func__);
13746 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_NO_LOAD_UNLOAD_IN_PROGRESS;
13747 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, FALSE);
13748 return VOS_STATUS_SUCCESS;
13749 }
13750
Jeff Johnson88ba7742013-02-27 14:36:02 -080013751 //Open watchdog module
Jeff Johnson295189b2012-06-20 16:38:30 -070013752 if(pHddCtx->cfg_ini->fIsLogpEnabled)
13753 {
13754 status = vos_watchdog_open(pVosContext,
13755 &((VosContextType*)pVosContext)->vosWatchdog, sizeof(VosWatchdogContext));
13756
13757 if(!VOS_IS_STATUS_SUCCESS( status ))
13758 {
13759 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: vos_watchdog_open failed",__func__);
Ashish Kumar Dhanotiya532bdef2017-05-09 17:31:59 +053013760 goto err_config;
Jeff Johnson295189b2012-06-20 16:38:30 -070013761 }
13762 }
13763
13764 pHddCtx->isLogpInProgress = FALSE;
13765 vos_set_logp_in_progress(VOS_MODULE_ID_VOSS, FALSE);
13766
Amar Singhala49cbc52013-10-08 18:37:44 -070013767#ifdef CONFIG_ENABLE_LINUX_REG
Amar Singhal0a402232013-10-11 20:57:16 -070013768 /* initialize the NV module. This is required so that
13769 we can initialize the channel information in wiphy
13770 from the NV.bin data. The channel information in
13771 wiphy needs to be initialized before wiphy registration */
13772
13773 status = vos_nv_open();
13774 if (!VOS_IS_STATUS_SUCCESS(status))
13775 {
13776 /* NV module cannot be initialized */
13777 hddLog( VOS_TRACE_LEVEL_FATAL,
13778 "%s: vos_nv_open failed", __func__);
Vinay Krishna Eranna2025d892014-09-18 16:51:42 +053013779 goto err_wdclose;
Amar Singhal0a402232013-10-11 20:57:16 -070013780 }
13781
13782 status = vos_init_wiphy_from_nv_bin();
13783 if (!VOS_IS_STATUS_SUCCESS(status))
13784 {
13785 /* NV module cannot be initialized */
13786 hddLog( VOS_TRACE_LEVEL_FATAL,
13787 "%s: vos_init_wiphy failed", __func__);
13788 goto err_vos_nv_close;
13789 }
13790
Amar Singhala49cbc52013-10-08 18:37:44 -070013791#endif
Mahesh A Saptasagarc3ed0122016-01-19 16:45:11 +053013792 //Initialize the nlink service
13793 if(nl_srv_init() != 0)
13794 {
13795 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: nl_srv_init failed", __func__);
13796 goto err_vos_nv_close;
13797 }
13798
13799#ifdef WLAN_KD_READY_NOTIFIER
13800 pHddCtx->kd_nl_init = 1;
13801#endif /* WLAN_KD_READY_NOTIFIER */
13802
Girish Gowlibf0e1ab2015-01-19 16:05:16 +053013803 vos_set_roam_delay_stats_enabled(pHddCtx->cfg_ini->gEnableRoamDelayStats);
Arun Kumar Khandavalliebb19482014-03-25 13:56:53 +053013804 status = vos_open( &pVosContext, pHddCtx->parent_dev);
Jeff Johnson295189b2012-06-20 16:38:30 -070013805 if ( !VOS_IS_STATUS_SUCCESS( status ))
13806 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -080013807 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: vos_open failed", __func__);
Mahesh A Saptasagarc3ed0122016-01-19 16:45:11 +053013808 goto err_nl_srv;
Jeff Johnson295189b2012-06-20 16:38:30 -070013809 }
13810
Jeff Johnson295189b2012-06-20 16:38:30 -070013811 pHddCtx->hHal = (tHalHandle)vos_get_context( VOS_MODULE_ID_SME, pVosContext );
13812
13813 if ( NULL == pHddCtx->hHal )
13814 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -080013815 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: HAL context is null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070013816 goto err_vosclose;
13817 }
13818
Jeff Johnsonbc676b42013-02-14 16:04:08 -080013819 status = vos_preStart( pHddCtx->pvosContext );
13820 if ( !VOS_IS_STATUS_SUCCESS( status ) )
13821 {
13822 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: vos_preStart failed", __func__);
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053013823 goto err_vosclose;
Jeff Johnsonbc676b42013-02-14 16:04:08 -080013824 }
Jeff Johnsone7245742012-09-05 17:12:55 -070013825
Arif Hussaineaf68602013-12-30 23:10:44 -080013826 if (0 == enable_dfs_chan_scan || 1 == enable_dfs_chan_scan)
13827 {
13828 pHddCtx->cfg_ini->enableDFSChnlScan = enable_dfs_chan_scan;
13829 hddLog(VOS_TRACE_LEVEL_INFO, "%s: module enable_dfs_chan_scan set to %d",
13830 __func__, enable_dfs_chan_scan);
13831 }
13832 if (0 == enable_11d || 1 == enable_11d)
13833 {
13834 pHddCtx->cfg_ini->Is11dSupportEnabled = enable_11d;
13835 hddLog(VOS_TRACE_LEVEL_INFO, "%s: module enable_11d set to %d",
13836 __func__, enable_11d);
13837 }
13838
Jeff Johnsonbc676b42013-02-14 16:04:08 -080013839 /* Note that the vos_preStart() sequence triggers the cfg download.
13840 The cfg download must occur before we update the SME config
13841 since the SME config operation must access the cfg database */
Jeff Johnson295189b2012-06-20 16:38:30 -070013842 status = hdd_set_sme_config( pHddCtx );
13843
13844 if ( VOS_STATUS_SUCCESS != status )
13845 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -080013846 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Failed hdd_set_sme_config", __func__);
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053013847 goto err_vosclose;
Jeff Johnsonbc676b42013-02-14 16:04:08 -080013848 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013849
Jeff Johnson295189b2012-06-20 16:38:30 -070013850 /* In the integrated architecture we update the configuration from
13851 the INI file and from NV before vOSS has been started so that
13852 the final contents are available to send down to the cCPU */
13853
13854 // Apply the cfg.ini to cfg.dat
13855 if (FALSE == hdd_update_config_dat(pHddCtx))
13856 {
13857 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: config update failed",__func__ );
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053013858 goto err_vosclose;
Jeff Johnson295189b2012-06-20 16:38:30 -070013859 }
13860
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +053013861 // Get mac addr from platform driver
13862 ret = wcnss_get_wlan_mac_address((char*)&mac_addr.bytes);
13863
13864 if ((0 == ret) && (!vos_is_macaddr_zero(&mac_addr)))
Jeff Johnson295189b2012-06-20 16:38:30 -070013865 {
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +053013866 /* Store the mac addr for first interface */
13867 pHddCtx->cfg_ini->intfMacAddr[0] = mac_addr;
13868
13869 hddLog(VOS_TRACE_LEVEL_ERROR,
13870 "%s: WLAN Mac Addr: "
13871 MAC_ADDRESS_STR, __func__,
13872 MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[0].bytes));
13873
13874 /* Here, passing Arg2 as 1 because we do not want to change the
13875 last 3 bytes (means non OUI bytes) of first interface mac
13876 addr.
13877 */
13878 if (0 != hdd_generate_iface_mac_addr_auto(pHddCtx, 1, mac_addr))
13879 {
13880 hddLog(VOS_TRACE_LEVEL_ERROR,
13881 "%s: Failed to generate wlan interface mac addr "
13882 "using MAC from ini file ", __func__);
13883 }
13884 }
13885 else if (VOS_STATUS_SUCCESS != hdd_update_config_from_nv(pHddCtx))
13886 {
13887 // Apply the NV to cfg.dat
13888 /* Prima Update MAC address only at here */
Jeff Johnson295189b2012-06-20 16:38:30 -070013889#ifdef WLAN_AUTOGEN_MACADDR_FEATURE
13890 /* There was not a valid set of MAC Addresses in NV. See if the
13891 default addresses were modified by the cfg.ini settings. If so,
13892 we'll use them, but if not, we'll autogenerate a set of MAC
13893 addresses based upon the device serial number */
13894
13895 static const v_MACADDR_t default_address =
13896 {{0x00, 0x0A, 0xF5, 0x89, 0x89, 0xFF}};
Jeff Johnson295189b2012-06-20 16:38:30 -070013897
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +053013898 if (0 == memcmp(&default_address, &pHddCtx->cfg_ini->intfMacAddr[0],
13899 sizeof(default_address)))
Jeff Johnson295189b2012-06-20 16:38:30 -070013900 {
13901 /* cfg.ini has the default address, invoke autogen logic */
13902
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +053013903 /* Here, passing Arg2 as 0 because we want to change the
13904 last 3 bytes (means non OUI bytes) of all the interfaces
13905 mac addr.
13906 */
13907 if (0 != hdd_generate_iface_mac_addr_auto(pHddCtx, 0,
13908 default_address))
Jeff Johnson295189b2012-06-20 16:38:30 -070013909 {
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +053013910 hddLog(VOS_TRACE_LEVEL_ERROR,
13911 "%s: Failed to generate wlan interface mac addr "
13912 "using MAC from ini file " MAC_ADDRESS_STR, __func__,
13913 MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[0].bytes));
Jeff Johnson295189b2012-06-20 16:38:30 -070013914 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013915 }
13916 else
13917#endif //WLAN_AUTOGEN_MACADDR_FEATURE
13918 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -080013919 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070013920 "%s: Invalid MAC address in NV, using MAC from ini file "
13921 MAC_ADDRESS_STR, __func__,
13922 MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[0].bytes));
13923 }
13924 }
13925 {
13926 eHalStatus halStatus;
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +053013927
13928 /* Set the MAC Address Currently this is used by HAL to
13929 * add self sta. Remove this once self sta is added as
13930 * part of session open.
13931 */
Jeff Johnson295189b2012-06-20 16:38:30 -070013932 halStatus = cfgSetStr( pHddCtx->hHal, WNI_CFG_STA_ID,
13933 (v_U8_t *)&pHddCtx->cfg_ini->intfMacAddr[0],
13934 sizeof( pHddCtx->cfg_ini->intfMacAddr[0]) );
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +053013935
Jeff Johnson295189b2012-06-20 16:38:30 -070013936 if (!HAL_STATUS_SUCCESS( halStatus ))
13937 {
13938 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Failed to set MAC Address. "
13939 "HALStatus is %08d [x%08x]",__func__, halStatus, halStatus );
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053013940 goto err_vosclose;
Jeff Johnson295189b2012-06-20 16:38:30 -070013941 }
13942 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013943
13944 /*Start VOSS which starts up the SME/MAC/HAL modules and everything else
13945 Note: Firmware image will be read and downloaded inside vos_start API */
13946 status = vos_start( pHddCtx->pvosContext );
13947 if ( !VOS_IS_STATUS_SUCCESS( status ) )
13948 {
13949 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: vos_start failed",__func__);
Hanumantha Reddy Pothulabd9601a2016-02-12 13:22:27 +053013950 if (isSsrPanicOnFailure())
13951 VOS_BUG(0);
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053013952 goto err_vosclose;
Jeff Johnson295189b2012-06-20 16:38:30 -070013953 }
13954
Leo Chang6cec3e22014-01-21 15:33:49 -080013955#ifdef FEATURE_WLAN_CH_AVOID
13956 /* Plug in avoid channel notification callback
13957 * This should happen before ADD_SELF_STA
13958 * FW will send first IND with ADD_SELF_STA REQ from host */
Pradeep Reddy POTTETI5c2e16d2014-06-27 16:47:38 +053013959
13960 /* check the Channel Avoidance is enabled */
13961 if (TRUE == pHddCtx->cfg_ini->fenableCHAvoidance)
13962 {
13963 sme_AddChAvoidCallback(pHddCtx->hHal,
13964 hdd_hostapd_ch_avoid_cb);
13965 }
Leo Chang6cec3e22014-01-21 15:33:49 -080013966#endif /* FEATURE_WLAN_CH_AVOID */
13967
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -070013968 /* Exchange capability info between Host and FW and also get versioning info from FW */
13969 hdd_exchange_version_and_caps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -070013970
Agarwal Ashishad9281b2014-06-10 14:57:30 +053013971#ifdef CONFIG_ENABLE_LINUX_REG
13972 status = wlan_hdd_init_channels(pHddCtx);
13973 if ( !VOS_IS_STATUS_SUCCESS( status ) )
13974 {
13975 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: wlan_hdd_init_channels failed",
13976 __func__);
13977 goto err_vosstop;
13978 }
13979#endif
13980
Jeff Johnson295189b2012-06-20 16:38:30 -070013981 status = hdd_post_voss_start_config( pHddCtx );
13982 if ( !VOS_IS_STATUS_SUCCESS( status ) )
13983 {
13984 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hdd_post_voss_start_config failed",
13985 __func__);
13986 goto err_vosstop;
13987 }
Amar Singhala49cbc52013-10-08 18:37:44 -070013988
Rajeev Kumar Sirasanagandla2bb30b82019-01-07 22:30:16 +053013989 wlan_hdd_cfg80211_scan_randomization_init(wiphy);
13990
Amar Singhala49cbc52013-10-08 18:37:44 -070013991#ifndef CONFIG_ENABLE_LINUX_REG
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +053013992 wlan_hdd_cfg80211_update_reg_info( wiphy );
13993
13994 /* registration of wiphy dev with cfg80211 */
13995 if (0 > wlan_hdd_cfg80211_register(wiphy))
13996 {
13997 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy register failed", __func__);
13998 goto err_vosstop;
13999 }
Amar Singhala49cbc52013-10-08 18:37:44 -070014000#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070014001
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053014002#ifdef CONFIG_ENABLE_LINUX_REG
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053014003 /* registration of wiphy dev with cfg80211 */
14004 if (0 > wlan_hdd_cfg80211_register(wiphy))
14005 {
14006 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy register failed", __func__);
14007 goto err_vosstop;
14008 }
14009
Agarwal Ashish6db9d532014-09-30 18:19:10 +053014010 status = wlan_hdd_init_channels_for_cc(pHddCtx, INIT);
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053014011 if ( !VOS_IS_STATUS_SUCCESS( status ) )
14012 {
14013 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: wlan_hdd_init_channels_for_cc failed",
14014 __func__);
14015 goto err_unregister_wiphy;
14016 }
14017#endif
14018
c_hpothu4a298be2014-12-22 21:12:51 +053014019 wcnss_wlan_set_drvdata(pHddCtx->parent_dev, pHddCtx);
14020
Rajeev Kumar Sirasanagandla4c068d42019-02-22 21:39:36 +053014021#ifdef SAP_AUTH_OFFLOAD
14022 if (!sme_IsFeatureSupportedByFW(SAP_OFFLOADS))
14023 {
14024 hddLog(VOS_TRACE_LEVEL_INFO, FL(" SAP AUTH OFFLOAD not supp by FW"));
14025 pHddCtx->cfg_ini->enable_sap_auth_offload = 0;
14026 }
14027#endif
14028
Jeff Johnson295189b2012-06-20 16:38:30 -070014029 if (VOS_STA_SAP_MODE == hdd_get_conparam())
14030 {
14031 pAdapter = hdd_open_adapter( pHddCtx, WLAN_HDD_SOFTAP, "softap.%d",
14032 wlan_hdd_get_intf_addr(pHddCtx), FALSE );
14033 }
14034 else
14035 {
Jeff Johnson295189b2012-06-20 16:38:30 -070014036 pAdapter = hdd_open_adapter( pHddCtx, WLAN_HDD_INFRA_STATION, "wlan%d",
14037 wlan_hdd_get_intf_addr(pHddCtx), FALSE );
14038 if (pAdapter != NULL)
14039 {
Katya Nigama7d81d72014-11-12 12:44:34 +053014040 if (pHddCtx->cfg_ini->isP2pDeviceAddrAdministrated && !(pHddCtx->cfg_ini->intfMacAddr[0].bytes[0] & 0x02))
Jeff Johnson295189b2012-06-20 16:38:30 -070014041 {
Gopichand Nakkala49f96f62013-02-06 14:38:17 +053014042 vos_mem_copy( pHddCtx->p2pDeviceAddress.bytes,
14043 pHddCtx->cfg_ini->intfMacAddr[0].bytes,
14044 sizeof(tSirMacAddr));
Madan Mohan Koyyalamudiedfc1b72012-10-18 20:25:55 -070014045
Gopichand Nakkala49f96f62013-02-06 14:38:17 +053014046 /* Generate the P2P Device Address. This consists of the device's
14047 * primary MAC address with the locally administered bit set.
14048 */
14049 pHddCtx->p2pDeviceAddress.bytes[0] |= 0x02;
Jeff Johnsone7245742012-09-05 17:12:55 -070014050 }
14051 else
14052 {
Gopichand Nakkala49f96f62013-02-06 14:38:17 +053014053 tANI_U8* p2p_dev_addr = wlan_hdd_get_intf_addr(pHddCtx);
14054 if (p2p_dev_addr != NULL)
14055 {
14056 vos_mem_copy(&pHddCtx->p2pDeviceAddress.bytes[0],
14057 p2p_dev_addr, VOS_MAC_ADDR_SIZE);
14058 }
14059 else
14060 {
14061 hddLog(VOS_TRACE_LEVEL_FATAL,
14062 "%s: Failed to allocate mac_address for p2p_device",
14063 __func__);
14064 goto err_close_adapter;
14065 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014066 }
Jeff Johnsone7245742012-09-05 17:12:55 -070014067
14068 pP2pAdapter = hdd_open_adapter( pHddCtx, WLAN_HDD_P2P_DEVICE, "p2p%d",
14069 &pHddCtx->p2pDeviceAddress.bytes[0], FALSE );
14070 if ( NULL == pP2pAdapter )
14071 {
14072 hddLog(VOS_TRACE_LEVEL_FATAL,
14073 "%s: Failed to do hdd_open_adapter for P2P Device Interface",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070014074 __func__);
Jeff Johnsone7245742012-09-05 17:12:55 -070014075 goto err_close_adapter;
14076 }
Jeff Johnsone7245742012-09-05 17:12:55 -070014077 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014078 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014079
14080 if( pAdapter == NULL )
14081 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -080014082 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: hdd_open_adapter failed", __func__);
14083 goto err_close_adapter;
Jeff Johnson295189b2012-06-20 16:38:30 -070014084 }
Jeff Johnsone7245742012-09-05 17:12:55 -070014085
Ashish Kumar Dhanotiya3ac85a22019-02-12 19:10:14 +053014086 if ((strlen(pHddCtx->cfg_ini->enabledefaultSAP) != 0) &&
14087 (strcmp(pHddCtx->cfg_ini->enabledefaultSAP, "") != 0)) {
Arunk Khandavalli95608be2019-01-22 13:12:54 +053014088 softapAdapter = hdd_open_adapter( pHddCtx, WLAN_HDD_SOFTAP,
14089 pHddCtx->cfg_ini->enabledefaultSAP,
14090 wlan_hdd_get_intf_addr(pHddCtx), FALSE);
14091 if (!softapAdapter) {
14092 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: hdd_open_adapter failed", __func__);
14093 goto err_close_adapter;
14094 }
14095 }
14096
Arif Hussain66559122013-11-21 10:11:40 -080014097 if (country_code)
14098 {
14099 eHalStatus ret;
Arif Hussaincb607082013-12-20 11:57:42 -080014100 INIT_COMPLETION(pAdapter->change_country_code);
Arif Hussain66559122013-11-21 10:11:40 -080014101 hdd_checkandupdate_dfssetting(pAdapter, country_code);
14102#ifndef CONFIG_ENABLE_LINUX_REG
14103 hdd_checkandupdate_phymode(pAdapter, country_code);
14104#endif
Arif Hussaineaf68602013-12-30 23:10:44 -080014105 ret = sme_ChangeCountryCode(pHddCtx->hHal,
14106 (void *)(tSmeChangeCountryCallback)
14107 wlan_hdd_change_country_code_callback,
Arif Hussain66559122013-11-21 10:11:40 -080014108 country_code,
14109 pAdapter, pHddCtx->pvosContext,
Abhishek Singha306a442013-11-07 18:39:01 +053014110 eSIR_TRUE, eSIR_TRUE);
Arif Hussain66559122013-11-21 10:11:40 -080014111 if (eHAL_STATUS_SUCCESS == ret)
14112 {
Arif Hussaincb607082013-12-20 11:57:42 -080014113 ret = wait_for_completion_interruptible_timeout(
14114 &pAdapter->change_country_code,
14115 msecs_to_jiffies(WLAN_WAIT_TIME_COUNTRY));
14116
14117 if (0 >= ret)
14118 {
14119 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
14120 "%s: SME while setting country code timed out", __func__);
14121 }
Arif Hussain66559122013-11-21 10:11:40 -080014122 }
14123 else
14124 {
Arif Hussaincb607082013-12-20 11:57:42 -080014125 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
14126 "%s: SME Change Country code from module param fail ret=%d",
14127 __func__, ret);
Arif Hussain66559122013-11-21 10:11:40 -080014128 }
14129 }
14130
Jeff Johnson295189b2012-06-20 16:38:30 -070014131#ifdef WLAN_BTAMP_FEATURE
14132 vStatus = WLANBAP_Open(pVosContext);
14133 if(!VOS_IS_STATUS_SUCCESS(vStatus))
14134 {
14135 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
14136 "%s: Failed to open BAP",__func__);
Jeff Johnsone7245742012-09-05 17:12:55 -070014137 goto err_close_adapter;
Jeff Johnson295189b2012-06-20 16:38:30 -070014138 }
14139
14140 vStatus = BSL_Init(pVosContext);
14141 if(!VOS_IS_STATUS_SUCCESS(vStatus))
14142 {
14143 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
14144 "%s: Failed to Init BSL",__func__);
14145 goto err_bap_close;
14146 }
14147 vStatus = WLANBAP_Start(pVosContext);
14148 if (!VOS_IS_STATUS_SUCCESS(vStatus))
14149 {
14150 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
14151 "%s: Failed to start TL",__func__);
14152 goto err_bap_close;
14153 }
14154
14155 pConfig = pHddCtx->cfg_ini;
14156 btAmpConfig.ucPreferredChannel = pConfig->preferredChannel;
14157 status = WLANBAP_SetConfig(&btAmpConfig);
14158
14159#endif //WLAN_BTAMP_FEATURE
Jeff Johnsone7245742012-09-05 17:12:55 -070014160
Mihir Shete9c238772014-10-15 14:35:16 +053014161 /*
14162 * UapsdMask is 0xf if U-APSD is enbaled for all AC's...
14163 * The value of CFG_QOS_WMM_UAPSD_MASK_DEFAULT is 0xaa(Magic Value)
14164 * which is greater than 0xf. So the below check is safe to make
14165 * sure that there is no entry for UapsdMask in the ini
14166 */
14167 if (CFG_QOS_WMM_UAPSD_MASK_DEFAULT == pHddCtx->cfg_ini->UapsdMask)
14168 {
14169 if(IS_DYNAMIC_WMM_PS_ENABLED)
14170 {
14171 hddLog(VOS_TRACE_LEVEL_DEBUG,"%s: Enable UAPSD for VI & VO",
14172 __func__);
14173 pHddCtx->cfg_ini->UapsdMask =
14174 CFG_QOS_WMM_UAPSD_MASK_DYMANIC_WMM_PS_DEFAULT;
14175 }
14176 else
14177 {
14178 hddLog(VOS_TRACE_LEVEL_DEBUG,"%s: Do not enable UAPSD",
14179 __func__);
14180 pHddCtx->cfg_ini->UapsdMask =
14181 CFG_QOS_WMM_UAPSD_MASK_LEGACY_WMM_PS_DEFAULT;
14182 }
14183 }
14184
Varun Reddy Yeturud0a3f252013-04-15 21:58:13 -070014185#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
14186 if(!(IS_ROAM_SCAN_OFFLOAD_FEATURE_ENABLE))
14187 {
14188 hddLog(VOS_TRACE_LEVEL_DEBUG,"%s: ROAM_SCAN_OFFLOAD Feature not supported",__func__);
14189 pHddCtx->cfg_ini->isRoamOffloadScanEnabled = 0;
14190 sme_UpdateRoamScanOffloadEnabled((tHalHandle)(pHddCtx->hHal),
14191 pHddCtx->cfg_ini->isRoamOffloadScanEnabled);
14192 }
14193#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070014194
Agarwal Ashish4b87f922014-06-18 03:03:21 +053014195 wlan_hdd_tdls_init(pHddCtx);
14196
Masti, Narayanraddi26378462016-01-05 18:20:28 +053014197 wlan_hdd_init_deinit_defer_scan_context(&pHddCtx->scan_ctxt);
14198
14199 vos_init_delayed_work(&pHddCtx->scan_ctxt.scan_work,
14200 wlan_hdd_schedule_defer_scan);
14201
Mihir Shetefc7ff5b2014-01-27 11:30:05 +053014202 sme_Register11dScanDoneCallback(pHddCtx->hHal, hdd_11d_scan_done);
14203
Jeff Johnson295189b2012-06-20 16:38:30 -070014204 /* Register with platform driver as client for Suspend/Resume */
14205 status = hddRegisterPmOps(pHddCtx);
14206 if ( !VOS_IS_STATUS_SUCCESS( status ) )
14207 {
14208 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddRegisterPmOps failed",__func__);
14209#ifdef WLAN_BTAMP_FEATURE
14210 goto err_bap_stop;
14211#else
Jeff Johnsone7245742012-09-05 17:12:55 -070014212 goto err_close_adapter;
Jeff Johnson295189b2012-06-20 16:38:30 -070014213#endif //WLAN_BTAMP_FEATURE
14214 }
14215
Yue Ma0d4891e2013-08-06 17:01:45 -070014216 /* Open debugfs interface */
14217 if (VOS_STATUS_SUCCESS != hdd_debugfs_init(pAdapter))
14218 {
14219 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
14220 "%s: hdd_debugfs_init failed!", __func__);
Yue Ma0d4891e2013-08-06 17:01:45 -070014221 }
14222
Jeff Johnson295189b2012-06-20 16:38:30 -070014223 /* Register TM level change handler function to the platform */
14224 status = hddDevTmRegisterNotifyCallback(pHddCtx);
14225 if ( !VOS_IS_STATUS_SUCCESS( status ) )
14226 {
14227 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddDevTmRegisterNotifyCallback failed",__func__);
14228 goto err_unregister_pmops;
14229 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014230
Jeff Johnson295189b2012-06-20 16:38:30 -070014231 // register net device notifier for device change notification
14232 ret = register_netdevice_notifier(&hdd_netdev_notifier);
14233
14234 if(ret < 0)
14235 {
14236 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: register_netdevice_notifier failed",__func__);
Siddharth Bhalcd92b782015-06-29 12:25:40 +053014237 goto err_unregister_pmops;
Jeff Johnson295189b2012-06-20 16:38:30 -070014238 }
14239
Jeff Johnson295189b2012-06-20 16:38:30 -070014240 //Initialize the BTC service
14241 if(btc_activate_service(pHddCtx) != 0)
14242 {
14243 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: btc_activate_service failed",__func__);
Mahesh A Saptasagarc3ed0122016-01-19 16:45:11 +053014244 goto err_reg_netdev;
Jeff Johnson295189b2012-06-20 16:38:30 -070014245 }
14246
Padma, Santhosh Kumar2762e9d2015-10-20 15:02:57 +053014247#ifdef FEATURE_OEM_DATA_SUPPORT
14248 //Initialize the OEM service
14249 if (oem_activate_service(pHddCtx) != 0)
14250 {
14251 hddLog(VOS_TRACE_LEVEL_FATAL,
14252 "%s: oem_activate_service failed", __func__);
Hanumanth Reddy Pothula13789c42017-09-12 15:18:13 +053014253 goto err_btc_activate_service;
Padma, Santhosh Kumar2762e9d2015-10-20 15:02:57 +053014254 }
14255#endif
14256
Jeff Johnson295189b2012-06-20 16:38:30 -070014257#ifdef PTT_SOCK_SVC_ENABLE
14258 //Initialize the PTT service
14259 if(ptt_sock_activate_svc(pHddCtx) != 0)
14260 {
14261 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: ptt_sock_activate_svc failed",__func__);
Hanumanth Reddy Pothula13789c42017-09-12 15:18:13 +053014262 goto err_oem_activate_service;
Jeff Johnson295189b2012-06-20 16:38:30 -070014263 }
14264#endif
14265
Abhishek Singh00b71972016-01-07 10:51:04 +053014266#ifdef WLAN_FEATURE_RMC
14267 if (hdd_open_cesium_nl_sock() < 0)
14268 {
14269 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hdd_open_cesium_nl_sock failed", __func__);
Hanumanth Reddy Pothula13789c42017-09-12 15:18:13 +053014270 goto err_ptt_sock_activate_svc;
Abhishek Singh00b71972016-01-07 10:51:04 +053014271 }
14272#endif
14273
Vinay Krishna Erannad938c422014-03-10 17:14:21 +053014274#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
14275 if(pHddCtx->cfg_ini && pHddCtx->cfg_ini->wlanLoggingEnable)
14276 {
Deepthi Gowri78083a32014-11-04 12:55:51 +053014277 if(wlan_logging_sock_activate_svc(
14278 pHddCtx->cfg_ini->wlanLoggingFEToConsole,
Sushant Kaushik33200572015-08-05 16:46:20 +053014279 pHddCtx->cfg_ini->wlanLoggingNumBuf,
14280 pHddCtx->cfg_ini->wlanPerPktStatsLogEnable,
14281 pHddCtx->cfg_ini->wlanPerPktStatsNumBuf))
Deepthi Gowri78083a32014-11-04 12:55:51 +053014282 {
14283 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wlan_logging_sock_activate_svc"
14284 " failed", __func__);
Hanumanth Reddy Pothula13789c42017-09-12 15:18:13 +053014285 goto err_open_cesium_nl_sock;
Deepthi Gowri78083a32014-11-04 12:55:51 +053014286 }
14287 //TODO: To Remove enableDhcpDebug and use gEnableDebugLog for
14288 //EAPOL and DHCP
Sachin Ahuja8c65f382014-12-12 15:34:21 +053014289 if (!pHddCtx->cfg_ini->gEnableDebugLog)
14290 pHddCtx->cfg_ini->gEnableDebugLog =
Sushant Kaushik6e4e2bc2015-10-05 17:23:07 +053014291 VOS_PKT_PROTO_TYPE_EAPOL | VOS_PKT_PROTO_TYPE_DHCP |
14292 VOS_PKT_PROTO_TYPE_ARP;
Vinay Krishna Erannad938c422014-03-10 17:14:21 +053014293 }
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053014294
Siddharth Bhald1be97f2015-05-27 22:39:59 +053014295 if (pHddCtx->cfg_ini->wlanLoggingEnable &&
14296 (pHddCtx->cfg_ini->enableFWLogging ||
Siddharth Bhaldb963232015-06-25 19:34:35 +053014297 pHddCtx->cfg_ini->enableMgmtLogging ||
sheenam monga1a0202d2020-01-03 15:20:57 +053014298 pHddCtx->cfg_ini->enableContFWLogging))
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053014299 {
Siddharth Bhald1be97f2015-05-27 22:39:59 +053014300 hdd_init_frame_logging(pHddCtx);
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053014301 }
14302 else
14303 {
Siddharth Bhald1be97f2015-05-27 22:39:59 +053014304 hddLog(VOS_TRACE_LEVEL_INFO, FL("Logging disabled in ini"));
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053014305 }
14306
Vinay Krishna Erannad938c422014-03-10 17:14:21 +053014307#endif
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053014308
Sushant Kaushik215778f2015-05-21 14:05:36 +053014309 if (vos_is_multicast_logging())
14310 wlan_logging_set_log_level();
14311
Jeff Johnson295189b2012-06-20 16:38:30 -070014312 hdd_register_mcast_bcast_filter(pHddCtx);
Bala Venkateshe65810a2019-02-18 20:32:36 +053014313
14314 /* Action frame registered in one adapter which will
14315 * applicable to all interfaces
14316 */
14317 wlan_hdd_cfg80211_register_frames(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070014318
14319 mutex_init(&pHddCtx->sap_lock);
Mahesh A Saptasagar60627942014-10-13 13:55:14 +053014320 mutex_init(&pHddCtx->roc_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -070014321
Jeff Johnsone7245742012-09-05 17:12:55 -070014322#ifdef WLAN_FEATURE_HOLD_RX_WAKELOCK
14323 /* Initialize the wake lcok */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053014324 vos_wake_lock_init(&pHddCtx->rx_wake_lock,
Jeff Johnsone7245742012-09-05 17:12:55 -070014325 "qcom_rx_wakelock");
Sushant Kaushik83392fa2015-05-05 17:44:40 +053014326
Jeff Johnsone7245742012-09-05 17:12:55 -070014327#endif
Madan Mohan Koyyalamudi69fc3ad2012-11-28 16:04:56 -080014328 /* Initialize the wake lcok */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053014329 vos_wake_lock_init(&pHddCtx->sap_wake_lock,
Madan Mohan Koyyalamudi69fc3ad2012-11-28 16:04:56 -080014330 "qcom_sap_wakelock");
Sushant Kaushik83392fa2015-05-05 17:44:40 +053014331
Jeff Johnsone7245742012-09-05 17:12:55 -070014332
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070014333 vos_event_init(&pHddCtx->scan_info.scan_finished_event);
14334 pHddCtx->scan_info.scan_pending_option = WEXT_SCAN_PENDING_GIVEUP;
Jeff Johnson295189b2012-06-20 16:38:30 -070014335
Katya Nigam5c306ea2014-06-19 15:39:54 +053014336 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_NO_LOAD_UNLOAD_IN_PROGRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -070014337 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, FALSE);
Sushant Kaushik83392fa2015-05-05 17:44:40 +053014338 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_DRIVER_INIT);
Katya Nigam5c306ea2014-06-19 15:39:54 +053014339
14340#ifdef FEATURE_WLAN_SCAN_PNO
14341 /*SME must send channel update configuration to RIVA*/
14342 sme_UpdateChannelConfig(pHddCtx->hHal);
14343#endif
Abhishek Singhf644b272014-08-21 02:59:39 +053014344 /* Send the update default channel list to the FW*/
14345 sme_UpdateChannelList(pHddCtx->hHal);
Mukul Sharma45063942015-04-01 20:07:59 +053014346
14347 /* Fwr capabilities received, Set the Dot11 mode */
Abhishek Singh41ebce12016-02-03 10:43:21 +053014348 sme_SetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter),
14349 hdd_cfg_xlate_to_csr_phy_mode(pHddCtx->cfg_ini->dot11Mode));
Mukul Sharma45063942015-04-01 20:07:59 +053014350 sme_SetDefDot11Mode(pHddCtx->hHal);
14351
Abhishek Singha306a442013-11-07 18:39:01 +053014352#ifndef CONFIG_ENABLE_LINUX_REG
14353 /*updating wiphy so that regulatory user hints can be processed*/
14354 if (wiphy)
14355 {
14356 regulatory_hint(wiphy, "00");
14357 }
14358#endif
Jeff Johnsone7245742012-09-05 17:12:55 -070014359 // Initialize the restart logic
14360 wlan_hdd_restart_init(pHddCtx);
Chilam NG571c65a2013-01-19 12:27:36 +053014361
Hanumanth Reddy Pothula146bca42016-11-08 12:01:07 +053014362 if (pHddCtx->cfg_ini->fIsLogpEnabled) {
14363 vos_wdthread_init_timer_work(vos_process_wd_timer);
14364 /* Initialize the timer to detect thread stuck issues */
14365 vos_thread_stuck_timer_init(
14366 &((VosContextType*)pVosContext)->vosWatchdog);
14367 }
14368
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -070014369 //Register the traffic monitor timer now
14370 if ( pHddCtx->cfg_ini->dynSplitscan)
14371 {
14372 vos_timer_init(&pHddCtx->tx_rx_trafficTmr,
14373 VOS_TIMER_TYPE_SW,
14374 hdd_tx_rx_pkt_cnt_stat_timer_handler,
14375 (void *)pHddCtx);
14376 }
Srinivas Dasari030bad32015-02-18 23:23:54 +053014377 wlan_hdd_cfg80211_nan_init(pHddCtx);
14378
Bhargav Shahd0715912015-10-01 18:17:37 +053014379 mutex_init(&pHddCtx->cur_rx_level_lock);
14380 vos_timer_init(&pHddCtx->delack_timer, VOS_TIMER_TYPE_SW,
14381 hdd_tcp_delack_compute_function,(void *)pHddCtx);
Masti, Narayanraddi44b0db02015-12-22 11:54:35 +053014382 vos_timer_init(&pHddCtx->tdls_source_timer, VOS_TIMER_TYPE_SW,
14383 wlan_hdd_change_tdls_mode, (void *)pHddCtx);
Bhargav Shahd0715912015-10-01 18:17:37 +053014384
Dino Mycle6fb96c12014-06-10 11:52:40 +053014385#ifdef WLAN_FEATURE_EXTSCAN
14386 sme_EXTScanRegisterCallback(pHddCtx->hHal,
14387 wlan_hdd_cfg80211_extscan_callback,
14388 pHddCtx);
14389#endif /* WLAN_FEATURE_EXTSCAN */
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +053014390
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053014391#ifdef FEATURE_OEM_DATA_SUPPORT
14392 sme_OemDataRegisterCallback(pHddCtx->hHal,
14393 wlan_hdd_cfg80211_oemdata_callback,
14394 pHddCtx);
14395#endif /* FEATURE_OEM_DATA_SUPPORT */
14396
Gupta, Kapil7c34b322015-09-30 13:12:35 +053014397 sme_set_rssi_threshold_breached_cb(pHddCtx->hHal, hdd_rssi_threshold_breached_cb);
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +053014398#ifdef WLAN_NS_OFFLOAD
14399 // Register IPv6 notifier to notify if any change in IP
14400 // So that we can reconfigure the offload parameters
14401 pHddCtx->ipv6_notifier.notifier_call = wlan_hdd_ipv6_changed;
14402 ret = register_inet6addr_notifier(&pHddCtx->ipv6_notifier);
14403 if (ret)
14404 {
Ratheesh S P36dbc932015-08-07 14:28:57 +053014405 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to register IPv6 notifier"));
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +053014406 }
14407 else
14408 {
Ratheesh S P36dbc932015-08-07 14:28:57 +053014409 hddLog(VOS_TRACE_LEVEL_INFO, FL("Registered IPv6 notifier"));
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +053014410 }
14411#endif
14412
Sravan Kumar Kairamb0edc612016-10-26 13:55:24 +053014413 vos_mem_set((uint8_t *)&pHddCtx->bad_sta, HDD_MAX_STA_COUNT, 0);
14414
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +053014415 // Register IPv4 notifier to notify if any change in IP
14416 // So that we can reconfigure the offload parameters
14417 pHddCtx->ipv4_notifier.notifier_call = wlan_hdd_ipv4_changed;
14418 ret = register_inetaddr_notifier(&pHddCtx->ipv4_notifier);
14419 if (ret)
14420 {
Ratheesh S P36dbc932015-08-07 14:28:57 +053014421 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to register IPv4 notifier"));
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +053014422 }
14423 else
14424 {
Ratheesh S P36dbc932015-08-07 14:28:57 +053014425 hddLog(VOS_TRACE_LEVEL_INFO, FL("Registered IPv4 notifier"));
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +053014426 }
Bhargav shah23c94942015-10-13 12:48:35 +053014427 hdd_dp_util_send_rps_ind(pHddCtx);
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +053014428
Nishank Aggarwalc11826c2016-12-15 18:54:10 +053014429 pHddCtx->is_ap_mode_wow_supported =
14430 sme_IsFeatureSupportedByFW(SAP_MODE_WOW);
Sravan Kumar Kairam091e5b62017-01-23 14:14:20 +053014431
Hanumanth Reddy Pothulae92bcc12017-05-19 13:56:35 +053014432 pHddCtx->is_fatal_event_log_sup =
14433 sme_IsFeatureSupportedByFW(FATAL_EVENT_LOGGING);
14434 hddLog(VOS_TRACE_LEVEL_INFO, FL("FATAL_EVENT_LOGGING: %d"),
14435 pHddCtx->is_fatal_event_log_sup);
14436
Sravan Kumar Kairam091e5b62017-01-23 14:14:20 +053014437 hdd_assoc_registerFwdEapolCB(pVosContext);
14438
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +053014439 mutex_init(&pHddCtx->cache_channel_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -070014440 goto success;
14441
Hanumanth Reddy Pothula13789c42017-09-12 15:18:13 +053014442err_open_cesium_nl_sock:
14443#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
14444 hdd_close_cesium_nl_sock();
14445#endif
14446
14447err_ptt_sock_activate_svc:
14448#ifdef PTT_SOCK_SVC_ENABLE
14449 ptt_sock_deactivate_svc(pHddCtx);
14450#endif
14451
14452err_oem_activate_service:
14453#ifdef FEATURE_OEM_DATA_SUPPORT
14454 oem_deactivate_service();
14455#endif
14456
14457err_btc_activate_service:
14458 btc_deactivate_service();
14459
Jeff Johnson295189b2012-06-20 16:38:30 -070014460err_reg_netdev:
14461 unregister_netdevice_notifier(&hdd_netdev_notifier);
14462
Jeff Johnson295189b2012-06-20 16:38:30 -070014463err_unregister_pmops:
14464 hddDevTmUnregisterNotifyCallback(pHddCtx);
14465 hddDeregisterPmOps(pHddCtx);
14466
Yue Ma0d4891e2013-08-06 17:01:45 -070014467 hdd_debugfs_exit(pHddCtx);
14468
Jeff Johnson295189b2012-06-20 16:38:30 -070014469#ifdef WLAN_BTAMP_FEATURE
14470err_bap_stop:
14471 WLANBAP_Stop(pVosContext);
14472#endif
14473
14474#ifdef WLAN_BTAMP_FEATURE
14475err_bap_close:
14476 WLANBAP_Close(pVosContext);
14477#endif
14478
Jeff Johnson295189b2012-06-20 16:38:30 -070014479err_close_adapter:
14480 hdd_close_all_adapters( pHddCtx );
Mahesh A Saptasagar9ecefe42014-07-15 18:43:49 +053014481#ifdef CONFIG_ENABLE_LINUX_REG
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053014482err_unregister_wiphy:
Mahesh A Saptasagar9ecefe42014-07-15 18:43:49 +053014483#endif
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +053014484 wiphy_unregister(wiphy) ;
Agrawal Ashish33ec71e2015-11-26 20:20:58 +053014485 hdd_wlan_free_wiphy_channels(wiphy);
14486
Jeff Johnson295189b2012-06-20 16:38:30 -070014487err_vosstop:
14488 vos_stop(pVosContext);
14489
Amar Singhala49cbc52013-10-08 18:37:44 -070014490err_vosclose:
Jeff Johnson295189b2012-06-20 16:38:30 -070014491 status = vos_sched_close( pVosContext );
14492 if (!VOS_IS_STATUS_SUCCESS(status)) {
14493 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
14494 "%s: Failed to close VOSS Scheduler", __func__);
14495 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( status ) );
14496 }
Amar Singhala49cbc52013-10-08 18:37:44 -070014497 vos_close(pVosContext );
14498
Mahesh A Saptasagarc3ed0122016-01-19 16:45:11 +053014499err_nl_srv:
14500#ifdef WLAN_KD_READY_NOTIFIER
14501 nl_srv_exit(pHddCtx->ptt_pid);
14502#else
14503 nl_srv_exit();
14504#endif /* WLAN_KD_READY_NOTIFIER */
Amar Singhal0a402232013-10-11 20:57:16 -070014505err_vos_nv_close:
14506
c_hpothue6a36282014-03-19 12:27:38 +053014507#ifdef CONFIG_ENABLE_LINUX_REG
Amar Singhal0a402232013-10-11 20:57:16 -070014508 vos_nv_close();
14509
c_hpothu70f8d812014-03-22 22:59:23 +053014510#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070014511
14512err_wdclose:
14513 if(pHddCtx->cfg_ini->fIsLogpEnabled)
14514 vos_watchdog_close(pVosContext);
14515
Jeff Johnson295189b2012-06-20 16:38:30 -070014516err_config:
Hanumanth Reddy Pothula1efcd162018-03-14 14:32:27 +053014517 hdd_request_manager_deinit();
Jeff Johnson295189b2012-06-20 16:38:30 -070014518 kfree(pHddCtx->cfg_ini);
14519 pHddCtx->cfg_ini= NULL;
14520
14521err_free_hdd_context:
Sushant Kaushik83392fa2015-05-05 17:44:40 +053014522 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_DRIVER_INIT);
Siddharth Bhalcd92b782015-06-29 12:25:40 +053014523 free_riva_power_on_lock("wlan");
Jeff Johnson295189b2012-06-20 16:38:30 -070014524 wiphy_free(wiphy) ;
14525 //kfree(wdev) ;
Jeff Johnson295189b2012-06-20 16:38:30 -070014526 VOS_BUG(1);
14527
Madan Mohan Koyyalamudid57ae632012-11-06 18:42:48 -080014528 if (hdd_is_ssr_required())
14529 {
14530 /* WDI timeout had happened during load, so SSR is needed here */
14531 subsystem_restart("wcnss");
14532 msleep(5000);
14533 }
14534 hdd_set_ssr_required (VOS_FALSE);
14535
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -080014536 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -070014537
14538success:
14539 EXIT();
14540 return 0;
14541}
14542
14543/**---------------------------------------------------------------------------
14544
Jeff Johnson32d95a32012-09-10 13:15:23 -070014545 \brief hdd_driver_init() - Core Driver Init Function
Jeff Johnson295189b2012-06-20 16:38:30 -070014546
Jeff Johnson32d95a32012-09-10 13:15:23 -070014547 This is the driver entry point - called in different timeline depending
14548 on whether the driver is statically or dynamically linked
Jeff Johnson295189b2012-06-20 16:38:30 -070014549
14550 \param - None
14551
14552 \return - 0 for success, non zero for failure
14553
14554 --------------------------------------------------------------------------*/
Jeff Johnson32d95a32012-09-10 13:15:23 -070014555static int hdd_driver_init( void)
Jeff Johnson295189b2012-06-20 16:38:30 -070014556{
14557 VOS_STATUS status;
14558 v_CONTEXT_t pVosContext = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070014559 struct device *dev = NULL;
14560 int ret_status = 0;
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -070014561#ifdef HAVE_WCNSS_CAL_DOWNLOAD
14562 int max_retries = 0;
14563#endif
Siddharth Bhalc7e79b62014-10-10 22:37:38 +053014564#ifdef HAVE_CBC_DONE
14565 int max_cbc_retries = 0;
14566#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070014567
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +053014568#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
14569 wlan_logging_sock_init_svc();
14570#endif
14571
Jeff Johnson295189b2012-06-20 16:38:30 -070014572 ENTER();
14573
Sushant Kaushik83392fa2015-05-05 17:44:40 +053014574 vos_wake_lock_init(&wlan_wake_lock, "wlan");
Jeff Johnson295189b2012-06-20 16:38:30 -070014575
14576 pr_info("%s: loading driver v%s\n", WLAN_MODULE_NAME,
14577 QWLAN_VERSIONSTR TIMER_MANAGER_STR MEMORY_DEBUG_STR);
14578
Jeff Johnson295189b2012-06-20 16:38:30 -070014579#ifdef ANI_BUS_TYPE_PCI
14580
14581 dev = wcnss_wlan_get_device();
14582
14583#endif // ANI_BUS_TYPE_PCI
14584
14585#ifdef ANI_BUS_TYPE_PLATFORM
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -070014586
14587#ifdef HAVE_WCNSS_CAL_DOWNLOAD
14588 /* wait until WCNSS driver downloads NV */
Ravi Kumar Bokka7a139e62016-11-17 21:32:55 +053014589 while (!wcnss_device_ready() && 10 >= ++max_retries) {
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -070014590 msleep(1000);
14591 }
Siddharth Bhalc7e79b62014-10-10 22:37:38 +053014592
Ravi Kumar Bokka7a139e62016-11-17 21:32:55 +053014593 if (max_retries >= 10) {
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -070014594 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: WCNSS driver not ready", __func__);
Sushant Kaushik83392fa2015-05-05 17:44:40 +053014595 vos_wake_lock_destroy(&wlan_wake_lock);
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +053014596#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
14597 wlan_logging_sock_deinit_svc();
14598#endif
14599
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -070014600 return -ENODEV;
14601 }
14602#endif
14603
Siddharth Bhalc7e79b62014-10-10 22:37:38 +053014604#ifdef HAVE_CBC_DONE
14605 while (!wcnss_cbc_complete() && 10 >= ++max_cbc_retries) {
14606 msleep(1000);
14607 }
14608 if (max_cbc_retries >= 10) {
14609 hddLog(VOS_TRACE_LEVEL_FATAL, "%s:CBC not completed", __func__);
14610 }
14611#endif
14612
Jeff Johnson295189b2012-06-20 16:38:30 -070014613 dev = wcnss_wlan_get_device();
14614#endif // ANI_BUS_TYPE_PLATFORM
14615
14616
14617 do {
14618 if (NULL == dev) {
14619 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: WLAN device not found!!",__func__);
14620 ret_status = -1;
14621 break;
14622 }
14623
Jeff Johnson295189b2012-06-20 16:38:30 -070014624#ifdef TIMER_MANAGER
14625 vos_timer_manager_init();
14626#endif
14627
14628 /* Preopen VOSS so that it is ready to start at least SAL */
14629 status = vos_preOpen(&pVosContext);
14630
14631 if (!VOS_IS_STATUS_SUCCESS(status))
14632 {
14633 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Failed to preOpen VOSS", __func__);
14634 ret_status = -1;
14635 break;
14636 }
14637
Sushant Kaushik02beb352015-06-04 15:15:01 +053014638 hddTraceInit();
Padma, Santhosh Kumar9093b202015-07-21 15:37:38 +053014639 hdd_register_debug_callback();
14640
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070014641#ifndef MODULE
14642 /* For statically linked driver, call hdd_set_conparam to update curr_con_mode
14643 */
14644 hdd_set_conparam((v_UINT_t)con_mode);
14645#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070014646
14647 // Call our main init function
Jeff Johnsonbc676b42013-02-14 16:04:08 -080014648 if (hdd_wlan_startup(dev))
14649 {
Jeff Johnson295189b2012-06-20 16:38:30 -070014650 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: WLAN Driver Initialization failed",
Jeff Johnsonbc676b42013-02-14 16:04:08 -080014651 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070014652 vos_preClose( &pVosContext );
14653 ret_status = -1;
14654 break;
14655 }
14656
Jeff Johnson295189b2012-06-20 16:38:30 -070014657 } while (0);
14658
14659 if (0 != ret_status)
14660 {
Jeff Johnson295189b2012-06-20 16:38:30 -070014661#ifdef TIMER_MANAGER
14662 vos_timer_exit();
14663#endif
14664#ifdef MEMORY_DEBUG
14665 vos_mem_exit();
14666#endif
Sushant Kaushik83392fa2015-05-05 17:44:40 +053014667 vos_wake_lock_destroy(&wlan_wake_lock);
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +053014668#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
14669 wlan_logging_sock_deinit_svc();
14670#endif
14671
Jeff Johnson295189b2012-06-20 16:38:30 -070014672 pr_err("%s: driver load failure\n", WLAN_MODULE_NAME);
14673 }
14674 else
14675 {
14676 //Send WLAN UP indication to Nlink Service
14677 send_btc_nlink_msg(WLAN_MODULE_UP_IND, 0);
14678
14679 pr_info("%s: driver loaded\n", WLAN_MODULE_NAME);
Jeff Johnson295189b2012-06-20 16:38:30 -070014680 }
14681
14682 EXIT();
14683
14684 return ret_status;
14685}
14686
Jeff Johnson32d95a32012-09-10 13:15:23 -070014687/**---------------------------------------------------------------------------
14688
14689 \brief hdd_module_init() - Init Function
14690
14691 This is the driver entry point (invoked when module is loaded using insmod)
14692
14693 \param - None
14694
14695 \return - 0 for success, non zero for failure
14696
14697 --------------------------------------------------------------------------*/
14698#ifdef MODULE
14699static int __init hdd_module_init ( void)
14700{
14701 return hdd_driver_init();
14702}
Jeff Johnson32d95a32012-09-10 13:15:23 -070014703#else /* #ifdef MODULE */
14704static int __init hdd_module_init ( void)
14705{
14706 /* Driver initialization is delayed to fwpath_changed_handler */
14707 return 0;
14708}
Jeff Johnson32d95a32012-09-10 13:15:23 -070014709#endif /* #ifdef MODULE */
14710
Jeff Johnson295189b2012-06-20 16:38:30 -070014711
14712/**---------------------------------------------------------------------------
14713
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070014714 \brief hdd_driver_exit() - Exit function
Jeff Johnson295189b2012-06-20 16:38:30 -070014715
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070014716 This is the driver exit point (invoked when module is unloaded using rmmod
14717 or con_mode was changed by userspace)
Jeff Johnson295189b2012-06-20 16:38:30 -070014718
14719 \param - None
14720
14721 \return - None
14722
14723 --------------------------------------------------------------------------*/
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070014724static void hdd_driver_exit(void)
Jeff Johnson295189b2012-06-20 16:38:30 -070014725{
14726 hdd_context_t *pHddCtx = NULL;
14727 v_CONTEXT_t pVosContext = NULL;
Agarwal Ashish5e414792014-06-08 15:25:23 +053014728 v_REGDOMAIN_t regId;
Arun Kumar Khandavallie0b046d2014-03-01 21:54:25 +053014729 unsigned long rc = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070014730
14731 pr_info("%s: unloading driver v%s\n", WLAN_MODULE_NAME, QWLAN_VERSIONSTR);
14732
14733 //Get the global vos context
14734 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
14735
14736 if(!pVosContext)
14737 {
14738 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Global VOS context is Null", __func__);
14739 goto done;
14740 }
14741
14742 //Get the HDD context.
14743 pHddCtx = (hdd_context_t *)vos_get_context(VOS_MODULE_ID_HDD, pVosContext );
14744
14745 if(!pHddCtx)
14746 {
14747 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: module exit called before probe",__func__);
14748 }
Katya Nigame7b69a82015-04-28 15:24:06 +053014749 else if (VOS_MONITOR_MODE == hdd_get_conparam())
14750 {
14751 hddLog(VOS_TRACE_LEVEL_INFO,"%s: MONITOR MODE",__func__);
14752 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_UNLOAD_IN_PROGRESS;
14753 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, TRUE);
14754 hdd_wlan_exit(pHddCtx);
14755 vos_preClose( &pVosContext );
14756 goto done;
14757 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014758 else
14759 {
Siddharth Bhal2e5871b2015-03-24 16:20:51 +053014760 /* We wait for active entry threads to exit from driver
14761 * by waiting until rtnl_lock is available.
14762 */
14763 rtnl_lock();
14764 rtnl_unlock();
14765
Siddharth Bhal3c29dca2015-02-19 00:41:40 +053014766 INIT_COMPLETION(pHddCtx->ssr_comp_var);
14767 if ((pHddCtx->isLogpInProgress) && (FALSE ==
14768 vos_is_wlan_in_badState(VOS_MODULE_ID_HDD, NULL)))
14769 {
Siddharth Bhala204f572015-01-17 02:03:36 +053014770 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Siddharth Bhal3c29dca2015-02-19 00:41:40 +053014771 "%s:SSR in Progress; block rmmod !!!", __func__);
Siddharth Bhala204f572015-01-17 02:03:36 +053014772 rc = wait_for_completion_timeout(&pHddCtx->ssr_comp_var,
14773 msecs_to_jiffies(30000));
14774 if(!rc)
14775 {
14776 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
14777 "%s:SSR timedout, fatal error", __func__);
14778 VOS_BUG(0);
14779 }
14780 }
14781
Siddharth Bhal3c29dca2015-02-19 00:41:40 +053014782 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_UNLOAD_IN_PROGRESS;
14783 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, TRUE);
Jeff Johnson295189b2012-06-20 16:38:30 -070014784
c_hpothu8adb97b2014-12-08 19:38:20 +053014785 /* Driver Need to send country code 00 in below condition
14786 * 1) If gCountryCodePriority is set to 1; and last country
14787 * code set is through 11d. This needs to be done in case
14788 * when NV country code is 00.
14789 * This Needs to be done as when kernel store last country
14790 * code and if stored country code is not through 11d,
14791 * in sme_HandleChangeCountryCodeByUser we will disable 11d
14792 * in next load/unload as soon as we get any country through
14793 * 11d. In sme_HandleChangeCountryCodeByUser
14794 * pMsg->countryCode will be last countryCode and
14795 * pMac->scan.countryCode11d will be country through 11d so
14796 * due to mismatch driver will disable 11d.
14797 *
14798 */
Agarwal Ashish8db39882014-07-30 21:56:07 +053014799
c_hpothu8adb97b2014-12-08 19:38:20 +053014800 if ((eANI_BOOLEAN_TRUE == sme_Is11dCountrycode(pHddCtx->hHal) &&
Agarwal Ashish8dcd2862014-07-25 11:58:52 +053014801 pHddCtx->cfg_ini->fSupplicantCountryCodeHasPriority &&
Abhishek Singh2a705962014-10-30 14:47:28 +053014802 sme_Is11dSupported(pHddCtx->hHal)))
c_hpothu8adb97b2014-12-08 19:38:20 +053014803 {
14804 hddLog(VOS_TRACE_LEVEL_INFO,
Agarwal Ashish8dcd2862014-07-25 11:58:52 +053014805 FL("CountryCode 00 is being set while unloading driver"));
c_hpothu8adb97b2014-12-08 19:38:20 +053014806 vos_nv_getRegDomainFromCountryCode(&regId , "00", COUNTRY_USER);
14807 }
Agarwal Ashish5e414792014-06-08 15:25:23 +053014808
c_hpothu8adb97b2014-12-08 19:38:20 +053014809 //Do all the cleanup before deregistering the driver
14810 hdd_wlan_exit(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -070014811 }
14812
Jeff Johnson295189b2012-06-20 16:38:30 -070014813 vos_preClose( &pVosContext );
14814
14815#ifdef TIMER_MANAGER
14816 vos_timer_exit();
14817#endif
14818#ifdef MEMORY_DEBUG
14819 vos_mem_exit();
14820#endif
14821
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +053014822#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
14823 wlan_logging_sock_deinit_svc();
14824#endif
14825
Jeff Johnson295189b2012-06-20 16:38:30 -070014826done:
Sushant Kaushik83392fa2015-05-05 17:44:40 +053014827 vos_wake_lock_destroy(&wlan_wake_lock);
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +053014828
Jeff Johnson295189b2012-06-20 16:38:30 -070014829 pr_info("%s: driver unloaded\n", WLAN_MODULE_NAME);
14830}
14831
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070014832/**---------------------------------------------------------------------------
14833
14834 \brief hdd_module_exit() - Exit function
14835
14836 This is the driver exit point (invoked when module is unloaded using rmmod)
14837
14838 \param - None
14839
14840 \return - None
14841
14842 --------------------------------------------------------------------------*/
14843static void __exit hdd_module_exit(void)
14844{
14845 hdd_driver_exit();
14846}
14847
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070014848#ifdef MODULE
14849static int fwpath_changed_handler(const char *kmessage,
Ashish Kumar Dhanotiyafb3fd972018-04-30 12:46:52 +053014850 const struct kernel_param *kp)
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070014851{
Jeff Johnson76052702013-04-16 13:55:05 -070014852 return param_set_copystring(kmessage, kp);
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070014853}
14854
14855static int con_mode_handler(const char *kmessage,
Ashish Kumar Dhanotiyafb3fd972018-04-30 12:46:52 +053014856 const struct kernel_param *kp)
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070014857{
Madan Mohan Koyyalamudif2f8d8b2012-10-11 17:06:59 -070014858 return param_set_int(kmessage, kp);
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070014859}
14860#else /* #ifdef MODULE */
14861/**---------------------------------------------------------------------------
14862
Jeff Johnson76052702013-04-16 13:55:05 -070014863 \brief kickstart_driver
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070014864
Jeff Johnson76052702013-04-16 13:55:05 -070014865 This is the driver entry point
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070014866 - delayed driver initialization when driver is statically linked
Jeff Johnson76052702013-04-16 13:55:05 -070014867 - invoked when module parameter fwpath is modified from userspace to signal
14868 initializing the WLAN driver or when con_mode is modified from userspace
14869 to signal a switch in operating mode
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070014870
14871 \return - 0 for success, non zero for failure
14872
14873 --------------------------------------------------------------------------*/
Jeff Johnson76052702013-04-16 13:55:05 -070014874static int kickstart_driver(void)
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070014875{
Madan Mohan Koyyalamudi62e60052012-10-05 14:27:22 -070014876 int ret_status;
14877
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070014878 if (!wlan_hdd_inited) {
Madan Mohan Koyyalamudi62e60052012-10-05 14:27:22 -070014879 ret_status = hdd_driver_init();
14880 wlan_hdd_inited = ret_status ? 0 : 1;
14881 return ret_status;
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070014882 }
14883
14884 hdd_driver_exit();
Jeff Johnson76052702013-04-16 13:55:05 -070014885
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070014886 msleep(200);
Jeff Johnson76052702013-04-16 13:55:05 -070014887
Madan Mohan Koyyalamudi62e60052012-10-05 14:27:22 -070014888 ret_status = hdd_driver_init();
14889 wlan_hdd_inited = ret_status ? 0 : 1;
14890 return ret_status;
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070014891}
14892
Jeff Johnson295189b2012-06-20 16:38:30 -070014893/**---------------------------------------------------------------------------
14894
Jeff Johnson76052702013-04-16 13:55:05 -070014895 \brief fwpath_changed_handler() - Handler Function
14896
14897 Handle changes to the fwpath parameter
14898
14899 \return - 0 for success, non zero for failure
14900
14901 --------------------------------------------------------------------------*/
14902static int fwpath_changed_handler(const char *kmessage,
Ashish Kumar Dhanotiyafb3fd972018-04-30 12:46:52 +053014903 const struct kernel_param *kp)
Jeff Johnson76052702013-04-16 13:55:05 -070014904{
14905 int ret;
14906
14907 ret = param_set_copystring(kmessage, kp);
14908 if (0 == ret)
14909 ret = kickstart_driver();
14910 return ret;
14911}
14912
14913/**---------------------------------------------------------------------------
14914
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070014915 \brief con_mode_handler() -
14916
14917 Handler function for module param con_mode when it is changed by userspace
14918 Dynamically linked - do nothing
14919 Statically linked - exit and init driver, as in rmmod and insmod
14920
Jeff Johnson76052702013-04-16 13:55:05 -070014921 \param -
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070014922
Jeff Johnson76052702013-04-16 13:55:05 -070014923 \return -
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070014924
14925 --------------------------------------------------------------------------*/
Ashish Kumar Dhanotiyafb3fd972018-04-30 12:46:52 +053014926static int con_mode_handler(const char *kmessage,
14927 const struct kernel_param *kp)
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070014928{
Jeff Johnson76052702013-04-16 13:55:05 -070014929 int ret;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070014930
Jeff Johnson76052702013-04-16 13:55:05 -070014931 ret = param_set_int(kmessage, kp);
14932 if (0 == ret)
14933 ret = kickstart_driver();
14934 return ret;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070014935}
14936#endif /* #ifdef MODULE */
14937
14938/**---------------------------------------------------------------------------
14939
Jeff Johnson295189b2012-06-20 16:38:30 -070014940 \brief hdd_get_conparam() -
14941
14942 This is the driver exit point (invoked when module is unloaded using rmmod)
14943
14944 \param - None
14945
14946 \return - tVOS_CON_MODE
14947
14948 --------------------------------------------------------------------------*/
14949tVOS_CON_MODE hdd_get_conparam ( void )
14950{
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070014951#ifdef MODULE
Jeff Johnson295189b2012-06-20 16:38:30 -070014952 return (tVOS_CON_MODE)con_mode;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070014953#else
14954 return (tVOS_CON_MODE)curr_con_mode;
14955#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070014956}
14957void hdd_set_conparam ( v_UINT_t newParam )
14958{
14959 con_mode = newParam;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070014960#ifndef MODULE
14961 curr_con_mode = con_mode;
14962#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070014963}
14964/**---------------------------------------------------------------------------
14965
14966 \brief hdd_softap_sta_deauth() - function
14967
14968 This to take counter measure to handle deauth req from HDD
14969
14970 \param - pAdapter - Pointer to the HDD
14971
14972 \param - enable - boolean value
14973
14974 \return - None
14975
14976 --------------------------------------------------------------------------*/
14977
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053014978VOS_STATUS hdd_softap_sta_deauth(hdd_adapter_t *pAdapter,
14979 struct tagCsrDelStaParams *pDelStaParams)
Jeff Johnson295189b2012-06-20 16:38:30 -070014980{
Jeff Johnson295189b2012-06-20 16:38:30 -070014981 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080014982 VOS_STATUS vosStatus = VOS_STATUS_E_FAULT;
Hanumanth Reddy Pothula57323632017-12-06 17:55:09 +053014983 struct hdd_cache_sta_info *cache_sta_info;
14984 ptSapContext pSapCtx = VOS_GET_SAP_CB(pVosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -070014985
14986 ENTER();
14987
Jeff Johnsonc135a9a2017-09-19 08:37:24 -070014988 hddLog(LOG1, "hdd_softap_sta_deauth:(%pK, false)",
Rajesh Chauhan18488fc2013-08-22 10:15:03 -070014989 (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -070014990
Hanumanth Reddy Pothula57323632017-12-06 17:55:09 +053014991 if (!pSapCtx) {
14992 hddLog(LOGE, "sap context is NULL");
14993 return vosStatus;
14994 }
14995
14996 cache_sta_info = hdd_get_cache_stainfo(pSapCtx->cache_sta_info,
14997 pDelStaParams->peerMacAddr);
14998 if (cache_sta_info) {
14999 cache_sta_info->reason_code = pDelStaParams->reason_code;
15000 cache_sta_info->rx_rate =
15001 wlan_tl_get_sta_rx_rate(pVosContext, cache_sta_info->ucSTAId);
15002 WLANTL_GetSAPStaRSSi(pVosContext, cache_sta_info->ucSTAId,
15003 &cache_sta_info->rssi);
15004 }
15005
Jeff Johnson295189b2012-06-20 16:38:30 -070015006 //Ignore request to deauth bcmc station
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053015007 if (pDelStaParams->peerMacAddr[0] & 0x1)
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080015008 return vosStatus;
Jeff Johnson295189b2012-06-20 16:38:30 -070015009
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053015010 vosStatus = WLANSAP_DeauthSta(pVosContext, pDelStaParams);
Jeff Johnson295189b2012-06-20 16:38:30 -070015011
15012 EXIT();
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080015013 return vosStatus;
Jeff Johnson295189b2012-06-20 16:38:30 -070015014}
15015
15016/**---------------------------------------------------------------------------
15017
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +053015018 \brief hdd_del_all_sta() - function
15019
15020 This function removes all the stations associated on stopping AP/P2P GO.
15021
15022 \param - pAdapter - Pointer to the HDD
15023
15024 \return - None
15025
15026 --------------------------------------------------------------------------*/
15027
15028int hdd_del_all_sta(hdd_adapter_t *pAdapter)
15029{
15030 v_U16_t i;
15031 VOS_STATUS vos_status;
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053015032 v_CONTEXT_t pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
15033 ptSapContext pSapCtx = NULL;
15034 pSapCtx = VOS_GET_SAP_CB(pVosContext);
15035 if(pSapCtx == NULL){
15036 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15037 FL("psapCtx is NULL"));
15038 return 1;
15039 }
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +053015040 ENTER();
15041
15042 hddLog(VOS_TRACE_LEVEL_INFO,
15043 "%s: Delete all STAs associated.",__func__);
15044 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
15045 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
15046 )
15047 {
15048 for(i = 0; i < WLAN_MAX_STA_COUNT; i++)
15049 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053015050 if ((pSapCtx->aStaInfo[i].isUsed) &&
15051 (!pSapCtx->aStaInfo[i].isDeauthInProgress))
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +053015052 {
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053015053 struct tagCsrDelStaParams delStaParams;
15054
15055 WLANSAP_PopulateDelStaParams(
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053015056 pSapCtx->aStaInfo[i].macAddrSTA.bytes,
Sushant Kaushik4cd28f62014-12-26 14:23:50 +053015057 eSIR_MAC_DEAUTH_LEAVING_BSS_REASON,
15058 SIR_MAC_MGMT_DEAUTH >> 4,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053015059 &delStaParams);
15060 vos_status = hdd_softap_sta_deauth(pAdapter, &delStaParams);
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +053015061 if (VOS_IS_STATUS_SUCCESS(vos_status))
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053015062 pSapCtx->aStaInfo[i].isDeauthInProgress = TRUE;
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +053015063 }
15064 }
15065 }
15066
15067 EXIT();
15068 return 0;
15069}
15070
15071/**---------------------------------------------------------------------------
15072
Jeff Johnson295189b2012-06-20 16:38:30 -070015073 \brief hdd_softap_sta_disassoc() - function
15074
15075 This to take counter measure to handle deauth req from HDD
15076
15077 \param - pAdapter - Pointer to the HDD
15078
15079 \param - enable - boolean value
15080
15081 \return - None
15082
15083 --------------------------------------------------------------------------*/
15084
15085void hdd_softap_sta_disassoc(hdd_adapter_t *pAdapter,v_U8_t *pDestMacAddress)
15086{
Hanumanth Reddy Pothula57323632017-12-06 17:55:09 +053015087 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
15088 struct hdd_cache_sta_info *cache_sta_info;
15089 ptSapContext pSapCtx = VOS_GET_SAP_CB(pVosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -070015090
15091 ENTER();
15092
Jeff Johnsonc135a9a2017-09-19 08:37:24 -070015093 hddLog( LOGE, "hdd_softap_sta_disassoc:(%pK, false)", (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -070015094
Hanumanth Reddy Pothula57323632017-12-06 17:55:09 +053015095 if (!pSapCtx) {
15096 hddLog(LOGE, "sap context is NULL");
15097 return ;
15098 }
15099
Jeff Johnson295189b2012-06-20 16:38:30 -070015100 //Ignore request to disassoc bcmc station
15101 if( pDestMacAddress[0] & 0x1 )
15102 return;
15103
Hanumanth Reddy Pothula57323632017-12-06 17:55:09 +053015104 cache_sta_info = hdd_get_cache_stainfo(pSapCtx->cache_sta_info,
15105 pDestMacAddress);
15106 if (cache_sta_info) {
15107 cache_sta_info->reason_code = eSIR_MAC_DEAUTH_LEAVING_BSS_REASON;
15108 cache_sta_info->rx_rate =
15109 wlan_tl_get_sta_rx_rate(pVosContext, cache_sta_info->ucSTAId);
15110 WLANTL_GetSAPStaRSSi(pVosContext, cache_sta_info->ucSTAId,
15111 &cache_sta_info->rssi);
15112 }
15113
Jeff Johnson295189b2012-06-20 16:38:30 -070015114 WLANSAP_DisassocSta(pVosContext,pDestMacAddress);
15115}
15116
15117void hdd_softap_tkip_mic_fail_counter_measure(hdd_adapter_t *pAdapter,v_BOOL_t enable)
15118{
15119 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
15120
15121 ENTER();
15122
Jeff Johnsonc135a9a2017-09-19 08:37:24 -070015123 hddLog( LOGE, "hdd_softap_tkip_mic_fail_counter_measure:(%pK, false)", (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -070015124
15125 WLANSAP_SetCounterMeasure(pVosContext, (v_BOOL_t)enable);
15126}
15127
Jeff Johnson295189b2012-06-20 16:38:30 -070015128/**---------------------------------------------------------------------------
15129 *
15130 * \brief hdd_get__concurrency_mode() -
15131 *
15132 *
15133 * \param - None
15134 *
15135 * \return - CONCURRENCY MODE
15136 *
15137 * --------------------------------------------------------------------------*/
15138tVOS_CONCURRENCY_MODE hdd_get_concurrency_mode ( void )
15139{
15140 v_CONTEXT_t pVosContext = vos_get_global_context( VOS_MODULE_ID_HDD, NULL );
15141 hdd_context_t *pHddCtx;
15142
15143 if (NULL != pVosContext)
15144 {
15145 pHddCtx = vos_get_context( VOS_MODULE_ID_HDD, pVosContext);
15146 if (NULL != pHddCtx)
15147 {
15148 return (tVOS_CONCURRENCY_MODE)pHddCtx->concurrency_mode;
15149 }
15150 }
15151
15152 /* we are in an invalid state :( */
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070015153 hddLog(LOGE, "%s: Invalid context", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070015154 return VOS_STA;
15155}
Sushant Kaushikabb7ee62014-07-18 16:20:12 +053015156v_BOOL_t
15157wlan_hdd_is_GO_power_collapse_allowed (hdd_context_t* pHddCtx)
15158{
15159 hdd_adapter_t *pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070015160
Sushant Kaushikabb7ee62014-07-18 16:20:12 +053015161 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_GO);
15162 if (pAdapter == NULL)
15163 {
15164 hddLog(VOS_TRACE_LEVEL_INFO,
15165 FL("GO doesn't exist"));
15166 return TRUE;
15167 }
15168 if (test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
15169 {
15170 hddLog(VOS_TRACE_LEVEL_INFO,
15171 FL("GO started"));
15172 return TRUE;
15173 }
15174 else
15175 /* wait till GO changes its interface to p2p device */
15176 hddLog(VOS_TRACE_LEVEL_INFO,
15177 FL("Del_bss called, avoid apps suspend"));
15178 return FALSE;
15179
15180}
Jeff Johnson295189b2012-06-20 16:38:30 -070015181/* Decide whether to allow/not the apps power collapse.
15182 * Allow apps power collapse if we are in connected state.
15183 * if not, allow only if we are in IMPS */
15184v_BOOL_t hdd_is_apps_power_collapse_allowed(hdd_context_t* pHddCtx)
15185{
15186 tPmcState pmcState = pmcGetPmcState(pHddCtx->hHal);
Srikant Kuppafef66a72013-01-30 17:32:44 -080015187 tANI_BOOLEAN scanRspPending = csrNeighborRoamScanRspPending(pHddCtx->hHal);
Srinivas Girigowdaa553c462013-03-07 19:42:52 -080015188 tANI_BOOLEAN inMiddleOfRoaming = csrNeighborMiddleOfRoaming(pHddCtx->hHal);
Jeff Johnson295189b2012-06-20 16:38:30 -070015189 hdd_config_t *pConfig = pHddCtx->cfg_ini;
15190 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
15191 hdd_adapter_t *pAdapter = NULL;
15192 VOS_STATUS status;
Yathish9f22e662012-12-10 14:21:35 -080015193 tVOS_CONCURRENCY_MODE concurrent_state = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070015194
Jeff Johnson295189b2012-06-20 16:38:30 -070015195 if (VOS_STA_SAP_MODE == hdd_get_conparam())
15196 return TRUE;
Jeff Johnson295189b2012-06-20 16:38:30 -070015197
Yathish9f22e662012-12-10 14:21:35 -080015198 concurrent_state = hdd_get_concurrency_mode();
15199
Sushant Kaushikabb7ee62014-07-18 16:20:12 +053015200 if ((concurrent_state == (VOS_STA | VOS_P2P_GO)) &&
15201 !(wlan_hdd_is_GO_power_collapse_allowed(pHddCtx)))
15202 return FALSE;
Yathish9f22e662012-12-10 14:21:35 -080015203#ifdef WLAN_ACTIVEMODE_OFFLOAD_FEATURE
Sushant Kaushikabb7ee62014-07-18 16:20:12 +053015204
Yathish9f22e662012-12-10 14:21:35 -080015205 if(((concurrent_state == (VOS_STA | VOS_P2P_CLIENT)) ||
Sushant Kaushikabb7ee62014-07-18 16:20:12 +053015206 (concurrent_state == (VOS_STA | VOS_P2P_GO)))&&
Yathish9f22e662012-12-10 14:21:35 -080015207 (IS_ACTIVEMODE_OFFLOAD_FEATURE_ENABLE))
15208 return TRUE;
15209#endif
15210
Jeff Johnson295189b2012-06-20 16:38:30 -070015211 /*loop through all adapters. TBD fix for Concurrency */
15212 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
15213 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
15214 {
15215 pAdapter = pAdapterNode->pAdapter;
15216 if ( (WLAN_HDD_INFRA_STATION == pAdapter->device_mode)
15217 || (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
15218 {
Srikant Kuppafef66a72013-01-30 17:32:44 -080015219 if (((pConfig->fIsImpsEnabled || pConfig->fIsBmpsEnabled)
c_hpothu4e8faac2014-05-16 17:38:44 +053015220 && (pmcState != IMPS && pmcState != BMPS && pmcState != UAPSD
c_hpothu1c6957d2015-01-06 18:19:47 +053015221 && pmcState != STOPPED && pmcState != STANDBY &&
15222 pmcState != WOWL)) ||
Srinivas Girigowdaa553c462013-03-07 19:42:52 -080015223 (eANI_BOOLEAN_TRUE == scanRspPending) ||
15224 (eANI_BOOLEAN_TRUE == inMiddleOfRoaming))
Jeff Johnson295189b2012-06-20 16:38:30 -070015225 {
Mukul Sharma4be88422015-03-09 20:29:07 +053015226 if(pmcState == FULL_POWER &&
15227 sme_IsCoexScoIndicationSet(pHddCtx->hHal))
15228 {
15229 /*
15230 * When SCO indication comes from Coex module , host will
15231 * enter in to full power mode, but this should not prevent
15232 * apps processor power collapse.
15233 */
15234 hddLog(LOG1,
15235 FL("Allow apps power collapse"
15236 "even when sco indication is set"));
15237 return TRUE;
15238 }
Srikant Kuppafef66a72013-01-30 17:32:44 -080015239 hddLog( LOGE, "%s: do not allow APPS power collapse-"
Deepthi Gowri03a979f2016-11-03 15:20:19 +053015240 "pmcState = %d scanRspPending = %d "
15241 "inMiddleOfRoaming = %d connected = %d",
15242 __func__, pmcState, scanRspPending,
15243 inMiddleOfRoaming, hdd_connIsConnected(
15244 WLAN_HDD_GET_STATION_CTX_PTR( pAdapter )));
15245 wlan_hdd_get_tdls_stats(pAdapter);
15246 return FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070015247 }
15248 }
15249 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
15250 pAdapterNode = pNext;
15251 }
15252 return TRUE;
15253}
15254
Madan Mohan Koyyalamudic72a4d62012-11-08 14:59:34 -080015255/* Decides whether to send suspend notification to Riva
15256 * if any adapter is in BMPS; then it is required */
15257v_BOOL_t hdd_is_suspend_notify_allowed(hdd_context_t* pHddCtx)
15258{
15259 tPmcState pmcState = pmcGetPmcState(pHddCtx->hHal);
15260 hdd_config_t *pConfig = pHddCtx->cfg_ini;
15261
15262 if (pConfig->fIsBmpsEnabled && (pmcState == BMPS))
15263 {
15264 return TRUE;
15265 }
15266 return FALSE;
15267}
15268
Jeff Johnson295189b2012-06-20 16:38:30 -070015269void wlan_hdd_set_concurrency_mode(hdd_context_t *pHddCtx, tVOS_CON_MODE mode)
15270{
15271 switch(mode)
15272 {
Chilam Ngc4244af2013-04-01 15:37:32 -070015273 case VOS_STA_MODE:
15274 case VOS_P2P_CLIENT_MODE:
15275 case VOS_P2P_GO_MODE:
15276 case VOS_STA_SAP_MODE:
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +053015277 case VOS_MONITOR_MODE:
Jeff Johnsone7245742012-09-05 17:12:55 -070015278 pHddCtx->concurrency_mode |= (1 << mode);
Agarwal Ashish51325b52014-06-16 16:50:49 +053015279 pHddCtx->no_of_open_sessions[mode]++;
Jeff Johnson295189b2012-06-20 16:38:30 -070015280 break;
15281 default:
15282 break;
Jeff Johnson295189b2012-06-20 16:38:30 -070015283 }
Agarwal Ashish51325b52014-06-16 16:50:49 +053015284 hddLog(VOS_TRACE_LEVEL_INFO, FL("concurrency_mode = 0x%x "
15285 "Number of open sessions for mode %d = %d"),
15286 pHddCtx->concurrency_mode, mode,
15287 pHddCtx->no_of_open_sessions[mode]);
Jeff Johnson295189b2012-06-20 16:38:30 -070015288}
15289
15290
15291void wlan_hdd_clear_concurrency_mode(hdd_context_t *pHddCtx, tVOS_CON_MODE mode)
15292{
15293 switch(mode)
15294 {
Chilam Ngc4244af2013-04-01 15:37:32 -070015295 case VOS_STA_MODE:
15296 case VOS_P2P_CLIENT_MODE:
15297 case VOS_P2P_GO_MODE:
15298 case VOS_STA_SAP_MODE:
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +053015299 case VOS_MONITOR_MODE:
Agarwal Ashish51325b52014-06-16 16:50:49 +053015300 pHddCtx->no_of_open_sessions[mode]--;
15301 if (!(pHddCtx->no_of_open_sessions[mode]))
15302 pHddCtx->concurrency_mode &= (~(1 << mode));
Jeff Johnson295189b2012-06-20 16:38:30 -070015303 break;
15304 default:
15305 break;
15306 }
Agarwal Ashish51325b52014-06-16 16:50:49 +053015307 hddLog(VOS_TRACE_LEVEL_INFO, FL("concurrency_mode = 0x%x "
15308 "Number of open sessions for mode %d = %d"),
15309 pHddCtx->concurrency_mode, mode, pHddCtx->no_of_open_sessions[mode]);
15310
15311}
15312/**---------------------------------------------------------------------------
15313 *
15314 * \brief wlan_hdd_incr_active_session()
15315 *
15316 * This function increments the number of active sessions
15317 * maintained per device mode
15318 * Incase of STA/P2P CLI/IBSS upon connection indication it is incremented
15319 * Incase of SAP/P2P GO upon bss start it is incremented
15320 *
15321 * \param pHddCtx - HDD Context
15322 * \param mode - device mode
15323 *
15324 * \return - None
15325 *
15326 * --------------------------------------------------------------------------*/
15327void wlan_hdd_incr_active_session(hdd_context_t *pHddCtx, tVOS_CON_MODE mode)
15328{
15329 switch (mode) {
15330 case VOS_STA_MODE:
15331 case VOS_P2P_CLIENT_MODE:
15332 case VOS_P2P_GO_MODE:
15333 case VOS_STA_SAP_MODE:
15334 pHddCtx->no_of_active_sessions[mode]++;
15335 break;
15336 default:
15337 hddLog(VOS_TRACE_LEVEL_INFO, FL("Not Expected Mode %d"), mode);
15338 break;
15339 }
15340 hddLog(VOS_TRACE_LEVEL_INFO, FL("No.# of active sessions for mode %d = %d"),
15341 mode,
15342 pHddCtx->no_of_active_sessions[mode]);
15343}
15344
15345/**---------------------------------------------------------------------------
15346 *
15347 * \brief wlan_hdd_decr_active_session()
15348 *
15349 * This function decrements the number of active sessions
15350 * maintained per device mode
15351 * Incase of STA/P2P CLI/IBSS upon disconnection it is decremented
15352 * Incase of SAP/P2P GO upon bss stop it is decremented
15353 *
15354 * \param pHddCtx - HDD Context
15355 * \param mode - device mode
15356 *
15357 * \return - None
15358 *
15359 * --------------------------------------------------------------------------*/
15360void wlan_hdd_decr_active_session(hdd_context_t *pHddCtx, tVOS_CON_MODE mode)
15361{
Bhargav Shahd0715912015-10-01 18:17:37 +053015362
Agarwal Ashish51325b52014-06-16 16:50:49 +053015363 switch (mode) {
15364 case VOS_STA_MODE:
15365 case VOS_P2P_CLIENT_MODE:
15366 case VOS_P2P_GO_MODE:
15367 case VOS_STA_SAP_MODE:
Agarwal Ashish5325f522014-08-06 00:58:44 +053015368 if (pHddCtx->no_of_active_sessions[mode] > 0)
15369 pHddCtx->no_of_active_sessions[mode]--;
15370 else
15371 hddLog(VOS_TRACE_LEVEL_INFO, FL(" No.# of Active sessions"
15372 "is already Zero"));
Agarwal Ashish51325b52014-06-16 16:50:49 +053015373 break;
15374 default:
15375 hddLog(VOS_TRACE_LEVEL_INFO, FL("Not Expected Mode %d"), mode);
15376 break;
15377 }
15378 hddLog(VOS_TRACE_LEVEL_INFO, FL("No.# of active sessions for mode %d = %d"),
15379 mode,
15380 pHddCtx->no_of_active_sessions[mode]);
Jeff Johnson295189b2012-06-20 16:38:30 -070015381}
15382
Jeff Johnsone7245742012-09-05 17:12:55 -070015383/**---------------------------------------------------------------------------
15384 *
15385 * \brief wlan_hdd_restart_init
15386 *
15387 * This function initalizes restart timer/flag. An internal function.
15388 *
15389 * \param - pHddCtx
15390 *
15391 * \return - None
15392 *
15393 * --------------------------------------------------------------------------*/
15394
15395static void wlan_hdd_restart_init(hdd_context_t *pHddCtx)
15396{
15397 /* Initialize */
15398 pHddCtx->hdd_restart_retries = 0;
15399 atomic_set(&pHddCtx->isRestartInProgress, 0);
15400 vos_timer_init(&pHddCtx->hdd_restart_timer,
15401 VOS_TIMER_TYPE_SW,
15402 wlan_hdd_restart_timer_cb,
15403 pHddCtx);
15404}
15405/**---------------------------------------------------------------------------
15406 *
15407 * \brief wlan_hdd_restart_deinit
15408 *
15409 * This function cleans up the resources used. An internal function.
15410 *
15411 * \param - pHddCtx
15412 *
15413 * \return - None
15414 *
15415 * --------------------------------------------------------------------------*/
15416
15417static void wlan_hdd_restart_deinit(hdd_context_t* pHddCtx)
15418{
15419
15420 VOS_STATUS vos_status;
15421 /* Block any further calls */
15422 atomic_set(&pHddCtx->isRestartInProgress, 1);
15423 /* Cleanup */
15424 vos_status = vos_timer_stop( &pHddCtx->hdd_restart_timer );
15425 if (!VOS_IS_STATUS_SUCCESS(vos_status))
c_hpothu6ff1c3c2013-10-01 19:01:57 +053015426 hddLog(LOGE, FL("Failed to stop HDD restart timer"));
Jeff Johnsone7245742012-09-05 17:12:55 -070015427 vos_status = vos_timer_destroy(&pHddCtx->hdd_restart_timer);
15428 if (!VOS_IS_STATUS_SUCCESS(vos_status))
c_hpothu6ff1c3c2013-10-01 19:01:57 +053015429 hddLog(LOGE, FL("Failed to destroy HDD restart timer"));
Jeff Johnsone7245742012-09-05 17:12:55 -070015430
15431}
15432
15433/**---------------------------------------------------------------------------
15434 *
15435 * \brief wlan_hdd_framework_restart
15436 *
15437 * This function uses a cfg80211 API to start a framework initiated WLAN
15438 * driver module unload/load.
15439 *
15440 * Also this API keep retrying (WLAN_HDD_RESTART_RETRY_MAX_CNT).
15441 *
15442 *
15443 * \param - pHddCtx
15444 *
15445 * \return - VOS_STATUS_SUCCESS: Success
15446 * VOS_STATUS_E_EMPTY: Adapter is Empty
15447 * VOS_STATUS_E_NOMEM: No memory
15448
15449 * --------------------------------------------------------------------------*/
15450
15451static VOS_STATUS wlan_hdd_framework_restart(hdd_context_t *pHddCtx)
15452{
15453 VOS_STATUS status = VOS_STATUS_SUCCESS;
15454 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
Madan Mohan Koyyalamudifc19e442013-05-09 18:24:08 -070015455 int len = (sizeof (struct ieee80211_mgmt));
15456 struct ieee80211_mgmt *mgmt = NULL;
15457
15458 /* Prepare the DEAUTH managment frame with reason code */
15459 mgmt = kzalloc(len, GFP_KERNEL);
15460 if(mgmt == NULL)
15461 {
15462 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
15463 "%s: memory allocation failed (%d bytes)", __func__, len);
15464 return VOS_STATUS_E_NOMEM;
15465 }
15466 mgmt->u.deauth.reason_code = WLAN_REASON_DISASSOC_LOW_ACK;
Jeff Johnsone7245742012-09-05 17:12:55 -070015467
15468 /* Iterate over all adapters/devices */
15469 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
Hanumantha Reddy Pothulada0fe362015-02-27 18:37:03 +053015470 if ((NULL == pAdapterNode) || (VOS_STATUS_SUCCESS != status))
15471 {
15472 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnsonc135a9a2017-09-19 08:37:24 -070015473 FL("fail to get adapter: %pK %d"), pAdapterNode, status);
Hanumantha Reddy Pothulada0fe362015-02-27 18:37:03 +053015474 goto end;
15475 }
15476
Jeff Johnsone7245742012-09-05 17:12:55 -070015477 do
15478 {
Hanumantha Reddy Pothulada0fe362015-02-27 18:37:03 +053015479 if(pAdapterNode->pAdapter &&
15480 WLAN_HDD_ADAPTER_MAGIC == pAdapterNode->pAdapter->magic)
Jeff Johnsone7245742012-09-05 17:12:55 -070015481 {
15482 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
15483 "restarting the driver(intf:\'%s\' mode:%d :try %d)",
15484 pAdapterNode->pAdapter->dev->name,
15485 pAdapterNode->pAdapter->device_mode,
15486 pHddCtx->hdd_restart_retries + 1);
Madan Mohan Koyyalamudifc19e442013-05-09 18:24:08 -070015487 /*
15488 * CFG80211 event to restart the driver
15489 *
15490 * 'cfg80211_send_unprot_deauth' sends a
15491 * NL80211_CMD_UNPROT_DEAUTHENTICATE event to supplicant at any state
15492 * of SME(Linux Kernel) state machine.
15493 *
15494 * Reason code WLAN_REASON_DISASSOC_LOW_ACK is currently used to restart
15495 * the driver.
15496 *
15497 */
Abhishek Singh00b71972016-01-07 10:51:04 +053015498
Anand N Sunkade9adb1b2015-07-29 09:56:45 +053015499#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 11, 0))
15500 cfg80211_rx_unprot_mlme_mgmt(pAdapterNode->pAdapter->dev, (u_int8_t*)mgmt, len);
15501#else
Madan Mohan Koyyalamudifc19e442013-05-09 18:24:08 -070015502 cfg80211_send_unprot_deauth(pAdapterNode->pAdapter->dev, (u_int8_t*)mgmt, len );
Anand N Sunkade9adb1b2015-07-29 09:56:45 +053015503#endif
Jeff Johnsone7245742012-09-05 17:12:55 -070015504 }
15505 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
15506 pAdapterNode = pNext;
15507 } while((NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status));
15508
Hanumantha Reddy Pothulada0fe362015-02-27 18:37:03 +053015509 end:
Madan Mohan Koyyalamudifc19e442013-05-09 18:24:08 -070015510 /* Free the allocated management frame */
15511 kfree(mgmt);
15512
Jeff Johnsone7245742012-09-05 17:12:55 -070015513 /* Retry until we unload or reach max count */
15514 if(++pHddCtx->hdd_restart_retries < WLAN_HDD_RESTART_RETRY_MAX_CNT)
15515 vos_timer_start(&pHddCtx->hdd_restart_timer, WLAN_HDD_RESTART_RETRY_DELAY_MS);
15516
15517 return status;
15518
15519}
15520/**---------------------------------------------------------------------------
15521 *
15522 * \brief wlan_hdd_restart_timer_cb
15523 *
15524 * Restart timer callback. An internal function.
15525 *
15526 * \param - User data:
15527 *
15528 * \return - None
15529 *
15530 * --------------------------------------------------------------------------*/
15531
15532void wlan_hdd_restart_timer_cb(v_PVOID_t usrDataForCallback)
15533{
15534 hdd_context_t *pHddCtx = usrDataForCallback;
15535 wlan_hdd_framework_restart(pHddCtx);
15536 return;
15537
15538}
15539
15540
15541/**---------------------------------------------------------------------------
15542 *
15543 * \brief wlan_hdd_restart_driver
15544 *
15545 * This function sends an event to supplicant to restart the WLAN driver.
15546 *
15547 * This function is called from vos_wlanRestart.
15548 *
15549 * \param - pHddCtx
15550 *
15551 * \return - VOS_STATUS_SUCCESS: Success
15552 * VOS_STATUS_E_EMPTY: Adapter is Empty
15553 * VOS_STATUS_E_ALREADY: Request already in progress
15554
15555 * --------------------------------------------------------------------------*/
15556VOS_STATUS wlan_hdd_restart_driver(hdd_context_t *pHddCtx)
15557{
15558 VOS_STATUS status = VOS_STATUS_SUCCESS;
15559
15560 /* A tight check to make sure reentrancy */
15561 if(atomic_xchg(&pHddCtx->isRestartInProgress, 1))
15562 {
Mihir Shetefd528652014-06-23 19:07:50 +053015563 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnsone7245742012-09-05 17:12:55 -070015564 "%s: WLAN restart is already in progress", __func__);
15565
15566 return VOS_STATUS_E_ALREADY;
15567 }
Sameer Thalappil0c164f52013-03-28 15:27:56 -070015568 /* Send reset FIQ to WCNSS to invoke SSR. */
Madan Mohan Koyyalamudie388b342012-11-08 15:03:16 -080015569#ifdef HAVE_WCNSS_RESET_INTR
Siddharth Bhal864e7e82015-04-07 20:07:24 +053015570 wcnss_reset_fiq(TRUE);
Madan Mohan Koyyalamudibb8f0172012-09-28 15:36:06 -070015571#endif
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -070015572
Jeff Johnsone7245742012-09-05 17:12:55 -070015573 return status;
15574}
15575
Bhargav Shahd0715912015-10-01 18:17:37 +053015576/**
15577 * hdd_get_total_sessions() - provide total number of active sessions
15578 * @pHddCtx: Valid Global HDD context pointer
15579 *
15580 * This function iterates through pAdaptors and find the number of all active
15581 * sessions. This active sessions includes connected sta, p2p client and number
15582 * of client connected to sap/p2p go.
15583 *
15584 * Return: Total number of active sessions.
15585 */
15586v_U8_t hdd_get_total_sessions(hdd_context_t *pHddCtx)
15587{
15588 v_U8_t active_session = 0;
15589 hdd_station_ctx_t *pHddStaCtx;
15590 hdd_adapter_list_node_t *pAdapterNode, *pNext;
15591 hdd_adapter_t *pAdapter;
15592 VOS_STATUS status;
15593
15594 status = hdd_get_front_adapter(pHddCtx, &pAdapterNode);
15595 while (NULL != pAdapterNode && VOS_STATUS_SUCCESS == status) {
15596 pAdapter = pAdapterNode->pAdapter;
15597 switch (pAdapter->device_mode) {
15598 case VOS_STA_MODE:
15599 case VOS_P2P_CLIENT_MODE:
15600 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
15601 if(eConnectionState_Associated == pHddStaCtx->conn_info.connState)
15602 active_session += 1;
15603 break;
15604 case VOS_STA_SAP_MODE:
15605 case VOS_P2P_GO_MODE:
15606 active_session += hdd_softap_get_connected_sta(pAdapter);
15607 break;
15608 default:
15609 break;
15610 }
15611
15612 status = hdd_get_next_adapter(pHddCtx, pAdapterNode, &pNext);
15613 pAdapterNode = pNext;
15614 }
15615
15616 return active_session;
15617}
15618
15619/**
15620 * hdd_set_delack_value() - Set delack value
15621 * @pHddCtx: Valid Global HDD context pointer
15622 * @next_rx_level: Value to set for delack
15623 *
15624 * This function compare present value and next value of delack. If the both
15625 * are diffrent then it sets next value .
15626 *
15627 * Return: void.
15628 */
15629void hdd_set_delack_value(hdd_context_t *pHddCtx, v_U32_t next_rx_level)
15630{
15631 if (pHddCtx->cur_rx_level != next_rx_level) {
Alok Kumarf3724462018-04-05 15:18:54 +053015632 struct wlan_rx_tp_data rx_tp_data = {0};
15633
Bhargav Shahd0715912015-10-01 18:17:37 +053015634 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_DEBUG,
15635 "%s: TCP DELACK trigger level %d",
15636 __func__, next_rx_level);
15637 mutex_lock(&pHddCtx->cur_rx_level_lock);
15638 pHddCtx->cur_rx_level = next_rx_level;
15639 mutex_unlock(&pHddCtx->cur_rx_level_lock);
Alok Kumarf3724462018-04-05 15:18:54 +053015640
15641 rx_tp_data.rx_tp_flags |= TCP_DEL_ACK_IND;
15642 rx_tp_data.level = next_rx_level;
15643
15644 wlan_hdd_send_svc_nlink_msg(WLAN_SVC_WLAN_TP_IND, &rx_tp_data,
15645 sizeof(rx_tp_data));
Bhargav Shahd0715912015-10-01 18:17:37 +053015646 }
15647}
15648
15649/**
15650 * hdd_set_default_stop_delack_timer() - Start delack timer
15651 * @pHddCtx: Valid Global HDD context pointer
15652 *
15653 * This function stop delack timer and set delack value to default..
15654 *
15655 * Return: void.
15656 */
15657
15658void hdd_set_default_stop_delack_timer(hdd_context_t *pHddCtx)
15659{
15660 if (VOS_TIMER_STATE_RUNNING !=
15661 vos_timer_getCurrentState(&pHddCtx->delack_timer)) {
15662 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_DEBUG,
15663 "%s: Can not stop timer", __func__);
15664 return;
15665 }
15666
15667 vos_timer_stop(&pHddCtx->delack_timer);
Alok Kumarf3724462018-04-05 15:18:54 +053015668 hdd_set_delack_value(pHddCtx, WLAN_SVC_TP_LOW);
Bhargav Shahd0715912015-10-01 18:17:37 +053015669}
15670
15671/**
15672 * hdd_start_delack_timer() - Start delack timer
15673 * @pHddCtx: Valid Global HDD context pointer
15674 *
15675 * This function starts the delack timer for tcpDelAckComputeInterval time
15676 * interval.The default timer value is 2 second.
15677 *
15678 * Return: void.
15679 */
15680void hdd_start_delack_timer(hdd_context_t *pHddCtx)
15681{
15682 if (VOS_TIMER_STATE_RUNNING ==
15683 vos_timer_getCurrentState(&pHddCtx->delack_timer)) {
15684 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_DEBUG,
15685 "%s: Timer is already running", __func__);
15686 return;
15687 }
15688
15689 vos_timer_start(&pHddCtx->delack_timer,
15690 pHddCtx->cfg_ini->tcpDelAckComputeInterval);
15691}
15692
15693/**
15694 * hdd_update_prev_rx_packet_count() - Update previous rx packet count
15695 * @pHddCtx: Valid Global HDD context pointer
15696 *
15697 * This function updates the prev_rx_packets count from the corresponding
15698 * pAdapter states. This prev_rx_packets will diffed with the packet count
15699 * at the end of delack timer. That can give number of RX packet is spacific
15700 * time.
15701 *
15702 * Return: void.
15703 */
15704void hdd_update_prev_rx_packet_count(hdd_context_t *pHddCtx)
15705{
15706 hdd_adapter_list_node_t *pAdapterNode, *pNext;
15707 hdd_adapter_t *pAdapter;
15708 VOS_STATUS status;
15709
15710 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
15711 while (NULL != pAdapterNode && VOS_STATUS_SUCCESS == status) {
15712 pAdapter = pAdapterNode->pAdapter;
15713 pAdapter->prev_rx_packets = pAdapter->stats.rx_packets;
15714 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
15715 pAdapterNode = pNext;
15716 }
15717}
15718
15719/**
15720 * hdd_manage_delack_timer() - start\stop delack timer
15721 * @pHddCtx: Valid Global HDD context pointer
15722 *
15723 * This function check the number of concerent session present, it starts the
15724 * delack timer if only one session is present.
15725 * In the case of BT_COEX and TDLS mode it blindly stop delack functionality.
15726 *
15727 * Return: void.
15728 */
15729void hdd_manage_delack_timer(hdd_context_t *pHddCtx)
15730{
15731 uint8_t sessions;
15732
15733 if (!pHddCtx->cfg_ini->enable_delack) {
15734 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_DEBUG,
15735 "%s: TCP DELACK is not enabled", __func__);
15736 return;
15737 }
15738
15739 /* Blindly stop timer of BTCOEX and TDLS Session is up */
15740 if (pHddCtx->mode != 0) {
15741 hdd_set_default_stop_delack_timer(pHddCtx);
15742 return;
15743 }
15744
15745 sessions = hdd_get_total_sessions(pHddCtx);
15746 if (sessions == 1) {
15747 hdd_update_prev_rx_packet_count(pHddCtx);
15748 hdd_start_delack_timer(pHddCtx);
15749 } else {
15750 hdd_set_default_stop_delack_timer(pHddCtx);
15751 }
15752}
15753
Mihir Shetee1093ba2014-01-21 20:13:32 +053015754/**---------------------------------------------------------------------------
15755 *
15756 * \brief wlan_hdd_init_channels
15757 *
15758 * This function is used to initialize the channel list in CSR
15759 *
15760 * This function is called from hdd_wlan_startup
15761 *
15762 * \param - pHddCtx: HDD context
15763 *
15764 * \return - VOS_STATUS_SUCCESS: Success
15765 * VOS_STATUS_E_FAULT: Failure reported by SME
15766
15767 * --------------------------------------------------------------------------*/
15768static VOS_STATUS wlan_hdd_init_channels(hdd_context_t *pHddCtx)
15769{
15770 eHalStatus status;
15771
15772 status = sme_InitChannels(pHddCtx->hHal);
15773 if (HAL_STATUS_SUCCESS(status))
15774 {
15775 return VOS_STATUS_SUCCESS;
15776 }
15777 else
15778 {
15779 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Channel initialization failed(%d)",
15780 __func__, status);
15781 return VOS_STATUS_E_FAULT;
15782 }
15783}
15784
Mihir Shete04206452014-11-20 17:50:58 +053015785#ifdef CONFIG_ENABLE_LINUX_REG
Agarwal Ashish6db9d532014-09-30 18:19:10 +053015786VOS_STATUS wlan_hdd_init_channels_for_cc(hdd_context_t *pHddCtx, driver_load_type init )
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053015787{
15788 eHalStatus status;
15789
Rajeev Kumar Sirasanagandlaf8fc27c2018-12-06 14:56:43 +053015790 if (init == INIT && init_by_reg_core_user) {
15791 init_by_reg_core_user = false;
15792 pr_info("driver regulatory hint is not required");
15793
15794 return VOS_STATUS_SUCCESS;
15795 }
15796
Agarwal Ashish6db9d532014-09-30 18:19:10 +053015797 status = sme_InitChannelsForCC(pHddCtx->hHal, init);
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053015798 if (HAL_STATUS_SUCCESS(status))
15799 {
15800 return VOS_STATUS_SUCCESS;
15801 }
15802 else
15803 {
15804 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Issue reg hint failed(%d)",
15805 __func__, status);
15806 return VOS_STATUS_E_FAULT;
15807 }
15808}
Mihir Shete04206452014-11-20 17:50:58 +053015809#endif
Sudhir Sattayappa Kohallib1d8c3a2013-06-18 14:47:20 -070015810/*
15811 * API to find if there is any STA or P2P-Client is connected
15812 */
15813VOS_STATUS hdd_issta_p2p_clientconnected(hdd_context_t *pHddCtx)
15814{
15815 return sme_isSta_p2p_clientConnected(pHddCtx->hHal);
15816}
Jeff Johnsone7245742012-09-05 17:12:55 -070015817
Mihir Shetee2ae82a2015-03-16 14:08:49 +053015818
15819/*
15820 * API to find if the firmware will send logs using DXE channel
15821 */
15822v_U8_t hdd_is_fw_logging_enabled(void)
15823{
15824 hdd_context_t *pHddCtx;
15825
15826 pHddCtx = vos_get_context(VOS_MODULE_ID_HDD,
15827 vos_get_global_context(VOS_MODULE_ID_HDD, NULL));
15828
Sravan Kumar Kairam1d5bf8e2019-03-21 00:33:56 +053015829 return (pHddCtx && pHddCtx->cfg_ini->wlanLoggingEnable &&
15830 pHddCtx->cfg_ini->enableMgmtLogging);
Mihir Shetee2ae82a2015-03-16 14:08:49 +053015831}
15832
Agarwal Ashish57e84372014-12-05 18:26:53 +053015833/*
Mihir Shetebe94ebb2015-05-26 12:07:14 +053015834 * API to find if the firmware will send trace logs using DXE channel
15835 */
15836v_U8_t hdd_is_fw_ev_logging_enabled(void)
15837{
15838 hdd_context_t *pHddCtx;
15839
15840 pHddCtx = vos_get_context(VOS_MODULE_ID_HDD,
15841 vos_get_global_context(VOS_MODULE_ID_HDD, NULL));
15842
Sravan Kumar Kairam1d5bf8e2019-03-21 00:33:56 +053015843 return (pHddCtx && pHddCtx->cfg_ini->wlanLoggingEnable &&
15844 pHddCtx->cfg_ini->enableFWLogging);
Mihir Shetebe94ebb2015-05-26 12:07:14 +053015845}
Sravan Kumar Kairam1d5bf8e2019-03-21 00:33:56 +053015846
Mihir Shetebe94ebb2015-05-26 12:07:14 +053015847/*
Agarwal Ashish57e84372014-12-05 18:26:53 +053015848 * API to find if there is any session connected
15849 */
15850VOS_STATUS hdd_is_any_session_connected(hdd_context_t *pHddCtx)
15851{
15852 return sme_is_any_session_connected(pHddCtx->hHal);
15853}
15854
15855
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053015856int wlan_hdd_scan_abort(hdd_adapter_t *pAdapter)
15857{
15858 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
15859 hdd_scaninfo_t *pScanInfo = NULL;
Girish Gowli4bf7a632014-06-12 13:42:11 +053015860 long status = 0;
c_hpothua3d45d52015-01-05 14:11:17 +053015861 tSirAbortScanStatus abortScanStatus;
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053015862
15863 pScanInfo = &pHddCtx->scan_info;
Ratnam Rachuric7681132015-06-30 10:35:13 +053015864 INIT_COMPLETION(pScanInfo->abortscan_event_var);
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053015865 if (pScanInfo->mScanPending)
15866 {
c_hpothua3d45d52015-01-05 14:11:17 +053015867 abortScanStatus = hdd_abort_mac_scan(pHddCtx, pScanInfo->sessionId,
15868 eCSR_SCAN_ABORT_DEFAULT);
15869 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15870 FL("abortScanStatus: %d"), abortScanStatus);
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053015871
c_hpothua3d45d52015-01-05 14:11:17 +053015872 /* If there is active scan command lets wait for the completion else
15873 * there is no need to wait as scan command might be in the SME pending
15874 * command list.
15875 */
15876 if (abortScanStatus == eSIR_ABORT_ACTIVE_SCAN_LIST_NOT_EMPTY)
15877 {
Mukul Sharmab392b642017-08-17 17:45:29 +053015878 status = wait_for_completion_timeout(
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053015879 &pScanInfo->abortscan_event_var,
15880 msecs_to_jiffies(5000));
c_hpothua3d45d52015-01-05 14:11:17 +053015881 if (0 >= status)
15882 {
15883 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Girish Gowli4bf7a632014-06-12 13:42:11 +053015884 "%s: Timeout or Interrupt occurred while waiting for abort"
15885 "scan, status- %ld", __func__, status);
c_hpothua3d45d52015-01-05 14:11:17 +053015886 return -ETIMEDOUT;
15887 }
15888 }
15889 else if (abortScanStatus == eSIR_ABORT_SCAN_FAILURE)
15890 {
15891 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15892 FL("hdd_abort_mac_scan failed"));
15893 return -VOS_STATUS_E_FAILURE;
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053015894 }
15895 }
Girish Gowli4bf7a632014-06-12 13:42:11 +053015896 return 0;
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053015897}
15898
Abhishek Singh7d624e12015-11-30 14:29:27 +053015899/**
15900 * hdd_indicate_mgmt_frame() - Wrapper to indicate management frame to
15901 * user space
15902 * @frame_ind: Management frame data to be informed.
15903 *
15904 * This function is used to indicate management frame to
15905 * user space
15906 *
15907 * Return: None
15908 *
15909 */
15910void hdd_indicate_mgmt_frame(tSirSmeMgmtFrameInd *frame_ind)
15911{
15912 hdd_context_t *hdd_ctx = NULL;
15913 hdd_adapter_t *adapter = NULL;
15914 v_CONTEXT_t vos_context = NULL;
Pragaspathi Thilagaraj4aa58d52019-05-27 18:35:26 +053015915 struct ieee80211_mgmt *mgmt =
15916 (struct ieee80211_mgmt *)frame_ind->frameBuf;
Abhishek Singh7d624e12015-11-30 14:29:27 +053015917
15918 /* Get the global VOSS context.*/
15919 vos_context = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
15920 if (!vos_context) {
15921 hddLog(LOGE, FL("Global VOS context is Null"));
15922 return;
15923 }
15924 /* Get the HDD context.*/
15925 hdd_ctx =
15926 (hdd_context_t *)vos_get_context(VOS_MODULE_ID_HDD, vos_context );
15927
15928 if (0 != wlan_hdd_validate_context(hdd_ctx))
15929 {
15930 return;
15931 }
Pragaspathi Thilagaraj4aa58d52019-05-27 18:35:26 +053015932
15933 if (frame_ind->frameLen < ieee80211_hdrlen(mgmt->frame_control)) {
15934 hddLog(LOGE, FL(" Invalid frame length"));
15935 return;
15936 }
15937
Abhishek Singh7d624e12015-11-30 14:29:27 +053015938 adapter = hdd_get_adapter_by_sme_session_id(hdd_ctx,
15939 frame_ind->sessionId);
15940
15941 if ((NULL != adapter) &&
15942 (WLAN_HDD_ADAPTER_MAGIC == adapter->magic))
15943 __hdd_indicate_mgmt_frame(adapter,
15944 frame_ind->frameLen,
15945 frame_ind->frameBuf,
15946 frame_ind->frameType,
15947 frame_ind->rxChan,
15948 frame_ind->rxRssi);
15949 return;
15950
15951}
15952
c_hpothu225aa7c2014-10-22 17:45:13 +053015953VOS_STATUS wlan_hdd_cancel_remain_on_channel(hdd_context_t *pHddCtx)
15954{
15955 hdd_adapter_t *pAdapter;
15956 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
15957 VOS_STATUS vosStatus;
15958
15959 vosStatus = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
15960 while (NULL != pAdapterNode && VOS_STATUS_E_EMPTY != vosStatus)
15961 {
15962 pAdapter = pAdapterNode->pAdapter;
15963 if (NULL != pAdapter)
15964 {
15965 if (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode ||
15966 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode ||
15967 WLAN_HDD_P2P_GO == pAdapter->device_mode)
15968 {
15969 hddLog(LOG1, FL("abort ROC deviceMode: %d"),
15970 pAdapter->device_mode);
15971 if (VOS_STATUS_SUCCESS !=
15972 wlan_hdd_cancel_existing_remain_on_channel(pAdapter))
15973 {
15974 hddLog(LOGE, FL("failed to abort ROC"));
15975 return VOS_STATUS_E_FAILURE;
15976 }
15977 }
15978 }
15979 vosStatus = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
15980 pAdapterNode = pNext;
15981 }
15982 return VOS_STATUS_SUCCESS;
15983}
Mahesh A Saptasagard477b092015-02-06 15:12:16 +053015984
Mihir Shete0be28772015-02-17 18:42:14 +053015985hdd_remain_on_chan_ctx_t *hdd_get_remain_on_channel_ctx(hdd_context_t *pHddCtx)
15986{
15987 hdd_adapter_t *pAdapter;
15988 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
15989 hdd_cfg80211_state_t *cfgState;
15990 hdd_remain_on_chan_ctx_t *pRemainChanCtx = NULL;
15991 VOS_STATUS vosStatus;
15992
15993 vosStatus = hdd_get_front_adapter (pHddCtx, &pAdapterNode);
15994 while (NULL != pAdapterNode && VOS_STATUS_E_EMPTY != vosStatus)
15995 {
15996 pAdapter = pAdapterNode->pAdapter;
15997 if (NULL != pAdapter)
15998 {
15999 cfgState = WLAN_HDD_GET_CFG_STATE_PTR(pAdapter);
16000 pRemainChanCtx = cfgState->remain_on_chan_ctx;
16001 if (pRemainChanCtx)
16002 break;
16003 }
16004 vosStatus = hdd_get_next_adapter (pHddCtx, pAdapterNode, &pNext);
16005 pAdapterNode = pNext;
16006 }
16007 return pRemainChanCtx;
16008}
16009
Padma, Santhosh Kumar778d8382015-03-04 17:41:22 +053016010/**
16011 * wlan_hdd_handle_dfs_chan_scan () - handles disable/enable DFS channels
16012 *
16013 * @pHddCtx: HDD context within host driver
16014 * @dfsScanMode: dfsScanMode passed from ioctl
16015 *
16016 */
16017
16018VOS_STATUS wlan_hdd_handle_dfs_chan_scan(hdd_context_t *pHddCtx,
16019 tANI_U8 dfsScanMode)
16020{
16021 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
16022 hdd_adapter_t *pAdapter;
16023 VOS_STATUS vosStatus;
16024 hdd_station_ctx_t *pHddStaCtx;
16025 eHalStatus status = eHAL_STATUS_SUCCESS;
16026
16027 if(!pHddCtx)
16028 {
16029 hddLog(LOGE, FL("HDD context is Null"));
16030 return eHAL_STATUS_FAILURE;
16031 }
16032
16033 if (pHddCtx->scan_info.mScanPending)
16034 {
16035 hddLog(LOG1, FL("Aborting scan for sessionId: %d"),
16036 pHddCtx->scan_info.sessionId);
16037 hdd_abort_mac_scan(pHddCtx,
16038 pHddCtx->scan_info.sessionId,
16039 eCSR_SCAN_ABORT_DEFAULT);
16040 }
16041
16042 if (!dfsScanMode)
16043 {
16044 vosStatus = hdd_get_front_adapter( pHddCtx, &pAdapterNode);
16045 while ((NULL != pAdapterNode) &&
16046 (VOS_STATUS_SUCCESS == vosStatus))
16047 {
16048 pAdapter = pAdapterNode->pAdapter;
16049
16050 if (WLAN_HDD_INFRA_STATION == pAdapter->device_mode)
16051 {
16052 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
16053
16054 if(!pHddStaCtx)
16055 {
16056 hddLog(LOGE, FL("HDD STA context is Null"));
16057 return eHAL_STATUS_FAILURE;
16058 }
16059
16060 /* if STA is already connected on DFS channel,
16061 disconnect immediately*/
16062 if (hdd_connIsConnected(pHddStaCtx) &&
16063 (NV_CHANNEL_DFS ==
16064 vos_nv_getChannelEnabledState(
16065 pHddStaCtx->conn_info.operationChannel)))
16066 {
16067 status = sme_RoamDisconnect(pHddCtx->hHal,
16068 pAdapter->sessionId,
16069 eCSR_DISCONNECT_REASON_UNSPECIFIED);
16070 hddLog(LOG1, FL("Client connected on DFS channel %d,"
16071 "sme_RoamDisconnect returned with status: %d"
16072 "for sessionid: %d"), pHddStaCtx->conn_info.
16073 operationChannel, status, pAdapter->sessionId);
16074 }
16075 }
16076
16077 vosStatus = hdd_get_next_adapter(pHddCtx, pAdapterNode,
16078 &pNext);
16079 pAdapterNode = pNext;
16080 }
16081 }
16082
16083 sme_UpdateDFSScanMode(pHddCtx->hHal, dfsScanMode);
16084 sme_UpdateDFSRoamMode(pHddCtx->hHal,
16085 (dfsScanMode != DFS_CHNL_SCAN_DISABLED));
16086
16087 status = sme_HandleDFSChanScan(pHddCtx->hHal);
16088 if (!HAL_STATUS_SUCCESS(status))
16089 {
16090 hddLog(LOGE,
16091 FL("Failed in sme_HandleDFSChanScan (err=%d)"), status);
16092 return status;
16093 }
16094
16095 return status;
16096}
16097
Nirav Shah7e3c8132015-06-22 23:51:42 +053016098static int hdd_log2_ceil(unsigned value)
16099{
16100 /* need to switch to unsigned math so that negative values
16101 * will right-shift towards 0 instead of -1
16102 */
16103 unsigned tmp = value;
16104 int log2 = -1;
16105
16106 if (value == 0)
16107 return 0;
16108
16109 while (tmp) {
16110 log2++;
16111 tmp >>= 1;
16112 }
16113 if (1U << log2 != value)
16114 log2++;
16115
16116 return log2;
16117}
16118
16119/**
16120 * hdd_sta_id_hash_attach() - initialize sta id to macaddr hash
16121 * @pAdapter: adapter handle
16122 *
16123 * Return: vos status
16124 */
16125VOS_STATUS hdd_sta_id_hash_attach(hdd_adapter_t *pAdapter)
16126{
16127 int hash_elem, log2, i;
16128
16129 spin_lock_bh( &pAdapter->sta_hash_lock);
16130 if (pAdapter->is_sta_id_hash_initialized == VOS_TRUE) {
16131 spin_unlock_bh( &pAdapter->sta_hash_lock);
16132 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16133 "%s: hash already attached for session id %d",
16134 __func__, pAdapter->sessionId);
16135 return VOS_STATUS_SUCCESS;
16136 }
16137 spin_unlock_bh( &pAdapter->sta_hash_lock);
16138
16139 hash_elem = WLAN_MAX_STA_COUNT;
16140 hash_elem *= HDD_STA_ID_HASH_MULTIPLIER;
16141 log2 = hdd_log2_ceil(hash_elem);
16142 hash_elem = 1 << log2;
16143
16144 pAdapter->sta_id_hash.mask = hash_elem - 1;
16145 pAdapter->sta_id_hash.idx_bits = log2;
16146 pAdapter->sta_id_hash.bins =
16147 vos_mem_malloc(hash_elem *sizeof(hdd_list_t));
16148 if (!pAdapter->sta_id_hash.bins) {
16149 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16150 "%s: malloc failed for session %d",
16151 __func__, pAdapter->sessionId);
16152 return VOS_STATUS_E_NOMEM;
16153 }
16154
16155 for (i = 0; i < hash_elem; i++)
16156 hdd_list_init(&pAdapter->sta_id_hash.bins[i], WLAN_MAX_STA_COUNT);
16157
16158 spin_lock_bh( &pAdapter->sta_hash_lock);
16159 pAdapter->is_sta_id_hash_initialized = VOS_TRUE;
16160 spin_unlock_bh( &pAdapter->sta_hash_lock);
16161 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16162 "%s: Station ID Hash attached for session id %d",
16163 __func__, pAdapter->sessionId);
16164
16165 return VOS_STATUS_SUCCESS;
16166}
16167
16168/**
16169 * hdd_sta_id_hash_detach() - deinit sta_id to macaddr hash
16170 * @pAdapter: adapter handle
16171 *
16172 * Return: vos status
16173 */
16174VOS_STATUS hdd_sta_id_hash_detach(hdd_adapter_t *pAdapter)
16175{
16176 int hash_elem, i;
16177 v_SIZE_t size;
16178
16179 spin_lock_bh( &pAdapter->sta_hash_lock);
16180 if (pAdapter->is_sta_id_hash_initialized != VOS_TRUE) {
16181 spin_unlock_bh( &pAdapter->sta_hash_lock);
16182 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16183 "%s: hash not initialized for session id %d",
16184 __func__, pAdapter->sessionId);
16185 return VOS_STATUS_SUCCESS;
16186 }
16187
16188 pAdapter->is_sta_id_hash_initialized = VOS_FALSE;
16189 spin_unlock_bh( &pAdapter->sta_hash_lock);
16190
16191 hash_elem = 1 << pAdapter->sta_id_hash.idx_bits;
16192
16193 /* free all station info*/
16194 for (i = 0; i < hash_elem; i++) {
16195 hdd_list_size(&pAdapter->sta_id_hash.bins[i], &size);
16196 if (size != 0) {
16197 VOS_STATUS status;
16198 hdd_staid_hash_node_t *sta_info_node = NULL;
16199 hdd_staid_hash_node_t *next_node = NULL;
16200 status = hdd_list_peek_front ( &pAdapter->sta_id_hash.bins[i],
16201 (hdd_list_node_t**) &sta_info_node );
16202
16203 while ( NULL != sta_info_node && VOS_STATUS_SUCCESS == status )
16204 {
16205 status = hdd_list_remove_node( &pAdapter->sta_id_hash.bins[i],
16206 &sta_info_node->node);
16207 vos_mem_free(sta_info_node);
16208
16209 status = hdd_list_peek_next (&pAdapter->sta_id_hash.bins[i],
16210 (hdd_list_node_t*)sta_info_node,
16211 (hdd_list_node_t**)&next_node);
16212 sta_info_node = next_node;
16213 }
16214 }
16215 }
16216
16217 vos_mem_free(pAdapter->sta_id_hash.bins);
16218 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16219 "%s: Station ID Hash detached for session id %d",
16220 __func__, pAdapter->sessionId);
16221 return VOS_STATUS_SUCCESS;
16222}
16223
16224/**
16225 * hdd_sta_id_hash_calculate_index() - derive index from macaddr
16226 * @pAdapter: adapter handle
16227 * @mac_addr_in: input mac address
16228 *
16229 * Return: index derived from mac address
16230 */
16231int hdd_sta_id_hash_calculate_index(hdd_adapter_t *pAdapter,
16232 v_MACADDR_t *mac_addr_in)
16233{
16234 uint16 index;
16235 struct hdd_align_mac_addr_t * mac_addr =
16236 (struct hdd_align_mac_addr_t *)mac_addr_in;
16237
16238 index = mac_addr->bytes_ab ^
16239 mac_addr->bytes_cd ^ mac_addr->bytes_ef;
16240 index ^= index >> pAdapter->sta_id_hash.idx_bits;
16241 index &= pAdapter->sta_id_hash.mask;
16242 return index;
16243}
16244
16245/**
16246 * hdd_sta_id_hash_add_entry() - add entry in hash
16247 * @pAdapter: adapter handle
16248 * @sta_id: station id
16249 * @mac_addr: mac address
16250 *
16251 * Return: vos status
16252 */
16253VOS_STATUS hdd_sta_id_hash_add_entry(hdd_adapter_t *pAdapter,
16254 v_U8_t sta_id, v_MACADDR_t *mac_addr)
16255{
16256 uint16 index;
16257 hdd_staid_hash_node_t *sta_info_node = NULL;
16258
Nirav Shah7e3c8132015-06-22 23:51:42 +053016259 index = hdd_sta_id_hash_calculate_index(pAdapter, mac_addr);
16260 sta_info_node = vos_mem_malloc(sizeof(hdd_staid_hash_node_t));
16261 if (!sta_info_node) {
Nirav Shah7e3c8132015-06-22 23:51:42 +053016262 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16263 "%s: malloc failed", __func__);
16264 return VOS_STATUS_E_NOMEM;
16265 }
16266
16267 sta_info_node->sta_id = sta_id;
16268 vos_mem_copy(&sta_info_node->mac_addr, mac_addr, sizeof(v_MACADDR_t));
16269
Nirav Shah303ed5c2015-08-24 10:29:25 +053016270 spin_lock_bh( &pAdapter->sta_hash_lock);
16271 if (pAdapter->is_sta_id_hash_initialized != VOS_TRUE) {
16272 spin_unlock_bh( &pAdapter->sta_hash_lock);
16273 vos_mem_free(sta_info_node);
16274 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16275 "%s: hash is not initialized for session id %d",
16276 __func__, pAdapter->sessionId);
16277 return VOS_STATUS_E_FAILURE;
16278 }
16279
Nirav Shah7e3c8132015-06-22 23:51:42 +053016280 hdd_list_insert_back ( &pAdapter->sta_id_hash.bins[index],
16281 (hdd_list_node_t*) sta_info_node );
16282 spin_unlock_bh( &pAdapter->sta_hash_lock);
16283 return VOS_STATUS_SUCCESS;
16284}
16285
16286/**
16287 * hdd_sta_id_hash_remove_entry() - remove entry from hash
16288 * @pAdapter: adapter handle
16289 * @sta_id: station id
16290 * @mac_addr: mac address
16291 *
16292 * Return: vos status
16293 */
16294VOS_STATUS hdd_sta_id_hash_remove_entry(hdd_adapter_t *pAdapter,
16295 v_U8_t sta_id, v_MACADDR_t *mac_addr)
16296{
16297 uint16 index;
16298 VOS_STATUS status;
16299 hdd_staid_hash_node_t *sta_info_node = NULL;
16300 hdd_staid_hash_node_t *next_node = NULL;
16301
16302 spin_lock_bh( &pAdapter->sta_hash_lock);
16303 if (pAdapter->is_sta_id_hash_initialized != VOS_TRUE) {
16304 spin_unlock_bh( &pAdapter->sta_hash_lock);
16305 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16306 "%s: hash is not initialized for session id %d",
16307 __func__, pAdapter->sessionId);
16308 return VOS_STATUS_E_FAILURE;
16309 }
16310
16311 index = hdd_sta_id_hash_calculate_index(pAdapter, mac_addr);
16312 status = hdd_list_peek_front ( &pAdapter->sta_id_hash.bins[index],
16313 (hdd_list_node_t**) &sta_info_node );
16314
16315 while ( NULL != sta_info_node && VOS_STATUS_SUCCESS == status )
16316 {
16317 if (sta_info_node->sta_id == sta_id) {
16318 status = hdd_list_remove_node( &pAdapter->sta_id_hash.bins[index],
16319 &sta_info_node->node);
16320 vos_mem_free(sta_info_node);
16321 break;
16322 }
16323 status = hdd_list_peek_next (&pAdapter->sta_id_hash.bins[index],
16324 (hdd_list_node_t*)sta_info_node, (hdd_list_node_t**)&next_node);
16325 sta_info_node = next_node;
16326 }
16327 spin_unlock_bh( &pAdapter->sta_hash_lock);
16328 return status;
16329}
16330
16331/**
16332 * hdd_sta_id_find_from_mac_addr() - find sta id from mac address
16333 * @pAdapter: adapter handle
16334 * @mac_addr_in: mac address
16335 *
16336 * Return: station id
16337 */
16338int hdd_sta_id_find_from_mac_addr(hdd_adapter_t *pAdapter,
16339 v_MACADDR_t *mac_addr_in)
16340{
16341 uint8 is_found = 0;
16342 uint8 sta_id = HDD_WLAN_INVALID_STA_ID;
16343 uint16 index;
16344 VOS_STATUS status;
16345 hdd_staid_hash_node_t *sta_info_node = NULL;
16346 hdd_staid_hash_node_t *next_node = NULL;
16347
16348 spin_lock_bh( &pAdapter->sta_hash_lock);
16349 if (pAdapter->is_sta_id_hash_initialized != VOS_TRUE) {
16350 spin_unlock_bh( &pAdapter->sta_hash_lock);
Bhargav Shahce3b32c2015-08-10 12:29:24 +053016351 hddLog(VOS_TRACE_LEVEL_INFO,
Nirav Shah7e3c8132015-06-22 23:51:42 +053016352 FL("hash is not initialized for session id %d"),
16353 pAdapter->sessionId);
16354 return HDD_WLAN_INVALID_STA_ID;
16355 }
16356
16357 index = hdd_sta_id_hash_calculate_index(pAdapter, mac_addr_in);
16358 status = hdd_list_peek_front ( &pAdapter->sta_id_hash.bins[index],
16359 (hdd_list_node_t**) &sta_info_node );
16360
16361 while ( NULL != sta_info_node && VOS_STATUS_SUCCESS == status )
16362 {
16363 if (vos_mem_compare(&sta_info_node->mac_addr,
16364 mac_addr_in, sizeof(v_MACADDR_t))) {
16365 is_found = 1;
16366 sta_id = sta_info_node->sta_id;
16367 break;
16368 }
16369 status = hdd_list_peek_next (&pAdapter->sta_id_hash.bins[index],
16370 (hdd_list_node_t*)sta_info_node,
16371 (hdd_list_node_t**)&next_node);
16372 sta_info_node = next_node;
16373 }
16374 spin_unlock_bh( &pAdapter->sta_hash_lock);
16375 return sta_id;
16376}
16377
Mahesh A Saptasagar67ab9222015-10-21 15:38:41 +053016378void hdd_initialize_adapter_common(hdd_adapter_t *pAdapter)
16379{
16380 if (NULL == pAdapter)
16381 {
16382 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: pAdapter is NULL ", __func__);
16383 return;
16384 }
16385 init_completion(&pAdapter->session_open_comp_var);
16386 init_completion(&pAdapter->session_close_comp_var);
16387 init_completion(&pAdapter->disconnect_comp_var);
16388 init_completion(&pAdapter->linkup_event_var);
16389 init_completion(&pAdapter->cancel_rem_on_chan_var);
16390 init_completion(&pAdapter->rem_on_chan_ready_event);
16391 init_completion(&pAdapter->pno_comp_var);
16392#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
16393 init_completion(&pAdapter->offchannel_tx_event);
16394#endif
16395 init_completion(&pAdapter->tx_action_cnf_event);
16396#ifdef FEATURE_WLAN_TDLS
16397 init_completion(&pAdapter->tdls_add_station_comp);
16398 init_completion(&pAdapter->tdls_del_station_comp);
16399 init_completion(&pAdapter->tdls_mgmt_comp);
16400 init_completion(&pAdapter->tdls_link_establish_req_comp);
16401#endif
16402
16403#ifdef WLAN_FEATURE_RMC
16404 init_completion(&pAdapter->ibss_peer_info_comp);
16405#endif /* WLAN_FEATURE_RMC */
16406 init_completion(&pAdapter->ula_complete);
16407 init_completion(&pAdapter->change_country_code);
16408
16409#ifdef FEATURE_WLAN_BATCH_SCAN
16410 init_completion(&pAdapter->hdd_set_batch_scan_req_var);
16411 init_completion(&pAdapter->hdd_get_batch_scan_req_var);
16412#endif
Kapil Gupta2b44acb2016-12-30 16:49:51 +053016413 init_completion(&pAdapter->wlan_suspend_comp_var);
Mahesh A Saptasagar67ab9222015-10-21 15:38:41 +053016414
16415 return;
16416}
c_manjeecfd1efb2015-09-25 19:32:34 +053016417
Anurag Chouhan0b29de02016-12-16 13:18:40 +053016418#ifdef MDNS_OFFLOAD
16419
16420/**
16421 * hdd_mdns_enable_offload_done() - mdns enable offload response api
16422 * @padapter: holds adapter
16423 * @status: response status
16424 *
16425 * Return - None
16426 */
16427void hdd_mdns_enable_offload_done(void *padapter, VOS_STATUS status)
16428{
16429 hdd_adapter_t* adapter = (hdd_adapter_t*) padapter;
16430
16431 ENTER();
16432
16433 if (NULL == adapter)
16434 {
16435 hddLog(VOS_TRACE_LEVEL_ERROR,
16436 "%s: adapter is NULL",__func__);
16437 return;
16438 }
16439
16440 adapter->mdns_status.mdns_enable_status = status;
16441 vos_event_set(&adapter->mdns_status.vos_event);
16442 return;
16443}
16444
16445/**
16446 * hdd_mdns_fqdn_offload_done() - mdns fqdn offload response api
16447 * @padapter: holds adapter
16448 * @status: responce status
16449 *
16450 * Return - None
16451 */
16452void hdd_mdns_fqdn_offload_done(void *padapter, VOS_STATUS status)
16453{
16454 hdd_adapter_t* adapter = (hdd_adapter_t*) padapter;
16455
16456 ENTER();
16457
16458 if (NULL == adapter)
16459 {
16460 hddLog(VOS_TRACE_LEVEL_ERROR,
16461 "%s: adapter is NULL",__func__);
16462 return;
16463 }
16464
16465 adapter->mdns_status.mdns_fqdn_status = status;
16466 return;
16467}
16468
16469/**
16470 * hdd_mdns_resp_offload_done() - mdns resp offload response api
16471 * @padapter: holds adapter
16472 * @status: responce status
16473 *
16474 * Return - None
16475 */
16476void hdd_mdns_resp_offload_done(void *padapter, VOS_STATUS status)
16477{
16478 hdd_adapter_t* adapter = (hdd_adapter_t*) padapter;
16479
16480 ENTER();
16481
16482 if (NULL == adapter)
16483 {
16484 hddLog(VOS_TRACE_LEVEL_ERROR,
16485 "%s: adapter is NULL",__func__);
16486 return;
16487 }
16488
16489 adapter->mdns_status.mdns_resp_status = status;
16490 return;
16491}
16492
16493/**
16494 * wlan_hdd_mdns_process_response_dname() - Process mDNS domain name
16495 * @response: Pointer to a struct hdd_mdns_resp_info
16496 * @resp_info: Pointer to a struct tSirMDNSResponseInfo
16497 *
16498 * This function will pack the whole domain name without compression. It will
16499 * add the leading len for each field and add zero length octet to terminate
16500 * the domain name.
16501 *
16502 * Return: Return boolean. TRUE for success, FALSE for fail.
16503 */
16504static bool
16505wlan_hdd_mdns_process_response_dname(struct hdd_mdns_resp_info *response,
16506 sir_mdns_resp_info resp_info)
16507{
16508 uint8_t num;
16509 uint16_t idx;
16510 uint8_t len = 0;
16511
16512 if ((response == NULL) || (response->data == NULL) ||
16513 (response->offset == NULL)) {
16514 hddLog(LOGE, FL("Either data or offset in response is NULL!"));
16515 return FALSE;
16516 }
16517
16518 if ((resp_info == NULL) ||
16519 (resp_info->resp_len >= MAX_MDNS_RESP_LEN)) {
16520 hddLog(LOGE, FL("resp_len exceeds %d!"), MAX_MDNS_RESP_LEN);
16521 return FALSE;
16522 }
16523
16524 for (num = 0; num < response->num_entries; num++) {
16525 response->offset[num] =
16526 resp_info->resp_len + MDNS_HEADER_LEN;
16527 idx = num * MAX_LEN_DOMAINNAME_FIELD;
16528 len = strlen((char *)&response->data[idx]);
16529 if ((resp_info->resp_len + len + 1) >= MAX_MDNS_RESP_LEN) {
16530 hddLog(LOGE, FL("resp_len exceeds %d!"),
16531 MAX_MDNS_RESP_LEN);
16532 return FALSE;
16533 }
16534 resp_info->resp_data[resp_info->resp_len] = len;
16535 resp_info->resp_len++;
16536 vos_mem_copy(&resp_info->resp_data[resp_info->resp_len],
16537 &response->data[idx], len);
16538 resp_info->resp_len += len;
16539 }
16540
16541 /* The domain name terminates with the zero length octet */
16542 if (num == response->num_entries) {
16543 if (resp_info->resp_len >= MAX_MDNS_RESP_LEN) {
16544 hddLog(LOGE, FL("resp_len exceeds %d!"),
16545 MAX_MDNS_RESP_LEN);
16546 return FALSE;
16547 }
16548 resp_info->resp_data[resp_info->resp_len] = 0;
16549 resp_info->resp_len++;
16550 }
16551
16552 return TRUE;
16553}
16554
16555/**
16556 * wlan_hdd_mdns_format_response_u16() - Form uint16_t response data
16557 * @value: The uint16_t value is formed to the struct tSirMDNSResponseInfo
16558 * @resp_info: Pointer to a struct tSirMDNSResponseInfo
16559 *
16560 * Return: None
16561 */
16562static void wlan_hdd_mdns_format_response_u16(uint16_t value,
16563 sir_mdns_resp_info resp_info)
16564{
16565 uint8_t val_u8;
16566
16567 if ((resp_info == NULL) || (resp_info->resp_data == NULL))
16568 return;
16569 val_u8 = (value & 0xff00) >> 8;
16570 resp_info->resp_data[resp_info->resp_len++] = val_u8;
16571 val_u8 = value & 0xff;
16572 resp_info->resp_data[resp_info->resp_len++] = val_u8;
16573}
16574
16575/**
16576 * wlan_hdd_mdns_format_response_u32() - Form uint32_t response data
16577 * @value: The uint32_t value is formed to the struct tSirMDNSResponseInfo
16578 * @resp_info: Pointer to a struct tSirMDNSResponseInfo
16579 *
16580 * Return: None
16581 */
16582static void wlan_hdd_mdns_format_response_u32(uint32_t value,
16583 sir_mdns_resp_info resp_info)
16584{
16585 uint8_t val_u8;
16586
16587 if ((resp_info == NULL) || (resp_info->resp_data == NULL))
16588 return;
16589 val_u8 = (value & 0xff000000) >> 24;
16590 resp_info->resp_data[resp_info->resp_len++] = val_u8;
16591 val_u8 = (value & 0xff0000) >> 16;
16592 resp_info->resp_data[resp_info->resp_len++] = val_u8;
16593 val_u8 = (value & 0xff00) >> 8;
16594 resp_info->resp_data[resp_info->resp_len++] = val_u8;
16595 val_u8 = value & 0xff;
16596 resp_info->resp_data[resp_info->resp_len++] = val_u8;
16597}
16598
16599/**
16600 * wlan_hdd_mdns_process_response_misc() - Process misc info in mDNS response
16601 * @resp_type: Response type for mDNS
16602 * @resp_info: Pointer to a struct tSirMDNSResponseInfo
16603 *
16604 * This function will pack the response type, class and TTL (Time To Live).
16605 *
16606 * Return: Return boolean. TRUE for success, FALSE for fail.
16607 */
16608static bool wlan_hdd_mdns_process_response_misc(uint16_t resp_type,
16609 sir_mdns_resp_info resp_info)
16610{
16611 uint16_t len;
16612
16613 if (resp_info == NULL) {
16614 hddLog(LOGE, FL("resp_info is NULL!"));
16615 return FALSE;
16616 }
16617
16618 len = resp_info->resp_len + (2 * sizeof(uint16_t) + sizeof(uint32_t));
16619 if (len >= MAX_MDNS_RESP_LEN) {
16620 hddLog(LOGE, FL("resp_len exceeds %d!"), MAX_MDNS_RESP_LEN);
16621 return FALSE;
16622 }
16623
16624 /* Fill Type, Class, TTL */
16625 wlan_hdd_mdns_format_response_u16(resp_type, resp_info);
16626 wlan_hdd_mdns_format_response_u16(MDNS_CLASS, resp_info);
16627 wlan_hdd_mdns_format_response_u32(MDNS_TTL, resp_info);
16628
16629 return TRUE;
16630}
16631
16632/**
16633 * wlan_hdd_mdns_compress_data() - Compress the domain name in mDNS response
16634 * @resp_info: Pointer to a struct tSirMDNSResponseInfo
16635 * @response_dst: The response which domain name is compressed.
16636 * @response_src: The response which domain name is matched with response_dst.
16637 * Its offset is used for data compression.
16638 * @num_matched: The number of matched entries between response_dst and
16639 * response_src
16640 *
16641 * This function will form the different fields of domain name in response_dst
16642 * if any. Then use the offset of the matched domain name in response_src to
16643 * compress the matched domain name.
16644 *
16645 * Return: Return boolean. TRUE for success, FALSE for fail.
16646 */
16647static bool
16648wlan_hdd_mdns_compress_data(sir_mdns_resp_info resp_info,
16649 struct hdd_mdns_resp_info *response_dst,
16650 struct hdd_mdns_resp_info *response_src,
16651 uint8_t num_matched)
16652{
16653 uint8_t num, num_diff;
16654 uint16_t value, idx;
16655 uint8_t len = 0;
16656
16657 if ((response_src == NULL) || (response_dst == NULL) ||
16658 (resp_info == NULL)) {
16659 hddLog(LOGE, FL("response info is NULL!"));
16660 return FALSE;
16661 }
16662
16663 if (response_dst->num_entries < num_matched) {
16664 hddLog(LOGE, FL("num_entries is less than num_matched!"));
16665 return FALSE;
16666 }
16667
16668 if (resp_info->resp_len >= MAX_MDNS_RESP_LEN) {
16669 hddLog(LOGE, FL("resp_len exceeds %d!"), MAX_MDNS_RESP_LEN);
16670 return FALSE;
16671 }
16672
16673 num_diff = response_dst->num_entries - num_matched;
16674 if ((num_diff > 0) && (response_dst->data == NULL)) {
16675 hddLog(LOGE, FL("response_dst->data is NULL!"));
16676 return FALSE;
16677 }
16678
16679 /*
16680 * Handle the unmatched string at the beginning
16681 * Store the length of octets and the octets
16682 */
16683 for (num = 0; num < num_diff; num++) {
16684 response_dst->offset[num] =
16685 resp_info->resp_len + MDNS_HEADER_LEN;
16686 idx = num * MAX_LEN_DOMAINNAME_FIELD;
16687 len = strlen((char *)&response_dst->data[idx]);
16688 if ((resp_info->resp_len + len + 1) >= MAX_MDNS_RESP_LEN) {
16689 hddLog(LOGE, FL("resp_len exceeds %d!"),
16690 MAX_MDNS_RESP_LEN);
16691 return FALSE;
16692 }
16693 resp_info->resp_data[resp_info->resp_len] = len;
16694 resp_info->resp_len++;
16695 vos_mem_copy(&resp_info->resp_data[resp_info->resp_len],
16696 &response_dst->data[idx], len);
16697 resp_info->resp_len += len;
16698 }
16699 /*
16700 * Handle the matched string from the end
16701 * Just keep the offset and mask the leading two bit
16702 */
16703 if (response_src->num_entries >= num_matched) {
16704 num_diff = response_src->num_entries - num_matched;
16705 value = response_src->offset[num_diff];
16706 if (value > 0) {
16707 value |= 0xc000;
16708 if ((resp_info->resp_len + sizeof(uint16_t)) >=
16709 MAX_MDNS_RESP_LEN) {
16710 hddLog(LOGE, FL("resp_len exceeds %d!"),
16711 MAX_MDNS_RESP_LEN);
16712 return FALSE;
16713 }
16714 wlan_hdd_mdns_format_response_u16(value, resp_info);
16715 return TRUE;
16716 }
16717 }
16718 return FALSE;
16719}
16720
16721/**
16722 * wlan_hdd_mdns_reset_response() - Reset the response info
16723 * @response: The response which info is reset.
16724 *
16725 * Return: None
16726 */
16727static void wlan_hdd_mdns_reset_response(struct hdd_mdns_resp_info *response)
16728{
16729 if (response == NULL)
16730 return;
16731 response->num_entries = 0;
16732 response->data = NULL;
16733 response->offset = NULL;
16734}
16735
16736/**
16737 * wlan_hdd_mdns_init_response() - Initialize the response info
16738 * @response: The response which info is initiatized.
16739 * @resp_dname: The domain name string which might be tokenized.
16740 *
16741 * This function will allocate the memory for both response->data and
16742 * response->offset. Besides, it will also tokenize the domain name to some
16743 * entries and fill response->num_entries with the num of entries.
16744 *
16745 * Return: Return boolean. TRUE for success, FALSE for fail.
16746 */
16747static bool wlan_hdd_mdns_init_response(struct hdd_mdns_resp_info *response,
16748 uint8_t *resp_dname, char separator)
16749{
16750 uint16_t size;
16751
16752 if ((resp_dname == NULL) || (response == NULL)) {
16753 hddLog(LOGE, FL("resp_dname or response is NULL!"));
16754 return FALSE;
16755 }
16756
16757 size = MAX_NUM_FIELD_DOMAINNAME * MAX_LEN_DOMAINNAME_FIELD;
16758 response->data = vos_mem_malloc(size);
16759 if (response->data) {
16760 vos_mem_zero(response->data, size);
16761 if (VOS_STATUS_SUCCESS !=
16762 hdd_string_to_string_array((char *)resp_dname,
16763 response->data,
16764 separator,
16765 &response->num_entries,
16766 MAX_NUM_FIELD_DOMAINNAME,
16767 MAX_LEN_DOMAINNAME_FIELD)) {
16768 hddLog(LOGE, FL("hdd_string_to_string_array fail!"));
16769 goto err_init_resp;
16770 }
16771
16772 if ((response->num_entries > 0) &&
16773 (strlen((char *)&response->data[0]) > 0)) {
16774 size = sizeof(uint16_t) * response->num_entries;
16775 response->offset = vos_mem_malloc(size);
16776 if (response->offset) {
16777 vos_mem_zero(response->offset, size);
16778 return TRUE;
16779 }
16780 }
16781 }
16782
16783err_init_resp:
16784 if (response->data)
16785 vos_mem_free(response->data);
16786 wlan_hdd_mdns_reset_response(response);
16787 return FALSE;
16788}
16789
16790/**
16791 * wlan_hdd_mdns_find_entries_from_end() - Find the matched entries
16792 * @response1: The response info is used to be compared.
16793 * @response2: The response info is used to be compared.
16794 *
16795 * This function will find the matched entries from the end.
16796 *
16797 * Return: Return the number of the matched entries.
16798 */
16799static uint8_t
16800wlan_hdd_mdns_find_entries_from_end(struct hdd_mdns_resp_info *response1,
16801 struct hdd_mdns_resp_info *response2)
16802{
16803 uint8_t min, len1, i;
16804 uint16_t num1, num2;
16805 uint8_t num_matched = 0;
16806
16807 min = VOS_MIN(response1->num_entries, response2->num_entries);
16808
16809 for (i = 1; i <= min; i++) {
16810 num1 = (response1->num_entries - i);
16811 num1 *= MAX_LEN_DOMAINNAME_FIELD;
16812 num2 = (response2->num_entries - i);
16813 num2 *= MAX_LEN_DOMAINNAME_FIELD;
16814 len1 = strlen((char *)&response1->data[num1]);
16815
16816 if ((len1 == 0) ||
16817 (len1 != strlen((char *)&response2->data[num2])))
16818 break;
16819 if (memcmp(&response1->data[num1],
16820 &response2->data[num2], len1))
16821 break;
16822 else
16823 num_matched++;
16824 }
16825
16826 return num_matched;
16827}
16828
16829/**
16830 * wlan_hdd_mdns_find_max() - Find the maximum number of the matched entries
16831 * @matchedlist: Pointer to the array of struct hdd_mdns_resp_matched
16832 * @numlist: The number of the elements in the array matchedlist.
16833 *
16834 * Find the max number of the matched entries among the array matchedlist.
16835 *
16836 * Return: None
16837 */
16838static void wlan_hdd_mdns_find_max(struct hdd_mdns_resp_matched *matchedlist,
16839 uint8_t numlist)
16840{
16841 int j;
16842 struct hdd_mdns_resp_matched tmp;
16843
16844 /* At least two values are used for sorting */
16845 if ((numlist < 2) || (matchedlist == NULL)) {
16846 hddLog(LOGE, FL("At least two values are used for sorting!"));
16847 return;
16848 }
16849
16850 for (j = 0; j < numlist-1; j++) {
16851 if (matchedlist[j].num_matched >
16852 matchedlist[j+1].num_matched) {
16853 vos_mem_copy(&tmp, &matchedlist[j],
16854 sizeof(struct hdd_mdns_resp_matched));
16855 vos_mem_copy(&matchedlist[j], &matchedlist[j+1],
16856 sizeof(struct hdd_mdns_resp_matched));
16857 vos_mem_copy(&matchedlist[j+1], &tmp,
16858 sizeof(struct hdd_mdns_resp_matched));
16859 }
16860 }
16861}
16862
16863/**
16864 * wlan_hdd_mdns_pack_response_type_a() - Pack Type A response
16865 * @ini_config: Pointer to the struct hdd_config_t
16866 * @resp_info: Pointer to the struct tSirMDNSResponseInfo
16867 * @resptype_a: Pointer to the struct hdd_mdns_resp_info of Type A
16868 *
16869 * Type A response include QName, response type, class, TTL and Ipv4.
16870 *
16871 * Return: Return boolean. TRUE for success, FALSE for fail.
16872 */
16873static bool
16874wlan_hdd_mdns_pack_response_type_a(hdd_config_t *ini_config,
16875 sir_mdns_resp_info resp_info,
16876 struct hdd_mdns_resp_info *resptype_a)
16877{
16878 uint16_t value;
16879 uint32_t len;
16880
16881 ENTER();
16882 if ((ini_config == NULL) || (resp_info == NULL) ||
16883 (resptype_a == NULL)) {
16884 hddLog(LOGE, FL("ini_config or response info is NULL!"));
16885 return FALSE;
16886 }
16887
16888 /* No Type A response */
16889 if (strlen((char *)ini_config->mdns_resp_type_a) <= 0)
16890 return TRUE;
16891
16892 /* Wrong response is assigned, just ignore this response */
16893 if (!wlan_hdd_mdns_init_response(resptype_a,
16894 ini_config->mdns_resp_type_a, '.'))
16895 return TRUE;
16896
16897 /* Process response domain name */
16898 if (!wlan_hdd_mdns_process_response_dname(resptype_a, resp_info)) {
16899 hddLog(LOGE, FL("Fail to process mDNS response (%d)!"),
16900 MDNS_TYPE_A);
16901 return FALSE;
16902 }
16903
16904 /* Process response Type, Class, TTL */
16905 if (!wlan_hdd_mdns_process_response_misc(MDNS_TYPE_A, resp_info)) {
16906 hddLog(LOGE, FL("Fail to process mDNS misc response (%d)!"),
16907 MDNS_TYPE_A);
16908 return FALSE;
16909 }
16910
16911 /* Process response RDLength, RData */
16912 len = sizeof(uint16_t) + sizeof(uint32_t);
16913 len += resp_info->resp_len;
16914 if (len >= MAX_MDNS_RESP_LEN) {
16915 hddLog(LOGE, FL("resp_len exceeds %d!"), MAX_MDNS_RESP_LEN);
16916 return FALSE;
16917 }
16918 value = sizeof(uint32_t);
16919 wlan_hdd_mdns_format_response_u16(value, resp_info);
16920 wlan_hdd_mdns_format_response_u32(ini_config->mdns_resp_type_a_ipv4,
16921 resp_info);
16922
16923 EXIT();
16924 return TRUE;
16925}
16926
16927/**
16928 * wlan_hdd_mdns_pack_response_type_txt() - Pack Type Txt response
16929 * @ini_config: Pointer to the struct hdd_config_t
16930 * @resp_info: Pointer to the struct tSirMDNSResponseInfo
16931 * @resptype_txt: Pointer to the struct hdd_mdns_resp_info of Type txt
16932 * @resptype_a: Pointer to the struct hdd_mdns_resp_info of Type A
16933 *
16934 * Type Txt response include QName, response type, class, TTL and text content.
16935 * Also, it will find the matched QName from resptype_A and compress the data.
16936 *
16937 * Return: Return boolean. TRUE for success, FALSE for fail.
16938 */
16939static bool
16940wlan_hdd_mdns_pack_response_type_txt(hdd_config_t *ini_config,
16941 sir_mdns_resp_info resp_info,
16942 struct hdd_mdns_resp_info *resptype_txt,
16943 struct hdd_mdns_resp_info *resptype_a)
16944{
16945 uint8_t num_matched;
16946 uint8_t num;
16947 uint16_t idx;
16948 uint16_t value = 0;
16949 uint32_t len;
16950 uint32_t total_len;
16951 bool status;
16952 struct hdd_mdns_resp_info resptype_content;
16953
16954 ENTER();
16955
16956 if ((ini_config == NULL) || (resp_info == NULL) ||
16957 (resptype_txt == NULL)) {
16958 hddLog(LOGE, FL("ini_config or response info is NULL!"));
16959 return FALSE;
16960 }
16961
16962 /* No Type Txt response */
16963 if (strlen((char *)ini_config->mdns_resp_type_txt) <= 0)
16964 return TRUE;
16965
16966 /* Wrong response is assigned, just ignore this response */
16967 if (!wlan_hdd_mdns_init_response(resptype_txt,
16968 ini_config->mdns_resp_type_txt, '.'))
16969 return TRUE;
16970
16971 /*
16972 * For data compression
16973 * Check if any strings are matched with Type A response
16974 */
16975 if (resptype_a && (resptype_a->num_entries > 0)) {
16976 num_matched = wlan_hdd_mdns_find_entries_from_end(resptype_txt,
16977 resptype_a);
16978 if (num_matched > 0) {
16979 if (!wlan_hdd_mdns_compress_data(resp_info,
16980 resptype_txt, resptype_a, num_matched)) {
16981 hddLog(LOGE, FL("Fail to compress mDNS "
16982 "response (%d)!"), MDNS_TYPE_TXT);
16983 return FALSE;
16984 }
16985 } else {
16986 /*
16987 * num_matched is zero. Error!
16988 * At least ".local" is needed.
16989 */
16990 hddLog(LOGE, FL("No matched string! Fail to pack mDNS "
16991 "response (%d)!"), MDNS_TYPE_TXT);
16992 return FALSE;
16993 }
16994 } else {
16995 /* no TypeA response, so show the whole data */
16996 if (!wlan_hdd_mdns_process_response_dname(resptype_txt,
16997 resp_info)) {
16998 hddLog(LOGE, FL("Fail to process mDNS response (%d)!"),
16999 MDNS_TYPE_TXT);
17000 return FALSE;
17001 }
17002 }
17003
17004 /* Process response Type, Class, TTL */
17005 if (!wlan_hdd_mdns_process_response_misc(MDNS_TYPE_TXT, resp_info)) {
17006 hddLog(LOGE, FL("Fail to process mDNS misc response (%d)!"),
17007 MDNS_TYPE_TXT);
17008 return FALSE;
17009 }
17010
17011 /*
17012 * Process response RDLength, RData.
17013 * TypeTxt RData include len.
17014 */
17015 status = wlan_hdd_mdns_init_response(&resptype_content,
17016 ini_config->mdns_resp_type_txt_content,
17017 '/');
17018 if (status == FALSE) {
17019 hddLog(LOGE, FL("wlan_hdd_mdns_init_response FAIL"));
17020 return FALSE;
17021 }
17022
17023 for (num = 0; num < resptype_content.num_entries; num++) {
17024 idx = num * MAX_LEN_DOMAINNAME_FIELD;
17025 value += strlen((char *)&resptype_content.data[idx]);
17026 }
17027
17028 /* content len is uint16_t */
17029 total_len = sizeof(uint16_t);
17030 total_len += resp_info->resp_len + value +
17031 resptype_content.num_entries;
17032
17033 if (total_len >= MAX_MDNS_RESP_LEN) {
17034 hddLog(LOGE, FL("resp_len exceeds %d!"), MAX_MDNS_RESP_LEN);
17035 return FALSE;
17036 }
17037 wlan_hdd_mdns_format_response_u16(value + resptype_content.num_entries,
17038 resp_info);
17039
17040 for (num = 0; num < resptype_content.num_entries; num++) {
17041 idx = num * MAX_LEN_DOMAINNAME_FIELD;
17042 len = strlen((char *)&resptype_content.data[idx]);
17043 resp_info->resp_data[resp_info->resp_len] = len;
17044 resp_info->resp_len++;
17045
17046 vos_mem_copy(&resp_info->resp_data[resp_info->resp_len],
17047 &resptype_content.data[idx], len);
17048
17049 resp_info->resp_len += len;
17050 hddLog(LOG1, FL("index = %d, len = %d, str = %s"),
17051 num, len, &resptype_content.data[idx]);
17052 }
17053
17054 EXIT();
17055 return TRUE;
17056}
17057
17058/**
17059 * wlan_hdd_mdns_pack_response_type_ptr_dname() - Pack Type PTR domain name
17060 * @ini_config: Pointer to the struct hdd_config_t
17061 * @resp_info: Pointer to the struct tSirMDNSResponseInfo
17062 * @resptype_ptr_dn: Pointer to the struct hdd_mdns_resp_info of Type Ptr
17063 * domain name
17064 * @resptype_ptr: Pointer to the struct hdd_mdns_resp_info of Type Ptr
17065 * @resptype_txt: Pointer to the struct hdd_mdns_resp_info of Type Txt
17066 * @resptype_a: Pointer to the struct hdd_mdns_resp_info of Type A
17067 *
17068 * The Type Ptr response include Type PTR domain name in its data field.
17069 * Also, it will find the matched QName from the existing resptype_ptr,
17070 * resptype_txt, resptype_a and then compress the data.
17071 *
17072 * Return: Return boolean. TRUE for success, FALSE for fail.
17073 */
17074static bool
17075wlan_hdd_mdns_pack_response_type_ptr_dname(hdd_config_t *ini_config,
17076 sir_mdns_resp_info resp_info,
17077 struct hdd_mdns_resp_info *resptype_ptr_dn,
17078 struct hdd_mdns_resp_info *resptype_ptr,
17079 struct hdd_mdns_resp_info *resptype_txt,
17080 struct hdd_mdns_resp_info *resptype_a)
17081{
17082 uint8_t num_matched, numlist, size;
17083 struct hdd_mdns_resp_matched matchedlist[MAX_MDNS_RESP_TYPE-1];
17084 struct hdd_mdns_resp_info *resp;
17085
17086 if ((ini_config == NULL) || (resp_info == NULL) ||
17087 (resptype_ptr == NULL) || (resptype_ptr_dn == NULL)) {
17088 hddLog(LOGE, FL("ini_config or response info is NULL!"));
17089 return FALSE;
17090 }
17091
17092 /* No Type Ptr domain name response */
17093 if (strlen((char *)ini_config->mdns_resp_type_ptr_dname) <= 0)
17094 return TRUE;
17095
17096 /* Wrong response is assigned, just ignore this response */
17097 if (!wlan_hdd_mdns_init_response(resptype_ptr_dn,
17098 ini_config->mdns_resp_type_ptr_dname, '.'))
17099 return TRUE;
17100
17101 /*
17102 * For data compression
17103 * Check if any strings are matched with previous
17104 * response.
17105 */
17106 numlist = 0;
17107 size = (MAX_MDNS_RESP_TYPE-1);
17108 size *= sizeof(struct hdd_mdns_resp_matched);
17109 vos_mem_zero(matchedlist, size);
17110 num_matched = wlan_hdd_mdns_find_entries_from_end(resptype_ptr_dn,
17111 resptype_ptr);
17112 if (num_matched > 0) {
17113 matchedlist[numlist].num_matched = num_matched;
17114 matchedlist[numlist].type = MDNS_TYPE_PTR;
17115 numlist++;
17116 }
17117 if (resptype_txt && (resptype_txt->num_entries > 0)) {
17118 num_matched = wlan_hdd_mdns_find_entries_from_end(
17119 resptype_ptr_dn, resptype_txt);
17120 if (num_matched > 0) {
17121 matchedlist[numlist].num_matched = num_matched;
17122 matchedlist[numlist].type = MDNS_TYPE_TXT;
17123 numlist++;
17124 }
17125 }
17126 if (resptype_a && (resptype_a->num_entries > 0)) {
17127 num_matched = wlan_hdd_mdns_find_entries_from_end(
17128 resptype_ptr_dn,resptype_a);
17129 if (num_matched > 0) {
17130 matchedlist[numlist].num_matched = num_matched;
17131 matchedlist[numlist].type = MDNS_TYPE_A;
17132 numlist++;
17133 }
17134 }
17135 if (numlist > 0) {
17136 if (numlist > 1)
17137 wlan_hdd_mdns_find_max(matchedlist, numlist);
17138 resp = NULL;
17139 switch (matchedlist[numlist-1].type) {
17140 case MDNS_TYPE_A:
17141 resp = resptype_a;
17142 break;
17143 case MDNS_TYPE_TXT:
17144 resp = resptype_txt;
17145 break;
17146 case MDNS_TYPE_PTR:
17147 resp = resptype_ptr;
17148 break;
17149 default:
17150 hddLog(LOGE, FL("Fail to compress mDNS response "
17151 "(%d)!"), MDNS_TYPE_PTR_DNAME);
17152 return FALSE;
17153 }
17154 num_matched = matchedlist[numlist-1].num_matched;
17155 if (!wlan_hdd_mdns_compress_data(resp_info, resptype_ptr_dn,
17156 resp, num_matched)) {
17157 hddLog(LOGE, FL("Fail to compress mDNS response "
17158 "(%d)!"), MDNS_TYPE_PTR_DNAME);
17159 return FALSE;
17160 }
17161 } else {
17162 /* num = 0 -> no matched string */
17163 if (!wlan_hdd_mdns_process_response_dname(resptype_ptr_dn,
17164 resp_info)) {
17165 hddLog(LOGE, FL("Fail to process mDNS response (%d)!"),
17166 MDNS_TYPE_PTR_DNAME);
17167 return FALSE;
17168 }
17169 }
17170
17171 return TRUE;
17172}
17173
17174/**
17175 * wlan_hdd_mdns_pack_response_type_ptr() - Pack Type PTR response
17176 * @ini_config: Pointer to the struct hdd_config_t
17177 * @resp_info: Pointer to the struct tSirMDNSResponseInfo
17178 * @resptype_ptr: Pointer to the struct hdd_mdns_resp_info of Type Ptr
17179 * @resptype_ptr_dn: Pointer to the struct hdd_mdns_resp_info of Type Ptr
17180 * domain name
17181 * @resptype_txt: Pointer to the struct hdd_mdns_resp_info of Type Txt
17182 * @resptype_a: Pointer to the struct hdd_mdns_resp_info of Type A
17183 *
17184 * The Type Ptr response include QName, response type, class, TTL and
17185 * Type PTR domain name. Also, it will find the matched QName from the
17186 * existing resptype_txt, resptype_a and then compress the data.
17187 *
17188 * Return: Return boolean. TRUE for success, FALSE for fail.
17189 */
17190static bool
17191wlan_hdd_mdns_pack_response_type_ptr(hdd_config_t *ini_config,
17192 sir_mdns_resp_info resp_info,
17193 struct hdd_mdns_resp_info *resptype_ptr,
17194 struct hdd_mdns_resp_info *resptype_ptr_dn,
17195 struct hdd_mdns_resp_info *resptype_txt,
17196 struct hdd_mdns_resp_info *resptype_a)
17197{
17198 uint8_t num_matched, num_matched1;
17199 uint16_t value;
17200 uint8_t val_u8;
17201 uint32_t offset_data_len, len;
17202
17203 ENTER();
17204 if ((ini_config == NULL) || (resp_info == NULL) ||
17205 (resptype_ptr == NULL) || (resptype_ptr_dn == NULL)) {
17206 hddLog(LOGE, FL("ini_config or response info is NULL!"));
17207 return FALSE;
17208 }
17209
17210 /* No Type Ptr response */
17211 if (strlen((char *)ini_config->mdns_resp_type_ptr) <= 0)
17212 return TRUE;
17213
17214 /* Wrong response is assigned, just ignore this response */
17215 if (!wlan_hdd_mdns_init_response(resptype_ptr,
17216 ini_config->mdns_resp_type_ptr, '.'))
17217 return TRUE;
17218
17219 /*
17220 * For data compression
17221 * Check if any strings are matched with Type A response
17222 */
17223 num_matched = 0;
17224 num_matched1 = 0;
17225 if (resptype_a && (resptype_a->num_entries > 0)) {
17226 num_matched = wlan_hdd_mdns_find_entries_from_end(resptype_ptr,
17227 resptype_a);
17228 }
17229 if (resptype_txt && (resptype_txt->num_entries > 0)) {
17230 num_matched1 = wlan_hdd_mdns_find_entries_from_end(
17231 resptype_ptr, resptype_txt);
17232 }
17233 if ((num_matched != num_matched1) ||
17234 ((num_matched > 0) && (num_matched1 > 0))) {
17235 if (num_matched >= num_matched1) {
17236 if (!wlan_hdd_mdns_compress_data(resp_info,
17237 resptype_ptr, resptype_a, num_matched)) {
17238 hddLog(LOGE, FL("Fail to compress mDNS "
17239 "response (%d)!"), MDNS_TYPE_PTR);
17240 return FALSE;
17241 }
17242 } else {
17243 /* num_matched is less than num_matched1 */
17244 if (!wlan_hdd_mdns_compress_data(resp_info,
17245 resptype_ptr, resptype_txt, num_matched1)) {
17246 hddLog(LOGE, FL("Fail to compress mDNS "
17247 "response (%d)!"), MDNS_TYPE_PTR);
17248 return FALSE;
17249 }
17250 }
17251 } else {
17252 /*
17253 * Both num_matched and num_matched1 are zero.
17254 * no TypeA & TypeTxt
17255 */
17256 if (!wlan_hdd_mdns_process_response_dname(resptype_ptr,
17257 resp_info)) {
17258 hddLog(LOGE, FL("Fail to process mDNS response (%d)!"),
17259 MDNS_TYPE_PTR);
17260 return FALSE;
17261 }
17262 }
17263
17264 /* Process response Type, Class, TTL */
17265 if (!wlan_hdd_mdns_process_response_misc(MDNS_TYPE_PTR, resp_info)) {
17266 hddLog(LOGE, FL("Fail to process mDNS misc response (%d)!"),
17267 MDNS_TYPE_PTR);
17268 return FALSE;
17269 }
17270
17271 /*
17272 * Process response RDLength, RData (Ptr domain name)
17273 * Save the offset of RData length
17274 */
17275 offset_data_len = resp_info->resp_len;
17276 resp_info->resp_len += sizeof(uint16_t);
17277
17278 if (!wlan_hdd_mdns_pack_response_type_ptr_dname(ini_config, resp_info,
17279 resptype_ptr_dn, resptype_ptr,
17280 resptype_txt, resptype_a)) {
17281 return FALSE;
17282 }
17283 /* Set the RData length */
17284 len = offset_data_len + sizeof(uint16_t);
17285 if ((resptype_ptr_dn->num_entries > 0) &&
17286 (resp_info->resp_len > len)) {
17287 value = resp_info->resp_len - len;
17288 val_u8 = (value & 0xff00) >> 8;
17289 resp_info->resp_data[offset_data_len] = val_u8;
17290 val_u8 = value & 0xff;
17291 resp_info->resp_data[offset_data_len+1] = val_u8;
17292 } else {
17293 hddLog(LOGE, FL("Fail to process mDNS response (%d)!"),
17294 MDNS_TYPE_PTR);
17295 return FALSE;
17296 }
17297
17298 EXIT();
17299 return TRUE;
17300}
17301
17302/**
17303 * wlan_hdd_mdns_pack_response_type_srv_target()- Pack Type Service Target
17304 * @ini_config: Pointer to the struct hdd_config_t
17305 * @resp_info: Pointer to the struct tSirMDNSResponseInfo
17306 * @resptype_srv_tgt: Pointer to the struct hdd_mdns_resp_info of Type Srv
17307 * target
17308 * @resptype_srv: Pointer to the struct hdd_mdns_resp_info of Type Srv
17309 * @resptype_ptr: Pointer to the struct hdd_mdns_resp_info of Type Ptr
17310 * @resptype_ptr_dn: Pointer to the struct hdd_mdns_resp_info of Type Ptr
17311 * domain name
17312 * @resptype_txt: Pointer to the struct hdd_mdns_resp_info of Type Txt
17313 * @resptype_a: Pointer to the struct hdd_mdns_resp_info of Type A
17314 *
17315 * The Type service target is one of the data field in the Type SRV response.
17316 * Also, it will find the matched QName from the existing resptype_srv,
17317 * resptype_ptr, resptype_ptr_dn, resptype_txt, resptype_a and then compress
17318 * the data.
17319 *
17320 * Return: Return boolean. TRUE for success, FALSE for fail.
17321 */
17322static bool
17323wlan_hdd_mdns_pack_response_type_srv_target(hdd_config_t *ini_config,
17324 sir_mdns_resp_info resp_info,
17325 struct hdd_mdns_resp_info *resptype_srv_tgt,
17326 struct hdd_mdns_resp_info *resptype_srv,
17327 struct hdd_mdns_resp_info *resptype_ptr,
17328 struct hdd_mdns_resp_info *resptype_ptr_dn,
17329 struct hdd_mdns_resp_info *resptype_txt,
17330 struct hdd_mdns_resp_info *resptype_a)
17331{
17332 uint8_t num_matched, num, size;
17333 struct hdd_mdns_resp_matched matchedlist[MAX_MDNS_RESP_TYPE-1];
17334 struct hdd_mdns_resp_info *resp;
17335
17336 if ((ini_config == NULL) || (resp_info == NULL) ||
17337 (resptype_srv == NULL) || (resptype_srv_tgt == NULL)) {
17338 hddLog(LOGE, FL("ini_config or response info is NULL!"));
17339 return FALSE;
17340 }
17341
17342 /* No Type Srv Target response */
17343 if (strlen((char *)ini_config->mdns_resp_type_srv_target) <= 0)
17344 return TRUE;
17345
17346 /* Wrong response is assigned, just ignore this response */
17347 if (!wlan_hdd_mdns_init_response(resptype_srv_tgt,
17348 ini_config->mdns_resp_type_srv_target, '.'))
17349 return TRUE;
17350
17351 /*
17352 * For data compression
17353 * Check if any strings are matched with previous response.
17354 */
17355 num = 0;
17356 size = (MAX_MDNS_RESP_TYPE-1);
17357 size *= sizeof(struct hdd_mdns_resp_matched);
17358 vos_mem_zero(matchedlist, size);
17359 num_matched = wlan_hdd_mdns_find_entries_from_end(resptype_srv_tgt,
17360 resptype_srv);
17361 if (num_matched > 0) {
17362 matchedlist[num].num_matched = num_matched;
17363 matchedlist[num].type = MDNS_TYPE_SRV;
17364 num++;
17365 }
17366 if (resptype_ptr && (resptype_ptr->num_entries > 0)) {
17367 if (resptype_ptr_dn && (resptype_ptr_dn->num_entries > 0)) {
17368 num_matched = wlan_hdd_mdns_find_entries_from_end(
17369 resptype_srv_tgt, resptype_ptr_dn);
17370 if (num_matched > 0) {
17371 matchedlist[num].num_matched = num_matched;
17372 matchedlist[num].type = MDNS_TYPE_PTR_DNAME;
17373 num++;
17374 }
17375 }
17376 num_matched = wlan_hdd_mdns_find_entries_from_end(
17377 resptype_srv_tgt, resptype_ptr);
17378 if (num_matched > 0) {
17379 matchedlist[num].num_matched = num_matched;
17380 matchedlist[num].type = MDNS_TYPE_PTR;
17381 num++;
17382 }
17383 }
17384 if (resptype_txt && (resptype_txt->num_entries > 0)) {
17385 num_matched = wlan_hdd_mdns_find_entries_from_end(
17386 resptype_srv_tgt, resptype_txt);
17387 if (num_matched > 0) {
17388 matchedlist[num].num_matched = num_matched;
17389 matchedlist[num].type = MDNS_TYPE_TXT;
17390 num++;
17391 }
17392 }
17393 if (resptype_a && (resptype_a->num_entries > 0)) {
17394 num_matched = wlan_hdd_mdns_find_entries_from_end(
17395 resptype_srv_tgt, resptype_a);
17396 if (num_matched > 0) {
17397 matchedlist[num].num_matched = num_matched;
17398 matchedlist[num].type = MDNS_TYPE_A;
17399 num++;
17400 }
17401 }
17402 if (num > 0) {
17403 if (num > 1)
17404 wlan_hdd_mdns_find_max(matchedlist, num);
17405 resp = NULL;
17406 switch (matchedlist[num-1].type) {
17407 case MDNS_TYPE_A:
17408 resp = resptype_a;
17409 break;
17410 case MDNS_TYPE_TXT:
17411 resp = resptype_txt;
17412 break;
17413 case MDNS_TYPE_PTR:
17414 resp = resptype_ptr;
17415 break;
17416 case MDNS_TYPE_PTR_DNAME:
17417 resp = resptype_ptr_dn;
17418 break;
17419 case MDNS_TYPE_SRV:
17420 resp = resptype_srv;
17421 break;
17422 default:
17423 hddLog(LOGE, FL("Fail to compress mDNS response "
17424 "(%d)!"), MDNS_TYPE_SRV_TARGET);
17425 return FALSE;
17426 }
17427 num_matched = matchedlist[num-1].num_matched;
17428 if (!wlan_hdd_mdns_compress_data(resp_info, resptype_srv_tgt,
17429 resp, num_matched)) {
17430 hddLog(LOGE, FL("Fail to compress mDNS response "
17431 "(%d)!"), MDNS_TYPE_SRV_TARGET);
17432 return FALSE;
17433 }
17434 } else {
17435 /* num = 0 -> no matched string */
17436 if (!wlan_hdd_mdns_process_response_dname(resptype_srv_tgt,
17437 resp_info)) {
17438 hddLog(LOGE, FL("Fail to process mDNS response (%d)!"),
17439 MDNS_TYPE_SRV_TARGET);
17440 return FALSE;
17441 }
17442 }
17443
17444 return TRUE;
17445}
17446
17447/**
17448 * wlan_hdd_mdns_pack_response_type_srv()- Pack Type Service response
17449 * @ini_config: Pointer to the struct hdd_config_t
17450 * @resp_info: Pointer to the struct tSirMDNSResponseInfo
17451 * @resptype_srv: Pointer to the struct hdd_mdns_resp_info of Type Srv
17452 * @resptype_srv_tgt: Pointer to the struct hdd_mdns_resp_info of Type Srv
17453 * target
17454 * @resptype_ptr: Pointer to the struct hdd_mdns_resp_info of Type Ptr
17455 * @resptype_ptr_dn: Pointer to the struct hdd_mdns_resp_info of Type Ptr
17456 * domain name
17457 * @resptype_txt: Pointer to the struct hdd_mdns_resp_info of Type Txt
17458 * @resptype_a: Pointer to the struct hdd_mdns_resp_info of Type A
17459 *
17460 * The Type SRV (Service) response include QName, response type, class, TTL
17461 * and four kinds of data fields. Also, it will find the matched QName from
17462 * the existing resptype_ptr, resptype_ptr_dn, resptype_txt, resptype_a and
17463 * then compress the data.
17464 *
17465 * Return: Return boolean. TRUE for success, FALSE for fail.
17466 */
17467static bool
17468wlan_hdd_mdns_pack_response_type_srv(hdd_config_t *ini_config,
17469 sir_mdns_resp_info resp_info,
17470 struct hdd_mdns_resp_info *resptype_srv,
17471 struct hdd_mdns_resp_info *resptype_srv_tgt,
17472 struct hdd_mdns_resp_info *resptype_ptr,
17473 struct hdd_mdns_resp_info *resptype_ptr_dn,
17474 struct hdd_mdns_resp_info *resptype_txt,
17475 struct hdd_mdns_resp_info *resptype_a)
17476{
17477 uint8_t num_matched, num, size;
17478 uint16_t value;
17479 uint8_t val_u8;
17480 uint32_t offset_data_len, len;
17481 struct hdd_mdns_resp_info *resp;
17482 struct hdd_mdns_resp_matched matchedlist[MAX_MDNS_RESP_TYPE-1];
17483
17484 ENTER();
17485
17486 if ((ini_config == NULL) || (resp_info == NULL) ||
17487 (resptype_srv == NULL) || (resptype_srv_tgt == NULL)) {
17488 hddLog(LOGE, FL("ini_config or response info is NULL!"));
17489 return FALSE;
17490 }
17491
17492 /* No Type Srv response */
17493 if (strlen((char *)ini_config->mdns_resp_type_srv) <= 0)
17494 return TRUE;
17495
17496 /* Wrong response is assigned, just ignore this response */
17497 if (!wlan_hdd_mdns_init_response(resptype_srv,
17498 ini_config->mdns_resp_type_srv, '.'))
17499 return TRUE;
17500
17501 /*
17502 * For data compression
17503 * Check if any strings are matched with Type A response
17504 */
17505 num = 0;
17506 size = (MAX_MDNS_RESP_TYPE-1);
17507 size *= sizeof(struct hdd_mdns_resp_matched);
17508 vos_mem_zero(matchedlist, size);
17509 if (resptype_ptr && (resptype_ptr->num_entries > 0)) {
17510 if (resptype_ptr_dn && (resptype_ptr_dn->num_entries > 0)) {
17511 num_matched = wlan_hdd_mdns_find_entries_from_end(
17512 resptype_srv,
17513 resptype_ptr_dn);
17514 if (num_matched > 0) {
17515 matchedlist[num].num_matched = num_matched;
17516 matchedlist[num].type = MDNS_TYPE_PTR_DNAME;
17517 num++;
17518 }
17519 }
17520 num_matched = wlan_hdd_mdns_find_entries_from_end(resptype_srv,
17521 resptype_ptr);
17522 if (num_matched > 0) {
17523 matchedlist[num].num_matched = num_matched;
17524 matchedlist[num].type = MDNS_TYPE_PTR;
17525 num++;
17526 }
17527 }
17528 if (resptype_txt && (resptype_txt->num_entries > 0)) {
17529 num_matched = wlan_hdd_mdns_find_entries_from_end(resptype_srv,
17530 resptype_txt);
17531 if (num_matched > 0) {
17532 matchedlist[num].num_matched =num_matched;
17533 matchedlist[num].type = MDNS_TYPE_TXT;
17534 num++;
17535 }
17536 }
17537 if (resptype_a && (resptype_a->num_entries > 0)) {
17538 num_matched = wlan_hdd_mdns_find_entries_from_end(resptype_srv,
17539 resptype_a);
17540 if (num_matched > 0) {
17541 matchedlist[num].num_matched = num_matched;
17542 matchedlist[num].type = MDNS_TYPE_A;
17543 num++;
17544 }
17545 }
17546 if (num > 0) {
17547 if (num > 1)
17548 wlan_hdd_mdns_find_max(matchedlist, num);
17549 resp = NULL;
17550 switch (matchedlist[num-1].type) {
17551 case MDNS_TYPE_A:
17552 resp = resptype_a;
17553 break;
17554 case MDNS_TYPE_TXT:
17555 resp = resptype_txt;
17556 break;
17557 case MDNS_TYPE_PTR:
17558 resp = resptype_ptr;
17559 break;
17560 case MDNS_TYPE_PTR_DNAME:
17561 resp = resptype_ptr_dn;
17562 break;
17563 default:
17564 hddLog(LOGE, FL("Fail to compress mDNS response "
17565 "(%d)!"), MDNS_TYPE_SRV);
17566 return FALSE;
17567 }
17568 num_matched = matchedlist[num-1].num_matched;
17569 if (!wlan_hdd_mdns_compress_data(resp_info, resptype_srv,
17570 resp, num_matched)) {
17571 hddLog(LOGE, FL("Fail to compress mDNS response "
17572 "(%d)!"), MDNS_TYPE_SRV);
17573 return FALSE;
17574 }
17575 } else {
17576 /* num = 0 -> no matched string */
17577 if (!wlan_hdd_mdns_process_response_dname(resptype_srv,
17578 resp_info)) {
17579 hddLog(LOGE, FL("Fail to process mDNS response (%d)!"),
17580 MDNS_TYPE_SRV);
17581 return FALSE;
17582 }
17583 }
17584
17585 /* Process response Type, Class, TTL */
17586 if (!wlan_hdd_mdns_process_response_misc(MDNS_TYPE_SRV, resp_info)) {
17587 hddLog(LOGE, FL("Fail to process mDNS misc response (%d)!"),
17588 MDNS_TYPE_SRV);
17589 return FALSE;
17590 }
17591
17592 /*
17593 * Process response RDLength, RData (Srv target name)
17594 * Save the offset of RData length
17595 */
17596 offset_data_len = resp_info->resp_len;
17597 resp_info->resp_len += sizeof(uint16_t);
17598
17599 len = resp_info->resp_len + (3 * sizeof(uint16_t));
17600 if (len >= MAX_MDNS_RESP_LEN) {
17601 hddLog(LOGE, FL("resp_len exceeds %d!"), MAX_MDNS_RESP_LEN);
17602 return FALSE;
17603 }
17604
17605 /* set Srv Priority */
17606 value = ini_config->mdns_resp_type_srv_priority;
17607 wlan_hdd_mdns_format_response_u16(value, resp_info);
17608 /* set Srv Weight */
17609 value = ini_config->mdns_resp_type_srv_weight;
17610 wlan_hdd_mdns_format_response_u16(value, resp_info);
17611 /* set Srv Port */
17612 value = ini_config->mdns_resp_type_srv_port;
17613 wlan_hdd_mdns_format_response_u16(value, resp_info);
17614
17615 if (!wlan_hdd_mdns_pack_response_type_srv_target(ini_config, resp_info,
17616 resptype_srv_tgt, resptype_srv,
17617 resptype_ptr, resptype_ptr_dn,
17618 resptype_txt, resptype_a)) {
17619 return FALSE;
17620 }
17621 /* Set the RData length */
17622 len = offset_data_len + sizeof(uint16_t);
17623 if ((resptype_srv_tgt->num_entries > 0) &&
17624 (resp_info->resp_len > len)) {
17625 value = resp_info->resp_len - len;
17626 val_u8 = (value & 0xff00) >> 8;
17627 resp_info->resp_data[offset_data_len] = val_u8;
17628 val_u8 = value & 0xff;
17629 resp_info->resp_data[offset_data_len+1] = val_u8;
17630 } else {
17631 hddLog(LOGE, FL("Fail to process mDNS response (%d)!"),
17632 MDNS_TYPE_SRV);
17633 return FALSE;
17634 }
17635
17636 EXIT();
17637 return TRUE;
17638}
17639
17640/**
17641 * wlan_hdd_mdns_free_mem() - Free the allocated memory
17642 * @response: Pointer to the struct hdd_mdns_resp_info
17643 *
17644 * Return: None
17645 */
17646static void wlan_hdd_mdns_free_mem(struct hdd_mdns_resp_info *response)
17647{
17648 if (response && response->data)
17649 vos_mem_free(response->data);
17650 if (response && response->offset)
17651 vos_mem_free(response->offset);
17652}
17653
17654/**
17655 * wlan_hdd_mdns_pack_response() - Pack mDNS response
17656 * @ini_config: Pointer to the struct hdd_config_t
17657 * @resp_info: Pointer to the struct tSirMDNSResponseInfo
17658 *
17659 * This function will pack four types of responses (Type A, Type Txt, Type Ptr
17660 * and Type Service). Each response contains QName, response type, class, TTL
17661 * and data fields.
17662 *
17663 * Return: Return boolean. TRUE for success, FALSE for fail.
17664 */
17665static bool wlan_hdd_mdns_pack_response(hdd_config_t *ini_config,
17666 sir_mdns_resp_info resp_info)
17667{
17668 struct hdd_mdns_resp_info resptype_a, resptype_txt;
17669 struct hdd_mdns_resp_info resptype_ptr, resptype_ptr_dn;
17670 struct hdd_mdns_resp_info resptype_srv, resptype_srv_tgt;
17671 uint32_t num_res_records = 0;
17672 bool status = FALSE;
17673
17674 ENTER();
17675
17676 wlan_hdd_mdns_reset_response(&resptype_a);
17677 wlan_hdd_mdns_reset_response(&resptype_txt);
17678 wlan_hdd_mdns_reset_response(&resptype_ptr);
17679 wlan_hdd_mdns_reset_response(&resptype_ptr_dn);
17680 wlan_hdd_mdns_reset_response(&resptype_srv);
17681 wlan_hdd_mdns_reset_response(&resptype_srv_tgt);
17682
17683 resp_info->resp_len = 0;
17684
17685 /* Process Type A response */
17686 if (!wlan_hdd_mdns_pack_response_type_a(ini_config, resp_info,
17687 &resptype_a))
17688 goto err_resptype_a;
17689
17690 if ((resptype_a.num_entries > 0) &&
17691 (strlen((char *)&resptype_a.data[0]) > 0))
17692 num_res_records++;
17693
17694 /* Process Type TXT response */
17695 if (!wlan_hdd_mdns_pack_response_type_txt(ini_config, resp_info,
17696 &resptype_txt, &resptype_a))
17697 goto err_resptype_txt;
17698
17699 if ((resptype_txt.num_entries > 0) &&
17700 (strlen((char *)&resptype_txt.data[0]) > 0))
17701 num_res_records++;
17702
17703 /* Process Type PTR response */
17704 if (!wlan_hdd_mdns_pack_response_type_ptr(ini_config, resp_info,
17705 &resptype_ptr, &resptype_ptr_dn,
17706 &resptype_txt, &resptype_a))
17707 goto err_resptype_ptr;
17708
17709 if ((resptype_ptr.num_entries > 0) &&
17710 (strlen((char *)&resptype_ptr.data[0]) > 0))
17711 num_res_records++;
17712
17713 /* Process Type SRV response */
17714 if (!wlan_hdd_mdns_pack_response_type_srv(ini_config, resp_info,
17715 &resptype_srv, &resptype_srv_tgt,
17716 &resptype_ptr, &resptype_ptr_dn,
17717 &resptype_txt, &resptype_a))
17718 goto err_resptype_srv;
17719
17720 if ((resptype_srv.num_entries > 0) &&
17721 (strlen((char *)&resptype_srv.data[0]) > 0))
17722 num_res_records++;
17723
17724 resp_info->resourceRecord_count = num_res_records;
17725 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
17726 "%s: Pack mDNS response data successfully!", __func__);
17727 status = TRUE;
17728
17729err_resptype_srv:
17730 wlan_hdd_mdns_free_mem(&resptype_srv);
17731 wlan_hdd_mdns_free_mem(&resptype_srv_tgt);
17732
17733err_resptype_ptr:
17734 wlan_hdd_mdns_free_mem(&resptype_ptr);
17735 wlan_hdd_mdns_free_mem(&resptype_ptr_dn);
17736
17737err_resptype_txt:
17738 wlan_hdd_mdns_free_mem(&resptype_txt);
17739
17740err_resptype_a:
17741 wlan_hdd_mdns_free_mem(&resptype_a);
17742
17743 EXIT();
17744 return status;
17745}
17746
17747/**
17748 * wlan_hdd_set_mdns_offload() - Enable mDNS offload
17749 * @hostapd_adapter: Pointer to the struct hdd_adapter_t
17750 *
17751 * This function will set FQDN/unique FQDN (full qualified domain name)
17752 * and the mDNS response. Then send them to SME.
17753 *
17754 * Return: Return boolean. TRUE for success, FALSE for fail.
17755 */
17756bool wlan_hdd_set_mdns_offload(hdd_adapter_t *hostapd_adapter)
17757{
17758 hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(hostapd_adapter);
17759 sir_mdns_offload_info mdns_offload_info;
17760 sir_mdns_fqdn_info mdns_fqdn_info;
17761 sir_mdns_resp_info mdns_resp_info;
17762 uint32_t fqdn_len, ufqdn_len;
17763
17764 ENTER();
17765
17766 /* 1. Prepare the MDNS fqdn request to send to SME */
17767 fqdn_len = strlen(hdd_ctx->cfg_ini->mdns_fqdn);
17768 ufqdn_len = strlen(hdd_ctx->cfg_ini->mdns_uniquefqdn);
17769 if ((fqdn_len == 0) && (ufqdn_len == 0)) {
17770 hddLog(LOGE, FL("No mDNS FQDN or UFQDN is assigned fqdn_len %d,"
17771 "ufqdn_len %d!"), fqdn_len, ufqdn_len);
17772 return FALSE;
17773 }
17774
17775 mdns_fqdn_info = vos_mem_malloc(sizeof(*mdns_fqdn_info));
17776 if (NULL == mdns_fqdn_info) {
17777 hddLog(LOGE, FL("could not allocate tSirMDNSFqdnInfo!"));
17778 return FALSE;
17779 }
17780 /* MDNS fqdn request */
17781 if (fqdn_len > 0) {
17782 vos_mem_zero(mdns_fqdn_info, sizeof(*mdns_fqdn_info));
17783 mdns_fqdn_info->bss_idx = hostapd_adapter->sessionId;
17784 mdns_fqdn_info->fqdn_type = MDNS_FQDN_TYPE_GENERAL;
17785 mdns_fqdn_info->fqdn_len = fqdn_len;
17786 mdns_fqdn_info->mdns_fqdn_callback = hdd_mdns_fqdn_offload_done;
17787 mdns_fqdn_info->mdns_fqdn_cb_context = hostapd_adapter;
17788 vos_mem_copy(mdns_fqdn_info->fqdn_data,
17789 hdd_ctx->cfg_ini->mdns_fqdn,
17790 mdns_fqdn_info->fqdn_len);
17791
17792 if (eHAL_STATUS_SUCCESS !=
17793 sme_set_mdns_fqdn(hdd_ctx->hHal, mdns_fqdn_info)) {
17794 hddLog(LOGE, FL("sme_set_mdns_fqdn fail!"));
17795 vos_mem_free(mdns_fqdn_info);
17796 return FALSE;
17797 }
17798 }
17799 /* MDNS unique fqdn request */
17800 if (ufqdn_len > 0) {
17801 vos_mem_zero(mdns_fqdn_info, sizeof(*mdns_fqdn_info));
17802 mdns_fqdn_info->bss_idx = hostapd_adapter->sessionId;
17803 mdns_fqdn_info->fqdn_type = MDNS_FQDN_TYPE_UNIQUE;
17804 mdns_fqdn_info->fqdn_len = ufqdn_len;
17805 mdns_fqdn_info->mdns_fqdn_callback = hdd_mdns_fqdn_offload_done;
17806 mdns_fqdn_info->mdns_fqdn_cb_context = hostapd_adapter;
17807 vos_mem_copy(mdns_fqdn_info->fqdn_data,
17808 hdd_ctx->cfg_ini->mdns_uniquefqdn,
17809 mdns_fqdn_info->fqdn_len);
17810 if (eHAL_STATUS_SUCCESS !=
17811 sme_set_mdns_fqdn(hdd_ctx->hHal, mdns_fqdn_info)) {
17812 hddLog(LOGE, FL("sme_set_mdns_fqdn fail!"));
17813 vos_mem_free(mdns_fqdn_info);
17814 return FALSE;
17815 }
17816 }
17817 vos_mem_free(mdns_fqdn_info);
17818
17819 /* 2. Prepare the MDNS response request to send to SME */
17820 mdns_resp_info = vos_mem_malloc(sizeof(*mdns_resp_info));
17821 if (NULL == mdns_resp_info) {
17822 hddLog(LOGE, FL("could not allocate tSirMDNSResponseInfo!"));
17823 return FALSE;
17824 }
17825
17826 vos_mem_zero(mdns_resp_info, sizeof(*mdns_resp_info));
17827 mdns_resp_info->bss_idx = hostapd_adapter->sessionId;
17828 mdns_resp_info->mdns_resp_callback = hdd_mdns_resp_offload_done;
17829 mdns_resp_info->mdns_resp_cb_context = hostapd_adapter;
17830 if (!wlan_hdd_mdns_pack_response(hdd_ctx->cfg_ini, mdns_resp_info)) {
17831 hddLog(LOGE, FL("wlan_hdd_pack_mdns_response fail!"));
17832 vos_mem_free(mdns_resp_info);
17833 return FALSE;
17834 }
17835 if (eHAL_STATUS_SUCCESS !=
17836 sme_set_mdns_resp(hdd_ctx->hHal, mdns_resp_info)) {
17837 hddLog(LOGE, FL("sme_set_mdns_resp fail!"));
17838 vos_mem_free(mdns_resp_info);
17839 return FALSE;
17840 }
17841 vos_mem_free(mdns_resp_info);
17842
17843 /* 3. Prepare the MDNS Enable request to send to SME */
17844 mdns_offload_info = vos_mem_malloc(sizeof(*mdns_offload_info));
17845 if (NULL == mdns_offload_info) {
17846 hddLog(LOGE, FL("could not allocate tSirMDNSOffloadInfo!"));
17847 return FALSE;
17848 }
17849
17850 vos_mem_zero(mdns_offload_info, sizeof(*mdns_offload_info));
17851
17852 mdns_offload_info->bss_idx = hostapd_adapter->sessionId;
17853 mdns_offload_info->enable = hdd_ctx->cfg_ini->enable_mdns_offload;
17854 mdns_offload_info->mdns_enable_callback = hdd_mdns_enable_offload_done;
17855 mdns_offload_info->mdns_enable_cb_context = hostapd_adapter;
17856 if (eHAL_STATUS_SUCCESS !=
17857 sme_set_mdns_offload(hdd_ctx->hHal, mdns_offload_info)) {
17858 hddLog(LOGE, FL("sme_set_mdns_offload fail!"));
17859 vos_mem_free(mdns_offload_info);
17860 return FALSE;
17861 }
17862
17863 vos_mem_free(mdns_offload_info);
17864 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
17865 "%s: enable mDNS offload successfully!", __func__);
17866 return TRUE;
17867}
Manjeet Singh3ed79242017-01-11 19:04:32 +053017868
17869
Anurag Chouhan0b29de02016-12-16 13:18:40 +053017870#endif /* MDNS_OFFLOAD */
c_manjeecfd1efb2015-09-25 19:32:34 +053017871
Hanumanth Reddy Pothulad864f312017-01-18 16:16:08 +053017872/**
17873 * wlan_hdd_start_sap() - This function starts bss of SAP.
17874 * @ap_adapter: SAP adapter
17875 *
17876 * This function will process the starting of sap adapter.
17877 *
17878 * Return: void.
17879 */
17880void wlan_hdd_start_sap(hdd_adapter_t *ap_adapter)
17881{
17882 hdd_ap_ctx_t *hdd_ap_ctx;
17883 hdd_hostapd_state_t *hostapd_state;
17884 VOS_STATUS vos_status;
17885 hdd_context_t *hdd_ctx;
17886 tsap_Config_t *pConfig;
17887
17888 if (NULL == ap_adapter) {
17889 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17890 FL("ap_adapter is NULL here"));
17891 return;
17892 }
17893
17894 hdd_ctx = WLAN_HDD_GET_CTX(ap_adapter);
17895 hdd_ap_ctx = WLAN_HDD_GET_AP_CTX_PTR(ap_adapter);
17896 hostapd_state = WLAN_HDD_GET_HOSTAP_STATE_PTR(ap_adapter);
17897 pConfig = &ap_adapter->sessionCtx.ap.sapConfig;
17898
17899 mutex_lock(&hdd_ctx->sap_lock);
17900 if (test_bit(SOFTAP_BSS_STARTED, &ap_adapter->event_flags))
17901 goto end;
17902
17903 if (0 != wlan_hdd_cfg80211_update_apies(ap_adapter)) {
17904 hddLog(LOGE, FL("SAP Not able to set AP IEs"));
17905 goto end;
17906 }
17907
17908 vos_event_reset(&hostapd_state->vosEvent);
17909 if (WLANSAP_StartBss(hdd_ctx->pvosContext, hdd_hostapd_SAPEventCB,
17910 &hdd_ap_ctx->sapConfig, (v_PVOID_t)ap_adapter->dev)
17911 != VOS_STATUS_SUCCESS) {
17912 goto end;
17913 }
17914
17915 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
17916 FL("Waiting for SAP to start"));
17917 vos_status = vos_wait_single_event(&hostapd_state->vosEvent, 10000);
17918 if (!VOS_IS_STATUS_SUCCESS(vos_status)) {
17919 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17920 FL("SAP Start failed"));
17921 goto end;
17922 }
17923 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
17924 FL("SAP Start Success"));
17925 set_bit(SOFTAP_BSS_STARTED, &ap_adapter->event_flags);
17926
17927 wlan_hdd_incr_active_session(hdd_ctx, ap_adapter->device_mode);
17928 hostapd_state->bCommit = TRUE;
17929
17930end:
17931 mutex_unlock(&hdd_ctx->sap_lock);
17932 return;
17933}
17934
Manjeet Singh3ed79242017-01-11 19:04:32 +053017935#ifdef WLAN_FEATURE_TSF
17936
17937/**
17938 * hdd_tsf_cb() - handle tsf request callback
17939 *
17940 * @pcb_cxt: pointer to the hdd_contex
17941 * @ptsf: pointer to struct stsf
17942 *
17943 * Based on the request sent .
17944 *
17945 * Return: Describe the execute result of this routine
17946 */
17947static int hdd_tsf_cb(void *pcb_ctx, struct stsf *ptsf)
17948{
17949 hdd_context_t *hddctx;
17950 int status;
17951 hdd_adapter_t* adapter = (hdd_adapter_t*)pcb_ctx;
17952
17953 if (pcb_ctx == NULL || ptsf == NULL) {
17954 hddLog(VOS_TRACE_LEVEL_ERROR,
17955 FL("HDD context is not valid"));
17956 return -EINVAL;
17957 }
17958
17959 hddctx = (hdd_context_t *)pcb_ctx;
17960 status = wlan_hdd_validate_context(hddctx);
17961 if (0 != status)
17962 return -EINVAL;
17963
17964 if (NULL == adapter) {
17965 hddLog(VOS_TRACE_LEVEL_ERROR,
17966 FL("failed to find adapter"));
17967 return -EINVAL;
17968 }
17969
17970 hddLog(VOS_TRACE_LEVEL_INFO,
17971 FL("tsf cb handle event, device_mode is %d"),
17972 adapter->device_mode);
17973
17974 /* copy the return value to hdd_tsf_ctx in adapter*/
17975 if (ptsf->tsf_req_status) {
17976
17977 vos_spin_lock_acquire(&adapter->tsf_cap_ctx.tsf_lock);
17978 adapter->tsf_cap_ctx.tsf_get_state = TSF_NOT_RETURNED_BY_FW;
17979 adapter->tsf_cap_ctx.tsf_capture_state = TSF_IDLE;
17980 vos_event_set (&adapter->tsf_cap_ctx.tsf_capture_done_event);
17981 vos_spin_lock_release(&adapter->tsf_cap_ctx.tsf_lock);
17982
17983 hddLog(VOS_TRACE_LEVEL_ERROR, FL("tsf req failure :%d"),
17984 ptsf->tsf_req_status);
17985 return ptsf->tsf_req_status;
17986 }
17987 /* If this is a get request.Store the tsf values in adapter. */
17988 if (!ptsf->set_tsf_req) {
17989 vos_spin_lock_acquire(&adapter->tsf_cap_ctx.tsf_lock);
17990 adapter->tsf_cap_ctx.tsf_low = ptsf->tsf_low;
17991 adapter->tsf_cap_ctx.tsf_high = ptsf->tsf_high;
17992 adapter->tsf_cap_ctx.tsf_get_state = TSF_RETURN;
17993 adapter->tsf_cap_ctx.tsf_capture_state = TSF_IDLE;
17994 vos_spin_lock_release(&adapter->tsf_cap_ctx.tsf_lock);
17995
17996 hddLog(VOS_TRACE_LEVEL_INFO,
17997 FL("hdd_get_tsf_cb sta=%u, tsf_low=%u, tsf_high=%u"),
17998 adapter->sessionId, ptsf->tsf_low, ptsf->tsf_high);
17999 }
18000 else {
18001 vos_spin_lock_acquire(&adapter->tsf_cap_ctx.tsf_lock);
18002 adapter->tsf_cap_ctx.tsf_capture_state = TSF_CAP_STATE;
18003 adapter->tsf_cap_ctx.tsf_get_state = TSF_CURRENT_IN_CAP_STATE;
18004 vos_spin_lock_release(&adapter->tsf_cap_ctx.tsf_lock);
18005 }
18006 vos_spin_lock_acquire(&adapter->tsf_cap_ctx.tsf_lock);
18007 vos_event_set (&adapter->tsf_cap_ctx.tsf_capture_done_event);
18008 vos_spin_lock_release(&adapter->tsf_cap_ctx.tsf_lock);
18009
18010 /* free allocated mem */
18011 vos_mem_free(ptsf);
18012
18013 return 0;
18014}
18015
18016/**
18017 * hdd_capture_tsf() - capture tsf
18018 *
18019 * @adapter: pointer to adapter
18020 * @buf: pointer to upper layer buf
18021 * @len : the length of buf
18022 *
18023 * This function returns tsf value to uplayer.
18024 *
18025 * Return: Describe the execute result of this routine
18026 */
18027int hdd_capture_tsf(hdd_adapter_t *adapter, uint32_t *buf, int len)
18028{
18029 int ret = 0;
18030 hdd_station_ctx_t *hdd_sta_ctx;
18031 hdd_context_t *hdd_ctx;
18032 tSirCapTsfParams cap_tsf_params;
18033 VOS_STATUS status;
18034
18035 if (adapter == NULL || buf == NULL) {
18036 hddLog(VOS_TRACE_LEVEL_ERROR,
18037 FL("invalid pointer"));
18038 return -EINVAL;
18039 }
18040 if (len != 1)
18041 return -EINVAL;
18042
18043 hdd_ctx = WLAN_HDD_GET_CTX(adapter);
18044
18045 if (wlan_hdd_validate_context(hdd_ctx)) {
18046 hddLog(VOS_TRACE_LEVEL_ERROR,
18047 FL("invalid hdd ctx"));
18048 return -EINVAL;
18049 }
18050 if (adapter->device_mode == WLAN_HDD_INFRA_STATION ||
18051 adapter->device_mode == WLAN_HDD_P2P_CLIENT) {
18052 hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
18053 if (hdd_sta_ctx->conn_info.connState !=
18054 eConnectionState_Associated) {
18055
18056 hddLog(VOS_TRACE_LEVEL_INFO,
18057 FL("failed to cap tsf, not connect with ap"));
18058 buf[0] = TSF_STA_NOT_CONNECTED_NO_TSF;
18059 return ret;
18060 }
18061 }
18062 if ((adapter->device_mode == WLAN_HDD_SOFTAP ||
18063 adapter->device_mode == WLAN_HDD_P2P_GO) &&
18064 !(test_bit(SOFTAP_BSS_STARTED, &adapter->event_flags))) {
18065 hddLog(VOS_TRACE_LEVEL_INFO,
18066 FL("Soft AP / P2p GO not beaconing"));
18067 buf[0] = TSF_SAP_NOT_STARTED_NO_TSF;
18068 return ret;
18069 }
18070 if (adapter->tsf_cap_ctx.tsf_capture_state == TSF_CAP_STATE) {
18071 hddLog(VOS_TRACE_LEVEL_INFO,
18072 FL("current in capture state, pls reset"));
18073 buf[0] = TSF_CURRENT_IN_CAP_STATE;
18074 } else {
18075 hddLog(VOS_TRACE_LEVEL_INFO, FL("ioctl issue cap tsf cmd"));
18076 buf[0] = TSF_RETURN;
18077 cap_tsf_params.session_id = adapter->sessionId;
18078 cap_tsf_params.tsf_rsp_cb_func = hdd_tsf_cb;
18079 cap_tsf_params.tsf_rsp_cb_ctx = adapter;
18080
18081 vos_spin_lock_acquire(&adapter->tsf_cap_ctx.tsf_lock);
18082 adapter->tsf_cap_ctx.tsf_capture_state = TSF_CAP_STATE;
18083 adapter->tsf_cap_ctx.tsf_get_state = TSF_CURRENT_IN_CAP_STATE;
18084 vos_spin_lock_release(&adapter->tsf_cap_ctx.tsf_lock);
18085
18086 ret = sme_capture_tsf_req(hdd_ctx->hHal, cap_tsf_params);
18087
18088 if (ret != VOS_STATUS_SUCCESS) {
18089 hddLog(VOS_TRACE_LEVEL_ERROR, FL("capture fail"));
18090 buf[0] = TSF_CAPTURE_FAIL;
18091 vos_spin_lock_acquire(&adapter->tsf_cap_ctx.tsf_lock);
18092 adapter->tsf_cap_ctx.tsf_capture_state = TSF_IDLE;
18093 vos_spin_lock_release(&adapter->tsf_cap_ctx.tsf_lock);
18094 return -EINVAL;
18095 }
18096 /* wait till we get a response from fw */
18097 status = vos_wait_single_event(&adapter->tsf_cap_ctx.
18098 tsf_capture_done_event,
18099 HDD_TSF_CAP_REQ_TIMEOUT);
18100
18101 if (!VOS_IS_STATUS_SUCCESS(status)) {
18102 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18103 ("capture tsf vos wait for single_event failed!! %d"),
18104 adapter->tsf_cap_ctx.tsf_get_state);
18105
18106 vos_spin_lock_acquire(&adapter->tsf_cap_ctx.tsf_lock);
18107 adapter->tsf_cap_ctx.tsf_capture_state = TSF_IDLE;
18108 vos_spin_lock_release(&adapter->tsf_cap_ctx.tsf_lock);
18109
18110 return -EINVAL;
18111 }
18112 }
18113 buf[0] = TSF_RETURN;
18114 hddLog(VOS_TRACE_LEVEL_INFO,
18115 FL("ioctl return cap tsf cmd, ret = %d"), ret);
18116 return ret;
18117}
18118
18119/**
18120 * hdd_indicate_tsf() - return tsf to uplayer
18121 *
18122 * @adapter: pointer to adapter
18123 * @buf: pointer to uplayer buf
18124 * @len : the length of buf
18125 *
18126 * This function returns tsf value to uplayer.
18127 *
18128 * Return: Describe the execute result of this routine
18129 */
18130int hdd_indicate_tsf(hdd_adapter_t *adapter, uint32_t *buf, int len)
18131{
18132 int ret = 0;
18133 hdd_station_ctx_t *hdd_sta_ctx;
18134 hdd_context_t *hdd_ctx;
18135 tSirCapTsfParams cap_tsf_params;
18136 VOS_STATUS status;
18137
18138 if (adapter == NULL || buf == NULL) {
18139 hddLog(VOS_TRACE_LEVEL_ERROR,
18140 FL("invalid pointer"));
18141 return -EINVAL;
18142 }
18143 if (len != 3)
18144 return -EINVAL;
18145
18146 buf [1] = 0;
18147 buf [2] = 0;
18148 hdd_ctx = WLAN_HDD_GET_CTX(adapter);
18149
18150 if (wlan_hdd_validate_context(hdd_ctx)) {
18151 hddLog(VOS_TRACE_LEVEL_ERROR,
18152 FL("invalid hdd ctx"));
18153 return -EINVAL;
18154 }
18155 if (adapter->device_mode == WLAN_HDD_INFRA_STATION ||
18156 adapter->device_mode == WLAN_HDD_P2P_CLIENT) {
18157 hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
18158 if (hdd_sta_ctx->conn_info.connState !=
18159 eConnectionState_Associated) {
18160
18161 hddLog(VOS_TRACE_LEVEL_INFO,
18162 FL("failed to cap tsf, not connect with ap"));
18163 buf[0] = TSF_STA_NOT_CONNECTED_NO_TSF;
18164 return ret;
18165 }
18166 }
18167 if ((adapter->device_mode == WLAN_HDD_SOFTAP ||
18168 adapter->device_mode == WLAN_HDD_P2P_GO) &&
18169 !(test_bit(SOFTAP_BSS_STARTED, &adapter->event_flags))) {
18170 hddLog(VOS_TRACE_LEVEL_INFO,
18171 FL("Soft AP / P2p GO not beaconing"));
18172 buf[0] = TSF_SAP_NOT_STARTED_NO_TSF;
18173 return ret;
18174 }
18175
18176 if (adapter->tsf_cap_ctx.tsf_capture_state != TSF_CAP_STATE ||
18177 adapter->tsf_cap_ctx.tsf_get_state != TSF_CURRENT_IN_CAP_STATE ) {
18178 hddLog(VOS_TRACE_LEVEL_INFO,
18179 FL("Not in capture state,Enter capture state first"));
18180 buf[0] = TSF_GET_FAIL;
18181 } else {
18182 hddLog(VOS_TRACE_LEVEL_INFO, FL("ioctl issue cap tsf cmd"));
18183 cap_tsf_params.session_id = adapter->sessionId;
18184 cap_tsf_params.tsf_rsp_cb_func = hdd_tsf_cb;
18185 cap_tsf_params.tsf_rsp_cb_ctx = adapter;
18186
18187 ret = sme_get_tsf_req(hdd_ctx->hHal, cap_tsf_params);
18188
18189 if (ret != VOS_STATUS_SUCCESS) {
18190 hddLog(VOS_TRACE_LEVEL_ERROR, FL("capture fail"));
18191 buf[0] = TSF_CAPTURE_FAIL;
18192 vos_spin_lock_acquire(&adapter->tsf_cap_ctx.tsf_lock);
18193 adapter->tsf_cap_ctx.tsf_capture_state = TSF_IDLE;
18194 vos_spin_lock_release(&adapter->tsf_cap_ctx.tsf_lock);
18195 return -EINVAL;
18196 }
18197 /* wait till we get a response from fw */
18198 status = vos_wait_single_event(&adapter->tsf_cap_ctx.
18199 tsf_capture_done_event,
18200 HDD_TSF_GET_REQ_TIMEOUT);
18201
18202 if (!VOS_IS_STATUS_SUCCESS(status)) {
18203 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18204 ("capture tsf vos wait for single_event failed!! %d"),
18205 status);
18206
18207 vos_spin_lock_acquire(&adapter->tsf_cap_ctx.tsf_lock);
18208 adapter->tsf_cap_ctx.tsf_capture_state = TSF_IDLE;
18209 vos_spin_lock_release(&adapter->tsf_cap_ctx.tsf_lock);
18210 return status;
18211 }
18212 buf[1] = adapter->tsf_cap_ctx.tsf_low;
18213 buf[2] = adapter->tsf_cap_ctx.tsf_high;
18214
18215 hddLog(VOS_TRACE_LEVEL_INFO,
18216 FL("get tsf cmd,status=%u, tsf_low=%u, tsf_high=%u"),
18217 buf[0], buf[1], buf[2]);
18218 }
18219 hddLog(VOS_TRACE_LEVEL_INFO,
18220 FL("ioctl return cap tsf cmd, ret = %d"), ret);
18221 return ret;
18222}
18223
18224void wlan_hdd_tsf_init(hdd_adapter_t *adapter)
18225{
18226
18227 if (adapter == NULL) {
18228 hddLog(VOS_TRACE_LEVEL_ERROR,
18229 FL("TSF init on a null adapter!"));
18230 return;
18231 }
18232
18233 adapter->tsf_cap_ctx.tsf_get_state = TSF_RETURN;
18234 adapter->tsf_cap_ctx.tsf_capture_state = TSF_IDLE;
18235 vos_event_init(&adapter->tsf_cap_ctx.tsf_capture_done_event);
18236 vos_spin_lock_init(&adapter->tsf_cap_ctx.tsf_lock);
18237 adapter->tsf_cap_ctx.tsf_high = 0;
18238 adapter->tsf_cap_ctx.tsf_low = 0;
18239}
18240
18241#endif
18242
Hanumanth Reddy Pothula972e1df2018-06-14 13:33:47 +053018243bool hdd_is_cli_iface_up(hdd_context_t *hdd_ctx)
18244{
18245 hdd_adapter_list_node_t *adapter_node = NULL, *next = NULL;
18246 hdd_adapter_t *adapter;
18247 VOS_STATUS status;
18248
18249 status = hdd_get_front_adapter(hdd_ctx, &adapter_node);
18250 while (NULL != adapter_node && VOS_STATUS_SUCCESS == status) {
18251 adapter = adapter_node->pAdapter;
18252 if ((adapter->device_mode == WLAN_HDD_INFRA_STATION ||
18253 adapter->device_mode == WLAN_HDD_P2P_CLIENT) &&
18254 test_bit(DEVICE_IFACE_OPENED,
18255 &adapter->event_flags)){
18256 return true;
18257 }
18258 status = hdd_get_next_adapter(hdd_ctx, adapter_node, &next);
18259 adapter_node = next;
18260 }
18261
18262 return false;
18263}
18264
Jeff Johnson295189b2012-06-20 16:38:30 -070018265//Register the module init/exit functions
18266module_init(hdd_module_init);
18267module_exit(hdd_module_exit);
18268
18269MODULE_LICENSE("Dual BSD/GPL");
18270MODULE_AUTHOR("Qualcomm Atheros, Inc.");
18271MODULE_DESCRIPTION("WLAN HOST DEVICE DRIVER");
18272
Ashish Kumar Dhanotiyafb3fd972018-04-30 12:46:52 +053018273static const struct kernel_param_ops con_mode_ops = {
18274 .set = con_mode_handler,
18275 .get = param_get_int,
18276};
18277
18278static const struct kernel_param_ops fwpath_ops = {
18279 .set = fwpath_changed_handler,
18280 .get = param_get_string,
18281};
18282
Hanumanth Reddy Pothula99219872018-06-08 14:45:18 +053018283#ifdef MODULE
18284module_param(con_mode, int, 0);
18285#else
Ashish Kumar Dhanotiyafb3fd972018-04-30 12:46:52 +053018286module_param_cb(con_mode, &con_mode_ops, &con_mode,
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070018287 S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
Hanumanth Reddy Pothula99219872018-06-08 14:45:18 +053018288#endif
Jeff Johnson32d95a32012-09-10 13:15:23 -070018289
Ashish Kumar Dhanotiyafb3fd972018-04-30 12:46:52 +053018290module_param_cb(fwpath, &fwpath_ops, &fwpath,
Jeff Johnson32d95a32012-09-10 13:15:23 -070018291 S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
Arif Hussain66559122013-11-21 10:11:40 -080018292
18293module_param(enable_dfs_chan_scan, int,
18294 S_IRUSR | S_IRGRP | S_IROTH);
18295
18296module_param(enable_11d, int,
18297 S_IRUSR | S_IRGRP | S_IROTH);
18298
18299module_param(country_code, charp,
18300 S_IRUSR | S_IRGRP | S_IROTH);