blob: d17aa924595213dfd5754d24e98871de3a6b7cee [file] [log] [blame]
Jeff Johnson295189b2012-06-20 16:38:30 -07001/*
Abhishek Singh8a3e4dc2017-01-02 10:39:18 +05302 * Copyright (c) 2012-2017 The Linux Foundation. All rights reserved.
Kiet Lam842dad02014-02-18 18:44:02 -08003 *
4 * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
5 *
6 *
7 * Permission to use, copy, modify, and/or distribute this software for
8 * any purpose with or without fee is hereby granted, provided that the
9 * above copyright notice and this permission notice appear in all
10 * copies.
11 *
12 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
13 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
14 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
15 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
16 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
17 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
18 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
19 * PERFORMANCE OF THIS SOFTWARE.
20 */
21
22/*
Kiet Lama7f454d2014-07-24 12:04:06 -070023 * This file was originally distributed by Qualcomm Atheros, Inc.
24 * under proprietary terms before Copyright ownership was assigned
25 * to the Linux Foundation.
Gopichand Nakkala92f07d82013-01-08 21:16:34 -080026 */
Kiet Lam842dad02014-02-18 18:44:02 -080027
28
Kiet Lama7f454d2014-07-24 12:04:06 -070029
30
Jeff Johnson295189b2012-06-20 16:38:30 -070031/*========================================================================
32
33 \file wlan_hdd_main.c
34
35 \brief WLAN Host Device Driver implementation
36
Jeff Johnson295189b2012-06-20 16:38:30 -070037
38 ========================================================================*/
39
40/**=========================================================================
41
42 EDIT HISTORY FOR FILE
43
44
45 This section contains comments describing changes made to the module.
46 Notice that changes are listed in reverse chronological order.
47
48
49 $Header:$ $DateTime: $ $Author: $
50
51
52 when who what, where, why
53 -------- --- --------------------------------------------------------
54 04/5/09 Shailender Created module.
55 02/24/10 Sudhir.S.Kohalli Added to support param for SoftAP module
56 06/03/10 js - Added support to hostapd driven deauth/disassoc/mic failure
57 ==========================================================================*/
58
59/*--------------------------------------------------------------------------
60 Include Files
61 ------------------------------------------------------------------------*/
62//#include <wlan_qct_driver.h>
63#include <wlan_hdd_includes.h>
Jeff Johnson295189b2012-06-20 16:38:30 -070064#include <vos_api.h>
65#include <vos_sched.h>
Jeff Johnson295189b2012-06-20 16:38:30 -070066#include <linux/etherdevice.h>
67#include <linux/firmware.h>
Jeff Johnson295189b2012-06-20 16:38:30 -070068#ifdef ANI_BUS_TYPE_PLATFORM
69#include <linux/wcnss_wlan.h>
70#endif //ANI_BUS_TYPE_PLATFORM
71#ifdef ANI_BUS_TYPE_PCI
72#include "wcnss_wlan.h"
73#endif /* ANI_BUS_TYPE_PCI */
74#include <wlan_hdd_tx_rx.h>
75#include <palTimer.h>
76#include <wniApi.h>
77#include <wlan_nlink_srv.h>
78#include <wlan_btc_svc.h>
79#include <wlan_hdd_cfg.h>
80#include <wlan_ptt_sock_svc.h>
Vinay Krishna Erannad938c422014-03-10 17:14:21 +053081#include <wlan_logging_sock_svc.h>
Jeff Johnson295189b2012-06-20 16:38:30 -070082#include <wlan_hdd_wowl.h>
83#include <wlan_hdd_misc.h>
84#include <wlan_hdd_wext.h>
85#ifdef WLAN_BTAMP_FEATURE
86#include <bap_hdd_main.h>
87#include <bapInternal.h>
88#endif // WLAN_BTAMP_FEATURE
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053089#include "wlan_hdd_trace.h"
90#include "vos_types.h"
91#include "vos_trace.h"
Jeff Johnson295189b2012-06-20 16:38:30 -070092#include <linux/wireless.h>
93#include <net/cfg80211.h>
Vinay Krishna Erannad9cbdb32014-01-16 12:59:10 +053094#include <linux/inetdevice.h>
95#include <net/addrconf.h>
Jeff Johnson295189b2012-06-20 16:38:30 -070096#include "wlan_hdd_cfg80211.h"
97#include "wlan_hdd_p2p.h"
Jeff Johnson295189b2012-06-20 16:38:30 -070098#include <linux/rtnetlink.h>
Jeff Johnson295189b2012-06-20 16:38:30 -070099int wlan_hdd_ftm_start(hdd_context_t *pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -0700100#include "sapApi.h"
101#include <linux/semaphore.h>
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -0700102#include <linux/ctype.h>
Arun Kumar Khandavalli74fe3032014-03-17 20:35:34 +0530103#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0))
104#include <soc/qcom/subsystem_restart.h>
105#else
Jeff Johnson295189b2012-06-20 16:38:30 -0700106#include <mach/subsystem_restart.h>
Arun Kumar Khandavalli74fe3032014-03-17 20:35:34 +0530107#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700108#include <wlan_hdd_hostapd.h>
109#include <wlan_hdd_softap_tx_rx.h>
Jeff Johnson295189b2012-06-20 16:38:30 -0700110#include "cfgApi.h"
Jeff Johnson295189b2012-06-20 16:38:30 -0700111#include "wlan_hdd_dev_pwr.h"
112#ifdef WLAN_BTAMP_FEATURE
113#include "bap_hdd_misc.h"
114#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700115#include "wlan_qct_pal_trace.h"
Jeff Johnson295189b2012-06-20 16:38:30 -0700116#include "qwlan_version.h"
Yathish9f22e662012-12-10 14:21:35 -0800117#include "wlan_qct_wda.h"
Chilam NG571c65a2013-01-19 12:27:36 +0530118#ifdef FEATURE_WLAN_TDLS
119#include "wlan_hdd_tdls.h"
120#endif
Yue Ma0d4891e2013-08-06 17:01:45 -0700121#include "wlan_hdd_debugfs.h"
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +0530122#include "sapInternal.h"
Jeff Johnson295189b2012-06-20 16:38:30 -0700123
124#ifdef MODULE
125#define WLAN_MODULE_NAME module_name(THIS_MODULE)
126#else
127#define WLAN_MODULE_NAME "wlan"
128#endif
129
130#ifdef TIMER_MANAGER
131#define TIMER_MANAGER_STR " +TIMER_MANAGER"
132#else
133#define TIMER_MANAGER_STR ""
134#endif
135
136#ifdef MEMORY_DEBUG
137#define MEMORY_DEBUG_STR " +MEMORY_DEBUG"
138#else
139#define MEMORY_DEBUG_STR ""
140#endif
Kaushik, Sushant7005e372014-04-08 11:36:54 +0530141#define MAX_WAIT_FOR_ROC_COMPLETION 3
Jeff Johnson295189b2012-06-20 16:38:30 -0700142/* the Android framework expects this param even though we don't use it */
143#define BUF_LEN 20
Jeff Johnson76052702013-04-16 13:55:05 -0700144static char fwpath_buffer[BUF_LEN];
145static struct kparam_string fwpath = {
146 .string = fwpath_buffer,
147 .maxlen = BUF_LEN,
148};
Arif Hussain66559122013-11-21 10:11:40 -0800149
150static char *country_code;
151static int enable_11d = -1;
152static int enable_dfs_chan_scan = -1;
c_hpothu92367912014-05-01 15:18:17 +0530153static int gbcnMissRate = -1;
Arif Hussain66559122013-11-21 10:11:40 -0800154
Madan Mohan Koyyalamudi05f313c2012-09-18 19:19:15 -0700155#ifndef MODULE
Madan Mohan Koyyalamudidfd6aa82012-10-18 20:18:43 -0700156static int wlan_hdd_inited;
Madan Mohan Koyyalamudi05f313c2012-09-18 19:19:15 -0700157#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700158
Jeff Johnsone7245742012-09-05 17:12:55 -0700159/*
Jeff Johnson72a40512013-12-19 10:14:15 -0800160 * spinlock for synchronizing asynchronous request/response
161 * (full description of use in wlan_hdd_main.h)
162 */
163DEFINE_SPINLOCK(hdd_context_lock);
164
165/*
Jeff Johnsone7245742012-09-05 17:12:55 -0700166 * The rate at which the driver sends RESTART event to supplicant
167 * once the function 'vos_wlanRestart()' is called
168 *
169 */
170#define WLAN_HDD_RESTART_RETRY_DELAY_MS 5000 /* 5 second */
171#define WLAN_HDD_RESTART_RETRY_MAX_CNT 5 /* 5 retries */
Varun Reddy Yeturu6d99ac82013-05-08 14:15:35 -0700172
173/*
174 * Size of Driver command strings from upper layer
175 */
176#define SIZE_OF_SETROAMMODE 11 /* size of SETROAMMODE */
177#define SIZE_OF_GETROAMMODE 11 /* size of GETROAMMODE */
178
Abhishek Singh00b71972016-01-07 10:51:04 +0530179#ifdef WLAN_FEATURE_RMC
180/*
181 * Ibss prop IE from command will be of size:
182 * size = sizeof(oui) + sizeof(oui_data) + 1(Element ID) + 1(EID Length)
183 * OUI_DATA should be at least 3 bytes long
184 */
185#define WLAN_HDD_IBSS_MIN_OUI_DATA_LENGTH (3)
186#endif
187
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -0800188#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
Srinivas Girigowda5cecb202013-10-08 09:13:25 -0700189#define TID_MIN_VALUE 0
190#define TID_MAX_VALUE 15
191static VOS_STATUS hdd_get_tsm_stats(hdd_adapter_t *pAdapter, const tANI_U8 tid,
192 tAniTrafStrmMetrics* pTsmMetrics);
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -0800193static VOS_STATUS hdd_parse_ese_beacon_req(tANI_U8 *pValue,
194 tCsrEseBeaconReq *pEseBcnReq);
195#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -0700196
Atul Mittal1d722422014-03-19 11:15:07 +0530197/*
198 * Maximum buffer size used for returning the data back to user space
199 */
200#define WLAN_MAX_BUF_SIZE 1024
201#define WLAN_PRIV_DATA_MAX_LEN 8192
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -0700202
Abhishek Singh00b71972016-01-07 10:51:04 +0530203/*
204 * When ever we need to print IBSSPEERINFOALL for morethan 16 STA
205 * we will split the printing.
206 */
207#define NUM_OF_STA_DATA_TO_PRINT 16
208
209#ifdef WLAN_FEATURE_RMC
210#define WLAN_NLINK_CESIUM 30
211#endif
212
c_hpothu92367912014-05-01 15:18:17 +0530213//wait time for beacon miss rate.
214#define BCN_MISS_RATE_TIME 500
215
Selvaraj, Sridhar5aff1ed2016-06-18 01:26:23 +0530216/*
217 * Android DRIVER command structures
218 */
219struct android_wifi_reassoc_params {
220 unsigned char bssid[18];
221 int channel;
222};
223
Sushant Kaushik83392fa2015-05-05 17:44:40 +0530224static vos_wake_lock_t wlan_wake_lock;
225
Jeff Johnson295189b2012-06-20 16:38:30 -0700226/* set when SSR is needed after unload */
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -0700227static e_hdd_ssr_required isSsrRequired = HDD_SSR_NOT_REQUIRED;
Jeff Johnson295189b2012-06-20 16:38:30 -0700228
229//internal function declaration
Jeff Johnsone7245742012-09-05 17:12:55 -0700230static VOS_STATUS wlan_hdd_framework_restart(hdd_context_t *pHddCtx);
231static void wlan_hdd_restart_init(hdd_context_t *pHddCtx);
232static void wlan_hdd_restart_deinit(hdd_context_t *pHddCtx);
Abhishek Singh00b71972016-01-07 10:51:04 +0530233
234#ifdef WLAN_FEATURE_RMC
235static void hdd_tx_fail_ind_callback(v_U8_t *MacAddr, v_U8_t seqNo);
236
237static int hdd_open_cesium_nl_sock(void);
238static void hdd_close_cesium_nl_sock(void);
239static struct sock *cesium_nl_srv_sock;
240static v_U16_t cesium_pid;
241
242static int hdd_ParseIBSSTXFailEventParams(tANI_U8 *pValue,
243 tANI_U8 *tx_fail_count,
244 tANI_U16 *pid);
245
246static int hdd_ParseUserParams(tANI_U8 *pValue, tANI_U8 **ppArg);
247
248#endif /* WLAN_FEATURE_RMC */
Jeff Johnsone7245742012-09-05 17:12:55 -0700249void wlan_hdd_restart_timer_cb(v_PVOID_t usrDataForCallback);
Sameer Thalappil45931fb2013-02-01 11:18:05 -0800250void hdd_set_wlan_suspend_mode(bool suspend);
Jeff Johnsone7245742012-09-05 17:12:55 -0700251
Jeff Johnson295189b2012-06-20 16:38:30 -0700252v_U16_t hdd_select_queue(struct net_device *dev,
Anand N Sunkade9adb1b2015-07-29 09:56:45 +0530253 struct sk_buff *skb
254#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,13,0))
255 , void *accel_priv
256#endif
257#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
258 , select_queue_fallback_t fallback
259#endif
260);
Jeff Johnson295189b2012-06-20 16:38:30 -0700261
262#ifdef WLAN_FEATURE_PACKET_FILTERING
263static void hdd_set_multicast_list(struct net_device *dev);
264#endif
265
266void hdd_wlan_initial_scan(hdd_adapter_t *pAdapter);
267
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -0800268#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowdade697412013-02-14 16:31:48 -0800269void hdd_getBand_helper(hdd_context_t *pHddCtx, int *pBand);
270static VOS_STATUS hdd_parse_channellist(tANI_U8 *pValue, tANI_U8 *pChannelList, tANI_U8 *pNumChannels);
Srinivas Girigowda100eb322013-03-15 16:48:20 -0700271static VOS_STATUS hdd_parse_send_action_frame_data(tANI_U8 *pValue, tANI_U8 *pTargetApBssid,
272 tANI_U8 *pChannel, tANI_U8 *pDwellTime,
273 tANI_U8 **pBuf, tANI_U8 *pBufLen);
Selvaraj, Sridhar5aff1ed2016-06-18 01:26:23 +0530274static int hdd_parse_reassoc_command_v1_data(const tANI_U8 *pValue,
275 tANI_U8 *pTargetApBssid, tANI_U8 *pChannel);
Srinivas Girigowdade697412013-02-14 16:31:48 -0800276#endif
Ratheesh S P21280412015-05-19 14:21:52 +0530277
278/* Store WLAN driver info in a global variable such that crash debugger
279 can extract it from driver debug symbol and crashdump for post processing */
280tANI_U8 g_wlan_driver[ ] = "pronto_driver";
281
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -0800282#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
Srinivas Girigowda5cecb202013-10-08 09:13:25 -0700283VOS_STATUS hdd_parse_get_cckm_ie(tANI_U8 *pValue, tANI_U8 **pCckmIe, tANI_U8 *pCckmIeLen);
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -0800284#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -0700285
Mihir Shetee1093ba2014-01-21 20:13:32 +0530286static VOS_STATUS wlan_hdd_init_channels(hdd_context_t *pHddCtx);
Sushant Kaushik8bc7df22014-04-09 17:55:29 +0530287const char * hdd_device_modetoString(v_U8_t device_mode)
288{
289 switch(device_mode)
290 {
291 CASE_RETURN_STRING( WLAN_HDD_INFRA_STATION );
292 CASE_RETURN_STRING( WLAN_HDD_SOFTAP );
293 CASE_RETURN_STRING( WLAN_HDD_P2P_CLIENT );
294 CASE_RETURN_STRING( WLAN_HDD_P2P_GO );
295 CASE_RETURN_STRING( WLAN_HDD_MONITOR);
296 CASE_RETURN_STRING( WLAN_HDD_FTM );
297 CASE_RETURN_STRING( WLAN_HDD_IBSS );
298 CASE_RETURN_STRING( WLAN_HDD_P2P_DEVICE );
299 default:
300 return "device_mode Unknown";
301 }
302}
Mihir Shetee1093ba2014-01-21 20:13:32 +0530303
Mukul Sharmaa78cf6b2015-02-24 16:59:01 +0530304static int __hdd_netdev_notifier_call(struct notifier_block * nb,
Jeff Johnson295189b2012-06-20 16:38:30 -0700305 unsigned long state,
306 void *ndev)
307{
308 struct net_device *dev = ndev;
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -0700309 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Jeff Johnson27cee452013-03-27 11:10:24 -0700310 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -0700311#ifdef WLAN_BTAMP_FEATURE
312 VOS_STATUS status;
Jeff Johnson295189b2012-06-20 16:38:30 -0700313#endif
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +0530314 long result;
Jeff Johnson295189b2012-06-20 16:38:30 -0700315
316 //Make sure that this callback corresponds to our device.
Jeff Johnson27cee452013-03-27 11:10:24 -0700317 if ((strncmp(dev->name, "wlan", 4)) &&
Amar Singhal4c723bd2013-03-25 18:14:15 -0700318 (strncmp(dev->name, "p2p", 3)))
319 return NOTIFY_DONE;
320
Jeff Johnson295189b2012-06-20 16:38:30 -0700321 if (!dev->ieee80211_ptr)
Jeff Johnson27cee452013-03-27 11:10:24 -0700322 return NOTIFY_DONE;
Jeff Johnson295189b2012-06-20 16:38:30 -0700323
Jeff Johnson27cee452013-03-27 11:10:24 -0700324 if (NULL == pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -0700325 {
Jeff Johnsona8a1a482012-12-12 16:49:33 -0800326 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: HDD Adapter Null Pointer", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700327 VOS_ASSERT(0);
328 return NOTIFY_DONE;
329 }
330
Jeff Johnson27cee452013-03-27 11:10:24 -0700331 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
332 if (NULL == pHddCtx)
333 {
334 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: HDD Context Null Pointer", __func__);
335 VOS_ASSERT(0);
336 return NOTIFY_DONE;
337 }
Sameer Thalappil14067972014-01-23 14:54:54 -0800338 if (pHddCtx->isLogpInProgress)
339 return NOTIFY_DONE;
340
Jeff Johnson27cee452013-03-27 11:10:24 -0700341
342 hddLog(VOS_TRACE_LEVEL_INFO, "%s: %s New Net Device State = %lu",
343 __func__, dev->name, state);
Jeff Johnson295189b2012-06-20 16:38:30 -0700344
345 switch (state) {
346 case NETDEV_REGISTER:
347 break;
348
349 case NETDEV_UNREGISTER:
350 break;
351
352 case NETDEV_UP:
353 break;
354
355 case NETDEV_DOWN:
356 break;
357
358 case NETDEV_CHANGE:
Jeff Johnsone7245742012-09-05 17:12:55 -0700359 if(TRUE == pAdapter->isLinkUpSvcNeeded)
360 complete(&pAdapter->linkup_event_var);
Jeff Johnson295189b2012-06-20 16:38:30 -0700361 break;
362
363 case NETDEV_GOING_DOWN:
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +0530364 result = wlan_hdd_scan_abort(pAdapter);
Girish Gowli4bf7a632014-06-12 13:42:11 +0530365 if (result < 0)
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +0530366 {
367 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
368 "%s: Timeout occurred while waiting for abortscan %ld",
369 __func__, result);
Jeff Johnson295189b2012-06-20 16:38:30 -0700370 }
371 else
372 {
373 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +0530374 "%s: Scan Abort Successful" , __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700375 }
376#ifdef WLAN_BTAMP_FEATURE
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700377 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,"%s: disabling AMP", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700378 status = WLANBAP_StopAmp();
379 if(VOS_STATUS_SUCCESS != status )
380 {
381 pHddCtx->isAmpAllowed = VOS_TRUE;
382 hddLog(VOS_TRACE_LEVEL_FATAL,
383 "%s: Failed to stop AMP", __func__);
384 }
385 else
386 {
387 //a state m/c implementation in PAL is TBD to avoid this delay
388 msleep(500);
Jeff Johnson04dd8a82012-06-29 20:41:40 -0700389 if ( pHddCtx->isAmpAllowed )
390 {
391 WLANBAP_DeregisterFromHCI();
392 pHddCtx->isAmpAllowed = VOS_FALSE;
393 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700394 }
395#endif //WLAN_BTAMP_FEATURE
396 break;
397
398 default:
399 break;
400 }
401
402 return NOTIFY_DONE;
403}
404
Mukul Sharmaa78cf6b2015-02-24 16:59:01 +0530405static int hdd_netdev_notifier_call(struct notifier_block * nb,
406 unsigned long state,
407 void *ndev)
408{
409 int ret;
410 vos_ssr_protect(__func__);
411 ret = __hdd_netdev_notifier_call( nb, state, ndev);
412 vos_ssr_unprotect(__func__);
413 return ret;
414}
415
Jeff Johnson295189b2012-06-20 16:38:30 -0700416struct notifier_block hdd_netdev_notifier = {
417 .notifier_call = hdd_netdev_notifier_call,
418};
419
420/*---------------------------------------------------------------------------
421 * Function definitions
422 *-------------------------------------------------------------------------*/
Jeff Johnson295189b2012-06-20 16:38:30 -0700423void hdd_unregister_mcast_bcast_filter(hdd_context_t *pHddCtx);
424void hdd_register_mcast_bcast_filter(hdd_context_t *pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -0700425//variable to hold the insmod parameters
Madan Mohan Koyyalamudidfd6aa82012-10-18 20:18:43 -0700426static int con_mode;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -0700427#ifndef MODULE
428/* current con_mode - used only for statically linked driver
429 * con_mode is changed by userspace to indicate a mode change which will
430 * result in calling the module exit and init functions. The module
431 * exit function will clean up based on the value of con_mode prior to it
432 * being changed by userspace. So curr_con_mode records the current con_mode
433 * for exit when con_mode becomes the next mode for init
434 */
Madan Mohan Koyyalamudidfd6aa82012-10-18 20:18:43 -0700435static int curr_con_mode;
Jeff Johnson295189b2012-06-20 16:38:30 -0700436#endif
437
Srinivas Girigowda8bf64cb2015-09-30 19:50:09 +0530438#ifdef WLAN_FEATURE_OFFLOAD_PACKETS
439/**
440 * hdd_init_offloaded_packets_ctx() - Initialize offload packets context
441 * @hdd_ctx: hdd global context
442 *
443 * Return: none
444 */
445static void hdd_init_offloaded_packets_ctx(hdd_context_t *hdd_ctx)
446{
447 uint8_t i;
448
449 mutex_init(&hdd_ctx->op_ctx.op_lock);
450 for (i = 0; i < MAXNUM_PERIODIC_TX_PTRNS; i++)
451 {
452 hdd_ctx->op_ctx.op_table[i].request_id = 0;
453 hdd_ctx->op_ctx.op_table[i].pattern_id = i;
454 }
455}
456#else
457static void hdd_init_offloaded_packets_ctx(hdd_context_t *hdd_ctx)
458{
459}
460#endif
461
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -0800462/**---------------------------------------------------------------------------
463
464 \brief hdd_vos_trace_enable() - Configure initial VOS Trace enable
465
466 Called immediately after the cfg.ini is read in order to configure
467 the desired trace levels.
468
469 \param - moduleId - module whose trace level is being configured
470 \param - bitmask - bitmask of log levels to be enabled
471
472 \return - void
473
474 --------------------------------------------------------------------------*/
475static void hdd_vos_trace_enable(VOS_MODULE_ID moduleId, v_U32_t bitmask)
476{
477 wpt_tracelevel level;
478
479 /* if the bitmask is the default value, then a bitmask was not
480 specified in cfg.ini, so leave the logging level alone (it
481 will remain at the "compiled in" default value) */
482 if (CFG_VOS_TRACE_ENABLE_DEFAULT == bitmask)
483 {
484 return;
485 }
486
487 /* a mask was specified. start by disabling all logging */
488 vos_trace_setValue(moduleId, VOS_TRACE_LEVEL_NONE, 0);
489
490 /* now cycle through the bitmask until all "set" bits are serviced */
491 level = VOS_TRACE_LEVEL_FATAL;
492 while (0 != bitmask)
493 {
494 if (bitmask & 1)
495 {
496 vos_trace_setValue(moduleId, level, 1);
497 }
498 level++;
499 bitmask >>= 1;
500 }
501}
502
503
Jeff Johnson295189b2012-06-20 16:38:30 -0700504/**---------------------------------------------------------------------------
505
506 \brief hdd_wdi_trace_enable() - Configure initial WDI Trace enable
507
508 Called immediately after the cfg.ini is read in order to configure
509 the desired trace levels in the WDI.
510
511 \param - moduleId - module whose trace level is being configured
512 \param - bitmask - bitmask of log levels to be enabled
513
514 \return - void
515
516 --------------------------------------------------------------------------*/
517static void hdd_wdi_trace_enable(wpt_moduleid moduleId, v_U32_t bitmask)
518{
519 wpt_tracelevel level;
520
521 /* if the bitmask is the default value, then a bitmask was not
522 specified in cfg.ini, so leave the logging level alone (it
523 will remain at the "compiled in" default value) */
524 if (CFG_WDI_TRACE_ENABLE_DEFAULT == bitmask)
525 {
526 return;
527 }
528
529 /* a mask was specified. start by disabling all logging */
530 wpalTraceSetLevel(moduleId, eWLAN_PAL_TRACE_LEVEL_NONE, 0);
531
532 /* now cycle through the bitmask until all "set" bits are serviced */
533 level = eWLAN_PAL_TRACE_LEVEL_FATAL;
534 while (0 != bitmask)
535 {
536 if (bitmask & 1)
537 {
538 wpalTraceSetLevel(moduleId, level, 1);
539 }
540 level++;
541 bitmask >>= 1;
542 }
543}
Jeff Johnson295189b2012-06-20 16:38:30 -0700544
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +0530545/*
546 * FUNCTION: wlan_hdd_validate_context
547 * This function is used to check the HDD context
548 */
549int wlan_hdd_validate_context(hdd_context_t *pHddCtx)
550{
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +0530551
552 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
553 {
Mahesh A Saptasagar886997a2015-03-04 13:15:51 +0530554 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +0530555 "%s: HDD context is Null", __func__);
556 return -ENODEV;
557 }
558
559 if (pHddCtx->isLogpInProgress)
560 {
Mahesh A Saptasagar886997a2015-03-04 13:15:51 +0530561 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
c_hpothu8adb97b2014-12-08 19:38:20 +0530562 "%s: LOGP %s. Ignore!!", __func__,
563 vos_is_wlan_in_badState(VOS_MODULE_ID_HDD, NULL)
564 ?"failed":"in Progress");
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +0530565 return -EAGAIN;
566 }
567
Mihir Shete18156292014-03-11 15:38:30 +0530568 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +0530569 {
Mahesh A Saptasagar886997a2015-03-04 13:15:51 +0530570 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +0530571 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
572 return -EAGAIN;
573 }
574 return 0;
575}
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -0700576#ifdef CONFIG_ENABLE_LINUX_REG
577void hdd_checkandupdate_phymode( hdd_context_t *pHddCtx)
578{
579 hdd_adapter_t *pAdapter = NULL;
580 hdd_station_ctx_t *pHddStaCtx = NULL;
581 eCsrPhyMode phyMode;
582 hdd_config_t *cfg_param = NULL;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +0530583
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -0700584 if (NULL == pHddCtx)
585 {
586 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
587 "HDD Context is null !!");
588 return ;
589 }
590
591 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION);
592 if (NULL == pAdapter)
593 {
594 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
595 "pAdapter is null !!");
596 return ;
597 }
598
599 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
600 if (NULL == pHddStaCtx)
601 {
602 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
603 "pHddStaCtx is null !!");
604 return ;
605 }
606
607 cfg_param = pHddCtx->cfg_ini;
608 if (NULL == cfg_param)
609 {
610 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
611 "cfg_params not available !!");
612 return ;
613 }
614
615 phyMode = sme_GetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter));
616
617 if (!pHddCtx->isVHT80Allowed)
618 {
619 if ((eCSR_DOT11_MODE_AUTO == phyMode) ||
620 (eCSR_DOT11_MODE_11ac == phyMode) ||
621 (eCSR_DOT11_MODE_11ac_ONLY == phyMode))
622 {
623 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
624 "Setting phymode to 11n!!");
625 sme_SetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter), eCSR_DOT11_MODE_11n);
626 }
627 }
628 else
629 {
630 /*New country Supports 11ac as well resetting value back from .ini*/
631 sme_SetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter),
632 hdd_cfg_xlate_to_csr_phy_mode(cfg_param->dot11Mode));
633 return ;
634 }
635
636 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
637 ((eCSR_CFG_DOT11_MODE_11AC_ONLY == pHddStaCtx->conn_info.dot11Mode) ||
638 (eCSR_CFG_DOT11_MODE_11AC == pHddStaCtx->conn_info.dot11Mode)))
639 {
640 VOS_STATUS vosStatus;
641
642 // need to issue a disconnect to CSR.
643 INIT_COMPLETION(pAdapter->disconnect_comp_var);
644 vosStatus = sme_RoamDisconnect(WLAN_HDD_GET_HAL_CTX(pAdapter),
645 pAdapter->sessionId,
646 eCSR_DISCONNECT_REASON_UNSPECIFIED );
647
648 if (VOS_STATUS_SUCCESS == vosStatus)
c_hpothu6ff1c3c2013-10-01 19:01:57 +0530649 {
650 long ret;
651
652 ret = wait_for_completion_interruptible_timeout(&pAdapter->disconnect_comp_var,
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -0700653 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
c_hpothu6ff1c3c2013-10-01 19:01:57 +0530654 if (0 >= ret)
655 hddLog(LOGE, FL("failure waiting for disconnect_comp_var %ld"),
656 ret);
657 }
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -0700658
659 }
660}
661#else
Gopichand Nakkaladacbcb52013-04-18 16:41:54 +0530662void hdd_checkandupdate_phymode( hdd_adapter_t *pAdapter, char *country_code)
663{
664 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
665 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
666 hdd_config_t *cfg_param;
667 eCsrPhyMode phyMode;
c_hpothu6ff1c3c2013-10-01 19:01:57 +0530668 long ret;
Gopichand Nakkaladacbcb52013-04-18 16:41:54 +0530669
670 if (NULL == pHddCtx)
671 {
672 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
673 "HDD Context is null !!");
674 return ;
675 }
676
677 cfg_param = pHddCtx->cfg_ini;
678
679 if (NULL == cfg_param)
680 {
681 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
682 "cfg_params not available !!");
683 return ;
684 }
685
686 phyMode = sme_GetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter));
687
688 if (NULL != strstr(cfg_param->listOfNon11acCountryCode, country_code))
689 {
690 if ((eCSR_DOT11_MODE_AUTO == phyMode) ||
691 (eCSR_DOT11_MODE_11ac == phyMode) ||
692 (eCSR_DOT11_MODE_11ac_ONLY == phyMode))
693 {
694 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
695 "Setting phymode to 11n!!");
696 sme_SetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter), eCSR_DOT11_MODE_11n);
697 }
698 }
699 else
700 {
701 /*New country Supports 11ac as well resetting value back from .ini*/
702 sme_SetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter),
703 hdd_cfg_xlate_to_csr_phy_mode(cfg_param->dot11Mode));
704 return ;
705 }
706
707 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
708 ((eCSR_CFG_DOT11_MODE_11AC_ONLY == pHddStaCtx->conn_info.dot11Mode) ||
709 (eCSR_CFG_DOT11_MODE_11AC == pHddStaCtx->conn_info.dot11Mode)))
710 {
711 VOS_STATUS vosStatus;
712
713 // need to issue a disconnect to CSR.
714 INIT_COMPLETION(pAdapter->disconnect_comp_var);
715 vosStatus = sme_RoamDisconnect(WLAN_HDD_GET_HAL_CTX(pAdapter),
716 pAdapter->sessionId,
717 eCSR_DISCONNECT_REASON_UNSPECIFIED );
718
719 if (VOS_STATUS_SUCCESS == vosStatus)
c_hpothu6ff1c3c2013-10-01 19:01:57 +0530720 {
721 ret = wait_for_completion_interruptible_timeout(&pAdapter->disconnect_comp_var,
Gopichand Nakkaladacbcb52013-04-18 16:41:54 +0530722 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
c_hpothu6ff1c3c2013-10-01 19:01:57 +0530723 if (ret <= 0)
724 {
725 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
726 "wait on disconnect_comp_var is failed %ld", ret);
727 }
728 }
Gopichand Nakkaladacbcb52013-04-18 16:41:54 +0530729
730 }
731}
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -0700732#endif //CONFIG_ENABLE_LINUX_REG
Gopichand Nakkaladacbcb52013-04-18 16:41:54 +0530733
Tushnim Bhattacharyya9cdf6082013-04-21 16:33:30 -0700734void hdd_checkandupdate_dfssetting( hdd_adapter_t *pAdapter, char *country_code)
735{
736 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
737 hdd_config_t *cfg_param;
738
739 if (NULL == pHddCtx)
740 {
741 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
742 "HDD Context is null !!");
743 return ;
744 }
745
746 cfg_param = pHddCtx->cfg_ini;
747
748 if (NULL == cfg_param)
749 {
750 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
751 "cfg_params not available !!");
752 return ;
753 }
754
Agarwal Ashish738843c2014-09-25 12:27:56 +0530755 if (NULL != strstr(cfg_param->listOfNonDfsCountryCode, country_code) ||
756 pHddCtx->disable_dfs_flag == TRUE)
Tushnim Bhattacharyya9cdf6082013-04-21 16:33:30 -0700757 {
758 /*New country doesn't support DFS */
759 sme_UpdateDfsSetting(WLAN_HDD_GET_HAL_CTX(pAdapter), 0);
760 }
Tushnim Bhattacharyya9cdf6082013-04-21 16:33:30 -0700761
762}
763
Abhishek Singh00b71972016-01-07 10:51:04 +0530764#ifdef WLAN_FEATURE_RMC
765static int hdd_parse_setrmcenable_command(tANI_U8 *pValue, tANI_U8 *pRmcEnable)
766{
767 tANI_U8 *inPtr = pValue;
768 int tempInt;
769 int v = 0;
770 char buf[32];
771 *pRmcEnable = 0;
772
773 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
774 /*no argument after the command*/
775 if (NULL == inPtr)
776 {
777 return 0;
778 }
779
780 /*no space after the command*/
781 else if (SPACE_ASCII_VALUE != *inPtr)
782 {
783 return 0;
784 }
785
786 /*removing empty spaces*/
787 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
788
789 /*no argument followed by spaces*/
790 if ('\0' == *inPtr)
791 {
792 return 0;
793 }
794
795 /* getting the first argument which enables or disables RMC
796 * for input IP v4 address*/
797 sscanf(inPtr, "%32s ", buf);
798 v = kstrtos32(buf, 10, &tempInt);
799 if ( v < 0)
800 {
801 return -EINVAL;
802 }
803
804 *pRmcEnable = tempInt;
805
806 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
807 "ucRmcEnable: %d", *pRmcEnable);
808
809 return 0;
810}
811
812/* Function header left blank Intentionally */
813static int hdd_parse_setrmcactionperiod_command(tANI_U8 *pValue,
814 tANI_U32 *pActionPeriod)
815{
816 tANI_U8 *inPtr = pValue;
817 int tempInt;
818 int v = 0;
819 char buf[32];
820 *pActionPeriod = 0;
821
822 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
823 /*no argument after the command*/
824 if (NULL == inPtr)
825 {
826 return -EINVAL;
827 }
828
829 /*no space after the command*/
830 else if (SPACE_ASCII_VALUE != *inPtr)
831 {
832 return -EINVAL;
833 }
834
835 /*removing empty spaces*/
836 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
837
838 /*no argument followed by spaces*/
839 if ('\0' == *inPtr)
840 {
841 return 0;
842 }
843
844 /* getting the first argument which enables or disables RMC
845 * for input IP v4 address*/
846 sscanf(inPtr, "%32s ", buf);
847 v = kstrtos32(buf, 10, &tempInt);
848 if ( v < 0)
849 {
850 return -EINVAL;
851 }
852
853 /* Range checking for passed paramter */
854 if (tempInt < WNI_CFG_RMC_ACTION_PERIOD_FREQUENCY_STAMIN ||
855 tempInt > WNI_CFG_RMC_ACTION_PERIOD_FREQUENCY_STAMAX)
856 {
857 return -EINVAL;
858 }
859
860 *pActionPeriod = tempInt;
861
862 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
863 "uActionPeriod: %d", *pActionPeriod);
864
865 return 0;
866}
867
868/* Function header left blank Intentionally */
869static int hdd_parse_setrmcrate_command(tANI_U8 *pValue,
870 tANI_U32 *pRate, tTxrateinfoflags *pTxFlags)
871{
872 tANI_U8 *inPtr = pValue;
873 int tempInt;
874 int v = 0;
875 char buf[32];
876 *pRate = 0;
877 *pTxFlags = 0;
878
879 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
880 /*no argument after the command*/
881 if (NULL == inPtr)
882 {
883 return -EINVAL;
884 }
885
886 /*no space after the command*/
887 else if (SPACE_ASCII_VALUE != *inPtr)
888 {
889 return -EINVAL;
890 }
891
892 /*removing empty spaces*/
893 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
894
895 /*no argument followed by spaces*/
896 if ('\0' == *inPtr)
897 {
898 return 0;
899 }
900
901 /*
902 * getting the first argument which sets multicast rate.
903 */
904 sscanf(inPtr, "%32s ", buf);
905 v = kstrtos32(buf, 10, &tempInt);
906 if ( v < 0)
907 {
908 return -EINVAL;
909 }
910
911 /*
912 * Validate the multicast rate.
913 */
914 switch (tempInt)
915 {
916 default:
917 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
918 "Unsupported rate: %d", tempInt);
919 return -EINVAL;
920 case 0:
921 case 6:
922 case 9:
923 case 12:
924 case 18:
925 case 24:
926 case 36:
927 case 48:
928 case 54:
929 *pTxFlags = eHAL_TX_RATE_LEGACY;
930 *pRate = tempInt * 10;
931 break;
932 case 65:
933 *pTxFlags = eHAL_TX_RATE_HT20;
934 *pRate = tempInt * 10;
935 break;
936 case 72:
937 *pTxFlags = eHAL_TX_RATE_HT20 | eHAL_TX_RATE_SGI;
938 *pRate = 722; /* fractional rate 72.2 Mbps */
939 break;
940 }
941
942 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
943 "Rate: %d", *pRate);
944
945 return 0;
946}
947
948/**---------------------------------------------------------------------------
949
950 \brief hdd_cfg80211_get_ibss_peer_info_cb() - Callback function for IBSS
951 Peer Info request
952
953 This is an asynchronous callback function from SME when the peer info
954 is received
955
956 \pUserData -> Adapter private data
957 \pPeerInfoRsp -> Peer info response
958
959 \return - 0 for success non-zero for failure
960 --------------------------------------------------------------------------*/
961static void
962hdd_cfg80211_get_ibss_peer_info_cb(v_VOID_t *pUserData, v_VOID_t *pPeerInfoRsp)
963{
964 hdd_adapter_t *pAdapter = (hdd_adapter_t *)pUserData;
965 tSirPeerInfoRspParams *pPeerInfo = (tSirPeerInfoRspParams *)pPeerInfoRsp;
966 hdd_station_ctx_t *pStaCtx;
967 v_U8_t i;
968
969 /*Sanity check*/
970 if ((NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic))
971 {
972 hddLog(LOGE,
973 FL("invalid adapter or adapter has invalid magic"));
974 return;
975 }
976
977 pStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
978 if (NULL != pStaCtx && NULL != pPeerInfo &&
979 eHAL_STATUS_SUCCESS == pPeerInfo->status)
980 {
981 pStaCtx->ibss_peer_info.status = pPeerInfo->status;
982 pStaCtx->ibss_peer_info.numIBSSPeers = pPeerInfo->numPeers;
983
984 /* Paranoia check */
985 if (pPeerInfo->numPeers < HDD_MAX_NUM_IBSS_STA)
986 {
987 for (i = 0; i < pPeerInfo->numPeers; i++)
988 {
989 memcpy(&pStaCtx->ibss_peer_info.ibssPeerList[i],
990 &pPeerInfo->peerInfoParams[i],
991 sizeof(hdd_ibss_peer_info_params_t));
992 }
993 hddLog(LOG1,
994 FL("Peer Info copied in HDD"));
995 }
996 else
997 {
998 hddLog(LOGE,
999 FL(" Number of peers %d returned is more than limit %d"),
1000 pPeerInfo->numPeers, HDD_MAX_NUM_IBSS_STA);
1001 }
1002 }
1003 else
1004 {
1005 hddLog(LOG1,
1006 FL("peerInfo returned is NULL"));
1007 }
1008
1009 complete(&pAdapter->ibss_peer_info_comp);
1010}
1011
1012/**---------------------------------------------------------------------------
1013
1014 \brief hdd_cfg80211_get_ibss_peer_info_all() -
1015
1016 Request function to get IBSS peer info from lower layers
1017
1018 \pAdapter -> Adapter context
1019
1020 \return - 0 for success non-zero for failure
1021 --------------------------------------------------------------------------*/
1022static
1023VOS_STATUS hdd_cfg80211_get_ibss_peer_info_all(hdd_adapter_t *pAdapter)
1024{
1025 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
1026 long status;
1027 VOS_STATUS retStatus = VOS_STATUS_E_FAILURE;
1028
1029 INIT_COMPLETION(pAdapter->ibss_peer_info_comp);
1030
1031 retStatus = sme_RequestIBSSPeerInfo(hHal, pAdapter,
1032 hdd_cfg80211_get_ibss_peer_info_cb,
1033 VOS_TRUE, 0xFF);
1034
1035 if (VOS_STATUS_SUCCESS == retStatus)
1036 {
1037 status = wait_for_completion_interruptible_timeout
1038 (&pAdapter->ibss_peer_info_comp,
1039 msecs_to_jiffies(IBSS_PEER_INFO_REQ_TIMOEUT));
1040
1041 /* status will be 0 if timed out */
1042 if (status <= 0)
1043 {
1044 hddLog(VOS_TRACE_LEVEL_WARN, "%s: Warning: IBSS_PEER_INFO_TIMEOUT %ld",
1045 __func__, status);
1046 retStatus = VOS_STATUS_E_FAILURE;
1047 return retStatus;
1048 }
1049 }
1050 else
1051 {
1052 hddLog(VOS_TRACE_LEVEL_WARN,
1053 "%s: Warning: sme_RequestIBSSPeerInfo Request failed", __func__);
1054 }
1055
1056 return retStatus;
1057}
1058
1059/**---------------------------------------------------------------------------
1060
1061 \brief hdd_cfg80211_get_ibss_peer_info() -
1062
1063 Request function to get IBSS peer info from lower layers
1064
1065 \pAdapter -> Adapter context
1066 \staIdx -> Sta index for which the peer info is requested
1067
1068 \return - 0 for success non-zero for failure
1069 --------------------------------------------------------------------------*/
1070static VOS_STATUS
1071hdd_cfg80211_get_ibss_peer_info(hdd_adapter_t *pAdapter, v_U8_t staIdx)
1072{
1073 long status;
1074 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
1075 VOS_STATUS retStatus = VOS_STATUS_E_FAILURE;
1076
1077 INIT_COMPLETION(pAdapter->ibss_peer_info_comp);
1078
1079 retStatus = sme_RequestIBSSPeerInfo(hHal, pAdapter,
1080 hdd_cfg80211_get_ibss_peer_info_cb,
1081 VOS_FALSE, staIdx);
1082
1083 if (VOS_STATUS_SUCCESS == retStatus)
1084 {
1085 status = wait_for_completion_interruptible_timeout
1086 (&pAdapter->ibss_peer_info_comp,
1087 msecs_to_jiffies(IBSS_PEER_INFO_REQ_TIMOEUT));
1088
1089 /* status = 0 on timeout */
1090 if (status <= 0)
1091 {
1092 hddLog(VOS_TRACE_LEVEL_WARN, "%s: Warning: IBSS_PEER_INFO_TIMEOUT %ld",
1093 __func__, status);
1094 retStatus = VOS_STATUS_E_FAILURE;
1095 return retStatus;
1096 }
1097 }
1098 else
1099 {
1100 hddLog(VOS_TRACE_LEVEL_WARN,
1101 "%s: Warning: sme_RequestIBSSPeerInfo Request failed", __func__);
1102 }
1103
1104 return retStatus;
1105}
1106
1107/* Function header left blank Intentionally */
1108VOS_STATUS
1109hdd_parse_get_ibss_peer_info(tANI_U8 *pValue, v_MACADDR_t *pPeerMacAddr)
1110{
1111 tANI_U8 *inPtr = pValue;
1112 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
1113
1114 /*no argument after the command*/
1115 if (NULL == inPtr)
1116 {
1117 return VOS_STATUS_E_FAILURE;;
1118 }
1119
1120 /*no space after the command*/
1121 else if (SPACE_ASCII_VALUE != *inPtr)
1122 {
1123 return VOS_STATUS_E_FAILURE;;
1124 }
1125
1126 /*removing empty spaces*/
1127 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
1128
1129 /*no argument followed by spaces*/
1130 if ('\0' == *inPtr)
1131 {
1132 return VOS_STATUS_E_FAILURE;;
1133 }
1134
1135 /*getting the first argument ie the peer mac address */
1136 if (inPtr[2] != ':' || inPtr[5] != ':' || inPtr[8] != ':' ||
1137 inPtr[11] != ':' || inPtr[14] != ':')
1138 {
1139 return VOS_STATUS_E_FAILURE;;
1140 }
1141 sscanf(inPtr, "%2x:%2x:%2x:%2x:%2x:%2x",
1142 (unsigned int *)&pPeerMacAddr->bytes[0],
1143 (unsigned int *)&pPeerMacAddr->bytes[1],
1144 (unsigned int *)&pPeerMacAddr->bytes[2],
1145 (unsigned int *)&pPeerMacAddr->bytes[3],
1146 (unsigned int *)&pPeerMacAddr->bytes[4],
1147 (unsigned int *)&pPeerMacAddr->bytes[5]);
1148
1149 /* The command buffer seems to be fine */
1150 return VOS_STATUS_SUCCESS;
1151}
1152
1153/* Function header left blank Intentionally */
1154static int hdd_parse_set_ibss_oui_data_command(tANI_U8 *command, tANI_U8 *ie,
1155 tANI_U32 limit)
1156{
1157 tANI_U8 len;
1158 tANI_U8 data;
1159
1160 /* skip white space */
1161 while ((SPACE_ASCII_VALUE == *command) && ('\0' != *command))
1162 {
1163 command++;
1164 limit--;
1165 }
1166
1167 /* skip element id and element length */
1168 len = 2;
1169
1170 /* extract oui */
1171 while ((SPACE_ASCII_VALUE != *command) && ('\0' != *command) &&
1172 (limit > 1))
1173 {
1174 /* Convert ASCII to decimal */
1175 data = ((*command -'0') << 4) | (*(command + 1) - '0');
1176 ie[len++] = data;
1177 command += 2;
1178 limit -= 2;
1179 }
1180
1181 /* skip white space */
1182 while ((SPACE_ASCII_VALUE == *command) && ('\0' != *command))
1183 {
1184 command++;
1185 limit--;
1186 }
1187
1188 /* extract data */
1189 while ((SPACE_ASCII_VALUE != *command) && ('\0' != *command) &&
1190 (limit > 1))
1191 {
1192 /* Convert ASCII to decimal */
1193 data = ((*command -'0') << 4) | (*(command + 1) - '0');
1194 ie[len++] = data;
1195 command += 2;
1196 limit -= 2;
1197 }
1198
1199 /* fill element id and element length */
1200 ie[0] = IE_EID_VENDOR;
1201 ie[1] = len - 2;
1202
1203 return len;
1204}
1205
1206static tANI_U32 hdd_find_ibss_wpa_ie_pos(tANI_U8 *addIePtr, tANI_U32 addIeLen)
1207{
1208 tANI_U32 ieLenPresent = 0;
1209 int left = addIeLen;
1210 v_U8_t *ptr = addIePtr;
1211 v_U8_t elem_id,elem_len;
1212
1213 while(left >= 2)
1214 {
1215 elem_id = ptr[0];
1216 elem_len = ptr[1];
1217 left -= 2;
1218 if(elem_len > left)
1219 {
1220 hddLog(LOGE,
1221 FL("****Invalid elem_len=%d left=%d*****"),
1222 elem_len,left);
1223 return 0;
1224 }
1225 if ((elem_id == IE_EID_VENDOR) &&
1226 (left >= WPA_OUI_TYPE_SIZE))
1227 {
1228 if (!memcmp(&ptr[2], WPA_OUI_TYPE,
1229 WPA_OUI_TYPE_SIZE))
1230 {
1231 ieLenPresent += elem_len + 2;
1232 return ieLenPresent;
1233 }
1234 }
1235 ieLenPresent += (elem_len + 2);
1236 left -= elem_len;
1237 ptr += (elem_len + 2);
1238 }
1239 return 0;
1240}
1241
1242#endif /* WLAN_FEATURE_RMC */
1243
Rajeev79dbe4c2013-10-05 11:03:42 +05301244#ifdef FEATURE_WLAN_BATCH_SCAN
1245
1246/**---------------------------------------------------------------------------
1247
1248 \brief hdd_extract_assigned_int_from_str() - Extracts assigned integer from
1249 input string
1250
1251 This function extracts assigned integer from string in below format:
1252 "STRING=10" : extracts integer 10 from this string
1253
1254 \param - pInPtr Pointer to input string
1255 \param - base Base for string to int conversion(10 for decimal 16 for hex)
1256 \param - pOutPtr Pointer to variable in which extracted integer needs to be
1257 assigned
1258 \param - pLastArg to tell whether it is last arguement in input string or
1259 not
1260
1261 \return - NULL for failure cases
1262 pointer to next arguement in input string for success cases
1263 --------------------------------------------------------------------------*/
1264static tANI_U8 *
1265hdd_extract_assigned_int_from_str
1266(
1267 tANI_U8 *pInPtr,
1268 tANI_U8 base,
1269 tANI_U32 *pOutPtr,
1270 tANI_U8 *pLastArg
1271)
1272{
1273 int tempInt;
1274 int v = 0;
1275 char buf[32];
1276 int val = 0;
1277 *pLastArg = FALSE;
1278
1279 pInPtr = strnchr(pInPtr, strlen(pInPtr), EQUALS_TO_ASCII_VALUE);
1280 if (NULL == pInPtr)
1281 {
1282 return NULL;
1283 }
1284
1285 pInPtr++;
1286
1287 while ((SPACE_ASCII_VALUE == *pInPtr) && ('\0' != *pInPtr)) pInPtr++;
1288
1289 val = sscanf(pInPtr, "%32s ", buf);
1290 if (val < 0 && val > strlen(pInPtr))
1291 {
1292 return NULL;
1293 }
1294 pInPtr += val;
1295 v = kstrtos32(buf, base, &tempInt);
1296 if (v < 0)
1297 {
1298 return NULL;
1299 }
Rajeev Kumar4d93d842014-01-02 18:31:21 -08001300 if (tempInt < 0)
1301 {
1302 tempInt = 0;
1303 }
Rajeev79dbe4c2013-10-05 11:03:42 +05301304 *pOutPtr = tempInt;
1305
1306 pInPtr = strnchr(pInPtr, strlen(pInPtr), SPACE_ASCII_VALUE);
1307 if (NULL == pInPtr)
1308 {
1309 *pLastArg = TRUE;
1310 return NULL;
1311 }
1312 while ((SPACE_ASCII_VALUE == *pInPtr) && ('\0' != *pInPtr)) pInPtr++;
1313
1314 return pInPtr;
1315}
1316
1317/**---------------------------------------------------------------------------
1318
1319 \brief hdd_extract_assigned_char_from_str() - Extracts assigned char from
1320 input string
1321
1322 This function extracts assigned character from string in below format:
1323 "STRING=A" : extracts char 'A' from this string
1324
1325 \param - pInPtr Pointer to input string
1326 \param - pOutPtr Pointer to variable in which extracted char needs to be
1327 assigned
1328 \param - pLastArg to tell whether it is last arguement in input string or
1329 not
1330
1331 \return - NULL for failure cases
1332 pointer to next arguement in input string for success cases
1333 --------------------------------------------------------------------------*/
1334static tANI_U8 *
1335hdd_extract_assigned_char_from_str
1336(
1337 tANI_U8 *pInPtr,
1338 tANI_U8 *pOutPtr,
1339 tANI_U8 *pLastArg
1340)
1341{
1342 *pLastArg = FALSE;
1343
1344 pInPtr = strnchr(pInPtr, strlen(pInPtr), EQUALS_TO_ASCII_VALUE);
1345 if (NULL == pInPtr)
1346 {
1347 return NULL;
1348 }
1349
1350 pInPtr++;
1351
1352 while ((SPACE_ASCII_VALUE == *pInPtr) && ('\0' != *pInPtr)) pInPtr++;
1353
1354 *pOutPtr = *pInPtr;
1355
1356 pInPtr = strnchr(pInPtr, strlen(pInPtr), SPACE_ASCII_VALUE);
1357 if (NULL == pInPtr)
1358 {
1359 *pLastArg = TRUE;
1360 return NULL;
1361 }
1362 while ((SPACE_ASCII_VALUE == *pInPtr) && ('\0' != *pInPtr)) pInPtr++;
1363
1364 return pInPtr;
1365}
1366
1367
1368/**---------------------------------------------------------------------------
1369
1370 \brief hdd_parse_set_batchscan_command () - HDD parse set batch scan command
1371
1372 This function parses set batch scan command in below format:
1373 WLS_BATCHING_SET <space> followed by below arguements
1374 "SCANFREQ=XX" : Optional defaults to 30 sec
1375 "MSCAN=XX" : Required number of scans to attempt to batch
1376 "BESTN=XX" : Best Network (RSSI) defaults to 16
1377 "CHANNEL=<X,Y>" : optional defaults to all channels, can list 'A'or` B.
1378 A. implies only 5 GHz , B. implies only 2.4GHz
1379 "RTT=X" : optional defaults to 0
1380 returns the MIN of MSCAN or the max # of scans firmware can cache or -1 on
1381 error
1382
1383 For example input commands:
1384 1) WLS_BATCHING_SET SCANFREQ=60 MSCAN=10 BESTN=20 CHANNEL=A RTT=0 -> This is
1385 translated into set batch scan with following parameters:
1386 a) Frequence 60 seconds
1387 b) Batch 10 scans together
1388 c) Best RSSI to be 20
1389 d) 5GHz band only
1390 e) RTT is equal to 0
1391
1392 \param - pValue Pointer to input channel list
1393 \param - pHddSetBatchScanReq Pointer to HDD batch scan request structure
1394
1395 \return - 0 for success non-zero for failure
1396
1397 --------------------------------------------------------------------------*/
1398static int
1399hdd_parse_set_batchscan_command
1400(
1401 tANI_U8 *pValue,
1402 tSirSetBatchScanReq *pHddSetBatchScanReq
1403)
1404{
1405 tANI_U8 *inPtr = pValue;
1406 tANI_U8 val = 0;
1407 tANI_U8 lastArg = 0;
Abhishek Singh00b71972016-01-07 10:51:04 +05301408 tANI_U32 nScanFreq = HDD_SET_BATCH_SCAN_DEFAULT_FREQ;
Rajeev Kumar45e64a72013-11-18 19:48:15 -08001409 tANI_U32 nMscan;
Abhishek Singh00b71972016-01-07 10:51:04 +05301410 tANI_U32 nBestN = HDD_SET_BATCH_SCAN_BEST_NETWORK;
1411 tANI_U8 ucRfBand = HDD_SET_BATCH_SCAN_DEFAULT_BAND;
1412 tANI_U32 nRtt = 0;
Rajeev Kumarc933d982013-11-18 20:04:20 -08001413 tANI_U32 temp;
Rajeev79dbe4c2013-10-05 11:03:42 +05301414
Rajeev79dbe4c2013-10-05 11:03:42 +05301415 /*go to space after WLS_BATCHING_SET command*/
1416 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
1417 /*no argument after the command*/
1418 if (NULL == inPtr)
1419 {
1420 return -EINVAL;
1421 }
1422
1423 /*no space after the command*/
1424 else if (SPACE_ASCII_VALUE != *inPtr)
1425 {
1426 return -EINVAL;
1427 }
1428
1429 /*removing empty spaces*/
1430 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
1431
1432 /*no argument followed by spaces*/
1433 if ('\0' == *inPtr)
1434 {
1435 return -EINVAL;
1436 }
1437
1438 /*check and parse SCANFREQ*/
1439 if ((strncmp(inPtr, "SCANFREQ", 8) == 0))
1440 {
1441 inPtr = hdd_extract_assigned_int_from_str(inPtr, 10,
Rajeev Kumarc933d982013-11-18 20:04:20 -08001442 &temp, &lastArg);
Rajeev Kumar45e64a72013-11-18 19:48:15 -08001443
Rajeev Kumarc933d982013-11-18 20:04:20 -08001444 if (0 != temp)
Rajeev Kumar45e64a72013-11-18 19:48:15 -08001445 {
Rajeev Kumarc933d982013-11-18 20:04:20 -08001446 nScanFreq = temp;
Rajeev Kumar45e64a72013-11-18 19:48:15 -08001447 }
1448
Rajeev79dbe4c2013-10-05 11:03:42 +05301449 if ( (NULL == inPtr) || (TRUE == lastArg))
1450 {
1451 return -EINVAL;
1452 }
1453 }
1454
1455 /*check and parse MSCAN*/
1456 if ((strncmp(inPtr, "MSCAN", 5) == 0))
1457 {
1458 inPtr = hdd_extract_assigned_int_from_str(inPtr, 10,
Rajeev Kumar45e64a72013-11-18 19:48:15 -08001459 &nMscan, &lastArg);
1460
1461 if (0 == nMscan)
1462 {
1463 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1464 "invalid MSCAN=%d", nMscan);
1465 return -EINVAL;
1466 }
1467
Rajeev79dbe4c2013-10-05 11:03:42 +05301468 if (TRUE == lastArg)
1469 {
1470 goto done;
1471 }
1472 else if (NULL == inPtr)
1473 {
1474 return -EINVAL;
1475 }
1476 }
1477 else
1478 {
1479 return -EINVAL;
1480 }
1481
1482 /*check and parse BESTN*/
1483 if ((strncmp(inPtr, "BESTN", 5) == 0))
1484 {
1485 inPtr = hdd_extract_assigned_int_from_str(inPtr, 10,
Rajeev Kumarc933d982013-11-18 20:04:20 -08001486 &temp, &lastArg);
Rajeev Kumar45e64a72013-11-18 19:48:15 -08001487
Rajeev Kumarc933d982013-11-18 20:04:20 -08001488 if (0 != temp)
Rajeev Kumar45e64a72013-11-18 19:48:15 -08001489 {
Rajeev Kumarc933d982013-11-18 20:04:20 -08001490 nBestN = temp;
Rajeev Kumar45e64a72013-11-18 19:48:15 -08001491 }
1492
Rajeev79dbe4c2013-10-05 11:03:42 +05301493 if (TRUE == lastArg)
1494 {
1495 goto done;
1496 }
1497 else if (NULL == inPtr)
1498 {
1499 return -EINVAL;
1500 }
1501 }
1502
1503 /*check and parse CHANNEL*/
1504 if ((strncmp(inPtr, "CHANNEL", 7) == 0))
1505 {
1506 inPtr = hdd_extract_assigned_char_from_str(inPtr, &val, &lastArg);
Rajeev Kumarc933d982013-11-18 20:04:20 -08001507
Rajeev79dbe4c2013-10-05 11:03:42 +05301508 if (('A' == val) || ('a' == val))
1509 {
c_hpothuebf89732014-02-25 13:00:24 +05301510 ucRfBand = HDD_SET_BATCH_SCAN_5GHz_BAND_ONLY;
Rajeev79dbe4c2013-10-05 11:03:42 +05301511 }
1512 else if (('B' == val) || ('b' == val))
1513 {
c_hpothuebf89732014-02-25 13:00:24 +05301514 ucRfBand = HDD_SET_BATCH_SCAN_24GHz_BAND_ONLY;
Rajeev79dbe4c2013-10-05 11:03:42 +05301515 }
1516 else
1517 {
Rajeev Kumarc933d982013-11-18 20:04:20 -08001518 ucRfBand = HDD_SET_BATCH_SCAN_DEFAULT_BAND;
1519 }
1520
1521 if (TRUE == lastArg)
1522 {
1523 goto done;
1524 }
1525 else if (NULL == inPtr)
1526 {
Rajeev79dbe4c2013-10-05 11:03:42 +05301527 return -EINVAL;
1528 }
1529 }
1530
1531 /*check and parse RTT*/
1532 if ((strncmp(inPtr, "RTT", 3) == 0))
1533 {
1534 inPtr = hdd_extract_assigned_int_from_str(inPtr, 10,
Rajeev Kumar45e64a72013-11-18 19:48:15 -08001535 &nRtt, &lastArg);
Rajeev79dbe4c2013-10-05 11:03:42 +05301536 if (TRUE == lastArg)
1537 {
1538 goto done;
1539 }
1540 if (NULL == inPtr)
1541 {
1542 return -EINVAL;
1543 }
1544 }
1545
1546
1547done:
1548
Rajeev Kumar45e64a72013-11-18 19:48:15 -08001549 pHddSetBatchScanReq->scanFrequency = nScanFreq;
1550 pHddSetBatchScanReq->numberOfScansToBatch = nMscan;
1551 pHddSetBatchScanReq->bestNetwork = nBestN;
1552 pHddSetBatchScanReq->rfBand = ucRfBand;
1553 pHddSetBatchScanReq->rtt = nRtt;
1554
Rajeev79dbe4c2013-10-05 11:03:42 +05301555 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1556 "Received WLS_BATCHING_SET with SCANFREQ=%d "
1557 "MSCAN=%d BESTN=%d CHANNEL=%d RTT=%d",
1558 pHddSetBatchScanReq->scanFrequency,
1559 pHddSetBatchScanReq->numberOfScansToBatch,
1560 pHddSetBatchScanReq->bestNetwork,
1561 pHddSetBatchScanReq->rfBand,
1562 pHddSetBatchScanReq->rtt);
1563
1564 return 0;
1565}/*End of hdd_parse_set_batchscan_command*/
1566
1567/**---------------------------------------------------------------------------
1568
1569 \brief hdd_set_batch_scan_req_callback () - This function is called after
1570 receiving set batch scan response from FW and it saves set batch scan
1571 response data FW to HDD context and sets the completion event on
1572 which hdd_ioctl is waiting
1573
1574 \param - callbackContext Pointer to HDD adapter
1575 \param - pRsp Pointer to set batch scan response data received from FW
1576
1577 \return - nothing
1578
1579 --------------------------------------------------------------------------*/
1580static void hdd_set_batch_scan_req_callback
1581(
1582 void *callbackContext,
1583 tSirSetBatchScanRsp *pRsp
1584)
1585{
1586 hdd_adapter_t* pAdapter = (hdd_adapter_t*)callbackContext;
1587 tSirSetBatchScanRsp *pHddSetBatchScanRsp;
1588
1589 /*sanity check*/
1590 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
1591 {
1592 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1593 "%s: Invalid pAdapter magic", __func__);
1594 VOS_ASSERT(0);
1595 return;
1596 }
1597 pHddSetBatchScanRsp = &pAdapter->hddSetBatchScanRsp;
1598
1599 /*save set batch scan response*/
1600 pHddSetBatchScanRsp->nScansToBatch = pRsp->nScansToBatch;
1601
1602 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
1603 "Received set batch scan rsp from FW with nScansToBatch=%d",
1604 pHddSetBatchScanRsp->nScansToBatch);
1605
1606 pAdapter->hdd_wait_for_set_batch_scan_rsp = FALSE;
1607 complete(&pAdapter->hdd_set_batch_scan_req_var);
1608
1609 return;
1610}/*End of hdd_set_batch_scan_req_callback*/
1611
1612
1613/**---------------------------------------------------------------------------
1614
1615 \brief hdd_populate_batch_scan_rsp_queue () - This function stores AP meta
1616 info in hdd batch scan response queue
1617
1618 \param - pAdapter Pointer to hdd adapter
1619 \param - pAPMetaInfo Pointer to access point meta info
1620 \param - scanId scan ID of batch scan response
1621 \param - isLastAp tells whether AP is last AP in batch scan response or not
1622
1623 \return - nothing
1624
1625 --------------------------------------------------------------------------*/
1626static void hdd_populate_batch_scan_rsp_queue( hdd_adapter_t* pAdapter,
1627 tpSirBatchScanNetworkInfo pApMetaInfo, tANI_U32 scanId, v_BOOL_t isLastAp)
1628{
1629 tHddBatchScanRsp *pHead;
1630 tHddBatchScanRsp *pNode;
1631 tHddBatchScanRsp *pPrev;
1632 tHddBatchScanRsp *pTemp;
1633 tANI_U8 ssidLen;
1634
1635 /*head of hdd batch scan response queue*/
1636 pHead = pAdapter->pBatchScanRsp;
1637
1638 pNode = (tHddBatchScanRsp *)vos_mem_malloc(sizeof(tHddBatchScanRsp));
1639 if (NULL == pNode)
1640 {
1641 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1642 "%s: Could not allocate memory", __func__);
1643 VOS_ASSERT(0);
1644 return;
1645 }
1646
1647 vos_mem_copy(pNode->ApInfo.bssid, pApMetaInfo->bssid,
1648 sizeof(pNode->ApInfo.bssid));
1649 ssidLen = strlen(pApMetaInfo->ssid);
1650 if (SIR_MAX_SSID_SIZE < ssidLen)
1651 {
1652 /*invalid scan result*/
1653 vos_mem_free(pNode);
1654 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1655 "%s: Invalid AP meta info ssidlen %d", __func__, ssidLen);
1656 return;
1657 }
1658 vos_mem_copy(pNode->ApInfo.ssid, pApMetaInfo->ssid, ssidLen);
1659 /*null terminate ssid*/
1660 pNode->ApInfo.ssid[ssidLen] = '\0';
1661 pNode->ApInfo.ch = pApMetaInfo->ch;
1662 pNode->ApInfo.rssi = pApMetaInfo->rssi;
1663 pNode->ApInfo.age = pApMetaInfo->timestamp;
1664 pNode->ApInfo.batchId = scanId;
1665 pNode->ApInfo.isLastAp = isLastAp;
1666
1667 pNode->pNext = NULL;
1668 if (NULL == pHead)
1669 {
1670 pAdapter->pBatchScanRsp = pNode;
1671 }
1672 else
1673 {
1674 pTemp = pHead;
1675 while (NULL != pTemp)
1676 {
1677 pPrev = pTemp;
1678 pTemp = pTemp->pNext;
1679 }
1680 pPrev->pNext = pNode;
1681 }
1682
1683 return;
1684}/*End of hdd_populate_batch_scan_rsp_queue*/
1685
1686/**---------------------------------------------------------------------------
1687
1688 \brief hdd_batch_scan_result_ind_callback () - This function is called after
1689 receiving batch scan response indication from FW. It saves get batch scan
1690 response data in HDD batch scan response queue. This callback sets the
1691 completion event on which hdd_ioctl is waiting only after getting complete
1692 batch scan response data from FW
1693
1694 \param - callbackContext Pointer to HDD adapter
1695 \param - pRsp Pointer to get batch scan response data received from FW
1696
1697 \return - nothing
1698
1699 --------------------------------------------------------------------------*/
1700static void hdd_batch_scan_result_ind_callback
1701(
1702 void *callbackContext,
1703 void *pRsp
1704)
1705{
1706 v_BOOL_t isLastAp;
1707 tANI_U32 numApMetaInfo;
Rajeev Kumarce651e42013-10-21 18:57:15 -07001708 tANI_U32 numNetworkInScanList;
Rajeev79dbe4c2013-10-05 11:03:42 +05301709 tANI_U32 numberScanList;
1710 tANI_U32 nextScanListOffset;
1711 tANI_U32 nextApMetaInfoOffset;
1712 hdd_adapter_t* pAdapter;
1713 tpSirBatchScanList pScanList;
1714 tpSirBatchScanNetworkInfo pApMetaInfo;
1715 tpSirBatchScanResultIndParam pBatchScanRsp;/*batch scan rsp data from FW*/
1716 tSirSetBatchScanReq *pReq;
1717
1718 pAdapter = (hdd_adapter_t *)callbackContext;
1719 /*sanity check*/
Rajeev Kumar5286bb92013-12-05 11:52:10 -08001720 if ((NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic))
Rajeev79dbe4c2013-10-05 11:03:42 +05301721 {
1722 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1723 "%s: Invalid pAdapter magic", __func__);
1724 VOS_ASSERT(0);
1725 return;
1726 }
1727
1728 /*initialize locals*/
1729 pReq = &pAdapter->hddSetBatchScanReq;
1730 pBatchScanRsp = (tpSirBatchScanResultIndParam)pRsp;
1731 isLastAp = FALSE;
1732 numApMetaInfo = 0;
Rajeev Kumarce651e42013-10-21 18:57:15 -07001733 numNetworkInScanList = 0;
Rajeev79dbe4c2013-10-05 11:03:42 +05301734 numberScanList = 0;
1735 nextScanListOffset = 0;
1736 nextApMetaInfoOffset = 0;
1737 pScanList = NULL;
1738 pApMetaInfo = NULL;
1739
1740 if ((NULL == pBatchScanRsp) || (NULL == pReq))
1741 {
1742 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1743 "%s: pBatchScanRsp is %p pReq %p", __func__, pBatchScanRsp, pReq);
1744 isLastAp = TRUE;
1745 goto done;
1746 }
1747
1748 pAdapter->numScanList = numberScanList = pBatchScanRsp->numScanLists;
1749 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1750 "Batch scan rsp: numberScalList %d", numberScanList);
1751
1752 if ((!numberScanList) || (numberScanList > pReq->numberOfScansToBatch))
1753 {
1754 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1755 "%s: numberScanList %d", __func__, numberScanList);
1756 isLastAp = TRUE;
1757 goto done;
1758 }
1759
1760 while (numberScanList)
1761 {
Rajeev Kumarce651e42013-10-21 18:57:15 -07001762 pScanList = (tpSirBatchScanList)((tANI_U8 *)pBatchScanRsp->scanResults +
Rajeev79dbe4c2013-10-05 11:03:42 +05301763 nextScanListOffset);
1764 if (NULL == pScanList)
1765 {
1766 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1767 "%s: pScanList is %p", __func__, pScanList);
1768 isLastAp = TRUE;
1769 goto done;
1770 }
Rajeev Kumarce651e42013-10-21 18:57:15 -07001771 numNetworkInScanList = numApMetaInfo = pScanList->numNetworksInScanList;
Rajeev79dbe4c2013-10-05 11:03:42 +05301772 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Rajeev Kumarce651e42013-10-21 18:57:15 -07001773 "Batch scan rsp: numApMetaInfo %d scanId %d",
1774 numApMetaInfo, pScanList->scanId);
Rajeev79dbe4c2013-10-05 11:03:42 +05301775
1776 if ((!numApMetaInfo) || (numApMetaInfo > pReq->bestNetwork))
1777 {
1778 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1779 "%s: numApMetaInfo %d", __func__, numApMetaInfo);
1780 isLastAp = TRUE;
1781 goto done;
1782 }
1783
Rajeev Kumarce651e42013-10-21 18:57:15 -07001784 /*Initialize next AP meta info offset for next scan list*/
1785 nextApMetaInfoOffset = 0;
1786
Rajeev79dbe4c2013-10-05 11:03:42 +05301787 while (numApMetaInfo)
1788 {
1789 pApMetaInfo = (tpSirBatchScanNetworkInfo)(pScanList->scanList +
1790 nextApMetaInfoOffset);
1791 if (NULL == pApMetaInfo)
1792 {
1793 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1794 "%s: pApMetaInfo is %p", __func__, pApMetaInfo);
1795 isLastAp = TRUE;
1796 goto done;
1797 }
1798 /*calculate AP age*/
1799 pApMetaInfo->timestamp =
1800 pBatchScanRsp->timestamp - pApMetaInfo->timestamp;
1801
1802 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
Arif Hussaina7c8e412013-11-20 11:06:42 -08001803 "%s: bssId "MAC_ADDRESS_STR
1804 " ch %d rssi %d timestamp %d", __func__,
1805 MAC_ADDR_ARRAY(pApMetaInfo->bssid),
1806 pApMetaInfo->ch, pApMetaInfo->rssi,
1807 pApMetaInfo->timestamp);
Rajeev79dbe4c2013-10-05 11:03:42 +05301808
1809 /*mark last AP in batch scan response*/
1810 if ((TRUE == pBatchScanRsp->isLastResult) &&
1811 (1 == numberScanList) && (1 == numApMetaInfo))
1812 {
1813 isLastAp = TRUE;
1814 }
1815
1816 mutex_lock(&pAdapter->hdd_batch_scan_lock);
1817 /*store batch scan repsonse in hdd queue*/
1818 hdd_populate_batch_scan_rsp_queue(pAdapter, pApMetaInfo,
1819 pScanList->scanId, isLastAp);
1820 mutex_unlock(&pAdapter->hdd_batch_scan_lock);
1821
1822 nextApMetaInfoOffset += sizeof(tSirBatchScanNetworkInfo);
1823 numApMetaInfo--;
1824 }
1825
Rajeev Kumarce651e42013-10-21 18:57:15 -07001826 nextScanListOffset += ((sizeof(tSirBatchScanList) - sizeof(tANI_U8))
1827 + (sizeof(tSirBatchScanNetworkInfo)
1828 * numNetworkInScanList));
Rajeev79dbe4c2013-10-05 11:03:42 +05301829 numberScanList--;
1830 }
1831
1832done:
1833
1834 /*notify hdd_ioctl only if complete batch scan rsp is received and it was
1835 requested from hdd_ioctl*/
1836 if ((TRUE == pAdapter->hdd_wait_for_get_batch_scan_rsp) &&
1837 (TRUE == isLastAp))
1838 {
1839 pAdapter->hdd_wait_for_get_batch_scan_rsp = FALSE;
1840 complete(&pAdapter->hdd_get_batch_scan_req_var);
1841 }
1842
1843 return;
1844}/*End of hdd_batch_scan_result_ind_callback*/
1845
1846/**---------------------------------------------------------------------------
1847
1848 \brief hdd_format_batch_scan_rsp () - This function formats batch scan
1849 response as per batch scan FR request format by putting proper markers
1850
1851 \param - pDest pointer to destination buffer
1852 \param - cur_len current length
1853 \param - tot_len total remaining size which can be written to user space
1854 \param - pApMetaInfo Pointer to get batch scan response AP meta info
1855 \param - pAdapter Pointer to HDD adapter
1856
1857 \return - ret no of characters written
1858
1859 --------------------------------------------------------------------------*/
1860static tANI_U32
1861hdd_format_batch_scan_rsp
1862(
1863 tANI_U8 *pDest,
1864 tANI_U32 cur_len,
1865 tANI_U32 tot_len,
1866 tHddBatchScanRsp *pApMetaInfo,
1867 hdd_adapter_t* pAdapter
1868)
1869{
1870 tANI_U32 ret = 0;
1871 tANI_U32 rem_len = 0;
1872 tANI_U8 temp_len = 0;
1873 tANI_U8 temp_total_len = 0;
1874 tANI_U8 temp[HDD_BATCH_SCAN_AP_META_INFO_SIZE];
1875 tANI_U8 *pTemp = temp;
1876
1877 /*Batch scan reponse needs to be returned to user space in
1878 following format:
1879 "scancount=X\n" where X is the number of scans in current batch
1880 batch
1881 "trunc\n" optional present if current scan truncated
1882 "bssid=XX:XX:XX:XX:XX:XX\n"
1883 "ssid=XXXX\n"
1884 "freq=X\n" frequency in Mhz
1885 "level=XX\n"
1886 "age=X\n" ms
1887 "dist=X\n" cm (-1 if not available)
1888 "errror=X\n" (-1if not available)
1889 "====\n" (end of ap marker)
1890 "####\n" (end of scan marker)
1891 "----\n" (end of results)*/
1892 /*send scan result in above format to user space based on
1893 available length*/
1894 /*The GET response may have more data than the driver can return in its
1895 buffer. In that case the buffer should be filled to the nearest complete
1896 scan, ending with "%%%%".Subsequent callsshould return the remaining data
1897 starting with the next scan (optional .trunc\n., .apcount=X\n., etc).
1898 The final buffer should end with "----\n"*/
1899
1900 /*sanity*/
1901 if (cur_len > tot_len)
1902 {
1903 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1904 "%s: invaid cur_len %d tot_len %d", __func__, cur_len, tot_len);
1905 return 0;
1906 }
1907 else
1908 {
1909 rem_len = (tot_len - cur_len);
1910 }
1911
1912 /*end scan marker*/
1913 if (pApMetaInfo->ApInfo.batchId != pAdapter->prev_batch_id)
1914 {
1915 temp_len = snprintf(pTemp, sizeof(temp), "####\n");
1916 pTemp += temp_len;
1917 temp_total_len += temp_len;
1918 }
1919
1920 /*bssid*/
1921 temp_len = snprintf(pTemp, sizeof(temp),
1922 "bssid=0x%x:0x%x:0x%x:0x%x:0x%x:0x%x\n",
1923 pApMetaInfo->ApInfo.bssid[0], pApMetaInfo->ApInfo.bssid[1],
1924 pApMetaInfo->ApInfo.bssid[2], pApMetaInfo->ApInfo.bssid[3],
1925 pApMetaInfo->ApInfo.bssid[4], pApMetaInfo->ApInfo.bssid[5]);
1926 pTemp += temp_len;
1927 temp_total_len += temp_len;
1928
1929 /*ssid*/
1930 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "ssid=%s\n",
1931 pApMetaInfo->ApInfo.ssid);
1932 pTemp += temp_len;
1933 temp_total_len += temp_len;
1934
1935 /*freq*/
1936 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "freq=%d\n",
Rajeev Kumarc40f7512013-11-04 14:13:23 -08001937 sme_ChnToFreq(pApMetaInfo->ApInfo.ch));
Rajeev79dbe4c2013-10-05 11:03:42 +05301938 pTemp += temp_len;
1939 temp_total_len += temp_len;
1940
1941 /*level*/
1942 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "level=%d\n",
1943 pApMetaInfo->ApInfo.rssi);
1944 pTemp += temp_len;
1945 temp_total_len += temp_len;
1946
1947 /*age*/
Jeff Johnson02797792013-10-26 19:17:13 -07001948 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "age=%d\n",
Rajeev79dbe4c2013-10-05 11:03:42 +05301949 pApMetaInfo->ApInfo.age);
1950 pTemp += temp_len;
1951 temp_total_len += temp_len;
1952
1953 /*dist*/
1954 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "dist=-1\n");
1955 pTemp += temp_len;
1956 temp_total_len += temp_len;
1957
1958 /*error*/
1959 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "error=-1\n");
1960 pTemp += temp_len;
1961 temp_total_len += temp_len;
1962
1963 /*end AP marker*/
1964 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "====\n");
1965 pTemp += temp_len;
1966 temp_total_len += temp_len;
1967
1968 /*last AP in batch scan response*/
1969 if(TRUE == pApMetaInfo->ApInfo.isLastAp)
1970 {
1971 /*end scan marker*/
1972 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "####\n");
1973 pTemp += temp_len;
1974 temp_total_len += temp_len;
1975
1976 /*end batch scan result marker*/
1977 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "----\n");
1978 pTemp += temp_len;
1979 temp_total_len += temp_len;
Kiet Lamaa8e15a2014-02-11 23:30:06 -08001980
Rajeev79dbe4c2013-10-05 11:03:42 +05301981 }
1982
1983 if (temp_total_len < rem_len)
1984 {
1985 ret = temp_total_len + 1;
1986 strlcpy(pDest, temp, ret);
1987 pAdapter->isTruncated = FALSE;
1988 }
1989 else
1990 {
1991 pAdapter->isTruncated = TRUE;
1992 if (rem_len >= strlen("%%%%"))
1993 {
Rajeev Kumarc933d982013-11-18 20:04:20 -08001994 ret = snprintf(pDest, sizeof(temp), "%%%%");
Rajeev79dbe4c2013-10-05 11:03:42 +05301995 }
Rajeev Kumarc933d982013-11-18 20:04:20 -08001996 else
Rajeev79dbe4c2013-10-05 11:03:42 +05301997 {
1998 ret = 0;
1999 }
2000 }
2001
2002 return ret;
2003
2004}/*End of hdd_format_batch_scan_rsp*/
2005
2006/**---------------------------------------------------------------------------
2007
2008 \brief hdd_populate_user_batch_scan_rsp() - This function populates user data
2009 buffer starting with head of hdd batch scan response queue
2010
2011 \param - pAdapter Pointer to HDD adapter
2012 \param - pDest Pointer to user data buffer
2013 \param - cur_len current offset in user buffer
2014 \param - rem_len remaining no of bytes in user buffer
2015
2016 \return - number of bytes written in user buffer
2017
2018 --------------------------------------------------------------------------*/
2019
2020tANI_U32 hdd_populate_user_batch_scan_rsp
2021(
2022 hdd_adapter_t* pAdapter,
2023 tANI_U8 *pDest,
2024 tANI_U32 cur_len,
2025 tANI_U32 rem_len
2026)
2027{
2028 tHddBatchScanRsp *pHead;
2029 tHddBatchScanRsp *pPrev;
2030 tANI_U32 len;
2031
Rajeev79dbe4c2013-10-05 11:03:42 +05302032 pAdapter->isTruncated = FALSE;
2033
2034 /*head of hdd batch scan response queue*/
2035 pHead = pAdapter->pBatchScanRsp;
2036 while (pHead)
2037 {
2038 len = hdd_format_batch_scan_rsp(pDest, cur_len, rem_len, pHead,
2039 pAdapter);
2040 pDest += len;
Rajeev Kumar292d2bb2013-10-23 15:01:44 -07002041 pDest--;
Rajeev79dbe4c2013-10-05 11:03:42 +05302042 cur_len += len;
2043 if(TRUE == pAdapter->isTruncated)
2044 {
2045 /*result is truncated return rest of scan rsp in next req*/
2046 cur_len = rem_len;
2047 break;
2048 }
2049 pPrev = pHead;
2050 pHead = pHead->pNext;
2051 pAdapter->pBatchScanRsp = pHead;
Rajeev Kumarbe17d8b2014-01-10 15:39:45 -08002052 if (TRUE == pPrev->ApInfo.isLastAp)
2053 {
2054 pAdapter->prev_batch_id = 0;
2055 }
2056 else
2057 {
2058 pAdapter->prev_batch_id = pPrev->ApInfo.batchId;
2059 }
Rajeev79dbe4c2013-10-05 11:03:42 +05302060 vos_mem_free(pPrev);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08002061 pPrev = NULL;
Rajeev79dbe4c2013-10-05 11:03:42 +05302062 }
2063
2064 return cur_len;
2065}/*End of hdd_populate_user_batch_scan_rsp*/
2066
2067/**---------------------------------------------------------------------------
2068
2069 \brief hdd_return_batch_scan_rsp_to_user () - This function returns batch
2070 scan response data from HDD queue to user space
2071 It does following in detail:
2072 a) if HDD has enough data in its queue then it 1st copies data to user
2073 space and then send get batch scan indication message to FW. In this
2074 case it does not wait on any event and batch scan response data will
2075 be populated in HDD response queue in MC thread context after receiving
2076 indication from FW
2077 b) else send get batch scan indication message to FW and wait on an event
2078 which will be set once HDD receives complete batch scan response from
2079 FW and then this function returns batch scan response to user space
2080
2081 \param - pAdapter Pointer to HDD adapter
2082 \param - pPrivData Pointer to priv_data
2083
2084 \return - 0 for success -EFAULT for failure
2085
2086 --------------------------------------------------------------------------*/
2087
2088int hdd_return_batch_scan_rsp_to_user
2089(
2090 hdd_adapter_t* pAdapter,
2091 hdd_priv_data_t *pPrivData,
2092 tANI_U8 *command
2093)
2094{
2095 tANI_U8 *pDest;
2096 tANI_U32 count = 0;
2097 tANI_U32 len = 0;
2098 tANI_U32 cur_len = 0;
2099 tANI_U32 rem_len = 0;
2100 eHalStatus halStatus;
2101 unsigned long rc;
2102 tSirTriggerBatchScanResultInd *pReq;
2103
2104 pReq = &pAdapter->hddTriggerBatchScanResultInd;
2105 pReq->param = 0;/*batch scan client*/
2106 pDest = (tANI_U8 *)(command + pPrivData->used_len);
2107 pAdapter->hdd_wait_for_get_batch_scan_rsp = FALSE;
2108
2109 cur_len = pPrivData->used_len;
2110 if (pPrivData->total_len > pPrivData->used_len)
2111 {
2112 rem_len = pPrivData->total_len - pPrivData->used_len;
2113 }
2114 else
2115 {
2116 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2117 "%s: Invalid user data buffer total_len %d used_len %d",
2118 __func__, pPrivData->total_len, pPrivData->used_len);
2119 return -EFAULT;
2120 }
2121
2122 mutex_lock(&pAdapter->hdd_batch_scan_lock);
2123 len = hdd_populate_user_batch_scan_rsp(pAdapter, pDest,
2124 cur_len, rem_len);
2125 mutex_unlock(&pAdapter->hdd_batch_scan_lock);
2126
2127 /*enough scan result available in cache to return to user space or
2128 scan result needs to be fetched 1st from fw and then return*/
Rajeev Kumar99db6262013-11-11 15:23:36 -08002129 if (len == cur_len)
Rajeev79dbe4c2013-10-05 11:03:42 +05302130 {
2131 pAdapter->hdd_wait_for_get_batch_scan_rsp = TRUE;
2132 halStatus = sme_TriggerBatchScanResultInd(
2133 WLAN_HDD_GET_HAL_CTX(pAdapter), pReq,
2134 pAdapter->sessionId, hdd_batch_scan_result_ind_callback,
2135 pAdapter);
2136 if ( eHAL_STATUS_SUCCESS == halStatus )
2137 {
2138 if (TRUE == pAdapter->hdd_wait_for_get_batch_scan_rsp)
2139 {
2140 INIT_COMPLETION(pAdapter->hdd_get_batch_scan_req_var);
2141 rc = wait_for_completion_timeout(
2142 &pAdapter->hdd_get_batch_scan_req_var,
2143 msecs_to_jiffies(HDD_GET_BATCH_SCAN_RSP_TIME_OUT));
Abhishek Singh00b71972016-01-07 10:51:04 +05302144 if (0 >= rc)
Rajeev79dbe4c2013-10-05 11:03:42 +05302145 {
2146 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Abhishek Singh00b71972016-01-07 10:51:04 +05302147 "%s: wait on hdd_get_batch_scan_req_var failed %ld",
2148 __func__, rc);
Rajeev79dbe4c2013-10-05 11:03:42 +05302149 return -EFAULT;
2150 }
2151 }
2152
2153 len = snprintf(pDest, HDD_BATCH_SCAN_AP_META_INFO_SIZE,
Jeff Johnson02797792013-10-26 19:17:13 -07002154 "scancount=%u\n", pAdapter->numScanList);
Rajeev79dbe4c2013-10-05 11:03:42 +05302155 pDest += len;
2156 cur_len += len;
2157
2158 mutex_lock(&pAdapter->hdd_batch_scan_lock);
2159 len = hdd_populate_user_batch_scan_rsp(pAdapter, pDest,
2160 cur_len, rem_len);
2161 mutex_unlock(&pAdapter->hdd_batch_scan_lock);
2162
2163 count = 0;
2164 len = (len - pPrivData->used_len);
2165 pDest = (command + pPrivData->used_len);
2166 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Rajeev Kumar99db6262013-11-11 15:23:36 -08002167 "NEW BATCH SCAN RESULT:");
Rajeev79dbe4c2013-10-05 11:03:42 +05302168 while(count < len)
2169 {
2170 printk("%c", *(pDest + count));
2171 count++;
2172 }
2173 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2174 "%s: copy %d data to user buffer", __func__, len);
2175 if (copy_to_user(pPrivData->buf, pDest, len))
2176 {
2177 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2178 "%s: failed to copy data to user buffer", __func__);
2179 return -EFAULT;
2180 }
2181 }
2182 else
2183 {
2184 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2185 "sme_GetBatchScanScan returned failure halStatus %d",
2186 halStatus);
2187 return -EINVAL;
2188 }
2189 }
2190 else
2191 {
Rajeev79dbe4c2013-10-05 11:03:42 +05302192 count = 0;
2193 len = (len - pPrivData->used_len);
2194 pDest = (command + pPrivData->used_len);
2195 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Rajeev Kumar99db6262013-11-11 15:23:36 -08002196 "REMAINING TRUNCATED BATCH SCAN RESULT:");
Rajeev79dbe4c2013-10-05 11:03:42 +05302197 while(count < len)
2198 {
2199 printk("%c", *(pDest + count));
2200 count++;
2201 }
Rajeev Kumar99db6262013-11-11 15:23:36 -08002202 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2203 "%s: copy %d data to user buffer", __func__, len);
Rajeev79dbe4c2013-10-05 11:03:42 +05302204 if (copy_to_user(pPrivData->buf, pDest, len))
2205 {
2206 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2207 "%s: failed to copy data to user buffer", __func__);
2208 return -EFAULT;
2209 }
Rajeev79dbe4c2013-10-05 11:03:42 +05302210 }
2211
2212 return 0;
2213} /*End of hdd_return_batch_scan_rsp_to_user*/
2214
Rajeev Kumar8b373292014-01-08 20:36:55 -08002215/**---------------------------------------------------------------------------
2216
2217 \brief hdd_handle_batch_scan_ioctl () - This function handles WLS_BATCHING
2218 IOCTLs from user space. Following BATCH SCAN DEV IOCTs are handled:
2219 WLS_BATCHING VERSION
2220 WLS_BATCHING SET
2221 WLS_BATCHING GET
2222 WLS_BATCHING STOP
2223
2224 \param - pAdapter Pointer to HDD adapter
2225 \param - pPrivdata Pointer to priv_data
2226 \param - command Pointer to command
2227
2228 \return - 0 for success -EFAULT for failure
2229
2230 --------------------------------------------------------------------------*/
2231
2232int hdd_handle_batch_scan_ioctl
2233(
2234 hdd_adapter_t *pAdapter,
2235 hdd_priv_data_t *pPrivdata,
2236 tANI_U8 *command
2237)
2238{
2239 int ret = 0;
Yue Mae36e3552014-03-05 17:06:20 -08002240 hdd_context_t *pHddCtx;
2241
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302242 ENTER();
2243
Yue Mae36e3552014-03-05 17:06:20 -08002244 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
2245 ret = wlan_hdd_validate_context(pHddCtx);
2246 if (ret)
2247 {
Yue Mae36e3552014-03-05 17:06:20 -08002248 goto exit;
2249 }
Rajeev Kumar8b373292014-01-08 20:36:55 -08002250
2251 if (strncmp(command, "WLS_BATCHING VERSION", 20) == 0)
2252 {
2253 char extra[32];
2254 tANI_U8 len = 0;
2255 tANI_U8 version = HDD_BATCH_SCAN_VERSION;
2256
2257 if (FALSE == sme_IsFeatureSupportedByFW(BATCH_SCAN))
2258 {
2259 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2260 "%s: Batch scan feature is not supported by FW", __func__);
2261 ret = -EINVAL;
2262 goto exit;
2263 }
2264
2265 len = scnprintf(extra, sizeof(extra), "WLS_BATCHING_VERSION %d",
2266 version);
2267 if (copy_to_user(pPrivdata->buf, &extra, len + 1))
2268 {
2269 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2270 "%s: failed to copy data to user buffer", __func__);
2271 ret = -EFAULT;
2272 goto exit;
2273 }
2274 ret = HDD_BATCH_SCAN_VERSION;
2275 }
2276 else if (strncmp(command, "WLS_BATCHING SET", 16) == 0)
2277 {
2278 int status;
2279 tANI_U8 *value = (command + 16);
2280 eHalStatus halStatus;
2281 unsigned long rc;
2282 tSirSetBatchScanReq *pReq = &pAdapter->hddSetBatchScanReq;
2283 tSirSetBatchScanRsp *pRsp = &pAdapter->hddSetBatchScanRsp;
2284
2285 if (FALSE == sme_IsFeatureSupportedByFW(BATCH_SCAN))
2286 {
2287 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2288 "%s: Batch scan feature is not supported by FW", __func__);
2289 ret = -EINVAL;
2290 goto exit;
2291 }
2292
2293 if ((WLAN_HDD_INFRA_STATION != pAdapter->device_mode) &&
2294 (WLAN_HDD_P2P_CLIENT != pAdapter->device_mode) &&
2295 (WLAN_HDD_P2P_GO != pAdapter->device_mode) &&
2296 (WLAN_HDD_P2P_DEVICE != pAdapter->device_mode))
2297 {
2298 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05302299 "Received WLS_BATCHING SET command in invalid mode %s (%d) "
Rajeev Kumar8b373292014-01-08 20:36:55 -08002300 "WLS_BATCHING_SET is only allowed in infra STA/P2P client mode",
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05302301 hdd_device_modetoString(pAdapter->device_mode),
2302 pAdapter->device_mode);
Rajeev Kumar8b373292014-01-08 20:36:55 -08002303 ret = -EINVAL;
2304 goto exit;
2305 }
2306
2307 status = hdd_parse_set_batchscan_command(value, pReq);
2308 if (status)
2309 {
2310 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2311 "Invalid WLS_BATCHING SET command");
2312 ret = -EINVAL;
2313 goto exit;
2314 }
2315
2316
2317 pAdapter->hdd_wait_for_set_batch_scan_rsp = TRUE;
2318 halStatus = sme_SetBatchScanReq(WLAN_HDD_GET_HAL_CTX(pAdapter), pReq,
2319 pAdapter->sessionId, hdd_set_batch_scan_req_callback,
2320 pAdapter);
2321
2322 if ( eHAL_STATUS_SUCCESS == halStatus )
2323 {
Mahesh A Saptasagar5f568172014-05-14 17:02:33 +05302324 char extra[32];
2325 tANI_U8 len = 0;
2326 tANI_U8 mScan = 0;
2327
Rajeev Kumar8b373292014-01-08 20:36:55 -08002328 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2329 "sme_SetBatchScanReq returned success halStatus %d",
2330 halStatus);
2331 if (TRUE == pAdapter->hdd_wait_for_set_batch_scan_rsp)
2332 {
2333 INIT_COMPLETION(pAdapter->hdd_set_batch_scan_req_var);
2334 rc = wait_for_completion_timeout(
2335 &pAdapter->hdd_set_batch_scan_req_var,
2336 msecs_to_jiffies(HDD_SET_BATCH_SCAN_REQ_TIME_OUT));
2337 if (0 == rc)
2338 {
2339 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2340 "%s: Timeout waiting for set batch scan to complete",
2341 __func__);
2342 ret = -EINVAL;
2343 goto exit;
2344 }
2345 }
2346 if ( !pRsp->nScansToBatch )
2347 {
2348 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2349 "%s: Received set batch scan failure response from FW",
2350 __func__);
2351 ret = -EINVAL;
2352 goto exit;
2353 }
2354 /*As per the Batch Scan Framework API we should return the MIN of
2355 either MSCAN or the max # of scans firmware can cache*/
Mahesh A Saptasagar5f568172014-05-14 17:02:33 +05302356 mScan = MIN(pReq->numberOfScansToBatch , pRsp->nScansToBatch);
Rajeev Kumar8b373292014-01-08 20:36:55 -08002357
2358 pAdapter->batchScanState = eHDD_BATCH_SCAN_STATE_STARTED;
2359
2360 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2361 "%s: request MSCAN %d response MSCAN %d ret %d",
Mahesh A Saptasagar5f568172014-05-14 17:02:33 +05302362 __func__, pReq->numberOfScansToBatch, pRsp->nScansToBatch, mScan);
2363 len = scnprintf(extra, sizeof(extra), "%d", mScan);
2364 if (copy_to_user(pPrivdata->buf, &extra, len + 1))
2365 {
2366 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2367 "%s: failed to copy MSCAN value to user buffer", __func__);
2368 ret = -EFAULT;
2369 goto exit;
2370 }
Rajeev Kumar8b373292014-01-08 20:36:55 -08002371 }
2372 else
2373 {
2374 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2375 "sme_SetBatchScanReq returned failure halStatus %d",
2376 halStatus);
2377 ret = -EINVAL;
2378 goto exit;
2379 }
2380 }
2381 else if (strncmp(command, "WLS_BATCHING STOP", 17) == 0)
2382 {
2383 eHalStatus halStatus;
2384 tSirStopBatchScanInd *pInd = &pAdapter->hddStopBatchScanInd;
2385 pInd->param = 0;
2386
2387 if (FALSE == sme_IsFeatureSupportedByFW(BATCH_SCAN))
2388 {
2389 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2390 "%s: Batch scan feature is not supported by FW", __func__);
2391 ret = -EINVAL;
2392 goto exit;
2393 }
2394
2395 if (eHDD_BATCH_SCAN_STATE_STARTED != pAdapter->batchScanState)
2396 {
Deepthi Gowribfd17132014-11-14 17:59:04 +05302397 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Rajeev Kumar8b373292014-01-08 20:36:55 -08002398 "Batch scan is not yet enabled batch scan state %d",
2399 pAdapter->batchScanState);
2400 ret = -EINVAL;
2401 goto exit;
2402 }
2403
Kiet Lamaa8e15a2014-02-11 23:30:06 -08002404 mutex_lock(&pAdapter->hdd_batch_scan_lock);
2405 hdd_deinit_batch_scan(pAdapter);
2406 mutex_unlock(&pAdapter->hdd_batch_scan_lock);
2407
Rajeev Kumar8b373292014-01-08 20:36:55 -08002408 pAdapter->batchScanState = eHDD_BATCH_SCAN_STATE_STOPPED;
2409
2410 halStatus = sme_StopBatchScanInd(WLAN_HDD_GET_HAL_CTX(pAdapter), pInd,
2411 pAdapter->sessionId);
2412 if ( eHAL_STATUS_SUCCESS == halStatus )
2413 {
2414 ret = 0;
2415 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2416 "sme_StopBatchScanInd returned success halStatus %d",
2417 halStatus);
2418 }
2419 else
2420 {
2421 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2422 "sme_StopBatchScanInd returned failure halStatus %d",
2423 halStatus);
2424 ret = -EINVAL;
2425 goto exit;
2426 }
2427 }
2428 else if (strncmp(command, "WLS_BATCHING GET", 16) == 0)
2429 {
2430 tANI_U32 remain_len;
2431
2432 if (FALSE == sme_IsFeatureSupportedByFW(BATCH_SCAN))
2433 {
2434 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2435 "%s: Batch scan feature is not supported by FW", __func__);
2436 ret = -EINVAL;
2437 goto exit;
2438 }
2439
2440 if (eHDD_BATCH_SCAN_STATE_STARTED != pAdapter->batchScanState)
2441 {
Deepthi Gowribfd17132014-11-14 17:59:04 +05302442 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Rajeev Kumar8b373292014-01-08 20:36:55 -08002443 "Batch scan is not yet enabled could not return results"
2444 "Batch Scan state %d",
2445 pAdapter->batchScanState);
2446 ret = -EINVAL;
2447 goto exit;
2448 }
2449
2450 pPrivdata->used_len = 16;
2451 remain_len = pPrivdata->total_len - pPrivdata->used_len;
2452 if (remain_len < pPrivdata->total_len)
2453 {
2454 /*Clear previous batch scan response data if any*/
2455 vos_mem_zero((tANI_U8 *)(command + pPrivdata->used_len), remain_len);
2456 }
2457 else
2458 {
2459 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2460 "Invalid total length from user space can't fetch batch"
2461 " scan response total_len %d used_len %d remain len %d",
2462 pPrivdata->total_len, pPrivdata->used_len, remain_len);
2463 ret = -EINVAL;
2464 goto exit;
2465 }
2466 ret = hdd_return_batch_scan_rsp_to_user(pAdapter, pPrivdata, command);
2467 }
2468
2469exit:
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302470 EXIT();
Rajeev Kumar8b373292014-01-08 20:36:55 -08002471 return ret;
2472}
2473
2474
Rajeev79dbe4c2013-10-05 11:03:42 +05302475#endif/*End of FEATURE_WLAN_BATCH_SCAN*/
2476
Selvaraj, Sridhar5aff1ed2016-06-18 01:26:23 +05302477#if defined(WLAN_FEATURE_VOWIFI_11R) || defined(FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
2478/**
2479 * hdd_assign_handoff_src_reassoc - Set handoff source as REASSOC
2480 * to Handoff request
2481 * @handoffInfo: Pointer to Handoff request
2482 * @src: enum of handoff_src
2483 * Return: None
2484 */
2485#ifndef QCA_WIFI_ISOC
2486static inline void hdd_assign_handoff_src_reassoc(tCsrHandoffRequest
2487 *handoffInfo, handoff_src src)
2488{
2489 handoffInfo->src = src;
2490}
2491#else
2492static inline void hdd_assign_handoff_src_reassoc(tCsrHandoffRequest
2493 *handoffInfo, handoff_src src)
2494{
2495}
2496#endif
2497
2498/**
Selvaraj, Sridhar4fa15232016-06-18 12:27:25 +05302499 * hdd_reassoc() - perform a user space-directed reassoc
Selvaraj, Sridhar5aff1ed2016-06-18 01:26:23 +05302500 *
2501 * @pAdapter: Adapter upon which the command was received
2502 * @bssid: BSSID with which to reassociate
2503 * @channel: channel upon which to reassociate
Selvaraj, Sridhar4fa15232016-06-18 12:27:25 +05302504 * @src: The source for the trigger of this action
Selvaraj, Sridhar5aff1ed2016-06-18 01:26:23 +05302505 *
2506 * Return: 0 for success non-zero for failure
2507 */
2508#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
Selvaraj, Sridhar8ecb4192016-06-23 17:50:49 +05302509int hdd_reassoc(hdd_adapter_t *pAdapter, const tANI_U8 *bssid,
Selvaraj, Sridhar4fa15232016-06-18 12:27:25 +05302510 const tANI_U8 channel, const handoff_src src)
Selvaraj, Sridhar5aff1ed2016-06-18 01:26:23 +05302511{
2512 hdd_station_ctx_t *pHddStaCtx;
2513 tCsrHandoffRequest handoffInfo;
2514 hdd_context_t *pHddCtx = NULL;
2515 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
2516
2517 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
2518
2519 /* if not associated, no need to proceed with reassoc */
2520 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState) {
2521 hddLog(LOG1, FL("Not associated"));
2522 return -EINVAL;
2523 }
2524
2525 /* if the target bssid is same as currently associated AP,
2526 then no need to proceed with reassoc */
2527 if (!memcmp(bssid, pHddStaCtx->conn_info.bssId, sizeof(tSirMacAddr))) {
2528 hddLog(LOG1, FL("Reassoc BSSID is same as currently associated AP bssid"));
2529 return -EINVAL;
2530 }
2531
2532 /* Check channel number is a valid channel number */
2533 if (VOS_STATUS_SUCCESS !=
2534 wlan_hdd_validate_operation_channel(pAdapter, channel)) {
2535 hddLog(LOGE, FL("Invalid Channel %d"), channel);
2536 return -EINVAL;
2537 }
2538
2539 /* Proceed with reassoc */
2540 handoffInfo.channel = channel;
Selvaraj, Sridhar4fa15232016-06-18 12:27:25 +05302541 hdd_assign_handoff_src_reassoc(&handoffInfo, src);
Selvaraj, Sridhar5aff1ed2016-06-18 01:26:23 +05302542 memcpy(handoffInfo.bssid, bssid, sizeof(tSirMacAddr));
2543 sme_HandoffRequest(pHddCtx->hHal, &handoffInfo);
2544 return 0;
2545}
2546#else
Selvaraj, Sridhar8ecb4192016-06-23 17:50:49 +05302547int hdd_reassoc(hdd_adapter_t *pAdapter, const tANI_U8 *bssid,
Selvaraj, Sridhar4fa15232016-06-18 12:27:25 +05302548 const tANI_U8 channel, const handoff_src src)
Selvaraj, Sridhar5aff1ed2016-06-18 01:26:23 +05302549{
2550 return -EPERM;
2551}
2552#endif
2553
2554/**
2555 * hdd_parse_reassoc_v1() - parse version 1 of the REASSOC command
2556 * This function parses the v1 REASSOC command with the format
2557 * REASSOC xx:xx:xx:xx:xx:xx CH where "xx:xx:xx:xx:xx:xx" is the
2558 * Hex-ASCII representation of the BSSID and CH is the ASCII
2559 * representation of the channel. For example
2560 * REASSOC 00:0a:0b:11:22:33 48
2561 *
2562 * @pAdapter: Adapter upon which the command was received
2563 * @command: ASCII text command that was received
2564 *
2565 * Return: 0 for success non-zero for failure
2566 */
2567static int
2568hdd_parse_reassoc_v1(hdd_adapter_t *pAdapter, const char *command)
2569{
2570 tANI_U8 channel = 0;
2571 tSirMacAddr bssid;
2572 int ret;
2573
2574 ret = hdd_parse_reassoc_command_v1_data(command, bssid, &channel);
2575 if (ret)
2576 hddLog(LOGE, FL("Failed to parse reassoc command data"));
2577 else
Selvaraj, Sridhar4fa15232016-06-18 12:27:25 +05302578 ret = hdd_reassoc(pAdapter, bssid, channel, REASSOC);
Selvaraj, Sridhar5aff1ed2016-06-18 01:26:23 +05302579
2580 return ret;
2581}
2582
2583/**
2584 * hdd_parse_reassoc_v2() - parse version 2 of the REASSOC command
2585 * This function parses the v2 REASSOC command with the format
2586 * REASSOC <android_wifi_reassoc_params>
2587 *
2588 * @pAdapter: Adapter upon which the command was received
2589 * @command: command that was received, ASCII command followed
2590 * by binary data
2591 *
2592 * Return: 0 for success non-zero for failure
2593 */
2594static int
2595hdd_parse_reassoc_v2(hdd_adapter_t *pAdapter, const char *command)
2596{
2597 struct android_wifi_reassoc_params params;
2598 tSirMacAddr bssid;
2599 int ret;
2600
2601 /* The params are located after "REASSOC " */
2602 memcpy(&params, command + 8, sizeof(params));
2603
2604 if (!mac_pton(params.bssid, (u8 *)&bssid)) {
2605 hddLog(LOGE, FL("MAC address parsing failed"));
2606 ret = -EINVAL;
2607 } else {
Selvaraj, Sridhar4fa15232016-06-18 12:27:25 +05302608 ret = hdd_reassoc(pAdapter, bssid, params.channel, REASSOC);
Selvaraj, Sridhar5aff1ed2016-06-18 01:26:23 +05302609 }
2610 return ret;
2611}
2612
2613/**
2614 * hdd_parse_reassoc() - parse the REASSOC command
2615 * There are two different versions of the REASSOC command.Version 1
2616 * of the command contains a parameter list that is ASCII characters
2617 * whereas version 2 contains a combination of ASCII and binary
2618 * payload. Determine if a version 1 or a version 2 command is being
2619 * parsed by examining the parameters, and then dispatch the parser
2620 * that is appropriate for the command.
2621 *
2622 * @pAdapter: Adapter upon which the command was received
2623 * @command: command that was received
2624 *
2625 * Return: 0 for success non-zero for failure
2626 */
2627static int
2628hdd_parse_reassoc(hdd_adapter_t *pAdapter, const char *command)
2629{
2630 int ret;
2631
2632 /*
2633 * both versions start with "REASSOC"
2634 * v1 has a bssid and channel # as an ASCII string
2635 * REASSOC xx:xx:xx:xx:xx:xx CH
2636 * v2 has a C struct
2637 * REASSOC <binary c struct>
2638 *
2639 * The first field in the v2 struct is also the bssid in ASCII.
2640 * But in the case of a v2 message the BSSID is NUL-terminated.
2641 * Hence we can peek at that offset to see if this is V1 or V2
2642 * REASSOC xx:xx:xx:xx:xx:xx*
2643 * 1111111111222222
2644 * 01234567890123456789012345
2645 */
2646 if (command[25])
2647 ret = hdd_parse_reassoc_v1(pAdapter, command);
2648 else
2649 ret = hdd_parse_reassoc_v2(pAdapter, command);
2650
2651 return ret;
2652}
2653#endif /* WLAN_FEATURE_VOWIFI_11R || FEATURE_WLAN_ESE FEATURE_WLAN_LFR */
2654
c_hpothu92367912014-05-01 15:18:17 +05302655static void getBcnMissRateCB(VOS_STATUS status, int bcnMissRate, void *data)
2656{
c_hpothu39eb1e32014-06-26 16:31:50 +05302657 bcnMissRateContext_t *pCBCtx;
2658
2659 if (NULL == data)
2660 {
2661 hddLog(VOS_TRACE_LEVEL_ERROR, FL("argument data is NULL"));
2662 return;
2663 }
c_hpothu92367912014-05-01 15:18:17 +05302664
2665 /* there is a race condition that exists between this callback
2666 function and the caller since the caller could time out either
2667 before or while this code is executing. we use a spinlock to
2668 serialize these actions */
2669 spin_lock(&hdd_context_lock);
2670
c_hpothu39eb1e32014-06-26 16:31:50 +05302671 pCBCtx = (bcnMissRateContext_t *)data;
c_hpothu92367912014-05-01 15:18:17 +05302672 gbcnMissRate = -1;
2673
c_hpothu39eb1e32014-06-26 16:31:50 +05302674 if (pCBCtx->magic != BCN_MISS_RATE_CONTEXT_MAGIC)
c_hpothu92367912014-05-01 15:18:17 +05302675 {
2676 hddLog(VOS_TRACE_LEVEL_ERROR,
c_hpothu39eb1e32014-06-26 16:31:50 +05302677 FL("invalid context magic: %08x"), pCBCtx->magic);
c_hpothu92367912014-05-01 15:18:17 +05302678 spin_unlock(&hdd_context_lock);
2679 return ;
2680 }
2681
2682 if (VOS_STATUS_SUCCESS == status)
2683 {
c_hpothu39eb1e32014-06-26 16:31:50 +05302684 gbcnMissRate = bcnMissRate;
c_hpothu92367912014-05-01 15:18:17 +05302685 }
c_hpothu39eb1e32014-06-26 16:31:50 +05302686 else
2687 {
2688 hddLog(VOS_TRACE_LEVEL_ERROR, FL("failed to get bcnMissRate"));
2689 }
2690
c_hpothu92367912014-05-01 15:18:17 +05302691 complete(&(pCBCtx->completion));
2692 spin_unlock(&hdd_context_lock);
2693
2694 return;
2695}
2696
Abhishek Singh08aa7762014-12-16 13:59:03 +05302697void hdd_FWStatisCB( VOS_STATUS status,
2698 tSirFwStatsResult *fwStatsResult, void *pContext )
Satyanarayana Dash72806012014-12-02 14:30:08 +05302699{
2700 fwStatsContext_t *fwStatsCtx;
Satyanarayana Dash72806012014-12-02 14:30:08 +05302701 hdd_adapter_t *pAdapter;
2702
2703 hddLog(VOS_TRACE_LEVEL_INFO, FL(" with status = %d"),status);
2704
Abhishek Singh08aa7762014-12-16 13:59:03 +05302705 if (NULL == pContext)
Satyanarayana Dash72806012014-12-02 14:30:08 +05302706 {
2707 hddLog(VOS_TRACE_LEVEL_ERROR, FL("argument data is NULL"));
2708 return;
2709 }
2710 /* there is a race condition that exists between this callback
2711 function and the caller since the caller could time out either
2712 before or while this code is executing. we use a spinlock to
2713 serialize these actions */
2714 spin_lock(&hdd_context_lock);
Abhishek Singh08aa7762014-12-16 13:59:03 +05302715 fwStatsCtx = (fwStatsContext_t *) pContext;
Satyanarayana Dash72806012014-12-02 14:30:08 +05302716 if (fwStatsCtx->magic != FW_STATS_CONTEXT_MAGIC)
2717 {
2718 hddLog(VOS_TRACE_LEVEL_ERROR,
2719 FL("invalid context magic: %08x"), fwStatsCtx->magic);
2720 spin_unlock(&hdd_context_lock);
2721 return;
2722 }
2723 pAdapter = fwStatsCtx->pAdapter;
2724 if ((NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic))
2725 {
2726 hddLog(VOS_TRACE_LEVEL_ERROR,
2727 FL("pAdapter returned is NULL or invalid"));
2728 spin_unlock(&hdd_context_lock);
2729 return;
2730 }
2731 pAdapter->fwStatsRsp.type = 0;
Abhishek Singh08aa7762014-12-16 13:59:03 +05302732 if ((VOS_STATUS_SUCCESS == status) && (NULL != fwStatsResult))
Satyanarayana Dash72806012014-12-02 14:30:08 +05302733 {
Satyanarayana Dash72806012014-12-02 14:30:08 +05302734 switch( fwStatsResult->type )
2735 {
2736 case FW_UBSP_STATS:
2737 {
Abhishek Singh08aa7762014-12-16 13:59:03 +05302738 memcpy(&pAdapter->fwStatsRsp,fwStatsResult,sizeof(tSirFwStatsResult));
Satyanarayana Dash72806012014-12-02 14:30:08 +05302739 hddLog(VOS_TRACE_LEVEL_INFO,
2740 FL("ubsp_enter_cnt = %d ubsp_jump_ddr_cnt = %d"),
Abhishek Singh08aa7762014-12-16 13:59:03 +05302741 pAdapter->fwStatsRsp.fwStatsData.ubspStats.ubsp_enter_cnt,
2742 pAdapter->fwStatsRsp.fwStatsData.ubspStats.ubsp_jump_ddr_cnt);
Satyanarayana Dash72806012014-12-02 14:30:08 +05302743 }
2744 break;
2745 default:
2746 {
2747 hddLog(VOS_TRACE_LEVEL_ERROR,
2748 FL(" No handling for stats type %d"),fwStatsResult->type);
2749 }
2750 }
2751 }
2752 complete(&(fwStatsCtx->completion));
2753 spin_unlock(&hdd_context_lock);
2754 return;
2755}
2756
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302757static int hdd_get_dwell_time(hdd_config_t *pCfg, tANI_U8 *command, char *extra, tANI_U8 n, tANI_U8 *len)
2758{
2759 int ret = 0;
2760
2761 if (!pCfg || !command || !extra || !len)
2762 {
2763 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2764 "%s: argument passsed for GETDWELLTIME is incorrect", __func__);
2765 ret = -EINVAL;
2766 return ret;
2767 }
2768
2769 if (strncmp(command, "GETDWELLTIME ACTIVE MAX", 23) == 0)
2770 {
2771 *len = scnprintf(extra, n, "GETDWELLTIME ACTIVE MAX %u\n",
2772 (int)pCfg->nActiveMaxChnTime);
2773 return ret;
2774 }
2775 else if (strncmp(command, "GETDWELLTIME ACTIVE MIN", 23) == 0)
2776 {
2777 *len = scnprintf(extra, n, "GETDWELLTIME ACTIVE MIN %u\n",
2778 (int)pCfg->nActiveMinChnTime);
2779 return ret;
2780 }
2781 else if (strncmp(command, "GETDWELLTIME PASSIVE MAX", 24) == 0)
2782 {
2783 *len = scnprintf(extra, n, "GETDWELLTIME PASSIVE MAX %u\n",
2784 (int)pCfg->nPassiveMaxChnTime);
2785 return ret;
2786 }
2787 else if (strncmp(command, "GETDWELLTIME PASSIVE MIN", 24) == 0)
2788 {
2789 *len = scnprintf(extra, n, "GETDWELLTIME PASSIVE MIN %u\n",
2790 (int)pCfg->nPassiveMinChnTime);
2791 return ret;
2792 }
Rajesh Babu Prathipati0fd227e2014-07-05 12:50:00 +05302793 else if (strncmp(command, "GETDWELLTIME", 12) == 0)
2794 {
2795 *len = scnprintf(extra, n, "GETDWELLTIME %u \n",
2796 (int)pCfg->nActiveMaxChnTime);
2797 return ret;
2798 }
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302799 else
2800 {
2801 ret = -EINVAL;
2802 }
2803
2804 return ret;
2805}
2806
2807static int hdd_set_dwell_time(hdd_adapter_t *pAdapter, tANI_U8 *command)
2808{
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05302809 tHalHandle hHal;
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302810 hdd_config_t *pCfg;
2811 tANI_U8 *value = command;
2812 int val = 0, ret = 0, temp = 0;
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05302813 tSmeConfigParams smeConfig;
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302814
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05302815 if (!pAdapter || !command || !(pCfg = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini)
2816 || !(hHal = (WLAN_HDD_GET_HAL_CTX(pAdapter))))
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302817 {
2818 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2819 "%s: argument passed for SETDWELLTIME is incorrect", __func__);
2820 ret = -EINVAL;
2821 return ret;
2822 }
2823
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05302824 vos_mem_zero(&smeConfig, sizeof(smeConfig));
2825 sme_GetConfigParam(hHal, &smeConfig);
2826
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302827 if (strncmp(command, "SETDWELLTIME ACTIVE MAX", 23) == 0 )
2828 {
2829 value = value + 24;
2830 temp = kstrtou32(value, 10, &val);
2831 if (temp != 0 || val < CFG_ACTIVE_MAX_CHANNEL_TIME_MIN ||
2832 val > CFG_ACTIVE_MAX_CHANNEL_TIME_MAX )
2833 {
2834 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2835 "%s: argument passed for SETDWELLTIME ACTIVE MAX is incorrect", __func__);
2836 ret = -EFAULT;
2837 return ret;
2838 }
2839 pCfg->nActiveMaxChnTime = val;
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05302840 smeConfig.csrConfig.nActiveMaxChnTime = val;
2841 sme_UpdateConfig(hHal, &smeConfig);
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302842 }
2843 else if (strncmp(command, "SETDWELLTIME ACTIVE MIN", 23) == 0)
2844 {
2845 value = value + 24;
2846 temp = kstrtou32(value, 10, &val);
2847 if (temp !=0 || val < CFG_ACTIVE_MIN_CHANNEL_TIME_MIN ||
2848 val > CFG_ACTIVE_MIN_CHANNEL_TIME_MAX )
2849 {
2850 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2851 "%s: argument passsed for SETDWELLTIME ACTIVE MIN is incorrect", __func__);
2852 ret = -EFAULT;
2853 return ret;
2854 }
2855 pCfg->nActiveMinChnTime = val;
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05302856 smeConfig.csrConfig.nActiveMinChnTime = val;
2857 sme_UpdateConfig(hHal, &smeConfig);
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302858 }
2859 else if (strncmp(command, "SETDWELLTIME PASSIVE MAX", 24) == 0)
2860 {
2861 value = value + 25;
2862 temp = kstrtou32(value, 10, &val);
2863 if (temp != 0 || val < CFG_PASSIVE_MAX_CHANNEL_TIME_MIN ||
2864 val > CFG_PASSIVE_MAX_CHANNEL_TIME_MAX )
2865 {
2866 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2867 "%s: argument passed for SETDWELLTIME PASSIVE MAX is incorrect", __func__);
2868 ret = -EFAULT;
2869 return ret;
2870 }
2871 pCfg->nPassiveMaxChnTime = val;
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05302872 smeConfig.csrConfig.nPassiveMaxChnTime = val;
2873 sme_UpdateConfig(hHal, &smeConfig);
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302874 }
2875 else if (strncmp(command, "SETDWELLTIME PASSIVE MIN", 24) == 0)
2876 {
2877 value = value + 25;
2878 temp = kstrtou32(value, 10, &val);
2879 if (temp != 0 || val < CFG_PASSIVE_MIN_CHANNEL_TIME_MIN ||
2880 val > CFG_PASSIVE_MIN_CHANNEL_TIME_MAX )
2881 {
2882 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2883 "%s: argument passed for SETDWELLTIME PASSIVE MIN is incorrect", __func__);
2884 ret = -EFAULT;
2885 return ret;
2886 }
2887 pCfg->nPassiveMinChnTime = val;
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05302888 smeConfig.csrConfig.nPassiveMinChnTime = val;
2889 sme_UpdateConfig(hHal, &smeConfig);
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302890 }
Rajesh Babu Prathipati0fd227e2014-07-05 12:50:00 +05302891 else if (strncmp(command, "SETDWELLTIME", 12) == 0)
2892 {
2893 value = value + 13;
2894 temp = kstrtou32(value, 10, &val);
2895 if (temp != 0 || val < CFG_ACTIVE_MAX_CHANNEL_TIME_MIN ||
2896 val > CFG_ACTIVE_MAX_CHANNEL_TIME_MAX )
2897 {
2898 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2899 "%s: argument passed for SETDWELLTIME is incorrect", __func__);
2900 ret = -EFAULT;
2901 return ret;
2902 }
2903 pCfg->nActiveMaxChnTime = val;
2904 smeConfig.csrConfig.nActiveMaxChnTime = val;
2905 sme_UpdateConfig(hHal, &smeConfig);
2906 }
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302907 else
2908 {
2909 ret = -EINVAL;
2910 }
2911
2912 return ret;
2913}
Agarwal Ashish8bd53ae2015-06-12 18:03:45 +05302914static int hdd_cmd_setFccChannel(hdd_context_t *pHddCtx, tANI_U8 *cmd,
2915 tANI_U8 cmd_len)
2916{
2917 tANI_U8 *value;
2918 tANI_U8 fcc_constraint;
2919
2920 eHalStatus status;
2921 int ret = 0;
2922 value = cmd + cmd_len + 1;
2923
2924 ret = kstrtou8(value, 10, &fcc_constraint);
2925 if ((ret < 0) || (fcc_constraint > 1)) {
2926 /*
2927 * If the input value is greater than max value of datatype,
2928 * then also it is a failure
2929 */
2930 hddLog(VOS_TRACE_LEVEL_ERROR,
2931 "%s: value out of range", __func__);
2932 return -EINVAL;
2933 }
2934
Agrawal Ashish842eea82016-02-04 17:56:16 +05302935 status = sme_handleSetFccChannel(pHddCtx->hHal, fcc_constraint,
2936 pHddCtx->scan_info.mScanPending);
Agarwal Ashish8bd53ae2015-06-12 18:03:45 +05302937 if (status != eHAL_STATUS_SUCCESS)
2938 ret = -EPERM;
2939
2940 return ret;
2941}
2942
Mahesh A Saptasagarbeca12c2015-09-07 16:21:06 +05302943/**---------------------------------------------------------------------------
Agarwal Ashish8bd53ae2015-06-12 18:03:45 +05302944
Mahesh A Saptasagarbeca12c2015-09-07 16:21:06 +05302945 \brief hdd_enable_disable_ca_event() - When Host sends IOCTL (enabled),
2946 FW will send *ONE* CA ind to Host(even though it is duplicate).
2947 When Host send IOCTL (disable), FW doesn't perform any action.
2948 Whenever any change in CA *and* WLAN is in SAP/P2P-GO mode, FW
2949 sends CA ind to host. (regard less of IOCTL status)
2950 \param - pHddCtx - HDD context
2951 \param - command - command received from framework
2952 \param - cmd_len - len of the command
2953
2954 \return - 0 on success, appropriate error values on failure.
2955
2956 --------------------------------------------------------------------------*/
2957int hdd_enable_disable_ca_event(hdd_context_t *pHddCtx, tANI_U8* command, tANI_U8 cmd_len)
2958{
2959 tANI_U8 set_value;
2960 int ret = 0;
2961 eHalStatus status;
2962
2963 ret = wlan_hdd_validate_context(pHddCtx);
2964 if (0 != ret)
2965 {
2966 ret = -EINVAL;
2967 goto exit;
2968 }
2969
2970 if (pHddCtx->cfg_ini->gOptimizeCAevent == 0)
2971 {
2972 hddLog(VOS_TRACE_LEVEL_ERROR, "Enable gOptimizeCAevent"
2973 " ini param to control channel avooidance indication");
2974 ret = 0;
2975 goto exit;
2976 }
2977
2978 set_value = command[cmd_len + 1] - '0';
2979 status = sme_enableDisableChanAvoidIndEvent(pHddCtx->hHal, set_value);
2980 if (status != eHAL_STATUS_SUCCESS)
2981 {
2982 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Failed to send"
2983 " enableDisableChanAoidance command to SME\n", __func__);
2984 ret = -EINVAL;
2985 }
2986
2987exit:
2988 return ret;
2989}
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302990
Selvaraj, Sridhar3714c4d2016-06-22 15:19:12 +05302991/**
2992 * wlan_hdd_fastreassoc_handoff_request() - Post Handoff request to SME
2993 * @pHddCtx: Pointer to the HDD context
2994 * @channel: channel to reassociate
2995 * @targetApBssid: Target AP/BSSID to reassociate
2996 *
2997 * Return: None
2998 */
2999#if defined(WLAN_FEATURE_ROAM_SCAN_OFFLOAD) && !defined(QCA_WIFI_ISOC)
3000static void wlan_hdd_fastreassoc_handoff_request(hdd_context_t *pHddCtx,
3001 uint8_t channel, tSirMacAddr targetApBssid)
3002{
3003 tCsrHandoffRequest handoffInfo;
3004 handoffInfo.channel = channel;
3005 handoffInfo.src = FASTREASSOC;
3006 vos_mem_copy(handoffInfo.bssid, targetApBssid, sizeof(tSirMacAddr));
3007 sme_HandoffRequest(pHddCtx->hHal, &handoffInfo);
3008}
3009#else
3010static void wlan_hdd_fastreassoc_handoff_request(hdd_context_t *pHddCtx,
3011 uint8_t channel, tSirMacAddr targetApBssid)
3012{
3013}
3014#endif
3015
3016/**
3017 * csr_fastroam_neighbor_ap_event() - Function to trigger scan/roam
3018 * @pAdapter: Pointer to HDD adapter
3019 * @channel: Channel to scan/roam
3020 * @targetApBssid: BSSID to roam
3021 *
3022 * Return: None
3023 */
3024#ifdef QCA_WIFI_ISOC
3025static void csr_fastroam_neighbor_ap_event(hdd_adapter_t *pAdapter,
3026 uint8_t channel, tSirMacAddr targetApBssid)
3027{
3028 smeIssueFastRoamNeighborAPEvent(WLAN_HDD_GET_HAL_CTX(pAdapter),
3029 &targetApBssid[0], eSME_ROAM_TRIGGER_SCAN, channel);
3030}
3031#else
3032static void csr_fastroam_neighbor_ap_event(hdd_adapter_t *pAdapter,
3033 uint8_t channel, tSirMacAddr targetApBssid)
3034{
3035}
3036#endif
3037
3038/**
3039 * wlan_hdd_handle_fastreassoc() - Handle fastreassoc command
3040 * @pAdapter: pointer to hdd adapter
3041 * @command: pointer to the command received
3042 *
3043 * Return: VOS_STATUS enum
3044 */
3045static VOS_STATUS wlan_hdd_handle_fastreassoc(hdd_adapter_t *pAdapter,
3046 uint8_t *command)
3047{
3048 tANI_U8 *value = command;
3049 tANI_U8 channel = 0;
3050 tSirMacAddr targetApBssid;
Selvaraj, Sridhar3714c4d2016-06-22 15:19:12 +05303051 hdd_station_ctx_t *pHddStaCtx = NULL;
3052 hdd_context_t *pHddCtx = NULL;
Selvaraj, Sridhar5aff1ed2016-06-18 01:26:23 +05303053 int ret;
Selvaraj, Sridhar349b8fe2017-01-18 13:11:25 +05303054 tCsrRoamModifyProfileFields mod_profile_fields;
3055 uint32_t roam_id = 0;
Selvaraj, Sridhar3714c4d2016-06-22 15:19:12 +05303056 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
3057 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
3058
3059 /* if not associated, no need to proceed with reassoc */
3060 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState) {
3061 hddLog(LOG1, FL("Not associated!"));
3062 return eHAL_STATUS_FAILURE;
3063 }
3064
Selvaraj, Sridhar5aff1ed2016-06-18 01:26:23 +05303065 ret = hdd_parse_reassoc_command_v1_data(value, targetApBssid, &channel);
3066 if (ret) {
Selvaraj, Sridhar3714c4d2016-06-22 15:19:12 +05303067 hddLog(LOGE, FL("Failed to parse reassoc command data"));
3068 return eHAL_STATUS_FAILURE;
3069 }
3070
3071 /* if the target bssid is same as currently associated AP,
3072 then no need to proceed with reassoc */
3073 if (vos_mem_compare(targetApBssid,
3074 pHddStaCtx->conn_info.bssId,
3075 sizeof(tSirMacAddr))) {
Selvaraj, Sridhar349b8fe2017-01-18 13:11:25 +05303076 sme_GetModifyProfileFields(pHddCtx->hHal, pAdapter->sessionId,
3077 &mod_profile_fields);
3078 sme_RoamReassoc(pHddCtx->hHal, pAdapter->sessionId, NULL,
3079 mod_profile_fields, &roam_id, 1);
Selvaraj, Sridhar3714c4d2016-06-22 15:19:12 +05303080 hddLog(LOG1, FL("Reassoc BSSID is same as currently associated AP bssid"));
Selvaraj, Sridhar349b8fe2017-01-18 13:11:25 +05303081 return eHAL_STATUS_SUCCESS;
Selvaraj, Sridhar3714c4d2016-06-22 15:19:12 +05303082 }
3083
3084 /* Check channel number is a valid channel number */
3085 if (VOS_STATUS_SUCCESS !=
3086 wlan_hdd_validate_operation_channel(pAdapter, channel)) {
3087 hddLog(LOGE, FL("Invalid Channel [%d]"), channel);
3088 return eHAL_STATUS_FAILURE;
3089 }
3090
3091 /* Proceed with reassoc */
3092 wlan_hdd_fastreassoc_handoff_request(pHddCtx, channel, targetApBssid);
3093
3094 /* Proceed with scan/roam */
3095 csr_fastroam_neighbor_ap_event(pAdapter, channel, targetApBssid);
3096
3097 return eHAL_STATUS_SUCCESS;
3098}
3099
3100/**
3101 * hdd_assign_reassoc_handoff - Set handoff source as REASSOC
3102 * @handoffInfo: Pointer to the csr Handoff Request.
3103 *
3104 * Return: None
3105 */
3106#ifndef QCA_WIFI_ISOC
3107static inline void hdd_assign_reassoc_handoff(tCsrHandoffRequest *handoffInfo)
3108{
3109 handoffInfo->src = REASSOC;
3110}
3111#else
3112static inline void hdd_assign_reassoc_handoff(tCsrHandoffRequest *handoffInfo)
3113{
3114}
3115#endif
3116
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07003117static int hdd_driver_command(hdd_adapter_t *pAdapter,
3118 hdd_priv_data_t *ppriv_data)
Jeff Johnson295189b2012-06-20 16:38:30 -07003119{
Jeff Johnson295189b2012-06-20 16:38:30 -07003120 hdd_priv_data_t priv_data;
3121 tANI_U8 *command = NULL;
Kaushik, Sushant96122442014-10-21 16:40:18 +05303122 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
3123 hdd_scaninfo_t *pScanInfo = NULL;
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07003124 int ret = 0;
Kaushik, Sushant96122442014-10-21 16:40:18 +05303125 int status;
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05303126#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
3127 struct cfg80211_mgmt_tx_params params;
3128#endif
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303129
3130 ENTER();
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07003131 /*
3132 * Note that valid pointers are provided by caller
3133 */
Jeff Johnson295189b2012-06-20 16:38:30 -07003134
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07003135 /* copy to local struct to avoid numerous changes to legacy code */
3136 priv_data = *ppriv_data;
Jeff Johnson295189b2012-06-20 16:38:30 -07003137
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07003138 if (priv_data.total_len <= 0 ||
3139 priv_data.total_len > WLAN_PRIV_DATA_MAX_LEN)
Sameer Thalappil8ef3a0e2013-04-05 14:36:04 -07003140 {
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07003141 hddLog(VOS_TRACE_LEVEL_WARN,
3142 "%s:invalid priv_data.total_len(%d)!!!", __func__,
3143 priv_data.total_len);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07003144 ret = -EINVAL;
3145 goto exit;
3146 }
Kaushik, Sushant96122442014-10-21 16:40:18 +05303147 status = wlan_hdd_validate_context(pHddCtx);
3148 if (0 != status)
3149 {
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303150 ret = -EINVAL;
3151 goto exit;
Kaushik, Sushant96122442014-10-21 16:40:18 +05303152 }
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07003153 /* Allocate +1 for '\0' */
3154 command = kmalloc(priv_data.total_len + 1, GFP_KERNEL);
Jeff Johnson295189b2012-06-20 16:38:30 -07003155 if (!command)
3156 {
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07003157 hddLog(VOS_TRACE_LEVEL_ERROR,
3158 "%s: failed to allocate memory", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07003159 ret = -ENOMEM;
3160 goto exit;
3161 }
3162
3163 if (copy_from_user(command, priv_data.buf, priv_data.total_len))
3164 {
3165 ret = -EFAULT;
3166 goto exit;
3167 }
3168
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07003169 /* Make sure the command is NUL-terminated */
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07003170 command[priv_data.total_len] = '\0';
3171
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07003172 /* at one time the following block of code was conditional. braces
3173 * have been retained to avoid re-indenting the legacy code
3174 */
Jeff Johnson295189b2012-06-20 16:38:30 -07003175 {
3176 hdd_context_t *pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
3177
3178 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudif9bdd4e2012-10-30 18:05:03 -07003179 "%s: Received %s cmd from Wi-Fi GUI***", __func__, command);
Jeff Johnson295189b2012-06-20 16:38:30 -07003180
3181 if (strncmp(command, "P2P_DEV_ADDR", 12) == 0 )
3182 {
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05303183 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
3184 TRACE_CODE_HDD_P2P_DEV_ADDR_IOCTL,
3185 pAdapter->sessionId, (unsigned)
3186 (*(pHddCtx->p2pDeviceAddress.bytes+2)<<24 |
3187 *(pHddCtx->p2pDeviceAddress.bytes+3)<<16 |
3188 *(pHddCtx->p2pDeviceAddress.bytes+4)<<8 |
3189 *(pHddCtx->p2pDeviceAddress.bytes+5))));
Jeff Johnson295189b2012-06-20 16:38:30 -07003190 if (copy_to_user(priv_data.buf, pHddCtx->p2pDeviceAddress.bytes,
3191 sizeof(tSirMacAddr)))
3192 {
3193 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08003194 "%s: failed to copy data to user buffer", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07003195 ret = -EFAULT;
3196 }
3197 }
Amar Singhal0974e402013-02-12 14:27:46 -08003198 else if(strncmp(command, "SETBAND", 7) == 0)
Jeff Johnson295189b2012-06-20 16:38:30 -07003199 {
Amar Singhal0974e402013-02-12 14:27:46 -08003200 tANI_U8 *ptr = command ;
Srinivas Girigowdade697412013-02-14 16:31:48 -08003201
Jeff Johnson295189b2012-06-20 16:38:30 -07003202 /* Change band request received */
Srinivas Girigowdade697412013-02-14 16:31:48 -08003203
3204 /* First 8 bytes will have "SETBAND " and
Jeff Johnson295189b2012-06-20 16:38:30 -07003205 * 9 byte will have band setting value */
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07003206 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Amar Singhal0974e402013-02-12 14:27:46 -08003207 "%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 +05303208 if(VOS_FTM_MODE != hdd_get_conparam())
3209 {
3210 /* Change band request received */
3211 ret = hdd_setBand_helper(pAdapter->dev, ptr);
3212 if(ret < 0)
3213 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
3214 "%s: failed to set band ret=%d", __func__, ret);
3215 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08003216 }
Kiet Lamf040f472013-11-20 21:15:23 +05303217 else if(strncmp(command, "SETWMMPS", 8) == 0)
3218 {
3219 tANI_U8 *ptr = command;
3220 ret = hdd_wmmps_helper(pAdapter, ptr);
3221 }
Agarwal Ashishef54a182014-12-16 15:07:31 +05303222
3223 else if(strncmp(command, "TDLSSCAN", 8) == 0)
3224 {
3225 tANI_U8 *ptr = command;
3226 ret = hdd_set_tdls_scan_type(pAdapter, ptr);
3227 }
3228
Jeff Johnson32d95a32012-09-10 13:15:23 -07003229 else if ( strncasecmp(command, "COUNTRY", 7) == 0 )
3230 {
3231 char *country_code;
3232
3233 country_code = command + 8;
Tushnim Bhattacharyya9cdf6082013-04-21 16:33:30 -07003234
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07003235 INIT_COMPLETION(pAdapter->change_country_code);
Tushnim Bhattacharyya9cdf6082013-04-21 16:33:30 -07003236 hdd_checkandupdate_dfssetting(pAdapter, country_code);
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -07003237#ifndef CONFIG_ENABLE_LINUX_REG
Gopichand Nakkaladacbcb52013-04-18 16:41:54 +05303238 hdd_checkandupdate_phymode(pAdapter, country_code);
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -07003239#endif
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07003240 ret = (int)sme_ChangeCountryCode(pHddCtx->hHal,
3241 (void *)(tSmeChangeCountryCallback)
3242 wlan_hdd_change_country_code_callback,
Abhishek Singha306a442013-11-07 18:39:01 +05303243 country_code, pAdapter, pHddCtx->pvosContext, eSIR_TRUE, eSIR_TRUE);
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07003244 if (eHAL_STATUS_SUCCESS == ret)
3245 {
3246 ret = wait_for_completion_interruptible_timeout(
3247 &pAdapter->change_country_code,
3248 msecs_to_jiffies(WLAN_WAIT_TIME_COUNTRY));
3249 if (0 >= ret)
3250 {
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07003251 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: SME while setting country code timed out %d",
c_hpothu6ff1c3c2013-10-01 19:01:57 +05303252 __func__, ret);
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07003253 }
3254 }
3255 else
Jeff Johnson32d95a32012-09-10 13:15:23 -07003256 {
3257 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07003258 "%s: SME Change Country code fail ret=%d", __func__, ret);
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07003259 ret = -EINVAL;
Jeff Johnson32d95a32012-09-10 13:15:23 -07003260 }
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07003261
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07003262 }
3263 /*
3264 command should be a string having format
3265 SET_SAP_CHANNEL_LIST <num of channels> <the channels seperated by spaces>
3266 */
Amar Singhal0974e402013-02-12 14:27:46 -08003267 else if(strncmp(command, "SET_SAP_CHANNEL_LIST", 20) == 0)
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07003268 {
Amar Singhal0974e402013-02-12 14:27:46 -08003269 tANI_U8 *ptr = command;
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07003270
3271 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07003272 " Received Command to Set Preferred Channels for SAP in %s", __func__);
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07003273
Mahesh Kumar Kalikot Veetil2aad8d82013-02-07 12:31:28 -08003274 ret = sapSetPreferredChannel(ptr);
Jeff Johnson32d95a32012-09-10 13:15:23 -07003275 }
Sameer Thalappil45931fb2013-02-01 11:18:05 -08003276 else if(strncmp(command, "SETSUSPENDMODE", 14) == 0)
3277 {
3278 int suspend = 0;
3279 tANI_U8 *ptr = (tANI_U8*)command + 15;
3280
3281 suspend = *ptr - '0';
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05303282 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
3283 TRACE_CODE_HDD_SETSUSPENDMODE_IOCTL,
3284 pAdapter->sessionId, suspend));
Sameer Thalappil45931fb2013-02-01 11:18:05 -08003285 hdd_set_wlan_suspend_mode(suspend);
3286 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08003287#ifdef WLAN_FEATURE_NEIGHBOR_ROAMING
3288 else if (strncmp(command, "SETROAMTRIGGER", 14) == 0)
3289 {
3290 tANI_U8 *value = command;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07003291 tANI_S8 rssi = 0;
Srinivas Girigowdade697412013-02-14 16:31:48 -08003292 tANI_U8 lookUpThreshold = CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_DEFAULT;
3293 eHalStatus status = eHAL_STATUS_SUCCESS;
3294
3295 /* Move pointer to ahead of SETROAMTRIGGER<delimiter> */
3296 value = value + 15;
3297
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07003298 /* Convert the value from ascii to integer */
3299 ret = kstrtos8(value, 10, &rssi);
3300 if (ret < 0)
3301 {
3302 /* If the input value is greater than max value of datatype, then also
3303 kstrtou8 fails */
3304 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3305 "%s: kstrtou8 failed Input value may be out of range[%d - %d]",
Srinivas Girigowdafa7157d2013-10-31 10:14:22 -07003306 __func__,
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07003307 CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MIN,
3308 CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MAX);
3309 ret = -EINVAL;
3310 goto exit;
3311 }
3312
Srinivas Girigowdade697412013-02-14 16:31:48 -08003313 lookUpThreshold = abs(rssi);
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07003314
Srinivas Girigowdade697412013-02-14 16:31:48 -08003315 if ((lookUpThreshold < CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MIN) ||
3316 (lookUpThreshold > CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MAX))
3317 {
3318 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3319 "Neighbor lookup threshold value %d is out of range"
3320 " (Min: %d Max: %d)", lookUpThreshold,
3321 CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MIN,
3322 CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MAX);
3323 ret = -EINVAL;
3324 goto exit;
3325 }
3326
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05303327 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
3328 TRACE_CODE_HDD_SETROAMTRIGGER_IOCTL,
3329 pAdapter->sessionId, lookUpThreshold));
Srinivas Girigowdade697412013-02-14 16:31:48 -08003330 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3331 "%s: Received Command to Set Roam trigger"
3332 " (Neighbor lookup threshold) = %d", __func__, lookUpThreshold);
3333
3334 pHddCtx->cfg_ini->nNeighborLookupRssiThreshold = lookUpThreshold;
3335 status = sme_setNeighborLookupRssiThreshold((tHalHandle)(pHddCtx->hHal), lookUpThreshold);
3336 if (eHAL_STATUS_SUCCESS != status)
3337 {
3338 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3339 "%s: Failed to set roam trigger, try again", __func__);
3340 ret = -EPERM;
3341 goto exit;
3342 }
3343
3344 /* Set Reassoc threshold to (lookup rssi threshold + 5 dBm) */
mukul sharmad6e1fdd2014-06-23 19:19:09 +05303345 pHddCtx->cfg_ini->nNeighborReassocRssiThreshold = lookUpThreshold + 5;
Srinivas Girigowdade697412013-02-14 16:31:48 -08003346 sme_setNeighborReassocRssiThreshold((tHalHandle)(pHddCtx->hHal), lookUpThreshold + 5);
3347 }
3348 else if (strncmp(command, "GETROAMTRIGGER", 14) == 0)
3349 {
3350 tANI_U8 lookUpThreshold = sme_getNeighborLookupRssiThreshold((tHalHandle)(pHddCtx->hHal));
3351 int rssi = (-1) * lookUpThreshold;
3352 char extra[32];
3353 tANI_U8 len = 0;
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05303354 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
3355 TRACE_CODE_HDD_GETROAMTRIGGER_IOCTL,
3356 pAdapter->sessionId, lookUpThreshold));
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003357 len = scnprintf(extra, sizeof(extra), "%s %d", command, rssi);
Srinivas Girigowda91719232015-07-13 15:10:10 +05303358 len = VOS_MIN(priv_data.total_len, len + 1);
3359 if (copy_to_user(priv_data.buf, &extra, len))
Srinivas Girigowdade697412013-02-14 16:31:48 -08003360 {
3361 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3362 "%s: failed to copy data to user buffer", __func__);
3363 ret = -EFAULT;
3364 goto exit;
3365 }
3366 }
3367 else if (strncmp(command, "SETROAMSCANPERIOD", 17) == 0)
3368 {
3369 tANI_U8 *value = command;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07003370 tANI_U8 roamScanPeriod = 0;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003371 tANI_U16 neighborEmptyScanRefreshPeriod = CFG_EMPTY_SCAN_REFRESH_PERIOD_DEFAULT;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07003372
Srinivas Girigowdade697412013-02-14 16:31:48 -08003373 /* input refresh period is in terms of seconds */
3374 /* Move pointer to ahead of SETROAMSCANPERIOD<delimiter> */
3375 value = value + 18;
3376 /* Convert the value from ascii to integer */
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07003377 ret = kstrtou8(value, 10, &roamScanPeriod);
Srinivas Girigowdade697412013-02-14 16:31:48 -08003378 if (ret < 0)
3379 {
3380 /* If the input value is greater than max value of datatype, then also
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07003381 kstrtou8 fails */
Srinivas Girigowdade697412013-02-14 16:31:48 -08003382 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07003383 "%s: kstrtou8 failed Input value may be out of range[%d - %d]",
Srinivas Girigowdade697412013-02-14 16:31:48 -08003384 __func__,
Srinivas Girigowdab8edd1e2013-03-19 11:42:08 -07003385 (CFG_EMPTY_SCAN_REFRESH_PERIOD_MIN/1000),
3386 (CFG_EMPTY_SCAN_REFRESH_PERIOD_MAX/1000));
Srinivas Girigowdade697412013-02-14 16:31:48 -08003387 ret = -EINVAL;
3388 goto exit;
3389 }
3390
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07003391 if ((roamScanPeriod < (CFG_EMPTY_SCAN_REFRESH_PERIOD_MIN/1000)) ||
3392 (roamScanPeriod > (CFG_EMPTY_SCAN_REFRESH_PERIOD_MAX/1000)))
Srinivas Girigowdade697412013-02-14 16:31:48 -08003393 {
3394 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07003395 "Roam scan period value %d is out of range"
3396 " (Min: %d Max: %d)", roamScanPeriod,
Srinivas Girigowdab8edd1e2013-03-19 11:42:08 -07003397 (CFG_EMPTY_SCAN_REFRESH_PERIOD_MIN/1000),
3398 (CFG_EMPTY_SCAN_REFRESH_PERIOD_MAX/1000));
Srinivas Girigowdade697412013-02-14 16:31:48 -08003399 ret = -EINVAL;
3400 goto exit;
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05303401 }
3402 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
3403 TRACE_CODE_HDD_SETROAMSCANPERIOD_IOCTL,
3404 pAdapter->sessionId, roamScanPeriod));
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07003405 neighborEmptyScanRefreshPeriod = roamScanPeriod * 1000;
Srinivas Girigowdade697412013-02-14 16:31:48 -08003406
3407 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3408 "%s: Received Command to Set roam scan period"
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07003409 " (Empty Scan refresh period) = %d", __func__, roamScanPeriod);
Srinivas Girigowdade697412013-02-14 16:31:48 -08003410
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003411 pHddCtx->cfg_ini->nEmptyScanRefreshPeriod = neighborEmptyScanRefreshPeriod;
3412 sme_UpdateEmptyScanRefreshPeriod((tHalHandle)(pHddCtx->hHal), neighborEmptyScanRefreshPeriod);
Srinivas Girigowdade697412013-02-14 16:31:48 -08003413 }
3414 else if (strncmp(command, "GETROAMSCANPERIOD", 17) == 0)
3415 {
3416 tANI_U16 nEmptyScanRefreshPeriod = sme_getEmptyScanRefreshPeriod((tHalHandle)(pHddCtx->hHal));
3417 char extra[32];
3418 tANI_U8 len = 0;
3419
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05303420 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
3421 TRACE_CODE_HDD_GETROAMSCANPERIOD_IOCTL,
3422 pAdapter->sessionId, nEmptyScanRefreshPeriod));
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003423 len = scnprintf(extra, sizeof(extra), "%s %d",
3424 "GETROAMSCANPERIOD", (nEmptyScanRefreshPeriod/1000));
Srinivas Girigowdade697412013-02-14 16:31:48 -08003425 /* Returned value is in units of seconds */
Ratnam Rachuria72ba112015-07-17 13:27:03 +05303426 len = VOS_MIN(priv_data.total_len, len + 1);
3427 if (copy_to_user(priv_data.buf, &extra, len)) {
Srinivas Girigowdade697412013-02-14 16:31:48 -08003428 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3429 "%s: failed to copy data to user buffer", __func__);
3430 ret = -EFAULT;
3431 goto exit;
3432 }
3433 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003434 else if (strncmp(command, "SETROAMSCANREFRESHPERIOD", 24) == 0)
3435 {
3436 tANI_U8 *value = command;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07003437 tANI_U8 roamScanRefreshPeriod = 0;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003438 tANI_U16 neighborScanRefreshPeriod = CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_DEFAULT;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07003439
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003440 /* input refresh period is in terms of seconds */
3441 /* Move pointer to ahead of SETROAMSCANREFRESHPERIOD<delimiter> */
3442 value = value + 25;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07003443
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003444 /* Convert the value from ascii to integer */
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07003445 ret = kstrtou8(value, 10, &roamScanRefreshPeriod);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003446 if (ret < 0)
3447 {
3448 /* If the input value is greater than max value of datatype, then also
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07003449 kstrtou8 fails */
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003450 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07003451 "%s: kstrtou8 failed Input value may be out of range[%d - %d]",
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003452 __func__,
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003453 (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MIN/1000),
3454 (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MAX/1000));
3455 ret = -EINVAL;
3456 goto exit;
3457 }
3458
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07003459 if ((roamScanRefreshPeriod < (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MIN/1000)) ||
3460 (roamScanRefreshPeriod > (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MAX/1000)))
3461 {
3462 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3463 "Neighbor scan results refresh period value %d is out of range"
3464 " (Min: %d Max: %d)", roamScanRefreshPeriod,
3465 (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MIN/1000),
3466 (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MAX/1000));
3467 ret = -EINVAL;
3468 goto exit;
3469 }
3470 neighborScanRefreshPeriod = roamScanRefreshPeriod * 1000;
3471
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003472 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3473 "%s: Received Command to Set roam scan refresh period"
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07003474 " (Scan refresh period) = %d", __func__, roamScanRefreshPeriod);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003475
3476 pHddCtx->cfg_ini->nNeighborResultsRefreshPeriod = neighborScanRefreshPeriod;
3477 sme_setNeighborScanRefreshPeriod((tHalHandle)(pHddCtx->hHal), neighborScanRefreshPeriod);
3478 }
3479 else if (strncmp(command, "GETROAMSCANREFRESHPERIOD", 24) == 0)
3480 {
3481 tANI_U16 value = sme_getNeighborScanRefreshPeriod((tHalHandle)(pHddCtx->hHal));
3482 char extra[32];
3483 tANI_U8 len = 0;
3484
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003485 len = scnprintf(extra, sizeof(extra), "%s %d",
3486 "GETROAMSCANREFRESHPERIOD", (value/1000));
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003487 /* Returned value is in units of seconds */
Ratnam Rachuri2c9d6702015-07-17 13:25:16 +05303488 len = VOS_MIN(priv_data.total_len, len + 1);
3489 if (copy_to_user(priv_data.buf, &extra, len)) {
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003490 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3491 "%s: failed to copy data to user buffer", __func__);
3492 ret = -EFAULT;
3493 goto exit;
3494 }
3495 }
Varun Reddy Yeturu6d99ac82013-05-08 14:15:35 -07003496#ifdef FEATURE_WLAN_LFR
3497 /* SETROAMMODE */
3498 else if (strncmp(command, "SETROAMMODE", SIZE_OF_SETROAMMODE) == 0)
3499 {
3500 tANI_U8 *value = command;
3501 tANI_BOOLEAN roamMode = CFG_LFR_FEATURE_ENABLED_DEFAULT;
3502
3503 /* Move pointer to ahead of SETROAMMODE<delimiter> */
3504 value = value + SIZE_OF_SETROAMMODE + 1;
3505
3506 /* Convert the value from ascii to integer */
3507 ret = kstrtou8(value, SIZE_OF_SETROAMMODE, &roamMode);
3508 if (ret < 0)
3509 {
3510 /* If the input value is greater than max value of datatype, then also
3511 kstrtou8 fails */
3512 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3513 "%s: kstrtou8 failed range [%d - %d]", __func__,
3514 CFG_LFR_FEATURE_ENABLED_MIN,
3515 CFG_LFR_FEATURE_ENABLED_MAX);
3516 ret = -EINVAL;
3517 goto exit;
3518 }
3519 if ((roamMode < CFG_LFR_FEATURE_ENABLED_MIN) ||
3520 (roamMode > CFG_LFR_FEATURE_ENABLED_MAX))
3521 {
3522 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3523 "Roam Mode value %d is out of range"
3524 " (Min: %d Max: %d)", roamMode,
3525 CFG_LFR_FEATURE_ENABLED_MIN,
3526 CFG_LFR_FEATURE_ENABLED_MAX);
3527 ret = -EINVAL;
3528 goto exit;
3529 }
3530
3531 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3532 "%s: Received Command to Set Roam Mode = %d", __func__, roamMode);
3533 /*
3534 * Note that
3535 * SETROAMMODE 0 is to enable LFR while
3536 * SETROAMMODE 1 is to disable LFR, but
3537 * NotifyIsFastRoamIniFeatureEnabled 0/1 is to enable/disable.
3538 * So, we have to invert the value to call sme_UpdateIsFastRoamIniFeatureEnabled.
3539 */
3540 if (CFG_LFR_FEATURE_ENABLED_MIN == roamMode)
3541 roamMode = CFG_LFR_FEATURE_ENABLED_MAX; /* Roam enable */
3542 else
3543 roamMode = CFG_LFR_FEATURE_ENABLED_MIN; /* Roam disable */
3544
3545 pHddCtx->cfg_ini->isFastRoamIniFeatureEnabled = roamMode;
3546 sme_UpdateIsFastRoamIniFeatureEnabled((tHalHandle)(pHddCtx->hHal), roamMode);
3547 }
3548 /* GETROAMMODE */
Mahesh A Saptasagarec7d1092015-04-02 13:41:34 +05303549 else if (strncmp(command, "GETROAMMODE", SIZE_OF_GETROAMMODE) == 0)
Varun Reddy Yeturu6d99ac82013-05-08 14:15:35 -07003550 {
3551 tANI_BOOLEAN roamMode = sme_getIsLfrFeatureEnabled((tHalHandle)(pHddCtx->hHal));
3552 char extra[32];
3553 tANI_U8 len = 0;
3554
3555 /*
3556 * roamMode value shall be inverted because the sementics is different.
3557 */
3558 if (CFG_LFR_FEATURE_ENABLED_MIN == roamMode)
3559 roamMode = CFG_LFR_FEATURE_ENABLED_MAX;
3560 else
3561 roamMode = CFG_LFR_FEATURE_ENABLED_MIN;
3562
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003563 len = scnprintf(extra, sizeof(extra), "%s %d", command, roamMode);
Ratnam Rachuri28693eb2015-07-17 13:23:42 +05303564 len = VOS_MIN(priv_data.total_len, len + 1);
3565 if (copy_to_user(priv_data.buf, &extra, len)) {
Varun Reddy Yeturu6d99ac82013-05-08 14:15:35 -07003566 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3567 "%s: failed to copy data to user buffer", __func__);
3568 ret = -EFAULT;
3569 goto exit;
3570 }
3571 }
3572#endif
Srinivas Girigowdade697412013-02-14 16:31:48 -08003573#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003574#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowdade697412013-02-14 16:31:48 -08003575 else if (strncmp(command, "SETROAMDELTA", 12) == 0)
3576 {
3577 tANI_U8 *value = command;
3578 tANI_U8 roamRssiDiff = CFG_ROAM_RSSI_DIFF_DEFAULT;
3579
3580 /* Move pointer to ahead of SETROAMDELTA<delimiter> */
3581 value = value + 13;
3582 /* Convert the value from ascii to integer */
3583 ret = kstrtou8(value, 10, &roamRssiDiff);
3584 if (ret < 0)
3585 {
3586 /* If the input value is greater than max value of datatype, then also
3587 kstrtou8 fails */
3588 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3589 "%s: kstrtou8 failed range [%d - %d]", __func__,
3590 CFG_ROAM_RSSI_DIFF_MIN,
3591 CFG_ROAM_RSSI_DIFF_MAX);
3592 ret = -EINVAL;
3593 goto exit;
3594 }
3595
3596 if ((roamRssiDiff < CFG_ROAM_RSSI_DIFF_MIN) ||
3597 (roamRssiDiff > CFG_ROAM_RSSI_DIFF_MAX))
3598 {
3599 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3600 "Roam rssi diff value %d is out of range"
3601 " (Min: %d Max: %d)", roamRssiDiff,
3602 CFG_ROAM_RSSI_DIFF_MIN,
3603 CFG_ROAM_RSSI_DIFF_MAX);
3604 ret = -EINVAL;
3605 goto exit;
3606 }
3607
3608 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3609 "%s: Received Command to Set roam rssi diff = %d", __func__, roamRssiDiff);
3610
3611 pHddCtx->cfg_ini->RoamRssiDiff = roamRssiDiff;
3612 sme_UpdateRoamRssiDiff((tHalHandle)(pHddCtx->hHal), roamRssiDiff);
3613 }
Mahesh A Saptasagarec7d1092015-04-02 13:41:34 +05303614 else if (strncmp(command, "GETROAMDELTA", 12) == 0)
Srinivas Girigowdade697412013-02-14 16:31:48 -08003615 {
3616 tANI_U8 roamRssiDiff = sme_getRoamRssiDiff((tHalHandle)(pHddCtx->hHal));
3617 char extra[32];
3618 tANI_U8 len = 0;
3619
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05303620 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
3621 TRACE_CODE_HDD_GETROAMDELTA_IOCTL,
3622 pAdapter->sessionId, roamRssiDiff));
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003623 len = scnprintf(extra, sizeof(extra), "%s %d",
3624 command, roamRssiDiff);
Ratnam Rachuri22a3b402015-07-17 13:21:49 +05303625 len = VOS_MIN(priv_data.total_len, len + 1);
3626 if (copy_to_user(priv_data.buf, &extra, len)) {
Srinivas Girigowdade697412013-02-14 16:31:48 -08003627 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3628 "%s: failed to copy data to user buffer", __func__);
3629 ret = -EFAULT;
3630 goto exit;
3631 }
3632 }
3633#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003634#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowdade697412013-02-14 16:31:48 -08003635 else if (strncmp(command, "GETBAND", 7) == 0)
3636 {
3637 int band = -1;
3638 char extra[32];
3639 tANI_U8 len = 0;
3640 hdd_getBand_helper(pHddCtx, &band);
3641
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05303642 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
3643 TRACE_CODE_HDD_GETBAND_IOCTL,
3644 pAdapter->sessionId, band));
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003645 len = scnprintf(extra, sizeof(extra), "%s %d", command, band);
Ratnam Rachuri52139592015-07-17 13:17:29 +05303646 len = VOS_MIN(priv_data.total_len, len + 1);
3647 if (copy_to_user(priv_data.buf, &extra, len)) {
Srinivas Girigowdade697412013-02-14 16:31:48 -08003648 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3649 "%s: failed to copy data to user buffer", __func__);
3650 ret = -EFAULT;
3651 goto exit;
3652 }
3653 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08003654 else if (strncmp(command, "SETROAMSCANCHANNELS", 19) == 0)
3655 {
3656 tANI_U8 *value = command;
3657 tANI_U8 ChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
3658 tANI_U8 numChannels = 0;
3659 eHalStatus status = eHAL_STATUS_SUCCESS;
3660
3661 status = hdd_parse_channellist(value, ChannelList, &numChannels);
3662 if (eHAL_STATUS_SUCCESS != status)
3663 {
3664 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3665 "%s: Failed to parse channel list information", __func__);
3666 ret = -EINVAL;
3667 goto exit;
3668 }
3669
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05303670 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
3671 TRACE_CODE_HDD_SETROAMSCANCHANNELS_IOCTL,
3672 pAdapter->sessionId, numChannels));
Srinivas Girigowdade697412013-02-14 16:31:48 -08003673 if (numChannels > WNI_CFG_VALID_CHANNEL_LIST_LEN)
3674 {
3675 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3676 "%s: number of channels (%d) supported exceeded max (%d)", __func__,
3677 numChannels, WNI_CFG_VALID_CHANNEL_LIST_LEN);
3678 ret = -EINVAL;
3679 goto exit;
3680 }
3681 status = sme_ChangeRoamScanChannelList((tHalHandle)(pHddCtx->hHal), ChannelList,
3682 numChannels);
3683 if (eHAL_STATUS_SUCCESS != status)
3684 {
3685 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3686 "%s: Failed to update channel list information", __func__);
3687 ret = -EINVAL;
3688 goto exit;
3689 }
3690 }
3691 else if (strncmp(command, "GETROAMSCANCHANNELS", 19) == 0)
3692 {
3693 tANI_U8 ChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
3694 tANI_U8 numChannels = 0;
Jeff Johnson51b67782013-04-05 12:35:41 -07003695 tANI_U8 j = 0;
Srinivas Girigowdade697412013-02-14 16:31:48 -08003696 char extra[128] = {0};
Jeff Johnson51b67782013-04-05 12:35:41 -07003697 int len;
Srinivas Girigowdade697412013-02-14 16:31:48 -08003698
3699 if (eHAL_STATUS_SUCCESS != sme_getRoamScanChannelList( (tHalHandle)(pHddCtx->hHal),
3700 ChannelList, &numChannels ))
3701 {
3702 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
3703 "%s: failed to get roam scan channel list", __func__);
3704 ret = -EFAULT;
3705 goto exit;
3706 }
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05303707 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
3708 TRACE_CODE_HDD_GETROAMSCANCHANNELS_IOCTL,
3709 pAdapter->sessionId, numChannels));
Srinivas Girigowdade697412013-02-14 16:31:48 -08003710 /* output channel list is of the format
3711 [Number of roam scan channels][Channel1][Channel2]... */
3712 /* copy the number of channels in the 0th index */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003713 len = scnprintf(extra, sizeof(extra), "%s %d", command, numChannels);
Sushant Kaushika08ca192015-09-16 15:52:04 +05303714 for (j = 0; (j < numChannels) && len <= sizeof(extra); j++)
Srinivas Girigowdade697412013-02-14 16:31:48 -08003715 {
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003716 len += scnprintf(extra + len, sizeof(extra) - len, " %d",
3717 ChannelList[j]);
Srinivas Girigowdade697412013-02-14 16:31:48 -08003718 }
3719
Sushant Kaushikc9b8be52015-07-15 16:41:27 +05303720 len = VOS_MIN(priv_data.total_len, len + 1);
3721 if (copy_to_user(priv_data.buf, &extra, len))
Srinivas Girigowdade697412013-02-14 16:31:48 -08003722 {
3723 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3724 "%s: failed to copy data to user buffer", __func__);
3725 ret = -EFAULT;
3726 goto exit;
3727 }
3728 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003729 else if (strncmp(command, "GETCCXMODE", 10) == 0)
3730 {
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003731 tANI_BOOLEAN eseMode = sme_getIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal));
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003732 char extra[32];
3733 tANI_U8 len = 0;
3734
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003735 /* Check if the features OKC/ESE/11R are supported simultaneously,
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07003736 then this operation is not permitted (return FAILURE) */
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003737 if (eseMode &&
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07003738 hdd_is_okc_mode_enabled(pHddCtx) &&
3739 sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal)))
3740 {
3741 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003742 "%s: OKC/ESE/11R are supported simultaneously"
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07003743 " hence this operation is not permitted!", __func__);
3744 ret = -EPERM;
3745 goto exit;
3746 }
3747
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003748 len = scnprintf(extra, sizeof(extra), "%s %d",
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003749 "GETCCXMODE", eseMode);
Sushant Kaushikf8abd352015-07-15 16:37:49 +05303750 len = VOS_MIN(priv_data.total_len, len + 1);
3751 if (copy_to_user(priv_data.buf, &extra, len))
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003752 {
3753 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3754 "%s: failed to copy data to user buffer", __func__);
3755 ret = -EFAULT;
3756 goto exit;
3757 }
3758 }
3759 else if (strncmp(command, "GETOKCMODE", 10) == 0)
3760 {
3761 tANI_BOOLEAN okcMode = hdd_is_okc_mode_enabled(pHddCtx);
3762 char extra[32];
3763 tANI_U8 len = 0;
3764
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003765 /* Check if the features OKC/ESE/11R are supported simultaneously,
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07003766 then this operation is not permitted (return FAILURE) */
3767 if (okcMode &&
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003768 sme_getIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal)) &&
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07003769 sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal)))
3770 {
3771 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003772 "%s: OKC/ESE/11R are supported simultaneously"
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07003773 " hence this operation is not permitted!", __func__);
3774 ret = -EPERM;
3775 goto exit;
3776 }
3777
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003778 len = scnprintf(extra, sizeof(extra), "%s %d",
3779 "GETOKCMODE", okcMode);
Sushant Kaushikbc2fb5c2015-07-15 16:43:16 +05303780 len = VOS_MIN(priv_data.total_len, len + 1);
3781 if (copy_to_user(priv_data.buf, &extra, len))
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003782 {
3783 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3784 "%s: failed to copy data to user buffer", __func__);
3785 ret = -EFAULT;
3786 goto exit;
3787 }
3788 }
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07003789 else if (strncmp(command, "GETFASTROAM", 11) == 0)
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003790 {
3791 tANI_BOOLEAN lfrMode = sme_getIsLfrFeatureEnabled((tHalHandle)(pHddCtx->hHal));
3792 char extra[32];
3793 tANI_U8 len = 0;
3794
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003795 len = scnprintf(extra, sizeof(extra), "%s %d",
3796 "GETFASTROAM", lfrMode);
Sushant Kaushik4da7ec92015-07-15 16:39:32 +05303797 len = VOS_MIN(priv_data.total_len, len + 1);
3798 if (copy_to_user(priv_data.buf, &extra, len))
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003799 {
3800 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3801 "%s: failed to copy data to user buffer", __func__);
3802 ret = -EFAULT;
3803 goto exit;
3804 }
3805 }
3806 else if (strncmp(command, "GETFASTTRANSITION", 17) == 0)
3807 {
3808 tANI_BOOLEAN ft = sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal));
3809 char extra[32];
3810 tANI_U8 len = 0;
3811
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003812 len = scnprintf(extra, sizeof(extra), "%s %d",
3813 "GETFASTTRANSITION", ft);
Sushant Kaushik231a4452015-07-15 16:23:56 +05303814 len = VOS_MIN(priv_data.total_len, len + 1);
3815 if (copy_to_user(priv_data.buf, &extra, len))
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003816 {
3817 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3818 "%s: failed to copy data to user buffer", __func__);
3819 ret = -EFAULT;
3820 goto exit;
3821 }
3822 }
3823 else if (strncmp(command, "SETROAMSCANCHANNELMINTIME", 25) == 0)
3824 {
3825 tANI_U8 *value = command;
3826 tANI_U8 minTime = CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_DEFAULT;
3827
3828 /* Move pointer to ahead of SETROAMSCANCHANNELMINTIME<delimiter> */
3829 value = value + 26;
3830 /* Convert the value from ascii to integer */
3831 ret = kstrtou8(value, 10, &minTime);
3832 if (ret < 0)
3833 {
3834 /* If the input value is greater than max value of datatype, then also
3835 kstrtou8 fails */
3836 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3837 "%s: kstrtou8 failed range [%d - %d]", __func__,
3838 CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MIN,
3839 CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MAX);
3840 ret = -EINVAL;
3841 goto exit;
3842 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003843 if ((minTime < CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MIN) ||
3844 (minTime > CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MAX))
3845 {
3846 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3847 "scan min channel time value %d is out of range"
3848 " (Min: %d Max: %d)", minTime,
3849 CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MIN,
3850 CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MAX);
3851 ret = -EINVAL;
3852 goto exit;
3853 }
3854
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05303855 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
3856 TRACE_CODE_HDD_SETROAMSCANCHANNELMINTIME_IOCTL,
3857 pAdapter->sessionId, minTime));
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003858 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3859 "%s: Received Command to change channel min time = %d", __func__, minTime);
3860
3861 pHddCtx->cfg_ini->nNeighborScanMinChanTime = minTime;
3862 sme_setNeighborScanMinChanTime((tHalHandle)(pHddCtx->hHal), minTime);
3863 }
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003864 else if (strncmp(command, "SENDACTIONFRAME", 15) == 0)
3865 {
3866 tANI_U8 *value = command;
3867 tANI_U8 channel = 0;
3868 tANI_U8 dwellTime = 0;
3869 tANI_U8 bufLen = 0;
3870 tANI_U8 *buf = NULL;
3871 tSirMacAddr targetApBssid;
3872 eHalStatus status = eHAL_STATUS_SUCCESS;
3873 struct ieee80211_channel chan;
3874 tANI_U8 finalLen = 0;
3875 tANI_U8 *finalBuf = NULL;
3876 tANI_U8 temp = 0;
3877 u64 cookie;
3878 hdd_station_ctx_t *pHddStaCtx = NULL;
3879 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
3880
3881 /* if not associated, no need to send action frame */
3882 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
3883 {
3884 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s:Not associated!",__func__);
3885 ret = -EINVAL;
3886 goto exit;
3887 }
3888
3889 status = hdd_parse_send_action_frame_data(value, targetApBssid, &channel,
3890 &dwellTime, &buf, &bufLen);
3891 if (eHAL_STATUS_SUCCESS != status)
3892 {
3893 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3894 "%s: Failed to parse send action frame data", __func__);
3895 ret = -EINVAL;
3896 goto exit;
3897 }
3898
3899 /* if the target bssid is different from currently associated AP,
3900 then no need to send action frame */
3901 if (VOS_TRUE != vos_mem_compare(targetApBssid,
3902 pHddStaCtx->conn_info.bssId, sizeof(tSirMacAddr)))
3903 {
3904 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s:STA is not associated to this AP!",__func__);
3905 ret = -EINVAL;
Jeff Johnson11c33152013-04-16 17:52:40 -07003906 vos_mem_free(buf);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08003907 buf = NULL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003908 goto exit;
3909 }
3910
3911 /* if the channel number is different from operating channel then
3912 no need to send action frame */
3913 if (channel != pHddStaCtx->conn_info.operationChannel)
3914 {
3915 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3916 "%s: channel(%d) is different from operating channel(%d)",
3917 __func__, channel, pHddStaCtx->conn_info.operationChannel);
3918 ret = -EINVAL;
Jeff Johnson11c33152013-04-16 17:52:40 -07003919 vos_mem_free(buf);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08003920 buf = NULL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003921 goto exit;
3922 }
3923 chan.center_freq = sme_ChnToFreq(channel);
3924
3925 finalLen = bufLen + 24;
3926 finalBuf = vos_mem_malloc(finalLen);
3927 if (NULL == finalBuf)
3928 {
3929 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "%s:memory allocation failed",__func__);
3930 ret = -ENOMEM;
Jeff Johnson11c33152013-04-16 17:52:40 -07003931 vos_mem_free(buf);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08003932 buf = NULL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003933 goto exit;
3934 }
3935 vos_mem_zero(finalBuf, finalLen);
3936
3937 /* Fill subtype */
3938 temp = SIR_MAC_MGMT_ACTION << 4;
3939 vos_mem_copy(finalBuf + 0, &temp, sizeof(temp));
3940
3941 /* Fill type */
3942 temp = SIR_MAC_MGMT_FRAME;
3943 vos_mem_copy(finalBuf + 2, &temp, sizeof(temp));
3944
3945 /* Fill destination address (bssid of the AP) */
3946 vos_mem_copy(finalBuf + 4, targetApBssid, sizeof(targetApBssid));
3947
Srinivas Girigowdab27c0192013-06-03 10:19:56 -07003948 /* Fill source address (STA mac address) */
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003949 vos_mem_copy(finalBuf + 10, pAdapter->macAddressCurrent.bytes, sizeof(pAdapter->macAddressCurrent.bytes));
3950
Srinivas Girigowdab27c0192013-06-03 10:19:56 -07003951 /* Fill BSSID (AP mac address) */
3952 vos_mem_copy(finalBuf + 16, targetApBssid, sizeof(targetApBssid));
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003953
3954 /* Fill received buffer from 24th address */
3955 vos_mem_copy(finalBuf + 24, buf, bufLen);
3956
Jeff Johnson11c33152013-04-16 17:52:40 -07003957 /* done with the parsed buffer */
3958 vos_mem_free(buf);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08003959 buf = NULL;
Jeff Johnson11c33152013-04-16 17:52:40 -07003960
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05303961#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
3962 params.chan = &chan;
3963 params.offchan = 0;
3964 params.wait = dwellTime;
3965 params.buf = finalBuf;
3966 params.len = finalLen;
3967 params.no_cck = 1;
3968 params.dont_wait_for_ack = 1;
3969 ret = wlan_hdd_mgmt_tx(NULL, &pAdapter->wdev, &params, &cookie);
3970#else
DARAM SUDHA39eede62014-02-12 11:16:40 +05303971 wlan_hdd_mgmt_tx( NULL,
Yue Maf49ba872013-08-19 12:04:25 -07003972#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
3973 &(pAdapter->wdev),
3974#else
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07003975 pAdapter->dev,
Yue Maf49ba872013-08-19 12:04:25 -07003976#endif
3977 &chan, 0,
3978#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0))
3979 NL80211_CHAN_HT20, 1,
3980#endif
3981 dwellTime, finalBuf, finalLen, 1,
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003982 1, &cookie );
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05303983#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0)*/
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003984 vos_mem_free(finalBuf);
3985 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003986 else if (strncmp(command, "GETROAMSCANCHANNELMINTIME", 25) == 0)
3987 {
3988 tANI_U16 val = sme_getNeighborScanMinChanTime((tHalHandle)(pHddCtx->hHal));
3989 char extra[32];
3990 tANI_U8 len = 0;
3991
3992 /* value is interms of msec */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003993 len = scnprintf(extra, sizeof(extra), "%s %d",
3994 "GETROAMSCANCHANNELMINTIME", val);
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05303995 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
3996 TRACE_CODE_HDD_GETROAMSCANCHANNELMINTIME_IOCTL,
3997 pAdapter->sessionId, val));
Sushant Kaushikbb8c52c2015-07-15 16:36:23 +05303998 len = VOS_MIN(priv_data.total_len, len + 1);
3999 if (copy_to_user(priv_data.buf, &extra, len))
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004000 {
4001 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4002 "%s: failed to copy data to user buffer", __func__);
4003 ret = -EFAULT;
4004 goto exit;
4005 }
4006 }
4007 else if (strncmp(command, "SETSCANCHANNELTIME", 18) == 0)
4008 {
4009 tANI_U8 *value = command;
Varun Reddy Yeturu3885a662013-06-19 07:10:37 -07004010 tANI_U16 maxTime = CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_DEFAULT;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004011
4012 /* Move pointer to ahead of SETSCANCHANNELTIME<delimiter> */
4013 value = value + 19;
4014 /* Convert the value from ascii to integer */
Varun Reddy Yeturu3885a662013-06-19 07:10:37 -07004015 ret = kstrtou16(value, 10, &maxTime);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004016 if (ret < 0)
4017 {
4018 /* If the input value is greater than max value of datatype, then also
Varun Reddy Yeturu3885a662013-06-19 07:10:37 -07004019 kstrtou16 fails */
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004020 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Varun Reddy Yeturu3885a662013-06-19 07:10:37 -07004021 "%s: kstrtou16 failed range [%d - %d]", __func__,
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004022 CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MIN,
4023 CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MAX);
4024 ret = -EINVAL;
4025 goto exit;
4026 }
4027
4028 if ((maxTime < CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MIN) ||
4029 (maxTime > CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MAX))
4030 {
4031 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4032 "lfr mode value %d is out of range"
4033 " (Min: %d Max: %d)", maxTime,
4034 CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MIN,
4035 CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MAX);
4036 ret = -EINVAL;
4037 goto exit;
4038 }
4039
4040 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4041 "%s: Received Command to change channel max time = %d", __func__, maxTime);
4042
4043 pHddCtx->cfg_ini->nNeighborScanMaxChanTime = maxTime;
4044 sme_setNeighborScanMaxChanTime((tHalHandle)(pHddCtx->hHal), maxTime);
4045 }
4046 else if (strncmp(command, "GETSCANCHANNELTIME", 18) == 0)
4047 {
4048 tANI_U16 val = sme_getNeighborScanMaxChanTime((tHalHandle)(pHddCtx->hHal));
4049 char extra[32];
4050 tANI_U8 len = 0;
4051
4052 /* value is interms of msec */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07004053 len = scnprintf(extra, sizeof(extra), "%s %d",
4054 "GETSCANCHANNELTIME", val);
Ratheesh S Pacbfa932015-07-16 15:27:18 +05304055 len = VOS_MIN(priv_data.total_len, len + 1);
4056 if (copy_to_user(priv_data.buf, &extra, len))
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004057 {
4058 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4059 "%s: failed to copy data to user buffer", __func__);
4060 ret = -EFAULT;
4061 goto exit;
4062 }
4063 }
4064 else if (strncmp(command, "SETSCANHOMETIME", 15) == 0)
4065 {
4066 tANI_U8 *value = command;
4067 tANI_U16 val = CFG_NEIGHBOR_SCAN_TIMER_PERIOD_DEFAULT;
4068
4069 /* Move pointer to ahead of SETSCANHOMETIME<delimiter> */
4070 value = value + 16;
4071 /* Convert the value from ascii to integer */
4072 ret = kstrtou16(value, 10, &val);
4073 if (ret < 0)
4074 {
4075 /* If the input value is greater than max value of datatype, then also
4076 kstrtou16 fails */
4077 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4078 "%s: kstrtou16 failed range [%d - %d]", __func__,
4079 CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MIN,
4080 CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MAX);
4081 ret = -EINVAL;
4082 goto exit;
4083 }
4084
4085 if ((val < CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MIN) ||
4086 (val > CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MAX))
4087 {
4088 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4089 "scan home time value %d is out of range"
4090 " (Min: %d Max: %d)", val,
4091 CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MIN,
4092 CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MAX);
4093 ret = -EINVAL;
4094 goto exit;
4095 }
4096
4097 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4098 "%s: Received Command to change scan home time = %d", __func__, val);
4099
4100 pHddCtx->cfg_ini->nNeighborScanPeriod = val;
4101 sme_setNeighborScanPeriod((tHalHandle)(pHddCtx->hHal), val);
4102 }
4103 else if (strncmp(command, "GETSCANHOMETIME", 15) == 0)
4104 {
4105 tANI_U16 val = sme_getNeighborScanPeriod((tHalHandle)(pHddCtx->hHal));
4106 char extra[32];
4107 tANI_U8 len = 0;
4108
4109 /* value is interms of msec */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07004110 len = scnprintf(extra, sizeof(extra), "%s %d",
4111 "GETSCANHOMETIME", val);
Ratheesh S P728d7c62015-07-16 15:38:58 +05304112 len = VOS_MIN(priv_data.total_len, len + 1);
4113 if (copy_to_user(priv_data.buf, &extra, len))
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004114 {
4115 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4116 "%s: failed to copy data to user buffer", __func__);
4117 ret = -EFAULT;
4118 goto exit;
4119 }
4120 }
4121 else if (strncmp(command, "SETROAMINTRABAND", 16) == 0)
4122 {
4123 tANI_U8 *value = command;
4124 tANI_U8 val = CFG_ROAM_INTRA_BAND_DEFAULT;
4125
4126 /* Move pointer to ahead of SETROAMINTRABAND<delimiter> */
4127 value = value + 17;
4128 /* Convert the value from ascii to integer */
4129 ret = kstrtou8(value, 10, &val);
4130 if (ret < 0)
4131 {
4132 /* If the input value is greater than max value of datatype, then also
4133 kstrtou8 fails */
4134 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4135 "%s: kstrtou8 failed range [%d - %d]", __func__,
4136 CFG_ROAM_INTRA_BAND_MIN,
4137 CFG_ROAM_INTRA_BAND_MAX);
4138 ret = -EINVAL;
4139 goto exit;
4140 }
4141
4142 if ((val < CFG_ROAM_INTRA_BAND_MIN) ||
4143 (val > CFG_ROAM_INTRA_BAND_MAX))
4144 {
4145 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4146 "intra band mode value %d is out of range"
4147 " (Min: %d Max: %d)", val,
4148 CFG_ROAM_INTRA_BAND_MIN,
4149 CFG_ROAM_INTRA_BAND_MAX);
4150 ret = -EINVAL;
4151 goto exit;
4152 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004153 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4154 "%s: Received Command to change intra band = %d", __func__, val);
4155
4156 pHddCtx->cfg_ini->nRoamIntraBand = val;
4157 sme_setRoamIntraBand((tHalHandle)(pHddCtx->hHal), val);
4158 }
4159 else if (strncmp(command, "GETROAMINTRABAND", 16) == 0)
4160 {
4161 tANI_U16 val = sme_getRoamIntraBand((tHalHandle)(pHddCtx->hHal));
4162 char extra[32];
4163 tANI_U8 len = 0;
4164
4165 /* value is interms of msec */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07004166 len = scnprintf(extra, sizeof(extra), "%s %d",
4167 "GETROAMINTRABAND", val);
Ratheesh S P2dd2a3e2015-07-16 15:34:23 +05304168 len = VOS_MIN(priv_data.total_len, len + 1);
4169 if (copy_to_user(priv_data.buf, &extra, len))
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004170 {
4171 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4172 "%s: failed to copy data to user buffer", __func__);
4173 ret = -EFAULT;
4174 goto exit;
4175 }
4176 }
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07004177 else if (strncmp(command, "SETSCANNPROBES", 14) == 0)
4178 {
4179 tANI_U8 *value = command;
4180 tANI_U8 nProbes = CFG_ROAM_SCAN_N_PROBES_DEFAULT;
4181
4182 /* Move pointer to ahead of SETSCANNPROBES<delimiter> */
4183 value = value + 15;
4184 /* Convert the value from ascii to integer */
4185 ret = kstrtou8(value, 10, &nProbes);
4186 if (ret < 0)
4187 {
4188 /* If the input value is greater than max value of datatype, then also
4189 kstrtou8 fails */
4190 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4191 "%s: kstrtou8 failed range [%d - %d]", __func__,
4192 CFG_ROAM_SCAN_N_PROBES_MIN,
4193 CFG_ROAM_SCAN_N_PROBES_MAX);
4194 ret = -EINVAL;
4195 goto exit;
4196 }
4197
4198 if ((nProbes < CFG_ROAM_SCAN_N_PROBES_MIN) ||
4199 (nProbes > CFG_ROAM_SCAN_N_PROBES_MAX))
4200 {
4201 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4202 "NProbes value %d is out of range"
4203 " (Min: %d Max: %d)", nProbes,
4204 CFG_ROAM_SCAN_N_PROBES_MIN,
4205 CFG_ROAM_SCAN_N_PROBES_MAX);
4206 ret = -EINVAL;
4207 goto exit;
4208 }
4209
4210 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4211 "%s: Received Command to Set nProbes = %d", __func__, nProbes);
4212
4213 pHddCtx->cfg_ini->nProbes = nProbes;
4214 sme_UpdateRoamScanNProbes((tHalHandle)(pHddCtx->hHal), nProbes);
4215 }
Mahesh A Saptasagarec7d1092015-04-02 13:41:34 +05304216 else if (strncmp(command, "GETSCANNPROBES", 14) == 0)
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07004217 {
4218 tANI_U8 val = sme_getRoamScanNProbes((tHalHandle)(pHddCtx->hHal));
4219 char extra[32];
4220 tANI_U8 len = 0;
4221
Sameer Thalappilb0a30232013-09-27 15:37:48 -07004222 len = scnprintf(extra, sizeof(extra), "%s %d", command, val);
Ratnam Rachuri6da525d2015-08-07 13:55:54 +05304223 len = VOS_MIN(priv_data.total_len, len + 1);
4224 if (copy_to_user(priv_data.buf, &extra, len)) {
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07004225 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4226 "%s: failed to copy data to user buffer", __func__);
4227 ret = -EFAULT;
4228 goto exit;
4229 }
4230 }
4231 else if (strncmp(command, "SETSCANHOMEAWAYTIME", 19) == 0)
4232 {
4233 tANI_U8 *value = command;
4234 tANI_U16 homeAwayTime = CFG_ROAM_SCAN_HOME_AWAY_TIME_DEFAULT;
4235
4236 /* Move pointer to ahead of SETSCANHOMEAWAYTIME<delimiter> */
4237 /* input value is in units of msec */
4238 value = value + 20;
4239 /* Convert the value from ascii to integer */
4240 ret = kstrtou16(value, 10, &homeAwayTime);
4241 if (ret < 0)
4242 {
4243 /* If the input value is greater than max value of datatype, then also
4244 kstrtou8 fails */
4245 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4246 "%s: kstrtou8 failed range [%d - %d]", __func__,
4247 CFG_ROAM_SCAN_HOME_AWAY_TIME_MIN,
4248 CFG_ROAM_SCAN_HOME_AWAY_TIME_MAX);
4249 ret = -EINVAL;
4250 goto exit;
4251 }
4252
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07004253 if ((homeAwayTime < CFG_ROAM_SCAN_HOME_AWAY_TIME_MIN) ||
4254 (homeAwayTime > CFG_ROAM_SCAN_HOME_AWAY_TIME_MAX))
4255 {
4256 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4257 "homeAwayTime value %d is out of range"
4258 " (Min: %d Max: %d)", homeAwayTime,
4259 CFG_ROAM_SCAN_HOME_AWAY_TIME_MIN,
4260 CFG_ROAM_SCAN_HOME_AWAY_TIME_MAX);
4261 ret = -EINVAL;
4262 goto exit;
4263 }
4264
4265 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4266 "%s: Received Command to Set scan away time = %d", __func__, homeAwayTime);
Srinivas Girigowda6cf0b822013-06-27 14:00:20 -07004267 if (pHddCtx->cfg_ini->nRoamScanHomeAwayTime != homeAwayTime)
4268 {
4269 pHddCtx->cfg_ini->nRoamScanHomeAwayTime = homeAwayTime;
4270 sme_UpdateRoamScanHomeAwayTime((tHalHandle)(pHddCtx->hHal), homeAwayTime, eANI_BOOLEAN_TRUE);
4271 }
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07004272 }
Mahesh A Saptasagarec7d1092015-04-02 13:41:34 +05304273 else if (strncmp(command, "GETSCANHOMEAWAYTIME", 19) == 0)
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07004274 {
4275 tANI_U16 val = sme_getRoamScanHomeAwayTime((tHalHandle)(pHddCtx->hHal));
4276 char extra[32];
4277 tANI_U8 len = 0;
4278
Sameer Thalappilb0a30232013-09-27 15:37:48 -07004279 len = scnprintf(extra, sizeof(extra), "%s %d", command, val);
Ratnam Rachuri51a5ad12015-08-07 14:06:37 +05304280 len = VOS_MIN(priv_data.total_len, len + 1);
4281 if (copy_to_user(priv_data.buf, &extra, len)) {
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07004282 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4283 "%s: failed to copy data to user buffer", __func__);
4284 ret = -EFAULT;
4285 goto exit;
4286 }
4287 }
4288 else if (strncmp(command, "REASSOC", 7) == 0)
4289 {
Selvaraj, Sridhar5aff1ed2016-06-18 01:26:23 +05304290 ret = hdd_parse_reassoc(pAdapter, command);
4291 if (!ret)
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07004292 goto exit;
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07004293 }
Srinivas Girigowdaad34ca92013-10-22 10:54:29 -07004294 else if (strncmp(command, "SETWESMODE", 10) == 0)
4295 {
4296 tANI_U8 *value = command;
4297 tANI_BOOLEAN wesMode = CFG_ENABLE_WES_MODE_NAME_DEFAULT;
4298
4299 /* Move pointer to ahead of SETWESMODE<delimiter> */
4300 value = value + 11;
4301 /* Convert the value from ascii to integer */
4302 ret = kstrtou8(value, 10, &wesMode);
4303 if (ret < 0)
4304 {
4305 /* If the input value is greater than max value of datatype, then also
4306 kstrtou8 fails */
4307 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4308 "%s: kstrtou8 failed range [%d - %d]", __func__,
4309 CFG_ENABLE_WES_MODE_NAME_MIN,
4310 CFG_ENABLE_WES_MODE_NAME_MAX);
4311 ret = -EINVAL;
4312 goto exit;
4313 }
4314
4315 if ((wesMode < CFG_ENABLE_WES_MODE_NAME_MIN) ||
4316 (wesMode > CFG_ENABLE_WES_MODE_NAME_MAX))
4317 {
4318 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4319 "WES Mode value %d is out of range"
4320 " (Min: %d Max: %d)", wesMode,
4321 CFG_ENABLE_WES_MODE_NAME_MIN,
4322 CFG_ENABLE_WES_MODE_NAME_MAX);
4323 ret = -EINVAL;
4324 goto exit;
4325 }
4326 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4327 "%s: Received Command to Set WES Mode rssi diff = %d", __func__, wesMode);
4328
4329 pHddCtx->cfg_ini->isWESModeEnabled = wesMode;
4330 sme_UpdateWESMode((tHalHandle)(pHddCtx->hHal), wesMode);
4331 }
Mahesh A Saptasagarec7d1092015-04-02 13:41:34 +05304332 else if (strncmp(command, "GETWESMODE", 10) == 0)
Srinivas Girigowdaad34ca92013-10-22 10:54:29 -07004333 {
4334 tANI_BOOLEAN wesMode = sme_GetWESMode((tHalHandle)(pHddCtx->hHal));
4335 char extra[32];
4336 tANI_U8 len = 0;
4337
Arif Hussain826d9412013-11-12 16:44:54 -08004338 len = scnprintf(extra, sizeof(extra), "%s %d", command, wesMode);
Ratnam Rachuri8fe90c62015-08-07 14:03:26 +05304339 len = VOS_MIN(priv_data.total_len, len + 1);
4340 if (copy_to_user(priv_data.buf, &extra, len)) {
Srinivas Girigowdaad34ca92013-10-22 10:54:29 -07004341 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4342 "%s: failed to copy data to user buffer", __func__);
4343 ret = -EFAULT;
4344 goto exit;
4345 }
4346 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004347#endif /* WLAN_FEATURE_VOWIFI_11R || FEATURE_WLAN_ESE || FEATURE_WLAN_LFR */
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004348#ifdef FEATURE_WLAN_LFR
4349 else if (strncmp(command, "SETFASTROAM", 11) == 0)
4350 {
4351 tANI_U8 *value = command;
4352 tANI_U8 lfrMode = CFG_LFR_FEATURE_ENABLED_DEFAULT;
4353
4354 /* Move pointer to ahead of SETFASTROAM<delimiter> */
4355 value = value + 12;
4356 /* Convert the value from ascii to integer */
4357 ret = kstrtou8(value, 10, &lfrMode);
4358 if (ret < 0)
4359 {
4360 /* If the input value is greater than max value of datatype, then also
4361 kstrtou8 fails */
4362 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4363 "%s: kstrtou8 failed range [%d - %d]", __func__,
4364 CFG_LFR_FEATURE_ENABLED_MIN,
4365 CFG_LFR_FEATURE_ENABLED_MAX);
4366 ret = -EINVAL;
4367 goto exit;
4368 }
4369
4370 if ((lfrMode < CFG_LFR_FEATURE_ENABLED_MIN) ||
4371 (lfrMode > CFG_LFR_FEATURE_ENABLED_MAX))
4372 {
4373 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4374 "lfr mode value %d is out of range"
4375 " (Min: %d Max: %d)", lfrMode,
4376 CFG_LFR_FEATURE_ENABLED_MIN,
4377 CFG_LFR_FEATURE_ENABLED_MAX);
4378 ret = -EINVAL;
4379 goto exit;
4380 }
4381
4382 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4383 "%s: Received Command to change lfr mode = %d", __func__, lfrMode);
4384
4385 pHddCtx->cfg_ini->isFastRoamIniFeatureEnabled = lfrMode;
4386 sme_UpdateIsFastRoamIniFeatureEnabled((tHalHandle)(pHddCtx->hHal), lfrMode);
4387 }
4388#endif
4389#ifdef WLAN_FEATURE_VOWIFI_11R
4390 else if (strncmp(command, "SETFASTTRANSITION", 17) == 0)
4391 {
4392 tANI_U8 *value = command;
4393 tANI_U8 ft = CFG_FAST_TRANSITION_ENABLED_NAME_DEFAULT;
4394
4395 /* Move pointer to ahead of SETFASTROAM<delimiter> */
4396 value = value + 18;
4397 /* Convert the value from ascii to integer */
4398 ret = kstrtou8(value, 10, &ft);
4399 if (ret < 0)
4400 {
4401 /* If the input value is greater than max value of datatype, then also
4402 kstrtou8 fails */
4403 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4404 "%s: kstrtou8 failed range [%d - %d]", __func__,
4405 CFG_FAST_TRANSITION_ENABLED_NAME_MIN,
4406 CFG_FAST_TRANSITION_ENABLED_NAME_MAX);
4407 ret = -EINVAL;
4408 goto exit;
4409 }
4410
4411 if ((ft < CFG_FAST_TRANSITION_ENABLED_NAME_MIN) ||
4412 (ft > CFG_FAST_TRANSITION_ENABLED_NAME_MAX))
4413 {
4414 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4415 "ft mode value %d is out of range"
4416 " (Min: %d Max: %d)", ft,
4417 CFG_FAST_TRANSITION_ENABLED_NAME_MIN,
4418 CFG_FAST_TRANSITION_ENABLED_NAME_MAX);
4419 ret = -EINVAL;
4420 goto exit;
4421 }
4422
4423 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4424 "%s: Received Command to change ft mode = %d", __func__, ft);
4425
4426 pHddCtx->cfg_ini->isFastTransitionEnabled = ft;
4427 sme_UpdateFastTransitionEnabled((tHalHandle)(pHddCtx->hHal), ft);
4428 }
Padma, Santhosh Kumar778d8382015-03-04 17:41:22 +05304429 else if (strncmp(command, "SETDFSSCANMODE", 14) == 0)
4430 {
4431 tANI_U8 *value = command;
4432 tANI_U8 dfsScanMode = DFS_CHNL_SCAN_ENABLED_NORMAL;
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05304433
Padma, Santhosh Kumar778d8382015-03-04 17:41:22 +05304434 /* Move pointer to ahead of SETDFSSCANMODE<delimiter> */
4435 value = value + 15;
4436 /* Convert the value from ascii to integer */
4437 ret = kstrtou8(value, 10, &dfsScanMode);
4438 if (ret < 0)
4439 {
4440 /* If the input value is greater than max value of
4441 datatype, then also kstrtou8 fails
4442 */
4443 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4444 "%s: kstrtou8 failed range [%d - %d]", __func__,
4445 CFG_ENABLE_DFS_CHNL_SCAN_MIN,
4446 CFG_ENABLE_DFS_CHNL_SCAN_MAX);
4447 ret = -EINVAL;
4448 goto exit;
4449 }
4450
4451 if ((dfsScanMode < CFG_ENABLE_DFS_CHNL_SCAN_MIN) ||
4452 (dfsScanMode > CFG_ENABLE_DFS_CHNL_SCAN_MAX))
4453 {
4454 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4455 "dfsScanMode value %d is out of range"
4456 " (Min: %d Max: %d)", dfsScanMode,
4457 CFG_ENABLE_DFS_CHNL_SCAN_MIN,
4458 CFG_ENABLE_DFS_CHNL_SCAN_MAX);
4459 ret = -EINVAL;
4460 goto exit;
4461 }
4462 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4463 "%s: Received Command to Set DFS Scan Mode = %d",
4464 __func__, dfsScanMode);
4465
4466 ret = wlan_hdd_handle_dfs_chan_scan(pHddCtx, dfsScanMode);
4467 }
4468 else if (strncmp(command, "GETDFSSCANMODE", 14) == 0)
4469 {
4470 tANI_U8 dfsScanMode = sme_GetDFSScanMode(pHddCtx->hHal);
4471 char extra[32];
4472 tANI_U8 len = 0;
4473
4474 len = scnprintf(extra, sizeof(extra), "%s %d", command, dfsScanMode);
Ratheesh S P767224e2015-07-16 15:35:51 +05304475 len = VOS_MIN(priv_data.total_len, len + 1);
4476 if (copy_to_user(priv_data.buf, &extra, len))
Padma, Santhosh Kumar778d8382015-03-04 17:41:22 +05304477 {
4478 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4479 "%s: failed to copy data to user buffer", __func__);
4480 ret = -EFAULT;
4481 goto exit;
4482 }
4483 }
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05304484 else if (strncmp(command, "FASTREASSOC", 11) == 0)
4485 {
Selvaraj, Sridhar3714c4d2016-06-22 15:19:12 +05304486 ret = wlan_hdd_handle_fastreassoc(pAdapter, command);
4487 if (!ret)
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05304488 goto exit;
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05304489 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004490#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004491#ifdef FEATURE_WLAN_ESE
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004492 else if (strncmp(command, "SETCCXMODE", 10) == 0)
4493 {
4494 tANI_U8 *value = command;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004495 tANI_U8 eseMode = CFG_ESE_FEATURE_ENABLED_DEFAULT;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004496
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004497 /* Check if the features OKC/ESE/11R are supported simultaneously,
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07004498 then this operation is not permitted (return FAILURE) */
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004499 if (sme_getIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal)) &&
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07004500 hdd_is_okc_mode_enabled(pHddCtx) &&
4501 sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal)))
4502 {
4503 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004504 "%s: OKC/ESE/11R are supported simultaneously"
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07004505 " hence this operation is not permitted!", __func__);
4506 ret = -EPERM;
4507 goto exit;
4508 }
4509
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004510 /* Move pointer to ahead of SETCCXMODE<delimiter> */
4511 value = value + 11;
4512 /* Convert the value from ascii to integer */
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004513 ret = kstrtou8(value, 10, &eseMode);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004514 if (ret < 0)
4515 {
4516 /* If the input value is greater than max value of datatype, then also
4517 kstrtou8 fails */
4518 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4519 "%s: kstrtou8 failed range [%d - %d]", __func__,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004520 CFG_ESE_FEATURE_ENABLED_MIN,
4521 CFG_ESE_FEATURE_ENABLED_MAX);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004522 ret = -EINVAL;
4523 goto exit;
4524 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004525 if ((eseMode < CFG_ESE_FEATURE_ENABLED_MIN) ||
4526 (eseMode > CFG_ESE_FEATURE_ENABLED_MAX))
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004527 {
4528 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004529 "Ese mode value %d is out of range"
4530 " (Min: %d Max: %d)", eseMode,
4531 CFG_ESE_FEATURE_ENABLED_MIN,
4532 CFG_ESE_FEATURE_ENABLED_MAX);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004533 ret = -EINVAL;
4534 goto exit;
4535 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004536 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004537 "%s: Received Command to change ese mode = %d", __func__, eseMode);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004538
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004539 pHddCtx->cfg_ini->isEseIniFeatureEnabled = eseMode;
4540 sme_UpdateIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal), eseMode);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004541 }
4542#endif
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004543 else if (strncmp(command, "SETROAMSCANCONTROL", 18) == 0)
4544 {
4545 tANI_U8 *value = command;
4546 tANI_BOOLEAN roamScanControl = 0;
4547
4548 /* Move pointer to ahead of SETROAMSCANCONTROL<delimiter> */
4549 value = value + 19;
4550 /* Convert the value from ascii to integer */
4551 ret = kstrtou8(value, 10, &roamScanControl);
4552 if (ret < 0)
4553 {
4554 /* If the input value is greater than max value of datatype, then also
4555 kstrtou8 fails */
4556 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4557 "%s: kstrtou8 failed ", __func__);
4558 ret = -EINVAL;
4559 goto exit;
4560 }
4561
4562 if (0 != roamScanControl)
4563 {
4564 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4565 "roam scan control invalid value = %d",
4566 roamScanControl);
4567 ret = -EINVAL;
4568 goto exit;
4569 }
4570 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4571 "%s: Received Command to Set roam scan control = %d", __func__, roamScanControl);
4572
4573 sme_SetRoamScanControl((tHalHandle)(pHddCtx->hHal), roamScanControl);
4574 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004575#ifdef FEATURE_WLAN_OKC
4576 else if (strncmp(command, "SETOKCMODE", 10) == 0)
4577 {
4578 tANI_U8 *value = command;
4579 tANI_U8 okcMode = CFG_OKC_FEATURE_ENABLED_DEFAULT;
4580
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004581 /* Check if the features OKC/ESE/11R are supported simultaneously,
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07004582 then this operation is not permitted (return FAILURE) */
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004583 if (sme_getIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal)) &&
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07004584 hdd_is_okc_mode_enabled(pHddCtx) &&
4585 sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal)))
4586 {
4587 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004588 "%s: OKC/ESE/11R are supported simultaneously"
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07004589 " hence this operation is not permitted!", __func__);
4590 ret = -EPERM;
4591 goto exit;
4592 }
4593
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004594 /* Move pointer to ahead of SETOKCMODE<delimiter> */
4595 value = value + 11;
4596 /* Convert the value from ascii to integer */
4597 ret = kstrtou8(value, 10, &okcMode);
4598 if (ret < 0)
4599 {
4600 /* If the input value is greater than max value of datatype, then also
4601 kstrtou8 fails */
4602 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4603 "%s: kstrtou8 failed range [%d - %d]", __func__,
4604 CFG_OKC_FEATURE_ENABLED_MIN,
4605 CFG_OKC_FEATURE_ENABLED_MAX);
4606 ret = -EINVAL;
4607 goto exit;
4608 }
4609
4610 if ((okcMode < CFG_OKC_FEATURE_ENABLED_MIN) ||
4611 (okcMode > CFG_OKC_FEATURE_ENABLED_MAX))
4612 {
4613 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4614 "Okc mode value %d is out of range"
4615 " (Min: %d Max: %d)", okcMode,
4616 CFG_OKC_FEATURE_ENABLED_MIN,
4617 CFG_OKC_FEATURE_ENABLED_MAX);
4618 ret = -EINVAL;
4619 goto exit;
4620 }
4621
4622 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4623 "%s: Received Command to change okc mode = %d", __func__, okcMode);
4624
4625 pHddCtx->cfg_ini->isOkcIniFeatureEnabled = okcMode;
4626 }
Srinivas Girigowdaad34ca92013-10-22 10:54:29 -07004627#endif /* FEATURE_WLAN_OKC */
Mahesh A Saptasagarec7d1092015-04-02 13:41:34 +05304628 else if (strncmp(command, "GETROAMSCANCONTROL", 18) == 0)
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004629 {
4630 tANI_BOOLEAN roamScanControl = sme_GetRoamScanControl((tHalHandle)(pHddCtx->hHal));
4631 char extra[32];
4632 tANI_U8 len = 0;
4633
Sameer Thalappilb0a30232013-09-27 15:37:48 -07004634 len = scnprintf(extra, sizeof(extra), "%s %d",
4635 command, roamScanControl);
Ratnam Rachuri083ada82015-08-07 14:01:05 +05304636 len = VOS_MIN(priv_data.total_len, len + 1);
4637 if (copy_to_user(priv_data.buf, &extra, len)) {
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004638 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4639 "%s: failed to copy data to user buffer", __func__);
4640 ret = -EFAULT;
4641 goto exit;
4642 }
4643 }
Gopichand Nakkala227c7f32013-06-26 22:44:57 +05304644#ifdef WLAN_FEATURE_PACKET_FILTERING
4645 else if (strncmp(command, "ENABLE_PKTFILTER_IPV6", 21) == 0)
4646 {
4647 tANI_U8 filterType = 0;
4648 tANI_U8 *value = command;
4649
4650 /* Move pointer to ahead of ENABLE_PKTFILTER_IPV6<delimiter> */
4651 value = value + 22;
4652
4653 /* Convert the value from ascii to integer */
4654 ret = kstrtou8(value, 10, &filterType);
4655 if (ret < 0)
4656 {
4657 /* If the input value is greater than max value of datatype,
4658 * then also kstrtou8 fails
4659 */
4660 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4661 "%s: kstrtou8 failed range ", __func__);
4662 ret = -EINVAL;
4663 goto exit;
4664 }
4665
4666 if (filterType != 0 && filterType != 1)
4667 {
4668 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4669 "%s: Accepted Values are 0 and 1 ", __func__);
4670 ret = -EINVAL;
4671 goto exit;
4672 }
4673 wlan_hdd_setIPv6Filter(WLAN_HDD_GET_CTX(pAdapter), filterType,
4674 pAdapter->sessionId);
4675 }
4676#endif
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05304677 else if (strncmp(command, "BTCOEXMODE", 10) == 0 )
4678 {
Kiet Lamad161252014-07-22 11:23:32 -07004679 char *dhcpPhase;
Satyanarayana Dash1faea4f2014-09-22 16:21:04 +05304680 int ret;
4681
Kiet Lamad161252014-07-22 11:23:32 -07004682 dhcpPhase = command + 11;
4683 if ('1' == *dhcpPhase)
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05304684 {
Deepthi Gowribfd17132014-11-14 17:59:04 +05304685 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Kiet Lamad161252014-07-22 11:23:32 -07004686 FL("send DHCP START indication"));
c_hpothu9b781ba2013-12-30 20:57:45 +05304687
4688 pHddCtx->btCoexModeSet = TRUE;
Kiet Lamad161252014-07-22 11:23:32 -07004689
Satyanarayana Dash1faea4f2014-09-22 16:21:04 +05304690 ret = wlan_hdd_scan_abort(pAdapter);
4691 if (ret < 0)
4692 {
4693 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4694 FL("failed to abort existing scan %d"), ret);
4695 }
4696
Kiet Lamad161252014-07-22 11:23:32 -07004697 sme_DHCPStartInd(pHddCtx->hHal, pAdapter->device_mode,
4698 pAdapter->sessionId);
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05304699 }
Kiet Lamad161252014-07-22 11:23:32 -07004700 else if ('2' == *dhcpPhase)
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05304701 {
Deepthi Gowribfd17132014-11-14 17:59:04 +05304702 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Kiet Lamad161252014-07-22 11:23:32 -07004703 FL("send DHCP STOP indication"));
c_hpothu9b781ba2013-12-30 20:57:45 +05304704
4705 pHddCtx->btCoexModeSet = FALSE;
Kiet Lamad161252014-07-22 11:23:32 -07004706
4707 sme_DHCPStopInd(pHddCtx->hHal, pAdapter->device_mode,
4708 pAdapter->sessionId);
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05304709 }
4710 }
Jeff Johnsonf54df2c2013-07-24 11:43:39 -07004711 else if (strncmp(command, "SCAN-ACTIVE", 11) == 0)
4712 {
Abhishek Singh58749d62016-02-03 15:27:20 +05304713 hddLog(LOG1,
4714 FL("making default scan to ACTIVE"));
c_hpothudbefd3e2014-04-28 15:59:47 +05304715 pHddCtx->scan_info.scan_mode = eSIR_ACTIVE_SCAN;
Jeff Johnsonf54df2c2013-07-24 11:43:39 -07004716 }
4717 else if (strncmp(command, "SCAN-PASSIVE", 12) == 0)
4718 {
Abhishek Singh58749d62016-02-03 15:27:20 +05304719 hddLog(LOG1,
4720 FL("making default scan to PASSIVE"));
c_hpothudbefd3e2014-04-28 15:59:47 +05304721 pHddCtx->scan_info.scan_mode = eSIR_PASSIVE_SCAN;
Jeff Johnsonf54df2c2013-07-24 11:43:39 -07004722 }
Hanumantha Reddy Pothula212243c2013-08-01 17:28:31 +05304723 else if (strncmp(command, "GETDWELLTIME", 12) == 0)
4724 {
4725 hdd_config_t *pCfg = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
4726 char extra[32];
4727 tANI_U8 len = 0;
4728
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05304729 memset(extra, 0, sizeof(extra));
4730 ret = hdd_get_dwell_time(pCfg, command, extra, sizeof(extra), &len);
Ratnam Rachuri12d5d462015-08-07 14:10:23 +05304731 len = VOS_MIN(priv_data.total_len, len + 1);
4732 if (ret != 0 || copy_to_user(priv_data.buf, &extra, len)) {
Hanumantha Reddy Pothula212243c2013-08-01 17:28:31 +05304733 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4734 "%s: failed to copy data to user buffer", __func__);
4735 ret = -EFAULT;
4736 goto exit;
4737 }
4738 ret = len;
4739 }
4740 else if (strncmp(command, "SETDWELLTIME", 12) == 0)
4741 {
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05304742 ret = hdd_set_dwell_time(pAdapter, command);
Hanumantha Reddy Pothula212243c2013-08-01 17:28:31 +05304743 }
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07004744 else if ( strncasecmp(command, "MIRACAST", 8) == 0 )
4745 {
4746 tANI_U8 filterType = 0;
4747 tANI_U8 *value;
4748 value = command + 9;
4749
4750 /* Convert the value from ascii to integer */
4751 ret = kstrtou8(value, 10, &filterType);
4752 if (ret < 0)
4753 {
4754 /* If the input value is greater than max value of datatype,
4755 * then also kstrtou8 fails
4756 */
4757 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4758 "%s: kstrtou8 failed range ", __func__);
4759 ret = -EINVAL;
4760 goto exit;
4761 }
4762 if ((filterType < WLAN_HDD_DRIVER_MIRACAST_CFG_MIN_VAL ) ||
4763 (filterType > WLAN_HDD_DRIVER_MIRACAST_CFG_MAX_VAL))
4764 {
4765 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4766 "%s: Accepted Values are 0 to 2. 0-Disabled, 1-Source,"
4767 " 2-Sink ", __func__);
4768 ret = -EINVAL;
4769 goto exit;
4770 }
4771 //Filtertype value should be either 0-Disabled, 1-Source, 2-sink
4772 pHddCtx->drvr_miracast = filterType;
Kaushik, Sushant96122442014-10-21 16:40:18 +05304773 pScanInfo = &pHddCtx->scan_info;
4774 if (filterType && pScanInfo != NULL &&
4775 pHddCtx->scan_info.mScanPending)
4776 {
4777 /*Miracast Session started. Abort Scan */
4778 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4779 "%s, Aborting Scan For Miracast",__func__);
4780 hdd_abort_mac_scan(pHddCtx, pScanInfo->sessionId,
4781 eCSR_SCAN_ABORT_DEFAULT);
4782 }
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07004783 hdd_tx_rx_pkt_cnt_stat_timer_handler(pHddCtx);
Ganesh Kondabattini8f6e3b32014-08-25 16:07:54 +05304784 sme_SetMiracastMode(pHddCtx->hHal, pHddCtx->drvr_miracast);
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07004785 }
Leo Chang614d2072013-08-22 14:59:44 -07004786 else if (strncmp(command, "SETMCRATE", 9) == 0)
4787 {
Leo Chang614d2072013-08-22 14:59:44 -07004788 tANI_U8 *value = command;
4789 int targetRate;
Leo Chang1f98cbd2013-10-17 15:03:52 -07004790 tSirRateUpdateInd *rateUpdate;
4791 eHalStatus status;
Leo Chang614d2072013-08-22 14:59:44 -07004792
4793 /* Only valid for SAP mode */
4794 if (WLAN_HDD_SOFTAP != pAdapter->device_mode)
4795 {
4796 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4797 "%s: SAP mode is not running", __func__);
4798 ret = -EFAULT;
4799 goto exit;
4800 }
4801
4802 /* Move pointer to ahead of SETMCRATE<delimiter> */
4803 /* input value is in units of hundred kbps */
4804 value = value + 10;
4805 /* Convert the value from ascii to integer, decimal base */
4806 ret = kstrtouint(value, 10, &targetRate);
4807
Leo Chang1f98cbd2013-10-17 15:03:52 -07004808 rateUpdate = (tSirRateUpdateInd *)vos_mem_malloc(sizeof(tSirRateUpdateInd));
4809 if (NULL == rateUpdate)
Leo Chang614d2072013-08-22 14:59:44 -07004810 {
Leo Chang1f98cbd2013-10-17 15:03:52 -07004811 hddLog(VOS_TRACE_LEVEL_ERROR,
4812 "%s: SETMCRATE indication alloc fail", __func__);
4813 ret = -EFAULT;
4814 goto exit;
4815 }
4816 vos_mem_zero(rateUpdate, sizeof(tSirRateUpdateInd ));
4817
4818 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4819 "MC Target rate %d", targetRate);
4820 /* Ignore unicast */
4821 rateUpdate->ucastDataRate = -1;
4822 rateUpdate->mcastDataRate24GHz = targetRate;
4823 rateUpdate->mcastDataRate5GHz = targetRate;
4824 rateUpdate->mcastDataRate24GHzTxFlag = 0;
4825 rateUpdate->mcastDataRate5GHzTxFlag = 0;
4826 status = sme_SendRateUpdateInd(pHddCtx->hHal, rateUpdate);
4827 if (eHAL_STATUS_SUCCESS != status)
4828 {
4829 hddLog(VOS_TRACE_LEVEL_ERROR,
4830 "%s: SET_MC_RATE failed", __func__);
4831 vos_mem_free(rateUpdate);
4832 ret = -EFAULT;
4833 goto exit;
Leo Chang614d2072013-08-22 14:59:44 -07004834 }
4835 }
Rajeev79dbe4c2013-10-05 11:03:42 +05304836#ifdef FEATURE_WLAN_BATCH_SCAN
Rajeev Kumar8b373292014-01-08 20:36:55 -08004837 else if (strncmp(command, "WLS_BATCHING", 12) == 0)
Rajeev79dbe4c2013-10-05 11:03:42 +05304838 {
Rajeev Kumar8b373292014-01-08 20:36:55 -08004839 ret = hdd_handle_batch_scan_ioctl(pAdapter, &priv_data, command);
Rajeev79dbe4c2013-10-05 11:03:42 +05304840 }
4841#endif
Abhishek Singh00b71972016-01-07 10:51:04 +05304842#ifdef WLAN_FEATURE_RMC
4843 else if ((strncasecmp(command, "SETIBSSBEACONOUIDATA", 20) == 0) &&
4844 (WLAN_HDD_IBSS == pAdapter->device_mode))
4845 {
4846 int i = 0;
4847 tANI_U8 *ibss_ie;
4848 tANI_U32 command_len;
4849 tANI_U8 *value = command;
4850 tHalHandle hHal = pHddCtx->hHal;
4851 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
4852 tANI_U32 ibss_ie_length;
4853 tANI_U32 len, present;
4854 tANI_U8 *addIE;
4855 tANI_U8 *addIEData;
4856
4857 hddLog(LOG1,
4858 FL(" received command %s"),((char *) value));
4859 /* validate argument of command */
4860 if (strlen(value) <= 21)
4861 {
4862 hddLog(LOGE,
4863 FL("No arguements in command length %zu"), strlen(value));
4864 ret = -EFAULT;
4865 goto exit;
4866 }
4867
4868 /* moving to arguments of commands */
4869 value = value + 21;
4870 command_len = strlen(value);
4871
4872 /* oui_data can't be less than 3 bytes */
4873 if (command_len <= (2 * WLAN_HDD_IBSS_MIN_OUI_DATA_LENGTH))
4874 {
4875 hddLog(LOGE,
4876 FL("Invalid SETIBSSBEACONOUIDATA command length %d"),
4877 command_len);
4878 ret = -EFAULT;
4879 goto exit;
4880 }
4881 ibss_ie = vos_mem_malloc(command_len);
4882 if (!ibss_ie) {
4883 hddLog(LOGE,
4884 FL("Could not allocate memory for command length %d"),
4885 command_len);
4886 ret = -ENOMEM;
4887 goto exit;
4888 }
4889 vos_mem_zero(ibss_ie, command_len);
4890
4891 ibss_ie_length = hdd_parse_set_ibss_oui_data_command(value, ibss_ie,
4892 command_len);
4893 if (ibss_ie_length < (2 * WLAN_HDD_IBSS_MIN_OUI_DATA_LENGTH)) {
4894 hddLog(LOGE, FL("Could not parse command %s return length %d"),
4895 value, ibss_ie_length);
4896 ret = -EFAULT;
4897 vos_mem_free(ibss_ie);
4898 goto exit;
4899 }
4900
4901 hddLog(LOG1, FL("ibss_ie length %d ibss_ie:"), ibss_ie_length);
4902 while (i < ibss_ie_length)
4903 hddLog(LOG1, FL("0x%x"), ibss_ie[i++]);
4904
4905 /* Populate Vendor IE in Beacon */
4906 if ((ccmCfgGetInt(hHal,
4907 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG,
4908 &present)) != eHAL_STATUS_SUCCESS)
4909 {
4910 hddLog(LOGE,
4911 FL("unable to ftch WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG"));
4912 ret = -EFAULT;
4913 vos_mem_free(ibss_ie);
4914 goto exit;
4915 }
4916
4917 addIE = vos_mem_malloc(WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA_LEN);
4918 if (!addIE) {
4919 hddLog(LOGE,
4920 FL("Could not allocate memory for command length %d"),
4921 command_len);
4922 vos_mem_free(ibss_ie);
4923 ret = -ENOMEM;
4924 goto exit;
4925 }
4926 vos_mem_zero(addIE, WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA_LEN);
4927
4928 if (present)
4929 {
4930 if ((wlan_cfgGetStrLen(pMac,
4931 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, &len)) != eSIR_SUCCESS)
4932 {
4933 hddLog(LOGE,
4934 FL("unable to fetch WNI_CFG_PROBE_RSP_BCN_ADDNIE_LEN"));
4935 ret = -EFAULT;
4936 vos_mem_free(ibss_ie);
4937 vos_mem_free(addIE);
4938 goto exit;
4939 }
4940
4941 if (len <= WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA_LEN && len &&
4942 ((len + ibss_ie_length) <=
4943 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA_LEN))
4944 {
4945 if ((ccmCfgGetStr(hHal,
4946 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, addIE, &len))
4947 != eHAL_STATUS_SUCCESS)
4948 {
4949 hddLog(LOGE,
4950 FL("unable to fetch WNI_PROBE_RSP_BCN_ADDNIE_DATA"));
4951 ret = -EFAULT;
4952 vos_mem_free(ibss_ie);
4953 vos_mem_free(addIE);
4954 goto exit;
4955 }
4956 else
4957 {
4958 /* Curruntly only WPA IE is added before Vendor IE
4959 * so we can blindly place the Vendor IE after WPA
4960 * IE. If no WPA IE found replace all with Vendor IE.
4961 */
4962 len = hdd_find_ibss_wpa_ie_pos(addIE, len);
4963 }
4964 }
4965 else
4966 {
4967 hddLog(LOGE,
4968 FL("IE len exceed limit len %d,ibss_ie_length %d "),
4969 len, ibss_ie_length);
4970 ret = -EFAULT;
4971 vos_mem_free(addIE);
4972 vos_mem_free(ibss_ie);
4973 goto exit;
4974 }
4975 }
4976 else {
4977 len = 0;
4978 }
4979
4980 vos_mem_copy (addIE + len , ibss_ie, ibss_ie_length);
4981 len += ibss_ie_length;
4982
4983 if (ccmCfgSetStr(hHal,
4984 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, addIE, len, NULL,
4985 eANI_BOOLEAN_FALSE) != eHAL_STATUS_SUCCESS)
4986 {
4987 hddLog(LOGE,
4988 FL("unable to set WNI_CFG_PRBE_RSP_BCN_ADDNIE_DATA"));
4989 ret = -EFAULT;
4990 vos_mem_free(ibss_ie);
4991 vos_mem_free(addIE);
4992 goto exit;
4993 }
4994 vos_mem_free(addIE);
4995 if (ccmCfgSetInt(hHal,
4996 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 1,NULL,
4997 eANI_BOOLEAN_FALSE) != eHAL_STATUS_SUCCESS)
4998 {
4999 hddLog(LOGE,
5000 FL("unble to set WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG"));
5001 ret = -EFAULT;
5002 vos_mem_free(ibss_ie);
5003 goto exit;
5004 }
5005
5006 /* Populate Vendor IE in probe resp */
5007 if ((ccmCfgGetInt(hHal,
5008 WNI_CFG_PROBE_RSP_ADDNIE_FLAG,
5009 &present)) != eHAL_STATUS_SUCCESS)
5010 {
5011 hddLog(LOGE,
5012 FL("unable to fetch WNI_CFG_PROBE_RSP_ADDNIE_FLAG"));
5013 ret = -EFAULT;
5014 vos_mem_free(ibss_ie);
5015 goto exit;
5016 }
5017
5018 addIEData = vos_mem_malloc(WNI_CFG_PROBE_RSP_ADDNIE_DATA1_LEN);
5019 if (!addIEData) {
5020 hddLog(LOGE,
5021 FL("Could not allocate memory for command length %d"),
5022 command_len);
5023 vos_mem_free(ibss_ie);
5024 ret = -ENOMEM;
5025 goto exit;
5026 }
5027 vos_mem_zero(addIEData, WNI_CFG_PROBE_RSP_ADDNIE_DATA1_LEN);
5028
5029 if (present) {
5030 if (eSIR_SUCCESS != wlan_cfgGetStrLen(pMac,
5031 WNI_CFG_PROBE_RSP_ADDNIE_DATA1, &len)) {
5032 hddLog(LOGE,
5033 FL("unable to fetch WNI_CFG_PROBE_RSP_ADDNIE_DATA1"));
5034 ret = -EFAULT;
5035 vos_mem_free(ibss_ie);
5036 vos_mem_free(addIEData);
5037 goto exit;
5038 }
5039 if (len < WNI_CFG_PROBE_RSP_ADDNIE_DATA1_LEN && len &&
5040 (ibss_ie_length + len) <=
5041 WNI_CFG_PROBE_RSP_ADDNIE_DATA1_LEN) {
5042
5043 if ((ccmCfgGetStr(hHal,
5044 WNI_CFG_PROBE_RSP_ADDNIE_DATA1, addIEData, &len))
5045 != eHAL_STATUS_SUCCESS) {
5046 hddLog(LOGE,
5047 FL("unable fetch WNI_CFG_PROBE_RSP_ADDNIE_DATA1"));
5048 ret = -EFAULT;
5049 vos_mem_free(ibss_ie);
5050 vos_mem_free(addIEData);
5051 goto exit;
5052 }
5053 else {
5054 /* Curruntly only WPA IE is added before Vendor IE
5055 * so we can blindly place the Vendor IE after WPA
5056 * IE. If no WPA IE found replace all with Vendor IE.
5057 */
5058 len = hdd_find_ibss_wpa_ie_pos(addIEData, len);
5059 }
5060 }
5061 else
5062 {
5063 hddLog(LOGE,
5064 FL("IE len exceed limit len %d,ibss_ie_length %d "),
5065 len, ibss_ie_length);
5066 ret = -EFAULT;
5067 vos_mem_free(addIEData);
5068 vos_mem_free(ibss_ie);
5069 goto exit;
5070 }
5071 } /* probe rsp ADD IE present */
5072 else {
5073 /* probe rsp add IE is not present */
5074 len = 0;
5075 }
5076
5077 vos_mem_copy(addIEData +len , ibss_ie, ibss_ie_length);
5078 len += ibss_ie_length;
5079
5080 vos_mem_free(ibss_ie);
5081
5082 if (ccmCfgSetStr(hHal,
5083 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,
5084 (tANI_U8*)(addIEData),
5085 len, NULL,
5086 eANI_BOOLEAN_FALSE)
5087 == eHAL_STATUS_FAILURE) {
5088 hddLog(LOGE,
5089 FL("unable to copy to WNI_CFG_PROBE_RSP_ADDNIE_DATA1"));
5090 ret = -EFAULT;
5091 vos_mem_free(addIEData);
5092 goto exit;
5093 }
5094 vos_mem_free(addIEData);
5095 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
5096 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 1,NULL,
5097 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
5098 {
5099 hddLog(LOGE,
5100 FL("unable to copy WNI_CFG_PROBE_RSP_ADDNIE_FLAG"));
5101 ret = -EFAULT;
5102 goto exit;
5103 }
5104 }
5105 else if (strncasecmp(command, "SETRMCENABLE", 12) == 0)
5106 {
5107 tANI_U8 *value = command;
5108 tANI_U8 ucRmcEnable = 0;
5109 int status;
5110
5111 if ((WLAN_HDD_IBSS != pAdapter->device_mode) &&
5112 (WLAN_HDD_SOFTAP != pAdapter->device_mode))
5113 {
5114 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5115 "Received SETRMCENABLE command in invalid mode %d "
5116 "SETRMCENABLE command is only allowed in IBSS or SOFTAP mode",
5117 pAdapter->device_mode);
5118 ret = -EINVAL;
5119 goto exit;
5120 }
5121
5122 status = hdd_parse_setrmcenable_command(value, &ucRmcEnable);
5123 if (status)
5124 {
5125 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5126 "Invalid SETRMCENABLE command ");
5127 ret = -EINVAL;
5128 goto exit;
5129 }
5130
5131 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
5132 "%s: ucRmcEnable %d ", __func__, ucRmcEnable);
5133
5134 if (TRUE == ucRmcEnable)
5135 {
5136 status = sme_EnableRMC( (tHalHandle)(pHddCtx->hHal),
5137 pAdapter->sessionId );
5138 }
5139 else if(FALSE == ucRmcEnable)
5140 {
5141 status = sme_DisableRMC( (tHalHandle)(pHddCtx->hHal),
5142 pAdapter->sessionId );
5143 }
5144 else
5145 {
5146 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5147 "Invalid SETRMCENABLE command %d", ucRmcEnable);
5148 ret = -EINVAL;
5149 goto exit;
5150 }
5151
5152 if (VOS_STATUS_SUCCESS != status)
5153 {
5154 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5155 "%s: SETRMC %d failed status %d", __func__, ucRmcEnable,
5156 status);
5157 ret = -EINVAL;
5158 goto exit;
5159 }
5160 }
5161 else if (strncasecmp(command, "SETRMCACTIONPERIOD", 18) == 0)
5162 {
5163 tANI_U8 *value = command;
5164 tANI_U32 uActionPeriod = 0;
5165 int status;
5166
5167 if ((WLAN_HDD_IBSS != pAdapter->device_mode) &&
5168 (WLAN_HDD_SOFTAP != pAdapter->device_mode))
5169 {
5170 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5171 "Received SETRMC command in invalid mode %d "
5172 "SETRMC command is only allowed in IBSS or SOFTAP mode",
5173 pAdapter->device_mode);
5174 ret = -EINVAL;
5175 goto exit;
5176 }
5177
5178 status = hdd_parse_setrmcactionperiod_command(value, &uActionPeriod);
5179 if (status)
5180 {
5181 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5182 "Invalid SETRMCACTIONPERIOD command ");
5183 ret = -EINVAL;
5184 goto exit;
5185 }
5186
5187 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
5188 "%s: uActionPeriod %d ", __func__, uActionPeriod);
5189
5190 if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_RMC_ACTION_PERIOD_FREQUENCY,
5191 uActionPeriod, NULL, eANI_BOOLEAN_FALSE))
5192 {
5193 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5194 "%s: Could not set SETRMCACTIONPERIOD %d", __func__, uActionPeriod);
5195 ret = -EINVAL;
5196 goto exit;
5197 }
5198
5199 }
5200 else if (strncasecmp(command, "GETIBSSPEERINFOALL", 18) == 0)
5201 {
5202 /* Peer Info All Command */
5203 int status = eHAL_STATUS_SUCCESS;
5204 hdd_station_ctx_t *pHddStaCtx = NULL;
5205 char *extra = NULL;
5206 int idx = 0, length = 0;
5207 v_MACADDR_t *macAddr;
5208 v_U32_t txRateMbps = 0, numOfBytestoPrint = 0;
5209
5210 if (WLAN_HDD_IBSS == pAdapter->device_mode)
5211 {
5212 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
5213 }
5214 else
5215 {
5216 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
5217 "%s: pAdapter is not valid for this device mode",
5218 __func__);
5219 ret = -EINVAL;
5220 goto exit;
5221 }
5222
5223 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
5224 "%s: Received GETIBSSPEERINFOALL Command", __func__);
5225
5226
5227 /* Handle the command */
5228 status = hdd_cfg80211_get_ibss_peer_info_all(pAdapter);
5229 if (VOS_STATUS_SUCCESS == status)
5230 {
5231 /* The variable extra needed to be allocated on the heap since
5232 * amount of memory required to copy the data for 32 devices
5233 * exceeds the size of 1024 bytes of default stack size. On
5234 * 64 bit devices, the default max stack size of 2048 bytes
5235 */
5236 extra = kmalloc(WLAN_MAX_BUF_SIZE, GFP_KERNEL);
5237
5238 if (NULL == extra)
5239 {
5240 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5241 "%s:kmalloc failed", __func__);
5242 ret = -EINVAL;
5243 goto exit;
5244 }
5245
5246 /* Copy number of stations */
5247 length = scnprintf( extra, WLAN_MAX_BUF_SIZE, "%d ",
5248 pHddStaCtx->ibss_peer_info.numIBSSPeers);
5249 numOfBytestoPrint = length;
5250 for (idx = 0; idx < pHddStaCtx->ibss_peer_info.numIBSSPeers; idx++)
5251 {
5252 macAddr =
5253 hdd_wlan_get_ibss_mac_addr_from_staid(pAdapter,
5254 pHddStaCtx->ibss_peer_info.ibssPeerList[idx].staIdx);
5255 if (NULL != macAddr)
5256 {
5257 txRateMbps =
5258 ((pHddStaCtx->ibss_peer_info.ibssPeerList[idx].txRate)*500*1000)/1000000;
5259
5260 length += scnprintf( (extra + length), WLAN_MAX_BUF_SIZE - length,
5261 "%02x:%02x:%02x:%02x:%02x:%02x %d %d ",
5262 macAddr->bytes[0], macAddr->bytes[1], macAddr->bytes[2],
5263 macAddr->bytes[3], macAddr->bytes[4], macAddr->bytes[5],
5264 (int)txRateMbps,
5265 (int)pHddStaCtx->ibss_peer_info.ibssPeerList[idx].rssi);
5266 }
5267 else
5268 {
5269 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5270 "%s: MAC ADDR is NULL for staIdx: %d", __func__,
5271 pHddStaCtx->ibss_peer_info.ibssPeerList[idx].staIdx);
5272 }
5273
5274 /*
5275 * VOS_TRACE() macro has limitation of 512 bytes for the print
5276 * buffer. Hence printing the data in two chunks. The first chunk
5277 * will have the data for 16 devices and the second chunk will
5278 * have the rest.
5279 */
5280 if (idx < NUM_OF_STA_DATA_TO_PRINT)
5281 {
5282 numOfBytestoPrint = length;
5283 }
5284 }
5285
5286 /*
5287 * Copy the data back into buffer, if the data to copy is
5288 * morethan 512 bytes than we will split the data and do
5289 * it in two shots
5290 */
5291 if (copy_to_user(priv_data.buf, extra, numOfBytestoPrint))
5292 {
5293 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5294 "%s: Copy into user data buffer failed ", __func__);
5295 ret = -EFAULT;
5296 kfree(extra);
5297 goto exit;
5298 }
5299 priv_data.buf[numOfBytestoPrint] = '\0';
5300 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_MED,
5301 "%s", priv_data.buf);
5302
5303 if (length > numOfBytestoPrint)
5304 {
5305 if (copy_to_user(priv_data.buf + numOfBytestoPrint,
5306 extra + numOfBytestoPrint,
5307 length - numOfBytestoPrint + 1))
5308 {
5309 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5310 "%s: Copy into user data buffer failed ", __func__);
5311 ret = -EFAULT;
5312 kfree(extra);
5313 goto exit;
5314 }
5315 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_MED,
5316 "%s", &priv_data.buf[numOfBytestoPrint]);
5317 }
5318
5319 /* Free temporary buffer */
5320 kfree(extra);
5321 }
5322
5323 else
5324 {
5325 /* Command failed, log error */
5326 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5327 "%s: GETIBSSPEERINFOALL command failed with status code %d",
5328 __func__, status);
5329 ret = -EINVAL;
5330 goto exit;
5331 }
5332 ret = 0;
5333 }
5334 else if(strncasecmp(command, "GETIBSSPEERINFO", 15) == 0)
5335 {
5336 /* Peer Info <Peer Addr> command */
5337 tANI_U8 *value = command;
5338 VOS_STATUS status;
5339 hdd_station_ctx_t *pHddStaCtx = NULL;
5340 char extra[128] = { 0 };
5341 v_U32_t length = 0;
5342 v_U8_t staIdx = 0;
5343 v_U32_t txRateMbps = 0;
5344 v_MACADDR_t peerMacAddr;
5345
5346 if (WLAN_HDD_IBSS == pAdapter->device_mode)
5347 {
5348 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
5349 }
5350 else
5351 {
5352 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
5353 "%s: pAdapter is not valid for this device mode",
5354 __func__);
5355 ret = -EINVAL;
5356 goto exit;
5357 }
5358
5359 /* if there are no peers, no need to continue with the command */
5360 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
5361 "%s: Received GETIBSSPEERINFO Command", __func__);
5362
5363 if (eConnectionState_IbssConnected != pHddStaCtx->conn_info.connState)
5364 {
5365 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
5366 "%s:No IBSS Peers coalesced", __func__);
5367 ret = -EINVAL;
5368 goto exit;
5369 }
5370
5371 /* Parse the incoming command buffer */
5372 status = hdd_parse_get_ibss_peer_info(value, &peerMacAddr);
5373 if (VOS_STATUS_SUCCESS != status)
5374 {
5375 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5376 "%s: Invalid GETIBSSPEERINFO command", __func__);
5377 ret = -EINVAL;
5378 goto exit;
5379 }
5380
5381 /* Get station index for the peer mac address */
5382 hdd_Ibss_GetStaId(pHddStaCtx, &peerMacAddr, &staIdx);
5383
5384 if (staIdx > HDD_MAX_NUM_IBSS_STA)
5385 {
5386 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5387 "%s: Invalid StaIdx %d returned", __func__, staIdx);
5388 ret = -EINVAL;
5389 goto exit;
5390 }
5391
5392 /* Handle the command */
5393 status = hdd_cfg80211_get_ibss_peer_info(pAdapter, staIdx);
5394 if (VOS_STATUS_SUCCESS == status)
5395 {
5396 v_U32_t txRate = pHddStaCtx->ibss_peer_info.ibssPeerList[0].txRate;
5397 txRateMbps = (txRate * 500 * 1000)/1000000;
5398
5399 length = scnprintf( extra, sizeof(extra), "%d %d", (int)txRateMbps,
5400 (int)pHddStaCtx->ibss_peer_info.ibssPeerList[0].rssi);
5401
5402 /* Copy the data back into buffer */
5403 if (copy_to_user(priv_data.buf, &extra, length+ 1))
5404 {
5405 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5406 "%s: copy data to user buffer failed GETIBSSPEERINFO command",
5407 __func__);
5408 ret = -EFAULT;
5409 goto exit;
5410 }
5411 }
5412 else
5413 {
5414 /* Command failed, log error */
5415 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5416 "%s: GETIBSSPEERINFO command failed with status code %d",
5417 __func__, status);
5418 ret = -EINVAL;
5419 goto exit;
5420 }
5421
5422 /* Success ! */
5423 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_MED,
5424 "%s", priv_data.buf);
5425 ret = 0;
5426 }
5427 else if (strncasecmp(command, "SETRMCTXRATE", 12) == 0)
5428 {
5429 tANI_U8 *value = command;
5430 tANI_U32 uRate = 0;
5431 tTxrateinfoflags txFlags = 0;
5432 tSirRateUpdateInd *rateUpdateParams;
5433 int status;
5434
5435 if ((WLAN_HDD_IBSS != pAdapter->device_mode) &&
5436 (WLAN_HDD_SOFTAP != pAdapter->device_mode))
5437 {
5438 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5439 "Received SETRMCTXRATE command in invalid mode %d "
5440 "SETRMC command is only allowed in IBSS or SOFTAP mode",
5441 pAdapter->device_mode);
5442 ret = -EINVAL;
5443 goto exit;
5444 }
5445
5446 status = hdd_parse_setrmcrate_command(value, &uRate, &txFlags);
5447 if (status)
5448 {
5449 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5450 "Invalid SETRMCTXRATE command ");
5451 ret = -EINVAL;
5452 goto exit;
5453 }
5454
5455 rateUpdateParams = vos_mem_malloc(sizeof(tSirRateUpdateInd));
5456 if (NULL == rateUpdateParams)
5457 {
5458 ret = -EINVAL;
5459 goto exit;
5460 }
5461
5462 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
5463 "%s: uRate %d ", __func__, uRate);
5464
5465 vos_mem_zero(rateUpdateParams, sizeof(tSirRateUpdateInd ));
5466
5467 /* -1 implies ignore this param */
5468 rateUpdateParams->ucastDataRate = -1;
5469
5470 /*
5471 * Fill the user specifieed RMC rate param
5472 * and the derived tx flags.
5473 */
5474 rateUpdateParams->rmcDataRate = uRate;
5475 rateUpdateParams->rmcDataRateTxFlag = txFlags;
5476
5477 status = sme_SendRateUpdateInd((tHalHandle)(pHddCtx->hHal), rateUpdateParams);
5478 }
5479 else if (strncasecmp(command, "SETIBSSTXFAILEVENT", 18) == 0 )
5480 {
5481 char *value;
5482 tANI_U8 tx_fail_count = 0;
5483 tANI_U16 pid = 0;
5484
5485 value = command;
5486
5487 ret = hdd_ParseIBSSTXFailEventParams(value, &tx_fail_count, &pid);
5488
5489 if (0 != ret)
5490 {
5491 hddLog(VOS_TRACE_LEVEL_INFO,
5492 "%s: Failed to parse SETIBSSTXFAILEVENT arguments",
5493 __func__);
5494 goto exit;
5495 }
5496
5497 hddLog(VOS_TRACE_LEVEL_INFO, "%s: tx_fail_cnt=%hhu, pid=%hu",
5498 __func__, tx_fail_count, pid);
5499
5500 if (0 == tx_fail_count)
5501 {
5502 // Disable TX Fail Indication
5503 if (eHAL_STATUS_SUCCESS ==
5504 sme_TXFailMonitorStartStopInd(pHddCtx->hHal,
5505 tx_fail_count,
5506 NULL))
5507 {
5508 cesium_pid = 0;
5509 }
5510 else
5511 {
5512 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5513 "%s: failed to disable TX Fail Event ", __func__);
5514 ret = -EINVAL;
5515 }
5516 }
5517 else
5518 {
5519 if (eHAL_STATUS_SUCCESS ==
5520 sme_TXFailMonitorStartStopInd(pHddCtx->hHal,
5521 tx_fail_count,
5522 (void*)hdd_tx_fail_ind_callback))
5523 {
5524 cesium_pid = pid;
5525 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
5526 "%s: Registered Cesium pid %u", __func__,
5527 cesium_pid);
5528 }
5529 else
5530 {
5531 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5532 "%s: Failed to enable TX Fail Monitoring", __func__);
5533 ret = -EINVAL;
5534 }
5535 }
5536 }
5537
5538#endif /* WLAN_FEATURE_RMC */
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005539#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07005540 else if (strncmp(command, "SETCCXROAMSCANCHANNELS", 22) == 0)
5541 {
5542 tANI_U8 *value = command;
5543 tANI_U8 ChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
5544 tANI_U8 numChannels = 0;
5545 eHalStatus status = eHAL_STATUS_SUCCESS;
5546
5547 status = hdd_parse_channellist(value, ChannelList, &numChannels);
5548 if (eHAL_STATUS_SUCCESS != status)
5549 {
5550 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5551 "%s: Failed to parse channel list information", __func__);
5552 ret = -EINVAL;
5553 goto exit;
5554 }
5555
5556 if (numChannels > WNI_CFG_VALID_CHANNEL_LIST_LEN)
5557 {
5558 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5559 "%s: number of channels (%d) supported exceeded max (%d)", __func__,
5560 numChannels, WNI_CFG_VALID_CHANNEL_LIST_LEN);
5561 ret = -EINVAL;
5562 goto exit;
5563 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005564 status = sme_SetEseRoamScanChannelList((tHalHandle)(pHddCtx->hHal),
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07005565 ChannelList,
5566 numChannels);
5567 if (eHAL_STATUS_SUCCESS != status)
5568 {
5569 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5570 "%s: Failed to update channel list information", __func__);
5571 ret = -EINVAL;
5572 goto exit;
5573 }
5574 }
5575 else if (strncmp(command, "GETTSMSTATS", 11) == 0)
5576 {
5577 tANI_U8 *value = command;
5578 char extra[128] = {0};
5579 int len = 0;
5580 tANI_U8 tid = 0;
5581 hdd_station_ctx_t *pHddStaCtx = NULL;
5582 tAniTrafStrmMetrics tsmMetrics;
5583 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
5584
5585 /* if not associated, return error */
5586 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
5587 {
5588 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "%s:Not associated!",__func__);
5589 ret = -EINVAL;
5590 goto exit;
5591 }
5592
5593 /* Move pointer to ahead of GETTSMSTATS<delimiter> */
5594 value = value + 12;
5595 /* Convert the value from ascii to integer */
5596 ret = kstrtou8(value, 10, &tid);
5597 if (ret < 0)
5598 {
5599 /* If the input value is greater than max value of datatype, then also
5600 kstrtou8 fails */
5601 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5602 "%s: kstrtou8 failed range [%d - %d]", __func__,
5603 TID_MIN_VALUE,
5604 TID_MAX_VALUE);
5605 ret = -EINVAL;
5606 goto exit;
5607 }
5608
5609 if ((tid < TID_MIN_VALUE) || (tid > TID_MAX_VALUE))
5610 {
5611 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5612 "tid value %d is out of range"
5613 " (Min: %d Max: %d)", tid,
5614 TID_MIN_VALUE,
5615 TID_MAX_VALUE);
5616 ret = -EINVAL;
5617 goto exit;
5618 }
5619
5620 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
5621 "%s: Received Command to get tsm stats tid = %d", __func__, tid);
5622
5623 if (VOS_STATUS_SUCCESS != hdd_get_tsm_stats(pAdapter, tid, &tsmMetrics))
5624 {
5625 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5626 "%s: failed to get tsm stats", __func__);
5627 ret = -EFAULT;
5628 goto exit;
5629 }
5630
5631 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
5632 "UplinkPktQueueDly(%d)\n"
5633 "UplinkPktQueueDlyHist[0](%d)\n"
5634 "UplinkPktQueueDlyHist[1](%d)\n"
5635 "UplinkPktQueueDlyHist[2](%d)\n"
5636 "UplinkPktQueueDlyHist[3](%d)\n"
Arun Kumar Khandavallie8768212014-02-17 16:43:34 +05305637 "UplinkPktTxDly(%u)\n"
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07005638 "UplinkPktLoss(%d)\n"
5639 "UplinkPktCount(%d)\n"
5640 "RoamingCount(%d)\n"
5641 "RoamingDly(%d)", tsmMetrics.UplinkPktQueueDly,
5642 tsmMetrics.UplinkPktQueueDlyHist[0],
5643 tsmMetrics.UplinkPktQueueDlyHist[1],
5644 tsmMetrics.UplinkPktQueueDlyHist[2],
5645 tsmMetrics.UplinkPktQueueDlyHist[3],
5646 tsmMetrics.UplinkPktTxDly, tsmMetrics.UplinkPktLoss,
5647 tsmMetrics.UplinkPktCount, tsmMetrics.RoamingCount, tsmMetrics.RoamingDly);
5648
5649 /* Output TSM stats is of the format
5650 GETTSMSTATS [PktQueueDly] [PktQueueDlyHist[0]]:[PktQueueDlyHist[1]] ...[RoamingDly]
5651 eg., GETTSMSTATS 10 1:0:0:161 20 1 17 8 39800 */
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08005652 len = scnprintf(extra, sizeof(extra), "%s %d %d:%d:%d:%d %u %d %d %d %d", command,
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07005653 tsmMetrics.UplinkPktQueueDly, tsmMetrics.UplinkPktQueueDlyHist[0],
5654 tsmMetrics.UplinkPktQueueDlyHist[1], tsmMetrics.UplinkPktQueueDlyHist[2],
5655 tsmMetrics.UplinkPktQueueDlyHist[3], tsmMetrics.UplinkPktTxDly,
5656 tsmMetrics.UplinkPktLoss, tsmMetrics.UplinkPktCount, tsmMetrics.RoamingCount,
5657 tsmMetrics.RoamingDly);
5658
Ratnam Rachurid53009c2015-08-07 13:59:00 +05305659 len = VOS_MIN(priv_data.total_len, len + 1);
5660 if (copy_to_user(priv_data.buf, &extra, len)) {
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07005661 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5662 "%s: failed to copy data to user buffer", __func__);
5663 ret = -EFAULT;
5664 goto exit;
5665 }
5666 }
5667 else if (strncmp(command, "SETCCKMIE", 9) == 0)
5668 {
5669 tANI_U8 *value = command;
5670 tANI_U8 *cckmIe = NULL;
5671 tANI_U8 cckmIeLen = 0;
5672 eHalStatus status = eHAL_STATUS_SUCCESS;
5673
5674 status = hdd_parse_get_cckm_ie(value, &cckmIe, &cckmIeLen);
5675 if (eHAL_STATUS_SUCCESS != status)
5676 {
5677 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5678 "%s: Failed to parse cckm ie data", __func__);
5679 ret = -EINVAL;
5680 goto exit;
5681 }
5682
5683 if (cckmIeLen > DOT11F_IE_RSN_MAX_LEN)
5684 {
5685 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5686 "%s: CCKM Ie input length is more than max[%d]", __func__,
5687 DOT11F_IE_RSN_MAX_LEN);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08005688 vos_mem_free(cckmIe);
5689 cckmIe = NULL;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07005690 ret = -EINVAL;
5691 goto exit;
5692 }
5693 sme_SetCCKMIe((tHalHandle)(pHddCtx->hHal), pAdapter->sessionId, cckmIe, cckmIeLen);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08005694 vos_mem_free(cckmIe);
5695 cckmIe = NULL;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07005696 }
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08005697 else if (strncmp(command, "CCXBEACONREQ", 12) == 0)
5698 {
5699 tANI_U8 *value = command;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005700 tCsrEseBeaconReq eseBcnReq;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08005701 eHalStatus status = eHAL_STATUS_SUCCESS;
Srinivas Girigowda0c6d7fe2014-05-28 18:18:10 -07005702
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005703 status = hdd_parse_ese_beacon_req(value, &eseBcnReq);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08005704 if (eHAL_STATUS_SUCCESS != status)
5705 {
5706 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005707 "%s: Failed to parse ese beacon req", __func__);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08005708 ret = -EINVAL;
5709 goto exit;
5710 }
Srinivas Girigowda0c6d7fe2014-05-28 18:18:10 -07005711 if (!hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))) {
5712 hddLog(VOS_TRACE_LEVEL_INFO, FL("Not associated"));
5713 hdd_indicateEseBcnReportNoResults (pAdapter,
5714 eseBcnReq.bcnReq[0].measurementToken,
5715 0x02, //BIT(1) set for measurement done
5716 0); // no BSS
5717 goto exit;
5718 }
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08005719
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005720 status = sme_SetEseBeaconRequest((tHalHandle)(pHddCtx->hHal), pAdapter->sessionId, &eseBcnReq);
5721 if (eHAL_STATUS_SUCCESS != status)
5722 {
5723 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5724 "%s: sme_SetEseBeaconRequest failed (%d)", __func__, status);
5725 ret = -EINVAL;
5726 goto exit;
5727 }
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08005728 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005729#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
c_hpothu92367912014-05-01 15:18:17 +05305730 else if (strncmp(command, "GETBCNMISSRATE", 14) == 0)
5731 {
5732 eHalStatus status;
5733 char buf[32], len;
5734 long waitRet;
5735 bcnMissRateContext_t getBcnMissRateCtx;
5736
5737 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
5738
5739 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
5740 {
5741 hddLog(VOS_TRACE_LEVEL_WARN,
5742 FL("GETBCNMISSRATE: STA is not in connected state"));
5743 ret = -1;
5744 goto exit;
5745 }
5746
5747 init_completion(&(getBcnMissRateCtx.completion));
5748 getBcnMissRateCtx.magic = BCN_MISS_RATE_CONTEXT_MAGIC;
5749
5750 status = sme_getBcnMissRate((tHalHandle)(pHddCtx->hHal),
5751 pAdapter->sessionId,
5752 (void *)getBcnMissRateCB,
5753 (void *)(&getBcnMissRateCtx));
5754 if( eHAL_STATUS_SUCCESS != status)
5755 {
5756 hddLog(VOS_TRACE_LEVEL_INFO,
5757 FL("GETBCNMISSRATE: fail to post WDA cmd"));
5758 ret = -EINVAL;
5759 goto exit;
5760 }
5761
5762 waitRet = wait_for_completion_interruptible_timeout
5763 (&getBcnMissRateCtx.completion, BCN_MISS_RATE_TIME);
5764 if(waitRet <= 0)
5765 {
5766 hddLog(VOS_TRACE_LEVEL_ERROR,
5767 FL("failed to wait on bcnMissRateComp %d"), ret);
5768
5769 //Make magic number to zero so that callback is not called.
5770 spin_lock(&hdd_context_lock);
5771 getBcnMissRateCtx.magic = 0x0;
5772 spin_unlock(&hdd_context_lock);
5773 ret = -EINVAL;
5774 goto exit;
5775 }
5776
5777 hddLog(VOS_TRACE_LEVEL_INFO,
5778 FL("GETBCNMISSRATE: bcnMissRate: %d"), gbcnMissRate);
5779
5780 len = snprintf(buf, sizeof(buf), "GETBCNMISSRATE %d", gbcnMissRate);
5781 if (copy_to_user(priv_data.buf, &buf, len + 1))
5782 {
5783 hddLog(VOS_TRACE_LEVEL_ERROR,
5784 "%s: failed to copy data to user buffer", __func__);
5785 ret = -EFAULT;
5786 goto exit;
5787 }
5788 ret = len;
5789 }
Atul Mittal87ec2422014-09-24 13:12:50 +05305790#ifdef FEATURE_WLAN_TDLS
5791 else if (strncmp(command, "TDLSSECONDARYCHANNELOFFSET", 26) == 0) {
5792 tANI_U8 *value = command;
5793 int set_value;
5794 /* Move pointer to ahead of TDLSOFFCH*/
5795 value += 26;
c_manjeebbc40212015-12-08 13:52:59 +05305796 if (!(sscanf(value, "%d", &set_value))) {
5797 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
5798 FL("No input identified"));
5799 ret = -EINVAL;
5800 goto exit;
5801 }
5802
Atul Mittal87ec2422014-09-24 13:12:50 +05305803 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
5804 "%s: Tdls offchannel offset:%d",
5805 __func__, set_value);
5806 ret = iw_set_tdlssecoffchanneloffset(pHddCtx, set_value);
5807 if (ret < 0)
5808 {
5809 ret = -EINVAL;
5810 goto exit;
5811 }
5812
5813 } else if (strncmp(command, "TDLSOFFCHANNELMODE", 18) == 0) {
5814 tANI_U8 *value = command;
5815 int set_value;
5816 /* Move pointer to ahead of tdlsoffchnmode*/
5817 value += 18;
c_manjee82323892015-12-08 12:40:34 +05305818 ret = sscanf(value, "%d", &set_value);
5819 if (ret != 1) {
5820 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
5821 FL("No input identified"));
5822 ret = -EINVAL;
5823 goto exit;
5824 }
Atul Mittal87ec2422014-09-24 13:12:50 +05305825 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
5826 "%s: Tdls offchannel mode:%d",
5827 __func__, set_value);
5828 ret = iw_set_tdlsoffchannelmode(pAdapter, set_value);
5829 if (ret < 0)
5830 {
5831 ret = -EINVAL;
5832 goto exit;
5833 }
5834 } else if (strncmp(command, "TDLSOFFCHANNEL", 14) == 0) {
5835 tANI_U8 *value = command;
5836 int set_value;
5837 /* Move pointer to ahead of TDLSOFFCH*/
5838 value += 14;
c_manjeef6ccaf52015-12-08 11:52:11 +05305839 ret = sscanf(value, "%d", &set_value);
5840 if (ret != 1) {
5841 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5842 "Wrong value is given for hdd_set_tdls_offchannel");
5843 ret = -EINVAL;
5844 goto exit;
5845 }
5846
Atul Mittal87ec2422014-09-24 13:12:50 +05305847 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
5848 "%s: Tdls offchannel num: %d",
5849 __func__, set_value);
5850 ret = iw_set_tdlsoffchannel(pHddCtx, set_value);
5851 if (ret < 0)
5852 {
5853 ret = -EINVAL;
5854 goto exit;
5855 }
5856 }
5857#endif
Satyanarayana Dash72806012014-12-02 14:30:08 +05305858 else if (strncmp(command, "GETFWSTATS", 10) == 0)
5859 {
5860 eHalStatus status;
5861 char *buf = NULL;
5862 char len;
5863 long waitRet;
5864 fwStatsContext_t fwStatsCtx;
Abhishek Singh08aa7762014-12-16 13:59:03 +05305865 tSirFwStatsResult *fwStatsRsp = &(pAdapter->fwStatsRsp);
Satyanarayana Dash72806012014-12-02 14:30:08 +05305866 tANI_U8 *ptr = command;
5867 int stats = *(ptr + 11) - '0';
5868
5869 hddLog(VOS_TRACE_LEVEL_INFO, FL("stats = %d "),stats);
5870 if (!IS_FEATURE_FW_STATS_ENABLE)
5871 {
5872 hddLog(VOS_TRACE_LEVEL_INFO,
5873 FL("Get Firmware stats feature not supported"));
5874 ret = -EINVAL;
5875 goto exit;
5876 }
5877
5878 if (FW_STATS_MAX <= stats || 0 >= stats)
5879 {
5880 hddLog(VOS_TRACE_LEVEL_INFO,
5881 FL(" stats %d not supported"),stats);
5882 ret = -EINVAL;
5883 goto exit;
5884 }
5885
5886 init_completion(&(fwStatsCtx.completion));
5887 fwStatsCtx.magic = FW_STATS_CONTEXT_MAGIC;
5888 fwStatsCtx.pAdapter = pAdapter;
5889 fwStatsRsp->type = 0;
5890 status = sme_GetFwStats( (tHalHandle)pHddCtx->hHal, stats,
Abhishek Singh08aa7762014-12-16 13:59:03 +05305891 &fwStatsCtx, hdd_FWStatisCB);
Satyanarayana Dash72806012014-12-02 14:30:08 +05305892 if (eHAL_STATUS_SUCCESS != status)
5893 {
5894 hddLog(VOS_TRACE_LEVEL_ERROR,
5895 FL(" fail to post WDA cmd status = %d"), status);
5896 ret = -EINVAL;
5897 goto exit;
5898 }
5899 waitRet = wait_for_completion_timeout
5900 (&(fwStatsCtx.completion), FW_STATE_WAIT_TIME);
5901 if (waitRet <= 0)
5902 {
5903 hddLog(VOS_TRACE_LEVEL_ERROR,
5904 FL("failed to wait on GwtFwstats"));
5905 //Make magic number to zero so that callback is not executed.
5906 spin_lock(&hdd_context_lock);
5907 fwStatsCtx.magic = 0x0;
5908 spin_unlock(&hdd_context_lock);
5909 ret = -EINVAL;
5910 goto exit;
5911 }
5912 if (fwStatsRsp->type)
5913 {
5914 buf = kmalloc(FW_STATE_RSP_LEN, GFP_KERNEL);
5915 if (!buf)
5916 {
5917 hddLog(VOS_TRACE_LEVEL_ERROR,
5918 FL(" failed to allocate memory"));
5919 ret = -ENOMEM;
5920 goto exit;
5921 }
5922 switch( fwStatsRsp->type )
5923 {
5924 case FW_UBSP_STATS:
5925 {
5926 len = snprintf(buf, FW_STATE_RSP_LEN,
5927 "GETFWSTATS: ubsp_enter_cnt %d ubsp_jump_ddr_cnt %d",
Abhishek Singh08aa7762014-12-16 13:59:03 +05305928 fwStatsRsp->fwStatsData.ubspStats.ubsp_enter_cnt,
5929 fwStatsRsp->fwStatsData.ubspStats.ubsp_jump_ddr_cnt);
Satyanarayana Dash72806012014-12-02 14:30:08 +05305930 }
5931 break;
5932 default:
5933 {
5934 hddLog(VOS_TRACE_LEVEL_ERROR, FL( "No handling for stats type %d"),fwStatsRsp->type);
5935 ret = -EFAULT;
5936 kfree(buf);
5937 goto exit;
5938 }
5939 }
5940 if (copy_to_user(priv_data.buf, buf, len + 1))
5941 {
5942 hddLog(VOS_TRACE_LEVEL_ERROR,
5943 FL(" failed to copy data to user buffer"));
5944 ret = -EFAULT;
5945 kfree(buf);
5946 goto exit;
5947 }
5948 ret = len;
5949 kfree(buf);
5950 }
5951 else
5952 {
5953 hddLog(VOS_TRACE_LEVEL_ERROR,
5954 FL("failed to fetch the stats"));
5955 ret = -EFAULT;
5956 goto exit;
5957 }
5958
5959 }
Agarwal Ashish8bd53ae2015-06-12 18:03:45 +05305960 else if (strncasecmp(command, "SET_FCC_CHANNEL", 15) == 0)
5961 {
5962 /*
5963 * this command wld be called by user-space when it detects WLAN
5964 * ON after airplane mode is set. When APM is set, WLAN turns off.
5965 * But it can be turned back on. Otherwise; when APM is turned back
5966 * off, WLAN wld turn back on. So at that point the command is
5967 * expected to come down. 0 means disable, 1 means enable. The
5968 * constraint is removed when parameter 1 is set or different
5969 * country code is set
5970 */
5971 ret = hdd_cmd_setFccChannel(pHddCtx, command, 15);
5972 }
Mahesh A Saptasagarbeca12c2015-09-07 16:21:06 +05305973 else if (strncasecmp(command, "DISABLE_CA_EVENT", 16) == 0)
5974 {
5975 ret = hdd_enable_disable_ca_event(pHddCtx, command, 16);
5976 }
Madan Mohan Koyyalamudif9bdd4e2012-10-30 18:05:03 -07005977 else {
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05305978 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
5979 TRACE_CODE_HDD_UNSUPPORTED_IOCTL,
5980 pAdapter->sessionId, 0));
Satyanarayana Dash72806012014-12-02 14:30:08 +05305981 hddLog( VOS_TRACE_LEVEL_WARN, FL("Unsupported GUI command %s"),
5982 command);
Madan Mohan Koyyalamudif9bdd4e2012-10-30 18:05:03 -07005983 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005984 }
5985exit:
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305986 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07005987 if (command)
5988 {
5989 kfree(command);
5990 }
5991 return ret;
5992}
5993
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07005994#ifdef CONFIG_COMPAT
5995static int hdd_driver_compat_ioctl(hdd_adapter_t *pAdapter, struct ifreq *ifr)
5996{
5997 struct {
5998 compat_uptr_t buf;
5999 int used_len;
6000 int total_len;
6001 } compat_priv_data;
6002 hdd_priv_data_t priv_data;
6003 int ret = 0;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07006004
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07006005 /*
6006 * Note that pAdapter and ifr have already been verified by caller,
6007 * and HDD context has also been validated
6008 */
6009 if (copy_from_user(&compat_priv_data, ifr->ifr_data,
6010 sizeof(compat_priv_data))) {
6011 ret = -EFAULT;
6012 goto exit;
6013 }
6014 priv_data.buf = compat_ptr(compat_priv_data.buf);
6015 priv_data.used_len = compat_priv_data.used_len;
6016 priv_data.total_len = compat_priv_data.total_len;
6017 ret = hdd_driver_command(pAdapter, &priv_data);
6018 exit:
6019 return ret;
6020}
6021#else /* CONFIG_COMPAT */
6022static int hdd_driver_compat_ioctl(hdd_adapter_t *pAdapter, struct ifreq *ifr)
6023{
6024 /* will never be invoked */
6025 return 0;
6026}
6027#endif /* CONFIG_COMPAT */
6028
6029static int hdd_driver_ioctl(hdd_adapter_t *pAdapter, struct ifreq *ifr)
6030{
6031 hdd_priv_data_t priv_data;
6032 int ret = 0;
6033
6034 /*
6035 * Note that pAdapter and ifr have already been verified by caller,
6036 * and HDD context has also been validated
6037 */
6038 if (copy_from_user(&priv_data, ifr->ifr_data, sizeof(priv_data))) {
6039 ret = -EFAULT;
6040 } else {
6041 ret = hdd_driver_command(pAdapter, &priv_data);
6042 }
6043 return ret;
6044}
6045
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05306046int __hdd_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07006047{
6048 hdd_adapter_t *pAdapter;
6049 hdd_context_t *pHddCtx;
6050 int ret;
6051
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05306052 ENTER();
6053
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07006054 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6055 if (NULL == pAdapter) {
6056 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
6057 "%s: HDD adapter context is Null", __func__);
6058 ret = -ENODEV;
6059 goto exit;
6060 }
6061 if (dev != pAdapter->dev) {
6062 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
6063 "%s: HDD adapter/dev inconsistency", __func__);
6064 ret = -ENODEV;
6065 goto exit;
6066 }
6067
6068 if ((!ifr) || (!ifr->ifr_data)) {
6069 ret = -EINVAL;
6070 goto exit;
6071 }
6072
6073 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
6074 ret = wlan_hdd_validate_context(pHddCtx);
6075 if (ret) {
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07006076 ret = -EBUSY;
6077 goto exit;
6078 }
6079
6080 switch (cmd) {
6081 case (SIOCDEVPRIVATE + 1):
6082 if (is_compat_task())
6083 ret = hdd_driver_compat_ioctl(pAdapter, ifr);
6084 else
6085 ret = hdd_driver_ioctl(pAdapter, ifr);
6086 break;
6087 default:
6088 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unknown ioctl %d",
6089 __func__, cmd);
6090 ret = -EINVAL;
6091 break;
6092 }
6093 exit:
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05306094 EXIT();
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07006095 return ret;
6096}
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07006097
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05306098int hdd_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
6099{
6100 int ret;
6101
6102 vos_ssr_protect(__func__);
6103 ret = __hdd_ioctl(dev, ifr, cmd);
6104 vos_ssr_unprotect(__func__);
6105
6106 return ret;
6107}
6108
Katya Nigame7b69a82015-04-28 15:24:06 +05306109int hdd_mon_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
6110{
6111 return 0;
6112}
6113
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08006114#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08006115/**---------------------------------------------------------------------------
6116
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08006117 \brief hdd_parse_ese_beacon_req() - Parse ese beacon request
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08006118
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08006119 This function parses the ese beacon request passed in the format
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08006120 CCXBEACONREQ<space><Number of fields><space><Measurement token>
6121 <space>Channel 1<space>Scan Mode <space>Meas Duration<space>Channel N
6122 <space>Scan Mode N<space>Meas Duration N
6123 if the Number of bcn req fields (N) does not match with the actual number of fields passed
6124 then take N.
6125 <Meas Token><Channel><Scan Mode> and <Meas Duration> are treated as one pair
6126 For example, CCXBEACONREQ 2 1 1 1 30 2 44 0 40.
6127 This function does not take care of removing duplicate channels from the list
6128
6129 \param - pValue Pointer to data
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08006130 \param - pEseBcnReq output pointer to store parsed ie information
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08006131
6132 \return - 0 for success non-zero for failure
6133
6134 --------------------------------------------------------------------------*/
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08006135static VOS_STATUS hdd_parse_ese_beacon_req(tANI_U8 *pValue,
6136 tCsrEseBeaconReq *pEseBcnReq)
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08006137{
6138 tANI_U8 *inPtr = pValue;
Arun Khandavalli9f3b4832016-06-30 16:58:38 +05306139 uint8_t input = 0;
6140 uint32_t tempInt = 0;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08006141 int j = 0, i = 0, v = 0;
6142 char buf[32];
6143
6144 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
6145 /*no argument after the command*/
6146 if (NULL == inPtr)
6147 {
6148 return -EINVAL;
6149 }
6150 /*no space after the command*/
6151 else if (SPACE_ASCII_VALUE != *inPtr)
6152 {
6153 return -EINVAL;
6154 }
6155
6156 /*removing empty spaces*/
6157 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
6158
6159 /*no argument followed by spaces*/
6160 if ('\0' == *inPtr) return -EINVAL;
6161
6162 /*getting the first argument ie measurement token*/
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08006163 v = sscanf(inPtr, "%31s ", buf);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08006164 if (1 != v) return -EINVAL;
6165
Arun Khandavalli9f3b4832016-06-30 16:58:38 +05306166 v = kstrtos8(buf, 10, &input);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08006167 if ( v < 0) return -EINVAL;
6168
Arun Khandavalli9f3b4832016-06-30 16:58:38 +05306169 input = VOS_MIN(input, SIR_ESE_MAX_MEAS_IE_REQS);
6170 pEseBcnReq->numBcnReqIe = input;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08006171
Srinivas Girigowda725a88e2016-03-31 19:24:25 +05306172 hddLog(LOG1, "Number of Bcn Req Ie fields: %d", pEseBcnReq->numBcnReqIe);
6173
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08006174
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08006175 for (j = 0; j < (pEseBcnReq->numBcnReqIe); j++)
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08006176 {
6177 for (i = 0; i < 4; i++)
6178 {
6179 /*inPtr pointing to the beginning of first space after number of ie fields*/
6180 inPtr = strpbrk( inPtr, " " );
6181 /*no ie data after the number of ie fields argument*/
6182 if (NULL == inPtr) return -EINVAL;
6183
6184 /*removing empty space*/
6185 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
6186
6187 /*no ie data after the number of ie fields argument and spaces*/
6188 if ( '\0' == *inPtr ) return -EINVAL;
6189
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08006190 v = sscanf(inPtr, "%31s ", buf);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08006191 if (1 != v) return -EINVAL;
6192
Arun Khandavalli9f3b4832016-06-30 16:58:38 +05306193 v = kstrtou32(buf, 10, &tempInt);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08006194 if (v < 0) return -EINVAL;
6195
6196 switch (i)
6197 {
6198 case 0: /* Measurement token */
Arun Khandavalli9f3b4832016-06-30 16:58:38 +05306199 if (!tempInt)
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08006200 {
6201 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arun Khandavalli9f3b4832016-06-30 16:58:38 +05306202 "Invalid Measurement Token: %u", tempInt);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08006203 return -EINVAL;
6204 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08006205 pEseBcnReq->bcnReq[j].measurementToken = tempInt;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08006206 break;
6207
6208 case 1: /* Channel number */
Arun Khandavalli9f3b4832016-06-30 16:58:38 +05306209 if ((!tempInt) ||
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08006210 (tempInt > WNI_CFG_CURRENT_CHANNEL_STAMAX))
6211 {
6212 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arun Khandavalli9f3b4832016-06-30 16:58:38 +05306213 "Invalid Channel Number: %u", tempInt);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08006214 return -EINVAL;
6215 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08006216 pEseBcnReq->bcnReq[j].channel = tempInt;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08006217 break;
6218
6219 case 2: /* Scan mode */
Varun Reddy Yeturu0b18d5a2013-12-04 11:42:23 -08006220 if ((tempInt < eSIR_PASSIVE_SCAN) || (tempInt > eSIR_BEACON_TABLE))
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08006221 {
6222 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arun Khandavalli9f3b4832016-06-30 16:58:38 +05306223 "Invalid Scan Mode(%u) Expected{0|1|2}", tempInt);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08006224 return -EINVAL;
6225 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08006226 pEseBcnReq->bcnReq[j].scanMode= tempInt;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08006227 break;
6228
6229 case 3: /* Measurement duration */
Arun Khandavalli9f3b4832016-06-30 16:58:38 +05306230 if (((!tempInt) && (pEseBcnReq->bcnReq[j].scanMode != eSIR_BEACON_TABLE)) ||
6231 ((pEseBcnReq->bcnReq[j].scanMode == eSIR_BEACON_TABLE)))
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08006232 {
6233 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arun Khandavalli9f3b4832016-06-30 16:58:38 +05306234 "Invalid Measurement Duration: %u", tempInt);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08006235 return -EINVAL;
6236 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08006237 pEseBcnReq->bcnReq[j].measurementDuration = tempInt;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08006238 break;
6239 }
6240 }
6241 }
6242
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08006243 for (j = 0; j < pEseBcnReq->numBcnReqIe; j++)
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08006244 {
6245 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Arun Kumar Khandavallie8768212014-02-17 16:43:34 +05306246 "Index(%d) Measurement Token(%u)Channel(%u) Scan Mode(%u) Measurement Duration(%u)\n",
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08006247 j,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08006248 pEseBcnReq->bcnReq[j].measurementToken,
6249 pEseBcnReq->bcnReq[j].channel,
6250 pEseBcnReq->bcnReq[j].scanMode,
6251 pEseBcnReq->bcnReq[j].measurementDuration);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08006252 }
6253
6254 return VOS_STATUS_SUCCESS;
6255}
6256
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07006257static void hdd_GetTsmStatsCB( tAniTrafStrmMetrics tsmMetrics, const tANI_U32 staId, void *pContext )
6258{
6259 struct statsContext *pStatsContext = NULL;
6260 hdd_adapter_t *pAdapter = NULL;
6261
6262 if (NULL == pContext)
6263 {
6264 hddLog(VOS_TRACE_LEVEL_ERROR,
6265 "%s: Bad param, pContext [%p]",
6266 __func__, pContext);
6267 return;
6268 }
6269
Jeff Johnson72a40512013-12-19 10:14:15 -08006270 /* there is a race condition that exists between this callback
6271 function and the caller since the caller could time out either
6272 before or while this code is executing. we use a spinlock to
6273 serialize these actions */
6274 spin_lock(&hdd_context_lock);
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07006275
6276 pStatsContext = pContext;
6277 pAdapter = pStatsContext->pAdapter;
6278 if ((NULL == pAdapter) || (STATS_CONTEXT_MAGIC != pStatsContext->magic))
6279 {
6280 /* the caller presumably timed out so there is nothing we can do */
Jeff Johnson72a40512013-12-19 10:14:15 -08006281 spin_unlock(&hdd_context_lock);
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07006282 hddLog(VOS_TRACE_LEVEL_WARN,
6283 "%s: Invalid context, pAdapter [%p] magic [%08x]",
6284 __func__, pAdapter, pStatsContext->magic);
6285 return;
6286 }
6287
Jeff Johnson72a40512013-12-19 10:14:15 -08006288 /* context is valid so caller is still waiting */
6289
6290 /* paranoia: invalidate the magic */
6291 pStatsContext->magic = 0;
6292
6293 /* copy over the tsm stats */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07006294 pAdapter->tsmStats.UplinkPktQueueDly = tsmMetrics.UplinkPktQueueDly;
6295 vos_mem_copy(pAdapter->tsmStats.UplinkPktQueueDlyHist,
6296 tsmMetrics.UplinkPktQueueDlyHist,
6297 sizeof(pAdapter->tsmStats.UplinkPktQueueDlyHist)/
6298 sizeof(pAdapter->tsmStats.UplinkPktQueueDlyHist[0]));
6299 pAdapter->tsmStats.UplinkPktTxDly = tsmMetrics.UplinkPktTxDly;
6300 pAdapter->tsmStats.UplinkPktLoss = tsmMetrics.UplinkPktLoss;
6301 pAdapter->tsmStats.UplinkPktCount = tsmMetrics.UplinkPktCount;
6302 pAdapter->tsmStats.RoamingCount = tsmMetrics.RoamingCount;
6303 pAdapter->tsmStats.RoamingDly = tsmMetrics.RoamingDly;
6304
Jeff Johnson72a40512013-12-19 10:14:15 -08006305 /* notify the caller */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07006306 complete(&pStatsContext->completion);
Jeff Johnson72a40512013-12-19 10:14:15 -08006307
6308 /* serialization is complete */
6309 spin_unlock(&hdd_context_lock);
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07006310}
6311
6312
6313
6314static VOS_STATUS hdd_get_tsm_stats(hdd_adapter_t *pAdapter, const tANI_U8 tid,
6315 tAniTrafStrmMetrics* pTsmMetrics)
6316{
6317 hdd_station_ctx_t *pHddStaCtx = NULL;
6318 eHalStatus hstatus;
Jeff Johnson72a40512013-12-19 10:14:15 -08006319 VOS_STATUS vstatus = VOS_STATUS_SUCCESS;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07006320 long lrc;
6321 struct statsContext context;
6322 hdd_context_t *pHddCtx = NULL;
6323
6324 if (NULL == pAdapter)
6325 {
6326 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: pAdapter is NULL", __func__);
6327 return VOS_STATUS_E_FAULT;
6328 }
6329
6330 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
6331 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
6332
6333 /* we are connected prepare our callback context */
6334 init_completion(&context.completion);
6335 context.pAdapter = pAdapter;
6336 context.magic = STATS_CONTEXT_MAGIC;
6337
6338 /* query tsm stats */
6339 hstatus = sme_GetTsmStats(pHddCtx->hHal, hdd_GetTsmStatsCB,
6340 pHddStaCtx->conn_info.staId[ 0 ],
6341 pHddStaCtx->conn_info.bssId,
6342 &context, pHddCtx->pvosContext, tid);
6343
6344 if (eHAL_STATUS_SUCCESS != hstatus)
6345 {
Jeff Johnson72a40512013-12-19 10:14:15 -08006346 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unable to retrieve statistics",
6347 __func__);
6348 vstatus = VOS_STATUS_E_FAULT;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07006349 }
6350 else
6351 {
6352 /* request was sent -- wait for the response */
6353 lrc = wait_for_completion_interruptible_timeout(&context.completion,
6354 msecs_to_jiffies(WLAN_WAIT_TIME_STATS));
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07006355 if (lrc <= 0)
6356 {
6357 hddLog(VOS_TRACE_LEVEL_ERROR,
6358 "%s: SME %s while retrieving statistics",
6359 __func__, (0 == lrc) ? "timeout" : "interrupt");
Jeff Johnson72a40512013-12-19 10:14:15 -08006360 vstatus = VOS_STATUS_E_TIMEOUT;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07006361 }
6362 }
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07006363
Jeff Johnson72a40512013-12-19 10:14:15 -08006364 /* either we never sent a request, we sent a request and received a
6365 response or we sent a request and timed out. if we never sent a
6366 request or if we sent a request and got a response, we want to
6367 clear the magic out of paranoia. if we timed out there is a
6368 race condition such that the callback function could be
6369 executing at the same time we are. of primary concern is if the
6370 callback function had already verified the "magic" but had not
6371 yet set the completion variable when a timeout occurred. we
6372 serialize these activities by invalidating the magic while
6373 holding a shared spinlock which will cause us to block if the
6374 callback is currently executing */
6375 spin_lock(&hdd_context_lock);
6376 context.magic = 0;
6377 spin_unlock(&hdd_context_lock);
6378
6379 if (VOS_STATUS_SUCCESS == vstatus)
6380 {
6381 pTsmMetrics->UplinkPktQueueDly = pAdapter->tsmStats.UplinkPktQueueDly;
6382 vos_mem_copy(pTsmMetrics->UplinkPktQueueDlyHist,
6383 pAdapter->tsmStats.UplinkPktQueueDlyHist,
6384 sizeof(pAdapter->tsmStats.UplinkPktQueueDlyHist)/
6385 sizeof(pAdapter->tsmStats.UplinkPktQueueDlyHist[0]));
6386 pTsmMetrics->UplinkPktTxDly = pAdapter->tsmStats.UplinkPktTxDly;
6387 pTsmMetrics->UplinkPktLoss = pAdapter->tsmStats.UplinkPktLoss;
6388 pTsmMetrics->UplinkPktCount = pAdapter->tsmStats.UplinkPktCount;
6389 pTsmMetrics->RoamingCount = pAdapter->tsmStats.RoamingCount;
6390 pTsmMetrics->RoamingDly = pAdapter->tsmStats.RoamingDly;
6391 }
6392 return vstatus;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07006393}
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08006394#endif /*FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07006395
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08006396#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowdade697412013-02-14 16:31:48 -08006397void hdd_getBand_helper(hdd_context_t *pHddCtx, int *pBand)
6398{
6399 eCsrBand band = -1;
6400 sme_GetFreqBand((tHalHandle)(pHddCtx->hHal), &band);
6401 switch (band)
6402 {
6403 case eCSR_BAND_ALL:
6404 *pBand = WLAN_HDD_UI_BAND_AUTO;
6405 break;
6406
6407 case eCSR_BAND_24:
6408 *pBand = WLAN_HDD_UI_BAND_2_4_GHZ;
6409 break;
6410
6411 case eCSR_BAND_5G:
6412 *pBand = WLAN_HDD_UI_BAND_5_GHZ;
6413 break;
6414
6415 default:
6416 hddLog( VOS_TRACE_LEVEL_WARN, "%s: Invalid Band %d", __func__, band);
6417 *pBand = -1;
6418 break;
6419 }
6420}
6421
6422/**---------------------------------------------------------------------------
6423
Srinivas Girigowda100eb322013-03-15 16:48:20 -07006424 \brief hdd_parse_send_action_frame_data() - HDD Parse send action frame data
6425
6426 This function parses the send action frame data passed in the format
6427 SENDACTIONFRAME<space><bssid><space><channel><space><dwelltime><space><data>
6428
Srinivas Girigowda56076852013-08-20 14:00:50 -07006429 \param - pValue Pointer to input data
Srinivas Girigowda100eb322013-03-15 16:48:20 -07006430 \param - pTargetApBssid Pointer to target Ap bssid
6431 \param - pChannel Pointer to the Target AP channel
6432 \param - pDwellTime Pointer to the time to stay off-channel after transmitting action frame
6433 \param - pBuf Pointer to data
6434 \param - pBufLen Pointer to data length
6435
6436 \return - 0 for success non-zero for failure
6437
6438 --------------------------------------------------------------------------*/
6439VOS_STATUS hdd_parse_send_action_frame_data(tANI_U8 *pValue, tANI_U8 *pTargetApBssid, tANI_U8 *pChannel,
6440 tANI_U8 *pDwellTime, tANI_U8 **pBuf, tANI_U8 *pBufLen)
6441{
6442 tANI_U8 *inPtr = pValue;
6443 tANI_U8 *dataEnd;
6444 int tempInt;
6445 int j = 0;
6446 int i = 0;
6447 int v = 0;
6448 tANI_U8 tempBuf[32];
6449 tANI_U8 tempByte = 0;
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08006450 /* 12 hexa decimal digits, 5 ':' and '\0' */
6451 tANI_U8 macAddress[18];
Srinivas Girigowda100eb322013-03-15 16:48:20 -07006452
6453 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
6454 /*no argument after the command*/
6455 if (NULL == inPtr)
6456 {
6457 return -EINVAL;
6458 }
6459
6460 /*no space after the command*/
6461 else if (SPACE_ASCII_VALUE != *inPtr)
6462 {
6463 return -EINVAL;
6464 }
6465
6466 /*removing empty spaces*/
6467 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
6468
6469 /*no argument followed by spaces*/
6470 if ('\0' == *inPtr)
6471 {
6472 return -EINVAL;
6473 }
6474
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07006475 v = sscanf(inPtr, "%17s", macAddress);
6476 if (!((1 == v) && hdd_is_valid_mac_address(macAddress)))
Srinivas Girigowda100eb322013-03-15 16:48:20 -07006477 {
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07006478 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6479 "Invalid MAC address or All hex inputs are not read (%d)", v);
6480 return -EINVAL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07006481 }
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07006482
6483 pTargetApBssid[0] = hdd_parse_hex(macAddress[0]) << 4 | hdd_parse_hex(macAddress[1]);
6484 pTargetApBssid[1] = hdd_parse_hex(macAddress[3]) << 4 | hdd_parse_hex(macAddress[4]);
6485 pTargetApBssid[2] = hdd_parse_hex(macAddress[6]) << 4 | hdd_parse_hex(macAddress[7]);
6486 pTargetApBssid[3] = hdd_parse_hex(macAddress[9]) << 4 | hdd_parse_hex(macAddress[10]);
6487 pTargetApBssid[4] = hdd_parse_hex(macAddress[12]) << 4 | hdd_parse_hex(macAddress[13]);
6488 pTargetApBssid[5] = hdd_parse_hex(macAddress[15]) << 4 | hdd_parse_hex(macAddress[16]);
Srinivas Girigowda100eb322013-03-15 16:48:20 -07006489
6490 /* point to the next argument */
6491 inPtr = strnchr(inPtr, strlen(inPtr), SPACE_ASCII_VALUE);
6492 /*no argument after the command*/
6493 if (NULL == inPtr) return -EINVAL;
6494
6495 /*removing empty spaces*/
6496 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
6497
6498 /*no argument followed by spaces*/
6499 if ('\0' == *inPtr)
6500 {
6501 return -EINVAL;
6502 }
6503
6504 /*getting the next argument ie the channel number */
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08006505 v = sscanf(inPtr, "%31s ", tempBuf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07006506 if (1 != v) return -EINVAL;
6507
Srinivas Girigowda100eb322013-03-15 16:48:20 -07006508 v = kstrtos32(tempBuf, 10, &tempInt);
Agarwal Ashish353b3a82014-04-08 14:55:11 +05306509 if ( v < 0 || tempInt <= 0 || tempInt > WNI_CFG_CURRENT_CHANNEL_STAMAX )
Kiet Lambe150c22013-11-21 16:30:32 +05306510 return -EINVAL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07006511
6512 *pChannel = tempInt;
6513
6514 /* point to the next argument */
6515 inPtr = strnchr(inPtr, strlen(inPtr), SPACE_ASCII_VALUE);
6516 /*no argument after the command*/
6517 if (NULL == inPtr) return -EINVAL;
6518 /*removing empty spaces*/
6519 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
6520
6521 /*no argument followed by spaces*/
6522 if ('\0' == *inPtr)
6523 {
6524 return -EINVAL;
6525 }
6526
6527 /*getting the next argument ie the dwell time */
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08006528 v = sscanf(inPtr, "%31s ", tempBuf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07006529 if (1 != v) return -EINVAL;
6530
Srinivas Girigowda100eb322013-03-15 16:48:20 -07006531 v = kstrtos32(tempBuf, 10, &tempInt);
Srinivas Girigowda5a6e0672014-01-09 14:42:57 -08006532 if ( v < 0 || tempInt < 0) return -EINVAL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07006533
6534 *pDwellTime = tempInt;
6535
6536 /* point to the next argument */
6537 inPtr = strnchr(inPtr, strlen(inPtr), SPACE_ASCII_VALUE);
6538 /*no argument after the command*/
6539 if (NULL == inPtr) return -EINVAL;
6540 /*removing empty spaces*/
6541 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
6542
6543 /*no argument followed by spaces*/
6544 if ('\0' == *inPtr)
6545 {
6546 return -EINVAL;
6547 }
6548
6549 /* find the length of data */
6550 dataEnd = inPtr;
6551 while(('\0' != *dataEnd) )
6552 {
6553 dataEnd++;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07006554 }
Kiet Lambe150c22013-11-21 16:30:32 +05306555 *pBufLen = dataEnd - inPtr ;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07006556 if ( *pBufLen <= 0) return -EINVAL;
6557
Srinivas Girigowdab5ae85d2013-06-03 10:51:45 -07006558 /* Allocate the number of bytes based on the number of input characters
6559 whether it is even or odd.
6560 if the number of input characters are even, then we need N/2 byte.
6561 if the number of input characters are odd, then we need do (N+1)/2 to
6562 compensate rounding off.
6563 For example, if N = 18, then (18 + 1)/2 = 9 bytes are enough.
6564 If N = 19, then we need 10 bytes, hence (19 + 1)/2 = 10 bytes */
6565 *pBuf = vos_mem_malloc((*pBufLen + 1)/2);
Srinivas Girigowda100eb322013-03-15 16:48:20 -07006566 if (NULL == *pBuf)
6567 {
6568 hddLog(VOS_TRACE_LEVEL_FATAL,
6569 "%s: vos_mem_alloc failed ", __func__);
6570 return -EINVAL;
6571 }
6572
6573 /* the buffer received from the upper layer is character buffer,
6574 we need to prepare the buffer taking 2 characters in to a U8 hex decimal number
6575 for example 7f0000f0...form a buffer to contain 7f in 0th location, 00 in 1st
6576 and f0 in 3rd location */
6577 for (i = 0, j = 0; j < *pBufLen; j += 2)
6578 {
Kiet Lambe150c22013-11-21 16:30:32 +05306579 if( j+1 == *pBufLen)
6580 {
6581 tempByte = hdd_parse_hex(inPtr[j]);
6582 }
6583 else
6584 {
6585 tempByte = (hdd_parse_hex(inPtr[j]) << 4) | (hdd_parse_hex(inPtr[j + 1]));
6586 }
Srinivas Girigowda100eb322013-03-15 16:48:20 -07006587 (*pBuf)[i++] = tempByte;
6588 }
6589 *pBufLen = i;
6590 return VOS_STATUS_SUCCESS;
6591}
6592
Srinivas Girigowda100eb322013-03-15 16:48:20 -07006593/**---------------------------------------------------------------------------
6594
Srinivas Girigowdade697412013-02-14 16:31:48 -08006595 \brief hdd_parse_channellist() - HDD Parse channel list
6596
6597 This function parses the channel list passed in the format
6598 SETROAMSCANCHANNELS<space><Number of channels><space>Channel 1<space>Channel 2<space>Channel N
Srinivas Girigowdacf9a9b42013-03-21 11:55:24 -07006599 if the Number of channels (N) does not match with the actual number of channels passed
6600 then take the minimum of N and count of (Ch1, Ch2, ...Ch M)
6601 For example, if SETROAMSCANCHANNELS 3 36 40 44 48, only 36, 40 and 44 shall be taken.
6602 If SETROAMSCANCHANNELS 5 36 40 44 48, ignore 5 and take 36, 40, 44 and 48.
6603 This function does not take care of removing duplicate channels from the list
Srinivas Girigowdade697412013-02-14 16:31:48 -08006604
6605 \param - pValue Pointer to input channel list
6606 \param - ChannelList Pointer to local output array to record channel list
6607 \param - pNumChannels Pointer to number of roam scan channels
6608
6609 \return - 0 for success non-zero for failure
6610
6611 --------------------------------------------------------------------------*/
6612VOS_STATUS hdd_parse_channellist(tANI_U8 *pValue, tANI_U8 *pChannelList, tANI_U8 *pNumChannels)
6613{
6614 tANI_U8 *inPtr = pValue;
6615 int tempInt;
6616 int j = 0;
6617 int v = 0;
6618 char buf[32];
6619
6620 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
6621 /*no argument after the command*/
6622 if (NULL == inPtr)
6623 {
6624 return -EINVAL;
6625 }
6626
6627 /*no space after the command*/
6628 else if (SPACE_ASCII_VALUE != *inPtr)
6629 {
6630 return -EINVAL;
6631 }
6632
6633 /*removing empty spaces*/
Jeff Johnsona1f9afb2013-04-03 09:13:31 -07006634 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
Srinivas Girigowdade697412013-02-14 16:31:48 -08006635
6636 /*no argument followed by spaces*/
6637 if ('\0' == *inPtr)
6638 {
6639 return -EINVAL;
6640 }
6641
6642 /*getting the first argument ie the number of channels*/
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08006643 v = sscanf(inPtr, "%31s ", buf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07006644 if (1 != v) return -EINVAL;
6645
Srinivas Girigowdade697412013-02-14 16:31:48 -08006646 v = kstrtos32(buf, 10, &tempInt);
Jeff Johnsona1f9afb2013-04-03 09:13:31 -07006647 if ((v < 0) ||
6648 (tempInt <= 0) ||
6649 (tempInt > WNI_CFG_VALID_CHANNEL_LIST_LEN))
6650 {
6651 return -EINVAL;
6652 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08006653
6654 *pNumChannels = tempInt;
6655
6656 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
6657 "Number of channels are: %d", *pNumChannels);
6658
6659 for (j = 0; j < (*pNumChannels); j++)
6660 {
6661 /*inPtr pointing to the beginning of first space after number of channels*/
6662 inPtr = strpbrk( inPtr, " " );
6663 /*no channel list after the number of channels argument*/
6664 if (NULL == inPtr)
6665 {
Srinivas Girigowdacf9a9b42013-03-21 11:55:24 -07006666 if (0 != j)
6667 {
6668 *pNumChannels = j;
6669 return VOS_STATUS_SUCCESS;
6670 }
6671 else
6672 {
6673 return -EINVAL;
6674 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08006675 }
6676
6677 /*removing empty space*/
Jeff Johnsona1f9afb2013-04-03 09:13:31 -07006678 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
Srinivas Girigowdade697412013-02-14 16:31:48 -08006679
6680 /*no channel list after the number of channels argument and spaces*/
6681 if ( '\0' == *inPtr )
6682 {
Srinivas Girigowdacf9a9b42013-03-21 11:55:24 -07006683 if (0 != j)
6684 {
6685 *pNumChannels = j;
6686 return VOS_STATUS_SUCCESS;
6687 }
6688 else
6689 {
6690 return -EINVAL;
6691 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08006692 }
6693
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08006694 v = sscanf(inPtr, "%31s ", buf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07006695 if (1 != v) return -EINVAL;
6696
Srinivas Girigowdade697412013-02-14 16:31:48 -08006697 v = kstrtos32(buf, 10, &tempInt);
Jeff Johnsona1f9afb2013-04-03 09:13:31 -07006698 if ((v < 0) ||
6699 (tempInt <= 0) ||
6700 (tempInt > WNI_CFG_CURRENT_CHANNEL_STAMAX))
6701 {
6702 return -EINVAL;
6703 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08006704 pChannelList[j] = tempInt;
6705
6706 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
6707 "Channel %d added to preferred channel list",
6708 pChannelList[j] );
6709 }
6710
Srinivas Girigowdade697412013-02-14 16:31:48 -08006711 return VOS_STATUS_SUCCESS;
6712}
6713
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07006714
Selvaraj, Sridhar5aff1ed2016-06-18 01:26:23 +05306715/**
6716 * hdd_parse_reassoc_command_v1_data() - HDD Parse reassoc command data
6717 * This function parses the reasoc command data passed in the format
6718 * REASSOC<space><bssid><space><channel>
6719 *
6720 * @pValue: Pointer to input data (its a NUL terminated string)
6721 * @pTargetApBssid: Pointer to target Ap bssid
6722 * @pChannel: Pointer to the Target AP channel
6723 *
6724 * Return: 0 for success non-zero for failure
6725 */
6726static int hdd_parse_reassoc_command_v1_data(const tANI_U8 *pValue,
6727 tANI_U8 *pTargetApBssid, tANI_U8 *pChannel)
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07006728{
Selvaraj, Sridhar5aff1ed2016-06-18 01:26:23 +05306729 const tANI_U8 *inPtr = pValue;
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07006730 int tempInt;
6731 int v = 0;
6732 tANI_U8 tempBuf[32];
Kiet Lamaa8e15a2014-02-11 23:30:06 -08006733 /* 12 hexa decimal digits, 5 ':' and '\0' */
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08006734 tANI_U8 macAddress[18];
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07006735
6736 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
6737 /*no argument after the command*/
6738 if (NULL == inPtr)
6739 {
6740 return -EINVAL;
6741 }
6742
6743 /*no space after the command*/
6744 else if (SPACE_ASCII_VALUE != *inPtr)
6745 {
6746 return -EINVAL;
6747 }
6748
6749 /*removing empty spaces*/
6750 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
6751
6752 /*no argument followed by spaces*/
6753 if ('\0' == *inPtr)
6754 {
6755 return -EINVAL;
6756 }
6757
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07006758 v = sscanf(inPtr, "%17s", macAddress);
6759 if (!((1 == v) && hdd_is_valid_mac_address(macAddress)))
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07006760 {
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07006761 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6762 "Invalid MAC address or All hex inputs are not read (%d)", v);
6763 return -EINVAL;
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07006764 }
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07006765
6766 pTargetApBssid[0] = hdd_parse_hex(macAddress[0]) << 4 | hdd_parse_hex(macAddress[1]);
6767 pTargetApBssid[1] = hdd_parse_hex(macAddress[3]) << 4 | hdd_parse_hex(macAddress[4]);
6768 pTargetApBssid[2] = hdd_parse_hex(macAddress[6]) << 4 | hdd_parse_hex(macAddress[7]);
6769 pTargetApBssid[3] = hdd_parse_hex(macAddress[9]) << 4 | hdd_parse_hex(macAddress[10]);
6770 pTargetApBssid[4] = hdd_parse_hex(macAddress[12]) << 4 | hdd_parse_hex(macAddress[13]);
6771 pTargetApBssid[5] = hdd_parse_hex(macAddress[15]) << 4 | hdd_parse_hex(macAddress[16]);
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07006772
6773 /* point to the next argument */
6774 inPtr = strnchr(inPtr, strlen(inPtr), SPACE_ASCII_VALUE);
6775 /*no argument after the command*/
6776 if (NULL == inPtr) return -EINVAL;
6777
6778 /*removing empty spaces*/
6779 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
6780
6781 /*no argument followed by spaces*/
6782 if ('\0' == *inPtr)
6783 {
6784 return -EINVAL;
6785 }
6786
6787 /*getting the next argument ie the channel number */
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08006788 v = sscanf(inPtr, "%31s ", tempBuf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07006789 if (1 != v) return -EINVAL;
6790
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07006791 v = kstrtos32(tempBuf, 10, &tempInt);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07006792 if ((v < 0) ||
Padma, Santhosh Kumar0fa809b2014-11-13 14:56:56 +05306793 (tempInt < 0) ||
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07006794 (tempInt > WNI_CFG_CURRENT_CHANNEL_STAMAX))
6795 {
6796 return -EINVAL;
6797 }
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07006798
6799 *pChannel = tempInt;
6800 return VOS_STATUS_SUCCESS;
6801}
6802
6803#endif
6804
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08006805#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07006806/**---------------------------------------------------------------------------
6807
6808 \brief hdd_parse_get_cckm_ie() - HDD Parse and fetch the CCKM IE
6809
6810 This function parses the SETCCKM IE command
6811 SETCCKMIE<space><ie data>
6812
6813 \param - pValue Pointer to input data
6814 \param - pCckmIe Pointer to output cckm Ie
6815 \param - pCckmIeLen Pointer to output cckm ie length
6816
6817 \return - 0 for success non-zero for failure
6818
6819 --------------------------------------------------------------------------*/
6820VOS_STATUS hdd_parse_get_cckm_ie(tANI_U8 *pValue, tANI_U8 **pCckmIe,
6821 tANI_U8 *pCckmIeLen)
6822{
6823 tANI_U8 *inPtr = pValue;
6824 tANI_U8 *dataEnd;
6825 int j = 0;
6826 int i = 0;
6827 tANI_U8 tempByte = 0;
6828
6829 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
6830 /*no argument after the command*/
6831 if (NULL == inPtr)
6832 {
6833 return -EINVAL;
6834 }
6835
6836 /*no space after the command*/
6837 else if (SPACE_ASCII_VALUE != *inPtr)
6838 {
6839 return -EINVAL;
6840 }
6841
6842 /*removing empty spaces*/
6843 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
6844
6845 /*no argument followed by spaces*/
6846 if ('\0' == *inPtr)
6847 {
6848 return -EINVAL;
6849 }
6850
6851 /* find the length of data */
6852 dataEnd = inPtr;
6853 while(('\0' != *dataEnd) )
6854 {
6855 dataEnd++;
6856 ++(*pCckmIeLen);
6857 }
6858 if ( *pCckmIeLen <= 0) return -EINVAL;
6859
6860 /* Allocate the number of bytes based on the number of input characters
6861 whether it is even or odd.
6862 if the number of input characters are even, then we need N/2 byte.
6863 if the number of input characters are odd, then we need do (N+1)/2 to
6864 compensate rounding off.
6865 For example, if N = 18, then (18 + 1)/2 = 9 bytes are enough.
6866 If N = 19, then we need 10 bytes, hence (19 + 1)/2 = 10 bytes */
6867 *pCckmIe = vos_mem_malloc((*pCckmIeLen + 1)/2);
6868 if (NULL == *pCckmIe)
6869 {
6870 hddLog(VOS_TRACE_LEVEL_FATAL,
6871 "%s: vos_mem_alloc failed ", __func__);
6872 return -EINVAL;
6873 }
6874 vos_mem_zero(*pCckmIe, (*pCckmIeLen + 1)/2);
6875 /* the buffer received from the upper layer is character buffer,
6876 we need to prepare the buffer taking 2 characters in to a U8 hex decimal number
6877 for example 7f0000f0...form a buffer to contain 7f in 0th location, 00 in 1st
6878 and f0 in 3rd location */
6879 for (i = 0, j = 0; j < *pCckmIeLen; j += 2)
6880 {
6881 tempByte = (hdd_parse_hex(inPtr[j]) << 4) | (hdd_parse_hex(inPtr[j + 1]));
6882 (*pCckmIe)[i++] = tempByte;
6883 }
6884 *pCckmIeLen = i;
6885
6886 return VOS_STATUS_SUCCESS;
6887}
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08006888#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07006889
Jeff Johnson295189b2012-06-20 16:38:30 -07006890/**---------------------------------------------------------------------------
6891
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07006892 \brief hdd_is_valid_mac_address() - Validate MAC address
6893
6894 This function validates whether the given MAC address is valid or not
6895 Expected MAC address is of the format XX:XX:XX:XX:XX:XX
6896 where X is the hexa decimal digit character and separated by ':'
6897 This algorithm works even if MAC address is not separated by ':'
6898
6899 This code checks given input string mac contains exactly 12 hexadecimal digits.
6900 and a separator colon : appears in the input string only after
6901 an even number of hex digits.
6902
6903 \param - pMacAddr pointer to the input MAC address
6904 \return - 1 for valid and 0 for invalid
6905
6906 --------------------------------------------------------------------------*/
6907
6908v_BOOL_t hdd_is_valid_mac_address(const tANI_U8 *pMacAddr)
6909{
6910 int xdigit = 0;
6911 int separator = 0;
6912 while (*pMacAddr)
6913 {
6914 if (isxdigit(*pMacAddr))
6915 {
6916 xdigit++;
6917 }
6918 else if (':' == *pMacAddr)
6919 {
6920 if (0 == xdigit || ((xdigit / 2) - 1) != separator)
6921 break;
6922
6923 ++separator;
6924 }
6925 else
6926 {
6927 separator = -1;
6928 /* Invalid MAC found */
6929 return 0;
6930 }
6931 ++pMacAddr;
6932 }
6933 return (xdigit == 12 && (separator == 5 || separator == 0));
6934}
6935
6936/**---------------------------------------------------------------------------
6937
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05306938 \brief __hdd_open() - HDD Open function
Jeff Johnson295189b2012-06-20 16:38:30 -07006939
6940 \param - dev Pointer to net_device structure
6941
6942 \return - 0 for success non-zero for failure
6943
6944 --------------------------------------------------------------------------*/
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05306945int __hdd_open(struct net_device *dev)
Jeff Johnson295189b2012-06-20 16:38:30 -07006946{
6947 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6948 hdd_context_t *pHddCtx;
6949 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
6950 VOS_STATUS status;
6951 v_BOOL_t in_standby = TRUE;
6952
6953 if (NULL == pAdapter)
6954 {
6955 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Agarwal Ashish971c2882013-10-30 20:11:12 +05306956 "%s: pAdapter is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006957 return -ENODEV;
6958 }
6959
6960 pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05306961 MTRACE(vos_trace(VOS_MODULE_ID_HDD, TRACE_CODE_HDD_OPEN_REQUEST,
6962 pAdapter->sessionId, pAdapter->device_mode));
Jeff Johnson295189b2012-06-20 16:38:30 -07006963 if (NULL == pHddCtx)
6964 {
6965 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07006966 "%s: HDD context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006967 return -ENODEV;
6968 }
6969
6970 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
6971 while ( (NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status) )
6972 {
Jeff Johnson6a81ca42013-04-05 10:37:08 -07006973 if (test_bit(DEVICE_IFACE_OPENED, &pAdapterNode->pAdapter->event_flags))
6974 {
6975 hddLog(VOS_TRACE_LEVEL_INFO, "%s: chip already out of standby",
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05306976 __func__);
Jeff Johnson6a81ca42013-04-05 10:37:08 -07006977 in_standby = FALSE;
6978 break;
6979 }
6980 else
6981 {
6982 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
6983 pAdapterNode = pNext;
6984 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006985 }
6986
6987 if (TRUE == in_standby)
6988 {
6989 if (VOS_STATUS_SUCCESS != wlan_hdd_exit_lowpower(pHddCtx, pAdapter))
6990 {
6991 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Failed to bring "
6992 "wlan out of power save", __func__);
6993 return -EINVAL;
6994 }
6995 }
6996
Jeff Johnson6a81ca42013-04-05 10:37:08 -07006997 set_bit(DEVICE_IFACE_OPENED, &pAdapter->event_flags);
Jeff Johnson295189b2012-06-20 16:38:30 -07006998 if (hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter)))
6999 {
7000 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007001 "%s: Enabling Tx Queues", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007002 /* Enable TX queues only when we are connected */
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +05307003 hddLog(VOS_TRACE_LEVEL_INFO, FL("Enabling queues"));
Jeff Johnson295189b2012-06-20 16:38:30 -07007004 netif_tx_start_all_queues(dev);
7005 }
7006
7007 return 0;
7008}
7009
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05307010/**---------------------------------------------------------------------------
7011
7012 \brief hdd_open() - Wrapper function for __hdd_open to protect it from SSR
7013
7014 This is called in response to ifconfig up
7015
7016 \param - dev Pointer to net_device structure
7017
7018 \return - 0 for success non-zero for failure
7019
7020 --------------------------------------------------------------------------*/
7021int hdd_open(struct net_device *dev)
7022{
7023 int ret;
7024
7025 vos_ssr_protect(__func__);
7026 ret = __hdd_open(dev);
7027 vos_ssr_unprotect(__func__);
7028
7029 return ret;
7030}
7031
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05307032int __hdd_mon_open (struct net_device *dev)
Jeff Johnson295189b2012-06-20 16:38:30 -07007033{
7034 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
7035
7036 if(pAdapter == NULL) {
7037 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007038 "%s: HDD adapter context is Null", __func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08007039 return -EINVAL;
Jeff Johnson295189b2012-06-20 16:38:30 -07007040 }
7041
Jeff Johnson295189b2012-06-20 16:38:30 -07007042 return 0;
7043}
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05307044
7045int hdd_mon_open (struct net_device *dev)
7046{
7047 int ret;
7048
7049 vos_ssr_protect(__func__);
7050 ret = __hdd_mon_open(dev);
7051 vos_ssr_unprotect(__func__);
7052
7053 return ret;
7054}
7055
Katya Nigame7b69a82015-04-28 15:24:06 +05307056int hdd_mon_stop(struct net_device *dev)
7057{
7058 return 0;
7059}
7060
Jeff Johnson295189b2012-06-20 16:38:30 -07007061/**---------------------------------------------------------------------------
7062
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05307063 \brief __hdd_stop() - HDD stop function
Jeff Johnson295189b2012-06-20 16:38:30 -07007064
7065 \param - dev Pointer to net_device structure
7066
7067 \return - 0 for success non-zero for failure
7068
7069 --------------------------------------------------------------------------*/
7070
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05307071int __hdd_stop (struct net_device *dev)
Jeff Johnson295189b2012-06-20 16:38:30 -07007072{
Vinay Krishna Eranna90f43532014-10-27 16:45:54 +05307073 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07007074 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
7075 hdd_context_t *pHddCtx;
7076 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7077 VOS_STATUS status;
7078 v_BOOL_t enter_standby = TRUE;
7079
7080 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07007081 if (NULL == pAdapter)
7082 {
7083 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Agarwal Ashish971c2882013-10-30 20:11:12 +05307084 "%s: pAdapter is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007085 return -ENODEV;
7086 }
Sachin Ahuja9b4958f2015-01-15 21:37:00 +05307087 MTRACE(vos_trace(VOS_MODULE_ID_HDD, TRACE_CODE_HDD_STOP_REQUEST,
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307088 pAdapter->sessionId, pAdapter->device_mode));
Vinay Krishna Eranna90f43532014-10-27 16:45:54 +05307089
7090 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7091 ret = wlan_hdd_validate_context(pHddCtx);
7092 if (ret)
Jeff Johnson295189b2012-06-20 16:38:30 -07007093 {
Vinay Krishna Eranna90f43532014-10-27 16:45:54 +05307094 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07007095 }
7096
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05307097 /* Nothing to be done if the interface is not opened */
7098 if (VOS_FALSE == test_bit(DEVICE_IFACE_OPENED, &pAdapter->event_flags))
7099 {
7100 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7101 "%s: NETDEV Interface is not OPENED", __func__);
7102 return -ENODEV;
7103 }
7104
7105 /* Make sure the interface is marked as closed */
Jeff Johnson6a81ca42013-04-05 10:37:08 -07007106 clear_bit(DEVICE_IFACE_OPENED, &pAdapter->event_flags);
Jeff Johnson295189b2012-06-20 16:38:30 -07007107 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Disabling OS Tx queues", __func__);
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05307108
7109 /* Disable TX on the interface, after this hard_start_xmit() will not
7110 * be called on that interface
7111 */
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +05307112 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Jeff Johnson295189b2012-06-20 16:38:30 -07007113 netif_tx_disable(pAdapter->dev);
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05307114
7115 /* Mark the interface status as "down" for outside world */
Jeff Johnson295189b2012-06-20 16:38:30 -07007116 netif_carrier_off(pAdapter->dev);
7117
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05307118 /* The interface is marked as down for outside world (aka kernel)
7119 * But the driver is pretty much alive inside. The driver needs to
7120 * tear down the existing connection on the netdev (session)
7121 * cleanup the data pipes and wait until the control plane is stabilized
7122 * for this interface. The call also needs to wait until the above
7123 * mentioned actions are completed before returning to the caller.
7124 * Notice that the hdd_stop_adapter is requested not to close the session
7125 * That is intentional to be able to scan if it is a STA/P2P interface
7126 */
7127 hdd_stop_adapter(pHddCtx, pAdapter, VOS_FALSE);
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05307128#ifdef FEATURE_WLAN_TDLS
7129 mutex_lock(&pHddCtx->tdls_lock);
7130#endif
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05307131 /* DeInit the adapter. This ensures datapath cleanup as well */
c_hpothu002231a2015-02-05 14:58:51 +05307132 hdd_deinit_adapter(pHddCtx, pAdapter, TRUE);
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05307133#ifdef FEATURE_WLAN_TDLS
7134 mutex_unlock(&pHddCtx->tdls_lock);
7135#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007136 /* SoftAP ifaces should never go in power save mode
7137 making sure same here. */
7138 if ( (WLAN_HDD_SOFTAP == pAdapter->device_mode )
7139 || (WLAN_HDD_MONITOR == pAdapter->device_mode )
Jeff Johnson295189b2012-06-20 16:38:30 -07007140 || (WLAN_HDD_P2P_GO == pAdapter->device_mode )
Jeff Johnson295189b2012-06-20 16:38:30 -07007141 )
7142 {
7143 /* SoftAP mode, so return from here */
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307144 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
7145 "%s: In SAP MODE", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007146 EXIT();
7147 return 0;
7148 }
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05307149 /* Find if any iface is up. If any iface is up then can't put device to
7150 * sleep/power save mode
7151 */
Jeff Johnson295189b2012-06-20 16:38:30 -07007152 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7153 while ( (NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status) )
7154 {
Jeff Johnson6a81ca42013-04-05 10:37:08 -07007155 if (test_bit(DEVICE_IFACE_OPENED, &pAdapterNode->pAdapter->event_flags))
7156 {
7157 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Still other ifaces are up cannot "
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05307158 "put device to sleep", __func__);
Jeff Johnson6a81ca42013-04-05 10:37:08 -07007159 enter_standby = FALSE;
7160 break;
7161 }
7162 else
7163 {
7164 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7165 pAdapterNode = pNext;
7166 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007167 }
7168
7169 if (TRUE == enter_standby)
7170 {
7171 hddLog(VOS_TRACE_LEVEL_INFO, "%s: All Interfaces are Down "
7172 "entering standby", __func__);
7173 if (VOS_STATUS_SUCCESS != wlan_hdd_enter_lowpower(pHddCtx))
7174 {
7175 /*log and return success*/
7176 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Failed to put "
7177 "wlan in power save", __func__);
7178 }
7179 }
7180
7181 EXIT();
7182 return 0;
7183}
7184
7185/**---------------------------------------------------------------------------
7186
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05307187 \brief hdd_stop() - wrapper_function for __hdd_stop to protect it from SSR
Jeff Johnson295189b2012-06-20 16:38:30 -07007188
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05307189 This is called in response to ifconfig down
7190
7191 \param - dev Pointer to net_device structure
7192
7193 \return - 0 for success non-zero for failure
7194-----------------------------------------------------------------------------*/
7195int hdd_stop (struct net_device *dev)
7196{
7197 int ret;
7198
7199 vos_ssr_protect(__func__);
7200 ret = __hdd_stop(dev);
7201 vos_ssr_unprotect(__func__);
7202
7203 return ret;
7204}
7205
7206/**---------------------------------------------------------------------------
7207
7208 \brief __hdd_uninit() - HDD uninit function
Jeff Johnson295189b2012-06-20 16:38:30 -07007209
7210 \param - dev Pointer to net_device structure
7211
7212 \return - void
7213
7214 --------------------------------------------------------------------------*/
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05307215static void __hdd_uninit (struct net_device *dev)
Jeff Johnson295189b2012-06-20 16:38:30 -07007216{
7217 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05307218 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07007219 ENTER();
7220
7221 do
7222 {
7223 if (NULL == pAdapter)
7224 {
7225 hddLog(VOS_TRACE_LEVEL_FATAL,
7226 "%s: NULL pAdapter", __func__);
7227 break;
7228 }
7229
7230 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
7231 {
7232 hddLog(VOS_TRACE_LEVEL_FATAL,
7233 "%s: Invalid magic", __func__);
7234 break;
7235 }
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05307236 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7237 if (NULL == pHddCtx)
Jeff Johnson295189b2012-06-20 16:38:30 -07007238 {
7239 hddLog(VOS_TRACE_LEVEL_FATAL,
7240 "%s: NULL pHddCtx", __func__);
7241 break;
7242 }
7243
7244 if (dev != pAdapter->dev)
7245 {
7246 hddLog(VOS_TRACE_LEVEL_FATAL,
7247 "%s: Invalid device reference", __func__);
7248 /* we haven't validated all cases so let this go for now */
7249 }
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05307250#ifdef FEATURE_WLAN_TDLS
7251 mutex_lock(&pHddCtx->tdls_lock);
7252#endif
c_hpothu002231a2015-02-05 14:58:51 +05307253 hdd_deinit_adapter(pHddCtx, pAdapter, TRUE);
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05307254#ifdef FEATURE_WLAN_TDLS
7255 mutex_unlock(&pHddCtx->tdls_lock);
7256#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007257
7258 /* after uninit our adapter structure will no longer be valid */
7259 pAdapter->dev = NULL;
7260 pAdapter->magic = 0;
Manjeet Singh47ee8472016-04-11 11:57:18 +05307261 pAdapter->pHddCtx = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07007262 } while (0);
7263
7264 EXIT();
7265}
7266
7267/**---------------------------------------------------------------------------
7268
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05307269 \brief hdd_uninit() - Wrapper function to protect __hdd_uninit from SSR
7270
7271 This is called during the netdev unregister to uninitialize all data
7272associated with the device
7273
7274 \param - dev Pointer to net_device structure
7275
7276 \return - void
7277
7278 --------------------------------------------------------------------------*/
7279static void hdd_uninit (struct net_device *dev)
7280{
7281 vos_ssr_protect(__func__);
7282 __hdd_uninit(dev);
7283 vos_ssr_unprotect(__func__);
7284}
7285
7286/**---------------------------------------------------------------------------
7287
Jeff Johnson295189b2012-06-20 16:38:30 -07007288 \brief hdd_release_firmware() -
7289
7290 This function calls the release firmware API to free the firmware buffer.
7291
7292 \param - pFileName Pointer to the File Name.
7293 pCtx - Pointer to the adapter .
7294
7295
7296 \return - 0 for success, non zero for failure
7297
7298 --------------------------------------------------------------------------*/
7299
7300VOS_STATUS hdd_release_firmware(char *pFileName,v_VOID_t *pCtx)
7301{
7302 VOS_STATUS status = VOS_STATUS_SUCCESS;
7303 hdd_context_t *pHddCtx = (hdd_context_t*)pCtx;
7304 ENTER();
7305
7306
7307 if (!strcmp(WLAN_FW_FILE, pFileName)) {
7308
7309 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,"%s: Loaded firmware file is %s",__func__,pFileName);
7310
7311 if(pHddCtx->fw) {
7312 release_firmware(pHddCtx->fw);
7313 pHddCtx->fw = NULL;
7314 }
7315 else
7316 status = VOS_STATUS_E_FAILURE;
7317 }
7318 else if (!strcmp(WLAN_NV_FILE,pFileName)) {
7319 if(pHddCtx->nv) {
7320 release_firmware(pHddCtx->nv);
7321 pHddCtx->nv = NULL;
7322 }
7323 else
7324 status = VOS_STATUS_E_FAILURE;
7325
7326 }
7327
7328 EXIT();
7329 return status;
7330}
7331
7332/**---------------------------------------------------------------------------
7333
7334 \brief hdd_request_firmware() -
7335
7336 This function reads the firmware file using the request firmware
7337 API and returns the the firmware data and the firmware file size.
7338
7339 \param - pfileName - Pointer to the file name.
7340 - pCtx - Pointer to the adapter .
7341 - ppfw_data - Pointer to the pointer of the firmware data.
7342 - pSize - Pointer to the file size.
7343
7344 \return - VOS_STATUS_SUCCESS for success, VOS_STATUS_E_FAILURE for failure
7345
7346 --------------------------------------------------------------------------*/
7347
7348
7349VOS_STATUS hdd_request_firmware(char *pfileName,v_VOID_t *pCtx,v_VOID_t **ppfw_data, v_SIZE_t *pSize)
7350{
7351 int status;
7352 VOS_STATUS retval = VOS_STATUS_SUCCESS;
7353 hdd_context_t *pHddCtx = (hdd_context_t*)pCtx;
7354 ENTER();
7355
7356 if( (!strcmp(WLAN_FW_FILE, pfileName)) ) {
7357
7358 status = request_firmware(&pHddCtx->fw, pfileName, pHddCtx->parent_dev);
7359
7360 if(status || !pHddCtx->fw || !pHddCtx->fw->data) {
7361 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Firmware %s download failed",
7362 __func__, pfileName);
7363 retval = VOS_STATUS_E_FAILURE;
7364 }
7365
7366 else {
7367 *ppfw_data = (v_VOID_t *)pHddCtx->fw->data;
7368 *pSize = pHddCtx->fw->size;
7369 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Firmware size = %d",
7370 __func__, *pSize);
7371 }
7372 }
7373 else if(!strcmp(WLAN_NV_FILE, pfileName)) {
7374
7375 status = request_firmware(&pHddCtx->nv, pfileName, pHddCtx->parent_dev);
7376
7377 if(status || !pHddCtx->nv || !pHddCtx->nv->data) {
7378 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: nv %s download failed",
7379 __func__, pfileName);
7380 retval = VOS_STATUS_E_FAILURE;
7381 }
7382
7383 else {
7384 *ppfw_data = (v_VOID_t *)pHddCtx->nv->data;
7385 *pSize = pHddCtx->nv->size;
7386 hddLog(VOS_TRACE_LEVEL_INFO, "%s: nv file size = %d",
7387 __func__, *pSize);
7388 }
7389 }
7390
7391 EXIT();
7392 return retval;
7393}
7394/**---------------------------------------------------------------------------
7395 \brief hdd_full_pwr_cbk() - HDD full power callbackfunction
7396
7397 This is the function invoked by SME to inform the result of a full power
7398 request issued by HDD
7399
7400 \param - callbackcontext - Pointer to cookie
7401 status - result of request
7402
7403 \return - None
7404
7405--------------------------------------------------------------------------*/
7406void hdd_full_pwr_cbk(void *callbackContext, eHalStatus status)
7407{
7408 hdd_context_t *pHddCtx = (hdd_context_t*)callbackContext;
7409
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07007410 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,"HDD full Power callback status = %d", status);
Jeff Johnson295189b2012-06-20 16:38:30 -07007411 if(&pHddCtx->full_pwr_comp_var)
7412 {
7413 complete(&pHddCtx->full_pwr_comp_var);
7414 }
7415}
7416
Abhishek Singh00b71972016-01-07 10:51:04 +05307417#ifdef WLAN_FEATURE_RMC
7418static void hdd_tx_fail_ind_callback(v_U8_t *MacAddr, v_U8_t seqNo)
7419{
7420 int payload_len;
7421 struct sk_buff *skb;
7422 struct nlmsghdr *nlh;
7423 v_U8_t *data;
7424
7425 payload_len = ETH_ALEN;
7426
7427 if (0 == cesium_pid)
7428 {
7429 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: cesium process not registered",
7430 __func__);
7431 return;
7432 }
7433
7434 if ((skb = nlmsg_new(payload_len,GFP_ATOMIC)) == NULL)
7435 {
7436 hddLog(VOS_TRACE_LEVEL_ERROR,
7437 "%s: nlmsg_new() failed for msg size[%d]",
7438 __func__, NLMSG_SPACE(payload_len));
7439 return;
7440 }
7441
7442 nlh = nlmsg_put(skb, cesium_pid, seqNo, 0, payload_len, NLM_F_REQUEST);
7443
7444 if (NULL == nlh)
7445 {
7446 hddLog(VOS_TRACE_LEVEL_ERROR,
7447 "%s: nlmsg_put() failed for msg size[%d]",
7448 __func__, NLMSG_SPACE(payload_len));
7449
7450 kfree_skb(skb);
7451 return;
7452 }
7453
7454 data = nlmsg_data(nlh);
7455 memcpy(data, MacAddr, ETH_ALEN);
7456
7457 if (nlmsg_unicast(cesium_nl_srv_sock, skb, cesium_pid) < 0)
7458 {
7459 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: nlmsg_unicast() failed for msg size[%d]",
7460 __func__, NLMSG_SPACE(payload_len));
7461 }
7462
7463 return;
7464}
7465
7466/**---------------------------------------------------------------------------
7467 \brief hdd_ParseuserParams - return a pointer to the next argument
7468
7469 \return - status
7470
7471--------------------------------------------------------------------------*/
7472static int hdd_ParseUserParams(tANI_U8 *pValue, tANI_U8 **ppArg)
7473{
7474 tANI_U8 *pVal;
7475
7476 pVal = strchr(pValue, ' ');
7477
7478 if (NULL == pVal)
7479 {
7480 /* no argument remains */
7481 return -EINVAL;
7482 }
7483 else if (SPACE_ASCII_VALUE != *pVal)
7484 {
7485 /* no space after the current argument */
7486 return -EINVAL;
7487 }
7488
7489 pVal++;
7490
7491 /* remove empty spaces */
7492 while ((SPACE_ASCII_VALUE == *pVal) && ('\0' != *pVal))
7493 {
7494 pVal++;
7495 }
7496
7497 /* no argument followed by spaces */
7498 if ('\0' == *pVal)
7499 {
7500 return -EINVAL;
7501 }
7502
7503 *ppArg = pVal;
7504
7505 return 0;
7506}
7507
7508/**----------------------------------------------------------------------------
7509 \brief hdd_ParseIBSSTXFailEventParams - Parse params for SETIBSSTXFAILEVENT
7510
7511 \return - status
7512
7513------------------------------------------------------------------------------*/
7514static int hdd_ParseIBSSTXFailEventParams(tANI_U8 *pValue,
7515 tANI_U8 *tx_fail_count,
7516 tANI_U16 *pid)
7517{
7518 tANI_U8 *param = NULL;
7519 int ret;
7520
7521 ret = hdd_ParseUserParams(pValue, &param);
7522
7523 if (0 == ret && NULL != param)
7524 {
7525 if (1 != sscanf(param, "%hhu", tx_fail_count))
7526 {
7527 ret = -EINVAL;
7528 goto done;
7529 }
7530 }
7531 else
7532 {
7533 goto done;
7534 }
7535
7536 if (0 == *tx_fail_count)
7537 {
7538 *pid = 0;
7539 goto done;
7540 }
7541
7542 pValue = param;
7543 pValue++;
7544
7545 ret = hdd_ParseUserParams(pValue, &param);
7546
7547 if (0 == ret)
7548 {
7549 if (1 != sscanf(param, "%hu", pid))
7550 {
7551 ret = -EINVAL;
7552 goto done;
7553 }
7554 }
7555 else
7556 {
7557 goto done;
7558 }
7559
7560done:
7561 return ret;
7562}
7563
7564static int hdd_open_cesium_nl_sock()
7565{
7566#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
7567 struct netlink_kernel_cfg cfg = {
7568 .groups = WLAN_NLINK_MCAST_GRP_ID,
7569 .input = NULL
7570 };
7571#endif
7572 int ret = 0;
7573
7574#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
7575 cesium_nl_srv_sock = netlink_kernel_create(&init_net, WLAN_NLINK_CESIUM,
7576#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,7,0))
7577 THIS_MODULE,
7578#endif
7579 &cfg);
7580#else
7581 cesium_nl_srv_sock = netlink_kernel_create(&init_net, WLAN_NLINK_CESIUM,
7582 WLAN_NLINK_MCAST_GRP_ID, NULL, NULL, THIS_MODULE);
7583#endif
7584
7585 if (cesium_nl_srv_sock == NULL)
7586 {
7587 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7588 "NLINK: cesium netlink_kernel_create failed");
7589 ret = -ECONNREFUSED;
7590 }
7591
7592 return ret;
7593}
7594
7595static void hdd_close_cesium_nl_sock()
7596{
7597 if (NULL != cesium_nl_srv_sock)
7598 {
7599 netlink_kernel_release(cesium_nl_srv_sock);
7600 cesium_nl_srv_sock = NULL;
7601 }
7602}
7603#endif /* WLAN_FEATURE_RMC */
Jeff Johnson295189b2012-06-20 16:38:30 -07007604/**---------------------------------------------------------------------------
7605
7606 \brief hdd_req_bmps_cbk() - HDD Request BMPS callback function
7607
7608 This is the function invoked by SME to inform the result of BMPS
7609 request issued by HDD
7610
7611 \param - callbackcontext - Pointer to cookie
7612 status - result of request
7613
7614 \return - None
7615
7616--------------------------------------------------------------------------*/
7617void hdd_req_bmps_cbk(void *callbackContext, eHalStatus status)
7618{
7619
7620 struct completion *completion_var = (struct completion*) callbackContext;
7621
Arif Hussain6d2a3322013-11-17 19:50:10 -08007622 hddLog(VOS_TRACE_LEVEL_ERROR, "HDD BMPS request Callback, status = %d", status);
Jeff Johnson295189b2012-06-20 16:38:30 -07007623 if(completion_var != NULL)
7624 {
7625 complete(completion_var);
7626 }
7627}
7628
7629/**---------------------------------------------------------------------------
7630
7631 \brief hdd_get_cfg_file_size() -
7632
7633 This function reads the configuration file using the request firmware
7634 API and returns the configuration file size.
7635
7636 \param - pCtx - Pointer to the adapter .
7637 - pFileName - Pointer to the file name.
7638 - pBufSize - Pointer to the buffer size.
7639
7640 \return - 0 for success, non zero for failure
7641
7642 --------------------------------------------------------------------------*/
7643
7644VOS_STATUS hdd_get_cfg_file_size(v_VOID_t *pCtx, char *pFileName, v_SIZE_t *pBufSize)
7645{
7646 int status;
7647 hdd_context_t *pHddCtx = (hdd_context_t*)pCtx;
7648
7649 ENTER();
7650
7651 status = request_firmware(&pHddCtx->fw, pFileName, pHddCtx->parent_dev);
7652
7653 if(status || !pHddCtx->fw || !pHddCtx->fw->data) {
7654 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: CFG download failed",__func__);
7655 status = VOS_STATUS_E_FAILURE;
7656 }
7657 else {
7658 *pBufSize = pHddCtx->fw->size;
7659 hddLog(VOS_TRACE_LEVEL_INFO, "%s: CFG size = %d", __func__, *pBufSize);
7660 release_firmware(pHddCtx->fw);
7661 pHddCtx->fw = NULL;
7662 }
7663
7664 EXIT();
7665 return VOS_STATUS_SUCCESS;
7666}
7667
7668/**---------------------------------------------------------------------------
7669
7670 \brief hdd_read_cfg_file() -
7671
7672 This function reads the configuration file using the request firmware
7673 API and returns the cfg data and the buffer size of the configuration file.
7674
7675 \param - pCtx - Pointer to the adapter .
7676 - pFileName - Pointer to the file name.
7677 - pBuffer - Pointer to the data buffer.
7678 - pBufSize - Pointer to the buffer size.
7679
7680 \return - 0 for success, non zero for failure
7681
7682 --------------------------------------------------------------------------*/
7683
7684VOS_STATUS hdd_read_cfg_file(v_VOID_t *pCtx, char *pFileName,
7685 v_VOID_t *pBuffer, v_SIZE_t *pBufSize)
7686{
7687 int status;
7688 hdd_context_t *pHddCtx = (hdd_context_t*)pCtx;
7689
7690 ENTER();
7691
7692 status = request_firmware(&pHddCtx->fw, pFileName, pHddCtx->parent_dev);
7693
7694 if(status || !pHddCtx->fw || !pHddCtx->fw->data) {
7695 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: CFG download failed",__func__);
7696 return VOS_STATUS_E_FAILURE;
7697 }
7698 else {
7699 if(*pBufSize != pHddCtx->fw->size) {
7700 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Caller sets invalid CFG "
7701 "file size", __func__);
7702 release_firmware(pHddCtx->fw);
7703 pHddCtx->fw = NULL;
7704 return VOS_STATUS_E_FAILURE;
7705 }
7706 else {
7707 if(pBuffer) {
7708 vos_mem_copy(pBuffer,pHddCtx->fw->data,*pBufSize);
7709 }
7710 release_firmware(pHddCtx->fw);
7711 pHddCtx->fw = NULL;
7712 }
7713 }
7714
7715 EXIT();
7716
7717 return VOS_STATUS_SUCCESS;
7718}
7719
7720/**---------------------------------------------------------------------------
7721
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05307722 \brief __hdd_set_mac_address() -
Jeff Johnson295189b2012-06-20 16:38:30 -07007723
7724 This function sets the user specified mac address using
7725 the command ifconfig wlanX hw ether <mac adress>.
7726
7727 \param - dev - Pointer to the net device.
7728 - addr - Pointer to the sockaddr.
7729 \return - 0 for success, non zero for failure
7730
7731 --------------------------------------------------------------------------*/
7732
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05307733static int __hdd_set_mac_address(struct net_device *dev, void *addr)
Jeff Johnson295189b2012-06-20 16:38:30 -07007734{
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05307735 hdd_adapter_t *pAdapter;
7736 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07007737 struct sockaddr *psta_mac_addr = addr;
7738 eHalStatus halStatus = eHAL_STATUS_SUCCESS;
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05307739 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07007740
7741 ENTER();
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05307742 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
7743 if (NULL == pAdapter)
7744 {
7745 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7746 "%s: Adapter is NULL",__func__);
7747 return -EINVAL;
7748 }
7749 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7750 ret = wlan_hdd_validate_context(pHddCtx);
7751 if (0 != ret)
7752 {
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05307753 return ret;
7754 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007755
7756 memcpy(&pAdapter->macAddressCurrent, psta_mac_addr->sa_data, ETH_ALEN);
Jeff Johnson295189b2012-06-20 16:38:30 -07007757 memcpy(dev->dev_addr, psta_mac_addr->sa_data, ETH_ALEN);
7758
7759 EXIT();
7760 return halStatus;
7761}
7762
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05307763/**---------------------------------------------------------------------------
7764
7765 \brief hdd_set_mac_address() -
7766
7767 Wrapper function to protect __hdd_set_mac_address() function from ssr
7768
7769 \param - dev - Pointer to the net device.
7770 - addr - Pointer to the sockaddr.
7771 \return - 0 for success, non zero for failure
7772
7773 --------------------------------------------------------------------------*/
7774static int hdd_set_mac_address(struct net_device *dev, void *addr)
7775{
7776 int ret;
7777
7778 vos_ssr_protect(__func__);
7779 ret = __hdd_set_mac_address(dev, addr);
7780 vos_ssr_unprotect(__func__);
7781
7782 return ret;
7783}
7784
Jeff Johnson295189b2012-06-20 16:38:30 -07007785tANI_U8* wlan_hdd_get_intf_addr(hdd_context_t* pHddCtx)
7786{
7787 int i;
7788 for ( i = 0; i < VOS_MAX_CONCURRENCY_PERSONA; i++)
7789 {
Abhishek Singheb183782014-02-06 13:37:21 +05307790 if( 0 == ((pHddCtx->cfg_ini->intfAddrMask) & (1 << i)) )
Jeff Johnson295189b2012-06-20 16:38:30 -07007791 break;
7792 }
7793
7794 if( VOS_MAX_CONCURRENCY_PERSONA == i)
7795 return NULL;
7796
7797 pHddCtx->cfg_ini->intfAddrMask |= (1 << i);
7798 return &pHddCtx->cfg_ini->intfMacAddr[i].bytes[0];
7799}
7800
7801void wlan_hdd_release_intf_addr(hdd_context_t* pHddCtx, tANI_U8* releaseAddr)
7802{
7803 int i;
7804 for ( i = 0; i < VOS_MAX_CONCURRENCY_PERSONA; i++)
7805 {
7806 if ( !memcmp(releaseAddr, &pHddCtx->cfg_ini->intfMacAddr[i].bytes[0], 6) )
7807 {
7808 pHddCtx->cfg_ini->intfAddrMask &= ~(1 << i);
7809 break;
7810 }
7811 }
7812 return;
7813}
7814
7815#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29))
7816 static struct net_device_ops wlan_drv_ops = {
7817 .ndo_open = hdd_open,
7818 .ndo_stop = hdd_stop,
7819 .ndo_uninit = hdd_uninit,
7820 .ndo_start_xmit = hdd_hard_start_xmit,
7821 .ndo_tx_timeout = hdd_tx_timeout,
7822 .ndo_get_stats = hdd_stats,
7823 .ndo_do_ioctl = hdd_ioctl,
7824 .ndo_set_mac_address = hdd_set_mac_address,
7825 .ndo_select_queue = hdd_select_queue,
7826#ifdef WLAN_FEATURE_PACKET_FILTERING
7827#if (LINUX_VERSION_CODE > KERNEL_VERSION(3,1,0))
7828 .ndo_set_rx_mode = hdd_set_multicast_list,
7829#else
7830 .ndo_set_multicast_list = hdd_set_multicast_list,
7831#endif //LINUX_VERSION_CODE
7832#endif
7833 };
Jeff Johnson295189b2012-06-20 16:38:30 -07007834 static struct net_device_ops wlan_mon_drv_ops = {
7835 .ndo_open = hdd_mon_open,
Katya Nigame7b69a82015-04-28 15:24:06 +05307836 .ndo_stop = hdd_mon_stop,
Jeff Johnson295189b2012-06-20 16:38:30 -07007837 .ndo_uninit = hdd_uninit,
7838 .ndo_start_xmit = hdd_mon_hard_start_xmit,
7839 .ndo_tx_timeout = hdd_tx_timeout,
7840 .ndo_get_stats = hdd_stats,
Katya Nigame7b69a82015-04-28 15:24:06 +05307841 .ndo_do_ioctl = hdd_mon_ioctl,
Jeff Johnson295189b2012-06-20 16:38:30 -07007842 .ndo_set_mac_address = hdd_set_mac_address,
7843 };
Mahesh A Saptasagar305e2632015-03-04 12:57:33 +05307844
Jeff Johnson295189b2012-06-20 16:38:30 -07007845#endif
7846
7847void hdd_set_station_ops( struct net_device *pWlanDev )
7848{
7849#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29))
Jeff Johnson295189b2012-06-20 16:38:30 -07007850 pWlanDev->netdev_ops = &wlan_drv_ops;
7851#else
7852 pWlanDev->open = hdd_open;
7853 pWlanDev->stop = hdd_stop;
7854 pWlanDev->uninit = hdd_uninit;
7855 pWlanDev->hard_start_xmit = NULL;
7856 pWlanDev->tx_timeout = hdd_tx_timeout;
7857 pWlanDev->get_stats = hdd_stats;
7858 pWlanDev->do_ioctl = hdd_ioctl;
Jeff Johnson295189b2012-06-20 16:38:30 -07007859 pWlanDev->set_mac_address = hdd_set_mac_address;
7860#endif
7861}
7862
Katya Nigam1fd24402015-02-16 14:52:19 +05307863void hdd_set_ibss_ops( hdd_adapter_t *pAdapter )
7864{
7865 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29))
7866 wlan_drv_ops.ndo_start_xmit = hdd_ibss_hard_start_xmit;
7867 #else
7868 pAdapter->dev->hard_start_xmit = hdd_ibss_hard_start_xmit;
7869 #endif
7870}
7871
Jeff Johnsoneed415b2013-01-18 16:11:20 -08007872static hdd_adapter_t* hdd_alloc_station_adapter( hdd_context_t *pHddCtx, tSirMacAddr macAddr, const char* name )
Jeff Johnson295189b2012-06-20 16:38:30 -07007873{
7874 struct net_device *pWlanDev = NULL;
7875 hdd_adapter_t *pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07007876 /*
7877 * cfg80211 initialization and registration....
7878 */
Anand N Sunkadc34abbd2015-07-29 09:52:59 +05307879 pWlanDev = alloc_netdev_mq(sizeof( hdd_adapter_t ), name,
7880#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,17,0))
7881 NET_NAME_UNKNOWN,
7882#endif
7883 ether_setup, NUM_TX_QUEUES);
Jeff Johnson295189b2012-06-20 16:38:30 -07007884 if(pWlanDev != NULL)
7885 {
7886
7887 //Save the pointer to the net_device in the HDD adapter
7888 pAdapter = (hdd_adapter_t*) netdev_priv( pWlanDev );
7889
Jeff Johnson295189b2012-06-20 16:38:30 -07007890 vos_mem_zero( pAdapter, sizeof( hdd_adapter_t ) );
7891
7892 pAdapter->dev = pWlanDev;
7893 pAdapter->pHddCtx = pHddCtx;
7894 pAdapter->magic = WLAN_HDD_ADAPTER_MAGIC;
Agarwal Ashish47d18112014-08-04 19:55:07 +05307895 spin_lock_init(&pAdapter->lock_for_active_session);
Jeff Johnson295189b2012-06-20 16:38:30 -07007896
Rajeev79dbe4c2013-10-05 11:03:42 +05307897#ifdef FEATURE_WLAN_BATCH_SCAN
Rajeev79dbe4c2013-10-05 11:03:42 +05307898 pAdapter->pBatchScanRsp = NULL;
7899 pAdapter->numScanList = 0;
Rajeev Kumar20140c12013-10-21 19:39:02 -07007900 pAdapter->batchScanState = eHDD_BATCH_SCAN_STATE_STOPPED;
Kiet Lamaa8e15a2014-02-11 23:30:06 -08007901 pAdapter->prev_batch_id = 0;
Rajeev79dbe4c2013-10-05 11:03:42 +05307902 mutex_init(&pAdapter->hdd_batch_scan_lock);
7903#endif
7904
Jeff Johnson295189b2012-06-20 16:38:30 -07007905 pAdapter->isLinkUpSvcNeeded = FALSE;
7906 pAdapter->higherDtimTransition = eANI_BOOLEAN_TRUE;
7907 //Init the net_device structure
7908 strlcpy(pWlanDev->name, name, IFNAMSIZ);
7909
7910 vos_mem_copy(pWlanDev->dev_addr, (void *)macAddr, sizeof(tSirMacAddr));
7911 vos_mem_copy( pAdapter->macAddressCurrent.bytes, macAddr, sizeof(tSirMacAddr));
7912 pWlanDev->watchdog_timeo = HDD_TX_TIMEOUT;
7913 pWlanDev->hard_header_len += LIBRA_HW_NEEDED_HEADROOM;
7914
7915 hdd_set_station_ops( pAdapter->dev );
7916
7917 pWlanDev->destructor = free_netdev;
Jeff Johnson295189b2012-06-20 16:38:30 -07007918 pWlanDev->ieee80211_ptr = &pAdapter->wdev ;
7919 pAdapter->wdev.wiphy = pHddCtx->wiphy;
7920 pAdapter->wdev.netdev = pWlanDev;
Jeff Johnson295189b2012-06-20 16:38:30 -07007921 /* set pWlanDev's parent to underlying device */
7922 SET_NETDEV_DEV(pWlanDev, pHddCtx->parent_dev);
Kumar Anand82c009f2014-05-29 00:29:42 -07007923
7924 hdd_wmm_init( pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -07007925 }
7926
7927 return pAdapter;
7928}
7929
7930VOS_STATUS hdd_register_interface( hdd_adapter_t *pAdapter, tANI_U8 rtnl_lock_held )
7931{
7932 struct net_device *pWlanDev = pAdapter->dev;
7933 //hdd_station_ctx_t *pHddStaCtx = &pAdapter->sessionCtx.station;
7934 //hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
7935 //eHalStatus halStatus = eHAL_STATUS_SUCCESS;
7936
7937 if( rtnl_lock_held )
7938 {
Madan Mohan Koyyalamudid8ac8662012-11-06 19:04:56 -08007939 if (strnchr(pWlanDev->name, strlen(pWlanDev->name), '%')) {
Jeff Johnson295189b2012-06-20 16:38:30 -07007940 if( dev_alloc_name(pWlanDev, pWlanDev->name) < 0 )
7941 {
7942 hddLog(VOS_TRACE_LEVEL_ERROR,"%s:Failed:dev_alloc_name",__func__);
7943 return VOS_STATUS_E_FAILURE;
7944 }
7945 }
7946 if (register_netdevice(pWlanDev))
7947 {
7948 hddLog(VOS_TRACE_LEVEL_ERROR,"%s:Failed:register_netdev",__func__);
7949 return VOS_STATUS_E_FAILURE;
7950 }
7951 }
7952 else
7953 {
7954 if(register_netdev(pWlanDev))
7955 {
7956 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Failed:register_netdev",__func__);
7957 return VOS_STATUS_E_FAILURE;
7958 }
7959 }
7960 set_bit(NET_DEVICE_REGISTERED, &pAdapter->event_flags);
7961
7962 return VOS_STATUS_SUCCESS;
7963}
7964
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07007965static eHalStatus hdd_smeCloseSessionCallback(void *pContext)
Jeff Johnson295189b2012-06-20 16:38:30 -07007966{
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07007967 hdd_adapter_t *pAdapter = pContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07007968
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07007969 if (NULL == pAdapter)
7970 {
7971 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: NULL pAdapter", __func__);
7972 return eHAL_STATUS_INVALID_PARAMETER;
Jeff Johnson295189b2012-06-20 16:38:30 -07007973 }
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07007974
7975 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
7976 {
7977 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Invalid magic", __func__);
7978 return eHAL_STATUS_NOT_INITIALIZED;
7979 }
7980
7981 clear_bit(SME_SESSION_OPENED, &pAdapter->event_flags);
7982
Sameer Thalappilbee426e2013-10-30 10:30:30 -07007983#ifndef WLAN_OPEN_SOURCE
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07007984 /* need to make sure all of our scheduled work has completed.
7985 * This callback is called from MC thread context, so it is safe to
7986 * to call below flush workqueue API from here.
Sameer Thalappilbee426e2013-10-30 10:30:30 -07007987 *
7988 * Even though this is called from MC thread context, if there is a faulty
7989 * work item in the system, that can hang this call forever. So flushing
7990 * this global work queue is not safe; and now we make sure that
7991 * individual work queues are stopped correctly. But the cancel work queue
7992 * is a GPL only API, so the proprietary version of the driver would still
7993 * rely on the global work queue flush.
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07007994 */
7995 flush_scheduled_work();
Sameer Thalappilbee426e2013-10-30 10:30:30 -07007996#endif
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07007997
7998 /* We can be blocked while waiting for scheduled work to be
7999 * flushed, and the adapter structure can potentially be freed, in
8000 * which case the magic will have been reset. So make sure the
8001 * magic is still good, and hence the adapter structure is still
8002 * valid, before signaling completion */
8003 if (WLAN_HDD_ADAPTER_MAGIC == pAdapter->magic)
8004 {
8005 complete(&pAdapter->session_close_comp_var);
8006 }
8007
Jeff Johnson295189b2012-06-20 16:38:30 -07008008 return eHAL_STATUS_SUCCESS;
8009}
Manjeet Singh47ee8472016-04-11 11:57:18 +05308010/**
8011 * hdd_close_tx_queues() - close tx queues
8012 * @hdd_ctx: hdd global context
8013 *
8014 * Return: None
8015 */
8016static void hdd_close_tx_queues(hdd_context_t *hdd_ctx)
8017{
8018 VOS_STATUS status;
8019 hdd_adapter_t *adapter;
8020 hdd_adapter_list_node_t *adapter_node = NULL, *next_adapter = NULL;
8021 /* Not validating hdd_ctx as it's already done by the caller */
8022 ENTER();
8023 status = hdd_get_front_adapter(hdd_ctx, &adapter_node);
8024 while (NULL != adapter_node && VOS_STATUS_SUCCESS == status) {
8025 adapter = adapter_node->pAdapter;
8026 if (adapter && adapter->dev) {
8027 netif_tx_disable (adapter->dev);
8028 netif_carrier_off(adapter->dev);
8029 }
8030 status = hdd_get_next_adapter(hdd_ctx, adapter_node,
8031 &next_adapter);
8032 adapter_node = next_adapter;
8033 }
8034 EXIT();
8035}
Jeff Johnson295189b2012-06-20 16:38:30 -07008036
8037VOS_STATUS hdd_init_station_mode( hdd_adapter_t *pAdapter )
8038{
8039 struct net_device *pWlanDev = pAdapter->dev;
8040 hdd_station_ctx_t *pHddStaCtx = &pAdapter->sessionCtx.station;
8041 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
8042 eHalStatus halStatus = eHAL_STATUS_SUCCESS;
8043 VOS_STATUS status = VOS_STATUS_E_FAILURE;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308044 long rc = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07008045
Nirav Shah7e3c8132015-06-22 23:51:42 +05308046 spin_lock_init( &pAdapter->sta_hash_lock);
8047 pAdapter->is_sta_id_hash_initialized = VOS_FALSE;
8048
Jeff Johnson295189b2012-06-20 16:38:30 -07008049 INIT_COMPLETION(pAdapter->session_open_comp_var);
Kiran Kumar Lokere0ad5cd32013-06-25 11:26:22 -07008050 sme_SetCurrDeviceMode(pHddCtx->hHal, pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07008051 //Open a SME session for future operation
8052 halStatus = sme_OpenSession( pHddCtx->hHal, hdd_smeRoamCallback, pAdapter,
Kiran Kumar Lokere0ad5cd32013-06-25 11:26:22 -07008053 (tANI_U8 *)&pAdapter->macAddressCurrent, &pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07008054 if ( !HAL_STATUS_SUCCESS( halStatus ) )
8055 {
8056 hddLog(VOS_TRACE_LEVEL_FATAL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07008057 "sme_OpenSession() failed with status code %08d [x%08x]",
Jeff Johnson295189b2012-06-20 16:38:30 -07008058 halStatus, halStatus );
8059 status = VOS_STATUS_E_FAILURE;
8060 goto error_sme_open;
8061 }
8062
8063 //Block on a completion variable. Can't wait forever though.
Vinay Krishna Eranna0fe2e7c2014-04-09 21:32:08 +05308064 rc = wait_for_completion_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -07008065 &pAdapter->session_open_comp_var,
8066 msecs_to_jiffies(WLAN_WAIT_TIME_SESSIONOPENCLOSE));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308067 if (rc <= 0)
Jeff Johnson295189b2012-06-20 16:38:30 -07008068 {
8069 hddLog(VOS_TRACE_LEVEL_FATAL,
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308070 "Session is not opened within timeout period code %ld", rc );
Jeff Johnson295189b2012-06-20 16:38:30 -07008071 status = VOS_STATUS_E_FAILURE;
8072 goto error_sme_open;
8073 }
8074
8075 // Register wireless extensions
8076 if( eHAL_STATUS_SUCCESS != (halStatus = hdd_register_wext(pWlanDev)))
8077 {
8078 hddLog(VOS_TRACE_LEVEL_FATAL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07008079 "hdd_register_wext() failed with status code %08d [x%08x]",
Jeff Johnson295189b2012-06-20 16:38:30 -07008080 halStatus, halStatus );
8081 status = VOS_STATUS_E_FAILURE;
8082 goto error_register_wext;
8083 }
Katya Nigam1fd24402015-02-16 14:52:19 +05308084
Jeff Johnson295189b2012-06-20 16:38:30 -07008085 //Safe to register the hard_start_xmit function again
Katya Nigam1fd24402015-02-16 14:52:19 +05308086 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29))
8087 wlan_drv_ops.ndo_start_xmit = hdd_hard_start_xmit;
8088 #else
8089 pWlanDev->hard_start_xmit = hdd_hard_start_xmit;
8090 #endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008091
8092 //Set the Connection State to Not Connected
Abhishek Singhf4669da2014-05-26 15:07:49 +05308093 hddLog(VOS_TRACE_LEVEL_INFO,
8094 "%s: Set HDD connState to eConnectionState_NotConnected",
8095 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07008096 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
8097
8098 //Set the default operation channel
8099 pHddStaCtx->conn_info.operationChannel = pHddCtx->cfg_ini->OperatingChannel;
8100
8101 /* Make the default Auth Type as OPEN*/
8102 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_OPEN_SYSTEM;
8103
8104 if( VOS_STATUS_SUCCESS != ( status = hdd_init_tx_rx( pAdapter ) ) )
8105 {
8106 hddLog(VOS_TRACE_LEVEL_FATAL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07008107 "hdd_init_tx_rx() failed with status code %08d [x%08x]",
Jeff Johnson295189b2012-06-20 16:38:30 -07008108 status, status );
8109 goto error_init_txrx;
8110 }
8111
8112 set_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
8113
8114 if( VOS_STATUS_SUCCESS != ( status = hdd_wmm_adapter_init( pAdapter ) ) )
8115 {
8116 hddLog(VOS_TRACE_LEVEL_FATAL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07008117 "hdd_wmm_adapter_init() failed with status code %08d [x%08x]",
Jeff Johnson295189b2012-06-20 16:38:30 -07008118 status, status );
8119 goto error_wmm_init;
8120 }
8121
8122 set_bit(WMM_INIT_DONE, &pAdapter->event_flags);
8123
8124 return VOS_STATUS_SUCCESS;
8125
8126error_wmm_init:
8127 clear_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
8128 hdd_deinit_tx_rx(pAdapter);
8129error_init_txrx:
8130 hdd_UnregisterWext(pWlanDev);
8131error_register_wext:
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07008132 if (test_bit(SME_SESSION_OPENED, &pAdapter->event_flags))
Jeff Johnson295189b2012-06-20 16:38:30 -07008133 {
8134 INIT_COMPLETION(pAdapter->session_close_comp_var);
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07008135 if (eHAL_STATUS_SUCCESS == sme_CloseSession(pHddCtx->hHal,
Agrawal Ashish5a3522c2016-03-02 15:08:28 +05308136 pAdapter->sessionId, FALSE, VOS_TRUE,
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07008137 hdd_smeCloseSessionCallback, pAdapter))
Jeff Johnson295189b2012-06-20 16:38:30 -07008138 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308139 unsigned long rc;
8140
Jeff Johnson295189b2012-06-20 16:38:30 -07008141 //Block on a completion variable. Can't wait forever though.
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308142 rc = wait_for_completion_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -07008143 &pAdapter->session_close_comp_var,
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07008144 msecs_to_jiffies(WLAN_WAIT_TIME_SESSIONOPENCLOSE));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308145 if (rc <= 0)
8146 hddLog(VOS_TRACE_LEVEL_ERROR,
8147 FL("Session is not opened within timeout period code %ld"), rc);
Jeff Johnson295189b2012-06-20 16:38:30 -07008148 }
8149}
8150error_sme_open:
8151 return status;
8152}
8153
Jeff Johnson295189b2012-06-20 16:38:30 -07008154void hdd_cleanup_actionframe( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter )
8155{
8156 hdd_cfg80211_state_t *cfgState;
8157
8158 cfgState = WLAN_HDD_GET_CFG_STATE_PTR( pAdapter );
8159
8160 if( NULL != cfgState->buf )
8161 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308162 long rc;
Jeff Johnson295189b2012-06-20 16:38:30 -07008163 INIT_COMPLETION(pAdapter->tx_action_cnf_event);
8164 rc = wait_for_completion_interruptible_timeout(
8165 &pAdapter->tx_action_cnf_event,
8166 msecs_to_jiffies(ACTION_FRAME_TX_TIMEOUT));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308167 if (rc <= 0)
Jeff Johnson295189b2012-06-20 16:38:30 -07008168 {
Deepthi Gowri91b3e9c2015-08-25 13:14:58 +05308169 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8170 "%s ERROR: HDD Wait for Action Confirmation Failed!! %ld"
8171 , __func__, rc);
8172
8173 // Inform tx status as FAILURE to upper layer and free cfgState->buf
8174 hdd_sendActionCnf( pAdapter, FALSE );
Jeff Johnson295189b2012-06-20 16:38:30 -07008175 }
8176 }
8177 return;
8178}
Jeff Johnson295189b2012-06-20 16:38:30 -07008179
c_hpothu002231a2015-02-05 14:58:51 +05308180void hdd_deinit_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter, tANI_U8 rtnl_held )
Jeff Johnson295189b2012-06-20 16:38:30 -07008181{
8182 ENTER();
8183 switch ( pAdapter->device_mode )
8184 {
Katya Nigam1fd24402015-02-16 14:52:19 +05308185 case WLAN_HDD_IBSS:
8186 {
8187 if(test_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags))
8188 {
8189 hdd_ibss_deinit_tx_rx( pAdapter );
8190 clear_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
8191 }
8192 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008193 case WLAN_HDD_INFRA_STATION:
8194 case WLAN_HDD_P2P_CLIENT:
Jeff Johnsone7245742012-09-05 17:12:55 -07008195 case WLAN_HDD_P2P_DEVICE:
Jeff Johnson295189b2012-06-20 16:38:30 -07008196 {
8197 if(test_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags))
8198 {
8199 hdd_deinit_tx_rx( pAdapter );
8200 clear_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
8201 }
8202
8203 if(test_bit(WMM_INIT_DONE, &pAdapter->event_flags))
8204 {
8205 hdd_wmm_adapter_close( pAdapter );
8206 clear_bit(WMM_INIT_DONE, &pAdapter->event_flags);
8207 }
8208
Jeff Johnson295189b2012-06-20 16:38:30 -07008209 hdd_cleanup_actionframe(pHddCtx, pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07008210 break;
8211 }
8212
8213 case WLAN_HDD_SOFTAP:
8214 case WLAN_HDD_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07008215 {
Madan Mohan Koyyalamudi8c6dec82013-09-26 15:56:13 +05308216
8217 if (test_bit(WMM_INIT_DONE, &pAdapter->event_flags))
8218 {
8219 hdd_wmm_adapter_close( pAdapter );
8220 clear_bit(WMM_INIT_DONE, &pAdapter->event_flags);
8221 }
8222
Jeff Johnson295189b2012-06-20 16:38:30 -07008223 hdd_cleanup_actionframe(pHddCtx, pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07008224
c_hpothu002231a2015-02-05 14:58:51 +05308225 hdd_unregister_hostapd(pAdapter, rtnl_held);
Agrawal Ashisha0584d42016-09-29 13:03:45 +05308226 /* set con_mode to STA only when no SAP concurrency mode */
8227 if (!(hdd_get_concurrency_mode() & (VOS_SAP | VOS_P2P_GO)))
8228 hdd_set_conparam(0);
Jeff Johnson295189b2012-06-20 16:38:30 -07008229 break;
8230 }
8231
8232 case WLAN_HDD_MONITOR:
8233 {
Jeff Johnson295189b2012-06-20 16:38:30 -07008234 if(test_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags))
8235 {
8236 hdd_deinit_tx_rx( pAdapter );
8237 clear_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
8238 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008239 break;
8240 }
8241
8242
8243 default:
8244 break;
8245 }
8246
8247 EXIT();
8248}
8249
8250void hdd_cleanup_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter, tANI_U8 rtnl_held )
8251{
Mingcheng Zhu87f22fc2014-01-30 19:23:32 -08008252 struct net_device *pWlanDev = NULL;
Srinivas, Dasari693dfc52013-12-27 17:29:09 +05308253
8254 ENTER();
8255 if (NULL == pAdapter)
8256 {
8257 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8258 "%s: HDD adapter is Null", __func__);
8259 return;
8260 }
8261
8262 pWlanDev = pAdapter->dev;
Jeff Johnson295189b2012-06-20 16:38:30 -07008263
Rajeev79dbe4c2013-10-05 11:03:42 +05308264#ifdef FEATURE_WLAN_BATCH_SCAN
Srinivas, Dasari693dfc52013-12-27 17:29:09 +05308265 if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
8266 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Rajeev Kumarf999e582014-01-09 17:33:29 -08008267 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Srinivas, Dasari693dfc52013-12-27 17:29:09 +05308268 || (pAdapter->device_mode == WLAN_HDD_P2P_DEVICE)
8269 )
8270 {
Rajeev Kumarf999e582014-01-09 17:33:29 -08008271 if (pAdapter)
Rajeev79dbe4c2013-10-05 11:03:42 +05308272 {
Rajeev Kumarf999e582014-01-09 17:33:29 -08008273 if (eHDD_BATCH_SCAN_STATE_STARTED == pAdapter->batchScanState)
8274 {
8275 hdd_deinit_batch_scan(pAdapter);
8276 }
Rajeev79dbe4c2013-10-05 11:03:42 +05308277 }
Rajeev Kumarf999e582014-01-09 17:33:29 -08008278 }
Rajeev79dbe4c2013-10-05 11:03:42 +05308279#endif
8280
Jeff Johnson295189b2012-06-20 16:38:30 -07008281 if(test_bit(NET_DEVICE_REGISTERED, &pAdapter->event_flags)) {
8282 if( rtnl_held )
8283 {
8284 unregister_netdevice(pWlanDev);
8285 }
8286 else
8287 {
8288 unregister_netdev(pWlanDev);
8289 }
8290 // note that the pAdapter is no longer valid at this point
8291 // since the memory has been reclaimed
8292 }
8293
Srinivas, Dasari693dfc52013-12-27 17:29:09 +05308294 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07008295}
8296
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08008297void hdd_set_pwrparams(hdd_context_t *pHddCtx)
8298{
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05308299 VOS_STATUS status;
8300 hdd_adapter_t *pAdapter = NULL;
8301 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08008302
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05308303 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08008304
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05308305 /*loop through all adapters.*/
8306 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08008307 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05308308 pAdapter = pAdapterNode->pAdapter;
8309 if ( (WLAN_HDD_INFRA_STATION != pAdapter->device_mode)
8310 && (WLAN_HDD_P2P_CLIENT != pAdapter->device_mode) )
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08008311
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05308312 { // we skip this registration for modes other than STA and P2P client modes.
8313 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
8314 pAdapterNode = pNext;
8315 continue;
8316 }
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08008317
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05308318 //Apply Dynamic DTIM For P2P
8319 //Only if ignoreDynamicDtimInP2pMode is not set in ini
8320 if ((pHddCtx->cfg_ini->enableDynamicDTIM ||
8321 pHddCtx->cfg_ini->enableModulatedDTIM) &&
8322 ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
8323 ((WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) &&
8324 !(pHddCtx->cfg_ini->ignoreDynamicDtimInP2pMode))) &&
8325 (eANI_BOOLEAN_TRUE == pAdapter->higherDtimTransition) &&
8326 (eConnectionState_Associated ==
8327 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState) &&
8328 (pHddCtx->cfg_ini->fIsBmpsEnabled))
8329 {
8330 tSirSetPowerParamsReq powerRequest = { 0 };
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08008331
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05308332 powerRequest.uIgnoreDTIM = 1;
8333 powerRequest.uMaxLIModulatedDTIM = pHddCtx->cfg_ini->fMaxLIModulatedDTIM;
8334
8335 if (pHddCtx->cfg_ini->enableModulatedDTIM)
8336 {
8337 powerRequest.uDTIMPeriod = pHddCtx->cfg_ini->enableModulatedDTIM;
8338 powerRequest.uListenInterval = pHddCtx->hdd_actual_LI_value;
8339 }
8340 else
8341 {
8342 powerRequest.uListenInterval = pHddCtx->cfg_ini->enableDynamicDTIM;
8343 }
8344
8345 /* Update ignoreDTIM and ListedInterval in CFG to remain at the DTIM
8346 * specified during Enter/Exit BMPS when LCD off*/
8347 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IGNORE_DTIM, powerRequest.uIgnoreDTIM,
8348 NULL, eANI_BOOLEAN_FALSE);
8349 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_LISTEN_INTERVAL, powerRequest.uListenInterval,
8350 NULL, eANI_BOOLEAN_FALSE);
8351
8352 /* switch to the DTIM specified in cfg.ini */
8353 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Abhishek Singh1e390cf2015-10-27 13:45:17 +05308354 "Switch to DTIM %d Listen interval %d",
8355 powerRequest.uDTIMPeriod,
8356 powerRequest.uListenInterval);
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05308357 sme_SetPowerParams( pHddCtx->hHal, &powerRequest, TRUE);
8358 break;
8359
8360 }
8361
8362 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
8363 pAdapterNode = pNext;
8364 }
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08008365}
8366
8367void hdd_reset_pwrparams(hdd_context_t *pHddCtx)
8368{
8369 /*Switch back to DTIM 1*/
8370 tSirSetPowerParamsReq powerRequest = { 0 };
8371
8372 powerRequest.uIgnoreDTIM = pHddCtx->hdd_actual_ignore_DTIM_value;
8373 powerRequest.uListenInterval = pHddCtx->hdd_actual_LI_value;
Yue Mac24062f2013-05-13 17:01:29 -07008374 powerRequest.uMaxLIModulatedDTIM = pHddCtx->cfg_ini->fMaxLIModulatedDTIM;
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08008375
8376 /* Update ignoreDTIM and ListedInterval in CFG with default values */
8377 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IGNORE_DTIM, powerRequest.uIgnoreDTIM,
8378 NULL, eANI_BOOLEAN_FALSE);
8379 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_LISTEN_INTERVAL, powerRequest.uListenInterval,
8380 NULL, eANI_BOOLEAN_FALSE);
8381
8382 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8383 "Switch to DTIM%d",powerRequest.uListenInterval);
8384 sme_SetPowerParams( pHddCtx->hHal, &powerRequest, TRUE);
8385
8386}
8387
Jeff Johnson295189b2012-06-20 16:38:30 -07008388VOS_STATUS hdd_enable_bmps_imps(hdd_context_t *pHddCtx)
8389{
8390 VOS_STATUS status = VOS_STATUS_SUCCESS;
Sushant Kaushik4928e542014-12-29 15:25:54 +05308391 if (WLAN_HDD_IS_UNLOAD_IN_PROGRESS(pHddCtx))
8392 {
8393 hddLog( LOGE, FL("Wlan Unload in progress"));
8394 return VOS_STATUS_E_PERM;
8395 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008396 if(pHddCtx->cfg_ini->fIsBmpsEnabled)
8397 {
8398 sme_EnablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
8399 }
8400
8401 if(pHddCtx->cfg_ini->fIsAutoBmpsTimerEnabled)
8402 {
8403 sme_StartAutoBmpsTimer(pHddCtx->hHal);
8404 }
8405
8406 if (pHddCtx->cfg_ini->fIsImpsEnabled)
8407 {
8408 sme_EnablePowerSave (pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
8409 }
8410
8411 return status;
8412}
8413
8414VOS_STATUS hdd_disable_bmps_imps(hdd_context_t *pHddCtx, tANI_U8 session_type)
8415{
8416 hdd_adapter_t *pAdapter = NULL;
8417 eHalStatus halStatus;
8418 VOS_STATUS status = VOS_STATUS_E_INVAL;
8419 v_BOOL_t disableBmps = FALSE;
8420 v_BOOL_t disableImps = FALSE;
8421
8422 switch(session_type)
8423 {
8424 case WLAN_HDD_INFRA_STATION:
8425 case WLAN_HDD_SOFTAP:
Jeff Johnson295189b2012-06-20 16:38:30 -07008426 case WLAN_HDD_P2P_CLIENT:
8427 case WLAN_HDD_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07008428 //Exit BMPS -> Is Sta/P2P Client is already connected
8429 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION);
8430 if((NULL != pAdapter)&&
8431 hdd_connIsConnected( WLAN_HDD_GET_STATION_CTX_PTR(pAdapter)))
8432 {
8433 disableBmps = TRUE;
8434 }
8435
8436 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_CLIENT);
8437 if((NULL != pAdapter)&&
8438 hdd_connIsConnected( WLAN_HDD_GET_STATION_CTX_PTR(pAdapter)))
8439 {
8440 disableBmps = TRUE;
8441 }
8442
8443 //Exit both Bmps and Imps incase of Go/SAP Mode
8444 if((WLAN_HDD_SOFTAP == session_type) ||
8445 (WLAN_HDD_P2P_GO == session_type))
8446 {
8447 disableBmps = TRUE;
8448 disableImps = TRUE;
8449 }
8450
8451 if(TRUE == disableImps)
8452 {
8453 if (pHddCtx->cfg_ini->fIsImpsEnabled)
8454 {
8455 sme_DisablePowerSave (pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
8456 }
8457 }
8458
8459 if(TRUE == disableBmps)
8460 {
8461 if(pHddCtx->cfg_ini->fIsBmpsEnabled)
8462 {
8463 halStatus = sme_DisablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
8464
8465 if(eHAL_STATUS_SUCCESS != halStatus)
8466 {
8467 status = VOS_STATUS_E_FAILURE;
Arif Hussain6d2a3322013-11-17 19:50:10 -08008468 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Fail to Disable Power Save", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07008469 VOS_ASSERT(0);
8470 return status;
8471 }
8472 }
8473
8474 if(pHddCtx->cfg_ini->fIsAutoBmpsTimerEnabled)
8475 {
8476 halStatus = sme_StopAutoBmpsTimer(pHddCtx->hHal);
8477
8478 if(eHAL_STATUS_SUCCESS != halStatus)
8479 {
8480 status = VOS_STATUS_E_FAILURE;
Arif Hussain6d2a3322013-11-17 19:50:10 -08008481 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Fail to Stop Auto Bmps Timer", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07008482 VOS_ASSERT(0);
8483 return status;
8484 }
8485 }
8486 }
8487
8488 if((TRUE == disableBmps) ||
8489 (TRUE == disableImps))
8490 {
8491 /* Now, get the chip into Full Power now */
8492 INIT_COMPLETION(pHddCtx->full_pwr_comp_var);
8493 halStatus = sme_RequestFullPower(pHddCtx->hHal, hdd_full_pwr_cbk,
8494 pHddCtx, eSME_FULL_PWR_NEEDED_BY_HDD);
8495
8496 if(halStatus != eHAL_STATUS_SUCCESS)
8497 {
8498 if(halStatus == eHAL_STATUS_PMC_PENDING)
8499 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308500 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07008501 //Block on a completion variable. Can't wait forever though
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308502 ret = wait_for_completion_interruptible_timeout(
8503 &pHddCtx->full_pwr_comp_var,
8504 msecs_to_jiffies(1000));
8505 if (ret <= 0)
8506 {
8507 hddLog(VOS_TRACE_LEVEL_ERROR,
8508 "%s: wait on full_pwr_comp_var failed %ld",
8509 __func__, ret);
8510 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008511 }
8512 else
8513 {
8514 status = VOS_STATUS_E_FAILURE;
Arif Hussain6d2a3322013-11-17 19:50:10 -08008515 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Request for Full Power failed", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07008516 VOS_ASSERT(0);
8517 return status;
8518 }
8519 }
8520
8521 status = VOS_STATUS_SUCCESS;
8522 }
8523
8524 break;
8525 }
8526 return status;
8527}
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +05308528
8529void hdd_monPostMsgCb(tANI_U32 *magic, struct completion *cmpVar)
8530{
8531 if (magic == NULL || cmpVar == NULL) {
8532 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8533 FL("invalid arguments %p %p"), magic, cmpVar);
8534 return;
8535 }
8536 if (*magic != MON_MODE_MSG_MAGIC) {
8537 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8538 FL("maic: %x"), *magic);
8539 return;
8540 }
8541
8542 complete(cmpVar);
8543 return;
8544}
8545
Katya Nigame7b69a82015-04-28 15:24:06 +05308546void hdd_init_mon_mode (hdd_adapter_t *pAdapter)
8547 {
8548 hdd_mon_ctx_t *pMonCtx = NULL;
8549 pMonCtx = WLAN_HDD_GET_MONITOR_CTX_PTR(pAdapter);
8550
8551 pMonCtx->state = 0;
8552 pMonCtx->ChannelNo = 1;
8553 pMonCtx->ChannelBW = 20;
Katya Nigamd7d3a1f2015-06-11 14:04:24 +05308554 pMonCtx->crcCheckEnabled = 1;
8555 pMonCtx->typeSubtypeBitmap = 0xFFFF00000000;
8556 pMonCtx->is80211to803ConReq = 1;
Katya Nigame7b69a82015-04-28 15:24:06 +05308557 pMonCtx->numOfMacFilters = 0;
8558 }
8559
Jeff Johnson295189b2012-06-20 16:38:30 -07008560
8561hdd_adapter_t* hdd_open_adapter( hdd_context_t *pHddCtx, tANI_U8 session_type,
Jeff Johnsoneed415b2013-01-18 16:11:20 -08008562 const char *iface_name, tSirMacAddr macAddr,
Jeff Johnson295189b2012-06-20 16:38:30 -07008563 tANI_U8 rtnl_held )
8564{
8565 hdd_adapter_t *pAdapter = NULL;
8566 hdd_adapter_list_node_t *pHddAdapterNode = NULL;
8567 VOS_STATUS status = VOS_STATUS_E_FAILURE;
8568 VOS_STATUS exitbmpsStatus;
8569
Arif Hussain6d2a3322013-11-17 19:50:10 -08008570 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s iface =%s type = %d",__func__,iface_name,session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07008571
Nirav Shah436658f2014-02-28 17:05:45 +05308572 if(macAddr == NULL)
8573 {
8574 /* Not received valid macAddr */
8575 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8576 "%s:Unable to add virtual intf: Not able to get"
8577 "valid mac address",__func__);
8578 return NULL;
8579 }
8580
Jeff Johnson295189b2012-06-20 16:38:30 -07008581 //Disable BMPS incase of Concurrency
8582 exitbmpsStatus = hdd_disable_bmps_imps(pHddCtx, session_type);
8583
8584 if(VOS_STATUS_E_FAILURE == exitbmpsStatus)
8585 {
8586 //Fail to Exit BMPS
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308587 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Fail to Exit BMPS", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07008588 VOS_ASSERT(0);
8589 return NULL;
8590 }
8591
8592 switch(session_type)
8593 {
8594 case WLAN_HDD_INFRA_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -07008595 case WLAN_HDD_P2P_CLIENT:
Jeff Johnsone7245742012-09-05 17:12:55 -07008596 case WLAN_HDD_P2P_DEVICE:
Jeff Johnson295189b2012-06-20 16:38:30 -07008597 {
8598 pAdapter = hdd_alloc_station_adapter( pHddCtx, macAddr, iface_name );
8599
8600 if( NULL == pAdapter )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308601 {
8602 hddLog(VOS_TRACE_LEVEL_FATAL,
8603 FL("failed to allocate adapter for session %d"), session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07008604 return NULL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308605 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008606
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05308607#ifdef FEATURE_WLAN_TDLS
8608 /* A Mutex Lock is introduced while changing/initializing the mode to
8609 * protect the concurrent access for the Adapters by TDLS module.
8610 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05308611 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05308612#endif
8613
Jeff Johnsone7245742012-09-05 17:12:55 -07008614 pAdapter->wdev.iftype = (session_type == WLAN_HDD_P2P_CLIENT) ?
8615 NL80211_IFTYPE_P2P_CLIENT:
8616 NL80211_IFTYPE_STATION;
Jeff Johnson295189b2012-06-20 16:38:30 -07008617
Jeff Johnson295189b2012-06-20 16:38:30 -07008618 pAdapter->device_mode = session_type;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05308619#ifdef FEATURE_WLAN_TDLS
8620 mutex_unlock(&pHddCtx->tdls_lock);
8621#endif
Sunil Dutt66485cb2013-12-19 19:05:03 +05308622
Mahesh A Saptasagar67ab9222015-10-21 15:38:41 +05308623 hdd_initialize_adapter_common(pAdapter);
Sunil Dutt66485cb2013-12-19 19:05:03 +05308624 status = hdd_init_station_mode( pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -07008625 if( VOS_STATUS_SUCCESS != status )
8626 goto err_free_netdev;
8627
8628 status = hdd_register_interface( pAdapter, rtnl_held );
8629 if( VOS_STATUS_SUCCESS != status )
8630 {
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05308631#ifdef FEATURE_WLAN_TDLS
8632 mutex_lock(&pHddCtx->tdls_lock);
8633#endif
c_hpothu002231a2015-02-05 14:58:51 +05308634 hdd_deinit_adapter(pHddCtx, pAdapter, rtnl_held);
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05308635#ifdef FEATURE_WLAN_TDLS
8636 mutex_unlock(&pHddCtx->tdls_lock);
8637#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008638 goto err_free_netdev;
8639 }
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05308640
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +05308641 // Workqueue which gets scheduled in IPv4 notification callback.
Anand N Sunkaddc63c792015-06-03 14:33:24 +05308642 vos_init_work(&pAdapter->ipv4NotifierWorkQueue, hdd_ipv4_notifier_work_queue);
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +05308643
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05308644#ifdef WLAN_NS_OFFLOAD
8645 // Workqueue which gets scheduled in IPv6 notification callback.
Anand N Sunkaddc63c792015-06-03 14:33:24 +05308646 vos_init_work(&pAdapter->ipv6NotifierWorkQueue, hdd_ipv6_notifier_work_queue);
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05308647#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008648 //Stop the Interface TX queue.
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +05308649 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Jeff Johnson295189b2012-06-20 16:38:30 -07008650 netif_tx_disable(pAdapter->dev);
8651 //netif_tx_disable(pWlanDev);
8652 netif_carrier_off(pAdapter->dev);
8653
Ganesh Kondabattinibabfb492014-12-17 20:25:29 +05308654 if (WLAN_HDD_P2P_CLIENT == session_type ||
8655 WLAN_HDD_P2P_DEVICE == session_type)
8656 {
8657 /* Initialize the work queue to defer the
8658 * back to back RoC request */
Anand N Sunkaddc63c792015-06-03 14:33:24 +05308659 vos_init_delayed_work(&pAdapter->roc_work,
Ganesh Kondabattinibabfb492014-12-17 20:25:29 +05308660 hdd_p2p_roc_work_queue);
8661 }
8662
Jeff Johnson295189b2012-06-20 16:38:30 -07008663 break;
8664 }
8665
Jeff Johnson295189b2012-06-20 16:38:30 -07008666 case WLAN_HDD_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07008667 case WLAN_HDD_SOFTAP:
8668 {
8669 pAdapter = hdd_wlan_create_ap_dev( pHddCtx, macAddr, (tANI_U8 *)iface_name );
8670 if( NULL == pAdapter )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308671 {
8672 hddLog(VOS_TRACE_LEVEL_FATAL,
8673 FL("failed to allocate adapter for session %d"), session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07008674 return NULL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308675 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008676
Jeff Johnson295189b2012-06-20 16:38:30 -07008677 pAdapter->wdev.iftype = (session_type == WLAN_HDD_SOFTAP) ?
8678 NL80211_IFTYPE_AP:
8679 NL80211_IFTYPE_P2P_GO;
Jeff Johnson295189b2012-06-20 16:38:30 -07008680 pAdapter->device_mode = session_type;
8681
Mahesh A Saptasagar67ab9222015-10-21 15:38:41 +05308682 hdd_initialize_adapter_common(pAdapter);
Hanumanth Reddy Pothula15bc0fa2017-02-03 17:24:17 +05308683 status = hdd_init_ap_mode(pAdapter, false);
Jeff Johnson295189b2012-06-20 16:38:30 -07008684 if( VOS_STATUS_SUCCESS != status )
8685 goto err_free_netdev;
8686
Nirav Shah7e3c8132015-06-22 23:51:42 +05308687 status = hdd_sta_id_hash_attach(pAdapter);
8688 if (VOS_STATUS_SUCCESS != status)
8689 {
8690 hddLog(VOS_TRACE_LEVEL_FATAL,
8691 FL("failed to attach hash for session %d"), session_type);
8692 hdd_deinit_adapter(pHddCtx, pAdapter, rtnl_held);
8693 goto err_free_netdev;
8694 }
8695
Jeff Johnson295189b2012-06-20 16:38:30 -07008696 status = hdd_register_hostapd( pAdapter, rtnl_held );
8697 if( VOS_STATUS_SUCCESS != status )
8698 {
c_hpothu002231a2015-02-05 14:58:51 +05308699 hdd_deinit_adapter(pHddCtx, pAdapter, rtnl_held);
Jeff Johnson295189b2012-06-20 16:38:30 -07008700 goto err_free_netdev;
8701 }
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +05308702 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Jeff Johnson295189b2012-06-20 16:38:30 -07008703 netif_tx_disable(pAdapter->dev);
8704 netif_carrier_off(pAdapter->dev);
8705
8706 hdd_set_conparam( 1 );
Ganesh Kondabattinibabfb492014-12-17 20:25:29 +05308707
8708 if (WLAN_HDD_P2P_GO == session_type)
8709 {
8710 /* Initialize the work queue to
8711 * defer the back to back RoC request */
8712 INIT_DELAYED_WORK(&pAdapter->roc_work,
8713 hdd_p2p_roc_work_queue);
8714 }
Bhargav Shahd0715912015-10-01 18:17:37 +05308715
Jeff Johnson295189b2012-06-20 16:38:30 -07008716 break;
8717 }
8718 case WLAN_HDD_MONITOR:
8719 {
Jeff Johnson295189b2012-06-20 16:38:30 -07008720 pAdapter = hdd_alloc_station_adapter( pHddCtx, macAddr, iface_name );
8721 if( NULL == pAdapter )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308722 {
8723 hddLog(VOS_TRACE_LEVEL_FATAL,
8724 FL("failed to allocate adapter for session %d"), session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07008725 return NULL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308726 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008727
Katya Nigame7b69a82015-04-28 15:24:06 +05308728 // Register wireless extensions
8729 if( VOS_STATUS_SUCCESS != (status = hdd_register_wext(pAdapter->dev)))
8730 {
8731 hddLog(VOS_TRACE_LEVEL_FATAL,
8732 "hdd_register_wext() failed with status code %08d [x%08x]",
8733 status, status );
8734 status = VOS_STATUS_E_FAILURE;
8735 }
8736
Jeff Johnson295189b2012-06-20 16:38:30 -07008737 pAdapter->wdev.iftype = NL80211_IFTYPE_MONITOR;
8738 pAdapter->device_mode = session_type;
Jeff Johnson295189b2012-06-20 16:38:30 -07008739#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29)
8740 pAdapter->dev->netdev_ops = &wlan_mon_drv_ops;
8741#else
8742 pAdapter->dev->open = hdd_mon_open;
8743 pAdapter->dev->hard_start_xmit = hdd_mon_hard_start_xmit;
Katya Nigame7b69a82015-04-28 15:24:06 +05308744 pAdapter->dev->stop = hdd_mon_stop;
8745 pAdapter->dev->do_ioctl = hdd_mon_ioctl;
Jeff Johnson295189b2012-06-20 16:38:30 -07008746#endif
Katya Nigame7b69a82015-04-28 15:24:06 +05308747 status = hdd_register_interface( pAdapter, rtnl_held );
8748 hdd_init_mon_mode( pAdapter );
Mahesh A Saptasagar67ab9222015-10-21 15:38:41 +05308749 hdd_initialize_adapter_common(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07008750 hdd_init_tx_rx( pAdapter );
8751 set_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
Katya Nigame7b69a82015-04-28 15:24:06 +05308752 //Stop the Interface TX queue.
8753 netif_tx_disable(pAdapter->dev);
8754 netif_carrier_off(pAdapter->dev);
Jeff Johnson295189b2012-06-20 16:38:30 -07008755 }
8756 break;
Jeff Johnson295189b2012-06-20 16:38:30 -07008757 case WLAN_HDD_FTM:
8758 {
8759 pAdapter = hdd_alloc_station_adapter( pHddCtx, macAddr, iface_name );
8760
8761 if( NULL == pAdapter )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308762 {
8763 hddLog(VOS_TRACE_LEVEL_FATAL,
8764 FL("failed to allocate adapter for session %d"), session_type);
8765 return NULL;
8766 }
8767
Jeff Johnson295189b2012-06-20 16:38:30 -07008768 /* Assign NL80211_IFTYPE_STATION as interface type to resolve Kernel Warning
8769 * message while loading driver in FTM mode. */
8770 pAdapter->wdev.iftype = NL80211_IFTYPE_STATION;
8771 pAdapter->device_mode = session_type;
8772 status = hdd_register_interface( pAdapter, rtnl_held );
Madan Mohan Koyyalamudif89ac9f2013-09-19 16:58:12 +05308773
Mahesh A Saptasagar67ab9222015-10-21 15:38:41 +05308774 hdd_initialize_adapter_common(pAdapter);
Madan Mohan Koyyalamudif89ac9f2013-09-19 16:58:12 +05308775 hdd_init_tx_rx( pAdapter );
8776
8777 //Stop the Interface TX queue.
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +05308778 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Madan Mohan Koyyalamudif89ac9f2013-09-19 16:58:12 +05308779 netif_tx_disable(pAdapter->dev);
8780 netif_carrier_off(pAdapter->dev);
Jeff Johnson295189b2012-06-20 16:38:30 -07008781 }
8782 break;
Jeff Johnson295189b2012-06-20 16:38:30 -07008783 default:
8784 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308785 hddLog(VOS_TRACE_LEVEL_FATAL,"%s Invalid session type %d",
8786 __func__, session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07008787 VOS_ASSERT(0);
8788 return NULL;
8789 }
8790 }
8791
Jeff Johnson295189b2012-06-20 16:38:30 -07008792 if( VOS_STATUS_SUCCESS == status )
8793 {
Mahesh A Saptasagar67ab9222015-10-21 15:38:41 +05308794 //Add it to the hdd's session list.
Jeff Johnson295189b2012-06-20 16:38:30 -07008795 pHddAdapterNode = vos_mem_malloc( sizeof( hdd_adapter_list_node_t ) );
8796 if( NULL == pHddAdapterNode )
8797 {
8798 status = VOS_STATUS_E_NOMEM;
8799 }
8800 else
8801 {
8802 pHddAdapterNode->pAdapter = pAdapter;
8803 status = hdd_add_adapter_back ( pHddCtx,
8804 pHddAdapterNode );
8805 }
8806 }
8807
8808 if( VOS_STATUS_SUCCESS != status )
8809 {
8810 if( NULL != pAdapter )
8811 {
8812 hdd_cleanup_adapter( pHddCtx, pAdapter, rtnl_held );
8813 pAdapter = NULL;
8814 }
8815 if( NULL != pHddAdapterNode )
8816 {
8817 vos_mem_free( pHddAdapterNode );
8818 }
8819
8820 goto resume_bmps;
8821 }
8822
8823 if(VOS_STATUS_SUCCESS == status)
8824 {
8825 wlan_hdd_set_concurrency_mode(pHddCtx, session_type);
Madan Mohan Koyyalamudi96dd30d2012-10-05 17:24:51 -07008826 //Initialize the WoWL service
8827 if(!hdd_init_wowl(pAdapter))
8828 {
8829 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hdd_init_wowl failed",__func__);
8830 goto err_free_netdev;
8831 }
Manjeet Singh3ed79242017-01-11 19:04:32 +05308832 //Initialize the TSF capture data
8833 wlan_hdd_tsf_init(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07008834 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008835 return pAdapter;
8836
8837err_free_netdev:
8838 free_netdev(pAdapter->dev);
8839 wlan_hdd_release_intf_addr( pHddCtx,
8840 pAdapter->macAddressCurrent.bytes );
8841
8842resume_bmps:
8843 //If bmps disabled enable it
8844 if(VOS_STATUS_SUCCESS == exitbmpsStatus)
8845 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05308846 if (pHddCtx->hdd_wlan_suspended)
8847 {
8848 hdd_set_pwrparams(pHddCtx);
8849 }
8850 hdd_enable_bmps_imps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07008851 }
8852 return NULL;
8853}
8854
8855VOS_STATUS hdd_close_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter,
8856 tANI_U8 rtnl_held )
8857{
8858 hdd_adapter_list_node_t *pAdapterNode, *pCurrent, *pNext;
8859 VOS_STATUS status;
8860
8861 status = hdd_get_front_adapter ( pHddCtx, &pCurrent );
8862 if( VOS_STATUS_SUCCESS != status )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308863 {
8864 hddLog(VOS_TRACE_LEVEL_WARN,"%s: adapter list empty %d",
8865 __func__, status);
Jeff Johnson295189b2012-06-20 16:38:30 -07008866 return status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308867 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008868
8869 while ( pCurrent->pAdapter != pAdapter )
8870 {
8871 status = hdd_get_next_adapter ( pHddCtx, pCurrent, &pNext );
8872 if( VOS_STATUS_SUCCESS != status )
8873 break;
8874
8875 pCurrent = pNext;
8876 }
8877 pAdapterNode = pCurrent;
8878 if( VOS_STATUS_SUCCESS == status )
8879 {
8880 wlan_hdd_clear_concurrency_mode(pHddCtx, pAdapter->device_mode);
8881 hdd_cleanup_adapter( pHddCtx, pAdapterNode->pAdapter, rtnl_held );
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05308882
8883#ifdef FEATURE_WLAN_TDLS
8884
8885 /* A Mutex Lock is introduced while changing/initializing the mode to
8886 * protect the concurrent access for the Adapters by TDLS module.
8887 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05308888 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05308889#endif
8890
Jeff Johnson295189b2012-06-20 16:38:30 -07008891 hdd_remove_adapter( pHddCtx, pAdapterNode );
8892 vos_mem_free( pAdapterNode );
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08008893 pAdapterNode = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07008894
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05308895#ifdef FEATURE_WLAN_TDLS
8896 mutex_unlock(&pHddCtx->tdls_lock);
8897#endif
8898
Jeff Johnson295189b2012-06-20 16:38:30 -07008899
8900 /* If there is a single session of STA/P2P client, re-enable BMPS */
Agarwal Ashish51325b52014-06-16 16:50:49 +05308901 if ((!vos_concurrent_open_sessions_running()) &&
8902 ((pHddCtx->no_of_open_sessions[VOS_STA_MODE] >= 1) ||
8903 (pHddCtx->no_of_open_sessions[VOS_P2P_CLIENT_MODE] >= 1)))
Jeff Johnson295189b2012-06-20 16:38:30 -07008904 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05308905 if (pHddCtx->hdd_wlan_suspended)
8906 {
8907 hdd_set_pwrparams(pHddCtx);
8908 }
8909 hdd_enable_bmps_imps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07008910 }
8911
8912 return VOS_STATUS_SUCCESS;
8913 }
8914
8915 return VOS_STATUS_E_FAILURE;
8916}
8917
8918VOS_STATUS hdd_close_all_adapters( hdd_context_t *pHddCtx )
8919{
8920 hdd_adapter_list_node_t *pHddAdapterNode;
8921 VOS_STATUS status;
8922
8923 ENTER();
8924
8925 do
8926 {
8927 status = hdd_remove_front_adapter( pHddCtx, &pHddAdapterNode );
8928 if( pHddAdapterNode && VOS_STATUS_SUCCESS == status )
8929 {
8930 hdd_cleanup_adapter( pHddCtx, pHddAdapterNode->pAdapter, FALSE );
8931 vos_mem_free( pHddAdapterNode );
8932 }
8933 }while( NULL != pHddAdapterNode && VOS_STATUS_E_EMPTY != status );
8934
8935 EXIT();
8936
8937 return VOS_STATUS_SUCCESS;
8938}
8939
8940void wlan_hdd_reset_prob_rspies(hdd_adapter_t* pHostapdAdapter)
8941{
8942 v_U8_t addIE[1] = {0};
8943
8944 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
8945 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,(tANI_U8*)addIE, 0, NULL,
8946 eANI_BOOLEAN_FALSE) )
8947 {
8948 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08008949 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07008950 }
8951
8952 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
8953 WNI_CFG_PROBE_RSP_ADDNIE_DATA2, (tANI_U8*)addIE, 0, NULL,
8954 eANI_BOOLEAN_FALSE) )
8955 {
8956 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08008957 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07008958 }
8959
8960 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
8961 WNI_CFG_PROBE_RSP_ADDNIE_DATA3, (tANI_U8*)addIE, 0, NULL,
8962 eANI_BOOLEAN_FALSE) )
8963 {
8964 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08008965 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07008966 }
8967}
8968
Anurag Chouhan83026002016-12-13 22:46:21 +05308969VOS_STATUS hdd_cleanup_ap_events(hdd_adapter_t *adapter)
8970{
8971#ifdef DHCP_SERVER_OFFLOAD
8972 vos_event_destroy(&adapter->dhcp_status.vos_event);
8973#endif
Anurag Chouhan0b29de02016-12-16 13:18:40 +05308974#ifdef MDNS_OFFLOAD
8975 vos_event_destroy(&adapter->mdns_status.vos_event);
8976#endif
Anurag Chouhan83026002016-12-13 22:46:21 +05308977 return VOS_STATUS_SUCCESS;
8978}
8979
8980
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05308981VOS_STATUS hdd_stop_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter,
8982 const v_BOOL_t bCloseSession )
Jeff Johnson295189b2012-06-20 16:38:30 -07008983{
8984 eHalStatus halStatus = eHAL_STATUS_SUCCESS;
8985 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Kaushik, Sushant4975a572014-10-21 16:07:48 +05308986 hdd_scaninfo_t *pScanInfo = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07008987 union iwreq_data wrqu;
Kaushik, Sushant7005e372014-04-08 11:36:54 +05308988 v_U8_t retry = 0;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308989 long ret;
Nirav Shah7e3c8132015-06-22 23:51:42 +05308990 VOS_STATUS status;
Jeff Johnson295189b2012-06-20 16:38:30 -07008991
Anand N Sunkad26d71b92014-12-24 18:08:22 +05308992 if (pHddCtx->isLogpInProgress) {
8993 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8994 "%s:LOGP in Progress. Ignore!!!",__func__);
8995 return VOS_STATUS_E_FAILURE;
8996 }
8997
Jeff Johnson295189b2012-06-20 16:38:30 -07008998 ENTER();
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +05308999
Kaushik, Sushant4975a572014-10-21 16:07:48 +05309000 pScanInfo = &pHddCtx->scan_info;
Jeff Johnson295189b2012-06-20 16:38:30 -07009001 switch(pAdapter->device_mode)
9002 {
Nirav Shah0cf4d892015-11-05 16:27:27 +05309003 case WLAN_HDD_IBSS:
9004 if ( VOS_TRUE == bCloseSession )
9005 {
9006 status = hdd_sta_id_hash_detach(pAdapter);
9007 if (status != VOS_STATUS_SUCCESS)
9008 hddLog(VOS_TRACE_LEVEL_ERROR,
9009 FL("sta id hash detach failed"));
9010 }
9011
Jeff Johnson295189b2012-06-20 16:38:30 -07009012 case WLAN_HDD_INFRA_STATION:
9013 case WLAN_HDD_P2P_CLIENT:
Jeff Johnsone7245742012-09-05 17:12:55 -07009014 case WLAN_HDD_P2P_DEVICE:
Vinay Krishna Erannab09d3e72014-03-26 21:23:55 +05309015 {
9016 hdd_station_ctx_t *pstation = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Mahesh A Saptasagare4d05d42015-07-02 16:17:20 +05309017#ifdef FEATURE_WLAN_TDLS
9018 mutex_lock(&pHddCtx->tdls_lock);
9019 wlan_hdd_tdls_exit(pAdapter, TRUE);
9020 mutex_unlock(&pHddCtx->tdls_lock);
9021#endif
Vinay Krishna Erannab09d3e72014-03-26 21:23:55 +05309022 if( hdd_connIsConnected(pstation) ||
9023 (pstation->conn_info.connState == eConnectionState_Connecting) )
Jeff Johnson295189b2012-06-20 16:38:30 -07009024 {
Abhishek Singhe21a5212017-06-09 09:42:58 +05309025 /*
9026 * Indicate sme of disconnect so that in progress connection
9027 * or preauth can be aborted.
9028 */
9029 sme_abortConnection(WLAN_HDD_GET_HAL_CTX(pAdapter),
9030 pAdapter->sessionId);
Abhishek Singh99f17b82017-02-06 16:57:56 +05309031 INIT_COMPLETION(pAdapter->disconnect_comp_var);
Jeff Johnson295189b2012-06-20 16:38:30 -07009032 if (pWextState->roamProfile.BSSType == eCSR_BSS_TYPE_START_IBSS)
9033 halStatus = sme_RoamDisconnect(pHddCtx->hHal,
9034 pAdapter->sessionId,
9035 eCSR_DISCONNECT_REASON_IBSS_LEAVE);
9036 else
9037 halStatus = sme_RoamDisconnect(pHddCtx->hHal,
9038 pAdapter->sessionId,
9039 eCSR_DISCONNECT_REASON_UNSPECIFIED);
Abhishek Singh7b52ed52016-02-11 17:45:54 +05309040 /* Success implies disconnect command got queued up successfully
9041 * Or cmd not queued as scan for SSID is in progress
9042 */
9043 if((eHAL_STATUS_SUCCESS == halStatus) ||
9044 (eHAL_STATUS_CMD_NOT_QUEUED == halStatus))
Jeff Johnson295189b2012-06-20 16:38:30 -07009045 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309046 ret = wait_for_completion_interruptible_timeout(
9047 &pAdapter->disconnect_comp_var,
9048 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
Abhishek Singh7b52ed52016-02-11 17:45:54 +05309049 if (ret <= 0 &&
9050 (eHAL_STATUS_CMD_NOT_QUEUED != halStatus))
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309051 {
9052 hddLog(VOS_TRACE_LEVEL_ERROR,
9053 "%s: wait on disconnect_comp_var failed %ld",
9054 __func__, ret);
9055 }
9056 }
9057 else
9058 {
9059 hddLog(LOGE, "%s: failed to post disconnect event to SME",
9060 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009061 }
9062 memset(&wrqu, '\0', sizeof(wrqu));
9063 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
9064 memset(wrqu.ap_addr.sa_data,'\0',ETH_ALEN);
9065 wireless_send_event(pAdapter->dev, SIOCGIWAP, &wrqu, NULL);
9066 }
Vinay Krishna Erannab09d3e72014-03-26 21:23:55 +05309067 else if(pstation->conn_info.connState ==
9068 eConnectionState_Disconnecting)
9069 {
9070 ret = wait_for_completion_interruptible_timeout(
9071 &pAdapter->disconnect_comp_var,
9072 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
9073 if (ret <= 0)
9074 {
9075 hddLog(VOS_TRACE_LEVEL_ERROR,
9076 FL("wait on disconnect_comp_var failed %ld"), ret);
9077 }
9078 }
Sachin Ahuja27dd2402016-08-01 20:30:31 +05309079 if(pScanInfo != NULL && pHddCtx->scan_info.mScanPending)
Jeff Johnson295189b2012-06-20 16:38:30 -07009080 {
Mahesh A Saptasagar0b61dcc2016-02-15 14:23:38 +05309081 wlan_hdd_scan_abort(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07009082 }
Abhishek Singh3ac179b2015-09-21 10:01:34 +05309083 if ((pAdapter->device_mode != WLAN_HDD_INFRA_STATION) &&
9084 (pAdapter->device_mode != WLAN_HDD_IBSS))
Kaushik, Sushant7005e372014-04-08 11:36:54 +05309085 {
9086 while (pAdapter->is_roc_inprogress)
9087 {
9088 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9089 "%s: ROC in progress for session %d!!!",
9090 __func__, pAdapter->sessionId);
9091 // waiting for ROC to expire
9092 msleep(500);
9093 /* In GO present case , if retry exceeds 3,
9094 it means something went wrong. */
9095 if ( retry++ > MAX_WAIT_FOR_ROC_COMPLETION )
9096 {
9097 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9098 "%s: ROC completion is not received.!!!", __func__);
Deepthi Gowri70498252015-01-20 15:56:45 +05309099 if (eHAL_STATUS_SUCCESS !=
9100 sme_CancelRemainOnChannel( WLAN_HDD_GET_HAL_CTX( pAdapter),
9101 pAdapter->sessionId ))
9102 {
9103 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9104 FL("Failed to Cancel Remain on Channel"));
9105 }
Kaushik, Sushant7005e372014-04-08 11:36:54 +05309106 wait_for_completion_interruptible_timeout(
9107 &pAdapter->cancel_rem_on_chan_var,
9108 msecs_to_jiffies(WAIT_CANCEL_REM_CHAN));
9109 break;
9110 }
9111 }
Anand N Sunkaddc63c792015-06-03 14:33:24 +05309112 vos_flush_delayed_work(&pAdapter->roc_work);
Kaushik, Sushant7005e372014-04-08 11:36:54 +05309113 }
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05309114#ifdef WLAN_NS_OFFLOAD
Anand N Sunkaddc63c792015-06-03 14:33:24 +05309115 vos_flush_work(&pAdapter->ipv6NotifierWorkQueue);
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05309116#endif
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +05309117
Anand N Sunkaddc63c792015-06-03 14:33:24 +05309118 vos_flush_work(&pAdapter->ipv4NotifierWorkQueue);
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +05309119
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05309120 /* It is possible that the caller of this function does not
9121 * wish to close the session
9122 */
9123 if (VOS_TRUE == bCloseSession &&
9124 test_bit(SME_SESSION_OPENED, &pAdapter->event_flags))
Jeff Johnson295189b2012-06-20 16:38:30 -07009125 {
9126 INIT_COMPLETION(pAdapter->session_close_comp_var);
9127 if (eHAL_STATUS_SUCCESS ==
Agrawal Ashish5a3522c2016-03-02 15:08:28 +05309128 sme_CloseSession(pHddCtx->hHal, pAdapter->sessionId, FALSE,
9129 VOS_FALSE, hdd_smeCloseSessionCallback, pAdapter))
Jeff Johnson295189b2012-06-20 16:38:30 -07009130 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309131 unsigned long ret;
9132
Jeff Johnson295189b2012-06-20 16:38:30 -07009133 //Block on a completion variable. Can't wait forever though.
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309134 ret = wait_for_completion_timeout(
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05309135 &pAdapter->session_close_comp_var,
9136 msecs_to_jiffies(WLAN_WAIT_TIME_SESSIONOPENCLOSE));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309137 if ( 0 >= ret)
9138 {
9139 hddLog(LOGE, "%s: failure waiting for session_close_comp_var %ld",
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05309140 __func__, ret);
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309141 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009142 }
9143 }
Vinay Krishna Erannab09d3e72014-03-26 21:23:55 +05309144 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009145 break;
9146
9147 case WLAN_HDD_SOFTAP:
9148 case WLAN_HDD_P2P_GO:
Nirav Shah0cf4d892015-11-05 16:27:27 +05309149 if ( VOS_TRUE == bCloseSession )
9150 {
9151 status = hdd_sta_id_hash_detach(pAdapter);
9152 if (status != VOS_STATUS_SUCCESS)
9153 hddLog(VOS_TRACE_LEVEL_ERROR,
9154 FL("sta id hash detach failed"));
9155 }
9156
Jeff Johnson295189b2012-06-20 16:38:30 -07009157 //Any softap specific cleanup here...
Anurag Chouhan83026002016-12-13 22:46:21 +05309158 hdd_cleanup_ap_events(pAdapter);
Kaushik, Sushant7005e372014-04-08 11:36:54 +05309159 if (pAdapter->device_mode == WLAN_HDD_P2P_GO) {
9160 while (pAdapter->is_roc_inprogress) {
9161 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9162 "%s: ROC in progress for session %d!!!",
9163 __func__, pAdapter->sessionId);
9164 msleep(500);
9165 if ( retry++ > MAX_WAIT_FOR_ROC_COMPLETION ) {
9166 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9167 "%s: ROC completion is not received.!!!", __func__);
9168 WLANSAP_CancelRemainOnChannel(
9169 (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
9170 wait_for_completion_interruptible_timeout(
9171 &pAdapter->cancel_rem_on_chan_var,
9172 msecs_to_jiffies(WAIT_CANCEL_REM_CHAN));
9173 break;
9174 }
9175 }
Ganesh Kondabattinibabfb492014-12-17 20:25:29 +05309176
Anand N Sunkaddc63c792015-06-03 14:33:24 +05309177 vos_flush_delayed_work(&pAdapter->roc_work);
Kaushik, Sushant7005e372014-04-08 11:36:54 +05309178 }
Agrawal Ashish17ef5082016-10-17 18:33:21 +05309179#ifdef SAP_AUTH_OFFLOAD
9180 if (pHddCtx->cfg_ini->enable_sap_auth_offload)
9181 hdd_set_sap_auth_offload(pAdapter, FALSE);
9182#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009183 mutex_lock(&pHddCtx->sap_lock);
9184 if (test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
9185 {
9186 VOS_STATUS status;
9187 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
9188
9189 //Stop Bss.
9190 status = WLANSAP_StopBss(pHddCtx->pvosContext);
9191 if (VOS_IS_STATUS_SUCCESS(status))
9192 {
9193 hdd_hostapd_state_t *pHostapdState =
9194 WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
9195
9196 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
9197
9198 if (!VOS_IS_STATUS_SUCCESS(status))
9199 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309200 hddLog(LOGE, "%s: failure waiting for WLANSAP_StopBss %d",
9201 __func__, status);
Jeff Johnson295189b2012-06-20 16:38:30 -07009202 }
9203 }
9204 else
9205 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07009206 hddLog(LOGE, "%s: failure in WLANSAP_StopBss", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009207 }
9208 clear_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags);
Agarwal Ashish51325b52014-06-16 16:50:49 +05309209 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07009210
9211 if (eHAL_STATUS_FAILURE ==
9212 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG,
9213 0, NULL, eANI_BOOLEAN_FALSE))
9214 {
9215 hddLog(LOGE,
9216 "%s: Failed to set WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07009217 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009218 }
9219
9220 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt((WLAN_HDD_GET_CTX(pAdapter))->hHal,
9221 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
9222 eANI_BOOLEAN_FALSE) )
9223 {
9224 hddLog(LOGE,
9225 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
9226 }
9227
9228 // Reset WNI_CFG_PROBE_RSP Flags
9229 wlan_hdd_reset_prob_rspies(pAdapter);
9230 kfree(pAdapter->sessionCtx.ap.beacon);
9231 pAdapter->sessionCtx.ap.beacon = NULL;
9232 }
9233 mutex_unlock(&pHddCtx->sap_lock);
9234 break;
Sameer Thalappilbee426e2013-10-30 10:30:30 -07009235
Jeff Johnson295189b2012-06-20 16:38:30 -07009236 case WLAN_HDD_MONITOR:
9237 break;
Sameer Thalappilbee426e2013-10-30 10:30:30 -07009238
Jeff Johnson295189b2012-06-20 16:38:30 -07009239 default:
9240 break;
9241 }
9242
9243 EXIT();
9244 return VOS_STATUS_SUCCESS;
9245}
9246
Kapil Gupta137ef892016-12-13 19:38:00 +05309247/**
9248 * wlan_hdd_restart_sap() - to restart SAP in driver internally
9249 * @ap_adapter: - Pointer to SAP hdd_adapter_t structure
9250 *
9251 * wlan_hdd_restart_sap first delete SAP and do cleanup.
9252 * After that WLANSAP_StartBss start re-start process of SAP.
9253 *
9254 * Return: None
9255 */
9256static void wlan_hdd_restart_sap(hdd_adapter_t *ap_adapter)
9257{
9258 hdd_ap_ctx_t *pHddApCtx;
9259 hdd_hostapd_state_t *pHostapdState;
9260 VOS_STATUS vos_status;
9261 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(ap_adapter);
9262#ifdef CFG80211_DEL_STA_V2
9263 struct station_del_parameters delStaParams;
9264#endif
9265 tsap_Config_t *pConfig;
9266
9267 pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(ap_adapter);
9268 pConfig = &pHddApCtx->sapConfig;
9269
9270 mutex_lock(&pHddCtx->sap_lock);
9271 if (test_bit(SOFTAP_BSS_STARTED, &ap_adapter->event_flags)) {
9272#ifdef CFG80211_DEL_STA_V2
9273 delStaParams.mac = NULL;
9274 delStaParams.subtype = SIR_MAC_MGMT_DEAUTH >> 4;
9275 delStaParams.reason_code = eCsrForcedDeauthSta;
9276 wlan_hdd_cfg80211_del_station(ap_adapter->wdev.wiphy, ap_adapter->dev,
9277 &delStaParams);
9278#else
9279 wlan_hdd_cfg80211_del_station(ap_adapter->wdev.wiphy, ap_adapter->dev,
9280 NULL);
9281#endif
9282 hdd_cleanup_actionframe(pHddCtx, ap_adapter);
9283
9284 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(ap_adapter);
9285 vos_event_reset(&pHostapdState->vosEvent);
9286
9287 if (VOS_STATUS_SUCCESS == WLANSAP_StopBss(pHddCtx->pvosContext)) {
9288 vos_status = vos_wait_single_event(&pHostapdState->vosEvent,
9289 10000);
9290 if (!VOS_IS_STATUS_SUCCESS(vos_status)) {
9291 hddLog(LOGE, FL("SAP Stop Failed"));
9292 goto end;
9293 }
9294 }
9295 clear_bit(SOFTAP_BSS_STARTED, &ap_adapter->event_flags);
9296 wlan_hdd_decr_active_session(pHddCtx, ap_adapter->device_mode);
9297 hddLog(LOG1, FL("SAP Stop Success"));
9298
9299 if (0 != wlan_hdd_cfg80211_update_apies(ap_adapter)) {
9300 hddLog(LOGE, FL("SAP Not able to set AP IEs"));
9301 goto end;
9302 }
9303
9304 if (WLANSAP_StartBss(pHddCtx->pvosContext, hdd_hostapd_SAPEventCB,
9305 pConfig, (v_PVOID_t)ap_adapter->dev) != VOS_STATUS_SUCCESS) {
9306 hddLog(LOGE, FL("SAP Start Bss fail"));
9307 goto end;
9308 }
9309
9310 hddLog(LOG1, FL("Waiting for SAP to start"));
9311 vos_status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
9312 if (!VOS_IS_STATUS_SUCCESS(vos_status)) {
9313 hddLog(LOGE, FL("SAP Start failed"));
9314 goto end;
9315 }
9316 hddLog(LOG1, FL("SAP Start Success"));
9317 set_bit(SOFTAP_BSS_STARTED, &ap_adapter->event_flags);
9318 wlan_hdd_incr_active_session(pHddCtx, ap_adapter->device_mode);
9319 pHostapdState->bCommit = TRUE;
Anurag Chouhanb2951ae2017-03-12 13:41:35 +05309320 if (!VOS_IS_STATUS_SUCCESS(hdd_dhcp_mdns_offload(ap_adapter))) {
9321 hddLog(VOS_TRACE_LEVEL_ERROR, FL("DHCP/MDNS offload Failed!!"));
9322 vos_event_reset(&pHostapdState->vosEvent);
9323 if (VOS_STATUS_SUCCESS == WLANSAP_StopBss(pHddCtx->pvosContext)) {
9324 vos_status = vos_wait_single_event(&pHostapdState->vosEvent,
9325 10000);
9326 if (!VOS_IS_STATUS_SUCCESS(vos_status)) {
9327 hddLog(LOGE, FL("SAP Stop Failed"));
9328 goto end;
9329 }
9330 }
9331 }
Kapil Gupta137ef892016-12-13 19:38:00 +05309332 }
9333end:
9334 mutex_unlock(&pHddCtx->sap_lock);
9335 return;
9336}
9337
9338/**
9339 * __hdd_sap_restart_handle() - to handle restarting of SAP
9340 * @work: name of the work
9341 *
9342 * Purpose of this function is to trigger sap start. this function
9343 * will be called from workqueue.
9344 *
9345 * Return: void.
9346 */
9347static void __hdd_sap_restart_handle(struct work_struct *work)
9348{
9349 hdd_adapter_t *sap_adapter;
9350 hdd_context_t *hdd_ctx = container_of(work,
9351 hdd_context_t,
9352 sap_start_work);
9353 if (0 != wlan_hdd_validate_context(hdd_ctx)) {
9354 vos_ssr_unprotect(__func__);
9355 return;
9356 }
9357 sap_adapter = hdd_get_adapter(hdd_ctx,
9358 WLAN_HDD_SOFTAP);
9359 if (sap_adapter == NULL) {
9360 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9361 FL("sap_adapter is NULL"));
9362 vos_ssr_unprotect(__func__);
9363 return;
9364 }
9365
9366 if (hdd_ctx->is_ch_avoid_in_progress) {
9367 sap_adapter->sessionCtx.ap.sapConfig.channel = AUTO_CHANNEL_SELECT;
9368 wlan_hdd_restart_sap(sap_adapter);
9369 hdd_change_ch_avoidance_status(hdd_ctx, false);
9370 }
Agrawal Ashish574b3e62017-02-09 18:58:34 +05309371 if (hdd_ctx->cfg_ini->enable_sap_auth_offload)
9372 wlan_hdd_restart_sap(sap_adapter);
Kapil Gupta137ef892016-12-13 19:38:00 +05309373}
9374
9375/**
9376 * hdd_sap_restart_handle() - to handle restarting of SAP
9377 * @work: name of the work
9378 *
9379 * Purpose of this function is to trigger sap start. this function
9380 * will be called from workqueue.
9381 *
9382 * Return: void.
9383 */
9384static void hdd_sap_restart_handle(struct work_struct *work)
9385{
9386 vos_ssr_protect(__func__);
9387 __hdd_sap_restart_handle(work);
9388 vos_ssr_unprotect(__func__);
9389}
9390
9391
Jeff Johnson295189b2012-06-20 16:38:30 -07009392VOS_STATUS hdd_stop_all_adapters( hdd_context_t *pHddCtx )
9393{
9394 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
9395 VOS_STATUS status;
9396 hdd_adapter_t *pAdapter;
9397
9398 ENTER();
9399
9400 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
9401
9402 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
9403 {
9404 pAdapter = pAdapterNode->pAdapter;
Jeff Johnson295189b2012-06-20 16:38:30 -07009405
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05309406 hdd_stop_adapter( pHddCtx, pAdapter, VOS_TRUE );
Jeff Johnson295189b2012-06-20 16:38:30 -07009407
9408 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
9409 pAdapterNode = pNext;
9410 }
9411
9412 EXIT();
9413
9414 return VOS_STATUS_SUCCESS;
9415}
9416
Rajeev Kumarf999e582014-01-09 17:33:29 -08009417
9418#ifdef FEATURE_WLAN_BATCH_SCAN
9419/**---------------------------------------------------------------------------
9420
9421 \brief hdd_deinit_batch_scan () - This function cleans up batch scan data
9422 structures
9423
9424 \param - pAdapter Pointer to HDD adapter
9425
9426 \return - None
9427
9428 --------------------------------------------------------------------------*/
9429void hdd_deinit_batch_scan(hdd_adapter_t *pAdapter)
9430{
9431 tHddBatchScanRsp *pNode;
9432 tHddBatchScanRsp *pPrev;
9433
Siddharth Bhalb3e9b792014-02-24 15:14:16 +05309434 if (NULL == pAdapter)
Rajeev Kumarf999e582014-01-09 17:33:29 -08009435 {
Siddharth Bhalb3e9b792014-02-24 15:14:16 +05309436 hddLog(VOS_TRACE_LEVEL_ERROR,
9437 "%s: Adapter context is Null", __func__);
9438 return;
9439 }
9440
9441 pNode = pAdapter->pBatchScanRsp;
9442 while (pNode)
9443 {
9444 pPrev = pNode;
9445 pNode = pNode->pNext;
9446 vos_mem_free((v_VOID_t * )pPrev);
Rajeev Kumarf999e582014-01-09 17:33:29 -08009447 }
9448
9449 pAdapter->pBatchScanRsp = NULL;
9450 pAdapter->numScanList = 0;
9451 pAdapter->batchScanState = eHDD_BATCH_SCAN_STATE_STOPPED;
9452 pAdapter->prev_batch_id = 0;
9453
9454 return;
9455}
9456#endif
9457
9458
Jeff Johnson295189b2012-06-20 16:38:30 -07009459VOS_STATUS hdd_reset_all_adapters( hdd_context_t *pHddCtx )
9460{
9461 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
9462 VOS_STATUS status;
9463 hdd_adapter_t *pAdapter;
9464
9465 ENTER();
9466
9467 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
9468
9469 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
9470 {
9471 pAdapter = pAdapterNode->pAdapter;
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +05309472 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Jeff Johnson295189b2012-06-20 16:38:30 -07009473 netif_tx_disable(pAdapter->dev);
Hanumanth Reddy Pothulad864f312017-01-18 16:16:08 +05309474
9475 if (pHddCtx->cfg_ini->sap_internal_restart &&
9476 pAdapter->device_mode == WLAN_HDD_SOFTAP) {
9477 hddLog(LOG1, FL("driver supports sap restart"));
9478 vos_flush_work(&pHddCtx->sap_start_work);
9479 hdd_sap_indicate_disconnect_for_sta(pAdapter);
9480 hdd_cleanup_actionframe(pHddCtx, pAdapter);
Hanumanth Reddy Pothula15bc0fa2017-02-03 17:24:17 +05309481 hdd_softap_deinit_tx_rx(pAdapter, true);
9482 hdd_sap_destroy_timers(pAdapter);
Hanumanth Reddy Pothulad864f312017-01-18 16:16:08 +05309483 } else {
9484 netif_carrier_off(pAdapter->dev);
9485 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009486
Srinivas Girigowda66c05eb2013-07-14 13:06:01 -07009487 pAdapter->sessionCtx.station.hdd_ReassocScenario = VOS_FALSE;
9488
Jeff Johnson295189b2012-06-20 16:38:30 -07009489 hdd_deinit_tx_rx(pAdapter);
Agarwal Ashish6267caa2014-08-06 19:16:21 +05309490
Katya Nigam1fd24402015-02-16 14:52:19 +05309491 if(pAdapter->device_mode == WLAN_HDD_IBSS )
9492 hdd_ibss_deinit_tx_rx(pAdapter);
9493
Nirav Shah7e3c8132015-06-22 23:51:42 +05309494 status = hdd_sta_id_hash_detach(pAdapter);
9495 if (status != VOS_STATUS_SUCCESS)
9496 hddLog(VOS_TRACE_LEVEL_ERROR,
9497 FL("sta id hash detach failed for session id %d"),
9498 pAdapter->sessionId);
9499
Agarwal Ashish6267caa2014-08-06 19:16:21 +05309500 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
9501
Madan Mohan Koyyalamudi8c6dec82013-09-26 15:56:13 +05309502 if (test_bit(WMM_INIT_DONE, &pAdapter->event_flags))
9503 {
9504 hdd_wmm_adapter_close( pAdapter );
9505 clear_bit(WMM_INIT_DONE, &pAdapter->event_flags);
9506 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009507
Siddharth Bhal2db319d2014-12-03 12:37:18 +05309508 if (test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
9509 {
9510 clear_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags);
9511 }
9512
Rajeev Kumarf999e582014-01-09 17:33:29 -08009513#ifdef FEATURE_WLAN_BATCH_SCAN
9514 if (eHDD_BATCH_SCAN_STATE_STARTED == pAdapter->batchScanState)
9515 {
9516 hdd_deinit_batch_scan(pAdapter);
9517 }
9518#endif
9519
Mahesh A Saptasagarf5b8eff2015-01-31 01:07:07 +05309520#ifdef FEATURE_WLAN_TDLS
9521 mutex_lock(&pHddCtx->tdls_lock);
Pradeep Reddy POTTETI2d4d5c42015-03-03 14:34:19 +05309522 wlan_hdd_tdls_exit(pAdapter, TRUE);
Mahesh A Saptasagarf5b8eff2015-01-31 01:07:07 +05309523 mutex_unlock(&pHddCtx->tdls_lock);
9524#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009525 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
9526 pAdapterNode = pNext;
9527 }
9528
9529 EXIT();
9530
9531 return VOS_STATUS_SUCCESS;
9532}
9533
Abhishek Singhbbe0b2a2016-12-05 11:57:36 +05309534/**
Abhishek Singh5a597e62016-12-05 15:16:30 +05309535 * hdd_get_bss_entry() - Get the bss entry matching the chan, bssid and ssid
9536 * @wiphy: wiphy
9537 * @channel: channel of the BSS to find
9538 * @bssid: bssid of the BSS to find
9539 * @ssid: ssid of the BSS to find
9540 * @ssid_len: ssid len of of the BSS to find
9541 *
9542 * The API is a wrapper to get bss from kernel matching the chan,
9543 * bssid and ssid
9544 *
9545 * Return: Void
9546 */
9547#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 1, 0)) \
9548 && !defined(WITH_BACKPORTS) && !defined(IEEE80211_PRIVACY)
9549
9550struct cfg80211_bss* hdd_get_bss_entry(struct wiphy *wiphy,
9551 struct ieee80211_channel *channel,
9552 const u8 *bssid,
9553 const u8 *ssid, size_t ssid_len)
9554{
9555 return cfg80211_get_bss(wiphy, channel, bssid,
9556 ssid, ssid_len,
9557 WLAN_CAPABILITY_ESS,
9558 WLAN_CAPABILITY_ESS);
9559}
9560#else
9561struct cfg80211_bss* hdd_get_bss_entry(struct wiphy *wiphy,
9562 struct ieee80211_channel *channel,
9563 const u8 *bssid,
9564 const u8 *ssid, size_t ssid_len)
9565{
9566 return cfg80211_get_bss(wiphy, channel, bssid,
9567 ssid, ssid_len,
9568 IEEE80211_BSS_TYPE_ESS,
9569 IEEE80211_PRIVACY_ANY);
9570}
9571#endif
9572
9573/**
Abhishek Singhbbe0b2a2016-12-05 11:57:36 +05309574 * hdd_connect_result() - API to send connection status to supplicant
9575 * @dev: network device
9576 * @bssid: bssid to which we want to associate
9577 * @roam_info: information about connected bss
9578 * @req_ie: Request Information Element
9579 * @req_ie_len: len of the req IE
9580 * @resp_ie: Response IE
9581 * @resp_ie_len: len of ht response IE
9582 * @status: status
9583 * @gfp: Kernel Flag
9584 *
9585 * The API is a wrapper to send connection status to supplicant
9586 *
9587 * Return: Void
9588 */
9589#if defined CFG80211_CONNECT_BSS
9590void hdd_connect_result(struct net_device *dev,
9591 const u8 *bssid,
9592 tCsrRoamInfo *roam_info,
9593 const u8 *req_ie,
9594 size_t req_ie_len,
9595 const u8 *resp_ie,
9596 size_t resp_ie_len,
9597 u16 status,
9598 gfp_t gfp)
9599{
9600 hdd_adapter_t *padapter = (hdd_adapter_t *) netdev_priv(dev);
9601 struct cfg80211_bss *bss = NULL;
9602
9603 if (WLAN_STATUS_SUCCESS == status) {
9604 struct ieee80211_channel *chan;
9605 int freq;
9606 int chan_no = roam_info->pBssDesc->channelId;;
9607
9608 if (chan_no <= 14)
9609 freq = ieee80211_channel_to_frequency(chan_no,
9610 IEEE80211_BAND_2GHZ);
9611 else
9612 freq = ieee80211_channel_to_frequency(chan_no,
9613 IEEE80211_BAND_5GHZ);
9614
9615 chan = ieee80211_get_channel(padapter->wdev.wiphy, freq);
Abhishek Singh5a597e62016-12-05 15:16:30 +05309616 bss = hdd_get_bss_entry(padapter->wdev.wiphy,
9617 chan, bssid,
9618 roam_info->u.pConnectedProfile->SSID.ssId,
9619 roam_info->u.pConnectedProfile->SSID.length);
Abhishek Singhbbe0b2a2016-12-05 11:57:36 +05309620 }
9621
9622 cfg80211_connect_bss(dev, bssid, bss, req_ie, req_ie_len,
9623 resp_ie, resp_ie_len, status, gfp);
9624}
9625#else
9626void hdd_connect_result(struct net_device *dev,
9627 const u8 *bssid,
9628 tCsrRoamInfo *roam_info,
9629 const u8 *req_ie,
9630 size_t req_ie_len,
9631 const u8 * resp_ie,
9632 size_t resp_ie_len,
9633 u16 status,
9634 gfp_t gfp)
9635{
9636 cfg80211_connect_result(dev, bssid, req_ie, req_ie_len,
9637 resp_ie, resp_ie_len, status, gfp);
9638}
9639#endif
9640
Jeff Johnson295189b2012-06-20 16:38:30 -07009641VOS_STATUS hdd_start_all_adapters( hdd_context_t *pHddCtx )
9642{
9643 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
9644 VOS_STATUS status;
9645 hdd_adapter_t *pAdapter;
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05309646 eConnectionState connState;
Jeff Johnson295189b2012-06-20 16:38:30 -07009647
9648 ENTER();
9649
9650 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
9651
9652 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
9653 {
9654 pAdapter = pAdapterNode->pAdapter;
9655
Kumar Anand82c009f2014-05-29 00:29:42 -07009656 hdd_wmm_init( pAdapter );
9657
Jeff Johnson295189b2012-06-20 16:38:30 -07009658 switch(pAdapter->device_mode)
9659 {
9660 case WLAN_HDD_INFRA_STATION:
9661 case WLAN_HDD_P2P_CLIENT:
Jeff Johnsone7245742012-09-05 17:12:55 -07009662 case WLAN_HDD_P2P_DEVICE:
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05309663
9664 connState = (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState;
9665
Jeff Johnson295189b2012-06-20 16:38:30 -07009666 hdd_init_station_mode(pAdapter);
9667 /* Open the gates for HDD to receive Wext commands */
9668 pAdapter->isLinkUpSvcNeeded = FALSE;
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07009669 pHddCtx->scan_info.mScanPending = FALSE;
9670 pHddCtx->scan_info.waitScanResult = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07009671
9672 //Trigger the initial scan
Mukul Sharmae74e42c2015-08-06 23:55:49 +05309673 if (!pHddCtx->isLogpInProgress)
9674 hdd_wlan_initial_scan(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07009675
9676 //Indicate disconnect event to supplicant if associated previously
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05309677 if (eConnectionState_Associated == connState ||
9678 eConnectionState_IbssConnected == connState )
Jeff Johnson295189b2012-06-20 16:38:30 -07009679 {
9680 union iwreq_data wrqu;
9681 memset(&wrqu, '\0', sizeof(wrqu));
9682 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
9683 memset(wrqu.ap_addr.sa_data,'\0',ETH_ALEN);
9684 wireless_send_event(pAdapter->dev, SIOCGIWAP, &wrqu, NULL);
Srinivas Girigowda66c05eb2013-07-14 13:06:01 -07009685 pAdapter->sessionCtx.station.hdd_ReassocScenario = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07009686
Jeff Johnson295189b2012-06-20 16:38:30 -07009687 /* indicate disconnected event to nl80211 */
Mahesh A Saptasagar9ff4bcc2016-06-01 17:17:50 +05309688 wlan_hdd_cfg80211_indicate_disconnect(pAdapter->dev, false,
Mahesh A Saptasagarb5a15142016-05-25 11:27:43 +05309689 WLAN_REASON_UNSPECIFIED);
Jeff Johnson295189b2012-06-20 16:38:30 -07009690 }
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05309691 else if (eConnectionState_Connecting == connState)
9692 {
9693 /*
9694 * Indicate connect failure to supplicant if we were in the
9695 * process of connecting
9696 */
Abhishek Singhbbe0b2a2016-12-05 11:57:36 +05309697 hdd_connect_result(pAdapter->dev, NULL, NULL,
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05309698 NULL, 0, NULL, 0,
9699 WLAN_STATUS_ASSOC_DENIED_UNSPEC,
9700 GFP_KERNEL);
9701 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009702 break;
9703
9704 case WLAN_HDD_SOFTAP:
Hanumanth Reddy Pothulad864f312017-01-18 16:16:08 +05309705 if (pHddCtx->cfg_ini->sap_internal_restart) {
Hanumanth Reddy Pothula15bc0fa2017-02-03 17:24:17 +05309706 hdd_init_ap_mode(pAdapter, true);
Hanumanth Reddy Pothulad864f312017-01-18 16:16:08 +05309707 status = hdd_sta_id_hash_attach(pAdapter);
9708 if (VOS_STATUS_SUCCESS != status)
9709 {
9710 hddLog(VOS_TRACE_LEVEL_FATAL,
9711 FL("failed to attach hash for"));
9712 }
9713 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009714 break;
9715
9716 case WLAN_HDD_P2P_GO:
Sameer Thalappiledf0d792013-08-09 14:31:03 -07009717 hddLog(VOS_TRACE_LEVEL_ERROR, "%s [SSR] send stop ap to supplicant",
Jeff Johnson295189b2012-06-20 16:38:30 -07009718 __func__);
Sameer Thalappiledf0d792013-08-09 14:31:03 -07009719 cfg80211_ap_stopped(pAdapter->dev, GFP_KERNEL);
Jeff Johnson295189b2012-06-20 16:38:30 -07009720 break;
9721
9722 case WLAN_HDD_MONITOR:
9723 /* monitor interface start */
9724 break;
9725 default:
9726 break;
9727 }
9728
9729 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
9730 pAdapterNode = pNext;
9731 }
9732
9733 EXIT();
9734
9735 return VOS_STATUS_SUCCESS;
9736}
9737
9738VOS_STATUS hdd_reconnect_all_adapters( hdd_context_t *pHddCtx )
9739{
9740 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
9741 hdd_adapter_t *pAdapter;
9742 VOS_STATUS status;
9743 v_U32_t roamId;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309744 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07009745
9746 ENTER();
9747
9748 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
9749
9750 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
9751 {
9752 pAdapter = pAdapterNode->pAdapter;
9753
9754 if( (WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
9755 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
9756 {
9757 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
9758 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
9759
Abhishek Singhf4669da2014-05-26 15:07:49 +05309760 hddLog(VOS_TRACE_LEVEL_INFO,
9761 "%s: Set HDD connState to eConnectionState_NotConnected",
9762 __func__);
Ganesh Kondabattini04338412015-09-14 15:39:09 +05309763 spin_lock_bh(&pAdapter->lock_for_active_session);
9764 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState)
9765 {
9766 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
9767 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009768 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
Ganesh Kondabattini04338412015-09-14 15:39:09 +05309769 spin_unlock_bh(&pAdapter->lock_for_active_session);
Jeff Johnson295189b2012-06-20 16:38:30 -07009770 init_completion(&pAdapter->disconnect_comp_var);
9771 sme_RoamDisconnect(pHddCtx->hHal, pAdapter->sessionId,
9772 eCSR_DISCONNECT_REASON_UNSPECIFIED);
9773
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309774 ret = wait_for_completion_interruptible_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -07009775 &pAdapter->disconnect_comp_var,
9776 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309777 if (0 >= ret)
9778 hddLog(LOGE, "%s: failure waiting for disconnect_comp_var %ld",
9779 __func__, ret);
Jeff Johnson295189b2012-06-20 16:38:30 -07009780
9781 pWextState->roamProfile.csrPersona = pAdapter->device_mode;
9782 pHddCtx->isAmpAllowed = VOS_FALSE;
9783 sme_RoamConnect(pHddCtx->hHal,
9784 pAdapter->sessionId, &(pWextState->roamProfile),
9785 &roamId);
9786 }
9787
9788 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
9789 pAdapterNode = pNext;
9790 }
9791
9792 EXIT();
9793
9794 return VOS_STATUS_SUCCESS;
9795}
9796
Sudhir Sattayappa Kohalli90e4c752013-03-21 14:25:04 -07009797void hdd_dump_concurrency_info(hdd_context_t *pHddCtx)
9798{
9799 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
9800 VOS_STATUS status;
9801 hdd_adapter_t *pAdapter;
9802 hdd_station_ctx_t *pHddStaCtx;
9803 hdd_ap_ctx_t *pHddApCtx;
9804 hdd_hostapd_state_t * pHostapdState;
9805 tCsrBssid staBssid = { 0 }, p2pBssid = { 0 }, apBssid = { 0 };
9806 v_U8_t staChannel = 0, p2pChannel = 0, apChannel = 0;
9807 const char *p2pMode = "DEV";
9808 const char *ccMode = "Standalone";
Sudhir Sattayappa Kohalli90e4c752013-03-21 14:25:04 -07009809
9810 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
9811 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
9812 {
9813 pAdapter = pAdapterNode->pAdapter;
9814 switch (pAdapter->device_mode) {
9815 case WLAN_HDD_INFRA_STATION:
9816 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
9817 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState) {
9818 staChannel = pHddStaCtx->conn_info.operationChannel;
9819 memcpy(staBssid, pHddStaCtx->conn_info.bssId, sizeof(staBssid));
9820 }
9821 break;
9822 case WLAN_HDD_P2P_CLIENT:
9823 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
9824 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState) {
9825 p2pChannel = pHddStaCtx->conn_info.operationChannel;
9826 memcpy(p2pBssid, pHddStaCtx->conn_info.bssId, sizeof(p2pBssid));
9827 p2pMode = "CLI";
9828 }
9829 break;
9830 case WLAN_HDD_P2P_GO:
9831 pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
9832 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
9833 if (pHostapdState->bssState == BSS_START && pHostapdState->vosStatus==VOS_STATUS_SUCCESS) {
9834 p2pChannel = pHddApCtx->operatingChannel;
9835 memcpy(p2pBssid, pAdapter->macAddressCurrent.bytes, sizeof(p2pBssid));
9836 }
9837 p2pMode = "GO";
9838 break;
9839 case WLAN_HDD_SOFTAP:
9840 pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
9841 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
9842 if (pHostapdState->bssState == BSS_START && pHostapdState->vosStatus==VOS_STATUS_SUCCESS) {
9843 apChannel = pHddApCtx->operatingChannel;
9844 memcpy(apBssid, pAdapter->macAddressCurrent.bytes, sizeof(apBssid));
9845 }
9846 break;
9847 default:
9848 break;
9849 }
9850 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
9851 pAdapterNode = pNext;
9852 }
9853 if (staChannel > 0 && (apChannel > 0 || p2pChannel > 0)) {
9854 ccMode = (p2pChannel==staChannel||apChannel==staChannel) ? "SCC" : "MCC";
9855 }
SaidiReddy Yenugaa8b32f92016-07-27 19:29:18 +05309856 hddLog(VOS_TRACE_LEVEL_INFO, "wlan(%d) " MAC_ADDRESS_STR " %s",
Sudhir Sattayappa Kohalli90e4c752013-03-21 14:25:04 -07009857 staChannel, MAC_ADDR_ARRAY(staBssid), ccMode);
9858 if (p2pChannel > 0) {
Sushant Kaushikdc3184b2015-10-09 12:00:21 +05309859 hddLog(VOS_TRACE_LEVEL_ERROR, "p2p-%s(%d) " MAC_ADDRESS_STR,
Sudhir Sattayappa Kohalli90e4c752013-03-21 14:25:04 -07009860 p2pMode, p2pChannel, MAC_ADDR_ARRAY(p2pBssid));
9861 }
9862 if (apChannel > 0) {
Sushant Kaushikdc3184b2015-10-09 12:00:21 +05309863 hddLog(VOS_TRACE_LEVEL_ERROR, "AP(%d) " MAC_ADDRESS_STR,
Sudhir Sattayappa Kohalli90e4c752013-03-21 14:25:04 -07009864 apChannel, MAC_ADDR_ARRAY(apBssid));
9865 }
9866
9867 if (p2pChannel > 0 && apChannel > 0) {
9868 hddLog(VOS_TRACE_LEVEL_ERROR, "Error concurrent SAP %d and P2P %d which is not support", apChannel, p2pChannel);
9869 }
9870}
9871
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -07009872bool hdd_is_ssr_required( void)
Jeff Johnson295189b2012-06-20 16:38:30 -07009873{
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -07009874 return (isSsrRequired == HDD_SSR_REQUIRED);
Jeff Johnson295189b2012-06-20 16:38:30 -07009875}
9876
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -07009877/* Once SSR is disabled then it cannot be set. */
9878void hdd_set_ssr_required( e_hdd_ssr_required value)
Jeff Johnson295189b2012-06-20 16:38:30 -07009879{
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -07009880 if (HDD_SSR_DISABLED == isSsrRequired)
9881 return;
9882
Jeff Johnson295189b2012-06-20 16:38:30 -07009883 isSsrRequired = value;
9884}
9885
Hema Aparna Medicharla6b4d4f32015-06-23 04:09:12 +05309886void hdd_set_pre_close( hdd_context_t *pHddCtx)
9887{
9888 sme_PreClose(pHddCtx->hHal);
9889}
9890
Jeff Johnson295189b2012-06-20 16:38:30 -07009891VOS_STATUS hdd_get_front_adapter( hdd_context_t *pHddCtx,
9892 hdd_adapter_list_node_t** ppAdapterNode)
9893{
9894 VOS_STATUS status;
Mukul Sharmaae1266d2015-06-26 15:29:53 +05309895 spin_lock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07009896 status = hdd_list_peek_front ( &pHddCtx->hddAdapters,
9897 (hdd_list_node_t**) ppAdapterNode );
Mukul Sharmaae1266d2015-06-26 15:29:53 +05309898 spin_unlock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07009899 return status;
9900}
9901
9902VOS_STATUS hdd_get_next_adapter( hdd_context_t *pHddCtx,
9903 hdd_adapter_list_node_t* pAdapterNode,
9904 hdd_adapter_list_node_t** pNextAdapterNode)
9905{
9906 VOS_STATUS status;
Mukul Sharmaae1266d2015-06-26 15:29:53 +05309907 spin_lock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07009908 status = hdd_list_peek_next ( &pHddCtx->hddAdapters,
9909 (hdd_list_node_t*) pAdapterNode,
9910 (hdd_list_node_t**)pNextAdapterNode );
9911
Mukul Sharmaae1266d2015-06-26 15:29:53 +05309912 spin_unlock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07009913 return status;
9914}
9915
9916VOS_STATUS hdd_remove_adapter( hdd_context_t *pHddCtx,
9917 hdd_adapter_list_node_t* pAdapterNode)
9918{
9919 VOS_STATUS status;
Mukul Sharmaae1266d2015-06-26 15:29:53 +05309920 spin_lock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07009921 status = hdd_list_remove_node ( &pHddCtx->hddAdapters,
9922 &pAdapterNode->node );
Mukul Sharmaae1266d2015-06-26 15:29:53 +05309923 spin_unlock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07009924 return status;
9925}
9926
9927VOS_STATUS hdd_remove_front_adapter( hdd_context_t *pHddCtx,
9928 hdd_adapter_list_node_t** ppAdapterNode)
9929{
9930 VOS_STATUS status;
Mukul Sharmaae1266d2015-06-26 15:29:53 +05309931 spin_lock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07009932 status = hdd_list_remove_front( &pHddCtx->hddAdapters,
9933 (hdd_list_node_t**) ppAdapterNode );
Mukul Sharmaae1266d2015-06-26 15:29:53 +05309934 spin_unlock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07009935 return status;
9936}
9937
9938VOS_STATUS hdd_add_adapter_back( hdd_context_t *pHddCtx,
9939 hdd_adapter_list_node_t* pAdapterNode)
9940{
9941 VOS_STATUS status;
Mukul Sharmaae1266d2015-06-26 15:29:53 +05309942 spin_lock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07009943 status = hdd_list_insert_back ( &pHddCtx->hddAdapters,
9944 (hdd_list_node_t*) pAdapterNode );
Mukul Sharmaae1266d2015-06-26 15:29:53 +05309945 spin_unlock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07009946 return status;
9947}
9948
9949VOS_STATUS hdd_add_adapter_front( hdd_context_t *pHddCtx,
9950 hdd_adapter_list_node_t* pAdapterNode)
9951{
9952 VOS_STATUS status;
Mukul Sharmaae1266d2015-06-26 15:29:53 +05309953 spin_lock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07009954 status = hdd_list_insert_front ( &pHddCtx->hddAdapters,
9955 (hdd_list_node_t*) pAdapterNode );
Mukul Sharmaae1266d2015-06-26 15:29:53 +05309956 spin_unlock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07009957 return status;
9958}
9959
9960hdd_adapter_t * hdd_get_adapter_by_macaddr( hdd_context_t *pHddCtx,
9961 tSirMacAddr macAddr )
9962{
9963 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
9964 hdd_adapter_t *pAdapter;
9965 VOS_STATUS status;
9966
9967 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
9968
9969 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
9970 {
9971 pAdapter = pAdapterNode->pAdapter;
9972
9973 if( pAdapter && vos_mem_compare( pAdapter->macAddressCurrent.bytes,
9974 macAddr, sizeof(tSirMacAddr) ) )
9975 {
9976 return pAdapter;
9977 }
9978 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
9979 pAdapterNode = pNext;
9980 }
9981
9982 return NULL;
9983
9984}
9985
9986hdd_adapter_t * hdd_get_adapter_by_name( hdd_context_t *pHddCtx, tANI_U8 *name )
9987{
9988 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
9989 hdd_adapter_t *pAdapter;
9990 VOS_STATUS status;
9991
9992 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
9993
9994 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
9995 {
9996 pAdapter = pAdapterNode->pAdapter;
9997
9998 if( pAdapter && !strncmp( pAdapter->dev->name, (const char *)name,
9999 IFNAMSIZ ) )
10000 {
10001 return pAdapter;
10002 }
10003 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
10004 pAdapterNode = pNext;
10005 }
10006
10007 return NULL;
10008
10009}
10010
Ganesh Kondabattinicbfdc392015-09-11 19:12:59 +053010011hdd_adapter_t *hdd_get_adapter_by_sme_session_id( hdd_context_t *pHddCtx,
10012 tANI_U32 sme_session_id )
10013{
10014 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
10015 hdd_adapter_t *pAdapter;
10016 VOS_STATUS vos_status;
10017
10018
10019 vos_status = hdd_get_front_adapter( pHddCtx, &pAdapterNode);
10020
10021 while ((NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == vos_status))
10022 {
10023 pAdapter = pAdapterNode->pAdapter;
10024
10025 if (pAdapter->sessionId == sme_session_id)
10026 return pAdapter;
10027
10028 vos_status = hdd_get_next_adapter(pHddCtx, pAdapterNode, &pNext);
10029 pAdapterNode = pNext;
10030 }
10031
10032 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10033 "%s: sme_session_id %d does not exist with host",
10034 __func__, sme_session_id);
10035
10036 return NULL;
10037}
10038
Jeff Johnson295189b2012-06-20 16:38:30 -070010039hdd_adapter_t * hdd_get_adapter( hdd_context_t *pHddCtx, device_mode_t mode )
10040{
10041 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
10042 hdd_adapter_t *pAdapter;
10043 VOS_STATUS status;
10044
10045 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
10046
10047 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
10048 {
10049 pAdapter = pAdapterNode->pAdapter;
10050
10051 if( pAdapter && (mode == pAdapter->device_mode) )
10052 {
10053 return pAdapter;
10054 }
10055 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
10056 pAdapterNode = pNext;
10057 }
10058
10059 return NULL;
10060
10061}
10062
10063//Remove this function later
10064hdd_adapter_t * hdd_get_mon_adapter( hdd_context_t *pHddCtx )
10065{
10066 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
10067 hdd_adapter_t *pAdapter;
10068 VOS_STATUS status;
10069
10070 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
10071
10072 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
10073 {
10074 pAdapter = pAdapterNode->pAdapter;
10075
10076 if( pAdapter && WLAN_HDD_MONITOR == pAdapter->device_mode )
10077 {
10078 return pAdapter;
10079 }
10080
10081 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
10082 pAdapterNode = pNext;
10083 }
10084
10085 return NULL;
10086
10087}
10088
Jeff Johnson295189b2012-06-20 16:38:30 -070010089/**---------------------------------------------------------------------------
10090
Mahesh A Saptasgar64534612014-09-23 13:13:33 +053010091 \brief hdd_get_operating_channel() -
Jeff Johnson295189b2012-06-20 16:38:30 -070010092
10093 This API returns the operating channel of the requested device mode
10094
10095 \param - pHddCtx - Pointer to the HDD context.
10096 - mode - Device mode for which operating channel is required
10097 suported modes - WLAN_HDD_INFRA_STATION, WLAN_HDD_P2P_CLIENT
10098 WLAN_HDD_SOFTAP, WLAN_HDD_P2P_GO.
10099 \return - channel number. "0" id the requested device is not found OR it is not connected.
10100 --------------------------------------------------------------------------*/
10101v_U8_t hdd_get_operating_channel( hdd_context_t *pHddCtx, device_mode_t mode )
10102{
10103 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
10104 VOS_STATUS status;
10105 hdd_adapter_t *pAdapter;
10106 v_U8_t operatingChannel = 0;
10107
10108 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
10109
10110 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
10111 {
10112 pAdapter = pAdapterNode->pAdapter;
10113
10114 if( mode == pAdapter->device_mode )
10115 {
10116 switch(pAdapter->device_mode)
10117 {
10118 case WLAN_HDD_INFRA_STATION:
10119 case WLAN_HDD_P2P_CLIENT:
10120 if( hdd_connIsConnected( WLAN_HDD_GET_STATION_CTX_PTR( pAdapter )) )
10121 operatingChannel = (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.operationChannel;
10122 break;
10123 case WLAN_HDD_SOFTAP:
10124 case WLAN_HDD_P2P_GO:
10125 /*softap connection info */
10126 if(test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
10127 operatingChannel = (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->operatingChannel;
10128 break;
10129 default:
10130 break;
10131 }
10132
10133 break; //Found the device of interest. break the loop
10134 }
10135
10136 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
10137 pAdapterNode = pNext;
10138 }
10139 return operatingChannel;
10140}
10141
10142#ifdef WLAN_FEATURE_PACKET_FILTERING
10143/**---------------------------------------------------------------------------
10144
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053010145 \brief __hdd_set_multicast_list() -
Jeff Johnson295189b2012-06-20 16:38:30 -070010146
10147 This used to set the multicast address list.
10148
10149 \param - dev - Pointer to the WLAN device.
10150 - skb - Pointer to OS packet (sk_buff).
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053010151 \return - success/fail
Jeff Johnson295189b2012-06-20 16:38:30 -070010152
10153 --------------------------------------------------------------------------*/
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053010154static void __hdd_set_multicast_list(struct net_device *dev)
Jeff Johnson295189b2012-06-20 16:38:30 -070010155{
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053010156 hdd_adapter_t *pAdapter;
10157 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070010158 int mc_count;
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053010159 int i = 0, ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070010160 struct netdev_hw_addr *ha;
Gopichand Nakkala0f276812013-02-24 14:45:51 +053010161
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053010162 ENTER();
10163
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053010164 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkala0f276812013-02-24 14:45:51 +053010165 if (NULL == pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -070010166 {
10167 hddLog(VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala0f276812013-02-24 14:45:51 +053010168 "%s: Adapter context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070010169 return;
10170 }
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053010171 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
10172 ret = wlan_hdd_validate_context(pHddCtx);
10173 if (0 != ret)
10174 {
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053010175 return;
10176 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010177 if (dev->flags & IFF_ALLMULTI)
10178 {
10179 hddLog(VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070010180 "%s: allow all multicast frames", __func__);
Gopichand Nakkala0f276812013-02-24 14:45:51 +053010181 pAdapter->mc_addr_list.mc_cnt = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070010182 }
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053010183 else
Jeff Johnson295189b2012-06-20 16:38:30 -070010184 {
10185 mc_count = netdev_mc_count(dev);
10186 hddLog(VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070010187 "%s: mc_count = %u", __func__, mc_count);
Jeff Johnson295189b2012-06-20 16:38:30 -070010188 if (mc_count > WLAN_HDD_MAX_MC_ADDR_LIST)
10189 {
10190 hddLog(VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070010191 "%s: No free filter available; allow all multicast frames", __func__);
Gopichand Nakkala0f276812013-02-24 14:45:51 +053010192 pAdapter->mc_addr_list.mc_cnt = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070010193 return;
10194 }
10195
Gopichand Nakkala0f276812013-02-24 14:45:51 +053010196 pAdapter->mc_addr_list.mc_cnt = mc_count;
Jeff Johnson295189b2012-06-20 16:38:30 -070010197
10198 netdev_for_each_mc_addr(ha, dev) {
10199 if (i == mc_count)
10200 break;
Gopichand Nakkala0f276812013-02-24 14:45:51 +053010201 memset(&(pAdapter->mc_addr_list.addr[i][0]), 0, ETH_ALEN);
10202 memcpy(&(pAdapter->mc_addr_list.addr[i][0]), ha->addr, ETH_ALEN);
Arif Hussain6d2a3322013-11-17 19:50:10 -080010203 hddLog(VOS_TRACE_LEVEL_INFO, "%s: mlist[%d] = "MAC_ADDRESS_STR,
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053010204 __func__, i,
Gopichand Nakkala0f276812013-02-24 14:45:51 +053010205 MAC_ADDR_ARRAY(pAdapter->mc_addr_list.addr[i]));
Jeff Johnson295189b2012-06-20 16:38:30 -070010206 i++;
10207 }
10208 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053010209
Ganesh Kondabattinifb37e652015-10-09 15:46:47 +053010210 if (pHddCtx->hdd_wlan_suspended)
10211 {
10212 /*
10213 * Configure the Mcast address list to FW
10214 * If wlan is already in suspend mode
10215 */
10216 wlan_hdd_set_mc_addr_list(pAdapter, TRUE);
10217 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053010218 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070010219 return;
10220}
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053010221
10222static void hdd_set_multicast_list(struct net_device *dev)
10223{
10224 vos_ssr_protect(__func__);
10225 __hdd_set_multicast_list(dev);
10226 vos_ssr_unprotect(__func__);
10227}
Jeff Johnson295189b2012-06-20 16:38:30 -070010228#endif
10229
10230/**---------------------------------------------------------------------------
10231
10232 \brief hdd_select_queue() -
10233
10234 This function is registered with the Linux OS for network
10235 core to decide which queue to use first.
10236
10237 \param - dev - Pointer to the WLAN device.
10238 - skb - Pointer to OS packet (sk_buff).
10239 \return - ac, Queue Index/access category corresponding to UP in IP header
10240
10241 --------------------------------------------------------------------------*/
10242v_U16_t hdd_select_queue(struct net_device *dev,
Anand N Sunkade9adb1b2015-07-29 09:56:45 +053010243 struct sk_buff *skb
10244#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,13,0))
10245 , void *accel_priv
10246#endif
10247#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
10248 , select_queue_fallback_t fallback
10249#endif
10250)
Jeff Johnson295189b2012-06-20 16:38:30 -070010251{
10252 return hdd_wmm_select_queue(dev, skb);
10253}
10254
10255
10256/**---------------------------------------------------------------------------
10257
10258 \brief hdd_wlan_initial_scan() -
10259
10260 This function triggers the initial scan
10261
10262 \param - pAdapter - Pointer to the HDD adapter.
10263
10264 --------------------------------------------------------------------------*/
10265void hdd_wlan_initial_scan(hdd_adapter_t *pAdapter)
10266{
10267 tCsrScanRequest scanReq;
10268 tCsrChannelInfo channelInfo;
10269 eHalStatus halStatus;
Jeff Johnson02797792013-10-26 19:17:13 -070010270 tANI_U32 scanId;
Jeff Johnson295189b2012-06-20 16:38:30 -070010271 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
10272
10273 vos_mem_zero(&scanReq, sizeof(tCsrScanRequest));
10274 vos_mem_set(&scanReq.bssid, sizeof(tCsrBssid), 0xff);
10275 scanReq.BSSType = eCSR_BSS_TYPE_ANY;
10276
10277 if(sme_Is11dSupported(pHddCtx->hHal))
10278 {
10279 halStatus = sme_ScanGetBaseChannels( pHddCtx->hHal, &channelInfo );
10280 if ( HAL_STATUS_SUCCESS( halStatus ) )
10281 {
10282 scanReq.ChannelInfo.ChannelList = vos_mem_malloc(channelInfo.numOfChannels);
10283 if( !scanReq.ChannelInfo.ChannelList )
10284 {
10285 hddLog(VOS_TRACE_LEVEL_ERROR, "%s kmalloc failed", __func__);
10286 vos_mem_free(channelInfo.ChannelList);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -080010287 channelInfo.ChannelList = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070010288 return;
10289 }
10290 vos_mem_copy(scanReq.ChannelInfo.ChannelList, channelInfo.ChannelList,
10291 channelInfo.numOfChannels);
10292 scanReq.ChannelInfo.numOfChannels = channelInfo.numOfChannels;
10293 vos_mem_free(channelInfo.ChannelList);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -080010294 channelInfo.ChannelList = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070010295 }
10296
10297 scanReq.scanType = eSIR_PASSIVE_SCAN;
10298 scanReq.requestType = eCSR_SCAN_REQUEST_11D_SCAN;
10299 scanReq.maxChnTime = pHddCtx->cfg_ini->nPassiveMaxChnTime;
10300 scanReq.minChnTime = pHddCtx->cfg_ini->nPassiveMinChnTime;
10301 }
10302 else
10303 {
10304 scanReq.scanType = eSIR_ACTIVE_SCAN;
10305 scanReq.requestType = eCSR_SCAN_REQUEST_FULL_SCAN;
10306 scanReq.maxChnTime = pHddCtx->cfg_ini->nActiveMaxChnTime;
10307 scanReq.minChnTime = pHddCtx->cfg_ini->nActiveMinChnTime;
10308 }
10309
10310 halStatus = sme_ScanRequest(pHddCtx->hHal, pAdapter->sessionId, &scanReq, &scanId, NULL, NULL);
10311 if ( !HAL_STATUS_SUCCESS( halStatus ) )
10312 {
10313 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: sme_ScanRequest failed status code %d",
10314 __func__, halStatus );
10315 }
10316
10317 if(sme_Is11dSupported(pHddCtx->hHal))
10318 vos_mem_free(scanReq.ChannelInfo.ChannelList);
10319}
10320
Jeff Johnson295189b2012-06-20 16:38:30 -070010321/**---------------------------------------------------------------------------
10322
10323 \brief hdd_full_power_callback() - HDD full power callback function
10324
10325 This is the function invoked by SME to inform the result of a full power
10326 request issued by HDD
10327
10328 \param - callbackcontext - Pointer to cookie
10329 \param - status - result of request
10330
10331 \return - None
10332
10333 --------------------------------------------------------------------------*/
10334static void hdd_full_power_callback(void *callbackContext, eHalStatus status)
10335{
Jeff Johnson72a40512013-12-19 10:14:15 -080010336 struct statsContext *pContext = callbackContext;
Jeff Johnson295189b2012-06-20 16:38:30 -070010337
10338 hddLog(VOS_TRACE_LEVEL_INFO,
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +053010339 "%s: context = %p, status = %d", __func__, pContext, status);
Jeff Johnson295189b2012-06-20 16:38:30 -070010340
10341 if (NULL == callbackContext)
10342 {
10343 hddLog(VOS_TRACE_LEVEL_ERROR,
10344 "%s: Bad param, context [%p]",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070010345 __func__, callbackContext);
Jeff Johnson295189b2012-06-20 16:38:30 -070010346 return;
10347 }
10348
Jeff Johnson72a40512013-12-19 10:14:15 -080010349 /* there is a race condition that exists between this callback
10350 function and the caller since the caller could time out either
10351 before or while this code is executing. we use a spinlock to
10352 serialize these actions */
10353 spin_lock(&hdd_context_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -070010354
10355 if (POWER_CONTEXT_MAGIC != pContext->magic)
10356 {
10357 /* the caller presumably timed out so there is nothing we can do */
Jeff Johnson72a40512013-12-19 10:14:15 -080010358 spin_unlock(&hdd_context_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -070010359 hddLog(VOS_TRACE_LEVEL_WARN,
10360 "%s: Invalid context, magic [%08x]",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070010361 __func__, pContext->magic);
Jeff Johnson295189b2012-06-20 16:38:30 -070010362 return;
10363 }
10364
Jeff Johnson72a40512013-12-19 10:14:15 -080010365 /* context is valid so caller is still waiting */
10366
10367 /* paranoia: invalidate the magic */
10368 pContext->magic = 0;
10369
10370 /* notify the caller */
Jeff Johnson295189b2012-06-20 16:38:30 -070010371 complete(&pContext->completion);
Jeff Johnson72a40512013-12-19 10:14:15 -080010372
10373 /* serialization is complete */
10374 spin_unlock(&hdd_context_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -070010375}
10376
Katya Nigamf0511f62015-05-05 16:40:57 +053010377void wlan_hdd_mon_set_typesubtype( hdd_mon_ctx_t *pMonCtx,int type)
10378{
10379 pMonCtx->typeSubtypeBitmap = 0;
10380 if( type%10 ) /* Management Packets */
10381 pMonCtx->typeSubtypeBitmap |= 0xFFFF;
10382 type/=10;
10383 if( type%10 ) /* Control Packets */
10384 pMonCtx->typeSubtypeBitmap |= 0xFFFF0000;
10385 type/=10;
10386 if( type%10 ) /* Data Packets */
10387 pMonCtx->typeSubtypeBitmap |= 0xFFFF00000000;
10388}
10389
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +053010390VOS_STATUS wlan_hdd_mon_postMsg(tANI_U32 *magic, struct completion *cmpVar,
10391 hdd_mon_ctx_t *pMonCtx , void* callback)
Katya Nigamf0511f62015-05-05 16:40:57 +053010392{
10393 vos_msg_t monMsg;
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +053010394 tSirMonModeReq *pMonModeReq;
Katya Nigamf0511f62015-05-05 16:40:57 +053010395
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +053010396 if (MON_MODE_START == pMonCtx->state)
10397 monMsg.type = WDA_MON_START_REQ;
10398 else if (MON_MODE_STOP == pMonCtx->state)
10399 monMsg.type = WDA_MON_STOP_REQ;
10400 else {
10401 hddLog(VOS_TRACE_LEVEL_ERROR,
10402 FL("invalid monitor state %d"), pMonCtx->state);
Katya Nigamf0511f62015-05-05 16:40:57 +053010403 return VOS_STATUS_E_FAILURE;
10404 }
10405
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +053010406 pMonModeReq = vos_mem_malloc(sizeof(tSirMonModeReq));
10407 if (pMonModeReq == NULL) {
10408 hddLog(VOS_TRACE_LEVEL_ERROR,
10409 FL("fail to allocate memory for monitor mode req"));
10410 return VOS_STATUS_E_FAILURE;
10411 }
Katya Nigamf0511f62015-05-05 16:40:57 +053010412
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +053010413 pMonModeReq->magic = magic;
10414 pMonModeReq->cmpVar = cmpVar;
10415 pMonModeReq->data = pMonCtx;
10416 pMonModeReq->callback = callback;
Katya Nigamf0511f62015-05-05 16:40:57 +053010417
Katya Nigamf0511f62015-05-05 16:40:57 +053010418 monMsg.reserved = 0;
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +053010419 monMsg.bodyptr = pMonModeReq;
Katya Nigamf0511f62015-05-05 16:40:57 +053010420 monMsg.bodyval = 0;
10421
10422 if (VOS_STATUS_SUCCESS != vos_mq_post_message(
10423 VOS_MODULE_ID_WDA,(vos_msg_t *)&monMsg)) {
10424 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: : Failed to post Msg to HAL",__func__);
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +053010425 vos_mem_free(pMonModeReq);
Katya Nigamf0511f62015-05-05 16:40:57 +053010426 }
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +053010427 return VOS_STATUS_SUCCESS;
Katya Nigamf0511f62015-05-05 16:40:57 +053010428}
10429
Katya Nigame7b69a82015-04-28 15:24:06 +053010430void wlan_hdd_mon_close(hdd_context_t *pHddCtx)
10431{
10432 VOS_STATUS vosStatus;
10433 v_CONTEXT_t pVosContext = pHddCtx->pvosContext;
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +053010434 long ret;
10435 hdd_mon_ctx_t *pMonCtx = NULL;
10436 v_U32_t magic;
10437 struct completion cmpVar;
Hanumantha Reddy Pothulac99bc062015-09-08 14:59:26 +053010438
Katya Nigame7b69a82015-04-28 15:24:06 +053010439 hdd_adapter_t *pAdapter = hdd_get_adapter(pHddCtx,WLAN_HDD_MONITOR);
10440 if(pAdapter == NULL || pVosContext == NULL)
10441 {
10442 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, "%s:pAdapter is NULL",__func__);
10443 return ;
10444 }
Katya Nigamf0511f62015-05-05 16:40:57 +053010445
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +053010446 pMonCtx = WLAN_HDD_GET_MONITOR_CTX_PTR(pAdapter);
10447 if (pMonCtx!= NULL && pMonCtx->state == MON_MODE_START) {
10448 pMonCtx->state = MON_MODE_STOP;
10449 magic = MON_MODE_MSG_MAGIC;
10450 init_completion(&cmpVar);
10451 if (VOS_STATUS_SUCCESS !=
10452 wlan_hdd_mon_postMsg(&magic, &cmpVar,
10453 pMonCtx, hdd_monPostMsgCb)) {
10454 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10455 FL("failed to post MON MODE REQ"));
10456 pMonCtx->state = MON_MODE_START;
10457 magic = 0;
10458 return;
10459 }
10460 ret = wait_for_completion_timeout(&cmpVar, MON_MODE_MSG_TIMEOUT);
10461 magic = 0;
10462 if (ret <= 0 ) {
10463 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10464 FL("timeout on monitor mode completion %ld"), ret);
10465 }
10466 }
10467
Katya Nigame7b69a82015-04-28 15:24:06 +053010468 hdd_UnregisterWext(pAdapter->dev);
10469
10470 vos_mon_stop( pVosContext );
10471
10472 vosStatus = vos_sched_close( pVosContext );
10473 if (!VOS_IS_STATUS_SUCCESS(vosStatus)) {
10474 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
10475 "%s: Failed to close VOSS Scheduler",__func__);
10476 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
10477 }
10478
10479 vosStatus = vos_nv_close();
10480 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
10481 {
10482 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
10483 "%s: Failed to close NV", __func__);
10484 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
10485 }
10486
10487 vos_close(pVosContext);
10488
10489 #ifdef WLAN_KD_READY_NOTIFIER
10490 nl_srv_exit(pHddCtx->ptt_pid);
10491 #else
10492 nl_srv_exit();
10493 #endif
10494
Katya Nigame7b69a82015-04-28 15:24:06 +053010495 hdd_close_all_adapters( pHddCtx );
Katya Nigame7b69a82015-04-28 15:24:06 +053010496}
Agrawal Ashish33ec71e2015-11-26 20:20:58 +053010497/**
10498 * hdd_wlan_free_wiphy_channels - free Channel pointer for wiphy
10499 * @ wiphy: the wiphy to validate against
10500 *
10501 * Return: void
10502 */
10503void hdd_wlan_free_wiphy_channels(struct wiphy *wiphy)
10504{
10505 int i =0;
10506 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
10507 {
10508 if (NULL != wiphy->bands[i] &&
10509 (NULL != wiphy->bands[i]->channels))
10510 {
10511 vos_mem_free(wiphy->bands[i]->channels);
10512 wiphy->bands[i]->channels = NULL;
10513 }
10514 }
10515}
Jeff Johnson295189b2012-06-20 16:38:30 -070010516/**---------------------------------------------------------------------------
10517
10518 \brief hdd_wlan_exit() - HDD WLAN exit function
10519
10520 This is the driver exit point (invoked during rmmod)
10521
10522 \param - pHddCtx - Pointer to the HDD Context
10523
10524 \return - None
10525
10526 --------------------------------------------------------------------------*/
10527void hdd_wlan_exit(hdd_context_t *pHddCtx)
10528{
10529 eHalStatus halStatus;
10530 v_CONTEXT_t pVosContext = pHddCtx->pvosContext;
10531 VOS_STATUS vosStatus;
Gopichand Nakkala66923aa2013-03-06 23:17:24 +053010532 struct wiphy *wiphy = pHddCtx->wiphy;
Mingcheng Zhu87f22fc2014-01-30 19:23:32 -080010533 hdd_adapter_t* pAdapter = NULL;
Jeff Johnson72a40512013-12-19 10:14:15 -080010534 struct statsContext powerContext;
Jeff Johnson295189b2012-06-20 16:38:30 -070010535 long lrc;
c_hpothu5ab05e92014-06-13 17:34:05 +053010536 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070010537
10538 ENTER();
10539
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +053010540
Katya Nigame7b69a82015-04-28 15:24:06 +053010541 if (VOS_MONITOR_MODE == hdd_get_conparam())
10542 {
10543 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: MONITOR MODE",__func__);
10544 wlan_hdd_mon_close(pHddCtx);
Hanumantha Reddy Pothulac99bc062015-09-08 14:59:26 +053010545 goto free_hdd_ctx;
Katya Nigame7b69a82015-04-28 15:24:06 +053010546 }
10547 else if (VOS_FTM_MODE != hdd_get_conparam())
Jeff Johnson88ba7742013-02-27 14:36:02 -080010548 {
10549 // Unloading, restart logic is no more required.
10550 wlan_hdd_restart_deinit(pHddCtx);
Jeff Johnsone7245742012-09-05 17:12:55 -070010551
Agarwal Ashishb20e0ff2014-12-17 22:50:19 +053010552#ifdef FEATURE_WLAN_TDLS
10553 /* At the time of driver unloading; if tdls connection is present;
10554 * hdd_rx_packet_cbk calls wlan_hdd_tdls_find_peer.
10555 * wlan_hdd_tdls_find_peer always checks for valid context;
10556 * as load/unload in progress there can be a race condition.
10557 * hdd_rx_packet_cbk calls wlan_hdd_tdls_find_peer only
10558 * when tdls state is enabled.
10559 * As soon as driver set load/unload flag; tdls flag also needs
10560 * to be disabled so that hdd_rx_packet_cbk won't call
10561 * wlan_hdd_tdls_find_peer.
10562 */
Masti, Narayanraddi20494af2015-12-17 20:56:42 +053010563 wlan_hdd_tdls_set_mode(pHddCtx, eTDLS_SUPPORT_DISABLED, FALSE,
10564 HDD_SET_TDLS_MODE_SOURCE_USER);
Agarwal Ashishb20e0ff2014-12-17 22:50:19 +053010565#endif
10566
c_hpothu5ab05e92014-06-13 17:34:05 +053010567 vosStatus = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
10568 while (NULL != pAdapterNode && VOS_STATUS_E_EMPTY != vosStatus)
Jeff Johnson295189b2012-06-20 16:38:30 -070010569 {
c_hpothu5ab05e92014-06-13 17:34:05 +053010570 pAdapter = pAdapterNode->pAdapter;
10571 if (NULL != pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -070010572 {
Mahesh A Saptasagar305e2632015-03-04 12:57:33 +053010573 /* Disable TX on the interface, after this hard_start_xmit() will
10574 * not be called on that interface
10575 */
10576 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
10577 netif_tx_disable(pAdapter->dev);
10578
10579 /* Mark the interface status as "down" for outside world */
10580 netif_carrier_off(pAdapter->dev);
10581
Agarwal Ashish9ffa5b92014-11-18 21:07:02 +053010582 /* DeInit the adapter. This ensures that all data packets
10583 * are freed.
10584 */
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +053010585#ifdef FEATURE_WLAN_TDLS
10586 mutex_lock(&pHddCtx->tdls_lock);
10587#endif
c_hpothu002231a2015-02-05 14:58:51 +053010588 hdd_deinit_adapter(pHddCtx, pAdapter, FALSE);
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +053010589#ifdef FEATURE_WLAN_TDLS
10590 mutex_unlock(&pHddCtx->tdls_lock);
10591#endif
Masti, Narayanraddi26378462016-01-05 18:20:28 +053010592 vos_flush_delayed_work(&pHddCtx->scan_ctxt.scan_work);
10593
10594 wlan_hdd_init_deinit_defer_scan_context(&pHddCtx->scan_ctxt);
Agarwal Ashish9ffa5b92014-11-18 21:07:02 +053010595
c_hpothu5ab05e92014-06-13 17:34:05 +053010596 if (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
10597 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode)
10598 {
10599 wlan_hdd_cfg80211_deregister_frames(pAdapter);
10600 hdd_UnregisterWext(pAdapter->dev);
10601 }
Kaushik, Sushant4975a572014-10-21 16:07:48 +053010602
Jeff Johnson295189b2012-06-20 16:38:30 -070010603 }
c_hpothu5ab05e92014-06-13 17:34:05 +053010604 vosStatus = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
10605 pAdapterNode = pNext;
Jeff Johnson295189b2012-06-20 16:38:30 -070010606 }
mukul sharmabab477d2015-06-11 17:14:55 +053010607
Kaushik, Sushant4975a572014-10-21 16:07:48 +053010608 // Cancel any outstanding scan requests. We are about to close all
10609 // of our adapters, but an adapter structure is what SME passes back
10610 // to our callback function. Hence if there are any outstanding scan
10611 // requests then there is a race condition between when the adapter
10612 // is closed and when the callback is invoked.We try to resolve that
10613 // race condition here by canceling any outstanding scans before we
10614 // close the adapters.
10615 // Note that the scans may be cancelled in an asynchronous manner,
10616 // so ideally there needs to be some kind of synchronization. Rather
10617 // than introduce a new synchronization here, we will utilize the
10618 // fact that we are about to Request Full Power, and since that is
10619 // synchronized, the expectation is that by the time Request Full
10620 // Power has completed all scans will be cancelled.
10621 if (pHddCtx->scan_info.mScanPending)
10622 {
Hema Aparna Medicharlaf05f6cd2015-01-21 14:44:19 +053010623 if(NULL != pAdapter)
10624 {
10625 hddLog(VOS_TRACE_LEVEL_INFO,
10626 FL("abort scan mode: %d sessionId: %d"),
10627 pAdapter->device_mode,
10628 pAdapter->sessionId);
10629 }
10630 hdd_abort_mac_scan(pHddCtx,
10631 pHddCtx->scan_info.sessionId,
10632 eCSR_SCAN_ABORT_DEFAULT);
Kaushik, Sushant4975a572014-10-21 16:07:48 +053010633 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010634 }
c_hpothu5ab05e92014-06-13 17:34:05 +053010635 else
Jeff Johnson88ba7742013-02-27 14:36:02 -080010636 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010637 hddLog(VOS_TRACE_LEVEL_INFO,"%s: FTM MODE",__func__);
Hanumantha Reddy Pothula45af96b2015-02-12 16:07:58 +053010638 if (pHddCtx->ftm.ftm_state == WLAN_FTM_STARTING)
10639 {
10640 INIT_COMPLETION(pHddCtx->ftm.startCmpVar);
10641 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
10642 "%s: in middle of FTM START", __func__);
10643 lrc = wait_for_completion_timeout(&pHddCtx->ftm.startCmpVar,
10644 msecs_to_jiffies(20000));
10645 if(!lrc)
10646 {
10647 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
10648 "%s: timedout on ftmStartCmpVar fatal error", __func__);
10649 }
10650 }
Jeff Johnson88ba7742013-02-27 14:36:02 -080010651 wlan_hdd_ftm_close(pHddCtx);
10652 goto free_hdd_ctx;
10653 }
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010654
Jeff Johnson295189b2012-06-20 16:38:30 -070010655 /* DeRegister with platform driver as client for Suspend/Resume */
10656 vosStatus = hddDeregisterPmOps(pHddCtx);
10657 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
10658 {
10659 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddDeregisterPmOps failed",__func__);
10660 VOS_ASSERT(0);
10661 }
10662
10663 vosStatus = hddDevTmUnregisterNotifyCallback(pHddCtx);
10664 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
10665 {
10666 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddDevTmUnregisterNotifyCallback failed",__func__);
10667 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010668
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -070010669 //Stop the traffic monitor timer
Mahesh A Saptasagard461e432016-07-20 15:01:40 +053010670 if ((pHddCtx->cfg_ini->dynSplitscan) && (VOS_TIMER_STATE_RUNNING ==
10671 vos_timer_getCurrentState(&pHddCtx->tx_rx_trafficTmr)))
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -070010672 {
10673 vos_timer_stop(&pHddCtx->tx_rx_trafficTmr);
10674 }
10675
10676 // Destroy the traffic monitor timer
Mahesh A Saptasagard461e432016-07-20 15:01:40 +053010677 if ((pHddCtx->cfg_ini->dynSplitscan) &&
10678 (!VOS_IS_STATUS_SUCCESS(vos_timer_destroy(
10679 &pHddCtx->tx_rx_trafficTmr))))
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -070010680 {
10681 hddLog(VOS_TRACE_LEVEL_ERROR,
10682 "%s: Cannot deallocate Traffic monitor timer", __func__);
10683 }
10684
Bhargav Shahd0715912015-10-01 18:17:37 +053010685 if (VOS_TIMER_STATE_RUNNING ==
10686 vos_timer_getCurrentState(&pHddCtx->delack_timer)) {
10687 vos_timer_stop(&pHddCtx->delack_timer);
10688 }
10689
10690 if (!VOS_IS_STATUS_SUCCESS(vos_timer_destroy(
10691 &pHddCtx->delack_timer))) {
10692 hddLog(VOS_TRACE_LEVEL_ERROR,
10693 "%s: Cannot deallocate Bus bandwidth timer", __func__);
10694 }
10695
Masti, Narayanraddi44b0db02015-12-22 11:54:35 +053010696 if (VOS_TIMER_STATE_RUNNING ==
10697 vos_timer_getCurrentState(&pHddCtx->tdls_source_timer)) {
10698 vos_timer_stop(&pHddCtx->tdls_source_timer);
10699 }
10700
Abhishek Singh8a3e4dc2017-01-02 10:39:18 +053010701 vos_set_snoc_high_freq_voting(false);
10702
Masti, Narayanraddi44b0db02015-12-22 11:54:35 +053010703 vos_timer_destroy(&pHddCtx->tdls_source_timer);
10704
Jeff Johnson295189b2012-06-20 16:38:30 -070010705 //Disable IMPS/BMPS as we do not want the device to enter any power
10706 //save mode during shutdown
10707 sme_DisablePowerSave(pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
10708 sme_DisablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
10709 sme_DisablePowerSave(pHddCtx->hHal, ePMC_UAPSD_MODE_POWER_SAVE);
10710
10711 //Ensure that device is in full power as we will touch H/W during vos_Stop
10712 init_completion(&powerContext.completion);
10713 powerContext.magic = POWER_CONTEXT_MAGIC;
10714
10715 halStatus = sme_RequestFullPower(pHddCtx->hHal, hdd_full_power_callback,
10716 &powerContext, eSME_FULL_PWR_NEEDED_BY_HDD);
10717
10718 if (eHAL_STATUS_SUCCESS != halStatus)
10719 {
10720 if (eHAL_STATUS_PMC_PENDING == halStatus)
10721 {
10722 /* request was sent -- wait for the response */
10723 lrc = wait_for_completion_interruptible_timeout(
10724 &powerContext.completion,
10725 msecs_to_jiffies(WLAN_WAIT_TIME_POWER));
Jeff Johnson295189b2012-06-20 16:38:30 -070010726 if (lrc <= 0)
10727 {
10728 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: %s while requesting full power",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070010729 __func__, (0 == lrc) ? "timeout" : "interrupt");
Jeff Johnson295189b2012-06-20 16:38:30 -070010730 }
10731 }
10732 else
10733 {
10734 hddLog(VOS_TRACE_LEVEL_ERROR,
10735 "%s: Request for Full Power failed, status %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070010736 __func__, halStatus);
Jeff Johnson295189b2012-06-20 16:38:30 -070010737 /* continue -- need to clean up as much as possible */
10738 }
10739 }
Hanumantha Reddy Pothula81b42b22015-05-12 13:52:00 +053010740 if ((eHAL_STATUS_SUCCESS == halStatus) ||
10741 (eHAL_STATUS_PMC_PENDING == halStatus && lrc > 0))
10742 {
10743 /* This will issue a dump command which will clean up
10744 BTQM queues and unblock MC thread */
10745 vos_fwDumpReq(274, 0, 0, 0, 0, 1);
10746 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010747
Jeff Johnson72a40512013-12-19 10:14:15 -080010748 /* either we never sent a request, we sent a request and received a
10749 response or we sent a request and timed out. if we never sent a
10750 request or if we sent a request and got a response, we want to
10751 clear the magic out of paranoia. if we timed out there is a
10752 race condition such that the callback function could be
10753 executing at the same time we are. of primary concern is if the
10754 callback function had already verified the "magic" but had not
10755 yet set the completion variable when a timeout occurred. we
10756 serialize these activities by invalidating the magic while
10757 holding a shared spinlock which will cause us to block if the
10758 callback is currently executing */
10759 spin_lock(&hdd_context_lock);
10760 powerContext.magic = 0;
10761 spin_unlock(&hdd_context_lock);
10762
Hema Aparna Medicharlaa6cf65e2015-06-01 16:23:28 +053010763 /* If Device is shutdown, no point for SME to wait for responses
10764 from device. Pre Close SME */
10765 if(wcnss_device_is_shutdown())
10766 {
10767 sme_PreClose(pHddCtx->hHal);
10768 }
Yue Ma0d4891e2013-08-06 17:01:45 -070010769 hdd_debugfs_exit(pHddCtx);
10770
Ratheesh S P35ed8b12015-04-27 14:01:07 +053010771#ifdef WLAN_NS_OFFLOAD
Ratheesh S P36dbc932015-08-07 14:28:57 +053010772 hddLog(LOG1, FL("Unregister IPv6 notifier"));
Ratheesh S P35ed8b12015-04-27 14:01:07 +053010773 unregister_inet6addr_notifier(&pHddCtx->ipv6_notifier);
10774#endif
Ratheesh S P36dbc932015-08-07 14:28:57 +053010775 hddLog(LOG1, FL("Unregister IPv4 notifier"));
Ratheesh S P35ed8b12015-04-27 14:01:07 +053010776 unregister_inetaddr_notifier(&pHddCtx->ipv4_notifier);
10777
Jeff Johnson295189b2012-06-20 16:38:30 -070010778 // Unregister the Net Device Notifier
10779 unregister_netdevice_notifier(&hdd_netdev_notifier);
10780
Jeff Johnson295189b2012-06-20 16:38:30 -070010781 hdd_stop_all_adapters( pHddCtx );
10782
Jeff Johnson295189b2012-06-20 16:38:30 -070010783#ifdef WLAN_BTAMP_FEATURE
10784 vosStatus = WLANBAP_Stop(pVosContext);
10785 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
10786 {
10787 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
10788 "%s: Failed to stop BAP",__func__);
10789 }
10790#endif //WLAN_BTAMP_FEATURE
10791
10792 //Stop all the modules
10793 vosStatus = vos_stop( pVosContext );
10794 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
10795 {
10796 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
10797 "%s: Failed to stop VOSS",__func__);
10798 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
Hanumantha Reddy Pothulabd9601a2016-02-12 13:22:27 +053010799 if (isSsrPanicOnFailure())
10800 VOS_BUG(0);
Jeff Johnson295189b2012-06-20 16:38:30 -070010801 }
10802
Jeff Johnson295189b2012-06-20 16:38:30 -070010803 //This requires pMac access, Call this before vos_close().
Jeff Johnson295189b2012-06-20 16:38:30 -070010804 hdd_unregister_mcast_bcast_filter(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -070010805
10806 //Close the scheduler before calling vos_close to make sure no thread is
10807 // scheduled after the each module close is called i.e after all the data
10808 // structures are freed.
10809 vosStatus = vos_sched_close( pVosContext );
10810 if (!VOS_IS_STATUS_SUCCESS(vosStatus)) {
10811 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
10812 "%s: Failed to close VOSS Scheduler",__func__);
10813 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
10814 }
Jeff Johnsone7245742012-09-05 17:12:55 -070010815#ifdef WLAN_FEATURE_HOLD_RX_WAKELOCK
10816 /* Destroy the wake lock */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053010817 vos_wake_lock_destroy(&pHddCtx->rx_wake_lock);
Jeff Johnsone7245742012-09-05 17:12:55 -070010818#endif
Madan Mohan Koyyalamudi69fc3ad2012-11-28 16:04:56 -080010819 /* Destroy the wake lock */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053010820 vos_wake_lock_destroy(&pHddCtx->sap_wake_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -070010821
Mihir Shete7a24b5f2013-12-21 12:18:31 +053010822#ifdef CONFIG_ENABLE_LINUX_REG
10823 vosStatus = vos_nv_close();
10824 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
10825 {
10826 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
10827 "%s: Failed to close NV", __func__);
10828 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
10829 }
10830#endif
10831
Jeff Johnson295189b2012-06-20 16:38:30 -070010832 //Close VOSS
10833 //This frees pMac(HAL) context. There should not be any call that requires pMac access after this.
10834 vos_close(pVosContext);
10835
Jeff Johnson295189b2012-06-20 16:38:30 -070010836 //Close Watchdog
10837 if(pHddCtx->cfg_ini->fIsLogpEnabled)
10838 vos_watchdog_close(pVosContext);
10839
Gopichand Nakkalaa0358482013-06-12 17:05:47 +053010840 //Clean up HDD Nlink Service
10841 send_btc_nlink_msg(WLAN_MODULE_DOWN_IND, 0);
Gopichand Nakkalaa0358482013-06-12 17:05:47 +053010842
Manjeet Singh47ee8472016-04-11 11:57:18 +053010843 hdd_close_tx_queues(pHddCtx);
c_manjeecfd1efb2015-09-25 19:32:34 +053010844 wlan_free_fwr_mem_dump_buffer();
10845 memdump_deinit();
10846
Vinay Krishna Erannad938c422014-03-10 17:14:21 +053010847#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +053010848 if (pHddCtx->cfg_ini->wlanLoggingEnable)
Vinay Krishna Erannad938c422014-03-10 17:14:21 +053010849 {
10850 wlan_logging_sock_deactivate_svc();
10851 }
10852#endif
10853
Vinay Krishna Erannaef30b522014-08-26 17:48:16 +053010854#ifdef WLAN_KD_READY_NOTIFIER
10855 nl_srv_exit(pHddCtx->ptt_pid);
10856#else
10857 nl_srv_exit();
10858#endif /* WLAN_KD_READY_NOTIFIER */
10859
Abhishek Singh00b71972016-01-07 10:51:04 +053010860#ifdef WLAN_FEATURE_RMC
10861 hdd_close_cesium_nl_sock();
10862#endif /* WLAN_FEATURE_RMC */
Vinay Krishna Erannaef30b522014-08-26 17:48:16 +053010863
Jeff Johnson295189b2012-06-20 16:38:30 -070010864 hdd_close_all_adapters( pHddCtx );
10865
Padma, Santhosh Kumar9cd38332015-11-17 12:18:10 +053010866 vos_flush_delayed_work(&pHddCtx->spoof_mac_addr_work);
Kapil Gupta137ef892016-12-13 19:38:00 +053010867 vos_flush_work(&pHddCtx->sap_start_work);
Padma, Santhosh Kumar9cd38332015-11-17 12:18:10 +053010868
Hanumantha Reddy Pothula97f9bc92015-08-10 17:21:20 +053010869free_hdd_ctx:
Jeff Johnson295189b2012-06-20 16:38:30 -070010870 /* free the power on lock from platform driver */
10871 if (free_riva_power_on_lock("wlan"))
10872 {
10873 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to free power on lock",
10874 __func__);
10875 }
10876
c_hpothu78c7b602014-05-17 17:35:49 +053010877 //Free up dynamically allocated members inside HDD Adapter
10878 if (pHddCtx->cfg_ini)
10879 {
10880 kfree(pHddCtx->cfg_ini);
10881 pHddCtx->cfg_ini= NULL;
10882 }
10883
Hanumantha Reddy Pothula6fe221c2016-01-28 15:01:09 +053010884 /* FTM/MONITOR mode, WIPHY did not registered
Leo Changf04ddad2013-09-18 13:46:38 -070010885 If un-register here, system crash will happen */
Hanumantha Reddy Pothula6fe221c2016-01-28 15:01:09 +053010886 if (!(VOS_FTM_MODE == hdd_get_conparam() ||
10887 VOS_MONITOR_MODE == hdd_get_conparam()))
Leo Changf04ddad2013-09-18 13:46:38 -070010888 {
10889 wiphy_unregister(wiphy) ;
Agrawal Ashish33ec71e2015-11-26 20:20:58 +053010890 hdd_wlan_free_wiphy_channels(wiphy);
Leo Changf04ddad2013-09-18 13:46:38 -070010891 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010892 wiphy_free(wiphy) ;
Jeff Johnson295189b2012-06-20 16:38:30 -070010893 if (hdd_is_ssr_required())
10894 {
10895 /* WDI timeout had happened during unload, so SSR is needed here */
Madan Mohan Koyyalamudi3246f5b2012-10-15 15:40:02 -070010896 subsystem_restart("wcnss");
Jeff Johnson295189b2012-06-20 16:38:30 -070010897 msleep(5000);
10898 }
10899 hdd_set_ssr_required (VOS_FALSE);
10900}
10901
10902
10903/**---------------------------------------------------------------------------
10904
10905 \brief hdd_update_config_from_nv() - Function to update the contents of
10906 the running configuration with parameters taken from NV storage
10907
10908 \param - pHddCtx - Pointer to the HDD global context
10909
10910 \return - VOS_STATUS_SUCCESS if successful
10911
10912 --------------------------------------------------------------------------*/
10913static VOS_STATUS hdd_update_config_from_nv(hdd_context_t* pHddCtx)
10914{
Jeff Johnson295189b2012-06-20 16:38:30 -070010915 v_BOOL_t itemIsValid = VOS_FALSE;
10916 VOS_STATUS status;
10917 v_MACADDR_t macFromNV[VOS_MAX_CONCURRENCY_PERSONA];
10918 v_U8_t macLoop;
10919
10920 /*If the NV is valid then get the macaddress from nv else get it from qcom_cfg.ini*/
10921 status = vos_nv_getValidity(VNV_FIELD_IMAGE, &itemIsValid);
10922 if(status != VOS_STATUS_SUCCESS)
10923 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080010924 hddLog(VOS_TRACE_LEVEL_ERROR," vos_nv_getValidity() failed");
Jeff Johnson295189b2012-06-20 16:38:30 -070010925 return VOS_STATUS_E_FAILURE;
10926 }
10927
10928 if (itemIsValid == VOS_TRUE)
10929 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080010930 hddLog(VOS_TRACE_LEVEL_INFO_HIGH," Reading the Macaddress from NV");
Jeff Johnson295189b2012-06-20 16:38:30 -070010931 status = vos_nv_readMultiMacAddress((v_U8_t *)&macFromNV[0].bytes[0],
10932 VOS_MAX_CONCURRENCY_PERSONA);
10933 if(status != VOS_STATUS_SUCCESS)
10934 {
10935 /* Get MAC from NV fail, not update CFG info
10936 * INI MAC value will be used for MAC setting */
Arif Hussain6d2a3322013-11-17 19:50:10 -080010937 hddLog(VOS_TRACE_LEVEL_ERROR," vos_nv_readMacAddress() failed");
Jeff Johnson295189b2012-06-20 16:38:30 -070010938 return VOS_STATUS_E_FAILURE;
10939 }
10940
10941 /* If first MAC is not valid, treat all others are not valid
10942 * Then all MACs will be got from ini file */
10943 if(vos_is_macaddr_zero(&macFromNV[0]))
10944 {
10945 /* MAC address in NV file is not configured yet */
10946 hddLog(VOS_TRACE_LEVEL_WARN, "Invalid MAC in NV file");
10947 return VOS_STATUS_E_INVAL;
10948 }
10949
10950 /* Get MAC address from NV, update CFG info */
10951 for(macLoop = 0; macLoop < VOS_MAX_CONCURRENCY_PERSONA; macLoop++)
10952 {
10953 if(vos_is_macaddr_zero(&macFromNV[macLoop]))
10954 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010955 hddLog(VOS_TRACE_LEVEL_ERROR,"not valid MAC from NV for %d", macLoop);
Jeff Johnson295189b2012-06-20 16:38:30 -070010956 /* This MAC is not valid, skip it
10957 * This MAC will be got from ini file */
10958 }
10959 else
10960 {
10961 vos_mem_copy((v_U8_t *)&pHddCtx->cfg_ini->intfMacAddr[macLoop].bytes[0],
10962 (v_U8_t *)&macFromNV[macLoop].bytes[0],
10963 VOS_MAC_ADDR_SIZE);
10964 }
10965 }
10966 }
10967 else
10968 {
10969 hddLog(VOS_TRACE_LEVEL_ERROR, "NV ITEM, MAC Not valid");
10970 return VOS_STATUS_E_FAILURE;
10971 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010972
Jeff Johnson295189b2012-06-20 16:38:30 -070010973
10974 return VOS_STATUS_SUCCESS;
10975}
10976
10977/**---------------------------------------------------------------------------
10978
10979 \brief hdd_post_voss_start_config() - HDD post voss start config helper
10980
10981 \param - pAdapter - Pointer to the HDD
10982
10983 \return - None
10984
10985 --------------------------------------------------------------------------*/
10986VOS_STATUS hdd_post_voss_start_config(hdd_context_t* pHddCtx)
10987{
10988 eHalStatus halStatus;
10989 v_U32_t listenInterval;
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +053010990 tANI_U32 ignoreDtim;
Jeff Johnson295189b2012-06-20 16:38:30 -070010991
Jeff Johnson295189b2012-06-20 16:38:30 -070010992
10993 // Send ready indication to the HDD. This will kick off the MAC
10994 // into a 'running' state and should kick off an initial scan.
10995 halStatus = sme_HDDReadyInd( pHddCtx->hHal );
10996 if ( !HAL_STATUS_SUCCESS( halStatus ) )
10997 {
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +053010998 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: sme_HDDReadyInd() failed with status "
Jeff Johnson295189b2012-06-20 16:38:30 -070010999 "code %08d [x%08x]",__func__, halStatus, halStatus );
11000 return VOS_STATUS_E_FAILURE;
11001 }
11002
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +053011003 // Set default LI and ignoreDtim into HDD context,
Jeff Johnson295189b2012-06-20 16:38:30 -070011004 // otherwise under some race condition, HDD will set 0 LI value into RIVA,
11005 // And RIVA will crash
11006 wlan_cfgGetInt(pHddCtx->hHal, WNI_CFG_LISTEN_INTERVAL, &listenInterval);
11007 pHddCtx->hdd_actual_LI_value = listenInterval;
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +053011008 wlan_cfgGetInt(pHddCtx->hHal, WNI_CFG_IGNORE_DTIM, &ignoreDtim);
11009 pHddCtx->hdd_actual_ignore_DTIM_value = ignoreDtim;
11010
11011
Jeff Johnson295189b2012-06-20 16:38:30 -070011012 return VOS_STATUS_SUCCESS;
11013}
11014
Jeff Johnson295189b2012-06-20 16:38:30 -070011015/* wake lock APIs for HDD */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053011016void hdd_prevent_suspend(uint32_t reason)
Jeff Johnson295189b2012-06-20 16:38:30 -070011017{
Sushant Kaushik83392fa2015-05-05 17:44:40 +053011018
11019 vos_wake_lock_acquire(&wlan_wake_lock, reason);
11020
Jeff Johnson295189b2012-06-20 16:38:30 -070011021}
11022
Sushant Kaushik83392fa2015-05-05 17:44:40 +053011023void hdd_allow_suspend(uint32_t reason)
Jeff Johnson295189b2012-06-20 16:38:30 -070011024{
Sushant Kaushik83392fa2015-05-05 17:44:40 +053011025
11026 vos_wake_lock_release(&wlan_wake_lock, reason);
11027
Jeff Johnson295189b2012-06-20 16:38:30 -070011028}
11029
Sushant Kaushik83392fa2015-05-05 17:44:40 +053011030void hdd_prevent_suspend_timeout(v_U32_t timeout, uint32_t reason)
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -070011031{
Sushant Kaushik83392fa2015-05-05 17:44:40 +053011032
11033 vos_wake_lock_timeout_release(&wlan_wake_lock, timeout,
11034 reason);
11035
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -070011036}
11037
Jeff Johnson295189b2012-06-20 16:38:30 -070011038/**---------------------------------------------------------------------------
11039
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -070011040 \brief hdd_exchange_version_and_caps() - HDD function to exchange version and capability
11041 information between Host and Riva
11042
11043 This function gets reported version of FW
11044 It also finds the version of Riva headers used to compile the host
11045 It compares the above two and prints a warning if they are different
11046 It gets the SW and HW version string
11047 Finally, it exchanges capabilities between host and Riva i.e. host and riva exchange a msg
11048 indicating the features they support through a bitmap
11049
11050 \param - pHddCtx - Pointer to HDD context
11051
11052 \return - void
11053
11054 --------------------------------------------------------------------------*/
11055
11056void hdd_exchange_version_and_caps(hdd_context_t *pHddCtx)
11057{
11058
11059 tSirVersionType versionCompiled;
11060 tSirVersionType versionReported;
11061 tSirVersionString versionString;
11062 tANI_U8 fwFeatCapsMsgSupported = 0;
11063 VOS_STATUS vstatus;
11064
Mingcheng Zhu87f22fc2014-01-30 19:23:32 -080011065 memset(&versionCompiled, 0, sizeof(versionCompiled));
11066 memset(&versionReported, 0, sizeof(versionReported));
11067
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -070011068 /* retrieve and display WCNSS version information */
11069 do {
11070
11071 vstatus = sme_GetWcnssWlanCompiledVersion(pHddCtx->hHal,
11072 &versionCompiled);
11073 if (!VOS_IS_STATUS_SUCCESS(vstatus))
11074 {
11075 hddLog(VOS_TRACE_LEVEL_FATAL,
11076 "%s: unable to retrieve WCNSS WLAN compiled version",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070011077 __func__);
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -070011078 break;
11079 }
11080
11081 vstatus = sme_GetWcnssWlanReportedVersion(pHddCtx->hHal,
11082 &versionReported);
11083 if (!VOS_IS_STATUS_SUCCESS(vstatus))
11084 {
11085 hddLog(VOS_TRACE_LEVEL_FATAL,
11086 "%s: unable to retrieve WCNSS WLAN reported version",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070011087 __func__);
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -070011088 break;
11089 }
11090
11091 if ((versionCompiled.major != versionReported.major) ||
11092 (versionCompiled.minor != versionReported.minor) ||
11093 (versionCompiled.version != versionReported.version) ||
11094 (versionCompiled.revision != versionReported.revision))
11095 {
11096 pr_err("%s: WCNSS WLAN Version %u.%u.%u.%u, "
11097 "Host expected %u.%u.%u.%u\n",
11098 WLAN_MODULE_NAME,
11099 (int)versionReported.major,
11100 (int)versionReported.minor,
11101 (int)versionReported.version,
11102 (int)versionReported.revision,
11103 (int)versionCompiled.major,
11104 (int)versionCompiled.minor,
11105 (int)versionCompiled.version,
11106 (int)versionCompiled.revision);
11107 }
11108 else
11109 {
11110 pr_info("%s: WCNSS WLAN version %u.%u.%u.%u\n",
11111 WLAN_MODULE_NAME,
11112 (int)versionReported.major,
11113 (int)versionReported.minor,
11114 (int)versionReported.version,
11115 (int)versionReported.revision);
11116 }
11117
11118 vstatus = sme_GetWcnssSoftwareVersion(pHddCtx->hHal,
11119 versionString,
11120 sizeof(versionString));
11121 if (!VOS_IS_STATUS_SUCCESS(vstatus))
11122 {
11123 hddLog(VOS_TRACE_LEVEL_FATAL,
11124 "%s: unable to retrieve WCNSS software version string",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070011125 __func__);
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -070011126 break;
11127 }
11128
11129 pr_info("%s: WCNSS software version %s\n",
11130 WLAN_MODULE_NAME, versionString);
Sushant Kaushik084f6592015-09-10 13:11:56 +053011131 vos_mem_copy(pHddCtx->fw_Version, versionString, sizeof(versionString));
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -070011132
11133 vstatus = sme_GetWcnssHardwareVersion(pHddCtx->hHal,
11134 versionString,
11135 sizeof(versionString));
11136 if (!VOS_IS_STATUS_SUCCESS(vstatus))
11137 {
11138 hddLog(VOS_TRACE_LEVEL_FATAL,
11139 "%s: unable to retrieve WCNSS hardware version string",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070011140 __func__);
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -070011141 break;
11142 }
11143
11144 pr_info("%s: WCNSS hardware version %s\n",
11145 WLAN_MODULE_NAME, versionString);
11146
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -070011147 /* 1.Check if FW version is greater than 0.1.1.0. Only then send host-FW capability exchange message
11148 2.Host-FW capability exchange message is only present on riva 1.1 so
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -070011149 send the message only if it the riva is 1.1
11150 minor numbers for different riva branches:
11151 0 -> (1.0)Mainline Build
11152 1 -> (1.1)Mainline Build
11153 2->(1.04) Stability Build
11154 */
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -070011155 if (((versionReported.major>0) || (versionReported.minor>1) ||
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -070011156 ((versionReported.minor>=1) && (versionReported.version>=1)))
11157 && ((versionReported.major == 1) && (versionReported.minor >= 1)))
11158 fwFeatCapsMsgSupported = 1;
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -070011159
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -070011160 if (fwFeatCapsMsgSupported)
Yathish9f22e662012-12-10 14:21:35 -080011161 {
11162#ifdef WLAN_ACTIVEMODE_OFFLOAD_FEATURE
11163 if(!pHddCtx->cfg_ini->fEnableActiveModeOffload)
11164 sme_disableFeatureCapablity(WLANACTIVE_OFFLOAD);
11165#endif
Ravi Joshid2ca7c42013-07-23 08:37:49 -070011166 /* Indicate if IBSS heartbeat monitoring needs to be offloaded */
11167 if (!pHddCtx->cfg_ini->enableIbssHeartBeatOffload)
11168 {
11169 sme_disableFeatureCapablity(IBSS_HEARTBEAT_OFFLOAD);
11170 }
11171
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -070011172 sme_featureCapsExchange(pHddCtx->hHal);
Yathish9f22e662012-12-10 14:21:35 -080011173 }
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -070011174
11175 } while (0);
11176
11177}
Neelansh Mittaledafed22014-09-04 18:54:39 +053011178void wlan_hdd_send_svc_nlink_msg(int type, void *data, int len)
11179{
11180 struct sk_buff *skb;
11181 struct nlmsghdr *nlh;
11182 tAniMsgHdr *ani_hdr;
Hanumantha Reddy Pothulacf2c7ea2015-04-27 14:50:47 +053011183 int flags = GFP_KERNEL;
Bhargav shah23c94942015-10-13 12:48:35 +053011184 void *nl_data = NULL;
Neelansh Mittaledafed22014-09-04 18:54:39 +053011185
Hanumantha Reddy Pothulacf2c7ea2015-04-27 14:50:47 +053011186 if (in_interrupt() || irqs_disabled() || in_atomic())
11187 flags = GFP_ATOMIC;
11188
11189 skb = alloc_skb(NLMSG_SPACE(WLAN_NL_MAX_PAYLOAD), flags);
Neelansh Mittaledafed22014-09-04 18:54:39 +053011190
11191 if(skb == NULL) {
11192 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11193 "%s: alloc_skb failed", __func__);
11194 return;
11195 }
11196
11197 nlh = (struct nlmsghdr *)skb->data;
11198 nlh->nlmsg_pid = 0; /* from kernel */
11199 nlh->nlmsg_flags = 0;
11200 nlh->nlmsg_seq = 0;
11201 nlh->nlmsg_type = WLAN_NL_MSG_SVC;
11202
11203 ani_hdr = NLMSG_DATA(nlh);
11204 ani_hdr->type = type;
11205
11206 switch(type) {
11207 case WLAN_SVC_SAP_RESTART_IND:
11208 ani_hdr->length = 0;
11209 nlh->nlmsg_len = NLMSG_LENGTH((sizeof(tAniMsgHdr)));
11210 skb_put(skb, NLMSG_SPACE(sizeof(tAniMsgHdr)));
11211 break;
Bhargav Shahd0715912015-10-01 18:17:37 +053011212 case WLAN_SVC_WLAN_TP_IND:
11213 ani_hdr->length = len;
11214 nlh->nlmsg_len = NLMSG_LENGTH((sizeof(tAniMsgHdr)
11215 + len));
11216 nl_data = (char *)ani_hdr + sizeof(tAniMsgHdr);
11217 memcpy(nl_data, data, len);
11218 skb_put(skb, NLMSG_SPACE(sizeof(tAniMsgHdr) + len));
11219 break;
Bhargav shah23c94942015-10-13 12:48:35 +053011220 case WLAN_MSG_RPS_ENABLE_IND:
11221 ani_hdr->length = len;
11222 nlh->nlmsg_len = NLMSG_LENGTH((sizeof(tAniMsgHdr) + len));
11223 nl_data = (char *)ani_hdr + sizeof(tAniMsgHdr);
11224 memcpy(nl_data, data, len);
11225 skb_put(skb, NLMSG_SPACE(sizeof(tAniMsgHdr) + len));
11226 break;
Neelansh Mittaledafed22014-09-04 18:54:39 +053011227 default:
11228 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11229 "Attempt to send unknown nlink message %d", type);
11230 kfree_skb(skb);
11231 return;
11232 }
11233
11234 nl_srv_bcast(skb);
11235
11236 return;
11237}
11238
Bhargav Shahd0715912015-10-01 18:17:37 +053011239/**
11240 * hdd_request_tcp_delack() - Find the Delack value based on RX packet
11241 * @pHddCtx: Valid Global HDD context pointer
11242 * @rx_packets: Number of RX packet in perticular time
11243 *
11244 * Based on the RX packet this function calculate next value of tcp delack.
11245 * This function compare rx packet value to high and low threshold limit.
11246 *
11247 * Return: void
11248 */
11249void hdd_request_tcp_delack(hdd_context_t *pHddCtx, uint64_t rx_packets)
11250{
11251 /* average of rx_packets and prev_rx is taken so that
11252 bus width doesnot fluctuate much */
11253 uint64_t temp_rx = (rx_packets + pHddCtx->prev_rx)/2;
11254 TP_IND_TYPE next_rx_level = pHddCtx->cur_rx_level;
Neelansh Mittaledafed22014-09-04 18:54:39 +053011255
Bhargav Shahd0715912015-10-01 18:17:37 +053011256 pHddCtx->prev_rx = rx_packets;
11257 if (temp_rx > pHddCtx->cfg_ini->tcpDelAckThresholdHigh)
11258 next_rx_level = TP_IND_HIGH;
11259 else if (temp_rx <= pHddCtx->cfg_ini->tcpDelAckThresholdLow)
11260 next_rx_level = TP_IND_LOW;
11261
11262 hdd_set_delack_value(pHddCtx, next_rx_level);
11263}
11264
11265#define HDD_BW_GET_DIFF(x, y) ((x) >= (y) ? (x) - (y) : (ULONG_MAX - (y) + (x)))
11266
11267/**
11268 * hdd_tcp_delack_compute_function() - get link status
11269 * @priv: Valid Global HDD context pointer
11270 *
11271 * This function find number of RX packet during timer life span.
11272 * It request tcp delack with number of RX packet and re-configure delack timer
11273 * for tcpDelAckComputeInterval timer interval.
11274 *
11275 * Return: void
11276 */
11277void hdd_tcp_delack_compute_function(void *priv)
11278{
11279 hdd_context_t *pHddCtx = (hdd_context_t *)priv;
11280 hdd_adapter_t *pAdapter = NULL;
11281 v_U32_t rx_packets = 0;
11282 hdd_adapter_list_node_t *pAdapterNode = NULL;
11283 VOS_STATUS status = 0;
11284
11285 for (status = hdd_get_front_adapter(pHddCtx, &pAdapterNode);
11286 NULL != pAdapterNode && VOS_STATUS_SUCCESS == status;
11287 status = hdd_get_next_adapter(pHddCtx, pAdapterNode, &pAdapterNode)) {
11288 if ((pAdapter = pAdapterNode->pAdapter) == NULL)
11289 continue;
11290
11291 rx_packets += HDD_BW_GET_DIFF(pAdapter->stats.rx_packets,
11292 pAdapter->prev_rx_packets);
11293 pAdapter->prev_rx_packets = pAdapter->stats.rx_packets;
11294 }
11295
11296 hdd_request_tcp_delack(pHddCtx, rx_packets);
11297
11298 vos_timer_start(&pHddCtx->delack_timer,
11299 pHddCtx->cfg_ini->tcpDelAckComputeInterval);
11300}
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -070011301
11302/**---------------------------------------------------------------------------
11303
Gopichand Nakkalafce506f2013-07-03 23:55:16 +053011304 \brief hdd_is_5g_supported() - HDD function to know if hardware supports 5GHz
11305
11306 \param - pHddCtx - Pointer to the hdd context
11307
11308 \return - true if hardware supports 5GHz
11309
11310 --------------------------------------------------------------------------*/
Vinay Krishna Erannafacf5e22014-02-24 13:16:25 +053011311boolean hdd_is_5g_supported(hdd_context_t * pHddCtx)
Gopichand Nakkalafce506f2013-07-03 23:55:16 +053011312{
11313 /* If wcnss_wlan_iris_xo_mode() returns WCNSS_XO_48MHZ(1);
11314 * then hardware support 5Ghz.
11315 */
11316 if (WCNSS_XO_48MHZ == wcnss_wlan_iris_xo_mode())
11317 {
Ratheesh S P36dbc932015-08-07 14:28:57 +053011318 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Hardware supports 5Ghz", __func__);
Gopichand Nakkalafce506f2013-07-03 23:55:16 +053011319 return true;
11320 }
11321 else
11322 {
Ratheesh S P36dbc932015-08-07 14:28:57 +053011323 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Hardware doesn't supports 5Ghz",
Gopichand Nakkalafce506f2013-07-03 23:55:16 +053011324 __func__);
11325 return false;
11326 }
11327}
11328
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +053011329/**---------------------------------------------------------------------------
11330
11331 \brief hdd_generate_iface_mac_addr_auto() - HDD Mac Interface Auto
11332 generate function
11333
11334 This is generate the random mac address for WLAN interface
11335
11336 \param - pHddCtx - Pointer to HDD context
11337 idx - Start interface index to get auto
11338 generated mac addr.
11339 mac_addr - Mac address
11340
11341 \return - 0 for success, < 0 for failure
11342
11343 --------------------------------------------------------------------------*/
11344
11345static int hdd_generate_iface_mac_addr_auto(hdd_context_t *pHddCtx,
11346 int idx, v_MACADDR_t mac_addr)
11347{
11348 int i;
11349 unsigned int serialno;
11350 serialno = wcnss_get_serial_number();
11351
11352 if (0 != serialno)
11353 {
11354 /* MAC address has 3 bytes of OUI so we have a maximum of 3
11355 bytes of the serial number that can be used to generate
11356 the other 3 bytes of the MAC address. Mask off all but
11357 the lower 3 bytes (this will also make sure we don't
11358 overflow in the next step) */
11359 serialno &= 0x00FFFFFF;
11360
11361 /* we need a unique address for each session */
11362 serialno *= VOS_MAX_CONCURRENCY_PERSONA;
11363
11364 /* autogen other Mac addresses */
11365 for (i = idx; i < VOS_MAX_CONCURRENCY_PERSONA; i++)
11366 {
11367 /* start with the entire default address */
11368 pHddCtx->cfg_ini->intfMacAddr[i] = mac_addr;
11369 /* then replace the lower 3 bytes */
11370 pHddCtx->cfg_ini->intfMacAddr[i].bytes[3] = (serialno >> 16) & 0xFF;
11371 pHddCtx->cfg_ini->intfMacAddr[i].bytes[4] = (serialno >> 8) & 0xFF;
11372 pHddCtx->cfg_ini->intfMacAddr[i].bytes[5] = serialno & 0xFF;
11373
11374 serialno++;
11375 hddLog(VOS_TRACE_LEVEL_ERROR,
11376 "%s: Derived Mac Addr: "
11377 MAC_ADDRESS_STR, __func__,
11378 MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[i].bytes));
11379 }
11380
11381 }
11382 else
11383 {
11384 hddLog(LOGE, FL("Failed to Get Serial NO"));
11385 return -1;
11386 }
11387 return 0;
11388}
Gopichand Nakkalafce506f2013-07-03 23:55:16 +053011389
Katya Nigame7b69a82015-04-28 15:24:06 +053011390int wlan_hdd_mon_open(hdd_context_t *pHddCtx)
11391{
11392 VOS_STATUS status;
11393 v_CONTEXT_t pVosContext= NULL;
11394 hdd_adapter_t *pAdapter= NULL;
11395
11396 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
11397
11398 if (NULL == pVosContext)
11399 {
11400 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11401 "%s: Trying to open VOSS without a PreOpen", __func__);
11402 VOS_ASSERT(0);
11403 return VOS_STATUS_E_FAILURE;
11404 }
11405
11406 status = vos_nv_open();
11407 if (!VOS_IS_STATUS_SUCCESS(status))
11408 {
11409 /* NV module cannot be initialized */
11410 hddLog( VOS_TRACE_LEVEL_FATAL,
11411 "%s: vos_nv_open failed", __func__);
11412 return VOS_STATUS_E_FAILURE;
11413 }
11414
11415 status = vos_init_wiphy_from_nv_bin();
11416 if (!VOS_IS_STATUS_SUCCESS(status))
11417 {
11418 /* NV module cannot be initialized */
11419 hddLog( VOS_TRACE_LEVEL_FATAL,
11420 "%s: vos_init_wiphy failed", __func__);
11421 goto err_vos_nv_close;
11422 }
11423
11424 status = vos_open( &pVosContext, pHddCtx->parent_dev);
11425 if ( !VOS_IS_STATUS_SUCCESS( status ))
11426 {
11427 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: vos_open failed", __func__);
11428 goto err_vos_nv_close;
11429 }
11430
11431 status = vos_mon_start( pVosContext );
11432 if ( !VOS_IS_STATUS_SUCCESS( status ) )
11433 {
11434 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: vos_start failed",__func__);
11435 goto err_vosclose;
11436 }
11437
11438 WLANTL_SetMonRxCbk( pVosContext, hdd_rx_packet_monitor_cbk );
11439 WDA_featureCapsExchange(pVosContext);
11440 wcnss_wlan_set_drvdata(pHddCtx->parent_dev, pHddCtx);
11441
11442 pAdapter = hdd_open_adapter( pHddCtx, WLAN_HDD_MONITOR, "wlan%d",
11443 wlan_hdd_get_intf_addr(pHddCtx), FALSE );
11444 if( pAdapter == NULL )
11445 {
11446 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: hdd_open_adapter failed", __func__);
11447 goto err_close_adapter;
11448 }
11449
11450 //Initialize the nlink service
11451 if(nl_srv_init() != 0)
11452 {
11453 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: nl_srv_init failed", __func__);
11454 goto err_close_adapter;
11455 }
11456 return VOS_STATUS_SUCCESS;
11457
11458err_close_adapter:
11459 hdd_close_all_adapters( pHddCtx );
11460 vos_mon_stop( pVosContext );
11461err_vosclose:
11462 status = vos_sched_close( pVosContext );
11463 if (!VOS_IS_STATUS_SUCCESS(status)) {
11464 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
11465 "%s: Failed to close VOSS Scheduler", __func__);
11466 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( status ) );
11467 }
11468 vos_close(pVosContext );
11469
11470err_vos_nv_close:
11471 vos_nv_close();
11472
11473return status;
11474}
Gopichand Nakkalafce506f2013-07-03 23:55:16 +053011475/**---------------------------------------------------------------------------
11476
Mihir Shetefc7ff5b2014-01-27 11:30:05 +053011477 \brief hdd_11d_scan_done - callback to be executed when 11d scan is
11478 completed to flush out the scan results
11479
11480 11d scan is done during driver load and is a passive scan on all
11481 channels supported by the device, 11d scans may find some APs on
11482 frequencies which are forbidden to be used in the regulatory domain
11483 the device is operating in. If these APs are notified to the supplicant
11484 it may try to connect to these APs, thus flush out all the scan results
11485 which are present in SME after 11d scan is done.
11486
11487 \return - eHalStatus
11488
11489 --------------------------------------------------------------------------*/
11490static eHalStatus hdd_11d_scan_done(tHalHandle halHandle, void *pContext,
11491 tANI_U32 scanId, eCsrScanStatus status)
11492{
11493 ENTER();
11494
11495 sme_ScanFlushResult(halHandle, 0);
11496
11497 EXIT();
11498
11499 return eHAL_STATUS_SUCCESS;
11500}
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053011501/**---------------------------------------------------------------------------
11502
11503 \brief hdd_init_frame_logging_done - callback to be executed when mgmt frame
11504 logging is completed successfully.
11505
11506 \return - None
11507
11508 --------------------------------------------------------------------------*/
c_manjeecfd1efb2015-09-25 19:32:34 +053011509void hdd_init_frame_logging_done(void *fwlogInitCbContext, tAniLoggingInitRsp *pRsp)
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053011510{
Siddharth Bhald1be97f2015-05-27 22:39:59 +053011511 hdd_context_t* pHddCtx = (hdd_context_t*)fwlogInitCbContext;
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053011512
11513 if (NULL == pHddCtx)
11514 {
11515 hddLog(VOS_TRACE_LEVEL_ERROR,
11516 "%s: HDD context is NULL",__func__);
11517 return;
11518 }
11519
c_manjeecfd1efb2015-09-25 19:32:34 +053011520 if ((pRsp->status == VOS_STATUS_SUCCESS) &&
Mahesh A Saptasagarfabb1a02015-06-29 12:17:04 +053011521 (TRUE == pHddCtx->cfg_ini->enableMgmtLogging))
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053011522 {
11523 hddLog(VOS_TRACE_LEVEL_INFO, FL("Mgmt Frame Logging init successful"));
11524 pHddCtx->mgmt_frame_logging = TRUE;
11525 }
11526 else
11527 {
11528 hddLog(VOS_TRACE_LEVEL_INFO, FL("Mgmt Frame Logging init not success"));
11529 pHddCtx->mgmt_frame_logging = FALSE;
c_manjeecfd1efb2015-09-25 19:32:34 +053011530 return;
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053011531 }
11532
c_manjeecfd1efb2015-09-25 19:32:34 +053011533 /*Check feature supported by FW*/
11534 if(TRUE == sme_IsFeatureSupportedByFW(MEMORY_DUMP_SUPPORTED))
11535 {
11536 //Store fwr mem dump size given by firmware.
11537 wlan_store_fwr_mem_dump_size(pRsp->fw_mem_dump_max_size);
11538 }
11539 else
11540 {
11541 wlan_store_fwr_mem_dump_size(0);
11542 }
11543
11544
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053011545}
11546/**---------------------------------------------------------------------------
11547
11548 \brief hdd_init_frame_logging - function to initialize frame logging.
11549 Currently only Mgmt Frames are logged in both TX
11550 and Rx direction and are sent to userspace
11551 application using logger thread when queried.
11552
11553 \return - None
11554
11555 --------------------------------------------------------------------------*/
Siddharth Bhald1be97f2015-05-27 22:39:59 +053011556void hdd_init_frame_logging(hdd_context_t* pHddCtx)
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053011557{
11558 eHalStatus halStatus = eHAL_STATUS_FAILURE;
Sreelakshmi Konamkid8784d92016-04-14 14:59:13 +053011559 tSirFWLoggingInitParam wlanFWLoggingInitParam = {0};
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053011560
Siddharth Bhald1be97f2015-05-27 22:39:59 +053011561 if (TRUE != sme_IsFeatureSupportedByFW(MGMT_FRAME_LOGGING) &&
11562 TRUE != sme_IsFeatureSupportedByFW(LOGGING_ENHANCEMENT))
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053011563 {
11564 hddLog(VOS_TRACE_LEVEL_INFO, FL("MGMT_FRAME_LOGGING not supp by FW"));
11565 return;
11566 }
11567
c_manjeecfd1efb2015-09-25 19:32:34 +053011568 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Configuring %s %s %s %s Logging",__func__,
Siddharth Bhald1be97f2015-05-27 22:39:59 +053011569 pHddCtx->cfg_ini->enableFWLogging?"FW Log,":"",
11570 pHddCtx->cfg_ini->enableContFWLogging ? "Cont FW log,":"",
c_manjeecfd1efb2015-09-25 19:32:34 +053011571 pHddCtx->cfg_ini->enableMgmtLogging ? "Mgmt Pkt Log":"",
11572 pHddCtx->cfg_ini->enableFwrMemDump ? "Fw Mem dump":"");
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053011573
Siddharth Bhald1be97f2015-05-27 22:39:59 +053011574 if (pHddCtx->cfg_ini->enableFWLogging ||
11575 pHddCtx->cfg_ini->enableContFWLogging)
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053011576 {
Sreelakshmi Konamkid8784d92016-04-14 14:59:13 +053011577 wlanFWLoggingInitParam.enableFlag |= WLAN_QXDM_LOG_EN;
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053011578 }
11579
Sushant Kaushik46804902015-07-08 14:46:03 +053011580 if (pHddCtx->cfg_ini->enableMgmtLogging)
11581 {
Sreelakshmi Konamkid8784d92016-04-14 14:59:13 +053011582 wlanFWLoggingInitParam.enableFlag |= WLAN_FRAME_LOG_EN;
Sushant Kaushik46804902015-07-08 14:46:03 +053011583 }
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053011584 if (pHddCtx->cfg_ini->enableBMUHWtracing)
11585 {
Sreelakshmi Konamkid8784d92016-04-14 14:59:13 +053011586 wlanFWLoggingInitParam.enableFlag |= WLAN_BMUHW_TRACE_LOG_EN;
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053011587 }
c_manjeecfd1efb2015-09-25 19:32:34 +053011588 if(pHddCtx->cfg_ini->enableFwrMemDump &&
11589 (TRUE == sme_IsFeatureSupportedByFW(MEMORY_DUMP_SUPPORTED)))
11590 {
Sreelakshmi Konamkid8784d92016-04-14 14:59:13 +053011591 wlanFWLoggingInitParam.enableFlag |= WLAN_FW_MEM_DUMP_EN;
c_manjeecfd1efb2015-09-25 19:32:34 +053011592 }
Sreelakshmi Konamkid8784d92016-04-14 14:59:13 +053011593 if( wlanFWLoggingInitParam.enableFlag == 0 )
c_manjeecfd1efb2015-09-25 19:32:34 +053011594 {
11595 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Logging not enabled", __func__);
11596 return;
11597 }
Sreelakshmi Konamkid8784d92016-04-14 14:59:13 +053011598 wlanFWLoggingInitParam.frameType = WLAN_FRAME_LOGGING_FRAMETYPE_MGMT;
11599 wlanFWLoggingInitParam.frameSize = WLAN_MGMT_LOGGING_FRAMESIZE_128BYTES;
11600 wlanFWLoggingInitParam.bufferMode = WLAN_FRAME_LOGGING_BUFFERMODE_CIRCULAR;
11601 wlanFWLoggingInitParam.continuousFrameLogging =
Siddharth Bhald1be97f2015-05-27 22:39:59 +053011602 pHddCtx->cfg_ini->enableContFWLogging;
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053011603
Sreelakshmi Konamkid8784d92016-04-14 14:59:13 +053011604 wlanFWLoggingInitParam.enableFlag &= ~WLAN_DPU_TXP_LOG_EN;
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053011605
Sreelakshmi Konamkid8784d92016-04-14 14:59:13 +053011606 wlanFWLoggingInitParam.minLogBufferSize =
Siddharth Bhald1be97f2015-05-27 22:39:59 +053011607 pHddCtx->cfg_ini->minLoggingBufferSize;
Sreelakshmi Konamkid8784d92016-04-14 14:59:13 +053011608 wlanFWLoggingInitParam.maxLogBufferSize =
Siddharth Bhald1be97f2015-05-27 22:39:59 +053011609 pHddCtx->cfg_ini->maxLoggingBufferSize;
Sreelakshmi Konamkid8784d92016-04-14 14:59:13 +053011610 wlanFWLoggingInitParam.fwlogInitCallback = hdd_init_frame_logging_done;
11611 wlanFWLoggingInitParam.fwlogInitCbContext= pHddCtx;
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053011612
Sreelakshmi Konamkid8784d92016-04-14 14:59:13 +053011613 halStatus = sme_InitMgmtFrameLogging(pHddCtx->hHal, &wlanFWLoggingInitParam);
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053011614
11615 if (eHAL_STATUS_SUCCESS != halStatus)
11616 {
Sreelakshmi Konamkid8784d92016-04-14 14:59:13 +053011617 hddLog(LOGE, FL("sme_InitMgmtFrameLogging failed, returned %d"),
11618 halStatus);
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053011619 }
11620
11621 return;
11622}
Mihir Shetefc7ff5b2014-01-27 11:30:05 +053011623
Bhargav shah23c94942015-10-13 12:48:35 +053011624static void hdd_dp_util_send_rps_ind(hdd_context_t *hdd_ctxt)
11625{
11626 hdd_adapter_t *adapter;
11627 hdd_adapter_list_node_t *adapter_node, *next;
11628 VOS_STATUS status = VOS_STATUS_SUCCESS;
11629 struct wlan_rps_data rps_data;
11630 int count;
11631
11632 if(!hdd_ctxt->cfg_ini->rps_mask)
11633 {
11634 return;
11635 }
11636
11637 for (count=0; count < WLAN_SVC_IFACE_NUM_QUEUES; count++)
11638 {
11639 rps_data.cpu_map[count] = hdd_ctxt->cfg_ini->rps_mask;
11640 }
11641
11642 rps_data.num_queues = WLAN_SVC_IFACE_NUM_QUEUES;
11643
11644 hddLog(LOG1, FL("0x%x 0x%x 0x%x 0x%x 0x%x 0x%x"),
11645 rps_data.cpu_map[0], rps_data.cpu_map[1],rps_data.cpu_map[2],
11646 rps_data.cpu_map[3], rps_data.cpu_map[4], rps_data.cpu_map[5]);
11647
11648 status = hdd_get_front_adapter (hdd_ctxt, &adapter_node);
11649
11650 while (NULL != adapter_node && VOS_STATUS_SUCCESS == status)
11651 {
11652 adapter = adapter_node->pAdapter;
11653 if (NULL != adapter) {
11654 strlcpy(rps_data.ifname, adapter->dev->name,
11655 sizeof(rps_data.ifname));
11656 wlan_hdd_send_svc_nlink_msg(WLAN_MSG_RPS_ENABLE_IND,
11657 (void *)&rps_data,sizeof(rps_data));
11658 }
11659 status = hdd_get_next_adapter (hdd_ctxt, adapter_node, &next);
11660 adapter_node = next;
11661 }
11662}
11663
Masti, Narayanraddi26378462016-01-05 18:20:28 +053011664void wlan_hdd_schedule_defer_scan(struct work_struct *work)
11665{
11666 scan_context_t *scan_ctx =
11667 container_of(work, scan_context_t, scan_work.work);
11668
11669 if (NULL == scan_ctx)
11670 {
11671 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11672 FL("scan_ctx is NULL"));
11673 return;
11674 }
11675
11676 if (unlikely(TDLS_CTX_MAGIC != scan_ctx->magic))
11677 return;
11678
11679 scan_ctx->attempt++;
11680
11681 wlan_hdd_cfg80211_scan(scan_ctx->wiphy,
11682#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
11683 scan_ctx->dev,
11684#endif
11685 scan_ctx->scan_request);
11686}
11687
11688int wlan_hdd_copy_defer_scan_context(hdd_context_t *pHddCtx,
11689 struct wiphy *wiphy,
11690#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
11691 struct net_device *dev,
11692#endif
11693 struct cfg80211_scan_request *request)
11694{
11695 scan_context_t *scan_ctx;
11696
11697 ENTER();
11698 if (0 != (wlan_hdd_validate_context(pHddCtx)))
11699 {
11700 return -1;
11701 }
11702
11703 scan_ctx = &pHddCtx->scan_ctxt;
11704
11705 scan_ctx->wiphy = wiphy;
11706#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
11707 scan_ctx->dev = dev;
11708#endif
11709
11710 scan_ctx->scan_request = request;
11711
11712 EXIT();
11713 return 0;
11714}
11715
11716void wlan_hdd_defer_scan_init_work(hdd_context_t *pHddCtx,
11717 struct wiphy *wiphy,
11718#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
11719 struct net_device *dev,
11720#endif
11721 struct cfg80211_scan_request *request,
11722 unsigned long delay)
11723{
11724 if (TDLS_CTX_MAGIC != pHddCtx->scan_ctxt.magic)
11725 {
11726#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
11727 wlan_hdd_copy_defer_scan_context(pHddCtx, wiphy, dev, request);
11728#else
11729 wlan_hdd_copy_defer_scan_context(pHddCtx, wiphy, request);
11730#endif
11731 pHddCtx->scan_ctxt.attempt = 0;
11732 pHddCtx->scan_ctxt.magic = TDLS_CTX_MAGIC;
11733 }
11734 schedule_delayed_work(&pHddCtx->scan_ctxt.scan_work, delay);
11735}
11736
11737void wlan_hdd_init_deinit_defer_scan_context(scan_context_t *scan_ctx)
11738{
11739 scan_ctx->magic = 0;
11740 scan_ctx->attempt = 0;
11741 scan_ctx->reject = 0;
11742 scan_ctx->scan_request = NULL;
11743
11744 return;
11745}
11746
Mihir Shetefc7ff5b2014-01-27 11:30:05 +053011747/**---------------------------------------------------------------------------
11748
Jeff Johnson295189b2012-06-20 16:38:30 -070011749 \brief hdd_wlan_startup() - HDD init function
11750
11751 This is the driver startup code executed once a WLAN device has been detected
11752
11753 \param - dev - Pointer to the underlying device
11754
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -080011755 \return - 0 for success, < 0 for failure
Jeff Johnson295189b2012-06-20 16:38:30 -070011756
11757 --------------------------------------------------------------------------*/
11758
11759int hdd_wlan_startup(struct device *dev )
11760{
11761 VOS_STATUS status;
11762 hdd_adapter_t *pAdapter = NULL;
Jeff Johnsone7245742012-09-05 17:12:55 -070011763 hdd_adapter_t *pP2pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070011764 hdd_context_t *pHddCtx = NULL;
11765 v_CONTEXT_t pVosContext= NULL;
11766#ifdef WLAN_BTAMP_FEATURE
11767 VOS_STATUS vStatus = VOS_STATUS_SUCCESS;
11768 WLANBAP_ConfigType btAmpConfig;
11769 hdd_config_t *pConfig;
11770#endif
11771 int ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070011772 struct wiphy *wiphy;
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +053011773 v_MACADDR_t mac_addr;
Jeff Johnson295189b2012-06-20 16:38:30 -070011774
11775 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -070011776 /*
11777 * cfg80211: wiphy allocation
11778 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +053011779 wiphy = wlan_hdd_cfg80211_wiphy_alloc(sizeof(hdd_context_t)) ;
Jeff Johnson295189b2012-06-20 16:38:30 -070011780
11781 if(wiphy == NULL)
11782 {
11783 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: cfg80211 init failed", __func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -080011784 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -070011785 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011786 pHddCtx = wiphy_priv(wiphy);
11787
Jeff Johnson295189b2012-06-20 16:38:30 -070011788 //Initialize the adapter context to zeros.
11789 vos_mem_zero(pHddCtx, sizeof( hdd_context_t ));
11790
Jeff Johnson295189b2012-06-20 16:38:30 -070011791 pHddCtx->wiphy = wiphy;
Sushant Kaushik83392fa2015-05-05 17:44:40 +053011792 hdd_prevent_suspend(WIFI_POWER_EVENT_WAKELOCK_DRIVER_INIT);
Mihir Shete18156292014-03-11 15:38:30 +053011793 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_LOAD_IN_PROGRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -070011794
11795 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, TRUE);
11796
Siddharth Bhalcd92b782015-06-29 12:25:40 +053011797 /* register for riva power on lock to platform driver
11798 * Locking power early to ensure FW doesn't reset by kernel while
11799 * host driver is busy initializing itself */
11800 if (req_riva_power_on_lock("wlan"))
11801 {
11802 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: req riva power on lock failed",
11803 __func__);
11804 goto err_free_hdd_context;
11805 }
11806
Jeff Johnson295189b2012-06-20 16:38:30 -070011807 /*Get vos context here bcoz vos_open requires it*/
11808 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
11809
Madan Mohan Koyyalamudi0b78e152012-11-28 15:46:51 -080011810 if(pVosContext == NULL)
11811 {
11812 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Failed vos_get_global_context",__func__);
11813 goto err_free_hdd_context;
11814 }
11815
Jeff Johnson295189b2012-06-20 16:38:30 -070011816 //Save the Global VOSS context in adapter context for future.
11817 pHddCtx->pvosContext = pVosContext;
11818
11819 //Save the adapter context in global context for future.
11820 ((VosContextType*)(pVosContext))->pHDDContext = (v_VOID_t*)pHddCtx;
11821
Jeff Johnson295189b2012-06-20 16:38:30 -070011822 pHddCtx->parent_dev = dev;
Sreelakshmi Konamkif0646d52016-12-09 12:35:31 +053011823 pHddCtx->last_scan_reject_session_id = 0xFF;
11824 pHddCtx->last_scan_reject_reason = 0;
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053011825 pHddCtx->last_scan_reject_timestamp = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070011826
11827 init_completion(&pHddCtx->full_pwr_comp_var);
11828 init_completion(&pHddCtx->standby_comp_var);
11829 init_completion(&pHddCtx->req_bmps_comp_var);
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070011830 init_completion(&pHddCtx->scan_info.scan_req_completion_event);
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -080011831 init_completion(&pHddCtx->scan_info.abortscan_event_var);
Kiet Lam46b8e4e2013-11-06 21:49:53 +053011832 init_completion(&pHddCtx->wiphy_channel_update_event);
Arun Kumar Khandavallie0b046d2014-03-01 21:54:25 +053011833 init_completion(&pHddCtx->ssr_comp_var);
Mahesh A Saptasagar67ab9222015-10-21 15:38:41 +053011834 init_completion(&pHddCtx->mc_sus_event_var);
11835 init_completion(&pHddCtx->tx_sus_event_var);
11836 init_completion(&pHddCtx->rx_sus_event_var);
11837
Amar Singhala49cbc52013-10-08 18:37:44 -070011838
mukul sharma4bd8d2e2015-08-13 20:33:25 +053011839 hdd_init_ll_stats_ctx(pHddCtx);
Anurag Chouhan6ee81542017-02-09 18:09:27 +053011840 hdd_init_nud_stats_ctx(pHddCtx);
mukul sharma4bd8d2e2015-08-13 20:33:25 +053011841
Amar Singhala49cbc52013-10-08 18:37:44 -070011842#ifdef CONFIG_ENABLE_LINUX_REG
Amar Singhalfddc28c2013-09-05 13:03:40 -070011843 init_completion(&pHddCtx->linux_reg_req);
Amar Singhala49cbc52013-10-08 18:37:44 -070011844#else
11845 init_completion(&pHddCtx->driver_crda_req);
11846#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070011847
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +053011848#ifdef WLAN_FEATURE_EXTSCAN
11849 init_completion(&pHddCtx->ext_scan_context.response_event);
11850#endif /* WLAN_FEATURE_EXTSCAN */
11851
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053011852 spin_lock_init(&pHddCtx->schedScan_lock);
Kapil Gupta137ef892016-12-13 19:38:00 +053011853 vos_spin_lock_init(&pHddCtx->sap_update_info_lock);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053011854
Jeff Johnson295189b2012-06-20 16:38:30 -070011855 hdd_list_init( &pHddCtx->hddAdapters, MAX_NUMBER_OF_ADAPTERS );
11856
Padma, Santhosh Kumar9cd38332015-11-17 12:18:10 +053011857 vos_init_delayed_work(&pHddCtx->spoof_mac_addr_work,
11858 hdd_processSpoofMacAddrRequest);
Kapil Gupta137ef892016-12-13 19:38:00 +053011859 vos_init_work(&pHddCtx->sap_start_work, hdd_sap_restart_handle);
Padma, Santhosh Kumar9cd38332015-11-17 12:18:10 +053011860
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053011861#ifdef FEATURE_WLAN_TDLS
11862 /* tdls_lock is initialized before an hdd_open_adapter ( which is
11863 * invoked by other instances also) to protect the concurrent
11864 * access for the Adapters by TDLS module.
11865 */
11866 mutex_init(&pHddCtx->tdls_lock);
11867#endif
Siddharth Bhal76972212014-10-15 16:22:51 +053011868 mutex_init(&pHddCtx->spoofMacAddr.macSpoofingLock);
Mukul Sharma1fd6efd2015-02-14 00:29:14 +053011869 mutex_init(&pHddCtx->wmmLock);
11870
Srinivas Girigowda8bf64cb2015-09-30 19:50:09 +053011871 hdd_init_offloaded_packets_ctx(pHddCtx);
Agarwal Ashish1f422872014-07-22 00:11:55 +053011872 /* By default Strict Regulatory For FCC should be false */
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053011873
Agarwal Ashish1f422872014-07-22 00:11:55 +053011874 pHddCtx->nEnableStrictRegulatoryForFCC = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070011875 // Load all config first as TL config is needed during vos_open
11876 pHddCtx->cfg_ini = (hdd_config_t*) kmalloc(sizeof(hdd_config_t), GFP_KERNEL);
11877 if(pHddCtx->cfg_ini == NULL)
11878 {
11879 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Failed kmalloc hdd_config_t",__func__);
11880 goto err_free_hdd_context;
11881 }
11882
11883 vos_mem_zero(pHddCtx->cfg_ini, sizeof( hdd_config_t ));
11884
11885 // Read and parse the qcom_cfg.ini file
11886 status = hdd_parse_config_ini( pHddCtx );
11887 if ( VOS_STATUS_SUCCESS != status )
11888 {
11889 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: error parsing %s",
11890 __func__, WLAN_INI_FILE);
11891 goto err_config;
11892 }
Arif Hussaind5218912013-12-05 01:10:55 -080011893#ifdef MEMORY_DEBUG
11894 if (pHddCtx->cfg_ini->IsMemoryDebugSupportEnabled)
11895 vos_mem_init();
11896
11897 hddLog(VOS_TRACE_LEVEL_INFO, "%s: gEnableMemoryDebug=%d",
11898 __func__, pHddCtx->cfg_ini->IsMemoryDebugSupportEnabled);
11899#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070011900
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +053011901 /* INI has been read, initialise the configuredMcastBcastFilter with
11902 * INI value as this will serve as the default value
11903 */
11904 pHddCtx->configuredMcastBcastFilter = pHddCtx->cfg_ini->mcastBcastFilterSetting;
11905 hddLog(VOS_TRACE_LEVEL_INFO, "Setting configuredMcastBcastFilter: %d",
11906 pHddCtx->cfg_ini->mcastBcastFilterSetting);
Gopichand Nakkalafce506f2013-07-03 23:55:16 +053011907
11908 if (false == hdd_is_5g_supported(pHddCtx))
11909 {
11910 //5Ghz is not supported.
11911 if (1 != pHddCtx->cfg_ini->nBandCapability)
11912 {
11913 hddLog(VOS_TRACE_LEVEL_INFO,
11914 "%s: Setting pHddCtx->cfg_ini->nBandCapability = 1", __func__);
11915 pHddCtx->cfg_ini->nBandCapability = 1;
11916 }
11917 }
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053011918
11919 /* If SNR Monitoring is enabled, FW has to parse all beacons
11920 * for calcaluting and storing the average SNR, so set Nth beacon
11921 * filter to 1 to enable FW to parse all the beaocons
11922 */
11923 if (1 == pHddCtx->cfg_ini->fEnableSNRMonitoring)
11924 {
11925 /* The log level is deliberately set to WARN as overriding
11926 * nthBeaconFilter to 1 will increase power cosumption and this
11927 * might just prove helpful to detect the power issue.
11928 */
11929 hddLog(VOS_TRACE_LEVEL_WARN,
11930 "%s: Setting pHddCtx->cfg_ini->nthBeaconFilter = 1", __func__);
11931 pHddCtx->cfg_ini->nthBeaconFilter = 1;
11932 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011933 /*
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +053011934 * cfg80211: Initialization ...
Jeff Johnson295189b2012-06-20 16:38:30 -070011935 */
Manjeet Singh61016fa2016-12-02 11:10:19 +053011936 if (0 < wlan_hdd_cfg80211_init(dev, wiphy, pHddCtx->cfg_ini))
Jeff Johnson295189b2012-06-20 16:38:30 -070011937 {
Manjeet Singh61016fa2016-12-02 11:10:19 +053011938 hddLog(VOS_TRACE_LEVEL_FATAL,
11939 "%s: wlan_hdd_cfg80211_init return failure", __func__);
11940 goto err_config;
Jeff Johnson295189b2012-06-20 16:38:30 -070011941 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011942
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -080011943 // Update VOS trace levels based upon the cfg.ini
11944 hdd_vos_trace_enable(VOS_MODULE_ID_BAP,
11945 pHddCtx->cfg_ini->vosTraceEnableBAP);
11946 hdd_vos_trace_enable(VOS_MODULE_ID_TL,
11947 pHddCtx->cfg_ini->vosTraceEnableTL);
11948 hdd_vos_trace_enable(VOS_MODULE_ID_WDI,
11949 pHddCtx->cfg_ini->vosTraceEnableWDI);
11950 hdd_vos_trace_enable(VOS_MODULE_ID_HDD,
11951 pHddCtx->cfg_ini->vosTraceEnableHDD);
11952 hdd_vos_trace_enable(VOS_MODULE_ID_SME,
11953 pHddCtx->cfg_ini->vosTraceEnableSME);
11954 hdd_vos_trace_enable(VOS_MODULE_ID_PE,
11955 pHddCtx->cfg_ini->vosTraceEnablePE);
Katya Nigam70d68332013-09-16 16:49:45 +053011956 hdd_vos_trace_enable(VOS_MODULE_ID_PMC,
11957 pHddCtx->cfg_ini->vosTraceEnablePMC);
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -080011958 hdd_vos_trace_enable(VOS_MODULE_ID_WDA,
11959 pHddCtx->cfg_ini->vosTraceEnableWDA);
11960 hdd_vos_trace_enable(VOS_MODULE_ID_SYS,
11961 pHddCtx->cfg_ini->vosTraceEnableSYS);
11962 hdd_vos_trace_enable(VOS_MODULE_ID_VOSS,
11963 pHddCtx->cfg_ini->vosTraceEnableVOSS);
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -080011964 hdd_vos_trace_enable(VOS_MODULE_ID_SAP,
11965 pHddCtx->cfg_ini->vosTraceEnableSAP);
11966 hdd_vos_trace_enable(VOS_MODULE_ID_HDD_SOFTAP,
11967 pHddCtx->cfg_ini->vosTraceEnableHDDSAP);
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -080011968
Jeff Johnson295189b2012-06-20 16:38:30 -070011969 // Update WDI trace levels based upon the cfg.ini
11970 hdd_wdi_trace_enable(eWLAN_MODULE_DAL,
11971 pHddCtx->cfg_ini->wdiTraceEnableDAL);
11972 hdd_wdi_trace_enable(eWLAN_MODULE_DAL_CTRL,
11973 pHddCtx->cfg_ini->wdiTraceEnableCTL);
11974 hdd_wdi_trace_enable(eWLAN_MODULE_DAL_DATA,
11975 pHddCtx->cfg_ini->wdiTraceEnableDAT);
11976 hdd_wdi_trace_enable(eWLAN_MODULE_PAL,
11977 pHddCtx->cfg_ini->wdiTraceEnablePAL);
Jeff Johnson295189b2012-06-20 16:38:30 -070011978
Jeff Johnson88ba7742013-02-27 14:36:02 -080011979 if (VOS_FTM_MODE == hdd_get_conparam())
11980 {
Jeff Johnson295189b2012-06-20 16:38:30 -070011981 if ( VOS_STATUS_SUCCESS != wlan_hdd_ftm_open(pHddCtx) )
11982 {
11983 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: wlan_hdd_ftm_open Failed",__func__);
11984 goto err_free_hdd_context;
11985 }
11986 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: FTM driver loaded success fully",__func__);
Sachin Ahuja38ef5e02015-03-13 17:31:16 +053011987 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_NO_LOAD_UNLOAD_IN_PROGRESS;
c_hpothu2de0ef62014-04-15 16:16:15 +053011988 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, FALSE);
Jeff Johnson295189b2012-06-20 16:38:30 -070011989 return VOS_STATUS_SUCCESS;
Jeff Johnson88ba7742013-02-27 14:36:02 -080011990 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011991
Katya Nigame7b69a82015-04-28 15:24:06 +053011992 if( VOS_MONITOR_MODE == hdd_get_conparam())
11993 {
11994 if ( VOS_STATUS_SUCCESS != wlan_hdd_mon_open(pHddCtx))
11995 {
11996 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: wlan_hdd_mon_open Failed",__func__);
11997 goto err_free_hdd_context;
11998 }
11999 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Driver loaded in Monitor Mode",__func__);
12000 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_NO_LOAD_UNLOAD_IN_PROGRESS;
12001 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, FALSE);
12002 return VOS_STATUS_SUCCESS;
12003 }
12004
Jeff Johnson88ba7742013-02-27 14:36:02 -080012005 //Open watchdog module
Jeff Johnson295189b2012-06-20 16:38:30 -070012006 if(pHddCtx->cfg_ini->fIsLogpEnabled)
12007 {
12008 status = vos_watchdog_open(pVosContext,
12009 &((VosContextType*)pVosContext)->vosWatchdog, sizeof(VosWatchdogContext));
12010
12011 if(!VOS_IS_STATUS_SUCCESS( status ))
12012 {
12013 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: vos_watchdog_open failed",__func__);
Ashish Kumar Dhanotiya532bdef2017-05-09 17:31:59 +053012014 goto err_config;
Jeff Johnson295189b2012-06-20 16:38:30 -070012015 }
12016 }
12017
12018 pHddCtx->isLogpInProgress = FALSE;
12019 vos_set_logp_in_progress(VOS_MODULE_ID_VOSS, FALSE);
12020
Amar Singhala49cbc52013-10-08 18:37:44 -070012021#ifdef CONFIG_ENABLE_LINUX_REG
Amar Singhal0a402232013-10-11 20:57:16 -070012022 /* initialize the NV module. This is required so that
12023 we can initialize the channel information in wiphy
12024 from the NV.bin data. The channel information in
12025 wiphy needs to be initialized before wiphy registration */
12026
12027 status = vos_nv_open();
12028 if (!VOS_IS_STATUS_SUCCESS(status))
12029 {
12030 /* NV module cannot be initialized */
12031 hddLog( VOS_TRACE_LEVEL_FATAL,
12032 "%s: vos_nv_open failed", __func__);
Vinay Krishna Eranna2025d892014-09-18 16:51:42 +053012033 goto err_wdclose;
Amar Singhal0a402232013-10-11 20:57:16 -070012034 }
12035
12036 status = vos_init_wiphy_from_nv_bin();
12037 if (!VOS_IS_STATUS_SUCCESS(status))
12038 {
12039 /* NV module cannot be initialized */
12040 hddLog( VOS_TRACE_LEVEL_FATAL,
12041 "%s: vos_init_wiphy failed", __func__);
12042 goto err_vos_nv_close;
12043 }
12044
Amar Singhala49cbc52013-10-08 18:37:44 -070012045#endif
Mahesh A Saptasagarc3ed0122016-01-19 16:45:11 +053012046 //Initialize the nlink service
12047 if(nl_srv_init() != 0)
12048 {
12049 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: nl_srv_init failed", __func__);
12050 goto err_vos_nv_close;
12051 }
12052
12053#ifdef WLAN_KD_READY_NOTIFIER
12054 pHddCtx->kd_nl_init = 1;
12055#endif /* WLAN_KD_READY_NOTIFIER */
12056
Girish Gowlibf0e1ab2015-01-19 16:05:16 +053012057 vos_set_roam_delay_stats_enabled(pHddCtx->cfg_ini->gEnableRoamDelayStats);
Arun Kumar Khandavalliebb19482014-03-25 13:56:53 +053012058 status = vos_open( &pVosContext, pHddCtx->parent_dev);
Jeff Johnson295189b2012-06-20 16:38:30 -070012059 if ( !VOS_IS_STATUS_SUCCESS( status ))
12060 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -080012061 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: vos_open failed", __func__);
Mahesh A Saptasagarc3ed0122016-01-19 16:45:11 +053012062 goto err_nl_srv;
Jeff Johnson295189b2012-06-20 16:38:30 -070012063 }
12064
Jeff Johnson295189b2012-06-20 16:38:30 -070012065 pHddCtx->hHal = (tHalHandle)vos_get_context( VOS_MODULE_ID_SME, pVosContext );
12066
12067 if ( NULL == pHddCtx->hHal )
12068 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -080012069 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: HAL context is null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070012070 goto err_vosclose;
12071 }
12072
Jeff Johnsonbc676b42013-02-14 16:04:08 -080012073 status = vos_preStart( pHddCtx->pvosContext );
12074 if ( !VOS_IS_STATUS_SUCCESS( status ) )
12075 {
12076 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: vos_preStart failed", __func__);
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053012077 goto err_vosclose;
Jeff Johnsonbc676b42013-02-14 16:04:08 -080012078 }
Jeff Johnsone7245742012-09-05 17:12:55 -070012079
Arif Hussaineaf68602013-12-30 23:10:44 -080012080 if (0 == enable_dfs_chan_scan || 1 == enable_dfs_chan_scan)
12081 {
12082 pHddCtx->cfg_ini->enableDFSChnlScan = enable_dfs_chan_scan;
12083 hddLog(VOS_TRACE_LEVEL_INFO, "%s: module enable_dfs_chan_scan set to %d",
12084 __func__, enable_dfs_chan_scan);
12085 }
12086 if (0 == enable_11d || 1 == enable_11d)
12087 {
12088 pHddCtx->cfg_ini->Is11dSupportEnabled = enable_11d;
12089 hddLog(VOS_TRACE_LEVEL_INFO, "%s: module enable_11d set to %d",
12090 __func__, enable_11d);
12091 }
12092
Jeff Johnsonbc676b42013-02-14 16:04:08 -080012093 /* Note that the vos_preStart() sequence triggers the cfg download.
12094 The cfg download must occur before we update the SME config
12095 since the SME config operation must access the cfg database */
Jeff Johnson295189b2012-06-20 16:38:30 -070012096 status = hdd_set_sme_config( pHddCtx );
12097
12098 if ( VOS_STATUS_SUCCESS != status )
12099 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -080012100 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Failed hdd_set_sme_config", __func__);
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053012101 goto err_vosclose;
Jeff Johnsonbc676b42013-02-14 16:04:08 -080012102 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012103
Jeff Johnson295189b2012-06-20 16:38:30 -070012104 /* In the integrated architecture we update the configuration from
12105 the INI file and from NV before vOSS has been started so that
12106 the final contents are available to send down to the cCPU */
12107
12108 // Apply the cfg.ini to cfg.dat
12109 if (FALSE == hdd_update_config_dat(pHddCtx))
12110 {
12111 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: config update failed",__func__ );
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053012112 goto err_vosclose;
Jeff Johnson295189b2012-06-20 16:38:30 -070012113 }
12114
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +053012115 // Get mac addr from platform driver
12116 ret = wcnss_get_wlan_mac_address((char*)&mac_addr.bytes);
12117
12118 if ((0 == ret) && (!vos_is_macaddr_zero(&mac_addr)))
Jeff Johnson295189b2012-06-20 16:38:30 -070012119 {
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +053012120 /* Store the mac addr for first interface */
12121 pHddCtx->cfg_ini->intfMacAddr[0] = mac_addr;
12122
12123 hddLog(VOS_TRACE_LEVEL_ERROR,
12124 "%s: WLAN Mac Addr: "
12125 MAC_ADDRESS_STR, __func__,
12126 MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[0].bytes));
12127
12128 /* Here, passing Arg2 as 1 because we do not want to change the
12129 last 3 bytes (means non OUI bytes) of first interface mac
12130 addr.
12131 */
12132 if (0 != hdd_generate_iface_mac_addr_auto(pHddCtx, 1, mac_addr))
12133 {
12134 hddLog(VOS_TRACE_LEVEL_ERROR,
12135 "%s: Failed to generate wlan interface mac addr "
12136 "using MAC from ini file ", __func__);
12137 }
12138 }
12139 else if (VOS_STATUS_SUCCESS != hdd_update_config_from_nv(pHddCtx))
12140 {
12141 // Apply the NV to cfg.dat
12142 /* Prima Update MAC address only at here */
Jeff Johnson295189b2012-06-20 16:38:30 -070012143#ifdef WLAN_AUTOGEN_MACADDR_FEATURE
12144 /* There was not a valid set of MAC Addresses in NV. See if the
12145 default addresses were modified by the cfg.ini settings. If so,
12146 we'll use them, but if not, we'll autogenerate a set of MAC
12147 addresses based upon the device serial number */
12148
12149 static const v_MACADDR_t default_address =
12150 {{0x00, 0x0A, 0xF5, 0x89, 0x89, 0xFF}};
Jeff Johnson295189b2012-06-20 16:38:30 -070012151
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +053012152 if (0 == memcmp(&default_address, &pHddCtx->cfg_ini->intfMacAddr[0],
12153 sizeof(default_address)))
Jeff Johnson295189b2012-06-20 16:38:30 -070012154 {
12155 /* cfg.ini has the default address, invoke autogen logic */
12156
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +053012157 /* Here, passing Arg2 as 0 because we want to change the
12158 last 3 bytes (means non OUI bytes) of all the interfaces
12159 mac addr.
12160 */
12161 if (0 != hdd_generate_iface_mac_addr_auto(pHddCtx, 0,
12162 default_address))
Jeff Johnson295189b2012-06-20 16:38:30 -070012163 {
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +053012164 hddLog(VOS_TRACE_LEVEL_ERROR,
12165 "%s: Failed to generate wlan interface mac addr "
12166 "using MAC from ini file " MAC_ADDRESS_STR, __func__,
12167 MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[0].bytes));
Jeff Johnson295189b2012-06-20 16:38:30 -070012168 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012169 }
12170 else
12171#endif //WLAN_AUTOGEN_MACADDR_FEATURE
12172 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -080012173 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070012174 "%s: Invalid MAC address in NV, using MAC from ini file "
12175 MAC_ADDRESS_STR, __func__,
12176 MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[0].bytes));
12177 }
12178 }
12179 {
12180 eHalStatus halStatus;
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +053012181
12182 /* Set the MAC Address Currently this is used by HAL to
12183 * add self sta. Remove this once self sta is added as
12184 * part of session open.
12185 */
Jeff Johnson295189b2012-06-20 16:38:30 -070012186 halStatus = cfgSetStr( pHddCtx->hHal, WNI_CFG_STA_ID,
12187 (v_U8_t *)&pHddCtx->cfg_ini->intfMacAddr[0],
12188 sizeof( pHddCtx->cfg_ini->intfMacAddr[0]) );
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +053012189
Jeff Johnson295189b2012-06-20 16:38:30 -070012190 if (!HAL_STATUS_SUCCESS( halStatus ))
12191 {
12192 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Failed to set MAC Address. "
12193 "HALStatus is %08d [x%08x]",__func__, halStatus, halStatus );
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053012194 goto err_vosclose;
Jeff Johnson295189b2012-06-20 16:38:30 -070012195 }
12196 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012197
12198 /*Start VOSS which starts up the SME/MAC/HAL modules and everything else
12199 Note: Firmware image will be read and downloaded inside vos_start API */
12200 status = vos_start( pHddCtx->pvosContext );
12201 if ( !VOS_IS_STATUS_SUCCESS( status ) )
12202 {
12203 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: vos_start failed",__func__);
Hanumantha Reddy Pothulabd9601a2016-02-12 13:22:27 +053012204 if (isSsrPanicOnFailure())
12205 VOS_BUG(0);
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053012206 goto err_vosclose;
Jeff Johnson295189b2012-06-20 16:38:30 -070012207 }
12208
Leo Chang6cec3e22014-01-21 15:33:49 -080012209#ifdef FEATURE_WLAN_CH_AVOID
12210 /* Plug in avoid channel notification callback
12211 * This should happen before ADD_SELF_STA
12212 * FW will send first IND with ADD_SELF_STA REQ from host */
Pradeep Reddy POTTETI5c2e16d2014-06-27 16:47:38 +053012213
12214 /* check the Channel Avoidance is enabled */
12215 if (TRUE == pHddCtx->cfg_ini->fenableCHAvoidance)
12216 {
12217 sme_AddChAvoidCallback(pHddCtx->hHal,
12218 hdd_hostapd_ch_avoid_cb);
12219 }
Leo Chang6cec3e22014-01-21 15:33:49 -080012220#endif /* FEATURE_WLAN_CH_AVOID */
12221
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -070012222 /* Exchange capability info between Host and FW and also get versioning info from FW */
12223 hdd_exchange_version_and_caps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -070012224
Agarwal Ashishad9281b2014-06-10 14:57:30 +053012225#ifdef CONFIG_ENABLE_LINUX_REG
12226 status = wlan_hdd_init_channels(pHddCtx);
12227 if ( !VOS_IS_STATUS_SUCCESS( status ) )
12228 {
12229 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: wlan_hdd_init_channels failed",
12230 __func__);
12231 goto err_vosstop;
12232 }
12233#endif
12234
Jeff Johnson295189b2012-06-20 16:38:30 -070012235 status = hdd_post_voss_start_config( pHddCtx );
12236 if ( !VOS_IS_STATUS_SUCCESS( status ) )
12237 {
12238 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hdd_post_voss_start_config failed",
12239 __func__);
12240 goto err_vosstop;
12241 }
Amar Singhala49cbc52013-10-08 18:37:44 -070012242
12243#ifndef CONFIG_ENABLE_LINUX_REG
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +053012244 wlan_hdd_cfg80211_update_reg_info( wiphy );
12245
12246 /* registration of wiphy dev with cfg80211 */
12247 if (0 > wlan_hdd_cfg80211_register(wiphy))
12248 {
12249 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy register failed", __func__);
12250 goto err_vosstop;
12251 }
Amar Singhala49cbc52013-10-08 18:37:44 -070012252#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070012253
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053012254#ifdef CONFIG_ENABLE_LINUX_REG
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053012255 /* registration of wiphy dev with cfg80211 */
12256 if (0 > wlan_hdd_cfg80211_register(wiphy))
12257 {
12258 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy register failed", __func__);
12259 goto err_vosstop;
12260 }
12261
Agarwal Ashish6db9d532014-09-30 18:19:10 +053012262 status = wlan_hdd_init_channels_for_cc(pHddCtx, INIT);
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053012263 if ( !VOS_IS_STATUS_SUCCESS( status ) )
12264 {
12265 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: wlan_hdd_init_channels_for_cc failed",
12266 __func__);
12267 goto err_unregister_wiphy;
12268 }
12269#endif
12270
c_hpothu4a298be2014-12-22 21:12:51 +053012271 wcnss_wlan_set_drvdata(pHddCtx->parent_dev, pHddCtx);
12272
Jeff Johnson295189b2012-06-20 16:38:30 -070012273 if (VOS_STA_SAP_MODE == hdd_get_conparam())
12274 {
12275 pAdapter = hdd_open_adapter( pHddCtx, WLAN_HDD_SOFTAP, "softap.%d",
12276 wlan_hdd_get_intf_addr(pHddCtx), FALSE );
12277 }
12278 else
12279 {
Jeff Johnson295189b2012-06-20 16:38:30 -070012280 pAdapter = hdd_open_adapter( pHddCtx, WLAN_HDD_INFRA_STATION, "wlan%d",
12281 wlan_hdd_get_intf_addr(pHddCtx), FALSE );
12282 if (pAdapter != NULL)
12283 {
Katya Nigama7d81d72014-11-12 12:44:34 +053012284 if (pHddCtx->cfg_ini->isP2pDeviceAddrAdministrated && !(pHddCtx->cfg_ini->intfMacAddr[0].bytes[0] & 0x02))
Jeff Johnson295189b2012-06-20 16:38:30 -070012285 {
Gopichand Nakkala49f96f62013-02-06 14:38:17 +053012286 vos_mem_copy( pHddCtx->p2pDeviceAddress.bytes,
12287 pHddCtx->cfg_ini->intfMacAddr[0].bytes,
12288 sizeof(tSirMacAddr));
Madan Mohan Koyyalamudiedfc1b72012-10-18 20:25:55 -070012289
Gopichand Nakkala49f96f62013-02-06 14:38:17 +053012290 /* Generate the P2P Device Address. This consists of the device's
12291 * primary MAC address with the locally administered bit set.
12292 */
12293 pHddCtx->p2pDeviceAddress.bytes[0] |= 0x02;
Jeff Johnsone7245742012-09-05 17:12:55 -070012294 }
12295 else
12296 {
Gopichand Nakkala49f96f62013-02-06 14:38:17 +053012297 tANI_U8* p2p_dev_addr = wlan_hdd_get_intf_addr(pHddCtx);
12298 if (p2p_dev_addr != NULL)
12299 {
12300 vos_mem_copy(&pHddCtx->p2pDeviceAddress.bytes[0],
12301 p2p_dev_addr, VOS_MAC_ADDR_SIZE);
12302 }
12303 else
12304 {
12305 hddLog(VOS_TRACE_LEVEL_FATAL,
12306 "%s: Failed to allocate mac_address for p2p_device",
12307 __func__);
12308 goto err_close_adapter;
12309 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012310 }
Jeff Johnsone7245742012-09-05 17:12:55 -070012311
12312 pP2pAdapter = hdd_open_adapter( pHddCtx, WLAN_HDD_P2P_DEVICE, "p2p%d",
12313 &pHddCtx->p2pDeviceAddress.bytes[0], FALSE );
12314 if ( NULL == pP2pAdapter )
12315 {
12316 hddLog(VOS_TRACE_LEVEL_FATAL,
12317 "%s: Failed to do hdd_open_adapter for P2P Device Interface",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070012318 __func__);
Jeff Johnsone7245742012-09-05 17:12:55 -070012319 goto err_close_adapter;
12320 }
Jeff Johnsone7245742012-09-05 17:12:55 -070012321 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012322 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012323
12324 if( pAdapter == NULL )
12325 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -080012326 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: hdd_open_adapter failed", __func__);
12327 goto err_close_adapter;
Jeff Johnson295189b2012-06-20 16:38:30 -070012328 }
Jeff Johnsone7245742012-09-05 17:12:55 -070012329
Arif Hussain66559122013-11-21 10:11:40 -080012330 if (country_code)
12331 {
12332 eHalStatus ret;
Arif Hussaincb607082013-12-20 11:57:42 -080012333 INIT_COMPLETION(pAdapter->change_country_code);
Arif Hussain66559122013-11-21 10:11:40 -080012334 hdd_checkandupdate_dfssetting(pAdapter, country_code);
12335#ifndef CONFIG_ENABLE_LINUX_REG
12336 hdd_checkandupdate_phymode(pAdapter, country_code);
12337#endif
Arif Hussaineaf68602013-12-30 23:10:44 -080012338 ret = sme_ChangeCountryCode(pHddCtx->hHal,
12339 (void *)(tSmeChangeCountryCallback)
12340 wlan_hdd_change_country_code_callback,
Arif Hussain66559122013-11-21 10:11:40 -080012341 country_code,
12342 pAdapter, pHddCtx->pvosContext,
Abhishek Singha306a442013-11-07 18:39:01 +053012343 eSIR_TRUE, eSIR_TRUE);
Arif Hussain66559122013-11-21 10:11:40 -080012344 if (eHAL_STATUS_SUCCESS == ret)
12345 {
Arif Hussaincb607082013-12-20 11:57:42 -080012346 ret = wait_for_completion_interruptible_timeout(
12347 &pAdapter->change_country_code,
12348 msecs_to_jiffies(WLAN_WAIT_TIME_COUNTRY));
12349
12350 if (0 >= ret)
12351 {
12352 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
12353 "%s: SME while setting country code timed out", __func__);
12354 }
Arif Hussain66559122013-11-21 10:11:40 -080012355 }
12356 else
12357 {
Arif Hussaincb607082013-12-20 11:57:42 -080012358 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
12359 "%s: SME Change Country code from module param fail ret=%d",
12360 __func__, ret);
Arif Hussain66559122013-11-21 10:11:40 -080012361 }
12362 }
12363
Jeff Johnson295189b2012-06-20 16:38:30 -070012364#ifdef WLAN_BTAMP_FEATURE
12365 vStatus = WLANBAP_Open(pVosContext);
12366 if(!VOS_IS_STATUS_SUCCESS(vStatus))
12367 {
12368 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
12369 "%s: Failed to open BAP",__func__);
Jeff Johnsone7245742012-09-05 17:12:55 -070012370 goto err_close_adapter;
Jeff Johnson295189b2012-06-20 16:38:30 -070012371 }
12372
12373 vStatus = BSL_Init(pVosContext);
12374 if(!VOS_IS_STATUS_SUCCESS(vStatus))
12375 {
12376 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
12377 "%s: Failed to Init BSL",__func__);
12378 goto err_bap_close;
12379 }
12380 vStatus = WLANBAP_Start(pVosContext);
12381 if (!VOS_IS_STATUS_SUCCESS(vStatus))
12382 {
12383 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
12384 "%s: Failed to start TL",__func__);
12385 goto err_bap_close;
12386 }
12387
12388 pConfig = pHddCtx->cfg_ini;
12389 btAmpConfig.ucPreferredChannel = pConfig->preferredChannel;
12390 status = WLANBAP_SetConfig(&btAmpConfig);
12391
12392#endif //WLAN_BTAMP_FEATURE
Jeff Johnsone7245742012-09-05 17:12:55 -070012393
Mihir Shete9c238772014-10-15 14:35:16 +053012394 /*
12395 * UapsdMask is 0xf if U-APSD is enbaled for all AC's...
12396 * The value of CFG_QOS_WMM_UAPSD_MASK_DEFAULT is 0xaa(Magic Value)
12397 * which is greater than 0xf. So the below check is safe to make
12398 * sure that there is no entry for UapsdMask in the ini
12399 */
12400 if (CFG_QOS_WMM_UAPSD_MASK_DEFAULT == pHddCtx->cfg_ini->UapsdMask)
12401 {
12402 if(IS_DYNAMIC_WMM_PS_ENABLED)
12403 {
12404 hddLog(VOS_TRACE_LEVEL_DEBUG,"%s: Enable UAPSD for VI & VO",
12405 __func__);
12406 pHddCtx->cfg_ini->UapsdMask =
12407 CFG_QOS_WMM_UAPSD_MASK_DYMANIC_WMM_PS_DEFAULT;
12408 }
12409 else
12410 {
12411 hddLog(VOS_TRACE_LEVEL_DEBUG,"%s: Do not enable UAPSD",
12412 __func__);
12413 pHddCtx->cfg_ini->UapsdMask =
12414 CFG_QOS_WMM_UAPSD_MASK_LEGACY_WMM_PS_DEFAULT;
12415 }
12416 }
12417
Varun Reddy Yeturud0a3f252013-04-15 21:58:13 -070012418#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
12419 if(!(IS_ROAM_SCAN_OFFLOAD_FEATURE_ENABLE))
12420 {
12421 hddLog(VOS_TRACE_LEVEL_DEBUG,"%s: ROAM_SCAN_OFFLOAD Feature not supported",__func__);
12422 pHddCtx->cfg_ini->isRoamOffloadScanEnabled = 0;
12423 sme_UpdateRoamScanOffloadEnabled((tHalHandle)(pHddCtx->hHal),
12424 pHddCtx->cfg_ini->isRoamOffloadScanEnabled);
12425 }
12426#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070012427
Agarwal Ashish4b87f922014-06-18 03:03:21 +053012428 wlan_hdd_tdls_init(pHddCtx);
12429
Masti, Narayanraddi26378462016-01-05 18:20:28 +053012430 wlan_hdd_init_deinit_defer_scan_context(&pHddCtx->scan_ctxt);
12431
12432 vos_init_delayed_work(&pHddCtx->scan_ctxt.scan_work,
12433 wlan_hdd_schedule_defer_scan);
12434
Mihir Shetefc7ff5b2014-01-27 11:30:05 +053012435 sme_Register11dScanDoneCallback(pHddCtx->hHal, hdd_11d_scan_done);
12436
Jeff Johnson295189b2012-06-20 16:38:30 -070012437 /* Register with platform driver as client for Suspend/Resume */
12438 status = hddRegisterPmOps(pHddCtx);
12439 if ( !VOS_IS_STATUS_SUCCESS( status ) )
12440 {
12441 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddRegisterPmOps failed",__func__);
12442#ifdef WLAN_BTAMP_FEATURE
12443 goto err_bap_stop;
12444#else
Jeff Johnsone7245742012-09-05 17:12:55 -070012445 goto err_close_adapter;
Jeff Johnson295189b2012-06-20 16:38:30 -070012446#endif //WLAN_BTAMP_FEATURE
12447 }
12448
Yue Ma0d4891e2013-08-06 17:01:45 -070012449 /* Open debugfs interface */
12450 if (VOS_STATUS_SUCCESS != hdd_debugfs_init(pAdapter))
12451 {
12452 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
12453 "%s: hdd_debugfs_init failed!", __func__);
Yue Ma0d4891e2013-08-06 17:01:45 -070012454 }
12455
Jeff Johnson295189b2012-06-20 16:38:30 -070012456 /* Register TM level change handler function to the platform */
12457 status = hddDevTmRegisterNotifyCallback(pHddCtx);
12458 if ( !VOS_IS_STATUS_SUCCESS( status ) )
12459 {
12460 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddDevTmRegisterNotifyCallback failed",__func__);
12461 goto err_unregister_pmops;
12462 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012463
Jeff Johnson295189b2012-06-20 16:38:30 -070012464 // register net device notifier for device change notification
12465 ret = register_netdevice_notifier(&hdd_netdev_notifier);
12466
12467 if(ret < 0)
12468 {
12469 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: register_netdevice_notifier failed",__func__);
Siddharth Bhalcd92b782015-06-29 12:25:40 +053012470 goto err_unregister_pmops;
Jeff Johnson295189b2012-06-20 16:38:30 -070012471 }
12472
Jeff Johnson295189b2012-06-20 16:38:30 -070012473 //Initialize the BTC service
12474 if(btc_activate_service(pHddCtx) != 0)
12475 {
12476 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: btc_activate_service failed",__func__);
Mahesh A Saptasagarc3ed0122016-01-19 16:45:11 +053012477 goto err_reg_netdev;
Jeff Johnson295189b2012-06-20 16:38:30 -070012478 }
12479
Padma, Santhosh Kumar2762e9d2015-10-20 15:02:57 +053012480#ifdef FEATURE_OEM_DATA_SUPPORT
12481 //Initialize the OEM service
12482 if (oem_activate_service(pHddCtx) != 0)
12483 {
12484 hddLog(VOS_TRACE_LEVEL_FATAL,
12485 "%s: oem_activate_service failed", __func__);
Mahesh A Saptasagarc3ed0122016-01-19 16:45:11 +053012486 goto err_reg_netdev;
Padma, Santhosh Kumar2762e9d2015-10-20 15:02:57 +053012487 }
12488#endif
12489
Jeff Johnson295189b2012-06-20 16:38:30 -070012490#ifdef PTT_SOCK_SVC_ENABLE
12491 //Initialize the PTT service
12492 if(ptt_sock_activate_svc(pHddCtx) != 0)
12493 {
12494 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: ptt_sock_activate_svc failed",__func__);
Mahesh A Saptasagarc3ed0122016-01-19 16:45:11 +053012495 goto err_reg_netdev;
Jeff Johnson295189b2012-06-20 16:38:30 -070012496 }
12497#endif
12498
Abhishek Singh00b71972016-01-07 10:51:04 +053012499#ifdef WLAN_FEATURE_RMC
12500 if (hdd_open_cesium_nl_sock() < 0)
12501 {
12502 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hdd_open_cesium_nl_sock failed", __func__);
12503 goto err_reg_netdev;
12504 }
12505#endif
12506
Vinay Krishna Erannad938c422014-03-10 17:14:21 +053012507#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
12508 if(pHddCtx->cfg_ini && pHddCtx->cfg_ini->wlanLoggingEnable)
12509 {
Deepthi Gowri78083a32014-11-04 12:55:51 +053012510 if(wlan_logging_sock_activate_svc(
12511 pHddCtx->cfg_ini->wlanLoggingFEToConsole,
Sushant Kaushik33200572015-08-05 16:46:20 +053012512 pHddCtx->cfg_ini->wlanLoggingNumBuf,
12513 pHddCtx->cfg_ini->wlanPerPktStatsLogEnable,
12514 pHddCtx->cfg_ini->wlanPerPktStatsNumBuf))
Deepthi Gowri78083a32014-11-04 12:55:51 +053012515 {
12516 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wlan_logging_sock_activate_svc"
12517 " failed", __func__);
Mahesh A Saptasagarc3ed0122016-01-19 16:45:11 +053012518 goto err_reg_netdev;
Deepthi Gowri78083a32014-11-04 12:55:51 +053012519 }
12520 //TODO: To Remove enableDhcpDebug and use gEnableDebugLog for
12521 //EAPOL and DHCP
Sachin Ahuja8c65f382014-12-12 15:34:21 +053012522 if (!pHddCtx->cfg_ini->gEnableDebugLog)
12523 pHddCtx->cfg_ini->gEnableDebugLog =
Sushant Kaushik6e4e2bc2015-10-05 17:23:07 +053012524 VOS_PKT_PROTO_TYPE_EAPOL | VOS_PKT_PROTO_TYPE_DHCP |
12525 VOS_PKT_PROTO_TYPE_ARP;
Vinay Krishna Erannad938c422014-03-10 17:14:21 +053012526 }
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053012527
Siddharth Bhald1be97f2015-05-27 22:39:59 +053012528 if (pHddCtx->cfg_ini->wlanLoggingEnable &&
12529 (pHddCtx->cfg_ini->enableFWLogging ||
Siddharth Bhaldb963232015-06-25 19:34:35 +053012530 pHddCtx->cfg_ini->enableMgmtLogging ||
c_manjeecfd1efb2015-09-25 19:32:34 +053012531 pHddCtx->cfg_ini->enableContFWLogging ||
12532 pHddCtx->cfg_ini->enableFwrMemDump )
12533 )
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053012534 {
Siddharth Bhald1be97f2015-05-27 22:39:59 +053012535 hdd_init_frame_logging(pHddCtx);
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053012536 }
12537 else
12538 {
Siddharth Bhald1be97f2015-05-27 22:39:59 +053012539 hddLog(VOS_TRACE_LEVEL_INFO, FL("Logging disabled in ini"));
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053012540 }
12541
Vinay Krishna Erannad938c422014-03-10 17:14:21 +053012542#endif
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053012543
Agrawal Ashish17ef5082016-10-17 18:33:21 +053012544#ifdef SAP_AUTH_OFFLOAD
12545 if (!sme_IsFeatureSupportedByFW(SAP_OFFLOADS))
12546 {
12547 hddLog(VOS_TRACE_LEVEL_INFO, FL(" SAP AUTH OFFLOAD not supp by FW"));
12548 pHddCtx->cfg_ini->enable_sap_auth_offload = 0;
12549 }
12550#endif
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053012551
Sushant Kaushik215778f2015-05-21 14:05:36 +053012552 if (vos_is_multicast_logging())
12553 wlan_logging_set_log_level();
12554
Jeff Johnson295189b2012-06-20 16:38:30 -070012555 hdd_register_mcast_bcast_filter(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -070012556 if (VOS_STA_SAP_MODE != hdd_get_conparam())
Jeff Johnson295189b2012-06-20 16:38:30 -070012557 {
Madan Mohan Koyyalamudic537df22012-10-22 15:07:08 -070012558 /* Action frame registered in one adapter which will
12559 * applicable to all interfaces
12560 */
Agarwal Ashish8fa0e9a2014-05-23 00:40:12 +053012561 wlan_hdd_cfg80211_register_frames(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070012562 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012563
12564 mutex_init(&pHddCtx->sap_lock);
Mahesh A Saptasagar60627942014-10-13 13:55:14 +053012565 mutex_init(&pHddCtx->roc_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -070012566
Jeff Johnsone7245742012-09-05 17:12:55 -070012567#ifdef WLAN_FEATURE_HOLD_RX_WAKELOCK
12568 /* Initialize the wake lcok */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053012569 vos_wake_lock_init(&pHddCtx->rx_wake_lock,
Jeff Johnsone7245742012-09-05 17:12:55 -070012570 "qcom_rx_wakelock");
Sushant Kaushik83392fa2015-05-05 17:44:40 +053012571
Jeff Johnsone7245742012-09-05 17:12:55 -070012572#endif
Madan Mohan Koyyalamudi69fc3ad2012-11-28 16:04:56 -080012573 /* Initialize the wake lcok */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053012574 vos_wake_lock_init(&pHddCtx->sap_wake_lock,
Madan Mohan Koyyalamudi69fc3ad2012-11-28 16:04:56 -080012575 "qcom_sap_wakelock");
Sushant Kaushik83392fa2015-05-05 17:44:40 +053012576
Jeff Johnsone7245742012-09-05 17:12:55 -070012577
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070012578 vos_event_init(&pHddCtx->scan_info.scan_finished_event);
12579 pHddCtx->scan_info.scan_pending_option = WEXT_SCAN_PENDING_GIVEUP;
Jeff Johnson295189b2012-06-20 16:38:30 -070012580
Katya Nigam5c306ea2014-06-19 15:39:54 +053012581 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_NO_LOAD_UNLOAD_IN_PROGRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -070012582 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, FALSE);
Sushant Kaushik83392fa2015-05-05 17:44:40 +053012583 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_DRIVER_INIT);
Katya Nigam5c306ea2014-06-19 15:39:54 +053012584
12585#ifdef FEATURE_WLAN_SCAN_PNO
12586 /*SME must send channel update configuration to RIVA*/
12587 sme_UpdateChannelConfig(pHddCtx->hHal);
12588#endif
Abhishek Singhf644b272014-08-21 02:59:39 +053012589 /* Send the update default channel list to the FW*/
12590 sme_UpdateChannelList(pHddCtx->hHal);
Mukul Sharma45063942015-04-01 20:07:59 +053012591
12592 /* Fwr capabilities received, Set the Dot11 mode */
Abhishek Singh41ebce12016-02-03 10:43:21 +053012593 sme_SetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter),
12594 hdd_cfg_xlate_to_csr_phy_mode(pHddCtx->cfg_ini->dot11Mode));
Mukul Sharma45063942015-04-01 20:07:59 +053012595 sme_SetDefDot11Mode(pHddCtx->hHal);
12596
Abhishek Singha306a442013-11-07 18:39:01 +053012597#ifndef CONFIG_ENABLE_LINUX_REG
12598 /*updating wiphy so that regulatory user hints can be processed*/
12599 if (wiphy)
12600 {
12601 regulatory_hint(wiphy, "00");
12602 }
12603#endif
Jeff Johnsone7245742012-09-05 17:12:55 -070012604 // Initialize the restart logic
12605 wlan_hdd_restart_init(pHddCtx);
Chilam NG571c65a2013-01-19 12:27:36 +053012606
Hanumanth Reddy Pothula146bca42016-11-08 12:01:07 +053012607 if (pHddCtx->cfg_ini->fIsLogpEnabled) {
12608 vos_wdthread_init_timer_work(vos_process_wd_timer);
12609 /* Initialize the timer to detect thread stuck issues */
12610 vos_thread_stuck_timer_init(
12611 &((VosContextType*)pVosContext)->vosWatchdog);
12612 }
12613
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -070012614 //Register the traffic monitor timer now
12615 if ( pHddCtx->cfg_ini->dynSplitscan)
12616 {
12617 vos_timer_init(&pHddCtx->tx_rx_trafficTmr,
12618 VOS_TIMER_TYPE_SW,
12619 hdd_tx_rx_pkt_cnt_stat_timer_handler,
12620 (void *)pHddCtx);
12621 }
Srinivas Dasari030bad32015-02-18 23:23:54 +053012622 wlan_hdd_cfg80211_nan_init(pHddCtx);
12623
Bhargav Shahd0715912015-10-01 18:17:37 +053012624 mutex_init(&pHddCtx->cur_rx_level_lock);
12625 vos_timer_init(&pHddCtx->delack_timer, VOS_TIMER_TYPE_SW,
12626 hdd_tcp_delack_compute_function,(void *)pHddCtx);
Masti, Narayanraddi44b0db02015-12-22 11:54:35 +053012627 vos_timer_init(&pHddCtx->tdls_source_timer, VOS_TIMER_TYPE_SW,
12628 wlan_hdd_change_tdls_mode, (void *)pHddCtx);
Bhargav Shahd0715912015-10-01 18:17:37 +053012629
Dino Mycle6fb96c12014-06-10 11:52:40 +053012630#ifdef WLAN_FEATURE_EXTSCAN
12631 sme_EXTScanRegisterCallback(pHddCtx->hHal,
12632 wlan_hdd_cfg80211_extscan_callback,
12633 pHddCtx);
12634#endif /* WLAN_FEATURE_EXTSCAN */
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +053012635
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053012636#ifdef FEATURE_OEM_DATA_SUPPORT
12637 sme_OemDataRegisterCallback(pHddCtx->hHal,
12638 wlan_hdd_cfg80211_oemdata_callback,
12639 pHddCtx);
12640#endif /* FEATURE_OEM_DATA_SUPPORT */
12641
Gupta, Kapil7c34b322015-09-30 13:12:35 +053012642 sme_set_rssi_threshold_breached_cb(pHddCtx->hHal, hdd_rssi_threshold_breached_cb);
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +053012643#ifdef WLAN_NS_OFFLOAD
12644 // Register IPv6 notifier to notify if any change in IP
12645 // So that we can reconfigure the offload parameters
12646 pHddCtx->ipv6_notifier.notifier_call = wlan_hdd_ipv6_changed;
12647 ret = register_inet6addr_notifier(&pHddCtx->ipv6_notifier);
12648 if (ret)
12649 {
Ratheesh S P36dbc932015-08-07 14:28:57 +053012650 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to register IPv6 notifier"));
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +053012651 }
12652 else
12653 {
Ratheesh S P36dbc932015-08-07 14:28:57 +053012654 hddLog(VOS_TRACE_LEVEL_INFO, FL("Registered IPv6 notifier"));
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +053012655 }
12656#endif
12657
Sravan Kumar Kairamb0edc612016-10-26 13:55:24 +053012658 vos_mem_set((uint8_t *)&pHddCtx->bad_sta, HDD_MAX_STA_COUNT, 0);
12659
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +053012660 // Register IPv4 notifier to notify if any change in IP
12661 // So that we can reconfigure the offload parameters
12662 pHddCtx->ipv4_notifier.notifier_call = wlan_hdd_ipv4_changed;
12663 ret = register_inetaddr_notifier(&pHddCtx->ipv4_notifier);
12664 if (ret)
12665 {
Ratheesh S P36dbc932015-08-07 14:28:57 +053012666 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to register IPv4 notifier"));
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +053012667 }
12668 else
12669 {
Ratheesh S P36dbc932015-08-07 14:28:57 +053012670 hddLog(VOS_TRACE_LEVEL_INFO, FL("Registered IPv4 notifier"));
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +053012671 }
c_manjeecfd1efb2015-09-25 19:32:34 +053012672 /*Fw mem dump procfs initialization*/
12673 memdump_init();
Bhargav shah23c94942015-10-13 12:48:35 +053012674 hdd_dp_util_send_rps_ind(pHddCtx);
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +053012675
Nishank Aggarwalc11826c2016-12-15 18:54:10 +053012676 pHddCtx->is_ap_mode_wow_supported =
12677 sme_IsFeatureSupportedByFW(SAP_MODE_WOW);
Sravan Kumar Kairam091e5b62017-01-23 14:14:20 +053012678
Hanumanth Reddy Pothulae92bcc12017-05-19 13:56:35 +053012679 pHddCtx->is_fatal_event_log_sup =
12680 sme_IsFeatureSupportedByFW(FATAL_EVENT_LOGGING);
12681 hddLog(VOS_TRACE_LEVEL_INFO, FL("FATAL_EVENT_LOGGING: %d"),
12682 pHddCtx->is_fatal_event_log_sup);
12683
Sravan Kumar Kairam091e5b62017-01-23 14:14:20 +053012684 hdd_assoc_registerFwdEapolCB(pVosContext);
12685
Jeff Johnson295189b2012-06-20 16:38:30 -070012686 goto success;
12687
Jeff Johnson295189b2012-06-20 16:38:30 -070012688err_reg_netdev:
12689 unregister_netdevice_notifier(&hdd_netdev_notifier);
12690
Jeff Johnson295189b2012-06-20 16:38:30 -070012691err_unregister_pmops:
12692 hddDevTmUnregisterNotifyCallback(pHddCtx);
12693 hddDeregisterPmOps(pHddCtx);
12694
Yue Ma0d4891e2013-08-06 17:01:45 -070012695 hdd_debugfs_exit(pHddCtx);
12696
Jeff Johnson295189b2012-06-20 16:38:30 -070012697#ifdef WLAN_BTAMP_FEATURE
12698err_bap_stop:
12699 WLANBAP_Stop(pVosContext);
12700#endif
12701
12702#ifdef WLAN_BTAMP_FEATURE
12703err_bap_close:
12704 WLANBAP_Close(pVosContext);
12705#endif
12706
Jeff Johnson295189b2012-06-20 16:38:30 -070012707err_close_adapter:
12708 hdd_close_all_adapters( pHddCtx );
Mahesh A Saptasagar9ecefe42014-07-15 18:43:49 +053012709#ifdef CONFIG_ENABLE_LINUX_REG
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053012710err_unregister_wiphy:
Mahesh A Saptasagar9ecefe42014-07-15 18:43:49 +053012711#endif
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +053012712 wiphy_unregister(wiphy) ;
Agrawal Ashish33ec71e2015-11-26 20:20:58 +053012713 hdd_wlan_free_wiphy_channels(wiphy);
12714
Jeff Johnson295189b2012-06-20 16:38:30 -070012715err_vosstop:
12716 vos_stop(pVosContext);
12717
Amar Singhala49cbc52013-10-08 18:37:44 -070012718err_vosclose:
Jeff Johnson295189b2012-06-20 16:38:30 -070012719 status = vos_sched_close( pVosContext );
12720 if (!VOS_IS_STATUS_SUCCESS(status)) {
12721 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
12722 "%s: Failed to close VOSS Scheduler", __func__);
12723 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( status ) );
12724 }
Amar Singhala49cbc52013-10-08 18:37:44 -070012725 vos_close(pVosContext );
12726
Mahesh A Saptasagarc3ed0122016-01-19 16:45:11 +053012727err_nl_srv:
12728#ifdef WLAN_KD_READY_NOTIFIER
12729 nl_srv_exit(pHddCtx->ptt_pid);
12730#else
12731 nl_srv_exit();
12732#endif /* WLAN_KD_READY_NOTIFIER */
Amar Singhal0a402232013-10-11 20:57:16 -070012733err_vos_nv_close:
12734
c_hpothue6a36282014-03-19 12:27:38 +053012735#ifdef CONFIG_ENABLE_LINUX_REG
Amar Singhal0a402232013-10-11 20:57:16 -070012736 vos_nv_close();
12737
c_hpothu70f8d812014-03-22 22:59:23 +053012738#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070012739
12740err_wdclose:
12741 if(pHddCtx->cfg_ini->fIsLogpEnabled)
12742 vos_watchdog_close(pVosContext);
12743
Jeff Johnson295189b2012-06-20 16:38:30 -070012744err_config:
12745 kfree(pHddCtx->cfg_ini);
12746 pHddCtx->cfg_ini= NULL;
12747
12748err_free_hdd_context:
Sushant Kaushik83392fa2015-05-05 17:44:40 +053012749 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_DRIVER_INIT);
Siddharth Bhalcd92b782015-06-29 12:25:40 +053012750 free_riva_power_on_lock("wlan");
Jeff Johnson295189b2012-06-20 16:38:30 -070012751 wiphy_free(wiphy) ;
12752 //kfree(wdev) ;
Jeff Johnson295189b2012-06-20 16:38:30 -070012753 VOS_BUG(1);
12754
Madan Mohan Koyyalamudid57ae632012-11-06 18:42:48 -080012755 if (hdd_is_ssr_required())
12756 {
12757 /* WDI timeout had happened during load, so SSR is needed here */
12758 subsystem_restart("wcnss");
12759 msleep(5000);
12760 }
12761 hdd_set_ssr_required (VOS_FALSE);
12762
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -080012763 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -070012764
12765success:
12766 EXIT();
12767 return 0;
12768}
12769
12770/**---------------------------------------------------------------------------
12771
Jeff Johnson32d95a32012-09-10 13:15:23 -070012772 \brief hdd_driver_init() - Core Driver Init Function
Jeff Johnson295189b2012-06-20 16:38:30 -070012773
Jeff Johnson32d95a32012-09-10 13:15:23 -070012774 This is the driver entry point - called in different timeline depending
12775 on whether the driver is statically or dynamically linked
Jeff Johnson295189b2012-06-20 16:38:30 -070012776
12777 \param - None
12778
12779 \return - 0 for success, non zero for failure
12780
12781 --------------------------------------------------------------------------*/
Jeff Johnson32d95a32012-09-10 13:15:23 -070012782static int hdd_driver_init( void)
Jeff Johnson295189b2012-06-20 16:38:30 -070012783{
12784 VOS_STATUS status;
12785 v_CONTEXT_t pVosContext = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070012786 struct device *dev = NULL;
12787 int ret_status = 0;
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -070012788#ifdef HAVE_WCNSS_CAL_DOWNLOAD
12789 int max_retries = 0;
12790#endif
Siddharth Bhalc7e79b62014-10-10 22:37:38 +053012791#ifdef HAVE_CBC_DONE
12792 int max_cbc_retries = 0;
12793#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070012794
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +053012795#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
12796 wlan_logging_sock_init_svc();
12797#endif
12798
Jeff Johnson295189b2012-06-20 16:38:30 -070012799 ENTER();
12800
Sushant Kaushik83392fa2015-05-05 17:44:40 +053012801 vos_wake_lock_init(&wlan_wake_lock, "wlan");
Jeff Johnson295189b2012-06-20 16:38:30 -070012802
12803 pr_info("%s: loading driver v%s\n", WLAN_MODULE_NAME,
12804 QWLAN_VERSIONSTR TIMER_MANAGER_STR MEMORY_DEBUG_STR);
12805
Jeff Johnson295189b2012-06-20 16:38:30 -070012806#ifdef ANI_BUS_TYPE_PCI
12807
12808 dev = wcnss_wlan_get_device();
12809
12810#endif // ANI_BUS_TYPE_PCI
12811
12812#ifdef ANI_BUS_TYPE_PLATFORM
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -070012813
12814#ifdef HAVE_WCNSS_CAL_DOWNLOAD
12815 /* wait until WCNSS driver downloads NV */
Ravi Kumar Bokka7a139e62016-11-17 21:32:55 +053012816 while (!wcnss_device_ready() && 10 >= ++max_retries) {
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -070012817 msleep(1000);
12818 }
Siddharth Bhalc7e79b62014-10-10 22:37:38 +053012819
Ravi Kumar Bokka7a139e62016-11-17 21:32:55 +053012820 if (max_retries >= 10) {
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -070012821 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: WCNSS driver not ready", __func__);
Sushant Kaushik83392fa2015-05-05 17:44:40 +053012822 vos_wake_lock_destroy(&wlan_wake_lock);
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +053012823#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
12824 wlan_logging_sock_deinit_svc();
12825#endif
12826
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -070012827 return -ENODEV;
12828 }
12829#endif
12830
Siddharth Bhalc7e79b62014-10-10 22:37:38 +053012831#ifdef HAVE_CBC_DONE
12832 while (!wcnss_cbc_complete() && 10 >= ++max_cbc_retries) {
12833 msleep(1000);
12834 }
12835 if (max_cbc_retries >= 10) {
12836 hddLog(VOS_TRACE_LEVEL_FATAL, "%s:CBC not completed", __func__);
12837 }
12838#endif
12839
Jeff Johnson295189b2012-06-20 16:38:30 -070012840 dev = wcnss_wlan_get_device();
12841#endif // ANI_BUS_TYPE_PLATFORM
12842
12843
12844 do {
12845 if (NULL == dev) {
12846 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: WLAN device not found!!",__func__);
12847 ret_status = -1;
12848 break;
12849 }
12850
Jeff Johnson295189b2012-06-20 16:38:30 -070012851#ifdef TIMER_MANAGER
12852 vos_timer_manager_init();
12853#endif
12854
12855 /* Preopen VOSS so that it is ready to start at least SAL */
12856 status = vos_preOpen(&pVosContext);
12857
12858 if (!VOS_IS_STATUS_SUCCESS(status))
12859 {
12860 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Failed to preOpen VOSS", __func__);
12861 ret_status = -1;
12862 break;
12863 }
12864
Sushant Kaushik02beb352015-06-04 15:15:01 +053012865 hddTraceInit();
Padma, Santhosh Kumar9093b202015-07-21 15:37:38 +053012866 hdd_register_debug_callback();
12867
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070012868#ifndef MODULE
12869 /* For statically linked driver, call hdd_set_conparam to update curr_con_mode
12870 */
12871 hdd_set_conparam((v_UINT_t)con_mode);
12872#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070012873
12874 // Call our main init function
Jeff Johnsonbc676b42013-02-14 16:04:08 -080012875 if (hdd_wlan_startup(dev))
12876 {
Jeff Johnson295189b2012-06-20 16:38:30 -070012877 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: WLAN Driver Initialization failed",
Jeff Johnsonbc676b42013-02-14 16:04:08 -080012878 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070012879 vos_preClose( &pVosContext );
12880 ret_status = -1;
12881 break;
12882 }
12883
Jeff Johnson295189b2012-06-20 16:38:30 -070012884 } while (0);
12885
12886 if (0 != ret_status)
12887 {
Jeff Johnson295189b2012-06-20 16:38:30 -070012888#ifdef TIMER_MANAGER
12889 vos_timer_exit();
12890#endif
12891#ifdef MEMORY_DEBUG
12892 vos_mem_exit();
12893#endif
Sushant Kaushik83392fa2015-05-05 17:44:40 +053012894 vos_wake_lock_destroy(&wlan_wake_lock);
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +053012895#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
12896 wlan_logging_sock_deinit_svc();
12897#endif
12898
Jeff Johnson295189b2012-06-20 16:38:30 -070012899 pr_err("%s: driver load failure\n", WLAN_MODULE_NAME);
12900 }
12901 else
12902 {
12903 //Send WLAN UP indication to Nlink Service
12904 send_btc_nlink_msg(WLAN_MODULE_UP_IND, 0);
12905
12906 pr_info("%s: driver loaded\n", WLAN_MODULE_NAME);
Jeff Johnson295189b2012-06-20 16:38:30 -070012907 }
12908
12909 EXIT();
12910
12911 return ret_status;
12912}
12913
Jeff Johnson32d95a32012-09-10 13:15:23 -070012914/**---------------------------------------------------------------------------
12915
12916 \brief hdd_module_init() - Init Function
12917
12918 This is the driver entry point (invoked when module is loaded using insmod)
12919
12920 \param - None
12921
12922 \return - 0 for success, non zero for failure
12923
12924 --------------------------------------------------------------------------*/
12925#ifdef MODULE
12926static int __init hdd_module_init ( void)
12927{
12928 return hdd_driver_init();
12929}
Jeff Johnson32d95a32012-09-10 13:15:23 -070012930#else /* #ifdef MODULE */
12931static int __init hdd_module_init ( void)
12932{
12933 /* Driver initialization is delayed to fwpath_changed_handler */
12934 return 0;
12935}
Jeff Johnson32d95a32012-09-10 13:15:23 -070012936#endif /* #ifdef MODULE */
12937
Jeff Johnson295189b2012-06-20 16:38:30 -070012938
12939/**---------------------------------------------------------------------------
12940
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070012941 \brief hdd_driver_exit() - Exit function
Jeff Johnson295189b2012-06-20 16:38:30 -070012942
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070012943 This is the driver exit point (invoked when module is unloaded using rmmod
12944 or con_mode was changed by userspace)
Jeff Johnson295189b2012-06-20 16:38:30 -070012945
12946 \param - None
12947
12948 \return - None
12949
12950 --------------------------------------------------------------------------*/
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070012951static void hdd_driver_exit(void)
Jeff Johnson295189b2012-06-20 16:38:30 -070012952{
12953 hdd_context_t *pHddCtx = NULL;
12954 v_CONTEXT_t pVosContext = NULL;
Agarwal Ashish5e414792014-06-08 15:25:23 +053012955 v_REGDOMAIN_t regId;
Arun Kumar Khandavallie0b046d2014-03-01 21:54:25 +053012956 unsigned long rc = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070012957
12958 pr_info("%s: unloading driver v%s\n", WLAN_MODULE_NAME, QWLAN_VERSIONSTR);
12959
12960 //Get the global vos context
12961 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
12962
12963 if(!pVosContext)
12964 {
12965 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Global VOS context is Null", __func__);
12966 goto done;
12967 }
12968
12969 //Get the HDD context.
12970 pHddCtx = (hdd_context_t *)vos_get_context(VOS_MODULE_ID_HDD, pVosContext );
12971
12972 if(!pHddCtx)
12973 {
12974 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: module exit called before probe",__func__);
12975 }
Katya Nigame7b69a82015-04-28 15:24:06 +053012976 else if (VOS_MONITOR_MODE == hdd_get_conparam())
12977 {
12978 hddLog(VOS_TRACE_LEVEL_INFO,"%s: MONITOR MODE",__func__);
12979 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_UNLOAD_IN_PROGRESS;
12980 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, TRUE);
12981 hdd_wlan_exit(pHddCtx);
12982 vos_preClose( &pVosContext );
12983 goto done;
12984 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012985 else
12986 {
Siddharth Bhal2e5871b2015-03-24 16:20:51 +053012987 /* We wait for active entry threads to exit from driver
12988 * by waiting until rtnl_lock is available.
12989 */
12990 rtnl_lock();
12991 rtnl_unlock();
12992
Siddharth Bhal3c29dca2015-02-19 00:41:40 +053012993 INIT_COMPLETION(pHddCtx->ssr_comp_var);
12994 if ((pHddCtx->isLogpInProgress) && (FALSE ==
12995 vos_is_wlan_in_badState(VOS_MODULE_ID_HDD, NULL)))
12996 {
Siddharth Bhala204f572015-01-17 02:03:36 +053012997 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Siddharth Bhal3c29dca2015-02-19 00:41:40 +053012998 "%s:SSR in Progress; block rmmod !!!", __func__);
Siddharth Bhala204f572015-01-17 02:03:36 +053012999 rc = wait_for_completion_timeout(&pHddCtx->ssr_comp_var,
13000 msecs_to_jiffies(30000));
13001 if(!rc)
13002 {
13003 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
13004 "%s:SSR timedout, fatal error", __func__);
13005 VOS_BUG(0);
13006 }
13007 }
13008
Siddharth Bhal3c29dca2015-02-19 00:41:40 +053013009 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_UNLOAD_IN_PROGRESS;
13010 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, TRUE);
Jeff Johnson295189b2012-06-20 16:38:30 -070013011
c_hpothu8adb97b2014-12-08 19:38:20 +053013012 /* Driver Need to send country code 00 in below condition
13013 * 1) If gCountryCodePriority is set to 1; and last country
13014 * code set is through 11d. This needs to be done in case
13015 * when NV country code is 00.
13016 * This Needs to be done as when kernel store last country
13017 * code and if stored country code is not through 11d,
13018 * in sme_HandleChangeCountryCodeByUser we will disable 11d
13019 * in next load/unload as soon as we get any country through
13020 * 11d. In sme_HandleChangeCountryCodeByUser
13021 * pMsg->countryCode will be last countryCode and
13022 * pMac->scan.countryCode11d will be country through 11d so
13023 * due to mismatch driver will disable 11d.
13024 *
13025 */
Agarwal Ashish8db39882014-07-30 21:56:07 +053013026
c_hpothu8adb97b2014-12-08 19:38:20 +053013027 if ((eANI_BOOLEAN_TRUE == sme_Is11dCountrycode(pHddCtx->hHal) &&
Agarwal Ashish8dcd2862014-07-25 11:58:52 +053013028 pHddCtx->cfg_ini->fSupplicantCountryCodeHasPriority &&
Abhishek Singh2a705962014-10-30 14:47:28 +053013029 sme_Is11dSupported(pHddCtx->hHal)))
c_hpothu8adb97b2014-12-08 19:38:20 +053013030 {
13031 hddLog(VOS_TRACE_LEVEL_INFO,
Agarwal Ashish8dcd2862014-07-25 11:58:52 +053013032 FL("CountryCode 00 is being set while unloading driver"));
c_hpothu8adb97b2014-12-08 19:38:20 +053013033 vos_nv_getRegDomainFromCountryCode(&regId , "00", COUNTRY_USER);
13034 }
Agarwal Ashish5e414792014-06-08 15:25:23 +053013035
c_hpothu8adb97b2014-12-08 19:38:20 +053013036 //Do all the cleanup before deregistering the driver
13037 hdd_wlan_exit(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -070013038 }
13039
Jeff Johnson295189b2012-06-20 16:38:30 -070013040 vos_preClose( &pVosContext );
13041
13042#ifdef TIMER_MANAGER
13043 vos_timer_exit();
13044#endif
13045#ifdef MEMORY_DEBUG
13046 vos_mem_exit();
13047#endif
13048
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +053013049#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
13050 wlan_logging_sock_deinit_svc();
13051#endif
13052
Jeff Johnson295189b2012-06-20 16:38:30 -070013053done:
Sushant Kaushik83392fa2015-05-05 17:44:40 +053013054 vos_wake_lock_destroy(&wlan_wake_lock);
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +053013055
Jeff Johnson295189b2012-06-20 16:38:30 -070013056 pr_info("%s: driver unloaded\n", WLAN_MODULE_NAME);
13057}
13058
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070013059/**---------------------------------------------------------------------------
13060
13061 \brief hdd_module_exit() - Exit function
13062
13063 This is the driver exit point (invoked when module is unloaded using rmmod)
13064
13065 \param - None
13066
13067 \return - None
13068
13069 --------------------------------------------------------------------------*/
13070static void __exit hdd_module_exit(void)
13071{
13072 hdd_driver_exit();
13073}
13074
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070013075#ifdef MODULE
13076static int fwpath_changed_handler(const char *kmessage,
13077 struct kernel_param *kp)
13078{
Jeff Johnson76052702013-04-16 13:55:05 -070013079 return param_set_copystring(kmessage, kp);
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070013080}
13081
13082static int con_mode_handler(const char *kmessage,
13083 struct kernel_param *kp)
13084{
Madan Mohan Koyyalamudif2f8d8b2012-10-11 17:06:59 -070013085 return param_set_int(kmessage, kp);
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070013086}
13087#else /* #ifdef MODULE */
13088/**---------------------------------------------------------------------------
13089
Jeff Johnson76052702013-04-16 13:55:05 -070013090 \brief kickstart_driver
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070013091
Jeff Johnson76052702013-04-16 13:55:05 -070013092 This is the driver entry point
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070013093 - delayed driver initialization when driver is statically linked
Jeff Johnson76052702013-04-16 13:55:05 -070013094 - invoked when module parameter fwpath is modified from userspace to signal
13095 initializing the WLAN driver or when con_mode is modified from userspace
13096 to signal a switch in operating mode
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070013097
13098 \return - 0 for success, non zero for failure
13099
13100 --------------------------------------------------------------------------*/
Jeff Johnson76052702013-04-16 13:55:05 -070013101static int kickstart_driver(void)
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070013102{
Madan Mohan Koyyalamudi62e60052012-10-05 14:27:22 -070013103 int ret_status;
13104
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070013105 if (!wlan_hdd_inited) {
Madan Mohan Koyyalamudi62e60052012-10-05 14:27:22 -070013106 ret_status = hdd_driver_init();
13107 wlan_hdd_inited = ret_status ? 0 : 1;
13108 return ret_status;
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070013109 }
13110
13111 hdd_driver_exit();
Jeff Johnson76052702013-04-16 13:55:05 -070013112
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070013113 msleep(200);
Jeff Johnson76052702013-04-16 13:55:05 -070013114
Madan Mohan Koyyalamudi62e60052012-10-05 14:27:22 -070013115 ret_status = hdd_driver_init();
13116 wlan_hdd_inited = ret_status ? 0 : 1;
13117 return ret_status;
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070013118}
13119
Jeff Johnson295189b2012-06-20 16:38:30 -070013120/**---------------------------------------------------------------------------
13121
Jeff Johnson76052702013-04-16 13:55:05 -070013122 \brief fwpath_changed_handler() - Handler Function
13123
13124 Handle changes to the fwpath parameter
13125
13126 \return - 0 for success, non zero for failure
13127
13128 --------------------------------------------------------------------------*/
13129static int fwpath_changed_handler(const char *kmessage,
13130 struct kernel_param *kp)
13131{
13132 int ret;
13133
13134 ret = param_set_copystring(kmessage, kp);
13135 if (0 == ret)
13136 ret = kickstart_driver();
13137 return ret;
13138}
13139
13140/**---------------------------------------------------------------------------
13141
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070013142 \brief con_mode_handler() -
13143
13144 Handler function for module param con_mode when it is changed by userspace
13145 Dynamically linked - do nothing
13146 Statically linked - exit and init driver, as in rmmod and insmod
13147
Jeff Johnson76052702013-04-16 13:55:05 -070013148 \param -
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070013149
Jeff Johnson76052702013-04-16 13:55:05 -070013150 \return -
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070013151
13152 --------------------------------------------------------------------------*/
Jeff Johnson76052702013-04-16 13:55:05 -070013153static int con_mode_handler(const char *kmessage, struct kernel_param *kp)
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070013154{
Jeff Johnson76052702013-04-16 13:55:05 -070013155 int ret;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070013156
Jeff Johnson76052702013-04-16 13:55:05 -070013157 ret = param_set_int(kmessage, kp);
13158 if (0 == ret)
13159 ret = kickstart_driver();
13160 return ret;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070013161}
13162#endif /* #ifdef MODULE */
13163
13164/**---------------------------------------------------------------------------
13165
Jeff Johnson295189b2012-06-20 16:38:30 -070013166 \brief hdd_get_conparam() -
13167
13168 This is the driver exit point (invoked when module is unloaded using rmmod)
13169
13170 \param - None
13171
13172 \return - tVOS_CON_MODE
13173
13174 --------------------------------------------------------------------------*/
13175tVOS_CON_MODE hdd_get_conparam ( void )
13176{
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070013177#ifdef MODULE
Jeff Johnson295189b2012-06-20 16:38:30 -070013178 return (tVOS_CON_MODE)con_mode;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070013179#else
13180 return (tVOS_CON_MODE)curr_con_mode;
13181#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070013182}
13183void hdd_set_conparam ( v_UINT_t newParam )
13184{
13185 con_mode = newParam;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070013186#ifndef MODULE
13187 curr_con_mode = con_mode;
13188#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070013189}
13190/**---------------------------------------------------------------------------
13191
13192 \brief hdd_softap_sta_deauth() - function
13193
13194 This to take counter measure to handle deauth req from HDD
13195
13196 \param - pAdapter - Pointer to the HDD
13197
13198 \param - enable - boolean value
13199
13200 \return - None
13201
13202 --------------------------------------------------------------------------*/
13203
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013204VOS_STATUS hdd_softap_sta_deauth(hdd_adapter_t *pAdapter,
13205 struct tagCsrDelStaParams *pDelStaParams)
Jeff Johnson295189b2012-06-20 16:38:30 -070013206{
Jeff Johnson295189b2012-06-20 16:38:30 -070013207 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080013208 VOS_STATUS vosStatus = VOS_STATUS_E_FAULT;
Jeff Johnson295189b2012-06-20 16:38:30 -070013209
13210 ENTER();
13211
Rajesh Chauhan18488fc2013-08-22 10:15:03 -070013212 hddLog(LOG1, "hdd_softap_sta_deauth:(%p, false)",
13213 (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -070013214
13215 //Ignore request to deauth bcmc station
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013216 if (pDelStaParams->peerMacAddr[0] & 0x1)
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080013217 return vosStatus;
Jeff Johnson295189b2012-06-20 16:38:30 -070013218
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013219 vosStatus = WLANSAP_DeauthSta(pVosContext, pDelStaParams);
Jeff Johnson295189b2012-06-20 16:38:30 -070013220
13221 EXIT();
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080013222 return vosStatus;
Jeff Johnson295189b2012-06-20 16:38:30 -070013223}
13224
13225/**---------------------------------------------------------------------------
13226
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +053013227 \brief hdd_del_all_sta() - function
13228
13229 This function removes all the stations associated on stopping AP/P2P GO.
13230
13231 \param - pAdapter - Pointer to the HDD
13232
13233 \return - None
13234
13235 --------------------------------------------------------------------------*/
13236
13237int hdd_del_all_sta(hdd_adapter_t *pAdapter)
13238{
13239 v_U16_t i;
13240 VOS_STATUS vos_status;
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053013241 v_CONTEXT_t pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
13242 ptSapContext pSapCtx = NULL;
13243 pSapCtx = VOS_GET_SAP_CB(pVosContext);
13244 if(pSapCtx == NULL){
13245 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13246 FL("psapCtx is NULL"));
13247 return 1;
13248 }
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +053013249 ENTER();
13250
13251 hddLog(VOS_TRACE_LEVEL_INFO,
13252 "%s: Delete all STAs associated.",__func__);
13253 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
13254 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
13255 )
13256 {
13257 for(i = 0; i < WLAN_MAX_STA_COUNT; i++)
13258 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053013259 if ((pSapCtx->aStaInfo[i].isUsed) &&
13260 (!pSapCtx->aStaInfo[i].isDeauthInProgress))
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +053013261 {
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013262 struct tagCsrDelStaParams delStaParams;
13263
13264 WLANSAP_PopulateDelStaParams(
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053013265 pSapCtx->aStaInfo[i].macAddrSTA.bytes,
Sushant Kaushik4cd28f62014-12-26 14:23:50 +053013266 eSIR_MAC_DEAUTH_LEAVING_BSS_REASON,
13267 SIR_MAC_MGMT_DEAUTH >> 4,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013268 &delStaParams);
13269 vos_status = hdd_softap_sta_deauth(pAdapter, &delStaParams);
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +053013270 if (VOS_IS_STATUS_SUCCESS(vos_status))
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053013271 pSapCtx->aStaInfo[i].isDeauthInProgress = TRUE;
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +053013272 }
13273 }
13274 }
13275
13276 EXIT();
13277 return 0;
13278}
13279
13280/**---------------------------------------------------------------------------
13281
Jeff Johnson295189b2012-06-20 16:38:30 -070013282 \brief hdd_softap_sta_disassoc() - function
13283
13284 This to take counter measure to handle deauth req from HDD
13285
13286 \param - pAdapter - Pointer to the HDD
13287
13288 \param - enable - boolean value
13289
13290 \return - None
13291
13292 --------------------------------------------------------------------------*/
13293
13294void hdd_softap_sta_disassoc(hdd_adapter_t *pAdapter,v_U8_t *pDestMacAddress)
13295{
13296 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
13297
13298 ENTER();
13299
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +053013300 hddLog( LOGE, "hdd_softap_sta_disassoc:(%p, false)", (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -070013301
13302 //Ignore request to disassoc bcmc station
13303 if( pDestMacAddress[0] & 0x1 )
13304 return;
13305
13306 WLANSAP_DisassocSta(pVosContext,pDestMacAddress);
13307}
13308
13309void hdd_softap_tkip_mic_fail_counter_measure(hdd_adapter_t *pAdapter,v_BOOL_t enable)
13310{
13311 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
13312
13313 ENTER();
13314
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +053013315 hddLog( LOGE, "hdd_softap_tkip_mic_fail_counter_measure:(%p, false)", (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -070013316
13317 WLANSAP_SetCounterMeasure(pVosContext, (v_BOOL_t)enable);
13318}
13319
Jeff Johnson295189b2012-06-20 16:38:30 -070013320/**---------------------------------------------------------------------------
13321 *
13322 * \brief hdd_get__concurrency_mode() -
13323 *
13324 *
13325 * \param - None
13326 *
13327 * \return - CONCURRENCY MODE
13328 *
13329 * --------------------------------------------------------------------------*/
13330tVOS_CONCURRENCY_MODE hdd_get_concurrency_mode ( void )
13331{
13332 v_CONTEXT_t pVosContext = vos_get_global_context( VOS_MODULE_ID_HDD, NULL );
13333 hdd_context_t *pHddCtx;
13334
13335 if (NULL != pVosContext)
13336 {
13337 pHddCtx = vos_get_context( VOS_MODULE_ID_HDD, pVosContext);
13338 if (NULL != pHddCtx)
13339 {
13340 return (tVOS_CONCURRENCY_MODE)pHddCtx->concurrency_mode;
13341 }
13342 }
13343
13344 /* we are in an invalid state :( */
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070013345 hddLog(LOGE, "%s: Invalid context", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070013346 return VOS_STA;
13347}
Sushant Kaushikabb7ee62014-07-18 16:20:12 +053013348v_BOOL_t
13349wlan_hdd_is_GO_power_collapse_allowed (hdd_context_t* pHddCtx)
13350{
13351 hdd_adapter_t *pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070013352
Sushant Kaushikabb7ee62014-07-18 16:20:12 +053013353 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_GO);
13354 if (pAdapter == NULL)
13355 {
13356 hddLog(VOS_TRACE_LEVEL_INFO,
13357 FL("GO doesn't exist"));
13358 return TRUE;
13359 }
13360 if (test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
13361 {
13362 hddLog(VOS_TRACE_LEVEL_INFO,
13363 FL("GO started"));
13364 return TRUE;
13365 }
13366 else
13367 /* wait till GO changes its interface to p2p device */
13368 hddLog(VOS_TRACE_LEVEL_INFO,
13369 FL("Del_bss called, avoid apps suspend"));
13370 return FALSE;
13371
13372}
Jeff Johnson295189b2012-06-20 16:38:30 -070013373/* Decide whether to allow/not the apps power collapse.
13374 * Allow apps power collapse if we are in connected state.
13375 * if not, allow only if we are in IMPS */
13376v_BOOL_t hdd_is_apps_power_collapse_allowed(hdd_context_t* pHddCtx)
13377{
13378 tPmcState pmcState = pmcGetPmcState(pHddCtx->hHal);
Srikant Kuppafef66a72013-01-30 17:32:44 -080013379 tANI_BOOLEAN scanRspPending = csrNeighborRoamScanRspPending(pHddCtx->hHal);
Srinivas Girigowdaa553c462013-03-07 19:42:52 -080013380 tANI_BOOLEAN inMiddleOfRoaming = csrNeighborMiddleOfRoaming(pHddCtx->hHal);
Jeff Johnson295189b2012-06-20 16:38:30 -070013381 hdd_config_t *pConfig = pHddCtx->cfg_ini;
13382 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
13383 hdd_adapter_t *pAdapter = NULL;
13384 VOS_STATUS status;
Yathish9f22e662012-12-10 14:21:35 -080013385 tVOS_CONCURRENCY_MODE concurrent_state = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070013386
Jeff Johnson295189b2012-06-20 16:38:30 -070013387 if (VOS_STA_SAP_MODE == hdd_get_conparam())
13388 return TRUE;
Jeff Johnson295189b2012-06-20 16:38:30 -070013389
Yathish9f22e662012-12-10 14:21:35 -080013390 concurrent_state = hdd_get_concurrency_mode();
13391
Sushant Kaushikabb7ee62014-07-18 16:20:12 +053013392 if ((concurrent_state == (VOS_STA | VOS_P2P_GO)) &&
13393 !(wlan_hdd_is_GO_power_collapse_allowed(pHddCtx)))
13394 return FALSE;
Yathish9f22e662012-12-10 14:21:35 -080013395#ifdef WLAN_ACTIVEMODE_OFFLOAD_FEATURE
Sushant Kaushikabb7ee62014-07-18 16:20:12 +053013396
Yathish9f22e662012-12-10 14:21:35 -080013397 if(((concurrent_state == (VOS_STA | VOS_P2P_CLIENT)) ||
Sushant Kaushikabb7ee62014-07-18 16:20:12 +053013398 (concurrent_state == (VOS_STA | VOS_P2P_GO)))&&
Yathish9f22e662012-12-10 14:21:35 -080013399 (IS_ACTIVEMODE_OFFLOAD_FEATURE_ENABLE))
13400 return TRUE;
13401#endif
13402
Jeff Johnson295189b2012-06-20 16:38:30 -070013403 /*loop through all adapters. TBD fix for Concurrency */
13404 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
13405 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
13406 {
13407 pAdapter = pAdapterNode->pAdapter;
13408 if ( (WLAN_HDD_INFRA_STATION == pAdapter->device_mode)
13409 || (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
13410 {
Srikant Kuppafef66a72013-01-30 17:32:44 -080013411 if (((pConfig->fIsImpsEnabled || pConfig->fIsBmpsEnabled)
c_hpothu4e8faac2014-05-16 17:38:44 +053013412 && (pmcState != IMPS && pmcState != BMPS && pmcState != UAPSD
c_hpothu1c6957d2015-01-06 18:19:47 +053013413 && pmcState != STOPPED && pmcState != STANDBY &&
13414 pmcState != WOWL)) ||
Srinivas Girigowdaa553c462013-03-07 19:42:52 -080013415 (eANI_BOOLEAN_TRUE == scanRspPending) ||
13416 (eANI_BOOLEAN_TRUE == inMiddleOfRoaming))
Jeff Johnson295189b2012-06-20 16:38:30 -070013417 {
Mukul Sharma4be88422015-03-09 20:29:07 +053013418 if(pmcState == FULL_POWER &&
13419 sme_IsCoexScoIndicationSet(pHddCtx->hHal))
13420 {
13421 /*
13422 * When SCO indication comes from Coex module , host will
13423 * enter in to full power mode, but this should not prevent
13424 * apps processor power collapse.
13425 */
13426 hddLog(LOG1,
13427 FL("Allow apps power collapse"
13428 "even when sco indication is set"));
13429 return TRUE;
13430 }
Srikant Kuppafef66a72013-01-30 17:32:44 -080013431 hddLog( LOGE, "%s: do not allow APPS power collapse-"
Deepthi Gowri03a979f2016-11-03 15:20:19 +053013432 "pmcState = %d scanRspPending = %d "
13433 "inMiddleOfRoaming = %d connected = %d",
13434 __func__, pmcState, scanRspPending,
13435 inMiddleOfRoaming, hdd_connIsConnected(
13436 WLAN_HDD_GET_STATION_CTX_PTR( pAdapter )));
13437 wlan_hdd_get_tdls_stats(pAdapter);
13438 return FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070013439 }
13440 }
13441 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
13442 pAdapterNode = pNext;
13443 }
13444 return TRUE;
13445}
13446
Madan Mohan Koyyalamudic72a4d62012-11-08 14:59:34 -080013447/* Decides whether to send suspend notification to Riva
13448 * if any adapter is in BMPS; then it is required */
13449v_BOOL_t hdd_is_suspend_notify_allowed(hdd_context_t* pHddCtx)
13450{
13451 tPmcState pmcState = pmcGetPmcState(pHddCtx->hHal);
13452 hdd_config_t *pConfig = pHddCtx->cfg_ini;
13453
13454 if (pConfig->fIsBmpsEnabled && (pmcState == BMPS))
13455 {
13456 return TRUE;
13457 }
13458 return FALSE;
13459}
13460
Jeff Johnson295189b2012-06-20 16:38:30 -070013461void wlan_hdd_set_concurrency_mode(hdd_context_t *pHddCtx, tVOS_CON_MODE mode)
13462{
13463 switch(mode)
13464 {
Chilam Ngc4244af2013-04-01 15:37:32 -070013465 case VOS_STA_MODE:
13466 case VOS_P2P_CLIENT_MODE:
13467 case VOS_P2P_GO_MODE:
13468 case VOS_STA_SAP_MODE:
Jeff Johnsone7245742012-09-05 17:12:55 -070013469 pHddCtx->concurrency_mode |= (1 << mode);
Agarwal Ashish51325b52014-06-16 16:50:49 +053013470 pHddCtx->no_of_open_sessions[mode]++;
Jeff Johnson295189b2012-06-20 16:38:30 -070013471 break;
13472 default:
13473 break;
Jeff Johnson295189b2012-06-20 16:38:30 -070013474 }
Agarwal Ashish51325b52014-06-16 16:50:49 +053013475 hddLog(VOS_TRACE_LEVEL_INFO, FL("concurrency_mode = 0x%x "
13476 "Number of open sessions for mode %d = %d"),
13477 pHddCtx->concurrency_mode, mode,
13478 pHddCtx->no_of_open_sessions[mode]);
Jeff Johnson295189b2012-06-20 16:38:30 -070013479}
13480
13481
13482void wlan_hdd_clear_concurrency_mode(hdd_context_t *pHddCtx, tVOS_CON_MODE mode)
13483{
13484 switch(mode)
13485 {
Chilam Ngc4244af2013-04-01 15:37:32 -070013486 case VOS_STA_MODE:
13487 case VOS_P2P_CLIENT_MODE:
13488 case VOS_P2P_GO_MODE:
13489 case VOS_STA_SAP_MODE:
Agarwal Ashish51325b52014-06-16 16:50:49 +053013490 pHddCtx->no_of_open_sessions[mode]--;
13491 if (!(pHddCtx->no_of_open_sessions[mode]))
13492 pHddCtx->concurrency_mode &= (~(1 << mode));
Jeff Johnson295189b2012-06-20 16:38:30 -070013493 break;
13494 default:
13495 break;
13496 }
Agarwal Ashish51325b52014-06-16 16:50:49 +053013497 hddLog(VOS_TRACE_LEVEL_INFO, FL("concurrency_mode = 0x%x "
13498 "Number of open sessions for mode %d = %d"),
13499 pHddCtx->concurrency_mode, mode, pHddCtx->no_of_open_sessions[mode]);
13500
13501}
13502/**---------------------------------------------------------------------------
13503 *
13504 * \brief wlan_hdd_incr_active_session()
13505 *
13506 * This function increments the number of active sessions
13507 * maintained per device mode
13508 * Incase of STA/P2P CLI/IBSS upon connection indication it is incremented
13509 * Incase of SAP/P2P GO upon bss start it is incremented
13510 *
13511 * \param pHddCtx - HDD Context
13512 * \param mode - device mode
13513 *
13514 * \return - None
13515 *
13516 * --------------------------------------------------------------------------*/
13517void wlan_hdd_incr_active_session(hdd_context_t *pHddCtx, tVOS_CON_MODE mode)
13518{
13519 switch (mode) {
13520 case VOS_STA_MODE:
13521 case VOS_P2P_CLIENT_MODE:
13522 case VOS_P2P_GO_MODE:
13523 case VOS_STA_SAP_MODE:
13524 pHddCtx->no_of_active_sessions[mode]++;
13525 break;
13526 default:
13527 hddLog(VOS_TRACE_LEVEL_INFO, FL("Not Expected Mode %d"), mode);
13528 break;
13529 }
13530 hddLog(VOS_TRACE_LEVEL_INFO, FL("No.# of active sessions for mode %d = %d"),
13531 mode,
13532 pHddCtx->no_of_active_sessions[mode]);
13533}
13534
13535/**---------------------------------------------------------------------------
13536 *
13537 * \brief wlan_hdd_decr_active_session()
13538 *
13539 * This function decrements the number of active sessions
13540 * maintained per device mode
13541 * Incase of STA/P2P CLI/IBSS upon disconnection it is decremented
13542 * Incase of SAP/P2P GO upon bss stop it is decremented
13543 *
13544 * \param pHddCtx - HDD Context
13545 * \param mode - device mode
13546 *
13547 * \return - None
13548 *
13549 * --------------------------------------------------------------------------*/
13550void wlan_hdd_decr_active_session(hdd_context_t *pHddCtx, tVOS_CON_MODE mode)
13551{
Bhargav Shahd0715912015-10-01 18:17:37 +053013552
Agarwal Ashish51325b52014-06-16 16:50:49 +053013553 switch (mode) {
13554 case VOS_STA_MODE:
13555 case VOS_P2P_CLIENT_MODE:
13556 case VOS_P2P_GO_MODE:
13557 case VOS_STA_SAP_MODE:
Agarwal Ashish5325f522014-08-06 00:58:44 +053013558 if (pHddCtx->no_of_active_sessions[mode] > 0)
13559 pHddCtx->no_of_active_sessions[mode]--;
13560 else
13561 hddLog(VOS_TRACE_LEVEL_INFO, FL(" No.# of Active sessions"
13562 "is already Zero"));
Agarwal Ashish51325b52014-06-16 16:50:49 +053013563 break;
13564 default:
13565 hddLog(VOS_TRACE_LEVEL_INFO, FL("Not Expected Mode %d"), mode);
13566 break;
13567 }
13568 hddLog(VOS_TRACE_LEVEL_INFO, FL("No.# of active sessions for mode %d = %d"),
13569 mode,
13570 pHddCtx->no_of_active_sessions[mode]);
Jeff Johnson295189b2012-06-20 16:38:30 -070013571}
13572
Jeff Johnsone7245742012-09-05 17:12:55 -070013573/**---------------------------------------------------------------------------
13574 *
13575 * \brief wlan_hdd_restart_init
13576 *
13577 * This function initalizes restart timer/flag. An internal function.
13578 *
13579 * \param - pHddCtx
13580 *
13581 * \return - None
13582 *
13583 * --------------------------------------------------------------------------*/
13584
13585static void wlan_hdd_restart_init(hdd_context_t *pHddCtx)
13586{
13587 /* Initialize */
13588 pHddCtx->hdd_restart_retries = 0;
13589 atomic_set(&pHddCtx->isRestartInProgress, 0);
13590 vos_timer_init(&pHddCtx->hdd_restart_timer,
13591 VOS_TIMER_TYPE_SW,
13592 wlan_hdd_restart_timer_cb,
13593 pHddCtx);
13594}
13595/**---------------------------------------------------------------------------
13596 *
13597 * \brief wlan_hdd_restart_deinit
13598 *
13599 * This function cleans up the resources used. An internal function.
13600 *
13601 * \param - pHddCtx
13602 *
13603 * \return - None
13604 *
13605 * --------------------------------------------------------------------------*/
13606
13607static void wlan_hdd_restart_deinit(hdd_context_t* pHddCtx)
13608{
13609
13610 VOS_STATUS vos_status;
13611 /* Block any further calls */
13612 atomic_set(&pHddCtx->isRestartInProgress, 1);
13613 /* Cleanup */
13614 vos_status = vos_timer_stop( &pHddCtx->hdd_restart_timer );
13615 if (!VOS_IS_STATUS_SUCCESS(vos_status))
c_hpothu6ff1c3c2013-10-01 19:01:57 +053013616 hddLog(LOGE, FL("Failed to stop HDD restart timer"));
Jeff Johnsone7245742012-09-05 17:12:55 -070013617 vos_status = vos_timer_destroy(&pHddCtx->hdd_restart_timer);
13618 if (!VOS_IS_STATUS_SUCCESS(vos_status))
c_hpothu6ff1c3c2013-10-01 19:01:57 +053013619 hddLog(LOGE, FL("Failed to destroy HDD restart timer"));
Jeff Johnsone7245742012-09-05 17:12:55 -070013620
13621}
13622
13623/**---------------------------------------------------------------------------
13624 *
13625 * \brief wlan_hdd_framework_restart
13626 *
13627 * This function uses a cfg80211 API to start a framework initiated WLAN
13628 * driver module unload/load.
13629 *
13630 * Also this API keep retrying (WLAN_HDD_RESTART_RETRY_MAX_CNT).
13631 *
13632 *
13633 * \param - pHddCtx
13634 *
13635 * \return - VOS_STATUS_SUCCESS: Success
13636 * VOS_STATUS_E_EMPTY: Adapter is Empty
13637 * VOS_STATUS_E_NOMEM: No memory
13638
13639 * --------------------------------------------------------------------------*/
13640
13641static VOS_STATUS wlan_hdd_framework_restart(hdd_context_t *pHddCtx)
13642{
13643 VOS_STATUS status = VOS_STATUS_SUCCESS;
13644 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
Madan Mohan Koyyalamudifc19e442013-05-09 18:24:08 -070013645 int len = (sizeof (struct ieee80211_mgmt));
13646 struct ieee80211_mgmt *mgmt = NULL;
13647
13648 /* Prepare the DEAUTH managment frame with reason code */
13649 mgmt = kzalloc(len, GFP_KERNEL);
13650 if(mgmt == NULL)
13651 {
13652 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
13653 "%s: memory allocation failed (%d bytes)", __func__, len);
13654 return VOS_STATUS_E_NOMEM;
13655 }
13656 mgmt->u.deauth.reason_code = WLAN_REASON_DISASSOC_LOW_ACK;
Jeff Johnsone7245742012-09-05 17:12:55 -070013657
13658 /* Iterate over all adapters/devices */
13659 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
Hanumantha Reddy Pothulada0fe362015-02-27 18:37:03 +053013660 if ((NULL == pAdapterNode) || (VOS_STATUS_SUCCESS != status))
13661 {
13662 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13663 FL("fail to get adapter: %p %d"), pAdapterNode, status);
13664 goto end;
13665 }
13666
Jeff Johnsone7245742012-09-05 17:12:55 -070013667 do
13668 {
Hanumantha Reddy Pothulada0fe362015-02-27 18:37:03 +053013669 if(pAdapterNode->pAdapter &&
13670 WLAN_HDD_ADAPTER_MAGIC == pAdapterNode->pAdapter->magic)
Jeff Johnsone7245742012-09-05 17:12:55 -070013671 {
13672 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
13673 "restarting the driver(intf:\'%s\' mode:%d :try %d)",
13674 pAdapterNode->pAdapter->dev->name,
13675 pAdapterNode->pAdapter->device_mode,
13676 pHddCtx->hdd_restart_retries + 1);
Madan Mohan Koyyalamudifc19e442013-05-09 18:24:08 -070013677 /*
13678 * CFG80211 event to restart the driver
13679 *
13680 * 'cfg80211_send_unprot_deauth' sends a
13681 * NL80211_CMD_UNPROT_DEAUTHENTICATE event to supplicant at any state
13682 * of SME(Linux Kernel) state machine.
13683 *
13684 * Reason code WLAN_REASON_DISASSOC_LOW_ACK is currently used to restart
13685 * the driver.
13686 *
13687 */
Abhishek Singh00b71972016-01-07 10:51:04 +053013688
Anand N Sunkade9adb1b2015-07-29 09:56:45 +053013689#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 11, 0))
13690 cfg80211_rx_unprot_mlme_mgmt(pAdapterNode->pAdapter->dev, (u_int8_t*)mgmt, len);
13691#else
Madan Mohan Koyyalamudifc19e442013-05-09 18:24:08 -070013692 cfg80211_send_unprot_deauth(pAdapterNode->pAdapter->dev, (u_int8_t*)mgmt, len );
Anand N Sunkade9adb1b2015-07-29 09:56:45 +053013693#endif
Jeff Johnsone7245742012-09-05 17:12:55 -070013694 }
13695 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
13696 pAdapterNode = pNext;
13697 } while((NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status));
13698
Hanumantha Reddy Pothulada0fe362015-02-27 18:37:03 +053013699 end:
Madan Mohan Koyyalamudifc19e442013-05-09 18:24:08 -070013700 /* Free the allocated management frame */
13701 kfree(mgmt);
13702
Jeff Johnsone7245742012-09-05 17:12:55 -070013703 /* Retry until we unload or reach max count */
13704 if(++pHddCtx->hdd_restart_retries < WLAN_HDD_RESTART_RETRY_MAX_CNT)
13705 vos_timer_start(&pHddCtx->hdd_restart_timer, WLAN_HDD_RESTART_RETRY_DELAY_MS);
13706
13707 return status;
13708
13709}
13710/**---------------------------------------------------------------------------
13711 *
13712 * \brief wlan_hdd_restart_timer_cb
13713 *
13714 * Restart timer callback. An internal function.
13715 *
13716 * \param - User data:
13717 *
13718 * \return - None
13719 *
13720 * --------------------------------------------------------------------------*/
13721
13722void wlan_hdd_restart_timer_cb(v_PVOID_t usrDataForCallback)
13723{
13724 hdd_context_t *pHddCtx = usrDataForCallback;
13725 wlan_hdd_framework_restart(pHddCtx);
13726 return;
13727
13728}
13729
13730
13731/**---------------------------------------------------------------------------
13732 *
13733 * \brief wlan_hdd_restart_driver
13734 *
13735 * This function sends an event to supplicant to restart the WLAN driver.
13736 *
13737 * This function is called from vos_wlanRestart.
13738 *
13739 * \param - pHddCtx
13740 *
13741 * \return - VOS_STATUS_SUCCESS: Success
13742 * VOS_STATUS_E_EMPTY: Adapter is Empty
13743 * VOS_STATUS_E_ALREADY: Request already in progress
13744
13745 * --------------------------------------------------------------------------*/
13746VOS_STATUS wlan_hdd_restart_driver(hdd_context_t *pHddCtx)
13747{
13748 VOS_STATUS status = VOS_STATUS_SUCCESS;
13749
13750 /* A tight check to make sure reentrancy */
13751 if(atomic_xchg(&pHddCtx->isRestartInProgress, 1))
13752 {
Mihir Shetefd528652014-06-23 19:07:50 +053013753 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnsone7245742012-09-05 17:12:55 -070013754 "%s: WLAN restart is already in progress", __func__);
13755
13756 return VOS_STATUS_E_ALREADY;
13757 }
Sameer Thalappil0c164f52013-03-28 15:27:56 -070013758 /* Send reset FIQ to WCNSS to invoke SSR. */
Madan Mohan Koyyalamudie388b342012-11-08 15:03:16 -080013759#ifdef HAVE_WCNSS_RESET_INTR
Siddharth Bhal864e7e82015-04-07 20:07:24 +053013760 wcnss_reset_fiq(TRUE);
Madan Mohan Koyyalamudibb8f0172012-09-28 15:36:06 -070013761#endif
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -070013762
Jeff Johnsone7245742012-09-05 17:12:55 -070013763 return status;
13764}
13765
Bhargav Shahd0715912015-10-01 18:17:37 +053013766/**
13767 * hdd_get_total_sessions() - provide total number of active sessions
13768 * @pHddCtx: Valid Global HDD context pointer
13769 *
13770 * This function iterates through pAdaptors and find the number of all active
13771 * sessions. This active sessions includes connected sta, p2p client and number
13772 * of client connected to sap/p2p go.
13773 *
13774 * Return: Total number of active sessions.
13775 */
13776v_U8_t hdd_get_total_sessions(hdd_context_t *pHddCtx)
13777{
13778 v_U8_t active_session = 0;
13779 hdd_station_ctx_t *pHddStaCtx;
13780 hdd_adapter_list_node_t *pAdapterNode, *pNext;
13781 hdd_adapter_t *pAdapter;
13782 VOS_STATUS status;
13783
13784 status = hdd_get_front_adapter(pHddCtx, &pAdapterNode);
13785 while (NULL != pAdapterNode && VOS_STATUS_SUCCESS == status) {
13786 pAdapter = pAdapterNode->pAdapter;
13787 switch (pAdapter->device_mode) {
13788 case VOS_STA_MODE:
13789 case VOS_P2P_CLIENT_MODE:
13790 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
13791 if(eConnectionState_Associated == pHddStaCtx->conn_info.connState)
13792 active_session += 1;
13793 break;
13794 case VOS_STA_SAP_MODE:
13795 case VOS_P2P_GO_MODE:
13796 active_session += hdd_softap_get_connected_sta(pAdapter);
13797 break;
13798 default:
13799 break;
13800 }
13801
13802 status = hdd_get_next_adapter(pHddCtx, pAdapterNode, &pNext);
13803 pAdapterNode = pNext;
13804 }
13805
13806 return active_session;
13807}
13808
13809/**
13810 * hdd_set_delack_value() - Set delack value
13811 * @pHddCtx: Valid Global HDD context pointer
13812 * @next_rx_level: Value to set for delack
13813 *
13814 * This function compare present value and next value of delack. If the both
13815 * are diffrent then it sets next value .
13816 *
13817 * Return: void.
13818 */
13819void hdd_set_delack_value(hdd_context_t *pHddCtx, v_U32_t next_rx_level)
13820{
13821 if (pHddCtx->cur_rx_level != next_rx_level) {
13822 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_DEBUG,
13823 "%s: TCP DELACK trigger level %d",
13824 __func__, next_rx_level);
13825 mutex_lock(&pHddCtx->cur_rx_level_lock);
13826 pHddCtx->cur_rx_level = next_rx_level;
13827 mutex_unlock(&pHddCtx->cur_rx_level_lock);
13828 wlan_hdd_send_svc_nlink_msg(WLAN_SVC_WLAN_TP_IND, &next_rx_level,
13829 sizeof(next_rx_level));
13830 }
13831}
13832
13833/**
13834 * hdd_set_default_stop_delack_timer() - Start delack timer
13835 * @pHddCtx: Valid Global HDD context pointer
13836 *
13837 * This function stop delack timer and set delack value to default..
13838 *
13839 * Return: void.
13840 */
13841
13842void hdd_set_default_stop_delack_timer(hdd_context_t *pHddCtx)
13843{
13844 if (VOS_TIMER_STATE_RUNNING !=
13845 vos_timer_getCurrentState(&pHddCtx->delack_timer)) {
13846 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_DEBUG,
13847 "%s: Can not stop timer", __func__);
13848 return;
13849 }
13850
13851 vos_timer_stop(&pHddCtx->delack_timer);
13852 hdd_set_delack_value(pHddCtx, TP_IND_LOW);
13853}
13854
13855/**
13856 * hdd_start_delack_timer() - Start delack timer
13857 * @pHddCtx: Valid Global HDD context pointer
13858 *
13859 * This function starts the delack timer for tcpDelAckComputeInterval time
13860 * interval.The default timer value is 2 second.
13861 *
13862 * Return: void.
13863 */
13864void hdd_start_delack_timer(hdd_context_t *pHddCtx)
13865{
13866 if (VOS_TIMER_STATE_RUNNING ==
13867 vos_timer_getCurrentState(&pHddCtx->delack_timer)) {
13868 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_DEBUG,
13869 "%s: Timer is already running", __func__);
13870 return;
13871 }
13872
13873 vos_timer_start(&pHddCtx->delack_timer,
13874 pHddCtx->cfg_ini->tcpDelAckComputeInterval);
13875}
13876
13877/**
13878 * hdd_update_prev_rx_packet_count() - Update previous rx packet count
13879 * @pHddCtx: Valid Global HDD context pointer
13880 *
13881 * This function updates the prev_rx_packets count from the corresponding
13882 * pAdapter states. This prev_rx_packets will diffed with the packet count
13883 * at the end of delack timer. That can give number of RX packet is spacific
13884 * time.
13885 *
13886 * Return: void.
13887 */
13888void hdd_update_prev_rx_packet_count(hdd_context_t *pHddCtx)
13889{
13890 hdd_adapter_list_node_t *pAdapterNode, *pNext;
13891 hdd_adapter_t *pAdapter;
13892 VOS_STATUS status;
13893
13894 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
13895 while (NULL != pAdapterNode && VOS_STATUS_SUCCESS == status) {
13896 pAdapter = pAdapterNode->pAdapter;
13897 pAdapter->prev_rx_packets = pAdapter->stats.rx_packets;
13898 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
13899 pAdapterNode = pNext;
13900 }
13901}
13902
13903/**
13904 * hdd_manage_delack_timer() - start\stop delack timer
13905 * @pHddCtx: Valid Global HDD context pointer
13906 *
13907 * This function check the number of concerent session present, it starts the
13908 * delack timer if only one session is present.
13909 * In the case of BT_COEX and TDLS mode it blindly stop delack functionality.
13910 *
13911 * Return: void.
13912 */
13913void hdd_manage_delack_timer(hdd_context_t *pHddCtx)
13914{
13915 uint8_t sessions;
13916
13917 if (!pHddCtx->cfg_ini->enable_delack) {
13918 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_DEBUG,
13919 "%s: TCP DELACK is not enabled", __func__);
13920 return;
13921 }
13922
13923 /* Blindly stop timer of BTCOEX and TDLS Session is up */
13924 if (pHddCtx->mode != 0) {
13925 hdd_set_default_stop_delack_timer(pHddCtx);
13926 return;
13927 }
13928
13929 sessions = hdd_get_total_sessions(pHddCtx);
13930 if (sessions == 1) {
13931 hdd_update_prev_rx_packet_count(pHddCtx);
13932 hdd_start_delack_timer(pHddCtx);
13933 } else {
13934 hdd_set_default_stop_delack_timer(pHddCtx);
13935 }
13936}
13937
Mihir Shetee1093ba2014-01-21 20:13:32 +053013938/**---------------------------------------------------------------------------
13939 *
13940 * \brief wlan_hdd_init_channels
13941 *
13942 * This function is used to initialize the channel list in CSR
13943 *
13944 * This function is called from hdd_wlan_startup
13945 *
13946 * \param - pHddCtx: HDD context
13947 *
13948 * \return - VOS_STATUS_SUCCESS: Success
13949 * VOS_STATUS_E_FAULT: Failure reported by SME
13950
13951 * --------------------------------------------------------------------------*/
13952static VOS_STATUS wlan_hdd_init_channels(hdd_context_t *pHddCtx)
13953{
13954 eHalStatus status;
13955
13956 status = sme_InitChannels(pHddCtx->hHal);
13957 if (HAL_STATUS_SUCCESS(status))
13958 {
13959 return VOS_STATUS_SUCCESS;
13960 }
13961 else
13962 {
13963 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Channel initialization failed(%d)",
13964 __func__, status);
13965 return VOS_STATUS_E_FAULT;
13966 }
13967}
13968
Mihir Shete04206452014-11-20 17:50:58 +053013969#ifdef CONFIG_ENABLE_LINUX_REG
Agarwal Ashish6db9d532014-09-30 18:19:10 +053013970VOS_STATUS wlan_hdd_init_channels_for_cc(hdd_context_t *pHddCtx, driver_load_type init )
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053013971{
13972 eHalStatus status;
13973
Agarwal Ashish6db9d532014-09-30 18:19:10 +053013974 status = sme_InitChannelsForCC(pHddCtx->hHal, init);
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053013975 if (HAL_STATUS_SUCCESS(status))
13976 {
13977 return VOS_STATUS_SUCCESS;
13978 }
13979 else
13980 {
13981 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Issue reg hint failed(%d)",
13982 __func__, status);
13983 return VOS_STATUS_E_FAULT;
13984 }
13985}
Mihir Shete04206452014-11-20 17:50:58 +053013986#endif
Sudhir Sattayappa Kohallib1d8c3a2013-06-18 14:47:20 -070013987/*
13988 * API to find if there is any STA or P2P-Client is connected
13989 */
13990VOS_STATUS hdd_issta_p2p_clientconnected(hdd_context_t *pHddCtx)
13991{
13992 return sme_isSta_p2p_clientConnected(pHddCtx->hHal);
13993}
Jeff Johnsone7245742012-09-05 17:12:55 -070013994
Mihir Shetee2ae82a2015-03-16 14:08:49 +053013995
13996/*
13997 * API to find if the firmware will send logs using DXE channel
13998 */
13999v_U8_t hdd_is_fw_logging_enabled(void)
14000{
14001 hdd_context_t *pHddCtx;
14002
14003 pHddCtx = vos_get_context(VOS_MODULE_ID_HDD,
14004 vos_get_global_context(VOS_MODULE_ID_HDD, NULL));
14005
Sachin Ahuja084313e2015-05-21 17:57:10 +053014006 return (pHddCtx && pHddCtx->cfg_ini->enableMgmtLogging);
Mihir Shetee2ae82a2015-03-16 14:08:49 +053014007}
14008
Agarwal Ashish57e84372014-12-05 18:26:53 +053014009/*
Mihir Shetebe94ebb2015-05-26 12:07:14 +053014010 * API to find if the firmware will send trace logs using DXE channel
14011 */
14012v_U8_t hdd_is_fw_ev_logging_enabled(void)
14013{
14014 hdd_context_t *pHddCtx;
14015
14016 pHddCtx = vos_get_context(VOS_MODULE_ID_HDD,
14017 vos_get_global_context(VOS_MODULE_ID_HDD, NULL));
14018
14019 return (pHddCtx && pHddCtx->cfg_ini->enableFWLogging);
14020}
14021/*
Agarwal Ashish57e84372014-12-05 18:26:53 +053014022 * API to find if there is any session connected
14023 */
14024VOS_STATUS hdd_is_any_session_connected(hdd_context_t *pHddCtx)
14025{
14026 return sme_is_any_session_connected(pHddCtx->hHal);
14027}
14028
14029
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053014030int wlan_hdd_scan_abort(hdd_adapter_t *pAdapter)
14031{
14032 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
14033 hdd_scaninfo_t *pScanInfo = NULL;
Girish Gowli4bf7a632014-06-12 13:42:11 +053014034 long status = 0;
c_hpothua3d45d52015-01-05 14:11:17 +053014035 tSirAbortScanStatus abortScanStatus;
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053014036
14037 pScanInfo = &pHddCtx->scan_info;
Ratnam Rachuric7681132015-06-30 10:35:13 +053014038 INIT_COMPLETION(pScanInfo->abortscan_event_var);
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053014039 if (pScanInfo->mScanPending)
14040 {
c_hpothua3d45d52015-01-05 14:11:17 +053014041 abortScanStatus = hdd_abort_mac_scan(pHddCtx, pScanInfo->sessionId,
14042 eCSR_SCAN_ABORT_DEFAULT);
14043 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14044 FL("abortScanStatus: %d"), abortScanStatus);
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053014045
c_hpothua3d45d52015-01-05 14:11:17 +053014046 /* If there is active scan command lets wait for the completion else
14047 * there is no need to wait as scan command might be in the SME pending
14048 * command list.
14049 */
14050 if (abortScanStatus == eSIR_ABORT_ACTIVE_SCAN_LIST_NOT_EMPTY)
14051 {
c_hpothua3d45d52015-01-05 14:11:17 +053014052 status = wait_for_completion_interruptible_timeout(
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053014053 &pScanInfo->abortscan_event_var,
14054 msecs_to_jiffies(5000));
c_hpothua3d45d52015-01-05 14:11:17 +053014055 if (0 >= status)
14056 {
14057 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Girish Gowli4bf7a632014-06-12 13:42:11 +053014058 "%s: Timeout or Interrupt occurred while waiting for abort"
14059 "scan, status- %ld", __func__, status);
c_hpothua3d45d52015-01-05 14:11:17 +053014060 return -ETIMEDOUT;
14061 }
14062 }
14063 else if (abortScanStatus == eSIR_ABORT_SCAN_FAILURE)
14064 {
14065 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14066 FL("hdd_abort_mac_scan failed"));
14067 return -VOS_STATUS_E_FAILURE;
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053014068 }
14069 }
Girish Gowli4bf7a632014-06-12 13:42:11 +053014070 return 0;
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053014071}
14072
Abhishek Singh7d624e12015-11-30 14:29:27 +053014073/**
14074 * hdd_indicate_mgmt_frame() - Wrapper to indicate management frame to
14075 * user space
14076 * @frame_ind: Management frame data to be informed.
14077 *
14078 * This function is used to indicate management frame to
14079 * user space
14080 *
14081 * Return: None
14082 *
14083 */
14084void hdd_indicate_mgmt_frame(tSirSmeMgmtFrameInd *frame_ind)
14085{
14086 hdd_context_t *hdd_ctx = NULL;
14087 hdd_adapter_t *adapter = NULL;
14088 v_CONTEXT_t vos_context = NULL;
14089
14090 /* Get the global VOSS context.*/
14091 vos_context = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
14092 if (!vos_context) {
14093 hddLog(LOGE, FL("Global VOS context is Null"));
14094 return;
14095 }
14096 /* Get the HDD context.*/
14097 hdd_ctx =
14098 (hdd_context_t *)vos_get_context(VOS_MODULE_ID_HDD, vos_context );
14099
14100 if (0 != wlan_hdd_validate_context(hdd_ctx))
14101 {
14102 return;
14103 }
14104 adapter = hdd_get_adapter_by_sme_session_id(hdd_ctx,
14105 frame_ind->sessionId);
14106
14107 if ((NULL != adapter) &&
14108 (WLAN_HDD_ADAPTER_MAGIC == adapter->magic))
14109 __hdd_indicate_mgmt_frame(adapter,
14110 frame_ind->frameLen,
14111 frame_ind->frameBuf,
14112 frame_ind->frameType,
14113 frame_ind->rxChan,
14114 frame_ind->rxRssi);
14115 return;
14116
14117}
14118
c_hpothu225aa7c2014-10-22 17:45:13 +053014119VOS_STATUS wlan_hdd_cancel_remain_on_channel(hdd_context_t *pHddCtx)
14120{
14121 hdd_adapter_t *pAdapter;
14122 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
14123 VOS_STATUS vosStatus;
14124
14125 vosStatus = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
14126 while (NULL != pAdapterNode && VOS_STATUS_E_EMPTY != vosStatus)
14127 {
14128 pAdapter = pAdapterNode->pAdapter;
14129 if (NULL != pAdapter)
14130 {
14131 if (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode ||
14132 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode ||
14133 WLAN_HDD_P2P_GO == pAdapter->device_mode)
14134 {
14135 hddLog(LOG1, FL("abort ROC deviceMode: %d"),
14136 pAdapter->device_mode);
14137 if (VOS_STATUS_SUCCESS !=
14138 wlan_hdd_cancel_existing_remain_on_channel(pAdapter))
14139 {
14140 hddLog(LOGE, FL("failed to abort ROC"));
14141 return VOS_STATUS_E_FAILURE;
14142 }
14143 }
14144 }
14145 vosStatus = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
14146 pAdapterNode = pNext;
14147 }
14148 return VOS_STATUS_SUCCESS;
14149}
Mahesh A Saptasagard477b092015-02-06 15:12:16 +053014150
Mihir Shete0be28772015-02-17 18:42:14 +053014151hdd_remain_on_chan_ctx_t *hdd_get_remain_on_channel_ctx(hdd_context_t *pHddCtx)
14152{
14153 hdd_adapter_t *pAdapter;
14154 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
14155 hdd_cfg80211_state_t *cfgState;
14156 hdd_remain_on_chan_ctx_t *pRemainChanCtx = NULL;
14157 VOS_STATUS vosStatus;
14158
14159 vosStatus = hdd_get_front_adapter (pHddCtx, &pAdapterNode);
14160 while (NULL != pAdapterNode && VOS_STATUS_E_EMPTY != vosStatus)
14161 {
14162 pAdapter = pAdapterNode->pAdapter;
14163 if (NULL != pAdapter)
14164 {
14165 cfgState = WLAN_HDD_GET_CFG_STATE_PTR(pAdapter);
14166 pRemainChanCtx = cfgState->remain_on_chan_ctx;
14167 if (pRemainChanCtx)
14168 break;
14169 }
14170 vosStatus = hdd_get_next_adapter (pHddCtx, pAdapterNode, &pNext);
14171 pAdapterNode = pNext;
14172 }
14173 return pRemainChanCtx;
14174}
14175
Padma, Santhosh Kumar778d8382015-03-04 17:41:22 +053014176/**
14177 * wlan_hdd_handle_dfs_chan_scan () - handles disable/enable DFS channels
14178 *
14179 * @pHddCtx: HDD context within host driver
14180 * @dfsScanMode: dfsScanMode passed from ioctl
14181 *
14182 */
14183
14184VOS_STATUS wlan_hdd_handle_dfs_chan_scan(hdd_context_t *pHddCtx,
14185 tANI_U8 dfsScanMode)
14186{
14187 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
14188 hdd_adapter_t *pAdapter;
14189 VOS_STATUS vosStatus;
14190 hdd_station_ctx_t *pHddStaCtx;
14191 eHalStatus status = eHAL_STATUS_SUCCESS;
14192
14193 if(!pHddCtx)
14194 {
14195 hddLog(LOGE, FL("HDD context is Null"));
14196 return eHAL_STATUS_FAILURE;
14197 }
14198
14199 if (pHddCtx->scan_info.mScanPending)
14200 {
14201 hddLog(LOG1, FL("Aborting scan for sessionId: %d"),
14202 pHddCtx->scan_info.sessionId);
14203 hdd_abort_mac_scan(pHddCtx,
14204 pHddCtx->scan_info.sessionId,
14205 eCSR_SCAN_ABORT_DEFAULT);
14206 }
14207
14208 if (!dfsScanMode)
14209 {
14210 vosStatus = hdd_get_front_adapter( pHddCtx, &pAdapterNode);
14211 while ((NULL != pAdapterNode) &&
14212 (VOS_STATUS_SUCCESS == vosStatus))
14213 {
14214 pAdapter = pAdapterNode->pAdapter;
14215
14216 if (WLAN_HDD_INFRA_STATION == pAdapter->device_mode)
14217 {
14218 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
14219
14220 if(!pHddStaCtx)
14221 {
14222 hddLog(LOGE, FL("HDD STA context is Null"));
14223 return eHAL_STATUS_FAILURE;
14224 }
14225
14226 /* if STA is already connected on DFS channel,
14227 disconnect immediately*/
14228 if (hdd_connIsConnected(pHddStaCtx) &&
14229 (NV_CHANNEL_DFS ==
14230 vos_nv_getChannelEnabledState(
14231 pHddStaCtx->conn_info.operationChannel)))
14232 {
14233 status = sme_RoamDisconnect(pHddCtx->hHal,
14234 pAdapter->sessionId,
14235 eCSR_DISCONNECT_REASON_UNSPECIFIED);
14236 hddLog(LOG1, FL("Client connected on DFS channel %d,"
14237 "sme_RoamDisconnect returned with status: %d"
14238 "for sessionid: %d"), pHddStaCtx->conn_info.
14239 operationChannel, status, pAdapter->sessionId);
14240 }
14241 }
14242
14243 vosStatus = hdd_get_next_adapter(pHddCtx, pAdapterNode,
14244 &pNext);
14245 pAdapterNode = pNext;
14246 }
14247 }
14248
14249 sme_UpdateDFSScanMode(pHddCtx->hHal, dfsScanMode);
14250 sme_UpdateDFSRoamMode(pHddCtx->hHal,
14251 (dfsScanMode != DFS_CHNL_SCAN_DISABLED));
14252
14253 status = sme_HandleDFSChanScan(pHddCtx->hHal);
14254 if (!HAL_STATUS_SUCCESS(status))
14255 {
14256 hddLog(LOGE,
14257 FL("Failed in sme_HandleDFSChanScan (err=%d)"), status);
14258 return status;
14259 }
14260
14261 return status;
14262}
14263
Nirav Shah7e3c8132015-06-22 23:51:42 +053014264static int hdd_log2_ceil(unsigned value)
14265{
14266 /* need to switch to unsigned math so that negative values
14267 * will right-shift towards 0 instead of -1
14268 */
14269 unsigned tmp = value;
14270 int log2 = -1;
14271
14272 if (value == 0)
14273 return 0;
14274
14275 while (tmp) {
14276 log2++;
14277 tmp >>= 1;
14278 }
14279 if (1U << log2 != value)
14280 log2++;
14281
14282 return log2;
14283}
14284
14285/**
14286 * hdd_sta_id_hash_attach() - initialize sta id to macaddr hash
14287 * @pAdapter: adapter handle
14288 *
14289 * Return: vos status
14290 */
14291VOS_STATUS hdd_sta_id_hash_attach(hdd_adapter_t *pAdapter)
14292{
14293 int hash_elem, log2, i;
14294
14295 spin_lock_bh( &pAdapter->sta_hash_lock);
14296 if (pAdapter->is_sta_id_hash_initialized == VOS_TRUE) {
14297 spin_unlock_bh( &pAdapter->sta_hash_lock);
14298 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14299 "%s: hash already attached for session id %d",
14300 __func__, pAdapter->sessionId);
14301 return VOS_STATUS_SUCCESS;
14302 }
14303 spin_unlock_bh( &pAdapter->sta_hash_lock);
14304
14305 hash_elem = WLAN_MAX_STA_COUNT;
14306 hash_elem *= HDD_STA_ID_HASH_MULTIPLIER;
14307 log2 = hdd_log2_ceil(hash_elem);
14308 hash_elem = 1 << log2;
14309
14310 pAdapter->sta_id_hash.mask = hash_elem - 1;
14311 pAdapter->sta_id_hash.idx_bits = log2;
14312 pAdapter->sta_id_hash.bins =
14313 vos_mem_malloc(hash_elem *sizeof(hdd_list_t));
14314 if (!pAdapter->sta_id_hash.bins) {
14315 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14316 "%s: malloc failed for session %d",
14317 __func__, pAdapter->sessionId);
14318 return VOS_STATUS_E_NOMEM;
14319 }
14320
14321 for (i = 0; i < hash_elem; i++)
14322 hdd_list_init(&pAdapter->sta_id_hash.bins[i], WLAN_MAX_STA_COUNT);
14323
14324 spin_lock_bh( &pAdapter->sta_hash_lock);
14325 pAdapter->is_sta_id_hash_initialized = VOS_TRUE;
14326 spin_unlock_bh( &pAdapter->sta_hash_lock);
14327 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14328 "%s: Station ID Hash attached for session id %d",
14329 __func__, pAdapter->sessionId);
14330
14331 return VOS_STATUS_SUCCESS;
14332}
14333
14334/**
14335 * hdd_sta_id_hash_detach() - deinit sta_id to macaddr hash
14336 * @pAdapter: adapter handle
14337 *
14338 * Return: vos status
14339 */
14340VOS_STATUS hdd_sta_id_hash_detach(hdd_adapter_t *pAdapter)
14341{
14342 int hash_elem, i;
14343 v_SIZE_t size;
14344
14345 spin_lock_bh( &pAdapter->sta_hash_lock);
14346 if (pAdapter->is_sta_id_hash_initialized != VOS_TRUE) {
14347 spin_unlock_bh( &pAdapter->sta_hash_lock);
14348 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14349 "%s: hash not initialized for session id %d",
14350 __func__, pAdapter->sessionId);
14351 return VOS_STATUS_SUCCESS;
14352 }
14353
14354 pAdapter->is_sta_id_hash_initialized = VOS_FALSE;
14355 spin_unlock_bh( &pAdapter->sta_hash_lock);
14356
14357 hash_elem = 1 << pAdapter->sta_id_hash.idx_bits;
14358
14359 /* free all station info*/
14360 for (i = 0; i < hash_elem; i++) {
14361 hdd_list_size(&pAdapter->sta_id_hash.bins[i], &size);
14362 if (size != 0) {
14363 VOS_STATUS status;
14364 hdd_staid_hash_node_t *sta_info_node = NULL;
14365 hdd_staid_hash_node_t *next_node = NULL;
14366 status = hdd_list_peek_front ( &pAdapter->sta_id_hash.bins[i],
14367 (hdd_list_node_t**) &sta_info_node );
14368
14369 while ( NULL != sta_info_node && VOS_STATUS_SUCCESS == status )
14370 {
14371 status = hdd_list_remove_node( &pAdapter->sta_id_hash.bins[i],
14372 &sta_info_node->node);
14373 vos_mem_free(sta_info_node);
14374
14375 status = hdd_list_peek_next (&pAdapter->sta_id_hash.bins[i],
14376 (hdd_list_node_t*)sta_info_node,
14377 (hdd_list_node_t**)&next_node);
14378 sta_info_node = next_node;
14379 }
14380 }
14381 }
14382
14383 vos_mem_free(pAdapter->sta_id_hash.bins);
14384 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14385 "%s: Station ID Hash detached for session id %d",
14386 __func__, pAdapter->sessionId);
14387 return VOS_STATUS_SUCCESS;
14388}
14389
14390/**
14391 * hdd_sta_id_hash_calculate_index() - derive index from macaddr
14392 * @pAdapter: adapter handle
14393 * @mac_addr_in: input mac address
14394 *
14395 * Return: index derived from mac address
14396 */
14397int hdd_sta_id_hash_calculate_index(hdd_adapter_t *pAdapter,
14398 v_MACADDR_t *mac_addr_in)
14399{
14400 uint16 index;
14401 struct hdd_align_mac_addr_t * mac_addr =
14402 (struct hdd_align_mac_addr_t *)mac_addr_in;
14403
14404 index = mac_addr->bytes_ab ^
14405 mac_addr->bytes_cd ^ mac_addr->bytes_ef;
14406 index ^= index >> pAdapter->sta_id_hash.idx_bits;
14407 index &= pAdapter->sta_id_hash.mask;
14408 return index;
14409}
14410
14411/**
14412 * hdd_sta_id_hash_add_entry() - add entry in hash
14413 * @pAdapter: adapter handle
14414 * @sta_id: station id
14415 * @mac_addr: mac address
14416 *
14417 * Return: vos status
14418 */
14419VOS_STATUS hdd_sta_id_hash_add_entry(hdd_adapter_t *pAdapter,
14420 v_U8_t sta_id, v_MACADDR_t *mac_addr)
14421{
14422 uint16 index;
14423 hdd_staid_hash_node_t *sta_info_node = NULL;
14424
Nirav Shah7e3c8132015-06-22 23:51:42 +053014425 index = hdd_sta_id_hash_calculate_index(pAdapter, mac_addr);
14426 sta_info_node = vos_mem_malloc(sizeof(hdd_staid_hash_node_t));
14427 if (!sta_info_node) {
Nirav Shah7e3c8132015-06-22 23:51:42 +053014428 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14429 "%s: malloc failed", __func__);
14430 return VOS_STATUS_E_NOMEM;
14431 }
14432
14433 sta_info_node->sta_id = sta_id;
14434 vos_mem_copy(&sta_info_node->mac_addr, mac_addr, sizeof(v_MACADDR_t));
14435
Nirav Shah303ed5c2015-08-24 10:29:25 +053014436 spin_lock_bh( &pAdapter->sta_hash_lock);
14437 if (pAdapter->is_sta_id_hash_initialized != VOS_TRUE) {
14438 spin_unlock_bh( &pAdapter->sta_hash_lock);
14439 vos_mem_free(sta_info_node);
14440 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14441 "%s: hash is not initialized for session id %d",
14442 __func__, pAdapter->sessionId);
14443 return VOS_STATUS_E_FAILURE;
14444 }
14445
Nirav Shah7e3c8132015-06-22 23:51:42 +053014446 hdd_list_insert_back ( &pAdapter->sta_id_hash.bins[index],
14447 (hdd_list_node_t*) sta_info_node );
14448 spin_unlock_bh( &pAdapter->sta_hash_lock);
14449 return VOS_STATUS_SUCCESS;
14450}
14451
14452/**
14453 * hdd_sta_id_hash_remove_entry() - remove entry from hash
14454 * @pAdapter: adapter handle
14455 * @sta_id: station id
14456 * @mac_addr: mac address
14457 *
14458 * Return: vos status
14459 */
14460VOS_STATUS hdd_sta_id_hash_remove_entry(hdd_adapter_t *pAdapter,
14461 v_U8_t sta_id, v_MACADDR_t *mac_addr)
14462{
14463 uint16 index;
14464 VOS_STATUS status;
14465 hdd_staid_hash_node_t *sta_info_node = NULL;
14466 hdd_staid_hash_node_t *next_node = NULL;
14467
14468 spin_lock_bh( &pAdapter->sta_hash_lock);
14469 if (pAdapter->is_sta_id_hash_initialized != VOS_TRUE) {
14470 spin_unlock_bh( &pAdapter->sta_hash_lock);
14471 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14472 "%s: hash is not initialized for session id %d",
14473 __func__, pAdapter->sessionId);
14474 return VOS_STATUS_E_FAILURE;
14475 }
14476
14477 index = hdd_sta_id_hash_calculate_index(pAdapter, mac_addr);
14478 status = hdd_list_peek_front ( &pAdapter->sta_id_hash.bins[index],
14479 (hdd_list_node_t**) &sta_info_node );
14480
14481 while ( NULL != sta_info_node && VOS_STATUS_SUCCESS == status )
14482 {
14483 if (sta_info_node->sta_id == sta_id) {
14484 status = hdd_list_remove_node( &pAdapter->sta_id_hash.bins[index],
14485 &sta_info_node->node);
14486 vos_mem_free(sta_info_node);
14487 break;
14488 }
14489 status = hdd_list_peek_next (&pAdapter->sta_id_hash.bins[index],
14490 (hdd_list_node_t*)sta_info_node, (hdd_list_node_t**)&next_node);
14491 sta_info_node = next_node;
14492 }
14493 spin_unlock_bh( &pAdapter->sta_hash_lock);
14494 return status;
14495}
14496
14497/**
14498 * hdd_sta_id_find_from_mac_addr() - find sta id from mac address
14499 * @pAdapter: adapter handle
14500 * @mac_addr_in: mac address
14501 *
14502 * Return: station id
14503 */
14504int hdd_sta_id_find_from_mac_addr(hdd_adapter_t *pAdapter,
14505 v_MACADDR_t *mac_addr_in)
14506{
14507 uint8 is_found = 0;
14508 uint8 sta_id = HDD_WLAN_INVALID_STA_ID;
14509 uint16 index;
14510 VOS_STATUS status;
14511 hdd_staid_hash_node_t *sta_info_node = NULL;
14512 hdd_staid_hash_node_t *next_node = NULL;
14513
14514 spin_lock_bh( &pAdapter->sta_hash_lock);
14515 if (pAdapter->is_sta_id_hash_initialized != VOS_TRUE) {
14516 spin_unlock_bh( &pAdapter->sta_hash_lock);
Bhargav Shahce3b32c2015-08-10 12:29:24 +053014517 hddLog(VOS_TRACE_LEVEL_INFO,
Nirav Shah7e3c8132015-06-22 23:51:42 +053014518 FL("hash is not initialized for session id %d"),
14519 pAdapter->sessionId);
14520 return HDD_WLAN_INVALID_STA_ID;
14521 }
14522
14523 index = hdd_sta_id_hash_calculate_index(pAdapter, mac_addr_in);
14524 status = hdd_list_peek_front ( &pAdapter->sta_id_hash.bins[index],
14525 (hdd_list_node_t**) &sta_info_node );
14526
14527 while ( NULL != sta_info_node && VOS_STATUS_SUCCESS == status )
14528 {
14529 if (vos_mem_compare(&sta_info_node->mac_addr,
14530 mac_addr_in, sizeof(v_MACADDR_t))) {
14531 is_found = 1;
14532 sta_id = sta_info_node->sta_id;
14533 break;
14534 }
14535 status = hdd_list_peek_next (&pAdapter->sta_id_hash.bins[index],
14536 (hdd_list_node_t*)sta_info_node,
14537 (hdd_list_node_t**)&next_node);
14538 sta_info_node = next_node;
14539 }
14540 spin_unlock_bh( &pAdapter->sta_hash_lock);
14541 return sta_id;
14542}
14543
c_manjeecfd1efb2015-09-25 19:32:34 +053014544/*FW memory dump feature*/
14545/**
14546 * This structure hold information about the /proc file
14547 *
14548 */
14549static struct proc_dir_entry *proc_file, *proc_dir;
14550
14551/**
14552 * memdump_read() - perform read operation in memory dump proc file
14553 *
14554 * @file - handle for the proc file.
14555 * @buf - pointer to user space buffer.
14556 * @count - number of bytes to be read.
14557 * @pos - offset in the from buffer.
14558 *
14559 * This function performs read operation for the memory dump proc file.
14560 *
14561 * Return: number of bytes read on success, error code otherwise.
14562 */
14563static ssize_t memdump_read(struct file *file, char __user *buf,
14564 size_t count, loff_t *pos)
14565{
14566 int status;
14567 hdd_context_t *hdd_ctx = (hdd_context_t *)PDE_DATA(file_inode(file));
14568 size_t ret_count;
c_manjeef1495642015-10-13 18:35:01 +053014569 loff_t bytes_left;
c_manjeecfd1efb2015-09-25 19:32:34 +053014570 ENTER();
14571
14572 hddLog(LOG1, FL("Read req for size:%zu pos:%llu"), count, *pos);
14573 status = wlan_hdd_validate_context(hdd_ctx);
14574 if (0 != status) {
14575 return -EINVAL;
14576 }
14577
14578 if (!wlan_fwr_mem_dump_test_and_set_read_allowed_bit()) {
14579 hddLog(LOGE, FL("Current mem dump request timed out/failed"));
14580 return -EINVAL;
14581 }
14582
14583 /* run fs_read_handler in an atomic context*/
14584 vos_ssr_protect(__func__);
c_manjeef1495642015-10-13 18:35:01 +053014585 ret_count = wlan_fwr_mem_dump_fsread_handler( buf, count, pos, &bytes_left);
14586 if(bytes_left == 0)
c_manjeecfd1efb2015-09-25 19:32:34 +053014587 {
14588 /*Free the fwr mem dump buffer */
14589 wlan_free_fwr_mem_dump_buffer();
14590 wlan_set_fwr_mem_dump_state(FW_MEM_DUMP_IDLE);
c_manjeef1495642015-10-13 18:35:01 +053014591 ret_count=0;
c_manjeecfd1efb2015-09-25 19:32:34 +053014592 }
14593 /*if SSR/unload code is waiting for memdump_read to finish,signal it*/
14594 vos_ssr_unprotect(__func__);
14595 EXIT();
14596 return ret_count;
14597}
14598
14599/**
14600 * struct memdump_fops - file operations for memory dump feature
14601 * @read - read function for memory dump operation.
14602 *
14603 * This structure initialize the file operation handle for memory
14604 * dump feature
14605 */
14606static const struct file_operations memdump_fops = {
14607 read: memdump_read
14608};
14609
14610/*
14611* wlan_hdd_fw_mem_dump_cb : callback for Fw mem dump request
14612* To be passed by HDD to WDA and called upon receiving of response
14613* from firmware
14614* @fwMemDumpReqContext : memory dump request context
14615* @dump_rsp : dump response from HAL
14616* Returns none
14617*/
14618void wlan_hdd_fw_mem_dump_cb(void *fwMemDumpReqContext,
14619 tAniFwrDumpRsp *dump_rsp)
14620{
c_manjeef1495642015-10-13 18:35:01 +053014621 struct hdd_fw_mem_dump_req_ctx *pHddFwMemDumpCtx = (struct hdd_fw_mem_dump_req_ctx *)fwMemDumpReqContext;
c_manjeecfd1efb2015-09-25 19:32:34 +053014622
c_manjeef1495642015-10-13 18:35:01 +053014623 ENTER();
14624 spin_lock(&hdd_context_lock);
14625 if(!pHddFwMemDumpCtx || (FW_MEM_DUMP_MAGIC != pHddFwMemDumpCtx->magic)) {
14626 spin_unlock(&hdd_context_lock);
14627 return;
14628 }
14629 /* report the status to requesting function and free mem.*/
c_manjeecfd1efb2015-09-25 19:32:34 +053014630 if (dump_rsp->dump_status != eHAL_STATUS_SUCCESS) {
c_manjeef1495642015-10-13 18:35:01 +053014631 hddLog(LOGE, FL("fw dump request declined by fwr"));
14632 //set the request completion variable
14633 complete(&(pHddFwMemDumpCtx->req_completion));
c_manjeecfd1efb2015-09-25 19:32:34 +053014634 //Free the allocated fwr dump
14635 wlan_free_fwr_mem_dump_buffer();
14636 wlan_set_fwr_mem_dump_state(FW_MEM_DUMP_IDLE);
c_manjeecfd1efb2015-09-25 19:32:34 +053014637 }
c_manjeef1495642015-10-13 18:35:01 +053014638 else {
14639 hddLog(LOG1, FL("fw dump request accepted by fwr"));
14640 /* register the HDD callback which will be called by SVC */
14641 wlan_set_svc_fw_mem_dump_req_cb((void*)wlan_hdd_fw_mem_dump_req_cb,(void*)pHddFwMemDumpCtx);
14642 }
14643 spin_unlock(&hdd_context_lock);
c_manjeecfd1efb2015-09-25 19:32:34 +053014644 EXIT();
14645
14646}
14647
14648/**
14649 * memdump_procfs_remove() - Remove file/dir under procfs for memory dump
14650 *
14651 * This function removes file/dir under proc file system that was
14652 * processing firmware memory dump
14653 *
14654 * Return: None
14655 */
14656static void memdump_procfs_remove(void)
14657{
14658 remove_proc_entry(PROCFS_MEMDUMP_NAME, proc_dir);
14659 hddLog(LOG1 , FL("/proc/%s/%s removed\n"),
14660 PROCFS_MEMDUMP_DIR, PROCFS_MEMDUMP_NAME);
14661 remove_proc_entry(PROCFS_MEMDUMP_DIR, NULL);
14662 hddLog(LOG1 , FL("/proc/%s removed\n"), PROCFS_MEMDUMP_DIR);
14663}
14664
14665/**
14666 * memdump_procfs_init() - Initialize procfs for memory dump
14667 *
14668 * @vos_ctx - Global vos context.
14669 *
14670 * This function create file under proc file system to be used later for
14671 * processing firmware memory dump
14672 *
14673 * Return: 0 on success, error code otherwise.
14674 */
14675static int memdump_procfs_init(void *vos_ctx)
14676{
14677 hdd_context_t *hdd_ctx;
14678
14679 hdd_ctx = vos_get_context(VOS_MODULE_ID_HDD, vos_ctx);
14680 if (!hdd_ctx) {
14681 hddLog(LOGE , FL("Invalid HDD context"));
14682 return -EINVAL;
14683 }
14684
14685 proc_dir = proc_mkdir(PROCFS_MEMDUMP_DIR, NULL);
14686 if (proc_dir == NULL) {
14687 remove_proc_entry(PROCFS_MEMDUMP_DIR, NULL);
14688 hddLog(LOGE , FL("Error: Could not initialize /proc/%s"),
14689 PROCFS_MEMDUMP_DIR);
14690 return -ENOMEM;
14691 }
14692
14693 proc_file = proc_create_data(PROCFS_MEMDUMP_NAME,
14694 S_IRUSR | S_IWUSR, proc_dir,
14695 &memdump_fops, hdd_ctx);
14696 if (proc_file == NULL) {
14697 remove_proc_entry(PROCFS_MEMDUMP_NAME, proc_dir);
14698 hddLog(LOGE , FL("Error: Could not initialize /proc/%s"),
14699 PROCFS_MEMDUMP_NAME);
14700 return -ENOMEM;
14701 }
14702
14703 hddLog(LOG1 , FL("/proc/%s/%s created"),
14704 PROCFS_MEMDUMP_DIR, PROCFS_MEMDUMP_NAME);
14705
14706 return 0;
14707}
14708
14709/**
14710 * memdump_init() - Initialization function for memory dump feature
14711 *
14712 * This function creates proc file for memdump feature and registers
14713 * HDD callback function with SME.
14714 *
14715 * Return - 0 on success, error otherwise
14716 */
14717int memdump_init(void)
14718{
14719 hdd_context_t *hdd_ctx;
14720 void *vos_ctx;
14721 int status = 0;
14722
14723 vos_ctx = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
14724 if (!vos_ctx) {
14725 hddLog(LOGE, FL("Invalid VOS context"));
14726 return -EINVAL;
14727 }
14728
14729 hdd_ctx = vos_get_context(VOS_MODULE_ID_HDD, vos_ctx);
14730 if (!hdd_ctx) {
14731 hddLog(LOGE , FL("Invalid HDD context"));
14732 return -EINVAL;
14733 }
14734
14735 status = memdump_procfs_init(vos_ctx);
14736 if (status) {
14737 hddLog(LOGE , FL("Failed to create proc file"));
14738 return status;
14739 }
14740
14741 return 0;
14742}
14743
14744/**
14745 * memdump_deinit() - De initialize memdump feature
14746 *
14747 * This function removes proc file created for memdump feature.
14748 *
14749 * Return: None
14750 */
14751int memdump_deinit(void)
14752{
14753 hdd_context_t *hdd_ctx;
14754 void *vos_ctx;
14755
14756 vos_ctx = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
14757 if (!vos_ctx) {
14758 hddLog(LOGE, FL("Invalid VOS context"));
14759 return -EINVAL;
14760 }
14761
14762 hdd_ctx = vos_get_context(VOS_MODULE_ID_HDD, vos_ctx);
14763 if(!hdd_ctx) {
14764 hddLog(LOGE , FL("Invalid HDD context"));
14765 return -EINVAL;
14766 }
14767
14768 memdump_procfs_remove();
14769 return 0;
14770}
14771
14772/**
14773 * wlan_hdd_fw_mem_dump_req(pHddCtx) - common API(cfg80211/ioctl) for requesting fw mem dump to SME
14774 * Return: HAL status
14775 */
14776
14777int wlan_hdd_fw_mem_dump_req(hdd_context_t * pHddCtx)
14778{
14779 tAniFwrDumpReq fw_mem_dump_req={0};
c_manjeef1495642015-10-13 18:35:01 +053014780 struct hdd_fw_mem_dump_req_ctx fw_mem_dump_ctx;
c_manjeecfd1efb2015-09-25 19:32:34 +053014781 eHalStatus status = eHAL_STATUS_FAILURE;
Abhishek Singh4eca9822015-12-09 18:07:34 +053014782 int ret=0, result;
c_manjeecfd1efb2015-09-25 19:32:34 +053014783 ENTER();
c_manjeef1495642015-10-13 18:35:01 +053014784
c_manjeecfd1efb2015-09-25 19:32:34 +053014785 /*Check whether a dump request is already going on
14786 *Caution this function will free previously held memory if new dump request is allowed*/
14787 if (!wlan_fwr_mem_dump_test_and_set_write_allowed_bit()) {
14788 hddLog(LOGE, FL("Fw memdump already in progress"));
14789 return -EBUSY;
14790 }
14791 //Allocate memory for fw mem dump buffer
14792 ret = wlan_fwr_mem_dump_buffer_allocation();
14793 if(ret == -EFAULT)
14794 {
14795 hddLog(LOGE, FL("Fwr mem dump not supported by FW"));
14796 return ret;
14797 }
14798 if (0 != ret) {
14799 hddLog(LOGE, FL("Fwr mem Allocation failed"));
14800 return -ENOMEM;
14801 }
c_manjeef1495642015-10-13 18:35:01 +053014802 init_completion(&fw_mem_dump_ctx.req_completion);
14803 fw_mem_dump_ctx.magic = FW_MEM_DUMP_MAGIC;
14804 fw_mem_dump_ctx.status = false;
14805
c_manjeecfd1efb2015-09-25 19:32:34 +053014806 fw_mem_dump_req.fwMemDumpReqCallback = wlan_hdd_fw_mem_dump_cb;
c_manjeef1495642015-10-13 18:35:01 +053014807 fw_mem_dump_req.fwMemDumpReqContext = &fw_mem_dump_ctx;
c_manjeecfd1efb2015-09-25 19:32:34 +053014808 status = sme_FwMemDumpReq(pHddCtx->hHal, &fw_mem_dump_req);
14809 if(eHAL_STATUS_SUCCESS != status)
14810 {
14811 hddLog(VOS_TRACE_LEVEL_ERROR,
14812 "%s: fw_mem_dump_req failed ", __func__);
14813 wlan_free_fwr_mem_dump_buffer();
c_manjeef1495642015-10-13 18:35:01 +053014814 ret = -EFAULT;
14815 goto cleanup;
c_manjeecfd1efb2015-09-25 19:32:34 +053014816 }
c_manjeef1495642015-10-13 18:35:01 +053014817 /*wait for fw mem dump completion to send event to userspace*/
Abhishek Singh4eca9822015-12-09 18:07:34 +053014818 result =
14819 wait_for_completion_timeout(&fw_mem_dump_ctx.req_completion,
14820 msecs_to_jiffies(FW_MEM_DUMP_TIMEOUT_MS));
14821 if (0 >= result )
c_manjeef1495642015-10-13 18:35:01 +053014822 {
14823 hddLog(VOS_TRACE_LEVEL_ERROR,
Abhishek Singh4eca9822015-12-09 18:07:34 +053014824 "%s: fw_mem_dump_req timeout %d ", __func__,result);
14825 ret = -ETIMEDOUT;
c_manjeef1495642015-10-13 18:35:01 +053014826 }
14827cleanup:
14828 spin_lock(&hdd_context_lock);
14829 fw_mem_dump_ctx.magic = 0;
Abhishek Singh4eca9822015-12-09 18:07:34 +053014830 if(!ret && !fw_mem_dump_ctx.status)
14831 ret = -EFAULT;
c_manjeef1495642015-10-13 18:35:01 +053014832 spin_unlock(&hdd_context_lock);
c_manjeecfd1efb2015-09-25 19:32:34 +053014833
c_manjeef1495642015-10-13 18:35:01 +053014834 EXIT();
Abhishek Singh4eca9822015-12-09 18:07:34 +053014835 return ret;
c_manjeef1495642015-10-13 18:35:01 +053014836}
14837
14838/**
14839 * HDD callback which will be called by SVC to indicate mem dump completion.
14840 */
14841void wlan_hdd_fw_mem_dump_req_cb(struct hdd_fw_mem_dump_req_ctx* pHddFwMemDumpCtx)
14842{
14843 if (!pHddFwMemDumpCtx) {
14844 hddLog(VOS_TRACE_LEVEL_ERROR,
14845 "%s: HDD context not valid ", __func__);
14846 return;
14847 }
14848 spin_lock(&hdd_context_lock);
14849 /* check the req magic and set status */
14850 if (pHddFwMemDumpCtx->magic == FW_MEM_DUMP_MAGIC)
14851 {
14852 pHddFwMemDumpCtx->status = true;
14853 //signal the completion
14854 complete(&(pHddFwMemDumpCtx->req_completion));
14855 }
14856 else
14857 {
14858 hddLog(VOS_TRACE_LEVEL_ERROR,
14859 "%s: fw mem dump request possible timeout ", __func__);
14860 }
14861 spin_unlock(&hdd_context_lock);
c_manjeecfd1efb2015-09-25 19:32:34 +053014862}
14863
Mahesh A Saptasagar67ab9222015-10-21 15:38:41 +053014864void hdd_initialize_adapter_common(hdd_adapter_t *pAdapter)
14865{
14866 if (NULL == pAdapter)
14867 {
14868 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: pAdapter is NULL ", __func__);
14869 return;
14870 }
14871 init_completion(&pAdapter->session_open_comp_var);
14872 init_completion(&pAdapter->session_close_comp_var);
14873 init_completion(&pAdapter->disconnect_comp_var);
14874 init_completion(&pAdapter->linkup_event_var);
14875 init_completion(&pAdapter->cancel_rem_on_chan_var);
14876 init_completion(&pAdapter->rem_on_chan_ready_event);
14877 init_completion(&pAdapter->pno_comp_var);
14878#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
14879 init_completion(&pAdapter->offchannel_tx_event);
14880#endif
14881 init_completion(&pAdapter->tx_action_cnf_event);
14882#ifdef FEATURE_WLAN_TDLS
14883 init_completion(&pAdapter->tdls_add_station_comp);
14884 init_completion(&pAdapter->tdls_del_station_comp);
14885 init_completion(&pAdapter->tdls_mgmt_comp);
14886 init_completion(&pAdapter->tdls_link_establish_req_comp);
14887#endif
14888
14889#ifdef WLAN_FEATURE_RMC
14890 init_completion(&pAdapter->ibss_peer_info_comp);
14891#endif /* WLAN_FEATURE_RMC */
14892 init_completion(&pAdapter->ula_complete);
14893 init_completion(&pAdapter->change_country_code);
14894
14895#ifdef FEATURE_WLAN_BATCH_SCAN
14896 init_completion(&pAdapter->hdd_set_batch_scan_req_var);
14897 init_completion(&pAdapter->hdd_get_batch_scan_req_var);
14898#endif
Kapil Gupta2b44acb2016-12-30 16:49:51 +053014899 init_completion(&pAdapter->wlan_suspend_comp_var);
Mahesh A Saptasagar67ab9222015-10-21 15:38:41 +053014900
14901 return;
14902}
c_manjeecfd1efb2015-09-25 19:32:34 +053014903
Anurag Chouhan0b29de02016-12-16 13:18:40 +053014904#ifdef MDNS_OFFLOAD
14905
14906/**
14907 * hdd_mdns_enable_offload_done() - mdns enable offload response api
14908 * @padapter: holds adapter
14909 * @status: response status
14910 *
14911 * Return - None
14912 */
14913void hdd_mdns_enable_offload_done(void *padapter, VOS_STATUS status)
14914{
14915 hdd_adapter_t* adapter = (hdd_adapter_t*) padapter;
14916
14917 ENTER();
14918
14919 if (NULL == adapter)
14920 {
14921 hddLog(VOS_TRACE_LEVEL_ERROR,
14922 "%s: adapter is NULL",__func__);
14923 return;
14924 }
14925
14926 adapter->mdns_status.mdns_enable_status = status;
14927 vos_event_set(&adapter->mdns_status.vos_event);
14928 return;
14929}
14930
14931/**
14932 * hdd_mdns_fqdn_offload_done() - mdns fqdn offload response api
14933 * @padapter: holds adapter
14934 * @status: responce status
14935 *
14936 * Return - None
14937 */
14938void hdd_mdns_fqdn_offload_done(void *padapter, VOS_STATUS status)
14939{
14940 hdd_adapter_t* adapter = (hdd_adapter_t*) padapter;
14941
14942 ENTER();
14943
14944 if (NULL == adapter)
14945 {
14946 hddLog(VOS_TRACE_LEVEL_ERROR,
14947 "%s: adapter is NULL",__func__);
14948 return;
14949 }
14950
14951 adapter->mdns_status.mdns_fqdn_status = status;
14952 return;
14953}
14954
14955/**
14956 * hdd_mdns_resp_offload_done() - mdns resp offload response api
14957 * @padapter: holds adapter
14958 * @status: responce status
14959 *
14960 * Return - None
14961 */
14962void hdd_mdns_resp_offload_done(void *padapter, VOS_STATUS status)
14963{
14964 hdd_adapter_t* adapter = (hdd_adapter_t*) padapter;
14965
14966 ENTER();
14967
14968 if (NULL == adapter)
14969 {
14970 hddLog(VOS_TRACE_LEVEL_ERROR,
14971 "%s: adapter is NULL",__func__);
14972 return;
14973 }
14974
14975 adapter->mdns_status.mdns_resp_status = status;
14976 return;
14977}
14978
14979/**
14980 * wlan_hdd_mdns_process_response_dname() - Process mDNS domain name
14981 * @response: Pointer to a struct hdd_mdns_resp_info
14982 * @resp_info: Pointer to a struct tSirMDNSResponseInfo
14983 *
14984 * This function will pack the whole domain name without compression. It will
14985 * add the leading len for each field and add zero length octet to terminate
14986 * the domain name.
14987 *
14988 * Return: Return boolean. TRUE for success, FALSE for fail.
14989 */
14990static bool
14991wlan_hdd_mdns_process_response_dname(struct hdd_mdns_resp_info *response,
14992 sir_mdns_resp_info resp_info)
14993{
14994 uint8_t num;
14995 uint16_t idx;
14996 uint8_t len = 0;
14997
14998 if ((response == NULL) || (response->data == NULL) ||
14999 (response->offset == NULL)) {
15000 hddLog(LOGE, FL("Either data or offset in response is NULL!"));
15001 return FALSE;
15002 }
15003
15004 if ((resp_info == NULL) ||
15005 (resp_info->resp_len >= MAX_MDNS_RESP_LEN)) {
15006 hddLog(LOGE, FL("resp_len exceeds %d!"), MAX_MDNS_RESP_LEN);
15007 return FALSE;
15008 }
15009
15010 for (num = 0; num < response->num_entries; num++) {
15011 response->offset[num] =
15012 resp_info->resp_len + MDNS_HEADER_LEN;
15013 idx = num * MAX_LEN_DOMAINNAME_FIELD;
15014 len = strlen((char *)&response->data[idx]);
15015 if ((resp_info->resp_len + len + 1) >= MAX_MDNS_RESP_LEN) {
15016 hddLog(LOGE, FL("resp_len exceeds %d!"),
15017 MAX_MDNS_RESP_LEN);
15018 return FALSE;
15019 }
15020 resp_info->resp_data[resp_info->resp_len] = len;
15021 resp_info->resp_len++;
15022 vos_mem_copy(&resp_info->resp_data[resp_info->resp_len],
15023 &response->data[idx], len);
15024 resp_info->resp_len += len;
15025 }
15026
15027 /* The domain name terminates with the zero length octet */
15028 if (num == response->num_entries) {
15029 if (resp_info->resp_len >= MAX_MDNS_RESP_LEN) {
15030 hddLog(LOGE, FL("resp_len exceeds %d!"),
15031 MAX_MDNS_RESP_LEN);
15032 return FALSE;
15033 }
15034 resp_info->resp_data[resp_info->resp_len] = 0;
15035 resp_info->resp_len++;
15036 }
15037
15038 return TRUE;
15039}
15040
15041/**
15042 * wlan_hdd_mdns_format_response_u16() - Form uint16_t response data
15043 * @value: The uint16_t value is formed to the struct tSirMDNSResponseInfo
15044 * @resp_info: Pointer to a struct tSirMDNSResponseInfo
15045 *
15046 * Return: None
15047 */
15048static void wlan_hdd_mdns_format_response_u16(uint16_t value,
15049 sir_mdns_resp_info resp_info)
15050{
15051 uint8_t val_u8;
15052
15053 if ((resp_info == NULL) || (resp_info->resp_data == NULL))
15054 return;
15055 val_u8 = (value & 0xff00) >> 8;
15056 resp_info->resp_data[resp_info->resp_len++] = val_u8;
15057 val_u8 = value & 0xff;
15058 resp_info->resp_data[resp_info->resp_len++] = val_u8;
15059}
15060
15061/**
15062 * wlan_hdd_mdns_format_response_u32() - Form uint32_t response data
15063 * @value: The uint32_t value is formed to the struct tSirMDNSResponseInfo
15064 * @resp_info: Pointer to a struct tSirMDNSResponseInfo
15065 *
15066 * Return: None
15067 */
15068static void wlan_hdd_mdns_format_response_u32(uint32_t value,
15069 sir_mdns_resp_info resp_info)
15070{
15071 uint8_t val_u8;
15072
15073 if ((resp_info == NULL) || (resp_info->resp_data == NULL))
15074 return;
15075 val_u8 = (value & 0xff000000) >> 24;
15076 resp_info->resp_data[resp_info->resp_len++] = val_u8;
15077 val_u8 = (value & 0xff0000) >> 16;
15078 resp_info->resp_data[resp_info->resp_len++] = val_u8;
15079 val_u8 = (value & 0xff00) >> 8;
15080 resp_info->resp_data[resp_info->resp_len++] = val_u8;
15081 val_u8 = value & 0xff;
15082 resp_info->resp_data[resp_info->resp_len++] = val_u8;
15083}
15084
15085/**
15086 * wlan_hdd_mdns_process_response_misc() - Process misc info in mDNS response
15087 * @resp_type: Response type for mDNS
15088 * @resp_info: Pointer to a struct tSirMDNSResponseInfo
15089 *
15090 * This function will pack the response type, class and TTL (Time To Live).
15091 *
15092 * Return: Return boolean. TRUE for success, FALSE for fail.
15093 */
15094static bool wlan_hdd_mdns_process_response_misc(uint16_t resp_type,
15095 sir_mdns_resp_info resp_info)
15096{
15097 uint16_t len;
15098
15099 if (resp_info == NULL) {
15100 hddLog(LOGE, FL("resp_info is NULL!"));
15101 return FALSE;
15102 }
15103
15104 len = resp_info->resp_len + (2 * sizeof(uint16_t) + sizeof(uint32_t));
15105 if (len >= MAX_MDNS_RESP_LEN) {
15106 hddLog(LOGE, FL("resp_len exceeds %d!"), MAX_MDNS_RESP_LEN);
15107 return FALSE;
15108 }
15109
15110 /* Fill Type, Class, TTL */
15111 wlan_hdd_mdns_format_response_u16(resp_type, resp_info);
15112 wlan_hdd_mdns_format_response_u16(MDNS_CLASS, resp_info);
15113 wlan_hdd_mdns_format_response_u32(MDNS_TTL, resp_info);
15114
15115 return TRUE;
15116}
15117
15118/**
15119 * wlan_hdd_mdns_compress_data() - Compress the domain name in mDNS response
15120 * @resp_info: Pointer to a struct tSirMDNSResponseInfo
15121 * @response_dst: The response which domain name is compressed.
15122 * @response_src: The response which domain name is matched with response_dst.
15123 * Its offset is used for data compression.
15124 * @num_matched: The number of matched entries between response_dst and
15125 * response_src
15126 *
15127 * This function will form the different fields of domain name in response_dst
15128 * if any. Then use the offset of the matched domain name in response_src to
15129 * compress the matched domain name.
15130 *
15131 * Return: Return boolean. TRUE for success, FALSE for fail.
15132 */
15133static bool
15134wlan_hdd_mdns_compress_data(sir_mdns_resp_info resp_info,
15135 struct hdd_mdns_resp_info *response_dst,
15136 struct hdd_mdns_resp_info *response_src,
15137 uint8_t num_matched)
15138{
15139 uint8_t num, num_diff;
15140 uint16_t value, idx;
15141 uint8_t len = 0;
15142
15143 if ((response_src == NULL) || (response_dst == NULL) ||
15144 (resp_info == NULL)) {
15145 hddLog(LOGE, FL("response info is NULL!"));
15146 return FALSE;
15147 }
15148
15149 if (response_dst->num_entries < num_matched) {
15150 hddLog(LOGE, FL("num_entries is less than num_matched!"));
15151 return FALSE;
15152 }
15153
15154 if (resp_info->resp_len >= MAX_MDNS_RESP_LEN) {
15155 hddLog(LOGE, FL("resp_len exceeds %d!"), MAX_MDNS_RESP_LEN);
15156 return FALSE;
15157 }
15158
15159 num_diff = response_dst->num_entries - num_matched;
15160 if ((num_diff > 0) && (response_dst->data == NULL)) {
15161 hddLog(LOGE, FL("response_dst->data is NULL!"));
15162 return FALSE;
15163 }
15164
15165 /*
15166 * Handle the unmatched string at the beginning
15167 * Store the length of octets and the octets
15168 */
15169 for (num = 0; num < num_diff; num++) {
15170 response_dst->offset[num] =
15171 resp_info->resp_len + MDNS_HEADER_LEN;
15172 idx = num * MAX_LEN_DOMAINNAME_FIELD;
15173 len = strlen((char *)&response_dst->data[idx]);
15174 if ((resp_info->resp_len + len + 1) >= MAX_MDNS_RESP_LEN) {
15175 hddLog(LOGE, FL("resp_len exceeds %d!"),
15176 MAX_MDNS_RESP_LEN);
15177 return FALSE;
15178 }
15179 resp_info->resp_data[resp_info->resp_len] = len;
15180 resp_info->resp_len++;
15181 vos_mem_copy(&resp_info->resp_data[resp_info->resp_len],
15182 &response_dst->data[idx], len);
15183 resp_info->resp_len += len;
15184 }
15185 /*
15186 * Handle the matched string from the end
15187 * Just keep the offset and mask the leading two bit
15188 */
15189 if (response_src->num_entries >= num_matched) {
15190 num_diff = response_src->num_entries - num_matched;
15191 value = response_src->offset[num_diff];
15192 if (value > 0) {
15193 value |= 0xc000;
15194 if ((resp_info->resp_len + sizeof(uint16_t)) >=
15195 MAX_MDNS_RESP_LEN) {
15196 hddLog(LOGE, FL("resp_len exceeds %d!"),
15197 MAX_MDNS_RESP_LEN);
15198 return FALSE;
15199 }
15200 wlan_hdd_mdns_format_response_u16(value, resp_info);
15201 return TRUE;
15202 }
15203 }
15204 return FALSE;
15205}
15206
15207/**
15208 * wlan_hdd_mdns_reset_response() - Reset the response info
15209 * @response: The response which info is reset.
15210 *
15211 * Return: None
15212 */
15213static void wlan_hdd_mdns_reset_response(struct hdd_mdns_resp_info *response)
15214{
15215 if (response == NULL)
15216 return;
15217 response->num_entries = 0;
15218 response->data = NULL;
15219 response->offset = NULL;
15220}
15221
15222/**
15223 * wlan_hdd_mdns_init_response() - Initialize the response info
15224 * @response: The response which info is initiatized.
15225 * @resp_dname: The domain name string which might be tokenized.
15226 *
15227 * This function will allocate the memory for both response->data and
15228 * response->offset. Besides, it will also tokenize the domain name to some
15229 * entries and fill response->num_entries with the num of entries.
15230 *
15231 * Return: Return boolean. TRUE for success, FALSE for fail.
15232 */
15233static bool wlan_hdd_mdns_init_response(struct hdd_mdns_resp_info *response,
15234 uint8_t *resp_dname, char separator)
15235{
15236 uint16_t size;
15237
15238 if ((resp_dname == NULL) || (response == NULL)) {
15239 hddLog(LOGE, FL("resp_dname or response is NULL!"));
15240 return FALSE;
15241 }
15242
15243 size = MAX_NUM_FIELD_DOMAINNAME * MAX_LEN_DOMAINNAME_FIELD;
15244 response->data = vos_mem_malloc(size);
15245 if (response->data) {
15246 vos_mem_zero(response->data, size);
15247 if (VOS_STATUS_SUCCESS !=
15248 hdd_string_to_string_array((char *)resp_dname,
15249 response->data,
15250 separator,
15251 &response->num_entries,
15252 MAX_NUM_FIELD_DOMAINNAME,
15253 MAX_LEN_DOMAINNAME_FIELD)) {
15254 hddLog(LOGE, FL("hdd_string_to_string_array fail!"));
15255 goto err_init_resp;
15256 }
15257
15258 if ((response->num_entries > 0) &&
15259 (strlen((char *)&response->data[0]) > 0)) {
15260 size = sizeof(uint16_t) * response->num_entries;
15261 response->offset = vos_mem_malloc(size);
15262 if (response->offset) {
15263 vos_mem_zero(response->offset, size);
15264 return TRUE;
15265 }
15266 }
15267 }
15268
15269err_init_resp:
15270 if (response->data)
15271 vos_mem_free(response->data);
15272 wlan_hdd_mdns_reset_response(response);
15273 return FALSE;
15274}
15275
15276/**
15277 * wlan_hdd_mdns_find_entries_from_end() - Find the matched entries
15278 * @response1: The response info is used to be compared.
15279 * @response2: The response info is used to be compared.
15280 *
15281 * This function will find the matched entries from the end.
15282 *
15283 * Return: Return the number of the matched entries.
15284 */
15285static uint8_t
15286wlan_hdd_mdns_find_entries_from_end(struct hdd_mdns_resp_info *response1,
15287 struct hdd_mdns_resp_info *response2)
15288{
15289 uint8_t min, len1, i;
15290 uint16_t num1, num2;
15291 uint8_t num_matched = 0;
15292
15293 min = VOS_MIN(response1->num_entries, response2->num_entries);
15294
15295 for (i = 1; i <= min; i++) {
15296 num1 = (response1->num_entries - i);
15297 num1 *= MAX_LEN_DOMAINNAME_FIELD;
15298 num2 = (response2->num_entries - i);
15299 num2 *= MAX_LEN_DOMAINNAME_FIELD;
15300 len1 = strlen((char *)&response1->data[num1]);
15301
15302 if ((len1 == 0) ||
15303 (len1 != strlen((char *)&response2->data[num2])))
15304 break;
15305 if (memcmp(&response1->data[num1],
15306 &response2->data[num2], len1))
15307 break;
15308 else
15309 num_matched++;
15310 }
15311
15312 return num_matched;
15313}
15314
15315/**
15316 * wlan_hdd_mdns_find_max() - Find the maximum number of the matched entries
15317 * @matchedlist: Pointer to the array of struct hdd_mdns_resp_matched
15318 * @numlist: The number of the elements in the array matchedlist.
15319 *
15320 * Find the max number of the matched entries among the array matchedlist.
15321 *
15322 * Return: None
15323 */
15324static void wlan_hdd_mdns_find_max(struct hdd_mdns_resp_matched *matchedlist,
15325 uint8_t numlist)
15326{
15327 int j;
15328 struct hdd_mdns_resp_matched tmp;
15329
15330 /* At least two values are used for sorting */
15331 if ((numlist < 2) || (matchedlist == NULL)) {
15332 hddLog(LOGE, FL("At least two values are used for sorting!"));
15333 return;
15334 }
15335
15336 for (j = 0; j < numlist-1; j++) {
15337 if (matchedlist[j].num_matched >
15338 matchedlist[j+1].num_matched) {
15339 vos_mem_copy(&tmp, &matchedlist[j],
15340 sizeof(struct hdd_mdns_resp_matched));
15341 vos_mem_copy(&matchedlist[j], &matchedlist[j+1],
15342 sizeof(struct hdd_mdns_resp_matched));
15343 vos_mem_copy(&matchedlist[j+1], &tmp,
15344 sizeof(struct hdd_mdns_resp_matched));
15345 }
15346 }
15347}
15348
15349/**
15350 * wlan_hdd_mdns_pack_response_type_a() - Pack Type A response
15351 * @ini_config: Pointer to the struct hdd_config_t
15352 * @resp_info: Pointer to the struct tSirMDNSResponseInfo
15353 * @resptype_a: Pointer to the struct hdd_mdns_resp_info of Type A
15354 *
15355 * Type A response include QName, response type, class, TTL and Ipv4.
15356 *
15357 * Return: Return boolean. TRUE for success, FALSE for fail.
15358 */
15359static bool
15360wlan_hdd_mdns_pack_response_type_a(hdd_config_t *ini_config,
15361 sir_mdns_resp_info resp_info,
15362 struct hdd_mdns_resp_info *resptype_a)
15363{
15364 uint16_t value;
15365 uint32_t len;
15366
15367 ENTER();
15368 if ((ini_config == NULL) || (resp_info == NULL) ||
15369 (resptype_a == NULL)) {
15370 hddLog(LOGE, FL("ini_config or response info is NULL!"));
15371 return FALSE;
15372 }
15373
15374 /* No Type A response */
15375 if (strlen((char *)ini_config->mdns_resp_type_a) <= 0)
15376 return TRUE;
15377
15378 /* Wrong response is assigned, just ignore this response */
15379 if (!wlan_hdd_mdns_init_response(resptype_a,
15380 ini_config->mdns_resp_type_a, '.'))
15381 return TRUE;
15382
15383 /* Process response domain name */
15384 if (!wlan_hdd_mdns_process_response_dname(resptype_a, resp_info)) {
15385 hddLog(LOGE, FL("Fail to process mDNS response (%d)!"),
15386 MDNS_TYPE_A);
15387 return FALSE;
15388 }
15389
15390 /* Process response Type, Class, TTL */
15391 if (!wlan_hdd_mdns_process_response_misc(MDNS_TYPE_A, resp_info)) {
15392 hddLog(LOGE, FL("Fail to process mDNS misc response (%d)!"),
15393 MDNS_TYPE_A);
15394 return FALSE;
15395 }
15396
15397 /* Process response RDLength, RData */
15398 len = sizeof(uint16_t) + sizeof(uint32_t);
15399 len += resp_info->resp_len;
15400 if (len >= MAX_MDNS_RESP_LEN) {
15401 hddLog(LOGE, FL("resp_len exceeds %d!"), MAX_MDNS_RESP_LEN);
15402 return FALSE;
15403 }
15404 value = sizeof(uint32_t);
15405 wlan_hdd_mdns_format_response_u16(value, resp_info);
15406 wlan_hdd_mdns_format_response_u32(ini_config->mdns_resp_type_a_ipv4,
15407 resp_info);
15408
15409 EXIT();
15410 return TRUE;
15411}
15412
15413/**
15414 * wlan_hdd_mdns_pack_response_type_txt() - Pack Type Txt response
15415 * @ini_config: Pointer to the struct hdd_config_t
15416 * @resp_info: Pointer to the struct tSirMDNSResponseInfo
15417 * @resptype_txt: Pointer to the struct hdd_mdns_resp_info of Type txt
15418 * @resptype_a: Pointer to the struct hdd_mdns_resp_info of Type A
15419 *
15420 * Type Txt response include QName, response type, class, TTL and text content.
15421 * Also, it will find the matched QName from resptype_A and compress the data.
15422 *
15423 * Return: Return boolean. TRUE for success, FALSE for fail.
15424 */
15425static bool
15426wlan_hdd_mdns_pack_response_type_txt(hdd_config_t *ini_config,
15427 sir_mdns_resp_info resp_info,
15428 struct hdd_mdns_resp_info *resptype_txt,
15429 struct hdd_mdns_resp_info *resptype_a)
15430{
15431 uint8_t num_matched;
15432 uint8_t num;
15433 uint16_t idx;
15434 uint16_t value = 0;
15435 uint32_t len;
15436 uint32_t total_len;
15437 bool status;
15438 struct hdd_mdns_resp_info resptype_content;
15439
15440 ENTER();
15441
15442 if ((ini_config == NULL) || (resp_info == NULL) ||
15443 (resptype_txt == NULL)) {
15444 hddLog(LOGE, FL("ini_config or response info is NULL!"));
15445 return FALSE;
15446 }
15447
15448 /* No Type Txt response */
15449 if (strlen((char *)ini_config->mdns_resp_type_txt) <= 0)
15450 return TRUE;
15451
15452 /* Wrong response is assigned, just ignore this response */
15453 if (!wlan_hdd_mdns_init_response(resptype_txt,
15454 ini_config->mdns_resp_type_txt, '.'))
15455 return TRUE;
15456
15457 /*
15458 * For data compression
15459 * Check if any strings are matched with Type A response
15460 */
15461 if (resptype_a && (resptype_a->num_entries > 0)) {
15462 num_matched = wlan_hdd_mdns_find_entries_from_end(resptype_txt,
15463 resptype_a);
15464 if (num_matched > 0) {
15465 if (!wlan_hdd_mdns_compress_data(resp_info,
15466 resptype_txt, resptype_a, num_matched)) {
15467 hddLog(LOGE, FL("Fail to compress mDNS "
15468 "response (%d)!"), MDNS_TYPE_TXT);
15469 return FALSE;
15470 }
15471 } else {
15472 /*
15473 * num_matched is zero. Error!
15474 * At least ".local" is needed.
15475 */
15476 hddLog(LOGE, FL("No matched string! Fail to pack mDNS "
15477 "response (%d)!"), MDNS_TYPE_TXT);
15478 return FALSE;
15479 }
15480 } else {
15481 /* no TypeA response, so show the whole data */
15482 if (!wlan_hdd_mdns_process_response_dname(resptype_txt,
15483 resp_info)) {
15484 hddLog(LOGE, FL("Fail to process mDNS response (%d)!"),
15485 MDNS_TYPE_TXT);
15486 return FALSE;
15487 }
15488 }
15489
15490 /* Process response Type, Class, TTL */
15491 if (!wlan_hdd_mdns_process_response_misc(MDNS_TYPE_TXT, resp_info)) {
15492 hddLog(LOGE, FL("Fail to process mDNS misc response (%d)!"),
15493 MDNS_TYPE_TXT);
15494 return FALSE;
15495 }
15496
15497 /*
15498 * Process response RDLength, RData.
15499 * TypeTxt RData include len.
15500 */
15501 status = wlan_hdd_mdns_init_response(&resptype_content,
15502 ini_config->mdns_resp_type_txt_content,
15503 '/');
15504 if (status == FALSE) {
15505 hddLog(LOGE, FL("wlan_hdd_mdns_init_response FAIL"));
15506 return FALSE;
15507 }
15508
15509 for (num = 0; num < resptype_content.num_entries; num++) {
15510 idx = num * MAX_LEN_DOMAINNAME_FIELD;
15511 value += strlen((char *)&resptype_content.data[idx]);
15512 }
15513
15514 /* content len is uint16_t */
15515 total_len = sizeof(uint16_t);
15516 total_len += resp_info->resp_len + value +
15517 resptype_content.num_entries;
15518
15519 if (total_len >= MAX_MDNS_RESP_LEN) {
15520 hddLog(LOGE, FL("resp_len exceeds %d!"), MAX_MDNS_RESP_LEN);
15521 return FALSE;
15522 }
15523 wlan_hdd_mdns_format_response_u16(value + resptype_content.num_entries,
15524 resp_info);
15525
15526 for (num = 0; num < resptype_content.num_entries; num++) {
15527 idx = num * MAX_LEN_DOMAINNAME_FIELD;
15528 len = strlen((char *)&resptype_content.data[idx]);
15529 resp_info->resp_data[resp_info->resp_len] = len;
15530 resp_info->resp_len++;
15531
15532 vos_mem_copy(&resp_info->resp_data[resp_info->resp_len],
15533 &resptype_content.data[idx], len);
15534
15535 resp_info->resp_len += len;
15536 hddLog(LOG1, FL("index = %d, len = %d, str = %s"),
15537 num, len, &resptype_content.data[idx]);
15538 }
15539
15540 EXIT();
15541 return TRUE;
15542}
15543
15544/**
15545 * wlan_hdd_mdns_pack_response_type_ptr_dname() - Pack Type PTR domain name
15546 * @ini_config: Pointer to the struct hdd_config_t
15547 * @resp_info: Pointer to the struct tSirMDNSResponseInfo
15548 * @resptype_ptr_dn: Pointer to the struct hdd_mdns_resp_info of Type Ptr
15549 * domain name
15550 * @resptype_ptr: Pointer to the struct hdd_mdns_resp_info of Type Ptr
15551 * @resptype_txt: Pointer to the struct hdd_mdns_resp_info of Type Txt
15552 * @resptype_a: Pointer to the struct hdd_mdns_resp_info of Type A
15553 *
15554 * The Type Ptr response include Type PTR domain name in its data field.
15555 * Also, it will find the matched QName from the existing resptype_ptr,
15556 * resptype_txt, resptype_a and then compress the data.
15557 *
15558 * Return: Return boolean. TRUE for success, FALSE for fail.
15559 */
15560static bool
15561wlan_hdd_mdns_pack_response_type_ptr_dname(hdd_config_t *ini_config,
15562 sir_mdns_resp_info resp_info,
15563 struct hdd_mdns_resp_info *resptype_ptr_dn,
15564 struct hdd_mdns_resp_info *resptype_ptr,
15565 struct hdd_mdns_resp_info *resptype_txt,
15566 struct hdd_mdns_resp_info *resptype_a)
15567{
15568 uint8_t num_matched, numlist, size;
15569 struct hdd_mdns_resp_matched matchedlist[MAX_MDNS_RESP_TYPE-1];
15570 struct hdd_mdns_resp_info *resp;
15571
15572 if ((ini_config == NULL) || (resp_info == NULL) ||
15573 (resptype_ptr == NULL) || (resptype_ptr_dn == NULL)) {
15574 hddLog(LOGE, FL("ini_config or response info is NULL!"));
15575 return FALSE;
15576 }
15577
15578 /* No Type Ptr domain name response */
15579 if (strlen((char *)ini_config->mdns_resp_type_ptr_dname) <= 0)
15580 return TRUE;
15581
15582 /* Wrong response is assigned, just ignore this response */
15583 if (!wlan_hdd_mdns_init_response(resptype_ptr_dn,
15584 ini_config->mdns_resp_type_ptr_dname, '.'))
15585 return TRUE;
15586
15587 /*
15588 * For data compression
15589 * Check if any strings are matched with previous
15590 * response.
15591 */
15592 numlist = 0;
15593 size = (MAX_MDNS_RESP_TYPE-1);
15594 size *= sizeof(struct hdd_mdns_resp_matched);
15595 vos_mem_zero(matchedlist, size);
15596 num_matched = wlan_hdd_mdns_find_entries_from_end(resptype_ptr_dn,
15597 resptype_ptr);
15598 if (num_matched > 0) {
15599 matchedlist[numlist].num_matched = num_matched;
15600 matchedlist[numlist].type = MDNS_TYPE_PTR;
15601 numlist++;
15602 }
15603 if (resptype_txt && (resptype_txt->num_entries > 0)) {
15604 num_matched = wlan_hdd_mdns_find_entries_from_end(
15605 resptype_ptr_dn, resptype_txt);
15606 if (num_matched > 0) {
15607 matchedlist[numlist].num_matched = num_matched;
15608 matchedlist[numlist].type = MDNS_TYPE_TXT;
15609 numlist++;
15610 }
15611 }
15612 if (resptype_a && (resptype_a->num_entries > 0)) {
15613 num_matched = wlan_hdd_mdns_find_entries_from_end(
15614 resptype_ptr_dn,resptype_a);
15615 if (num_matched > 0) {
15616 matchedlist[numlist].num_matched = num_matched;
15617 matchedlist[numlist].type = MDNS_TYPE_A;
15618 numlist++;
15619 }
15620 }
15621 if (numlist > 0) {
15622 if (numlist > 1)
15623 wlan_hdd_mdns_find_max(matchedlist, numlist);
15624 resp = NULL;
15625 switch (matchedlist[numlist-1].type) {
15626 case MDNS_TYPE_A:
15627 resp = resptype_a;
15628 break;
15629 case MDNS_TYPE_TXT:
15630 resp = resptype_txt;
15631 break;
15632 case MDNS_TYPE_PTR:
15633 resp = resptype_ptr;
15634 break;
15635 default:
15636 hddLog(LOGE, FL("Fail to compress mDNS response "
15637 "(%d)!"), MDNS_TYPE_PTR_DNAME);
15638 return FALSE;
15639 }
15640 num_matched = matchedlist[numlist-1].num_matched;
15641 if (!wlan_hdd_mdns_compress_data(resp_info, resptype_ptr_dn,
15642 resp, num_matched)) {
15643 hddLog(LOGE, FL("Fail to compress mDNS response "
15644 "(%d)!"), MDNS_TYPE_PTR_DNAME);
15645 return FALSE;
15646 }
15647 } else {
15648 /* num = 0 -> no matched string */
15649 if (!wlan_hdd_mdns_process_response_dname(resptype_ptr_dn,
15650 resp_info)) {
15651 hddLog(LOGE, FL("Fail to process mDNS response (%d)!"),
15652 MDNS_TYPE_PTR_DNAME);
15653 return FALSE;
15654 }
15655 }
15656
15657 return TRUE;
15658}
15659
15660/**
15661 * wlan_hdd_mdns_pack_response_type_ptr() - Pack Type PTR response
15662 * @ini_config: Pointer to the struct hdd_config_t
15663 * @resp_info: Pointer to the struct tSirMDNSResponseInfo
15664 * @resptype_ptr: Pointer to the struct hdd_mdns_resp_info of Type Ptr
15665 * @resptype_ptr_dn: Pointer to the struct hdd_mdns_resp_info of Type Ptr
15666 * domain name
15667 * @resptype_txt: Pointer to the struct hdd_mdns_resp_info of Type Txt
15668 * @resptype_a: Pointer to the struct hdd_mdns_resp_info of Type A
15669 *
15670 * The Type Ptr response include QName, response type, class, TTL and
15671 * Type PTR domain name. Also, it will find the matched QName from the
15672 * existing resptype_txt, resptype_a and then compress the data.
15673 *
15674 * Return: Return boolean. TRUE for success, FALSE for fail.
15675 */
15676static bool
15677wlan_hdd_mdns_pack_response_type_ptr(hdd_config_t *ini_config,
15678 sir_mdns_resp_info resp_info,
15679 struct hdd_mdns_resp_info *resptype_ptr,
15680 struct hdd_mdns_resp_info *resptype_ptr_dn,
15681 struct hdd_mdns_resp_info *resptype_txt,
15682 struct hdd_mdns_resp_info *resptype_a)
15683{
15684 uint8_t num_matched, num_matched1;
15685 uint16_t value;
15686 uint8_t val_u8;
15687 uint32_t offset_data_len, len;
15688
15689 ENTER();
15690 if ((ini_config == NULL) || (resp_info == NULL) ||
15691 (resptype_ptr == NULL) || (resptype_ptr_dn == NULL)) {
15692 hddLog(LOGE, FL("ini_config or response info is NULL!"));
15693 return FALSE;
15694 }
15695
15696 /* No Type Ptr response */
15697 if (strlen((char *)ini_config->mdns_resp_type_ptr) <= 0)
15698 return TRUE;
15699
15700 /* Wrong response is assigned, just ignore this response */
15701 if (!wlan_hdd_mdns_init_response(resptype_ptr,
15702 ini_config->mdns_resp_type_ptr, '.'))
15703 return TRUE;
15704
15705 /*
15706 * For data compression
15707 * Check if any strings are matched with Type A response
15708 */
15709 num_matched = 0;
15710 num_matched1 = 0;
15711 if (resptype_a && (resptype_a->num_entries > 0)) {
15712 num_matched = wlan_hdd_mdns_find_entries_from_end(resptype_ptr,
15713 resptype_a);
15714 }
15715 if (resptype_txt && (resptype_txt->num_entries > 0)) {
15716 num_matched1 = wlan_hdd_mdns_find_entries_from_end(
15717 resptype_ptr, resptype_txt);
15718 }
15719 if ((num_matched != num_matched1) ||
15720 ((num_matched > 0) && (num_matched1 > 0))) {
15721 if (num_matched >= num_matched1) {
15722 if (!wlan_hdd_mdns_compress_data(resp_info,
15723 resptype_ptr, resptype_a, num_matched)) {
15724 hddLog(LOGE, FL("Fail to compress mDNS "
15725 "response (%d)!"), MDNS_TYPE_PTR);
15726 return FALSE;
15727 }
15728 } else {
15729 /* num_matched is less than num_matched1 */
15730 if (!wlan_hdd_mdns_compress_data(resp_info,
15731 resptype_ptr, resptype_txt, num_matched1)) {
15732 hddLog(LOGE, FL("Fail to compress mDNS "
15733 "response (%d)!"), MDNS_TYPE_PTR);
15734 return FALSE;
15735 }
15736 }
15737 } else {
15738 /*
15739 * Both num_matched and num_matched1 are zero.
15740 * no TypeA & TypeTxt
15741 */
15742 if (!wlan_hdd_mdns_process_response_dname(resptype_ptr,
15743 resp_info)) {
15744 hddLog(LOGE, FL("Fail to process mDNS response (%d)!"),
15745 MDNS_TYPE_PTR);
15746 return FALSE;
15747 }
15748 }
15749
15750 /* Process response Type, Class, TTL */
15751 if (!wlan_hdd_mdns_process_response_misc(MDNS_TYPE_PTR, resp_info)) {
15752 hddLog(LOGE, FL("Fail to process mDNS misc response (%d)!"),
15753 MDNS_TYPE_PTR);
15754 return FALSE;
15755 }
15756
15757 /*
15758 * Process response RDLength, RData (Ptr domain name)
15759 * Save the offset of RData length
15760 */
15761 offset_data_len = resp_info->resp_len;
15762 resp_info->resp_len += sizeof(uint16_t);
15763
15764 if (!wlan_hdd_mdns_pack_response_type_ptr_dname(ini_config, resp_info,
15765 resptype_ptr_dn, resptype_ptr,
15766 resptype_txt, resptype_a)) {
15767 return FALSE;
15768 }
15769 /* Set the RData length */
15770 len = offset_data_len + sizeof(uint16_t);
15771 if ((resptype_ptr_dn->num_entries > 0) &&
15772 (resp_info->resp_len > len)) {
15773 value = resp_info->resp_len - len;
15774 val_u8 = (value & 0xff00) >> 8;
15775 resp_info->resp_data[offset_data_len] = val_u8;
15776 val_u8 = value & 0xff;
15777 resp_info->resp_data[offset_data_len+1] = val_u8;
15778 } else {
15779 hddLog(LOGE, FL("Fail to process mDNS response (%d)!"),
15780 MDNS_TYPE_PTR);
15781 return FALSE;
15782 }
15783
15784 EXIT();
15785 return TRUE;
15786}
15787
15788/**
15789 * wlan_hdd_mdns_pack_response_type_srv_target()- Pack Type Service Target
15790 * @ini_config: Pointer to the struct hdd_config_t
15791 * @resp_info: Pointer to the struct tSirMDNSResponseInfo
15792 * @resptype_srv_tgt: Pointer to the struct hdd_mdns_resp_info of Type Srv
15793 * target
15794 * @resptype_srv: Pointer to the struct hdd_mdns_resp_info of Type Srv
15795 * @resptype_ptr: Pointer to the struct hdd_mdns_resp_info of Type Ptr
15796 * @resptype_ptr_dn: Pointer to the struct hdd_mdns_resp_info of Type Ptr
15797 * domain name
15798 * @resptype_txt: Pointer to the struct hdd_mdns_resp_info of Type Txt
15799 * @resptype_a: Pointer to the struct hdd_mdns_resp_info of Type A
15800 *
15801 * The Type service target is one of the data field in the Type SRV response.
15802 * Also, it will find the matched QName from the existing resptype_srv,
15803 * resptype_ptr, resptype_ptr_dn, resptype_txt, resptype_a and then compress
15804 * the data.
15805 *
15806 * Return: Return boolean. TRUE for success, FALSE for fail.
15807 */
15808static bool
15809wlan_hdd_mdns_pack_response_type_srv_target(hdd_config_t *ini_config,
15810 sir_mdns_resp_info resp_info,
15811 struct hdd_mdns_resp_info *resptype_srv_tgt,
15812 struct hdd_mdns_resp_info *resptype_srv,
15813 struct hdd_mdns_resp_info *resptype_ptr,
15814 struct hdd_mdns_resp_info *resptype_ptr_dn,
15815 struct hdd_mdns_resp_info *resptype_txt,
15816 struct hdd_mdns_resp_info *resptype_a)
15817{
15818 uint8_t num_matched, num, size;
15819 struct hdd_mdns_resp_matched matchedlist[MAX_MDNS_RESP_TYPE-1];
15820 struct hdd_mdns_resp_info *resp;
15821
15822 if ((ini_config == NULL) || (resp_info == NULL) ||
15823 (resptype_srv == NULL) || (resptype_srv_tgt == NULL)) {
15824 hddLog(LOGE, FL("ini_config or response info is NULL!"));
15825 return FALSE;
15826 }
15827
15828 /* No Type Srv Target response */
15829 if (strlen((char *)ini_config->mdns_resp_type_srv_target) <= 0)
15830 return TRUE;
15831
15832 /* Wrong response is assigned, just ignore this response */
15833 if (!wlan_hdd_mdns_init_response(resptype_srv_tgt,
15834 ini_config->mdns_resp_type_srv_target, '.'))
15835 return TRUE;
15836
15837 /*
15838 * For data compression
15839 * Check if any strings are matched with previous response.
15840 */
15841 num = 0;
15842 size = (MAX_MDNS_RESP_TYPE-1);
15843 size *= sizeof(struct hdd_mdns_resp_matched);
15844 vos_mem_zero(matchedlist, size);
15845 num_matched = wlan_hdd_mdns_find_entries_from_end(resptype_srv_tgt,
15846 resptype_srv);
15847 if (num_matched > 0) {
15848 matchedlist[num].num_matched = num_matched;
15849 matchedlist[num].type = MDNS_TYPE_SRV;
15850 num++;
15851 }
15852 if (resptype_ptr && (resptype_ptr->num_entries > 0)) {
15853 if (resptype_ptr_dn && (resptype_ptr_dn->num_entries > 0)) {
15854 num_matched = wlan_hdd_mdns_find_entries_from_end(
15855 resptype_srv_tgt, resptype_ptr_dn);
15856 if (num_matched > 0) {
15857 matchedlist[num].num_matched = num_matched;
15858 matchedlist[num].type = MDNS_TYPE_PTR_DNAME;
15859 num++;
15860 }
15861 }
15862 num_matched = wlan_hdd_mdns_find_entries_from_end(
15863 resptype_srv_tgt, resptype_ptr);
15864 if (num_matched > 0) {
15865 matchedlist[num].num_matched = num_matched;
15866 matchedlist[num].type = MDNS_TYPE_PTR;
15867 num++;
15868 }
15869 }
15870 if (resptype_txt && (resptype_txt->num_entries > 0)) {
15871 num_matched = wlan_hdd_mdns_find_entries_from_end(
15872 resptype_srv_tgt, resptype_txt);
15873 if (num_matched > 0) {
15874 matchedlist[num].num_matched = num_matched;
15875 matchedlist[num].type = MDNS_TYPE_TXT;
15876 num++;
15877 }
15878 }
15879 if (resptype_a && (resptype_a->num_entries > 0)) {
15880 num_matched = wlan_hdd_mdns_find_entries_from_end(
15881 resptype_srv_tgt, resptype_a);
15882 if (num_matched > 0) {
15883 matchedlist[num].num_matched = num_matched;
15884 matchedlist[num].type = MDNS_TYPE_A;
15885 num++;
15886 }
15887 }
15888 if (num > 0) {
15889 if (num > 1)
15890 wlan_hdd_mdns_find_max(matchedlist, num);
15891 resp = NULL;
15892 switch (matchedlist[num-1].type) {
15893 case MDNS_TYPE_A:
15894 resp = resptype_a;
15895 break;
15896 case MDNS_TYPE_TXT:
15897 resp = resptype_txt;
15898 break;
15899 case MDNS_TYPE_PTR:
15900 resp = resptype_ptr;
15901 break;
15902 case MDNS_TYPE_PTR_DNAME:
15903 resp = resptype_ptr_dn;
15904 break;
15905 case MDNS_TYPE_SRV:
15906 resp = resptype_srv;
15907 break;
15908 default:
15909 hddLog(LOGE, FL("Fail to compress mDNS response "
15910 "(%d)!"), MDNS_TYPE_SRV_TARGET);
15911 return FALSE;
15912 }
15913 num_matched = matchedlist[num-1].num_matched;
15914 if (!wlan_hdd_mdns_compress_data(resp_info, resptype_srv_tgt,
15915 resp, num_matched)) {
15916 hddLog(LOGE, FL("Fail to compress mDNS response "
15917 "(%d)!"), MDNS_TYPE_SRV_TARGET);
15918 return FALSE;
15919 }
15920 } else {
15921 /* num = 0 -> no matched string */
15922 if (!wlan_hdd_mdns_process_response_dname(resptype_srv_tgt,
15923 resp_info)) {
15924 hddLog(LOGE, FL("Fail to process mDNS response (%d)!"),
15925 MDNS_TYPE_SRV_TARGET);
15926 return FALSE;
15927 }
15928 }
15929
15930 return TRUE;
15931}
15932
15933/**
15934 * wlan_hdd_mdns_pack_response_type_srv()- Pack Type Service response
15935 * @ini_config: Pointer to the struct hdd_config_t
15936 * @resp_info: Pointer to the struct tSirMDNSResponseInfo
15937 * @resptype_srv: Pointer to the struct hdd_mdns_resp_info of Type Srv
15938 * @resptype_srv_tgt: Pointer to the struct hdd_mdns_resp_info of Type Srv
15939 * target
15940 * @resptype_ptr: Pointer to the struct hdd_mdns_resp_info of Type Ptr
15941 * @resptype_ptr_dn: Pointer to the struct hdd_mdns_resp_info of Type Ptr
15942 * domain name
15943 * @resptype_txt: Pointer to the struct hdd_mdns_resp_info of Type Txt
15944 * @resptype_a: Pointer to the struct hdd_mdns_resp_info of Type A
15945 *
15946 * The Type SRV (Service) response include QName, response type, class, TTL
15947 * and four kinds of data fields. Also, it will find the matched QName from
15948 * the existing resptype_ptr, resptype_ptr_dn, resptype_txt, resptype_a and
15949 * then compress the data.
15950 *
15951 * Return: Return boolean. TRUE for success, FALSE for fail.
15952 */
15953static bool
15954wlan_hdd_mdns_pack_response_type_srv(hdd_config_t *ini_config,
15955 sir_mdns_resp_info resp_info,
15956 struct hdd_mdns_resp_info *resptype_srv,
15957 struct hdd_mdns_resp_info *resptype_srv_tgt,
15958 struct hdd_mdns_resp_info *resptype_ptr,
15959 struct hdd_mdns_resp_info *resptype_ptr_dn,
15960 struct hdd_mdns_resp_info *resptype_txt,
15961 struct hdd_mdns_resp_info *resptype_a)
15962{
15963 uint8_t num_matched, num, size;
15964 uint16_t value;
15965 uint8_t val_u8;
15966 uint32_t offset_data_len, len;
15967 struct hdd_mdns_resp_info *resp;
15968 struct hdd_mdns_resp_matched matchedlist[MAX_MDNS_RESP_TYPE-1];
15969
15970 ENTER();
15971
15972 if ((ini_config == NULL) || (resp_info == NULL) ||
15973 (resptype_srv == NULL) || (resptype_srv_tgt == NULL)) {
15974 hddLog(LOGE, FL("ini_config or response info is NULL!"));
15975 return FALSE;
15976 }
15977
15978 /* No Type Srv response */
15979 if (strlen((char *)ini_config->mdns_resp_type_srv) <= 0)
15980 return TRUE;
15981
15982 /* Wrong response is assigned, just ignore this response */
15983 if (!wlan_hdd_mdns_init_response(resptype_srv,
15984 ini_config->mdns_resp_type_srv, '.'))
15985 return TRUE;
15986
15987 /*
15988 * For data compression
15989 * Check if any strings are matched with Type A response
15990 */
15991 num = 0;
15992 size = (MAX_MDNS_RESP_TYPE-1);
15993 size *= sizeof(struct hdd_mdns_resp_matched);
15994 vos_mem_zero(matchedlist, size);
15995 if (resptype_ptr && (resptype_ptr->num_entries > 0)) {
15996 if (resptype_ptr_dn && (resptype_ptr_dn->num_entries > 0)) {
15997 num_matched = wlan_hdd_mdns_find_entries_from_end(
15998 resptype_srv,
15999 resptype_ptr_dn);
16000 if (num_matched > 0) {
16001 matchedlist[num].num_matched = num_matched;
16002 matchedlist[num].type = MDNS_TYPE_PTR_DNAME;
16003 num++;
16004 }
16005 }
16006 num_matched = wlan_hdd_mdns_find_entries_from_end(resptype_srv,
16007 resptype_ptr);
16008 if (num_matched > 0) {
16009 matchedlist[num].num_matched = num_matched;
16010 matchedlist[num].type = MDNS_TYPE_PTR;
16011 num++;
16012 }
16013 }
16014 if (resptype_txt && (resptype_txt->num_entries > 0)) {
16015 num_matched = wlan_hdd_mdns_find_entries_from_end(resptype_srv,
16016 resptype_txt);
16017 if (num_matched > 0) {
16018 matchedlist[num].num_matched =num_matched;
16019 matchedlist[num].type = MDNS_TYPE_TXT;
16020 num++;
16021 }
16022 }
16023 if (resptype_a && (resptype_a->num_entries > 0)) {
16024 num_matched = wlan_hdd_mdns_find_entries_from_end(resptype_srv,
16025 resptype_a);
16026 if (num_matched > 0) {
16027 matchedlist[num].num_matched = num_matched;
16028 matchedlist[num].type = MDNS_TYPE_A;
16029 num++;
16030 }
16031 }
16032 if (num > 0) {
16033 if (num > 1)
16034 wlan_hdd_mdns_find_max(matchedlist, num);
16035 resp = NULL;
16036 switch (matchedlist[num-1].type) {
16037 case MDNS_TYPE_A:
16038 resp = resptype_a;
16039 break;
16040 case MDNS_TYPE_TXT:
16041 resp = resptype_txt;
16042 break;
16043 case MDNS_TYPE_PTR:
16044 resp = resptype_ptr;
16045 break;
16046 case MDNS_TYPE_PTR_DNAME:
16047 resp = resptype_ptr_dn;
16048 break;
16049 default:
16050 hddLog(LOGE, FL("Fail to compress mDNS response "
16051 "(%d)!"), MDNS_TYPE_SRV);
16052 return FALSE;
16053 }
16054 num_matched = matchedlist[num-1].num_matched;
16055 if (!wlan_hdd_mdns_compress_data(resp_info, resptype_srv,
16056 resp, num_matched)) {
16057 hddLog(LOGE, FL("Fail to compress mDNS response "
16058 "(%d)!"), MDNS_TYPE_SRV);
16059 return FALSE;
16060 }
16061 } else {
16062 /* num = 0 -> no matched string */
16063 if (!wlan_hdd_mdns_process_response_dname(resptype_srv,
16064 resp_info)) {
16065 hddLog(LOGE, FL("Fail to process mDNS response (%d)!"),
16066 MDNS_TYPE_SRV);
16067 return FALSE;
16068 }
16069 }
16070
16071 /* Process response Type, Class, TTL */
16072 if (!wlan_hdd_mdns_process_response_misc(MDNS_TYPE_SRV, resp_info)) {
16073 hddLog(LOGE, FL("Fail to process mDNS misc response (%d)!"),
16074 MDNS_TYPE_SRV);
16075 return FALSE;
16076 }
16077
16078 /*
16079 * Process response RDLength, RData (Srv target name)
16080 * Save the offset of RData length
16081 */
16082 offset_data_len = resp_info->resp_len;
16083 resp_info->resp_len += sizeof(uint16_t);
16084
16085 len = resp_info->resp_len + (3 * sizeof(uint16_t));
16086 if (len >= MAX_MDNS_RESP_LEN) {
16087 hddLog(LOGE, FL("resp_len exceeds %d!"), MAX_MDNS_RESP_LEN);
16088 return FALSE;
16089 }
16090
16091 /* set Srv Priority */
16092 value = ini_config->mdns_resp_type_srv_priority;
16093 wlan_hdd_mdns_format_response_u16(value, resp_info);
16094 /* set Srv Weight */
16095 value = ini_config->mdns_resp_type_srv_weight;
16096 wlan_hdd_mdns_format_response_u16(value, resp_info);
16097 /* set Srv Port */
16098 value = ini_config->mdns_resp_type_srv_port;
16099 wlan_hdd_mdns_format_response_u16(value, resp_info);
16100
16101 if (!wlan_hdd_mdns_pack_response_type_srv_target(ini_config, resp_info,
16102 resptype_srv_tgt, resptype_srv,
16103 resptype_ptr, resptype_ptr_dn,
16104 resptype_txt, resptype_a)) {
16105 return FALSE;
16106 }
16107 /* Set the RData length */
16108 len = offset_data_len + sizeof(uint16_t);
16109 if ((resptype_srv_tgt->num_entries > 0) &&
16110 (resp_info->resp_len > len)) {
16111 value = resp_info->resp_len - len;
16112 val_u8 = (value & 0xff00) >> 8;
16113 resp_info->resp_data[offset_data_len] = val_u8;
16114 val_u8 = value & 0xff;
16115 resp_info->resp_data[offset_data_len+1] = val_u8;
16116 } else {
16117 hddLog(LOGE, FL("Fail to process mDNS response (%d)!"),
16118 MDNS_TYPE_SRV);
16119 return FALSE;
16120 }
16121
16122 EXIT();
16123 return TRUE;
16124}
16125
16126/**
16127 * wlan_hdd_mdns_free_mem() - Free the allocated memory
16128 * @response: Pointer to the struct hdd_mdns_resp_info
16129 *
16130 * Return: None
16131 */
16132static void wlan_hdd_mdns_free_mem(struct hdd_mdns_resp_info *response)
16133{
16134 if (response && response->data)
16135 vos_mem_free(response->data);
16136 if (response && response->offset)
16137 vos_mem_free(response->offset);
16138}
16139
16140/**
16141 * wlan_hdd_mdns_pack_response() - Pack mDNS response
16142 * @ini_config: Pointer to the struct hdd_config_t
16143 * @resp_info: Pointer to the struct tSirMDNSResponseInfo
16144 *
16145 * This function will pack four types of responses (Type A, Type Txt, Type Ptr
16146 * and Type Service). Each response contains QName, response type, class, TTL
16147 * and data fields.
16148 *
16149 * Return: Return boolean. TRUE for success, FALSE for fail.
16150 */
16151static bool wlan_hdd_mdns_pack_response(hdd_config_t *ini_config,
16152 sir_mdns_resp_info resp_info)
16153{
16154 struct hdd_mdns_resp_info resptype_a, resptype_txt;
16155 struct hdd_mdns_resp_info resptype_ptr, resptype_ptr_dn;
16156 struct hdd_mdns_resp_info resptype_srv, resptype_srv_tgt;
16157 uint32_t num_res_records = 0;
16158 bool status = FALSE;
16159
16160 ENTER();
16161
16162 wlan_hdd_mdns_reset_response(&resptype_a);
16163 wlan_hdd_mdns_reset_response(&resptype_txt);
16164 wlan_hdd_mdns_reset_response(&resptype_ptr);
16165 wlan_hdd_mdns_reset_response(&resptype_ptr_dn);
16166 wlan_hdd_mdns_reset_response(&resptype_srv);
16167 wlan_hdd_mdns_reset_response(&resptype_srv_tgt);
16168
16169 resp_info->resp_len = 0;
16170
16171 /* Process Type A response */
16172 if (!wlan_hdd_mdns_pack_response_type_a(ini_config, resp_info,
16173 &resptype_a))
16174 goto err_resptype_a;
16175
16176 if ((resptype_a.num_entries > 0) &&
16177 (strlen((char *)&resptype_a.data[0]) > 0))
16178 num_res_records++;
16179
16180 /* Process Type TXT response */
16181 if (!wlan_hdd_mdns_pack_response_type_txt(ini_config, resp_info,
16182 &resptype_txt, &resptype_a))
16183 goto err_resptype_txt;
16184
16185 if ((resptype_txt.num_entries > 0) &&
16186 (strlen((char *)&resptype_txt.data[0]) > 0))
16187 num_res_records++;
16188
16189 /* Process Type PTR response */
16190 if (!wlan_hdd_mdns_pack_response_type_ptr(ini_config, resp_info,
16191 &resptype_ptr, &resptype_ptr_dn,
16192 &resptype_txt, &resptype_a))
16193 goto err_resptype_ptr;
16194
16195 if ((resptype_ptr.num_entries > 0) &&
16196 (strlen((char *)&resptype_ptr.data[0]) > 0))
16197 num_res_records++;
16198
16199 /* Process Type SRV response */
16200 if (!wlan_hdd_mdns_pack_response_type_srv(ini_config, resp_info,
16201 &resptype_srv, &resptype_srv_tgt,
16202 &resptype_ptr, &resptype_ptr_dn,
16203 &resptype_txt, &resptype_a))
16204 goto err_resptype_srv;
16205
16206 if ((resptype_srv.num_entries > 0) &&
16207 (strlen((char *)&resptype_srv.data[0]) > 0))
16208 num_res_records++;
16209
16210 resp_info->resourceRecord_count = num_res_records;
16211 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
16212 "%s: Pack mDNS response data successfully!", __func__);
16213 status = TRUE;
16214
16215err_resptype_srv:
16216 wlan_hdd_mdns_free_mem(&resptype_srv);
16217 wlan_hdd_mdns_free_mem(&resptype_srv_tgt);
16218
16219err_resptype_ptr:
16220 wlan_hdd_mdns_free_mem(&resptype_ptr);
16221 wlan_hdd_mdns_free_mem(&resptype_ptr_dn);
16222
16223err_resptype_txt:
16224 wlan_hdd_mdns_free_mem(&resptype_txt);
16225
16226err_resptype_a:
16227 wlan_hdd_mdns_free_mem(&resptype_a);
16228
16229 EXIT();
16230 return status;
16231}
16232
16233/**
16234 * wlan_hdd_set_mdns_offload() - Enable mDNS offload
16235 * @hostapd_adapter: Pointer to the struct hdd_adapter_t
16236 *
16237 * This function will set FQDN/unique FQDN (full qualified domain name)
16238 * and the mDNS response. Then send them to SME.
16239 *
16240 * Return: Return boolean. TRUE for success, FALSE for fail.
16241 */
16242bool wlan_hdd_set_mdns_offload(hdd_adapter_t *hostapd_adapter)
16243{
16244 hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(hostapd_adapter);
16245 sir_mdns_offload_info mdns_offload_info;
16246 sir_mdns_fqdn_info mdns_fqdn_info;
16247 sir_mdns_resp_info mdns_resp_info;
16248 uint32_t fqdn_len, ufqdn_len;
16249
16250 ENTER();
16251
16252 /* 1. Prepare the MDNS fqdn request to send to SME */
16253 fqdn_len = strlen(hdd_ctx->cfg_ini->mdns_fqdn);
16254 ufqdn_len = strlen(hdd_ctx->cfg_ini->mdns_uniquefqdn);
16255 if ((fqdn_len == 0) && (ufqdn_len == 0)) {
16256 hddLog(LOGE, FL("No mDNS FQDN or UFQDN is assigned fqdn_len %d,"
16257 "ufqdn_len %d!"), fqdn_len, ufqdn_len);
16258 return FALSE;
16259 }
16260
16261 mdns_fqdn_info = vos_mem_malloc(sizeof(*mdns_fqdn_info));
16262 if (NULL == mdns_fqdn_info) {
16263 hddLog(LOGE, FL("could not allocate tSirMDNSFqdnInfo!"));
16264 return FALSE;
16265 }
16266 /* MDNS fqdn request */
16267 if (fqdn_len > 0) {
16268 vos_mem_zero(mdns_fqdn_info, sizeof(*mdns_fqdn_info));
16269 mdns_fqdn_info->bss_idx = hostapd_adapter->sessionId;
16270 mdns_fqdn_info->fqdn_type = MDNS_FQDN_TYPE_GENERAL;
16271 mdns_fqdn_info->fqdn_len = fqdn_len;
16272 mdns_fqdn_info->mdns_fqdn_callback = hdd_mdns_fqdn_offload_done;
16273 mdns_fqdn_info->mdns_fqdn_cb_context = hostapd_adapter;
16274 vos_mem_copy(mdns_fqdn_info->fqdn_data,
16275 hdd_ctx->cfg_ini->mdns_fqdn,
16276 mdns_fqdn_info->fqdn_len);
16277
16278 if (eHAL_STATUS_SUCCESS !=
16279 sme_set_mdns_fqdn(hdd_ctx->hHal, mdns_fqdn_info)) {
16280 hddLog(LOGE, FL("sme_set_mdns_fqdn fail!"));
16281 vos_mem_free(mdns_fqdn_info);
16282 return FALSE;
16283 }
16284 }
16285 /* MDNS unique fqdn request */
16286 if (ufqdn_len > 0) {
16287 vos_mem_zero(mdns_fqdn_info, sizeof(*mdns_fqdn_info));
16288 mdns_fqdn_info->bss_idx = hostapd_adapter->sessionId;
16289 mdns_fqdn_info->fqdn_type = MDNS_FQDN_TYPE_UNIQUE;
16290 mdns_fqdn_info->fqdn_len = ufqdn_len;
16291 mdns_fqdn_info->mdns_fqdn_callback = hdd_mdns_fqdn_offload_done;
16292 mdns_fqdn_info->mdns_fqdn_cb_context = hostapd_adapter;
16293 vos_mem_copy(mdns_fqdn_info->fqdn_data,
16294 hdd_ctx->cfg_ini->mdns_uniquefqdn,
16295 mdns_fqdn_info->fqdn_len);
16296 if (eHAL_STATUS_SUCCESS !=
16297 sme_set_mdns_fqdn(hdd_ctx->hHal, mdns_fqdn_info)) {
16298 hddLog(LOGE, FL("sme_set_mdns_fqdn fail!"));
16299 vos_mem_free(mdns_fqdn_info);
16300 return FALSE;
16301 }
16302 }
16303 vos_mem_free(mdns_fqdn_info);
16304
16305 /* 2. Prepare the MDNS response request to send to SME */
16306 mdns_resp_info = vos_mem_malloc(sizeof(*mdns_resp_info));
16307 if (NULL == mdns_resp_info) {
16308 hddLog(LOGE, FL("could not allocate tSirMDNSResponseInfo!"));
16309 return FALSE;
16310 }
16311
16312 vos_mem_zero(mdns_resp_info, sizeof(*mdns_resp_info));
16313 mdns_resp_info->bss_idx = hostapd_adapter->sessionId;
16314 mdns_resp_info->mdns_resp_callback = hdd_mdns_resp_offload_done;
16315 mdns_resp_info->mdns_resp_cb_context = hostapd_adapter;
16316 if (!wlan_hdd_mdns_pack_response(hdd_ctx->cfg_ini, mdns_resp_info)) {
16317 hddLog(LOGE, FL("wlan_hdd_pack_mdns_response fail!"));
16318 vos_mem_free(mdns_resp_info);
16319 return FALSE;
16320 }
16321 if (eHAL_STATUS_SUCCESS !=
16322 sme_set_mdns_resp(hdd_ctx->hHal, mdns_resp_info)) {
16323 hddLog(LOGE, FL("sme_set_mdns_resp fail!"));
16324 vos_mem_free(mdns_resp_info);
16325 return FALSE;
16326 }
16327 vos_mem_free(mdns_resp_info);
16328
16329 /* 3. Prepare the MDNS Enable request to send to SME */
16330 mdns_offload_info = vos_mem_malloc(sizeof(*mdns_offload_info));
16331 if (NULL == mdns_offload_info) {
16332 hddLog(LOGE, FL("could not allocate tSirMDNSOffloadInfo!"));
16333 return FALSE;
16334 }
16335
16336 vos_mem_zero(mdns_offload_info, sizeof(*mdns_offload_info));
16337
16338 mdns_offload_info->bss_idx = hostapd_adapter->sessionId;
16339 mdns_offload_info->enable = hdd_ctx->cfg_ini->enable_mdns_offload;
16340 mdns_offload_info->mdns_enable_callback = hdd_mdns_enable_offload_done;
16341 mdns_offload_info->mdns_enable_cb_context = hostapd_adapter;
16342 if (eHAL_STATUS_SUCCESS !=
16343 sme_set_mdns_offload(hdd_ctx->hHal, mdns_offload_info)) {
16344 hddLog(LOGE, FL("sme_set_mdns_offload fail!"));
16345 vos_mem_free(mdns_offload_info);
16346 return FALSE;
16347 }
16348
16349 vos_mem_free(mdns_offload_info);
16350 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
16351 "%s: enable mDNS offload successfully!", __func__);
16352 return TRUE;
16353}
Manjeet Singh3ed79242017-01-11 19:04:32 +053016354
16355
Anurag Chouhan0b29de02016-12-16 13:18:40 +053016356#endif /* MDNS_OFFLOAD */
c_manjeecfd1efb2015-09-25 19:32:34 +053016357
Hanumanth Reddy Pothulad864f312017-01-18 16:16:08 +053016358/**
16359 * wlan_hdd_start_sap() - This function starts bss of SAP.
16360 * @ap_adapter: SAP adapter
16361 *
16362 * This function will process the starting of sap adapter.
16363 *
16364 * Return: void.
16365 */
16366void wlan_hdd_start_sap(hdd_adapter_t *ap_adapter)
16367{
16368 hdd_ap_ctx_t *hdd_ap_ctx;
16369 hdd_hostapd_state_t *hostapd_state;
16370 VOS_STATUS vos_status;
16371 hdd_context_t *hdd_ctx;
16372 tsap_Config_t *pConfig;
16373
16374 if (NULL == ap_adapter) {
16375 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16376 FL("ap_adapter is NULL here"));
16377 return;
16378 }
16379
16380 hdd_ctx = WLAN_HDD_GET_CTX(ap_adapter);
16381 hdd_ap_ctx = WLAN_HDD_GET_AP_CTX_PTR(ap_adapter);
16382 hostapd_state = WLAN_HDD_GET_HOSTAP_STATE_PTR(ap_adapter);
16383 pConfig = &ap_adapter->sessionCtx.ap.sapConfig;
16384
16385 mutex_lock(&hdd_ctx->sap_lock);
16386 if (test_bit(SOFTAP_BSS_STARTED, &ap_adapter->event_flags))
16387 goto end;
16388
16389 if (0 != wlan_hdd_cfg80211_update_apies(ap_adapter)) {
16390 hddLog(LOGE, FL("SAP Not able to set AP IEs"));
16391 goto end;
16392 }
16393
16394 vos_event_reset(&hostapd_state->vosEvent);
16395 if (WLANSAP_StartBss(hdd_ctx->pvosContext, hdd_hostapd_SAPEventCB,
16396 &hdd_ap_ctx->sapConfig, (v_PVOID_t)ap_adapter->dev)
16397 != VOS_STATUS_SUCCESS) {
16398 goto end;
16399 }
16400
16401 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
16402 FL("Waiting for SAP to start"));
16403 vos_status = vos_wait_single_event(&hostapd_state->vosEvent, 10000);
16404 if (!VOS_IS_STATUS_SUCCESS(vos_status)) {
16405 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16406 FL("SAP Start failed"));
16407 goto end;
16408 }
16409 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
16410 FL("SAP Start Success"));
16411 set_bit(SOFTAP_BSS_STARTED, &ap_adapter->event_flags);
16412
16413 wlan_hdd_incr_active_session(hdd_ctx, ap_adapter->device_mode);
16414 hostapd_state->bCommit = TRUE;
16415
16416end:
16417 mutex_unlock(&hdd_ctx->sap_lock);
16418 return;
16419}
16420
Manjeet Singh3ed79242017-01-11 19:04:32 +053016421#ifdef WLAN_FEATURE_TSF
16422
16423/**
16424 * hdd_tsf_cb() - handle tsf request callback
16425 *
16426 * @pcb_cxt: pointer to the hdd_contex
16427 * @ptsf: pointer to struct stsf
16428 *
16429 * Based on the request sent .
16430 *
16431 * Return: Describe the execute result of this routine
16432 */
16433static int hdd_tsf_cb(void *pcb_ctx, struct stsf *ptsf)
16434{
16435 hdd_context_t *hddctx;
16436 int status;
16437 hdd_adapter_t* adapter = (hdd_adapter_t*)pcb_ctx;
16438
16439 if (pcb_ctx == NULL || ptsf == NULL) {
16440 hddLog(VOS_TRACE_LEVEL_ERROR,
16441 FL("HDD context is not valid"));
16442 return -EINVAL;
16443 }
16444
16445 hddctx = (hdd_context_t *)pcb_ctx;
16446 status = wlan_hdd_validate_context(hddctx);
16447 if (0 != status)
16448 return -EINVAL;
16449
16450 if (NULL == adapter) {
16451 hddLog(VOS_TRACE_LEVEL_ERROR,
16452 FL("failed to find adapter"));
16453 return -EINVAL;
16454 }
16455
16456 hddLog(VOS_TRACE_LEVEL_INFO,
16457 FL("tsf cb handle event, device_mode is %d"),
16458 adapter->device_mode);
16459
16460 /* copy the return value to hdd_tsf_ctx in adapter*/
16461 if (ptsf->tsf_req_status) {
16462
16463 vos_spin_lock_acquire(&adapter->tsf_cap_ctx.tsf_lock);
16464 adapter->tsf_cap_ctx.tsf_get_state = TSF_NOT_RETURNED_BY_FW;
16465 adapter->tsf_cap_ctx.tsf_capture_state = TSF_IDLE;
16466 vos_event_set (&adapter->tsf_cap_ctx.tsf_capture_done_event);
16467 vos_spin_lock_release(&adapter->tsf_cap_ctx.tsf_lock);
16468
16469 hddLog(VOS_TRACE_LEVEL_ERROR, FL("tsf req failure :%d"),
16470 ptsf->tsf_req_status);
16471 return ptsf->tsf_req_status;
16472 }
16473 /* If this is a get request.Store the tsf values in adapter. */
16474 if (!ptsf->set_tsf_req) {
16475 vos_spin_lock_acquire(&adapter->tsf_cap_ctx.tsf_lock);
16476 adapter->tsf_cap_ctx.tsf_low = ptsf->tsf_low;
16477 adapter->tsf_cap_ctx.tsf_high = ptsf->tsf_high;
16478 adapter->tsf_cap_ctx.tsf_get_state = TSF_RETURN;
16479 adapter->tsf_cap_ctx.tsf_capture_state = TSF_IDLE;
16480 vos_spin_lock_release(&adapter->tsf_cap_ctx.tsf_lock);
16481
16482 hddLog(VOS_TRACE_LEVEL_INFO,
16483 FL("hdd_get_tsf_cb sta=%u, tsf_low=%u, tsf_high=%u"),
16484 adapter->sessionId, ptsf->tsf_low, ptsf->tsf_high);
16485 }
16486 else {
16487 vos_spin_lock_acquire(&adapter->tsf_cap_ctx.tsf_lock);
16488 adapter->tsf_cap_ctx.tsf_capture_state = TSF_CAP_STATE;
16489 adapter->tsf_cap_ctx.tsf_get_state = TSF_CURRENT_IN_CAP_STATE;
16490 vos_spin_lock_release(&adapter->tsf_cap_ctx.tsf_lock);
16491 }
16492 vos_spin_lock_acquire(&adapter->tsf_cap_ctx.tsf_lock);
16493 vos_event_set (&adapter->tsf_cap_ctx.tsf_capture_done_event);
16494 vos_spin_lock_release(&adapter->tsf_cap_ctx.tsf_lock);
16495
16496 /* free allocated mem */
16497 vos_mem_free(ptsf);
16498
16499 return 0;
16500}
16501
16502/**
16503 * hdd_capture_tsf() - capture tsf
16504 *
16505 * @adapter: pointer to adapter
16506 * @buf: pointer to upper layer buf
16507 * @len : the length of buf
16508 *
16509 * This function returns tsf value to uplayer.
16510 *
16511 * Return: Describe the execute result of this routine
16512 */
16513int hdd_capture_tsf(hdd_adapter_t *adapter, uint32_t *buf, int len)
16514{
16515 int ret = 0;
16516 hdd_station_ctx_t *hdd_sta_ctx;
16517 hdd_context_t *hdd_ctx;
16518 tSirCapTsfParams cap_tsf_params;
16519 VOS_STATUS status;
16520
16521 if (adapter == NULL || buf == NULL) {
16522 hddLog(VOS_TRACE_LEVEL_ERROR,
16523 FL("invalid pointer"));
16524 return -EINVAL;
16525 }
16526 if (len != 1)
16527 return -EINVAL;
16528
16529 hdd_ctx = WLAN_HDD_GET_CTX(adapter);
16530
16531 if (wlan_hdd_validate_context(hdd_ctx)) {
16532 hddLog(VOS_TRACE_LEVEL_ERROR,
16533 FL("invalid hdd ctx"));
16534 return -EINVAL;
16535 }
16536 if (adapter->device_mode == WLAN_HDD_INFRA_STATION ||
16537 adapter->device_mode == WLAN_HDD_P2P_CLIENT) {
16538 hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
16539 if (hdd_sta_ctx->conn_info.connState !=
16540 eConnectionState_Associated) {
16541
16542 hddLog(VOS_TRACE_LEVEL_INFO,
16543 FL("failed to cap tsf, not connect with ap"));
16544 buf[0] = TSF_STA_NOT_CONNECTED_NO_TSF;
16545 return ret;
16546 }
16547 }
16548 if ((adapter->device_mode == WLAN_HDD_SOFTAP ||
16549 adapter->device_mode == WLAN_HDD_P2P_GO) &&
16550 !(test_bit(SOFTAP_BSS_STARTED, &adapter->event_flags))) {
16551 hddLog(VOS_TRACE_LEVEL_INFO,
16552 FL("Soft AP / P2p GO not beaconing"));
16553 buf[0] = TSF_SAP_NOT_STARTED_NO_TSF;
16554 return ret;
16555 }
16556 if (adapter->tsf_cap_ctx.tsf_capture_state == TSF_CAP_STATE) {
16557 hddLog(VOS_TRACE_LEVEL_INFO,
16558 FL("current in capture state, pls reset"));
16559 buf[0] = TSF_CURRENT_IN_CAP_STATE;
16560 } else {
16561 hddLog(VOS_TRACE_LEVEL_INFO, FL("ioctl issue cap tsf cmd"));
16562 buf[0] = TSF_RETURN;
16563 cap_tsf_params.session_id = adapter->sessionId;
16564 cap_tsf_params.tsf_rsp_cb_func = hdd_tsf_cb;
16565 cap_tsf_params.tsf_rsp_cb_ctx = adapter;
16566
16567 vos_spin_lock_acquire(&adapter->tsf_cap_ctx.tsf_lock);
16568 adapter->tsf_cap_ctx.tsf_capture_state = TSF_CAP_STATE;
16569 adapter->tsf_cap_ctx.tsf_get_state = TSF_CURRENT_IN_CAP_STATE;
16570 vos_spin_lock_release(&adapter->tsf_cap_ctx.tsf_lock);
16571
16572 ret = sme_capture_tsf_req(hdd_ctx->hHal, cap_tsf_params);
16573
16574 if (ret != VOS_STATUS_SUCCESS) {
16575 hddLog(VOS_TRACE_LEVEL_ERROR, FL("capture fail"));
16576 buf[0] = TSF_CAPTURE_FAIL;
16577 vos_spin_lock_acquire(&adapter->tsf_cap_ctx.tsf_lock);
16578 adapter->tsf_cap_ctx.tsf_capture_state = TSF_IDLE;
16579 vos_spin_lock_release(&adapter->tsf_cap_ctx.tsf_lock);
16580 return -EINVAL;
16581 }
16582 /* wait till we get a response from fw */
16583 status = vos_wait_single_event(&adapter->tsf_cap_ctx.
16584 tsf_capture_done_event,
16585 HDD_TSF_CAP_REQ_TIMEOUT);
16586
16587 if (!VOS_IS_STATUS_SUCCESS(status)) {
16588 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16589 ("capture tsf vos wait for single_event failed!! %d"),
16590 adapter->tsf_cap_ctx.tsf_get_state);
16591
16592 vos_spin_lock_acquire(&adapter->tsf_cap_ctx.tsf_lock);
16593 adapter->tsf_cap_ctx.tsf_capture_state = TSF_IDLE;
16594 vos_spin_lock_release(&adapter->tsf_cap_ctx.tsf_lock);
16595
16596 return -EINVAL;
16597 }
16598 }
16599 buf[0] = TSF_RETURN;
16600 hddLog(VOS_TRACE_LEVEL_INFO,
16601 FL("ioctl return cap tsf cmd, ret = %d"), ret);
16602 return ret;
16603}
16604
16605/**
16606 * hdd_indicate_tsf() - return tsf to uplayer
16607 *
16608 * @adapter: pointer to adapter
16609 * @buf: pointer to uplayer buf
16610 * @len : the length of buf
16611 *
16612 * This function returns tsf value to uplayer.
16613 *
16614 * Return: Describe the execute result of this routine
16615 */
16616int hdd_indicate_tsf(hdd_adapter_t *adapter, uint32_t *buf, int len)
16617{
16618 int ret = 0;
16619 hdd_station_ctx_t *hdd_sta_ctx;
16620 hdd_context_t *hdd_ctx;
16621 tSirCapTsfParams cap_tsf_params;
16622 VOS_STATUS status;
16623
16624 if (adapter == NULL || buf == NULL) {
16625 hddLog(VOS_TRACE_LEVEL_ERROR,
16626 FL("invalid pointer"));
16627 return -EINVAL;
16628 }
16629 if (len != 3)
16630 return -EINVAL;
16631
16632 buf [1] = 0;
16633 buf [2] = 0;
16634 hdd_ctx = WLAN_HDD_GET_CTX(adapter);
16635
16636 if (wlan_hdd_validate_context(hdd_ctx)) {
16637 hddLog(VOS_TRACE_LEVEL_ERROR,
16638 FL("invalid hdd ctx"));
16639 return -EINVAL;
16640 }
16641 if (adapter->device_mode == WLAN_HDD_INFRA_STATION ||
16642 adapter->device_mode == WLAN_HDD_P2P_CLIENT) {
16643 hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
16644 if (hdd_sta_ctx->conn_info.connState !=
16645 eConnectionState_Associated) {
16646
16647 hddLog(VOS_TRACE_LEVEL_INFO,
16648 FL("failed to cap tsf, not connect with ap"));
16649 buf[0] = TSF_STA_NOT_CONNECTED_NO_TSF;
16650 return ret;
16651 }
16652 }
16653 if ((adapter->device_mode == WLAN_HDD_SOFTAP ||
16654 adapter->device_mode == WLAN_HDD_P2P_GO) &&
16655 !(test_bit(SOFTAP_BSS_STARTED, &adapter->event_flags))) {
16656 hddLog(VOS_TRACE_LEVEL_INFO,
16657 FL("Soft AP / P2p GO not beaconing"));
16658 buf[0] = TSF_SAP_NOT_STARTED_NO_TSF;
16659 return ret;
16660 }
16661
16662 if (adapter->tsf_cap_ctx.tsf_capture_state != TSF_CAP_STATE ||
16663 adapter->tsf_cap_ctx.tsf_get_state != TSF_CURRENT_IN_CAP_STATE ) {
16664 hddLog(VOS_TRACE_LEVEL_INFO,
16665 FL("Not in capture state,Enter capture state first"));
16666 buf[0] = TSF_GET_FAIL;
16667 } else {
16668 hddLog(VOS_TRACE_LEVEL_INFO, FL("ioctl issue cap tsf cmd"));
16669 cap_tsf_params.session_id = adapter->sessionId;
16670 cap_tsf_params.tsf_rsp_cb_func = hdd_tsf_cb;
16671 cap_tsf_params.tsf_rsp_cb_ctx = adapter;
16672
16673 ret = sme_get_tsf_req(hdd_ctx->hHal, cap_tsf_params);
16674
16675 if (ret != VOS_STATUS_SUCCESS) {
16676 hddLog(VOS_TRACE_LEVEL_ERROR, FL("capture fail"));
16677 buf[0] = TSF_CAPTURE_FAIL;
16678 vos_spin_lock_acquire(&adapter->tsf_cap_ctx.tsf_lock);
16679 adapter->tsf_cap_ctx.tsf_capture_state = TSF_IDLE;
16680 vos_spin_lock_release(&adapter->tsf_cap_ctx.tsf_lock);
16681 return -EINVAL;
16682 }
16683 /* wait till we get a response from fw */
16684 status = vos_wait_single_event(&adapter->tsf_cap_ctx.
16685 tsf_capture_done_event,
16686 HDD_TSF_GET_REQ_TIMEOUT);
16687
16688 if (!VOS_IS_STATUS_SUCCESS(status)) {
16689 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16690 ("capture tsf vos wait for single_event failed!! %d"),
16691 status);
16692
16693 vos_spin_lock_acquire(&adapter->tsf_cap_ctx.tsf_lock);
16694 adapter->tsf_cap_ctx.tsf_capture_state = TSF_IDLE;
16695 vos_spin_lock_release(&adapter->tsf_cap_ctx.tsf_lock);
16696 return status;
16697 }
16698 buf[1] = adapter->tsf_cap_ctx.tsf_low;
16699 buf[2] = adapter->tsf_cap_ctx.tsf_high;
16700
16701 hddLog(VOS_TRACE_LEVEL_INFO,
16702 FL("get tsf cmd,status=%u, tsf_low=%u, tsf_high=%u"),
16703 buf[0], buf[1], buf[2]);
16704 }
16705 hddLog(VOS_TRACE_LEVEL_INFO,
16706 FL("ioctl return cap tsf cmd, ret = %d"), ret);
16707 return ret;
16708}
16709
16710void wlan_hdd_tsf_init(hdd_adapter_t *adapter)
16711{
16712
16713 if (adapter == NULL) {
16714 hddLog(VOS_TRACE_LEVEL_ERROR,
16715 FL("TSF init on a null adapter!"));
16716 return;
16717 }
16718
16719 adapter->tsf_cap_ctx.tsf_get_state = TSF_RETURN;
16720 adapter->tsf_cap_ctx.tsf_capture_state = TSF_IDLE;
16721 vos_event_init(&adapter->tsf_cap_ctx.tsf_capture_done_event);
16722 vos_spin_lock_init(&adapter->tsf_cap_ctx.tsf_lock);
16723 adapter->tsf_cap_ctx.tsf_high = 0;
16724 adapter->tsf_cap_ctx.tsf_low = 0;
16725}
16726
16727#endif
16728
Jeff Johnson295189b2012-06-20 16:38:30 -070016729//Register the module init/exit functions
16730module_init(hdd_module_init);
16731module_exit(hdd_module_exit);
16732
16733MODULE_LICENSE("Dual BSD/GPL");
16734MODULE_AUTHOR("Qualcomm Atheros, Inc.");
16735MODULE_DESCRIPTION("WLAN HOST DEVICE DRIVER");
16736
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070016737module_param_call(con_mode, con_mode_handler, param_get_int, &con_mode,
16738 S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
Jeff Johnson32d95a32012-09-10 13:15:23 -070016739
Jeff Johnson76052702013-04-16 13:55:05 -070016740module_param_call(fwpath, fwpath_changed_handler, param_get_string, &fwpath,
Jeff Johnson32d95a32012-09-10 13:15:23 -070016741 S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
Arif Hussain66559122013-11-21 10:11:40 -080016742
16743module_param(enable_dfs_chan_scan, int,
16744 S_IRUSR | S_IRGRP | S_IROTH);
16745
16746module_param(enable_11d, int,
16747 S_IRUSR | S_IRGRP | S_IROTH);
16748
16749module_param(country_code, charp,
16750 S_IRUSR | S_IRGRP | S_IROTH);