blob: 9a8424ae8dc7f4f78afc43e18d0b4bbe375e1365 [file] [log] [blame]
Jeff Johnson295189b2012-06-20 16:38:30 -07001/*
Masti, Narayanraddi44b0db02015-12-22 11:54:35 +05302 * Copyright (c) 2012-2016 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
Sushant Kaushik83392fa2015-05-05 17:44:40 +0530216static vos_wake_lock_t wlan_wake_lock;
217
Jeff Johnson295189b2012-06-20 16:38:30 -0700218/* set when SSR is needed after unload */
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -0700219static e_hdd_ssr_required isSsrRequired = HDD_SSR_NOT_REQUIRED;
Jeff Johnson295189b2012-06-20 16:38:30 -0700220
221//internal function declaration
Jeff Johnsone7245742012-09-05 17:12:55 -0700222static VOS_STATUS wlan_hdd_framework_restart(hdd_context_t *pHddCtx);
223static void wlan_hdd_restart_init(hdd_context_t *pHddCtx);
224static void wlan_hdd_restart_deinit(hdd_context_t *pHddCtx);
Abhishek Singh00b71972016-01-07 10:51:04 +0530225
226#ifdef WLAN_FEATURE_RMC
227static void hdd_tx_fail_ind_callback(v_U8_t *MacAddr, v_U8_t seqNo);
228
229static int hdd_open_cesium_nl_sock(void);
230static void hdd_close_cesium_nl_sock(void);
231static struct sock *cesium_nl_srv_sock;
232static v_U16_t cesium_pid;
233
234static int hdd_ParseIBSSTXFailEventParams(tANI_U8 *pValue,
235 tANI_U8 *tx_fail_count,
236 tANI_U16 *pid);
237
238static int hdd_ParseUserParams(tANI_U8 *pValue, tANI_U8 **ppArg);
239
240#endif /* WLAN_FEATURE_RMC */
Jeff Johnsone7245742012-09-05 17:12:55 -0700241void wlan_hdd_restart_timer_cb(v_PVOID_t usrDataForCallback);
Sameer Thalappil45931fb2013-02-01 11:18:05 -0800242void hdd_set_wlan_suspend_mode(bool suspend);
Jeff Johnsone7245742012-09-05 17:12:55 -0700243
Jeff Johnson295189b2012-06-20 16:38:30 -0700244v_U16_t hdd_select_queue(struct net_device *dev,
Anand N Sunkade9adb1b2015-07-29 09:56:45 +0530245 struct sk_buff *skb
246#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,13,0))
247 , void *accel_priv
248#endif
249#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
250 , select_queue_fallback_t fallback
251#endif
252);
Jeff Johnson295189b2012-06-20 16:38:30 -0700253
254#ifdef WLAN_FEATURE_PACKET_FILTERING
255static void hdd_set_multicast_list(struct net_device *dev);
256#endif
257
258void hdd_wlan_initial_scan(hdd_adapter_t *pAdapter);
259
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -0800260#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowdade697412013-02-14 16:31:48 -0800261void hdd_getBand_helper(hdd_context_t *pHddCtx, int *pBand);
262static VOS_STATUS hdd_parse_channellist(tANI_U8 *pValue, tANI_U8 *pChannelList, tANI_U8 *pNumChannels);
Srinivas Girigowda100eb322013-03-15 16:48:20 -0700263static VOS_STATUS hdd_parse_send_action_frame_data(tANI_U8 *pValue, tANI_U8 *pTargetApBssid,
264 tANI_U8 *pChannel, tANI_U8 *pDwellTime,
265 tANI_U8 **pBuf, tANI_U8 *pBufLen);
Varun Reddy Yeturu920df212013-05-22 08:07:23 -0700266static VOS_STATUS hdd_parse_reassoc_command_data(tANI_U8 *pValue,
267 tANI_U8 *pTargetApBssid,
268 tANI_U8 *pChannel);
Srinivas Girigowdade697412013-02-14 16:31:48 -0800269#endif
Ratheesh S P21280412015-05-19 14:21:52 +0530270
271/* Store WLAN driver info in a global variable such that crash debugger
272 can extract it from driver debug symbol and crashdump for post processing */
273tANI_U8 g_wlan_driver[ ] = "pronto_driver";
274
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -0800275#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
Srinivas Girigowda5cecb202013-10-08 09:13:25 -0700276VOS_STATUS hdd_parse_get_cckm_ie(tANI_U8 *pValue, tANI_U8 **pCckmIe, tANI_U8 *pCckmIeLen);
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -0800277#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -0700278
Mihir Shetee1093ba2014-01-21 20:13:32 +0530279static VOS_STATUS wlan_hdd_init_channels(hdd_context_t *pHddCtx);
Sushant Kaushik8bc7df22014-04-09 17:55:29 +0530280const char * hdd_device_modetoString(v_U8_t device_mode)
281{
282 switch(device_mode)
283 {
284 CASE_RETURN_STRING( WLAN_HDD_INFRA_STATION );
285 CASE_RETURN_STRING( WLAN_HDD_SOFTAP );
286 CASE_RETURN_STRING( WLAN_HDD_P2P_CLIENT );
287 CASE_RETURN_STRING( WLAN_HDD_P2P_GO );
288 CASE_RETURN_STRING( WLAN_HDD_MONITOR);
289 CASE_RETURN_STRING( WLAN_HDD_FTM );
290 CASE_RETURN_STRING( WLAN_HDD_IBSS );
291 CASE_RETURN_STRING( WLAN_HDD_P2P_DEVICE );
292 default:
293 return "device_mode Unknown";
294 }
295}
Mihir Shetee1093ba2014-01-21 20:13:32 +0530296
Mukul Sharmaa78cf6b2015-02-24 16:59:01 +0530297static int __hdd_netdev_notifier_call(struct notifier_block * nb,
Jeff Johnson295189b2012-06-20 16:38:30 -0700298 unsigned long state,
299 void *ndev)
300{
301 struct net_device *dev = ndev;
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -0700302 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Jeff Johnson27cee452013-03-27 11:10:24 -0700303 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -0700304#ifdef WLAN_BTAMP_FEATURE
305 VOS_STATUS status;
Jeff Johnson295189b2012-06-20 16:38:30 -0700306#endif
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +0530307 long result;
Jeff Johnson295189b2012-06-20 16:38:30 -0700308
309 //Make sure that this callback corresponds to our device.
Jeff Johnson27cee452013-03-27 11:10:24 -0700310 if ((strncmp(dev->name, "wlan", 4)) &&
Amar Singhal4c723bd2013-03-25 18:14:15 -0700311 (strncmp(dev->name, "p2p", 3)))
312 return NOTIFY_DONE;
313
Jeff Johnson295189b2012-06-20 16:38:30 -0700314 if (!dev->ieee80211_ptr)
Jeff Johnson27cee452013-03-27 11:10:24 -0700315 return NOTIFY_DONE;
Jeff Johnson295189b2012-06-20 16:38:30 -0700316
Jeff Johnson27cee452013-03-27 11:10:24 -0700317 if (NULL == pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -0700318 {
Jeff Johnsona8a1a482012-12-12 16:49:33 -0800319 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: HDD Adapter Null Pointer", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700320 VOS_ASSERT(0);
321 return NOTIFY_DONE;
322 }
323
Jeff Johnson27cee452013-03-27 11:10:24 -0700324 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
325 if (NULL == pHddCtx)
326 {
327 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: HDD Context Null Pointer", __func__);
328 VOS_ASSERT(0);
329 return NOTIFY_DONE;
330 }
Sameer Thalappil14067972014-01-23 14:54:54 -0800331 if (pHddCtx->isLogpInProgress)
332 return NOTIFY_DONE;
333
Jeff Johnson27cee452013-03-27 11:10:24 -0700334
335 hddLog(VOS_TRACE_LEVEL_INFO, "%s: %s New Net Device State = %lu",
336 __func__, dev->name, state);
Jeff Johnson295189b2012-06-20 16:38:30 -0700337
338 switch (state) {
339 case NETDEV_REGISTER:
340 break;
341
342 case NETDEV_UNREGISTER:
343 break;
344
345 case NETDEV_UP:
346 break;
347
348 case NETDEV_DOWN:
349 break;
350
351 case NETDEV_CHANGE:
Jeff Johnsone7245742012-09-05 17:12:55 -0700352 if(TRUE == pAdapter->isLinkUpSvcNeeded)
353 complete(&pAdapter->linkup_event_var);
Jeff Johnson295189b2012-06-20 16:38:30 -0700354 break;
355
356 case NETDEV_GOING_DOWN:
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +0530357 result = wlan_hdd_scan_abort(pAdapter);
Girish Gowli4bf7a632014-06-12 13:42:11 +0530358 if (result < 0)
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +0530359 {
360 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
361 "%s: Timeout occurred while waiting for abortscan %ld",
362 __func__, result);
Jeff Johnson295189b2012-06-20 16:38:30 -0700363 }
364 else
365 {
366 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +0530367 "%s: Scan Abort Successful" , __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700368 }
369#ifdef WLAN_BTAMP_FEATURE
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700370 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,"%s: disabling AMP", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700371 status = WLANBAP_StopAmp();
372 if(VOS_STATUS_SUCCESS != status )
373 {
374 pHddCtx->isAmpAllowed = VOS_TRUE;
375 hddLog(VOS_TRACE_LEVEL_FATAL,
376 "%s: Failed to stop AMP", __func__);
377 }
378 else
379 {
380 //a state m/c implementation in PAL is TBD to avoid this delay
381 msleep(500);
Jeff Johnson04dd8a82012-06-29 20:41:40 -0700382 if ( pHddCtx->isAmpAllowed )
383 {
384 WLANBAP_DeregisterFromHCI();
385 pHddCtx->isAmpAllowed = VOS_FALSE;
386 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700387 }
388#endif //WLAN_BTAMP_FEATURE
389 break;
390
391 default:
392 break;
393 }
394
395 return NOTIFY_DONE;
396}
397
Mukul Sharmaa78cf6b2015-02-24 16:59:01 +0530398static int hdd_netdev_notifier_call(struct notifier_block * nb,
399 unsigned long state,
400 void *ndev)
401{
402 int ret;
403 vos_ssr_protect(__func__);
404 ret = __hdd_netdev_notifier_call( nb, state, ndev);
405 vos_ssr_unprotect(__func__);
406 return ret;
407}
408
Jeff Johnson295189b2012-06-20 16:38:30 -0700409struct notifier_block hdd_netdev_notifier = {
410 .notifier_call = hdd_netdev_notifier_call,
411};
412
413/*---------------------------------------------------------------------------
414 * Function definitions
415 *-------------------------------------------------------------------------*/
Jeff Johnson295189b2012-06-20 16:38:30 -0700416void hdd_unregister_mcast_bcast_filter(hdd_context_t *pHddCtx);
417void hdd_register_mcast_bcast_filter(hdd_context_t *pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -0700418//variable to hold the insmod parameters
Madan Mohan Koyyalamudidfd6aa82012-10-18 20:18:43 -0700419static int con_mode;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -0700420#ifndef MODULE
421/* current con_mode - used only for statically linked driver
422 * con_mode is changed by userspace to indicate a mode change which will
423 * result in calling the module exit and init functions. The module
424 * exit function will clean up based on the value of con_mode prior to it
425 * being changed by userspace. So curr_con_mode records the current con_mode
426 * for exit when con_mode becomes the next mode for init
427 */
Madan Mohan Koyyalamudidfd6aa82012-10-18 20:18:43 -0700428static int curr_con_mode;
Jeff Johnson295189b2012-06-20 16:38:30 -0700429#endif
430
Srinivas Girigowda8bf64cb2015-09-30 19:50:09 +0530431#ifdef WLAN_FEATURE_OFFLOAD_PACKETS
432/**
433 * hdd_init_offloaded_packets_ctx() - Initialize offload packets context
434 * @hdd_ctx: hdd global context
435 *
436 * Return: none
437 */
438static void hdd_init_offloaded_packets_ctx(hdd_context_t *hdd_ctx)
439{
440 uint8_t i;
441
442 mutex_init(&hdd_ctx->op_ctx.op_lock);
443 for (i = 0; i < MAXNUM_PERIODIC_TX_PTRNS; i++)
444 {
445 hdd_ctx->op_ctx.op_table[i].request_id = 0;
446 hdd_ctx->op_ctx.op_table[i].pattern_id = i;
447 }
448}
449#else
450static void hdd_init_offloaded_packets_ctx(hdd_context_t *hdd_ctx)
451{
452}
453#endif
454
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -0800455/**---------------------------------------------------------------------------
456
457 \brief hdd_vos_trace_enable() - Configure initial VOS Trace enable
458
459 Called immediately after the cfg.ini is read in order to configure
460 the desired trace levels.
461
462 \param - moduleId - module whose trace level is being configured
463 \param - bitmask - bitmask of log levels to be enabled
464
465 \return - void
466
467 --------------------------------------------------------------------------*/
468static void hdd_vos_trace_enable(VOS_MODULE_ID moduleId, v_U32_t bitmask)
469{
470 wpt_tracelevel level;
471
472 /* if the bitmask is the default value, then a bitmask was not
473 specified in cfg.ini, so leave the logging level alone (it
474 will remain at the "compiled in" default value) */
475 if (CFG_VOS_TRACE_ENABLE_DEFAULT == bitmask)
476 {
477 return;
478 }
479
480 /* a mask was specified. start by disabling all logging */
481 vos_trace_setValue(moduleId, VOS_TRACE_LEVEL_NONE, 0);
482
483 /* now cycle through the bitmask until all "set" bits are serviced */
484 level = VOS_TRACE_LEVEL_FATAL;
485 while (0 != bitmask)
486 {
487 if (bitmask & 1)
488 {
489 vos_trace_setValue(moduleId, level, 1);
490 }
491 level++;
492 bitmask >>= 1;
493 }
494}
495
496
Jeff Johnson295189b2012-06-20 16:38:30 -0700497/**---------------------------------------------------------------------------
498
499 \brief hdd_wdi_trace_enable() - Configure initial WDI Trace enable
500
501 Called immediately after the cfg.ini is read in order to configure
502 the desired trace levels in the WDI.
503
504 \param - moduleId - module whose trace level is being configured
505 \param - bitmask - bitmask of log levels to be enabled
506
507 \return - void
508
509 --------------------------------------------------------------------------*/
510static void hdd_wdi_trace_enable(wpt_moduleid moduleId, v_U32_t bitmask)
511{
512 wpt_tracelevel level;
513
514 /* if the bitmask is the default value, then a bitmask was not
515 specified in cfg.ini, so leave the logging level alone (it
516 will remain at the "compiled in" default value) */
517 if (CFG_WDI_TRACE_ENABLE_DEFAULT == bitmask)
518 {
519 return;
520 }
521
522 /* a mask was specified. start by disabling all logging */
523 wpalTraceSetLevel(moduleId, eWLAN_PAL_TRACE_LEVEL_NONE, 0);
524
525 /* now cycle through the bitmask until all "set" bits are serviced */
526 level = eWLAN_PAL_TRACE_LEVEL_FATAL;
527 while (0 != bitmask)
528 {
529 if (bitmask & 1)
530 {
531 wpalTraceSetLevel(moduleId, level, 1);
532 }
533 level++;
534 bitmask >>= 1;
535 }
536}
Jeff Johnson295189b2012-06-20 16:38:30 -0700537
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +0530538/*
539 * FUNCTION: wlan_hdd_validate_context
540 * This function is used to check the HDD context
541 */
542int wlan_hdd_validate_context(hdd_context_t *pHddCtx)
543{
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +0530544
545 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
546 {
Mahesh A Saptasagar886997a2015-03-04 13:15:51 +0530547 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +0530548 "%s: HDD context is Null", __func__);
549 return -ENODEV;
550 }
551
552 if (pHddCtx->isLogpInProgress)
553 {
Mahesh A Saptasagar886997a2015-03-04 13:15:51 +0530554 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
c_hpothu8adb97b2014-12-08 19:38:20 +0530555 "%s: LOGP %s. Ignore!!", __func__,
556 vos_is_wlan_in_badState(VOS_MODULE_ID_HDD, NULL)
557 ?"failed":"in Progress");
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +0530558 return -EAGAIN;
559 }
560
Mihir Shete18156292014-03-11 15:38:30 +0530561 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +0530562 {
Mahesh A Saptasagar886997a2015-03-04 13:15:51 +0530563 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +0530564 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
565 return -EAGAIN;
566 }
567 return 0;
568}
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -0700569#ifdef CONFIG_ENABLE_LINUX_REG
570void hdd_checkandupdate_phymode( hdd_context_t *pHddCtx)
571{
572 hdd_adapter_t *pAdapter = NULL;
573 hdd_station_ctx_t *pHddStaCtx = NULL;
574 eCsrPhyMode phyMode;
575 hdd_config_t *cfg_param = NULL;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +0530576
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -0700577 if (NULL == pHddCtx)
578 {
579 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
580 "HDD Context is null !!");
581 return ;
582 }
583
584 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION);
585 if (NULL == pAdapter)
586 {
587 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
588 "pAdapter is null !!");
589 return ;
590 }
591
592 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
593 if (NULL == pHddStaCtx)
594 {
595 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
596 "pHddStaCtx is null !!");
597 return ;
598 }
599
600 cfg_param = pHddCtx->cfg_ini;
601 if (NULL == cfg_param)
602 {
603 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
604 "cfg_params not available !!");
605 return ;
606 }
607
608 phyMode = sme_GetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter));
609
610 if (!pHddCtx->isVHT80Allowed)
611 {
612 if ((eCSR_DOT11_MODE_AUTO == phyMode) ||
613 (eCSR_DOT11_MODE_11ac == phyMode) ||
614 (eCSR_DOT11_MODE_11ac_ONLY == phyMode))
615 {
616 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
617 "Setting phymode to 11n!!");
618 sme_SetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter), eCSR_DOT11_MODE_11n);
619 }
620 }
621 else
622 {
623 /*New country Supports 11ac as well resetting value back from .ini*/
624 sme_SetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter),
625 hdd_cfg_xlate_to_csr_phy_mode(cfg_param->dot11Mode));
626 return ;
627 }
628
629 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
630 ((eCSR_CFG_DOT11_MODE_11AC_ONLY == pHddStaCtx->conn_info.dot11Mode) ||
631 (eCSR_CFG_DOT11_MODE_11AC == pHddStaCtx->conn_info.dot11Mode)))
632 {
633 VOS_STATUS vosStatus;
634
635 // need to issue a disconnect to CSR.
636 INIT_COMPLETION(pAdapter->disconnect_comp_var);
637 vosStatus = sme_RoamDisconnect(WLAN_HDD_GET_HAL_CTX(pAdapter),
638 pAdapter->sessionId,
639 eCSR_DISCONNECT_REASON_UNSPECIFIED );
640
641 if (VOS_STATUS_SUCCESS == vosStatus)
c_hpothu6ff1c3c2013-10-01 19:01:57 +0530642 {
643 long ret;
644
645 ret = wait_for_completion_interruptible_timeout(&pAdapter->disconnect_comp_var,
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -0700646 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
c_hpothu6ff1c3c2013-10-01 19:01:57 +0530647 if (0 >= ret)
648 hddLog(LOGE, FL("failure waiting for disconnect_comp_var %ld"),
649 ret);
650 }
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -0700651
652 }
653}
654#else
Gopichand Nakkaladacbcb52013-04-18 16:41:54 +0530655void hdd_checkandupdate_phymode( hdd_adapter_t *pAdapter, char *country_code)
656{
657 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
658 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
659 hdd_config_t *cfg_param;
660 eCsrPhyMode phyMode;
c_hpothu6ff1c3c2013-10-01 19:01:57 +0530661 long ret;
Gopichand Nakkaladacbcb52013-04-18 16:41:54 +0530662
663 if (NULL == pHddCtx)
664 {
665 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
666 "HDD Context is null !!");
667 return ;
668 }
669
670 cfg_param = pHddCtx->cfg_ini;
671
672 if (NULL == cfg_param)
673 {
674 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
675 "cfg_params not available !!");
676 return ;
677 }
678
679 phyMode = sme_GetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter));
680
681 if (NULL != strstr(cfg_param->listOfNon11acCountryCode, country_code))
682 {
683 if ((eCSR_DOT11_MODE_AUTO == phyMode) ||
684 (eCSR_DOT11_MODE_11ac == phyMode) ||
685 (eCSR_DOT11_MODE_11ac_ONLY == phyMode))
686 {
687 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
688 "Setting phymode to 11n!!");
689 sme_SetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter), eCSR_DOT11_MODE_11n);
690 }
691 }
692 else
693 {
694 /*New country Supports 11ac as well resetting value back from .ini*/
695 sme_SetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter),
696 hdd_cfg_xlate_to_csr_phy_mode(cfg_param->dot11Mode));
697 return ;
698 }
699
700 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
701 ((eCSR_CFG_DOT11_MODE_11AC_ONLY == pHddStaCtx->conn_info.dot11Mode) ||
702 (eCSR_CFG_DOT11_MODE_11AC == pHddStaCtx->conn_info.dot11Mode)))
703 {
704 VOS_STATUS vosStatus;
705
706 // need to issue a disconnect to CSR.
707 INIT_COMPLETION(pAdapter->disconnect_comp_var);
708 vosStatus = sme_RoamDisconnect(WLAN_HDD_GET_HAL_CTX(pAdapter),
709 pAdapter->sessionId,
710 eCSR_DISCONNECT_REASON_UNSPECIFIED );
711
712 if (VOS_STATUS_SUCCESS == vosStatus)
c_hpothu6ff1c3c2013-10-01 19:01:57 +0530713 {
714 ret = wait_for_completion_interruptible_timeout(&pAdapter->disconnect_comp_var,
Gopichand Nakkaladacbcb52013-04-18 16:41:54 +0530715 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
c_hpothu6ff1c3c2013-10-01 19:01:57 +0530716 if (ret <= 0)
717 {
718 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
719 "wait on disconnect_comp_var is failed %ld", ret);
720 }
721 }
Gopichand Nakkaladacbcb52013-04-18 16:41:54 +0530722
723 }
724}
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -0700725#endif //CONFIG_ENABLE_LINUX_REG
Gopichand Nakkaladacbcb52013-04-18 16:41:54 +0530726
Tushnim Bhattacharyya9cdf6082013-04-21 16:33:30 -0700727void hdd_checkandupdate_dfssetting( hdd_adapter_t *pAdapter, char *country_code)
728{
729 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
730 hdd_config_t *cfg_param;
731
732 if (NULL == pHddCtx)
733 {
734 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
735 "HDD Context is null !!");
736 return ;
737 }
738
739 cfg_param = pHddCtx->cfg_ini;
740
741 if (NULL == cfg_param)
742 {
743 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
744 "cfg_params not available !!");
745 return ;
746 }
747
Agarwal Ashish738843c2014-09-25 12:27:56 +0530748 if (NULL != strstr(cfg_param->listOfNonDfsCountryCode, country_code) ||
749 pHddCtx->disable_dfs_flag == TRUE)
Tushnim Bhattacharyya9cdf6082013-04-21 16:33:30 -0700750 {
751 /*New country doesn't support DFS */
752 sme_UpdateDfsSetting(WLAN_HDD_GET_HAL_CTX(pAdapter), 0);
753 }
754 else
755 {
756 /*New country Supports DFS as well resetting value back from .ini*/
757 sme_UpdateDfsSetting(WLAN_HDD_GET_HAL_CTX(pAdapter), cfg_param->enableDFSChnlScan);
758 }
759
760}
761
Abhishek Singh00b71972016-01-07 10:51:04 +0530762#ifdef WLAN_FEATURE_RMC
763static int hdd_parse_setrmcenable_command(tANI_U8 *pValue, tANI_U8 *pRmcEnable)
764{
765 tANI_U8 *inPtr = pValue;
766 int tempInt;
767 int v = 0;
768 char buf[32];
769 *pRmcEnable = 0;
770
771 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
772 /*no argument after the command*/
773 if (NULL == inPtr)
774 {
775 return 0;
776 }
777
778 /*no space after the command*/
779 else if (SPACE_ASCII_VALUE != *inPtr)
780 {
781 return 0;
782 }
783
784 /*removing empty spaces*/
785 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
786
787 /*no argument followed by spaces*/
788 if ('\0' == *inPtr)
789 {
790 return 0;
791 }
792
793 /* getting the first argument which enables or disables RMC
794 * for input IP v4 address*/
795 sscanf(inPtr, "%32s ", buf);
796 v = kstrtos32(buf, 10, &tempInt);
797 if ( v < 0)
798 {
799 return -EINVAL;
800 }
801
802 *pRmcEnable = tempInt;
803
804 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
805 "ucRmcEnable: %d", *pRmcEnable);
806
807 return 0;
808}
809
810/* Function header left blank Intentionally */
811static int hdd_parse_setrmcactionperiod_command(tANI_U8 *pValue,
812 tANI_U32 *pActionPeriod)
813{
814 tANI_U8 *inPtr = pValue;
815 int tempInt;
816 int v = 0;
817 char buf[32];
818 *pActionPeriod = 0;
819
820 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
821 /*no argument after the command*/
822 if (NULL == inPtr)
823 {
824 return -EINVAL;
825 }
826
827 /*no space after the command*/
828 else if (SPACE_ASCII_VALUE != *inPtr)
829 {
830 return -EINVAL;
831 }
832
833 /*removing empty spaces*/
834 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
835
836 /*no argument followed by spaces*/
837 if ('\0' == *inPtr)
838 {
839 return 0;
840 }
841
842 /* getting the first argument which enables or disables RMC
843 * for input IP v4 address*/
844 sscanf(inPtr, "%32s ", buf);
845 v = kstrtos32(buf, 10, &tempInt);
846 if ( v < 0)
847 {
848 return -EINVAL;
849 }
850
851 /* Range checking for passed paramter */
852 if (tempInt < WNI_CFG_RMC_ACTION_PERIOD_FREQUENCY_STAMIN ||
853 tempInt > WNI_CFG_RMC_ACTION_PERIOD_FREQUENCY_STAMAX)
854 {
855 return -EINVAL;
856 }
857
858 *pActionPeriod = tempInt;
859
860 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
861 "uActionPeriod: %d", *pActionPeriod);
862
863 return 0;
864}
865
866/* Function header left blank Intentionally */
867static int hdd_parse_setrmcrate_command(tANI_U8 *pValue,
868 tANI_U32 *pRate, tTxrateinfoflags *pTxFlags)
869{
870 tANI_U8 *inPtr = pValue;
871 int tempInt;
872 int v = 0;
873 char buf[32];
874 *pRate = 0;
875 *pTxFlags = 0;
876
877 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
878 /*no argument after the command*/
879 if (NULL == inPtr)
880 {
881 return -EINVAL;
882 }
883
884 /*no space after the command*/
885 else if (SPACE_ASCII_VALUE != *inPtr)
886 {
887 return -EINVAL;
888 }
889
890 /*removing empty spaces*/
891 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
892
893 /*no argument followed by spaces*/
894 if ('\0' == *inPtr)
895 {
896 return 0;
897 }
898
899 /*
900 * getting the first argument which sets multicast rate.
901 */
902 sscanf(inPtr, "%32s ", buf);
903 v = kstrtos32(buf, 10, &tempInt);
904 if ( v < 0)
905 {
906 return -EINVAL;
907 }
908
909 /*
910 * Validate the multicast rate.
911 */
912 switch (tempInt)
913 {
914 default:
915 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
916 "Unsupported rate: %d", tempInt);
917 return -EINVAL;
918 case 0:
919 case 6:
920 case 9:
921 case 12:
922 case 18:
923 case 24:
924 case 36:
925 case 48:
926 case 54:
927 *pTxFlags = eHAL_TX_RATE_LEGACY;
928 *pRate = tempInt * 10;
929 break;
930 case 65:
931 *pTxFlags = eHAL_TX_RATE_HT20;
932 *pRate = tempInt * 10;
933 break;
934 case 72:
935 *pTxFlags = eHAL_TX_RATE_HT20 | eHAL_TX_RATE_SGI;
936 *pRate = 722; /* fractional rate 72.2 Mbps */
937 break;
938 }
939
940 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
941 "Rate: %d", *pRate);
942
943 return 0;
944}
945
946/**---------------------------------------------------------------------------
947
948 \brief hdd_cfg80211_get_ibss_peer_info_cb() - Callback function for IBSS
949 Peer Info request
950
951 This is an asynchronous callback function from SME when the peer info
952 is received
953
954 \pUserData -> Adapter private data
955 \pPeerInfoRsp -> Peer info response
956
957 \return - 0 for success non-zero for failure
958 --------------------------------------------------------------------------*/
959static void
960hdd_cfg80211_get_ibss_peer_info_cb(v_VOID_t *pUserData, v_VOID_t *pPeerInfoRsp)
961{
962 hdd_adapter_t *pAdapter = (hdd_adapter_t *)pUserData;
963 tSirPeerInfoRspParams *pPeerInfo = (tSirPeerInfoRspParams *)pPeerInfoRsp;
964 hdd_station_ctx_t *pStaCtx;
965 v_U8_t i;
966
967 /*Sanity check*/
968 if ((NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic))
969 {
970 hddLog(LOGE,
971 FL("invalid adapter or adapter has invalid magic"));
972 return;
973 }
974
975 pStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
976 if (NULL != pStaCtx && NULL != pPeerInfo &&
977 eHAL_STATUS_SUCCESS == pPeerInfo->status)
978 {
979 pStaCtx->ibss_peer_info.status = pPeerInfo->status;
980 pStaCtx->ibss_peer_info.numIBSSPeers = pPeerInfo->numPeers;
981
982 /* Paranoia check */
983 if (pPeerInfo->numPeers < HDD_MAX_NUM_IBSS_STA)
984 {
985 for (i = 0; i < pPeerInfo->numPeers; i++)
986 {
987 memcpy(&pStaCtx->ibss_peer_info.ibssPeerList[i],
988 &pPeerInfo->peerInfoParams[i],
989 sizeof(hdd_ibss_peer_info_params_t));
990 }
991 hddLog(LOG1,
992 FL("Peer Info copied in HDD"));
993 }
994 else
995 {
996 hddLog(LOGE,
997 FL(" Number of peers %d returned is more than limit %d"),
998 pPeerInfo->numPeers, HDD_MAX_NUM_IBSS_STA);
999 }
1000 }
1001 else
1002 {
1003 hddLog(LOG1,
1004 FL("peerInfo returned is NULL"));
1005 }
1006
1007 complete(&pAdapter->ibss_peer_info_comp);
1008}
1009
1010/**---------------------------------------------------------------------------
1011
1012 \brief hdd_cfg80211_get_ibss_peer_info_all() -
1013
1014 Request function to get IBSS peer info from lower layers
1015
1016 \pAdapter -> Adapter context
1017
1018 \return - 0 for success non-zero for failure
1019 --------------------------------------------------------------------------*/
1020static
1021VOS_STATUS hdd_cfg80211_get_ibss_peer_info_all(hdd_adapter_t *pAdapter)
1022{
1023 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
1024 long status;
1025 VOS_STATUS retStatus = VOS_STATUS_E_FAILURE;
1026
1027 INIT_COMPLETION(pAdapter->ibss_peer_info_comp);
1028
1029 retStatus = sme_RequestIBSSPeerInfo(hHal, pAdapter,
1030 hdd_cfg80211_get_ibss_peer_info_cb,
1031 VOS_TRUE, 0xFF);
1032
1033 if (VOS_STATUS_SUCCESS == retStatus)
1034 {
1035 status = wait_for_completion_interruptible_timeout
1036 (&pAdapter->ibss_peer_info_comp,
1037 msecs_to_jiffies(IBSS_PEER_INFO_REQ_TIMOEUT));
1038
1039 /* status will be 0 if timed out */
1040 if (status <= 0)
1041 {
1042 hddLog(VOS_TRACE_LEVEL_WARN, "%s: Warning: IBSS_PEER_INFO_TIMEOUT %ld",
1043 __func__, status);
1044 retStatus = VOS_STATUS_E_FAILURE;
1045 return retStatus;
1046 }
1047 }
1048 else
1049 {
1050 hddLog(VOS_TRACE_LEVEL_WARN,
1051 "%s: Warning: sme_RequestIBSSPeerInfo Request failed", __func__);
1052 }
1053
1054 return retStatus;
1055}
1056
1057/**---------------------------------------------------------------------------
1058
1059 \brief hdd_cfg80211_get_ibss_peer_info() -
1060
1061 Request function to get IBSS peer info from lower layers
1062
1063 \pAdapter -> Adapter context
1064 \staIdx -> Sta index for which the peer info is requested
1065
1066 \return - 0 for success non-zero for failure
1067 --------------------------------------------------------------------------*/
1068static VOS_STATUS
1069hdd_cfg80211_get_ibss_peer_info(hdd_adapter_t *pAdapter, v_U8_t staIdx)
1070{
1071 long status;
1072 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
1073 VOS_STATUS retStatus = VOS_STATUS_E_FAILURE;
1074
1075 INIT_COMPLETION(pAdapter->ibss_peer_info_comp);
1076
1077 retStatus = sme_RequestIBSSPeerInfo(hHal, pAdapter,
1078 hdd_cfg80211_get_ibss_peer_info_cb,
1079 VOS_FALSE, staIdx);
1080
1081 if (VOS_STATUS_SUCCESS == retStatus)
1082 {
1083 status = wait_for_completion_interruptible_timeout
1084 (&pAdapter->ibss_peer_info_comp,
1085 msecs_to_jiffies(IBSS_PEER_INFO_REQ_TIMOEUT));
1086
1087 /* status = 0 on timeout */
1088 if (status <= 0)
1089 {
1090 hddLog(VOS_TRACE_LEVEL_WARN, "%s: Warning: IBSS_PEER_INFO_TIMEOUT %ld",
1091 __func__, status);
1092 retStatus = VOS_STATUS_E_FAILURE;
1093 return retStatus;
1094 }
1095 }
1096 else
1097 {
1098 hddLog(VOS_TRACE_LEVEL_WARN,
1099 "%s: Warning: sme_RequestIBSSPeerInfo Request failed", __func__);
1100 }
1101
1102 return retStatus;
1103}
1104
1105/* Function header left blank Intentionally */
1106VOS_STATUS
1107hdd_parse_get_ibss_peer_info(tANI_U8 *pValue, v_MACADDR_t *pPeerMacAddr)
1108{
1109 tANI_U8 *inPtr = pValue;
1110 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
1111
1112 /*no argument after the command*/
1113 if (NULL == inPtr)
1114 {
1115 return VOS_STATUS_E_FAILURE;;
1116 }
1117
1118 /*no space after the command*/
1119 else if (SPACE_ASCII_VALUE != *inPtr)
1120 {
1121 return VOS_STATUS_E_FAILURE;;
1122 }
1123
1124 /*removing empty spaces*/
1125 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
1126
1127 /*no argument followed by spaces*/
1128 if ('\0' == *inPtr)
1129 {
1130 return VOS_STATUS_E_FAILURE;;
1131 }
1132
1133 /*getting the first argument ie the peer mac address */
1134 if (inPtr[2] != ':' || inPtr[5] != ':' || inPtr[8] != ':' ||
1135 inPtr[11] != ':' || inPtr[14] != ':')
1136 {
1137 return VOS_STATUS_E_FAILURE;;
1138 }
1139 sscanf(inPtr, "%2x:%2x:%2x:%2x:%2x:%2x",
1140 (unsigned int *)&pPeerMacAddr->bytes[0],
1141 (unsigned int *)&pPeerMacAddr->bytes[1],
1142 (unsigned int *)&pPeerMacAddr->bytes[2],
1143 (unsigned int *)&pPeerMacAddr->bytes[3],
1144 (unsigned int *)&pPeerMacAddr->bytes[4],
1145 (unsigned int *)&pPeerMacAddr->bytes[5]);
1146
1147 /* The command buffer seems to be fine */
1148 return VOS_STATUS_SUCCESS;
1149}
1150
1151/* Function header left blank Intentionally */
1152static int hdd_parse_set_ibss_oui_data_command(tANI_U8 *command, tANI_U8 *ie,
1153 tANI_U32 limit)
1154{
1155 tANI_U8 len;
1156 tANI_U8 data;
1157
1158 /* skip white space */
1159 while ((SPACE_ASCII_VALUE == *command) && ('\0' != *command))
1160 {
1161 command++;
1162 limit--;
1163 }
1164
1165 /* skip element id and element length */
1166 len = 2;
1167
1168 /* extract oui */
1169 while ((SPACE_ASCII_VALUE != *command) && ('\0' != *command) &&
1170 (limit > 1))
1171 {
1172 /* Convert ASCII to decimal */
1173 data = ((*command -'0') << 4) | (*(command + 1) - '0');
1174 ie[len++] = data;
1175 command += 2;
1176 limit -= 2;
1177 }
1178
1179 /* skip white space */
1180 while ((SPACE_ASCII_VALUE == *command) && ('\0' != *command))
1181 {
1182 command++;
1183 limit--;
1184 }
1185
1186 /* extract data */
1187 while ((SPACE_ASCII_VALUE != *command) && ('\0' != *command) &&
1188 (limit > 1))
1189 {
1190 /* Convert ASCII to decimal */
1191 data = ((*command -'0') << 4) | (*(command + 1) - '0');
1192 ie[len++] = data;
1193 command += 2;
1194 limit -= 2;
1195 }
1196
1197 /* fill element id and element length */
1198 ie[0] = IE_EID_VENDOR;
1199 ie[1] = len - 2;
1200
1201 return len;
1202}
1203
1204static tANI_U32 hdd_find_ibss_wpa_ie_pos(tANI_U8 *addIePtr, tANI_U32 addIeLen)
1205{
1206 tANI_U32 ieLenPresent = 0;
1207 int left = addIeLen;
1208 v_U8_t *ptr = addIePtr;
1209 v_U8_t elem_id,elem_len;
1210
1211 while(left >= 2)
1212 {
1213 elem_id = ptr[0];
1214 elem_len = ptr[1];
1215 left -= 2;
1216 if(elem_len > left)
1217 {
1218 hddLog(LOGE,
1219 FL("****Invalid elem_len=%d left=%d*****"),
1220 elem_len,left);
1221 return 0;
1222 }
1223 if ((elem_id == IE_EID_VENDOR) &&
1224 (left >= WPA_OUI_TYPE_SIZE))
1225 {
1226 if (!memcmp(&ptr[2], WPA_OUI_TYPE,
1227 WPA_OUI_TYPE_SIZE))
1228 {
1229 ieLenPresent += elem_len + 2;
1230 return ieLenPresent;
1231 }
1232 }
1233 ieLenPresent += (elem_len + 2);
1234 left -= elem_len;
1235 ptr += (elem_len + 2);
1236 }
1237 return 0;
1238}
1239
1240#endif /* WLAN_FEATURE_RMC */
1241
Rajeev79dbe4c2013-10-05 11:03:42 +05301242#ifdef FEATURE_WLAN_BATCH_SCAN
1243
1244/**---------------------------------------------------------------------------
1245
1246 \brief hdd_extract_assigned_int_from_str() - Extracts assigned integer from
1247 input string
1248
1249 This function extracts assigned integer from string in below format:
1250 "STRING=10" : extracts integer 10 from this string
1251
1252 \param - pInPtr Pointer to input string
1253 \param - base Base for string to int conversion(10 for decimal 16 for hex)
1254 \param - pOutPtr Pointer to variable in which extracted integer needs to be
1255 assigned
1256 \param - pLastArg to tell whether it is last arguement in input string or
1257 not
1258
1259 \return - NULL for failure cases
1260 pointer to next arguement in input string for success cases
1261 --------------------------------------------------------------------------*/
1262static tANI_U8 *
1263hdd_extract_assigned_int_from_str
1264(
1265 tANI_U8 *pInPtr,
1266 tANI_U8 base,
1267 tANI_U32 *pOutPtr,
1268 tANI_U8 *pLastArg
1269)
1270{
1271 int tempInt;
1272 int v = 0;
1273 char buf[32];
1274 int val = 0;
1275 *pLastArg = FALSE;
1276
1277 pInPtr = strnchr(pInPtr, strlen(pInPtr), EQUALS_TO_ASCII_VALUE);
1278 if (NULL == pInPtr)
1279 {
1280 return NULL;
1281 }
1282
1283 pInPtr++;
1284
1285 while ((SPACE_ASCII_VALUE == *pInPtr) && ('\0' != *pInPtr)) pInPtr++;
1286
1287 val = sscanf(pInPtr, "%32s ", buf);
1288 if (val < 0 && val > strlen(pInPtr))
1289 {
1290 return NULL;
1291 }
1292 pInPtr += val;
1293 v = kstrtos32(buf, base, &tempInt);
1294 if (v < 0)
1295 {
1296 return NULL;
1297 }
Rajeev Kumar4d93d842014-01-02 18:31:21 -08001298 if (tempInt < 0)
1299 {
1300 tempInt = 0;
1301 }
Rajeev79dbe4c2013-10-05 11:03:42 +05301302 *pOutPtr = tempInt;
1303
1304 pInPtr = strnchr(pInPtr, strlen(pInPtr), SPACE_ASCII_VALUE);
1305 if (NULL == pInPtr)
1306 {
1307 *pLastArg = TRUE;
1308 return NULL;
1309 }
1310 while ((SPACE_ASCII_VALUE == *pInPtr) && ('\0' != *pInPtr)) pInPtr++;
1311
1312 return pInPtr;
1313}
1314
1315/**---------------------------------------------------------------------------
1316
1317 \brief hdd_extract_assigned_char_from_str() - Extracts assigned char from
1318 input string
1319
1320 This function extracts assigned character from string in below format:
1321 "STRING=A" : extracts char 'A' from this string
1322
1323 \param - pInPtr Pointer to input string
1324 \param - pOutPtr Pointer to variable in which extracted char needs to be
1325 assigned
1326 \param - pLastArg to tell whether it is last arguement in input string or
1327 not
1328
1329 \return - NULL for failure cases
1330 pointer to next arguement in input string for success cases
1331 --------------------------------------------------------------------------*/
1332static tANI_U8 *
1333hdd_extract_assigned_char_from_str
1334(
1335 tANI_U8 *pInPtr,
1336 tANI_U8 *pOutPtr,
1337 tANI_U8 *pLastArg
1338)
1339{
1340 *pLastArg = FALSE;
1341
1342 pInPtr = strnchr(pInPtr, strlen(pInPtr), EQUALS_TO_ASCII_VALUE);
1343 if (NULL == pInPtr)
1344 {
1345 return NULL;
1346 }
1347
1348 pInPtr++;
1349
1350 while ((SPACE_ASCII_VALUE == *pInPtr) && ('\0' != *pInPtr)) pInPtr++;
1351
1352 *pOutPtr = *pInPtr;
1353
1354 pInPtr = strnchr(pInPtr, strlen(pInPtr), SPACE_ASCII_VALUE);
1355 if (NULL == pInPtr)
1356 {
1357 *pLastArg = TRUE;
1358 return NULL;
1359 }
1360 while ((SPACE_ASCII_VALUE == *pInPtr) && ('\0' != *pInPtr)) pInPtr++;
1361
1362 return pInPtr;
1363}
1364
1365
1366/**---------------------------------------------------------------------------
1367
1368 \brief hdd_parse_set_batchscan_command () - HDD parse set batch scan command
1369
1370 This function parses set batch scan command in below format:
1371 WLS_BATCHING_SET <space> followed by below arguements
1372 "SCANFREQ=XX" : Optional defaults to 30 sec
1373 "MSCAN=XX" : Required number of scans to attempt to batch
1374 "BESTN=XX" : Best Network (RSSI) defaults to 16
1375 "CHANNEL=<X,Y>" : optional defaults to all channels, can list 'A'or` B.
1376 A. implies only 5 GHz , B. implies only 2.4GHz
1377 "RTT=X" : optional defaults to 0
1378 returns the MIN of MSCAN or the max # of scans firmware can cache or -1 on
1379 error
1380
1381 For example input commands:
1382 1) WLS_BATCHING_SET SCANFREQ=60 MSCAN=10 BESTN=20 CHANNEL=A RTT=0 -> This is
1383 translated into set batch scan with following parameters:
1384 a) Frequence 60 seconds
1385 b) Batch 10 scans together
1386 c) Best RSSI to be 20
1387 d) 5GHz band only
1388 e) RTT is equal to 0
1389
1390 \param - pValue Pointer to input channel list
1391 \param - pHddSetBatchScanReq Pointer to HDD batch scan request structure
1392
1393 \return - 0 for success non-zero for failure
1394
1395 --------------------------------------------------------------------------*/
1396static int
1397hdd_parse_set_batchscan_command
1398(
1399 tANI_U8 *pValue,
1400 tSirSetBatchScanReq *pHddSetBatchScanReq
1401)
1402{
1403 tANI_U8 *inPtr = pValue;
1404 tANI_U8 val = 0;
1405 tANI_U8 lastArg = 0;
Abhishek Singh00b71972016-01-07 10:51:04 +05301406 tANI_U32 nScanFreq = HDD_SET_BATCH_SCAN_DEFAULT_FREQ;
Rajeev Kumar45e64a72013-11-18 19:48:15 -08001407 tANI_U32 nMscan;
Abhishek Singh00b71972016-01-07 10:51:04 +05301408 tANI_U32 nBestN = HDD_SET_BATCH_SCAN_BEST_NETWORK;
1409 tANI_U8 ucRfBand = HDD_SET_BATCH_SCAN_DEFAULT_BAND;
1410 tANI_U32 nRtt = 0;
Rajeev Kumarc933d982013-11-18 20:04:20 -08001411 tANI_U32 temp;
Rajeev79dbe4c2013-10-05 11:03:42 +05301412
Rajeev79dbe4c2013-10-05 11:03:42 +05301413 /*go to space after WLS_BATCHING_SET command*/
1414 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
1415 /*no argument after the command*/
1416 if (NULL == inPtr)
1417 {
1418 return -EINVAL;
1419 }
1420
1421 /*no space after the command*/
1422 else if (SPACE_ASCII_VALUE != *inPtr)
1423 {
1424 return -EINVAL;
1425 }
1426
1427 /*removing empty spaces*/
1428 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
1429
1430 /*no argument followed by spaces*/
1431 if ('\0' == *inPtr)
1432 {
1433 return -EINVAL;
1434 }
1435
1436 /*check and parse SCANFREQ*/
1437 if ((strncmp(inPtr, "SCANFREQ", 8) == 0))
1438 {
1439 inPtr = hdd_extract_assigned_int_from_str(inPtr, 10,
Rajeev Kumarc933d982013-11-18 20:04:20 -08001440 &temp, &lastArg);
Rajeev Kumar45e64a72013-11-18 19:48:15 -08001441
Rajeev Kumarc933d982013-11-18 20:04:20 -08001442 if (0 != temp)
Rajeev Kumar45e64a72013-11-18 19:48:15 -08001443 {
Rajeev Kumarc933d982013-11-18 20:04:20 -08001444 nScanFreq = temp;
Rajeev Kumar45e64a72013-11-18 19:48:15 -08001445 }
1446
Rajeev79dbe4c2013-10-05 11:03:42 +05301447 if ( (NULL == inPtr) || (TRUE == lastArg))
1448 {
1449 return -EINVAL;
1450 }
1451 }
1452
1453 /*check and parse MSCAN*/
1454 if ((strncmp(inPtr, "MSCAN", 5) == 0))
1455 {
1456 inPtr = hdd_extract_assigned_int_from_str(inPtr, 10,
Rajeev Kumar45e64a72013-11-18 19:48:15 -08001457 &nMscan, &lastArg);
1458
1459 if (0 == nMscan)
1460 {
1461 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1462 "invalid MSCAN=%d", nMscan);
1463 return -EINVAL;
1464 }
1465
Rajeev79dbe4c2013-10-05 11:03:42 +05301466 if (TRUE == lastArg)
1467 {
1468 goto done;
1469 }
1470 else if (NULL == inPtr)
1471 {
1472 return -EINVAL;
1473 }
1474 }
1475 else
1476 {
1477 return -EINVAL;
1478 }
1479
1480 /*check and parse BESTN*/
1481 if ((strncmp(inPtr, "BESTN", 5) == 0))
1482 {
1483 inPtr = hdd_extract_assigned_int_from_str(inPtr, 10,
Rajeev Kumarc933d982013-11-18 20:04:20 -08001484 &temp, &lastArg);
Rajeev Kumar45e64a72013-11-18 19:48:15 -08001485
Rajeev Kumarc933d982013-11-18 20:04:20 -08001486 if (0 != temp)
Rajeev Kumar45e64a72013-11-18 19:48:15 -08001487 {
Rajeev Kumarc933d982013-11-18 20:04:20 -08001488 nBestN = temp;
Rajeev Kumar45e64a72013-11-18 19:48:15 -08001489 }
1490
Rajeev79dbe4c2013-10-05 11:03:42 +05301491 if (TRUE == lastArg)
1492 {
1493 goto done;
1494 }
1495 else if (NULL == inPtr)
1496 {
1497 return -EINVAL;
1498 }
1499 }
1500
1501 /*check and parse CHANNEL*/
1502 if ((strncmp(inPtr, "CHANNEL", 7) == 0))
1503 {
1504 inPtr = hdd_extract_assigned_char_from_str(inPtr, &val, &lastArg);
Rajeev Kumarc933d982013-11-18 20:04:20 -08001505
Rajeev79dbe4c2013-10-05 11:03:42 +05301506 if (('A' == val) || ('a' == val))
1507 {
c_hpothuebf89732014-02-25 13:00:24 +05301508 ucRfBand = HDD_SET_BATCH_SCAN_5GHz_BAND_ONLY;
Rajeev79dbe4c2013-10-05 11:03:42 +05301509 }
1510 else if (('B' == val) || ('b' == val))
1511 {
c_hpothuebf89732014-02-25 13:00:24 +05301512 ucRfBand = HDD_SET_BATCH_SCAN_24GHz_BAND_ONLY;
Rajeev79dbe4c2013-10-05 11:03:42 +05301513 }
1514 else
1515 {
Rajeev Kumarc933d982013-11-18 20:04:20 -08001516 ucRfBand = HDD_SET_BATCH_SCAN_DEFAULT_BAND;
1517 }
1518
1519 if (TRUE == lastArg)
1520 {
1521 goto done;
1522 }
1523 else if (NULL == inPtr)
1524 {
Rajeev79dbe4c2013-10-05 11:03:42 +05301525 return -EINVAL;
1526 }
1527 }
1528
1529 /*check and parse RTT*/
1530 if ((strncmp(inPtr, "RTT", 3) == 0))
1531 {
1532 inPtr = hdd_extract_assigned_int_from_str(inPtr, 10,
Rajeev Kumar45e64a72013-11-18 19:48:15 -08001533 &nRtt, &lastArg);
Rajeev79dbe4c2013-10-05 11:03:42 +05301534 if (TRUE == lastArg)
1535 {
1536 goto done;
1537 }
1538 if (NULL == inPtr)
1539 {
1540 return -EINVAL;
1541 }
1542 }
1543
1544
1545done:
1546
Rajeev Kumar45e64a72013-11-18 19:48:15 -08001547 pHddSetBatchScanReq->scanFrequency = nScanFreq;
1548 pHddSetBatchScanReq->numberOfScansToBatch = nMscan;
1549 pHddSetBatchScanReq->bestNetwork = nBestN;
1550 pHddSetBatchScanReq->rfBand = ucRfBand;
1551 pHddSetBatchScanReq->rtt = nRtt;
1552
Rajeev79dbe4c2013-10-05 11:03:42 +05301553 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1554 "Received WLS_BATCHING_SET with SCANFREQ=%d "
1555 "MSCAN=%d BESTN=%d CHANNEL=%d RTT=%d",
1556 pHddSetBatchScanReq->scanFrequency,
1557 pHddSetBatchScanReq->numberOfScansToBatch,
1558 pHddSetBatchScanReq->bestNetwork,
1559 pHddSetBatchScanReq->rfBand,
1560 pHddSetBatchScanReq->rtt);
1561
1562 return 0;
1563}/*End of hdd_parse_set_batchscan_command*/
1564
1565/**---------------------------------------------------------------------------
1566
1567 \brief hdd_set_batch_scan_req_callback () - This function is called after
1568 receiving set batch scan response from FW and it saves set batch scan
1569 response data FW to HDD context and sets the completion event on
1570 which hdd_ioctl is waiting
1571
1572 \param - callbackContext Pointer to HDD adapter
1573 \param - pRsp Pointer to set batch scan response data received from FW
1574
1575 \return - nothing
1576
1577 --------------------------------------------------------------------------*/
1578static void hdd_set_batch_scan_req_callback
1579(
1580 void *callbackContext,
1581 tSirSetBatchScanRsp *pRsp
1582)
1583{
1584 hdd_adapter_t* pAdapter = (hdd_adapter_t*)callbackContext;
1585 tSirSetBatchScanRsp *pHddSetBatchScanRsp;
1586
1587 /*sanity check*/
1588 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
1589 {
1590 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1591 "%s: Invalid pAdapter magic", __func__);
1592 VOS_ASSERT(0);
1593 return;
1594 }
1595 pHddSetBatchScanRsp = &pAdapter->hddSetBatchScanRsp;
1596
1597 /*save set batch scan response*/
1598 pHddSetBatchScanRsp->nScansToBatch = pRsp->nScansToBatch;
1599
1600 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
1601 "Received set batch scan rsp from FW with nScansToBatch=%d",
1602 pHddSetBatchScanRsp->nScansToBatch);
1603
1604 pAdapter->hdd_wait_for_set_batch_scan_rsp = FALSE;
1605 complete(&pAdapter->hdd_set_batch_scan_req_var);
1606
1607 return;
1608}/*End of hdd_set_batch_scan_req_callback*/
1609
1610
1611/**---------------------------------------------------------------------------
1612
1613 \brief hdd_populate_batch_scan_rsp_queue () - This function stores AP meta
1614 info in hdd batch scan response queue
1615
1616 \param - pAdapter Pointer to hdd adapter
1617 \param - pAPMetaInfo Pointer to access point meta info
1618 \param - scanId scan ID of batch scan response
1619 \param - isLastAp tells whether AP is last AP in batch scan response or not
1620
1621 \return - nothing
1622
1623 --------------------------------------------------------------------------*/
1624static void hdd_populate_batch_scan_rsp_queue( hdd_adapter_t* pAdapter,
1625 tpSirBatchScanNetworkInfo pApMetaInfo, tANI_U32 scanId, v_BOOL_t isLastAp)
1626{
1627 tHddBatchScanRsp *pHead;
1628 tHddBatchScanRsp *pNode;
1629 tHddBatchScanRsp *pPrev;
1630 tHddBatchScanRsp *pTemp;
1631 tANI_U8 ssidLen;
1632
1633 /*head of hdd batch scan response queue*/
1634 pHead = pAdapter->pBatchScanRsp;
1635
1636 pNode = (tHddBatchScanRsp *)vos_mem_malloc(sizeof(tHddBatchScanRsp));
1637 if (NULL == pNode)
1638 {
1639 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1640 "%s: Could not allocate memory", __func__);
1641 VOS_ASSERT(0);
1642 return;
1643 }
1644
1645 vos_mem_copy(pNode->ApInfo.bssid, pApMetaInfo->bssid,
1646 sizeof(pNode->ApInfo.bssid));
1647 ssidLen = strlen(pApMetaInfo->ssid);
1648 if (SIR_MAX_SSID_SIZE < ssidLen)
1649 {
1650 /*invalid scan result*/
1651 vos_mem_free(pNode);
1652 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1653 "%s: Invalid AP meta info ssidlen %d", __func__, ssidLen);
1654 return;
1655 }
1656 vos_mem_copy(pNode->ApInfo.ssid, pApMetaInfo->ssid, ssidLen);
1657 /*null terminate ssid*/
1658 pNode->ApInfo.ssid[ssidLen] = '\0';
1659 pNode->ApInfo.ch = pApMetaInfo->ch;
1660 pNode->ApInfo.rssi = pApMetaInfo->rssi;
1661 pNode->ApInfo.age = pApMetaInfo->timestamp;
1662 pNode->ApInfo.batchId = scanId;
1663 pNode->ApInfo.isLastAp = isLastAp;
1664
1665 pNode->pNext = NULL;
1666 if (NULL == pHead)
1667 {
1668 pAdapter->pBatchScanRsp = pNode;
1669 }
1670 else
1671 {
1672 pTemp = pHead;
1673 while (NULL != pTemp)
1674 {
1675 pPrev = pTemp;
1676 pTemp = pTemp->pNext;
1677 }
1678 pPrev->pNext = pNode;
1679 }
1680
1681 return;
1682}/*End of hdd_populate_batch_scan_rsp_queue*/
1683
1684/**---------------------------------------------------------------------------
1685
1686 \brief hdd_batch_scan_result_ind_callback () - This function is called after
1687 receiving batch scan response indication from FW. It saves get batch scan
1688 response data in HDD batch scan response queue. This callback sets the
1689 completion event on which hdd_ioctl is waiting only after getting complete
1690 batch scan response data from FW
1691
1692 \param - callbackContext Pointer to HDD adapter
1693 \param - pRsp Pointer to get batch scan response data received from FW
1694
1695 \return - nothing
1696
1697 --------------------------------------------------------------------------*/
1698static void hdd_batch_scan_result_ind_callback
1699(
1700 void *callbackContext,
1701 void *pRsp
1702)
1703{
1704 v_BOOL_t isLastAp;
1705 tANI_U32 numApMetaInfo;
Rajeev Kumarce651e42013-10-21 18:57:15 -07001706 tANI_U32 numNetworkInScanList;
Rajeev79dbe4c2013-10-05 11:03:42 +05301707 tANI_U32 numberScanList;
1708 tANI_U32 nextScanListOffset;
1709 tANI_U32 nextApMetaInfoOffset;
1710 hdd_adapter_t* pAdapter;
1711 tpSirBatchScanList pScanList;
1712 tpSirBatchScanNetworkInfo pApMetaInfo;
1713 tpSirBatchScanResultIndParam pBatchScanRsp;/*batch scan rsp data from FW*/
1714 tSirSetBatchScanReq *pReq;
1715
1716 pAdapter = (hdd_adapter_t *)callbackContext;
1717 /*sanity check*/
Rajeev Kumar5286bb92013-12-05 11:52:10 -08001718 if ((NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic))
Rajeev79dbe4c2013-10-05 11:03:42 +05301719 {
1720 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1721 "%s: Invalid pAdapter magic", __func__);
1722 VOS_ASSERT(0);
1723 return;
1724 }
1725
1726 /*initialize locals*/
1727 pReq = &pAdapter->hddSetBatchScanReq;
1728 pBatchScanRsp = (tpSirBatchScanResultIndParam)pRsp;
1729 isLastAp = FALSE;
1730 numApMetaInfo = 0;
Rajeev Kumarce651e42013-10-21 18:57:15 -07001731 numNetworkInScanList = 0;
Rajeev79dbe4c2013-10-05 11:03:42 +05301732 numberScanList = 0;
1733 nextScanListOffset = 0;
1734 nextApMetaInfoOffset = 0;
1735 pScanList = NULL;
1736 pApMetaInfo = NULL;
1737
1738 if ((NULL == pBatchScanRsp) || (NULL == pReq))
1739 {
1740 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1741 "%s: pBatchScanRsp is %p pReq %p", __func__, pBatchScanRsp, pReq);
1742 isLastAp = TRUE;
1743 goto done;
1744 }
1745
1746 pAdapter->numScanList = numberScanList = pBatchScanRsp->numScanLists;
1747 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1748 "Batch scan rsp: numberScalList %d", numberScanList);
1749
1750 if ((!numberScanList) || (numberScanList > pReq->numberOfScansToBatch))
1751 {
1752 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1753 "%s: numberScanList %d", __func__, numberScanList);
1754 isLastAp = TRUE;
1755 goto done;
1756 }
1757
1758 while (numberScanList)
1759 {
Rajeev Kumarce651e42013-10-21 18:57:15 -07001760 pScanList = (tpSirBatchScanList)((tANI_U8 *)pBatchScanRsp->scanResults +
Rajeev79dbe4c2013-10-05 11:03:42 +05301761 nextScanListOffset);
1762 if (NULL == pScanList)
1763 {
1764 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1765 "%s: pScanList is %p", __func__, pScanList);
1766 isLastAp = TRUE;
1767 goto done;
1768 }
Rajeev Kumarce651e42013-10-21 18:57:15 -07001769 numNetworkInScanList = numApMetaInfo = pScanList->numNetworksInScanList;
Rajeev79dbe4c2013-10-05 11:03:42 +05301770 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Rajeev Kumarce651e42013-10-21 18:57:15 -07001771 "Batch scan rsp: numApMetaInfo %d scanId %d",
1772 numApMetaInfo, pScanList->scanId);
Rajeev79dbe4c2013-10-05 11:03:42 +05301773
1774 if ((!numApMetaInfo) || (numApMetaInfo > pReq->bestNetwork))
1775 {
1776 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1777 "%s: numApMetaInfo %d", __func__, numApMetaInfo);
1778 isLastAp = TRUE;
1779 goto done;
1780 }
1781
Rajeev Kumarce651e42013-10-21 18:57:15 -07001782 /*Initialize next AP meta info offset for next scan list*/
1783 nextApMetaInfoOffset = 0;
1784
Rajeev79dbe4c2013-10-05 11:03:42 +05301785 while (numApMetaInfo)
1786 {
1787 pApMetaInfo = (tpSirBatchScanNetworkInfo)(pScanList->scanList +
1788 nextApMetaInfoOffset);
1789 if (NULL == pApMetaInfo)
1790 {
1791 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1792 "%s: pApMetaInfo is %p", __func__, pApMetaInfo);
1793 isLastAp = TRUE;
1794 goto done;
1795 }
1796 /*calculate AP age*/
1797 pApMetaInfo->timestamp =
1798 pBatchScanRsp->timestamp - pApMetaInfo->timestamp;
1799
1800 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
Arif Hussaina7c8e412013-11-20 11:06:42 -08001801 "%s: bssId "MAC_ADDRESS_STR
1802 " ch %d rssi %d timestamp %d", __func__,
1803 MAC_ADDR_ARRAY(pApMetaInfo->bssid),
1804 pApMetaInfo->ch, pApMetaInfo->rssi,
1805 pApMetaInfo->timestamp);
Rajeev79dbe4c2013-10-05 11:03:42 +05301806
1807 /*mark last AP in batch scan response*/
1808 if ((TRUE == pBatchScanRsp->isLastResult) &&
1809 (1 == numberScanList) && (1 == numApMetaInfo))
1810 {
1811 isLastAp = TRUE;
1812 }
1813
1814 mutex_lock(&pAdapter->hdd_batch_scan_lock);
1815 /*store batch scan repsonse in hdd queue*/
1816 hdd_populate_batch_scan_rsp_queue(pAdapter, pApMetaInfo,
1817 pScanList->scanId, isLastAp);
1818 mutex_unlock(&pAdapter->hdd_batch_scan_lock);
1819
1820 nextApMetaInfoOffset += sizeof(tSirBatchScanNetworkInfo);
1821 numApMetaInfo--;
1822 }
1823
Rajeev Kumarce651e42013-10-21 18:57:15 -07001824 nextScanListOffset += ((sizeof(tSirBatchScanList) - sizeof(tANI_U8))
1825 + (sizeof(tSirBatchScanNetworkInfo)
1826 * numNetworkInScanList));
Rajeev79dbe4c2013-10-05 11:03:42 +05301827 numberScanList--;
1828 }
1829
1830done:
1831
1832 /*notify hdd_ioctl only if complete batch scan rsp is received and it was
1833 requested from hdd_ioctl*/
1834 if ((TRUE == pAdapter->hdd_wait_for_get_batch_scan_rsp) &&
1835 (TRUE == isLastAp))
1836 {
1837 pAdapter->hdd_wait_for_get_batch_scan_rsp = FALSE;
1838 complete(&pAdapter->hdd_get_batch_scan_req_var);
1839 }
1840
1841 return;
1842}/*End of hdd_batch_scan_result_ind_callback*/
1843
1844/**---------------------------------------------------------------------------
1845
1846 \brief hdd_format_batch_scan_rsp () - This function formats batch scan
1847 response as per batch scan FR request format by putting proper markers
1848
1849 \param - pDest pointer to destination buffer
1850 \param - cur_len current length
1851 \param - tot_len total remaining size which can be written to user space
1852 \param - pApMetaInfo Pointer to get batch scan response AP meta info
1853 \param - pAdapter Pointer to HDD adapter
1854
1855 \return - ret no of characters written
1856
1857 --------------------------------------------------------------------------*/
1858static tANI_U32
1859hdd_format_batch_scan_rsp
1860(
1861 tANI_U8 *pDest,
1862 tANI_U32 cur_len,
1863 tANI_U32 tot_len,
1864 tHddBatchScanRsp *pApMetaInfo,
1865 hdd_adapter_t* pAdapter
1866)
1867{
1868 tANI_U32 ret = 0;
1869 tANI_U32 rem_len = 0;
1870 tANI_U8 temp_len = 0;
1871 tANI_U8 temp_total_len = 0;
1872 tANI_U8 temp[HDD_BATCH_SCAN_AP_META_INFO_SIZE];
1873 tANI_U8 *pTemp = temp;
1874
1875 /*Batch scan reponse needs to be returned to user space in
1876 following format:
1877 "scancount=X\n" where X is the number of scans in current batch
1878 batch
1879 "trunc\n" optional present if current scan truncated
1880 "bssid=XX:XX:XX:XX:XX:XX\n"
1881 "ssid=XXXX\n"
1882 "freq=X\n" frequency in Mhz
1883 "level=XX\n"
1884 "age=X\n" ms
1885 "dist=X\n" cm (-1 if not available)
1886 "errror=X\n" (-1if not available)
1887 "====\n" (end of ap marker)
1888 "####\n" (end of scan marker)
1889 "----\n" (end of results)*/
1890 /*send scan result in above format to user space based on
1891 available length*/
1892 /*The GET response may have more data than the driver can return in its
1893 buffer. In that case the buffer should be filled to the nearest complete
1894 scan, ending with "%%%%".Subsequent callsshould return the remaining data
1895 starting with the next scan (optional .trunc\n., .apcount=X\n., etc).
1896 The final buffer should end with "----\n"*/
1897
1898 /*sanity*/
1899 if (cur_len > tot_len)
1900 {
1901 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1902 "%s: invaid cur_len %d tot_len %d", __func__, cur_len, tot_len);
1903 return 0;
1904 }
1905 else
1906 {
1907 rem_len = (tot_len - cur_len);
1908 }
1909
1910 /*end scan marker*/
1911 if (pApMetaInfo->ApInfo.batchId != pAdapter->prev_batch_id)
1912 {
1913 temp_len = snprintf(pTemp, sizeof(temp), "####\n");
1914 pTemp += temp_len;
1915 temp_total_len += temp_len;
1916 }
1917
1918 /*bssid*/
1919 temp_len = snprintf(pTemp, sizeof(temp),
1920 "bssid=0x%x:0x%x:0x%x:0x%x:0x%x:0x%x\n",
1921 pApMetaInfo->ApInfo.bssid[0], pApMetaInfo->ApInfo.bssid[1],
1922 pApMetaInfo->ApInfo.bssid[2], pApMetaInfo->ApInfo.bssid[3],
1923 pApMetaInfo->ApInfo.bssid[4], pApMetaInfo->ApInfo.bssid[5]);
1924 pTemp += temp_len;
1925 temp_total_len += temp_len;
1926
1927 /*ssid*/
1928 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "ssid=%s\n",
1929 pApMetaInfo->ApInfo.ssid);
1930 pTemp += temp_len;
1931 temp_total_len += temp_len;
1932
1933 /*freq*/
1934 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "freq=%d\n",
Rajeev Kumarc40f7512013-11-04 14:13:23 -08001935 sme_ChnToFreq(pApMetaInfo->ApInfo.ch));
Rajeev79dbe4c2013-10-05 11:03:42 +05301936 pTemp += temp_len;
1937 temp_total_len += temp_len;
1938
1939 /*level*/
1940 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "level=%d\n",
1941 pApMetaInfo->ApInfo.rssi);
1942 pTemp += temp_len;
1943 temp_total_len += temp_len;
1944
1945 /*age*/
Jeff Johnson02797792013-10-26 19:17:13 -07001946 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "age=%d\n",
Rajeev79dbe4c2013-10-05 11:03:42 +05301947 pApMetaInfo->ApInfo.age);
1948 pTemp += temp_len;
1949 temp_total_len += temp_len;
1950
1951 /*dist*/
1952 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "dist=-1\n");
1953 pTemp += temp_len;
1954 temp_total_len += temp_len;
1955
1956 /*error*/
1957 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "error=-1\n");
1958 pTemp += temp_len;
1959 temp_total_len += temp_len;
1960
1961 /*end AP marker*/
1962 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "====\n");
1963 pTemp += temp_len;
1964 temp_total_len += temp_len;
1965
1966 /*last AP in batch scan response*/
1967 if(TRUE == pApMetaInfo->ApInfo.isLastAp)
1968 {
1969 /*end scan marker*/
1970 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "####\n");
1971 pTemp += temp_len;
1972 temp_total_len += temp_len;
1973
1974 /*end batch scan result marker*/
1975 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "----\n");
1976 pTemp += temp_len;
1977 temp_total_len += temp_len;
Kiet Lamaa8e15a2014-02-11 23:30:06 -08001978
Rajeev79dbe4c2013-10-05 11:03:42 +05301979 }
1980
1981 if (temp_total_len < rem_len)
1982 {
1983 ret = temp_total_len + 1;
1984 strlcpy(pDest, temp, ret);
1985 pAdapter->isTruncated = FALSE;
1986 }
1987 else
1988 {
1989 pAdapter->isTruncated = TRUE;
1990 if (rem_len >= strlen("%%%%"))
1991 {
Rajeev Kumarc933d982013-11-18 20:04:20 -08001992 ret = snprintf(pDest, sizeof(temp), "%%%%");
Rajeev79dbe4c2013-10-05 11:03:42 +05301993 }
Rajeev Kumarc933d982013-11-18 20:04:20 -08001994 else
Rajeev79dbe4c2013-10-05 11:03:42 +05301995 {
1996 ret = 0;
1997 }
1998 }
1999
2000 return ret;
2001
2002}/*End of hdd_format_batch_scan_rsp*/
2003
2004/**---------------------------------------------------------------------------
2005
2006 \brief hdd_populate_user_batch_scan_rsp() - This function populates user data
2007 buffer starting with head of hdd batch scan response queue
2008
2009 \param - pAdapter Pointer to HDD adapter
2010 \param - pDest Pointer to user data buffer
2011 \param - cur_len current offset in user buffer
2012 \param - rem_len remaining no of bytes in user buffer
2013
2014 \return - number of bytes written in user buffer
2015
2016 --------------------------------------------------------------------------*/
2017
2018tANI_U32 hdd_populate_user_batch_scan_rsp
2019(
2020 hdd_adapter_t* pAdapter,
2021 tANI_U8 *pDest,
2022 tANI_U32 cur_len,
2023 tANI_U32 rem_len
2024)
2025{
2026 tHddBatchScanRsp *pHead;
2027 tHddBatchScanRsp *pPrev;
2028 tANI_U32 len;
2029
Rajeev79dbe4c2013-10-05 11:03:42 +05302030 pAdapter->isTruncated = FALSE;
2031
2032 /*head of hdd batch scan response queue*/
2033 pHead = pAdapter->pBatchScanRsp;
2034 while (pHead)
2035 {
2036 len = hdd_format_batch_scan_rsp(pDest, cur_len, rem_len, pHead,
2037 pAdapter);
2038 pDest += len;
Rajeev Kumar292d2bb2013-10-23 15:01:44 -07002039 pDest--;
Rajeev79dbe4c2013-10-05 11:03:42 +05302040 cur_len += len;
2041 if(TRUE == pAdapter->isTruncated)
2042 {
2043 /*result is truncated return rest of scan rsp in next req*/
2044 cur_len = rem_len;
2045 break;
2046 }
2047 pPrev = pHead;
2048 pHead = pHead->pNext;
2049 pAdapter->pBatchScanRsp = pHead;
Rajeev Kumarbe17d8b2014-01-10 15:39:45 -08002050 if (TRUE == pPrev->ApInfo.isLastAp)
2051 {
2052 pAdapter->prev_batch_id = 0;
2053 }
2054 else
2055 {
2056 pAdapter->prev_batch_id = pPrev->ApInfo.batchId;
2057 }
Rajeev79dbe4c2013-10-05 11:03:42 +05302058 vos_mem_free(pPrev);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08002059 pPrev = NULL;
Rajeev79dbe4c2013-10-05 11:03:42 +05302060 }
2061
2062 return cur_len;
2063}/*End of hdd_populate_user_batch_scan_rsp*/
2064
2065/**---------------------------------------------------------------------------
2066
2067 \brief hdd_return_batch_scan_rsp_to_user () - This function returns batch
2068 scan response data from HDD queue to user space
2069 It does following in detail:
2070 a) if HDD has enough data in its queue then it 1st copies data to user
2071 space and then send get batch scan indication message to FW. In this
2072 case it does not wait on any event and batch scan response data will
2073 be populated in HDD response queue in MC thread context after receiving
2074 indication from FW
2075 b) else send get batch scan indication message to FW and wait on an event
2076 which will be set once HDD receives complete batch scan response from
2077 FW and then this function returns batch scan response to user space
2078
2079 \param - pAdapter Pointer to HDD adapter
2080 \param - pPrivData Pointer to priv_data
2081
2082 \return - 0 for success -EFAULT for failure
2083
2084 --------------------------------------------------------------------------*/
2085
2086int hdd_return_batch_scan_rsp_to_user
2087(
2088 hdd_adapter_t* pAdapter,
2089 hdd_priv_data_t *pPrivData,
2090 tANI_U8 *command
2091)
2092{
2093 tANI_U8 *pDest;
2094 tANI_U32 count = 0;
2095 tANI_U32 len = 0;
2096 tANI_U32 cur_len = 0;
2097 tANI_U32 rem_len = 0;
2098 eHalStatus halStatus;
2099 unsigned long rc;
2100 tSirTriggerBatchScanResultInd *pReq;
2101
2102 pReq = &pAdapter->hddTriggerBatchScanResultInd;
2103 pReq->param = 0;/*batch scan client*/
2104 pDest = (tANI_U8 *)(command + pPrivData->used_len);
2105 pAdapter->hdd_wait_for_get_batch_scan_rsp = FALSE;
2106
2107 cur_len = pPrivData->used_len;
2108 if (pPrivData->total_len > pPrivData->used_len)
2109 {
2110 rem_len = pPrivData->total_len - pPrivData->used_len;
2111 }
2112 else
2113 {
2114 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2115 "%s: Invalid user data buffer total_len %d used_len %d",
2116 __func__, pPrivData->total_len, pPrivData->used_len);
2117 return -EFAULT;
2118 }
2119
2120 mutex_lock(&pAdapter->hdd_batch_scan_lock);
2121 len = hdd_populate_user_batch_scan_rsp(pAdapter, pDest,
2122 cur_len, rem_len);
2123 mutex_unlock(&pAdapter->hdd_batch_scan_lock);
2124
2125 /*enough scan result available in cache to return to user space or
2126 scan result needs to be fetched 1st from fw and then return*/
Rajeev Kumar99db6262013-11-11 15:23:36 -08002127 if (len == cur_len)
Rajeev79dbe4c2013-10-05 11:03:42 +05302128 {
2129 pAdapter->hdd_wait_for_get_batch_scan_rsp = TRUE;
2130 halStatus = sme_TriggerBatchScanResultInd(
2131 WLAN_HDD_GET_HAL_CTX(pAdapter), pReq,
2132 pAdapter->sessionId, hdd_batch_scan_result_ind_callback,
2133 pAdapter);
2134 if ( eHAL_STATUS_SUCCESS == halStatus )
2135 {
2136 if (TRUE == pAdapter->hdd_wait_for_get_batch_scan_rsp)
2137 {
2138 INIT_COMPLETION(pAdapter->hdd_get_batch_scan_req_var);
2139 rc = wait_for_completion_timeout(
2140 &pAdapter->hdd_get_batch_scan_req_var,
2141 msecs_to_jiffies(HDD_GET_BATCH_SCAN_RSP_TIME_OUT));
Abhishek Singh00b71972016-01-07 10:51:04 +05302142 if (0 >= rc)
Rajeev79dbe4c2013-10-05 11:03:42 +05302143 {
2144 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Abhishek Singh00b71972016-01-07 10:51:04 +05302145 "%s: wait on hdd_get_batch_scan_req_var failed %ld",
2146 __func__, rc);
Rajeev79dbe4c2013-10-05 11:03:42 +05302147 return -EFAULT;
2148 }
2149 }
2150
2151 len = snprintf(pDest, HDD_BATCH_SCAN_AP_META_INFO_SIZE,
Jeff Johnson02797792013-10-26 19:17:13 -07002152 "scancount=%u\n", pAdapter->numScanList);
Rajeev79dbe4c2013-10-05 11:03:42 +05302153 pDest += len;
2154 cur_len += len;
2155
2156 mutex_lock(&pAdapter->hdd_batch_scan_lock);
2157 len = hdd_populate_user_batch_scan_rsp(pAdapter, pDest,
2158 cur_len, rem_len);
2159 mutex_unlock(&pAdapter->hdd_batch_scan_lock);
2160
2161 count = 0;
2162 len = (len - pPrivData->used_len);
2163 pDest = (command + pPrivData->used_len);
2164 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Rajeev Kumar99db6262013-11-11 15:23:36 -08002165 "NEW BATCH SCAN RESULT:");
Rajeev79dbe4c2013-10-05 11:03:42 +05302166 while(count < len)
2167 {
2168 printk("%c", *(pDest + count));
2169 count++;
2170 }
2171 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2172 "%s: copy %d data to user buffer", __func__, len);
2173 if (copy_to_user(pPrivData->buf, pDest, len))
2174 {
2175 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2176 "%s: failed to copy data to user buffer", __func__);
2177 return -EFAULT;
2178 }
2179 }
2180 else
2181 {
2182 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2183 "sme_GetBatchScanScan returned failure halStatus %d",
2184 halStatus);
2185 return -EINVAL;
2186 }
2187 }
2188 else
2189 {
Rajeev79dbe4c2013-10-05 11:03:42 +05302190 count = 0;
2191 len = (len - pPrivData->used_len);
2192 pDest = (command + pPrivData->used_len);
2193 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Rajeev Kumar99db6262013-11-11 15:23:36 -08002194 "REMAINING TRUNCATED BATCH SCAN RESULT:");
Rajeev79dbe4c2013-10-05 11:03:42 +05302195 while(count < len)
2196 {
2197 printk("%c", *(pDest + count));
2198 count++;
2199 }
Rajeev Kumar99db6262013-11-11 15:23:36 -08002200 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2201 "%s: copy %d data to user buffer", __func__, len);
Rajeev79dbe4c2013-10-05 11:03:42 +05302202 if (copy_to_user(pPrivData->buf, pDest, len))
2203 {
2204 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2205 "%s: failed to copy data to user buffer", __func__);
2206 return -EFAULT;
2207 }
Rajeev79dbe4c2013-10-05 11:03:42 +05302208 }
2209
2210 return 0;
2211} /*End of hdd_return_batch_scan_rsp_to_user*/
2212
Rajeev Kumar8b373292014-01-08 20:36:55 -08002213/**---------------------------------------------------------------------------
2214
2215 \brief hdd_handle_batch_scan_ioctl () - This function handles WLS_BATCHING
2216 IOCTLs from user space. Following BATCH SCAN DEV IOCTs are handled:
2217 WLS_BATCHING VERSION
2218 WLS_BATCHING SET
2219 WLS_BATCHING GET
2220 WLS_BATCHING STOP
2221
2222 \param - pAdapter Pointer to HDD adapter
2223 \param - pPrivdata Pointer to priv_data
2224 \param - command Pointer to command
2225
2226 \return - 0 for success -EFAULT for failure
2227
2228 --------------------------------------------------------------------------*/
2229
2230int hdd_handle_batch_scan_ioctl
2231(
2232 hdd_adapter_t *pAdapter,
2233 hdd_priv_data_t *pPrivdata,
2234 tANI_U8 *command
2235)
2236{
2237 int ret = 0;
Yue Mae36e3552014-03-05 17:06:20 -08002238 hdd_context_t *pHddCtx;
2239
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302240 ENTER();
2241
Yue Mae36e3552014-03-05 17:06:20 -08002242 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
2243 ret = wlan_hdd_validate_context(pHddCtx);
2244 if (ret)
2245 {
Yue Mae36e3552014-03-05 17:06:20 -08002246 goto exit;
2247 }
Rajeev Kumar8b373292014-01-08 20:36:55 -08002248
2249 if (strncmp(command, "WLS_BATCHING VERSION", 20) == 0)
2250 {
2251 char extra[32];
2252 tANI_U8 len = 0;
2253 tANI_U8 version = HDD_BATCH_SCAN_VERSION;
2254
2255 if (FALSE == sme_IsFeatureSupportedByFW(BATCH_SCAN))
2256 {
2257 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2258 "%s: Batch scan feature is not supported by FW", __func__);
2259 ret = -EINVAL;
2260 goto exit;
2261 }
2262
2263 len = scnprintf(extra, sizeof(extra), "WLS_BATCHING_VERSION %d",
2264 version);
2265 if (copy_to_user(pPrivdata->buf, &extra, len + 1))
2266 {
2267 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2268 "%s: failed to copy data to user buffer", __func__);
2269 ret = -EFAULT;
2270 goto exit;
2271 }
2272 ret = HDD_BATCH_SCAN_VERSION;
2273 }
2274 else if (strncmp(command, "WLS_BATCHING SET", 16) == 0)
2275 {
2276 int status;
2277 tANI_U8 *value = (command + 16);
2278 eHalStatus halStatus;
2279 unsigned long rc;
2280 tSirSetBatchScanReq *pReq = &pAdapter->hddSetBatchScanReq;
2281 tSirSetBatchScanRsp *pRsp = &pAdapter->hddSetBatchScanRsp;
2282
2283 if (FALSE == sme_IsFeatureSupportedByFW(BATCH_SCAN))
2284 {
2285 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2286 "%s: Batch scan feature is not supported by FW", __func__);
2287 ret = -EINVAL;
2288 goto exit;
2289 }
2290
2291 if ((WLAN_HDD_INFRA_STATION != pAdapter->device_mode) &&
2292 (WLAN_HDD_P2P_CLIENT != pAdapter->device_mode) &&
2293 (WLAN_HDD_P2P_GO != pAdapter->device_mode) &&
2294 (WLAN_HDD_P2P_DEVICE != pAdapter->device_mode))
2295 {
2296 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05302297 "Received WLS_BATCHING SET command in invalid mode %s (%d) "
Rajeev Kumar8b373292014-01-08 20:36:55 -08002298 "WLS_BATCHING_SET is only allowed in infra STA/P2P client mode",
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05302299 hdd_device_modetoString(pAdapter->device_mode),
2300 pAdapter->device_mode);
Rajeev Kumar8b373292014-01-08 20:36:55 -08002301 ret = -EINVAL;
2302 goto exit;
2303 }
2304
2305 status = hdd_parse_set_batchscan_command(value, pReq);
2306 if (status)
2307 {
2308 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2309 "Invalid WLS_BATCHING SET command");
2310 ret = -EINVAL;
2311 goto exit;
2312 }
2313
2314
2315 pAdapter->hdd_wait_for_set_batch_scan_rsp = TRUE;
2316 halStatus = sme_SetBatchScanReq(WLAN_HDD_GET_HAL_CTX(pAdapter), pReq,
2317 pAdapter->sessionId, hdd_set_batch_scan_req_callback,
2318 pAdapter);
2319
2320 if ( eHAL_STATUS_SUCCESS == halStatus )
2321 {
Mahesh A Saptasagar5f568172014-05-14 17:02:33 +05302322 char extra[32];
2323 tANI_U8 len = 0;
2324 tANI_U8 mScan = 0;
2325
Rajeev Kumar8b373292014-01-08 20:36:55 -08002326 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2327 "sme_SetBatchScanReq returned success halStatus %d",
2328 halStatus);
2329 if (TRUE == pAdapter->hdd_wait_for_set_batch_scan_rsp)
2330 {
2331 INIT_COMPLETION(pAdapter->hdd_set_batch_scan_req_var);
2332 rc = wait_for_completion_timeout(
2333 &pAdapter->hdd_set_batch_scan_req_var,
2334 msecs_to_jiffies(HDD_SET_BATCH_SCAN_REQ_TIME_OUT));
2335 if (0 == rc)
2336 {
2337 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2338 "%s: Timeout waiting for set batch scan to complete",
2339 __func__);
2340 ret = -EINVAL;
2341 goto exit;
2342 }
2343 }
2344 if ( !pRsp->nScansToBatch )
2345 {
2346 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2347 "%s: Received set batch scan failure response from FW",
2348 __func__);
2349 ret = -EINVAL;
2350 goto exit;
2351 }
2352 /*As per the Batch Scan Framework API we should return the MIN of
2353 either MSCAN or the max # of scans firmware can cache*/
Mahesh A Saptasagar5f568172014-05-14 17:02:33 +05302354 mScan = MIN(pReq->numberOfScansToBatch , pRsp->nScansToBatch);
Rajeev Kumar8b373292014-01-08 20:36:55 -08002355
2356 pAdapter->batchScanState = eHDD_BATCH_SCAN_STATE_STARTED;
2357
2358 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2359 "%s: request MSCAN %d response MSCAN %d ret %d",
Mahesh A Saptasagar5f568172014-05-14 17:02:33 +05302360 __func__, pReq->numberOfScansToBatch, pRsp->nScansToBatch, mScan);
2361 len = scnprintf(extra, sizeof(extra), "%d", mScan);
2362 if (copy_to_user(pPrivdata->buf, &extra, len + 1))
2363 {
2364 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2365 "%s: failed to copy MSCAN value to user buffer", __func__);
2366 ret = -EFAULT;
2367 goto exit;
2368 }
Rajeev Kumar8b373292014-01-08 20:36:55 -08002369 }
2370 else
2371 {
2372 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2373 "sme_SetBatchScanReq returned failure halStatus %d",
2374 halStatus);
2375 ret = -EINVAL;
2376 goto exit;
2377 }
2378 }
2379 else if (strncmp(command, "WLS_BATCHING STOP", 17) == 0)
2380 {
2381 eHalStatus halStatus;
2382 tSirStopBatchScanInd *pInd = &pAdapter->hddStopBatchScanInd;
2383 pInd->param = 0;
2384
2385 if (FALSE == sme_IsFeatureSupportedByFW(BATCH_SCAN))
2386 {
2387 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2388 "%s: Batch scan feature is not supported by FW", __func__);
2389 ret = -EINVAL;
2390 goto exit;
2391 }
2392
2393 if (eHDD_BATCH_SCAN_STATE_STARTED != pAdapter->batchScanState)
2394 {
Deepthi Gowribfd17132014-11-14 17:59:04 +05302395 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Rajeev Kumar8b373292014-01-08 20:36:55 -08002396 "Batch scan is not yet enabled batch scan state %d",
2397 pAdapter->batchScanState);
2398 ret = -EINVAL;
2399 goto exit;
2400 }
2401
Kiet Lamaa8e15a2014-02-11 23:30:06 -08002402 mutex_lock(&pAdapter->hdd_batch_scan_lock);
2403 hdd_deinit_batch_scan(pAdapter);
2404 mutex_unlock(&pAdapter->hdd_batch_scan_lock);
2405
Rajeev Kumar8b373292014-01-08 20:36:55 -08002406 pAdapter->batchScanState = eHDD_BATCH_SCAN_STATE_STOPPED;
2407
2408 halStatus = sme_StopBatchScanInd(WLAN_HDD_GET_HAL_CTX(pAdapter), pInd,
2409 pAdapter->sessionId);
2410 if ( eHAL_STATUS_SUCCESS == halStatus )
2411 {
2412 ret = 0;
2413 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2414 "sme_StopBatchScanInd returned success halStatus %d",
2415 halStatus);
2416 }
2417 else
2418 {
2419 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2420 "sme_StopBatchScanInd returned failure halStatus %d",
2421 halStatus);
2422 ret = -EINVAL;
2423 goto exit;
2424 }
2425 }
2426 else if (strncmp(command, "WLS_BATCHING GET", 16) == 0)
2427 {
2428 tANI_U32 remain_len;
2429
2430 if (FALSE == sme_IsFeatureSupportedByFW(BATCH_SCAN))
2431 {
2432 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2433 "%s: Batch scan feature is not supported by FW", __func__);
2434 ret = -EINVAL;
2435 goto exit;
2436 }
2437
2438 if (eHDD_BATCH_SCAN_STATE_STARTED != pAdapter->batchScanState)
2439 {
Deepthi Gowribfd17132014-11-14 17:59:04 +05302440 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Rajeev Kumar8b373292014-01-08 20:36:55 -08002441 "Batch scan is not yet enabled could not return results"
2442 "Batch Scan state %d",
2443 pAdapter->batchScanState);
2444 ret = -EINVAL;
2445 goto exit;
2446 }
2447
2448 pPrivdata->used_len = 16;
2449 remain_len = pPrivdata->total_len - pPrivdata->used_len;
2450 if (remain_len < pPrivdata->total_len)
2451 {
2452 /*Clear previous batch scan response data if any*/
2453 vos_mem_zero((tANI_U8 *)(command + pPrivdata->used_len), remain_len);
2454 }
2455 else
2456 {
2457 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2458 "Invalid total length from user space can't fetch batch"
2459 " scan response total_len %d used_len %d remain len %d",
2460 pPrivdata->total_len, pPrivdata->used_len, remain_len);
2461 ret = -EINVAL;
2462 goto exit;
2463 }
2464 ret = hdd_return_batch_scan_rsp_to_user(pAdapter, pPrivdata, command);
2465 }
2466
2467exit:
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302468 EXIT();
Rajeev Kumar8b373292014-01-08 20:36:55 -08002469 return ret;
2470}
2471
2472
Rajeev79dbe4c2013-10-05 11:03:42 +05302473#endif/*End of FEATURE_WLAN_BATCH_SCAN*/
2474
c_hpothu92367912014-05-01 15:18:17 +05302475static void getBcnMissRateCB(VOS_STATUS status, int bcnMissRate, void *data)
2476{
c_hpothu39eb1e32014-06-26 16:31:50 +05302477 bcnMissRateContext_t *pCBCtx;
2478
2479 if (NULL == data)
2480 {
2481 hddLog(VOS_TRACE_LEVEL_ERROR, FL("argument data is NULL"));
2482 return;
2483 }
c_hpothu92367912014-05-01 15:18:17 +05302484
2485 /* there is a race condition that exists between this callback
2486 function and the caller since the caller could time out either
2487 before or while this code is executing. we use a spinlock to
2488 serialize these actions */
2489 spin_lock(&hdd_context_lock);
2490
c_hpothu39eb1e32014-06-26 16:31:50 +05302491 pCBCtx = (bcnMissRateContext_t *)data;
c_hpothu92367912014-05-01 15:18:17 +05302492 gbcnMissRate = -1;
2493
c_hpothu39eb1e32014-06-26 16:31:50 +05302494 if (pCBCtx->magic != BCN_MISS_RATE_CONTEXT_MAGIC)
c_hpothu92367912014-05-01 15:18:17 +05302495 {
2496 hddLog(VOS_TRACE_LEVEL_ERROR,
c_hpothu39eb1e32014-06-26 16:31:50 +05302497 FL("invalid context magic: %08x"), pCBCtx->magic);
c_hpothu92367912014-05-01 15:18:17 +05302498 spin_unlock(&hdd_context_lock);
2499 return ;
2500 }
2501
2502 if (VOS_STATUS_SUCCESS == status)
2503 {
c_hpothu39eb1e32014-06-26 16:31:50 +05302504 gbcnMissRate = bcnMissRate;
c_hpothu92367912014-05-01 15:18:17 +05302505 }
c_hpothu39eb1e32014-06-26 16:31:50 +05302506 else
2507 {
2508 hddLog(VOS_TRACE_LEVEL_ERROR, FL("failed to get bcnMissRate"));
2509 }
2510
c_hpothu92367912014-05-01 15:18:17 +05302511 complete(&(pCBCtx->completion));
2512 spin_unlock(&hdd_context_lock);
2513
2514 return;
2515}
2516
Abhishek Singh08aa7762014-12-16 13:59:03 +05302517void hdd_FWStatisCB( VOS_STATUS status,
2518 tSirFwStatsResult *fwStatsResult, void *pContext )
Satyanarayana Dash72806012014-12-02 14:30:08 +05302519{
2520 fwStatsContext_t *fwStatsCtx;
Satyanarayana Dash72806012014-12-02 14:30:08 +05302521 hdd_adapter_t *pAdapter;
2522
2523 hddLog(VOS_TRACE_LEVEL_INFO, FL(" with status = %d"),status);
2524
Abhishek Singh08aa7762014-12-16 13:59:03 +05302525 if (NULL == pContext)
Satyanarayana Dash72806012014-12-02 14:30:08 +05302526 {
2527 hddLog(VOS_TRACE_LEVEL_ERROR, FL("argument data is NULL"));
2528 return;
2529 }
2530 /* there is a race condition that exists between this callback
2531 function and the caller since the caller could time out either
2532 before or while this code is executing. we use a spinlock to
2533 serialize these actions */
2534 spin_lock(&hdd_context_lock);
Abhishek Singh08aa7762014-12-16 13:59:03 +05302535 fwStatsCtx = (fwStatsContext_t *) pContext;
Satyanarayana Dash72806012014-12-02 14:30:08 +05302536 if (fwStatsCtx->magic != FW_STATS_CONTEXT_MAGIC)
2537 {
2538 hddLog(VOS_TRACE_LEVEL_ERROR,
2539 FL("invalid context magic: %08x"), fwStatsCtx->magic);
2540 spin_unlock(&hdd_context_lock);
2541 return;
2542 }
2543 pAdapter = fwStatsCtx->pAdapter;
2544 if ((NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic))
2545 {
2546 hddLog(VOS_TRACE_LEVEL_ERROR,
2547 FL("pAdapter returned is NULL or invalid"));
2548 spin_unlock(&hdd_context_lock);
2549 return;
2550 }
2551 pAdapter->fwStatsRsp.type = 0;
Abhishek Singh08aa7762014-12-16 13:59:03 +05302552 if ((VOS_STATUS_SUCCESS == status) && (NULL != fwStatsResult))
Satyanarayana Dash72806012014-12-02 14:30:08 +05302553 {
Satyanarayana Dash72806012014-12-02 14:30:08 +05302554 switch( fwStatsResult->type )
2555 {
2556 case FW_UBSP_STATS:
2557 {
Abhishek Singh08aa7762014-12-16 13:59:03 +05302558 memcpy(&pAdapter->fwStatsRsp,fwStatsResult,sizeof(tSirFwStatsResult));
Satyanarayana Dash72806012014-12-02 14:30:08 +05302559 hddLog(VOS_TRACE_LEVEL_INFO,
2560 FL("ubsp_enter_cnt = %d ubsp_jump_ddr_cnt = %d"),
Abhishek Singh08aa7762014-12-16 13:59:03 +05302561 pAdapter->fwStatsRsp.fwStatsData.ubspStats.ubsp_enter_cnt,
2562 pAdapter->fwStatsRsp.fwStatsData.ubspStats.ubsp_jump_ddr_cnt);
Satyanarayana Dash72806012014-12-02 14:30:08 +05302563 }
2564 break;
2565 default:
2566 {
2567 hddLog(VOS_TRACE_LEVEL_ERROR,
2568 FL(" No handling for stats type %d"),fwStatsResult->type);
2569 }
2570 }
2571 }
2572 complete(&(fwStatsCtx->completion));
2573 spin_unlock(&hdd_context_lock);
2574 return;
2575}
2576
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302577static int hdd_get_dwell_time(hdd_config_t *pCfg, tANI_U8 *command, char *extra, tANI_U8 n, tANI_U8 *len)
2578{
2579 int ret = 0;
2580
2581 if (!pCfg || !command || !extra || !len)
2582 {
2583 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2584 "%s: argument passsed for GETDWELLTIME is incorrect", __func__);
2585 ret = -EINVAL;
2586 return ret;
2587 }
2588
2589 if (strncmp(command, "GETDWELLTIME ACTIVE MAX", 23) == 0)
2590 {
2591 *len = scnprintf(extra, n, "GETDWELLTIME ACTIVE MAX %u\n",
2592 (int)pCfg->nActiveMaxChnTime);
2593 return ret;
2594 }
2595 else if (strncmp(command, "GETDWELLTIME ACTIVE MIN", 23) == 0)
2596 {
2597 *len = scnprintf(extra, n, "GETDWELLTIME ACTIVE MIN %u\n",
2598 (int)pCfg->nActiveMinChnTime);
2599 return ret;
2600 }
2601 else if (strncmp(command, "GETDWELLTIME PASSIVE MAX", 24) == 0)
2602 {
2603 *len = scnprintf(extra, n, "GETDWELLTIME PASSIVE MAX %u\n",
2604 (int)pCfg->nPassiveMaxChnTime);
2605 return ret;
2606 }
2607 else if (strncmp(command, "GETDWELLTIME PASSIVE MIN", 24) == 0)
2608 {
2609 *len = scnprintf(extra, n, "GETDWELLTIME PASSIVE MIN %u\n",
2610 (int)pCfg->nPassiveMinChnTime);
2611 return ret;
2612 }
Rajesh Babu Prathipati0fd227e2014-07-05 12:50:00 +05302613 else if (strncmp(command, "GETDWELLTIME", 12) == 0)
2614 {
2615 *len = scnprintf(extra, n, "GETDWELLTIME %u \n",
2616 (int)pCfg->nActiveMaxChnTime);
2617 return ret;
2618 }
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302619 else
2620 {
2621 ret = -EINVAL;
2622 }
2623
2624 return ret;
2625}
2626
2627static int hdd_set_dwell_time(hdd_adapter_t *pAdapter, tANI_U8 *command)
2628{
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05302629 tHalHandle hHal;
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302630 hdd_config_t *pCfg;
2631 tANI_U8 *value = command;
2632 int val = 0, ret = 0, temp = 0;
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05302633 tSmeConfigParams smeConfig;
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302634
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05302635 if (!pAdapter || !command || !(pCfg = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini)
2636 || !(hHal = (WLAN_HDD_GET_HAL_CTX(pAdapter))))
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302637 {
2638 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2639 "%s: argument passed for SETDWELLTIME is incorrect", __func__);
2640 ret = -EINVAL;
2641 return ret;
2642 }
2643
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05302644 vos_mem_zero(&smeConfig, sizeof(smeConfig));
2645 sme_GetConfigParam(hHal, &smeConfig);
2646
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302647 if (strncmp(command, "SETDWELLTIME ACTIVE MAX", 23) == 0 )
2648 {
2649 value = value + 24;
2650 temp = kstrtou32(value, 10, &val);
2651 if (temp != 0 || val < CFG_ACTIVE_MAX_CHANNEL_TIME_MIN ||
2652 val > CFG_ACTIVE_MAX_CHANNEL_TIME_MAX )
2653 {
2654 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2655 "%s: argument passed for SETDWELLTIME ACTIVE MAX is incorrect", __func__);
2656 ret = -EFAULT;
2657 return ret;
2658 }
2659 pCfg->nActiveMaxChnTime = val;
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05302660 smeConfig.csrConfig.nActiveMaxChnTime = val;
2661 sme_UpdateConfig(hHal, &smeConfig);
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302662 }
2663 else if (strncmp(command, "SETDWELLTIME ACTIVE MIN", 23) == 0)
2664 {
2665 value = value + 24;
2666 temp = kstrtou32(value, 10, &val);
2667 if (temp !=0 || val < CFG_ACTIVE_MIN_CHANNEL_TIME_MIN ||
2668 val > CFG_ACTIVE_MIN_CHANNEL_TIME_MAX )
2669 {
2670 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2671 "%s: argument passsed for SETDWELLTIME ACTIVE MIN is incorrect", __func__);
2672 ret = -EFAULT;
2673 return ret;
2674 }
2675 pCfg->nActiveMinChnTime = val;
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05302676 smeConfig.csrConfig.nActiveMinChnTime = val;
2677 sme_UpdateConfig(hHal, &smeConfig);
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302678 }
2679 else if (strncmp(command, "SETDWELLTIME PASSIVE MAX", 24) == 0)
2680 {
2681 value = value + 25;
2682 temp = kstrtou32(value, 10, &val);
2683 if (temp != 0 || val < CFG_PASSIVE_MAX_CHANNEL_TIME_MIN ||
2684 val > CFG_PASSIVE_MAX_CHANNEL_TIME_MAX )
2685 {
2686 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2687 "%s: argument passed for SETDWELLTIME PASSIVE MAX is incorrect", __func__);
2688 ret = -EFAULT;
2689 return ret;
2690 }
2691 pCfg->nPassiveMaxChnTime = val;
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05302692 smeConfig.csrConfig.nPassiveMaxChnTime = val;
2693 sme_UpdateConfig(hHal, &smeConfig);
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302694 }
2695 else if (strncmp(command, "SETDWELLTIME PASSIVE MIN", 24) == 0)
2696 {
2697 value = value + 25;
2698 temp = kstrtou32(value, 10, &val);
2699 if (temp != 0 || val < CFG_PASSIVE_MIN_CHANNEL_TIME_MIN ||
2700 val > CFG_PASSIVE_MIN_CHANNEL_TIME_MAX )
2701 {
2702 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2703 "%s: argument passed for SETDWELLTIME PASSIVE MIN is incorrect", __func__);
2704 ret = -EFAULT;
2705 return ret;
2706 }
2707 pCfg->nPassiveMinChnTime = val;
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05302708 smeConfig.csrConfig.nPassiveMinChnTime = val;
2709 sme_UpdateConfig(hHal, &smeConfig);
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302710 }
Rajesh Babu Prathipati0fd227e2014-07-05 12:50:00 +05302711 else if (strncmp(command, "SETDWELLTIME", 12) == 0)
2712 {
2713 value = value + 13;
2714 temp = kstrtou32(value, 10, &val);
2715 if (temp != 0 || val < CFG_ACTIVE_MAX_CHANNEL_TIME_MIN ||
2716 val > CFG_ACTIVE_MAX_CHANNEL_TIME_MAX )
2717 {
2718 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2719 "%s: argument passed for SETDWELLTIME is incorrect", __func__);
2720 ret = -EFAULT;
2721 return ret;
2722 }
2723 pCfg->nActiveMaxChnTime = val;
2724 smeConfig.csrConfig.nActiveMaxChnTime = val;
2725 sme_UpdateConfig(hHal, &smeConfig);
2726 }
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302727 else
2728 {
2729 ret = -EINVAL;
2730 }
2731
2732 return ret;
2733}
Agarwal Ashish8bd53ae2015-06-12 18:03:45 +05302734static int hdd_cmd_setFccChannel(hdd_context_t *pHddCtx, tANI_U8 *cmd,
2735 tANI_U8 cmd_len)
2736{
2737 tANI_U8 *value;
2738 tANI_U8 fcc_constraint;
2739
2740 eHalStatus status;
2741 int ret = 0;
2742 value = cmd + cmd_len + 1;
2743
2744 ret = kstrtou8(value, 10, &fcc_constraint);
2745 if ((ret < 0) || (fcc_constraint > 1)) {
2746 /*
2747 * If the input value is greater than max value of datatype,
2748 * then also it is a failure
2749 */
2750 hddLog(VOS_TRACE_LEVEL_ERROR,
2751 "%s: value out of range", __func__);
2752 return -EINVAL;
2753 }
2754
2755 status = sme_handleSetFccChannel(pHddCtx->hHal, fcc_constraint);
2756 if (status != eHAL_STATUS_SUCCESS)
2757 ret = -EPERM;
2758
2759 return ret;
2760}
2761
Mahesh A Saptasagarbeca12c2015-09-07 16:21:06 +05302762/**---------------------------------------------------------------------------
Agarwal Ashish8bd53ae2015-06-12 18:03:45 +05302763
Mahesh A Saptasagarbeca12c2015-09-07 16:21:06 +05302764 \brief hdd_enable_disable_ca_event() - When Host sends IOCTL (enabled),
2765 FW will send *ONE* CA ind to Host(even though it is duplicate).
2766 When Host send IOCTL (disable), FW doesn't perform any action.
2767 Whenever any change in CA *and* WLAN is in SAP/P2P-GO mode, FW
2768 sends CA ind to host. (regard less of IOCTL status)
2769 \param - pHddCtx - HDD context
2770 \param - command - command received from framework
2771 \param - cmd_len - len of the command
2772
2773 \return - 0 on success, appropriate error values on failure.
2774
2775 --------------------------------------------------------------------------*/
2776int hdd_enable_disable_ca_event(hdd_context_t *pHddCtx, tANI_U8* command, tANI_U8 cmd_len)
2777{
2778 tANI_U8 set_value;
2779 int ret = 0;
2780 eHalStatus status;
2781
2782 ret = wlan_hdd_validate_context(pHddCtx);
2783 if (0 != ret)
2784 {
2785 ret = -EINVAL;
2786 goto exit;
2787 }
2788
2789 if (pHddCtx->cfg_ini->gOptimizeCAevent == 0)
2790 {
2791 hddLog(VOS_TRACE_LEVEL_ERROR, "Enable gOptimizeCAevent"
2792 " ini param to control channel avooidance indication");
2793 ret = 0;
2794 goto exit;
2795 }
2796
2797 set_value = command[cmd_len + 1] - '0';
2798 status = sme_enableDisableChanAvoidIndEvent(pHddCtx->hHal, set_value);
2799 if (status != eHAL_STATUS_SUCCESS)
2800 {
2801 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Failed to send"
2802 " enableDisableChanAoidance command to SME\n", __func__);
2803 ret = -EINVAL;
2804 }
2805
2806exit:
2807 return ret;
2808}
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302809
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002810static int hdd_driver_command(hdd_adapter_t *pAdapter,
2811 hdd_priv_data_t *ppriv_data)
Jeff Johnson295189b2012-06-20 16:38:30 -07002812{
Jeff Johnson295189b2012-06-20 16:38:30 -07002813 hdd_priv_data_t priv_data;
2814 tANI_U8 *command = NULL;
Kaushik, Sushant96122442014-10-21 16:40:18 +05302815 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
2816 hdd_scaninfo_t *pScanInfo = NULL;
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002817 int ret = 0;
Kaushik, Sushant96122442014-10-21 16:40:18 +05302818 int status;
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05302819#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
2820 struct cfg80211_mgmt_tx_params params;
2821#endif
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302822
2823 ENTER();
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002824 /*
2825 * Note that valid pointers are provided by caller
2826 */
Jeff Johnson295189b2012-06-20 16:38:30 -07002827
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002828 /* copy to local struct to avoid numerous changes to legacy code */
2829 priv_data = *ppriv_data;
Jeff Johnson295189b2012-06-20 16:38:30 -07002830
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002831 if (priv_data.total_len <= 0 ||
2832 priv_data.total_len > WLAN_PRIV_DATA_MAX_LEN)
Sameer Thalappil8ef3a0e2013-04-05 14:36:04 -07002833 {
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002834 hddLog(VOS_TRACE_LEVEL_WARN,
2835 "%s:invalid priv_data.total_len(%d)!!!", __func__,
2836 priv_data.total_len);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07002837 ret = -EINVAL;
2838 goto exit;
2839 }
Kaushik, Sushant96122442014-10-21 16:40:18 +05302840 status = wlan_hdd_validate_context(pHddCtx);
2841 if (0 != status)
2842 {
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302843 ret = -EINVAL;
2844 goto exit;
Kaushik, Sushant96122442014-10-21 16:40:18 +05302845 }
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07002846 /* Allocate +1 for '\0' */
2847 command = kmalloc(priv_data.total_len + 1, GFP_KERNEL);
Jeff Johnson295189b2012-06-20 16:38:30 -07002848 if (!command)
2849 {
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002850 hddLog(VOS_TRACE_LEVEL_ERROR,
2851 "%s: failed to allocate memory", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002852 ret = -ENOMEM;
2853 goto exit;
2854 }
2855
2856 if (copy_from_user(command, priv_data.buf, priv_data.total_len))
2857 {
2858 ret = -EFAULT;
2859 goto exit;
2860 }
2861
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002862 /* Make sure the command is NUL-terminated */
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07002863 command[priv_data.total_len] = '\0';
2864
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002865 /* at one time the following block of code was conditional. braces
2866 * have been retained to avoid re-indenting the legacy code
2867 */
Jeff Johnson295189b2012-06-20 16:38:30 -07002868 {
2869 hdd_context_t *pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
2870
2871 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudif9bdd4e2012-10-30 18:05:03 -07002872 "%s: Received %s cmd from Wi-Fi GUI***", __func__, command);
Jeff Johnson295189b2012-06-20 16:38:30 -07002873
2874 if (strncmp(command, "P2P_DEV_ADDR", 12) == 0 )
2875 {
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302876 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2877 TRACE_CODE_HDD_P2P_DEV_ADDR_IOCTL,
2878 pAdapter->sessionId, (unsigned)
2879 (*(pHddCtx->p2pDeviceAddress.bytes+2)<<24 |
2880 *(pHddCtx->p2pDeviceAddress.bytes+3)<<16 |
2881 *(pHddCtx->p2pDeviceAddress.bytes+4)<<8 |
2882 *(pHddCtx->p2pDeviceAddress.bytes+5))));
Jeff Johnson295189b2012-06-20 16:38:30 -07002883 if (copy_to_user(priv_data.buf, pHddCtx->p2pDeviceAddress.bytes,
2884 sizeof(tSirMacAddr)))
2885 {
2886 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08002887 "%s: failed to copy data to user buffer", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002888 ret = -EFAULT;
2889 }
2890 }
Amar Singhal0974e402013-02-12 14:27:46 -08002891 else if(strncmp(command, "SETBAND", 7) == 0)
Jeff Johnson295189b2012-06-20 16:38:30 -07002892 {
Amar Singhal0974e402013-02-12 14:27:46 -08002893 tANI_U8 *ptr = command ;
Srinivas Girigowdade697412013-02-14 16:31:48 -08002894
Jeff Johnson295189b2012-06-20 16:38:30 -07002895 /* Change band request received */
Srinivas Girigowdade697412013-02-14 16:31:48 -08002896
2897 /* First 8 bytes will have "SETBAND " and
Jeff Johnson295189b2012-06-20 16:38:30 -07002898 * 9 byte will have band setting value */
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07002899 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Amar Singhal0974e402013-02-12 14:27:46 -08002900 "%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 +05302901 if(VOS_FTM_MODE != hdd_get_conparam())
2902 {
2903 /* Change band request received */
2904 ret = hdd_setBand_helper(pAdapter->dev, ptr);
2905 if(ret < 0)
2906 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
2907 "%s: failed to set band ret=%d", __func__, ret);
2908 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08002909 }
Kiet Lamf040f472013-11-20 21:15:23 +05302910 else if(strncmp(command, "SETWMMPS", 8) == 0)
2911 {
2912 tANI_U8 *ptr = command;
2913 ret = hdd_wmmps_helper(pAdapter, ptr);
2914 }
Agarwal Ashishef54a182014-12-16 15:07:31 +05302915
2916 else if(strncmp(command, "TDLSSCAN", 8) == 0)
2917 {
2918 tANI_U8 *ptr = command;
2919 ret = hdd_set_tdls_scan_type(pAdapter, ptr);
2920 }
2921
Jeff Johnson32d95a32012-09-10 13:15:23 -07002922 else if ( strncasecmp(command, "COUNTRY", 7) == 0 )
2923 {
2924 char *country_code;
2925
2926 country_code = command + 8;
Tushnim Bhattacharyya9cdf6082013-04-21 16:33:30 -07002927
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07002928 INIT_COMPLETION(pAdapter->change_country_code);
Tushnim Bhattacharyya9cdf6082013-04-21 16:33:30 -07002929 hdd_checkandupdate_dfssetting(pAdapter, country_code);
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -07002930#ifndef CONFIG_ENABLE_LINUX_REG
Gopichand Nakkaladacbcb52013-04-18 16:41:54 +05302931 hdd_checkandupdate_phymode(pAdapter, country_code);
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -07002932#endif
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07002933 ret = (int)sme_ChangeCountryCode(pHddCtx->hHal,
2934 (void *)(tSmeChangeCountryCallback)
2935 wlan_hdd_change_country_code_callback,
Abhishek Singha306a442013-11-07 18:39:01 +05302936 country_code, pAdapter, pHddCtx->pvosContext, eSIR_TRUE, eSIR_TRUE);
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07002937 if (eHAL_STATUS_SUCCESS == ret)
2938 {
2939 ret = wait_for_completion_interruptible_timeout(
2940 &pAdapter->change_country_code,
2941 msecs_to_jiffies(WLAN_WAIT_TIME_COUNTRY));
2942 if (0 >= ret)
2943 {
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002944 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: SME while setting country code timed out %d",
c_hpothu6ff1c3c2013-10-01 19:01:57 +05302945 __func__, ret);
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07002946 }
2947 }
2948 else
Jeff Johnson32d95a32012-09-10 13:15:23 -07002949 {
2950 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002951 "%s: SME Change Country code fail ret=%d", __func__, ret);
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07002952 ret = -EINVAL;
Jeff Johnson32d95a32012-09-10 13:15:23 -07002953 }
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07002954
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07002955 }
2956 /*
2957 command should be a string having format
2958 SET_SAP_CHANNEL_LIST <num of channels> <the channels seperated by spaces>
2959 */
Amar Singhal0974e402013-02-12 14:27:46 -08002960 else if(strncmp(command, "SET_SAP_CHANNEL_LIST", 20) == 0)
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07002961 {
Amar Singhal0974e402013-02-12 14:27:46 -08002962 tANI_U8 *ptr = command;
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07002963
2964 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002965 " Received Command to Set Preferred Channels for SAP in %s", __func__);
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07002966
Mahesh Kumar Kalikot Veetil2aad8d82013-02-07 12:31:28 -08002967 ret = sapSetPreferredChannel(ptr);
Jeff Johnson32d95a32012-09-10 13:15:23 -07002968 }
Sameer Thalappil45931fb2013-02-01 11:18:05 -08002969 else if(strncmp(command, "SETSUSPENDMODE", 14) == 0)
2970 {
2971 int suspend = 0;
2972 tANI_U8 *ptr = (tANI_U8*)command + 15;
2973
2974 suspend = *ptr - '0';
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302975 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2976 TRACE_CODE_HDD_SETSUSPENDMODE_IOCTL,
2977 pAdapter->sessionId, suspend));
Sameer Thalappil45931fb2013-02-01 11:18:05 -08002978 hdd_set_wlan_suspend_mode(suspend);
2979 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08002980#ifdef WLAN_FEATURE_NEIGHBOR_ROAMING
2981 else if (strncmp(command, "SETROAMTRIGGER", 14) == 0)
2982 {
2983 tANI_U8 *value = command;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002984 tANI_S8 rssi = 0;
Srinivas Girigowdade697412013-02-14 16:31:48 -08002985 tANI_U8 lookUpThreshold = CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_DEFAULT;
2986 eHalStatus status = eHAL_STATUS_SUCCESS;
2987
2988 /* Move pointer to ahead of SETROAMTRIGGER<delimiter> */
2989 value = value + 15;
2990
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002991 /* Convert the value from ascii to integer */
2992 ret = kstrtos8(value, 10, &rssi);
2993 if (ret < 0)
2994 {
2995 /* If the input value is greater than max value of datatype, then also
2996 kstrtou8 fails */
2997 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2998 "%s: kstrtou8 failed Input value may be out of range[%d - %d]",
Srinivas Girigowdafa7157d2013-10-31 10:14:22 -07002999 __func__,
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07003000 CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MIN,
3001 CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MAX);
3002 ret = -EINVAL;
3003 goto exit;
3004 }
3005
Srinivas Girigowdade697412013-02-14 16:31:48 -08003006 lookUpThreshold = abs(rssi);
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07003007
Srinivas Girigowdade697412013-02-14 16:31:48 -08003008 if ((lookUpThreshold < CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MIN) ||
3009 (lookUpThreshold > CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MAX))
3010 {
3011 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3012 "Neighbor lookup threshold value %d is out of range"
3013 " (Min: %d Max: %d)", lookUpThreshold,
3014 CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MIN,
3015 CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MAX);
3016 ret = -EINVAL;
3017 goto exit;
3018 }
3019
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05303020 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
3021 TRACE_CODE_HDD_SETROAMTRIGGER_IOCTL,
3022 pAdapter->sessionId, lookUpThreshold));
Srinivas Girigowdade697412013-02-14 16:31:48 -08003023 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3024 "%s: Received Command to Set Roam trigger"
3025 " (Neighbor lookup threshold) = %d", __func__, lookUpThreshold);
3026
3027 pHddCtx->cfg_ini->nNeighborLookupRssiThreshold = lookUpThreshold;
3028 status = sme_setNeighborLookupRssiThreshold((tHalHandle)(pHddCtx->hHal), lookUpThreshold);
3029 if (eHAL_STATUS_SUCCESS != status)
3030 {
3031 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3032 "%s: Failed to set roam trigger, try again", __func__);
3033 ret = -EPERM;
3034 goto exit;
3035 }
3036
3037 /* Set Reassoc threshold to (lookup rssi threshold + 5 dBm) */
mukul sharmad6e1fdd2014-06-23 19:19:09 +05303038 pHddCtx->cfg_ini->nNeighborReassocRssiThreshold = lookUpThreshold + 5;
Srinivas Girigowdade697412013-02-14 16:31:48 -08003039 sme_setNeighborReassocRssiThreshold((tHalHandle)(pHddCtx->hHal), lookUpThreshold + 5);
3040 }
3041 else if (strncmp(command, "GETROAMTRIGGER", 14) == 0)
3042 {
3043 tANI_U8 lookUpThreshold = sme_getNeighborLookupRssiThreshold((tHalHandle)(pHddCtx->hHal));
3044 int rssi = (-1) * lookUpThreshold;
3045 char extra[32];
3046 tANI_U8 len = 0;
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05303047 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
3048 TRACE_CODE_HDD_GETROAMTRIGGER_IOCTL,
3049 pAdapter->sessionId, lookUpThreshold));
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003050 len = scnprintf(extra, sizeof(extra), "%s %d", command, rssi);
Srinivas Girigowda91719232015-07-13 15:10:10 +05303051 len = VOS_MIN(priv_data.total_len, len + 1);
3052 if (copy_to_user(priv_data.buf, &extra, len))
Srinivas Girigowdade697412013-02-14 16:31:48 -08003053 {
3054 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3055 "%s: failed to copy data to user buffer", __func__);
3056 ret = -EFAULT;
3057 goto exit;
3058 }
3059 }
3060 else if (strncmp(command, "SETROAMSCANPERIOD", 17) == 0)
3061 {
3062 tANI_U8 *value = command;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07003063 tANI_U8 roamScanPeriod = 0;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003064 tANI_U16 neighborEmptyScanRefreshPeriod = CFG_EMPTY_SCAN_REFRESH_PERIOD_DEFAULT;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07003065
Srinivas Girigowdade697412013-02-14 16:31:48 -08003066 /* input refresh period is in terms of seconds */
3067 /* Move pointer to ahead of SETROAMSCANPERIOD<delimiter> */
3068 value = value + 18;
3069 /* Convert the value from ascii to integer */
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07003070 ret = kstrtou8(value, 10, &roamScanPeriod);
Srinivas Girigowdade697412013-02-14 16:31:48 -08003071 if (ret < 0)
3072 {
3073 /* If the input value is greater than max value of datatype, then also
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07003074 kstrtou8 fails */
Srinivas Girigowdade697412013-02-14 16:31:48 -08003075 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07003076 "%s: kstrtou8 failed Input value may be out of range[%d - %d]",
Srinivas Girigowdade697412013-02-14 16:31:48 -08003077 __func__,
Srinivas Girigowdab8edd1e2013-03-19 11:42:08 -07003078 (CFG_EMPTY_SCAN_REFRESH_PERIOD_MIN/1000),
3079 (CFG_EMPTY_SCAN_REFRESH_PERIOD_MAX/1000));
Srinivas Girigowdade697412013-02-14 16:31:48 -08003080 ret = -EINVAL;
3081 goto exit;
3082 }
3083
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07003084 if ((roamScanPeriod < (CFG_EMPTY_SCAN_REFRESH_PERIOD_MIN/1000)) ||
3085 (roamScanPeriod > (CFG_EMPTY_SCAN_REFRESH_PERIOD_MAX/1000)))
Srinivas Girigowdade697412013-02-14 16:31:48 -08003086 {
3087 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07003088 "Roam scan period value %d is out of range"
3089 " (Min: %d Max: %d)", roamScanPeriod,
Srinivas Girigowdab8edd1e2013-03-19 11:42:08 -07003090 (CFG_EMPTY_SCAN_REFRESH_PERIOD_MIN/1000),
3091 (CFG_EMPTY_SCAN_REFRESH_PERIOD_MAX/1000));
Srinivas Girigowdade697412013-02-14 16:31:48 -08003092 ret = -EINVAL;
3093 goto exit;
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05303094 }
3095 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
3096 TRACE_CODE_HDD_SETROAMSCANPERIOD_IOCTL,
3097 pAdapter->sessionId, roamScanPeriod));
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07003098 neighborEmptyScanRefreshPeriod = roamScanPeriod * 1000;
Srinivas Girigowdade697412013-02-14 16:31:48 -08003099
3100 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3101 "%s: Received Command to Set roam scan period"
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07003102 " (Empty Scan refresh period) = %d", __func__, roamScanPeriod);
Srinivas Girigowdade697412013-02-14 16:31:48 -08003103
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003104 pHddCtx->cfg_ini->nEmptyScanRefreshPeriod = neighborEmptyScanRefreshPeriod;
3105 sme_UpdateEmptyScanRefreshPeriod((tHalHandle)(pHddCtx->hHal), neighborEmptyScanRefreshPeriod);
Srinivas Girigowdade697412013-02-14 16:31:48 -08003106 }
3107 else if (strncmp(command, "GETROAMSCANPERIOD", 17) == 0)
3108 {
3109 tANI_U16 nEmptyScanRefreshPeriod = sme_getEmptyScanRefreshPeriod((tHalHandle)(pHddCtx->hHal));
3110 char extra[32];
3111 tANI_U8 len = 0;
3112
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05303113 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
3114 TRACE_CODE_HDD_GETROAMSCANPERIOD_IOCTL,
3115 pAdapter->sessionId, nEmptyScanRefreshPeriod));
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003116 len = scnprintf(extra, sizeof(extra), "%s %d",
3117 "GETROAMSCANPERIOD", (nEmptyScanRefreshPeriod/1000));
Srinivas Girigowdade697412013-02-14 16:31:48 -08003118 /* Returned value is in units of seconds */
Ratnam Rachuria72ba112015-07-17 13:27:03 +05303119 len = VOS_MIN(priv_data.total_len, len + 1);
3120 if (copy_to_user(priv_data.buf, &extra, len)) {
Srinivas Girigowdade697412013-02-14 16:31:48 -08003121 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3122 "%s: failed to copy data to user buffer", __func__);
3123 ret = -EFAULT;
3124 goto exit;
3125 }
3126 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003127 else if (strncmp(command, "SETROAMSCANREFRESHPERIOD", 24) == 0)
3128 {
3129 tANI_U8 *value = command;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07003130 tANI_U8 roamScanRefreshPeriod = 0;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003131 tANI_U16 neighborScanRefreshPeriod = CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_DEFAULT;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07003132
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003133 /* input refresh period is in terms of seconds */
3134 /* Move pointer to ahead of SETROAMSCANREFRESHPERIOD<delimiter> */
3135 value = value + 25;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07003136
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003137 /* Convert the value from ascii to integer */
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07003138 ret = kstrtou8(value, 10, &roamScanRefreshPeriod);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003139 if (ret < 0)
3140 {
3141 /* If the input value is greater than max value of datatype, then also
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07003142 kstrtou8 fails */
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003143 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07003144 "%s: kstrtou8 failed Input value may be out of range[%d - %d]",
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003145 __func__,
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003146 (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MIN/1000),
3147 (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MAX/1000));
3148 ret = -EINVAL;
3149 goto exit;
3150 }
3151
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07003152 if ((roamScanRefreshPeriod < (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MIN/1000)) ||
3153 (roamScanRefreshPeriod > (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MAX/1000)))
3154 {
3155 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3156 "Neighbor scan results refresh period value %d is out of range"
3157 " (Min: %d Max: %d)", roamScanRefreshPeriod,
3158 (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MIN/1000),
3159 (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MAX/1000));
3160 ret = -EINVAL;
3161 goto exit;
3162 }
3163 neighborScanRefreshPeriod = roamScanRefreshPeriod * 1000;
3164
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003165 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3166 "%s: Received Command to Set roam scan refresh period"
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07003167 " (Scan refresh period) = %d", __func__, roamScanRefreshPeriod);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003168
3169 pHddCtx->cfg_ini->nNeighborResultsRefreshPeriod = neighborScanRefreshPeriod;
3170 sme_setNeighborScanRefreshPeriod((tHalHandle)(pHddCtx->hHal), neighborScanRefreshPeriod);
3171 }
3172 else if (strncmp(command, "GETROAMSCANREFRESHPERIOD", 24) == 0)
3173 {
3174 tANI_U16 value = sme_getNeighborScanRefreshPeriod((tHalHandle)(pHddCtx->hHal));
3175 char extra[32];
3176 tANI_U8 len = 0;
3177
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003178 len = scnprintf(extra, sizeof(extra), "%s %d",
3179 "GETROAMSCANREFRESHPERIOD", (value/1000));
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003180 /* Returned value is in units of seconds */
Ratnam Rachuri2c9d6702015-07-17 13:25:16 +05303181 len = VOS_MIN(priv_data.total_len, len + 1);
3182 if (copy_to_user(priv_data.buf, &extra, len)) {
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003183 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3184 "%s: failed to copy data to user buffer", __func__);
3185 ret = -EFAULT;
3186 goto exit;
3187 }
3188 }
Varun Reddy Yeturu6d99ac82013-05-08 14:15:35 -07003189#ifdef FEATURE_WLAN_LFR
3190 /* SETROAMMODE */
3191 else if (strncmp(command, "SETROAMMODE", SIZE_OF_SETROAMMODE) == 0)
3192 {
3193 tANI_U8 *value = command;
3194 tANI_BOOLEAN roamMode = CFG_LFR_FEATURE_ENABLED_DEFAULT;
3195
3196 /* Move pointer to ahead of SETROAMMODE<delimiter> */
3197 value = value + SIZE_OF_SETROAMMODE + 1;
3198
3199 /* Convert the value from ascii to integer */
3200 ret = kstrtou8(value, SIZE_OF_SETROAMMODE, &roamMode);
3201 if (ret < 0)
3202 {
3203 /* If the input value is greater than max value of datatype, then also
3204 kstrtou8 fails */
3205 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3206 "%s: kstrtou8 failed range [%d - %d]", __func__,
3207 CFG_LFR_FEATURE_ENABLED_MIN,
3208 CFG_LFR_FEATURE_ENABLED_MAX);
3209 ret = -EINVAL;
3210 goto exit;
3211 }
3212 if ((roamMode < CFG_LFR_FEATURE_ENABLED_MIN) ||
3213 (roamMode > CFG_LFR_FEATURE_ENABLED_MAX))
3214 {
3215 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3216 "Roam Mode value %d is out of range"
3217 " (Min: %d Max: %d)", roamMode,
3218 CFG_LFR_FEATURE_ENABLED_MIN,
3219 CFG_LFR_FEATURE_ENABLED_MAX);
3220 ret = -EINVAL;
3221 goto exit;
3222 }
3223
3224 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3225 "%s: Received Command to Set Roam Mode = %d", __func__, roamMode);
3226 /*
3227 * Note that
3228 * SETROAMMODE 0 is to enable LFR while
3229 * SETROAMMODE 1 is to disable LFR, but
3230 * NotifyIsFastRoamIniFeatureEnabled 0/1 is to enable/disable.
3231 * So, we have to invert the value to call sme_UpdateIsFastRoamIniFeatureEnabled.
3232 */
3233 if (CFG_LFR_FEATURE_ENABLED_MIN == roamMode)
3234 roamMode = CFG_LFR_FEATURE_ENABLED_MAX; /* Roam enable */
3235 else
3236 roamMode = CFG_LFR_FEATURE_ENABLED_MIN; /* Roam disable */
3237
3238 pHddCtx->cfg_ini->isFastRoamIniFeatureEnabled = roamMode;
3239 sme_UpdateIsFastRoamIniFeatureEnabled((tHalHandle)(pHddCtx->hHal), roamMode);
3240 }
3241 /* GETROAMMODE */
Mahesh A Saptasagarec7d1092015-04-02 13:41:34 +05303242 else if (strncmp(command, "GETROAMMODE", SIZE_OF_GETROAMMODE) == 0)
Varun Reddy Yeturu6d99ac82013-05-08 14:15:35 -07003243 {
3244 tANI_BOOLEAN roamMode = sme_getIsLfrFeatureEnabled((tHalHandle)(pHddCtx->hHal));
3245 char extra[32];
3246 tANI_U8 len = 0;
3247
3248 /*
3249 * roamMode value shall be inverted because the sementics is different.
3250 */
3251 if (CFG_LFR_FEATURE_ENABLED_MIN == roamMode)
3252 roamMode = CFG_LFR_FEATURE_ENABLED_MAX;
3253 else
3254 roamMode = CFG_LFR_FEATURE_ENABLED_MIN;
3255
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003256 len = scnprintf(extra, sizeof(extra), "%s %d", command, roamMode);
Ratnam Rachuri28693eb2015-07-17 13:23:42 +05303257 len = VOS_MIN(priv_data.total_len, len + 1);
3258 if (copy_to_user(priv_data.buf, &extra, len)) {
Varun Reddy Yeturu6d99ac82013-05-08 14:15:35 -07003259 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3260 "%s: failed to copy data to user buffer", __func__);
3261 ret = -EFAULT;
3262 goto exit;
3263 }
3264 }
3265#endif
Srinivas Girigowdade697412013-02-14 16:31:48 -08003266#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003267#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowdade697412013-02-14 16:31:48 -08003268 else if (strncmp(command, "SETROAMDELTA", 12) == 0)
3269 {
3270 tANI_U8 *value = command;
3271 tANI_U8 roamRssiDiff = CFG_ROAM_RSSI_DIFF_DEFAULT;
3272
3273 /* Move pointer to ahead of SETROAMDELTA<delimiter> */
3274 value = value + 13;
3275 /* Convert the value from ascii to integer */
3276 ret = kstrtou8(value, 10, &roamRssiDiff);
3277 if (ret < 0)
3278 {
3279 /* If the input value is greater than max value of datatype, then also
3280 kstrtou8 fails */
3281 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3282 "%s: kstrtou8 failed range [%d - %d]", __func__,
3283 CFG_ROAM_RSSI_DIFF_MIN,
3284 CFG_ROAM_RSSI_DIFF_MAX);
3285 ret = -EINVAL;
3286 goto exit;
3287 }
3288
3289 if ((roamRssiDiff < CFG_ROAM_RSSI_DIFF_MIN) ||
3290 (roamRssiDiff > CFG_ROAM_RSSI_DIFF_MAX))
3291 {
3292 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3293 "Roam rssi diff value %d is out of range"
3294 " (Min: %d Max: %d)", roamRssiDiff,
3295 CFG_ROAM_RSSI_DIFF_MIN,
3296 CFG_ROAM_RSSI_DIFF_MAX);
3297 ret = -EINVAL;
3298 goto exit;
3299 }
3300
3301 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3302 "%s: Received Command to Set roam rssi diff = %d", __func__, roamRssiDiff);
3303
3304 pHddCtx->cfg_ini->RoamRssiDiff = roamRssiDiff;
3305 sme_UpdateRoamRssiDiff((tHalHandle)(pHddCtx->hHal), roamRssiDiff);
3306 }
Mahesh A Saptasagarec7d1092015-04-02 13:41:34 +05303307 else if (strncmp(command, "GETROAMDELTA", 12) == 0)
Srinivas Girigowdade697412013-02-14 16:31:48 -08003308 {
3309 tANI_U8 roamRssiDiff = sme_getRoamRssiDiff((tHalHandle)(pHddCtx->hHal));
3310 char extra[32];
3311 tANI_U8 len = 0;
3312
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05303313 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
3314 TRACE_CODE_HDD_GETROAMDELTA_IOCTL,
3315 pAdapter->sessionId, roamRssiDiff));
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003316 len = scnprintf(extra, sizeof(extra), "%s %d",
3317 command, roamRssiDiff);
Ratnam Rachuri22a3b402015-07-17 13:21:49 +05303318 len = VOS_MIN(priv_data.total_len, len + 1);
3319 if (copy_to_user(priv_data.buf, &extra, len)) {
Srinivas Girigowdade697412013-02-14 16:31:48 -08003320 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3321 "%s: failed to copy data to user buffer", __func__);
3322 ret = -EFAULT;
3323 goto exit;
3324 }
3325 }
3326#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003327#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowdade697412013-02-14 16:31:48 -08003328 else if (strncmp(command, "GETBAND", 7) == 0)
3329 {
3330 int band = -1;
3331 char extra[32];
3332 tANI_U8 len = 0;
3333 hdd_getBand_helper(pHddCtx, &band);
3334
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05303335 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
3336 TRACE_CODE_HDD_GETBAND_IOCTL,
3337 pAdapter->sessionId, band));
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003338 len = scnprintf(extra, sizeof(extra), "%s %d", command, band);
Ratnam Rachuri52139592015-07-17 13:17:29 +05303339 len = VOS_MIN(priv_data.total_len, len + 1);
3340 if (copy_to_user(priv_data.buf, &extra, len)) {
Srinivas Girigowdade697412013-02-14 16:31:48 -08003341 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3342 "%s: failed to copy data to user buffer", __func__);
3343 ret = -EFAULT;
3344 goto exit;
3345 }
3346 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08003347 else if (strncmp(command, "SETROAMSCANCHANNELS", 19) == 0)
3348 {
3349 tANI_U8 *value = command;
3350 tANI_U8 ChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
3351 tANI_U8 numChannels = 0;
3352 eHalStatus status = eHAL_STATUS_SUCCESS;
3353
3354 status = hdd_parse_channellist(value, ChannelList, &numChannels);
3355 if (eHAL_STATUS_SUCCESS != status)
3356 {
3357 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3358 "%s: Failed to parse channel list information", __func__);
3359 ret = -EINVAL;
3360 goto exit;
3361 }
3362
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05303363 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
3364 TRACE_CODE_HDD_SETROAMSCANCHANNELS_IOCTL,
3365 pAdapter->sessionId, numChannels));
Srinivas Girigowdade697412013-02-14 16:31:48 -08003366 if (numChannels > WNI_CFG_VALID_CHANNEL_LIST_LEN)
3367 {
3368 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3369 "%s: number of channels (%d) supported exceeded max (%d)", __func__,
3370 numChannels, WNI_CFG_VALID_CHANNEL_LIST_LEN);
3371 ret = -EINVAL;
3372 goto exit;
3373 }
3374 status = sme_ChangeRoamScanChannelList((tHalHandle)(pHddCtx->hHal), ChannelList,
3375 numChannels);
3376 if (eHAL_STATUS_SUCCESS != status)
3377 {
3378 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3379 "%s: Failed to update channel list information", __func__);
3380 ret = -EINVAL;
3381 goto exit;
3382 }
3383 }
3384 else if (strncmp(command, "GETROAMSCANCHANNELS", 19) == 0)
3385 {
3386 tANI_U8 ChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
3387 tANI_U8 numChannels = 0;
Jeff Johnson51b67782013-04-05 12:35:41 -07003388 tANI_U8 j = 0;
Srinivas Girigowdade697412013-02-14 16:31:48 -08003389 char extra[128] = {0};
Jeff Johnson51b67782013-04-05 12:35:41 -07003390 int len;
Srinivas Girigowdade697412013-02-14 16:31:48 -08003391
3392 if (eHAL_STATUS_SUCCESS != sme_getRoamScanChannelList( (tHalHandle)(pHddCtx->hHal),
3393 ChannelList, &numChannels ))
3394 {
3395 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
3396 "%s: failed to get roam scan channel list", __func__);
3397 ret = -EFAULT;
3398 goto exit;
3399 }
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05303400 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
3401 TRACE_CODE_HDD_GETROAMSCANCHANNELS_IOCTL,
3402 pAdapter->sessionId, numChannels));
Srinivas Girigowdade697412013-02-14 16:31:48 -08003403 /* output channel list is of the format
3404 [Number of roam scan channels][Channel1][Channel2]... */
3405 /* copy the number of channels in the 0th index */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003406 len = scnprintf(extra, sizeof(extra), "%s %d", command, numChannels);
Sushant Kaushika08ca192015-09-16 15:52:04 +05303407 for (j = 0; (j < numChannels) && len <= sizeof(extra); j++)
Srinivas Girigowdade697412013-02-14 16:31:48 -08003408 {
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003409 len += scnprintf(extra + len, sizeof(extra) - len, " %d",
3410 ChannelList[j]);
Srinivas Girigowdade697412013-02-14 16:31:48 -08003411 }
3412
Sushant Kaushikc9b8be52015-07-15 16:41:27 +05303413 len = VOS_MIN(priv_data.total_len, len + 1);
3414 if (copy_to_user(priv_data.buf, &extra, len))
Srinivas Girigowdade697412013-02-14 16:31:48 -08003415 {
3416 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3417 "%s: failed to copy data to user buffer", __func__);
3418 ret = -EFAULT;
3419 goto exit;
3420 }
3421 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003422 else if (strncmp(command, "GETCCXMODE", 10) == 0)
3423 {
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003424 tANI_BOOLEAN eseMode = sme_getIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal));
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003425 char extra[32];
3426 tANI_U8 len = 0;
3427
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003428 /* Check if the features OKC/ESE/11R are supported simultaneously,
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07003429 then this operation is not permitted (return FAILURE) */
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003430 if (eseMode &&
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07003431 hdd_is_okc_mode_enabled(pHddCtx) &&
3432 sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal)))
3433 {
3434 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003435 "%s: OKC/ESE/11R are supported simultaneously"
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07003436 " hence this operation is not permitted!", __func__);
3437 ret = -EPERM;
3438 goto exit;
3439 }
3440
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003441 len = scnprintf(extra, sizeof(extra), "%s %d",
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003442 "GETCCXMODE", eseMode);
Sushant Kaushikf8abd352015-07-15 16:37:49 +05303443 len = VOS_MIN(priv_data.total_len, len + 1);
3444 if (copy_to_user(priv_data.buf, &extra, len))
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003445 {
3446 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3447 "%s: failed to copy data to user buffer", __func__);
3448 ret = -EFAULT;
3449 goto exit;
3450 }
3451 }
3452 else if (strncmp(command, "GETOKCMODE", 10) == 0)
3453 {
3454 tANI_BOOLEAN okcMode = hdd_is_okc_mode_enabled(pHddCtx);
3455 char extra[32];
3456 tANI_U8 len = 0;
3457
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003458 /* Check if the features OKC/ESE/11R are supported simultaneously,
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07003459 then this operation is not permitted (return FAILURE) */
3460 if (okcMode &&
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003461 sme_getIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal)) &&
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07003462 sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal)))
3463 {
3464 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003465 "%s: OKC/ESE/11R are supported simultaneously"
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07003466 " hence this operation is not permitted!", __func__);
3467 ret = -EPERM;
3468 goto exit;
3469 }
3470
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003471 len = scnprintf(extra, sizeof(extra), "%s %d",
3472 "GETOKCMODE", okcMode);
Sushant Kaushikbc2fb5c2015-07-15 16:43:16 +05303473 len = VOS_MIN(priv_data.total_len, len + 1);
3474 if (copy_to_user(priv_data.buf, &extra, len))
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003475 {
3476 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3477 "%s: failed to copy data to user buffer", __func__);
3478 ret = -EFAULT;
3479 goto exit;
3480 }
3481 }
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07003482 else if (strncmp(command, "GETFASTROAM", 11) == 0)
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003483 {
3484 tANI_BOOLEAN lfrMode = sme_getIsLfrFeatureEnabled((tHalHandle)(pHddCtx->hHal));
3485 char extra[32];
3486 tANI_U8 len = 0;
3487
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003488 len = scnprintf(extra, sizeof(extra), "%s %d",
3489 "GETFASTROAM", lfrMode);
Sushant Kaushik4da7ec92015-07-15 16:39:32 +05303490 len = VOS_MIN(priv_data.total_len, len + 1);
3491 if (copy_to_user(priv_data.buf, &extra, len))
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003492 {
3493 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3494 "%s: failed to copy data to user buffer", __func__);
3495 ret = -EFAULT;
3496 goto exit;
3497 }
3498 }
3499 else if (strncmp(command, "GETFASTTRANSITION", 17) == 0)
3500 {
3501 tANI_BOOLEAN ft = sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal));
3502 char extra[32];
3503 tANI_U8 len = 0;
3504
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003505 len = scnprintf(extra, sizeof(extra), "%s %d",
3506 "GETFASTTRANSITION", ft);
Sushant Kaushik231a4452015-07-15 16:23:56 +05303507 len = VOS_MIN(priv_data.total_len, len + 1);
3508 if (copy_to_user(priv_data.buf, &extra, len))
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003509 {
3510 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3511 "%s: failed to copy data to user buffer", __func__);
3512 ret = -EFAULT;
3513 goto exit;
3514 }
3515 }
3516 else if (strncmp(command, "SETROAMSCANCHANNELMINTIME", 25) == 0)
3517 {
3518 tANI_U8 *value = command;
3519 tANI_U8 minTime = CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_DEFAULT;
3520
3521 /* Move pointer to ahead of SETROAMSCANCHANNELMINTIME<delimiter> */
3522 value = value + 26;
3523 /* Convert the value from ascii to integer */
3524 ret = kstrtou8(value, 10, &minTime);
3525 if (ret < 0)
3526 {
3527 /* If the input value is greater than max value of datatype, then also
3528 kstrtou8 fails */
3529 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3530 "%s: kstrtou8 failed range [%d - %d]", __func__,
3531 CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MIN,
3532 CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MAX);
3533 ret = -EINVAL;
3534 goto exit;
3535 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003536 if ((minTime < CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MIN) ||
3537 (minTime > CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MAX))
3538 {
3539 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3540 "scan min channel time value %d is out of range"
3541 " (Min: %d Max: %d)", minTime,
3542 CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MIN,
3543 CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MAX);
3544 ret = -EINVAL;
3545 goto exit;
3546 }
3547
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05303548 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
3549 TRACE_CODE_HDD_SETROAMSCANCHANNELMINTIME_IOCTL,
3550 pAdapter->sessionId, minTime));
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003551 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3552 "%s: Received Command to change channel min time = %d", __func__, minTime);
3553
3554 pHddCtx->cfg_ini->nNeighborScanMinChanTime = minTime;
3555 sme_setNeighborScanMinChanTime((tHalHandle)(pHddCtx->hHal), minTime);
3556 }
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003557 else if (strncmp(command, "SENDACTIONFRAME", 15) == 0)
3558 {
3559 tANI_U8 *value = command;
3560 tANI_U8 channel = 0;
3561 tANI_U8 dwellTime = 0;
3562 tANI_U8 bufLen = 0;
3563 tANI_U8 *buf = NULL;
3564 tSirMacAddr targetApBssid;
3565 eHalStatus status = eHAL_STATUS_SUCCESS;
3566 struct ieee80211_channel chan;
3567 tANI_U8 finalLen = 0;
3568 tANI_U8 *finalBuf = NULL;
3569 tANI_U8 temp = 0;
3570 u64 cookie;
3571 hdd_station_ctx_t *pHddStaCtx = NULL;
3572 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
3573
3574 /* if not associated, no need to send action frame */
3575 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
3576 {
3577 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s:Not associated!",__func__);
3578 ret = -EINVAL;
3579 goto exit;
3580 }
3581
3582 status = hdd_parse_send_action_frame_data(value, targetApBssid, &channel,
3583 &dwellTime, &buf, &bufLen);
3584 if (eHAL_STATUS_SUCCESS != status)
3585 {
3586 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3587 "%s: Failed to parse send action frame data", __func__);
3588 ret = -EINVAL;
3589 goto exit;
3590 }
3591
3592 /* if the target bssid is different from currently associated AP,
3593 then no need to send action frame */
3594 if (VOS_TRUE != vos_mem_compare(targetApBssid,
3595 pHddStaCtx->conn_info.bssId, sizeof(tSirMacAddr)))
3596 {
3597 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s:STA is not associated to this AP!",__func__);
3598 ret = -EINVAL;
Jeff Johnson11c33152013-04-16 17:52:40 -07003599 vos_mem_free(buf);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08003600 buf = NULL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003601 goto exit;
3602 }
3603
3604 /* if the channel number is different from operating channel then
3605 no need to send action frame */
3606 if (channel != pHddStaCtx->conn_info.operationChannel)
3607 {
3608 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3609 "%s: channel(%d) is different from operating channel(%d)",
3610 __func__, channel, pHddStaCtx->conn_info.operationChannel);
3611 ret = -EINVAL;
Jeff Johnson11c33152013-04-16 17:52:40 -07003612 vos_mem_free(buf);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08003613 buf = NULL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003614 goto exit;
3615 }
3616 chan.center_freq = sme_ChnToFreq(channel);
3617
3618 finalLen = bufLen + 24;
3619 finalBuf = vos_mem_malloc(finalLen);
3620 if (NULL == finalBuf)
3621 {
3622 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "%s:memory allocation failed",__func__);
3623 ret = -ENOMEM;
Jeff Johnson11c33152013-04-16 17:52:40 -07003624 vos_mem_free(buf);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08003625 buf = NULL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003626 goto exit;
3627 }
3628 vos_mem_zero(finalBuf, finalLen);
3629
3630 /* Fill subtype */
3631 temp = SIR_MAC_MGMT_ACTION << 4;
3632 vos_mem_copy(finalBuf + 0, &temp, sizeof(temp));
3633
3634 /* Fill type */
3635 temp = SIR_MAC_MGMT_FRAME;
3636 vos_mem_copy(finalBuf + 2, &temp, sizeof(temp));
3637
3638 /* Fill destination address (bssid of the AP) */
3639 vos_mem_copy(finalBuf + 4, targetApBssid, sizeof(targetApBssid));
3640
Srinivas Girigowdab27c0192013-06-03 10:19:56 -07003641 /* Fill source address (STA mac address) */
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003642 vos_mem_copy(finalBuf + 10, pAdapter->macAddressCurrent.bytes, sizeof(pAdapter->macAddressCurrent.bytes));
3643
Srinivas Girigowdab27c0192013-06-03 10:19:56 -07003644 /* Fill BSSID (AP mac address) */
3645 vos_mem_copy(finalBuf + 16, targetApBssid, sizeof(targetApBssid));
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003646
3647 /* Fill received buffer from 24th address */
3648 vos_mem_copy(finalBuf + 24, buf, bufLen);
3649
Jeff Johnson11c33152013-04-16 17:52:40 -07003650 /* done with the parsed buffer */
3651 vos_mem_free(buf);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08003652 buf = NULL;
Jeff Johnson11c33152013-04-16 17:52:40 -07003653
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05303654#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
3655 params.chan = &chan;
3656 params.offchan = 0;
3657 params.wait = dwellTime;
3658 params.buf = finalBuf;
3659 params.len = finalLen;
3660 params.no_cck = 1;
3661 params.dont_wait_for_ack = 1;
3662 ret = wlan_hdd_mgmt_tx(NULL, &pAdapter->wdev, &params, &cookie);
3663#else
DARAM SUDHA39eede62014-02-12 11:16:40 +05303664 wlan_hdd_mgmt_tx( NULL,
Yue Maf49ba872013-08-19 12:04:25 -07003665#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
3666 &(pAdapter->wdev),
3667#else
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07003668 pAdapter->dev,
Yue Maf49ba872013-08-19 12:04:25 -07003669#endif
3670 &chan, 0,
3671#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0))
3672 NL80211_CHAN_HT20, 1,
3673#endif
3674 dwellTime, finalBuf, finalLen, 1,
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003675 1, &cookie );
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05303676#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0)*/
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003677 vos_mem_free(finalBuf);
3678 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003679 else if (strncmp(command, "GETROAMSCANCHANNELMINTIME", 25) == 0)
3680 {
3681 tANI_U16 val = sme_getNeighborScanMinChanTime((tHalHandle)(pHddCtx->hHal));
3682 char extra[32];
3683 tANI_U8 len = 0;
3684
3685 /* value is interms of msec */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003686 len = scnprintf(extra, sizeof(extra), "%s %d",
3687 "GETROAMSCANCHANNELMINTIME", val);
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05303688 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
3689 TRACE_CODE_HDD_GETROAMSCANCHANNELMINTIME_IOCTL,
3690 pAdapter->sessionId, val));
Sushant Kaushikbb8c52c2015-07-15 16:36:23 +05303691 len = VOS_MIN(priv_data.total_len, len + 1);
3692 if (copy_to_user(priv_data.buf, &extra, len))
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003693 {
3694 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3695 "%s: failed to copy data to user buffer", __func__);
3696 ret = -EFAULT;
3697 goto exit;
3698 }
3699 }
3700 else if (strncmp(command, "SETSCANCHANNELTIME", 18) == 0)
3701 {
3702 tANI_U8 *value = command;
Varun Reddy Yeturu3885a662013-06-19 07:10:37 -07003703 tANI_U16 maxTime = CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_DEFAULT;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003704
3705 /* Move pointer to ahead of SETSCANCHANNELTIME<delimiter> */
3706 value = value + 19;
3707 /* Convert the value from ascii to integer */
Varun Reddy Yeturu3885a662013-06-19 07:10:37 -07003708 ret = kstrtou16(value, 10, &maxTime);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003709 if (ret < 0)
3710 {
3711 /* If the input value is greater than max value of datatype, then also
Varun Reddy Yeturu3885a662013-06-19 07:10:37 -07003712 kstrtou16 fails */
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003713 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Varun Reddy Yeturu3885a662013-06-19 07:10:37 -07003714 "%s: kstrtou16 failed range [%d - %d]", __func__,
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003715 CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MIN,
3716 CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MAX);
3717 ret = -EINVAL;
3718 goto exit;
3719 }
3720
3721 if ((maxTime < CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MIN) ||
3722 (maxTime > CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MAX))
3723 {
3724 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3725 "lfr mode value %d is out of range"
3726 " (Min: %d Max: %d)", maxTime,
3727 CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MIN,
3728 CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MAX);
3729 ret = -EINVAL;
3730 goto exit;
3731 }
3732
3733 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3734 "%s: Received Command to change channel max time = %d", __func__, maxTime);
3735
3736 pHddCtx->cfg_ini->nNeighborScanMaxChanTime = maxTime;
3737 sme_setNeighborScanMaxChanTime((tHalHandle)(pHddCtx->hHal), maxTime);
3738 }
3739 else if (strncmp(command, "GETSCANCHANNELTIME", 18) == 0)
3740 {
3741 tANI_U16 val = sme_getNeighborScanMaxChanTime((tHalHandle)(pHddCtx->hHal));
3742 char extra[32];
3743 tANI_U8 len = 0;
3744
3745 /* value is interms of msec */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003746 len = scnprintf(extra, sizeof(extra), "%s %d",
3747 "GETSCANCHANNELTIME", val);
Ratheesh S Pacbfa932015-07-16 15:27:18 +05303748 len = VOS_MIN(priv_data.total_len, len + 1);
3749 if (copy_to_user(priv_data.buf, &extra, len))
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003750 {
3751 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3752 "%s: failed to copy data to user buffer", __func__);
3753 ret = -EFAULT;
3754 goto exit;
3755 }
3756 }
3757 else if (strncmp(command, "SETSCANHOMETIME", 15) == 0)
3758 {
3759 tANI_U8 *value = command;
3760 tANI_U16 val = CFG_NEIGHBOR_SCAN_TIMER_PERIOD_DEFAULT;
3761
3762 /* Move pointer to ahead of SETSCANHOMETIME<delimiter> */
3763 value = value + 16;
3764 /* Convert the value from ascii to integer */
3765 ret = kstrtou16(value, 10, &val);
3766 if (ret < 0)
3767 {
3768 /* If the input value is greater than max value of datatype, then also
3769 kstrtou16 fails */
3770 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3771 "%s: kstrtou16 failed range [%d - %d]", __func__,
3772 CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MIN,
3773 CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MAX);
3774 ret = -EINVAL;
3775 goto exit;
3776 }
3777
3778 if ((val < CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MIN) ||
3779 (val > CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MAX))
3780 {
3781 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3782 "scan home time value %d is out of range"
3783 " (Min: %d Max: %d)", val,
3784 CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MIN,
3785 CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MAX);
3786 ret = -EINVAL;
3787 goto exit;
3788 }
3789
3790 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3791 "%s: Received Command to change scan home time = %d", __func__, val);
3792
3793 pHddCtx->cfg_ini->nNeighborScanPeriod = val;
3794 sme_setNeighborScanPeriod((tHalHandle)(pHddCtx->hHal), val);
3795 }
3796 else if (strncmp(command, "GETSCANHOMETIME", 15) == 0)
3797 {
3798 tANI_U16 val = sme_getNeighborScanPeriod((tHalHandle)(pHddCtx->hHal));
3799 char extra[32];
3800 tANI_U8 len = 0;
3801
3802 /* value is interms of msec */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003803 len = scnprintf(extra, sizeof(extra), "%s %d",
3804 "GETSCANHOMETIME", val);
Ratheesh S P728d7c62015-07-16 15:38:58 +05303805 len = VOS_MIN(priv_data.total_len, len + 1);
3806 if (copy_to_user(priv_data.buf, &extra, len))
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003807 {
3808 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3809 "%s: failed to copy data to user buffer", __func__);
3810 ret = -EFAULT;
3811 goto exit;
3812 }
3813 }
3814 else if (strncmp(command, "SETROAMINTRABAND", 16) == 0)
3815 {
3816 tANI_U8 *value = command;
3817 tANI_U8 val = CFG_ROAM_INTRA_BAND_DEFAULT;
3818
3819 /* Move pointer to ahead of SETROAMINTRABAND<delimiter> */
3820 value = value + 17;
3821 /* Convert the value from ascii to integer */
3822 ret = kstrtou8(value, 10, &val);
3823 if (ret < 0)
3824 {
3825 /* If the input value is greater than max value of datatype, then also
3826 kstrtou8 fails */
3827 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3828 "%s: kstrtou8 failed range [%d - %d]", __func__,
3829 CFG_ROAM_INTRA_BAND_MIN,
3830 CFG_ROAM_INTRA_BAND_MAX);
3831 ret = -EINVAL;
3832 goto exit;
3833 }
3834
3835 if ((val < CFG_ROAM_INTRA_BAND_MIN) ||
3836 (val > CFG_ROAM_INTRA_BAND_MAX))
3837 {
3838 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3839 "intra band mode value %d is out of range"
3840 " (Min: %d Max: %d)", val,
3841 CFG_ROAM_INTRA_BAND_MIN,
3842 CFG_ROAM_INTRA_BAND_MAX);
3843 ret = -EINVAL;
3844 goto exit;
3845 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003846 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3847 "%s: Received Command to change intra band = %d", __func__, val);
3848
3849 pHddCtx->cfg_ini->nRoamIntraBand = val;
3850 sme_setRoamIntraBand((tHalHandle)(pHddCtx->hHal), val);
3851 }
3852 else if (strncmp(command, "GETROAMINTRABAND", 16) == 0)
3853 {
3854 tANI_U16 val = sme_getRoamIntraBand((tHalHandle)(pHddCtx->hHal));
3855 char extra[32];
3856 tANI_U8 len = 0;
3857
3858 /* value is interms of msec */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003859 len = scnprintf(extra, sizeof(extra), "%s %d",
3860 "GETROAMINTRABAND", val);
Ratheesh S P2dd2a3e2015-07-16 15:34:23 +05303861 len = VOS_MIN(priv_data.total_len, len + 1);
3862 if (copy_to_user(priv_data.buf, &extra, len))
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003863 {
3864 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3865 "%s: failed to copy data to user buffer", __func__);
3866 ret = -EFAULT;
3867 goto exit;
3868 }
3869 }
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003870 else if (strncmp(command, "SETSCANNPROBES", 14) == 0)
3871 {
3872 tANI_U8 *value = command;
3873 tANI_U8 nProbes = CFG_ROAM_SCAN_N_PROBES_DEFAULT;
3874
3875 /* Move pointer to ahead of SETSCANNPROBES<delimiter> */
3876 value = value + 15;
3877 /* Convert the value from ascii to integer */
3878 ret = kstrtou8(value, 10, &nProbes);
3879 if (ret < 0)
3880 {
3881 /* If the input value is greater than max value of datatype, then also
3882 kstrtou8 fails */
3883 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3884 "%s: kstrtou8 failed range [%d - %d]", __func__,
3885 CFG_ROAM_SCAN_N_PROBES_MIN,
3886 CFG_ROAM_SCAN_N_PROBES_MAX);
3887 ret = -EINVAL;
3888 goto exit;
3889 }
3890
3891 if ((nProbes < CFG_ROAM_SCAN_N_PROBES_MIN) ||
3892 (nProbes > CFG_ROAM_SCAN_N_PROBES_MAX))
3893 {
3894 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3895 "NProbes value %d is out of range"
3896 " (Min: %d Max: %d)", nProbes,
3897 CFG_ROAM_SCAN_N_PROBES_MIN,
3898 CFG_ROAM_SCAN_N_PROBES_MAX);
3899 ret = -EINVAL;
3900 goto exit;
3901 }
3902
3903 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3904 "%s: Received Command to Set nProbes = %d", __func__, nProbes);
3905
3906 pHddCtx->cfg_ini->nProbes = nProbes;
3907 sme_UpdateRoamScanNProbes((tHalHandle)(pHddCtx->hHal), nProbes);
3908 }
Mahesh A Saptasagarec7d1092015-04-02 13:41:34 +05303909 else if (strncmp(command, "GETSCANNPROBES", 14) == 0)
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003910 {
3911 tANI_U8 val = sme_getRoamScanNProbes((tHalHandle)(pHddCtx->hHal));
3912 char extra[32];
3913 tANI_U8 len = 0;
3914
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003915 len = scnprintf(extra, sizeof(extra), "%s %d", command, val);
Ratnam Rachuri6da525d2015-08-07 13:55:54 +05303916 len = VOS_MIN(priv_data.total_len, len + 1);
3917 if (copy_to_user(priv_data.buf, &extra, len)) {
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003918 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3919 "%s: failed to copy data to user buffer", __func__);
3920 ret = -EFAULT;
3921 goto exit;
3922 }
3923 }
3924 else if (strncmp(command, "SETSCANHOMEAWAYTIME", 19) == 0)
3925 {
3926 tANI_U8 *value = command;
3927 tANI_U16 homeAwayTime = CFG_ROAM_SCAN_HOME_AWAY_TIME_DEFAULT;
3928
3929 /* Move pointer to ahead of SETSCANHOMEAWAYTIME<delimiter> */
3930 /* input value is in units of msec */
3931 value = value + 20;
3932 /* Convert the value from ascii to integer */
3933 ret = kstrtou16(value, 10, &homeAwayTime);
3934 if (ret < 0)
3935 {
3936 /* If the input value is greater than max value of datatype, then also
3937 kstrtou8 fails */
3938 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3939 "%s: kstrtou8 failed range [%d - %d]", __func__,
3940 CFG_ROAM_SCAN_HOME_AWAY_TIME_MIN,
3941 CFG_ROAM_SCAN_HOME_AWAY_TIME_MAX);
3942 ret = -EINVAL;
3943 goto exit;
3944 }
3945
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003946 if ((homeAwayTime < CFG_ROAM_SCAN_HOME_AWAY_TIME_MIN) ||
3947 (homeAwayTime > CFG_ROAM_SCAN_HOME_AWAY_TIME_MAX))
3948 {
3949 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3950 "homeAwayTime value %d is out of range"
3951 " (Min: %d Max: %d)", homeAwayTime,
3952 CFG_ROAM_SCAN_HOME_AWAY_TIME_MIN,
3953 CFG_ROAM_SCAN_HOME_AWAY_TIME_MAX);
3954 ret = -EINVAL;
3955 goto exit;
3956 }
3957
3958 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3959 "%s: Received Command to Set scan away time = %d", __func__, homeAwayTime);
Srinivas Girigowda6cf0b822013-06-27 14:00:20 -07003960 if (pHddCtx->cfg_ini->nRoamScanHomeAwayTime != homeAwayTime)
3961 {
3962 pHddCtx->cfg_ini->nRoamScanHomeAwayTime = homeAwayTime;
3963 sme_UpdateRoamScanHomeAwayTime((tHalHandle)(pHddCtx->hHal), homeAwayTime, eANI_BOOLEAN_TRUE);
3964 }
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003965 }
Mahesh A Saptasagarec7d1092015-04-02 13:41:34 +05303966 else if (strncmp(command, "GETSCANHOMEAWAYTIME", 19) == 0)
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003967 {
3968 tANI_U16 val = sme_getRoamScanHomeAwayTime((tHalHandle)(pHddCtx->hHal));
3969 char extra[32];
3970 tANI_U8 len = 0;
3971
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003972 len = scnprintf(extra, sizeof(extra), "%s %d", command, val);
Ratnam Rachuri51a5ad12015-08-07 14:06:37 +05303973 len = VOS_MIN(priv_data.total_len, len + 1);
3974 if (copy_to_user(priv_data.buf, &extra, len)) {
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003975 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3976 "%s: failed to copy data to user buffer", __func__);
3977 ret = -EFAULT;
3978 goto exit;
3979 }
3980 }
3981 else if (strncmp(command, "REASSOC", 7) == 0)
3982 {
3983 tANI_U8 *value = command;
3984 tANI_U8 channel = 0;
3985 tSirMacAddr targetApBssid;
3986 eHalStatus status = eHAL_STATUS_SUCCESS;
Varun Reddy Yeturucc661d22013-05-20 11:47:10 -07003987#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
3988 tCsrHandoffRequest handoffInfo;
3989#endif
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003990 hdd_station_ctx_t *pHddStaCtx = NULL;
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003991 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
3992
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003993 /* if not associated, no need to proceed with reassoc */
3994 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
3995 {
3996 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s:Not associated!",__func__);
3997 ret = -EINVAL;
3998 goto exit;
3999 }
4000
4001 status = hdd_parse_reassoc_command_data(value, targetApBssid, &channel);
4002 if (eHAL_STATUS_SUCCESS != status)
4003 {
4004 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4005 "%s: Failed to parse reassoc command data", __func__);
4006 ret = -EINVAL;
4007 goto exit;
4008 }
4009
4010 /* if the target bssid is same as currently associated AP,
4011 then no need to proceed with reassoc */
4012 if (VOS_TRUE == vos_mem_compare(targetApBssid,
4013 pHddStaCtx->conn_info.bssId, sizeof(tSirMacAddr)))
4014 {
4015 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s:Reassoc BSSID is same as currently associated AP bssid",__func__);
c_manjee6de1f452015-12-08 14:13:28 +05304016 ret = 0;
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07004017 goto exit;
4018 }
4019
4020 /* Check channel number is a valid channel number */
4021 if(VOS_STATUS_SUCCESS !=
4022 wlan_hdd_validate_operation_channel(pAdapter, channel))
4023 {
4024 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08004025 "%s: Invalid Channel [%d]", __func__, channel);
c_manjee6de1f452015-12-08 14:13:28 +05304026
4027 ret = -EINVAL;
4028 goto exit;
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07004029 }
4030
4031 /* Proceed with reassoc */
Varun Reddy Yeturucc661d22013-05-20 11:47:10 -07004032#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
4033 handoffInfo.channel = channel;
4034 vos_mem_copy(handoffInfo.bssid, targetApBssid, sizeof(tSirMacAddr));
4035 sme_HandoffRequest(pHddCtx->hHal, &handoffInfo);
4036#endif
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07004037 }
Srinivas Girigowdaad34ca92013-10-22 10:54:29 -07004038 else if (strncmp(command, "SETWESMODE", 10) == 0)
4039 {
4040 tANI_U8 *value = command;
4041 tANI_BOOLEAN wesMode = CFG_ENABLE_WES_MODE_NAME_DEFAULT;
4042
4043 /* Move pointer to ahead of SETWESMODE<delimiter> */
4044 value = value + 11;
4045 /* Convert the value from ascii to integer */
4046 ret = kstrtou8(value, 10, &wesMode);
4047 if (ret < 0)
4048 {
4049 /* If the input value is greater than max value of datatype, then also
4050 kstrtou8 fails */
4051 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4052 "%s: kstrtou8 failed range [%d - %d]", __func__,
4053 CFG_ENABLE_WES_MODE_NAME_MIN,
4054 CFG_ENABLE_WES_MODE_NAME_MAX);
4055 ret = -EINVAL;
4056 goto exit;
4057 }
4058
4059 if ((wesMode < CFG_ENABLE_WES_MODE_NAME_MIN) ||
4060 (wesMode > CFG_ENABLE_WES_MODE_NAME_MAX))
4061 {
4062 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4063 "WES Mode value %d is out of range"
4064 " (Min: %d Max: %d)", wesMode,
4065 CFG_ENABLE_WES_MODE_NAME_MIN,
4066 CFG_ENABLE_WES_MODE_NAME_MAX);
4067 ret = -EINVAL;
4068 goto exit;
4069 }
4070 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4071 "%s: Received Command to Set WES Mode rssi diff = %d", __func__, wesMode);
4072
4073 pHddCtx->cfg_ini->isWESModeEnabled = wesMode;
4074 sme_UpdateWESMode((tHalHandle)(pHddCtx->hHal), wesMode);
4075 }
Mahesh A Saptasagarec7d1092015-04-02 13:41:34 +05304076 else if (strncmp(command, "GETWESMODE", 10) == 0)
Srinivas Girigowdaad34ca92013-10-22 10:54:29 -07004077 {
4078 tANI_BOOLEAN wesMode = sme_GetWESMode((tHalHandle)(pHddCtx->hHal));
4079 char extra[32];
4080 tANI_U8 len = 0;
4081
Arif Hussain826d9412013-11-12 16:44:54 -08004082 len = scnprintf(extra, sizeof(extra), "%s %d", command, wesMode);
Ratnam Rachuri8fe90c62015-08-07 14:03:26 +05304083 len = VOS_MIN(priv_data.total_len, len + 1);
4084 if (copy_to_user(priv_data.buf, &extra, len)) {
Srinivas Girigowdaad34ca92013-10-22 10:54:29 -07004085 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4086 "%s: failed to copy data to user buffer", __func__);
4087 ret = -EFAULT;
4088 goto exit;
4089 }
4090 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004091#endif /* WLAN_FEATURE_VOWIFI_11R || FEATURE_WLAN_ESE || FEATURE_WLAN_LFR */
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004092#ifdef FEATURE_WLAN_LFR
4093 else if (strncmp(command, "SETFASTROAM", 11) == 0)
4094 {
4095 tANI_U8 *value = command;
4096 tANI_U8 lfrMode = CFG_LFR_FEATURE_ENABLED_DEFAULT;
4097
4098 /* Move pointer to ahead of SETFASTROAM<delimiter> */
4099 value = value + 12;
4100 /* Convert the value from ascii to integer */
4101 ret = kstrtou8(value, 10, &lfrMode);
4102 if (ret < 0)
4103 {
4104 /* If the input value is greater than max value of datatype, then also
4105 kstrtou8 fails */
4106 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4107 "%s: kstrtou8 failed range [%d - %d]", __func__,
4108 CFG_LFR_FEATURE_ENABLED_MIN,
4109 CFG_LFR_FEATURE_ENABLED_MAX);
4110 ret = -EINVAL;
4111 goto exit;
4112 }
4113
4114 if ((lfrMode < CFG_LFR_FEATURE_ENABLED_MIN) ||
4115 (lfrMode > CFG_LFR_FEATURE_ENABLED_MAX))
4116 {
4117 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4118 "lfr mode value %d is out of range"
4119 " (Min: %d Max: %d)", lfrMode,
4120 CFG_LFR_FEATURE_ENABLED_MIN,
4121 CFG_LFR_FEATURE_ENABLED_MAX);
4122 ret = -EINVAL;
4123 goto exit;
4124 }
4125
4126 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4127 "%s: Received Command to change lfr mode = %d", __func__, lfrMode);
4128
4129 pHddCtx->cfg_ini->isFastRoamIniFeatureEnabled = lfrMode;
4130 sme_UpdateIsFastRoamIniFeatureEnabled((tHalHandle)(pHddCtx->hHal), lfrMode);
4131 }
4132#endif
4133#ifdef WLAN_FEATURE_VOWIFI_11R
4134 else if (strncmp(command, "SETFASTTRANSITION", 17) == 0)
4135 {
4136 tANI_U8 *value = command;
4137 tANI_U8 ft = CFG_FAST_TRANSITION_ENABLED_NAME_DEFAULT;
4138
4139 /* Move pointer to ahead of SETFASTROAM<delimiter> */
4140 value = value + 18;
4141 /* Convert the value from ascii to integer */
4142 ret = kstrtou8(value, 10, &ft);
4143 if (ret < 0)
4144 {
4145 /* If the input value is greater than max value of datatype, then also
4146 kstrtou8 fails */
4147 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4148 "%s: kstrtou8 failed range [%d - %d]", __func__,
4149 CFG_FAST_TRANSITION_ENABLED_NAME_MIN,
4150 CFG_FAST_TRANSITION_ENABLED_NAME_MAX);
4151 ret = -EINVAL;
4152 goto exit;
4153 }
4154
4155 if ((ft < CFG_FAST_TRANSITION_ENABLED_NAME_MIN) ||
4156 (ft > CFG_FAST_TRANSITION_ENABLED_NAME_MAX))
4157 {
4158 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4159 "ft mode value %d is out of range"
4160 " (Min: %d Max: %d)", ft,
4161 CFG_FAST_TRANSITION_ENABLED_NAME_MIN,
4162 CFG_FAST_TRANSITION_ENABLED_NAME_MAX);
4163 ret = -EINVAL;
4164 goto exit;
4165 }
4166
4167 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4168 "%s: Received Command to change ft mode = %d", __func__, ft);
4169
4170 pHddCtx->cfg_ini->isFastTransitionEnabled = ft;
4171 sme_UpdateFastTransitionEnabled((tHalHandle)(pHddCtx->hHal), ft);
4172 }
Padma, Santhosh Kumar778d8382015-03-04 17:41:22 +05304173 else if (strncmp(command, "SETDFSSCANMODE", 14) == 0)
4174 {
4175 tANI_U8 *value = command;
4176 tANI_U8 dfsScanMode = DFS_CHNL_SCAN_ENABLED_NORMAL;
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05304177
Padma, Santhosh Kumar778d8382015-03-04 17:41:22 +05304178 /* Move pointer to ahead of SETDFSSCANMODE<delimiter> */
4179 value = value + 15;
4180 /* Convert the value from ascii to integer */
4181 ret = kstrtou8(value, 10, &dfsScanMode);
4182 if (ret < 0)
4183 {
4184 /* If the input value is greater than max value of
4185 datatype, then also kstrtou8 fails
4186 */
4187 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4188 "%s: kstrtou8 failed range [%d - %d]", __func__,
4189 CFG_ENABLE_DFS_CHNL_SCAN_MIN,
4190 CFG_ENABLE_DFS_CHNL_SCAN_MAX);
4191 ret = -EINVAL;
4192 goto exit;
4193 }
4194
4195 if ((dfsScanMode < CFG_ENABLE_DFS_CHNL_SCAN_MIN) ||
4196 (dfsScanMode > CFG_ENABLE_DFS_CHNL_SCAN_MAX))
4197 {
4198 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4199 "dfsScanMode value %d is out of range"
4200 " (Min: %d Max: %d)", dfsScanMode,
4201 CFG_ENABLE_DFS_CHNL_SCAN_MIN,
4202 CFG_ENABLE_DFS_CHNL_SCAN_MAX);
4203 ret = -EINVAL;
4204 goto exit;
4205 }
4206 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4207 "%s: Received Command to Set DFS Scan Mode = %d",
4208 __func__, dfsScanMode);
4209
4210 ret = wlan_hdd_handle_dfs_chan_scan(pHddCtx, dfsScanMode);
4211 }
4212 else if (strncmp(command, "GETDFSSCANMODE", 14) == 0)
4213 {
4214 tANI_U8 dfsScanMode = sme_GetDFSScanMode(pHddCtx->hHal);
4215 char extra[32];
4216 tANI_U8 len = 0;
4217
4218 len = scnprintf(extra, sizeof(extra), "%s %d", command, dfsScanMode);
Ratheesh S P767224e2015-07-16 15:35:51 +05304219 len = VOS_MIN(priv_data.total_len, len + 1);
4220 if (copy_to_user(priv_data.buf, &extra, len))
Padma, Santhosh Kumar778d8382015-03-04 17:41:22 +05304221 {
4222 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4223 "%s: failed to copy data to user buffer", __func__);
4224 ret = -EFAULT;
4225 goto exit;
4226 }
4227 }
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05304228 else if (strncmp(command, "FASTREASSOC", 11) == 0)
4229 {
4230 tANI_U8 *value = command;
Padma, Santhosh Kumarf4582d32014-11-06 19:24:51 +05304231 tANI_U8 channel = 0;
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05304232 tSirMacAddr targetApBssid;
4233 tANI_U8 trigger = 0;
4234 eHalStatus status = eHAL_STATUS_SUCCESS;
Padma, Santhosh Kumarb980a6f2014-11-06 19:07:24 +05304235 tHalHandle hHal;
4236 v_U32_t roamId = 0;
4237 tCsrRoamModifyProfileFields modProfileFields;
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05304238 hdd_station_ctx_t *pHddStaCtx = NULL;
4239 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Padma, Santhosh Kumarb980a6f2014-11-06 19:07:24 +05304240 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05304241
4242 /* if not associated, no need to proceed with reassoc */
4243 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
4244 {
4245 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s:Not associated!",__func__);
4246 ret = -EINVAL;
4247 goto exit;
4248 }
4249
Padma, Santhosh Kumarf4582d32014-11-06 19:24:51 +05304250 status = hdd_parse_reassoc_command_data(value, targetApBssid, &channel);
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05304251 if (eHAL_STATUS_SUCCESS != status)
4252 {
4253 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4254 "%s: Failed to parse reassoc command data", __func__);
4255 ret = -EINVAL;
4256 goto exit;
4257 }
4258
4259 /* if the target bssid is same as currently associated AP,
Padma, Santhosh Kumarb980a6f2014-11-06 19:07:24 +05304260 issue reassoc to same AP */
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05304261 if (VOS_TRUE == vos_mem_compare(targetApBssid,
4262 pHddStaCtx->conn_info.bssId, sizeof(tSirMacAddr)))
4263 {
AnjaneeDevi Kapparapu228d0c52015-11-09 12:32:21 +05304264 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4265 "%s:11r Reassoc BSSID is same as currently associated AP bssid",
4266 __func__);
Padma, Santhosh Kumarb980a6f2014-11-06 19:07:24 +05304267 sme_GetModifyProfileFields(hHal, pAdapter->sessionId,
4268 &modProfileFields);
4269 sme_RoamReassoc(hHal, pAdapter->sessionId,
4270 NULL, modProfileFields, &roamId, 1);
AnjaneeDevi Kapparapu228d0c52015-11-09 12:32:21 +05304271 return 0;
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05304272 }
Padma, Santhosh Kumar0fa809b2014-11-13 14:56:56 +05304273
4274 /* Check channel number is a valid channel number */
4275 if(VOS_STATUS_SUCCESS !=
4276 wlan_hdd_validate_operation_channel(pAdapter, channel))
4277 {
4278 hddLog(VOS_TRACE_LEVEL_ERROR,
4279 "%s: Invalid Channel [%d]", __func__, channel);
AnjaneeDevi Kapparapu228d0c52015-11-09 12:32:21 +05304280 return -EINVAL;
Padma, Santhosh Kumar0fa809b2014-11-13 14:56:56 +05304281 }
4282
Padma, Santhosh Kumarf4582d32014-11-06 19:24:51 +05304283 trigger = eSME_ROAM_TRIGGER_SCAN;
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05304284
4285 /* Proceed with scan/roam */
4286 smeIssueFastRoamNeighborAPEvent(WLAN_HDD_GET_HAL_CTX(pAdapter),
4287 &targetApBssid[0],
Mukul Sharma9e4e0f92015-02-13 18:45:20 +05304288 (tSmeFastRoamTrigger)(trigger),
4289 channel);
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05304290 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004291#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004292#ifdef FEATURE_WLAN_ESE
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004293 else if (strncmp(command, "SETCCXMODE", 10) == 0)
4294 {
4295 tANI_U8 *value = command;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004296 tANI_U8 eseMode = CFG_ESE_FEATURE_ENABLED_DEFAULT;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004297
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004298 /* Check if the features OKC/ESE/11R are supported simultaneously,
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07004299 then this operation is not permitted (return FAILURE) */
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004300 if (sme_getIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal)) &&
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07004301 hdd_is_okc_mode_enabled(pHddCtx) &&
4302 sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal)))
4303 {
4304 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004305 "%s: OKC/ESE/11R are supported simultaneously"
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07004306 " hence this operation is not permitted!", __func__);
4307 ret = -EPERM;
4308 goto exit;
4309 }
4310
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004311 /* Move pointer to ahead of SETCCXMODE<delimiter> */
4312 value = value + 11;
4313 /* Convert the value from ascii to integer */
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004314 ret = kstrtou8(value, 10, &eseMode);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004315 if (ret < 0)
4316 {
4317 /* If the input value is greater than max value of datatype, then also
4318 kstrtou8 fails */
4319 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4320 "%s: kstrtou8 failed range [%d - %d]", __func__,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004321 CFG_ESE_FEATURE_ENABLED_MIN,
4322 CFG_ESE_FEATURE_ENABLED_MAX);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004323 ret = -EINVAL;
4324 goto exit;
4325 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004326 if ((eseMode < CFG_ESE_FEATURE_ENABLED_MIN) ||
4327 (eseMode > CFG_ESE_FEATURE_ENABLED_MAX))
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004328 {
4329 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004330 "Ese mode value %d is out of range"
4331 " (Min: %d Max: %d)", eseMode,
4332 CFG_ESE_FEATURE_ENABLED_MIN,
4333 CFG_ESE_FEATURE_ENABLED_MAX);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004334 ret = -EINVAL;
4335 goto exit;
4336 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004337 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004338 "%s: Received Command to change ese mode = %d", __func__, eseMode);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004339
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004340 pHddCtx->cfg_ini->isEseIniFeatureEnabled = eseMode;
4341 sme_UpdateIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal), eseMode);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004342 }
4343#endif
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004344 else if (strncmp(command, "SETROAMSCANCONTROL", 18) == 0)
4345 {
4346 tANI_U8 *value = command;
4347 tANI_BOOLEAN roamScanControl = 0;
4348
4349 /* Move pointer to ahead of SETROAMSCANCONTROL<delimiter> */
4350 value = value + 19;
4351 /* Convert the value from ascii to integer */
4352 ret = kstrtou8(value, 10, &roamScanControl);
4353 if (ret < 0)
4354 {
4355 /* If the input value is greater than max value of datatype, then also
4356 kstrtou8 fails */
4357 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4358 "%s: kstrtou8 failed ", __func__);
4359 ret = -EINVAL;
4360 goto exit;
4361 }
4362
4363 if (0 != roamScanControl)
4364 {
4365 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4366 "roam scan control invalid value = %d",
4367 roamScanControl);
4368 ret = -EINVAL;
4369 goto exit;
4370 }
4371 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4372 "%s: Received Command to Set roam scan control = %d", __func__, roamScanControl);
4373
4374 sme_SetRoamScanControl((tHalHandle)(pHddCtx->hHal), roamScanControl);
4375 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004376#ifdef FEATURE_WLAN_OKC
4377 else if (strncmp(command, "SETOKCMODE", 10) == 0)
4378 {
4379 tANI_U8 *value = command;
4380 tANI_U8 okcMode = CFG_OKC_FEATURE_ENABLED_DEFAULT;
4381
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004382 /* Check if the features OKC/ESE/11R are supported simultaneously,
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07004383 then this operation is not permitted (return FAILURE) */
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004384 if (sme_getIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal)) &&
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07004385 hdd_is_okc_mode_enabled(pHddCtx) &&
4386 sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal)))
4387 {
4388 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004389 "%s: OKC/ESE/11R are supported simultaneously"
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07004390 " hence this operation is not permitted!", __func__);
4391 ret = -EPERM;
4392 goto exit;
4393 }
4394
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004395 /* Move pointer to ahead of SETOKCMODE<delimiter> */
4396 value = value + 11;
4397 /* Convert the value from ascii to integer */
4398 ret = kstrtou8(value, 10, &okcMode);
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_OKC_FEATURE_ENABLED_MIN,
4406 CFG_OKC_FEATURE_ENABLED_MAX);
4407 ret = -EINVAL;
4408 goto exit;
4409 }
4410
4411 if ((okcMode < CFG_OKC_FEATURE_ENABLED_MIN) ||
4412 (okcMode > CFG_OKC_FEATURE_ENABLED_MAX))
4413 {
4414 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4415 "Okc mode value %d is out of range"
4416 " (Min: %d Max: %d)", okcMode,
4417 CFG_OKC_FEATURE_ENABLED_MIN,
4418 CFG_OKC_FEATURE_ENABLED_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 okc mode = %d", __func__, okcMode);
4425
4426 pHddCtx->cfg_ini->isOkcIniFeatureEnabled = okcMode;
4427 }
Srinivas Girigowdaad34ca92013-10-22 10:54:29 -07004428#endif /* FEATURE_WLAN_OKC */
Mahesh A Saptasagarec7d1092015-04-02 13:41:34 +05304429 else if (strncmp(command, "GETROAMSCANCONTROL", 18) == 0)
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004430 {
4431 tANI_BOOLEAN roamScanControl = sme_GetRoamScanControl((tHalHandle)(pHddCtx->hHal));
4432 char extra[32];
4433 tANI_U8 len = 0;
4434
Sameer Thalappilb0a30232013-09-27 15:37:48 -07004435 len = scnprintf(extra, sizeof(extra), "%s %d",
4436 command, roamScanControl);
Ratnam Rachuri083ada82015-08-07 14:01:05 +05304437 len = VOS_MIN(priv_data.total_len, len + 1);
4438 if (copy_to_user(priv_data.buf, &extra, len)) {
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004439 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4440 "%s: failed to copy data to user buffer", __func__);
4441 ret = -EFAULT;
4442 goto exit;
4443 }
4444 }
Gopichand Nakkala227c7f32013-06-26 22:44:57 +05304445#ifdef WLAN_FEATURE_PACKET_FILTERING
4446 else if (strncmp(command, "ENABLE_PKTFILTER_IPV6", 21) == 0)
4447 {
4448 tANI_U8 filterType = 0;
4449 tANI_U8 *value = command;
4450
4451 /* Move pointer to ahead of ENABLE_PKTFILTER_IPV6<delimiter> */
4452 value = value + 22;
4453
4454 /* Convert the value from ascii to integer */
4455 ret = kstrtou8(value, 10, &filterType);
4456 if (ret < 0)
4457 {
4458 /* If the input value is greater than max value of datatype,
4459 * then also kstrtou8 fails
4460 */
4461 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4462 "%s: kstrtou8 failed range ", __func__);
4463 ret = -EINVAL;
4464 goto exit;
4465 }
4466
4467 if (filterType != 0 && filterType != 1)
4468 {
4469 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4470 "%s: Accepted Values are 0 and 1 ", __func__);
4471 ret = -EINVAL;
4472 goto exit;
4473 }
4474 wlan_hdd_setIPv6Filter(WLAN_HDD_GET_CTX(pAdapter), filterType,
4475 pAdapter->sessionId);
4476 }
4477#endif
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05304478 else if (strncmp(command, "BTCOEXMODE", 10) == 0 )
4479 {
Kiet Lamad161252014-07-22 11:23:32 -07004480 char *dhcpPhase;
Satyanarayana Dash1faea4f2014-09-22 16:21:04 +05304481 int ret;
4482
Kiet Lamad161252014-07-22 11:23:32 -07004483 dhcpPhase = command + 11;
4484 if ('1' == *dhcpPhase)
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05304485 {
Deepthi Gowribfd17132014-11-14 17:59:04 +05304486 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Kiet Lamad161252014-07-22 11:23:32 -07004487 FL("send DHCP START indication"));
c_hpothu9b781ba2013-12-30 20:57:45 +05304488
4489 pHddCtx->btCoexModeSet = TRUE;
Kiet Lamad161252014-07-22 11:23:32 -07004490
Satyanarayana Dash1faea4f2014-09-22 16:21:04 +05304491 ret = wlan_hdd_scan_abort(pAdapter);
4492 if (ret < 0)
4493 {
4494 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4495 FL("failed to abort existing scan %d"), ret);
4496 }
4497
Kiet Lamad161252014-07-22 11:23:32 -07004498 sme_DHCPStartInd(pHddCtx->hHal, pAdapter->device_mode,
4499 pAdapter->sessionId);
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05304500 }
Kiet Lamad161252014-07-22 11:23:32 -07004501 else if ('2' == *dhcpPhase)
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05304502 {
Deepthi Gowribfd17132014-11-14 17:59:04 +05304503 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Kiet Lamad161252014-07-22 11:23:32 -07004504 FL("send DHCP STOP indication"));
c_hpothu9b781ba2013-12-30 20:57:45 +05304505
4506 pHddCtx->btCoexModeSet = FALSE;
Kiet Lamad161252014-07-22 11:23:32 -07004507
4508 sme_DHCPStopInd(pHddCtx->hHal, pAdapter->device_mode,
4509 pAdapter->sessionId);
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05304510 }
4511 }
Jeff Johnsonf54df2c2013-07-24 11:43:39 -07004512 else if (strncmp(command, "SCAN-ACTIVE", 11) == 0)
4513 {
Abhishek Singh58749d62016-02-03 15:27:20 +05304514 hddLog(LOG1,
4515 FL("making default scan to ACTIVE"));
c_hpothudbefd3e2014-04-28 15:59:47 +05304516 pHddCtx->scan_info.scan_mode = eSIR_ACTIVE_SCAN;
Jeff Johnsonf54df2c2013-07-24 11:43:39 -07004517 }
4518 else if (strncmp(command, "SCAN-PASSIVE", 12) == 0)
4519 {
Abhishek Singh58749d62016-02-03 15:27:20 +05304520 hddLog(LOG1,
4521 FL("making default scan to PASSIVE"));
c_hpothudbefd3e2014-04-28 15:59:47 +05304522 pHddCtx->scan_info.scan_mode = eSIR_PASSIVE_SCAN;
Jeff Johnsonf54df2c2013-07-24 11:43:39 -07004523 }
Hanumantha Reddy Pothula212243c2013-08-01 17:28:31 +05304524 else if (strncmp(command, "GETDWELLTIME", 12) == 0)
4525 {
4526 hdd_config_t *pCfg = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
4527 char extra[32];
4528 tANI_U8 len = 0;
4529
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05304530 memset(extra, 0, sizeof(extra));
4531 ret = hdd_get_dwell_time(pCfg, command, extra, sizeof(extra), &len);
Ratnam Rachuri12d5d462015-08-07 14:10:23 +05304532 len = VOS_MIN(priv_data.total_len, len + 1);
4533 if (ret != 0 || copy_to_user(priv_data.buf, &extra, len)) {
Hanumantha Reddy Pothula212243c2013-08-01 17:28:31 +05304534 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4535 "%s: failed to copy data to user buffer", __func__);
4536 ret = -EFAULT;
4537 goto exit;
4538 }
4539 ret = len;
4540 }
4541 else if (strncmp(command, "SETDWELLTIME", 12) == 0)
4542 {
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05304543 ret = hdd_set_dwell_time(pAdapter, command);
Hanumantha Reddy Pothula212243c2013-08-01 17:28:31 +05304544 }
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07004545 else if ( strncasecmp(command, "MIRACAST", 8) == 0 )
4546 {
4547 tANI_U8 filterType = 0;
4548 tANI_U8 *value;
4549 value = command + 9;
4550
4551 /* Convert the value from ascii to integer */
4552 ret = kstrtou8(value, 10, &filterType);
4553 if (ret < 0)
4554 {
4555 /* If the input value is greater than max value of datatype,
4556 * then also kstrtou8 fails
4557 */
4558 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4559 "%s: kstrtou8 failed range ", __func__);
4560 ret = -EINVAL;
4561 goto exit;
4562 }
4563 if ((filterType < WLAN_HDD_DRIVER_MIRACAST_CFG_MIN_VAL ) ||
4564 (filterType > WLAN_HDD_DRIVER_MIRACAST_CFG_MAX_VAL))
4565 {
4566 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4567 "%s: Accepted Values are 0 to 2. 0-Disabled, 1-Source,"
4568 " 2-Sink ", __func__);
4569 ret = -EINVAL;
4570 goto exit;
4571 }
4572 //Filtertype value should be either 0-Disabled, 1-Source, 2-sink
4573 pHddCtx->drvr_miracast = filterType;
Kaushik, Sushant96122442014-10-21 16:40:18 +05304574 pScanInfo = &pHddCtx->scan_info;
4575 if (filterType && pScanInfo != NULL &&
4576 pHddCtx->scan_info.mScanPending)
4577 {
4578 /*Miracast Session started. Abort Scan */
4579 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4580 "%s, Aborting Scan For Miracast",__func__);
4581 hdd_abort_mac_scan(pHddCtx, pScanInfo->sessionId,
4582 eCSR_SCAN_ABORT_DEFAULT);
4583 }
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07004584 hdd_tx_rx_pkt_cnt_stat_timer_handler(pHddCtx);
Ganesh Kondabattini8f6e3b32014-08-25 16:07:54 +05304585 sme_SetMiracastMode(pHddCtx->hHal, pHddCtx->drvr_miracast);
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07004586 }
Leo Chang614d2072013-08-22 14:59:44 -07004587 else if (strncmp(command, "SETMCRATE", 9) == 0)
4588 {
Leo Chang614d2072013-08-22 14:59:44 -07004589 tANI_U8 *value = command;
4590 int targetRate;
Leo Chang1f98cbd2013-10-17 15:03:52 -07004591 tSirRateUpdateInd *rateUpdate;
4592 eHalStatus status;
Leo Chang614d2072013-08-22 14:59:44 -07004593
4594 /* Only valid for SAP mode */
4595 if (WLAN_HDD_SOFTAP != pAdapter->device_mode)
4596 {
4597 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4598 "%s: SAP mode is not running", __func__);
4599 ret = -EFAULT;
4600 goto exit;
4601 }
4602
4603 /* Move pointer to ahead of SETMCRATE<delimiter> */
4604 /* input value is in units of hundred kbps */
4605 value = value + 10;
4606 /* Convert the value from ascii to integer, decimal base */
4607 ret = kstrtouint(value, 10, &targetRate);
4608
Leo Chang1f98cbd2013-10-17 15:03:52 -07004609 rateUpdate = (tSirRateUpdateInd *)vos_mem_malloc(sizeof(tSirRateUpdateInd));
4610 if (NULL == rateUpdate)
Leo Chang614d2072013-08-22 14:59:44 -07004611 {
Leo Chang1f98cbd2013-10-17 15:03:52 -07004612 hddLog(VOS_TRACE_LEVEL_ERROR,
4613 "%s: SETMCRATE indication alloc fail", __func__);
4614 ret = -EFAULT;
4615 goto exit;
4616 }
4617 vos_mem_zero(rateUpdate, sizeof(tSirRateUpdateInd ));
4618
4619 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4620 "MC Target rate %d", targetRate);
4621 /* Ignore unicast */
4622 rateUpdate->ucastDataRate = -1;
4623 rateUpdate->mcastDataRate24GHz = targetRate;
4624 rateUpdate->mcastDataRate5GHz = targetRate;
4625 rateUpdate->mcastDataRate24GHzTxFlag = 0;
4626 rateUpdate->mcastDataRate5GHzTxFlag = 0;
4627 status = sme_SendRateUpdateInd(pHddCtx->hHal, rateUpdate);
4628 if (eHAL_STATUS_SUCCESS != status)
4629 {
4630 hddLog(VOS_TRACE_LEVEL_ERROR,
4631 "%s: SET_MC_RATE failed", __func__);
4632 vos_mem_free(rateUpdate);
4633 ret = -EFAULT;
4634 goto exit;
Leo Chang614d2072013-08-22 14:59:44 -07004635 }
4636 }
Rajeev79dbe4c2013-10-05 11:03:42 +05304637#ifdef FEATURE_WLAN_BATCH_SCAN
Rajeev Kumar8b373292014-01-08 20:36:55 -08004638 else if (strncmp(command, "WLS_BATCHING", 12) == 0)
Rajeev79dbe4c2013-10-05 11:03:42 +05304639 {
Rajeev Kumar8b373292014-01-08 20:36:55 -08004640 ret = hdd_handle_batch_scan_ioctl(pAdapter, &priv_data, command);
Rajeev79dbe4c2013-10-05 11:03:42 +05304641 }
4642#endif
Abhishek Singh00b71972016-01-07 10:51:04 +05304643#ifdef WLAN_FEATURE_RMC
4644 else if ((strncasecmp(command, "SETIBSSBEACONOUIDATA", 20) == 0) &&
4645 (WLAN_HDD_IBSS == pAdapter->device_mode))
4646 {
4647 int i = 0;
4648 tANI_U8 *ibss_ie;
4649 tANI_U32 command_len;
4650 tANI_U8 *value = command;
4651 tHalHandle hHal = pHddCtx->hHal;
4652 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
4653 tANI_U32 ibss_ie_length;
4654 tANI_U32 len, present;
4655 tANI_U8 *addIE;
4656 tANI_U8 *addIEData;
4657
4658 hddLog(LOG1,
4659 FL(" received command %s"),((char *) value));
4660 /* validate argument of command */
4661 if (strlen(value) <= 21)
4662 {
4663 hddLog(LOGE,
4664 FL("No arguements in command length %zu"), strlen(value));
4665 ret = -EFAULT;
4666 goto exit;
4667 }
4668
4669 /* moving to arguments of commands */
4670 value = value + 21;
4671 command_len = strlen(value);
4672
4673 /* oui_data can't be less than 3 bytes */
4674 if (command_len <= (2 * WLAN_HDD_IBSS_MIN_OUI_DATA_LENGTH))
4675 {
4676 hddLog(LOGE,
4677 FL("Invalid SETIBSSBEACONOUIDATA command length %d"),
4678 command_len);
4679 ret = -EFAULT;
4680 goto exit;
4681 }
4682 ibss_ie = vos_mem_malloc(command_len);
4683 if (!ibss_ie) {
4684 hddLog(LOGE,
4685 FL("Could not allocate memory for command length %d"),
4686 command_len);
4687 ret = -ENOMEM;
4688 goto exit;
4689 }
4690 vos_mem_zero(ibss_ie, command_len);
4691
4692 ibss_ie_length = hdd_parse_set_ibss_oui_data_command(value, ibss_ie,
4693 command_len);
4694 if (ibss_ie_length < (2 * WLAN_HDD_IBSS_MIN_OUI_DATA_LENGTH)) {
4695 hddLog(LOGE, FL("Could not parse command %s return length %d"),
4696 value, ibss_ie_length);
4697 ret = -EFAULT;
4698 vos_mem_free(ibss_ie);
4699 goto exit;
4700 }
4701
4702 hddLog(LOG1, FL("ibss_ie length %d ibss_ie:"), ibss_ie_length);
4703 while (i < ibss_ie_length)
4704 hddLog(LOG1, FL("0x%x"), ibss_ie[i++]);
4705
4706 /* Populate Vendor IE in Beacon */
4707 if ((ccmCfgGetInt(hHal,
4708 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG,
4709 &present)) != eHAL_STATUS_SUCCESS)
4710 {
4711 hddLog(LOGE,
4712 FL("unable to ftch WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG"));
4713 ret = -EFAULT;
4714 vos_mem_free(ibss_ie);
4715 goto exit;
4716 }
4717
4718 addIE = vos_mem_malloc(WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA_LEN);
4719 if (!addIE) {
4720 hddLog(LOGE,
4721 FL("Could not allocate memory for command length %d"),
4722 command_len);
4723 vos_mem_free(ibss_ie);
4724 ret = -ENOMEM;
4725 goto exit;
4726 }
4727 vos_mem_zero(addIE, WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA_LEN);
4728
4729 if (present)
4730 {
4731 if ((wlan_cfgGetStrLen(pMac,
4732 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, &len)) != eSIR_SUCCESS)
4733 {
4734 hddLog(LOGE,
4735 FL("unable to fetch WNI_CFG_PROBE_RSP_BCN_ADDNIE_LEN"));
4736 ret = -EFAULT;
4737 vos_mem_free(ibss_ie);
4738 vos_mem_free(addIE);
4739 goto exit;
4740 }
4741
4742 if (len <= WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA_LEN && len &&
4743 ((len + ibss_ie_length) <=
4744 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA_LEN))
4745 {
4746 if ((ccmCfgGetStr(hHal,
4747 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, addIE, &len))
4748 != eHAL_STATUS_SUCCESS)
4749 {
4750 hddLog(LOGE,
4751 FL("unable to fetch WNI_PROBE_RSP_BCN_ADDNIE_DATA"));
4752 ret = -EFAULT;
4753 vos_mem_free(ibss_ie);
4754 vos_mem_free(addIE);
4755 goto exit;
4756 }
4757 else
4758 {
4759 /* Curruntly only WPA IE is added before Vendor IE
4760 * so we can blindly place the Vendor IE after WPA
4761 * IE. If no WPA IE found replace all with Vendor IE.
4762 */
4763 len = hdd_find_ibss_wpa_ie_pos(addIE, len);
4764 }
4765 }
4766 else
4767 {
4768 hddLog(LOGE,
4769 FL("IE len exceed limit len %d,ibss_ie_length %d "),
4770 len, ibss_ie_length);
4771 ret = -EFAULT;
4772 vos_mem_free(addIE);
4773 vos_mem_free(ibss_ie);
4774 goto exit;
4775 }
4776 }
4777 else {
4778 len = 0;
4779 }
4780
4781 vos_mem_copy (addIE + len , ibss_ie, ibss_ie_length);
4782 len += ibss_ie_length;
4783
4784 if (ccmCfgSetStr(hHal,
4785 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, addIE, len, NULL,
4786 eANI_BOOLEAN_FALSE) != eHAL_STATUS_SUCCESS)
4787 {
4788 hddLog(LOGE,
4789 FL("unable to set WNI_CFG_PRBE_RSP_BCN_ADDNIE_DATA"));
4790 ret = -EFAULT;
4791 vos_mem_free(ibss_ie);
4792 vos_mem_free(addIE);
4793 goto exit;
4794 }
4795 vos_mem_free(addIE);
4796 if (ccmCfgSetInt(hHal,
4797 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 1,NULL,
4798 eANI_BOOLEAN_FALSE) != eHAL_STATUS_SUCCESS)
4799 {
4800 hddLog(LOGE,
4801 FL("unble to set WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG"));
4802 ret = -EFAULT;
4803 vos_mem_free(ibss_ie);
4804 goto exit;
4805 }
4806
4807 /* Populate Vendor IE in probe resp */
4808 if ((ccmCfgGetInt(hHal,
4809 WNI_CFG_PROBE_RSP_ADDNIE_FLAG,
4810 &present)) != eHAL_STATUS_SUCCESS)
4811 {
4812 hddLog(LOGE,
4813 FL("unable to fetch WNI_CFG_PROBE_RSP_ADDNIE_FLAG"));
4814 ret = -EFAULT;
4815 vos_mem_free(ibss_ie);
4816 goto exit;
4817 }
4818
4819 addIEData = vos_mem_malloc(WNI_CFG_PROBE_RSP_ADDNIE_DATA1_LEN);
4820 if (!addIEData) {
4821 hddLog(LOGE,
4822 FL("Could not allocate memory for command length %d"),
4823 command_len);
4824 vos_mem_free(ibss_ie);
4825 ret = -ENOMEM;
4826 goto exit;
4827 }
4828 vos_mem_zero(addIEData, WNI_CFG_PROBE_RSP_ADDNIE_DATA1_LEN);
4829
4830 if (present) {
4831 if (eSIR_SUCCESS != wlan_cfgGetStrLen(pMac,
4832 WNI_CFG_PROBE_RSP_ADDNIE_DATA1, &len)) {
4833 hddLog(LOGE,
4834 FL("unable to fetch WNI_CFG_PROBE_RSP_ADDNIE_DATA1"));
4835 ret = -EFAULT;
4836 vos_mem_free(ibss_ie);
4837 vos_mem_free(addIEData);
4838 goto exit;
4839 }
4840 if (len < WNI_CFG_PROBE_RSP_ADDNIE_DATA1_LEN && len &&
4841 (ibss_ie_length + len) <=
4842 WNI_CFG_PROBE_RSP_ADDNIE_DATA1_LEN) {
4843
4844 if ((ccmCfgGetStr(hHal,
4845 WNI_CFG_PROBE_RSP_ADDNIE_DATA1, addIEData, &len))
4846 != eHAL_STATUS_SUCCESS) {
4847 hddLog(LOGE,
4848 FL("unable fetch WNI_CFG_PROBE_RSP_ADDNIE_DATA1"));
4849 ret = -EFAULT;
4850 vos_mem_free(ibss_ie);
4851 vos_mem_free(addIEData);
4852 goto exit;
4853 }
4854 else {
4855 /* Curruntly only WPA IE is added before Vendor IE
4856 * so we can blindly place the Vendor IE after WPA
4857 * IE. If no WPA IE found replace all with Vendor IE.
4858 */
4859 len = hdd_find_ibss_wpa_ie_pos(addIEData, len);
4860 }
4861 }
4862 else
4863 {
4864 hddLog(LOGE,
4865 FL("IE len exceed limit len %d,ibss_ie_length %d "),
4866 len, ibss_ie_length);
4867 ret = -EFAULT;
4868 vos_mem_free(addIEData);
4869 vos_mem_free(ibss_ie);
4870 goto exit;
4871 }
4872 } /* probe rsp ADD IE present */
4873 else {
4874 /* probe rsp add IE is not present */
4875 len = 0;
4876 }
4877
4878 vos_mem_copy(addIEData +len , ibss_ie, ibss_ie_length);
4879 len += ibss_ie_length;
4880
4881 vos_mem_free(ibss_ie);
4882
4883 if (ccmCfgSetStr(hHal,
4884 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,
4885 (tANI_U8*)(addIEData),
4886 len, NULL,
4887 eANI_BOOLEAN_FALSE)
4888 == eHAL_STATUS_FAILURE) {
4889 hddLog(LOGE,
4890 FL("unable to copy to WNI_CFG_PROBE_RSP_ADDNIE_DATA1"));
4891 ret = -EFAULT;
4892 vos_mem_free(addIEData);
4893 goto exit;
4894 }
4895 vos_mem_free(addIEData);
4896 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
4897 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 1,NULL,
4898 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
4899 {
4900 hddLog(LOGE,
4901 FL("unable to copy WNI_CFG_PROBE_RSP_ADDNIE_FLAG"));
4902 ret = -EFAULT;
4903 goto exit;
4904 }
4905 }
4906 else if (strncasecmp(command, "SETRMCENABLE", 12) == 0)
4907 {
4908 tANI_U8 *value = command;
4909 tANI_U8 ucRmcEnable = 0;
4910 int status;
4911
4912 if ((WLAN_HDD_IBSS != pAdapter->device_mode) &&
4913 (WLAN_HDD_SOFTAP != pAdapter->device_mode))
4914 {
4915 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4916 "Received SETRMCENABLE command in invalid mode %d "
4917 "SETRMCENABLE command is only allowed in IBSS or SOFTAP mode",
4918 pAdapter->device_mode);
4919 ret = -EINVAL;
4920 goto exit;
4921 }
4922
4923 status = hdd_parse_setrmcenable_command(value, &ucRmcEnable);
4924 if (status)
4925 {
4926 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4927 "Invalid SETRMCENABLE command ");
4928 ret = -EINVAL;
4929 goto exit;
4930 }
4931
4932 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4933 "%s: ucRmcEnable %d ", __func__, ucRmcEnable);
4934
4935 if (TRUE == ucRmcEnable)
4936 {
4937 status = sme_EnableRMC( (tHalHandle)(pHddCtx->hHal),
4938 pAdapter->sessionId );
4939 }
4940 else if(FALSE == ucRmcEnable)
4941 {
4942 status = sme_DisableRMC( (tHalHandle)(pHddCtx->hHal),
4943 pAdapter->sessionId );
4944 }
4945 else
4946 {
4947 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4948 "Invalid SETRMCENABLE command %d", ucRmcEnable);
4949 ret = -EINVAL;
4950 goto exit;
4951 }
4952
4953 if (VOS_STATUS_SUCCESS != status)
4954 {
4955 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4956 "%s: SETRMC %d failed status %d", __func__, ucRmcEnable,
4957 status);
4958 ret = -EINVAL;
4959 goto exit;
4960 }
4961 }
4962 else if (strncasecmp(command, "SETRMCACTIONPERIOD", 18) == 0)
4963 {
4964 tANI_U8 *value = command;
4965 tANI_U32 uActionPeriod = 0;
4966 int status;
4967
4968 if ((WLAN_HDD_IBSS != pAdapter->device_mode) &&
4969 (WLAN_HDD_SOFTAP != pAdapter->device_mode))
4970 {
4971 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4972 "Received SETRMC command in invalid mode %d "
4973 "SETRMC command is only allowed in IBSS or SOFTAP mode",
4974 pAdapter->device_mode);
4975 ret = -EINVAL;
4976 goto exit;
4977 }
4978
4979 status = hdd_parse_setrmcactionperiod_command(value, &uActionPeriod);
4980 if (status)
4981 {
4982 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4983 "Invalid SETRMCACTIONPERIOD command ");
4984 ret = -EINVAL;
4985 goto exit;
4986 }
4987
4988 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4989 "%s: uActionPeriod %d ", __func__, uActionPeriod);
4990
4991 if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_RMC_ACTION_PERIOD_FREQUENCY,
4992 uActionPeriod, NULL, eANI_BOOLEAN_FALSE))
4993 {
4994 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4995 "%s: Could not set SETRMCACTIONPERIOD %d", __func__, uActionPeriod);
4996 ret = -EINVAL;
4997 goto exit;
4998 }
4999
5000 }
5001 else if (strncasecmp(command, "GETIBSSPEERINFOALL", 18) == 0)
5002 {
5003 /* Peer Info All Command */
5004 int status = eHAL_STATUS_SUCCESS;
5005 hdd_station_ctx_t *pHddStaCtx = NULL;
5006 char *extra = NULL;
5007 int idx = 0, length = 0;
5008 v_MACADDR_t *macAddr;
5009 v_U32_t txRateMbps = 0, numOfBytestoPrint = 0;
5010
5011 if (WLAN_HDD_IBSS == pAdapter->device_mode)
5012 {
5013 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
5014 }
5015 else
5016 {
5017 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
5018 "%s: pAdapter is not valid for this device mode",
5019 __func__);
5020 ret = -EINVAL;
5021 goto exit;
5022 }
5023
5024 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
5025 "%s: Received GETIBSSPEERINFOALL Command", __func__);
5026
5027
5028 /* Handle the command */
5029 status = hdd_cfg80211_get_ibss_peer_info_all(pAdapter);
5030 if (VOS_STATUS_SUCCESS == status)
5031 {
5032 /* The variable extra needed to be allocated on the heap since
5033 * amount of memory required to copy the data for 32 devices
5034 * exceeds the size of 1024 bytes of default stack size. On
5035 * 64 bit devices, the default max stack size of 2048 bytes
5036 */
5037 extra = kmalloc(WLAN_MAX_BUF_SIZE, GFP_KERNEL);
5038
5039 if (NULL == extra)
5040 {
5041 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5042 "%s:kmalloc failed", __func__);
5043 ret = -EINVAL;
5044 goto exit;
5045 }
5046
5047 /* Copy number of stations */
5048 length = scnprintf( extra, WLAN_MAX_BUF_SIZE, "%d ",
5049 pHddStaCtx->ibss_peer_info.numIBSSPeers);
5050 numOfBytestoPrint = length;
5051 for (idx = 0; idx < pHddStaCtx->ibss_peer_info.numIBSSPeers; idx++)
5052 {
5053 macAddr =
5054 hdd_wlan_get_ibss_mac_addr_from_staid(pAdapter,
5055 pHddStaCtx->ibss_peer_info.ibssPeerList[idx].staIdx);
5056 if (NULL != macAddr)
5057 {
5058 txRateMbps =
5059 ((pHddStaCtx->ibss_peer_info.ibssPeerList[idx].txRate)*500*1000)/1000000;
5060
5061 length += scnprintf( (extra + length), WLAN_MAX_BUF_SIZE - length,
5062 "%02x:%02x:%02x:%02x:%02x:%02x %d %d ",
5063 macAddr->bytes[0], macAddr->bytes[1], macAddr->bytes[2],
5064 macAddr->bytes[3], macAddr->bytes[4], macAddr->bytes[5],
5065 (int)txRateMbps,
5066 (int)pHddStaCtx->ibss_peer_info.ibssPeerList[idx].rssi);
5067 }
5068 else
5069 {
5070 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5071 "%s: MAC ADDR is NULL for staIdx: %d", __func__,
5072 pHddStaCtx->ibss_peer_info.ibssPeerList[idx].staIdx);
5073 }
5074
5075 /*
5076 * VOS_TRACE() macro has limitation of 512 bytes for the print
5077 * buffer. Hence printing the data in two chunks. The first chunk
5078 * will have the data for 16 devices and the second chunk will
5079 * have the rest.
5080 */
5081 if (idx < NUM_OF_STA_DATA_TO_PRINT)
5082 {
5083 numOfBytestoPrint = length;
5084 }
5085 }
5086
5087 /*
5088 * Copy the data back into buffer, if the data to copy is
5089 * morethan 512 bytes than we will split the data and do
5090 * it in two shots
5091 */
5092 if (copy_to_user(priv_data.buf, extra, numOfBytestoPrint))
5093 {
5094 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5095 "%s: Copy into user data buffer failed ", __func__);
5096 ret = -EFAULT;
5097 kfree(extra);
5098 goto exit;
5099 }
5100 priv_data.buf[numOfBytestoPrint] = '\0';
5101 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_MED,
5102 "%s", priv_data.buf);
5103
5104 if (length > numOfBytestoPrint)
5105 {
5106 if (copy_to_user(priv_data.buf + numOfBytestoPrint,
5107 extra + numOfBytestoPrint,
5108 length - numOfBytestoPrint + 1))
5109 {
5110 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5111 "%s: Copy into user data buffer failed ", __func__);
5112 ret = -EFAULT;
5113 kfree(extra);
5114 goto exit;
5115 }
5116 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_MED,
5117 "%s", &priv_data.buf[numOfBytestoPrint]);
5118 }
5119
5120 /* Free temporary buffer */
5121 kfree(extra);
5122 }
5123
5124 else
5125 {
5126 /* Command failed, log error */
5127 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5128 "%s: GETIBSSPEERINFOALL command failed with status code %d",
5129 __func__, status);
5130 ret = -EINVAL;
5131 goto exit;
5132 }
5133 ret = 0;
5134 }
5135 else if(strncasecmp(command, "GETIBSSPEERINFO", 15) == 0)
5136 {
5137 /* Peer Info <Peer Addr> command */
5138 tANI_U8 *value = command;
5139 VOS_STATUS status;
5140 hdd_station_ctx_t *pHddStaCtx = NULL;
5141 char extra[128] = { 0 };
5142 v_U32_t length = 0;
5143 v_U8_t staIdx = 0;
5144 v_U32_t txRateMbps = 0;
5145 v_MACADDR_t peerMacAddr;
5146
5147 if (WLAN_HDD_IBSS == pAdapter->device_mode)
5148 {
5149 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
5150 }
5151 else
5152 {
5153 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
5154 "%s: pAdapter is not valid for this device mode",
5155 __func__);
5156 ret = -EINVAL;
5157 goto exit;
5158 }
5159
5160 /* if there are no peers, no need to continue with the command */
5161 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
5162 "%s: Received GETIBSSPEERINFO Command", __func__);
5163
5164 if (eConnectionState_IbssConnected != pHddStaCtx->conn_info.connState)
5165 {
5166 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
5167 "%s:No IBSS Peers coalesced", __func__);
5168 ret = -EINVAL;
5169 goto exit;
5170 }
5171
5172 /* Parse the incoming command buffer */
5173 status = hdd_parse_get_ibss_peer_info(value, &peerMacAddr);
5174 if (VOS_STATUS_SUCCESS != status)
5175 {
5176 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5177 "%s: Invalid GETIBSSPEERINFO command", __func__);
5178 ret = -EINVAL;
5179 goto exit;
5180 }
5181
5182 /* Get station index for the peer mac address */
5183 hdd_Ibss_GetStaId(pHddStaCtx, &peerMacAddr, &staIdx);
5184
5185 if (staIdx > HDD_MAX_NUM_IBSS_STA)
5186 {
5187 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5188 "%s: Invalid StaIdx %d returned", __func__, staIdx);
5189 ret = -EINVAL;
5190 goto exit;
5191 }
5192
5193 /* Handle the command */
5194 status = hdd_cfg80211_get_ibss_peer_info(pAdapter, staIdx);
5195 if (VOS_STATUS_SUCCESS == status)
5196 {
5197 v_U32_t txRate = pHddStaCtx->ibss_peer_info.ibssPeerList[0].txRate;
5198 txRateMbps = (txRate * 500 * 1000)/1000000;
5199
5200 length = scnprintf( extra, sizeof(extra), "%d %d", (int)txRateMbps,
5201 (int)pHddStaCtx->ibss_peer_info.ibssPeerList[0].rssi);
5202
5203 /* Copy the data back into buffer */
5204 if (copy_to_user(priv_data.buf, &extra, length+ 1))
5205 {
5206 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5207 "%s: copy data to user buffer failed GETIBSSPEERINFO command",
5208 __func__);
5209 ret = -EFAULT;
5210 goto exit;
5211 }
5212 }
5213 else
5214 {
5215 /* Command failed, log error */
5216 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5217 "%s: GETIBSSPEERINFO command failed with status code %d",
5218 __func__, status);
5219 ret = -EINVAL;
5220 goto exit;
5221 }
5222
5223 /* Success ! */
5224 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_MED,
5225 "%s", priv_data.buf);
5226 ret = 0;
5227 }
5228 else if (strncasecmp(command, "SETRMCTXRATE", 12) == 0)
5229 {
5230 tANI_U8 *value = command;
5231 tANI_U32 uRate = 0;
5232 tTxrateinfoflags txFlags = 0;
5233 tSirRateUpdateInd *rateUpdateParams;
5234 int status;
5235
5236 if ((WLAN_HDD_IBSS != pAdapter->device_mode) &&
5237 (WLAN_HDD_SOFTAP != pAdapter->device_mode))
5238 {
5239 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5240 "Received SETRMCTXRATE command in invalid mode %d "
5241 "SETRMC command is only allowed in IBSS or SOFTAP mode",
5242 pAdapter->device_mode);
5243 ret = -EINVAL;
5244 goto exit;
5245 }
5246
5247 status = hdd_parse_setrmcrate_command(value, &uRate, &txFlags);
5248 if (status)
5249 {
5250 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5251 "Invalid SETRMCTXRATE command ");
5252 ret = -EINVAL;
5253 goto exit;
5254 }
5255
5256 rateUpdateParams = vos_mem_malloc(sizeof(tSirRateUpdateInd));
5257 if (NULL == rateUpdateParams)
5258 {
5259 ret = -EINVAL;
5260 goto exit;
5261 }
5262
5263 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
5264 "%s: uRate %d ", __func__, uRate);
5265
5266 vos_mem_zero(rateUpdateParams, sizeof(tSirRateUpdateInd ));
5267
5268 /* -1 implies ignore this param */
5269 rateUpdateParams->ucastDataRate = -1;
5270
5271 /*
5272 * Fill the user specifieed RMC rate param
5273 * and the derived tx flags.
5274 */
5275 rateUpdateParams->rmcDataRate = uRate;
5276 rateUpdateParams->rmcDataRateTxFlag = txFlags;
5277
5278 status = sme_SendRateUpdateInd((tHalHandle)(pHddCtx->hHal), rateUpdateParams);
5279 }
5280 else if (strncasecmp(command, "SETIBSSTXFAILEVENT", 18) == 0 )
5281 {
5282 char *value;
5283 tANI_U8 tx_fail_count = 0;
5284 tANI_U16 pid = 0;
5285
5286 value = command;
5287
5288 ret = hdd_ParseIBSSTXFailEventParams(value, &tx_fail_count, &pid);
5289
5290 if (0 != ret)
5291 {
5292 hddLog(VOS_TRACE_LEVEL_INFO,
5293 "%s: Failed to parse SETIBSSTXFAILEVENT arguments",
5294 __func__);
5295 goto exit;
5296 }
5297
5298 hddLog(VOS_TRACE_LEVEL_INFO, "%s: tx_fail_cnt=%hhu, pid=%hu",
5299 __func__, tx_fail_count, pid);
5300
5301 if (0 == tx_fail_count)
5302 {
5303 // Disable TX Fail Indication
5304 if (eHAL_STATUS_SUCCESS ==
5305 sme_TXFailMonitorStartStopInd(pHddCtx->hHal,
5306 tx_fail_count,
5307 NULL))
5308 {
5309 cesium_pid = 0;
5310 }
5311 else
5312 {
5313 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5314 "%s: failed to disable TX Fail Event ", __func__);
5315 ret = -EINVAL;
5316 }
5317 }
5318 else
5319 {
5320 if (eHAL_STATUS_SUCCESS ==
5321 sme_TXFailMonitorStartStopInd(pHddCtx->hHal,
5322 tx_fail_count,
5323 (void*)hdd_tx_fail_ind_callback))
5324 {
5325 cesium_pid = pid;
5326 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
5327 "%s: Registered Cesium pid %u", __func__,
5328 cesium_pid);
5329 }
5330 else
5331 {
5332 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5333 "%s: Failed to enable TX Fail Monitoring", __func__);
5334 ret = -EINVAL;
5335 }
5336 }
5337 }
5338
5339#endif /* WLAN_FEATURE_RMC */
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005340#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07005341 else if (strncmp(command, "SETCCXROAMSCANCHANNELS", 22) == 0)
5342 {
5343 tANI_U8 *value = command;
5344 tANI_U8 ChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
5345 tANI_U8 numChannels = 0;
5346 eHalStatus status = eHAL_STATUS_SUCCESS;
5347
5348 status = hdd_parse_channellist(value, ChannelList, &numChannels);
5349 if (eHAL_STATUS_SUCCESS != status)
5350 {
5351 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5352 "%s: Failed to parse channel list information", __func__);
5353 ret = -EINVAL;
5354 goto exit;
5355 }
5356
5357 if (numChannels > WNI_CFG_VALID_CHANNEL_LIST_LEN)
5358 {
5359 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5360 "%s: number of channels (%d) supported exceeded max (%d)", __func__,
5361 numChannels, WNI_CFG_VALID_CHANNEL_LIST_LEN);
5362 ret = -EINVAL;
5363 goto exit;
5364 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005365 status = sme_SetEseRoamScanChannelList((tHalHandle)(pHddCtx->hHal),
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07005366 ChannelList,
5367 numChannels);
5368 if (eHAL_STATUS_SUCCESS != status)
5369 {
5370 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5371 "%s: Failed to update channel list information", __func__);
5372 ret = -EINVAL;
5373 goto exit;
5374 }
5375 }
5376 else if (strncmp(command, "GETTSMSTATS", 11) == 0)
5377 {
5378 tANI_U8 *value = command;
5379 char extra[128] = {0};
5380 int len = 0;
5381 tANI_U8 tid = 0;
5382 hdd_station_ctx_t *pHddStaCtx = NULL;
5383 tAniTrafStrmMetrics tsmMetrics;
5384 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
5385
5386 /* if not associated, return error */
5387 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
5388 {
5389 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "%s:Not associated!",__func__);
5390 ret = -EINVAL;
5391 goto exit;
5392 }
5393
5394 /* Move pointer to ahead of GETTSMSTATS<delimiter> */
5395 value = value + 12;
5396 /* Convert the value from ascii to integer */
5397 ret = kstrtou8(value, 10, &tid);
5398 if (ret < 0)
5399 {
5400 /* If the input value is greater than max value of datatype, then also
5401 kstrtou8 fails */
5402 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5403 "%s: kstrtou8 failed range [%d - %d]", __func__,
5404 TID_MIN_VALUE,
5405 TID_MAX_VALUE);
5406 ret = -EINVAL;
5407 goto exit;
5408 }
5409
5410 if ((tid < TID_MIN_VALUE) || (tid > TID_MAX_VALUE))
5411 {
5412 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5413 "tid value %d is out of range"
5414 " (Min: %d Max: %d)", tid,
5415 TID_MIN_VALUE,
5416 TID_MAX_VALUE);
5417 ret = -EINVAL;
5418 goto exit;
5419 }
5420
5421 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
5422 "%s: Received Command to get tsm stats tid = %d", __func__, tid);
5423
5424 if (VOS_STATUS_SUCCESS != hdd_get_tsm_stats(pAdapter, tid, &tsmMetrics))
5425 {
5426 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5427 "%s: failed to get tsm stats", __func__);
5428 ret = -EFAULT;
5429 goto exit;
5430 }
5431
5432 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
5433 "UplinkPktQueueDly(%d)\n"
5434 "UplinkPktQueueDlyHist[0](%d)\n"
5435 "UplinkPktQueueDlyHist[1](%d)\n"
5436 "UplinkPktQueueDlyHist[2](%d)\n"
5437 "UplinkPktQueueDlyHist[3](%d)\n"
Arun Kumar Khandavallie8768212014-02-17 16:43:34 +05305438 "UplinkPktTxDly(%u)\n"
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07005439 "UplinkPktLoss(%d)\n"
5440 "UplinkPktCount(%d)\n"
5441 "RoamingCount(%d)\n"
5442 "RoamingDly(%d)", tsmMetrics.UplinkPktQueueDly,
5443 tsmMetrics.UplinkPktQueueDlyHist[0],
5444 tsmMetrics.UplinkPktQueueDlyHist[1],
5445 tsmMetrics.UplinkPktQueueDlyHist[2],
5446 tsmMetrics.UplinkPktQueueDlyHist[3],
5447 tsmMetrics.UplinkPktTxDly, tsmMetrics.UplinkPktLoss,
5448 tsmMetrics.UplinkPktCount, tsmMetrics.RoamingCount, tsmMetrics.RoamingDly);
5449
5450 /* Output TSM stats is of the format
5451 GETTSMSTATS [PktQueueDly] [PktQueueDlyHist[0]]:[PktQueueDlyHist[1]] ...[RoamingDly]
5452 eg., GETTSMSTATS 10 1:0:0:161 20 1 17 8 39800 */
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08005453 len = scnprintf(extra, sizeof(extra), "%s %d %d:%d:%d:%d %u %d %d %d %d", command,
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07005454 tsmMetrics.UplinkPktQueueDly, tsmMetrics.UplinkPktQueueDlyHist[0],
5455 tsmMetrics.UplinkPktQueueDlyHist[1], tsmMetrics.UplinkPktQueueDlyHist[2],
5456 tsmMetrics.UplinkPktQueueDlyHist[3], tsmMetrics.UplinkPktTxDly,
5457 tsmMetrics.UplinkPktLoss, tsmMetrics.UplinkPktCount, tsmMetrics.RoamingCount,
5458 tsmMetrics.RoamingDly);
5459
Ratnam Rachurid53009c2015-08-07 13:59:00 +05305460 len = VOS_MIN(priv_data.total_len, len + 1);
5461 if (copy_to_user(priv_data.buf, &extra, len)) {
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07005462 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5463 "%s: failed to copy data to user buffer", __func__);
5464 ret = -EFAULT;
5465 goto exit;
5466 }
5467 }
5468 else if (strncmp(command, "SETCCKMIE", 9) == 0)
5469 {
5470 tANI_U8 *value = command;
5471 tANI_U8 *cckmIe = NULL;
5472 tANI_U8 cckmIeLen = 0;
5473 eHalStatus status = eHAL_STATUS_SUCCESS;
5474
5475 status = hdd_parse_get_cckm_ie(value, &cckmIe, &cckmIeLen);
5476 if (eHAL_STATUS_SUCCESS != status)
5477 {
5478 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5479 "%s: Failed to parse cckm ie data", __func__);
5480 ret = -EINVAL;
5481 goto exit;
5482 }
5483
5484 if (cckmIeLen > DOT11F_IE_RSN_MAX_LEN)
5485 {
5486 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5487 "%s: CCKM Ie input length is more than max[%d]", __func__,
5488 DOT11F_IE_RSN_MAX_LEN);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08005489 vos_mem_free(cckmIe);
5490 cckmIe = NULL;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07005491 ret = -EINVAL;
5492 goto exit;
5493 }
5494 sme_SetCCKMIe((tHalHandle)(pHddCtx->hHal), pAdapter->sessionId, cckmIe, cckmIeLen);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08005495 vos_mem_free(cckmIe);
5496 cckmIe = NULL;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07005497 }
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08005498 else if (strncmp(command, "CCXBEACONREQ", 12) == 0)
5499 {
5500 tANI_U8 *value = command;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005501 tCsrEseBeaconReq eseBcnReq;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08005502 eHalStatus status = eHAL_STATUS_SUCCESS;
Srinivas Girigowda0c6d7fe2014-05-28 18:18:10 -07005503
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005504 status = hdd_parse_ese_beacon_req(value, &eseBcnReq);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08005505 if (eHAL_STATUS_SUCCESS != status)
5506 {
5507 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005508 "%s: Failed to parse ese beacon req", __func__);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08005509 ret = -EINVAL;
5510 goto exit;
5511 }
Srinivas Girigowda0c6d7fe2014-05-28 18:18:10 -07005512 if (!hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))) {
5513 hddLog(VOS_TRACE_LEVEL_INFO, FL("Not associated"));
5514 hdd_indicateEseBcnReportNoResults (pAdapter,
5515 eseBcnReq.bcnReq[0].measurementToken,
5516 0x02, //BIT(1) set for measurement done
5517 0); // no BSS
5518 goto exit;
5519 }
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08005520
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005521 status = sme_SetEseBeaconRequest((tHalHandle)(pHddCtx->hHal), pAdapter->sessionId, &eseBcnReq);
5522 if (eHAL_STATUS_SUCCESS != status)
5523 {
5524 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5525 "%s: sme_SetEseBeaconRequest failed (%d)", __func__, status);
5526 ret = -EINVAL;
5527 goto exit;
5528 }
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08005529 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005530#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
c_hpothu92367912014-05-01 15:18:17 +05305531 else if (strncmp(command, "GETBCNMISSRATE", 14) == 0)
5532 {
5533 eHalStatus status;
5534 char buf[32], len;
5535 long waitRet;
5536 bcnMissRateContext_t getBcnMissRateCtx;
5537
5538 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
5539
5540 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
5541 {
5542 hddLog(VOS_TRACE_LEVEL_WARN,
5543 FL("GETBCNMISSRATE: STA is not in connected state"));
5544 ret = -1;
5545 goto exit;
5546 }
5547
5548 init_completion(&(getBcnMissRateCtx.completion));
5549 getBcnMissRateCtx.magic = BCN_MISS_RATE_CONTEXT_MAGIC;
5550
5551 status = sme_getBcnMissRate((tHalHandle)(pHddCtx->hHal),
5552 pAdapter->sessionId,
5553 (void *)getBcnMissRateCB,
5554 (void *)(&getBcnMissRateCtx));
5555 if( eHAL_STATUS_SUCCESS != status)
5556 {
5557 hddLog(VOS_TRACE_LEVEL_INFO,
5558 FL("GETBCNMISSRATE: fail to post WDA cmd"));
5559 ret = -EINVAL;
5560 goto exit;
5561 }
5562
5563 waitRet = wait_for_completion_interruptible_timeout
5564 (&getBcnMissRateCtx.completion, BCN_MISS_RATE_TIME);
5565 if(waitRet <= 0)
5566 {
5567 hddLog(VOS_TRACE_LEVEL_ERROR,
5568 FL("failed to wait on bcnMissRateComp %d"), ret);
5569
5570 //Make magic number to zero so that callback is not called.
5571 spin_lock(&hdd_context_lock);
5572 getBcnMissRateCtx.magic = 0x0;
5573 spin_unlock(&hdd_context_lock);
5574 ret = -EINVAL;
5575 goto exit;
5576 }
5577
5578 hddLog(VOS_TRACE_LEVEL_INFO,
5579 FL("GETBCNMISSRATE: bcnMissRate: %d"), gbcnMissRate);
5580
5581 len = snprintf(buf, sizeof(buf), "GETBCNMISSRATE %d", gbcnMissRate);
5582 if (copy_to_user(priv_data.buf, &buf, len + 1))
5583 {
5584 hddLog(VOS_TRACE_LEVEL_ERROR,
5585 "%s: failed to copy data to user buffer", __func__);
5586 ret = -EFAULT;
5587 goto exit;
5588 }
5589 ret = len;
5590 }
Atul Mittal87ec2422014-09-24 13:12:50 +05305591#ifdef FEATURE_WLAN_TDLS
5592 else if (strncmp(command, "TDLSSECONDARYCHANNELOFFSET", 26) == 0) {
5593 tANI_U8 *value = command;
5594 int set_value;
5595 /* Move pointer to ahead of TDLSOFFCH*/
5596 value += 26;
c_manjeebbc40212015-12-08 13:52:59 +05305597 if (!(sscanf(value, "%d", &set_value))) {
5598 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
5599 FL("No input identified"));
5600 ret = -EINVAL;
5601 goto exit;
5602 }
5603
Atul Mittal87ec2422014-09-24 13:12:50 +05305604 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
5605 "%s: Tdls offchannel offset:%d",
5606 __func__, set_value);
5607 ret = iw_set_tdlssecoffchanneloffset(pHddCtx, set_value);
5608 if (ret < 0)
5609 {
5610 ret = -EINVAL;
5611 goto exit;
5612 }
5613
5614 } else if (strncmp(command, "TDLSOFFCHANNELMODE", 18) == 0) {
5615 tANI_U8 *value = command;
5616 int set_value;
5617 /* Move pointer to ahead of tdlsoffchnmode*/
5618 value += 18;
c_manjee82323892015-12-08 12:40:34 +05305619 ret = sscanf(value, "%d", &set_value);
5620 if (ret != 1) {
5621 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
5622 FL("No input identified"));
5623 ret = -EINVAL;
5624 goto exit;
5625 }
Atul Mittal87ec2422014-09-24 13:12:50 +05305626 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
5627 "%s: Tdls offchannel mode:%d",
5628 __func__, set_value);
5629 ret = iw_set_tdlsoffchannelmode(pAdapter, set_value);
5630 if (ret < 0)
5631 {
5632 ret = -EINVAL;
5633 goto exit;
5634 }
5635 } else if (strncmp(command, "TDLSOFFCHANNEL", 14) == 0) {
5636 tANI_U8 *value = command;
5637 int set_value;
5638 /* Move pointer to ahead of TDLSOFFCH*/
5639 value += 14;
c_manjeef6ccaf52015-12-08 11:52:11 +05305640 ret = sscanf(value, "%d", &set_value);
5641 if (ret != 1) {
5642 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5643 "Wrong value is given for hdd_set_tdls_offchannel");
5644 ret = -EINVAL;
5645 goto exit;
5646 }
5647
Atul Mittal87ec2422014-09-24 13:12:50 +05305648 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
5649 "%s: Tdls offchannel num: %d",
5650 __func__, set_value);
5651 ret = iw_set_tdlsoffchannel(pHddCtx, set_value);
5652 if (ret < 0)
5653 {
5654 ret = -EINVAL;
5655 goto exit;
5656 }
5657 }
5658#endif
Satyanarayana Dash72806012014-12-02 14:30:08 +05305659 else if (strncmp(command, "GETFWSTATS", 10) == 0)
5660 {
5661 eHalStatus status;
5662 char *buf = NULL;
5663 char len;
5664 long waitRet;
5665 fwStatsContext_t fwStatsCtx;
Abhishek Singh08aa7762014-12-16 13:59:03 +05305666 tSirFwStatsResult *fwStatsRsp = &(pAdapter->fwStatsRsp);
Satyanarayana Dash72806012014-12-02 14:30:08 +05305667 tANI_U8 *ptr = command;
5668 int stats = *(ptr + 11) - '0';
5669
5670 hddLog(VOS_TRACE_LEVEL_INFO, FL("stats = %d "),stats);
5671 if (!IS_FEATURE_FW_STATS_ENABLE)
5672 {
5673 hddLog(VOS_TRACE_LEVEL_INFO,
5674 FL("Get Firmware stats feature not supported"));
5675 ret = -EINVAL;
5676 goto exit;
5677 }
5678
5679 if (FW_STATS_MAX <= stats || 0 >= stats)
5680 {
5681 hddLog(VOS_TRACE_LEVEL_INFO,
5682 FL(" stats %d not supported"),stats);
5683 ret = -EINVAL;
5684 goto exit;
5685 }
5686
5687 init_completion(&(fwStatsCtx.completion));
5688 fwStatsCtx.magic = FW_STATS_CONTEXT_MAGIC;
5689 fwStatsCtx.pAdapter = pAdapter;
5690 fwStatsRsp->type = 0;
5691 status = sme_GetFwStats( (tHalHandle)pHddCtx->hHal, stats,
Abhishek Singh08aa7762014-12-16 13:59:03 +05305692 &fwStatsCtx, hdd_FWStatisCB);
Satyanarayana Dash72806012014-12-02 14:30:08 +05305693 if (eHAL_STATUS_SUCCESS != status)
5694 {
5695 hddLog(VOS_TRACE_LEVEL_ERROR,
5696 FL(" fail to post WDA cmd status = %d"), status);
5697 ret = -EINVAL;
5698 goto exit;
5699 }
5700 waitRet = wait_for_completion_timeout
5701 (&(fwStatsCtx.completion), FW_STATE_WAIT_TIME);
5702 if (waitRet <= 0)
5703 {
5704 hddLog(VOS_TRACE_LEVEL_ERROR,
5705 FL("failed to wait on GwtFwstats"));
5706 //Make magic number to zero so that callback is not executed.
5707 spin_lock(&hdd_context_lock);
5708 fwStatsCtx.magic = 0x0;
5709 spin_unlock(&hdd_context_lock);
5710 ret = -EINVAL;
5711 goto exit;
5712 }
5713 if (fwStatsRsp->type)
5714 {
5715 buf = kmalloc(FW_STATE_RSP_LEN, GFP_KERNEL);
5716 if (!buf)
5717 {
5718 hddLog(VOS_TRACE_LEVEL_ERROR,
5719 FL(" failed to allocate memory"));
5720 ret = -ENOMEM;
5721 goto exit;
5722 }
5723 switch( fwStatsRsp->type )
5724 {
5725 case FW_UBSP_STATS:
5726 {
5727 len = snprintf(buf, FW_STATE_RSP_LEN,
5728 "GETFWSTATS: ubsp_enter_cnt %d ubsp_jump_ddr_cnt %d",
Abhishek Singh08aa7762014-12-16 13:59:03 +05305729 fwStatsRsp->fwStatsData.ubspStats.ubsp_enter_cnt,
5730 fwStatsRsp->fwStatsData.ubspStats.ubsp_jump_ddr_cnt);
Satyanarayana Dash72806012014-12-02 14:30:08 +05305731 }
5732 break;
5733 default:
5734 {
5735 hddLog(VOS_TRACE_LEVEL_ERROR, FL( "No handling for stats type %d"),fwStatsRsp->type);
5736 ret = -EFAULT;
5737 kfree(buf);
5738 goto exit;
5739 }
5740 }
5741 if (copy_to_user(priv_data.buf, buf, len + 1))
5742 {
5743 hddLog(VOS_TRACE_LEVEL_ERROR,
5744 FL(" failed to copy data to user buffer"));
5745 ret = -EFAULT;
5746 kfree(buf);
5747 goto exit;
5748 }
5749 ret = len;
5750 kfree(buf);
5751 }
5752 else
5753 {
5754 hddLog(VOS_TRACE_LEVEL_ERROR,
5755 FL("failed to fetch the stats"));
5756 ret = -EFAULT;
5757 goto exit;
5758 }
5759
5760 }
Agarwal Ashish8bd53ae2015-06-12 18:03:45 +05305761 else if (strncasecmp(command, "SET_FCC_CHANNEL", 15) == 0)
5762 {
5763 /*
5764 * this command wld be called by user-space when it detects WLAN
5765 * ON after airplane mode is set. When APM is set, WLAN turns off.
5766 * But it can be turned back on. Otherwise; when APM is turned back
5767 * off, WLAN wld turn back on. So at that point the command is
5768 * expected to come down. 0 means disable, 1 means enable. The
5769 * constraint is removed when parameter 1 is set or different
5770 * country code is set
5771 */
5772 ret = hdd_cmd_setFccChannel(pHddCtx, command, 15);
5773 }
Mahesh A Saptasagarbeca12c2015-09-07 16:21:06 +05305774 else if (strncasecmp(command, "DISABLE_CA_EVENT", 16) == 0)
5775 {
5776 ret = hdd_enable_disable_ca_event(pHddCtx, command, 16);
5777 }
Madan Mohan Koyyalamudif9bdd4e2012-10-30 18:05:03 -07005778 else {
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05305779 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
5780 TRACE_CODE_HDD_UNSUPPORTED_IOCTL,
5781 pAdapter->sessionId, 0));
Satyanarayana Dash72806012014-12-02 14:30:08 +05305782 hddLog( VOS_TRACE_LEVEL_WARN, FL("Unsupported GUI command %s"),
5783 command);
Madan Mohan Koyyalamudif9bdd4e2012-10-30 18:05:03 -07005784 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005785 }
5786exit:
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305787 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07005788 if (command)
5789 {
5790 kfree(command);
5791 }
5792 return ret;
5793}
5794
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07005795#ifdef CONFIG_COMPAT
5796static int hdd_driver_compat_ioctl(hdd_adapter_t *pAdapter, struct ifreq *ifr)
5797{
5798 struct {
5799 compat_uptr_t buf;
5800 int used_len;
5801 int total_len;
5802 } compat_priv_data;
5803 hdd_priv_data_t priv_data;
5804 int ret = 0;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07005805
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07005806 /*
5807 * Note that pAdapter and ifr have already been verified by caller,
5808 * and HDD context has also been validated
5809 */
5810 if (copy_from_user(&compat_priv_data, ifr->ifr_data,
5811 sizeof(compat_priv_data))) {
5812 ret = -EFAULT;
5813 goto exit;
5814 }
5815 priv_data.buf = compat_ptr(compat_priv_data.buf);
5816 priv_data.used_len = compat_priv_data.used_len;
5817 priv_data.total_len = compat_priv_data.total_len;
5818 ret = hdd_driver_command(pAdapter, &priv_data);
5819 exit:
5820 return ret;
5821}
5822#else /* CONFIG_COMPAT */
5823static int hdd_driver_compat_ioctl(hdd_adapter_t *pAdapter, struct ifreq *ifr)
5824{
5825 /* will never be invoked */
5826 return 0;
5827}
5828#endif /* CONFIG_COMPAT */
5829
5830static int hdd_driver_ioctl(hdd_adapter_t *pAdapter, struct ifreq *ifr)
5831{
5832 hdd_priv_data_t priv_data;
5833 int ret = 0;
5834
5835 /*
5836 * Note that pAdapter and ifr have already been verified by caller,
5837 * and HDD context has also been validated
5838 */
5839 if (copy_from_user(&priv_data, ifr->ifr_data, sizeof(priv_data))) {
5840 ret = -EFAULT;
5841 } else {
5842 ret = hdd_driver_command(pAdapter, &priv_data);
5843 }
5844 return ret;
5845}
5846
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305847int __hdd_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07005848{
5849 hdd_adapter_t *pAdapter;
5850 hdd_context_t *pHddCtx;
5851 int ret;
5852
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305853 ENTER();
5854
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07005855 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5856 if (NULL == pAdapter) {
5857 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
5858 "%s: HDD adapter context is Null", __func__);
5859 ret = -ENODEV;
5860 goto exit;
5861 }
5862 if (dev != pAdapter->dev) {
5863 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
5864 "%s: HDD adapter/dev inconsistency", __func__);
5865 ret = -ENODEV;
5866 goto exit;
5867 }
5868
5869 if ((!ifr) || (!ifr->ifr_data)) {
5870 ret = -EINVAL;
5871 goto exit;
5872 }
5873
5874 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
5875 ret = wlan_hdd_validate_context(pHddCtx);
5876 if (ret) {
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07005877 ret = -EBUSY;
5878 goto exit;
5879 }
5880
5881 switch (cmd) {
5882 case (SIOCDEVPRIVATE + 1):
5883 if (is_compat_task())
5884 ret = hdd_driver_compat_ioctl(pAdapter, ifr);
5885 else
5886 ret = hdd_driver_ioctl(pAdapter, ifr);
5887 break;
5888 default:
5889 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unknown ioctl %d",
5890 __func__, cmd);
5891 ret = -EINVAL;
5892 break;
5893 }
5894 exit:
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305895 EXIT();
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07005896 return ret;
5897}
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07005898
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305899int hdd_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
5900{
5901 int ret;
5902
5903 vos_ssr_protect(__func__);
5904 ret = __hdd_ioctl(dev, ifr, cmd);
5905 vos_ssr_unprotect(__func__);
5906
5907 return ret;
5908}
5909
Katya Nigame7b69a82015-04-28 15:24:06 +05305910int hdd_mon_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
5911{
5912 return 0;
5913}
5914
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005915#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08005916/**---------------------------------------------------------------------------
5917
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005918 \brief hdd_parse_ese_beacon_req() - Parse ese beacon request
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08005919
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005920 This function parses the ese beacon request passed in the format
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08005921 CCXBEACONREQ<space><Number of fields><space><Measurement token>
5922 <space>Channel 1<space>Scan Mode <space>Meas Duration<space>Channel N
5923 <space>Scan Mode N<space>Meas Duration N
5924 if the Number of bcn req fields (N) does not match with the actual number of fields passed
5925 then take N.
5926 <Meas Token><Channel><Scan Mode> and <Meas Duration> are treated as one pair
5927 For example, CCXBEACONREQ 2 1 1 1 30 2 44 0 40.
5928 This function does not take care of removing duplicate channels from the list
5929
5930 \param - pValue Pointer to data
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005931 \param - pEseBcnReq output pointer to store parsed ie information
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08005932
5933 \return - 0 for success non-zero for failure
5934
5935 --------------------------------------------------------------------------*/
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005936static VOS_STATUS hdd_parse_ese_beacon_req(tANI_U8 *pValue,
5937 tCsrEseBeaconReq *pEseBcnReq)
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08005938{
5939 tANI_U8 *inPtr = pValue;
5940 int tempInt = 0;
5941 int j = 0, i = 0, v = 0;
5942 char buf[32];
5943
5944 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
5945 /*no argument after the command*/
5946 if (NULL == inPtr)
5947 {
5948 return -EINVAL;
5949 }
5950 /*no space after the command*/
5951 else if (SPACE_ASCII_VALUE != *inPtr)
5952 {
5953 return -EINVAL;
5954 }
5955
5956 /*removing empty spaces*/
5957 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
5958
5959 /*no argument followed by spaces*/
5960 if ('\0' == *inPtr) return -EINVAL;
5961
5962 /*getting the first argument ie measurement token*/
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08005963 v = sscanf(inPtr, "%31s ", buf);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08005964 if (1 != v) return -EINVAL;
5965
5966 v = kstrtos32(buf, 10, &tempInt);
5967 if ( v < 0) return -EINVAL;
5968
Srinivas Girigowda725a88e2016-03-31 19:24:25 +05305969 tempInt = VOS_MIN(tempInt, SIR_ESE_MAX_MEAS_IE_REQS);
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005970 pEseBcnReq->numBcnReqIe = tempInt;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08005971
Srinivas Girigowda725a88e2016-03-31 19:24:25 +05305972 hddLog(LOG1, "Number of Bcn Req Ie fields: %d", pEseBcnReq->numBcnReqIe);
5973
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08005974
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005975 for (j = 0; j < (pEseBcnReq->numBcnReqIe); j++)
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08005976 {
5977 for (i = 0; i < 4; i++)
5978 {
5979 /*inPtr pointing to the beginning of first space after number of ie fields*/
5980 inPtr = strpbrk( inPtr, " " );
5981 /*no ie data after the number of ie fields argument*/
5982 if (NULL == inPtr) return -EINVAL;
5983
5984 /*removing empty space*/
5985 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
5986
5987 /*no ie data after the number of ie fields argument and spaces*/
5988 if ( '\0' == *inPtr ) return -EINVAL;
5989
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08005990 v = sscanf(inPtr, "%31s ", buf);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08005991 if (1 != v) return -EINVAL;
5992
5993 v = kstrtos32(buf, 10, &tempInt);
5994 if (v < 0) return -EINVAL;
5995
5996 switch (i)
5997 {
5998 case 0: /* Measurement token */
5999 if (tempInt <= 0)
6000 {
6001 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6002 "Invalid Measurement Token(%d)", tempInt);
6003 return -EINVAL;
6004 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08006005 pEseBcnReq->bcnReq[j].measurementToken = tempInt;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08006006 break;
6007
6008 case 1: /* Channel number */
6009 if ((tempInt <= 0) ||
6010 (tempInt > WNI_CFG_CURRENT_CHANNEL_STAMAX))
6011 {
6012 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6013 "Invalid Channel Number(%d)", tempInt);
6014 return -EINVAL;
6015 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08006016 pEseBcnReq->bcnReq[j].channel = tempInt;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08006017 break;
6018
6019 case 2: /* Scan mode */
Varun Reddy Yeturu0b18d5a2013-12-04 11:42:23 -08006020 if ((tempInt < eSIR_PASSIVE_SCAN) || (tempInt > eSIR_BEACON_TABLE))
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08006021 {
6022 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6023 "Invalid Scan Mode(%d) Expected{0|1|2}", tempInt);
6024 return -EINVAL;
6025 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08006026 pEseBcnReq->bcnReq[j].scanMode= tempInt;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08006027 break;
6028
6029 case 3: /* Measurement duration */
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08006030 if (((tempInt <= 0) && (pEseBcnReq->bcnReq[j].scanMode != eSIR_BEACON_TABLE)) ||
6031 ((tempInt < 0) && (pEseBcnReq->bcnReq[j].scanMode == eSIR_BEACON_TABLE)))
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08006032 {
6033 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6034 "Invalid Measurement Duration(%d)", tempInt);
6035 return -EINVAL;
6036 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08006037 pEseBcnReq->bcnReq[j].measurementDuration = tempInt;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08006038 break;
6039 }
6040 }
6041 }
6042
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08006043 for (j = 0; j < pEseBcnReq->numBcnReqIe; j++)
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08006044 {
6045 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Arun Kumar Khandavallie8768212014-02-17 16:43:34 +05306046 "Index(%d) Measurement Token(%u)Channel(%u) Scan Mode(%u) Measurement Duration(%u)\n",
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08006047 j,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08006048 pEseBcnReq->bcnReq[j].measurementToken,
6049 pEseBcnReq->bcnReq[j].channel,
6050 pEseBcnReq->bcnReq[j].scanMode,
6051 pEseBcnReq->bcnReq[j].measurementDuration);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08006052 }
6053
6054 return VOS_STATUS_SUCCESS;
6055}
6056
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07006057static void hdd_GetTsmStatsCB( tAniTrafStrmMetrics tsmMetrics, const tANI_U32 staId, void *pContext )
6058{
6059 struct statsContext *pStatsContext = NULL;
6060 hdd_adapter_t *pAdapter = NULL;
6061
6062 if (NULL == pContext)
6063 {
6064 hddLog(VOS_TRACE_LEVEL_ERROR,
6065 "%s: Bad param, pContext [%p]",
6066 __func__, pContext);
6067 return;
6068 }
6069
Jeff Johnson72a40512013-12-19 10:14:15 -08006070 /* there is a race condition that exists between this callback
6071 function and the caller since the caller could time out either
6072 before or while this code is executing. we use a spinlock to
6073 serialize these actions */
6074 spin_lock(&hdd_context_lock);
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07006075
6076 pStatsContext = pContext;
6077 pAdapter = pStatsContext->pAdapter;
6078 if ((NULL == pAdapter) || (STATS_CONTEXT_MAGIC != pStatsContext->magic))
6079 {
6080 /* the caller presumably timed out so there is nothing we can do */
Jeff Johnson72a40512013-12-19 10:14:15 -08006081 spin_unlock(&hdd_context_lock);
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07006082 hddLog(VOS_TRACE_LEVEL_WARN,
6083 "%s: Invalid context, pAdapter [%p] magic [%08x]",
6084 __func__, pAdapter, pStatsContext->magic);
6085 return;
6086 }
6087
Jeff Johnson72a40512013-12-19 10:14:15 -08006088 /* context is valid so caller is still waiting */
6089
6090 /* paranoia: invalidate the magic */
6091 pStatsContext->magic = 0;
6092
6093 /* copy over the tsm stats */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07006094 pAdapter->tsmStats.UplinkPktQueueDly = tsmMetrics.UplinkPktQueueDly;
6095 vos_mem_copy(pAdapter->tsmStats.UplinkPktQueueDlyHist,
6096 tsmMetrics.UplinkPktQueueDlyHist,
6097 sizeof(pAdapter->tsmStats.UplinkPktQueueDlyHist)/
6098 sizeof(pAdapter->tsmStats.UplinkPktQueueDlyHist[0]));
6099 pAdapter->tsmStats.UplinkPktTxDly = tsmMetrics.UplinkPktTxDly;
6100 pAdapter->tsmStats.UplinkPktLoss = tsmMetrics.UplinkPktLoss;
6101 pAdapter->tsmStats.UplinkPktCount = tsmMetrics.UplinkPktCount;
6102 pAdapter->tsmStats.RoamingCount = tsmMetrics.RoamingCount;
6103 pAdapter->tsmStats.RoamingDly = tsmMetrics.RoamingDly;
6104
Jeff Johnson72a40512013-12-19 10:14:15 -08006105 /* notify the caller */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07006106 complete(&pStatsContext->completion);
Jeff Johnson72a40512013-12-19 10:14:15 -08006107
6108 /* serialization is complete */
6109 spin_unlock(&hdd_context_lock);
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07006110}
6111
6112
6113
6114static VOS_STATUS hdd_get_tsm_stats(hdd_adapter_t *pAdapter, const tANI_U8 tid,
6115 tAniTrafStrmMetrics* pTsmMetrics)
6116{
6117 hdd_station_ctx_t *pHddStaCtx = NULL;
6118 eHalStatus hstatus;
Jeff Johnson72a40512013-12-19 10:14:15 -08006119 VOS_STATUS vstatus = VOS_STATUS_SUCCESS;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07006120 long lrc;
6121 struct statsContext context;
6122 hdd_context_t *pHddCtx = NULL;
6123
6124 if (NULL == pAdapter)
6125 {
6126 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: pAdapter is NULL", __func__);
6127 return VOS_STATUS_E_FAULT;
6128 }
6129
6130 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
6131 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
6132
6133 /* we are connected prepare our callback context */
6134 init_completion(&context.completion);
6135 context.pAdapter = pAdapter;
6136 context.magic = STATS_CONTEXT_MAGIC;
6137
6138 /* query tsm stats */
6139 hstatus = sme_GetTsmStats(pHddCtx->hHal, hdd_GetTsmStatsCB,
6140 pHddStaCtx->conn_info.staId[ 0 ],
6141 pHddStaCtx->conn_info.bssId,
6142 &context, pHddCtx->pvosContext, tid);
6143
6144 if (eHAL_STATUS_SUCCESS != hstatus)
6145 {
Jeff Johnson72a40512013-12-19 10:14:15 -08006146 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unable to retrieve statistics",
6147 __func__);
6148 vstatus = VOS_STATUS_E_FAULT;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07006149 }
6150 else
6151 {
6152 /* request was sent -- wait for the response */
6153 lrc = wait_for_completion_interruptible_timeout(&context.completion,
6154 msecs_to_jiffies(WLAN_WAIT_TIME_STATS));
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07006155 if (lrc <= 0)
6156 {
6157 hddLog(VOS_TRACE_LEVEL_ERROR,
6158 "%s: SME %s while retrieving statistics",
6159 __func__, (0 == lrc) ? "timeout" : "interrupt");
Jeff Johnson72a40512013-12-19 10:14:15 -08006160 vstatus = VOS_STATUS_E_TIMEOUT;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07006161 }
6162 }
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07006163
Jeff Johnson72a40512013-12-19 10:14:15 -08006164 /* either we never sent a request, we sent a request and received a
6165 response or we sent a request and timed out. if we never sent a
6166 request or if we sent a request and got a response, we want to
6167 clear the magic out of paranoia. if we timed out there is a
6168 race condition such that the callback function could be
6169 executing at the same time we are. of primary concern is if the
6170 callback function had already verified the "magic" but had not
6171 yet set the completion variable when a timeout occurred. we
6172 serialize these activities by invalidating the magic while
6173 holding a shared spinlock which will cause us to block if the
6174 callback is currently executing */
6175 spin_lock(&hdd_context_lock);
6176 context.magic = 0;
6177 spin_unlock(&hdd_context_lock);
6178
6179 if (VOS_STATUS_SUCCESS == vstatus)
6180 {
6181 pTsmMetrics->UplinkPktQueueDly = pAdapter->tsmStats.UplinkPktQueueDly;
6182 vos_mem_copy(pTsmMetrics->UplinkPktQueueDlyHist,
6183 pAdapter->tsmStats.UplinkPktQueueDlyHist,
6184 sizeof(pAdapter->tsmStats.UplinkPktQueueDlyHist)/
6185 sizeof(pAdapter->tsmStats.UplinkPktQueueDlyHist[0]));
6186 pTsmMetrics->UplinkPktTxDly = pAdapter->tsmStats.UplinkPktTxDly;
6187 pTsmMetrics->UplinkPktLoss = pAdapter->tsmStats.UplinkPktLoss;
6188 pTsmMetrics->UplinkPktCount = pAdapter->tsmStats.UplinkPktCount;
6189 pTsmMetrics->RoamingCount = pAdapter->tsmStats.RoamingCount;
6190 pTsmMetrics->RoamingDly = pAdapter->tsmStats.RoamingDly;
6191 }
6192 return vstatus;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07006193}
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08006194#endif /*FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07006195
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08006196#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowdade697412013-02-14 16:31:48 -08006197void hdd_getBand_helper(hdd_context_t *pHddCtx, int *pBand)
6198{
6199 eCsrBand band = -1;
6200 sme_GetFreqBand((tHalHandle)(pHddCtx->hHal), &band);
6201 switch (band)
6202 {
6203 case eCSR_BAND_ALL:
6204 *pBand = WLAN_HDD_UI_BAND_AUTO;
6205 break;
6206
6207 case eCSR_BAND_24:
6208 *pBand = WLAN_HDD_UI_BAND_2_4_GHZ;
6209 break;
6210
6211 case eCSR_BAND_5G:
6212 *pBand = WLAN_HDD_UI_BAND_5_GHZ;
6213 break;
6214
6215 default:
6216 hddLog( VOS_TRACE_LEVEL_WARN, "%s: Invalid Band %d", __func__, band);
6217 *pBand = -1;
6218 break;
6219 }
6220}
6221
6222/**---------------------------------------------------------------------------
6223
Srinivas Girigowda100eb322013-03-15 16:48:20 -07006224 \brief hdd_parse_send_action_frame_data() - HDD Parse send action frame data
6225
6226 This function parses the send action frame data passed in the format
6227 SENDACTIONFRAME<space><bssid><space><channel><space><dwelltime><space><data>
6228
Srinivas Girigowda56076852013-08-20 14:00:50 -07006229 \param - pValue Pointer to input data
Srinivas Girigowda100eb322013-03-15 16:48:20 -07006230 \param - pTargetApBssid Pointer to target Ap bssid
6231 \param - pChannel Pointer to the Target AP channel
6232 \param - pDwellTime Pointer to the time to stay off-channel after transmitting action frame
6233 \param - pBuf Pointer to data
6234 \param - pBufLen Pointer to data length
6235
6236 \return - 0 for success non-zero for failure
6237
6238 --------------------------------------------------------------------------*/
6239VOS_STATUS hdd_parse_send_action_frame_data(tANI_U8 *pValue, tANI_U8 *pTargetApBssid, tANI_U8 *pChannel,
6240 tANI_U8 *pDwellTime, tANI_U8 **pBuf, tANI_U8 *pBufLen)
6241{
6242 tANI_U8 *inPtr = pValue;
6243 tANI_U8 *dataEnd;
6244 int tempInt;
6245 int j = 0;
6246 int i = 0;
6247 int v = 0;
6248 tANI_U8 tempBuf[32];
6249 tANI_U8 tempByte = 0;
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08006250 /* 12 hexa decimal digits, 5 ':' and '\0' */
6251 tANI_U8 macAddress[18];
Srinivas Girigowda100eb322013-03-15 16:48:20 -07006252
6253 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
6254 /*no argument after the command*/
6255 if (NULL == inPtr)
6256 {
6257 return -EINVAL;
6258 }
6259
6260 /*no space after the command*/
6261 else if (SPACE_ASCII_VALUE != *inPtr)
6262 {
6263 return -EINVAL;
6264 }
6265
6266 /*removing empty spaces*/
6267 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
6268
6269 /*no argument followed by spaces*/
6270 if ('\0' == *inPtr)
6271 {
6272 return -EINVAL;
6273 }
6274
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07006275 v = sscanf(inPtr, "%17s", macAddress);
6276 if (!((1 == v) && hdd_is_valid_mac_address(macAddress)))
Srinivas Girigowda100eb322013-03-15 16:48:20 -07006277 {
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07006278 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6279 "Invalid MAC address or All hex inputs are not read (%d)", v);
6280 return -EINVAL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07006281 }
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07006282
6283 pTargetApBssid[0] = hdd_parse_hex(macAddress[0]) << 4 | hdd_parse_hex(macAddress[1]);
6284 pTargetApBssid[1] = hdd_parse_hex(macAddress[3]) << 4 | hdd_parse_hex(macAddress[4]);
6285 pTargetApBssid[2] = hdd_parse_hex(macAddress[6]) << 4 | hdd_parse_hex(macAddress[7]);
6286 pTargetApBssid[3] = hdd_parse_hex(macAddress[9]) << 4 | hdd_parse_hex(macAddress[10]);
6287 pTargetApBssid[4] = hdd_parse_hex(macAddress[12]) << 4 | hdd_parse_hex(macAddress[13]);
6288 pTargetApBssid[5] = hdd_parse_hex(macAddress[15]) << 4 | hdd_parse_hex(macAddress[16]);
Srinivas Girigowda100eb322013-03-15 16:48:20 -07006289
6290 /* point to the next argument */
6291 inPtr = strnchr(inPtr, strlen(inPtr), SPACE_ASCII_VALUE);
6292 /*no argument after the command*/
6293 if (NULL == inPtr) return -EINVAL;
6294
6295 /*removing empty spaces*/
6296 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
6297
6298 /*no argument followed by spaces*/
6299 if ('\0' == *inPtr)
6300 {
6301 return -EINVAL;
6302 }
6303
6304 /*getting the next argument ie the channel number */
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08006305 v = sscanf(inPtr, "%31s ", tempBuf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07006306 if (1 != v) return -EINVAL;
6307
Srinivas Girigowda100eb322013-03-15 16:48:20 -07006308 v = kstrtos32(tempBuf, 10, &tempInt);
Agarwal Ashish353b3a82014-04-08 14:55:11 +05306309 if ( v < 0 || tempInt <= 0 || tempInt > WNI_CFG_CURRENT_CHANNEL_STAMAX )
Kiet Lambe150c22013-11-21 16:30:32 +05306310 return -EINVAL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07006311
6312 *pChannel = tempInt;
6313
6314 /* point to the next argument */
6315 inPtr = strnchr(inPtr, strlen(inPtr), SPACE_ASCII_VALUE);
6316 /*no argument after the command*/
6317 if (NULL == inPtr) return -EINVAL;
6318 /*removing empty spaces*/
6319 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
6320
6321 /*no argument followed by spaces*/
6322 if ('\0' == *inPtr)
6323 {
6324 return -EINVAL;
6325 }
6326
6327 /*getting the next argument ie the dwell time */
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08006328 v = sscanf(inPtr, "%31s ", tempBuf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07006329 if (1 != v) return -EINVAL;
6330
Srinivas Girigowda100eb322013-03-15 16:48:20 -07006331 v = kstrtos32(tempBuf, 10, &tempInt);
Srinivas Girigowda5a6e0672014-01-09 14:42:57 -08006332 if ( v < 0 || tempInt < 0) return -EINVAL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07006333
6334 *pDwellTime = tempInt;
6335
6336 /* point to the next argument */
6337 inPtr = strnchr(inPtr, strlen(inPtr), SPACE_ASCII_VALUE);
6338 /*no argument after the command*/
6339 if (NULL == inPtr) return -EINVAL;
6340 /*removing empty spaces*/
6341 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
6342
6343 /*no argument followed by spaces*/
6344 if ('\0' == *inPtr)
6345 {
6346 return -EINVAL;
6347 }
6348
6349 /* find the length of data */
6350 dataEnd = inPtr;
6351 while(('\0' != *dataEnd) )
6352 {
6353 dataEnd++;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07006354 }
Kiet Lambe150c22013-11-21 16:30:32 +05306355 *pBufLen = dataEnd - inPtr ;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07006356 if ( *pBufLen <= 0) return -EINVAL;
6357
Srinivas Girigowdab5ae85d2013-06-03 10:51:45 -07006358 /* Allocate the number of bytes based on the number of input characters
6359 whether it is even or odd.
6360 if the number of input characters are even, then we need N/2 byte.
6361 if the number of input characters are odd, then we need do (N+1)/2 to
6362 compensate rounding off.
6363 For example, if N = 18, then (18 + 1)/2 = 9 bytes are enough.
6364 If N = 19, then we need 10 bytes, hence (19 + 1)/2 = 10 bytes */
6365 *pBuf = vos_mem_malloc((*pBufLen + 1)/2);
Srinivas Girigowda100eb322013-03-15 16:48:20 -07006366 if (NULL == *pBuf)
6367 {
6368 hddLog(VOS_TRACE_LEVEL_FATAL,
6369 "%s: vos_mem_alloc failed ", __func__);
6370 return -EINVAL;
6371 }
6372
6373 /* the buffer received from the upper layer is character buffer,
6374 we need to prepare the buffer taking 2 characters in to a U8 hex decimal number
6375 for example 7f0000f0...form a buffer to contain 7f in 0th location, 00 in 1st
6376 and f0 in 3rd location */
6377 for (i = 0, j = 0; j < *pBufLen; j += 2)
6378 {
Kiet Lambe150c22013-11-21 16:30:32 +05306379 if( j+1 == *pBufLen)
6380 {
6381 tempByte = hdd_parse_hex(inPtr[j]);
6382 }
6383 else
6384 {
6385 tempByte = (hdd_parse_hex(inPtr[j]) << 4) | (hdd_parse_hex(inPtr[j + 1]));
6386 }
Srinivas Girigowda100eb322013-03-15 16:48:20 -07006387 (*pBuf)[i++] = tempByte;
6388 }
6389 *pBufLen = i;
6390 return VOS_STATUS_SUCCESS;
6391}
6392
Srinivas Girigowda100eb322013-03-15 16:48:20 -07006393/**---------------------------------------------------------------------------
6394
Srinivas Girigowdade697412013-02-14 16:31:48 -08006395 \brief hdd_parse_channellist() - HDD Parse channel list
6396
6397 This function parses the channel list passed in the format
6398 SETROAMSCANCHANNELS<space><Number of channels><space>Channel 1<space>Channel 2<space>Channel N
Srinivas Girigowdacf9a9b42013-03-21 11:55:24 -07006399 if the Number of channels (N) does not match with the actual number of channels passed
6400 then take the minimum of N and count of (Ch1, Ch2, ...Ch M)
6401 For example, if SETROAMSCANCHANNELS 3 36 40 44 48, only 36, 40 and 44 shall be taken.
6402 If SETROAMSCANCHANNELS 5 36 40 44 48, ignore 5 and take 36, 40, 44 and 48.
6403 This function does not take care of removing duplicate channels from the list
Srinivas Girigowdade697412013-02-14 16:31:48 -08006404
6405 \param - pValue Pointer to input channel list
6406 \param - ChannelList Pointer to local output array to record channel list
6407 \param - pNumChannels Pointer to number of roam scan channels
6408
6409 \return - 0 for success non-zero for failure
6410
6411 --------------------------------------------------------------------------*/
6412VOS_STATUS hdd_parse_channellist(tANI_U8 *pValue, tANI_U8 *pChannelList, tANI_U8 *pNumChannels)
6413{
6414 tANI_U8 *inPtr = pValue;
6415 int tempInt;
6416 int j = 0;
6417 int v = 0;
6418 char buf[32];
6419
6420 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
6421 /*no argument after the command*/
6422 if (NULL == inPtr)
6423 {
6424 return -EINVAL;
6425 }
6426
6427 /*no space after the command*/
6428 else if (SPACE_ASCII_VALUE != *inPtr)
6429 {
6430 return -EINVAL;
6431 }
6432
6433 /*removing empty spaces*/
Jeff Johnsona1f9afb2013-04-03 09:13:31 -07006434 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
Srinivas Girigowdade697412013-02-14 16:31:48 -08006435
6436 /*no argument followed by spaces*/
6437 if ('\0' == *inPtr)
6438 {
6439 return -EINVAL;
6440 }
6441
6442 /*getting the first argument ie the number of channels*/
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08006443 v = sscanf(inPtr, "%31s ", buf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07006444 if (1 != v) return -EINVAL;
6445
Srinivas Girigowdade697412013-02-14 16:31:48 -08006446 v = kstrtos32(buf, 10, &tempInt);
Jeff Johnsona1f9afb2013-04-03 09:13:31 -07006447 if ((v < 0) ||
6448 (tempInt <= 0) ||
6449 (tempInt > WNI_CFG_VALID_CHANNEL_LIST_LEN))
6450 {
6451 return -EINVAL;
6452 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08006453
6454 *pNumChannels = tempInt;
6455
6456 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
6457 "Number of channels are: %d", *pNumChannels);
6458
6459 for (j = 0; j < (*pNumChannels); j++)
6460 {
6461 /*inPtr pointing to the beginning of first space after number of channels*/
6462 inPtr = strpbrk( inPtr, " " );
6463 /*no channel list after the number of channels argument*/
6464 if (NULL == inPtr)
6465 {
Srinivas Girigowdacf9a9b42013-03-21 11:55:24 -07006466 if (0 != j)
6467 {
6468 *pNumChannels = j;
6469 return VOS_STATUS_SUCCESS;
6470 }
6471 else
6472 {
6473 return -EINVAL;
6474 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08006475 }
6476
6477 /*removing empty space*/
Jeff Johnsona1f9afb2013-04-03 09:13:31 -07006478 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
Srinivas Girigowdade697412013-02-14 16:31:48 -08006479
6480 /*no channel list after the number of channels argument and spaces*/
6481 if ( '\0' == *inPtr )
6482 {
Srinivas Girigowdacf9a9b42013-03-21 11:55:24 -07006483 if (0 != j)
6484 {
6485 *pNumChannels = j;
6486 return VOS_STATUS_SUCCESS;
6487 }
6488 else
6489 {
6490 return -EINVAL;
6491 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08006492 }
6493
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08006494 v = sscanf(inPtr, "%31s ", buf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07006495 if (1 != v) return -EINVAL;
6496
Srinivas Girigowdade697412013-02-14 16:31:48 -08006497 v = kstrtos32(buf, 10, &tempInt);
Jeff Johnsona1f9afb2013-04-03 09:13:31 -07006498 if ((v < 0) ||
6499 (tempInt <= 0) ||
6500 (tempInt > WNI_CFG_CURRENT_CHANNEL_STAMAX))
6501 {
6502 return -EINVAL;
6503 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08006504 pChannelList[j] = tempInt;
6505
6506 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
6507 "Channel %d added to preferred channel list",
6508 pChannelList[j] );
6509 }
6510
Srinivas Girigowdade697412013-02-14 16:31:48 -08006511 return VOS_STATUS_SUCCESS;
6512}
6513
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07006514
6515/**---------------------------------------------------------------------------
6516
6517 \brief hdd_parse_reassoc_command_data() - HDD Parse reassoc command data
6518
6519 This function parses the reasoc command data passed in the format
6520 REASSOC<space><bssid><space><channel>
6521
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07006522 \param - pValue Pointer to input data (its a NUL terminated string)
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07006523 \param - pTargetApBssid Pointer to target Ap bssid
6524 \param - pChannel Pointer to the Target AP channel
6525
6526 \return - 0 for success non-zero for failure
6527
6528 --------------------------------------------------------------------------*/
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07006529VOS_STATUS hdd_parse_reassoc_command_data(tANI_U8 *pValue,
6530 tANI_U8 *pTargetApBssid, tANI_U8 *pChannel)
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07006531{
6532 tANI_U8 *inPtr = pValue;
6533 int tempInt;
6534 int v = 0;
6535 tANI_U8 tempBuf[32];
Kiet Lamaa8e15a2014-02-11 23:30:06 -08006536 /* 12 hexa decimal digits, 5 ':' and '\0' */
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08006537 tANI_U8 macAddress[18];
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07006538
6539 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
6540 /*no argument after the command*/
6541 if (NULL == inPtr)
6542 {
6543 return -EINVAL;
6544 }
6545
6546 /*no space after the command*/
6547 else if (SPACE_ASCII_VALUE != *inPtr)
6548 {
6549 return -EINVAL;
6550 }
6551
6552 /*removing empty spaces*/
6553 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
6554
6555 /*no argument followed by spaces*/
6556 if ('\0' == *inPtr)
6557 {
6558 return -EINVAL;
6559 }
6560
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07006561 v = sscanf(inPtr, "%17s", macAddress);
6562 if (!((1 == v) && hdd_is_valid_mac_address(macAddress)))
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07006563 {
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07006564 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6565 "Invalid MAC address or All hex inputs are not read (%d)", v);
6566 return -EINVAL;
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07006567 }
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07006568
6569 pTargetApBssid[0] = hdd_parse_hex(macAddress[0]) << 4 | hdd_parse_hex(macAddress[1]);
6570 pTargetApBssid[1] = hdd_parse_hex(macAddress[3]) << 4 | hdd_parse_hex(macAddress[4]);
6571 pTargetApBssid[2] = hdd_parse_hex(macAddress[6]) << 4 | hdd_parse_hex(macAddress[7]);
6572 pTargetApBssid[3] = hdd_parse_hex(macAddress[9]) << 4 | hdd_parse_hex(macAddress[10]);
6573 pTargetApBssid[4] = hdd_parse_hex(macAddress[12]) << 4 | hdd_parse_hex(macAddress[13]);
6574 pTargetApBssid[5] = hdd_parse_hex(macAddress[15]) << 4 | hdd_parse_hex(macAddress[16]);
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07006575
6576 /* point to the next argument */
6577 inPtr = strnchr(inPtr, strlen(inPtr), SPACE_ASCII_VALUE);
6578 /*no argument after the command*/
6579 if (NULL == inPtr) return -EINVAL;
6580
6581 /*removing empty spaces*/
6582 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
6583
6584 /*no argument followed by spaces*/
6585 if ('\0' == *inPtr)
6586 {
6587 return -EINVAL;
6588 }
6589
6590 /*getting the next argument ie the channel number */
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08006591 v = sscanf(inPtr, "%31s ", tempBuf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07006592 if (1 != v) return -EINVAL;
6593
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07006594 v = kstrtos32(tempBuf, 10, &tempInt);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07006595 if ((v < 0) ||
Padma, Santhosh Kumar0fa809b2014-11-13 14:56:56 +05306596 (tempInt < 0) ||
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07006597 (tempInt > WNI_CFG_CURRENT_CHANNEL_STAMAX))
6598 {
6599 return -EINVAL;
6600 }
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07006601
6602 *pChannel = tempInt;
6603 return VOS_STATUS_SUCCESS;
6604}
6605
6606#endif
6607
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08006608#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07006609/**---------------------------------------------------------------------------
6610
6611 \brief hdd_parse_get_cckm_ie() - HDD Parse and fetch the CCKM IE
6612
6613 This function parses the SETCCKM IE command
6614 SETCCKMIE<space><ie data>
6615
6616 \param - pValue Pointer to input data
6617 \param - pCckmIe Pointer to output cckm Ie
6618 \param - pCckmIeLen Pointer to output cckm ie length
6619
6620 \return - 0 for success non-zero for failure
6621
6622 --------------------------------------------------------------------------*/
6623VOS_STATUS hdd_parse_get_cckm_ie(tANI_U8 *pValue, tANI_U8 **pCckmIe,
6624 tANI_U8 *pCckmIeLen)
6625{
6626 tANI_U8 *inPtr = pValue;
6627 tANI_U8 *dataEnd;
6628 int j = 0;
6629 int i = 0;
6630 tANI_U8 tempByte = 0;
6631
6632 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
6633 /*no argument after the command*/
6634 if (NULL == inPtr)
6635 {
6636 return -EINVAL;
6637 }
6638
6639 /*no space after the command*/
6640 else if (SPACE_ASCII_VALUE != *inPtr)
6641 {
6642 return -EINVAL;
6643 }
6644
6645 /*removing empty spaces*/
6646 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
6647
6648 /*no argument followed by spaces*/
6649 if ('\0' == *inPtr)
6650 {
6651 return -EINVAL;
6652 }
6653
6654 /* find the length of data */
6655 dataEnd = inPtr;
6656 while(('\0' != *dataEnd) )
6657 {
6658 dataEnd++;
6659 ++(*pCckmIeLen);
6660 }
6661 if ( *pCckmIeLen <= 0) return -EINVAL;
6662
6663 /* Allocate the number of bytes based on the number of input characters
6664 whether it is even or odd.
6665 if the number of input characters are even, then we need N/2 byte.
6666 if the number of input characters are odd, then we need do (N+1)/2 to
6667 compensate rounding off.
6668 For example, if N = 18, then (18 + 1)/2 = 9 bytes are enough.
6669 If N = 19, then we need 10 bytes, hence (19 + 1)/2 = 10 bytes */
6670 *pCckmIe = vos_mem_malloc((*pCckmIeLen + 1)/2);
6671 if (NULL == *pCckmIe)
6672 {
6673 hddLog(VOS_TRACE_LEVEL_FATAL,
6674 "%s: vos_mem_alloc failed ", __func__);
6675 return -EINVAL;
6676 }
6677 vos_mem_zero(*pCckmIe, (*pCckmIeLen + 1)/2);
6678 /* the buffer received from the upper layer is character buffer,
6679 we need to prepare the buffer taking 2 characters in to a U8 hex decimal number
6680 for example 7f0000f0...form a buffer to contain 7f in 0th location, 00 in 1st
6681 and f0 in 3rd location */
6682 for (i = 0, j = 0; j < *pCckmIeLen; j += 2)
6683 {
6684 tempByte = (hdd_parse_hex(inPtr[j]) << 4) | (hdd_parse_hex(inPtr[j + 1]));
6685 (*pCckmIe)[i++] = tempByte;
6686 }
6687 *pCckmIeLen = i;
6688
6689 return VOS_STATUS_SUCCESS;
6690}
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08006691#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07006692
Jeff Johnson295189b2012-06-20 16:38:30 -07006693/**---------------------------------------------------------------------------
6694
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07006695 \brief hdd_is_valid_mac_address() - Validate MAC address
6696
6697 This function validates whether the given MAC address is valid or not
6698 Expected MAC address is of the format XX:XX:XX:XX:XX:XX
6699 where X is the hexa decimal digit character and separated by ':'
6700 This algorithm works even if MAC address is not separated by ':'
6701
6702 This code checks given input string mac contains exactly 12 hexadecimal digits.
6703 and a separator colon : appears in the input string only after
6704 an even number of hex digits.
6705
6706 \param - pMacAddr pointer to the input MAC address
6707 \return - 1 for valid and 0 for invalid
6708
6709 --------------------------------------------------------------------------*/
6710
6711v_BOOL_t hdd_is_valid_mac_address(const tANI_U8 *pMacAddr)
6712{
6713 int xdigit = 0;
6714 int separator = 0;
6715 while (*pMacAddr)
6716 {
6717 if (isxdigit(*pMacAddr))
6718 {
6719 xdigit++;
6720 }
6721 else if (':' == *pMacAddr)
6722 {
6723 if (0 == xdigit || ((xdigit / 2) - 1) != separator)
6724 break;
6725
6726 ++separator;
6727 }
6728 else
6729 {
6730 separator = -1;
6731 /* Invalid MAC found */
6732 return 0;
6733 }
6734 ++pMacAddr;
6735 }
6736 return (xdigit == 12 && (separator == 5 || separator == 0));
6737}
6738
6739/**---------------------------------------------------------------------------
6740
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05306741 \brief __hdd_open() - HDD Open function
Jeff Johnson295189b2012-06-20 16:38:30 -07006742
6743 \param - dev Pointer to net_device structure
6744
6745 \return - 0 for success non-zero for failure
6746
6747 --------------------------------------------------------------------------*/
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05306748int __hdd_open(struct net_device *dev)
Jeff Johnson295189b2012-06-20 16:38:30 -07006749{
6750 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6751 hdd_context_t *pHddCtx;
6752 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
6753 VOS_STATUS status;
6754 v_BOOL_t in_standby = TRUE;
6755
6756 if (NULL == pAdapter)
6757 {
6758 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Agarwal Ashish971c2882013-10-30 20:11:12 +05306759 "%s: pAdapter is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006760 return -ENODEV;
6761 }
6762
6763 pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05306764 MTRACE(vos_trace(VOS_MODULE_ID_HDD, TRACE_CODE_HDD_OPEN_REQUEST,
6765 pAdapter->sessionId, pAdapter->device_mode));
Jeff Johnson295189b2012-06-20 16:38:30 -07006766 if (NULL == pHddCtx)
6767 {
6768 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07006769 "%s: HDD context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006770 return -ENODEV;
6771 }
6772
6773 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
6774 while ( (NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status) )
6775 {
Jeff Johnson6a81ca42013-04-05 10:37:08 -07006776 if (test_bit(DEVICE_IFACE_OPENED, &pAdapterNode->pAdapter->event_flags))
6777 {
6778 hddLog(VOS_TRACE_LEVEL_INFO, "%s: chip already out of standby",
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05306779 __func__);
Jeff Johnson6a81ca42013-04-05 10:37:08 -07006780 in_standby = FALSE;
6781 break;
6782 }
6783 else
6784 {
6785 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
6786 pAdapterNode = pNext;
6787 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006788 }
6789
6790 if (TRUE == in_standby)
6791 {
6792 if (VOS_STATUS_SUCCESS != wlan_hdd_exit_lowpower(pHddCtx, pAdapter))
6793 {
6794 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Failed to bring "
6795 "wlan out of power save", __func__);
6796 return -EINVAL;
6797 }
6798 }
6799
Jeff Johnson6a81ca42013-04-05 10:37:08 -07006800 set_bit(DEVICE_IFACE_OPENED, &pAdapter->event_flags);
Jeff Johnson295189b2012-06-20 16:38:30 -07006801 if (hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter)))
6802 {
6803 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07006804 "%s: Enabling Tx Queues", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006805 /* Enable TX queues only when we are connected */
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +05306806 hddLog(VOS_TRACE_LEVEL_INFO, FL("Enabling queues"));
Jeff Johnson295189b2012-06-20 16:38:30 -07006807 netif_tx_start_all_queues(dev);
6808 }
6809
6810 return 0;
6811}
6812
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05306813/**---------------------------------------------------------------------------
6814
6815 \brief hdd_open() - Wrapper function for __hdd_open to protect it from SSR
6816
6817 This is called in response to ifconfig up
6818
6819 \param - dev Pointer to net_device structure
6820
6821 \return - 0 for success non-zero for failure
6822
6823 --------------------------------------------------------------------------*/
6824int hdd_open(struct net_device *dev)
6825{
6826 int ret;
6827
6828 vos_ssr_protect(__func__);
6829 ret = __hdd_open(dev);
6830 vos_ssr_unprotect(__func__);
6831
6832 return ret;
6833}
6834
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05306835int __hdd_mon_open (struct net_device *dev)
Jeff Johnson295189b2012-06-20 16:38:30 -07006836{
6837 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6838
6839 if(pAdapter == NULL) {
6840 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07006841 "%s: HDD adapter context is Null", __func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08006842 return -EINVAL;
Jeff Johnson295189b2012-06-20 16:38:30 -07006843 }
6844
Jeff Johnson295189b2012-06-20 16:38:30 -07006845 return 0;
6846}
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05306847
6848int hdd_mon_open (struct net_device *dev)
6849{
6850 int ret;
6851
6852 vos_ssr_protect(__func__);
6853 ret = __hdd_mon_open(dev);
6854 vos_ssr_unprotect(__func__);
6855
6856 return ret;
6857}
6858
Katya Nigame7b69a82015-04-28 15:24:06 +05306859int hdd_mon_stop(struct net_device *dev)
6860{
6861 return 0;
6862}
6863
Jeff Johnson295189b2012-06-20 16:38:30 -07006864/**---------------------------------------------------------------------------
6865
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05306866 \brief __hdd_stop() - HDD stop function
Jeff Johnson295189b2012-06-20 16:38:30 -07006867
6868 \param - dev Pointer to net_device structure
6869
6870 \return - 0 for success non-zero for failure
6871
6872 --------------------------------------------------------------------------*/
6873
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05306874int __hdd_stop (struct net_device *dev)
Jeff Johnson295189b2012-06-20 16:38:30 -07006875{
Vinay Krishna Eranna90f43532014-10-27 16:45:54 +05306876 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07006877 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6878 hdd_context_t *pHddCtx;
6879 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
6880 VOS_STATUS status;
6881 v_BOOL_t enter_standby = TRUE;
6882
6883 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07006884 if (NULL == pAdapter)
6885 {
6886 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Agarwal Ashish971c2882013-10-30 20:11:12 +05306887 "%s: pAdapter is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006888 return -ENODEV;
6889 }
Sachin Ahuja9b4958f2015-01-15 21:37:00 +05306890 MTRACE(vos_trace(VOS_MODULE_ID_HDD, TRACE_CODE_HDD_STOP_REQUEST,
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05306891 pAdapter->sessionId, pAdapter->device_mode));
Vinay Krishna Eranna90f43532014-10-27 16:45:54 +05306892
6893 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
6894 ret = wlan_hdd_validate_context(pHddCtx);
6895 if (ret)
Jeff Johnson295189b2012-06-20 16:38:30 -07006896 {
Vinay Krishna Eranna90f43532014-10-27 16:45:54 +05306897 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07006898 }
6899
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05306900 /* Nothing to be done if the interface is not opened */
6901 if (VOS_FALSE == test_bit(DEVICE_IFACE_OPENED, &pAdapter->event_flags))
6902 {
6903 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6904 "%s: NETDEV Interface is not OPENED", __func__);
6905 return -ENODEV;
6906 }
6907
6908 /* Make sure the interface is marked as closed */
Jeff Johnson6a81ca42013-04-05 10:37:08 -07006909 clear_bit(DEVICE_IFACE_OPENED, &pAdapter->event_flags);
Jeff Johnson295189b2012-06-20 16:38:30 -07006910 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Disabling OS Tx queues", __func__);
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05306911
6912 /* Disable TX on the interface, after this hard_start_xmit() will not
6913 * be called on that interface
6914 */
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +05306915 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Jeff Johnson295189b2012-06-20 16:38:30 -07006916 netif_tx_disable(pAdapter->dev);
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05306917
6918 /* Mark the interface status as "down" for outside world */
Jeff Johnson295189b2012-06-20 16:38:30 -07006919 netif_carrier_off(pAdapter->dev);
6920
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05306921 /* The interface is marked as down for outside world (aka kernel)
6922 * But the driver is pretty much alive inside. The driver needs to
6923 * tear down the existing connection on the netdev (session)
6924 * cleanup the data pipes and wait until the control plane is stabilized
6925 * for this interface. The call also needs to wait until the above
6926 * mentioned actions are completed before returning to the caller.
6927 * Notice that the hdd_stop_adapter is requested not to close the session
6928 * That is intentional to be able to scan if it is a STA/P2P interface
6929 */
6930 hdd_stop_adapter(pHddCtx, pAdapter, VOS_FALSE);
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05306931#ifdef FEATURE_WLAN_TDLS
6932 mutex_lock(&pHddCtx->tdls_lock);
6933#endif
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05306934 /* DeInit the adapter. This ensures datapath cleanup as well */
c_hpothu002231a2015-02-05 14:58:51 +05306935 hdd_deinit_adapter(pHddCtx, pAdapter, TRUE);
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05306936#ifdef FEATURE_WLAN_TDLS
6937 mutex_unlock(&pHddCtx->tdls_lock);
6938#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006939 /* SoftAP ifaces should never go in power save mode
6940 making sure same here. */
6941 if ( (WLAN_HDD_SOFTAP == pAdapter->device_mode )
6942 || (WLAN_HDD_MONITOR == pAdapter->device_mode )
Jeff Johnson295189b2012-06-20 16:38:30 -07006943 || (WLAN_HDD_P2P_GO == pAdapter->device_mode )
Jeff Johnson295189b2012-06-20 16:38:30 -07006944 )
6945 {
6946 /* SoftAP mode, so return from here */
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306947 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6948 "%s: In SAP MODE", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006949 EXIT();
6950 return 0;
6951 }
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05306952 /* Find if any iface is up. If any iface is up then can't put device to
6953 * sleep/power save mode
6954 */
Jeff Johnson295189b2012-06-20 16:38:30 -07006955 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
6956 while ( (NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status) )
6957 {
Jeff Johnson6a81ca42013-04-05 10:37:08 -07006958 if (test_bit(DEVICE_IFACE_OPENED, &pAdapterNode->pAdapter->event_flags))
6959 {
6960 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Still other ifaces are up cannot "
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05306961 "put device to sleep", __func__);
Jeff Johnson6a81ca42013-04-05 10:37:08 -07006962 enter_standby = FALSE;
6963 break;
6964 }
6965 else
6966 {
6967 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
6968 pAdapterNode = pNext;
6969 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006970 }
6971
6972 if (TRUE == enter_standby)
6973 {
6974 hddLog(VOS_TRACE_LEVEL_INFO, "%s: All Interfaces are Down "
6975 "entering standby", __func__);
6976 if (VOS_STATUS_SUCCESS != wlan_hdd_enter_lowpower(pHddCtx))
6977 {
6978 /*log and return success*/
6979 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Failed to put "
6980 "wlan in power save", __func__);
6981 }
6982 }
6983
6984 EXIT();
6985 return 0;
6986}
6987
6988/**---------------------------------------------------------------------------
6989
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05306990 \brief hdd_stop() - wrapper_function for __hdd_stop to protect it from SSR
Jeff Johnson295189b2012-06-20 16:38:30 -07006991
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05306992 This is called in response to ifconfig down
6993
6994 \param - dev Pointer to net_device structure
6995
6996 \return - 0 for success non-zero for failure
6997-----------------------------------------------------------------------------*/
6998int hdd_stop (struct net_device *dev)
6999{
7000 int ret;
7001
7002 vos_ssr_protect(__func__);
7003 ret = __hdd_stop(dev);
7004 vos_ssr_unprotect(__func__);
7005
7006 return ret;
7007}
7008
7009/**---------------------------------------------------------------------------
7010
7011 \brief __hdd_uninit() - HDD uninit function
Jeff Johnson295189b2012-06-20 16:38:30 -07007012
7013 \param - dev Pointer to net_device structure
7014
7015 \return - void
7016
7017 --------------------------------------------------------------------------*/
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05307018static void __hdd_uninit (struct net_device *dev)
Jeff Johnson295189b2012-06-20 16:38:30 -07007019{
7020 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05307021 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07007022 ENTER();
7023
7024 do
7025 {
7026 if (NULL == pAdapter)
7027 {
7028 hddLog(VOS_TRACE_LEVEL_FATAL,
7029 "%s: NULL pAdapter", __func__);
7030 break;
7031 }
7032
7033 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
7034 {
7035 hddLog(VOS_TRACE_LEVEL_FATAL,
7036 "%s: Invalid magic", __func__);
7037 break;
7038 }
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05307039 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7040 if (NULL == pHddCtx)
Jeff Johnson295189b2012-06-20 16:38:30 -07007041 {
7042 hddLog(VOS_TRACE_LEVEL_FATAL,
7043 "%s: NULL pHddCtx", __func__);
7044 break;
7045 }
7046
7047 if (dev != pAdapter->dev)
7048 {
7049 hddLog(VOS_TRACE_LEVEL_FATAL,
7050 "%s: Invalid device reference", __func__);
7051 /* we haven't validated all cases so let this go for now */
7052 }
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05307053#ifdef FEATURE_WLAN_TDLS
7054 mutex_lock(&pHddCtx->tdls_lock);
7055#endif
c_hpothu002231a2015-02-05 14:58:51 +05307056 hdd_deinit_adapter(pHddCtx, pAdapter, TRUE);
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05307057#ifdef FEATURE_WLAN_TDLS
7058 mutex_unlock(&pHddCtx->tdls_lock);
7059#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007060
7061 /* after uninit our adapter structure will no longer be valid */
7062 pAdapter->dev = NULL;
7063 pAdapter->magic = 0;
Manjeet Singh47ee8472016-04-11 11:57:18 +05307064 pAdapter->pHddCtx = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07007065 } while (0);
7066
7067 EXIT();
7068}
7069
7070/**---------------------------------------------------------------------------
7071
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05307072 \brief hdd_uninit() - Wrapper function to protect __hdd_uninit from SSR
7073
7074 This is called during the netdev unregister to uninitialize all data
7075associated with the device
7076
7077 \param - dev Pointer to net_device structure
7078
7079 \return - void
7080
7081 --------------------------------------------------------------------------*/
7082static void hdd_uninit (struct net_device *dev)
7083{
7084 vos_ssr_protect(__func__);
7085 __hdd_uninit(dev);
7086 vos_ssr_unprotect(__func__);
7087}
7088
7089/**---------------------------------------------------------------------------
7090
Jeff Johnson295189b2012-06-20 16:38:30 -07007091 \brief hdd_release_firmware() -
7092
7093 This function calls the release firmware API to free the firmware buffer.
7094
7095 \param - pFileName Pointer to the File Name.
7096 pCtx - Pointer to the adapter .
7097
7098
7099 \return - 0 for success, non zero for failure
7100
7101 --------------------------------------------------------------------------*/
7102
7103VOS_STATUS hdd_release_firmware(char *pFileName,v_VOID_t *pCtx)
7104{
7105 VOS_STATUS status = VOS_STATUS_SUCCESS;
7106 hdd_context_t *pHddCtx = (hdd_context_t*)pCtx;
7107 ENTER();
7108
7109
7110 if (!strcmp(WLAN_FW_FILE, pFileName)) {
7111
7112 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,"%s: Loaded firmware file is %s",__func__,pFileName);
7113
7114 if(pHddCtx->fw) {
7115 release_firmware(pHddCtx->fw);
7116 pHddCtx->fw = NULL;
7117 }
7118 else
7119 status = VOS_STATUS_E_FAILURE;
7120 }
7121 else if (!strcmp(WLAN_NV_FILE,pFileName)) {
7122 if(pHddCtx->nv) {
7123 release_firmware(pHddCtx->nv);
7124 pHddCtx->nv = NULL;
7125 }
7126 else
7127 status = VOS_STATUS_E_FAILURE;
7128
7129 }
7130
7131 EXIT();
7132 return status;
7133}
7134
7135/**---------------------------------------------------------------------------
7136
7137 \brief hdd_request_firmware() -
7138
7139 This function reads the firmware file using the request firmware
7140 API and returns the the firmware data and the firmware file size.
7141
7142 \param - pfileName - Pointer to the file name.
7143 - pCtx - Pointer to the adapter .
7144 - ppfw_data - Pointer to the pointer of the firmware data.
7145 - pSize - Pointer to the file size.
7146
7147 \return - VOS_STATUS_SUCCESS for success, VOS_STATUS_E_FAILURE for failure
7148
7149 --------------------------------------------------------------------------*/
7150
7151
7152VOS_STATUS hdd_request_firmware(char *pfileName,v_VOID_t *pCtx,v_VOID_t **ppfw_data, v_SIZE_t *pSize)
7153{
7154 int status;
7155 VOS_STATUS retval = VOS_STATUS_SUCCESS;
7156 hdd_context_t *pHddCtx = (hdd_context_t*)pCtx;
7157 ENTER();
7158
7159 if( (!strcmp(WLAN_FW_FILE, pfileName)) ) {
7160
7161 status = request_firmware(&pHddCtx->fw, pfileName, pHddCtx->parent_dev);
7162
7163 if(status || !pHddCtx->fw || !pHddCtx->fw->data) {
7164 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Firmware %s download failed",
7165 __func__, pfileName);
7166 retval = VOS_STATUS_E_FAILURE;
7167 }
7168
7169 else {
7170 *ppfw_data = (v_VOID_t *)pHddCtx->fw->data;
7171 *pSize = pHddCtx->fw->size;
7172 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Firmware size = %d",
7173 __func__, *pSize);
7174 }
7175 }
7176 else if(!strcmp(WLAN_NV_FILE, pfileName)) {
7177
7178 status = request_firmware(&pHddCtx->nv, pfileName, pHddCtx->parent_dev);
7179
7180 if(status || !pHddCtx->nv || !pHddCtx->nv->data) {
7181 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: nv %s download failed",
7182 __func__, pfileName);
7183 retval = VOS_STATUS_E_FAILURE;
7184 }
7185
7186 else {
7187 *ppfw_data = (v_VOID_t *)pHddCtx->nv->data;
7188 *pSize = pHddCtx->nv->size;
7189 hddLog(VOS_TRACE_LEVEL_INFO, "%s: nv file size = %d",
7190 __func__, *pSize);
7191 }
7192 }
7193
7194 EXIT();
7195 return retval;
7196}
7197/**---------------------------------------------------------------------------
7198 \brief hdd_full_pwr_cbk() - HDD full power callbackfunction
7199
7200 This is the function invoked by SME to inform the result of a full power
7201 request issued by HDD
7202
7203 \param - callbackcontext - Pointer to cookie
7204 status - result of request
7205
7206 \return - None
7207
7208--------------------------------------------------------------------------*/
7209void hdd_full_pwr_cbk(void *callbackContext, eHalStatus status)
7210{
7211 hdd_context_t *pHddCtx = (hdd_context_t*)callbackContext;
7212
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07007213 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,"HDD full Power callback status = %d", status);
Jeff Johnson295189b2012-06-20 16:38:30 -07007214 if(&pHddCtx->full_pwr_comp_var)
7215 {
7216 complete(&pHddCtx->full_pwr_comp_var);
7217 }
7218}
7219
Abhishek Singh00b71972016-01-07 10:51:04 +05307220#ifdef WLAN_FEATURE_RMC
7221static void hdd_tx_fail_ind_callback(v_U8_t *MacAddr, v_U8_t seqNo)
7222{
7223 int payload_len;
7224 struct sk_buff *skb;
7225 struct nlmsghdr *nlh;
7226 v_U8_t *data;
7227
7228 payload_len = ETH_ALEN;
7229
7230 if (0 == cesium_pid)
7231 {
7232 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: cesium process not registered",
7233 __func__);
7234 return;
7235 }
7236
7237 if ((skb = nlmsg_new(payload_len,GFP_ATOMIC)) == NULL)
7238 {
7239 hddLog(VOS_TRACE_LEVEL_ERROR,
7240 "%s: nlmsg_new() failed for msg size[%d]",
7241 __func__, NLMSG_SPACE(payload_len));
7242 return;
7243 }
7244
7245 nlh = nlmsg_put(skb, cesium_pid, seqNo, 0, payload_len, NLM_F_REQUEST);
7246
7247 if (NULL == nlh)
7248 {
7249 hddLog(VOS_TRACE_LEVEL_ERROR,
7250 "%s: nlmsg_put() failed for msg size[%d]",
7251 __func__, NLMSG_SPACE(payload_len));
7252
7253 kfree_skb(skb);
7254 return;
7255 }
7256
7257 data = nlmsg_data(nlh);
7258 memcpy(data, MacAddr, ETH_ALEN);
7259
7260 if (nlmsg_unicast(cesium_nl_srv_sock, skb, cesium_pid) < 0)
7261 {
7262 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: nlmsg_unicast() failed for msg size[%d]",
7263 __func__, NLMSG_SPACE(payload_len));
7264 }
7265
7266 return;
7267}
7268
7269/**---------------------------------------------------------------------------
7270 \brief hdd_ParseuserParams - return a pointer to the next argument
7271
7272 \return - status
7273
7274--------------------------------------------------------------------------*/
7275static int hdd_ParseUserParams(tANI_U8 *pValue, tANI_U8 **ppArg)
7276{
7277 tANI_U8 *pVal;
7278
7279 pVal = strchr(pValue, ' ');
7280
7281 if (NULL == pVal)
7282 {
7283 /* no argument remains */
7284 return -EINVAL;
7285 }
7286 else if (SPACE_ASCII_VALUE != *pVal)
7287 {
7288 /* no space after the current argument */
7289 return -EINVAL;
7290 }
7291
7292 pVal++;
7293
7294 /* remove empty spaces */
7295 while ((SPACE_ASCII_VALUE == *pVal) && ('\0' != *pVal))
7296 {
7297 pVal++;
7298 }
7299
7300 /* no argument followed by spaces */
7301 if ('\0' == *pVal)
7302 {
7303 return -EINVAL;
7304 }
7305
7306 *ppArg = pVal;
7307
7308 return 0;
7309}
7310
7311/**----------------------------------------------------------------------------
7312 \brief hdd_ParseIBSSTXFailEventParams - Parse params for SETIBSSTXFAILEVENT
7313
7314 \return - status
7315
7316------------------------------------------------------------------------------*/
7317static int hdd_ParseIBSSTXFailEventParams(tANI_U8 *pValue,
7318 tANI_U8 *tx_fail_count,
7319 tANI_U16 *pid)
7320{
7321 tANI_U8 *param = NULL;
7322 int ret;
7323
7324 ret = hdd_ParseUserParams(pValue, &param);
7325
7326 if (0 == ret && NULL != param)
7327 {
7328 if (1 != sscanf(param, "%hhu", tx_fail_count))
7329 {
7330 ret = -EINVAL;
7331 goto done;
7332 }
7333 }
7334 else
7335 {
7336 goto done;
7337 }
7338
7339 if (0 == *tx_fail_count)
7340 {
7341 *pid = 0;
7342 goto done;
7343 }
7344
7345 pValue = param;
7346 pValue++;
7347
7348 ret = hdd_ParseUserParams(pValue, &param);
7349
7350 if (0 == ret)
7351 {
7352 if (1 != sscanf(param, "%hu", pid))
7353 {
7354 ret = -EINVAL;
7355 goto done;
7356 }
7357 }
7358 else
7359 {
7360 goto done;
7361 }
7362
7363done:
7364 return ret;
7365}
7366
7367static int hdd_open_cesium_nl_sock()
7368{
7369#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
7370 struct netlink_kernel_cfg cfg = {
7371 .groups = WLAN_NLINK_MCAST_GRP_ID,
7372 .input = NULL
7373 };
7374#endif
7375 int ret = 0;
7376
7377#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
7378 cesium_nl_srv_sock = netlink_kernel_create(&init_net, WLAN_NLINK_CESIUM,
7379#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,7,0))
7380 THIS_MODULE,
7381#endif
7382 &cfg);
7383#else
7384 cesium_nl_srv_sock = netlink_kernel_create(&init_net, WLAN_NLINK_CESIUM,
7385 WLAN_NLINK_MCAST_GRP_ID, NULL, NULL, THIS_MODULE);
7386#endif
7387
7388 if (cesium_nl_srv_sock == NULL)
7389 {
7390 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7391 "NLINK: cesium netlink_kernel_create failed");
7392 ret = -ECONNREFUSED;
7393 }
7394
7395 return ret;
7396}
7397
7398static void hdd_close_cesium_nl_sock()
7399{
7400 if (NULL != cesium_nl_srv_sock)
7401 {
7402 netlink_kernel_release(cesium_nl_srv_sock);
7403 cesium_nl_srv_sock = NULL;
7404 }
7405}
7406#endif /* WLAN_FEATURE_RMC */
Jeff Johnson295189b2012-06-20 16:38:30 -07007407/**---------------------------------------------------------------------------
7408
7409 \brief hdd_req_bmps_cbk() - HDD Request BMPS callback function
7410
7411 This is the function invoked by SME to inform the result of BMPS
7412 request issued by HDD
7413
7414 \param - callbackcontext - Pointer to cookie
7415 status - result of request
7416
7417 \return - None
7418
7419--------------------------------------------------------------------------*/
7420void hdd_req_bmps_cbk(void *callbackContext, eHalStatus status)
7421{
7422
7423 struct completion *completion_var = (struct completion*) callbackContext;
7424
Arif Hussain6d2a3322013-11-17 19:50:10 -08007425 hddLog(VOS_TRACE_LEVEL_ERROR, "HDD BMPS request Callback, status = %d", status);
Jeff Johnson295189b2012-06-20 16:38:30 -07007426 if(completion_var != NULL)
7427 {
7428 complete(completion_var);
7429 }
7430}
7431
7432/**---------------------------------------------------------------------------
7433
7434 \brief hdd_get_cfg_file_size() -
7435
7436 This function reads the configuration file using the request firmware
7437 API and returns the configuration file size.
7438
7439 \param - pCtx - Pointer to the adapter .
7440 - pFileName - Pointer to the file name.
7441 - pBufSize - Pointer to the buffer size.
7442
7443 \return - 0 for success, non zero for failure
7444
7445 --------------------------------------------------------------------------*/
7446
7447VOS_STATUS hdd_get_cfg_file_size(v_VOID_t *pCtx, char *pFileName, v_SIZE_t *pBufSize)
7448{
7449 int status;
7450 hdd_context_t *pHddCtx = (hdd_context_t*)pCtx;
7451
7452 ENTER();
7453
7454 status = request_firmware(&pHddCtx->fw, pFileName, pHddCtx->parent_dev);
7455
7456 if(status || !pHddCtx->fw || !pHddCtx->fw->data) {
7457 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: CFG download failed",__func__);
7458 status = VOS_STATUS_E_FAILURE;
7459 }
7460 else {
7461 *pBufSize = pHddCtx->fw->size;
7462 hddLog(VOS_TRACE_LEVEL_INFO, "%s: CFG size = %d", __func__, *pBufSize);
7463 release_firmware(pHddCtx->fw);
7464 pHddCtx->fw = NULL;
7465 }
7466
7467 EXIT();
7468 return VOS_STATUS_SUCCESS;
7469}
7470
7471/**---------------------------------------------------------------------------
7472
7473 \brief hdd_read_cfg_file() -
7474
7475 This function reads the configuration file using the request firmware
7476 API and returns the cfg data and the buffer size of the configuration file.
7477
7478 \param - pCtx - Pointer to the adapter .
7479 - pFileName - Pointer to the file name.
7480 - pBuffer - Pointer to the data buffer.
7481 - pBufSize - Pointer to the buffer size.
7482
7483 \return - 0 for success, non zero for failure
7484
7485 --------------------------------------------------------------------------*/
7486
7487VOS_STATUS hdd_read_cfg_file(v_VOID_t *pCtx, char *pFileName,
7488 v_VOID_t *pBuffer, v_SIZE_t *pBufSize)
7489{
7490 int status;
7491 hdd_context_t *pHddCtx = (hdd_context_t*)pCtx;
7492
7493 ENTER();
7494
7495 status = request_firmware(&pHddCtx->fw, pFileName, pHddCtx->parent_dev);
7496
7497 if(status || !pHddCtx->fw || !pHddCtx->fw->data) {
7498 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: CFG download failed",__func__);
7499 return VOS_STATUS_E_FAILURE;
7500 }
7501 else {
7502 if(*pBufSize != pHddCtx->fw->size) {
7503 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Caller sets invalid CFG "
7504 "file size", __func__);
7505 release_firmware(pHddCtx->fw);
7506 pHddCtx->fw = NULL;
7507 return VOS_STATUS_E_FAILURE;
7508 }
7509 else {
7510 if(pBuffer) {
7511 vos_mem_copy(pBuffer,pHddCtx->fw->data,*pBufSize);
7512 }
7513 release_firmware(pHddCtx->fw);
7514 pHddCtx->fw = NULL;
7515 }
7516 }
7517
7518 EXIT();
7519
7520 return VOS_STATUS_SUCCESS;
7521}
7522
7523/**---------------------------------------------------------------------------
7524
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05307525 \brief __hdd_set_mac_address() -
Jeff Johnson295189b2012-06-20 16:38:30 -07007526
7527 This function sets the user specified mac address using
7528 the command ifconfig wlanX hw ether <mac adress>.
7529
7530 \param - dev - Pointer to the net device.
7531 - addr - Pointer to the sockaddr.
7532 \return - 0 for success, non zero for failure
7533
7534 --------------------------------------------------------------------------*/
7535
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05307536static int __hdd_set_mac_address(struct net_device *dev, void *addr)
Jeff Johnson295189b2012-06-20 16:38:30 -07007537{
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05307538 hdd_adapter_t *pAdapter;
7539 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07007540 struct sockaddr *psta_mac_addr = addr;
7541 eHalStatus halStatus = eHAL_STATUS_SUCCESS;
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05307542 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07007543
7544 ENTER();
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05307545 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
7546 if (NULL == pAdapter)
7547 {
7548 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7549 "%s: Adapter is NULL",__func__);
7550 return -EINVAL;
7551 }
7552 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7553 ret = wlan_hdd_validate_context(pHddCtx);
7554 if (0 != ret)
7555 {
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05307556 return ret;
7557 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007558
7559 memcpy(&pAdapter->macAddressCurrent, psta_mac_addr->sa_data, ETH_ALEN);
Jeff Johnson295189b2012-06-20 16:38:30 -07007560 memcpy(dev->dev_addr, psta_mac_addr->sa_data, ETH_ALEN);
7561
7562 EXIT();
7563 return halStatus;
7564}
7565
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05307566/**---------------------------------------------------------------------------
7567
7568 \brief hdd_set_mac_address() -
7569
7570 Wrapper function to protect __hdd_set_mac_address() function from ssr
7571
7572 \param - dev - Pointer to the net device.
7573 - addr - Pointer to the sockaddr.
7574 \return - 0 for success, non zero for failure
7575
7576 --------------------------------------------------------------------------*/
7577static int hdd_set_mac_address(struct net_device *dev, void *addr)
7578{
7579 int ret;
7580
7581 vos_ssr_protect(__func__);
7582 ret = __hdd_set_mac_address(dev, addr);
7583 vos_ssr_unprotect(__func__);
7584
7585 return ret;
7586}
7587
Jeff Johnson295189b2012-06-20 16:38:30 -07007588tANI_U8* wlan_hdd_get_intf_addr(hdd_context_t* pHddCtx)
7589{
7590 int i;
7591 for ( i = 0; i < VOS_MAX_CONCURRENCY_PERSONA; i++)
7592 {
Abhishek Singheb183782014-02-06 13:37:21 +05307593 if( 0 == ((pHddCtx->cfg_ini->intfAddrMask) & (1 << i)) )
Jeff Johnson295189b2012-06-20 16:38:30 -07007594 break;
7595 }
7596
7597 if( VOS_MAX_CONCURRENCY_PERSONA == i)
7598 return NULL;
7599
7600 pHddCtx->cfg_ini->intfAddrMask |= (1 << i);
7601 return &pHddCtx->cfg_ini->intfMacAddr[i].bytes[0];
7602}
7603
7604void wlan_hdd_release_intf_addr(hdd_context_t* pHddCtx, tANI_U8* releaseAddr)
7605{
7606 int i;
7607 for ( i = 0; i < VOS_MAX_CONCURRENCY_PERSONA; i++)
7608 {
7609 if ( !memcmp(releaseAddr, &pHddCtx->cfg_ini->intfMacAddr[i].bytes[0], 6) )
7610 {
7611 pHddCtx->cfg_ini->intfAddrMask &= ~(1 << i);
7612 break;
7613 }
7614 }
7615 return;
7616}
7617
7618#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29))
7619 static struct net_device_ops wlan_drv_ops = {
7620 .ndo_open = hdd_open,
7621 .ndo_stop = hdd_stop,
7622 .ndo_uninit = hdd_uninit,
7623 .ndo_start_xmit = hdd_hard_start_xmit,
7624 .ndo_tx_timeout = hdd_tx_timeout,
7625 .ndo_get_stats = hdd_stats,
7626 .ndo_do_ioctl = hdd_ioctl,
7627 .ndo_set_mac_address = hdd_set_mac_address,
7628 .ndo_select_queue = hdd_select_queue,
7629#ifdef WLAN_FEATURE_PACKET_FILTERING
7630#if (LINUX_VERSION_CODE > KERNEL_VERSION(3,1,0))
7631 .ndo_set_rx_mode = hdd_set_multicast_list,
7632#else
7633 .ndo_set_multicast_list = hdd_set_multicast_list,
7634#endif //LINUX_VERSION_CODE
7635#endif
7636 };
Jeff Johnson295189b2012-06-20 16:38:30 -07007637 static struct net_device_ops wlan_mon_drv_ops = {
7638 .ndo_open = hdd_mon_open,
Katya Nigame7b69a82015-04-28 15:24:06 +05307639 .ndo_stop = hdd_mon_stop,
Jeff Johnson295189b2012-06-20 16:38:30 -07007640 .ndo_uninit = hdd_uninit,
7641 .ndo_start_xmit = hdd_mon_hard_start_xmit,
7642 .ndo_tx_timeout = hdd_tx_timeout,
7643 .ndo_get_stats = hdd_stats,
Katya Nigame7b69a82015-04-28 15:24:06 +05307644 .ndo_do_ioctl = hdd_mon_ioctl,
Jeff Johnson295189b2012-06-20 16:38:30 -07007645 .ndo_set_mac_address = hdd_set_mac_address,
7646 };
Mahesh A Saptasagar305e2632015-03-04 12:57:33 +05307647
Jeff Johnson295189b2012-06-20 16:38:30 -07007648#endif
7649
7650void hdd_set_station_ops( struct net_device *pWlanDev )
7651{
7652#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29))
Jeff Johnson295189b2012-06-20 16:38:30 -07007653 pWlanDev->netdev_ops = &wlan_drv_ops;
7654#else
7655 pWlanDev->open = hdd_open;
7656 pWlanDev->stop = hdd_stop;
7657 pWlanDev->uninit = hdd_uninit;
7658 pWlanDev->hard_start_xmit = NULL;
7659 pWlanDev->tx_timeout = hdd_tx_timeout;
7660 pWlanDev->get_stats = hdd_stats;
7661 pWlanDev->do_ioctl = hdd_ioctl;
Jeff Johnson295189b2012-06-20 16:38:30 -07007662 pWlanDev->set_mac_address = hdd_set_mac_address;
7663#endif
7664}
7665
Katya Nigam1fd24402015-02-16 14:52:19 +05307666void hdd_set_ibss_ops( hdd_adapter_t *pAdapter )
7667{
7668 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29))
7669 wlan_drv_ops.ndo_start_xmit = hdd_ibss_hard_start_xmit;
7670 #else
7671 pAdapter->dev->hard_start_xmit = hdd_ibss_hard_start_xmit;
7672 #endif
7673}
7674
Jeff Johnsoneed415b2013-01-18 16:11:20 -08007675static hdd_adapter_t* hdd_alloc_station_adapter( hdd_context_t *pHddCtx, tSirMacAddr macAddr, const char* name )
Jeff Johnson295189b2012-06-20 16:38:30 -07007676{
7677 struct net_device *pWlanDev = NULL;
7678 hdd_adapter_t *pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07007679 /*
7680 * cfg80211 initialization and registration....
7681 */
Anand N Sunkadc34abbd2015-07-29 09:52:59 +05307682 pWlanDev = alloc_netdev_mq(sizeof( hdd_adapter_t ), name,
7683#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,17,0))
7684 NET_NAME_UNKNOWN,
7685#endif
7686 ether_setup, NUM_TX_QUEUES);
Jeff Johnson295189b2012-06-20 16:38:30 -07007687 if(pWlanDev != NULL)
7688 {
7689
7690 //Save the pointer to the net_device in the HDD adapter
7691 pAdapter = (hdd_adapter_t*) netdev_priv( pWlanDev );
7692
Jeff Johnson295189b2012-06-20 16:38:30 -07007693 vos_mem_zero( pAdapter, sizeof( hdd_adapter_t ) );
7694
7695 pAdapter->dev = pWlanDev;
7696 pAdapter->pHddCtx = pHddCtx;
7697 pAdapter->magic = WLAN_HDD_ADAPTER_MAGIC;
Agarwal Ashish47d18112014-08-04 19:55:07 +05307698 spin_lock_init(&pAdapter->lock_for_active_session);
Jeff Johnson295189b2012-06-20 16:38:30 -07007699
Rajeev79dbe4c2013-10-05 11:03:42 +05307700#ifdef FEATURE_WLAN_BATCH_SCAN
Rajeev79dbe4c2013-10-05 11:03:42 +05307701 pAdapter->pBatchScanRsp = NULL;
7702 pAdapter->numScanList = 0;
Rajeev Kumar20140c12013-10-21 19:39:02 -07007703 pAdapter->batchScanState = eHDD_BATCH_SCAN_STATE_STOPPED;
Kiet Lamaa8e15a2014-02-11 23:30:06 -08007704 pAdapter->prev_batch_id = 0;
Rajeev79dbe4c2013-10-05 11:03:42 +05307705 mutex_init(&pAdapter->hdd_batch_scan_lock);
7706#endif
7707
Jeff Johnson295189b2012-06-20 16:38:30 -07007708 pAdapter->isLinkUpSvcNeeded = FALSE;
7709 pAdapter->higherDtimTransition = eANI_BOOLEAN_TRUE;
7710 //Init the net_device structure
7711 strlcpy(pWlanDev->name, name, IFNAMSIZ);
7712
7713 vos_mem_copy(pWlanDev->dev_addr, (void *)macAddr, sizeof(tSirMacAddr));
7714 vos_mem_copy( pAdapter->macAddressCurrent.bytes, macAddr, sizeof(tSirMacAddr));
7715 pWlanDev->watchdog_timeo = HDD_TX_TIMEOUT;
7716 pWlanDev->hard_header_len += LIBRA_HW_NEEDED_HEADROOM;
7717
7718 hdd_set_station_ops( pAdapter->dev );
7719
7720 pWlanDev->destructor = free_netdev;
Jeff Johnson295189b2012-06-20 16:38:30 -07007721 pWlanDev->ieee80211_ptr = &pAdapter->wdev ;
7722 pAdapter->wdev.wiphy = pHddCtx->wiphy;
7723 pAdapter->wdev.netdev = pWlanDev;
Jeff Johnson295189b2012-06-20 16:38:30 -07007724 /* set pWlanDev's parent to underlying device */
7725 SET_NETDEV_DEV(pWlanDev, pHddCtx->parent_dev);
Kumar Anand82c009f2014-05-29 00:29:42 -07007726
7727 hdd_wmm_init( pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -07007728 }
7729
7730 return pAdapter;
7731}
7732
7733VOS_STATUS hdd_register_interface( hdd_adapter_t *pAdapter, tANI_U8 rtnl_lock_held )
7734{
7735 struct net_device *pWlanDev = pAdapter->dev;
7736 //hdd_station_ctx_t *pHddStaCtx = &pAdapter->sessionCtx.station;
7737 //hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
7738 //eHalStatus halStatus = eHAL_STATUS_SUCCESS;
7739
7740 if( rtnl_lock_held )
7741 {
Madan Mohan Koyyalamudid8ac8662012-11-06 19:04:56 -08007742 if (strnchr(pWlanDev->name, strlen(pWlanDev->name), '%')) {
Jeff Johnson295189b2012-06-20 16:38:30 -07007743 if( dev_alloc_name(pWlanDev, pWlanDev->name) < 0 )
7744 {
7745 hddLog(VOS_TRACE_LEVEL_ERROR,"%s:Failed:dev_alloc_name",__func__);
7746 return VOS_STATUS_E_FAILURE;
7747 }
7748 }
7749 if (register_netdevice(pWlanDev))
7750 {
7751 hddLog(VOS_TRACE_LEVEL_ERROR,"%s:Failed:register_netdev",__func__);
7752 return VOS_STATUS_E_FAILURE;
7753 }
7754 }
7755 else
7756 {
7757 if(register_netdev(pWlanDev))
7758 {
7759 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Failed:register_netdev",__func__);
7760 return VOS_STATUS_E_FAILURE;
7761 }
7762 }
7763 set_bit(NET_DEVICE_REGISTERED, &pAdapter->event_flags);
7764
7765 return VOS_STATUS_SUCCESS;
7766}
7767
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07007768static eHalStatus hdd_smeCloseSessionCallback(void *pContext)
Jeff Johnson295189b2012-06-20 16:38:30 -07007769{
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07007770 hdd_adapter_t *pAdapter = pContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07007771
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07007772 if (NULL == pAdapter)
7773 {
7774 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: NULL pAdapter", __func__);
7775 return eHAL_STATUS_INVALID_PARAMETER;
Jeff Johnson295189b2012-06-20 16:38:30 -07007776 }
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07007777
7778 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
7779 {
7780 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Invalid magic", __func__);
7781 return eHAL_STATUS_NOT_INITIALIZED;
7782 }
7783
7784 clear_bit(SME_SESSION_OPENED, &pAdapter->event_flags);
7785
Sameer Thalappilbee426e2013-10-30 10:30:30 -07007786#ifndef WLAN_OPEN_SOURCE
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07007787 /* need to make sure all of our scheduled work has completed.
7788 * This callback is called from MC thread context, so it is safe to
7789 * to call below flush workqueue API from here.
Sameer Thalappilbee426e2013-10-30 10:30:30 -07007790 *
7791 * Even though this is called from MC thread context, if there is a faulty
7792 * work item in the system, that can hang this call forever. So flushing
7793 * this global work queue is not safe; and now we make sure that
7794 * individual work queues are stopped correctly. But the cancel work queue
7795 * is a GPL only API, so the proprietary version of the driver would still
7796 * rely on the global work queue flush.
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07007797 */
7798 flush_scheduled_work();
Sameer Thalappilbee426e2013-10-30 10:30:30 -07007799#endif
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07007800
7801 /* We can be blocked while waiting for scheduled work to be
7802 * flushed, and the adapter structure can potentially be freed, in
7803 * which case the magic will have been reset. So make sure the
7804 * magic is still good, and hence the adapter structure is still
7805 * valid, before signaling completion */
7806 if (WLAN_HDD_ADAPTER_MAGIC == pAdapter->magic)
7807 {
7808 complete(&pAdapter->session_close_comp_var);
7809 }
7810
Jeff Johnson295189b2012-06-20 16:38:30 -07007811 return eHAL_STATUS_SUCCESS;
7812}
Manjeet Singh47ee8472016-04-11 11:57:18 +05307813/**
7814 * hdd_close_tx_queues() - close tx queues
7815 * @hdd_ctx: hdd global context
7816 *
7817 * Return: None
7818 */
7819static void hdd_close_tx_queues(hdd_context_t *hdd_ctx)
7820{
7821 VOS_STATUS status;
7822 hdd_adapter_t *adapter;
7823 hdd_adapter_list_node_t *adapter_node = NULL, *next_adapter = NULL;
7824 /* Not validating hdd_ctx as it's already done by the caller */
7825 ENTER();
7826 status = hdd_get_front_adapter(hdd_ctx, &adapter_node);
7827 while (NULL != adapter_node && VOS_STATUS_SUCCESS == status) {
7828 adapter = adapter_node->pAdapter;
7829 if (adapter && adapter->dev) {
7830 netif_tx_disable (adapter->dev);
7831 netif_carrier_off(adapter->dev);
7832 }
7833 status = hdd_get_next_adapter(hdd_ctx, adapter_node,
7834 &next_adapter);
7835 adapter_node = next_adapter;
7836 }
7837 EXIT();
7838}
Jeff Johnson295189b2012-06-20 16:38:30 -07007839
7840VOS_STATUS hdd_init_station_mode( hdd_adapter_t *pAdapter )
7841{
7842 struct net_device *pWlanDev = pAdapter->dev;
7843 hdd_station_ctx_t *pHddStaCtx = &pAdapter->sessionCtx.station;
7844 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
7845 eHalStatus halStatus = eHAL_STATUS_SUCCESS;
7846 VOS_STATUS status = VOS_STATUS_E_FAILURE;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307847 long rc = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07007848
Nirav Shah7e3c8132015-06-22 23:51:42 +05307849 spin_lock_init( &pAdapter->sta_hash_lock);
7850 pAdapter->is_sta_id_hash_initialized = VOS_FALSE;
7851
Jeff Johnson295189b2012-06-20 16:38:30 -07007852 INIT_COMPLETION(pAdapter->session_open_comp_var);
Kiran Kumar Lokere0ad5cd32013-06-25 11:26:22 -07007853 sme_SetCurrDeviceMode(pHddCtx->hHal, pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07007854 //Open a SME session for future operation
7855 halStatus = sme_OpenSession( pHddCtx->hHal, hdd_smeRoamCallback, pAdapter,
Kiran Kumar Lokere0ad5cd32013-06-25 11:26:22 -07007856 (tANI_U8 *)&pAdapter->macAddressCurrent, &pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07007857 if ( !HAL_STATUS_SUCCESS( halStatus ) )
7858 {
7859 hddLog(VOS_TRACE_LEVEL_FATAL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07007860 "sme_OpenSession() failed with status code %08d [x%08x]",
Jeff Johnson295189b2012-06-20 16:38:30 -07007861 halStatus, halStatus );
7862 status = VOS_STATUS_E_FAILURE;
7863 goto error_sme_open;
7864 }
7865
7866 //Block on a completion variable. Can't wait forever though.
Vinay Krishna Eranna0fe2e7c2014-04-09 21:32:08 +05307867 rc = wait_for_completion_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -07007868 &pAdapter->session_open_comp_var,
7869 msecs_to_jiffies(WLAN_WAIT_TIME_SESSIONOPENCLOSE));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307870 if (rc <= 0)
Jeff Johnson295189b2012-06-20 16:38:30 -07007871 {
7872 hddLog(VOS_TRACE_LEVEL_FATAL,
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307873 "Session is not opened within timeout period code %ld", rc );
Jeff Johnson295189b2012-06-20 16:38:30 -07007874 status = VOS_STATUS_E_FAILURE;
7875 goto error_sme_open;
7876 }
7877
7878 // Register wireless extensions
7879 if( eHAL_STATUS_SUCCESS != (halStatus = hdd_register_wext(pWlanDev)))
7880 {
7881 hddLog(VOS_TRACE_LEVEL_FATAL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07007882 "hdd_register_wext() failed with status code %08d [x%08x]",
Jeff Johnson295189b2012-06-20 16:38:30 -07007883 halStatus, halStatus );
7884 status = VOS_STATUS_E_FAILURE;
7885 goto error_register_wext;
7886 }
Katya Nigam1fd24402015-02-16 14:52:19 +05307887
Jeff Johnson295189b2012-06-20 16:38:30 -07007888 //Safe to register the hard_start_xmit function again
Katya Nigam1fd24402015-02-16 14:52:19 +05307889 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29))
7890 wlan_drv_ops.ndo_start_xmit = hdd_hard_start_xmit;
7891 #else
7892 pWlanDev->hard_start_xmit = hdd_hard_start_xmit;
7893 #endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007894
7895 //Set the Connection State to Not Connected
Abhishek Singhf4669da2014-05-26 15:07:49 +05307896 hddLog(VOS_TRACE_LEVEL_INFO,
7897 "%s: Set HDD connState to eConnectionState_NotConnected",
7898 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007899 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
7900
7901 //Set the default operation channel
7902 pHddStaCtx->conn_info.operationChannel = pHddCtx->cfg_ini->OperatingChannel;
7903
7904 /* Make the default Auth Type as OPEN*/
7905 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_OPEN_SYSTEM;
7906
7907 if( VOS_STATUS_SUCCESS != ( status = hdd_init_tx_rx( pAdapter ) ) )
7908 {
7909 hddLog(VOS_TRACE_LEVEL_FATAL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07007910 "hdd_init_tx_rx() failed with status code %08d [x%08x]",
Jeff Johnson295189b2012-06-20 16:38:30 -07007911 status, status );
7912 goto error_init_txrx;
7913 }
7914
7915 set_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
7916
7917 if( VOS_STATUS_SUCCESS != ( status = hdd_wmm_adapter_init( pAdapter ) ) )
7918 {
7919 hddLog(VOS_TRACE_LEVEL_FATAL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07007920 "hdd_wmm_adapter_init() failed with status code %08d [x%08x]",
Jeff Johnson295189b2012-06-20 16:38:30 -07007921 status, status );
7922 goto error_wmm_init;
7923 }
7924
7925 set_bit(WMM_INIT_DONE, &pAdapter->event_flags);
7926
7927 return VOS_STATUS_SUCCESS;
7928
7929error_wmm_init:
7930 clear_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
7931 hdd_deinit_tx_rx(pAdapter);
7932error_init_txrx:
7933 hdd_UnregisterWext(pWlanDev);
7934error_register_wext:
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07007935 if (test_bit(SME_SESSION_OPENED, &pAdapter->event_flags))
Jeff Johnson295189b2012-06-20 16:38:30 -07007936 {
7937 INIT_COMPLETION(pAdapter->session_close_comp_var);
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07007938 if (eHAL_STATUS_SUCCESS == sme_CloseSession(pHddCtx->hHal,
Agrawal Ashish5a3522c2016-03-02 15:08:28 +05307939 pAdapter->sessionId, FALSE, VOS_TRUE,
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07007940 hdd_smeCloseSessionCallback, pAdapter))
Jeff Johnson295189b2012-06-20 16:38:30 -07007941 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307942 unsigned long rc;
7943
Jeff Johnson295189b2012-06-20 16:38:30 -07007944 //Block on a completion variable. Can't wait forever though.
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307945 rc = wait_for_completion_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -07007946 &pAdapter->session_close_comp_var,
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07007947 msecs_to_jiffies(WLAN_WAIT_TIME_SESSIONOPENCLOSE));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307948 if (rc <= 0)
7949 hddLog(VOS_TRACE_LEVEL_ERROR,
7950 FL("Session is not opened within timeout period code %ld"), rc);
Jeff Johnson295189b2012-06-20 16:38:30 -07007951 }
7952}
7953error_sme_open:
7954 return status;
7955}
7956
Jeff Johnson295189b2012-06-20 16:38:30 -07007957void hdd_cleanup_actionframe( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter )
7958{
7959 hdd_cfg80211_state_t *cfgState;
7960
7961 cfgState = WLAN_HDD_GET_CFG_STATE_PTR( pAdapter );
7962
7963 if( NULL != cfgState->buf )
7964 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307965 long rc;
Jeff Johnson295189b2012-06-20 16:38:30 -07007966 INIT_COMPLETION(pAdapter->tx_action_cnf_event);
7967 rc = wait_for_completion_interruptible_timeout(
7968 &pAdapter->tx_action_cnf_event,
7969 msecs_to_jiffies(ACTION_FRAME_TX_TIMEOUT));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307970 if (rc <= 0)
Jeff Johnson295189b2012-06-20 16:38:30 -07007971 {
Deepthi Gowri91b3e9c2015-08-25 13:14:58 +05307972 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7973 "%s ERROR: HDD Wait for Action Confirmation Failed!! %ld"
7974 , __func__, rc);
7975
7976 // Inform tx status as FAILURE to upper layer and free cfgState->buf
7977 hdd_sendActionCnf( pAdapter, FALSE );
Jeff Johnson295189b2012-06-20 16:38:30 -07007978 }
7979 }
7980 return;
7981}
Jeff Johnson295189b2012-06-20 16:38:30 -07007982
c_hpothu002231a2015-02-05 14:58:51 +05307983void hdd_deinit_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter, tANI_U8 rtnl_held )
Jeff Johnson295189b2012-06-20 16:38:30 -07007984{
7985 ENTER();
7986 switch ( pAdapter->device_mode )
7987 {
Katya Nigam1fd24402015-02-16 14:52:19 +05307988 case WLAN_HDD_IBSS:
7989 {
7990 if(test_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags))
7991 {
7992 hdd_ibss_deinit_tx_rx( pAdapter );
7993 clear_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
7994 }
7995 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007996 case WLAN_HDD_INFRA_STATION:
7997 case WLAN_HDD_P2P_CLIENT:
Jeff Johnsone7245742012-09-05 17:12:55 -07007998 case WLAN_HDD_P2P_DEVICE:
Jeff Johnson295189b2012-06-20 16:38:30 -07007999 {
8000 if(test_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags))
8001 {
8002 hdd_deinit_tx_rx( pAdapter );
8003 clear_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
8004 }
8005
8006 if(test_bit(WMM_INIT_DONE, &pAdapter->event_flags))
8007 {
8008 hdd_wmm_adapter_close( pAdapter );
8009 clear_bit(WMM_INIT_DONE, &pAdapter->event_flags);
8010 }
8011
Jeff Johnson295189b2012-06-20 16:38:30 -07008012 hdd_cleanup_actionframe(pHddCtx, pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07008013 break;
8014 }
8015
8016 case WLAN_HDD_SOFTAP:
8017 case WLAN_HDD_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07008018 {
Madan Mohan Koyyalamudi8c6dec82013-09-26 15:56:13 +05308019
8020 if (test_bit(WMM_INIT_DONE, &pAdapter->event_flags))
8021 {
8022 hdd_wmm_adapter_close( pAdapter );
8023 clear_bit(WMM_INIT_DONE, &pAdapter->event_flags);
8024 }
8025
Jeff Johnson295189b2012-06-20 16:38:30 -07008026 hdd_cleanup_actionframe(pHddCtx, pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07008027
c_hpothu002231a2015-02-05 14:58:51 +05308028 hdd_unregister_hostapd(pAdapter, rtnl_held);
Jeff Johnson295189b2012-06-20 16:38:30 -07008029 hdd_set_conparam( 0 );
Jeff Johnson295189b2012-06-20 16:38:30 -07008030 break;
8031 }
8032
8033 case WLAN_HDD_MONITOR:
8034 {
Jeff Johnson295189b2012-06-20 16:38:30 -07008035 if(test_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags))
8036 {
8037 hdd_deinit_tx_rx( pAdapter );
8038 clear_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
8039 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008040 break;
8041 }
8042
8043
8044 default:
8045 break;
8046 }
8047
8048 EXIT();
8049}
8050
8051void hdd_cleanup_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter, tANI_U8 rtnl_held )
8052{
Mingcheng Zhu87f22fc2014-01-30 19:23:32 -08008053 struct net_device *pWlanDev = NULL;
Srinivas, Dasari693dfc52013-12-27 17:29:09 +05308054
8055 ENTER();
8056 if (NULL == pAdapter)
8057 {
8058 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8059 "%s: HDD adapter is Null", __func__);
8060 return;
8061 }
8062
8063 pWlanDev = pAdapter->dev;
Jeff Johnson295189b2012-06-20 16:38:30 -07008064
Rajeev79dbe4c2013-10-05 11:03:42 +05308065#ifdef FEATURE_WLAN_BATCH_SCAN
Srinivas, Dasari693dfc52013-12-27 17:29:09 +05308066 if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
8067 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Rajeev Kumarf999e582014-01-09 17:33:29 -08008068 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Srinivas, Dasari693dfc52013-12-27 17:29:09 +05308069 || (pAdapter->device_mode == WLAN_HDD_P2P_DEVICE)
8070 )
8071 {
Rajeev Kumarf999e582014-01-09 17:33:29 -08008072 if (pAdapter)
Rajeev79dbe4c2013-10-05 11:03:42 +05308073 {
Rajeev Kumarf999e582014-01-09 17:33:29 -08008074 if (eHDD_BATCH_SCAN_STATE_STARTED == pAdapter->batchScanState)
8075 {
8076 hdd_deinit_batch_scan(pAdapter);
8077 }
Rajeev79dbe4c2013-10-05 11:03:42 +05308078 }
Rajeev Kumarf999e582014-01-09 17:33:29 -08008079 }
Rajeev79dbe4c2013-10-05 11:03:42 +05308080#endif
8081
Jeff Johnson295189b2012-06-20 16:38:30 -07008082 if(test_bit(NET_DEVICE_REGISTERED, &pAdapter->event_flags)) {
8083 if( rtnl_held )
8084 {
8085 unregister_netdevice(pWlanDev);
8086 }
8087 else
8088 {
8089 unregister_netdev(pWlanDev);
8090 }
8091 // note that the pAdapter is no longer valid at this point
8092 // since the memory has been reclaimed
8093 }
8094
Srinivas, Dasari693dfc52013-12-27 17:29:09 +05308095 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07008096}
8097
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08008098void hdd_set_pwrparams(hdd_context_t *pHddCtx)
8099{
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05308100 VOS_STATUS status;
8101 hdd_adapter_t *pAdapter = NULL;
8102 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08008103
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05308104 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08008105
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05308106 /*loop through all adapters.*/
8107 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08008108 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05308109 pAdapter = pAdapterNode->pAdapter;
8110 if ( (WLAN_HDD_INFRA_STATION != pAdapter->device_mode)
8111 && (WLAN_HDD_P2P_CLIENT != pAdapter->device_mode) )
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08008112
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05308113 { // we skip this registration for modes other than STA and P2P client modes.
8114 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
8115 pAdapterNode = pNext;
8116 continue;
8117 }
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08008118
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05308119 //Apply Dynamic DTIM For P2P
8120 //Only if ignoreDynamicDtimInP2pMode is not set in ini
8121 if ((pHddCtx->cfg_ini->enableDynamicDTIM ||
8122 pHddCtx->cfg_ini->enableModulatedDTIM) &&
8123 ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
8124 ((WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) &&
8125 !(pHddCtx->cfg_ini->ignoreDynamicDtimInP2pMode))) &&
8126 (eANI_BOOLEAN_TRUE == pAdapter->higherDtimTransition) &&
8127 (eConnectionState_Associated ==
8128 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState) &&
8129 (pHddCtx->cfg_ini->fIsBmpsEnabled))
8130 {
8131 tSirSetPowerParamsReq powerRequest = { 0 };
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08008132
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05308133 powerRequest.uIgnoreDTIM = 1;
8134 powerRequest.uMaxLIModulatedDTIM = pHddCtx->cfg_ini->fMaxLIModulatedDTIM;
8135
8136 if (pHddCtx->cfg_ini->enableModulatedDTIM)
8137 {
8138 powerRequest.uDTIMPeriod = pHddCtx->cfg_ini->enableModulatedDTIM;
8139 powerRequest.uListenInterval = pHddCtx->hdd_actual_LI_value;
8140 }
8141 else
8142 {
8143 powerRequest.uListenInterval = pHddCtx->cfg_ini->enableDynamicDTIM;
8144 }
8145
8146 /* Update ignoreDTIM and ListedInterval in CFG to remain at the DTIM
8147 * specified during Enter/Exit BMPS when LCD off*/
8148 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IGNORE_DTIM, powerRequest.uIgnoreDTIM,
8149 NULL, eANI_BOOLEAN_FALSE);
8150 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_LISTEN_INTERVAL, powerRequest.uListenInterval,
8151 NULL, eANI_BOOLEAN_FALSE);
8152
8153 /* switch to the DTIM specified in cfg.ini */
8154 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Abhishek Singh1e390cf2015-10-27 13:45:17 +05308155 "Switch to DTIM %d Listen interval %d",
8156 powerRequest.uDTIMPeriod,
8157 powerRequest.uListenInterval);
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05308158 sme_SetPowerParams( pHddCtx->hHal, &powerRequest, TRUE);
8159 break;
8160
8161 }
8162
8163 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
8164 pAdapterNode = pNext;
8165 }
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08008166}
8167
8168void hdd_reset_pwrparams(hdd_context_t *pHddCtx)
8169{
8170 /*Switch back to DTIM 1*/
8171 tSirSetPowerParamsReq powerRequest = { 0 };
8172
8173 powerRequest.uIgnoreDTIM = pHddCtx->hdd_actual_ignore_DTIM_value;
8174 powerRequest.uListenInterval = pHddCtx->hdd_actual_LI_value;
Yue Mac24062f2013-05-13 17:01:29 -07008175 powerRequest.uMaxLIModulatedDTIM = pHddCtx->cfg_ini->fMaxLIModulatedDTIM;
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08008176
8177 /* Update ignoreDTIM and ListedInterval in CFG with default values */
8178 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IGNORE_DTIM, powerRequest.uIgnoreDTIM,
8179 NULL, eANI_BOOLEAN_FALSE);
8180 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_LISTEN_INTERVAL, powerRequest.uListenInterval,
8181 NULL, eANI_BOOLEAN_FALSE);
8182
8183 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8184 "Switch to DTIM%d",powerRequest.uListenInterval);
8185 sme_SetPowerParams( pHddCtx->hHal, &powerRequest, TRUE);
8186
8187}
8188
Jeff Johnson295189b2012-06-20 16:38:30 -07008189VOS_STATUS hdd_enable_bmps_imps(hdd_context_t *pHddCtx)
8190{
8191 VOS_STATUS status = VOS_STATUS_SUCCESS;
Sushant Kaushik4928e542014-12-29 15:25:54 +05308192 if (WLAN_HDD_IS_UNLOAD_IN_PROGRESS(pHddCtx))
8193 {
8194 hddLog( LOGE, FL("Wlan Unload in progress"));
8195 return VOS_STATUS_E_PERM;
8196 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008197 if(pHddCtx->cfg_ini->fIsBmpsEnabled)
8198 {
8199 sme_EnablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
8200 }
8201
8202 if(pHddCtx->cfg_ini->fIsAutoBmpsTimerEnabled)
8203 {
8204 sme_StartAutoBmpsTimer(pHddCtx->hHal);
8205 }
8206
8207 if (pHddCtx->cfg_ini->fIsImpsEnabled)
8208 {
8209 sme_EnablePowerSave (pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
8210 }
8211
8212 return status;
8213}
8214
8215VOS_STATUS hdd_disable_bmps_imps(hdd_context_t *pHddCtx, tANI_U8 session_type)
8216{
8217 hdd_adapter_t *pAdapter = NULL;
8218 eHalStatus halStatus;
8219 VOS_STATUS status = VOS_STATUS_E_INVAL;
8220 v_BOOL_t disableBmps = FALSE;
8221 v_BOOL_t disableImps = FALSE;
8222
8223 switch(session_type)
8224 {
8225 case WLAN_HDD_INFRA_STATION:
8226 case WLAN_HDD_SOFTAP:
Jeff Johnson295189b2012-06-20 16:38:30 -07008227 case WLAN_HDD_P2P_CLIENT:
8228 case WLAN_HDD_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07008229 //Exit BMPS -> Is Sta/P2P Client is already connected
8230 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION);
8231 if((NULL != pAdapter)&&
8232 hdd_connIsConnected( WLAN_HDD_GET_STATION_CTX_PTR(pAdapter)))
8233 {
8234 disableBmps = TRUE;
8235 }
8236
8237 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_CLIENT);
8238 if((NULL != pAdapter)&&
8239 hdd_connIsConnected( WLAN_HDD_GET_STATION_CTX_PTR(pAdapter)))
8240 {
8241 disableBmps = TRUE;
8242 }
8243
8244 //Exit both Bmps and Imps incase of Go/SAP Mode
8245 if((WLAN_HDD_SOFTAP == session_type) ||
8246 (WLAN_HDD_P2P_GO == session_type))
8247 {
8248 disableBmps = TRUE;
8249 disableImps = TRUE;
8250 }
8251
8252 if(TRUE == disableImps)
8253 {
8254 if (pHddCtx->cfg_ini->fIsImpsEnabled)
8255 {
8256 sme_DisablePowerSave (pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
8257 }
8258 }
8259
8260 if(TRUE == disableBmps)
8261 {
8262 if(pHddCtx->cfg_ini->fIsBmpsEnabled)
8263 {
8264 halStatus = sme_DisablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
8265
8266 if(eHAL_STATUS_SUCCESS != halStatus)
8267 {
8268 status = VOS_STATUS_E_FAILURE;
Arif Hussain6d2a3322013-11-17 19:50:10 -08008269 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Fail to Disable Power Save", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07008270 VOS_ASSERT(0);
8271 return status;
8272 }
8273 }
8274
8275 if(pHddCtx->cfg_ini->fIsAutoBmpsTimerEnabled)
8276 {
8277 halStatus = sme_StopAutoBmpsTimer(pHddCtx->hHal);
8278
8279 if(eHAL_STATUS_SUCCESS != halStatus)
8280 {
8281 status = VOS_STATUS_E_FAILURE;
Arif Hussain6d2a3322013-11-17 19:50:10 -08008282 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Fail to Stop Auto Bmps Timer", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07008283 VOS_ASSERT(0);
8284 return status;
8285 }
8286 }
8287 }
8288
8289 if((TRUE == disableBmps) ||
8290 (TRUE == disableImps))
8291 {
8292 /* Now, get the chip into Full Power now */
8293 INIT_COMPLETION(pHddCtx->full_pwr_comp_var);
8294 halStatus = sme_RequestFullPower(pHddCtx->hHal, hdd_full_pwr_cbk,
8295 pHddCtx, eSME_FULL_PWR_NEEDED_BY_HDD);
8296
8297 if(halStatus != eHAL_STATUS_SUCCESS)
8298 {
8299 if(halStatus == eHAL_STATUS_PMC_PENDING)
8300 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308301 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07008302 //Block on a completion variable. Can't wait forever though
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308303 ret = wait_for_completion_interruptible_timeout(
8304 &pHddCtx->full_pwr_comp_var,
8305 msecs_to_jiffies(1000));
8306 if (ret <= 0)
8307 {
8308 hddLog(VOS_TRACE_LEVEL_ERROR,
8309 "%s: wait on full_pwr_comp_var failed %ld",
8310 __func__, ret);
8311 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008312 }
8313 else
8314 {
8315 status = VOS_STATUS_E_FAILURE;
Arif Hussain6d2a3322013-11-17 19:50:10 -08008316 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Request for Full Power failed", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07008317 VOS_ASSERT(0);
8318 return status;
8319 }
8320 }
8321
8322 status = VOS_STATUS_SUCCESS;
8323 }
8324
8325 break;
8326 }
8327 return status;
8328}
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +05308329
8330void hdd_monPostMsgCb(tANI_U32 *magic, struct completion *cmpVar)
8331{
8332 if (magic == NULL || cmpVar == NULL) {
8333 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8334 FL("invalid arguments %p %p"), magic, cmpVar);
8335 return;
8336 }
8337 if (*magic != MON_MODE_MSG_MAGIC) {
8338 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8339 FL("maic: %x"), *magic);
8340 return;
8341 }
8342
8343 complete(cmpVar);
8344 return;
8345}
8346
Katya Nigame7b69a82015-04-28 15:24:06 +05308347void hdd_init_mon_mode (hdd_adapter_t *pAdapter)
8348 {
8349 hdd_mon_ctx_t *pMonCtx = NULL;
8350 pMonCtx = WLAN_HDD_GET_MONITOR_CTX_PTR(pAdapter);
8351
8352 pMonCtx->state = 0;
8353 pMonCtx->ChannelNo = 1;
8354 pMonCtx->ChannelBW = 20;
Katya Nigamd7d3a1f2015-06-11 14:04:24 +05308355 pMonCtx->crcCheckEnabled = 1;
8356 pMonCtx->typeSubtypeBitmap = 0xFFFF00000000;
8357 pMonCtx->is80211to803ConReq = 1;
Katya Nigame7b69a82015-04-28 15:24:06 +05308358 pMonCtx->numOfMacFilters = 0;
8359 }
8360
Jeff Johnson295189b2012-06-20 16:38:30 -07008361
8362hdd_adapter_t* hdd_open_adapter( hdd_context_t *pHddCtx, tANI_U8 session_type,
Jeff Johnsoneed415b2013-01-18 16:11:20 -08008363 const char *iface_name, tSirMacAddr macAddr,
Jeff Johnson295189b2012-06-20 16:38:30 -07008364 tANI_U8 rtnl_held )
8365{
8366 hdd_adapter_t *pAdapter = NULL;
8367 hdd_adapter_list_node_t *pHddAdapterNode = NULL;
8368 VOS_STATUS status = VOS_STATUS_E_FAILURE;
8369 VOS_STATUS exitbmpsStatus;
8370
Arif Hussain6d2a3322013-11-17 19:50:10 -08008371 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s iface =%s type = %d",__func__,iface_name,session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07008372
Nirav Shah436658f2014-02-28 17:05:45 +05308373 if(macAddr == NULL)
8374 {
8375 /* Not received valid macAddr */
8376 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8377 "%s:Unable to add virtual intf: Not able to get"
8378 "valid mac address",__func__);
8379 return NULL;
8380 }
8381
Jeff Johnson295189b2012-06-20 16:38:30 -07008382 //Disable BMPS incase of Concurrency
8383 exitbmpsStatus = hdd_disable_bmps_imps(pHddCtx, session_type);
8384
8385 if(VOS_STATUS_E_FAILURE == exitbmpsStatus)
8386 {
8387 //Fail to Exit BMPS
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308388 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Fail to Exit BMPS", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07008389 VOS_ASSERT(0);
8390 return NULL;
8391 }
8392
8393 switch(session_type)
8394 {
8395 case WLAN_HDD_INFRA_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -07008396 case WLAN_HDD_P2P_CLIENT:
Jeff Johnsone7245742012-09-05 17:12:55 -07008397 case WLAN_HDD_P2P_DEVICE:
Jeff Johnson295189b2012-06-20 16:38:30 -07008398 {
8399 pAdapter = hdd_alloc_station_adapter( pHddCtx, macAddr, iface_name );
8400
8401 if( NULL == pAdapter )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308402 {
8403 hddLog(VOS_TRACE_LEVEL_FATAL,
8404 FL("failed to allocate adapter for session %d"), session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07008405 return NULL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308406 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008407
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05308408#ifdef FEATURE_WLAN_TDLS
8409 /* A Mutex Lock is introduced while changing/initializing the mode to
8410 * protect the concurrent access for the Adapters by TDLS module.
8411 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05308412 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05308413#endif
8414
Jeff Johnsone7245742012-09-05 17:12:55 -07008415 pAdapter->wdev.iftype = (session_type == WLAN_HDD_P2P_CLIENT) ?
8416 NL80211_IFTYPE_P2P_CLIENT:
8417 NL80211_IFTYPE_STATION;
Jeff Johnson295189b2012-06-20 16:38:30 -07008418
Jeff Johnson295189b2012-06-20 16:38:30 -07008419 pAdapter->device_mode = session_type;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05308420#ifdef FEATURE_WLAN_TDLS
8421 mutex_unlock(&pHddCtx->tdls_lock);
8422#endif
Sunil Dutt66485cb2013-12-19 19:05:03 +05308423
Mahesh A Saptasagar67ab9222015-10-21 15:38:41 +05308424 hdd_initialize_adapter_common(pAdapter);
Sunil Dutt66485cb2013-12-19 19:05:03 +05308425 status = hdd_init_station_mode( pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -07008426 if( VOS_STATUS_SUCCESS != status )
8427 goto err_free_netdev;
8428
8429 status = hdd_register_interface( pAdapter, rtnl_held );
8430 if( VOS_STATUS_SUCCESS != status )
8431 {
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05308432#ifdef FEATURE_WLAN_TDLS
8433 mutex_lock(&pHddCtx->tdls_lock);
8434#endif
c_hpothu002231a2015-02-05 14:58:51 +05308435 hdd_deinit_adapter(pHddCtx, pAdapter, rtnl_held);
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05308436#ifdef FEATURE_WLAN_TDLS
8437 mutex_unlock(&pHddCtx->tdls_lock);
8438#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008439 goto err_free_netdev;
8440 }
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05308441
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +05308442 // Workqueue which gets scheduled in IPv4 notification callback.
Anand N Sunkaddc63c792015-06-03 14:33:24 +05308443 vos_init_work(&pAdapter->ipv4NotifierWorkQueue, hdd_ipv4_notifier_work_queue);
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +05308444
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05308445#ifdef WLAN_NS_OFFLOAD
8446 // Workqueue which gets scheduled in IPv6 notification callback.
Anand N Sunkaddc63c792015-06-03 14:33:24 +05308447 vos_init_work(&pAdapter->ipv6NotifierWorkQueue, hdd_ipv6_notifier_work_queue);
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05308448#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008449 //Stop the Interface TX queue.
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +05308450 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Jeff Johnson295189b2012-06-20 16:38:30 -07008451 netif_tx_disable(pAdapter->dev);
8452 //netif_tx_disable(pWlanDev);
8453 netif_carrier_off(pAdapter->dev);
8454
Ganesh Kondabattinibabfb492014-12-17 20:25:29 +05308455 if (WLAN_HDD_P2P_CLIENT == session_type ||
8456 WLAN_HDD_P2P_DEVICE == session_type)
8457 {
8458 /* Initialize the work queue to defer the
8459 * back to back RoC request */
Anand N Sunkaddc63c792015-06-03 14:33:24 +05308460 vos_init_delayed_work(&pAdapter->roc_work,
Ganesh Kondabattinibabfb492014-12-17 20:25:29 +05308461 hdd_p2p_roc_work_queue);
8462 }
8463
Jeff Johnson295189b2012-06-20 16:38:30 -07008464 break;
8465 }
8466
Jeff Johnson295189b2012-06-20 16:38:30 -07008467 case WLAN_HDD_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07008468 case WLAN_HDD_SOFTAP:
8469 {
8470 pAdapter = hdd_wlan_create_ap_dev( pHddCtx, macAddr, (tANI_U8 *)iface_name );
8471 if( NULL == pAdapter )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308472 {
8473 hddLog(VOS_TRACE_LEVEL_FATAL,
8474 FL("failed to allocate adapter for session %d"), session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07008475 return NULL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308476 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008477
Jeff Johnson295189b2012-06-20 16:38:30 -07008478 pAdapter->wdev.iftype = (session_type == WLAN_HDD_SOFTAP) ?
8479 NL80211_IFTYPE_AP:
8480 NL80211_IFTYPE_P2P_GO;
Jeff Johnson295189b2012-06-20 16:38:30 -07008481 pAdapter->device_mode = session_type;
8482
Mahesh A Saptasagar67ab9222015-10-21 15:38:41 +05308483 hdd_initialize_adapter_common(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07008484 status = hdd_init_ap_mode(pAdapter);
8485 if( VOS_STATUS_SUCCESS != status )
8486 goto err_free_netdev;
8487
Nirav Shah7e3c8132015-06-22 23:51:42 +05308488 status = hdd_sta_id_hash_attach(pAdapter);
8489 if (VOS_STATUS_SUCCESS != status)
8490 {
8491 hddLog(VOS_TRACE_LEVEL_FATAL,
8492 FL("failed to attach hash for session %d"), session_type);
8493 hdd_deinit_adapter(pHddCtx, pAdapter, rtnl_held);
8494 goto err_free_netdev;
8495 }
8496
Jeff Johnson295189b2012-06-20 16:38:30 -07008497 status = hdd_register_hostapd( pAdapter, rtnl_held );
8498 if( VOS_STATUS_SUCCESS != status )
8499 {
c_hpothu002231a2015-02-05 14:58:51 +05308500 hdd_deinit_adapter(pHddCtx, pAdapter, rtnl_held);
Jeff Johnson295189b2012-06-20 16:38:30 -07008501 goto err_free_netdev;
8502 }
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +05308503 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Jeff Johnson295189b2012-06-20 16:38:30 -07008504 netif_tx_disable(pAdapter->dev);
8505 netif_carrier_off(pAdapter->dev);
8506
8507 hdd_set_conparam( 1 );
Ganesh Kondabattinibabfb492014-12-17 20:25:29 +05308508
8509 if (WLAN_HDD_P2P_GO == session_type)
8510 {
8511 /* Initialize the work queue to
8512 * defer the back to back RoC request */
8513 INIT_DELAYED_WORK(&pAdapter->roc_work,
8514 hdd_p2p_roc_work_queue);
8515 }
Bhargav Shahd0715912015-10-01 18:17:37 +05308516
Jeff Johnson295189b2012-06-20 16:38:30 -07008517 break;
8518 }
8519 case WLAN_HDD_MONITOR:
8520 {
Jeff Johnson295189b2012-06-20 16:38:30 -07008521 pAdapter = hdd_alloc_station_adapter( pHddCtx, macAddr, iface_name );
8522 if( NULL == pAdapter )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308523 {
8524 hddLog(VOS_TRACE_LEVEL_FATAL,
8525 FL("failed to allocate adapter for session %d"), session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07008526 return NULL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308527 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008528
Katya Nigame7b69a82015-04-28 15:24:06 +05308529 // Register wireless extensions
8530 if( VOS_STATUS_SUCCESS != (status = hdd_register_wext(pAdapter->dev)))
8531 {
8532 hddLog(VOS_TRACE_LEVEL_FATAL,
8533 "hdd_register_wext() failed with status code %08d [x%08x]",
8534 status, status );
8535 status = VOS_STATUS_E_FAILURE;
8536 }
8537
Jeff Johnson295189b2012-06-20 16:38:30 -07008538 pAdapter->wdev.iftype = NL80211_IFTYPE_MONITOR;
8539 pAdapter->device_mode = session_type;
Jeff Johnson295189b2012-06-20 16:38:30 -07008540#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29)
8541 pAdapter->dev->netdev_ops = &wlan_mon_drv_ops;
8542#else
8543 pAdapter->dev->open = hdd_mon_open;
8544 pAdapter->dev->hard_start_xmit = hdd_mon_hard_start_xmit;
Katya Nigame7b69a82015-04-28 15:24:06 +05308545 pAdapter->dev->stop = hdd_mon_stop;
8546 pAdapter->dev->do_ioctl = hdd_mon_ioctl;
Jeff Johnson295189b2012-06-20 16:38:30 -07008547#endif
Katya Nigame7b69a82015-04-28 15:24:06 +05308548 status = hdd_register_interface( pAdapter, rtnl_held );
8549 hdd_init_mon_mode( pAdapter );
Mahesh A Saptasagar67ab9222015-10-21 15:38:41 +05308550 hdd_initialize_adapter_common(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07008551 hdd_init_tx_rx( pAdapter );
8552 set_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
Katya Nigame7b69a82015-04-28 15:24:06 +05308553 //Stop the Interface TX queue.
8554 netif_tx_disable(pAdapter->dev);
8555 netif_carrier_off(pAdapter->dev);
Jeff Johnson295189b2012-06-20 16:38:30 -07008556 }
8557 break;
Jeff Johnson295189b2012-06-20 16:38:30 -07008558 case WLAN_HDD_FTM:
8559 {
8560 pAdapter = hdd_alloc_station_adapter( pHddCtx, macAddr, iface_name );
8561
8562 if( NULL == pAdapter )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308563 {
8564 hddLog(VOS_TRACE_LEVEL_FATAL,
8565 FL("failed to allocate adapter for session %d"), session_type);
8566 return NULL;
8567 }
8568
Jeff Johnson295189b2012-06-20 16:38:30 -07008569 /* Assign NL80211_IFTYPE_STATION as interface type to resolve Kernel Warning
8570 * message while loading driver in FTM mode. */
8571 pAdapter->wdev.iftype = NL80211_IFTYPE_STATION;
8572 pAdapter->device_mode = session_type;
8573 status = hdd_register_interface( pAdapter, rtnl_held );
Madan Mohan Koyyalamudif89ac9f2013-09-19 16:58:12 +05308574
Mahesh A Saptasagar67ab9222015-10-21 15:38:41 +05308575 hdd_initialize_adapter_common(pAdapter);
Madan Mohan Koyyalamudif89ac9f2013-09-19 16:58:12 +05308576 hdd_init_tx_rx( pAdapter );
8577
8578 //Stop the Interface TX queue.
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +05308579 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Madan Mohan Koyyalamudif89ac9f2013-09-19 16:58:12 +05308580 netif_tx_disable(pAdapter->dev);
8581 netif_carrier_off(pAdapter->dev);
Jeff Johnson295189b2012-06-20 16:38:30 -07008582 }
8583 break;
Jeff Johnson295189b2012-06-20 16:38:30 -07008584 default:
8585 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308586 hddLog(VOS_TRACE_LEVEL_FATAL,"%s Invalid session type %d",
8587 __func__, session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07008588 VOS_ASSERT(0);
8589 return NULL;
8590 }
8591 }
8592
Jeff Johnson295189b2012-06-20 16:38:30 -07008593 if( VOS_STATUS_SUCCESS == status )
8594 {
Mahesh A Saptasagar67ab9222015-10-21 15:38:41 +05308595 //Add it to the hdd's session list.
Jeff Johnson295189b2012-06-20 16:38:30 -07008596 pHddAdapterNode = vos_mem_malloc( sizeof( hdd_adapter_list_node_t ) );
8597 if( NULL == pHddAdapterNode )
8598 {
8599 status = VOS_STATUS_E_NOMEM;
8600 }
8601 else
8602 {
8603 pHddAdapterNode->pAdapter = pAdapter;
8604 status = hdd_add_adapter_back ( pHddCtx,
8605 pHddAdapterNode );
8606 }
8607 }
8608
8609 if( VOS_STATUS_SUCCESS != status )
8610 {
8611 if( NULL != pAdapter )
8612 {
8613 hdd_cleanup_adapter( pHddCtx, pAdapter, rtnl_held );
8614 pAdapter = NULL;
8615 }
8616 if( NULL != pHddAdapterNode )
8617 {
8618 vos_mem_free( pHddAdapterNode );
8619 }
8620
8621 goto resume_bmps;
8622 }
8623
8624 if(VOS_STATUS_SUCCESS == status)
8625 {
8626 wlan_hdd_set_concurrency_mode(pHddCtx, session_type);
8627
Madan Mohan Koyyalamudi96dd30d2012-10-05 17:24:51 -07008628 //Initialize the WoWL service
8629 if(!hdd_init_wowl(pAdapter))
8630 {
8631 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hdd_init_wowl failed",__func__);
8632 goto err_free_netdev;
8633 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008634 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008635 return pAdapter;
8636
8637err_free_netdev:
8638 free_netdev(pAdapter->dev);
8639 wlan_hdd_release_intf_addr( pHddCtx,
8640 pAdapter->macAddressCurrent.bytes );
8641
8642resume_bmps:
8643 //If bmps disabled enable it
8644 if(VOS_STATUS_SUCCESS == exitbmpsStatus)
8645 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05308646 if (pHddCtx->hdd_wlan_suspended)
8647 {
8648 hdd_set_pwrparams(pHddCtx);
8649 }
8650 hdd_enable_bmps_imps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07008651 }
8652 return NULL;
8653}
8654
8655VOS_STATUS hdd_close_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter,
8656 tANI_U8 rtnl_held )
8657{
8658 hdd_adapter_list_node_t *pAdapterNode, *pCurrent, *pNext;
8659 VOS_STATUS status;
8660
8661 status = hdd_get_front_adapter ( pHddCtx, &pCurrent );
8662 if( VOS_STATUS_SUCCESS != status )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308663 {
8664 hddLog(VOS_TRACE_LEVEL_WARN,"%s: adapter list empty %d",
8665 __func__, status);
Jeff Johnson295189b2012-06-20 16:38:30 -07008666 return status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308667 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008668
8669 while ( pCurrent->pAdapter != pAdapter )
8670 {
8671 status = hdd_get_next_adapter ( pHddCtx, pCurrent, &pNext );
8672 if( VOS_STATUS_SUCCESS != status )
8673 break;
8674
8675 pCurrent = pNext;
8676 }
8677 pAdapterNode = pCurrent;
8678 if( VOS_STATUS_SUCCESS == status )
8679 {
8680 wlan_hdd_clear_concurrency_mode(pHddCtx, pAdapter->device_mode);
8681 hdd_cleanup_adapter( pHddCtx, pAdapterNode->pAdapter, rtnl_held );
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05308682
8683#ifdef FEATURE_WLAN_TDLS
8684
8685 /* A Mutex Lock is introduced while changing/initializing the mode to
8686 * protect the concurrent access for the Adapters by TDLS module.
8687 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05308688 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05308689#endif
8690
Jeff Johnson295189b2012-06-20 16:38:30 -07008691 hdd_remove_adapter( pHddCtx, pAdapterNode );
8692 vos_mem_free( pAdapterNode );
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08008693 pAdapterNode = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07008694
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05308695#ifdef FEATURE_WLAN_TDLS
8696 mutex_unlock(&pHddCtx->tdls_lock);
8697#endif
8698
Jeff Johnson295189b2012-06-20 16:38:30 -07008699
8700 /* If there is a single session of STA/P2P client, re-enable BMPS */
Agarwal Ashish51325b52014-06-16 16:50:49 +05308701 if ((!vos_concurrent_open_sessions_running()) &&
8702 ((pHddCtx->no_of_open_sessions[VOS_STA_MODE] >= 1) ||
8703 (pHddCtx->no_of_open_sessions[VOS_P2P_CLIENT_MODE] >= 1)))
Jeff Johnson295189b2012-06-20 16:38:30 -07008704 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05308705 if (pHddCtx->hdd_wlan_suspended)
8706 {
8707 hdd_set_pwrparams(pHddCtx);
8708 }
8709 hdd_enable_bmps_imps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07008710 }
8711
8712 return VOS_STATUS_SUCCESS;
8713 }
8714
8715 return VOS_STATUS_E_FAILURE;
8716}
8717
8718VOS_STATUS hdd_close_all_adapters( hdd_context_t *pHddCtx )
8719{
8720 hdd_adapter_list_node_t *pHddAdapterNode;
8721 VOS_STATUS status;
8722
8723 ENTER();
8724
8725 do
8726 {
8727 status = hdd_remove_front_adapter( pHddCtx, &pHddAdapterNode );
8728 if( pHddAdapterNode && VOS_STATUS_SUCCESS == status )
8729 {
8730 hdd_cleanup_adapter( pHddCtx, pHddAdapterNode->pAdapter, FALSE );
8731 vos_mem_free( pHddAdapterNode );
8732 }
8733 }while( NULL != pHddAdapterNode && VOS_STATUS_E_EMPTY != status );
8734
8735 EXIT();
8736
8737 return VOS_STATUS_SUCCESS;
8738}
8739
8740void wlan_hdd_reset_prob_rspies(hdd_adapter_t* pHostapdAdapter)
8741{
8742 v_U8_t addIE[1] = {0};
8743
8744 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
8745 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,(tANI_U8*)addIE, 0, NULL,
8746 eANI_BOOLEAN_FALSE) )
8747 {
8748 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08008749 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07008750 }
8751
8752 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
8753 WNI_CFG_PROBE_RSP_ADDNIE_DATA2, (tANI_U8*)addIE, 0, NULL,
8754 eANI_BOOLEAN_FALSE) )
8755 {
8756 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08008757 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07008758 }
8759
8760 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
8761 WNI_CFG_PROBE_RSP_ADDNIE_DATA3, (tANI_U8*)addIE, 0, NULL,
8762 eANI_BOOLEAN_FALSE) )
8763 {
8764 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08008765 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07008766 }
8767}
8768
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05308769VOS_STATUS hdd_stop_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter,
8770 const v_BOOL_t bCloseSession )
Jeff Johnson295189b2012-06-20 16:38:30 -07008771{
8772 eHalStatus halStatus = eHAL_STATUS_SUCCESS;
8773 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Kaushik, Sushant4975a572014-10-21 16:07:48 +05308774 hdd_scaninfo_t *pScanInfo = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07008775 union iwreq_data wrqu;
Kaushik, Sushant7005e372014-04-08 11:36:54 +05308776 v_U8_t retry = 0;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308777 long ret;
Nirav Shah7e3c8132015-06-22 23:51:42 +05308778 VOS_STATUS status;
Jeff Johnson295189b2012-06-20 16:38:30 -07008779
Anand N Sunkad26d71b92014-12-24 18:08:22 +05308780 if (pHddCtx->isLogpInProgress) {
8781 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8782 "%s:LOGP in Progress. Ignore!!!",__func__);
8783 return VOS_STATUS_E_FAILURE;
8784 }
8785
Jeff Johnson295189b2012-06-20 16:38:30 -07008786 ENTER();
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +05308787
Kaushik, Sushant4975a572014-10-21 16:07:48 +05308788 pScanInfo = &pHddCtx->scan_info;
Jeff Johnson295189b2012-06-20 16:38:30 -07008789 switch(pAdapter->device_mode)
8790 {
Nirav Shah0cf4d892015-11-05 16:27:27 +05308791 case WLAN_HDD_IBSS:
8792 if ( VOS_TRUE == bCloseSession )
8793 {
8794 status = hdd_sta_id_hash_detach(pAdapter);
8795 if (status != VOS_STATUS_SUCCESS)
8796 hddLog(VOS_TRACE_LEVEL_ERROR,
8797 FL("sta id hash detach failed"));
8798 }
8799
Jeff Johnson295189b2012-06-20 16:38:30 -07008800 case WLAN_HDD_INFRA_STATION:
8801 case WLAN_HDD_P2P_CLIENT:
Jeff Johnsone7245742012-09-05 17:12:55 -07008802 case WLAN_HDD_P2P_DEVICE:
Vinay Krishna Erannab09d3e72014-03-26 21:23:55 +05308803 {
8804 hdd_station_ctx_t *pstation = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Mahesh A Saptasagare4d05d42015-07-02 16:17:20 +05308805#ifdef FEATURE_WLAN_TDLS
8806 mutex_lock(&pHddCtx->tdls_lock);
8807 wlan_hdd_tdls_exit(pAdapter, TRUE);
8808 mutex_unlock(&pHddCtx->tdls_lock);
8809#endif
Vinay Krishna Erannab09d3e72014-03-26 21:23:55 +05308810 if( hdd_connIsConnected(pstation) ||
8811 (pstation->conn_info.connState == eConnectionState_Connecting) )
Jeff Johnson295189b2012-06-20 16:38:30 -07008812 {
8813 if (pWextState->roamProfile.BSSType == eCSR_BSS_TYPE_START_IBSS)
8814 halStatus = sme_RoamDisconnect(pHddCtx->hHal,
8815 pAdapter->sessionId,
8816 eCSR_DISCONNECT_REASON_IBSS_LEAVE);
8817 else
8818 halStatus = sme_RoamDisconnect(pHddCtx->hHal,
8819 pAdapter->sessionId,
8820 eCSR_DISCONNECT_REASON_UNSPECIFIED);
Abhishek Singh7b52ed52016-02-11 17:45:54 +05308821 /* Success implies disconnect command got queued up successfully
8822 * Or cmd not queued as scan for SSID is in progress
8823 */
8824 if((eHAL_STATUS_SUCCESS == halStatus) ||
8825 (eHAL_STATUS_CMD_NOT_QUEUED == halStatus))
Jeff Johnson295189b2012-06-20 16:38:30 -07008826 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308827 ret = wait_for_completion_interruptible_timeout(
8828 &pAdapter->disconnect_comp_var,
8829 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
Abhishek Singh7b52ed52016-02-11 17:45:54 +05308830 if (ret <= 0 &&
8831 (eHAL_STATUS_CMD_NOT_QUEUED != halStatus))
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308832 {
8833 hddLog(VOS_TRACE_LEVEL_ERROR,
8834 "%s: wait on disconnect_comp_var failed %ld",
8835 __func__, ret);
8836 }
8837 }
8838 else
8839 {
8840 hddLog(LOGE, "%s: failed to post disconnect event to SME",
8841 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07008842 }
8843 memset(&wrqu, '\0', sizeof(wrqu));
8844 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
8845 memset(wrqu.ap_addr.sa_data,'\0',ETH_ALEN);
8846 wireless_send_event(pAdapter->dev, SIOCGIWAP, &wrqu, NULL);
8847 }
Vinay Krishna Erannab09d3e72014-03-26 21:23:55 +05308848 else if(pstation->conn_info.connState ==
8849 eConnectionState_Disconnecting)
8850 {
8851 ret = wait_for_completion_interruptible_timeout(
8852 &pAdapter->disconnect_comp_var,
8853 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
8854 if (ret <= 0)
8855 {
8856 hddLog(VOS_TRACE_LEVEL_ERROR,
8857 FL("wait on disconnect_comp_var failed %ld"), ret);
8858 }
8859 }
Kaushik, Sushant4975a572014-10-21 16:07:48 +05308860 else if(pScanInfo != NULL && pHddCtx->scan_info.mScanPending)
Jeff Johnson295189b2012-06-20 16:38:30 -07008861 {
Mahesh A Saptasagar0b61dcc2016-02-15 14:23:38 +05308862 wlan_hdd_scan_abort(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07008863 }
Abhishek Singh3ac179b2015-09-21 10:01:34 +05308864 if ((pAdapter->device_mode != WLAN_HDD_INFRA_STATION) &&
8865 (pAdapter->device_mode != WLAN_HDD_IBSS))
Kaushik, Sushant7005e372014-04-08 11:36:54 +05308866 {
8867 while (pAdapter->is_roc_inprogress)
8868 {
8869 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8870 "%s: ROC in progress for session %d!!!",
8871 __func__, pAdapter->sessionId);
8872 // waiting for ROC to expire
8873 msleep(500);
8874 /* In GO present case , if retry exceeds 3,
8875 it means something went wrong. */
8876 if ( retry++ > MAX_WAIT_FOR_ROC_COMPLETION )
8877 {
8878 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8879 "%s: ROC completion is not received.!!!", __func__);
Deepthi Gowri70498252015-01-20 15:56:45 +05308880 if (eHAL_STATUS_SUCCESS !=
8881 sme_CancelRemainOnChannel( WLAN_HDD_GET_HAL_CTX( pAdapter),
8882 pAdapter->sessionId ))
8883 {
8884 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8885 FL("Failed to Cancel Remain on Channel"));
8886 }
Kaushik, Sushant7005e372014-04-08 11:36:54 +05308887 wait_for_completion_interruptible_timeout(
8888 &pAdapter->cancel_rem_on_chan_var,
8889 msecs_to_jiffies(WAIT_CANCEL_REM_CHAN));
8890 break;
8891 }
8892 }
Anand N Sunkaddc63c792015-06-03 14:33:24 +05308893 vos_flush_delayed_work(&pAdapter->roc_work);
Kaushik, Sushant7005e372014-04-08 11:36:54 +05308894 }
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05308895#ifdef WLAN_NS_OFFLOAD
Anand N Sunkaddc63c792015-06-03 14:33:24 +05308896 vos_flush_work(&pAdapter->ipv6NotifierWorkQueue);
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05308897#endif
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +05308898
Anand N Sunkaddc63c792015-06-03 14:33:24 +05308899 vos_flush_work(&pAdapter->ipv4NotifierWorkQueue);
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +05308900
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05308901 /* It is possible that the caller of this function does not
8902 * wish to close the session
8903 */
8904 if (VOS_TRUE == bCloseSession &&
8905 test_bit(SME_SESSION_OPENED, &pAdapter->event_flags))
Jeff Johnson295189b2012-06-20 16:38:30 -07008906 {
8907 INIT_COMPLETION(pAdapter->session_close_comp_var);
8908 if (eHAL_STATUS_SUCCESS ==
Agrawal Ashish5a3522c2016-03-02 15:08:28 +05308909 sme_CloseSession(pHddCtx->hHal, pAdapter->sessionId, FALSE,
8910 VOS_FALSE, hdd_smeCloseSessionCallback, pAdapter))
Jeff Johnson295189b2012-06-20 16:38:30 -07008911 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308912 unsigned long ret;
8913
Jeff Johnson295189b2012-06-20 16:38:30 -07008914 //Block on a completion variable. Can't wait forever though.
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308915 ret = wait_for_completion_timeout(
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05308916 &pAdapter->session_close_comp_var,
8917 msecs_to_jiffies(WLAN_WAIT_TIME_SESSIONOPENCLOSE));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308918 if ( 0 >= ret)
8919 {
8920 hddLog(LOGE, "%s: failure waiting for session_close_comp_var %ld",
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05308921 __func__, ret);
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308922 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008923 }
8924 }
Vinay Krishna Erannab09d3e72014-03-26 21:23:55 +05308925 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008926 break;
8927
8928 case WLAN_HDD_SOFTAP:
8929 case WLAN_HDD_P2P_GO:
Nirav Shah0cf4d892015-11-05 16:27:27 +05308930 if ( VOS_TRUE == bCloseSession )
8931 {
8932 status = hdd_sta_id_hash_detach(pAdapter);
8933 if (status != VOS_STATUS_SUCCESS)
8934 hddLog(VOS_TRACE_LEVEL_ERROR,
8935 FL("sta id hash detach failed"));
8936 }
8937
Jeff Johnson295189b2012-06-20 16:38:30 -07008938 //Any softap specific cleanup here...
Kaushik, Sushant7005e372014-04-08 11:36:54 +05308939 if (pAdapter->device_mode == WLAN_HDD_P2P_GO) {
8940 while (pAdapter->is_roc_inprogress) {
8941 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8942 "%s: ROC in progress for session %d!!!",
8943 __func__, pAdapter->sessionId);
8944 msleep(500);
8945 if ( retry++ > MAX_WAIT_FOR_ROC_COMPLETION ) {
8946 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8947 "%s: ROC completion is not received.!!!", __func__);
8948 WLANSAP_CancelRemainOnChannel(
8949 (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
8950 wait_for_completion_interruptible_timeout(
8951 &pAdapter->cancel_rem_on_chan_var,
8952 msecs_to_jiffies(WAIT_CANCEL_REM_CHAN));
8953 break;
8954 }
8955 }
Ganesh Kondabattinibabfb492014-12-17 20:25:29 +05308956
Anand N Sunkaddc63c792015-06-03 14:33:24 +05308957 vos_flush_delayed_work(&pAdapter->roc_work);
Kaushik, Sushant7005e372014-04-08 11:36:54 +05308958 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008959 mutex_lock(&pHddCtx->sap_lock);
8960 if (test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
8961 {
8962 VOS_STATUS status;
8963 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8964
8965 //Stop Bss.
8966 status = WLANSAP_StopBss(pHddCtx->pvosContext);
8967 if (VOS_IS_STATUS_SUCCESS(status))
8968 {
8969 hdd_hostapd_state_t *pHostapdState =
8970 WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
8971
8972 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
8973
8974 if (!VOS_IS_STATUS_SUCCESS(status))
8975 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308976 hddLog(LOGE, "%s: failure waiting for WLANSAP_StopBss %d",
8977 __func__, status);
Jeff Johnson295189b2012-06-20 16:38:30 -07008978 }
8979 }
8980 else
8981 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008982 hddLog(LOGE, "%s: failure in WLANSAP_StopBss", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07008983 }
8984 clear_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags);
Agarwal Ashish51325b52014-06-16 16:50:49 +05308985 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07008986
8987 if (eHAL_STATUS_FAILURE ==
8988 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG,
8989 0, NULL, eANI_BOOLEAN_FALSE))
8990 {
8991 hddLog(LOGE,
8992 "%s: Failed to set WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008993 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07008994 }
8995
8996 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt((WLAN_HDD_GET_CTX(pAdapter))->hHal,
8997 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
8998 eANI_BOOLEAN_FALSE) )
8999 {
9000 hddLog(LOGE,
9001 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
9002 }
9003
9004 // Reset WNI_CFG_PROBE_RSP Flags
9005 wlan_hdd_reset_prob_rspies(pAdapter);
9006 kfree(pAdapter->sessionCtx.ap.beacon);
9007 pAdapter->sessionCtx.ap.beacon = NULL;
9008 }
9009 mutex_unlock(&pHddCtx->sap_lock);
9010 break;
Sameer Thalappilbee426e2013-10-30 10:30:30 -07009011
Jeff Johnson295189b2012-06-20 16:38:30 -07009012 case WLAN_HDD_MONITOR:
9013 break;
Sameer Thalappilbee426e2013-10-30 10:30:30 -07009014
Jeff Johnson295189b2012-06-20 16:38:30 -07009015 default:
9016 break;
9017 }
9018
9019 EXIT();
9020 return VOS_STATUS_SUCCESS;
9021}
9022
9023VOS_STATUS hdd_stop_all_adapters( hdd_context_t *pHddCtx )
9024{
9025 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
9026 VOS_STATUS status;
9027 hdd_adapter_t *pAdapter;
9028
9029 ENTER();
9030
9031 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
9032
9033 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
9034 {
9035 pAdapter = pAdapterNode->pAdapter;
Jeff Johnson295189b2012-06-20 16:38:30 -07009036
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05309037 hdd_stop_adapter( pHddCtx, pAdapter, VOS_TRUE );
Jeff Johnson295189b2012-06-20 16:38:30 -07009038
9039 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
9040 pAdapterNode = pNext;
9041 }
9042
9043 EXIT();
9044
9045 return VOS_STATUS_SUCCESS;
9046}
9047
Rajeev Kumarf999e582014-01-09 17:33:29 -08009048
9049#ifdef FEATURE_WLAN_BATCH_SCAN
9050/**---------------------------------------------------------------------------
9051
9052 \brief hdd_deinit_batch_scan () - This function cleans up batch scan data
9053 structures
9054
9055 \param - pAdapter Pointer to HDD adapter
9056
9057 \return - None
9058
9059 --------------------------------------------------------------------------*/
9060void hdd_deinit_batch_scan(hdd_adapter_t *pAdapter)
9061{
9062 tHddBatchScanRsp *pNode;
9063 tHddBatchScanRsp *pPrev;
9064
Siddharth Bhalb3e9b792014-02-24 15:14:16 +05309065 if (NULL == pAdapter)
Rajeev Kumarf999e582014-01-09 17:33:29 -08009066 {
Siddharth Bhalb3e9b792014-02-24 15:14:16 +05309067 hddLog(VOS_TRACE_LEVEL_ERROR,
9068 "%s: Adapter context is Null", __func__);
9069 return;
9070 }
9071
9072 pNode = pAdapter->pBatchScanRsp;
9073 while (pNode)
9074 {
9075 pPrev = pNode;
9076 pNode = pNode->pNext;
9077 vos_mem_free((v_VOID_t * )pPrev);
Rajeev Kumarf999e582014-01-09 17:33:29 -08009078 }
9079
9080 pAdapter->pBatchScanRsp = NULL;
9081 pAdapter->numScanList = 0;
9082 pAdapter->batchScanState = eHDD_BATCH_SCAN_STATE_STOPPED;
9083 pAdapter->prev_batch_id = 0;
9084
9085 return;
9086}
9087#endif
9088
9089
Jeff Johnson295189b2012-06-20 16:38:30 -07009090VOS_STATUS hdd_reset_all_adapters( hdd_context_t *pHddCtx )
9091{
9092 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
9093 VOS_STATUS status;
9094 hdd_adapter_t *pAdapter;
9095
9096 ENTER();
9097
9098 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
9099
9100 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
9101 {
9102 pAdapter = pAdapterNode->pAdapter;
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +05309103 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Jeff Johnson295189b2012-06-20 16:38:30 -07009104 netif_tx_disable(pAdapter->dev);
9105 netif_carrier_off(pAdapter->dev);
9106
Srinivas Girigowda66c05eb2013-07-14 13:06:01 -07009107 pAdapter->sessionCtx.station.hdd_ReassocScenario = VOS_FALSE;
9108
Jeff Johnson295189b2012-06-20 16:38:30 -07009109 hdd_deinit_tx_rx(pAdapter);
Agarwal Ashish6267caa2014-08-06 19:16:21 +05309110
Katya Nigam1fd24402015-02-16 14:52:19 +05309111 if(pAdapter->device_mode == WLAN_HDD_IBSS )
9112 hdd_ibss_deinit_tx_rx(pAdapter);
9113
Nirav Shah7e3c8132015-06-22 23:51:42 +05309114 status = hdd_sta_id_hash_detach(pAdapter);
9115 if (status != VOS_STATUS_SUCCESS)
9116 hddLog(VOS_TRACE_LEVEL_ERROR,
9117 FL("sta id hash detach failed for session id %d"),
9118 pAdapter->sessionId);
9119
Agarwal Ashish6267caa2014-08-06 19:16:21 +05309120 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
9121
Madan Mohan Koyyalamudi8c6dec82013-09-26 15:56:13 +05309122 if (test_bit(WMM_INIT_DONE, &pAdapter->event_flags))
9123 {
9124 hdd_wmm_adapter_close( pAdapter );
9125 clear_bit(WMM_INIT_DONE, &pAdapter->event_flags);
9126 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009127
Siddharth Bhal2db319d2014-12-03 12:37:18 +05309128 if (test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
9129 {
9130 clear_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags);
9131 }
9132
Rajeev Kumarf999e582014-01-09 17:33:29 -08009133#ifdef FEATURE_WLAN_BATCH_SCAN
9134 if (eHDD_BATCH_SCAN_STATE_STARTED == pAdapter->batchScanState)
9135 {
9136 hdd_deinit_batch_scan(pAdapter);
9137 }
9138#endif
9139
Mahesh A Saptasagarf5b8eff2015-01-31 01:07:07 +05309140#ifdef FEATURE_WLAN_TDLS
9141 mutex_lock(&pHddCtx->tdls_lock);
Pradeep Reddy POTTETI2d4d5c42015-03-03 14:34:19 +05309142 wlan_hdd_tdls_exit(pAdapter, TRUE);
Mahesh A Saptasagarf5b8eff2015-01-31 01:07:07 +05309143 mutex_unlock(&pHddCtx->tdls_lock);
9144#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009145 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
9146 pAdapterNode = pNext;
9147 }
9148
9149 EXIT();
9150
9151 return VOS_STATUS_SUCCESS;
9152}
9153
9154VOS_STATUS hdd_start_all_adapters( hdd_context_t *pHddCtx )
9155{
9156 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
9157 VOS_STATUS status;
9158 hdd_adapter_t *pAdapter;
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05309159 eConnectionState connState;
Jeff Johnson295189b2012-06-20 16:38:30 -07009160
9161 ENTER();
9162
9163 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
9164
9165 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
9166 {
9167 pAdapter = pAdapterNode->pAdapter;
9168
Kumar Anand82c009f2014-05-29 00:29:42 -07009169 hdd_wmm_init( pAdapter );
9170
Jeff Johnson295189b2012-06-20 16:38:30 -07009171 switch(pAdapter->device_mode)
9172 {
9173 case WLAN_HDD_INFRA_STATION:
9174 case WLAN_HDD_P2P_CLIENT:
Jeff Johnsone7245742012-09-05 17:12:55 -07009175 case WLAN_HDD_P2P_DEVICE:
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05309176
9177 connState = (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState;
9178
Jeff Johnson295189b2012-06-20 16:38:30 -07009179 hdd_init_station_mode(pAdapter);
9180 /* Open the gates for HDD to receive Wext commands */
9181 pAdapter->isLinkUpSvcNeeded = FALSE;
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07009182 pHddCtx->scan_info.mScanPending = FALSE;
9183 pHddCtx->scan_info.waitScanResult = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07009184
9185 //Trigger the initial scan
Mukul Sharmae74e42c2015-08-06 23:55:49 +05309186 if (!pHddCtx->isLogpInProgress)
9187 hdd_wlan_initial_scan(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07009188
9189 //Indicate disconnect event to supplicant if associated previously
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05309190 if (eConnectionState_Associated == connState ||
9191 eConnectionState_IbssConnected == connState )
Jeff Johnson295189b2012-06-20 16:38:30 -07009192 {
9193 union iwreq_data wrqu;
9194 memset(&wrqu, '\0', sizeof(wrqu));
9195 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
9196 memset(wrqu.ap_addr.sa_data,'\0',ETH_ALEN);
9197 wireless_send_event(pAdapter->dev, SIOCGIWAP, &wrqu, NULL);
Srinivas Girigowda66c05eb2013-07-14 13:06:01 -07009198 pAdapter->sessionCtx.station.hdd_ReassocScenario = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07009199
Jeff Johnson295189b2012-06-20 16:38:30 -07009200 /* indicate disconnected event to nl80211 */
9201 cfg80211_disconnected(pAdapter->dev, WLAN_REASON_UNSPECIFIED,
9202 NULL, 0, GFP_KERNEL);
Jeff Johnson295189b2012-06-20 16:38:30 -07009203 }
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05309204 else if (eConnectionState_Connecting == connState)
9205 {
9206 /*
9207 * Indicate connect failure to supplicant if we were in the
9208 * process of connecting
9209 */
9210 cfg80211_connect_result(pAdapter->dev, NULL,
9211 NULL, 0, NULL, 0,
9212 WLAN_STATUS_ASSOC_DENIED_UNSPEC,
9213 GFP_KERNEL);
9214 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009215 break;
9216
9217 case WLAN_HDD_SOFTAP:
9218 /* softAP can handle SSR */
9219 break;
9220
9221 case WLAN_HDD_P2P_GO:
Sameer Thalappiledf0d792013-08-09 14:31:03 -07009222 hddLog(VOS_TRACE_LEVEL_ERROR, "%s [SSR] send stop ap to supplicant",
Jeff Johnson295189b2012-06-20 16:38:30 -07009223 __func__);
Sameer Thalappiledf0d792013-08-09 14:31:03 -07009224 cfg80211_ap_stopped(pAdapter->dev, GFP_KERNEL);
Jeff Johnson295189b2012-06-20 16:38:30 -07009225 break;
9226
9227 case WLAN_HDD_MONITOR:
9228 /* monitor interface start */
9229 break;
9230 default:
9231 break;
9232 }
9233
9234 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
9235 pAdapterNode = pNext;
9236 }
9237
9238 EXIT();
9239
9240 return VOS_STATUS_SUCCESS;
9241}
9242
9243VOS_STATUS hdd_reconnect_all_adapters( hdd_context_t *pHddCtx )
9244{
9245 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
9246 hdd_adapter_t *pAdapter;
9247 VOS_STATUS status;
9248 v_U32_t roamId;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309249 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07009250
9251 ENTER();
9252
9253 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
9254
9255 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
9256 {
9257 pAdapter = pAdapterNode->pAdapter;
9258
9259 if( (WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
9260 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
9261 {
9262 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
9263 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
9264
Abhishek Singhf4669da2014-05-26 15:07:49 +05309265 hddLog(VOS_TRACE_LEVEL_INFO,
9266 "%s: Set HDD connState to eConnectionState_NotConnected",
9267 __func__);
Ganesh Kondabattini04338412015-09-14 15:39:09 +05309268 spin_lock_bh(&pAdapter->lock_for_active_session);
9269 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState)
9270 {
9271 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
9272 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009273 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
Ganesh Kondabattini04338412015-09-14 15:39:09 +05309274 spin_unlock_bh(&pAdapter->lock_for_active_session);
Jeff Johnson295189b2012-06-20 16:38:30 -07009275 init_completion(&pAdapter->disconnect_comp_var);
9276 sme_RoamDisconnect(pHddCtx->hHal, pAdapter->sessionId,
9277 eCSR_DISCONNECT_REASON_UNSPECIFIED);
9278
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309279 ret = wait_for_completion_interruptible_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -07009280 &pAdapter->disconnect_comp_var,
9281 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309282 if (0 >= ret)
9283 hddLog(LOGE, "%s: failure waiting for disconnect_comp_var %ld",
9284 __func__, ret);
Jeff Johnson295189b2012-06-20 16:38:30 -07009285
9286 pWextState->roamProfile.csrPersona = pAdapter->device_mode;
9287 pHddCtx->isAmpAllowed = VOS_FALSE;
9288 sme_RoamConnect(pHddCtx->hHal,
9289 pAdapter->sessionId, &(pWextState->roamProfile),
9290 &roamId);
9291 }
9292
9293 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
9294 pAdapterNode = pNext;
9295 }
9296
9297 EXIT();
9298
9299 return VOS_STATUS_SUCCESS;
9300}
9301
Sudhir Sattayappa Kohalli90e4c752013-03-21 14:25:04 -07009302void hdd_dump_concurrency_info(hdd_context_t *pHddCtx)
9303{
9304 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
9305 VOS_STATUS status;
9306 hdd_adapter_t *pAdapter;
9307 hdd_station_ctx_t *pHddStaCtx;
9308 hdd_ap_ctx_t *pHddApCtx;
9309 hdd_hostapd_state_t * pHostapdState;
9310 tCsrBssid staBssid = { 0 }, p2pBssid = { 0 }, apBssid = { 0 };
9311 v_U8_t staChannel = 0, p2pChannel = 0, apChannel = 0;
9312 const char *p2pMode = "DEV";
9313 const char *ccMode = "Standalone";
Sudhir Sattayappa Kohalli90e4c752013-03-21 14:25:04 -07009314
9315 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
9316 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
9317 {
9318 pAdapter = pAdapterNode->pAdapter;
9319 switch (pAdapter->device_mode) {
9320 case WLAN_HDD_INFRA_STATION:
9321 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
9322 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState) {
9323 staChannel = pHddStaCtx->conn_info.operationChannel;
9324 memcpy(staBssid, pHddStaCtx->conn_info.bssId, sizeof(staBssid));
9325 }
9326 break;
9327 case WLAN_HDD_P2P_CLIENT:
9328 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
9329 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState) {
9330 p2pChannel = pHddStaCtx->conn_info.operationChannel;
9331 memcpy(p2pBssid, pHddStaCtx->conn_info.bssId, sizeof(p2pBssid));
9332 p2pMode = "CLI";
9333 }
9334 break;
9335 case WLAN_HDD_P2P_GO:
9336 pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
9337 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
9338 if (pHostapdState->bssState == BSS_START && pHostapdState->vosStatus==VOS_STATUS_SUCCESS) {
9339 p2pChannel = pHddApCtx->operatingChannel;
9340 memcpy(p2pBssid, pAdapter->macAddressCurrent.bytes, sizeof(p2pBssid));
9341 }
9342 p2pMode = "GO";
9343 break;
9344 case WLAN_HDD_SOFTAP:
9345 pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
9346 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
9347 if (pHostapdState->bssState == BSS_START && pHostapdState->vosStatus==VOS_STATUS_SUCCESS) {
9348 apChannel = pHddApCtx->operatingChannel;
9349 memcpy(apBssid, pAdapter->macAddressCurrent.bytes, sizeof(apBssid));
9350 }
9351 break;
9352 default:
9353 break;
9354 }
9355 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
9356 pAdapterNode = pNext;
9357 }
9358 if (staChannel > 0 && (apChannel > 0 || p2pChannel > 0)) {
9359 ccMode = (p2pChannel==staChannel||apChannel==staChannel) ? "SCC" : "MCC";
9360 }
Sushant Kaushikdc3184b2015-10-09 12:00:21 +05309361 hddLog(VOS_TRACE_LEVEL_ERROR, "wlan(%d) " MAC_ADDRESS_STR " %s",
Sudhir Sattayappa Kohalli90e4c752013-03-21 14:25:04 -07009362 staChannel, MAC_ADDR_ARRAY(staBssid), ccMode);
9363 if (p2pChannel > 0) {
Sushant Kaushikdc3184b2015-10-09 12:00:21 +05309364 hddLog(VOS_TRACE_LEVEL_ERROR, "p2p-%s(%d) " MAC_ADDRESS_STR,
Sudhir Sattayappa Kohalli90e4c752013-03-21 14:25:04 -07009365 p2pMode, p2pChannel, MAC_ADDR_ARRAY(p2pBssid));
9366 }
9367 if (apChannel > 0) {
Sushant Kaushikdc3184b2015-10-09 12:00:21 +05309368 hddLog(VOS_TRACE_LEVEL_ERROR, "AP(%d) " MAC_ADDRESS_STR,
Sudhir Sattayappa Kohalli90e4c752013-03-21 14:25:04 -07009369 apChannel, MAC_ADDR_ARRAY(apBssid));
9370 }
9371
9372 if (p2pChannel > 0 && apChannel > 0) {
9373 hddLog(VOS_TRACE_LEVEL_ERROR, "Error concurrent SAP %d and P2P %d which is not support", apChannel, p2pChannel);
9374 }
9375}
9376
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -07009377bool hdd_is_ssr_required( void)
Jeff Johnson295189b2012-06-20 16:38:30 -07009378{
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -07009379 return (isSsrRequired == HDD_SSR_REQUIRED);
Jeff Johnson295189b2012-06-20 16:38:30 -07009380}
9381
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -07009382/* Once SSR is disabled then it cannot be set. */
9383void hdd_set_ssr_required( e_hdd_ssr_required value)
Jeff Johnson295189b2012-06-20 16:38:30 -07009384{
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -07009385 if (HDD_SSR_DISABLED == isSsrRequired)
9386 return;
9387
Jeff Johnson295189b2012-06-20 16:38:30 -07009388 isSsrRequired = value;
9389}
9390
Hema Aparna Medicharla6b4d4f32015-06-23 04:09:12 +05309391void hdd_set_pre_close( hdd_context_t *pHddCtx)
9392{
9393 sme_PreClose(pHddCtx->hHal);
9394}
9395
Jeff Johnson295189b2012-06-20 16:38:30 -07009396VOS_STATUS hdd_get_front_adapter( hdd_context_t *pHddCtx,
9397 hdd_adapter_list_node_t** ppAdapterNode)
9398{
9399 VOS_STATUS status;
Mukul Sharmaae1266d2015-06-26 15:29:53 +05309400 spin_lock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07009401 status = hdd_list_peek_front ( &pHddCtx->hddAdapters,
9402 (hdd_list_node_t**) ppAdapterNode );
Mukul Sharmaae1266d2015-06-26 15:29:53 +05309403 spin_unlock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07009404 return status;
9405}
9406
9407VOS_STATUS hdd_get_next_adapter( hdd_context_t *pHddCtx,
9408 hdd_adapter_list_node_t* pAdapterNode,
9409 hdd_adapter_list_node_t** pNextAdapterNode)
9410{
9411 VOS_STATUS status;
Mukul Sharmaae1266d2015-06-26 15:29:53 +05309412 spin_lock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07009413 status = hdd_list_peek_next ( &pHddCtx->hddAdapters,
9414 (hdd_list_node_t*) pAdapterNode,
9415 (hdd_list_node_t**)pNextAdapterNode );
9416
Mukul Sharmaae1266d2015-06-26 15:29:53 +05309417 spin_unlock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07009418 return status;
9419}
9420
9421VOS_STATUS hdd_remove_adapter( hdd_context_t *pHddCtx,
9422 hdd_adapter_list_node_t* pAdapterNode)
9423{
9424 VOS_STATUS status;
Mukul Sharmaae1266d2015-06-26 15:29:53 +05309425 spin_lock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07009426 status = hdd_list_remove_node ( &pHddCtx->hddAdapters,
9427 &pAdapterNode->node );
Mukul Sharmaae1266d2015-06-26 15:29:53 +05309428 spin_unlock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07009429 return status;
9430}
9431
9432VOS_STATUS hdd_remove_front_adapter( hdd_context_t *pHddCtx,
9433 hdd_adapter_list_node_t** ppAdapterNode)
9434{
9435 VOS_STATUS status;
Mukul Sharmaae1266d2015-06-26 15:29:53 +05309436 spin_lock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07009437 status = hdd_list_remove_front( &pHddCtx->hddAdapters,
9438 (hdd_list_node_t**) ppAdapterNode );
Mukul Sharmaae1266d2015-06-26 15:29:53 +05309439 spin_unlock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07009440 return status;
9441}
9442
9443VOS_STATUS hdd_add_adapter_back( hdd_context_t *pHddCtx,
9444 hdd_adapter_list_node_t* pAdapterNode)
9445{
9446 VOS_STATUS status;
Mukul Sharmaae1266d2015-06-26 15:29:53 +05309447 spin_lock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07009448 status = hdd_list_insert_back ( &pHddCtx->hddAdapters,
9449 (hdd_list_node_t*) pAdapterNode );
Mukul Sharmaae1266d2015-06-26 15:29:53 +05309450 spin_unlock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07009451 return status;
9452}
9453
9454VOS_STATUS hdd_add_adapter_front( hdd_context_t *pHddCtx,
9455 hdd_adapter_list_node_t* pAdapterNode)
9456{
9457 VOS_STATUS status;
Mukul Sharmaae1266d2015-06-26 15:29:53 +05309458 spin_lock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07009459 status = hdd_list_insert_front ( &pHddCtx->hddAdapters,
9460 (hdd_list_node_t*) pAdapterNode );
Mukul Sharmaae1266d2015-06-26 15:29:53 +05309461 spin_unlock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07009462 return status;
9463}
9464
9465hdd_adapter_t * hdd_get_adapter_by_macaddr( hdd_context_t *pHddCtx,
9466 tSirMacAddr macAddr )
9467{
9468 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
9469 hdd_adapter_t *pAdapter;
9470 VOS_STATUS status;
9471
9472 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
9473
9474 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
9475 {
9476 pAdapter = pAdapterNode->pAdapter;
9477
9478 if( pAdapter && vos_mem_compare( pAdapter->macAddressCurrent.bytes,
9479 macAddr, sizeof(tSirMacAddr) ) )
9480 {
9481 return pAdapter;
9482 }
9483 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
9484 pAdapterNode = pNext;
9485 }
9486
9487 return NULL;
9488
9489}
9490
9491hdd_adapter_t * hdd_get_adapter_by_name( hdd_context_t *pHddCtx, tANI_U8 *name )
9492{
9493 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
9494 hdd_adapter_t *pAdapter;
9495 VOS_STATUS status;
9496
9497 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
9498
9499 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
9500 {
9501 pAdapter = pAdapterNode->pAdapter;
9502
9503 if( pAdapter && !strncmp( pAdapter->dev->name, (const char *)name,
9504 IFNAMSIZ ) )
9505 {
9506 return pAdapter;
9507 }
9508 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
9509 pAdapterNode = pNext;
9510 }
9511
9512 return NULL;
9513
9514}
9515
Ganesh Kondabattinicbfdc392015-09-11 19:12:59 +05309516hdd_adapter_t *hdd_get_adapter_by_sme_session_id( hdd_context_t *pHddCtx,
9517 tANI_U32 sme_session_id )
9518{
9519 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
9520 hdd_adapter_t *pAdapter;
9521 VOS_STATUS vos_status;
9522
9523
9524 vos_status = hdd_get_front_adapter( pHddCtx, &pAdapterNode);
9525
9526 while ((NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == vos_status))
9527 {
9528 pAdapter = pAdapterNode->pAdapter;
9529
9530 if (pAdapter->sessionId == sme_session_id)
9531 return pAdapter;
9532
9533 vos_status = hdd_get_next_adapter(pHddCtx, pAdapterNode, &pNext);
9534 pAdapterNode = pNext;
9535 }
9536
9537 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9538 "%s: sme_session_id %d does not exist with host",
9539 __func__, sme_session_id);
9540
9541 return NULL;
9542}
9543
Jeff Johnson295189b2012-06-20 16:38:30 -07009544hdd_adapter_t * hdd_get_adapter( hdd_context_t *pHddCtx, device_mode_t mode )
9545{
9546 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
9547 hdd_adapter_t *pAdapter;
9548 VOS_STATUS status;
9549
9550 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
9551
9552 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
9553 {
9554 pAdapter = pAdapterNode->pAdapter;
9555
9556 if( pAdapter && (mode == pAdapter->device_mode) )
9557 {
9558 return pAdapter;
9559 }
9560 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
9561 pAdapterNode = pNext;
9562 }
9563
9564 return NULL;
9565
9566}
9567
9568//Remove this function later
9569hdd_adapter_t * hdd_get_mon_adapter( hdd_context_t *pHddCtx )
9570{
9571 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
9572 hdd_adapter_t *pAdapter;
9573 VOS_STATUS status;
9574
9575 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
9576
9577 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
9578 {
9579 pAdapter = pAdapterNode->pAdapter;
9580
9581 if( pAdapter && WLAN_HDD_MONITOR == pAdapter->device_mode )
9582 {
9583 return pAdapter;
9584 }
9585
9586 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
9587 pAdapterNode = pNext;
9588 }
9589
9590 return NULL;
9591
9592}
9593
Jeff Johnson295189b2012-06-20 16:38:30 -07009594/**---------------------------------------------------------------------------
9595
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05309596 \brief hdd_get_operating_channel() -
Jeff Johnson295189b2012-06-20 16:38:30 -07009597
9598 This API returns the operating channel of the requested device mode
9599
9600 \param - pHddCtx - Pointer to the HDD context.
9601 - mode - Device mode for which operating channel is required
9602 suported modes - WLAN_HDD_INFRA_STATION, WLAN_HDD_P2P_CLIENT
9603 WLAN_HDD_SOFTAP, WLAN_HDD_P2P_GO.
9604 \return - channel number. "0" id the requested device is not found OR it is not connected.
9605 --------------------------------------------------------------------------*/
9606v_U8_t hdd_get_operating_channel( hdd_context_t *pHddCtx, device_mode_t mode )
9607{
9608 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
9609 VOS_STATUS status;
9610 hdd_adapter_t *pAdapter;
9611 v_U8_t operatingChannel = 0;
9612
9613 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
9614
9615 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
9616 {
9617 pAdapter = pAdapterNode->pAdapter;
9618
9619 if( mode == pAdapter->device_mode )
9620 {
9621 switch(pAdapter->device_mode)
9622 {
9623 case WLAN_HDD_INFRA_STATION:
9624 case WLAN_HDD_P2P_CLIENT:
9625 if( hdd_connIsConnected( WLAN_HDD_GET_STATION_CTX_PTR( pAdapter )) )
9626 operatingChannel = (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.operationChannel;
9627 break;
9628 case WLAN_HDD_SOFTAP:
9629 case WLAN_HDD_P2P_GO:
9630 /*softap connection info */
9631 if(test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
9632 operatingChannel = (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->operatingChannel;
9633 break;
9634 default:
9635 break;
9636 }
9637
9638 break; //Found the device of interest. break the loop
9639 }
9640
9641 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
9642 pAdapterNode = pNext;
9643 }
9644 return operatingChannel;
9645}
9646
9647#ifdef WLAN_FEATURE_PACKET_FILTERING
9648/**---------------------------------------------------------------------------
9649
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05309650 \brief __hdd_set_multicast_list() -
Jeff Johnson295189b2012-06-20 16:38:30 -07009651
9652 This used to set the multicast address list.
9653
9654 \param - dev - Pointer to the WLAN device.
9655 - skb - Pointer to OS packet (sk_buff).
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05309656 \return - success/fail
Jeff Johnson295189b2012-06-20 16:38:30 -07009657
9658 --------------------------------------------------------------------------*/
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05309659static void __hdd_set_multicast_list(struct net_device *dev)
Jeff Johnson295189b2012-06-20 16:38:30 -07009660{
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05309661 hdd_adapter_t *pAdapter;
9662 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07009663 int mc_count;
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05309664 int i = 0, ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07009665 struct netdev_hw_addr *ha;
Gopichand Nakkala0f276812013-02-24 14:45:51 +05309666
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05309667 ENTER();
9668
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05309669 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkala0f276812013-02-24 14:45:51 +05309670 if (NULL == pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07009671 {
9672 hddLog(VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala0f276812013-02-24 14:45:51 +05309673 "%s: Adapter context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009674 return;
9675 }
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05309676 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
9677 ret = wlan_hdd_validate_context(pHddCtx);
9678 if (0 != ret)
9679 {
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05309680 return;
9681 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009682 if (dev->flags & IFF_ALLMULTI)
9683 {
9684 hddLog(VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07009685 "%s: allow all multicast frames", __func__);
Gopichand Nakkala0f276812013-02-24 14:45:51 +05309686 pAdapter->mc_addr_list.mc_cnt = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07009687 }
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05309688 else
Jeff Johnson295189b2012-06-20 16:38:30 -07009689 {
9690 mc_count = netdev_mc_count(dev);
9691 hddLog(VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07009692 "%s: mc_count = %u", __func__, mc_count);
Jeff Johnson295189b2012-06-20 16:38:30 -07009693 if (mc_count > WLAN_HDD_MAX_MC_ADDR_LIST)
9694 {
9695 hddLog(VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07009696 "%s: No free filter available; allow all multicast frames", __func__);
Gopichand Nakkala0f276812013-02-24 14:45:51 +05309697 pAdapter->mc_addr_list.mc_cnt = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07009698 return;
9699 }
9700
Gopichand Nakkala0f276812013-02-24 14:45:51 +05309701 pAdapter->mc_addr_list.mc_cnt = mc_count;
Jeff Johnson295189b2012-06-20 16:38:30 -07009702
9703 netdev_for_each_mc_addr(ha, dev) {
9704 if (i == mc_count)
9705 break;
Gopichand Nakkala0f276812013-02-24 14:45:51 +05309706 memset(&(pAdapter->mc_addr_list.addr[i][0]), 0, ETH_ALEN);
9707 memcpy(&(pAdapter->mc_addr_list.addr[i][0]), ha->addr, ETH_ALEN);
Arif Hussain6d2a3322013-11-17 19:50:10 -08009708 hddLog(VOS_TRACE_LEVEL_INFO, "%s: mlist[%d] = "MAC_ADDRESS_STR,
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05309709 __func__, i,
Gopichand Nakkala0f276812013-02-24 14:45:51 +05309710 MAC_ADDR_ARRAY(pAdapter->mc_addr_list.addr[i]));
Jeff Johnson295189b2012-06-20 16:38:30 -07009711 i++;
9712 }
9713 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05309714
Ganesh Kondabattinifb37e652015-10-09 15:46:47 +05309715 if (pHddCtx->hdd_wlan_suspended)
9716 {
9717 /*
9718 * Configure the Mcast address list to FW
9719 * If wlan is already in suspend mode
9720 */
9721 wlan_hdd_set_mc_addr_list(pAdapter, TRUE);
9722 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05309723 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07009724 return;
9725}
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05309726
9727static void hdd_set_multicast_list(struct net_device *dev)
9728{
9729 vos_ssr_protect(__func__);
9730 __hdd_set_multicast_list(dev);
9731 vos_ssr_unprotect(__func__);
9732}
Jeff Johnson295189b2012-06-20 16:38:30 -07009733#endif
9734
9735/**---------------------------------------------------------------------------
9736
9737 \brief hdd_select_queue() -
9738
9739 This function is registered with the Linux OS for network
9740 core to decide which queue to use first.
9741
9742 \param - dev - Pointer to the WLAN device.
9743 - skb - Pointer to OS packet (sk_buff).
9744 \return - ac, Queue Index/access category corresponding to UP in IP header
9745
9746 --------------------------------------------------------------------------*/
9747v_U16_t hdd_select_queue(struct net_device *dev,
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05309748 struct sk_buff *skb
9749#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,13,0))
9750 , void *accel_priv
9751#endif
9752#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
9753 , select_queue_fallback_t fallback
9754#endif
9755)
Jeff Johnson295189b2012-06-20 16:38:30 -07009756{
9757 return hdd_wmm_select_queue(dev, skb);
9758}
9759
9760
9761/**---------------------------------------------------------------------------
9762
9763 \brief hdd_wlan_initial_scan() -
9764
9765 This function triggers the initial scan
9766
9767 \param - pAdapter - Pointer to the HDD adapter.
9768
9769 --------------------------------------------------------------------------*/
9770void hdd_wlan_initial_scan(hdd_adapter_t *pAdapter)
9771{
9772 tCsrScanRequest scanReq;
9773 tCsrChannelInfo channelInfo;
9774 eHalStatus halStatus;
Jeff Johnson02797792013-10-26 19:17:13 -07009775 tANI_U32 scanId;
Jeff Johnson295189b2012-06-20 16:38:30 -07009776 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
9777
9778 vos_mem_zero(&scanReq, sizeof(tCsrScanRequest));
9779 vos_mem_set(&scanReq.bssid, sizeof(tCsrBssid), 0xff);
9780 scanReq.BSSType = eCSR_BSS_TYPE_ANY;
9781
9782 if(sme_Is11dSupported(pHddCtx->hHal))
9783 {
9784 halStatus = sme_ScanGetBaseChannels( pHddCtx->hHal, &channelInfo );
9785 if ( HAL_STATUS_SUCCESS( halStatus ) )
9786 {
9787 scanReq.ChannelInfo.ChannelList = vos_mem_malloc(channelInfo.numOfChannels);
9788 if( !scanReq.ChannelInfo.ChannelList )
9789 {
9790 hddLog(VOS_TRACE_LEVEL_ERROR, "%s kmalloc failed", __func__);
9791 vos_mem_free(channelInfo.ChannelList);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08009792 channelInfo.ChannelList = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07009793 return;
9794 }
9795 vos_mem_copy(scanReq.ChannelInfo.ChannelList, channelInfo.ChannelList,
9796 channelInfo.numOfChannels);
9797 scanReq.ChannelInfo.numOfChannels = channelInfo.numOfChannels;
9798 vos_mem_free(channelInfo.ChannelList);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08009799 channelInfo.ChannelList = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07009800 }
9801
9802 scanReq.scanType = eSIR_PASSIVE_SCAN;
9803 scanReq.requestType = eCSR_SCAN_REQUEST_11D_SCAN;
9804 scanReq.maxChnTime = pHddCtx->cfg_ini->nPassiveMaxChnTime;
9805 scanReq.minChnTime = pHddCtx->cfg_ini->nPassiveMinChnTime;
9806 }
9807 else
9808 {
9809 scanReq.scanType = eSIR_ACTIVE_SCAN;
9810 scanReq.requestType = eCSR_SCAN_REQUEST_FULL_SCAN;
9811 scanReq.maxChnTime = pHddCtx->cfg_ini->nActiveMaxChnTime;
9812 scanReq.minChnTime = pHddCtx->cfg_ini->nActiveMinChnTime;
9813 }
9814
9815 halStatus = sme_ScanRequest(pHddCtx->hHal, pAdapter->sessionId, &scanReq, &scanId, NULL, NULL);
9816 if ( !HAL_STATUS_SUCCESS( halStatus ) )
9817 {
9818 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: sme_ScanRequest failed status code %d",
9819 __func__, halStatus );
9820 }
9821
9822 if(sme_Is11dSupported(pHddCtx->hHal))
9823 vos_mem_free(scanReq.ChannelInfo.ChannelList);
9824}
9825
mukul sharmabab477d2015-06-11 17:14:55 +05309826void hdd_purge_cmd_list_all_adapters( hdd_context_t *pHddCtx )
9827{
9828 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
9829 VOS_STATUS status;
9830 hdd_adapter_t *pAdapter;
9831
9832 ENTER();
9833
9834 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
9835
9836 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
9837 {
9838 pAdapter = pAdapterNode->pAdapter;
9839
9840 status = sme_PurgeCmdList(pHddCtx->hHal, pAdapter->sessionId);
9841 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
9842 pAdapterNode = pNext;
9843 }
9844
9845 EXIT();
9846}
Jeff Johnson295189b2012-06-20 16:38:30 -07009847/**---------------------------------------------------------------------------
9848
9849 \brief hdd_full_power_callback() - HDD full power callback function
9850
9851 This is the function invoked by SME to inform the result of a full power
9852 request issued by HDD
9853
9854 \param - callbackcontext - Pointer to cookie
9855 \param - status - result of request
9856
9857 \return - None
9858
9859 --------------------------------------------------------------------------*/
9860static void hdd_full_power_callback(void *callbackContext, eHalStatus status)
9861{
Jeff Johnson72a40512013-12-19 10:14:15 -08009862 struct statsContext *pContext = callbackContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07009863
9864 hddLog(VOS_TRACE_LEVEL_INFO,
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05309865 "%s: context = %p, status = %d", __func__, pContext, status);
Jeff Johnson295189b2012-06-20 16:38:30 -07009866
9867 if (NULL == callbackContext)
9868 {
9869 hddLog(VOS_TRACE_LEVEL_ERROR,
9870 "%s: Bad param, context [%p]",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07009871 __func__, callbackContext);
Jeff Johnson295189b2012-06-20 16:38:30 -07009872 return;
9873 }
9874
Jeff Johnson72a40512013-12-19 10:14:15 -08009875 /* there is a race condition that exists between this callback
9876 function and the caller since the caller could time out either
9877 before or while this code is executing. we use a spinlock to
9878 serialize these actions */
9879 spin_lock(&hdd_context_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07009880
9881 if (POWER_CONTEXT_MAGIC != pContext->magic)
9882 {
9883 /* the caller presumably timed out so there is nothing we can do */
Jeff Johnson72a40512013-12-19 10:14:15 -08009884 spin_unlock(&hdd_context_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07009885 hddLog(VOS_TRACE_LEVEL_WARN,
9886 "%s: Invalid context, magic [%08x]",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07009887 __func__, pContext->magic);
Jeff Johnson295189b2012-06-20 16:38:30 -07009888 return;
9889 }
9890
Jeff Johnson72a40512013-12-19 10:14:15 -08009891 /* context is valid so caller is still waiting */
9892
9893 /* paranoia: invalidate the magic */
9894 pContext->magic = 0;
9895
9896 /* notify the caller */
Jeff Johnson295189b2012-06-20 16:38:30 -07009897 complete(&pContext->completion);
Jeff Johnson72a40512013-12-19 10:14:15 -08009898
9899 /* serialization is complete */
9900 spin_unlock(&hdd_context_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07009901}
9902
Katya Nigamf0511f62015-05-05 16:40:57 +05309903void wlan_hdd_mon_set_typesubtype( hdd_mon_ctx_t *pMonCtx,int type)
9904{
9905 pMonCtx->typeSubtypeBitmap = 0;
9906 if( type%10 ) /* Management Packets */
9907 pMonCtx->typeSubtypeBitmap |= 0xFFFF;
9908 type/=10;
9909 if( type%10 ) /* Control Packets */
9910 pMonCtx->typeSubtypeBitmap |= 0xFFFF0000;
9911 type/=10;
9912 if( type%10 ) /* Data Packets */
9913 pMonCtx->typeSubtypeBitmap |= 0xFFFF00000000;
9914}
9915
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +05309916VOS_STATUS wlan_hdd_mon_postMsg(tANI_U32 *magic, struct completion *cmpVar,
9917 hdd_mon_ctx_t *pMonCtx , void* callback)
Katya Nigamf0511f62015-05-05 16:40:57 +05309918{
9919 vos_msg_t monMsg;
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +05309920 tSirMonModeReq *pMonModeReq;
Katya Nigamf0511f62015-05-05 16:40:57 +05309921
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +05309922 if (MON_MODE_START == pMonCtx->state)
9923 monMsg.type = WDA_MON_START_REQ;
9924 else if (MON_MODE_STOP == pMonCtx->state)
9925 monMsg.type = WDA_MON_STOP_REQ;
9926 else {
9927 hddLog(VOS_TRACE_LEVEL_ERROR,
9928 FL("invalid monitor state %d"), pMonCtx->state);
Katya Nigamf0511f62015-05-05 16:40:57 +05309929 return VOS_STATUS_E_FAILURE;
9930 }
9931
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +05309932 pMonModeReq = vos_mem_malloc(sizeof(tSirMonModeReq));
9933 if (pMonModeReq == NULL) {
9934 hddLog(VOS_TRACE_LEVEL_ERROR,
9935 FL("fail to allocate memory for monitor mode req"));
9936 return VOS_STATUS_E_FAILURE;
9937 }
Katya Nigamf0511f62015-05-05 16:40:57 +05309938
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +05309939 pMonModeReq->magic = magic;
9940 pMonModeReq->cmpVar = cmpVar;
9941 pMonModeReq->data = pMonCtx;
9942 pMonModeReq->callback = callback;
Katya Nigamf0511f62015-05-05 16:40:57 +05309943
Katya Nigamf0511f62015-05-05 16:40:57 +05309944 monMsg.reserved = 0;
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +05309945 monMsg.bodyptr = pMonModeReq;
Katya Nigamf0511f62015-05-05 16:40:57 +05309946 monMsg.bodyval = 0;
9947
9948 if (VOS_STATUS_SUCCESS != vos_mq_post_message(
9949 VOS_MODULE_ID_WDA,(vos_msg_t *)&monMsg)) {
9950 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: : Failed to post Msg to HAL",__func__);
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +05309951 vos_mem_free(pMonModeReq);
Katya Nigamf0511f62015-05-05 16:40:57 +05309952 }
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +05309953 return VOS_STATUS_SUCCESS;
Katya Nigamf0511f62015-05-05 16:40:57 +05309954}
9955
Katya Nigame7b69a82015-04-28 15:24:06 +05309956void wlan_hdd_mon_close(hdd_context_t *pHddCtx)
9957{
9958 VOS_STATUS vosStatus;
9959 v_CONTEXT_t pVosContext = pHddCtx->pvosContext;
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +05309960 long ret;
9961 hdd_mon_ctx_t *pMonCtx = NULL;
9962 v_U32_t magic;
9963 struct completion cmpVar;
Hanumantha Reddy Pothulac99bc062015-09-08 14:59:26 +05309964
Katya Nigame7b69a82015-04-28 15:24:06 +05309965 hdd_adapter_t *pAdapter = hdd_get_adapter(pHddCtx,WLAN_HDD_MONITOR);
9966 if(pAdapter == NULL || pVosContext == NULL)
9967 {
9968 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, "%s:pAdapter is NULL",__func__);
9969 return ;
9970 }
Katya Nigamf0511f62015-05-05 16:40:57 +05309971
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +05309972 pMonCtx = WLAN_HDD_GET_MONITOR_CTX_PTR(pAdapter);
9973 if (pMonCtx!= NULL && pMonCtx->state == MON_MODE_START) {
9974 pMonCtx->state = MON_MODE_STOP;
9975 magic = MON_MODE_MSG_MAGIC;
9976 init_completion(&cmpVar);
9977 if (VOS_STATUS_SUCCESS !=
9978 wlan_hdd_mon_postMsg(&magic, &cmpVar,
9979 pMonCtx, hdd_monPostMsgCb)) {
9980 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9981 FL("failed to post MON MODE REQ"));
9982 pMonCtx->state = MON_MODE_START;
9983 magic = 0;
9984 return;
9985 }
9986 ret = wait_for_completion_timeout(&cmpVar, MON_MODE_MSG_TIMEOUT);
9987 magic = 0;
9988 if (ret <= 0 ) {
9989 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9990 FL("timeout on monitor mode completion %ld"), ret);
9991 }
9992 }
9993
Katya Nigame7b69a82015-04-28 15:24:06 +05309994 hdd_UnregisterWext(pAdapter->dev);
9995
9996 vos_mon_stop( pVosContext );
9997
9998 vosStatus = vos_sched_close( pVosContext );
9999 if (!VOS_IS_STATUS_SUCCESS(vosStatus)) {
10000 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
10001 "%s: Failed to close VOSS Scheduler",__func__);
10002 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
10003 }
10004
10005 vosStatus = vos_nv_close();
10006 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
10007 {
10008 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
10009 "%s: Failed to close NV", __func__);
10010 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
10011 }
10012
10013 vos_close(pVosContext);
10014
10015 #ifdef WLAN_KD_READY_NOTIFIER
10016 nl_srv_exit(pHddCtx->ptt_pid);
10017 #else
10018 nl_srv_exit();
10019 #endif
10020
Katya Nigame7b69a82015-04-28 15:24:06 +053010021 hdd_close_all_adapters( pHddCtx );
Katya Nigame7b69a82015-04-28 15:24:06 +053010022}
Agrawal Ashish33ec71e2015-11-26 20:20:58 +053010023/**
10024 * hdd_wlan_free_wiphy_channels - free Channel pointer for wiphy
10025 * @ wiphy: the wiphy to validate against
10026 *
10027 * Return: void
10028 */
10029void hdd_wlan_free_wiphy_channels(struct wiphy *wiphy)
10030{
10031 int i =0;
10032 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
10033 {
10034 if (NULL != wiphy->bands[i] &&
10035 (NULL != wiphy->bands[i]->channels))
10036 {
10037 vos_mem_free(wiphy->bands[i]->channels);
10038 wiphy->bands[i]->channels = NULL;
10039 }
10040 }
10041}
Jeff Johnson295189b2012-06-20 16:38:30 -070010042/**---------------------------------------------------------------------------
10043
10044 \brief hdd_wlan_exit() - HDD WLAN exit function
10045
10046 This is the driver exit point (invoked during rmmod)
10047
10048 \param - pHddCtx - Pointer to the HDD Context
10049
10050 \return - None
10051
10052 --------------------------------------------------------------------------*/
10053void hdd_wlan_exit(hdd_context_t *pHddCtx)
10054{
10055 eHalStatus halStatus;
10056 v_CONTEXT_t pVosContext = pHddCtx->pvosContext;
10057 VOS_STATUS vosStatus;
Gopichand Nakkala66923aa2013-03-06 23:17:24 +053010058 struct wiphy *wiphy = pHddCtx->wiphy;
Mingcheng Zhu87f22fc2014-01-30 19:23:32 -080010059 hdd_adapter_t* pAdapter = NULL;
Jeff Johnson72a40512013-12-19 10:14:15 -080010060 struct statsContext powerContext;
Jeff Johnson295189b2012-06-20 16:38:30 -070010061 long lrc;
c_hpothu5ab05e92014-06-13 17:34:05 +053010062 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070010063
10064 ENTER();
10065
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +053010066
Katya Nigame7b69a82015-04-28 15:24:06 +053010067 if (VOS_MONITOR_MODE == hdd_get_conparam())
10068 {
10069 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: MONITOR MODE",__func__);
10070 wlan_hdd_mon_close(pHddCtx);
Hanumantha Reddy Pothulac99bc062015-09-08 14:59:26 +053010071 goto free_hdd_ctx;
Katya Nigame7b69a82015-04-28 15:24:06 +053010072 }
10073 else if (VOS_FTM_MODE != hdd_get_conparam())
Jeff Johnson88ba7742013-02-27 14:36:02 -080010074 {
10075 // Unloading, restart logic is no more required.
10076 wlan_hdd_restart_deinit(pHddCtx);
Jeff Johnsone7245742012-09-05 17:12:55 -070010077
Agarwal Ashishb20e0ff2014-12-17 22:50:19 +053010078#ifdef FEATURE_WLAN_TDLS
10079 /* At the time of driver unloading; if tdls connection is present;
10080 * hdd_rx_packet_cbk calls wlan_hdd_tdls_find_peer.
10081 * wlan_hdd_tdls_find_peer always checks for valid context;
10082 * as load/unload in progress there can be a race condition.
10083 * hdd_rx_packet_cbk calls wlan_hdd_tdls_find_peer only
10084 * when tdls state is enabled.
10085 * As soon as driver set load/unload flag; tdls flag also needs
10086 * to be disabled so that hdd_rx_packet_cbk won't call
10087 * wlan_hdd_tdls_find_peer.
10088 */
Masti, Narayanraddi20494af2015-12-17 20:56:42 +053010089 wlan_hdd_tdls_set_mode(pHddCtx, eTDLS_SUPPORT_DISABLED, FALSE,
10090 HDD_SET_TDLS_MODE_SOURCE_USER);
Agarwal Ashishb20e0ff2014-12-17 22:50:19 +053010091#endif
10092
c_hpothu5ab05e92014-06-13 17:34:05 +053010093 vosStatus = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
10094 while (NULL != pAdapterNode && VOS_STATUS_E_EMPTY != vosStatus)
Jeff Johnson295189b2012-06-20 16:38:30 -070010095 {
c_hpothu5ab05e92014-06-13 17:34:05 +053010096 pAdapter = pAdapterNode->pAdapter;
10097 if (NULL != pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -070010098 {
Mahesh A Saptasagar305e2632015-03-04 12:57:33 +053010099 /* Disable TX on the interface, after this hard_start_xmit() will
10100 * not be called on that interface
10101 */
10102 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
10103 netif_tx_disable(pAdapter->dev);
10104
10105 /* Mark the interface status as "down" for outside world */
10106 netif_carrier_off(pAdapter->dev);
10107
Agarwal Ashish9ffa5b92014-11-18 21:07:02 +053010108 /* DeInit the adapter. This ensures that all data packets
10109 * are freed.
10110 */
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +053010111#ifdef FEATURE_WLAN_TDLS
10112 mutex_lock(&pHddCtx->tdls_lock);
10113#endif
c_hpothu002231a2015-02-05 14:58:51 +053010114 hdd_deinit_adapter(pHddCtx, pAdapter, FALSE);
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +053010115#ifdef FEATURE_WLAN_TDLS
10116 mutex_unlock(&pHddCtx->tdls_lock);
10117#endif
Masti, Narayanraddi26378462016-01-05 18:20:28 +053010118 vos_flush_delayed_work(&pHddCtx->scan_ctxt.scan_work);
10119
10120 wlan_hdd_init_deinit_defer_scan_context(&pHddCtx->scan_ctxt);
Agarwal Ashish9ffa5b92014-11-18 21:07:02 +053010121
c_hpothu5ab05e92014-06-13 17:34:05 +053010122 if (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
10123 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode)
10124 {
10125 wlan_hdd_cfg80211_deregister_frames(pAdapter);
10126 hdd_UnregisterWext(pAdapter->dev);
10127 }
Kaushik, Sushant4975a572014-10-21 16:07:48 +053010128
Jeff Johnson295189b2012-06-20 16:38:30 -070010129 }
c_hpothu5ab05e92014-06-13 17:34:05 +053010130 vosStatus = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
10131 pAdapterNode = pNext;
Jeff Johnson295189b2012-06-20 16:38:30 -070010132 }
mukul sharmabab477d2015-06-11 17:14:55 +053010133
10134 //Purge all sme cmd's for all interface
10135 hdd_purge_cmd_list_all_adapters(pHddCtx);
10136
Kaushik, Sushant4975a572014-10-21 16:07:48 +053010137 // Cancel any outstanding scan requests. We are about to close all
10138 // of our adapters, but an adapter structure is what SME passes back
10139 // to our callback function. Hence if there are any outstanding scan
10140 // requests then there is a race condition between when the adapter
10141 // is closed and when the callback is invoked.We try to resolve that
10142 // race condition here by canceling any outstanding scans before we
10143 // close the adapters.
10144 // Note that the scans may be cancelled in an asynchronous manner,
10145 // so ideally there needs to be some kind of synchronization. Rather
10146 // than introduce a new synchronization here, we will utilize the
10147 // fact that we are about to Request Full Power, and since that is
10148 // synchronized, the expectation is that by the time Request Full
10149 // Power has completed all scans will be cancelled.
10150 if (pHddCtx->scan_info.mScanPending)
10151 {
Hema Aparna Medicharlaf05f6cd2015-01-21 14:44:19 +053010152 if(NULL != pAdapter)
10153 {
10154 hddLog(VOS_TRACE_LEVEL_INFO,
10155 FL("abort scan mode: %d sessionId: %d"),
10156 pAdapter->device_mode,
10157 pAdapter->sessionId);
10158 }
10159 hdd_abort_mac_scan(pHddCtx,
10160 pHddCtx->scan_info.sessionId,
10161 eCSR_SCAN_ABORT_DEFAULT);
Kaushik, Sushant4975a572014-10-21 16:07:48 +053010162 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010163 }
c_hpothu5ab05e92014-06-13 17:34:05 +053010164 else
Jeff Johnson88ba7742013-02-27 14:36:02 -080010165 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010166 hddLog(VOS_TRACE_LEVEL_INFO,"%s: FTM MODE",__func__);
Hanumantha Reddy Pothula45af96b2015-02-12 16:07:58 +053010167 if (pHddCtx->ftm.ftm_state == WLAN_FTM_STARTING)
10168 {
10169 INIT_COMPLETION(pHddCtx->ftm.startCmpVar);
10170 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
10171 "%s: in middle of FTM START", __func__);
10172 lrc = wait_for_completion_timeout(&pHddCtx->ftm.startCmpVar,
10173 msecs_to_jiffies(20000));
10174 if(!lrc)
10175 {
10176 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
10177 "%s: timedout on ftmStartCmpVar fatal error", __func__);
10178 }
10179 }
Jeff Johnson88ba7742013-02-27 14:36:02 -080010180 wlan_hdd_ftm_close(pHddCtx);
10181 goto free_hdd_ctx;
10182 }
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010183
Jeff Johnson295189b2012-06-20 16:38:30 -070010184 /* DeRegister with platform driver as client for Suspend/Resume */
10185 vosStatus = hddDeregisterPmOps(pHddCtx);
10186 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
10187 {
10188 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddDeregisterPmOps failed",__func__);
10189 VOS_ASSERT(0);
10190 }
10191
10192 vosStatus = hddDevTmUnregisterNotifyCallback(pHddCtx);
10193 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
10194 {
10195 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddDevTmUnregisterNotifyCallback failed",__func__);
10196 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010197
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -070010198 //Stop the traffic monitor timer
10199 if ( VOS_TIMER_STATE_RUNNING ==
10200 vos_timer_getCurrentState(&pHddCtx->tx_rx_trafficTmr))
10201 {
10202 vos_timer_stop(&pHddCtx->tx_rx_trafficTmr);
10203 }
10204
10205 // Destroy the traffic monitor timer
10206 if (!VOS_IS_STATUS_SUCCESS(vos_timer_destroy(
10207 &pHddCtx->tx_rx_trafficTmr)))
10208 {
10209 hddLog(VOS_TRACE_LEVEL_ERROR,
10210 "%s: Cannot deallocate Traffic monitor timer", __func__);
10211 }
10212
Bhargav Shahd0715912015-10-01 18:17:37 +053010213 if (VOS_TIMER_STATE_RUNNING ==
10214 vos_timer_getCurrentState(&pHddCtx->delack_timer)) {
10215 vos_timer_stop(&pHddCtx->delack_timer);
10216 }
10217
10218 if (!VOS_IS_STATUS_SUCCESS(vos_timer_destroy(
10219 &pHddCtx->delack_timer))) {
10220 hddLog(VOS_TRACE_LEVEL_ERROR,
10221 "%s: Cannot deallocate Bus bandwidth timer", __func__);
10222 }
10223
Masti, Narayanraddi44b0db02015-12-22 11:54:35 +053010224 if (VOS_TIMER_STATE_RUNNING ==
10225 vos_timer_getCurrentState(&pHddCtx->tdls_source_timer)) {
10226 vos_timer_stop(&pHddCtx->tdls_source_timer);
10227 }
10228
10229 vos_timer_destroy(&pHddCtx->tdls_source_timer);
10230
Jeff Johnson295189b2012-06-20 16:38:30 -070010231 //Disable IMPS/BMPS as we do not want the device to enter any power
10232 //save mode during shutdown
10233 sme_DisablePowerSave(pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
10234 sme_DisablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
10235 sme_DisablePowerSave(pHddCtx->hHal, ePMC_UAPSD_MODE_POWER_SAVE);
10236
10237 //Ensure that device is in full power as we will touch H/W during vos_Stop
10238 init_completion(&powerContext.completion);
10239 powerContext.magic = POWER_CONTEXT_MAGIC;
10240
10241 halStatus = sme_RequestFullPower(pHddCtx->hHal, hdd_full_power_callback,
10242 &powerContext, eSME_FULL_PWR_NEEDED_BY_HDD);
10243
10244 if (eHAL_STATUS_SUCCESS != halStatus)
10245 {
10246 if (eHAL_STATUS_PMC_PENDING == halStatus)
10247 {
10248 /* request was sent -- wait for the response */
10249 lrc = wait_for_completion_interruptible_timeout(
10250 &powerContext.completion,
10251 msecs_to_jiffies(WLAN_WAIT_TIME_POWER));
Jeff Johnson295189b2012-06-20 16:38:30 -070010252 if (lrc <= 0)
10253 {
10254 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: %s while requesting full power",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070010255 __func__, (0 == lrc) ? "timeout" : "interrupt");
Jeff Johnson295189b2012-06-20 16:38:30 -070010256 }
10257 }
10258 else
10259 {
10260 hddLog(VOS_TRACE_LEVEL_ERROR,
10261 "%s: Request for Full Power failed, status %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070010262 __func__, halStatus);
Jeff Johnson295189b2012-06-20 16:38:30 -070010263 /* continue -- need to clean up as much as possible */
10264 }
10265 }
Hanumantha Reddy Pothula81b42b22015-05-12 13:52:00 +053010266 if ((eHAL_STATUS_SUCCESS == halStatus) ||
10267 (eHAL_STATUS_PMC_PENDING == halStatus && lrc > 0))
10268 {
10269 /* This will issue a dump command which will clean up
10270 BTQM queues and unblock MC thread */
10271 vos_fwDumpReq(274, 0, 0, 0, 0, 1);
10272 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010273
Jeff Johnson72a40512013-12-19 10:14:15 -080010274 /* either we never sent a request, we sent a request and received a
10275 response or we sent a request and timed out. if we never sent a
10276 request or if we sent a request and got a response, we want to
10277 clear the magic out of paranoia. if we timed out there is a
10278 race condition such that the callback function could be
10279 executing at the same time we are. of primary concern is if the
10280 callback function had already verified the "magic" but had not
10281 yet set the completion variable when a timeout occurred. we
10282 serialize these activities by invalidating the magic while
10283 holding a shared spinlock which will cause us to block if the
10284 callback is currently executing */
10285 spin_lock(&hdd_context_lock);
10286 powerContext.magic = 0;
10287 spin_unlock(&hdd_context_lock);
10288
Hema Aparna Medicharlaa6cf65e2015-06-01 16:23:28 +053010289 /* If Device is shutdown, no point for SME to wait for responses
10290 from device. Pre Close SME */
10291 if(wcnss_device_is_shutdown())
10292 {
10293 sme_PreClose(pHddCtx->hHal);
10294 }
Yue Ma0d4891e2013-08-06 17:01:45 -070010295 hdd_debugfs_exit(pHddCtx);
10296
Ratheesh S P35ed8b12015-04-27 14:01:07 +053010297#ifdef WLAN_NS_OFFLOAD
Ratheesh S P36dbc932015-08-07 14:28:57 +053010298 hddLog(LOG1, FL("Unregister IPv6 notifier"));
Ratheesh S P35ed8b12015-04-27 14:01:07 +053010299 unregister_inet6addr_notifier(&pHddCtx->ipv6_notifier);
10300#endif
Ratheesh S P36dbc932015-08-07 14:28:57 +053010301 hddLog(LOG1, FL("Unregister IPv4 notifier"));
Ratheesh S P35ed8b12015-04-27 14:01:07 +053010302 unregister_inetaddr_notifier(&pHddCtx->ipv4_notifier);
10303
Jeff Johnson295189b2012-06-20 16:38:30 -070010304 // Unregister the Net Device Notifier
10305 unregister_netdevice_notifier(&hdd_netdev_notifier);
10306
Jeff Johnson295189b2012-06-20 16:38:30 -070010307 hdd_stop_all_adapters( pHddCtx );
10308
Jeff Johnson295189b2012-06-20 16:38:30 -070010309#ifdef WLAN_BTAMP_FEATURE
10310 vosStatus = WLANBAP_Stop(pVosContext);
10311 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
10312 {
10313 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
10314 "%s: Failed to stop BAP",__func__);
10315 }
10316#endif //WLAN_BTAMP_FEATURE
10317
10318 //Stop all the modules
10319 vosStatus = vos_stop( pVosContext );
10320 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
10321 {
10322 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
10323 "%s: Failed to stop VOSS",__func__);
10324 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
Hanumantha Reddy Pothulabd9601a2016-02-12 13:22:27 +053010325 if (isSsrPanicOnFailure())
10326 VOS_BUG(0);
Jeff Johnson295189b2012-06-20 16:38:30 -070010327 }
10328
Jeff Johnson295189b2012-06-20 16:38:30 -070010329 //This requires pMac access, Call this before vos_close().
Jeff Johnson295189b2012-06-20 16:38:30 -070010330 hdd_unregister_mcast_bcast_filter(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -070010331
10332 //Close the scheduler before calling vos_close to make sure no thread is
10333 // scheduled after the each module close is called i.e after all the data
10334 // structures are freed.
10335 vosStatus = vos_sched_close( pVosContext );
10336 if (!VOS_IS_STATUS_SUCCESS(vosStatus)) {
10337 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
10338 "%s: Failed to close VOSS Scheduler",__func__);
10339 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
10340 }
Jeff Johnsone7245742012-09-05 17:12:55 -070010341#ifdef WLAN_FEATURE_HOLD_RX_WAKELOCK
10342 /* Destroy the wake lock */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053010343 vos_wake_lock_destroy(&pHddCtx->rx_wake_lock);
Jeff Johnsone7245742012-09-05 17:12:55 -070010344#endif
Madan Mohan Koyyalamudi69fc3ad2012-11-28 16:04:56 -080010345 /* Destroy the wake lock */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053010346 vos_wake_lock_destroy(&pHddCtx->sap_wake_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -070010347
Mihir Shete7a24b5f2013-12-21 12:18:31 +053010348#ifdef CONFIG_ENABLE_LINUX_REG
10349 vosStatus = vos_nv_close();
10350 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
10351 {
10352 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
10353 "%s: Failed to close NV", __func__);
10354 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
10355 }
10356#endif
10357
Jeff Johnson295189b2012-06-20 16:38:30 -070010358 //Close VOSS
10359 //This frees pMac(HAL) context. There should not be any call that requires pMac access after this.
10360 vos_close(pVosContext);
10361
Jeff Johnson295189b2012-06-20 16:38:30 -070010362 //Close Watchdog
10363 if(pHddCtx->cfg_ini->fIsLogpEnabled)
10364 vos_watchdog_close(pVosContext);
10365
Gopichand Nakkalaa0358482013-06-12 17:05:47 +053010366 //Clean up HDD Nlink Service
10367 send_btc_nlink_msg(WLAN_MODULE_DOWN_IND, 0);
Gopichand Nakkalaa0358482013-06-12 17:05:47 +053010368
Manjeet Singh47ee8472016-04-11 11:57:18 +053010369 hdd_close_tx_queues(pHddCtx);
c_manjeecfd1efb2015-09-25 19:32:34 +053010370 wlan_free_fwr_mem_dump_buffer();
10371 memdump_deinit();
10372
Vinay Krishna Erannad938c422014-03-10 17:14:21 +053010373#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +053010374 if (pHddCtx->cfg_ini->wlanLoggingEnable)
Vinay Krishna Erannad938c422014-03-10 17:14:21 +053010375 {
10376 wlan_logging_sock_deactivate_svc();
10377 }
10378#endif
10379
Vinay Krishna Erannaef30b522014-08-26 17:48:16 +053010380#ifdef WLAN_KD_READY_NOTIFIER
10381 nl_srv_exit(pHddCtx->ptt_pid);
10382#else
10383 nl_srv_exit();
10384#endif /* WLAN_KD_READY_NOTIFIER */
10385
Abhishek Singh00b71972016-01-07 10:51:04 +053010386#ifdef WLAN_FEATURE_RMC
10387 hdd_close_cesium_nl_sock();
10388#endif /* WLAN_FEATURE_RMC */
Vinay Krishna Erannaef30b522014-08-26 17:48:16 +053010389
Jeff Johnson295189b2012-06-20 16:38:30 -070010390 hdd_close_all_adapters( pHddCtx );
10391
Padma, Santhosh Kumar9cd38332015-11-17 12:18:10 +053010392 vos_flush_delayed_work(&pHddCtx->spoof_mac_addr_work);
10393
Hanumantha Reddy Pothula97f9bc92015-08-10 17:21:20 +053010394free_hdd_ctx:
Jeff Johnson295189b2012-06-20 16:38:30 -070010395 /* free the power on lock from platform driver */
10396 if (free_riva_power_on_lock("wlan"))
10397 {
10398 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to free power on lock",
10399 __func__);
10400 }
10401
c_hpothu78c7b602014-05-17 17:35:49 +053010402 //Free up dynamically allocated members inside HDD Adapter
10403 if (pHddCtx->cfg_ini)
10404 {
10405 kfree(pHddCtx->cfg_ini);
10406 pHddCtx->cfg_ini= NULL;
10407 }
10408
Hanumantha Reddy Pothula6fe221c2016-01-28 15:01:09 +053010409 /* FTM/MONITOR mode, WIPHY did not registered
Leo Changf04ddad2013-09-18 13:46:38 -070010410 If un-register here, system crash will happen */
Hanumantha Reddy Pothula6fe221c2016-01-28 15:01:09 +053010411 if (!(VOS_FTM_MODE == hdd_get_conparam() ||
10412 VOS_MONITOR_MODE == hdd_get_conparam()))
Leo Changf04ddad2013-09-18 13:46:38 -070010413 {
10414 wiphy_unregister(wiphy) ;
Agrawal Ashish33ec71e2015-11-26 20:20:58 +053010415 hdd_wlan_free_wiphy_channels(wiphy);
Leo Changf04ddad2013-09-18 13:46:38 -070010416 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010417 wiphy_free(wiphy) ;
Jeff Johnson295189b2012-06-20 16:38:30 -070010418 if (hdd_is_ssr_required())
10419 {
10420 /* WDI timeout had happened during unload, so SSR is needed here */
Madan Mohan Koyyalamudi3246f5b2012-10-15 15:40:02 -070010421 subsystem_restart("wcnss");
Jeff Johnson295189b2012-06-20 16:38:30 -070010422 msleep(5000);
10423 }
10424 hdd_set_ssr_required (VOS_FALSE);
10425}
10426
10427
10428/**---------------------------------------------------------------------------
10429
10430 \brief hdd_update_config_from_nv() - Function to update the contents of
10431 the running configuration with parameters taken from NV storage
10432
10433 \param - pHddCtx - Pointer to the HDD global context
10434
10435 \return - VOS_STATUS_SUCCESS if successful
10436
10437 --------------------------------------------------------------------------*/
10438static VOS_STATUS hdd_update_config_from_nv(hdd_context_t* pHddCtx)
10439{
Jeff Johnson295189b2012-06-20 16:38:30 -070010440 v_BOOL_t itemIsValid = VOS_FALSE;
10441 VOS_STATUS status;
10442 v_MACADDR_t macFromNV[VOS_MAX_CONCURRENCY_PERSONA];
10443 v_U8_t macLoop;
10444
10445 /*If the NV is valid then get the macaddress from nv else get it from qcom_cfg.ini*/
10446 status = vos_nv_getValidity(VNV_FIELD_IMAGE, &itemIsValid);
10447 if(status != VOS_STATUS_SUCCESS)
10448 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080010449 hddLog(VOS_TRACE_LEVEL_ERROR," vos_nv_getValidity() failed");
Jeff Johnson295189b2012-06-20 16:38:30 -070010450 return VOS_STATUS_E_FAILURE;
10451 }
10452
10453 if (itemIsValid == VOS_TRUE)
10454 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080010455 hddLog(VOS_TRACE_LEVEL_INFO_HIGH," Reading the Macaddress from NV");
Jeff Johnson295189b2012-06-20 16:38:30 -070010456 status = vos_nv_readMultiMacAddress((v_U8_t *)&macFromNV[0].bytes[0],
10457 VOS_MAX_CONCURRENCY_PERSONA);
10458 if(status != VOS_STATUS_SUCCESS)
10459 {
10460 /* Get MAC from NV fail, not update CFG info
10461 * INI MAC value will be used for MAC setting */
Arif Hussain6d2a3322013-11-17 19:50:10 -080010462 hddLog(VOS_TRACE_LEVEL_ERROR," vos_nv_readMacAddress() failed");
Jeff Johnson295189b2012-06-20 16:38:30 -070010463 return VOS_STATUS_E_FAILURE;
10464 }
10465
10466 /* If first MAC is not valid, treat all others are not valid
10467 * Then all MACs will be got from ini file */
10468 if(vos_is_macaddr_zero(&macFromNV[0]))
10469 {
10470 /* MAC address in NV file is not configured yet */
10471 hddLog(VOS_TRACE_LEVEL_WARN, "Invalid MAC in NV file");
10472 return VOS_STATUS_E_INVAL;
10473 }
10474
10475 /* Get MAC address from NV, update CFG info */
10476 for(macLoop = 0; macLoop < VOS_MAX_CONCURRENCY_PERSONA; macLoop++)
10477 {
10478 if(vos_is_macaddr_zero(&macFromNV[macLoop]))
10479 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010480 hddLog(VOS_TRACE_LEVEL_ERROR,"not valid MAC from NV for %d", macLoop);
Jeff Johnson295189b2012-06-20 16:38:30 -070010481 /* This MAC is not valid, skip it
10482 * This MAC will be got from ini file */
10483 }
10484 else
10485 {
10486 vos_mem_copy((v_U8_t *)&pHddCtx->cfg_ini->intfMacAddr[macLoop].bytes[0],
10487 (v_U8_t *)&macFromNV[macLoop].bytes[0],
10488 VOS_MAC_ADDR_SIZE);
10489 }
10490 }
10491 }
10492 else
10493 {
10494 hddLog(VOS_TRACE_LEVEL_ERROR, "NV ITEM, MAC Not valid");
10495 return VOS_STATUS_E_FAILURE;
10496 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010497
Jeff Johnson295189b2012-06-20 16:38:30 -070010498
10499 return VOS_STATUS_SUCCESS;
10500}
10501
10502/**---------------------------------------------------------------------------
10503
10504 \brief hdd_post_voss_start_config() - HDD post voss start config helper
10505
10506 \param - pAdapter - Pointer to the HDD
10507
10508 \return - None
10509
10510 --------------------------------------------------------------------------*/
10511VOS_STATUS hdd_post_voss_start_config(hdd_context_t* pHddCtx)
10512{
10513 eHalStatus halStatus;
10514 v_U32_t listenInterval;
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +053010515 tANI_U32 ignoreDtim;
Jeff Johnson295189b2012-06-20 16:38:30 -070010516
Jeff Johnson295189b2012-06-20 16:38:30 -070010517
10518 // Send ready indication to the HDD. This will kick off the MAC
10519 // into a 'running' state and should kick off an initial scan.
10520 halStatus = sme_HDDReadyInd( pHddCtx->hHal );
10521 if ( !HAL_STATUS_SUCCESS( halStatus ) )
10522 {
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +053010523 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: sme_HDDReadyInd() failed with status "
Jeff Johnson295189b2012-06-20 16:38:30 -070010524 "code %08d [x%08x]",__func__, halStatus, halStatus );
10525 return VOS_STATUS_E_FAILURE;
10526 }
10527
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +053010528 // Set default LI and ignoreDtim into HDD context,
Jeff Johnson295189b2012-06-20 16:38:30 -070010529 // otherwise under some race condition, HDD will set 0 LI value into RIVA,
10530 // And RIVA will crash
10531 wlan_cfgGetInt(pHddCtx->hHal, WNI_CFG_LISTEN_INTERVAL, &listenInterval);
10532 pHddCtx->hdd_actual_LI_value = listenInterval;
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +053010533 wlan_cfgGetInt(pHddCtx->hHal, WNI_CFG_IGNORE_DTIM, &ignoreDtim);
10534 pHddCtx->hdd_actual_ignore_DTIM_value = ignoreDtim;
10535
10536
Jeff Johnson295189b2012-06-20 16:38:30 -070010537 return VOS_STATUS_SUCCESS;
10538}
10539
Jeff Johnson295189b2012-06-20 16:38:30 -070010540/* wake lock APIs for HDD */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053010541void hdd_prevent_suspend(uint32_t reason)
Jeff Johnson295189b2012-06-20 16:38:30 -070010542{
Sushant Kaushik83392fa2015-05-05 17:44:40 +053010543
10544 vos_wake_lock_acquire(&wlan_wake_lock, reason);
10545
Jeff Johnson295189b2012-06-20 16:38:30 -070010546}
10547
Sushant Kaushik83392fa2015-05-05 17:44:40 +053010548void hdd_allow_suspend(uint32_t reason)
Jeff Johnson295189b2012-06-20 16:38:30 -070010549{
Sushant Kaushik83392fa2015-05-05 17:44:40 +053010550
10551 vos_wake_lock_release(&wlan_wake_lock, reason);
10552
Jeff Johnson295189b2012-06-20 16:38:30 -070010553}
10554
Sushant Kaushik83392fa2015-05-05 17:44:40 +053010555void hdd_prevent_suspend_timeout(v_U32_t timeout, uint32_t reason)
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -070010556{
Sushant Kaushik83392fa2015-05-05 17:44:40 +053010557
10558 vos_wake_lock_timeout_release(&wlan_wake_lock, timeout,
10559 reason);
10560
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -070010561}
10562
Jeff Johnson295189b2012-06-20 16:38:30 -070010563/**---------------------------------------------------------------------------
10564
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -070010565 \brief hdd_exchange_version_and_caps() - HDD function to exchange version and capability
10566 information between Host and Riva
10567
10568 This function gets reported version of FW
10569 It also finds the version of Riva headers used to compile the host
10570 It compares the above two and prints a warning if they are different
10571 It gets the SW and HW version string
10572 Finally, it exchanges capabilities between host and Riva i.e. host and riva exchange a msg
10573 indicating the features they support through a bitmap
10574
10575 \param - pHddCtx - Pointer to HDD context
10576
10577 \return - void
10578
10579 --------------------------------------------------------------------------*/
10580
10581void hdd_exchange_version_and_caps(hdd_context_t *pHddCtx)
10582{
10583
10584 tSirVersionType versionCompiled;
10585 tSirVersionType versionReported;
10586 tSirVersionString versionString;
10587 tANI_U8 fwFeatCapsMsgSupported = 0;
10588 VOS_STATUS vstatus;
10589
Mingcheng Zhu87f22fc2014-01-30 19:23:32 -080010590 memset(&versionCompiled, 0, sizeof(versionCompiled));
10591 memset(&versionReported, 0, sizeof(versionReported));
10592
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -070010593 /* retrieve and display WCNSS version information */
10594 do {
10595
10596 vstatus = sme_GetWcnssWlanCompiledVersion(pHddCtx->hHal,
10597 &versionCompiled);
10598 if (!VOS_IS_STATUS_SUCCESS(vstatus))
10599 {
10600 hddLog(VOS_TRACE_LEVEL_FATAL,
10601 "%s: unable to retrieve WCNSS WLAN compiled version",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070010602 __func__);
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -070010603 break;
10604 }
10605
10606 vstatus = sme_GetWcnssWlanReportedVersion(pHddCtx->hHal,
10607 &versionReported);
10608 if (!VOS_IS_STATUS_SUCCESS(vstatus))
10609 {
10610 hddLog(VOS_TRACE_LEVEL_FATAL,
10611 "%s: unable to retrieve WCNSS WLAN reported version",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070010612 __func__);
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -070010613 break;
10614 }
10615
10616 if ((versionCompiled.major != versionReported.major) ||
10617 (versionCompiled.minor != versionReported.minor) ||
10618 (versionCompiled.version != versionReported.version) ||
10619 (versionCompiled.revision != versionReported.revision))
10620 {
10621 pr_err("%s: WCNSS WLAN Version %u.%u.%u.%u, "
10622 "Host expected %u.%u.%u.%u\n",
10623 WLAN_MODULE_NAME,
10624 (int)versionReported.major,
10625 (int)versionReported.minor,
10626 (int)versionReported.version,
10627 (int)versionReported.revision,
10628 (int)versionCompiled.major,
10629 (int)versionCompiled.minor,
10630 (int)versionCompiled.version,
10631 (int)versionCompiled.revision);
10632 }
10633 else
10634 {
10635 pr_info("%s: WCNSS WLAN version %u.%u.%u.%u\n",
10636 WLAN_MODULE_NAME,
10637 (int)versionReported.major,
10638 (int)versionReported.minor,
10639 (int)versionReported.version,
10640 (int)versionReported.revision);
10641 }
10642
10643 vstatus = sme_GetWcnssSoftwareVersion(pHddCtx->hHal,
10644 versionString,
10645 sizeof(versionString));
10646 if (!VOS_IS_STATUS_SUCCESS(vstatus))
10647 {
10648 hddLog(VOS_TRACE_LEVEL_FATAL,
10649 "%s: unable to retrieve WCNSS software version string",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070010650 __func__);
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -070010651 break;
10652 }
10653
10654 pr_info("%s: WCNSS software version %s\n",
10655 WLAN_MODULE_NAME, versionString);
Sushant Kaushik084f6592015-09-10 13:11:56 +053010656 vos_mem_copy(pHddCtx->fw_Version, versionString, sizeof(versionString));
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -070010657
10658 vstatus = sme_GetWcnssHardwareVersion(pHddCtx->hHal,
10659 versionString,
10660 sizeof(versionString));
10661 if (!VOS_IS_STATUS_SUCCESS(vstatus))
10662 {
10663 hddLog(VOS_TRACE_LEVEL_FATAL,
10664 "%s: unable to retrieve WCNSS hardware version string",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070010665 __func__);
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -070010666 break;
10667 }
10668
10669 pr_info("%s: WCNSS hardware version %s\n",
10670 WLAN_MODULE_NAME, versionString);
10671
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -070010672 /* 1.Check if FW version is greater than 0.1.1.0. Only then send host-FW capability exchange message
10673 2.Host-FW capability exchange message is only present on riva 1.1 so
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -070010674 send the message only if it the riva is 1.1
10675 minor numbers for different riva branches:
10676 0 -> (1.0)Mainline Build
10677 1 -> (1.1)Mainline Build
10678 2->(1.04) Stability Build
10679 */
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -070010680 if (((versionReported.major>0) || (versionReported.minor>1) ||
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -070010681 ((versionReported.minor>=1) && (versionReported.version>=1)))
10682 && ((versionReported.major == 1) && (versionReported.minor >= 1)))
10683 fwFeatCapsMsgSupported = 1;
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -070010684
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -070010685 if (fwFeatCapsMsgSupported)
Yathish9f22e662012-12-10 14:21:35 -080010686 {
10687#ifdef WLAN_ACTIVEMODE_OFFLOAD_FEATURE
10688 if(!pHddCtx->cfg_ini->fEnableActiveModeOffload)
10689 sme_disableFeatureCapablity(WLANACTIVE_OFFLOAD);
10690#endif
Ravi Joshid2ca7c42013-07-23 08:37:49 -070010691 /* Indicate if IBSS heartbeat monitoring needs to be offloaded */
10692 if (!pHddCtx->cfg_ini->enableIbssHeartBeatOffload)
10693 {
10694 sme_disableFeatureCapablity(IBSS_HEARTBEAT_OFFLOAD);
10695 }
10696
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -070010697 sme_featureCapsExchange(pHddCtx->hHal);
Yathish9f22e662012-12-10 14:21:35 -080010698 }
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -070010699
10700 } while (0);
10701
10702}
Neelansh Mittaledafed22014-09-04 18:54:39 +053010703void wlan_hdd_send_svc_nlink_msg(int type, void *data, int len)
10704{
10705 struct sk_buff *skb;
10706 struct nlmsghdr *nlh;
10707 tAniMsgHdr *ani_hdr;
Hanumantha Reddy Pothulacf2c7ea2015-04-27 14:50:47 +053010708 int flags = GFP_KERNEL;
Bhargav shah23c94942015-10-13 12:48:35 +053010709 void *nl_data = NULL;
Neelansh Mittaledafed22014-09-04 18:54:39 +053010710
Hanumantha Reddy Pothulacf2c7ea2015-04-27 14:50:47 +053010711 if (in_interrupt() || irqs_disabled() || in_atomic())
10712 flags = GFP_ATOMIC;
10713
10714 skb = alloc_skb(NLMSG_SPACE(WLAN_NL_MAX_PAYLOAD), flags);
Neelansh Mittaledafed22014-09-04 18:54:39 +053010715
10716 if(skb == NULL) {
10717 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10718 "%s: alloc_skb failed", __func__);
10719 return;
10720 }
10721
10722 nlh = (struct nlmsghdr *)skb->data;
10723 nlh->nlmsg_pid = 0; /* from kernel */
10724 nlh->nlmsg_flags = 0;
10725 nlh->nlmsg_seq = 0;
10726 nlh->nlmsg_type = WLAN_NL_MSG_SVC;
10727
10728 ani_hdr = NLMSG_DATA(nlh);
10729 ani_hdr->type = type;
10730
10731 switch(type) {
10732 case WLAN_SVC_SAP_RESTART_IND:
10733 ani_hdr->length = 0;
10734 nlh->nlmsg_len = NLMSG_LENGTH((sizeof(tAniMsgHdr)));
10735 skb_put(skb, NLMSG_SPACE(sizeof(tAniMsgHdr)));
10736 break;
Bhargav Shahd0715912015-10-01 18:17:37 +053010737 case WLAN_SVC_WLAN_TP_IND:
10738 ani_hdr->length = len;
10739 nlh->nlmsg_len = NLMSG_LENGTH((sizeof(tAniMsgHdr)
10740 + len));
10741 nl_data = (char *)ani_hdr + sizeof(tAniMsgHdr);
10742 memcpy(nl_data, data, len);
10743 skb_put(skb, NLMSG_SPACE(sizeof(tAniMsgHdr) + len));
10744 break;
Bhargav shah23c94942015-10-13 12:48:35 +053010745 case WLAN_MSG_RPS_ENABLE_IND:
10746 ani_hdr->length = len;
10747 nlh->nlmsg_len = NLMSG_LENGTH((sizeof(tAniMsgHdr) + len));
10748 nl_data = (char *)ani_hdr + sizeof(tAniMsgHdr);
10749 memcpy(nl_data, data, len);
10750 skb_put(skb, NLMSG_SPACE(sizeof(tAniMsgHdr) + len));
10751 break;
Neelansh Mittaledafed22014-09-04 18:54:39 +053010752 default:
10753 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10754 "Attempt to send unknown nlink message %d", type);
10755 kfree_skb(skb);
10756 return;
10757 }
10758
10759 nl_srv_bcast(skb);
10760
10761 return;
10762}
10763
Bhargav Shahd0715912015-10-01 18:17:37 +053010764/**
10765 * hdd_request_tcp_delack() - Find the Delack value based on RX packet
10766 * @pHddCtx: Valid Global HDD context pointer
10767 * @rx_packets: Number of RX packet in perticular time
10768 *
10769 * Based on the RX packet this function calculate next value of tcp delack.
10770 * This function compare rx packet value to high and low threshold limit.
10771 *
10772 * Return: void
10773 */
10774void hdd_request_tcp_delack(hdd_context_t *pHddCtx, uint64_t rx_packets)
10775{
10776 /* average of rx_packets and prev_rx is taken so that
10777 bus width doesnot fluctuate much */
10778 uint64_t temp_rx = (rx_packets + pHddCtx->prev_rx)/2;
10779 TP_IND_TYPE next_rx_level = pHddCtx->cur_rx_level;
Neelansh Mittaledafed22014-09-04 18:54:39 +053010780
Bhargav Shahd0715912015-10-01 18:17:37 +053010781 pHddCtx->prev_rx = rx_packets;
10782 if (temp_rx > pHddCtx->cfg_ini->tcpDelAckThresholdHigh)
10783 next_rx_level = TP_IND_HIGH;
10784 else if (temp_rx <= pHddCtx->cfg_ini->tcpDelAckThresholdLow)
10785 next_rx_level = TP_IND_LOW;
10786
10787 hdd_set_delack_value(pHddCtx, next_rx_level);
10788}
10789
10790#define HDD_BW_GET_DIFF(x, y) ((x) >= (y) ? (x) - (y) : (ULONG_MAX - (y) + (x)))
10791
10792/**
10793 * hdd_tcp_delack_compute_function() - get link status
10794 * @priv: Valid Global HDD context pointer
10795 *
10796 * This function find number of RX packet during timer life span.
10797 * It request tcp delack with number of RX packet and re-configure delack timer
10798 * for tcpDelAckComputeInterval timer interval.
10799 *
10800 * Return: void
10801 */
10802void hdd_tcp_delack_compute_function(void *priv)
10803{
10804 hdd_context_t *pHddCtx = (hdd_context_t *)priv;
10805 hdd_adapter_t *pAdapter = NULL;
10806 v_U32_t rx_packets = 0;
10807 hdd_adapter_list_node_t *pAdapterNode = NULL;
10808 VOS_STATUS status = 0;
10809
10810 for (status = hdd_get_front_adapter(pHddCtx, &pAdapterNode);
10811 NULL != pAdapterNode && VOS_STATUS_SUCCESS == status;
10812 status = hdd_get_next_adapter(pHddCtx, pAdapterNode, &pAdapterNode)) {
10813 if ((pAdapter = pAdapterNode->pAdapter) == NULL)
10814 continue;
10815
10816 rx_packets += HDD_BW_GET_DIFF(pAdapter->stats.rx_packets,
10817 pAdapter->prev_rx_packets);
10818 pAdapter->prev_rx_packets = pAdapter->stats.rx_packets;
10819 }
10820
10821 hdd_request_tcp_delack(pHddCtx, rx_packets);
10822
10823 vos_timer_start(&pHddCtx->delack_timer,
10824 pHddCtx->cfg_ini->tcpDelAckComputeInterval);
10825}
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -070010826
10827/**---------------------------------------------------------------------------
10828
Gopichand Nakkalafce506f2013-07-03 23:55:16 +053010829 \brief hdd_is_5g_supported() - HDD function to know if hardware supports 5GHz
10830
10831 \param - pHddCtx - Pointer to the hdd context
10832
10833 \return - true if hardware supports 5GHz
10834
10835 --------------------------------------------------------------------------*/
Vinay Krishna Erannafacf5e22014-02-24 13:16:25 +053010836boolean hdd_is_5g_supported(hdd_context_t * pHddCtx)
Gopichand Nakkalafce506f2013-07-03 23:55:16 +053010837{
10838 /* If wcnss_wlan_iris_xo_mode() returns WCNSS_XO_48MHZ(1);
10839 * then hardware support 5Ghz.
10840 */
10841 if (WCNSS_XO_48MHZ == wcnss_wlan_iris_xo_mode())
10842 {
Ratheesh S P36dbc932015-08-07 14:28:57 +053010843 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Hardware supports 5Ghz", __func__);
Gopichand Nakkalafce506f2013-07-03 23:55:16 +053010844 return true;
10845 }
10846 else
10847 {
Ratheesh S P36dbc932015-08-07 14:28:57 +053010848 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Hardware doesn't supports 5Ghz",
Gopichand Nakkalafce506f2013-07-03 23:55:16 +053010849 __func__);
10850 return false;
10851 }
10852}
10853
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +053010854/**---------------------------------------------------------------------------
10855
10856 \brief hdd_generate_iface_mac_addr_auto() - HDD Mac Interface Auto
10857 generate function
10858
10859 This is generate the random mac address for WLAN interface
10860
10861 \param - pHddCtx - Pointer to HDD context
10862 idx - Start interface index to get auto
10863 generated mac addr.
10864 mac_addr - Mac address
10865
10866 \return - 0 for success, < 0 for failure
10867
10868 --------------------------------------------------------------------------*/
10869
10870static int hdd_generate_iface_mac_addr_auto(hdd_context_t *pHddCtx,
10871 int idx, v_MACADDR_t mac_addr)
10872{
10873 int i;
10874 unsigned int serialno;
10875 serialno = wcnss_get_serial_number();
10876
10877 if (0 != serialno)
10878 {
10879 /* MAC address has 3 bytes of OUI so we have a maximum of 3
10880 bytes of the serial number that can be used to generate
10881 the other 3 bytes of the MAC address. Mask off all but
10882 the lower 3 bytes (this will also make sure we don't
10883 overflow in the next step) */
10884 serialno &= 0x00FFFFFF;
10885
10886 /* we need a unique address for each session */
10887 serialno *= VOS_MAX_CONCURRENCY_PERSONA;
10888
10889 /* autogen other Mac addresses */
10890 for (i = idx; i < VOS_MAX_CONCURRENCY_PERSONA; i++)
10891 {
10892 /* start with the entire default address */
10893 pHddCtx->cfg_ini->intfMacAddr[i] = mac_addr;
10894 /* then replace the lower 3 bytes */
10895 pHddCtx->cfg_ini->intfMacAddr[i].bytes[3] = (serialno >> 16) & 0xFF;
10896 pHddCtx->cfg_ini->intfMacAddr[i].bytes[4] = (serialno >> 8) & 0xFF;
10897 pHddCtx->cfg_ini->intfMacAddr[i].bytes[5] = serialno & 0xFF;
10898
10899 serialno++;
10900 hddLog(VOS_TRACE_LEVEL_ERROR,
10901 "%s: Derived Mac Addr: "
10902 MAC_ADDRESS_STR, __func__,
10903 MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[i].bytes));
10904 }
10905
10906 }
10907 else
10908 {
10909 hddLog(LOGE, FL("Failed to Get Serial NO"));
10910 return -1;
10911 }
10912 return 0;
10913}
Gopichand Nakkalafce506f2013-07-03 23:55:16 +053010914
Katya Nigame7b69a82015-04-28 15:24:06 +053010915int wlan_hdd_mon_open(hdd_context_t *pHddCtx)
10916{
10917 VOS_STATUS status;
10918 v_CONTEXT_t pVosContext= NULL;
10919 hdd_adapter_t *pAdapter= NULL;
10920
10921 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
10922
10923 if (NULL == pVosContext)
10924 {
10925 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10926 "%s: Trying to open VOSS without a PreOpen", __func__);
10927 VOS_ASSERT(0);
10928 return VOS_STATUS_E_FAILURE;
10929 }
10930
10931 status = vos_nv_open();
10932 if (!VOS_IS_STATUS_SUCCESS(status))
10933 {
10934 /* NV module cannot be initialized */
10935 hddLog( VOS_TRACE_LEVEL_FATAL,
10936 "%s: vos_nv_open failed", __func__);
10937 return VOS_STATUS_E_FAILURE;
10938 }
10939
10940 status = vos_init_wiphy_from_nv_bin();
10941 if (!VOS_IS_STATUS_SUCCESS(status))
10942 {
10943 /* NV module cannot be initialized */
10944 hddLog( VOS_TRACE_LEVEL_FATAL,
10945 "%s: vos_init_wiphy failed", __func__);
10946 goto err_vos_nv_close;
10947 }
10948
10949 status = vos_open( &pVosContext, pHddCtx->parent_dev);
10950 if ( !VOS_IS_STATUS_SUCCESS( status ))
10951 {
10952 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: vos_open failed", __func__);
10953 goto err_vos_nv_close;
10954 }
10955
10956 status = vos_mon_start( pVosContext );
10957 if ( !VOS_IS_STATUS_SUCCESS( status ) )
10958 {
10959 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: vos_start failed",__func__);
10960 goto err_vosclose;
10961 }
10962
10963 WLANTL_SetMonRxCbk( pVosContext, hdd_rx_packet_monitor_cbk );
10964 WDA_featureCapsExchange(pVosContext);
10965 wcnss_wlan_set_drvdata(pHddCtx->parent_dev, pHddCtx);
10966
10967 pAdapter = hdd_open_adapter( pHddCtx, WLAN_HDD_MONITOR, "wlan%d",
10968 wlan_hdd_get_intf_addr(pHddCtx), FALSE );
10969 if( pAdapter == NULL )
10970 {
10971 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: hdd_open_adapter failed", __func__);
10972 goto err_close_adapter;
10973 }
10974
10975 //Initialize the nlink service
10976 if(nl_srv_init() != 0)
10977 {
10978 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: nl_srv_init failed", __func__);
10979 goto err_close_adapter;
10980 }
10981 return VOS_STATUS_SUCCESS;
10982
10983err_close_adapter:
10984 hdd_close_all_adapters( pHddCtx );
10985 vos_mon_stop( pVosContext );
10986err_vosclose:
10987 status = vos_sched_close( pVosContext );
10988 if (!VOS_IS_STATUS_SUCCESS(status)) {
10989 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
10990 "%s: Failed to close VOSS Scheduler", __func__);
10991 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( status ) );
10992 }
10993 vos_close(pVosContext );
10994
10995err_vos_nv_close:
10996 vos_nv_close();
10997
10998return status;
10999}
Gopichand Nakkalafce506f2013-07-03 23:55:16 +053011000/**---------------------------------------------------------------------------
11001
Mihir Shetefc7ff5b2014-01-27 11:30:05 +053011002 \brief hdd_11d_scan_done - callback to be executed when 11d scan is
11003 completed to flush out the scan results
11004
11005 11d scan is done during driver load and is a passive scan on all
11006 channels supported by the device, 11d scans may find some APs on
11007 frequencies which are forbidden to be used in the regulatory domain
11008 the device is operating in. If these APs are notified to the supplicant
11009 it may try to connect to these APs, thus flush out all the scan results
11010 which are present in SME after 11d scan is done.
11011
11012 \return - eHalStatus
11013
11014 --------------------------------------------------------------------------*/
11015static eHalStatus hdd_11d_scan_done(tHalHandle halHandle, void *pContext,
11016 tANI_U32 scanId, eCsrScanStatus status)
11017{
11018 ENTER();
11019
11020 sme_ScanFlushResult(halHandle, 0);
11021
11022 EXIT();
11023
11024 return eHAL_STATUS_SUCCESS;
11025}
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053011026/**---------------------------------------------------------------------------
11027
11028 \brief hdd_init_frame_logging_done - callback to be executed when mgmt frame
11029 logging is completed successfully.
11030
11031 \return - None
11032
11033 --------------------------------------------------------------------------*/
c_manjeecfd1efb2015-09-25 19:32:34 +053011034void hdd_init_frame_logging_done(void *fwlogInitCbContext, tAniLoggingInitRsp *pRsp)
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053011035{
Siddharth Bhald1be97f2015-05-27 22:39:59 +053011036 hdd_context_t* pHddCtx = (hdd_context_t*)fwlogInitCbContext;
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053011037
11038 if (NULL == pHddCtx)
11039 {
11040 hddLog(VOS_TRACE_LEVEL_ERROR,
11041 "%s: HDD context is NULL",__func__);
11042 return;
11043 }
11044
c_manjeecfd1efb2015-09-25 19:32:34 +053011045 if ((pRsp->status == VOS_STATUS_SUCCESS) &&
Mahesh A Saptasagarfabb1a02015-06-29 12:17:04 +053011046 (TRUE == pHddCtx->cfg_ini->enableMgmtLogging))
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053011047 {
11048 hddLog(VOS_TRACE_LEVEL_INFO, FL("Mgmt Frame Logging init successful"));
11049 pHddCtx->mgmt_frame_logging = TRUE;
11050 }
11051 else
11052 {
11053 hddLog(VOS_TRACE_LEVEL_INFO, FL("Mgmt Frame Logging init not success"));
11054 pHddCtx->mgmt_frame_logging = FALSE;
c_manjeecfd1efb2015-09-25 19:32:34 +053011055 return;
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053011056 }
11057
c_manjeecfd1efb2015-09-25 19:32:34 +053011058 /*Check feature supported by FW*/
11059 if(TRUE == sme_IsFeatureSupportedByFW(MEMORY_DUMP_SUPPORTED))
11060 {
11061 //Store fwr mem dump size given by firmware.
11062 wlan_store_fwr_mem_dump_size(pRsp->fw_mem_dump_max_size);
11063 }
11064 else
11065 {
11066 wlan_store_fwr_mem_dump_size(0);
11067 }
11068
11069
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053011070}
11071/**---------------------------------------------------------------------------
11072
11073 \brief hdd_init_frame_logging - function to initialize frame logging.
11074 Currently only Mgmt Frames are logged in both TX
11075 and Rx direction and are sent to userspace
11076 application using logger thread when queried.
11077
11078 \return - None
11079
11080 --------------------------------------------------------------------------*/
Siddharth Bhald1be97f2015-05-27 22:39:59 +053011081void hdd_init_frame_logging(hdd_context_t* pHddCtx)
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053011082{
11083 eHalStatus halStatus = eHAL_STATUS_FAILURE;
Siddharth Bhald1be97f2015-05-27 22:39:59 +053011084 tpSirFWLoggingInitParam wlanFWLoggingInitParam;
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053011085
Siddharth Bhald1be97f2015-05-27 22:39:59 +053011086 if (TRUE != sme_IsFeatureSupportedByFW(MGMT_FRAME_LOGGING) &&
11087 TRUE != sme_IsFeatureSupportedByFW(LOGGING_ENHANCEMENT))
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053011088 {
11089 hddLog(VOS_TRACE_LEVEL_INFO, FL("MGMT_FRAME_LOGGING not supp by FW"));
11090 return;
11091 }
11092
Siddharth Bhald1be97f2015-05-27 22:39:59 +053011093 wlanFWLoggingInitParam = vos_mem_malloc(sizeof(tSirFWLoggingInitParam));
11094 if(NULL == wlanFWLoggingInitParam)
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053011095 {
11096 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: vos_mem_alloc failed ", __func__);
11097 return;
11098 }
11099
Siddharth Bhald1be97f2015-05-27 22:39:59 +053011100 vos_mem_set(wlanFWLoggingInitParam, sizeof(tSirFWLoggingInitParam), 0);
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053011101
c_manjeecfd1efb2015-09-25 19:32:34 +053011102 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Configuring %s %s %s %s Logging",__func__,
Siddharth Bhald1be97f2015-05-27 22:39:59 +053011103 pHddCtx->cfg_ini->enableFWLogging?"FW Log,":"",
11104 pHddCtx->cfg_ini->enableContFWLogging ? "Cont FW log,":"",
c_manjeecfd1efb2015-09-25 19:32:34 +053011105 pHddCtx->cfg_ini->enableMgmtLogging ? "Mgmt Pkt Log":"",
11106 pHddCtx->cfg_ini->enableFwrMemDump ? "Fw Mem dump":"");
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053011107
Siddharth Bhald1be97f2015-05-27 22:39:59 +053011108 if (pHddCtx->cfg_ini->enableFWLogging ||
11109 pHddCtx->cfg_ini->enableContFWLogging)
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053011110 {
Siddharth Bhald1be97f2015-05-27 22:39:59 +053011111 wlanFWLoggingInitParam->enableFlag |= WLAN_QXDM_LOG_EN;
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053011112 }
11113
Sushant Kaushik46804902015-07-08 14:46:03 +053011114 if (pHddCtx->cfg_ini->enableMgmtLogging)
11115 {
11116 wlanFWLoggingInitParam->enableFlag |= WLAN_FRAME_LOG_EN;
11117 }
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053011118 if (pHddCtx->cfg_ini->enableBMUHWtracing)
11119 {
Siddharth Bhald1be97f2015-05-27 22:39:59 +053011120 wlanFWLoggingInitParam->enableFlag |= WLAN_BMUHW_TRACE_LOG_EN;
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053011121 }
c_manjeecfd1efb2015-09-25 19:32:34 +053011122 if(pHddCtx->cfg_ini->enableFwrMemDump &&
11123 (TRUE == sme_IsFeatureSupportedByFW(MEMORY_DUMP_SUPPORTED)))
11124 {
11125 wlanFWLoggingInitParam->enableFlag |= WLAN_FW_MEM_DUMP_EN;
11126 }
11127 if( wlanFWLoggingInitParam->enableFlag == 0 )
11128 {
11129 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Logging not enabled", __func__);
11130 return;
11131 }
Siddharth Bhald1be97f2015-05-27 22:39:59 +053011132 wlanFWLoggingInitParam->frameType = WLAN_FRAME_LOGGING_FRAMETYPE_MGMT;
11133 wlanFWLoggingInitParam->frameSize = WLAN_MGMT_LOGGING_FRAMESIZE_128BYTES;
11134 wlanFWLoggingInitParam->bufferMode = WLAN_FRAME_LOGGING_BUFFERMODE_CIRCULAR;
11135 wlanFWLoggingInitParam->continuousFrameLogging =
11136 pHddCtx->cfg_ini->enableContFWLogging;
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053011137
Siddharth Bhald1be97f2015-05-27 22:39:59 +053011138 wlanFWLoggingInitParam->enableFlag &= ~WLAN_DPU_TXP_LOG_EN;
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053011139
Siddharth Bhald1be97f2015-05-27 22:39:59 +053011140 wlanFWLoggingInitParam->minLogBufferSize =
11141 pHddCtx->cfg_ini->minLoggingBufferSize;
11142 wlanFWLoggingInitParam->maxLogBufferSize =
11143 pHddCtx->cfg_ini->maxLoggingBufferSize;
11144 wlanFWLoggingInitParam->fwlogInitCallback = hdd_init_frame_logging_done;
11145 wlanFWLoggingInitParam->fwlogInitCbContext= pHddCtx;
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053011146
Siddharth Bhald1be97f2015-05-27 22:39:59 +053011147 halStatus = sme_InitMgmtFrameLogging(pHddCtx->hHal, wlanFWLoggingInitParam);
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053011148
11149 if (eHAL_STATUS_SUCCESS != halStatus)
11150 {
Siddharth Bhald1be97f2015-05-27 22:39:59 +053011151 vos_mem_free(wlanFWLoggingInitParam);
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053011152 }
11153
11154 return;
11155}
Mihir Shetefc7ff5b2014-01-27 11:30:05 +053011156
Bhargav shah23c94942015-10-13 12:48:35 +053011157static void hdd_dp_util_send_rps_ind(hdd_context_t *hdd_ctxt)
11158{
11159 hdd_adapter_t *adapter;
11160 hdd_adapter_list_node_t *adapter_node, *next;
11161 VOS_STATUS status = VOS_STATUS_SUCCESS;
11162 struct wlan_rps_data rps_data;
11163 int count;
11164
11165 if(!hdd_ctxt->cfg_ini->rps_mask)
11166 {
11167 return;
11168 }
11169
11170 for (count=0; count < WLAN_SVC_IFACE_NUM_QUEUES; count++)
11171 {
11172 rps_data.cpu_map[count] = hdd_ctxt->cfg_ini->rps_mask;
11173 }
11174
11175 rps_data.num_queues = WLAN_SVC_IFACE_NUM_QUEUES;
11176
11177 hddLog(LOG1, FL("0x%x 0x%x 0x%x 0x%x 0x%x 0x%x"),
11178 rps_data.cpu_map[0], rps_data.cpu_map[1],rps_data.cpu_map[2],
11179 rps_data.cpu_map[3], rps_data.cpu_map[4], rps_data.cpu_map[5]);
11180
11181 status = hdd_get_front_adapter (hdd_ctxt, &adapter_node);
11182
11183 while (NULL != adapter_node && VOS_STATUS_SUCCESS == status)
11184 {
11185 adapter = adapter_node->pAdapter;
11186 if (NULL != adapter) {
11187 strlcpy(rps_data.ifname, adapter->dev->name,
11188 sizeof(rps_data.ifname));
11189 wlan_hdd_send_svc_nlink_msg(WLAN_MSG_RPS_ENABLE_IND,
11190 (void *)&rps_data,sizeof(rps_data));
11191 }
11192 status = hdd_get_next_adapter (hdd_ctxt, adapter_node, &next);
11193 adapter_node = next;
11194 }
11195}
11196
Masti, Narayanraddi26378462016-01-05 18:20:28 +053011197void wlan_hdd_schedule_defer_scan(struct work_struct *work)
11198{
11199 scan_context_t *scan_ctx =
11200 container_of(work, scan_context_t, scan_work.work);
11201
11202 if (NULL == scan_ctx)
11203 {
11204 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11205 FL("scan_ctx is NULL"));
11206 return;
11207 }
11208
11209 if (unlikely(TDLS_CTX_MAGIC != scan_ctx->magic))
11210 return;
11211
11212 scan_ctx->attempt++;
11213
11214 wlan_hdd_cfg80211_scan(scan_ctx->wiphy,
11215#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
11216 scan_ctx->dev,
11217#endif
11218 scan_ctx->scan_request);
11219}
11220
11221int wlan_hdd_copy_defer_scan_context(hdd_context_t *pHddCtx,
11222 struct wiphy *wiphy,
11223#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
11224 struct net_device *dev,
11225#endif
11226 struct cfg80211_scan_request *request)
11227{
11228 scan_context_t *scan_ctx;
11229
11230 ENTER();
11231 if (0 != (wlan_hdd_validate_context(pHddCtx)))
11232 {
11233 return -1;
11234 }
11235
11236 scan_ctx = &pHddCtx->scan_ctxt;
11237
11238 scan_ctx->wiphy = wiphy;
11239#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
11240 scan_ctx->dev = dev;
11241#endif
11242
11243 scan_ctx->scan_request = request;
11244
11245 EXIT();
11246 return 0;
11247}
11248
11249void wlan_hdd_defer_scan_init_work(hdd_context_t *pHddCtx,
11250 struct wiphy *wiphy,
11251#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
11252 struct net_device *dev,
11253#endif
11254 struct cfg80211_scan_request *request,
11255 unsigned long delay)
11256{
11257 if (TDLS_CTX_MAGIC != pHddCtx->scan_ctxt.magic)
11258 {
11259#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
11260 wlan_hdd_copy_defer_scan_context(pHddCtx, wiphy, dev, request);
11261#else
11262 wlan_hdd_copy_defer_scan_context(pHddCtx, wiphy, request);
11263#endif
11264 pHddCtx->scan_ctxt.attempt = 0;
11265 pHddCtx->scan_ctxt.magic = TDLS_CTX_MAGIC;
11266 }
11267 schedule_delayed_work(&pHddCtx->scan_ctxt.scan_work, delay);
11268}
11269
11270void wlan_hdd_init_deinit_defer_scan_context(scan_context_t *scan_ctx)
11271{
11272 scan_ctx->magic = 0;
11273 scan_ctx->attempt = 0;
11274 scan_ctx->reject = 0;
11275 scan_ctx->scan_request = NULL;
11276
11277 return;
11278}
11279
Mihir Shetefc7ff5b2014-01-27 11:30:05 +053011280/**---------------------------------------------------------------------------
11281
Jeff Johnson295189b2012-06-20 16:38:30 -070011282 \brief hdd_wlan_startup() - HDD init function
11283
11284 This is the driver startup code executed once a WLAN device has been detected
11285
11286 \param - dev - Pointer to the underlying device
11287
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -080011288 \return - 0 for success, < 0 for failure
Jeff Johnson295189b2012-06-20 16:38:30 -070011289
11290 --------------------------------------------------------------------------*/
11291
11292int hdd_wlan_startup(struct device *dev )
11293{
11294 VOS_STATUS status;
11295 hdd_adapter_t *pAdapter = NULL;
Jeff Johnsone7245742012-09-05 17:12:55 -070011296 hdd_adapter_t *pP2pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070011297 hdd_context_t *pHddCtx = NULL;
11298 v_CONTEXT_t pVosContext= NULL;
11299#ifdef WLAN_BTAMP_FEATURE
11300 VOS_STATUS vStatus = VOS_STATUS_SUCCESS;
11301 WLANBAP_ConfigType btAmpConfig;
11302 hdd_config_t *pConfig;
11303#endif
11304 int ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070011305 struct wiphy *wiphy;
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +053011306 v_MACADDR_t mac_addr;
Jeff Johnson295189b2012-06-20 16:38:30 -070011307
11308 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -070011309 /*
11310 * cfg80211: wiphy allocation
11311 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +053011312 wiphy = wlan_hdd_cfg80211_wiphy_alloc(sizeof(hdd_context_t)) ;
Jeff Johnson295189b2012-06-20 16:38:30 -070011313
11314 if(wiphy == NULL)
11315 {
11316 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: cfg80211 init failed", __func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -080011317 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -070011318 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011319 pHddCtx = wiphy_priv(wiphy);
11320
Jeff Johnson295189b2012-06-20 16:38:30 -070011321 //Initialize the adapter context to zeros.
11322 vos_mem_zero(pHddCtx, sizeof( hdd_context_t ));
11323
Jeff Johnson295189b2012-06-20 16:38:30 -070011324 pHddCtx->wiphy = wiphy;
Sushant Kaushik83392fa2015-05-05 17:44:40 +053011325 hdd_prevent_suspend(WIFI_POWER_EVENT_WAKELOCK_DRIVER_INIT);
Mihir Shete18156292014-03-11 15:38:30 +053011326 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_LOAD_IN_PROGRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -070011327
11328 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, TRUE);
11329
Siddharth Bhalcd92b782015-06-29 12:25:40 +053011330 /* register for riva power on lock to platform driver
11331 * Locking power early to ensure FW doesn't reset by kernel while
11332 * host driver is busy initializing itself */
11333 if (req_riva_power_on_lock("wlan"))
11334 {
11335 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: req riva power on lock failed",
11336 __func__);
11337 goto err_free_hdd_context;
11338 }
11339
Jeff Johnson295189b2012-06-20 16:38:30 -070011340 /*Get vos context here bcoz vos_open requires it*/
11341 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
11342
Madan Mohan Koyyalamudi0b78e152012-11-28 15:46:51 -080011343 if(pVosContext == NULL)
11344 {
11345 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Failed vos_get_global_context",__func__);
11346 goto err_free_hdd_context;
11347 }
11348
Jeff Johnson295189b2012-06-20 16:38:30 -070011349 //Save the Global VOSS context in adapter context for future.
11350 pHddCtx->pvosContext = pVosContext;
11351
11352 //Save the adapter context in global context for future.
11353 ((VosContextType*)(pVosContext))->pHDDContext = (v_VOID_t*)pHddCtx;
11354
Jeff Johnson295189b2012-06-20 16:38:30 -070011355 pHddCtx->parent_dev = dev;
11356
11357 init_completion(&pHddCtx->full_pwr_comp_var);
11358 init_completion(&pHddCtx->standby_comp_var);
11359 init_completion(&pHddCtx->req_bmps_comp_var);
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070011360 init_completion(&pHddCtx->scan_info.scan_req_completion_event);
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -080011361 init_completion(&pHddCtx->scan_info.abortscan_event_var);
Kiet Lam46b8e4e2013-11-06 21:49:53 +053011362 init_completion(&pHddCtx->wiphy_channel_update_event);
Arun Kumar Khandavallie0b046d2014-03-01 21:54:25 +053011363 init_completion(&pHddCtx->ssr_comp_var);
Mahesh A Saptasagar67ab9222015-10-21 15:38:41 +053011364 init_completion(&pHddCtx->mc_sus_event_var);
11365 init_completion(&pHddCtx->tx_sus_event_var);
11366 init_completion(&pHddCtx->rx_sus_event_var);
11367
Amar Singhala49cbc52013-10-08 18:37:44 -070011368
mukul sharma4bd8d2e2015-08-13 20:33:25 +053011369 hdd_init_ll_stats_ctx(pHddCtx);
11370
Amar Singhala49cbc52013-10-08 18:37:44 -070011371#ifdef CONFIG_ENABLE_LINUX_REG
Amar Singhalfddc28c2013-09-05 13:03:40 -070011372 init_completion(&pHddCtx->linux_reg_req);
Amar Singhala49cbc52013-10-08 18:37:44 -070011373#else
11374 init_completion(&pHddCtx->driver_crda_req);
11375#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070011376
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +053011377#ifdef WLAN_FEATURE_EXTSCAN
11378 init_completion(&pHddCtx->ext_scan_context.response_event);
11379#endif /* WLAN_FEATURE_EXTSCAN */
11380
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053011381 spin_lock_init(&pHddCtx->schedScan_lock);
11382
Jeff Johnson295189b2012-06-20 16:38:30 -070011383 hdd_list_init( &pHddCtx->hddAdapters, MAX_NUMBER_OF_ADAPTERS );
11384
Padma, Santhosh Kumar9cd38332015-11-17 12:18:10 +053011385 vos_init_delayed_work(&pHddCtx->spoof_mac_addr_work,
11386 hdd_processSpoofMacAddrRequest);
11387
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053011388#ifdef FEATURE_WLAN_TDLS
11389 /* tdls_lock is initialized before an hdd_open_adapter ( which is
11390 * invoked by other instances also) to protect the concurrent
11391 * access for the Adapters by TDLS module.
11392 */
11393 mutex_init(&pHddCtx->tdls_lock);
11394#endif
Siddharth Bhal76972212014-10-15 16:22:51 +053011395 mutex_init(&pHddCtx->spoofMacAddr.macSpoofingLock);
Mukul Sharma1fd6efd2015-02-14 00:29:14 +053011396 mutex_init(&pHddCtx->wmmLock);
11397
Srinivas Girigowda8bf64cb2015-09-30 19:50:09 +053011398 hdd_init_offloaded_packets_ctx(pHddCtx);
Agarwal Ashish1f422872014-07-22 00:11:55 +053011399 /* By default Strict Regulatory For FCC should be false */
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053011400
Agarwal Ashish1f422872014-07-22 00:11:55 +053011401 pHddCtx->nEnableStrictRegulatoryForFCC = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070011402 // Load all config first as TL config is needed during vos_open
11403 pHddCtx->cfg_ini = (hdd_config_t*) kmalloc(sizeof(hdd_config_t), GFP_KERNEL);
11404 if(pHddCtx->cfg_ini == NULL)
11405 {
11406 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Failed kmalloc hdd_config_t",__func__);
11407 goto err_free_hdd_context;
11408 }
11409
11410 vos_mem_zero(pHddCtx->cfg_ini, sizeof( hdd_config_t ));
11411
11412 // Read and parse the qcom_cfg.ini file
11413 status = hdd_parse_config_ini( pHddCtx );
11414 if ( VOS_STATUS_SUCCESS != status )
11415 {
11416 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: error parsing %s",
11417 __func__, WLAN_INI_FILE);
11418 goto err_config;
11419 }
Arif Hussaind5218912013-12-05 01:10:55 -080011420#ifdef MEMORY_DEBUG
11421 if (pHddCtx->cfg_ini->IsMemoryDebugSupportEnabled)
11422 vos_mem_init();
11423
11424 hddLog(VOS_TRACE_LEVEL_INFO, "%s: gEnableMemoryDebug=%d",
11425 __func__, pHddCtx->cfg_ini->IsMemoryDebugSupportEnabled);
11426#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070011427
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +053011428 /* INI has been read, initialise the configuredMcastBcastFilter with
11429 * INI value as this will serve as the default value
11430 */
11431 pHddCtx->configuredMcastBcastFilter = pHddCtx->cfg_ini->mcastBcastFilterSetting;
11432 hddLog(VOS_TRACE_LEVEL_INFO, "Setting configuredMcastBcastFilter: %d",
11433 pHddCtx->cfg_ini->mcastBcastFilterSetting);
Gopichand Nakkalafce506f2013-07-03 23:55:16 +053011434
11435 if (false == hdd_is_5g_supported(pHddCtx))
11436 {
11437 //5Ghz is not supported.
11438 if (1 != pHddCtx->cfg_ini->nBandCapability)
11439 {
11440 hddLog(VOS_TRACE_LEVEL_INFO,
11441 "%s: Setting pHddCtx->cfg_ini->nBandCapability = 1", __func__);
11442 pHddCtx->cfg_ini->nBandCapability = 1;
11443 }
11444 }
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053011445
11446 /* If SNR Monitoring is enabled, FW has to parse all beacons
11447 * for calcaluting and storing the average SNR, so set Nth beacon
11448 * filter to 1 to enable FW to parse all the beaocons
11449 */
11450 if (1 == pHddCtx->cfg_ini->fEnableSNRMonitoring)
11451 {
11452 /* The log level is deliberately set to WARN as overriding
11453 * nthBeaconFilter to 1 will increase power cosumption and this
11454 * might just prove helpful to detect the power issue.
11455 */
11456 hddLog(VOS_TRACE_LEVEL_WARN,
11457 "%s: Setting pHddCtx->cfg_ini->nthBeaconFilter = 1", __func__);
11458 pHddCtx->cfg_ini->nthBeaconFilter = 1;
11459 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011460 /*
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +053011461 * cfg80211: Initialization ...
Jeff Johnson295189b2012-06-20 16:38:30 -070011462 */
Manjunathappa Prakasheec4ddf2014-01-13 18:23:51 -080011463 if (VOS_FTM_MODE != hdd_get_conparam())
Jeff Johnson295189b2012-06-20 16:38:30 -070011464 {
Manjunathappa Prakasheec4ddf2014-01-13 18:23:51 -080011465 if (0 < wlan_hdd_cfg80211_init(dev, wiphy, pHddCtx->cfg_ini))
11466 {
11467 hddLog(VOS_TRACE_LEVEL_FATAL,
11468 "%s: wlan_hdd_cfg80211_init return failure", __func__);
11469 goto err_config;
11470 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011471 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011472
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -080011473 // Update VOS trace levels based upon the cfg.ini
11474 hdd_vos_trace_enable(VOS_MODULE_ID_BAP,
11475 pHddCtx->cfg_ini->vosTraceEnableBAP);
11476 hdd_vos_trace_enable(VOS_MODULE_ID_TL,
11477 pHddCtx->cfg_ini->vosTraceEnableTL);
11478 hdd_vos_trace_enable(VOS_MODULE_ID_WDI,
11479 pHddCtx->cfg_ini->vosTraceEnableWDI);
11480 hdd_vos_trace_enable(VOS_MODULE_ID_HDD,
11481 pHddCtx->cfg_ini->vosTraceEnableHDD);
11482 hdd_vos_trace_enable(VOS_MODULE_ID_SME,
11483 pHddCtx->cfg_ini->vosTraceEnableSME);
11484 hdd_vos_trace_enable(VOS_MODULE_ID_PE,
11485 pHddCtx->cfg_ini->vosTraceEnablePE);
Katya Nigam70d68332013-09-16 16:49:45 +053011486 hdd_vos_trace_enable(VOS_MODULE_ID_PMC,
11487 pHddCtx->cfg_ini->vosTraceEnablePMC);
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -080011488 hdd_vos_trace_enable(VOS_MODULE_ID_WDA,
11489 pHddCtx->cfg_ini->vosTraceEnableWDA);
11490 hdd_vos_trace_enable(VOS_MODULE_ID_SYS,
11491 pHddCtx->cfg_ini->vosTraceEnableSYS);
11492 hdd_vos_trace_enable(VOS_MODULE_ID_VOSS,
11493 pHddCtx->cfg_ini->vosTraceEnableVOSS);
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -080011494 hdd_vos_trace_enable(VOS_MODULE_ID_SAP,
11495 pHddCtx->cfg_ini->vosTraceEnableSAP);
11496 hdd_vos_trace_enable(VOS_MODULE_ID_HDD_SOFTAP,
11497 pHddCtx->cfg_ini->vosTraceEnableHDDSAP);
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -080011498
Jeff Johnson295189b2012-06-20 16:38:30 -070011499 // Update WDI trace levels based upon the cfg.ini
11500 hdd_wdi_trace_enable(eWLAN_MODULE_DAL,
11501 pHddCtx->cfg_ini->wdiTraceEnableDAL);
11502 hdd_wdi_trace_enable(eWLAN_MODULE_DAL_CTRL,
11503 pHddCtx->cfg_ini->wdiTraceEnableCTL);
11504 hdd_wdi_trace_enable(eWLAN_MODULE_DAL_DATA,
11505 pHddCtx->cfg_ini->wdiTraceEnableDAT);
11506 hdd_wdi_trace_enable(eWLAN_MODULE_PAL,
11507 pHddCtx->cfg_ini->wdiTraceEnablePAL);
Jeff Johnson295189b2012-06-20 16:38:30 -070011508
Jeff Johnson88ba7742013-02-27 14:36:02 -080011509 if (VOS_FTM_MODE == hdd_get_conparam())
11510 {
Jeff Johnson295189b2012-06-20 16:38:30 -070011511 if ( VOS_STATUS_SUCCESS != wlan_hdd_ftm_open(pHddCtx) )
11512 {
11513 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: wlan_hdd_ftm_open Failed",__func__);
11514 goto err_free_hdd_context;
11515 }
11516 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: FTM driver loaded success fully",__func__);
Sachin Ahuja38ef5e02015-03-13 17:31:16 +053011517 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_NO_LOAD_UNLOAD_IN_PROGRESS;
c_hpothu2de0ef62014-04-15 16:16:15 +053011518 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, FALSE);
Jeff Johnson295189b2012-06-20 16:38:30 -070011519 return VOS_STATUS_SUCCESS;
Jeff Johnson88ba7742013-02-27 14:36:02 -080011520 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011521
Katya Nigame7b69a82015-04-28 15:24:06 +053011522 if( VOS_MONITOR_MODE == hdd_get_conparam())
11523 {
11524 if ( VOS_STATUS_SUCCESS != wlan_hdd_mon_open(pHddCtx))
11525 {
11526 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: wlan_hdd_mon_open Failed",__func__);
11527 goto err_free_hdd_context;
11528 }
11529 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Driver loaded in Monitor Mode",__func__);
11530 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_NO_LOAD_UNLOAD_IN_PROGRESS;
11531 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, FALSE);
11532 return VOS_STATUS_SUCCESS;
11533 }
11534
Jeff Johnson88ba7742013-02-27 14:36:02 -080011535 //Open watchdog module
Jeff Johnson295189b2012-06-20 16:38:30 -070011536 if(pHddCtx->cfg_ini->fIsLogpEnabled)
11537 {
11538 status = vos_watchdog_open(pVosContext,
11539 &((VosContextType*)pVosContext)->vosWatchdog, sizeof(VosWatchdogContext));
11540
11541 if(!VOS_IS_STATUS_SUCCESS( status ))
11542 {
11543 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: vos_watchdog_open failed",__func__);
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +053011544 goto err_wdclose;
Jeff Johnson295189b2012-06-20 16:38:30 -070011545 }
11546 }
11547
11548 pHddCtx->isLogpInProgress = FALSE;
11549 vos_set_logp_in_progress(VOS_MODULE_ID_VOSS, FALSE);
11550
Amar Singhala49cbc52013-10-08 18:37:44 -070011551#ifdef CONFIG_ENABLE_LINUX_REG
Amar Singhal0a402232013-10-11 20:57:16 -070011552 /* initialize the NV module. This is required so that
11553 we can initialize the channel information in wiphy
11554 from the NV.bin data. The channel information in
11555 wiphy needs to be initialized before wiphy registration */
11556
11557 status = vos_nv_open();
11558 if (!VOS_IS_STATUS_SUCCESS(status))
11559 {
11560 /* NV module cannot be initialized */
11561 hddLog( VOS_TRACE_LEVEL_FATAL,
11562 "%s: vos_nv_open failed", __func__);
Vinay Krishna Eranna2025d892014-09-18 16:51:42 +053011563 goto err_wdclose;
Amar Singhal0a402232013-10-11 20:57:16 -070011564 }
11565
11566 status = vos_init_wiphy_from_nv_bin();
11567 if (!VOS_IS_STATUS_SUCCESS(status))
11568 {
11569 /* NV module cannot be initialized */
11570 hddLog( VOS_TRACE_LEVEL_FATAL,
11571 "%s: vos_init_wiphy failed", __func__);
11572 goto err_vos_nv_close;
11573 }
11574
Amar Singhala49cbc52013-10-08 18:37:44 -070011575#endif
Mahesh A Saptasagarc3ed0122016-01-19 16:45:11 +053011576 //Initialize the nlink service
11577 if(nl_srv_init() != 0)
11578 {
11579 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: nl_srv_init failed", __func__);
11580 goto err_vos_nv_close;
11581 }
11582
11583#ifdef WLAN_KD_READY_NOTIFIER
11584 pHddCtx->kd_nl_init = 1;
11585#endif /* WLAN_KD_READY_NOTIFIER */
11586
Girish Gowlibf0e1ab2015-01-19 16:05:16 +053011587 vos_set_roam_delay_stats_enabled(pHddCtx->cfg_ini->gEnableRoamDelayStats);
Arun Kumar Khandavalliebb19482014-03-25 13:56:53 +053011588 status = vos_open( &pVosContext, pHddCtx->parent_dev);
Jeff Johnson295189b2012-06-20 16:38:30 -070011589 if ( !VOS_IS_STATUS_SUCCESS( status ))
11590 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -080011591 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: vos_open failed", __func__);
Mahesh A Saptasagarc3ed0122016-01-19 16:45:11 +053011592 goto err_nl_srv;
Jeff Johnson295189b2012-06-20 16:38:30 -070011593 }
11594
Jeff Johnson295189b2012-06-20 16:38:30 -070011595 pHddCtx->hHal = (tHalHandle)vos_get_context( VOS_MODULE_ID_SME, pVosContext );
11596
11597 if ( NULL == pHddCtx->hHal )
11598 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -080011599 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: HAL context is null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070011600 goto err_vosclose;
11601 }
11602
Jeff Johnsonbc676b42013-02-14 16:04:08 -080011603 status = vos_preStart( pHddCtx->pvosContext );
11604 if ( !VOS_IS_STATUS_SUCCESS( status ) )
11605 {
11606 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: vos_preStart failed", __func__);
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053011607 goto err_vosclose;
Jeff Johnsonbc676b42013-02-14 16:04:08 -080011608 }
Jeff Johnsone7245742012-09-05 17:12:55 -070011609
Arif Hussaineaf68602013-12-30 23:10:44 -080011610 if (0 == enable_dfs_chan_scan || 1 == enable_dfs_chan_scan)
11611 {
11612 pHddCtx->cfg_ini->enableDFSChnlScan = enable_dfs_chan_scan;
11613 hddLog(VOS_TRACE_LEVEL_INFO, "%s: module enable_dfs_chan_scan set to %d",
11614 __func__, enable_dfs_chan_scan);
11615 }
11616 if (0 == enable_11d || 1 == enable_11d)
11617 {
11618 pHddCtx->cfg_ini->Is11dSupportEnabled = enable_11d;
11619 hddLog(VOS_TRACE_LEVEL_INFO, "%s: module enable_11d set to %d",
11620 __func__, enable_11d);
11621 }
11622
Jeff Johnsonbc676b42013-02-14 16:04:08 -080011623 /* Note that the vos_preStart() sequence triggers the cfg download.
11624 The cfg download must occur before we update the SME config
11625 since the SME config operation must access the cfg database */
Jeff Johnson295189b2012-06-20 16:38:30 -070011626 status = hdd_set_sme_config( pHddCtx );
11627
11628 if ( VOS_STATUS_SUCCESS != status )
11629 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -080011630 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Failed hdd_set_sme_config", __func__);
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053011631 goto err_vosclose;
Jeff Johnsonbc676b42013-02-14 16:04:08 -080011632 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011633
Jeff Johnson295189b2012-06-20 16:38:30 -070011634 /* In the integrated architecture we update the configuration from
11635 the INI file and from NV before vOSS has been started so that
11636 the final contents are available to send down to the cCPU */
11637
11638 // Apply the cfg.ini to cfg.dat
11639 if (FALSE == hdd_update_config_dat(pHddCtx))
11640 {
11641 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: config update failed",__func__ );
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053011642 goto err_vosclose;
Jeff Johnson295189b2012-06-20 16:38:30 -070011643 }
11644
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +053011645 // Get mac addr from platform driver
11646 ret = wcnss_get_wlan_mac_address((char*)&mac_addr.bytes);
11647
11648 if ((0 == ret) && (!vos_is_macaddr_zero(&mac_addr)))
Jeff Johnson295189b2012-06-20 16:38:30 -070011649 {
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +053011650 /* Store the mac addr for first interface */
11651 pHddCtx->cfg_ini->intfMacAddr[0] = mac_addr;
11652
11653 hddLog(VOS_TRACE_LEVEL_ERROR,
11654 "%s: WLAN Mac Addr: "
11655 MAC_ADDRESS_STR, __func__,
11656 MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[0].bytes));
11657
11658 /* Here, passing Arg2 as 1 because we do not want to change the
11659 last 3 bytes (means non OUI bytes) of first interface mac
11660 addr.
11661 */
11662 if (0 != hdd_generate_iface_mac_addr_auto(pHddCtx, 1, mac_addr))
11663 {
11664 hddLog(VOS_TRACE_LEVEL_ERROR,
11665 "%s: Failed to generate wlan interface mac addr "
11666 "using MAC from ini file ", __func__);
11667 }
11668 }
11669 else if (VOS_STATUS_SUCCESS != hdd_update_config_from_nv(pHddCtx))
11670 {
11671 // Apply the NV to cfg.dat
11672 /* Prima Update MAC address only at here */
Jeff Johnson295189b2012-06-20 16:38:30 -070011673#ifdef WLAN_AUTOGEN_MACADDR_FEATURE
11674 /* There was not a valid set of MAC Addresses in NV. See if the
11675 default addresses were modified by the cfg.ini settings. If so,
11676 we'll use them, but if not, we'll autogenerate a set of MAC
11677 addresses based upon the device serial number */
11678
11679 static const v_MACADDR_t default_address =
11680 {{0x00, 0x0A, 0xF5, 0x89, 0x89, 0xFF}};
Jeff Johnson295189b2012-06-20 16:38:30 -070011681
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +053011682 if (0 == memcmp(&default_address, &pHddCtx->cfg_ini->intfMacAddr[0],
11683 sizeof(default_address)))
Jeff Johnson295189b2012-06-20 16:38:30 -070011684 {
11685 /* cfg.ini has the default address, invoke autogen logic */
11686
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +053011687 /* Here, passing Arg2 as 0 because we want to change the
11688 last 3 bytes (means non OUI bytes) of all the interfaces
11689 mac addr.
11690 */
11691 if (0 != hdd_generate_iface_mac_addr_auto(pHddCtx, 0,
11692 default_address))
Jeff Johnson295189b2012-06-20 16:38:30 -070011693 {
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +053011694 hddLog(VOS_TRACE_LEVEL_ERROR,
11695 "%s: Failed to generate wlan interface mac addr "
11696 "using MAC from ini file " MAC_ADDRESS_STR, __func__,
11697 MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[0].bytes));
Jeff Johnson295189b2012-06-20 16:38:30 -070011698 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011699 }
11700 else
11701#endif //WLAN_AUTOGEN_MACADDR_FEATURE
11702 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -080011703 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070011704 "%s: Invalid MAC address in NV, using MAC from ini file "
11705 MAC_ADDRESS_STR, __func__,
11706 MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[0].bytes));
11707 }
11708 }
11709 {
11710 eHalStatus halStatus;
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +053011711
11712 /* Set the MAC Address Currently this is used by HAL to
11713 * add self sta. Remove this once self sta is added as
11714 * part of session open.
11715 */
Jeff Johnson295189b2012-06-20 16:38:30 -070011716 halStatus = cfgSetStr( pHddCtx->hHal, WNI_CFG_STA_ID,
11717 (v_U8_t *)&pHddCtx->cfg_ini->intfMacAddr[0],
11718 sizeof( pHddCtx->cfg_ini->intfMacAddr[0]) );
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +053011719
Jeff Johnson295189b2012-06-20 16:38:30 -070011720 if (!HAL_STATUS_SUCCESS( halStatus ))
11721 {
11722 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Failed to set MAC Address. "
11723 "HALStatus is %08d [x%08x]",__func__, halStatus, halStatus );
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053011724 goto err_vosclose;
Jeff Johnson295189b2012-06-20 16:38:30 -070011725 }
11726 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011727
11728 /*Start VOSS which starts up the SME/MAC/HAL modules and everything else
11729 Note: Firmware image will be read and downloaded inside vos_start API */
11730 status = vos_start( pHddCtx->pvosContext );
11731 if ( !VOS_IS_STATUS_SUCCESS( status ) )
11732 {
11733 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: vos_start failed",__func__);
Hanumantha Reddy Pothulabd9601a2016-02-12 13:22:27 +053011734 if (isSsrPanicOnFailure())
11735 VOS_BUG(0);
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053011736 goto err_vosclose;
Jeff Johnson295189b2012-06-20 16:38:30 -070011737 }
11738
Leo Chang6cec3e22014-01-21 15:33:49 -080011739#ifdef FEATURE_WLAN_CH_AVOID
11740 /* Plug in avoid channel notification callback
11741 * This should happen before ADD_SELF_STA
11742 * FW will send first IND with ADD_SELF_STA REQ from host */
Pradeep Reddy POTTETI5c2e16d2014-06-27 16:47:38 +053011743
11744 /* check the Channel Avoidance is enabled */
11745 if (TRUE == pHddCtx->cfg_ini->fenableCHAvoidance)
11746 {
11747 sme_AddChAvoidCallback(pHddCtx->hHal,
11748 hdd_hostapd_ch_avoid_cb);
11749 }
Leo Chang6cec3e22014-01-21 15:33:49 -080011750#endif /* FEATURE_WLAN_CH_AVOID */
11751
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -070011752 /* Exchange capability info between Host and FW and also get versioning info from FW */
11753 hdd_exchange_version_and_caps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -070011754
Agarwal Ashishad9281b2014-06-10 14:57:30 +053011755#ifdef CONFIG_ENABLE_LINUX_REG
11756 status = wlan_hdd_init_channels(pHddCtx);
11757 if ( !VOS_IS_STATUS_SUCCESS( status ) )
11758 {
11759 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: wlan_hdd_init_channels failed",
11760 __func__);
11761 goto err_vosstop;
11762 }
11763#endif
11764
Jeff Johnson295189b2012-06-20 16:38:30 -070011765 status = hdd_post_voss_start_config( pHddCtx );
11766 if ( !VOS_IS_STATUS_SUCCESS( status ) )
11767 {
11768 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hdd_post_voss_start_config failed",
11769 __func__);
11770 goto err_vosstop;
11771 }
Amar Singhala49cbc52013-10-08 18:37:44 -070011772
11773#ifndef CONFIG_ENABLE_LINUX_REG
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +053011774 wlan_hdd_cfg80211_update_reg_info( wiphy );
11775
11776 /* registration of wiphy dev with cfg80211 */
11777 if (0 > wlan_hdd_cfg80211_register(wiphy))
11778 {
11779 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy register failed", __func__);
11780 goto err_vosstop;
11781 }
Amar Singhala49cbc52013-10-08 18:37:44 -070011782#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070011783
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053011784#ifdef CONFIG_ENABLE_LINUX_REG
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053011785 /* registration of wiphy dev with cfg80211 */
11786 if (0 > wlan_hdd_cfg80211_register(wiphy))
11787 {
11788 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy register failed", __func__);
11789 goto err_vosstop;
11790 }
11791
Agarwal Ashish6db9d532014-09-30 18:19:10 +053011792 status = wlan_hdd_init_channels_for_cc(pHddCtx, INIT);
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053011793 if ( !VOS_IS_STATUS_SUCCESS( status ) )
11794 {
11795 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: wlan_hdd_init_channels_for_cc failed",
11796 __func__);
11797 goto err_unregister_wiphy;
11798 }
11799#endif
11800
c_hpothu4a298be2014-12-22 21:12:51 +053011801 wcnss_wlan_set_drvdata(pHddCtx->parent_dev, pHddCtx);
11802
Jeff Johnson295189b2012-06-20 16:38:30 -070011803 if (VOS_STA_SAP_MODE == hdd_get_conparam())
11804 {
11805 pAdapter = hdd_open_adapter( pHddCtx, WLAN_HDD_SOFTAP, "softap.%d",
11806 wlan_hdd_get_intf_addr(pHddCtx), FALSE );
11807 }
11808 else
11809 {
Jeff Johnson295189b2012-06-20 16:38:30 -070011810 pAdapter = hdd_open_adapter( pHddCtx, WLAN_HDD_INFRA_STATION, "wlan%d",
11811 wlan_hdd_get_intf_addr(pHddCtx), FALSE );
11812 if (pAdapter != NULL)
11813 {
Katya Nigama7d81d72014-11-12 12:44:34 +053011814 if (pHddCtx->cfg_ini->isP2pDeviceAddrAdministrated && !(pHddCtx->cfg_ini->intfMacAddr[0].bytes[0] & 0x02))
Jeff Johnson295189b2012-06-20 16:38:30 -070011815 {
Gopichand Nakkala49f96f62013-02-06 14:38:17 +053011816 vos_mem_copy( pHddCtx->p2pDeviceAddress.bytes,
11817 pHddCtx->cfg_ini->intfMacAddr[0].bytes,
11818 sizeof(tSirMacAddr));
Madan Mohan Koyyalamudiedfc1b72012-10-18 20:25:55 -070011819
Gopichand Nakkala49f96f62013-02-06 14:38:17 +053011820 /* Generate the P2P Device Address. This consists of the device's
11821 * primary MAC address with the locally administered bit set.
11822 */
11823 pHddCtx->p2pDeviceAddress.bytes[0] |= 0x02;
Jeff Johnsone7245742012-09-05 17:12:55 -070011824 }
11825 else
11826 {
Gopichand Nakkala49f96f62013-02-06 14:38:17 +053011827 tANI_U8* p2p_dev_addr = wlan_hdd_get_intf_addr(pHddCtx);
11828 if (p2p_dev_addr != NULL)
11829 {
11830 vos_mem_copy(&pHddCtx->p2pDeviceAddress.bytes[0],
11831 p2p_dev_addr, VOS_MAC_ADDR_SIZE);
11832 }
11833 else
11834 {
11835 hddLog(VOS_TRACE_LEVEL_FATAL,
11836 "%s: Failed to allocate mac_address for p2p_device",
11837 __func__);
11838 goto err_close_adapter;
11839 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011840 }
Jeff Johnsone7245742012-09-05 17:12:55 -070011841
11842 pP2pAdapter = hdd_open_adapter( pHddCtx, WLAN_HDD_P2P_DEVICE, "p2p%d",
11843 &pHddCtx->p2pDeviceAddress.bytes[0], FALSE );
11844 if ( NULL == pP2pAdapter )
11845 {
11846 hddLog(VOS_TRACE_LEVEL_FATAL,
11847 "%s: Failed to do hdd_open_adapter for P2P Device Interface",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070011848 __func__);
Jeff Johnsone7245742012-09-05 17:12:55 -070011849 goto err_close_adapter;
11850 }
Jeff Johnsone7245742012-09-05 17:12:55 -070011851 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011852 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011853
11854 if( pAdapter == NULL )
11855 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -080011856 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: hdd_open_adapter failed", __func__);
11857 goto err_close_adapter;
Jeff Johnson295189b2012-06-20 16:38:30 -070011858 }
Jeff Johnsone7245742012-09-05 17:12:55 -070011859
Arif Hussain66559122013-11-21 10:11:40 -080011860 if (country_code)
11861 {
11862 eHalStatus ret;
Arif Hussaincb607082013-12-20 11:57:42 -080011863 INIT_COMPLETION(pAdapter->change_country_code);
Arif Hussain66559122013-11-21 10:11:40 -080011864 hdd_checkandupdate_dfssetting(pAdapter, country_code);
11865#ifndef CONFIG_ENABLE_LINUX_REG
11866 hdd_checkandupdate_phymode(pAdapter, country_code);
11867#endif
Arif Hussaineaf68602013-12-30 23:10:44 -080011868 ret = sme_ChangeCountryCode(pHddCtx->hHal,
11869 (void *)(tSmeChangeCountryCallback)
11870 wlan_hdd_change_country_code_callback,
Arif Hussain66559122013-11-21 10:11:40 -080011871 country_code,
11872 pAdapter, pHddCtx->pvosContext,
Abhishek Singha306a442013-11-07 18:39:01 +053011873 eSIR_TRUE, eSIR_TRUE);
Arif Hussain66559122013-11-21 10:11:40 -080011874 if (eHAL_STATUS_SUCCESS == ret)
11875 {
Arif Hussaincb607082013-12-20 11:57:42 -080011876 ret = wait_for_completion_interruptible_timeout(
11877 &pAdapter->change_country_code,
11878 msecs_to_jiffies(WLAN_WAIT_TIME_COUNTRY));
11879
11880 if (0 >= ret)
11881 {
11882 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
11883 "%s: SME while setting country code timed out", __func__);
11884 }
Arif Hussain66559122013-11-21 10:11:40 -080011885 }
11886 else
11887 {
Arif Hussaincb607082013-12-20 11:57:42 -080011888 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
11889 "%s: SME Change Country code from module param fail ret=%d",
11890 __func__, ret);
Arif Hussain66559122013-11-21 10:11:40 -080011891 }
11892 }
11893
Jeff Johnson295189b2012-06-20 16:38:30 -070011894#ifdef WLAN_BTAMP_FEATURE
11895 vStatus = WLANBAP_Open(pVosContext);
11896 if(!VOS_IS_STATUS_SUCCESS(vStatus))
11897 {
11898 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
11899 "%s: Failed to open BAP",__func__);
Jeff Johnsone7245742012-09-05 17:12:55 -070011900 goto err_close_adapter;
Jeff Johnson295189b2012-06-20 16:38:30 -070011901 }
11902
11903 vStatus = BSL_Init(pVosContext);
11904 if(!VOS_IS_STATUS_SUCCESS(vStatus))
11905 {
11906 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
11907 "%s: Failed to Init BSL",__func__);
11908 goto err_bap_close;
11909 }
11910 vStatus = WLANBAP_Start(pVosContext);
11911 if (!VOS_IS_STATUS_SUCCESS(vStatus))
11912 {
11913 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
11914 "%s: Failed to start TL",__func__);
11915 goto err_bap_close;
11916 }
11917
11918 pConfig = pHddCtx->cfg_ini;
11919 btAmpConfig.ucPreferredChannel = pConfig->preferredChannel;
11920 status = WLANBAP_SetConfig(&btAmpConfig);
11921
11922#endif //WLAN_BTAMP_FEATURE
Jeff Johnsone7245742012-09-05 17:12:55 -070011923
Mihir Shete9c238772014-10-15 14:35:16 +053011924 /*
11925 * UapsdMask is 0xf if U-APSD is enbaled for all AC's...
11926 * The value of CFG_QOS_WMM_UAPSD_MASK_DEFAULT is 0xaa(Magic Value)
11927 * which is greater than 0xf. So the below check is safe to make
11928 * sure that there is no entry for UapsdMask in the ini
11929 */
11930 if (CFG_QOS_WMM_UAPSD_MASK_DEFAULT == pHddCtx->cfg_ini->UapsdMask)
11931 {
11932 if(IS_DYNAMIC_WMM_PS_ENABLED)
11933 {
11934 hddLog(VOS_TRACE_LEVEL_DEBUG,"%s: Enable UAPSD for VI & VO",
11935 __func__);
11936 pHddCtx->cfg_ini->UapsdMask =
11937 CFG_QOS_WMM_UAPSD_MASK_DYMANIC_WMM_PS_DEFAULT;
11938 }
11939 else
11940 {
11941 hddLog(VOS_TRACE_LEVEL_DEBUG,"%s: Do not enable UAPSD",
11942 __func__);
11943 pHddCtx->cfg_ini->UapsdMask =
11944 CFG_QOS_WMM_UAPSD_MASK_LEGACY_WMM_PS_DEFAULT;
11945 }
11946 }
11947
Varun Reddy Yeturud0a3f252013-04-15 21:58:13 -070011948#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
11949 if(!(IS_ROAM_SCAN_OFFLOAD_FEATURE_ENABLE))
11950 {
11951 hddLog(VOS_TRACE_LEVEL_DEBUG,"%s: ROAM_SCAN_OFFLOAD Feature not supported",__func__);
11952 pHddCtx->cfg_ini->isRoamOffloadScanEnabled = 0;
11953 sme_UpdateRoamScanOffloadEnabled((tHalHandle)(pHddCtx->hHal),
11954 pHddCtx->cfg_ini->isRoamOffloadScanEnabled);
11955 }
11956#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070011957
Agarwal Ashish4b87f922014-06-18 03:03:21 +053011958 wlan_hdd_tdls_init(pHddCtx);
11959
Masti, Narayanraddi26378462016-01-05 18:20:28 +053011960 wlan_hdd_init_deinit_defer_scan_context(&pHddCtx->scan_ctxt);
11961
11962 vos_init_delayed_work(&pHddCtx->scan_ctxt.scan_work,
11963 wlan_hdd_schedule_defer_scan);
11964
Mihir Shetefc7ff5b2014-01-27 11:30:05 +053011965 sme_Register11dScanDoneCallback(pHddCtx->hHal, hdd_11d_scan_done);
11966
Jeff Johnson295189b2012-06-20 16:38:30 -070011967 /* Register with platform driver as client for Suspend/Resume */
11968 status = hddRegisterPmOps(pHddCtx);
11969 if ( !VOS_IS_STATUS_SUCCESS( status ) )
11970 {
11971 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddRegisterPmOps failed",__func__);
11972#ifdef WLAN_BTAMP_FEATURE
11973 goto err_bap_stop;
11974#else
Jeff Johnsone7245742012-09-05 17:12:55 -070011975 goto err_close_adapter;
Jeff Johnson295189b2012-06-20 16:38:30 -070011976#endif //WLAN_BTAMP_FEATURE
11977 }
11978
Yue Ma0d4891e2013-08-06 17:01:45 -070011979 /* Open debugfs interface */
11980 if (VOS_STATUS_SUCCESS != hdd_debugfs_init(pAdapter))
11981 {
11982 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
11983 "%s: hdd_debugfs_init failed!", __func__);
Yue Ma0d4891e2013-08-06 17:01:45 -070011984 }
11985
Jeff Johnson295189b2012-06-20 16:38:30 -070011986 /* Register TM level change handler function to the platform */
11987 status = hddDevTmRegisterNotifyCallback(pHddCtx);
11988 if ( !VOS_IS_STATUS_SUCCESS( status ) )
11989 {
11990 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddDevTmRegisterNotifyCallback failed",__func__);
11991 goto err_unregister_pmops;
11992 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011993
Jeff Johnson295189b2012-06-20 16:38:30 -070011994 // register net device notifier for device change notification
11995 ret = register_netdevice_notifier(&hdd_netdev_notifier);
11996
11997 if(ret < 0)
11998 {
11999 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: register_netdevice_notifier failed",__func__);
Siddharth Bhalcd92b782015-06-29 12:25:40 +053012000 goto err_unregister_pmops;
Jeff Johnson295189b2012-06-20 16:38:30 -070012001 }
12002
Jeff Johnson295189b2012-06-20 16:38:30 -070012003 //Initialize the BTC service
12004 if(btc_activate_service(pHddCtx) != 0)
12005 {
12006 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: btc_activate_service failed",__func__);
Mahesh A Saptasagarc3ed0122016-01-19 16:45:11 +053012007 goto err_reg_netdev;
Jeff Johnson295189b2012-06-20 16:38:30 -070012008 }
12009
Padma, Santhosh Kumar2762e9d2015-10-20 15:02:57 +053012010#ifdef FEATURE_OEM_DATA_SUPPORT
12011 //Initialize the OEM service
12012 if (oem_activate_service(pHddCtx) != 0)
12013 {
12014 hddLog(VOS_TRACE_LEVEL_FATAL,
12015 "%s: oem_activate_service failed", __func__);
Mahesh A Saptasagarc3ed0122016-01-19 16:45:11 +053012016 goto err_reg_netdev;
Padma, Santhosh Kumar2762e9d2015-10-20 15:02:57 +053012017 }
12018#endif
12019
Jeff Johnson295189b2012-06-20 16:38:30 -070012020#ifdef PTT_SOCK_SVC_ENABLE
12021 //Initialize the PTT service
12022 if(ptt_sock_activate_svc(pHddCtx) != 0)
12023 {
12024 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: ptt_sock_activate_svc failed",__func__);
Mahesh A Saptasagarc3ed0122016-01-19 16:45:11 +053012025 goto err_reg_netdev;
Jeff Johnson295189b2012-06-20 16:38:30 -070012026 }
12027#endif
12028
Abhishek Singh00b71972016-01-07 10:51:04 +053012029#ifdef WLAN_FEATURE_RMC
12030 if (hdd_open_cesium_nl_sock() < 0)
12031 {
12032 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hdd_open_cesium_nl_sock failed", __func__);
12033 goto err_reg_netdev;
12034 }
12035#endif
12036
Vinay Krishna Erannad938c422014-03-10 17:14:21 +053012037#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
12038 if(pHddCtx->cfg_ini && pHddCtx->cfg_ini->wlanLoggingEnable)
12039 {
Deepthi Gowri78083a32014-11-04 12:55:51 +053012040 if(wlan_logging_sock_activate_svc(
12041 pHddCtx->cfg_ini->wlanLoggingFEToConsole,
Sushant Kaushik33200572015-08-05 16:46:20 +053012042 pHddCtx->cfg_ini->wlanLoggingNumBuf,
12043 pHddCtx->cfg_ini->wlanPerPktStatsLogEnable,
12044 pHddCtx->cfg_ini->wlanPerPktStatsNumBuf))
Deepthi Gowri78083a32014-11-04 12:55:51 +053012045 {
12046 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wlan_logging_sock_activate_svc"
12047 " failed", __func__);
Mahesh A Saptasagarc3ed0122016-01-19 16:45:11 +053012048 goto err_reg_netdev;
Deepthi Gowri78083a32014-11-04 12:55:51 +053012049 }
12050 //TODO: To Remove enableDhcpDebug and use gEnableDebugLog for
12051 //EAPOL and DHCP
Sachin Ahuja8c65f382014-12-12 15:34:21 +053012052 if (!pHddCtx->cfg_ini->gEnableDebugLog)
12053 pHddCtx->cfg_ini->gEnableDebugLog =
Sushant Kaushik6e4e2bc2015-10-05 17:23:07 +053012054 VOS_PKT_PROTO_TYPE_EAPOL | VOS_PKT_PROTO_TYPE_DHCP |
12055 VOS_PKT_PROTO_TYPE_ARP;
Vinay Krishna Erannad938c422014-03-10 17:14:21 +053012056 }
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053012057
Siddharth Bhald1be97f2015-05-27 22:39:59 +053012058 if (pHddCtx->cfg_ini->wlanLoggingEnable &&
12059 (pHddCtx->cfg_ini->enableFWLogging ||
Siddharth Bhaldb963232015-06-25 19:34:35 +053012060 pHddCtx->cfg_ini->enableMgmtLogging ||
c_manjeecfd1efb2015-09-25 19:32:34 +053012061 pHddCtx->cfg_ini->enableContFWLogging ||
12062 pHddCtx->cfg_ini->enableFwrMemDump )
12063 )
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053012064 {
Siddharth Bhald1be97f2015-05-27 22:39:59 +053012065 hdd_init_frame_logging(pHddCtx);
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053012066 }
12067 else
12068 {
Siddharth Bhald1be97f2015-05-27 22:39:59 +053012069 hddLog(VOS_TRACE_LEVEL_INFO, FL("Logging disabled in ini"));
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053012070 }
12071
Vinay Krishna Erannad938c422014-03-10 17:14:21 +053012072#endif
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053012073
12074
Sushant Kaushik215778f2015-05-21 14:05:36 +053012075 if (vos_is_multicast_logging())
12076 wlan_logging_set_log_level();
12077
Jeff Johnson295189b2012-06-20 16:38:30 -070012078 hdd_register_mcast_bcast_filter(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -070012079 if (VOS_STA_SAP_MODE != hdd_get_conparam())
Jeff Johnson295189b2012-06-20 16:38:30 -070012080 {
Madan Mohan Koyyalamudic537df22012-10-22 15:07:08 -070012081 /* Action frame registered in one adapter which will
12082 * applicable to all interfaces
12083 */
Agarwal Ashish8fa0e9a2014-05-23 00:40:12 +053012084 wlan_hdd_cfg80211_register_frames(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070012085 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012086
12087 mutex_init(&pHddCtx->sap_lock);
Mahesh A Saptasagar60627942014-10-13 13:55:14 +053012088 mutex_init(&pHddCtx->roc_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -070012089
Jeff Johnsone7245742012-09-05 17:12:55 -070012090#ifdef WLAN_FEATURE_HOLD_RX_WAKELOCK
12091 /* Initialize the wake lcok */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053012092 vos_wake_lock_init(&pHddCtx->rx_wake_lock,
Jeff Johnsone7245742012-09-05 17:12:55 -070012093 "qcom_rx_wakelock");
Sushant Kaushik83392fa2015-05-05 17:44:40 +053012094
Jeff Johnsone7245742012-09-05 17:12:55 -070012095#endif
Madan Mohan Koyyalamudi69fc3ad2012-11-28 16:04:56 -080012096 /* Initialize the wake lcok */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053012097 vos_wake_lock_init(&pHddCtx->sap_wake_lock,
Madan Mohan Koyyalamudi69fc3ad2012-11-28 16:04:56 -080012098 "qcom_sap_wakelock");
Sushant Kaushik83392fa2015-05-05 17:44:40 +053012099
Jeff Johnsone7245742012-09-05 17:12:55 -070012100
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070012101 vos_event_init(&pHddCtx->scan_info.scan_finished_event);
12102 pHddCtx->scan_info.scan_pending_option = WEXT_SCAN_PENDING_GIVEUP;
Jeff Johnson295189b2012-06-20 16:38:30 -070012103
Katya Nigam5c306ea2014-06-19 15:39:54 +053012104 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_NO_LOAD_UNLOAD_IN_PROGRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -070012105 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, FALSE);
Sushant Kaushik83392fa2015-05-05 17:44:40 +053012106 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_DRIVER_INIT);
Katya Nigam5c306ea2014-06-19 15:39:54 +053012107
12108#ifdef FEATURE_WLAN_SCAN_PNO
12109 /*SME must send channel update configuration to RIVA*/
12110 sme_UpdateChannelConfig(pHddCtx->hHal);
12111#endif
Abhishek Singhf644b272014-08-21 02:59:39 +053012112 /* Send the update default channel list to the FW*/
12113 sme_UpdateChannelList(pHddCtx->hHal);
Mukul Sharma45063942015-04-01 20:07:59 +053012114
12115 /* Fwr capabilities received, Set the Dot11 mode */
Abhishek Singh41ebce12016-02-03 10:43:21 +053012116 sme_SetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter),
12117 hdd_cfg_xlate_to_csr_phy_mode(pHddCtx->cfg_ini->dot11Mode));
Mukul Sharma45063942015-04-01 20:07:59 +053012118 sme_SetDefDot11Mode(pHddCtx->hHal);
12119
Abhishek Singha306a442013-11-07 18:39:01 +053012120#ifndef CONFIG_ENABLE_LINUX_REG
12121 /*updating wiphy so that regulatory user hints can be processed*/
12122 if (wiphy)
12123 {
12124 regulatory_hint(wiphy, "00");
12125 }
12126#endif
Jeff Johnsone7245742012-09-05 17:12:55 -070012127 // Initialize the restart logic
12128 wlan_hdd_restart_init(pHddCtx);
Chilam NG571c65a2013-01-19 12:27:36 +053012129
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -070012130 //Register the traffic monitor timer now
12131 if ( pHddCtx->cfg_ini->dynSplitscan)
12132 {
12133 vos_timer_init(&pHddCtx->tx_rx_trafficTmr,
12134 VOS_TIMER_TYPE_SW,
12135 hdd_tx_rx_pkt_cnt_stat_timer_handler,
12136 (void *)pHddCtx);
12137 }
Srinivas Dasari030bad32015-02-18 23:23:54 +053012138 wlan_hdd_cfg80211_nan_init(pHddCtx);
12139
Bhargav Shahd0715912015-10-01 18:17:37 +053012140 mutex_init(&pHddCtx->cur_rx_level_lock);
12141 vos_timer_init(&pHddCtx->delack_timer, VOS_TIMER_TYPE_SW,
12142 hdd_tcp_delack_compute_function,(void *)pHddCtx);
Masti, Narayanraddi44b0db02015-12-22 11:54:35 +053012143 vos_timer_init(&pHddCtx->tdls_source_timer, VOS_TIMER_TYPE_SW,
12144 wlan_hdd_change_tdls_mode, (void *)pHddCtx);
Bhargav Shahd0715912015-10-01 18:17:37 +053012145
Dino Mycle6fb96c12014-06-10 11:52:40 +053012146#ifdef WLAN_FEATURE_EXTSCAN
12147 sme_EXTScanRegisterCallback(pHddCtx->hHal,
12148 wlan_hdd_cfg80211_extscan_callback,
12149 pHddCtx);
12150#endif /* WLAN_FEATURE_EXTSCAN */
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +053012151
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053012152#ifdef FEATURE_OEM_DATA_SUPPORT
12153 sme_OemDataRegisterCallback(pHddCtx->hHal,
12154 wlan_hdd_cfg80211_oemdata_callback,
12155 pHddCtx);
12156#endif /* FEATURE_OEM_DATA_SUPPORT */
12157
Gupta, Kapil7c34b322015-09-30 13:12:35 +053012158 sme_set_rssi_threshold_breached_cb(pHddCtx->hHal, hdd_rssi_threshold_breached_cb);
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +053012159#ifdef WLAN_NS_OFFLOAD
12160 // Register IPv6 notifier to notify if any change in IP
12161 // So that we can reconfigure the offload parameters
12162 pHddCtx->ipv6_notifier.notifier_call = wlan_hdd_ipv6_changed;
12163 ret = register_inet6addr_notifier(&pHddCtx->ipv6_notifier);
12164 if (ret)
12165 {
Ratheesh S P36dbc932015-08-07 14:28:57 +053012166 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to register IPv6 notifier"));
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +053012167 }
12168 else
12169 {
Ratheesh S P36dbc932015-08-07 14:28:57 +053012170 hddLog(VOS_TRACE_LEVEL_INFO, FL("Registered IPv6 notifier"));
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +053012171 }
12172#endif
12173
12174 // Register IPv4 notifier to notify if any change in IP
12175 // So that we can reconfigure the offload parameters
12176 pHddCtx->ipv4_notifier.notifier_call = wlan_hdd_ipv4_changed;
12177 ret = register_inetaddr_notifier(&pHddCtx->ipv4_notifier);
12178 if (ret)
12179 {
Ratheesh S P36dbc932015-08-07 14:28:57 +053012180 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to register IPv4 notifier"));
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +053012181 }
12182 else
12183 {
Ratheesh S P36dbc932015-08-07 14:28:57 +053012184 hddLog(VOS_TRACE_LEVEL_INFO, FL("Registered IPv4 notifier"));
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +053012185 }
c_manjeecfd1efb2015-09-25 19:32:34 +053012186 /*Fw mem dump procfs initialization*/
12187 memdump_init();
Bhargav shah23c94942015-10-13 12:48:35 +053012188 hdd_dp_util_send_rps_ind(pHddCtx);
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +053012189
Jeff Johnson295189b2012-06-20 16:38:30 -070012190 goto success;
12191
Jeff Johnson295189b2012-06-20 16:38:30 -070012192err_reg_netdev:
12193 unregister_netdevice_notifier(&hdd_netdev_notifier);
12194
Jeff Johnson295189b2012-06-20 16:38:30 -070012195err_unregister_pmops:
12196 hddDevTmUnregisterNotifyCallback(pHddCtx);
12197 hddDeregisterPmOps(pHddCtx);
12198
Yue Ma0d4891e2013-08-06 17:01:45 -070012199 hdd_debugfs_exit(pHddCtx);
12200
Jeff Johnson295189b2012-06-20 16:38:30 -070012201#ifdef WLAN_BTAMP_FEATURE
12202err_bap_stop:
12203 WLANBAP_Stop(pVosContext);
12204#endif
12205
12206#ifdef WLAN_BTAMP_FEATURE
12207err_bap_close:
12208 WLANBAP_Close(pVosContext);
12209#endif
12210
Jeff Johnson295189b2012-06-20 16:38:30 -070012211err_close_adapter:
12212 hdd_close_all_adapters( pHddCtx );
Mahesh A Saptasagar9ecefe42014-07-15 18:43:49 +053012213#ifdef CONFIG_ENABLE_LINUX_REG
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053012214err_unregister_wiphy:
Mahesh A Saptasagar9ecefe42014-07-15 18:43:49 +053012215#endif
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +053012216 wiphy_unregister(wiphy) ;
Agrawal Ashish33ec71e2015-11-26 20:20:58 +053012217 hdd_wlan_free_wiphy_channels(wiphy);
12218
Jeff Johnson295189b2012-06-20 16:38:30 -070012219err_vosstop:
12220 vos_stop(pVosContext);
12221
Amar Singhala49cbc52013-10-08 18:37:44 -070012222err_vosclose:
Jeff Johnson295189b2012-06-20 16:38:30 -070012223 status = vos_sched_close( pVosContext );
12224 if (!VOS_IS_STATUS_SUCCESS(status)) {
12225 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
12226 "%s: Failed to close VOSS Scheduler", __func__);
12227 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( status ) );
12228 }
Amar Singhala49cbc52013-10-08 18:37:44 -070012229 vos_close(pVosContext );
12230
Mahesh A Saptasagarc3ed0122016-01-19 16:45:11 +053012231err_nl_srv:
12232#ifdef WLAN_KD_READY_NOTIFIER
12233 nl_srv_exit(pHddCtx->ptt_pid);
12234#else
12235 nl_srv_exit();
12236#endif /* WLAN_KD_READY_NOTIFIER */
Amar Singhal0a402232013-10-11 20:57:16 -070012237err_vos_nv_close:
12238
c_hpothue6a36282014-03-19 12:27:38 +053012239#ifdef CONFIG_ENABLE_LINUX_REG
Amar Singhal0a402232013-10-11 20:57:16 -070012240 vos_nv_close();
12241
c_hpothu70f8d812014-03-22 22:59:23 +053012242#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070012243
12244err_wdclose:
12245 if(pHddCtx->cfg_ini->fIsLogpEnabled)
12246 vos_watchdog_close(pVosContext);
12247
Jeff Johnson295189b2012-06-20 16:38:30 -070012248err_config:
12249 kfree(pHddCtx->cfg_ini);
12250 pHddCtx->cfg_ini= NULL;
12251
12252err_free_hdd_context:
Sushant Kaushik83392fa2015-05-05 17:44:40 +053012253 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_DRIVER_INIT);
Siddharth Bhalcd92b782015-06-29 12:25:40 +053012254 free_riva_power_on_lock("wlan");
Jeff Johnson295189b2012-06-20 16:38:30 -070012255 wiphy_free(wiphy) ;
12256 //kfree(wdev) ;
Jeff Johnson295189b2012-06-20 16:38:30 -070012257 VOS_BUG(1);
12258
Madan Mohan Koyyalamudid57ae632012-11-06 18:42:48 -080012259 if (hdd_is_ssr_required())
12260 {
12261 /* WDI timeout had happened during load, so SSR is needed here */
12262 subsystem_restart("wcnss");
12263 msleep(5000);
12264 }
12265 hdd_set_ssr_required (VOS_FALSE);
12266
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -080012267 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -070012268
12269success:
12270 EXIT();
12271 return 0;
12272}
12273
12274/**---------------------------------------------------------------------------
12275
Jeff Johnson32d95a32012-09-10 13:15:23 -070012276 \brief hdd_driver_init() - Core Driver Init Function
Jeff Johnson295189b2012-06-20 16:38:30 -070012277
Jeff Johnson32d95a32012-09-10 13:15:23 -070012278 This is the driver entry point - called in different timeline depending
12279 on whether the driver is statically or dynamically linked
Jeff Johnson295189b2012-06-20 16:38:30 -070012280
12281 \param - None
12282
12283 \return - 0 for success, non zero for failure
12284
12285 --------------------------------------------------------------------------*/
Jeff Johnson32d95a32012-09-10 13:15:23 -070012286static int hdd_driver_init( void)
Jeff Johnson295189b2012-06-20 16:38:30 -070012287{
12288 VOS_STATUS status;
12289 v_CONTEXT_t pVosContext = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070012290 struct device *dev = NULL;
12291 int ret_status = 0;
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -070012292#ifdef HAVE_WCNSS_CAL_DOWNLOAD
12293 int max_retries = 0;
12294#endif
Siddharth Bhalc7e79b62014-10-10 22:37:38 +053012295#ifdef HAVE_CBC_DONE
12296 int max_cbc_retries = 0;
12297#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070012298
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +053012299#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
12300 wlan_logging_sock_init_svc();
12301#endif
12302
Jeff Johnson295189b2012-06-20 16:38:30 -070012303 ENTER();
12304
Sushant Kaushik83392fa2015-05-05 17:44:40 +053012305 vos_wake_lock_init(&wlan_wake_lock, "wlan");
Jeff Johnson295189b2012-06-20 16:38:30 -070012306
12307 pr_info("%s: loading driver v%s\n", WLAN_MODULE_NAME,
12308 QWLAN_VERSIONSTR TIMER_MANAGER_STR MEMORY_DEBUG_STR);
12309
Jeff Johnson295189b2012-06-20 16:38:30 -070012310#ifdef ANI_BUS_TYPE_PCI
12311
12312 dev = wcnss_wlan_get_device();
12313
12314#endif // ANI_BUS_TYPE_PCI
12315
12316#ifdef ANI_BUS_TYPE_PLATFORM
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -070012317
12318#ifdef HAVE_WCNSS_CAL_DOWNLOAD
12319 /* wait until WCNSS driver downloads NV */
12320 while (!wcnss_device_ready() && 5 >= ++max_retries) {
12321 msleep(1000);
12322 }
Siddharth Bhalc7e79b62014-10-10 22:37:38 +053012323
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -070012324 if (max_retries >= 5) {
12325 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: WCNSS driver not ready", __func__);
Sushant Kaushik83392fa2015-05-05 17:44:40 +053012326 vos_wake_lock_destroy(&wlan_wake_lock);
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +053012327#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
12328 wlan_logging_sock_deinit_svc();
12329#endif
12330
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -070012331 return -ENODEV;
12332 }
12333#endif
12334
Siddharth Bhalc7e79b62014-10-10 22:37:38 +053012335#ifdef HAVE_CBC_DONE
12336 while (!wcnss_cbc_complete() && 10 >= ++max_cbc_retries) {
12337 msleep(1000);
12338 }
12339 if (max_cbc_retries >= 10) {
12340 hddLog(VOS_TRACE_LEVEL_FATAL, "%s:CBC not completed", __func__);
12341 }
12342#endif
12343
Jeff Johnson295189b2012-06-20 16:38:30 -070012344 dev = wcnss_wlan_get_device();
12345#endif // ANI_BUS_TYPE_PLATFORM
12346
12347
12348 do {
12349 if (NULL == dev) {
12350 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: WLAN device not found!!",__func__);
12351 ret_status = -1;
12352 break;
12353 }
12354
Jeff Johnson295189b2012-06-20 16:38:30 -070012355#ifdef TIMER_MANAGER
12356 vos_timer_manager_init();
12357#endif
12358
12359 /* Preopen VOSS so that it is ready to start at least SAL */
12360 status = vos_preOpen(&pVosContext);
12361
12362 if (!VOS_IS_STATUS_SUCCESS(status))
12363 {
12364 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Failed to preOpen VOSS", __func__);
12365 ret_status = -1;
12366 break;
12367 }
12368
Sushant Kaushik02beb352015-06-04 15:15:01 +053012369 hddTraceInit();
Padma, Santhosh Kumar9093b202015-07-21 15:37:38 +053012370 hdd_register_debug_callback();
12371
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070012372#ifndef MODULE
12373 /* For statically linked driver, call hdd_set_conparam to update curr_con_mode
12374 */
12375 hdd_set_conparam((v_UINT_t)con_mode);
12376#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070012377
12378 // Call our main init function
Jeff Johnsonbc676b42013-02-14 16:04:08 -080012379 if (hdd_wlan_startup(dev))
12380 {
Jeff Johnson295189b2012-06-20 16:38:30 -070012381 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: WLAN Driver Initialization failed",
Jeff Johnsonbc676b42013-02-14 16:04:08 -080012382 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070012383 vos_preClose( &pVosContext );
12384 ret_status = -1;
12385 break;
12386 }
12387
Jeff Johnson295189b2012-06-20 16:38:30 -070012388 } while (0);
12389
12390 if (0 != ret_status)
12391 {
Jeff Johnson295189b2012-06-20 16:38:30 -070012392#ifdef TIMER_MANAGER
12393 vos_timer_exit();
12394#endif
12395#ifdef MEMORY_DEBUG
12396 vos_mem_exit();
12397#endif
Sushant Kaushik83392fa2015-05-05 17:44:40 +053012398 vos_wake_lock_destroy(&wlan_wake_lock);
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +053012399#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
12400 wlan_logging_sock_deinit_svc();
12401#endif
12402
Jeff Johnson295189b2012-06-20 16:38:30 -070012403 pr_err("%s: driver load failure\n", WLAN_MODULE_NAME);
12404 }
12405 else
12406 {
12407 //Send WLAN UP indication to Nlink Service
12408 send_btc_nlink_msg(WLAN_MODULE_UP_IND, 0);
12409
12410 pr_info("%s: driver loaded\n", WLAN_MODULE_NAME);
Jeff Johnson295189b2012-06-20 16:38:30 -070012411 }
12412
12413 EXIT();
12414
12415 return ret_status;
12416}
12417
Jeff Johnson32d95a32012-09-10 13:15:23 -070012418/**---------------------------------------------------------------------------
12419
12420 \brief hdd_module_init() - Init Function
12421
12422 This is the driver entry point (invoked when module is loaded using insmod)
12423
12424 \param - None
12425
12426 \return - 0 for success, non zero for failure
12427
12428 --------------------------------------------------------------------------*/
12429#ifdef MODULE
12430static int __init hdd_module_init ( void)
12431{
12432 return hdd_driver_init();
12433}
Jeff Johnson32d95a32012-09-10 13:15:23 -070012434#else /* #ifdef MODULE */
12435static int __init hdd_module_init ( void)
12436{
12437 /* Driver initialization is delayed to fwpath_changed_handler */
12438 return 0;
12439}
Jeff Johnson32d95a32012-09-10 13:15:23 -070012440#endif /* #ifdef MODULE */
12441
Jeff Johnson295189b2012-06-20 16:38:30 -070012442
12443/**---------------------------------------------------------------------------
12444
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070012445 \brief hdd_driver_exit() - Exit function
Jeff Johnson295189b2012-06-20 16:38:30 -070012446
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070012447 This is the driver exit point (invoked when module is unloaded using rmmod
12448 or con_mode was changed by userspace)
Jeff Johnson295189b2012-06-20 16:38:30 -070012449
12450 \param - None
12451
12452 \return - None
12453
12454 --------------------------------------------------------------------------*/
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070012455static void hdd_driver_exit(void)
Jeff Johnson295189b2012-06-20 16:38:30 -070012456{
12457 hdd_context_t *pHddCtx = NULL;
12458 v_CONTEXT_t pVosContext = NULL;
Agarwal Ashish5e414792014-06-08 15:25:23 +053012459 v_REGDOMAIN_t regId;
Arun Kumar Khandavallie0b046d2014-03-01 21:54:25 +053012460 unsigned long rc = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070012461
12462 pr_info("%s: unloading driver v%s\n", WLAN_MODULE_NAME, QWLAN_VERSIONSTR);
12463
12464 //Get the global vos context
12465 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
12466
12467 if(!pVosContext)
12468 {
12469 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Global VOS context is Null", __func__);
12470 goto done;
12471 }
12472
12473 //Get the HDD context.
12474 pHddCtx = (hdd_context_t *)vos_get_context(VOS_MODULE_ID_HDD, pVosContext );
12475
12476 if(!pHddCtx)
12477 {
12478 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: module exit called before probe",__func__);
12479 }
Katya Nigame7b69a82015-04-28 15:24:06 +053012480 else if (VOS_MONITOR_MODE == hdd_get_conparam())
12481 {
12482 hddLog(VOS_TRACE_LEVEL_INFO,"%s: MONITOR MODE",__func__);
12483 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_UNLOAD_IN_PROGRESS;
12484 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, TRUE);
12485 hdd_wlan_exit(pHddCtx);
12486 vos_preClose( &pVosContext );
12487 goto done;
12488 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012489 else
12490 {
Siddharth Bhal2e5871b2015-03-24 16:20:51 +053012491 /* We wait for active entry threads to exit from driver
12492 * by waiting until rtnl_lock is available.
12493 */
12494 rtnl_lock();
12495 rtnl_unlock();
12496
Siddharth Bhal3c29dca2015-02-19 00:41:40 +053012497 INIT_COMPLETION(pHddCtx->ssr_comp_var);
12498 if ((pHddCtx->isLogpInProgress) && (FALSE ==
12499 vos_is_wlan_in_badState(VOS_MODULE_ID_HDD, NULL)))
12500 {
Siddharth Bhala204f572015-01-17 02:03:36 +053012501 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Siddharth Bhal3c29dca2015-02-19 00:41:40 +053012502 "%s:SSR in Progress; block rmmod !!!", __func__);
Siddharth Bhala204f572015-01-17 02:03:36 +053012503 rc = wait_for_completion_timeout(&pHddCtx->ssr_comp_var,
12504 msecs_to_jiffies(30000));
12505 if(!rc)
12506 {
12507 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
12508 "%s:SSR timedout, fatal error", __func__);
12509 VOS_BUG(0);
12510 }
12511 }
12512
Siddharth Bhal3c29dca2015-02-19 00:41:40 +053012513 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_UNLOAD_IN_PROGRESS;
12514 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, TRUE);
Jeff Johnson295189b2012-06-20 16:38:30 -070012515
c_hpothu8adb97b2014-12-08 19:38:20 +053012516 /* Driver Need to send country code 00 in below condition
12517 * 1) If gCountryCodePriority is set to 1; and last country
12518 * code set is through 11d. This needs to be done in case
12519 * when NV country code is 00.
12520 * This Needs to be done as when kernel store last country
12521 * code and if stored country code is not through 11d,
12522 * in sme_HandleChangeCountryCodeByUser we will disable 11d
12523 * in next load/unload as soon as we get any country through
12524 * 11d. In sme_HandleChangeCountryCodeByUser
12525 * pMsg->countryCode will be last countryCode and
12526 * pMac->scan.countryCode11d will be country through 11d so
12527 * due to mismatch driver will disable 11d.
12528 *
12529 */
Agarwal Ashish8db39882014-07-30 21:56:07 +053012530
c_hpothu8adb97b2014-12-08 19:38:20 +053012531 if ((eANI_BOOLEAN_TRUE == sme_Is11dCountrycode(pHddCtx->hHal) &&
Agarwal Ashish8dcd2862014-07-25 11:58:52 +053012532 pHddCtx->cfg_ini->fSupplicantCountryCodeHasPriority &&
Abhishek Singh2a705962014-10-30 14:47:28 +053012533 sme_Is11dSupported(pHddCtx->hHal)))
c_hpothu8adb97b2014-12-08 19:38:20 +053012534 {
12535 hddLog(VOS_TRACE_LEVEL_INFO,
Agarwal Ashish8dcd2862014-07-25 11:58:52 +053012536 FL("CountryCode 00 is being set while unloading driver"));
c_hpothu8adb97b2014-12-08 19:38:20 +053012537 vos_nv_getRegDomainFromCountryCode(&regId , "00", COUNTRY_USER);
12538 }
Agarwal Ashish5e414792014-06-08 15:25:23 +053012539
c_hpothu8adb97b2014-12-08 19:38:20 +053012540 //Do all the cleanup before deregistering the driver
12541 hdd_wlan_exit(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -070012542 }
12543
Jeff Johnson295189b2012-06-20 16:38:30 -070012544 vos_preClose( &pVosContext );
12545
12546#ifdef TIMER_MANAGER
12547 vos_timer_exit();
12548#endif
12549#ifdef MEMORY_DEBUG
12550 vos_mem_exit();
12551#endif
12552
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +053012553#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
12554 wlan_logging_sock_deinit_svc();
12555#endif
12556
Jeff Johnson295189b2012-06-20 16:38:30 -070012557done:
Sushant Kaushik83392fa2015-05-05 17:44:40 +053012558 vos_wake_lock_destroy(&wlan_wake_lock);
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +053012559
Jeff Johnson295189b2012-06-20 16:38:30 -070012560 pr_info("%s: driver unloaded\n", WLAN_MODULE_NAME);
12561}
12562
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070012563/**---------------------------------------------------------------------------
12564
12565 \brief hdd_module_exit() - Exit function
12566
12567 This is the driver exit point (invoked when module is unloaded using rmmod)
12568
12569 \param - None
12570
12571 \return - None
12572
12573 --------------------------------------------------------------------------*/
12574static void __exit hdd_module_exit(void)
12575{
12576 hdd_driver_exit();
12577}
12578
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070012579#ifdef MODULE
12580static int fwpath_changed_handler(const char *kmessage,
12581 struct kernel_param *kp)
12582{
Jeff Johnson76052702013-04-16 13:55:05 -070012583 return param_set_copystring(kmessage, kp);
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070012584}
12585
12586static int con_mode_handler(const char *kmessage,
12587 struct kernel_param *kp)
12588{
Madan Mohan Koyyalamudif2f8d8b2012-10-11 17:06:59 -070012589 return param_set_int(kmessage, kp);
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070012590}
12591#else /* #ifdef MODULE */
12592/**---------------------------------------------------------------------------
12593
Jeff Johnson76052702013-04-16 13:55:05 -070012594 \brief kickstart_driver
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070012595
Jeff Johnson76052702013-04-16 13:55:05 -070012596 This is the driver entry point
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070012597 - delayed driver initialization when driver is statically linked
Jeff Johnson76052702013-04-16 13:55:05 -070012598 - invoked when module parameter fwpath is modified from userspace to signal
12599 initializing the WLAN driver or when con_mode is modified from userspace
12600 to signal a switch in operating mode
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070012601
12602 \return - 0 for success, non zero for failure
12603
12604 --------------------------------------------------------------------------*/
Jeff Johnson76052702013-04-16 13:55:05 -070012605static int kickstart_driver(void)
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070012606{
Madan Mohan Koyyalamudi62e60052012-10-05 14:27:22 -070012607 int ret_status;
12608
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070012609 if (!wlan_hdd_inited) {
Madan Mohan Koyyalamudi62e60052012-10-05 14:27:22 -070012610 ret_status = hdd_driver_init();
12611 wlan_hdd_inited = ret_status ? 0 : 1;
12612 return ret_status;
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070012613 }
12614
12615 hdd_driver_exit();
Jeff Johnson76052702013-04-16 13:55:05 -070012616
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070012617 msleep(200);
Jeff Johnson76052702013-04-16 13:55:05 -070012618
Madan Mohan Koyyalamudi62e60052012-10-05 14:27:22 -070012619 ret_status = hdd_driver_init();
12620 wlan_hdd_inited = ret_status ? 0 : 1;
12621 return ret_status;
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070012622}
12623
Jeff Johnson295189b2012-06-20 16:38:30 -070012624/**---------------------------------------------------------------------------
12625
Jeff Johnson76052702013-04-16 13:55:05 -070012626 \brief fwpath_changed_handler() - Handler Function
12627
12628 Handle changes to the fwpath parameter
12629
12630 \return - 0 for success, non zero for failure
12631
12632 --------------------------------------------------------------------------*/
12633static int fwpath_changed_handler(const char *kmessage,
12634 struct kernel_param *kp)
12635{
12636 int ret;
12637
12638 ret = param_set_copystring(kmessage, kp);
12639 if (0 == ret)
12640 ret = kickstart_driver();
12641 return ret;
12642}
12643
12644/**---------------------------------------------------------------------------
12645
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070012646 \brief con_mode_handler() -
12647
12648 Handler function for module param con_mode when it is changed by userspace
12649 Dynamically linked - do nothing
12650 Statically linked - exit and init driver, as in rmmod and insmod
12651
Jeff Johnson76052702013-04-16 13:55:05 -070012652 \param -
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070012653
Jeff Johnson76052702013-04-16 13:55:05 -070012654 \return -
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070012655
12656 --------------------------------------------------------------------------*/
Jeff Johnson76052702013-04-16 13:55:05 -070012657static int con_mode_handler(const char *kmessage, struct kernel_param *kp)
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070012658{
Jeff Johnson76052702013-04-16 13:55:05 -070012659 int ret;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070012660
Jeff Johnson76052702013-04-16 13:55:05 -070012661 ret = param_set_int(kmessage, kp);
12662 if (0 == ret)
12663 ret = kickstart_driver();
12664 return ret;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070012665}
12666#endif /* #ifdef MODULE */
12667
12668/**---------------------------------------------------------------------------
12669
Jeff Johnson295189b2012-06-20 16:38:30 -070012670 \brief hdd_get_conparam() -
12671
12672 This is the driver exit point (invoked when module is unloaded using rmmod)
12673
12674 \param - None
12675
12676 \return - tVOS_CON_MODE
12677
12678 --------------------------------------------------------------------------*/
12679tVOS_CON_MODE hdd_get_conparam ( void )
12680{
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070012681#ifdef MODULE
Jeff Johnson295189b2012-06-20 16:38:30 -070012682 return (tVOS_CON_MODE)con_mode;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070012683#else
12684 return (tVOS_CON_MODE)curr_con_mode;
12685#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070012686}
12687void hdd_set_conparam ( v_UINT_t newParam )
12688{
12689 con_mode = newParam;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070012690#ifndef MODULE
12691 curr_con_mode = con_mode;
12692#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070012693}
12694/**---------------------------------------------------------------------------
12695
12696 \brief hdd_softap_sta_deauth() - function
12697
12698 This to take counter measure to handle deauth req from HDD
12699
12700 \param - pAdapter - Pointer to the HDD
12701
12702 \param - enable - boolean value
12703
12704 \return - None
12705
12706 --------------------------------------------------------------------------*/
12707
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053012708VOS_STATUS hdd_softap_sta_deauth(hdd_adapter_t *pAdapter,
12709 struct tagCsrDelStaParams *pDelStaParams)
Jeff Johnson295189b2012-06-20 16:38:30 -070012710{
Jeff Johnson295189b2012-06-20 16:38:30 -070012711 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080012712 VOS_STATUS vosStatus = VOS_STATUS_E_FAULT;
Jeff Johnson295189b2012-06-20 16:38:30 -070012713
12714 ENTER();
12715
Rajesh Chauhan18488fc2013-08-22 10:15:03 -070012716 hddLog(LOG1, "hdd_softap_sta_deauth:(%p, false)",
12717 (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -070012718
12719 //Ignore request to deauth bcmc station
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053012720 if (pDelStaParams->peerMacAddr[0] & 0x1)
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080012721 return vosStatus;
Jeff Johnson295189b2012-06-20 16:38:30 -070012722
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053012723 vosStatus = WLANSAP_DeauthSta(pVosContext, pDelStaParams);
Jeff Johnson295189b2012-06-20 16:38:30 -070012724
12725 EXIT();
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080012726 return vosStatus;
Jeff Johnson295189b2012-06-20 16:38:30 -070012727}
12728
12729/**---------------------------------------------------------------------------
12730
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +053012731 \brief hdd_del_all_sta() - function
12732
12733 This function removes all the stations associated on stopping AP/P2P GO.
12734
12735 \param - pAdapter - Pointer to the HDD
12736
12737 \return - None
12738
12739 --------------------------------------------------------------------------*/
12740
12741int hdd_del_all_sta(hdd_adapter_t *pAdapter)
12742{
12743 v_U16_t i;
12744 VOS_STATUS vos_status;
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053012745 v_CONTEXT_t pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
12746 ptSapContext pSapCtx = NULL;
12747 pSapCtx = VOS_GET_SAP_CB(pVosContext);
12748 if(pSapCtx == NULL){
12749 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12750 FL("psapCtx is NULL"));
12751 return 1;
12752 }
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +053012753 ENTER();
12754
12755 hddLog(VOS_TRACE_LEVEL_INFO,
12756 "%s: Delete all STAs associated.",__func__);
12757 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
12758 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
12759 )
12760 {
12761 for(i = 0; i < WLAN_MAX_STA_COUNT; i++)
12762 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053012763 if ((pSapCtx->aStaInfo[i].isUsed) &&
12764 (!pSapCtx->aStaInfo[i].isDeauthInProgress))
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +053012765 {
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053012766 struct tagCsrDelStaParams delStaParams;
12767
12768 WLANSAP_PopulateDelStaParams(
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053012769 pSapCtx->aStaInfo[i].macAddrSTA.bytes,
Sushant Kaushik4cd28f62014-12-26 14:23:50 +053012770 eSIR_MAC_DEAUTH_LEAVING_BSS_REASON,
12771 SIR_MAC_MGMT_DEAUTH >> 4,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053012772 &delStaParams);
12773 vos_status = hdd_softap_sta_deauth(pAdapter, &delStaParams);
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +053012774 if (VOS_IS_STATUS_SUCCESS(vos_status))
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053012775 pSapCtx->aStaInfo[i].isDeauthInProgress = TRUE;
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +053012776 }
12777 }
12778 }
12779
12780 EXIT();
12781 return 0;
12782}
12783
12784/**---------------------------------------------------------------------------
12785
Jeff Johnson295189b2012-06-20 16:38:30 -070012786 \brief hdd_softap_sta_disassoc() - function
12787
12788 This to take counter measure to handle deauth req from HDD
12789
12790 \param - pAdapter - Pointer to the HDD
12791
12792 \param - enable - boolean value
12793
12794 \return - None
12795
12796 --------------------------------------------------------------------------*/
12797
12798void hdd_softap_sta_disassoc(hdd_adapter_t *pAdapter,v_U8_t *pDestMacAddress)
12799{
12800 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
12801
12802 ENTER();
12803
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +053012804 hddLog( LOGE, "hdd_softap_sta_disassoc:(%p, false)", (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -070012805
12806 //Ignore request to disassoc bcmc station
12807 if( pDestMacAddress[0] & 0x1 )
12808 return;
12809
12810 WLANSAP_DisassocSta(pVosContext,pDestMacAddress);
12811}
12812
12813void hdd_softap_tkip_mic_fail_counter_measure(hdd_adapter_t *pAdapter,v_BOOL_t enable)
12814{
12815 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
12816
12817 ENTER();
12818
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +053012819 hddLog( LOGE, "hdd_softap_tkip_mic_fail_counter_measure:(%p, false)", (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -070012820
12821 WLANSAP_SetCounterMeasure(pVosContext, (v_BOOL_t)enable);
12822}
12823
Jeff Johnson295189b2012-06-20 16:38:30 -070012824/**---------------------------------------------------------------------------
12825 *
12826 * \brief hdd_get__concurrency_mode() -
12827 *
12828 *
12829 * \param - None
12830 *
12831 * \return - CONCURRENCY MODE
12832 *
12833 * --------------------------------------------------------------------------*/
12834tVOS_CONCURRENCY_MODE hdd_get_concurrency_mode ( void )
12835{
12836 v_CONTEXT_t pVosContext = vos_get_global_context( VOS_MODULE_ID_HDD, NULL );
12837 hdd_context_t *pHddCtx;
12838
12839 if (NULL != pVosContext)
12840 {
12841 pHddCtx = vos_get_context( VOS_MODULE_ID_HDD, pVosContext);
12842 if (NULL != pHddCtx)
12843 {
12844 return (tVOS_CONCURRENCY_MODE)pHddCtx->concurrency_mode;
12845 }
12846 }
12847
12848 /* we are in an invalid state :( */
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070012849 hddLog(LOGE, "%s: Invalid context", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070012850 return VOS_STA;
12851}
Sushant Kaushikabb7ee62014-07-18 16:20:12 +053012852v_BOOL_t
12853wlan_hdd_is_GO_power_collapse_allowed (hdd_context_t* pHddCtx)
12854{
12855 hdd_adapter_t *pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070012856
Sushant Kaushikabb7ee62014-07-18 16:20:12 +053012857 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_GO);
12858 if (pAdapter == NULL)
12859 {
12860 hddLog(VOS_TRACE_LEVEL_INFO,
12861 FL("GO doesn't exist"));
12862 return TRUE;
12863 }
12864 if (test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
12865 {
12866 hddLog(VOS_TRACE_LEVEL_INFO,
12867 FL("GO started"));
12868 return TRUE;
12869 }
12870 else
12871 /* wait till GO changes its interface to p2p device */
12872 hddLog(VOS_TRACE_LEVEL_INFO,
12873 FL("Del_bss called, avoid apps suspend"));
12874 return FALSE;
12875
12876}
Jeff Johnson295189b2012-06-20 16:38:30 -070012877/* Decide whether to allow/not the apps power collapse.
12878 * Allow apps power collapse if we are in connected state.
12879 * if not, allow only if we are in IMPS */
12880v_BOOL_t hdd_is_apps_power_collapse_allowed(hdd_context_t* pHddCtx)
12881{
12882 tPmcState pmcState = pmcGetPmcState(pHddCtx->hHal);
Srikant Kuppafef66a72013-01-30 17:32:44 -080012883 tANI_BOOLEAN scanRspPending = csrNeighborRoamScanRspPending(pHddCtx->hHal);
Srinivas Girigowdaa553c462013-03-07 19:42:52 -080012884 tANI_BOOLEAN inMiddleOfRoaming = csrNeighborMiddleOfRoaming(pHddCtx->hHal);
Jeff Johnson295189b2012-06-20 16:38:30 -070012885 hdd_config_t *pConfig = pHddCtx->cfg_ini;
12886 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
12887 hdd_adapter_t *pAdapter = NULL;
12888 VOS_STATUS status;
Yathish9f22e662012-12-10 14:21:35 -080012889 tVOS_CONCURRENCY_MODE concurrent_state = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070012890
Jeff Johnson295189b2012-06-20 16:38:30 -070012891 if (VOS_STA_SAP_MODE == hdd_get_conparam())
12892 return TRUE;
Jeff Johnson295189b2012-06-20 16:38:30 -070012893
Yathish9f22e662012-12-10 14:21:35 -080012894 concurrent_state = hdd_get_concurrency_mode();
12895
Sushant Kaushikabb7ee62014-07-18 16:20:12 +053012896 if ((concurrent_state == (VOS_STA | VOS_P2P_GO)) &&
12897 !(wlan_hdd_is_GO_power_collapse_allowed(pHddCtx)))
12898 return FALSE;
Yathish9f22e662012-12-10 14:21:35 -080012899#ifdef WLAN_ACTIVEMODE_OFFLOAD_FEATURE
Sushant Kaushikabb7ee62014-07-18 16:20:12 +053012900
Yathish9f22e662012-12-10 14:21:35 -080012901 if(((concurrent_state == (VOS_STA | VOS_P2P_CLIENT)) ||
Sushant Kaushikabb7ee62014-07-18 16:20:12 +053012902 (concurrent_state == (VOS_STA | VOS_P2P_GO)))&&
Yathish9f22e662012-12-10 14:21:35 -080012903 (IS_ACTIVEMODE_OFFLOAD_FEATURE_ENABLE))
12904 return TRUE;
12905#endif
12906
Jeff Johnson295189b2012-06-20 16:38:30 -070012907 /*loop through all adapters. TBD fix for Concurrency */
12908 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
12909 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
12910 {
12911 pAdapter = pAdapterNode->pAdapter;
12912 if ( (WLAN_HDD_INFRA_STATION == pAdapter->device_mode)
12913 || (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
12914 {
Srikant Kuppafef66a72013-01-30 17:32:44 -080012915 if (((pConfig->fIsImpsEnabled || pConfig->fIsBmpsEnabled)
c_hpothu4e8faac2014-05-16 17:38:44 +053012916 && (pmcState != IMPS && pmcState != BMPS && pmcState != UAPSD
c_hpothu1c6957d2015-01-06 18:19:47 +053012917 && pmcState != STOPPED && pmcState != STANDBY &&
12918 pmcState != WOWL)) ||
Srinivas Girigowdaa553c462013-03-07 19:42:52 -080012919 (eANI_BOOLEAN_TRUE == scanRspPending) ||
12920 (eANI_BOOLEAN_TRUE == inMiddleOfRoaming))
Jeff Johnson295189b2012-06-20 16:38:30 -070012921 {
Mukul Sharma4be88422015-03-09 20:29:07 +053012922 if(pmcState == FULL_POWER &&
12923 sme_IsCoexScoIndicationSet(pHddCtx->hHal))
12924 {
12925 /*
12926 * When SCO indication comes from Coex module , host will
12927 * enter in to full power mode, but this should not prevent
12928 * apps processor power collapse.
12929 */
12930 hddLog(LOG1,
12931 FL("Allow apps power collapse"
12932 "even when sco indication is set"));
12933 return TRUE;
12934 }
Srikant Kuppafef66a72013-01-30 17:32:44 -080012935 hddLog( LOGE, "%s: do not allow APPS power collapse-"
Srinivas Girigowdaa553c462013-03-07 19:42:52 -080012936 "pmcState = %d scanRspPending = %d inMiddleOfRoaming = %d",
12937 __func__, pmcState, scanRspPending, inMiddleOfRoaming );
Jeff Johnson295189b2012-06-20 16:38:30 -070012938 return FALSE;
12939 }
12940 }
12941 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
12942 pAdapterNode = pNext;
12943 }
12944 return TRUE;
12945}
12946
Madan Mohan Koyyalamudic72a4d62012-11-08 14:59:34 -080012947/* Decides whether to send suspend notification to Riva
12948 * if any adapter is in BMPS; then it is required */
12949v_BOOL_t hdd_is_suspend_notify_allowed(hdd_context_t* pHddCtx)
12950{
12951 tPmcState pmcState = pmcGetPmcState(pHddCtx->hHal);
12952 hdd_config_t *pConfig = pHddCtx->cfg_ini;
12953
12954 if (pConfig->fIsBmpsEnabled && (pmcState == BMPS))
12955 {
12956 return TRUE;
12957 }
12958 return FALSE;
12959}
12960
Jeff Johnson295189b2012-06-20 16:38:30 -070012961void wlan_hdd_set_concurrency_mode(hdd_context_t *pHddCtx, tVOS_CON_MODE mode)
12962{
12963 switch(mode)
12964 {
Chilam Ngc4244af2013-04-01 15:37:32 -070012965 case VOS_STA_MODE:
12966 case VOS_P2P_CLIENT_MODE:
12967 case VOS_P2P_GO_MODE:
12968 case VOS_STA_SAP_MODE:
Jeff Johnsone7245742012-09-05 17:12:55 -070012969 pHddCtx->concurrency_mode |= (1 << mode);
Agarwal Ashish51325b52014-06-16 16:50:49 +053012970 pHddCtx->no_of_open_sessions[mode]++;
Jeff Johnson295189b2012-06-20 16:38:30 -070012971 break;
12972 default:
12973 break;
Jeff Johnson295189b2012-06-20 16:38:30 -070012974 }
Agarwal Ashish51325b52014-06-16 16:50:49 +053012975 hddLog(VOS_TRACE_LEVEL_INFO, FL("concurrency_mode = 0x%x "
12976 "Number of open sessions for mode %d = %d"),
12977 pHddCtx->concurrency_mode, mode,
12978 pHddCtx->no_of_open_sessions[mode]);
Jeff Johnson295189b2012-06-20 16:38:30 -070012979}
12980
12981
12982void wlan_hdd_clear_concurrency_mode(hdd_context_t *pHddCtx, tVOS_CON_MODE mode)
12983{
12984 switch(mode)
12985 {
Chilam Ngc4244af2013-04-01 15:37:32 -070012986 case VOS_STA_MODE:
12987 case VOS_P2P_CLIENT_MODE:
12988 case VOS_P2P_GO_MODE:
12989 case VOS_STA_SAP_MODE:
Agarwal Ashish51325b52014-06-16 16:50:49 +053012990 pHddCtx->no_of_open_sessions[mode]--;
12991 if (!(pHddCtx->no_of_open_sessions[mode]))
12992 pHddCtx->concurrency_mode &= (~(1 << mode));
Jeff Johnson295189b2012-06-20 16:38:30 -070012993 break;
12994 default:
12995 break;
12996 }
Agarwal Ashish51325b52014-06-16 16:50:49 +053012997 hddLog(VOS_TRACE_LEVEL_INFO, FL("concurrency_mode = 0x%x "
12998 "Number of open sessions for mode %d = %d"),
12999 pHddCtx->concurrency_mode, mode, pHddCtx->no_of_open_sessions[mode]);
13000
13001}
13002/**---------------------------------------------------------------------------
13003 *
13004 * \brief wlan_hdd_incr_active_session()
13005 *
13006 * This function increments the number of active sessions
13007 * maintained per device mode
13008 * Incase of STA/P2P CLI/IBSS upon connection indication it is incremented
13009 * Incase of SAP/P2P GO upon bss start it is incremented
13010 *
13011 * \param pHddCtx - HDD Context
13012 * \param mode - device mode
13013 *
13014 * \return - None
13015 *
13016 * --------------------------------------------------------------------------*/
13017void wlan_hdd_incr_active_session(hdd_context_t *pHddCtx, tVOS_CON_MODE mode)
13018{
13019 switch (mode) {
13020 case VOS_STA_MODE:
13021 case VOS_P2P_CLIENT_MODE:
13022 case VOS_P2P_GO_MODE:
13023 case VOS_STA_SAP_MODE:
13024 pHddCtx->no_of_active_sessions[mode]++;
13025 break;
13026 default:
13027 hddLog(VOS_TRACE_LEVEL_INFO, FL("Not Expected Mode %d"), mode);
13028 break;
13029 }
13030 hddLog(VOS_TRACE_LEVEL_INFO, FL("No.# of active sessions for mode %d = %d"),
13031 mode,
13032 pHddCtx->no_of_active_sessions[mode]);
13033}
13034
13035/**---------------------------------------------------------------------------
13036 *
13037 * \brief wlan_hdd_decr_active_session()
13038 *
13039 * This function decrements the number of active sessions
13040 * maintained per device mode
13041 * Incase of STA/P2P CLI/IBSS upon disconnection it is decremented
13042 * Incase of SAP/P2P GO upon bss stop it is decremented
13043 *
13044 * \param pHddCtx - HDD Context
13045 * \param mode - device mode
13046 *
13047 * \return - None
13048 *
13049 * --------------------------------------------------------------------------*/
13050void wlan_hdd_decr_active_session(hdd_context_t *pHddCtx, tVOS_CON_MODE mode)
13051{
Bhargav Shahd0715912015-10-01 18:17:37 +053013052
Agarwal Ashish51325b52014-06-16 16:50:49 +053013053 switch (mode) {
13054 case VOS_STA_MODE:
13055 case VOS_P2P_CLIENT_MODE:
13056 case VOS_P2P_GO_MODE:
13057 case VOS_STA_SAP_MODE:
Agarwal Ashish5325f522014-08-06 00:58:44 +053013058 if (pHddCtx->no_of_active_sessions[mode] > 0)
13059 pHddCtx->no_of_active_sessions[mode]--;
13060 else
13061 hddLog(VOS_TRACE_LEVEL_INFO, FL(" No.# of Active sessions"
13062 "is already Zero"));
Agarwal Ashish51325b52014-06-16 16:50:49 +053013063 break;
13064 default:
13065 hddLog(VOS_TRACE_LEVEL_INFO, FL("Not Expected Mode %d"), mode);
13066 break;
13067 }
13068 hddLog(VOS_TRACE_LEVEL_INFO, FL("No.# of active sessions for mode %d = %d"),
13069 mode,
13070 pHddCtx->no_of_active_sessions[mode]);
Jeff Johnson295189b2012-06-20 16:38:30 -070013071}
13072
Jeff Johnsone7245742012-09-05 17:12:55 -070013073/**---------------------------------------------------------------------------
13074 *
13075 * \brief wlan_hdd_restart_init
13076 *
13077 * This function initalizes restart timer/flag. An internal function.
13078 *
13079 * \param - pHddCtx
13080 *
13081 * \return - None
13082 *
13083 * --------------------------------------------------------------------------*/
13084
13085static void wlan_hdd_restart_init(hdd_context_t *pHddCtx)
13086{
13087 /* Initialize */
13088 pHddCtx->hdd_restart_retries = 0;
13089 atomic_set(&pHddCtx->isRestartInProgress, 0);
13090 vos_timer_init(&pHddCtx->hdd_restart_timer,
13091 VOS_TIMER_TYPE_SW,
13092 wlan_hdd_restart_timer_cb,
13093 pHddCtx);
13094}
13095/**---------------------------------------------------------------------------
13096 *
13097 * \brief wlan_hdd_restart_deinit
13098 *
13099 * This function cleans up the resources used. An internal function.
13100 *
13101 * \param - pHddCtx
13102 *
13103 * \return - None
13104 *
13105 * --------------------------------------------------------------------------*/
13106
13107static void wlan_hdd_restart_deinit(hdd_context_t* pHddCtx)
13108{
13109
13110 VOS_STATUS vos_status;
13111 /* Block any further calls */
13112 atomic_set(&pHddCtx->isRestartInProgress, 1);
13113 /* Cleanup */
13114 vos_status = vos_timer_stop( &pHddCtx->hdd_restart_timer );
13115 if (!VOS_IS_STATUS_SUCCESS(vos_status))
c_hpothu6ff1c3c2013-10-01 19:01:57 +053013116 hddLog(LOGE, FL("Failed to stop HDD restart timer"));
Jeff Johnsone7245742012-09-05 17:12:55 -070013117 vos_status = vos_timer_destroy(&pHddCtx->hdd_restart_timer);
13118 if (!VOS_IS_STATUS_SUCCESS(vos_status))
c_hpothu6ff1c3c2013-10-01 19:01:57 +053013119 hddLog(LOGE, FL("Failed to destroy HDD restart timer"));
Jeff Johnsone7245742012-09-05 17:12:55 -070013120
13121}
13122
13123/**---------------------------------------------------------------------------
13124 *
13125 * \brief wlan_hdd_framework_restart
13126 *
13127 * This function uses a cfg80211 API to start a framework initiated WLAN
13128 * driver module unload/load.
13129 *
13130 * Also this API keep retrying (WLAN_HDD_RESTART_RETRY_MAX_CNT).
13131 *
13132 *
13133 * \param - pHddCtx
13134 *
13135 * \return - VOS_STATUS_SUCCESS: Success
13136 * VOS_STATUS_E_EMPTY: Adapter is Empty
13137 * VOS_STATUS_E_NOMEM: No memory
13138
13139 * --------------------------------------------------------------------------*/
13140
13141static VOS_STATUS wlan_hdd_framework_restart(hdd_context_t *pHddCtx)
13142{
13143 VOS_STATUS status = VOS_STATUS_SUCCESS;
13144 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
Madan Mohan Koyyalamudifc19e442013-05-09 18:24:08 -070013145 int len = (sizeof (struct ieee80211_mgmt));
13146 struct ieee80211_mgmt *mgmt = NULL;
13147
13148 /* Prepare the DEAUTH managment frame with reason code */
13149 mgmt = kzalloc(len, GFP_KERNEL);
13150 if(mgmt == NULL)
13151 {
13152 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
13153 "%s: memory allocation failed (%d bytes)", __func__, len);
13154 return VOS_STATUS_E_NOMEM;
13155 }
13156 mgmt->u.deauth.reason_code = WLAN_REASON_DISASSOC_LOW_ACK;
Jeff Johnsone7245742012-09-05 17:12:55 -070013157
13158 /* Iterate over all adapters/devices */
13159 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
Hanumantha Reddy Pothulada0fe362015-02-27 18:37:03 +053013160 if ((NULL == pAdapterNode) || (VOS_STATUS_SUCCESS != status))
13161 {
13162 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13163 FL("fail to get adapter: %p %d"), pAdapterNode, status);
13164 goto end;
13165 }
13166
Jeff Johnsone7245742012-09-05 17:12:55 -070013167 do
13168 {
Hanumantha Reddy Pothulada0fe362015-02-27 18:37:03 +053013169 if(pAdapterNode->pAdapter &&
13170 WLAN_HDD_ADAPTER_MAGIC == pAdapterNode->pAdapter->magic)
Jeff Johnsone7245742012-09-05 17:12:55 -070013171 {
13172 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
13173 "restarting the driver(intf:\'%s\' mode:%d :try %d)",
13174 pAdapterNode->pAdapter->dev->name,
13175 pAdapterNode->pAdapter->device_mode,
13176 pHddCtx->hdd_restart_retries + 1);
Madan Mohan Koyyalamudifc19e442013-05-09 18:24:08 -070013177 /*
13178 * CFG80211 event to restart the driver
13179 *
13180 * 'cfg80211_send_unprot_deauth' sends a
13181 * NL80211_CMD_UNPROT_DEAUTHENTICATE event to supplicant at any state
13182 * of SME(Linux Kernel) state machine.
13183 *
13184 * Reason code WLAN_REASON_DISASSOC_LOW_ACK is currently used to restart
13185 * the driver.
13186 *
13187 */
Abhishek Singh00b71972016-01-07 10:51:04 +053013188
Anand N Sunkade9adb1b2015-07-29 09:56:45 +053013189#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 11, 0))
13190 cfg80211_rx_unprot_mlme_mgmt(pAdapterNode->pAdapter->dev, (u_int8_t*)mgmt, len);
13191#else
Madan Mohan Koyyalamudifc19e442013-05-09 18:24:08 -070013192 cfg80211_send_unprot_deauth(pAdapterNode->pAdapter->dev, (u_int8_t*)mgmt, len );
Anand N Sunkade9adb1b2015-07-29 09:56:45 +053013193#endif
Jeff Johnsone7245742012-09-05 17:12:55 -070013194 }
13195 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
13196 pAdapterNode = pNext;
13197 } while((NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status));
13198
Hanumantha Reddy Pothulada0fe362015-02-27 18:37:03 +053013199 end:
Madan Mohan Koyyalamudifc19e442013-05-09 18:24:08 -070013200 /* Free the allocated management frame */
13201 kfree(mgmt);
13202
Jeff Johnsone7245742012-09-05 17:12:55 -070013203 /* Retry until we unload or reach max count */
13204 if(++pHddCtx->hdd_restart_retries < WLAN_HDD_RESTART_RETRY_MAX_CNT)
13205 vos_timer_start(&pHddCtx->hdd_restart_timer, WLAN_HDD_RESTART_RETRY_DELAY_MS);
13206
13207 return status;
13208
13209}
13210/**---------------------------------------------------------------------------
13211 *
13212 * \brief wlan_hdd_restart_timer_cb
13213 *
13214 * Restart timer callback. An internal function.
13215 *
13216 * \param - User data:
13217 *
13218 * \return - None
13219 *
13220 * --------------------------------------------------------------------------*/
13221
13222void wlan_hdd_restart_timer_cb(v_PVOID_t usrDataForCallback)
13223{
13224 hdd_context_t *pHddCtx = usrDataForCallback;
13225 wlan_hdd_framework_restart(pHddCtx);
13226 return;
13227
13228}
13229
13230
13231/**---------------------------------------------------------------------------
13232 *
13233 * \brief wlan_hdd_restart_driver
13234 *
13235 * This function sends an event to supplicant to restart the WLAN driver.
13236 *
13237 * This function is called from vos_wlanRestart.
13238 *
13239 * \param - pHddCtx
13240 *
13241 * \return - VOS_STATUS_SUCCESS: Success
13242 * VOS_STATUS_E_EMPTY: Adapter is Empty
13243 * VOS_STATUS_E_ALREADY: Request already in progress
13244
13245 * --------------------------------------------------------------------------*/
13246VOS_STATUS wlan_hdd_restart_driver(hdd_context_t *pHddCtx)
13247{
13248 VOS_STATUS status = VOS_STATUS_SUCCESS;
13249
13250 /* A tight check to make sure reentrancy */
13251 if(atomic_xchg(&pHddCtx->isRestartInProgress, 1))
13252 {
Mihir Shetefd528652014-06-23 19:07:50 +053013253 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnsone7245742012-09-05 17:12:55 -070013254 "%s: WLAN restart is already in progress", __func__);
13255
13256 return VOS_STATUS_E_ALREADY;
13257 }
Sameer Thalappil0c164f52013-03-28 15:27:56 -070013258 /* Send reset FIQ to WCNSS to invoke SSR. */
Madan Mohan Koyyalamudie388b342012-11-08 15:03:16 -080013259#ifdef HAVE_WCNSS_RESET_INTR
Siddharth Bhal864e7e82015-04-07 20:07:24 +053013260 wcnss_reset_fiq(TRUE);
Madan Mohan Koyyalamudibb8f0172012-09-28 15:36:06 -070013261#endif
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -070013262
Jeff Johnsone7245742012-09-05 17:12:55 -070013263 return status;
13264}
13265
Bhargav Shahd0715912015-10-01 18:17:37 +053013266/**
13267 * hdd_get_total_sessions() - provide total number of active sessions
13268 * @pHddCtx: Valid Global HDD context pointer
13269 *
13270 * This function iterates through pAdaptors and find the number of all active
13271 * sessions. This active sessions includes connected sta, p2p client and number
13272 * of client connected to sap/p2p go.
13273 *
13274 * Return: Total number of active sessions.
13275 */
13276v_U8_t hdd_get_total_sessions(hdd_context_t *pHddCtx)
13277{
13278 v_U8_t active_session = 0;
13279 hdd_station_ctx_t *pHddStaCtx;
13280 hdd_adapter_list_node_t *pAdapterNode, *pNext;
13281 hdd_adapter_t *pAdapter;
13282 VOS_STATUS status;
13283
13284 status = hdd_get_front_adapter(pHddCtx, &pAdapterNode);
13285 while (NULL != pAdapterNode && VOS_STATUS_SUCCESS == status) {
13286 pAdapter = pAdapterNode->pAdapter;
13287 switch (pAdapter->device_mode) {
13288 case VOS_STA_MODE:
13289 case VOS_P2P_CLIENT_MODE:
13290 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
13291 if(eConnectionState_Associated == pHddStaCtx->conn_info.connState)
13292 active_session += 1;
13293 break;
13294 case VOS_STA_SAP_MODE:
13295 case VOS_P2P_GO_MODE:
13296 active_session += hdd_softap_get_connected_sta(pAdapter);
13297 break;
13298 default:
13299 break;
13300 }
13301
13302 status = hdd_get_next_adapter(pHddCtx, pAdapterNode, &pNext);
13303 pAdapterNode = pNext;
13304 }
13305
13306 return active_session;
13307}
13308
13309/**
13310 * hdd_set_delack_value() - Set delack value
13311 * @pHddCtx: Valid Global HDD context pointer
13312 * @next_rx_level: Value to set for delack
13313 *
13314 * This function compare present value and next value of delack. If the both
13315 * are diffrent then it sets next value .
13316 *
13317 * Return: void.
13318 */
13319void hdd_set_delack_value(hdd_context_t *pHddCtx, v_U32_t next_rx_level)
13320{
13321 if (pHddCtx->cur_rx_level != next_rx_level) {
13322 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_DEBUG,
13323 "%s: TCP DELACK trigger level %d",
13324 __func__, next_rx_level);
13325 mutex_lock(&pHddCtx->cur_rx_level_lock);
13326 pHddCtx->cur_rx_level = next_rx_level;
13327 mutex_unlock(&pHddCtx->cur_rx_level_lock);
13328 wlan_hdd_send_svc_nlink_msg(WLAN_SVC_WLAN_TP_IND, &next_rx_level,
13329 sizeof(next_rx_level));
13330 }
13331}
13332
13333/**
13334 * hdd_set_default_stop_delack_timer() - Start delack timer
13335 * @pHddCtx: Valid Global HDD context pointer
13336 *
13337 * This function stop delack timer and set delack value to default..
13338 *
13339 * Return: void.
13340 */
13341
13342void hdd_set_default_stop_delack_timer(hdd_context_t *pHddCtx)
13343{
13344 if (VOS_TIMER_STATE_RUNNING !=
13345 vos_timer_getCurrentState(&pHddCtx->delack_timer)) {
13346 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_DEBUG,
13347 "%s: Can not stop timer", __func__);
13348 return;
13349 }
13350
13351 vos_timer_stop(&pHddCtx->delack_timer);
13352 hdd_set_delack_value(pHddCtx, TP_IND_LOW);
13353}
13354
13355/**
13356 * hdd_start_delack_timer() - Start delack timer
13357 * @pHddCtx: Valid Global HDD context pointer
13358 *
13359 * This function starts the delack timer for tcpDelAckComputeInterval time
13360 * interval.The default timer value is 2 second.
13361 *
13362 * Return: void.
13363 */
13364void hdd_start_delack_timer(hdd_context_t *pHddCtx)
13365{
13366 if (VOS_TIMER_STATE_RUNNING ==
13367 vos_timer_getCurrentState(&pHddCtx->delack_timer)) {
13368 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_DEBUG,
13369 "%s: Timer is already running", __func__);
13370 return;
13371 }
13372
13373 vos_timer_start(&pHddCtx->delack_timer,
13374 pHddCtx->cfg_ini->tcpDelAckComputeInterval);
13375}
13376
13377/**
13378 * hdd_update_prev_rx_packet_count() - Update previous rx packet count
13379 * @pHddCtx: Valid Global HDD context pointer
13380 *
13381 * This function updates the prev_rx_packets count from the corresponding
13382 * pAdapter states. This prev_rx_packets will diffed with the packet count
13383 * at the end of delack timer. That can give number of RX packet is spacific
13384 * time.
13385 *
13386 * Return: void.
13387 */
13388void hdd_update_prev_rx_packet_count(hdd_context_t *pHddCtx)
13389{
13390 hdd_adapter_list_node_t *pAdapterNode, *pNext;
13391 hdd_adapter_t *pAdapter;
13392 VOS_STATUS status;
13393
13394 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
13395 while (NULL != pAdapterNode && VOS_STATUS_SUCCESS == status) {
13396 pAdapter = pAdapterNode->pAdapter;
13397 pAdapter->prev_rx_packets = pAdapter->stats.rx_packets;
13398 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
13399 pAdapterNode = pNext;
13400 }
13401}
13402
13403/**
13404 * hdd_manage_delack_timer() - start\stop delack timer
13405 * @pHddCtx: Valid Global HDD context pointer
13406 *
13407 * This function check the number of concerent session present, it starts the
13408 * delack timer if only one session is present.
13409 * In the case of BT_COEX and TDLS mode it blindly stop delack functionality.
13410 *
13411 * Return: void.
13412 */
13413void hdd_manage_delack_timer(hdd_context_t *pHddCtx)
13414{
13415 uint8_t sessions;
13416
13417 if (!pHddCtx->cfg_ini->enable_delack) {
13418 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_DEBUG,
13419 "%s: TCP DELACK is not enabled", __func__);
13420 return;
13421 }
13422
13423 /* Blindly stop timer of BTCOEX and TDLS Session is up */
13424 if (pHddCtx->mode != 0) {
13425 hdd_set_default_stop_delack_timer(pHddCtx);
13426 return;
13427 }
13428
13429 sessions = hdd_get_total_sessions(pHddCtx);
13430 if (sessions == 1) {
13431 hdd_update_prev_rx_packet_count(pHddCtx);
13432 hdd_start_delack_timer(pHddCtx);
13433 } else {
13434 hdd_set_default_stop_delack_timer(pHddCtx);
13435 }
13436}
13437
Mihir Shetee1093ba2014-01-21 20:13:32 +053013438/**---------------------------------------------------------------------------
13439 *
13440 * \brief wlan_hdd_init_channels
13441 *
13442 * This function is used to initialize the channel list in CSR
13443 *
13444 * This function is called from hdd_wlan_startup
13445 *
13446 * \param - pHddCtx: HDD context
13447 *
13448 * \return - VOS_STATUS_SUCCESS: Success
13449 * VOS_STATUS_E_FAULT: Failure reported by SME
13450
13451 * --------------------------------------------------------------------------*/
13452static VOS_STATUS wlan_hdd_init_channels(hdd_context_t *pHddCtx)
13453{
13454 eHalStatus status;
13455
13456 status = sme_InitChannels(pHddCtx->hHal);
13457 if (HAL_STATUS_SUCCESS(status))
13458 {
13459 return VOS_STATUS_SUCCESS;
13460 }
13461 else
13462 {
13463 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Channel initialization failed(%d)",
13464 __func__, status);
13465 return VOS_STATUS_E_FAULT;
13466 }
13467}
13468
Mihir Shete04206452014-11-20 17:50:58 +053013469#ifdef CONFIG_ENABLE_LINUX_REG
Agarwal Ashish6db9d532014-09-30 18:19:10 +053013470VOS_STATUS wlan_hdd_init_channels_for_cc(hdd_context_t *pHddCtx, driver_load_type init )
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053013471{
13472 eHalStatus status;
13473
Agarwal Ashish6db9d532014-09-30 18:19:10 +053013474 status = sme_InitChannelsForCC(pHddCtx->hHal, init);
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053013475 if (HAL_STATUS_SUCCESS(status))
13476 {
13477 return VOS_STATUS_SUCCESS;
13478 }
13479 else
13480 {
13481 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Issue reg hint failed(%d)",
13482 __func__, status);
13483 return VOS_STATUS_E_FAULT;
13484 }
13485}
Mihir Shete04206452014-11-20 17:50:58 +053013486#endif
Sudhir Sattayappa Kohallib1d8c3a2013-06-18 14:47:20 -070013487/*
13488 * API to find if there is any STA or P2P-Client is connected
13489 */
13490VOS_STATUS hdd_issta_p2p_clientconnected(hdd_context_t *pHddCtx)
13491{
13492 return sme_isSta_p2p_clientConnected(pHddCtx->hHal);
13493}
Jeff Johnsone7245742012-09-05 17:12:55 -070013494
Mihir Shetee2ae82a2015-03-16 14:08:49 +053013495
13496/*
13497 * API to find if the firmware will send logs using DXE channel
13498 */
13499v_U8_t hdd_is_fw_logging_enabled(void)
13500{
13501 hdd_context_t *pHddCtx;
13502
13503 pHddCtx = vos_get_context(VOS_MODULE_ID_HDD,
13504 vos_get_global_context(VOS_MODULE_ID_HDD, NULL));
13505
Sachin Ahuja084313e2015-05-21 17:57:10 +053013506 return (pHddCtx && pHddCtx->cfg_ini->enableMgmtLogging);
Mihir Shetee2ae82a2015-03-16 14:08:49 +053013507}
13508
Agarwal Ashish57e84372014-12-05 18:26:53 +053013509/*
Mihir Shetebe94ebb2015-05-26 12:07:14 +053013510 * API to find if the firmware will send trace logs using DXE channel
13511 */
13512v_U8_t hdd_is_fw_ev_logging_enabled(void)
13513{
13514 hdd_context_t *pHddCtx;
13515
13516 pHddCtx = vos_get_context(VOS_MODULE_ID_HDD,
13517 vos_get_global_context(VOS_MODULE_ID_HDD, NULL));
13518
13519 return (pHddCtx && pHddCtx->cfg_ini->enableFWLogging);
13520}
13521/*
Agarwal Ashish57e84372014-12-05 18:26:53 +053013522 * API to find if there is any session connected
13523 */
13524VOS_STATUS hdd_is_any_session_connected(hdd_context_t *pHddCtx)
13525{
13526 return sme_is_any_session_connected(pHddCtx->hHal);
13527}
13528
13529
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053013530int wlan_hdd_scan_abort(hdd_adapter_t *pAdapter)
13531{
13532 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
13533 hdd_scaninfo_t *pScanInfo = NULL;
Girish Gowli4bf7a632014-06-12 13:42:11 +053013534 long status = 0;
c_hpothua3d45d52015-01-05 14:11:17 +053013535 tSirAbortScanStatus abortScanStatus;
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053013536
13537 pScanInfo = &pHddCtx->scan_info;
Ratnam Rachuric7681132015-06-30 10:35:13 +053013538 INIT_COMPLETION(pScanInfo->abortscan_event_var);
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053013539 if (pScanInfo->mScanPending)
13540 {
c_hpothua3d45d52015-01-05 14:11:17 +053013541 abortScanStatus = hdd_abort_mac_scan(pHddCtx, pScanInfo->sessionId,
13542 eCSR_SCAN_ABORT_DEFAULT);
13543 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13544 FL("abortScanStatus: %d"), abortScanStatus);
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053013545
c_hpothua3d45d52015-01-05 14:11:17 +053013546 /* If there is active scan command lets wait for the completion else
13547 * there is no need to wait as scan command might be in the SME pending
13548 * command list.
13549 */
13550 if (abortScanStatus == eSIR_ABORT_ACTIVE_SCAN_LIST_NOT_EMPTY)
13551 {
c_hpothua3d45d52015-01-05 14:11:17 +053013552 status = wait_for_completion_interruptible_timeout(
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053013553 &pScanInfo->abortscan_event_var,
13554 msecs_to_jiffies(5000));
c_hpothua3d45d52015-01-05 14:11:17 +053013555 if (0 >= status)
13556 {
13557 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Girish Gowli4bf7a632014-06-12 13:42:11 +053013558 "%s: Timeout or Interrupt occurred while waiting for abort"
13559 "scan, status- %ld", __func__, status);
c_hpothua3d45d52015-01-05 14:11:17 +053013560 return -ETIMEDOUT;
13561 }
13562 }
13563 else if (abortScanStatus == eSIR_ABORT_SCAN_FAILURE)
13564 {
13565 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13566 FL("hdd_abort_mac_scan failed"));
13567 return -VOS_STATUS_E_FAILURE;
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053013568 }
13569 }
Girish Gowli4bf7a632014-06-12 13:42:11 +053013570 return 0;
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053013571}
13572
Abhishek Singh7d624e12015-11-30 14:29:27 +053013573/**
13574 * hdd_indicate_mgmt_frame() - Wrapper to indicate management frame to
13575 * user space
13576 * @frame_ind: Management frame data to be informed.
13577 *
13578 * This function is used to indicate management frame to
13579 * user space
13580 *
13581 * Return: None
13582 *
13583 */
13584void hdd_indicate_mgmt_frame(tSirSmeMgmtFrameInd *frame_ind)
13585{
13586 hdd_context_t *hdd_ctx = NULL;
13587 hdd_adapter_t *adapter = NULL;
13588 v_CONTEXT_t vos_context = NULL;
13589
13590 /* Get the global VOSS context.*/
13591 vos_context = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
13592 if (!vos_context) {
13593 hddLog(LOGE, FL("Global VOS context is Null"));
13594 return;
13595 }
13596 /* Get the HDD context.*/
13597 hdd_ctx =
13598 (hdd_context_t *)vos_get_context(VOS_MODULE_ID_HDD, vos_context );
13599
13600 if (0 != wlan_hdd_validate_context(hdd_ctx))
13601 {
13602 return;
13603 }
13604 adapter = hdd_get_adapter_by_sme_session_id(hdd_ctx,
13605 frame_ind->sessionId);
13606
13607 if ((NULL != adapter) &&
13608 (WLAN_HDD_ADAPTER_MAGIC == adapter->magic))
13609 __hdd_indicate_mgmt_frame(adapter,
13610 frame_ind->frameLen,
13611 frame_ind->frameBuf,
13612 frame_ind->frameType,
13613 frame_ind->rxChan,
13614 frame_ind->rxRssi);
13615 return;
13616
13617}
13618
c_hpothu225aa7c2014-10-22 17:45:13 +053013619VOS_STATUS wlan_hdd_cancel_remain_on_channel(hdd_context_t *pHddCtx)
13620{
13621 hdd_adapter_t *pAdapter;
13622 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
13623 VOS_STATUS vosStatus;
13624
13625 vosStatus = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
13626 while (NULL != pAdapterNode && VOS_STATUS_E_EMPTY != vosStatus)
13627 {
13628 pAdapter = pAdapterNode->pAdapter;
13629 if (NULL != pAdapter)
13630 {
13631 if (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode ||
13632 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode ||
13633 WLAN_HDD_P2P_GO == pAdapter->device_mode)
13634 {
13635 hddLog(LOG1, FL("abort ROC deviceMode: %d"),
13636 pAdapter->device_mode);
13637 if (VOS_STATUS_SUCCESS !=
13638 wlan_hdd_cancel_existing_remain_on_channel(pAdapter))
13639 {
13640 hddLog(LOGE, FL("failed to abort ROC"));
13641 return VOS_STATUS_E_FAILURE;
13642 }
13643 }
13644 }
13645 vosStatus = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
13646 pAdapterNode = pNext;
13647 }
13648 return VOS_STATUS_SUCCESS;
13649}
Mahesh A Saptasagard477b092015-02-06 15:12:16 +053013650
Mihir Shete0be28772015-02-17 18:42:14 +053013651hdd_remain_on_chan_ctx_t *hdd_get_remain_on_channel_ctx(hdd_context_t *pHddCtx)
13652{
13653 hdd_adapter_t *pAdapter;
13654 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
13655 hdd_cfg80211_state_t *cfgState;
13656 hdd_remain_on_chan_ctx_t *pRemainChanCtx = NULL;
13657 VOS_STATUS vosStatus;
13658
13659 vosStatus = hdd_get_front_adapter (pHddCtx, &pAdapterNode);
13660 while (NULL != pAdapterNode && VOS_STATUS_E_EMPTY != vosStatus)
13661 {
13662 pAdapter = pAdapterNode->pAdapter;
13663 if (NULL != pAdapter)
13664 {
13665 cfgState = WLAN_HDD_GET_CFG_STATE_PTR(pAdapter);
13666 pRemainChanCtx = cfgState->remain_on_chan_ctx;
13667 if (pRemainChanCtx)
13668 break;
13669 }
13670 vosStatus = hdd_get_next_adapter (pHddCtx, pAdapterNode, &pNext);
13671 pAdapterNode = pNext;
13672 }
13673 return pRemainChanCtx;
13674}
13675
Padma, Santhosh Kumar778d8382015-03-04 17:41:22 +053013676/**
13677 * wlan_hdd_handle_dfs_chan_scan () - handles disable/enable DFS channels
13678 *
13679 * @pHddCtx: HDD context within host driver
13680 * @dfsScanMode: dfsScanMode passed from ioctl
13681 *
13682 */
13683
13684VOS_STATUS wlan_hdd_handle_dfs_chan_scan(hdd_context_t *pHddCtx,
13685 tANI_U8 dfsScanMode)
13686{
13687 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
13688 hdd_adapter_t *pAdapter;
13689 VOS_STATUS vosStatus;
13690 hdd_station_ctx_t *pHddStaCtx;
13691 eHalStatus status = eHAL_STATUS_SUCCESS;
13692
13693 if(!pHddCtx)
13694 {
13695 hddLog(LOGE, FL("HDD context is Null"));
13696 return eHAL_STATUS_FAILURE;
13697 }
13698
13699 if (pHddCtx->scan_info.mScanPending)
13700 {
13701 hddLog(LOG1, FL("Aborting scan for sessionId: %d"),
13702 pHddCtx->scan_info.sessionId);
13703 hdd_abort_mac_scan(pHddCtx,
13704 pHddCtx->scan_info.sessionId,
13705 eCSR_SCAN_ABORT_DEFAULT);
13706 }
13707
13708 if (!dfsScanMode)
13709 {
13710 vosStatus = hdd_get_front_adapter( pHddCtx, &pAdapterNode);
13711 while ((NULL != pAdapterNode) &&
13712 (VOS_STATUS_SUCCESS == vosStatus))
13713 {
13714 pAdapter = pAdapterNode->pAdapter;
13715
13716 if (WLAN_HDD_INFRA_STATION == pAdapter->device_mode)
13717 {
13718 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
13719
13720 if(!pHddStaCtx)
13721 {
13722 hddLog(LOGE, FL("HDD STA context is Null"));
13723 return eHAL_STATUS_FAILURE;
13724 }
13725
13726 /* if STA is already connected on DFS channel,
13727 disconnect immediately*/
13728 if (hdd_connIsConnected(pHddStaCtx) &&
13729 (NV_CHANNEL_DFS ==
13730 vos_nv_getChannelEnabledState(
13731 pHddStaCtx->conn_info.operationChannel)))
13732 {
13733 status = sme_RoamDisconnect(pHddCtx->hHal,
13734 pAdapter->sessionId,
13735 eCSR_DISCONNECT_REASON_UNSPECIFIED);
13736 hddLog(LOG1, FL("Client connected on DFS channel %d,"
13737 "sme_RoamDisconnect returned with status: %d"
13738 "for sessionid: %d"), pHddStaCtx->conn_info.
13739 operationChannel, status, pAdapter->sessionId);
13740 }
13741 }
13742
13743 vosStatus = hdd_get_next_adapter(pHddCtx, pAdapterNode,
13744 &pNext);
13745 pAdapterNode = pNext;
13746 }
13747 }
13748
13749 sme_UpdateDFSScanMode(pHddCtx->hHal, dfsScanMode);
13750 sme_UpdateDFSRoamMode(pHddCtx->hHal,
13751 (dfsScanMode != DFS_CHNL_SCAN_DISABLED));
13752
13753 status = sme_HandleDFSChanScan(pHddCtx->hHal);
13754 if (!HAL_STATUS_SUCCESS(status))
13755 {
13756 hddLog(LOGE,
13757 FL("Failed in sme_HandleDFSChanScan (err=%d)"), status);
13758 return status;
13759 }
13760
13761 return status;
13762}
13763
Nirav Shah7e3c8132015-06-22 23:51:42 +053013764static int hdd_log2_ceil(unsigned value)
13765{
13766 /* need to switch to unsigned math so that negative values
13767 * will right-shift towards 0 instead of -1
13768 */
13769 unsigned tmp = value;
13770 int log2 = -1;
13771
13772 if (value == 0)
13773 return 0;
13774
13775 while (tmp) {
13776 log2++;
13777 tmp >>= 1;
13778 }
13779 if (1U << log2 != value)
13780 log2++;
13781
13782 return log2;
13783}
13784
13785/**
13786 * hdd_sta_id_hash_attach() - initialize sta id to macaddr hash
13787 * @pAdapter: adapter handle
13788 *
13789 * Return: vos status
13790 */
13791VOS_STATUS hdd_sta_id_hash_attach(hdd_adapter_t *pAdapter)
13792{
13793 int hash_elem, log2, i;
13794
13795 spin_lock_bh( &pAdapter->sta_hash_lock);
13796 if (pAdapter->is_sta_id_hash_initialized == VOS_TRUE) {
13797 spin_unlock_bh( &pAdapter->sta_hash_lock);
13798 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13799 "%s: hash already attached for session id %d",
13800 __func__, pAdapter->sessionId);
13801 return VOS_STATUS_SUCCESS;
13802 }
13803 spin_unlock_bh( &pAdapter->sta_hash_lock);
13804
13805 hash_elem = WLAN_MAX_STA_COUNT;
13806 hash_elem *= HDD_STA_ID_HASH_MULTIPLIER;
13807 log2 = hdd_log2_ceil(hash_elem);
13808 hash_elem = 1 << log2;
13809
13810 pAdapter->sta_id_hash.mask = hash_elem - 1;
13811 pAdapter->sta_id_hash.idx_bits = log2;
13812 pAdapter->sta_id_hash.bins =
13813 vos_mem_malloc(hash_elem *sizeof(hdd_list_t));
13814 if (!pAdapter->sta_id_hash.bins) {
13815 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13816 "%s: malloc failed for session %d",
13817 __func__, pAdapter->sessionId);
13818 return VOS_STATUS_E_NOMEM;
13819 }
13820
13821 for (i = 0; i < hash_elem; i++)
13822 hdd_list_init(&pAdapter->sta_id_hash.bins[i], WLAN_MAX_STA_COUNT);
13823
13824 spin_lock_bh( &pAdapter->sta_hash_lock);
13825 pAdapter->is_sta_id_hash_initialized = VOS_TRUE;
13826 spin_unlock_bh( &pAdapter->sta_hash_lock);
13827 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13828 "%s: Station ID Hash attached for session id %d",
13829 __func__, pAdapter->sessionId);
13830
13831 return VOS_STATUS_SUCCESS;
13832}
13833
13834/**
13835 * hdd_sta_id_hash_detach() - deinit sta_id to macaddr hash
13836 * @pAdapter: adapter handle
13837 *
13838 * Return: vos status
13839 */
13840VOS_STATUS hdd_sta_id_hash_detach(hdd_adapter_t *pAdapter)
13841{
13842 int hash_elem, i;
13843 v_SIZE_t size;
13844
13845 spin_lock_bh( &pAdapter->sta_hash_lock);
13846 if (pAdapter->is_sta_id_hash_initialized != VOS_TRUE) {
13847 spin_unlock_bh( &pAdapter->sta_hash_lock);
13848 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13849 "%s: hash not initialized for session id %d",
13850 __func__, pAdapter->sessionId);
13851 return VOS_STATUS_SUCCESS;
13852 }
13853
13854 pAdapter->is_sta_id_hash_initialized = VOS_FALSE;
13855 spin_unlock_bh( &pAdapter->sta_hash_lock);
13856
13857 hash_elem = 1 << pAdapter->sta_id_hash.idx_bits;
13858
13859 /* free all station info*/
13860 for (i = 0; i < hash_elem; i++) {
13861 hdd_list_size(&pAdapter->sta_id_hash.bins[i], &size);
13862 if (size != 0) {
13863 VOS_STATUS status;
13864 hdd_staid_hash_node_t *sta_info_node = NULL;
13865 hdd_staid_hash_node_t *next_node = NULL;
13866 status = hdd_list_peek_front ( &pAdapter->sta_id_hash.bins[i],
13867 (hdd_list_node_t**) &sta_info_node );
13868
13869 while ( NULL != sta_info_node && VOS_STATUS_SUCCESS == status )
13870 {
13871 status = hdd_list_remove_node( &pAdapter->sta_id_hash.bins[i],
13872 &sta_info_node->node);
13873 vos_mem_free(sta_info_node);
13874
13875 status = hdd_list_peek_next (&pAdapter->sta_id_hash.bins[i],
13876 (hdd_list_node_t*)sta_info_node,
13877 (hdd_list_node_t**)&next_node);
13878 sta_info_node = next_node;
13879 }
13880 }
13881 }
13882
13883 vos_mem_free(pAdapter->sta_id_hash.bins);
13884 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13885 "%s: Station ID Hash detached for session id %d",
13886 __func__, pAdapter->sessionId);
13887 return VOS_STATUS_SUCCESS;
13888}
13889
13890/**
13891 * hdd_sta_id_hash_calculate_index() - derive index from macaddr
13892 * @pAdapter: adapter handle
13893 * @mac_addr_in: input mac address
13894 *
13895 * Return: index derived from mac address
13896 */
13897int hdd_sta_id_hash_calculate_index(hdd_adapter_t *pAdapter,
13898 v_MACADDR_t *mac_addr_in)
13899{
13900 uint16 index;
13901 struct hdd_align_mac_addr_t * mac_addr =
13902 (struct hdd_align_mac_addr_t *)mac_addr_in;
13903
13904 index = mac_addr->bytes_ab ^
13905 mac_addr->bytes_cd ^ mac_addr->bytes_ef;
13906 index ^= index >> pAdapter->sta_id_hash.idx_bits;
13907 index &= pAdapter->sta_id_hash.mask;
13908 return index;
13909}
13910
13911/**
13912 * hdd_sta_id_hash_add_entry() - add entry in hash
13913 * @pAdapter: adapter handle
13914 * @sta_id: station id
13915 * @mac_addr: mac address
13916 *
13917 * Return: vos status
13918 */
13919VOS_STATUS hdd_sta_id_hash_add_entry(hdd_adapter_t *pAdapter,
13920 v_U8_t sta_id, v_MACADDR_t *mac_addr)
13921{
13922 uint16 index;
13923 hdd_staid_hash_node_t *sta_info_node = NULL;
13924
Nirav Shah7e3c8132015-06-22 23:51:42 +053013925 index = hdd_sta_id_hash_calculate_index(pAdapter, mac_addr);
13926 sta_info_node = vos_mem_malloc(sizeof(hdd_staid_hash_node_t));
13927 if (!sta_info_node) {
Nirav Shah7e3c8132015-06-22 23:51:42 +053013928 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13929 "%s: malloc failed", __func__);
13930 return VOS_STATUS_E_NOMEM;
13931 }
13932
13933 sta_info_node->sta_id = sta_id;
13934 vos_mem_copy(&sta_info_node->mac_addr, mac_addr, sizeof(v_MACADDR_t));
13935
Nirav Shah303ed5c2015-08-24 10:29:25 +053013936 spin_lock_bh( &pAdapter->sta_hash_lock);
13937 if (pAdapter->is_sta_id_hash_initialized != VOS_TRUE) {
13938 spin_unlock_bh( &pAdapter->sta_hash_lock);
13939 vos_mem_free(sta_info_node);
13940 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13941 "%s: hash is not initialized for session id %d",
13942 __func__, pAdapter->sessionId);
13943 return VOS_STATUS_E_FAILURE;
13944 }
13945
Nirav Shah7e3c8132015-06-22 23:51:42 +053013946 hdd_list_insert_back ( &pAdapter->sta_id_hash.bins[index],
13947 (hdd_list_node_t*) sta_info_node );
13948 spin_unlock_bh( &pAdapter->sta_hash_lock);
13949 return VOS_STATUS_SUCCESS;
13950}
13951
13952/**
13953 * hdd_sta_id_hash_remove_entry() - remove entry from hash
13954 * @pAdapter: adapter handle
13955 * @sta_id: station id
13956 * @mac_addr: mac address
13957 *
13958 * Return: vos status
13959 */
13960VOS_STATUS hdd_sta_id_hash_remove_entry(hdd_adapter_t *pAdapter,
13961 v_U8_t sta_id, v_MACADDR_t *mac_addr)
13962{
13963 uint16 index;
13964 VOS_STATUS status;
13965 hdd_staid_hash_node_t *sta_info_node = NULL;
13966 hdd_staid_hash_node_t *next_node = NULL;
13967
13968 spin_lock_bh( &pAdapter->sta_hash_lock);
13969 if (pAdapter->is_sta_id_hash_initialized != VOS_TRUE) {
13970 spin_unlock_bh( &pAdapter->sta_hash_lock);
13971 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13972 "%s: hash is not initialized for session id %d",
13973 __func__, pAdapter->sessionId);
13974 return VOS_STATUS_E_FAILURE;
13975 }
13976
13977 index = hdd_sta_id_hash_calculate_index(pAdapter, mac_addr);
13978 status = hdd_list_peek_front ( &pAdapter->sta_id_hash.bins[index],
13979 (hdd_list_node_t**) &sta_info_node );
13980
13981 while ( NULL != sta_info_node && VOS_STATUS_SUCCESS == status )
13982 {
13983 if (sta_info_node->sta_id == sta_id) {
13984 status = hdd_list_remove_node( &pAdapter->sta_id_hash.bins[index],
13985 &sta_info_node->node);
13986 vos_mem_free(sta_info_node);
13987 break;
13988 }
13989 status = hdd_list_peek_next (&pAdapter->sta_id_hash.bins[index],
13990 (hdd_list_node_t*)sta_info_node, (hdd_list_node_t**)&next_node);
13991 sta_info_node = next_node;
13992 }
13993 spin_unlock_bh( &pAdapter->sta_hash_lock);
13994 return status;
13995}
13996
13997/**
13998 * hdd_sta_id_find_from_mac_addr() - find sta id from mac address
13999 * @pAdapter: adapter handle
14000 * @mac_addr_in: mac address
14001 *
14002 * Return: station id
14003 */
14004int hdd_sta_id_find_from_mac_addr(hdd_adapter_t *pAdapter,
14005 v_MACADDR_t *mac_addr_in)
14006{
14007 uint8 is_found = 0;
14008 uint8 sta_id = HDD_WLAN_INVALID_STA_ID;
14009 uint16 index;
14010 VOS_STATUS status;
14011 hdd_staid_hash_node_t *sta_info_node = NULL;
14012 hdd_staid_hash_node_t *next_node = NULL;
14013
14014 spin_lock_bh( &pAdapter->sta_hash_lock);
14015 if (pAdapter->is_sta_id_hash_initialized != VOS_TRUE) {
14016 spin_unlock_bh( &pAdapter->sta_hash_lock);
Bhargav Shahce3b32c2015-08-10 12:29:24 +053014017 hddLog(VOS_TRACE_LEVEL_INFO,
Nirav Shah7e3c8132015-06-22 23:51:42 +053014018 FL("hash is not initialized for session id %d"),
14019 pAdapter->sessionId);
14020 return HDD_WLAN_INVALID_STA_ID;
14021 }
14022
14023 index = hdd_sta_id_hash_calculate_index(pAdapter, mac_addr_in);
14024 status = hdd_list_peek_front ( &pAdapter->sta_id_hash.bins[index],
14025 (hdd_list_node_t**) &sta_info_node );
14026
14027 while ( NULL != sta_info_node && VOS_STATUS_SUCCESS == status )
14028 {
14029 if (vos_mem_compare(&sta_info_node->mac_addr,
14030 mac_addr_in, sizeof(v_MACADDR_t))) {
14031 is_found = 1;
14032 sta_id = sta_info_node->sta_id;
14033 break;
14034 }
14035 status = hdd_list_peek_next (&pAdapter->sta_id_hash.bins[index],
14036 (hdd_list_node_t*)sta_info_node,
14037 (hdd_list_node_t**)&next_node);
14038 sta_info_node = next_node;
14039 }
14040 spin_unlock_bh( &pAdapter->sta_hash_lock);
14041 return sta_id;
14042}
14043
c_manjeecfd1efb2015-09-25 19:32:34 +053014044/*FW memory dump feature*/
14045/**
14046 * This structure hold information about the /proc file
14047 *
14048 */
14049static struct proc_dir_entry *proc_file, *proc_dir;
14050
14051/**
14052 * memdump_read() - perform read operation in memory dump proc file
14053 *
14054 * @file - handle for the proc file.
14055 * @buf - pointer to user space buffer.
14056 * @count - number of bytes to be read.
14057 * @pos - offset in the from buffer.
14058 *
14059 * This function performs read operation for the memory dump proc file.
14060 *
14061 * Return: number of bytes read on success, error code otherwise.
14062 */
14063static ssize_t memdump_read(struct file *file, char __user *buf,
14064 size_t count, loff_t *pos)
14065{
14066 int status;
14067 hdd_context_t *hdd_ctx = (hdd_context_t *)PDE_DATA(file_inode(file));
14068 size_t ret_count;
c_manjeef1495642015-10-13 18:35:01 +053014069 loff_t bytes_left;
c_manjeecfd1efb2015-09-25 19:32:34 +053014070 ENTER();
14071
14072 hddLog(LOG1, FL("Read req for size:%zu pos:%llu"), count, *pos);
14073 status = wlan_hdd_validate_context(hdd_ctx);
14074 if (0 != status) {
14075 return -EINVAL;
14076 }
14077
14078 if (!wlan_fwr_mem_dump_test_and_set_read_allowed_bit()) {
14079 hddLog(LOGE, FL("Current mem dump request timed out/failed"));
14080 return -EINVAL;
14081 }
14082
14083 /* run fs_read_handler in an atomic context*/
14084 vos_ssr_protect(__func__);
c_manjeef1495642015-10-13 18:35:01 +053014085 ret_count = wlan_fwr_mem_dump_fsread_handler( buf, count, pos, &bytes_left);
14086 if(bytes_left == 0)
c_manjeecfd1efb2015-09-25 19:32:34 +053014087 {
14088 /*Free the fwr mem dump buffer */
14089 wlan_free_fwr_mem_dump_buffer();
14090 wlan_set_fwr_mem_dump_state(FW_MEM_DUMP_IDLE);
c_manjeef1495642015-10-13 18:35:01 +053014091 ret_count=0;
c_manjeecfd1efb2015-09-25 19:32:34 +053014092 }
14093 /*if SSR/unload code is waiting for memdump_read to finish,signal it*/
14094 vos_ssr_unprotect(__func__);
14095 EXIT();
14096 return ret_count;
14097}
14098
14099/**
14100 * struct memdump_fops - file operations for memory dump feature
14101 * @read - read function for memory dump operation.
14102 *
14103 * This structure initialize the file operation handle for memory
14104 * dump feature
14105 */
14106static const struct file_operations memdump_fops = {
14107 read: memdump_read
14108};
14109
14110/*
14111* wlan_hdd_fw_mem_dump_cb : callback for Fw mem dump request
14112* To be passed by HDD to WDA and called upon receiving of response
14113* from firmware
14114* @fwMemDumpReqContext : memory dump request context
14115* @dump_rsp : dump response from HAL
14116* Returns none
14117*/
14118void wlan_hdd_fw_mem_dump_cb(void *fwMemDumpReqContext,
14119 tAniFwrDumpRsp *dump_rsp)
14120{
c_manjeef1495642015-10-13 18:35:01 +053014121 struct hdd_fw_mem_dump_req_ctx *pHddFwMemDumpCtx = (struct hdd_fw_mem_dump_req_ctx *)fwMemDumpReqContext;
c_manjeecfd1efb2015-09-25 19:32:34 +053014122
c_manjeef1495642015-10-13 18:35:01 +053014123 ENTER();
14124 spin_lock(&hdd_context_lock);
14125 if(!pHddFwMemDumpCtx || (FW_MEM_DUMP_MAGIC != pHddFwMemDumpCtx->magic)) {
14126 spin_unlock(&hdd_context_lock);
14127 return;
14128 }
14129 /* report the status to requesting function and free mem.*/
c_manjeecfd1efb2015-09-25 19:32:34 +053014130 if (dump_rsp->dump_status != eHAL_STATUS_SUCCESS) {
c_manjeef1495642015-10-13 18:35:01 +053014131 hddLog(LOGE, FL("fw dump request declined by fwr"));
14132 //set the request completion variable
14133 complete(&(pHddFwMemDumpCtx->req_completion));
c_manjeecfd1efb2015-09-25 19:32:34 +053014134 //Free the allocated fwr dump
14135 wlan_free_fwr_mem_dump_buffer();
14136 wlan_set_fwr_mem_dump_state(FW_MEM_DUMP_IDLE);
c_manjeecfd1efb2015-09-25 19:32:34 +053014137 }
c_manjeef1495642015-10-13 18:35:01 +053014138 else {
14139 hddLog(LOG1, FL("fw dump request accepted by fwr"));
14140 /* register the HDD callback which will be called by SVC */
14141 wlan_set_svc_fw_mem_dump_req_cb((void*)wlan_hdd_fw_mem_dump_req_cb,(void*)pHddFwMemDumpCtx);
14142 }
14143 spin_unlock(&hdd_context_lock);
c_manjeecfd1efb2015-09-25 19:32:34 +053014144 EXIT();
14145
14146}
14147
14148/**
14149 * memdump_procfs_remove() - Remove file/dir under procfs for memory dump
14150 *
14151 * This function removes file/dir under proc file system that was
14152 * processing firmware memory dump
14153 *
14154 * Return: None
14155 */
14156static void memdump_procfs_remove(void)
14157{
14158 remove_proc_entry(PROCFS_MEMDUMP_NAME, proc_dir);
14159 hddLog(LOG1 , FL("/proc/%s/%s removed\n"),
14160 PROCFS_MEMDUMP_DIR, PROCFS_MEMDUMP_NAME);
14161 remove_proc_entry(PROCFS_MEMDUMP_DIR, NULL);
14162 hddLog(LOG1 , FL("/proc/%s removed\n"), PROCFS_MEMDUMP_DIR);
14163}
14164
14165/**
14166 * memdump_procfs_init() - Initialize procfs for memory dump
14167 *
14168 * @vos_ctx - Global vos context.
14169 *
14170 * This function create file under proc file system to be used later for
14171 * processing firmware memory dump
14172 *
14173 * Return: 0 on success, error code otherwise.
14174 */
14175static int memdump_procfs_init(void *vos_ctx)
14176{
14177 hdd_context_t *hdd_ctx;
14178
14179 hdd_ctx = vos_get_context(VOS_MODULE_ID_HDD, vos_ctx);
14180 if (!hdd_ctx) {
14181 hddLog(LOGE , FL("Invalid HDD context"));
14182 return -EINVAL;
14183 }
14184
14185 proc_dir = proc_mkdir(PROCFS_MEMDUMP_DIR, NULL);
14186 if (proc_dir == NULL) {
14187 remove_proc_entry(PROCFS_MEMDUMP_DIR, NULL);
14188 hddLog(LOGE , FL("Error: Could not initialize /proc/%s"),
14189 PROCFS_MEMDUMP_DIR);
14190 return -ENOMEM;
14191 }
14192
14193 proc_file = proc_create_data(PROCFS_MEMDUMP_NAME,
14194 S_IRUSR | S_IWUSR, proc_dir,
14195 &memdump_fops, hdd_ctx);
14196 if (proc_file == NULL) {
14197 remove_proc_entry(PROCFS_MEMDUMP_NAME, proc_dir);
14198 hddLog(LOGE , FL("Error: Could not initialize /proc/%s"),
14199 PROCFS_MEMDUMP_NAME);
14200 return -ENOMEM;
14201 }
14202
14203 hddLog(LOG1 , FL("/proc/%s/%s created"),
14204 PROCFS_MEMDUMP_DIR, PROCFS_MEMDUMP_NAME);
14205
14206 return 0;
14207}
14208
14209/**
14210 * memdump_init() - Initialization function for memory dump feature
14211 *
14212 * This function creates proc file for memdump feature and registers
14213 * HDD callback function with SME.
14214 *
14215 * Return - 0 on success, error otherwise
14216 */
14217int memdump_init(void)
14218{
14219 hdd_context_t *hdd_ctx;
14220 void *vos_ctx;
14221 int status = 0;
14222
14223 vos_ctx = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
14224 if (!vos_ctx) {
14225 hddLog(LOGE, FL("Invalid VOS context"));
14226 return -EINVAL;
14227 }
14228
14229 hdd_ctx = vos_get_context(VOS_MODULE_ID_HDD, vos_ctx);
14230 if (!hdd_ctx) {
14231 hddLog(LOGE , FL("Invalid HDD context"));
14232 return -EINVAL;
14233 }
14234
14235 status = memdump_procfs_init(vos_ctx);
14236 if (status) {
14237 hddLog(LOGE , FL("Failed to create proc file"));
14238 return status;
14239 }
14240
14241 return 0;
14242}
14243
14244/**
14245 * memdump_deinit() - De initialize memdump feature
14246 *
14247 * This function removes proc file created for memdump feature.
14248 *
14249 * Return: None
14250 */
14251int memdump_deinit(void)
14252{
14253 hdd_context_t *hdd_ctx;
14254 void *vos_ctx;
14255
14256 vos_ctx = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
14257 if (!vos_ctx) {
14258 hddLog(LOGE, FL("Invalid VOS context"));
14259 return -EINVAL;
14260 }
14261
14262 hdd_ctx = vos_get_context(VOS_MODULE_ID_HDD, vos_ctx);
14263 if(!hdd_ctx) {
14264 hddLog(LOGE , FL("Invalid HDD context"));
14265 return -EINVAL;
14266 }
14267
14268 memdump_procfs_remove();
14269 return 0;
14270}
14271
14272/**
14273 * wlan_hdd_fw_mem_dump_req(pHddCtx) - common API(cfg80211/ioctl) for requesting fw mem dump to SME
14274 * Return: HAL status
14275 */
14276
14277int wlan_hdd_fw_mem_dump_req(hdd_context_t * pHddCtx)
14278{
14279 tAniFwrDumpReq fw_mem_dump_req={0};
c_manjeef1495642015-10-13 18:35:01 +053014280 struct hdd_fw_mem_dump_req_ctx fw_mem_dump_ctx;
c_manjeecfd1efb2015-09-25 19:32:34 +053014281 eHalStatus status = eHAL_STATUS_FAILURE;
Abhishek Singh4eca9822015-12-09 18:07:34 +053014282 int ret=0, result;
c_manjeecfd1efb2015-09-25 19:32:34 +053014283 ENTER();
c_manjeef1495642015-10-13 18:35:01 +053014284
c_manjeecfd1efb2015-09-25 19:32:34 +053014285 /*Check whether a dump request is already going on
14286 *Caution this function will free previously held memory if new dump request is allowed*/
14287 if (!wlan_fwr_mem_dump_test_and_set_write_allowed_bit()) {
14288 hddLog(LOGE, FL("Fw memdump already in progress"));
14289 return -EBUSY;
14290 }
14291 //Allocate memory for fw mem dump buffer
14292 ret = wlan_fwr_mem_dump_buffer_allocation();
14293 if(ret == -EFAULT)
14294 {
14295 hddLog(LOGE, FL("Fwr mem dump not supported by FW"));
14296 return ret;
14297 }
14298 if (0 != ret) {
14299 hddLog(LOGE, FL("Fwr mem Allocation failed"));
14300 return -ENOMEM;
14301 }
c_manjeef1495642015-10-13 18:35:01 +053014302 init_completion(&fw_mem_dump_ctx.req_completion);
14303 fw_mem_dump_ctx.magic = FW_MEM_DUMP_MAGIC;
14304 fw_mem_dump_ctx.status = false;
14305
c_manjeecfd1efb2015-09-25 19:32:34 +053014306 fw_mem_dump_req.fwMemDumpReqCallback = wlan_hdd_fw_mem_dump_cb;
c_manjeef1495642015-10-13 18:35:01 +053014307 fw_mem_dump_req.fwMemDumpReqContext = &fw_mem_dump_ctx;
c_manjeecfd1efb2015-09-25 19:32:34 +053014308 status = sme_FwMemDumpReq(pHddCtx->hHal, &fw_mem_dump_req);
14309 if(eHAL_STATUS_SUCCESS != status)
14310 {
14311 hddLog(VOS_TRACE_LEVEL_ERROR,
14312 "%s: fw_mem_dump_req failed ", __func__);
14313 wlan_free_fwr_mem_dump_buffer();
c_manjeef1495642015-10-13 18:35:01 +053014314 ret = -EFAULT;
14315 goto cleanup;
c_manjeecfd1efb2015-09-25 19:32:34 +053014316 }
c_manjeef1495642015-10-13 18:35:01 +053014317 /*wait for fw mem dump completion to send event to userspace*/
Abhishek Singh4eca9822015-12-09 18:07:34 +053014318 result =
14319 wait_for_completion_timeout(&fw_mem_dump_ctx.req_completion,
14320 msecs_to_jiffies(FW_MEM_DUMP_TIMEOUT_MS));
14321 if (0 >= result )
c_manjeef1495642015-10-13 18:35:01 +053014322 {
14323 hddLog(VOS_TRACE_LEVEL_ERROR,
Abhishek Singh4eca9822015-12-09 18:07:34 +053014324 "%s: fw_mem_dump_req timeout %d ", __func__,result);
14325 ret = -ETIMEDOUT;
c_manjeef1495642015-10-13 18:35:01 +053014326 }
14327cleanup:
14328 spin_lock(&hdd_context_lock);
14329 fw_mem_dump_ctx.magic = 0;
Abhishek Singh4eca9822015-12-09 18:07:34 +053014330 if(!ret && !fw_mem_dump_ctx.status)
14331 ret = -EFAULT;
c_manjeef1495642015-10-13 18:35:01 +053014332 spin_unlock(&hdd_context_lock);
c_manjeecfd1efb2015-09-25 19:32:34 +053014333
c_manjeef1495642015-10-13 18:35:01 +053014334 EXIT();
Abhishek Singh4eca9822015-12-09 18:07:34 +053014335 return ret;
c_manjeef1495642015-10-13 18:35:01 +053014336}
14337
14338/**
14339 * HDD callback which will be called by SVC to indicate mem dump completion.
14340 */
14341void wlan_hdd_fw_mem_dump_req_cb(struct hdd_fw_mem_dump_req_ctx* pHddFwMemDumpCtx)
14342{
14343 if (!pHddFwMemDumpCtx) {
14344 hddLog(VOS_TRACE_LEVEL_ERROR,
14345 "%s: HDD context not valid ", __func__);
14346 return;
14347 }
14348 spin_lock(&hdd_context_lock);
14349 /* check the req magic and set status */
14350 if (pHddFwMemDumpCtx->magic == FW_MEM_DUMP_MAGIC)
14351 {
14352 pHddFwMemDumpCtx->status = true;
14353 //signal the completion
14354 complete(&(pHddFwMemDumpCtx->req_completion));
14355 }
14356 else
14357 {
14358 hddLog(VOS_TRACE_LEVEL_ERROR,
14359 "%s: fw mem dump request possible timeout ", __func__);
14360 }
14361 spin_unlock(&hdd_context_lock);
c_manjeecfd1efb2015-09-25 19:32:34 +053014362}
14363
Mahesh A Saptasagar67ab9222015-10-21 15:38:41 +053014364void hdd_initialize_adapter_common(hdd_adapter_t *pAdapter)
14365{
14366 if (NULL == pAdapter)
14367 {
14368 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: pAdapter is NULL ", __func__);
14369 return;
14370 }
14371 init_completion(&pAdapter->session_open_comp_var);
14372 init_completion(&pAdapter->session_close_comp_var);
14373 init_completion(&pAdapter->disconnect_comp_var);
14374 init_completion(&pAdapter->linkup_event_var);
14375 init_completion(&pAdapter->cancel_rem_on_chan_var);
14376 init_completion(&pAdapter->rem_on_chan_ready_event);
14377 init_completion(&pAdapter->pno_comp_var);
14378#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
14379 init_completion(&pAdapter->offchannel_tx_event);
14380#endif
14381 init_completion(&pAdapter->tx_action_cnf_event);
14382#ifdef FEATURE_WLAN_TDLS
14383 init_completion(&pAdapter->tdls_add_station_comp);
14384 init_completion(&pAdapter->tdls_del_station_comp);
14385 init_completion(&pAdapter->tdls_mgmt_comp);
14386 init_completion(&pAdapter->tdls_link_establish_req_comp);
14387#endif
14388
14389#ifdef WLAN_FEATURE_RMC
14390 init_completion(&pAdapter->ibss_peer_info_comp);
14391#endif /* WLAN_FEATURE_RMC */
14392 init_completion(&pAdapter->ula_complete);
14393 init_completion(&pAdapter->change_country_code);
14394
14395#ifdef FEATURE_WLAN_BATCH_SCAN
14396 init_completion(&pAdapter->hdd_set_batch_scan_req_var);
14397 init_completion(&pAdapter->hdd_get_batch_scan_req_var);
14398#endif
14399
14400 return;
14401}
c_manjeecfd1efb2015-09-25 19:32:34 +053014402
14403
Jeff Johnson295189b2012-06-20 16:38:30 -070014404//Register the module init/exit functions
14405module_init(hdd_module_init);
14406module_exit(hdd_module_exit);
14407
14408MODULE_LICENSE("Dual BSD/GPL");
14409MODULE_AUTHOR("Qualcomm Atheros, Inc.");
14410MODULE_DESCRIPTION("WLAN HOST DEVICE DRIVER");
14411
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070014412module_param_call(con_mode, con_mode_handler, param_get_int, &con_mode,
14413 S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
Jeff Johnson32d95a32012-09-10 13:15:23 -070014414
Jeff Johnson76052702013-04-16 13:55:05 -070014415module_param_call(fwpath, fwpath_changed_handler, param_get_string, &fwpath,
Jeff Johnson32d95a32012-09-10 13:15:23 -070014416 S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
Arif Hussain66559122013-11-21 10:11:40 -080014417
14418module_param(enable_dfs_chan_scan, int,
14419 S_IRUSR | S_IRGRP | S_IROTH);
14420
14421module_param(enable_11d, int,
14422 S_IRUSR | S_IRGRP | S_IROTH);
14423
14424module_param(country_code, charp,
14425 S_IRUSR | S_IRGRP | S_IROTH);