blob: de28b13b7556d41aad30037ca74b45ac91bd6439 [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{
310 struct net_device *dev = ndev;
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -0700311 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Jeff Johnson27cee452013-03-27 11:10:24 -0700312 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -0700313#ifdef WLAN_BTAMP_FEATURE
314 VOS_STATUS status;
Jeff Johnson295189b2012-06-20 16:38:30 -0700315#endif
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +0530316 long result;
Jeff Johnson295189b2012-06-20 16:38:30 -0700317
318 //Make sure that this callback corresponds to our device.
Jeff Johnson27cee452013-03-27 11:10:24 -0700319 if ((strncmp(dev->name, "wlan", 4)) &&
Amar Singhal4c723bd2013-03-25 18:14:15 -0700320 (strncmp(dev->name, "p2p", 3)))
321 return NOTIFY_DONE;
322
Jeff Johnson295189b2012-06-20 16:38:30 -0700323 if (!dev->ieee80211_ptr)
Jeff Johnson27cee452013-03-27 11:10:24 -0700324 return NOTIFY_DONE;
Jeff Johnson295189b2012-06-20 16:38:30 -0700325
Jeff Johnson27cee452013-03-27 11:10:24 -0700326 if (NULL == pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -0700327 {
Jeff Johnsona8a1a482012-12-12 16:49:33 -0800328 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: HDD Adapter Null Pointer", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700329 VOS_ASSERT(0);
330 return NOTIFY_DONE;
331 }
332
Jeff Johnson27cee452013-03-27 11:10:24 -0700333 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
334 if (NULL == pHddCtx)
335 {
336 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: HDD Context Null Pointer", __func__);
337 VOS_ASSERT(0);
338 return NOTIFY_DONE;
339 }
Sameer Thalappil14067972014-01-23 14:54:54 -0800340 if (pHddCtx->isLogpInProgress)
341 return NOTIFY_DONE;
342
Jeff Johnson27cee452013-03-27 11:10:24 -0700343
344 hddLog(VOS_TRACE_LEVEL_INFO, "%s: %s New Net Device State = %lu",
345 __func__, dev->name, state);
Jeff Johnson295189b2012-06-20 16:38:30 -0700346
347 switch (state) {
348 case NETDEV_REGISTER:
349 break;
350
351 case NETDEV_UNREGISTER:
352 break;
353
354 case NETDEV_UP:
355 break;
356
357 case NETDEV_DOWN:
358 break;
359
360 case NETDEV_CHANGE:
Jeff Johnsone7245742012-09-05 17:12:55 -0700361 if(TRUE == pAdapter->isLinkUpSvcNeeded)
362 complete(&pAdapter->linkup_event_var);
Jeff Johnson295189b2012-06-20 16:38:30 -0700363 break;
364
365 case NETDEV_GOING_DOWN:
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +0530366 result = wlan_hdd_scan_abort(pAdapter);
Girish Gowli4bf7a632014-06-12 13:42:11 +0530367 if (result < 0)
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +0530368 {
369 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
370 "%s: Timeout occurred while waiting for abortscan %ld",
371 __func__, result);
Jeff Johnson295189b2012-06-20 16:38:30 -0700372 }
373 else
374 {
375 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +0530376 "%s: Scan Abort Successful" , __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700377 }
378#ifdef WLAN_BTAMP_FEATURE
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700379 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,"%s: disabling AMP", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700380 status = WLANBAP_StopAmp();
381 if(VOS_STATUS_SUCCESS != status )
382 {
383 pHddCtx->isAmpAllowed = VOS_TRUE;
384 hddLog(VOS_TRACE_LEVEL_FATAL,
385 "%s: Failed to stop AMP", __func__);
386 }
387 else
388 {
389 //a state m/c implementation in PAL is TBD to avoid this delay
390 msleep(500);
Jeff Johnson04dd8a82012-06-29 20:41:40 -0700391 if ( pHddCtx->isAmpAllowed )
392 {
393 WLANBAP_DeregisterFromHCI();
394 pHddCtx->isAmpAllowed = VOS_FALSE;
395 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700396 }
397#endif //WLAN_BTAMP_FEATURE
398 break;
399
400 default:
401 break;
402 }
403
404 return NOTIFY_DONE;
405}
406
Mukul Sharmaa78cf6b2015-02-24 16:59:01 +0530407static int hdd_netdev_notifier_call(struct notifier_block * nb,
408 unsigned long state,
409 void *ndev)
410{
411 int ret;
412 vos_ssr_protect(__func__);
413 ret = __hdd_netdev_notifier_call( nb, state, ndev);
414 vos_ssr_unprotect(__func__);
415 return ret;
416}
417
Jeff Johnson295189b2012-06-20 16:38:30 -0700418struct notifier_block hdd_netdev_notifier = {
419 .notifier_call = hdd_netdev_notifier_call,
420};
421
422/*---------------------------------------------------------------------------
423 * Function definitions
424 *-------------------------------------------------------------------------*/
Jeff Johnson295189b2012-06-20 16:38:30 -0700425void hdd_unregister_mcast_bcast_filter(hdd_context_t *pHddCtx);
426void hdd_register_mcast_bcast_filter(hdd_context_t *pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -0700427//variable to hold the insmod parameters
Madan Mohan Koyyalamudidfd6aa82012-10-18 20:18:43 -0700428static int con_mode;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -0700429#ifndef MODULE
430/* current con_mode - used only for statically linked driver
431 * con_mode is changed by userspace to indicate a mode change which will
432 * result in calling the module exit and init functions. The module
433 * exit function will clean up based on the value of con_mode prior to it
434 * being changed by userspace. So curr_con_mode records the current con_mode
435 * for exit when con_mode becomes the next mode for init
436 */
Madan Mohan Koyyalamudidfd6aa82012-10-18 20:18:43 -0700437static int curr_con_mode;
Jeff Johnson295189b2012-06-20 16:38:30 -0700438#endif
439
Srinivas Girigowda8bf64cb2015-09-30 19:50:09 +0530440#ifdef WLAN_FEATURE_OFFLOAD_PACKETS
441/**
442 * hdd_init_offloaded_packets_ctx() - Initialize offload packets context
443 * @hdd_ctx: hdd global context
444 *
445 * Return: none
446 */
447static void hdd_init_offloaded_packets_ctx(hdd_context_t *hdd_ctx)
448{
449 uint8_t i;
450
451 mutex_init(&hdd_ctx->op_ctx.op_lock);
452 for (i = 0; i < MAXNUM_PERIODIC_TX_PTRNS; i++)
453 {
454 hdd_ctx->op_ctx.op_table[i].request_id = 0;
455 hdd_ctx->op_ctx.op_table[i].pattern_id = i;
456 }
457}
458#else
459static void hdd_init_offloaded_packets_ctx(hdd_context_t *hdd_ctx)
460{
461}
462#endif
463
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -0800464/**---------------------------------------------------------------------------
465
466 \brief hdd_vos_trace_enable() - Configure initial VOS Trace enable
467
468 Called immediately after the cfg.ini is read in order to configure
469 the desired trace levels.
470
471 \param - moduleId - module whose trace level is being configured
472 \param - bitmask - bitmask of log levels to be enabled
473
474 \return - void
475
476 --------------------------------------------------------------------------*/
477static void hdd_vos_trace_enable(VOS_MODULE_ID moduleId, v_U32_t bitmask)
478{
479 wpt_tracelevel level;
480
481 /* if the bitmask is the default value, then a bitmask was not
482 specified in cfg.ini, so leave the logging level alone (it
483 will remain at the "compiled in" default value) */
484 if (CFG_VOS_TRACE_ENABLE_DEFAULT == bitmask)
485 {
486 return;
487 }
488
489 /* a mask was specified. start by disabling all logging */
490 vos_trace_setValue(moduleId, VOS_TRACE_LEVEL_NONE, 0);
491
492 /* now cycle through the bitmask until all "set" bits are serviced */
493 level = VOS_TRACE_LEVEL_FATAL;
494 while (0 != bitmask)
495 {
496 if (bitmask & 1)
497 {
498 vos_trace_setValue(moduleId, level, 1);
499 }
500 level++;
501 bitmask >>= 1;
502 }
503}
504
505
Jeff Johnson295189b2012-06-20 16:38:30 -0700506/**---------------------------------------------------------------------------
507
508 \brief hdd_wdi_trace_enable() - Configure initial WDI Trace enable
509
510 Called immediately after the cfg.ini is read in order to configure
511 the desired trace levels in the WDI.
512
513 \param - moduleId - module whose trace level is being configured
514 \param - bitmask - bitmask of log levels to be enabled
515
516 \return - void
517
518 --------------------------------------------------------------------------*/
519static void hdd_wdi_trace_enable(wpt_moduleid moduleId, v_U32_t bitmask)
520{
521 wpt_tracelevel level;
522
523 /* if the bitmask is the default value, then a bitmask was not
524 specified in cfg.ini, so leave the logging level alone (it
525 will remain at the "compiled in" default value) */
526 if (CFG_WDI_TRACE_ENABLE_DEFAULT == bitmask)
527 {
528 return;
529 }
530
531 /* a mask was specified. start by disabling all logging */
532 wpalTraceSetLevel(moduleId, eWLAN_PAL_TRACE_LEVEL_NONE, 0);
533
534 /* now cycle through the bitmask until all "set" bits are serviced */
535 level = eWLAN_PAL_TRACE_LEVEL_FATAL;
536 while (0 != bitmask)
537 {
538 if (bitmask & 1)
539 {
540 wpalTraceSetLevel(moduleId, level, 1);
541 }
542 level++;
543 bitmask >>= 1;
544 }
545}
Jeff Johnson295189b2012-06-20 16:38:30 -0700546
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +0530547/*
548 * FUNCTION: wlan_hdd_validate_context
549 * This function is used to check the HDD context
550 */
551int wlan_hdd_validate_context(hdd_context_t *pHddCtx)
552{
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +0530553
554 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
555 {
Mahesh A Saptasagar886997a2015-03-04 13:15:51 +0530556 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +0530557 "%s: HDD context is Null", __func__);
558 return -ENODEV;
559 }
560
561 if (pHddCtx->isLogpInProgress)
562 {
Mahesh A Saptasagar886997a2015-03-04 13:15:51 +0530563 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
c_hpothu8adb97b2014-12-08 19:38:20 +0530564 "%s: LOGP %s. Ignore!!", __func__,
565 vos_is_wlan_in_badState(VOS_MODULE_ID_HDD, NULL)
566 ?"failed":"in Progress");
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +0530567 return -EAGAIN;
568 }
569
Mihir Shete18156292014-03-11 15:38:30 +0530570 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +0530571 {
Mahesh A Saptasagar886997a2015-03-04 13:15:51 +0530572 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +0530573 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
574 return -EAGAIN;
575 }
576 return 0;
577}
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -0700578#ifdef CONFIG_ENABLE_LINUX_REG
579void hdd_checkandupdate_phymode( hdd_context_t *pHddCtx)
580{
581 hdd_adapter_t *pAdapter = NULL;
582 hdd_station_ctx_t *pHddStaCtx = NULL;
583 eCsrPhyMode phyMode;
584 hdd_config_t *cfg_param = NULL;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +0530585
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -0700586 if (NULL == pHddCtx)
587 {
588 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
589 "HDD Context is null !!");
590 return ;
591 }
592
593 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION);
594 if (NULL == pAdapter)
595 {
596 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
597 "pAdapter is null !!");
598 return ;
599 }
600
601 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
602 if (NULL == pHddStaCtx)
603 {
604 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
605 "pHddStaCtx is null !!");
606 return ;
607 }
608
609 cfg_param = pHddCtx->cfg_ini;
610 if (NULL == cfg_param)
611 {
612 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
613 "cfg_params not available !!");
614 return ;
615 }
616
617 phyMode = sme_GetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter));
618
619 if (!pHddCtx->isVHT80Allowed)
620 {
621 if ((eCSR_DOT11_MODE_AUTO == phyMode) ||
622 (eCSR_DOT11_MODE_11ac == phyMode) ||
623 (eCSR_DOT11_MODE_11ac_ONLY == phyMode))
624 {
625 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
626 "Setting phymode to 11n!!");
627 sme_SetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter), eCSR_DOT11_MODE_11n);
628 }
629 }
630 else
631 {
632 /*New country Supports 11ac as well resetting value back from .ini*/
633 sme_SetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter),
634 hdd_cfg_xlate_to_csr_phy_mode(cfg_param->dot11Mode));
635 return ;
636 }
637
638 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
639 ((eCSR_CFG_DOT11_MODE_11AC_ONLY == pHddStaCtx->conn_info.dot11Mode) ||
640 (eCSR_CFG_DOT11_MODE_11AC == pHddStaCtx->conn_info.dot11Mode)))
641 {
642 VOS_STATUS vosStatus;
643
644 // need to issue a disconnect to CSR.
645 INIT_COMPLETION(pAdapter->disconnect_comp_var);
646 vosStatus = sme_RoamDisconnect(WLAN_HDD_GET_HAL_CTX(pAdapter),
647 pAdapter->sessionId,
648 eCSR_DISCONNECT_REASON_UNSPECIFIED );
649
650 if (VOS_STATUS_SUCCESS == vosStatus)
c_hpothu6ff1c3c2013-10-01 19:01:57 +0530651 {
652 long ret;
653
654 ret = wait_for_completion_interruptible_timeout(&pAdapter->disconnect_comp_var,
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -0700655 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
c_hpothu6ff1c3c2013-10-01 19:01:57 +0530656 if (0 >= ret)
657 hddLog(LOGE, FL("failure waiting for disconnect_comp_var %ld"),
658 ret);
659 }
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -0700660
661 }
662}
663#else
Gopichand Nakkaladacbcb52013-04-18 16:41:54 +0530664void hdd_checkandupdate_phymode( hdd_adapter_t *pAdapter, char *country_code)
665{
666 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
667 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
668 hdd_config_t *cfg_param;
669 eCsrPhyMode phyMode;
c_hpothu6ff1c3c2013-10-01 19:01:57 +0530670 long ret;
Gopichand Nakkaladacbcb52013-04-18 16:41:54 +0530671
672 if (NULL == pHddCtx)
673 {
674 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
675 "HDD Context is null !!");
676 return ;
677 }
678
679 cfg_param = pHddCtx->cfg_ini;
680
681 if (NULL == cfg_param)
682 {
683 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
684 "cfg_params not available !!");
685 return ;
686 }
687
688 phyMode = sme_GetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter));
689
690 if (NULL != strstr(cfg_param->listOfNon11acCountryCode, country_code))
691 {
692 if ((eCSR_DOT11_MODE_AUTO == phyMode) ||
693 (eCSR_DOT11_MODE_11ac == phyMode) ||
694 (eCSR_DOT11_MODE_11ac_ONLY == phyMode))
695 {
696 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
697 "Setting phymode to 11n!!");
698 sme_SetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter), eCSR_DOT11_MODE_11n);
699 }
700 }
701 else
702 {
703 /*New country Supports 11ac as well resetting value back from .ini*/
704 sme_SetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter),
705 hdd_cfg_xlate_to_csr_phy_mode(cfg_param->dot11Mode));
706 return ;
707 }
708
709 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
710 ((eCSR_CFG_DOT11_MODE_11AC_ONLY == pHddStaCtx->conn_info.dot11Mode) ||
711 (eCSR_CFG_DOT11_MODE_11AC == pHddStaCtx->conn_info.dot11Mode)))
712 {
713 VOS_STATUS vosStatus;
714
715 // need to issue a disconnect to CSR.
716 INIT_COMPLETION(pAdapter->disconnect_comp_var);
717 vosStatus = sme_RoamDisconnect(WLAN_HDD_GET_HAL_CTX(pAdapter),
718 pAdapter->sessionId,
719 eCSR_DISCONNECT_REASON_UNSPECIFIED );
720
721 if (VOS_STATUS_SUCCESS == vosStatus)
c_hpothu6ff1c3c2013-10-01 19:01:57 +0530722 {
723 ret = wait_for_completion_interruptible_timeout(&pAdapter->disconnect_comp_var,
Gopichand Nakkaladacbcb52013-04-18 16:41:54 +0530724 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
c_hpothu6ff1c3c2013-10-01 19:01:57 +0530725 if (ret <= 0)
726 {
727 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
728 "wait on disconnect_comp_var is failed %ld", ret);
729 }
730 }
Gopichand Nakkaladacbcb52013-04-18 16:41:54 +0530731
732 }
733}
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -0700734#endif //CONFIG_ENABLE_LINUX_REG
Gopichand Nakkaladacbcb52013-04-18 16:41:54 +0530735
Tushnim Bhattacharyya9cdf6082013-04-21 16:33:30 -0700736void hdd_checkandupdate_dfssetting( hdd_adapter_t *pAdapter, char *country_code)
737{
738 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
739 hdd_config_t *cfg_param;
740
741 if (NULL == pHddCtx)
742 {
743 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
744 "HDD Context is null !!");
745 return ;
746 }
747
748 cfg_param = pHddCtx->cfg_ini;
749
750 if (NULL == cfg_param)
751 {
752 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
753 "cfg_params not available !!");
754 return ;
755 }
756
Agarwal Ashish738843c2014-09-25 12:27:56 +0530757 if (NULL != strstr(cfg_param->listOfNonDfsCountryCode, country_code) ||
758 pHddCtx->disable_dfs_flag == TRUE)
Tushnim Bhattacharyya9cdf6082013-04-21 16:33:30 -0700759 {
760 /*New country doesn't support DFS */
761 sme_UpdateDfsSetting(WLAN_HDD_GET_HAL_CTX(pAdapter), 0);
762 }
Ashish Kumar Dhanotiya445b3b92018-06-07 12:38:12 +0530763 else
764 {
765 /* New country Supports DFS as well resetting value back from .ini */
766 sme_UpdateDfsSetting(WLAN_HDD_GET_HAL_CTX(pAdapter),
767 cfg_param->enableDFSChnlScan);
768 }
Tushnim Bhattacharyya9cdf6082013-04-21 16:33:30 -0700769
770}
771
Abhishek Singh00b71972016-01-07 10:51:04 +0530772#ifdef WLAN_FEATURE_RMC
773static int hdd_parse_setrmcenable_command(tANI_U8 *pValue, tANI_U8 *pRmcEnable)
774{
775 tANI_U8 *inPtr = pValue;
776 int tempInt;
777 int v = 0;
778 char buf[32];
779 *pRmcEnable = 0;
780
781 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
782 /*no argument after the command*/
783 if (NULL == inPtr)
784 {
785 return 0;
786 }
787
788 /*no space after the command*/
789 else if (SPACE_ASCII_VALUE != *inPtr)
790 {
791 return 0;
792 }
793
794 /*removing empty spaces*/
795 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
796
797 /*no argument followed by spaces*/
798 if ('\0' == *inPtr)
799 {
800 return 0;
801 }
802
803 /* getting the first argument which enables or disables RMC
804 * for input IP v4 address*/
Ashish Kumar Dhanotiya54d31a32017-08-04 17:12:44 +0530805 sscanf(inPtr, "%31s ", buf);
Abhishek Singh00b71972016-01-07 10:51:04 +0530806 v = kstrtos32(buf, 10, &tempInt);
807 if ( v < 0)
808 {
809 return -EINVAL;
810 }
811
812 *pRmcEnable = tempInt;
813
814 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
815 "ucRmcEnable: %d", *pRmcEnable);
816
817 return 0;
818}
819
820/* Function header left blank Intentionally */
821static int hdd_parse_setrmcactionperiod_command(tANI_U8 *pValue,
822 tANI_U32 *pActionPeriod)
823{
824 tANI_U8 *inPtr = pValue;
825 int tempInt;
826 int v = 0;
827 char buf[32];
828 *pActionPeriod = 0;
829
830 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
831 /*no argument after the command*/
832 if (NULL == inPtr)
833 {
834 return -EINVAL;
835 }
836
837 /*no space after the command*/
838 else if (SPACE_ASCII_VALUE != *inPtr)
839 {
840 return -EINVAL;
841 }
842
843 /*removing empty spaces*/
844 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
845
846 /*no argument followed by spaces*/
847 if ('\0' == *inPtr)
848 {
849 return 0;
850 }
851
852 /* getting the first argument which enables or disables RMC
853 * for input IP v4 address*/
Ashish Kumar Dhanotiya54d31a32017-08-04 17:12:44 +0530854 sscanf(inPtr, "%31s ", buf);
Abhishek Singh00b71972016-01-07 10:51:04 +0530855 v = kstrtos32(buf, 10, &tempInt);
856 if ( v < 0)
857 {
858 return -EINVAL;
859 }
860
861 /* Range checking for passed paramter */
862 if (tempInt < WNI_CFG_RMC_ACTION_PERIOD_FREQUENCY_STAMIN ||
863 tempInt > WNI_CFG_RMC_ACTION_PERIOD_FREQUENCY_STAMAX)
864 {
865 return -EINVAL;
866 }
867
868 *pActionPeriod = tempInt;
869
870 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
871 "uActionPeriod: %d", *pActionPeriod);
872
873 return 0;
874}
Dundi Ravitejae110a042018-04-18 13:11:37 +0530875
876/**
877 * hdd_set_vowifi_mode() - Process VOWIFI command.
878 * @hdd_ctx: context handler
Sourav Mohapatra2416e0e2018-03-05 18:44:21 +0530879 * @enable: Value to be sent as a part of the VOWIFI command
880 *
Dundi Ravitejae110a042018-04-18 13:11:37 +0530881 * Invoke the SME api if station is connected in 2.4 GHz band.
882 * Also start split scan if VOWIFIMODE and dynamic split scan
883 * both are enabled.
884
Sourav Mohapatra2416e0e2018-03-05 18:44:21 +0530885 * Return: void
886 */
887void hdd_set_vowifi_mode(hdd_context_t *hdd_ctx, bool enable)
888{
889 tANI_U8 sta_chan;
890
Dundi Ravitejaab9d3092018-04-05 18:24:40 +0530891 if (!hdd_ctx->cfg_ini) {
892 hddLog(LOGE, "cfg_ini got NULL");
893 return;
894 }
895
Sourav Mohapatra2416e0e2018-03-05 18:44:21 +0530896 sta_chan = hdd_get_operating_channel(hdd_ctx, WLAN_HDD_INFRA_STATION);
897
Dundi Ravitejae110a042018-04-18 13:11:37 +0530898 if (CSR_IS_CHANNEL_24GHZ(sta_chan))
Sourav Mohapatra2416e0e2018-03-05 18:44:21 +0530899 sme_set_vowifi_mode(hdd_ctx->hHal, enable);
Dundi Ravitejae110a042018-04-18 13:11:37 +0530900 else
Sourav Mohapatra2416e0e2018-03-05 18:44:21 +0530901 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
902 "VoWiFi command rejected as not connected in 2.4GHz");
Dundi Ravitejae110a042018-04-18 13:11:37 +0530903
904 if (enable && hdd_ctx->cfg_ini->dynSplitscan) {
905 hdd_ctx->is_vowifi_enabled = true;
906 hdd_ctx->issplitscan_enabled = TRUE;
907 sme_enable_disable_split_scan(hdd_ctx->hHal,
908 hdd_ctx->cfg_ini->nNumStaChanCombinedConc,
909 hdd_ctx->cfg_ini->nNumP2PChanCombinedConc);
910 } else {
911 hdd_ctx->is_vowifi_enabled = false;
Dundi Ravitejaab9d3092018-04-05 18:24:40 +0530912 }
Sourav Mohapatra2416e0e2018-03-05 18:44:21 +0530913}
Abhishek Singh00b71972016-01-07 10:51:04 +0530914
915/* Function header left blank Intentionally */
916static int hdd_parse_setrmcrate_command(tANI_U8 *pValue,
917 tANI_U32 *pRate, tTxrateinfoflags *pTxFlags)
918{
919 tANI_U8 *inPtr = pValue;
920 int tempInt;
921 int v = 0;
922 char buf[32];
923 *pRate = 0;
924 *pTxFlags = 0;
925
926 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
927 /*no argument after the command*/
928 if (NULL == inPtr)
929 {
930 return -EINVAL;
931 }
932
933 /*no space after the command*/
934 else if (SPACE_ASCII_VALUE != *inPtr)
935 {
936 return -EINVAL;
937 }
938
939 /*removing empty spaces*/
940 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
941
942 /*no argument followed by spaces*/
943 if ('\0' == *inPtr)
944 {
945 return 0;
946 }
947
948 /*
949 * getting the first argument which sets multicast rate.
950 */
Ashish Kumar Dhanotiya06f9f202017-08-04 15:26:27 +0530951 sscanf(inPtr, "%31s ", buf);
Abhishek Singh00b71972016-01-07 10:51:04 +0530952 v = kstrtos32(buf, 10, &tempInt);
953 if ( v < 0)
954 {
955 return -EINVAL;
956 }
957
958 /*
959 * Validate the multicast rate.
960 */
961 switch (tempInt)
962 {
963 default:
964 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
965 "Unsupported rate: %d", tempInt);
966 return -EINVAL;
967 case 0:
968 case 6:
969 case 9:
970 case 12:
971 case 18:
972 case 24:
973 case 36:
974 case 48:
975 case 54:
976 *pTxFlags = eHAL_TX_RATE_LEGACY;
977 *pRate = tempInt * 10;
978 break;
979 case 65:
980 *pTxFlags = eHAL_TX_RATE_HT20;
981 *pRate = tempInt * 10;
982 break;
983 case 72:
984 *pTxFlags = eHAL_TX_RATE_HT20 | eHAL_TX_RATE_SGI;
985 *pRate = 722; /* fractional rate 72.2 Mbps */
986 break;
987 }
988
989 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
990 "Rate: %d", *pRate);
991
992 return 0;
993}
994
995/**---------------------------------------------------------------------------
996
997 \brief hdd_cfg80211_get_ibss_peer_info_cb() - Callback function for IBSS
998 Peer Info request
999
1000 This is an asynchronous callback function from SME when the peer info
1001 is received
1002
1003 \pUserData -> Adapter private data
1004 \pPeerInfoRsp -> Peer info response
1005
1006 \return - 0 for success non-zero for failure
1007 --------------------------------------------------------------------------*/
1008static void
1009hdd_cfg80211_get_ibss_peer_info_cb(v_VOID_t *pUserData, v_VOID_t *pPeerInfoRsp)
1010{
1011 hdd_adapter_t *pAdapter = (hdd_adapter_t *)pUserData;
1012 tSirPeerInfoRspParams *pPeerInfo = (tSirPeerInfoRspParams *)pPeerInfoRsp;
1013 hdd_station_ctx_t *pStaCtx;
1014 v_U8_t i;
1015
1016 /*Sanity check*/
1017 if ((NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic))
1018 {
1019 hddLog(LOGE,
1020 FL("invalid adapter or adapter has invalid magic"));
1021 return;
1022 }
1023
1024 pStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
1025 if (NULL != pStaCtx && NULL != pPeerInfo &&
1026 eHAL_STATUS_SUCCESS == pPeerInfo->status)
1027 {
1028 pStaCtx->ibss_peer_info.status = pPeerInfo->status;
1029 pStaCtx->ibss_peer_info.numIBSSPeers = pPeerInfo->numPeers;
1030
1031 /* Paranoia check */
1032 if (pPeerInfo->numPeers < HDD_MAX_NUM_IBSS_STA)
1033 {
1034 for (i = 0; i < pPeerInfo->numPeers; i++)
1035 {
1036 memcpy(&pStaCtx->ibss_peer_info.ibssPeerList[i],
1037 &pPeerInfo->peerInfoParams[i],
1038 sizeof(hdd_ibss_peer_info_params_t));
1039 }
1040 hddLog(LOG1,
1041 FL("Peer Info copied in HDD"));
1042 }
1043 else
1044 {
1045 hddLog(LOGE,
1046 FL(" Number of peers %d returned is more than limit %d"),
1047 pPeerInfo->numPeers, HDD_MAX_NUM_IBSS_STA);
1048 }
1049 }
1050 else
1051 {
1052 hddLog(LOG1,
1053 FL("peerInfo returned is NULL"));
1054 }
1055
1056 complete(&pAdapter->ibss_peer_info_comp);
1057}
1058
1059/**---------------------------------------------------------------------------
1060
1061 \brief hdd_cfg80211_get_ibss_peer_info_all() -
1062
1063 Request function to get IBSS peer info from lower layers
1064
1065 \pAdapter -> Adapter context
1066
1067 \return - 0 for success non-zero for failure
1068 --------------------------------------------------------------------------*/
1069static
1070VOS_STATUS hdd_cfg80211_get_ibss_peer_info_all(hdd_adapter_t *pAdapter)
1071{
1072 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
1073 long status;
1074 VOS_STATUS retStatus = VOS_STATUS_E_FAILURE;
1075
1076 INIT_COMPLETION(pAdapter->ibss_peer_info_comp);
1077
1078 retStatus = sme_RequestIBSSPeerInfo(hHal, pAdapter,
1079 hdd_cfg80211_get_ibss_peer_info_cb,
1080 VOS_TRUE, 0xFF);
1081
1082 if (VOS_STATUS_SUCCESS == retStatus)
1083 {
1084 status = wait_for_completion_interruptible_timeout
1085 (&pAdapter->ibss_peer_info_comp,
1086 msecs_to_jiffies(IBSS_PEER_INFO_REQ_TIMOEUT));
1087
1088 /* status will be 0 if timed out */
1089 if (status <= 0)
1090 {
1091 hddLog(VOS_TRACE_LEVEL_WARN, "%s: Warning: IBSS_PEER_INFO_TIMEOUT %ld",
1092 __func__, status);
1093 retStatus = VOS_STATUS_E_FAILURE;
1094 return retStatus;
1095 }
1096 }
1097 else
1098 {
1099 hddLog(VOS_TRACE_LEVEL_WARN,
1100 "%s: Warning: sme_RequestIBSSPeerInfo Request failed", __func__);
1101 }
1102
1103 return retStatus;
1104}
1105
1106/**---------------------------------------------------------------------------
1107
1108 \brief hdd_cfg80211_get_ibss_peer_info() -
1109
1110 Request function to get IBSS peer info from lower layers
1111
1112 \pAdapter -> Adapter context
1113 \staIdx -> Sta index for which the peer info is requested
1114
1115 \return - 0 for success non-zero for failure
1116 --------------------------------------------------------------------------*/
1117static VOS_STATUS
1118hdd_cfg80211_get_ibss_peer_info(hdd_adapter_t *pAdapter, v_U8_t staIdx)
1119{
1120 long status;
1121 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
1122 VOS_STATUS retStatus = VOS_STATUS_E_FAILURE;
1123
1124 INIT_COMPLETION(pAdapter->ibss_peer_info_comp);
1125
1126 retStatus = sme_RequestIBSSPeerInfo(hHal, pAdapter,
1127 hdd_cfg80211_get_ibss_peer_info_cb,
1128 VOS_FALSE, staIdx);
1129
1130 if (VOS_STATUS_SUCCESS == retStatus)
1131 {
1132 status = wait_for_completion_interruptible_timeout
1133 (&pAdapter->ibss_peer_info_comp,
1134 msecs_to_jiffies(IBSS_PEER_INFO_REQ_TIMOEUT));
1135
1136 /* status = 0 on timeout */
1137 if (status <= 0)
1138 {
1139 hddLog(VOS_TRACE_LEVEL_WARN, "%s: Warning: IBSS_PEER_INFO_TIMEOUT %ld",
1140 __func__, status);
1141 retStatus = VOS_STATUS_E_FAILURE;
1142 return retStatus;
1143 }
1144 }
1145 else
1146 {
1147 hddLog(VOS_TRACE_LEVEL_WARN,
1148 "%s: Warning: sme_RequestIBSSPeerInfo Request failed", __func__);
1149 }
1150
1151 return retStatus;
1152}
1153
1154/* Function header left blank Intentionally */
1155VOS_STATUS
1156hdd_parse_get_ibss_peer_info(tANI_U8 *pValue, v_MACADDR_t *pPeerMacAddr)
1157{
1158 tANI_U8 *inPtr = pValue;
1159 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
1160
1161 /*no argument after the command*/
1162 if (NULL == inPtr)
1163 {
1164 return VOS_STATUS_E_FAILURE;;
1165 }
1166
1167 /*no space after the command*/
1168 else if (SPACE_ASCII_VALUE != *inPtr)
1169 {
1170 return VOS_STATUS_E_FAILURE;;
1171 }
1172
1173 /*removing empty spaces*/
1174 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
1175
1176 /*no argument followed by spaces*/
1177 if ('\0' == *inPtr)
1178 {
1179 return VOS_STATUS_E_FAILURE;;
1180 }
1181
1182 /*getting the first argument ie the peer mac address */
1183 if (inPtr[2] != ':' || inPtr[5] != ':' || inPtr[8] != ':' ||
1184 inPtr[11] != ':' || inPtr[14] != ':')
1185 {
1186 return VOS_STATUS_E_FAILURE;;
1187 }
1188 sscanf(inPtr, "%2x:%2x:%2x:%2x:%2x:%2x",
1189 (unsigned int *)&pPeerMacAddr->bytes[0],
1190 (unsigned int *)&pPeerMacAddr->bytes[1],
1191 (unsigned int *)&pPeerMacAddr->bytes[2],
1192 (unsigned int *)&pPeerMacAddr->bytes[3],
1193 (unsigned int *)&pPeerMacAddr->bytes[4],
1194 (unsigned int *)&pPeerMacAddr->bytes[5]);
1195
1196 /* The command buffer seems to be fine */
1197 return VOS_STATUS_SUCCESS;
1198}
1199
1200/* Function header left blank Intentionally */
1201static int hdd_parse_set_ibss_oui_data_command(tANI_U8 *command, tANI_U8 *ie,
1202 tANI_U32 limit)
1203{
1204 tANI_U8 len;
1205 tANI_U8 data;
1206
1207 /* skip white space */
1208 while ((SPACE_ASCII_VALUE == *command) && ('\0' != *command))
1209 {
1210 command++;
1211 limit--;
1212 }
1213
1214 /* skip element id and element length */
1215 len = 2;
1216
1217 /* extract oui */
1218 while ((SPACE_ASCII_VALUE != *command) && ('\0' != *command) &&
1219 (limit > 1))
1220 {
1221 /* Convert ASCII to decimal */
1222 data = ((*command -'0') << 4) | (*(command + 1) - '0');
1223 ie[len++] = data;
1224 command += 2;
1225 limit -= 2;
1226 }
1227
1228 /* skip white space */
1229 while ((SPACE_ASCII_VALUE == *command) && ('\0' != *command))
1230 {
1231 command++;
1232 limit--;
1233 }
1234
1235 /* extract data */
1236 while ((SPACE_ASCII_VALUE != *command) && ('\0' != *command) &&
1237 (limit > 1))
1238 {
1239 /* Convert ASCII to decimal */
1240 data = ((*command -'0') << 4) | (*(command + 1) - '0');
1241 ie[len++] = data;
1242 command += 2;
1243 limit -= 2;
1244 }
1245
1246 /* fill element id and element length */
1247 ie[0] = IE_EID_VENDOR;
1248 ie[1] = len - 2;
1249
1250 return len;
1251}
1252
1253static tANI_U32 hdd_find_ibss_wpa_ie_pos(tANI_U8 *addIePtr, tANI_U32 addIeLen)
1254{
1255 tANI_U32 ieLenPresent = 0;
1256 int left = addIeLen;
1257 v_U8_t *ptr = addIePtr;
1258 v_U8_t elem_id,elem_len;
1259
1260 while(left >= 2)
1261 {
1262 elem_id = ptr[0];
1263 elem_len = ptr[1];
1264 left -= 2;
1265 if(elem_len > left)
1266 {
1267 hddLog(LOGE,
1268 FL("****Invalid elem_len=%d left=%d*****"),
1269 elem_len,left);
1270 return 0;
1271 }
1272 if ((elem_id == IE_EID_VENDOR) &&
1273 (left >= WPA_OUI_TYPE_SIZE))
1274 {
1275 if (!memcmp(&ptr[2], WPA_OUI_TYPE,
1276 WPA_OUI_TYPE_SIZE))
1277 {
1278 ieLenPresent += elem_len + 2;
1279 return ieLenPresent;
1280 }
1281 }
1282 ieLenPresent += (elem_len + 2);
1283 left -= elem_len;
1284 ptr += (elem_len + 2);
1285 }
1286 return 0;
1287}
1288
1289#endif /* WLAN_FEATURE_RMC */
1290
Rajeev79dbe4c2013-10-05 11:03:42 +05301291#ifdef FEATURE_WLAN_BATCH_SCAN
1292
1293/**---------------------------------------------------------------------------
1294
1295 \brief hdd_extract_assigned_int_from_str() - Extracts assigned integer from
1296 input string
1297
1298 This function extracts assigned integer from string in below format:
1299 "STRING=10" : extracts integer 10 from this string
1300
1301 \param - pInPtr Pointer to input string
1302 \param - base Base for string to int conversion(10 for decimal 16 for hex)
1303 \param - pOutPtr Pointer to variable in which extracted integer needs to be
1304 assigned
1305 \param - pLastArg to tell whether it is last arguement in input string or
1306 not
1307
1308 \return - NULL for failure cases
1309 pointer to next arguement in input string for success cases
1310 --------------------------------------------------------------------------*/
1311static tANI_U8 *
1312hdd_extract_assigned_int_from_str
1313(
1314 tANI_U8 *pInPtr,
1315 tANI_U8 base,
1316 tANI_U32 *pOutPtr,
1317 tANI_U8 *pLastArg
1318)
1319{
1320 int tempInt;
1321 int v = 0;
1322 char buf[32];
1323 int val = 0;
1324 *pLastArg = FALSE;
1325
1326 pInPtr = strnchr(pInPtr, strlen(pInPtr), EQUALS_TO_ASCII_VALUE);
1327 if (NULL == pInPtr)
1328 {
1329 return NULL;
1330 }
1331
1332 pInPtr++;
1333
1334 while ((SPACE_ASCII_VALUE == *pInPtr) && ('\0' != *pInPtr)) pInPtr++;
1335
1336 val = sscanf(pInPtr, "%32s ", buf);
1337 if (val < 0 && val > strlen(pInPtr))
1338 {
1339 return NULL;
1340 }
1341 pInPtr += val;
1342 v = kstrtos32(buf, base, &tempInt);
1343 if (v < 0)
1344 {
1345 return NULL;
1346 }
Rajeev Kumar4d93d842014-01-02 18:31:21 -08001347 if (tempInt < 0)
1348 {
1349 tempInt = 0;
1350 }
Rajeev79dbe4c2013-10-05 11:03:42 +05301351 *pOutPtr = tempInt;
1352
1353 pInPtr = strnchr(pInPtr, strlen(pInPtr), SPACE_ASCII_VALUE);
1354 if (NULL == pInPtr)
1355 {
1356 *pLastArg = TRUE;
1357 return NULL;
1358 }
1359 while ((SPACE_ASCII_VALUE == *pInPtr) && ('\0' != *pInPtr)) pInPtr++;
1360
1361 return pInPtr;
1362}
1363
1364/**---------------------------------------------------------------------------
1365
1366 \brief hdd_extract_assigned_char_from_str() - Extracts assigned char from
1367 input string
1368
1369 This function extracts assigned character from string in below format:
1370 "STRING=A" : extracts char 'A' from this string
1371
1372 \param - pInPtr Pointer to input string
1373 \param - pOutPtr Pointer to variable in which extracted char needs to be
1374 assigned
1375 \param - pLastArg to tell whether it is last arguement in input string or
1376 not
1377
1378 \return - NULL for failure cases
1379 pointer to next arguement in input string for success cases
1380 --------------------------------------------------------------------------*/
1381static tANI_U8 *
1382hdd_extract_assigned_char_from_str
1383(
1384 tANI_U8 *pInPtr,
1385 tANI_U8 *pOutPtr,
1386 tANI_U8 *pLastArg
1387)
1388{
1389 *pLastArg = FALSE;
1390
1391 pInPtr = strnchr(pInPtr, strlen(pInPtr), EQUALS_TO_ASCII_VALUE);
1392 if (NULL == pInPtr)
1393 {
1394 return NULL;
1395 }
1396
1397 pInPtr++;
1398
1399 while ((SPACE_ASCII_VALUE == *pInPtr) && ('\0' != *pInPtr)) pInPtr++;
1400
1401 *pOutPtr = *pInPtr;
1402
1403 pInPtr = strnchr(pInPtr, strlen(pInPtr), SPACE_ASCII_VALUE);
1404 if (NULL == pInPtr)
1405 {
1406 *pLastArg = TRUE;
1407 return NULL;
1408 }
1409 while ((SPACE_ASCII_VALUE == *pInPtr) && ('\0' != *pInPtr)) pInPtr++;
1410
1411 return pInPtr;
1412}
1413
1414
1415/**---------------------------------------------------------------------------
1416
1417 \brief hdd_parse_set_batchscan_command () - HDD parse set batch scan command
1418
1419 This function parses set batch scan command in below format:
1420 WLS_BATCHING_SET <space> followed by below arguements
1421 "SCANFREQ=XX" : Optional defaults to 30 sec
1422 "MSCAN=XX" : Required number of scans to attempt to batch
1423 "BESTN=XX" : Best Network (RSSI) defaults to 16
1424 "CHANNEL=<X,Y>" : optional defaults to all channels, can list 'A'or` B.
1425 A. implies only 5 GHz , B. implies only 2.4GHz
1426 "RTT=X" : optional defaults to 0
1427 returns the MIN of MSCAN or the max # of scans firmware can cache or -1 on
1428 error
1429
1430 For example input commands:
1431 1) WLS_BATCHING_SET SCANFREQ=60 MSCAN=10 BESTN=20 CHANNEL=A RTT=0 -> This is
1432 translated into set batch scan with following parameters:
1433 a) Frequence 60 seconds
1434 b) Batch 10 scans together
1435 c) Best RSSI to be 20
1436 d) 5GHz band only
1437 e) RTT is equal to 0
1438
1439 \param - pValue Pointer to input channel list
1440 \param - pHddSetBatchScanReq Pointer to HDD batch scan request structure
1441
1442 \return - 0 for success non-zero for failure
1443
1444 --------------------------------------------------------------------------*/
1445static int
1446hdd_parse_set_batchscan_command
1447(
1448 tANI_U8 *pValue,
1449 tSirSetBatchScanReq *pHddSetBatchScanReq
1450)
1451{
1452 tANI_U8 *inPtr = pValue;
1453 tANI_U8 val = 0;
1454 tANI_U8 lastArg = 0;
Abhishek Singh00b71972016-01-07 10:51:04 +05301455 tANI_U32 nScanFreq = HDD_SET_BATCH_SCAN_DEFAULT_FREQ;
Rajeev Kumar45e64a72013-11-18 19:48:15 -08001456 tANI_U32 nMscan;
Abhishek Singh00b71972016-01-07 10:51:04 +05301457 tANI_U32 nBestN = HDD_SET_BATCH_SCAN_BEST_NETWORK;
1458 tANI_U8 ucRfBand = HDD_SET_BATCH_SCAN_DEFAULT_BAND;
1459 tANI_U32 nRtt = 0;
Rajeev Kumarc933d982013-11-18 20:04:20 -08001460 tANI_U32 temp;
Rajeev79dbe4c2013-10-05 11:03:42 +05301461
Rajeev79dbe4c2013-10-05 11:03:42 +05301462 /*go to space after WLS_BATCHING_SET command*/
1463 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
1464 /*no argument after the command*/
1465 if (NULL == inPtr)
1466 {
1467 return -EINVAL;
1468 }
1469
1470 /*no space after the command*/
1471 else if (SPACE_ASCII_VALUE != *inPtr)
1472 {
1473 return -EINVAL;
1474 }
1475
1476 /*removing empty spaces*/
1477 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
1478
1479 /*no argument followed by spaces*/
1480 if ('\0' == *inPtr)
1481 {
1482 return -EINVAL;
1483 }
1484
1485 /*check and parse SCANFREQ*/
1486 if ((strncmp(inPtr, "SCANFREQ", 8) == 0))
1487 {
1488 inPtr = hdd_extract_assigned_int_from_str(inPtr, 10,
Rajeev Kumarc933d982013-11-18 20:04:20 -08001489 &temp, &lastArg);
Rajeev Kumar45e64a72013-11-18 19:48:15 -08001490
Rajeev Kumarc933d982013-11-18 20:04:20 -08001491 if (0 != temp)
Rajeev Kumar45e64a72013-11-18 19:48:15 -08001492 {
Rajeev Kumarc933d982013-11-18 20:04:20 -08001493 nScanFreq = temp;
Rajeev Kumar45e64a72013-11-18 19:48:15 -08001494 }
1495
Rajeev79dbe4c2013-10-05 11:03:42 +05301496 if ( (NULL == inPtr) || (TRUE == lastArg))
1497 {
1498 return -EINVAL;
1499 }
1500 }
1501
1502 /*check and parse MSCAN*/
1503 if ((strncmp(inPtr, "MSCAN", 5) == 0))
1504 {
1505 inPtr = hdd_extract_assigned_int_from_str(inPtr, 10,
Rajeev Kumar45e64a72013-11-18 19:48:15 -08001506 &nMscan, &lastArg);
1507
1508 if (0 == nMscan)
1509 {
1510 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1511 "invalid MSCAN=%d", nMscan);
1512 return -EINVAL;
1513 }
1514
Rajeev79dbe4c2013-10-05 11:03:42 +05301515 if (TRUE == lastArg)
1516 {
1517 goto done;
1518 }
1519 else if (NULL == inPtr)
1520 {
1521 return -EINVAL;
1522 }
1523 }
1524 else
1525 {
1526 return -EINVAL;
1527 }
1528
1529 /*check and parse BESTN*/
1530 if ((strncmp(inPtr, "BESTN", 5) == 0))
1531 {
1532 inPtr = hdd_extract_assigned_int_from_str(inPtr, 10,
Rajeev Kumarc933d982013-11-18 20:04:20 -08001533 &temp, &lastArg);
Rajeev Kumar45e64a72013-11-18 19:48:15 -08001534
Rajeev Kumarc933d982013-11-18 20:04:20 -08001535 if (0 != temp)
Rajeev Kumar45e64a72013-11-18 19:48:15 -08001536 {
Rajeev Kumarc933d982013-11-18 20:04:20 -08001537 nBestN = temp;
Rajeev Kumar45e64a72013-11-18 19:48:15 -08001538 }
1539
Rajeev79dbe4c2013-10-05 11:03:42 +05301540 if (TRUE == lastArg)
1541 {
1542 goto done;
1543 }
1544 else if (NULL == inPtr)
1545 {
1546 return -EINVAL;
1547 }
1548 }
1549
1550 /*check and parse CHANNEL*/
1551 if ((strncmp(inPtr, "CHANNEL", 7) == 0))
1552 {
1553 inPtr = hdd_extract_assigned_char_from_str(inPtr, &val, &lastArg);
Rajeev Kumarc933d982013-11-18 20:04:20 -08001554
Rajeev79dbe4c2013-10-05 11:03:42 +05301555 if (('A' == val) || ('a' == val))
1556 {
c_hpothuebf89732014-02-25 13:00:24 +05301557 ucRfBand = HDD_SET_BATCH_SCAN_5GHz_BAND_ONLY;
Rajeev79dbe4c2013-10-05 11:03:42 +05301558 }
1559 else if (('B' == val) || ('b' == val))
1560 {
c_hpothuebf89732014-02-25 13:00:24 +05301561 ucRfBand = HDD_SET_BATCH_SCAN_24GHz_BAND_ONLY;
Rajeev79dbe4c2013-10-05 11:03:42 +05301562 }
1563 else
1564 {
Rajeev Kumarc933d982013-11-18 20:04:20 -08001565 ucRfBand = HDD_SET_BATCH_SCAN_DEFAULT_BAND;
1566 }
1567
1568 if (TRUE == lastArg)
1569 {
1570 goto done;
1571 }
1572 else if (NULL == inPtr)
1573 {
Rajeev79dbe4c2013-10-05 11:03:42 +05301574 return -EINVAL;
1575 }
1576 }
1577
1578 /*check and parse RTT*/
1579 if ((strncmp(inPtr, "RTT", 3) == 0))
1580 {
1581 inPtr = hdd_extract_assigned_int_from_str(inPtr, 10,
Rajeev Kumar45e64a72013-11-18 19:48:15 -08001582 &nRtt, &lastArg);
Rajeev79dbe4c2013-10-05 11:03:42 +05301583 if (TRUE == lastArg)
1584 {
1585 goto done;
1586 }
1587 if (NULL == inPtr)
1588 {
1589 return -EINVAL;
1590 }
1591 }
1592
1593
1594done:
1595
Rajeev Kumar45e64a72013-11-18 19:48:15 -08001596 pHddSetBatchScanReq->scanFrequency = nScanFreq;
1597 pHddSetBatchScanReq->numberOfScansToBatch = nMscan;
1598 pHddSetBatchScanReq->bestNetwork = nBestN;
1599 pHddSetBatchScanReq->rfBand = ucRfBand;
1600 pHddSetBatchScanReq->rtt = nRtt;
1601
Rajeev79dbe4c2013-10-05 11:03:42 +05301602 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1603 "Received WLS_BATCHING_SET with SCANFREQ=%d "
1604 "MSCAN=%d BESTN=%d CHANNEL=%d RTT=%d",
1605 pHddSetBatchScanReq->scanFrequency,
1606 pHddSetBatchScanReq->numberOfScansToBatch,
1607 pHddSetBatchScanReq->bestNetwork,
1608 pHddSetBatchScanReq->rfBand,
1609 pHddSetBatchScanReq->rtt);
1610
1611 return 0;
1612}/*End of hdd_parse_set_batchscan_command*/
1613
1614/**---------------------------------------------------------------------------
1615
1616 \brief hdd_set_batch_scan_req_callback () - This function is called after
1617 receiving set batch scan response from FW and it saves set batch scan
1618 response data FW to HDD context and sets the completion event on
1619 which hdd_ioctl is waiting
1620
1621 \param - callbackContext Pointer to HDD adapter
1622 \param - pRsp Pointer to set batch scan response data received from FW
1623
1624 \return - nothing
1625
1626 --------------------------------------------------------------------------*/
1627static void hdd_set_batch_scan_req_callback
1628(
1629 void *callbackContext,
1630 tSirSetBatchScanRsp *pRsp
1631)
1632{
1633 hdd_adapter_t* pAdapter = (hdd_adapter_t*)callbackContext;
1634 tSirSetBatchScanRsp *pHddSetBatchScanRsp;
1635
1636 /*sanity check*/
1637 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
1638 {
1639 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1640 "%s: Invalid pAdapter magic", __func__);
1641 VOS_ASSERT(0);
1642 return;
1643 }
1644 pHddSetBatchScanRsp = &pAdapter->hddSetBatchScanRsp;
1645
1646 /*save set batch scan response*/
1647 pHddSetBatchScanRsp->nScansToBatch = pRsp->nScansToBatch;
1648
1649 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
1650 "Received set batch scan rsp from FW with nScansToBatch=%d",
1651 pHddSetBatchScanRsp->nScansToBatch);
1652
1653 pAdapter->hdd_wait_for_set_batch_scan_rsp = FALSE;
1654 complete(&pAdapter->hdd_set_batch_scan_req_var);
1655
1656 return;
1657}/*End of hdd_set_batch_scan_req_callback*/
1658
1659
1660/**---------------------------------------------------------------------------
1661
1662 \brief hdd_populate_batch_scan_rsp_queue () - This function stores AP meta
1663 info in hdd batch scan response queue
1664
1665 \param - pAdapter Pointer to hdd adapter
1666 \param - pAPMetaInfo Pointer to access point meta info
1667 \param - scanId scan ID of batch scan response
1668 \param - isLastAp tells whether AP is last AP in batch scan response or not
1669
1670 \return - nothing
1671
1672 --------------------------------------------------------------------------*/
1673static void hdd_populate_batch_scan_rsp_queue( hdd_adapter_t* pAdapter,
1674 tpSirBatchScanNetworkInfo pApMetaInfo, tANI_U32 scanId, v_BOOL_t isLastAp)
1675{
1676 tHddBatchScanRsp *pHead;
1677 tHddBatchScanRsp *pNode;
1678 tHddBatchScanRsp *pPrev;
1679 tHddBatchScanRsp *pTemp;
1680 tANI_U8 ssidLen;
1681
1682 /*head of hdd batch scan response queue*/
1683 pHead = pAdapter->pBatchScanRsp;
1684
1685 pNode = (tHddBatchScanRsp *)vos_mem_malloc(sizeof(tHddBatchScanRsp));
1686 if (NULL == pNode)
1687 {
1688 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1689 "%s: Could not allocate memory", __func__);
1690 VOS_ASSERT(0);
1691 return;
1692 }
1693
1694 vos_mem_copy(pNode->ApInfo.bssid, pApMetaInfo->bssid,
1695 sizeof(pNode->ApInfo.bssid));
1696 ssidLen = strlen(pApMetaInfo->ssid);
1697 if (SIR_MAX_SSID_SIZE < ssidLen)
1698 {
1699 /*invalid scan result*/
1700 vos_mem_free(pNode);
1701 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1702 "%s: Invalid AP meta info ssidlen %d", __func__, ssidLen);
1703 return;
1704 }
1705 vos_mem_copy(pNode->ApInfo.ssid, pApMetaInfo->ssid, ssidLen);
1706 /*null terminate ssid*/
1707 pNode->ApInfo.ssid[ssidLen] = '\0';
1708 pNode->ApInfo.ch = pApMetaInfo->ch;
1709 pNode->ApInfo.rssi = pApMetaInfo->rssi;
1710 pNode->ApInfo.age = pApMetaInfo->timestamp;
1711 pNode->ApInfo.batchId = scanId;
1712 pNode->ApInfo.isLastAp = isLastAp;
1713
1714 pNode->pNext = NULL;
1715 if (NULL == pHead)
1716 {
1717 pAdapter->pBatchScanRsp = pNode;
1718 }
1719 else
1720 {
1721 pTemp = pHead;
1722 while (NULL != pTemp)
1723 {
1724 pPrev = pTemp;
1725 pTemp = pTemp->pNext;
1726 }
1727 pPrev->pNext = pNode;
1728 }
1729
1730 return;
1731}/*End of hdd_populate_batch_scan_rsp_queue*/
1732
1733/**---------------------------------------------------------------------------
1734
1735 \brief hdd_batch_scan_result_ind_callback () - This function is called after
1736 receiving batch scan response indication from FW. It saves get batch scan
1737 response data in HDD batch scan response queue. This callback sets the
1738 completion event on which hdd_ioctl is waiting only after getting complete
1739 batch scan response data from FW
1740
1741 \param - callbackContext Pointer to HDD adapter
1742 \param - pRsp Pointer to get batch scan response data received from FW
1743
1744 \return - nothing
1745
1746 --------------------------------------------------------------------------*/
1747static void hdd_batch_scan_result_ind_callback
1748(
1749 void *callbackContext,
1750 void *pRsp
1751)
1752{
1753 v_BOOL_t isLastAp;
1754 tANI_U32 numApMetaInfo;
Rajeev Kumarce651e42013-10-21 18:57:15 -07001755 tANI_U32 numNetworkInScanList;
Rajeev79dbe4c2013-10-05 11:03:42 +05301756 tANI_U32 numberScanList;
1757 tANI_U32 nextScanListOffset;
1758 tANI_U32 nextApMetaInfoOffset;
1759 hdd_adapter_t* pAdapter;
1760 tpSirBatchScanList pScanList;
1761 tpSirBatchScanNetworkInfo pApMetaInfo;
1762 tpSirBatchScanResultIndParam pBatchScanRsp;/*batch scan rsp data from FW*/
1763 tSirSetBatchScanReq *pReq;
1764
1765 pAdapter = (hdd_adapter_t *)callbackContext;
1766 /*sanity check*/
Rajeev Kumar5286bb92013-12-05 11:52:10 -08001767 if ((NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic))
Rajeev79dbe4c2013-10-05 11:03:42 +05301768 {
1769 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1770 "%s: Invalid pAdapter magic", __func__);
1771 VOS_ASSERT(0);
1772 return;
1773 }
1774
1775 /*initialize locals*/
1776 pReq = &pAdapter->hddSetBatchScanReq;
1777 pBatchScanRsp = (tpSirBatchScanResultIndParam)pRsp;
1778 isLastAp = FALSE;
1779 numApMetaInfo = 0;
Rajeev Kumarce651e42013-10-21 18:57:15 -07001780 numNetworkInScanList = 0;
Rajeev79dbe4c2013-10-05 11:03:42 +05301781 numberScanList = 0;
1782 nextScanListOffset = 0;
1783 nextApMetaInfoOffset = 0;
1784 pScanList = NULL;
1785 pApMetaInfo = NULL;
1786
1787 if ((NULL == pBatchScanRsp) || (NULL == pReq))
1788 {
1789 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnsonc135a9a2017-09-19 08:37:24 -07001790 "%s: pBatchScanRsp is %pK pReq %pK", __func__, pBatchScanRsp, pReq);
Rajeev79dbe4c2013-10-05 11:03:42 +05301791 isLastAp = TRUE;
1792 goto done;
1793 }
1794
1795 pAdapter->numScanList = numberScanList = pBatchScanRsp->numScanLists;
1796 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1797 "Batch scan rsp: numberScalList %d", numberScanList);
1798
1799 if ((!numberScanList) || (numberScanList > pReq->numberOfScansToBatch))
1800 {
1801 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1802 "%s: numberScanList %d", __func__, numberScanList);
1803 isLastAp = TRUE;
1804 goto done;
1805 }
1806
1807 while (numberScanList)
1808 {
Rajeev Kumarce651e42013-10-21 18:57:15 -07001809 pScanList = (tpSirBatchScanList)((tANI_U8 *)pBatchScanRsp->scanResults +
Rajeev79dbe4c2013-10-05 11:03:42 +05301810 nextScanListOffset);
1811 if (NULL == pScanList)
1812 {
1813 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnsonc135a9a2017-09-19 08:37:24 -07001814 "%s: pScanList is %pK", __func__, pScanList);
Rajeev79dbe4c2013-10-05 11:03:42 +05301815 isLastAp = TRUE;
1816 goto done;
1817 }
Rajeev Kumarce651e42013-10-21 18:57:15 -07001818 numNetworkInScanList = numApMetaInfo = pScanList->numNetworksInScanList;
Rajeev79dbe4c2013-10-05 11:03:42 +05301819 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Rajeev Kumarce651e42013-10-21 18:57:15 -07001820 "Batch scan rsp: numApMetaInfo %d scanId %d",
1821 numApMetaInfo, pScanList->scanId);
Rajeev79dbe4c2013-10-05 11:03:42 +05301822
1823 if ((!numApMetaInfo) || (numApMetaInfo > pReq->bestNetwork))
1824 {
1825 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1826 "%s: numApMetaInfo %d", __func__, numApMetaInfo);
1827 isLastAp = TRUE;
1828 goto done;
1829 }
1830
Rajeev Kumarce651e42013-10-21 18:57:15 -07001831 /*Initialize next AP meta info offset for next scan list*/
1832 nextApMetaInfoOffset = 0;
1833
Rajeev79dbe4c2013-10-05 11:03:42 +05301834 while (numApMetaInfo)
1835 {
1836 pApMetaInfo = (tpSirBatchScanNetworkInfo)(pScanList->scanList +
1837 nextApMetaInfoOffset);
1838 if (NULL == pApMetaInfo)
1839 {
1840 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnsonc135a9a2017-09-19 08:37:24 -07001841 "%s: pApMetaInfo is %pK", __func__, pApMetaInfo);
Rajeev79dbe4c2013-10-05 11:03:42 +05301842 isLastAp = TRUE;
1843 goto done;
1844 }
1845 /*calculate AP age*/
1846 pApMetaInfo->timestamp =
1847 pBatchScanRsp->timestamp - pApMetaInfo->timestamp;
1848
1849 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
Arif Hussaina7c8e412013-11-20 11:06:42 -08001850 "%s: bssId "MAC_ADDRESS_STR
1851 " ch %d rssi %d timestamp %d", __func__,
1852 MAC_ADDR_ARRAY(pApMetaInfo->bssid),
1853 pApMetaInfo->ch, pApMetaInfo->rssi,
1854 pApMetaInfo->timestamp);
Rajeev79dbe4c2013-10-05 11:03:42 +05301855
1856 /*mark last AP in batch scan response*/
1857 if ((TRUE == pBatchScanRsp->isLastResult) &&
1858 (1 == numberScanList) && (1 == numApMetaInfo))
1859 {
1860 isLastAp = TRUE;
1861 }
1862
1863 mutex_lock(&pAdapter->hdd_batch_scan_lock);
1864 /*store batch scan repsonse in hdd queue*/
1865 hdd_populate_batch_scan_rsp_queue(pAdapter, pApMetaInfo,
1866 pScanList->scanId, isLastAp);
1867 mutex_unlock(&pAdapter->hdd_batch_scan_lock);
1868
1869 nextApMetaInfoOffset += sizeof(tSirBatchScanNetworkInfo);
1870 numApMetaInfo--;
1871 }
1872
Rajeev Kumarce651e42013-10-21 18:57:15 -07001873 nextScanListOffset += ((sizeof(tSirBatchScanList) - sizeof(tANI_U8))
1874 + (sizeof(tSirBatchScanNetworkInfo)
1875 * numNetworkInScanList));
Rajeev79dbe4c2013-10-05 11:03:42 +05301876 numberScanList--;
1877 }
1878
1879done:
1880
1881 /*notify hdd_ioctl only if complete batch scan rsp is received and it was
1882 requested from hdd_ioctl*/
1883 if ((TRUE == pAdapter->hdd_wait_for_get_batch_scan_rsp) &&
1884 (TRUE == isLastAp))
1885 {
1886 pAdapter->hdd_wait_for_get_batch_scan_rsp = FALSE;
1887 complete(&pAdapter->hdd_get_batch_scan_req_var);
1888 }
1889
1890 return;
1891}/*End of hdd_batch_scan_result_ind_callback*/
1892
1893/**---------------------------------------------------------------------------
1894
1895 \brief hdd_format_batch_scan_rsp () - This function formats batch scan
1896 response as per batch scan FR request format by putting proper markers
1897
1898 \param - pDest pointer to destination buffer
1899 \param - cur_len current length
1900 \param - tot_len total remaining size which can be written to user space
1901 \param - pApMetaInfo Pointer to get batch scan response AP meta info
1902 \param - pAdapter Pointer to HDD adapter
1903
1904 \return - ret no of characters written
1905
1906 --------------------------------------------------------------------------*/
1907static tANI_U32
1908hdd_format_batch_scan_rsp
1909(
1910 tANI_U8 *pDest,
1911 tANI_U32 cur_len,
1912 tANI_U32 tot_len,
1913 tHddBatchScanRsp *pApMetaInfo,
1914 hdd_adapter_t* pAdapter
1915)
1916{
1917 tANI_U32 ret = 0;
1918 tANI_U32 rem_len = 0;
1919 tANI_U8 temp_len = 0;
1920 tANI_U8 temp_total_len = 0;
1921 tANI_U8 temp[HDD_BATCH_SCAN_AP_META_INFO_SIZE];
1922 tANI_U8 *pTemp = temp;
1923
1924 /*Batch scan reponse needs to be returned to user space in
1925 following format:
1926 "scancount=X\n" where X is the number of scans in current batch
1927 batch
1928 "trunc\n" optional present if current scan truncated
1929 "bssid=XX:XX:XX:XX:XX:XX\n"
1930 "ssid=XXXX\n"
1931 "freq=X\n" frequency in Mhz
1932 "level=XX\n"
1933 "age=X\n" ms
1934 "dist=X\n" cm (-1 if not available)
1935 "errror=X\n" (-1if not available)
1936 "====\n" (end of ap marker)
1937 "####\n" (end of scan marker)
1938 "----\n" (end of results)*/
1939 /*send scan result in above format to user space based on
1940 available length*/
1941 /*The GET response may have more data than the driver can return in its
1942 buffer. In that case the buffer should be filled to the nearest complete
1943 scan, ending with "%%%%".Subsequent callsshould return the remaining data
1944 starting with the next scan (optional .trunc\n., .apcount=X\n., etc).
1945 The final buffer should end with "----\n"*/
1946
1947 /*sanity*/
1948 if (cur_len > tot_len)
1949 {
1950 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1951 "%s: invaid cur_len %d tot_len %d", __func__, cur_len, tot_len);
1952 return 0;
1953 }
1954 else
1955 {
1956 rem_len = (tot_len - cur_len);
1957 }
1958
1959 /*end scan marker*/
1960 if (pApMetaInfo->ApInfo.batchId != pAdapter->prev_batch_id)
1961 {
1962 temp_len = snprintf(pTemp, sizeof(temp), "####\n");
1963 pTemp += temp_len;
1964 temp_total_len += temp_len;
1965 }
1966
1967 /*bssid*/
1968 temp_len = snprintf(pTemp, sizeof(temp),
1969 "bssid=0x%x:0x%x:0x%x:0x%x:0x%x:0x%x\n",
1970 pApMetaInfo->ApInfo.bssid[0], pApMetaInfo->ApInfo.bssid[1],
1971 pApMetaInfo->ApInfo.bssid[2], pApMetaInfo->ApInfo.bssid[3],
1972 pApMetaInfo->ApInfo.bssid[4], pApMetaInfo->ApInfo.bssid[5]);
1973 pTemp += temp_len;
1974 temp_total_len += temp_len;
1975
1976 /*ssid*/
1977 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "ssid=%s\n",
1978 pApMetaInfo->ApInfo.ssid);
1979 pTemp += temp_len;
1980 temp_total_len += temp_len;
1981
1982 /*freq*/
1983 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "freq=%d\n",
Rajeev Kumarc40f7512013-11-04 14:13:23 -08001984 sme_ChnToFreq(pApMetaInfo->ApInfo.ch));
Rajeev79dbe4c2013-10-05 11:03:42 +05301985 pTemp += temp_len;
1986 temp_total_len += temp_len;
1987
1988 /*level*/
1989 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "level=%d\n",
1990 pApMetaInfo->ApInfo.rssi);
1991 pTemp += temp_len;
1992 temp_total_len += temp_len;
1993
1994 /*age*/
Jeff Johnson02797792013-10-26 19:17:13 -07001995 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "age=%d\n",
Rajeev79dbe4c2013-10-05 11:03:42 +05301996 pApMetaInfo->ApInfo.age);
1997 pTemp += temp_len;
1998 temp_total_len += temp_len;
1999
2000 /*dist*/
2001 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "dist=-1\n");
2002 pTemp += temp_len;
2003 temp_total_len += temp_len;
2004
2005 /*error*/
2006 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "error=-1\n");
2007 pTemp += temp_len;
2008 temp_total_len += temp_len;
2009
2010 /*end AP marker*/
2011 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "====\n");
2012 pTemp += temp_len;
2013 temp_total_len += temp_len;
2014
2015 /*last AP in batch scan response*/
2016 if(TRUE == pApMetaInfo->ApInfo.isLastAp)
2017 {
2018 /*end scan marker*/
2019 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "####\n");
2020 pTemp += temp_len;
2021 temp_total_len += temp_len;
2022
2023 /*end batch scan result marker*/
2024 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "----\n");
2025 pTemp += temp_len;
2026 temp_total_len += temp_len;
Kiet Lamaa8e15a2014-02-11 23:30:06 -08002027
Rajeev79dbe4c2013-10-05 11:03:42 +05302028 }
2029
2030 if (temp_total_len < rem_len)
2031 {
2032 ret = temp_total_len + 1;
2033 strlcpy(pDest, temp, ret);
2034 pAdapter->isTruncated = FALSE;
2035 }
2036 else
2037 {
2038 pAdapter->isTruncated = TRUE;
2039 if (rem_len >= strlen("%%%%"))
2040 {
Rajeev Kumarc933d982013-11-18 20:04:20 -08002041 ret = snprintf(pDest, sizeof(temp), "%%%%");
Rajeev79dbe4c2013-10-05 11:03:42 +05302042 }
Rajeev Kumarc933d982013-11-18 20:04:20 -08002043 else
Rajeev79dbe4c2013-10-05 11:03:42 +05302044 {
2045 ret = 0;
2046 }
2047 }
2048
2049 return ret;
2050
2051}/*End of hdd_format_batch_scan_rsp*/
2052
2053/**---------------------------------------------------------------------------
2054
2055 \brief hdd_populate_user_batch_scan_rsp() - This function populates user data
2056 buffer starting with head of hdd batch scan response queue
2057
2058 \param - pAdapter Pointer to HDD adapter
2059 \param - pDest Pointer to user data buffer
2060 \param - cur_len current offset in user buffer
2061 \param - rem_len remaining no of bytes in user buffer
2062
2063 \return - number of bytes written in user buffer
2064
2065 --------------------------------------------------------------------------*/
2066
2067tANI_U32 hdd_populate_user_batch_scan_rsp
2068(
2069 hdd_adapter_t* pAdapter,
2070 tANI_U8 *pDest,
2071 tANI_U32 cur_len,
2072 tANI_U32 rem_len
2073)
2074{
2075 tHddBatchScanRsp *pHead;
2076 tHddBatchScanRsp *pPrev;
2077 tANI_U32 len;
2078
Rajeev79dbe4c2013-10-05 11:03:42 +05302079 pAdapter->isTruncated = FALSE;
2080
2081 /*head of hdd batch scan response queue*/
2082 pHead = pAdapter->pBatchScanRsp;
2083 while (pHead)
2084 {
2085 len = hdd_format_batch_scan_rsp(pDest, cur_len, rem_len, pHead,
2086 pAdapter);
2087 pDest += len;
Rajeev Kumar292d2bb2013-10-23 15:01:44 -07002088 pDest--;
Rajeev79dbe4c2013-10-05 11:03:42 +05302089 cur_len += len;
2090 if(TRUE == pAdapter->isTruncated)
2091 {
2092 /*result is truncated return rest of scan rsp in next req*/
2093 cur_len = rem_len;
2094 break;
2095 }
2096 pPrev = pHead;
2097 pHead = pHead->pNext;
2098 pAdapter->pBatchScanRsp = pHead;
Rajeev Kumarbe17d8b2014-01-10 15:39:45 -08002099 if (TRUE == pPrev->ApInfo.isLastAp)
2100 {
2101 pAdapter->prev_batch_id = 0;
2102 }
2103 else
2104 {
2105 pAdapter->prev_batch_id = pPrev->ApInfo.batchId;
2106 }
Rajeev79dbe4c2013-10-05 11:03:42 +05302107 vos_mem_free(pPrev);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08002108 pPrev = NULL;
Rajeev79dbe4c2013-10-05 11:03:42 +05302109 }
2110
2111 return cur_len;
2112}/*End of hdd_populate_user_batch_scan_rsp*/
2113
2114/**---------------------------------------------------------------------------
2115
2116 \brief hdd_return_batch_scan_rsp_to_user () - This function returns batch
2117 scan response data from HDD queue to user space
2118 It does following in detail:
2119 a) if HDD has enough data in its queue then it 1st copies data to user
2120 space and then send get batch scan indication message to FW. In this
2121 case it does not wait on any event and batch scan response data will
2122 be populated in HDD response queue in MC thread context after receiving
2123 indication from FW
2124 b) else send get batch scan indication message to FW and wait on an event
2125 which will be set once HDD receives complete batch scan response from
2126 FW and then this function returns batch scan response to user space
2127
2128 \param - pAdapter Pointer to HDD adapter
2129 \param - pPrivData Pointer to priv_data
2130
2131 \return - 0 for success -EFAULT for failure
2132
2133 --------------------------------------------------------------------------*/
2134
2135int hdd_return_batch_scan_rsp_to_user
2136(
2137 hdd_adapter_t* pAdapter,
2138 hdd_priv_data_t *pPrivData,
2139 tANI_U8 *command
2140)
2141{
2142 tANI_U8 *pDest;
2143 tANI_U32 count = 0;
2144 tANI_U32 len = 0;
2145 tANI_U32 cur_len = 0;
2146 tANI_U32 rem_len = 0;
2147 eHalStatus halStatus;
2148 unsigned long rc;
2149 tSirTriggerBatchScanResultInd *pReq;
2150
2151 pReq = &pAdapter->hddTriggerBatchScanResultInd;
2152 pReq->param = 0;/*batch scan client*/
2153 pDest = (tANI_U8 *)(command + pPrivData->used_len);
2154 pAdapter->hdd_wait_for_get_batch_scan_rsp = FALSE;
2155
2156 cur_len = pPrivData->used_len;
2157 if (pPrivData->total_len > pPrivData->used_len)
2158 {
2159 rem_len = pPrivData->total_len - pPrivData->used_len;
2160 }
2161 else
2162 {
2163 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2164 "%s: Invalid user data buffer total_len %d used_len %d",
2165 __func__, pPrivData->total_len, pPrivData->used_len);
2166 return -EFAULT;
2167 }
2168
2169 mutex_lock(&pAdapter->hdd_batch_scan_lock);
2170 len = hdd_populate_user_batch_scan_rsp(pAdapter, pDest,
2171 cur_len, rem_len);
2172 mutex_unlock(&pAdapter->hdd_batch_scan_lock);
2173
2174 /*enough scan result available in cache to return to user space or
2175 scan result needs to be fetched 1st from fw and then return*/
Rajeev Kumar99db6262013-11-11 15:23:36 -08002176 if (len == cur_len)
Rajeev79dbe4c2013-10-05 11:03:42 +05302177 {
2178 pAdapter->hdd_wait_for_get_batch_scan_rsp = TRUE;
2179 halStatus = sme_TriggerBatchScanResultInd(
2180 WLAN_HDD_GET_HAL_CTX(pAdapter), pReq,
2181 pAdapter->sessionId, hdd_batch_scan_result_ind_callback,
2182 pAdapter);
2183 if ( eHAL_STATUS_SUCCESS == halStatus )
2184 {
2185 if (TRUE == pAdapter->hdd_wait_for_get_batch_scan_rsp)
2186 {
2187 INIT_COMPLETION(pAdapter->hdd_get_batch_scan_req_var);
2188 rc = wait_for_completion_timeout(
2189 &pAdapter->hdd_get_batch_scan_req_var,
2190 msecs_to_jiffies(HDD_GET_BATCH_SCAN_RSP_TIME_OUT));
Abhishek Singh00b71972016-01-07 10:51:04 +05302191 if (0 >= rc)
Rajeev79dbe4c2013-10-05 11:03:42 +05302192 {
2193 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Abhishek Singh00b71972016-01-07 10:51:04 +05302194 "%s: wait on hdd_get_batch_scan_req_var failed %ld",
2195 __func__, rc);
Rajeev79dbe4c2013-10-05 11:03:42 +05302196 return -EFAULT;
2197 }
2198 }
2199
2200 len = snprintf(pDest, HDD_BATCH_SCAN_AP_META_INFO_SIZE,
Jeff Johnson02797792013-10-26 19:17:13 -07002201 "scancount=%u\n", pAdapter->numScanList);
Rajeev79dbe4c2013-10-05 11:03:42 +05302202 pDest += len;
2203 cur_len += len;
2204
2205 mutex_lock(&pAdapter->hdd_batch_scan_lock);
2206 len = hdd_populate_user_batch_scan_rsp(pAdapter, pDest,
2207 cur_len, rem_len);
2208 mutex_unlock(&pAdapter->hdd_batch_scan_lock);
2209
2210 count = 0;
2211 len = (len - pPrivData->used_len);
2212 pDest = (command + pPrivData->used_len);
2213 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Rajeev Kumar99db6262013-11-11 15:23:36 -08002214 "NEW BATCH SCAN RESULT:");
Rajeev79dbe4c2013-10-05 11:03:42 +05302215 while(count < len)
2216 {
2217 printk("%c", *(pDest + count));
2218 count++;
2219 }
2220 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2221 "%s: copy %d data to user buffer", __func__, len);
2222 if (copy_to_user(pPrivData->buf, pDest, len))
2223 {
2224 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2225 "%s: failed to copy data to user buffer", __func__);
2226 return -EFAULT;
2227 }
2228 }
2229 else
2230 {
2231 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2232 "sme_GetBatchScanScan returned failure halStatus %d",
2233 halStatus);
2234 return -EINVAL;
2235 }
2236 }
2237 else
2238 {
Rajeev79dbe4c2013-10-05 11:03:42 +05302239 count = 0;
2240 len = (len - pPrivData->used_len);
2241 pDest = (command + pPrivData->used_len);
2242 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Rajeev Kumar99db6262013-11-11 15:23:36 -08002243 "REMAINING TRUNCATED BATCH SCAN RESULT:");
Rajeev79dbe4c2013-10-05 11:03:42 +05302244 while(count < len)
2245 {
2246 printk("%c", *(pDest + count));
2247 count++;
2248 }
Rajeev Kumar99db6262013-11-11 15:23:36 -08002249 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2250 "%s: copy %d data to user buffer", __func__, len);
Rajeev79dbe4c2013-10-05 11:03:42 +05302251 if (copy_to_user(pPrivData->buf, pDest, len))
2252 {
2253 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2254 "%s: failed to copy data to user buffer", __func__);
2255 return -EFAULT;
2256 }
Rajeev79dbe4c2013-10-05 11:03:42 +05302257 }
2258
2259 return 0;
2260} /*End of hdd_return_batch_scan_rsp_to_user*/
2261
Rajeev Kumar8b373292014-01-08 20:36:55 -08002262/**---------------------------------------------------------------------------
2263
2264 \brief hdd_handle_batch_scan_ioctl () - This function handles WLS_BATCHING
2265 IOCTLs from user space. Following BATCH SCAN DEV IOCTs are handled:
2266 WLS_BATCHING VERSION
2267 WLS_BATCHING SET
2268 WLS_BATCHING GET
2269 WLS_BATCHING STOP
2270
2271 \param - pAdapter Pointer to HDD adapter
2272 \param - pPrivdata Pointer to priv_data
2273 \param - command Pointer to command
2274
2275 \return - 0 for success -EFAULT for failure
2276
2277 --------------------------------------------------------------------------*/
2278
2279int hdd_handle_batch_scan_ioctl
2280(
2281 hdd_adapter_t *pAdapter,
2282 hdd_priv_data_t *pPrivdata,
2283 tANI_U8 *command
2284)
2285{
2286 int ret = 0;
Yue Mae36e3552014-03-05 17:06:20 -08002287 hdd_context_t *pHddCtx;
2288
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302289 ENTER();
2290
Yue Mae36e3552014-03-05 17:06:20 -08002291 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
2292 ret = wlan_hdd_validate_context(pHddCtx);
2293 if (ret)
2294 {
Yue Mae36e3552014-03-05 17:06:20 -08002295 goto exit;
2296 }
Rajeev Kumar8b373292014-01-08 20:36:55 -08002297
2298 if (strncmp(command, "WLS_BATCHING VERSION", 20) == 0)
2299 {
2300 char extra[32];
2301 tANI_U8 len = 0;
2302 tANI_U8 version = HDD_BATCH_SCAN_VERSION;
2303
2304 if (FALSE == sme_IsFeatureSupportedByFW(BATCH_SCAN))
2305 {
2306 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2307 "%s: Batch scan feature is not supported by FW", __func__);
2308 ret = -EINVAL;
2309 goto exit;
2310 }
2311
2312 len = scnprintf(extra, sizeof(extra), "WLS_BATCHING_VERSION %d",
2313 version);
2314 if (copy_to_user(pPrivdata->buf, &extra, len + 1))
2315 {
2316 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2317 "%s: failed to copy data to user buffer", __func__);
2318 ret = -EFAULT;
2319 goto exit;
2320 }
2321 ret = HDD_BATCH_SCAN_VERSION;
2322 }
2323 else if (strncmp(command, "WLS_BATCHING SET", 16) == 0)
2324 {
2325 int status;
2326 tANI_U8 *value = (command + 16);
2327 eHalStatus halStatus;
2328 unsigned long rc;
2329 tSirSetBatchScanReq *pReq = &pAdapter->hddSetBatchScanReq;
2330 tSirSetBatchScanRsp *pRsp = &pAdapter->hddSetBatchScanRsp;
2331
2332 if (FALSE == sme_IsFeatureSupportedByFW(BATCH_SCAN))
2333 {
2334 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2335 "%s: Batch scan feature is not supported by FW", __func__);
2336 ret = -EINVAL;
2337 goto exit;
2338 }
2339
2340 if ((WLAN_HDD_INFRA_STATION != pAdapter->device_mode) &&
2341 (WLAN_HDD_P2P_CLIENT != pAdapter->device_mode) &&
2342 (WLAN_HDD_P2P_GO != pAdapter->device_mode) &&
2343 (WLAN_HDD_P2P_DEVICE != pAdapter->device_mode))
2344 {
2345 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05302346 "Received WLS_BATCHING SET command in invalid mode %s (%d) "
Rajeev Kumar8b373292014-01-08 20:36:55 -08002347 "WLS_BATCHING_SET is only allowed in infra STA/P2P client mode",
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05302348 hdd_device_modetoString(pAdapter->device_mode),
2349 pAdapter->device_mode);
Rajeev Kumar8b373292014-01-08 20:36:55 -08002350 ret = -EINVAL;
2351 goto exit;
2352 }
2353
2354 status = hdd_parse_set_batchscan_command(value, pReq);
2355 if (status)
2356 {
2357 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2358 "Invalid WLS_BATCHING SET command");
2359 ret = -EINVAL;
2360 goto exit;
2361 }
2362
2363
2364 pAdapter->hdd_wait_for_set_batch_scan_rsp = TRUE;
2365 halStatus = sme_SetBatchScanReq(WLAN_HDD_GET_HAL_CTX(pAdapter), pReq,
2366 pAdapter->sessionId, hdd_set_batch_scan_req_callback,
2367 pAdapter);
2368
2369 if ( eHAL_STATUS_SUCCESS == halStatus )
2370 {
Mahesh A Saptasagar5f568172014-05-14 17:02:33 +05302371 char extra[32];
2372 tANI_U8 len = 0;
2373 tANI_U8 mScan = 0;
2374
Rajeev Kumar8b373292014-01-08 20:36:55 -08002375 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2376 "sme_SetBatchScanReq returned success halStatus %d",
2377 halStatus);
2378 if (TRUE == pAdapter->hdd_wait_for_set_batch_scan_rsp)
2379 {
2380 INIT_COMPLETION(pAdapter->hdd_set_batch_scan_req_var);
2381 rc = wait_for_completion_timeout(
2382 &pAdapter->hdd_set_batch_scan_req_var,
2383 msecs_to_jiffies(HDD_SET_BATCH_SCAN_REQ_TIME_OUT));
2384 if (0 == rc)
2385 {
2386 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2387 "%s: Timeout waiting for set batch scan to complete",
2388 __func__);
2389 ret = -EINVAL;
2390 goto exit;
2391 }
2392 }
2393 if ( !pRsp->nScansToBatch )
2394 {
2395 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2396 "%s: Received set batch scan failure response from FW",
2397 __func__);
2398 ret = -EINVAL;
2399 goto exit;
2400 }
2401 /*As per the Batch Scan Framework API we should return the MIN of
2402 either MSCAN or the max # of scans firmware can cache*/
Mahesh A Saptasagar5f568172014-05-14 17:02:33 +05302403 mScan = MIN(pReq->numberOfScansToBatch , pRsp->nScansToBatch);
Rajeev Kumar8b373292014-01-08 20:36:55 -08002404
2405 pAdapter->batchScanState = eHDD_BATCH_SCAN_STATE_STARTED;
2406
2407 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2408 "%s: request MSCAN %d response MSCAN %d ret %d",
Mahesh A Saptasagar5f568172014-05-14 17:02:33 +05302409 __func__, pReq->numberOfScansToBatch, pRsp->nScansToBatch, mScan);
2410 len = scnprintf(extra, sizeof(extra), "%d", mScan);
2411 if (copy_to_user(pPrivdata->buf, &extra, len + 1))
2412 {
2413 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2414 "%s: failed to copy MSCAN value to user buffer", __func__);
2415 ret = -EFAULT;
2416 goto exit;
2417 }
Rajeev Kumar8b373292014-01-08 20:36:55 -08002418 }
2419 else
2420 {
2421 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2422 "sme_SetBatchScanReq returned failure halStatus %d",
2423 halStatus);
2424 ret = -EINVAL;
2425 goto exit;
2426 }
2427 }
2428 else if (strncmp(command, "WLS_BATCHING STOP", 17) == 0)
2429 {
2430 eHalStatus halStatus;
2431 tSirStopBatchScanInd *pInd = &pAdapter->hddStopBatchScanInd;
2432 pInd->param = 0;
2433
2434 if (FALSE == sme_IsFeatureSupportedByFW(BATCH_SCAN))
2435 {
2436 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2437 "%s: Batch scan feature is not supported by FW", __func__);
2438 ret = -EINVAL;
2439 goto exit;
2440 }
2441
2442 if (eHDD_BATCH_SCAN_STATE_STARTED != pAdapter->batchScanState)
2443 {
Deepthi Gowribfd17132014-11-14 17:59:04 +05302444 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Rajeev Kumar8b373292014-01-08 20:36:55 -08002445 "Batch scan is not yet enabled batch scan state %d",
2446 pAdapter->batchScanState);
2447 ret = -EINVAL;
2448 goto exit;
2449 }
2450
Kiet Lamaa8e15a2014-02-11 23:30:06 -08002451 mutex_lock(&pAdapter->hdd_batch_scan_lock);
2452 hdd_deinit_batch_scan(pAdapter);
2453 mutex_unlock(&pAdapter->hdd_batch_scan_lock);
2454
Rajeev Kumar8b373292014-01-08 20:36:55 -08002455 pAdapter->batchScanState = eHDD_BATCH_SCAN_STATE_STOPPED;
2456
2457 halStatus = sme_StopBatchScanInd(WLAN_HDD_GET_HAL_CTX(pAdapter), pInd,
2458 pAdapter->sessionId);
2459 if ( eHAL_STATUS_SUCCESS == halStatus )
2460 {
2461 ret = 0;
2462 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2463 "sme_StopBatchScanInd returned success halStatus %d",
2464 halStatus);
2465 }
2466 else
2467 {
2468 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2469 "sme_StopBatchScanInd returned failure halStatus %d",
2470 halStatus);
2471 ret = -EINVAL;
2472 goto exit;
2473 }
2474 }
2475 else if (strncmp(command, "WLS_BATCHING GET", 16) == 0)
2476 {
2477 tANI_U32 remain_len;
2478
2479 if (FALSE == sme_IsFeatureSupportedByFW(BATCH_SCAN))
2480 {
2481 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2482 "%s: Batch scan feature is not supported by FW", __func__);
2483 ret = -EINVAL;
2484 goto exit;
2485 }
2486
2487 if (eHDD_BATCH_SCAN_STATE_STARTED != pAdapter->batchScanState)
2488 {
Deepthi Gowribfd17132014-11-14 17:59:04 +05302489 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Rajeev Kumar8b373292014-01-08 20:36:55 -08002490 "Batch scan is not yet enabled could not return results"
2491 "Batch Scan state %d",
2492 pAdapter->batchScanState);
2493 ret = -EINVAL;
2494 goto exit;
2495 }
2496
2497 pPrivdata->used_len = 16;
2498 remain_len = pPrivdata->total_len - pPrivdata->used_len;
2499 if (remain_len < pPrivdata->total_len)
2500 {
2501 /*Clear previous batch scan response data if any*/
2502 vos_mem_zero((tANI_U8 *)(command + pPrivdata->used_len), remain_len);
2503 }
2504 else
2505 {
2506 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2507 "Invalid total length from user space can't fetch batch"
2508 " scan response total_len %d used_len %d remain len %d",
2509 pPrivdata->total_len, pPrivdata->used_len, remain_len);
2510 ret = -EINVAL;
2511 goto exit;
2512 }
2513 ret = hdd_return_batch_scan_rsp_to_user(pAdapter, pPrivdata, command);
2514 }
2515
2516exit:
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302517 EXIT();
Rajeev Kumar8b373292014-01-08 20:36:55 -08002518 return ret;
2519}
2520
2521
Rajeev79dbe4c2013-10-05 11:03:42 +05302522#endif/*End of FEATURE_WLAN_BATCH_SCAN*/
2523
Selvaraj, Sridhar5aff1ed2016-06-18 01:26:23 +05302524#if defined(WLAN_FEATURE_VOWIFI_11R) || defined(FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
2525/**
2526 * hdd_assign_handoff_src_reassoc - Set handoff source as REASSOC
2527 * to Handoff request
2528 * @handoffInfo: Pointer to Handoff request
2529 * @src: enum of handoff_src
2530 * Return: None
2531 */
2532#ifndef QCA_WIFI_ISOC
2533static inline void hdd_assign_handoff_src_reassoc(tCsrHandoffRequest
2534 *handoffInfo, handoff_src src)
2535{
2536 handoffInfo->src = src;
2537}
2538#else
2539static inline void hdd_assign_handoff_src_reassoc(tCsrHandoffRequest
2540 *handoffInfo, handoff_src src)
2541{
2542}
2543#endif
2544
2545/**
Selvaraj, Sridhar4fa15232016-06-18 12:27:25 +05302546 * hdd_reassoc() - perform a user space-directed reassoc
Selvaraj, Sridhar5aff1ed2016-06-18 01:26:23 +05302547 *
2548 * @pAdapter: Adapter upon which the command was received
2549 * @bssid: BSSID with which to reassociate
2550 * @channel: channel upon which to reassociate
Selvaraj, Sridhar4fa15232016-06-18 12:27:25 +05302551 * @src: The source for the trigger of this action
Selvaraj, Sridhar5aff1ed2016-06-18 01:26:23 +05302552 *
2553 * Return: 0 for success non-zero for failure
2554 */
2555#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
Selvaraj, Sridhar8ecb4192016-06-23 17:50:49 +05302556int hdd_reassoc(hdd_adapter_t *pAdapter, const tANI_U8 *bssid,
Selvaraj, Sridhar4fa15232016-06-18 12:27:25 +05302557 const tANI_U8 channel, const handoff_src src)
Selvaraj, Sridhar5aff1ed2016-06-18 01:26:23 +05302558{
2559 hdd_station_ctx_t *pHddStaCtx;
2560 tCsrHandoffRequest handoffInfo;
2561 hdd_context_t *pHddCtx = NULL;
2562 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
2563
2564 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
2565
2566 /* if not associated, no need to proceed with reassoc */
2567 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState) {
2568 hddLog(LOG1, FL("Not associated"));
2569 return -EINVAL;
2570 }
2571
2572 /* if the target bssid is same as currently associated AP,
2573 then no need to proceed with reassoc */
2574 if (!memcmp(bssid, pHddStaCtx->conn_info.bssId, sizeof(tSirMacAddr))) {
2575 hddLog(LOG1, FL("Reassoc BSSID is same as currently associated AP bssid"));
2576 return -EINVAL;
2577 }
2578
2579 /* Check channel number is a valid channel number */
2580 if (VOS_STATUS_SUCCESS !=
2581 wlan_hdd_validate_operation_channel(pAdapter, channel)) {
2582 hddLog(LOGE, FL("Invalid Channel %d"), channel);
2583 return -EINVAL;
2584 }
2585
2586 /* Proceed with reassoc */
2587 handoffInfo.channel = channel;
Selvaraj, Sridhar4fa15232016-06-18 12:27:25 +05302588 hdd_assign_handoff_src_reassoc(&handoffInfo, src);
Selvaraj, Sridhar5aff1ed2016-06-18 01:26:23 +05302589 memcpy(handoffInfo.bssid, bssid, sizeof(tSirMacAddr));
2590 sme_HandoffRequest(pHddCtx->hHal, &handoffInfo);
2591 return 0;
2592}
2593#else
Selvaraj, Sridhar8ecb4192016-06-23 17:50:49 +05302594int hdd_reassoc(hdd_adapter_t *pAdapter, const tANI_U8 *bssid,
Selvaraj, Sridhar4fa15232016-06-18 12:27:25 +05302595 const tANI_U8 channel, const handoff_src src)
Selvaraj, Sridhar5aff1ed2016-06-18 01:26:23 +05302596{
2597 return -EPERM;
2598}
2599#endif
2600
2601/**
2602 * hdd_parse_reassoc_v1() - parse version 1 of the REASSOC command
2603 * This function parses the v1 REASSOC command with the format
2604 * REASSOC xx:xx:xx:xx:xx:xx CH where "xx:xx:xx:xx:xx:xx" is the
2605 * Hex-ASCII representation of the BSSID and CH is the ASCII
2606 * representation of the channel. For example
2607 * REASSOC 00:0a:0b:11:22:33 48
2608 *
2609 * @pAdapter: Adapter upon which the command was received
2610 * @command: ASCII text command that was received
2611 *
2612 * Return: 0 for success non-zero for failure
2613 */
2614static int
2615hdd_parse_reassoc_v1(hdd_adapter_t *pAdapter, const char *command)
2616{
2617 tANI_U8 channel = 0;
2618 tSirMacAddr bssid;
2619 int ret;
2620
2621 ret = hdd_parse_reassoc_command_v1_data(command, bssid, &channel);
2622 if (ret)
2623 hddLog(LOGE, FL("Failed to parse reassoc command data"));
2624 else
Selvaraj, Sridhar4fa15232016-06-18 12:27:25 +05302625 ret = hdd_reassoc(pAdapter, bssid, channel, REASSOC);
Selvaraj, Sridhar5aff1ed2016-06-18 01:26:23 +05302626
2627 return ret;
2628}
2629
2630/**
2631 * hdd_parse_reassoc_v2() - parse version 2 of the REASSOC command
2632 * This function parses the v2 REASSOC command with the format
2633 * REASSOC <android_wifi_reassoc_params>
2634 *
2635 * @pAdapter: Adapter upon which the command was received
2636 * @command: command that was received, ASCII command followed
2637 * by binary data
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05302638 * @total_len: Total length of the command received
Selvaraj, Sridhar5aff1ed2016-06-18 01:26:23 +05302639 *
2640 * Return: 0 for success non-zero for failure
2641 */
2642static int
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05302643hdd_parse_reassoc_v2(hdd_adapter_t *pAdapter, const char *command,
2644 int total_len)
Selvaraj, Sridhar5aff1ed2016-06-18 01:26:23 +05302645{
2646 struct android_wifi_reassoc_params params;
2647 tSirMacAddr bssid;
2648 int ret;
2649
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05302650 if (total_len < sizeof(params) + 8) {
2651 hddLog(LOGE, FL("Invalid command length"));
2652 return -EINVAL;
2653 }
2654
Selvaraj, Sridhar5aff1ed2016-06-18 01:26:23 +05302655 /* The params are located after "REASSOC " */
2656 memcpy(&params, command + 8, sizeof(params));
2657
2658 if (!mac_pton(params.bssid, (u8 *)&bssid)) {
2659 hddLog(LOGE, FL("MAC address parsing failed"));
2660 ret = -EINVAL;
2661 } else {
Selvaraj, Sridhar4fa15232016-06-18 12:27:25 +05302662 ret = hdd_reassoc(pAdapter, bssid, params.channel, REASSOC);
Selvaraj, Sridhar5aff1ed2016-06-18 01:26:23 +05302663 }
2664 return ret;
2665}
2666
2667/**
2668 * hdd_parse_reassoc() - parse the REASSOC command
2669 * There are two different versions of the REASSOC command.Version 1
2670 * of the command contains a parameter list that is ASCII characters
2671 * whereas version 2 contains a combination of ASCII and binary
2672 * payload. Determine if a version 1 or a version 2 command is being
2673 * parsed by examining the parameters, and then dispatch the parser
2674 * that is appropriate for the command.
2675 *
2676 * @pAdapter: Adapter upon which the command was received
2677 * @command: command that was received
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05302678 * @total_len: Total length of the command received
Selvaraj, Sridhar5aff1ed2016-06-18 01:26:23 +05302679 *
2680 * Return: 0 for success non-zero for failure
2681 */
2682static int
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05302683hdd_parse_reassoc(hdd_adapter_t *pAdapter, const char *command, int total_len)
Selvaraj, Sridhar5aff1ed2016-06-18 01:26:23 +05302684{
2685 int ret;
2686
2687 /*
2688 * both versions start with "REASSOC"
2689 * v1 has a bssid and channel # as an ASCII string
2690 * REASSOC xx:xx:xx:xx:xx:xx CH
2691 * v2 has a C struct
2692 * REASSOC <binary c struct>
2693 *
2694 * The first field in the v2 struct is also the bssid in ASCII.
2695 * But in the case of a v2 message the BSSID is NUL-terminated.
2696 * Hence we can peek at that offset to see if this is V1 or V2
2697 * REASSOC xx:xx:xx:xx:xx:xx*
2698 * 1111111111222222
2699 * 01234567890123456789012345
2700 */
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05302701
2702 if (total_len < 26) {
2703 hddLog(LOGE, FL("Invalid command (total_len=%d)"), total_len);
2704 return -EINVAL;
2705 }
2706
Selvaraj, Sridhar5aff1ed2016-06-18 01:26:23 +05302707 if (command[25])
2708 ret = hdd_parse_reassoc_v1(pAdapter, command);
2709 else
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05302710 ret = hdd_parse_reassoc_v2(pAdapter, command, total_len);
Selvaraj, Sridhar5aff1ed2016-06-18 01:26:23 +05302711
2712 return ret;
2713}
2714#endif /* WLAN_FEATURE_VOWIFI_11R || FEATURE_WLAN_ESE FEATURE_WLAN_LFR */
2715
Hanumanth Reddy Pothula7aa4bea2018-04-09 17:19:03 +05302716struct bcn_miss_rate_priv {
2717 int bcn_miss_rate;
2718};
2719
2720/**
2721 * get_bcn_miss_rate_cb() callback invoked on receiving beacon miss
2722 * rate from firmware
2723 * @status: Status of get beacon miss rate operation
2724 * @bcnMissRate: Beacon miss rate
2725 * @context: Context passed while registering callback
2726 *
2727 * This function is invoked by WDA layer on receiving
2728 * WDI_GET_BCN_MISS_RATE_RSP
2729 *
2730 * Return: None
2731 */
2732static void get_bcn_miss_rate_cb(VOS_STATUS status, int bcnMissRate,
2733 void *context)
c_hpothu92367912014-05-01 15:18:17 +05302734{
Hanumanth Reddy Pothula7aa4bea2018-04-09 17:19:03 +05302735 struct hdd_request *request;
2736 struct bcn_miss_rate_priv *priv;
c_hpothu39eb1e32014-06-26 16:31:50 +05302737
Hanumanth Reddy Pothula7aa4bea2018-04-09 17:19:03 +05302738 request = hdd_request_get(context);
2739 if (!request) {
2740 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Obsolete request"));
2741 return;
2742 }
c_hpothu92367912014-05-01 15:18:17 +05302743
Hanumanth Reddy Pothula7aa4bea2018-04-09 17:19:03 +05302744 priv = hdd_request_priv(request);
c_hpothu92367912014-05-01 15:18:17 +05302745
Hanumanth Reddy Pothula7aa4bea2018-04-09 17:19:03 +05302746 if (VOS_STATUS_SUCCESS == status)
2747 priv->bcn_miss_rate = bcnMissRate;
2748 else
2749 hddLog(VOS_TRACE_LEVEL_ERROR, FL("failed to get bcnMissRate"));
c_hpothu92367912014-05-01 15:18:17 +05302750
Hanumanth Reddy Pothula7aa4bea2018-04-09 17:19:03 +05302751 hdd_request_complete(request);
2752 hdd_request_put(request);
Hanumanth Reddy Pothulad0d3c172018-05-02 18:53:05 +05302753
Hanumanth Reddy Pothula7aa4bea2018-04-09 17:19:03 +05302754 return;
c_hpothu92367912014-05-01 15:18:17 +05302755}
2756
Hanumanth Reddy Pothula7aa4bea2018-04-09 17:19:03 +05302757struct fw_stats_priv {
2758 tSirFwStatsResult *fw_stats;
2759};
2760
2761/**
2762 * hdd_fw_stats_cb() callback invoked on receiving firmware stats
2763 * from firmware
2764 * @status: Status of get firmware stats operation
2765 * @fwStatsResult: firmware stats
2766 * @context: Context passed while registering callback
2767 *
2768 * This function is invoked by WDA layer on receiving
2769 * WDI_GET_FW_STATS_RSP
2770 *
2771 * Return: None
2772 */
2773static void hdd_fw_stats_cb(VOS_STATUS status,
2774 tSirFwStatsResult *fwStatsResult, void *context)
Satyanarayana Dash72806012014-12-02 14:30:08 +05302775{
Hanumanth Reddy Pothula7aa4bea2018-04-09 17:19:03 +05302776 struct hdd_request *request;
2777 struct fw_stats_priv *priv;
Satyanarayana Dash72806012014-12-02 14:30:08 +05302778
Hanumanth Reddy Pothula7aa4bea2018-04-09 17:19:03 +05302779 hddLog(VOS_TRACE_LEVEL_INFO, FL("with status = %d"),status);
Satyanarayana Dash72806012014-12-02 14:30:08 +05302780
Hanumanth Reddy Pothula7aa4bea2018-04-09 17:19:03 +05302781 request = hdd_request_get(context);
2782 if (!request) {
2783 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Obsolete request"));
2784 return;
2785 }
2786 priv = hdd_request_priv(request);
2787
2788 if (VOS_STATUS_SUCCESS == status)
2789 *priv->fw_stats = *fwStatsResult;
2790 else
2791 priv->fw_stats = NULL;
2792
2793 hdd_request_complete(request);
2794 hdd_request_put(request);
2795 return;
Satyanarayana Dash72806012014-12-02 14:30:08 +05302796}
2797
jge35567202017-06-21 16:39:38 +08002798/*
2799 *hdd_parse_setmaxtxpower_command() - HDD Parse MAXTXPOWER command
2800 *@pValue Pointer to MAXTXPOWER command
2801 *@pTxPower Pointer to tx power
2802 *
2803 *This function parses the MAXTXPOWER command passed in the format
2804 * MAXTXPOWER<space>X(Tx power in dbm)
2805 * For example input commands:
2806 * 1) MAXTXPOWER -8 -> This is translated into set max TX power to -8 dbm
2807 * 2) MAXTXPOWER -23 -> This is translated into set max TX power to -23 dbm
2808 *
2809 *return - 0 for success non-zero for failure
2810 */
2811static int hdd_parse_setmaxtxpower_command(unsigned char *pValue, int *pTxPower)
2812{
2813 unsigned char *inPtr = pValue;
2814 int tempInt;
2815 int v = 0;
2816 *pTxPower = 0;
2817
2818 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
2819 /* no argument after the command */
2820 if (NULL == inPtr)
2821 return -EINVAL;
2822 /* no space after the command */
2823 else if (SPACE_ASCII_VALUE != *inPtr)
2824 return -EINVAL;
2825
2826 /* removing empty spaces */
2827 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
2828
2829 /* no argument followed by spaces */
2830 if ('\0' == *inPtr)
2831 return 0;
2832
2833 v = kstrtos32(inPtr, 10, &tempInt);
2834
2835 /* Range checking for passed parameter */
2836 if ((tempInt < HDD_MIN_TX_POWER) || (tempInt > HDD_MAX_TX_POWER))
2837 return -EINVAL;
2838
2839 *pTxPower = tempInt;
2840
2841 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2842 "SETMAXTXPOWER: %d", *pTxPower);
2843
2844 return 0;
2845}
2846
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302847static int hdd_get_dwell_time(hdd_config_t *pCfg, tANI_U8 *command, char *extra, tANI_U8 n, tANI_U8 *len)
2848{
2849 int ret = 0;
2850
2851 if (!pCfg || !command || !extra || !len)
2852 {
2853 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2854 "%s: argument passsed for GETDWELLTIME is incorrect", __func__);
2855 ret = -EINVAL;
2856 return ret;
2857 }
2858
2859 if (strncmp(command, "GETDWELLTIME ACTIVE MAX", 23) == 0)
2860 {
2861 *len = scnprintf(extra, n, "GETDWELLTIME ACTIVE MAX %u\n",
2862 (int)pCfg->nActiveMaxChnTime);
2863 return ret;
2864 }
2865 else if (strncmp(command, "GETDWELLTIME ACTIVE MIN", 23) == 0)
2866 {
2867 *len = scnprintf(extra, n, "GETDWELLTIME ACTIVE MIN %u\n",
2868 (int)pCfg->nActiveMinChnTime);
2869 return ret;
2870 }
2871 else if (strncmp(command, "GETDWELLTIME PASSIVE MAX", 24) == 0)
2872 {
2873 *len = scnprintf(extra, n, "GETDWELLTIME PASSIVE MAX %u\n",
2874 (int)pCfg->nPassiveMaxChnTime);
2875 return ret;
2876 }
2877 else if (strncmp(command, "GETDWELLTIME PASSIVE MIN", 24) == 0)
2878 {
2879 *len = scnprintf(extra, n, "GETDWELLTIME PASSIVE MIN %u\n",
2880 (int)pCfg->nPassiveMinChnTime);
2881 return ret;
2882 }
Rajesh Babu Prathipati0fd227e2014-07-05 12:50:00 +05302883 else if (strncmp(command, "GETDWELLTIME", 12) == 0)
2884 {
2885 *len = scnprintf(extra, n, "GETDWELLTIME %u \n",
2886 (int)pCfg->nActiveMaxChnTime);
2887 return ret;
2888 }
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302889 else
2890 {
2891 ret = -EINVAL;
2892 }
2893
2894 return ret;
2895}
2896
Dundi Ravitejaae5adf42018-04-23 20:44:47 +05302897/**
2898 * hdd_btc_get_dwell_time() - Get BTC dwell time parameters
2899 * @pCfg: Pointer to HDD context
2900 * @command: ASCII text command that is received
2901 * @extra: Pointer to copy data sent to user
2902 * @n: size of 'extra' buffer
2903 * @len: length copied to 'extra' buffer
2904 *
2905 * Driver commands:
2906 * wpa_cli DRIVER BTCGETDWELLTIME ESCO MAX
2907 * wpa_cli DRIVER BTCGETDWELLTIME ESCO MIN
2908 * wpa_cli DRIVER BTCGETDWELLTIME SCO MAX
2909 * wpa_cli DRIVER BTCGETDWELLTIME SCO MIN
2910 *
2911 * Return: 0 for success non-zero for failure
2912 */
2913
2914static int hdd_btc_get_dwell_time(hdd_config_t *pCfg, tANI_U8 *command,
2915 char *extra, tANI_U8 n, tANI_U8 *len)
2916{
2917 int ret = 0;
2918
2919 if (!pCfg || !command || !extra || !len)
2920 {
2921 hddLog(LOGE, FL("Argument passsed for BTCGETDWELLTIME is incorrect"));
2922 ret = -EINVAL;
2923 return ret;
2924 }
2925
2926 if (strncmp(command, "BTCGETDWELLTIME ESCO MAX", 24) == 0)
2927 {
2928 *len = scnprintf(extra, n, "BTCGETDWELLTIME ESCO MAX %u\n",
2929 (int)pCfg->max_chntime_btc_esco);
2930 return ret;
2931 }
2932 else if (strncmp(command, "BTCGETDWELLTIME ESCO MIN", 24) == 0)
2933 {
2934 *len = scnprintf(extra, n, "BTCGETDWELLTIME ESCO MIN %u\n",
2935 (int)pCfg->min_chntime_btc_esco);
2936 return ret;
2937 }
2938 else if (strncmp(command, "BTCGETDWELLTIME SCO MAX", 23) == 0)
2939 {
2940 *len = scnprintf(extra, n, "BTCGETDWELLTIME SCO MAX %u\n",
2941 (int)pCfg->max_chntime_btc_sco);
2942 return ret;
2943 }
2944 else if (strncmp(command, "BTCGETDWELLTIME SCO MIN", 23) == 0)
2945 {
2946 *len = scnprintf(extra, n, "BTCGETDWELLTIME SCO MIN %u\n",
2947 (int)pCfg->min_chntime_btc_sco);
2948 return ret;
2949 }
2950 else
2951 {
2952 ret = -EINVAL;
2953 }
2954
2955 return ret;
2956}
2957
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05302958int hdd_drv_cmd_validate(tANI_U8 *command, int len)
2959{
2960 if (command[len] != ' ')
2961 return -EINVAL;
2962
2963 return 0;
2964}
2965
Dundi Ravitejaae5adf42018-04-23 20:44:47 +05302966#ifdef WLAN_AP_STA_CONCURRENCY
2967
2968/**
2969 * hdd_conc_get_dwell_time() - Get concurrency dwell time parameters
2970 * @pCfg: Pointer to HDD context
2971 * @command: ASCII text command that is received
2972 * @extra: Pointer to copy data sent to user
2973 * @n: size of 'extra' buffer
2974 * @len: length copied to 'extra' buffer
2975 *
2976 * Driver commands:
2977 * wpa_cli DRIVER CONCGETDWELLTIME ACTIVE MAX
2978 * wpa_cli DRIVER CONCGETDWELLTIME ACTIVE MIN
2979 * wpa_cli DRIVER CONCGETDWELLTIME PASSIVE MAX
2980 * wpa_cli DRIVER CONCGETDWELLTIME PASSIVE MIN
2981 *
2982 * Return: 0 for success non-zero for failure
2983 */
2984
2985static int hdd_conc_get_dwell_time(hdd_config_t *pCfg, tANI_U8 *command,
2986 char *extra, tANI_U8 n, tANI_U8 *len)
2987{
2988 int ret = 0;
2989
2990 if (!pCfg || !command || !extra || !len)
2991 {
2992 hddLog(LOGE, FL("Argument passsed for CONCGETDWELLTIME is incorrect"));
2993 ret = -EINVAL;
2994 return ret;
2995 }
2996
2997 if (strncmp(command, "CONCGETDWELLTIME ACTIVE MAX", 27) == 0)
2998 {
2999 *len = scnprintf(extra, n, "CONCGETDWELLTIME ACTIVE MAX %u\n",
3000 (int)pCfg->nActiveMaxChnTimeConc);
3001 return ret;
3002 }
3003 else if (strncmp(command, "CONCGETDWELLTIME ACTIVE MIN", 27) == 0)
3004 {
3005 *len = scnprintf(extra, n, "CONCGETDWELLTIME ACTIVE MIN %u\n",
3006 (int)pCfg->nActiveMinChnTimeConc);
3007 return ret;
3008 }
3009 else if (strncmp(command, "CONCGETDWELLTIME PASSIVE MAX", 28) == 0)
3010 {
3011 *len = scnprintf(extra, n, "CONCGETDWELLTIME PASSIVE MAX %u\n",
3012 (int)pCfg->nPassiveMaxChnTimeConc);
3013 return ret;
3014 }
3015 else if (strncmp(command, "CONCGETDWELLTIME PASSIVE MIN", 28) == 0)
3016 {
3017 *len = scnprintf(extra, n, "CONCGETDWELLTIME PASSIVE MIN %u\n",
3018 (int)pCfg->nPassiveMinChnTimeConc);
3019 return ret;
3020 }
3021 else
3022 {
3023 ret = -EINVAL;
3024 }
3025
3026 return ret;
3027}
3028
3029/**
3030 * hdd_conc_set_dwell_time() - Set concurrency dwell time parameters
3031 * @pAdapter: Adapter upon which the command was received
3032 * @command: ASCII text command that is received
3033 *
3034 * Driver commands:
3035 * wpa_cli DRIVER CONCSETDWELLTIME ACTIVE MAX <value>
3036 * wpa_cli DRIVER CONCSETDWELLTIME ACTIVE MIN <value>
3037 * wpa_cli DRIVER CONCSETDWELLTIME PASSIVE MAX <value
3038 * wpa_cli DRIVER CONCSETDWELLTIME PASSIVE MIN <value>
3039 *
3040 * Return: 0 for success non-zero for failure
3041 */
3042
3043static int hdd_conc_set_dwell_time(hdd_adapter_t *pAdapter, tANI_U8 *command)
3044{
3045 tHalHandle hHal;
3046 hdd_config_t *pCfg;
3047 tANI_U8 *value = command;
3048 int val = 0, ret = 0, temp = 0;
3049 tSmeConfigParams smeConfig;
3050
3051 if (!pAdapter || !command || !(pCfg = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini)
3052 || !(hHal = (WLAN_HDD_GET_HAL_CTX(pAdapter))))
3053 {
3054 hddLog(LOGE, FL("Argument passed for CONCSETDWELLTIME is incorrect"));
3055 ret = -EINVAL;
3056 return ret;
3057 }
3058
3059 vos_mem_zero(&smeConfig, sizeof(smeConfig));
3060 sme_GetConfigParam(hHal, &smeConfig);
3061
3062 if (strncmp(command, "CONCSETDWELLTIME ACTIVE MAX", 27) == 0 )
3063 {
3064 if (hdd_drv_cmd_validate(command, 27)) {
3065 hddLog(LOGE, FL("Invalid driver command"));
3066 return -EINVAL;
3067 }
3068
3069 value = value + 28;
3070 temp = kstrtou32(value, 10, &val);
3071 if (temp != 0 || val < CFG_ACTIVE_MAX_CHANNEL_TIME_CONC_MIN ||
3072 val > CFG_ACTIVE_MAX_CHANNEL_TIME_CONC_MAX)
3073 {
3074 hddLog(LOGE, FL("Argument passed for CONCSETDWELLTIME ACTIVE MAX is incorrect"));
3075 ret = -EFAULT;
3076 return ret;
3077 }
3078 pCfg->nActiveMaxChnTimeConc = val;
3079 smeConfig.csrConfig.nActiveMaxChnTimeConc = val;
3080 sme_UpdateConfig(hHal, &smeConfig);
3081 }
3082 else if (strncmp(command, "CONCSETDWELLTIME ACTIVE MIN", 27) == 0)
3083 {
3084 if (hdd_drv_cmd_validate(command, 27)) {
3085 hddLog(LOGE, FL("Invalid driver command"));
3086 return -EINVAL;
3087 }
3088
3089 value = value + 28;
3090 temp = kstrtou32(value, 10, &val);
3091 if (temp !=0 || val < CFG_ACTIVE_MIN_CHANNEL_TIME_CONC_MIN ||
3092 val > CFG_ACTIVE_MIN_CHANNEL_TIME_CONC_MAX)
3093 {
3094 hddLog(LOGE, FL("Argument passsed for CONCSETDWELLTIME ACTIVE MIN is incorrect"));
3095 ret = -EFAULT;
3096 return ret;
3097 }
3098 pCfg->nActiveMinChnTimeConc = val;
3099 smeConfig.csrConfig.nActiveMinChnTimeConc = val;
3100 sme_UpdateConfig(hHal, &smeConfig);
3101 }
3102 else if (strncmp(command, "CONCSETDWELLTIME PASSIVE MAX", 28) == 0)
3103 {
3104 if (hdd_drv_cmd_validate(command, 28)) {
3105 hddLog(LOGE, FL("Invalid driver command"));
3106 return -EINVAL;
3107 }
3108
3109 value = value + 29;
3110 temp = kstrtou32(value, 10, &val);
3111 if (temp != 0 || val < CFG_PASSIVE_MAX_CHANNEL_TIME_CONC_MIN ||
3112 val > CFG_PASSIVE_MAX_CHANNEL_TIME_CONC_MAX)
3113 {
3114 hddLog(LOGE, FL("Argument passed for CONCSETDWELLTIME PASSIVE MAX is incorrect"));
3115 ret = -EFAULT;
3116 return ret;
3117 }
3118 pCfg->nPassiveMaxChnTimeConc = val;
3119 smeConfig.csrConfig.nPassiveMaxChnTimeConc = val;
3120 sme_UpdateConfig(hHal, &smeConfig);
3121 }
3122 else if (strncmp(command, "CONCSETDWELLTIME PASSIVE MIN", 28) == 0)
3123 {
3124 if (hdd_drv_cmd_validate(command, 28)) {
3125 hddLog(LOGE, FL("Invalid driver command"));
3126 return -EINVAL;
3127 }
3128
3129 value = value + 29;
3130 temp = kstrtou32(value, 10, &val);
3131 if (temp != 0 || val < CFG_PASSIVE_MIN_CHANNEL_TIME_CONC_MIN ||
3132 val > CFG_PASSIVE_MIN_CHANNEL_TIME_CONC_MAX )
3133 {
3134 hddLog(LOGE, FL("Argument passed for CONCSETDWELLTIME PASSIVE MIN is incorrect"));
3135 ret = -EFAULT;
3136 return ret;
3137 }
3138 pCfg->nPassiveMinChnTimeConc = val;
3139 smeConfig.csrConfig.nPassiveMinChnTimeConc = val;
3140 sme_UpdateConfig(hHal, &smeConfig);
3141 }
3142 else
3143 {
3144 ret = -EINVAL;
3145 }
3146
3147 return ret;
3148}
3149
3150#endif
3151
3152/**
3153 * hdd_btc_set_dwell_time() - Set BTC dwell time parameters
3154 * @pAdapter: Adapter upon which the command was received
3155 * @command: ASCII text command that is received
3156 *
3157 * Driver commands:
3158 * wpa_cli DRIVER BTCSETDWELLTIME ESCO MAX <value>
3159 * wpa_cli DRIVER BTCSETDWELLTIME ESCO MIN <value>
3160 * wpa_cli DRIVER BTCSETDWELLTIME SCO MAX <value>
3161 * wpa_cli DRIVER BTCSETDWELLTIME SCO MIN <value>
3162 *
3163 * Return: 0 for success non-zero for failure
3164 */
3165
3166static int hdd_btc_set_dwell_time(hdd_adapter_t *pAdapter, tANI_U8 *command)
3167{
3168 tHalHandle hHal;
3169 hdd_config_t *pCfg;
3170 tANI_U8 *value = command;
3171 int val = 0, ret = 0, temp = 0;
3172 tSmeConfigParams smeConfig;
3173
3174 if (!pAdapter || !command || !(pCfg = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini)
3175 || !(hHal = (WLAN_HDD_GET_HAL_CTX(pAdapter))))
3176 {
3177 hddLog(LOGE, FL("Argument passed for BTCSETDWELLTIME is incorrect"));
3178 ret = -EINVAL;
3179 return ret;
3180 }
3181
3182 vos_mem_zero(&smeConfig, sizeof(smeConfig));
3183 sme_GetConfigParam(hHal, &smeConfig);
3184
3185 if (strncmp(command, "BTCSETDWELLTIME ESCO MAX", 24) == 0)
3186 {
3187 if (hdd_drv_cmd_validate(command, 24)) {
3188 hddLog(LOGE, FL("Invalid driver command"));
3189 return -EINVAL;
3190 }
3191
3192 value = value + 25;
3193 temp = kstrtou32(value, 10, &val);
3194 if (temp != 0 || val < CFG_ACTIVE_MAX_CHANNEL_TIME_BTC_MIN ||
3195 val > CFG_ACTIVE_MAX_CHANNEL_TIME_BTC_MAX)
3196 {
3197 hddLog(LOGE, FL("Argument passed for BTCSETDWELLTIME ESCO MAX is incorrect"));
3198 ret = -EFAULT;
3199 return ret;
3200 }
3201 pCfg->max_chntime_btc_esco = val;
3202 smeConfig.csrConfig.max_chntime_btc_esco = val;
3203 sme_UpdateConfig(hHal, &smeConfig);
3204 }
3205 else if (strncmp(command, "BTCSETDWELLTIME ESCO MIN", 24) == 0)
3206 {
3207 if (hdd_drv_cmd_validate(command, 24)) {
3208 hddLog(LOGE, FL("Invalid driver command"));
3209 return -EINVAL;
3210 }
3211
3212 value = value + 25;
3213 temp = kstrtou32(value, 10, &val);
3214 if (temp !=0 || val < CFG_ACTIVE_MIN_CHANNEL_TIME_BTC_MIN ||
3215 val > CFG_ACTIVE_MIN_CHANNEL_TIME_BTC_MAX)
3216 {
3217 hddLog(LOGE, FL("Argument passsed for BTCSETDWELLTIME ESCO MIN is incorrect"));
3218 ret = -EFAULT;
3219 return ret;
3220 }
3221 pCfg->min_chntime_btc_esco = val;
3222 smeConfig.csrConfig.min_chntime_btc_esco = val;
3223 sme_UpdateConfig(hHal, &smeConfig);
3224 }
3225 else if (strncmp(command, "BTCSETDWELLTIME SCO MAX", 23) == 0)
3226 {
3227 if (hdd_drv_cmd_validate(command, 23)) {
3228 hddLog(LOGE, FL("Invalid driver command"));
3229 return -EINVAL;
3230 }
3231
3232 value = value + 24;
3233 temp = kstrtou32(value, 10, &val);
3234 if (temp != 0 || val < CFG_ACTIVE_MAX_CHANNEL_TIME_BTC_SCO_MIN ||
3235 val > CFG_ACTIVE_MAX_CHANNEL_TIME_BTC_SCO_MAX)
3236 {
3237 hddLog(LOGE, FL("Argument passed for BTCSETDWELLTIME SCO MAX is incorrect"));
3238 ret = -EFAULT;
3239 return ret;
3240 }
3241 pCfg->max_chntime_btc_sco = val;
3242 smeConfig.csrConfig.max_chntime_btc_sco = val;
3243 sme_UpdateConfig(hHal, &smeConfig);
3244 }
3245 else if (strncmp(command, "BTCSETDWELLTIME SCO MIN", 23) == 0)
3246 {
3247 if (hdd_drv_cmd_validate(command, 23)) {
3248 hddLog(LOGE, FL("Invalid driver command"));
3249 return -EINVAL;
3250 }
3251
3252 value = value + 24;
3253 temp = kstrtou32(value, 10, &val);
3254 if (temp != 0 || val < CFG_ACTIVE_MIN_CHANNEL_TIME_BTC_SCO_MIN ||
3255 val > CFG_ACTIVE_MIN_CHANNEL_TIME_BTC_SCO_MAX)
3256 {
3257 hddLog(LOGE, FL("Argument passed for BTCSETDWELLTIME SCO MIN is incorrect"));
3258 ret = -EFAULT;
3259 return ret;
3260 }
3261 pCfg->min_chntime_btc_sco = val;
3262 smeConfig.csrConfig.min_chntime_btc_sco = val;
3263 sme_UpdateConfig(hHal, &smeConfig);
3264 }
3265 else
3266 {
3267 ret = -EINVAL;
3268 }
3269
3270 return ret;
3271}
3272
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05303273static int hdd_set_dwell_time(hdd_adapter_t *pAdapter, tANI_U8 *command)
3274{
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05303275 tHalHandle hHal;
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05303276 hdd_config_t *pCfg;
3277 tANI_U8 *value = command;
3278 int val = 0, ret = 0, temp = 0;
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05303279 tSmeConfigParams smeConfig;
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05303280
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05303281 if (!pAdapter || !command || !(pCfg = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini)
3282 || !(hHal = (WLAN_HDD_GET_HAL_CTX(pAdapter))))
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05303283 {
3284 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3285 "%s: argument passed for SETDWELLTIME is incorrect", __func__);
3286 ret = -EINVAL;
3287 return ret;
3288 }
3289
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05303290 vos_mem_zero(&smeConfig, sizeof(smeConfig));
3291 sme_GetConfigParam(hHal, &smeConfig);
3292
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05303293 if (strncmp(command, "SETDWELLTIME ACTIVE MAX", 23) == 0 )
3294 {
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05303295 if (hdd_drv_cmd_validate(command, 23))
3296 return -EINVAL;
3297
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05303298 value = value + 24;
3299 temp = kstrtou32(value, 10, &val);
3300 if (temp != 0 || val < CFG_ACTIVE_MAX_CHANNEL_TIME_MIN ||
3301 val > CFG_ACTIVE_MAX_CHANNEL_TIME_MAX )
3302 {
3303 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3304 "%s: argument passed for SETDWELLTIME ACTIVE MAX is incorrect", __func__);
3305 ret = -EFAULT;
3306 return ret;
3307 }
3308 pCfg->nActiveMaxChnTime = val;
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05303309 smeConfig.csrConfig.nActiveMaxChnTime = val;
3310 sme_UpdateConfig(hHal, &smeConfig);
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05303311 }
3312 else if (strncmp(command, "SETDWELLTIME ACTIVE MIN", 23) == 0)
3313 {
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05303314 if (hdd_drv_cmd_validate(command, 23))
3315 return -EINVAL;
3316
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05303317 value = value + 24;
3318 temp = kstrtou32(value, 10, &val);
3319 if (temp !=0 || val < CFG_ACTIVE_MIN_CHANNEL_TIME_MIN ||
3320 val > CFG_ACTIVE_MIN_CHANNEL_TIME_MAX )
3321 {
3322 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3323 "%s: argument passsed for SETDWELLTIME ACTIVE MIN is incorrect", __func__);
3324 ret = -EFAULT;
3325 return ret;
3326 }
3327 pCfg->nActiveMinChnTime = val;
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05303328 smeConfig.csrConfig.nActiveMinChnTime = val;
3329 sme_UpdateConfig(hHal, &smeConfig);
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05303330 }
3331 else if (strncmp(command, "SETDWELLTIME PASSIVE MAX", 24) == 0)
3332 {
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05303333 if (hdd_drv_cmd_validate(command, 24))
3334 return -EINVAL;
3335
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05303336 value = value + 25;
3337 temp = kstrtou32(value, 10, &val);
3338 if (temp != 0 || val < CFG_PASSIVE_MAX_CHANNEL_TIME_MIN ||
3339 val > CFG_PASSIVE_MAX_CHANNEL_TIME_MAX )
3340 {
3341 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3342 "%s: argument passed for SETDWELLTIME PASSIVE MAX is incorrect", __func__);
3343 ret = -EFAULT;
3344 return ret;
3345 }
3346 pCfg->nPassiveMaxChnTime = val;
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05303347 smeConfig.csrConfig.nPassiveMaxChnTime = val;
3348 sme_UpdateConfig(hHal, &smeConfig);
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05303349 }
3350 else if (strncmp(command, "SETDWELLTIME PASSIVE MIN", 24) == 0)
3351 {
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05303352 if (hdd_drv_cmd_validate(command, 24))
3353 return -EINVAL;
3354
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05303355 value = value + 25;
3356 temp = kstrtou32(value, 10, &val);
3357 if (temp != 0 || val < CFG_PASSIVE_MIN_CHANNEL_TIME_MIN ||
3358 val > CFG_PASSIVE_MIN_CHANNEL_TIME_MAX )
3359 {
3360 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3361 "%s: argument passed for SETDWELLTIME PASSIVE MIN is incorrect", __func__);
3362 ret = -EFAULT;
3363 return ret;
3364 }
3365 pCfg->nPassiveMinChnTime = val;
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05303366 smeConfig.csrConfig.nPassiveMinChnTime = val;
3367 sme_UpdateConfig(hHal, &smeConfig);
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05303368 }
Rajesh Babu Prathipati0fd227e2014-07-05 12:50:00 +05303369 else if (strncmp(command, "SETDWELLTIME", 12) == 0)
3370 {
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05303371 if (hdd_drv_cmd_validate(command, 12))
3372 return -EINVAL;
3373
Rajesh Babu Prathipati0fd227e2014-07-05 12:50:00 +05303374 value = value + 13;
3375 temp = kstrtou32(value, 10, &val);
3376 if (temp != 0 || val < CFG_ACTIVE_MAX_CHANNEL_TIME_MIN ||
3377 val > CFG_ACTIVE_MAX_CHANNEL_TIME_MAX )
3378 {
3379 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3380 "%s: argument passed for SETDWELLTIME is incorrect", __func__);
3381 ret = -EFAULT;
3382 return ret;
3383 }
3384 pCfg->nActiveMaxChnTime = val;
3385 smeConfig.csrConfig.nActiveMaxChnTime = val;
3386 sme_UpdateConfig(hHal, &smeConfig);
3387 }
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05303388 else
3389 {
3390 ret = -EINVAL;
3391 }
3392
3393 return ret;
3394}
Agarwal Ashish8bd53ae2015-06-12 18:03:45 +05303395static int hdd_cmd_setFccChannel(hdd_context_t *pHddCtx, tANI_U8 *cmd,
3396 tANI_U8 cmd_len)
3397{
3398 tANI_U8 *value;
3399 tANI_U8 fcc_constraint;
3400
3401 eHalStatus status;
3402 int ret = 0;
3403 value = cmd + cmd_len + 1;
3404
3405 ret = kstrtou8(value, 10, &fcc_constraint);
3406 if ((ret < 0) || (fcc_constraint > 1)) {
3407 /*
3408 * If the input value is greater than max value of datatype,
3409 * then also it is a failure
3410 */
3411 hddLog(VOS_TRACE_LEVEL_ERROR,
3412 "%s: value out of range", __func__);
3413 return -EINVAL;
3414 }
3415
Agrawal Ashish842eea82016-02-04 17:56:16 +05303416 status = sme_handleSetFccChannel(pHddCtx->hHal, fcc_constraint,
3417 pHddCtx->scan_info.mScanPending);
Agarwal Ashish8bd53ae2015-06-12 18:03:45 +05303418 if (status != eHAL_STATUS_SUCCESS)
3419 ret = -EPERM;
3420
3421 return ret;
3422}
3423
Mahesh A Saptasagarbeca12c2015-09-07 16:21:06 +05303424/**---------------------------------------------------------------------------
Agarwal Ashish8bd53ae2015-06-12 18:03:45 +05303425
Mahesh A Saptasagarbeca12c2015-09-07 16:21:06 +05303426 \brief hdd_enable_disable_ca_event() - When Host sends IOCTL (enabled),
3427 FW will send *ONE* CA ind to Host(even though it is duplicate).
3428 When Host send IOCTL (disable), FW doesn't perform any action.
3429 Whenever any change in CA *and* WLAN is in SAP/P2P-GO mode, FW
3430 sends CA ind to host. (regard less of IOCTL status)
3431 \param - pHddCtx - HDD context
3432 \param - command - command received from framework
3433 \param - cmd_len - len of the command
3434
3435 \return - 0 on success, appropriate error values on failure.
3436
3437 --------------------------------------------------------------------------*/
3438int hdd_enable_disable_ca_event(hdd_context_t *pHddCtx, tANI_U8* command, tANI_U8 cmd_len)
3439{
3440 tANI_U8 set_value;
3441 int ret = 0;
3442 eHalStatus status;
3443
3444 ret = wlan_hdd_validate_context(pHddCtx);
3445 if (0 != ret)
3446 {
3447 ret = -EINVAL;
3448 goto exit;
3449 }
3450
3451 if (pHddCtx->cfg_ini->gOptimizeCAevent == 0)
3452 {
3453 hddLog(VOS_TRACE_LEVEL_ERROR, "Enable gOptimizeCAevent"
3454 " ini param to control channel avooidance indication");
3455 ret = 0;
3456 goto exit;
3457 }
3458
3459 set_value = command[cmd_len + 1] - '0';
3460 status = sme_enableDisableChanAvoidIndEvent(pHddCtx->hHal, set_value);
3461 if (status != eHAL_STATUS_SUCCESS)
3462 {
3463 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Failed to send"
3464 " enableDisableChanAoidance command to SME\n", __func__);
3465 ret = -EINVAL;
3466 }
3467
3468exit:
3469 return ret;
3470}
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05303471
Selvaraj, Sridhar3714c4d2016-06-22 15:19:12 +05303472/**
3473 * wlan_hdd_fastreassoc_handoff_request() - Post Handoff request to SME
3474 * @pHddCtx: Pointer to the HDD context
3475 * @channel: channel to reassociate
3476 * @targetApBssid: Target AP/BSSID to reassociate
3477 *
3478 * Return: None
3479 */
3480#if defined(WLAN_FEATURE_ROAM_SCAN_OFFLOAD) && !defined(QCA_WIFI_ISOC)
3481static void wlan_hdd_fastreassoc_handoff_request(hdd_context_t *pHddCtx,
3482 uint8_t channel, tSirMacAddr targetApBssid)
3483{
3484 tCsrHandoffRequest handoffInfo;
3485 handoffInfo.channel = channel;
3486 handoffInfo.src = FASTREASSOC;
3487 vos_mem_copy(handoffInfo.bssid, targetApBssid, sizeof(tSirMacAddr));
3488 sme_HandoffRequest(pHddCtx->hHal, &handoffInfo);
3489}
3490#else
3491static void wlan_hdd_fastreassoc_handoff_request(hdd_context_t *pHddCtx,
3492 uint8_t channel, tSirMacAddr targetApBssid)
3493{
3494}
3495#endif
3496
3497/**
3498 * csr_fastroam_neighbor_ap_event() - Function to trigger scan/roam
3499 * @pAdapter: Pointer to HDD adapter
3500 * @channel: Channel to scan/roam
3501 * @targetApBssid: BSSID to roam
3502 *
3503 * Return: None
3504 */
3505#ifdef QCA_WIFI_ISOC
3506static void csr_fastroam_neighbor_ap_event(hdd_adapter_t *pAdapter,
3507 uint8_t channel, tSirMacAddr targetApBssid)
3508{
3509 smeIssueFastRoamNeighborAPEvent(WLAN_HDD_GET_HAL_CTX(pAdapter),
3510 &targetApBssid[0], eSME_ROAM_TRIGGER_SCAN, channel);
3511}
3512#else
3513static void csr_fastroam_neighbor_ap_event(hdd_adapter_t *pAdapter,
3514 uint8_t channel, tSirMacAddr targetApBssid)
3515{
3516}
3517#endif
3518
3519/**
3520 * wlan_hdd_handle_fastreassoc() - Handle fastreassoc command
3521 * @pAdapter: pointer to hdd adapter
3522 * @command: pointer to the command received
3523 *
3524 * Return: VOS_STATUS enum
3525 */
3526static VOS_STATUS wlan_hdd_handle_fastreassoc(hdd_adapter_t *pAdapter,
3527 uint8_t *command)
3528{
3529 tANI_U8 *value = command;
3530 tANI_U8 channel = 0;
3531 tSirMacAddr targetApBssid;
Selvaraj, Sridhar3714c4d2016-06-22 15:19:12 +05303532 hdd_station_ctx_t *pHddStaCtx = NULL;
3533 hdd_context_t *pHddCtx = NULL;
Selvaraj, Sridhar5aff1ed2016-06-18 01:26:23 +05303534 int ret;
Selvaraj, Sridhar349b8fe2017-01-18 13:11:25 +05303535 tCsrRoamModifyProfileFields mod_profile_fields;
3536 uint32_t roam_id = 0;
Selvaraj, Sridhar3714c4d2016-06-22 15:19:12 +05303537 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
3538 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
3539
3540 /* if not associated, no need to proceed with reassoc */
3541 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState) {
3542 hddLog(LOG1, FL("Not associated!"));
3543 return eHAL_STATUS_FAILURE;
3544 }
3545
Selvaraj, Sridhar5aff1ed2016-06-18 01:26:23 +05303546 ret = hdd_parse_reassoc_command_v1_data(value, targetApBssid, &channel);
3547 if (ret) {
Selvaraj, Sridhar3714c4d2016-06-22 15:19:12 +05303548 hddLog(LOGE, FL("Failed to parse reassoc command data"));
3549 return eHAL_STATUS_FAILURE;
3550 }
3551
3552 /* if the target bssid is same as currently associated AP,
3553 then no need to proceed with reassoc */
3554 if (vos_mem_compare(targetApBssid,
3555 pHddStaCtx->conn_info.bssId,
3556 sizeof(tSirMacAddr))) {
Selvaraj, Sridhar349b8fe2017-01-18 13:11:25 +05303557 sme_GetModifyProfileFields(pHddCtx->hHal, pAdapter->sessionId,
3558 &mod_profile_fields);
3559 sme_RoamReassoc(pHddCtx->hHal, pAdapter->sessionId, NULL,
3560 mod_profile_fields, &roam_id, 1);
Selvaraj, Sridhar3714c4d2016-06-22 15:19:12 +05303561 hddLog(LOG1, FL("Reassoc BSSID is same as currently associated AP bssid"));
Selvaraj, Sridhar349b8fe2017-01-18 13:11:25 +05303562 return eHAL_STATUS_SUCCESS;
Selvaraj, Sridhar3714c4d2016-06-22 15:19:12 +05303563 }
3564
3565 /* Check channel number is a valid channel number */
3566 if (VOS_STATUS_SUCCESS !=
3567 wlan_hdd_validate_operation_channel(pAdapter, channel)) {
3568 hddLog(LOGE, FL("Invalid Channel [%d]"), channel);
3569 return eHAL_STATUS_FAILURE;
3570 }
3571
3572 /* Proceed with reassoc */
3573 wlan_hdd_fastreassoc_handoff_request(pHddCtx, channel, targetApBssid);
3574
3575 /* Proceed with scan/roam */
3576 csr_fastroam_neighbor_ap_event(pAdapter, channel, targetApBssid);
3577
3578 return eHAL_STATUS_SUCCESS;
3579}
3580
3581/**
3582 * hdd_assign_reassoc_handoff - Set handoff source as REASSOC
3583 * @handoffInfo: Pointer to the csr Handoff Request.
3584 *
3585 * Return: None
3586 */
3587#ifndef QCA_WIFI_ISOC
3588static inline void hdd_assign_reassoc_handoff(tCsrHandoffRequest *handoffInfo)
3589{
3590 handoffInfo->src = REASSOC;
3591}
3592#else
3593static inline void hdd_assign_reassoc_handoff(tCsrHandoffRequest *handoffInfo)
3594{
3595}
3596#endif
3597
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +05303598/**
3599 * wlan_hdd_free_cache_channels() - Free the cache channels list
3600 * @hdd_ctx: Pointer to HDD context
3601 *
3602 * Return: None
3603 */
3604
3605static void wlan_hdd_free_cache_channels(hdd_context_t *hdd_ctx)
3606{
Ashish Kumar Dhanotiya19803832018-05-24 19:05:48 +05303607 if(!hdd_ctx || !hdd_ctx->original_channels)
3608 return;
3609
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +05303610 mutex_lock(&hdd_ctx->cache_channel_lock);
Ashish Kumar Dhanotiya95e5bc22018-04-19 17:06:33 +05303611 hdd_ctx->original_channels->num_channels = 0;
3612 vos_mem_free(hdd_ctx->original_channels->channel_info);
3613 hdd_ctx->original_channels->channel_info = NULL;
3614 vos_mem_free(hdd_ctx->original_channels);
3615 hdd_ctx->original_channels = NULL;
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +05303616 mutex_unlock(&hdd_ctx->cache_channel_lock);
3617}
3618
3619/**
3620 * hdd_alloc_chan_cache() - Allocate the memory to cache the channel
3621 * info for the channels received in command SET_DISABLE_CHANNEL_LIST
3622 * @hdd_ctx: Pointer to HDD context
3623 * @num_chan: Number of channels for which memory needs to
3624 * be allocated
3625 *
3626 * Return: 0 on success and error code on failure
3627 */
3628
3629int hdd_alloc_chan_cache(hdd_context_t *hdd_ctx, int num_chan)
3630{
Ashish Kumar Dhanotiya95e5bc22018-04-19 17:06:33 +05303631 hdd_ctx->original_channels =
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +05303632 vos_mem_malloc(sizeof(struct hdd_cache_channels));
Ashish Kumar Dhanotiya95e5bc22018-04-19 17:06:33 +05303633 if (!hdd_ctx->original_channels) {
3634 hddLog(VOS_TRACE_LEVEL_ERROR,
3635 "In %s, VOS_MALLOC_ERR", __func__);
3636 return -EINVAL;
3637 }
3638 hdd_ctx->original_channels->num_channels = num_chan;
3639 hdd_ctx->original_channels->channel_info =
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +05303640 vos_mem_malloc(num_chan *
3641 sizeof(struct hdd_cache_channel_info));
Ashish Kumar Dhanotiya95e5bc22018-04-19 17:06:33 +05303642 if (!hdd_ctx->original_channels->channel_info) {
3643 hddLog(VOS_TRACE_LEVEL_ERROR,
3644 "In %s, VOS_MALLOC_ERR", __func__);
3645 hdd_ctx->original_channels->num_channels = 0;
3646 vos_mem_free(hdd_ctx->original_channels);
3647 hdd_ctx->original_channels = NULL;
3648 return -ENOMEM;
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +05303649 }
3650 return 0;
3651
3652}
3653
3654
3655int hdd_parse_disable_chan_cmd(hdd_adapter_t *adapter, tANI_U8 *ptr)
3656{
3657 v_PVOID_t pvosGCtx = vos_get_global_context(VOS_MODULE_ID_HDD, NULL);
3658 hdd_context_t *hdd_ctx = vos_get_context(VOS_MODULE_ID_HDD, pvosGCtx);
3659 tANI_U8 *param;
Ashish Kumar Dhanotiya95e5bc22018-04-19 17:06:33 +05303660 int j, tempInt, ret = 0, i, num_channels;
3661 int parsed_channels[MAX_CHANNEL];
3662 bool is_command_repeated = false;
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +05303663
3664 if (NULL == pvosGCtx) {
3665 hddLog(VOS_TRACE_LEVEL_FATAL,
3666 "VOS Global Context is NULL");
3667 return -EINVAL;
3668 }
3669
3670 if (NULL == hdd_ctx) {
3671 hddLog(VOS_TRACE_LEVEL_FATAL, "HDD Context is NULL");
3672 return -EINVAL;
3673 }
3674
3675 param = strchr(ptr, ' ');
3676 /*no argument after the command*/
3677 if (NULL == param)
3678 return -EINVAL;
3679
3680 /*no space after the command*/
3681 else if (SPACE_ASCII_VALUE != *param)
3682 return -EINVAL;
3683
3684 param++;
3685
3686 /*removing empty spaces*/
3687 while ((SPACE_ASCII_VALUE == *param) && ('\0' != *param))
3688 param++;
3689
3690 /*no argument followed by spaces*/
3691 if ('\0' == *param)
3692 return -EINVAL;
3693
3694 /*getting the first argument ie the number of channels*/
3695 if (sscanf(param, "%d ", &tempInt) != 1) {
3696 hddLog(VOS_TRACE_LEVEL_ERROR,
3697 "%s: Cannot get number of channels from input",
3698 __func__);
3699 return -EINVAL;
3700 }
3701
3702 if (tempInt < 0 || tempInt > MAX_CHANNEL) {
3703 hddLog(VOS_TRACE_LEVEL_ERROR,
3704 "%s: Invalid Number of channel received", __func__);
3705 return -EINVAL;
3706 }
3707
3708 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
3709 "%s: Number of channel to disable are: %d",
3710 __func__, tempInt);
3711
3712 if (!tempInt) {
3713 if (!wlan_hdd_restore_channels(hdd_ctx)) {
3714 /*
3715 * Free the cache channels only when the command is
3716 * received with num channels as 0
3717 */
3718 wlan_hdd_free_cache_channels(hdd_ctx);
3719 }
3720 return 0;
3721 }
3722
3723 mutex_lock(&hdd_ctx->cache_channel_lock);
Ashish Kumar Dhanotiya95e5bc22018-04-19 17:06:33 +05303724 if (!hdd_ctx->original_channels) {
3725 if (hdd_alloc_chan_cache(hdd_ctx, tempInt)) {
3726 ret = -ENOMEM;
3727 goto mem_alloc_failed;
3728 }
3729 } else if (hdd_ctx->original_channels->num_channels != tempInt) {
3730 hddLog(VOS_TRACE_LEVEL_ERROR,
3731 "%s, Invalid No of channel provided in the list",
3732 __func__);
3733 ret = -EINVAL;
3734 is_command_repeated = true;
3735 goto parse_failed;
3736 } else {
3737 is_command_repeated = true;
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +05303738 }
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +05303739
Ashish Kumar Dhanotiya95e5bc22018-04-19 17:06:33 +05303740 num_channels = tempInt;
3741
3742 for (j = 0; j < num_channels; j++) {
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +05303743 /*
3744 * param pointing to the beginning of first space
3745 * after number of channels
3746 */
3747 param = strpbrk(param, " ");
3748 /*no channel list after the number of channels argument*/
3749 if (NULL == param) {
3750 hddLog(VOS_TRACE_LEVEL_ERROR,
3751 "%s, Invalid No of channel provided in the list",
3752 __func__);
3753 ret = -EINVAL;
Ashish Kumar Dhanotiya95e5bc22018-04-19 17:06:33 +05303754 goto parse_failed;
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +05303755 }
3756
3757 param++;
3758
3759 /*removing empty space*/
3760 while ((SPACE_ASCII_VALUE == *param) && ('\0' != *param))
3761 param++;
3762
3763 if ('\0' == *param) {
3764 hddLog(VOS_TRACE_LEVEL_ERROR,
3765 "%s, No channel is provided in the list",
3766 __func__);
3767 ret = -EINVAL;
Ashish Kumar Dhanotiya95e5bc22018-04-19 17:06:33 +05303768 goto parse_failed;
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +05303769
3770 }
3771
3772 if (sscanf(param, "%d ", &tempInt) != 1) {
3773 hddLog(VOS_TRACE_LEVEL_ERROR,
3774 "%s: Cannot read channel number",
3775 __func__);
3776 ret = -EINVAL;
Ashish Kumar Dhanotiya95e5bc22018-04-19 17:06:33 +05303777 goto parse_failed;
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +05303778
3779 }
3780
3781 if (!IS_CHANNEL_VALID(tempInt)) {
3782 hddLog(VOS_TRACE_LEVEL_ERROR,
3783 "%s: Invalid channel number received",
3784 __func__);
3785 ret = -EINVAL;
Ashish Kumar Dhanotiya95e5bc22018-04-19 17:06:33 +05303786 goto parse_failed;
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +05303787
3788 }
3789
3790 hddLog(VOS_TRACE_LEVEL_INFO, "%s: channel[%d] = %d", __func__,
3791 j, tempInt);
Ashish Kumar Dhanotiya95e5bc22018-04-19 17:06:33 +05303792
3793 parsed_channels[j] = tempInt;
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +05303794 }
3795
3796 /*extra arguments check*/
3797 param = strchr(param, ' ');
3798 if (NULL != param) {
3799 while ((SPACE_ASCII_VALUE == *param) && ('\0' != *param))
3800 param++;
3801
3802 if ('\0' != *param) {
3803 hddLog(VOS_TRACE_LEVEL_ERROR,
3804 "%s: Invalid argument received", __func__);
3805 ret = -EINVAL;
Ashish Kumar Dhanotiya95e5bc22018-04-19 17:06:33 +05303806 goto parse_failed;
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +05303807 }
3808 }
3809
Ashish Kumar Dhanotiya95e5bc22018-04-19 17:06:33 +05303810 /*
3811 * If command is received first time, cache the channels to
3812 * be disabled else compare the channels received in the
3813 * command with the cached channels, if channel list matches
3814 * return success otherewise return failure.
3815 */
3816 if (!is_command_repeated)
3817 for (j = 0; j < num_channels; j++)
3818 hdd_ctx->original_channels->
3819 channel_info[j].channel_num =
3820 parsed_channels[j];
3821 else {
3822 for (i = 0; i < num_channels; i++) {
3823 for (j = 0; j < num_channels; j++)
3824 if (hdd_ctx->original_channels->
3825 channel_info[i].channel_num ==
3826 parsed_channels[j])
3827 break;
3828 if (j == num_channels) {
3829 ret = -EINVAL;
3830 goto parse_failed;
3831 }
3832 }
3833 ret = 0;
3834 }
3835
3836mem_alloc_failed:
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +05303837 mutex_unlock(&hdd_ctx->cache_channel_lock);
3838 EXIT();
3839
3840 return ret;
Ashish Kumar Dhanotiya95e5bc22018-04-19 17:06:33 +05303841
3842parse_failed:
3843 mutex_unlock(&hdd_ctx->cache_channel_lock);
3844 if (!is_command_repeated)
3845 wlan_hdd_free_cache_channels(hdd_ctx);
3846 EXIT();
3847 return ret;
3848
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +05303849}
3850
Hanumanth Reddy Pothula8ae38bb2018-03-07 18:59:30 +05303851int hdd_get_disable_ch_list(hdd_context_t *hdd_ctx, tANI_U8 *buf,
Ashish Kumar Dhanotiya95e5bc22018-04-19 17:06:33 +05303852 uint32_t buf_len)
Hanumanth Reddy Pothula8ae38bb2018-03-07 18:59:30 +05303853{
3854 struct hdd_cache_channel_info *ch_list;
3855 unsigned char i, num_ch;
3856 int len = 0;
3857
3858 mutex_lock(&hdd_ctx->cache_channel_lock);
Ashish Kumar Dhanotiya95e5bc22018-04-19 17:06:33 +05303859 if (hdd_ctx->original_channels &&
3860 hdd_ctx->original_channels->num_channels &&
3861 hdd_ctx->original_channels->channel_info) {
3862 num_ch = hdd_ctx->original_channels->num_channels;
Hanumanth Reddy Pothula8ae38bb2018-03-07 18:59:30 +05303863
3864 len = scnprintf(buf, buf_len, "%s %hhu",
3865 "GET_DISABLE_CHANNEL_LIST", num_ch);
3866
Ashish Kumar Dhanotiya95e5bc22018-04-19 17:06:33 +05303867 ch_list = hdd_ctx->original_channels->channel_info;
Hanumanth Reddy Pothula8ae38bb2018-03-07 18:59:30 +05303868
Ashish Kumar Dhanotiya95e5bc22018-04-19 17:06:33 +05303869 for (i = 0; (i < num_ch) && (len < buf_len-1); i++) {
Hanumanth Reddy Pothula8ae38bb2018-03-07 18:59:30 +05303870 len += scnprintf(buf + len, buf_len - len,
3871 " %d", ch_list[i].channel_num);
3872 }
3873 }
3874 mutex_unlock(&hdd_ctx->cache_channel_lock);
3875
3876 return len;
3877}
3878
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07003879static int hdd_driver_command(hdd_adapter_t *pAdapter,
3880 hdd_priv_data_t *ppriv_data)
Jeff Johnson295189b2012-06-20 16:38:30 -07003881{
Jeff Johnson295189b2012-06-20 16:38:30 -07003882 hdd_priv_data_t priv_data;
3883 tANI_U8 *command = NULL;
Kaushik, Sushant96122442014-10-21 16:40:18 +05303884 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
3885 hdd_scaninfo_t *pScanInfo = NULL;
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07003886 int ret = 0;
Kaushik, Sushant96122442014-10-21 16:40:18 +05303887 int status;
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05303888#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
3889 struct cfg80211_mgmt_tx_params params;
3890#endif
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303891
3892 ENTER();
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07003893 /*
3894 * Note that valid pointers are provided by caller
3895 */
Jeff Johnson295189b2012-06-20 16:38:30 -07003896
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07003897 /* copy to local struct to avoid numerous changes to legacy code */
3898 priv_data = *ppriv_data;
Jeff Johnson295189b2012-06-20 16:38:30 -07003899
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07003900 if (priv_data.total_len <= 0 ||
3901 priv_data.total_len > WLAN_PRIV_DATA_MAX_LEN)
Sameer Thalappil8ef3a0e2013-04-05 14:36:04 -07003902 {
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07003903 hddLog(VOS_TRACE_LEVEL_WARN,
3904 "%s:invalid priv_data.total_len(%d)!!!", __func__,
3905 priv_data.total_len);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07003906 ret = -EINVAL;
3907 goto exit;
3908 }
Kaushik, Sushant96122442014-10-21 16:40:18 +05303909 status = wlan_hdd_validate_context(pHddCtx);
3910 if (0 != status)
3911 {
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303912 ret = -EINVAL;
3913 goto exit;
Kaushik, Sushant96122442014-10-21 16:40:18 +05303914 }
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07003915 /* Allocate +1 for '\0' */
3916 command = kmalloc(priv_data.total_len + 1, GFP_KERNEL);
Jeff Johnson295189b2012-06-20 16:38:30 -07003917 if (!command)
3918 {
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07003919 hddLog(VOS_TRACE_LEVEL_ERROR,
3920 "%s: failed to allocate memory", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07003921 ret = -ENOMEM;
3922 goto exit;
3923 }
3924
3925 if (copy_from_user(command, priv_data.buf, priv_data.total_len))
3926 {
3927 ret = -EFAULT;
3928 goto exit;
3929 }
3930
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07003931 /* Make sure the command is NUL-terminated */
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07003932 command[priv_data.total_len] = '\0';
3933
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07003934 /* at one time the following block of code was conditional. braces
3935 * have been retained to avoid re-indenting the legacy code
3936 */
Jeff Johnson295189b2012-06-20 16:38:30 -07003937 {
3938 hdd_context_t *pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
3939
3940 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudif9bdd4e2012-10-30 18:05:03 -07003941 "%s: Received %s cmd from Wi-Fi GUI***", __func__, command);
Jeff Johnson295189b2012-06-20 16:38:30 -07003942
3943 if (strncmp(command, "P2P_DEV_ADDR", 12) == 0 )
3944 {
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05303945 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
3946 TRACE_CODE_HDD_P2P_DEV_ADDR_IOCTL,
3947 pAdapter->sessionId, (unsigned)
3948 (*(pHddCtx->p2pDeviceAddress.bytes+2)<<24 |
3949 *(pHddCtx->p2pDeviceAddress.bytes+3)<<16 |
3950 *(pHddCtx->p2pDeviceAddress.bytes+4)<<8 |
3951 *(pHddCtx->p2pDeviceAddress.bytes+5))));
Jeff Johnson295189b2012-06-20 16:38:30 -07003952 if (copy_to_user(priv_data.buf, pHddCtx->p2pDeviceAddress.bytes,
3953 sizeof(tSirMacAddr)))
3954 {
3955 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08003956 "%s: failed to copy data to user buffer", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07003957 ret = -EFAULT;
3958 }
3959 }
Amar Singhal0974e402013-02-12 14:27:46 -08003960 else if(strncmp(command, "SETBAND", 7) == 0)
Jeff Johnson295189b2012-06-20 16:38:30 -07003961 {
Amar Singhal0974e402013-02-12 14:27:46 -08003962 tANI_U8 *ptr = command ;
Srinivas Girigowdade697412013-02-14 16:31:48 -08003963
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05303964 ret = hdd_drv_cmd_validate(command, 7);
3965 if (ret)
3966 goto exit;
3967
Jeff Johnson295189b2012-06-20 16:38:30 -07003968 /* Change band request received */
Srinivas Girigowdade697412013-02-14 16:31:48 -08003969
3970 /* First 8 bytes will have "SETBAND " and
Jeff Johnson295189b2012-06-20 16:38:30 -07003971 * 9 byte will have band setting value */
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07003972 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Amar Singhal0974e402013-02-12 14:27:46 -08003973 "%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 +05303974 if(VOS_FTM_MODE != hdd_get_conparam())
3975 {
3976 /* Change band request received */
3977 ret = hdd_setBand_helper(pAdapter->dev, ptr);
3978 if(ret < 0)
3979 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
3980 "%s: failed to set band ret=%d", __func__, ret);
3981 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08003982 }
Kiet Lamf040f472013-11-20 21:15:23 +05303983 else if(strncmp(command, "SETWMMPS", 8) == 0)
3984 {
3985 tANI_U8 *ptr = command;
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05303986
3987 ret = hdd_drv_cmd_validate(command, 8);
3988 if (ret)
3989 goto exit;
3990
Kiet Lamf040f472013-11-20 21:15:23 +05303991 ret = hdd_wmmps_helper(pAdapter, ptr);
3992 }
Agarwal Ashishef54a182014-12-16 15:07:31 +05303993
3994 else if(strncmp(command, "TDLSSCAN", 8) == 0)
3995 {
3996 tANI_U8 *ptr = command;
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05303997
3998 ret = hdd_drv_cmd_validate(command, 8);
3999 if (ret)
4000 goto exit;
4001
Agarwal Ashishef54a182014-12-16 15:07:31 +05304002 ret = hdd_set_tdls_scan_type(pAdapter, ptr);
4003 }
4004
Jeff Johnson32d95a32012-09-10 13:15:23 -07004005 else if ( strncasecmp(command, "COUNTRY", 7) == 0 )
4006 {
4007 char *country_code;
4008
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05304009 ret = hdd_drv_cmd_validate(command, 7);
4010 if (ret)
4011 goto exit;
4012
Jeff Johnson32d95a32012-09-10 13:15:23 -07004013 country_code = command + 8;
Tushnim Bhattacharyya9cdf6082013-04-21 16:33:30 -07004014
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07004015 INIT_COMPLETION(pAdapter->change_country_code);
Tushnim Bhattacharyya9cdf6082013-04-21 16:33:30 -07004016 hdd_checkandupdate_dfssetting(pAdapter, country_code);
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -07004017#ifndef CONFIG_ENABLE_LINUX_REG
Gopichand Nakkaladacbcb52013-04-18 16:41:54 +05304018 hdd_checkandupdate_phymode(pAdapter, country_code);
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -07004019#endif
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07004020 ret = (int)sme_ChangeCountryCode(pHddCtx->hHal,
4021 (void *)(tSmeChangeCountryCallback)
4022 wlan_hdd_change_country_code_callback,
Abhishek Singha306a442013-11-07 18:39:01 +05304023 country_code, pAdapter, pHddCtx->pvosContext, eSIR_TRUE, eSIR_TRUE);
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07004024 if (eHAL_STATUS_SUCCESS == ret)
4025 {
4026 ret = wait_for_completion_interruptible_timeout(
4027 &pAdapter->change_country_code,
4028 msecs_to_jiffies(WLAN_WAIT_TIME_COUNTRY));
4029 if (0 >= ret)
4030 {
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07004031 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: SME while setting country code timed out %d",
c_hpothu6ff1c3c2013-10-01 19:01:57 +05304032 __func__, ret);
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07004033 }
4034 }
4035 else
Jeff Johnson32d95a32012-09-10 13:15:23 -07004036 {
4037 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07004038 "%s: SME Change Country code fail ret=%d", __func__, ret);
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07004039 ret = -EINVAL;
Jeff Johnson32d95a32012-09-10 13:15:23 -07004040 }
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07004041
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07004042 }
4043 /*
4044 command should be a string having format
4045 SET_SAP_CHANNEL_LIST <num of channels> <the channels seperated by spaces>
4046 */
Amar Singhal0974e402013-02-12 14:27:46 -08004047 else if(strncmp(command, "SET_SAP_CHANNEL_LIST", 20) == 0)
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07004048 {
Amar Singhal0974e402013-02-12 14:27:46 -08004049 tANI_U8 *ptr = command;
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07004050
4051 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004052 " Received Command to Set Preferred Channels for SAP in %s", __func__);
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07004053
Mahesh Kumar Kalikot Veetil2aad8d82013-02-07 12:31:28 -08004054 ret = sapSetPreferredChannel(ptr);
Jeff Johnson32d95a32012-09-10 13:15:23 -07004055 }
Sourav Mohapatra2416e0e2018-03-05 18:44:21 +05304056
4057 else if (strncmp(command, "VOWIFIMODE", 10) == 0)
4058 {
4059 tANI_U8 *ptr;
4060
4061 ret = hdd_drv_cmd_validate(command, 10);
4062 if (ret)
4063 goto exit;
4064
4065 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4066 "Received Command for VOWIFI mode in %s", __func__);
4067
4068 ptr = (tANI_U8*)command + 11;
4069 hdd_set_vowifi_mode(pHddCtx, *ptr - '0');
4070 }
4071
Sameer Thalappil45931fb2013-02-01 11:18:05 -08004072 else if(strncmp(command, "SETSUSPENDMODE", 14) == 0)
4073 {
4074 int suspend = 0;
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05304075 tANI_U8 *ptr;
4076
4077 ret = hdd_drv_cmd_validate(command, 14);
4078 if (ret)
4079 goto exit;
4080
4081 ptr = (tANI_U8*)command + 15;
Sameer Thalappil45931fb2013-02-01 11:18:05 -08004082
4083 suspend = *ptr - '0';
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05304084 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
4085 TRACE_CODE_HDD_SETSUSPENDMODE_IOCTL,
4086 pAdapter->sessionId, suspend));
Sameer Thalappil45931fb2013-02-01 11:18:05 -08004087 hdd_set_wlan_suspend_mode(suspend);
4088 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08004089#ifdef WLAN_FEATURE_NEIGHBOR_ROAMING
4090 else if (strncmp(command, "SETROAMTRIGGER", 14) == 0)
4091 {
4092 tANI_U8 *value = command;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07004093 tANI_S8 rssi = 0;
Srinivas Girigowdade697412013-02-14 16:31:48 -08004094 tANI_U8 lookUpThreshold = CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_DEFAULT;
4095 eHalStatus status = eHAL_STATUS_SUCCESS;
4096
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05304097 ret = hdd_drv_cmd_validate(command, 14);
4098 if (ret)
4099 goto exit;
4100
Srinivas Girigowdade697412013-02-14 16:31:48 -08004101 /* Move pointer to ahead of SETROAMTRIGGER<delimiter> */
4102 value = value + 15;
4103
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07004104 /* Convert the value from ascii to integer */
4105 ret = kstrtos8(value, 10, &rssi);
4106 if (ret < 0)
4107 {
4108 /* If the input value is greater than max value of datatype, then also
4109 kstrtou8 fails */
4110 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4111 "%s: kstrtou8 failed Input value may be out of range[%d - %d]",
Srinivas Girigowdafa7157d2013-10-31 10:14:22 -07004112 __func__,
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07004113 CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MIN,
4114 CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MAX);
4115 ret = -EINVAL;
4116 goto exit;
4117 }
4118
Srinivas Girigowdade697412013-02-14 16:31:48 -08004119 lookUpThreshold = abs(rssi);
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07004120
Srinivas Girigowdade697412013-02-14 16:31:48 -08004121 if ((lookUpThreshold < CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MIN) ||
4122 (lookUpThreshold > CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MAX))
4123 {
4124 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4125 "Neighbor lookup threshold value %d is out of range"
4126 " (Min: %d Max: %d)", lookUpThreshold,
4127 CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MIN,
4128 CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MAX);
4129 ret = -EINVAL;
4130 goto exit;
4131 }
4132
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05304133 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
4134 TRACE_CODE_HDD_SETROAMTRIGGER_IOCTL,
4135 pAdapter->sessionId, lookUpThreshold));
Srinivas Girigowdade697412013-02-14 16:31:48 -08004136 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4137 "%s: Received Command to Set Roam trigger"
4138 " (Neighbor lookup threshold) = %d", __func__, lookUpThreshold);
4139
4140 pHddCtx->cfg_ini->nNeighborLookupRssiThreshold = lookUpThreshold;
4141 status = sme_setNeighborLookupRssiThreshold((tHalHandle)(pHddCtx->hHal), lookUpThreshold);
4142 if (eHAL_STATUS_SUCCESS != status)
4143 {
4144 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4145 "%s: Failed to set roam trigger, try again", __func__);
4146 ret = -EPERM;
4147 goto exit;
4148 }
4149
4150 /* Set Reassoc threshold to (lookup rssi threshold + 5 dBm) */
mukul sharmad6e1fdd2014-06-23 19:19:09 +05304151 pHddCtx->cfg_ini->nNeighborReassocRssiThreshold = lookUpThreshold + 5;
Srinivas Girigowdade697412013-02-14 16:31:48 -08004152 sme_setNeighborReassocRssiThreshold((tHalHandle)(pHddCtx->hHal), lookUpThreshold + 5);
4153 }
4154 else if (strncmp(command, "GETROAMTRIGGER", 14) == 0)
4155 {
4156 tANI_U8 lookUpThreshold = sme_getNeighborLookupRssiThreshold((tHalHandle)(pHddCtx->hHal));
4157 int rssi = (-1) * lookUpThreshold;
4158 char extra[32];
4159 tANI_U8 len = 0;
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05304160 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
4161 TRACE_CODE_HDD_GETROAMTRIGGER_IOCTL,
4162 pAdapter->sessionId, lookUpThreshold));
Sameer Thalappilb0a30232013-09-27 15:37:48 -07004163 len = scnprintf(extra, sizeof(extra), "%s %d", command, rssi);
Srinivas Girigowda91719232015-07-13 15:10:10 +05304164 len = VOS_MIN(priv_data.total_len, len + 1);
4165 if (copy_to_user(priv_data.buf, &extra, len))
Srinivas Girigowdade697412013-02-14 16:31:48 -08004166 {
4167 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4168 "%s: failed to copy data to user buffer", __func__);
4169 ret = -EFAULT;
4170 goto exit;
4171 }
4172 }
4173 else if (strncmp(command, "SETROAMSCANPERIOD", 17) == 0)
4174 {
4175 tANI_U8 *value = command;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07004176 tANI_U8 roamScanPeriod = 0;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004177 tANI_U16 neighborEmptyScanRefreshPeriod = CFG_EMPTY_SCAN_REFRESH_PERIOD_DEFAULT;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07004178
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05304179 ret = hdd_drv_cmd_validate(command, 17);
4180 if (ret)
4181 goto exit;
4182
Srinivas Girigowdade697412013-02-14 16:31:48 -08004183 /* input refresh period is in terms of seconds */
4184 /* Move pointer to ahead of SETROAMSCANPERIOD<delimiter> */
4185 value = value + 18;
4186 /* Convert the value from ascii to integer */
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07004187 ret = kstrtou8(value, 10, &roamScanPeriod);
Srinivas Girigowdade697412013-02-14 16:31:48 -08004188 if (ret < 0)
4189 {
4190 /* If the input value is greater than max value of datatype, then also
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07004191 kstrtou8 fails */
Srinivas Girigowdade697412013-02-14 16:31:48 -08004192 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07004193 "%s: kstrtou8 failed Input value may be out of range[%d - %d]",
Srinivas Girigowdade697412013-02-14 16:31:48 -08004194 __func__,
Srinivas Girigowdab8edd1e2013-03-19 11:42:08 -07004195 (CFG_EMPTY_SCAN_REFRESH_PERIOD_MIN/1000),
4196 (CFG_EMPTY_SCAN_REFRESH_PERIOD_MAX/1000));
Srinivas Girigowdade697412013-02-14 16:31:48 -08004197 ret = -EINVAL;
4198 goto exit;
4199 }
4200
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07004201 if ((roamScanPeriod < (CFG_EMPTY_SCAN_REFRESH_PERIOD_MIN/1000)) ||
4202 (roamScanPeriod > (CFG_EMPTY_SCAN_REFRESH_PERIOD_MAX/1000)))
Srinivas Girigowdade697412013-02-14 16:31:48 -08004203 {
4204 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07004205 "Roam scan period value %d is out of range"
4206 " (Min: %d Max: %d)", roamScanPeriod,
Srinivas Girigowdab8edd1e2013-03-19 11:42:08 -07004207 (CFG_EMPTY_SCAN_REFRESH_PERIOD_MIN/1000),
4208 (CFG_EMPTY_SCAN_REFRESH_PERIOD_MAX/1000));
Srinivas Girigowdade697412013-02-14 16:31:48 -08004209 ret = -EINVAL;
4210 goto exit;
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05304211 }
4212 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
4213 TRACE_CODE_HDD_SETROAMSCANPERIOD_IOCTL,
4214 pAdapter->sessionId, roamScanPeriod));
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07004215 neighborEmptyScanRefreshPeriod = roamScanPeriod * 1000;
Srinivas Girigowdade697412013-02-14 16:31:48 -08004216
4217 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4218 "%s: Received Command to Set roam scan period"
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07004219 " (Empty Scan refresh period) = %d", __func__, roamScanPeriod);
Srinivas Girigowdade697412013-02-14 16:31:48 -08004220
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004221 pHddCtx->cfg_ini->nEmptyScanRefreshPeriod = neighborEmptyScanRefreshPeriod;
4222 sme_UpdateEmptyScanRefreshPeriod((tHalHandle)(pHddCtx->hHal), neighborEmptyScanRefreshPeriod);
Srinivas Girigowdade697412013-02-14 16:31:48 -08004223 }
4224 else if (strncmp(command, "GETROAMSCANPERIOD", 17) == 0)
4225 {
4226 tANI_U16 nEmptyScanRefreshPeriod = sme_getEmptyScanRefreshPeriod((tHalHandle)(pHddCtx->hHal));
4227 char extra[32];
4228 tANI_U8 len = 0;
4229
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05304230 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
4231 TRACE_CODE_HDD_GETROAMSCANPERIOD_IOCTL,
4232 pAdapter->sessionId, nEmptyScanRefreshPeriod));
Sameer Thalappilb0a30232013-09-27 15:37:48 -07004233 len = scnprintf(extra, sizeof(extra), "%s %d",
4234 "GETROAMSCANPERIOD", (nEmptyScanRefreshPeriod/1000));
Srinivas Girigowdade697412013-02-14 16:31:48 -08004235 /* Returned value is in units of seconds */
Ratnam Rachuria72ba112015-07-17 13:27:03 +05304236 len = VOS_MIN(priv_data.total_len, len + 1);
4237 if (copy_to_user(priv_data.buf, &extra, len)) {
Srinivas Girigowdade697412013-02-14 16:31:48 -08004238 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4239 "%s: failed to copy data to user buffer", __func__);
4240 ret = -EFAULT;
4241 goto exit;
4242 }
4243 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004244 else if (strncmp(command, "SETROAMSCANREFRESHPERIOD", 24) == 0)
4245 {
4246 tANI_U8 *value = command;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07004247 tANI_U8 roamScanRefreshPeriod = 0;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004248 tANI_U16 neighborScanRefreshPeriod = CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_DEFAULT;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07004249
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05304250 ret = hdd_drv_cmd_validate(command, 24);
4251 if (ret)
4252 goto exit;
4253
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004254 /* input refresh period is in terms of seconds */
4255 /* Move pointer to ahead of SETROAMSCANREFRESHPERIOD<delimiter> */
4256 value = value + 25;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07004257
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004258 /* Convert the value from ascii to integer */
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07004259 ret = kstrtou8(value, 10, &roamScanRefreshPeriod);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004260 if (ret < 0)
4261 {
4262 /* If the input value is greater than max value of datatype, then also
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07004263 kstrtou8 fails */
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004264 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07004265 "%s: kstrtou8 failed Input value may be out of range[%d - %d]",
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004266 __func__,
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004267 (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MIN/1000),
4268 (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MAX/1000));
4269 ret = -EINVAL;
4270 goto exit;
4271 }
4272
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07004273 if ((roamScanRefreshPeriod < (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MIN/1000)) ||
4274 (roamScanRefreshPeriod > (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MAX/1000)))
4275 {
4276 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4277 "Neighbor scan results refresh period value %d is out of range"
4278 " (Min: %d Max: %d)", roamScanRefreshPeriod,
4279 (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MIN/1000),
4280 (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MAX/1000));
4281 ret = -EINVAL;
4282 goto exit;
4283 }
4284 neighborScanRefreshPeriod = roamScanRefreshPeriod * 1000;
4285
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004286 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4287 "%s: Received Command to Set roam scan refresh period"
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07004288 " (Scan refresh period) = %d", __func__, roamScanRefreshPeriod);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004289
4290 pHddCtx->cfg_ini->nNeighborResultsRefreshPeriod = neighborScanRefreshPeriod;
4291 sme_setNeighborScanRefreshPeriod((tHalHandle)(pHddCtx->hHal), neighborScanRefreshPeriod);
4292 }
4293 else if (strncmp(command, "GETROAMSCANREFRESHPERIOD", 24) == 0)
4294 {
4295 tANI_U16 value = sme_getNeighborScanRefreshPeriod((tHalHandle)(pHddCtx->hHal));
4296 char extra[32];
4297 tANI_U8 len = 0;
4298
Sameer Thalappilb0a30232013-09-27 15:37:48 -07004299 len = scnprintf(extra, sizeof(extra), "%s %d",
4300 "GETROAMSCANREFRESHPERIOD", (value/1000));
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004301 /* Returned value is in units of seconds */
Ratnam Rachuri2c9d6702015-07-17 13:25:16 +05304302 len = VOS_MIN(priv_data.total_len, len + 1);
4303 if (copy_to_user(priv_data.buf, &extra, len)) {
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004304 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4305 "%s: failed to copy data to user buffer", __func__);
4306 ret = -EFAULT;
4307 goto exit;
4308 }
4309 }
Varun Reddy Yeturu6d99ac82013-05-08 14:15:35 -07004310#ifdef FEATURE_WLAN_LFR
4311 /* SETROAMMODE */
4312 else if (strncmp(command, "SETROAMMODE", SIZE_OF_SETROAMMODE) == 0)
4313 {
4314 tANI_U8 *value = command;
4315 tANI_BOOLEAN roamMode = CFG_LFR_FEATURE_ENABLED_DEFAULT;
4316
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +05304317 if (pHddCtx->concurrency_mode == VOS_STA_MON) {
4318 hddLog(LOGE,
4319 FL("Roaming is always disabled in STA + MON concurrency"));
4320 ret = -EINVAL;
4321 goto exit;
4322 }
4323
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05304324 ret = hdd_drv_cmd_validate(command, SIZE_OF_SETROAMMODE);
4325 if (ret)
4326 goto exit;
4327
Varun Reddy Yeturu6d99ac82013-05-08 14:15:35 -07004328 /* Move pointer to ahead of SETROAMMODE<delimiter> */
4329 value = value + SIZE_OF_SETROAMMODE + 1;
4330
4331 /* Convert the value from ascii to integer */
4332 ret = kstrtou8(value, SIZE_OF_SETROAMMODE, &roamMode);
4333 if (ret < 0)
4334 {
4335 /* If the input value is greater than max value of datatype, then also
4336 kstrtou8 fails */
4337 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4338 "%s: kstrtou8 failed range [%d - %d]", __func__,
4339 CFG_LFR_FEATURE_ENABLED_MIN,
4340 CFG_LFR_FEATURE_ENABLED_MAX);
4341 ret = -EINVAL;
4342 goto exit;
4343 }
4344 if ((roamMode < CFG_LFR_FEATURE_ENABLED_MIN) ||
4345 (roamMode > CFG_LFR_FEATURE_ENABLED_MAX))
4346 {
4347 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4348 "Roam Mode value %d is out of range"
4349 " (Min: %d Max: %d)", roamMode,
4350 CFG_LFR_FEATURE_ENABLED_MIN,
4351 CFG_LFR_FEATURE_ENABLED_MAX);
4352 ret = -EINVAL;
4353 goto exit;
4354 }
4355
4356 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4357 "%s: Received Command to Set Roam Mode = %d", __func__, roamMode);
4358 /*
4359 * Note that
4360 * SETROAMMODE 0 is to enable LFR while
4361 * SETROAMMODE 1 is to disable LFR, but
4362 * NotifyIsFastRoamIniFeatureEnabled 0/1 is to enable/disable.
4363 * So, we have to invert the value to call sme_UpdateIsFastRoamIniFeatureEnabled.
4364 */
4365 if (CFG_LFR_FEATURE_ENABLED_MIN == roamMode)
4366 roamMode = CFG_LFR_FEATURE_ENABLED_MAX; /* Roam enable */
4367 else
4368 roamMode = CFG_LFR_FEATURE_ENABLED_MIN; /* Roam disable */
4369
4370 pHddCtx->cfg_ini->isFastRoamIniFeatureEnabled = roamMode;
4371 sme_UpdateIsFastRoamIniFeatureEnabled((tHalHandle)(pHddCtx->hHal), roamMode);
4372 }
4373 /* GETROAMMODE */
Mahesh A Saptasagarec7d1092015-04-02 13:41:34 +05304374 else if (strncmp(command, "GETROAMMODE", SIZE_OF_GETROAMMODE) == 0)
Varun Reddy Yeturu6d99ac82013-05-08 14:15:35 -07004375 {
4376 tANI_BOOLEAN roamMode = sme_getIsLfrFeatureEnabled((tHalHandle)(pHddCtx->hHal));
4377 char extra[32];
4378 tANI_U8 len = 0;
4379
4380 /*
4381 * roamMode value shall be inverted because the sementics is different.
4382 */
4383 if (CFG_LFR_FEATURE_ENABLED_MIN == roamMode)
4384 roamMode = CFG_LFR_FEATURE_ENABLED_MAX;
4385 else
4386 roamMode = CFG_LFR_FEATURE_ENABLED_MIN;
4387
Sameer Thalappilb0a30232013-09-27 15:37:48 -07004388 len = scnprintf(extra, sizeof(extra), "%s %d", command, roamMode);
Ratnam Rachuri28693eb2015-07-17 13:23:42 +05304389 len = VOS_MIN(priv_data.total_len, len + 1);
4390 if (copy_to_user(priv_data.buf, &extra, len)) {
Varun Reddy Yeturu6d99ac82013-05-08 14:15:35 -07004391 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4392 "%s: failed to copy data to user buffer", __func__);
4393 ret = -EFAULT;
4394 goto exit;
4395 }
4396 }
4397#endif
Srinivas Girigowdade697412013-02-14 16:31:48 -08004398#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004399#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowdade697412013-02-14 16:31:48 -08004400 else if (strncmp(command, "SETROAMDELTA", 12) == 0)
4401 {
4402 tANI_U8 *value = command;
4403 tANI_U8 roamRssiDiff = CFG_ROAM_RSSI_DIFF_DEFAULT;
4404
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05304405 ret = hdd_drv_cmd_validate(command, 12);
4406 if (ret)
4407 goto exit;
4408
Srinivas Girigowdade697412013-02-14 16:31:48 -08004409 /* Move pointer to ahead of SETROAMDELTA<delimiter> */
4410 value = value + 13;
4411 /* Convert the value from ascii to integer */
4412 ret = kstrtou8(value, 10, &roamRssiDiff);
4413 if (ret < 0)
4414 {
4415 /* If the input value is greater than max value of datatype, then also
4416 kstrtou8 fails */
4417 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4418 "%s: kstrtou8 failed range [%d - %d]", __func__,
4419 CFG_ROAM_RSSI_DIFF_MIN,
4420 CFG_ROAM_RSSI_DIFF_MAX);
4421 ret = -EINVAL;
4422 goto exit;
4423 }
4424
4425 if ((roamRssiDiff < CFG_ROAM_RSSI_DIFF_MIN) ||
4426 (roamRssiDiff > CFG_ROAM_RSSI_DIFF_MAX))
4427 {
4428 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4429 "Roam rssi diff value %d is out of range"
4430 " (Min: %d Max: %d)", roamRssiDiff,
4431 CFG_ROAM_RSSI_DIFF_MIN,
4432 CFG_ROAM_RSSI_DIFF_MAX);
4433 ret = -EINVAL;
4434 goto exit;
4435 }
4436
4437 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4438 "%s: Received Command to Set roam rssi diff = %d", __func__, roamRssiDiff);
4439
4440 pHddCtx->cfg_ini->RoamRssiDiff = roamRssiDiff;
4441 sme_UpdateRoamRssiDiff((tHalHandle)(pHddCtx->hHal), roamRssiDiff);
4442 }
Mahesh A Saptasagarec7d1092015-04-02 13:41:34 +05304443 else if (strncmp(command, "GETROAMDELTA", 12) == 0)
Srinivas Girigowdade697412013-02-14 16:31:48 -08004444 {
4445 tANI_U8 roamRssiDiff = sme_getRoamRssiDiff((tHalHandle)(pHddCtx->hHal));
4446 char extra[32];
4447 tANI_U8 len = 0;
4448
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05304449 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
4450 TRACE_CODE_HDD_GETROAMDELTA_IOCTL,
4451 pAdapter->sessionId, roamRssiDiff));
Sameer Thalappilb0a30232013-09-27 15:37:48 -07004452 len = scnprintf(extra, sizeof(extra), "%s %d",
4453 command, roamRssiDiff);
Ratnam Rachuri22a3b402015-07-17 13:21:49 +05304454 len = VOS_MIN(priv_data.total_len, len + 1);
4455 if (copy_to_user(priv_data.buf, &extra, len)) {
Srinivas Girigowdade697412013-02-14 16:31:48 -08004456 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4457 "%s: failed to copy data to user buffer", __func__);
4458 ret = -EFAULT;
4459 goto exit;
4460 }
4461 }
4462#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004463#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowdade697412013-02-14 16:31:48 -08004464 else if (strncmp(command, "GETBAND", 7) == 0)
4465 {
4466 int band = -1;
4467 char extra[32];
4468 tANI_U8 len = 0;
4469 hdd_getBand_helper(pHddCtx, &band);
4470
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05304471 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
4472 TRACE_CODE_HDD_GETBAND_IOCTL,
4473 pAdapter->sessionId, band));
Sameer Thalappilb0a30232013-09-27 15:37:48 -07004474 len = scnprintf(extra, sizeof(extra), "%s %d", command, band);
Ratnam Rachuri52139592015-07-17 13:17:29 +05304475 len = VOS_MIN(priv_data.total_len, len + 1);
4476 if (copy_to_user(priv_data.buf, &extra, len)) {
Srinivas Girigowdade697412013-02-14 16:31:48 -08004477 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4478 "%s: failed to copy data to user buffer", __func__);
4479 ret = -EFAULT;
4480 goto exit;
4481 }
4482 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08004483 else if (strncmp(command, "SETROAMSCANCHANNELS", 19) == 0)
4484 {
4485 tANI_U8 *value = command;
4486 tANI_U8 ChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
4487 tANI_U8 numChannels = 0;
4488 eHalStatus status = eHAL_STATUS_SUCCESS;
4489
4490 status = hdd_parse_channellist(value, ChannelList, &numChannels);
4491 if (eHAL_STATUS_SUCCESS != status)
4492 {
4493 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4494 "%s: Failed to parse channel list information", __func__);
4495 ret = -EINVAL;
4496 goto exit;
4497 }
4498
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05304499 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
4500 TRACE_CODE_HDD_SETROAMSCANCHANNELS_IOCTL,
4501 pAdapter->sessionId, numChannels));
Srinivas Girigowdade697412013-02-14 16:31:48 -08004502 if (numChannels > WNI_CFG_VALID_CHANNEL_LIST_LEN)
4503 {
4504 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4505 "%s: number of channels (%d) supported exceeded max (%d)", __func__,
4506 numChannels, WNI_CFG_VALID_CHANNEL_LIST_LEN);
4507 ret = -EINVAL;
4508 goto exit;
4509 }
4510 status = sme_ChangeRoamScanChannelList((tHalHandle)(pHddCtx->hHal), ChannelList,
4511 numChannels);
4512 if (eHAL_STATUS_SUCCESS != status)
4513 {
4514 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4515 "%s: Failed to update channel list information", __func__);
4516 ret = -EINVAL;
4517 goto exit;
4518 }
4519 }
4520 else if (strncmp(command, "GETROAMSCANCHANNELS", 19) == 0)
4521 {
4522 tANI_U8 ChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
4523 tANI_U8 numChannels = 0;
Jeff Johnson51b67782013-04-05 12:35:41 -07004524 tANI_U8 j = 0;
Srinivas Girigowdade697412013-02-14 16:31:48 -08004525 char extra[128] = {0};
Jeff Johnson51b67782013-04-05 12:35:41 -07004526 int len;
Srinivas Girigowdade697412013-02-14 16:31:48 -08004527
4528 if (eHAL_STATUS_SUCCESS != sme_getRoamScanChannelList( (tHalHandle)(pHddCtx->hHal),
4529 ChannelList, &numChannels ))
4530 {
4531 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
4532 "%s: failed to get roam scan channel list", __func__);
4533 ret = -EFAULT;
4534 goto exit;
4535 }
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05304536 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
4537 TRACE_CODE_HDD_GETROAMSCANCHANNELS_IOCTL,
4538 pAdapter->sessionId, numChannels));
Srinivas Girigowdade697412013-02-14 16:31:48 -08004539 /* output channel list is of the format
4540 [Number of roam scan channels][Channel1][Channel2]... */
4541 /* copy the number of channels in the 0th index */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07004542 len = scnprintf(extra, sizeof(extra), "%s %d", command, numChannels);
Sushant Kaushika08ca192015-09-16 15:52:04 +05304543 for (j = 0; (j < numChannels) && len <= sizeof(extra); j++)
Srinivas Girigowdade697412013-02-14 16:31:48 -08004544 {
Sameer Thalappilb0a30232013-09-27 15:37:48 -07004545 len += scnprintf(extra + len, sizeof(extra) - len, " %d",
4546 ChannelList[j]);
Srinivas Girigowdade697412013-02-14 16:31:48 -08004547 }
4548
Sushant Kaushikc9b8be52015-07-15 16:41:27 +05304549 len = VOS_MIN(priv_data.total_len, len + 1);
4550 if (copy_to_user(priv_data.buf, &extra, len))
Srinivas Girigowdade697412013-02-14 16:31:48 -08004551 {
4552 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4553 "%s: failed to copy data to user buffer", __func__);
4554 ret = -EFAULT;
4555 goto exit;
4556 }
4557 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004558 else if (strncmp(command, "GETCCXMODE", 10) == 0)
4559 {
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004560 tANI_BOOLEAN eseMode = sme_getIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal));
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004561 char extra[32];
4562 tANI_U8 len = 0;
4563
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004564 /* Check if the features OKC/ESE/11R are supported simultaneously,
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07004565 then this operation is not permitted (return FAILURE) */
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004566 if (eseMode &&
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07004567 hdd_is_okc_mode_enabled(pHddCtx) &&
4568 sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal)))
4569 {
4570 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004571 "%s: OKC/ESE/11R are supported simultaneously"
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07004572 " hence this operation is not permitted!", __func__);
4573 ret = -EPERM;
4574 goto exit;
4575 }
4576
Sameer Thalappilb0a30232013-09-27 15:37:48 -07004577 len = scnprintf(extra, sizeof(extra), "%s %d",
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004578 "GETCCXMODE", eseMode);
Sushant Kaushikf8abd352015-07-15 16:37:49 +05304579 len = VOS_MIN(priv_data.total_len, len + 1);
4580 if (copy_to_user(priv_data.buf, &extra, len))
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004581 {
4582 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4583 "%s: failed to copy data to user buffer", __func__);
4584 ret = -EFAULT;
4585 goto exit;
4586 }
4587 }
4588 else if (strncmp(command, "GETOKCMODE", 10) == 0)
4589 {
4590 tANI_BOOLEAN okcMode = hdd_is_okc_mode_enabled(pHddCtx);
4591 char extra[32];
4592 tANI_U8 len = 0;
4593
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004594 /* Check if the features OKC/ESE/11R are supported simultaneously,
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07004595 then this operation is not permitted (return FAILURE) */
4596 if (okcMode &&
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004597 sme_getIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal)) &&
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07004598 sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal)))
4599 {
4600 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004601 "%s: OKC/ESE/11R are supported simultaneously"
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07004602 " hence this operation is not permitted!", __func__);
4603 ret = -EPERM;
4604 goto exit;
4605 }
4606
Sameer Thalappilb0a30232013-09-27 15:37:48 -07004607 len = scnprintf(extra, sizeof(extra), "%s %d",
4608 "GETOKCMODE", okcMode);
Sushant Kaushikbc2fb5c2015-07-15 16:43:16 +05304609 len = VOS_MIN(priv_data.total_len, len + 1);
4610 if (copy_to_user(priv_data.buf, &extra, len))
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004611 {
4612 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4613 "%s: failed to copy data to user buffer", __func__);
4614 ret = -EFAULT;
4615 goto exit;
4616 }
4617 }
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07004618 else if (strncmp(command, "GETFASTROAM", 11) == 0)
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004619 {
4620 tANI_BOOLEAN lfrMode = sme_getIsLfrFeatureEnabled((tHalHandle)(pHddCtx->hHal));
4621 char extra[32];
4622 tANI_U8 len = 0;
4623
Sameer Thalappilb0a30232013-09-27 15:37:48 -07004624 len = scnprintf(extra, sizeof(extra), "%s %d",
4625 "GETFASTROAM", lfrMode);
Sushant Kaushik4da7ec92015-07-15 16:39:32 +05304626 len = VOS_MIN(priv_data.total_len, len + 1);
4627 if (copy_to_user(priv_data.buf, &extra, len))
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004628 {
4629 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4630 "%s: failed to copy data to user buffer", __func__);
4631 ret = -EFAULT;
4632 goto exit;
4633 }
4634 }
4635 else if (strncmp(command, "GETFASTTRANSITION", 17) == 0)
4636 {
4637 tANI_BOOLEAN ft = sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal));
4638 char extra[32];
4639 tANI_U8 len = 0;
4640
Sameer Thalappilb0a30232013-09-27 15:37:48 -07004641 len = scnprintf(extra, sizeof(extra), "%s %d",
4642 "GETFASTTRANSITION", ft);
Sushant Kaushik231a4452015-07-15 16:23:56 +05304643 len = VOS_MIN(priv_data.total_len, len + 1);
4644 if (copy_to_user(priv_data.buf, &extra, len))
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004645 {
4646 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4647 "%s: failed to copy data to user buffer", __func__);
4648 ret = -EFAULT;
4649 goto exit;
4650 }
4651 }
4652 else if (strncmp(command, "SETROAMSCANCHANNELMINTIME", 25) == 0)
4653 {
4654 tANI_U8 *value = command;
4655 tANI_U8 minTime = CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_DEFAULT;
4656
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05304657 ret = hdd_drv_cmd_validate(command, 25);
4658 if (ret)
4659 goto exit;
4660
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004661 /* Move pointer to ahead of SETROAMSCANCHANNELMINTIME<delimiter> */
4662 value = value + 26;
4663 /* Convert the value from ascii to integer */
4664 ret = kstrtou8(value, 10, &minTime);
4665 if (ret < 0)
4666 {
4667 /* If the input value is greater than max value of datatype, then also
4668 kstrtou8 fails */
4669 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4670 "%s: kstrtou8 failed range [%d - %d]", __func__,
4671 CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MIN,
4672 CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MAX);
4673 ret = -EINVAL;
4674 goto exit;
4675 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004676 if ((minTime < CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MIN) ||
4677 (minTime > CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MAX))
4678 {
4679 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4680 "scan min channel time value %d is out of range"
4681 " (Min: %d Max: %d)", minTime,
4682 CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MIN,
4683 CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MAX);
4684 ret = -EINVAL;
4685 goto exit;
4686 }
4687
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05304688 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
4689 TRACE_CODE_HDD_SETROAMSCANCHANNELMINTIME_IOCTL,
4690 pAdapter->sessionId, minTime));
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004691 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4692 "%s: Received Command to change channel min time = %d", __func__, minTime);
4693
4694 pHddCtx->cfg_ini->nNeighborScanMinChanTime = minTime;
4695 sme_setNeighborScanMinChanTime((tHalHandle)(pHddCtx->hHal), minTime);
4696 }
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004697 else if (strncmp(command, "SENDACTIONFRAME", 15) == 0)
4698 {
4699 tANI_U8 *value = command;
4700 tANI_U8 channel = 0;
4701 tANI_U8 dwellTime = 0;
4702 tANI_U8 bufLen = 0;
4703 tANI_U8 *buf = NULL;
4704 tSirMacAddr targetApBssid;
4705 eHalStatus status = eHAL_STATUS_SUCCESS;
4706 struct ieee80211_channel chan;
4707 tANI_U8 finalLen = 0;
4708 tANI_U8 *finalBuf = NULL;
4709 tANI_U8 temp = 0;
4710 u64 cookie;
4711 hdd_station_ctx_t *pHddStaCtx = NULL;
4712 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4713
4714 /* if not associated, no need to send action frame */
4715 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
4716 {
4717 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s:Not associated!",__func__);
4718 ret = -EINVAL;
4719 goto exit;
4720 }
4721
4722 status = hdd_parse_send_action_frame_data(value, targetApBssid, &channel,
4723 &dwellTime, &buf, &bufLen);
4724 if (eHAL_STATUS_SUCCESS != status)
4725 {
4726 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4727 "%s: Failed to parse send action frame data", __func__);
4728 ret = -EINVAL;
4729 goto exit;
4730 }
4731
4732 /* if the target bssid is different from currently associated AP,
4733 then no need to send action frame */
4734 if (VOS_TRUE != vos_mem_compare(targetApBssid,
4735 pHddStaCtx->conn_info.bssId, sizeof(tSirMacAddr)))
4736 {
4737 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s:STA is not associated to this AP!",__func__);
4738 ret = -EINVAL;
Jeff Johnson11c33152013-04-16 17:52:40 -07004739 vos_mem_free(buf);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08004740 buf = NULL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004741 goto exit;
4742 }
4743
4744 /* if the channel number is different from operating channel then
4745 no need to send action frame */
4746 if (channel != pHddStaCtx->conn_info.operationChannel)
4747 {
4748 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4749 "%s: channel(%d) is different from operating channel(%d)",
4750 __func__, channel, pHddStaCtx->conn_info.operationChannel);
4751 ret = -EINVAL;
Jeff Johnson11c33152013-04-16 17:52:40 -07004752 vos_mem_free(buf);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08004753 buf = NULL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004754 goto exit;
4755 }
4756 chan.center_freq = sme_ChnToFreq(channel);
4757
4758 finalLen = bufLen + 24;
4759 finalBuf = vos_mem_malloc(finalLen);
4760 if (NULL == finalBuf)
4761 {
4762 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "%s:memory allocation failed",__func__);
4763 ret = -ENOMEM;
Jeff Johnson11c33152013-04-16 17:52:40 -07004764 vos_mem_free(buf);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08004765 buf = NULL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004766 goto exit;
4767 }
4768 vos_mem_zero(finalBuf, finalLen);
4769
4770 /* Fill subtype */
4771 temp = SIR_MAC_MGMT_ACTION << 4;
4772 vos_mem_copy(finalBuf + 0, &temp, sizeof(temp));
4773
4774 /* Fill type */
4775 temp = SIR_MAC_MGMT_FRAME;
4776 vos_mem_copy(finalBuf + 2, &temp, sizeof(temp));
4777
4778 /* Fill destination address (bssid of the AP) */
4779 vos_mem_copy(finalBuf + 4, targetApBssid, sizeof(targetApBssid));
4780
Srinivas Girigowdab27c0192013-06-03 10:19:56 -07004781 /* Fill source address (STA mac address) */
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004782 vos_mem_copy(finalBuf + 10, pAdapter->macAddressCurrent.bytes, sizeof(pAdapter->macAddressCurrent.bytes));
4783
Srinivas Girigowdab27c0192013-06-03 10:19:56 -07004784 /* Fill BSSID (AP mac address) */
4785 vos_mem_copy(finalBuf + 16, targetApBssid, sizeof(targetApBssid));
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004786
4787 /* Fill received buffer from 24th address */
4788 vos_mem_copy(finalBuf + 24, buf, bufLen);
4789
Jeff Johnson11c33152013-04-16 17:52:40 -07004790 /* done with the parsed buffer */
4791 vos_mem_free(buf);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08004792 buf = NULL;
Jeff Johnson11c33152013-04-16 17:52:40 -07004793
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05304794#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
4795 params.chan = &chan;
4796 params.offchan = 0;
4797 params.wait = dwellTime;
4798 params.buf = finalBuf;
4799 params.len = finalLen;
4800 params.no_cck = 1;
4801 params.dont_wait_for_ack = 1;
4802 ret = wlan_hdd_mgmt_tx(NULL, &pAdapter->wdev, &params, &cookie);
4803#else
DARAM SUDHA39eede62014-02-12 11:16:40 +05304804 wlan_hdd_mgmt_tx( NULL,
Yue Maf49ba872013-08-19 12:04:25 -07004805#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
4806 &(pAdapter->wdev),
4807#else
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07004808 pAdapter->dev,
Yue Maf49ba872013-08-19 12:04:25 -07004809#endif
4810 &chan, 0,
4811#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0))
4812 NL80211_CHAN_HT20, 1,
4813#endif
4814 dwellTime, finalBuf, finalLen, 1,
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004815 1, &cookie );
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05304816#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0)*/
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004817 vos_mem_free(finalBuf);
4818 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004819 else if (strncmp(command, "GETROAMSCANCHANNELMINTIME", 25) == 0)
4820 {
4821 tANI_U16 val = sme_getNeighborScanMinChanTime((tHalHandle)(pHddCtx->hHal));
4822 char extra[32];
4823 tANI_U8 len = 0;
4824
4825 /* value is interms of msec */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07004826 len = scnprintf(extra, sizeof(extra), "%s %d",
4827 "GETROAMSCANCHANNELMINTIME", val);
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05304828 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
4829 TRACE_CODE_HDD_GETROAMSCANCHANNELMINTIME_IOCTL,
4830 pAdapter->sessionId, val));
Sushant Kaushikbb8c52c2015-07-15 16:36:23 +05304831 len = VOS_MIN(priv_data.total_len, len + 1);
4832 if (copy_to_user(priv_data.buf, &extra, len))
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004833 {
4834 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4835 "%s: failed to copy data to user buffer", __func__);
4836 ret = -EFAULT;
4837 goto exit;
4838 }
4839 }
4840 else if (strncmp(command, "SETSCANCHANNELTIME", 18) == 0)
4841 {
4842 tANI_U8 *value = command;
Varun Reddy Yeturu3885a662013-06-19 07:10:37 -07004843 tANI_U16 maxTime = CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_DEFAULT;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004844
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05304845 ret = hdd_drv_cmd_validate(command, 18);
4846 if (ret)
4847 goto exit;
4848
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004849 /* Move pointer to ahead of SETSCANCHANNELTIME<delimiter> */
4850 value = value + 19;
4851 /* Convert the value from ascii to integer */
Varun Reddy Yeturu3885a662013-06-19 07:10:37 -07004852 ret = kstrtou16(value, 10, &maxTime);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004853 if (ret < 0)
4854 {
4855 /* If the input value is greater than max value of datatype, then also
Varun Reddy Yeturu3885a662013-06-19 07:10:37 -07004856 kstrtou16 fails */
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004857 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Varun Reddy Yeturu3885a662013-06-19 07:10:37 -07004858 "%s: kstrtou16 failed range [%d - %d]", __func__,
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004859 CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MIN,
4860 CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MAX);
4861 ret = -EINVAL;
4862 goto exit;
4863 }
4864
4865 if ((maxTime < CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MIN) ||
4866 (maxTime > CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MAX))
4867 {
4868 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4869 "lfr mode value %d is out of range"
4870 " (Min: %d Max: %d)", maxTime,
4871 CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MIN,
4872 CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MAX);
4873 ret = -EINVAL;
4874 goto exit;
4875 }
4876
4877 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4878 "%s: Received Command to change channel max time = %d", __func__, maxTime);
4879
4880 pHddCtx->cfg_ini->nNeighborScanMaxChanTime = maxTime;
4881 sme_setNeighborScanMaxChanTime((tHalHandle)(pHddCtx->hHal), maxTime);
4882 }
4883 else if (strncmp(command, "GETSCANCHANNELTIME", 18) == 0)
4884 {
4885 tANI_U16 val = sme_getNeighborScanMaxChanTime((tHalHandle)(pHddCtx->hHal));
4886 char extra[32];
4887 tANI_U8 len = 0;
4888
4889 /* value is interms of msec */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07004890 len = scnprintf(extra, sizeof(extra), "%s %d",
4891 "GETSCANCHANNELTIME", val);
Ratheesh S Pacbfa932015-07-16 15:27:18 +05304892 len = VOS_MIN(priv_data.total_len, len + 1);
4893 if (copy_to_user(priv_data.buf, &extra, len))
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004894 {
4895 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4896 "%s: failed to copy data to user buffer", __func__);
4897 ret = -EFAULT;
4898 goto exit;
4899 }
4900 }
4901 else if (strncmp(command, "SETSCANHOMETIME", 15) == 0)
4902 {
4903 tANI_U8 *value = command;
4904 tANI_U16 val = CFG_NEIGHBOR_SCAN_TIMER_PERIOD_DEFAULT;
4905
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05304906 ret = hdd_drv_cmd_validate(command, 15);
4907 if (ret)
4908 goto exit;
4909
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004910 /* Move pointer to ahead of SETSCANHOMETIME<delimiter> */
4911 value = value + 16;
4912 /* Convert the value from ascii to integer */
4913 ret = kstrtou16(value, 10, &val);
4914 if (ret < 0)
4915 {
4916 /* If the input value is greater than max value of datatype, then also
4917 kstrtou16 fails */
4918 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4919 "%s: kstrtou16 failed range [%d - %d]", __func__,
4920 CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MIN,
4921 CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MAX);
4922 ret = -EINVAL;
4923 goto exit;
4924 }
4925
4926 if ((val < CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MIN) ||
4927 (val > CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MAX))
4928 {
4929 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4930 "scan home time value %d is out of range"
4931 " (Min: %d Max: %d)", val,
4932 CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MIN,
4933 CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MAX);
4934 ret = -EINVAL;
4935 goto exit;
4936 }
4937
4938 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4939 "%s: Received Command to change scan home time = %d", __func__, val);
4940
4941 pHddCtx->cfg_ini->nNeighborScanPeriod = val;
4942 sme_setNeighborScanPeriod((tHalHandle)(pHddCtx->hHal), val);
4943 }
4944 else if (strncmp(command, "GETSCANHOMETIME", 15) == 0)
4945 {
4946 tANI_U16 val = sme_getNeighborScanPeriod((tHalHandle)(pHddCtx->hHal));
4947 char extra[32];
4948 tANI_U8 len = 0;
4949
4950 /* value is interms of msec */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07004951 len = scnprintf(extra, sizeof(extra), "%s %d",
4952 "GETSCANHOMETIME", val);
Ratheesh S P728d7c62015-07-16 15:38:58 +05304953 len = VOS_MIN(priv_data.total_len, len + 1);
4954 if (copy_to_user(priv_data.buf, &extra, len))
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004955 {
4956 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4957 "%s: failed to copy data to user buffer", __func__);
4958 ret = -EFAULT;
4959 goto exit;
4960 }
4961 }
4962 else if (strncmp(command, "SETROAMINTRABAND", 16) == 0)
4963 {
4964 tANI_U8 *value = command;
4965 tANI_U8 val = CFG_ROAM_INTRA_BAND_DEFAULT;
4966
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05304967 ret = hdd_drv_cmd_validate(command, 16);
4968 if (ret)
4969 goto exit;
4970
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004971 /* Move pointer to ahead of SETROAMINTRABAND<delimiter> */
4972 value = value + 17;
4973 /* Convert the value from ascii to integer */
4974 ret = kstrtou8(value, 10, &val);
4975 if (ret < 0)
4976 {
4977 /* If the input value is greater than max value of datatype, then also
4978 kstrtou8 fails */
4979 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4980 "%s: kstrtou8 failed range [%d - %d]", __func__,
4981 CFG_ROAM_INTRA_BAND_MIN,
4982 CFG_ROAM_INTRA_BAND_MAX);
4983 ret = -EINVAL;
4984 goto exit;
4985 }
4986
4987 if ((val < CFG_ROAM_INTRA_BAND_MIN) ||
4988 (val > CFG_ROAM_INTRA_BAND_MAX))
4989 {
4990 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4991 "intra band mode value %d is out of range"
4992 " (Min: %d Max: %d)", val,
4993 CFG_ROAM_INTRA_BAND_MIN,
4994 CFG_ROAM_INTRA_BAND_MAX);
4995 ret = -EINVAL;
4996 goto exit;
4997 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004998 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4999 "%s: Received Command to change intra band = %d", __func__, val);
5000
5001 pHddCtx->cfg_ini->nRoamIntraBand = val;
5002 sme_setRoamIntraBand((tHalHandle)(pHddCtx->hHal), val);
5003 }
5004 else if (strncmp(command, "GETROAMINTRABAND", 16) == 0)
5005 {
5006 tANI_U16 val = sme_getRoamIntraBand((tHalHandle)(pHddCtx->hHal));
5007 char extra[32];
5008 tANI_U8 len = 0;
5009
5010 /* value is interms of msec */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07005011 len = scnprintf(extra, sizeof(extra), "%s %d",
5012 "GETROAMINTRABAND", val);
Ratheesh S P2dd2a3e2015-07-16 15:34:23 +05305013 len = VOS_MIN(priv_data.total_len, len + 1);
5014 if (copy_to_user(priv_data.buf, &extra, len))
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07005015 {
5016 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5017 "%s: failed to copy data to user buffer", __func__);
5018 ret = -EFAULT;
5019 goto exit;
5020 }
5021 }
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005022 else if (strncmp(command, "SETSCANNPROBES", 14) == 0)
5023 {
5024 tANI_U8 *value = command;
5025 tANI_U8 nProbes = CFG_ROAM_SCAN_N_PROBES_DEFAULT;
5026
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05305027 ret = hdd_drv_cmd_validate(command, 14);
5028 if (ret)
5029 goto exit;
5030
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005031 /* Move pointer to ahead of SETSCANNPROBES<delimiter> */
5032 value = value + 15;
5033 /* Convert the value from ascii to integer */
5034 ret = kstrtou8(value, 10, &nProbes);
5035 if (ret < 0)
5036 {
5037 /* If the input value is greater than max value of datatype, then also
5038 kstrtou8 fails */
5039 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5040 "%s: kstrtou8 failed range [%d - %d]", __func__,
5041 CFG_ROAM_SCAN_N_PROBES_MIN,
5042 CFG_ROAM_SCAN_N_PROBES_MAX);
5043 ret = -EINVAL;
5044 goto exit;
5045 }
5046
5047 if ((nProbes < CFG_ROAM_SCAN_N_PROBES_MIN) ||
5048 (nProbes > CFG_ROAM_SCAN_N_PROBES_MAX))
5049 {
5050 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5051 "NProbes value %d is out of range"
5052 " (Min: %d Max: %d)", nProbes,
5053 CFG_ROAM_SCAN_N_PROBES_MIN,
5054 CFG_ROAM_SCAN_N_PROBES_MAX);
5055 ret = -EINVAL;
5056 goto exit;
5057 }
5058
5059 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
5060 "%s: Received Command to Set nProbes = %d", __func__, nProbes);
5061
5062 pHddCtx->cfg_ini->nProbes = nProbes;
5063 sme_UpdateRoamScanNProbes((tHalHandle)(pHddCtx->hHal), nProbes);
5064 }
Mahesh A Saptasagarec7d1092015-04-02 13:41:34 +05305065 else if (strncmp(command, "GETSCANNPROBES", 14) == 0)
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005066 {
5067 tANI_U8 val = sme_getRoamScanNProbes((tHalHandle)(pHddCtx->hHal));
5068 char extra[32];
5069 tANI_U8 len = 0;
5070
Sameer Thalappilb0a30232013-09-27 15:37:48 -07005071 len = scnprintf(extra, sizeof(extra), "%s %d", command, val);
Ratnam Rachuri6da525d2015-08-07 13:55:54 +05305072 len = VOS_MIN(priv_data.total_len, len + 1);
5073 if (copy_to_user(priv_data.buf, &extra, len)) {
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005074 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5075 "%s: failed to copy data to user buffer", __func__);
5076 ret = -EFAULT;
5077 goto exit;
5078 }
5079 }
5080 else if (strncmp(command, "SETSCANHOMEAWAYTIME", 19) == 0)
5081 {
5082 tANI_U8 *value = command;
5083 tANI_U16 homeAwayTime = CFG_ROAM_SCAN_HOME_AWAY_TIME_DEFAULT;
5084
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05305085 ret = hdd_drv_cmd_validate(command, 19);
5086 if (ret)
5087 goto exit;
5088
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005089 /* Move pointer to ahead of SETSCANHOMEAWAYTIME<delimiter> */
5090 /* input value is in units of msec */
5091 value = value + 20;
5092 /* Convert the value from ascii to integer */
5093 ret = kstrtou16(value, 10, &homeAwayTime);
5094 if (ret < 0)
5095 {
5096 /* If the input value is greater than max value of datatype, then also
5097 kstrtou8 fails */
5098 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5099 "%s: kstrtou8 failed range [%d - %d]", __func__,
5100 CFG_ROAM_SCAN_HOME_AWAY_TIME_MIN,
5101 CFG_ROAM_SCAN_HOME_AWAY_TIME_MAX);
5102 ret = -EINVAL;
5103 goto exit;
5104 }
5105
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005106 if ((homeAwayTime < CFG_ROAM_SCAN_HOME_AWAY_TIME_MIN) ||
5107 (homeAwayTime > CFG_ROAM_SCAN_HOME_AWAY_TIME_MAX))
5108 {
5109 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5110 "homeAwayTime value %d is out of range"
5111 " (Min: %d Max: %d)", homeAwayTime,
5112 CFG_ROAM_SCAN_HOME_AWAY_TIME_MIN,
5113 CFG_ROAM_SCAN_HOME_AWAY_TIME_MAX);
5114 ret = -EINVAL;
5115 goto exit;
5116 }
5117
5118 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
5119 "%s: Received Command to Set scan away time = %d", __func__, homeAwayTime);
Srinivas Girigowda6cf0b822013-06-27 14:00:20 -07005120 if (pHddCtx->cfg_ini->nRoamScanHomeAwayTime != homeAwayTime)
5121 {
5122 pHddCtx->cfg_ini->nRoamScanHomeAwayTime = homeAwayTime;
5123 sme_UpdateRoamScanHomeAwayTime((tHalHandle)(pHddCtx->hHal), homeAwayTime, eANI_BOOLEAN_TRUE);
5124 }
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005125 }
Mahesh A Saptasagarec7d1092015-04-02 13:41:34 +05305126 else if (strncmp(command, "GETSCANHOMEAWAYTIME", 19) == 0)
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005127 {
5128 tANI_U16 val = sme_getRoamScanHomeAwayTime((tHalHandle)(pHddCtx->hHal));
5129 char extra[32];
5130 tANI_U8 len = 0;
5131
Sameer Thalappilb0a30232013-09-27 15:37:48 -07005132 len = scnprintf(extra, sizeof(extra), "%s %d", command, val);
Ratnam Rachuri51a5ad12015-08-07 14:06:37 +05305133 len = VOS_MIN(priv_data.total_len, len + 1);
5134 if (copy_to_user(priv_data.buf, &extra, len)) {
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005135 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5136 "%s: failed to copy data to user buffer", __func__);
5137 ret = -EFAULT;
5138 goto exit;
5139 }
5140 }
5141 else if (strncmp(command, "REASSOC", 7) == 0)
5142 {
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05305143 ret = hdd_drv_cmd_validate(command, 7);
5144 if (ret)
5145 goto exit;
5146
5147 ret = hdd_parse_reassoc(pAdapter, command, priv_data.total_len);
Selvaraj, Sridhar5aff1ed2016-06-18 01:26:23 +05305148 if (!ret)
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005149 goto exit;
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005150 }
Srinivas Girigowdaad34ca92013-10-22 10:54:29 -07005151 else if (strncmp(command, "SETWESMODE", 10) == 0)
5152 {
5153 tANI_U8 *value = command;
5154 tANI_BOOLEAN wesMode = CFG_ENABLE_WES_MODE_NAME_DEFAULT;
5155
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05305156 ret = hdd_drv_cmd_validate(command, 10);
5157 if (ret)
5158 goto exit;
5159
Srinivas Girigowdaad34ca92013-10-22 10:54:29 -07005160 /* Move pointer to ahead of SETWESMODE<delimiter> */
5161 value = value + 11;
5162 /* Convert the value from ascii to integer */
5163 ret = kstrtou8(value, 10, &wesMode);
5164 if (ret < 0)
5165 {
5166 /* If the input value is greater than max value of datatype, then also
5167 kstrtou8 fails */
5168 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5169 "%s: kstrtou8 failed range [%d - %d]", __func__,
5170 CFG_ENABLE_WES_MODE_NAME_MIN,
5171 CFG_ENABLE_WES_MODE_NAME_MAX);
5172 ret = -EINVAL;
5173 goto exit;
5174 }
5175
5176 if ((wesMode < CFG_ENABLE_WES_MODE_NAME_MIN) ||
5177 (wesMode > CFG_ENABLE_WES_MODE_NAME_MAX))
5178 {
5179 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5180 "WES Mode value %d is out of range"
5181 " (Min: %d Max: %d)", wesMode,
5182 CFG_ENABLE_WES_MODE_NAME_MIN,
5183 CFG_ENABLE_WES_MODE_NAME_MAX);
5184 ret = -EINVAL;
5185 goto exit;
5186 }
5187 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
5188 "%s: Received Command to Set WES Mode rssi diff = %d", __func__, wesMode);
5189
5190 pHddCtx->cfg_ini->isWESModeEnabled = wesMode;
5191 sme_UpdateWESMode((tHalHandle)(pHddCtx->hHal), wesMode);
5192 }
Mahesh A Saptasagarec7d1092015-04-02 13:41:34 +05305193 else if (strncmp(command, "GETWESMODE", 10) == 0)
Srinivas Girigowdaad34ca92013-10-22 10:54:29 -07005194 {
5195 tANI_BOOLEAN wesMode = sme_GetWESMode((tHalHandle)(pHddCtx->hHal));
5196 char extra[32];
5197 tANI_U8 len = 0;
5198
Arif Hussain826d9412013-11-12 16:44:54 -08005199 len = scnprintf(extra, sizeof(extra), "%s %d", command, wesMode);
Ratnam Rachuri8fe90c62015-08-07 14:03:26 +05305200 len = VOS_MIN(priv_data.total_len, len + 1);
5201 if (copy_to_user(priv_data.buf, &extra, len)) {
Srinivas Girigowdaad34ca92013-10-22 10:54:29 -07005202 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5203 "%s: failed to copy data to user buffer", __func__);
5204 ret = -EFAULT;
5205 goto exit;
5206 }
5207 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005208#endif /* WLAN_FEATURE_VOWIFI_11R || FEATURE_WLAN_ESE || FEATURE_WLAN_LFR */
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07005209#ifdef FEATURE_WLAN_LFR
5210 else if (strncmp(command, "SETFASTROAM", 11) == 0)
5211 {
5212 tANI_U8 *value = command;
5213 tANI_U8 lfrMode = CFG_LFR_FEATURE_ENABLED_DEFAULT;
5214
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +05305215 if (pHddCtx->concurrency_mode == VOS_STA_MON) {
5216 hddLog(LOGE,
5217 FL("Roaming is always disabled in STA + MON concurrency"));
5218 ret = -EINVAL;
5219 goto exit;
5220 }
5221
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05305222 ret = hdd_drv_cmd_validate(command, 11);
5223 if (ret)
5224 goto exit;
5225
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07005226 /* Move pointer to ahead of SETFASTROAM<delimiter> */
5227 value = value + 12;
5228 /* Convert the value from ascii to integer */
5229 ret = kstrtou8(value, 10, &lfrMode);
5230 if (ret < 0)
5231 {
5232 /* If the input value is greater than max value of datatype, then also
5233 kstrtou8 fails */
5234 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5235 "%s: kstrtou8 failed range [%d - %d]", __func__,
5236 CFG_LFR_FEATURE_ENABLED_MIN,
5237 CFG_LFR_FEATURE_ENABLED_MAX);
5238 ret = -EINVAL;
5239 goto exit;
5240 }
5241
5242 if ((lfrMode < CFG_LFR_FEATURE_ENABLED_MIN) ||
5243 (lfrMode > CFG_LFR_FEATURE_ENABLED_MAX))
5244 {
5245 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5246 "lfr mode value %d is out of range"
5247 " (Min: %d Max: %d)", lfrMode,
5248 CFG_LFR_FEATURE_ENABLED_MIN,
5249 CFG_LFR_FEATURE_ENABLED_MAX);
5250 ret = -EINVAL;
5251 goto exit;
5252 }
5253
5254 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
5255 "%s: Received Command to change lfr mode = %d", __func__, lfrMode);
5256
5257 pHddCtx->cfg_ini->isFastRoamIniFeatureEnabled = lfrMode;
5258 sme_UpdateIsFastRoamIniFeatureEnabled((tHalHandle)(pHddCtx->hHal), lfrMode);
5259 }
5260#endif
5261#ifdef WLAN_FEATURE_VOWIFI_11R
5262 else if (strncmp(command, "SETFASTTRANSITION", 17) == 0)
5263 {
5264 tANI_U8 *value = command;
5265 tANI_U8 ft = CFG_FAST_TRANSITION_ENABLED_NAME_DEFAULT;
5266
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05305267 ret = hdd_drv_cmd_validate(command, 17);
5268 if (ret)
5269 goto exit;
5270
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07005271 /* Move pointer to ahead of SETFASTROAM<delimiter> */
5272 value = value + 18;
5273 /* Convert the value from ascii to integer */
5274 ret = kstrtou8(value, 10, &ft);
5275 if (ret < 0)
5276 {
5277 /* If the input value is greater than max value of datatype, then also
5278 kstrtou8 fails */
5279 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5280 "%s: kstrtou8 failed range [%d - %d]", __func__,
5281 CFG_FAST_TRANSITION_ENABLED_NAME_MIN,
5282 CFG_FAST_TRANSITION_ENABLED_NAME_MAX);
5283 ret = -EINVAL;
5284 goto exit;
5285 }
5286
5287 if ((ft < CFG_FAST_TRANSITION_ENABLED_NAME_MIN) ||
5288 (ft > CFG_FAST_TRANSITION_ENABLED_NAME_MAX))
5289 {
5290 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5291 "ft mode value %d is out of range"
5292 " (Min: %d Max: %d)", ft,
5293 CFG_FAST_TRANSITION_ENABLED_NAME_MIN,
5294 CFG_FAST_TRANSITION_ENABLED_NAME_MAX);
5295 ret = -EINVAL;
5296 goto exit;
5297 }
5298
5299 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
5300 "%s: Received Command to change ft mode = %d", __func__, ft);
5301
5302 pHddCtx->cfg_ini->isFastTransitionEnabled = ft;
5303 sme_UpdateFastTransitionEnabled((tHalHandle)(pHddCtx->hHal), ft);
5304 }
Padma, Santhosh Kumar778d8382015-03-04 17:41:22 +05305305 else if (strncmp(command, "SETDFSSCANMODE", 14) == 0)
5306 {
5307 tANI_U8 *value = command;
5308 tANI_U8 dfsScanMode = DFS_CHNL_SCAN_ENABLED_NORMAL;
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05305309
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05305310 ret = hdd_drv_cmd_validate(command, 14);
5311 if (ret)
5312 goto exit;
5313
Padma, Santhosh Kumar778d8382015-03-04 17:41:22 +05305314 /* Move pointer to ahead of SETDFSSCANMODE<delimiter> */
5315 value = value + 15;
5316 /* Convert the value from ascii to integer */
5317 ret = kstrtou8(value, 10, &dfsScanMode);
5318 if (ret < 0)
5319 {
5320 /* If the input value is greater than max value of
5321 datatype, then also kstrtou8 fails
5322 */
5323 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5324 "%s: kstrtou8 failed range [%d - %d]", __func__,
5325 CFG_ENABLE_DFS_CHNL_SCAN_MIN,
5326 CFG_ENABLE_DFS_CHNL_SCAN_MAX);
5327 ret = -EINVAL;
5328 goto exit;
5329 }
5330
5331 if ((dfsScanMode < CFG_ENABLE_DFS_CHNL_SCAN_MIN) ||
5332 (dfsScanMode > CFG_ENABLE_DFS_CHNL_SCAN_MAX))
5333 {
5334 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5335 "dfsScanMode value %d is out of range"
5336 " (Min: %d Max: %d)", dfsScanMode,
5337 CFG_ENABLE_DFS_CHNL_SCAN_MIN,
5338 CFG_ENABLE_DFS_CHNL_SCAN_MAX);
5339 ret = -EINVAL;
5340 goto exit;
5341 }
5342 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
5343 "%s: Received Command to Set DFS Scan Mode = %d",
5344 __func__, dfsScanMode);
5345
5346 ret = wlan_hdd_handle_dfs_chan_scan(pHddCtx, dfsScanMode);
5347 }
5348 else if (strncmp(command, "GETDFSSCANMODE", 14) == 0)
5349 {
5350 tANI_U8 dfsScanMode = sme_GetDFSScanMode(pHddCtx->hHal);
5351 char extra[32];
5352 tANI_U8 len = 0;
5353
5354 len = scnprintf(extra, sizeof(extra), "%s %d", command, dfsScanMode);
Ratheesh S P767224e2015-07-16 15:35:51 +05305355 len = VOS_MIN(priv_data.total_len, len + 1);
5356 if (copy_to_user(priv_data.buf, &extra, len))
Padma, Santhosh Kumar778d8382015-03-04 17:41:22 +05305357 {
5358 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5359 "%s: failed to copy data to user buffer", __func__);
5360 ret = -EFAULT;
5361 goto exit;
5362 }
5363 }
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05305364 else if (strncmp(command, "FASTREASSOC", 11) == 0)
5365 {
Selvaraj, Sridhar3714c4d2016-06-22 15:19:12 +05305366 ret = wlan_hdd_handle_fastreassoc(pAdapter, command);
5367 if (!ret)
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05305368 goto exit;
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05305369 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07005370#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005371#ifdef FEATURE_WLAN_ESE
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07005372 else if (strncmp(command, "SETCCXMODE", 10) == 0)
5373 {
5374 tANI_U8 *value = command;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005375 tANI_U8 eseMode = CFG_ESE_FEATURE_ENABLED_DEFAULT;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07005376
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05305377 ret = hdd_drv_cmd_validate(command, 10);
5378 if (ret)
5379 goto exit;
5380
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005381 /* Check if the features OKC/ESE/11R are supported simultaneously,
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07005382 then this operation is not permitted (return FAILURE) */
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005383 if (sme_getIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal)) &&
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07005384 hdd_is_okc_mode_enabled(pHddCtx) &&
5385 sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal)))
5386 {
5387 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005388 "%s: OKC/ESE/11R are supported simultaneously"
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07005389 " hence this operation is not permitted!", __func__);
5390 ret = -EPERM;
5391 goto exit;
5392 }
5393
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07005394 /* Move pointer to ahead of SETCCXMODE<delimiter> */
5395 value = value + 11;
5396 /* Convert the value from ascii to integer */
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005397 ret = kstrtou8(value, 10, &eseMode);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07005398 if (ret < 0)
5399 {
5400 /* If the input value is greater than max value of datatype, then also
5401 kstrtou8 fails */
5402 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5403 "%s: kstrtou8 failed range [%d - %d]", __func__,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005404 CFG_ESE_FEATURE_ENABLED_MIN,
5405 CFG_ESE_FEATURE_ENABLED_MAX);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07005406 ret = -EINVAL;
5407 goto exit;
5408 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005409 if ((eseMode < CFG_ESE_FEATURE_ENABLED_MIN) ||
5410 (eseMode > CFG_ESE_FEATURE_ENABLED_MAX))
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07005411 {
5412 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005413 "Ese mode value %d is out of range"
5414 " (Min: %d Max: %d)", eseMode,
5415 CFG_ESE_FEATURE_ENABLED_MIN,
5416 CFG_ESE_FEATURE_ENABLED_MAX);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07005417 ret = -EINVAL;
5418 goto exit;
5419 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07005420 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005421 "%s: Received Command to change ese mode = %d", __func__, eseMode);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07005422
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005423 pHddCtx->cfg_ini->isEseIniFeatureEnabled = eseMode;
5424 sme_UpdateIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal), eseMode);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07005425 }
5426#endif
Srinivas Girigowda100eb322013-03-15 16:48:20 -07005427 else if (strncmp(command, "SETROAMSCANCONTROL", 18) == 0)
5428 {
5429 tANI_U8 *value = command;
5430 tANI_BOOLEAN roamScanControl = 0;
5431
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05305432 ret = hdd_drv_cmd_validate(command, 18);
5433 if (ret)
5434 goto exit;
5435
Srinivas Girigowda100eb322013-03-15 16:48:20 -07005436 /* Move pointer to ahead of SETROAMSCANCONTROL<delimiter> */
5437 value = value + 19;
5438 /* Convert the value from ascii to integer */
5439 ret = kstrtou8(value, 10, &roamScanControl);
5440 if (ret < 0)
5441 {
5442 /* If the input value is greater than max value of datatype, then also
5443 kstrtou8 fails */
5444 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5445 "%s: kstrtou8 failed ", __func__);
5446 ret = -EINVAL;
5447 goto exit;
5448 }
5449
5450 if (0 != roamScanControl)
5451 {
5452 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5453 "roam scan control invalid value = %d",
5454 roamScanControl);
5455 ret = -EINVAL;
5456 goto exit;
5457 }
5458 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
5459 "%s: Received Command to Set roam scan control = %d", __func__, roamScanControl);
5460
5461 sme_SetRoamScanControl((tHalHandle)(pHddCtx->hHal), roamScanControl);
5462 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07005463#ifdef FEATURE_WLAN_OKC
5464 else if (strncmp(command, "SETOKCMODE", 10) == 0)
5465 {
5466 tANI_U8 *value = command;
5467 tANI_U8 okcMode = CFG_OKC_FEATURE_ENABLED_DEFAULT;
5468
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05305469 ret = hdd_drv_cmd_validate(command, 10);
5470 if (ret)
5471 goto exit;
5472
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005473 /* Check if the features OKC/ESE/11R are supported simultaneously,
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07005474 then this operation is not permitted (return FAILURE) */
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005475 if (sme_getIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal)) &&
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07005476 hdd_is_okc_mode_enabled(pHddCtx) &&
5477 sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal)))
5478 {
5479 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005480 "%s: OKC/ESE/11R are supported simultaneously"
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07005481 " hence this operation is not permitted!", __func__);
5482 ret = -EPERM;
5483 goto exit;
5484 }
5485
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07005486 /* Move pointer to ahead of SETOKCMODE<delimiter> */
5487 value = value + 11;
5488 /* Convert the value from ascii to integer */
5489 ret = kstrtou8(value, 10, &okcMode);
5490 if (ret < 0)
5491 {
5492 /* If the input value is greater than max value of datatype, then also
5493 kstrtou8 fails */
5494 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5495 "%s: kstrtou8 failed range [%d - %d]", __func__,
5496 CFG_OKC_FEATURE_ENABLED_MIN,
5497 CFG_OKC_FEATURE_ENABLED_MAX);
5498 ret = -EINVAL;
5499 goto exit;
5500 }
5501
5502 if ((okcMode < CFG_OKC_FEATURE_ENABLED_MIN) ||
5503 (okcMode > CFG_OKC_FEATURE_ENABLED_MAX))
5504 {
5505 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5506 "Okc mode value %d is out of range"
5507 " (Min: %d Max: %d)", okcMode,
5508 CFG_OKC_FEATURE_ENABLED_MIN,
5509 CFG_OKC_FEATURE_ENABLED_MAX);
5510 ret = -EINVAL;
5511 goto exit;
5512 }
5513
5514 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
5515 "%s: Received Command to change okc mode = %d", __func__, okcMode);
5516
5517 pHddCtx->cfg_ini->isOkcIniFeatureEnabled = okcMode;
5518 }
Srinivas Girigowdaad34ca92013-10-22 10:54:29 -07005519#endif /* FEATURE_WLAN_OKC */
Mahesh A Saptasagarec7d1092015-04-02 13:41:34 +05305520 else if (strncmp(command, "GETROAMSCANCONTROL", 18) == 0)
Srinivas Girigowda100eb322013-03-15 16:48:20 -07005521 {
5522 tANI_BOOLEAN roamScanControl = sme_GetRoamScanControl((tHalHandle)(pHddCtx->hHal));
5523 char extra[32];
5524 tANI_U8 len = 0;
5525
Sameer Thalappilb0a30232013-09-27 15:37:48 -07005526 len = scnprintf(extra, sizeof(extra), "%s %d",
5527 command, roamScanControl);
Ratnam Rachuri083ada82015-08-07 14:01:05 +05305528 len = VOS_MIN(priv_data.total_len, len + 1);
5529 if (copy_to_user(priv_data.buf, &extra, len)) {
Srinivas Girigowda100eb322013-03-15 16:48:20 -07005530 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5531 "%s: failed to copy data to user buffer", __func__);
5532 ret = -EFAULT;
5533 goto exit;
5534 }
5535 }
Gopichand Nakkala227c7f32013-06-26 22:44:57 +05305536#ifdef WLAN_FEATURE_PACKET_FILTERING
5537 else if (strncmp(command, "ENABLE_PKTFILTER_IPV6", 21) == 0)
5538 {
5539 tANI_U8 filterType = 0;
5540 tANI_U8 *value = command;
5541
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05305542 ret = hdd_drv_cmd_validate(command, 21);
5543 if (ret)
5544 goto exit;
5545
Gopichand Nakkala227c7f32013-06-26 22:44:57 +05305546 /* Move pointer to ahead of ENABLE_PKTFILTER_IPV6<delimiter> */
5547 value = value + 22;
5548
5549 /* Convert the value from ascii to integer */
5550 ret = kstrtou8(value, 10, &filterType);
5551 if (ret < 0)
5552 {
5553 /* If the input value is greater than max value of datatype,
5554 * then also kstrtou8 fails
5555 */
5556 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5557 "%s: kstrtou8 failed range ", __func__);
5558 ret = -EINVAL;
5559 goto exit;
5560 }
5561
5562 if (filterType != 0 && filterType != 1)
5563 {
5564 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5565 "%s: Accepted Values are 0 and 1 ", __func__);
5566 ret = -EINVAL;
5567 goto exit;
5568 }
5569 wlan_hdd_setIPv6Filter(WLAN_HDD_GET_CTX(pAdapter), filterType,
5570 pAdapter->sessionId);
5571 }
5572#endif
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05305573 else if (strncmp(command, "BTCOEXMODE", 10) == 0 )
5574 {
Kiet Lamad161252014-07-22 11:23:32 -07005575 char *dhcpPhase;
Satyanarayana Dash1faea4f2014-09-22 16:21:04 +05305576 int ret;
5577
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05305578 ret = hdd_drv_cmd_validate(command, 10);
5579 if (ret)
5580 goto exit;
5581
Kiet Lamad161252014-07-22 11:23:32 -07005582 dhcpPhase = command + 11;
5583 if ('1' == *dhcpPhase)
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05305584 {
Deepthi Gowribfd17132014-11-14 17:59:04 +05305585 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Kiet Lamad161252014-07-22 11:23:32 -07005586 FL("send DHCP START indication"));
c_hpothu9b781ba2013-12-30 20:57:45 +05305587
5588 pHddCtx->btCoexModeSet = TRUE;
Kiet Lamad161252014-07-22 11:23:32 -07005589
Satyanarayana Dash1faea4f2014-09-22 16:21:04 +05305590 ret = wlan_hdd_scan_abort(pAdapter);
5591 if (ret < 0)
5592 {
5593 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5594 FL("failed to abort existing scan %d"), ret);
5595 }
5596
Kiet Lamad161252014-07-22 11:23:32 -07005597 sme_DHCPStartInd(pHddCtx->hHal, pAdapter->device_mode,
5598 pAdapter->sessionId);
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05305599 }
Kiet Lamad161252014-07-22 11:23:32 -07005600 else if ('2' == *dhcpPhase)
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05305601 {
Deepthi Gowribfd17132014-11-14 17:59:04 +05305602 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Kiet Lamad161252014-07-22 11:23:32 -07005603 FL("send DHCP STOP indication"));
c_hpothu9b781ba2013-12-30 20:57:45 +05305604
5605 pHddCtx->btCoexModeSet = FALSE;
Kiet Lamad161252014-07-22 11:23:32 -07005606
5607 sme_DHCPStopInd(pHddCtx->hHal, pAdapter->device_mode,
5608 pAdapter->sessionId);
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05305609 }
5610 }
Jeff Johnsonf54df2c2013-07-24 11:43:39 -07005611 else if (strncmp(command, "SCAN-ACTIVE", 11) == 0)
5612 {
Abhishek Singh58749d62016-02-03 15:27:20 +05305613 hddLog(LOG1,
5614 FL("making default scan to ACTIVE"));
c_hpothudbefd3e2014-04-28 15:59:47 +05305615 pHddCtx->scan_info.scan_mode = eSIR_ACTIVE_SCAN;
Jeff Johnsonf54df2c2013-07-24 11:43:39 -07005616 }
5617 else if (strncmp(command, "SCAN-PASSIVE", 12) == 0)
5618 {
Abhishek Singh58749d62016-02-03 15:27:20 +05305619 hddLog(LOG1,
5620 FL("making default scan to PASSIVE"));
c_hpothudbefd3e2014-04-28 15:59:47 +05305621 pHddCtx->scan_info.scan_mode = eSIR_PASSIVE_SCAN;
Jeff Johnsonf54df2c2013-07-24 11:43:39 -07005622 }
Hanumantha Reddy Pothula212243c2013-08-01 17:28:31 +05305623 else if (strncmp(command, "GETDWELLTIME", 12) == 0)
5624 {
5625 hdd_config_t *pCfg = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
5626 char extra[32];
5627 tANI_U8 len = 0;
5628
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05305629 memset(extra, 0, sizeof(extra));
5630 ret = hdd_get_dwell_time(pCfg, command, extra, sizeof(extra), &len);
Ratnam Rachuri12d5d462015-08-07 14:10:23 +05305631 len = VOS_MIN(priv_data.total_len, len + 1);
5632 if (ret != 0 || copy_to_user(priv_data.buf, &extra, len)) {
Hanumantha Reddy Pothula212243c2013-08-01 17:28:31 +05305633 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5634 "%s: failed to copy data to user buffer", __func__);
5635 ret = -EFAULT;
5636 goto exit;
5637 }
5638 ret = len;
5639 }
5640 else if (strncmp(command, "SETDWELLTIME", 12) == 0)
5641 {
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05305642 ret = hdd_set_dwell_time(pAdapter, command);
Hanumantha Reddy Pothula212243c2013-08-01 17:28:31 +05305643 }
Dundi Ravitejaae5adf42018-04-23 20:44:47 +05305644 else if (strncmp(command, "BTCGETDWELLTIME", 15) == 0)
5645 {
5646 hdd_config_t *pCfg = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
5647 char extra[32];
5648 tANI_U8 len = 0;
5649
5650 if (hdd_drv_cmd_validate(command, 15)) {
5651 hddLog(LOGE, FL("Invalid driver command"));
5652 return -EINVAL;
5653 }
5654
5655 memset(extra, 0, sizeof(extra));
5656 ret = hdd_btc_get_dwell_time(pCfg, command, extra,
5657 sizeof(extra), &len);
5658 len = VOS_MIN(priv_data.total_len, len + 1);
5659 if (ret != 0 || copy_to_user(priv_data.buf, &extra, len)) {
5660 hddLog(LOGE, FL("Failed to copy data to user buffer"));
5661 ret = -EFAULT;
5662 goto exit;
5663 }
5664 ret = len;
5665 }
5666 else if (strncmp(command, "BTCSETDWELLTIME", 15) == 0)
5667 {
5668 if (hdd_drv_cmd_validate(command, 15)) {
5669 hddLog(LOGE, FL("Invalid driver command"));
5670 return -EINVAL;
5671 }
5672 ret = hdd_btc_set_dwell_time(pAdapter, command);
5673 }
5674#ifdef WLAN_AP_STA_CONCURRENCY
5675 else if (strncmp(command, "CONCGETDWELLTIME", 16) == 0)
5676 {
5677 hdd_config_t *pCfg = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
5678 char extra[32];
5679 tANI_U8 len = 0;
5680
5681 if (hdd_drv_cmd_validate(command, 16)) {
5682 hddLog(LOGE, FL("Invalid driver command"));
5683 return -EINVAL;
5684 }
5685
5686 memset(extra, 0, sizeof(extra));
5687 ret = hdd_conc_get_dwell_time(pCfg, command, extra,
5688 sizeof(extra), &len);
5689 len = VOS_MIN(priv_data.total_len, len + 1);
5690 if (ret != 0 || copy_to_user(priv_data.buf, &extra, len)) {
5691 hddLog(LOGE, FL("Failed to copy data to user buffer"));
5692 ret = -EFAULT;
5693 goto exit;
5694 }
5695 ret = len;
5696 }
5697 else if (strncmp(command, "CONCSETDWELLTIME", 16) == 0)
5698 {
5699 if (hdd_drv_cmd_validate(command, 16)) {
5700 hddLog(LOGE, FL("Invalid driver command"));
5701 return -EINVAL;
5702 }
5703 ret = hdd_conc_set_dwell_time(pAdapter, command);
5704 }
5705#endif
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07005706 else if ( strncasecmp(command, "MIRACAST", 8) == 0 )
5707 {
5708 tANI_U8 filterType = 0;
5709 tANI_U8 *value;
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05305710
5711 ret = hdd_drv_cmd_validate(command, 8);
5712 if (ret)
5713 goto exit;
5714
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07005715 value = command + 9;
5716
5717 /* Convert the value from ascii to integer */
5718 ret = kstrtou8(value, 10, &filterType);
5719 if (ret < 0)
5720 {
5721 /* If the input value is greater than max value of datatype,
5722 * then also kstrtou8 fails
5723 */
5724 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5725 "%s: kstrtou8 failed range ", __func__);
5726 ret = -EINVAL;
5727 goto exit;
5728 }
5729 if ((filterType < WLAN_HDD_DRIVER_MIRACAST_CFG_MIN_VAL ) ||
5730 (filterType > WLAN_HDD_DRIVER_MIRACAST_CFG_MAX_VAL))
5731 {
5732 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5733 "%s: Accepted Values are 0 to 2. 0-Disabled, 1-Source,"
5734 " 2-Sink ", __func__);
5735 ret = -EINVAL;
5736 goto exit;
5737 }
5738 //Filtertype value should be either 0-Disabled, 1-Source, 2-sink
5739 pHddCtx->drvr_miracast = filterType;
Kaushik, Sushant96122442014-10-21 16:40:18 +05305740 pScanInfo = &pHddCtx->scan_info;
5741 if (filterType && pScanInfo != NULL &&
5742 pHddCtx->scan_info.mScanPending)
5743 {
5744 /*Miracast Session started. Abort Scan */
5745 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
5746 "%s, Aborting Scan For Miracast",__func__);
5747 hdd_abort_mac_scan(pHddCtx, pScanInfo->sessionId,
5748 eCSR_SCAN_ABORT_DEFAULT);
5749 }
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07005750 hdd_tx_rx_pkt_cnt_stat_timer_handler(pHddCtx);
Ganesh Kondabattini8f6e3b32014-08-25 16:07:54 +05305751 sme_SetMiracastMode(pHddCtx->hHal, pHddCtx->drvr_miracast);
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07005752 }
Leo Chang614d2072013-08-22 14:59:44 -07005753 else if (strncmp(command, "SETMCRATE", 9) == 0)
5754 {
Leo Chang614d2072013-08-22 14:59:44 -07005755 tANI_U8 *value = command;
5756 int targetRate;
Leo Chang1f98cbd2013-10-17 15:03:52 -07005757 tSirRateUpdateInd *rateUpdate;
5758 eHalStatus status;
Leo Chang614d2072013-08-22 14:59:44 -07005759
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05305760 ret = hdd_drv_cmd_validate(command, 9);
5761 if (ret)
5762 goto exit;
5763
Leo Chang614d2072013-08-22 14:59:44 -07005764 /* Only valid for SAP mode */
5765 if (WLAN_HDD_SOFTAP != pAdapter->device_mode)
5766 {
5767 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5768 "%s: SAP mode is not running", __func__);
5769 ret = -EFAULT;
5770 goto exit;
5771 }
5772
5773 /* Move pointer to ahead of SETMCRATE<delimiter> */
5774 /* input value is in units of hundred kbps */
5775 value = value + 10;
5776 /* Convert the value from ascii to integer, decimal base */
5777 ret = kstrtouint(value, 10, &targetRate);
5778
Leo Chang1f98cbd2013-10-17 15:03:52 -07005779 rateUpdate = (tSirRateUpdateInd *)vos_mem_malloc(sizeof(tSirRateUpdateInd));
5780 if (NULL == rateUpdate)
Leo Chang614d2072013-08-22 14:59:44 -07005781 {
Leo Chang1f98cbd2013-10-17 15:03:52 -07005782 hddLog(VOS_TRACE_LEVEL_ERROR,
5783 "%s: SETMCRATE indication alloc fail", __func__);
5784 ret = -EFAULT;
5785 goto exit;
5786 }
5787 vos_mem_zero(rateUpdate, sizeof(tSirRateUpdateInd ));
5788
5789 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
5790 "MC Target rate %d", targetRate);
5791 /* Ignore unicast */
5792 rateUpdate->ucastDataRate = -1;
5793 rateUpdate->mcastDataRate24GHz = targetRate;
5794 rateUpdate->mcastDataRate5GHz = targetRate;
5795 rateUpdate->mcastDataRate24GHzTxFlag = 0;
5796 rateUpdate->mcastDataRate5GHzTxFlag = 0;
5797 status = sme_SendRateUpdateInd(pHddCtx->hHal, rateUpdate);
5798 if (eHAL_STATUS_SUCCESS != status)
5799 {
5800 hddLog(VOS_TRACE_LEVEL_ERROR,
5801 "%s: SET_MC_RATE failed", __func__);
5802 vos_mem_free(rateUpdate);
5803 ret = -EFAULT;
5804 goto exit;
Leo Chang614d2072013-08-22 14:59:44 -07005805 }
5806 }
jge35567202017-06-21 16:39:38 +08005807 else if (strncmp(command, "MAXTXPOWER", 10) == 0)
5808 {
5809 int status;
5810 int txPower;
5811 eHalStatus smeStatus;
5812 tANI_U8 *value = command;
5813 tSirMacAddr bssid = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
5814 tSirMacAddr selfMac = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
5815
5816 status = hdd_parse_setmaxtxpower_command(value, &txPower);
5817 if (status)
5818 {
5819 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5820 "Invalid MAXTXPOWER command ");
5821 ret = -EINVAL;
5822 goto exit;
5823 }
5824
5825 hddLog(VOS_TRACE_LEVEL_INFO, "max tx power %d selfMac: "
5826 MAC_ADDRESS_STR " bssId: " MAC_ADDRESS_STR " ",
5827 txPower, MAC_ADDR_ARRAY(selfMac),
5828 MAC_ADDR_ARRAY(bssid));
5829 smeStatus = sme_SetMaxTxPower((tHalHandle)(pHddCtx->hHal),
5830 bssid, selfMac, txPower) ;
5831 if( smeStatus != eHAL_STATUS_SUCCESS )
5832 {
5833 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:Set max tx power failed",
5834 __func__);
5835 ret = -EINVAL;
5836 goto exit;
5837 }
5838
5839 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Set max tx power success",
5840 __func__);
5841 }
Rajeev79dbe4c2013-10-05 11:03:42 +05305842#ifdef FEATURE_WLAN_BATCH_SCAN
Rajeev Kumar8b373292014-01-08 20:36:55 -08005843 else if (strncmp(command, "WLS_BATCHING", 12) == 0)
Rajeev79dbe4c2013-10-05 11:03:42 +05305844 {
Rajeev Kumar8b373292014-01-08 20:36:55 -08005845 ret = hdd_handle_batch_scan_ioctl(pAdapter, &priv_data, command);
Rajeev79dbe4c2013-10-05 11:03:42 +05305846 }
5847#endif
Abhishek Singh00b71972016-01-07 10:51:04 +05305848#ifdef WLAN_FEATURE_RMC
5849 else if ((strncasecmp(command, "SETIBSSBEACONOUIDATA", 20) == 0) &&
5850 (WLAN_HDD_IBSS == pAdapter->device_mode))
5851 {
5852 int i = 0;
5853 tANI_U8 *ibss_ie;
5854 tANI_U32 command_len;
5855 tANI_U8 *value = command;
5856 tHalHandle hHal = pHddCtx->hHal;
5857 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
5858 tANI_U32 ibss_ie_length;
5859 tANI_U32 len, present;
5860 tANI_U8 *addIE;
5861 tANI_U8 *addIEData;
5862
5863 hddLog(LOG1,
5864 FL(" received command %s"),((char *) value));
5865 /* validate argument of command */
5866 if (strlen(value) <= 21)
5867 {
5868 hddLog(LOGE,
5869 FL("No arguements in command length %zu"), strlen(value));
5870 ret = -EFAULT;
5871 goto exit;
5872 }
5873
5874 /* moving to arguments of commands */
5875 value = value + 21;
5876 command_len = strlen(value);
5877
5878 /* oui_data can't be less than 3 bytes */
5879 if (command_len <= (2 * WLAN_HDD_IBSS_MIN_OUI_DATA_LENGTH))
5880 {
5881 hddLog(LOGE,
5882 FL("Invalid SETIBSSBEACONOUIDATA command length %d"),
5883 command_len);
5884 ret = -EFAULT;
5885 goto exit;
5886 }
5887 ibss_ie = vos_mem_malloc(command_len);
5888 if (!ibss_ie) {
5889 hddLog(LOGE,
5890 FL("Could not allocate memory for command length %d"),
5891 command_len);
5892 ret = -ENOMEM;
5893 goto exit;
5894 }
5895 vos_mem_zero(ibss_ie, command_len);
5896
5897 ibss_ie_length = hdd_parse_set_ibss_oui_data_command(value, ibss_ie,
5898 command_len);
5899 if (ibss_ie_length < (2 * WLAN_HDD_IBSS_MIN_OUI_DATA_LENGTH)) {
5900 hddLog(LOGE, FL("Could not parse command %s return length %d"),
5901 value, ibss_ie_length);
5902 ret = -EFAULT;
5903 vos_mem_free(ibss_ie);
5904 goto exit;
5905 }
5906
5907 hddLog(LOG1, FL("ibss_ie length %d ibss_ie:"), ibss_ie_length);
5908 while (i < ibss_ie_length)
5909 hddLog(LOG1, FL("0x%x"), ibss_ie[i++]);
5910
5911 /* Populate Vendor IE in Beacon */
5912 if ((ccmCfgGetInt(hHal,
5913 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG,
5914 &present)) != eHAL_STATUS_SUCCESS)
5915 {
5916 hddLog(LOGE,
5917 FL("unable to ftch WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG"));
5918 ret = -EFAULT;
5919 vos_mem_free(ibss_ie);
5920 goto exit;
5921 }
5922
5923 addIE = vos_mem_malloc(WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA_LEN);
5924 if (!addIE) {
5925 hddLog(LOGE,
5926 FL("Could not allocate memory for command length %d"),
5927 command_len);
5928 vos_mem_free(ibss_ie);
5929 ret = -ENOMEM;
5930 goto exit;
5931 }
5932 vos_mem_zero(addIE, WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA_LEN);
5933
5934 if (present)
5935 {
5936 if ((wlan_cfgGetStrLen(pMac,
5937 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, &len)) != eSIR_SUCCESS)
5938 {
5939 hddLog(LOGE,
5940 FL("unable to fetch WNI_CFG_PROBE_RSP_BCN_ADDNIE_LEN"));
5941 ret = -EFAULT;
5942 vos_mem_free(ibss_ie);
5943 vos_mem_free(addIE);
5944 goto exit;
5945 }
5946
5947 if (len <= WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA_LEN && len &&
5948 ((len + ibss_ie_length) <=
5949 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA_LEN))
5950 {
5951 if ((ccmCfgGetStr(hHal,
5952 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, addIE, &len))
5953 != eHAL_STATUS_SUCCESS)
5954 {
5955 hddLog(LOGE,
5956 FL("unable to fetch WNI_PROBE_RSP_BCN_ADDNIE_DATA"));
5957 ret = -EFAULT;
5958 vos_mem_free(ibss_ie);
5959 vos_mem_free(addIE);
5960 goto exit;
5961 }
5962 else
5963 {
5964 /* Curruntly only WPA IE is added before Vendor IE
5965 * so we can blindly place the Vendor IE after WPA
5966 * IE. If no WPA IE found replace all with Vendor IE.
5967 */
5968 len = hdd_find_ibss_wpa_ie_pos(addIE, len);
5969 }
5970 }
5971 else
5972 {
5973 hddLog(LOGE,
5974 FL("IE len exceed limit len %d,ibss_ie_length %d "),
5975 len, ibss_ie_length);
5976 ret = -EFAULT;
5977 vos_mem_free(addIE);
5978 vos_mem_free(ibss_ie);
5979 goto exit;
5980 }
5981 }
5982 else {
5983 len = 0;
5984 }
5985
5986 vos_mem_copy (addIE + len , ibss_ie, ibss_ie_length);
5987 len += ibss_ie_length;
5988
5989 if (ccmCfgSetStr(hHal,
5990 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, addIE, len, NULL,
5991 eANI_BOOLEAN_FALSE) != eHAL_STATUS_SUCCESS)
5992 {
5993 hddLog(LOGE,
5994 FL("unable to set WNI_CFG_PRBE_RSP_BCN_ADDNIE_DATA"));
5995 ret = -EFAULT;
5996 vos_mem_free(ibss_ie);
5997 vos_mem_free(addIE);
5998 goto exit;
5999 }
6000 vos_mem_free(addIE);
6001 if (ccmCfgSetInt(hHal,
6002 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 1,NULL,
6003 eANI_BOOLEAN_FALSE) != eHAL_STATUS_SUCCESS)
6004 {
6005 hddLog(LOGE,
6006 FL("unble to set WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG"));
6007 ret = -EFAULT;
6008 vos_mem_free(ibss_ie);
6009 goto exit;
6010 }
6011
6012 /* Populate Vendor IE in probe resp */
6013 if ((ccmCfgGetInt(hHal,
6014 WNI_CFG_PROBE_RSP_ADDNIE_FLAG,
6015 &present)) != eHAL_STATUS_SUCCESS)
6016 {
6017 hddLog(LOGE,
6018 FL("unable to fetch WNI_CFG_PROBE_RSP_ADDNIE_FLAG"));
6019 ret = -EFAULT;
6020 vos_mem_free(ibss_ie);
6021 goto exit;
6022 }
6023
6024 addIEData = vos_mem_malloc(WNI_CFG_PROBE_RSP_ADDNIE_DATA1_LEN);
6025 if (!addIEData) {
6026 hddLog(LOGE,
6027 FL("Could not allocate memory for command length %d"),
6028 command_len);
6029 vos_mem_free(ibss_ie);
6030 ret = -ENOMEM;
6031 goto exit;
6032 }
6033 vos_mem_zero(addIEData, WNI_CFG_PROBE_RSP_ADDNIE_DATA1_LEN);
6034
6035 if (present) {
6036 if (eSIR_SUCCESS != wlan_cfgGetStrLen(pMac,
6037 WNI_CFG_PROBE_RSP_ADDNIE_DATA1, &len)) {
6038 hddLog(LOGE,
6039 FL("unable to fetch WNI_CFG_PROBE_RSP_ADDNIE_DATA1"));
6040 ret = -EFAULT;
6041 vos_mem_free(ibss_ie);
6042 vos_mem_free(addIEData);
6043 goto exit;
6044 }
6045 if (len < WNI_CFG_PROBE_RSP_ADDNIE_DATA1_LEN && len &&
6046 (ibss_ie_length + len) <=
6047 WNI_CFG_PROBE_RSP_ADDNIE_DATA1_LEN) {
6048
6049 if ((ccmCfgGetStr(hHal,
6050 WNI_CFG_PROBE_RSP_ADDNIE_DATA1, addIEData, &len))
6051 != eHAL_STATUS_SUCCESS) {
6052 hddLog(LOGE,
6053 FL("unable fetch WNI_CFG_PROBE_RSP_ADDNIE_DATA1"));
6054 ret = -EFAULT;
6055 vos_mem_free(ibss_ie);
6056 vos_mem_free(addIEData);
6057 goto exit;
6058 }
6059 else {
6060 /* Curruntly only WPA IE is added before Vendor IE
6061 * so we can blindly place the Vendor IE after WPA
6062 * IE. If no WPA IE found replace all with Vendor IE.
6063 */
6064 len = hdd_find_ibss_wpa_ie_pos(addIEData, len);
6065 }
6066 }
6067 else
6068 {
6069 hddLog(LOGE,
6070 FL("IE len exceed limit len %d,ibss_ie_length %d "),
6071 len, ibss_ie_length);
6072 ret = -EFAULT;
6073 vos_mem_free(addIEData);
6074 vos_mem_free(ibss_ie);
6075 goto exit;
6076 }
6077 } /* probe rsp ADD IE present */
6078 else {
6079 /* probe rsp add IE is not present */
6080 len = 0;
6081 }
6082
6083 vos_mem_copy(addIEData +len , ibss_ie, ibss_ie_length);
6084 len += ibss_ie_length;
6085
6086 vos_mem_free(ibss_ie);
6087
6088 if (ccmCfgSetStr(hHal,
6089 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,
6090 (tANI_U8*)(addIEData),
6091 len, NULL,
6092 eANI_BOOLEAN_FALSE)
6093 == eHAL_STATUS_FAILURE) {
6094 hddLog(LOGE,
6095 FL("unable to copy to WNI_CFG_PROBE_RSP_ADDNIE_DATA1"));
6096 ret = -EFAULT;
6097 vos_mem_free(addIEData);
6098 goto exit;
6099 }
6100 vos_mem_free(addIEData);
6101 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
6102 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 1,NULL,
6103 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
6104 {
6105 hddLog(LOGE,
6106 FL("unable to copy WNI_CFG_PROBE_RSP_ADDNIE_FLAG"));
6107 ret = -EFAULT;
6108 goto exit;
6109 }
6110 }
6111 else if (strncasecmp(command, "SETRMCENABLE", 12) == 0)
6112 {
6113 tANI_U8 *value = command;
6114 tANI_U8 ucRmcEnable = 0;
6115 int status;
6116
6117 if ((WLAN_HDD_IBSS != pAdapter->device_mode) &&
6118 (WLAN_HDD_SOFTAP != pAdapter->device_mode))
6119 {
6120 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6121 "Received SETRMCENABLE command in invalid mode %d "
6122 "SETRMCENABLE command is only allowed in IBSS or SOFTAP mode",
6123 pAdapter->device_mode);
6124 ret = -EINVAL;
6125 goto exit;
6126 }
6127
6128 status = hdd_parse_setrmcenable_command(value, &ucRmcEnable);
6129 if (status)
6130 {
6131 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6132 "Invalid SETRMCENABLE command ");
6133 ret = -EINVAL;
6134 goto exit;
6135 }
6136
6137 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6138 "%s: ucRmcEnable %d ", __func__, ucRmcEnable);
6139
6140 if (TRUE == ucRmcEnable)
6141 {
6142 status = sme_EnableRMC( (tHalHandle)(pHddCtx->hHal),
6143 pAdapter->sessionId );
6144 }
6145 else if(FALSE == ucRmcEnable)
6146 {
6147 status = sme_DisableRMC( (tHalHandle)(pHddCtx->hHal),
6148 pAdapter->sessionId );
6149 }
6150 else
6151 {
6152 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6153 "Invalid SETRMCENABLE command %d", ucRmcEnable);
6154 ret = -EINVAL;
6155 goto exit;
6156 }
6157
6158 if (VOS_STATUS_SUCCESS != status)
6159 {
6160 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6161 "%s: SETRMC %d failed status %d", __func__, ucRmcEnable,
6162 status);
6163 ret = -EINVAL;
6164 goto exit;
6165 }
6166 }
6167 else if (strncasecmp(command, "SETRMCACTIONPERIOD", 18) == 0)
6168 {
6169 tANI_U8 *value = command;
6170 tANI_U32 uActionPeriod = 0;
6171 int status;
6172
6173 if ((WLAN_HDD_IBSS != pAdapter->device_mode) &&
6174 (WLAN_HDD_SOFTAP != pAdapter->device_mode))
6175 {
6176 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6177 "Received SETRMC command in invalid mode %d "
6178 "SETRMC command is only allowed in IBSS or SOFTAP mode",
6179 pAdapter->device_mode);
6180 ret = -EINVAL;
6181 goto exit;
6182 }
6183
6184 status = hdd_parse_setrmcactionperiod_command(value, &uActionPeriod);
6185 if (status)
6186 {
6187 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6188 "Invalid SETRMCACTIONPERIOD command ");
6189 ret = -EINVAL;
6190 goto exit;
6191 }
6192
6193 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6194 "%s: uActionPeriod %d ", __func__, uActionPeriod);
6195
6196 if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_RMC_ACTION_PERIOD_FREQUENCY,
6197 uActionPeriod, NULL, eANI_BOOLEAN_FALSE))
6198 {
6199 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6200 "%s: Could not set SETRMCACTIONPERIOD %d", __func__, uActionPeriod);
6201 ret = -EINVAL;
6202 goto exit;
6203 }
6204
6205 }
6206 else if (strncasecmp(command, "GETIBSSPEERINFOALL", 18) == 0)
6207 {
6208 /* Peer Info All Command */
6209 int status = eHAL_STATUS_SUCCESS;
6210 hdd_station_ctx_t *pHddStaCtx = NULL;
6211 char *extra = NULL;
6212 int idx = 0, length = 0;
6213 v_MACADDR_t *macAddr;
6214 v_U32_t txRateMbps = 0, numOfBytestoPrint = 0;
6215
6216 if (WLAN_HDD_IBSS == pAdapter->device_mode)
6217 {
6218 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
6219 }
6220 else
6221 {
6222 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6223 "%s: pAdapter is not valid for this device mode",
6224 __func__);
6225 ret = -EINVAL;
6226 goto exit;
6227 }
6228
6229 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6230 "%s: Received GETIBSSPEERINFOALL Command", __func__);
6231
6232
6233 /* Handle the command */
6234 status = hdd_cfg80211_get_ibss_peer_info_all(pAdapter);
6235 if (VOS_STATUS_SUCCESS == status)
6236 {
6237 /* The variable extra needed to be allocated on the heap since
6238 * amount of memory required to copy the data for 32 devices
6239 * exceeds the size of 1024 bytes of default stack size. On
6240 * 64 bit devices, the default max stack size of 2048 bytes
6241 */
6242 extra = kmalloc(WLAN_MAX_BUF_SIZE, GFP_KERNEL);
6243
6244 if (NULL == extra)
6245 {
6246 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6247 "%s:kmalloc failed", __func__);
6248 ret = -EINVAL;
6249 goto exit;
6250 }
6251
6252 /* Copy number of stations */
6253 length = scnprintf( extra, WLAN_MAX_BUF_SIZE, "%d ",
6254 pHddStaCtx->ibss_peer_info.numIBSSPeers);
6255 numOfBytestoPrint = length;
6256 for (idx = 0; idx < pHddStaCtx->ibss_peer_info.numIBSSPeers; idx++)
6257 {
6258 macAddr =
6259 hdd_wlan_get_ibss_mac_addr_from_staid(pAdapter,
6260 pHddStaCtx->ibss_peer_info.ibssPeerList[idx].staIdx);
6261 if (NULL != macAddr)
6262 {
6263 txRateMbps =
6264 ((pHddStaCtx->ibss_peer_info.ibssPeerList[idx].txRate)*500*1000)/1000000;
6265
6266 length += scnprintf( (extra + length), WLAN_MAX_BUF_SIZE - length,
6267 "%02x:%02x:%02x:%02x:%02x:%02x %d %d ",
6268 macAddr->bytes[0], macAddr->bytes[1], macAddr->bytes[2],
6269 macAddr->bytes[3], macAddr->bytes[4], macAddr->bytes[5],
6270 (int)txRateMbps,
6271 (int)pHddStaCtx->ibss_peer_info.ibssPeerList[idx].rssi);
6272 }
6273 else
6274 {
6275 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6276 "%s: MAC ADDR is NULL for staIdx: %d", __func__,
6277 pHddStaCtx->ibss_peer_info.ibssPeerList[idx].staIdx);
6278 }
6279
6280 /*
6281 * VOS_TRACE() macro has limitation of 512 bytes for the print
6282 * buffer. Hence printing the data in two chunks. The first chunk
6283 * will have the data for 16 devices and the second chunk will
6284 * have the rest.
6285 */
6286 if (idx < NUM_OF_STA_DATA_TO_PRINT)
6287 {
6288 numOfBytestoPrint = length;
6289 }
6290 }
6291
6292 /*
6293 * Copy the data back into buffer, if the data to copy is
6294 * morethan 512 bytes than we will split the data and do
6295 * it in two shots
6296 */
6297 if (copy_to_user(priv_data.buf, extra, numOfBytestoPrint))
6298 {
6299 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6300 "%s: Copy into user data buffer failed ", __func__);
6301 ret = -EFAULT;
6302 kfree(extra);
6303 goto exit;
6304 }
6305 priv_data.buf[numOfBytestoPrint] = '\0';
6306 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_MED,
6307 "%s", priv_data.buf);
6308
6309 if (length > numOfBytestoPrint)
6310 {
6311 if (copy_to_user(priv_data.buf + numOfBytestoPrint,
6312 extra + numOfBytestoPrint,
6313 length - numOfBytestoPrint + 1))
6314 {
6315 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6316 "%s: Copy into user data buffer failed ", __func__);
6317 ret = -EFAULT;
6318 kfree(extra);
6319 goto exit;
6320 }
6321 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_MED,
6322 "%s", &priv_data.buf[numOfBytestoPrint]);
6323 }
6324
6325 /* Free temporary buffer */
6326 kfree(extra);
6327 }
6328
6329 else
6330 {
6331 /* Command failed, log error */
6332 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6333 "%s: GETIBSSPEERINFOALL command failed with status code %d",
6334 __func__, status);
6335 ret = -EINVAL;
6336 goto exit;
6337 }
6338 ret = 0;
6339 }
6340 else if(strncasecmp(command, "GETIBSSPEERINFO", 15) == 0)
6341 {
6342 /* Peer Info <Peer Addr> command */
6343 tANI_U8 *value = command;
6344 VOS_STATUS status;
6345 hdd_station_ctx_t *pHddStaCtx = NULL;
6346 char extra[128] = { 0 };
6347 v_U32_t length = 0;
6348 v_U8_t staIdx = 0;
6349 v_U32_t txRateMbps = 0;
6350 v_MACADDR_t peerMacAddr;
6351
6352 if (WLAN_HDD_IBSS == pAdapter->device_mode)
6353 {
6354 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
6355 }
6356 else
6357 {
6358 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6359 "%s: pAdapter is not valid for this device mode",
6360 __func__);
6361 ret = -EINVAL;
6362 goto exit;
6363 }
6364
6365 /* if there are no peers, no need to continue with the command */
6366 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6367 "%s: Received GETIBSSPEERINFO Command", __func__);
6368
6369 if (eConnectionState_IbssConnected != pHddStaCtx->conn_info.connState)
6370 {
6371 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6372 "%s:No IBSS Peers coalesced", __func__);
6373 ret = -EINVAL;
6374 goto exit;
6375 }
6376
6377 /* Parse the incoming command buffer */
6378 status = hdd_parse_get_ibss_peer_info(value, &peerMacAddr);
6379 if (VOS_STATUS_SUCCESS != status)
6380 {
6381 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6382 "%s: Invalid GETIBSSPEERINFO command", __func__);
6383 ret = -EINVAL;
6384 goto exit;
6385 }
6386
6387 /* Get station index for the peer mac address */
6388 hdd_Ibss_GetStaId(pHddStaCtx, &peerMacAddr, &staIdx);
6389
6390 if (staIdx > HDD_MAX_NUM_IBSS_STA)
6391 {
6392 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6393 "%s: Invalid StaIdx %d returned", __func__, staIdx);
6394 ret = -EINVAL;
6395 goto exit;
6396 }
6397
6398 /* Handle the command */
6399 status = hdd_cfg80211_get_ibss_peer_info(pAdapter, staIdx);
6400 if (VOS_STATUS_SUCCESS == status)
6401 {
6402 v_U32_t txRate = pHddStaCtx->ibss_peer_info.ibssPeerList[0].txRate;
6403 txRateMbps = (txRate * 500 * 1000)/1000000;
6404
6405 length = scnprintf( extra, sizeof(extra), "%d %d", (int)txRateMbps,
6406 (int)pHddStaCtx->ibss_peer_info.ibssPeerList[0].rssi);
6407
6408 /* Copy the data back into buffer */
6409 if (copy_to_user(priv_data.buf, &extra, length+ 1))
6410 {
6411 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6412 "%s: copy data to user buffer failed GETIBSSPEERINFO command",
6413 __func__);
6414 ret = -EFAULT;
6415 goto exit;
6416 }
6417 }
6418 else
6419 {
6420 /* Command failed, log error */
6421 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6422 "%s: GETIBSSPEERINFO command failed with status code %d",
6423 __func__, status);
6424 ret = -EINVAL;
6425 goto exit;
6426 }
6427
6428 /* Success ! */
6429 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_MED,
6430 "%s", priv_data.buf);
6431 ret = 0;
6432 }
6433 else if (strncasecmp(command, "SETRMCTXRATE", 12) == 0)
6434 {
6435 tANI_U8 *value = command;
6436 tANI_U32 uRate = 0;
6437 tTxrateinfoflags txFlags = 0;
6438 tSirRateUpdateInd *rateUpdateParams;
6439 int status;
6440
6441 if ((WLAN_HDD_IBSS != pAdapter->device_mode) &&
6442 (WLAN_HDD_SOFTAP != pAdapter->device_mode))
6443 {
6444 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6445 "Received SETRMCTXRATE command in invalid mode %d "
6446 "SETRMC command is only allowed in IBSS or SOFTAP mode",
6447 pAdapter->device_mode);
6448 ret = -EINVAL;
6449 goto exit;
6450 }
6451
6452 status = hdd_parse_setrmcrate_command(value, &uRate, &txFlags);
6453 if (status)
6454 {
6455 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6456 "Invalid SETRMCTXRATE command ");
6457 ret = -EINVAL;
6458 goto exit;
6459 }
6460
6461 rateUpdateParams = vos_mem_malloc(sizeof(tSirRateUpdateInd));
6462 if (NULL == rateUpdateParams)
6463 {
6464 ret = -EINVAL;
6465 goto exit;
6466 }
6467
6468 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6469 "%s: uRate %d ", __func__, uRate);
6470
6471 vos_mem_zero(rateUpdateParams, sizeof(tSirRateUpdateInd ));
6472
6473 /* -1 implies ignore this param */
6474 rateUpdateParams->ucastDataRate = -1;
6475
6476 /*
6477 * Fill the user specifieed RMC rate param
6478 * and the derived tx flags.
6479 */
6480 rateUpdateParams->rmcDataRate = uRate;
6481 rateUpdateParams->rmcDataRateTxFlag = txFlags;
6482
6483 status = sme_SendRateUpdateInd((tHalHandle)(pHddCtx->hHal), rateUpdateParams);
6484 }
6485 else if (strncasecmp(command, "SETIBSSTXFAILEVENT", 18) == 0 )
6486 {
6487 char *value;
6488 tANI_U8 tx_fail_count = 0;
6489 tANI_U16 pid = 0;
6490
6491 value = command;
6492
6493 ret = hdd_ParseIBSSTXFailEventParams(value, &tx_fail_count, &pid);
6494
6495 if (0 != ret)
6496 {
6497 hddLog(VOS_TRACE_LEVEL_INFO,
6498 "%s: Failed to parse SETIBSSTXFAILEVENT arguments",
6499 __func__);
6500 goto exit;
6501 }
6502
6503 hddLog(VOS_TRACE_LEVEL_INFO, "%s: tx_fail_cnt=%hhu, pid=%hu",
6504 __func__, tx_fail_count, pid);
6505
6506 if (0 == tx_fail_count)
6507 {
6508 // Disable TX Fail Indication
6509 if (eHAL_STATUS_SUCCESS ==
6510 sme_TXFailMonitorStartStopInd(pHddCtx->hHal,
6511 tx_fail_count,
6512 NULL))
6513 {
6514 cesium_pid = 0;
6515 }
6516 else
6517 {
6518 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6519 "%s: failed to disable TX Fail Event ", __func__);
6520 ret = -EINVAL;
6521 }
6522 }
6523 else
6524 {
6525 if (eHAL_STATUS_SUCCESS ==
6526 sme_TXFailMonitorStartStopInd(pHddCtx->hHal,
6527 tx_fail_count,
6528 (void*)hdd_tx_fail_ind_callback))
6529 {
6530 cesium_pid = pid;
6531 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6532 "%s: Registered Cesium pid %u", __func__,
6533 cesium_pid);
6534 }
6535 else
6536 {
6537 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6538 "%s: Failed to enable TX Fail Monitoring", __func__);
6539 ret = -EINVAL;
6540 }
6541 }
6542 }
6543
6544#endif /* WLAN_FEATURE_RMC */
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08006545#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07006546 else if (strncmp(command, "SETCCXROAMSCANCHANNELS", 22) == 0)
6547 {
6548 tANI_U8 *value = command;
6549 tANI_U8 ChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
6550 tANI_U8 numChannels = 0;
6551 eHalStatus status = eHAL_STATUS_SUCCESS;
6552
6553 status = hdd_parse_channellist(value, ChannelList, &numChannels);
6554 if (eHAL_STATUS_SUCCESS != status)
6555 {
6556 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6557 "%s: Failed to parse channel list information", __func__);
6558 ret = -EINVAL;
6559 goto exit;
6560 }
6561
6562 if (numChannels > WNI_CFG_VALID_CHANNEL_LIST_LEN)
6563 {
6564 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6565 "%s: number of channels (%d) supported exceeded max (%d)", __func__,
6566 numChannels, WNI_CFG_VALID_CHANNEL_LIST_LEN);
6567 ret = -EINVAL;
6568 goto exit;
6569 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08006570 status = sme_SetEseRoamScanChannelList((tHalHandle)(pHddCtx->hHal),
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07006571 ChannelList,
6572 numChannels);
6573 if (eHAL_STATUS_SUCCESS != status)
6574 {
6575 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6576 "%s: Failed to update channel list information", __func__);
6577 ret = -EINVAL;
6578 goto exit;
6579 }
6580 }
6581 else if (strncmp(command, "GETTSMSTATS", 11) == 0)
6582 {
6583 tANI_U8 *value = command;
6584 char extra[128] = {0};
6585 int len = 0;
6586 tANI_U8 tid = 0;
6587 hdd_station_ctx_t *pHddStaCtx = NULL;
6588 tAniTrafStrmMetrics tsmMetrics;
6589 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
6590
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05306591 ret = hdd_drv_cmd_validate(command, 11);
6592 if (ret)
6593 goto exit;
6594
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07006595 /* if not associated, return error */
6596 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
6597 {
6598 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "%s:Not associated!",__func__);
6599 ret = -EINVAL;
6600 goto exit;
6601 }
6602
6603 /* Move pointer to ahead of GETTSMSTATS<delimiter> */
6604 value = value + 12;
6605 /* Convert the value from ascii to integer */
6606 ret = kstrtou8(value, 10, &tid);
6607 if (ret < 0)
6608 {
6609 /* If the input value is greater than max value of datatype, then also
6610 kstrtou8 fails */
6611 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6612 "%s: kstrtou8 failed range [%d - %d]", __func__,
6613 TID_MIN_VALUE,
6614 TID_MAX_VALUE);
6615 ret = -EINVAL;
6616 goto exit;
6617 }
6618
6619 if ((tid < TID_MIN_VALUE) || (tid > TID_MAX_VALUE))
6620 {
6621 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6622 "tid value %d is out of range"
6623 " (Min: %d Max: %d)", tid,
6624 TID_MIN_VALUE,
6625 TID_MAX_VALUE);
6626 ret = -EINVAL;
6627 goto exit;
6628 }
6629
6630 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6631 "%s: Received Command to get tsm stats tid = %d", __func__, tid);
6632
6633 if (VOS_STATUS_SUCCESS != hdd_get_tsm_stats(pAdapter, tid, &tsmMetrics))
6634 {
6635 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6636 "%s: failed to get tsm stats", __func__);
6637 ret = -EFAULT;
6638 goto exit;
6639 }
6640
6641 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6642 "UplinkPktQueueDly(%d)\n"
6643 "UplinkPktQueueDlyHist[0](%d)\n"
6644 "UplinkPktQueueDlyHist[1](%d)\n"
6645 "UplinkPktQueueDlyHist[2](%d)\n"
6646 "UplinkPktQueueDlyHist[3](%d)\n"
Arun Kumar Khandavallie8768212014-02-17 16:43:34 +05306647 "UplinkPktTxDly(%u)\n"
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07006648 "UplinkPktLoss(%d)\n"
6649 "UplinkPktCount(%d)\n"
6650 "RoamingCount(%d)\n"
6651 "RoamingDly(%d)", tsmMetrics.UplinkPktQueueDly,
6652 tsmMetrics.UplinkPktQueueDlyHist[0],
6653 tsmMetrics.UplinkPktQueueDlyHist[1],
6654 tsmMetrics.UplinkPktQueueDlyHist[2],
6655 tsmMetrics.UplinkPktQueueDlyHist[3],
6656 tsmMetrics.UplinkPktTxDly, tsmMetrics.UplinkPktLoss,
6657 tsmMetrics.UplinkPktCount, tsmMetrics.RoamingCount, tsmMetrics.RoamingDly);
6658
6659 /* Output TSM stats is of the format
6660 GETTSMSTATS [PktQueueDly] [PktQueueDlyHist[0]]:[PktQueueDlyHist[1]] ...[RoamingDly]
6661 eg., GETTSMSTATS 10 1:0:0:161 20 1 17 8 39800 */
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08006662 len = scnprintf(extra, sizeof(extra), "%s %d %d:%d:%d:%d %u %d %d %d %d", command,
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07006663 tsmMetrics.UplinkPktQueueDly, tsmMetrics.UplinkPktQueueDlyHist[0],
6664 tsmMetrics.UplinkPktQueueDlyHist[1], tsmMetrics.UplinkPktQueueDlyHist[2],
6665 tsmMetrics.UplinkPktQueueDlyHist[3], tsmMetrics.UplinkPktTxDly,
6666 tsmMetrics.UplinkPktLoss, tsmMetrics.UplinkPktCount, tsmMetrics.RoamingCount,
6667 tsmMetrics.RoamingDly);
6668
Ratnam Rachurid53009c2015-08-07 13:59:00 +05306669 len = VOS_MIN(priv_data.total_len, len + 1);
6670 if (copy_to_user(priv_data.buf, &extra, len)) {
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07006671 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6672 "%s: failed to copy data to user buffer", __func__);
6673 ret = -EFAULT;
6674 goto exit;
6675 }
6676 }
6677 else if (strncmp(command, "SETCCKMIE", 9) == 0)
6678 {
6679 tANI_U8 *value = command;
6680 tANI_U8 *cckmIe = NULL;
6681 tANI_U8 cckmIeLen = 0;
6682 eHalStatus status = eHAL_STATUS_SUCCESS;
6683
6684 status = hdd_parse_get_cckm_ie(value, &cckmIe, &cckmIeLen);
6685 if (eHAL_STATUS_SUCCESS != status)
6686 {
6687 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6688 "%s: Failed to parse cckm ie data", __func__);
6689 ret = -EINVAL;
6690 goto exit;
6691 }
6692
6693 if (cckmIeLen > DOT11F_IE_RSN_MAX_LEN)
6694 {
6695 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6696 "%s: CCKM Ie input length is more than max[%d]", __func__,
6697 DOT11F_IE_RSN_MAX_LEN);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08006698 vos_mem_free(cckmIe);
6699 cckmIe = NULL;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07006700 ret = -EINVAL;
6701 goto exit;
6702 }
6703 sme_SetCCKMIe((tHalHandle)(pHddCtx->hHal), pAdapter->sessionId, cckmIe, cckmIeLen);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08006704 vos_mem_free(cckmIe);
6705 cckmIe = NULL;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07006706 }
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08006707 else if (strncmp(command, "CCXBEACONREQ", 12) == 0)
6708 {
6709 tANI_U8 *value = command;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08006710 tCsrEseBeaconReq eseBcnReq;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08006711 eHalStatus status = eHAL_STATUS_SUCCESS;
Srinivas Girigowda0c6d7fe2014-05-28 18:18:10 -07006712
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08006713 status = hdd_parse_ese_beacon_req(value, &eseBcnReq);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08006714 if (eHAL_STATUS_SUCCESS != status)
6715 {
6716 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08006717 "%s: Failed to parse ese beacon req", __func__);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08006718 ret = -EINVAL;
6719 goto exit;
6720 }
Srinivas Girigowda0c6d7fe2014-05-28 18:18:10 -07006721 if (!hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))) {
6722 hddLog(VOS_TRACE_LEVEL_INFO, FL("Not associated"));
6723 hdd_indicateEseBcnReportNoResults (pAdapter,
6724 eseBcnReq.bcnReq[0].measurementToken,
6725 0x02, //BIT(1) set for measurement done
6726 0); // no BSS
6727 goto exit;
6728 }
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08006729
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08006730 status = sme_SetEseBeaconRequest((tHalHandle)(pHddCtx->hHal), pAdapter->sessionId, &eseBcnReq);
6731 if (eHAL_STATUS_SUCCESS != status)
6732 {
6733 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6734 "%s: sme_SetEseBeaconRequest failed (%d)", __func__, status);
6735 ret = -EINVAL;
6736 goto exit;
6737 }
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08006738 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08006739#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
c_hpothu92367912014-05-01 15:18:17 +05306740 else if (strncmp(command, "GETBCNMISSRATE", 14) == 0)
6741 {
6742 eHalStatus status;
6743 char buf[32], len;
Hanumanth Reddy Pothula7aa4bea2018-04-09 17:19:03 +05306744 void *cookie;
6745 struct hdd_request *request;
6746 struct bcn_miss_rate_priv *priv;
6747 static const struct hdd_request_params params = {
6748 .priv_size = sizeof(*priv),
6749 .timeout_ms = WLAN_WAIT_TIME_STATS,
6750 };
c_hpothu92367912014-05-01 15:18:17 +05306751
6752 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
6753
6754 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
6755 {
6756 hddLog(VOS_TRACE_LEVEL_WARN,
6757 FL("GETBCNMISSRATE: STA is not in connected state"));
6758 ret = -1;
6759 goto exit;
6760 }
Hanumanth Reddy Pothula7aa4bea2018-04-09 17:19:03 +05306761 request = hdd_request_alloc(&params);
6762 if (!request) {
6763 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Request allocation failure"));
6764 ret = -ENOMEM;
6765 goto exit;
6766 }
6767 cookie = hdd_request_cookie(request);
6768 priv = hdd_request_priv(request);
6769 priv->bcn_miss_rate = -1;
c_hpothu92367912014-05-01 15:18:17 +05306770
6771 status = sme_getBcnMissRate((tHalHandle)(pHddCtx->hHal),
6772 pAdapter->sessionId,
Hanumanth Reddy Pothula7aa4bea2018-04-09 17:19:03 +05306773 (void *)get_bcn_miss_rate_cb,
6774 cookie);
c_hpothu92367912014-05-01 15:18:17 +05306775 if( eHAL_STATUS_SUCCESS != status)
6776 {
6777 hddLog(VOS_TRACE_LEVEL_INFO,
6778 FL("GETBCNMISSRATE: fail to post WDA cmd"));
6779 ret = -EINVAL;
Hanumanth Reddy Pothula7aa4bea2018-04-09 17:19:03 +05306780 goto free_bcn_miss_rate_req;
c_hpothu92367912014-05-01 15:18:17 +05306781 }
6782
Hanumanth Reddy Pothula7aa4bea2018-04-09 17:19:03 +05306783 ret = hdd_request_wait_for_response(request);
6784 if(ret)
c_hpothu92367912014-05-01 15:18:17 +05306785 {
6786 hddLog(VOS_TRACE_LEVEL_ERROR,
6787 FL("failed to wait on bcnMissRateComp %d"), ret);
6788
c_hpothu92367912014-05-01 15:18:17 +05306789 ret = -EINVAL;
Hanumanth Reddy Pothula7aa4bea2018-04-09 17:19:03 +05306790 goto free_bcn_miss_rate_req;
c_hpothu92367912014-05-01 15:18:17 +05306791 }
6792
6793 hddLog(VOS_TRACE_LEVEL_INFO,
Hanumanth Reddy Pothula7aa4bea2018-04-09 17:19:03 +05306794 FL("GETBCNMISSRATE: bcnMissRate: %d"), priv->bcn_miss_rate);
c_hpothu92367912014-05-01 15:18:17 +05306795
Hanumanth Reddy Pothula7aa4bea2018-04-09 17:19:03 +05306796 if (priv->bcn_miss_rate == -1) {
6797 ret = -EFAULT;
6798 goto free_bcn_miss_rate_req;
6799 }
6800
6801 len = snprintf(buf, sizeof(buf), "GETBCNMISSRATE %d",
6802 priv->bcn_miss_rate);
c_hpothu92367912014-05-01 15:18:17 +05306803 if (copy_to_user(priv_data.buf, &buf, len + 1))
6804 {
6805 hddLog(VOS_TRACE_LEVEL_ERROR,
6806 "%s: failed to copy data to user buffer", __func__);
6807 ret = -EFAULT;
Hanumanth Reddy Pothula7aa4bea2018-04-09 17:19:03 +05306808 goto free_bcn_miss_rate_req;
c_hpothu92367912014-05-01 15:18:17 +05306809 }
6810 ret = len;
Hanumanth Reddy Pothula7aa4bea2018-04-09 17:19:03 +05306811
6812free_bcn_miss_rate_req:
6813 hdd_request_put(request);
c_hpothu92367912014-05-01 15:18:17 +05306814 }
Atul Mittal87ec2422014-09-24 13:12:50 +05306815#ifdef FEATURE_WLAN_TDLS
6816 else if (strncmp(command, "TDLSSECONDARYCHANNELOFFSET", 26) == 0) {
6817 tANI_U8 *value = command;
6818 int set_value;
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05306819
6820 ret = hdd_drv_cmd_validate(command, 26);
6821 if (ret)
6822 goto exit;
6823
Atul Mittal87ec2422014-09-24 13:12:50 +05306824 /* Move pointer to ahead of TDLSOFFCH*/
6825 value += 26;
c_manjeebbc40212015-12-08 13:52:59 +05306826 if (!(sscanf(value, "%d", &set_value))) {
6827 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6828 FL("No input identified"));
6829 ret = -EINVAL;
6830 goto exit;
6831 }
6832
Atul Mittal87ec2422014-09-24 13:12:50 +05306833 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6834 "%s: Tdls offchannel offset:%d",
6835 __func__, set_value);
6836 ret = iw_set_tdlssecoffchanneloffset(pHddCtx, set_value);
6837 if (ret < 0)
6838 {
6839 ret = -EINVAL;
6840 goto exit;
6841 }
6842
6843 } else if (strncmp(command, "TDLSOFFCHANNELMODE", 18) == 0) {
6844 tANI_U8 *value = command;
6845 int set_value;
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05306846
6847 ret = hdd_drv_cmd_validate(command, 18);
6848 if (ret)
6849 goto exit;
6850
Atul Mittal87ec2422014-09-24 13:12:50 +05306851 /* Move pointer to ahead of tdlsoffchnmode*/
6852 value += 18;
c_manjee82323892015-12-08 12:40:34 +05306853 ret = sscanf(value, "%d", &set_value);
6854 if (ret != 1) {
6855 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6856 FL("No input identified"));
6857 ret = -EINVAL;
6858 goto exit;
6859 }
Atul Mittal87ec2422014-09-24 13:12:50 +05306860 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6861 "%s: Tdls offchannel mode:%d",
6862 __func__, set_value);
6863 ret = iw_set_tdlsoffchannelmode(pAdapter, set_value);
6864 if (ret < 0)
6865 {
6866 ret = -EINVAL;
6867 goto exit;
6868 }
6869 } else if (strncmp(command, "TDLSOFFCHANNEL", 14) == 0) {
6870 tANI_U8 *value = command;
6871 int set_value;
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05306872
6873 ret = hdd_drv_cmd_validate(command, 14);
6874 if (ret)
6875 goto exit;
6876
Atul Mittal87ec2422014-09-24 13:12:50 +05306877 /* Move pointer to ahead of TDLSOFFCH*/
6878 value += 14;
c_manjeef6ccaf52015-12-08 11:52:11 +05306879 ret = sscanf(value, "%d", &set_value);
6880 if (ret != 1) {
6881 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6882 "Wrong value is given for hdd_set_tdls_offchannel");
6883 ret = -EINVAL;
6884 goto exit;
6885 }
6886
Atul Mittal87ec2422014-09-24 13:12:50 +05306887 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6888 "%s: Tdls offchannel num: %d",
6889 __func__, set_value);
6890 ret = iw_set_tdlsoffchannel(pHddCtx, set_value);
6891 if (ret < 0)
6892 {
6893 ret = -EINVAL;
6894 goto exit;
6895 }
6896 }
6897#endif
Satyanarayana Dash72806012014-12-02 14:30:08 +05306898 else if (strncmp(command, "GETFWSTATS", 10) == 0)
6899 {
6900 eHalStatus status;
6901 char *buf = NULL;
6902 char len;
Hanumanth Reddy Pothula7aa4bea2018-04-09 17:19:03 +05306903 tSirFwStatsResult *fwStatsRsp = &(pAdapter->fwStatsRsp),
6904 *fw_stats_result;
Satyanarayana Dash72806012014-12-02 14:30:08 +05306905 tANI_U8 *ptr = command;
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05306906 int stats;
Hanumanth Reddy Pothula7aa4bea2018-04-09 17:19:03 +05306907 void *cookie;
6908 struct hdd_request *request;
6909 struct fw_stats_priv *priv;
6910 static const struct hdd_request_params params = {
6911 .priv_size = sizeof(*priv),
6912 .timeout_ms = WLAN_WAIT_TIME_STATS,
6913 };
Satyanarayana Dash72806012014-12-02 14:30:08 +05306914
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05306915 ret = hdd_drv_cmd_validate(command, 10);
6916 if (ret)
6917 goto exit;
6918
6919 stats = *(ptr + 11) - '0';
Satyanarayana Dash72806012014-12-02 14:30:08 +05306920 hddLog(VOS_TRACE_LEVEL_INFO, FL("stats = %d "),stats);
6921 if (!IS_FEATURE_FW_STATS_ENABLE)
6922 {
6923 hddLog(VOS_TRACE_LEVEL_INFO,
6924 FL("Get Firmware stats feature not supported"));
6925 ret = -EINVAL;
6926 goto exit;
6927 }
6928
6929 if (FW_STATS_MAX <= stats || 0 >= stats)
6930 {
6931 hddLog(VOS_TRACE_LEVEL_INFO,
6932 FL(" stats %d not supported"),stats);
6933 ret = -EINVAL;
6934 goto exit;
6935 }
6936
Hanumanth Reddy Pothula7aa4bea2018-04-09 17:19:03 +05306937 request = hdd_request_alloc(&params);
6938 if (!request) {
6939 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Request allocation failure"));
6940 ret = -ENOMEM;
6941 goto exit;
6942 }
6943 cookie = hdd_request_cookie(request);
6944
Satyanarayana Dash72806012014-12-02 14:30:08 +05306945 status = sme_GetFwStats( (tHalHandle)pHddCtx->hHal, stats,
Hanumanth Reddy Pothula7aa4bea2018-04-09 17:19:03 +05306946 cookie, hdd_fw_stats_cb);
Satyanarayana Dash72806012014-12-02 14:30:08 +05306947 if (eHAL_STATUS_SUCCESS != status)
6948 {
6949 hddLog(VOS_TRACE_LEVEL_ERROR,
6950 FL(" fail to post WDA cmd status = %d"), status);
6951 ret = -EINVAL;
Hanumanth Reddy Pothula7aa4bea2018-04-09 17:19:03 +05306952 hdd_request_put(request);
Satyanarayana Dash72806012014-12-02 14:30:08 +05306953 goto exit;
6954 }
Hanumanth Reddy Pothula7aa4bea2018-04-09 17:19:03 +05306955 ret = hdd_request_wait_for_response(request);
6956 if (ret)
Satyanarayana Dash72806012014-12-02 14:30:08 +05306957 {
6958 hddLog(VOS_TRACE_LEVEL_ERROR,
6959 FL("failed to wait on GwtFwstats"));
Satyanarayana Dash72806012014-12-02 14:30:08 +05306960 ret = -EINVAL;
Hanumanth Reddy Pothula7aa4bea2018-04-09 17:19:03 +05306961 hdd_request_put(request);
Satyanarayana Dash72806012014-12-02 14:30:08 +05306962 goto exit;
6963 }
Hanumanth Reddy Pothula7aa4bea2018-04-09 17:19:03 +05306964
6965 priv = hdd_request_priv(request);
6966 fw_stats_result = priv->fw_stats;
6967 fwStatsRsp->type = 0;
6968 if (NULL != fw_stats_result)
6969 {
6970 switch (fw_stats_result->type )
6971 {
6972 case FW_UBSP_STATS:
6973 {
6974 tSirUbspFwStats *stats =
6975 &fwStatsRsp->fwStatsData.ubspStats;
6976 memcpy(fwStatsRsp, fw_stats_result,
6977 sizeof(tSirFwStatsResult));
6978 hddLog(VOS_TRACE_LEVEL_INFO,
6979 FL("ubsp_enter_cnt = %d ubsp_jump_ddr_cnt = %d"),
6980 stats->ubsp_enter_cnt,
6981 stats->ubsp_jump_ddr_cnt);
6982 }
6983 break;
6984
6985 default:
6986 {
6987 hddLog(VOS_TRACE_LEVEL_ERROR,
6988 FL("No handling for stats type %d"),
6989 fw_stats_result->type);
6990 }
6991 }
6992 }
6993 hdd_request_put(request);
6994
Satyanarayana Dash72806012014-12-02 14:30:08 +05306995 if (fwStatsRsp->type)
6996 {
6997 buf = kmalloc(FW_STATE_RSP_LEN, GFP_KERNEL);
6998 if (!buf)
6999 {
7000 hddLog(VOS_TRACE_LEVEL_ERROR,
7001 FL(" failed to allocate memory"));
7002 ret = -ENOMEM;
7003 goto exit;
7004 }
7005 switch( fwStatsRsp->type )
7006 {
7007 case FW_UBSP_STATS:
7008 {
7009 len = snprintf(buf, FW_STATE_RSP_LEN,
7010 "GETFWSTATS: ubsp_enter_cnt %d ubsp_jump_ddr_cnt %d",
Abhishek Singh08aa7762014-12-16 13:59:03 +05307011 fwStatsRsp->fwStatsData.ubspStats.ubsp_enter_cnt,
7012 fwStatsRsp->fwStatsData.ubspStats.ubsp_jump_ddr_cnt);
Satyanarayana Dash72806012014-12-02 14:30:08 +05307013 }
7014 break;
7015 default:
7016 {
7017 hddLog(VOS_TRACE_LEVEL_ERROR, FL( "No handling for stats type %d"),fwStatsRsp->type);
7018 ret = -EFAULT;
7019 kfree(buf);
7020 goto exit;
7021 }
7022 }
7023 if (copy_to_user(priv_data.buf, buf, len + 1))
7024 {
7025 hddLog(VOS_TRACE_LEVEL_ERROR,
7026 FL(" failed to copy data to user buffer"));
7027 ret = -EFAULT;
7028 kfree(buf);
7029 goto exit;
7030 }
7031 ret = len;
7032 kfree(buf);
7033 }
7034 else
7035 {
7036 hddLog(VOS_TRACE_LEVEL_ERROR,
7037 FL("failed to fetch the stats"));
7038 ret = -EFAULT;
7039 goto exit;
7040 }
Satyanarayana Dash72806012014-12-02 14:30:08 +05307041 }
Agarwal Ashish8bd53ae2015-06-12 18:03:45 +05307042 else if (strncasecmp(command, "SET_FCC_CHANNEL", 15) == 0)
7043 {
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05307044 ret = hdd_drv_cmd_validate(command, 15);
7045 if (ret)
7046 goto exit;
7047
Agarwal Ashish8bd53ae2015-06-12 18:03:45 +05307048 /*
7049 * this command wld be called by user-space when it detects WLAN
7050 * ON after airplane mode is set. When APM is set, WLAN turns off.
7051 * But it can be turned back on. Otherwise; when APM is turned back
7052 * off, WLAN wld turn back on. So at that point the command is
7053 * expected to come down. 0 means disable, 1 means enable. The
7054 * constraint is removed when parameter 1 is set or different
7055 * country code is set
7056 */
7057 ret = hdd_cmd_setFccChannel(pHddCtx, command, 15);
7058 }
Mahesh A Saptasagarbeca12c2015-09-07 16:21:06 +05307059 else if (strncasecmp(command, "DISABLE_CA_EVENT", 16) == 0)
7060 {
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05307061 ret = hdd_drv_cmd_validate(command, 16);
7062 if (ret)
7063 goto exit;
7064
Mahesh A Saptasagarbeca12c2015-09-07 16:21:06 +05307065 ret = hdd_enable_disable_ca_event(pHddCtx, command, 16);
7066 }
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +05307067 /*
7068 * command should be a string having format
7069 * SET_DISABLE_CHANNEL_LIST <num of channels>
7070 * <channels separated by spaces>
7071 */
7072 else if (strncmp(command, "SET_DISABLE_CHANNEL_LIST", 24) == 0) {
7073 tANI_U8 *ptr = command;
7074 ret = hdd_drv_cmd_validate(command, 24);
7075 if (ret)
7076 goto exit;
7077
7078 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
7079 " Received Command to disable Channels %s",
7080 __func__);
7081 ret = hdd_parse_disable_chan_cmd(pAdapter, ptr);
7082 if (ret)
7083 goto exit;
7084 }
Hanumanth Reddy Pothula8ae38bb2018-03-07 18:59:30 +05307085 else if (strncmp(command, "GET_DISABLE_CHANNEL_LIST", 24) == 0) {
Ashish Kumar Dhanotiya95e5bc22018-04-19 17:06:33 +05307086 char extra[512] = {0};
7087 int max_len, copied_length;
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +05307088
Ashish Kumar Dhanotiya95e5bc22018-04-19 17:06:33 +05307089 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Hanumanth Reddy Pothula8ae38bb2018-03-07 18:59:30 +05307090 " Received Command to get disable Channels list %s",
7091 __func__);
7092
Ashish Kumar Dhanotiya95e5bc22018-04-19 17:06:33 +05307093 max_len = VOS_MIN(priv_data.total_len, sizeof(extra));
7094 copied_length = hdd_get_disable_ch_list(pHddCtx, extra, max_len);
7095 if (copied_length == 0) {
7096 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Hanumanth Reddy Pothula8ae38bb2018-03-07 18:59:30 +05307097 FL("disable channel list are not yet programed"));
7098 ret = -EINVAL;
7099 goto exit;
7100 }
7101
Ashish Kumar Dhanotiya95e5bc22018-04-19 17:06:33 +05307102 if (copy_to_user(priv_data.buf, &extra, copied_length + 1)) {
7103 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7104 "%s: failed to copy data to user buffer", __func__);
Hanumanth Reddy Pothula8ae38bb2018-03-07 18:59:30 +05307105 ret = -EFAULT;
7106 goto exit;
7107 }
7108
7109 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
7110 FL("data:%s"), extra);
7111 }
Madan Mohan Koyyalamudif9bdd4e2012-10-30 18:05:03 -07007112 else {
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307113 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
7114 TRACE_CODE_HDD_UNSUPPORTED_IOCTL,
7115 pAdapter->sessionId, 0));
Satyanarayana Dash72806012014-12-02 14:30:08 +05307116 hddLog( VOS_TRACE_LEVEL_WARN, FL("Unsupported GUI command %s"),
7117 command);
Madan Mohan Koyyalamudif9bdd4e2012-10-30 18:05:03 -07007118 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007119 }
7120exit:
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05307121 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07007122 if (command)
7123 {
7124 kfree(command);
7125 }
7126 return ret;
7127}
7128
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07007129#ifdef CONFIG_COMPAT
7130static int hdd_driver_compat_ioctl(hdd_adapter_t *pAdapter, struct ifreq *ifr)
7131{
7132 struct {
7133 compat_uptr_t buf;
7134 int used_len;
7135 int total_len;
7136 } compat_priv_data;
7137 hdd_priv_data_t priv_data;
7138 int ret = 0;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07007139
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07007140 /*
7141 * Note that pAdapter and ifr have already been verified by caller,
7142 * and HDD context has also been validated
7143 */
7144 if (copy_from_user(&compat_priv_data, ifr->ifr_data,
7145 sizeof(compat_priv_data))) {
7146 ret = -EFAULT;
7147 goto exit;
7148 }
7149 priv_data.buf = compat_ptr(compat_priv_data.buf);
7150 priv_data.used_len = compat_priv_data.used_len;
7151 priv_data.total_len = compat_priv_data.total_len;
7152 ret = hdd_driver_command(pAdapter, &priv_data);
7153 exit:
7154 return ret;
7155}
7156#else /* CONFIG_COMPAT */
7157static int hdd_driver_compat_ioctl(hdd_adapter_t *pAdapter, struct ifreq *ifr)
7158{
7159 /* will never be invoked */
7160 return 0;
7161}
7162#endif /* CONFIG_COMPAT */
7163
7164static int hdd_driver_ioctl(hdd_adapter_t *pAdapter, struct ifreq *ifr)
7165{
7166 hdd_priv_data_t priv_data;
7167 int ret = 0;
7168
7169 /*
7170 * Note that pAdapter and ifr have already been verified by caller,
7171 * and HDD context has also been validated
7172 */
7173 if (copy_from_user(&priv_data, ifr->ifr_data, sizeof(priv_data))) {
7174 ret = -EFAULT;
7175 } else {
7176 ret = hdd_driver_command(pAdapter, &priv_data);
7177 }
7178 return ret;
7179}
7180
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05307181int __hdd_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07007182{
7183 hdd_adapter_t *pAdapter;
7184 hdd_context_t *pHddCtx;
7185 int ret;
7186
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05307187 ENTER();
7188
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07007189 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
7190 if (NULL == pAdapter) {
7191 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
7192 "%s: HDD adapter context is Null", __func__);
7193 ret = -ENODEV;
7194 goto exit;
7195 }
7196 if (dev != pAdapter->dev) {
7197 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
7198 "%s: HDD adapter/dev inconsistency", __func__);
7199 ret = -ENODEV;
7200 goto exit;
7201 }
7202
7203 if ((!ifr) || (!ifr->ifr_data)) {
7204 ret = -EINVAL;
7205 goto exit;
7206 }
7207
7208 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7209 ret = wlan_hdd_validate_context(pHddCtx);
7210 if (ret) {
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07007211 ret = -EBUSY;
7212 goto exit;
7213 }
7214
7215 switch (cmd) {
7216 case (SIOCDEVPRIVATE + 1):
7217 if (is_compat_task())
7218 ret = hdd_driver_compat_ioctl(pAdapter, ifr);
7219 else
7220 ret = hdd_driver_ioctl(pAdapter, ifr);
7221 break;
7222 default:
7223 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unknown ioctl %d",
7224 __func__, cmd);
7225 ret = -EINVAL;
7226 break;
7227 }
7228 exit:
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05307229 EXIT();
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07007230 return ret;
7231}
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07007232
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05307233int hdd_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
7234{
7235 int ret;
7236
7237 vos_ssr_protect(__func__);
7238 ret = __hdd_ioctl(dev, ifr, cmd);
7239 vos_ssr_unprotect(__func__);
7240
7241 return ret;
7242}
7243
Katya Nigame7b69a82015-04-28 15:24:06 +05307244int hdd_mon_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
7245{
7246 return 0;
7247}
7248
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08007249#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08007250/**---------------------------------------------------------------------------
7251
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08007252 \brief hdd_parse_ese_beacon_req() - Parse ese beacon request
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08007253
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08007254 This function parses the ese beacon request passed in the format
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08007255 CCXBEACONREQ<space><Number of fields><space><Measurement token>
7256 <space>Channel 1<space>Scan Mode <space>Meas Duration<space>Channel N
7257 <space>Scan Mode N<space>Meas Duration N
7258 if the Number of bcn req fields (N) does not match with the actual number of fields passed
7259 then take N.
7260 <Meas Token><Channel><Scan Mode> and <Meas Duration> are treated as one pair
7261 For example, CCXBEACONREQ 2 1 1 1 30 2 44 0 40.
7262 This function does not take care of removing duplicate channels from the list
7263
7264 \param - pValue Pointer to data
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08007265 \param - pEseBcnReq output pointer to store parsed ie information
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08007266
7267 \return - 0 for success non-zero for failure
7268
7269 --------------------------------------------------------------------------*/
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08007270static VOS_STATUS hdd_parse_ese_beacon_req(tANI_U8 *pValue,
7271 tCsrEseBeaconReq *pEseBcnReq)
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08007272{
7273 tANI_U8 *inPtr = pValue;
Arun Khandavalli9f3b4832016-06-30 16:58:38 +05307274 uint8_t input = 0;
7275 uint32_t tempInt = 0;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08007276 int j = 0, i = 0, v = 0;
7277 char buf[32];
7278
7279 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
7280 /*no argument after the command*/
7281 if (NULL == inPtr)
7282 {
7283 return -EINVAL;
7284 }
7285 /*no space after the command*/
7286 else if (SPACE_ASCII_VALUE != *inPtr)
7287 {
7288 return -EINVAL;
7289 }
7290
7291 /*removing empty spaces*/
7292 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
7293
7294 /*no argument followed by spaces*/
7295 if ('\0' == *inPtr) return -EINVAL;
7296
7297 /*getting the first argument ie measurement token*/
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08007298 v = sscanf(inPtr, "%31s ", buf);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08007299 if (1 != v) return -EINVAL;
7300
Arun Khandavalli9f3b4832016-06-30 16:58:38 +05307301 v = kstrtos8(buf, 10, &input);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08007302 if ( v < 0) return -EINVAL;
7303
Arun Khandavalli9f3b4832016-06-30 16:58:38 +05307304 input = VOS_MIN(input, SIR_ESE_MAX_MEAS_IE_REQS);
7305 pEseBcnReq->numBcnReqIe = input;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08007306
Srinivas Girigowda725a88e2016-03-31 19:24:25 +05307307 hddLog(LOG1, "Number of Bcn Req Ie fields: %d", pEseBcnReq->numBcnReqIe);
7308
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08007309
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08007310 for (j = 0; j < (pEseBcnReq->numBcnReqIe); j++)
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08007311 {
7312 for (i = 0; i < 4; i++)
7313 {
7314 /*inPtr pointing to the beginning of first space after number of ie fields*/
7315 inPtr = strpbrk( inPtr, " " );
7316 /*no ie data after the number of ie fields argument*/
7317 if (NULL == inPtr) return -EINVAL;
7318
7319 /*removing empty space*/
7320 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
7321
7322 /*no ie data after the number of ie fields argument and spaces*/
7323 if ( '\0' == *inPtr ) return -EINVAL;
7324
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08007325 v = sscanf(inPtr, "%31s ", buf);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08007326 if (1 != v) return -EINVAL;
7327
Arun Khandavalli9f3b4832016-06-30 16:58:38 +05307328 v = kstrtou32(buf, 10, &tempInt);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08007329 if (v < 0) return -EINVAL;
7330
7331 switch (i)
7332 {
7333 case 0: /* Measurement token */
Arun Khandavalli9f3b4832016-06-30 16:58:38 +05307334 if (!tempInt)
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08007335 {
7336 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arun Khandavalli9f3b4832016-06-30 16:58:38 +05307337 "Invalid Measurement Token: %u", tempInt);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08007338 return -EINVAL;
7339 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08007340 pEseBcnReq->bcnReq[j].measurementToken = tempInt;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08007341 break;
7342
7343 case 1: /* Channel number */
Arun Khandavalli9f3b4832016-06-30 16:58:38 +05307344 if ((!tempInt) ||
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08007345 (tempInt > WNI_CFG_CURRENT_CHANNEL_STAMAX))
7346 {
7347 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arun Khandavalli9f3b4832016-06-30 16:58:38 +05307348 "Invalid Channel Number: %u", tempInt);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08007349 return -EINVAL;
7350 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08007351 pEseBcnReq->bcnReq[j].channel = tempInt;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08007352 break;
7353
7354 case 2: /* Scan mode */
Varun Reddy Yeturu0b18d5a2013-12-04 11:42:23 -08007355 if ((tempInt < eSIR_PASSIVE_SCAN) || (tempInt > eSIR_BEACON_TABLE))
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08007356 {
7357 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arun Khandavalli9f3b4832016-06-30 16:58:38 +05307358 "Invalid Scan Mode(%u) Expected{0|1|2}", tempInt);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08007359 return -EINVAL;
7360 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08007361 pEseBcnReq->bcnReq[j].scanMode= tempInt;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08007362 break;
7363
7364 case 3: /* Measurement duration */
Arun Khandavalli9f3b4832016-06-30 16:58:38 +05307365 if (((!tempInt) && (pEseBcnReq->bcnReq[j].scanMode != eSIR_BEACON_TABLE)) ||
7366 ((pEseBcnReq->bcnReq[j].scanMode == eSIR_BEACON_TABLE)))
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08007367 {
7368 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arun Khandavalli9f3b4832016-06-30 16:58:38 +05307369 "Invalid Measurement Duration: %u", tempInt);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08007370 return -EINVAL;
7371 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08007372 pEseBcnReq->bcnReq[j].measurementDuration = tempInt;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08007373 break;
7374 }
7375 }
7376 }
7377
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08007378 for (j = 0; j < pEseBcnReq->numBcnReqIe; j++)
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08007379 {
7380 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Arun Kumar Khandavallie8768212014-02-17 16:43:34 +05307381 "Index(%d) Measurement Token(%u)Channel(%u) Scan Mode(%u) Measurement Duration(%u)\n",
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08007382 j,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08007383 pEseBcnReq->bcnReq[j].measurementToken,
7384 pEseBcnReq->bcnReq[j].channel,
7385 pEseBcnReq->bcnReq[j].scanMode,
7386 pEseBcnReq->bcnReq[j].measurementDuration);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08007387 }
7388
7389 return VOS_STATUS_SUCCESS;
7390}
7391
Hanumanth Reddy Pothula1ceb7032018-04-05 19:35:55 +05307392struct tsm_priv {
7393 tAniTrafStrmMetrics tsm_metrics;
7394};
7395
7396static void hdd_get_tsm_stats_cb(tAniTrafStrmMetrics tsm_metrics,
7397 const tANI_U32 sta_id, void *context )
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07007398{
Hanumanth Reddy Pothula1ceb7032018-04-05 19:35:55 +05307399 struct hdd_request *request;
7400 struct tsm_priv *priv;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07007401
Hanumanth Reddy Pothula1ceb7032018-04-05 19:35:55 +05307402 ENTER();
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07007403
Hanumanth Reddy Pothula1ceb7032018-04-05 19:35:55 +05307404 request = hdd_request_get(context);
7405 if (!request) {
7406 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Obsolete request"));
7407 return;
7408 }
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07007409
Hanumanth Reddy Pothula1ceb7032018-04-05 19:35:55 +05307410 priv = hdd_request_priv(request);
7411 priv->tsm_metrics = tsm_metrics;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07007412
Hanumanth Reddy Pothula1ceb7032018-04-05 19:35:55 +05307413 hdd_request_complete(request);
7414 hdd_request_put(request);
Jeff Johnson72a40512013-12-19 10:14:15 -08007415
Hanumanth Reddy Pothula1ceb7032018-04-05 19:35:55 +05307416 EXIT();
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07007417}
7418
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07007419static VOS_STATUS hdd_get_tsm_stats(hdd_adapter_t *pAdapter, const tANI_U8 tid,
7420 tAniTrafStrmMetrics* pTsmMetrics)
7421{
7422 hdd_station_ctx_t *pHddStaCtx = NULL;
7423 eHalStatus hstatus;
Jeff Johnson72a40512013-12-19 10:14:15 -08007424 VOS_STATUS vstatus = VOS_STATUS_SUCCESS;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07007425 hdd_context_t *pHddCtx = NULL;
Hanumanth Reddy Pothula1ceb7032018-04-05 19:35:55 +05307426 int ret;
7427 void *cookie;
7428 struct hdd_request *request;
7429 struct tsm_priv *priv;
7430 static const struct hdd_request_params params = {
7431 .priv_size = sizeof(*priv),
7432 .timeout_ms = WLAN_WAIT_TIME_STATS,
7433 };
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07007434
7435 if (NULL == pAdapter)
7436 {
7437 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: pAdapter is NULL", __func__);
7438 return VOS_STATUS_E_FAULT;
7439 }
7440
7441 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7442 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7443
Hanumanth Reddy Pothula1ceb7032018-04-05 19:35:55 +05307444 request = hdd_request_alloc(&params);
7445 if (!request) {
7446 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Request allocation failure"));
7447 return VOS_STATUS_E_NOMEM;
7448 }
7449 cookie = hdd_request_cookie(request);
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07007450
7451 /* query tsm stats */
Hanumanth Reddy Pothula1ceb7032018-04-05 19:35:55 +05307452 hstatus = sme_GetTsmStats(pHddCtx->hHal, hdd_get_tsm_stats_cb,
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07007453 pHddStaCtx->conn_info.staId[ 0 ],
7454 pHddStaCtx->conn_info.bssId,
Hanumanth Reddy Pothula1ceb7032018-04-05 19:35:55 +05307455 cookie, pHddCtx->pvosContext, tid);
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07007456
7457 if (eHAL_STATUS_SUCCESS != hstatus)
7458 {
Jeff Johnson72a40512013-12-19 10:14:15 -08007459 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unable to retrieve statistics",
7460 __func__);
7461 vstatus = VOS_STATUS_E_FAULT;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07007462 }
7463 else
7464 {
7465 /* request was sent -- wait for the response */
Hanumanth Reddy Pothula1ceb7032018-04-05 19:35:55 +05307466 ret = hdd_request_wait_for_response(request);
7467 if (ret) {
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07007468 hddLog(VOS_TRACE_LEVEL_ERROR,
Hanumanth Reddy Pothula1ceb7032018-04-05 19:35:55 +05307469 "SME timeout while retrieving statistics");
Jeff Johnson72a40512013-12-19 10:14:15 -08007470 vstatus = VOS_STATUS_E_TIMEOUT;
Hanumanth Reddy Pothula1ceb7032018-04-05 19:35:55 +05307471 } else {
7472 priv = hdd_request_priv(request);
7473 *pTsmMetrics = priv->tsm_metrics;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07007474 }
7475 }
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07007476
Hanumanth Reddy Pothula1ceb7032018-04-05 19:35:55 +05307477 hdd_request_put(request);
Jeff Johnson72a40512013-12-19 10:14:15 -08007478
Jeff Johnson72a40512013-12-19 10:14:15 -08007479 return vstatus;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07007480}
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08007481#endif /*FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07007482
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08007483#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowdade697412013-02-14 16:31:48 -08007484void hdd_getBand_helper(hdd_context_t *pHddCtx, int *pBand)
7485{
7486 eCsrBand band = -1;
7487 sme_GetFreqBand((tHalHandle)(pHddCtx->hHal), &band);
7488 switch (band)
7489 {
7490 case eCSR_BAND_ALL:
7491 *pBand = WLAN_HDD_UI_BAND_AUTO;
7492 break;
7493
7494 case eCSR_BAND_24:
7495 *pBand = WLAN_HDD_UI_BAND_2_4_GHZ;
7496 break;
7497
7498 case eCSR_BAND_5G:
7499 *pBand = WLAN_HDD_UI_BAND_5_GHZ;
7500 break;
7501
7502 default:
7503 hddLog( VOS_TRACE_LEVEL_WARN, "%s: Invalid Band %d", __func__, band);
7504 *pBand = -1;
7505 break;
7506 }
7507}
7508
7509/**---------------------------------------------------------------------------
7510
Srinivas Girigowda100eb322013-03-15 16:48:20 -07007511 \brief hdd_parse_send_action_frame_data() - HDD Parse send action frame data
7512
7513 This function parses the send action frame data passed in the format
7514 SENDACTIONFRAME<space><bssid><space><channel><space><dwelltime><space><data>
7515
Srinivas Girigowda56076852013-08-20 14:00:50 -07007516 \param - pValue Pointer to input data
Srinivas Girigowda100eb322013-03-15 16:48:20 -07007517 \param - pTargetApBssid Pointer to target Ap bssid
7518 \param - pChannel Pointer to the Target AP channel
7519 \param - pDwellTime Pointer to the time to stay off-channel after transmitting action frame
7520 \param - pBuf Pointer to data
7521 \param - pBufLen Pointer to data length
7522
7523 \return - 0 for success non-zero for failure
7524
7525 --------------------------------------------------------------------------*/
7526VOS_STATUS hdd_parse_send_action_frame_data(tANI_U8 *pValue, tANI_U8 *pTargetApBssid, tANI_U8 *pChannel,
7527 tANI_U8 *pDwellTime, tANI_U8 **pBuf, tANI_U8 *pBufLen)
7528{
7529 tANI_U8 *inPtr = pValue;
7530 tANI_U8 *dataEnd;
7531 int tempInt;
7532 int j = 0;
7533 int i = 0;
7534 int v = 0;
7535 tANI_U8 tempBuf[32];
7536 tANI_U8 tempByte = 0;
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08007537 /* 12 hexa decimal digits, 5 ':' and '\0' */
7538 tANI_U8 macAddress[18];
Srinivas Girigowda100eb322013-03-15 16:48:20 -07007539
7540 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
7541 /*no argument after the command*/
7542 if (NULL == inPtr)
7543 {
7544 return -EINVAL;
7545 }
7546
7547 /*no space after the command*/
7548 else if (SPACE_ASCII_VALUE != *inPtr)
7549 {
7550 return -EINVAL;
7551 }
7552
7553 /*removing empty spaces*/
7554 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
7555
7556 /*no argument followed by spaces*/
7557 if ('\0' == *inPtr)
7558 {
7559 return -EINVAL;
7560 }
7561
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07007562 v = sscanf(inPtr, "%17s", macAddress);
7563 if (!((1 == v) && hdd_is_valid_mac_address(macAddress)))
Srinivas Girigowda100eb322013-03-15 16:48:20 -07007564 {
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07007565 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7566 "Invalid MAC address or All hex inputs are not read (%d)", v);
7567 return -EINVAL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07007568 }
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07007569
7570 pTargetApBssid[0] = hdd_parse_hex(macAddress[0]) << 4 | hdd_parse_hex(macAddress[1]);
7571 pTargetApBssid[1] = hdd_parse_hex(macAddress[3]) << 4 | hdd_parse_hex(macAddress[4]);
7572 pTargetApBssid[2] = hdd_parse_hex(macAddress[6]) << 4 | hdd_parse_hex(macAddress[7]);
7573 pTargetApBssid[3] = hdd_parse_hex(macAddress[9]) << 4 | hdd_parse_hex(macAddress[10]);
7574 pTargetApBssid[4] = hdd_parse_hex(macAddress[12]) << 4 | hdd_parse_hex(macAddress[13]);
7575 pTargetApBssid[5] = hdd_parse_hex(macAddress[15]) << 4 | hdd_parse_hex(macAddress[16]);
Srinivas Girigowda100eb322013-03-15 16:48:20 -07007576
7577 /* point to the next argument */
7578 inPtr = strnchr(inPtr, strlen(inPtr), SPACE_ASCII_VALUE);
7579 /*no argument after the command*/
7580 if (NULL == inPtr) return -EINVAL;
7581
7582 /*removing empty spaces*/
7583 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
7584
7585 /*no argument followed by spaces*/
7586 if ('\0' == *inPtr)
7587 {
7588 return -EINVAL;
7589 }
7590
7591 /*getting the next argument ie the channel number */
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08007592 v = sscanf(inPtr, "%31s ", tempBuf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07007593 if (1 != v) return -EINVAL;
7594
Srinivas Girigowda100eb322013-03-15 16:48:20 -07007595 v = kstrtos32(tempBuf, 10, &tempInt);
Agarwal Ashish353b3a82014-04-08 14:55:11 +05307596 if ( v < 0 || tempInt <= 0 || tempInt > WNI_CFG_CURRENT_CHANNEL_STAMAX )
Kiet Lambe150c22013-11-21 16:30:32 +05307597 return -EINVAL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07007598
7599 *pChannel = tempInt;
7600
7601 /* point to the next argument */
7602 inPtr = strnchr(inPtr, strlen(inPtr), SPACE_ASCII_VALUE);
7603 /*no argument after the command*/
7604 if (NULL == inPtr) return -EINVAL;
7605 /*removing empty spaces*/
7606 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
7607
7608 /*no argument followed by spaces*/
7609 if ('\0' == *inPtr)
7610 {
7611 return -EINVAL;
7612 }
7613
7614 /*getting the next argument ie the dwell time */
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08007615 v = sscanf(inPtr, "%31s ", tempBuf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07007616 if (1 != v) return -EINVAL;
7617
Srinivas Girigowda100eb322013-03-15 16:48:20 -07007618 v = kstrtos32(tempBuf, 10, &tempInt);
Srinivas Girigowda5a6e0672014-01-09 14:42:57 -08007619 if ( v < 0 || tempInt < 0) return -EINVAL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07007620
7621 *pDwellTime = tempInt;
7622
7623 /* point to the next argument */
7624 inPtr = strnchr(inPtr, strlen(inPtr), SPACE_ASCII_VALUE);
7625 /*no argument after the command*/
7626 if (NULL == inPtr) return -EINVAL;
7627 /*removing empty spaces*/
7628 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
7629
7630 /*no argument followed by spaces*/
7631 if ('\0' == *inPtr)
7632 {
7633 return -EINVAL;
7634 }
7635
7636 /* find the length of data */
7637 dataEnd = inPtr;
7638 while(('\0' != *dataEnd) )
7639 {
7640 dataEnd++;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07007641 }
Kiet Lambe150c22013-11-21 16:30:32 +05307642 *pBufLen = dataEnd - inPtr ;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07007643 if ( *pBufLen <= 0) return -EINVAL;
7644
Srinivas Girigowdab5ae85d2013-06-03 10:51:45 -07007645 /* Allocate the number of bytes based on the number of input characters
7646 whether it is even or odd.
7647 if the number of input characters are even, then we need N/2 byte.
7648 if the number of input characters are odd, then we need do (N+1)/2 to
7649 compensate rounding off.
7650 For example, if N = 18, then (18 + 1)/2 = 9 bytes are enough.
7651 If N = 19, then we need 10 bytes, hence (19 + 1)/2 = 10 bytes */
7652 *pBuf = vos_mem_malloc((*pBufLen + 1)/2);
Srinivas Girigowda100eb322013-03-15 16:48:20 -07007653 if (NULL == *pBuf)
7654 {
7655 hddLog(VOS_TRACE_LEVEL_FATAL,
7656 "%s: vos_mem_alloc failed ", __func__);
7657 return -EINVAL;
7658 }
7659
7660 /* the buffer received from the upper layer is character buffer,
7661 we need to prepare the buffer taking 2 characters in to a U8 hex decimal number
7662 for example 7f0000f0...form a buffer to contain 7f in 0th location, 00 in 1st
7663 and f0 in 3rd location */
7664 for (i = 0, j = 0; j < *pBufLen; j += 2)
7665 {
Kiet Lambe150c22013-11-21 16:30:32 +05307666 if( j+1 == *pBufLen)
7667 {
7668 tempByte = hdd_parse_hex(inPtr[j]);
7669 }
7670 else
7671 {
7672 tempByte = (hdd_parse_hex(inPtr[j]) << 4) | (hdd_parse_hex(inPtr[j + 1]));
7673 }
Srinivas Girigowda100eb322013-03-15 16:48:20 -07007674 (*pBuf)[i++] = tempByte;
7675 }
7676 *pBufLen = i;
7677 return VOS_STATUS_SUCCESS;
7678}
7679
Srinivas Girigowda100eb322013-03-15 16:48:20 -07007680/**---------------------------------------------------------------------------
7681
Srinivas Girigowdade697412013-02-14 16:31:48 -08007682 \brief hdd_parse_channellist() - HDD Parse channel list
7683
7684 This function parses the channel list passed in the format
7685 SETROAMSCANCHANNELS<space><Number of channels><space>Channel 1<space>Channel 2<space>Channel N
Srinivas Girigowdacf9a9b42013-03-21 11:55:24 -07007686 if the Number of channels (N) does not match with the actual number of channels passed
7687 then take the minimum of N and count of (Ch1, Ch2, ...Ch M)
7688 For example, if SETROAMSCANCHANNELS 3 36 40 44 48, only 36, 40 and 44 shall be taken.
7689 If SETROAMSCANCHANNELS 5 36 40 44 48, ignore 5 and take 36, 40, 44 and 48.
7690 This function does not take care of removing duplicate channels from the list
Srinivas Girigowdade697412013-02-14 16:31:48 -08007691
7692 \param - pValue Pointer to input channel list
7693 \param - ChannelList Pointer to local output array to record channel list
7694 \param - pNumChannels Pointer to number of roam scan channels
7695
7696 \return - 0 for success non-zero for failure
7697
7698 --------------------------------------------------------------------------*/
7699VOS_STATUS hdd_parse_channellist(tANI_U8 *pValue, tANI_U8 *pChannelList, tANI_U8 *pNumChannels)
7700{
7701 tANI_U8 *inPtr = pValue;
7702 int tempInt;
7703 int j = 0;
7704 int v = 0;
7705 char buf[32];
7706
7707 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
7708 /*no argument after the command*/
7709 if (NULL == inPtr)
7710 {
7711 return -EINVAL;
7712 }
7713
7714 /*no space after the command*/
7715 else if (SPACE_ASCII_VALUE != *inPtr)
7716 {
7717 return -EINVAL;
7718 }
7719
7720 /*removing empty spaces*/
Jeff Johnsona1f9afb2013-04-03 09:13:31 -07007721 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
Srinivas Girigowdade697412013-02-14 16:31:48 -08007722
7723 /*no argument followed by spaces*/
7724 if ('\0' == *inPtr)
7725 {
7726 return -EINVAL;
7727 }
7728
7729 /*getting the first argument ie the number of channels*/
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08007730 v = sscanf(inPtr, "%31s ", buf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07007731 if (1 != v) return -EINVAL;
7732
Srinivas Girigowdade697412013-02-14 16:31:48 -08007733 v = kstrtos32(buf, 10, &tempInt);
Jeff Johnsona1f9afb2013-04-03 09:13:31 -07007734 if ((v < 0) ||
7735 (tempInt <= 0) ||
7736 (tempInt > WNI_CFG_VALID_CHANNEL_LIST_LEN))
7737 {
7738 return -EINVAL;
7739 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08007740
7741 *pNumChannels = tempInt;
7742
7743 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
7744 "Number of channels are: %d", *pNumChannels);
7745
7746 for (j = 0; j < (*pNumChannels); j++)
7747 {
7748 /*inPtr pointing to the beginning of first space after number of channels*/
7749 inPtr = strpbrk( inPtr, " " );
7750 /*no channel list after the number of channels argument*/
7751 if (NULL == inPtr)
7752 {
Srinivas Girigowdacf9a9b42013-03-21 11:55:24 -07007753 if (0 != j)
7754 {
7755 *pNumChannels = j;
7756 return VOS_STATUS_SUCCESS;
7757 }
7758 else
7759 {
7760 return -EINVAL;
7761 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08007762 }
7763
7764 /*removing empty space*/
Jeff Johnsona1f9afb2013-04-03 09:13:31 -07007765 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
Srinivas Girigowdade697412013-02-14 16:31:48 -08007766
7767 /*no channel list after the number of channels argument and spaces*/
7768 if ( '\0' == *inPtr )
7769 {
Srinivas Girigowdacf9a9b42013-03-21 11:55:24 -07007770 if (0 != j)
7771 {
7772 *pNumChannels = j;
7773 return VOS_STATUS_SUCCESS;
7774 }
7775 else
7776 {
7777 return -EINVAL;
7778 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08007779 }
7780
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08007781 v = sscanf(inPtr, "%31s ", buf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07007782 if (1 != v) return -EINVAL;
7783
Srinivas Girigowdade697412013-02-14 16:31:48 -08007784 v = kstrtos32(buf, 10, &tempInt);
Jeff Johnsona1f9afb2013-04-03 09:13:31 -07007785 if ((v < 0) ||
7786 (tempInt <= 0) ||
7787 (tempInt > WNI_CFG_CURRENT_CHANNEL_STAMAX))
7788 {
7789 return -EINVAL;
7790 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08007791 pChannelList[j] = tempInt;
7792
7793 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
7794 "Channel %d added to preferred channel list",
7795 pChannelList[j] );
7796 }
7797
Srinivas Girigowdade697412013-02-14 16:31:48 -08007798 return VOS_STATUS_SUCCESS;
7799}
7800
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07007801
Selvaraj, Sridhar5aff1ed2016-06-18 01:26:23 +05307802/**
7803 * hdd_parse_reassoc_command_v1_data() - HDD Parse reassoc command data
7804 * This function parses the reasoc command data passed in the format
7805 * REASSOC<space><bssid><space><channel>
7806 *
7807 * @pValue: Pointer to input data (its a NUL terminated string)
7808 * @pTargetApBssid: Pointer to target Ap bssid
7809 * @pChannel: Pointer to the Target AP channel
7810 *
7811 * Return: 0 for success non-zero for failure
7812 */
7813static int hdd_parse_reassoc_command_v1_data(const tANI_U8 *pValue,
7814 tANI_U8 *pTargetApBssid, tANI_U8 *pChannel)
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07007815{
Selvaraj, Sridhar5aff1ed2016-06-18 01:26:23 +05307816 const tANI_U8 *inPtr = pValue;
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07007817 int tempInt;
7818 int v = 0;
7819 tANI_U8 tempBuf[32];
Kiet Lamaa8e15a2014-02-11 23:30:06 -08007820 /* 12 hexa decimal digits, 5 ':' and '\0' */
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08007821 tANI_U8 macAddress[18];
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07007822
7823 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
7824 /*no argument after the command*/
7825 if (NULL == inPtr)
7826 {
7827 return -EINVAL;
7828 }
7829
7830 /*no space after the command*/
7831 else if (SPACE_ASCII_VALUE != *inPtr)
7832 {
7833 return -EINVAL;
7834 }
7835
7836 /*removing empty spaces*/
7837 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
7838
7839 /*no argument followed by spaces*/
7840 if ('\0' == *inPtr)
7841 {
7842 return -EINVAL;
7843 }
7844
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07007845 v = sscanf(inPtr, "%17s", macAddress);
7846 if (!((1 == v) && hdd_is_valid_mac_address(macAddress)))
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07007847 {
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07007848 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7849 "Invalid MAC address or All hex inputs are not read (%d)", v);
7850 return -EINVAL;
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07007851 }
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07007852
7853 pTargetApBssid[0] = hdd_parse_hex(macAddress[0]) << 4 | hdd_parse_hex(macAddress[1]);
7854 pTargetApBssid[1] = hdd_parse_hex(macAddress[3]) << 4 | hdd_parse_hex(macAddress[4]);
7855 pTargetApBssid[2] = hdd_parse_hex(macAddress[6]) << 4 | hdd_parse_hex(macAddress[7]);
7856 pTargetApBssid[3] = hdd_parse_hex(macAddress[9]) << 4 | hdd_parse_hex(macAddress[10]);
7857 pTargetApBssid[4] = hdd_parse_hex(macAddress[12]) << 4 | hdd_parse_hex(macAddress[13]);
7858 pTargetApBssid[5] = hdd_parse_hex(macAddress[15]) << 4 | hdd_parse_hex(macAddress[16]);
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07007859
7860 /* point to the next argument */
7861 inPtr = strnchr(inPtr, strlen(inPtr), SPACE_ASCII_VALUE);
7862 /*no argument after the command*/
7863 if (NULL == inPtr) return -EINVAL;
7864
7865 /*removing empty spaces*/
7866 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
7867
7868 /*no argument followed by spaces*/
7869 if ('\0' == *inPtr)
7870 {
7871 return -EINVAL;
7872 }
7873
7874 /*getting the next argument ie the channel number */
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08007875 v = sscanf(inPtr, "%31s ", tempBuf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07007876 if (1 != v) return -EINVAL;
7877
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07007878 v = kstrtos32(tempBuf, 10, &tempInt);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07007879 if ((v < 0) ||
Padma, Santhosh Kumar0fa809b2014-11-13 14:56:56 +05307880 (tempInt < 0) ||
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07007881 (tempInt > WNI_CFG_CURRENT_CHANNEL_STAMAX))
7882 {
7883 return -EINVAL;
7884 }
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07007885
7886 *pChannel = tempInt;
7887 return VOS_STATUS_SUCCESS;
7888}
7889
7890#endif
7891
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08007892#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07007893/**---------------------------------------------------------------------------
7894
7895 \brief hdd_parse_get_cckm_ie() - HDD Parse and fetch the CCKM IE
7896
7897 This function parses the SETCCKM IE command
7898 SETCCKMIE<space><ie data>
7899
7900 \param - pValue Pointer to input data
7901 \param - pCckmIe Pointer to output cckm Ie
7902 \param - pCckmIeLen Pointer to output cckm ie length
7903
7904 \return - 0 for success non-zero for failure
7905
7906 --------------------------------------------------------------------------*/
7907VOS_STATUS hdd_parse_get_cckm_ie(tANI_U8 *pValue, tANI_U8 **pCckmIe,
7908 tANI_U8 *pCckmIeLen)
7909{
7910 tANI_U8 *inPtr = pValue;
7911 tANI_U8 *dataEnd;
7912 int j = 0;
7913 int i = 0;
7914 tANI_U8 tempByte = 0;
7915
7916 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
7917 /*no argument after the command*/
7918 if (NULL == inPtr)
7919 {
7920 return -EINVAL;
7921 }
7922
7923 /*no space after the command*/
7924 else if (SPACE_ASCII_VALUE != *inPtr)
7925 {
7926 return -EINVAL;
7927 }
7928
7929 /*removing empty spaces*/
7930 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
7931
7932 /*no argument followed by spaces*/
7933 if ('\0' == *inPtr)
7934 {
7935 return -EINVAL;
7936 }
7937
7938 /* find the length of data */
7939 dataEnd = inPtr;
7940 while(('\0' != *dataEnd) )
7941 {
7942 dataEnd++;
7943 ++(*pCckmIeLen);
7944 }
7945 if ( *pCckmIeLen <= 0) return -EINVAL;
7946
7947 /* Allocate the number of bytes based on the number of input characters
7948 whether it is even or odd.
7949 if the number of input characters are even, then we need N/2 byte.
7950 if the number of input characters are odd, then we need do (N+1)/2 to
7951 compensate rounding off.
7952 For example, if N = 18, then (18 + 1)/2 = 9 bytes are enough.
7953 If N = 19, then we need 10 bytes, hence (19 + 1)/2 = 10 bytes */
7954 *pCckmIe = vos_mem_malloc((*pCckmIeLen + 1)/2);
7955 if (NULL == *pCckmIe)
7956 {
7957 hddLog(VOS_TRACE_LEVEL_FATAL,
7958 "%s: vos_mem_alloc failed ", __func__);
7959 return -EINVAL;
7960 }
7961 vos_mem_zero(*pCckmIe, (*pCckmIeLen + 1)/2);
7962 /* the buffer received from the upper layer is character buffer,
7963 we need to prepare the buffer taking 2 characters in to a U8 hex decimal number
7964 for example 7f0000f0...form a buffer to contain 7f in 0th location, 00 in 1st
7965 and f0 in 3rd location */
7966 for (i = 0, j = 0; j < *pCckmIeLen; j += 2)
7967 {
7968 tempByte = (hdd_parse_hex(inPtr[j]) << 4) | (hdd_parse_hex(inPtr[j + 1]));
7969 (*pCckmIe)[i++] = tempByte;
7970 }
7971 *pCckmIeLen = i;
7972
7973 return VOS_STATUS_SUCCESS;
7974}
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08007975#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07007976
Jeff Johnson295189b2012-06-20 16:38:30 -07007977/**---------------------------------------------------------------------------
7978
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07007979 \brief hdd_is_valid_mac_address() - Validate MAC address
7980
7981 This function validates whether the given MAC address is valid or not
7982 Expected MAC address is of the format XX:XX:XX:XX:XX:XX
7983 where X is the hexa decimal digit character and separated by ':'
7984 This algorithm works even if MAC address is not separated by ':'
7985
7986 This code checks given input string mac contains exactly 12 hexadecimal digits.
7987 and a separator colon : appears in the input string only after
7988 an even number of hex digits.
7989
7990 \param - pMacAddr pointer to the input MAC address
7991 \return - 1 for valid and 0 for invalid
7992
7993 --------------------------------------------------------------------------*/
7994
7995v_BOOL_t hdd_is_valid_mac_address(const tANI_U8 *pMacAddr)
7996{
7997 int xdigit = 0;
7998 int separator = 0;
7999 while (*pMacAddr)
8000 {
8001 if (isxdigit(*pMacAddr))
8002 {
8003 xdigit++;
8004 }
8005 else if (':' == *pMacAddr)
8006 {
8007 if (0 == xdigit || ((xdigit / 2) - 1) != separator)
8008 break;
8009
8010 ++separator;
8011 }
8012 else
8013 {
8014 separator = -1;
8015 /* Invalid MAC found */
8016 return 0;
8017 }
8018 ++pMacAddr;
8019 }
8020 return (xdigit == 12 && (separator == 5 || separator == 0));
8021}
8022
8023/**---------------------------------------------------------------------------
8024
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05308025 \brief __hdd_open() - HDD Open function
Jeff Johnson295189b2012-06-20 16:38:30 -07008026
8027 \param - dev Pointer to net_device structure
8028
8029 \return - 0 for success non-zero for failure
8030
8031 --------------------------------------------------------------------------*/
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05308032int __hdd_open(struct net_device *dev)
Jeff Johnson295189b2012-06-20 16:38:30 -07008033{
8034 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
8035 hdd_context_t *pHddCtx;
8036 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
8037 VOS_STATUS status;
8038 v_BOOL_t in_standby = TRUE;
8039
8040 if (NULL == pAdapter)
8041 {
8042 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Agarwal Ashish971c2882013-10-30 20:11:12 +05308043 "%s: pAdapter is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07008044 return -ENODEV;
8045 }
8046
8047 pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05308048 MTRACE(vos_trace(VOS_MODULE_ID_HDD, TRACE_CODE_HDD_OPEN_REQUEST,
8049 pAdapter->sessionId, pAdapter->device_mode));
Jeff Johnson295189b2012-06-20 16:38:30 -07008050 if (NULL == pHddCtx)
8051 {
8052 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008053 "%s: HDD context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07008054 return -ENODEV;
8055 }
8056
8057 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
8058 while ( (NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status) )
8059 {
Jeff Johnson6a81ca42013-04-05 10:37:08 -07008060 if (test_bit(DEVICE_IFACE_OPENED, &pAdapterNode->pAdapter->event_flags))
8061 {
8062 hddLog(VOS_TRACE_LEVEL_INFO, "%s: chip already out of standby",
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05308063 __func__);
Jeff Johnson6a81ca42013-04-05 10:37:08 -07008064 in_standby = FALSE;
8065 break;
8066 }
8067 else
8068 {
8069 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
8070 pAdapterNode = pNext;
8071 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008072 }
8073
8074 if (TRUE == in_standby)
8075 {
8076 if (VOS_STATUS_SUCCESS != wlan_hdd_exit_lowpower(pHddCtx, pAdapter))
8077 {
8078 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Failed to bring "
8079 "wlan out of power save", __func__);
8080 return -EINVAL;
8081 }
8082 }
8083
Jeff Johnson6a81ca42013-04-05 10:37:08 -07008084 set_bit(DEVICE_IFACE_OPENED, &pAdapter->event_flags);
Jeff Johnson295189b2012-06-20 16:38:30 -07008085 if (hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter)))
8086 {
8087 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008088 "%s: Enabling Tx Queues", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07008089 /* Enable TX queues only when we are connected */
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +05308090 hddLog(VOS_TRACE_LEVEL_INFO, FL("Enabling queues"));
Jeff Johnson295189b2012-06-20 16:38:30 -07008091 netif_tx_start_all_queues(dev);
8092 }
8093
8094 return 0;
8095}
8096
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05308097/**---------------------------------------------------------------------------
8098
8099 \brief hdd_open() - Wrapper function for __hdd_open to protect it from SSR
8100
8101 This is called in response to ifconfig up
8102
8103 \param - dev Pointer to net_device structure
8104
8105 \return - 0 for success non-zero for failure
8106
8107 --------------------------------------------------------------------------*/
8108int hdd_open(struct net_device *dev)
8109{
8110 int ret;
8111
8112 vos_ssr_protect(__func__);
8113 ret = __hdd_open(dev);
8114 vos_ssr_unprotect(__func__);
8115
8116 return ret;
8117}
8118
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05308119int __hdd_mon_open (struct net_device *dev)
Jeff Johnson295189b2012-06-20 16:38:30 -07008120{
8121 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +05308122 hdd_adapter_t *sta_adapter;
8123 hdd_context_t *hdd_ctx;
Jeff Johnson295189b2012-06-20 16:38:30 -07008124
8125 if(pAdapter == NULL) {
8126 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008127 "%s: HDD adapter context is Null", __func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08008128 return -EINVAL;
Jeff Johnson295189b2012-06-20 16:38:30 -07008129 }
8130
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +05308131 if (vos_get_concurrency_mode() != VOS_STA_MON)
8132 return 0;
8133
8134 hdd_ctx = WLAN_HDD_GET_CTX(pAdapter);
8135 if (wlan_hdd_validate_context(hdd_ctx))
8136 return -EINVAL;
8137
8138 sta_adapter = hdd_get_adapter(hdd_ctx, WLAN_HDD_INFRA_STATION);
8139 if (!sta_adapter) {
8140 hddLog(LOGE, FL("No valid STA interface"));
8141 return -EINVAL;
8142 }
8143
8144 if (!test_bit(DEVICE_IFACE_OPENED, &sta_adapter->event_flags)) {
8145 hddLog(LOGE, FL("STA Interface is not OPENED"));
8146 return -EINVAL;
8147 }
8148
8149 set_bit(DEVICE_IFACE_OPENED, &pAdapter->event_flags);
8150
Jeff Johnson295189b2012-06-20 16:38:30 -07008151 return 0;
8152}
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05308153
8154int hdd_mon_open (struct net_device *dev)
8155{
8156 int ret;
8157
8158 vos_ssr_protect(__func__);
8159 ret = __hdd_mon_open(dev);
8160 vos_ssr_unprotect(__func__);
8161
8162 return ret;
8163}
8164
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +05308165int __hdd_mon_stop (struct net_device *dev)
8166{
8167 hdd_adapter_t *mon_adapter = WLAN_HDD_GET_PRIV_PTR(dev);
8168 hdd_context_t *hdd_ctx;
8169
8170 if (vos_get_concurrency_mode() != VOS_STA_MON)
8171 return 0;
8172
8173 if(!mon_adapter) {
8174 hddLog(LOGE, FL("HDD adapter is Null"));
8175 return -EINVAL;
8176 }
8177
8178 hdd_ctx = WLAN_HDD_GET_CTX(mon_adapter);
8179 if (wlan_hdd_validate_context(hdd_ctx))
8180 return -EINVAL;
8181
8182 if (!test_bit(DEVICE_IFACE_OPENED, &mon_adapter->event_flags)) {
8183 hddLog(LOGE, FL("NETDEV Interface is not OPENED"));
8184 return -ENODEV;
8185 }
8186
8187 clear_bit(DEVICE_IFACE_OPENED, &mon_adapter->event_flags);
8188 hdd_stop_adapter(hdd_ctx, mon_adapter, VOS_FALSE);
8189
8190 return 0;
8191}
8192
Katya Nigame7b69a82015-04-28 15:24:06 +05308193int hdd_mon_stop(struct net_device *dev)
8194{
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +05308195 int ret;
8196
8197 vos_ssr_protect(__func__);
8198 ret = __hdd_mon_stop(dev);
8199 vos_ssr_unprotect(__func__);
8200
8201 return ret;
Katya Nigame7b69a82015-04-28 15:24:06 +05308202}
8203
Jeff Johnson295189b2012-06-20 16:38:30 -07008204/**---------------------------------------------------------------------------
8205
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05308206 \brief __hdd_stop() - HDD stop function
Jeff Johnson295189b2012-06-20 16:38:30 -07008207
8208 \param - dev Pointer to net_device structure
8209
8210 \return - 0 for success non-zero for failure
8211
8212 --------------------------------------------------------------------------*/
8213
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05308214int __hdd_stop (struct net_device *dev)
Jeff Johnson295189b2012-06-20 16:38:30 -07008215{
Vinay Krishna Eranna90f43532014-10-27 16:45:54 +05308216 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07008217 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
8218 hdd_context_t *pHddCtx;
8219 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
8220 VOS_STATUS status;
8221 v_BOOL_t enter_standby = TRUE;
8222
8223 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07008224 if (NULL == pAdapter)
8225 {
8226 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Agarwal Ashish971c2882013-10-30 20:11:12 +05308227 "%s: pAdapter is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07008228 return -ENODEV;
8229 }
Sachin Ahuja9b4958f2015-01-15 21:37:00 +05308230 MTRACE(vos_trace(VOS_MODULE_ID_HDD, TRACE_CODE_HDD_STOP_REQUEST,
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05308231 pAdapter->sessionId, pAdapter->device_mode));
Vinay Krishna Eranna90f43532014-10-27 16:45:54 +05308232
8233 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8234 ret = wlan_hdd_validate_context(pHddCtx);
8235 if (ret)
Jeff Johnson295189b2012-06-20 16:38:30 -07008236 {
Vinay Krishna Eranna90f43532014-10-27 16:45:54 +05308237 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07008238 }
8239
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05308240 /* Nothing to be done if the interface is not opened */
8241 if (VOS_FALSE == test_bit(DEVICE_IFACE_OPENED, &pAdapter->event_flags))
8242 {
8243 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8244 "%s: NETDEV Interface is not OPENED", __func__);
8245 return -ENODEV;
8246 }
8247
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +05308248 if (pHddCtx->concurrency_mode == VOS_STA_MON) {
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +05308249 /*
Rajeev Kumar Sirasanagandlaa74e1222018-01-09 17:38:55 +05308250 * In STA + Monitor mode concurrency, no point in running
8251 * capture on monitor interface, when STA interface is stopped
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +05308252 */
Rajeev Kumar Sirasanagandlaa74e1222018-01-09 17:38:55 +05308253 wlan_hdd_stop_mon(pHddCtx, true);
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +05308254 }
8255
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05308256 /* Make sure the interface is marked as closed */
Jeff Johnson6a81ca42013-04-05 10:37:08 -07008257 clear_bit(DEVICE_IFACE_OPENED, &pAdapter->event_flags);
Jeff Johnson295189b2012-06-20 16:38:30 -07008258 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Disabling OS Tx queues", __func__);
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05308259
8260 /* Disable TX on the interface, after this hard_start_xmit() will not
8261 * be called on that interface
8262 */
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +05308263 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Jeff Johnson295189b2012-06-20 16:38:30 -07008264 netif_tx_disable(pAdapter->dev);
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05308265
8266 /* Mark the interface status as "down" for outside world */
Jeff Johnson295189b2012-06-20 16:38:30 -07008267 netif_carrier_off(pAdapter->dev);
8268
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05308269 /* The interface is marked as down for outside world (aka kernel)
8270 * But the driver is pretty much alive inside. The driver needs to
8271 * tear down the existing connection on the netdev (session)
8272 * cleanup the data pipes and wait until the control plane is stabilized
8273 * for this interface. The call also needs to wait until the above
8274 * mentioned actions are completed before returning to the caller.
8275 * Notice that the hdd_stop_adapter is requested not to close the session
8276 * That is intentional to be able to scan if it is a STA/P2P interface
8277 */
8278 hdd_stop_adapter(pHddCtx, pAdapter, VOS_FALSE);
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05308279#ifdef FEATURE_WLAN_TDLS
8280 mutex_lock(&pHddCtx->tdls_lock);
8281#endif
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05308282 /* DeInit the adapter. This ensures datapath cleanup as well */
c_hpothu002231a2015-02-05 14:58:51 +05308283 hdd_deinit_adapter(pHddCtx, pAdapter, TRUE);
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05308284#ifdef FEATURE_WLAN_TDLS
8285 mutex_unlock(&pHddCtx->tdls_lock);
8286#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008287 /* SoftAP ifaces should never go in power save mode
8288 making sure same here. */
8289 if ( (WLAN_HDD_SOFTAP == pAdapter->device_mode )
Jeff Johnson295189b2012-06-20 16:38:30 -07008290 || (WLAN_HDD_P2P_GO == pAdapter->device_mode )
Jeff Johnson295189b2012-06-20 16:38:30 -07008291 )
8292 {
8293 /* SoftAP mode, so return from here */
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308294 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8295 "%s: In SAP MODE", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07008296 EXIT();
8297 return 0;
8298 }
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05308299 /* Find if any iface is up. If any iface is up then can't put device to
8300 * sleep/power save mode
8301 */
Jeff Johnson295189b2012-06-20 16:38:30 -07008302 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
8303 while ( (NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status) )
8304 {
Jeff Johnson6a81ca42013-04-05 10:37:08 -07008305 if (test_bit(DEVICE_IFACE_OPENED, &pAdapterNode->pAdapter->event_flags))
8306 {
8307 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Still other ifaces are up cannot "
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05308308 "put device to sleep", __func__);
Jeff Johnson6a81ca42013-04-05 10:37:08 -07008309 enter_standby = FALSE;
8310 break;
8311 }
8312 else
8313 {
8314 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
8315 pAdapterNode = pNext;
8316 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008317 }
8318
8319 if (TRUE == enter_standby)
8320 {
8321 hddLog(VOS_TRACE_LEVEL_INFO, "%s: All Interfaces are Down "
8322 "entering standby", __func__);
8323 if (VOS_STATUS_SUCCESS != wlan_hdd_enter_lowpower(pHddCtx))
8324 {
8325 /*log and return success*/
8326 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Failed to put "
8327 "wlan in power save", __func__);
8328 }
8329 }
Hanumanth Reddy Pothula972e1df2018-06-14 13:33:47 +05308330
8331 /*
8332 * Upon wifi turn off, DUT has to flush the scan results so if
8333 * this is the last cli iface, flush the scan database.
8334 */
8335 if (!hdd_is_cli_iface_up(pHddCtx))
8336 sme_ScanFlushResult(pHddCtx->hHal, 0);
Jeff Johnson295189b2012-06-20 16:38:30 -07008337
8338 EXIT();
8339 return 0;
8340}
8341
8342/**---------------------------------------------------------------------------
8343
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05308344 \brief hdd_stop() - wrapper_function for __hdd_stop to protect it from SSR
Jeff Johnson295189b2012-06-20 16:38:30 -07008345
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05308346 This is called in response to ifconfig down
8347
8348 \param - dev Pointer to net_device structure
8349
8350 \return - 0 for success non-zero for failure
8351-----------------------------------------------------------------------------*/
8352int hdd_stop (struct net_device *dev)
8353{
8354 int ret;
8355
8356 vos_ssr_protect(__func__);
8357 ret = __hdd_stop(dev);
8358 vos_ssr_unprotect(__func__);
8359
8360 return ret;
8361}
8362
8363/**---------------------------------------------------------------------------
8364
8365 \brief __hdd_uninit() - HDD uninit function
Jeff Johnson295189b2012-06-20 16:38:30 -07008366
8367 \param - dev Pointer to net_device structure
8368
8369 \return - void
8370
8371 --------------------------------------------------------------------------*/
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05308372static void __hdd_uninit (struct net_device *dev)
Jeff Johnson295189b2012-06-20 16:38:30 -07008373{
8374 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05308375 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07008376 ENTER();
8377
8378 do
8379 {
8380 if (NULL == pAdapter)
8381 {
8382 hddLog(VOS_TRACE_LEVEL_FATAL,
8383 "%s: NULL pAdapter", __func__);
8384 break;
8385 }
8386
8387 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
8388 {
8389 hddLog(VOS_TRACE_LEVEL_FATAL,
8390 "%s: Invalid magic", __func__);
8391 break;
8392 }
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05308393 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8394 if (NULL == pHddCtx)
Jeff Johnson295189b2012-06-20 16:38:30 -07008395 {
8396 hddLog(VOS_TRACE_LEVEL_FATAL,
8397 "%s: NULL pHddCtx", __func__);
8398 break;
8399 }
8400
8401 if (dev != pAdapter->dev)
8402 {
8403 hddLog(VOS_TRACE_LEVEL_FATAL,
8404 "%s: Invalid device reference", __func__);
8405 /* we haven't validated all cases so let this go for now */
8406 }
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05308407#ifdef FEATURE_WLAN_TDLS
8408 mutex_lock(&pHddCtx->tdls_lock);
8409#endif
c_hpothu002231a2015-02-05 14:58:51 +05308410 hdd_deinit_adapter(pHddCtx, pAdapter, TRUE);
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05308411#ifdef FEATURE_WLAN_TDLS
8412 mutex_unlock(&pHddCtx->tdls_lock);
8413#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008414
8415 /* after uninit our adapter structure will no longer be valid */
8416 pAdapter->dev = NULL;
8417 pAdapter->magic = 0;
Manjeet Singh47ee8472016-04-11 11:57:18 +05308418 pAdapter->pHddCtx = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07008419 } while (0);
8420
8421 EXIT();
8422}
8423
8424/**---------------------------------------------------------------------------
8425
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05308426 \brief hdd_uninit() - Wrapper function to protect __hdd_uninit from SSR
8427
8428 This is called during the netdev unregister to uninitialize all data
8429associated with the device
8430
8431 \param - dev Pointer to net_device structure
8432
8433 \return - void
8434
8435 --------------------------------------------------------------------------*/
8436static void hdd_uninit (struct net_device *dev)
8437{
8438 vos_ssr_protect(__func__);
8439 __hdd_uninit(dev);
8440 vos_ssr_unprotect(__func__);
8441}
8442
8443/**---------------------------------------------------------------------------
8444
Jeff Johnson295189b2012-06-20 16:38:30 -07008445 \brief hdd_release_firmware() -
8446
8447 This function calls the release firmware API to free the firmware buffer.
8448
8449 \param - pFileName Pointer to the File Name.
8450 pCtx - Pointer to the adapter .
8451
8452
8453 \return - 0 for success, non zero for failure
8454
8455 --------------------------------------------------------------------------*/
8456
8457VOS_STATUS hdd_release_firmware(char *pFileName,v_VOID_t *pCtx)
8458{
8459 VOS_STATUS status = VOS_STATUS_SUCCESS;
8460 hdd_context_t *pHddCtx = (hdd_context_t*)pCtx;
8461 ENTER();
8462
8463
8464 if (!strcmp(WLAN_FW_FILE, pFileName)) {
8465
8466 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,"%s: Loaded firmware file is %s",__func__,pFileName);
8467
8468 if(pHddCtx->fw) {
8469 release_firmware(pHddCtx->fw);
8470 pHddCtx->fw = NULL;
8471 }
8472 else
8473 status = VOS_STATUS_E_FAILURE;
8474 }
8475 else if (!strcmp(WLAN_NV_FILE,pFileName)) {
8476 if(pHddCtx->nv) {
8477 release_firmware(pHddCtx->nv);
8478 pHddCtx->nv = NULL;
8479 }
8480 else
8481 status = VOS_STATUS_E_FAILURE;
8482
8483 }
8484
8485 EXIT();
8486 return status;
8487}
8488
8489/**---------------------------------------------------------------------------
8490
8491 \brief hdd_request_firmware() -
8492
8493 This function reads the firmware file using the request firmware
8494 API and returns the the firmware data and the firmware file size.
8495
8496 \param - pfileName - Pointer to the file name.
8497 - pCtx - Pointer to the adapter .
8498 - ppfw_data - Pointer to the pointer of the firmware data.
8499 - pSize - Pointer to the file size.
8500
8501 \return - VOS_STATUS_SUCCESS for success, VOS_STATUS_E_FAILURE for failure
8502
8503 --------------------------------------------------------------------------*/
8504
8505
8506VOS_STATUS hdd_request_firmware(char *pfileName,v_VOID_t *pCtx,v_VOID_t **ppfw_data, v_SIZE_t *pSize)
8507{
8508 int status;
8509 VOS_STATUS retval = VOS_STATUS_SUCCESS;
8510 hdd_context_t *pHddCtx = (hdd_context_t*)pCtx;
8511 ENTER();
8512
8513 if( (!strcmp(WLAN_FW_FILE, pfileName)) ) {
8514
8515 status = request_firmware(&pHddCtx->fw, pfileName, pHddCtx->parent_dev);
8516
8517 if(status || !pHddCtx->fw || !pHddCtx->fw->data) {
8518 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Firmware %s download failed",
8519 __func__, pfileName);
8520 retval = VOS_STATUS_E_FAILURE;
8521 }
8522
8523 else {
8524 *ppfw_data = (v_VOID_t *)pHddCtx->fw->data;
8525 *pSize = pHddCtx->fw->size;
8526 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Firmware size = %d",
8527 __func__, *pSize);
8528 }
8529 }
8530 else if(!strcmp(WLAN_NV_FILE, pfileName)) {
8531
8532 status = request_firmware(&pHddCtx->nv, pfileName, pHddCtx->parent_dev);
8533
8534 if(status || !pHddCtx->nv || !pHddCtx->nv->data) {
8535 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: nv %s download failed",
8536 __func__, pfileName);
8537 retval = VOS_STATUS_E_FAILURE;
8538 }
8539
8540 else {
8541 *ppfw_data = (v_VOID_t *)pHddCtx->nv->data;
8542 *pSize = pHddCtx->nv->size;
8543 hddLog(VOS_TRACE_LEVEL_INFO, "%s: nv file size = %d",
8544 __func__, *pSize);
8545 }
8546 }
8547
8548 EXIT();
8549 return retval;
8550}
8551/**---------------------------------------------------------------------------
8552 \brief hdd_full_pwr_cbk() - HDD full power callbackfunction
8553
8554 This is the function invoked by SME to inform the result of a full power
8555 request issued by HDD
8556
8557 \param - callbackcontext - Pointer to cookie
8558 status - result of request
8559
8560 \return - None
8561
8562--------------------------------------------------------------------------*/
8563void hdd_full_pwr_cbk(void *callbackContext, eHalStatus status)
8564{
8565 hdd_context_t *pHddCtx = (hdd_context_t*)callbackContext;
8566
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07008567 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,"HDD full Power callback status = %d", status);
Jeff Johnson295189b2012-06-20 16:38:30 -07008568 if(&pHddCtx->full_pwr_comp_var)
8569 {
8570 complete(&pHddCtx->full_pwr_comp_var);
8571 }
8572}
8573
Abhishek Singh00b71972016-01-07 10:51:04 +05308574#ifdef WLAN_FEATURE_RMC
8575static void hdd_tx_fail_ind_callback(v_U8_t *MacAddr, v_U8_t seqNo)
8576{
8577 int payload_len;
8578 struct sk_buff *skb;
8579 struct nlmsghdr *nlh;
8580 v_U8_t *data;
8581
8582 payload_len = ETH_ALEN;
8583
8584 if (0 == cesium_pid)
8585 {
8586 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: cesium process not registered",
8587 __func__);
8588 return;
8589 }
8590
8591 if ((skb = nlmsg_new(payload_len,GFP_ATOMIC)) == NULL)
8592 {
8593 hddLog(VOS_TRACE_LEVEL_ERROR,
8594 "%s: nlmsg_new() failed for msg size[%d]",
8595 __func__, NLMSG_SPACE(payload_len));
8596 return;
8597 }
8598
8599 nlh = nlmsg_put(skb, cesium_pid, seqNo, 0, payload_len, NLM_F_REQUEST);
8600
8601 if (NULL == nlh)
8602 {
8603 hddLog(VOS_TRACE_LEVEL_ERROR,
8604 "%s: nlmsg_put() failed for msg size[%d]",
8605 __func__, NLMSG_SPACE(payload_len));
8606
8607 kfree_skb(skb);
8608 return;
8609 }
8610
8611 data = nlmsg_data(nlh);
8612 memcpy(data, MacAddr, ETH_ALEN);
8613
8614 if (nlmsg_unicast(cesium_nl_srv_sock, skb, cesium_pid) < 0)
8615 {
8616 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: nlmsg_unicast() failed for msg size[%d]",
8617 __func__, NLMSG_SPACE(payload_len));
8618 }
8619
8620 return;
8621}
8622
8623/**---------------------------------------------------------------------------
8624 \brief hdd_ParseuserParams - return a pointer to the next argument
8625
8626 \return - status
8627
8628--------------------------------------------------------------------------*/
8629static int hdd_ParseUserParams(tANI_U8 *pValue, tANI_U8 **ppArg)
8630{
8631 tANI_U8 *pVal;
8632
8633 pVal = strchr(pValue, ' ');
8634
8635 if (NULL == pVal)
8636 {
8637 /* no argument remains */
8638 return -EINVAL;
8639 }
8640 else if (SPACE_ASCII_VALUE != *pVal)
8641 {
8642 /* no space after the current argument */
8643 return -EINVAL;
8644 }
8645
8646 pVal++;
8647
8648 /* remove empty spaces */
8649 while ((SPACE_ASCII_VALUE == *pVal) && ('\0' != *pVal))
8650 {
8651 pVal++;
8652 }
8653
8654 /* no argument followed by spaces */
8655 if ('\0' == *pVal)
8656 {
8657 return -EINVAL;
8658 }
8659
8660 *ppArg = pVal;
8661
8662 return 0;
8663}
8664
8665/**----------------------------------------------------------------------------
8666 \brief hdd_ParseIBSSTXFailEventParams - Parse params for SETIBSSTXFAILEVENT
8667
8668 \return - status
8669
8670------------------------------------------------------------------------------*/
8671static int hdd_ParseIBSSTXFailEventParams(tANI_U8 *pValue,
8672 tANI_U8 *tx_fail_count,
8673 tANI_U16 *pid)
8674{
8675 tANI_U8 *param = NULL;
8676 int ret;
8677
8678 ret = hdd_ParseUserParams(pValue, &param);
8679
8680 if (0 == ret && NULL != param)
8681 {
8682 if (1 != sscanf(param, "%hhu", tx_fail_count))
8683 {
8684 ret = -EINVAL;
8685 goto done;
8686 }
8687 }
8688 else
8689 {
8690 goto done;
8691 }
8692
8693 if (0 == *tx_fail_count)
8694 {
8695 *pid = 0;
8696 goto done;
8697 }
8698
8699 pValue = param;
8700 pValue++;
8701
8702 ret = hdd_ParseUserParams(pValue, &param);
8703
8704 if (0 == ret)
8705 {
8706 if (1 != sscanf(param, "%hu", pid))
8707 {
8708 ret = -EINVAL;
8709 goto done;
8710 }
8711 }
8712 else
8713 {
8714 goto done;
8715 }
8716
8717done:
8718 return ret;
8719}
8720
8721static int hdd_open_cesium_nl_sock()
8722{
8723#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
8724 struct netlink_kernel_cfg cfg = {
8725 .groups = WLAN_NLINK_MCAST_GRP_ID,
8726 .input = NULL
8727 };
8728#endif
8729 int ret = 0;
8730
8731#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
8732 cesium_nl_srv_sock = netlink_kernel_create(&init_net, WLAN_NLINK_CESIUM,
8733#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,7,0))
8734 THIS_MODULE,
8735#endif
8736 &cfg);
8737#else
8738 cesium_nl_srv_sock = netlink_kernel_create(&init_net, WLAN_NLINK_CESIUM,
8739 WLAN_NLINK_MCAST_GRP_ID, NULL, NULL, THIS_MODULE);
8740#endif
8741
8742 if (cesium_nl_srv_sock == NULL)
8743 {
8744 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8745 "NLINK: cesium netlink_kernel_create failed");
8746 ret = -ECONNREFUSED;
8747 }
8748
8749 return ret;
8750}
8751
8752static void hdd_close_cesium_nl_sock()
8753{
8754 if (NULL != cesium_nl_srv_sock)
8755 {
8756 netlink_kernel_release(cesium_nl_srv_sock);
8757 cesium_nl_srv_sock = NULL;
8758 }
8759}
8760#endif /* WLAN_FEATURE_RMC */
Jeff Johnson295189b2012-06-20 16:38:30 -07008761/**---------------------------------------------------------------------------
8762
8763 \brief hdd_req_bmps_cbk() - HDD Request BMPS callback function
8764
8765 This is the function invoked by SME to inform the result of BMPS
8766 request issued by HDD
8767
8768 \param - callbackcontext - Pointer to cookie
8769 status - result of request
8770
8771 \return - None
8772
8773--------------------------------------------------------------------------*/
8774void hdd_req_bmps_cbk(void *callbackContext, eHalStatus status)
8775{
8776
8777 struct completion *completion_var = (struct completion*) callbackContext;
8778
Arif Hussain6d2a3322013-11-17 19:50:10 -08008779 hddLog(VOS_TRACE_LEVEL_ERROR, "HDD BMPS request Callback, status = %d", status);
Jeff Johnson295189b2012-06-20 16:38:30 -07008780 if(completion_var != NULL)
8781 {
8782 complete(completion_var);
8783 }
8784}
8785
8786/**---------------------------------------------------------------------------
8787
8788 \brief hdd_get_cfg_file_size() -
8789
8790 This function reads the configuration file using the request firmware
8791 API and returns the configuration file size.
8792
8793 \param - pCtx - Pointer to the adapter .
8794 - pFileName - Pointer to the file name.
8795 - pBufSize - Pointer to the buffer size.
8796
8797 \return - 0 for success, non zero for failure
8798
8799 --------------------------------------------------------------------------*/
8800
8801VOS_STATUS hdd_get_cfg_file_size(v_VOID_t *pCtx, char *pFileName, v_SIZE_t *pBufSize)
8802{
8803 int status;
8804 hdd_context_t *pHddCtx = (hdd_context_t*)pCtx;
8805
8806 ENTER();
8807
8808 status = request_firmware(&pHddCtx->fw, pFileName, pHddCtx->parent_dev);
8809
8810 if(status || !pHddCtx->fw || !pHddCtx->fw->data) {
8811 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: CFG download failed",__func__);
8812 status = VOS_STATUS_E_FAILURE;
8813 }
8814 else {
8815 *pBufSize = pHddCtx->fw->size;
8816 hddLog(VOS_TRACE_LEVEL_INFO, "%s: CFG size = %d", __func__, *pBufSize);
8817 release_firmware(pHddCtx->fw);
8818 pHddCtx->fw = NULL;
8819 }
8820
8821 EXIT();
8822 return VOS_STATUS_SUCCESS;
8823}
8824
8825/**---------------------------------------------------------------------------
8826
8827 \brief hdd_read_cfg_file() -
8828
8829 This function reads the configuration file using the request firmware
8830 API and returns the cfg data and the buffer size of the configuration file.
8831
8832 \param - pCtx - Pointer to the adapter .
8833 - pFileName - Pointer to the file name.
8834 - pBuffer - Pointer to the data buffer.
8835 - pBufSize - Pointer to the buffer size.
8836
8837 \return - 0 for success, non zero for failure
8838
8839 --------------------------------------------------------------------------*/
8840
8841VOS_STATUS hdd_read_cfg_file(v_VOID_t *pCtx, char *pFileName,
8842 v_VOID_t *pBuffer, v_SIZE_t *pBufSize)
8843{
8844 int status;
8845 hdd_context_t *pHddCtx = (hdd_context_t*)pCtx;
8846
8847 ENTER();
8848
8849 status = request_firmware(&pHddCtx->fw, pFileName, pHddCtx->parent_dev);
8850
8851 if(status || !pHddCtx->fw || !pHddCtx->fw->data) {
8852 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: CFG download failed",__func__);
8853 return VOS_STATUS_E_FAILURE;
8854 }
8855 else {
8856 if(*pBufSize != pHddCtx->fw->size) {
8857 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Caller sets invalid CFG "
8858 "file size", __func__);
8859 release_firmware(pHddCtx->fw);
8860 pHddCtx->fw = NULL;
8861 return VOS_STATUS_E_FAILURE;
8862 }
8863 else {
8864 if(pBuffer) {
8865 vos_mem_copy(pBuffer,pHddCtx->fw->data,*pBufSize);
8866 }
8867 release_firmware(pHddCtx->fw);
8868 pHddCtx->fw = NULL;
8869 }
8870 }
8871
8872 EXIT();
8873
8874 return VOS_STATUS_SUCCESS;
8875}
8876
8877/**---------------------------------------------------------------------------
8878
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05308879 \brief __hdd_set_mac_address() -
Jeff Johnson295189b2012-06-20 16:38:30 -07008880
8881 This function sets the user specified mac address using
8882 the command ifconfig wlanX hw ether <mac adress>.
8883
8884 \param - dev - Pointer to the net device.
8885 - addr - Pointer to the sockaddr.
8886 \return - 0 for success, non zero for failure
8887
8888 --------------------------------------------------------------------------*/
8889
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05308890static int __hdd_set_mac_address(struct net_device *dev, void *addr)
Jeff Johnson295189b2012-06-20 16:38:30 -07008891{
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05308892 hdd_adapter_t *pAdapter;
8893 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07008894 struct sockaddr *psta_mac_addr = addr;
8895 eHalStatus halStatus = eHAL_STATUS_SUCCESS;
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05308896 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07008897
8898 ENTER();
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05308899 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
8900 if (NULL == pAdapter)
8901 {
8902 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8903 "%s: Adapter is NULL",__func__);
8904 return -EINVAL;
8905 }
8906 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8907 ret = wlan_hdd_validate_context(pHddCtx);
8908 if (0 != ret)
8909 {
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05308910 return ret;
8911 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008912
8913 memcpy(&pAdapter->macAddressCurrent, psta_mac_addr->sa_data, ETH_ALEN);
Jeff Johnson295189b2012-06-20 16:38:30 -07008914 memcpy(dev->dev_addr, psta_mac_addr->sa_data, ETH_ALEN);
8915
8916 EXIT();
8917 return halStatus;
8918}
8919
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05308920/**---------------------------------------------------------------------------
8921
8922 \brief hdd_set_mac_address() -
8923
8924 Wrapper function to protect __hdd_set_mac_address() function from ssr
8925
8926 \param - dev - Pointer to the net device.
8927 - addr - Pointer to the sockaddr.
8928 \return - 0 for success, non zero for failure
8929
8930 --------------------------------------------------------------------------*/
8931static int hdd_set_mac_address(struct net_device *dev, void *addr)
8932{
8933 int ret;
8934
8935 vos_ssr_protect(__func__);
8936 ret = __hdd_set_mac_address(dev, addr);
8937 vos_ssr_unprotect(__func__);
8938
8939 return ret;
8940}
8941
Jeff Johnson295189b2012-06-20 16:38:30 -07008942tANI_U8* wlan_hdd_get_intf_addr(hdd_context_t* pHddCtx)
8943{
8944 int i;
8945 for ( i = 0; i < VOS_MAX_CONCURRENCY_PERSONA; i++)
8946 {
Abhishek Singheb183782014-02-06 13:37:21 +05308947 if( 0 == ((pHddCtx->cfg_ini->intfAddrMask) & (1 << i)) )
Jeff Johnson295189b2012-06-20 16:38:30 -07008948 break;
8949 }
8950
8951 if( VOS_MAX_CONCURRENCY_PERSONA == i)
8952 return NULL;
8953
8954 pHddCtx->cfg_ini->intfAddrMask |= (1 << i);
8955 return &pHddCtx->cfg_ini->intfMacAddr[i].bytes[0];
8956}
8957
8958void wlan_hdd_release_intf_addr(hdd_context_t* pHddCtx, tANI_U8* releaseAddr)
8959{
8960 int i;
8961 for ( i = 0; i < VOS_MAX_CONCURRENCY_PERSONA; i++)
8962 {
8963 if ( !memcmp(releaseAddr, &pHddCtx->cfg_ini->intfMacAddr[i].bytes[0], 6) )
8964 {
8965 pHddCtx->cfg_ini->intfAddrMask &= ~(1 << i);
8966 break;
8967 }
8968 }
8969 return;
8970}
8971
8972#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29))
8973 static struct net_device_ops wlan_drv_ops = {
8974 .ndo_open = hdd_open,
8975 .ndo_stop = hdd_stop,
8976 .ndo_uninit = hdd_uninit,
8977 .ndo_start_xmit = hdd_hard_start_xmit,
8978 .ndo_tx_timeout = hdd_tx_timeout,
8979 .ndo_get_stats = hdd_stats,
8980 .ndo_do_ioctl = hdd_ioctl,
8981 .ndo_set_mac_address = hdd_set_mac_address,
8982 .ndo_select_queue = hdd_select_queue,
8983#ifdef WLAN_FEATURE_PACKET_FILTERING
8984#if (LINUX_VERSION_CODE > KERNEL_VERSION(3,1,0))
8985 .ndo_set_rx_mode = hdd_set_multicast_list,
8986#else
8987 .ndo_set_multicast_list = hdd_set_multicast_list,
8988#endif //LINUX_VERSION_CODE
8989#endif
8990 };
Jeff Johnson295189b2012-06-20 16:38:30 -07008991 static struct net_device_ops wlan_mon_drv_ops = {
8992 .ndo_open = hdd_mon_open,
Katya Nigame7b69a82015-04-28 15:24:06 +05308993 .ndo_stop = hdd_mon_stop,
Jeff Johnson295189b2012-06-20 16:38:30 -07008994 .ndo_uninit = hdd_uninit,
8995 .ndo_start_xmit = hdd_mon_hard_start_xmit,
8996 .ndo_tx_timeout = hdd_tx_timeout,
8997 .ndo_get_stats = hdd_stats,
Katya Nigame7b69a82015-04-28 15:24:06 +05308998 .ndo_do_ioctl = hdd_mon_ioctl,
Jeff Johnson295189b2012-06-20 16:38:30 -07008999 .ndo_set_mac_address = hdd_set_mac_address,
9000 };
Mahesh A Saptasagar305e2632015-03-04 12:57:33 +05309001
Jeff Johnson295189b2012-06-20 16:38:30 -07009002#endif
9003
9004void hdd_set_station_ops( struct net_device *pWlanDev )
9005{
9006#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29))
Jeff Johnson295189b2012-06-20 16:38:30 -07009007 pWlanDev->netdev_ops = &wlan_drv_ops;
9008#else
9009 pWlanDev->open = hdd_open;
9010 pWlanDev->stop = hdd_stop;
9011 pWlanDev->uninit = hdd_uninit;
9012 pWlanDev->hard_start_xmit = NULL;
9013 pWlanDev->tx_timeout = hdd_tx_timeout;
9014 pWlanDev->get_stats = hdd_stats;
9015 pWlanDev->do_ioctl = hdd_ioctl;
Jeff Johnson295189b2012-06-20 16:38:30 -07009016 pWlanDev->set_mac_address = hdd_set_mac_address;
9017#endif
9018}
9019
Katya Nigam1fd24402015-02-16 14:52:19 +05309020void hdd_set_ibss_ops( hdd_adapter_t *pAdapter )
9021{
9022 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29))
9023 wlan_drv_ops.ndo_start_xmit = hdd_ibss_hard_start_xmit;
9024 #else
9025 pAdapter->dev->hard_start_xmit = hdd_ibss_hard_start_xmit;
9026 #endif
9027}
9028
Jeff Johnsoneed415b2013-01-18 16:11:20 -08009029static hdd_adapter_t* hdd_alloc_station_adapter( hdd_context_t *pHddCtx, tSirMacAddr macAddr, const char* name )
Jeff Johnson295189b2012-06-20 16:38:30 -07009030{
9031 struct net_device *pWlanDev = NULL;
9032 hdd_adapter_t *pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07009033 /*
9034 * cfg80211 initialization and registration....
9035 */
Anand N Sunkadc34abbd2015-07-29 09:52:59 +05309036 pWlanDev = alloc_netdev_mq(sizeof( hdd_adapter_t ), name,
9037#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,17,0))
9038 NET_NAME_UNKNOWN,
9039#endif
9040 ether_setup, NUM_TX_QUEUES);
Jeff Johnson295189b2012-06-20 16:38:30 -07009041 if(pWlanDev != NULL)
9042 {
9043
9044 //Save the pointer to the net_device in the HDD adapter
9045 pAdapter = (hdd_adapter_t*) netdev_priv( pWlanDev );
9046
Jeff Johnson295189b2012-06-20 16:38:30 -07009047 vos_mem_zero( pAdapter, sizeof( hdd_adapter_t ) );
9048
9049 pAdapter->dev = pWlanDev;
9050 pAdapter->pHddCtx = pHddCtx;
9051 pAdapter->magic = WLAN_HDD_ADAPTER_MAGIC;
Agarwal Ashish47d18112014-08-04 19:55:07 +05309052 spin_lock_init(&pAdapter->lock_for_active_session);
Jeff Johnson295189b2012-06-20 16:38:30 -07009053
Rajeev79dbe4c2013-10-05 11:03:42 +05309054#ifdef FEATURE_WLAN_BATCH_SCAN
Rajeev79dbe4c2013-10-05 11:03:42 +05309055 pAdapter->pBatchScanRsp = NULL;
9056 pAdapter->numScanList = 0;
Rajeev Kumar20140c12013-10-21 19:39:02 -07009057 pAdapter->batchScanState = eHDD_BATCH_SCAN_STATE_STOPPED;
Kiet Lamaa8e15a2014-02-11 23:30:06 -08009058 pAdapter->prev_batch_id = 0;
Rajeev79dbe4c2013-10-05 11:03:42 +05309059 mutex_init(&pAdapter->hdd_batch_scan_lock);
9060#endif
9061
Jeff Johnson295189b2012-06-20 16:38:30 -07009062 pAdapter->isLinkUpSvcNeeded = FALSE;
9063 pAdapter->higherDtimTransition = eANI_BOOLEAN_TRUE;
9064 //Init the net_device structure
9065 strlcpy(pWlanDev->name, name, IFNAMSIZ);
9066
9067 vos_mem_copy(pWlanDev->dev_addr, (void *)macAddr, sizeof(tSirMacAddr));
9068 vos_mem_copy( pAdapter->macAddressCurrent.bytes, macAddr, sizeof(tSirMacAddr));
9069 pWlanDev->watchdog_timeo = HDD_TX_TIMEOUT;
Alok Kumar84458542018-05-14 15:03:08 +05309070
9071 pWlanDev->needed_headroom = LIBRA_HW_NEEDED_HEADROOM;
Jeff Johnson295189b2012-06-20 16:38:30 -07009072
9073 hdd_set_station_ops( pAdapter->dev );
9074
9075 pWlanDev->destructor = free_netdev;
Jeff Johnson295189b2012-06-20 16:38:30 -07009076 pWlanDev->ieee80211_ptr = &pAdapter->wdev ;
9077 pAdapter->wdev.wiphy = pHddCtx->wiphy;
9078 pAdapter->wdev.netdev = pWlanDev;
Jeff Johnson295189b2012-06-20 16:38:30 -07009079 /* set pWlanDev's parent to underlying device */
9080 SET_NETDEV_DEV(pWlanDev, pHddCtx->parent_dev);
Kumar Anand82c009f2014-05-29 00:29:42 -07009081
9082 hdd_wmm_init( pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -07009083 }
9084
9085 return pAdapter;
9086}
9087
9088VOS_STATUS hdd_register_interface( hdd_adapter_t *pAdapter, tANI_U8 rtnl_lock_held )
9089{
9090 struct net_device *pWlanDev = pAdapter->dev;
9091 //hdd_station_ctx_t *pHddStaCtx = &pAdapter->sessionCtx.station;
9092 //hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
9093 //eHalStatus halStatus = eHAL_STATUS_SUCCESS;
9094
9095 if( rtnl_lock_held )
9096 {
Madan Mohan Koyyalamudid8ac8662012-11-06 19:04:56 -08009097 if (strnchr(pWlanDev->name, strlen(pWlanDev->name), '%')) {
Jeff Johnson295189b2012-06-20 16:38:30 -07009098 if( dev_alloc_name(pWlanDev, pWlanDev->name) < 0 )
9099 {
9100 hddLog(VOS_TRACE_LEVEL_ERROR,"%s:Failed:dev_alloc_name",__func__);
9101 return VOS_STATUS_E_FAILURE;
9102 }
9103 }
9104 if (register_netdevice(pWlanDev))
9105 {
9106 hddLog(VOS_TRACE_LEVEL_ERROR,"%s:Failed:register_netdev",__func__);
9107 return VOS_STATUS_E_FAILURE;
9108 }
9109 }
9110 else
9111 {
9112 if(register_netdev(pWlanDev))
9113 {
9114 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Failed:register_netdev",__func__);
9115 return VOS_STATUS_E_FAILURE;
9116 }
9117 }
9118 set_bit(NET_DEVICE_REGISTERED, &pAdapter->event_flags);
9119
9120 return VOS_STATUS_SUCCESS;
9121}
9122
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07009123static eHalStatus hdd_smeCloseSessionCallback(void *pContext)
Jeff Johnson295189b2012-06-20 16:38:30 -07009124{
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07009125 hdd_adapter_t *pAdapter = pContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07009126
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07009127 if (NULL == pAdapter)
9128 {
9129 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: NULL pAdapter", __func__);
9130 return eHAL_STATUS_INVALID_PARAMETER;
Jeff Johnson295189b2012-06-20 16:38:30 -07009131 }
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07009132
9133 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
9134 {
9135 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Invalid magic", __func__);
9136 return eHAL_STATUS_NOT_INITIALIZED;
9137 }
9138
9139 clear_bit(SME_SESSION_OPENED, &pAdapter->event_flags);
9140
Sameer Thalappilbee426e2013-10-30 10:30:30 -07009141#ifndef WLAN_OPEN_SOURCE
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07009142 /* need to make sure all of our scheduled work has completed.
9143 * This callback is called from MC thread context, so it is safe to
9144 * to call below flush workqueue API from here.
Sameer Thalappilbee426e2013-10-30 10:30:30 -07009145 *
9146 * Even though this is called from MC thread context, if there is a faulty
9147 * work item in the system, that can hang this call forever. So flushing
9148 * this global work queue is not safe; and now we make sure that
9149 * individual work queues are stopped correctly. But the cancel work queue
9150 * is a GPL only API, so the proprietary version of the driver would still
9151 * rely on the global work queue flush.
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07009152 */
9153 flush_scheduled_work();
Sameer Thalappilbee426e2013-10-30 10:30:30 -07009154#endif
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07009155
9156 /* We can be blocked while waiting for scheduled work to be
9157 * flushed, and the adapter structure can potentially be freed, in
9158 * which case the magic will have been reset. So make sure the
9159 * magic is still good, and hence the adapter structure is still
9160 * valid, before signaling completion */
9161 if (WLAN_HDD_ADAPTER_MAGIC == pAdapter->magic)
9162 {
9163 complete(&pAdapter->session_close_comp_var);
9164 }
9165
Jeff Johnson295189b2012-06-20 16:38:30 -07009166 return eHAL_STATUS_SUCCESS;
9167}
Manjeet Singh47ee8472016-04-11 11:57:18 +05309168/**
9169 * hdd_close_tx_queues() - close tx queues
9170 * @hdd_ctx: hdd global context
9171 *
9172 * Return: None
9173 */
9174static void hdd_close_tx_queues(hdd_context_t *hdd_ctx)
9175{
9176 VOS_STATUS status;
9177 hdd_adapter_t *adapter;
9178 hdd_adapter_list_node_t *adapter_node = NULL, *next_adapter = NULL;
9179 /* Not validating hdd_ctx as it's already done by the caller */
9180 ENTER();
9181 status = hdd_get_front_adapter(hdd_ctx, &adapter_node);
9182 while (NULL != adapter_node && VOS_STATUS_SUCCESS == status) {
9183 adapter = adapter_node->pAdapter;
9184 if (adapter && adapter->dev) {
9185 netif_tx_disable (adapter->dev);
9186 netif_carrier_off(adapter->dev);
9187 }
9188 status = hdd_get_next_adapter(hdd_ctx, adapter_node,
9189 &next_adapter);
9190 adapter_node = next_adapter;
9191 }
9192 EXIT();
9193}
Jeff Johnson295189b2012-06-20 16:38:30 -07009194
9195VOS_STATUS hdd_init_station_mode( hdd_adapter_t *pAdapter )
9196{
9197 struct net_device *pWlanDev = pAdapter->dev;
9198 hdd_station_ctx_t *pHddStaCtx = &pAdapter->sessionCtx.station;
9199 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
9200 eHalStatus halStatus = eHAL_STATUS_SUCCESS;
9201 VOS_STATUS status = VOS_STATUS_E_FAILURE;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309202 long rc = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07009203
Nirav Shah7e3c8132015-06-22 23:51:42 +05309204 spin_lock_init( &pAdapter->sta_hash_lock);
9205 pAdapter->is_sta_id_hash_initialized = VOS_FALSE;
9206
Jeff Johnson295189b2012-06-20 16:38:30 -07009207 INIT_COMPLETION(pAdapter->session_open_comp_var);
Kiran Kumar Lokere0ad5cd32013-06-25 11:26:22 -07009208 sme_SetCurrDeviceMode(pHddCtx->hHal, pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07009209 //Open a SME session for future operation
9210 halStatus = sme_OpenSession( pHddCtx->hHal, hdd_smeRoamCallback, pAdapter,
Kiran Kumar Lokere0ad5cd32013-06-25 11:26:22 -07009211 (tANI_U8 *)&pAdapter->macAddressCurrent, &pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07009212 if ( !HAL_STATUS_SUCCESS( halStatus ) )
9213 {
9214 hddLog(VOS_TRACE_LEVEL_FATAL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07009215 "sme_OpenSession() failed with status code %08d [x%08x]",
Jeff Johnson295189b2012-06-20 16:38:30 -07009216 halStatus, halStatus );
9217 status = VOS_STATUS_E_FAILURE;
9218 goto error_sme_open;
9219 }
9220
9221 //Block on a completion variable. Can't wait forever though.
Vinay Krishna Eranna0fe2e7c2014-04-09 21:32:08 +05309222 rc = wait_for_completion_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -07009223 &pAdapter->session_open_comp_var,
9224 msecs_to_jiffies(WLAN_WAIT_TIME_SESSIONOPENCLOSE));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309225 if (rc <= 0)
Jeff Johnson295189b2012-06-20 16:38:30 -07009226 {
9227 hddLog(VOS_TRACE_LEVEL_FATAL,
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309228 "Session is not opened within timeout period code %ld", rc );
Jeff Johnson295189b2012-06-20 16:38:30 -07009229 status = VOS_STATUS_E_FAILURE;
9230 goto error_sme_open;
9231 }
9232
9233 // Register wireless extensions
9234 if( eHAL_STATUS_SUCCESS != (halStatus = hdd_register_wext(pWlanDev)))
9235 {
9236 hddLog(VOS_TRACE_LEVEL_FATAL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07009237 "hdd_register_wext() failed with status code %08d [x%08x]",
Jeff Johnson295189b2012-06-20 16:38:30 -07009238 halStatus, halStatus );
9239 status = VOS_STATUS_E_FAILURE;
9240 goto error_register_wext;
9241 }
Katya Nigam1fd24402015-02-16 14:52:19 +05309242
Jeff Johnson295189b2012-06-20 16:38:30 -07009243 //Safe to register the hard_start_xmit function again
Katya Nigam1fd24402015-02-16 14:52:19 +05309244 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29))
9245 wlan_drv_ops.ndo_start_xmit = hdd_hard_start_xmit;
9246 #else
9247 pWlanDev->hard_start_xmit = hdd_hard_start_xmit;
9248 #endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009249
9250 //Set the Connection State to Not Connected
Abhishek Singhf4669da2014-05-26 15:07:49 +05309251 hddLog(VOS_TRACE_LEVEL_INFO,
9252 "%s: Set HDD connState to eConnectionState_NotConnected",
9253 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009254 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
9255
9256 //Set the default operation channel
9257 pHddStaCtx->conn_info.operationChannel = pHddCtx->cfg_ini->OperatingChannel;
9258
9259 /* Make the default Auth Type as OPEN*/
9260 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_OPEN_SYSTEM;
9261
9262 if( VOS_STATUS_SUCCESS != ( status = hdd_init_tx_rx( pAdapter ) ) )
9263 {
9264 hddLog(VOS_TRACE_LEVEL_FATAL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07009265 "hdd_init_tx_rx() failed with status code %08d [x%08x]",
Jeff Johnson295189b2012-06-20 16:38:30 -07009266 status, status );
9267 goto error_init_txrx;
9268 }
9269
9270 set_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
9271
9272 if( VOS_STATUS_SUCCESS != ( status = hdd_wmm_adapter_init( pAdapter ) ) )
9273 {
9274 hddLog(VOS_TRACE_LEVEL_FATAL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07009275 "hdd_wmm_adapter_init() failed with status code %08d [x%08x]",
Jeff Johnson295189b2012-06-20 16:38:30 -07009276 status, status );
9277 goto error_wmm_init;
9278 }
9279
9280 set_bit(WMM_INIT_DONE, &pAdapter->event_flags);
9281
9282 return VOS_STATUS_SUCCESS;
9283
9284error_wmm_init:
9285 clear_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
9286 hdd_deinit_tx_rx(pAdapter);
9287error_init_txrx:
9288 hdd_UnregisterWext(pWlanDev);
9289error_register_wext:
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07009290 if (test_bit(SME_SESSION_OPENED, &pAdapter->event_flags))
Jeff Johnson295189b2012-06-20 16:38:30 -07009291 {
9292 INIT_COMPLETION(pAdapter->session_close_comp_var);
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07009293 if (eHAL_STATUS_SUCCESS == sme_CloseSession(pHddCtx->hHal,
Agrawal Ashish5a3522c2016-03-02 15:08:28 +05309294 pAdapter->sessionId, FALSE, VOS_TRUE,
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07009295 hdd_smeCloseSessionCallback, pAdapter))
Jeff Johnson295189b2012-06-20 16:38:30 -07009296 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309297 unsigned long rc;
9298
Jeff Johnson295189b2012-06-20 16:38:30 -07009299 //Block on a completion variable. Can't wait forever though.
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309300 rc = wait_for_completion_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -07009301 &pAdapter->session_close_comp_var,
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07009302 msecs_to_jiffies(WLAN_WAIT_TIME_SESSIONOPENCLOSE));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309303 if (rc <= 0)
9304 hddLog(VOS_TRACE_LEVEL_ERROR,
9305 FL("Session is not opened within timeout period code %ld"), rc);
Jeff Johnson295189b2012-06-20 16:38:30 -07009306 }
9307}
9308error_sme_open:
9309 return status;
9310}
9311
Jeff Johnson295189b2012-06-20 16:38:30 -07009312void hdd_cleanup_actionframe( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter )
9313{
9314 hdd_cfg80211_state_t *cfgState;
9315
9316 cfgState = WLAN_HDD_GET_CFG_STATE_PTR( pAdapter );
9317
9318 if( NULL != cfgState->buf )
9319 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309320 long rc;
Jeff Johnson295189b2012-06-20 16:38:30 -07009321 INIT_COMPLETION(pAdapter->tx_action_cnf_event);
9322 rc = wait_for_completion_interruptible_timeout(
9323 &pAdapter->tx_action_cnf_event,
9324 msecs_to_jiffies(ACTION_FRAME_TX_TIMEOUT));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309325 if (rc <= 0)
Jeff Johnson295189b2012-06-20 16:38:30 -07009326 {
Deepthi Gowri91b3e9c2015-08-25 13:14:58 +05309327 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9328 "%s ERROR: HDD Wait for Action Confirmation Failed!! %ld"
9329 , __func__, rc);
9330
9331 // Inform tx status as FAILURE to upper layer and free cfgState->buf
9332 hdd_sendActionCnf( pAdapter, FALSE );
Jeff Johnson295189b2012-06-20 16:38:30 -07009333 }
9334 }
9335 return;
9336}
Jeff Johnson295189b2012-06-20 16:38:30 -07009337
c_hpothu002231a2015-02-05 14:58:51 +05309338void hdd_deinit_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter, tANI_U8 rtnl_held )
Jeff Johnson295189b2012-06-20 16:38:30 -07009339{
9340 ENTER();
9341 switch ( pAdapter->device_mode )
9342 {
Katya Nigam1fd24402015-02-16 14:52:19 +05309343 case WLAN_HDD_IBSS:
9344 {
9345 if(test_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags))
9346 {
9347 hdd_ibss_deinit_tx_rx( pAdapter );
9348 clear_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
9349 }
9350 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009351 case WLAN_HDD_INFRA_STATION:
9352 case WLAN_HDD_P2P_CLIENT:
Jeff Johnsone7245742012-09-05 17:12:55 -07009353 case WLAN_HDD_P2P_DEVICE:
Jeff Johnson295189b2012-06-20 16:38:30 -07009354 {
9355 if(test_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags))
9356 {
9357 hdd_deinit_tx_rx( pAdapter );
9358 clear_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
9359 }
9360
9361 if(test_bit(WMM_INIT_DONE, &pAdapter->event_flags))
9362 {
9363 hdd_wmm_adapter_close( pAdapter );
9364 clear_bit(WMM_INIT_DONE, &pAdapter->event_flags);
9365 }
9366
Jeff Johnson295189b2012-06-20 16:38:30 -07009367 hdd_cleanup_actionframe(pHddCtx, pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07009368 break;
9369 }
9370
9371 case WLAN_HDD_SOFTAP:
9372 case WLAN_HDD_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07009373 {
Madan Mohan Koyyalamudi8c6dec82013-09-26 15:56:13 +05309374
9375 if (test_bit(WMM_INIT_DONE, &pAdapter->event_flags))
9376 {
9377 hdd_wmm_adapter_close( pAdapter );
9378 clear_bit(WMM_INIT_DONE, &pAdapter->event_flags);
9379 }
9380
Jeff Johnson295189b2012-06-20 16:38:30 -07009381 hdd_cleanup_actionframe(pHddCtx, pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07009382
c_hpothu002231a2015-02-05 14:58:51 +05309383 hdd_unregister_hostapd(pAdapter, rtnl_held);
Agrawal Ashisha0584d42016-09-29 13:03:45 +05309384 /* set con_mode to STA only when no SAP concurrency mode */
9385 if (!(hdd_get_concurrency_mode() & (VOS_SAP | VOS_P2P_GO)))
9386 hdd_set_conparam(0);
Jeff Johnson295189b2012-06-20 16:38:30 -07009387 break;
9388 }
9389
9390 case WLAN_HDD_MONITOR:
9391 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009392 if(test_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags))
9393 {
9394 hdd_deinit_tx_rx( pAdapter );
9395 clear_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
9396 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009397 break;
9398 }
9399
9400
9401 default:
9402 break;
9403 }
9404
9405 EXIT();
9406}
9407
9408void hdd_cleanup_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter, tANI_U8 rtnl_held )
9409{
Mingcheng Zhu87f22fc2014-01-30 19:23:32 -08009410 struct net_device *pWlanDev = NULL;
Srinivas, Dasari693dfc52013-12-27 17:29:09 +05309411
9412 ENTER();
9413 if (NULL == pAdapter)
9414 {
9415 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9416 "%s: HDD adapter is Null", __func__);
9417 return;
9418 }
9419
9420 pWlanDev = pAdapter->dev;
Jeff Johnson295189b2012-06-20 16:38:30 -07009421
Rajeev79dbe4c2013-10-05 11:03:42 +05309422#ifdef FEATURE_WLAN_BATCH_SCAN
Srinivas, Dasari693dfc52013-12-27 17:29:09 +05309423 if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
9424 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Rajeev Kumarf999e582014-01-09 17:33:29 -08009425 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Srinivas, Dasari693dfc52013-12-27 17:29:09 +05309426 || (pAdapter->device_mode == WLAN_HDD_P2P_DEVICE)
9427 )
9428 {
Rajeev Kumarf999e582014-01-09 17:33:29 -08009429 if (pAdapter)
Rajeev79dbe4c2013-10-05 11:03:42 +05309430 {
Rajeev Kumarf999e582014-01-09 17:33:29 -08009431 if (eHDD_BATCH_SCAN_STATE_STARTED == pAdapter->batchScanState)
9432 {
9433 hdd_deinit_batch_scan(pAdapter);
9434 }
Rajeev79dbe4c2013-10-05 11:03:42 +05309435 }
Rajeev Kumarf999e582014-01-09 17:33:29 -08009436 }
Rajeev79dbe4c2013-10-05 11:03:42 +05309437#endif
9438
Jeff Johnson295189b2012-06-20 16:38:30 -07009439 if(test_bit(NET_DEVICE_REGISTERED, &pAdapter->event_flags)) {
9440 if( rtnl_held )
9441 {
9442 unregister_netdevice(pWlanDev);
9443 }
9444 else
9445 {
9446 unregister_netdev(pWlanDev);
9447 }
9448 // note that the pAdapter is no longer valid at this point
9449 // since the memory has been reclaimed
9450 }
9451
Srinivas, Dasari693dfc52013-12-27 17:29:09 +05309452 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07009453}
9454
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08009455void hdd_set_pwrparams(hdd_context_t *pHddCtx)
9456{
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05309457 VOS_STATUS status;
9458 hdd_adapter_t *pAdapter = NULL;
9459 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08009460
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05309461 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08009462
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05309463 /*loop through all adapters.*/
9464 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08009465 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05309466 pAdapter = pAdapterNode->pAdapter;
9467 if ( (WLAN_HDD_INFRA_STATION != pAdapter->device_mode)
9468 && (WLAN_HDD_P2P_CLIENT != pAdapter->device_mode) )
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08009469
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05309470 { // we skip this registration for modes other than STA and P2P client modes.
9471 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
9472 pAdapterNode = pNext;
9473 continue;
9474 }
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08009475
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05309476 //Apply Dynamic DTIM For P2P
9477 //Only if ignoreDynamicDtimInP2pMode is not set in ini
9478 if ((pHddCtx->cfg_ini->enableDynamicDTIM ||
9479 pHddCtx->cfg_ini->enableModulatedDTIM) &&
9480 ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
9481 ((WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) &&
9482 !(pHddCtx->cfg_ini->ignoreDynamicDtimInP2pMode))) &&
9483 (eANI_BOOLEAN_TRUE == pAdapter->higherDtimTransition) &&
9484 (eConnectionState_Associated ==
9485 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState) &&
9486 (pHddCtx->cfg_ini->fIsBmpsEnabled))
9487 {
9488 tSirSetPowerParamsReq powerRequest = { 0 };
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08009489
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05309490 powerRequest.uIgnoreDTIM = 1;
9491 powerRequest.uMaxLIModulatedDTIM = pHddCtx->cfg_ini->fMaxLIModulatedDTIM;
9492
9493 if (pHddCtx->cfg_ini->enableModulatedDTIM)
9494 {
9495 powerRequest.uDTIMPeriod = pHddCtx->cfg_ini->enableModulatedDTIM;
9496 powerRequest.uListenInterval = pHddCtx->hdd_actual_LI_value;
9497 }
9498 else
9499 {
9500 powerRequest.uListenInterval = pHddCtx->cfg_ini->enableDynamicDTIM;
9501 }
9502
9503 /* Update ignoreDTIM and ListedInterval in CFG to remain at the DTIM
9504 * specified during Enter/Exit BMPS when LCD off*/
9505 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IGNORE_DTIM, powerRequest.uIgnoreDTIM,
9506 NULL, eANI_BOOLEAN_FALSE);
9507 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_LISTEN_INTERVAL, powerRequest.uListenInterval,
9508 NULL, eANI_BOOLEAN_FALSE);
9509
9510 /* switch to the DTIM specified in cfg.ini */
9511 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Abhishek Singh1e390cf2015-10-27 13:45:17 +05309512 "Switch to DTIM %d Listen interval %d",
9513 powerRequest.uDTIMPeriod,
9514 powerRequest.uListenInterval);
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05309515 sme_SetPowerParams( pHddCtx->hHal, &powerRequest, TRUE);
9516 break;
9517
9518 }
9519
9520 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
9521 pAdapterNode = pNext;
9522 }
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08009523}
9524
9525void hdd_reset_pwrparams(hdd_context_t *pHddCtx)
9526{
9527 /*Switch back to DTIM 1*/
9528 tSirSetPowerParamsReq powerRequest = { 0 };
9529
9530 powerRequest.uIgnoreDTIM = pHddCtx->hdd_actual_ignore_DTIM_value;
9531 powerRequest.uListenInterval = pHddCtx->hdd_actual_LI_value;
Yue Mac24062f2013-05-13 17:01:29 -07009532 powerRequest.uMaxLIModulatedDTIM = pHddCtx->cfg_ini->fMaxLIModulatedDTIM;
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08009533
9534 /* Update ignoreDTIM and ListedInterval in CFG with default values */
9535 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IGNORE_DTIM, powerRequest.uIgnoreDTIM,
9536 NULL, eANI_BOOLEAN_FALSE);
9537 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_LISTEN_INTERVAL, powerRequest.uListenInterval,
9538 NULL, eANI_BOOLEAN_FALSE);
9539
9540 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
9541 "Switch to DTIM%d",powerRequest.uListenInterval);
9542 sme_SetPowerParams( pHddCtx->hHal, &powerRequest, TRUE);
9543
9544}
9545
Jeff Johnson295189b2012-06-20 16:38:30 -07009546VOS_STATUS hdd_enable_bmps_imps(hdd_context_t *pHddCtx)
9547{
9548 VOS_STATUS status = VOS_STATUS_SUCCESS;
Sushant Kaushik4928e542014-12-29 15:25:54 +05309549 if (WLAN_HDD_IS_UNLOAD_IN_PROGRESS(pHddCtx))
9550 {
9551 hddLog( LOGE, FL("Wlan Unload in progress"));
9552 return VOS_STATUS_E_PERM;
9553 }
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +05309554
9555 if (wlan_hdd_check_monitor_state(pHddCtx)) {
9556 hddLog(LOG1, FL("Monitor mode is started, cannot enable BMPS"));
9557 return VOS_STATUS_SUCCESS;
9558 }
9559
Jeff Johnson295189b2012-06-20 16:38:30 -07009560 if(pHddCtx->cfg_ini->fIsBmpsEnabled)
9561 {
9562 sme_EnablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
9563 }
9564
9565 if(pHddCtx->cfg_ini->fIsAutoBmpsTimerEnabled)
9566 {
9567 sme_StartAutoBmpsTimer(pHddCtx->hHal);
9568 }
9569
9570 if (pHddCtx->cfg_ini->fIsImpsEnabled)
9571 {
9572 sme_EnablePowerSave (pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
9573 }
9574
9575 return status;
9576}
9577
9578VOS_STATUS hdd_disable_bmps_imps(hdd_context_t *pHddCtx, tANI_U8 session_type)
9579{
9580 hdd_adapter_t *pAdapter = NULL;
9581 eHalStatus halStatus;
9582 VOS_STATUS status = VOS_STATUS_E_INVAL;
9583 v_BOOL_t disableBmps = FALSE;
9584 v_BOOL_t disableImps = FALSE;
9585
9586 switch(session_type)
9587 {
9588 case WLAN_HDD_INFRA_STATION:
9589 case WLAN_HDD_SOFTAP:
Jeff Johnson295189b2012-06-20 16:38:30 -07009590 case WLAN_HDD_P2P_CLIENT:
9591 case WLAN_HDD_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07009592 //Exit BMPS -> Is Sta/P2P Client is already connected
9593 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION);
9594 if((NULL != pAdapter)&&
9595 hdd_connIsConnected( WLAN_HDD_GET_STATION_CTX_PTR(pAdapter)))
9596 {
9597 disableBmps = TRUE;
9598 }
9599
9600 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_CLIENT);
9601 if((NULL != pAdapter)&&
9602 hdd_connIsConnected( WLAN_HDD_GET_STATION_CTX_PTR(pAdapter)))
9603 {
9604 disableBmps = TRUE;
9605 }
9606
9607 //Exit both Bmps and Imps incase of Go/SAP Mode
9608 if((WLAN_HDD_SOFTAP == session_type) ||
9609 (WLAN_HDD_P2P_GO == session_type))
9610 {
9611 disableBmps = TRUE;
9612 disableImps = TRUE;
9613 }
9614
9615 if(TRUE == disableImps)
9616 {
9617 if (pHddCtx->cfg_ini->fIsImpsEnabled)
9618 {
9619 sme_DisablePowerSave (pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
9620 }
9621 }
9622
9623 if(TRUE == disableBmps)
9624 {
9625 if(pHddCtx->cfg_ini->fIsBmpsEnabled)
9626 {
9627 halStatus = sme_DisablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
9628
9629 if(eHAL_STATUS_SUCCESS != halStatus)
9630 {
9631 status = VOS_STATUS_E_FAILURE;
Arif Hussain6d2a3322013-11-17 19:50:10 -08009632 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Fail to Disable Power Save", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009633 VOS_ASSERT(0);
9634 return status;
9635 }
9636 }
9637
9638 if(pHddCtx->cfg_ini->fIsAutoBmpsTimerEnabled)
9639 {
9640 halStatus = sme_StopAutoBmpsTimer(pHddCtx->hHal);
9641
9642 if(eHAL_STATUS_SUCCESS != halStatus)
9643 {
9644 status = VOS_STATUS_E_FAILURE;
Arif Hussain6d2a3322013-11-17 19:50:10 -08009645 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Fail to Stop Auto Bmps Timer", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009646 VOS_ASSERT(0);
9647 return status;
9648 }
9649 }
9650 }
9651
9652 if((TRUE == disableBmps) ||
9653 (TRUE == disableImps))
9654 {
9655 /* Now, get the chip into Full Power now */
9656 INIT_COMPLETION(pHddCtx->full_pwr_comp_var);
9657 halStatus = sme_RequestFullPower(pHddCtx->hHal, hdd_full_pwr_cbk,
9658 pHddCtx, eSME_FULL_PWR_NEEDED_BY_HDD);
9659
9660 if(halStatus != eHAL_STATUS_SUCCESS)
9661 {
9662 if(halStatus == eHAL_STATUS_PMC_PENDING)
9663 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309664 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07009665 //Block on a completion variable. Can't wait forever though
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309666 ret = wait_for_completion_interruptible_timeout(
9667 &pHddCtx->full_pwr_comp_var,
9668 msecs_to_jiffies(1000));
9669 if (ret <= 0)
9670 {
9671 hddLog(VOS_TRACE_LEVEL_ERROR,
9672 "%s: wait on full_pwr_comp_var failed %ld",
9673 __func__, ret);
9674 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009675 }
9676 else
9677 {
9678 status = VOS_STATUS_E_FAILURE;
Arif Hussain6d2a3322013-11-17 19:50:10 -08009679 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Request for Full Power failed", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009680 VOS_ASSERT(0);
9681 return status;
9682 }
9683 }
9684
9685 status = VOS_STATUS_SUCCESS;
9686 }
9687
9688 break;
9689 }
9690 return status;
9691}
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +05309692
Hanumanth Reddy Pothulab8be9ab2018-04-12 20:03:05 +05309693void hdd_mon_post_msg_cb(void *context)
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +05309694{
Hanumanth Reddy Pothulab8be9ab2018-04-12 20:03:05 +05309695 struct hdd_request *request;
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +05309696
Hanumanth Reddy Pothulab8be9ab2018-04-12 20:03:05 +05309697 request = hdd_request_get(context);
9698 if (!request) {
9699 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Obsolete request"));
9700 return;
9701 }
9702
9703 hdd_request_complete(request);
9704 hdd_request_put(request);
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +05309705}
9706
Hanumanth Reddy Pothulab8be9ab2018-04-12 20:03:05 +05309707
Katya Nigame7b69a82015-04-28 15:24:06 +05309708void hdd_init_mon_mode (hdd_adapter_t *pAdapter)
9709 {
9710 hdd_mon_ctx_t *pMonCtx = NULL;
Katya Nigame7b69a82015-04-28 15:24:06 +05309711
Rajeev Kumar Sirasanagandla54447612018-03-06 15:49:56 +05309712 spin_lock_init(&pAdapter->sta_hash_lock);
9713 pAdapter->is_sta_id_hash_initialized = VOS_FALSE;
9714
9715 pMonCtx = WLAN_HDD_GET_MONITOR_CTX_PTR(pAdapter);
Katya Nigame7b69a82015-04-28 15:24:06 +05309716 pMonCtx->state = 0;
9717 pMonCtx->ChannelNo = 1;
9718 pMonCtx->ChannelBW = 20;
Katya Nigamd7d3a1f2015-06-11 14:04:24 +05309719 pMonCtx->crcCheckEnabled = 1;
9720 pMonCtx->typeSubtypeBitmap = 0xFFFF00000000;
9721 pMonCtx->is80211to803ConReq = 1;
Katya Nigame7b69a82015-04-28 15:24:06 +05309722 pMonCtx->numOfMacFilters = 0;
9723 }
9724
Jeff Johnson295189b2012-06-20 16:38:30 -07009725
9726hdd_adapter_t* hdd_open_adapter( hdd_context_t *pHddCtx, tANI_U8 session_type,
Jeff Johnsoneed415b2013-01-18 16:11:20 -08009727 const char *iface_name, tSirMacAddr macAddr,
Jeff Johnson295189b2012-06-20 16:38:30 -07009728 tANI_U8 rtnl_held )
9729{
9730 hdd_adapter_t *pAdapter = NULL;
9731 hdd_adapter_list_node_t *pHddAdapterNode = NULL;
9732 VOS_STATUS status = VOS_STATUS_E_FAILURE;
9733 VOS_STATUS exitbmpsStatus;
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +05309734 v_CONTEXT_t pVosContext = NULL;
9735
9736 /* No need to check for NULL, reaching this step
9737 * means vos context is initialized
9738 */
9739 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
Jeff Johnson295189b2012-06-20 16:38:30 -07009740
Arif Hussain6d2a3322013-11-17 19:50:10 -08009741 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s iface =%s type = %d",__func__,iface_name,session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07009742
Nirav Shah436658f2014-02-28 17:05:45 +05309743 if(macAddr == NULL)
9744 {
9745 /* Not received valid macAddr */
9746 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9747 "%s:Unable to add virtual intf: Not able to get"
9748 "valid mac address",__func__);
9749 return NULL;
9750 }
9751
Jeff Johnson295189b2012-06-20 16:38:30 -07009752 //Disable BMPS incase of Concurrency
9753 exitbmpsStatus = hdd_disable_bmps_imps(pHddCtx, session_type);
9754
9755 if(VOS_STATUS_E_FAILURE == exitbmpsStatus)
9756 {
9757 //Fail to Exit BMPS
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309758 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Fail to Exit BMPS", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009759 VOS_ASSERT(0);
9760 return NULL;
9761 }
9762
9763 switch(session_type)
9764 {
9765 case WLAN_HDD_INFRA_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -07009766 case WLAN_HDD_P2P_CLIENT:
Jeff Johnsone7245742012-09-05 17:12:55 -07009767 case WLAN_HDD_P2P_DEVICE:
Jeff Johnson295189b2012-06-20 16:38:30 -07009768 {
9769 pAdapter = hdd_alloc_station_adapter( pHddCtx, macAddr, iface_name );
9770
9771 if( NULL == pAdapter )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309772 {
9773 hddLog(VOS_TRACE_LEVEL_FATAL,
9774 FL("failed to allocate adapter for session %d"), session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07009775 return NULL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309776 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009777
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05309778#ifdef FEATURE_WLAN_TDLS
9779 /* A Mutex Lock is introduced while changing/initializing the mode to
9780 * protect the concurrent access for the Adapters by TDLS module.
9781 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05309782 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05309783#endif
9784
Jeff Johnsone7245742012-09-05 17:12:55 -07009785 pAdapter->wdev.iftype = (session_type == WLAN_HDD_P2P_CLIENT) ?
9786 NL80211_IFTYPE_P2P_CLIENT:
9787 NL80211_IFTYPE_STATION;
Jeff Johnson295189b2012-06-20 16:38:30 -07009788
Jeff Johnson295189b2012-06-20 16:38:30 -07009789 pAdapter->device_mode = session_type;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05309790#ifdef FEATURE_WLAN_TDLS
9791 mutex_unlock(&pHddCtx->tdls_lock);
9792#endif
Sunil Dutt66485cb2013-12-19 19:05:03 +05309793
Mahesh A Saptasagar67ab9222015-10-21 15:38:41 +05309794 hdd_initialize_adapter_common(pAdapter);
Sunil Dutt66485cb2013-12-19 19:05:03 +05309795 status = hdd_init_station_mode( pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -07009796 if( VOS_STATUS_SUCCESS != status )
9797 goto err_free_netdev;
9798
9799 status = hdd_register_interface( pAdapter, rtnl_held );
9800 if( VOS_STATUS_SUCCESS != status )
9801 {
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05309802#ifdef FEATURE_WLAN_TDLS
9803 mutex_lock(&pHddCtx->tdls_lock);
9804#endif
c_hpothu002231a2015-02-05 14:58:51 +05309805 hdd_deinit_adapter(pHddCtx, pAdapter, rtnl_held);
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05309806#ifdef FEATURE_WLAN_TDLS
9807 mutex_unlock(&pHddCtx->tdls_lock);
9808#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009809 goto err_free_netdev;
9810 }
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05309811
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +05309812 // Workqueue which gets scheduled in IPv4 notification callback.
Anand N Sunkaddc63c792015-06-03 14:33:24 +05309813 vos_init_work(&pAdapter->ipv4NotifierWorkQueue, hdd_ipv4_notifier_work_queue);
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +05309814
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05309815#ifdef WLAN_NS_OFFLOAD
9816 // Workqueue which gets scheduled in IPv6 notification callback.
Anand N Sunkaddc63c792015-06-03 14:33:24 +05309817 vos_init_work(&pAdapter->ipv6NotifierWorkQueue, hdd_ipv6_notifier_work_queue);
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05309818#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009819 //Stop the Interface TX queue.
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +05309820 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Jeff Johnson295189b2012-06-20 16:38:30 -07009821 netif_tx_disable(pAdapter->dev);
9822 //netif_tx_disable(pWlanDev);
9823 netif_carrier_off(pAdapter->dev);
9824
Ganesh Kondabattinibabfb492014-12-17 20:25:29 +05309825 if (WLAN_HDD_P2P_CLIENT == session_type ||
9826 WLAN_HDD_P2P_DEVICE == session_type)
9827 {
9828 /* Initialize the work queue to defer the
9829 * back to back RoC request */
Anand N Sunkaddc63c792015-06-03 14:33:24 +05309830 vos_init_delayed_work(&pAdapter->roc_work,
Ganesh Kondabattinibabfb492014-12-17 20:25:29 +05309831 hdd_p2p_roc_work_queue);
9832 }
9833
Jeff Johnson295189b2012-06-20 16:38:30 -07009834 break;
9835 }
9836
Jeff Johnson295189b2012-06-20 16:38:30 -07009837 case WLAN_HDD_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07009838 case WLAN_HDD_SOFTAP:
9839 {
9840 pAdapter = hdd_wlan_create_ap_dev( pHddCtx, macAddr, (tANI_U8 *)iface_name );
9841 if( NULL == pAdapter )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309842 {
9843 hddLog(VOS_TRACE_LEVEL_FATAL,
9844 FL("failed to allocate adapter for session %d"), session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07009845 return NULL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309846 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009847
Jeff Johnson295189b2012-06-20 16:38:30 -07009848 pAdapter->wdev.iftype = (session_type == WLAN_HDD_SOFTAP) ?
9849 NL80211_IFTYPE_AP:
9850 NL80211_IFTYPE_P2P_GO;
Jeff Johnson295189b2012-06-20 16:38:30 -07009851 pAdapter->device_mode = session_type;
9852
Mahesh A Saptasagar67ab9222015-10-21 15:38:41 +05309853 hdd_initialize_adapter_common(pAdapter);
Hanumanth Reddy Pothula15bc0fa2017-02-03 17:24:17 +05309854 status = hdd_init_ap_mode(pAdapter, false);
Jeff Johnson295189b2012-06-20 16:38:30 -07009855 if( VOS_STATUS_SUCCESS != status )
9856 goto err_free_netdev;
9857
Nirav Shah7e3c8132015-06-22 23:51:42 +05309858 status = hdd_sta_id_hash_attach(pAdapter);
9859 if (VOS_STATUS_SUCCESS != status)
9860 {
9861 hddLog(VOS_TRACE_LEVEL_FATAL,
9862 FL("failed to attach hash for session %d"), session_type);
9863 hdd_deinit_adapter(pHddCtx, pAdapter, rtnl_held);
9864 goto err_free_netdev;
9865 }
9866
Jeff Johnson295189b2012-06-20 16:38:30 -07009867 status = hdd_register_hostapd( pAdapter, rtnl_held );
9868 if( VOS_STATUS_SUCCESS != status )
9869 {
c_hpothu002231a2015-02-05 14:58:51 +05309870 hdd_deinit_adapter(pHddCtx, pAdapter, rtnl_held);
Jeff Johnson295189b2012-06-20 16:38:30 -07009871 goto err_free_netdev;
9872 }
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +05309873 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Jeff Johnson295189b2012-06-20 16:38:30 -07009874 netif_tx_disable(pAdapter->dev);
9875 netif_carrier_off(pAdapter->dev);
9876
9877 hdd_set_conparam( 1 );
Ganesh Kondabattinibabfb492014-12-17 20:25:29 +05309878
Hanumanth Reddy Pothulab4537b82018-03-02 12:20:38 +05309879 // Workqueue which gets scheduled in IPv4 notification callback.
9880 vos_init_work(&pAdapter->ipv4NotifierWorkQueue,
9881 hdd_ipv4_notifier_work_queue);
9882
9883#ifdef WLAN_NS_OFFLOAD
9884 // Workqueue which gets scheduled in IPv6 notification callback.
9885 vos_init_work(&pAdapter->ipv6NotifierWorkQueue,
9886 hdd_ipv6_notifier_work_queue);
9887#endif
9888
Ganesh Kondabattinibabfb492014-12-17 20:25:29 +05309889 if (WLAN_HDD_P2P_GO == session_type)
9890 {
9891 /* Initialize the work queue to
9892 * defer the back to back RoC request */
9893 INIT_DELAYED_WORK(&pAdapter->roc_work,
9894 hdd_p2p_roc_work_queue);
9895 }
Bhargav Shahd0715912015-10-01 18:17:37 +05309896
Jeff Johnson295189b2012-06-20 16:38:30 -07009897 break;
9898 }
9899 case WLAN_HDD_MONITOR:
9900 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009901 pAdapter = hdd_alloc_station_adapter( pHddCtx, macAddr, iface_name );
9902 if( NULL == pAdapter )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309903 {
9904 hddLog(VOS_TRACE_LEVEL_FATAL,
9905 FL("failed to allocate adapter for session %d"), session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07009906 return NULL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309907 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009908
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +05309909 pAdapter->device_mode = session_type;
9910 pAdapter->wdev.iftype = NL80211_IFTYPE_MONITOR;
9911
Katya Nigame7b69a82015-04-28 15:24:06 +05309912 // Register wireless extensions
9913 if( VOS_STATUS_SUCCESS != (status = hdd_register_wext(pAdapter->dev)))
9914 {
9915 hddLog(VOS_TRACE_LEVEL_FATAL,
9916 "hdd_register_wext() failed with status code %08d [x%08x]",
9917 status, status );
9918 status = VOS_STATUS_E_FAILURE;
9919 }
9920
Jeff Johnson295189b2012-06-20 16:38:30 -07009921#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29)
9922 pAdapter->dev->netdev_ops = &wlan_mon_drv_ops;
9923#else
9924 pAdapter->dev->open = hdd_mon_open;
9925 pAdapter->dev->hard_start_xmit = hdd_mon_hard_start_xmit;
Katya Nigame7b69a82015-04-28 15:24:06 +05309926 pAdapter->dev->stop = hdd_mon_stop;
9927 pAdapter->dev->do_ioctl = hdd_mon_ioctl;
Jeff Johnson295189b2012-06-20 16:38:30 -07009928#endif
Katya Nigame7b69a82015-04-28 15:24:06 +05309929 hdd_init_mon_mode( pAdapter );
Mahesh A Saptasagar67ab9222015-10-21 15:38:41 +05309930 hdd_initialize_adapter_common(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07009931 hdd_init_tx_rx( pAdapter );
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +05309932
9933 if (VOS_MONITOR_MODE != hdd_get_conparam())
9934 WLANTL_SetMonRxCbk( pVosContext, hdd_rx_packet_monitor_cbk );
9935
Jeff Johnson295189b2012-06-20 16:38:30 -07009936 set_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +05309937 status = hdd_register_interface( pAdapter, rtnl_held );
Katya Nigame7b69a82015-04-28 15:24:06 +05309938 //Stop the Interface TX queue.
9939 netif_tx_disable(pAdapter->dev);
9940 netif_carrier_off(pAdapter->dev);
Jeff Johnson295189b2012-06-20 16:38:30 -07009941 }
9942 break;
Jeff Johnson295189b2012-06-20 16:38:30 -07009943 case WLAN_HDD_FTM:
9944 {
9945 pAdapter = hdd_alloc_station_adapter( pHddCtx, macAddr, iface_name );
9946
9947 if( NULL == pAdapter )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309948 {
9949 hddLog(VOS_TRACE_LEVEL_FATAL,
9950 FL("failed to allocate adapter for session %d"), session_type);
9951 return NULL;
9952 }
9953
Jeff Johnson295189b2012-06-20 16:38:30 -07009954 /* Assign NL80211_IFTYPE_STATION as interface type to resolve Kernel Warning
9955 * message while loading driver in FTM mode. */
9956 pAdapter->wdev.iftype = NL80211_IFTYPE_STATION;
9957 pAdapter->device_mode = session_type;
9958 status = hdd_register_interface( pAdapter, rtnl_held );
Madan Mohan Koyyalamudif89ac9f2013-09-19 16:58:12 +05309959
Mahesh A Saptasagar67ab9222015-10-21 15:38:41 +05309960 hdd_initialize_adapter_common(pAdapter);
Madan Mohan Koyyalamudif89ac9f2013-09-19 16:58:12 +05309961 hdd_init_tx_rx( pAdapter );
9962
9963 //Stop the Interface TX queue.
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +05309964 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Madan Mohan Koyyalamudif89ac9f2013-09-19 16:58:12 +05309965 netif_tx_disable(pAdapter->dev);
9966 netif_carrier_off(pAdapter->dev);
Jeff Johnson295189b2012-06-20 16:38:30 -07009967 }
9968 break;
Jeff Johnson295189b2012-06-20 16:38:30 -07009969 default:
9970 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309971 hddLog(VOS_TRACE_LEVEL_FATAL,"%s Invalid session type %d",
9972 __func__, session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07009973 VOS_ASSERT(0);
9974 return NULL;
9975 }
9976 }
9977
Jeff Johnson295189b2012-06-20 16:38:30 -07009978 if( VOS_STATUS_SUCCESS == status )
9979 {
Mahesh A Saptasagar67ab9222015-10-21 15:38:41 +05309980 //Add it to the hdd's session list.
Jeff Johnson295189b2012-06-20 16:38:30 -07009981 pHddAdapterNode = vos_mem_malloc( sizeof( hdd_adapter_list_node_t ) );
9982 if( NULL == pHddAdapterNode )
9983 {
9984 status = VOS_STATUS_E_NOMEM;
9985 }
9986 else
9987 {
9988 pHddAdapterNode->pAdapter = pAdapter;
9989 status = hdd_add_adapter_back ( pHddCtx,
9990 pHddAdapterNode );
9991 }
9992 }
9993
9994 if( VOS_STATUS_SUCCESS != status )
9995 {
9996 if( NULL != pAdapter )
9997 {
9998 hdd_cleanup_adapter( pHddCtx, pAdapter, rtnl_held );
9999 pAdapter = NULL;
10000 }
10001 if( NULL != pHddAdapterNode )
10002 {
10003 vos_mem_free( pHddAdapterNode );
10004 }
10005
10006 goto resume_bmps;
10007 }
10008
10009 if(VOS_STATUS_SUCCESS == status)
10010 {
10011 wlan_hdd_set_concurrency_mode(pHddCtx, session_type);
Madan Mohan Koyyalamudi96dd30d2012-10-05 17:24:51 -070010012 //Initialize the WoWL service
10013 if(!hdd_init_wowl(pAdapter))
10014 {
10015 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hdd_init_wowl failed",__func__);
10016 goto err_free_netdev;
10017 }
Manjeet Singh3ed79242017-01-11 19:04:32 +053010018 //Initialize the TSF capture data
10019 wlan_hdd_tsf_init(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070010020 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010021 return pAdapter;
10022
10023err_free_netdev:
Jeff Johnson295189b2012-06-20 16:38:30 -070010024 wlan_hdd_release_intf_addr( pHddCtx,
10025 pAdapter->macAddressCurrent.bytes );
Hanumanth Reddy Pothulaab8e1942018-05-24 18:10:39 +053010026 free_netdev(pAdapter->dev);
Jeff Johnson295189b2012-06-20 16:38:30 -070010027
10028resume_bmps:
10029 //If bmps disabled enable it
10030 if(VOS_STATUS_SUCCESS == exitbmpsStatus)
10031 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +053010032 if (pHddCtx->hdd_wlan_suspended)
10033 {
10034 hdd_set_pwrparams(pHddCtx);
10035 }
10036 hdd_enable_bmps_imps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -070010037 }
10038 return NULL;
10039}
10040
10041VOS_STATUS hdd_close_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter,
10042 tANI_U8 rtnl_held )
10043{
10044 hdd_adapter_list_node_t *pAdapterNode, *pCurrent, *pNext;
10045 VOS_STATUS status;
10046
10047 status = hdd_get_front_adapter ( pHddCtx, &pCurrent );
10048 if( VOS_STATUS_SUCCESS != status )
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010049 {
10050 hddLog(VOS_TRACE_LEVEL_WARN,"%s: adapter list empty %d",
10051 __func__, status);
Jeff Johnson295189b2012-06-20 16:38:30 -070010052 return status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010053 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010054
10055 while ( pCurrent->pAdapter != pAdapter )
10056 {
10057 status = hdd_get_next_adapter ( pHddCtx, pCurrent, &pNext );
10058 if( VOS_STATUS_SUCCESS != status )
10059 break;
10060
10061 pCurrent = pNext;
10062 }
10063 pAdapterNode = pCurrent;
10064 if( VOS_STATUS_SUCCESS == status )
10065 {
10066 wlan_hdd_clear_concurrency_mode(pHddCtx, pAdapter->device_mode);
10067 hdd_cleanup_adapter( pHddCtx, pAdapterNode->pAdapter, rtnl_held );
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053010068
10069#ifdef FEATURE_WLAN_TDLS
10070
10071 /* A Mutex Lock is introduced while changing/initializing the mode to
10072 * protect the concurrent access for the Adapters by TDLS module.
10073 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053010074 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053010075#endif
10076
Jeff Johnson295189b2012-06-20 16:38:30 -070010077 hdd_remove_adapter( pHddCtx, pAdapterNode );
10078 vos_mem_free( pAdapterNode );
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -080010079 pAdapterNode = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070010080
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053010081#ifdef FEATURE_WLAN_TDLS
10082 mutex_unlock(&pHddCtx->tdls_lock);
10083#endif
10084
Jeff Johnson295189b2012-06-20 16:38:30 -070010085
10086 /* If there is a single session of STA/P2P client, re-enable BMPS */
Agarwal Ashish51325b52014-06-16 16:50:49 +053010087 if ((!vos_concurrent_open_sessions_running()) &&
10088 ((pHddCtx->no_of_open_sessions[VOS_STA_MODE] >= 1) ||
10089 (pHddCtx->no_of_open_sessions[VOS_P2P_CLIENT_MODE] >= 1)))
Jeff Johnson295189b2012-06-20 16:38:30 -070010090 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +053010091 if (pHddCtx->hdd_wlan_suspended)
10092 {
10093 hdd_set_pwrparams(pHddCtx);
10094 }
10095 hdd_enable_bmps_imps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -070010096 }
10097
10098 return VOS_STATUS_SUCCESS;
10099 }
10100
10101 return VOS_STATUS_E_FAILURE;
10102}
10103
10104VOS_STATUS hdd_close_all_adapters( hdd_context_t *pHddCtx )
10105{
10106 hdd_adapter_list_node_t *pHddAdapterNode;
10107 VOS_STATUS status;
10108
10109 ENTER();
10110
10111 do
10112 {
10113 status = hdd_remove_front_adapter( pHddCtx, &pHddAdapterNode );
10114 if( pHddAdapterNode && VOS_STATUS_SUCCESS == status )
10115 {
10116 hdd_cleanup_adapter( pHddCtx, pHddAdapterNode->pAdapter, FALSE );
10117 vos_mem_free( pHddAdapterNode );
10118 }
10119 }while( NULL != pHddAdapterNode && VOS_STATUS_E_EMPTY != status );
10120
10121 EXIT();
10122
10123 return VOS_STATUS_SUCCESS;
10124}
10125
10126void wlan_hdd_reset_prob_rspies(hdd_adapter_t* pHostapdAdapter)
10127{
10128 v_U8_t addIE[1] = {0};
10129
10130 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
10131 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,(tANI_U8*)addIE, 0, NULL,
10132 eANI_BOOLEAN_FALSE) )
10133 {
10134 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010135 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -070010136 }
10137
10138 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
10139 WNI_CFG_PROBE_RSP_ADDNIE_DATA2, (tANI_U8*)addIE, 0, NULL,
10140 eANI_BOOLEAN_FALSE) )
10141 {
10142 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010143 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -070010144 }
10145
10146 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
10147 WNI_CFG_PROBE_RSP_ADDNIE_DATA3, (tANI_U8*)addIE, 0, NULL,
10148 eANI_BOOLEAN_FALSE) )
10149 {
10150 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010151 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -070010152 }
10153}
10154
Anurag Chouhan83026002016-12-13 22:46:21 +053010155VOS_STATUS hdd_cleanup_ap_events(hdd_adapter_t *adapter)
10156{
10157#ifdef DHCP_SERVER_OFFLOAD
10158 vos_event_destroy(&adapter->dhcp_status.vos_event);
10159#endif
Anurag Chouhan0b29de02016-12-16 13:18:40 +053010160#ifdef MDNS_OFFLOAD
10161 vos_event_destroy(&adapter->mdns_status.vos_event);
10162#endif
Anurag Chouhan83026002016-12-13 22:46:21 +053010163 return VOS_STATUS_SUCCESS;
10164}
10165
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +053010166int wlan_hdd_stop_mon(hdd_context_t *hdd_ctx, bool wait)
10167{
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +053010168 hdd_adapter_t *adapter;
Hanumanth Reddy Pothulab8be9ab2018-04-12 20:03:05 +053010169 hdd_mon_ctx_t *mon_ctx;
10170 void (*func_ptr)(void *context) = NULL;
10171 int ret = 0;
10172 void *cookie = NULL;
10173 struct hdd_request *request;
10174 static const struct hdd_request_params params = {
10175 .priv_size = 0,
10176 .timeout_ms = MON_MODE_MSG_TIMEOUT,
10177 };
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +053010178
10179 adapter = hdd_get_adapter(hdd_ctx, WLAN_HDD_MONITOR);
10180 if (!adapter) {
10181 hddLog(LOGE, FL("Invalid STA + MON mode"));
10182 return -EINVAL;
10183 }
10184
10185 mon_ctx = WLAN_HDD_GET_MONITOR_CTX_PTR(adapter);
10186 if (!mon_ctx)
10187 return 0;
10188
10189 if (mon_ctx->state != MON_MODE_START)
10190 return 0;
10191
10192 mon_ctx->state = MON_MODE_STOP;
10193 if (wait) {
Hanumanth Reddy Pothulab8be9ab2018-04-12 20:03:05 +053010194 func_ptr = hdd_mon_post_msg_cb;
10195 request = hdd_request_alloc(&params);
10196 if (!request) {
10197 hddLog(VOS_TRACE_LEVEL_ERROR,
10198 FL("Request allocation failure"));
10199 return -ENOMEM;
10200 }
10201 cookie = hdd_request_cookie(request);
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +053010202 }
10203
Hanumanth Reddy Pothulab8be9ab2018-04-12 20:03:05 +053010204 /*
10205 * If func_ptr is NULL, on receiving WDI_MON_START_RSP or
10206 * WDI_MON_STOP_RSP hdd_mon_post_msg_cb() won't be invoked
10207 * and so uninitialized cookie won't be accessed.
10208 */
10209 if (VOS_STATUS_SUCCESS != wlan_hdd_mon_postMsg(cookie,
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +053010210 mon_ctx,
Hanumanth Reddy Pothulab8be9ab2018-04-12 20:03:05 +053010211 func_ptr)) {
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +053010212 hddLog(LOGE, FL("failed to stop MON MODE"));
Hanumanth Reddy Pothulab8be9ab2018-04-12 20:03:05 +053010213 ret = -EINVAL;
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +053010214 }
10215
10216 if (!wait)
10217 goto bmps_roaming;
10218
Hanumanth Reddy Pothulab8be9ab2018-04-12 20:03:05 +053010219 if (!ret)
10220 ret = hdd_request_wait_for_response(request);
10221 hdd_request_put(request);
10222 if (ret) {
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +053010223 hddLog(LOGE,
Hanumanth Reddy Pothulab8be9ab2018-04-12 20:03:05 +053010224 FL("timeout on stop monitor mode completion %d"), ret);
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +053010225 return -EINVAL;
10226 }
10227
10228bmps_roaming:
10229 hddLog(LOG1, FL("Enable BMPS"));
10230 hdd_enable_bmps_imps(hdd_ctx);
10231 hdd_restore_roaming(hdd_ctx);
10232
10233 return 0;
10234}
10235
10236bool wlan_hdd_check_monitor_state(hdd_context_t *hdd_ctx)
10237{
10238 hdd_adapter_t *mon_adapter;
10239 hdd_mon_ctx_t *mon_ctx;
10240
10241 if (hdd_ctx->concurrency_mode != VOS_STA_MON)
10242 return false;
10243
10244 mon_adapter = hdd_get_adapter(hdd_ctx, WLAN_HDD_MONITOR);
10245 if (!mon_adapter) {
10246 hddLog(LOGE, FL("Invalid concurrency mode"));
10247 return false;
10248 }
10249
10250 mon_ctx = WLAN_HDD_GET_MONITOR_CTX_PTR(mon_adapter);
10251 if (mon_ctx->state == MON_MODE_START)
10252 return true;
10253
10254 return false;
10255}
10256
10257int wlan_hdd_check_and_stop_mon(hdd_adapter_t *sta_adapter, bool wait)
10258{
10259 hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(sta_adapter);
10260
10261 if ((sta_adapter->device_mode != WLAN_HDD_INFRA_STATION) ||
10262 !wlan_hdd_check_monitor_state(hdd_ctx))
10263 return 0;
10264
10265 if (wlan_hdd_stop_mon(hdd_ctx, wait))
10266 return -EINVAL;
10267
10268 return 0;
10269}
10270
10271void hdd_disable_roaming(hdd_context_t *hdd_ctx)
10272{
10273 if (!hdd_ctx)
10274 return;
10275
10276 if (!hdd_ctx->cfg_ini->isFastRoamIniFeatureEnabled) {
10277 hdd_ctx->roaming_ini_original = CFG_LFR_FEATURE_ENABLED_MIN;
10278 return;
10279 }
10280
10281 hddLog(LOG1, FL("Disable driver and firmware roaming"));
10282
10283 hdd_ctx->roaming_ini_original =
10284 hdd_ctx->cfg_ini->isFastRoamIniFeatureEnabled;
10285
10286 hdd_ctx->cfg_ini->isFastRoamIniFeatureEnabled =
10287 CFG_LFR_FEATURE_ENABLED_MIN;
10288
10289 sme_UpdateIsFastRoamIniFeatureEnabled(hdd_ctx->hHal,
10290 CFG_LFR_FEATURE_ENABLED_MIN);
10291}
10292
10293void hdd_restore_roaming(hdd_context_t *hdd_ctx)
10294{
10295 if (!hdd_ctx->roaming_ini_original)
10296 return;
10297
10298 hddLog(LOG1, FL("Enable driver and firmware roaming"));
10299
10300 hdd_ctx->cfg_ini->isFastRoamIniFeatureEnabled =
10301 CFG_LFR_FEATURE_ENABLED_MAX;
10302
10303 hdd_ctx->roaming_ini_original = CFG_LFR_FEATURE_ENABLED_MIN;
10304
10305 sme_UpdateIsFastRoamIniFeatureEnabled(hdd_ctx->hHal,
10306 CFG_LFR_FEATURE_ENABLED_MAX);
10307}
Anurag Chouhan83026002016-12-13 22:46:21 +053010308
Agarwal Ashish3a38bd12014-06-12 15:16:52 +053010309VOS_STATUS hdd_stop_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter,
10310 const v_BOOL_t bCloseSession )
Jeff Johnson295189b2012-06-20 16:38:30 -070010311{
10312 eHalStatus halStatus = eHAL_STATUS_SUCCESS;
10313 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Kaushik, Sushant4975a572014-10-21 16:07:48 +053010314 hdd_scaninfo_t *pScanInfo = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070010315 union iwreq_data wrqu;
Kaushik, Sushant7005e372014-04-08 11:36:54 +053010316 v_U8_t retry = 0;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010317 long ret;
Nirav Shah7e3c8132015-06-22 23:51:42 +053010318 VOS_STATUS status;
Jeff Johnson295189b2012-06-20 16:38:30 -070010319
Anand N Sunkad26d71b92014-12-24 18:08:22 +053010320 if (pHddCtx->isLogpInProgress) {
10321 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
10322 "%s:LOGP in Progress. Ignore!!!",__func__);
10323 return VOS_STATUS_E_FAILURE;
10324 }
10325
Jeff Johnson295189b2012-06-20 16:38:30 -070010326 ENTER();
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +053010327
Kaushik, Sushant4975a572014-10-21 16:07:48 +053010328 pScanInfo = &pHddCtx->scan_info;
Jeff Johnson295189b2012-06-20 16:38:30 -070010329 switch(pAdapter->device_mode)
10330 {
Nirav Shah0cf4d892015-11-05 16:27:27 +053010331 case WLAN_HDD_IBSS:
10332 if ( VOS_TRUE == bCloseSession )
10333 {
10334 status = hdd_sta_id_hash_detach(pAdapter);
10335 if (status != VOS_STATUS_SUCCESS)
10336 hddLog(VOS_TRACE_LEVEL_ERROR,
10337 FL("sta id hash detach failed"));
10338 }
10339
Jeff Johnson295189b2012-06-20 16:38:30 -070010340 case WLAN_HDD_INFRA_STATION:
10341 case WLAN_HDD_P2P_CLIENT:
Jeff Johnsone7245742012-09-05 17:12:55 -070010342 case WLAN_HDD_P2P_DEVICE:
Vinay Krishna Erannab09d3e72014-03-26 21:23:55 +053010343 {
10344 hdd_station_ctx_t *pstation = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Mahesh A Saptasagare4d05d42015-07-02 16:17:20 +053010345#ifdef FEATURE_WLAN_TDLS
10346 mutex_lock(&pHddCtx->tdls_lock);
10347 wlan_hdd_tdls_exit(pAdapter, TRUE);
10348 mutex_unlock(&pHddCtx->tdls_lock);
10349#endif
Abhinav Kumare548f1e2018-07-12 16:40:43 +053010350 if(hdd_connIsConnected(pstation) ||
10351 (pstation->conn_info.connState == eConnectionState_Connecting))
Jeff Johnson295189b2012-06-20 16:38:30 -070010352 {
10353 if (pWextState->roamProfile.BSSType == eCSR_BSS_TYPE_START_IBSS)
Abhinav Kumare548f1e2018-07-12 16:40:43 +053010354 {
10355 INIT_COMPLETION(pAdapter->disconnect_comp_var);
Jeff Johnson295189b2012-06-20 16:38:30 -070010356 halStatus = sme_RoamDisconnect(pHddCtx->hHal,
10357 pAdapter->sessionId,
10358 eCSR_DISCONNECT_REASON_IBSS_LEAVE);
Abhinav Kumare548f1e2018-07-12 16:40:43 +053010359 /* Success implies disconnect command got queued up successfully
10360 * Or cmd not queued as scan for SSID is in progress
10361 */
10362 if((eHAL_STATUS_SUCCESS == halStatus) ||
10363 (eHAL_STATUS_CMD_NOT_QUEUED == halStatus))
10364 {
10365 ret = wait_for_completion_timeout(
10366 &pAdapter->disconnect_comp_var,
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010367 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
Abhinav Kumare548f1e2018-07-12 16:40:43 +053010368 if (ret <= 0 &&
10369 (eHAL_STATUS_CMD_NOT_QUEUED != halStatus))
10370 {
10371 hddLog(VOS_TRACE_LEVEL_ERROR,
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010372 "%s: wait on disconnect_comp_var failed %ld",
10373 __func__, ret);
Abhinav Kumare548f1e2018-07-12 16:40:43 +053010374 }
10375 }
10376 else
10377 {
10378 hddLog(LOGE, "%s: failed to post disconnect event to SME",
10379 __func__);
10380 }
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010381 }
10382 else
10383 {
Abhinav Kumare548f1e2018-07-12 16:40:43 +053010384 wlan_hdd_disconnect(pAdapter, eCSR_DISCONNECT_REASON_DEAUTH);
Jeff Johnson295189b2012-06-20 16:38:30 -070010385 }
10386 memset(&wrqu, '\0', sizeof(wrqu));
10387 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
10388 memset(wrqu.ap_addr.sa_data,'\0',ETH_ALEN);
10389 wireless_send_event(pAdapter->dev, SIOCGIWAP, &wrqu, NULL);
10390 }
Vinay Krishna Erannab09d3e72014-03-26 21:23:55 +053010391 else if(pstation->conn_info.connState ==
10392 eConnectionState_Disconnecting)
10393 {
10394 ret = wait_for_completion_interruptible_timeout(
10395 &pAdapter->disconnect_comp_var,
10396 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
10397 if (ret <= 0)
10398 {
10399 hddLog(VOS_TRACE_LEVEL_ERROR,
10400 FL("wait on disconnect_comp_var failed %ld"), ret);
10401 }
10402 }
Sachin Ahuja27dd2402016-08-01 20:30:31 +053010403 if(pScanInfo != NULL && pHddCtx->scan_info.mScanPending)
Jeff Johnson295189b2012-06-20 16:38:30 -070010404 {
Mahesh A Saptasagar0b61dcc2016-02-15 14:23:38 +053010405 wlan_hdd_scan_abort(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070010406 }
Abhishek Singh3ac179b2015-09-21 10:01:34 +053010407 if ((pAdapter->device_mode != WLAN_HDD_INFRA_STATION) &&
10408 (pAdapter->device_mode != WLAN_HDD_IBSS))
Kaushik, Sushant7005e372014-04-08 11:36:54 +053010409 {
10410 while (pAdapter->is_roc_inprogress)
10411 {
10412 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10413 "%s: ROC in progress for session %d!!!",
10414 __func__, pAdapter->sessionId);
10415 // waiting for ROC to expire
10416 msleep(500);
10417 /* In GO present case , if retry exceeds 3,
10418 it means something went wrong. */
10419 if ( retry++ > MAX_WAIT_FOR_ROC_COMPLETION )
10420 {
10421 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10422 "%s: ROC completion is not received.!!!", __func__);
Deepthi Gowri70498252015-01-20 15:56:45 +053010423 if (eHAL_STATUS_SUCCESS !=
10424 sme_CancelRemainOnChannel( WLAN_HDD_GET_HAL_CTX( pAdapter),
10425 pAdapter->sessionId ))
10426 {
10427 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10428 FL("Failed to Cancel Remain on Channel"));
10429 }
Kaushik, Sushant7005e372014-04-08 11:36:54 +053010430 wait_for_completion_interruptible_timeout(
10431 &pAdapter->cancel_rem_on_chan_var,
10432 msecs_to_jiffies(WAIT_CANCEL_REM_CHAN));
10433 break;
10434 }
10435 }
Anand N Sunkaddc63c792015-06-03 14:33:24 +053010436 vos_flush_delayed_work(&pAdapter->roc_work);
Kaushik, Sushant7005e372014-04-08 11:36:54 +053010437 }
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +053010438#ifdef WLAN_NS_OFFLOAD
Anand N Sunkaddc63c792015-06-03 14:33:24 +053010439 vos_flush_work(&pAdapter->ipv6NotifierWorkQueue);
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +053010440#endif
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +053010441
Anand N Sunkaddc63c792015-06-03 14:33:24 +053010442 vos_flush_work(&pAdapter->ipv4NotifierWorkQueue);
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +053010443
Agarwal Ashish3a38bd12014-06-12 15:16:52 +053010444 /* It is possible that the caller of this function does not
10445 * wish to close the session
10446 */
10447 if (VOS_TRUE == bCloseSession &&
10448 test_bit(SME_SESSION_OPENED, &pAdapter->event_flags))
Jeff Johnson295189b2012-06-20 16:38:30 -070010449 {
10450 INIT_COMPLETION(pAdapter->session_close_comp_var);
10451 if (eHAL_STATUS_SUCCESS ==
Agrawal Ashish5a3522c2016-03-02 15:08:28 +053010452 sme_CloseSession(pHddCtx->hHal, pAdapter->sessionId, FALSE,
10453 VOS_FALSE, hdd_smeCloseSessionCallback, pAdapter))
Jeff Johnson295189b2012-06-20 16:38:30 -070010454 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010455 unsigned long ret;
10456
Jeff Johnson295189b2012-06-20 16:38:30 -070010457 //Block on a completion variable. Can't wait forever though.
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010458 ret = wait_for_completion_timeout(
Agarwal Ashish3a38bd12014-06-12 15:16:52 +053010459 &pAdapter->session_close_comp_var,
10460 msecs_to_jiffies(WLAN_WAIT_TIME_SESSIONOPENCLOSE));
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010461 if ( 0 >= ret)
10462 {
10463 hddLog(LOGE, "%s: failure waiting for session_close_comp_var %ld",
Agarwal Ashish3a38bd12014-06-12 15:16:52 +053010464 __func__, ret);
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010465 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010466 }
10467 }
Vinay Krishna Erannab09d3e72014-03-26 21:23:55 +053010468 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010469 break;
10470
10471 case WLAN_HDD_SOFTAP:
10472 case WLAN_HDD_P2P_GO:
Nirav Shah0cf4d892015-11-05 16:27:27 +053010473 if ( VOS_TRUE == bCloseSession )
10474 {
10475 status = hdd_sta_id_hash_detach(pAdapter);
10476 if (status != VOS_STATUS_SUCCESS)
10477 hddLog(VOS_TRACE_LEVEL_ERROR,
10478 FL("sta id hash detach failed"));
10479 }
10480
Jeff Johnson295189b2012-06-20 16:38:30 -070010481 //Any softap specific cleanup here...
Anurag Chouhan83026002016-12-13 22:46:21 +053010482 hdd_cleanup_ap_events(pAdapter);
Kaushik, Sushant7005e372014-04-08 11:36:54 +053010483 if (pAdapter->device_mode == WLAN_HDD_P2P_GO) {
10484 while (pAdapter->is_roc_inprogress) {
10485 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10486 "%s: ROC in progress for session %d!!!",
10487 __func__, pAdapter->sessionId);
10488 msleep(500);
10489 if ( retry++ > MAX_WAIT_FOR_ROC_COMPLETION ) {
10490 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10491 "%s: ROC completion is not received.!!!", __func__);
10492 WLANSAP_CancelRemainOnChannel(
10493 (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
10494 wait_for_completion_interruptible_timeout(
10495 &pAdapter->cancel_rem_on_chan_var,
10496 msecs_to_jiffies(WAIT_CANCEL_REM_CHAN));
10497 break;
10498 }
10499 }
Ganesh Kondabattinibabfb492014-12-17 20:25:29 +053010500
Anand N Sunkaddc63c792015-06-03 14:33:24 +053010501 vos_flush_delayed_work(&pAdapter->roc_work);
Kaushik, Sushant7005e372014-04-08 11:36:54 +053010502 }
Agrawal Ashish17ef5082016-10-17 18:33:21 +053010503#ifdef SAP_AUTH_OFFLOAD
10504 if (pHddCtx->cfg_ini->enable_sap_auth_offload)
10505 hdd_set_sap_auth_offload(pAdapter, FALSE);
10506#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010507 mutex_lock(&pHddCtx->sap_lock);
10508 if (test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
10509 {
10510 VOS_STATUS status;
10511 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Hanumanth Reddy Pothula74ba68c2018-06-22 17:52:09 +053010512 hdd_hostapd_state_t *pHostapdState =
10513 WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070010514
Hanumanth Reddy Pothula74ba68c2018-06-22 17:52:09 +053010515 vos_event_reset(&pHostapdState->vosEvent);
Jeff Johnson295189b2012-06-20 16:38:30 -070010516 //Stop Bss.
10517 status = WLANSAP_StopBss(pHddCtx->pvosContext);
10518 if (VOS_IS_STATUS_SUCCESS(status))
10519 {
Jeff Johnson295189b2012-06-20 16:38:30 -070010520 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
10521
10522 if (!VOS_IS_STATUS_SUCCESS(status))
10523 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010524 hddLog(LOGE, "%s: failure waiting for WLANSAP_StopBss %d",
10525 __func__, status);
Jeff Johnson295189b2012-06-20 16:38:30 -070010526 }
10527 }
10528 else
10529 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070010530 hddLog(LOGE, "%s: failure in WLANSAP_StopBss", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070010531 }
10532 clear_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags);
Agarwal Ashish51325b52014-06-16 16:50:49 +053010533 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070010534
10535 if (eHAL_STATUS_FAILURE ==
10536 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG,
10537 0, NULL, eANI_BOOLEAN_FALSE))
10538 {
10539 hddLog(LOGE,
10540 "%s: Failed to set WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070010541 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070010542 }
10543
10544 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt((WLAN_HDD_GET_CTX(pAdapter))->hHal,
10545 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
10546 eANI_BOOLEAN_FALSE) )
10547 {
10548 hddLog(LOGE,
10549 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
10550 }
10551
10552 // Reset WNI_CFG_PROBE_RSP Flags
10553 wlan_hdd_reset_prob_rspies(pAdapter);
10554 kfree(pAdapter->sessionCtx.ap.beacon);
10555 pAdapter->sessionCtx.ap.beacon = NULL;
10556 }
10557 mutex_unlock(&pHddCtx->sap_lock);
Hanumanth Reddy Pothulab4537b82018-03-02 12:20:38 +053010558
10559#ifdef WLAN_NS_OFFLOAD
10560 vos_flush_work(&pAdapter->ipv6NotifierWorkQueue);
10561#endif
10562 vos_flush_work(&pAdapter->ipv4NotifierWorkQueue);
10563
Jeff Johnson295189b2012-06-20 16:38:30 -070010564 break;
Sameer Thalappilbee426e2013-10-30 10:30:30 -070010565
Jeff Johnson295189b2012-06-20 16:38:30 -070010566 case WLAN_HDD_MONITOR:
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +053010567 if (VOS_MONITOR_MODE != hdd_get_conparam())
10568 wlan_hdd_stop_mon(pHddCtx, true);
10569 break;
Sameer Thalappilbee426e2013-10-30 10:30:30 -070010570
Jeff Johnson295189b2012-06-20 16:38:30 -070010571 default:
10572 break;
10573 }
10574
10575 EXIT();
10576 return VOS_STATUS_SUCCESS;
10577}
10578
Kapil Gupta137ef892016-12-13 19:38:00 +053010579/**
10580 * wlan_hdd_restart_sap() - to restart SAP in driver internally
10581 * @ap_adapter: - Pointer to SAP hdd_adapter_t structure
10582 *
10583 * wlan_hdd_restart_sap first delete SAP and do cleanup.
10584 * After that WLANSAP_StartBss start re-start process of SAP.
10585 *
10586 * Return: None
10587 */
10588static void wlan_hdd_restart_sap(hdd_adapter_t *ap_adapter)
10589{
10590 hdd_ap_ctx_t *pHddApCtx;
10591 hdd_hostapd_state_t *pHostapdState;
10592 VOS_STATUS vos_status;
10593 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(ap_adapter);
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053010594#ifdef USE_CFG80211_DEL_STA_V2
Kapil Gupta137ef892016-12-13 19:38:00 +053010595 struct station_del_parameters delStaParams;
10596#endif
10597 tsap_Config_t *pConfig;
10598
10599 pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(ap_adapter);
10600 pConfig = &pHddApCtx->sapConfig;
10601
10602 mutex_lock(&pHddCtx->sap_lock);
10603 if (test_bit(SOFTAP_BSS_STARTED, &ap_adapter->event_flags)) {
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053010604#ifdef USE_CFG80211_DEL_STA_V2
Kapil Gupta137ef892016-12-13 19:38:00 +053010605 delStaParams.mac = NULL;
10606 delStaParams.subtype = SIR_MAC_MGMT_DEAUTH >> 4;
10607 delStaParams.reason_code = eCsrForcedDeauthSta;
10608 wlan_hdd_cfg80211_del_station(ap_adapter->wdev.wiphy, ap_adapter->dev,
10609 &delStaParams);
10610#else
10611 wlan_hdd_cfg80211_del_station(ap_adapter->wdev.wiphy, ap_adapter->dev,
10612 NULL);
10613#endif
10614 hdd_cleanup_actionframe(pHddCtx, ap_adapter);
10615
10616 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(ap_adapter);
10617 vos_event_reset(&pHostapdState->vosEvent);
10618
10619 if (VOS_STATUS_SUCCESS == WLANSAP_StopBss(pHddCtx->pvosContext)) {
10620 vos_status = vos_wait_single_event(&pHostapdState->vosEvent,
10621 10000);
10622 if (!VOS_IS_STATUS_SUCCESS(vos_status)) {
10623 hddLog(LOGE, FL("SAP Stop Failed"));
10624 goto end;
10625 }
10626 }
10627 clear_bit(SOFTAP_BSS_STARTED, &ap_adapter->event_flags);
10628 wlan_hdd_decr_active_session(pHddCtx, ap_adapter->device_mode);
10629 hddLog(LOG1, FL("SAP Stop Success"));
10630
10631 if (0 != wlan_hdd_cfg80211_update_apies(ap_adapter)) {
10632 hddLog(LOGE, FL("SAP Not able to set AP IEs"));
10633 goto end;
10634 }
10635
Hanumanth Reddy Pothula74ba68c2018-06-22 17:52:09 +053010636 vos_event_reset(&pHostapdState->vosEvent);
Kapil Gupta137ef892016-12-13 19:38:00 +053010637 if (WLANSAP_StartBss(pHddCtx->pvosContext, hdd_hostapd_SAPEventCB,
10638 pConfig, (v_PVOID_t)ap_adapter->dev) != VOS_STATUS_SUCCESS) {
10639 hddLog(LOGE, FL("SAP Start Bss fail"));
10640 goto end;
10641 }
10642
10643 hddLog(LOG1, FL("Waiting for SAP to start"));
10644 vos_status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
10645 if (!VOS_IS_STATUS_SUCCESS(vos_status)) {
10646 hddLog(LOGE, FL("SAP Start failed"));
10647 goto end;
10648 }
10649 hddLog(LOG1, FL("SAP Start Success"));
10650 set_bit(SOFTAP_BSS_STARTED, &ap_adapter->event_flags);
10651 wlan_hdd_incr_active_session(pHddCtx, ap_adapter->device_mode);
10652 pHostapdState->bCommit = TRUE;
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053010653 if (!VOS_IS_STATUS_SUCCESS(hdd_dhcp_mdns_offload(ap_adapter))) {
10654 hddLog(VOS_TRACE_LEVEL_ERROR, FL("DHCP/MDNS offload Failed!!"));
10655 vos_event_reset(&pHostapdState->vosEvent);
10656 if (VOS_STATUS_SUCCESS == WLANSAP_StopBss(pHddCtx->pvosContext)) {
10657 vos_status = vos_wait_single_event(&pHostapdState->vosEvent,
10658 10000);
10659 if (!VOS_IS_STATUS_SUCCESS(vos_status)) {
10660 hddLog(LOGE, FL("SAP Stop Failed"));
10661 goto end;
10662 }
10663 }
10664 }
Kapil Gupta137ef892016-12-13 19:38:00 +053010665 }
10666end:
10667 mutex_unlock(&pHddCtx->sap_lock);
10668 return;
10669}
10670
10671/**
10672 * __hdd_sap_restart_handle() - to handle restarting of SAP
10673 * @work: name of the work
10674 *
10675 * Purpose of this function is to trigger sap start. this function
10676 * will be called from workqueue.
10677 *
10678 * Return: void.
10679 */
10680static void __hdd_sap_restart_handle(struct work_struct *work)
10681{
10682 hdd_adapter_t *sap_adapter;
10683 hdd_context_t *hdd_ctx = container_of(work,
10684 hdd_context_t,
10685 sap_start_work);
10686 if (0 != wlan_hdd_validate_context(hdd_ctx)) {
10687 vos_ssr_unprotect(__func__);
10688 return;
10689 }
10690 sap_adapter = hdd_get_adapter(hdd_ctx,
10691 WLAN_HDD_SOFTAP);
10692 if (sap_adapter == NULL) {
10693 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10694 FL("sap_adapter is NULL"));
10695 vos_ssr_unprotect(__func__);
10696 return;
10697 }
10698
10699 if (hdd_ctx->is_ch_avoid_in_progress) {
10700 sap_adapter->sessionCtx.ap.sapConfig.channel = AUTO_CHANNEL_SELECT;
10701 wlan_hdd_restart_sap(sap_adapter);
10702 hdd_change_ch_avoidance_status(hdd_ctx, false);
10703 }
Agrawal Ashish574b3e62017-02-09 18:58:34 +053010704 if (hdd_ctx->cfg_ini->enable_sap_auth_offload)
10705 wlan_hdd_restart_sap(sap_adapter);
Kapil Gupta137ef892016-12-13 19:38:00 +053010706}
10707
10708/**
10709 * hdd_sap_restart_handle() - to handle restarting of SAP
10710 * @work: name of the work
10711 *
10712 * Purpose of this function is to trigger sap start. this function
10713 * will be called from workqueue.
10714 *
10715 * Return: void.
10716 */
10717static void hdd_sap_restart_handle(struct work_struct *work)
10718{
10719 vos_ssr_protect(__func__);
10720 __hdd_sap_restart_handle(work);
10721 vos_ssr_unprotect(__func__);
10722}
10723
10724
Abhishek Singh78c691f2017-11-30 13:48:44 +053010725/**
10726 * __hdd_force_scc_with_ecsa_handle() - to handle force scc using ecsa
10727 * @work: name of the work
10728 *
10729 * Purpose of this function is to force SCC using ECSA. This function
10730 * will be called from workqueue.
10731 *
10732 * Return: void.
10733 */
10734static void
10735__hdd_force_scc_with_ecsa_handle(struct work_struct *work)
10736{
10737 hdd_adapter_t *sap_adapter;
10738 hdd_station_ctx_t *sta_ctx;
10739 hdd_adapter_t *sta_adapter;
Ganesh Kondabattini3655a6d2018-01-08 20:25:39 +053010740 ptSapContext sap_ctx = NULL;
10741 v_CONTEXT_t vos_ctx;
10742 tANI_U8 target_channel;
10743 tsap_Config_t *sap_config;
10744 bool sta_sap_scc_on_dfs_chan;
10745 eNVChannelEnabledType chan_state;
Abhishek Singh78c691f2017-11-30 13:48:44 +053010746 hdd_context_t *hdd_ctx = container_of(to_delayed_work(work),
10747 hdd_context_t,
10748 ecsa_chan_change_work);
10749
10750 if (wlan_hdd_validate_context(hdd_ctx))
10751 return;
10752
10753 sap_adapter = hdd_get_adapter(hdd_ctx,
10754 WLAN_HDD_SOFTAP);
10755 if (!sap_adapter) {
10756 hddLog(LOGE, FL("sap_adapter is NULL"));
10757 return;
10758 }
10759
Ganesh Kondabattini3655a6d2018-01-08 20:25:39 +053010760 vos_ctx = hdd_ctx->pvosContext;
10761 if (!vos_ctx) {
10762 hddLog(LOGE, FL("vos_ctx is NULL"));
10763 return;
10764 }
10765
10766 sap_ctx = VOS_GET_SAP_CB(vos_ctx);
10767 if (!sap_ctx) {
10768 hddLog(LOGE, FL("sap_ctx is NULL"));
10769 return;
10770 }
10771
10772 sap_config = &sap_adapter->sessionCtx.ap.sapConfig;
10773
10774 sta_sap_scc_on_dfs_chan = hdd_is_sta_sap_scc_allowed_on_dfs_chan(hdd_ctx);
10775
Abhishek Singh78c691f2017-11-30 13:48:44 +053010776 sta_adapter = hdd_get_adapter(hdd_ctx,
10777 WLAN_HDD_INFRA_STATION);
10778 if (!sta_adapter) {
10779 hddLog(LOGE, FL("sta_adapter is NULL"));
10780 return;
10781 }
Abhishek Singh78c691f2017-11-30 13:48:44 +053010782
Abhishek Singh10e17cf2018-03-12 14:34:22 +053010783 if (wlansap_chk_n_set_chan_change_in_progress(sap_ctx))
Abhishek Singh78c691f2017-11-30 13:48:44 +053010784 return;
Abhishek Singh10e17cf2018-03-12 14:34:22 +053010785 INIT_COMPLETION(sap_ctx->ecsa_info.chan_switch_comp);
10786
10787 sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(sta_adapter);
10788 if (sta_ctx->conn_info.connState != eConnectionState_Associated) {
10789 if (sta_ctx->conn_info.connState == eConnectionState_NotConnected) {
10790 chan_state = vos_nv_getChannelEnabledState(sap_ctx->channel);
10791 hddLog(LOG1, FL("sta not in connected state %d, sta_sap_scc_on_dfs_chan %d, chan_state %d"),
10792 sta_ctx->conn_info.connState, sta_sap_scc_on_dfs_chan,
10793 chan_state);
10794 if (sta_sap_scc_on_dfs_chan &&
10795 (chan_state == NV_CHANNEL_DFS)) {
10796 hddLog(LOGE, FL("Switch SAP to user configured channel"));
10797 target_channel = sap_config->user_config_channel;
10798 goto switch_channel;
10799 }
10800 }
10801 goto abort;
Abhishek Singh78c691f2017-11-30 13:48:44 +053010802 }
10803
Ganesh Kondabattini3655a6d2018-01-08 20:25:39 +053010804 target_channel = sta_ctx->conn_info.operationChannel;
10805switch_channel:
10806 hddLog(LOGE, FL("Switch SAP to %d channel"),
10807 target_channel);
Abhishek Singh10e17cf2018-03-12 14:34:22 +053010808 if (!wlansap_set_channel_change(vos_ctx, target_channel, true))
10809 return;
10810
10811abort:
10812 wlansap_reset_chan_change_in_progress(sap_ctx);
10813 complete(&sap_ctx->ecsa_info.chan_switch_comp);
Abhishek Singh78c691f2017-11-30 13:48:44 +053010814}
10815
10816/**
10817 * hdd_force_scc_with_ecsa_handle() - to handle force scc using ecsa
10818 * @work: name of the work
10819 *
10820 * Purpose of this function is to force SCC using ECSA. This function
10821 * will be called from workqueue.
10822 *
10823 * Return: void.
10824 */
10825static void
10826hdd_force_scc_with_ecsa_handle(struct work_struct *work)
10827{
10828 vos_ssr_protect(__func__);
10829 __hdd_force_scc_with_ecsa_handle(work);
10830 vos_ssr_unprotect(__func__);
10831}
10832
Abhishek Singh10e17cf2018-03-12 14:34:22 +053010833int hdd_wait_for_ecsa_complete(hdd_context_t *hdd_ctx)
10834{
10835 int ret;
10836 ptSapContext sap_ctx = NULL;
10837 v_CONTEXT_t vos_ctx;
10838
10839 vos_ctx = hdd_ctx->pvosContext;
10840 if (!vos_ctx) {
10841 hddLog(LOGE, FL("vos_ctx is NULL"));
10842 return 0;
10843 }
10844
10845 sap_ctx = VOS_GET_SAP_CB(vos_ctx);
10846 if (!sap_ctx) {
10847 hddLog(LOG1, FL("sap_ctx is NULL"));
10848 return 0;
10849 }
10850 if(!sap_ctx->isSapSessionOpen) {
10851 hddLog(LOG1, FL("sap session not opened, SAP in state %d"),
10852 sap_ctx->sapsMachine);
10853 return 0;
10854 }
10855
10856 if (!wlansap_get_change_in_progress(sap_ctx)) {
10857 hddLog(LOG1, FL("channel switch not in progress"));
10858 return 0;
10859 }
10860 ret = wait_for_completion_timeout(&sap_ctx->ecsa_info.chan_switch_comp,
10861 msecs_to_jiffies(HDD_SAP_CHAN_CNG_WAIT_TIME));
10862 if (!ret)
10863 {
10864 hddLog(LOGE, FL("Timeout waiting for SAP channel switch"));
10865 return ret;
10866 }
10867
10868 return 0;
10869}
10870
10871
Ganesh Kondabattini3655a6d2018-01-08 20:25:39 +053010872/**
10873 * hdd_is_sta_sap_scc_allowed_on_dfs_chan() - check if sta+sap scc allowed on
10874 * dfs chan
10875 * @hdd_ctx: pointer to hdd context
10876 *
10877 * This function used to check if sta+sap scc allowed on DFS channel.
10878 *
10879 * Return: None
10880 */
10881bool hdd_is_sta_sap_scc_allowed_on_dfs_chan(hdd_context_t *hdd_ctx)
10882{
10883 if (hdd_ctx->cfg_ini->force_scc_with_ecsa &&
10884 hdd_ctx->cfg_ini->sta_sap_scc_on_dfs_chan)
10885 return true;
10886 else
10887 return false;
10888}
10889
Jeff Johnson295189b2012-06-20 16:38:30 -070010890VOS_STATUS hdd_stop_all_adapters( hdd_context_t *pHddCtx )
10891{
10892 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
10893 VOS_STATUS status;
10894 hdd_adapter_t *pAdapter;
10895
10896 ENTER();
10897
10898 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
10899
10900 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
10901 {
10902 pAdapter = pAdapterNode->pAdapter;
Jeff Johnson295189b2012-06-20 16:38:30 -070010903
Agarwal Ashish3a38bd12014-06-12 15:16:52 +053010904 hdd_stop_adapter( pHddCtx, pAdapter, VOS_TRUE );
Jeff Johnson295189b2012-06-20 16:38:30 -070010905
10906 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
10907 pAdapterNode = pNext;
10908 }
10909
10910 EXIT();
10911
10912 return VOS_STATUS_SUCCESS;
10913}
10914
Rajeev Kumarf999e582014-01-09 17:33:29 -080010915
10916#ifdef FEATURE_WLAN_BATCH_SCAN
10917/**---------------------------------------------------------------------------
10918
10919 \brief hdd_deinit_batch_scan () - This function cleans up batch scan data
10920 structures
10921
10922 \param - pAdapter Pointer to HDD adapter
10923
10924 \return - None
10925
10926 --------------------------------------------------------------------------*/
10927void hdd_deinit_batch_scan(hdd_adapter_t *pAdapter)
10928{
10929 tHddBatchScanRsp *pNode;
10930 tHddBatchScanRsp *pPrev;
10931
Siddharth Bhalb3e9b792014-02-24 15:14:16 +053010932 if (NULL == pAdapter)
Rajeev Kumarf999e582014-01-09 17:33:29 -080010933 {
Siddharth Bhalb3e9b792014-02-24 15:14:16 +053010934 hddLog(VOS_TRACE_LEVEL_ERROR,
10935 "%s: Adapter context is Null", __func__);
10936 return;
10937 }
10938
10939 pNode = pAdapter->pBatchScanRsp;
10940 while (pNode)
10941 {
10942 pPrev = pNode;
10943 pNode = pNode->pNext;
10944 vos_mem_free((v_VOID_t * )pPrev);
Rajeev Kumarf999e582014-01-09 17:33:29 -080010945 }
10946
10947 pAdapter->pBatchScanRsp = NULL;
10948 pAdapter->numScanList = 0;
10949 pAdapter->batchScanState = eHDD_BATCH_SCAN_STATE_STOPPED;
10950 pAdapter->prev_batch_id = 0;
10951
10952 return;
10953}
10954#endif
10955
10956
Jeff Johnson295189b2012-06-20 16:38:30 -070010957VOS_STATUS hdd_reset_all_adapters( hdd_context_t *pHddCtx )
10958{
10959 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
10960 VOS_STATUS status;
10961 hdd_adapter_t *pAdapter;
10962
10963 ENTER();
10964
10965 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
10966
10967 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
10968 {
10969 pAdapter = pAdapterNode->pAdapter;
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +053010970 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Jeff Johnson295189b2012-06-20 16:38:30 -070010971 netif_tx_disable(pAdapter->dev);
Hanumanth Reddy Pothulad864f312017-01-18 16:16:08 +053010972
10973 if (pHddCtx->cfg_ini->sap_internal_restart &&
10974 pAdapter->device_mode == WLAN_HDD_SOFTAP) {
10975 hddLog(LOG1, FL("driver supports sap restart"));
10976 vos_flush_work(&pHddCtx->sap_start_work);
10977 hdd_sap_indicate_disconnect_for_sta(pAdapter);
10978 hdd_cleanup_actionframe(pHddCtx, pAdapter);
Hanumanth Reddy Pothula15bc0fa2017-02-03 17:24:17 +053010979 hdd_softap_deinit_tx_rx(pAdapter, true);
10980 hdd_sap_destroy_timers(pAdapter);
Hanumanth Reddy Pothulad864f312017-01-18 16:16:08 +053010981 } else {
10982 netif_carrier_off(pAdapter->dev);
10983 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010984
Srinivas Girigowda66c05eb2013-07-14 13:06:01 -070010985 pAdapter->sessionCtx.station.hdd_ReassocScenario = VOS_FALSE;
Hanumanth Reddy Pothulada449f12018-03-13 18:19:19 +053010986
10987 if (pAdapter->device_mode == WLAN_HDD_MONITOR)
10988 pAdapter->sessionCtx.monitor.state = MON_MODE_STOP;
Srinivas Girigowda66c05eb2013-07-14 13:06:01 -070010989
Jeff Johnson295189b2012-06-20 16:38:30 -070010990 hdd_deinit_tx_rx(pAdapter);
Agarwal Ashish6267caa2014-08-06 19:16:21 +053010991
Katya Nigam1fd24402015-02-16 14:52:19 +053010992 if(pAdapter->device_mode == WLAN_HDD_IBSS )
10993 hdd_ibss_deinit_tx_rx(pAdapter);
10994
Nirav Shah7e3c8132015-06-22 23:51:42 +053010995 status = hdd_sta_id_hash_detach(pAdapter);
10996 if (status != VOS_STATUS_SUCCESS)
10997 hddLog(VOS_TRACE_LEVEL_ERROR,
10998 FL("sta id hash detach failed for session id %d"),
10999 pAdapter->sessionId);
11000
Agarwal Ashish6267caa2014-08-06 19:16:21 +053011001 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
11002
Madan Mohan Koyyalamudi8c6dec82013-09-26 15:56:13 +053011003 if (test_bit(WMM_INIT_DONE, &pAdapter->event_flags))
11004 {
11005 hdd_wmm_adapter_close( pAdapter );
11006 clear_bit(WMM_INIT_DONE, &pAdapter->event_flags);
11007 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011008
Siddharth Bhal2db319d2014-12-03 12:37:18 +053011009 if (test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
11010 {
11011 clear_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags);
11012 }
11013
Rajeev Kumarf999e582014-01-09 17:33:29 -080011014#ifdef FEATURE_WLAN_BATCH_SCAN
11015 if (eHDD_BATCH_SCAN_STATE_STARTED == pAdapter->batchScanState)
11016 {
11017 hdd_deinit_batch_scan(pAdapter);
11018 }
11019#endif
11020
Mahesh A Saptasagarf5b8eff2015-01-31 01:07:07 +053011021#ifdef FEATURE_WLAN_TDLS
11022 mutex_lock(&pHddCtx->tdls_lock);
Pradeep Reddy POTTETI2d4d5c42015-03-03 14:34:19 +053011023 wlan_hdd_tdls_exit(pAdapter, TRUE);
Mahesh A Saptasagarf5b8eff2015-01-31 01:07:07 +053011024 mutex_unlock(&pHddCtx->tdls_lock);
11025#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070011026 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
11027 pAdapterNode = pNext;
11028 }
11029
11030 EXIT();
11031
11032 return VOS_STATUS_SUCCESS;
11033}
11034
Abhishek Singhbbe0b2a2016-12-05 11:57:36 +053011035/**
Abhishek Singh5a597e62016-12-05 15:16:30 +053011036 * hdd_get_bss_entry() - Get the bss entry matching the chan, bssid and ssid
11037 * @wiphy: wiphy
11038 * @channel: channel of the BSS to find
11039 * @bssid: bssid of the BSS to find
11040 * @ssid: ssid of the BSS to find
11041 * @ssid_len: ssid len of of the BSS to find
11042 *
11043 * The API is a wrapper to get bss from kernel matching the chan,
11044 * bssid and ssid
11045 *
11046 * Return: Void
11047 */
11048#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 1, 0)) \
11049 && !defined(WITH_BACKPORTS) && !defined(IEEE80211_PRIVACY)
11050
11051struct cfg80211_bss* hdd_get_bss_entry(struct wiphy *wiphy,
11052 struct ieee80211_channel *channel,
11053 const u8 *bssid,
11054 const u8 *ssid, size_t ssid_len)
11055{
11056 return cfg80211_get_bss(wiphy, channel, bssid,
11057 ssid, ssid_len,
11058 WLAN_CAPABILITY_ESS,
11059 WLAN_CAPABILITY_ESS);
11060}
11061#else
11062struct cfg80211_bss* hdd_get_bss_entry(struct wiphy *wiphy,
11063 struct ieee80211_channel *channel,
11064 const u8 *bssid,
11065 const u8 *ssid, size_t ssid_len)
11066{
11067 return cfg80211_get_bss(wiphy, channel, bssid,
11068 ssid, ssid_len,
11069 IEEE80211_BSS_TYPE_ESS,
11070 IEEE80211_PRIVACY_ANY);
11071}
11072#endif
11073
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053011074#if defined(CFG80211_CONNECT_BSS) || \
11075 (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 7, 0))
11076
11077#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 11, 0) || \
11078 defined (CFG80211_CONNECT_TIMEOUT_REASON_CODE)
11079/**
11080 * hdd_connect_bss() - helper function to send connection status to supplicant
11081 * @dev: network device
11082 * @bssid: bssid to which we want to associate
11083 * @bss: information about connected bss
11084 * @req_ie: Request Information Element
11085 * @req_ie_len: len of the req IE
11086 * @resp_ie: Response IE
11087 * @resp_ie_len: len of ht response IE
11088 * @status: status
11089 * @gfp: Kernel Flag
11090 *
11091 * This is a helper function to send connection status to supplicant
11092 * and gets invoked from wrapper API
11093 *
11094 * Return: Void
11095 */
11096static void hdd_connect_bss(struct net_device *dev,
11097 const u8 *bssid,
11098 struct cfg80211_bss *bss,
11099 const u8 *req_ie,
11100 size_t req_ie_len,
11101 const u8 *resp_ie,
11102 size_t resp_ie_len,
11103 u16 status,
11104 gfp_t gfp)
11105{
11106 cfg80211_connect_bss(dev, bssid, bss, req_ie, req_ie_len,
11107 resp_ie, resp_ie_len, status, gfp, NL80211_TIMEOUT_UNSPECIFIED);
11108}
11109#else
11110/**
11111 * hdd_connect_bss() - helper function to send connection status to supplicant
11112 * @dev: network device
11113 * @bssid: bssid to which we want to associate
11114 * @bss: information about connected bss
11115 * @req_ie: Request Information Element
11116 * @req_ie_len: len of the req IE
11117 * @resp_ie: Response IE
11118 * @resp_ie_len: len of ht response IE
11119 * @status: status
11120 * @gfp: Kernel Flag
11121 *
11122 * This is a helper function to send connection status to supplicant
11123 * and gets invoked from wrapper API
11124 *
11125 * Return: Void
11126 */
11127static void hdd_connect_bss(struct net_device *dev,
11128 const u8 *bssid,
11129 struct cfg80211_bss *bss,
11130 const u8 *req_ie,
11131 size_t req_ie_len,
11132 const u8 *resp_ie,
11133 size_t resp_ie_len,
11134 u16 status,
11135 gfp_t gfp)
11136{
11137 cfg80211_connect_bss(dev, bssid, bss, req_ie, req_ie_len,
11138 resp_ie, resp_ie_len, status, gfp);
11139}
11140#endif
11141
Abhishek Singh5a597e62016-12-05 15:16:30 +053011142/**
Abhishek Singhbbe0b2a2016-12-05 11:57:36 +053011143 * hdd_connect_result() - API to send connection status to supplicant
11144 * @dev: network device
11145 * @bssid: bssid to which we want to associate
11146 * @roam_info: information about connected bss
11147 * @req_ie: Request Information Element
11148 * @req_ie_len: len of the req IE
11149 * @resp_ie: Response IE
11150 * @resp_ie_len: len of ht response IE
11151 * @status: status
11152 * @gfp: Kernel Flag
11153 *
11154 * The API is a wrapper to send connection status to supplicant
11155 *
11156 * Return: Void
11157 */
Abhishek Singhbbe0b2a2016-12-05 11:57:36 +053011158void hdd_connect_result(struct net_device *dev,
11159 const u8 *bssid,
11160 tCsrRoamInfo *roam_info,
11161 const u8 *req_ie,
11162 size_t req_ie_len,
11163 const u8 *resp_ie,
11164 size_t resp_ie_len,
11165 u16 status,
11166 gfp_t gfp)
11167{
11168 hdd_adapter_t *padapter = (hdd_adapter_t *) netdev_priv(dev);
11169 struct cfg80211_bss *bss = NULL;
11170
11171 if (WLAN_STATUS_SUCCESS == status) {
11172 struct ieee80211_channel *chan;
11173 int freq;
11174 int chan_no = roam_info->pBssDesc->channelId;;
11175
11176 if (chan_no <= 14)
11177 freq = ieee80211_channel_to_frequency(chan_no,
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053011178 HDD_NL80211_BAND_2GHZ);
Abhishek Singhbbe0b2a2016-12-05 11:57:36 +053011179 else
11180 freq = ieee80211_channel_to_frequency(chan_no,
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053011181 HDD_NL80211_BAND_5GHZ);
Abhishek Singhbbe0b2a2016-12-05 11:57:36 +053011182
11183 chan = ieee80211_get_channel(padapter->wdev.wiphy, freq);
Abhishek Singh5a597e62016-12-05 15:16:30 +053011184 bss = hdd_get_bss_entry(padapter->wdev.wiphy,
11185 chan, bssid,
11186 roam_info->u.pConnectedProfile->SSID.ssId,
11187 roam_info->u.pConnectedProfile->SSID.length);
Abhishek Singhbbe0b2a2016-12-05 11:57:36 +053011188 }
11189
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053011190 hdd_connect_bss(dev, bssid, bss, req_ie, req_ie_len, resp_ie, resp_ie_len,
11191 status, gfp);
Abhishek Singhbbe0b2a2016-12-05 11:57:36 +053011192}
11193#else
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053011194/**
11195 * hdd_connect_result() - API to send connection status to supplicant
11196 * @dev: network device
11197 * @bssid: bssid to which we want to associate
11198 * @roam_info: information about connected bss
11199 * @req_ie: Request Information Element
11200 * @req_ie_len: len of the req IE
11201 * @resp_ie: Response IE
11202 * @resp_ie_len: len of ht response IE
11203 * @status: status
11204 * @gfp: Kernel Flag
11205 *
11206 * The API is a wrapper to send connection status to supplicant
11207 *
11208 * Return: Void
11209 */
Abhishek Singhbbe0b2a2016-12-05 11:57:36 +053011210void hdd_connect_result(struct net_device *dev,
11211 const u8 *bssid,
11212 tCsrRoamInfo *roam_info,
11213 const u8 *req_ie,
11214 size_t req_ie_len,
11215 const u8 * resp_ie,
11216 size_t resp_ie_len,
11217 u16 status,
11218 gfp_t gfp)
11219{
11220 cfg80211_connect_result(dev, bssid, req_ie, req_ie_len,
11221 resp_ie, resp_ie_len, status, gfp);
11222}
11223#endif
11224
Jeff Johnson295189b2012-06-20 16:38:30 -070011225VOS_STATUS hdd_start_all_adapters( hdd_context_t *pHddCtx )
11226{
11227 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
11228 VOS_STATUS status;
11229 hdd_adapter_t *pAdapter;
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +053011230 eConnectionState connState;
Hanumanth Reddy Pothulada449f12018-03-13 18:19:19 +053011231 v_CONTEXT_t pVosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -070011232
11233 ENTER();
11234
11235 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
11236
11237 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
11238 {
11239 pAdapter = pAdapterNode->pAdapter;
11240
Kumar Anand82c009f2014-05-29 00:29:42 -070011241 hdd_wmm_init( pAdapter );
11242
Jeff Johnson295189b2012-06-20 16:38:30 -070011243 switch(pAdapter->device_mode)
11244 {
11245 case WLAN_HDD_INFRA_STATION:
11246 case WLAN_HDD_P2P_CLIENT:
Jeff Johnsone7245742012-09-05 17:12:55 -070011247 case WLAN_HDD_P2P_DEVICE:
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +053011248
11249 connState = (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState;
11250
Jeff Johnson295189b2012-06-20 16:38:30 -070011251 hdd_init_station_mode(pAdapter);
11252 /* Open the gates for HDD to receive Wext commands */
11253 pAdapter->isLinkUpSvcNeeded = FALSE;
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070011254 pHddCtx->scan_info.mScanPending = FALSE;
11255 pHddCtx->scan_info.waitScanResult = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070011256
11257 //Trigger the initial scan
Mukul Sharmae74e42c2015-08-06 23:55:49 +053011258 if (!pHddCtx->isLogpInProgress)
11259 hdd_wlan_initial_scan(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070011260
11261 //Indicate disconnect event to supplicant if associated previously
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +053011262 if (eConnectionState_Associated == connState ||
11263 eConnectionState_IbssConnected == connState )
Jeff Johnson295189b2012-06-20 16:38:30 -070011264 {
11265 union iwreq_data wrqu;
11266 memset(&wrqu, '\0', sizeof(wrqu));
11267 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
11268 memset(wrqu.ap_addr.sa_data,'\0',ETH_ALEN);
11269 wireless_send_event(pAdapter->dev, SIOCGIWAP, &wrqu, NULL);
Srinivas Girigowda66c05eb2013-07-14 13:06:01 -070011270 pAdapter->sessionCtx.station.hdd_ReassocScenario = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070011271
Jeff Johnson295189b2012-06-20 16:38:30 -070011272 /* indicate disconnected event to nl80211 */
Mahesh A Saptasagar9ff4bcc2016-06-01 17:17:50 +053011273 wlan_hdd_cfg80211_indicate_disconnect(pAdapter->dev, false,
Mahesh A Saptasagarb5a15142016-05-25 11:27:43 +053011274 WLAN_REASON_UNSPECIFIED);
Jeff Johnson295189b2012-06-20 16:38:30 -070011275 }
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +053011276 else if (eConnectionState_Connecting == connState)
11277 {
11278 /*
11279 * Indicate connect failure to supplicant if we were in the
11280 * process of connecting
11281 */
Abhishek Singhbbe0b2a2016-12-05 11:57:36 +053011282 hdd_connect_result(pAdapter->dev, NULL, NULL,
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +053011283 NULL, 0, NULL, 0,
11284 WLAN_STATUS_ASSOC_DENIED_UNSPEC,
11285 GFP_KERNEL);
11286 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011287 break;
11288
11289 case WLAN_HDD_SOFTAP:
Hanumanth Reddy Pothulad864f312017-01-18 16:16:08 +053011290 if (pHddCtx->cfg_ini->sap_internal_restart) {
Hanumanth Reddy Pothula15bc0fa2017-02-03 17:24:17 +053011291 hdd_init_ap_mode(pAdapter, true);
Hanumanth Reddy Pothulad864f312017-01-18 16:16:08 +053011292 status = hdd_sta_id_hash_attach(pAdapter);
11293 if (VOS_STATUS_SUCCESS != status)
11294 {
11295 hddLog(VOS_TRACE_LEVEL_FATAL,
11296 FL("failed to attach hash for"));
11297 }
11298 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011299 break;
11300
11301 case WLAN_HDD_P2P_GO:
Sameer Thalappiledf0d792013-08-09 14:31:03 -070011302 hddLog(VOS_TRACE_LEVEL_ERROR, "%s [SSR] send stop ap to supplicant",
Jeff Johnson295189b2012-06-20 16:38:30 -070011303 __func__);
Sameer Thalappiledf0d792013-08-09 14:31:03 -070011304 cfg80211_ap_stopped(pAdapter->dev, GFP_KERNEL);
Jeff Johnson295189b2012-06-20 16:38:30 -070011305 break;
11306
11307 case WLAN_HDD_MONITOR:
Hanumanth Reddy Pothulada449f12018-03-13 18:19:19 +053011308 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
11309
11310 hddLog(VOS_TRACE_LEVEL_INFO, FL("[SSR] monitor mode"));
11311 if (!pVosContext) {
11312 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos context is NULL"));
11313 break;
11314 }
11315
11316 hdd_init_tx_rx(pAdapter);
11317 WLANTL_SetMonRxCbk( pVosContext, hdd_rx_packet_monitor_cbk);
Jeff Johnson295189b2012-06-20 16:38:30 -070011318 break;
Hanumanth Reddy Pothulada449f12018-03-13 18:19:19 +053011319
Jeff Johnson295189b2012-06-20 16:38:30 -070011320 default:
11321 break;
11322 }
11323
11324 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
11325 pAdapterNode = pNext;
11326 }
11327
11328 EXIT();
11329
11330 return VOS_STATUS_SUCCESS;
11331}
11332
11333VOS_STATUS hdd_reconnect_all_adapters( hdd_context_t *pHddCtx )
11334{
11335 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
11336 hdd_adapter_t *pAdapter;
11337 VOS_STATUS status;
11338 v_U32_t roamId;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011339 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070011340
11341 ENTER();
11342
11343 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
11344
11345 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
11346 {
11347 pAdapter = pAdapterNode->pAdapter;
11348
11349 if( (WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
11350 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
11351 {
11352 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
11353 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
11354
Abhishek Singhf4669da2014-05-26 15:07:49 +053011355 hddLog(VOS_TRACE_LEVEL_INFO,
11356 "%s: Set HDD connState to eConnectionState_NotConnected",
11357 __func__);
Ganesh Kondabattini04338412015-09-14 15:39:09 +053011358 spin_lock_bh(&pAdapter->lock_for_active_session);
11359 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState)
11360 {
11361 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
11362 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011363 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
Ganesh Kondabattini04338412015-09-14 15:39:09 +053011364 spin_unlock_bh(&pAdapter->lock_for_active_session);
Jeff Johnson295189b2012-06-20 16:38:30 -070011365 init_completion(&pAdapter->disconnect_comp_var);
11366 sme_RoamDisconnect(pHddCtx->hHal, pAdapter->sessionId,
11367 eCSR_DISCONNECT_REASON_UNSPECIFIED);
11368
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011369 ret = wait_for_completion_interruptible_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -070011370 &pAdapter->disconnect_comp_var,
11371 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011372 if (0 >= ret)
11373 hddLog(LOGE, "%s: failure waiting for disconnect_comp_var %ld",
11374 __func__, ret);
Jeff Johnson295189b2012-06-20 16:38:30 -070011375
11376 pWextState->roamProfile.csrPersona = pAdapter->device_mode;
11377 pHddCtx->isAmpAllowed = VOS_FALSE;
11378 sme_RoamConnect(pHddCtx->hHal,
11379 pAdapter->sessionId, &(pWextState->roamProfile),
11380 &roamId);
11381 }
11382
11383 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
11384 pAdapterNode = pNext;
11385 }
11386
11387 EXIT();
11388
11389 return VOS_STATUS_SUCCESS;
11390}
11391
Sudhir Sattayappa Kohalli90e4c752013-03-21 14:25:04 -070011392void hdd_dump_concurrency_info(hdd_context_t *pHddCtx)
11393{
11394 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
11395 VOS_STATUS status;
11396 hdd_adapter_t *pAdapter;
11397 hdd_station_ctx_t *pHddStaCtx;
11398 hdd_ap_ctx_t *pHddApCtx;
11399 hdd_hostapd_state_t * pHostapdState;
11400 tCsrBssid staBssid = { 0 }, p2pBssid = { 0 }, apBssid = { 0 };
11401 v_U8_t staChannel = 0, p2pChannel = 0, apChannel = 0;
11402 const char *p2pMode = "DEV";
11403 const char *ccMode = "Standalone";
Sudhir Sattayappa Kohalli90e4c752013-03-21 14:25:04 -070011404
11405 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
11406 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
11407 {
11408 pAdapter = pAdapterNode->pAdapter;
11409 switch (pAdapter->device_mode) {
11410 case WLAN_HDD_INFRA_STATION:
11411 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
11412 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState) {
11413 staChannel = pHddStaCtx->conn_info.operationChannel;
11414 memcpy(staBssid, pHddStaCtx->conn_info.bssId, sizeof(staBssid));
11415 }
11416 break;
11417 case WLAN_HDD_P2P_CLIENT:
11418 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
11419 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState) {
11420 p2pChannel = pHddStaCtx->conn_info.operationChannel;
11421 memcpy(p2pBssid, pHddStaCtx->conn_info.bssId, sizeof(p2pBssid));
11422 p2pMode = "CLI";
11423 }
11424 break;
11425 case WLAN_HDD_P2P_GO:
11426 pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
11427 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
11428 if (pHostapdState->bssState == BSS_START && pHostapdState->vosStatus==VOS_STATUS_SUCCESS) {
11429 p2pChannel = pHddApCtx->operatingChannel;
11430 memcpy(p2pBssid, pAdapter->macAddressCurrent.bytes, sizeof(p2pBssid));
11431 }
11432 p2pMode = "GO";
11433 break;
11434 case WLAN_HDD_SOFTAP:
11435 pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
11436 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
11437 if (pHostapdState->bssState == BSS_START && pHostapdState->vosStatus==VOS_STATUS_SUCCESS) {
11438 apChannel = pHddApCtx->operatingChannel;
11439 memcpy(apBssid, pAdapter->macAddressCurrent.bytes, sizeof(apBssid));
11440 }
11441 break;
11442 default:
11443 break;
11444 }
11445 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
11446 pAdapterNode = pNext;
11447 }
11448 if (staChannel > 0 && (apChannel > 0 || p2pChannel > 0)) {
11449 ccMode = (p2pChannel==staChannel||apChannel==staChannel) ? "SCC" : "MCC";
11450 }
Yeshwanth Sriram Guntuka0004c0b2017-12-06 14:43:49 +053011451 hddLog(VOS_TRACE_LEVEL_ERROR, "wlan(%d) " MAC_ADDRESS_STR " %s",
11452 staChannel, MAC_ADDR_ARRAY(staBssid), ccMode);
Sudhir Sattayappa Kohalli90e4c752013-03-21 14:25:04 -070011453 if (p2pChannel > 0) {
Sushant Kaushikdc3184b2015-10-09 12:00:21 +053011454 hddLog(VOS_TRACE_LEVEL_ERROR, "p2p-%s(%d) " MAC_ADDRESS_STR,
Sudhir Sattayappa Kohalli90e4c752013-03-21 14:25:04 -070011455 p2pMode, p2pChannel, MAC_ADDR_ARRAY(p2pBssid));
11456 }
11457 if (apChannel > 0) {
Sushant Kaushikdc3184b2015-10-09 12:00:21 +053011458 hddLog(VOS_TRACE_LEVEL_ERROR, "AP(%d) " MAC_ADDRESS_STR,
Sudhir Sattayappa Kohalli90e4c752013-03-21 14:25:04 -070011459 apChannel, MAC_ADDR_ARRAY(apBssid));
11460 }
11461
11462 if (p2pChannel > 0 && apChannel > 0) {
11463 hddLog(VOS_TRACE_LEVEL_ERROR, "Error concurrent SAP %d and P2P %d which is not support", apChannel, p2pChannel);
11464 }
11465}
11466
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -070011467bool hdd_is_ssr_required( void)
Jeff Johnson295189b2012-06-20 16:38:30 -070011468{
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -070011469 return (isSsrRequired == HDD_SSR_REQUIRED);
Jeff Johnson295189b2012-06-20 16:38:30 -070011470}
11471
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -070011472/* Once SSR is disabled then it cannot be set. */
11473void hdd_set_ssr_required( e_hdd_ssr_required value)
Jeff Johnson295189b2012-06-20 16:38:30 -070011474{
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -070011475 if (HDD_SSR_DISABLED == isSsrRequired)
11476 return;
11477
Jeff Johnson295189b2012-06-20 16:38:30 -070011478 isSsrRequired = value;
11479}
11480
Hema Aparna Medicharla6b4d4f32015-06-23 04:09:12 +053011481void hdd_set_pre_close( hdd_context_t *pHddCtx)
11482{
11483 sme_PreClose(pHddCtx->hHal);
11484}
11485
Jeff Johnson295189b2012-06-20 16:38:30 -070011486VOS_STATUS hdd_get_front_adapter( hdd_context_t *pHddCtx,
11487 hdd_adapter_list_node_t** ppAdapterNode)
11488{
11489 VOS_STATUS status;
Mukul Sharmaae1266d2015-06-26 15:29:53 +053011490 spin_lock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -070011491 status = hdd_list_peek_front ( &pHddCtx->hddAdapters,
11492 (hdd_list_node_t**) ppAdapterNode );
Mukul Sharmaae1266d2015-06-26 15:29:53 +053011493 spin_unlock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -070011494 return status;
11495}
11496
11497VOS_STATUS hdd_get_next_adapter( hdd_context_t *pHddCtx,
11498 hdd_adapter_list_node_t* pAdapterNode,
11499 hdd_adapter_list_node_t** pNextAdapterNode)
11500{
11501 VOS_STATUS status;
Mukul Sharmaae1266d2015-06-26 15:29:53 +053011502 spin_lock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -070011503 status = hdd_list_peek_next ( &pHddCtx->hddAdapters,
11504 (hdd_list_node_t*) pAdapterNode,
11505 (hdd_list_node_t**)pNextAdapterNode );
11506
Mukul Sharmaae1266d2015-06-26 15:29:53 +053011507 spin_unlock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -070011508 return status;
11509}
11510
11511VOS_STATUS hdd_remove_adapter( hdd_context_t *pHddCtx,
11512 hdd_adapter_list_node_t* pAdapterNode)
11513{
11514 VOS_STATUS status;
Mukul Sharmaae1266d2015-06-26 15:29:53 +053011515 spin_lock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -070011516 status = hdd_list_remove_node ( &pHddCtx->hddAdapters,
11517 &pAdapterNode->node );
Mukul Sharmaae1266d2015-06-26 15:29:53 +053011518 spin_unlock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -070011519 return status;
11520}
11521
11522VOS_STATUS hdd_remove_front_adapter( hdd_context_t *pHddCtx,
11523 hdd_adapter_list_node_t** ppAdapterNode)
11524{
11525 VOS_STATUS status;
Mukul Sharmaae1266d2015-06-26 15:29:53 +053011526 spin_lock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -070011527 status = hdd_list_remove_front( &pHddCtx->hddAdapters,
11528 (hdd_list_node_t**) ppAdapterNode );
Mukul Sharmaae1266d2015-06-26 15:29:53 +053011529 spin_unlock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -070011530 return status;
11531}
11532
11533VOS_STATUS hdd_add_adapter_back( hdd_context_t *pHddCtx,
11534 hdd_adapter_list_node_t* pAdapterNode)
11535{
11536 VOS_STATUS status;
Mukul Sharmaae1266d2015-06-26 15:29:53 +053011537 spin_lock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -070011538 status = hdd_list_insert_back ( &pHddCtx->hddAdapters,
11539 (hdd_list_node_t*) pAdapterNode );
Mukul Sharmaae1266d2015-06-26 15:29:53 +053011540 spin_unlock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -070011541 return status;
11542}
11543
11544VOS_STATUS hdd_add_adapter_front( hdd_context_t *pHddCtx,
11545 hdd_adapter_list_node_t* pAdapterNode)
11546{
11547 VOS_STATUS status;
Mukul Sharmaae1266d2015-06-26 15:29:53 +053011548 spin_lock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -070011549 status = hdd_list_insert_front ( &pHddCtx->hddAdapters,
11550 (hdd_list_node_t*) pAdapterNode );
Mukul Sharmaae1266d2015-06-26 15:29:53 +053011551 spin_unlock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -070011552 return status;
11553}
11554
11555hdd_adapter_t * hdd_get_adapter_by_macaddr( hdd_context_t *pHddCtx,
11556 tSirMacAddr macAddr )
11557{
11558 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
11559 hdd_adapter_t *pAdapter;
11560 VOS_STATUS status;
11561
11562 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
11563
11564 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
11565 {
11566 pAdapter = pAdapterNode->pAdapter;
11567
11568 if( pAdapter && vos_mem_compare( pAdapter->macAddressCurrent.bytes,
11569 macAddr, sizeof(tSirMacAddr) ) )
11570 {
11571 return pAdapter;
11572 }
11573 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
11574 pAdapterNode = pNext;
11575 }
11576
11577 return NULL;
11578
11579}
11580
11581hdd_adapter_t * hdd_get_adapter_by_name( hdd_context_t *pHddCtx, tANI_U8 *name )
11582{
11583 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
11584 hdd_adapter_t *pAdapter;
11585 VOS_STATUS status;
11586
11587 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
11588
11589 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
11590 {
11591 pAdapter = pAdapterNode->pAdapter;
11592
11593 if( pAdapter && !strncmp( pAdapter->dev->name, (const char *)name,
11594 IFNAMSIZ ) )
11595 {
11596 return pAdapter;
11597 }
11598 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
11599 pAdapterNode = pNext;
11600 }
11601
11602 return NULL;
11603
11604}
11605
Ganesh Kondabattinicbfdc392015-09-11 19:12:59 +053011606hdd_adapter_t *hdd_get_adapter_by_sme_session_id( hdd_context_t *pHddCtx,
11607 tANI_U32 sme_session_id )
11608{
11609 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
11610 hdd_adapter_t *pAdapter;
11611 VOS_STATUS vos_status;
11612
11613
11614 vos_status = hdd_get_front_adapter( pHddCtx, &pAdapterNode);
11615
11616 while ((NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == vos_status))
11617 {
11618 pAdapter = pAdapterNode->pAdapter;
11619
11620 if (pAdapter->sessionId == sme_session_id)
11621 return pAdapter;
11622
11623 vos_status = hdd_get_next_adapter(pHddCtx, pAdapterNode, &pNext);
11624 pAdapterNode = pNext;
11625 }
11626
11627 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11628 "%s: sme_session_id %d does not exist with host",
11629 __func__, sme_session_id);
11630
11631 return NULL;
11632}
11633
Jeff Johnson295189b2012-06-20 16:38:30 -070011634hdd_adapter_t * hdd_get_adapter( hdd_context_t *pHddCtx, device_mode_t mode )
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 && (mode == pAdapter->device_mode) )
11647 {
11648 return pAdapter;
11649 }
11650 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
11651 pAdapterNode = pNext;
11652 }
11653
11654 return NULL;
11655
11656}
11657
11658//Remove this function later
11659hdd_adapter_t * hdd_get_mon_adapter( hdd_context_t *pHddCtx )
11660{
11661 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
11662 hdd_adapter_t *pAdapter;
11663 VOS_STATUS status;
11664
11665 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
11666
11667 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
11668 {
11669 pAdapter = pAdapterNode->pAdapter;
11670
11671 if( pAdapter && WLAN_HDD_MONITOR == pAdapter->device_mode )
11672 {
11673 return pAdapter;
11674 }
11675
11676 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
11677 pAdapterNode = pNext;
11678 }
11679
11680 return NULL;
11681
11682}
11683
Jeff Johnson295189b2012-06-20 16:38:30 -070011684/**---------------------------------------------------------------------------
11685
Mahesh A Saptasgar64534612014-09-23 13:13:33 +053011686 \brief hdd_get_operating_channel() -
Jeff Johnson295189b2012-06-20 16:38:30 -070011687
11688 This API returns the operating channel of the requested device mode
11689
11690 \param - pHddCtx - Pointer to the HDD context.
11691 - mode - Device mode for which operating channel is required
11692 suported modes - WLAN_HDD_INFRA_STATION, WLAN_HDD_P2P_CLIENT
11693 WLAN_HDD_SOFTAP, WLAN_HDD_P2P_GO.
11694 \return - channel number. "0" id the requested device is not found OR it is not connected.
11695 --------------------------------------------------------------------------*/
11696v_U8_t hdd_get_operating_channel( hdd_context_t *pHddCtx, device_mode_t mode )
11697{
11698 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
11699 VOS_STATUS status;
11700 hdd_adapter_t *pAdapter;
11701 v_U8_t operatingChannel = 0;
11702
11703 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
11704
11705 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
11706 {
11707 pAdapter = pAdapterNode->pAdapter;
11708
11709 if( mode == pAdapter->device_mode )
11710 {
11711 switch(pAdapter->device_mode)
11712 {
11713 case WLAN_HDD_INFRA_STATION:
11714 case WLAN_HDD_P2P_CLIENT:
11715 if( hdd_connIsConnected( WLAN_HDD_GET_STATION_CTX_PTR( pAdapter )) )
11716 operatingChannel = (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.operationChannel;
11717 break;
11718 case WLAN_HDD_SOFTAP:
11719 case WLAN_HDD_P2P_GO:
11720 /*softap connection info */
11721 if(test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
11722 operatingChannel = (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->operatingChannel;
11723 break;
11724 default:
11725 break;
11726 }
11727
11728 break; //Found the device of interest. break the loop
11729 }
11730
11731 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
11732 pAdapterNode = pNext;
11733 }
11734 return operatingChannel;
11735}
11736
11737#ifdef WLAN_FEATURE_PACKET_FILTERING
11738/**---------------------------------------------------------------------------
11739
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053011740 \brief __hdd_set_multicast_list() -
Jeff Johnson295189b2012-06-20 16:38:30 -070011741
11742 This used to set the multicast address list.
11743
11744 \param - dev - Pointer to the WLAN device.
11745 - skb - Pointer to OS packet (sk_buff).
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053011746 \return - success/fail
Jeff Johnson295189b2012-06-20 16:38:30 -070011747
11748 --------------------------------------------------------------------------*/
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053011749static void __hdd_set_multicast_list(struct net_device *dev)
Jeff Johnson295189b2012-06-20 16:38:30 -070011750{
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053011751 hdd_adapter_t *pAdapter;
11752 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070011753 int mc_count;
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053011754 int i = 0, ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070011755 struct netdev_hw_addr *ha;
Gopichand Nakkala0f276812013-02-24 14:45:51 +053011756
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053011757 ENTER();
11758
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053011759 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkala0f276812013-02-24 14:45:51 +053011760 if (NULL == pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -070011761 {
11762 hddLog(VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala0f276812013-02-24 14:45:51 +053011763 "%s: Adapter context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070011764 return;
11765 }
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053011766 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
11767 ret = wlan_hdd_validate_context(pHddCtx);
11768 if (0 != ret)
11769 {
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053011770 return;
11771 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011772 if (dev->flags & IFF_ALLMULTI)
11773 {
11774 hddLog(VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070011775 "%s: allow all multicast frames", __func__);
Gopichand Nakkala0f276812013-02-24 14:45:51 +053011776 pAdapter->mc_addr_list.mc_cnt = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070011777 }
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053011778 else
Jeff Johnson295189b2012-06-20 16:38:30 -070011779 {
11780 mc_count = netdev_mc_count(dev);
11781 hddLog(VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070011782 "%s: mc_count = %u", __func__, mc_count);
Jeff Johnson295189b2012-06-20 16:38:30 -070011783 if (mc_count > WLAN_HDD_MAX_MC_ADDR_LIST)
11784 {
11785 hddLog(VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070011786 "%s: No free filter available; allow all multicast frames", __func__);
Gopichand Nakkala0f276812013-02-24 14:45:51 +053011787 pAdapter->mc_addr_list.mc_cnt = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070011788 return;
11789 }
11790
Gopichand Nakkala0f276812013-02-24 14:45:51 +053011791 pAdapter->mc_addr_list.mc_cnt = mc_count;
Jeff Johnson295189b2012-06-20 16:38:30 -070011792
11793 netdev_for_each_mc_addr(ha, dev) {
11794 if (i == mc_count)
11795 break;
Gopichand Nakkala0f276812013-02-24 14:45:51 +053011796 memset(&(pAdapter->mc_addr_list.addr[i][0]), 0, ETH_ALEN);
11797 memcpy(&(pAdapter->mc_addr_list.addr[i][0]), ha->addr, ETH_ALEN);
Arif Hussain6d2a3322013-11-17 19:50:10 -080011798 hddLog(VOS_TRACE_LEVEL_INFO, "%s: mlist[%d] = "MAC_ADDRESS_STR,
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053011799 __func__, i,
Gopichand Nakkala0f276812013-02-24 14:45:51 +053011800 MAC_ADDR_ARRAY(pAdapter->mc_addr_list.addr[i]));
Jeff Johnson295189b2012-06-20 16:38:30 -070011801 i++;
11802 }
11803 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053011804
Ganesh Kondabattinifb37e652015-10-09 15:46:47 +053011805 if (pHddCtx->hdd_wlan_suspended)
11806 {
11807 /*
11808 * Configure the Mcast address list to FW
11809 * If wlan is already in suspend mode
11810 */
11811 wlan_hdd_set_mc_addr_list(pAdapter, TRUE);
11812 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053011813 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070011814 return;
11815}
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053011816
11817static void hdd_set_multicast_list(struct net_device *dev)
11818{
11819 vos_ssr_protect(__func__);
11820 __hdd_set_multicast_list(dev);
11821 vos_ssr_unprotect(__func__);
11822}
Jeff Johnson295189b2012-06-20 16:38:30 -070011823#endif
11824
11825/**---------------------------------------------------------------------------
11826
11827 \brief hdd_select_queue() -
11828
11829 This function is registered with the Linux OS for network
11830 core to decide which queue to use first.
11831
11832 \param - dev - Pointer to the WLAN device.
11833 - skb - Pointer to OS packet (sk_buff).
11834 \return - ac, Queue Index/access category corresponding to UP in IP header
11835
11836 --------------------------------------------------------------------------*/
11837v_U16_t hdd_select_queue(struct net_device *dev,
Anand N Sunkade9adb1b2015-07-29 09:56:45 +053011838 struct sk_buff *skb
11839#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,13,0))
11840 , void *accel_priv
11841#endif
11842#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
11843 , select_queue_fallback_t fallback
11844#endif
11845)
Jeff Johnson295189b2012-06-20 16:38:30 -070011846{
11847 return hdd_wmm_select_queue(dev, skb);
11848}
11849
11850
11851/**---------------------------------------------------------------------------
11852
11853 \brief hdd_wlan_initial_scan() -
11854
11855 This function triggers the initial scan
11856
11857 \param - pAdapter - Pointer to the HDD adapter.
11858
11859 --------------------------------------------------------------------------*/
11860void hdd_wlan_initial_scan(hdd_adapter_t *pAdapter)
11861{
11862 tCsrScanRequest scanReq;
11863 tCsrChannelInfo channelInfo;
11864 eHalStatus halStatus;
Jeff Johnson02797792013-10-26 19:17:13 -070011865 tANI_U32 scanId;
Jeff Johnson295189b2012-06-20 16:38:30 -070011866 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
11867
11868 vos_mem_zero(&scanReq, sizeof(tCsrScanRequest));
11869 vos_mem_set(&scanReq.bssid, sizeof(tCsrBssid), 0xff);
11870 scanReq.BSSType = eCSR_BSS_TYPE_ANY;
11871
11872 if(sme_Is11dSupported(pHddCtx->hHal))
11873 {
11874 halStatus = sme_ScanGetBaseChannels( pHddCtx->hHal, &channelInfo );
11875 if ( HAL_STATUS_SUCCESS( halStatus ) )
11876 {
11877 scanReq.ChannelInfo.ChannelList = vos_mem_malloc(channelInfo.numOfChannels);
11878 if( !scanReq.ChannelInfo.ChannelList )
11879 {
11880 hddLog(VOS_TRACE_LEVEL_ERROR, "%s kmalloc failed", __func__);
11881 vos_mem_free(channelInfo.ChannelList);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -080011882 channelInfo.ChannelList = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070011883 return;
11884 }
11885 vos_mem_copy(scanReq.ChannelInfo.ChannelList, channelInfo.ChannelList,
11886 channelInfo.numOfChannels);
11887 scanReq.ChannelInfo.numOfChannels = channelInfo.numOfChannels;
11888 vos_mem_free(channelInfo.ChannelList);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -080011889 channelInfo.ChannelList = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070011890 }
11891
11892 scanReq.scanType = eSIR_PASSIVE_SCAN;
11893 scanReq.requestType = eCSR_SCAN_REQUEST_11D_SCAN;
11894 scanReq.maxChnTime = pHddCtx->cfg_ini->nPassiveMaxChnTime;
11895 scanReq.minChnTime = pHddCtx->cfg_ini->nPassiveMinChnTime;
11896 }
11897 else
11898 {
11899 scanReq.scanType = eSIR_ACTIVE_SCAN;
11900 scanReq.requestType = eCSR_SCAN_REQUEST_FULL_SCAN;
11901 scanReq.maxChnTime = pHddCtx->cfg_ini->nActiveMaxChnTime;
11902 scanReq.minChnTime = pHddCtx->cfg_ini->nActiveMinChnTime;
11903 }
11904
11905 halStatus = sme_ScanRequest(pHddCtx->hHal, pAdapter->sessionId, &scanReq, &scanId, NULL, NULL);
11906 if ( !HAL_STATUS_SUCCESS( halStatus ) )
11907 {
11908 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: sme_ScanRequest failed status code %d",
11909 __func__, halStatus );
11910 }
11911
11912 if(sme_Is11dSupported(pHddCtx->hHal))
11913 vos_mem_free(scanReq.ChannelInfo.ChannelList);
11914}
11915
Jeff Johnson295189b2012-06-20 16:38:30 -070011916/**---------------------------------------------------------------------------
11917
11918 \brief hdd_full_power_callback() - HDD full power callback function
11919
11920 This is the function invoked by SME to inform the result of a full power
11921 request issued by HDD
11922
11923 \param - callbackcontext - Pointer to cookie
11924 \param - status - result of request
11925
11926 \return - None
11927
11928 --------------------------------------------------------------------------*/
11929static void hdd_full_power_callback(void *callbackContext, eHalStatus status)
11930{
Jeff Johnson72a40512013-12-19 10:14:15 -080011931 struct statsContext *pContext = callbackContext;
Jeff Johnson295189b2012-06-20 16:38:30 -070011932
11933 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnsonc135a9a2017-09-19 08:37:24 -070011934 "%s: context = %pK, status = %d", __func__, pContext, status);
Jeff Johnson295189b2012-06-20 16:38:30 -070011935
11936 if (NULL == callbackContext)
11937 {
11938 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnsonc135a9a2017-09-19 08:37:24 -070011939 "%s: Bad param, context [%pK]",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070011940 __func__, callbackContext);
Jeff Johnson295189b2012-06-20 16:38:30 -070011941 return;
11942 }
11943
Jeff Johnson72a40512013-12-19 10:14:15 -080011944 /* there is a race condition that exists between this callback
11945 function and the caller since the caller could time out either
11946 before or while this code is executing. we use a spinlock to
11947 serialize these actions */
11948 spin_lock(&hdd_context_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -070011949
11950 if (POWER_CONTEXT_MAGIC != pContext->magic)
11951 {
11952 /* the caller presumably timed out so there is nothing we can do */
Jeff Johnson72a40512013-12-19 10:14:15 -080011953 spin_unlock(&hdd_context_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -070011954 hddLog(VOS_TRACE_LEVEL_WARN,
11955 "%s: Invalid context, magic [%08x]",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070011956 __func__, pContext->magic);
Jeff Johnson295189b2012-06-20 16:38:30 -070011957 return;
11958 }
11959
Jeff Johnson72a40512013-12-19 10:14:15 -080011960 /* context is valid so caller is still waiting */
11961
11962 /* paranoia: invalidate the magic */
11963 pContext->magic = 0;
11964
11965 /* notify the caller */
Jeff Johnson295189b2012-06-20 16:38:30 -070011966 complete(&pContext->completion);
Jeff Johnson72a40512013-12-19 10:14:15 -080011967
11968 /* serialization is complete */
11969 spin_unlock(&hdd_context_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -070011970}
11971
Katya Nigamf0511f62015-05-05 16:40:57 +053011972void wlan_hdd_mon_set_typesubtype( hdd_mon_ctx_t *pMonCtx,int type)
11973{
11974 pMonCtx->typeSubtypeBitmap = 0;
11975 if( type%10 ) /* Management Packets */
11976 pMonCtx->typeSubtypeBitmap |= 0xFFFF;
11977 type/=10;
11978 if( type%10 ) /* Control Packets */
11979 pMonCtx->typeSubtypeBitmap |= 0xFFFF0000;
11980 type/=10;
11981 if( type%10 ) /* Data Packets */
11982 pMonCtx->typeSubtypeBitmap |= 0xFFFF00000000;
11983}
11984
Hanumanth Reddy Pothulab8be9ab2018-04-12 20:03:05 +053011985VOS_STATUS wlan_hdd_mon_postMsg(void *context, hdd_mon_ctx_t *pMonCtx,
11986 void* callback)
Katya Nigamf0511f62015-05-05 16:40:57 +053011987{
11988 vos_msg_t monMsg;
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +053011989 tSirMonModeReq *pMonModeReq;
Katya Nigamf0511f62015-05-05 16:40:57 +053011990
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +053011991 if (MON_MODE_START == pMonCtx->state)
11992 monMsg.type = WDA_MON_START_REQ;
11993 else if (MON_MODE_STOP == pMonCtx->state)
11994 monMsg.type = WDA_MON_STOP_REQ;
11995 else {
11996 hddLog(VOS_TRACE_LEVEL_ERROR,
11997 FL("invalid monitor state %d"), pMonCtx->state);
Katya Nigamf0511f62015-05-05 16:40:57 +053011998 return VOS_STATUS_E_FAILURE;
11999 }
12000
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +053012001 pMonModeReq = vos_mem_malloc(sizeof(tSirMonModeReq));
12002 if (pMonModeReq == NULL) {
12003 hddLog(VOS_TRACE_LEVEL_ERROR,
12004 FL("fail to allocate memory for monitor mode req"));
12005 return VOS_STATUS_E_FAILURE;
12006 }
Katya Nigamf0511f62015-05-05 16:40:57 +053012007
Hanumanth Reddy Pothulab8be9ab2018-04-12 20:03:05 +053012008 pMonModeReq->context = context;
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +053012009 pMonModeReq->data = pMonCtx;
12010 pMonModeReq->callback = callback;
Katya Nigamf0511f62015-05-05 16:40:57 +053012011
Katya Nigamf0511f62015-05-05 16:40:57 +053012012 monMsg.reserved = 0;
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +053012013 monMsg.bodyptr = pMonModeReq;
Katya Nigamf0511f62015-05-05 16:40:57 +053012014 monMsg.bodyval = 0;
12015
12016 if (VOS_STATUS_SUCCESS != vos_mq_post_message(
12017 VOS_MODULE_ID_WDA,(vos_msg_t *)&monMsg)) {
12018 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: : Failed to post Msg to HAL",__func__);
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +053012019 vos_mem_free(pMonModeReq);
Katya Nigamf0511f62015-05-05 16:40:57 +053012020 }
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +053012021 return VOS_STATUS_SUCCESS;
Katya Nigamf0511f62015-05-05 16:40:57 +053012022}
12023
Katya Nigame7b69a82015-04-28 15:24:06 +053012024void wlan_hdd_mon_close(hdd_context_t *pHddCtx)
12025{
12026 VOS_STATUS vosStatus;
12027 v_CONTEXT_t pVosContext = pHddCtx->pvosContext;
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +053012028 hdd_mon_ctx_t *pMonCtx = NULL;
Hanumanth Reddy Pothulab8be9ab2018-04-12 20:03:05 +053012029 int ret;
12030 void *cookie;
12031 struct hdd_request *request;
12032 static const struct hdd_request_params params = {
12033 .priv_size = 0,
12034 .timeout_ms = MON_MODE_MSG_TIMEOUT,
12035 };
Hanumantha Reddy Pothulac99bc062015-09-08 14:59:26 +053012036
Katya Nigame7b69a82015-04-28 15:24:06 +053012037 hdd_adapter_t *pAdapter = hdd_get_adapter(pHddCtx,WLAN_HDD_MONITOR);
12038 if(pAdapter == NULL || pVosContext == NULL)
12039 {
12040 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, "%s:pAdapter is NULL",__func__);
12041 return ;
12042 }
Katya Nigamf0511f62015-05-05 16:40:57 +053012043
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +053012044 pMonCtx = WLAN_HDD_GET_MONITOR_CTX_PTR(pAdapter);
12045 if (pMonCtx!= NULL && pMonCtx->state == MON_MODE_START) {
12046 pMonCtx->state = MON_MODE_STOP;
Hanumanth Reddy Pothulab8be9ab2018-04-12 20:03:05 +053012047 request = hdd_request_alloc(&params);
12048 if (!request) {
12049 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Request allocation failure"));
12050 return;
12051 }
12052 cookie = hdd_request_cookie(request);
12053
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +053012054 if (VOS_STATUS_SUCCESS !=
Hanumanth Reddy Pothulab8be9ab2018-04-12 20:03:05 +053012055 wlan_hdd_mon_postMsg(cookie, pMonCtx,
12056 hdd_mon_post_msg_cb)) {
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +053012057 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12058 FL("failed to post MON MODE REQ"));
12059 pMonCtx->state = MON_MODE_START;
Hanumanth Reddy Pothulab8be9ab2018-04-12 20:03:05 +053012060 goto req_put;
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +053012061 }
Hanumanth Reddy Pothulab8be9ab2018-04-12 20:03:05 +053012062
12063 ret = hdd_request_wait_for_response(request);
12064 if (ret)
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +053012065 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Hanumanth Reddy Pothulab8be9ab2018-04-12 20:03:05 +053012066 FL("timeout on monitor mode completion %d"), ret);
12067
12068req_put:
12069 hdd_request_put(request);
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +053012070 }
12071
Katya Nigame7b69a82015-04-28 15:24:06 +053012072 hdd_UnregisterWext(pAdapter->dev);
12073
12074 vos_mon_stop( pVosContext );
12075
12076 vosStatus = vos_sched_close( pVosContext );
12077 if (!VOS_IS_STATUS_SUCCESS(vosStatus)) {
12078 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
12079 "%s: Failed to close VOSS Scheduler",__func__);
12080 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
12081 }
12082
12083 vosStatus = vos_nv_close();
12084 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
12085 {
12086 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
12087 "%s: Failed to close NV", __func__);
12088 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
12089 }
12090
12091 vos_close(pVosContext);
12092
12093 #ifdef WLAN_KD_READY_NOTIFIER
12094 nl_srv_exit(pHddCtx->ptt_pid);
12095 #else
12096 nl_srv_exit();
12097 #endif
12098
Katya Nigame7b69a82015-04-28 15:24:06 +053012099 hdd_close_all_adapters( pHddCtx );
Katya Nigame7b69a82015-04-28 15:24:06 +053012100}
Agrawal Ashish33ec71e2015-11-26 20:20:58 +053012101/**
12102 * hdd_wlan_free_wiphy_channels - free Channel pointer for wiphy
12103 * @ wiphy: the wiphy to validate against
12104 *
12105 * Return: void
12106 */
12107void hdd_wlan_free_wiphy_channels(struct wiphy *wiphy)
12108{
12109 int i =0;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053012110 for (i = 0; i < HDD_NUM_NL80211_BANDS; i++)
Agrawal Ashish33ec71e2015-11-26 20:20:58 +053012111 {
12112 if (NULL != wiphy->bands[i] &&
12113 (NULL != wiphy->bands[i]->channels))
12114 {
12115 vos_mem_free(wiphy->bands[i]->channels);
12116 wiphy->bands[i]->channels = NULL;
12117 }
12118 }
12119}
Jeff Johnson295189b2012-06-20 16:38:30 -070012120/**---------------------------------------------------------------------------
12121
12122 \brief hdd_wlan_exit() - HDD WLAN exit function
12123
12124 This is the driver exit point (invoked during rmmod)
12125
12126 \param - pHddCtx - Pointer to the HDD Context
12127
12128 \return - None
12129
12130 --------------------------------------------------------------------------*/
12131void hdd_wlan_exit(hdd_context_t *pHddCtx)
12132{
12133 eHalStatus halStatus;
12134 v_CONTEXT_t pVosContext = pHddCtx->pvosContext;
12135 VOS_STATUS vosStatus;
Gopichand Nakkala66923aa2013-03-06 23:17:24 +053012136 struct wiphy *wiphy = pHddCtx->wiphy;
Mingcheng Zhu87f22fc2014-01-30 19:23:32 -080012137 hdd_adapter_t* pAdapter = NULL;
Jeff Johnson72a40512013-12-19 10:14:15 -080012138 struct statsContext powerContext;
Jeff Johnson295189b2012-06-20 16:38:30 -070012139 long lrc;
c_hpothu5ab05e92014-06-13 17:34:05 +053012140 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070012141
12142 ENTER();
12143
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +053012144
Katya Nigame7b69a82015-04-28 15:24:06 +053012145 if (VOS_MONITOR_MODE == hdd_get_conparam())
12146 {
12147 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: MONITOR MODE",__func__);
12148 wlan_hdd_mon_close(pHddCtx);
Hanumantha Reddy Pothulac99bc062015-09-08 14:59:26 +053012149 goto free_hdd_ctx;
Katya Nigame7b69a82015-04-28 15:24:06 +053012150 }
12151 else if (VOS_FTM_MODE != hdd_get_conparam())
Jeff Johnson88ba7742013-02-27 14:36:02 -080012152 {
12153 // Unloading, restart logic is no more required.
12154 wlan_hdd_restart_deinit(pHddCtx);
Jeff Johnsone7245742012-09-05 17:12:55 -070012155
Agarwal Ashishb20e0ff2014-12-17 22:50:19 +053012156#ifdef FEATURE_WLAN_TDLS
12157 /* At the time of driver unloading; if tdls connection is present;
12158 * hdd_rx_packet_cbk calls wlan_hdd_tdls_find_peer.
12159 * wlan_hdd_tdls_find_peer always checks for valid context;
12160 * as load/unload in progress there can be a race condition.
12161 * hdd_rx_packet_cbk calls wlan_hdd_tdls_find_peer only
12162 * when tdls state is enabled.
12163 * As soon as driver set load/unload flag; tdls flag also needs
12164 * to be disabled so that hdd_rx_packet_cbk won't call
12165 * wlan_hdd_tdls_find_peer.
12166 */
Masti, Narayanraddi20494af2015-12-17 20:56:42 +053012167 wlan_hdd_tdls_set_mode(pHddCtx, eTDLS_SUPPORT_DISABLED, FALSE,
12168 HDD_SET_TDLS_MODE_SOURCE_USER);
Agarwal Ashishb20e0ff2014-12-17 22:50:19 +053012169#endif
12170
c_hpothu5ab05e92014-06-13 17:34:05 +053012171 vosStatus = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
12172 while (NULL != pAdapterNode && VOS_STATUS_E_EMPTY != vosStatus)
Jeff Johnson295189b2012-06-20 16:38:30 -070012173 {
c_hpothu5ab05e92014-06-13 17:34:05 +053012174 pAdapter = pAdapterNode->pAdapter;
12175 if (NULL != pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -070012176 {
Mahesh A Saptasagar305e2632015-03-04 12:57:33 +053012177 /* Disable TX on the interface, after this hard_start_xmit() will
12178 * not be called on that interface
12179 */
12180 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
12181 netif_tx_disable(pAdapter->dev);
12182
12183 /* Mark the interface status as "down" for outside world */
12184 netif_carrier_off(pAdapter->dev);
12185
Agarwal Ashish9ffa5b92014-11-18 21:07:02 +053012186 /* DeInit the adapter. This ensures that all data packets
12187 * are freed.
12188 */
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +053012189#ifdef FEATURE_WLAN_TDLS
12190 mutex_lock(&pHddCtx->tdls_lock);
12191#endif
c_hpothu002231a2015-02-05 14:58:51 +053012192 hdd_deinit_adapter(pHddCtx, pAdapter, FALSE);
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +053012193#ifdef FEATURE_WLAN_TDLS
12194 mutex_unlock(&pHddCtx->tdls_lock);
12195#endif
Masti, Narayanraddi26378462016-01-05 18:20:28 +053012196 vos_flush_delayed_work(&pHddCtx->scan_ctxt.scan_work);
12197
12198 wlan_hdd_init_deinit_defer_scan_context(&pHddCtx->scan_ctxt);
Agarwal Ashish9ffa5b92014-11-18 21:07:02 +053012199
c_hpothu5ab05e92014-06-13 17:34:05 +053012200 if (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +053012201 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode ||
12202 WLAN_HDD_MONITOR == pAdapter->device_mode)
c_hpothu5ab05e92014-06-13 17:34:05 +053012203 {
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +053012204 if (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
12205 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode)
12206 wlan_hdd_cfg80211_deregister_frames(pAdapter);
12207
c_hpothu5ab05e92014-06-13 17:34:05 +053012208 hdd_UnregisterWext(pAdapter->dev);
12209 }
Kaushik, Sushant4975a572014-10-21 16:07:48 +053012210
Jeff Johnson295189b2012-06-20 16:38:30 -070012211 }
c_hpothu5ab05e92014-06-13 17:34:05 +053012212 vosStatus = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
12213 pAdapterNode = pNext;
Jeff Johnson295189b2012-06-20 16:38:30 -070012214 }
mukul sharmabab477d2015-06-11 17:14:55 +053012215
Kaushik, Sushant4975a572014-10-21 16:07:48 +053012216 // Cancel any outstanding scan requests. We are about to close all
12217 // of our adapters, but an adapter structure is what SME passes back
12218 // to our callback function. Hence if there are any outstanding scan
12219 // requests then there is a race condition between when the adapter
12220 // is closed and when the callback is invoked.We try to resolve that
12221 // race condition here by canceling any outstanding scans before we
12222 // close the adapters.
12223 // Note that the scans may be cancelled in an asynchronous manner,
12224 // so ideally there needs to be some kind of synchronization. Rather
12225 // than introduce a new synchronization here, we will utilize the
12226 // fact that we are about to Request Full Power, and since that is
12227 // synchronized, the expectation is that by the time Request Full
12228 // Power has completed all scans will be cancelled.
12229 if (pHddCtx->scan_info.mScanPending)
12230 {
Hema Aparna Medicharlaf05f6cd2015-01-21 14:44:19 +053012231 if(NULL != pAdapter)
12232 {
12233 hddLog(VOS_TRACE_LEVEL_INFO,
12234 FL("abort scan mode: %d sessionId: %d"),
12235 pAdapter->device_mode,
12236 pAdapter->sessionId);
12237 }
12238 hdd_abort_mac_scan(pHddCtx,
12239 pHddCtx->scan_info.sessionId,
12240 eCSR_SCAN_ABORT_DEFAULT);
Kaushik, Sushant4975a572014-10-21 16:07:48 +053012241 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012242 }
c_hpothu5ab05e92014-06-13 17:34:05 +053012243 else
Jeff Johnson88ba7742013-02-27 14:36:02 -080012244 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012245 hddLog(VOS_TRACE_LEVEL_INFO,"%s: FTM MODE",__func__);
Hanumantha Reddy Pothula45af96b2015-02-12 16:07:58 +053012246 if (pHddCtx->ftm.ftm_state == WLAN_FTM_STARTING)
12247 {
12248 INIT_COMPLETION(pHddCtx->ftm.startCmpVar);
12249 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
12250 "%s: in middle of FTM START", __func__);
12251 lrc = wait_for_completion_timeout(&pHddCtx->ftm.startCmpVar,
12252 msecs_to_jiffies(20000));
12253 if(!lrc)
12254 {
12255 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
12256 "%s: timedout on ftmStartCmpVar fatal error", __func__);
12257 }
12258 }
Jeff Johnson88ba7742013-02-27 14:36:02 -080012259 wlan_hdd_ftm_close(pHddCtx);
12260 goto free_hdd_ctx;
12261 }
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012262
Jeff Johnson295189b2012-06-20 16:38:30 -070012263 /* DeRegister with platform driver as client for Suspend/Resume */
12264 vosStatus = hddDeregisterPmOps(pHddCtx);
12265 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
12266 {
12267 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddDeregisterPmOps failed",__func__);
12268 VOS_ASSERT(0);
12269 }
12270
12271 vosStatus = hddDevTmUnregisterNotifyCallback(pHddCtx);
12272 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
12273 {
12274 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddDevTmUnregisterNotifyCallback failed",__func__);
12275 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012276
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -070012277 //Stop the traffic monitor timer
Mahesh A Saptasagard461e432016-07-20 15:01:40 +053012278 if ((pHddCtx->cfg_ini->dynSplitscan) && (VOS_TIMER_STATE_RUNNING ==
12279 vos_timer_getCurrentState(&pHddCtx->tx_rx_trafficTmr)))
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -070012280 {
12281 vos_timer_stop(&pHddCtx->tx_rx_trafficTmr);
12282 }
12283
12284 // Destroy the traffic monitor timer
Mahesh A Saptasagard461e432016-07-20 15:01:40 +053012285 if ((pHddCtx->cfg_ini->dynSplitscan) &&
12286 (!VOS_IS_STATUS_SUCCESS(vos_timer_destroy(
12287 &pHddCtx->tx_rx_trafficTmr))))
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -070012288 {
12289 hddLog(VOS_TRACE_LEVEL_ERROR,
12290 "%s: Cannot deallocate Traffic monitor timer", __func__);
12291 }
12292
Bhargav Shahd0715912015-10-01 18:17:37 +053012293 if (VOS_TIMER_STATE_RUNNING ==
12294 vos_timer_getCurrentState(&pHddCtx->delack_timer)) {
12295 vos_timer_stop(&pHddCtx->delack_timer);
12296 }
12297
12298 if (!VOS_IS_STATUS_SUCCESS(vos_timer_destroy(
12299 &pHddCtx->delack_timer))) {
12300 hddLog(VOS_TRACE_LEVEL_ERROR,
12301 "%s: Cannot deallocate Bus bandwidth timer", __func__);
12302 }
12303
Masti, Narayanraddi44b0db02015-12-22 11:54:35 +053012304 if (VOS_TIMER_STATE_RUNNING ==
12305 vos_timer_getCurrentState(&pHddCtx->tdls_source_timer)) {
12306 vos_timer_stop(&pHddCtx->tdls_source_timer);
12307 }
12308
Abhishek Singh8a3e4dc2017-01-02 10:39:18 +053012309 vos_set_snoc_high_freq_voting(false);
12310
Masti, Narayanraddi44b0db02015-12-22 11:54:35 +053012311 vos_timer_destroy(&pHddCtx->tdls_source_timer);
12312
Jeff Johnson295189b2012-06-20 16:38:30 -070012313 //Disable IMPS/BMPS as we do not want the device to enter any power
12314 //save mode during shutdown
12315 sme_DisablePowerSave(pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
12316 sme_DisablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
12317 sme_DisablePowerSave(pHddCtx->hHal, ePMC_UAPSD_MODE_POWER_SAVE);
12318
12319 //Ensure that device is in full power as we will touch H/W during vos_Stop
12320 init_completion(&powerContext.completion);
12321 powerContext.magic = POWER_CONTEXT_MAGIC;
12322
12323 halStatus = sme_RequestFullPower(pHddCtx->hHal, hdd_full_power_callback,
12324 &powerContext, eSME_FULL_PWR_NEEDED_BY_HDD);
12325
12326 if (eHAL_STATUS_SUCCESS != halStatus)
12327 {
12328 if (eHAL_STATUS_PMC_PENDING == halStatus)
12329 {
12330 /* request was sent -- wait for the response */
12331 lrc = wait_for_completion_interruptible_timeout(
12332 &powerContext.completion,
12333 msecs_to_jiffies(WLAN_WAIT_TIME_POWER));
Jeff Johnson295189b2012-06-20 16:38:30 -070012334 if (lrc <= 0)
12335 {
12336 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: %s while requesting full power",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070012337 __func__, (0 == lrc) ? "timeout" : "interrupt");
Jeff Johnson295189b2012-06-20 16:38:30 -070012338 }
12339 }
12340 else
12341 {
12342 hddLog(VOS_TRACE_LEVEL_ERROR,
12343 "%s: Request for Full Power failed, status %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070012344 __func__, halStatus);
Jeff Johnson295189b2012-06-20 16:38:30 -070012345 /* continue -- need to clean up as much as possible */
12346 }
12347 }
Hanumantha Reddy Pothula81b42b22015-05-12 13:52:00 +053012348 if ((eHAL_STATUS_SUCCESS == halStatus) ||
12349 (eHAL_STATUS_PMC_PENDING == halStatus && lrc > 0))
12350 {
12351 /* This will issue a dump command which will clean up
12352 BTQM queues and unblock MC thread */
12353 vos_fwDumpReq(274, 0, 0, 0, 0, 1);
12354 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012355
Jeff Johnson72a40512013-12-19 10:14:15 -080012356 /* either we never sent a request, we sent a request and received a
12357 response or we sent a request and timed out. if we never sent a
12358 request or if we sent a request and got a response, we want to
12359 clear the magic out of paranoia. if we timed out there is a
12360 race condition such that the callback function could be
12361 executing at the same time we are. of primary concern is if the
12362 callback function had already verified the "magic" but had not
12363 yet set the completion variable when a timeout occurred. we
12364 serialize these activities by invalidating the magic while
12365 holding a shared spinlock which will cause us to block if the
12366 callback is currently executing */
12367 spin_lock(&hdd_context_lock);
12368 powerContext.magic = 0;
12369 spin_unlock(&hdd_context_lock);
12370
Hema Aparna Medicharlaa6cf65e2015-06-01 16:23:28 +053012371 /* If Device is shutdown, no point for SME to wait for responses
12372 from device. Pre Close SME */
12373 if(wcnss_device_is_shutdown())
12374 {
12375 sme_PreClose(pHddCtx->hHal);
12376 }
Yue Ma0d4891e2013-08-06 17:01:45 -070012377 hdd_debugfs_exit(pHddCtx);
12378
Ratheesh S P35ed8b12015-04-27 14:01:07 +053012379#ifdef WLAN_NS_OFFLOAD
Ratheesh S P36dbc932015-08-07 14:28:57 +053012380 hddLog(LOG1, FL("Unregister IPv6 notifier"));
Ratheesh S P35ed8b12015-04-27 14:01:07 +053012381 unregister_inet6addr_notifier(&pHddCtx->ipv6_notifier);
12382#endif
Ratheesh S P36dbc932015-08-07 14:28:57 +053012383 hddLog(LOG1, FL("Unregister IPv4 notifier"));
Ratheesh S P35ed8b12015-04-27 14:01:07 +053012384 unregister_inetaddr_notifier(&pHddCtx->ipv4_notifier);
12385
Jeff Johnson295189b2012-06-20 16:38:30 -070012386 // Unregister the Net Device Notifier
12387 unregister_netdevice_notifier(&hdd_netdev_notifier);
12388
Jeff Johnson295189b2012-06-20 16:38:30 -070012389 hdd_stop_all_adapters( pHddCtx );
12390
Jeff Johnson295189b2012-06-20 16:38:30 -070012391#ifdef WLAN_BTAMP_FEATURE
12392 vosStatus = WLANBAP_Stop(pVosContext);
12393 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
12394 {
12395 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
12396 "%s: Failed to stop BAP",__func__);
12397 }
12398#endif //WLAN_BTAMP_FEATURE
12399
12400 //Stop all the modules
12401 vosStatus = vos_stop( pVosContext );
12402 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
12403 {
12404 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
12405 "%s: Failed to stop VOSS",__func__);
12406 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
Hanumantha Reddy Pothulabd9601a2016-02-12 13:22:27 +053012407 if (isSsrPanicOnFailure())
12408 VOS_BUG(0);
Jeff Johnson295189b2012-06-20 16:38:30 -070012409 }
12410
Jeff Johnson295189b2012-06-20 16:38:30 -070012411 //This requires pMac access, Call this before vos_close().
Jeff Johnson295189b2012-06-20 16:38:30 -070012412 hdd_unregister_mcast_bcast_filter(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -070012413
12414 //Close the scheduler before calling vos_close to make sure no thread is
12415 // scheduled after the each module close is called i.e after all the data
12416 // structures are freed.
12417 vosStatus = vos_sched_close( pVosContext );
12418 if (!VOS_IS_STATUS_SUCCESS(vosStatus)) {
12419 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
12420 "%s: Failed to close VOSS Scheduler",__func__);
12421 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
12422 }
Jeff Johnsone7245742012-09-05 17:12:55 -070012423#ifdef WLAN_FEATURE_HOLD_RX_WAKELOCK
12424 /* Destroy the wake lock */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053012425 vos_wake_lock_destroy(&pHddCtx->rx_wake_lock);
Jeff Johnsone7245742012-09-05 17:12:55 -070012426#endif
Madan Mohan Koyyalamudi69fc3ad2012-11-28 16:04:56 -080012427 /* Destroy the wake lock */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053012428 vos_wake_lock_destroy(&pHddCtx->sap_wake_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -070012429
Mihir Shete7a24b5f2013-12-21 12:18:31 +053012430#ifdef CONFIG_ENABLE_LINUX_REG
12431 vosStatus = vos_nv_close();
12432 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
12433 {
12434 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
12435 "%s: Failed to close NV", __func__);
12436 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
12437 }
12438#endif
12439
Jeff Johnson295189b2012-06-20 16:38:30 -070012440 //Close VOSS
12441 //This frees pMac(HAL) context. There should not be any call that requires pMac access after this.
12442 vos_close(pVosContext);
12443
Jeff Johnson295189b2012-06-20 16:38:30 -070012444 //Close Watchdog
12445 if(pHddCtx->cfg_ini->fIsLogpEnabled)
12446 vos_watchdog_close(pVosContext);
12447
Gopichand Nakkalaa0358482013-06-12 17:05:47 +053012448 //Clean up HDD Nlink Service
12449 send_btc_nlink_msg(WLAN_MODULE_DOWN_IND, 0);
Gopichand Nakkalaa0358482013-06-12 17:05:47 +053012450
Manjeet Singh47ee8472016-04-11 11:57:18 +053012451 hdd_close_tx_queues(pHddCtx);
c_manjeecfd1efb2015-09-25 19:32:34 +053012452 wlan_free_fwr_mem_dump_buffer();
12453 memdump_deinit();
12454
Vinay Krishna Erannad938c422014-03-10 17:14:21 +053012455#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +053012456 if (pHddCtx->cfg_ini->wlanLoggingEnable)
Vinay Krishna Erannad938c422014-03-10 17:14:21 +053012457 {
12458 wlan_logging_sock_deactivate_svc();
12459 }
12460#endif
12461
Vinay Krishna Erannaef30b522014-08-26 17:48:16 +053012462#ifdef WLAN_KD_READY_NOTIFIER
12463 nl_srv_exit(pHddCtx->ptt_pid);
12464#else
12465 nl_srv_exit();
12466#endif /* WLAN_KD_READY_NOTIFIER */
12467
Abhishek Singh00b71972016-01-07 10:51:04 +053012468#ifdef WLAN_FEATURE_RMC
12469 hdd_close_cesium_nl_sock();
12470#endif /* WLAN_FEATURE_RMC */
Vinay Krishna Erannaef30b522014-08-26 17:48:16 +053012471
Jeff Johnson295189b2012-06-20 16:38:30 -070012472 hdd_close_all_adapters( pHddCtx );
12473
Padma, Santhosh Kumar9cd38332015-11-17 12:18:10 +053012474 vos_flush_delayed_work(&pHddCtx->spoof_mac_addr_work);
Abhishek Singh78c691f2017-11-30 13:48:44 +053012475 vos_flush_delayed_work(&pHddCtx->ecsa_chan_change_work);
Kapil Gupta137ef892016-12-13 19:38:00 +053012476 vos_flush_work(&pHddCtx->sap_start_work);
Padma, Santhosh Kumar9cd38332015-11-17 12:18:10 +053012477
Hanumantha Reddy Pothula97f9bc92015-08-10 17:21:20 +053012478free_hdd_ctx:
Jeff Johnson295189b2012-06-20 16:38:30 -070012479 /* free the power on lock from platform driver */
12480 if (free_riva_power_on_lock("wlan"))
12481 {
12482 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to free power on lock",
12483 __func__);
12484 }
12485
Ashish Kumar Dhanotiya95e5bc22018-04-19 17:06:33 +053012486 /* Free the cache channels of the command SET_DISABLE_CHANNEL_LIST */
12487 wlan_hdd_free_cache_channels(pHddCtx);
12488
c_hpothu78c7b602014-05-17 17:35:49 +053012489 //Free up dynamically allocated members inside HDD Adapter
12490 if (pHddCtx->cfg_ini)
12491 {
12492 kfree(pHddCtx->cfg_ini);
12493 pHddCtx->cfg_ini= NULL;
12494 }
12495
Hanumanth Reddy Pothula1efcd162018-03-14 14:32:27 +053012496 hdd_request_manager_deinit();
12497
Hanumantha Reddy Pothula6fe221c2016-01-28 15:01:09 +053012498 /* FTM/MONITOR mode, WIPHY did not registered
Leo Changf04ddad2013-09-18 13:46:38 -070012499 If un-register here, system crash will happen */
Hanumantha Reddy Pothula6fe221c2016-01-28 15:01:09 +053012500 if (!(VOS_FTM_MODE == hdd_get_conparam() ||
12501 VOS_MONITOR_MODE == hdd_get_conparam()))
Leo Changf04ddad2013-09-18 13:46:38 -070012502 {
12503 wiphy_unregister(wiphy) ;
Agrawal Ashish33ec71e2015-11-26 20:20:58 +053012504 hdd_wlan_free_wiphy_channels(wiphy);
Leo Changf04ddad2013-09-18 13:46:38 -070012505 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012506 wiphy_free(wiphy) ;
Jeff Johnson295189b2012-06-20 16:38:30 -070012507 if (hdd_is_ssr_required())
12508 {
12509 /* WDI timeout had happened during unload, so SSR is needed here */
Madan Mohan Koyyalamudi3246f5b2012-10-15 15:40:02 -070012510 subsystem_restart("wcnss");
Jeff Johnson295189b2012-06-20 16:38:30 -070012511 msleep(5000);
12512 }
12513 hdd_set_ssr_required (VOS_FALSE);
12514}
12515
12516
12517/**---------------------------------------------------------------------------
12518
12519 \brief hdd_update_config_from_nv() - Function to update the contents of
12520 the running configuration with parameters taken from NV storage
12521
12522 \param - pHddCtx - Pointer to the HDD global context
12523
12524 \return - VOS_STATUS_SUCCESS if successful
12525
12526 --------------------------------------------------------------------------*/
12527static VOS_STATUS hdd_update_config_from_nv(hdd_context_t* pHddCtx)
12528{
Jeff Johnson295189b2012-06-20 16:38:30 -070012529 v_BOOL_t itemIsValid = VOS_FALSE;
12530 VOS_STATUS status;
12531 v_MACADDR_t macFromNV[VOS_MAX_CONCURRENCY_PERSONA];
12532 v_U8_t macLoop;
12533
12534 /*If the NV is valid then get the macaddress from nv else get it from qcom_cfg.ini*/
12535 status = vos_nv_getValidity(VNV_FIELD_IMAGE, &itemIsValid);
12536 if(status != VOS_STATUS_SUCCESS)
12537 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080012538 hddLog(VOS_TRACE_LEVEL_ERROR," vos_nv_getValidity() failed");
Jeff Johnson295189b2012-06-20 16:38:30 -070012539 return VOS_STATUS_E_FAILURE;
12540 }
12541
12542 if (itemIsValid == VOS_TRUE)
12543 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080012544 hddLog(VOS_TRACE_LEVEL_INFO_HIGH," Reading the Macaddress from NV");
Jeff Johnson295189b2012-06-20 16:38:30 -070012545 status = vos_nv_readMultiMacAddress((v_U8_t *)&macFromNV[0].bytes[0],
12546 VOS_MAX_CONCURRENCY_PERSONA);
12547 if(status != VOS_STATUS_SUCCESS)
12548 {
12549 /* Get MAC from NV fail, not update CFG info
12550 * INI MAC value will be used for MAC setting */
Arif Hussain6d2a3322013-11-17 19:50:10 -080012551 hddLog(VOS_TRACE_LEVEL_ERROR," vos_nv_readMacAddress() failed");
Jeff Johnson295189b2012-06-20 16:38:30 -070012552 return VOS_STATUS_E_FAILURE;
12553 }
12554
12555 /* If first MAC is not valid, treat all others are not valid
12556 * Then all MACs will be got from ini file */
12557 if(vos_is_macaddr_zero(&macFromNV[0]))
12558 {
12559 /* MAC address in NV file is not configured yet */
12560 hddLog(VOS_TRACE_LEVEL_WARN, "Invalid MAC in NV file");
12561 return VOS_STATUS_E_INVAL;
12562 }
12563
12564 /* Get MAC address from NV, update CFG info */
12565 for(macLoop = 0; macLoop < VOS_MAX_CONCURRENCY_PERSONA; macLoop++)
12566 {
12567 if(vos_is_macaddr_zero(&macFromNV[macLoop]))
12568 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012569 hddLog(VOS_TRACE_LEVEL_ERROR,"not valid MAC from NV for %d", macLoop);
Jeff Johnson295189b2012-06-20 16:38:30 -070012570 /* This MAC is not valid, skip it
12571 * This MAC will be got from ini file */
12572 }
12573 else
12574 {
12575 vos_mem_copy((v_U8_t *)&pHddCtx->cfg_ini->intfMacAddr[macLoop].bytes[0],
12576 (v_U8_t *)&macFromNV[macLoop].bytes[0],
12577 VOS_MAC_ADDR_SIZE);
12578 }
12579 }
12580 }
12581 else
12582 {
12583 hddLog(VOS_TRACE_LEVEL_ERROR, "NV ITEM, MAC Not valid");
12584 return VOS_STATUS_E_FAILURE;
12585 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012586
Jeff Johnson295189b2012-06-20 16:38:30 -070012587
12588 return VOS_STATUS_SUCCESS;
12589}
12590
12591/**---------------------------------------------------------------------------
12592
12593 \brief hdd_post_voss_start_config() - HDD post voss start config helper
12594
12595 \param - pAdapter - Pointer to the HDD
12596
12597 \return - None
12598
12599 --------------------------------------------------------------------------*/
12600VOS_STATUS hdd_post_voss_start_config(hdd_context_t* pHddCtx)
12601{
12602 eHalStatus halStatus;
12603 v_U32_t listenInterval;
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +053012604 tANI_U32 ignoreDtim;
Jeff Johnson295189b2012-06-20 16:38:30 -070012605
Jeff Johnson295189b2012-06-20 16:38:30 -070012606
12607 // Send ready indication to the HDD. This will kick off the MAC
12608 // into a 'running' state and should kick off an initial scan.
12609 halStatus = sme_HDDReadyInd( pHddCtx->hHal );
12610 if ( !HAL_STATUS_SUCCESS( halStatus ) )
12611 {
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +053012612 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: sme_HDDReadyInd() failed with status "
Jeff Johnson295189b2012-06-20 16:38:30 -070012613 "code %08d [x%08x]",__func__, halStatus, halStatus );
12614 return VOS_STATUS_E_FAILURE;
12615 }
12616
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +053012617 // Set default LI and ignoreDtim into HDD context,
Jeff Johnson295189b2012-06-20 16:38:30 -070012618 // otherwise under some race condition, HDD will set 0 LI value into RIVA,
12619 // And RIVA will crash
12620 wlan_cfgGetInt(pHddCtx->hHal, WNI_CFG_LISTEN_INTERVAL, &listenInterval);
12621 pHddCtx->hdd_actual_LI_value = listenInterval;
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +053012622 wlan_cfgGetInt(pHddCtx->hHal, WNI_CFG_IGNORE_DTIM, &ignoreDtim);
12623 pHddCtx->hdd_actual_ignore_DTIM_value = ignoreDtim;
12624
12625
Jeff Johnson295189b2012-06-20 16:38:30 -070012626 return VOS_STATUS_SUCCESS;
12627}
12628
Jeff Johnson295189b2012-06-20 16:38:30 -070012629/* wake lock APIs for HDD */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053012630void hdd_prevent_suspend(uint32_t reason)
Jeff Johnson295189b2012-06-20 16:38:30 -070012631{
Sushant Kaushik83392fa2015-05-05 17:44:40 +053012632
12633 vos_wake_lock_acquire(&wlan_wake_lock, reason);
12634
Jeff Johnson295189b2012-06-20 16:38:30 -070012635}
12636
Sushant Kaushik83392fa2015-05-05 17:44:40 +053012637void hdd_allow_suspend(uint32_t reason)
Jeff Johnson295189b2012-06-20 16:38:30 -070012638{
Sushant Kaushik83392fa2015-05-05 17:44:40 +053012639
12640 vos_wake_lock_release(&wlan_wake_lock, reason);
12641
Jeff Johnson295189b2012-06-20 16:38:30 -070012642}
12643
Sushant Kaushik83392fa2015-05-05 17:44:40 +053012644void hdd_prevent_suspend_timeout(v_U32_t timeout, uint32_t reason)
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -070012645{
Sushant Kaushik83392fa2015-05-05 17:44:40 +053012646
12647 vos_wake_lock_timeout_release(&wlan_wake_lock, timeout,
12648 reason);
12649
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -070012650}
12651
Jeff Johnson295189b2012-06-20 16:38:30 -070012652/**---------------------------------------------------------------------------
12653
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -070012654 \brief hdd_exchange_version_and_caps() - HDD function to exchange version and capability
12655 information between Host and Riva
12656
12657 This function gets reported version of FW
12658 It also finds the version of Riva headers used to compile the host
12659 It compares the above two and prints a warning if they are different
12660 It gets the SW and HW version string
12661 Finally, it exchanges capabilities between host and Riva i.e. host and riva exchange a msg
12662 indicating the features they support through a bitmap
12663
12664 \param - pHddCtx - Pointer to HDD context
12665
12666 \return - void
12667
12668 --------------------------------------------------------------------------*/
12669
12670void hdd_exchange_version_and_caps(hdd_context_t *pHddCtx)
12671{
12672
12673 tSirVersionType versionCompiled;
12674 tSirVersionType versionReported;
12675 tSirVersionString versionString;
12676 tANI_U8 fwFeatCapsMsgSupported = 0;
12677 VOS_STATUS vstatus;
12678
Mingcheng Zhu87f22fc2014-01-30 19:23:32 -080012679 memset(&versionCompiled, 0, sizeof(versionCompiled));
12680 memset(&versionReported, 0, sizeof(versionReported));
12681
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -070012682 /* retrieve and display WCNSS version information */
12683 do {
12684
12685 vstatus = sme_GetWcnssWlanCompiledVersion(pHddCtx->hHal,
12686 &versionCompiled);
12687 if (!VOS_IS_STATUS_SUCCESS(vstatus))
12688 {
12689 hddLog(VOS_TRACE_LEVEL_FATAL,
12690 "%s: unable to retrieve WCNSS WLAN compiled version",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070012691 __func__);
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -070012692 break;
12693 }
12694
12695 vstatus = sme_GetWcnssWlanReportedVersion(pHddCtx->hHal,
12696 &versionReported);
12697 if (!VOS_IS_STATUS_SUCCESS(vstatus))
12698 {
12699 hddLog(VOS_TRACE_LEVEL_FATAL,
12700 "%s: unable to retrieve WCNSS WLAN reported version",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070012701 __func__);
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -070012702 break;
12703 }
12704
12705 if ((versionCompiled.major != versionReported.major) ||
12706 (versionCompiled.minor != versionReported.minor) ||
12707 (versionCompiled.version != versionReported.version) ||
12708 (versionCompiled.revision != versionReported.revision))
12709 {
12710 pr_err("%s: WCNSS WLAN Version %u.%u.%u.%u, "
12711 "Host expected %u.%u.%u.%u\n",
12712 WLAN_MODULE_NAME,
12713 (int)versionReported.major,
12714 (int)versionReported.minor,
12715 (int)versionReported.version,
12716 (int)versionReported.revision,
12717 (int)versionCompiled.major,
12718 (int)versionCompiled.minor,
12719 (int)versionCompiled.version,
12720 (int)versionCompiled.revision);
12721 }
12722 else
12723 {
12724 pr_info("%s: WCNSS WLAN version %u.%u.%u.%u\n",
12725 WLAN_MODULE_NAME,
12726 (int)versionReported.major,
12727 (int)versionReported.minor,
12728 (int)versionReported.version,
12729 (int)versionReported.revision);
12730 }
12731
12732 vstatus = sme_GetWcnssSoftwareVersion(pHddCtx->hHal,
12733 versionString,
12734 sizeof(versionString));
12735 if (!VOS_IS_STATUS_SUCCESS(vstatus))
12736 {
12737 hddLog(VOS_TRACE_LEVEL_FATAL,
12738 "%s: unable to retrieve WCNSS software version string",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070012739 __func__);
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -070012740 break;
12741 }
12742
12743 pr_info("%s: WCNSS software version %s\n",
12744 WLAN_MODULE_NAME, versionString);
Sushant Kaushik084f6592015-09-10 13:11:56 +053012745 vos_mem_copy(pHddCtx->fw_Version, versionString, sizeof(versionString));
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -070012746
12747 vstatus = sme_GetWcnssHardwareVersion(pHddCtx->hHal,
12748 versionString,
12749 sizeof(versionString));
12750 if (!VOS_IS_STATUS_SUCCESS(vstatus))
12751 {
12752 hddLog(VOS_TRACE_LEVEL_FATAL,
12753 "%s: unable to retrieve WCNSS hardware version string",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070012754 __func__);
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -070012755 break;
12756 }
12757
12758 pr_info("%s: WCNSS hardware version %s\n",
12759 WLAN_MODULE_NAME, versionString);
12760
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -070012761 /* 1.Check if FW version is greater than 0.1.1.0. Only then send host-FW capability exchange message
12762 2.Host-FW capability exchange message is only present on riva 1.1 so
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -070012763 send the message only if it the riva is 1.1
12764 minor numbers for different riva branches:
12765 0 -> (1.0)Mainline Build
12766 1 -> (1.1)Mainline Build
12767 2->(1.04) Stability Build
12768 */
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -070012769 if (((versionReported.major>0) || (versionReported.minor>1) ||
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -070012770 ((versionReported.minor>=1) && (versionReported.version>=1)))
12771 && ((versionReported.major == 1) && (versionReported.minor >= 1)))
12772 fwFeatCapsMsgSupported = 1;
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -070012773
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -070012774 if (fwFeatCapsMsgSupported)
Yathish9f22e662012-12-10 14:21:35 -080012775 {
12776#ifdef WLAN_ACTIVEMODE_OFFLOAD_FEATURE
12777 if(!pHddCtx->cfg_ini->fEnableActiveModeOffload)
12778 sme_disableFeatureCapablity(WLANACTIVE_OFFLOAD);
12779#endif
Ravi Joshid2ca7c42013-07-23 08:37:49 -070012780 /* Indicate if IBSS heartbeat monitoring needs to be offloaded */
12781 if (!pHddCtx->cfg_ini->enableIbssHeartBeatOffload)
12782 {
12783 sme_disableFeatureCapablity(IBSS_HEARTBEAT_OFFLOAD);
12784 }
12785
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -070012786 sme_featureCapsExchange(pHddCtx->hHal);
Yathish9f22e662012-12-10 14:21:35 -080012787 }
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -070012788
12789 } while (0);
12790
12791}
Neelansh Mittaledafed22014-09-04 18:54:39 +053012792void wlan_hdd_send_svc_nlink_msg(int type, void *data, int len)
12793{
12794 struct sk_buff *skb;
12795 struct nlmsghdr *nlh;
12796 tAniMsgHdr *ani_hdr;
Hanumantha Reddy Pothulacf2c7ea2015-04-27 14:50:47 +053012797 int flags = GFP_KERNEL;
Bhargav shah23c94942015-10-13 12:48:35 +053012798 void *nl_data = NULL;
Neelansh Mittaledafed22014-09-04 18:54:39 +053012799
Hanumantha Reddy Pothulacf2c7ea2015-04-27 14:50:47 +053012800 if (in_interrupt() || irqs_disabled() || in_atomic())
12801 flags = GFP_ATOMIC;
12802
12803 skb = alloc_skb(NLMSG_SPACE(WLAN_NL_MAX_PAYLOAD), flags);
Neelansh Mittaledafed22014-09-04 18:54:39 +053012804
12805 if(skb == NULL) {
12806 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12807 "%s: alloc_skb failed", __func__);
12808 return;
12809 }
12810
12811 nlh = (struct nlmsghdr *)skb->data;
12812 nlh->nlmsg_pid = 0; /* from kernel */
12813 nlh->nlmsg_flags = 0;
12814 nlh->nlmsg_seq = 0;
12815 nlh->nlmsg_type = WLAN_NL_MSG_SVC;
12816
12817 ani_hdr = NLMSG_DATA(nlh);
12818 ani_hdr->type = type;
12819
12820 switch(type) {
12821 case WLAN_SVC_SAP_RESTART_IND:
12822 ani_hdr->length = 0;
12823 nlh->nlmsg_len = NLMSG_LENGTH((sizeof(tAniMsgHdr)));
12824 skb_put(skb, NLMSG_SPACE(sizeof(tAniMsgHdr)));
12825 break;
Bhargav Shahd0715912015-10-01 18:17:37 +053012826 case WLAN_SVC_WLAN_TP_IND:
12827 ani_hdr->length = len;
12828 nlh->nlmsg_len = NLMSG_LENGTH((sizeof(tAniMsgHdr)
12829 + len));
12830 nl_data = (char *)ani_hdr + sizeof(tAniMsgHdr);
12831 memcpy(nl_data, data, len);
12832 skb_put(skb, NLMSG_SPACE(sizeof(tAniMsgHdr) + len));
12833 break;
Bhargav shah23c94942015-10-13 12:48:35 +053012834 case WLAN_MSG_RPS_ENABLE_IND:
12835 ani_hdr->length = len;
12836 nlh->nlmsg_len = NLMSG_LENGTH((sizeof(tAniMsgHdr) + len));
12837 nl_data = (char *)ani_hdr + sizeof(tAniMsgHdr);
12838 memcpy(nl_data, data, len);
12839 skb_put(skb, NLMSG_SPACE(sizeof(tAniMsgHdr) + len));
12840 break;
Neelansh Mittaledafed22014-09-04 18:54:39 +053012841 default:
12842 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12843 "Attempt to send unknown nlink message %d", type);
12844 kfree_skb(skb);
12845 return;
12846 }
12847
12848 nl_srv_bcast(skb);
12849
12850 return;
12851}
12852
Bhargav Shahd0715912015-10-01 18:17:37 +053012853/**
12854 * hdd_request_tcp_delack() - Find the Delack value based on RX packet
12855 * @pHddCtx: Valid Global HDD context pointer
12856 * @rx_packets: Number of RX packet in perticular time
12857 *
12858 * Based on the RX packet this function calculate next value of tcp delack.
12859 * This function compare rx packet value to high and low threshold limit.
12860 *
12861 * Return: void
12862 */
12863void hdd_request_tcp_delack(hdd_context_t *pHddCtx, uint64_t rx_packets)
12864{
12865 /* average of rx_packets and prev_rx is taken so that
12866 bus width doesnot fluctuate much */
12867 uint64_t temp_rx = (rx_packets + pHddCtx->prev_rx)/2;
Alok Kumarf3724462018-04-05 15:18:54 +053012868 enum wlan_tp_level next_rx_level = pHddCtx->cur_rx_level;
Neelansh Mittaledafed22014-09-04 18:54:39 +053012869
Bhargav Shahd0715912015-10-01 18:17:37 +053012870 pHddCtx->prev_rx = rx_packets;
12871 if (temp_rx > pHddCtx->cfg_ini->tcpDelAckThresholdHigh)
Alok Kumarf3724462018-04-05 15:18:54 +053012872 next_rx_level = WLAN_SVC_TP_HIGH;
Bhargav Shahd0715912015-10-01 18:17:37 +053012873 else if (temp_rx <= pHddCtx->cfg_ini->tcpDelAckThresholdLow)
Alok Kumarf3724462018-04-05 15:18:54 +053012874 next_rx_level = WLAN_SVC_TP_LOW;
Bhargav Shahd0715912015-10-01 18:17:37 +053012875
12876 hdd_set_delack_value(pHddCtx, next_rx_level);
12877}
12878
12879#define HDD_BW_GET_DIFF(x, y) ((x) >= (y) ? (x) - (y) : (ULONG_MAX - (y) + (x)))
12880
12881/**
12882 * hdd_tcp_delack_compute_function() - get link status
12883 * @priv: Valid Global HDD context pointer
12884 *
12885 * This function find number of RX packet during timer life span.
12886 * It request tcp delack with number of RX packet and re-configure delack timer
12887 * for tcpDelAckComputeInterval timer interval.
12888 *
12889 * Return: void
12890 */
12891void hdd_tcp_delack_compute_function(void *priv)
12892{
12893 hdd_context_t *pHddCtx = (hdd_context_t *)priv;
12894 hdd_adapter_t *pAdapter = NULL;
12895 v_U32_t rx_packets = 0;
12896 hdd_adapter_list_node_t *pAdapterNode = NULL;
12897 VOS_STATUS status = 0;
12898
12899 for (status = hdd_get_front_adapter(pHddCtx, &pAdapterNode);
12900 NULL != pAdapterNode && VOS_STATUS_SUCCESS == status;
12901 status = hdd_get_next_adapter(pHddCtx, pAdapterNode, &pAdapterNode)) {
12902 if ((pAdapter = pAdapterNode->pAdapter) == NULL)
12903 continue;
12904
12905 rx_packets += HDD_BW_GET_DIFF(pAdapter->stats.rx_packets,
12906 pAdapter->prev_rx_packets);
12907 pAdapter->prev_rx_packets = pAdapter->stats.rx_packets;
12908 }
12909
12910 hdd_request_tcp_delack(pHddCtx, rx_packets);
12911
12912 vos_timer_start(&pHddCtx->delack_timer,
12913 pHddCtx->cfg_ini->tcpDelAckComputeInterval);
12914}
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -070012915
12916/**---------------------------------------------------------------------------
12917
Gopichand Nakkalafce506f2013-07-03 23:55:16 +053012918 \brief hdd_is_5g_supported() - HDD function to know if hardware supports 5GHz
12919
12920 \param - pHddCtx - Pointer to the hdd context
12921
12922 \return - true if hardware supports 5GHz
12923
12924 --------------------------------------------------------------------------*/
Vinay Krishna Erannafacf5e22014-02-24 13:16:25 +053012925boolean hdd_is_5g_supported(hdd_context_t * pHddCtx)
Gopichand Nakkalafce506f2013-07-03 23:55:16 +053012926{
12927 /* If wcnss_wlan_iris_xo_mode() returns WCNSS_XO_48MHZ(1);
12928 * then hardware support 5Ghz.
12929 */
12930 if (WCNSS_XO_48MHZ == wcnss_wlan_iris_xo_mode())
12931 {
Ratheesh S P36dbc932015-08-07 14:28:57 +053012932 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Hardware supports 5Ghz", __func__);
Gopichand Nakkalafce506f2013-07-03 23:55:16 +053012933 return true;
12934 }
12935 else
12936 {
Ratheesh S P36dbc932015-08-07 14:28:57 +053012937 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Hardware doesn't supports 5Ghz",
Gopichand Nakkalafce506f2013-07-03 23:55:16 +053012938 __func__);
12939 return false;
12940 }
12941}
12942
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +053012943/**---------------------------------------------------------------------------
12944
12945 \brief hdd_generate_iface_mac_addr_auto() - HDD Mac Interface Auto
12946 generate function
12947
12948 This is generate the random mac address for WLAN interface
12949
12950 \param - pHddCtx - Pointer to HDD context
12951 idx - Start interface index to get auto
12952 generated mac addr.
12953 mac_addr - Mac address
12954
12955 \return - 0 for success, < 0 for failure
12956
12957 --------------------------------------------------------------------------*/
12958
12959static int hdd_generate_iface_mac_addr_auto(hdd_context_t *pHddCtx,
12960 int idx, v_MACADDR_t mac_addr)
12961{
12962 int i;
12963 unsigned int serialno;
12964 serialno = wcnss_get_serial_number();
12965
12966 if (0 != serialno)
12967 {
12968 /* MAC address has 3 bytes of OUI so we have a maximum of 3
12969 bytes of the serial number that can be used to generate
12970 the other 3 bytes of the MAC address. Mask off all but
12971 the lower 3 bytes (this will also make sure we don't
12972 overflow in the next step) */
12973 serialno &= 0x00FFFFFF;
12974
12975 /* we need a unique address for each session */
12976 serialno *= VOS_MAX_CONCURRENCY_PERSONA;
12977
12978 /* autogen other Mac addresses */
12979 for (i = idx; i < VOS_MAX_CONCURRENCY_PERSONA; i++)
12980 {
12981 /* start with the entire default address */
12982 pHddCtx->cfg_ini->intfMacAddr[i] = mac_addr;
12983 /* then replace the lower 3 bytes */
12984 pHddCtx->cfg_ini->intfMacAddr[i].bytes[3] = (serialno >> 16) & 0xFF;
12985 pHddCtx->cfg_ini->intfMacAddr[i].bytes[4] = (serialno >> 8) & 0xFF;
12986 pHddCtx->cfg_ini->intfMacAddr[i].bytes[5] = serialno & 0xFF;
12987
Nachiket Kukadede2e24f2017-09-25 16:24:27 +053012988 if (0 == memcmp(&pHddCtx->cfg_ini->intfMacAddr[i].bytes[0],
12989 &mac_addr.bytes[0], VOS_MAC_ADDR_SIZE))
12990 pHddCtx->cfg_ini->intfMacAddr[i].bytes[5] +=
12991 VOS_MAX_CONCURRENCY_PERSONA;
12992
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +053012993 serialno++;
12994 hddLog(VOS_TRACE_LEVEL_ERROR,
12995 "%s: Derived Mac Addr: "
12996 MAC_ADDRESS_STR, __func__,
12997 MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[i].bytes));
12998 }
12999
13000 }
13001 else
13002 {
13003 hddLog(LOGE, FL("Failed to Get Serial NO"));
13004 return -1;
13005 }
13006 return 0;
13007}
Gopichand Nakkalafce506f2013-07-03 23:55:16 +053013008
Katya Nigame7b69a82015-04-28 15:24:06 +053013009int wlan_hdd_mon_open(hdd_context_t *pHddCtx)
13010{
13011 VOS_STATUS status;
13012 v_CONTEXT_t pVosContext= NULL;
13013 hdd_adapter_t *pAdapter= NULL;
13014
13015 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
13016
13017 if (NULL == pVosContext)
13018 {
13019 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13020 "%s: Trying to open VOSS without a PreOpen", __func__);
13021 VOS_ASSERT(0);
13022 return VOS_STATUS_E_FAILURE;
13023 }
13024
13025 status = vos_nv_open();
13026 if (!VOS_IS_STATUS_SUCCESS(status))
13027 {
13028 /* NV module cannot be initialized */
13029 hddLog( VOS_TRACE_LEVEL_FATAL,
13030 "%s: vos_nv_open failed", __func__);
13031 return VOS_STATUS_E_FAILURE;
13032 }
13033
13034 status = vos_init_wiphy_from_nv_bin();
13035 if (!VOS_IS_STATUS_SUCCESS(status))
13036 {
13037 /* NV module cannot be initialized */
13038 hddLog( VOS_TRACE_LEVEL_FATAL,
13039 "%s: vos_init_wiphy failed", __func__);
13040 goto err_vos_nv_close;
13041 }
13042
13043 status = vos_open( &pVosContext, pHddCtx->parent_dev);
13044 if ( !VOS_IS_STATUS_SUCCESS( status ))
13045 {
13046 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: vos_open failed", __func__);
13047 goto err_vos_nv_close;
13048 }
13049
13050 status = vos_mon_start( pVosContext );
13051 if ( !VOS_IS_STATUS_SUCCESS( status ) )
13052 {
13053 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: vos_start failed",__func__);
13054 goto err_vosclose;
13055 }
13056
13057 WLANTL_SetMonRxCbk( pVosContext, hdd_rx_packet_monitor_cbk );
13058 WDA_featureCapsExchange(pVosContext);
13059 wcnss_wlan_set_drvdata(pHddCtx->parent_dev, pHddCtx);
13060
13061 pAdapter = hdd_open_adapter( pHddCtx, WLAN_HDD_MONITOR, "wlan%d",
13062 wlan_hdd_get_intf_addr(pHddCtx), FALSE );
13063 if( pAdapter == NULL )
13064 {
13065 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: hdd_open_adapter failed", __func__);
13066 goto err_close_adapter;
13067 }
13068
13069 //Initialize the nlink service
13070 if(nl_srv_init() != 0)
13071 {
13072 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: nl_srv_init failed", __func__);
13073 goto err_close_adapter;
13074 }
13075 return VOS_STATUS_SUCCESS;
13076
13077err_close_adapter:
13078 hdd_close_all_adapters( pHddCtx );
13079 vos_mon_stop( pVosContext );
13080err_vosclose:
13081 status = vos_sched_close( pVosContext );
13082 if (!VOS_IS_STATUS_SUCCESS(status)) {
13083 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
13084 "%s: Failed to close VOSS Scheduler", __func__);
13085 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( status ) );
13086 }
13087 vos_close(pVosContext );
13088
13089err_vos_nv_close:
13090 vos_nv_close();
13091
13092return status;
13093}
Gopichand Nakkalafce506f2013-07-03 23:55:16 +053013094/**---------------------------------------------------------------------------
13095
Mihir Shetefc7ff5b2014-01-27 11:30:05 +053013096 \brief hdd_11d_scan_done - callback to be executed when 11d scan is
13097 completed to flush out the scan results
13098
13099 11d scan is done during driver load and is a passive scan on all
13100 channels supported by the device, 11d scans may find some APs on
13101 frequencies which are forbidden to be used in the regulatory domain
13102 the device is operating in. If these APs are notified to the supplicant
13103 it may try to connect to these APs, thus flush out all the scan results
13104 which are present in SME after 11d scan is done.
13105
13106 \return - eHalStatus
13107
13108 --------------------------------------------------------------------------*/
13109static eHalStatus hdd_11d_scan_done(tHalHandle halHandle, void *pContext,
13110 tANI_U32 scanId, eCsrScanStatus status)
13111{
13112 ENTER();
13113
13114 sme_ScanFlushResult(halHandle, 0);
13115
13116 EXIT();
13117
13118 return eHAL_STATUS_SUCCESS;
13119}
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053013120/**---------------------------------------------------------------------------
13121
13122 \brief hdd_init_frame_logging_done - callback to be executed when mgmt frame
13123 logging is completed successfully.
13124
13125 \return - None
13126
13127 --------------------------------------------------------------------------*/
c_manjeecfd1efb2015-09-25 19:32:34 +053013128void hdd_init_frame_logging_done(void *fwlogInitCbContext, tAniLoggingInitRsp *pRsp)
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053013129{
Siddharth Bhald1be97f2015-05-27 22:39:59 +053013130 hdd_context_t* pHddCtx = (hdd_context_t*)fwlogInitCbContext;
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053013131
13132 if (NULL == pHddCtx)
13133 {
13134 hddLog(VOS_TRACE_LEVEL_ERROR,
13135 "%s: HDD context is NULL",__func__);
13136 return;
13137 }
13138
c_manjeecfd1efb2015-09-25 19:32:34 +053013139 if ((pRsp->status == VOS_STATUS_SUCCESS) &&
Mahesh A Saptasagarfabb1a02015-06-29 12:17:04 +053013140 (TRUE == pHddCtx->cfg_ini->enableMgmtLogging))
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053013141 {
13142 hddLog(VOS_TRACE_LEVEL_INFO, FL("Mgmt Frame Logging init successful"));
13143 pHddCtx->mgmt_frame_logging = TRUE;
13144 }
13145 else
13146 {
13147 hddLog(VOS_TRACE_LEVEL_INFO, FL("Mgmt Frame Logging init not success"));
13148 pHddCtx->mgmt_frame_logging = FALSE;
c_manjeecfd1efb2015-09-25 19:32:34 +053013149 return;
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053013150 }
13151
c_manjeecfd1efb2015-09-25 19:32:34 +053013152 /*Check feature supported by FW*/
13153 if(TRUE == sme_IsFeatureSupportedByFW(MEMORY_DUMP_SUPPORTED))
13154 {
13155 //Store fwr mem dump size given by firmware.
13156 wlan_store_fwr_mem_dump_size(pRsp->fw_mem_dump_max_size);
13157 }
13158 else
13159 {
13160 wlan_store_fwr_mem_dump_size(0);
13161 }
13162
13163
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053013164}
13165/**---------------------------------------------------------------------------
13166
13167 \brief hdd_init_frame_logging - function to initialize frame logging.
13168 Currently only Mgmt Frames are logged in both TX
13169 and Rx direction and are sent to userspace
13170 application using logger thread when queried.
13171
13172 \return - None
13173
13174 --------------------------------------------------------------------------*/
Siddharth Bhald1be97f2015-05-27 22:39:59 +053013175void hdd_init_frame_logging(hdd_context_t* pHddCtx)
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053013176{
13177 eHalStatus halStatus = eHAL_STATUS_FAILURE;
Sreelakshmi Konamkid8784d92016-04-14 14:59:13 +053013178 tSirFWLoggingInitParam wlanFWLoggingInitParam = {0};
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053013179
Siddharth Bhald1be97f2015-05-27 22:39:59 +053013180 if (TRUE != sme_IsFeatureSupportedByFW(MGMT_FRAME_LOGGING) &&
13181 TRUE != sme_IsFeatureSupportedByFW(LOGGING_ENHANCEMENT))
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053013182 {
13183 hddLog(VOS_TRACE_LEVEL_INFO, FL("MGMT_FRAME_LOGGING not supp by FW"));
13184 return;
13185 }
13186
c_manjeecfd1efb2015-09-25 19:32:34 +053013187 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Configuring %s %s %s %s Logging",__func__,
Siddharth Bhald1be97f2015-05-27 22:39:59 +053013188 pHddCtx->cfg_ini->enableFWLogging?"FW Log,":"",
13189 pHddCtx->cfg_ini->enableContFWLogging ? "Cont FW log,":"",
c_manjeecfd1efb2015-09-25 19:32:34 +053013190 pHddCtx->cfg_ini->enableMgmtLogging ? "Mgmt Pkt Log":"",
13191 pHddCtx->cfg_ini->enableFwrMemDump ? "Fw Mem dump":"");
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053013192
Siddharth Bhald1be97f2015-05-27 22:39:59 +053013193 if (pHddCtx->cfg_ini->enableFWLogging ||
13194 pHddCtx->cfg_ini->enableContFWLogging)
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053013195 {
Sreelakshmi Konamkid8784d92016-04-14 14:59:13 +053013196 wlanFWLoggingInitParam.enableFlag |= WLAN_QXDM_LOG_EN;
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053013197 }
13198
Sushant Kaushik46804902015-07-08 14:46:03 +053013199 if (pHddCtx->cfg_ini->enableMgmtLogging)
13200 {
Sreelakshmi Konamkid8784d92016-04-14 14:59:13 +053013201 wlanFWLoggingInitParam.enableFlag |= WLAN_FRAME_LOG_EN;
Sushant Kaushik46804902015-07-08 14:46:03 +053013202 }
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053013203 if (pHddCtx->cfg_ini->enableBMUHWtracing)
13204 {
Sreelakshmi Konamkid8784d92016-04-14 14:59:13 +053013205 wlanFWLoggingInitParam.enableFlag |= WLAN_BMUHW_TRACE_LOG_EN;
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053013206 }
c_manjeecfd1efb2015-09-25 19:32:34 +053013207 if(pHddCtx->cfg_ini->enableFwrMemDump &&
13208 (TRUE == sme_IsFeatureSupportedByFW(MEMORY_DUMP_SUPPORTED)))
13209 {
Sreelakshmi Konamkid8784d92016-04-14 14:59:13 +053013210 wlanFWLoggingInitParam.enableFlag |= WLAN_FW_MEM_DUMP_EN;
c_manjeecfd1efb2015-09-25 19:32:34 +053013211 }
Sreelakshmi Konamkid8784d92016-04-14 14:59:13 +053013212 if( wlanFWLoggingInitParam.enableFlag == 0 )
c_manjeecfd1efb2015-09-25 19:32:34 +053013213 {
13214 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Logging not enabled", __func__);
13215 return;
13216 }
Sreelakshmi Konamkid8784d92016-04-14 14:59:13 +053013217 wlanFWLoggingInitParam.frameType = WLAN_FRAME_LOGGING_FRAMETYPE_MGMT;
13218 wlanFWLoggingInitParam.frameSize = WLAN_MGMT_LOGGING_FRAMESIZE_128BYTES;
13219 wlanFWLoggingInitParam.bufferMode = WLAN_FRAME_LOGGING_BUFFERMODE_CIRCULAR;
13220 wlanFWLoggingInitParam.continuousFrameLogging =
Siddharth Bhald1be97f2015-05-27 22:39:59 +053013221 pHddCtx->cfg_ini->enableContFWLogging;
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053013222
Sreelakshmi Konamkid8784d92016-04-14 14:59:13 +053013223 wlanFWLoggingInitParam.enableFlag &= ~WLAN_DPU_TXP_LOG_EN;
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053013224
Sreelakshmi Konamkid8784d92016-04-14 14:59:13 +053013225 wlanFWLoggingInitParam.minLogBufferSize =
Siddharth Bhald1be97f2015-05-27 22:39:59 +053013226 pHddCtx->cfg_ini->minLoggingBufferSize;
Sreelakshmi Konamkid8784d92016-04-14 14:59:13 +053013227 wlanFWLoggingInitParam.maxLogBufferSize =
Siddharth Bhald1be97f2015-05-27 22:39:59 +053013228 pHddCtx->cfg_ini->maxLoggingBufferSize;
Sreelakshmi Konamkid8784d92016-04-14 14:59:13 +053013229 wlanFWLoggingInitParam.fwlogInitCallback = hdd_init_frame_logging_done;
13230 wlanFWLoggingInitParam.fwlogInitCbContext= pHddCtx;
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053013231
Sreelakshmi Konamkid8784d92016-04-14 14:59:13 +053013232 halStatus = sme_InitMgmtFrameLogging(pHddCtx->hHal, &wlanFWLoggingInitParam);
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053013233
13234 if (eHAL_STATUS_SUCCESS != halStatus)
13235 {
Sreelakshmi Konamkid8784d92016-04-14 14:59:13 +053013236 hddLog(LOGE, FL("sme_InitMgmtFrameLogging failed, returned %d"),
13237 halStatus);
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053013238 }
13239
13240 return;
13241}
Mihir Shetefc7ff5b2014-01-27 11:30:05 +053013242
Bhargav shah23c94942015-10-13 12:48:35 +053013243static void hdd_dp_util_send_rps_ind(hdd_context_t *hdd_ctxt)
13244{
13245 hdd_adapter_t *adapter;
13246 hdd_adapter_list_node_t *adapter_node, *next;
13247 VOS_STATUS status = VOS_STATUS_SUCCESS;
13248 struct wlan_rps_data rps_data;
13249 int count;
13250
13251 if(!hdd_ctxt->cfg_ini->rps_mask)
13252 {
13253 return;
13254 }
13255
13256 for (count=0; count < WLAN_SVC_IFACE_NUM_QUEUES; count++)
13257 {
13258 rps_data.cpu_map[count] = hdd_ctxt->cfg_ini->rps_mask;
13259 }
13260
13261 rps_data.num_queues = WLAN_SVC_IFACE_NUM_QUEUES;
13262
13263 hddLog(LOG1, FL("0x%x 0x%x 0x%x 0x%x 0x%x 0x%x"),
13264 rps_data.cpu_map[0], rps_data.cpu_map[1],rps_data.cpu_map[2],
13265 rps_data.cpu_map[3], rps_data.cpu_map[4], rps_data.cpu_map[5]);
13266
13267 status = hdd_get_front_adapter (hdd_ctxt, &adapter_node);
13268
13269 while (NULL != adapter_node && VOS_STATUS_SUCCESS == status)
13270 {
13271 adapter = adapter_node->pAdapter;
13272 if (NULL != adapter) {
13273 strlcpy(rps_data.ifname, adapter->dev->name,
13274 sizeof(rps_data.ifname));
13275 wlan_hdd_send_svc_nlink_msg(WLAN_MSG_RPS_ENABLE_IND,
13276 (void *)&rps_data,sizeof(rps_data));
13277 }
13278 status = hdd_get_next_adapter (hdd_ctxt, adapter_node, &next);
13279 adapter_node = next;
13280 }
13281}
13282
Masti, Narayanraddi26378462016-01-05 18:20:28 +053013283void wlan_hdd_schedule_defer_scan(struct work_struct *work)
13284{
13285 scan_context_t *scan_ctx =
13286 container_of(work, scan_context_t, scan_work.work);
13287
13288 if (NULL == scan_ctx)
13289 {
13290 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13291 FL("scan_ctx is NULL"));
13292 return;
13293 }
13294
13295 if (unlikely(TDLS_CTX_MAGIC != scan_ctx->magic))
13296 return;
13297
13298 scan_ctx->attempt++;
13299
13300 wlan_hdd_cfg80211_scan(scan_ctx->wiphy,
13301#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
13302 scan_ctx->dev,
13303#endif
13304 scan_ctx->scan_request);
13305}
13306
13307int wlan_hdd_copy_defer_scan_context(hdd_context_t *pHddCtx,
13308 struct wiphy *wiphy,
13309#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
13310 struct net_device *dev,
13311#endif
13312 struct cfg80211_scan_request *request)
13313{
13314 scan_context_t *scan_ctx;
13315
13316 ENTER();
13317 if (0 != (wlan_hdd_validate_context(pHddCtx)))
13318 {
13319 return -1;
13320 }
13321
13322 scan_ctx = &pHddCtx->scan_ctxt;
13323
13324 scan_ctx->wiphy = wiphy;
13325#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
13326 scan_ctx->dev = dev;
13327#endif
13328
13329 scan_ctx->scan_request = request;
13330
13331 EXIT();
13332 return 0;
13333}
13334
13335void wlan_hdd_defer_scan_init_work(hdd_context_t *pHddCtx,
13336 struct wiphy *wiphy,
13337#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
13338 struct net_device *dev,
13339#endif
13340 struct cfg80211_scan_request *request,
13341 unsigned long delay)
13342{
13343 if (TDLS_CTX_MAGIC != pHddCtx->scan_ctxt.magic)
13344 {
13345#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
13346 wlan_hdd_copy_defer_scan_context(pHddCtx, wiphy, dev, request);
13347#else
13348 wlan_hdd_copy_defer_scan_context(pHddCtx, wiphy, request);
13349#endif
13350 pHddCtx->scan_ctxt.attempt = 0;
13351 pHddCtx->scan_ctxt.magic = TDLS_CTX_MAGIC;
13352 }
13353 schedule_delayed_work(&pHddCtx->scan_ctxt.scan_work, delay);
13354}
13355
13356void wlan_hdd_init_deinit_defer_scan_context(scan_context_t *scan_ctx)
13357{
13358 scan_ctx->magic = 0;
13359 scan_ctx->attempt = 0;
13360 scan_ctx->reject = 0;
13361 scan_ctx->scan_request = NULL;
13362
13363 return;
13364}
13365
Mihir Shetefc7ff5b2014-01-27 11:30:05 +053013366/**---------------------------------------------------------------------------
13367
Jeff Johnson295189b2012-06-20 16:38:30 -070013368 \brief hdd_wlan_startup() - HDD init function
13369
13370 This is the driver startup code executed once a WLAN device has been detected
13371
13372 \param - dev - Pointer to the underlying device
13373
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -080013374 \return - 0 for success, < 0 for failure
Jeff Johnson295189b2012-06-20 16:38:30 -070013375
13376 --------------------------------------------------------------------------*/
13377
13378int hdd_wlan_startup(struct device *dev )
13379{
13380 VOS_STATUS status;
13381 hdd_adapter_t *pAdapter = NULL;
Jeff Johnsone7245742012-09-05 17:12:55 -070013382 hdd_adapter_t *pP2pAdapter = NULL;
Arunk Khandavalli95608be2019-01-22 13:12:54 +053013383 hdd_adapter_t *softapAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070013384 hdd_context_t *pHddCtx = NULL;
13385 v_CONTEXT_t pVosContext= NULL;
13386#ifdef WLAN_BTAMP_FEATURE
13387 VOS_STATUS vStatus = VOS_STATUS_SUCCESS;
13388 WLANBAP_ConfigType btAmpConfig;
13389 hdd_config_t *pConfig;
13390#endif
13391 int ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070013392 struct wiphy *wiphy;
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +053013393 v_MACADDR_t mac_addr;
Jeff Johnson295189b2012-06-20 16:38:30 -070013394
13395 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -070013396 /*
13397 * cfg80211: wiphy allocation
13398 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +053013399 wiphy = wlan_hdd_cfg80211_wiphy_alloc(sizeof(hdd_context_t)) ;
Jeff Johnson295189b2012-06-20 16:38:30 -070013400
13401 if(wiphy == NULL)
13402 {
13403 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: cfg80211 init failed", __func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -080013404 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -070013405 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013406 pHddCtx = wiphy_priv(wiphy);
13407
Jeff Johnson295189b2012-06-20 16:38:30 -070013408 //Initialize the adapter context to zeros.
13409 vos_mem_zero(pHddCtx, sizeof( hdd_context_t ));
13410
Jeff Johnson295189b2012-06-20 16:38:30 -070013411 pHddCtx->wiphy = wiphy;
Sushant Kaushik83392fa2015-05-05 17:44:40 +053013412 hdd_prevent_suspend(WIFI_POWER_EVENT_WAKELOCK_DRIVER_INIT);
Mihir Shete18156292014-03-11 15:38:30 +053013413 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_LOAD_IN_PROGRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -070013414
13415 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, TRUE);
13416
Siddharth Bhalcd92b782015-06-29 12:25:40 +053013417 /* register for riva power on lock to platform driver
13418 * Locking power early to ensure FW doesn't reset by kernel while
13419 * host driver is busy initializing itself */
13420 if (req_riva_power_on_lock("wlan"))
13421 {
13422 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: req riva power on lock failed",
13423 __func__);
13424 goto err_free_hdd_context;
13425 }
13426
Jeff Johnson295189b2012-06-20 16:38:30 -070013427 /*Get vos context here bcoz vos_open requires it*/
13428 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
13429
Madan Mohan Koyyalamudi0b78e152012-11-28 15:46:51 -080013430 if(pVosContext == NULL)
13431 {
13432 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Failed vos_get_global_context",__func__);
13433 goto err_free_hdd_context;
13434 }
13435
Jeff Johnson295189b2012-06-20 16:38:30 -070013436 //Save the Global VOSS context in adapter context for future.
13437 pHddCtx->pvosContext = pVosContext;
13438
13439 //Save the adapter context in global context for future.
13440 ((VosContextType*)(pVosContext))->pHDDContext = (v_VOID_t*)pHddCtx;
13441
Jeff Johnson295189b2012-06-20 16:38:30 -070013442 pHddCtx->parent_dev = dev;
Sreelakshmi Konamkif0646d52016-12-09 12:35:31 +053013443 pHddCtx->last_scan_reject_session_id = 0xFF;
13444 pHddCtx->last_scan_reject_reason = 0;
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053013445 pHddCtx->last_scan_reject_timestamp = 0;
Abhishek Singhe4b12562017-06-20 16:53:39 +053013446 pHddCtx->scan_reject_cnt = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070013447
13448 init_completion(&pHddCtx->full_pwr_comp_var);
13449 init_completion(&pHddCtx->standby_comp_var);
13450 init_completion(&pHddCtx->req_bmps_comp_var);
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070013451 init_completion(&pHddCtx->scan_info.scan_req_completion_event);
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -080013452 init_completion(&pHddCtx->scan_info.abortscan_event_var);
Kiet Lam46b8e4e2013-11-06 21:49:53 +053013453 init_completion(&pHddCtx->wiphy_channel_update_event);
Arun Kumar Khandavallie0b046d2014-03-01 21:54:25 +053013454 init_completion(&pHddCtx->ssr_comp_var);
Mahesh A Saptasagar67ab9222015-10-21 15:38:41 +053013455 init_completion(&pHddCtx->mc_sus_event_var);
13456 init_completion(&pHddCtx->tx_sus_event_var);
13457 init_completion(&pHddCtx->rx_sus_event_var);
13458
Amar Singhala49cbc52013-10-08 18:37:44 -070013459
mukul sharma4bd8d2e2015-08-13 20:33:25 +053013460 hdd_init_ll_stats_ctx(pHddCtx);
Anurag Chouhan6ee81542017-02-09 18:09:27 +053013461 hdd_init_nud_stats_ctx(pHddCtx);
mukul sharma4bd8d2e2015-08-13 20:33:25 +053013462
Amar Singhala49cbc52013-10-08 18:37:44 -070013463#ifdef CONFIG_ENABLE_LINUX_REG
Amar Singhalfddc28c2013-09-05 13:03:40 -070013464 init_completion(&pHddCtx->linux_reg_req);
Amar Singhala49cbc52013-10-08 18:37:44 -070013465#else
13466 init_completion(&pHddCtx->driver_crda_req);
13467#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070013468
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +053013469#ifdef WLAN_FEATURE_EXTSCAN
13470 init_completion(&pHddCtx->ext_scan_context.response_event);
13471#endif /* WLAN_FEATURE_EXTSCAN */
13472
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053013473 spin_lock_init(&pHddCtx->schedScan_lock);
Kapil Gupta137ef892016-12-13 19:38:00 +053013474 vos_spin_lock_init(&pHddCtx->sap_update_info_lock);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053013475
Jeff Johnson295189b2012-06-20 16:38:30 -070013476 hdd_list_init( &pHddCtx->hddAdapters, MAX_NUMBER_OF_ADAPTERS );
13477
Padma, Santhosh Kumar9cd38332015-11-17 12:18:10 +053013478 vos_init_delayed_work(&pHddCtx->spoof_mac_addr_work,
13479 hdd_processSpoofMacAddrRequest);
Kapil Gupta137ef892016-12-13 19:38:00 +053013480 vos_init_work(&pHddCtx->sap_start_work, hdd_sap_restart_handle);
Abhishek Singh78c691f2017-11-30 13:48:44 +053013481 vos_init_delayed_work(&pHddCtx->ecsa_chan_change_work,
13482 hdd_force_scc_with_ecsa_handle);
Padma, Santhosh Kumar9cd38332015-11-17 12:18:10 +053013483
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053013484#ifdef FEATURE_WLAN_TDLS
13485 /* tdls_lock is initialized before an hdd_open_adapter ( which is
13486 * invoked by other instances also) to protect the concurrent
13487 * access for the Adapters by TDLS module.
13488 */
13489 mutex_init(&pHddCtx->tdls_lock);
13490#endif
Siddharth Bhal76972212014-10-15 16:22:51 +053013491 mutex_init(&pHddCtx->spoofMacAddr.macSpoofingLock);
Mukul Sharma1fd6efd2015-02-14 00:29:14 +053013492 mutex_init(&pHddCtx->wmmLock);
13493
Srinivas Girigowda8bf64cb2015-09-30 19:50:09 +053013494 hdd_init_offloaded_packets_ctx(pHddCtx);
Agarwal Ashish1f422872014-07-22 00:11:55 +053013495 /* By default Strict Regulatory For FCC should be false */
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053013496
Agarwal Ashish1f422872014-07-22 00:11:55 +053013497 pHddCtx->nEnableStrictRegulatoryForFCC = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070013498 // Load all config first as TL config is needed during vos_open
13499 pHddCtx->cfg_ini = (hdd_config_t*) kmalloc(sizeof(hdd_config_t), GFP_KERNEL);
13500 if(pHddCtx->cfg_ini == NULL)
13501 {
13502 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Failed kmalloc hdd_config_t",__func__);
13503 goto err_free_hdd_context;
13504 }
13505
Hanumanth Reddy Pothula1efcd162018-03-14 14:32:27 +053013506 hdd_request_manager_init();
13507
Jeff Johnson295189b2012-06-20 16:38:30 -070013508 vos_mem_zero(pHddCtx->cfg_ini, sizeof( hdd_config_t ));
13509
13510 // Read and parse the qcom_cfg.ini file
13511 status = hdd_parse_config_ini( pHddCtx );
13512 if ( VOS_STATUS_SUCCESS != status )
13513 {
13514 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: error parsing %s",
13515 __func__, WLAN_INI_FILE);
13516 goto err_config;
13517 }
Arif Hussaind5218912013-12-05 01:10:55 -080013518#ifdef MEMORY_DEBUG
13519 if (pHddCtx->cfg_ini->IsMemoryDebugSupportEnabled)
13520 vos_mem_init();
13521
13522 hddLog(VOS_TRACE_LEVEL_INFO, "%s: gEnableMemoryDebug=%d",
13523 __func__, pHddCtx->cfg_ini->IsMemoryDebugSupportEnabled);
13524#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070013525
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +053013526 /* INI has been read, initialise the configuredMcastBcastFilter with
13527 * INI value as this will serve as the default value
13528 */
13529 pHddCtx->configuredMcastBcastFilter = pHddCtx->cfg_ini->mcastBcastFilterSetting;
13530 hddLog(VOS_TRACE_LEVEL_INFO, "Setting configuredMcastBcastFilter: %d",
13531 pHddCtx->cfg_ini->mcastBcastFilterSetting);
Gopichand Nakkalafce506f2013-07-03 23:55:16 +053013532
13533 if (false == hdd_is_5g_supported(pHddCtx))
13534 {
13535 //5Ghz is not supported.
13536 if (1 != pHddCtx->cfg_ini->nBandCapability)
13537 {
13538 hddLog(VOS_TRACE_LEVEL_INFO,
13539 "%s: Setting pHddCtx->cfg_ini->nBandCapability = 1", __func__);
13540 pHddCtx->cfg_ini->nBandCapability = 1;
13541 }
13542 }
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053013543
13544 /* If SNR Monitoring is enabled, FW has to parse all beacons
13545 * for calcaluting and storing the average SNR, so set Nth beacon
13546 * filter to 1 to enable FW to parse all the beaocons
13547 */
13548 if (1 == pHddCtx->cfg_ini->fEnableSNRMonitoring)
13549 {
13550 /* The log level is deliberately set to WARN as overriding
13551 * nthBeaconFilter to 1 will increase power cosumption and this
13552 * might just prove helpful to detect the power issue.
13553 */
13554 hddLog(VOS_TRACE_LEVEL_WARN,
13555 "%s: Setting pHddCtx->cfg_ini->nthBeaconFilter = 1", __func__);
13556 pHddCtx->cfg_ini->nthBeaconFilter = 1;
13557 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013558 /*
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +053013559 * cfg80211: Initialization ...
Jeff Johnson295189b2012-06-20 16:38:30 -070013560 */
Manjeet Singh61016fa2016-12-02 11:10:19 +053013561 if (0 < wlan_hdd_cfg80211_init(dev, wiphy, pHddCtx->cfg_ini))
Jeff Johnson295189b2012-06-20 16:38:30 -070013562 {
Manjeet Singh61016fa2016-12-02 11:10:19 +053013563 hddLog(VOS_TRACE_LEVEL_FATAL,
13564 "%s: wlan_hdd_cfg80211_init return failure", __func__);
13565 goto err_config;
Jeff Johnson295189b2012-06-20 16:38:30 -070013566 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013567
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -080013568 // Update VOS trace levels based upon the cfg.ini
13569 hdd_vos_trace_enable(VOS_MODULE_ID_BAP,
13570 pHddCtx->cfg_ini->vosTraceEnableBAP);
13571 hdd_vos_trace_enable(VOS_MODULE_ID_TL,
13572 pHddCtx->cfg_ini->vosTraceEnableTL);
13573 hdd_vos_trace_enable(VOS_MODULE_ID_WDI,
13574 pHddCtx->cfg_ini->vosTraceEnableWDI);
13575 hdd_vos_trace_enable(VOS_MODULE_ID_HDD,
13576 pHddCtx->cfg_ini->vosTraceEnableHDD);
13577 hdd_vos_trace_enable(VOS_MODULE_ID_SME,
13578 pHddCtx->cfg_ini->vosTraceEnableSME);
13579 hdd_vos_trace_enable(VOS_MODULE_ID_PE,
13580 pHddCtx->cfg_ini->vosTraceEnablePE);
Katya Nigam70d68332013-09-16 16:49:45 +053013581 hdd_vos_trace_enable(VOS_MODULE_ID_PMC,
13582 pHddCtx->cfg_ini->vosTraceEnablePMC);
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -080013583 hdd_vos_trace_enable(VOS_MODULE_ID_WDA,
13584 pHddCtx->cfg_ini->vosTraceEnableWDA);
13585 hdd_vos_trace_enable(VOS_MODULE_ID_SYS,
13586 pHddCtx->cfg_ini->vosTraceEnableSYS);
13587 hdd_vos_trace_enable(VOS_MODULE_ID_VOSS,
13588 pHddCtx->cfg_ini->vosTraceEnableVOSS);
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -080013589 hdd_vos_trace_enable(VOS_MODULE_ID_SAP,
13590 pHddCtx->cfg_ini->vosTraceEnableSAP);
13591 hdd_vos_trace_enable(VOS_MODULE_ID_HDD_SOFTAP,
13592 pHddCtx->cfg_ini->vosTraceEnableHDDSAP);
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -080013593
Jeff Johnson295189b2012-06-20 16:38:30 -070013594 // Update WDI trace levels based upon the cfg.ini
13595 hdd_wdi_trace_enable(eWLAN_MODULE_DAL,
13596 pHddCtx->cfg_ini->wdiTraceEnableDAL);
13597 hdd_wdi_trace_enable(eWLAN_MODULE_DAL_CTRL,
13598 pHddCtx->cfg_ini->wdiTraceEnableCTL);
13599 hdd_wdi_trace_enable(eWLAN_MODULE_DAL_DATA,
13600 pHddCtx->cfg_ini->wdiTraceEnableDAT);
13601 hdd_wdi_trace_enable(eWLAN_MODULE_PAL,
13602 pHddCtx->cfg_ini->wdiTraceEnablePAL);
Jeff Johnson295189b2012-06-20 16:38:30 -070013603
Jeff Johnson88ba7742013-02-27 14:36:02 -080013604 if (VOS_FTM_MODE == hdd_get_conparam())
13605 {
Jeff Johnson295189b2012-06-20 16:38:30 -070013606 if ( VOS_STATUS_SUCCESS != wlan_hdd_ftm_open(pHddCtx) )
13607 {
13608 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: wlan_hdd_ftm_open Failed",__func__);
13609 goto err_free_hdd_context;
13610 }
13611 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: FTM driver loaded success fully",__func__);
Sachin Ahuja38ef5e02015-03-13 17:31:16 +053013612 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_NO_LOAD_UNLOAD_IN_PROGRESS;
c_hpothu2de0ef62014-04-15 16:16:15 +053013613 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, FALSE);
Jeff Johnson295189b2012-06-20 16:38:30 -070013614 return VOS_STATUS_SUCCESS;
Jeff Johnson88ba7742013-02-27 14:36:02 -080013615 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013616
Katya Nigame7b69a82015-04-28 15:24:06 +053013617 if( VOS_MONITOR_MODE == hdd_get_conparam())
13618 {
13619 if ( VOS_STATUS_SUCCESS != wlan_hdd_mon_open(pHddCtx))
13620 {
13621 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: wlan_hdd_mon_open Failed",__func__);
13622 goto err_free_hdd_context;
13623 }
13624 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Driver loaded in Monitor Mode",__func__);
13625 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_NO_LOAD_UNLOAD_IN_PROGRESS;
13626 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, FALSE);
13627 return VOS_STATUS_SUCCESS;
13628 }
13629
Jeff Johnson88ba7742013-02-27 14:36:02 -080013630 //Open watchdog module
Jeff Johnson295189b2012-06-20 16:38:30 -070013631 if(pHddCtx->cfg_ini->fIsLogpEnabled)
13632 {
13633 status = vos_watchdog_open(pVosContext,
13634 &((VosContextType*)pVosContext)->vosWatchdog, sizeof(VosWatchdogContext));
13635
13636 if(!VOS_IS_STATUS_SUCCESS( status ))
13637 {
13638 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: vos_watchdog_open failed",__func__);
Ashish Kumar Dhanotiya532bdef2017-05-09 17:31:59 +053013639 goto err_config;
Jeff Johnson295189b2012-06-20 16:38:30 -070013640 }
13641 }
13642
13643 pHddCtx->isLogpInProgress = FALSE;
13644 vos_set_logp_in_progress(VOS_MODULE_ID_VOSS, FALSE);
13645
Amar Singhala49cbc52013-10-08 18:37:44 -070013646#ifdef CONFIG_ENABLE_LINUX_REG
Amar Singhal0a402232013-10-11 20:57:16 -070013647 /* initialize the NV module. This is required so that
13648 we can initialize the channel information in wiphy
13649 from the NV.bin data. The channel information in
13650 wiphy needs to be initialized before wiphy registration */
13651
13652 status = vos_nv_open();
13653 if (!VOS_IS_STATUS_SUCCESS(status))
13654 {
13655 /* NV module cannot be initialized */
13656 hddLog( VOS_TRACE_LEVEL_FATAL,
13657 "%s: vos_nv_open failed", __func__);
Vinay Krishna Eranna2025d892014-09-18 16:51:42 +053013658 goto err_wdclose;
Amar Singhal0a402232013-10-11 20:57:16 -070013659 }
13660
13661 status = vos_init_wiphy_from_nv_bin();
13662 if (!VOS_IS_STATUS_SUCCESS(status))
13663 {
13664 /* NV module cannot be initialized */
13665 hddLog( VOS_TRACE_LEVEL_FATAL,
13666 "%s: vos_init_wiphy failed", __func__);
13667 goto err_vos_nv_close;
13668 }
13669
Amar Singhala49cbc52013-10-08 18:37:44 -070013670#endif
Mahesh A Saptasagarc3ed0122016-01-19 16:45:11 +053013671 //Initialize the nlink service
13672 if(nl_srv_init() != 0)
13673 {
13674 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: nl_srv_init failed", __func__);
13675 goto err_vos_nv_close;
13676 }
13677
13678#ifdef WLAN_KD_READY_NOTIFIER
13679 pHddCtx->kd_nl_init = 1;
13680#endif /* WLAN_KD_READY_NOTIFIER */
13681
Girish Gowlibf0e1ab2015-01-19 16:05:16 +053013682 vos_set_roam_delay_stats_enabled(pHddCtx->cfg_ini->gEnableRoamDelayStats);
Arun Kumar Khandavalliebb19482014-03-25 13:56:53 +053013683 status = vos_open( &pVosContext, pHddCtx->parent_dev);
Jeff Johnson295189b2012-06-20 16:38:30 -070013684 if ( !VOS_IS_STATUS_SUCCESS( status ))
13685 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -080013686 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: vos_open failed", __func__);
Mahesh A Saptasagarc3ed0122016-01-19 16:45:11 +053013687 goto err_nl_srv;
Jeff Johnson295189b2012-06-20 16:38:30 -070013688 }
13689
Jeff Johnson295189b2012-06-20 16:38:30 -070013690 pHddCtx->hHal = (tHalHandle)vos_get_context( VOS_MODULE_ID_SME, pVosContext );
13691
13692 if ( NULL == pHddCtx->hHal )
13693 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -080013694 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: HAL context is null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070013695 goto err_vosclose;
13696 }
13697
Jeff Johnsonbc676b42013-02-14 16:04:08 -080013698 status = vos_preStart( pHddCtx->pvosContext );
13699 if ( !VOS_IS_STATUS_SUCCESS( status ) )
13700 {
13701 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: vos_preStart failed", __func__);
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053013702 goto err_vosclose;
Jeff Johnsonbc676b42013-02-14 16:04:08 -080013703 }
Jeff Johnsone7245742012-09-05 17:12:55 -070013704
Arif Hussaineaf68602013-12-30 23:10:44 -080013705 if (0 == enable_dfs_chan_scan || 1 == enable_dfs_chan_scan)
13706 {
13707 pHddCtx->cfg_ini->enableDFSChnlScan = enable_dfs_chan_scan;
13708 hddLog(VOS_TRACE_LEVEL_INFO, "%s: module enable_dfs_chan_scan set to %d",
13709 __func__, enable_dfs_chan_scan);
13710 }
13711 if (0 == enable_11d || 1 == enable_11d)
13712 {
13713 pHddCtx->cfg_ini->Is11dSupportEnabled = enable_11d;
13714 hddLog(VOS_TRACE_LEVEL_INFO, "%s: module enable_11d set to %d",
13715 __func__, enable_11d);
13716 }
13717
Jeff Johnsonbc676b42013-02-14 16:04:08 -080013718 /* Note that the vos_preStart() sequence triggers the cfg download.
13719 The cfg download must occur before we update the SME config
13720 since the SME config operation must access the cfg database */
Jeff Johnson295189b2012-06-20 16:38:30 -070013721 status = hdd_set_sme_config( pHddCtx );
13722
13723 if ( VOS_STATUS_SUCCESS != status )
13724 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -080013725 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Failed hdd_set_sme_config", __func__);
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053013726 goto err_vosclose;
Jeff Johnsonbc676b42013-02-14 16:04:08 -080013727 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013728
Jeff Johnson295189b2012-06-20 16:38:30 -070013729 /* In the integrated architecture we update the configuration from
13730 the INI file and from NV before vOSS has been started so that
13731 the final contents are available to send down to the cCPU */
13732
13733 // Apply the cfg.ini to cfg.dat
13734 if (FALSE == hdd_update_config_dat(pHddCtx))
13735 {
13736 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: config update failed",__func__ );
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053013737 goto err_vosclose;
Jeff Johnson295189b2012-06-20 16:38:30 -070013738 }
13739
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +053013740 // Get mac addr from platform driver
13741 ret = wcnss_get_wlan_mac_address((char*)&mac_addr.bytes);
13742
13743 if ((0 == ret) && (!vos_is_macaddr_zero(&mac_addr)))
Jeff Johnson295189b2012-06-20 16:38:30 -070013744 {
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +053013745 /* Store the mac addr for first interface */
13746 pHddCtx->cfg_ini->intfMacAddr[0] = mac_addr;
13747
13748 hddLog(VOS_TRACE_LEVEL_ERROR,
13749 "%s: WLAN Mac Addr: "
13750 MAC_ADDRESS_STR, __func__,
13751 MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[0].bytes));
13752
13753 /* Here, passing Arg2 as 1 because we do not want to change the
13754 last 3 bytes (means non OUI bytes) of first interface mac
13755 addr.
13756 */
13757 if (0 != hdd_generate_iface_mac_addr_auto(pHddCtx, 1, mac_addr))
13758 {
13759 hddLog(VOS_TRACE_LEVEL_ERROR,
13760 "%s: Failed to generate wlan interface mac addr "
13761 "using MAC from ini file ", __func__);
13762 }
13763 }
13764 else if (VOS_STATUS_SUCCESS != hdd_update_config_from_nv(pHddCtx))
13765 {
13766 // Apply the NV to cfg.dat
13767 /* Prima Update MAC address only at here */
Jeff Johnson295189b2012-06-20 16:38:30 -070013768#ifdef WLAN_AUTOGEN_MACADDR_FEATURE
13769 /* There was not a valid set of MAC Addresses in NV. See if the
13770 default addresses were modified by the cfg.ini settings. If so,
13771 we'll use them, but if not, we'll autogenerate a set of MAC
13772 addresses based upon the device serial number */
13773
13774 static const v_MACADDR_t default_address =
13775 {{0x00, 0x0A, 0xF5, 0x89, 0x89, 0xFF}};
Jeff Johnson295189b2012-06-20 16:38:30 -070013776
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +053013777 if (0 == memcmp(&default_address, &pHddCtx->cfg_ini->intfMacAddr[0],
13778 sizeof(default_address)))
Jeff Johnson295189b2012-06-20 16:38:30 -070013779 {
13780 /* cfg.ini has the default address, invoke autogen logic */
13781
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +053013782 /* Here, passing Arg2 as 0 because we want to change the
13783 last 3 bytes (means non OUI bytes) of all the interfaces
13784 mac addr.
13785 */
13786 if (0 != hdd_generate_iface_mac_addr_auto(pHddCtx, 0,
13787 default_address))
Jeff Johnson295189b2012-06-20 16:38:30 -070013788 {
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +053013789 hddLog(VOS_TRACE_LEVEL_ERROR,
13790 "%s: Failed to generate wlan interface mac addr "
13791 "using MAC from ini file " MAC_ADDRESS_STR, __func__,
13792 MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[0].bytes));
Jeff Johnson295189b2012-06-20 16:38:30 -070013793 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013794 }
13795 else
13796#endif //WLAN_AUTOGEN_MACADDR_FEATURE
13797 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -080013798 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070013799 "%s: Invalid MAC address in NV, using MAC from ini file "
13800 MAC_ADDRESS_STR, __func__,
13801 MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[0].bytes));
13802 }
13803 }
13804 {
13805 eHalStatus halStatus;
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +053013806
13807 /* Set the MAC Address Currently this is used by HAL to
13808 * add self sta. Remove this once self sta is added as
13809 * part of session open.
13810 */
Jeff Johnson295189b2012-06-20 16:38:30 -070013811 halStatus = cfgSetStr( pHddCtx->hHal, WNI_CFG_STA_ID,
13812 (v_U8_t *)&pHddCtx->cfg_ini->intfMacAddr[0],
13813 sizeof( pHddCtx->cfg_ini->intfMacAddr[0]) );
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +053013814
Jeff Johnson295189b2012-06-20 16:38:30 -070013815 if (!HAL_STATUS_SUCCESS( halStatus ))
13816 {
13817 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Failed to set MAC Address. "
13818 "HALStatus is %08d [x%08x]",__func__, halStatus, halStatus );
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053013819 goto err_vosclose;
Jeff Johnson295189b2012-06-20 16:38:30 -070013820 }
13821 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013822
13823 /*Start VOSS which starts up the SME/MAC/HAL modules and everything else
13824 Note: Firmware image will be read and downloaded inside vos_start API */
13825 status = vos_start( pHddCtx->pvosContext );
13826 if ( !VOS_IS_STATUS_SUCCESS( status ) )
13827 {
13828 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: vos_start failed",__func__);
Hanumantha Reddy Pothulabd9601a2016-02-12 13:22:27 +053013829 if (isSsrPanicOnFailure())
13830 VOS_BUG(0);
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053013831 goto err_vosclose;
Jeff Johnson295189b2012-06-20 16:38:30 -070013832 }
13833
Leo Chang6cec3e22014-01-21 15:33:49 -080013834#ifdef FEATURE_WLAN_CH_AVOID
13835 /* Plug in avoid channel notification callback
13836 * This should happen before ADD_SELF_STA
13837 * FW will send first IND with ADD_SELF_STA REQ from host */
Pradeep Reddy POTTETI5c2e16d2014-06-27 16:47:38 +053013838
13839 /* check the Channel Avoidance is enabled */
13840 if (TRUE == pHddCtx->cfg_ini->fenableCHAvoidance)
13841 {
13842 sme_AddChAvoidCallback(pHddCtx->hHal,
13843 hdd_hostapd_ch_avoid_cb);
13844 }
Leo Chang6cec3e22014-01-21 15:33:49 -080013845#endif /* FEATURE_WLAN_CH_AVOID */
13846
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -070013847 /* Exchange capability info between Host and FW and also get versioning info from FW */
13848 hdd_exchange_version_and_caps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -070013849
Agarwal Ashishad9281b2014-06-10 14:57:30 +053013850#ifdef CONFIG_ENABLE_LINUX_REG
13851 status = wlan_hdd_init_channels(pHddCtx);
13852 if ( !VOS_IS_STATUS_SUCCESS( status ) )
13853 {
13854 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: wlan_hdd_init_channels failed",
13855 __func__);
13856 goto err_vosstop;
13857 }
13858#endif
13859
Jeff Johnson295189b2012-06-20 16:38:30 -070013860 status = hdd_post_voss_start_config( pHddCtx );
13861 if ( !VOS_IS_STATUS_SUCCESS( status ) )
13862 {
13863 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hdd_post_voss_start_config failed",
13864 __func__);
13865 goto err_vosstop;
13866 }
Amar Singhala49cbc52013-10-08 18:37:44 -070013867
Rajeev Kumar Sirasanagandla2bb30b82019-01-07 22:30:16 +053013868 wlan_hdd_cfg80211_scan_randomization_init(wiphy);
13869
Amar Singhala49cbc52013-10-08 18:37:44 -070013870#ifndef CONFIG_ENABLE_LINUX_REG
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +053013871 wlan_hdd_cfg80211_update_reg_info( wiphy );
13872
13873 /* registration of wiphy dev with cfg80211 */
13874 if (0 > wlan_hdd_cfg80211_register(wiphy))
13875 {
13876 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy register failed", __func__);
13877 goto err_vosstop;
13878 }
Amar Singhala49cbc52013-10-08 18:37:44 -070013879#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070013880
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053013881#ifdef CONFIG_ENABLE_LINUX_REG
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053013882 /* registration of wiphy dev with cfg80211 */
13883 if (0 > wlan_hdd_cfg80211_register(wiphy))
13884 {
13885 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy register failed", __func__);
13886 goto err_vosstop;
13887 }
13888
Agarwal Ashish6db9d532014-09-30 18:19:10 +053013889 status = wlan_hdd_init_channels_for_cc(pHddCtx, INIT);
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053013890 if ( !VOS_IS_STATUS_SUCCESS( status ) )
13891 {
13892 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: wlan_hdd_init_channels_for_cc failed",
13893 __func__);
13894 goto err_unregister_wiphy;
13895 }
13896#endif
13897
c_hpothu4a298be2014-12-22 21:12:51 +053013898 wcnss_wlan_set_drvdata(pHddCtx->parent_dev, pHddCtx);
13899
Jeff Johnson295189b2012-06-20 16:38:30 -070013900 if (VOS_STA_SAP_MODE == hdd_get_conparam())
13901 {
13902 pAdapter = hdd_open_adapter( pHddCtx, WLAN_HDD_SOFTAP, "softap.%d",
13903 wlan_hdd_get_intf_addr(pHddCtx), FALSE );
13904 }
13905 else
13906 {
Jeff Johnson295189b2012-06-20 16:38:30 -070013907 pAdapter = hdd_open_adapter( pHddCtx, WLAN_HDD_INFRA_STATION, "wlan%d",
13908 wlan_hdd_get_intf_addr(pHddCtx), FALSE );
13909 if (pAdapter != NULL)
13910 {
Katya Nigama7d81d72014-11-12 12:44:34 +053013911 if (pHddCtx->cfg_ini->isP2pDeviceAddrAdministrated && !(pHddCtx->cfg_ini->intfMacAddr[0].bytes[0] & 0x02))
Jeff Johnson295189b2012-06-20 16:38:30 -070013912 {
Gopichand Nakkala49f96f62013-02-06 14:38:17 +053013913 vos_mem_copy( pHddCtx->p2pDeviceAddress.bytes,
13914 pHddCtx->cfg_ini->intfMacAddr[0].bytes,
13915 sizeof(tSirMacAddr));
Madan Mohan Koyyalamudiedfc1b72012-10-18 20:25:55 -070013916
Gopichand Nakkala49f96f62013-02-06 14:38:17 +053013917 /* Generate the P2P Device Address. This consists of the device's
13918 * primary MAC address with the locally administered bit set.
13919 */
13920 pHddCtx->p2pDeviceAddress.bytes[0] |= 0x02;
Jeff Johnsone7245742012-09-05 17:12:55 -070013921 }
13922 else
13923 {
Gopichand Nakkala49f96f62013-02-06 14:38:17 +053013924 tANI_U8* p2p_dev_addr = wlan_hdd_get_intf_addr(pHddCtx);
13925 if (p2p_dev_addr != NULL)
13926 {
13927 vos_mem_copy(&pHddCtx->p2pDeviceAddress.bytes[0],
13928 p2p_dev_addr, VOS_MAC_ADDR_SIZE);
13929 }
13930 else
13931 {
13932 hddLog(VOS_TRACE_LEVEL_FATAL,
13933 "%s: Failed to allocate mac_address for p2p_device",
13934 __func__);
13935 goto err_close_adapter;
13936 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013937 }
Jeff Johnsone7245742012-09-05 17:12:55 -070013938
13939 pP2pAdapter = hdd_open_adapter( pHddCtx, WLAN_HDD_P2P_DEVICE, "p2p%d",
13940 &pHddCtx->p2pDeviceAddress.bytes[0], FALSE );
13941 if ( NULL == pP2pAdapter )
13942 {
13943 hddLog(VOS_TRACE_LEVEL_FATAL,
13944 "%s: Failed to do hdd_open_adapter for P2P Device Interface",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070013945 __func__);
Jeff Johnsone7245742012-09-05 17:12:55 -070013946 goto err_close_adapter;
13947 }
Jeff Johnsone7245742012-09-05 17:12:55 -070013948 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013949 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013950
13951 if( pAdapter == NULL )
13952 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -080013953 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: hdd_open_adapter failed", __func__);
13954 goto err_close_adapter;
Jeff Johnson295189b2012-06-20 16:38:30 -070013955 }
Jeff Johnsone7245742012-09-05 17:12:55 -070013956
Ashish Kumar Dhanotiya3ac85a22019-02-12 19:10:14 +053013957 if ((strlen(pHddCtx->cfg_ini->enabledefaultSAP) != 0) &&
13958 (strcmp(pHddCtx->cfg_ini->enabledefaultSAP, "") != 0)) {
Arunk Khandavalli95608be2019-01-22 13:12:54 +053013959 softapAdapter = hdd_open_adapter( pHddCtx, WLAN_HDD_SOFTAP,
13960 pHddCtx->cfg_ini->enabledefaultSAP,
13961 wlan_hdd_get_intf_addr(pHddCtx), FALSE);
13962 if (!softapAdapter) {
13963 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: hdd_open_adapter failed", __func__);
13964 goto err_close_adapter;
13965 }
13966 }
13967
Arif Hussain66559122013-11-21 10:11:40 -080013968 if (country_code)
13969 {
13970 eHalStatus ret;
Arif Hussaincb607082013-12-20 11:57:42 -080013971 INIT_COMPLETION(pAdapter->change_country_code);
Arif Hussain66559122013-11-21 10:11:40 -080013972 hdd_checkandupdate_dfssetting(pAdapter, country_code);
13973#ifndef CONFIG_ENABLE_LINUX_REG
13974 hdd_checkandupdate_phymode(pAdapter, country_code);
13975#endif
Arif Hussaineaf68602013-12-30 23:10:44 -080013976 ret = sme_ChangeCountryCode(pHddCtx->hHal,
13977 (void *)(tSmeChangeCountryCallback)
13978 wlan_hdd_change_country_code_callback,
Arif Hussain66559122013-11-21 10:11:40 -080013979 country_code,
13980 pAdapter, pHddCtx->pvosContext,
Abhishek Singha306a442013-11-07 18:39:01 +053013981 eSIR_TRUE, eSIR_TRUE);
Arif Hussain66559122013-11-21 10:11:40 -080013982 if (eHAL_STATUS_SUCCESS == ret)
13983 {
Arif Hussaincb607082013-12-20 11:57:42 -080013984 ret = wait_for_completion_interruptible_timeout(
13985 &pAdapter->change_country_code,
13986 msecs_to_jiffies(WLAN_WAIT_TIME_COUNTRY));
13987
13988 if (0 >= ret)
13989 {
13990 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
13991 "%s: SME while setting country code timed out", __func__);
13992 }
Arif Hussain66559122013-11-21 10:11:40 -080013993 }
13994 else
13995 {
Arif Hussaincb607082013-12-20 11:57:42 -080013996 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
13997 "%s: SME Change Country code from module param fail ret=%d",
13998 __func__, ret);
Arif Hussain66559122013-11-21 10:11:40 -080013999 }
14000 }
14001
Jeff Johnson295189b2012-06-20 16:38:30 -070014002#ifdef WLAN_BTAMP_FEATURE
14003 vStatus = WLANBAP_Open(pVosContext);
14004 if(!VOS_IS_STATUS_SUCCESS(vStatus))
14005 {
14006 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
14007 "%s: Failed to open BAP",__func__);
Jeff Johnsone7245742012-09-05 17:12:55 -070014008 goto err_close_adapter;
Jeff Johnson295189b2012-06-20 16:38:30 -070014009 }
14010
14011 vStatus = BSL_Init(pVosContext);
14012 if(!VOS_IS_STATUS_SUCCESS(vStatus))
14013 {
14014 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
14015 "%s: Failed to Init BSL",__func__);
14016 goto err_bap_close;
14017 }
14018 vStatus = WLANBAP_Start(pVosContext);
14019 if (!VOS_IS_STATUS_SUCCESS(vStatus))
14020 {
14021 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
14022 "%s: Failed to start TL",__func__);
14023 goto err_bap_close;
14024 }
14025
14026 pConfig = pHddCtx->cfg_ini;
14027 btAmpConfig.ucPreferredChannel = pConfig->preferredChannel;
14028 status = WLANBAP_SetConfig(&btAmpConfig);
14029
14030#endif //WLAN_BTAMP_FEATURE
Jeff Johnsone7245742012-09-05 17:12:55 -070014031
Mihir Shete9c238772014-10-15 14:35:16 +053014032 /*
14033 * UapsdMask is 0xf if U-APSD is enbaled for all AC's...
14034 * The value of CFG_QOS_WMM_UAPSD_MASK_DEFAULT is 0xaa(Magic Value)
14035 * which is greater than 0xf. So the below check is safe to make
14036 * sure that there is no entry for UapsdMask in the ini
14037 */
14038 if (CFG_QOS_WMM_UAPSD_MASK_DEFAULT == pHddCtx->cfg_ini->UapsdMask)
14039 {
14040 if(IS_DYNAMIC_WMM_PS_ENABLED)
14041 {
14042 hddLog(VOS_TRACE_LEVEL_DEBUG,"%s: Enable UAPSD for VI & VO",
14043 __func__);
14044 pHddCtx->cfg_ini->UapsdMask =
14045 CFG_QOS_WMM_UAPSD_MASK_DYMANIC_WMM_PS_DEFAULT;
14046 }
14047 else
14048 {
14049 hddLog(VOS_TRACE_LEVEL_DEBUG,"%s: Do not enable UAPSD",
14050 __func__);
14051 pHddCtx->cfg_ini->UapsdMask =
14052 CFG_QOS_WMM_UAPSD_MASK_LEGACY_WMM_PS_DEFAULT;
14053 }
14054 }
14055
Varun Reddy Yeturud0a3f252013-04-15 21:58:13 -070014056#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
14057 if(!(IS_ROAM_SCAN_OFFLOAD_FEATURE_ENABLE))
14058 {
14059 hddLog(VOS_TRACE_LEVEL_DEBUG,"%s: ROAM_SCAN_OFFLOAD Feature not supported",__func__);
14060 pHddCtx->cfg_ini->isRoamOffloadScanEnabled = 0;
14061 sme_UpdateRoamScanOffloadEnabled((tHalHandle)(pHddCtx->hHal),
14062 pHddCtx->cfg_ini->isRoamOffloadScanEnabled);
14063 }
14064#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070014065
Agarwal Ashish4b87f922014-06-18 03:03:21 +053014066 wlan_hdd_tdls_init(pHddCtx);
14067
Masti, Narayanraddi26378462016-01-05 18:20:28 +053014068 wlan_hdd_init_deinit_defer_scan_context(&pHddCtx->scan_ctxt);
14069
14070 vos_init_delayed_work(&pHddCtx->scan_ctxt.scan_work,
14071 wlan_hdd_schedule_defer_scan);
14072
Mihir Shetefc7ff5b2014-01-27 11:30:05 +053014073 sme_Register11dScanDoneCallback(pHddCtx->hHal, hdd_11d_scan_done);
14074
Jeff Johnson295189b2012-06-20 16:38:30 -070014075 /* Register with platform driver as client for Suspend/Resume */
14076 status = hddRegisterPmOps(pHddCtx);
14077 if ( !VOS_IS_STATUS_SUCCESS( status ) )
14078 {
14079 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddRegisterPmOps failed",__func__);
14080#ifdef WLAN_BTAMP_FEATURE
14081 goto err_bap_stop;
14082#else
Jeff Johnsone7245742012-09-05 17:12:55 -070014083 goto err_close_adapter;
Jeff Johnson295189b2012-06-20 16:38:30 -070014084#endif //WLAN_BTAMP_FEATURE
14085 }
14086
Yue Ma0d4891e2013-08-06 17:01:45 -070014087 /* Open debugfs interface */
14088 if (VOS_STATUS_SUCCESS != hdd_debugfs_init(pAdapter))
14089 {
14090 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
14091 "%s: hdd_debugfs_init failed!", __func__);
Yue Ma0d4891e2013-08-06 17:01:45 -070014092 }
14093
Jeff Johnson295189b2012-06-20 16:38:30 -070014094 /* Register TM level change handler function to the platform */
14095 status = hddDevTmRegisterNotifyCallback(pHddCtx);
14096 if ( !VOS_IS_STATUS_SUCCESS( status ) )
14097 {
14098 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddDevTmRegisterNotifyCallback failed",__func__);
14099 goto err_unregister_pmops;
14100 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014101
Jeff Johnson295189b2012-06-20 16:38:30 -070014102 // register net device notifier for device change notification
14103 ret = register_netdevice_notifier(&hdd_netdev_notifier);
14104
14105 if(ret < 0)
14106 {
14107 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: register_netdevice_notifier failed",__func__);
Siddharth Bhalcd92b782015-06-29 12:25:40 +053014108 goto err_unregister_pmops;
Jeff Johnson295189b2012-06-20 16:38:30 -070014109 }
14110
Jeff Johnson295189b2012-06-20 16:38:30 -070014111 //Initialize the BTC service
14112 if(btc_activate_service(pHddCtx) != 0)
14113 {
14114 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: btc_activate_service failed",__func__);
Mahesh A Saptasagarc3ed0122016-01-19 16:45:11 +053014115 goto err_reg_netdev;
Jeff Johnson295189b2012-06-20 16:38:30 -070014116 }
14117
Padma, Santhosh Kumar2762e9d2015-10-20 15:02:57 +053014118#ifdef FEATURE_OEM_DATA_SUPPORT
14119 //Initialize the OEM service
14120 if (oem_activate_service(pHddCtx) != 0)
14121 {
14122 hddLog(VOS_TRACE_LEVEL_FATAL,
14123 "%s: oem_activate_service failed", __func__);
Hanumanth Reddy Pothula13789c42017-09-12 15:18:13 +053014124 goto err_btc_activate_service;
Padma, Santhosh Kumar2762e9d2015-10-20 15:02:57 +053014125 }
14126#endif
14127
Jeff Johnson295189b2012-06-20 16:38:30 -070014128#ifdef PTT_SOCK_SVC_ENABLE
14129 //Initialize the PTT service
14130 if(ptt_sock_activate_svc(pHddCtx) != 0)
14131 {
14132 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: ptt_sock_activate_svc failed",__func__);
Hanumanth Reddy Pothula13789c42017-09-12 15:18:13 +053014133 goto err_oem_activate_service;
Jeff Johnson295189b2012-06-20 16:38:30 -070014134 }
14135#endif
14136
Abhishek Singh00b71972016-01-07 10:51:04 +053014137#ifdef WLAN_FEATURE_RMC
14138 if (hdd_open_cesium_nl_sock() < 0)
14139 {
14140 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hdd_open_cesium_nl_sock failed", __func__);
Hanumanth Reddy Pothula13789c42017-09-12 15:18:13 +053014141 goto err_ptt_sock_activate_svc;
Abhishek Singh00b71972016-01-07 10:51:04 +053014142 }
14143#endif
14144
Vinay Krishna Erannad938c422014-03-10 17:14:21 +053014145#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
14146 if(pHddCtx->cfg_ini && pHddCtx->cfg_ini->wlanLoggingEnable)
14147 {
Deepthi Gowri78083a32014-11-04 12:55:51 +053014148 if(wlan_logging_sock_activate_svc(
14149 pHddCtx->cfg_ini->wlanLoggingFEToConsole,
Sushant Kaushik33200572015-08-05 16:46:20 +053014150 pHddCtx->cfg_ini->wlanLoggingNumBuf,
14151 pHddCtx->cfg_ini->wlanPerPktStatsLogEnable,
14152 pHddCtx->cfg_ini->wlanPerPktStatsNumBuf))
Deepthi Gowri78083a32014-11-04 12:55:51 +053014153 {
14154 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wlan_logging_sock_activate_svc"
14155 " failed", __func__);
Hanumanth Reddy Pothula13789c42017-09-12 15:18:13 +053014156 goto err_open_cesium_nl_sock;
Deepthi Gowri78083a32014-11-04 12:55:51 +053014157 }
14158 //TODO: To Remove enableDhcpDebug and use gEnableDebugLog for
14159 //EAPOL and DHCP
Sachin Ahuja8c65f382014-12-12 15:34:21 +053014160 if (!pHddCtx->cfg_ini->gEnableDebugLog)
14161 pHddCtx->cfg_ini->gEnableDebugLog =
Sushant Kaushik6e4e2bc2015-10-05 17:23:07 +053014162 VOS_PKT_PROTO_TYPE_EAPOL | VOS_PKT_PROTO_TYPE_DHCP |
14163 VOS_PKT_PROTO_TYPE_ARP;
Vinay Krishna Erannad938c422014-03-10 17:14:21 +053014164 }
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053014165
Siddharth Bhald1be97f2015-05-27 22:39:59 +053014166 if (pHddCtx->cfg_ini->wlanLoggingEnable &&
14167 (pHddCtx->cfg_ini->enableFWLogging ||
Siddharth Bhaldb963232015-06-25 19:34:35 +053014168 pHddCtx->cfg_ini->enableMgmtLogging ||
c_manjeecfd1efb2015-09-25 19:32:34 +053014169 pHddCtx->cfg_ini->enableContFWLogging ||
14170 pHddCtx->cfg_ini->enableFwrMemDump )
14171 )
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053014172 {
Siddharth Bhald1be97f2015-05-27 22:39:59 +053014173 hdd_init_frame_logging(pHddCtx);
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053014174 }
14175 else
14176 {
Siddharth Bhald1be97f2015-05-27 22:39:59 +053014177 hddLog(VOS_TRACE_LEVEL_INFO, FL("Logging disabled in ini"));
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053014178 }
14179
Vinay Krishna Erannad938c422014-03-10 17:14:21 +053014180#endif
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053014181
Agrawal Ashish17ef5082016-10-17 18:33:21 +053014182#ifdef SAP_AUTH_OFFLOAD
14183 if (!sme_IsFeatureSupportedByFW(SAP_OFFLOADS))
14184 {
14185 hddLog(VOS_TRACE_LEVEL_INFO, FL(" SAP AUTH OFFLOAD not supp by FW"));
14186 pHddCtx->cfg_ini->enable_sap_auth_offload = 0;
14187 }
14188#endif
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053014189
Sushant Kaushik215778f2015-05-21 14:05:36 +053014190 if (vos_is_multicast_logging())
14191 wlan_logging_set_log_level();
14192
Jeff Johnson295189b2012-06-20 16:38:30 -070014193 hdd_register_mcast_bcast_filter(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -070014194 if (VOS_STA_SAP_MODE != hdd_get_conparam())
Jeff Johnson295189b2012-06-20 16:38:30 -070014195 {
Madan Mohan Koyyalamudic537df22012-10-22 15:07:08 -070014196 /* Action frame registered in one adapter which will
14197 * applicable to all interfaces
14198 */
Agarwal Ashish8fa0e9a2014-05-23 00:40:12 +053014199 wlan_hdd_cfg80211_register_frames(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070014200 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014201
14202 mutex_init(&pHddCtx->sap_lock);
Mahesh A Saptasagar60627942014-10-13 13:55:14 +053014203 mutex_init(&pHddCtx->roc_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -070014204
Jeff Johnsone7245742012-09-05 17:12:55 -070014205#ifdef WLAN_FEATURE_HOLD_RX_WAKELOCK
14206 /* Initialize the wake lcok */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053014207 vos_wake_lock_init(&pHddCtx->rx_wake_lock,
Jeff Johnsone7245742012-09-05 17:12:55 -070014208 "qcom_rx_wakelock");
Sushant Kaushik83392fa2015-05-05 17:44:40 +053014209
Jeff Johnsone7245742012-09-05 17:12:55 -070014210#endif
Madan Mohan Koyyalamudi69fc3ad2012-11-28 16:04:56 -080014211 /* Initialize the wake lcok */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053014212 vos_wake_lock_init(&pHddCtx->sap_wake_lock,
Madan Mohan Koyyalamudi69fc3ad2012-11-28 16:04:56 -080014213 "qcom_sap_wakelock");
Sushant Kaushik83392fa2015-05-05 17:44:40 +053014214
Jeff Johnsone7245742012-09-05 17:12:55 -070014215
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070014216 vos_event_init(&pHddCtx->scan_info.scan_finished_event);
14217 pHddCtx->scan_info.scan_pending_option = WEXT_SCAN_PENDING_GIVEUP;
Jeff Johnson295189b2012-06-20 16:38:30 -070014218
Katya Nigam5c306ea2014-06-19 15:39:54 +053014219 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_NO_LOAD_UNLOAD_IN_PROGRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -070014220 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, FALSE);
Sushant Kaushik83392fa2015-05-05 17:44:40 +053014221 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_DRIVER_INIT);
Katya Nigam5c306ea2014-06-19 15:39:54 +053014222
14223#ifdef FEATURE_WLAN_SCAN_PNO
14224 /*SME must send channel update configuration to RIVA*/
14225 sme_UpdateChannelConfig(pHddCtx->hHal);
14226#endif
Abhishek Singhf644b272014-08-21 02:59:39 +053014227 /* Send the update default channel list to the FW*/
14228 sme_UpdateChannelList(pHddCtx->hHal);
Mukul Sharma45063942015-04-01 20:07:59 +053014229
14230 /* Fwr capabilities received, Set the Dot11 mode */
Abhishek Singh41ebce12016-02-03 10:43:21 +053014231 sme_SetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter),
14232 hdd_cfg_xlate_to_csr_phy_mode(pHddCtx->cfg_ini->dot11Mode));
Mukul Sharma45063942015-04-01 20:07:59 +053014233 sme_SetDefDot11Mode(pHddCtx->hHal);
14234
Abhishek Singha306a442013-11-07 18:39:01 +053014235#ifndef CONFIG_ENABLE_LINUX_REG
14236 /*updating wiphy so that regulatory user hints can be processed*/
14237 if (wiphy)
14238 {
14239 regulatory_hint(wiphy, "00");
14240 }
14241#endif
Jeff Johnsone7245742012-09-05 17:12:55 -070014242 // Initialize the restart logic
14243 wlan_hdd_restart_init(pHddCtx);
Chilam NG571c65a2013-01-19 12:27:36 +053014244
Hanumanth Reddy Pothula146bca42016-11-08 12:01:07 +053014245 if (pHddCtx->cfg_ini->fIsLogpEnabled) {
14246 vos_wdthread_init_timer_work(vos_process_wd_timer);
14247 /* Initialize the timer to detect thread stuck issues */
14248 vos_thread_stuck_timer_init(
14249 &((VosContextType*)pVosContext)->vosWatchdog);
14250 }
14251
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -070014252 //Register the traffic monitor timer now
14253 if ( pHddCtx->cfg_ini->dynSplitscan)
14254 {
14255 vos_timer_init(&pHddCtx->tx_rx_trafficTmr,
14256 VOS_TIMER_TYPE_SW,
14257 hdd_tx_rx_pkt_cnt_stat_timer_handler,
14258 (void *)pHddCtx);
14259 }
Srinivas Dasari030bad32015-02-18 23:23:54 +053014260 wlan_hdd_cfg80211_nan_init(pHddCtx);
14261
Bhargav Shahd0715912015-10-01 18:17:37 +053014262 mutex_init(&pHddCtx->cur_rx_level_lock);
14263 vos_timer_init(&pHddCtx->delack_timer, VOS_TIMER_TYPE_SW,
14264 hdd_tcp_delack_compute_function,(void *)pHddCtx);
Masti, Narayanraddi44b0db02015-12-22 11:54:35 +053014265 vos_timer_init(&pHddCtx->tdls_source_timer, VOS_TIMER_TYPE_SW,
14266 wlan_hdd_change_tdls_mode, (void *)pHddCtx);
Bhargav Shahd0715912015-10-01 18:17:37 +053014267
Dino Mycle6fb96c12014-06-10 11:52:40 +053014268#ifdef WLAN_FEATURE_EXTSCAN
14269 sme_EXTScanRegisterCallback(pHddCtx->hHal,
14270 wlan_hdd_cfg80211_extscan_callback,
14271 pHddCtx);
14272#endif /* WLAN_FEATURE_EXTSCAN */
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +053014273
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053014274#ifdef FEATURE_OEM_DATA_SUPPORT
14275 sme_OemDataRegisterCallback(pHddCtx->hHal,
14276 wlan_hdd_cfg80211_oemdata_callback,
14277 pHddCtx);
14278#endif /* FEATURE_OEM_DATA_SUPPORT */
14279
Gupta, Kapil7c34b322015-09-30 13:12:35 +053014280 sme_set_rssi_threshold_breached_cb(pHddCtx->hHal, hdd_rssi_threshold_breached_cb);
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +053014281#ifdef WLAN_NS_OFFLOAD
14282 // Register IPv6 notifier to notify if any change in IP
14283 // So that we can reconfigure the offload parameters
14284 pHddCtx->ipv6_notifier.notifier_call = wlan_hdd_ipv6_changed;
14285 ret = register_inet6addr_notifier(&pHddCtx->ipv6_notifier);
14286 if (ret)
14287 {
Ratheesh S P36dbc932015-08-07 14:28:57 +053014288 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to register IPv6 notifier"));
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +053014289 }
14290 else
14291 {
Ratheesh S P36dbc932015-08-07 14:28:57 +053014292 hddLog(VOS_TRACE_LEVEL_INFO, FL("Registered IPv6 notifier"));
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +053014293 }
14294#endif
14295
Sravan Kumar Kairamb0edc612016-10-26 13:55:24 +053014296 vos_mem_set((uint8_t *)&pHddCtx->bad_sta, HDD_MAX_STA_COUNT, 0);
14297
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +053014298 // Register IPv4 notifier to notify if any change in IP
14299 // So that we can reconfigure the offload parameters
14300 pHddCtx->ipv4_notifier.notifier_call = wlan_hdd_ipv4_changed;
14301 ret = register_inetaddr_notifier(&pHddCtx->ipv4_notifier);
14302 if (ret)
14303 {
Ratheesh S P36dbc932015-08-07 14:28:57 +053014304 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to register IPv4 notifier"));
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +053014305 }
14306 else
14307 {
Ratheesh S P36dbc932015-08-07 14:28:57 +053014308 hddLog(VOS_TRACE_LEVEL_INFO, FL("Registered IPv4 notifier"));
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +053014309 }
c_manjeecfd1efb2015-09-25 19:32:34 +053014310 /*Fw mem dump procfs initialization*/
14311 memdump_init();
Bhargav shah23c94942015-10-13 12:48:35 +053014312 hdd_dp_util_send_rps_ind(pHddCtx);
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +053014313
Nishank Aggarwalc11826c2016-12-15 18:54:10 +053014314 pHddCtx->is_ap_mode_wow_supported =
14315 sme_IsFeatureSupportedByFW(SAP_MODE_WOW);
Sravan Kumar Kairam091e5b62017-01-23 14:14:20 +053014316
Hanumanth Reddy Pothulae92bcc12017-05-19 13:56:35 +053014317 pHddCtx->is_fatal_event_log_sup =
14318 sme_IsFeatureSupportedByFW(FATAL_EVENT_LOGGING);
14319 hddLog(VOS_TRACE_LEVEL_INFO, FL("FATAL_EVENT_LOGGING: %d"),
14320 pHddCtx->is_fatal_event_log_sup);
14321
Sravan Kumar Kairam091e5b62017-01-23 14:14:20 +053014322 hdd_assoc_registerFwdEapolCB(pVosContext);
14323
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +053014324 mutex_init(&pHddCtx->cache_channel_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -070014325 goto success;
14326
Hanumanth Reddy Pothula13789c42017-09-12 15:18:13 +053014327err_open_cesium_nl_sock:
14328#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
14329 hdd_close_cesium_nl_sock();
14330#endif
14331
14332err_ptt_sock_activate_svc:
14333#ifdef PTT_SOCK_SVC_ENABLE
14334 ptt_sock_deactivate_svc(pHddCtx);
14335#endif
14336
14337err_oem_activate_service:
14338#ifdef FEATURE_OEM_DATA_SUPPORT
14339 oem_deactivate_service();
14340#endif
14341
14342err_btc_activate_service:
14343 btc_deactivate_service();
14344
Jeff Johnson295189b2012-06-20 16:38:30 -070014345err_reg_netdev:
14346 unregister_netdevice_notifier(&hdd_netdev_notifier);
14347
Jeff Johnson295189b2012-06-20 16:38:30 -070014348err_unregister_pmops:
14349 hddDevTmUnregisterNotifyCallback(pHddCtx);
14350 hddDeregisterPmOps(pHddCtx);
14351
Yue Ma0d4891e2013-08-06 17:01:45 -070014352 hdd_debugfs_exit(pHddCtx);
14353
Jeff Johnson295189b2012-06-20 16:38:30 -070014354#ifdef WLAN_BTAMP_FEATURE
14355err_bap_stop:
14356 WLANBAP_Stop(pVosContext);
14357#endif
14358
14359#ifdef WLAN_BTAMP_FEATURE
14360err_bap_close:
14361 WLANBAP_Close(pVosContext);
14362#endif
14363
Jeff Johnson295189b2012-06-20 16:38:30 -070014364err_close_adapter:
14365 hdd_close_all_adapters( pHddCtx );
Mahesh A Saptasagar9ecefe42014-07-15 18:43:49 +053014366#ifdef CONFIG_ENABLE_LINUX_REG
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053014367err_unregister_wiphy:
Mahesh A Saptasagar9ecefe42014-07-15 18:43:49 +053014368#endif
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +053014369 wiphy_unregister(wiphy) ;
Agrawal Ashish33ec71e2015-11-26 20:20:58 +053014370 hdd_wlan_free_wiphy_channels(wiphy);
14371
Jeff Johnson295189b2012-06-20 16:38:30 -070014372err_vosstop:
14373 vos_stop(pVosContext);
14374
Amar Singhala49cbc52013-10-08 18:37:44 -070014375err_vosclose:
Jeff Johnson295189b2012-06-20 16:38:30 -070014376 status = vos_sched_close( pVosContext );
14377 if (!VOS_IS_STATUS_SUCCESS(status)) {
14378 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
14379 "%s: Failed to close VOSS Scheduler", __func__);
14380 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( status ) );
14381 }
Amar Singhala49cbc52013-10-08 18:37:44 -070014382 vos_close(pVosContext );
14383
Mahesh A Saptasagarc3ed0122016-01-19 16:45:11 +053014384err_nl_srv:
14385#ifdef WLAN_KD_READY_NOTIFIER
14386 nl_srv_exit(pHddCtx->ptt_pid);
14387#else
14388 nl_srv_exit();
14389#endif /* WLAN_KD_READY_NOTIFIER */
Amar Singhal0a402232013-10-11 20:57:16 -070014390err_vos_nv_close:
14391
c_hpothue6a36282014-03-19 12:27:38 +053014392#ifdef CONFIG_ENABLE_LINUX_REG
Amar Singhal0a402232013-10-11 20:57:16 -070014393 vos_nv_close();
14394
c_hpothu70f8d812014-03-22 22:59:23 +053014395#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070014396
14397err_wdclose:
14398 if(pHddCtx->cfg_ini->fIsLogpEnabled)
14399 vos_watchdog_close(pVosContext);
14400
Jeff Johnson295189b2012-06-20 16:38:30 -070014401err_config:
Hanumanth Reddy Pothula1efcd162018-03-14 14:32:27 +053014402 hdd_request_manager_deinit();
Jeff Johnson295189b2012-06-20 16:38:30 -070014403 kfree(pHddCtx->cfg_ini);
14404 pHddCtx->cfg_ini= NULL;
14405
14406err_free_hdd_context:
Sushant Kaushik83392fa2015-05-05 17:44:40 +053014407 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_DRIVER_INIT);
Siddharth Bhalcd92b782015-06-29 12:25:40 +053014408 free_riva_power_on_lock("wlan");
Jeff Johnson295189b2012-06-20 16:38:30 -070014409 wiphy_free(wiphy) ;
14410 //kfree(wdev) ;
Jeff Johnson295189b2012-06-20 16:38:30 -070014411 VOS_BUG(1);
14412
Madan Mohan Koyyalamudid57ae632012-11-06 18:42:48 -080014413 if (hdd_is_ssr_required())
14414 {
14415 /* WDI timeout had happened during load, so SSR is needed here */
14416 subsystem_restart("wcnss");
14417 msleep(5000);
14418 }
14419 hdd_set_ssr_required (VOS_FALSE);
14420
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -080014421 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -070014422
14423success:
14424 EXIT();
14425 return 0;
14426}
14427
14428/**---------------------------------------------------------------------------
14429
Jeff Johnson32d95a32012-09-10 13:15:23 -070014430 \brief hdd_driver_init() - Core Driver Init Function
Jeff Johnson295189b2012-06-20 16:38:30 -070014431
Jeff Johnson32d95a32012-09-10 13:15:23 -070014432 This is the driver entry point - called in different timeline depending
14433 on whether the driver is statically or dynamically linked
Jeff Johnson295189b2012-06-20 16:38:30 -070014434
14435 \param - None
14436
14437 \return - 0 for success, non zero for failure
14438
14439 --------------------------------------------------------------------------*/
Jeff Johnson32d95a32012-09-10 13:15:23 -070014440static int hdd_driver_init( void)
Jeff Johnson295189b2012-06-20 16:38:30 -070014441{
14442 VOS_STATUS status;
14443 v_CONTEXT_t pVosContext = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070014444 struct device *dev = NULL;
14445 int ret_status = 0;
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -070014446#ifdef HAVE_WCNSS_CAL_DOWNLOAD
14447 int max_retries = 0;
14448#endif
Siddharth Bhalc7e79b62014-10-10 22:37:38 +053014449#ifdef HAVE_CBC_DONE
14450 int max_cbc_retries = 0;
14451#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070014452
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +053014453#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
14454 wlan_logging_sock_init_svc();
14455#endif
14456
Jeff Johnson295189b2012-06-20 16:38:30 -070014457 ENTER();
14458
Sushant Kaushik83392fa2015-05-05 17:44:40 +053014459 vos_wake_lock_init(&wlan_wake_lock, "wlan");
Jeff Johnson295189b2012-06-20 16:38:30 -070014460
14461 pr_info("%s: loading driver v%s\n", WLAN_MODULE_NAME,
14462 QWLAN_VERSIONSTR TIMER_MANAGER_STR MEMORY_DEBUG_STR);
14463
Jeff Johnson295189b2012-06-20 16:38:30 -070014464#ifdef ANI_BUS_TYPE_PCI
14465
14466 dev = wcnss_wlan_get_device();
14467
14468#endif // ANI_BUS_TYPE_PCI
14469
14470#ifdef ANI_BUS_TYPE_PLATFORM
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -070014471
14472#ifdef HAVE_WCNSS_CAL_DOWNLOAD
14473 /* wait until WCNSS driver downloads NV */
Ravi Kumar Bokka7a139e62016-11-17 21:32:55 +053014474 while (!wcnss_device_ready() && 10 >= ++max_retries) {
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -070014475 msleep(1000);
14476 }
Siddharth Bhalc7e79b62014-10-10 22:37:38 +053014477
Ravi Kumar Bokka7a139e62016-11-17 21:32:55 +053014478 if (max_retries >= 10) {
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -070014479 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: WCNSS driver not ready", __func__);
Sushant Kaushik83392fa2015-05-05 17:44:40 +053014480 vos_wake_lock_destroy(&wlan_wake_lock);
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +053014481#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
14482 wlan_logging_sock_deinit_svc();
14483#endif
14484
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -070014485 return -ENODEV;
14486 }
14487#endif
14488
Siddharth Bhalc7e79b62014-10-10 22:37:38 +053014489#ifdef HAVE_CBC_DONE
14490 while (!wcnss_cbc_complete() && 10 >= ++max_cbc_retries) {
14491 msleep(1000);
14492 }
14493 if (max_cbc_retries >= 10) {
14494 hddLog(VOS_TRACE_LEVEL_FATAL, "%s:CBC not completed", __func__);
14495 }
14496#endif
14497
Jeff Johnson295189b2012-06-20 16:38:30 -070014498 dev = wcnss_wlan_get_device();
14499#endif // ANI_BUS_TYPE_PLATFORM
14500
14501
14502 do {
14503 if (NULL == dev) {
14504 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: WLAN device not found!!",__func__);
14505 ret_status = -1;
14506 break;
14507 }
14508
Jeff Johnson295189b2012-06-20 16:38:30 -070014509#ifdef TIMER_MANAGER
14510 vos_timer_manager_init();
14511#endif
14512
14513 /* Preopen VOSS so that it is ready to start at least SAL */
14514 status = vos_preOpen(&pVosContext);
14515
14516 if (!VOS_IS_STATUS_SUCCESS(status))
14517 {
14518 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Failed to preOpen VOSS", __func__);
14519 ret_status = -1;
14520 break;
14521 }
14522
Sushant Kaushik02beb352015-06-04 15:15:01 +053014523 hddTraceInit();
Padma, Santhosh Kumar9093b202015-07-21 15:37:38 +053014524 hdd_register_debug_callback();
14525
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070014526#ifndef MODULE
14527 /* For statically linked driver, call hdd_set_conparam to update curr_con_mode
14528 */
14529 hdd_set_conparam((v_UINT_t)con_mode);
14530#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070014531
14532 // Call our main init function
Jeff Johnsonbc676b42013-02-14 16:04:08 -080014533 if (hdd_wlan_startup(dev))
14534 {
Jeff Johnson295189b2012-06-20 16:38:30 -070014535 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: WLAN Driver Initialization failed",
Jeff Johnsonbc676b42013-02-14 16:04:08 -080014536 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070014537 vos_preClose( &pVosContext );
14538 ret_status = -1;
14539 break;
14540 }
14541
Jeff Johnson295189b2012-06-20 16:38:30 -070014542 } while (0);
14543
14544 if (0 != ret_status)
14545 {
Jeff Johnson295189b2012-06-20 16:38:30 -070014546#ifdef TIMER_MANAGER
14547 vos_timer_exit();
14548#endif
14549#ifdef MEMORY_DEBUG
14550 vos_mem_exit();
14551#endif
Sushant Kaushik83392fa2015-05-05 17:44:40 +053014552 vos_wake_lock_destroy(&wlan_wake_lock);
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +053014553#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
14554 wlan_logging_sock_deinit_svc();
14555#endif
14556
Jeff Johnson295189b2012-06-20 16:38:30 -070014557 pr_err("%s: driver load failure\n", WLAN_MODULE_NAME);
14558 }
14559 else
14560 {
14561 //Send WLAN UP indication to Nlink Service
14562 send_btc_nlink_msg(WLAN_MODULE_UP_IND, 0);
14563
14564 pr_info("%s: driver loaded\n", WLAN_MODULE_NAME);
Jeff Johnson295189b2012-06-20 16:38:30 -070014565 }
14566
14567 EXIT();
14568
14569 return ret_status;
14570}
14571
Jeff Johnson32d95a32012-09-10 13:15:23 -070014572/**---------------------------------------------------------------------------
14573
14574 \brief hdd_module_init() - Init Function
14575
14576 This is the driver entry point (invoked when module is loaded using insmod)
14577
14578 \param - None
14579
14580 \return - 0 for success, non zero for failure
14581
14582 --------------------------------------------------------------------------*/
14583#ifdef MODULE
14584static int __init hdd_module_init ( void)
14585{
14586 return hdd_driver_init();
14587}
Jeff Johnson32d95a32012-09-10 13:15:23 -070014588#else /* #ifdef MODULE */
14589static int __init hdd_module_init ( void)
14590{
14591 /* Driver initialization is delayed to fwpath_changed_handler */
14592 return 0;
14593}
Jeff Johnson32d95a32012-09-10 13:15:23 -070014594#endif /* #ifdef MODULE */
14595
Jeff Johnson295189b2012-06-20 16:38:30 -070014596
14597/**---------------------------------------------------------------------------
14598
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070014599 \brief hdd_driver_exit() - Exit function
Jeff Johnson295189b2012-06-20 16:38:30 -070014600
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070014601 This is the driver exit point (invoked when module is unloaded using rmmod
14602 or con_mode was changed by userspace)
Jeff Johnson295189b2012-06-20 16:38:30 -070014603
14604 \param - None
14605
14606 \return - None
14607
14608 --------------------------------------------------------------------------*/
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070014609static void hdd_driver_exit(void)
Jeff Johnson295189b2012-06-20 16:38:30 -070014610{
14611 hdd_context_t *pHddCtx = NULL;
14612 v_CONTEXT_t pVosContext = NULL;
Agarwal Ashish5e414792014-06-08 15:25:23 +053014613 v_REGDOMAIN_t regId;
Arun Kumar Khandavallie0b046d2014-03-01 21:54:25 +053014614 unsigned long rc = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070014615
14616 pr_info("%s: unloading driver v%s\n", WLAN_MODULE_NAME, QWLAN_VERSIONSTR);
14617
14618 //Get the global vos context
14619 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
14620
14621 if(!pVosContext)
14622 {
14623 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Global VOS context is Null", __func__);
14624 goto done;
14625 }
14626
14627 //Get the HDD context.
14628 pHddCtx = (hdd_context_t *)vos_get_context(VOS_MODULE_ID_HDD, pVosContext );
14629
14630 if(!pHddCtx)
14631 {
14632 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: module exit called before probe",__func__);
14633 }
Katya Nigame7b69a82015-04-28 15:24:06 +053014634 else if (VOS_MONITOR_MODE == hdd_get_conparam())
14635 {
14636 hddLog(VOS_TRACE_LEVEL_INFO,"%s: MONITOR MODE",__func__);
14637 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_UNLOAD_IN_PROGRESS;
14638 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, TRUE);
14639 hdd_wlan_exit(pHddCtx);
14640 vos_preClose( &pVosContext );
14641 goto done;
14642 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014643 else
14644 {
Siddharth Bhal2e5871b2015-03-24 16:20:51 +053014645 /* We wait for active entry threads to exit from driver
14646 * by waiting until rtnl_lock is available.
14647 */
14648 rtnl_lock();
14649 rtnl_unlock();
14650
Siddharth Bhal3c29dca2015-02-19 00:41:40 +053014651 INIT_COMPLETION(pHddCtx->ssr_comp_var);
14652 if ((pHddCtx->isLogpInProgress) && (FALSE ==
14653 vos_is_wlan_in_badState(VOS_MODULE_ID_HDD, NULL)))
14654 {
Siddharth Bhala204f572015-01-17 02:03:36 +053014655 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Siddharth Bhal3c29dca2015-02-19 00:41:40 +053014656 "%s:SSR in Progress; block rmmod !!!", __func__);
Siddharth Bhala204f572015-01-17 02:03:36 +053014657 rc = wait_for_completion_timeout(&pHddCtx->ssr_comp_var,
14658 msecs_to_jiffies(30000));
14659 if(!rc)
14660 {
14661 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
14662 "%s:SSR timedout, fatal error", __func__);
14663 VOS_BUG(0);
14664 }
14665 }
14666
Siddharth Bhal3c29dca2015-02-19 00:41:40 +053014667 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_UNLOAD_IN_PROGRESS;
14668 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, TRUE);
Jeff Johnson295189b2012-06-20 16:38:30 -070014669
c_hpothu8adb97b2014-12-08 19:38:20 +053014670 /* Driver Need to send country code 00 in below condition
14671 * 1) If gCountryCodePriority is set to 1; and last country
14672 * code set is through 11d. This needs to be done in case
14673 * when NV country code is 00.
14674 * This Needs to be done as when kernel store last country
14675 * code and if stored country code is not through 11d,
14676 * in sme_HandleChangeCountryCodeByUser we will disable 11d
14677 * in next load/unload as soon as we get any country through
14678 * 11d. In sme_HandleChangeCountryCodeByUser
14679 * pMsg->countryCode will be last countryCode and
14680 * pMac->scan.countryCode11d will be country through 11d so
14681 * due to mismatch driver will disable 11d.
14682 *
14683 */
Agarwal Ashish8db39882014-07-30 21:56:07 +053014684
c_hpothu8adb97b2014-12-08 19:38:20 +053014685 if ((eANI_BOOLEAN_TRUE == sme_Is11dCountrycode(pHddCtx->hHal) &&
Agarwal Ashish8dcd2862014-07-25 11:58:52 +053014686 pHddCtx->cfg_ini->fSupplicantCountryCodeHasPriority &&
Abhishek Singh2a705962014-10-30 14:47:28 +053014687 sme_Is11dSupported(pHddCtx->hHal)))
c_hpothu8adb97b2014-12-08 19:38:20 +053014688 {
14689 hddLog(VOS_TRACE_LEVEL_INFO,
Agarwal Ashish8dcd2862014-07-25 11:58:52 +053014690 FL("CountryCode 00 is being set while unloading driver"));
c_hpothu8adb97b2014-12-08 19:38:20 +053014691 vos_nv_getRegDomainFromCountryCode(&regId , "00", COUNTRY_USER);
14692 }
Agarwal Ashish5e414792014-06-08 15:25:23 +053014693
c_hpothu8adb97b2014-12-08 19:38:20 +053014694 //Do all the cleanup before deregistering the driver
14695 hdd_wlan_exit(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -070014696 }
14697
Jeff Johnson295189b2012-06-20 16:38:30 -070014698 vos_preClose( &pVosContext );
14699
14700#ifdef TIMER_MANAGER
14701 vos_timer_exit();
14702#endif
14703#ifdef MEMORY_DEBUG
14704 vos_mem_exit();
14705#endif
14706
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +053014707#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
14708 wlan_logging_sock_deinit_svc();
14709#endif
14710
Jeff Johnson295189b2012-06-20 16:38:30 -070014711done:
Sushant Kaushik83392fa2015-05-05 17:44:40 +053014712 vos_wake_lock_destroy(&wlan_wake_lock);
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +053014713
Jeff Johnson295189b2012-06-20 16:38:30 -070014714 pr_info("%s: driver unloaded\n", WLAN_MODULE_NAME);
14715}
14716
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070014717/**---------------------------------------------------------------------------
14718
14719 \brief hdd_module_exit() - Exit function
14720
14721 This is the driver exit point (invoked when module is unloaded using rmmod)
14722
14723 \param - None
14724
14725 \return - None
14726
14727 --------------------------------------------------------------------------*/
14728static void __exit hdd_module_exit(void)
14729{
14730 hdd_driver_exit();
14731}
14732
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070014733#ifdef MODULE
14734static int fwpath_changed_handler(const char *kmessage,
Ashish Kumar Dhanotiyafb3fd972018-04-30 12:46:52 +053014735 const struct kernel_param *kp)
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070014736{
Jeff Johnson76052702013-04-16 13:55:05 -070014737 return param_set_copystring(kmessage, kp);
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070014738}
14739
14740static int con_mode_handler(const char *kmessage,
Ashish Kumar Dhanotiyafb3fd972018-04-30 12:46:52 +053014741 const struct kernel_param *kp)
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070014742{
Madan Mohan Koyyalamudif2f8d8b2012-10-11 17:06:59 -070014743 return param_set_int(kmessage, kp);
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070014744}
14745#else /* #ifdef MODULE */
14746/**---------------------------------------------------------------------------
14747
Jeff Johnson76052702013-04-16 13:55:05 -070014748 \brief kickstart_driver
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070014749
Jeff Johnson76052702013-04-16 13:55:05 -070014750 This is the driver entry point
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070014751 - delayed driver initialization when driver is statically linked
Jeff Johnson76052702013-04-16 13:55:05 -070014752 - invoked when module parameter fwpath is modified from userspace to signal
14753 initializing the WLAN driver or when con_mode is modified from userspace
14754 to signal a switch in operating mode
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070014755
14756 \return - 0 for success, non zero for failure
14757
14758 --------------------------------------------------------------------------*/
Jeff Johnson76052702013-04-16 13:55:05 -070014759static int kickstart_driver(void)
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070014760{
Madan Mohan Koyyalamudi62e60052012-10-05 14:27:22 -070014761 int ret_status;
14762
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070014763 if (!wlan_hdd_inited) {
Madan Mohan Koyyalamudi62e60052012-10-05 14:27:22 -070014764 ret_status = hdd_driver_init();
14765 wlan_hdd_inited = ret_status ? 0 : 1;
14766 return ret_status;
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070014767 }
14768
14769 hdd_driver_exit();
Jeff Johnson76052702013-04-16 13:55:05 -070014770
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070014771 msleep(200);
Jeff Johnson76052702013-04-16 13:55:05 -070014772
Madan Mohan Koyyalamudi62e60052012-10-05 14:27:22 -070014773 ret_status = hdd_driver_init();
14774 wlan_hdd_inited = ret_status ? 0 : 1;
14775 return ret_status;
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070014776}
14777
Jeff Johnson295189b2012-06-20 16:38:30 -070014778/**---------------------------------------------------------------------------
14779
Jeff Johnson76052702013-04-16 13:55:05 -070014780 \brief fwpath_changed_handler() - Handler Function
14781
14782 Handle changes to the fwpath parameter
14783
14784 \return - 0 for success, non zero for failure
14785
14786 --------------------------------------------------------------------------*/
14787static int fwpath_changed_handler(const char *kmessage,
Ashish Kumar Dhanotiyafb3fd972018-04-30 12:46:52 +053014788 const struct kernel_param *kp)
Jeff Johnson76052702013-04-16 13:55:05 -070014789{
14790 int ret;
14791
14792 ret = param_set_copystring(kmessage, kp);
14793 if (0 == ret)
14794 ret = kickstart_driver();
14795 return ret;
14796}
14797
14798/**---------------------------------------------------------------------------
14799
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070014800 \brief con_mode_handler() -
14801
14802 Handler function for module param con_mode when it is changed by userspace
14803 Dynamically linked - do nothing
14804 Statically linked - exit and init driver, as in rmmod and insmod
14805
Jeff Johnson76052702013-04-16 13:55:05 -070014806 \param -
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070014807
Jeff Johnson76052702013-04-16 13:55:05 -070014808 \return -
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070014809
14810 --------------------------------------------------------------------------*/
Ashish Kumar Dhanotiyafb3fd972018-04-30 12:46:52 +053014811static int con_mode_handler(const char *kmessage,
14812 const struct kernel_param *kp)
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070014813{
Jeff Johnson76052702013-04-16 13:55:05 -070014814 int ret;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070014815
Jeff Johnson76052702013-04-16 13:55:05 -070014816 ret = param_set_int(kmessage, kp);
14817 if (0 == ret)
14818 ret = kickstart_driver();
14819 return ret;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070014820}
14821#endif /* #ifdef MODULE */
14822
14823/**---------------------------------------------------------------------------
14824
Jeff Johnson295189b2012-06-20 16:38:30 -070014825 \brief hdd_get_conparam() -
14826
14827 This is the driver exit point (invoked when module is unloaded using rmmod)
14828
14829 \param - None
14830
14831 \return - tVOS_CON_MODE
14832
14833 --------------------------------------------------------------------------*/
14834tVOS_CON_MODE hdd_get_conparam ( void )
14835{
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070014836#ifdef MODULE
Jeff Johnson295189b2012-06-20 16:38:30 -070014837 return (tVOS_CON_MODE)con_mode;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070014838#else
14839 return (tVOS_CON_MODE)curr_con_mode;
14840#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070014841}
14842void hdd_set_conparam ( v_UINT_t newParam )
14843{
14844 con_mode = newParam;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070014845#ifndef MODULE
14846 curr_con_mode = con_mode;
14847#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070014848}
14849/**---------------------------------------------------------------------------
14850
14851 \brief hdd_softap_sta_deauth() - function
14852
14853 This to take counter measure to handle deauth req from HDD
14854
14855 \param - pAdapter - Pointer to the HDD
14856
14857 \param - enable - boolean value
14858
14859 \return - None
14860
14861 --------------------------------------------------------------------------*/
14862
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053014863VOS_STATUS hdd_softap_sta_deauth(hdd_adapter_t *pAdapter,
14864 struct tagCsrDelStaParams *pDelStaParams)
Jeff Johnson295189b2012-06-20 16:38:30 -070014865{
Jeff Johnson295189b2012-06-20 16:38:30 -070014866 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080014867 VOS_STATUS vosStatus = VOS_STATUS_E_FAULT;
Hanumanth Reddy Pothula57323632017-12-06 17:55:09 +053014868 struct hdd_cache_sta_info *cache_sta_info;
14869 ptSapContext pSapCtx = VOS_GET_SAP_CB(pVosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -070014870
14871 ENTER();
14872
Jeff Johnsonc135a9a2017-09-19 08:37:24 -070014873 hddLog(LOG1, "hdd_softap_sta_deauth:(%pK, false)",
Rajesh Chauhan18488fc2013-08-22 10:15:03 -070014874 (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -070014875
Hanumanth Reddy Pothula57323632017-12-06 17:55:09 +053014876 if (!pSapCtx) {
14877 hddLog(LOGE, "sap context is NULL");
14878 return vosStatus;
14879 }
14880
14881 cache_sta_info = hdd_get_cache_stainfo(pSapCtx->cache_sta_info,
14882 pDelStaParams->peerMacAddr);
14883 if (cache_sta_info) {
14884 cache_sta_info->reason_code = pDelStaParams->reason_code;
14885 cache_sta_info->rx_rate =
14886 wlan_tl_get_sta_rx_rate(pVosContext, cache_sta_info->ucSTAId);
14887 WLANTL_GetSAPStaRSSi(pVosContext, cache_sta_info->ucSTAId,
14888 &cache_sta_info->rssi);
14889 }
14890
Jeff Johnson295189b2012-06-20 16:38:30 -070014891 //Ignore request to deauth bcmc station
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053014892 if (pDelStaParams->peerMacAddr[0] & 0x1)
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080014893 return vosStatus;
Jeff Johnson295189b2012-06-20 16:38:30 -070014894
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053014895 vosStatus = WLANSAP_DeauthSta(pVosContext, pDelStaParams);
Jeff Johnson295189b2012-06-20 16:38:30 -070014896
14897 EXIT();
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080014898 return vosStatus;
Jeff Johnson295189b2012-06-20 16:38:30 -070014899}
14900
14901/**---------------------------------------------------------------------------
14902
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +053014903 \brief hdd_del_all_sta() - function
14904
14905 This function removes all the stations associated on stopping AP/P2P GO.
14906
14907 \param - pAdapter - Pointer to the HDD
14908
14909 \return - None
14910
14911 --------------------------------------------------------------------------*/
14912
14913int hdd_del_all_sta(hdd_adapter_t *pAdapter)
14914{
14915 v_U16_t i;
14916 VOS_STATUS vos_status;
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053014917 v_CONTEXT_t pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
14918 ptSapContext pSapCtx = NULL;
14919 pSapCtx = VOS_GET_SAP_CB(pVosContext);
14920 if(pSapCtx == NULL){
14921 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14922 FL("psapCtx is NULL"));
14923 return 1;
14924 }
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +053014925 ENTER();
14926
14927 hddLog(VOS_TRACE_LEVEL_INFO,
14928 "%s: Delete all STAs associated.",__func__);
14929 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
14930 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
14931 )
14932 {
14933 for(i = 0; i < WLAN_MAX_STA_COUNT; i++)
14934 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053014935 if ((pSapCtx->aStaInfo[i].isUsed) &&
14936 (!pSapCtx->aStaInfo[i].isDeauthInProgress))
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +053014937 {
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053014938 struct tagCsrDelStaParams delStaParams;
14939
14940 WLANSAP_PopulateDelStaParams(
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053014941 pSapCtx->aStaInfo[i].macAddrSTA.bytes,
Sushant Kaushik4cd28f62014-12-26 14:23:50 +053014942 eSIR_MAC_DEAUTH_LEAVING_BSS_REASON,
14943 SIR_MAC_MGMT_DEAUTH >> 4,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053014944 &delStaParams);
14945 vos_status = hdd_softap_sta_deauth(pAdapter, &delStaParams);
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +053014946 if (VOS_IS_STATUS_SUCCESS(vos_status))
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053014947 pSapCtx->aStaInfo[i].isDeauthInProgress = TRUE;
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +053014948 }
14949 }
14950 }
14951
14952 EXIT();
14953 return 0;
14954}
14955
14956/**---------------------------------------------------------------------------
14957
Jeff Johnson295189b2012-06-20 16:38:30 -070014958 \brief hdd_softap_sta_disassoc() - function
14959
14960 This to take counter measure to handle deauth req from HDD
14961
14962 \param - pAdapter - Pointer to the HDD
14963
14964 \param - enable - boolean value
14965
14966 \return - None
14967
14968 --------------------------------------------------------------------------*/
14969
14970void hdd_softap_sta_disassoc(hdd_adapter_t *pAdapter,v_U8_t *pDestMacAddress)
14971{
Hanumanth Reddy Pothula57323632017-12-06 17:55:09 +053014972 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
14973 struct hdd_cache_sta_info *cache_sta_info;
14974 ptSapContext pSapCtx = VOS_GET_SAP_CB(pVosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -070014975
14976 ENTER();
14977
Jeff Johnsonc135a9a2017-09-19 08:37:24 -070014978 hddLog( LOGE, "hdd_softap_sta_disassoc:(%pK, false)", (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -070014979
Hanumanth Reddy Pothula57323632017-12-06 17:55:09 +053014980 if (!pSapCtx) {
14981 hddLog(LOGE, "sap context is NULL");
14982 return ;
14983 }
14984
Jeff Johnson295189b2012-06-20 16:38:30 -070014985 //Ignore request to disassoc bcmc station
14986 if( pDestMacAddress[0] & 0x1 )
14987 return;
14988
Hanumanth Reddy Pothula57323632017-12-06 17:55:09 +053014989 cache_sta_info = hdd_get_cache_stainfo(pSapCtx->cache_sta_info,
14990 pDestMacAddress);
14991 if (cache_sta_info) {
14992 cache_sta_info->reason_code = eSIR_MAC_DEAUTH_LEAVING_BSS_REASON;
14993 cache_sta_info->rx_rate =
14994 wlan_tl_get_sta_rx_rate(pVosContext, cache_sta_info->ucSTAId);
14995 WLANTL_GetSAPStaRSSi(pVosContext, cache_sta_info->ucSTAId,
14996 &cache_sta_info->rssi);
14997 }
14998
Jeff Johnson295189b2012-06-20 16:38:30 -070014999 WLANSAP_DisassocSta(pVosContext,pDestMacAddress);
15000}
15001
15002void hdd_softap_tkip_mic_fail_counter_measure(hdd_adapter_t *pAdapter,v_BOOL_t enable)
15003{
15004 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
15005
15006 ENTER();
15007
Jeff Johnsonc135a9a2017-09-19 08:37:24 -070015008 hddLog( LOGE, "hdd_softap_tkip_mic_fail_counter_measure:(%pK, false)", (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -070015009
15010 WLANSAP_SetCounterMeasure(pVosContext, (v_BOOL_t)enable);
15011}
15012
Jeff Johnson295189b2012-06-20 16:38:30 -070015013/**---------------------------------------------------------------------------
15014 *
15015 * \brief hdd_get__concurrency_mode() -
15016 *
15017 *
15018 * \param - None
15019 *
15020 * \return - CONCURRENCY MODE
15021 *
15022 * --------------------------------------------------------------------------*/
15023tVOS_CONCURRENCY_MODE hdd_get_concurrency_mode ( void )
15024{
15025 v_CONTEXT_t pVosContext = vos_get_global_context( VOS_MODULE_ID_HDD, NULL );
15026 hdd_context_t *pHddCtx;
15027
15028 if (NULL != pVosContext)
15029 {
15030 pHddCtx = vos_get_context( VOS_MODULE_ID_HDD, pVosContext);
15031 if (NULL != pHddCtx)
15032 {
15033 return (tVOS_CONCURRENCY_MODE)pHddCtx->concurrency_mode;
15034 }
15035 }
15036
15037 /* we are in an invalid state :( */
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070015038 hddLog(LOGE, "%s: Invalid context", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070015039 return VOS_STA;
15040}
Sushant Kaushikabb7ee62014-07-18 16:20:12 +053015041v_BOOL_t
15042wlan_hdd_is_GO_power_collapse_allowed (hdd_context_t* pHddCtx)
15043{
15044 hdd_adapter_t *pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070015045
Sushant Kaushikabb7ee62014-07-18 16:20:12 +053015046 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_GO);
15047 if (pAdapter == NULL)
15048 {
15049 hddLog(VOS_TRACE_LEVEL_INFO,
15050 FL("GO doesn't exist"));
15051 return TRUE;
15052 }
15053 if (test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
15054 {
15055 hddLog(VOS_TRACE_LEVEL_INFO,
15056 FL("GO started"));
15057 return TRUE;
15058 }
15059 else
15060 /* wait till GO changes its interface to p2p device */
15061 hddLog(VOS_TRACE_LEVEL_INFO,
15062 FL("Del_bss called, avoid apps suspend"));
15063 return FALSE;
15064
15065}
Jeff Johnson295189b2012-06-20 16:38:30 -070015066/* Decide whether to allow/not the apps power collapse.
15067 * Allow apps power collapse if we are in connected state.
15068 * if not, allow only if we are in IMPS */
15069v_BOOL_t hdd_is_apps_power_collapse_allowed(hdd_context_t* pHddCtx)
15070{
15071 tPmcState pmcState = pmcGetPmcState(pHddCtx->hHal);
Srikant Kuppafef66a72013-01-30 17:32:44 -080015072 tANI_BOOLEAN scanRspPending = csrNeighborRoamScanRspPending(pHddCtx->hHal);
Srinivas Girigowdaa553c462013-03-07 19:42:52 -080015073 tANI_BOOLEAN inMiddleOfRoaming = csrNeighborMiddleOfRoaming(pHddCtx->hHal);
Jeff Johnson295189b2012-06-20 16:38:30 -070015074 hdd_config_t *pConfig = pHddCtx->cfg_ini;
15075 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
15076 hdd_adapter_t *pAdapter = NULL;
15077 VOS_STATUS status;
Yathish9f22e662012-12-10 14:21:35 -080015078 tVOS_CONCURRENCY_MODE concurrent_state = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070015079
Jeff Johnson295189b2012-06-20 16:38:30 -070015080 if (VOS_STA_SAP_MODE == hdd_get_conparam())
15081 return TRUE;
Jeff Johnson295189b2012-06-20 16:38:30 -070015082
Yathish9f22e662012-12-10 14:21:35 -080015083 concurrent_state = hdd_get_concurrency_mode();
15084
Sushant Kaushikabb7ee62014-07-18 16:20:12 +053015085 if ((concurrent_state == (VOS_STA | VOS_P2P_GO)) &&
15086 !(wlan_hdd_is_GO_power_collapse_allowed(pHddCtx)))
15087 return FALSE;
Yathish9f22e662012-12-10 14:21:35 -080015088#ifdef WLAN_ACTIVEMODE_OFFLOAD_FEATURE
Sushant Kaushikabb7ee62014-07-18 16:20:12 +053015089
Yathish9f22e662012-12-10 14:21:35 -080015090 if(((concurrent_state == (VOS_STA | VOS_P2P_CLIENT)) ||
Sushant Kaushikabb7ee62014-07-18 16:20:12 +053015091 (concurrent_state == (VOS_STA | VOS_P2P_GO)))&&
Yathish9f22e662012-12-10 14:21:35 -080015092 (IS_ACTIVEMODE_OFFLOAD_FEATURE_ENABLE))
15093 return TRUE;
15094#endif
15095
Jeff Johnson295189b2012-06-20 16:38:30 -070015096 /*loop through all adapters. TBD fix for Concurrency */
15097 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
15098 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
15099 {
15100 pAdapter = pAdapterNode->pAdapter;
15101 if ( (WLAN_HDD_INFRA_STATION == pAdapter->device_mode)
15102 || (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
15103 {
Srikant Kuppafef66a72013-01-30 17:32:44 -080015104 if (((pConfig->fIsImpsEnabled || pConfig->fIsBmpsEnabled)
c_hpothu4e8faac2014-05-16 17:38:44 +053015105 && (pmcState != IMPS && pmcState != BMPS && pmcState != UAPSD
c_hpothu1c6957d2015-01-06 18:19:47 +053015106 && pmcState != STOPPED && pmcState != STANDBY &&
15107 pmcState != WOWL)) ||
Srinivas Girigowdaa553c462013-03-07 19:42:52 -080015108 (eANI_BOOLEAN_TRUE == scanRspPending) ||
15109 (eANI_BOOLEAN_TRUE == inMiddleOfRoaming))
Jeff Johnson295189b2012-06-20 16:38:30 -070015110 {
Mukul Sharma4be88422015-03-09 20:29:07 +053015111 if(pmcState == FULL_POWER &&
15112 sme_IsCoexScoIndicationSet(pHddCtx->hHal))
15113 {
15114 /*
15115 * When SCO indication comes from Coex module , host will
15116 * enter in to full power mode, but this should not prevent
15117 * apps processor power collapse.
15118 */
15119 hddLog(LOG1,
15120 FL("Allow apps power collapse"
15121 "even when sco indication is set"));
15122 return TRUE;
15123 }
Srikant Kuppafef66a72013-01-30 17:32:44 -080015124 hddLog( LOGE, "%s: do not allow APPS power collapse-"
Deepthi Gowri03a979f2016-11-03 15:20:19 +053015125 "pmcState = %d scanRspPending = %d "
15126 "inMiddleOfRoaming = %d connected = %d",
15127 __func__, pmcState, scanRspPending,
15128 inMiddleOfRoaming, hdd_connIsConnected(
15129 WLAN_HDD_GET_STATION_CTX_PTR( pAdapter )));
15130 wlan_hdd_get_tdls_stats(pAdapter);
15131 return FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070015132 }
15133 }
15134 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
15135 pAdapterNode = pNext;
15136 }
15137 return TRUE;
15138}
15139
Madan Mohan Koyyalamudic72a4d62012-11-08 14:59:34 -080015140/* Decides whether to send suspend notification to Riva
15141 * if any adapter is in BMPS; then it is required */
15142v_BOOL_t hdd_is_suspend_notify_allowed(hdd_context_t* pHddCtx)
15143{
15144 tPmcState pmcState = pmcGetPmcState(pHddCtx->hHal);
15145 hdd_config_t *pConfig = pHddCtx->cfg_ini;
15146
15147 if (pConfig->fIsBmpsEnabled && (pmcState == BMPS))
15148 {
15149 return TRUE;
15150 }
15151 return FALSE;
15152}
15153
Jeff Johnson295189b2012-06-20 16:38:30 -070015154void wlan_hdd_set_concurrency_mode(hdd_context_t *pHddCtx, tVOS_CON_MODE mode)
15155{
15156 switch(mode)
15157 {
Chilam Ngc4244af2013-04-01 15:37:32 -070015158 case VOS_STA_MODE:
15159 case VOS_P2P_CLIENT_MODE:
15160 case VOS_P2P_GO_MODE:
15161 case VOS_STA_SAP_MODE:
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +053015162 case VOS_MONITOR_MODE:
Jeff Johnsone7245742012-09-05 17:12:55 -070015163 pHddCtx->concurrency_mode |= (1 << mode);
Agarwal Ashish51325b52014-06-16 16:50:49 +053015164 pHddCtx->no_of_open_sessions[mode]++;
Jeff Johnson295189b2012-06-20 16:38:30 -070015165 break;
15166 default:
15167 break;
Jeff Johnson295189b2012-06-20 16:38:30 -070015168 }
Agarwal Ashish51325b52014-06-16 16:50:49 +053015169 hddLog(VOS_TRACE_LEVEL_INFO, FL("concurrency_mode = 0x%x "
15170 "Number of open sessions for mode %d = %d"),
15171 pHddCtx->concurrency_mode, mode,
15172 pHddCtx->no_of_open_sessions[mode]);
Jeff Johnson295189b2012-06-20 16:38:30 -070015173}
15174
15175
15176void wlan_hdd_clear_concurrency_mode(hdd_context_t *pHddCtx, tVOS_CON_MODE mode)
15177{
15178 switch(mode)
15179 {
Chilam Ngc4244af2013-04-01 15:37:32 -070015180 case VOS_STA_MODE:
15181 case VOS_P2P_CLIENT_MODE:
15182 case VOS_P2P_GO_MODE:
15183 case VOS_STA_SAP_MODE:
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +053015184 case VOS_MONITOR_MODE:
Agarwal Ashish51325b52014-06-16 16:50:49 +053015185 pHddCtx->no_of_open_sessions[mode]--;
15186 if (!(pHddCtx->no_of_open_sessions[mode]))
15187 pHddCtx->concurrency_mode &= (~(1 << mode));
Jeff Johnson295189b2012-06-20 16:38:30 -070015188 break;
15189 default:
15190 break;
15191 }
Agarwal Ashish51325b52014-06-16 16:50:49 +053015192 hddLog(VOS_TRACE_LEVEL_INFO, FL("concurrency_mode = 0x%x "
15193 "Number of open sessions for mode %d = %d"),
15194 pHddCtx->concurrency_mode, mode, pHddCtx->no_of_open_sessions[mode]);
15195
15196}
15197/**---------------------------------------------------------------------------
15198 *
15199 * \brief wlan_hdd_incr_active_session()
15200 *
15201 * This function increments the number of active sessions
15202 * maintained per device mode
15203 * Incase of STA/P2P CLI/IBSS upon connection indication it is incremented
15204 * Incase of SAP/P2P GO upon bss start it is incremented
15205 *
15206 * \param pHddCtx - HDD Context
15207 * \param mode - device mode
15208 *
15209 * \return - None
15210 *
15211 * --------------------------------------------------------------------------*/
15212void wlan_hdd_incr_active_session(hdd_context_t *pHddCtx, tVOS_CON_MODE mode)
15213{
15214 switch (mode) {
15215 case VOS_STA_MODE:
15216 case VOS_P2P_CLIENT_MODE:
15217 case VOS_P2P_GO_MODE:
15218 case VOS_STA_SAP_MODE:
15219 pHddCtx->no_of_active_sessions[mode]++;
15220 break;
15221 default:
15222 hddLog(VOS_TRACE_LEVEL_INFO, FL("Not Expected Mode %d"), mode);
15223 break;
15224 }
15225 hddLog(VOS_TRACE_LEVEL_INFO, FL("No.# of active sessions for mode %d = %d"),
15226 mode,
15227 pHddCtx->no_of_active_sessions[mode]);
15228}
15229
15230/**---------------------------------------------------------------------------
15231 *
15232 * \brief wlan_hdd_decr_active_session()
15233 *
15234 * This function decrements the number of active sessions
15235 * maintained per device mode
15236 * Incase of STA/P2P CLI/IBSS upon disconnection it is decremented
15237 * Incase of SAP/P2P GO upon bss stop it is decremented
15238 *
15239 * \param pHddCtx - HDD Context
15240 * \param mode - device mode
15241 *
15242 * \return - None
15243 *
15244 * --------------------------------------------------------------------------*/
15245void wlan_hdd_decr_active_session(hdd_context_t *pHddCtx, tVOS_CON_MODE mode)
15246{
Bhargav Shahd0715912015-10-01 18:17:37 +053015247
Agarwal Ashish51325b52014-06-16 16:50:49 +053015248 switch (mode) {
15249 case VOS_STA_MODE:
15250 case VOS_P2P_CLIENT_MODE:
15251 case VOS_P2P_GO_MODE:
15252 case VOS_STA_SAP_MODE:
Agarwal Ashish5325f522014-08-06 00:58:44 +053015253 if (pHddCtx->no_of_active_sessions[mode] > 0)
15254 pHddCtx->no_of_active_sessions[mode]--;
15255 else
15256 hddLog(VOS_TRACE_LEVEL_INFO, FL(" No.# of Active sessions"
15257 "is already Zero"));
Agarwal Ashish51325b52014-06-16 16:50:49 +053015258 break;
15259 default:
15260 hddLog(VOS_TRACE_LEVEL_INFO, FL("Not Expected Mode %d"), mode);
15261 break;
15262 }
15263 hddLog(VOS_TRACE_LEVEL_INFO, FL("No.# of active sessions for mode %d = %d"),
15264 mode,
15265 pHddCtx->no_of_active_sessions[mode]);
Jeff Johnson295189b2012-06-20 16:38:30 -070015266}
15267
Jeff Johnsone7245742012-09-05 17:12:55 -070015268/**---------------------------------------------------------------------------
15269 *
15270 * \brief wlan_hdd_restart_init
15271 *
15272 * This function initalizes restart timer/flag. An internal function.
15273 *
15274 * \param - pHddCtx
15275 *
15276 * \return - None
15277 *
15278 * --------------------------------------------------------------------------*/
15279
15280static void wlan_hdd_restart_init(hdd_context_t *pHddCtx)
15281{
15282 /* Initialize */
15283 pHddCtx->hdd_restart_retries = 0;
15284 atomic_set(&pHddCtx->isRestartInProgress, 0);
15285 vos_timer_init(&pHddCtx->hdd_restart_timer,
15286 VOS_TIMER_TYPE_SW,
15287 wlan_hdd_restart_timer_cb,
15288 pHddCtx);
15289}
15290/**---------------------------------------------------------------------------
15291 *
15292 * \brief wlan_hdd_restart_deinit
15293 *
15294 * This function cleans up the resources used. An internal function.
15295 *
15296 * \param - pHddCtx
15297 *
15298 * \return - None
15299 *
15300 * --------------------------------------------------------------------------*/
15301
15302static void wlan_hdd_restart_deinit(hdd_context_t* pHddCtx)
15303{
15304
15305 VOS_STATUS vos_status;
15306 /* Block any further calls */
15307 atomic_set(&pHddCtx->isRestartInProgress, 1);
15308 /* Cleanup */
15309 vos_status = vos_timer_stop( &pHddCtx->hdd_restart_timer );
15310 if (!VOS_IS_STATUS_SUCCESS(vos_status))
c_hpothu6ff1c3c2013-10-01 19:01:57 +053015311 hddLog(LOGE, FL("Failed to stop HDD restart timer"));
Jeff Johnsone7245742012-09-05 17:12:55 -070015312 vos_status = vos_timer_destroy(&pHddCtx->hdd_restart_timer);
15313 if (!VOS_IS_STATUS_SUCCESS(vos_status))
c_hpothu6ff1c3c2013-10-01 19:01:57 +053015314 hddLog(LOGE, FL("Failed to destroy HDD restart timer"));
Jeff Johnsone7245742012-09-05 17:12:55 -070015315
15316}
15317
15318/**---------------------------------------------------------------------------
15319 *
15320 * \brief wlan_hdd_framework_restart
15321 *
15322 * This function uses a cfg80211 API to start a framework initiated WLAN
15323 * driver module unload/load.
15324 *
15325 * Also this API keep retrying (WLAN_HDD_RESTART_RETRY_MAX_CNT).
15326 *
15327 *
15328 * \param - pHddCtx
15329 *
15330 * \return - VOS_STATUS_SUCCESS: Success
15331 * VOS_STATUS_E_EMPTY: Adapter is Empty
15332 * VOS_STATUS_E_NOMEM: No memory
15333
15334 * --------------------------------------------------------------------------*/
15335
15336static VOS_STATUS wlan_hdd_framework_restart(hdd_context_t *pHddCtx)
15337{
15338 VOS_STATUS status = VOS_STATUS_SUCCESS;
15339 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
Madan Mohan Koyyalamudifc19e442013-05-09 18:24:08 -070015340 int len = (sizeof (struct ieee80211_mgmt));
15341 struct ieee80211_mgmt *mgmt = NULL;
15342
15343 /* Prepare the DEAUTH managment frame with reason code */
15344 mgmt = kzalloc(len, GFP_KERNEL);
15345 if(mgmt == NULL)
15346 {
15347 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
15348 "%s: memory allocation failed (%d bytes)", __func__, len);
15349 return VOS_STATUS_E_NOMEM;
15350 }
15351 mgmt->u.deauth.reason_code = WLAN_REASON_DISASSOC_LOW_ACK;
Jeff Johnsone7245742012-09-05 17:12:55 -070015352
15353 /* Iterate over all adapters/devices */
15354 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
Hanumantha Reddy Pothulada0fe362015-02-27 18:37:03 +053015355 if ((NULL == pAdapterNode) || (VOS_STATUS_SUCCESS != status))
15356 {
15357 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnsonc135a9a2017-09-19 08:37:24 -070015358 FL("fail to get adapter: %pK %d"), pAdapterNode, status);
Hanumantha Reddy Pothulada0fe362015-02-27 18:37:03 +053015359 goto end;
15360 }
15361
Jeff Johnsone7245742012-09-05 17:12:55 -070015362 do
15363 {
Hanumantha Reddy Pothulada0fe362015-02-27 18:37:03 +053015364 if(pAdapterNode->pAdapter &&
15365 WLAN_HDD_ADAPTER_MAGIC == pAdapterNode->pAdapter->magic)
Jeff Johnsone7245742012-09-05 17:12:55 -070015366 {
15367 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
15368 "restarting the driver(intf:\'%s\' mode:%d :try %d)",
15369 pAdapterNode->pAdapter->dev->name,
15370 pAdapterNode->pAdapter->device_mode,
15371 pHddCtx->hdd_restart_retries + 1);
Madan Mohan Koyyalamudifc19e442013-05-09 18:24:08 -070015372 /*
15373 * CFG80211 event to restart the driver
15374 *
15375 * 'cfg80211_send_unprot_deauth' sends a
15376 * NL80211_CMD_UNPROT_DEAUTHENTICATE event to supplicant at any state
15377 * of SME(Linux Kernel) state machine.
15378 *
15379 * Reason code WLAN_REASON_DISASSOC_LOW_ACK is currently used to restart
15380 * the driver.
15381 *
15382 */
Abhishek Singh00b71972016-01-07 10:51:04 +053015383
Anand N Sunkade9adb1b2015-07-29 09:56:45 +053015384#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 11, 0))
15385 cfg80211_rx_unprot_mlme_mgmt(pAdapterNode->pAdapter->dev, (u_int8_t*)mgmt, len);
15386#else
Madan Mohan Koyyalamudifc19e442013-05-09 18:24:08 -070015387 cfg80211_send_unprot_deauth(pAdapterNode->pAdapter->dev, (u_int8_t*)mgmt, len );
Anand N Sunkade9adb1b2015-07-29 09:56:45 +053015388#endif
Jeff Johnsone7245742012-09-05 17:12:55 -070015389 }
15390 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
15391 pAdapterNode = pNext;
15392 } while((NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status));
15393
Hanumantha Reddy Pothulada0fe362015-02-27 18:37:03 +053015394 end:
Madan Mohan Koyyalamudifc19e442013-05-09 18:24:08 -070015395 /* Free the allocated management frame */
15396 kfree(mgmt);
15397
Jeff Johnsone7245742012-09-05 17:12:55 -070015398 /* Retry until we unload or reach max count */
15399 if(++pHddCtx->hdd_restart_retries < WLAN_HDD_RESTART_RETRY_MAX_CNT)
15400 vos_timer_start(&pHddCtx->hdd_restart_timer, WLAN_HDD_RESTART_RETRY_DELAY_MS);
15401
15402 return status;
15403
15404}
15405/**---------------------------------------------------------------------------
15406 *
15407 * \brief wlan_hdd_restart_timer_cb
15408 *
15409 * Restart timer callback. An internal function.
15410 *
15411 * \param - User data:
15412 *
15413 * \return - None
15414 *
15415 * --------------------------------------------------------------------------*/
15416
15417void wlan_hdd_restart_timer_cb(v_PVOID_t usrDataForCallback)
15418{
15419 hdd_context_t *pHddCtx = usrDataForCallback;
15420 wlan_hdd_framework_restart(pHddCtx);
15421 return;
15422
15423}
15424
15425
15426/**---------------------------------------------------------------------------
15427 *
15428 * \brief wlan_hdd_restart_driver
15429 *
15430 * This function sends an event to supplicant to restart the WLAN driver.
15431 *
15432 * This function is called from vos_wlanRestart.
15433 *
15434 * \param - pHddCtx
15435 *
15436 * \return - VOS_STATUS_SUCCESS: Success
15437 * VOS_STATUS_E_EMPTY: Adapter is Empty
15438 * VOS_STATUS_E_ALREADY: Request already in progress
15439
15440 * --------------------------------------------------------------------------*/
15441VOS_STATUS wlan_hdd_restart_driver(hdd_context_t *pHddCtx)
15442{
15443 VOS_STATUS status = VOS_STATUS_SUCCESS;
15444
15445 /* A tight check to make sure reentrancy */
15446 if(atomic_xchg(&pHddCtx->isRestartInProgress, 1))
15447 {
Mihir Shetefd528652014-06-23 19:07:50 +053015448 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnsone7245742012-09-05 17:12:55 -070015449 "%s: WLAN restart is already in progress", __func__);
15450
15451 return VOS_STATUS_E_ALREADY;
15452 }
Sameer Thalappil0c164f52013-03-28 15:27:56 -070015453 /* Send reset FIQ to WCNSS to invoke SSR. */
Madan Mohan Koyyalamudie388b342012-11-08 15:03:16 -080015454#ifdef HAVE_WCNSS_RESET_INTR
Siddharth Bhal864e7e82015-04-07 20:07:24 +053015455 wcnss_reset_fiq(TRUE);
Madan Mohan Koyyalamudibb8f0172012-09-28 15:36:06 -070015456#endif
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -070015457
Jeff Johnsone7245742012-09-05 17:12:55 -070015458 return status;
15459}
15460
Bhargav Shahd0715912015-10-01 18:17:37 +053015461/**
15462 * hdd_get_total_sessions() - provide total number of active sessions
15463 * @pHddCtx: Valid Global HDD context pointer
15464 *
15465 * This function iterates through pAdaptors and find the number of all active
15466 * sessions. This active sessions includes connected sta, p2p client and number
15467 * of client connected to sap/p2p go.
15468 *
15469 * Return: Total number of active sessions.
15470 */
15471v_U8_t hdd_get_total_sessions(hdd_context_t *pHddCtx)
15472{
15473 v_U8_t active_session = 0;
15474 hdd_station_ctx_t *pHddStaCtx;
15475 hdd_adapter_list_node_t *pAdapterNode, *pNext;
15476 hdd_adapter_t *pAdapter;
15477 VOS_STATUS status;
15478
15479 status = hdd_get_front_adapter(pHddCtx, &pAdapterNode);
15480 while (NULL != pAdapterNode && VOS_STATUS_SUCCESS == status) {
15481 pAdapter = pAdapterNode->pAdapter;
15482 switch (pAdapter->device_mode) {
15483 case VOS_STA_MODE:
15484 case VOS_P2P_CLIENT_MODE:
15485 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
15486 if(eConnectionState_Associated == pHddStaCtx->conn_info.connState)
15487 active_session += 1;
15488 break;
15489 case VOS_STA_SAP_MODE:
15490 case VOS_P2P_GO_MODE:
15491 active_session += hdd_softap_get_connected_sta(pAdapter);
15492 break;
15493 default:
15494 break;
15495 }
15496
15497 status = hdd_get_next_adapter(pHddCtx, pAdapterNode, &pNext);
15498 pAdapterNode = pNext;
15499 }
15500
15501 return active_session;
15502}
15503
15504/**
15505 * hdd_set_delack_value() - Set delack value
15506 * @pHddCtx: Valid Global HDD context pointer
15507 * @next_rx_level: Value to set for delack
15508 *
15509 * This function compare present value and next value of delack. If the both
15510 * are diffrent then it sets next value .
15511 *
15512 * Return: void.
15513 */
15514void hdd_set_delack_value(hdd_context_t *pHddCtx, v_U32_t next_rx_level)
15515{
15516 if (pHddCtx->cur_rx_level != next_rx_level) {
Alok Kumarf3724462018-04-05 15:18:54 +053015517 struct wlan_rx_tp_data rx_tp_data = {0};
15518
Bhargav Shahd0715912015-10-01 18:17:37 +053015519 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_DEBUG,
15520 "%s: TCP DELACK trigger level %d",
15521 __func__, next_rx_level);
15522 mutex_lock(&pHddCtx->cur_rx_level_lock);
15523 pHddCtx->cur_rx_level = next_rx_level;
15524 mutex_unlock(&pHddCtx->cur_rx_level_lock);
Alok Kumarf3724462018-04-05 15:18:54 +053015525
15526 rx_tp_data.rx_tp_flags |= TCP_DEL_ACK_IND;
15527 rx_tp_data.level = next_rx_level;
15528
15529 wlan_hdd_send_svc_nlink_msg(WLAN_SVC_WLAN_TP_IND, &rx_tp_data,
15530 sizeof(rx_tp_data));
Bhargav Shahd0715912015-10-01 18:17:37 +053015531 }
15532}
15533
15534/**
15535 * hdd_set_default_stop_delack_timer() - Start delack timer
15536 * @pHddCtx: Valid Global HDD context pointer
15537 *
15538 * This function stop delack timer and set delack value to default..
15539 *
15540 * Return: void.
15541 */
15542
15543void hdd_set_default_stop_delack_timer(hdd_context_t *pHddCtx)
15544{
15545 if (VOS_TIMER_STATE_RUNNING !=
15546 vos_timer_getCurrentState(&pHddCtx->delack_timer)) {
15547 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_DEBUG,
15548 "%s: Can not stop timer", __func__);
15549 return;
15550 }
15551
15552 vos_timer_stop(&pHddCtx->delack_timer);
Alok Kumarf3724462018-04-05 15:18:54 +053015553 hdd_set_delack_value(pHddCtx, WLAN_SVC_TP_LOW);
Bhargav Shahd0715912015-10-01 18:17:37 +053015554}
15555
15556/**
15557 * hdd_start_delack_timer() - Start delack timer
15558 * @pHddCtx: Valid Global HDD context pointer
15559 *
15560 * This function starts the delack timer for tcpDelAckComputeInterval time
15561 * interval.The default timer value is 2 second.
15562 *
15563 * Return: void.
15564 */
15565void hdd_start_delack_timer(hdd_context_t *pHddCtx)
15566{
15567 if (VOS_TIMER_STATE_RUNNING ==
15568 vos_timer_getCurrentState(&pHddCtx->delack_timer)) {
15569 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_DEBUG,
15570 "%s: Timer is already running", __func__);
15571 return;
15572 }
15573
15574 vos_timer_start(&pHddCtx->delack_timer,
15575 pHddCtx->cfg_ini->tcpDelAckComputeInterval);
15576}
15577
15578/**
15579 * hdd_update_prev_rx_packet_count() - Update previous rx packet count
15580 * @pHddCtx: Valid Global HDD context pointer
15581 *
15582 * This function updates the prev_rx_packets count from the corresponding
15583 * pAdapter states. This prev_rx_packets will diffed with the packet count
15584 * at the end of delack timer. That can give number of RX packet is spacific
15585 * time.
15586 *
15587 * Return: void.
15588 */
15589void hdd_update_prev_rx_packet_count(hdd_context_t *pHddCtx)
15590{
15591 hdd_adapter_list_node_t *pAdapterNode, *pNext;
15592 hdd_adapter_t *pAdapter;
15593 VOS_STATUS status;
15594
15595 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
15596 while (NULL != pAdapterNode && VOS_STATUS_SUCCESS == status) {
15597 pAdapter = pAdapterNode->pAdapter;
15598 pAdapter->prev_rx_packets = pAdapter->stats.rx_packets;
15599 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
15600 pAdapterNode = pNext;
15601 }
15602}
15603
15604/**
15605 * hdd_manage_delack_timer() - start\stop delack timer
15606 * @pHddCtx: Valid Global HDD context pointer
15607 *
15608 * This function check the number of concerent session present, it starts the
15609 * delack timer if only one session is present.
15610 * In the case of BT_COEX and TDLS mode it blindly stop delack functionality.
15611 *
15612 * Return: void.
15613 */
15614void hdd_manage_delack_timer(hdd_context_t *pHddCtx)
15615{
15616 uint8_t sessions;
15617
15618 if (!pHddCtx->cfg_ini->enable_delack) {
15619 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_DEBUG,
15620 "%s: TCP DELACK is not enabled", __func__);
15621 return;
15622 }
15623
15624 /* Blindly stop timer of BTCOEX and TDLS Session is up */
15625 if (pHddCtx->mode != 0) {
15626 hdd_set_default_stop_delack_timer(pHddCtx);
15627 return;
15628 }
15629
15630 sessions = hdd_get_total_sessions(pHddCtx);
15631 if (sessions == 1) {
15632 hdd_update_prev_rx_packet_count(pHddCtx);
15633 hdd_start_delack_timer(pHddCtx);
15634 } else {
15635 hdd_set_default_stop_delack_timer(pHddCtx);
15636 }
15637}
15638
Mihir Shetee1093ba2014-01-21 20:13:32 +053015639/**---------------------------------------------------------------------------
15640 *
15641 * \brief wlan_hdd_init_channels
15642 *
15643 * This function is used to initialize the channel list in CSR
15644 *
15645 * This function is called from hdd_wlan_startup
15646 *
15647 * \param - pHddCtx: HDD context
15648 *
15649 * \return - VOS_STATUS_SUCCESS: Success
15650 * VOS_STATUS_E_FAULT: Failure reported by SME
15651
15652 * --------------------------------------------------------------------------*/
15653static VOS_STATUS wlan_hdd_init_channels(hdd_context_t *pHddCtx)
15654{
15655 eHalStatus status;
15656
15657 status = sme_InitChannels(pHddCtx->hHal);
15658 if (HAL_STATUS_SUCCESS(status))
15659 {
15660 return VOS_STATUS_SUCCESS;
15661 }
15662 else
15663 {
15664 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Channel initialization failed(%d)",
15665 __func__, status);
15666 return VOS_STATUS_E_FAULT;
15667 }
15668}
15669
Mihir Shete04206452014-11-20 17:50:58 +053015670#ifdef CONFIG_ENABLE_LINUX_REG
Agarwal Ashish6db9d532014-09-30 18:19:10 +053015671VOS_STATUS wlan_hdd_init_channels_for_cc(hdd_context_t *pHddCtx, driver_load_type init )
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053015672{
15673 eHalStatus status;
15674
Rajeev Kumar Sirasanagandlaf8fc27c2018-12-06 14:56:43 +053015675 if (init == INIT && init_by_reg_core_user) {
15676 init_by_reg_core_user = false;
15677 pr_info("driver regulatory hint is not required");
15678
15679 return VOS_STATUS_SUCCESS;
15680 }
15681
Agarwal Ashish6db9d532014-09-30 18:19:10 +053015682 status = sme_InitChannelsForCC(pHddCtx->hHal, init);
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053015683 if (HAL_STATUS_SUCCESS(status))
15684 {
15685 return VOS_STATUS_SUCCESS;
15686 }
15687 else
15688 {
15689 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Issue reg hint failed(%d)",
15690 __func__, status);
15691 return VOS_STATUS_E_FAULT;
15692 }
15693}
Mihir Shete04206452014-11-20 17:50:58 +053015694#endif
Sudhir Sattayappa Kohallib1d8c3a2013-06-18 14:47:20 -070015695/*
15696 * API to find if there is any STA or P2P-Client is connected
15697 */
15698VOS_STATUS hdd_issta_p2p_clientconnected(hdd_context_t *pHddCtx)
15699{
15700 return sme_isSta_p2p_clientConnected(pHddCtx->hHal);
15701}
Jeff Johnsone7245742012-09-05 17:12:55 -070015702
Mihir Shetee2ae82a2015-03-16 14:08:49 +053015703
15704/*
15705 * API to find if the firmware will send logs using DXE channel
15706 */
15707v_U8_t hdd_is_fw_logging_enabled(void)
15708{
15709 hdd_context_t *pHddCtx;
15710
15711 pHddCtx = vos_get_context(VOS_MODULE_ID_HDD,
15712 vos_get_global_context(VOS_MODULE_ID_HDD, NULL));
15713
Sachin Ahuja084313e2015-05-21 17:57:10 +053015714 return (pHddCtx && pHddCtx->cfg_ini->enableMgmtLogging);
Mihir Shetee2ae82a2015-03-16 14:08:49 +053015715}
15716
Agarwal Ashish57e84372014-12-05 18:26:53 +053015717/*
Mihir Shetebe94ebb2015-05-26 12:07:14 +053015718 * API to find if the firmware will send trace logs using DXE channel
15719 */
15720v_U8_t hdd_is_fw_ev_logging_enabled(void)
15721{
15722 hdd_context_t *pHddCtx;
15723
15724 pHddCtx = vos_get_context(VOS_MODULE_ID_HDD,
15725 vos_get_global_context(VOS_MODULE_ID_HDD, NULL));
15726
15727 return (pHddCtx && pHddCtx->cfg_ini->enableFWLogging);
15728}
15729/*
Agarwal Ashish57e84372014-12-05 18:26:53 +053015730 * API to find if there is any session connected
15731 */
15732VOS_STATUS hdd_is_any_session_connected(hdd_context_t *pHddCtx)
15733{
15734 return sme_is_any_session_connected(pHddCtx->hHal);
15735}
15736
15737
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053015738int wlan_hdd_scan_abort(hdd_adapter_t *pAdapter)
15739{
15740 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
15741 hdd_scaninfo_t *pScanInfo = NULL;
Girish Gowli4bf7a632014-06-12 13:42:11 +053015742 long status = 0;
c_hpothua3d45d52015-01-05 14:11:17 +053015743 tSirAbortScanStatus abortScanStatus;
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053015744
15745 pScanInfo = &pHddCtx->scan_info;
Ratnam Rachuric7681132015-06-30 10:35:13 +053015746 INIT_COMPLETION(pScanInfo->abortscan_event_var);
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053015747 if (pScanInfo->mScanPending)
15748 {
c_hpothua3d45d52015-01-05 14:11:17 +053015749 abortScanStatus = hdd_abort_mac_scan(pHddCtx, pScanInfo->sessionId,
15750 eCSR_SCAN_ABORT_DEFAULT);
15751 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15752 FL("abortScanStatus: %d"), abortScanStatus);
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053015753
c_hpothua3d45d52015-01-05 14:11:17 +053015754 /* If there is active scan command lets wait for the completion else
15755 * there is no need to wait as scan command might be in the SME pending
15756 * command list.
15757 */
15758 if (abortScanStatus == eSIR_ABORT_ACTIVE_SCAN_LIST_NOT_EMPTY)
15759 {
Mukul Sharmab392b642017-08-17 17:45:29 +053015760 status = wait_for_completion_timeout(
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053015761 &pScanInfo->abortscan_event_var,
15762 msecs_to_jiffies(5000));
c_hpothua3d45d52015-01-05 14:11:17 +053015763 if (0 >= status)
15764 {
15765 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Girish Gowli4bf7a632014-06-12 13:42:11 +053015766 "%s: Timeout or Interrupt occurred while waiting for abort"
15767 "scan, status- %ld", __func__, status);
c_hpothua3d45d52015-01-05 14:11:17 +053015768 return -ETIMEDOUT;
15769 }
15770 }
15771 else if (abortScanStatus == eSIR_ABORT_SCAN_FAILURE)
15772 {
15773 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15774 FL("hdd_abort_mac_scan failed"));
15775 return -VOS_STATUS_E_FAILURE;
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053015776 }
15777 }
Girish Gowli4bf7a632014-06-12 13:42:11 +053015778 return 0;
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053015779}
15780
Abhishek Singh7d624e12015-11-30 14:29:27 +053015781/**
15782 * hdd_indicate_mgmt_frame() - Wrapper to indicate management frame to
15783 * user space
15784 * @frame_ind: Management frame data to be informed.
15785 *
15786 * This function is used to indicate management frame to
15787 * user space
15788 *
15789 * Return: None
15790 *
15791 */
15792void hdd_indicate_mgmt_frame(tSirSmeMgmtFrameInd *frame_ind)
15793{
15794 hdd_context_t *hdd_ctx = NULL;
15795 hdd_adapter_t *adapter = NULL;
15796 v_CONTEXT_t vos_context = NULL;
15797
15798 /* Get the global VOSS context.*/
15799 vos_context = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
15800 if (!vos_context) {
15801 hddLog(LOGE, FL("Global VOS context is Null"));
15802 return;
15803 }
15804 /* Get the HDD context.*/
15805 hdd_ctx =
15806 (hdd_context_t *)vos_get_context(VOS_MODULE_ID_HDD, vos_context );
15807
15808 if (0 != wlan_hdd_validate_context(hdd_ctx))
15809 {
15810 return;
15811 }
15812 adapter = hdd_get_adapter_by_sme_session_id(hdd_ctx,
15813 frame_ind->sessionId);
15814
15815 if ((NULL != adapter) &&
15816 (WLAN_HDD_ADAPTER_MAGIC == adapter->magic))
15817 __hdd_indicate_mgmt_frame(adapter,
15818 frame_ind->frameLen,
15819 frame_ind->frameBuf,
15820 frame_ind->frameType,
15821 frame_ind->rxChan,
15822 frame_ind->rxRssi);
15823 return;
15824
15825}
15826
c_hpothu225aa7c2014-10-22 17:45:13 +053015827VOS_STATUS wlan_hdd_cancel_remain_on_channel(hdd_context_t *pHddCtx)
15828{
15829 hdd_adapter_t *pAdapter;
15830 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
15831 VOS_STATUS vosStatus;
15832
15833 vosStatus = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
15834 while (NULL != pAdapterNode && VOS_STATUS_E_EMPTY != vosStatus)
15835 {
15836 pAdapter = pAdapterNode->pAdapter;
15837 if (NULL != pAdapter)
15838 {
15839 if (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode ||
15840 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode ||
15841 WLAN_HDD_P2P_GO == pAdapter->device_mode)
15842 {
15843 hddLog(LOG1, FL("abort ROC deviceMode: %d"),
15844 pAdapter->device_mode);
15845 if (VOS_STATUS_SUCCESS !=
15846 wlan_hdd_cancel_existing_remain_on_channel(pAdapter))
15847 {
15848 hddLog(LOGE, FL("failed to abort ROC"));
15849 return VOS_STATUS_E_FAILURE;
15850 }
15851 }
15852 }
15853 vosStatus = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
15854 pAdapterNode = pNext;
15855 }
15856 return VOS_STATUS_SUCCESS;
15857}
Mahesh A Saptasagard477b092015-02-06 15:12:16 +053015858
Mihir Shete0be28772015-02-17 18:42:14 +053015859hdd_remain_on_chan_ctx_t *hdd_get_remain_on_channel_ctx(hdd_context_t *pHddCtx)
15860{
15861 hdd_adapter_t *pAdapter;
15862 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
15863 hdd_cfg80211_state_t *cfgState;
15864 hdd_remain_on_chan_ctx_t *pRemainChanCtx = NULL;
15865 VOS_STATUS vosStatus;
15866
15867 vosStatus = hdd_get_front_adapter (pHddCtx, &pAdapterNode);
15868 while (NULL != pAdapterNode && VOS_STATUS_E_EMPTY != vosStatus)
15869 {
15870 pAdapter = pAdapterNode->pAdapter;
15871 if (NULL != pAdapter)
15872 {
15873 cfgState = WLAN_HDD_GET_CFG_STATE_PTR(pAdapter);
15874 pRemainChanCtx = cfgState->remain_on_chan_ctx;
15875 if (pRemainChanCtx)
15876 break;
15877 }
15878 vosStatus = hdd_get_next_adapter (pHddCtx, pAdapterNode, &pNext);
15879 pAdapterNode = pNext;
15880 }
15881 return pRemainChanCtx;
15882}
15883
Padma, Santhosh Kumar778d8382015-03-04 17:41:22 +053015884/**
15885 * wlan_hdd_handle_dfs_chan_scan () - handles disable/enable DFS channels
15886 *
15887 * @pHddCtx: HDD context within host driver
15888 * @dfsScanMode: dfsScanMode passed from ioctl
15889 *
15890 */
15891
15892VOS_STATUS wlan_hdd_handle_dfs_chan_scan(hdd_context_t *pHddCtx,
15893 tANI_U8 dfsScanMode)
15894{
15895 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
15896 hdd_adapter_t *pAdapter;
15897 VOS_STATUS vosStatus;
15898 hdd_station_ctx_t *pHddStaCtx;
15899 eHalStatus status = eHAL_STATUS_SUCCESS;
15900
15901 if(!pHddCtx)
15902 {
15903 hddLog(LOGE, FL("HDD context is Null"));
15904 return eHAL_STATUS_FAILURE;
15905 }
15906
15907 if (pHddCtx->scan_info.mScanPending)
15908 {
15909 hddLog(LOG1, FL("Aborting scan for sessionId: %d"),
15910 pHddCtx->scan_info.sessionId);
15911 hdd_abort_mac_scan(pHddCtx,
15912 pHddCtx->scan_info.sessionId,
15913 eCSR_SCAN_ABORT_DEFAULT);
15914 }
15915
15916 if (!dfsScanMode)
15917 {
15918 vosStatus = hdd_get_front_adapter( pHddCtx, &pAdapterNode);
15919 while ((NULL != pAdapterNode) &&
15920 (VOS_STATUS_SUCCESS == vosStatus))
15921 {
15922 pAdapter = pAdapterNode->pAdapter;
15923
15924 if (WLAN_HDD_INFRA_STATION == pAdapter->device_mode)
15925 {
15926 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
15927
15928 if(!pHddStaCtx)
15929 {
15930 hddLog(LOGE, FL("HDD STA context is Null"));
15931 return eHAL_STATUS_FAILURE;
15932 }
15933
15934 /* if STA is already connected on DFS channel,
15935 disconnect immediately*/
15936 if (hdd_connIsConnected(pHddStaCtx) &&
15937 (NV_CHANNEL_DFS ==
15938 vos_nv_getChannelEnabledState(
15939 pHddStaCtx->conn_info.operationChannel)))
15940 {
15941 status = sme_RoamDisconnect(pHddCtx->hHal,
15942 pAdapter->sessionId,
15943 eCSR_DISCONNECT_REASON_UNSPECIFIED);
15944 hddLog(LOG1, FL("Client connected on DFS channel %d,"
15945 "sme_RoamDisconnect returned with status: %d"
15946 "for sessionid: %d"), pHddStaCtx->conn_info.
15947 operationChannel, status, pAdapter->sessionId);
15948 }
15949 }
15950
15951 vosStatus = hdd_get_next_adapter(pHddCtx, pAdapterNode,
15952 &pNext);
15953 pAdapterNode = pNext;
15954 }
15955 }
15956
15957 sme_UpdateDFSScanMode(pHddCtx->hHal, dfsScanMode);
15958 sme_UpdateDFSRoamMode(pHddCtx->hHal,
15959 (dfsScanMode != DFS_CHNL_SCAN_DISABLED));
15960
15961 status = sme_HandleDFSChanScan(pHddCtx->hHal);
15962 if (!HAL_STATUS_SUCCESS(status))
15963 {
15964 hddLog(LOGE,
15965 FL("Failed in sme_HandleDFSChanScan (err=%d)"), status);
15966 return status;
15967 }
15968
15969 return status;
15970}
15971
Nirav Shah7e3c8132015-06-22 23:51:42 +053015972static int hdd_log2_ceil(unsigned value)
15973{
15974 /* need to switch to unsigned math so that negative values
15975 * will right-shift towards 0 instead of -1
15976 */
15977 unsigned tmp = value;
15978 int log2 = -1;
15979
15980 if (value == 0)
15981 return 0;
15982
15983 while (tmp) {
15984 log2++;
15985 tmp >>= 1;
15986 }
15987 if (1U << log2 != value)
15988 log2++;
15989
15990 return log2;
15991}
15992
15993/**
15994 * hdd_sta_id_hash_attach() - initialize sta id to macaddr hash
15995 * @pAdapter: adapter handle
15996 *
15997 * Return: vos status
15998 */
15999VOS_STATUS hdd_sta_id_hash_attach(hdd_adapter_t *pAdapter)
16000{
16001 int hash_elem, log2, i;
16002
16003 spin_lock_bh( &pAdapter->sta_hash_lock);
16004 if (pAdapter->is_sta_id_hash_initialized == VOS_TRUE) {
16005 spin_unlock_bh( &pAdapter->sta_hash_lock);
16006 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16007 "%s: hash already attached for session id %d",
16008 __func__, pAdapter->sessionId);
16009 return VOS_STATUS_SUCCESS;
16010 }
16011 spin_unlock_bh( &pAdapter->sta_hash_lock);
16012
16013 hash_elem = WLAN_MAX_STA_COUNT;
16014 hash_elem *= HDD_STA_ID_HASH_MULTIPLIER;
16015 log2 = hdd_log2_ceil(hash_elem);
16016 hash_elem = 1 << log2;
16017
16018 pAdapter->sta_id_hash.mask = hash_elem - 1;
16019 pAdapter->sta_id_hash.idx_bits = log2;
16020 pAdapter->sta_id_hash.bins =
16021 vos_mem_malloc(hash_elem *sizeof(hdd_list_t));
16022 if (!pAdapter->sta_id_hash.bins) {
16023 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16024 "%s: malloc failed for session %d",
16025 __func__, pAdapter->sessionId);
16026 return VOS_STATUS_E_NOMEM;
16027 }
16028
16029 for (i = 0; i < hash_elem; i++)
16030 hdd_list_init(&pAdapter->sta_id_hash.bins[i], WLAN_MAX_STA_COUNT);
16031
16032 spin_lock_bh( &pAdapter->sta_hash_lock);
16033 pAdapter->is_sta_id_hash_initialized = VOS_TRUE;
16034 spin_unlock_bh( &pAdapter->sta_hash_lock);
16035 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16036 "%s: Station ID Hash attached for session id %d",
16037 __func__, pAdapter->sessionId);
16038
16039 return VOS_STATUS_SUCCESS;
16040}
16041
16042/**
16043 * hdd_sta_id_hash_detach() - deinit sta_id to macaddr hash
16044 * @pAdapter: adapter handle
16045 *
16046 * Return: vos status
16047 */
16048VOS_STATUS hdd_sta_id_hash_detach(hdd_adapter_t *pAdapter)
16049{
16050 int hash_elem, i;
16051 v_SIZE_t size;
16052
16053 spin_lock_bh( &pAdapter->sta_hash_lock);
16054 if (pAdapter->is_sta_id_hash_initialized != VOS_TRUE) {
16055 spin_unlock_bh( &pAdapter->sta_hash_lock);
16056 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16057 "%s: hash not initialized for session id %d",
16058 __func__, pAdapter->sessionId);
16059 return VOS_STATUS_SUCCESS;
16060 }
16061
16062 pAdapter->is_sta_id_hash_initialized = VOS_FALSE;
16063 spin_unlock_bh( &pAdapter->sta_hash_lock);
16064
16065 hash_elem = 1 << pAdapter->sta_id_hash.idx_bits;
16066
16067 /* free all station info*/
16068 for (i = 0; i < hash_elem; i++) {
16069 hdd_list_size(&pAdapter->sta_id_hash.bins[i], &size);
16070 if (size != 0) {
16071 VOS_STATUS status;
16072 hdd_staid_hash_node_t *sta_info_node = NULL;
16073 hdd_staid_hash_node_t *next_node = NULL;
16074 status = hdd_list_peek_front ( &pAdapter->sta_id_hash.bins[i],
16075 (hdd_list_node_t**) &sta_info_node );
16076
16077 while ( NULL != sta_info_node && VOS_STATUS_SUCCESS == status )
16078 {
16079 status = hdd_list_remove_node( &pAdapter->sta_id_hash.bins[i],
16080 &sta_info_node->node);
16081 vos_mem_free(sta_info_node);
16082
16083 status = hdd_list_peek_next (&pAdapter->sta_id_hash.bins[i],
16084 (hdd_list_node_t*)sta_info_node,
16085 (hdd_list_node_t**)&next_node);
16086 sta_info_node = next_node;
16087 }
16088 }
16089 }
16090
16091 vos_mem_free(pAdapter->sta_id_hash.bins);
16092 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16093 "%s: Station ID Hash detached for session id %d",
16094 __func__, pAdapter->sessionId);
16095 return VOS_STATUS_SUCCESS;
16096}
16097
16098/**
16099 * hdd_sta_id_hash_calculate_index() - derive index from macaddr
16100 * @pAdapter: adapter handle
16101 * @mac_addr_in: input mac address
16102 *
16103 * Return: index derived from mac address
16104 */
16105int hdd_sta_id_hash_calculate_index(hdd_adapter_t *pAdapter,
16106 v_MACADDR_t *mac_addr_in)
16107{
16108 uint16 index;
16109 struct hdd_align_mac_addr_t * mac_addr =
16110 (struct hdd_align_mac_addr_t *)mac_addr_in;
16111
16112 index = mac_addr->bytes_ab ^
16113 mac_addr->bytes_cd ^ mac_addr->bytes_ef;
16114 index ^= index >> pAdapter->sta_id_hash.idx_bits;
16115 index &= pAdapter->sta_id_hash.mask;
16116 return index;
16117}
16118
16119/**
16120 * hdd_sta_id_hash_add_entry() - add entry in hash
16121 * @pAdapter: adapter handle
16122 * @sta_id: station id
16123 * @mac_addr: mac address
16124 *
16125 * Return: vos status
16126 */
16127VOS_STATUS hdd_sta_id_hash_add_entry(hdd_adapter_t *pAdapter,
16128 v_U8_t sta_id, v_MACADDR_t *mac_addr)
16129{
16130 uint16 index;
16131 hdd_staid_hash_node_t *sta_info_node = NULL;
16132
Nirav Shah7e3c8132015-06-22 23:51:42 +053016133 index = hdd_sta_id_hash_calculate_index(pAdapter, mac_addr);
16134 sta_info_node = vos_mem_malloc(sizeof(hdd_staid_hash_node_t));
16135 if (!sta_info_node) {
Nirav Shah7e3c8132015-06-22 23:51:42 +053016136 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16137 "%s: malloc failed", __func__);
16138 return VOS_STATUS_E_NOMEM;
16139 }
16140
16141 sta_info_node->sta_id = sta_id;
16142 vos_mem_copy(&sta_info_node->mac_addr, mac_addr, sizeof(v_MACADDR_t));
16143
Nirav Shah303ed5c2015-08-24 10:29:25 +053016144 spin_lock_bh( &pAdapter->sta_hash_lock);
16145 if (pAdapter->is_sta_id_hash_initialized != VOS_TRUE) {
16146 spin_unlock_bh( &pAdapter->sta_hash_lock);
16147 vos_mem_free(sta_info_node);
16148 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16149 "%s: hash is not initialized for session id %d",
16150 __func__, pAdapter->sessionId);
16151 return VOS_STATUS_E_FAILURE;
16152 }
16153
Nirav Shah7e3c8132015-06-22 23:51:42 +053016154 hdd_list_insert_back ( &pAdapter->sta_id_hash.bins[index],
16155 (hdd_list_node_t*) sta_info_node );
16156 spin_unlock_bh( &pAdapter->sta_hash_lock);
16157 return VOS_STATUS_SUCCESS;
16158}
16159
16160/**
16161 * hdd_sta_id_hash_remove_entry() - remove entry from hash
16162 * @pAdapter: adapter handle
16163 * @sta_id: station id
16164 * @mac_addr: mac address
16165 *
16166 * Return: vos status
16167 */
16168VOS_STATUS hdd_sta_id_hash_remove_entry(hdd_adapter_t *pAdapter,
16169 v_U8_t sta_id, v_MACADDR_t *mac_addr)
16170{
16171 uint16 index;
16172 VOS_STATUS status;
16173 hdd_staid_hash_node_t *sta_info_node = NULL;
16174 hdd_staid_hash_node_t *next_node = NULL;
16175
16176 spin_lock_bh( &pAdapter->sta_hash_lock);
16177 if (pAdapter->is_sta_id_hash_initialized != VOS_TRUE) {
16178 spin_unlock_bh( &pAdapter->sta_hash_lock);
16179 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16180 "%s: hash is not initialized for session id %d",
16181 __func__, pAdapter->sessionId);
16182 return VOS_STATUS_E_FAILURE;
16183 }
16184
16185 index = hdd_sta_id_hash_calculate_index(pAdapter, mac_addr);
16186 status = hdd_list_peek_front ( &pAdapter->sta_id_hash.bins[index],
16187 (hdd_list_node_t**) &sta_info_node );
16188
16189 while ( NULL != sta_info_node && VOS_STATUS_SUCCESS == status )
16190 {
16191 if (sta_info_node->sta_id == sta_id) {
16192 status = hdd_list_remove_node( &pAdapter->sta_id_hash.bins[index],
16193 &sta_info_node->node);
16194 vos_mem_free(sta_info_node);
16195 break;
16196 }
16197 status = hdd_list_peek_next (&pAdapter->sta_id_hash.bins[index],
16198 (hdd_list_node_t*)sta_info_node, (hdd_list_node_t**)&next_node);
16199 sta_info_node = next_node;
16200 }
16201 spin_unlock_bh( &pAdapter->sta_hash_lock);
16202 return status;
16203}
16204
16205/**
16206 * hdd_sta_id_find_from_mac_addr() - find sta id from mac address
16207 * @pAdapter: adapter handle
16208 * @mac_addr_in: mac address
16209 *
16210 * Return: station id
16211 */
16212int hdd_sta_id_find_from_mac_addr(hdd_adapter_t *pAdapter,
16213 v_MACADDR_t *mac_addr_in)
16214{
16215 uint8 is_found = 0;
16216 uint8 sta_id = HDD_WLAN_INVALID_STA_ID;
16217 uint16 index;
16218 VOS_STATUS status;
16219 hdd_staid_hash_node_t *sta_info_node = NULL;
16220 hdd_staid_hash_node_t *next_node = NULL;
16221
16222 spin_lock_bh( &pAdapter->sta_hash_lock);
16223 if (pAdapter->is_sta_id_hash_initialized != VOS_TRUE) {
16224 spin_unlock_bh( &pAdapter->sta_hash_lock);
Bhargav Shahce3b32c2015-08-10 12:29:24 +053016225 hddLog(VOS_TRACE_LEVEL_INFO,
Nirav Shah7e3c8132015-06-22 23:51:42 +053016226 FL("hash is not initialized for session id %d"),
16227 pAdapter->sessionId);
16228 return HDD_WLAN_INVALID_STA_ID;
16229 }
16230
16231 index = hdd_sta_id_hash_calculate_index(pAdapter, mac_addr_in);
16232 status = hdd_list_peek_front ( &pAdapter->sta_id_hash.bins[index],
16233 (hdd_list_node_t**) &sta_info_node );
16234
16235 while ( NULL != sta_info_node && VOS_STATUS_SUCCESS == status )
16236 {
16237 if (vos_mem_compare(&sta_info_node->mac_addr,
16238 mac_addr_in, sizeof(v_MACADDR_t))) {
16239 is_found = 1;
16240 sta_id = sta_info_node->sta_id;
16241 break;
16242 }
16243 status = hdd_list_peek_next (&pAdapter->sta_id_hash.bins[index],
16244 (hdd_list_node_t*)sta_info_node,
16245 (hdd_list_node_t**)&next_node);
16246 sta_info_node = next_node;
16247 }
16248 spin_unlock_bh( &pAdapter->sta_hash_lock);
16249 return sta_id;
16250}
16251
c_manjeecfd1efb2015-09-25 19:32:34 +053016252/*FW memory dump feature*/
16253/**
16254 * This structure hold information about the /proc file
16255 *
16256 */
16257static struct proc_dir_entry *proc_file, *proc_dir;
16258
16259/**
16260 * memdump_read() - perform read operation in memory dump proc file
16261 *
16262 * @file - handle for the proc file.
16263 * @buf - pointer to user space buffer.
16264 * @count - number of bytes to be read.
16265 * @pos - offset in the from buffer.
16266 *
16267 * This function performs read operation for the memory dump proc file.
16268 *
16269 * Return: number of bytes read on success, error code otherwise.
16270 */
16271static ssize_t memdump_read(struct file *file, char __user *buf,
16272 size_t count, loff_t *pos)
16273{
16274 int status;
16275 hdd_context_t *hdd_ctx = (hdd_context_t *)PDE_DATA(file_inode(file));
16276 size_t ret_count;
c_manjeef1495642015-10-13 18:35:01 +053016277 loff_t bytes_left;
c_manjeecfd1efb2015-09-25 19:32:34 +053016278 ENTER();
16279
16280 hddLog(LOG1, FL("Read req for size:%zu pos:%llu"), count, *pos);
16281 status = wlan_hdd_validate_context(hdd_ctx);
16282 if (0 != status) {
16283 return -EINVAL;
16284 }
16285
16286 if (!wlan_fwr_mem_dump_test_and_set_read_allowed_bit()) {
16287 hddLog(LOGE, FL("Current mem dump request timed out/failed"));
16288 return -EINVAL;
16289 }
16290
16291 /* run fs_read_handler in an atomic context*/
16292 vos_ssr_protect(__func__);
c_manjeef1495642015-10-13 18:35:01 +053016293 ret_count = wlan_fwr_mem_dump_fsread_handler( buf, count, pos, &bytes_left);
16294 if(bytes_left == 0)
c_manjeecfd1efb2015-09-25 19:32:34 +053016295 {
16296 /*Free the fwr mem dump buffer */
16297 wlan_free_fwr_mem_dump_buffer();
16298 wlan_set_fwr_mem_dump_state(FW_MEM_DUMP_IDLE);
c_manjeef1495642015-10-13 18:35:01 +053016299 ret_count=0;
c_manjeecfd1efb2015-09-25 19:32:34 +053016300 }
16301 /*if SSR/unload code is waiting for memdump_read to finish,signal it*/
16302 vos_ssr_unprotect(__func__);
16303 EXIT();
16304 return ret_count;
16305}
16306
16307/**
16308 * struct memdump_fops - file operations for memory dump feature
16309 * @read - read function for memory dump operation.
16310 *
16311 * This structure initialize the file operation handle for memory
16312 * dump feature
16313 */
16314static const struct file_operations memdump_fops = {
16315 read: memdump_read
16316};
16317
Hanumanth Reddy Pothulae856bc22018-04-11 15:35:36 +053016318struct fw_mem_dump_priv {
16319 uint32_t status;
16320};
16321
c_manjeecfd1efb2015-09-25 19:32:34 +053016322/*
16323* wlan_hdd_fw_mem_dump_cb : callback for Fw mem dump request
16324* To be passed by HDD to WDA and called upon receiving of response
16325* from firmware
16326* @fwMemDumpReqContext : memory dump request context
16327* @dump_rsp : dump response from HAL
16328* Returns none
16329*/
Hanumanth Reddy Pothulae856bc22018-04-11 15:35:36 +053016330void wlan_hdd_fw_mem_dump_cb(void *context,
c_manjeecfd1efb2015-09-25 19:32:34 +053016331 tAniFwrDumpRsp *dump_rsp)
16332{
Hanumanth Reddy Pothulae856bc22018-04-11 15:35:36 +053016333 struct hdd_request *request;
16334 struct fw_mem_dump_priv *priv;
c_manjeecfd1efb2015-09-25 19:32:34 +053016335
Hanumanth Reddy Pothulae856bc22018-04-11 15:35:36 +053016336 request = hdd_request_get(context);
16337 if (!request) {
16338 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Obsolete request"));
16339 return;
16340 }
c_manjeecfd1efb2015-09-25 19:32:34 +053016341
Hanumanth Reddy Pothulae856bc22018-04-11 15:35:36 +053016342 ENTER();
16343
16344 priv = hdd_request_priv(request);
16345 priv->status = dump_rsp->dump_status;
16346
16347 /* report the status to requesting function and free mem.*/
16348 if (dump_rsp->dump_status != eHAL_STATUS_SUCCESS) {
16349 hddLog(LOGE, FL("fw dump request declined by fwr"));
16350 //set the request completion variable
16351 hdd_request_complete(request);
16352 //Free the allocated fwr dump
16353 wlan_free_fwr_mem_dump_buffer();
16354 wlan_set_fwr_mem_dump_state(FW_MEM_DUMP_IDLE);
16355 } else {
16356 hddLog(LOG1, FL("fw dump request accepted by fwr"));
16357 /* register the HDD callback which will be called by SVC */
16358 wlan_set_svc_fw_mem_dump_req_cb(
16359 (void*)wlan_hdd_fw_mem_dump_req_cb,
16360 context);
16361 }
16362
16363 hdd_request_put(request);
16364
16365 EXIT();
c_manjeecfd1efb2015-09-25 19:32:34 +053016366}
16367
16368/**
16369 * memdump_procfs_remove() - Remove file/dir under procfs for memory dump
16370 *
16371 * This function removes file/dir under proc file system that was
16372 * processing firmware memory dump
16373 *
16374 * Return: None
16375 */
16376static void memdump_procfs_remove(void)
16377{
16378 remove_proc_entry(PROCFS_MEMDUMP_NAME, proc_dir);
16379 hddLog(LOG1 , FL("/proc/%s/%s removed\n"),
16380 PROCFS_MEMDUMP_DIR, PROCFS_MEMDUMP_NAME);
16381 remove_proc_entry(PROCFS_MEMDUMP_DIR, NULL);
16382 hddLog(LOG1 , FL("/proc/%s removed\n"), PROCFS_MEMDUMP_DIR);
16383}
16384
16385/**
16386 * memdump_procfs_init() - Initialize procfs for memory dump
16387 *
16388 * @vos_ctx - Global vos context.
16389 *
16390 * This function create file under proc file system to be used later for
16391 * processing firmware memory dump
16392 *
16393 * Return: 0 on success, error code otherwise.
16394 */
16395static int memdump_procfs_init(void *vos_ctx)
16396{
16397 hdd_context_t *hdd_ctx;
16398
16399 hdd_ctx = vos_get_context(VOS_MODULE_ID_HDD, vos_ctx);
16400 if (!hdd_ctx) {
16401 hddLog(LOGE , FL("Invalid HDD context"));
16402 return -EINVAL;
16403 }
16404
16405 proc_dir = proc_mkdir(PROCFS_MEMDUMP_DIR, NULL);
16406 if (proc_dir == NULL) {
16407 remove_proc_entry(PROCFS_MEMDUMP_DIR, NULL);
16408 hddLog(LOGE , FL("Error: Could not initialize /proc/%s"),
16409 PROCFS_MEMDUMP_DIR);
16410 return -ENOMEM;
16411 }
16412
16413 proc_file = proc_create_data(PROCFS_MEMDUMP_NAME,
16414 S_IRUSR | S_IWUSR, proc_dir,
16415 &memdump_fops, hdd_ctx);
16416 if (proc_file == NULL) {
16417 remove_proc_entry(PROCFS_MEMDUMP_NAME, proc_dir);
16418 hddLog(LOGE , FL("Error: Could not initialize /proc/%s"),
16419 PROCFS_MEMDUMP_NAME);
16420 return -ENOMEM;
16421 }
16422
16423 hddLog(LOG1 , FL("/proc/%s/%s created"),
16424 PROCFS_MEMDUMP_DIR, PROCFS_MEMDUMP_NAME);
16425
16426 return 0;
16427}
16428
16429/**
16430 * memdump_init() - Initialization function for memory dump feature
16431 *
16432 * This function creates proc file for memdump feature and registers
16433 * HDD callback function with SME.
16434 *
16435 * Return - 0 on success, error otherwise
16436 */
16437int memdump_init(void)
16438{
16439 hdd_context_t *hdd_ctx;
16440 void *vos_ctx;
16441 int status = 0;
16442
16443 vos_ctx = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
16444 if (!vos_ctx) {
16445 hddLog(LOGE, FL("Invalid VOS context"));
16446 return -EINVAL;
16447 }
16448
16449 hdd_ctx = vos_get_context(VOS_MODULE_ID_HDD, vos_ctx);
16450 if (!hdd_ctx) {
16451 hddLog(LOGE , FL("Invalid HDD context"));
16452 return -EINVAL;
16453 }
16454
16455 status = memdump_procfs_init(vos_ctx);
16456 if (status) {
16457 hddLog(LOGE , FL("Failed to create proc file"));
16458 return status;
16459 }
16460
16461 return 0;
16462}
16463
16464/**
16465 * memdump_deinit() - De initialize memdump feature
16466 *
16467 * This function removes proc file created for memdump feature.
16468 *
16469 * Return: None
16470 */
16471int memdump_deinit(void)
16472{
16473 hdd_context_t *hdd_ctx;
16474 void *vos_ctx;
16475
16476 vos_ctx = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
16477 if (!vos_ctx) {
16478 hddLog(LOGE, FL("Invalid VOS context"));
16479 return -EINVAL;
16480 }
16481
16482 hdd_ctx = vos_get_context(VOS_MODULE_ID_HDD, vos_ctx);
16483 if(!hdd_ctx) {
16484 hddLog(LOGE , FL("Invalid HDD context"));
16485 return -EINVAL;
16486 }
16487
16488 memdump_procfs_remove();
16489 return 0;
16490}
16491
16492/**
16493 * wlan_hdd_fw_mem_dump_req(pHddCtx) - common API(cfg80211/ioctl) for requesting fw mem dump to SME
16494 * Return: HAL status
16495 */
16496
16497int wlan_hdd_fw_mem_dump_req(hdd_context_t * pHddCtx)
16498{
16499 tAniFwrDumpReq fw_mem_dump_req={0};
16500 eHalStatus status = eHAL_STATUS_FAILURE;
Hanumanth Reddy Pothulae856bc22018-04-11 15:35:36 +053016501 int ret=0, dump_status;
16502 void *cookie;
16503 struct hdd_request *request;
16504 struct fw_mem_dump_priv *priv;
16505 static const struct hdd_request_params params = {
16506 .priv_size = sizeof(*priv),
16507 .timeout_ms = FW_MEM_DUMP_TIMEOUT_MS,
16508 };
16509
c_manjeecfd1efb2015-09-25 19:32:34 +053016510 ENTER();
c_manjeef1495642015-10-13 18:35:01 +053016511
c_manjeecfd1efb2015-09-25 19:32:34 +053016512 /*Check whether a dump request is already going on
16513 *Caution this function will free previously held memory if new dump request is allowed*/
16514 if (!wlan_fwr_mem_dump_test_and_set_write_allowed_bit()) {
16515 hddLog(LOGE, FL("Fw memdump already in progress"));
16516 return -EBUSY;
16517 }
16518 //Allocate memory for fw mem dump buffer
16519 ret = wlan_fwr_mem_dump_buffer_allocation();
16520 if(ret == -EFAULT)
16521 {
16522 hddLog(LOGE, FL("Fwr mem dump not supported by FW"));
16523 return ret;
16524 }
16525 if (0 != ret) {
16526 hddLog(LOGE, FL("Fwr mem Allocation failed"));
16527 return -ENOMEM;
16528 }
Hanumanth Reddy Pothulae856bc22018-04-11 15:35:36 +053016529
16530 request = hdd_request_alloc(&params);
16531 if (!request) {
16532 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Request allocation failure"));
16533 return VOS_STATUS_E_NOMEM;
16534 }
16535 cookie = hdd_request_cookie(request);
c_manjeef1495642015-10-13 18:35:01 +053016536
c_manjeecfd1efb2015-09-25 19:32:34 +053016537 fw_mem_dump_req.fwMemDumpReqCallback = wlan_hdd_fw_mem_dump_cb;
Hanumanth Reddy Pothulae856bc22018-04-11 15:35:36 +053016538 fw_mem_dump_req.fwMemDumpReqContext = cookie;
c_manjeecfd1efb2015-09-25 19:32:34 +053016539 status = sme_FwMemDumpReq(pHddCtx->hHal, &fw_mem_dump_req);
16540 if(eHAL_STATUS_SUCCESS != status)
16541 {
16542 hddLog(VOS_TRACE_LEVEL_ERROR,
16543 "%s: fw_mem_dump_req failed ", __func__);
16544 wlan_free_fwr_mem_dump_buffer();
c_manjeef1495642015-10-13 18:35:01 +053016545 ret = -EFAULT;
16546 goto cleanup;
c_manjeecfd1efb2015-09-25 19:32:34 +053016547 }
c_manjeef1495642015-10-13 18:35:01 +053016548 /*wait for fw mem dump completion to send event to userspace*/
Hanumanth Reddy Pothulae856bc22018-04-11 15:35:36 +053016549 ret = hdd_request_wait_for_response(request);
16550 if (ret)
c_manjeef1495642015-10-13 18:35:01 +053016551 {
16552 hddLog(VOS_TRACE_LEVEL_ERROR,
Hanumanth Reddy Pothulae856bc22018-04-11 15:35:36 +053016553 "%s: fw_mem_dump_req timeout %d ", __func__,ret);
Abhishek Singh4eca9822015-12-09 18:07:34 +053016554 ret = -ETIMEDOUT;
Hanumanth Reddy Pothulae856bc22018-04-11 15:35:36 +053016555 }else {
16556 priv = hdd_request_priv(request);
16557 dump_status = priv->status;
c_manjeef1495642015-10-13 18:35:01 +053016558 }
16559cleanup:
Hanumanth Reddy Pothulae856bc22018-04-11 15:35:36 +053016560 hdd_request_put(request);
16561 if(!ret && !dump_status)
Abhishek Singh4eca9822015-12-09 18:07:34 +053016562 ret = -EFAULT;
c_manjeecfd1efb2015-09-25 19:32:34 +053016563
c_manjeef1495642015-10-13 18:35:01 +053016564 EXIT();
Abhishek Singh4eca9822015-12-09 18:07:34 +053016565 return ret;
c_manjeef1495642015-10-13 18:35:01 +053016566}
16567
16568/**
16569 * HDD callback which will be called by SVC to indicate mem dump completion.
16570 */
Hanumanth Reddy Pothulae856bc22018-04-11 15:35:36 +053016571void wlan_hdd_fw_mem_dump_req_cb(void *context)
c_manjeef1495642015-10-13 18:35:01 +053016572{
Hanumanth Reddy Pothulae856bc22018-04-11 15:35:36 +053016573 struct hdd_request *request;
16574 struct fw_mem_dump_priv *priv;
16575
16576 request = hdd_request_get(context);
16577 if (!request) {
16578 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Obsolete request"));
16579 return;
16580 }
16581
16582 priv = hdd_request_priv(request);
16583 priv->status = true;
16584
16585 hdd_request_complete(request);
16586 hdd_request_put(request);
c_manjeecfd1efb2015-09-25 19:32:34 +053016587}
16588
Mahesh A Saptasagar67ab9222015-10-21 15:38:41 +053016589void hdd_initialize_adapter_common(hdd_adapter_t *pAdapter)
16590{
16591 if (NULL == pAdapter)
16592 {
16593 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: pAdapter is NULL ", __func__);
16594 return;
16595 }
16596 init_completion(&pAdapter->session_open_comp_var);
16597 init_completion(&pAdapter->session_close_comp_var);
16598 init_completion(&pAdapter->disconnect_comp_var);
16599 init_completion(&pAdapter->linkup_event_var);
16600 init_completion(&pAdapter->cancel_rem_on_chan_var);
16601 init_completion(&pAdapter->rem_on_chan_ready_event);
16602 init_completion(&pAdapter->pno_comp_var);
16603#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
16604 init_completion(&pAdapter->offchannel_tx_event);
16605#endif
16606 init_completion(&pAdapter->tx_action_cnf_event);
16607#ifdef FEATURE_WLAN_TDLS
16608 init_completion(&pAdapter->tdls_add_station_comp);
16609 init_completion(&pAdapter->tdls_del_station_comp);
16610 init_completion(&pAdapter->tdls_mgmt_comp);
16611 init_completion(&pAdapter->tdls_link_establish_req_comp);
16612#endif
16613
16614#ifdef WLAN_FEATURE_RMC
16615 init_completion(&pAdapter->ibss_peer_info_comp);
16616#endif /* WLAN_FEATURE_RMC */
16617 init_completion(&pAdapter->ula_complete);
16618 init_completion(&pAdapter->change_country_code);
16619
16620#ifdef FEATURE_WLAN_BATCH_SCAN
16621 init_completion(&pAdapter->hdd_set_batch_scan_req_var);
16622 init_completion(&pAdapter->hdd_get_batch_scan_req_var);
16623#endif
Kapil Gupta2b44acb2016-12-30 16:49:51 +053016624 init_completion(&pAdapter->wlan_suspend_comp_var);
Mahesh A Saptasagar67ab9222015-10-21 15:38:41 +053016625
16626 return;
16627}
c_manjeecfd1efb2015-09-25 19:32:34 +053016628
Anurag Chouhan0b29de02016-12-16 13:18:40 +053016629#ifdef MDNS_OFFLOAD
16630
16631/**
16632 * hdd_mdns_enable_offload_done() - mdns enable offload response api
16633 * @padapter: holds adapter
16634 * @status: response status
16635 *
16636 * Return - None
16637 */
16638void hdd_mdns_enable_offload_done(void *padapter, VOS_STATUS status)
16639{
16640 hdd_adapter_t* adapter = (hdd_adapter_t*) padapter;
16641
16642 ENTER();
16643
16644 if (NULL == adapter)
16645 {
16646 hddLog(VOS_TRACE_LEVEL_ERROR,
16647 "%s: adapter is NULL",__func__);
16648 return;
16649 }
16650
16651 adapter->mdns_status.mdns_enable_status = status;
16652 vos_event_set(&adapter->mdns_status.vos_event);
16653 return;
16654}
16655
16656/**
16657 * hdd_mdns_fqdn_offload_done() - mdns fqdn offload response api
16658 * @padapter: holds adapter
16659 * @status: responce status
16660 *
16661 * Return - None
16662 */
16663void hdd_mdns_fqdn_offload_done(void *padapter, VOS_STATUS status)
16664{
16665 hdd_adapter_t* adapter = (hdd_adapter_t*) padapter;
16666
16667 ENTER();
16668
16669 if (NULL == adapter)
16670 {
16671 hddLog(VOS_TRACE_LEVEL_ERROR,
16672 "%s: adapter is NULL",__func__);
16673 return;
16674 }
16675
16676 adapter->mdns_status.mdns_fqdn_status = status;
16677 return;
16678}
16679
16680/**
16681 * hdd_mdns_resp_offload_done() - mdns resp offload response api
16682 * @padapter: holds adapter
16683 * @status: responce status
16684 *
16685 * Return - None
16686 */
16687void hdd_mdns_resp_offload_done(void *padapter, VOS_STATUS status)
16688{
16689 hdd_adapter_t* adapter = (hdd_adapter_t*) padapter;
16690
16691 ENTER();
16692
16693 if (NULL == adapter)
16694 {
16695 hddLog(VOS_TRACE_LEVEL_ERROR,
16696 "%s: adapter is NULL",__func__);
16697 return;
16698 }
16699
16700 adapter->mdns_status.mdns_resp_status = status;
16701 return;
16702}
16703
16704/**
16705 * wlan_hdd_mdns_process_response_dname() - Process mDNS domain name
16706 * @response: Pointer to a struct hdd_mdns_resp_info
16707 * @resp_info: Pointer to a struct tSirMDNSResponseInfo
16708 *
16709 * This function will pack the whole domain name without compression. It will
16710 * add the leading len for each field and add zero length octet to terminate
16711 * the domain name.
16712 *
16713 * Return: Return boolean. TRUE for success, FALSE for fail.
16714 */
16715static bool
16716wlan_hdd_mdns_process_response_dname(struct hdd_mdns_resp_info *response,
16717 sir_mdns_resp_info resp_info)
16718{
16719 uint8_t num;
16720 uint16_t idx;
16721 uint8_t len = 0;
16722
16723 if ((response == NULL) || (response->data == NULL) ||
16724 (response->offset == NULL)) {
16725 hddLog(LOGE, FL("Either data or offset in response is NULL!"));
16726 return FALSE;
16727 }
16728
16729 if ((resp_info == NULL) ||
16730 (resp_info->resp_len >= MAX_MDNS_RESP_LEN)) {
16731 hddLog(LOGE, FL("resp_len exceeds %d!"), MAX_MDNS_RESP_LEN);
16732 return FALSE;
16733 }
16734
16735 for (num = 0; num < response->num_entries; num++) {
16736 response->offset[num] =
16737 resp_info->resp_len + MDNS_HEADER_LEN;
16738 idx = num * MAX_LEN_DOMAINNAME_FIELD;
16739 len = strlen((char *)&response->data[idx]);
16740 if ((resp_info->resp_len + len + 1) >= MAX_MDNS_RESP_LEN) {
16741 hddLog(LOGE, FL("resp_len exceeds %d!"),
16742 MAX_MDNS_RESP_LEN);
16743 return FALSE;
16744 }
16745 resp_info->resp_data[resp_info->resp_len] = len;
16746 resp_info->resp_len++;
16747 vos_mem_copy(&resp_info->resp_data[resp_info->resp_len],
16748 &response->data[idx], len);
16749 resp_info->resp_len += len;
16750 }
16751
16752 /* The domain name terminates with the zero length octet */
16753 if (num == response->num_entries) {
16754 if (resp_info->resp_len >= MAX_MDNS_RESP_LEN) {
16755 hddLog(LOGE, FL("resp_len exceeds %d!"),
16756 MAX_MDNS_RESP_LEN);
16757 return FALSE;
16758 }
16759 resp_info->resp_data[resp_info->resp_len] = 0;
16760 resp_info->resp_len++;
16761 }
16762
16763 return TRUE;
16764}
16765
16766/**
16767 * wlan_hdd_mdns_format_response_u16() - Form uint16_t response data
16768 * @value: The uint16_t value is formed to the struct tSirMDNSResponseInfo
16769 * @resp_info: Pointer to a struct tSirMDNSResponseInfo
16770 *
16771 * Return: None
16772 */
16773static void wlan_hdd_mdns_format_response_u16(uint16_t value,
16774 sir_mdns_resp_info resp_info)
16775{
16776 uint8_t val_u8;
16777
16778 if ((resp_info == NULL) || (resp_info->resp_data == NULL))
16779 return;
16780 val_u8 = (value & 0xff00) >> 8;
16781 resp_info->resp_data[resp_info->resp_len++] = val_u8;
16782 val_u8 = value & 0xff;
16783 resp_info->resp_data[resp_info->resp_len++] = val_u8;
16784}
16785
16786/**
16787 * wlan_hdd_mdns_format_response_u32() - Form uint32_t response data
16788 * @value: The uint32_t value is formed to the struct tSirMDNSResponseInfo
16789 * @resp_info: Pointer to a struct tSirMDNSResponseInfo
16790 *
16791 * Return: None
16792 */
16793static void wlan_hdd_mdns_format_response_u32(uint32_t value,
16794 sir_mdns_resp_info resp_info)
16795{
16796 uint8_t val_u8;
16797
16798 if ((resp_info == NULL) || (resp_info->resp_data == NULL))
16799 return;
16800 val_u8 = (value & 0xff000000) >> 24;
16801 resp_info->resp_data[resp_info->resp_len++] = val_u8;
16802 val_u8 = (value & 0xff0000) >> 16;
16803 resp_info->resp_data[resp_info->resp_len++] = val_u8;
16804 val_u8 = (value & 0xff00) >> 8;
16805 resp_info->resp_data[resp_info->resp_len++] = val_u8;
16806 val_u8 = value & 0xff;
16807 resp_info->resp_data[resp_info->resp_len++] = val_u8;
16808}
16809
16810/**
16811 * wlan_hdd_mdns_process_response_misc() - Process misc info in mDNS response
16812 * @resp_type: Response type for mDNS
16813 * @resp_info: Pointer to a struct tSirMDNSResponseInfo
16814 *
16815 * This function will pack the response type, class and TTL (Time To Live).
16816 *
16817 * Return: Return boolean. TRUE for success, FALSE for fail.
16818 */
16819static bool wlan_hdd_mdns_process_response_misc(uint16_t resp_type,
16820 sir_mdns_resp_info resp_info)
16821{
16822 uint16_t len;
16823
16824 if (resp_info == NULL) {
16825 hddLog(LOGE, FL("resp_info is NULL!"));
16826 return FALSE;
16827 }
16828
16829 len = resp_info->resp_len + (2 * sizeof(uint16_t) + sizeof(uint32_t));
16830 if (len >= MAX_MDNS_RESP_LEN) {
16831 hddLog(LOGE, FL("resp_len exceeds %d!"), MAX_MDNS_RESP_LEN);
16832 return FALSE;
16833 }
16834
16835 /* Fill Type, Class, TTL */
16836 wlan_hdd_mdns_format_response_u16(resp_type, resp_info);
16837 wlan_hdd_mdns_format_response_u16(MDNS_CLASS, resp_info);
16838 wlan_hdd_mdns_format_response_u32(MDNS_TTL, resp_info);
16839
16840 return TRUE;
16841}
16842
16843/**
16844 * wlan_hdd_mdns_compress_data() - Compress the domain name in mDNS response
16845 * @resp_info: Pointer to a struct tSirMDNSResponseInfo
16846 * @response_dst: The response which domain name is compressed.
16847 * @response_src: The response which domain name is matched with response_dst.
16848 * Its offset is used for data compression.
16849 * @num_matched: The number of matched entries between response_dst and
16850 * response_src
16851 *
16852 * This function will form the different fields of domain name in response_dst
16853 * if any. Then use the offset of the matched domain name in response_src to
16854 * compress the matched domain name.
16855 *
16856 * Return: Return boolean. TRUE for success, FALSE for fail.
16857 */
16858static bool
16859wlan_hdd_mdns_compress_data(sir_mdns_resp_info resp_info,
16860 struct hdd_mdns_resp_info *response_dst,
16861 struct hdd_mdns_resp_info *response_src,
16862 uint8_t num_matched)
16863{
16864 uint8_t num, num_diff;
16865 uint16_t value, idx;
16866 uint8_t len = 0;
16867
16868 if ((response_src == NULL) || (response_dst == NULL) ||
16869 (resp_info == NULL)) {
16870 hddLog(LOGE, FL("response info is NULL!"));
16871 return FALSE;
16872 }
16873
16874 if (response_dst->num_entries < num_matched) {
16875 hddLog(LOGE, FL("num_entries is less than num_matched!"));
16876 return FALSE;
16877 }
16878
16879 if (resp_info->resp_len >= MAX_MDNS_RESP_LEN) {
16880 hddLog(LOGE, FL("resp_len exceeds %d!"), MAX_MDNS_RESP_LEN);
16881 return FALSE;
16882 }
16883
16884 num_diff = response_dst->num_entries - num_matched;
16885 if ((num_diff > 0) && (response_dst->data == NULL)) {
16886 hddLog(LOGE, FL("response_dst->data is NULL!"));
16887 return FALSE;
16888 }
16889
16890 /*
16891 * Handle the unmatched string at the beginning
16892 * Store the length of octets and the octets
16893 */
16894 for (num = 0; num < num_diff; num++) {
16895 response_dst->offset[num] =
16896 resp_info->resp_len + MDNS_HEADER_LEN;
16897 idx = num * MAX_LEN_DOMAINNAME_FIELD;
16898 len = strlen((char *)&response_dst->data[idx]);
16899 if ((resp_info->resp_len + len + 1) >= MAX_MDNS_RESP_LEN) {
16900 hddLog(LOGE, FL("resp_len exceeds %d!"),
16901 MAX_MDNS_RESP_LEN);
16902 return FALSE;
16903 }
16904 resp_info->resp_data[resp_info->resp_len] = len;
16905 resp_info->resp_len++;
16906 vos_mem_copy(&resp_info->resp_data[resp_info->resp_len],
16907 &response_dst->data[idx], len);
16908 resp_info->resp_len += len;
16909 }
16910 /*
16911 * Handle the matched string from the end
16912 * Just keep the offset and mask the leading two bit
16913 */
16914 if (response_src->num_entries >= num_matched) {
16915 num_diff = response_src->num_entries - num_matched;
16916 value = response_src->offset[num_diff];
16917 if (value > 0) {
16918 value |= 0xc000;
16919 if ((resp_info->resp_len + sizeof(uint16_t)) >=
16920 MAX_MDNS_RESP_LEN) {
16921 hddLog(LOGE, FL("resp_len exceeds %d!"),
16922 MAX_MDNS_RESP_LEN);
16923 return FALSE;
16924 }
16925 wlan_hdd_mdns_format_response_u16(value, resp_info);
16926 return TRUE;
16927 }
16928 }
16929 return FALSE;
16930}
16931
16932/**
16933 * wlan_hdd_mdns_reset_response() - Reset the response info
16934 * @response: The response which info is reset.
16935 *
16936 * Return: None
16937 */
16938static void wlan_hdd_mdns_reset_response(struct hdd_mdns_resp_info *response)
16939{
16940 if (response == NULL)
16941 return;
16942 response->num_entries = 0;
16943 response->data = NULL;
16944 response->offset = NULL;
16945}
16946
16947/**
16948 * wlan_hdd_mdns_init_response() - Initialize the response info
16949 * @response: The response which info is initiatized.
16950 * @resp_dname: The domain name string which might be tokenized.
16951 *
16952 * This function will allocate the memory for both response->data and
16953 * response->offset. Besides, it will also tokenize the domain name to some
16954 * entries and fill response->num_entries with the num of entries.
16955 *
16956 * Return: Return boolean. TRUE for success, FALSE for fail.
16957 */
16958static bool wlan_hdd_mdns_init_response(struct hdd_mdns_resp_info *response,
16959 uint8_t *resp_dname, char separator)
16960{
16961 uint16_t size;
16962
16963 if ((resp_dname == NULL) || (response == NULL)) {
16964 hddLog(LOGE, FL("resp_dname or response is NULL!"));
16965 return FALSE;
16966 }
16967
16968 size = MAX_NUM_FIELD_DOMAINNAME * MAX_LEN_DOMAINNAME_FIELD;
16969 response->data = vos_mem_malloc(size);
16970 if (response->data) {
16971 vos_mem_zero(response->data, size);
16972 if (VOS_STATUS_SUCCESS !=
16973 hdd_string_to_string_array((char *)resp_dname,
16974 response->data,
16975 separator,
16976 &response->num_entries,
16977 MAX_NUM_FIELD_DOMAINNAME,
16978 MAX_LEN_DOMAINNAME_FIELD)) {
16979 hddLog(LOGE, FL("hdd_string_to_string_array fail!"));
16980 goto err_init_resp;
16981 }
16982
16983 if ((response->num_entries > 0) &&
16984 (strlen((char *)&response->data[0]) > 0)) {
16985 size = sizeof(uint16_t) * response->num_entries;
16986 response->offset = vos_mem_malloc(size);
16987 if (response->offset) {
16988 vos_mem_zero(response->offset, size);
16989 return TRUE;
16990 }
16991 }
16992 }
16993
16994err_init_resp:
16995 if (response->data)
16996 vos_mem_free(response->data);
16997 wlan_hdd_mdns_reset_response(response);
16998 return FALSE;
16999}
17000
17001/**
17002 * wlan_hdd_mdns_find_entries_from_end() - Find the matched entries
17003 * @response1: The response info is used to be compared.
17004 * @response2: The response info is used to be compared.
17005 *
17006 * This function will find the matched entries from the end.
17007 *
17008 * Return: Return the number of the matched entries.
17009 */
17010static uint8_t
17011wlan_hdd_mdns_find_entries_from_end(struct hdd_mdns_resp_info *response1,
17012 struct hdd_mdns_resp_info *response2)
17013{
17014 uint8_t min, len1, i;
17015 uint16_t num1, num2;
17016 uint8_t num_matched = 0;
17017
17018 min = VOS_MIN(response1->num_entries, response2->num_entries);
17019
17020 for (i = 1; i <= min; i++) {
17021 num1 = (response1->num_entries - i);
17022 num1 *= MAX_LEN_DOMAINNAME_FIELD;
17023 num2 = (response2->num_entries - i);
17024 num2 *= MAX_LEN_DOMAINNAME_FIELD;
17025 len1 = strlen((char *)&response1->data[num1]);
17026
17027 if ((len1 == 0) ||
17028 (len1 != strlen((char *)&response2->data[num2])))
17029 break;
17030 if (memcmp(&response1->data[num1],
17031 &response2->data[num2], len1))
17032 break;
17033 else
17034 num_matched++;
17035 }
17036
17037 return num_matched;
17038}
17039
17040/**
17041 * wlan_hdd_mdns_find_max() - Find the maximum number of the matched entries
17042 * @matchedlist: Pointer to the array of struct hdd_mdns_resp_matched
17043 * @numlist: The number of the elements in the array matchedlist.
17044 *
17045 * Find the max number of the matched entries among the array matchedlist.
17046 *
17047 * Return: None
17048 */
17049static void wlan_hdd_mdns_find_max(struct hdd_mdns_resp_matched *matchedlist,
17050 uint8_t numlist)
17051{
17052 int j;
17053 struct hdd_mdns_resp_matched tmp;
17054
17055 /* At least two values are used for sorting */
17056 if ((numlist < 2) || (matchedlist == NULL)) {
17057 hddLog(LOGE, FL("At least two values are used for sorting!"));
17058 return;
17059 }
17060
17061 for (j = 0; j < numlist-1; j++) {
17062 if (matchedlist[j].num_matched >
17063 matchedlist[j+1].num_matched) {
17064 vos_mem_copy(&tmp, &matchedlist[j],
17065 sizeof(struct hdd_mdns_resp_matched));
17066 vos_mem_copy(&matchedlist[j], &matchedlist[j+1],
17067 sizeof(struct hdd_mdns_resp_matched));
17068 vos_mem_copy(&matchedlist[j+1], &tmp,
17069 sizeof(struct hdd_mdns_resp_matched));
17070 }
17071 }
17072}
17073
17074/**
17075 * wlan_hdd_mdns_pack_response_type_a() - Pack Type A response
17076 * @ini_config: Pointer to the struct hdd_config_t
17077 * @resp_info: Pointer to the struct tSirMDNSResponseInfo
17078 * @resptype_a: Pointer to the struct hdd_mdns_resp_info of Type A
17079 *
17080 * Type A response include QName, response type, class, TTL and Ipv4.
17081 *
17082 * Return: Return boolean. TRUE for success, FALSE for fail.
17083 */
17084static bool
17085wlan_hdd_mdns_pack_response_type_a(hdd_config_t *ini_config,
17086 sir_mdns_resp_info resp_info,
17087 struct hdd_mdns_resp_info *resptype_a)
17088{
17089 uint16_t value;
17090 uint32_t len;
17091
17092 ENTER();
17093 if ((ini_config == NULL) || (resp_info == NULL) ||
17094 (resptype_a == NULL)) {
17095 hddLog(LOGE, FL("ini_config or response info is NULL!"));
17096 return FALSE;
17097 }
17098
17099 /* No Type A response */
17100 if (strlen((char *)ini_config->mdns_resp_type_a) <= 0)
17101 return TRUE;
17102
17103 /* Wrong response is assigned, just ignore this response */
17104 if (!wlan_hdd_mdns_init_response(resptype_a,
17105 ini_config->mdns_resp_type_a, '.'))
17106 return TRUE;
17107
17108 /* Process response domain name */
17109 if (!wlan_hdd_mdns_process_response_dname(resptype_a, resp_info)) {
17110 hddLog(LOGE, FL("Fail to process mDNS response (%d)!"),
17111 MDNS_TYPE_A);
17112 return FALSE;
17113 }
17114
17115 /* Process response Type, Class, TTL */
17116 if (!wlan_hdd_mdns_process_response_misc(MDNS_TYPE_A, resp_info)) {
17117 hddLog(LOGE, FL("Fail to process mDNS misc response (%d)!"),
17118 MDNS_TYPE_A);
17119 return FALSE;
17120 }
17121
17122 /* Process response RDLength, RData */
17123 len = sizeof(uint16_t) + sizeof(uint32_t);
17124 len += resp_info->resp_len;
17125 if (len >= MAX_MDNS_RESP_LEN) {
17126 hddLog(LOGE, FL("resp_len exceeds %d!"), MAX_MDNS_RESP_LEN);
17127 return FALSE;
17128 }
17129 value = sizeof(uint32_t);
17130 wlan_hdd_mdns_format_response_u16(value, resp_info);
17131 wlan_hdd_mdns_format_response_u32(ini_config->mdns_resp_type_a_ipv4,
17132 resp_info);
17133
17134 EXIT();
17135 return TRUE;
17136}
17137
17138/**
17139 * wlan_hdd_mdns_pack_response_type_txt() - Pack Type Txt response
17140 * @ini_config: Pointer to the struct hdd_config_t
17141 * @resp_info: Pointer to the struct tSirMDNSResponseInfo
17142 * @resptype_txt: Pointer to the struct hdd_mdns_resp_info of Type txt
17143 * @resptype_a: Pointer to the struct hdd_mdns_resp_info of Type A
17144 *
17145 * Type Txt response include QName, response type, class, TTL and text content.
17146 * Also, it will find the matched QName from resptype_A and compress the data.
17147 *
17148 * Return: Return boolean. TRUE for success, FALSE for fail.
17149 */
17150static bool
17151wlan_hdd_mdns_pack_response_type_txt(hdd_config_t *ini_config,
17152 sir_mdns_resp_info resp_info,
17153 struct hdd_mdns_resp_info *resptype_txt,
17154 struct hdd_mdns_resp_info *resptype_a)
17155{
17156 uint8_t num_matched;
17157 uint8_t num;
17158 uint16_t idx;
17159 uint16_t value = 0;
17160 uint32_t len;
17161 uint32_t total_len;
17162 bool status;
17163 struct hdd_mdns_resp_info resptype_content;
17164
17165 ENTER();
17166
17167 if ((ini_config == NULL) || (resp_info == NULL) ||
17168 (resptype_txt == NULL)) {
17169 hddLog(LOGE, FL("ini_config or response info is NULL!"));
17170 return FALSE;
17171 }
17172
17173 /* No Type Txt response */
17174 if (strlen((char *)ini_config->mdns_resp_type_txt) <= 0)
17175 return TRUE;
17176
17177 /* Wrong response is assigned, just ignore this response */
17178 if (!wlan_hdd_mdns_init_response(resptype_txt,
17179 ini_config->mdns_resp_type_txt, '.'))
17180 return TRUE;
17181
17182 /*
17183 * For data compression
17184 * Check if any strings are matched with Type A response
17185 */
17186 if (resptype_a && (resptype_a->num_entries > 0)) {
17187 num_matched = wlan_hdd_mdns_find_entries_from_end(resptype_txt,
17188 resptype_a);
17189 if (num_matched > 0) {
17190 if (!wlan_hdd_mdns_compress_data(resp_info,
17191 resptype_txt, resptype_a, num_matched)) {
17192 hddLog(LOGE, FL("Fail to compress mDNS "
17193 "response (%d)!"), MDNS_TYPE_TXT);
17194 return FALSE;
17195 }
17196 } else {
17197 /*
17198 * num_matched is zero. Error!
17199 * At least ".local" is needed.
17200 */
17201 hddLog(LOGE, FL("No matched string! Fail to pack mDNS "
17202 "response (%d)!"), MDNS_TYPE_TXT);
17203 return FALSE;
17204 }
17205 } else {
17206 /* no TypeA response, so show the whole data */
17207 if (!wlan_hdd_mdns_process_response_dname(resptype_txt,
17208 resp_info)) {
17209 hddLog(LOGE, FL("Fail to process mDNS response (%d)!"),
17210 MDNS_TYPE_TXT);
17211 return FALSE;
17212 }
17213 }
17214
17215 /* Process response Type, Class, TTL */
17216 if (!wlan_hdd_mdns_process_response_misc(MDNS_TYPE_TXT, resp_info)) {
17217 hddLog(LOGE, FL("Fail to process mDNS misc response (%d)!"),
17218 MDNS_TYPE_TXT);
17219 return FALSE;
17220 }
17221
17222 /*
17223 * Process response RDLength, RData.
17224 * TypeTxt RData include len.
17225 */
17226 status = wlan_hdd_mdns_init_response(&resptype_content,
17227 ini_config->mdns_resp_type_txt_content,
17228 '/');
17229 if (status == FALSE) {
17230 hddLog(LOGE, FL("wlan_hdd_mdns_init_response FAIL"));
17231 return FALSE;
17232 }
17233
17234 for (num = 0; num < resptype_content.num_entries; num++) {
17235 idx = num * MAX_LEN_DOMAINNAME_FIELD;
17236 value += strlen((char *)&resptype_content.data[idx]);
17237 }
17238
17239 /* content len is uint16_t */
17240 total_len = sizeof(uint16_t);
17241 total_len += resp_info->resp_len + value +
17242 resptype_content.num_entries;
17243
17244 if (total_len >= MAX_MDNS_RESP_LEN) {
17245 hddLog(LOGE, FL("resp_len exceeds %d!"), MAX_MDNS_RESP_LEN);
17246 return FALSE;
17247 }
17248 wlan_hdd_mdns_format_response_u16(value + resptype_content.num_entries,
17249 resp_info);
17250
17251 for (num = 0; num < resptype_content.num_entries; num++) {
17252 idx = num * MAX_LEN_DOMAINNAME_FIELD;
17253 len = strlen((char *)&resptype_content.data[idx]);
17254 resp_info->resp_data[resp_info->resp_len] = len;
17255 resp_info->resp_len++;
17256
17257 vos_mem_copy(&resp_info->resp_data[resp_info->resp_len],
17258 &resptype_content.data[idx], len);
17259
17260 resp_info->resp_len += len;
17261 hddLog(LOG1, FL("index = %d, len = %d, str = %s"),
17262 num, len, &resptype_content.data[idx]);
17263 }
17264
17265 EXIT();
17266 return TRUE;
17267}
17268
17269/**
17270 * wlan_hdd_mdns_pack_response_type_ptr_dname() - Pack Type PTR domain name
17271 * @ini_config: Pointer to the struct hdd_config_t
17272 * @resp_info: Pointer to the struct tSirMDNSResponseInfo
17273 * @resptype_ptr_dn: Pointer to the struct hdd_mdns_resp_info of Type Ptr
17274 * domain name
17275 * @resptype_ptr: Pointer to the struct hdd_mdns_resp_info of Type Ptr
17276 * @resptype_txt: Pointer to the struct hdd_mdns_resp_info of Type Txt
17277 * @resptype_a: Pointer to the struct hdd_mdns_resp_info of Type A
17278 *
17279 * The Type Ptr response include Type PTR domain name in its data field.
17280 * Also, it will find the matched QName from the existing resptype_ptr,
17281 * resptype_txt, resptype_a and then compress the data.
17282 *
17283 * Return: Return boolean. TRUE for success, FALSE for fail.
17284 */
17285static bool
17286wlan_hdd_mdns_pack_response_type_ptr_dname(hdd_config_t *ini_config,
17287 sir_mdns_resp_info resp_info,
17288 struct hdd_mdns_resp_info *resptype_ptr_dn,
17289 struct hdd_mdns_resp_info *resptype_ptr,
17290 struct hdd_mdns_resp_info *resptype_txt,
17291 struct hdd_mdns_resp_info *resptype_a)
17292{
17293 uint8_t num_matched, numlist, size;
17294 struct hdd_mdns_resp_matched matchedlist[MAX_MDNS_RESP_TYPE-1];
17295 struct hdd_mdns_resp_info *resp;
17296
17297 if ((ini_config == NULL) || (resp_info == NULL) ||
17298 (resptype_ptr == NULL) || (resptype_ptr_dn == NULL)) {
17299 hddLog(LOGE, FL("ini_config or response info is NULL!"));
17300 return FALSE;
17301 }
17302
17303 /* No Type Ptr domain name response */
17304 if (strlen((char *)ini_config->mdns_resp_type_ptr_dname) <= 0)
17305 return TRUE;
17306
17307 /* Wrong response is assigned, just ignore this response */
17308 if (!wlan_hdd_mdns_init_response(resptype_ptr_dn,
17309 ini_config->mdns_resp_type_ptr_dname, '.'))
17310 return TRUE;
17311
17312 /*
17313 * For data compression
17314 * Check if any strings are matched with previous
17315 * response.
17316 */
17317 numlist = 0;
17318 size = (MAX_MDNS_RESP_TYPE-1);
17319 size *= sizeof(struct hdd_mdns_resp_matched);
17320 vos_mem_zero(matchedlist, size);
17321 num_matched = wlan_hdd_mdns_find_entries_from_end(resptype_ptr_dn,
17322 resptype_ptr);
17323 if (num_matched > 0) {
17324 matchedlist[numlist].num_matched = num_matched;
17325 matchedlist[numlist].type = MDNS_TYPE_PTR;
17326 numlist++;
17327 }
17328 if (resptype_txt && (resptype_txt->num_entries > 0)) {
17329 num_matched = wlan_hdd_mdns_find_entries_from_end(
17330 resptype_ptr_dn, resptype_txt);
17331 if (num_matched > 0) {
17332 matchedlist[numlist].num_matched = num_matched;
17333 matchedlist[numlist].type = MDNS_TYPE_TXT;
17334 numlist++;
17335 }
17336 }
17337 if (resptype_a && (resptype_a->num_entries > 0)) {
17338 num_matched = wlan_hdd_mdns_find_entries_from_end(
17339 resptype_ptr_dn,resptype_a);
17340 if (num_matched > 0) {
17341 matchedlist[numlist].num_matched = num_matched;
17342 matchedlist[numlist].type = MDNS_TYPE_A;
17343 numlist++;
17344 }
17345 }
17346 if (numlist > 0) {
17347 if (numlist > 1)
17348 wlan_hdd_mdns_find_max(matchedlist, numlist);
17349 resp = NULL;
17350 switch (matchedlist[numlist-1].type) {
17351 case MDNS_TYPE_A:
17352 resp = resptype_a;
17353 break;
17354 case MDNS_TYPE_TXT:
17355 resp = resptype_txt;
17356 break;
17357 case MDNS_TYPE_PTR:
17358 resp = resptype_ptr;
17359 break;
17360 default:
17361 hddLog(LOGE, FL("Fail to compress mDNS response "
17362 "(%d)!"), MDNS_TYPE_PTR_DNAME);
17363 return FALSE;
17364 }
17365 num_matched = matchedlist[numlist-1].num_matched;
17366 if (!wlan_hdd_mdns_compress_data(resp_info, resptype_ptr_dn,
17367 resp, num_matched)) {
17368 hddLog(LOGE, FL("Fail to compress mDNS response "
17369 "(%d)!"), MDNS_TYPE_PTR_DNAME);
17370 return FALSE;
17371 }
17372 } else {
17373 /* num = 0 -> no matched string */
17374 if (!wlan_hdd_mdns_process_response_dname(resptype_ptr_dn,
17375 resp_info)) {
17376 hddLog(LOGE, FL("Fail to process mDNS response (%d)!"),
17377 MDNS_TYPE_PTR_DNAME);
17378 return FALSE;
17379 }
17380 }
17381
17382 return TRUE;
17383}
17384
17385/**
17386 * wlan_hdd_mdns_pack_response_type_ptr() - Pack Type PTR response
17387 * @ini_config: Pointer to the struct hdd_config_t
17388 * @resp_info: Pointer to the struct tSirMDNSResponseInfo
17389 * @resptype_ptr: Pointer to the struct hdd_mdns_resp_info of Type Ptr
17390 * @resptype_ptr_dn: Pointer to the struct hdd_mdns_resp_info of Type Ptr
17391 * domain name
17392 * @resptype_txt: Pointer to the struct hdd_mdns_resp_info of Type Txt
17393 * @resptype_a: Pointer to the struct hdd_mdns_resp_info of Type A
17394 *
17395 * The Type Ptr response include QName, response type, class, TTL and
17396 * Type PTR domain name. Also, it will find the matched QName from the
17397 * existing resptype_txt, resptype_a and then compress the data.
17398 *
17399 * Return: Return boolean. TRUE for success, FALSE for fail.
17400 */
17401static bool
17402wlan_hdd_mdns_pack_response_type_ptr(hdd_config_t *ini_config,
17403 sir_mdns_resp_info resp_info,
17404 struct hdd_mdns_resp_info *resptype_ptr,
17405 struct hdd_mdns_resp_info *resptype_ptr_dn,
17406 struct hdd_mdns_resp_info *resptype_txt,
17407 struct hdd_mdns_resp_info *resptype_a)
17408{
17409 uint8_t num_matched, num_matched1;
17410 uint16_t value;
17411 uint8_t val_u8;
17412 uint32_t offset_data_len, len;
17413
17414 ENTER();
17415 if ((ini_config == NULL) || (resp_info == NULL) ||
17416 (resptype_ptr == NULL) || (resptype_ptr_dn == NULL)) {
17417 hddLog(LOGE, FL("ini_config or response info is NULL!"));
17418 return FALSE;
17419 }
17420
17421 /* No Type Ptr response */
17422 if (strlen((char *)ini_config->mdns_resp_type_ptr) <= 0)
17423 return TRUE;
17424
17425 /* Wrong response is assigned, just ignore this response */
17426 if (!wlan_hdd_mdns_init_response(resptype_ptr,
17427 ini_config->mdns_resp_type_ptr, '.'))
17428 return TRUE;
17429
17430 /*
17431 * For data compression
17432 * Check if any strings are matched with Type A response
17433 */
17434 num_matched = 0;
17435 num_matched1 = 0;
17436 if (resptype_a && (resptype_a->num_entries > 0)) {
17437 num_matched = wlan_hdd_mdns_find_entries_from_end(resptype_ptr,
17438 resptype_a);
17439 }
17440 if (resptype_txt && (resptype_txt->num_entries > 0)) {
17441 num_matched1 = wlan_hdd_mdns_find_entries_from_end(
17442 resptype_ptr, resptype_txt);
17443 }
17444 if ((num_matched != num_matched1) ||
17445 ((num_matched > 0) && (num_matched1 > 0))) {
17446 if (num_matched >= num_matched1) {
17447 if (!wlan_hdd_mdns_compress_data(resp_info,
17448 resptype_ptr, resptype_a, num_matched)) {
17449 hddLog(LOGE, FL("Fail to compress mDNS "
17450 "response (%d)!"), MDNS_TYPE_PTR);
17451 return FALSE;
17452 }
17453 } else {
17454 /* num_matched is less than num_matched1 */
17455 if (!wlan_hdd_mdns_compress_data(resp_info,
17456 resptype_ptr, resptype_txt, num_matched1)) {
17457 hddLog(LOGE, FL("Fail to compress mDNS "
17458 "response (%d)!"), MDNS_TYPE_PTR);
17459 return FALSE;
17460 }
17461 }
17462 } else {
17463 /*
17464 * Both num_matched and num_matched1 are zero.
17465 * no TypeA & TypeTxt
17466 */
17467 if (!wlan_hdd_mdns_process_response_dname(resptype_ptr,
17468 resp_info)) {
17469 hddLog(LOGE, FL("Fail to process mDNS response (%d)!"),
17470 MDNS_TYPE_PTR);
17471 return FALSE;
17472 }
17473 }
17474
17475 /* Process response Type, Class, TTL */
17476 if (!wlan_hdd_mdns_process_response_misc(MDNS_TYPE_PTR, resp_info)) {
17477 hddLog(LOGE, FL("Fail to process mDNS misc response (%d)!"),
17478 MDNS_TYPE_PTR);
17479 return FALSE;
17480 }
17481
17482 /*
17483 * Process response RDLength, RData (Ptr domain name)
17484 * Save the offset of RData length
17485 */
17486 offset_data_len = resp_info->resp_len;
17487 resp_info->resp_len += sizeof(uint16_t);
17488
17489 if (!wlan_hdd_mdns_pack_response_type_ptr_dname(ini_config, resp_info,
17490 resptype_ptr_dn, resptype_ptr,
17491 resptype_txt, resptype_a)) {
17492 return FALSE;
17493 }
17494 /* Set the RData length */
17495 len = offset_data_len + sizeof(uint16_t);
17496 if ((resptype_ptr_dn->num_entries > 0) &&
17497 (resp_info->resp_len > len)) {
17498 value = resp_info->resp_len - len;
17499 val_u8 = (value & 0xff00) >> 8;
17500 resp_info->resp_data[offset_data_len] = val_u8;
17501 val_u8 = value & 0xff;
17502 resp_info->resp_data[offset_data_len+1] = val_u8;
17503 } else {
17504 hddLog(LOGE, FL("Fail to process mDNS response (%d)!"),
17505 MDNS_TYPE_PTR);
17506 return FALSE;
17507 }
17508
17509 EXIT();
17510 return TRUE;
17511}
17512
17513/**
17514 * wlan_hdd_mdns_pack_response_type_srv_target()- Pack Type Service Target
17515 * @ini_config: Pointer to the struct hdd_config_t
17516 * @resp_info: Pointer to the struct tSirMDNSResponseInfo
17517 * @resptype_srv_tgt: Pointer to the struct hdd_mdns_resp_info of Type Srv
17518 * target
17519 * @resptype_srv: Pointer to the struct hdd_mdns_resp_info of Type Srv
17520 * @resptype_ptr: Pointer to the struct hdd_mdns_resp_info of Type Ptr
17521 * @resptype_ptr_dn: Pointer to the struct hdd_mdns_resp_info of Type Ptr
17522 * domain name
17523 * @resptype_txt: Pointer to the struct hdd_mdns_resp_info of Type Txt
17524 * @resptype_a: Pointer to the struct hdd_mdns_resp_info of Type A
17525 *
17526 * The Type service target is one of the data field in the Type SRV response.
17527 * Also, it will find the matched QName from the existing resptype_srv,
17528 * resptype_ptr, resptype_ptr_dn, resptype_txt, resptype_a and then compress
17529 * the data.
17530 *
17531 * Return: Return boolean. TRUE for success, FALSE for fail.
17532 */
17533static bool
17534wlan_hdd_mdns_pack_response_type_srv_target(hdd_config_t *ini_config,
17535 sir_mdns_resp_info resp_info,
17536 struct hdd_mdns_resp_info *resptype_srv_tgt,
17537 struct hdd_mdns_resp_info *resptype_srv,
17538 struct hdd_mdns_resp_info *resptype_ptr,
17539 struct hdd_mdns_resp_info *resptype_ptr_dn,
17540 struct hdd_mdns_resp_info *resptype_txt,
17541 struct hdd_mdns_resp_info *resptype_a)
17542{
17543 uint8_t num_matched, num, size;
17544 struct hdd_mdns_resp_matched matchedlist[MAX_MDNS_RESP_TYPE-1];
17545 struct hdd_mdns_resp_info *resp;
17546
17547 if ((ini_config == NULL) || (resp_info == NULL) ||
17548 (resptype_srv == NULL) || (resptype_srv_tgt == NULL)) {
17549 hddLog(LOGE, FL("ini_config or response info is NULL!"));
17550 return FALSE;
17551 }
17552
17553 /* No Type Srv Target response */
17554 if (strlen((char *)ini_config->mdns_resp_type_srv_target) <= 0)
17555 return TRUE;
17556
17557 /* Wrong response is assigned, just ignore this response */
17558 if (!wlan_hdd_mdns_init_response(resptype_srv_tgt,
17559 ini_config->mdns_resp_type_srv_target, '.'))
17560 return TRUE;
17561
17562 /*
17563 * For data compression
17564 * Check if any strings are matched with previous response.
17565 */
17566 num = 0;
17567 size = (MAX_MDNS_RESP_TYPE-1);
17568 size *= sizeof(struct hdd_mdns_resp_matched);
17569 vos_mem_zero(matchedlist, size);
17570 num_matched = wlan_hdd_mdns_find_entries_from_end(resptype_srv_tgt,
17571 resptype_srv);
17572 if (num_matched > 0) {
17573 matchedlist[num].num_matched = num_matched;
17574 matchedlist[num].type = MDNS_TYPE_SRV;
17575 num++;
17576 }
17577 if (resptype_ptr && (resptype_ptr->num_entries > 0)) {
17578 if (resptype_ptr_dn && (resptype_ptr_dn->num_entries > 0)) {
17579 num_matched = wlan_hdd_mdns_find_entries_from_end(
17580 resptype_srv_tgt, resptype_ptr_dn);
17581 if (num_matched > 0) {
17582 matchedlist[num].num_matched = num_matched;
17583 matchedlist[num].type = MDNS_TYPE_PTR_DNAME;
17584 num++;
17585 }
17586 }
17587 num_matched = wlan_hdd_mdns_find_entries_from_end(
17588 resptype_srv_tgt, resptype_ptr);
17589 if (num_matched > 0) {
17590 matchedlist[num].num_matched = num_matched;
17591 matchedlist[num].type = MDNS_TYPE_PTR;
17592 num++;
17593 }
17594 }
17595 if (resptype_txt && (resptype_txt->num_entries > 0)) {
17596 num_matched = wlan_hdd_mdns_find_entries_from_end(
17597 resptype_srv_tgt, resptype_txt);
17598 if (num_matched > 0) {
17599 matchedlist[num].num_matched = num_matched;
17600 matchedlist[num].type = MDNS_TYPE_TXT;
17601 num++;
17602 }
17603 }
17604 if (resptype_a && (resptype_a->num_entries > 0)) {
17605 num_matched = wlan_hdd_mdns_find_entries_from_end(
17606 resptype_srv_tgt, resptype_a);
17607 if (num_matched > 0) {
17608 matchedlist[num].num_matched = num_matched;
17609 matchedlist[num].type = MDNS_TYPE_A;
17610 num++;
17611 }
17612 }
17613 if (num > 0) {
17614 if (num > 1)
17615 wlan_hdd_mdns_find_max(matchedlist, num);
17616 resp = NULL;
17617 switch (matchedlist[num-1].type) {
17618 case MDNS_TYPE_A:
17619 resp = resptype_a;
17620 break;
17621 case MDNS_TYPE_TXT:
17622 resp = resptype_txt;
17623 break;
17624 case MDNS_TYPE_PTR:
17625 resp = resptype_ptr;
17626 break;
17627 case MDNS_TYPE_PTR_DNAME:
17628 resp = resptype_ptr_dn;
17629 break;
17630 case MDNS_TYPE_SRV:
17631 resp = resptype_srv;
17632 break;
17633 default:
17634 hddLog(LOGE, FL("Fail to compress mDNS response "
17635 "(%d)!"), MDNS_TYPE_SRV_TARGET);
17636 return FALSE;
17637 }
17638 num_matched = matchedlist[num-1].num_matched;
17639 if (!wlan_hdd_mdns_compress_data(resp_info, resptype_srv_tgt,
17640 resp, num_matched)) {
17641 hddLog(LOGE, FL("Fail to compress mDNS response "
17642 "(%d)!"), MDNS_TYPE_SRV_TARGET);
17643 return FALSE;
17644 }
17645 } else {
17646 /* num = 0 -> no matched string */
17647 if (!wlan_hdd_mdns_process_response_dname(resptype_srv_tgt,
17648 resp_info)) {
17649 hddLog(LOGE, FL("Fail to process mDNS response (%d)!"),
17650 MDNS_TYPE_SRV_TARGET);
17651 return FALSE;
17652 }
17653 }
17654
17655 return TRUE;
17656}
17657
17658/**
17659 * wlan_hdd_mdns_pack_response_type_srv()- Pack Type Service response
17660 * @ini_config: Pointer to the struct hdd_config_t
17661 * @resp_info: Pointer to the struct tSirMDNSResponseInfo
17662 * @resptype_srv: Pointer to the struct hdd_mdns_resp_info of Type Srv
17663 * @resptype_srv_tgt: Pointer to the struct hdd_mdns_resp_info of Type Srv
17664 * target
17665 * @resptype_ptr: Pointer to the struct hdd_mdns_resp_info of Type Ptr
17666 * @resptype_ptr_dn: Pointer to the struct hdd_mdns_resp_info of Type Ptr
17667 * domain name
17668 * @resptype_txt: Pointer to the struct hdd_mdns_resp_info of Type Txt
17669 * @resptype_a: Pointer to the struct hdd_mdns_resp_info of Type A
17670 *
17671 * The Type SRV (Service) response include QName, response type, class, TTL
17672 * and four kinds of data fields. Also, it will find the matched QName from
17673 * the existing resptype_ptr, resptype_ptr_dn, resptype_txt, resptype_a and
17674 * then compress the data.
17675 *
17676 * Return: Return boolean. TRUE for success, FALSE for fail.
17677 */
17678static bool
17679wlan_hdd_mdns_pack_response_type_srv(hdd_config_t *ini_config,
17680 sir_mdns_resp_info resp_info,
17681 struct hdd_mdns_resp_info *resptype_srv,
17682 struct hdd_mdns_resp_info *resptype_srv_tgt,
17683 struct hdd_mdns_resp_info *resptype_ptr,
17684 struct hdd_mdns_resp_info *resptype_ptr_dn,
17685 struct hdd_mdns_resp_info *resptype_txt,
17686 struct hdd_mdns_resp_info *resptype_a)
17687{
17688 uint8_t num_matched, num, size;
17689 uint16_t value;
17690 uint8_t val_u8;
17691 uint32_t offset_data_len, len;
17692 struct hdd_mdns_resp_info *resp;
17693 struct hdd_mdns_resp_matched matchedlist[MAX_MDNS_RESP_TYPE-1];
17694
17695 ENTER();
17696
17697 if ((ini_config == NULL) || (resp_info == NULL) ||
17698 (resptype_srv == NULL) || (resptype_srv_tgt == NULL)) {
17699 hddLog(LOGE, FL("ini_config or response info is NULL!"));
17700 return FALSE;
17701 }
17702
17703 /* No Type Srv response */
17704 if (strlen((char *)ini_config->mdns_resp_type_srv) <= 0)
17705 return TRUE;
17706
17707 /* Wrong response is assigned, just ignore this response */
17708 if (!wlan_hdd_mdns_init_response(resptype_srv,
17709 ini_config->mdns_resp_type_srv, '.'))
17710 return TRUE;
17711
17712 /*
17713 * For data compression
17714 * Check if any strings are matched with Type A response
17715 */
17716 num = 0;
17717 size = (MAX_MDNS_RESP_TYPE-1);
17718 size *= sizeof(struct hdd_mdns_resp_matched);
17719 vos_mem_zero(matchedlist, size);
17720 if (resptype_ptr && (resptype_ptr->num_entries > 0)) {
17721 if (resptype_ptr_dn && (resptype_ptr_dn->num_entries > 0)) {
17722 num_matched = wlan_hdd_mdns_find_entries_from_end(
17723 resptype_srv,
17724 resptype_ptr_dn);
17725 if (num_matched > 0) {
17726 matchedlist[num].num_matched = num_matched;
17727 matchedlist[num].type = MDNS_TYPE_PTR_DNAME;
17728 num++;
17729 }
17730 }
17731 num_matched = wlan_hdd_mdns_find_entries_from_end(resptype_srv,
17732 resptype_ptr);
17733 if (num_matched > 0) {
17734 matchedlist[num].num_matched = num_matched;
17735 matchedlist[num].type = MDNS_TYPE_PTR;
17736 num++;
17737 }
17738 }
17739 if (resptype_txt && (resptype_txt->num_entries > 0)) {
17740 num_matched = wlan_hdd_mdns_find_entries_from_end(resptype_srv,
17741 resptype_txt);
17742 if (num_matched > 0) {
17743 matchedlist[num].num_matched =num_matched;
17744 matchedlist[num].type = MDNS_TYPE_TXT;
17745 num++;
17746 }
17747 }
17748 if (resptype_a && (resptype_a->num_entries > 0)) {
17749 num_matched = wlan_hdd_mdns_find_entries_from_end(resptype_srv,
17750 resptype_a);
17751 if (num_matched > 0) {
17752 matchedlist[num].num_matched = num_matched;
17753 matchedlist[num].type = MDNS_TYPE_A;
17754 num++;
17755 }
17756 }
17757 if (num > 0) {
17758 if (num > 1)
17759 wlan_hdd_mdns_find_max(matchedlist, num);
17760 resp = NULL;
17761 switch (matchedlist[num-1].type) {
17762 case MDNS_TYPE_A:
17763 resp = resptype_a;
17764 break;
17765 case MDNS_TYPE_TXT:
17766 resp = resptype_txt;
17767 break;
17768 case MDNS_TYPE_PTR:
17769 resp = resptype_ptr;
17770 break;
17771 case MDNS_TYPE_PTR_DNAME:
17772 resp = resptype_ptr_dn;
17773 break;
17774 default:
17775 hddLog(LOGE, FL("Fail to compress mDNS response "
17776 "(%d)!"), MDNS_TYPE_SRV);
17777 return FALSE;
17778 }
17779 num_matched = matchedlist[num-1].num_matched;
17780 if (!wlan_hdd_mdns_compress_data(resp_info, resptype_srv,
17781 resp, num_matched)) {
17782 hddLog(LOGE, FL("Fail to compress mDNS response "
17783 "(%d)!"), MDNS_TYPE_SRV);
17784 return FALSE;
17785 }
17786 } else {
17787 /* num = 0 -> no matched string */
17788 if (!wlan_hdd_mdns_process_response_dname(resptype_srv,
17789 resp_info)) {
17790 hddLog(LOGE, FL("Fail to process mDNS response (%d)!"),
17791 MDNS_TYPE_SRV);
17792 return FALSE;
17793 }
17794 }
17795
17796 /* Process response Type, Class, TTL */
17797 if (!wlan_hdd_mdns_process_response_misc(MDNS_TYPE_SRV, resp_info)) {
17798 hddLog(LOGE, FL("Fail to process mDNS misc response (%d)!"),
17799 MDNS_TYPE_SRV);
17800 return FALSE;
17801 }
17802
17803 /*
17804 * Process response RDLength, RData (Srv target name)
17805 * Save the offset of RData length
17806 */
17807 offset_data_len = resp_info->resp_len;
17808 resp_info->resp_len += sizeof(uint16_t);
17809
17810 len = resp_info->resp_len + (3 * sizeof(uint16_t));
17811 if (len >= MAX_MDNS_RESP_LEN) {
17812 hddLog(LOGE, FL("resp_len exceeds %d!"), MAX_MDNS_RESP_LEN);
17813 return FALSE;
17814 }
17815
17816 /* set Srv Priority */
17817 value = ini_config->mdns_resp_type_srv_priority;
17818 wlan_hdd_mdns_format_response_u16(value, resp_info);
17819 /* set Srv Weight */
17820 value = ini_config->mdns_resp_type_srv_weight;
17821 wlan_hdd_mdns_format_response_u16(value, resp_info);
17822 /* set Srv Port */
17823 value = ini_config->mdns_resp_type_srv_port;
17824 wlan_hdd_mdns_format_response_u16(value, resp_info);
17825
17826 if (!wlan_hdd_mdns_pack_response_type_srv_target(ini_config, resp_info,
17827 resptype_srv_tgt, resptype_srv,
17828 resptype_ptr, resptype_ptr_dn,
17829 resptype_txt, resptype_a)) {
17830 return FALSE;
17831 }
17832 /* Set the RData length */
17833 len = offset_data_len + sizeof(uint16_t);
17834 if ((resptype_srv_tgt->num_entries > 0) &&
17835 (resp_info->resp_len > len)) {
17836 value = resp_info->resp_len - len;
17837 val_u8 = (value & 0xff00) >> 8;
17838 resp_info->resp_data[offset_data_len] = val_u8;
17839 val_u8 = value & 0xff;
17840 resp_info->resp_data[offset_data_len+1] = val_u8;
17841 } else {
17842 hddLog(LOGE, FL("Fail to process mDNS response (%d)!"),
17843 MDNS_TYPE_SRV);
17844 return FALSE;
17845 }
17846
17847 EXIT();
17848 return TRUE;
17849}
17850
17851/**
17852 * wlan_hdd_mdns_free_mem() - Free the allocated memory
17853 * @response: Pointer to the struct hdd_mdns_resp_info
17854 *
17855 * Return: None
17856 */
17857static void wlan_hdd_mdns_free_mem(struct hdd_mdns_resp_info *response)
17858{
17859 if (response && response->data)
17860 vos_mem_free(response->data);
17861 if (response && response->offset)
17862 vos_mem_free(response->offset);
17863}
17864
17865/**
17866 * wlan_hdd_mdns_pack_response() - Pack mDNS response
17867 * @ini_config: Pointer to the struct hdd_config_t
17868 * @resp_info: Pointer to the struct tSirMDNSResponseInfo
17869 *
17870 * This function will pack four types of responses (Type A, Type Txt, Type Ptr
17871 * and Type Service). Each response contains QName, response type, class, TTL
17872 * and data fields.
17873 *
17874 * Return: Return boolean. TRUE for success, FALSE for fail.
17875 */
17876static bool wlan_hdd_mdns_pack_response(hdd_config_t *ini_config,
17877 sir_mdns_resp_info resp_info)
17878{
17879 struct hdd_mdns_resp_info resptype_a, resptype_txt;
17880 struct hdd_mdns_resp_info resptype_ptr, resptype_ptr_dn;
17881 struct hdd_mdns_resp_info resptype_srv, resptype_srv_tgt;
17882 uint32_t num_res_records = 0;
17883 bool status = FALSE;
17884
17885 ENTER();
17886
17887 wlan_hdd_mdns_reset_response(&resptype_a);
17888 wlan_hdd_mdns_reset_response(&resptype_txt);
17889 wlan_hdd_mdns_reset_response(&resptype_ptr);
17890 wlan_hdd_mdns_reset_response(&resptype_ptr_dn);
17891 wlan_hdd_mdns_reset_response(&resptype_srv);
17892 wlan_hdd_mdns_reset_response(&resptype_srv_tgt);
17893
17894 resp_info->resp_len = 0;
17895
17896 /* Process Type A response */
17897 if (!wlan_hdd_mdns_pack_response_type_a(ini_config, resp_info,
17898 &resptype_a))
17899 goto err_resptype_a;
17900
17901 if ((resptype_a.num_entries > 0) &&
17902 (strlen((char *)&resptype_a.data[0]) > 0))
17903 num_res_records++;
17904
17905 /* Process Type TXT response */
17906 if (!wlan_hdd_mdns_pack_response_type_txt(ini_config, resp_info,
17907 &resptype_txt, &resptype_a))
17908 goto err_resptype_txt;
17909
17910 if ((resptype_txt.num_entries > 0) &&
17911 (strlen((char *)&resptype_txt.data[0]) > 0))
17912 num_res_records++;
17913
17914 /* Process Type PTR response */
17915 if (!wlan_hdd_mdns_pack_response_type_ptr(ini_config, resp_info,
17916 &resptype_ptr, &resptype_ptr_dn,
17917 &resptype_txt, &resptype_a))
17918 goto err_resptype_ptr;
17919
17920 if ((resptype_ptr.num_entries > 0) &&
17921 (strlen((char *)&resptype_ptr.data[0]) > 0))
17922 num_res_records++;
17923
17924 /* Process Type SRV response */
17925 if (!wlan_hdd_mdns_pack_response_type_srv(ini_config, resp_info,
17926 &resptype_srv, &resptype_srv_tgt,
17927 &resptype_ptr, &resptype_ptr_dn,
17928 &resptype_txt, &resptype_a))
17929 goto err_resptype_srv;
17930
17931 if ((resptype_srv.num_entries > 0) &&
17932 (strlen((char *)&resptype_srv.data[0]) > 0))
17933 num_res_records++;
17934
17935 resp_info->resourceRecord_count = num_res_records;
17936 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
17937 "%s: Pack mDNS response data successfully!", __func__);
17938 status = TRUE;
17939
17940err_resptype_srv:
17941 wlan_hdd_mdns_free_mem(&resptype_srv);
17942 wlan_hdd_mdns_free_mem(&resptype_srv_tgt);
17943
17944err_resptype_ptr:
17945 wlan_hdd_mdns_free_mem(&resptype_ptr);
17946 wlan_hdd_mdns_free_mem(&resptype_ptr_dn);
17947
17948err_resptype_txt:
17949 wlan_hdd_mdns_free_mem(&resptype_txt);
17950
17951err_resptype_a:
17952 wlan_hdd_mdns_free_mem(&resptype_a);
17953
17954 EXIT();
17955 return status;
17956}
17957
17958/**
17959 * wlan_hdd_set_mdns_offload() - Enable mDNS offload
17960 * @hostapd_adapter: Pointer to the struct hdd_adapter_t
17961 *
17962 * This function will set FQDN/unique FQDN (full qualified domain name)
17963 * and the mDNS response. Then send them to SME.
17964 *
17965 * Return: Return boolean. TRUE for success, FALSE for fail.
17966 */
17967bool wlan_hdd_set_mdns_offload(hdd_adapter_t *hostapd_adapter)
17968{
17969 hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(hostapd_adapter);
17970 sir_mdns_offload_info mdns_offload_info;
17971 sir_mdns_fqdn_info mdns_fqdn_info;
17972 sir_mdns_resp_info mdns_resp_info;
17973 uint32_t fqdn_len, ufqdn_len;
17974
17975 ENTER();
17976
17977 /* 1. Prepare the MDNS fqdn request to send to SME */
17978 fqdn_len = strlen(hdd_ctx->cfg_ini->mdns_fqdn);
17979 ufqdn_len = strlen(hdd_ctx->cfg_ini->mdns_uniquefqdn);
17980 if ((fqdn_len == 0) && (ufqdn_len == 0)) {
17981 hddLog(LOGE, FL("No mDNS FQDN or UFQDN is assigned fqdn_len %d,"
17982 "ufqdn_len %d!"), fqdn_len, ufqdn_len);
17983 return FALSE;
17984 }
17985
17986 mdns_fqdn_info = vos_mem_malloc(sizeof(*mdns_fqdn_info));
17987 if (NULL == mdns_fqdn_info) {
17988 hddLog(LOGE, FL("could not allocate tSirMDNSFqdnInfo!"));
17989 return FALSE;
17990 }
17991 /* MDNS fqdn request */
17992 if (fqdn_len > 0) {
17993 vos_mem_zero(mdns_fqdn_info, sizeof(*mdns_fqdn_info));
17994 mdns_fqdn_info->bss_idx = hostapd_adapter->sessionId;
17995 mdns_fqdn_info->fqdn_type = MDNS_FQDN_TYPE_GENERAL;
17996 mdns_fqdn_info->fqdn_len = fqdn_len;
17997 mdns_fqdn_info->mdns_fqdn_callback = hdd_mdns_fqdn_offload_done;
17998 mdns_fqdn_info->mdns_fqdn_cb_context = hostapd_adapter;
17999 vos_mem_copy(mdns_fqdn_info->fqdn_data,
18000 hdd_ctx->cfg_ini->mdns_fqdn,
18001 mdns_fqdn_info->fqdn_len);
18002
18003 if (eHAL_STATUS_SUCCESS !=
18004 sme_set_mdns_fqdn(hdd_ctx->hHal, mdns_fqdn_info)) {
18005 hddLog(LOGE, FL("sme_set_mdns_fqdn fail!"));
18006 vos_mem_free(mdns_fqdn_info);
18007 return FALSE;
18008 }
18009 }
18010 /* MDNS unique fqdn request */
18011 if (ufqdn_len > 0) {
18012 vos_mem_zero(mdns_fqdn_info, sizeof(*mdns_fqdn_info));
18013 mdns_fqdn_info->bss_idx = hostapd_adapter->sessionId;
18014 mdns_fqdn_info->fqdn_type = MDNS_FQDN_TYPE_UNIQUE;
18015 mdns_fqdn_info->fqdn_len = ufqdn_len;
18016 mdns_fqdn_info->mdns_fqdn_callback = hdd_mdns_fqdn_offload_done;
18017 mdns_fqdn_info->mdns_fqdn_cb_context = hostapd_adapter;
18018 vos_mem_copy(mdns_fqdn_info->fqdn_data,
18019 hdd_ctx->cfg_ini->mdns_uniquefqdn,
18020 mdns_fqdn_info->fqdn_len);
18021 if (eHAL_STATUS_SUCCESS !=
18022 sme_set_mdns_fqdn(hdd_ctx->hHal, mdns_fqdn_info)) {
18023 hddLog(LOGE, FL("sme_set_mdns_fqdn fail!"));
18024 vos_mem_free(mdns_fqdn_info);
18025 return FALSE;
18026 }
18027 }
18028 vos_mem_free(mdns_fqdn_info);
18029
18030 /* 2. Prepare the MDNS response request to send to SME */
18031 mdns_resp_info = vos_mem_malloc(sizeof(*mdns_resp_info));
18032 if (NULL == mdns_resp_info) {
18033 hddLog(LOGE, FL("could not allocate tSirMDNSResponseInfo!"));
18034 return FALSE;
18035 }
18036
18037 vos_mem_zero(mdns_resp_info, sizeof(*mdns_resp_info));
18038 mdns_resp_info->bss_idx = hostapd_adapter->sessionId;
18039 mdns_resp_info->mdns_resp_callback = hdd_mdns_resp_offload_done;
18040 mdns_resp_info->mdns_resp_cb_context = hostapd_adapter;
18041 if (!wlan_hdd_mdns_pack_response(hdd_ctx->cfg_ini, mdns_resp_info)) {
18042 hddLog(LOGE, FL("wlan_hdd_pack_mdns_response fail!"));
18043 vos_mem_free(mdns_resp_info);
18044 return FALSE;
18045 }
18046 if (eHAL_STATUS_SUCCESS !=
18047 sme_set_mdns_resp(hdd_ctx->hHal, mdns_resp_info)) {
18048 hddLog(LOGE, FL("sme_set_mdns_resp fail!"));
18049 vos_mem_free(mdns_resp_info);
18050 return FALSE;
18051 }
18052 vos_mem_free(mdns_resp_info);
18053
18054 /* 3. Prepare the MDNS Enable request to send to SME */
18055 mdns_offload_info = vos_mem_malloc(sizeof(*mdns_offload_info));
18056 if (NULL == mdns_offload_info) {
18057 hddLog(LOGE, FL("could not allocate tSirMDNSOffloadInfo!"));
18058 return FALSE;
18059 }
18060
18061 vos_mem_zero(mdns_offload_info, sizeof(*mdns_offload_info));
18062
18063 mdns_offload_info->bss_idx = hostapd_adapter->sessionId;
18064 mdns_offload_info->enable = hdd_ctx->cfg_ini->enable_mdns_offload;
18065 mdns_offload_info->mdns_enable_callback = hdd_mdns_enable_offload_done;
18066 mdns_offload_info->mdns_enable_cb_context = hostapd_adapter;
18067 if (eHAL_STATUS_SUCCESS !=
18068 sme_set_mdns_offload(hdd_ctx->hHal, mdns_offload_info)) {
18069 hddLog(LOGE, FL("sme_set_mdns_offload fail!"));
18070 vos_mem_free(mdns_offload_info);
18071 return FALSE;
18072 }
18073
18074 vos_mem_free(mdns_offload_info);
18075 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
18076 "%s: enable mDNS offload successfully!", __func__);
18077 return TRUE;
18078}
Manjeet Singh3ed79242017-01-11 19:04:32 +053018079
18080
Anurag Chouhan0b29de02016-12-16 13:18:40 +053018081#endif /* MDNS_OFFLOAD */
c_manjeecfd1efb2015-09-25 19:32:34 +053018082
Hanumanth Reddy Pothulad864f312017-01-18 16:16:08 +053018083/**
18084 * wlan_hdd_start_sap() - This function starts bss of SAP.
18085 * @ap_adapter: SAP adapter
18086 *
18087 * This function will process the starting of sap adapter.
18088 *
18089 * Return: void.
18090 */
18091void wlan_hdd_start_sap(hdd_adapter_t *ap_adapter)
18092{
18093 hdd_ap_ctx_t *hdd_ap_ctx;
18094 hdd_hostapd_state_t *hostapd_state;
18095 VOS_STATUS vos_status;
18096 hdd_context_t *hdd_ctx;
18097 tsap_Config_t *pConfig;
18098
18099 if (NULL == ap_adapter) {
18100 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18101 FL("ap_adapter is NULL here"));
18102 return;
18103 }
18104
18105 hdd_ctx = WLAN_HDD_GET_CTX(ap_adapter);
18106 hdd_ap_ctx = WLAN_HDD_GET_AP_CTX_PTR(ap_adapter);
18107 hostapd_state = WLAN_HDD_GET_HOSTAP_STATE_PTR(ap_adapter);
18108 pConfig = &ap_adapter->sessionCtx.ap.sapConfig;
18109
18110 mutex_lock(&hdd_ctx->sap_lock);
18111 if (test_bit(SOFTAP_BSS_STARTED, &ap_adapter->event_flags))
18112 goto end;
18113
18114 if (0 != wlan_hdd_cfg80211_update_apies(ap_adapter)) {
18115 hddLog(LOGE, FL("SAP Not able to set AP IEs"));
18116 goto end;
18117 }
18118
18119 vos_event_reset(&hostapd_state->vosEvent);
18120 if (WLANSAP_StartBss(hdd_ctx->pvosContext, hdd_hostapd_SAPEventCB,
18121 &hdd_ap_ctx->sapConfig, (v_PVOID_t)ap_adapter->dev)
18122 != VOS_STATUS_SUCCESS) {
18123 goto end;
18124 }
18125
18126 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
18127 FL("Waiting for SAP to start"));
18128 vos_status = vos_wait_single_event(&hostapd_state->vosEvent, 10000);
18129 if (!VOS_IS_STATUS_SUCCESS(vos_status)) {
18130 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18131 FL("SAP Start failed"));
18132 goto end;
18133 }
18134 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
18135 FL("SAP Start Success"));
18136 set_bit(SOFTAP_BSS_STARTED, &ap_adapter->event_flags);
18137
18138 wlan_hdd_incr_active_session(hdd_ctx, ap_adapter->device_mode);
18139 hostapd_state->bCommit = TRUE;
18140
18141end:
18142 mutex_unlock(&hdd_ctx->sap_lock);
18143 return;
18144}
18145
Manjeet Singh3ed79242017-01-11 19:04:32 +053018146#ifdef WLAN_FEATURE_TSF
18147
18148/**
18149 * hdd_tsf_cb() - handle tsf request callback
18150 *
18151 * @pcb_cxt: pointer to the hdd_contex
18152 * @ptsf: pointer to struct stsf
18153 *
18154 * Based on the request sent .
18155 *
18156 * Return: Describe the execute result of this routine
18157 */
18158static int hdd_tsf_cb(void *pcb_ctx, struct stsf *ptsf)
18159{
18160 hdd_context_t *hddctx;
18161 int status;
18162 hdd_adapter_t* adapter = (hdd_adapter_t*)pcb_ctx;
18163
18164 if (pcb_ctx == NULL || ptsf == NULL) {
18165 hddLog(VOS_TRACE_LEVEL_ERROR,
18166 FL("HDD context is not valid"));
18167 return -EINVAL;
18168 }
18169
18170 hddctx = (hdd_context_t *)pcb_ctx;
18171 status = wlan_hdd_validate_context(hddctx);
18172 if (0 != status)
18173 return -EINVAL;
18174
18175 if (NULL == adapter) {
18176 hddLog(VOS_TRACE_LEVEL_ERROR,
18177 FL("failed to find adapter"));
18178 return -EINVAL;
18179 }
18180
18181 hddLog(VOS_TRACE_LEVEL_INFO,
18182 FL("tsf cb handle event, device_mode is %d"),
18183 adapter->device_mode);
18184
18185 /* copy the return value to hdd_tsf_ctx in adapter*/
18186 if (ptsf->tsf_req_status) {
18187
18188 vos_spin_lock_acquire(&adapter->tsf_cap_ctx.tsf_lock);
18189 adapter->tsf_cap_ctx.tsf_get_state = TSF_NOT_RETURNED_BY_FW;
18190 adapter->tsf_cap_ctx.tsf_capture_state = TSF_IDLE;
18191 vos_event_set (&adapter->tsf_cap_ctx.tsf_capture_done_event);
18192 vos_spin_lock_release(&adapter->tsf_cap_ctx.tsf_lock);
18193
18194 hddLog(VOS_TRACE_LEVEL_ERROR, FL("tsf req failure :%d"),
18195 ptsf->tsf_req_status);
18196 return ptsf->tsf_req_status;
18197 }
18198 /* If this is a get request.Store the tsf values in adapter. */
18199 if (!ptsf->set_tsf_req) {
18200 vos_spin_lock_acquire(&adapter->tsf_cap_ctx.tsf_lock);
18201 adapter->tsf_cap_ctx.tsf_low = ptsf->tsf_low;
18202 adapter->tsf_cap_ctx.tsf_high = ptsf->tsf_high;
18203 adapter->tsf_cap_ctx.tsf_get_state = TSF_RETURN;
18204 adapter->tsf_cap_ctx.tsf_capture_state = TSF_IDLE;
18205 vos_spin_lock_release(&adapter->tsf_cap_ctx.tsf_lock);
18206
18207 hddLog(VOS_TRACE_LEVEL_INFO,
18208 FL("hdd_get_tsf_cb sta=%u, tsf_low=%u, tsf_high=%u"),
18209 adapter->sessionId, ptsf->tsf_low, ptsf->tsf_high);
18210 }
18211 else {
18212 vos_spin_lock_acquire(&adapter->tsf_cap_ctx.tsf_lock);
18213 adapter->tsf_cap_ctx.tsf_capture_state = TSF_CAP_STATE;
18214 adapter->tsf_cap_ctx.tsf_get_state = TSF_CURRENT_IN_CAP_STATE;
18215 vos_spin_lock_release(&adapter->tsf_cap_ctx.tsf_lock);
18216 }
18217 vos_spin_lock_acquire(&adapter->tsf_cap_ctx.tsf_lock);
18218 vos_event_set (&adapter->tsf_cap_ctx.tsf_capture_done_event);
18219 vos_spin_lock_release(&adapter->tsf_cap_ctx.tsf_lock);
18220
18221 /* free allocated mem */
18222 vos_mem_free(ptsf);
18223
18224 return 0;
18225}
18226
18227/**
18228 * hdd_capture_tsf() - capture tsf
18229 *
18230 * @adapter: pointer to adapter
18231 * @buf: pointer to upper layer buf
18232 * @len : the length of buf
18233 *
18234 * This function returns tsf value to uplayer.
18235 *
18236 * Return: Describe the execute result of this routine
18237 */
18238int hdd_capture_tsf(hdd_adapter_t *adapter, uint32_t *buf, int len)
18239{
18240 int ret = 0;
18241 hdd_station_ctx_t *hdd_sta_ctx;
18242 hdd_context_t *hdd_ctx;
18243 tSirCapTsfParams cap_tsf_params;
18244 VOS_STATUS status;
18245
18246 if (adapter == NULL || buf == NULL) {
18247 hddLog(VOS_TRACE_LEVEL_ERROR,
18248 FL("invalid pointer"));
18249 return -EINVAL;
18250 }
18251 if (len != 1)
18252 return -EINVAL;
18253
18254 hdd_ctx = WLAN_HDD_GET_CTX(adapter);
18255
18256 if (wlan_hdd_validate_context(hdd_ctx)) {
18257 hddLog(VOS_TRACE_LEVEL_ERROR,
18258 FL("invalid hdd ctx"));
18259 return -EINVAL;
18260 }
18261 if (adapter->device_mode == WLAN_HDD_INFRA_STATION ||
18262 adapter->device_mode == WLAN_HDD_P2P_CLIENT) {
18263 hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
18264 if (hdd_sta_ctx->conn_info.connState !=
18265 eConnectionState_Associated) {
18266
18267 hddLog(VOS_TRACE_LEVEL_INFO,
18268 FL("failed to cap tsf, not connect with ap"));
18269 buf[0] = TSF_STA_NOT_CONNECTED_NO_TSF;
18270 return ret;
18271 }
18272 }
18273 if ((adapter->device_mode == WLAN_HDD_SOFTAP ||
18274 adapter->device_mode == WLAN_HDD_P2P_GO) &&
18275 !(test_bit(SOFTAP_BSS_STARTED, &adapter->event_flags))) {
18276 hddLog(VOS_TRACE_LEVEL_INFO,
18277 FL("Soft AP / P2p GO not beaconing"));
18278 buf[0] = TSF_SAP_NOT_STARTED_NO_TSF;
18279 return ret;
18280 }
18281 if (adapter->tsf_cap_ctx.tsf_capture_state == TSF_CAP_STATE) {
18282 hddLog(VOS_TRACE_LEVEL_INFO,
18283 FL("current in capture state, pls reset"));
18284 buf[0] = TSF_CURRENT_IN_CAP_STATE;
18285 } else {
18286 hddLog(VOS_TRACE_LEVEL_INFO, FL("ioctl issue cap tsf cmd"));
18287 buf[0] = TSF_RETURN;
18288 cap_tsf_params.session_id = adapter->sessionId;
18289 cap_tsf_params.tsf_rsp_cb_func = hdd_tsf_cb;
18290 cap_tsf_params.tsf_rsp_cb_ctx = adapter;
18291
18292 vos_spin_lock_acquire(&adapter->tsf_cap_ctx.tsf_lock);
18293 adapter->tsf_cap_ctx.tsf_capture_state = TSF_CAP_STATE;
18294 adapter->tsf_cap_ctx.tsf_get_state = TSF_CURRENT_IN_CAP_STATE;
18295 vos_spin_lock_release(&adapter->tsf_cap_ctx.tsf_lock);
18296
18297 ret = sme_capture_tsf_req(hdd_ctx->hHal, cap_tsf_params);
18298
18299 if (ret != VOS_STATUS_SUCCESS) {
18300 hddLog(VOS_TRACE_LEVEL_ERROR, FL("capture fail"));
18301 buf[0] = TSF_CAPTURE_FAIL;
18302 vos_spin_lock_acquire(&adapter->tsf_cap_ctx.tsf_lock);
18303 adapter->tsf_cap_ctx.tsf_capture_state = TSF_IDLE;
18304 vos_spin_lock_release(&adapter->tsf_cap_ctx.tsf_lock);
18305 return -EINVAL;
18306 }
18307 /* wait till we get a response from fw */
18308 status = vos_wait_single_event(&adapter->tsf_cap_ctx.
18309 tsf_capture_done_event,
18310 HDD_TSF_CAP_REQ_TIMEOUT);
18311
18312 if (!VOS_IS_STATUS_SUCCESS(status)) {
18313 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18314 ("capture tsf vos wait for single_event failed!! %d"),
18315 adapter->tsf_cap_ctx.tsf_get_state);
18316
18317 vos_spin_lock_acquire(&adapter->tsf_cap_ctx.tsf_lock);
18318 adapter->tsf_cap_ctx.tsf_capture_state = TSF_IDLE;
18319 vos_spin_lock_release(&adapter->tsf_cap_ctx.tsf_lock);
18320
18321 return -EINVAL;
18322 }
18323 }
18324 buf[0] = TSF_RETURN;
18325 hddLog(VOS_TRACE_LEVEL_INFO,
18326 FL("ioctl return cap tsf cmd, ret = %d"), ret);
18327 return ret;
18328}
18329
18330/**
18331 * hdd_indicate_tsf() - return tsf to uplayer
18332 *
18333 * @adapter: pointer to adapter
18334 * @buf: pointer to uplayer buf
18335 * @len : the length of buf
18336 *
18337 * This function returns tsf value to uplayer.
18338 *
18339 * Return: Describe the execute result of this routine
18340 */
18341int hdd_indicate_tsf(hdd_adapter_t *adapter, uint32_t *buf, int len)
18342{
18343 int ret = 0;
18344 hdd_station_ctx_t *hdd_sta_ctx;
18345 hdd_context_t *hdd_ctx;
18346 tSirCapTsfParams cap_tsf_params;
18347 VOS_STATUS status;
18348
18349 if (adapter == NULL || buf == NULL) {
18350 hddLog(VOS_TRACE_LEVEL_ERROR,
18351 FL("invalid pointer"));
18352 return -EINVAL;
18353 }
18354 if (len != 3)
18355 return -EINVAL;
18356
18357 buf [1] = 0;
18358 buf [2] = 0;
18359 hdd_ctx = WLAN_HDD_GET_CTX(adapter);
18360
18361 if (wlan_hdd_validate_context(hdd_ctx)) {
18362 hddLog(VOS_TRACE_LEVEL_ERROR,
18363 FL("invalid hdd ctx"));
18364 return -EINVAL;
18365 }
18366 if (adapter->device_mode == WLAN_HDD_INFRA_STATION ||
18367 adapter->device_mode == WLAN_HDD_P2P_CLIENT) {
18368 hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
18369 if (hdd_sta_ctx->conn_info.connState !=
18370 eConnectionState_Associated) {
18371
18372 hddLog(VOS_TRACE_LEVEL_INFO,
18373 FL("failed to cap tsf, not connect with ap"));
18374 buf[0] = TSF_STA_NOT_CONNECTED_NO_TSF;
18375 return ret;
18376 }
18377 }
18378 if ((adapter->device_mode == WLAN_HDD_SOFTAP ||
18379 adapter->device_mode == WLAN_HDD_P2P_GO) &&
18380 !(test_bit(SOFTAP_BSS_STARTED, &adapter->event_flags))) {
18381 hddLog(VOS_TRACE_LEVEL_INFO,
18382 FL("Soft AP / P2p GO not beaconing"));
18383 buf[0] = TSF_SAP_NOT_STARTED_NO_TSF;
18384 return ret;
18385 }
18386
18387 if (adapter->tsf_cap_ctx.tsf_capture_state != TSF_CAP_STATE ||
18388 adapter->tsf_cap_ctx.tsf_get_state != TSF_CURRENT_IN_CAP_STATE ) {
18389 hddLog(VOS_TRACE_LEVEL_INFO,
18390 FL("Not in capture state,Enter capture state first"));
18391 buf[0] = TSF_GET_FAIL;
18392 } else {
18393 hddLog(VOS_TRACE_LEVEL_INFO, FL("ioctl issue cap tsf cmd"));
18394 cap_tsf_params.session_id = adapter->sessionId;
18395 cap_tsf_params.tsf_rsp_cb_func = hdd_tsf_cb;
18396 cap_tsf_params.tsf_rsp_cb_ctx = adapter;
18397
18398 ret = sme_get_tsf_req(hdd_ctx->hHal, cap_tsf_params);
18399
18400 if (ret != VOS_STATUS_SUCCESS) {
18401 hddLog(VOS_TRACE_LEVEL_ERROR, FL("capture fail"));
18402 buf[0] = TSF_CAPTURE_FAIL;
18403 vos_spin_lock_acquire(&adapter->tsf_cap_ctx.tsf_lock);
18404 adapter->tsf_cap_ctx.tsf_capture_state = TSF_IDLE;
18405 vos_spin_lock_release(&adapter->tsf_cap_ctx.tsf_lock);
18406 return -EINVAL;
18407 }
18408 /* wait till we get a response from fw */
18409 status = vos_wait_single_event(&adapter->tsf_cap_ctx.
18410 tsf_capture_done_event,
18411 HDD_TSF_GET_REQ_TIMEOUT);
18412
18413 if (!VOS_IS_STATUS_SUCCESS(status)) {
18414 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18415 ("capture tsf vos wait for single_event failed!! %d"),
18416 status);
18417
18418 vos_spin_lock_acquire(&adapter->tsf_cap_ctx.tsf_lock);
18419 adapter->tsf_cap_ctx.tsf_capture_state = TSF_IDLE;
18420 vos_spin_lock_release(&adapter->tsf_cap_ctx.tsf_lock);
18421 return status;
18422 }
18423 buf[1] = adapter->tsf_cap_ctx.tsf_low;
18424 buf[2] = adapter->tsf_cap_ctx.tsf_high;
18425
18426 hddLog(VOS_TRACE_LEVEL_INFO,
18427 FL("get tsf cmd,status=%u, tsf_low=%u, tsf_high=%u"),
18428 buf[0], buf[1], buf[2]);
18429 }
18430 hddLog(VOS_TRACE_LEVEL_INFO,
18431 FL("ioctl return cap tsf cmd, ret = %d"), ret);
18432 return ret;
18433}
18434
18435void wlan_hdd_tsf_init(hdd_adapter_t *adapter)
18436{
18437
18438 if (adapter == NULL) {
18439 hddLog(VOS_TRACE_LEVEL_ERROR,
18440 FL("TSF init on a null adapter!"));
18441 return;
18442 }
18443
18444 adapter->tsf_cap_ctx.tsf_get_state = TSF_RETURN;
18445 adapter->tsf_cap_ctx.tsf_capture_state = TSF_IDLE;
18446 vos_event_init(&adapter->tsf_cap_ctx.tsf_capture_done_event);
18447 vos_spin_lock_init(&adapter->tsf_cap_ctx.tsf_lock);
18448 adapter->tsf_cap_ctx.tsf_high = 0;
18449 adapter->tsf_cap_ctx.tsf_low = 0;
18450}
18451
18452#endif
18453
Hanumanth Reddy Pothula49c3f902018-02-16 16:01:13 +053018454bool hdd_is_memdump_supported(void)
18455{
18456#ifdef WLAN_FEATURE_MEMDUMP
18457 return true;
18458#endif
18459 return false;
18460}
18461
Hanumanth Reddy Pothula972e1df2018-06-14 13:33:47 +053018462bool hdd_is_cli_iface_up(hdd_context_t *hdd_ctx)
18463{
18464 hdd_adapter_list_node_t *adapter_node = NULL, *next = NULL;
18465 hdd_adapter_t *adapter;
18466 VOS_STATUS status;
18467
18468 status = hdd_get_front_adapter(hdd_ctx, &adapter_node);
18469 while (NULL != adapter_node && VOS_STATUS_SUCCESS == status) {
18470 adapter = adapter_node->pAdapter;
18471 if ((adapter->device_mode == WLAN_HDD_INFRA_STATION ||
18472 adapter->device_mode == WLAN_HDD_P2P_CLIENT) &&
18473 test_bit(DEVICE_IFACE_OPENED,
18474 &adapter->event_flags)){
18475 return true;
18476 }
18477 status = hdd_get_next_adapter(hdd_ctx, adapter_node, &next);
18478 adapter_node = next;
18479 }
18480
18481 return false;
18482}
18483
Jeff Johnson295189b2012-06-20 16:38:30 -070018484//Register the module init/exit functions
18485module_init(hdd_module_init);
18486module_exit(hdd_module_exit);
18487
18488MODULE_LICENSE("Dual BSD/GPL");
18489MODULE_AUTHOR("Qualcomm Atheros, Inc.");
18490MODULE_DESCRIPTION("WLAN HOST DEVICE DRIVER");
18491
Ashish Kumar Dhanotiyafb3fd972018-04-30 12:46:52 +053018492static const struct kernel_param_ops con_mode_ops = {
18493 .set = con_mode_handler,
18494 .get = param_get_int,
18495};
18496
18497static const struct kernel_param_ops fwpath_ops = {
18498 .set = fwpath_changed_handler,
18499 .get = param_get_string,
18500};
18501
Hanumanth Reddy Pothula99219872018-06-08 14:45:18 +053018502#ifdef MODULE
18503module_param(con_mode, int, 0);
18504#else
Ashish Kumar Dhanotiyafb3fd972018-04-30 12:46:52 +053018505module_param_cb(con_mode, &con_mode_ops, &con_mode,
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070018506 S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
Hanumanth Reddy Pothula99219872018-06-08 14:45:18 +053018507#endif
Jeff Johnson32d95a32012-09-10 13:15:23 -070018508
Ashish Kumar Dhanotiyafb3fd972018-04-30 12:46:52 +053018509module_param_cb(fwpath, &fwpath_ops, &fwpath,
Jeff Johnson32d95a32012-09-10 13:15:23 -070018510 S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
Arif Hussain66559122013-11-21 10:11:40 -080018511
18512module_param(enable_dfs_chan_scan, int,
18513 S_IRUSR | S_IRGRP | S_IROTH);
18514
18515module_param(enable_11d, int,
18516 S_IRUSR | S_IRGRP | S_IROTH);
18517
18518module_param(country_code, charp,
18519 S_IRUSR | S_IRGRP | S_IROTH);