blob: 20c85036c457b8f20028241453220bf32bbdf2cb [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
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -0800179#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
Srinivas Girigowda5cecb202013-10-08 09:13:25 -0700180#define TID_MIN_VALUE 0
181#define TID_MAX_VALUE 15
182static VOS_STATUS hdd_get_tsm_stats(hdd_adapter_t *pAdapter, const tANI_U8 tid,
183 tAniTrafStrmMetrics* pTsmMetrics);
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -0800184static VOS_STATUS hdd_parse_ese_beacon_req(tANI_U8 *pValue,
185 tCsrEseBeaconReq *pEseBcnReq);
186#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -0700187
Atul Mittal1d722422014-03-19 11:15:07 +0530188/*
189 * Maximum buffer size used for returning the data back to user space
190 */
191#define WLAN_MAX_BUF_SIZE 1024
192#define WLAN_PRIV_DATA_MAX_LEN 8192
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -0700193
c_hpothu92367912014-05-01 15:18:17 +0530194//wait time for beacon miss rate.
195#define BCN_MISS_RATE_TIME 500
196
Sushant Kaushik83392fa2015-05-05 17:44:40 +0530197static vos_wake_lock_t wlan_wake_lock;
198
Jeff Johnson295189b2012-06-20 16:38:30 -0700199/* set when SSR is needed after unload */
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -0700200static e_hdd_ssr_required isSsrRequired = HDD_SSR_NOT_REQUIRED;
Jeff Johnson295189b2012-06-20 16:38:30 -0700201
202//internal function declaration
Jeff Johnsone7245742012-09-05 17:12:55 -0700203static VOS_STATUS wlan_hdd_framework_restart(hdd_context_t *pHddCtx);
204static void wlan_hdd_restart_init(hdd_context_t *pHddCtx);
205static void wlan_hdd_restart_deinit(hdd_context_t *pHddCtx);
206void wlan_hdd_restart_timer_cb(v_PVOID_t usrDataForCallback);
Sameer Thalappil45931fb2013-02-01 11:18:05 -0800207void hdd_set_wlan_suspend_mode(bool suspend);
Jeff Johnsone7245742012-09-05 17:12:55 -0700208
Jeff Johnson295189b2012-06-20 16:38:30 -0700209v_U16_t hdd_select_queue(struct net_device *dev,
Anand N Sunkade9adb1b2015-07-29 09:56:45 +0530210 struct sk_buff *skb
211#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,13,0))
212 , void *accel_priv
213#endif
214#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
215 , select_queue_fallback_t fallback
216#endif
217);
Jeff Johnson295189b2012-06-20 16:38:30 -0700218
219#ifdef WLAN_FEATURE_PACKET_FILTERING
220static void hdd_set_multicast_list(struct net_device *dev);
221#endif
222
223void hdd_wlan_initial_scan(hdd_adapter_t *pAdapter);
224
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -0800225#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowdade697412013-02-14 16:31:48 -0800226void hdd_getBand_helper(hdd_context_t *pHddCtx, int *pBand);
227static VOS_STATUS hdd_parse_channellist(tANI_U8 *pValue, tANI_U8 *pChannelList, tANI_U8 *pNumChannels);
Srinivas Girigowda100eb322013-03-15 16:48:20 -0700228static VOS_STATUS hdd_parse_send_action_frame_data(tANI_U8 *pValue, tANI_U8 *pTargetApBssid,
229 tANI_U8 *pChannel, tANI_U8 *pDwellTime,
230 tANI_U8 **pBuf, tANI_U8 *pBufLen);
Varun Reddy Yeturu920df212013-05-22 08:07:23 -0700231static VOS_STATUS hdd_parse_reassoc_command_data(tANI_U8 *pValue,
232 tANI_U8 *pTargetApBssid,
233 tANI_U8 *pChannel);
Srinivas Girigowdade697412013-02-14 16:31:48 -0800234#endif
Ratheesh S P21280412015-05-19 14:21:52 +0530235
236/* Store WLAN driver info in a global variable such that crash debugger
237 can extract it from driver debug symbol and crashdump for post processing */
238tANI_U8 g_wlan_driver[ ] = "pronto_driver";
239
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -0800240#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
Srinivas Girigowda5cecb202013-10-08 09:13:25 -0700241VOS_STATUS hdd_parse_get_cckm_ie(tANI_U8 *pValue, tANI_U8 **pCckmIe, tANI_U8 *pCckmIeLen);
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -0800242#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -0700243
Mihir Shetee1093ba2014-01-21 20:13:32 +0530244static VOS_STATUS wlan_hdd_init_channels(hdd_context_t *pHddCtx);
Sushant Kaushik8bc7df22014-04-09 17:55:29 +0530245const char * hdd_device_modetoString(v_U8_t device_mode)
246{
247 switch(device_mode)
248 {
249 CASE_RETURN_STRING( WLAN_HDD_INFRA_STATION );
250 CASE_RETURN_STRING( WLAN_HDD_SOFTAP );
251 CASE_RETURN_STRING( WLAN_HDD_P2P_CLIENT );
252 CASE_RETURN_STRING( WLAN_HDD_P2P_GO );
253 CASE_RETURN_STRING( WLAN_HDD_MONITOR);
254 CASE_RETURN_STRING( WLAN_HDD_FTM );
255 CASE_RETURN_STRING( WLAN_HDD_IBSS );
256 CASE_RETURN_STRING( WLAN_HDD_P2P_DEVICE );
257 default:
258 return "device_mode Unknown";
259 }
260}
Mihir Shetee1093ba2014-01-21 20:13:32 +0530261
Mukul Sharmaa78cf6b2015-02-24 16:59:01 +0530262static int __hdd_netdev_notifier_call(struct notifier_block * nb,
Jeff Johnson295189b2012-06-20 16:38:30 -0700263 unsigned long state,
264 void *ndev)
265{
266 struct net_device *dev = ndev;
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -0700267 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Jeff Johnson27cee452013-03-27 11:10:24 -0700268 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -0700269#ifdef WLAN_BTAMP_FEATURE
270 VOS_STATUS status;
Jeff Johnson295189b2012-06-20 16:38:30 -0700271#endif
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +0530272 long result;
Jeff Johnson295189b2012-06-20 16:38:30 -0700273
274 //Make sure that this callback corresponds to our device.
Jeff Johnson27cee452013-03-27 11:10:24 -0700275 if ((strncmp(dev->name, "wlan", 4)) &&
Amar Singhal4c723bd2013-03-25 18:14:15 -0700276 (strncmp(dev->name, "p2p", 3)))
277 return NOTIFY_DONE;
278
Jeff Johnson295189b2012-06-20 16:38:30 -0700279 if (!dev->ieee80211_ptr)
Jeff Johnson27cee452013-03-27 11:10:24 -0700280 return NOTIFY_DONE;
Jeff Johnson295189b2012-06-20 16:38:30 -0700281
Jeff Johnson27cee452013-03-27 11:10:24 -0700282 if (NULL == pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -0700283 {
Jeff Johnsona8a1a482012-12-12 16:49:33 -0800284 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: HDD Adapter Null Pointer", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700285 VOS_ASSERT(0);
286 return NOTIFY_DONE;
287 }
288
Jeff Johnson27cee452013-03-27 11:10:24 -0700289 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
290 if (NULL == pHddCtx)
291 {
292 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: HDD Context Null Pointer", __func__);
293 VOS_ASSERT(0);
294 return NOTIFY_DONE;
295 }
Sameer Thalappil14067972014-01-23 14:54:54 -0800296 if (pHddCtx->isLogpInProgress)
297 return NOTIFY_DONE;
298
Jeff Johnson27cee452013-03-27 11:10:24 -0700299
300 hddLog(VOS_TRACE_LEVEL_INFO, "%s: %s New Net Device State = %lu",
301 __func__, dev->name, state);
Jeff Johnson295189b2012-06-20 16:38:30 -0700302
303 switch (state) {
304 case NETDEV_REGISTER:
305 break;
306
307 case NETDEV_UNREGISTER:
308 break;
309
310 case NETDEV_UP:
311 break;
312
313 case NETDEV_DOWN:
314 break;
315
316 case NETDEV_CHANGE:
Jeff Johnsone7245742012-09-05 17:12:55 -0700317 if(TRUE == pAdapter->isLinkUpSvcNeeded)
318 complete(&pAdapter->linkup_event_var);
Jeff Johnson295189b2012-06-20 16:38:30 -0700319 break;
320
321 case NETDEV_GOING_DOWN:
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +0530322 result = wlan_hdd_scan_abort(pAdapter);
Girish Gowli4bf7a632014-06-12 13:42:11 +0530323 if (result < 0)
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +0530324 {
325 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
326 "%s: Timeout occurred while waiting for abortscan %ld",
327 __func__, result);
Jeff Johnson295189b2012-06-20 16:38:30 -0700328 }
329 else
330 {
331 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +0530332 "%s: Scan Abort Successful" , __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700333 }
334#ifdef WLAN_BTAMP_FEATURE
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700335 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,"%s: disabling AMP", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700336 status = WLANBAP_StopAmp();
337 if(VOS_STATUS_SUCCESS != status )
338 {
339 pHddCtx->isAmpAllowed = VOS_TRUE;
340 hddLog(VOS_TRACE_LEVEL_FATAL,
341 "%s: Failed to stop AMP", __func__);
342 }
343 else
344 {
345 //a state m/c implementation in PAL is TBD to avoid this delay
346 msleep(500);
Jeff Johnson04dd8a82012-06-29 20:41:40 -0700347 if ( pHddCtx->isAmpAllowed )
348 {
349 WLANBAP_DeregisterFromHCI();
350 pHddCtx->isAmpAllowed = VOS_FALSE;
351 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700352 }
353#endif //WLAN_BTAMP_FEATURE
354 break;
355
356 default:
357 break;
358 }
359
360 return NOTIFY_DONE;
361}
362
Mukul Sharmaa78cf6b2015-02-24 16:59:01 +0530363static int hdd_netdev_notifier_call(struct notifier_block * nb,
364 unsigned long state,
365 void *ndev)
366{
367 int ret;
368 vos_ssr_protect(__func__);
369 ret = __hdd_netdev_notifier_call( nb, state, ndev);
370 vos_ssr_unprotect(__func__);
371 return ret;
372}
373
Jeff Johnson295189b2012-06-20 16:38:30 -0700374struct notifier_block hdd_netdev_notifier = {
375 .notifier_call = hdd_netdev_notifier_call,
376};
377
378/*---------------------------------------------------------------------------
379 * Function definitions
380 *-------------------------------------------------------------------------*/
Jeff Johnson295189b2012-06-20 16:38:30 -0700381void hdd_unregister_mcast_bcast_filter(hdd_context_t *pHddCtx);
382void hdd_register_mcast_bcast_filter(hdd_context_t *pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -0700383//variable to hold the insmod parameters
Madan Mohan Koyyalamudidfd6aa82012-10-18 20:18:43 -0700384static int con_mode;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -0700385#ifndef MODULE
386/* current con_mode - used only for statically linked driver
387 * con_mode is changed by userspace to indicate a mode change which will
388 * result in calling the module exit and init functions. The module
389 * exit function will clean up based on the value of con_mode prior to it
390 * being changed by userspace. So curr_con_mode records the current con_mode
391 * for exit when con_mode becomes the next mode for init
392 */
Madan Mohan Koyyalamudidfd6aa82012-10-18 20:18:43 -0700393static int curr_con_mode;
Jeff Johnson295189b2012-06-20 16:38:30 -0700394#endif
395
Srinivas Girigowda8bf64cb2015-09-30 19:50:09 +0530396#ifdef WLAN_FEATURE_OFFLOAD_PACKETS
397/**
398 * hdd_init_offloaded_packets_ctx() - Initialize offload packets context
399 * @hdd_ctx: hdd global context
400 *
401 * Return: none
402 */
403static void hdd_init_offloaded_packets_ctx(hdd_context_t *hdd_ctx)
404{
405 uint8_t i;
406
407 mutex_init(&hdd_ctx->op_ctx.op_lock);
408 for (i = 0; i < MAXNUM_PERIODIC_TX_PTRNS; i++)
409 {
410 hdd_ctx->op_ctx.op_table[i].request_id = 0;
411 hdd_ctx->op_ctx.op_table[i].pattern_id = i;
412 }
413}
414#else
415static void hdd_init_offloaded_packets_ctx(hdd_context_t *hdd_ctx)
416{
417}
418#endif
419
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -0800420/**---------------------------------------------------------------------------
421
422 \brief hdd_vos_trace_enable() - Configure initial VOS Trace enable
423
424 Called immediately after the cfg.ini is read in order to configure
425 the desired trace levels.
426
427 \param - moduleId - module whose trace level is being configured
428 \param - bitmask - bitmask of log levels to be enabled
429
430 \return - void
431
432 --------------------------------------------------------------------------*/
433static void hdd_vos_trace_enable(VOS_MODULE_ID moduleId, v_U32_t bitmask)
434{
435 wpt_tracelevel level;
436
437 /* if the bitmask is the default value, then a bitmask was not
438 specified in cfg.ini, so leave the logging level alone (it
439 will remain at the "compiled in" default value) */
440 if (CFG_VOS_TRACE_ENABLE_DEFAULT == bitmask)
441 {
442 return;
443 }
444
445 /* a mask was specified. start by disabling all logging */
446 vos_trace_setValue(moduleId, VOS_TRACE_LEVEL_NONE, 0);
447
448 /* now cycle through the bitmask until all "set" bits are serviced */
449 level = VOS_TRACE_LEVEL_FATAL;
450 while (0 != bitmask)
451 {
452 if (bitmask & 1)
453 {
454 vos_trace_setValue(moduleId, level, 1);
455 }
456 level++;
457 bitmask >>= 1;
458 }
459}
460
461
Jeff Johnson295189b2012-06-20 16:38:30 -0700462/**---------------------------------------------------------------------------
463
464 \brief hdd_wdi_trace_enable() - Configure initial WDI Trace enable
465
466 Called immediately after the cfg.ini is read in order to configure
467 the desired trace levels in the WDI.
468
469 \param - moduleId - module whose trace level is being configured
470 \param - bitmask - bitmask of log levels to be enabled
471
472 \return - void
473
474 --------------------------------------------------------------------------*/
475static void hdd_wdi_trace_enable(wpt_moduleid moduleId, v_U32_t bitmask)
476{
477 wpt_tracelevel level;
478
479 /* if the bitmask is the default value, then a bitmask was not
480 specified in cfg.ini, so leave the logging level alone (it
481 will remain at the "compiled in" default value) */
482 if (CFG_WDI_TRACE_ENABLE_DEFAULT == bitmask)
483 {
484 return;
485 }
486
487 /* a mask was specified. start by disabling all logging */
488 wpalTraceSetLevel(moduleId, eWLAN_PAL_TRACE_LEVEL_NONE, 0);
489
490 /* now cycle through the bitmask until all "set" bits are serviced */
491 level = eWLAN_PAL_TRACE_LEVEL_FATAL;
492 while (0 != bitmask)
493 {
494 if (bitmask & 1)
495 {
496 wpalTraceSetLevel(moduleId, level, 1);
497 }
498 level++;
499 bitmask >>= 1;
500 }
501}
Jeff Johnson295189b2012-06-20 16:38:30 -0700502
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +0530503/*
504 * FUNCTION: wlan_hdd_validate_context
505 * This function is used to check the HDD context
506 */
507int wlan_hdd_validate_context(hdd_context_t *pHddCtx)
508{
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +0530509
510 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
511 {
Mahesh A Saptasagar886997a2015-03-04 13:15:51 +0530512 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +0530513 "%s: HDD context is Null", __func__);
514 return -ENODEV;
515 }
516
517 if (pHddCtx->isLogpInProgress)
518 {
Mahesh A Saptasagar886997a2015-03-04 13:15:51 +0530519 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
c_hpothu8adb97b2014-12-08 19:38:20 +0530520 "%s: LOGP %s. Ignore!!", __func__,
521 vos_is_wlan_in_badState(VOS_MODULE_ID_HDD, NULL)
522 ?"failed":"in Progress");
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +0530523 return -EAGAIN;
524 }
525
Mihir Shete18156292014-03-11 15:38:30 +0530526 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +0530527 {
Mahesh A Saptasagar886997a2015-03-04 13:15:51 +0530528 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +0530529 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
530 return -EAGAIN;
531 }
532 return 0;
533}
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -0700534#ifdef CONFIG_ENABLE_LINUX_REG
535void hdd_checkandupdate_phymode( hdd_context_t *pHddCtx)
536{
537 hdd_adapter_t *pAdapter = NULL;
538 hdd_station_ctx_t *pHddStaCtx = NULL;
539 eCsrPhyMode phyMode;
540 hdd_config_t *cfg_param = NULL;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +0530541
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -0700542 if (NULL == pHddCtx)
543 {
544 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
545 "HDD Context is null !!");
546 return ;
547 }
548
549 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION);
550 if (NULL == pAdapter)
551 {
552 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
553 "pAdapter is null !!");
554 return ;
555 }
556
557 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
558 if (NULL == pHddStaCtx)
559 {
560 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
561 "pHddStaCtx is null !!");
562 return ;
563 }
564
565 cfg_param = pHddCtx->cfg_ini;
566 if (NULL == cfg_param)
567 {
568 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
569 "cfg_params not available !!");
570 return ;
571 }
572
573 phyMode = sme_GetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter));
574
575 if (!pHddCtx->isVHT80Allowed)
576 {
577 if ((eCSR_DOT11_MODE_AUTO == phyMode) ||
578 (eCSR_DOT11_MODE_11ac == phyMode) ||
579 (eCSR_DOT11_MODE_11ac_ONLY == phyMode))
580 {
581 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
582 "Setting phymode to 11n!!");
583 sme_SetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter), eCSR_DOT11_MODE_11n);
584 }
585 }
586 else
587 {
588 /*New country Supports 11ac as well resetting value back from .ini*/
589 sme_SetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter),
590 hdd_cfg_xlate_to_csr_phy_mode(cfg_param->dot11Mode));
591 return ;
592 }
593
594 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
595 ((eCSR_CFG_DOT11_MODE_11AC_ONLY == pHddStaCtx->conn_info.dot11Mode) ||
596 (eCSR_CFG_DOT11_MODE_11AC == pHddStaCtx->conn_info.dot11Mode)))
597 {
598 VOS_STATUS vosStatus;
599
600 // need to issue a disconnect to CSR.
601 INIT_COMPLETION(pAdapter->disconnect_comp_var);
602 vosStatus = sme_RoamDisconnect(WLAN_HDD_GET_HAL_CTX(pAdapter),
603 pAdapter->sessionId,
604 eCSR_DISCONNECT_REASON_UNSPECIFIED );
605
606 if (VOS_STATUS_SUCCESS == vosStatus)
c_hpothu6ff1c3c2013-10-01 19:01:57 +0530607 {
608 long ret;
609
610 ret = wait_for_completion_interruptible_timeout(&pAdapter->disconnect_comp_var,
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -0700611 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
c_hpothu6ff1c3c2013-10-01 19:01:57 +0530612 if (0 >= ret)
613 hddLog(LOGE, FL("failure waiting for disconnect_comp_var %ld"),
614 ret);
615 }
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -0700616
617 }
618}
619#else
Gopichand Nakkaladacbcb52013-04-18 16:41:54 +0530620void hdd_checkandupdate_phymode( hdd_adapter_t *pAdapter, char *country_code)
621{
622 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
623 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
624 hdd_config_t *cfg_param;
625 eCsrPhyMode phyMode;
c_hpothu6ff1c3c2013-10-01 19:01:57 +0530626 long ret;
Gopichand Nakkaladacbcb52013-04-18 16:41:54 +0530627
628 if (NULL == pHddCtx)
629 {
630 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
631 "HDD Context is null !!");
632 return ;
633 }
634
635 cfg_param = pHddCtx->cfg_ini;
636
637 if (NULL == cfg_param)
638 {
639 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
640 "cfg_params not available !!");
641 return ;
642 }
643
644 phyMode = sme_GetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter));
645
646 if (NULL != strstr(cfg_param->listOfNon11acCountryCode, country_code))
647 {
648 if ((eCSR_DOT11_MODE_AUTO == phyMode) ||
649 (eCSR_DOT11_MODE_11ac == phyMode) ||
650 (eCSR_DOT11_MODE_11ac_ONLY == phyMode))
651 {
652 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
653 "Setting phymode to 11n!!");
654 sme_SetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter), eCSR_DOT11_MODE_11n);
655 }
656 }
657 else
658 {
659 /*New country Supports 11ac as well resetting value back from .ini*/
660 sme_SetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter),
661 hdd_cfg_xlate_to_csr_phy_mode(cfg_param->dot11Mode));
662 return ;
663 }
664
665 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
666 ((eCSR_CFG_DOT11_MODE_11AC_ONLY == pHddStaCtx->conn_info.dot11Mode) ||
667 (eCSR_CFG_DOT11_MODE_11AC == pHddStaCtx->conn_info.dot11Mode)))
668 {
669 VOS_STATUS vosStatus;
670
671 // need to issue a disconnect to CSR.
672 INIT_COMPLETION(pAdapter->disconnect_comp_var);
673 vosStatus = sme_RoamDisconnect(WLAN_HDD_GET_HAL_CTX(pAdapter),
674 pAdapter->sessionId,
675 eCSR_DISCONNECT_REASON_UNSPECIFIED );
676
677 if (VOS_STATUS_SUCCESS == vosStatus)
c_hpothu6ff1c3c2013-10-01 19:01:57 +0530678 {
679 ret = wait_for_completion_interruptible_timeout(&pAdapter->disconnect_comp_var,
Gopichand Nakkaladacbcb52013-04-18 16:41:54 +0530680 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
c_hpothu6ff1c3c2013-10-01 19:01:57 +0530681 if (ret <= 0)
682 {
683 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
684 "wait on disconnect_comp_var is failed %ld", ret);
685 }
686 }
Gopichand Nakkaladacbcb52013-04-18 16:41:54 +0530687
688 }
689}
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -0700690#endif //CONFIG_ENABLE_LINUX_REG
Gopichand Nakkaladacbcb52013-04-18 16:41:54 +0530691
Tushnim Bhattacharyya9cdf6082013-04-21 16:33:30 -0700692void hdd_checkandupdate_dfssetting( hdd_adapter_t *pAdapter, char *country_code)
693{
694 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
695 hdd_config_t *cfg_param;
696
697 if (NULL == pHddCtx)
698 {
699 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
700 "HDD Context is null !!");
701 return ;
702 }
703
704 cfg_param = pHddCtx->cfg_ini;
705
706 if (NULL == cfg_param)
707 {
708 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
709 "cfg_params not available !!");
710 return ;
711 }
712
Agarwal Ashish738843c2014-09-25 12:27:56 +0530713 if (NULL != strstr(cfg_param->listOfNonDfsCountryCode, country_code) ||
714 pHddCtx->disable_dfs_flag == TRUE)
Tushnim Bhattacharyya9cdf6082013-04-21 16:33:30 -0700715 {
716 /*New country doesn't support DFS */
717 sme_UpdateDfsSetting(WLAN_HDD_GET_HAL_CTX(pAdapter), 0);
718 }
719 else
720 {
721 /*New country Supports DFS as well resetting value back from .ini*/
722 sme_UpdateDfsSetting(WLAN_HDD_GET_HAL_CTX(pAdapter), cfg_param->enableDFSChnlScan);
723 }
724
725}
726
Rajeev79dbe4c2013-10-05 11:03:42 +0530727#ifdef FEATURE_WLAN_BATCH_SCAN
728
729/**---------------------------------------------------------------------------
730
731 \brief hdd_extract_assigned_int_from_str() - Extracts assigned integer from
732 input string
733
734 This function extracts assigned integer from string in below format:
735 "STRING=10" : extracts integer 10 from this string
736
737 \param - pInPtr Pointer to input string
738 \param - base Base for string to int conversion(10 for decimal 16 for hex)
739 \param - pOutPtr Pointer to variable in which extracted integer needs to be
740 assigned
741 \param - pLastArg to tell whether it is last arguement in input string or
742 not
743
744 \return - NULL for failure cases
745 pointer to next arguement in input string for success cases
746 --------------------------------------------------------------------------*/
747static tANI_U8 *
748hdd_extract_assigned_int_from_str
749(
750 tANI_U8 *pInPtr,
751 tANI_U8 base,
752 tANI_U32 *pOutPtr,
753 tANI_U8 *pLastArg
754)
755{
756 int tempInt;
757 int v = 0;
758 char buf[32];
759 int val = 0;
760 *pLastArg = FALSE;
761
762 pInPtr = strnchr(pInPtr, strlen(pInPtr), EQUALS_TO_ASCII_VALUE);
763 if (NULL == pInPtr)
764 {
765 return NULL;
766 }
767
768 pInPtr++;
769
770 while ((SPACE_ASCII_VALUE == *pInPtr) && ('\0' != *pInPtr)) pInPtr++;
771
772 val = sscanf(pInPtr, "%32s ", buf);
773 if (val < 0 && val > strlen(pInPtr))
774 {
775 return NULL;
776 }
777 pInPtr += val;
778 v = kstrtos32(buf, base, &tempInt);
779 if (v < 0)
780 {
781 return NULL;
782 }
Rajeev Kumar4d93d842014-01-02 18:31:21 -0800783 if (tempInt < 0)
784 {
785 tempInt = 0;
786 }
Rajeev79dbe4c2013-10-05 11:03:42 +0530787 *pOutPtr = tempInt;
788
789 pInPtr = strnchr(pInPtr, strlen(pInPtr), SPACE_ASCII_VALUE);
790 if (NULL == pInPtr)
791 {
792 *pLastArg = TRUE;
793 return NULL;
794 }
795 while ((SPACE_ASCII_VALUE == *pInPtr) && ('\0' != *pInPtr)) pInPtr++;
796
797 return pInPtr;
798}
799
800/**---------------------------------------------------------------------------
801
802 \brief hdd_extract_assigned_char_from_str() - Extracts assigned char from
803 input string
804
805 This function extracts assigned character from string in below format:
806 "STRING=A" : extracts char 'A' from this string
807
808 \param - pInPtr Pointer to input string
809 \param - pOutPtr Pointer to variable in which extracted char needs to be
810 assigned
811 \param - pLastArg to tell whether it is last arguement in input string or
812 not
813
814 \return - NULL for failure cases
815 pointer to next arguement in input string for success cases
816 --------------------------------------------------------------------------*/
817static tANI_U8 *
818hdd_extract_assigned_char_from_str
819(
820 tANI_U8 *pInPtr,
821 tANI_U8 *pOutPtr,
822 tANI_U8 *pLastArg
823)
824{
825 *pLastArg = FALSE;
826
827 pInPtr = strnchr(pInPtr, strlen(pInPtr), EQUALS_TO_ASCII_VALUE);
828 if (NULL == pInPtr)
829 {
830 return NULL;
831 }
832
833 pInPtr++;
834
835 while ((SPACE_ASCII_VALUE == *pInPtr) && ('\0' != *pInPtr)) pInPtr++;
836
837 *pOutPtr = *pInPtr;
838
839 pInPtr = strnchr(pInPtr, strlen(pInPtr), SPACE_ASCII_VALUE);
840 if (NULL == pInPtr)
841 {
842 *pLastArg = TRUE;
843 return NULL;
844 }
845 while ((SPACE_ASCII_VALUE == *pInPtr) && ('\0' != *pInPtr)) pInPtr++;
846
847 return pInPtr;
848}
849
850
851/**---------------------------------------------------------------------------
852
853 \brief hdd_parse_set_batchscan_command () - HDD parse set batch scan command
854
855 This function parses set batch scan command in below format:
856 WLS_BATCHING_SET <space> followed by below arguements
857 "SCANFREQ=XX" : Optional defaults to 30 sec
858 "MSCAN=XX" : Required number of scans to attempt to batch
859 "BESTN=XX" : Best Network (RSSI) defaults to 16
860 "CHANNEL=<X,Y>" : optional defaults to all channels, can list 'A'or` B.
861 A. implies only 5 GHz , B. implies only 2.4GHz
862 "RTT=X" : optional defaults to 0
863 returns the MIN of MSCAN or the max # of scans firmware can cache or -1 on
864 error
865
866 For example input commands:
867 1) WLS_BATCHING_SET SCANFREQ=60 MSCAN=10 BESTN=20 CHANNEL=A RTT=0 -> This is
868 translated into set batch scan with following parameters:
869 a) Frequence 60 seconds
870 b) Batch 10 scans together
871 c) Best RSSI to be 20
872 d) 5GHz band only
873 e) RTT is equal to 0
874
875 \param - pValue Pointer to input channel list
876 \param - pHddSetBatchScanReq Pointer to HDD batch scan request structure
877
878 \return - 0 for success non-zero for failure
879
880 --------------------------------------------------------------------------*/
881static int
882hdd_parse_set_batchscan_command
883(
884 tANI_U8 *pValue,
885 tSirSetBatchScanReq *pHddSetBatchScanReq
886)
887{
888 tANI_U8 *inPtr = pValue;
889 tANI_U8 val = 0;
890 tANI_U8 lastArg = 0;
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800891 tANI_U32 nScanFreq;
892 tANI_U32 nMscan;
893 tANI_U32 nBestN;
894 tANI_U8 ucRfBand;
895 tANI_U32 nRtt;
Rajeev Kumarc933d982013-11-18 20:04:20 -0800896 tANI_U32 temp;
Rajeev79dbe4c2013-10-05 11:03:42 +0530897
898 /*initialize default values*/
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800899 nScanFreq = HDD_SET_BATCH_SCAN_DEFAULT_FREQ;
900 ucRfBand = HDD_SET_BATCH_SCAN_DEFAULT_BAND;
901 nRtt = 0;
902 nBestN = HDD_SET_BATCH_SCAN_BEST_NETWORK;
Rajeev79dbe4c2013-10-05 11:03:42 +0530903
904 /*go to space after WLS_BATCHING_SET command*/
905 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
906 /*no argument after the command*/
907 if (NULL == inPtr)
908 {
909 return -EINVAL;
910 }
911
912 /*no space after the command*/
913 else if (SPACE_ASCII_VALUE != *inPtr)
914 {
915 return -EINVAL;
916 }
917
918 /*removing empty spaces*/
919 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
920
921 /*no argument followed by spaces*/
922 if ('\0' == *inPtr)
923 {
924 return -EINVAL;
925 }
926
927 /*check and parse SCANFREQ*/
928 if ((strncmp(inPtr, "SCANFREQ", 8) == 0))
929 {
930 inPtr = hdd_extract_assigned_int_from_str(inPtr, 10,
Rajeev Kumarc933d982013-11-18 20:04:20 -0800931 &temp, &lastArg);
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800932
Rajeev Kumarc933d982013-11-18 20:04:20 -0800933 if (0 != temp)
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800934 {
Rajeev Kumarc933d982013-11-18 20:04:20 -0800935 nScanFreq = temp;
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800936 }
937
Rajeev79dbe4c2013-10-05 11:03:42 +0530938 if ( (NULL == inPtr) || (TRUE == lastArg))
939 {
940 return -EINVAL;
941 }
942 }
943
944 /*check and parse MSCAN*/
945 if ((strncmp(inPtr, "MSCAN", 5) == 0))
946 {
947 inPtr = hdd_extract_assigned_int_from_str(inPtr, 10,
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800948 &nMscan, &lastArg);
949
950 if (0 == nMscan)
951 {
952 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
953 "invalid MSCAN=%d", nMscan);
954 return -EINVAL;
955 }
956
Rajeev79dbe4c2013-10-05 11:03:42 +0530957 if (TRUE == lastArg)
958 {
959 goto done;
960 }
961 else if (NULL == inPtr)
962 {
963 return -EINVAL;
964 }
965 }
966 else
967 {
968 return -EINVAL;
969 }
970
971 /*check and parse BESTN*/
972 if ((strncmp(inPtr, "BESTN", 5) == 0))
973 {
974 inPtr = hdd_extract_assigned_int_from_str(inPtr, 10,
Rajeev Kumarc933d982013-11-18 20:04:20 -0800975 &temp, &lastArg);
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800976
Rajeev Kumarc933d982013-11-18 20:04:20 -0800977 if (0 != temp)
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800978 {
Rajeev Kumarc933d982013-11-18 20:04:20 -0800979 nBestN = temp;
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800980 }
981
Rajeev79dbe4c2013-10-05 11:03:42 +0530982 if (TRUE == lastArg)
983 {
984 goto done;
985 }
986 else if (NULL == inPtr)
987 {
988 return -EINVAL;
989 }
990 }
991
992 /*check and parse CHANNEL*/
993 if ((strncmp(inPtr, "CHANNEL", 7) == 0))
994 {
995 inPtr = hdd_extract_assigned_char_from_str(inPtr, &val, &lastArg);
Rajeev Kumarc933d982013-11-18 20:04:20 -0800996
Rajeev79dbe4c2013-10-05 11:03:42 +0530997 if (('A' == val) || ('a' == val))
998 {
c_hpothuebf89732014-02-25 13:00:24 +0530999 ucRfBand = HDD_SET_BATCH_SCAN_5GHz_BAND_ONLY;
Rajeev79dbe4c2013-10-05 11:03:42 +05301000 }
1001 else if (('B' == val) || ('b' == val))
1002 {
c_hpothuebf89732014-02-25 13:00:24 +05301003 ucRfBand = HDD_SET_BATCH_SCAN_24GHz_BAND_ONLY;
Rajeev79dbe4c2013-10-05 11:03:42 +05301004 }
1005 else
1006 {
Rajeev Kumarc933d982013-11-18 20:04:20 -08001007 ucRfBand = HDD_SET_BATCH_SCAN_DEFAULT_BAND;
1008 }
1009
1010 if (TRUE == lastArg)
1011 {
1012 goto done;
1013 }
1014 else if (NULL == inPtr)
1015 {
Rajeev79dbe4c2013-10-05 11:03:42 +05301016 return -EINVAL;
1017 }
1018 }
1019
1020 /*check and parse RTT*/
1021 if ((strncmp(inPtr, "RTT", 3) == 0))
1022 {
1023 inPtr = hdd_extract_assigned_int_from_str(inPtr, 10,
Rajeev Kumar45e64a72013-11-18 19:48:15 -08001024 &nRtt, &lastArg);
Rajeev79dbe4c2013-10-05 11:03:42 +05301025 if (TRUE == lastArg)
1026 {
1027 goto done;
1028 }
1029 if (NULL == inPtr)
1030 {
1031 return -EINVAL;
1032 }
1033 }
1034
1035
1036done:
1037
Rajeev Kumar45e64a72013-11-18 19:48:15 -08001038 pHddSetBatchScanReq->scanFrequency = nScanFreq;
1039 pHddSetBatchScanReq->numberOfScansToBatch = nMscan;
1040 pHddSetBatchScanReq->bestNetwork = nBestN;
1041 pHddSetBatchScanReq->rfBand = ucRfBand;
1042 pHddSetBatchScanReq->rtt = nRtt;
1043
Rajeev79dbe4c2013-10-05 11:03:42 +05301044 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1045 "Received WLS_BATCHING_SET with SCANFREQ=%d "
1046 "MSCAN=%d BESTN=%d CHANNEL=%d RTT=%d",
1047 pHddSetBatchScanReq->scanFrequency,
1048 pHddSetBatchScanReq->numberOfScansToBatch,
1049 pHddSetBatchScanReq->bestNetwork,
1050 pHddSetBatchScanReq->rfBand,
1051 pHddSetBatchScanReq->rtt);
1052
1053 return 0;
1054}/*End of hdd_parse_set_batchscan_command*/
1055
1056/**---------------------------------------------------------------------------
1057
1058 \brief hdd_set_batch_scan_req_callback () - This function is called after
1059 receiving set batch scan response from FW and it saves set batch scan
1060 response data FW to HDD context and sets the completion event on
1061 which hdd_ioctl is waiting
1062
1063 \param - callbackContext Pointer to HDD adapter
1064 \param - pRsp Pointer to set batch scan response data received from FW
1065
1066 \return - nothing
1067
1068 --------------------------------------------------------------------------*/
1069static void hdd_set_batch_scan_req_callback
1070(
1071 void *callbackContext,
1072 tSirSetBatchScanRsp *pRsp
1073)
1074{
1075 hdd_adapter_t* pAdapter = (hdd_adapter_t*)callbackContext;
1076 tSirSetBatchScanRsp *pHddSetBatchScanRsp;
1077
1078 /*sanity check*/
1079 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
1080 {
1081 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1082 "%s: Invalid pAdapter magic", __func__);
1083 VOS_ASSERT(0);
1084 return;
1085 }
1086 pHddSetBatchScanRsp = &pAdapter->hddSetBatchScanRsp;
1087
1088 /*save set batch scan response*/
1089 pHddSetBatchScanRsp->nScansToBatch = pRsp->nScansToBatch;
1090
1091 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
1092 "Received set batch scan rsp from FW with nScansToBatch=%d",
1093 pHddSetBatchScanRsp->nScansToBatch);
1094
1095 pAdapter->hdd_wait_for_set_batch_scan_rsp = FALSE;
1096 complete(&pAdapter->hdd_set_batch_scan_req_var);
1097
1098 return;
1099}/*End of hdd_set_batch_scan_req_callback*/
1100
1101
1102/**---------------------------------------------------------------------------
1103
1104 \brief hdd_populate_batch_scan_rsp_queue () - This function stores AP meta
1105 info in hdd batch scan response queue
1106
1107 \param - pAdapter Pointer to hdd adapter
1108 \param - pAPMetaInfo Pointer to access point meta info
1109 \param - scanId scan ID of batch scan response
1110 \param - isLastAp tells whether AP is last AP in batch scan response or not
1111
1112 \return - nothing
1113
1114 --------------------------------------------------------------------------*/
1115static void hdd_populate_batch_scan_rsp_queue( hdd_adapter_t* pAdapter,
1116 tpSirBatchScanNetworkInfo pApMetaInfo, tANI_U32 scanId, v_BOOL_t isLastAp)
1117{
1118 tHddBatchScanRsp *pHead;
1119 tHddBatchScanRsp *pNode;
1120 tHddBatchScanRsp *pPrev;
1121 tHddBatchScanRsp *pTemp;
1122 tANI_U8 ssidLen;
1123
1124 /*head of hdd batch scan response queue*/
1125 pHead = pAdapter->pBatchScanRsp;
1126
1127 pNode = (tHddBatchScanRsp *)vos_mem_malloc(sizeof(tHddBatchScanRsp));
1128 if (NULL == pNode)
1129 {
1130 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1131 "%s: Could not allocate memory", __func__);
1132 VOS_ASSERT(0);
1133 return;
1134 }
1135
1136 vos_mem_copy(pNode->ApInfo.bssid, pApMetaInfo->bssid,
1137 sizeof(pNode->ApInfo.bssid));
1138 ssidLen = strlen(pApMetaInfo->ssid);
1139 if (SIR_MAX_SSID_SIZE < ssidLen)
1140 {
1141 /*invalid scan result*/
1142 vos_mem_free(pNode);
1143 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1144 "%s: Invalid AP meta info ssidlen %d", __func__, ssidLen);
1145 return;
1146 }
1147 vos_mem_copy(pNode->ApInfo.ssid, pApMetaInfo->ssid, ssidLen);
1148 /*null terminate ssid*/
1149 pNode->ApInfo.ssid[ssidLen] = '\0';
1150 pNode->ApInfo.ch = pApMetaInfo->ch;
1151 pNode->ApInfo.rssi = pApMetaInfo->rssi;
1152 pNode->ApInfo.age = pApMetaInfo->timestamp;
1153 pNode->ApInfo.batchId = scanId;
1154 pNode->ApInfo.isLastAp = isLastAp;
1155
1156 pNode->pNext = NULL;
1157 if (NULL == pHead)
1158 {
1159 pAdapter->pBatchScanRsp = pNode;
1160 }
1161 else
1162 {
1163 pTemp = pHead;
1164 while (NULL != pTemp)
1165 {
1166 pPrev = pTemp;
1167 pTemp = pTemp->pNext;
1168 }
1169 pPrev->pNext = pNode;
1170 }
1171
1172 return;
1173}/*End of hdd_populate_batch_scan_rsp_queue*/
1174
1175/**---------------------------------------------------------------------------
1176
1177 \brief hdd_batch_scan_result_ind_callback () - This function is called after
1178 receiving batch scan response indication from FW. It saves get batch scan
1179 response data in HDD batch scan response queue. This callback sets the
1180 completion event on which hdd_ioctl is waiting only after getting complete
1181 batch scan response data from FW
1182
1183 \param - callbackContext Pointer to HDD adapter
1184 \param - pRsp Pointer to get batch scan response data received from FW
1185
1186 \return - nothing
1187
1188 --------------------------------------------------------------------------*/
1189static void hdd_batch_scan_result_ind_callback
1190(
1191 void *callbackContext,
1192 void *pRsp
1193)
1194{
1195 v_BOOL_t isLastAp;
1196 tANI_U32 numApMetaInfo;
Rajeev Kumarce651e42013-10-21 18:57:15 -07001197 tANI_U32 numNetworkInScanList;
Rajeev79dbe4c2013-10-05 11:03:42 +05301198 tANI_U32 numberScanList;
1199 tANI_U32 nextScanListOffset;
1200 tANI_U32 nextApMetaInfoOffset;
1201 hdd_adapter_t* pAdapter;
1202 tpSirBatchScanList pScanList;
1203 tpSirBatchScanNetworkInfo pApMetaInfo;
1204 tpSirBatchScanResultIndParam pBatchScanRsp;/*batch scan rsp data from FW*/
1205 tSirSetBatchScanReq *pReq;
1206
1207 pAdapter = (hdd_adapter_t *)callbackContext;
1208 /*sanity check*/
Rajeev Kumar5286bb92013-12-05 11:52:10 -08001209 if ((NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic))
Rajeev79dbe4c2013-10-05 11:03:42 +05301210 {
1211 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1212 "%s: Invalid pAdapter magic", __func__);
1213 VOS_ASSERT(0);
1214 return;
1215 }
1216
1217 /*initialize locals*/
1218 pReq = &pAdapter->hddSetBatchScanReq;
1219 pBatchScanRsp = (tpSirBatchScanResultIndParam)pRsp;
1220 isLastAp = FALSE;
1221 numApMetaInfo = 0;
Rajeev Kumarce651e42013-10-21 18:57:15 -07001222 numNetworkInScanList = 0;
Rajeev79dbe4c2013-10-05 11:03:42 +05301223 numberScanList = 0;
1224 nextScanListOffset = 0;
1225 nextApMetaInfoOffset = 0;
1226 pScanList = NULL;
1227 pApMetaInfo = NULL;
1228
1229 if ((NULL == pBatchScanRsp) || (NULL == pReq))
1230 {
1231 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1232 "%s: pBatchScanRsp is %p pReq %p", __func__, pBatchScanRsp, pReq);
1233 isLastAp = TRUE;
1234 goto done;
1235 }
1236
1237 pAdapter->numScanList = numberScanList = pBatchScanRsp->numScanLists;
1238 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1239 "Batch scan rsp: numberScalList %d", numberScanList);
1240
1241 if ((!numberScanList) || (numberScanList > pReq->numberOfScansToBatch))
1242 {
1243 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1244 "%s: numberScanList %d", __func__, numberScanList);
1245 isLastAp = TRUE;
1246 goto done;
1247 }
1248
1249 while (numberScanList)
1250 {
Rajeev Kumarce651e42013-10-21 18:57:15 -07001251 pScanList = (tpSirBatchScanList)((tANI_U8 *)pBatchScanRsp->scanResults +
Rajeev79dbe4c2013-10-05 11:03:42 +05301252 nextScanListOffset);
1253 if (NULL == pScanList)
1254 {
1255 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1256 "%s: pScanList is %p", __func__, pScanList);
1257 isLastAp = TRUE;
1258 goto done;
1259 }
Rajeev Kumarce651e42013-10-21 18:57:15 -07001260 numNetworkInScanList = numApMetaInfo = pScanList->numNetworksInScanList;
Rajeev79dbe4c2013-10-05 11:03:42 +05301261 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Rajeev Kumarce651e42013-10-21 18:57:15 -07001262 "Batch scan rsp: numApMetaInfo %d scanId %d",
1263 numApMetaInfo, pScanList->scanId);
Rajeev79dbe4c2013-10-05 11:03:42 +05301264
1265 if ((!numApMetaInfo) || (numApMetaInfo > pReq->bestNetwork))
1266 {
1267 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1268 "%s: numApMetaInfo %d", __func__, numApMetaInfo);
1269 isLastAp = TRUE;
1270 goto done;
1271 }
1272
Rajeev Kumarce651e42013-10-21 18:57:15 -07001273 /*Initialize next AP meta info offset for next scan list*/
1274 nextApMetaInfoOffset = 0;
1275
Rajeev79dbe4c2013-10-05 11:03:42 +05301276 while (numApMetaInfo)
1277 {
1278 pApMetaInfo = (tpSirBatchScanNetworkInfo)(pScanList->scanList +
1279 nextApMetaInfoOffset);
1280 if (NULL == pApMetaInfo)
1281 {
1282 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1283 "%s: pApMetaInfo is %p", __func__, pApMetaInfo);
1284 isLastAp = TRUE;
1285 goto done;
1286 }
1287 /*calculate AP age*/
1288 pApMetaInfo->timestamp =
1289 pBatchScanRsp->timestamp - pApMetaInfo->timestamp;
1290
1291 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
Arif Hussaina7c8e412013-11-20 11:06:42 -08001292 "%s: bssId "MAC_ADDRESS_STR
1293 " ch %d rssi %d timestamp %d", __func__,
1294 MAC_ADDR_ARRAY(pApMetaInfo->bssid),
1295 pApMetaInfo->ch, pApMetaInfo->rssi,
1296 pApMetaInfo->timestamp);
Rajeev79dbe4c2013-10-05 11:03:42 +05301297
1298 /*mark last AP in batch scan response*/
1299 if ((TRUE == pBatchScanRsp->isLastResult) &&
1300 (1 == numberScanList) && (1 == numApMetaInfo))
1301 {
1302 isLastAp = TRUE;
1303 }
1304
1305 mutex_lock(&pAdapter->hdd_batch_scan_lock);
1306 /*store batch scan repsonse in hdd queue*/
1307 hdd_populate_batch_scan_rsp_queue(pAdapter, pApMetaInfo,
1308 pScanList->scanId, isLastAp);
1309 mutex_unlock(&pAdapter->hdd_batch_scan_lock);
1310
1311 nextApMetaInfoOffset += sizeof(tSirBatchScanNetworkInfo);
1312 numApMetaInfo--;
1313 }
1314
Rajeev Kumarce651e42013-10-21 18:57:15 -07001315 nextScanListOffset += ((sizeof(tSirBatchScanList) - sizeof(tANI_U8))
1316 + (sizeof(tSirBatchScanNetworkInfo)
1317 * numNetworkInScanList));
Rajeev79dbe4c2013-10-05 11:03:42 +05301318 numberScanList--;
1319 }
1320
1321done:
1322
1323 /*notify hdd_ioctl only if complete batch scan rsp is received and it was
1324 requested from hdd_ioctl*/
1325 if ((TRUE == pAdapter->hdd_wait_for_get_batch_scan_rsp) &&
1326 (TRUE == isLastAp))
1327 {
1328 pAdapter->hdd_wait_for_get_batch_scan_rsp = FALSE;
1329 complete(&pAdapter->hdd_get_batch_scan_req_var);
1330 }
1331
1332 return;
1333}/*End of hdd_batch_scan_result_ind_callback*/
1334
1335/**---------------------------------------------------------------------------
1336
1337 \brief hdd_format_batch_scan_rsp () - This function formats batch scan
1338 response as per batch scan FR request format by putting proper markers
1339
1340 \param - pDest pointer to destination buffer
1341 \param - cur_len current length
1342 \param - tot_len total remaining size which can be written to user space
1343 \param - pApMetaInfo Pointer to get batch scan response AP meta info
1344 \param - pAdapter Pointer to HDD adapter
1345
1346 \return - ret no of characters written
1347
1348 --------------------------------------------------------------------------*/
1349static tANI_U32
1350hdd_format_batch_scan_rsp
1351(
1352 tANI_U8 *pDest,
1353 tANI_U32 cur_len,
1354 tANI_U32 tot_len,
1355 tHddBatchScanRsp *pApMetaInfo,
1356 hdd_adapter_t* pAdapter
1357)
1358{
1359 tANI_U32 ret = 0;
1360 tANI_U32 rem_len = 0;
1361 tANI_U8 temp_len = 0;
1362 tANI_U8 temp_total_len = 0;
1363 tANI_U8 temp[HDD_BATCH_SCAN_AP_META_INFO_SIZE];
1364 tANI_U8 *pTemp = temp;
1365
1366 /*Batch scan reponse needs to be returned to user space in
1367 following format:
1368 "scancount=X\n" where X is the number of scans in current batch
1369 batch
1370 "trunc\n" optional present if current scan truncated
1371 "bssid=XX:XX:XX:XX:XX:XX\n"
1372 "ssid=XXXX\n"
1373 "freq=X\n" frequency in Mhz
1374 "level=XX\n"
1375 "age=X\n" ms
1376 "dist=X\n" cm (-1 if not available)
1377 "errror=X\n" (-1if not available)
1378 "====\n" (end of ap marker)
1379 "####\n" (end of scan marker)
1380 "----\n" (end of results)*/
1381 /*send scan result in above format to user space based on
1382 available length*/
1383 /*The GET response may have more data than the driver can return in its
1384 buffer. In that case the buffer should be filled to the nearest complete
1385 scan, ending with "%%%%".Subsequent callsshould return the remaining data
1386 starting with the next scan (optional .trunc\n., .apcount=X\n., etc).
1387 The final buffer should end with "----\n"*/
1388
1389 /*sanity*/
1390 if (cur_len > tot_len)
1391 {
1392 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1393 "%s: invaid cur_len %d tot_len %d", __func__, cur_len, tot_len);
1394 return 0;
1395 }
1396 else
1397 {
1398 rem_len = (tot_len - cur_len);
1399 }
1400
1401 /*end scan marker*/
1402 if (pApMetaInfo->ApInfo.batchId != pAdapter->prev_batch_id)
1403 {
1404 temp_len = snprintf(pTemp, sizeof(temp), "####\n");
1405 pTemp += temp_len;
1406 temp_total_len += temp_len;
1407 }
1408
1409 /*bssid*/
1410 temp_len = snprintf(pTemp, sizeof(temp),
1411 "bssid=0x%x:0x%x:0x%x:0x%x:0x%x:0x%x\n",
1412 pApMetaInfo->ApInfo.bssid[0], pApMetaInfo->ApInfo.bssid[1],
1413 pApMetaInfo->ApInfo.bssid[2], pApMetaInfo->ApInfo.bssid[3],
1414 pApMetaInfo->ApInfo.bssid[4], pApMetaInfo->ApInfo.bssid[5]);
1415 pTemp += temp_len;
1416 temp_total_len += temp_len;
1417
1418 /*ssid*/
1419 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "ssid=%s\n",
1420 pApMetaInfo->ApInfo.ssid);
1421 pTemp += temp_len;
1422 temp_total_len += temp_len;
1423
1424 /*freq*/
1425 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "freq=%d\n",
Rajeev Kumarc40f7512013-11-04 14:13:23 -08001426 sme_ChnToFreq(pApMetaInfo->ApInfo.ch));
Rajeev79dbe4c2013-10-05 11:03:42 +05301427 pTemp += temp_len;
1428 temp_total_len += temp_len;
1429
1430 /*level*/
1431 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "level=%d\n",
1432 pApMetaInfo->ApInfo.rssi);
1433 pTemp += temp_len;
1434 temp_total_len += temp_len;
1435
1436 /*age*/
Jeff Johnson02797792013-10-26 19:17:13 -07001437 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "age=%d\n",
Rajeev79dbe4c2013-10-05 11:03:42 +05301438 pApMetaInfo->ApInfo.age);
1439 pTemp += temp_len;
1440 temp_total_len += temp_len;
1441
1442 /*dist*/
1443 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "dist=-1\n");
1444 pTemp += temp_len;
1445 temp_total_len += temp_len;
1446
1447 /*error*/
1448 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "error=-1\n");
1449 pTemp += temp_len;
1450 temp_total_len += temp_len;
1451
1452 /*end AP marker*/
1453 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "====\n");
1454 pTemp += temp_len;
1455 temp_total_len += temp_len;
1456
1457 /*last AP in batch scan response*/
1458 if(TRUE == pApMetaInfo->ApInfo.isLastAp)
1459 {
1460 /*end scan marker*/
1461 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "####\n");
1462 pTemp += temp_len;
1463 temp_total_len += temp_len;
1464
1465 /*end batch scan result marker*/
1466 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "----\n");
1467 pTemp += temp_len;
1468 temp_total_len += temp_len;
Kiet Lamaa8e15a2014-02-11 23:30:06 -08001469
Rajeev79dbe4c2013-10-05 11:03:42 +05301470 }
1471
1472 if (temp_total_len < rem_len)
1473 {
1474 ret = temp_total_len + 1;
1475 strlcpy(pDest, temp, ret);
1476 pAdapter->isTruncated = FALSE;
1477 }
1478 else
1479 {
1480 pAdapter->isTruncated = TRUE;
1481 if (rem_len >= strlen("%%%%"))
1482 {
Rajeev Kumarc933d982013-11-18 20:04:20 -08001483 ret = snprintf(pDest, sizeof(temp), "%%%%");
Rajeev79dbe4c2013-10-05 11:03:42 +05301484 }
Rajeev Kumarc933d982013-11-18 20:04:20 -08001485 else
Rajeev79dbe4c2013-10-05 11:03:42 +05301486 {
1487 ret = 0;
1488 }
1489 }
1490
1491 return ret;
1492
1493}/*End of hdd_format_batch_scan_rsp*/
1494
1495/**---------------------------------------------------------------------------
1496
1497 \brief hdd_populate_user_batch_scan_rsp() - This function populates user data
1498 buffer starting with head of hdd batch scan response queue
1499
1500 \param - pAdapter Pointer to HDD adapter
1501 \param - pDest Pointer to user data buffer
1502 \param - cur_len current offset in user buffer
1503 \param - rem_len remaining no of bytes in user buffer
1504
1505 \return - number of bytes written in user buffer
1506
1507 --------------------------------------------------------------------------*/
1508
1509tANI_U32 hdd_populate_user_batch_scan_rsp
1510(
1511 hdd_adapter_t* pAdapter,
1512 tANI_U8 *pDest,
1513 tANI_U32 cur_len,
1514 tANI_U32 rem_len
1515)
1516{
1517 tHddBatchScanRsp *pHead;
1518 tHddBatchScanRsp *pPrev;
1519 tANI_U32 len;
1520
Rajeev79dbe4c2013-10-05 11:03:42 +05301521 pAdapter->isTruncated = FALSE;
1522
1523 /*head of hdd batch scan response queue*/
1524 pHead = pAdapter->pBatchScanRsp;
1525 while (pHead)
1526 {
1527 len = hdd_format_batch_scan_rsp(pDest, cur_len, rem_len, pHead,
1528 pAdapter);
1529 pDest += len;
Rajeev Kumar292d2bb2013-10-23 15:01:44 -07001530 pDest--;
Rajeev79dbe4c2013-10-05 11:03:42 +05301531 cur_len += len;
1532 if(TRUE == pAdapter->isTruncated)
1533 {
1534 /*result is truncated return rest of scan rsp in next req*/
1535 cur_len = rem_len;
1536 break;
1537 }
1538 pPrev = pHead;
1539 pHead = pHead->pNext;
1540 pAdapter->pBatchScanRsp = pHead;
Rajeev Kumarbe17d8b2014-01-10 15:39:45 -08001541 if (TRUE == pPrev->ApInfo.isLastAp)
1542 {
1543 pAdapter->prev_batch_id = 0;
1544 }
1545 else
1546 {
1547 pAdapter->prev_batch_id = pPrev->ApInfo.batchId;
1548 }
Rajeev79dbe4c2013-10-05 11:03:42 +05301549 vos_mem_free(pPrev);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08001550 pPrev = NULL;
Rajeev79dbe4c2013-10-05 11:03:42 +05301551 }
1552
1553 return cur_len;
1554}/*End of hdd_populate_user_batch_scan_rsp*/
1555
1556/**---------------------------------------------------------------------------
1557
1558 \brief hdd_return_batch_scan_rsp_to_user () - This function returns batch
1559 scan response data from HDD queue to user space
1560 It does following in detail:
1561 a) if HDD has enough data in its queue then it 1st copies data to user
1562 space and then send get batch scan indication message to FW. In this
1563 case it does not wait on any event and batch scan response data will
1564 be populated in HDD response queue in MC thread context after receiving
1565 indication from FW
1566 b) else send get batch scan indication message to FW and wait on an event
1567 which will be set once HDD receives complete batch scan response from
1568 FW and then this function returns batch scan response to user space
1569
1570 \param - pAdapter Pointer to HDD adapter
1571 \param - pPrivData Pointer to priv_data
1572
1573 \return - 0 for success -EFAULT for failure
1574
1575 --------------------------------------------------------------------------*/
1576
1577int hdd_return_batch_scan_rsp_to_user
1578(
1579 hdd_adapter_t* pAdapter,
1580 hdd_priv_data_t *pPrivData,
1581 tANI_U8 *command
1582)
1583{
1584 tANI_U8 *pDest;
1585 tANI_U32 count = 0;
1586 tANI_U32 len = 0;
1587 tANI_U32 cur_len = 0;
1588 tANI_U32 rem_len = 0;
1589 eHalStatus halStatus;
1590 unsigned long rc;
1591 tSirTriggerBatchScanResultInd *pReq;
1592
1593 pReq = &pAdapter->hddTriggerBatchScanResultInd;
1594 pReq->param = 0;/*batch scan client*/
1595 pDest = (tANI_U8 *)(command + pPrivData->used_len);
1596 pAdapter->hdd_wait_for_get_batch_scan_rsp = FALSE;
1597
1598 cur_len = pPrivData->used_len;
1599 if (pPrivData->total_len > pPrivData->used_len)
1600 {
1601 rem_len = pPrivData->total_len - pPrivData->used_len;
1602 }
1603 else
1604 {
1605 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1606 "%s: Invalid user data buffer total_len %d used_len %d",
1607 __func__, pPrivData->total_len, pPrivData->used_len);
1608 return -EFAULT;
1609 }
1610
1611 mutex_lock(&pAdapter->hdd_batch_scan_lock);
1612 len = hdd_populate_user_batch_scan_rsp(pAdapter, pDest,
1613 cur_len, rem_len);
1614 mutex_unlock(&pAdapter->hdd_batch_scan_lock);
1615
1616 /*enough scan result available in cache to return to user space or
1617 scan result needs to be fetched 1st from fw and then return*/
Rajeev Kumar99db6262013-11-11 15:23:36 -08001618 if (len == cur_len)
Rajeev79dbe4c2013-10-05 11:03:42 +05301619 {
1620 pAdapter->hdd_wait_for_get_batch_scan_rsp = TRUE;
1621 halStatus = sme_TriggerBatchScanResultInd(
1622 WLAN_HDD_GET_HAL_CTX(pAdapter), pReq,
1623 pAdapter->sessionId, hdd_batch_scan_result_ind_callback,
1624 pAdapter);
1625 if ( eHAL_STATUS_SUCCESS == halStatus )
1626 {
1627 if (TRUE == pAdapter->hdd_wait_for_get_batch_scan_rsp)
1628 {
1629 INIT_COMPLETION(pAdapter->hdd_get_batch_scan_req_var);
1630 rc = wait_for_completion_timeout(
1631 &pAdapter->hdd_get_batch_scan_req_var,
1632 msecs_to_jiffies(HDD_GET_BATCH_SCAN_RSP_TIME_OUT));
1633 if (0 == rc)
1634 {
1635 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1636 "%s: Timeout waiting to fetch batch scan rsp from fw",
1637 __func__);
1638 return -EFAULT;
1639 }
1640 }
1641
1642 len = snprintf(pDest, HDD_BATCH_SCAN_AP_META_INFO_SIZE,
Jeff Johnson02797792013-10-26 19:17:13 -07001643 "scancount=%u\n", pAdapter->numScanList);
Rajeev79dbe4c2013-10-05 11:03:42 +05301644 pDest += len;
1645 cur_len += len;
1646
1647 mutex_lock(&pAdapter->hdd_batch_scan_lock);
1648 len = hdd_populate_user_batch_scan_rsp(pAdapter, pDest,
1649 cur_len, rem_len);
1650 mutex_unlock(&pAdapter->hdd_batch_scan_lock);
1651
1652 count = 0;
1653 len = (len - pPrivData->used_len);
1654 pDest = (command + pPrivData->used_len);
1655 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Rajeev Kumar99db6262013-11-11 15:23:36 -08001656 "NEW BATCH SCAN RESULT:");
Rajeev79dbe4c2013-10-05 11:03:42 +05301657 while(count < len)
1658 {
1659 printk("%c", *(pDest + count));
1660 count++;
1661 }
1662 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1663 "%s: copy %d data to user buffer", __func__, len);
1664 if (copy_to_user(pPrivData->buf, pDest, len))
1665 {
1666 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1667 "%s: failed to copy data to user buffer", __func__);
1668 return -EFAULT;
1669 }
1670 }
1671 else
1672 {
1673 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1674 "sme_GetBatchScanScan returned failure halStatus %d",
1675 halStatus);
1676 return -EINVAL;
1677 }
1678 }
1679 else
1680 {
Rajeev79dbe4c2013-10-05 11:03:42 +05301681 count = 0;
1682 len = (len - pPrivData->used_len);
1683 pDest = (command + pPrivData->used_len);
1684 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Rajeev Kumar99db6262013-11-11 15:23:36 -08001685 "REMAINING TRUNCATED BATCH SCAN RESULT:");
Rajeev79dbe4c2013-10-05 11:03:42 +05301686 while(count < len)
1687 {
1688 printk("%c", *(pDest + count));
1689 count++;
1690 }
Rajeev Kumar99db6262013-11-11 15:23:36 -08001691 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1692 "%s: copy %d data to user buffer", __func__, len);
Rajeev79dbe4c2013-10-05 11:03:42 +05301693 if (copy_to_user(pPrivData->buf, pDest, len))
1694 {
1695 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1696 "%s: failed to copy data to user buffer", __func__);
1697 return -EFAULT;
1698 }
Rajeev79dbe4c2013-10-05 11:03:42 +05301699 }
1700
1701 return 0;
1702} /*End of hdd_return_batch_scan_rsp_to_user*/
1703
Rajeev Kumar8b373292014-01-08 20:36:55 -08001704
1705/**---------------------------------------------------------------------------
1706
1707 \brief hdd_handle_batch_scan_ioctl () - This function handles WLS_BATCHING
1708 IOCTLs from user space. Following BATCH SCAN DEV IOCTs are handled:
1709 WLS_BATCHING VERSION
1710 WLS_BATCHING SET
1711 WLS_BATCHING GET
1712 WLS_BATCHING STOP
1713
1714 \param - pAdapter Pointer to HDD adapter
1715 \param - pPrivdata Pointer to priv_data
1716 \param - command Pointer to command
1717
1718 \return - 0 for success -EFAULT for failure
1719
1720 --------------------------------------------------------------------------*/
1721
1722int hdd_handle_batch_scan_ioctl
1723(
1724 hdd_adapter_t *pAdapter,
1725 hdd_priv_data_t *pPrivdata,
1726 tANI_U8 *command
1727)
1728{
1729 int ret = 0;
Yue Mae36e3552014-03-05 17:06:20 -08001730 hdd_context_t *pHddCtx;
1731
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301732 ENTER();
1733
Yue Mae36e3552014-03-05 17:06:20 -08001734 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
1735 ret = wlan_hdd_validate_context(pHddCtx);
1736 if (ret)
1737 {
Yue Mae36e3552014-03-05 17:06:20 -08001738 goto exit;
1739 }
Rajeev Kumar8b373292014-01-08 20:36:55 -08001740
1741 if (strncmp(command, "WLS_BATCHING VERSION", 20) == 0)
1742 {
1743 char extra[32];
1744 tANI_U8 len = 0;
1745 tANI_U8 version = HDD_BATCH_SCAN_VERSION;
1746
1747 if (FALSE == sme_IsFeatureSupportedByFW(BATCH_SCAN))
1748 {
1749 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1750 "%s: Batch scan feature is not supported by FW", __func__);
1751 ret = -EINVAL;
1752 goto exit;
1753 }
1754
1755 len = scnprintf(extra, sizeof(extra), "WLS_BATCHING_VERSION %d",
1756 version);
1757 if (copy_to_user(pPrivdata->buf, &extra, len + 1))
1758 {
1759 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1760 "%s: failed to copy data to user buffer", __func__);
1761 ret = -EFAULT;
1762 goto exit;
1763 }
1764 ret = HDD_BATCH_SCAN_VERSION;
1765 }
1766 else if (strncmp(command, "WLS_BATCHING SET", 16) == 0)
1767 {
1768 int status;
1769 tANI_U8 *value = (command + 16);
1770 eHalStatus halStatus;
1771 unsigned long rc;
1772 tSirSetBatchScanReq *pReq = &pAdapter->hddSetBatchScanReq;
1773 tSirSetBatchScanRsp *pRsp = &pAdapter->hddSetBatchScanRsp;
1774
1775 if (FALSE == sme_IsFeatureSupportedByFW(BATCH_SCAN))
1776 {
1777 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1778 "%s: Batch scan feature is not supported by FW", __func__);
1779 ret = -EINVAL;
1780 goto exit;
1781 }
1782
1783 if ((WLAN_HDD_INFRA_STATION != pAdapter->device_mode) &&
1784 (WLAN_HDD_P2P_CLIENT != pAdapter->device_mode) &&
1785 (WLAN_HDD_P2P_GO != pAdapter->device_mode) &&
1786 (WLAN_HDD_P2P_DEVICE != pAdapter->device_mode))
1787 {
1788 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05301789 "Received WLS_BATCHING SET command in invalid mode %s (%d) "
Rajeev Kumar8b373292014-01-08 20:36:55 -08001790 "WLS_BATCHING_SET is only allowed in infra STA/P2P client mode",
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05301791 hdd_device_modetoString(pAdapter->device_mode),
1792 pAdapter->device_mode);
Rajeev Kumar8b373292014-01-08 20:36:55 -08001793 ret = -EINVAL;
1794 goto exit;
1795 }
1796
1797 status = hdd_parse_set_batchscan_command(value, pReq);
1798 if (status)
1799 {
1800 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1801 "Invalid WLS_BATCHING SET command");
1802 ret = -EINVAL;
1803 goto exit;
1804 }
1805
1806
1807 pAdapter->hdd_wait_for_set_batch_scan_rsp = TRUE;
1808 halStatus = sme_SetBatchScanReq(WLAN_HDD_GET_HAL_CTX(pAdapter), pReq,
1809 pAdapter->sessionId, hdd_set_batch_scan_req_callback,
1810 pAdapter);
1811
1812 if ( eHAL_STATUS_SUCCESS == halStatus )
1813 {
Mahesh A Saptasagar5f568172014-05-14 17:02:33 +05301814 char extra[32];
1815 tANI_U8 len = 0;
1816 tANI_U8 mScan = 0;
1817
Rajeev Kumar8b373292014-01-08 20:36:55 -08001818 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1819 "sme_SetBatchScanReq returned success halStatus %d",
1820 halStatus);
1821 if (TRUE == pAdapter->hdd_wait_for_set_batch_scan_rsp)
1822 {
1823 INIT_COMPLETION(pAdapter->hdd_set_batch_scan_req_var);
1824 rc = wait_for_completion_timeout(
1825 &pAdapter->hdd_set_batch_scan_req_var,
1826 msecs_to_jiffies(HDD_SET_BATCH_SCAN_REQ_TIME_OUT));
1827 if (0 == rc)
1828 {
1829 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1830 "%s: Timeout waiting for set batch scan to complete",
1831 __func__);
1832 ret = -EINVAL;
1833 goto exit;
1834 }
1835 }
1836 if ( !pRsp->nScansToBatch )
1837 {
1838 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1839 "%s: Received set batch scan failure response from FW",
1840 __func__);
1841 ret = -EINVAL;
1842 goto exit;
1843 }
1844 /*As per the Batch Scan Framework API we should return the MIN of
1845 either MSCAN or the max # of scans firmware can cache*/
Mahesh A Saptasagar5f568172014-05-14 17:02:33 +05301846 mScan = MIN(pReq->numberOfScansToBatch , pRsp->nScansToBatch);
Rajeev Kumar8b373292014-01-08 20:36:55 -08001847
1848 pAdapter->batchScanState = eHDD_BATCH_SCAN_STATE_STARTED;
1849
1850 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1851 "%s: request MSCAN %d response MSCAN %d ret %d",
Mahesh A Saptasagar5f568172014-05-14 17:02:33 +05301852 __func__, pReq->numberOfScansToBatch, pRsp->nScansToBatch, mScan);
1853 len = scnprintf(extra, sizeof(extra), "%d", mScan);
1854 if (copy_to_user(pPrivdata->buf, &extra, len + 1))
1855 {
1856 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1857 "%s: failed to copy MSCAN value to user buffer", __func__);
1858 ret = -EFAULT;
1859 goto exit;
1860 }
Rajeev Kumar8b373292014-01-08 20:36:55 -08001861 }
1862 else
1863 {
1864 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1865 "sme_SetBatchScanReq returned failure halStatus %d",
1866 halStatus);
1867 ret = -EINVAL;
1868 goto exit;
1869 }
1870 }
1871 else if (strncmp(command, "WLS_BATCHING STOP", 17) == 0)
1872 {
1873 eHalStatus halStatus;
1874 tSirStopBatchScanInd *pInd = &pAdapter->hddStopBatchScanInd;
1875 pInd->param = 0;
1876
1877 if (FALSE == sme_IsFeatureSupportedByFW(BATCH_SCAN))
1878 {
1879 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1880 "%s: Batch scan feature is not supported by FW", __func__);
1881 ret = -EINVAL;
1882 goto exit;
1883 }
1884
1885 if (eHDD_BATCH_SCAN_STATE_STARTED != pAdapter->batchScanState)
1886 {
Deepthi Gowribfd17132014-11-14 17:59:04 +05301887 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Rajeev Kumar8b373292014-01-08 20:36:55 -08001888 "Batch scan is not yet enabled batch scan state %d",
1889 pAdapter->batchScanState);
1890 ret = -EINVAL;
1891 goto exit;
1892 }
1893
Kiet Lamaa8e15a2014-02-11 23:30:06 -08001894 mutex_lock(&pAdapter->hdd_batch_scan_lock);
1895 hdd_deinit_batch_scan(pAdapter);
1896 mutex_unlock(&pAdapter->hdd_batch_scan_lock);
1897
Rajeev Kumar8b373292014-01-08 20:36:55 -08001898 pAdapter->batchScanState = eHDD_BATCH_SCAN_STATE_STOPPED;
1899
1900 halStatus = sme_StopBatchScanInd(WLAN_HDD_GET_HAL_CTX(pAdapter), pInd,
1901 pAdapter->sessionId);
1902 if ( eHAL_STATUS_SUCCESS == halStatus )
1903 {
1904 ret = 0;
1905 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1906 "sme_StopBatchScanInd returned success halStatus %d",
1907 halStatus);
1908 }
1909 else
1910 {
1911 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1912 "sme_StopBatchScanInd returned failure halStatus %d",
1913 halStatus);
1914 ret = -EINVAL;
1915 goto exit;
1916 }
1917 }
1918 else if (strncmp(command, "WLS_BATCHING GET", 16) == 0)
1919 {
1920 tANI_U32 remain_len;
1921
1922 if (FALSE == sme_IsFeatureSupportedByFW(BATCH_SCAN))
1923 {
1924 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1925 "%s: Batch scan feature is not supported by FW", __func__);
1926 ret = -EINVAL;
1927 goto exit;
1928 }
1929
1930 if (eHDD_BATCH_SCAN_STATE_STARTED != pAdapter->batchScanState)
1931 {
Deepthi Gowribfd17132014-11-14 17:59:04 +05301932 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Rajeev Kumar8b373292014-01-08 20:36:55 -08001933 "Batch scan is not yet enabled could not return results"
1934 "Batch Scan state %d",
1935 pAdapter->batchScanState);
1936 ret = -EINVAL;
1937 goto exit;
1938 }
1939
1940 pPrivdata->used_len = 16;
1941 remain_len = pPrivdata->total_len - pPrivdata->used_len;
1942 if (remain_len < pPrivdata->total_len)
1943 {
1944 /*Clear previous batch scan response data if any*/
1945 vos_mem_zero((tANI_U8 *)(command + pPrivdata->used_len), remain_len);
1946 }
1947 else
1948 {
1949 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1950 "Invalid total length from user space can't fetch batch"
1951 " scan response total_len %d used_len %d remain len %d",
1952 pPrivdata->total_len, pPrivdata->used_len, remain_len);
1953 ret = -EINVAL;
1954 goto exit;
1955 }
1956 ret = hdd_return_batch_scan_rsp_to_user(pAdapter, pPrivdata, command);
1957 }
1958
1959exit:
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301960 EXIT();
Rajeev Kumar8b373292014-01-08 20:36:55 -08001961 return ret;
1962}
1963
1964
Rajeev79dbe4c2013-10-05 11:03:42 +05301965#endif/*End of FEATURE_WLAN_BATCH_SCAN*/
1966
c_hpothu92367912014-05-01 15:18:17 +05301967static void getBcnMissRateCB(VOS_STATUS status, int bcnMissRate, void *data)
1968{
c_hpothu39eb1e32014-06-26 16:31:50 +05301969 bcnMissRateContext_t *pCBCtx;
1970
1971 if (NULL == data)
1972 {
1973 hddLog(VOS_TRACE_LEVEL_ERROR, FL("argument data is NULL"));
1974 return;
1975 }
c_hpothu92367912014-05-01 15:18:17 +05301976
1977 /* there is a race condition that exists between this callback
1978 function and the caller since the caller could time out either
1979 before or while this code is executing. we use a spinlock to
1980 serialize these actions */
1981 spin_lock(&hdd_context_lock);
1982
c_hpothu39eb1e32014-06-26 16:31:50 +05301983 pCBCtx = (bcnMissRateContext_t *)data;
c_hpothu92367912014-05-01 15:18:17 +05301984 gbcnMissRate = -1;
1985
c_hpothu39eb1e32014-06-26 16:31:50 +05301986 if (pCBCtx->magic != BCN_MISS_RATE_CONTEXT_MAGIC)
c_hpothu92367912014-05-01 15:18:17 +05301987 {
1988 hddLog(VOS_TRACE_LEVEL_ERROR,
c_hpothu39eb1e32014-06-26 16:31:50 +05301989 FL("invalid context magic: %08x"), pCBCtx->magic);
c_hpothu92367912014-05-01 15:18:17 +05301990 spin_unlock(&hdd_context_lock);
1991 return ;
1992 }
1993
1994 if (VOS_STATUS_SUCCESS == status)
1995 {
c_hpothu39eb1e32014-06-26 16:31:50 +05301996 gbcnMissRate = bcnMissRate;
c_hpothu92367912014-05-01 15:18:17 +05301997 }
c_hpothu39eb1e32014-06-26 16:31:50 +05301998 else
1999 {
2000 hddLog(VOS_TRACE_LEVEL_ERROR, FL("failed to get bcnMissRate"));
2001 }
2002
c_hpothu92367912014-05-01 15:18:17 +05302003 complete(&(pCBCtx->completion));
2004 spin_unlock(&hdd_context_lock);
2005
2006 return;
2007}
2008
Abhishek Singh08aa7762014-12-16 13:59:03 +05302009void hdd_FWStatisCB( VOS_STATUS status,
2010 tSirFwStatsResult *fwStatsResult, void *pContext )
Satyanarayana Dash72806012014-12-02 14:30:08 +05302011{
2012 fwStatsContext_t *fwStatsCtx;
Satyanarayana Dash72806012014-12-02 14:30:08 +05302013 hdd_adapter_t *pAdapter;
2014
2015 hddLog(VOS_TRACE_LEVEL_INFO, FL(" with status = %d"),status);
2016
Abhishek Singh08aa7762014-12-16 13:59:03 +05302017 if (NULL == pContext)
Satyanarayana Dash72806012014-12-02 14:30:08 +05302018 {
2019 hddLog(VOS_TRACE_LEVEL_ERROR, FL("argument data is NULL"));
2020 return;
2021 }
2022 /* there is a race condition that exists between this callback
2023 function and the caller since the caller could time out either
2024 before or while this code is executing. we use a spinlock to
2025 serialize these actions */
2026 spin_lock(&hdd_context_lock);
Abhishek Singh08aa7762014-12-16 13:59:03 +05302027 fwStatsCtx = (fwStatsContext_t *) pContext;
Satyanarayana Dash72806012014-12-02 14:30:08 +05302028 if (fwStatsCtx->magic != FW_STATS_CONTEXT_MAGIC)
2029 {
2030 hddLog(VOS_TRACE_LEVEL_ERROR,
2031 FL("invalid context magic: %08x"), fwStatsCtx->magic);
2032 spin_unlock(&hdd_context_lock);
2033 return;
2034 }
2035 pAdapter = fwStatsCtx->pAdapter;
2036 if ((NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic))
2037 {
2038 hddLog(VOS_TRACE_LEVEL_ERROR,
2039 FL("pAdapter returned is NULL or invalid"));
2040 spin_unlock(&hdd_context_lock);
2041 return;
2042 }
2043 pAdapter->fwStatsRsp.type = 0;
Abhishek Singh08aa7762014-12-16 13:59:03 +05302044 if ((VOS_STATUS_SUCCESS == status) && (NULL != fwStatsResult))
Satyanarayana Dash72806012014-12-02 14:30:08 +05302045 {
Satyanarayana Dash72806012014-12-02 14:30:08 +05302046 switch( fwStatsResult->type )
2047 {
2048 case FW_UBSP_STATS:
2049 {
Abhishek Singh08aa7762014-12-16 13:59:03 +05302050 memcpy(&pAdapter->fwStatsRsp,fwStatsResult,sizeof(tSirFwStatsResult));
Satyanarayana Dash72806012014-12-02 14:30:08 +05302051 hddLog(VOS_TRACE_LEVEL_INFO,
2052 FL("ubsp_enter_cnt = %d ubsp_jump_ddr_cnt = %d"),
Abhishek Singh08aa7762014-12-16 13:59:03 +05302053 pAdapter->fwStatsRsp.fwStatsData.ubspStats.ubsp_enter_cnt,
2054 pAdapter->fwStatsRsp.fwStatsData.ubspStats.ubsp_jump_ddr_cnt);
Satyanarayana Dash72806012014-12-02 14:30:08 +05302055 }
2056 break;
2057 default:
2058 {
2059 hddLog(VOS_TRACE_LEVEL_ERROR,
2060 FL(" No handling for stats type %d"),fwStatsResult->type);
2061 }
2062 }
2063 }
2064 complete(&(fwStatsCtx->completion));
2065 spin_unlock(&hdd_context_lock);
2066 return;
2067}
2068
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302069static int hdd_get_dwell_time(hdd_config_t *pCfg, tANI_U8 *command, char *extra, tANI_U8 n, tANI_U8 *len)
2070{
2071 int ret = 0;
2072
2073 if (!pCfg || !command || !extra || !len)
2074 {
2075 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2076 "%s: argument passsed for GETDWELLTIME is incorrect", __func__);
2077 ret = -EINVAL;
2078 return ret;
2079 }
2080
2081 if (strncmp(command, "GETDWELLTIME ACTIVE MAX", 23) == 0)
2082 {
2083 *len = scnprintf(extra, n, "GETDWELLTIME ACTIVE MAX %u\n",
2084 (int)pCfg->nActiveMaxChnTime);
2085 return ret;
2086 }
2087 else if (strncmp(command, "GETDWELLTIME ACTIVE MIN", 23) == 0)
2088 {
2089 *len = scnprintf(extra, n, "GETDWELLTIME ACTIVE MIN %u\n",
2090 (int)pCfg->nActiveMinChnTime);
2091 return ret;
2092 }
2093 else if (strncmp(command, "GETDWELLTIME PASSIVE MAX", 24) == 0)
2094 {
2095 *len = scnprintf(extra, n, "GETDWELLTIME PASSIVE MAX %u\n",
2096 (int)pCfg->nPassiveMaxChnTime);
2097 return ret;
2098 }
2099 else if (strncmp(command, "GETDWELLTIME PASSIVE MIN", 24) == 0)
2100 {
2101 *len = scnprintf(extra, n, "GETDWELLTIME PASSIVE MIN %u\n",
2102 (int)pCfg->nPassiveMinChnTime);
2103 return ret;
2104 }
Rajesh Babu Prathipati0fd227e2014-07-05 12:50:00 +05302105 else if (strncmp(command, "GETDWELLTIME", 12) == 0)
2106 {
2107 *len = scnprintf(extra, n, "GETDWELLTIME %u \n",
2108 (int)pCfg->nActiveMaxChnTime);
2109 return ret;
2110 }
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302111 else
2112 {
2113 ret = -EINVAL;
2114 }
2115
2116 return ret;
2117}
2118
2119static int hdd_set_dwell_time(hdd_adapter_t *pAdapter, tANI_U8 *command)
2120{
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05302121 tHalHandle hHal;
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302122 hdd_config_t *pCfg;
2123 tANI_U8 *value = command;
2124 int val = 0, ret = 0, temp = 0;
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05302125 tSmeConfigParams smeConfig;
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302126
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05302127 if (!pAdapter || !command || !(pCfg = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini)
2128 || !(hHal = (WLAN_HDD_GET_HAL_CTX(pAdapter))))
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302129 {
2130 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2131 "%s: argument passed for SETDWELLTIME is incorrect", __func__);
2132 ret = -EINVAL;
2133 return ret;
2134 }
2135
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05302136 vos_mem_zero(&smeConfig, sizeof(smeConfig));
2137 sme_GetConfigParam(hHal, &smeConfig);
2138
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302139 if (strncmp(command, "SETDWELLTIME ACTIVE MAX", 23) == 0 )
2140 {
2141 value = value + 24;
2142 temp = kstrtou32(value, 10, &val);
2143 if (temp != 0 || val < CFG_ACTIVE_MAX_CHANNEL_TIME_MIN ||
2144 val > CFG_ACTIVE_MAX_CHANNEL_TIME_MAX )
2145 {
2146 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2147 "%s: argument passed for SETDWELLTIME ACTIVE MAX is incorrect", __func__);
2148 ret = -EFAULT;
2149 return ret;
2150 }
2151 pCfg->nActiveMaxChnTime = val;
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05302152 smeConfig.csrConfig.nActiveMaxChnTime = val;
2153 sme_UpdateConfig(hHal, &smeConfig);
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302154 }
2155 else if (strncmp(command, "SETDWELLTIME ACTIVE MIN", 23) == 0)
2156 {
2157 value = value + 24;
2158 temp = kstrtou32(value, 10, &val);
2159 if (temp !=0 || val < CFG_ACTIVE_MIN_CHANNEL_TIME_MIN ||
2160 val > CFG_ACTIVE_MIN_CHANNEL_TIME_MAX )
2161 {
2162 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2163 "%s: argument passsed for SETDWELLTIME ACTIVE MIN is incorrect", __func__);
2164 ret = -EFAULT;
2165 return ret;
2166 }
2167 pCfg->nActiveMinChnTime = val;
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05302168 smeConfig.csrConfig.nActiveMinChnTime = val;
2169 sme_UpdateConfig(hHal, &smeConfig);
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302170 }
2171 else if (strncmp(command, "SETDWELLTIME PASSIVE MAX", 24) == 0)
2172 {
2173 value = value + 25;
2174 temp = kstrtou32(value, 10, &val);
2175 if (temp != 0 || val < CFG_PASSIVE_MAX_CHANNEL_TIME_MIN ||
2176 val > CFG_PASSIVE_MAX_CHANNEL_TIME_MAX )
2177 {
2178 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2179 "%s: argument passed for SETDWELLTIME PASSIVE MAX is incorrect", __func__);
2180 ret = -EFAULT;
2181 return ret;
2182 }
2183 pCfg->nPassiveMaxChnTime = val;
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05302184 smeConfig.csrConfig.nPassiveMaxChnTime = val;
2185 sme_UpdateConfig(hHal, &smeConfig);
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302186 }
2187 else if (strncmp(command, "SETDWELLTIME PASSIVE MIN", 24) == 0)
2188 {
2189 value = value + 25;
2190 temp = kstrtou32(value, 10, &val);
2191 if (temp != 0 || val < CFG_PASSIVE_MIN_CHANNEL_TIME_MIN ||
2192 val > CFG_PASSIVE_MIN_CHANNEL_TIME_MAX )
2193 {
2194 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2195 "%s: argument passed for SETDWELLTIME PASSIVE MIN is incorrect", __func__);
2196 ret = -EFAULT;
2197 return ret;
2198 }
2199 pCfg->nPassiveMinChnTime = val;
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05302200 smeConfig.csrConfig.nPassiveMinChnTime = val;
2201 sme_UpdateConfig(hHal, &smeConfig);
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302202 }
Rajesh Babu Prathipati0fd227e2014-07-05 12:50:00 +05302203 else if (strncmp(command, "SETDWELLTIME", 12) == 0)
2204 {
2205 value = value + 13;
2206 temp = kstrtou32(value, 10, &val);
2207 if (temp != 0 || val < CFG_ACTIVE_MAX_CHANNEL_TIME_MIN ||
2208 val > CFG_ACTIVE_MAX_CHANNEL_TIME_MAX )
2209 {
2210 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2211 "%s: argument passed for SETDWELLTIME is incorrect", __func__);
2212 ret = -EFAULT;
2213 return ret;
2214 }
2215 pCfg->nActiveMaxChnTime = val;
2216 smeConfig.csrConfig.nActiveMaxChnTime = val;
2217 sme_UpdateConfig(hHal, &smeConfig);
2218 }
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302219 else
2220 {
2221 ret = -EINVAL;
2222 }
2223
2224 return ret;
2225}
Agarwal Ashish8bd53ae2015-06-12 18:03:45 +05302226static int hdd_cmd_setFccChannel(hdd_context_t *pHddCtx, tANI_U8 *cmd,
2227 tANI_U8 cmd_len)
2228{
2229 tANI_U8 *value;
2230 tANI_U8 fcc_constraint;
2231
2232 eHalStatus status;
2233 int ret = 0;
2234 value = cmd + cmd_len + 1;
2235
2236 ret = kstrtou8(value, 10, &fcc_constraint);
2237 if ((ret < 0) || (fcc_constraint > 1)) {
2238 /*
2239 * If the input value is greater than max value of datatype,
2240 * then also it is a failure
2241 */
2242 hddLog(VOS_TRACE_LEVEL_ERROR,
2243 "%s: value out of range", __func__);
2244 return -EINVAL;
2245 }
2246
2247 status = sme_handleSetFccChannel(pHddCtx->hHal, fcc_constraint);
2248 if (status != eHAL_STATUS_SUCCESS)
2249 ret = -EPERM;
2250
2251 return ret;
2252}
2253
Mahesh A Saptasagarbeca12c2015-09-07 16:21:06 +05302254/**---------------------------------------------------------------------------
Agarwal Ashish8bd53ae2015-06-12 18:03:45 +05302255
Mahesh A Saptasagarbeca12c2015-09-07 16:21:06 +05302256 \brief hdd_enable_disable_ca_event() - When Host sends IOCTL (enabled),
2257 FW will send *ONE* CA ind to Host(even though it is duplicate).
2258 When Host send IOCTL (disable), FW doesn't perform any action.
2259 Whenever any change in CA *and* WLAN is in SAP/P2P-GO mode, FW
2260 sends CA ind to host. (regard less of IOCTL status)
2261 \param - pHddCtx - HDD context
2262 \param - command - command received from framework
2263 \param - cmd_len - len of the command
2264
2265 \return - 0 on success, appropriate error values on failure.
2266
2267 --------------------------------------------------------------------------*/
2268int hdd_enable_disable_ca_event(hdd_context_t *pHddCtx, tANI_U8* command, tANI_U8 cmd_len)
2269{
2270 tANI_U8 set_value;
2271 int ret = 0;
2272 eHalStatus status;
2273
2274 ret = wlan_hdd_validate_context(pHddCtx);
2275 if (0 != ret)
2276 {
2277 ret = -EINVAL;
2278 goto exit;
2279 }
2280
2281 if (pHddCtx->cfg_ini->gOptimizeCAevent == 0)
2282 {
2283 hddLog(VOS_TRACE_LEVEL_ERROR, "Enable gOptimizeCAevent"
2284 " ini param to control channel avooidance indication");
2285 ret = 0;
2286 goto exit;
2287 }
2288
2289 set_value = command[cmd_len + 1] - '0';
2290 status = sme_enableDisableChanAvoidIndEvent(pHddCtx->hHal, set_value);
2291 if (status != eHAL_STATUS_SUCCESS)
2292 {
2293 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Failed to send"
2294 " enableDisableChanAoidance command to SME\n", __func__);
2295 ret = -EINVAL;
2296 }
2297
2298exit:
2299 return ret;
2300}
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302301
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002302static int hdd_driver_command(hdd_adapter_t *pAdapter,
2303 hdd_priv_data_t *ppriv_data)
Jeff Johnson295189b2012-06-20 16:38:30 -07002304{
Jeff Johnson295189b2012-06-20 16:38:30 -07002305 hdd_priv_data_t priv_data;
2306 tANI_U8 *command = NULL;
Kaushik, Sushant96122442014-10-21 16:40:18 +05302307 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
2308 hdd_scaninfo_t *pScanInfo = NULL;
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002309 int ret = 0;
Kaushik, Sushant96122442014-10-21 16:40:18 +05302310 int status;
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05302311#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
2312 struct cfg80211_mgmt_tx_params params;
2313#endif
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302314
2315 ENTER();
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002316 /*
2317 * Note that valid pointers are provided by caller
2318 */
Jeff Johnson295189b2012-06-20 16:38:30 -07002319
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002320 /* copy to local struct to avoid numerous changes to legacy code */
2321 priv_data = *ppriv_data;
Jeff Johnson295189b2012-06-20 16:38:30 -07002322
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002323 if (priv_data.total_len <= 0 ||
2324 priv_data.total_len > WLAN_PRIV_DATA_MAX_LEN)
Sameer Thalappil8ef3a0e2013-04-05 14:36:04 -07002325 {
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002326 hddLog(VOS_TRACE_LEVEL_WARN,
2327 "%s:invalid priv_data.total_len(%d)!!!", __func__,
2328 priv_data.total_len);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07002329 ret = -EINVAL;
2330 goto exit;
2331 }
Kaushik, Sushant96122442014-10-21 16:40:18 +05302332 status = wlan_hdd_validate_context(pHddCtx);
2333 if (0 != status)
2334 {
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302335 ret = -EINVAL;
2336 goto exit;
Kaushik, Sushant96122442014-10-21 16:40:18 +05302337 }
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07002338 /* Allocate +1 for '\0' */
2339 command = kmalloc(priv_data.total_len + 1, GFP_KERNEL);
Jeff Johnson295189b2012-06-20 16:38:30 -07002340 if (!command)
2341 {
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002342 hddLog(VOS_TRACE_LEVEL_ERROR,
2343 "%s: failed to allocate memory", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002344 ret = -ENOMEM;
2345 goto exit;
2346 }
2347
2348 if (copy_from_user(command, priv_data.buf, priv_data.total_len))
2349 {
2350 ret = -EFAULT;
2351 goto exit;
2352 }
2353
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002354 /* Make sure the command is NUL-terminated */
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07002355 command[priv_data.total_len] = '\0';
2356
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002357 /* at one time the following block of code was conditional. braces
2358 * have been retained to avoid re-indenting the legacy code
2359 */
Jeff Johnson295189b2012-06-20 16:38:30 -07002360 {
2361 hdd_context_t *pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
2362
2363 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudif9bdd4e2012-10-30 18:05:03 -07002364 "%s: Received %s cmd from Wi-Fi GUI***", __func__, command);
Jeff Johnson295189b2012-06-20 16:38:30 -07002365
2366 if (strncmp(command, "P2P_DEV_ADDR", 12) == 0 )
2367 {
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302368 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2369 TRACE_CODE_HDD_P2P_DEV_ADDR_IOCTL,
2370 pAdapter->sessionId, (unsigned)
2371 (*(pHddCtx->p2pDeviceAddress.bytes+2)<<24 |
2372 *(pHddCtx->p2pDeviceAddress.bytes+3)<<16 |
2373 *(pHddCtx->p2pDeviceAddress.bytes+4)<<8 |
2374 *(pHddCtx->p2pDeviceAddress.bytes+5))));
Jeff Johnson295189b2012-06-20 16:38:30 -07002375 if (copy_to_user(priv_data.buf, pHddCtx->p2pDeviceAddress.bytes,
2376 sizeof(tSirMacAddr)))
2377 {
2378 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08002379 "%s: failed to copy data to user buffer", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002380 ret = -EFAULT;
2381 }
2382 }
Amar Singhal0974e402013-02-12 14:27:46 -08002383 else if(strncmp(command, "SETBAND", 7) == 0)
Jeff Johnson295189b2012-06-20 16:38:30 -07002384 {
Amar Singhal0974e402013-02-12 14:27:46 -08002385 tANI_U8 *ptr = command ;
Srinivas Girigowdade697412013-02-14 16:31:48 -08002386
Jeff Johnson295189b2012-06-20 16:38:30 -07002387 /* Change band request received */
Srinivas Girigowdade697412013-02-14 16:31:48 -08002388
2389 /* First 8 bytes will have "SETBAND " and
Jeff Johnson295189b2012-06-20 16:38:30 -07002390 * 9 byte will have band setting value */
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07002391 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Amar Singhal0974e402013-02-12 14:27:46 -08002392 "%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 +05302393 if(VOS_FTM_MODE != hdd_get_conparam())
2394 {
2395 /* Change band request received */
2396 ret = hdd_setBand_helper(pAdapter->dev, ptr);
2397 if(ret < 0)
2398 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
2399 "%s: failed to set band ret=%d", __func__, ret);
2400 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08002401 }
Kiet Lamf040f472013-11-20 21:15:23 +05302402 else if(strncmp(command, "SETWMMPS", 8) == 0)
2403 {
2404 tANI_U8 *ptr = command;
2405 ret = hdd_wmmps_helper(pAdapter, ptr);
2406 }
Agarwal Ashishef54a182014-12-16 15:07:31 +05302407
2408 else if(strncmp(command, "TDLSSCAN", 8) == 0)
2409 {
2410 tANI_U8 *ptr = command;
2411 ret = hdd_set_tdls_scan_type(pAdapter, ptr);
2412 }
2413
Jeff Johnson32d95a32012-09-10 13:15:23 -07002414 else if ( strncasecmp(command, "COUNTRY", 7) == 0 )
2415 {
2416 char *country_code;
2417
2418 country_code = command + 8;
Tushnim Bhattacharyya9cdf6082013-04-21 16:33:30 -07002419
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07002420 INIT_COMPLETION(pAdapter->change_country_code);
Tushnim Bhattacharyya9cdf6082013-04-21 16:33:30 -07002421 hdd_checkandupdate_dfssetting(pAdapter, country_code);
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -07002422#ifndef CONFIG_ENABLE_LINUX_REG
Gopichand Nakkaladacbcb52013-04-18 16:41:54 +05302423 hdd_checkandupdate_phymode(pAdapter, country_code);
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -07002424#endif
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07002425 ret = (int)sme_ChangeCountryCode(pHddCtx->hHal,
2426 (void *)(tSmeChangeCountryCallback)
2427 wlan_hdd_change_country_code_callback,
Abhishek Singha306a442013-11-07 18:39:01 +05302428 country_code, pAdapter, pHddCtx->pvosContext, eSIR_TRUE, eSIR_TRUE);
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07002429 if (eHAL_STATUS_SUCCESS == ret)
2430 {
2431 ret = wait_for_completion_interruptible_timeout(
2432 &pAdapter->change_country_code,
2433 msecs_to_jiffies(WLAN_WAIT_TIME_COUNTRY));
2434 if (0 >= ret)
2435 {
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002436 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: SME while setting country code timed out %d",
c_hpothu6ff1c3c2013-10-01 19:01:57 +05302437 __func__, ret);
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07002438 }
2439 }
2440 else
Jeff Johnson32d95a32012-09-10 13:15:23 -07002441 {
2442 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002443 "%s: SME Change Country code fail ret=%d", __func__, ret);
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07002444 ret = -EINVAL;
Jeff Johnson32d95a32012-09-10 13:15:23 -07002445 }
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07002446
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07002447 }
2448 /*
2449 command should be a string having format
2450 SET_SAP_CHANNEL_LIST <num of channels> <the channels seperated by spaces>
2451 */
Amar Singhal0974e402013-02-12 14:27:46 -08002452 else if(strncmp(command, "SET_SAP_CHANNEL_LIST", 20) == 0)
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07002453 {
Amar Singhal0974e402013-02-12 14:27:46 -08002454 tANI_U8 *ptr = command;
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07002455
2456 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002457 " Received Command to Set Preferred Channels for SAP in %s", __func__);
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07002458
Mahesh Kumar Kalikot Veetil2aad8d82013-02-07 12:31:28 -08002459 ret = sapSetPreferredChannel(ptr);
Jeff Johnson32d95a32012-09-10 13:15:23 -07002460 }
Sameer Thalappil45931fb2013-02-01 11:18:05 -08002461 else if(strncmp(command, "SETSUSPENDMODE", 14) == 0)
2462 {
2463 int suspend = 0;
2464 tANI_U8 *ptr = (tANI_U8*)command + 15;
2465
2466 suspend = *ptr - '0';
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302467 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2468 TRACE_CODE_HDD_SETSUSPENDMODE_IOCTL,
2469 pAdapter->sessionId, suspend));
Sameer Thalappil45931fb2013-02-01 11:18:05 -08002470 hdd_set_wlan_suspend_mode(suspend);
2471 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08002472#ifdef WLAN_FEATURE_NEIGHBOR_ROAMING
2473 else if (strncmp(command, "SETROAMTRIGGER", 14) == 0)
2474 {
2475 tANI_U8 *value = command;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002476 tANI_S8 rssi = 0;
Srinivas Girigowdade697412013-02-14 16:31:48 -08002477 tANI_U8 lookUpThreshold = CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_DEFAULT;
2478 eHalStatus status = eHAL_STATUS_SUCCESS;
2479
2480 /* Move pointer to ahead of SETROAMTRIGGER<delimiter> */
2481 value = value + 15;
2482
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002483 /* Convert the value from ascii to integer */
2484 ret = kstrtos8(value, 10, &rssi);
2485 if (ret < 0)
2486 {
2487 /* If the input value is greater than max value of datatype, then also
2488 kstrtou8 fails */
2489 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2490 "%s: kstrtou8 failed Input value may be out of range[%d - %d]",
Srinivas Girigowdafa7157d2013-10-31 10:14:22 -07002491 __func__,
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002492 CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MIN,
2493 CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MAX);
2494 ret = -EINVAL;
2495 goto exit;
2496 }
2497
Srinivas Girigowdade697412013-02-14 16:31:48 -08002498 lookUpThreshold = abs(rssi);
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002499
Srinivas Girigowdade697412013-02-14 16:31:48 -08002500 if ((lookUpThreshold < CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MIN) ||
2501 (lookUpThreshold > CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MAX))
2502 {
2503 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2504 "Neighbor lookup threshold value %d is out of range"
2505 " (Min: %d Max: %d)", lookUpThreshold,
2506 CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MIN,
2507 CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MAX);
2508 ret = -EINVAL;
2509 goto exit;
2510 }
2511
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302512 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2513 TRACE_CODE_HDD_SETROAMTRIGGER_IOCTL,
2514 pAdapter->sessionId, lookUpThreshold));
Srinivas Girigowdade697412013-02-14 16:31:48 -08002515 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2516 "%s: Received Command to Set Roam trigger"
2517 " (Neighbor lookup threshold) = %d", __func__, lookUpThreshold);
2518
2519 pHddCtx->cfg_ini->nNeighborLookupRssiThreshold = lookUpThreshold;
2520 status = sme_setNeighborLookupRssiThreshold((tHalHandle)(pHddCtx->hHal), lookUpThreshold);
2521 if (eHAL_STATUS_SUCCESS != status)
2522 {
2523 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2524 "%s: Failed to set roam trigger, try again", __func__);
2525 ret = -EPERM;
2526 goto exit;
2527 }
2528
2529 /* Set Reassoc threshold to (lookup rssi threshold + 5 dBm) */
mukul sharmad6e1fdd2014-06-23 19:19:09 +05302530 pHddCtx->cfg_ini->nNeighborReassocRssiThreshold = lookUpThreshold + 5;
Srinivas Girigowdade697412013-02-14 16:31:48 -08002531 sme_setNeighborReassocRssiThreshold((tHalHandle)(pHddCtx->hHal), lookUpThreshold + 5);
2532 }
2533 else if (strncmp(command, "GETROAMTRIGGER", 14) == 0)
2534 {
2535 tANI_U8 lookUpThreshold = sme_getNeighborLookupRssiThreshold((tHalHandle)(pHddCtx->hHal));
2536 int rssi = (-1) * lookUpThreshold;
2537 char extra[32];
2538 tANI_U8 len = 0;
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302539 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2540 TRACE_CODE_HDD_GETROAMTRIGGER_IOCTL,
2541 pAdapter->sessionId, lookUpThreshold));
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002542 len = scnprintf(extra, sizeof(extra), "%s %d", command, rssi);
Srinivas Girigowda91719232015-07-13 15:10:10 +05302543 len = VOS_MIN(priv_data.total_len, len + 1);
2544 if (copy_to_user(priv_data.buf, &extra, len))
Srinivas Girigowdade697412013-02-14 16:31:48 -08002545 {
2546 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2547 "%s: failed to copy data to user buffer", __func__);
2548 ret = -EFAULT;
2549 goto exit;
2550 }
2551 }
2552 else if (strncmp(command, "SETROAMSCANPERIOD", 17) == 0)
2553 {
2554 tANI_U8 *value = command;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002555 tANI_U8 roamScanPeriod = 0;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002556 tANI_U16 neighborEmptyScanRefreshPeriod = CFG_EMPTY_SCAN_REFRESH_PERIOD_DEFAULT;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002557
Srinivas Girigowdade697412013-02-14 16:31:48 -08002558 /* input refresh period is in terms of seconds */
2559 /* Move pointer to ahead of SETROAMSCANPERIOD<delimiter> */
2560 value = value + 18;
2561 /* Convert the value from ascii to integer */
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002562 ret = kstrtou8(value, 10, &roamScanPeriod);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002563 if (ret < 0)
2564 {
2565 /* If the input value is greater than max value of datatype, then also
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002566 kstrtou8 fails */
Srinivas Girigowdade697412013-02-14 16:31:48 -08002567 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002568 "%s: kstrtou8 failed Input value may be out of range[%d - %d]",
Srinivas Girigowdade697412013-02-14 16:31:48 -08002569 __func__,
Srinivas Girigowdab8edd1e2013-03-19 11:42:08 -07002570 (CFG_EMPTY_SCAN_REFRESH_PERIOD_MIN/1000),
2571 (CFG_EMPTY_SCAN_REFRESH_PERIOD_MAX/1000));
Srinivas Girigowdade697412013-02-14 16:31:48 -08002572 ret = -EINVAL;
2573 goto exit;
2574 }
2575
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002576 if ((roamScanPeriod < (CFG_EMPTY_SCAN_REFRESH_PERIOD_MIN/1000)) ||
2577 (roamScanPeriod > (CFG_EMPTY_SCAN_REFRESH_PERIOD_MAX/1000)))
Srinivas Girigowdade697412013-02-14 16:31:48 -08002578 {
2579 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002580 "Roam scan period value %d is out of range"
2581 " (Min: %d Max: %d)", roamScanPeriod,
Srinivas Girigowdab8edd1e2013-03-19 11:42:08 -07002582 (CFG_EMPTY_SCAN_REFRESH_PERIOD_MIN/1000),
2583 (CFG_EMPTY_SCAN_REFRESH_PERIOD_MAX/1000));
Srinivas Girigowdade697412013-02-14 16:31:48 -08002584 ret = -EINVAL;
2585 goto exit;
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302586 }
2587 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2588 TRACE_CODE_HDD_SETROAMSCANPERIOD_IOCTL,
2589 pAdapter->sessionId, roamScanPeriod));
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002590 neighborEmptyScanRefreshPeriod = roamScanPeriod * 1000;
Srinivas Girigowdade697412013-02-14 16:31:48 -08002591
2592 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2593 "%s: Received Command to Set roam scan period"
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002594 " (Empty Scan refresh period) = %d", __func__, roamScanPeriod);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002595
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002596 pHddCtx->cfg_ini->nEmptyScanRefreshPeriod = neighborEmptyScanRefreshPeriod;
2597 sme_UpdateEmptyScanRefreshPeriod((tHalHandle)(pHddCtx->hHal), neighborEmptyScanRefreshPeriod);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002598 }
2599 else if (strncmp(command, "GETROAMSCANPERIOD", 17) == 0)
2600 {
2601 tANI_U16 nEmptyScanRefreshPeriod = sme_getEmptyScanRefreshPeriod((tHalHandle)(pHddCtx->hHal));
2602 char extra[32];
2603 tANI_U8 len = 0;
2604
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302605 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2606 TRACE_CODE_HDD_GETROAMSCANPERIOD_IOCTL,
2607 pAdapter->sessionId, nEmptyScanRefreshPeriod));
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002608 len = scnprintf(extra, sizeof(extra), "%s %d",
2609 "GETROAMSCANPERIOD", (nEmptyScanRefreshPeriod/1000));
Srinivas Girigowdade697412013-02-14 16:31:48 -08002610 /* Returned value is in units of seconds */
Ratnam Rachuria72ba112015-07-17 13:27:03 +05302611 len = VOS_MIN(priv_data.total_len, len + 1);
2612 if (copy_to_user(priv_data.buf, &extra, len)) {
Srinivas Girigowdade697412013-02-14 16:31:48 -08002613 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2614 "%s: failed to copy data to user buffer", __func__);
2615 ret = -EFAULT;
2616 goto exit;
2617 }
2618 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002619 else if (strncmp(command, "SETROAMSCANREFRESHPERIOD", 24) == 0)
2620 {
2621 tANI_U8 *value = command;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002622 tANI_U8 roamScanRefreshPeriod = 0;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002623 tANI_U16 neighborScanRefreshPeriod = CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_DEFAULT;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002624
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002625 /* input refresh period is in terms of seconds */
2626 /* Move pointer to ahead of SETROAMSCANREFRESHPERIOD<delimiter> */
2627 value = value + 25;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002628
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002629 /* Convert the value from ascii to integer */
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002630 ret = kstrtou8(value, 10, &roamScanRefreshPeriod);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002631 if (ret < 0)
2632 {
2633 /* If the input value is greater than max value of datatype, then also
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002634 kstrtou8 fails */
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002635 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002636 "%s: kstrtou8 failed Input value may be out of range[%d - %d]",
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002637 __func__,
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002638 (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MIN/1000),
2639 (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MAX/1000));
2640 ret = -EINVAL;
2641 goto exit;
2642 }
2643
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002644 if ((roamScanRefreshPeriod < (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MIN/1000)) ||
2645 (roamScanRefreshPeriod > (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MAX/1000)))
2646 {
2647 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2648 "Neighbor scan results refresh period value %d is out of range"
2649 " (Min: %d Max: %d)", roamScanRefreshPeriod,
2650 (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MIN/1000),
2651 (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MAX/1000));
2652 ret = -EINVAL;
2653 goto exit;
2654 }
2655 neighborScanRefreshPeriod = roamScanRefreshPeriod * 1000;
2656
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002657 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2658 "%s: Received Command to Set roam scan refresh period"
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002659 " (Scan refresh period) = %d", __func__, roamScanRefreshPeriod);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002660
2661 pHddCtx->cfg_ini->nNeighborResultsRefreshPeriod = neighborScanRefreshPeriod;
2662 sme_setNeighborScanRefreshPeriod((tHalHandle)(pHddCtx->hHal), neighborScanRefreshPeriod);
2663 }
2664 else if (strncmp(command, "GETROAMSCANREFRESHPERIOD", 24) == 0)
2665 {
2666 tANI_U16 value = sme_getNeighborScanRefreshPeriod((tHalHandle)(pHddCtx->hHal));
2667 char extra[32];
2668 tANI_U8 len = 0;
2669
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002670 len = scnprintf(extra, sizeof(extra), "%s %d",
2671 "GETROAMSCANREFRESHPERIOD", (value/1000));
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002672 /* Returned value is in units of seconds */
Ratnam Rachuri2c9d6702015-07-17 13:25:16 +05302673 len = VOS_MIN(priv_data.total_len, len + 1);
2674 if (copy_to_user(priv_data.buf, &extra, len)) {
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002675 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2676 "%s: failed to copy data to user buffer", __func__);
2677 ret = -EFAULT;
2678 goto exit;
2679 }
2680 }
Varun Reddy Yeturu6d99ac82013-05-08 14:15:35 -07002681#ifdef FEATURE_WLAN_LFR
2682 /* SETROAMMODE */
2683 else if (strncmp(command, "SETROAMMODE", SIZE_OF_SETROAMMODE) == 0)
2684 {
2685 tANI_U8 *value = command;
2686 tANI_BOOLEAN roamMode = CFG_LFR_FEATURE_ENABLED_DEFAULT;
2687
2688 /* Move pointer to ahead of SETROAMMODE<delimiter> */
2689 value = value + SIZE_OF_SETROAMMODE + 1;
2690
2691 /* Convert the value from ascii to integer */
2692 ret = kstrtou8(value, SIZE_OF_SETROAMMODE, &roamMode);
2693 if (ret < 0)
2694 {
2695 /* If the input value is greater than max value of datatype, then also
2696 kstrtou8 fails */
2697 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2698 "%s: kstrtou8 failed range [%d - %d]", __func__,
2699 CFG_LFR_FEATURE_ENABLED_MIN,
2700 CFG_LFR_FEATURE_ENABLED_MAX);
2701 ret = -EINVAL;
2702 goto exit;
2703 }
2704 if ((roamMode < CFG_LFR_FEATURE_ENABLED_MIN) ||
2705 (roamMode > CFG_LFR_FEATURE_ENABLED_MAX))
2706 {
2707 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2708 "Roam Mode value %d is out of range"
2709 " (Min: %d Max: %d)", roamMode,
2710 CFG_LFR_FEATURE_ENABLED_MIN,
2711 CFG_LFR_FEATURE_ENABLED_MAX);
2712 ret = -EINVAL;
2713 goto exit;
2714 }
2715
2716 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2717 "%s: Received Command to Set Roam Mode = %d", __func__, roamMode);
2718 /*
2719 * Note that
2720 * SETROAMMODE 0 is to enable LFR while
2721 * SETROAMMODE 1 is to disable LFR, but
2722 * NotifyIsFastRoamIniFeatureEnabled 0/1 is to enable/disable.
2723 * So, we have to invert the value to call sme_UpdateIsFastRoamIniFeatureEnabled.
2724 */
2725 if (CFG_LFR_FEATURE_ENABLED_MIN == roamMode)
2726 roamMode = CFG_LFR_FEATURE_ENABLED_MAX; /* Roam enable */
2727 else
2728 roamMode = CFG_LFR_FEATURE_ENABLED_MIN; /* Roam disable */
2729
2730 pHddCtx->cfg_ini->isFastRoamIniFeatureEnabled = roamMode;
2731 sme_UpdateIsFastRoamIniFeatureEnabled((tHalHandle)(pHddCtx->hHal), roamMode);
2732 }
2733 /* GETROAMMODE */
Mahesh A Saptasagarec7d1092015-04-02 13:41:34 +05302734 else if (strncmp(command, "GETROAMMODE", SIZE_OF_GETROAMMODE) == 0)
Varun Reddy Yeturu6d99ac82013-05-08 14:15:35 -07002735 {
2736 tANI_BOOLEAN roamMode = sme_getIsLfrFeatureEnabled((tHalHandle)(pHddCtx->hHal));
2737 char extra[32];
2738 tANI_U8 len = 0;
2739
2740 /*
2741 * roamMode value shall be inverted because the sementics is different.
2742 */
2743 if (CFG_LFR_FEATURE_ENABLED_MIN == roamMode)
2744 roamMode = CFG_LFR_FEATURE_ENABLED_MAX;
2745 else
2746 roamMode = CFG_LFR_FEATURE_ENABLED_MIN;
2747
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002748 len = scnprintf(extra, sizeof(extra), "%s %d", command, roamMode);
Ratnam Rachuri28693eb2015-07-17 13:23:42 +05302749 len = VOS_MIN(priv_data.total_len, len + 1);
2750 if (copy_to_user(priv_data.buf, &extra, len)) {
Varun Reddy Yeturu6d99ac82013-05-08 14:15:35 -07002751 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2752 "%s: failed to copy data to user buffer", __func__);
2753 ret = -EFAULT;
2754 goto exit;
2755 }
2756 }
2757#endif
Srinivas Girigowdade697412013-02-14 16:31:48 -08002758#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002759#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowdade697412013-02-14 16:31:48 -08002760 else if (strncmp(command, "SETROAMDELTA", 12) == 0)
2761 {
2762 tANI_U8 *value = command;
2763 tANI_U8 roamRssiDiff = CFG_ROAM_RSSI_DIFF_DEFAULT;
2764
2765 /* Move pointer to ahead of SETROAMDELTA<delimiter> */
2766 value = value + 13;
2767 /* Convert the value from ascii to integer */
2768 ret = kstrtou8(value, 10, &roamRssiDiff);
2769 if (ret < 0)
2770 {
2771 /* If the input value is greater than max value of datatype, then also
2772 kstrtou8 fails */
2773 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2774 "%s: kstrtou8 failed range [%d - %d]", __func__,
2775 CFG_ROAM_RSSI_DIFF_MIN,
2776 CFG_ROAM_RSSI_DIFF_MAX);
2777 ret = -EINVAL;
2778 goto exit;
2779 }
2780
2781 if ((roamRssiDiff < CFG_ROAM_RSSI_DIFF_MIN) ||
2782 (roamRssiDiff > CFG_ROAM_RSSI_DIFF_MAX))
2783 {
2784 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2785 "Roam rssi diff value %d is out of range"
2786 " (Min: %d Max: %d)", roamRssiDiff,
2787 CFG_ROAM_RSSI_DIFF_MIN,
2788 CFG_ROAM_RSSI_DIFF_MAX);
2789 ret = -EINVAL;
2790 goto exit;
2791 }
2792
2793 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2794 "%s: Received Command to Set roam rssi diff = %d", __func__, roamRssiDiff);
2795
2796 pHddCtx->cfg_ini->RoamRssiDiff = roamRssiDiff;
2797 sme_UpdateRoamRssiDiff((tHalHandle)(pHddCtx->hHal), roamRssiDiff);
2798 }
Mahesh A Saptasagarec7d1092015-04-02 13:41:34 +05302799 else if (strncmp(command, "GETROAMDELTA", 12) == 0)
Srinivas Girigowdade697412013-02-14 16:31:48 -08002800 {
2801 tANI_U8 roamRssiDiff = sme_getRoamRssiDiff((tHalHandle)(pHddCtx->hHal));
2802 char extra[32];
2803 tANI_U8 len = 0;
2804
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302805 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2806 TRACE_CODE_HDD_GETROAMDELTA_IOCTL,
2807 pAdapter->sessionId, roamRssiDiff));
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002808 len = scnprintf(extra, sizeof(extra), "%s %d",
2809 command, roamRssiDiff);
Ratnam Rachuri22a3b402015-07-17 13:21:49 +05302810 len = VOS_MIN(priv_data.total_len, len + 1);
2811 if (copy_to_user(priv_data.buf, &extra, len)) {
Srinivas Girigowdade697412013-02-14 16:31:48 -08002812 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2813 "%s: failed to copy data to user buffer", __func__);
2814 ret = -EFAULT;
2815 goto exit;
2816 }
2817 }
2818#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002819#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowdade697412013-02-14 16:31:48 -08002820 else if (strncmp(command, "GETBAND", 7) == 0)
2821 {
2822 int band = -1;
2823 char extra[32];
2824 tANI_U8 len = 0;
2825 hdd_getBand_helper(pHddCtx, &band);
2826
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302827 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2828 TRACE_CODE_HDD_GETBAND_IOCTL,
2829 pAdapter->sessionId, band));
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002830 len = scnprintf(extra, sizeof(extra), "%s %d", command, band);
Ratnam Rachuri52139592015-07-17 13:17:29 +05302831 len = VOS_MIN(priv_data.total_len, len + 1);
2832 if (copy_to_user(priv_data.buf, &extra, len)) {
Srinivas Girigowdade697412013-02-14 16:31:48 -08002833 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2834 "%s: failed to copy data to user buffer", __func__);
2835 ret = -EFAULT;
2836 goto exit;
2837 }
2838 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08002839 else if (strncmp(command, "SETROAMSCANCHANNELS", 19) == 0)
2840 {
2841 tANI_U8 *value = command;
2842 tANI_U8 ChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
2843 tANI_U8 numChannels = 0;
2844 eHalStatus status = eHAL_STATUS_SUCCESS;
2845
2846 status = hdd_parse_channellist(value, ChannelList, &numChannels);
2847 if (eHAL_STATUS_SUCCESS != status)
2848 {
2849 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2850 "%s: Failed to parse channel list information", __func__);
2851 ret = -EINVAL;
2852 goto exit;
2853 }
2854
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302855 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2856 TRACE_CODE_HDD_SETROAMSCANCHANNELS_IOCTL,
2857 pAdapter->sessionId, numChannels));
Srinivas Girigowdade697412013-02-14 16:31:48 -08002858 if (numChannels > WNI_CFG_VALID_CHANNEL_LIST_LEN)
2859 {
2860 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2861 "%s: number of channels (%d) supported exceeded max (%d)", __func__,
2862 numChannels, WNI_CFG_VALID_CHANNEL_LIST_LEN);
2863 ret = -EINVAL;
2864 goto exit;
2865 }
2866 status = sme_ChangeRoamScanChannelList((tHalHandle)(pHddCtx->hHal), ChannelList,
2867 numChannels);
2868 if (eHAL_STATUS_SUCCESS != status)
2869 {
2870 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2871 "%s: Failed to update channel list information", __func__);
2872 ret = -EINVAL;
2873 goto exit;
2874 }
2875 }
2876 else if (strncmp(command, "GETROAMSCANCHANNELS", 19) == 0)
2877 {
2878 tANI_U8 ChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
2879 tANI_U8 numChannels = 0;
Jeff Johnson51b67782013-04-05 12:35:41 -07002880 tANI_U8 j = 0;
Srinivas Girigowdade697412013-02-14 16:31:48 -08002881 char extra[128] = {0};
Jeff Johnson51b67782013-04-05 12:35:41 -07002882 int len;
Srinivas Girigowdade697412013-02-14 16:31:48 -08002883
2884 if (eHAL_STATUS_SUCCESS != sme_getRoamScanChannelList( (tHalHandle)(pHddCtx->hHal),
2885 ChannelList, &numChannels ))
2886 {
2887 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
2888 "%s: failed to get roam scan channel list", __func__);
2889 ret = -EFAULT;
2890 goto exit;
2891 }
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302892 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2893 TRACE_CODE_HDD_GETROAMSCANCHANNELS_IOCTL,
2894 pAdapter->sessionId, numChannels));
Srinivas Girigowdade697412013-02-14 16:31:48 -08002895 /* output channel list is of the format
2896 [Number of roam scan channels][Channel1][Channel2]... */
2897 /* copy the number of channels in the 0th index */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002898 len = scnprintf(extra, sizeof(extra), "%s %d", command, numChannels);
Sushant Kaushika08ca192015-09-16 15:52:04 +05302899 for (j = 0; (j < numChannels) && len <= sizeof(extra); j++)
Srinivas Girigowdade697412013-02-14 16:31:48 -08002900 {
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002901 len += scnprintf(extra + len, sizeof(extra) - len, " %d",
2902 ChannelList[j]);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002903 }
2904
Sushant Kaushikc9b8be52015-07-15 16:41:27 +05302905 len = VOS_MIN(priv_data.total_len, len + 1);
2906 if (copy_to_user(priv_data.buf, &extra, len))
Srinivas Girigowdade697412013-02-14 16:31:48 -08002907 {
2908 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2909 "%s: failed to copy data to user buffer", __func__);
2910 ret = -EFAULT;
2911 goto exit;
2912 }
2913 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002914 else if (strncmp(command, "GETCCXMODE", 10) == 0)
2915 {
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002916 tANI_BOOLEAN eseMode = sme_getIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal));
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002917 char extra[32];
2918 tANI_U8 len = 0;
2919
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002920 /* Check if the features OKC/ESE/11R are supported simultaneously,
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07002921 then this operation is not permitted (return FAILURE) */
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002922 if (eseMode &&
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07002923 hdd_is_okc_mode_enabled(pHddCtx) &&
2924 sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal)))
2925 {
2926 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002927 "%s: OKC/ESE/11R are supported simultaneously"
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07002928 " hence this operation is not permitted!", __func__);
2929 ret = -EPERM;
2930 goto exit;
2931 }
2932
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002933 len = scnprintf(extra, sizeof(extra), "%s %d",
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002934 "GETCCXMODE", eseMode);
Sushant Kaushikf8abd352015-07-15 16:37:49 +05302935 len = VOS_MIN(priv_data.total_len, len + 1);
2936 if (copy_to_user(priv_data.buf, &extra, len))
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002937 {
2938 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2939 "%s: failed to copy data to user buffer", __func__);
2940 ret = -EFAULT;
2941 goto exit;
2942 }
2943 }
2944 else if (strncmp(command, "GETOKCMODE", 10) == 0)
2945 {
2946 tANI_BOOLEAN okcMode = hdd_is_okc_mode_enabled(pHddCtx);
2947 char extra[32];
2948 tANI_U8 len = 0;
2949
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002950 /* Check if the features OKC/ESE/11R are supported simultaneously,
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07002951 then this operation is not permitted (return FAILURE) */
2952 if (okcMode &&
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002953 sme_getIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal)) &&
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07002954 sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal)))
2955 {
2956 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002957 "%s: OKC/ESE/11R are supported simultaneously"
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07002958 " hence this operation is not permitted!", __func__);
2959 ret = -EPERM;
2960 goto exit;
2961 }
2962
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002963 len = scnprintf(extra, sizeof(extra), "%s %d",
2964 "GETOKCMODE", okcMode);
Sushant Kaushikbc2fb5c2015-07-15 16:43:16 +05302965 len = VOS_MIN(priv_data.total_len, len + 1);
2966 if (copy_to_user(priv_data.buf, &extra, len))
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002967 {
2968 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2969 "%s: failed to copy data to user buffer", __func__);
2970 ret = -EFAULT;
2971 goto exit;
2972 }
2973 }
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002974 else if (strncmp(command, "GETFASTROAM", 11) == 0)
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002975 {
2976 tANI_BOOLEAN lfrMode = sme_getIsLfrFeatureEnabled((tHalHandle)(pHddCtx->hHal));
2977 char extra[32];
2978 tANI_U8 len = 0;
2979
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002980 len = scnprintf(extra, sizeof(extra), "%s %d",
2981 "GETFASTROAM", lfrMode);
Sushant Kaushik4da7ec92015-07-15 16:39:32 +05302982 len = VOS_MIN(priv_data.total_len, len + 1);
2983 if (copy_to_user(priv_data.buf, &extra, len))
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002984 {
2985 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2986 "%s: failed to copy data to user buffer", __func__);
2987 ret = -EFAULT;
2988 goto exit;
2989 }
2990 }
2991 else if (strncmp(command, "GETFASTTRANSITION", 17) == 0)
2992 {
2993 tANI_BOOLEAN ft = sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal));
2994 char extra[32];
2995 tANI_U8 len = 0;
2996
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002997 len = scnprintf(extra, sizeof(extra), "%s %d",
2998 "GETFASTTRANSITION", ft);
Sushant Kaushik231a4452015-07-15 16:23:56 +05302999 len = VOS_MIN(priv_data.total_len, len + 1);
3000 if (copy_to_user(priv_data.buf, &extra, len))
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003001 {
3002 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3003 "%s: failed to copy data to user buffer", __func__);
3004 ret = -EFAULT;
3005 goto exit;
3006 }
3007 }
3008 else if (strncmp(command, "SETROAMSCANCHANNELMINTIME", 25) == 0)
3009 {
3010 tANI_U8 *value = command;
3011 tANI_U8 minTime = CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_DEFAULT;
3012
3013 /* Move pointer to ahead of SETROAMSCANCHANNELMINTIME<delimiter> */
3014 value = value + 26;
3015 /* Convert the value from ascii to integer */
3016 ret = kstrtou8(value, 10, &minTime);
3017 if (ret < 0)
3018 {
3019 /* If the input value is greater than max value of datatype, then also
3020 kstrtou8 fails */
3021 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3022 "%s: kstrtou8 failed range [%d - %d]", __func__,
3023 CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MIN,
3024 CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MAX);
3025 ret = -EINVAL;
3026 goto exit;
3027 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003028 if ((minTime < CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MIN) ||
3029 (minTime > CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MAX))
3030 {
3031 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3032 "scan min channel time value %d is out of range"
3033 " (Min: %d Max: %d)", minTime,
3034 CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MIN,
3035 CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MAX);
3036 ret = -EINVAL;
3037 goto exit;
3038 }
3039
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05303040 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
3041 TRACE_CODE_HDD_SETROAMSCANCHANNELMINTIME_IOCTL,
3042 pAdapter->sessionId, minTime));
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003043 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3044 "%s: Received Command to change channel min time = %d", __func__, minTime);
3045
3046 pHddCtx->cfg_ini->nNeighborScanMinChanTime = minTime;
3047 sme_setNeighborScanMinChanTime((tHalHandle)(pHddCtx->hHal), minTime);
3048 }
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003049 else if (strncmp(command, "SENDACTIONFRAME", 15) == 0)
3050 {
3051 tANI_U8 *value = command;
3052 tANI_U8 channel = 0;
3053 tANI_U8 dwellTime = 0;
3054 tANI_U8 bufLen = 0;
3055 tANI_U8 *buf = NULL;
3056 tSirMacAddr targetApBssid;
3057 eHalStatus status = eHAL_STATUS_SUCCESS;
3058 struct ieee80211_channel chan;
3059 tANI_U8 finalLen = 0;
3060 tANI_U8 *finalBuf = NULL;
3061 tANI_U8 temp = 0;
3062 u64 cookie;
3063 hdd_station_ctx_t *pHddStaCtx = NULL;
3064 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
3065
3066 /* if not associated, no need to send action frame */
3067 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
3068 {
3069 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s:Not associated!",__func__);
3070 ret = -EINVAL;
3071 goto exit;
3072 }
3073
3074 status = hdd_parse_send_action_frame_data(value, targetApBssid, &channel,
3075 &dwellTime, &buf, &bufLen);
3076 if (eHAL_STATUS_SUCCESS != status)
3077 {
3078 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3079 "%s: Failed to parse send action frame data", __func__);
3080 ret = -EINVAL;
3081 goto exit;
3082 }
3083
3084 /* if the target bssid is different from currently associated AP,
3085 then no need to send action frame */
3086 if (VOS_TRUE != vos_mem_compare(targetApBssid,
3087 pHddStaCtx->conn_info.bssId, sizeof(tSirMacAddr)))
3088 {
3089 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s:STA is not associated to this AP!",__func__);
3090 ret = -EINVAL;
Jeff Johnson11c33152013-04-16 17:52:40 -07003091 vos_mem_free(buf);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08003092 buf = NULL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003093 goto exit;
3094 }
3095
3096 /* if the channel number is different from operating channel then
3097 no need to send action frame */
3098 if (channel != pHddStaCtx->conn_info.operationChannel)
3099 {
3100 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3101 "%s: channel(%d) is different from operating channel(%d)",
3102 __func__, channel, pHddStaCtx->conn_info.operationChannel);
3103 ret = -EINVAL;
Jeff Johnson11c33152013-04-16 17:52:40 -07003104 vos_mem_free(buf);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08003105 buf = NULL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003106 goto exit;
3107 }
3108 chan.center_freq = sme_ChnToFreq(channel);
3109
3110 finalLen = bufLen + 24;
3111 finalBuf = vos_mem_malloc(finalLen);
3112 if (NULL == finalBuf)
3113 {
3114 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "%s:memory allocation failed",__func__);
3115 ret = -ENOMEM;
Jeff Johnson11c33152013-04-16 17:52:40 -07003116 vos_mem_free(buf);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08003117 buf = NULL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003118 goto exit;
3119 }
3120 vos_mem_zero(finalBuf, finalLen);
3121
3122 /* Fill subtype */
3123 temp = SIR_MAC_MGMT_ACTION << 4;
3124 vos_mem_copy(finalBuf + 0, &temp, sizeof(temp));
3125
3126 /* Fill type */
3127 temp = SIR_MAC_MGMT_FRAME;
3128 vos_mem_copy(finalBuf + 2, &temp, sizeof(temp));
3129
3130 /* Fill destination address (bssid of the AP) */
3131 vos_mem_copy(finalBuf + 4, targetApBssid, sizeof(targetApBssid));
3132
Srinivas Girigowdab27c0192013-06-03 10:19:56 -07003133 /* Fill source address (STA mac address) */
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003134 vos_mem_copy(finalBuf + 10, pAdapter->macAddressCurrent.bytes, sizeof(pAdapter->macAddressCurrent.bytes));
3135
Srinivas Girigowdab27c0192013-06-03 10:19:56 -07003136 /* Fill BSSID (AP mac address) */
3137 vos_mem_copy(finalBuf + 16, targetApBssid, sizeof(targetApBssid));
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003138
3139 /* Fill received buffer from 24th address */
3140 vos_mem_copy(finalBuf + 24, buf, bufLen);
3141
Jeff Johnson11c33152013-04-16 17:52:40 -07003142 /* done with the parsed buffer */
3143 vos_mem_free(buf);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08003144 buf = NULL;
Jeff Johnson11c33152013-04-16 17:52:40 -07003145
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05303146#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
3147 params.chan = &chan;
3148 params.offchan = 0;
3149 params.wait = dwellTime;
3150 params.buf = finalBuf;
3151 params.len = finalLen;
3152 params.no_cck = 1;
3153 params.dont_wait_for_ack = 1;
3154 ret = wlan_hdd_mgmt_tx(NULL, &pAdapter->wdev, &params, &cookie);
3155#else
DARAM SUDHA39eede62014-02-12 11:16:40 +05303156 wlan_hdd_mgmt_tx( NULL,
Yue Maf49ba872013-08-19 12:04:25 -07003157#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
3158 &(pAdapter->wdev),
3159#else
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07003160 pAdapter->dev,
Yue Maf49ba872013-08-19 12:04:25 -07003161#endif
3162 &chan, 0,
3163#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0))
3164 NL80211_CHAN_HT20, 1,
3165#endif
3166 dwellTime, finalBuf, finalLen, 1,
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003167 1, &cookie );
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05303168#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0)*/
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003169 vos_mem_free(finalBuf);
3170 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003171 else if (strncmp(command, "GETROAMSCANCHANNELMINTIME", 25) == 0)
3172 {
3173 tANI_U16 val = sme_getNeighborScanMinChanTime((tHalHandle)(pHddCtx->hHal));
3174 char extra[32];
3175 tANI_U8 len = 0;
3176
3177 /* value is interms of msec */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003178 len = scnprintf(extra, sizeof(extra), "%s %d",
3179 "GETROAMSCANCHANNELMINTIME", val);
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05303180 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
3181 TRACE_CODE_HDD_GETROAMSCANCHANNELMINTIME_IOCTL,
3182 pAdapter->sessionId, val));
Sushant Kaushikbb8c52c2015-07-15 16:36:23 +05303183 len = VOS_MIN(priv_data.total_len, len + 1);
3184 if (copy_to_user(priv_data.buf, &extra, len))
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003185 {
3186 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3187 "%s: failed to copy data to user buffer", __func__);
3188 ret = -EFAULT;
3189 goto exit;
3190 }
3191 }
3192 else if (strncmp(command, "SETSCANCHANNELTIME", 18) == 0)
3193 {
3194 tANI_U8 *value = command;
Varun Reddy Yeturu3885a662013-06-19 07:10:37 -07003195 tANI_U16 maxTime = CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_DEFAULT;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003196
3197 /* Move pointer to ahead of SETSCANCHANNELTIME<delimiter> */
3198 value = value + 19;
3199 /* Convert the value from ascii to integer */
Varun Reddy Yeturu3885a662013-06-19 07:10:37 -07003200 ret = kstrtou16(value, 10, &maxTime);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003201 if (ret < 0)
3202 {
3203 /* If the input value is greater than max value of datatype, then also
Varun Reddy Yeturu3885a662013-06-19 07:10:37 -07003204 kstrtou16 fails */
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003205 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Varun Reddy Yeturu3885a662013-06-19 07:10:37 -07003206 "%s: kstrtou16 failed range [%d - %d]", __func__,
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003207 CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MIN,
3208 CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MAX);
3209 ret = -EINVAL;
3210 goto exit;
3211 }
3212
3213 if ((maxTime < CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MIN) ||
3214 (maxTime > CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MAX))
3215 {
3216 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3217 "lfr mode value %d is out of range"
3218 " (Min: %d Max: %d)", maxTime,
3219 CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MIN,
3220 CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MAX);
3221 ret = -EINVAL;
3222 goto exit;
3223 }
3224
3225 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3226 "%s: Received Command to change channel max time = %d", __func__, maxTime);
3227
3228 pHddCtx->cfg_ini->nNeighborScanMaxChanTime = maxTime;
3229 sme_setNeighborScanMaxChanTime((tHalHandle)(pHddCtx->hHal), maxTime);
3230 }
3231 else if (strncmp(command, "GETSCANCHANNELTIME", 18) == 0)
3232 {
3233 tANI_U16 val = sme_getNeighborScanMaxChanTime((tHalHandle)(pHddCtx->hHal));
3234 char extra[32];
3235 tANI_U8 len = 0;
3236
3237 /* value is interms of msec */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003238 len = scnprintf(extra, sizeof(extra), "%s %d",
3239 "GETSCANCHANNELTIME", val);
Ratheesh S Pacbfa932015-07-16 15:27:18 +05303240 len = VOS_MIN(priv_data.total_len, len + 1);
3241 if (copy_to_user(priv_data.buf, &extra, len))
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003242 {
3243 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3244 "%s: failed to copy data to user buffer", __func__);
3245 ret = -EFAULT;
3246 goto exit;
3247 }
3248 }
3249 else if (strncmp(command, "SETSCANHOMETIME", 15) == 0)
3250 {
3251 tANI_U8 *value = command;
3252 tANI_U16 val = CFG_NEIGHBOR_SCAN_TIMER_PERIOD_DEFAULT;
3253
3254 /* Move pointer to ahead of SETSCANHOMETIME<delimiter> */
3255 value = value + 16;
3256 /* Convert the value from ascii to integer */
3257 ret = kstrtou16(value, 10, &val);
3258 if (ret < 0)
3259 {
3260 /* If the input value is greater than max value of datatype, then also
3261 kstrtou16 fails */
3262 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3263 "%s: kstrtou16 failed range [%d - %d]", __func__,
3264 CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MIN,
3265 CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MAX);
3266 ret = -EINVAL;
3267 goto exit;
3268 }
3269
3270 if ((val < CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MIN) ||
3271 (val > CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MAX))
3272 {
3273 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3274 "scan home time value %d is out of range"
3275 " (Min: %d Max: %d)", val,
3276 CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MIN,
3277 CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MAX);
3278 ret = -EINVAL;
3279 goto exit;
3280 }
3281
3282 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3283 "%s: Received Command to change scan home time = %d", __func__, val);
3284
3285 pHddCtx->cfg_ini->nNeighborScanPeriod = val;
3286 sme_setNeighborScanPeriod((tHalHandle)(pHddCtx->hHal), val);
3287 }
3288 else if (strncmp(command, "GETSCANHOMETIME", 15) == 0)
3289 {
3290 tANI_U16 val = sme_getNeighborScanPeriod((tHalHandle)(pHddCtx->hHal));
3291 char extra[32];
3292 tANI_U8 len = 0;
3293
3294 /* value is interms of msec */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003295 len = scnprintf(extra, sizeof(extra), "%s %d",
3296 "GETSCANHOMETIME", val);
Ratheesh S P728d7c62015-07-16 15:38:58 +05303297 len = VOS_MIN(priv_data.total_len, len + 1);
3298 if (copy_to_user(priv_data.buf, &extra, len))
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003299 {
3300 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3301 "%s: failed to copy data to user buffer", __func__);
3302 ret = -EFAULT;
3303 goto exit;
3304 }
3305 }
3306 else if (strncmp(command, "SETROAMINTRABAND", 16) == 0)
3307 {
3308 tANI_U8 *value = command;
3309 tANI_U8 val = CFG_ROAM_INTRA_BAND_DEFAULT;
3310
3311 /* Move pointer to ahead of SETROAMINTRABAND<delimiter> */
3312 value = value + 17;
3313 /* Convert the value from ascii to integer */
3314 ret = kstrtou8(value, 10, &val);
3315 if (ret < 0)
3316 {
3317 /* If the input value is greater than max value of datatype, then also
3318 kstrtou8 fails */
3319 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3320 "%s: kstrtou8 failed range [%d - %d]", __func__,
3321 CFG_ROAM_INTRA_BAND_MIN,
3322 CFG_ROAM_INTRA_BAND_MAX);
3323 ret = -EINVAL;
3324 goto exit;
3325 }
3326
3327 if ((val < CFG_ROAM_INTRA_BAND_MIN) ||
3328 (val > CFG_ROAM_INTRA_BAND_MAX))
3329 {
3330 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3331 "intra band mode value %d is out of range"
3332 " (Min: %d Max: %d)", val,
3333 CFG_ROAM_INTRA_BAND_MIN,
3334 CFG_ROAM_INTRA_BAND_MAX);
3335 ret = -EINVAL;
3336 goto exit;
3337 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003338 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3339 "%s: Received Command to change intra band = %d", __func__, val);
3340
3341 pHddCtx->cfg_ini->nRoamIntraBand = val;
3342 sme_setRoamIntraBand((tHalHandle)(pHddCtx->hHal), val);
3343 }
3344 else if (strncmp(command, "GETROAMINTRABAND", 16) == 0)
3345 {
3346 tANI_U16 val = sme_getRoamIntraBand((tHalHandle)(pHddCtx->hHal));
3347 char extra[32];
3348 tANI_U8 len = 0;
3349
3350 /* value is interms of msec */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003351 len = scnprintf(extra, sizeof(extra), "%s %d",
3352 "GETROAMINTRABAND", val);
Ratheesh S P2dd2a3e2015-07-16 15:34:23 +05303353 len = VOS_MIN(priv_data.total_len, len + 1);
3354 if (copy_to_user(priv_data.buf, &extra, len))
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003355 {
3356 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3357 "%s: failed to copy data to user buffer", __func__);
3358 ret = -EFAULT;
3359 goto exit;
3360 }
3361 }
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003362 else if (strncmp(command, "SETSCANNPROBES", 14) == 0)
3363 {
3364 tANI_U8 *value = command;
3365 tANI_U8 nProbes = CFG_ROAM_SCAN_N_PROBES_DEFAULT;
3366
3367 /* Move pointer to ahead of SETSCANNPROBES<delimiter> */
3368 value = value + 15;
3369 /* Convert the value from ascii to integer */
3370 ret = kstrtou8(value, 10, &nProbes);
3371 if (ret < 0)
3372 {
3373 /* If the input value is greater than max value of datatype, then also
3374 kstrtou8 fails */
3375 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3376 "%s: kstrtou8 failed range [%d - %d]", __func__,
3377 CFG_ROAM_SCAN_N_PROBES_MIN,
3378 CFG_ROAM_SCAN_N_PROBES_MAX);
3379 ret = -EINVAL;
3380 goto exit;
3381 }
3382
3383 if ((nProbes < CFG_ROAM_SCAN_N_PROBES_MIN) ||
3384 (nProbes > CFG_ROAM_SCAN_N_PROBES_MAX))
3385 {
3386 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3387 "NProbes value %d is out of range"
3388 " (Min: %d Max: %d)", nProbes,
3389 CFG_ROAM_SCAN_N_PROBES_MIN,
3390 CFG_ROAM_SCAN_N_PROBES_MAX);
3391 ret = -EINVAL;
3392 goto exit;
3393 }
3394
3395 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3396 "%s: Received Command to Set nProbes = %d", __func__, nProbes);
3397
3398 pHddCtx->cfg_ini->nProbes = nProbes;
3399 sme_UpdateRoamScanNProbes((tHalHandle)(pHddCtx->hHal), nProbes);
3400 }
Mahesh A Saptasagarec7d1092015-04-02 13:41:34 +05303401 else if (strncmp(command, "GETSCANNPROBES", 14) == 0)
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003402 {
3403 tANI_U8 val = sme_getRoamScanNProbes((tHalHandle)(pHddCtx->hHal));
3404 char extra[32];
3405 tANI_U8 len = 0;
3406
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003407 len = scnprintf(extra, sizeof(extra), "%s %d", command, val);
Ratnam Rachuri6da525d2015-08-07 13:55:54 +05303408 len = VOS_MIN(priv_data.total_len, len + 1);
3409 if (copy_to_user(priv_data.buf, &extra, len)) {
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003410 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3411 "%s: failed to copy data to user buffer", __func__);
3412 ret = -EFAULT;
3413 goto exit;
3414 }
3415 }
3416 else if (strncmp(command, "SETSCANHOMEAWAYTIME", 19) == 0)
3417 {
3418 tANI_U8 *value = command;
3419 tANI_U16 homeAwayTime = CFG_ROAM_SCAN_HOME_AWAY_TIME_DEFAULT;
3420
3421 /* Move pointer to ahead of SETSCANHOMEAWAYTIME<delimiter> */
3422 /* input value is in units of msec */
3423 value = value + 20;
3424 /* Convert the value from ascii to integer */
3425 ret = kstrtou16(value, 10, &homeAwayTime);
3426 if (ret < 0)
3427 {
3428 /* If the input value is greater than max value of datatype, then also
3429 kstrtou8 fails */
3430 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3431 "%s: kstrtou8 failed range [%d - %d]", __func__,
3432 CFG_ROAM_SCAN_HOME_AWAY_TIME_MIN,
3433 CFG_ROAM_SCAN_HOME_AWAY_TIME_MAX);
3434 ret = -EINVAL;
3435 goto exit;
3436 }
3437
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003438 if ((homeAwayTime < CFG_ROAM_SCAN_HOME_AWAY_TIME_MIN) ||
3439 (homeAwayTime > CFG_ROAM_SCAN_HOME_AWAY_TIME_MAX))
3440 {
3441 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3442 "homeAwayTime value %d is out of range"
3443 " (Min: %d Max: %d)", homeAwayTime,
3444 CFG_ROAM_SCAN_HOME_AWAY_TIME_MIN,
3445 CFG_ROAM_SCAN_HOME_AWAY_TIME_MAX);
3446 ret = -EINVAL;
3447 goto exit;
3448 }
3449
3450 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3451 "%s: Received Command to Set scan away time = %d", __func__, homeAwayTime);
Srinivas Girigowda6cf0b822013-06-27 14:00:20 -07003452 if (pHddCtx->cfg_ini->nRoamScanHomeAwayTime != homeAwayTime)
3453 {
3454 pHddCtx->cfg_ini->nRoamScanHomeAwayTime = homeAwayTime;
3455 sme_UpdateRoamScanHomeAwayTime((tHalHandle)(pHddCtx->hHal), homeAwayTime, eANI_BOOLEAN_TRUE);
3456 }
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003457 }
Mahesh A Saptasagarec7d1092015-04-02 13:41:34 +05303458 else if (strncmp(command, "GETSCANHOMEAWAYTIME", 19) == 0)
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003459 {
3460 tANI_U16 val = sme_getRoamScanHomeAwayTime((tHalHandle)(pHddCtx->hHal));
3461 char extra[32];
3462 tANI_U8 len = 0;
3463
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003464 len = scnprintf(extra, sizeof(extra), "%s %d", command, val);
Ratnam Rachuri51a5ad12015-08-07 14:06:37 +05303465 len = VOS_MIN(priv_data.total_len, len + 1);
3466 if (copy_to_user(priv_data.buf, &extra, len)) {
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003467 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3468 "%s: failed to copy data to user buffer", __func__);
3469 ret = -EFAULT;
3470 goto exit;
3471 }
3472 }
3473 else if (strncmp(command, "REASSOC", 7) == 0)
3474 {
3475 tANI_U8 *value = command;
3476 tANI_U8 channel = 0;
3477 tSirMacAddr targetApBssid;
3478 eHalStatus status = eHAL_STATUS_SUCCESS;
Varun Reddy Yeturucc661d22013-05-20 11:47:10 -07003479#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
3480 tCsrHandoffRequest handoffInfo;
3481#endif
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003482 hdd_station_ctx_t *pHddStaCtx = NULL;
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003483 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
3484
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003485 /* if not associated, no need to proceed with reassoc */
3486 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
3487 {
3488 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s:Not associated!",__func__);
3489 ret = -EINVAL;
3490 goto exit;
3491 }
3492
3493 status = hdd_parse_reassoc_command_data(value, targetApBssid, &channel);
3494 if (eHAL_STATUS_SUCCESS != status)
3495 {
3496 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3497 "%s: Failed to parse reassoc command data", __func__);
3498 ret = -EINVAL;
3499 goto exit;
3500 }
3501
3502 /* if the target bssid is same as currently associated AP,
3503 then no need to proceed with reassoc */
3504 if (VOS_TRUE == vos_mem_compare(targetApBssid,
3505 pHddStaCtx->conn_info.bssId, sizeof(tSirMacAddr)))
3506 {
3507 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 +05303508 ret = 0;
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003509 goto exit;
3510 }
3511
3512 /* Check channel number is a valid channel number */
3513 if(VOS_STATUS_SUCCESS !=
3514 wlan_hdd_validate_operation_channel(pAdapter, channel))
3515 {
3516 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08003517 "%s: Invalid Channel [%d]", __func__, channel);
c_manjee6de1f452015-12-08 14:13:28 +05303518
3519 ret = -EINVAL;
3520 goto exit;
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003521 }
3522
3523 /* Proceed with reassoc */
Varun Reddy Yeturucc661d22013-05-20 11:47:10 -07003524#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
3525 handoffInfo.channel = channel;
3526 vos_mem_copy(handoffInfo.bssid, targetApBssid, sizeof(tSirMacAddr));
3527 sme_HandoffRequest(pHddCtx->hHal, &handoffInfo);
3528#endif
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003529 }
Srinivas Girigowdaad34ca92013-10-22 10:54:29 -07003530 else if (strncmp(command, "SETWESMODE", 10) == 0)
3531 {
3532 tANI_U8 *value = command;
3533 tANI_BOOLEAN wesMode = CFG_ENABLE_WES_MODE_NAME_DEFAULT;
3534
3535 /* Move pointer to ahead of SETWESMODE<delimiter> */
3536 value = value + 11;
3537 /* Convert the value from ascii to integer */
3538 ret = kstrtou8(value, 10, &wesMode);
3539 if (ret < 0)
3540 {
3541 /* If the input value is greater than max value of datatype, then also
3542 kstrtou8 fails */
3543 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3544 "%s: kstrtou8 failed range [%d - %d]", __func__,
3545 CFG_ENABLE_WES_MODE_NAME_MIN,
3546 CFG_ENABLE_WES_MODE_NAME_MAX);
3547 ret = -EINVAL;
3548 goto exit;
3549 }
3550
3551 if ((wesMode < CFG_ENABLE_WES_MODE_NAME_MIN) ||
3552 (wesMode > CFG_ENABLE_WES_MODE_NAME_MAX))
3553 {
3554 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3555 "WES Mode value %d is out of range"
3556 " (Min: %d Max: %d)", wesMode,
3557 CFG_ENABLE_WES_MODE_NAME_MIN,
3558 CFG_ENABLE_WES_MODE_NAME_MAX);
3559 ret = -EINVAL;
3560 goto exit;
3561 }
3562 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3563 "%s: Received Command to Set WES Mode rssi diff = %d", __func__, wesMode);
3564
3565 pHddCtx->cfg_ini->isWESModeEnabled = wesMode;
3566 sme_UpdateWESMode((tHalHandle)(pHddCtx->hHal), wesMode);
3567 }
Mahesh A Saptasagarec7d1092015-04-02 13:41:34 +05303568 else if (strncmp(command, "GETWESMODE", 10) == 0)
Srinivas Girigowdaad34ca92013-10-22 10:54:29 -07003569 {
3570 tANI_BOOLEAN wesMode = sme_GetWESMode((tHalHandle)(pHddCtx->hHal));
3571 char extra[32];
3572 tANI_U8 len = 0;
3573
Arif Hussain826d9412013-11-12 16:44:54 -08003574 len = scnprintf(extra, sizeof(extra), "%s %d", command, wesMode);
Ratnam Rachuri8fe90c62015-08-07 14:03:26 +05303575 len = VOS_MIN(priv_data.total_len, len + 1);
3576 if (copy_to_user(priv_data.buf, &extra, len)) {
Srinivas Girigowdaad34ca92013-10-22 10:54:29 -07003577 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3578 "%s: failed to copy data to user buffer", __func__);
3579 ret = -EFAULT;
3580 goto exit;
3581 }
3582 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003583#endif /* WLAN_FEATURE_VOWIFI_11R || FEATURE_WLAN_ESE || FEATURE_WLAN_LFR */
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003584#ifdef FEATURE_WLAN_LFR
3585 else if (strncmp(command, "SETFASTROAM", 11) == 0)
3586 {
3587 tANI_U8 *value = command;
3588 tANI_U8 lfrMode = CFG_LFR_FEATURE_ENABLED_DEFAULT;
3589
3590 /* Move pointer to ahead of SETFASTROAM<delimiter> */
3591 value = value + 12;
3592 /* Convert the value from ascii to integer */
3593 ret = kstrtou8(value, 10, &lfrMode);
3594 if (ret < 0)
3595 {
3596 /* If the input value is greater than max value of datatype, then also
3597 kstrtou8 fails */
3598 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3599 "%s: kstrtou8 failed range [%d - %d]", __func__,
3600 CFG_LFR_FEATURE_ENABLED_MIN,
3601 CFG_LFR_FEATURE_ENABLED_MAX);
3602 ret = -EINVAL;
3603 goto exit;
3604 }
3605
3606 if ((lfrMode < CFG_LFR_FEATURE_ENABLED_MIN) ||
3607 (lfrMode > CFG_LFR_FEATURE_ENABLED_MAX))
3608 {
3609 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3610 "lfr mode value %d is out of range"
3611 " (Min: %d Max: %d)", lfrMode,
3612 CFG_LFR_FEATURE_ENABLED_MIN,
3613 CFG_LFR_FEATURE_ENABLED_MAX);
3614 ret = -EINVAL;
3615 goto exit;
3616 }
3617
3618 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3619 "%s: Received Command to change lfr mode = %d", __func__, lfrMode);
3620
3621 pHddCtx->cfg_ini->isFastRoamIniFeatureEnabled = lfrMode;
3622 sme_UpdateIsFastRoamIniFeatureEnabled((tHalHandle)(pHddCtx->hHal), lfrMode);
3623 }
3624#endif
3625#ifdef WLAN_FEATURE_VOWIFI_11R
3626 else if (strncmp(command, "SETFASTTRANSITION", 17) == 0)
3627 {
3628 tANI_U8 *value = command;
3629 tANI_U8 ft = CFG_FAST_TRANSITION_ENABLED_NAME_DEFAULT;
3630
3631 /* Move pointer to ahead of SETFASTROAM<delimiter> */
3632 value = value + 18;
3633 /* Convert the value from ascii to integer */
3634 ret = kstrtou8(value, 10, &ft);
3635 if (ret < 0)
3636 {
3637 /* If the input value is greater than max value of datatype, then also
3638 kstrtou8 fails */
3639 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3640 "%s: kstrtou8 failed range [%d - %d]", __func__,
3641 CFG_FAST_TRANSITION_ENABLED_NAME_MIN,
3642 CFG_FAST_TRANSITION_ENABLED_NAME_MAX);
3643 ret = -EINVAL;
3644 goto exit;
3645 }
3646
3647 if ((ft < CFG_FAST_TRANSITION_ENABLED_NAME_MIN) ||
3648 (ft > CFG_FAST_TRANSITION_ENABLED_NAME_MAX))
3649 {
3650 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3651 "ft mode value %d is out of range"
3652 " (Min: %d Max: %d)", ft,
3653 CFG_FAST_TRANSITION_ENABLED_NAME_MIN,
3654 CFG_FAST_TRANSITION_ENABLED_NAME_MAX);
3655 ret = -EINVAL;
3656 goto exit;
3657 }
3658
3659 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3660 "%s: Received Command to change ft mode = %d", __func__, ft);
3661
3662 pHddCtx->cfg_ini->isFastTransitionEnabled = ft;
3663 sme_UpdateFastTransitionEnabled((tHalHandle)(pHddCtx->hHal), ft);
3664 }
Padma, Santhosh Kumar778d8382015-03-04 17:41:22 +05303665 else if (strncmp(command, "SETDFSSCANMODE", 14) == 0)
3666 {
3667 tANI_U8 *value = command;
3668 tANI_U8 dfsScanMode = DFS_CHNL_SCAN_ENABLED_NORMAL;
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05303669
Padma, Santhosh Kumar778d8382015-03-04 17:41:22 +05303670 /* Move pointer to ahead of SETDFSSCANMODE<delimiter> */
3671 value = value + 15;
3672 /* Convert the value from ascii to integer */
3673 ret = kstrtou8(value, 10, &dfsScanMode);
3674 if (ret < 0)
3675 {
3676 /* If the input value is greater than max value of
3677 datatype, then also kstrtou8 fails
3678 */
3679 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3680 "%s: kstrtou8 failed range [%d - %d]", __func__,
3681 CFG_ENABLE_DFS_CHNL_SCAN_MIN,
3682 CFG_ENABLE_DFS_CHNL_SCAN_MAX);
3683 ret = -EINVAL;
3684 goto exit;
3685 }
3686
3687 if ((dfsScanMode < CFG_ENABLE_DFS_CHNL_SCAN_MIN) ||
3688 (dfsScanMode > CFG_ENABLE_DFS_CHNL_SCAN_MAX))
3689 {
3690 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3691 "dfsScanMode value %d is out of range"
3692 " (Min: %d Max: %d)", dfsScanMode,
3693 CFG_ENABLE_DFS_CHNL_SCAN_MIN,
3694 CFG_ENABLE_DFS_CHNL_SCAN_MAX);
3695 ret = -EINVAL;
3696 goto exit;
3697 }
3698 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3699 "%s: Received Command to Set DFS Scan Mode = %d",
3700 __func__, dfsScanMode);
3701
3702 ret = wlan_hdd_handle_dfs_chan_scan(pHddCtx, dfsScanMode);
3703 }
3704 else if (strncmp(command, "GETDFSSCANMODE", 14) == 0)
3705 {
3706 tANI_U8 dfsScanMode = sme_GetDFSScanMode(pHddCtx->hHal);
3707 char extra[32];
3708 tANI_U8 len = 0;
3709
3710 len = scnprintf(extra, sizeof(extra), "%s %d", command, dfsScanMode);
Ratheesh S P767224e2015-07-16 15:35:51 +05303711 len = VOS_MIN(priv_data.total_len, len + 1);
3712 if (copy_to_user(priv_data.buf, &extra, len))
Padma, Santhosh Kumar778d8382015-03-04 17:41:22 +05303713 {
3714 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3715 "%s: failed to copy data to user buffer", __func__);
3716 ret = -EFAULT;
3717 goto exit;
3718 }
3719 }
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05303720 else if (strncmp(command, "FASTREASSOC", 11) == 0)
3721 {
3722 tANI_U8 *value = command;
Padma, Santhosh Kumarf4582d32014-11-06 19:24:51 +05303723 tANI_U8 channel = 0;
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05303724 tSirMacAddr targetApBssid;
3725 tANI_U8 trigger = 0;
3726 eHalStatus status = eHAL_STATUS_SUCCESS;
Padma, Santhosh Kumarb980a6f2014-11-06 19:07:24 +05303727 tHalHandle hHal;
3728 v_U32_t roamId = 0;
3729 tCsrRoamModifyProfileFields modProfileFields;
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05303730 hdd_station_ctx_t *pHddStaCtx = NULL;
3731 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Padma, Santhosh Kumarb980a6f2014-11-06 19:07:24 +05303732 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05303733
3734 /* if not associated, no need to proceed with reassoc */
3735 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
3736 {
3737 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s:Not associated!",__func__);
3738 ret = -EINVAL;
3739 goto exit;
3740 }
3741
Padma, Santhosh Kumarf4582d32014-11-06 19:24:51 +05303742 status = hdd_parse_reassoc_command_data(value, targetApBssid, &channel);
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05303743 if (eHAL_STATUS_SUCCESS != status)
3744 {
3745 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3746 "%s: Failed to parse reassoc command data", __func__);
3747 ret = -EINVAL;
3748 goto exit;
3749 }
3750
3751 /* if the target bssid is same as currently associated AP,
Padma, Santhosh Kumarb980a6f2014-11-06 19:07:24 +05303752 issue reassoc to same AP */
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05303753 if (VOS_TRUE == vos_mem_compare(targetApBssid,
3754 pHddStaCtx->conn_info.bssId, sizeof(tSirMacAddr)))
3755 {
AnjaneeDevi Kapparapu228d0c52015-11-09 12:32:21 +05303756 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3757 "%s:11r Reassoc BSSID is same as currently associated AP bssid",
3758 __func__);
Padma, Santhosh Kumarb980a6f2014-11-06 19:07:24 +05303759 sme_GetModifyProfileFields(hHal, pAdapter->sessionId,
3760 &modProfileFields);
3761 sme_RoamReassoc(hHal, pAdapter->sessionId,
3762 NULL, modProfileFields, &roamId, 1);
AnjaneeDevi Kapparapu228d0c52015-11-09 12:32:21 +05303763 return 0;
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05303764 }
Padma, Santhosh Kumar0fa809b2014-11-13 14:56:56 +05303765
3766 /* Check channel number is a valid channel number */
3767 if(VOS_STATUS_SUCCESS !=
3768 wlan_hdd_validate_operation_channel(pAdapter, channel))
3769 {
3770 hddLog(VOS_TRACE_LEVEL_ERROR,
3771 "%s: Invalid Channel [%d]", __func__, channel);
AnjaneeDevi Kapparapu228d0c52015-11-09 12:32:21 +05303772 return -EINVAL;
Padma, Santhosh Kumar0fa809b2014-11-13 14:56:56 +05303773 }
3774
Padma, Santhosh Kumarf4582d32014-11-06 19:24:51 +05303775 trigger = eSME_ROAM_TRIGGER_SCAN;
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05303776
3777 /* Proceed with scan/roam */
3778 smeIssueFastRoamNeighborAPEvent(WLAN_HDD_GET_HAL_CTX(pAdapter),
3779 &targetApBssid[0],
Mukul Sharma9e4e0f92015-02-13 18:45:20 +05303780 (tSmeFastRoamTrigger)(trigger),
3781 channel);
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05303782 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003783#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003784#ifdef FEATURE_WLAN_ESE
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003785 else if (strncmp(command, "SETCCXMODE", 10) == 0)
3786 {
3787 tANI_U8 *value = command;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003788 tANI_U8 eseMode = CFG_ESE_FEATURE_ENABLED_DEFAULT;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003789
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003790 /* Check if the features OKC/ESE/11R are supported simultaneously,
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07003791 then this operation is not permitted (return FAILURE) */
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003792 if (sme_getIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal)) &&
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07003793 hdd_is_okc_mode_enabled(pHddCtx) &&
3794 sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal)))
3795 {
3796 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003797 "%s: OKC/ESE/11R are supported simultaneously"
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07003798 " hence this operation is not permitted!", __func__);
3799 ret = -EPERM;
3800 goto exit;
3801 }
3802
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003803 /* Move pointer to ahead of SETCCXMODE<delimiter> */
3804 value = value + 11;
3805 /* Convert the value from ascii to integer */
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003806 ret = kstrtou8(value, 10, &eseMode);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003807 if (ret < 0)
3808 {
3809 /* If the input value is greater than max value of datatype, then also
3810 kstrtou8 fails */
3811 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3812 "%s: kstrtou8 failed range [%d - %d]", __func__,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003813 CFG_ESE_FEATURE_ENABLED_MIN,
3814 CFG_ESE_FEATURE_ENABLED_MAX);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003815 ret = -EINVAL;
3816 goto exit;
3817 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003818 if ((eseMode < CFG_ESE_FEATURE_ENABLED_MIN) ||
3819 (eseMode > CFG_ESE_FEATURE_ENABLED_MAX))
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003820 {
3821 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003822 "Ese mode value %d is out of range"
3823 " (Min: %d Max: %d)", eseMode,
3824 CFG_ESE_FEATURE_ENABLED_MIN,
3825 CFG_ESE_FEATURE_ENABLED_MAX);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003826 ret = -EINVAL;
3827 goto exit;
3828 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003829 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003830 "%s: Received Command to change ese mode = %d", __func__, eseMode);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003831
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003832 pHddCtx->cfg_ini->isEseIniFeatureEnabled = eseMode;
3833 sme_UpdateIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal), eseMode);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003834 }
3835#endif
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003836 else if (strncmp(command, "SETROAMSCANCONTROL", 18) == 0)
3837 {
3838 tANI_U8 *value = command;
3839 tANI_BOOLEAN roamScanControl = 0;
3840
3841 /* Move pointer to ahead of SETROAMSCANCONTROL<delimiter> */
3842 value = value + 19;
3843 /* Convert the value from ascii to integer */
3844 ret = kstrtou8(value, 10, &roamScanControl);
3845 if (ret < 0)
3846 {
3847 /* If the input value is greater than max value of datatype, then also
3848 kstrtou8 fails */
3849 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3850 "%s: kstrtou8 failed ", __func__);
3851 ret = -EINVAL;
3852 goto exit;
3853 }
3854
3855 if (0 != roamScanControl)
3856 {
3857 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3858 "roam scan control invalid value = %d",
3859 roamScanControl);
3860 ret = -EINVAL;
3861 goto exit;
3862 }
3863 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3864 "%s: Received Command to Set roam scan control = %d", __func__, roamScanControl);
3865
3866 sme_SetRoamScanControl((tHalHandle)(pHddCtx->hHal), roamScanControl);
3867 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003868#ifdef FEATURE_WLAN_OKC
3869 else if (strncmp(command, "SETOKCMODE", 10) == 0)
3870 {
3871 tANI_U8 *value = command;
3872 tANI_U8 okcMode = CFG_OKC_FEATURE_ENABLED_DEFAULT;
3873
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003874 /* Check if the features OKC/ESE/11R are supported simultaneously,
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07003875 then this operation is not permitted (return FAILURE) */
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003876 if (sme_getIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal)) &&
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07003877 hdd_is_okc_mode_enabled(pHddCtx) &&
3878 sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal)))
3879 {
3880 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003881 "%s: OKC/ESE/11R are supported simultaneously"
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07003882 " hence this operation is not permitted!", __func__);
3883 ret = -EPERM;
3884 goto exit;
3885 }
3886
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003887 /* Move pointer to ahead of SETOKCMODE<delimiter> */
3888 value = value + 11;
3889 /* Convert the value from ascii to integer */
3890 ret = kstrtou8(value, 10, &okcMode);
3891 if (ret < 0)
3892 {
3893 /* If the input value is greater than max value of datatype, then also
3894 kstrtou8 fails */
3895 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3896 "%s: kstrtou8 failed range [%d - %d]", __func__,
3897 CFG_OKC_FEATURE_ENABLED_MIN,
3898 CFG_OKC_FEATURE_ENABLED_MAX);
3899 ret = -EINVAL;
3900 goto exit;
3901 }
3902
3903 if ((okcMode < CFG_OKC_FEATURE_ENABLED_MIN) ||
3904 (okcMode > CFG_OKC_FEATURE_ENABLED_MAX))
3905 {
3906 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3907 "Okc mode value %d is out of range"
3908 " (Min: %d Max: %d)", okcMode,
3909 CFG_OKC_FEATURE_ENABLED_MIN,
3910 CFG_OKC_FEATURE_ENABLED_MAX);
3911 ret = -EINVAL;
3912 goto exit;
3913 }
3914
3915 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3916 "%s: Received Command to change okc mode = %d", __func__, okcMode);
3917
3918 pHddCtx->cfg_ini->isOkcIniFeatureEnabled = okcMode;
3919 }
Srinivas Girigowdaad34ca92013-10-22 10:54:29 -07003920#endif /* FEATURE_WLAN_OKC */
Mahesh A Saptasagarec7d1092015-04-02 13:41:34 +05303921 else if (strncmp(command, "GETROAMSCANCONTROL", 18) == 0)
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003922 {
3923 tANI_BOOLEAN roamScanControl = sme_GetRoamScanControl((tHalHandle)(pHddCtx->hHal));
3924 char extra[32];
3925 tANI_U8 len = 0;
3926
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003927 len = scnprintf(extra, sizeof(extra), "%s %d",
3928 command, roamScanControl);
Ratnam Rachuri083ada82015-08-07 14:01:05 +05303929 len = VOS_MIN(priv_data.total_len, len + 1);
3930 if (copy_to_user(priv_data.buf, &extra, len)) {
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003931 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3932 "%s: failed to copy data to user buffer", __func__);
3933 ret = -EFAULT;
3934 goto exit;
3935 }
3936 }
Gopichand Nakkala227c7f32013-06-26 22:44:57 +05303937#ifdef WLAN_FEATURE_PACKET_FILTERING
3938 else if (strncmp(command, "ENABLE_PKTFILTER_IPV6", 21) == 0)
3939 {
3940 tANI_U8 filterType = 0;
3941 tANI_U8 *value = command;
3942
3943 /* Move pointer to ahead of ENABLE_PKTFILTER_IPV6<delimiter> */
3944 value = value + 22;
3945
3946 /* Convert the value from ascii to integer */
3947 ret = kstrtou8(value, 10, &filterType);
3948 if (ret < 0)
3949 {
3950 /* If the input value is greater than max value of datatype,
3951 * then also kstrtou8 fails
3952 */
3953 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3954 "%s: kstrtou8 failed range ", __func__);
3955 ret = -EINVAL;
3956 goto exit;
3957 }
3958
3959 if (filterType != 0 && filterType != 1)
3960 {
3961 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3962 "%s: Accepted Values are 0 and 1 ", __func__);
3963 ret = -EINVAL;
3964 goto exit;
3965 }
3966 wlan_hdd_setIPv6Filter(WLAN_HDD_GET_CTX(pAdapter), filterType,
3967 pAdapter->sessionId);
3968 }
3969#endif
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05303970 else if (strncmp(command, "BTCOEXMODE", 10) == 0 )
3971 {
Kiet Lamad161252014-07-22 11:23:32 -07003972 char *dhcpPhase;
Satyanarayana Dash1faea4f2014-09-22 16:21:04 +05303973 int ret;
3974
Kiet Lamad161252014-07-22 11:23:32 -07003975 dhcpPhase = command + 11;
3976 if ('1' == *dhcpPhase)
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05303977 {
Deepthi Gowribfd17132014-11-14 17:59:04 +05303978 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Kiet Lamad161252014-07-22 11:23:32 -07003979 FL("send DHCP START indication"));
c_hpothu9b781ba2013-12-30 20:57:45 +05303980
3981 pHddCtx->btCoexModeSet = TRUE;
Kiet Lamad161252014-07-22 11:23:32 -07003982
Satyanarayana Dash1faea4f2014-09-22 16:21:04 +05303983 ret = wlan_hdd_scan_abort(pAdapter);
3984 if (ret < 0)
3985 {
3986 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3987 FL("failed to abort existing scan %d"), ret);
3988 }
3989
Kiet Lamad161252014-07-22 11:23:32 -07003990 sme_DHCPStartInd(pHddCtx->hHal, pAdapter->device_mode,
3991 pAdapter->sessionId);
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05303992 }
Kiet Lamad161252014-07-22 11:23:32 -07003993 else if ('2' == *dhcpPhase)
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05303994 {
Deepthi Gowribfd17132014-11-14 17:59:04 +05303995 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Kiet Lamad161252014-07-22 11:23:32 -07003996 FL("send DHCP STOP indication"));
c_hpothu9b781ba2013-12-30 20:57:45 +05303997
3998 pHddCtx->btCoexModeSet = FALSE;
Kiet Lamad161252014-07-22 11:23:32 -07003999
4000 sme_DHCPStopInd(pHddCtx->hHal, pAdapter->device_mode,
4001 pAdapter->sessionId);
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05304002 }
4003 }
Jeff Johnsonf54df2c2013-07-24 11:43:39 -07004004 else if (strncmp(command, "SCAN-ACTIVE", 11) == 0)
4005 {
Abhishek Singh58749d62016-02-03 15:27:20 +05304006 hddLog(LOG1,
4007 FL("making default scan to ACTIVE"));
c_hpothudbefd3e2014-04-28 15:59:47 +05304008 pHddCtx->scan_info.scan_mode = eSIR_ACTIVE_SCAN;
Jeff Johnsonf54df2c2013-07-24 11:43:39 -07004009 }
4010 else if (strncmp(command, "SCAN-PASSIVE", 12) == 0)
4011 {
Abhishek Singh58749d62016-02-03 15:27:20 +05304012 hddLog(LOG1,
4013 FL("making default scan to PASSIVE"));
c_hpothudbefd3e2014-04-28 15:59:47 +05304014 pHddCtx->scan_info.scan_mode = eSIR_PASSIVE_SCAN;
Jeff Johnsonf54df2c2013-07-24 11:43:39 -07004015 }
Hanumantha Reddy Pothula212243c2013-08-01 17:28:31 +05304016 else if (strncmp(command, "GETDWELLTIME", 12) == 0)
4017 {
4018 hdd_config_t *pCfg = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
4019 char extra[32];
4020 tANI_U8 len = 0;
4021
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05304022 memset(extra, 0, sizeof(extra));
4023 ret = hdd_get_dwell_time(pCfg, command, extra, sizeof(extra), &len);
Ratnam Rachuri12d5d462015-08-07 14:10:23 +05304024 len = VOS_MIN(priv_data.total_len, len + 1);
4025 if (ret != 0 || copy_to_user(priv_data.buf, &extra, len)) {
Hanumantha Reddy Pothula212243c2013-08-01 17:28:31 +05304026 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4027 "%s: failed to copy data to user buffer", __func__);
4028 ret = -EFAULT;
4029 goto exit;
4030 }
4031 ret = len;
4032 }
4033 else if (strncmp(command, "SETDWELLTIME", 12) == 0)
4034 {
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05304035 ret = hdd_set_dwell_time(pAdapter, command);
Hanumantha Reddy Pothula212243c2013-08-01 17:28:31 +05304036 }
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07004037 else if ( strncasecmp(command, "MIRACAST", 8) == 0 )
4038 {
4039 tANI_U8 filterType = 0;
4040 tANI_U8 *value;
4041 value = command + 9;
4042
4043 /* Convert the value from ascii to integer */
4044 ret = kstrtou8(value, 10, &filterType);
4045 if (ret < 0)
4046 {
4047 /* If the input value is greater than max value of datatype,
4048 * then also kstrtou8 fails
4049 */
4050 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4051 "%s: kstrtou8 failed range ", __func__);
4052 ret = -EINVAL;
4053 goto exit;
4054 }
4055 if ((filterType < WLAN_HDD_DRIVER_MIRACAST_CFG_MIN_VAL ) ||
4056 (filterType > WLAN_HDD_DRIVER_MIRACAST_CFG_MAX_VAL))
4057 {
4058 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4059 "%s: Accepted Values are 0 to 2. 0-Disabled, 1-Source,"
4060 " 2-Sink ", __func__);
4061 ret = -EINVAL;
4062 goto exit;
4063 }
4064 //Filtertype value should be either 0-Disabled, 1-Source, 2-sink
4065 pHddCtx->drvr_miracast = filterType;
Kaushik, Sushant96122442014-10-21 16:40:18 +05304066 pScanInfo = &pHddCtx->scan_info;
4067 if (filterType && pScanInfo != NULL &&
4068 pHddCtx->scan_info.mScanPending)
4069 {
4070 /*Miracast Session started. Abort Scan */
4071 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4072 "%s, Aborting Scan For Miracast",__func__);
4073 hdd_abort_mac_scan(pHddCtx, pScanInfo->sessionId,
4074 eCSR_SCAN_ABORT_DEFAULT);
4075 }
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07004076 hdd_tx_rx_pkt_cnt_stat_timer_handler(pHddCtx);
Ganesh Kondabattini8f6e3b32014-08-25 16:07:54 +05304077 sme_SetMiracastMode(pHddCtx->hHal, pHddCtx->drvr_miracast);
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07004078 }
Leo Chang614d2072013-08-22 14:59:44 -07004079 else if (strncmp(command, "SETMCRATE", 9) == 0)
4080 {
Leo Chang614d2072013-08-22 14:59:44 -07004081 tANI_U8 *value = command;
4082 int targetRate;
Leo Chang1f98cbd2013-10-17 15:03:52 -07004083 tSirRateUpdateInd *rateUpdate;
4084 eHalStatus status;
Leo Chang614d2072013-08-22 14:59:44 -07004085
4086 /* Only valid for SAP mode */
4087 if (WLAN_HDD_SOFTAP != pAdapter->device_mode)
4088 {
4089 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4090 "%s: SAP mode is not running", __func__);
4091 ret = -EFAULT;
4092 goto exit;
4093 }
4094
4095 /* Move pointer to ahead of SETMCRATE<delimiter> */
4096 /* input value is in units of hundred kbps */
4097 value = value + 10;
4098 /* Convert the value from ascii to integer, decimal base */
4099 ret = kstrtouint(value, 10, &targetRate);
4100
Leo Chang1f98cbd2013-10-17 15:03:52 -07004101 rateUpdate = (tSirRateUpdateInd *)vos_mem_malloc(sizeof(tSirRateUpdateInd));
4102 if (NULL == rateUpdate)
Leo Chang614d2072013-08-22 14:59:44 -07004103 {
Leo Chang1f98cbd2013-10-17 15:03:52 -07004104 hddLog(VOS_TRACE_LEVEL_ERROR,
4105 "%s: SETMCRATE indication alloc fail", __func__);
4106 ret = -EFAULT;
4107 goto exit;
4108 }
4109 vos_mem_zero(rateUpdate, sizeof(tSirRateUpdateInd ));
4110
4111 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4112 "MC Target rate %d", targetRate);
4113 /* Ignore unicast */
4114 rateUpdate->ucastDataRate = -1;
4115 rateUpdate->mcastDataRate24GHz = targetRate;
4116 rateUpdate->mcastDataRate5GHz = targetRate;
4117 rateUpdate->mcastDataRate24GHzTxFlag = 0;
4118 rateUpdate->mcastDataRate5GHzTxFlag = 0;
4119 status = sme_SendRateUpdateInd(pHddCtx->hHal, rateUpdate);
4120 if (eHAL_STATUS_SUCCESS != status)
4121 {
4122 hddLog(VOS_TRACE_LEVEL_ERROR,
4123 "%s: SET_MC_RATE failed", __func__);
4124 vos_mem_free(rateUpdate);
4125 ret = -EFAULT;
4126 goto exit;
Leo Chang614d2072013-08-22 14:59:44 -07004127 }
4128 }
Rajeev79dbe4c2013-10-05 11:03:42 +05304129#ifdef FEATURE_WLAN_BATCH_SCAN
Rajeev Kumar8b373292014-01-08 20:36:55 -08004130 else if (strncmp(command, "WLS_BATCHING", 12) == 0)
Rajeev79dbe4c2013-10-05 11:03:42 +05304131 {
Rajeev Kumar8b373292014-01-08 20:36:55 -08004132 ret = hdd_handle_batch_scan_ioctl(pAdapter, &priv_data, command);
Rajeev79dbe4c2013-10-05 11:03:42 +05304133 }
4134#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004135#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004136 else if (strncmp(command, "SETCCXROAMSCANCHANNELS", 22) == 0)
4137 {
4138 tANI_U8 *value = command;
4139 tANI_U8 ChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
4140 tANI_U8 numChannels = 0;
4141 eHalStatus status = eHAL_STATUS_SUCCESS;
4142
4143 status = hdd_parse_channellist(value, ChannelList, &numChannels);
4144 if (eHAL_STATUS_SUCCESS != status)
4145 {
4146 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4147 "%s: Failed to parse channel list information", __func__);
4148 ret = -EINVAL;
4149 goto exit;
4150 }
4151
4152 if (numChannels > WNI_CFG_VALID_CHANNEL_LIST_LEN)
4153 {
4154 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4155 "%s: number of channels (%d) supported exceeded max (%d)", __func__,
4156 numChannels, WNI_CFG_VALID_CHANNEL_LIST_LEN);
4157 ret = -EINVAL;
4158 goto exit;
4159 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004160 status = sme_SetEseRoamScanChannelList((tHalHandle)(pHddCtx->hHal),
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004161 ChannelList,
4162 numChannels);
4163 if (eHAL_STATUS_SUCCESS != status)
4164 {
4165 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4166 "%s: Failed to update channel list information", __func__);
4167 ret = -EINVAL;
4168 goto exit;
4169 }
4170 }
4171 else if (strncmp(command, "GETTSMSTATS", 11) == 0)
4172 {
4173 tANI_U8 *value = command;
4174 char extra[128] = {0};
4175 int len = 0;
4176 tANI_U8 tid = 0;
4177 hdd_station_ctx_t *pHddStaCtx = NULL;
4178 tAniTrafStrmMetrics tsmMetrics;
4179 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4180
4181 /* if not associated, return error */
4182 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
4183 {
4184 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "%s:Not associated!",__func__);
4185 ret = -EINVAL;
4186 goto exit;
4187 }
4188
4189 /* Move pointer to ahead of GETTSMSTATS<delimiter> */
4190 value = value + 12;
4191 /* Convert the value from ascii to integer */
4192 ret = kstrtou8(value, 10, &tid);
4193 if (ret < 0)
4194 {
4195 /* If the input value is greater than max value of datatype, then also
4196 kstrtou8 fails */
4197 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4198 "%s: kstrtou8 failed range [%d - %d]", __func__,
4199 TID_MIN_VALUE,
4200 TID_MAX_VALUE);
4201 ret = -EINVAL;
4202 goto exit;
4203 }
4204
4205 if ((tid < TID_MIN_VALUE) || (tid > TID_MAX_VALUE))
4206 {
4207 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4208 "tid value %d is out of range"
4209 " (Min: %d Max: %d)", tid,
4210 TID_MIN_VALUE,
4211 TID_MAX_VALUE);
4212 ret = -EINVAL;
4213 goto exit;
4214 }
4215
4216 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4217 "%s: Received Command to get tsm stats tid = %d", __func__, tid);
4218
4219 if (VOS_STATUS_SUCCESS != hdd_get_tsm_stats(pAdapter, tid, &tsmMetrics))
4220 {
4221 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4222 "%s: failed to get tsm stats", __func__);
4223 ret = -EFAULT;
4224 goto exit;
4225 }
4226
4227 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4228 "UplinkPktQueueDly(%d)\n"
4229 "UplinkPktQueueDlyHist[0](%d)\n"
4230 "UplinkPktQueueDlyHist[1](%d)\n"
4231 "UplinkPktQueueDlyHist[2](%d)\n"
4232 "UplinkPktQueueDlyHist[3](%d)\n"
Arun Kumar Khandavallie8768212014-02-17 16:43:34 +05304233 "UplinkPktTxDly(%u)\n"
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004234 "UplinkPktLoss(%d)\n"
4235 "UplinkPktCount(%d)\n"
4236 "RoamingCount(%d)\n"
4237 "RoamingDly(%d)", tsmMetrics.UplinkPktQueueDly,
4238 tsmMetrics.UplinkPktQueueDlyHist[0],
4239 tsmMetrics.UplinkPktQueueDlyHist[1],
4240 tsmMetrics.UplinkPktQueueDlyHist[2],
4241 tsmMetrics.UplinkPktQueueDlyHist[3],
4242 tsmMetrics.UplinkPktTxDly, tsmMetrics.UplinkPktLoss,
4243 tsmMetrics.UplinkPktCount, tsmMetrics.RoamingCount, tsmMetrics.RoamingDly);
4244
4245 /* Output TSM stats is of the format
4246 GETTSMSTATS [PktQueueDly] [PktQueueDlyHist[0]]:[PktQueueDlyHist[1]] ...[RoamingDly]
4247 eg., GETTSMSTATS 10 1:0:0:161 20 1 17 8 39800 */
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004248 len = scnprintf(extra, sizeof(extra), "%s %d %d:%d:%d:%d %u %d %d %d %d", command,
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004249 tsmMetrics.UplinkPktQueueDly, tsmMetrics.UplinkPktQueueDlyHist[0],
4250 tsmMetrics.UplinkPktQueueDlyHist[1], tsmMetrics.UplinkPktQueueDlyHist[2],
4251 tsmMetrics.UplinkPktQueueDlyHist[3], tsmMetrics.UplinkPktTxDly,
4252 tsmMetrics.UplinkPktLoss, tsmMetrics.UplinkPktCount, tsmMetrics.RoamingCount,
4253 tsmMetrics.RoamingDly);
4254
Ratnam Rachurid53009c2015-08-07 13:59:00 +05304255 len = VOS_MIN(priv_data.total_len, len + 1);
4256 if (copy_to_user(priv_data.buf, &extra, len)) {
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004257 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4258 "%s: failed to copy data to user buffer", __func__);
4259 ret = -EFAULT;
4260 goto exit;
4261 }
4262 }
4263 else if (strncmp(command, "SETCCKMIE", 9) == 0)
4264 {
4265 tANI_U8 *value = command;
4266 tANI_U8 *cckmIe = NULL;
4267 tANI_U8 cckmIeLen = 0;
4268 eHalStatus status = eHAL_STATUS_SUCCESS;
4269
4270 status = hdd_parse_get_cckm_ie(value, &cckmIe, &cckmIeLen);
4271 if (eHAL_STATUS_SUCCESS != status)
4272 {
4273 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4274 "%s: Failed to parse cckm ie data", __func__);
4275 ret = -EINVAL;
4276 goto exit;
4277 }
4278
4279 if (cckmIeLen > DOT11F_IE_RSN_MAX_LEN)
4280 {
4281 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4282 "%s: CCKM Ie input length is more than max[%d]", __func__,
4283 DOT11F_IE_RSN_MAX_LEN);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08004284 vos_mem_free(cckmIe);
4285 cckmIe = NULL;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004286 ret = -EINVAL;
4287 goto exit;
4288 }
4289 sme_SetCCKMIe((tHalHandle)(pHddCtx->hHal), pAdapter->sessionId, cckmIe, cckmIeLen);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08004290 vos_mem_free(cckmIe);
4291 cckmIe = NULL;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004292 }
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004293 else if (strncmp(command, "CCXBEACONREQ", 12) == 0)
4294 {
4295 tANI_U8 *value = command;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004296 tCsrEseBeaconReq eseBcnReq;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004297 eHalStatus status = eHAL_STATUS_SUCCESS;
Srinivas Girigowda0c6d7fe2014-05-28 18:18:10 -07004298
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004299 status = hdd_parse_ese_beacon_req(value, &eseBcnReq);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004300 if (eHAL_STATUS_SUCCESS != status)
4301 {
4302 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004303 "%s: Failed to parse ese beacon req", __func__);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004304 ret = -EINVAL;
4305 goto exit;
4306 }
Srinivas Girigowda0c6d7fe2014-05-28 18:18:10 -07004307 if (!hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))) {
4308 hddLog(VOS_TRACE_LEVEL_INFO, FL("Not associated"));
4309 hdd_indicateEseBcnReportNoResults (pAdapter,
4310 eseBcnReq.bcnReq[0].measurementToken,
4311 0x02, //BIT(1) set for measurement done
4312 0); // no BSS
4313 goto exit;
4314 }
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004315
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004316 status = sme_SetEseBeaconRequest((tHalHandle)(pHddCtx->hHal), pAdapter->sessionId, &eseBcnReq);
4317 if (eHAL_STATUS_SUCCESS != status)
4318 {
4319 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4320 "%s: sme_SetEseBeaconRequest failed (%d)", __func__, status);
4321 ret = -EINVAL;
4322 goto exit;
4323 }
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004324 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004325#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
c_hpothu92367912014-05-01 15:18:17 +05304326 else if (strncmp(command, "GETBCNMISSRATE", 14) == 0)
4327 {
4328 eHalStatus status;
4329 char buf[32], len;
4330 long waitRet;
4331 bcnMissRateContext_t getBcnMissRateCtx;
4332
4333 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4334
4335 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
4336 {
4337 hddLog(VOS_TRACE_LEVEL_WARN,
4338 FL("GETBCNMISSRATE: STA is not in connected state"));
4339 ret = -1;
4340 goto exit;
4341 }
4342
4343 init_completion(&(getBcnMissRateCtx.completion));
4344 getBcnMissRateCtx.magic = BCN_MISS_RATE_CONTEXT_MAGIC;
4345
4346 status = sme_getBcnMissRate((tHalHandle)(pHddCtx->hHal),
4347 pAdapter->sessionId,
4348 (void *)getBcnMissRateCB,
4349 (void *)(&getBcnMissRateCtx));
4350 if( eHAL_STATUS_SUCCESS != status)
4351 {
4352 hddLog(VOS_TRACE_LEVEL_INFO,
4353 FL("GETBCNMISSRATE: fail to post WDA cmd"));
4354 ret = -EINVAL;
4355 goto exit;
4356 }
4357
4358 waitRet = wait_for_completion_interruptible_timeout
4359 (&getBcnMissRateCtx.completion, BCN_MISS_RATE_TIME);
4360 if(waitRet <= 0)
4361 {
4362 hddLog(VOS_TRACE_LEVEL_ERROR,
4363 FL("failed to wait on bcnMissRateComp %d"), ret);
4364
4365 //Make magic number to zero so that callback is not called.
4366 spin_lock(&hdd_context_lock);
4367 getBcnMissRateCtx.magic = 0x0;
4368 spin_unlock(&hdd_context_lock);
4369 ret = -EINVAL;
4370 goto exit;
4371 }
4372
4373 hddLog(VOS_TRACE_LEVEL_INFO,
4374 FL("GETBCNMISSRATE: bcnMissRate: %d"), gbcnMissRate);
4375
4376 len = snprintf(buf, sizeof(buf), "GETBCNMISSRATE %d", gbcnMissRate);
4377 if (copy_to_user(priv_data.buf, &buf, len + 1))
4378 {
4379 hddLog(VOS_TRACE_LEVEL_ERROR,
4380 "%s: failed to copy data to user buffer", __func__);
4381 ret = -EFAULT;
4382 goto exit;
4383 }
4384 ret = len;
4385 }
Atul Mittal87ec2422014-09-24 13:12:50 +05304386#ifdef FEATURE_WLAN_TDLS
4387 else if (strncmp(command, "TDLSSECONDARYCHANNELOFFSET", 26) == 0) {
4388 tANI_U8 *value = command;
4389 int set_value;
4390 /* Move pointer to ahead of TDLSOFFCH*/
4391 value += 26;
c_manjeebbc40212015-12-08 13:52:59 +05304392 if (!(sscanf(value, "%d", &set_value))) {
4393 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4394 FL("No input identified"));
4395 ret = -EINVAL;
4396 goto exit;
4397 }
4398
Atul Mittal87ec2422014-09-24 13:12:50 +05304399 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4400 "%s: Tdls offchannel offset:%d",
4401 __func__, set_value);
4402 ret = iw_set_tdlssecoffchanneloffset(pHddCtx, set_value);
4403 if (ret < 0)
4404 {
4405 ret = -EINVAL;
4406 goto exit;
4407 }
4408
4409 } else if (strncmp(command, "TDLSOFFCHANNELMODE", 18) == 0) {
4410 tANI_U8 *value = command;
4411 int set_value;
4412 /* Move pointer to ahead of tdlsoffchnmode*/
4413 value += 18;
c_manjee82323892015-12-08 12:40:34 +05304414 ret = sscanf(value, "%d", &set_value);
4415 if (ret != 1) {
4416 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4417 FL("No input identified"));
4418 ret = -EINVAL;
4419 goto exit;
4420 }
Atul Mittal87ec2422014-09-24 13:12:50 +05304421 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4422 "%s: Tdls offchannel mode:%d",
4423 __func__, set_value);
4424 ret = iw_set_tdlsoffchannelmode(pAdapter, set_value);
4425 if (ret < 0)
4426 {
4427 ret = -EINVAL;
4428 goto exit;
4429 }
4430 } else if (strncmp(command, "TDLSOFFCHANNEL", 14) == 0) {
4431 tANI_U8 *value = command;
4432 int set_value;
4433 /* Move pointer to ahead of TDLSOFFCH*/
4434 value += 14;
c_manjeef6ccaf52015-12-08 11:52:11 +05304435 ret = sscanf(value, "%d", &set_value);
4436 if (ret != 1) {
4437 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4438 "Wrong value is given for hdd_set_tdls_offchannel");
4439 ret = -EINVAL;
4440 goto exit;
4441 }
4442
Atul Mittal87ec2422014-09-24 13:12:50 +05304443 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4444 "%s: Tdls offchannel num: %d",
4445 __func__, set_value);
4446 ret = iw_set_tdlsoffchannel(pHddCtx, set_value);
4447 if (ret < 0)
4448 {
4449 ret = -EINVAL;
4450 goto exit;
4451 }
4452 }
4453#endif
Satyanarayana Dash72806012014-12-02 14:30:08 +05304454 else if (strncmp(command, "GETFWSTATS", 10) == 0)
4455 {
4456 eHalStatus status;
4457 char *buf = NULL;
4458 char len;
4459 long waitRet;
4460 fwStatsContext_t fwStatsCtx;
Abhishek Singh08aa7762014-12-16 13:59:03 +05304461 tSirFwStatsResult *fwStatsRsp = &(pAdapter->fwStatsRsp);
Satyanarayana Dash72806012014-12-02 14:30:08 +05304462 tANI_U8 *ptr = command;
4463 int stats = *(ptr + 11) - '0';
4464
4465 hddLog(VOS_TRACE_LEVEL_INFO, FL("stats = %d "),stats);
4466 if (!IS_FEATURE_FW_STATS_ENABLE)
4467 {
4468 hddLog(VOS_TRACE_LEVEL_INFO,
4469 FL("Get Firmware stats feature not supported"));
4470 ret = -EINVAL;
4471 goto exit;
4472 }
4473
4474 if (FW_STATS_MAX <= stats || 0 >= stats)
4475 {
4476 hddLog(VOS_TRACE_LEVEL_INFO,
4477 FL(" stats %d not supported"),stats);
4478 ret = -EINVAL;
4479 goto exit;
4480 }
4481
4482 init_completion(&(fwStatsCtx.completion));
4483 fwStatsCtx.magic = FW_STATS_CONTEXT_MAGIC;
4484 fwStatsCtx.pAdapter = pAdapter;
4485 fwStatsRsp->type = 0;
4486 status = sme_GetFwStats( (tHalHandle)pHddCtx->hHal, stats,
Abhishek Singh08aa7762014-12-16 13:59:03 +05304487 &fwStatsCtx, hdd_FWStatisCB);
Satyanarayana Dash72806012014-12-02 14:30:08 +05304488 if (eHAL_STATUS_SUCCESS != status)
4489 {
4490 hddLog(VOS_TRACE_LEVEL_ERROR,
4491 FL(" fail to post WDA cmd status = %d"), status);
4492 ret = -EINVAL;
4493 goto exit;
4494 }
4495 waitRet = wait_for_completion_timeout
4496 (&(fwStatsCtx.completion), FW_STATE_WAIT_TIME);
4497 if (waitRet <= 0)
4498 {
4499 hddLog(VOS_TRACE_LEVEL_ERROR,
4500 FL("failed to wait on GwtFwstats"));
4501 //Make magic number to zero so that callback is not executed.
4502 spin_lock(&hdd_context_lock);
4503 fwStatsCtx.magic = 0x0;
4504 spin_unlock(&hdd_context_lock);
4505 ret = -EINVAL;
4506 goto exit;
4507 }
4508 if (fwStatsRsp->type)
4509 {
4510 buf = kmalloc(FW_STATE_RSP_LEN, GFP_KERNEL);
4511 if (!buf)
4512 {
4513 hddLog(VOS_TRACE_LEVEL_ERROR,
4514 FL(" failed to allocate memory"));
4515 ret = -ENOMEM;
4516 goto exit;
4517 }
4518 switch( fwStatsRsp->type )
4519 {
4520 case FW_UBSP_STATS:
4521 {
4522 len = snprintf(buf, FW_STATE_RSP_LEN,
4523 "GETFWSTATS: ubsp_enter_cnt %d ubsp_jump_ddr_cnt %d",
Abhishek Singh08aa7762014-12-16 13:59:03 +05304524 fwStatsRsp->fwStatsData.ubspStats.ubsp_enter_cnt,
4525 fwStatsRsp->fwStatsData.ubspStats.ubsp_jump_ddr_cnt);
Satyanarayana Dash72806012014-12-02 14:30:08 +05304526 }
4527 break;
4528 default:
4529 {
4530 hddLog(VOS_TRACE_LEVEL_ERROR, FL( "No handling for stats type %d"),fwStatsRsp->type);
4531 ret = -EFAULT;
4532 kfree(buf);
4533 goto exit;
4534 }
4535 }
4536 if (copy_to_user(priv_data.buf, buf, len + 1))
4537 {
4538 hddLog(VOS_TRACE_LEVEL_ERROR,
4539 FL(" failed to copy data to user buffer"));
4540 ret = -EFAULT;
4541 kfree(buf);
4542 goto exit;
4543 }
4544 ret = len;
4545 kfree(buf);
4546 }
4547 else
4548 {
4549 hddLog(VOS_TRACE_LEVEL_ERROR,
4550 FL("failed to fetch the stats"));
4551 ret = -EFAULT;
4552 goto exit;
4553 }
4554
4555 }
Agarwal Ashish8bd53ae2015-06-12 18:03:45 +05304556 else if (strncasecmp(command, "SET_FCC_CHANNEL", 15) == 0)
4557 {
4558 /*
4559 * this command wld be called by user-space when it detects WLAN
4560 * ON after airplane mode is set. When APM is set, WLAN turns off.
4561 * But it can be turned back on. Otherwise; when APM is turned back
4562 * off, WLAN wld turn back on. So at that point the command is
4563 * expected to come down. 0 means disable, 1 means enable. The
4564 * constraint is removed when parameter 1 is set or different
4565 * country code is set
4566 */
4567 ret = hdd_cmd_setFccChannel(pHddCtx, command, 15);
4568 }
Mahesh A Saptasagarbeca12c2015-09-07 16:21:06 +05304569 else if (strncasecmp(command, "DISABLE_CA_EVENT", 16) == 0)
4570 {
4571 ret = hdd_enable_disable_ca_event(pHddCtx, command, 16);
4572 }
Madan Mohan Koyyalamudif9bdd4e2012-10-30 18:05:03 -07004573 else {
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05304574 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
4575 TRACE_CODE_HDD_UNSUPPORTED_IOCTL,
4576 pAdapter->sessionId, 0));
Satyanarayana Dash72806012014-12-02 14:30:08 +05304577 hddLog( VOS_TRACE_LEVEL_WARN, FL("Unsupported GUI command %s"),
4578 command);
Madan Mohan Koyyalamudif9bdd4e2012-10-30 18:05:03 -07004579 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004580 }
4581exit:
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304582 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07004583 if (command)
4584 {
4585 kfree(command);
4586 }
4587 return ret;
4588}
4589
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07004590#ifdef CONFIG_COMPAT
4591static int hdd_driver_compat_ioctl(hdd_adapter_t *pAdapter, struct ifreq *ifr)
4592{
4593 struct {
4594 compat_uptr_t buf;
4595 int used_len;
4596 int total_len;
4597 } compat_priv_data;
4598 hdd_priv_data_t priv_data;
4599 int ret = 0;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004600
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07004601 /*
4602 * Note that pAdapter and ifr have already been verified by caller,
4603 * and HDD context has also been validated
4604 */
4605 if (copy_from_user(&compat_priv_data, ifr->ifr_data,
4606 sizeof(compat_priv_data))) {
4607 ret = -EFAULT;
4608 goto exit;
4609 }
4610 priv_data.buf = compat_ptr(compat_priv_data.buf);
4611 priv_data.used_len = compat_priv_data.used_len;
4612 priv_data.total_len = compat_priv_data.total_len;
4613 ret = hdd_driver_command(pAdapter, &priv_data);
4614 exit:
4615 return ret;
4616}
4617#else /* CONFIG_COMPAT */
4618static int hdd_driver_compat_ioctl(hdd_adapter_t *pAdapter, struct ifreq *ifr)
4619{
4620 /* will never be invoked */
4621 return 0;
4622}
4623#endif /* CONFIG_COMPAT */
4624
4625static int hdd_driver_ioctl(hdd_adapter_t *pAdapter, struct ifreq *ifr)
4626{
4627 hdd_priv_data_t priv_data;
4628 int ret = 0;
4629
4630 /*
4631 * Note that pAdapter and ifr have already been verified by caller,
4632 * and HDD context has also been validated
4633 */
4634 if (copy_from_user(&priv_data, ifr->ifr_data, sizeof(priv_data))) {
4635 ret = -EFAULT;
4636 } else {
4637 ret = hdd_driver_command(pAdapter, &priv_data);
4638 }
4639 return ret;
4640}
4641
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05304642int __hdd_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07004643{
4644 hdd_adapter_t *pAdapter;
4645 hdd_context_t *pHddCtx;
4646 int ret;
4647
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304648 ENTER();
4649
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07004650 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4651 if (NULL == pAdapter) {
4652 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
4653 "%s: HDD adapter context is Null", __func__);
4654 ret = -ENODEV;
4655 goto exit;
4656 }
4657 if (dev != pAdapter->dev) {
4658 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
4659 "%s: HDD adapter/dev inconsistency", __func__);
4660 ret = -ENODEV;
4661 goto exit;
4662 }
4663
4664 if ((!ifr) || (!ifr->ifr_data)) {
4665 ret = -EINVAL;
4666 goto exit;
4667 }
4668
4669 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
4670 ret = wlan_hdd_validate_context(pHddCtx);
4671 if (ret) {
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07004672 ret = -EBUSY;
4673 goto exit;
4674 }
4675
4676 switch (cmd) {
4677 case (SIOCDEVPRIVATE + 1):
4678 if (is_compat_task())
4679 ret = hdd_driver_compat_ioctl(pAdapter, ifr);
4680 else
4681 ret = hdd_driver_ioctl(pAdapter, ifr);
4682 break;
4683 default:
4684 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unknown ioctl %d",
4685 __func__, cmd);
4686 ret = -EINVAL;
4687 break;
4688 }
4689 exit:
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304690 EXIT();
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07004691 return ret;
4692}
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004693
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05304694int hdd_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
4695{
4696 int ret;
4697
4698 vos_ssr_protect(__func__);
4699 ret = __hdd_ioctl(dev, ifr, cmd);
4700 vos_ssr_unprotect(__func__);
4701
4702 return ret;
4703}
4704
Katya Nigame7b69a82015-04-28 15:24:06 +05304705int hdd_mon_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
4706{
4707 return 0;
4708}
4709
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004710#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004711/**---------------------------------------------------------------------------
4712
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004713 \brief hdd_parse_ese_beacon_req() - Parse ese beacon request
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004714
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004715 This function parses the ese beacon request passed in the format
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004716 CCXBEACONREQ<space><Number of fields><space><Measurement token>
4717 <space>Channel 1<space>Scan Mode <space>Meas Duration<space>Channel N
4718 <space>Scan Mode N<space>Meas Duration N
4719 if the Number of bcn req fields (N) does not match with the actual number of fields passed
4720 then take N.
4721 <Meas Token><Channel><Scan Mode> and <Meas Duration> are treated as one pair
4722 For example, CCXBEACONREQ 2 1 1 1 30 2 44 0 40.
4723 This function does not take care of removing duplicate channels from the list
4724
4725 \param - pValue Pointer to data
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004726 \param - pEseBcnReq output pointer to store parsed ie information
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004727
4728 \return - 0 for success non-zero for failure
4729
4730 --------------------------------------------------------------------------*/
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004731static VOS_STATUS hdd_parse_ese_beacon_req(tANI_U8 *pValue,
4732 tCsrEseBeaconReq *pEseBcnReq)
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004733{
4734 tANI_U8 *inPtr = pValue;
4735 int tempInt = 0;
4736 int j = 0, i = 0, v = 0;
4737 char buf[32];
4738
4739 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
4740 /*no argument after the command*/
4741 if (NULL == inPtr)
4742 {
4743 return -EINVAL;
4744 }
4745 /*no space after the command*/
4746 else if (SPACE_ASCII_VALUE != *inPtr)
4747 {
4748 return -EINVAL;
4749 }
4750
4751 /*removing empty spaces*/
4752 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
4753
4754 /*no argument followed by spaces*/
4755 if ('\0' == *inPtr) return -EINVAL;
4756
4757 /*getting the first argument ie measurement token*/
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08004758 v = sscanf(inPtr, "%31s ", buf);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004759 if (1 != v) return -EINVAL;
4760
4761 v = kstrtos32(buf, 10, &tempInt);
4762 if ( v < 0) return -EINVAL;
4763
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004764 pEseBcnReq->numBcnReqIe = tempInt;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004765
4766 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004767 "Number of Bcn Req Ie fields(%d)", pEseBcnReq->numBcnReqIe);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004768
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004769 for (j = 0; j < (pEseBcnReq->numBcnReqIe); j++)
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004770 {
4771 for (i = 0; i < 4; i++)
4772 {
4773 /*inPtr pointing to the beginning of first space after number of ie fields*/
4774 inPtr = strpbrk( inPtr, " " );
4775 /*no ie data after the number of ie fields argument*/
4776 if (NULL == inPtr) return -EINVAL;
4777
4778 /*removing empty space*/
4779 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
4780
4781 /*no ie data after the number of ie fields argument and spaces*/
4782 if ( '\0' == *inPtr ) return -EINVAL;
4783
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08004784 v = sscanf(inPtr, "%31s ", buf);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004785 if (1 != v) return -EINVAL;
4786
4787 v = kstrtos32(buf, 10, &tempInt);
4788 if (v < 0) return -EINVAL;
4789
4790 switch (i)
4791 {
4792 case 0: /* Measurement token */
4793 if (tempInt <= 0)
4794 {
4795 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4796 "Invalid Measurement Token(%d)", tempInt);
4797 return -EINVAL;
4798 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004799 pEseBcnReq->bcnReq[j].measurementToken = tempInt;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004800 break;
4801
4802 case 1: /* Channel number */
4803 if ((tempInt <= 0) ||
4804 (tempInt > WNI_CFG_CURRENT_CHANNEL_STAMAX))
4805 {
4806 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4807 "Invalid Channel Number(%d)", tempInt);
4808 return -EINVAL;
4809 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004810 pEseBcnReq->bcnReq[j].channel = tempInt;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004811 break;
4812
4813 case 2: /* Scan mode */
Varun Reddy Yeturu0b18d5a2013-12-04 11:42:23 -08004814 if ((tempInt < eSIR_PASSIVE_SCAN) || (tempInt > eSIR_BEACON_TABLE))
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004815 {
4816 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4817 "Invalid Scan Mode(%d) Expected{0|1|2}", tempInt);
4818 return -EINVAL;
4819 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004820 pEseBcnReq->bcnReq[j].scanMode= tempInt;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004821 break;
4822
4823 case 3: /* Measurement duration */
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004824 if (((tempInt <= 0) && (pEseBcnReq->bcnReq[j].scanMode != eSIR_BEACON_TABLE)) ||
4825 ((tempInt < 0) && (pEseBcnReq->bcnReq[j].scanMode == eSIR_BEACON_TABLE)))
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004826 {
4827 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4828 "Invalid Measurement Duration(%d)", tempInt);
4829 return -EINVAL;
4830 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004831 pEseBcnReq->bcnReq[j].measurementDuration = tempInt;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004832 break;
4833 }
4834 }
4835 }
4836
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004837 for (j = 0; j < pEseBcnReq->numBcnReqIe; j++)
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004838 {
4839 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Arun Kumar Khandavallie8768212014-02-17 16:43:34 +05304840 "Index(%d) Measurement Token(%u)Channel(%u) Scan Mode(%u) Measurement Duration(%u)\n",
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004841 j,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004842 pEseBcnReq->bcnReq[j].measurementToken,
4843 pEseBcnReq->bcnReq[j].channel,
4844 pEseBcnReq->bcnReq[j].scanMode,
4845 pEseBcnReq->bcnReq[j].measurementDuration);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004846 }
4847
4848 return VOS_STATUS_SUCCESS;
4849}
4850
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004851static void hdd_GetTsmStatsCB( tAniTrafStrmMetrics tsmMetrics, const tANI_U32 staId, void *pContext )
4852{
4853 struct statsContext *pStatsContext = NULL;
4854 hdd_adapter_t *pAdapter = NULL;
4855
4856 if (NULL == pContext)
4857 {
4858 hddLog(VOS_TRACE_LEVEL_ERROR,
4859 "%s: Bad param, pContext [%p]",
4860 __func__, pContext);
4861 return;
4862 }
4863
Jeff Johnson72a40512013-12-19 10:14:15 -08004864 /* there is a race condition that exists between this callback
4865 function and the caller since the caller could time out either
4866 before or while this code is executing. we use a spinlock to
4867 serialize these actions */
4868 spin_lock(&hdd_context_lock);
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004869
4870 pStatsContext = pContext;
4871 pAdapter = pStatsContext->pAdapter;
4872 if ((NULL == pAdapter) || (STATS_CONTEXT_MAGIC != pStatsContext->magic))
4873 {
4874 /* the caller presumably timed out so there is nothing we can do */
Jeff Johnson72a40512013-12-19 10:14:15 -08004875 spin_unlock(&hdd_context_lock);
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004876 hddLog(VOS_TRACE_LEVEL_WARN,
4877 "%s: Invalid context, pAdapter [%p] magic [%08x]",
4878 __func__, pAdapter, pStatsContext->magic);
4879 return;
4880 }
4881
Jeff Johnson72a40512013-12-19 10:14:15 -08004882 /* context is valid so caller is still waiting */
4883
4884 /* paranoia: invalidate the magic */
4885 pStatsContext->magic = 0;
4886
4887 /* copy over the tsm stats */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004888 pAdapter->tsmStats.UplinkPktQueueDly = tsmMetrics.UplinkPktQueueDly;
4889 vos_mem_copy(pAdapter->tsmStats.UplinkPktQueueDlyHist,
4890 tsmMetrics.UplinkPktQueueDlyHist,
4891 sizeof(pAdapter->tsmStats.UplinkPktQueueDlyHist)/
4892 sizeof(pAdapter->tsmStats.UplinkPktQueueDlyHist[0]));
4893 pAdapter->tsmStats.UplinkPktTxDly = tsmMetrics.UplinkPktTxDly;
4894 pAdapter->tsmStats.UplinkPktLoss = tsmMetrics.UplinkPktLoss;
4895 pAdapter->tsmStats.UplinkPktCount = tsmMetrics.UplinkPktCount;
4896 pAdapter->tsmStats.RoamingCount = tsmMetrics.RoamingCount;
4897 pAdapter->tsmStats.RoamingDly = tsmMetrics.RoamingDly;
4898
Jeff Johnson72a40512013-12-19 10:14:15 -08004899 /* notify the caller */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004900 complete(&pStatsContext->completion);
Jeff Johnson72a40512013-12-19 10:14:15 -08004901
4902 /* serialization is complete */
4903 spin_unlock(&hdd_context_lock);
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004904}
4905
4906
4907
4908static VOS_STATUS hdd_get_tsm_stats(hdd_adapter_t *pAdapter, const tANI_U8 tid,
4909 tAniTrafStrmMetrics* pTsmMetrics)
4910{
4911 hdd_station_ctx_t *pHddStaCtx = NULL;
4912 eHalStatus hstatus;
Jeff Johnson72a40512013-12-19 10:14:15 -08004913 VOS_STATUS vstatus = VOS_STATUS_SUCCESS;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004914 long lrc;
4915 struct statsContext context;
4916 hdd_context_t *pHddCtx = NULL;
4917
4918 if (NULL == pAdapter)
4919 {
4920 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: pAdapter is NULL", __func__);
4921 return VOS_STATUS_E_FAULT;
4922 }
4923
4924 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
4925 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4926
4927 /* we are connected prepare our callback context */
4928 init_completion(&context.completion);
4929 context.pAdapter = pAdapter;
4930 context.magic = STATS_CONTEXT_MAGIC;
4931
4932 /* query tsm stats */
4933 hstatus = sme_GetTsmStats(pHddCtx->hHal, hdd_GetTsmStatsCB,
4934 pHddStaCtx->conn_info.staId[ 0 ],
4935 pHddStaCtx->conn_info.bssId,
4936 &context, pHddCtx->pvosContext, tid);
4937
4938 if (eHAL_STATUS_SUCCESS != hstatus)
4939 {
Jeff Johnson72a40512013-12-19 10:14:15 -08004940 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unable to retrieve statistics",
4941 __func__);
4942 vstatus = VOS_STATUS_E_FAULT;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004943 }
4944 else
4945 {
4946 /* request was sent -- wait for the response */
4947 lrc = wait_for_completion_interruptible_timeout(&context.completion,
4948 msecs_to_jiffies(WLAN_WAIT_TIME_STATS));
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004949 if (lrc <= 0)
4950 {
4951 hddLog(VOS_TRACE_LEVEL_ERROR,
4952 "%s: SME %s while retrieving statistics",
4953 __func__, (0 == lrc) ? "timeout" : "interrupt");
Jeff Johnson72a40512013-12-19 10:14:15 -08004954 vstatus = VOS_STATUS_E_TIMEOUT;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004955 }
4956 }
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004957
Jeff Johnson72a40512013-12-19 10:14:15 -08004958 /* either we never sent a request, we sent a request and received a
4959 response or we sent a request and timed out. if we never sent a
4960 request or if we sent a request and got a response, we want to
4961 clear the magic out of paranoia. if we timed out there is a
4962 race condition such that the callback function could be
4963 executing at the same time we are. of primary concern is if the
4964 callback function had already verified the "magic" but had not
4965 yet set the completion variable when a timeout occurred. we
4966 serialize these activities by invalidating the magic while
4967 holding a shared spinlock which will cause us to block if the
4968 callback is currently executing */
4969 spin_lock(&hdd_context_lock);
4970 context.magic = 0;
4971 spin_unlock(&hdd_context_lock);
4972
4973 if (VOS_STATUS_SUCCESS == vstatus)
4974 {
4975 pTsmMetrics->UplinkPktQueueDly = pAdapter->tsmStats.UplinkPktQueueDly;
4976 vos_mem_copy(pTsmMetrics->UplinkPktQueueDlyHist,
4977 pAdapter->tsmStats.UplinkPktQueueDlyHist,
4978 sizeof(pAdapter->tsmStats.UplinkPktQueueDlyHist)/
4979 sizeof(pAdapter->tsmStats.UplinkPktQueueDlyHist[0]));
4980 pTsmMetrics->UplinkPktTxDly = pAdapter->tsmStats.UplinkPktTxDly;
4981 pTsmMetrics->UplinkPktLoss = pAdapter->tsmStats.UplinkPktLoss;
4982 pTsmMetrics->UplinkPktCount = pAdapter->tsmStats.UplinkPktCount;
4983 pTsmMetrics->RoamingCount = pAdapter->tsmStats.RoamingCount;
4984 pTsmMetrics->RoamingDly = pAdapter->tsmStats.RoamingDly;
4985 }
4986 return vstatus;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004987}
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004988#endif /*FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004989
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004990#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowdade697412013-02-14 16:31:48 -08004991void hdd_getBand_helper(hdd_context_t *pHddCtx, int *pBand)
4992{
4993 eCsrBand band = -1;
4994 sme_GetFreqBand((tHalHandle)(pHddCtx->hHal), &band);
4995 switch (band)
4996 {
4997 case eCSR_BAND_ALL:
4998 *pBand = WLAN_HDD_UI_BAND_AUTO;
4999 break;
5000
5001 case eCSR_BAND_24:
5002 *pBand = WLAN_HDD_UI_BAND_2_4_GHZ;
5003 break;
5004
5005 case eCSR_BAND_5G:
5006 *pBand = WLAN_HDD_UI_BAND_5_GHZ;
5007 break;
5008
5009 default:
5010 hddLog( VOS_TRACE_LEVEL_WARN, "%s: Invalid Band %d", __func__, band);
5011 *pBand = -1;
5012 break;
5013 }
5014}
5015
5016/**---------------------------------------------------------------------------
5017
Srinivas Girigowda100eb322013-03-15 16:48:20 -07005018 \brief hdd_parse_send_action_frame_data() - HDD Parse send action frame data
5019
5020 This function parses the send action frame data passed in the format
5021 SENDACTIONFRAME<space><bssid><space><channel><space><dwelltime><space><data>
5022
Srinivas Girigowda56076852013-08-20 14:00:50 -07005023 \param - pValue Pointer to input data
Srinivas Girigowda100eb322013-03-15 16:48:20 -07005024 \param - pTargetApBssid Pointer to target Ap bssid
5025 \param - pChannel Pointer to the Target AP channel
5026 \param - pDwellTime Pointer to the time to stay off-channel after transmitting action frame
5027 \param - pBuf Pointer to data
5028 \param - pBufLen Pointer to data length
5029
5030 \return - 0 for success non-zero for failure
5031
5032 --------------------------------------------------------------------------*/
5033VOS_STATUS hdd_parse_send_action_frame_data(tANI_U8 *pValue, tANI_U8 *pTargetApBssid, tANI_U8 *pChannel,
5034 tANI_U8 *pDwellTime, tANI_U8 **pBuf, tANI_U8 *pBufLen)
5035{
5036 tANI_U8 *inPtr = pValue;
5037 tANI_U8 *dataEnd;
5038 int tempInt;
5039 int j = 0;
5040 int i = 0;
5041 int v = 0;
5042 tANI_U8 tempBuf[32];
5043 tANI_U8 tempByte = 0;
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08005044 /* 12 hexa decimal digits, 5 ':' and '\0' */
5045 tANI_U8 macAddress[18];
Srinivas Girigowda100eb322013-03-15 16:48:20 -07005046
5047 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
5048 /*no argument after the command*/
5049 if (NULL == inPtr)
5050 {
5051 return -EINVAL;
5052 }
5053
5054 /*no space after the command*/
5055 else if (SPACE_ASCII_VALUE != *inPtr)
5056 {
5057 return -EINVAL;
5058 }
5059
5060 /*removing empty spaces*/
5061 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
5062
5063 /*no argument followed by spaces*/
5064 if ('\0' == *inPtr)
5065 {
5066 return -EINVAL;
5067 }
5068
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005069 v = sscanf(inPtr, "%17s", macAddress);
5070 if (!((1 == v) && hdd_is_valid_mac_address(macAddress)))
Srinivas Girigowda100eb322013-03-15 16:48:20 -07005071 {
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005072 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5073 "Invalid MAC address or All hex inputs are not read (%d)", v);
5074 return -EINVAL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07005075 }
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005076
5077 pTargetApBssid[0] = hdd_parse_hex(macAddress[0]) << 4 | hdd_parse_hex(macAddress[1]);
5078 pTargetApBssid[1] = hdd_parse_hex(macAddress[3]) << 4 | hdd_parse_hex(macAddress[4]);
5079 pTargetApBssid[2] = hdd_parse_hex(macAddress[6]) << 4 | hdd_parse_hex(macAddress[7]);
5080 pTargetApBssid[3] = hdd_parse_hex(macAddress[9]) << 4 | hdd_parse_hex(macAddress[10]);
5081 pTargetApBssid[4] = hdd_parse_hex(macAddress[12]) << 4 | hdd_parse_hex(macAddress[13]);
5082 pTargetApBssid[5] = hdd_parse_hex(macAddress[15]) << 4 | hdd_parse_hex(macAddress[16]);
Srinivas Girigowda100eb322013-03-15 16:48:20 -07005083
5084 /* point to the next argument */
5085 inPtr = strnchr(inPtr, strlen(inPtr), SPACE_ASCII_VALUE);
5086 /*no argument after the command*/
5087 if (NULL == inPtr) return -EINVAL;
5088
5089 /*removing empty spaces*/
5090 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
5091
5092 /*no argument followed by spaces*/
5093 if ('\0' == *inPtr)
5094 {
5095 return -EINVAL;
5096 }
5097
5098 /*getting the next argument ie the channel number */
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08005099 v = sscanf(inPtr, "%31s ", tempBuf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005100 if (1 != v) return -EINVAL;
5101
Srinivas Girigowda100eb322013-03-15 16:48:20 -07005102 v = kstrtos32(tempBuf, 10, &tempInt);
Agarwal Ashish353b3a82014-04-08 14:55:11 +05305103 if ( v < 0 || tempInt <= 0 || tempInt > WNI_CFG_CURRENT_CHANNEL_STAMAX )
Kiet Lambe150c22013-11-21 16:30:32 +05305104 return -EINVAL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07005105
5106 *pChannel = tempInt;
5107
5108 /* point to the next argument */
5109 inPtr = strnchr(inPtr, strlen(inPtr), SPACE_ASCII_VALUE);
5110 /*no argument after the command*/
5111 if (NULL == inPtr) return -EINVAL;
5112 /*removing empty spaces*/
5113 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
5114
5115 /*no argument followed by spaces*/
5116 if ('\0' == *inPtr)
5117 {
5118 return -EINVAL;
5119 }
5120
5121 /*getting the next argument ie the dwell time */
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08005122 v = sscanf(inPtr, "%31s ", tempBuf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005123 if (1 != v) return -EINVAL;
5124
Srinivas Girigowda100eb322013-03-15 16:48:20 -07005125 v = kstrtos32(tempBuf, 10, &tempInt);
Srinivas Girigowda5a6e0672014-01-09 14:42:57 -08005126 if ( v < 0 || tempInt < 0) return -EINVAL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07005127
5128 *pDwellTime = tempInt;
5129
5130 /* point to the next argument */
5131 inPtr = strnchr(inPtr, strlen(inPtr), SPACE_ASCII_VALUE);
5132 /*no argument after the command*/
5133 if (NULL == inPtr) return -EINVAL;
5134 /*removing empty spaces*/
5135 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
5136
5137 /*no argument followed by spaces*/
5138 if ('\0' == *inPtr)
5139 {
5140 return -EINVAL;
5141 }
5142
5143 /* find the length of data */
5144 dataEnd = inPtr;
5145 while(('\0' != *dataEnd) )
5146 {
5147 dataEnd++;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07005148 }
Kiet Lambe150c22013-11-21 16:30:32 +05305149 *pBufLen = dataEnd - inPtr ;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07005150 if ( *pBufLen <= 0) return -EINVAL;
5151
Srinivas Girigowdab5ae85d2013-06-03 10:51:45 -07005152 /* Allocate the number of bytes based on the number of input characters
5153 whether it is even or odd.
5154 if the number of input characters are even, then we need N/2 byte.
5155 if the number of input characters are odd, then we need do (N+1)/2 to
5156 compensate rounding off.
5157 For example, if N = 18, then (18 + 1)/2 = 9 bytes are enough.
5158 If N = 19, then we need 10 bytes, hence (19 + 1)/2 = 10 bytes */
5159 *pBuf = vos_mem_malloc((*pBufLen + 1)/2);
Srinivas Girigowda100eb322013-03-15 16:48:20 -07005160 if (NULL == *pBuf)
5161 {
5162 hddLog(VOS_TRACE_LEVEL_FATAL,
5163 "%s: vos_mem_alloc failed ", __func__);
5164 return -EINVAL;
5165 }
5166
5167 /* the buffer received from the upper layer is character buffer,
5168 we need to prepare the buffer taking 2 characters in to a U8 hex decimal number
5169 for example 7f0000f0...form a buffer to contain 7f in 0th location, 00 in 1st
5170 and f0 in 3rd location */
5171 for (i = 0, j = 0; j < *pBufLen; j += 2)
5172 {
Kiet Lambe150c22013-11-21 16:30:32 +05305173 if( j+1 == *pBufLen)
5174 {
5175 tempByte = hdd_parse_hex(inPtr[j]);
5176 }
5177 else
5178 {
5179 tempByte = (hdd_parse_hex(inPtr[j]) << 4) | (hdd_parse_hex(inPtr[j + 1]));
5180 }
Srinivas Girigowda100eb322013-03-15 16:48:20 -07005181 (*pBuf)[i++] = tempByte;
5182 }
5183 *pBufLen = i;
5184 return VOS_STATUS_SUCCESS;
5185}
5186
Srinivas Girigowda100eb322013-03-15 16:48:20 -07005187/**---------------------------------------------------------------------------
5188
Srinivas Girigowdade697412013-02-14 16:31:48 -08005189 \brief hdd_parse_channellist() - HDD Parse channel list
5190
5191 This function parses the channel list passed in the format
5192 SETROAMSCANCHANNELS<space><Number of channels><space>Channel 1<space>Channel 2<space>Channel N
Srinivas Girigowdacf9a9b42013-03-21 11:55:24 -07005193 if the Number of channels (N) does not match with the actual number of channels passed
5194 then take the minimum of N and count of (Ch1, Ch2, ...Ch M)
5195 For example, if SETROAMSCANCHANNELS 3 36 40 44 48, only 36, 40 and 44 shall be taken.
5196 If SETROAMSCANCHANNELS 5 36 40 44 48, ignore 5 and take 36, 40, 44 and 48.
5197 This function does not take care of removing duplicate channels from the list
Srinivas Girigowdade697412013-02-14 16:31:48 -08005198
5199 \param - pValue Pointer to input channel list
5200 \param - ChannelList Pointer to local output array to record channel list
5201 \param - pNumChannels Pointer to number of roam scan channels
5202
5203 \return - 0 for success non-zero for failure
5204
5205 --------------------------------------------------------------------------*/
5206VOS_STATUS hdd_parse_channellist(tANI_U8 *pValue, tANI_U8 *pChannelList, tANI_U8 *pNumChannels)
5207{
5208 tANI_U8 *inPtr = pValue;
5209 int tempInt;
5210 int j = 0;
5211 int v = 0;
5212 char buf[32];
5213
5214 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
5215 /*no argument after the command*/
5216 if (NULL == inPtr)
5217 {
5218 return -EINVAL;
5219 }
5220
5221 /*no space after the command*/
5222 else if (SPACE_ASCII_VALUE != *inPtr)
5223 {
5224 return -EINVAL;
5225 }
5226
5227 /*removing empty spaces*/
Jeff Johnsona1f9afb2013-04-03 09:13:31 -07005228 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
Srinivas Girigowdade697412013-02-14 16:31:48 -08005229
5230 /*no argument followed by spaces*/
5231 if ('\0' == *inPtr)
5232 {
5233 return -EINVAL;
5234 }
5235
5236 /*getting the first argument ie the number of channels*/
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08005237 v = sscanf(inPtr, "%31s ", buf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005238 if (1 != v) return -EINVAL;
5239
Srinivas Girigowdade697412013-02-14 16:31:48 -08005240 v = kstrtos32(buf, 10, &tempInt);
Jeff Johnsona1f9afb2013-04-03 09:13:31 -07005241 if ((v < 0) ||
5242 (tempInt <= 0) ||
5243 (tempInt > WNI_CFG_VALID_CHANNEL_LIST_LEN))
5244 {
5245 return -EINVAL;
5246 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08005247
5248 *pNumChannels = tempInt;
5249
5250 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
5251 "Number of channels are: %d", *pNumChannels);
5252
5253 for (j = 0; j < (*pNumChannels); j++)
5254 {
5255 /*inPtr pointing to the beginning of first space after number of channels*/
5256 inPtr = strpbrk( inPtr, " " );
5257 /*no channel list after the number of channels argument*/
5258 if (NULL == inPtr)
5259 {
Srinivas Girigowdacf9a9b42013-03-21 11:55:24 -07005260 if (0 != j)
5261 {
5262 *pNumChannels = j;
5263 return VOS_STATUS_SUCCESS;
5264 }
5265 else
5266 {
5267 return -EINVAL;
5268 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08005269 }
5270
5271 /*removing empty space*/
Jeff Johnsona1f9afb2013-04-03 09:13:31 -07005272 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
Srinivas Girigowdade697412013-02-14 16:31:48 -08005273
5274 /*no channel list after the number of channels argument and spaces*/
5275 if ( '\0' == *inPtr )
5276 {
Srinivas Girigowdacf9a9b42013-03-21 11:55:24 -07005277 if (0 != j)
5278 {
5279 *pNumChannels = j;
5280 return VOS_STATUS_SUCCESS;
5281 }
5282 else
5283 {
5284 return -EINVAL;
5285 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08005286 }
5287
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08005288 v = sscanf(inPtr, "%31s ", buf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005289 if (1 != v) return -EINVAL;
5290
Srinivas Girigowdade697412013-02-14 16:31:48 -08005291 v = kstrtos32(buf, 10, &tempInt);
Jeff Johnsona1f9afb2013-04-03 09:13:31 -07005292 if ((v < 0) ||
5293 (tempInt <= 0) ||
5294 (tempInt > WNI_CFG_CURRENT_CHANNEL_STAMAX))
5295 {
5296 return -EINVAL;
5297 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08005298 pChannelList[j] = tempInt;
5299
5300 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
5301 "Channel %d added to preferred channel list",
5302 pChannelList[j] );
5303 }
5304
Srinivas Girigowdade697412013-02-14 16:31:48 -08005305 return VOS_STATUS_SUCCESS;
5306}
5307
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005308
5309/**---------------------------------------------------------------------------
5310
5311 \brief hdd_parse_reassoc_command_data() - HDD Parse reassoc command data
5312
5313 This function parses the reasoc command data passed in the format
5314 REASSOC<space><bssid><space><channel>
5315
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005316 \param - pValue Pointer to input data (its a NUL terminated string)
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005317 \param - pTargetApBssid Pointer to target Ap bssid
5318 \param - pChannel Pointer to the Target AP channel
5319
5320 \return - 0 for success non-zero for failure
5321
5322 --------------------------------------------------------------------------*/
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005323VOS_STATUS hdd_parse_reassoc_command_data(tANI_U8 *pValue,
5324 tANI_U8 *pTargetApBssid, tANI_U8 *pChannel)
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005325{
5326 tANI_U8 *inPtr = pValue;
5327 int tempInt;
5328 int v = 0;
5329 tANI_U8 tempBuf[32];
Kiet Lamaa8e15a2014-02-11 23:30:06 -08005330 /* 12 hexa decimal digits, 5 ':' and '\0' */
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08005331 tANI_U8 macAddress[18];
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005332
5333 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
5334 /*no argument after the command*/
5335 if (NULL == inPtr)
5336 {
5337 return -EINVAL;
5338 }
5339
5340 /*no space after the command*/
5341 else if (SPACE_ASCII_VALUE != *inPtr)
5342 {
5343 return -EINVAL;
5344 }
5345
5346 /*removing empty spaces*/
5347 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
5348
5349 /*no argument followed by spaces*/
5350 if ('\0' == *inPtr)
5351 {
5352 return -EINVAL;
5353 }
5354
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005355 v = sscanf(inPtr, "%17s", macAddress);
5356 if (!((1 == v) && hdd_is_valid_mac_address(macAddress)))
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005357 {
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005358 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5359 "Invalid MAC address or All hex inputs are not read (%d)", v);
5360 return -EINVAL;
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005361 }
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005362
5363 pTargetApBssid[0] = hdd_parse_hex(macAddress[0]) << 4 | hdd_parse_hex(macAddress[1]);
5364 pTargetApBssid[1] = hdd_parse_hex(macAddress[3]) << 4 | hdd_parse_hex(macAddress[4]);
5365 pTargetApBssid[2] = hdd_parse_hex(macAddress[6]) << 4 | hdd_parse_hex(macAddress[7]);
5366 pTargetApBssid[3] = hdd_parse_hex(macAddress[9]) << 4 | hdd_parse_hex(macAddress[10]);
5367 pTargetApBssid[4] = hdd_parse_hex(macAddress[12]) << 4 | hdd_parse_hex(macAddress[13]);
5368 pTargetApBssid[5] = hdd_parse_hex(macAddress[15]) << 4 | hdd_parse_hex(macAddress[16]);
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005369
5370 /* point to the next argument */
5371 inPtr = strnchr(inPtr, strlen(inPtr), SPACE_ASCII_VALUE);
5372 /*no argument after the command*/
5373 if (NULL == inPtr) return -EINVAL;
5374
5375 /*removing empty spaces*/
5376 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
5377
5378 /*no argument followed by spaces*/
5379 if ('\0' == *inPtr)
5380 {
5381 return -EINVAL;
5382 }
5383
5384 /*getting the next argument ie the channel number */
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08005385 v = sscanf(inPtr, "%31s ", tempBuf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005386 if (1 != v) return -EINVAL;
5387
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005388 v = kstrtos32(tempBuf, 10, &tempInt);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005389 if ((v < 0) ||
Padma, Santhosh Kumar0fa809b2014-11-13 14:56:56 +05305390 (tempInt < 0) ||
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005391 (tempInt > WNI_CFG_CURRENT_CHANNEL_STAMAX))
5392 {
5393 return -EINVAL;
5394 }
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005395
5396 *pChannel = tempInt;
5397 return VOS_STATUS_SUCCESS;
5398}
5399
5400#endif
5401
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005402#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07005403/**---------------------------------------------------------------------------
5404
5405 \brief hdd_parse_get_cckm_ie() - HDD Parse and fetch the CCKM IE
5406
5407 This function parses the SETCCKM IE command
5408 SETCCKMIE<space><ie data>
5409
5410 \param - pValue Pointer to input data
5411 \param - pCckmIe Pointer to output cckm Ie
5412 \param - pCckmIeLen Pointer to output cckm ie length
5413
5414 \return - 0 for success non-zero for failure
5415
5416 --------------------------------------------------------------------------*/
5417VOS_STATUS hdd_parse_get_cckm_ie(tANI_U8 *pValue, tANI_U8 **pCckmIe,
5418 tANI_U8 *pCckmIeLen)
5419{
5420 tANI_U8 *inPtr = pValue;
5421 tANI_U8 *dataEnd;
5422 int j = 0;
5423 int i = 0;
5424 tANI_U8 tempByte = 0;
5425
5426 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
5427 /*no argument after the command*/
5428 if (NULL == inPtr)
5429 {
5430 return -EINVAL;
5431 }
5432
5433 /*no space after the command*/
5434 else if (SPACE_ASCII_VALUE != *inPtr)
5435 {
5436 return -EINVAL;
5437 }
5438
5439 /*removing empty spaces*/
5440 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
5441
5442 /*no argument followed by spaces*/
5443 if ('\0' == *inPtr)
5444 {
5445 return -EINVAL;
5446 }
5447
5448 /* find the length of data */
5449 dataEnd = inPtr;
5450 while(('\0' != *dataEnd) )
5451 {
5452 dataEnd++;
5453 ++(*pCckmIeLen);
5454 }
5455 if ( *pCckmIeLen <= 0) return -EINVAL;
5456
5457 /* Allocate the number of bytes based on the number of input characters
5458 whether it is even or odd.
5459 if the number of input characters are even, then we need N/2 byte.
5460 if the number of input characters are odd, then we need do (N+1)/2 to
5461 compensate rounding off.
5462 For example, if N = 18, then (18 + 1)/2 = 9 bytes are enough.
5463 If N = 19, then we need 10 bytes, hence (19 + 1)/2 = 10 bytes */
5464 *pCckmIe = vos_mem_malloc((*pCckmIeLen + 1)/2);
5465 if (NULL == *pCckmIe)
5466 {
5467 hddLog(VOS_TRACE_LEVEL_FATAL,
5468 "%s: vos_mem_alloc failed ", __func__);
5469 return -EINVAL;
5470 }
5471 vos_mem_zero(*pCckmIe, (*pCckmIeLen + 1)/2);
5472 /* the buffer received from the upper layer is character buffer,
5473 we need to prepare the buffer taking 2 characters in to a U8 hex decimal number
5474 for example 7f0000f0...form a buffer to contain 7f in 0th location, 00 in 1st
5475 and f0 in 3rd location */
5476 for (i = 0, j = 0; j < *pCckmIeLen; j += 2)
5477 {
5478 tempByte = (hdd_parse_hex(inPtr[j]) << 4) | (hdd_parse_hex(inPtr[j + 1]));
5479 (*pCckmIe)[i++] = tempByte;
5480 }
5481 *pCckmIeLen = i;
5482
5483 return VOS_STATUS_SUCCESS;
5484}
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005485#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07005486
Jeff Johnson295189b2012-06-20 16:38:30 -07005487/**---------------------------------------------------------------------------
5488
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005489 \brief hdd_is_valid_mac_address() - Validate MAC address
5490
5491 This function validates whether the given MAC address is valid or not
5492 Expected MAC address is of the format XX:XX:XX:XX:XX:XX
5493 where X is the hexa decimal digit character and separated by ':'
5494 This algorithm works even if MAC address is not separated by ':'
5495
5496 This code checks given input string mac contains exactly 12 hexadecimal digits.
5497 and a separator colon : appears in the input string only after
5498 an even number of hex digits.
5499
5500 \param - pMacAddr pointer to the input MAC address
5501 \return - 1 for valid and 0 for invalid
5502
5503 --------------------------------------------------------------------------*/
5504
5505v_BOOL_t hdd_is_valid_mac_address(const tANI_U8 *pMacAddr)
5506{
5507 int xdigit = 0;
5508 int separator = 0;
5509 while (*pMacAddr)
5510 {
5511 if (isxdigit(*pMacAddr))
5512 {
5513 xdigit++;
5514 }
5515 else if (':' == *pMacAddr)
5516 {
5517 if (0 == xdigit || ((xdigit / 2) - 1) != separator)
5518 break;
5519
5520 ++separator;
5521 }
5522 else
5523 {
5524 separator = -1;
5525 /* Invalid MAC found */
5526 return 0;
5527 }
5528 ++pMacAddr;
5529 }
5530 return (xdigit == 12 && (separator == 5 || separator == 0));
5531}
5532
5533/**---------------------------------------------------------------------------
5534
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305535 \brief __hdd_open() - HDD Open function
Jeff Johnson295189b2012-06-20 16:38:30 -07005536
5537 \param - dev Pointer to net_device structure
5538
5539 \return - 0 for success non-zero for failure
5540
5541 --------------------------------------------------------------------------*/
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305542int __hdd_open(struct net_device *dev)
Jeff Johnson295189b2012-06-20 16:38:30 -07005543{
5544 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5545 hdd_context_t *pHddCtx;
5546 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
5547 VOS_STATUS status;
5548 v_BOOL_t in_standby = TRUE;
5549
5550 if (NULL == pAdapter)
5551 {
5552 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Agarwal Ashish971c2882013-10-30 20:11:12 +05305553 "%s: pAdapter is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005554 return -ENODEV;
5555 }
5556
5557 pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05305558 MTRACE(vos_trace(VOS_MODULE_ID_HDD, TRACE_CODE_HDD_OPEN_REQUEST,
5559 pAdapter->sessionId, pAdapter->device_mode));
Jeff Johnson295189b2012-06-20 16:38:30 -07005560 if (NULL == pHddCtx)
5561 {
5562 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005563 "%s: HDD context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005564 return -ENODEV;
5565 }
5566
5567 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
5568 while ( (NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status) )
5569 {
Jeff Johnson6a81ca42013-04-05 10:37:08 -07005570 if (test_bit(DEVICE_IFACE_OPENED, &pAdapterNode->pAdapter->event_flags))
5571 {
5572 hddLog(VOS_TRACE_LEVEL_INFO, "%s: chip already out of standby",
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05305573 __func__);
Jeff Johnson6a81ca42013-04-05 10:37:08 -07005574 in_standby = FALSE;
5575 break;
5576 }
5577 else
5578 {
5579 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
5580 pAdapterNode = pNext;
5581 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005582 }
5583
5584 if (TRUE == in_standby)
5585 {
5586 if (VOS_STATUS_SUCCESS != wlan_hdd_exit_lowpower(pHddCtx, pAdapter))
5587 {
5588 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Failed to bring "
5589 "wlan out of power save", __func__);
5590 return -EINVAL;
5591 }
5592 }
5593
Jeff Johnson6a81ca42013-04-05 10:37:08 -07005594 set_bit(DEVICE_IFACE_OPENED, &pAdapter->event_flags);
Jeff Johnson295189b2012-06-20 16:38:30 -07005595 if (hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter)))
5596 {
5597 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005598 "%s: Enabling Tx Queues", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005599 /* Enable TX queues only when we are connected */
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +05305600 hddLog(VOS_TRACE_LEVEL_INFO, FL("Enabling queues"));
Jeff Johnson295189b2012-06-20 16:38:30 -07005601 netif_tx_start_all_queues(dev);
5602 }
5603
5604 return 0;
5605}
5606
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305607/**---------------------------------------------------------------------------
5608
5609 \brief hdd_open() - Wrapper function for __hdd_open to protect it from SSR
5610
5611 This is called in response to ifconfig up
5612
5613 \param - dev Pointer to net_device structure
5614
5615 \return - 0 for success non-zero for failure
5616
5617 --------------------------------------------------------------------------*/
5618int hdd_open(struct net_device *dev)
5619{
5620 int ret;
5621
5622 vos_ssr_protect(__func__);
5623 ret = __hdd_open(dev);
5624 vos_ssr_unprotect(__func__);
5625
5626 return ret;
5627}
5628
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05305629int __hdd_mon_open (struct net_device *dev)
Jeff Johnson295189b2012-06-20 16:38:30 -07005630{
5631 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5632
5633 if(pAdapter == NULL) {
5634 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005635 "%s: HDD adapter context is Null", __func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08005636 return -EINVAL;
Jeff Johnson295189b2012-06-20 16:38:30 -07005637 }
5638
Jeff Johnson295189b2012-06-20 16:38:30 -07005639 return 0;
5640}
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05305641
5642int hdd_mon_open (struct net_device *dev)
5643{
5644 int ret;
5645
5646 vos_ssr_protect(__func__);
5647 ret = __hdd_mon_open(dev);
5648 vos_ssr_unprotect(__func__);
5649
5650 return ret;
5651}
5652
Katya Nigame7b69a82015-04-28 15:24:06 +05305653int hdd_mon_stop(struct net_device *dev)
5654{
5655 return 0;
5656}
5657
Jeff Johnson295189b2012-06-20 16:38:30 -07005658/**---------------------------------------------------------------------------
5659
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305660 \brief __hdd_stop() - HDD stop function
Jeff Johnson295189b2012-06-20 16:38:30 -07005661
5662 \param - dev Pointer to net_device structure
5663
5664 \return - 0 for success non-zero for failure
5665
5666 --------------------------------------------------------------------------*/
5667
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305668int __hdd_stop (struct net_device *dev)
Jeff Johnson295189b2012-06-20 16:38:30 -07005669{
Vinay Krishna Eranna90f43532014-10-27 16:45:54 +05305670 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07005671 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5672 hdd_context_t *pHddCtx;
5673 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
5674 VOS_STATUS status;
5675 v_BOOL_t enter_standby = TRUE;
5676
5677 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07005678 if (NULL == pAdapter)
5679 {
5680 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Agarwal Ashish971c2882013-10-30 20:11:12 +05305681 "%s: pAdapter is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005682 return -ENODEV;
5683 }
Sachin Ahuja9b4958f2015-01-15 21:37:00 +05305684 MTRACE(vos_trace(VOS_MODULE_ID_HDD, TRACE_CODE_HDD_STOP_REQUEST,
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05305685 pAdapter->sessionId, pAdapter->device_mode));
Vinay Krishna Eranna90f43532014-10-27 16:45:54 +05305686
5687 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
5688 ret = wlan_hdd_validate_context(pHddCtx);
5689 if (ret)
Jeff Johnson295189b2012-06-20 16:38:30 -07005690 {
Vinay Krishna Eranna90f43532014-10-27 16:45:54 +05305691 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07005692 }
5693
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05305694 /* Nothing to be done if the interface is not opened */
5695 if (VOS_FALSE == test_bit(DEVICE_IFACE_OPENED, &pAdapter->event_flags))
5696 {
5697 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5698 "%s: NETDEV Interface is not OPENED", __func__);
5699 return -ENODEV;
5700 }
5701
5702 /* Make sure the interface is marked as closed */
Jeff Johnson6a81ca42013-04-05 10:37:08 -07005703 clear_bit(DEVICE_IFACE_OPENED, &pAdapter->event_flags);
Jeff Johnson295189b2012-06-20 16:38:30 -07005704 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Disabling OS Tx queues", __func__);
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05305705
5706 /* Disable TX on the interface, after this hard_start_xmit() will not
5707 * be called on that interface
5708 */
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +05305709 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Jeff Johnson295189b2012-06-20 16:38:30 -07005710 netif_tx_disable(pAdapter->dev);
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05305711
5712 /* Mark the interface status as "down" for outside world */
Jeff Johnson295189b2012-06-20 16:38:30 -07005713 netif_carrier_off(pAdapter->dev);
5714
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05305715 /* The interface is marked as down for outside world (aka kernel)
5716 * But the driver is pretty much alive inside. The driver needs to
5717 * tear down the existing connection on the netdev (session)
5718 * cleanup the data pipes and wait until the control plane is stabilized
5719 * for this interface. The call also needs to wait until the above
5720 * mentioned actions are completed before returning to the caller.
5721 * Notice that the hdd_stop_adapter is requested not to close the session
5722 * That is intentional to be able to scan if it is a STA/P2P interface
5723 */
5724 hdd_stop_adapter(pHddCtx, pAdapter, VOS_FALSE);
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05305725#ifdef FEATURE_WLAN_TDLS
5726 mutex_lock(&pHddCtx->tdls_lock);
5727#endif
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05305728 /* DeInit the adapter. This ensures datapath cleanup as well */
c_hpothu002231a2015-02-05 14:58:51 +05305729 hdd_deinit_adapter(pHddCtx, pAdapter, TRUE);
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05305730#ifdef FEATURE_WLAN_TDLS
5731 mutex_unlock(&pHddCtx->tdls_lock);
5732#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07005733 /* SoftAP ifaces should never go in power save mode
5734 making sure same here. */
5735 if ( (WLAN_HDD_SOFTAP == pAdapter->device_mode )
5736 || (WLAN_HDD_MONITOR == pAdapter->device_mode )
Jeff Johnson295189b2012-06-20 16:38:30 -07005737 || (WLAN_HDD_P2P_GO == pAdapter->device_mode )
Jeff Johnson295189b2012-06-20 16:38:30 -07005738 )
5739 {
5740 /* SoftAP mode, so return from here */
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305741 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
5742 "%s: In SAP MODE", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005743 EXIT();
5744 return 0;
5745 }
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05305746 /* Find if any iface is up. If any iface is up then can't put device to
5747 * sleep/power save mode
5748 */
Jeff Johnson295189b2012-06-20 16:38:30 -07005749 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
5750 while ( (NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status) )
5751 {
Jeff Johnson6a81ca42013-04-05 10:37:08 -07005752 if (test_bit(DEVICE_IFACE_OPENED, &pAdapterNode->pAdapter->event_flags))
5753 {
5754 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Still other ifaces are up cannot "
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05305755 "put device to sleep", __func__);
Jeff Johnson6a81ca42013-04-05 10:37:08 -07005756 enter_standby = FALSE;
5757 break;
5758 }
5759 else
5760 {
5761 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
5762 pAdapterNode = pNext;
5763 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005764 }
5765
5766 if (TRUE == enter_standby)
5767 {
5768 hddLog(VOS_TRACE_LEVEL_INFO, "%s: All Interfaces are Down "
5769 "entering standby", __func__);
5770 if (VOS_STATUS_SUCCESS != wlan_hdd_enter_lowpower(pHddCtx))
5771 {
5772 /*log and return success*/
5773 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Failed to put "
5774 "wlan in power save", __func__);
5775 }
5776 }
5777
5778 EXIT();
5779 return 0;
5780}
5781
5782/**---------------------------------------------------------------------------
5783
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305784 \brief hdd_stop() - wrapper_function for __hdd_stop to protect it from SSR
Jeff Johnson295189b2012-06-20 16:38:30 -07005785
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305786 This is called in response to ifconfig down
5787
5788 \param - dev Pointer to net_device structure
5789
5790 \return - 0 for success non-zero for failure
5791-----------------------------------------------------------------------------*/
5792int hdd_stop (struct net_device *dev)
5793{
5794 int ret;
5795
5796 vos_ssr_protect(__func__);
5797 ret = __hdd_stop(dev);
5798 vos_ssr_unprotect(__func__);
5799
5800 return ret;
5801}
5802
5803/**---------------------------------------------------------------------------
5804
5805 \brief __hdd_uninit() - HDD uninit function
Jeff Johnson295189b2012-06-20 16:38:30 -07005806
5807 \param - dev Pointer to net_device structure
5808
5809 \return - void
5810
5811 --------------------------------------------------------------------------*/
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305812static void __hdd_uninit (struct net_device *dev)
Jeff Johnson295189b2012-06-20 16:38:30 -07005813{
5814 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05305815 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07005816 ENTER();
5817
5818 do
5819 {
5820 if (NULL == pAdapter)
5821 {
5822 hddLog(VOS_TRACE_LEVEL_FATAL,
5823 "%s: NULL pAdapter", __func__);
5824 break;
5825 }
5826
5827 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
5828 {
5829 hddLog(VOS_TRACE_LEVEL_FATAL,
5830 "%s: Invalid magic", __func__);
5831 break;
5832 }
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05305833 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
5834 if (NULL == pHddCtx)
Jeff Johnson295189b2012-06-20 16:38:30 -07005835 {
5836 hddLog(VOS_TRACE_LEVEL_FATAL,
5837 "%s: NULL pHddCtx", __func__);
5838 break;
5839 }
5840
5841 if (dev != pAdapter->dev)
5842 {
5843 hddLog(VOS_TRACE_LEVEL_FATAL,
5844 "%s: Invalid device reference", __func__);
5845 /* we haven't validated all cases so let this go for now */
5846 }
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05305847#ifdef FEATURE_WLAN_TDLS
5848 mutex_lock(&pHddCtx->tdls_lock);
5849#endif
c_hpothu002231a2015-02-05 14:58:51 +05305850 hdd_deinit_adapter(pHddCtx, pAdapter, TRUE);
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05305851#ifdef FEATURE_WLAN_TDLS
5852 mutex_unlock(&pHddCtx->tdls_lock);
5853#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07005854
5855 /* after uninit our adapter structure will no longer be valid */
5856 pAdapter->dev = NULL;
5857 pAdapter->magic = 0;
5858 } while (0);
5859
5860 EXIT();
5861}
5862
5863/**---------------------------------------------------------------------------
5864
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305865 \brief hdd_uninit() - Wrapper function to protect __hdd_uninit from SSR
5866
5867 This is called during the netdev unregister to uninitialize all data
5868associated with the device
5869
5870 \param - dev Pointer to net_device structure
5871
5872 \return - void
5873
5874 --------------------------------------------------------------------------*/
5875static void hdd_uninit (struct net_device *dev)
5876{
5877 vos_ssr_protect(__func__);
5878 __hdd_uninit(dev);
5879 vos_ssr_unprotect(__func__);
5880}
5881
5882/**---------------------------------------------------------------------------
5883
Jeff Johnson295189b2012-06-20 16:38:30 -07005884 \brief hdd_release_firmware() -
5885
5886 This function calls the release firmware API to free the firmware buffer.
5887
5888 \param - pFileName Pointer to the File Name.
5889 pCtx - Pointer to the adapter .
5890
5891
5892 \return - 0 for success, non zero for failure
5893
5894 --------------------------------------------------------------------------*/
5895
5896VOS_STATUS hdd_release_firmware(char *pFileName,v_VOID_t *pCtx)
5897{
5898 VOS_STATUS status = VOS_STATUS_SUCCESS;
5899 hdd_context_t *pHddCtx = (hdd_context_t*)pCtx;
5900 ENTER();
5901
5902
5903 if (!strcmp(WLAN_FW_FILE, pFileName)) {
5904
5905 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,"%s: Loaded firmware file is %s",__func__,pFileName);
5906
5907 if(pHddCtx->fw) {
5908 release_firmware(pHddCtx->fw);
5909 pHddCtx->fw = NULL;
5910 }
5911 else
5912 status = VOS_STATUS_E_FAILURE;
5913 }
5914 else if (!strcmp(WLAN_NV_FILE,pFileName)) {
5915 if(pHddCtx->nv) {
5916 release_firmware(pHddCtx->nv);
5917 pHddCtx->nv = NULL;
5918 }
5919 else
5920 status = VOS_STATUS_E_FAILURE;
5921
5922 }
5923
5924 EXIT();
5925 return status;
5926}
5927
5928/**---------------------------------------------------------------------------
5929
5930 \brief hdd_request_firmware() -
5931
5932 This function reads the firmware file using the request firmware
5933 API and returns the the firmware data and the firmware file size.
5934
5935 \param - pfileName - Pointer to the file name.
5936 - pCtx - Pointer to the adapter .
5937 - ppfw_data - Pointer to the pointer of the firmware data.
5938 - pSize - Pointer to the file size.
5939
5940 \return - VOS_STATUS_SUCCESS for success, VOS_STATUS_E_FAILURE for failure
5941
5942 --------------------------------------------------------------------------*/
5943
5944
5945VOS_STATUS hdd_request_firmware(char *pfileName,v_VOID_t *pCtx,v_VOID_t **ppfw_data, v_SIZE_t *pSize)
5946{
5947 int status;
5948 VOS_STATUS retval = VOS_STATUS_SUCCESS;
5949 hdd_context_t *pHddCtx = (hdd_context_t*)pCtx;
5950 ENTER();
5951
5952 if( (!strcmp(WLAN_FW_FILE, pfileName)) ) {
5953
5954 status = request_firmware(&pHddCtx->fw, pfileName, pHddCtx->parent_dev);
5955
5956 if(status || !pHddCtx->fw || !pHddCtx->fw->data) {
5957 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Firmware %s download failed",
5958 __func__, pfileName);
5959 retval = VOS_STATUS_E_FAILURE;
5960 }
5961
5962 else {
5963 *ppfw_data = (v_VOID_t *)pHddCtx->fw->data;
5964 *pSize = pHddCtx->fw->size;
5965 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Firmware size = %d",
5966 __func__, *pSize);
5967 }
5968 }
5969 else if(!strcmp(WLAN_NV_FILE, pfileName)) {
5970
5971 status = request_firmware(&pHddCtx->nv, pfileName, pHddCtx->parent_dev);
5972
5973 if(status || !pHddCtx->nv || !pHddCtx->nv->data) {
5974 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: nv %s download failed",
5975 __func__, pfileName);
5976 retval = VOS_STATUS_E_FAILURE;
5977 }
5978
5979 else {
5980 *ppfw_data = (v_VOID_t *)pHddCtx->nv->data;
5981 *pSize = pHddCtx->nv->size;
5982 hddLog(VOS_TRACE_LEVEL_INFO, "%s: nv file size = %d",
5983 __func__, *pSize);
5984 }
5985 }
5986
5987 EXIT();
5988 return retval;
5989}
5990/**---------------------------------------------------------------------------
5991 \brief hdd_full_pwr_cbk() - HDD full power callbackfunction
5992
5993 This is the function invoked by SME to inform the result of a full power
5994 request issued by HDD
5995
5996 \param - callbackcontext - Pointer to cookie
5997 status - result of request
5998
5999 \return - None
6000
6001--------------------------------------------------------------------------*/
6002void hdd_full_pwr_cbk(void *callbackContext, eHalStatus status)
6003{
6004 hdd_context_t *pHddCtx = (hdd_context_t*)callbackContext;
6005
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07006006 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,"HDD full Power callback status = %d", status);
Jeff Johnson295189b2012-06-20 16:38:30 -07006007 if(&pHddCtx->full_pwr_comp_var)
6008 {
6009 complete(&pHddCtx->full_pwr_comp_var);
6010 }
6011}
6012
6013/**---------------------------------------------------------------------------
6014
6015 \brief hdd_req_bmps_cbk() - HDD Request BMPS callback function
6016
6017 This is the function invoked by SME to inform the result of BMPS
6018 request issued by HDD
6019
6020 \param - callbackcontext - Pointer to cookie
6021 status - result of request
6022
6023 \return - None
6024
6025--------------------------------------------------------------------------*/
6026void hdd_req_bmps_cbk(void *callbackContext, eHalStatus status)
6027{
6028
6029 struct completion *completion_var = (struct completion*) callbackContext;
6030
Arif Hussain6d2a3322013-11-17 19:50:10 -08006031 hddLog(VOS_TRACE_LEVEL_ERROR, "HDD BMPS request Callback, status = %d", status);
Jeff Johnson295189b2012-06-20 16:38:30 -07006032 if(completion_var != NULL)
6033 {
6034 complete(completion_var);
6035 }
6036}
6037
6038/**---------------------------------------------------------------------------
6039
6040 \brief hdd_get_cfg_file_size() -
6041
6042 This function reads the configuration file using the request firmware
6043 API and returns the configuration file size.
6044
6045 \param - pCtx - Pointer to the adapter .
6046 - pFileName - Pointer to the file name.
6047 - pBufSize - Pointer to the buffer size.
6048
6049 \return - 0 for success, non zero for failure
6050
6051 --------------------------------------------------------------------------*/
6052
6053VOS_STATUS hdd_get_cfg_file_size(v_VOID_t *pCtx, char *pFileName, v_SIZE_t *pBufSize)
6054{
6055 int status;
6056 hdd_context_t *pHddCtx = (hdd_context_t*)pCtx;
6057
6058 ENTER();
6059
6060 status = request_firmware(&pHddCtx->fw, pFileName, pHddCtx->parent_dev);
6061
6062 if(status || !pHddCtx->fw || !pHddCtx->fw->data) {
6063 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: CFG download failed",__func__);
6064 status = VOS_STATUS_E_FAILURE;
6065 }
6066 else {
6067 *pBufSize = pHddCtx->fw->size;
6068 hddLog(VOS_TRACE_LEVEL_INFO, "%s: CFG size = %d", __func__, *pBufSize);
6069 release_firmware(pHddCtx->fw);
6070 pHddCtx->fw = NULL;
6071 }
6072
6073 EXIT();
6074 return VOS_STATUS_SUCCESS;
6075}
6076
6077/**---------------------------------------------------------------------------
6078
6079 \brief hdd_read_cfg_file() -
6080
6081 This function reads the configuration file using the request firmware
6082 API and returns the cfg data and the buffer size of the configuration file.
6083
6084 \param - pCtx - Pointer to the adapter .
6085 - pFileName - Pointer to the file name.
6086 - pBuffer - Pointer to the data buffer.
6087 - pBufSize - Pointer to the buffer size.
6088
6089 \return - 0 for success, non zero for failure
6090
6091 --------------------------------------------------------------------------*/
6092
6093VOS_STATUS hdd_read_cfg_file(v_VOID_t *pCtx, char *pFileName,
6094 v_VOID_t *pBuffer, v_SIZE_t *pBufSize)
6095{
6096 int status;
6097 hdd_context_t *pHddCtx = (hdd_context_t*)pCtx;
6098
6099 ENTER();
6100
6101 status = request_firmware(&pHddCtx->fw, pFileName, pHddCtx->parent_dev);
6102
6103 if(status || !pHddCtx->fw || !pHddCtx->fw->data) {
6104 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: CFG download failed",__func__);
6105 return VOS_STATUS_E_FAILURE;
6106 }
6107 else {
6108 if(*pBufSize != pHddCtx->fw->size) {
6109 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Caller sets invalid CFG "
6110 "file size", __func__);
6111 release_firmware(pHddCtx->fw);
6112 pHddCtx->fw = NULL;
6113 return VOS_STATUS_E_FAILURE;
6114 }
6115 else {
6116 if(pBuffer) {
6117 vos_mem_copy(pBuffer,pHddCtx->fw->data,*pBufSize);
6118 }
6119 release_firmware(pHddCtx->fw);
6120 pHddCtx->fw = NULL;
6121 }
6122 }
6123
6124 EXIT();
6125
6126 return VOS_STATUS_SUCCESS;
6127}
6128
6129/**---------------------------------------------------------------------------
6130
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05306131 \brief __hdd_set_mac_address() -
Jeff Johnson295189b2012-06-20 16:38:30 -07006132
6133 This function sets the user specified mac address using
6134 the command ifconfig wlanX hw ether <mac adress>.
6135
6136 \param - dev - Pointer to the net device.
6137 - addr - Pointer to the sockaddr.
6138 \return - 0 for success, non zero for failure
6139
6140 --------------------------------------------------------------------------*/
6141
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05306142static int __hdd_set_mac_address(struct net_device *dev, void *addr)
Jeff Johnson295189b2012-06-20 16:38:30 -07006143{
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05306144 hdd_adapter_t *pAdapter;
6145 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07006146 struct sockaddr *psta_mac_addr = addr;
6147 eHalStatus halStatus = eHAL_STATUS_SUCCESS;
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05306148 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07006149
6150 ENTER();
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05306151 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6152 if (NULL == pAdapter)
6153 {
6154 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6155 "%s: Adapter is NULL",__func__);
6156 return -EINVAL;
6157 }
6158 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
6159 ret = wlan_hdd_validate_context(pHddCtx);
6160 if (0 != ret)
6161 {
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05306162 return ret;
6163 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006164
6165 memcpy(&pAdapter->macAddressCurrent, psta_mac_addr->sa_data, ETH_ALEN);
Jeff Johnson295189b2012-06-20 16:38:30 -07006166 memcpy(dev->dev_addr, psta_mac_addr->sa_data, ETH_ALEN);
6167
6168 EXIT();
6169 return halStatus;
6170}
6171
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05306172/**---------------------------------------------------------------------------
6173
6174 \brief hdd_set_mac_address() -
6175
6176 Wrapper function to protect __hdd_set_mac_address() function from ssr
6177
6178 \param - dev - Pointer to the net device.
6179 - addr - Pointer to the sockaddr.
6180 \return - 0 for success, non zero for failure
6181
6182 --------------------------------------------------------------------------*/
6183static int hdd_set_mac_address(struct net_device *dev, void *addr)
6184{
6185 int ret;
6186
6187 vos_ssr_protect(__func__);
6188 ret = __hdd_set_mac_address(dev, addr);
6189 vos_ssr_unprotect(__func__);
6190
6191 return ret;
6192}
6193
Jeff Johnson295189b2012-06-20 16:38:30 -07006194tANI_U8* wlan_hdd_get_intf_addr(hdd_context_t* pHddCtx)
6195{
6196 int i;
6197 for ( i = 0; i < VOS_MAX_CONCURRENCY_PERSONA; i++)
6198 {
Abhishek Singheb183782014-02-06 13:37:21 +05306199 if( 0 == ((pHddCtx->cfg_ini->intfAddrMask) & (1 << i)) )
Jeff Johnson295189b2012-06-20 16:38:30 -07006200 break;
6201 }
6202
6203 if( VOS_MAX_CONCURRENCY_PERSONA == i)
6204 return NULL;
6205
6206 pHddCtx->cfg_ini->intfAddrMask |= (1 << i);
6207 return &pHddCtx->cfg_ini->intfMacAddr[i].bytes[0];
6208}
6209
6210void wlan_hdd_release_intf_addr(hdd_context_t* pHddCtx, tANI_U8* releaseAddr)
6211{
6212 int i;
6213 for ( i = 0; i < VOS_MAX_CONCURRENCY_PERSONA; i++)
6214 {
6215 if ( !memcmp(releaseAddr, &pHddCtx->cfg_ini->intfMacAddr[i].bytes[0], 6) )
6216 {
6217 pHddCtx->cfg_ini->intfAddrMask &= ~(1 << i);
6218 break;
6219 }
6220 }
6221 return;
6222}
6223
6224#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29))
6225 static struct net_device_ops wlan_drv_ops = {
6226 .ndo_open = hdd_open,
6227 .ndo_stop = hdd_stop,
6228 .ndo_uninit = hdd_uninit,
6229 .ndo_start_xmit = hdd_hard_start_xmit,
6230 .ndo_tx_timeout = hdd_tx_timeout,
6231 .ndo_get_stats = hdd_stats,
6232 .ndo_do_ioctl = hdd_ioctl,
6233 .ndo_set_mac_address = hdd_set_mac_address,
6234 .ndo_select_queue = hdd_select_queue,
6235#ifdef WLAN_FEATURE_PACKET_FILTERING
6236#if (LINUX_VERSION_CODE > KERNEL_VERSION(3,1,0))
6237 .ndo_set_rx_mode = hdd_set_multicast_list,
6238#else
6239 .ndo_set_multicast_list = hdd_set_multicast_list,
6240#endif //LINUX_VERSION_CODE
6241#endif
6242 };
Jeff Johnson295189b2012-06-20 16:38:30 -07006243 static struct net_device_ops wlan_mon_drv_ops = {
6244 .ndo_open = hdd_mon_open,
Katya Nigame7b69a82015-04-28 15:24:06 +05306245 .ndo_stop = hdd_mon_stop,
Jeff Johnson295189b2012-06-20 16:38:30 -07006246 .ndo_uninit = hdd_uninit,
6247 .ndo_start_xmit = hdd_mon_hard_start_xmit,
6248 .ndo_tx_timeout = hdd_tx_timeout,
6249 .ndo_get_stats = hdd_stats,
Katya Nigame7b69a82015-04-28 15:24:06 +05306250 .ndo_do_ioctl = hdd_mon_ioctl,
Jeff Johnson295189b2012-06-20 16:38:30 -07006251 .ndo_set_mac_address = hdd_set_mac_address,
6252 };
Mahesh A Saptasagar305e2632015-03-04 12:57:33 +05306253
Jeff Johnson295189b2012-06-20 16:38:30 -07006254#endif
6255
6256void hdd_set_station_ops( struct net_device *pWlanDev )
6257{
6258#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29))
Jeff Johnson295189b2012-06-20 16:38:30 -07006259 pWlanDev->netdev_ops = &wlan_drv_ops;
6260#else
6261 pWlanDev->open = hdd_open;
6262 pWlanDev->stop = hdd_stop;
6263 pWlanDev->uninit = hdd_uninit;
6264 pWlanDev->hard_start_xmit = NULL;
6265 pWlanDev->tx_timeout = hdd_tx_timeout;
6266 pWlanDev->get_stats = hdd_stats;
6267 pWlanDev->do_ioctl = hdd_ioctl;
Jeff Johnson295189b2012-06-20 16:38:30 -07006268 pWlanDev->set_mac_address = hdd_set_mac_address;
6269#endif
6270}
6271
Katya Nigam1fd24402015-02-16 14:52:19 +05306272void hdd_set_ibss_ops( hdd_adapter_t *pAdapter )
6273{
6274 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29))
6275 wlan_drv_ops.ndo_start_xmit = hdd_ibss_hard_start_xmit;
6276 #else
6277 pAdapter->dev->hard_start_xmit = hdd_ibss_hard_start_xmit;
6278 #endif
6279}
6280
Jeff Johnsoneed415b2013-01-18 16:11:20 -08006281static hdd_adapter_t* hdd_alloc_station_adapter( hdd_context_t *pHddCtx, tSirMacAddr macAddr, const char* name )
Jeff Johnson295189b2012-06-20 16:38:30 -07006282{
6283 struct net_device *pWlanDev = NULL;
6284 hdd_adapter_t *pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07006285 /*
6286 * cfg80211 initialization and registration....
6287 */
Anand N Sunkadc34abbd2015-07-29 09:52:59 +05306288 pWlanDev = alloc_netdev_mq(sizeof( hdd_adapter_t ), name,
6289#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,17,0))
6290 NET_NAME_UNKNOWN,
6291#endif
6292 ether_setup, NUM_TX_QUEUES);
Jeff Johnson295189b2012-06-20 16:38:30 -07006293 if(pWlanDev != NULL)
6294 {
6295
6296 //Save the pointer to the net_device in the HDD adapter
6297 pAdapter = (hdd_adapter_t*) netdev_priv( pWlanDev );
6298
Jeff Johnson295189b2012-06-20 16:38:30 -07006299 vos_mem_zero( pAdapter, sizeof( hdd_adapter_t ) );
6300
6301 pAdapter->dev = pWlanDev;
6302 pAdapter->pHddCtx = pHddCtx;
6303 pAdapter->magic = WLAN_HDD_ADAPTER_MAGIC;
Agarwal Ashish47d18112014-08-04 19:55:07 +05306304 spin_lock_init(&pAdapter->lock_for_active_session);
Jeff Johnson295189b2012-06-20 16:38:30 -07006305
Rajeev79dbe4c2013-10-05 11:03:42 +05306306#ifdef FEATURE_WLAN_BATCH_SCAN
Rajeev79dbe4c2013-10-05 11:03:42 +05306307 pAdapter->pBatchScanRsp = NULL;
6308 pAdapter->numScanList = 0;
Rajeev Kumar20140c12013-10-21 19:39:02 -07006309 pAdapter->batchScanState = eHDD_BATCH_SCAN_STATE_STOPPED;
Kiet Lamaa8e15a2014-02-11 23:30:06 -08006310 pAdapter->prev_batch_id = 0;
Rajeev79dbe4c2013-10-05 11:03:42 +05306311 mutex_init(&pAdapter->hdd_batch_scan_lock);
6312#endif
6313
Jeff Johnson295189b2012-06-20 16:38:30 -07006314 pAdapter->isLinkUpSvcNeeded = FALSE;
6315 pAdapter->higherDtimTransition = eANI_BOOLEAN_TRUE;
6316 //Init the net_device structure
6317 strlcpy(pWlanDev->name, name, IFNAMSIZ);
6318
6319 vos_mem_copy(pWlanDev->dev_addr, (void *)macAddr, sizeof(tSirMacAddr));
6320 vos_mem_copy( pAdapter->macAddressCurrent.bytes, macAddr, sizeof(tSirMacAddr));
6321 pWlanDev->watchdog_timeo = HDD_TX_TIMEOUT;
6322 pWlanDev->hard_header_len += LIBRA_HW_NEEDED_HEADROOM;
6323
6324 hdd_set_station_ops( pAdapter->dev );
6325
6326 pWlanDev->destructor = free_netdev;
Jeff Johnson295189b2012-06-20 16:38:30 -07006327 pWlanDev->ieee80211_ptr = &pAdapter->wdev ;
6328 pAdapter->wdev.wiphy = pHddCtx->wiphy;
6329 pAdapter->wdev.netdev = pWlanDev;
Jeff Johnson295189b2012-06-20 16:38:30 -07006330 /* set pWlanDev's parent to underlying device */
6331 SET_NETDEV_DEV(pWlanDev, pHddCtx->parent_dev);
Kumar Anand82c009f2014-05-29 00:29:42 -07006332
6333 hdd_wmm_init( pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -07006334 }
6335
6336 return pAdapter;
6337}
6338
6339VOS_STATUS hdd_register_interface( hdd_adapter_t *pAdapter, tANI_U8 rtnl_lock_held )
6340{
6341 struct net_device *pWlanDev = pAdapter->dev;
6342 //hdd_station_ctx_t *pHddStaCtx = &pAdapter->sessionCtx.station;
6343 //hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
6344 //eHalStatus halStatus = eHAL_STATUS_SUCCESS;
6345
6346 if( rtnl_lock_held )
6347 {
Madan Mohan Koyyalamudid8ac8662012-11-06 19:04:56 -08006348 if (strnchr(pWlanDev->name, strlen(pWlanDev->name), '%')) {
Jeff Johnson295189b2012-06-20 16:38:30 -07006349 if( dev_alloc_name(pWlanDev, pWlanDev->name) < 0 )
6350 {
6351 hddLog(VOS_TRACE_LEVEL_ERROR,"%s:Failed:dev_alloc_name",__func__);
6352 return VOS_STATUS_E_FAILURE;
6353 }
6354 }
6355 if (register_netdevice(pWlanDev))
6356 {
6357 hddLog(VOS_TRACE_LEVEL_ERROR,"%s:Failed:register_netdev",__func__);
6358 return VOS_STATUS_E_FAILURE;
6359 }
6360 }
6361 else
6362 {
6363 if(register_netdev(pWlanDev))
6364 {
6365 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Failed:register_netdev",__func__);
6366 return VOS_STATUS_E_FAILURE;
6367 }
6368 }
6369 set_bit(NET_DEVICE_REGISTERED, &pAdapter->event_flags);
6370
6371 return VOS_STATUS_SUCCESS;
6372}
6373
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006374static eHalStatus hdd_smeCloseSessionCallback(void *pContext)
Jeff Johnson295189b2012-06-20 16:38:30 -07006375{
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006376 hdd_adapter_t *pAdapter = pContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07006377
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006378 if (NULL == pAdapter)
6379 {
6380 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: NULL pAdapter", __func__);
6381 return eHAL_STATUS_INVALID_PARAMETER;
Jeff Johnson295189b2012-06-20 16:38:30 -07006382 }
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006383
6384 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
6385 {
6386 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Invalid magic", __func__);
6387 return eHAL_STATUS_NOT_INITIALIZED;
6388 }
6389
6390 clear_bit(SME_SESSION_OPENED, &pAdapter->event_flags);
6391
Sameer Thalappilbee426e2013-10-30 10:30:30 -07006392#ifndef WLAN_OPEN_SOURCE
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006393 /* need to make sure all of our scheduled work has completed.
6394 * This callback is called from MC thread context, so it is safe to
6395 * to call below flush workqueue API from here.
Sameer Thalappilbee426e2013-10-30 10:30:30 -07006396 *
6397 * Even though this is called from MC thread context, if there is a faulty
6398 * work item in the system, that can hang this call forever. So flushing
6399 * this global work queue is not safe; and now we make sure that
6400 * individual work queues are stopped correctly. But the cancel work queue
6401 * is a GPL only API, so the proprietary version of the driver would still
6402 * rely on the global work queue flush.
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006403 */
6404 flush_scheduled_work();
Sameer Thalappilbee426e2013-10-30 10:30:30 -07006405#endif
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006406
6407 /* We can be blocked while waiting for scheduled work to be
6408 * flushed, and the adapter structure can potentially be freed, in
6409 * which case the magic will have been reset. So make sure the
6410 * magic is still good, and hence the adapter structure is still
6411 * valid, before signaling completion */
6412 if (WLAN_HDD_ADAPTER_MAGIC == pAdapter->magic)
6413 {
6414 complete(&pAdapter->session_close_comp_var);
6415 }
6416
Jeff Johnson295189b2012-06-20 16:38:30 -07006417 return eHAL_STATUS_SUCCESS;
6418}
6419
6420VOS_STATUS hdd_init_station_mode( hdd_adapter_t *pAdapter )
6421{
6422 struct net_device *pWlanDev = pAdapter->dev;
6423 hdd_station_ctx_t *pHddStaCtx = &pAdapter->sessionCtx.station;
6424 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
6425 eHalStatus halStatus = eHAL_STATUS_SUCCESS;
6426 VOS_STATUS status = VOS_STATUS_E_FAILURE;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306427 long rc = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07006428
Nirav Shah7e3c8132015-06-22 23:51:42 +05306429 spin_lock_init( &pAdapter->sta_hash_lock);
6430 pAdapter->is_sta_id_hash_initialized = VOS_FALSE;
6431
Jeff Johnson295189b2012-06-20 16:38:30 -07006432 INIT_COMPLETION(pAdapter->session_open_comp_var);
Kiran Kumar Lokere0ad5cd32013-06-25 11:26:22 -07006433 sme_SetCurrDeviceMode(pHddCtx->hHal, pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07006434 //Open a SME session for future operation
6435 halStatus = sme_OpenSession( pHddCtx->hHal, hdd_smeRoamCallback, pAdapter,
Kiran Kumar Lokere0ad5cd32013-06-25 11:26:22 -07006436 (tANI_U8 *)&pAdapter->macAddressCurrent, &pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07006437 if ( !HAL_STATUS_SUCCESS( halStatus ) )
6438 {
6439 hddLog(VOS_TRACE_LEVEL_FATAL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07006440 "sme_OpenSession() failed with status code %08d [x%08x]",
Jeff Johnson295189b2012-06-20 16:38:30 -07006441 halStatus, halStatus );
6442 status = VOS_STATUS_E_FAILURE;
6443 goto error_sme_open;
6444 }
6445
6446 //Block on a completion variable. Can't wait forever though.
Vinay Krishna Eranna0fe2e7c2014-04-09 21:32:08 +05306447 rc = wait_for_completion_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -07006448 &pAdapter->session_open_comp_var,
6449 msecs_to_jiffies(WLAN_WAIT_TIME_SESSIONOPENCLOSE));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306450 if (rc <= 0)
Jeff Johnson295189b2012-06-20 16:38:30 -07006451 {
6452 hddLog(VOS_TRACE_LEVEL_FATAL,
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306453 "Session is not opened within timeout period code %ld", rc );
Jeff Johnson295189b2012-06-20 16:38:30 -07006454 status = VOS_STATUS_E_FAILURE;
6455 goto error_sme_open;
6456 }
6457
6458 // Register wireless extensions
6459 if( eHAL_STATUS_SUCCESS != (halStatus = hdd_register_wext(pWlanDev)))
6460 {
6461 hddLog(VOS_TRACE_LEVEL_FATAL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07006462 "hdd_register_wext() failed with status code %08d [x%08x]",
Jeff Johnson295189b2012-06-20 16:38:30 -07006463 halStatus, halStatus );
6464 status = VOS_STATUS_E_FAILURE;
6465 goto error_register_wext;
6466 }
Katya Nigam1fd24402015-02-16 14:52:19 +05306467
Jeff Johnson295189b2012-06-20 16:38:30 -07006468 //Safe to register the hard_start_xmit function again
Katya Nigam1fd24402015-02-16 14:52:19 +05306469 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29))
6470 wlan_drv_ops.ndo_start_xmit = hdd_hard_start_xmit;
6471 #else
6472 pWlanDev->hard_start_xmit = hdd_hard_start_xmit;
6473 #endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006474
6475 //Set the Connection State to Not Connected
Abhishek Singhf4669da2014-05-26 15:07:49 +05306476 hddLog(VOS_TRACE_LEVEL_INFO,
6477 "%s: Set HDD connState to eConnectionState_NotConnected",
6478 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006479 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
6480
6481 //Set the default operation channel
6482 pHddStaCtx->conn_info.operationChannel = pHddCtx->cfg_ini->OperatingChannel;
6483
6484 /* Make the default Auth Type as OPEN*/
6485 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_OPEN_SYSTEM;
6486
6487 if( VOS_STATUS_SUCCESS != ( status = hdd_init_tx_rx( pAdapter ) ) )
6488 {
6489 hddLog(VOS_TRACE_LEVEL_FATAL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07006490 "hdd_init_tx_rx() failed with status code %08d [x%08x]",
Jeff Johnson295189b2012-06-20 16:38:30 -07006491 status, status );
6492 goto error_init_txrx;
6493 }
6494
6495 set_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
6496
6497 if( VOS_STATUS_SUCCESS != ( status = hdd_wmm_adapter_init( pAdapter ) ) )
6498 {
6499 hddLog(VOS_TRACE_LEVEL_FATAL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07006500 "hdd_wmm_adapter_init() failed with status code %08d [x%08x]",
Jeff Johnson295189b2012-06-20 16:38:30 -07006501 status, status );
6502 goto error_wmm_init;
6503 }
6504
6505 set_bit(WMM_INIT_DONE, &pAdapter->event_flags);
6506
6507 return VOS_STATUS_SUCCESS;
6508
6509error_wmm_init:
6510 clear_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
6511 hdd_deinit_tx_rx(pAdapter);
6512error_init_txrx:
6513 hdd_UnregisterWext(pWlanDev);
6514error_register_wext:
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006515 if (test_bit(SME_SESSION_OPENED, &pAdapter->event_flags))
Jeff Johnson295189b2012-06-20 16:38:30 -07006516 {
6517 INIT_COMPLETION(pAdapter->session_close_comp_var);
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006518 if (eHAL_STATUS_SUCCESS == sme_CloseSession(pHddCtx->hHal,
mukul sharmabab477d2015-06-11 17:14:55 +05306519 pAdapter->sessionId, VOS_TRUE,
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006520 hdd_smeCloseSessionCallback, pAdapter))
Jeff Johnson295189b2012-06-20 16:38:30 -07006521 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306522 unsigned long rc;
6523
Jeff Johnson295189b2012-06-20 16:38:30 -07006524 //Block on a completion variable. Can't wait forever though.
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306525 rc = wait_for_completion_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -07006526 &pAdapter->session_close_comp_var,
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006527 msecs_to_jiffies(WLAN_WAIT_TIME_SESSIONOPENCLOSE));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306528 if (rc <= 0)
6529 hddLog(VOS_TRACE_LEVEL_ERROR,
6530 FL("Session is not opened within timeout period code %ld"), rc);
Jeff Johnson295189b2012-06-20 16:38:30 -07006531 }
6532}
6533error_sme_open:
6534 return status;
6535}
6536
Jeff Johnson295189b2012-06-20 16:38:30 -07006537void hdd_cleanup_actionframe( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter )
6538{
6539 hdd_cfg80211_state_t *cfgState;
6540
6541 cfgState = WLAN_HDD_GET_CFG_STATE_PTR( pAdapter );
6542
6543 if( NULL != cfgState->buf )
6544 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306545 long rc;
Jeff Johnson295189b2012-06-20 16:38:30 -07006546 INIT_COMPLETION(pAdapter->tx_action_cnf_event);
6547 rc = wait_for_completion_interruptible_timeout(
6548 &pAdapter->tx_action_cnf_event,
6549 msecs_to_jiffies(ACTION_FRAME_TX_TIMEOUT));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306550 if (rc <= 0)
Jeff Johnson295189b2012-06-20 16:38:30 -07006551 {
Deepthi Gowri91b3e9c2015-08-25 13:14:58 +05306552 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6553 "%s ERROR: HDD Wait for Action Confirmation Failed!! %ld"
6554 , __func__, rc);
6555
6556 // Inform tx status as FAILURE to upper layer and free cfgState->buf
6557 hdd_sendActionCnf( pAdapter, FALSE );
Jeff Johnson295189b2012-06-20 16:38:30 -07006558 }
6559 }
6560 return;
6561}
Jeff Johnson295189b2012-06-20 16:38:30 -07006562
c_hpothu002231a2015-02-05 14:58:51 +05306563void hdd_deinit_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter, tANI_U8 rtnl_held )
Jeff Johnson295189b2012-06-20 16:38:30 -07006564{
6565 ENTER();
6566 switch ( pAdapter->device_mode )
6567 {
Katya Nigam1fd24402015-02-16 14:52:19 +05306568 case WLAN_HDD_IBSS:
6569 {
6570 if(test_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags))
6571 {
6572 hdd_ibss_deinit_tx_rx( pAdapter );
6573 clear_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
6574 }
6575 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006576 case WLAN_HDD_INFRA_STATION:
6577 case WLAN_HDD_P2P_CLIENT:
Jeff Johnsone7245742012-09-05 17:12:55 -07006578 case WLAN_HDD_P2P_DEVICE:
Jeff Johnson295189b2012-06-20 16:38:30 -07006579 {
6580 if(test_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags))
6581 {
6582 hdd_deinit_tx_rx( pAdapter );
6583 clear_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
6584 }
6585
6586 if(test_bit(WMM_INIT_DONE, &pAdapter->event_flags))
6587 {
6588 hdd_wmm_adapter_close( pAdapter );
6589 clear_bit(WMM_INIT_DONE, &pAdapter->event_flags);
6590 }
6591
Jeff Johnson295189b2012-06-20 16:38:30 -07006592 hdd_cleanup_actionframe(pHddCtx, pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07006593 break;
6594 }
6595
6596 case WLAN_HDD_SOFTAP:
6597 case WLAN_HDD_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07006598 {
Madan Mohan Koyyalamudi8c6dec82013-09-26 15:56:13 +05306599
6600 if (test_bit(WMM_INIT_DONE, &pAdapter->event_flags))
6601 {
6602 hdd_wmm_adapter_close( pAdapter );
6603 clear_bit(WMM_INIT_DONE, &pAdapter->event_flags);
6604 }
6605
Jeff Johnson295189b2012-06-20 16:38:30 -07006606 hdd_cleanup_actionframe(pHddCtx, pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07006607
c_hpothu002231a2015-02-05 14:58:51 +05306608 hdd_unregister_hostapd(pAdapter, rtnl_held);
Jeff Johnson295189b2012-06-20 16:38:30 -07006609 hdd_set_conparam( 0 );
Jeff Johnson295189b2012-06-20 16:38:30 -07006610 break;
6611 }
6612
6613 case WLAN_HDD_MONITOR:
6614 {
Jeff Johnson295189b2012-06-20 16:38:30 -07006615 if(test_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags))
6616 {
6617 hdd_deinit_tx_rx( pAdapter );
6618 clear_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
6619 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006620 break;
6621 }
6622
6623
6624 default:
6625 break;
6626 }
6627
6628 EXIT();
6629}
6630
6631void hdd_cleanup_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter, tANI_U8 rtnl_held )
6632{
Mingcheng Zhu87f22fc2014-01-30 19:23:32 -08006633 struct net_device *pWlanDev = NULL;
Srinivas, Dasari693dfc52013-12-27 17:29:09 +05306634
6635 ENTER();
6636 if (NULL == pAdapter)
6637 {
6638 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6639 "%s: HDD adapter is Null", __func__);
6640 return;
6641 }
6642
6643 pWlanDev = pAdapter->dev;
Jeff Johnson295189b2012-06-20 16:38:30 -07006644
Rajeev79dbe4c2013-10-05 11:03:42 +05306645#ifdef FEATURE_WLAN_BATCH_SCAN
Srinivas, Dasari693dfc52013-12-27 17:29:09 +05306646 if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
6647 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Rajeev Kumarf999e582014-01-09 17:33:29 -08006648 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Srinivas, Dasari693dfc52013-12-27 17:29:09 +05306649 || (pAdapter->device_mode == WLAN_HDD_P2P_DEVICE)
6650 )
6651 {
Rajeev Kumarf999e582014-01-09 17:33:29 -08006652 if (pAdapter)
Rajeev79dbe4c2013-10-05 11:03:42 +05306653 {
Rajeev Kumarf999e582014-01-09 17:33:29 -08006654 if (eHDD_BATCH_SCAN_STATE_STARTED == pAdapter->batchScanState)
6655 {
6656 hdd_deinit_batch_scan(pAdapter);
6657 }
Rajeev79dbe4c2013-10-05 11:03:42 +05306658 }
Rajeev Kumarf999e582014-01-09 17:33:29 -08006659 }
Rajeev79dbe4c2013-10-05 11:03:42 +05306660#endif
6661
Jeff Johnson295189b2012-06-20 16:38:30 -07006662 if(test_bit(NET_DEVICE_REGISTERED, &pAdapter->event_flags)) {
6663 if( rtnl_held )
6664 {
6665 unregister_netdevice(pWlanDev);
6666 }
6667 else
6668 {
6669 unregister_netdev(pWlanDev);
6670 }
6671 // note that the pAdapter is no longer valid at this point
6672 // since the memory has been reclaimed
6673 }
6674
Srinivas, Dasari693dfc52013-12-27 17:29:09 +05306675 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07006676}
6677
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006678void hdd_set_pwrparams(hdd_context_t *pHddCtx)
6679{
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306680 VOS_STATUS status;
6681 hdd_adapter_t *pAdapter = NULL;
6682 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006683
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306684 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006685
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306686 /*loop through all adapters.*/
6687 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006688 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306689 pAdapter = pAdapterNode->pAdapter;
6690 if ( (WLAN_HDD_INFRA_STATION != pAdapter->device_mode)
6691 && (WLAN_HDD_P2P_CLIENT != pAdapter->device_mode) )
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006692
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306693 { // we skip this registration for modes other than STA and P2P client modes.
6694 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
6695 pAdapterNode = pNext;
6696 continue;
6697 }
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006698
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306699 //Apply Dynamic DTIM For P2P
6700 //Only if ignoreDynamicDtimInP2pMode is not set in ini
6701 if ((pHddCtx->cfg_ini->enableDynamicDTIM ||
6702 pHddCtx->cfg_ini->enableModulatedDTIM) &&
6703 ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
6704 ((WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) &&
6705 !(pHddCtx->cfg_ini->ignoreDynamicDtimInP2pMode))) &&
6706 (eANI_BOOLEAN_TRUE == pAdapter->higherDtimTransition) &&
6707 (eConnectionState_Associated ==
6708 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState) &&
6709 (pHddCtx->cfg_ini->fIsBmpsEnabled))
6710 {
6711 tSirSetPowerParamsReq powerRequest = { 0 };
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006712
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306713 powerRequest.uIgnoreDTIM = 1;
6714 powerRequest.uMaxLIModulatedDTIM = pHddCtx->cfg_ini->fMaxLIModulatedDTIM;
6715
6716 if (pHddCtx->cfg_ini->enableModulatedDTIM)
6717 {
6718 powerRequest.uDTIMPeriod = pHddCtx->cfg_ini->enableModulatedDTIM;
6719 powerRequest.uListenInterval = pHddCtx->hdd_actual_LI_value;
6720 }
6721 else
6722 {
6723 powerRequest.uListenInterval = pHddCtx->cfg_ini->enableDynamicDTIM;
6724 }
6725
6726 /* Update ignoreDTIM and ListedInterval in CFG to remain at the DTIM
6727 * specified during Enter/Exit BMPS when LCD off*/
6728 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IGNORE_DTIM, powerRequest.uIgnoreDTIM,
6729 NULL, eANI_BOOLEAN_FALSE);
6730 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_LISTEN_INTERVAL, powerRequest.uListenInterval,
6731 NULL, eANI_BOOLEAN_FALSE);
6732
6733 /* switch to the DTIM specified in cfg.ini */
6734 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Abhishek Singh1e390cf2015-10-27 13:45:17 +05306735 "Switch to DTIM %d Listen interval %d",
6736 powerRequest.uDTIMPeriod,
6737 powerRequest.uListenInterval);
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306738 sme_SetPowerParams( pHddCtx->hHal, &powerRequest, TRUE);
6739 break;
6740
6741 }
6742
6743 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
6744 pAdapterNode = pNext;
6745 }
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006746}
6747
6748void hdd_reset_pwrparams(hdd_context_t *pHddCtx)
6749{
6750 /*Switch back to DTIM 1*/
6751 tSirSetPowerParamsReq powerRequest = { 0 };
6752
6753 powerRequest.uIgnoreDTIM = pHddCtx->hdd_actual_ignore_DTIM_value;
6754 powerRequest.uListenInterval = pHddCtx->hdd_actual_LI_value;
Yue Mac24062f2013-05-13 17:01:29 -07006755 powerRequest.uMaxLIModulatedDTIM = pHddCtx->cfg_ini->fMaxLIModulatedDTIM;
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006756
6757 /* Update ignoreDTIM and ListedInterval in CFG with default values */
6758 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IGNORE_DTIM, powerRequest.uIgnoreDTIM,
6759 NULL, eANI_BOOLEAN_FALSE);
6760 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_LISTEN_INTERVAL, powerRequest.uListenInterval,
6761 NULL, eANI_BOOLEAN_FALSE);
6762
6763 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6764 "Switch to DTIM%d",powerRequest.uListenInterval);
6765 sme_SetPowerParams( pHddCtx->hHal, &powerRequest, TRUE);
6766
6767}
6768
Jeff Johnson295189b2012-06-20 16:38:30 -07006769VOS_STATUS hdd_enable_bmps_imps(hdd_context_t *pHddCtx)
6770{
6771 VOS_STATUS status = VOS_STATUS_SUCCESS;
Sushant Kaushik4928e542014-12-29 15:25:54 +05306772 if (WLAN_HDD_IS_UNLOAD_IN_PROGRESS(pHddCtx))
6773 {
6774 hddLog( LOGE, FL("Wlan Unload in progress"));
6775 return VOS_STATUS_E_PERM;
6776 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006777 if(pHddCtx->cfg_ini->fIsBmpsEnabled)
6778 {
6779 sme_EnablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
6780 }
6781
6782 if(pHddCtx->cfg_ini->fIsAutoBmpsTimerEnabled)
6783 {
6784 sme_StartAutoBmpsTimer(pHddCtx->hHal);
6785 }
6786
6787 if (pHddCtx->cfg_ini->fIsImpsEnabled)
6788 {
6789 sme_EnablePowerSave (pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
6790 }
6791
6792 return status;
6793}
6794
6795VOS_STATUS hdd_disable_bmps_imps(hdd_context_t *pHddCtx, tANI_U8 session_type)
6796{
6797 hdd_adapter_t *pAdapter = NULL;
6798 eHalStatus halStatus;
6799 VOS_STATUS status = VOS_STATUS_E_INVAL;
6800 v_BOOL_t disableBmps = FALSE;
6801 v_BOOL_t disableImps = FALSE;
6802
6803 switch(session_type)
6804 {
6805 case WLAN_HDD_INFRA_STATION:
6806 case WLAN_HDD_SOFTAP:
Jeff Johnson295189b2012-06-20 16:38:30 -07006807 case WLAN_HDD_P2P_CLIENT:
6808 case WLAN_HDD_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07006809 //Exit BMPS -> Is Sta/P2P Client is already connected
6810 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION);
6811 if((NULL != pAdapter)&&
6812 hdd_connIsConnected( WLAN_HDD_GET_STATION_CTX_PTR(pAdapter)))
6813 {
6814 disableBmps = TRUE;
6815 }
6816
6817 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_CLIENT);
6818 if((NULL != pAdapter)&&
6819 hdd_connIsConnected( WLAN_HDD_GET_STATION_CTX_PTR(pAdapter)))
6820 {
6821 disableBmps = TRUE;
6822 }
6823
6824 //Exit both Bmps and Imps incase of Go/SAP Mode
6825 if((WLAN_HDD_SOFTAP == session_type) ||
6826 (WLAN_HDD_P2P_GO == session_type))
6827 {
6828 disableBmps = TRUE;
6829 disableImps = TRUE;
6830 }
6831
6832 if(TRUE == disableImps)
6833 {
6834 if (pHddCtx->cfg_ini->fIsImpsEnabled)
6835 {
6836 sme_DisablePowerSave (pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
6837 }
6838 }
6839
6840 if(TRUE == disableBmps)
6841 {
6842 if(pHddCtx->cfg_ini->fIsBmpsEnabled)
6843 {
6844 halStatus = sme_DisablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
6845
6846 if(eHAL_STATUS_SUCCESS != halStatus)
6847 {
6848 status = VOS_STATUS_E_FAILURE;
Arif Hussain6d2a3322013-11-17 19:50:10 -08006849 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Fail to Disable Power Save", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006850 VOS_ASSERT(0);
6851 return status;
6852 }
6853 }
6854
6855 if(pHddCtx->cfg_ini->fIsAutoBmpsTimerEnabled)
6856 {
6857 halStatus = sme_StopAutoBmpsTimer(pHddCtx->hHal);
6858
6859 if(eHAL_STATUS_SUCCESS != halStatus)
6860 {
6861 status = VOS_STATUS_E_FAILURE;
Arif Hussain6d2a3322013-11-17 19:50:10 -08006862 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Fail to Stop Auto Bmps Timer", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006863 VOS_ASSERT(0);
6864 return status;
6865 }
6866 }
6867 }
6868
6869 if((TRUE == disableBmps) ||
6870 (TRUE == disableImps))
6871 {
6872 /* Now, get the chip into Full Power now */
6873 INIT_COMPLETION(pHddCtx->full_pwr_comp_var);
6874 halStatus = sme_RequestFullPower(pHddCtx->hHal, hdd_full_pwr_cbk,
6875 pHddCtx, eSME_FULL_PWR_NEEDED_BY_HDD);
6876
6877 if(halStatus != eHAL_STATUS_SUCCESS)
6878 {
6879 if(halStatus == eHAL_STATUS_PMC_PENDING)
6880 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306881 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07006882 //Block on a completion variable. Can't wait forever though
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306883 ret = wait_for_completion_interruptible_timeout(
6884 &pHddCtx->full_pwr_comp_var,
6885 msecs_to_jiffies(1000));
6886 if (ret <= 0)
6887 {
6888 hddLog(VOS_TRACE_LEVEL_ERROR,
6889 "%s: wait on full_pwr_comp_var failed %ld",
6890 __func__, ret);
6891 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006892 }
6893 else
6894 {
6895 status = VOS_STATUS_E_FAILURE;
Arif Hussain6d2a3322013-11-17 19:50:10 -08006896 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Request for Full Power failed", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006897 VOS_ASSERT(0);
6898 return status;
6899 }
6900 }
6901
6902 status = VOS_STATUS_SUCCESS;
6903 }
6904
6905 break;
6906 }
6907 return status;
6908}
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +05306909
6910void hdd_monPostMsgCb(tANI_U32 *magic, struct completion *cmpVar)
6911{
6912 if (magic == NULL || cmpVar == NULL) {
6913 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6914 FL("invalid arguments %p %p"), magic, cmpVar);
6915 return;
6916 }
6917 if (*magic != MON_MODE_MSG_MAGIC) {
6918 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6919 FL("maic: %x"), *magic);
6920 return;
6921 }
6922
6923 complete(cmpVar);
6924 return;
6925}
6926
Katya Nigame7b69a82015-04-28 15:24:06 +05306927void hdd_init_mon_mode (hdd_adapter_t *pAdapter)
6928 {
6929 hdd_mon_ctx_t *pMonCtx = NULL;
6930 pMonCtx = WLAN_HDD_GET_MONITOR_CTX_PTR(pAdapter);
6931
6932 pMonCtx->state = 0;
6933 pMonCtx->ChannelNo = 1;
6934 pMonCtx->ChannelBW = 20;
Katya Nigamd7d3a1f2015-06-11 14:04:24 +05306935 pMonCtx->crcCheckEnabled = 1;
6936 pMonCtx->typeSubtypeBitmap = 0xFFFF00000000;
6937 pMonCtx->is80211to803ConReq = 1;
Katya Nigame7b69a82015-04-28 15:24:06 +05306938 pMonCtx->numOfMacFilters = 0;
6939 }
6940
Jeff Johnson295189b2012-06-20 16:38:30 -07006941
6942hdd_adapter_t* hdd_open_adapter( hdd_context_t *pHddCtx, tANI_U8 session_type,
Jeff Johnsoneed415b2013-01-18 16:11:20 -08006943 const char *iface_name, tSirMacAddr macAddr,
Jeff Johnson295189b2012-06-20 16:38:30 -07006944 tANI_U8 rtnl_held )
6945{
6946 hdd_adapter_t *pAdapter = NULL;
6947 hdd_adapter_list_node_t *pHddAdapterNode = NULL;
6948 VOS_STATUS status = VOS_STATUS_E_FAILURE;
6949 VOS_STATUS exitbmpsStatus;
6950
Arif Hussain6d2a3322013-11-17 19:50:10 -08006951 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s iface =%s type = %d",__func__,iface_name,session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07006952
Nirav Shah436658f2014-02-28 17:05:45 +05306953 if(macAddr == NULL)
6954 {
6955 /* Not received valid macAddr */
6956 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6957 "%s:Unable to add virtual intf: Not able to get"
6958 "valid mac address",__func__);
6959 return NULL;
6960 }
6961
Jeff Johnson295189b2012-06-20 16:38:30 -07006962 //Disable BMPS incase of Concurrency
6963 exitbmpsStatus = hdd_disable_bmps_imps(pHddCtx, session_type);
6964
6965 if(VOS_STATUS_E_FAILURE == exitbmpsStatus)
6966 {
6967 //Fail to Exit BMPS
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306968 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Fail to Exit BMPS", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006969 VOS_ASSERT(0);
6970 return NULL;
6971 }
6972
6973 switch(session_type)
6974 {
6975 case WLAN_HDD_INFRA_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -07006976 case WLAN_HDD_P2P_CLIENT:
Jeff Johnsone7245742012-09-05 17:12:55 -07006977 case WLAN_HDD_P2P_DEVICE:
Jeff Johnson295189b2012-06-20 16:38:30 -07006978 {
6979 pAdapter = hdd_alloc_station_adapter( pHddCtx, macAddr, iface_name );
6980
6981 if( NULL == pAdapter )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306982 {
6983 hddLog(VOS_TRACE_LEVEL_FATAL,
6984 FL("failed to allocate adapter for session %d"), session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07006985 return NULL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306986 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006987
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306988#ifdef FEATURE_WLAN_TDLS
6989 /* A Mutex Lock is introduced while changing/initializing the mode to
6990 * protect the concurrent access for the Adapters by TDLS module.
6991 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05306992 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306993#endif
6994
Jeff Johnsone7245742012-09-05 17:12:55 -07006995 pAdapter->wdev.iftype = (session_type == WLAN_HDD_P2P_CLIENT) ?
6996 NL80211_IFTYPE_P2P_CLIENT:
6997 NL80211_IFTYPE_STATION;
Jeff Johnson295189b2012-06-20 16:38:30 -07006998
Jeff Johnson295189b2012-06-20 16:38:30 -07006999 pAdapter->device_mode = session_type;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05307000#ifdef FEATURE_WLAN_TDLS
7001 mutex_unlock(&pHddCtx->tdls_lock);
7002#endif
Sunil Dutt66485cb2013-12-19 19:05:03 +05307003
Mahesh A Saptasagar67ab9222015-10-21 15:38:41 +05307004 hdd_initialize_adapter_common(pAdapter);
Sunil Dutt66485cb2013-12-19 19:05:03 +05307005 status = hdd_init_station_mode( pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -07007006 if( VOS_STATUS_SUCCESS != status )
7007 goto err_free_netdev;
7008
7009 status = hdd_register_interface( pAdapter, rtnl_held );
7010 if( VOS_STATUS_SUCCESS != status )
7011 {
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05307012#ifdef FEATURE_WLAN_TDLS
7013 mutex_lock(&pHddCtx->tdls_lock);
7014#endif
c_hpothu002231a2015-02-05 14:58:51 +05307015 hdd_deinit_adapter(pHddCtx, pAdapter, rtnl_held);
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05307016#ifdef FEATURE_WLAN_TDLS
7017 mutex_unlock(&pHddCtx->tdls_lock);
7018#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007019 goto err_free_netdev;
7020 }
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05307021
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +05307022 // Workqueue which gets scheduled in IPv4 notification callback.
Anand N Sunkaddc63c792015-06-03 14:33:24 +05307023 vos_init_work(&pAdapter->ipv4NotifierWorkQueue, hdd_ipv4_notifier_work_queue);
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +05307024
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05307025#ifdef WLAN_NS_OFFLOAD
7026 // Workqueue which gets scheduled in IPv6 notification callback.
Anand N Sunkaddc63c792015-06-03 14:33:24 +05307027 vos_init_work(&pAdapter->ipv6NotifierWorkQueue, hdd_ipv6_notifier_work_queue);
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05307028#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007029 //Stop the Interface TX queue.
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +05307030 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Jeff Johnson295189b2012-06-20 16:38:30 -07007031 netif_tx_disable(pAdapter->dev);
7032 //netif_tx_disable(pWlanDev);
7033 netif_carrier_off(pAdapter->dev);
7034
Ganesh Kondabattinibabfb492014-12-17 20:25:29 +05307035 if (WLAN_HDD_P2P_CLIENT == session_type ||
7036 WLAN_HDD_P2P_DEVICE == session_type)
7037 {
7038 /* Initialize the work queue to defer the
7039 * back to back RoC request */
Anand N Sunkaddc63c792015-06-03 14:33:24 +05307040 vos_init_delayed_work(&pAdapter->roc_work,
Ganesh Kondabattinibabfb492014-12-17 20:25:29 +05307041 hdd_p2p_roc_work_queue);
7042 }
7043
Jeff Johnson295189b2012-06-20 16:38:30 -07007044 break;
7045 }
7046
Jeff Johnson295189b2012-06-20 16:38:30 -07007047 case WLAN_HDD_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07007048 case WLAN_HDD_SOFTAP:
7049 {
7050 pAdapter = hdd_wlan_create_ap_dev( pHddCtx, macAddr, (tANI_U8 *)iface_name );
7051 if( NULL == pAdapter )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307052 {
7053 hddLog(VOS_TRACE_LEVEL_FATAL,
7054 FL("failed to allocate adapter for session %d"), session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07007055 return NULL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307056 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007057
Jeff Johnson295189b2012-06-20 16:38:30 -07007058 pAdapter->wdev.iftype = (session_type == WLAN_HDD_SOFTAP) ?
7059 NL80211_IFTYPE_AP:
7060 NL80211_IFTYPE_P2P_GO;
Jeff Johnson295189b2012-06-20 16:38:30 -07007061 pAdapter->device_mode = session_type;
7062
Mahesh A Saptasagar67ab9222015-10-21 15:38:41 +05307063 hdd_initialize_adapter_common(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07007064 status = hdd_init_ap_mode(pAdapter);
7065 if( VOS_STATUS_SUCCESS != status )
7066 goto err_free_netdev;
7067
Nirav Shah7e3c8132015-06-22 23:51:42 +05307068 status = hdd_sta_id_hash_attach(pAdapter);
7069 if (VOS_STATUS_SUCCESS != status)
7070 {
7071 hddLog(VOS_TRACE_LEVEL_FATAL,
7072 FL("failed to attach hash for session %d"), session_type);
7073 hdd_deinit_adapter(pHddCtx, pAdapter, rtnl_held);
7074 goto err_free_netdev;
7075 }
7076
Jeff Johnson295189b2012-06-20 16:38:30 -07007077 status = hdd_register_hostapd( pAdapter, rtnl_held );
7078 if( VOS_STATUS_SUCCESS != status )
7079 {
c_hpothu002231a2015-02-05 14:58:51 +05307080 hdd_deinit_adapter(pHddCtx, pAdapter, rtnl_held);
Jeff Johnson295189b2012-06-20 16:38:30 -07007081 goto err_free_netdev;
7082 }
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +05307083 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Jeff Johnson295189b2012-06-20 16:38:30 -07007084 netif_tx_disable(pAdapter->dev);
7085 netif_carrier_off(pAdapter->dev);
7086
7087 hdd_set_conparam( 1 );
Ganesh Kondabattinibabfb492014-12-17 20:25:29 +05307088
7089 if (WLAN_HDD_P2P_GO == session_type)
7090 {
7091 /* Initialize the work queue to
7092 * defer the back to back RoC request */
7093 INIT_DELAYED_WORK(&pAdapter->roc_work,
7094 hdd_p2p_roc_work_queue);
7095 }
Bhargav Shahd0715912015-10-01 18:17:37 +05307096
Jeff Johnson295189b2012-06-20 16:38:30 -07007097 break;
7098 }
7099 case WLAN_HDD_MONITOR:
7100 {
Jeff Johnson295189b2012-06-20 16:38:30 -07007101 pAdapter = hdd_alloc_station_adapter( pHddCtx, macAddr, iface_name );
7102 if( NULL == pAdapter )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307103 {
7104 hddLog(VOS_TRACE_LEVEL_FATAL,
7105 FL("failed to allocate adapter for session %d"), session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07007106 return NULL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307107 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007108
Katya Nigame7b69a82015-04-28 15:24:06 +05307109 // Register wireless extensions
7110 if( VOS_STATUS_SUCCESS != (status = hdd_register_wext(pAdapter->dev)))
7111 {
7112 hddLog(VOS_TRACE_LEVEL_FATAL,
7113 "hdd_register_wext() failed with status code %08d [x%08x]",
7114 status, status );
7115 status = VOS_STATUS_E_FAILURE;
7116 }
7117
Jeff Johnson295189b2012-06-20 16:38:30 -07007118 pAdapter->wdev.iftype = NL80211_IFTYPE_MONITOR;
7119 pAdapter->device_mode = session_type;
Jeff Johnson295189b2012-06-20 16:38:30 -07007120#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29)
7121 pAdapter->dev->netdev_ops = &wlan_mon_drv_ops;
7122#else
7123 pAdapter->dev->open = hdd_mon_open;
7124 pAdapter->dev->hard_start_xmit = hdd_mon_hard_start_xmit;
Katya Nigame7b69a82015-04-28 15:24:06 +05307125 pAdapter->dev->stop = hdd_mon_stop;
7126 pAdapter->dev->do_ioctl = hdd_mon_ioctl;
Jeff Johnson295189b2012-06-20 16:38:30 -07007127#endif
Katya Nigame7b69a82015-04-28 15:24:06 +05307128 status = hdd_register_interface( pAdapter, rtnl_held );
7129 hdd_init_mon_mode( pAdapter );
Mahesh A Saptasagar67ab9222015-10-21 15:38:41 +05307130 hdd_initialize_adapter_common(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07007131 hdd_init_tx_rx( pAdapter );
7132 set_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
Katya Nigame7b69a82015-04-28 15:24:06 +05307133 //Stop the Interface TX queue.
7134 netif_tx_disable(pAdapter->dev);
7135 netif_carrier_off(pAdapter->dev);
Jeff Johnson295189b2012-06-20 16:38:30 -07007136 }
7137 break;
Jeff Johnson295189b2012-06-20 16:38:30 -07007138 case WLAN_HDD_FTM:
7139 {
7140 pAdapter = hdd_alloc_station_adapter( pHddCtx, macAddr, iface_name );
7141
7142 if( NULL == pAdapter )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307143 {
7144 hddLog(VOS_TRACE_LEVEL_FATAL,
7145 FL("failed to allocate adapter for session %d"), session_type);
7146 return NULL;
7147 }
7148
Jeff Johnson295189b2012-06-20 16:38:30 -07007149 /* Assign NL80211_IFTYPE_STATION as interface type to resolve Kernel Warning
7150 * message while loading driver in FTM mode. */
7151 pAdapter->wdev.iftype = NL80211_IFTYPE_STATION;
7152 pAdapter->device_mode = session_type;
7153 status = hdd_register_interface( pAdapter, rtnl_held );
Madan Mohan Koyyalamudif89ac9f2013-09-19 16:58:12 +05307154
Mahesh A Saptasagar67ab9222015-10-21 15:38:41 +05307155 hdd_initialize_adapter_common(pAdapter);
Madan Mohan Koyyalamudif89ac9f2013-09-19 16:58:12 +05307156 hdd_init_tx_rx( pAdapter );
7157
7158 //Stop the Interface TX queue.
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +05307159 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Madan Mohan Koyyalamudif89ac9f2013-09-19 16:58:12 +05307160 netif_tx_disable(pAdapter->dev);
7161 netif_carrier_off(pAdapter->dev);
Jeff Johnson295189b2012-06-20 16:38:30 -07007162 }
7163 break;
Jeff Johnson295189b2012-06-20 16:38:30 -07007164 default:
7165 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307166 hddLog(VOS_TRACE_LEVEL_FATAL,"%s Invalid session type %d",
7167 __func__, session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07007168 VOS_ASSERT(0);
7169 return NULL;
7170 }
7171 }
7172
Jeff Johnson295189b2012-06-20 16:38:30 -07007173 if( VOS_STATUS_SUCCESS == status )
7174 {
Mahesh A Saptasagar67ab9222015-10-21 15:38:41 +05307175 //Add it to the hdd's session list.
Jeff Johnson295189b2012-06-20 16:38:30 -07007176 pHddAdapterNode = vos_mem_malloc( sizeof( hdd_adapter_list_node_t ) );
7177 if( NULL == pHddAdapterNode )
7178 {
7179 status = VOS_STATUS_E_NOMEM;
7180 }
7181 else
7182 {
7183 pHddAdapterNode->pAdapter = pAdapter;
7184 status = hdd_add_adapter_back ( pHddCtx,
7185 pHddAdapterNode );
7186 }
7187 }
7188
7189 if( VOS_STATUS_SUCCESS != status )
7190 {
7191 if( NULL != pAdapter )
7192 {
7193 hdd_cleanup_adapter( pHddCtx, pAdapter, rtnl_held );
7194 pAdapter = NULL;
7195 }
7196 if( NULL != pHddAdapterNode )
7197 {
7198 vos_mem_free( pHddAdapterNode );
7199 }
7200
7201 goto resume_bmps;
7202 }
7203
7204 if(VOS_STATUS_SUCCESS == status)
7205 {
7206 wlan_hdd_set_concurrency_mode(pHddCtx, session_type);
7207
Madan Mohan Koyyalamudi96dd30d2012-10-05 17:24:51 -07007208 //Initialize the WoWL service
7209 if(!hdd_init_wowl(pAdapter))
7210 {
7211 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hdd_init_wowl failed",__func__);
7212 goto err_free_netdev;
7213 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007214 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007215 return pAdapter;
7216
7217err_free_netdev:
7218 free_netdev(pAdapter->dev);
7219 wlan_hdd_release_intf_addr( pHddCtx,
7220 pAdapter->macAddressCurrent.bytes );
7221
7222resume_bmps:
7223 //If bmps disabled enable it
7224 if(VOS_STATUS_SUCCESS == exitbmpsStatus)
7225 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05307226 if (pHddCtx->hdd_wlan_suspended)
7227 {
7228 hdd_set_pwrparams(pHddCtx);
7229 }
7230 hdd_enable_bmps_imps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07007231 }
7232 return NULL;
7233}
7234
7235VOS_STATUS hdd_close_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter,
7236 tANI_U8 rtnl_held )
7237{
7238 hdd_adapter_list_node_t *pAdapterNode, *pCurrent, *pNext;
7239 VOS_STATUS status;
7240
7241 status = hdd_get_front_adapter ( pHddCtx, &pCurrent );
7242 if( VOS_STATUS_SUCCESS != status )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307243 {
7244 hddLog(VOS_TRACE_LEVEL_WARN,"%s: adapter list empty %d",
7245 __func__, status);
Jeff Johnson295189b2012-06-20 16:38:30 -07007246 return status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307247 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007248
7249 while ( pCurrent->pAdapter != pAdapter )
7250 {
7251 status = hdd_get_next_adapter ( pHddCtx, pCurrent, &pNext );
7252 if( VOS_STATUS_SUCCESS != status )
7253 break;
7254
7255 pCurrent = pNext;
7256 }
7257 pAdapterNode = pCurrent;
7258 if( VOS_STATUS_SUCCESS == status )
7259 {
7260 wlan_hdd_clear_concurrency_mode(pHddCtx, pAdapter->device_mode);
7261 hdd_cleanup_adapter( pHddCtx, pAdapterNode->pAdapter, rtnl_held );
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05307262
7263#ifdef FEATURE_WLAN_TDLS
7264
7265 /* A Mutex Lock is introduced while changing/initializing the mode to
7266 * protect the concurrent access for the Adapters by TDLS module.
7267 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05307268 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05307269#endif
7270
Jeff Johnson295189b2012-06-20 16:38:30 -07007271 hdd_remove_adapter( pHddCtx, pAdapterNode );
7272 vos_mem_free( pAdapterNode );
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08007273 pAdapterNode = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07007274
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05307275#ifdef FEATURE_WLAN_TDLS
7276 mutex_unlock(&pHddCtx->tdls_lock);
7277#endif
7278
Jeff Johnson295189b2012-06-20 16:38:30 -07007279
7280 /* If there is a single session of STA/P2P client, re-enable BMPS */
Agarwal Ashish51325b52014-06-16 16:50:49 +05307281 if ((!vos_concurrent_open_sessions_running()) &&
7282 ((pHddCtx->no_of_open_sessions[VOS_STA_MODE] >= 1) ||
7283 (pHddCtx->no_of_open_sessions[VOS_P2P_CLIENT_MODE] >= 1)))
Jeff Johnson295189b2012-06-20 16:38:30 -07007284 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05307285 if (pHddCtx->hdd_wlan_suspended)
7286 {
7287 hdd_set_pwrparams(pHddCtx);
7288 }
7289 hdd_enable_bmps_imps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07007290 }
7291
7292 return VOS_STATUS_SUCCESS;
7293 }
7294
7295 return VOS_STATUS_E_FAILURE;
7296}
7297
7298VOS_STATUS hdd_close_all_adapters( hdd_context_t *pHddCtx )
7299{
7300 hdd_adapter_list_node_t *pHddAdapterNode;
7301 VOS_STATUS status;
7302
7303 ENTER();
7304
7305 do
7306 {
7307 status = hdd_remove_front_adapter( pHddCtx, &pHddAdapterNode );
7308 if( pHddAdapterNode && VOS_STATUS_SUCCESS == status )
7309 {
7310 hdd_cleanup_adapter( pHddCtx, pHddAdapterNode->pAdapter, FALSE );
7311 vos_mem_free( pHddAdapterNode );
7312 }
7313 }while( NULL != pHddAdapterNode && VOS_STATUS_E_EMPTY != status );
7314
7315 EXIT();
7316
7317 return VOS_STATUS_SUCCESS;
7318}
7319
7320void wlan_hdd_reset_prob_rspies(hdd_adapter_t* pHostapdAdapter)
7321{
7322 v_U8_t addIE[1] = {0};
7323
7324 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
7325 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,(tANI_U8*)addIE, 0, NULL,
7326 eANI_BOOLEAN_FALSE) )
7327 {
7328 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007329 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07007330 }
7331
7332 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
7333 WNI_CFG_PROBE_RSP_ADDNIE_DATA2, (tANI_U8*)addIE, 0, NULL,
7334 eANI_BOOLEAN_FALSE) )
7335 {
7336 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007337 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07007338 }
7339
7340 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
7341 WNI_CFG_PROBE_RSP_ADDNIE_DATA3, (tANI_U8*)addIE, 0, NULL,
7342 eANI_BOOLEAN_FALSE) )
7343 {
7344 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007345 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07007346 }
7347}
7348
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05307349VOS_STATUS hdd_stop_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter,
7350 const v_BOOL_t bCloseSession )
Jeff Johnson295189b2012-06-20 16:38:30 -07007351{
7352 eHalStatus halStatus = eHAL_STATUS_SUCCESS;
7353 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Kaushik, Sushant4975a572014-10-21 16:07:48 +05307354 hdd_scaninfo_t *pScanInfo = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07007355 union iwreq_data wrqu;
Kaushik, Sushant7005e372014-04-08 11:36:54 +05307356 v_U8_t retry = 0;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307357 long ret;
Nirav Shah7e3c8132015-06-22 23:51:42 +05307358 VOS_STATUS status;
Jeff Johnson295189b2012-06-20 16:38:30 -07007359
Anand N Sunkad26d71b92014-12-24 18:08:22 +05307360 if (pHddCtx->isLogpInProgress) {
7361 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
7362 "%s:LOGP in Progress. Ignore!!!",__func__);
7363 return VOS_STATUS_E_FAILURE;
7364 }
7365
Jeff Johnson295189b2012-06-20 16:38:30 -07007366 ENTER();
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +05307367
Kaushik, Sushant4975a572014-10-21 16:07:48 +05307368 pScanInfo = &pHddCtx->scan_info;
Jeff Johnson295189b2012-06-20 16:38:30 -07007369 switch(pAdapter->device_mode)
7370 {
Nirav Shah0cf4d892015-11-05 16:27:27 +05307371 case WLAN_HDD_IBSS:
7372 if ( VOS_TRUE == bCloseSession )
7373 {
7374 status = hdd_sta_id_hash_detach(pAdapter);
7375 if (status != VOS_STATUS_SUCCESS)
7376 hddLog(VOS_TRACE_LEVEL_ERROR,
7377 FL("sta id hash detach failed"));
7378 }
7379
Jeff Johnson295189b2012-06-20 16:38:30 -07007380 case WLAN_HDD_INFRA_STATION:
7381 case WLAN_HDD_P2P_CLIENT:
Jeff Johnsone7245742012-09-05 17:12:55 -07007382 case WLAN_HDD_P2P_DEVICE:
Vinay Krishna Erannab09d3e72014-03-26 21:23:55 +05307383 {
7384 hdd_station_ctx_t *pstation = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Mahesh A Saptasagare4d05d42015-07-02 16:17:20 +05307385#ifdef FEATURE_WLAN_TDLS
7386 mutex_lock(&pHddCtx->tdls_lock);
7387 wlan_hdd_tdls_exit(pAdapter, TRUE);
7388 mutex_unlock(&pHddCtx->tdls_lock);
7389#endif
Vinay Krishna Erannab09d3e72014-03-26 21:23:55 +05307390 if( hdd_connIsConnected(pstation) ||
7391 (pstation->conn_info.connState == eConnectionState_Connecting) )
Jeff Johnson295189b2012-06-20 16:38:30 -07007392 {
7393 if (pWextState->roamProfile.BSSType == eCSR_BSS_TYPE_START_IBSS)
7394 halStatus = sme_RoamDisconnect(pHddCtx->hHal,
7395 pAdapter->sessionId,
7396 eCSR_DISCONNECT_REASON_IBSS_LEAVE);
7397 else
7398 halStatus = sme_RoamDisconnect(pHddCtx->hHal,
7399 pAdapter->sessionId,
7400 eCSR_DISCONNECT_REASON_UNSPECIFIED);
Abhishek Singh7b52ed52016-02-11 17:45:54 +05307401 /* Success implies disconnect command got queued up successfully
7402 * Or cmd not queued as scan for SSID is in progress
7403 */
7404 if((eHAL_STATUS_SUCCESS == halStatus) ||
7405 (eHAL_STATUS_CMD_NOT_QUEUED == halStatus))
Jeff Johnson295189b2012-06-20 16:38:30 -07007406 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307407 ret = wait_for_completion_interruptible_timeout(
7408 &pAdapter->disconnect_comp_var,
7409 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
Abhishek Singh7b52ed52016-02-11 17:45:54 +05307410 if (ret <= 0 &&
7411 (eHAL_STATUS_CMD_NOT_QUEUED != halStatus))
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307412 {
7413 hddLog(VOS_TRACE_LEVEL_ERROR,
7414 "%s: wait on disconnect_comp_var failed %ld",
7415 __func__, ret);
7416 }
7417 }
7418 else
7419 {
7420 hddLog(LOGE, "%s: failed to post disconnect event to SME",
7421 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007422 }
7423 memset(&wrqu, '\0', sizeof(wrqu));
7424 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
7425 memset(wrqu.ap_addr.sa_data,'\0',ETH_ALEN);
7426 wireless_send_event(pAdapter->dev, SIOCGIWAP, &wrqu, NULL);
7427 }
Vinay Krishna Erannab09d3e72014-03-26 21:23:55 +05307428 else if(pstation->conn_info.connState ==
7429 eConnectionState_Disconnecting)
7430 {
7431 ret = wait_for_completion_interruptible_timeout(
7432 &pAdapter->disconnect_comp_var,
7433 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
7434 if (ret <= 0)
7435 {
7436 hddLog(VOS_TRACE_LEVEL_ERROR,
7437 FL("wait on disconnect_comp_var failed %ld"), ret);
7438 }
7439 }
Kaushik, Sushant4975a572014-10-21 16:07:48 +05307440 else if(pScanInfo != NULL && pHddCtx->scan_info.mScanPending)
Jeff Johnson295189b2012-06-20 16:38:30 -07007441 {
Mahesh A Saptasagar0b61dcc2016-02-15 14:23:38 +05307442 wlan_hdd_scan_abort(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07007443 }
Abhishek Singh3ac179b2015-09-21 10:01:34 +05307444 if ((pAdapter->device_mode != WLAN_HDD_INFRA_STATION) &&
7445 (pAdapter->device_mode != WLAN_HDD_IBSS))
Kaushik, Sushant7005e372014-04-08 11:36:54 +05307446 {
7447 while (pAdapter->is_roc_inprogress)
7448 {
7449 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7450 "%s: ROC in progress for session %d!!!",
7451 __func__, pAdapter->sessionId);
7452 // waiting for ROC to expire
7453 msleep(500);
7454 /* In GO present case , if retry exceeds 3,
7455 it means something went wrong. */
7456 if ( retry++ > MAX_WAIT_FOR_ROC_COMPLETION )
7457 {
7458 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7459 "%s: ROC completion is not received.!!!", __func__);
Deepthi Gowri70498252015-01-20 15:56:45 +05307460 if (eHAL_STATUS_SUCCESS !=
7461 sme_CancelRemainOnChannel( WLAN_HDD_GET_HAL_CTX( pAdapter),
7462 pAdapter->sessionId ))
7463 {
7464 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7465 FL("Failed to Cancel Remain on Channel"));
7466 }
Kaushik, Sushant7005e372014-04-08 11:36:54 +05307467 wait_for_completion_interruptible_timeout(
7468 &pAdapter->cancel_rem_on_chan_var,
7469 msecs_to_jiffies(WAIT_CANCEL_REM_CHAN));
7470 break;
7471 }
7472 }
Anand N Sunkaddc63c792015-06-03 14:33:24 +05307473 vos_flush_delayed_work(&pAdapter->roc_work);
Kaushik, Sushant7005e372014-04-08 11:36:54 +05307474 }
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05307475#ifdef WLAN_NS_OFFLOAD
Anand N Sunkaddc63c792015-06-03 14:33:24 +05307476 vos_flush_work(&pAdapter->ipv6NotifierWorkQueue);
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05307477#endif
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +05307478
Anand N Sunkaddc63c792015-06-03 14:33:24 +05307479 vos_flush_work(&pAdapter->ipv4NotifierWorkQueue);
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +05307480
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05307481 /* It is possible that the caller of this function does not
7482 * wish to close the session
7483 */
7484 if (VOS_TRUE == bCloseSession &&
7485 test_bit(SME_SESSION_OPENED, &pAdapter->event_flags))
Jeff Johnson295189b2012-06-20 16:38:30 -07007486 {
7487 INIT_COMPLETION(pAdapter->session_close_comp_var);
7488 if (eHAL_STATUS_SUCCESS ==
mukul sharmabab477d2015-06-11 17:14:55 +05307489 sme_CloseSession(pHddCtx->hHal, pAdapter->sessionId, VOS_FALSE,
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05307490 hdd_smeCloseSessionCallback, pAdapter))
Jeff Johnson295189b2012-06-20 16:38:30 -07007491 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307492 unsigned long ret;
7493
Jeff Johnson295189b2012-06-20 16:38:30 -07007494 //Block on a completion variable. Can't wait forever though.
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307495 ret = wait_for_completion_timeout(
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05307496 &pAdapter->session_close_comp_var,
7497 msecs_to_jiffies(WLAN_WAIT_TIME_SESSIONOPENCLOSE));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307498 if ( 0 >= ret)
7499 {
7500 hddLog(LOGE, "%s: failure waiting for session_close_comp_var %ld",
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05307501 __func__, ret);
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307502 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007503 }
7504 }
Vinay Krishna Erannab09d3e72014-03-26 21:23:55 +05307505 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007506 break;
7507
7508 case WLAN_HDD_SOFTAP:
7509 case WLAN_HDD_P2P_GO:
Nirav Shah0cf4d892015-11-05 16:27:27 +05307510 if ( VOS_TRUE == bCloseSession )
7511 {
7512 status = hdd_sta_id_hash_detach(pAdapter);
7513 if (status != VOS_STATUS_SUCCESS)
7514 hddLog(VOS_TRACE_LEVEL_ERROR,
7515 FL("sta id hash detach failed"));
7516 }
7517
Jeff Johnson295189b2012-06-20 16:38:30 -07007518 //Any softap specific cleanup here...
Kaushik, Sushant7005e372014-04-08 11:36:54 +05307519 if (pAdapter->device_mode == WLAN_HDD_P2P_GO) {
7520 while (pAdapter->is_roc_inprogress) {
7521 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7522 "%s: ROC in progress for session %d!!!",
7523 __func__, pAdapter->sessionId);
7524 msleep(500);
7525 if ( retry++ > MAX_WAIT_FOR_ROC_COMPLETION ) {
7526 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7527 "%s: ROC completion is not received.!!!", __func__);
7528 WLANSAP_CancelRemainOnChannel(
7529 (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
7530 wait_for_completion_interruptible_timeout(
7531 &pAdapter->cancel_rem_on_chan_var,
7532 msecs_to_jiffies(WAIT_CANCEL_REM_CHAN));
7533 break;
7534 }
7535 }
Ganesh Kondabattinibabfb492014-12-17 20:25:29 +05307536
Anand N Sunkaddc63c792015-06-03 14:33:24 +05307537 vos_flush_delayed_work(&pAdapter->roc_work);
Kaushik, Sushant7005e372014-04-08 11:36:54 +05307538 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007539 mutex_lock(&pHddCtx->sap_lock);
7540 if (test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
7541 {
7542 VOS_STATUS status;
7543 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7544
7545 //Stop Bss.
7546 status = WLANSAP_StopBss(pHddCtx->pvosContext);
7547 if (VOS_IS_STATUS_SUCCESS(status))
7548 {
7549 hdd_hostapd_state_t *pHostapdState =
7550 WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
7551
7552 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
7553
7554 if (!VOS_IS_STATUS_SUCCESS(status))
7555 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307556 hddLog(LOGE, "%s: failure waiting for WLANSAP_StopBss %d",
7557 __func__, status);
Jeff Johnson295189b2012-06-20 16:38:30 -07007558 }
7559 }
7560 else
7561 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007562 hddLog(LOGE, "%s: failure in WLANSAP_StopBss", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007563 }
7564 clear_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags);
Agarwal Ashish51325b52014-06-16 16:50:49 +05307565 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07007566
7567 if (eHAL_STATUS_FAILURE ==
7568 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG,
7569 0, NULL, eANI_BOOLEAN_FALSE))
7570 {
7571 hddLog(LOGE,
7572 "%s: Failed to set WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007573 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007574 }
7575
7576 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt((WLAN_HDD_GET_CTX(pAdapter))->hHal,
7577 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
7578 eANI_BOOLEAN_FALSE) )
7579 {
7580 hddLog(LOGE,
7581 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
7582 }
7583
7584 // Reset WNI_CFG_PROBE_RSP Flags
7585 wlan_hdd_reset_prob_rspies(pAdapter);
7586 kfree(pAdapter->sessionCtx.ap.beacon);
7587 pAdapter->sessionCtx.ap.beacon = NULL;
7588 }
7589 mutex_unlock(&pHddCtx->sap_lock);
7590 break;
Sameer Thalappilbee426e2013-10-30 10:30:30 -07007591
Jeff Johnson295189b2012-06-20 16:38:30 -07007592 case WLAN_HDD_MONITOR:
7593 break;
Sameer Thalappilbee426e2013-10-30 10:30:30 -07007594
Jeff Johnson295189b2012-06-20 16:38:30 -07007595 default:
7596 break;
7597 }
7598
7599 EXIT();
7600 return VOS_STATUS_SUCCESS;
7601}
7602
7603VOS_STATUS hdd_stop_all_adapters( hdd_context_t *pHddCtx )
7604{
7605 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7606 VOS_STATUS status;
7607 hdd_adapter_t *pAdapter;
7608
7609 ENTER();
7610
7611 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7612
7613 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7614 {
7615 pAdapter = pAdapterNode->pAdapter;
Jeff Johnson295189b2012-06-20 16:38:30 -07007616
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05307617 hdd_stop_adapter( pHddCtx, pAdapter, VOS_TRUE );
Jeff Johnson295189b2012-06-20 16:38:30 -07007618
7619 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7620 pAdapterNode = pNext;
7621 }
7622
7623 EXIT();
7624
7625 return VOS_STATUS_SUCCESS;
7626}
7627
Rajeev Kumarf999e582014-01-09 17:33:29 -08007628
7629#ifdef FEATURE_WLAN_BATCH_SCAN
7630/**---------------------------------------------------------------------------
7631
7632 \brief hdd_deinit_batch_scan () - This function cleans up batch scan data
7633 structures
7634
7635 \param - pAdapter Pointer to HDD adapter
7636
7637 \return - None
7638
7639 --------------------------------------------------------------------------*/
7640void hdd_deinit_batch_scan(hdd_adapter_t *pAdapter)
7641{
7642 tHddBatchScanRsp *pNode;
7643 tHddBatchScanRsp *pPrev;
7644
Siddharth Bhalb3e9b792014-02-24 15:14:16 +05307645 if (NULL == pAdapter)
Rajeev Kumarf999e582014-01-09 17:33:29 -08007646 {
Siddharth Bhalb3e9b792014-02-24 15:14:16 +05307647 hddLog(VOS_TRACE_LEVEL_ERROR,
7648 "%s: Adapter context is Null", __func__);
7649 return;
7650 }
7651
7652 pNode = pAdapter->pBatchScanRsp;
7653 while (pNode)
7654 {
7655 pPrev = pNode;
7656 pNode = pNode->pNext;
7657 vos_mem_free((v_VOID_t * )pPrev);
Rajeev Kumarf999e582014-01-09 17:33:29 -08007658 }
7659
7660 pAdapter->pBatchScanRsp = NULL;
7661 pAdapter->numScanList = 0;
7662 pAdapter->batchScanState = eHDD_BATCH_SCAN_STATE_STOPPED;
7663 pAdapter->prev_batch_id = 0;
7664
7665 return;
7666}
7667#endif
7668
7669
Jeff Johnson295189b2012-06-20 16:38:30 -07007670VOS_STATUS hdd_reset_all_adapters( hdd_context_t *pHddCtx )
7671{
7672 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7673 VOS_STATUS status;
7674 hdd_adapter_t *pAdapter;
7675
7676 ENTER();
7677
7678 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7679
7680 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7681 {
7682 pAdapter = pAdapterNode->pAdapter;
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +05307683 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Jeff Johnson295189b2012-06-20 16:38:30 -07007684 netif_tx_disable(pAdapter->dev);
7685 netif_carrier_off(pAdapter->dev);
7686
Srinivas Girigowda66c05eb2013-07-14 13:06:01 -07007687 pAdapter->sessionCtx.station.hdd_ReassocScenario = VOS_FALSE;
7688
Jeff Johnson295189b2012-06-20 16:38:30 -07007689 hdd_deinit_tx_rx(pAdapter);
Agarwal Ashish6267caa2014-08-06 19:16:21 +05307690
Katya Nigam1fd24402015-02-16 14:52:19 +05307691 if(pAdapter->device_mode == WLAN_HDD_IBSS )
7692 hdd_ibss_deinit_tx_rx(pAdapter);
7693
Nirav Shah7e3c8132015-06-22 23:51:42 +05307694 status = hdd_sta_id_hash_detach(pAdapter);
7695 if (status != VOS_STATUS_SUCCESS)
7696 hddLog(VOS_TRACE_LEVEL_ERROR,
7697 FL("sta id hash detach failed for session id %d"),
7698 pAdapter->sessionId);
7699
Agarwal Ashish6267caa2014-08-06 19:16:21 +05307700 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
7701
Madan Mohan Koyyalamudi8c6dec82013-09-26 15:56:13 +05307702 if (test_bit(WMM_INIT_DONE, &pAdapter->event_flags))
7703 {
7704 hdd_wmm_adapter_close( pAdapter );
7705 clear_bit(WMM_INIT_DONE, &pAdapter->event_flags);
7706 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007707
Siddharth Bhal2db319d2014-12-03 12:37:18 +05307708 if (test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
7709 {
7710 clear_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags);
7711 }
7712
Rajeev Kumarf999e582014-01-09 17:33:29 -08007713#ifdef FEATURE_WLAN_BATCH_SCAN
7714 if (eHDD_BATCH_SCAN_STATE_STARTED == pAdapter->batchScanState)
7715 {
7716 hdd_deinit_batch_scan(pAdapter);
7717 }
7718#endif
7719
Mahesh A Saptasagarf5b8eff2015-01-31 01:07:07 +05307720#ifdef FEATURE_WLAN_TDLS
7721 mutex_lock(&pHddCtx->tdls_lock);
Pradeep Reddy POTTETI2d4d5c42015-03-03 14:34:19 +05307722 wlan_hdd_tdls_exit(pAdapter, TRUE);
Mahesh A Saptasagarf5b8eff2015-01-31 01:07:07 +05307723 mutex_unlock(&pHddCtx->tdls_lock);
7724#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007725 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7726 pAdapterNode = pNext;
7727 }
7728
7729 EXIT();
7730
7731 return VOS_STATUS_SUCCESS;
7732}
7733
7734VOS_STATUS hdd_start_all_adapters( hdd_context_t *pHddCtx )
7735{
7736 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7737 VOS_STATUS status;
7738 hdd_adapter_t *pAdapter;
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05307739 eConnectionState connState;
Jeff Johnson295189b2012-06-20 16:38:30 -07007740
7741 ENTER();
7742
7743 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7744
7745 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7746 {
7747 pAdapter = pAdapterNode->pAdapter;
7748
Kumar Anand82c009f2014-05-29 00:29:42 -07007749 hdd_wmm_init( pAdapter );
7750
Jeff Johnson295189b2012-06-20 16:38:30 -07007751 switch(pAdapter->device_mode)
7752 {
7753 case WLAN_HDD_INFRA_STATION:
7754 case WLAN_HDD_P2P_CLIENT:
Jeff Johnsone7245742012-09-05 17:12:55 -07007755 case WLAN_HDD_P2P_DEVICE:
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05307756
7757 connState = (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState;
7758
Jeff Johnson295189b2012-06-20 16:38:30 -07007759 hdd_init_station_mode(pAdapter);
7760 /* Open the gates for HDD to receive Wext commands */
7761 pAdapter->isLinkUpSvcNeeded = FALSE;
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07007762 pHddCtx->scan_info.mScanPending = FALSE;
7763 pHddCtx->scan_info.waitScanResult = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07007764
7765 //Trigger the initial scan
Mukul Sharmae74e42c2015-08-06 23:55:49 +05307766 if (!pHddCtx->isLogpInProgress)
7767 hdd_wlan_initial_scan(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07007768
7769 //Indicate disconnect event to supplicant if associated previously
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05307770 if (eConnectionState_Associated == connState ||
7771 eConnectionState_IbssConnected == connState )
Jeff Johnson295189b2012-06-20 16:38:30 -07007772 {
7773 union iwreq_data wrqu;
7774 memset(&wrqu, '\0', sizeof(wrqu));
7775 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
7776 memset(wrqu.ap_addr.sa_data,'\0',ETH_ALEN);
7777 wireless_send_event(pAdapter->dev, SIOCGIWAP, &wrqu, NULL);
Srinivas Girigowda66c05eb2013-07-14 13:06:01 -07007778 pAdapter->sessionCtx.station.hdd_ReassocScenario = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07007779
Jeff Johnson295189b2012-06-20 16:38:30 -07007780 /* indicate disconnected event to nl80211 */
7781 cfg80211_disconnected(pAdapter->dev, WLAN_REASON_UNSPECIFIED,
7782 NULL, 0, GFP_KERNEL);
Jeff Johnson295189b2012-06-20 16:38:30 -07007783 }
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05307784 else if (eConnectionState_Connecting == connState)
7785 {
7786 /*
7787 * Indicate connect failure to supplicant if we were in the
7788 * process of connecting
7789 */
7790 cfg80211_connect_result(pAdapter->dev, NULL,
7791 NULL, 0, NULL, 0,
7792 WLAN_STATUS_ASSOC_DENIED_UNSPEC,
7793 GFP_KERNEL);
7794 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007795 break;
7796
7797 case WLAN_HDD_SOFTAP:
7798 /* softAP can handle SSR */
7799 break;
7800
7801 case WLAN_HDD_P2P_GO:
Sameer Thalappiledf0d792013-08-09 14:31:03 -07007802 hddLog(VOS_TRACE_LEVEL_ERROR, "%s [SSR] send stop ap to supplicant",
Jeff Johnson295189b2012-06-20 16:38:30 -07007803 __func__);
Sameer Thalappiledf0d792013-08-09 14:31:03 -07007804 cfg80211_ap_stopped(pAdapter->dev, GFP_KERNEL);
Jeff Johnson295189b2012-06-20 16:38:30 -07007805 break;
7806
7807 case WLAN_HDD_MONITOR:
7808 /* monitor interface start */
7809 break;
7810 default:
7811 break;
7812 }
7813
7814 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7815 pAdapterNode = pNext;
7816 }
7817
7818 EXIT();
7819
7820 return VOS_STATUS_SUCCESS;
7821}
7822
7823VOS_STATUS hdd_reconnect_all_adapters( hdd_context_t *pHddCtx )
7824{
7825 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7826 hdd_adapter_t *pAdapter;
7827 VOS_STATUS status;
7828 v_U32_t roamId;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307829 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07007830
7831 ENTER();
7832
7833 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7834
7835 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7836 {
7837 pAdapter = pAdapterNode->pAdapter;
7838
7839 if( (WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
7840 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
7841 {
7842 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7843 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
7844
Abhishek Singhf4669da2014-05-26 15:07:49 +05307845 hddLog(VOS_TRACE_LEVEL_INFO,
7846 "%s: Set HDD connState to eConnectionState_NotConnected",
7847 __func__);
Ganesh Kondabattini04338412015-09-14 15:39:09 +05307848 spin_lock_bh(&pAdapter->lock_for_active_session);
7849 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState)
7850 {
7851 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
7852 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007853 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
Ganesh Kondabattini04338412015-09-14 15:39:09 +05307854 spin_unlock_bh(&pAdapter->lock_for_active_session);
Jeff Johnson295189b2012-06-20 16:38:30 -07007855 init_completion(&pAdapter->disconnect_comp_var);
7856 sme_RoamDisconnect(pHddCtx->hHal, pAdapter->sessionId,
7857 eCSR_DISCONNECT_REASON_UNSPECIFIED);
7858
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307859 ret = wait_for_completion_interruptible_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -07007860 &pAdapter->disconnect_comp_var,
7861 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307862 if (0 >= ret)
7863 hddLog(LOGE, "%s: failure waiting for disconnect_comp_var %ld",
7864 __func__, ret);
Jeff Johnson295189b2012-06-20 16:38:30 -07007865
7866 pWextState->roamProfile.csrPersona = pAdapter->device_mode;
7867 pHddCtx->isAmpAllowed = VOS_FALSE;
7868 sme_RoamConnect(pHddCtx->hHal,
7869 pAdapter->sessionId, &(pWextState->roamProfile),
7870 &roamId);
7871 }
7872
7873 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7874 pAdapterNode = pNext;
7875 }
7876
7877 EXIT();
7878
7879 return VOS_STATUS_SUCCESS;
7880}
7881
Sudhir Sattayappa Kohalli90e4c752013-03-21 14:25:04 -07007882void hdd_dump_concurrency_info(hdd_context_t *pHddCtx)
7883{
7884 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7885 VOS_STATUS status;
7886 hdd_adapter_t *pAdapter;
7887 hdd_station_ctx_t *pHddStaCtx;
7888 hdd_ap_ctx_t *pHddApCtx;
7889 hdd_hostapd_state_t * pHostapdState;
7890 tCsrBssid staBssid = { 0 }, p2pBssid = { 0 }, apBssid = { 0 };
7891 v_U8_t staChannel = 0, p2pChannel = 0, apChannel = 0;
7892 const char *p2pMode = "DEV";
7893 const char *ccMode = "Standalone";
Sudhir Sattayappa Kohalli90e4c752013-03-21 14:25:04 -07007894
7895 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7896 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7897 {
7898 pAdapter = pAdapterNode->pAdapter;
7899 switch (pAdapter->device_mode) {
7900 case WLAN_HDD_INFRA_STATION:
7901 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7902 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState) {
7903 staChannel = pHddStaCtx->conn_info.operationChannel;
7904 memcpy(staBssid, pHddStaCtx->conn_info.bssId, sizeof(staBssid));
7905 }
7906 break;
7907 case WLAN_HDD_P2P_CLIENT:
7908 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7909 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState) {
7910 p2pChannel = pHddStaCtx->conn_info.operationChannel;
7911 memcpy(p2pBssid, pHddStaCtx->conn_info.bssId, sizeof(p2pBssid));
7912 p2pMode = "CLI";
7913 }
7914 break;
7915 case WLAN_HDD_P2P_GO:
7916 pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
7917 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
7918 if (pHostapdState->bssState == BSS_START && pHostapdState->vosStatus==VOS_STATUS_SUCCESS) {
7919 p2pChannel = pHddApCtx->operatingChannel;
7920 memcpy(p2pBssid, pAdapter->macAddressCurrent.bytes, sizeof(p2pBssid));
7921 }
7922 p2pMode = "GO";
7923 break;
7924 case WLAN_HDD_SOFTAP:
7925 pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
7926 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
7927 if (pHostapdState->bssState == BSS_START && pHostapdState->vosStatus==VOS_STATUS_SUCCESS) {
7928 apChannel = pHddApCtx->operatingChannel;
7929 memcpy(apBssid, pAdapter->macAddressCurrent.bytes, sizeof(apBssid));
7930 }
7931 break;
7932 default:
7933 break;
7934 }
7935 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7936 pAdapterNode = pNext;
7937 }
7938 if (staChannel > 0 && (apChannel > 0 || p2pChannel > 0)) {
7939 ccMode = (p2pChannel==staChannel||apChannel==staChannel) ? "SCC" : "MCC";
7940 }
Sushant Kaushikdc3184b2015-10-09 12:00:21 +05307941 hddLog(VOS_TRACE_LEVEL_ERROR, "wlan(%d) " MAC_ADDRESS_STR " %s",
Sudhir Sattayappa Kohalli90e4c752013-03-21 14:25:04 -07007942 staChannel, MAC_ADDR_ARRAY(staBssid), ccMode);
7943 if (p2pChannel > 0) {
Sushant Kaushikdc3184b2015-10-09 12:00:21 +05307944 hddLog(VOS_TRACE_LEVEL_ERROR, "p2p-%s(%d) " MAC_ADDRESS_STR,
Sudhir Sattayappa Kohalli90e4c752013-03-21 14:25:04 -07007945 p2pMode, p2pChannel, MAC_ADDR_ARRAY(p2pBssid));
7946 }
7947 if (apChannel > 0) {
Sushant Kaushikdc3184b2015-10-09 12:00:21 +05307948 hddLog(VOS_TRACE_LEVEL_ERROR, "AP(%d) " MAC_ADDRESS_STR,
Sudhir Sattayappa Kohalli90e4c752013-03-21 14:25:04 -07007949 apChannel, MAC_ADDR_ARRAY(apBssid));
7950 }
7951
7952 if (p2pChannel > 0 && apChannel > 0) {
7953 hddLog(VOS_TRACE_LEVEL_ERROR, "Error concurrent SAP %d and P2P %d which is not support", apChannel, p2pChannel);
7954 }
7955}
7956
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -07007957bool hdd_is_ssr_required( void)
Jeff Johnson295189b2012-06-20 16:38:30 -07007958{
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -07007959 return (isSsrRequired == HDD_SSR_REQUIRED);
Jeff Johnson295189b2012-06-20 16:38:30 -07007960}
7961
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -07007962/* Once SSR is disabled then it cannot be set. */
7963void hdd_set_ssr_required( e_hdd_ssr_required value)
Jeff Johnson295189b2012-06-20 16:38:30 -07007964{
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -07007965 if (HDD_SSR_DISABLED == isSsrRequired)
7966 return;
7967
Jeff Johnson295189b2012-06-20 16:38:30 -07007968 isSsrRequired = value;
7969}
7970
Hema Aparna Medicharla6b4d4f32015-06-23 04:09:12 +05307971void hdd_set_pre_close( hdd_context_t *pHddCtx)
7972{
7973 sme_PreClose(pHddCtx->hHal);
7974}
7975
Jeff Johnson295189b2012-06-20 16:38:30 -07007976VOS_STATUS hdd_get_front_adapter( hdd_context_t *pHddCtx,
7977 hdd_adapter_list_node_t** ppAdapterNode)
7978{
7979 VOS_STATUS status;
Mukul Sharmaae1266d2015-06-26 15:29:53 +05307980 spin_lock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07007981 status = hdd_list_peek_front ( &pHddCtx->hddAdapters,
7982 (hdd_list_node_t**) ppAdapterNode );
Mukul Sharmaae1266d2015-06-26 15:29:53 +05307983 spin_unlock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07007984 return status;
7985}
7986
7987VOS_STATUS hdd_get_next_adapter( hdd_context_t *pHddCtx,
7988 hdd_adapter_list_node_t* pAdapterNode,
7989 hdd_adapter_list_node_t** pNextAdapterNode)
7990{
7991 VOS_STATUS status;
Mukul Sharmaae1266d2015-06-26 15:29:53 +05307992 spin_lock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07007993 status = hdd_list_peek_next ( &pHddCtx->hddAdapters,
7994 (hdd_list_node_t*) pAdapterNode,
7995 (hdd_list_node_t**)pNextAdapterNode );
7996
Mukul Sharmaae1266d2015-06-26 15:29:53 +05307997 spin_unlock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07007998 return status;
7999}
8000
8001VOS_STATUS hdd_remove_adapter( hdd_context_t *pHddCtx,
8002 hdd_adapter_list_node_t* pAdapterNode)
8003{
8004 VOS_STATUS status;
Mukul Sharmaae1266d2015-06-26 15:29:53 +05308005 spin_lock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07008006 status = hdd_list_remove_node ( &pHddCtx->hddAdapters,
8007 &pAdapterNode->node );
Mukul Sharmaae1266d2015-06-26 15:29:53 +05308008 spin_unlock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07008009 return status;
8010}
8011
8012VOS_STATUS hdd_remove_front_adapter( hdd_context_t *pHddCtx,
8013 hdd_adapter_list_node_t** ppAdapterNode)
8014{
8015 VOS_STATUS status;
Mukul Sharmaae1266d2015-06-26 15:29:53 +05308016 spin_lock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07008017 status = hdd_list_remove_front( &pHddCtx->hddAdapters,
8018 (hdd_list_node_t**) ppAdapterNode );
Mukul Sharmaae1266d2015-06-26 15:29:53 +05308019 spin_unlock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07008020 return status;
8021}
8022
8023VOS_STATUS hdd_add_adapter_back( hdd_context_t *pHddCtx,
8024 hdd_adapter_list_node_t* pAdapterNode)
8025{
8026 VOS_STATUS status;
Mukul Sharmaae1266d2015-06-26 15:29:53 +05308027 spin_lock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07008028 status = hdd_list_insert_back ( &pHddCtx->hddAdapters,
8029 (hdd_list_node_t*) pAdapterNode );
Mukul Sharmaae1266d2015-06-26 15:29:53 +05308030 spin_unlock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07008031 return status;
8032}
8033
8034VOS_STATUS hdd_add_adapter_front( hdd_context_t *pHddCtx,
8035 hdd_adapter_list_node_t* pAdapterNode)
8036{
8037 VOS_STATUS status;
Mukul Sharmaae1266d2015-06-26 15:29:53 +05308038 spin_lock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07008039 status = hdd_list_insert_front ( &pHddCtx->hddAdapters,
8040 (hdd_list_node_t*) pAdapterNode );
Mukul Sharmaae1266d2015-06-26 15:29:53 +05308041 spin_unlock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07008042 return status;
8043}
8044
8045hdd_adapter_t * hdd_get_adapter_by_macaddr( hdd_context_t *pHddCtx,
8046 tSirMacAddr macAddr )
8047{
8048 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
8049 hdd_adapter_t *pAdapter;
8050 VOS_STATUS status;
8051
8052 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
8053
8054 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
8055 {
8056 pAdapter = pAdapterNode->pAdapter;
8057
8058 if( pAdapter && vos_mem_compare( pAdapter->macAddressCurrent.bytes,
8059 macAddr, sizeof(tSirMacAddr) ) )
8060 {
8061 return pAdapter;
8062 }
8063 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
8064 pAdapterNode = pNext;
8065 }
8066
8067 return NULL;
8068
8069}
8070
8071hdd_adapter_t * hdd_get_adapter_by_name( hdd_context_t *pHddCtx, tANI_U8 *name )
8072{
8073 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
8074 hdd_adapter_t *pAdapter;
8075 VOS_STATUS status;
8076
8077 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
8078
8079 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
8080 {
8081 pAdapter = pAdapterNode->pAdapter;
8082
8083 if( pAdapter && !strncmp( pAdapter->dev->name, (const char *)name,
8084 IFNAMSIZ ) )
8085 {
8086 return pAdapter;
8087 }
8088 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
8089 pAdapterNode = pNext;
8090 }
8091
8092 return NULL;
8093
8094}
8095
Ganesh Kondabattinicbfdc392015-09-11 19:12:59 +05308096hdd_adapter_t *hdd_get_adapter_by_sme_session_id( hdd_context_t *pHddCtx,
8097 tANI_U32 sme_session_id )
8098{
8099 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
8100 hdd_adapter_t *pAdapter;
8101 VOS_STATUS vos_status;
8102
8103
8104 vos_status = hdd_get_front_adapter( pHddCtx, &pAdapterNode);
8105
8106 while ((NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == vos_status))
8107 {
8108 pAdapter = pAdapterNode->pAdapter;
8109
8110 if (pAdapter->sessionId == sme_session_id)
8111 return pAdapter;
8112
8113 vos_status = hdd_get_next_adapter(pHddCtx, pAdapterNode, &pNext);
8114 pAdapterNode = pNext;
8115 }
8116
8117 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8118 "%s: sme_session_id %d does not exist with host",
8119 __func__, sme_session_id);
8120
8121 return NULL;
8122}
8123
Jeff Johnson295189b2012-06-20 16:38:30 -07008124hdd_adapter_t * hdd_get_adapter( hdd_context_t *pHddCtx, device_mode_t mode )
8125{
8126 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
8127 hdd_adapter_t *pAdapter;
8128 VOS_STATUS status;
8129
8130 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
8131
8132 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
8133 {
8134 pAdapter = pAdapterNode->pAdapter;
8135
8136 if( pAdapter && (mode == pAdapter->device_mode) )
8137 {
8138 return pAdapter;
8139 }
8140 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
8141 pAdapterNode = pNext;
8142 }
8143
8144 return NULL;
8145
8146}
8147
8148//Remove this function later
8149hdd_adapter_t * hdd_get_mon_adapter( hdd_context_t *pHddCtx )
8150{
8151 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
8152 hdd_adapter_t *pAdapter;
8153 VOS_STATUS status;
8154
8155 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
8156
8157 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
8158 {
8159 pAdapter = pAdapterNode->pAdapter;
8160
8161 if( pAdapter && WLAN_HDD_MONITOR == pAdapter->device_mode )
8162 {
8163 return pAdapter;
8164 }
8165
8166 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
8167 pAdapterNode = pNext;
8168 }
8169
8170 return NULL;
8171
8172}
8173
Jeff Johnson295189b2012-06-20 16:38:30 -07008174/**---------------------------------------------------------------------------
8175
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05308176 \brief hdd_get_operating_channel() -
Jeff Johnson295189b2012-06-20 16:38:30 -07008177
8178 This API returns the operating channel of the requested device mode
8179
8180 \param - pHddCtx - Pointer to the HDD context.
8181 - mode - Device mode for which operating channel is required
8182 suported modes - WLAN_HDD_INFRA_STATION, WLAN_HDD_P2P_CLIENT
8183 WLAN_HDD_SOFTAP, WLAN_HDD_P2P_GO.
8184 \return - channel number. "0" id the requested device is not found OR it is not connected.
8185 --------------------------------------------------------------------------*/
8186v_U8_t hdd_get_operating_channel( hdd_context_t *pHddCtx, device_mode_t mode )
8187{
8188 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
8189 VOS_STATUS status;
8190 hdd_adapter_t *pAdapter;
8191 v_U8_t operatingChannel = 0;
8192
8193 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
8194
8195 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
8196 {
8197 pAdapter = pAdapterNode->pAdapter;
8198
8199 if( mode == pAdapter->device_mode )
8200 {
8201 switch(pAdapter->device_mode)
8202 {
8203 case WLAN_HDD_INFRA_STATION:
8204 case WLAN_HDD_P2P_CLIENT:
8205 if( hdd_connIsConnected( WLAN_HDD_GET_STATION_CTX_PTR( pAdapter )) )
8206 operatingChannel = (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.operationChannel;
8207 break;
8208 case WLAN_HDD_SOFTAP:
8209 case WLAN_HDD_P2P_GO:
8210 /*softap connection info */
8211 if(test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
8212 operatingChannel = (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->operatingChannel;
8213 break;
8214 default:
8215 break;
8216 }
8217
8218 break; //Found the device of interest. break the loop
8219 }
8220
8221 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
8222 pAdapterNode = pNext;
8223 }
8224 return operatingChannel;
8225}
8226
8227#ifdef WLAN_FEATURE_PACKET_FILTERING
8228/**---------------------------------------------------------------------------
8229
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05308230 \brief __hdd_set_multicast_list() -
Jeff Johnson295189b2012-06-20 16:38:30 -07008231
8232 This used to set the multicast address list.
8233
8234 \param - dev - Pointer to the WLAN device.
8235 - skb - Pointer to OS packet (sk_buff).
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05308236 \return - success/fail
Jeff Johnson295189b2012-06-20 16:38:30 -07008237
8238 --------------------------------------------------------------------------*/
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05308239static void __hdd_set_multicast_list(struct net_device *dev)
Jeff Johnson295189b2012-06-20 16:38:30 -07008240{
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05308241 hdd_adapter_t *pAdapter;
8242 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07008243 int mc_count;
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05308244 int i = 0, ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07008245 struct netdev_hw_addr *ha;
Gopichand Nakkala0f276812013-02-24 14:45:51 +05308246
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05308247 ENTER();
8248
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05308249 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkala0f276812013-02-24 14:45:51 +05308250 if (NULL == pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07008251 {
8252 hddLog(VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala0f276812013-02-24 14:45:51 +05308253 "%s: Adapter context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07008254 return;
8255 }
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05308256 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8257 ret = wlan_hdd_validate_context(pHddCtx);
8258 if (0 != ret)
8259 {
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05308260 return;
8261 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008262 if (dev->flags & IFF_ALLMULTI)
8263 {
8264 hddLog(VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008265 "%s: allow all multicast frames", __func__);
Gopichand Nakkala0f276812013-02-24 14:45:51 +05308266 pAdapter->mc_addr_list.mc_cnt = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07008267 }
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05308268 else
Jeff Johnson295189b2012-06-20 16:38:30 -07008269 {
8270 mc_count = netdev_mc_count(dev);
8271 hddLog(VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008272 "%s: mc_count = %u", __func__, mc_count);
Jeff Johnson295189b2012-06-20 16:38:30 -07008273 if (mc_count > WLAN_HDD_MAX_MC_ADDR_LIST)
8274 {
8275 hddLog(VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008276 "%s: No free filter available; allow all multicast frames", __func__);
Gopichand Nakkala0f276812013-02-24 14:45:51 +05308277 pAdapter->mc_addr_list.mc_cnt = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07008278 return;
8279 }
8280
Gopichand Nakkala0f276812013-02-24 14:45:51 +05308281 pAdapter->mc_addr_list.mc_cnt = mc_count;
Jeff Johnson295189b2012-06-20 16:38:30 -07008282
8283 netdev_for_each_mc_addr(ha, dev) {
8284 if (i == mc_count)
8285 break;
Gopichand Nakkala0f276812013-02-24 14:45:51 +05308286 memset(&(pAdapter->mc_addr_list.addr[i][0]), 0, ETH_ALEN);
8287 memcpy(&(pAdapter->mc_addr_list.addr[i][0]), ha->addr, ETH_ALEN);
Arif Hussain6d2a3322013-11-17 19:50:10 -08008288 hddLog(VOS_TRACE_LEVEL_INFO, "%s: mlist[%d] = "MAC_ADDRESS_STR,
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05308289 __func__, i,
Gopichand Nakkala0f276812013-02-24 14:45:51 +05308290 MAC_ADDR_ARRAY(pAdapter->mc_addr_list.addr[i]));
Jeff Johnson295189b2012-06-20 16:38:30 -07008291 i++;
8292 }
8293 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05308294
Ganesh Kondabattinifb37e652015-10-09 15:46:47 +05308295 if (pHddCtx->hdd_wlan_suspended)
8296 {
8297 /*
8298 * Configure the Mcast address list to FW
8299 * If wlan is already in suspend mode
8300 */
8301 wlan_hdd_set_mc_addr_list(pAdapter, TRUE);
8302 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05308303 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07008304 return;
8305}
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05308306
8307static void hdd_set_multicast_list(struct net_device *dev)
8308{
8309 vos_ssr_protect(__func__);
8310 __hdd_set_multicast_list(dev);
8311 vos_ssr_unprotect(__func__);
8312}
Jeff Johnson295189b2012-06-20 16:38:30 -07008313#endif
8314
8315/**---------------------------------------------------------------------------
8316
8317 \brief hdd_select_queue() -
8318
8319 This function is registered with the Linux OS for network
8320 core to decide which queue to use first.
8321
8322 \param - dev - Pointer to the WLAN device.
8323 - skb - Pointer to OS packet (sk_buff).
8324 \return - ac, Queue Index/access category corresponding to UP in IP header
8325
8326 --------------------------------------------------------------------------*/
8327v_U16_t hdd_select_queue(struct net_device *dev,
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05308328 struct sk_buff *skb
8329#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,13,0))
8330 , void *accel_priv
8331#endif
8332#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
8333 , select_queue_fallback_t fallback
8334#endif
8335)
Jeff Johnson295189b2012-06-20 16:38:30 -07008336{
8337 return hdd_wmm_select_queue(dev, skb);
8338}
8339
8340
8341/**---------------------------------------------------------------------------
8342
8343 \brief hdd_wlan_initial_scan() -
8344
8345 This function triggers the initial scan
8346
8347 \param - pAdapter - Pointer to the HDD adapter.
8348
8349 --------------------------------------------------------------------------*/
8350void hdd_wlan_initial_scan(hdd_adapter_t *pAdapter)
8351{
8352 tCsrScanRequest scanReq;
8353 tCsrChannelInfo channelInfo;
8354 eHalStatus halStatus;
Jeff Johnson02797792013-10-26 19:17:13 -07008355 tANI_U32 scanId;
Jeff Johnson295189b2012-06-20 16:38:30 -07008356 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8357
8358 vos_mem_zero(&scanReq, sizeof(tCsrScanRequest));
8359 vos_mem_set(&scanReq.bssid, sizeof(tCsrBssid), 0xff);
8360 scanReq.BSSType = eCSR_BSS_TYPE_ANY;
8361
8362 if(sme_Is11dSupported(pHddCtx->hHal))
8363 {
8364 halStatus = sme_ScanGetBaseChannels( pHddCtx->hHal, &channelInfo );
8365 if ( HAL_STATUS_SUCCESS( halStatus ) )
8366 {
8367 scanReq.ChannelInfo.ChannelList = vos_mem_malloc(channelInfo.numOfChannels);
8368 if( !scanReq.ChannelInfo.ChannelList )
8369 {
8370 hddLog(VOS_TRACE_LEVEL_ERROR, "%s kmalloc failed", __func__);
8371 vos_mem_free(channelInfo.ChannelList);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08008372 channelInfo.ChannelList = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07008373 return;
8374 }
8375 vos_mem_copy(scanReq.ChannelInfo.ChannelList, channelInfo.ChannelList,
8376 channelInfo.numOfChannels);
8377 scanReq.ChannelInfo.numOfChannels = channelInfo.numOfChannels;
8378 vos_mem_free(channelInfo.ChannelList);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08008379 channelInfo.ChannelList = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07008380 }
8381
8382 scanReq.scanType = eSIR_PASSIVE_SCAN;
8383 scanReq.requestType = eCSR_SCAN_REQUEST_11D_SCAN;
8384 scanReq.maxChnTime = pHddCtx->cfg_ini->nPassiveMaxChnTime;
8385 scanReq.minChnTime = pHddCtx->cfg_ini->nPassiveMinChnTime;
8386 }
8387 else
8388 {
8389 scanReq.scanType = eSIR_ACTIVE_SCAN;
8390 scanReq.requestType = eCSR_SCAN_REQUEST_FULL_SCAN;
8391 scanReq.maxChnTime = pHddCtx->cfg_ini->nActiveMaxChnTime;
8392 scanReq.minChnTime = pHddCtx->cfg_ini->nActiveMinChnTime;
8393 }
8394
8395 halStatus = sme_ScanRequest(pHddCtx->hHal, pAdapter->sessionId, &scanReq, &scanId, NULL, NULL);
8396 if ( !HAL_STATUS_SUCCESS( halStatus ) )
8397 {
8398 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: sme_ScanRequest failed status code %d",
8399 __func__, halStatus );
8400 }
8401
8402 if(sme_Is11dSupported(pHddCtx->hHal))
8403 vos_mem_free(scanReq.ChannelInfo.ChannelList);
8404}
8405
mukul sharmabab477d2015-06-11 17:14:55 +05308406void hdd_purge_cmd_list_all_adapters( hdd_context_t *pHddCtx )
8407{
8408 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
8409 VOS_STATUS status;
8410 hdd_adapter_t *pAdapter;
8411
8412 ENTER();
8413
8414 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
8415
8416 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
8417 {
8418 pAdapter = pAdapterNode->pAdapter;
8419
8420 status = sme_PurgeCmdList(pHddCtx->hHal, pAdapter->sessionId);
8421 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
8422 pAdapterNode = pNext;
8423 }
8424
8425 EXIT();
8426}
Jeff Johnson295189b2012-06-20 16:38:30 -07008427/**---------------------------------------------------------------------------
8428
8429 \brief hdd_full_power_callback() - HDD full power callback function
8430
8431 This is the function invoked by SME to inform the result of a full power
8432 request issued by HDD
8433
8434 \param - callbackcontext - Pointer to cookie
8435 \param - status - result of request
8436
8437 \return - None
8438
8439 --------------------------------------------------------------------------*/
8440static void hdd_full_power_callback(void *callbackContext, eHalStatus status)
8441{
Jeff Johnson72a40512013-12-19 10:14:15 -08008442 struct statsContext *pContext = callbackContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07008443
8444 hddLog(VOS_TRACE_LEVEL_INFO,
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05308445 "%s: context = %p, status = %d", __func__, pContext, status);
Jeff Johnson295189b2012-06-20 16:38:30 -07008446
8447 if (NULL == callbackContext)
8448 {
8449 hddLog(VOS_TRACE_LEVEL_ERROR,
8450 "%s: Bad param, context [%p]",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008451 __func__, callbackContext);
Jeff Johnson295189b2012-06-20 16:38:30 -07008452 return;
8453 }
8454
Jeff Johnson72a40512013-12-19 10:14:15 -08008455 /* there is a race condition that exists between this callback
8456 function and the caller since the caller could time out either
8457 before or while this code is executing. we use a spinlock to
8458 serialize these actions */
8459 spin_lock(&hdd_context_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07008460
8461 if (POWER_CONTEXT_MAGIC != pContext->magic)
8462 {
8463 /* the caller presumably timed out so there is nothing we can do */
Jeff Johnson72a40512013-12-19 10:14:15 -08008464 spin_unlock(&hdd_context_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07008465 hddLog(VOS_TRACE_LEVEL_WARN,
8466 "%s: Invalid context, magic [%08x]",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008467 __func__, pContext->magic);
Jeff Johnson295189b2012-06-20 16:38:30 -07008468 return;
8469 }
8470
Jeff Johnson72a40512013-12-19 10:14:15 -08008471 /* context is valid so caller is still waiting */
8472
8473 /* paranoia: invalidate the magic */
8474 pContext->magic = 0;
8475
8476 /* notify the caller */
Jeff Johnson295189b2012-06-20 16:38:30 -07008477 complete(&pContext->completion);
Jeff Johnson72a40512013-12-19 10:14:15 -08008478
8479 /* serialization is complete */
8480 spin_unlock(&hdd_context_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07008481}
8482
Katya Nigamf0511f62015-05-05 16:40:57 +05308483void wlan_hdd_mon_set_typesubtype( hdd_mon_ctx_t *pMonCtx,int type)
8484{
8485 pMonCtx->typeSubtypeBitmap = 0;
8486 if( type%10 ) /* Management Packets */
8487 pMonCtx->typeSubtypeBitmap |= 0xFFFF;
8488 type/=10;
8489 if( type%10 ) /* Control Packets */
8490 pMonCtx->typeSubtypeBitmap |= 0xFFFF0000;
8491 type/=10;
8492 if( type%10 ) /* Data Packets */
8493 pMonCtx->typeSubtypeBitmap |= 0xFFFF00000000;
8494}
8495
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +05308496VOS_STATUS wlan_hdd_mon_postMsg(tANI_U32 *magic, struct completion *cmpVar,
8497 hdd_mon_ctx_t *pMonCtx , void* callback)
Katya Nigamf0511f62015-05-05 16:40:57 +05308498{
8499 vos_msg_t monMsg;
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +05308500 tSirMonModeReq *pMonModeReq;
Katya Nigamf0511f62015-05-05 16:40:57 +05308501
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +05308502 if (MON_MODE_START == pMonCtx->state)
8503 monMsg.type = WDA_MON_START_REQ;
8504 else if (MON_MODE_STOP == pMonCtx->state)
8505 monMsg.type = WDA_MON_STOP_REQ;
8506 else {
8507 hddLog(VOS_TRACE_LEVEL_ERROR,
8508 FL("invalid monitor state %d"), pMonCtx->state);
Katya Nigamf0511f62015-05-05 16:40:57 +05308509 return VOS_STATUS_E_FAILURE;
8510 }
8511
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +05308512 pMonModeReq = vos_mem_malloc(sizeof(tSirMonModeReq));
8513 if (pMonModeReq == NULL) {
8514 hddLog(VOS_TRACE_LEVEL_ERROR,
8515 FL("fail to allocate memory for monitor mode req"));
8516 return VOS_STATUS_E_FAILURE;
8517 }
Katya Nigamf0511f62015-05-05 16:40:57 +05308518
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +05308519 pMonModeReq->magic = magic;
8520 pMonModeReq->cmpVar = cmpVar;
8521 pMonModeReq->data = pMonCtx;
8522 pMonModeReq->callback = callback;
Katya Nigamf0511f62015-05-05 16:40:57 +05308523
Katya Nigamf0511f62015-05-05 16:40:57 +05308524 monMsg.reserved = 0;
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +05308525 monMsg.bodyptr = pMonModeReq;
Katya Nigamf0511f62015-05-05 16:40:57 +05308526 monMsg.bodyval = 0;
8527
8528 if (VOS_STATUS_SUCCESS != vos_mq_post_message(
8529 VOS_MODULE_ID_WDA,(vos_msg_t *)&monMsg)) {
8530 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: : Failed to post Msg to HAL",__func__);
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +05308531 vos_mem_free(pMonModeReq);
Katya Nigamf0511f62015-05-05 16:40:57 +05308532 }
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +05308533 return VOS_STATUS_SUCCESS;
Katya Nigamf0511f62015-05-05 16:40:57 +05308534}
8535
Katya Nigame7b69a82015-04-28 15:24:06 +05308536void wlan_hdd_mon_close(hdd_context_t *pHddCtx)
8537{
8538 VOS_STATUS vosStatus;
8539 v_CONTEXT_t pVosContext = pHddCtx->pvosContext;
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +05308540 long ret;
8541 hdd_mon_ctx_t *pMonCtx = NULL;
8542 v_U32_t magic;
8543 struct completion cmpVar;
Hanumantha Reddy Pothulac99bc062015-09-08 14:59:26 +05308544
Katya Nigame7b69a82015-04-28 15:24:06 +05308545 hdd_adapter_t *pAdapter = hdd_get_adapter(pHddCtx,WLAN_HDD_MONITOR);
8546 if(pAdapter == NULL || pVosContext == NULL)
8547 {
8548 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, "%s:pAdapter is NULL",__func__);
8549 return ;
8550 }
Katya Nigamf0511f62015-05-05 16:40:57 +05308551
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +05308552 pMonCtx = WLAN_HDD_GET_MONITOR_CTX_PTR(pAdapter);
8553 if (pMonCtx!= NULL && pMonCtx->state == MON_MODE_START) {
8554 pMonCtx->state = MON_MODE_STOP;
8555 magic = MON_MODE_MSG_MAGIC;
8556 init_completion(&cmpVar);
8557 if (VOS_STATUS_SUCCESS !=
8558 wlan_hdd_mon_postMsg(&magic, &cmpVar,
8559 pMonCtx, hdd_monPostMsgCb)) {
8560 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8561 FL("failed to post MON MODE REQ"));
8562 pMonCtx->state = MON_MODE_START;
8563 magic = 0;
8564 return;
8565 }
8566 ret = wait_for_completion_timeout(&cmpVar, MON_MODE_MSG_TIMEOUT);
8567 magic = 0;
8568 if (ret <= 0 ) {
8569 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8570 FL("timeout on monitor mode completion %ld"), ret);
8571 }
8572 }
8573
Katya Nigame7b69a82015-04-28 15:24:06 +05308574 hdd_UnregisterWext(pAdapter->dev);
8575
8576 vos_mon_stop( pVosContext );
8577
8578 vosStatus = vos_sched_close( pVosContext );
8579 if (!VOS_IS_STATUS_SUCCESS(vosStatus)) {
8580 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
8581 "%s: Failed to close VOSS Scheduler",__func__);
8582 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
8583 }
8584
8585 vosStatus = vos_nv_close();
8586 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
8587 {
8588 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
8589 "%s: Failed to close NV", __func__);
8590 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
8591 }
8592
8593 vos_close(pVosContext);
8594
8595 #ifdef WLAN_KD_READY_NOTIFIER
8596 nl_srv_exit(pHddCtx->ptt_pid);
8597 #else
8598 nl_srv_exit();
8599 #endif
8600
Katya Nigame7b69a82015-04-28 15:24:06 +05308601 hdd_close_all_adapters( pHddCtx );
Katya Nigame7b69a82015-04-28 15:24:06 +05308602}
Agrawal Ashish33ec71e2015-11-26 20:20:58 +05308603/**
8604 * hdd_wlan_free_wiphy_channels - free Channel pointer for wiphy
8605 * @ wiphy: the wiphy to validate against
8606 *
8607 * Return: void
8608 */
8609void hdd_wlan_free_wiphy_channels(struct wiphy *wiphy)
8610{
8611 int i =0;
8612 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
8613 {
8614 if (NULL != wiphy->bands[i] &&
8615 (NULL != wiphy->bands[i]->channels))
8616 {
8617 vos_mem_free(wiphy->bands[i]->channels);
8618 wiphy->bands[i]->channels = NULL;
8619 }
8620 }
8621}
Jeff Johnson295189b2012-06-20 16:38:30 -07008622/**---------------------------------------------------------------------------
8623
8624 \brief hdd_wlan_exit() - HDD WLAN exit function
8625
8626 This is the driver exit point (invoked during rmmod)
8627
8628 \param - pHddCtx - Pointer to the HDD Context
8629
8630 \return - None
8631
8632 --------------------------------------------------------------------------*/
8633void hdd_wlan_exit(hdd_context_t *pHddCtx)
8634{
8635 eHalStatus halStatus;
8636 v_CONTEXT_t pVosContext = pHddCtx->pvosContext;
8637 VOS_STATUS vosStatus;
Gopichand Nakkala66923aa2013-03-06 23:17:24 +05308638 struct wiphy *wiphy = pHddCtx->wiphy;
Mingcheng Zhu87f22fc2014-01-30 19:23:32 -08008639 hdd_adapter_t* pAdapter = NULL;
Jeff Johnson72a40512013-12-19 10:14:15 -08008640 struct statsContext powerContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07008641 long lrc;
c_hpothu5ab05e92014-06-13 17:34:05 +05308642 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07008643
8644 ENTER();
8645
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +05308646
Katya Nigame7b69a82015-04-28 15:24:06 +05308647 if (VOS_MONITOR_MODE == hdd_get_conparam())
8648 {
8649 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: MONITOR MODE",__func__);
8650 wlan_hdd_mon_close(pHddCtx);
Hanumantha Reddy Pothulac99bc062015-09-08 14:59:26 +05308651 goto free_hdd_ctx;
Katya Nigame7b69a82015-04-28 15:24:06 +05308652 }
8653 else if (VOS_FTM_MODE != hdd_get_conparam())
Jeff Johnson88ba7742013-02-27 14:36:02 -08008654 {
8655 // Unloading, restart logic is no more required.
8656 wlan_hdd_restart_deinit(pHddCtx);
Jeff Johnsone7245742012-09-05 17:12:55 -07008657
Agarwal Ashishb20e0ff2014-12-17 22:50:19 +05308658#ifdef FEATURE_WLAN_TDLS
8659 /* At the time of driver unloading; if tdls connection is present;
8660 * hdd_rx_packet_cbk calls wlan_hdd_tdls_find_peer.
8661 * wlan_hdd_tdls_find_peer always checks for valid context;
8662 * as load/unload in progress there can be a race condition.
8663 * hdd_rx_packet_cbk calls wlan_hdd_tdls_find_peer only
8664 * when tdls state is enabled.
8665 * As soon as driver set load/unload flag; tdls flag also needs
8666 * to be disabled so that hdd_rx_packet_cbk won't call
8667 * wlan_hdd_tdls_find_peer.
8668 */
Masti, Narayanraddi20494af2015-12-17 20:56:42 +05308669 wlan_hdd_tdls_set_mode(pHddCtx, eTDLS_SUPPORT_DISABLED, FALSE,
8670 HDD_SET_TDLS_MODE_SOURCE_USER);
Agarwal Ashishb20e0ff2014-12-17 22:50:19 +05308671#endif
8672
c_hpothu5ab05e92014-06-13 17:34:05 +05308673 vosStatus = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
8674 while (NULL != pAdapterNode && VOS_STATUS_E_EMPTY != vosStatus)
Jeff Johnson295189b2012-06-20 16:38:30 -07008675 {
c_hpothu5ab05e92014-06-13 17:34:05 +05308676 pAdapter = pAdapterNode->pAdapter;
8677 if (NULL != pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07008678 {
Mahesh A Saptasagar305e2632015-03-04 12:57:33 +05308679 /* Disable TX on the interface, after this hard_start_xmit() will
8680 * not be called on that interface
8681 */
8682 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
8683 netif_tx_disable(pAdapter->dev);
8684
8685 /* Mark the interface status as "down" for outside world */
8686 netif_carrier_off(pAdapter->dev);
8687
Agarwal Ashish9ffa5b92014-11-18 21:07:02 +05308688 /* DeInit the adapter. This ensures that all data packets
8689 * are freed.
8690 */
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05308691#ifdef FEATURE_WLAN_TDLS
8692 mutex_lock(&pHddCtx->tdls_lock);
8693#endif
c_hpothu002231a2015-02-05 14:58:51 +05308694 hdd_deinit_adapter(pHddCtx, pAdapter, FALSE);
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05308695#ifdef FEATURE_WLAN_TDLS
8696 mutex_unlock(&pHddCtx->tdls_lock);
8697#endif
Masti, Narayanraddi26378462016-01-05 18:20:28 +05308698 vos_flush_delayed_work(&pHddCtx->scan_ctxt.scan_work);
8699
8700 wlan_hdd_init_deinit_defer_scan_context(&pHddCtx->scan_ctxt);
Agarwal Ashish9ffa5b92014-11-18 21:07:02 +05308701
c_hpothu5ab05e92014-06-13 17:34:05 +05308702 if (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
8703 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode)
8704 {
8705 wlan_hdd_cfg80211_deregister_frames(pAdapter);
8706 hdd_UnregisterWext(pAdapter->dev);
8707 }
Kaushik, Sushant4975a572014-10-21 16:07:48 +05308708
Jeff Johnson295189b2012-06-20 16:38:30 -07008709 }
c_hpothu5ab05e92014-06-13 17:34:05 +05308710 vosStatus = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
8711 pAdapterNode = pNext;
Jeff Johnson295189b2012-06-20 16:38:30 -07008712 }
mukul sharmabab477d2015-06-11 17:14:55 +05308713
8714 //Purge all sme cmd's for all interface
8715 hdd_purge_cmd_list_all_adapters(pHddCtx);
8716
Kaushik, Sushant4975a572014-10-21 16:07:48 +05308717 // Cancel any outstanding scan requests. We are about to close all
8718 // of our adapters, but an adapter structure is what SME passes back
8719 // to our callback function. Hence if there are any outstanding scan
8720 // requests then there is a race condition between when the adapter
8721 // is closed and when the callback is invoked.We try to resolve that
8722 // race condition here by canceling any outstanding scans before we
8723 // close the adapters.
8724 // Note that the scans may be cancelled in an asynchronous manner,
8725 // so ideally there needs to be some kind of synchronization. Rather
8726 // than introduce a new synchronization here, we will utilize the
8727 // fact that we are about to Request Full Power, and since that is
8728 // synchronized, the expectation is that by the time Request Full
8729 // Power has completed all scans will be cancelled.
8730 if (pHddCtx->scan_info.mScanPending)
8731 {
Hema Aparna Medicharlaf05f6cd2015-01-21 14:44:19 +05308732 if(NULL != pAdapter)
8733 {
8734 hddLog(VOS_TRACE_LEVEL_INFO,
8735 FL("abort scan mode: %d sessionId: %d"),
8736 pAdapter->device_mode,
8737 pAdapter->sessionId);
8738 }
8739 hdd_abort_mac_scan(pHddCtx,
8740 pHddCtx->scan_info.sessionId,
8741 eCSR_SCAN_ABORT_DEFAULT);
Kaushik, Sushant4975a572014-10-21 16:07:48 +05308742 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008743 }
c_hpothu5ab05e92014-06-13 17:34:05 +05308744 else
Jeff Johnson88ba7742013-02-27 14:36:02 -08008745 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308746 hddLog(VOS_TRACE_LEVEL_INFO,"%s: FTM MODE",__func__);
Hanumantha Reddy Pothula45af96b2015-02-12 16:07:58 +05308747 if (pHddCtx->ftm.ftm_state == WLAN_FTM_STARTING)
8748 {
8749 INIT_COMPLETION(pHddCtx->ftm.startCmpVar);
8750 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8751 "%s: in middle of FTM START", __func__);
8752 lrc = wait_for_completion_timeout(&pHddCtx->ftm.startCmpVar,
8753 msecs_to_jiffies(20000));
8754 if(!lrc)
8755 {
8756 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
8757 "%s: timedout on ftmStartCmpVar fatal error", __func__);
8758 }
8759 }
Jeff Johnson88ba7742013-02-27 14:36:02 -08008760 wlan_hdd_ftm_close(pHddCtx);
8761 goto free_hdd_ctx;
8762 }
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308763
Jeff Johnson295189b2012-06-20 16:38:30 -07008764 /* DeRegister with platform driver as client for Suspend/Resume */
8765 vosStatus = hddDeregisterPmOps(pHddCtx);
8766 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
8767 {
8768 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddDeregisterPmOps failed",__func__);
8769 VOS_ASSERT(0);
8770 }
8771
8772 vosStatus = hddDevTmUnregisterNotifyCallback(pHddCtx);
8773 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
8774 {
8775 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddDevTmUnregisterNotifyCallback failed",__func__);
8776 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008777
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07008778 //Stop the traffic monitor timer
8779 if ( VOS_TIMER_STATE_RUNNING ==
8780 vos_timer_getCurrentState(&pHddCtx->tx_rx_trafficTmr))
8781 {
8782 vos_timer_stop(&pHddCtx->tx_rx_trafficTmr);
8783 }
8784
8785 // Destroy the traffic monitor timer
8786 if (!VOS_IS_STATUS_SUCCESS(vos_timer_destroy(
8787 &pHddCtx->tx_rx_trafficTmr)))
8788 {
8789 hddLog(VOS_TRACE_LEVEL_ERROR,
8790 "%s: Cannot deallocate Traffic monitor timer", __func__);
8791 }
8792
Bhargav Shahd0715912015-10-01 18:17:37 +05308793 if (VOS_TIMER_STATE_RUNNING ==
8794 vos_timer_getCurrentState(&pHddCtx->delack_timer)) {
8795 vos_timer_stop(&pHddCtx->delack_timer);
8796 }
8797
8798 if (!VOS_IS_STATUS_SUCCESS(vos_timer_destroy(
8799 &pHddCtx->delack_timer))) {
8800 hddLog(VOS_TRACE_LEVEL_ERROR,
8801 "%s: Cannot deallocate Bus bandwidth timer", __func__);
8802 }
8803
Masti, Narayanraddi44b0db02015-12-22 11:54:35 +05308804 if (VOS_TIMER_STATE_RUNNING ==
8805 vos_timer_getCurrentState(&pHddCtx->tdls_source_timer)) {
8806 vos_timer_stop(&pHddCtx->tdls_source_timer);
8807 }
8808
8809 vos_timer_destroy(&pHddCtx->tdls_source_timer);
8810
Jeff Johnson295189b2012-06-20 16:38:30 -07008811 //Disable IMPS/BMPS as we do not want the device to enter any power
8812 //save mode during shutdown
8813 sme_DisablePowerSave(pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
8814 sme_DisablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
8815 sme_DisablePowerSave(pHddCtx->hHal, ePMC_UAPSD_MODE_POWER_SAVE);
8816
8817 //Ensure that device is in full power as we will touch H/W during vos_Stop
8818 init_completion(&powerContext.completion);
8819 powerContext.magic = POWER_CONTEXT_MAGIC;
8820
8821 halStatus = sme_RequestFullPower(pHddCtx->hHal, hdd_full_power_callback,
8822 &powerContext, eSME_FULL_PWR_NEEDED_BY_HDD);
8823
8824 if (eHAL_STATUS_SUCCESS != halStatus)
8825 {
8826 if (eHAL_STATUS_PMC_PENDING == halStatus)
8827 {
8828 /* request was sent -- wait for the response */
8829 lrc = wait_for_completion_interruptible_timeout(
8830 &powerContext.completion,
8831 msecs_to_jiffies(WLAN_WAIT_TIME_POWER));
Jeff Johnson295189b2012-06-20 16:38:30 -07008832 if (lrc <= 0)
8833 {
8834 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: %s while requesting full power",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008835 __func__, (0 == lrc) ? "timeout" : "interrupt");
Jeff Johnson295189b2012-06-20 16:38:30 -07008836 }
8837 }
8838 else
8839 {
8840 hddLog(VOS_TRACE_LEVEL_ERROR,
8841 "%s: Request for Full Power failed, status %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008842 __func__, halStatus);
Jeff Johnson295189b2012-06-20 16:38:30 -07008843 /* continue -- need to clean up as much as possible */
8844 }
8845 }
Hanumantha Reddy Pothula81b42b22015-05-12 13:52:00 +05308846 if ((eHAL_STATUS_SUCCESS == halStatus) ||
8847 (eHAL_STATUS_PMC_PENDING == halStatus && lrc > 0))
8848 {
8849 /* This will issue a dump command which will clean up
8850 BTQM queues and unblock MC thread */
8851 vos_fwDumpReq(274, 0, 0, 0, 0, 1);
8852 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008853
Jeff Johnson72a40512013-12-19 10:14:15 -08008854 /* either we never sent a request, we sent a request and received a
8855 response or we sent a request and timed out. if we never sent a
8856 request or if we sent a request and got a response, we want to
8857 clear the magic out of paranoia. if we timed out there is a
8858 race condition such that the callback function could be
8859 executing at the same time we are. of primary concern is if the
8860 callback function had already verified the "magic" but had not
8861 yet set the completion variable when a timeout occurred. we
8862 serialize these activities by invalidating the magic while
8863 holding a shared spinlock which will cause us to block if the
8864 callback is currently executing */
8865 spin_lock(&hdd_context_lock);
8866 powerContext.magic = 0;
8867 spin_unlock(&hdd_context_lock);
8868
Hema Aparna Medicharlaa6cf65e2015-06-01 16:23:28 +05308869 /* If Device is shutdown, no point for SME to wait for responses
8870 from device. Pre Close SME */
8871 if(wcnss_device_is_shutdown())
8872 {
8873 sme_PreClose(pHddCtx->hHal);
8874 }
Yue Ma0d4891e2013-08-06 17:01:45 -07008875 hdd_debugfs_exit(pHddCtx);
8876
Ratheesh S P35ed8b12015-04-27 14:01:07 +05308877#ifdef WLAN_NS_OFFLOAD
Ratheesh S P36dbc932015-08-07 14:28:57 +05308878 hddLog(LOG1, FL("Unregister IPv6 notifier"));
Ratheesh S P35ed8b12015-04-27 14:01:07 +05308879 unregister_inet6addr_notifier(&pHddCtx->ipv6_notifier);
8880#endif
Ratheesh S P36dbc932015-08-07 14:28:57 +05308881 hddLog(LOG1, FL("Unregister IPv4 notifier"));
Ratheesh S P35ed8b12015-04-27 14:01:07 +05308882 unregister_inetaddr_notifier(&pHddCtx->ipv4_notifier);
8883
Jeff Johnson295189b2012-06-20 16:38:30 -07008884 // Unregister the Net Device Notifier
8885 unregister_netdevice_notifier(&hdd_netdev_notifier);
8886
Jeff Johnson295189b2012-06-20 16:38:30 -07008887 hdd_stop_all_adapters( pHddCtx );
8888
Jeff Johnson295189b2012-06-20 16:38:30 -07008889#ifdef WLAN_BTAMP_FEATURE
8890 vosStatus = WLANBAP_Stop(pVosContext);
8891 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
8892 {
8893 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
8894 "%s: Failed to stop BAP",__func__);
8895 }
8896#endif //WLAN_BTAMP_FEATURE
8897
8898 //Stop all the modules
8899 vosStatus = vos_stop( pVosContext );
8900 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
8901 {
8902 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
8903 "%s: Failed to stop VOSS",__func__);
8904 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
Hanumantha Reddy Pothulabd9601a2016-02-12 13:22:27 +05308905 if (isSsrPanicOnFailure())
8906 VOS_BUG(0);
Jeff Johnson295189b2012-06-20 16:38:30 -07008907 }
8908
Jeff Johnson295189b2012-06-20 16:38:30 -07008909 //This requires pMac access, Call this before vos_close().
Jeff Johnson295189b2012-06-20 16:38:30 -07008910 hdd_unregister_mcast_bcast_filter(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07008911
8912 //Close the scheduler before calling vos_close to make sure no thread is
8913 // scheduled after the each module close is called i.e after all the data
8914 // structures are freed.
8915 vosStatus = vos_sched_close( pVosContext );
8916 if (!VOS_IS_STATUS_SUCCESS(vosStatus)) {
8917 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
8918 "%s: Failed to close VOSS Scheduler",__func__);
8919 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
8920 }
Jeff Johnsone7245742012-09-05 17:12:55 -07008921#ifdef WLAN_FEATURE_HOLD_RX_WAKELOCK
8922 /* Destroy the wake lock */
Sushant Kaushik83392fa2015-05-05 17:44:40 +05308923 vos_wake_lock_destroy(&pHddCtx->rx_wake_lock);
Jeff Johnsone7245742012-09-05 17:12:55 -07008924#endif
Madan Mohan Koyyalamudi69fc3ad2012-11-28 16:04:56 -08008925 /* Destroy the wake lock */
Sushant Kaushik83392fa2015-05-05 17:44:40 +05308926 vos_wake_lock_destroy(&pHddCtx->sap_wake_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07008927
Mihir Shete7a24b5f2013-12-21 12:18:31 +05308928#ifdef CONFIG_ENABLE_LINUX_REG
8929 vosStatus = vos_nv_close();
8930 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
8931 {
8932 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
8933 "%s: Failed to close NV", __func__);
8934 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
8935 }
8936#endif
8937
Jeff Johnson295189b2012-06-20 16:38:30 -07008938 //Close VOSS
8939 //This frees pMac(HAL) context. There should not be any call that requires pMac access after this.
8940 vos_close(pVosContext);
8941
Jeff Johnson295189b2012-06-20 16:38:30 -07008942 //Close Watchdog
8943 if(pHddCtx->cfg_ini->fIsLogpEnabled)
8944 vos_watchdog_close(pVosContext);
8945
Gopichand Nakkalaa0358482013-06-12 17:05:47 +05308946 //Clean up HDD Nlink Service
8947 send_btc_nlink_msg(WLAN_MODULE_DOWN_IND, 0);
Gopichand Nakkalaa0358482013-06-12 17:05:47 +05308948
c_manjeecfd1efb2015-09-25 19:32:34 +05308949 wlan_free_fwr_mem_dump_buffer();
8950 memdump_deinit();
8951
Vinay Krishna Erannad938c422014-03-10 17:14:21 +05308952#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +05308953 if (pHddCtx->cfg_ini->wlanLoggingEnable)
Vinay Krishna Erannad938c422014-03-10 17:14:21 +05308954 {
8955 wlan_logging_sock_deactivate_svc();
8956 }
8957#endif
8958
Vinay Krishna Erannaef30b522014-08-26 17:48:16 +05308959#ifdef WLAN_KD_READY_NOTIFIER
8960 nl_srv_exit(pHddCtx->ptt_pid);
8961#else
8962 nl_srv_exit();
8963#endif /* WLAN_KD_READY_NOTIFIER */
8964
8965
Jeff Johnson295189b2012-06-20 16:38:30 -07008966 hdd_close_all_adapters( pHddCtx );
8967
Padma, Santhosh Kumar9cd38332015-11-17 12:18:10 +05308968 vos_flush_delayed_work(&pHddCtx->spoof_mac_addr_work);
8969
Hanumantha Reddy Pothula97f9bc92015-08-10 17:21:20 +05308970free_hdd_ctx:
Jeff Johnson295189b2012-06-20 16:38:30 -07008971 /* free the power on lock from platform driver */
8972 if (free_riva_power_on_lock("wlan"))
8973 {
8974 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to free power on lock",
8975 __func__);
8976 }
8977
c_hpothu78c7b602014-05-17 17:35:49 +05308978 //Free up dynamically allocated members inside HDD Adapter
8979 if (pHddCtx->cfg_ini)
8980 {
8981 kfree(pHddCtx->cfg_ini);
8982 pHddCtx->cfg_ini= NULL;
8983 }
8984
Hanumantha Reddy Pothula6fe221c2016-01-28 15:01:09 +05308985 /* FTM/MONITOR mode, WIPHY did not registered
Leo Changf04ddad2013-09-18 13:46:38 -07008986 If un-register here, system crash will happen */
Hanumantha Reddy Pothula6fe221c2016-01-28 15:01:09 +05308987 if (!(VOS_FTM_MODE == hdd_get_conparam() ||
8988 VOS_MONITOR_MODE == hdd_get_conparam()))
Leo Changf04ddad2013-09-18 13:46:38 -07008989 {
8990 wiphy_unregister(wiphy) ;
Agrawal Ashish33ec71e2015-11-26 20:20:58 +05308991 hdd_wlan_free_wiphy_channels(wiphy);
Leo Changf04ddad2013-09-18 13:46:38 -07008992 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008993 wiphy_free(wiphy) ;
Jeff Johnson295189b2012-06-20 16:38:30 -07008994 if (hdd_is_ssr_required())
8995 {
8996 /* WDI timeout had happened during unload, so SSR is needed here */
Madan Mohan Koyyalamudi3246f5b2012-10-15 15:40:02 -07008997 subsystem_restart("wcnss");
Jeff Johnson295189b2012-06-20 16:38:30 -07008998 msleep(5000);
8999 }
9000 hdd_set_ssr_required (VOS_FALSE);
9001}
9002
9003
9004/**---------------------------------------------------------------------------
9005
9006 \brief hdd_update_config_from_nv() - Function to update the contents of
9007 the running configuration with parameters taken from NV storage
9008
9009 \param - pHddCtx - Pointer to the HDD global context
9010
9011 \return - VOS_STATUS_SUCCESS if successful
9012
9013 --------------------------------------------------------------------------*/
9014static VOS_STATUS hdd_update_config_from_nv(hdd_context_t* pHddCtx)
9015{
Jeff Johnson295189b2012-06-20 16:38:30 -07009016 v_BOOL_t itemIsValid = VOS_FALSE;
9017 VOS_STATUS status;
9018 v_MACADDR_t macFromNV[VOS_MAX_CONCURRENCY_PERSONA];
9019 v_U8_t macLoop;
9020
9021 /*If the NV is valid then get the macaddress from nv else get it from qcom_cfg.ini*/
9022 status = vos_nv_getValidity(VNV_FIELD_IMAGE, &itemIsValid);
9023 if(status != VOS_STATUS_SUCCESS)
9024 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08009025 hddLog(VOS_TRACE_LEVEL_ERROR," vos_nv_getValidity() failed");
Jeff Johnson295189b2012-06-20 16:38:30 -07009026 return VOS_STATUS_E_FAILURE;
9027 }
9028
9029 if (itemIsValid == VOS_TRUE)
9030 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08009031 hddLog(VOS_TRACE_LEVEL_INFO_HIGH," Reading the Macaddress from NV");
Jeff Johnson295189b2012-06-20 16:38:30 -07009032 status = vos_nv_readMultiMacAddress((v_U8_t *)&macFromNV[0].bytes[0],
9033 VOS_MAX_CONCURRENCY_PERSONA);
9034 if(status != VOS_STATUS_SUCCESS)
9035 {
9036 /* Get MAC from NV fail, not update CFG info
9037 * INI MAC value will be used for MAC setting */
Arif Hussain6d2a3322013-11-17 19:50:10 -08009038 hddLog(VOS_TRACE_LEVEL_ERROR," vos_nv_readMacAddress() failed");
Jeff Johnson295189b2012-06-20 16:38:30 -07009039 return VOS_STATUS_E_FAILURE;
9040 }
9041
9042 /* If first MAC is not valid, treat all others are not valid
9043 * Then all MACs will be got from ini file */
9044 if(vos_is_macaddr_zero(&macFromNV[0]))
9045 {
9046 /* MAC address in NV file is not configured yet */
9047 hddLog(VOS_TRACE_LEVEL_WARN, "Invalid MAC in NV file");
9048 return VOS_STATUS_E_INVAL;
9049 }
9050
9051 /* Get MAC address from NV, update CFG info */
9052 for(macLoop = 0; macLoop < VOS_MAX_CONCURRENCY_PERSONA; macLoop++)
9053 {
9054 if(vos_is_macaddr_zero(&macFromNV[macLoop]))
9055 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309056 hddLog(VOS_TRACE_LEVEL_ERROR,"not valid MAC from NV for %d", macLoop);
Jeff Johnson295189b2012-06-20 16:38:30 -07009057 /* This MAC is not valid, skip it
9058 * This MAC will be got from ini file */
9059 }
9060 else
9061 {
9062 vos_mem_copy((v_U8_t *)&pHddCtx->cfg_ini->intfMacAddr[macLoop].bytes[0],
9063 (v_U8_t *)&macFromNV[macLoop].bytes[0],
9064 VOS_MAC_ADDR_SIZE);
9065 }
9066 }
9067 }
9068 else
9069 {
9070 hddLog(VOS_TRACE_LEVEL_ERROR, "NV ITEM, MAC Not valid");
9071 return VOS_STATUS_E_FAILURE;
9072 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009073
Jeff Johnson295189b2012-06-20 16:38:30 -07009074
9075 return VOS_STATUS_SUCCESS;
9076}
9077
9078/**---------------------------------------------------------------------------
9079
9080 \brief hdd_post_voss_start_config() - HDD post voss start config helper
9081
9082 \param - pAdapter - Pointer to the HDD
9083
9084 \return - None
9085
9086 --------------------------------------------------------------------------*/
9087VOS_STATUS hdd_post_voss_start_config(hdd_context_t* pHddCtx)
9088{
9089 eHalStatus halStatus;
9090 v_U32_t listenInterval;
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05309091 tANI_U32 ignoreDtim;
Jeff Johnson295189b2012-06-20 16:38:30 -07009092
Jeff Johnson295189b2012-06-20 16:38:30 -07009093
9094 // Send ready indication to the HDD. This will kick off the MAC
9095 // into a 'running' state and should kick off an initial scan.
9096 halStatus = sme_HDDReadyInd( pHddCtx->hHal );
9097 if ( !HAL_STATUS_SUCCESS( halStatus ) )
9098 {
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05309099 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: sme_HDDReadyInd() failed with status "
Jeff Johnson295189b2012-06-20 16:38:30 -07009100 "code %08d [x%08x]",__func__, halStatus, halStatus );
9101 return VOS_STATUS_E_FAILURE;
9102 }
9103
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05309104 // Set default LI and ignoreDtim into HDD context,
Jeff Johnson295189b2012-06-20 16:38:30 -07009105 // otherwise under some race condition, HDD will set 0 LI value into RIVA,
9106 // And RIVA will crash
9107 wlan_cfgGetInt(pHddCtx->hHal, WNI_CFG_LISTEN_INTERVAL, &listenInterval);
9108 pHddCtx->hdd_actual_LI_value = listenInterval;
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05309109 wlan_cfgGetInt(pHddCtx->hHal, WNI_CFG_IGNORE_DTIM, &ignoreDtim);
9110 pHddCtx->hdd_actual_ignore_DTIM_value = ignoreDtim;
9111
9112
Jeff Johnson295189b2012-06-20 16:38:30 -07009113 return VOS_STATUS_SUCCESS;
9114}
9115
Jeff Johnson295189b2012-06-20 16:38:30 -07009116/* wake lock APIs for HDD */
Sushant Kaushik83392fa2015-05-05 17:44:40 +05309117void hdd_prevent_suspend(uint32_t reason)
Jeff Johnson295189b2012-06-20 16:38:30 -07009118{
Sushant Kaushik83392fa2015-05-05 17:44:40 +05309119
9120 vos_wake_lock_acquire(&wlan_wake_lock, reason);
9121
Jeff Johnson295189b2012-06-20 16:38:30 -07009122}
9123
Sushant Kaushik83392fa2015-05-05 17:44:40 +05309124void hdd_allow_suspend(uint32_t reason)
Jeff Johnson295189b2012-06-20 16:38:30 -07009125{
Sushant Kaushik83392fa2015-05-05 17:44:40 +05309126
9127 vos_wake_lock_release(&wlan_wake_lock, reason);
9128
Jeff Johnson295189b2012-06-20 16:38:30 -07009129}
9130
Sushant Kaushik83392fa2015-05-05 17:44:40 +05309131void hdd_prevent_suspend_timeout(v_U32_t timeout, uint32_t reason)
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -07009132{
Sushant Kaushik83392fa2015-05-05 17:44:40 +05309133
9134 vos_wake_lock_timeout_release(&wlan_wake_lock, timeout,
9135 reason);
9136
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -07009137}
9138
Jeff Johnson295189b2012-06-20 16:38:30 -07009139/**---------------------------------------------------------------------------
9140
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07009141 \brief hdd_exchange_version_and_caps() - HDD function to exchange version and capability
9142 information between Host and Riva
9143
9144 This function gets reported version of FW
9145 It also finds the version of Riva headers used to compile the host
9146 It compares the above two and prints a warning if they are different
9147 It gets the SW and HW version string
9148 Finally, it exchanges capabilities between host and Riva i.e. host and riva exchange a msg
9149 indicating the features they support through a bitmap
9150
9151 \param - pHddCtx - Pointer to HDD context
9152
9153 \return - void
9154
9155 --------------------------------------------------------------------------*/
9156
9157void hdd_exchange_version_and_caps(hdd_context_t *pHddCtx)
9158{
9159
9160 tSirVersionType versionCompiled;
9161 tSirVersionType versionReported;
9162 tSirVersionString versionString;
9163 tANI_U8 fwFeatCapsMsgSupported = 0;
9164 VOS_STATUS vstatus;
9165
Mingcheng Zhu87f22fc2014-01-30 19:23:32 -08009166 memset(&versionCompiled, 0, sizeof(versionCompiled));
9167 memset(&versionReported, 0, sizeof(versionReported));
9168
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07009169 /* retrieve and display WCNSS version information */
9170 do {
9171
9172 vstatus = sme_GetWcnssWlanCompiledVersion(pHddCtx->hHal,
9173 &versionCompiled);
9174 if (!VOS_IS_STATUS_SUCCESS(vstatus))
9175 {
9176 hddLog(VOS_TRACE_LEVEL_FATAL,
9177 "%s: unable to retrieve WCNSS WLAN compiled version",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07009178 __func__);
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07009179 break;
9180 }
9181
9182 vstatus = sme_GetWcnssWlanReportedVersion(pHddCtx->hHal,
9183 &versionReported);
9184 if (!VOS_IS_STATUS_SUCCESS(vstatus))
9185 {
9186 hddLog(VOS_TRACE_LEVEL_FATAL,
9187 "%s: unable to retrieve WCNSS WLAN reported version",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07009188 __func__);
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07009189 break;
9190 }
9191
9192 if ((versionCompiled.major != versionReported.major) ||
9193 (versionCompiled.minor != versionReported.minor) ||
9194 (versionCompiled.version != versionReported.version) ||
9195 (versionCompiled.revision != versionReported.revision))
9196 {
9197 pr_err("%s: WCNSS WLAN Version %u.%u.%u.%u, "
9198 "Host expected %u.%u.%u.%u\n",
9199 WLAN_MODULE_NAME,
9200 (int)versionReported.major,
9201 (int)versionReported.minor,
9202 (int)versionReported.version,
9203 (int)versionReported.revision,
9204 (int)versionCompiled.major,
9205 (int)versionCompiled.minor,
9206 (int)versionCompiled.version,
9207 (int)versionCompiled.revision);
9208 }
9209 else
9210 {
9211 pr_info("%s: WCNSS WLAN version %u.%u.%u.%u\n",
9212 WLAN_MODULE_NAME,
9213 (int)versionReported.major,
9214 (int)versionReported.minor,
9215 (int)versionReported.version,
9216 (int)versionReported.revision);
9217 }
9218
9219 vstatus = sme_GetWcnssSoftwareVersion(pHddCtx->hHal,
9220 versionString,
9221 sizeof(versionString));
9222 if (!VOS_IS_STATUS_SUCCESS(vstatus))
9223 {
9224 hddLog(VOS_TRACE_LEVEL_FATAL,
9225 "%s: unable to retrieve WCNSS software version string",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07009226 __func__);
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07009227 break;
9228 }
9229
9230 pr_info("%s: WCNSS software version %s\n",
9231 WLAN_MODULE_NAME, versionString);
Sushant Kaushik084f6592015-09-10 13:11:56 +05309232 vos_mem_copy(pHddCtx->fw_Version, versionString, sizeof(versionString));
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07009233
9234 vstatus = sme_GetWcnssHardwareVersion(pHddCtx->hHal,
9235 versionString,
9236 sizeof(versionString));
9237 if (!VOS_IS_STATUS_SUCCESS(vstatus))
9238 {
9239 hddLog(VOS_TRACE_LEVEL_FATAL,
9240 "%s: unable to retrieve WCNSS hardware version string",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07009241 __func__);
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07009242 break;
9243 }
9244
9245 pr_info("%s: WCNSS hardware version %s\n",
9246 WLAN_MODULE_NAME, versionString);
9247
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -07009248 /* 1.Check if FW version is greater than 0.1.1.0. Only then send host-FW capability exchange message
9249 2.Host-FW capability exchange message is only present on riva 1.1 so
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07009250 send the message only if it the riva is 1.1
9251 minor numbers for different riva branches:
9252 0 -> (1.0)Mainline Build
9253 1 -> (1.1)Mainline Build
9254 2->(1.04) Stability Build
9255 */
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -07009256 if (((versionReported.major>0) || (versionReported.minor>1) ||
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07009257 ((versionReported.minor>=1) && (versionReported.version>=1)))
9258 && ((versionReported.major == 1) && (versionReported.minor >= 1)))
9259 fwFeatCapsMsgSupported = 1;
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -07009260
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07009261 if (fwFeatCapsMsgSupported)
Yathish9f22e662012-12-10 14:21:35 -08009262 {
9263#ifdef WLAN_ACTIVEMODE_OFFLOAD_FEATURE
9264 if(!pHddCtx->cfg_ini->fEnableActiveModeOffload)
9265 sme_disableFeatureCapablity(WLANACTIVE_OFFLOAD);
9266#endif
Ravi Joshid2ca7c42013-07-23 08:37:49 -07009267 /* Indicate if IBSS heartbeat monitoring needs to be offloaded */
9268 if (!pHddCtx->cfg_ini->enableIbssHeartBeatOffload)
9269 {
9270 sme_disableFeatureCapablity(IBSS_HEARTBEAT_OFFLOAD);
9271 }
9272
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07009273 sme_featureCapsExchange(pHddCtx->hHal);
Yathish9f22e662012-12-10 14:21:35 -08009274 }
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07009275
9276 } while (0);
9277
9278}
Neelansh Mittaledafed22014-09-04 18:54:39 +05309279void wlan_hdd_send_svc_nlink_msg(int type, void *data, int len)
9280{
9281 struct sk_buff *skb;
9282 struct nlmsghdr *nlh;
9283 tAniMsgHdr *ani_hdr;
Hanumantha Reddy Pothulacf2c7ea2015-04-27 14:50:47 +05309284 int flags = GFP_KERNEL;
Bhargav shah23c94942015-10-13 12:48:35 +05309285 void *nl_data = NULL;
Neelansh Mittaledafed22014-09-04 18:54:39 +05309286
Hanumantha Reddy Pothulacf2c7ea2015-04-27 14:50:47 +05309287 if (in_interrupt() || irqs_disabled() || in_atomic())
9288 flags = GFP_ATOMIC;
9289
9290 skb = alloc_skb(NLMSG_SPACE(WLAN_NL_MAX_PAYLOAD), flags);
Neelansh Mittaledafed22014-09-04 18:54:39 +05309291
9292 if(skb == NULL) {
9293 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9294 "%s: alloc_skb failed", __func__);
9295 return;
9296 }
9297
9298 nlh = (struct nlmsghdr *)skb->data;
9299 nlh->nlmsg_pid = 0; /* from kernel */
9300 nlh->nlmsg_flags = 0;
9301 nlh->nlmsg_seq = 0;
9302 nlh->nlmsg_type = WLAN_NL_MSG_SVC;
9303
9304 ani_hdr = NLMSG_DATA(nlh);
9305 ani_hdr->type = type;
9306
9307 switch(type) {
9308 case WLAN_SVC_SAP_RESTART_IND:
9309 ani_hdr->length = 0;
9310 nlh->nlmsg_len = NLMSG_LENGTH((sizeof(tAniMsgHdr)));
9311 skb_put(skb, NLMSG_SPACE(sizeof(tAniMsgHdr)));
9312 break;
Bhargav Shahd0715912015-10-01 18:17:37 +05309313 case WLAN_SVC_WLAN_TP_IND:
9314 ani_hdr->length = len;
9315 nlh->nlmsg_len = NLMSG_LENGTH((sizeof(tAniMsgHdr)
9316 + len));
9317 nl_data = (char *)ani_hdr + sizeof(tAniMsgHdr);
9318 memcpy(nl_data, data, len);
9319 skb_put(skb, NLMSG_SPACE(sizeof(tAniMsgHdr) + len));
9320 break;
Bhargav shah23c94942015-10-13 12:48:35 +05309321 case WLAN_MSG_RPS_ENABLE_IND:
9322 ani_hdr->length = len;
9323 nlh->nlmsg_len = NLMSG_LENGTH((sizeof(tAniMsgHdr) + len));
9324 nl_data = (char *)ani_hdr + sizeof(tAniMsgHdr);
9325 memcpy(nl_data, data, len);
9326 skb_put(skb, NLMSG_SPACE(sizeof(tAniMsgHdr) + len));
9327 break;
Neelansh Mittaledafed22014-09-04 18:54:39 +05309328 default:
9329 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9330 "Attempt to send unknown nlink message %d", type);
9331 kfree_skb(skb);
9332 return;
9333 }
9334
9335 nl_srv_bcast(skb);
9336
9337 return;
9338}
9339
Bhargav Shahd0715912015-10-01 18:17:37 +05309340/**
9341 * hdd_request_tcp_delack() - Find the Delack value based on RX packet
9342 * @pHddCtx: Valid Global HDD context pointer
9343 * @rx_packets: Number of RX packet in perticular time
9344 *
9345 * Based on the RX packet this function calculate next value of tcp delack.
9346 * This function compare rx packet value to high and low threshold limit.
9347 *
9348 * Return: void
9349 */
9350void hdd_request_tcp_delack(hdd_context_t *pHddCtx, uint64_t rx_packets)
9351{
9352 /* average of rx_packets and prev_rx is taken so that
9353 bus width doesnot fluctuate much */
9354 uint64_t temp_rx = (rx_packets + pHddCtx->prev_rx)/2;
9355 TP_IND_TYPE next_rx_level = pHddCtx->cur_rx_level;
Neelansh Mittaledafed22014-09-04 18:54:39 +05309356
Bhargav Shahd0715912015-10-01 18:17:37 +05309357 pHddCtx->prev_rx = rx_packets;
9358 if (temp_rx > pHddCtx->cfg_ini->tcpDelAckThresholdHigh)
9359 next_rx_level = TP_IND_HIGH;
9360 else if (temp_rx <= pHddCtx->cfg_ini->tcpDelAckThresholdLow)
9361 next_rx_level = TP_IND_LOW;
9362
9363 hdd_set_delack_value(pHddCtx, next_rx_level);
9364}
9365
9366#define HDD_BW_GET_DIFF(x, y) ((x) >= (y) ? (x) - (y) : (ULONG_MAX - (y) + (x)))
9367
9368/**
9369 * hdd_tcp_delack_compute_function() - get link status
9370 * @priv: Valid Global HDD context pointer
9371 *
9372 * This function find number of RX packet during timer life span.
9373 * It request tcp delack with number of RX packet and re-configure delack timer
9374 * for tcpDelAckComputeInterval timer interval.
9375 *
9376 * Return: void
9377 */
9378void hdd_tcp_delack_compute_function(void *priv)
9379{
9380 hdd_context_t *pHddCtx = (hdd_context_t *)priv;
9381 hdd_adapter_t *pAdapter = NULL;
9382 v_U32_t rx_packets = 0;
9383 hdd_adapter_list_node_t *pAdapterNode = NULL;
9384 VOS_STATUS status = 0;
9385
9386 for (status = hdd_get_front_adapter(pHddCtx, &pAdapterNode);
9387 NULL != pAdapterNode && VOS_STATUS_SUCCESS == status;
9388 status = hdd_get_next_adapter(pHddCtx, pAdapterNode, &pAdapterNode)) {
9389 if ((pAdapter = pAdapterNode->pAdapter) == NULL)
9390 continue;
9391
9392 rx_packets += HDD_BW_GET_DIFF(pAdapter->stats.rx_packets,
9393 pAdapter->prev_rx_packets);
9394 pAdapter->prev_rx_packets = pAdapter->stats.rx_packets;
9395 }
9396
9397 hdd_request_tcp_delack(pHddCtx, rx_packets);
9398
9399 vos_timer_start(&pHddCtx->delack_timer,
9400 pHddCtx->cfg_ini->tcpDelAckComputeInterval);
9401}
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07009402
9403/**---------------------------------------------------------------------------
9404
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05309405 \brief hdd_is_5g_supported() - HDD function to know if hardware supports 5GHz
9406
9407 \param - pHddCtx - Pointer to the hdd context
9408
9409 \return - true if hardware supports 5GHz
9410
9411 --------------------------------------------------------------------------*/
Vinay Krishna Erannafacf5e22014-02-24 13:16:25 +05309412boolean hdd_is_5g_supported(hdd_context_t * pHddCtx)
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05309413{
9414 /* If wcnss_wlan_iris_xo_mode() returns WCNSS_XO_48MHZ(1);
9415 * then hardware support 5Ghz.
9416 */
9417 if (WCNSS_XO_48MHZ == wcnss_wlan_iris_xo_mode())
9418 {
Ratheesh S P36dbc932015-08-07 14:28:57 +05309419 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Hardware supports 5Ghz", __func__);
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05309420 return true;
9421 }
9422 else
9423 {
Ratheesh S P36dbc932015-08-07 14:28:57 +05309424 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Hardware doesn't supports 5Ghz",
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05309425 __func__);
9426 return false;
9427 }
9428}
9429
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05309430/**---------------------------------------------------------------------------
9431
9432 \brief hdd_generate_iface_mac_addr_auto() - HDD Mac Interface Auto
9433 generate function
9434
9435 This is generate the random mac address for WLAN interface
9436
9437 \param - pHddCtx - Pointer to HDD context
9438 idx - Start interface index to get auto
9439 generated mac addr.
9440 mac_addr - Mac address
9441
9442 \return - 0 for success, < 0 for failure
9443
9444 --------------------------------------------------------------------------*/
9445
9446static int hdd_generate_iface_mac_addr_auto(hdd_context_t *pHddCtx,
9447 int idx, v_MACADDR_t mac_addr)
9448{
9449 int i;
9450 unsigned int serialno;
9451 serialno = wcnss_get_serial_number();
9452
9453 if (0 != serialno)
9454 {
9455 /* MAC address has 3 bytes of OUI so we have a maximum of 3
9456 bytes of the serial number that can be used to generate
9457 the other 3 bytes of the MAC address. Mask off all but
9458 the lower 3 bytes (this will also make sure we don't
9459 overflow in the next step) */
9460 serialno &= 0x00FFFFFF;
9461
9462 /* we need a unique address for each session */
9463 serialno *= VOS_MAX_CONCURRENCY_PERSONA;
9464
9465 /* autogen other Mac addresses */
9466 for (i = idx; i < VOS_MAX_CONCURRENCY_PERSONA; i++)
9467 {
9468 /* start with the entire default address */
9469 pHddCtx->cfg_ini->intfMacAddr[i] = mac_addr;
9470 /* then replace the lower 3 bytes */
9471 pHddCtx->cfg_ini->intfMacAddr[i].bytes[3] = (serialno >> 16) & 0xFF;
9472 pHddCtx->cfg_ini->intfMacAddr[i].bytes[4] = (serialno >> 8) & 0xFF;
9473 pHddCtx->cfg_ini->intfMacAddr[i].bytes[5] = serialno & 0xFF;
9474
9475 serialno++;
9476 hddLog(VOS_TRACE_LEVEL_ERROR,
9477 "%s: Derived Mac Addr: "
9478 MAC_ADDRESS_STR, __func__,
9479 MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[i].bytes));
9480 }
9481
9482 }
9483 else
9484 {
9485 hddLog(LOGE, FL("Failed to Get Serial NO"));
9486 return -1;
9487 }
9488 return 0;
9489}
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05309490
Katya Nigame7b69a82015-04-28 15:24:06 +05309491int wlan_hdd_mon_open(hdd_context_t *pHddCtx)
9492{
9493 VOS_STATUS status;
9494 v_CONTEXT_t pVosContext= NULL;
9495 hdd_adapter_t *pAdapter= NULL;
9496
9497 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
9498
9499 if (NULL == pVosContext)
9500 {
9501 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9502 "%s: Trying to open VOSS without a PreOpen", __func__);
9503 VOS_ASSERT(0);
9504 return VOS_STATUS_E_FAILURE;
9505 }
9506
9507 status = vos_nv_open();
9508 if (!VOS_IS_STATUS_SUCCESS(status))
9509 {
9510 /* NV module cannot be initialized */
9511 hddLog( VOS_TRACE_LEVEL_FATAL,
9512 "%s: vos_nv_open failed", __func__);
9513 return VOS_STATUS_E_FAILURE;
9514 }
9515
9516 status = vos_init_wiphy_from_nv_bin();
9517 if (!VOS_IS_STATUS_SUCCESS(status))
9518 {
9519 /* NV module cannot be initialized */
9520 hddLog( VOS_TRACE_LEVEL_FATAL,
9521 "%s: vos_init_wiphy failed", __func__);
9522 goto err_vos_nv_close;
9523 }
9524
9525 status = vos_open( &pVosContext, pHddCtx->parent_dev);
9526 if ( !VOS_IS_STATUS_SUCCESS( status ))
9527 {
9528 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: vos_open failed", __func__);
9529 goto err_vos_nv_close;
9530 }
9531
9532 status = vos_mon_start( pVosContext );
9533 if ( !VOS_IS_STATUS_SUCCESS( status ) )
9534 {
9535 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: vos_start failed",__func__);
9536 goto err_vosclose;
9537 }
9538
9539 WLANTL_SetMonRxCbk( pVosContext, hdd_rx_packet_monitor_cbk );
9540 WDA_featureCapsExchange(pVosContext);
9541 wcnss_wlan_set_drvdata(pHddCtx->parent_dev, pHddCtx);
9542
9543 pAdapter = hdd_open_adapter( pHddCtx, WLAN_HDD_MONITOR, "wlan%d",
9544 wlan_hdd_get_intf_addr(pHddCtx), FALSE );
9545 if( pAdapter == NULL )
9546 {
9547 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: hdd_open_adapter failed", __func__);
9548 goto err_close_adapter;
9549 }
9550
9551 //Initialize the nlink service
9552 if(nl_srv_init() != 0)
9553 {
9554 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: nl_srv_init failed", __func__);
9555 goto err_close_adapter;
9556 }
9557 return VOS_STATUS_SUCCESS;
9558
9559err_close_adapter:
9560 hdd_close_all_adapters( pHddCtx );
9561 vos_mon_stop( pVosContext );
9562err_vosclose:
9563 status = vos_sched_close( pVosContext );
9564 if (!VOS_IS_STATUS_SUCCESS(status)) {
9565 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
9566 "%s: Failed to close VOSS Scheduler", __func__);
9567 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( status ) );
9568 }
9569 vos_close(pVosContext );
9570
9571err_vos_nv_close:
9572 vos_nv_close();
9573
9574return status;
9575}
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05309576/**---------------------------------------------------------------------------
9577
Mihir Shetefc7ff5b2014-01-27 11:30:05 +05309578 \brief hdd_11d_scan_done - callback to be executed when 11d scan is
9579 completed to flush out the scan results
9580
9581 11d scan is done during driver load and is a passive scan on all
9582 channels supported by the device, 11d scans may find some APs on
9583 frequencies which are forbidden to be used in the regulatory domain
9584 the device is operating in. If these APs are notified to the supplicant
9585 it may try to connect to these APs, thus flush out all the scan results
9586 which are present in SME after 11d scan is done.
9587
9588 \return - eHalStatus
9589
9590 --------------------------------------------------------------------------*/
9591static eHalStatus hdd_11d_scan_done(tHalHandle halHandle, void *pContext,
9592 tANI_U32 scanId, eCsrScanStatus status)
9593{
9594 ENTER();
9595
9596 sme_ScanFlushResult(halHandle, 0);
9597
9598 EXIT();
9599
9600 return eHAL_STATUS_SUCCESS;
9601}
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309602/**---------------------------------------------------------------------------
9603
9604 \brief hdd_init_frame_logging_done - callback to be executed when mgmt frame
9605 logging is completed successfully.
9606
9607 \return - None
9608
9609 --------------------------------------------------------------------------*/
c_manjeecfd1efb2015-09-25 19:32:34 +05309610void hdd_init_frame_logging_done(void *fwlogInitCbContext, tAniLoggingInitRsp *pRsp)
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309611{
Siddharth Bhald1be97f2015-05-27 22:39:59 +05309612 hdd_context_t* pHddCtx = (hdd_context_t*)fwlogInitCbContext;
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309613
9614 if (NULL == pHddCtx)
9615 {
9616 hddLog(VOS_TRACE_LEVEL_ERROR,
9617 "%s: HDD context is NULL",__func__);
9618 return;
9619 }
9620
c_manjeecfd1efb2015-09-25 19:32:34 +05309621 if ((pRsp->status == VOS_STATUS_SUCCESS) &&
Mahesh A Saptasagarfabb1a02015-06-29 12:17:04 +05309622 (TRUE == pHddCtx->cfg_ini->enableMgmtLogging))
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309623 {
9624 hddLog(VOS_TRACE_LEVEL_INFO, FL("Mgmt Frame Logging init successful"));
9625 pHddCtx->mgmt_frame_logging = TRUE;
9626 }
9627 else
9628 {
9629 hddLog(VOS_TRACE_LEVEL_INFO, FL("Mgmt Frame Logging init not success"));
9630 pHddCtx->mgmt_frame_logging = FALSE;
c_manjeecfd1efb2015-09-25 19:32:34 +05309631 return;
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309632 }
9633
c_manjeecfd1efb2015-09-25 19:32:34 +05309634 /*Check feature supported by FW*/
9635 if(TRUE == sme_IsFeatureSupportedByFW(MEMORY_DUMP_SUPPORTED))
9636 {
9637 //Store fwr mem dump size given by firmware.
9638 wlan_store_fwr_mem_dump_size(pRsp->fw_mem_dump_max_size);
9639 }
9640 else
9641 {
9642 wlan_store_fwr_mem_dump_size(0);
9643 }
9644
9645
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309646}
9647/**---------------------------------------------------------------------------
9648
9649 \brief hdd_init_frame_logging - function to initialize frame logging.
9650 Currently only Mgmt Frames are logged in both TX
9651 and Rx direction and are sent to userspace
9652 application using logger thread when queried.
9653
9654 \return - None
9655
9656 --------------------------------------------------------------------------*/
Siddharth Bhald1be97f2015-05-27 22:39:59 +05309657void hdd_init_frame_logging(hdd_context_t* pHddCtx)
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309658{
9659 eHalStatus halStatus = eHAL_STATUS_FAILURE;
Siddharth Bhald1be97f2015-05-27 22:39:59 +05309660 tpSirFWLoggingInitParam wlanFWLoggingInitParam;
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309661
Siddharth Bhald1be97f2015-05-27 22:39:59 +05309662 if (TRUE != sme_IsFeatureSupportedByFW(MGMT_FRAME_LOGGING) &&
9663 TRUE != sme_IsFeatureSupportedByFW(LOGGING_ENHANCEMENT))
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309664 {
9665 hddLog(VOS_TRACE_LEVEL_INFO, FL("MGMT_FRAME_LOGGING not supp by FW"));
9666 return;
9667 }
9668
Siddharth Bhald1be97f2015-05-27 22:39:59 +05309669 wlanFWLoggingInitParam = vos_mem_malloc(sizeof(tSirFWLoggingInitParam));
9670 if(NULL == wlanFWLoggingInitParam)
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309671 {
9672 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: vos_mem_alloc failed ", __func__);
9673 return;
9674 }
9675
Siddharth Bhald1be97f2015-05-27 22:39:59 +05309676 vos_mem_set(wlanFWLoggingInitParam, sizeof(tSirFWLoggingInitParam), 0);
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309677
c_manjeecfd1efb2015-09-25 19:32:34 +05309678 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Configuring %s %s %s %s Logging",__func__,
Siddharth Bhald1be97f2015-05-27 22:39:59 +05309679 pHddCtx->cfg_ini->enableFWLogging?"FW Log,":"",
9680 pHddCtx->cfg_ini->enableContFWLogging ? "Cont FW log,":"",
c_manjeecfd1efb2015-09-25 19:32:34 +05309681 pHddCtx->cfg_ini->enableMgmtLogging ? "Mgmt Pkt Log":"",
9682 pHddCtx->cfg_ini->enableFwrMemDump ? "Fw Mem dump":"");
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309683
Siddharth Bhald1be97f2015-05-27 22:39:59 +05309684 if (pHddCtx->cfg_ini->enableFWLogging ||
9685 pHddCtx->cfg_ini->enableContFWLogging)
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309686 {
Siddharth Bhald1be97f2015-05-27 22:39:59 +05309687 wlanFWLoggingInitParam->enableFlag |= WLAN_QXDM_LOG_EN;
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309688 }
9689
Sushant Kaushik46804902015-07-08 14:46:03 +05309690 if (pHddCtx->cfg_ini->enableMgmtLogging)
9691 {
9692 wlanFWLoggingInitParam->enableFlag |= WLAN_FRAME_LOG_EN;
9693 }
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309694 if (pHddCtx->cfg_ini->enableBMUHWtracing)
9695 {
Siddharth Bhald1be97f2015-05-27 22:39:59 +05309696 wlanFWLoggingInitParam->enableFlag |= WLAN_BMUHW_TRACE_LOG_EN;
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309697 }
c_manjeecfd1efb2015-09-25 19:32:34 +05309698 if(pHddCtx->cfg_ini->enableFwrMemDump &&
9699 (TRUE == sme_IsFeatureSupportedByFW(MEMORY_DUMP_SUPPORTED)))
9700 {
9701 wlanFWLoggingInitParam->enableFlag |= WLAN_FW_MEM_DUMP_EN;
9702 }
9703 if( wlanFWLoggingInitParam->enableFlag == 0 )
9704 {
9705 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Logging not enabled", __func__);
9706 return;
9707 }
Siddharth Bhald1be97f2015-05-27 22:39:59 +05309708 wlanFWLoggingInitParam->frameType = WLAN_FRAME_LOGGING_FRAMETYPE_MGMT;
9709 wlanFWLoggingInitParam->frameSize = WLAN_MGMT_LOGGING_FRAMESIZE_128BYTES;
9710 wlanFWLoggingInitParam->bufferMode = WLAN_FRAME_LOGGING_BUFFERMODE_CIRCULAR;
9711 wlanFWLoggingInitParam->continuousFrameLogging =
9712 pHddCtx->cfg_ini->enableContFWLogging;
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309713
Siddharth Bhald1be97f2015-05-27 22:39:59 +05309714 wlanFWLoggingInitParam->enableFlag &= ~WLAN_DPU_TXP_LOG_EN;
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309715
Siddharth Bhald1be97f2015-05-27 22:39:59 +05309716 wlanFWLoggingInitParam->minLogBufferSize =
9717 pHddCtx->cfg_ini->minLoggingBufferSize;
9718 wlanFWLoggingInitParam->maxLogBufferSize =
9719 pHddCtx->cfg_ini->maxLoggingBufferSize;
9720 wlanFWLoggingInitParam->fwlogInitCallback = hdd_init_frame_logging_done;
9721 wlanFWLoggingInitParam->fwlogInitCbContext= pHddCtx;
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309722
Siddharth Bhald1be97f2015-05-27 22:39:59 +05309723 halStatus = sme_InitMgmtFrameLogging(pHddCtx->hHal, wlanFWLoggingInitParam);
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309724
9725 if (eHAL_STATUS_SUCCESS != halStatus)
9726 {
Siddharth Bhald1be97f2015-05-27 22:39:59 +05309727 vos_mem_free(wlanFWLoggingInitParam);
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309728 }
9729
9730 return;
9731}
Mihir Shetefc7ff5b2014-01-27 11:30:05 +05309732
Bhargav shah23c94942015-10-13 12:48:35 +05309733static void hdd_dp_util_send_rps_ind(hdd_context_t *hdd_ctxt)
9734{
9735 hdd_adapter_t *adapter;
9736 hdd_adapter_list_node_t *adapter_node, *next;
9737 VOS_STATUS status = VOS_STATUS_SUCCESS;
9738 struct wlan_rps_data rps_data;
9739 int count;
9740
9741 if(!hdd_ctxt->cfg_ini->rps_mask)
9742 {
9743 return;
9744 }
9745
9746 for (count=0; count < WLAN_SVC_IFACE_NUM_QUEUES; count++)
9747 {
9748 rps_data.cpu_map[count] = hdd_ctxt->cfg_ini->rps_mask;
9749 }
9750
9751 rps_data.num_queues = WLAN_SVC_IFACE_NUM_QUEUES;
9752
9753 hddLog(LOG1, FL("0x%x 0x%x 0x%x 0x%x 0x%x 0x%x"),
9754 rps_data.cpu_map[0], rps_data.cpu_map[1],rps_data.cpu_map[2],
9755 rps_data.cpu_map[3], rps_data.cpu_map[4], rps_data.cpu_map[5]);
9756
9757 status = hdd_get_front_adapter (hdd_ctxt, &adapter_node);
9758
9759 while (NULL != adapter_node && VOS_STATUS_SUCCESS == status)
9760 {
9761 adapter = adapter_node->pAdapter;
9762 if (NULL != adapter) {
9763 strlcpy(rps_data.ifname, adapter->dev->name,
9764 sizeof(rps_data.ifname));
9765 wlan_hdd_send_svc_nlink_msg(WLAN_MSG_RPS_ENABLE_IND,
9766 (void *)&rps_data,sizeof(rps_data));
9767 }
9768 status = hdd_get_next_adapter (hdd_ctxt, adapter_node, &next);
9769 adapter_node = next;
9770 }
9771}
9772
Masti, Narayanraddi26378462016-01-05 18:20:28 +05309773void wlan_hdd_schedule_defer_scan(struct work_struct *work)
9774{
9775 scan_context_t *scan_ctx =
9776 container_of(work, scan_context_t, scan_work.work);
9777
9778 if (NULL == scan_ctx)
9779 {
9780 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9781 FL("scan_ctx is NULL"));
9782 return;
9783 }
9784
9785 if (unlikely(TDLS_CTX_MAGIC != scan_ctx->magic))
9786 return;
9787
9788 scan_ctx->attempt++;
9789
9790 wlan_hdd_cfg80211_scan(scan_ctx->wiphy,
9791#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
9792 scan_ctx->dev,
9793#endif
9794 scan_ctx->scan_request);
9795}
9796
9797int wlan_hdd_copy_defer_scan_context(hdd_context_t *pHddCtx,
9798 struct wiphy *wiphy,
9799#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
9800 struct net_device *dev,
9801#endif
9802 struct cfg80211_scan_request *request)
9803{
9804 scan_context_t *scan_ctx;
9805
9806 ENTER();
9807 if (0 != (wlan_hdd_validate_context(pHddCtx)))
9808 {
9809 return -1;
9810 }
9811
9812 scan_ctx = &pHddCtx->scan_ctxt;
9813
9814 scan_ctx->wiphy = wiphy;
9815#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
9816 scan_ctx->dev = dev;
9817#endif
9818
9819 scan_ctx->scan_request = request;
9820
9821 EXIT();
9822 return 0;
9823}
9824
9825void wlan_hdd_defer_scan_init_work(hdd_context_t *pHddCtx,
9826 struct wiphy *wiphy,
9827#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
9828 struct net_device *dev,
9829#endif
9830 struct cfg80211_scan_request *request,
9831 unsigned long delay)
9832{
9833 if (TDLS_CTX_MAGIC != pHddCtx->scan_ctxt.magic)
9834 {
9835#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
9836 wlan_hdd_copy_defer_scan_context(pHddCtx, wiphy, dev, request);
9837#else
9838 wlan_hdd_copy_defer_scan_context(pHddCtx, wiphy, request);
9839#endif
9840 pHddCtx->scan_ctxt.attempt = 0;
9841 pHddCtx->scan_ctxt.magic = TDLS_CTX_MAGIC;
9842 }
9843 schedule_delayed_work(&pHddCtx->scan_ctxt.scan_work, delay);
9844}
9845
9846void wlan_hdd_init_deinit_defer_scan_context(scan_context_t *scan_ctx)
9847{
9848 scan_ctx->magic = 0;
9849 scan_ctx->attempt = 0;
9850 scan_ctx->reject = 0;
9851 scan_ctx->scan_request = NULL;
9852
9853 return;
9854}
9855
Mihir Shetefc7ff5b2014-01-27 11:30:05 +05309856/**---------------------------------------------------------------------------
9857
Jeff Johnson295189b2012-06-20 16:38:30 -07009858 \brief hdd_wlan_startup() - HDD init function
9859
9860 This is the driver startup code executed once a WLAN device has been detected
9861
9862 \param - dev - Pointer to the underlying device
9863
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08009864 \return - 0 for success, < 0 for failure
Jeff Johnson295189b2012-06-20 16:38:30 -07009865
9866 --------------------------------------------------------------------------*/
9867
9868int hdd_wlan_startup(struct device *dev )
9869{
9870 VOS_STATUS status;
9871 hdd_adapter_t *pAdapter = NULL;
Jeff Johnsone7245742012-09-05 17:12:55 -07009872 hdd_adapter_t *pP2pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07009873 hdd_context_t *pHddCtx = NULL;
9874 v_CONTEXT_t pVosContext= NULL;
9875#ifdef WLAN_BTAMP_FEATURE
9876 VOS_STATUS vStatus = VOS_STATUS_SUCCESS;
9877 WLANBAP_ConfigType btAmpConfig;
9878 hdd_config_t *pConfig;
9879#endif
9880 int ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07009881 struct wiphy *wiphy;
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05309882 v_MACADDR_t mac_addr;
Jeff Johnson295189b2012-06-20 16:38:30 -07009883
9884 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07009885 /*
9886 * cfg80211: wiphy allocation
9887 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309888 wiphy = wlan_hdd_cfg80211_wiphy_alloc(sizeof(hdd_context_t)) ;
Jeff Johnson295189b2012-06-20 16:38:30 -07009889
9890 if(wiphy == NULL)
9891 {
9892 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: cfg80211 init failed", __func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08009893 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -07009894 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009895 pHddCtx = wiphy_priv(wiphy);
9896
Jeff Johnson295189b2012-06-20 16:38:30 -07009897 //Initialize the adapter context to zeros.
9898 vos_mem_zero(pHddCtx, sizeof( hdd_context_t ));
9899
Jeff Johnson295189b2012-06-20 16:38:30 -07009900 pHddCtx->wiphy = wiphy;
Sushant Kaushik83392fa2015-05-05 17:44:40 +05309901 hdd_prevent_suspend(WIFI_POWER_EVENT_WAKELOCK_DRIVER_INIT);
Mihir Shete18156292014-03-11 15:38:30 +05309902 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_LOAD_IN_PROGRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07009903
9904 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, TRUE);
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05309905 pHddCtx->wifi_turn_on_time_since_boot = vos_get_monotonic_boottime();
Jeff Johnson295189b2012-06-20 16:38:30 -07009906
Siddharth Bhalcd92b782015-06-29 12:25:40 +05309907 /* register for riva power on lock to platform driver
9908 * Locking power early to ensure FW doesn't reset by kernel while
9909 * host driver is busy initializing itself */
9910 if (req_riva_power_on_lock("wlan"))
9911 {
9912 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: req riva power on lock failed",
9913 __func__);
9914 goto err_free_hdd_context;
9915 }
9916
Jeff Johnson295189b2012-06-20 16:38:30 -07009917 /*Get vos context here bcoz vos_open requires it*/
9918 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
9919
Madan Mohan Koyyalamudi0b78e152012-11-28 15:46:51 -08009920 if(pVosContext == NULL)
9921 {
9922 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Failed vos_get_global_context",__func__);
9923 goto err_free_hdd_context;
9924 }
9925
Jeff Johnson295189b2012-06-20 16:38:30 -07009926 //Save the Global VOSS context in adapter context for future.
9927 pHddCtx->pvosContext = pVosContext;
9928
9929 //Save the adapter context in global context for future.
9930 ((VosContextType*)(pVosContext))->pHDDContext = (v_VOID_t*)pHddCtx;
9931
Jeff Johnson295189b2012-06-20 16:38:30 -07009932 pHddCtx->parent_dev = dev;
9933
9934 init_completion(&pHddCtx->full_pwr_comp_var);
9935 init_completion(&pHddCtx->standby_comp_var);
9936 init_completion(&pHddCtx->req_bmps_comp_var);
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07009937 init_completion(&pHddCtx->scan_info.scan_req_completion_event);
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -08009938 init_completion(&pHddCtx->scan_info.abortscan_event_var);
Kiet Lam46b8e4e2013-11-06 21:49:53 +05309939 init_completion(&pHddCtx->wiphy_channel_update_event);
Arun Kumar Khandavallie0b046d2014-03-01 21:54:25 +05309940 init_completion(&pHddCtx->ssr_comp_var);
Mahesh A Saptasagar67ab9222015-10-21 15:38:41 +05309941 init_completion(&pHddCtx->mc_sus_event_var);
9942 init_completion(&pHddCtx->tx_sus_event_var);
9943 init_completion(&pHddCtx->rx_sus_event_var);
9944
Amar Singhala49cbc52013-10-08 18:37:44 -07009945
mukul sharma4bd8d2e2015-08-13 20:33:25 +05309946 hdd_init_ll_stats_ctx(pHddCtx);
9947
Amar Singhala49cbc52013-10-08 18:37:44 -07009948#ifdef CONFIG_ENABLE_LINUX_REG
Amar Singhalfddc28c2013-09-05 13:03:40 -07009949 init_completion(&pHddCtx->linux_reg_req);
Amar Singhala49cbc52013-10-08 18:37:44 -07009950#else
9951 init_completion(&pHddCtx->driver_crda_req);
9952#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009953
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05309954#ifdef WLAN_FEATURE_EXTSCAN
9955 init_completion(&pHddCtx->ext_scan_context.response_event);
9956#endif /* WLAN_FEATURE_EXTSCAN */
9957
Kamath Vinayak4000c9a2013-08-23 14:24:27 +05309958 spin_lock_init(&pHddCtx->schedScan_lock);
9959
Jeff Johnson295189b2012-06-20 16:38:30 -07009960 hdd_list_init( &pHddCtx->hddAdapters, MAX_NUMBER_OF_ADAPTERS );
9961
Padma, Santhosh Kumar9cd38332015-11-17 12:18:10 +05309962 vos_init_delayed_work(&pHddCtx->spoof_mac_addr_work,
9963 hdd_processSpoofMacAddrRequest);
9964
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05309965#ifdef FEATURE_WLAN_TDLS
9966 /* tdls_lock is initialized before an hdd_open_adapter ( which is
9967 * invoked by other instances also) to protect the concurrent
9968 * access for the Adapters by TDLS module.
9969 */
9970 mutex_init(&pHddCtx->tdls_lock);
9971#endif
Siddharth Bhal76972212014-10-15 16:22:51 +05309972 mutex_init(&pHddCtx->spoofMacAddr.macSpoofingLock);
Mukul Sharma1fd6efd2015-02-14 00:29:14 +05309973 mutex_init(&pHddCtx->wmmLock);
9974
Srinivas Girigowda8bf64cb2015-09-30 19:50:09 +05309975 hdd_init_offloaded_packets_ctx(pHddCtx);
Agarwal Ashish1f422872014-07-22 00:11:55 +05309976 /* By default Strict Regulatory For FCC should be false */
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05309977
Agarwal Ashish1f422872014-07-22 00:11:55 +05309978 pHddCtx->nEnableStrictRegulatoryForFCC = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07009979 // Load all config first as TL config is needed during vos_open
9980 pHddCtx->cfg_ini = (hdd_config_t*) kmalloc(sizeof(hdd_config_t), GFP_KERNEL);
9981 if(pHddCtx->cfg_ini == NULL)
9982 {
9983 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Failed kmalloc hdd_config_t",__func__);
9984 goto err_free_hdd_context;
9985 }
9986
9987 vos_mem_zero(pHddCtx->cfg_ini, sizeof( hdd_config_t ));
9988
9989 // Read and parse the qcom_cfg.ini file
9990 status = hdd_parse_config_ini( pHddCtx );
9991 if ( VOS_STATUS_SUCCESS != status )
9992 {
9993 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: error parsing %s",
9994 __func__, WLAN_INI_FILE);
9995 goto err_config;
9996 }
Arif Hussaind5218912013-12-05 01:10:55 -08009997#ifdef MEMORY_DEBUG
9998 if (pHddCtx->cfg_ini->IsMemoryDebugSupportEnabled)
9999 vos_mem_init();
10000
10001 hddLog(VOS_TRACE_LEVEL_INFO, "%s: gEnableMemoryDebug=%d",
10002 __func__, pHddCtx->cfg_ini->IsMemoryDebugSupportEnabled);
10003#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010004
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +053010005 /* INI has been read, initialise the configuredMcastBcastFilter with
10006 * INI value as this will serve as the default value
10007 */
10008 pHddCtx->configuredMcastBcastFilter = pHddCtx->cfg_ini->mcastBcastFilterSetting;
10009 hddLog(VOS_TRACE_LEVEL_INFO, "Setting configuredMcastBcastFilter: %d",
10010 pHddCtx->cfg_ini->mcastBcastFilterSetting);
Gopichand Nakkalafce506f2013-07-03 23:55:16 +053010011
10012 if (false == hdd_is_5g_supported(pHddCtx))
10013 {
10014 //5Ghz is not supported.
10015 if (1 != pHddCtx->cfg_ini->nBandCapability)
10016 {
10017 hddLog(VOS_TRACE_LEVEL_INFO,
10018 "%s: Setting pHddCtx->cfg_ini->nBandCapability = 1", __func__);
10019 pHddCtx->cfg_ini->nBandCapability = 1;
10020 }
10021 }
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053010022
10023 /* If SNR Monitoring is enabled, FW has to parse all beacons
10024 * for calcaluting and storing the average SNR, so set Nth beacon
10025 * filter to 1 to enable FW to parse all the beaocons
10026 */
10027 if (1 == pHddCtx->cfg_ini->fEnableSNRMonitoring)
10028 {
10029 /* The log level is deliberately set to WARN as overriding
10030 * nthBeaconFilter to 1 will increase power cosumption and this
10031 * might just prove helpful to detect the power issue.
10032 */
10033 hddLog(VOS_TRACE_LEVEL_WARN,
10034 "%s: Setting pHddCtx->cfg_ini->nthBeaconFilter = 1", __func__);
10035 pHddCtx->cfg_ini->nthBeaconFilter = 1;
10036 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010037 /*
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +053010038 * cfg80211: Initialization ...
Jeff Johnson295189b2012-06-20 16:38:30 -070010039 */
Manjunathappa Prakasheec4ddf2014-01-13 18:23:51 -080010040 if (VOS_FTM_MODE != hdd_get_conparam())
Jeff Johnson295189b2012-06-20 16:38:30 -070010041 {
Manjunathappa Prakasheec4ddf2014-01-13 18:23:51 -080010042 if (0 < wlan_hdd_cfg80211_init(dev, wiphy, pHddCtx->cfg_ini))
10043 {
10044 hddLog(VOS_TRACE_LEVEL_FATAL,
10045 "%s: wlan_hdd_cfg80211_init return failure", __func__);
10046 goto err_config;
10047 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010048 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010049
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -080010050 // Update VOS trace levels based upon the cfg.ini
10051 hdd_vos_trace_enable(VOS_MODULE_ID_BAP,
10052 pHddCtx->cfg_ini->vosTraceEnableBAP);
10053 hdd_vos_trace_enable(VOS_MODULE_ID_TL,
10054 pHddCtx->cfg_ini->vosTraceEnableTL);
10055 hdd_vos_trace_enable(VOS_MODULE_ID_WDI,
10056 pHddCtx->cfg_ini->vosTraceEnableWDI);
10057 hdd_vos_trace_enable(VOS_MODULE_ID_HDD,
10058 pHddCtx->cfg_ini->vosTraceEnableHDD);
10059 hdd_vos_trace_enable(VOS_MODULE_ID_SME,
10060 pHddCtx->cfg_ini->vosTraceEnableSME);
10061 hdd_vos_trace_enable(VOS_MODULE_ID_PE,
10062 pHddCtx->cfg_ini->vosTraceEnablePE);
Katya Nigam70d68332013-09-16 16:49:45 +053010063 hdd_vos_trace_enable(VOS_MODULE_ID_PMC,
10064 pHddCtx->cfg_ini->vosTraceEnablePMC);
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -080010065 hdd_vos_trace_enable(VOS_MODULE_ID_WDA,
10066 pHddCtx->cfg_ini->vosTraceEnableWDA);
10067 hdd_vos_trace_enable(VOS_MODULE_ID_SYS,
10068 pHddCtx->cfg_ini->vosTraceEnableSYS);
10069 hdd_vos_trace_enable(VOS_MODULE_ID_VOSS,
10070 pHddCtx->cfg_ini->vosTraceEnableVOSS);
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -080010071 hdd_vos_trace_enable(VOS_MODULE_ID_SAP,
10072 pHddCtx->cfg_ini->vosTraceEnableSAP);
10073 hdd_vos_trace_enable(VOS_MODULE_ID_HDD_SOFTAP,
10074 pHddCtx->cfg_ini->vosTraceEnableHDDSAP);
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -080010075
Jeff Johnson295189b2012-06-20 16:38:30 -070010076 // Update WDI trace levels based upon the cfg.ini
10077 hdd_wdi_trace_enable(eWLAN_MODULE_DAL,
10078 pHddCtx->cfg_ini->wdiTraceEnableDAL);
10079 hdd_wdi_trace_enable(eWLAN_MODULE_DAL_CTRL,
10080 pHddCtx->cfg_ini->wdiTraceEnableCTL);
10081 hdd_wdi_trace_enable(eWLAN_MODULE_DAL_DATA,
10082 pHddCtx->cfg_ini->wdiTraceEnableDAT);
10083 hdd_wdi_trace_enable(eWLAN_MODULE_PAL,
10084 pHddCtx->cfg_ini->wdiTraceEnablePAL);
Jeff Johnson295189b2012-06-20 16:38:30 -070010085
Jeff Johnson88ba7742013-02-27 14:36:02 -080010086 if (VOS_FTM_MODE == hdd_get_conparam())
10087 {
Jeff Johnson295189b2012-06-20 16:38:30 -070010088 if ( VOS_STATUS_SUCCESS != wlan_hdd_ftm_open(pHddCtx) )
10089 {
10090 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: wlan_hdd_ftm_open Failed",__func__);
10091 goto err_free_hdd_context;
10092 }
10093 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: FTM driver loaded success fully",__func__);
Sachin Ahuja38ef5e02015-03-13 17:31:16 +053010094 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_NO_LOAD_UNLOAD_IN_PROGRESS;
c_hpothu2de0ef62014-04-15 16:16:15 +053010095 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, FALSE);
Jeff Johnson295189b2012-06-20 16:38:30 -070010096 return VOS_STATUS_SUCCESS;
Jeff Johnson88ba7742013-02-27 14:36:02 -080010097 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010098
Katya Nigame7b69a82015-04-28 15:24:06 +053010099 if( VOS_MONITOR_MODE == hdd_get_conparam())
10100 {
10101 if ( VOS_STATUS_SUCCESS != wlan_hdd_mon_open(pHddCtx))
10102 {
10103 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: wlan_hdd_mon_open Failed",__func__);
10104 goto err_free_hdd_context;
10105 }
10106 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Driver loaded in Monitor Mode",__func__);
10107 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_NO_LOAD_UNLOAD_IN_PROGRESS;
10108 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, FALSE);
10109 return VOS_STATUS_SUCCESS;
10110 }
10111
Jeff Johnson88ba7742013-02-27 14:36:02 -080010112 //Open watchdog module
Jeff Johnson295189b2012-06-20 16:38:30 -070010113 if(pHddCtx->cfg_ini->fIsLogpEnabled)
10114 {
10115 status = vos_watchdog_open(pVosContext,
10116 &((VosContextType*)pVosContext)->vosWatchdog, sizeof(VosWatchdogContext));
10117
10118 if(!VOS_IS_STATUS_SUCCESS( status ))
10119 {
10120 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: vos_watchdog_open failed",__func__);
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +053010121 goto err_wdclose;
Jeff Johnson295189b2012-06-20 16:38:30 -070010122 }
10123 }
10124
10125 pHddCtx->isLogpInProgress = FALSE;
10126 vos_set_logp_in_progress(VOS_MODULE_ID_VOSS, FALSE);
10127
Amar Singhala49cbc52013-10-08 18:37:44 -070010128#ifdef CONFIG_ENABLE_LINUX_REG
Amar Singhal0a402232013-10-11 20:57:16 -070010129 /* initialize the NV module. This is required so that
10130 we can initialize the channel information in wiphy
10131 from the NV.bin data. The channel information in
10132 wiphy needs to be initialized before wiphy registration */
10133
10134 status = vos_nv_open();
10135 if (!VOS_IS_STATUS_SUCCESS(status))
10136 {
10137 /* NV module cannot be initialized */
10138 hddLog( VOS_TRACE_LEVEL_FATAL,
10139 "%s: vos_nv_open failed", __func__);
Vinay Krishna Eranna2025d892014-09-18 16:51:42 +053010140 goto err_wdclose;
Amar Singhal0a402232013-10-11 20:57:16 -070010141 }
10142
10143 status = vos_init_wiphy_from_nv_bin();
10144 if (!VOS_IS_STATUS_SUCCESS(status))
10145 {
10146 /* NV module cannot be initialized */
10147 hddLog( VOS_TRACE_LEVEL_FATAL,
10148 "%s: vos_init_wiphy failed", __func__);
10149 goto err_vos_nv_close;
10150 }
10151
Amar Singhala49cbc52013-10-08 18:37:44 -070010152#endif
Mahesh A Saptasagarc3ed0122016-01-19 16:45:11 +053010153 //Initialize the nlink service
10154 if(nl_srv_init() != 0)
10155 {
10156 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: nl_srv_init failed", __func__);
10157 goto err_vos_nv_close;
10158 }
10159
10160#ifdef WLAN_KD_READY_NOTIFIER
10161 pHddCtx->kd_nl_init = 1;
10162#endif /* WLAN_KD_READY_NOTIFIER */
10163
Girish Gowlibf0e1ab2015-01-19 16:05:16 +053010164 vos_set_roam_delay_stats_enabled(pHddCtx->cfg_ini->gEnableRoamDelayStats);
Arun Kumar Khandavalliebb19482014-03-25 13:56:53 +053010165 status = vos_open( &pVosContext, pHddCtx->parent_dev);
Jeff Johnson295189b2012-06-20 16:38:30 -070010166 if ( !VOS_IS_STATUS_SUCCESS( status ))
10167 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -080010168 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: vos_open failed", __func__);
Mahesh A Saptasagarc3ed0122016-01-19 16:45:11 +053010169 goto err_nl_srv;
Jeff Johnson295189b2012-06-20 16:38:30 -070010170 }
10171
Jeff Johnson295189b2012-06-20 16:38:30 -070010172 pHddCtx->hHal = (tHalHandle)vos_get_context( VOS_MODULE_ID_SME, pVosContext );
10173
10174 if ( NULL == pHddCtx->hHal )
10175 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -080010176 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: HAL context is null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070010177 goto err_vosclose;
10178 }
10179
Jeff Johnsonbc676b42013-02-14 16:04:08 -080010180 status = vos_preStart( pHddCtx->pvosContext );
10181 if ( !VOS_IS_STATUS_SUCCESS( status ) )
10182 {
10183 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: vos_preStart failed", __func__);
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053010184 goto err_vosclose;
Jeff Johnsonbc676b42013-02-14 16:04:08 -080010185 }
Jeff Johnsone7245742012-09-05 17:12:55 -070010186
Arif Hussaineaf68602013-12-30 23:10:44 -080010187 if (0 == enable_dfs_chan_scan || 1 == enable_dfs_chan_scan)
10188 {
10189 pHddCtx->cfg_ini->enableDFSChnlScan = enable_dfs_chan_scan;
10190 hddLog(VOS_TRACE_LEVEL_INFO, "%s: module enable_dfs_chan_scan set to %d",
10191 __func__, enable_dfs_chan_scan);
10192 }
10193 if (0 == enable_11d || 1 == enable_11d)
10194 {
10195 pHddCtx->cfg_ini->Is11dSupportEnabled = enable_11d;
10196 hddLog(VOS_TRACE_LEVEL_INFO, "%s: module enable_11d set to %d",
10197 __func__, enable_11d);
10198 }
10199
Jeff Johnsonbc676b42013-02-14 16:04:08 -080010200 /* Note that the vos_preStart() sequence triggers the cfg download.
10201 The cfg download must occur before we update the SME config
10202 since the SME config operation must access the cfg database */
Jeff Johnson295189b2012-06-20 16:38:30 -070010203 status = hdd_set_sme_config( pHddCtx );
10204
10205 if ( VOS_STATUS_SUCCESS != status )
10206 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -080010207 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Failed hdd_set_sme_config", __func__);
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053010208 goto err_vosclose;
Jeff Johnsonbc676b42013-02-14 16:04:08 -080010209 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010210
Jeff Johnson295189b2012-06-20 16:38:30 -070010211 /* In the integrated architecture we update the configuration from
10212 the INI file and from NV before vOSS has been started so that
10213 the final contents are available to send down to the cCPU */
10214
10215 // Apply the cfg.ini to cfg.dat
10216 if (FALSE == hdd_update_config_dat(pHddCtx))
10217 {
10218 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: config update failed",__func__ );
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053010219 goto err_vosclose;
Jeff Johnson295189b2012-06-20 16:38:30 -070010220 }
10221
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +053010222 // Get mac addr from platform driver
10223 ret = wcnss_get_wlan_mac_address((char*)&mac_addr.bytes);
10224
10225 if ((0 == ret) && (!vos_is_macaddr_zero(&mac_addr)))
Jeff Johnson295189b2012-06-20 16:38:30 -070010226 {
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +053010227 /* Store the mac addr for first interface */
10228 pHddCtx->cfg_ini->intfMacAddr[0] = mac_addr;
10229
10230 hddLog(VOS_TRACE_LEVEL_ERROR,
10231 "%s: WLAN Mac Addr: "
10232 MAC_ADDRESS_STR, __func__,
10233 MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[0].bytes));
10234
10235 /* Here, passing Arg2 as 1 because we do not want to change the
10236 last 3 bytes (means non OUI bytes) of first interface mac
10237 addr.
10238 */
10239 if (0 != hdd_generate_iface_mac_addr_auto(pHddCtx, 1, mac_addr))
10240 {
10241 hddLog(VOS_TRACE_LEVEL_ERROR,
10242 "%s: Failed to generate wlan interface mac addr "
10243 "using MAC from ini file ", __func__);
10244 }
10245 }
10246 else if (VOS_STATUS_SUCCESS != hdd_update_config_from_nv(pHddCtx))
10247 {
10248 // Apply the NV to cfg.dat
10249 /* Prima Update MAC address only at here */
Jeff Johnson295189b2012-06-20 16:38:30 -070010250#ifdef WLAN_AUTOGEN_MACADDR_FEATURE
10251 /* There was not a valid set of MAC Addresses in NV. See if the
10252 default addresses were modified by the cfg.ini settings. If so,
10253 we'll use them, but if not, we'll autogenerate a set of MAC
10254 addresses based upon the device serial number */
10255
10256 static const v_MACADDR_t default_address =
10257 {{0x00, 0x0A, 0xF5, 0x89, 0x89, 0xFF}};
Jeff Johnson295189b2012-06-20 16:38:30 -070010258
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +053010259 if (0 == memcmp(&default_address, &pHddCtx->cfg_ini->intfMacAddr[0],
10260 sizeof(default_address)))
Jeff Johnson295189b2012-06-20 16:38:30 -070010261 {
10262 /* cfg.ini has the default address, invoke autogen logic */
10263
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +053010264 /* Here, passing Arg2 as 0 because we want to change the
10265 last 3 bytes (means non OUI bytes) of all the interfaces
10266 mac addr.
10267 */
10268 if (0 != hdd_generate_iface_mac_addr_auto(pHddCtx, 0,
10269 default_address))
Jeff Johnson295189b2012-06-20 16:38:30 -070010270 {
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +053010271 hddLog(VOS_TRACE_LEVEL_ERROR,
10272 "%s: Failed to generate wlan interface mac addr "
10273 "using MAC from ini file " MAC_ADDRESS_STR, __func__,
10274 MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[0].bytes));
Jeff Johnson295189b2012-06-20 16:38:30 -070010275 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010276 }
10277 else
10278#endif //WLAN_AUTOGEN_MACADDR_FEATURE
10279 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -080010280 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070010281 "%s: Invalid MAC address in NV, using MAC from ini file "
10282 MAC_ADDRESS_STR, __func__,
10283 MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[0].bytes));
10284 }
10285 }
10286 {
10287 eHalStatus halStatus;
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +053010288
10289 /* Set the MAC Address Currently this is used by HAL to
10290 * add self sta. Remove this once self sta is added as
10291 * part of session open.
10292 */
Jeff Johnson295189b2012-06-20 16:38:30 -070010293 halStatus = cfgSetStr( pHddCtx->hHal, WNI_CFG_STA_ID,
10294 (v_U8_t *)&pHddCtx->cfg_ini->intfMacAddr[0],
10295 sizeof( pHddCtx->cfg_ini->intfMacAddr[0]) );
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +053010296
Jeff Johnson295189b2012-06-20 16:38:30 -070010297 if (!HAL_STATUS_SUCCESS( halStatus ))
10298 {
10299 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Failed to set MAC Address. "
10300 "HALStatus is %08d [x%08x]",__func__, halStatus, halStatus );
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053010301 goto err_vosclose;
Jeff Johnson295189b2012-06-20 16:38:30 -070010302 }
10303 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010304
10305 /*Start VOSS which starts up the SME/MAC/HAL modules and everything else
10306 Note: Firmware image will be read and downloaded inside vos_start API */
10307 status = vos_start( pHddCtx->pvosContext );
10308 if ( !VOS_IS_STATUS_SUCCESS( status ) )
10309 {
10310 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: vos_start failed",__func__);
Hanumantha Reddy Pothulabd9601a2016-02-12 13:22:27 +053010311 if (isSsrPanicOnFailure())
10312 VOS_BUG(0);
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053010313 goto err_vosclose;
Jeff Johnson295189b2012-06-20 16:38:30 -070010314 }
10315
Leo Chang6cec3e22014-01-21 15:33:49 -080010316#ifdef FEATURE_WLAN_CH_AVOID
10317 /* Plug in avoid channel notification callback
10318 * This should happen before ADD_SELF_STA
10319 * FW will send first IND with ADD_SELF_STA REQ from host */
Pradeep Reddy POTTETI5c2e16d2014-06-27 16:47:38 +053010320
10321 /* check the Channel Avoidance is enabled */
10322 if (TRUE == pHddCtx->cfg_ini->fenableCHAvoidance)
10323 {
10324 sme_AddChAvoidCallback(pHddCtx->hHal,
10325 hdd_hostapd_ch_avoid_cb);
10326 }
Leo Chang6cec3e22014-01-21 15:33:49 -080010327#endif /* FEATURE_WLAN_CH_AVOID */
10328
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -070010329 /* Exchange capability info between Host and FW and also get versioning info from FW */
10330 hdd_exchange_version_and_caps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -070010331
Agarwal Ashishad9281b2014-06-10 14:57:30 +053010332#ifdef CONFIG_ENABLE_LINUX_REG
10333 status = wlan_hdd_init_channels(pHddCtx);
10334 if ( !VOS_IS_STATUS_SUCCESS( status ) )
10335 {
10336 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: wlan_hdd_init_channels failed",
10337 __func__);
10338 goto err_vosstop;
10339 }
10340#endif
10341
Jeff Johnson295189b2012-06-20 16:38:30 -070010342 status = hdd_post_voss_start_config( pHddCtx );
10343 if ( !VOS_IS_STATUS_SUCCESS( status ) )
10344 {
10345 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hdd_post_voss_start_config failed",
10346 __func__);
10347 goto err_vosstop;
10348 }
Amar Singhala49cbc52013-10-08 18:37:44 -070010349
10350#ifndef CONFIG_ENABLE_LINUX_REG
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +053010351 wlan_hdd_cfg80211_update_reg_info( wiphy );
10352
10353 /* registration of wiphy dev with cfg80211 */
10354 if (0 > wlan_hdd_cfg80211_register(wiphy))
10355 {
10356 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy register failed", __func__);
10357 goto err_vosstop;
10358 }
Amar Singhala49cbc52013-10-08 18:37:44 -070010359#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010360
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053010361#ifdef CONFIG_ENABLE_LINUX_REG
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053010362 /* registration of wiphy dev with cfg80211 */
10363 if (0 > wlan_hdd_cfg80211_register(wiphy))
10364 {
10365 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy register failed", __func__);
10366 goto err_vosstop;
10367 }
10368
Agarwal Ashish6db9d532014-09-30 18:19:10 +053010369 status = wlan_hdd_init_channels_for_cc(pHddCtx, INIT);
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053010370 if ( !VOS_IS_STATUS_SUCCESS( status ) )
10371 {
10372 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: wlan_hdd_init_channels_for_cc failed",
10373 __func__);
10374 goto err_unregister_wiphy;
10375 }
10376#endif
10377
c_hpothu4a298be2014-12-22 21:12:51 +053010378 wcnss_wlan_set_drvdata(pHddCtx->parent_dev, pHddCtx);
10379
Jeff Johnson295189b2012-06-20 16:38:30 -070010380 if (VOS_STA_SAP_MODE == hdd_get_conparam())
10381 {
10382 pAdapter = hdd_open_adapter( pHddCtx, WLAN_HDD_SOFTAP, "softap.%d",
10383 wlan_hdd_get_intf_addr(pHddCtx), FALSE );
10384 }
10385 else
10386 {
Jeff Johnson295189b2012-06-20 16:38:30 -070010387 pAdapter = hdd_open_adapter( pHddCtx, WLAN_HDD_INFRA_STATION, "wlan%d",
10388 wlan_hdd_get_intf_addr(pHddCtx), FALSE );
10389 if (pAdapter != NULL)
10390 {
Katya Nigama7d81d72014-11-12 12:44:34 +053010391 if (pHddCtx->cfg_ini->isP2pDeviceAddrAdministrated && !(pHddCtx->cfg_ini->intfMacAddr[0].bytes[0] & 0x02))
Jeff Johnson295189b2012-06-20 16:38:30 -070010392 {
Gopichand Nakkala49f96f62013-02-06 14:38:17 +053010393 vos_mem_copy( pHddCtx->p2pDeviceAddress.bytes,
10394 pHddCtx->cfg_ini->intfMacAddr[0].bytes,
10395 sizeof(tSirMacAddr));
Madan Mohan Koyyalamudiedfc1b72012-10-18 20:25:55 -070010396
Gopichand Nakkala49f96f62013-02-06 14:38:17 +053010397 /* Generate the P2P Device Address. This consists of the device's
10398 * primary MAC address with the locally administered bit set.
10399 */
10400 pHddCtx->p2pDeviceAddress.bytes[0] |= 0x02;
Jeff Johnsone7245742012-09-05 17:12:55 -070010401 }
10402 else
10403 {
Gopichand Nakkala49f96f62013-02-06 14:38:17 +053010404 tANI_U8* p2p_dev_addr = wlan_hdd_get_intf_addr(pHddCtx);
10405 if (p2p_dev_addr != NULL)
10406 {
10407 vos_mem_copy(&pHddCtx->p2pDeviceAddress.bytes[0],
10408 p2p_dev_addr, VOS_MAC_ADDR_SIZE);
10409 }
10410 else
10411 {
10412 hddLog(VOS_TRACE_LEVEL_FATAL,
10413 "%s: Failed to allocate mac_address for p2p_device",
10414 __func__);
10415 goto err_close_adapter;
10416 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010417 }
Jeff Johnsone7245742012-09-05 17:12:55 -070010418
10419 pP2pAdapter = hdd_open_adapter( pHddCtx, WLAN_HDD_P2P_DEVICE, "p2p%d",
10420 &pHddCtx->p2pDeviceAddress.bytes[0], FALSE );
10421 if ( NULL == pP2pAdapter )
10422 {
10423 hddLog(VOS_TRACE_LEVEL_FATAL,
10424 "%s: Failed to do hdd_open_adapter for P2P Device Interface",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070010425 __func__);
Jeff Johnsone7245742012-09-05 17:12:55 -070010426 goto err_close_adapter;
10427 }
Jeff Johnsone7245742012-09-05 17:12:55 -070010428 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010429 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010430
10431 if( pAdapter == NULL )
10432 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -080010433 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: hdd_open_adapter failed", __func__);
10434 goto err_close_adapter;
Jeff Johnson295189b2012-06-20 16:38:30 -070010435 }
Jeff Johnsone7245742012-09-05 17:12:55 -070010436
Arif Hussain66559122013-11-21 10:11:40 -080010437 if (country_code)
10438 {
10439 eHalStatus ret;
Arif Hussaincb607082013-12-20 11:57:42 -080010440 INIT_COMPLETION(pAdapter->change_country_code);
Arif Hussain66559122013-11-21 10:11:40 -080010441 hdd_checkandupdate_dfssetting(pAdapter, country_code);
10442#ifndef CONFIG_ENABLE_LINUX_REG
10443 hdd_checkandupdate_phymode(pAdapter, country_code);
10444#endif
Arif Hussaineaf68602013-12-30 23:10:44 -080010445 ret = sme_ChangeCountryCode(pHddCtx->hHal,
10446 (void *)(tSmeChangeCountryCallback)
10447 wlan_hdd_change_country_code_callback,
Arif Hussain66559122013-11-21 10:11:40 -080010448 country_code,
10449 pAdapter, pHddCtx->pvosContext,
Abhishek Singha306a442013-11-07 18:39:01 +053010450 eSIR_TRUE, eSIR_TRUE);
Arif Hussain66559122013-11-21 10:11:40 -080010451 if (eHAL_STATUS_SUCCESS == ret)
10452 {
Arif Hussaincb607082013-12-20 11:57:42 -080010453 ret = wait_for_completion_interruptible_timeout(
10454 &pAdapter->change_country_code,
10455 msecs_to_jiffies(WLAN_WAIT_TIME_COUNTRY));
10456
10457 if (0 >= ret)
10458 {
10459 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
10460 "%s: SME while setting country code timed out", __func__);
10461 }
Arif Hussain66559122013-11-21 10:11:40 -080010462 }
10463 else
10464 {
Arif Hussaincb607082013-12-20 11:57:42 -080010465 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
10466 "%s: SME Change Country code from module param fail ret=%d",
10467 __func__, ret);
Arif Hussain66559122013-11-21 10:11:40 -080010468 }
10469 }
10470
Jeff Johnson295189b2012-06-20 16:38:30 -070010471#ifdef WLAN_BTAMP_FEATURE
10472 vStatus = WLANBAP_Open(pVosContext);
10473 if(!VOS_IS_STATUS_SUCCESS(vStatus))
10474 {
10475 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
10476 "%s: Failed to open BAP",__func__);
Jeff Johnsone7245742012-09-05 17:12:55 -070010477 goto err_close_adapter;
Jeff Johnson295189b2012-06-20 16:38:30 -070010478 }
10479
10480 vStatus = BSL_Init(pVosContext);
10481 if(!VOS_IS_STATUS_SUCCESS(vStatus))
10482 {
10483 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
10484 "%s: Failed to Init BSL",__func__);
10485 goto err_bap_close;
10486 }
10487 vStatus = WLANBAP_Start(pVosContext);
10488 if (!VOS_IS_STATUS_SUCCESS(vStatus))
10489 {
10490 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
10491 "%s: Failed to start TL",__func__);
10492 goto err_bap_close;
10493 }
10494
10495 pConfig = pHddCtx->cfg_ini;
10496 btAmpConfig.ucPreferredChannel = pConfig->preferredChannel;
10497 status = WLANBAP_SetConfig(&btAmpConfig);
10498
10499#endif //WLAN_BTAMP_FEATURE
Jeff Johnsone7245742012-09-05 17:12:55 -070010500
Mihir Shete9c238772014-10-15 14:35:16 +053010501 /*
10502 * UapsdMask is 0xf if U-APSD is enbaled for all AC's...
10503 * The value of CFG_QOS_WMM_UAPSD_MASK_DEFAULT is 0xaa(Magic Value)
10504 * which is greater than 0xf. So the below check is safe to make
10505 * sure that there is no entry for UapsdMask in the ini
10506 */
10507 if (CFG_QOS_WMM_UAPSD_MASK_DEFAULT == pHddCtx->cfg_ini->UapsdMask)
10508 {
10509 if(IS_DYNAMIC_WMM_PS_ENABLED)
10510 {
10511 hddLog(VOS_TRACE_LEVEL_DEBUG,"%s: Enable UAPSD for VI & VO",
10512 __func__);
10513 pHddCtx->cfg_ini->UapsdMask =
10514 CFG_QOS_WMM_UAPSD_MASK_DYMANIC_WMM_PS_DEFAULT;
10515 }
10516 else
10517 {
10518 hddLog(VOS_TRACE_LEVEL_DEBUG,"%s: Do not enable UAPSD",
10519 __func__);
10520 pHddCtx->cfg_ini->UapsdMask =
10521 CFG_QOS_WMM_UAPSD_MASK_LEGACY_WMM_PS_DEFAULT;
10522 }
10523 }
10524
Varun Reddy Yeturud0a3f252013-04-15 21:58:13 -070010525#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
10526 if(!(IS_ROAM_SCAN_OFFLOAD_FEATURE_ENABLE))
10527 {
10528 hddLog(VOS_TRACE_LEVEL_DEBUG,"%s: ROAM_SCAN_OFFLOAD Feature not supported",__func__);
10529 pHddCtx->cfg_ini->isRoamOffloadScanEnabled = 0;
10530 sme_UpdateRoamScanOffloadEnabled((tHalHandle)(pHddCtx->hHal),
10531 pHddCtx->cfg_ini->isRoamOffloadScanEnabled);
10532 }
10533#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010534
Agarwal Ashish4b87f922014-06-18 03:03:21 +053010535 wlan_hdd_tdls_init(pHddCtx);
10536
Masti, Narayanraddi26378462016-01-05 18:20:28 +053010537 wlan_hdd_init_deinit_defer_scan_context(&pHddCtx->scan_ctxt);
10538
10539 vos_init_delayed_work(&pHddCtx->scan_ctxt.scan_work,
10540 wlan_hdd_schedule_defer_scan);
10541
Mihir Shetefc7ff5b2014-01-27 11:30:05 +053010542 sme_Register11dScanDoneCallback(pHddCtx->hHal, hdd_11d_scan_done);
10543
Jeff Johnson295189b2012-06-20 16:38:30 -070010544 /* Register with platform driver as client for Suspend/Resume */
10545 status = hddRegisterPmOps(pHddCtx);
10546 if ( !VOS_IS_STATUS_SUCCESS( status ) )
10547 {
10548 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddRegisterPmOps failed",__func__);
10549#ifdef WLAN_BTAMP_FEATURE
10550 goto err_bap_stop;
10551#else
Jeff Johnsone7245742012-09-05 17:12:55 -070010552 goto err_close_adapter;
Jeff Johnson295189b2012-06-20 16:38:30 -070010553#endif //WLAN_BTAMP_FEATURE
10554 }
10555
Yue Ma0d4891e2013-08-06 17:01:45 -070010556 /* Open debugfs interface */
10557 if (VOS_STATUS_SUCCESS != hdd_debugfs_init(pAdapter))
10558 {
10559 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
10560 "%s: hdd_debugfs_init failed!", __func__);
Yue Ma0d4891e2013-08-06 17:01:45 -070010561 }
10562
Jeff Johnson295189b2012-06-20 16:38:30 -070010563 /* Register TM level change handler function to the platform */
10564 status = hddDevTmRegisterNotifyCallback(pHddCtx);
10565 if ( !VOS_IS_STATUS_SUCCESS( status ) )
10566 {
10567 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddDevTmRegisterNotifyCallback failed",__func__);
10568 goto err_unregister_pmops;
10569 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010570
Jeff Johnson295189b2012-06-20 16:38:30 -070010571 // register net device notifier for device change notification
10572 ret = register_netdevice_notifier(&hdd_netdev_notifier);
10573
10574 if(ret < 0)
10575 {
10576 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: register_netdevice_notifier failed",__func__);
Siddharth Bhalcd92b782015-06-29 12:25:40 +053010577 goto err_unregister_pmops;
Jeff Johnson295189b2012-06-20 16:38:30 -070010578 }
10579
Jeff Johnson295189b2012-06-20 16:38:30 -070010580 //Initialize the BTC service
10581 if(btc_activate_service(pHddCtx) != 0)
10582 {
10583 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: btc_activate_service failed",__func__);
Mahesh A Saptasagarc3ed0122016-01-19 16:45:11 +053010584 goto err_reg_netdev;
Jeff Johnson295189b2012-06-20 16:38:30 -070010585 }
10586
Padma, Santhosh Kumar2762e9d2015-10-20 15:02:57 +053010587#ifdef FEATURE_OEM_DATA_SUPPORT
10588 //Initialize the OEM service
10589 if (oem_activate_service(pHddCtx) != 0)
10590 {
10591 hddLog(VOS_TRACE_LEVEL_FATAL,
10592 "%s: oem_activate_service failed", __func__);
Mahesh A Saptasagarc3ed0122016-01-19 16:45:11 +053010593 goto err_reg_netdev;
Padma, Santhosh Kumar2762e9d2015-10-20 15:02:57 +053010594 }
10595#endif
10596
Jeff Johnson295189b2012-06-20 16:38:30 -070010597#ifdef PTT_SOCK_SVC_ENABLE
10598 //Initialize the PTT service
10599 if(ptt_sock_activate_svc(pHddCtx) != 0)
10600 {
10601 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: ptt_sock_activate_svc failed",__func__);
Mahesh A Saptasagarc3ed0122016-01-19 16:45:11 +053010602 goto err_reg_netdev;
Jeff Johnson295189b2012-06-20 16:38:30 -070010603 }
10604#endif
10605
Vinay Krishna Erannad938c422014-03-10 17:14:21 +053010606#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
10607 if(pHddCtx->cfg_ini && pHddCtx->cfg_ini->wlanLoggingEnable)
10608 {
Deepthi Gowri78083a32014-11-04 12:55:51 +053010609 if(wlan_logging_sock_activate_svc(
10610 pHddCtx->cfg_ini->wlanLoggingFEToConsole,
Sushant Kaushik33200572015-08-05 16:46:20 +053010611 pHddCtx->cfg_ini->wlanLoggingNumBuf,
10612 pHddCtx->cfg_ini->wlanPerPktStatsLogEnable,
10613 pHddCtx->cfg_ini->wlanPerPktStatsNumBuf))
Deepthi Gowri78083a32014-11-04 12:55:51 +053010614 {
10615 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wlan_logging_sock_activate_svc"
10616 " failed", __func__);
Mahesh A Saptasagarc3ed0122016-01-19 16:45:11 +053010617 goto err_reg_netdev;
Deepthi Gowri78083a32014-11-04 12:55:51 +053010618 }
10619 //TODO: To Remove enableDhcpDebug and use gEnableDebugLog for
10620 //EAPOL and DHCP
Sachin Ahuja8c65f382014-12-12 15:34:21 +053010621 if (!pHddCtx->cfg_ini->gEnableDebugLog)
10622 pHddCtx->cfg_ini->gEnableDebugLog =
Sushant Kaushik6e4e2bc2015-10-05 17:23:07 +053010623 VOS_PKT_PROTO_TYPE_EAPOL | VOS_PKT_PROTO_TYPE_DHCP |
10624 VOS_PKT_PROTO_TYPE_ARP;
Vinay Krishna Erannad938c422014-03-10 17:14:21 +053010625 }
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053010626
Siddharth Bhald1be97f2015-05-27 22:39:59 +053010627 if (pHddCtx->cfg_ini->wlanLoggingEnable &&
10628 (pHddCtx->cfg_ini->enableFWLogging ||
Siddharth Bhaldb963232015-06-25 19:34:35 +053010629 pHddCtx->cfg_ini->enableMgmtLogging ||
c_manjeecfd1efb2015-09-25 19:32:34 +053010630 pHddCtx->cfg_ini->enableContFWLogging ||
10631 pHddCtx->cfg_ini->enableFwrMemDump )
10632 )
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053010633 {
Siddharth Bhald1be97f2015-05-27 22:39:59 +053010634 hdd_init_frame_logging(pHddCtx);
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053010635 }
10636 else
10637 {
Siddharth Bhald1be97f2015-05-27 22:39:59 +053010638 hddLog(VOS_TRACE_LEVEL_INFO, FL("Logging disabled in ini"));
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053010639 }
10640
Vinay Krishna Erannad938c422014-03-10 17:14:21 +053010641#endif
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053010642
10643
Sushant Kaushik215778f2015-05-21 14:05:36 +053010644 if (vos_is_multicast_logging())
10645 wlan_logging_set_log_level();
10646
Jeff Johnson295189b2012-06-20 16:38:30 -070010647 hdd_register_mcast_bcast_filter(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -070010648 if (VOS_STA_SAP_MODE != hdd_get_conparam())
Jeff Johnson295189b2012-06-20 16:38:30 -070010649 {
Madan Mohan Koyyalamudic537df22012-10-22 15:07:08 -070010650 /* Action frame registered in one adapter which will
10651 * applicable to all interfaces
10652 */
Agarwal Ashish8fa0e9a2014-05-23 00:40:12 +053010653 wlan_hdd_cfg80211_register_frames(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070010654 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010655
10656 mutex_init(&pHddCtx->sap_lock);
Mahesh A Saptasagar60627942014-10-13 13:55:14 +053010657 mutex_init(&pHddCtx->roc_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -070010658
Jeff Johnsone7245742012-09-05 17:12:55 -070010659#ifdef WLAN_FEATURE_HOLD_RX_WAKELOCK
10660 /* Initialize the wake lcok */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053010661 vos_wake_lock_init(&pHddCtx->rx_wake_lock,
Jeff Johnsone7245742012-09-05 17:12:55 -070010662 "qcom_rx_wakelock");
Sushant Kaushik83392fa2015-05-05 17:44:40 +053010663
Jeff Johnsone7245742012-09-05 17:12:55 -070010664#endif
Madan Mohan Koyyalamudi69fc3ad2012-11-28 16:04:56 -080010665 /* Initialize the wake lcok */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053010666 vos_wake_lock_init(&pHddCtx->sap_wake_lock,
Madan Mohan Koyyalamudi69fc3ad2012-11-28 16:04:56 -080010667 "qcom_sap_wakelock");
Sushant Kaushik83392fa2015-05-05 17:44:40 +053010668
Jeff Johnsone7245742012-09-05 17:12:55 -070010669
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070010670 vos_event_init(&pHddCtx->scan_info.scan_finished_event);
10671 pHddCtx->scan_info.scan_pending_option = WEXT_SCAN_PENDING_GIVEUP;
Jeff Johnson295189b2012-06-20 16:38:30 -070010672
Katya Nigam5c306ea2014-06-19 15:39:54 +053010673 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_NO_LOAD_UNLOAD_IN_PROGRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -070010674 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, FALSE);
Sushant Kaushik83392fa2015-05-05 17:44:40 +053010675 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_DRIVER_INIT);
Katya Nigam5c306ea2014-06-19 15:39:54 +053010676
10677#ifdef FEATURE_WLAN_SCAN_PNO
10678 /*SME must send channel update configuration to RIVA*/
10679 sme_UpdateChannelConfig(pHddCtx->hHal);
10680#endif
Abhishek Singhf644b272014-08-21 02:59:39 +053010681 /* Send the update default channel list to the FW*/
10682 sme_UpdateChannelList(pHddCtx->hHal);
Mukul Sharma45063942015-04-01 20:07:59 +053010683
10684 /* Fwr capabilities received, Set the Dot11 mode */
Abhishek Singh41ebce12016-02-03 10:43:21 +053010685 sme_SetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter),
10686 hdd_cfg_xlate_to_csr_phy_mode(pHddCtx->cfg_ini->dot11Mode));
Mukul Sharma45063942015-04-01 20:07:59 +053010687 sme_SetDefDot11Mode(pHddCtx->hHal);
10688
Abhishek Singha306a442013-11-07 18:39:01 +053010689#ifndef CONFIG_ENABLE_LINUX_REG
10690 /*updating wiphy so that regulatory user hints can be processed*/
10691 if (wiphy)
10692 {
10693 regulatory_hint(wiphy, "00");
10694 }
10695#endif
Jeff Johnsone7245742012-09-05 17:12:55 -070010696 // Initialize the restart logic
10697 wlan_hdd_restart_init(pHddCtx);
Chilam NG571c65a2013-01-19 12:27:36 +053010698
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -070010699 //Register the traffic monitor timer now
10700 if ( pHddCtx->cfg_ini->dynSplitscan)
10701 {
10702 vos_timer_init(&pHddCtx->tx_rx_trafficTmr,
10703 VOS_TIMER_TYPE_SW,
10704 hdd_tx_rx_pkt_cnt_stat_timer_handler,
10705 (void *)pHddCtx);
10706 }
Srinivas Dasari030bad32015-02-18 23:23:54 +053010707 wlan_hdd_cfg80211_nan_init(pHddCtx);
10708
Bhargav Shahd0715912015-10-01 18:17:37 +053010709 mutex_init(&pHddCtx->cur_rx_level_lock);
10710 vos_timer_init(&pHddCtx->delack_timer, VOS_TIMER_TYPE_SW,
10711 hdd_tcp_delack_compute_function,(void *)pHddCtx);
Masti, Narayanraddi44b0db02015-12-22 11:54:35 +053010712 vos_timer_init(&pHddCtx->tdls_source_timer, VOS_TIMER_TYPE_SW,
10713 wlan_hdd_change_tdls_mode, (void *)pHddCtx);
Bhargav Shahd0715912015-10-01 18:17:37 +053010714
Dino Mycle6fb96c12014-06-10 11:52:40 +053010715#ifdef WLAN_FEATURE_EXTSCAN
10716 sme_EXTScanRegisterCallback(pHddCtx->hHal,
10717 wlan_hdd_cfg80211_extscan_callback,
10718 pHddCtx);
10719#endif /* WLAN_FEATURE_EXTSCAN */
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +053010720
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053010721#ifdef FEATURE_OEM_DATA_SUPPORT
10722 sme_OemDataRegisterCallback(pHddCtx->hHal,
10723 wlan_hdd_cfg80211_oemdata_callback,
10724 pHddCtx);
10725#endif /* FEATURE_OEM_DATA_SUPPORT */
10726
Gupta, Kapil7c34b322015-09-30 13:12:35 +053010727 sme_set_rssi_threshold_breached_cb(pHddCtx->hHal, hdd_rssi_threshold_breached_cb);
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +053010728#ifdef WLAN_NS_OFFLOAD
10729 // Register IPv6 notifier to notify if any change in IP
10730 // So that we can reconfigure the offload parameters
10731 pHddCtx->ipv6_notifier.notifier_call = wlan_hdd_ipv6_changed;
10732 ret = register_inet6addr_notifier(&pHddCtx->ipv6_notifier);
10733 if (ret)
10734 {
Ratheesh S P36dbc932015-08-07 14:28:57 +053010735 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to register IPv6 notifier"));
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +053010736 }
10737 else
10738 {
Ratheesh S P36dbc932015-08-07 14:28:57 +053010739 hddLog(VOS_TRACE_LEVEL_INFO, FL("Registered IPv6 notifier"));
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +053010740 }
10741#endif
10742
10743 // Register IPv4 notifier to notify if any change in IP
10744 // So that we can reconfigure the offload parameters
10745 pHddCtx->ipv4_notifier.notifier_call = wlan_hdd_ipv4_changed;
10746 ret = register_inetaddr_notifier(&pHddCtx->ipv4_notifier);
10747 if (ret)
10748 {
Ratheesh S P36dbc932015-08-07 14:28:57 +053010749 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to register IPv4 notifier"));
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +053010750 }
10751 else
10752 {
Ratheesh S P36dbc932015-08-07 14:28:57 +053010753 hddLog(VOS_TRACE_LEVEL_INFO, FL("Registered IPv4 notifier"));
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +053010754 }
c_manjeecfd1efb2015-09-25 19:32:34 +053010755 /*Fw mem dump procfs initialization*/
10756 memdump_init();
Bhargav shah23c94942015-10-13 12:48:35 +053010757 hdd_dp_util_send_rps_ind(pHddCtx);
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +053010758
Jeff Johnson295189b2012-06-20 16:38:30 -070010759 goto success;
10760
Jeff Johnson295189b2012-06-20 16:38:30 -070010761err_reg_netdev:
10762 unregister_netdevice_notifier(&hdd_netdev_notifier);
10763
Jeff Johnson295189b2012-06-20 16:38:30 -070010764err_unregister_pmops:
10765 hddDevTmUnregisterNotifyCallback(pHddCtx);
10766 hddDeregisterPmOps(pHddCtx);
10767
Yue Ma0d4891e2013-08-06 17:01:45 -070010768 hdd_debugfs_exit(pHddCtx);
10769
Jeff Johnson295189b2012-06-20 16:38:30 -070010770#ifdef WLAN_BTAMP_FEATURE
10771err_bap_stop:
10772 WLANBAP_Stop(pVosContext);
10773#endif
10774
10775#ifdef WLAN_BTAMP_FEATURE
10776err_bap_close:
10777 WLANBAP_Close(pVosContext);
10778#endif
10779
Jeff Johnson295189b2012-06-20 16:38:30 -070010780err_close_adapter:
10781 hdd_close_all_adapters( pHddCtx );
Mahesh A Saptasagar9ecefe42014-07-15 18:43:49 +053010782#ifdef CONFIG_ENABLE_LINUX_REG
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053010783err_unregister_wiphy:
Mahesh A Saptasagar9ecefe42014-07-15 18:43:49 +053010784#endif
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +053010785 wiphy_unregister(wiphy) ;
Agrawal Ashish33ec71e2015-11-26 20:20:58 +053010786 hdd_wlan_free_wiphy_channels(wiphy);
10787
Jeff Johnson295189b2012-06-20 16:38:30 -070010788err_vosstop:
10789 vos_stop(pVosContext);
10790
Amar Singhala49cbc52013-10-08 18:37:44 -070010791err_vosclose:
Jeff Johnson295189b2012-06-20 16:38:30 -070010792 status = vos_sched_close( pVosContext );
10793 if (!VOS_IS_STATUS_SUCCESS(status)) {
10794 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
10795 "%s: Failed to close VOSS Scheduler", __func__);
10796 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( status ) );
10797 }
Amar Singhala49cbc52013-10-08 18:37:44 -070010798 vos_close(pVosContext );
10799
Mahesh A Saptasagarc3ed0122016-01-19 16:45:11 +053010800err_nl_srv:
10801#ifdef WLAN_KD_READY_NOTIFIER
10802 nl_srv_exit(pHddCtx->ptt_pid);
10803#else
10804 nl_srv_exit();
10805#endif /* WLAN_KD_READY_NOTIFIER */
Amar Singhal0a402232013-10-11 20:57:16 -070010806err_vos_nv_close:
10807
c_hpothue6a36282014-03-19 12:27:38 +053010808#ifdef CONFIG_ENABLE_LINUX_REG
Amar Singhal0a402232013-10-11 20:57:16 -070010809 vos_nv_close();
10810
c_hpothu70f8d812014-03-22 22:59:23 +053010811#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010812
10813err_wdclose:
10814 if(pHddCtx->cfg_ini->fIsLogpEnabled)
10815 vos_watchdog_close(pVosContext);
10816
Jeff Johnson295189b2012-06-20 16:38:30 -070010817err_config:
10818 kfree(pHddCtx->cfg_ini);
10819 pHddCtx->cfg_ini= NULL;
10820
10821err_free_hdd_context:
Sushant Kaushik83392fa2015-05-05 17:44:40 +053010822 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_DRIVER_INIT);
Siddharth Bhalcd92b782015-06-29 12:25:40 +053010823 free_riva_power_on_lock("wlan");
Jeff Johnson295189b2012-06-20 16:38:30 -070010824 wiphy_free(wiphy) ;
10825 //kfree(wdev) ;
Jeff Johnson295189b2012-06-20 16:38:30 -070010826 VOS_BUG(1);
10827
Madan Mohan Koyyalamudid57ae632012-11-06 18:42:48 -080010828 if (hdd_is_ssr_required())
10829 {
10830 /* WDI timeout had happened during load, so SSR is needed here */
10831 subsystem_restart("wcnss");
10832 msleep(5000);
10833 }
10834 hdd_set_ssr_required (VOS_FALSE);
10835
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -080010836 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -070010837
10838success:
10839 EXIT();
10840 return 0;
10841}
10842
10843/**---------------------------------------------------------------------------
10844
Jeff Johnson32d95a32012-09-10 13:15:23 -070010845 \brief hdd_driver_init() - Core Driver Init Function
Jeff Johnson295189b2012-06-20 16:38:30 -070010846
Jeff Johnson32d95a32012-09-10 13:15:23 -070010847 This is the driver entry point - called in different timeline depending
10848 on whether the driver is statically or dynamically linked
Jeff Johnson295189b2012-06-20 16:38:30 -070010849
10850 \param - None
10851
10852 \return - 0 for success, non zero for failure
10853
10854 --------------------------------------------------------------------------*/
Jeff Johnson32d95a32012-09-10 13:15:23 -070010855static int hdd_driver_init( void)
Jeff Johnson295189b2012-06-20 16:38:30 -070010856{
10857 VOS_STATUS status;
10858 v_CONTEXT_t pVosContext = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070010859 struct device *dev = NULL;
10860 int ret_status = 0;
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -070010861#ifdef HAVE_WCNSS_CAL_DOWNLOAD
10862 int max_retries = 0;
10863#endif
Siddharth Bhalc7e79b62014-10-10 22:37:38 +053010864#ifdef HAVE_CBC_DONE
10865 int max_cbc_retries = 0;
10866#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010867
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +053010868#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
10869 wlan_logging_sock_init_svc();
10870#endif
10871
Jeff Johnson295189b2012-06-20 16:38:30 -070010872 ENTER();
10873
Sushant Kaushik83392fa2015-05-05 17:44:40 +053010874 vos_wake_lock_init(&wlan_wake_lock, "wlan");
Jeff Johnson295189b2012-06-20 16:38:30 -070010875
10876 pr_info("%s: loading driver v%s\n", WLAN_MODULE_NAME,
10877 QWLAN_VERSIONSTR TIMER_MANAGER_STR MEMORY_DEBUG_STR);
10878
Jeff Johnson295189b2012-06-20 16:38:30 -070010879#ifdef ANI_BUS_TYPE_PCI
10880
10881 dev = wcnss_wlan_get_device();
10882
10883#endif // ANI_BUS_TYPE_PCI
10884
10885#ifdef ANI_BUS_TYPE_PLATFORM
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -070010886
10887#ifdef HAVE_WCNSS_CAL_DOWNLOAD
10888 /* wait until WCNSS driver downloads NV */
10889 while (!wcnss_device_ready() && 5 >= ++max_retries) {
10890 msleep(1000);
10891 }
Siddharth Bhalc7e79b62014-10-10 22:37:38 +053010892
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -070010893 if (max_retries >= 5) {
10894 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: WCNSS driver not ready", __func__);
Sushant Kaushik83392fa2015-05-05 17:44:40 +053010895 vos_wake_lock_destroy(&wlan_wake_lock);
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +053010896#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
10897 wlan_logging_sock_deinit_svc();
10898#endif
10899
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -070010900 return -ENODEV;
10901 }
10902#endif
10903
Siddharth Bhalc7e79b62014-10-10 22:37:38 +053010904#ifdef HAVE_CBC_DONE
10905 while (!wcnss_cbc_complete() && 10 >= ++max_cbc_retries) {
10906 msleep(1000);
10907 }
10908 if (max_cbc_retries >= 10) {
10909 hddLog(VOS_TRACE_LEVEL_FATAL, "%s:CBC not completed", __func__);
10910 }
10911#endif
10912
Jeff Johnson295189b2012-06-20 16:38:30 -070010913 dev = wcnss_wlan_get_device();
10914#endif // ANI_BUS_TYPE_PLATFORM
10915
10916
10917 do {
10918 if (NULL == dev) {
10919 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: WLAN device not found!!",__func__);
10920 ret_status = -1;
10921 break;
10922 }
10923
Jeff Johnson295189b2012-06-20 16:38:30 -070010924#ifdef TIMER_MANAGER
10925 vos_timer_manager_init();
10926#endif
10927
10928 /* Preopen VOSS so that it is ready to start at least SAL */
10929 status = vos_preOpen(&pVosContext);
10930
10931 if (!VOS_IS_STATUS_SUCCESS(status))
10932 {
10933 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Failed to preOpen VOSS", __func__);
10934 ret_status = -1;
10935 break;
10936 }
10937
Sushant Kaushik02beb352015-06-04 15:15:01 +053010938 hddTraceInit();
Padma, Santhosh Kumar9093b202015-07-21 15:37:38 +053010939 hdd_register_debug_callback();
10940
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010941#ifndef MODULE
10942 /* For statically linked driver, call hdd_set_conparam to update curr_con_mode
10943 */
10944 hdd_set_conparam((v_UINT_t)con_mode);
10945#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010946
10947 // Call our main init function
Jeff Johnsonbc676b42013-02-14 16:04:08 -080010948 if (hdd_wlan_startup(dev))
10949 {
Jeff Johnson295189b2012-06-20 16:38:30 -070010950 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: WLAN Driver Initialization failed",
Jeff Johnsonbc676b42013-02-14 16:04:08 -080010951 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070010952 vos_preClose( &pVosContext );
10953 ret_status = -1;
10954 break;
10955 }
10956
Jeff Johnson295189b2012-06-20 16:38:30 -070010957 } while (0);
10958
10959 if (0 != ret_status)
10960 {
Jeff Johnson295189b2012-06-20 16:38:30 -070010961#ifdef TIMER_MANAGER
10962 vos_timer_exit();
10963#endif
10964#ifdef MEMORY_DEBUG
10965 vos_mem_exit();
10966#endif
Sushant Kaushik83392fa2015-05-05 17:44:40 +053010967 vos_wake_lock_destroy(&wlan_wake_lock);
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +053010968#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
10969 wlan_logging_sock_deinit_svc();
10970#endif
10971
Jeff Johnson295189b2012-06-20 16:38:30 -070010972 pr_err("%s: driver load failure\n", WLAN_MODULE_NAME);
10973 }
10974 else
10975 {
10976 //Send WLAN UP indication to Nlink Service
10977 send_btc_nlink_msg(WLAN_MODULE_UP_IND, 0);
10978
10979 pr_info("%s: driver loaded\n", WLAN_MODULE_NAME);
Jeff Johnson295189b2012-06-20 16:38:30 -070010980 }
10981
10982 EXIT();
10983
10984 return ret_status;
10985}
10986
Jeff Johnson32d95a32012-09-10 13:15:23 -070010987/**---------------------------------------------------------------------------
10988
10989 \brief hdd_module_init() - Init Function
10990
10991 This is the driver entry point (invoked when module is loaded using insmod)
10992
10993 \param - None
10994
10995 \return - 0 for success, non zero for failure
10996
10997 --------------------------------------------------------------------------*/
10998#ifdef MODULE
10999static int __init hdd_module_init ( void)
11000{
11001 return hdd_driver_init();
11002}
Jeff Johnson32d95a32012-09-10 13:15:23 -070011003#else /* #ifdef MODULE */
11004static int __init hdd_module_init ( void)
11005{
11006 /* Driver initialization is delayed to fwpath_changed_handler */
11007 return 0;
11008}
Jeff Johnson32d95a32012-09-10 13:15:23 -070011009#endif /* #ifdef MODULE */
11010
Jeff Johnson295189b2012-06-20 16:38:30 -070011011
11012/**---------------------------------------------------------------------------
11013
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070011014 \brief hdd_driver_exit() - Exit function
Jeff Johnson295189b2012-06-20 16:38:30 -070011015
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070011016 This is the driver exit point (invoked when module is unloaded using rmmod
11017 or con_mode was changed by userspace)
Jeff Johnson295189b2012-06-20 16:38:30 -070011018
11019 \param - None
11020
11021 \return - None
11022
11023 --------------------------------------------------------------------------*/
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070011024static void hdd_driver_exit(void)
Jeff Johnson295189b2012-06-20 16:38:30 -070011025{
11026 hdd_context_t *pHddCtx = NULL;
11027 v_CONTEXT_t pVosContext = NULL;
Agarwal Ashish5e414792014-06-08 15:25:23 +053011028 v_REGDOMAIN_t regId;
Arun Kumar Khandavallie0b046d2014-03-01 21:54:25 +053011029 unsigned long rc = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070011030
11031 pr_info("%s: unloading driver v%s\n", WLAN_MODULE_NAME, QWLAN_VERSIONSTR);
11032
11033 //Get the global vos context
11034 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
11035
11036 if(!pVosContext)
11037 {
11038 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Global VOS context is Null", __func__);
11039 goto done;
11040 }
11041
11042 //Get the HDD context.
11043 pHddCtx = (hdd_context_t *)vos_get_context(VOS_MODULE_ID_HDD, pVosContext );
11044
11045 if(!pHddCtx)
11046 {
11047 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: module exit called before probe",__func__);
11048 }
Katya Nigame7b69a82015-04-28 15:24:06 +053011049 else if (VOS_MONITOR_MODE == hdd_get_conparam())
11050 {
11051 hddLog(VOS_TRACE_LEVEL_INFO,"%s: MONITOR MODE",__func__);
11052 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_UNLOAD_IN_PROGRESS;
11053 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, TRUE);
11054 hdd_wlan_exit(pHddCtx);
11055 vos_preClose( &pVosContext );
11056 goto done;
11057 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011058 else
11059 {
Siddharth Bhal2e5871b2015-03-24 16:20:51 +053011060 /* We wait for active entry threads to exit from driver
11061 * by waiting until rtnl_lock is available.
11062 */
11063 rtnl_lock();
11064 rtnl_unlock();
11065
Siddharth Bhal3c29dca2015-02-19 00:41:40 +053011066 INIT_COMPLETION(pHddCtx->ssr_comp_var);
11067 if ((pHddCtx->isLogpInProgress) && (FALSE ==
11068 vos_is_wlan_in_badState(VOS_MODULE_ID_HDD, NULL)))
11069 {
Siddharth Bhala204f572015-01-17 02:03:36 +053011070 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Siddharth Bhal3c29dca2015-02-19 00:41:40 +053011071 "%s:SSR in Progress; block rmmod !!!", __func__);
Siddharth Bhala204f572015-01-17 02:03:36 +053011072 rc = wait_for_completion_timeout(&pHddCtx->ssr_comp_var,
11073 msecs_to_jiffies(30000));
11074 if(!rc)
11075 {
11076 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
11077 "%s:SSR timedout, fatal error", __func__);
11078 VOS_BUG(0);
11079 }
11080 }
11081
Siddharth Bhal3c29dca2015-02-19 00:41:40 +053011082 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_UNLOAD_IN_PROGRESS;
11083 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, TRUE);
Jeff Johnson295189b2012-06-20 16:38:30 -070011084
c_hpothu8adb97b2014-12-08 19:38:20 +053011085 /* Driver Need to send country code 00 in below condition
11086 * 1) If gCountryCodePriority is set to 1; and last country
11087 * code set is through 11d. This needs to be done in case
11088 * when NV country code is 00.
11089 * This Needs to be done as when kernel store last country
11090 * code and if stored country code is not through 11d,
11091 * in sme_HandleChangeCountryCodeByUser we will disable 11d
11092 * in next load/unload as soon as we get any country through
11093 * 11d. In sme_HandleChangeCountryCodeByUser
11094 * pMsg->countryCode will be last countryCode and
11095 * pMac->scan.countryCode11d will be country through 11d so
11096 * due to mismatch driver will disable 11d.
11097 *
11098 */
Agarwal Ashish8db39882014-07-30 21:56:07 +053011099
c_hpothu8adb97b2014-12-08 19:38:20 +053011100 if ((eANI_BOOLEAN_TRUE == sme_Is11dCountrycode(pHddCtx->hHal) &&
Agarwal Ashish8dcd2862014-07-25 11:58:52 +053011101 pHddCtx->cfg_ini->fSupplicantCountryCodeHasPriority &&
Abhishek Singh2a705962014-10-30 14:47:28 +053011102 sme_Is11dSupported(pHddCtx->hHal)))
c_hpothu8adb97b2014-12-08 19:38:20 +053011103 {
11104 hddLog(VOS_TRACE_LEVEL_INFO,
Agarwal Ashish8dcd2862014-07-25 11:58:52 +053011105 FL("CountryCode 00 is being set while unloading driver"));
c_hpothu8adb97b2014-12-08 19:38:20 +053011106 vos_nv_getRegDomainFromCountryCode(&regId , "00", COUNTRY_USER);
11107 }
Agarwal Ashish5e414792014-06-08 15:25:23 +053011108
c_hpothu8adb97b2014-12-08 19:38:20 +053011109 //Do all the cleanup before deregistering the driver
11110 hdd_wlan_exit(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -070011111 }
11112
Jeff Johnson295189b2012-06-20 16:38:30 -070011113 vos_preClose( &pVosContext );
11114
11115#ifdef TIMER_MANAGER
11116 vos_timer_exit();
11117#endif
11118#ifdef MEMORY_DEBUG
11119 vos_mem_exit();
11120#endif
11121
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +053011122#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
11123 wlan_logging_sock_deinit_svc();
11124#endif
11125
Jeff Johnson295189b2012-06-20 16:38:30 -070011126done:
Sushant Kaushik83392fa2015-05-05 17:44:40 +053011127 vos_wake_lock_destroy(&wlan_wake_lock);
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +053011128
Jeff Johnson295189b2012-06-20 16:38:30 -070011129 pr_info("%s: driver unloaded\n", WLAN_MODULE_NAME);
11130}
11131
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070011132/**---------------------------------------------------------------------------
11133
11134 \brief hdd_module_exit() - Exit function
11135
11136 This is the driver exit point (invoked when module is unloaded using rmmod)
11137
11138 \param - None
11139
11140 \return - None
11141
11142 --------------------------------------------------------------------------*/
11143static void __exit hdd_module_exit(void)
11144{
11145 hdd_driver_exit();
11146}
11147
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070011148#ifdef MODULE
11149static int fwpath_changed_handler(const char *kmessage,
11150 struct kernel_param *kp)
11151{
Jeff Johnson76052702013-04-16 13:55:05 -070011152 return param_set_copystring(kmessage, kp);
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070011153}
11154
11155static int con_mode_handler(const char *kmessage,
11156 struct kernel_param *kp)
11157{
Madan Mohan Koyyalamudif2f8d8b2012-10-11 17:06:59 -070011158 return param_set_int(kmessage, kp);
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070011159}
11160#else /* #ifdef MODULE */
11161/**---------------------------------------------------------------------------
11162
Jeff Johnson76052702013-04-16 13:55:05 -070011163 \brief kickstart_driver
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070011164
Jeff Johnson76052702013-04-16 13:55:05 -070011165 This is the driver entry point
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070011166 - delayed driver initialization when driver is statically linked
Jeff Johnson76052702013-04-16 13:55:05 -070011167 - invoked when module parameter fwpath is modified from userspace to signal
11168 initializing the WLAN driver or when con_mode is modified from userspace
11169 to signal a switch in operating mode
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070011170
11171 \return - 0 for success, non zero for failure
11172
11173 --------------------------------------------------------------------------*/
Jeff Johnson76052702013-04-16 13:55:05 -070011174static int kickstart_driver(void)
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070011175{
Madan Mohan Koyyalamudi62e60052012-10-05 14:27:22 -070011176 int ret_status;
11177
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070011178 if (!wlan_hdd_inited) {
Madan Mohan Koyyalamudi62e60052012-10-05 14:27:22 -070011179 ret_status = hdd_driver_init();
11180 wlan_hdd_inited = ret_status ? 0 : 1;
11181 return ret_status;
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070011182 }
11183
11184 hdd_driver_exit();
Jeff Johnson76052702013-04-16 13:55:05 -070011185
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070011186 msleep(200);
Jeff Johnson76052702013-04-16 13:55:05 -070011187
Madan Mohan Koyyalamudi62e60052012-10-05 14:27:22 -070011188 ret_status = hdd_driver_init();
11189 wlan_hdd_inited = ret_status ? 0 : 1;
11190 return ret_status;
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070011191}
11192
Jeff Johnson295189b2012-06-20 16:38:30 -070011193/**---------------------------------------------------------------------------
11194
Jeff Johnson76052702013-04-16 13:55:05 -070011195 \brief fwpath_changed_handler() - Handler Function
11196
11197 Handle changes to the fwpath parameter
11198
11199 \return - 0 for success, non zero for failure
11200
11201 --------------------------------------------------------------------------*/
11202static int fwpath_changed_handler(const char *kmessage,
11203 struct kernel_param *kp)
11204{
11205 int ret;
11206
11207 ret = param_set_copystring(kmessage, kp);
11208 if (0 == ret)
11209 ret = kickstart_driver();
11210 return ret;
11211}
11212
11213/**---------------------------------------------------------------------------
11214
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070011215 \brief con_mode_handler() -
11216
11217 Handler function for module param con_mode when it is changed by userspace
11218 Dynamically linked - do nothing
11219 Statically linked - exit and init driver, as in rmmod and insmod
11220
Jeff Johnson76052702013-04-16 13:55:05 -070011221 \param -
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070011222
Jeff Johnson76052702013-04-16 13:55:05 -070011223 \return -
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070011224
11225 --------------------------------------------------------------------------*/
Jeff Johnson76052702013-04-16 13:55:05 -070011226static int con_mode_handler(const char *kmessage, struct kernel_param *kp)
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070011227{
Jeff Johnson76052702013-04-16 13:55:05 -070011228 int ret;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070011229
Jeff Johnson76052702013-04-16 13:55:05 -070011230 ret = param_set_int(kmessage, kp);
11231 if (0 == ret)
11232 ret = kickstart_driver();
11233 return ret;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070011234}
11235#endif /* #ifdef MODULE */
11236
11237/**---------------------------------------------------------------------------
11238
Jeff Johnson295189b2012-06-20 16:38:30 -070011239 \brief hdd_get_conparam() -
11240
11241 This is the driver exit point (invoked when module is unloaded using rmmod)
11242
11243 \param - None
11244
11245 \return - tVOS_CON_MODE
11246
11247 --------------------------------------------------------------------------*/
11248tVOS_CON_MODE hdd_get_conparam ( void )
11249{
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070011250#ifdef MODULE
Jeff Johnson295189b2012-06-20 16:38:30 -070011251 return (tVOS_CON_MODE)con_mode;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070011252#else
11253 return (tVOS_CON_MODE)curr_con_mode;
11254#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070011255}
11256void hdd_set_conparam ( v_UINT_t newParam )
11257{
11258 con_mode = newParam;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070011259#ifndef MODULE
11260 curr_con_mode = con_mode;
11261#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070011262}
11263/**---------------------------------------------------------------------------
11264
11265 \brief hdd_softap_sta_deauth() - function
11266
11267 This to take counter measure to handle deauth req from HDD
11268
11269 \param - pAdapter - Pointer to the HDD
11270
11271 \param - enable - boolean value
11272
11273 \return - None
11274
11275 --------------------------------------------------------------------------*/
11276
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053011277VOS_STATUS hdd_softap_sta_deauth(hdd_adapter_t *pAdapter,
11278 struct tagCsrDelStaParams *pDelStaParams)
Jeff Johnson295189b2012-06-20 16:38:30 -070011279{
Jeff Johnson295189b2012-06-20 16:38:30 -070011280 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080011281 VOS_STATUS vosStatus = VOS_STATUS_E_FAULT;
Jeff Johnson295189b2012-06-20 16:38:30 -070011282
11283 ENTER();
11284
Rajesh Chauhan18488fc2013-08-22 10:15:03 -070011285 hddLog(LOG1, "hdd_softap_sta_deauth:(%p, false)",
11286 (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -070011287
11288 //Ignore request to deauth bcmc station
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053011289 if (pDelStaParams->peerMacAddr[0] & 0x1)
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080011290 return vosStatus;
Jeff Johnson295189b2012-06-20 16:38:30 -070011291
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053011292 vosStatus = WLANSAP_DeauthSta(pVosContext, pDelStaParams);
Jeff Johnson295189b2012-06-20 16:38:30 -070011293
11294 EXIT();
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080011295 return vosStatus;
Jeff Johnson295189b2012-06-20 16:38:30 -070011296}
11297
11298/**---------------------------------------------------------------------------
11299
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +053011300 \brief hdd_del_all_sta() - function
11301
11302 This function removes all the stations associated on stopping AP/P2P GO.
11303
11304 \param - pAdapter - Pointer to the HDD
11305
11306 \return - None
11307
11308 --------------------------------------------------------------------------*/
11309
11310int hdd_del_all_sta(hdd_adapter_t *pAdapter)
11311{
11312 v_U16_t i;
11313 VOS_STATUS vos_status;
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053011314 v_CONTEXT_t pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
11315 ptSapContext pSapCtx = NULL;
11316 pSapCtx = VOS_GET_SAP_CB(pVosContext);
11317 if(pSapCtx == NULL){
11318 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11319 FL("psapCtx is NULL"));
11320 return 1;
11321 }
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +053011322 ENTER();
11323
11324 hddLog(VOS_TRACE_LEVEL_INFO,
11325 "%s: Delete all STAs associated.",__func__);
11326 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
11327 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
11328 )
11329 {
11330 for(i = 0; i < WLAN_MAX_STA_COUNT; i++)
11331 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053011332 if ((pSapCtx->aStaInfo[i].isUsed) &&
11333 (!pSapCtx->aStaInfo[i].isDeauthInProgress))
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +053011334 {
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053011335 struct tagCsrDelStaParams delStaParams;
11336
11337 WLANSAP_PopulateDelStaParams(
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053011338 pSapCtx->aStaInfo[i].macAddrSTA.bytes,
Sushant Kaushik4cd28f62014-12-26 14:23:50 +053011339 eSIR_MAC_DEAUTH_LEAVING_BSS_REASON,
11340 SIR_MAC_MGMT_DEAUTH >> 4,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053011341 &delStaParams);
11342 vos_status = hdd_softap_sta_deauth(pAdapter, &delStaParams);
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +053011343 if (VOS_IS_STATUS_SUCCESS(vos_status))
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053011344 pSapCtx->aStaInfo[i].isDeauthInProgress = TRUE;
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +053011345 }
11346 }
11347 }
11348
11349 EXIT();
11350 return 0;
11351}
11352
11353/**---------------------------------------------------------------------------
11354
Jeff Johnson295189b2012-06-20 16:38:30 -070011355 \brief hdd_softap_sta_disassoc() - function
11356
11357 This to take counter measure to handle deauth req from HDD
11358
11359 \param - pAdapter - Pointer to the HDD
11360
11361 \param - enable - boolean value
11362
11363 \return - None
11364
11365 --------------------------------------------------------------------------*/
11366
11367void hdd_softap_sta_disassoc(hdd_adapter_t *pAdapter,v_U8_t *pDestMacAddress)
11368{
11369 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
11370
11371 ENTER();
11372
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +053011373 hddLog( LOGE, "hdd_softap_sta_disassoc:(%p, false)", (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -070011374
11375 //Ignore request to disassoc bcmc station
11376 if( pDestMacAddress[0] & 0x1 )
11377 return;
11378
11379 WLANSAP_DisassocSta(pVosContext,pDestMacAddress);
11380}
11381
11382void hdd_softap_tkip_mic_fail_counter_measure(hdd_adapter_t *pAdapter,v_BOOL_t enable)
11383{
11384 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
11385
11386 ENTER();
11387
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +053011388 hddLog( LOGE, "hdd_softap_tkip_mic_fail_counter_measure:(%p, false)", (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -070011389
11390 WLANSAP_SetCounterMeasure(pVosContext, (v_BOOL_t)enable);
11391}
11392
Jeff Johnson295189b2012-06-20 16:38:30 -070011393/**---------------------------------------------------------------------------
11394 *
11395 * \brief hdd_get__concurrency_mode() -
11396 *
11397 *
11398 * \param - None
11399 *
11400 * \return - CONCURRENCY MODE
11401 *
11402 * --------------------------------------------------------------------------*/
11403tVOS_CONCURRENCY_MODE hdd_get_concurrency_mode ( void )
11404{
11405 v_CONTEXT_t pVosContext = vos_get_global_context( VOS_MODULE_ID_HDD, NULL );
11406 hdd_context_t *pHddCtx;
11407
11408 if (NULL != pVosContext)
11409 {
11410 pHddCtx = vos_get_context( VOS_MODULE_ID_HDD, pVosContext);
11411 if (NULL != pHddCtx)
11412 {
11413 return (tVOS_CONCURRENCY_MODE)pHddCtx->concurrency_mode;
11414 }
11415 }
11416
11417 /* we are in an invalid state :( */
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070011418 hddLog(LOGE, "%s: Invalid context", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070011419 return VOS_STA;
11420}
Sushant Kaushikabb7ee62014-07-18 16:20:12 +053011421v_BOOL_t
11422wlan_hdd_is_GO_power_collapse_allowed (hdd_context_t* pHddCtx)
11423{
11424 hdd_adapter_t *pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070011425
Sushant Kaushikabb7ee62014-07-18 16:20:12 +053011426 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_GO);
11427 if (pAdapter == NULL)
11428 {
11429 hddLog(VOS_TRACE_LEVEL_INFO,
11430 FL("GO doesn't exist"));
11431 return TRUE;
11432 }
11433 if (test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
11434 {
11435 hddLog(VOS_TRACE_LEVEL_INFO,
11436 FL("GO started"));
11437 return TRUE;
11438 }
11439 else
11440 /* wait till GO changes its interface to p2p device */
11441 hddLog(VOS_TRACE_LEVEL_INFO,
11442 FL("Del_bss called, avoid apps suspend"));
11443 return FALSE;
11444
11445}
Jeff Johnson295189b2012-06-20 16:38:30 -070011446/* Decide whether to allow/not the apps power collapse.
11447 * Allow apps power collapse if we are in connected state.
11448 * if not, allow only if we are in IMPS */
11449v_BOOL_t hdd_is_apps_power_collapse_allowed(hdd_context_t* pHddCtx)
11450{
11451 tPmcState pmcState = pmcGetPmcState(pHddCtx->hHal);
Srikant Kuppafef66a72013-01-30 17:32:44 -080011452 tANI_BOOLEAN scanRspPending = csrNeighborRoamScanRspPending(pHddCtx->hHal);
Srinivas Girigowdaa553c462013-03-07 19:42:52 -080011453 tANI_BOOLEAN inMiddleOfRoaming = csrNeighborMiddleOfRoaming(pHddCtx->hHal);
Jeff Johnson295189b2012-06-20 16:38:30 -070011454 hdd_config_t *pConfig = pHddCtx->cfg_ini;
11455 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
11456 hdd_adapter_t *pAdapter = NULL;
11457 VOS_STATUS status;
Yathish9f22e662012-12-10 14:21:35 -080011458 tVOS_CONCURRENCY_MODE concurrent_state = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070011459
Jeff Johnson295189b2012-06-20 16:38:30 -070011460 if (VOS_STA_SAP_MODE == hdd_get_conparam())
11461 return TRUE;
Jeff Johnson295189b2012-06-20 16:38:30 -070011462
Yathish9f22e662012-12-10 14:21:35 -080011463 concurrent_state = hdd_get_concurrency_mode();
11464
Sushant Kaushikabb7ee62014-07-18 16:20:12 +053011465 if ((concurrent_state == (VOS_STA | VOS_P2P_GO)) &&
11466 !(wlan_hdd_is_GO_power_collapse_allowed(pHddCtx)))
11467 return FALSE;
Yathish9f22e662012-12-10 14:21:35 -080011468#ifdef WLAN_ACTIVEMODE_OFFLOAD_FEATURE
Sushant Kaushikabb7ee62014-07-18 16:20:12 +053011469
Yathish9f22e662012-12-10 14:21:35 -080011470 if(((concurrent_state == (VOS_STA | VOS_P2P_CLIENT)) ||
Sushant Kaushikabb7ee62014-07-18 16:20:12 +053011471 (concurrent_state == (VOS_STA | VOS_P2P_GO)))&&
Yathish9f22e662012-12-10 14:21:35 -080011472 (IS_ACTIVEMODE_OFFLOAD_FEATURE_ENABLE))
11473 return TRUE;
11474#endif
11475
Jeff Johnson295189b2012-06-20 16:38:30 -070011476 /*loop through all adapters. TBD fix for Concurrency */
11477 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
11478 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
11479 {
11480 pAdapter = pAdapterNode->pAdapter;
11481 if ( (WLAN_HDD_INFRA_STATION == pAdapter->device_mode)
11482 || (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
11483 {
Srikant Kuppafef66a72013-01-30 17:32:44 -080011484 if (((pConfig->fIsImpsEnabled || pConfig->fIsBmpsEnabled)
c_hpothu4e8faac2014-05-16 17:38:44 +053011485 && (pmcState != IMPS && pmcState != BMPS && pmcState != UAPSD
c_hpothu1c6957d2015-01-06 18:19:47 +053011486 && pmcState != STOPPED && pmcState != STANDBY &&
11487 pmcState != WOWL)) ||
Srinivas Girigowdaa553c462013-03-07 19:42:52 -080011488 (eANI_BOOLEAN_TRUE == scanRspPending) ||
11489 (eANI_BOOLEAN_TRUE == inMiddleOfRoaming))
Jeff Johnson295189b2012-06-20 16:38:30 -070011490 {
Mukul Sharma4be88422015-03-09 20:29:07 +053011491 if(pmcState == FULL_POWER &&
11492 sme_IsCoexScoIndicationSet(pHddCtx->hHal))
11493 {
11494 /*
11495 * When SCO indication comes from Coex module , host will
11496 * enter in to full power mode, but this should not prevent
11497 * apps processor power collapse.
11498 */
11499 hddLog(LOG1,
11500 FL("Allow apps power collapse"
11501 "even when sco indication is set"));
11502 return TRUE;
11503 }
Srikant Kuppafef66a72013-01-30 17:32:44 -080011504 hddLog( LOGE, "%s: do not allow APPS power collapse-"
Srinivas Girigowdaa553c462013-03-07 19:42:52 -080011505 "pmcState = %d scanRspPending = %d inMiddleOfRoaming = %d",
11506 __func__, pmcState, scanRspPending, inMiddleOfRoaming );
Jeff Johnson295189b2012-06-20 16:38:30 -070011507 return FALSE;
11508 }
11509 }
11510 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
11511 pAdapterNode = pNext;
11512 }
11513 return TRUE;
11514}
11515
Madan Mohan Koyyalamudic72a4d62012-11-08 14:59:34 -080011516/* Decides whether to send suspend notification to Riva
11517 * if any adapter is in BMPS; then it is required */
11518v_BOOL_t hdd_is_suspend_notify_allowed(hdd_context_t* pHddCtx)
11519{
11520 tPmcState pmcState = pmcGetPmcState(pHddCtx->hHal);
11521 hdd_config_t *pConfig = pHddCtx->cfg_ini;
11522
11523 if (pConfig->fIsBmpsEnabled && (pmcState == BMPS))
11524 {
11525 return TRUE;
11526 }
11527 return FALSE;
11528}
11529
Jeff Johnson295189b2012-06-20 16:38:30 -070011530void wlan_hdd_set_concurrency_mode(hdd_context_t *pHddCtx, tVOS_CON_MODE mode)
11531{
11532 switch(mode)
11533 {
Chilam Ngc4244af2013-04-01 15:37:32 -070011534 case VOS_STA_MODE:
11535 case VOS_P2P_CLIENT_MODE:
11536 case VOS_P2P_GO_MODE:
11537 case VOS_STA_SAP_MODE:
Jeff Johnsone7245742012-09-05 17:12:55 -070011538 pHddCtx->concurrency_mode |= (1 << mode);
Agarwal Ashish51325b52014-06-16 16:50:49 +053011539 pHddCtx->no_of_open_sessions[mode]++;
Jeff Johnson295189b2012-06-20 16:38:30 -070011540 break;
11541 default:
11542 break;
Jeff Johnson295189b2012-06-20 16:38:30 -070011543 }
Agarwal Ashish51325b52014-06-16 16:50:49 +053011544 hddLog(VOS_TRACE_LEVEL_INFO, FL("concurrency_mode = 0x%x "
11545 "Number of open sessions for mode %d = %d"),
11546 pHddCtx->concurrency_mode, mode,
11547 pHddCtx->no_of_open_sessions[mode]);
Jeff Johnson295189b2012-06-20 16:38:30 -070011548}
11549
11550
11551void wlan_hdd_clear_concurrency_mode(hdd_context_t *pHddCtx, tVOS_CON_MODE mode)
11552{
11553 switch(mode)
11554 {
Chilam Ngc4244af2013-04-01 15:37:32 -070011555 case VOS_STA_MODE:
11556 case VOS_P2P_CLIENT_MODE:
11557 case VOS_P2P_GO_MODE:
11558 case VOS_STA_SAP_MODE:
Agarwal Ashish51325b52014-06-16 16:50:49 +053011559 pHddCtx->no_of_open_sessions[mode]--;
11560 if (!(pHddCtx->no_of_open_sessions[mode]))
11561 pHddCtx->concurrency_mode &= (~(1 << mode));
Jeff Johnson295189b2012-06-20 16:38:30 -070011562 break;
11563 default:
11564 break;
11565 }
Agarwal Ashish51325b52014-06-16 16:50:49 +053011566 hddLog(VOS_TRACE_LEVEL_INFO, FL("concurrency_mode = 0x%x "
11567 "Number of open sessions for mode %d = %d"),
11568 pHddCtx->concurrency_mode, mode, pHddCtx->no_of_open_sessions[mode]);
11569
11570}
11571/**---------------------------------------------------------------------------
11572 *
11573 * \brief wlan_hdd_incr_active_session()
11574 *
11575 * This function increments the number of active sessions
11576 * maintained per device mode
11577 * Incase of STA/P2P CLI/IBSS upon connection indication it is incremented
11578 * Incase of SAP/P2P GO upon bss start it is incremented
11579 *
11580 * \param pHddCtx - HDD Context
11581 * \param mode - device mode
11582 *
11583 * \return - None
11584 *
11585 * --------------------------------------------------------------------------*/
11586void wlan_hdd_incr_active_session(hdd_context_t *pHddCtx, tVOS_CON_MODE mode)
11587{
11588 switch (mode) {
11589 case VOS_STA_MODE:
11590 case VOS_P2P_CLIENT_MODE:
11591 case VOS_P2P_GO_MODE:
11592 case VOS_STA_SAP_MODE:
11593 pHddCtx->no_of_active_sessions[mode]++;
11594 break;
11595 default:
11596 hddLog(VOS_TRACE_LEVEL_INFO, FL("Not Expected Mode %d"), mode);
11597 break;
11598 }
11599 hddLog(VOS_TRACE_LEVEL_INFO, FL("No.# of active sessions for mode %d = %d"),
11600 mode,
11601 pHddCtx->no_of_active_sessions[mode]);
11602}
11603
11604/**---------------------------------------------------------------------------
11605 *
11606 * \brief wlan_hdd_decr_active_session()
11607 *
11608 * This function decrements the number of active sessions
11609 * maintained per device mode
11610 * Incase of STA/P2P CLI/IBSS upon disconnection it is decremented
11611 * Incase of SAP/P2P GO upon bss stop it is decremented
11612 *
11613 * \param pHddCtx - HDD Context
11614 * \param mode - device mode
11615 *
11616 * \return - None
11617 *
11618 * --------------------------------------------------------------------------*/
11619void wlan_hdd_decr_active_session(hdd_context_t *pHddCtx, tVOS_CON_MODE mode)
11620{
Bhargav Shahd0715912015-10-01 18:17:37 +053011621
Agarwal Ashish51325b52014-06-16 16:50:49 +053011622 switch (mode) {
11623 case VOS_STA_MODE:
11624 case VOS_P2P_CLIENT_MODE:
11625 case VOS_P2P_GO_MODE:
11626 case VOS_STA_SAP_MODE:
Agarwal Ashish5325f522014-08-06 00:58:44 +053011627 if (pHddCtx->no_of_active_sessions[mode] > 0)
11628 pHddCtx->no_of_active_sessions[mode]--;
11629 else
11630 hddLog(VOS_TRACE_LEVEL_INFO, FL(" No.# of Active sessions"
11631 "is already Zero"));
Agarwal Ashish51325b52014-06-16 16:50:49 +053011632 break;
11633 default:
11634 hddLog(VOS_TRACE_LEVEL_INFO, FL("Not Expected Mode %d"), mode);
11635 break;
11636 }
11637 hddLog(VOS_TRACE_LEVEL_INFO, FL("No.# of active sessions for mode %d = %d"),
11638 mode,
11639 pHddCtx->no_of_active_sessions[mode]);
Jeff Johnson295189b2012-06-20 16:38:30 -070011640}
11641
Jeff Johnsone7245742012-09-05 17:12:55 -070011642/**---------------------------------------------------------------------------
11643 *
11644 * \brief wlan_hdd_restart_init
11645 *
11646 * This function initalizes restart timer/flag. An internal function.
11647 *
11648 * \param - pHddCtx
11649 *
11650 * \return - None
11651 *
11652 * --------------------------------------------------------------------------*/
11653
11654static void wlan_hdd_restart_init(hdd_context_t *pHddCtx)
11655{
11656 /* Initialize */
11657 pHddCtx->hdd_restart_retries = 0;
11658 atomic_set(&pHddCtx->isRestartInProgress, 0);
11659 vos_timer_init(&pHddCtx->hdd_restart_timer,
11660 VOS_TIMER_TYPE_SW,
11661 wlan_hdd_restart_timer_cb,
11662 pHddCtx);
11663}
11664/**---------------------------------------------------------------------------
11665 *
11666 * \brief wlan_hdd_restart_deinit
11667 *
11668 * This function cleans up the resources used. An internal function.
11669 *
11670 * \param - pHddCtx
11671 *
11672 * \return - None
11673 *
11674 * --------------------------------------------------------------------------*/
11675
11676static void wlan_hdd_restart_deinit(hdd_context_t* pHddCtx)
11677{
11678
11679 VOS_STATUS vos_status;
11680 /* Block any further calls */
11681 atomic_set(&pHddCtx->isRestartInProgress, 1);
11682 /* Cleanup */
11683 vos_status = vos_timer_stop( &pHddCtx->hdd_restart_timer );
11684 if (!VOS_IS_STATUS_SUCCESS(vos_status))
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011685 hddLog(LOGE, FL("Failed to stop HDD restart timer"));
Jeff Johnsone7245742012-09-05 17:12:55 -070011686 vos_status = vos_timer_destroy(&pHddCtx->hdd_restart_timer);
11687 if (!VOS_IS_STATUS_SUCCESS(vos_status))
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011688 hddLog(LOGE, FL("Failed to destroy HDD restart timer"));
Jeff Johnsone7245742012-09-05 17:12:55 -070011689
11690}
11691
11692/**---------------------------------------------------------------------------
11693 *
11694 * \brief wlan_hdd_framework_restart
11695 *
11696 * This function uses a cfg80211 API to start a framework initiated WLAN
11697 * driver module unload/load.
11698 *
11699 * Also this API keep retrying (WLAN_HDD_RESTART_RETRY_MAX_CNT).
11700 *
11701 *
11702 * \param - pHddCtx
11703 *
11704 * \return - VOS_STATUS_SUCCESS: Success
11705 * VOS_STATUS_E_EMPTY: Adapter is Empty
11706 * VOS_STATUS_E_NOMEM: No memory
11707
11708 * --------------------------------------------------------------------------*/
11709
11710static VOS_STATUS wlan_hdd_framework_restart(hdd_context_t *pHddCtx)
11711{
11712 VOS_STATUS status = VOS_STATUS_SUCCESS;
11713 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
Madan Mohan Koyyalamudifc19e442013-05-09 18:24:08 -070011714 int len = (sizeof (struct ieee80211_mgmt));
11715 struct ieee80211_mgmt *mgmt = NULL;
11716
11717 /* Prepare the DEAUTH managment frame with reason code */
11718 mgmt = kzalloc(len, GFP_KERNEL);
11719 if(mgmt == NULL)
11720 {
11721 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
11722 "%s: memory allocation failed (%d bytes)", __func__, len);
11723 return VOS_STATUS_E_NOMEM;
11724 }
11725 mgmt->u.deauth.reason_code = WLAN_REASON_DISASSOC_LOW_ACK;
Jeff Johnsone7245742012-09-05 17:12:55 -070011726
11727 /* Iterate over all adapters/devices */
11728 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
Hanumantha Reddy Pothulada0fe362015-02-27 18:37:03 +053011729 if ((NULL == pAdapterNode) || (VOS_STATUS_SUCCESS != status))
11730 {
11731 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11732 FL("fail to get adapter: %p %d"), pAdapterNode, status);
11733 goto end;
11734 }
11735
Jeff Johnsone7245742012-09-05 17:12:55 -070011736 do
11737 {
Hanumantha Reddy Pothulada0fe362015-02-27 18:37:03 +053011738 if(pAdapterNode->pAdapter &&
11739 WLAN_HDD_ADAPTER_MAGIC == pAdapterNode->pAdapter->magic)
Jeff Johnsone7245742012-09-05 17:12:55 -070011740 {
11741 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
11742 "restarting the driver(intf:\'%s\' mode:%d :try %d)",
11743 pAdapterNode->pAdapter->dev->name,
11744 pAdapterNode->pAdapter->device_mode,
11745 pHddCtx->hdd_restart_retries + 1);
Madan Mohan Koyyalamudifc19e442013-05-09 18:24:08 -070011746 /*
11747 * CFG80211 event to restart the driver
11748 *
11749 * 'cfg80211_send_unprot_deauth' sends a
11750 * NL80211_CMD_UNPROT_DEAUTHENTICATE event to supplicant at any state
11751 * of SME(Linux Kernel) state machine.
11752 *
11753 * Reason code WLAN_REASON_DISASSOC_LOW_ACK is currently used to restart
11754 * the driver.
11755 *
11756 */
Anand N Sunkade9adb1b2015-07-29 09:56:45 +053011757#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 11, 0))
11758 cfg80211_rx_unprot_mlme_mgmt(pAdapterNode->pAdapter->dev, (u_int8_t*)mgmt, len);
11759#else
Madan Mohan Koyyalamudifc19e442013-05-09 18:24:08 -070011760 cfg80211_send_unprot_deauth(pAdapterNode->pAdapter->dev, (u_int8_t*)mgmt, len );
Anand N Sunkade9adb1b2015-07-29 09:56:45 +053011761#endif
Jeff Johnsone7245742012-09-05 17:12:55 -070011762 }
11763 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
11764 pAdapterNode = pNext;
11765 } while((NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status));
11766
Hanumantha Reddy Pothulada0fe362015-02-27 18:37:03 +053011767 end:
Madan Mohan Koyyalamudifc19e442013-05-09 18:24:08 -070011768 /* Free the allocated management frame */
11769 kfree(mgmt);
11770
Jeff Johnsone7245742012-09-05 17:12:55 -070011771 /* Retry until we unload or reach max count */
11772 if(++pHddCtx->hdd_restart_retries < WLAN_HDD_RESTART_RETRY_MAX_CNT)
11773 vos_timer_start(&pHddCtx->hdd_restart_timer, WLAN_HDD_RESTART_RETRY_DELAY_MS);
11774
11775 return status;
11776
11777}
11778/**---------------------------------------------------------------------------
11779 *
11780 * \brief wlan_hdd_restart_timer_cb
11781 *
11782 * Restart timer callback. An internal function.
11783 *
11784 * \param - User data:
11785 *
11786 * \return - None
11787 *
11788 * --------------------------------------------------------------------------*/
11789
11790void wlan_hdd_restart_timer_cb(v_PVOID_t usrDataForCallback)
11791{
11792 hdd_context_t *pHddCtx = usrDataForCallback;
11793 wlan_hdd_framework_restart(pHddCtx);
11794 return;
11795
11796}
11797
11798
11799/**---------------------------------------------------------------------------
11800 *
11801 * \brief wlan_hdd_restart_driver
11802 *
11803 * This function sends an event to supplicant to restart the WLAN driver.
11804 *
11805 * This function is called from vos_wlanRestart.
11806 *
11807 * \param - pHddCtx
11808 *
11809 * \return - VOS_STATUS_SUCCESS: Success
11810 * VOS_STATUS_E_EMPTY: Adapter is Empty
11811 * VOS_STATUS_E_ALREADY: Request already in progress
11812
11813 * --------------------------------------------------------------------------*/
11814VOS_STATUS wlan_hdd_restart_driver(hdd_context_t *pHddCtx)
11815{
11816 VOS_STATUS status = VOS_STATUS_SUCCESS;
11817
11818 /* A tight check to make sure reentrancy */
11819 if(atomic_xchg(&pHddCtx->isRestartInProgress, 1))
11820 {
Mihir Shetefd528652014-06-23 19:07:50 +053011821 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnsone7245742012-09-05 17:12:55 -070011822 "%s: WLAN restart is already in progress", __func__);
11823
11824 return VOS_STATUS_E_ALREADY;
11825 }
Sameer Thalappil0c164f52013-03-28 15:27:56 -070011826 /* Send reset FIQ to WCNSS to invoke SSR. */
Madan Mohan Koyyalamudie388b342012-11-08 15:03:16 -080011827#ifdef HAVE_WCNSS_RESET_INTR
Siddharth Bhal864e7e82015-04-07 20:07:24 +053011828 wcnss_reset_fiq(TRUE);
Madan Mohan Koyyalamudibb8f0172012-09-28 15:36:06 -070011829#endif
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -070011830
Jeff Johnsone7245742012-09-05 17:12:55 -070011831 return status;
11832}
11833
Bhargav Shahd0715912015-10-01 18:17:37 +053011834/**
11835 * hdd_get_total_sessions() - provide total number of active sessions
11836 * @pHddCtx: Valid Global HDD context pointer
11837 *
11838 * This function iterates through pAdaptors and find the number of all active
11839 * sessions. This active sessions includes connected sta, p2p client and number
11840 * of client connected to sap/p2p go.
11841 *
11842 * Return: Total number of active sessions.
11843 */
11844v_U8_t hdd_get_total_sessions(hdd_context_t *pHddCtx)
11845{
11846 v_U8_t active_session = 0;
11847 hdd_station_ctx_t *pHddStaCtx;
11848 hdd_adapter_list_node_t *pAdapterNode, *pNext;
11849 hdd_adapter_t *pAdapter;
11850 VOS_STATUS status;
11851
11852 status = hdd_get_front_adapter(pHddCtx, &pAdapterNode);
11853 while (NULL != pAdapterNode && VOS_STATUS_SUCCESS == status) {
11854 pAdapter = pAdapterNode->pAdapter;
11855 switch (pAdapter->device_mode) {
11856 case VOS_STA_MODE:
11857 case VOS_P2P_CLIENT_MODE:
11858 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
11859 if(eConnectionState_Associated == pHddStaCtx->conn_info.connState)
11860 active_session += 1;
11861 break;
11862 case VOS_STA_SAP_MODE:
11863 case VOS_P2P_GO_MODE:
11864 active_session += hdd_softap_get_connected_sta(pAdapter);
11865 break;
11866 default:
11867 break;
11868 }
11869
11870 status = hdd_get_next_adapter(pHddCtx, pAdapterNode, &pNext);
11871 pAdapterNode = pNext;
11872 }
11873
11874 return active_session;
11875}
11876
11877/**
11878 * hdd_set_delack_value() - Set delack value
11879 * @pHddCtx: Valid Global HDD context pointer
11880 * @next_rx_level: Value to set for delack
11881 *
11882 * This function compare present value and next value of delack. If the both
11883 * are diffrent then it sets next value .
11884 *
11885 * Return: void.
11886 */
11887void hdd_set_delack_value(hdd_context_t *pHddCtx, v_U32_t next_rx_level)
11888{
11889 if (pHddCtx->cur_rx_level != next_rx_level) {
11890 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_DEBUG,
11891 "%s: TCP DELACK trigger level %d",
11892 __func__, next_rx_level);
11893 mutex_lock(&pHddCtx->cur_rx_level_lock);
11894 pHddCtx->cur_rx_level = next_rx_level;
11895 mutex_unlock(&pHddCtx->cur_rx_level_lock);
11896 wlan_hdd_send_svc_nlink_msg(WLAN_SVC_WLAN_TP_IND, &next_rx_level,
11897 sizeof(next_rx_level));
11898 }
11899}
11900
11901/**
11902 * hdd_set_default_stop_delack_timer() - Start delack timer
11903 * @pHddCtx: Valid Global HDD context pointer
11904 *
11905 * This function stop delack timer and set delack value to default..
11906 *
11907 * Return: void.
11908 */
11909
11910void hdd_set_default_stop_delack_timer(hdd_context_t *pHddCtx)
11911{
11912 if (VOS_TIMER_STATE_RUNNING !=
11913 vos_timer_getCurrentState(&pHddCtx->delack_timer)) {
11914 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_DEBUG,
11915 "%s: Can not stop timer", __func__);
11916 return;
11917 }
11918
11919 vos_timer_stop(&pHddCtx->delack_timer);
11920 hdd_set_delack_value(pHddCtx, TP_IND_LOW);
11921}
11922
11923/**
11924 * hdd_start_delack_timer() - Start delack timer
11925 * @pHddCtx: Valid Global HDD context pointer
11926 *
11927 * This function starts the delack timer for tcpDelAckComputeInterval time
11928 * interval.The default timer value is 2 second.
11929 *
11930 * Return: void.
11931 */
11932void hdd_start_delack_timer(hdd_context_t *pHddCtx)
11933{
11934 if (VOS_TIMER_STATE_RUNNING ==
11935 vos_timer_getCurrentState(&pHddCtx->delack_timer)) {
11936 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_DEBUG,
11937 "%s: Timer is already running", __func__);
11938 return;
11939 }
11940
11941 vos_timer_start(&pHddCtx->delack_timer,
11942 pHddCtx->cfg_ini->tcpDelAckComputeInterval);
11943}
11944
11945/**
11946 * hdd_update_prev_rx_packet_count() - Update previous rx packet count
11947 * @pHddCtx: Valid Global HDD context pointer
11948 *
11949 * This function updates the prev_rx_packets count from the corresponding
11950 * pAdapter states. This prev_rx_packets will diffed with the packet count
11951 * at the end of delack timer. That can give number of RX packet is spacific
11952 * time.
11953 *
11954 * Return: void.
11955 */
11956void hdd_update_prev_rx_packet_count(hdd_context_t *pHddCtx)
11957{
11958 hdd_adapter_list_node_t *pAdapterNode, *pNext;
11959 hdd_adapter_t *pAdapter;
11960 VOS_STATUS status;
11961
11962 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
11963 while (NULL != pAdapterNode && VOS_STATUS_SUCCESS == status) {
11964 pAdapter = pAdapterNode->pAdapter;
11965 pAdapter->prev_rx_packets = pAdapter->stats.rx_packets;
11966 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
11967 pAdapterNode = pNext;
11968 }
11969}
11970
11971/**
11972 * hdd_manage_delack_timer() - start\stop delack timer
11973 * @pHddCtx: Valid Global HDD context pointer
11974 *
11975 * This function check the number of concerent session present, it starts the
11976 * delack timer if only one session is present.
11977 * In the case of BT_COEX and TDLS mode it blindly stop delack functionality.
11978 *
11979 * Return: void.
11980 */
11981void hdd_manage_delack_timer(hdd_context_t *pHddCtx)
11982{
11983 uint8_t sessions;
11984
11985 if (!pHddCtx->cfg_ini->enable_delack) {
11986 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_DEBUG,
11987 "%s: TCP DELACK is not enabled", __func__);
11988 return;
11989 }
11990
11991 /* Blindly stop timer of BTCOEX and TDLS Session is up */
11992 if (pHddCtx->mode != 0) {
11993 hdd_set_default_stop_delack_timer(pHddCtx);
11994 return;
11995 }
11996
11997 sessions = hdd_get_total_sessions(pHddCtx);
11998 if (sessions == 1) {
11999 hdd_update_prev_rx_packet_count(pHddCtx);
12000 hdd_start_delack_timer(pHddCtx);
12001 } else {
12002 hdd_set_default_stop_delack_timer(pHddCtx);
12003 }
12004}
12005
Mihir Shetee1093ba2014-01-21 20:13:32 +053012006/**---------------------------------------------------------------------------
12007 *
12008 * \brief wlan_hdd_init_channels
12009 *
12010 * This function is used to initialize the channel list in CSR
12011 *
12012 * This function is called from hdd_wlan_startup
12013 *
12014 * \param - pHddCtx: HDD context
12015 *
12016 * \return - VOS_STATUS_SUCCESS: Success
12017 * VOS_STATUS_E_FAULT: Failure reported by SME
12018
12019 * --------------------------------------------------------------------------*/
12020static VOS_STATUS wlan_hdd_init_channels(hdd_context_t *pHddCtx)
12021{
12022 eHalStatus status;
12023
12024 status = sme_InitChannels(pHddCtx->hHal);
12025 if (HAL_STATUS_SUCCESS(status))
12026 {
12027 return VOS_STATUS_SUCCESS;
12028 }
12029 else
12030 {
12031 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Channel initialization failed(%d)",
12032 __func__, status);
12033 return VOS_STATUS_E_FAULT;
12034 }
12035}
12036
Mihir Shete04206452014-11-20 17:50:58 +053012037#ifdef CONFIG_ENABLE_LINUX_REG
Agarwal Ashish6db9d532014-09-30 18:19:10 +053012038VOS_STATUS wlan_hdd_init_channels_for_cc(hdd_context_t *pHddCtx, driver_load_type init )
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053012039{
12040 eHalStatus status;
12041
Agarwal Ashish6db9d532014-09-30 18:19:10 +053012042 status = sme_InitChannelsForCC(pHddCtx->hHal, init);
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053012043 if (HAL_STATUS_SUCCESS(status))
12044 {
12045 return VOS_STATUS_SUCCESS;
12046 }
12047 else
12048 {
12049 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Issue reg hint failed(%d)",
12050 __func__, status);
12051 return VOS_STATUS_E_FAULT;
12052 }
12053}
Mihir Shete04206452014-11-20 17:50:58 +053012054#endif
Sudhir Sattayappa Kohallib1d8c3a2013-06-18 14:47:20 -070012055/*
12056 * API to find if there is any STA or P2P-Client is connected
12057 */
12058VOS_STATUS hdd_issta_p2p_clientconnected(hdd_context_t *pHddCtx)
12059{
12060 return sme_isSta_p2p_clientConnected(pHddCtx->hHal);
12061}
Jeff Johnsone7245742012-09-05 17:12:55 -070012062
Mihir Shetee2ae82a2015-03-16 14:08:49 +053012063
12064/*
12065 * API to find if the firmware will send logs using DXE channel
12066 */
12067v_U8_t hdd_is_fw_logging_enabled(void)
12068{
12069 hdd_context_t *pHddCtx;
12070
12071 pHddCtx = vos_get_context(VOS_MODULE_ID_HDD,
12072 vos_get_global_context(VOS_MODULE_ID_HDD, NULL));
12073
Sachin Ahuja084313e2015-05-21 17:57:10 +053012074 return (pHddCtx && pHddCtx->cfg_ini->enableMgmtLogging);
Mihir Shetee2ae82a2015-03-16 14:08:49 +053012075}
12076
Agarwal Ashish57e84372014-12-05 18:26:53 +053012077/*
Mihir Shetebe94ebb2015-05-26 12:07:14 +053012078 * API to find if the firmware will send trace logs using DXE channel
12079 */
12080v_U8_t hdd_is_fw_ev_logging_enabled(void)
12081{
12082 hdd_context_t *pHddCtx;
12083
12084 pHddCtx = vos_get_context(VOS_MODULE_ID_HDD,
12085 vos_get_global_context(VOS_MODULE_ID_HDD, NULL));
12086
12087 return (pHddCtx && pHddCtx->cfg_ini->enableFWLogging);
12088}
12089/*
Agarwal Ashish57e84372014-12-05 18:26:53 +053012090 * API to find if there is any session connected
12091 */
12092VOS_STATUS hdd_is_any_session_connected(hdd_context_t *pHddCtx)
12093{
12094 return sme_is_any_session_connected(pHddCtx->hHal);
12095}
12096
12097
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053012098int wlan_hdd_scan_abort(hdd_adapter_t *pAdapter)
12099{
12100 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
12101 hdd_scaninfo_t *pScanInfo = NULL;
Girish Gowli4bf7a632014-06-12 13:42:11 +053012102 long status = 0;
c_hpothua3d45d52015-01-05 14:11:17 +053012103 tSirAbortScanStatus abortScanStatus;
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053012104
12105 pScanInfo = &pHddCtx->scan_info;
Ratnam Rachuric7681132015-06-30 10:35:13 +053012106 INIT_COMPLETION(pScanInfo->abortscan_event_var);
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053012107 if (pScanInfo->mScanPending)
12108 {
c_hpothua3d45d52015-01-05 14:11:17 +053012109 abortScanStatus = hdd_abort_mac_scan(pHddCtx, pScanInfo->sessionId,
12110 eCSR_SCAN_ABORT_DEFAULT);
12111 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
12112 FL("abortScanStatus: %d"), abortScanStatus);
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053012113
c_hpothua3d45d52015-01-05 14:11:17 +053012114 /* If there is active scan command lets wait for the completion else
12115 * there is no need to wait as scan command might be in the SME pending
12116 * command list.
12117 */
12118 if (abortScanStatus == eSIR_ABORT_ACTIVE_SCAN_LIST_NOT_EMPTY)
12119 {
c_hpothua3d45d52015-01-05 14:11:17 +053012120 status = wait_for_completion_interruptible_timeout(
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053012121 &pScanInfo->abortscan_event_var,
12122 msecs_to_jiffies(5000));
c_hpothua3d45d52015-01-05 14:11:17 +053012123 if (0 >= status)
12124 {
12125 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Girish Gowli4bf7a632014-06-12 13:42:11 +053012126 "%s: Timeout or Interrupt occurred while waiting for abort"
12127 "scan, status- %ld", __func__, status);
c_hpothua3d45d52015-01-05 14:11:17 +053012128 return -ETIMEDOUT;
12129 }
12130 }
12131 else if (abortScanStatus == eSIR_ABORT_SCAN_FAILURE)
12132 {
12133 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12134 FL("hdd_abort_mac_scan failed"));
12135 return -VOS_STATUS_E_FAILURE;
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053012136 }
12137 }
Girish Gowli4bf7a632014-06-12 13:42:11 +053012138 return 0;
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053012139}
12140
Abhishek Singh7d624e12015-11-30 14:29:27 +053012141/**
12142 * hdd_indicate_mgmt_frame() - Wrapper to indicate management frame to
12143 * user space
12144 * @frame_ind: Management frame data to be informed.
12145 *
12146 * This function is used to indicate management frame to
12147 * user space
12148 *
12149 * Return: None
12150 *
12151 */
12152void hdd_indicate_mgmt_frame(tSirSmeMgmtFrameInd *frame_ind)
12153{
12154 hdd_context_t *hdd_ctx = NULL;
12155 hdd_adapter_t *adapter = NULL;
12156 v_CONTEXT_t vos_context = NULL;
12157
12158 /* Get the global VOSS context.*/
12159 vos_context = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
12160 if (!vos_context) {
12161 hddLog(LOGE, FL("Global VOS context is Null"));
12162 return;
12163 }
12164 /* Get the HDD context.*/
12165 hdd_ctx =
12166 (hdd_context_t *)vos_get_context(VOS_MODULE_ID_HDD, vos_context );
12167
12168 if (0 != wlan_hdd_validate_context(hdd_ctx))
12169 {
12170 return;
12171 }
12172 adapter = hdd_get_adapter_by_sme_session_id(hdd_ctx,
12173 frame_ind->sessionId);
12174
12175 if ((NULL != adapter) &&
12176 (WLAN_HDD_ADAPTER_MAGIC == adapter->magic))
12177 __hdd_indicate_mgmt_frame(adapter,
12178 frame_ind->frameLen,
12179 frame_ind->frameBuf,
12180 frame_ind->frameType,
12181 frame_ind->rxChan,
12182 frame_ind->rxRssi);
12183 return;
12184
12185}
12186
c_hpothu225aa7c2014-10-22 17:45:13 +053012187VOS_STATUS wlan_hdd_cancel_remain_on_channel(hdd_context_t *pHddCtx)
12188{
12189 hdd_adapter_t *pAdapter;
12190 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
12191 VOS_STATUS vosStatus;
12192
12193 vosStatus = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
12194 while (NULL != pAdapterNode && VOS_STATUS_E_EMPTY != vosStatus)
12195 {
12196 pAdapter = pAdapterNode->pAdapter;
12197 if (NULL != pAdapter)
12198 {
12199 if (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode ||
12200 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode ||
12201 WLAN_HDD_P2P_GO == pAdapter->device_mode)
12202 {
12203 hddLog(LOG1, FL("abort ROC deviceMode: %d"),
12204 pAdapter->device_mode);
12205 if (VOS_STATUS_SUCCESS !=
12206 wlan_hdd_cancel_existing_remain_on_channel(pAdapter))
12207 {
12208 hddLog(LOGE, FL("failed to abort ROC"));
12209 return VOS_STATUS_E_FAILURE;
12210 }
12211 }
12212 }
12213 vosStatus = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
12214 pAdapterNode = pNext;
12215 }
12216 return VOS_STATUS_SUCCESS;
12217}
Mahesh A Saptasagard477b092015-02-06 15:12:16 +053012218
Mihir Shete0be28772015-02-17 18:42:14 +053012219hdd_remain_on_chan_ctx_t *hdd_get_remain_on_channel_ctx(hdd_context_t *pHddCtx)
12220{
12221 hdd_adapter_t *pAdapter;
12222 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
12223 hdd_cfg80211_state_t *cfgState;
12224 hdd_remain_on_chan_ctx_t *pRemainChanCtx = NULL;
12225 VOS_STATUS vosStatus;
12226
12227 vosStatus = hdd_get_front_adapter (pHddCtx, &pAdapterNode);
12228 while (NULL != pAdapterNode && VOS_STATUS_E_EMPTY != vosStatus)
12229 {
12230 pAdapter = pAdapterNode->pAdapter;
12231 if (NULL != pAdapter)
12232 {
12233 cfgState = WLAN_HDD_GET_CFG_STATE_PTR(pAdapter);
12234 pRemainChanCtx = cfgState->remain_on_chan_ctx;
12235 if (pRemainChanCtx)
12236 break;
12237 }
12238 vosStatus = hdd_get_next_adapter (pHddCtx, pAdapterNode, &pNext);
12239 pAdapterNode = pNext;
12240 }
12241 return pRemainChanCtx;
12242}
12243
Padma, Santhosh Kumar778d8382015-03-04 17:41:22 +053012244/**
12245 * wlan_hdd_handle_dfs_chan_scan () - handles disable/enable DFS channels
12246 *
12247 * @pHddCtx: HDD context within host driver
12248 * @dfsScanMode: dfsScanMode passed from ioctl
12249 *
12250 */
12251
12252VOS_STATUS wlan_hdd_handle_dfs_chan_scan(hdd_context_t *pHddCtx,
12253 tANI_U8 dfsScanMode)
12254{
12255 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
12256 hdd_adapter_t *pAdapter;
12257 VOS_STATUS vosStatus;
12258 hdd_station_ctx_t *pHddStaCtx;
12259 eHalStatus status = eHAL_STATUS_SUCCESS;
12260
12261 if(!pHddCtx)
12262 {
12263 hddLog(LOGE, FL("HDD context is Null"));
12264 return eHAL_STATUS_FAILURE;
12265 }
12266
12267 if (pHddCtx->scan_info.mScanPending)
12268 {
12269 hddLog(LOG1, FL("Aborting scan for sessionId: %d"),
12270 pHddCtx->scan_info.sessionId);
12271 hdd_abort_mac_scan(pHddCtx,
12272 pHddCtx->scan_info.sessionId,
12273 eCSR_SCAN_ABORT_DEFAULT);
12274 }
12275
12276 if (!dfsScanMode)
12277 {
12278 vosStatus = hdd_get_front_adapter( pHddCtx, &pAdapterNode);
12279 while ((NULL != pAdapterNode) &&
12280 (VOS_STATUS_SUCCESS == vosStatus))
12281 {
12282 pAdapter = pAdapterNode->pAdapter;
12283
12284 if (WLAN_HDD_INFRA_STATION == pAdapter->device_mode)
12285 {
12286 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
12287
12288 if(!pHddStaCtx)
12289 {
12290 hddLog(LOGE, FL("HDD STA context is Null"));
12291 return eHAL_STATUS_FAILURE;
12292 }
12293
12294 /* if STA is already connected on DFS channel,
12295 disconnect immediately*/
12296 if (hdd_connIsConnected(pHddStaCtx) &&
12297 (NV_CHANNEL_DFS ==
12298 vos_nv_getChannelEnabledState(
12299 pHddStaCtx->conn_info.operationChannel)))
12300 {
12301 status = sme_RoamDisconnect(pHddCtx->hHal,
12302 pAdapter->sessionId,
12303 eCSR_DISCONNECT_REASON_UNSPECIFIED);
12304 hddLog(LOG1, FL("Client connected on DFS channel %d,"
12305 "sme_RoamDisconnect returned with status: %d"
12306 "for sessionid: %d"), pHddStaCtx->conn_info.
12307 operationChannel, status, pAdapter->sessionId);
12308 }
12309 }
12310
12311 vosStatus = hdd_get_next_adapter(pHddCtx, pAdapterNode,
12312 &pNext);
12313 pAdapterNode = pNext;
12314 }
12315 }
12316
12317 sme_UpdateDFSScanMode(pHddCtx->hHal, dfsScanMode);
12318 sme_UpdateDFSRoamMode(pHddCtx->hHal,
12319 (dfsScanMode != DFS_CHNL_SCAN_DISABLED));
12320
12321 status = sme_HandleDFSChanScan(pHddCtx->hHal);
12322 if (!HAL_STATUS_SUCCESS(status))
12323 {
12324 hddLog(LOGE,
12325 FL("Failed in sme_HandleDFSChanScan (err=%d)"), status);
12326 return status;
12327 }
12328
12329 return status;
12330}
12331
Nirav Shah7e3c8132015-06-22 23:51:42 +053012332static int hdd_log2_ceil(unsigned value)
12333{
12334 /* need to switch to unsigned math so that negative values
12335 * will right-shift towards 0 instead of -1
12336 */
12337 unsigned tmp = value;
12338 int log2 = -1;
12339
12340 if (value == 0)
12341 return 0;
12342
12343 while (tmp) {
12344 log2++;
12345 tmp >>= 1;
12346 }
12347 if (1U << log2 != value)
12348 log2++;
12349
12350 return log2;
12351}
12352
12353/**
12354 * hdd_sta_id_hash_attach() - initialize sta id to macaddr hash
12355 * @pAdapter: adapter handle
12356 *
12357 * Return: vos status
12358 */
12359VOS_STATUS hdd_sta_id_hash_attach(hdd_adapter_t *pAdapter)
12360{
12361 int hash_elem, log2, i;
12362
12363 spin_lock_bh( &pAdapter->sta_hash_lock);
12364 if (pAdapter->is_sta_id_hash_initialized == VOS_TRUE) {
12365 spin_unlock_bh( &pAdapter->sta_hash_lock);
12366 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12367 "%s: hash already attached for session id %d",
12368 __func__, pAdapter->sessionId);
12369 return VOS_STATUS_SUCCESS;
12370 }
12371 spin_unlock_bh( &pAdapter->sta_hash_lock);
12372
12373 hash_elem = WLAN_MAX_STA_COUNT;
12374 hash_elem *= HDD_STA_ID_HASH_MULTIPLIER;
12375 log2 = hdd_log2_ceil(hash_elem);
12376 hash_elem = 1 << log2;
12377
12378 pAdapter->sta_id_hash.mask = hash_elem - 1;
12379 pAdapter->sta_id_hash.idx_bits = log2;
12380 pAdapter->sta_id_hash.bins =
12381 vos_mem_malloc(hash_elem *sizeof(hdd_list_t));
12382 if (!pAdapter->sta_id_hash.bins) {
12383 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12384 "%s: malloc failed for session %d",
12385 __func__, pAdapter->sessionId);
12386 return VOS_STATUS_E_NOMEM;
12387 }
12388
12389 for (i = 0; i < hash_elem; i++)
12390 hdd_list_init(&pAdapter->sta_id_hash.bins[i], WLAN_MAX_STA_COUNT);
12391
12392 spin_lock_bh( &pAdapter->sta_hash_lock);
12393 pAdapter->is_sta_id_hash_initialized = VOS_TRUE;
12394 spin_unlock_bh( &pAdapter->sta_hash_lock);
12395 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
12396 "%s: Station ID Hash attached for session id %d",
12397 __func__, pAdapter->sessionId);
12398
12399 return VOS_STATUS_SUCCESS;
12400}
12401
12402/**
12403 * hdd_sta_id_hash_detach() - deinit sta_id to macaddr hash
12404 * @pAdapter: adapter handle
12405 *
12406 * Return: vos status
12407 */
12408VOS_STATUS hdd_sta_id_hash_detach(hdd_adapter_t *pAdapter)
12409{
12410 int hash_elem, i;
12411 v_SIZE_t size;
12412
12413 spin_lock_bh( &pAdapter->sta_hash_lock);
12414 if (pAdapter->is_sta_id_hash_initialized != VOS_TRUE) {
12415 spin_unlock_bh( &pAdapter->sta_hash_lock);
12416 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
12417 "%s: hash not initialized for session id %d",
12418 __func__, pAdapter->sessionId);
12419 return VOS_STATUS_SUCCESS;
12420 }
12421
12422 pAdapter->is_sta_id_hash_initialized = VOS_FALSE;
12423 spin_unlock_bh( &pAdapter->sta_hash_lock);
12424
12425 hash_elem = 1 << pAdapter->sta_id_hash.idx_bits;
12426
12427 /* free all station info*/
12428 for (i = 0; i < hash_elem; i++) {
12429 hdd_list_size(&pAdapter->sta_id_hash.bins[i], &size);
12430 if (size != 0) {
12431 VOS_STATUS status;
12432 hdd_staid_hash_node_t *sta_info_node = NULL;
12433 hdd_staid_hash_node_t *next_node = NULL;
12434 status = hdd_list_peek_front ( &pAdapter->sta_id_hash.bins[i],
12435 (hdd_list_node_t**) &sta_info_node );
12436
12437 while ( NULL != sta_info_node && VOS_STATUS_SUCCESS == status )
12438 {
12439 status = hdd_list_remove_node( &pAdapter->sta_id_hash.bins[i],
12440 &sta_info_node->node);
12441 vos_mem_free(sta_info_node);
12442
12443 status = hdd_list_peek_next (&pAdapter->sta_id_hash.bins[i],
12444 (hdd_list_node_t*)sta_info_node,
12445 (hdd_list_node_t**)&next_node);
12446 sta_info_node = next_node;
12447 }
12448 }
12449 }
12450
12451 vos_mem_free(pAdapter->sta_id_hash.bins);
12452 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
12453 "%s: Station ID Hash detached for session id %d",
12454 __func__, pAdapter->sessionId);
12455 return VOS_STATUS_SUCCESS;
12456}
12457
12458/**
12459 * hdd_sta_id_hash_calculate_index() - derive index from macaddr
12460 * @pAdapter: adapter handle
12461 * @mac_addr_in: input mac address
12462 *
12463 * Return: index derived from mac address
12464 */
12465int hdd_sta_id_hash_calculate_index(hdd_adapter_t *pAdapter,
12466 v_MACADDR_t *mac_addr_in)
12467{
12468 uint16 index;
12469 struct hdd_align_mac_addr_t * mac_addr =
12470 (struct hdd_align_mac_addr_t *)mac_addr_in;
12471
12472 index = mac_addr->bytes_ab ^
12473 mac_addr->bytes_cd ^ mac_addr->bytes_ef;
12474 index ^= index >> pAdapter->sta_id_hash.idx_bits;
12475 index &= pAdapter->sta_id_hash.mask;
12476 return index;
12477}
12478
12479/**
12480 * hdd_sta_id_hash_add_entry() - add entry in hash
12481 * @pAdapter: adapter handle
12482 * @sta_id: station id
12483 * @mac_addr: mac address
12484 *
12485 * Return: vos status
12486 */
12487VOS_STATUS hdd_sta_id_hash_add_entry(hdd_adapter_t *pAdapter,
12488 v_U8_t sta_id, v_MACADDR_t *mac_addr)
12489{
12490 uint16 index;
12491 hdd_staid_hash_node_t *sta_info_node = NULL;
12492
Nirav Shah7e3c8132015-06-22 23:51:42 +053012493 index = hdd_sta_id_hash_calculate_index(pAdapter, mac_addr);
12494 sta_info_node = vos_mem_malloc(sizeof(hdd_staid_hash_node_t));
12495 if (!sta_info_node) {
Nirav Shah7e3c8132015-06-22 23:51:42 +053012496 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12497 "%s: malloc failed", __func__);
12498 return VOS_STATUS_E_NOMEM;
12499 }
12500
12501 sta_info_node->sta_id = sta_id;
12502 vos_mem_copy(&sta_info_node->mac_addr, mac_addr, sizeof(v_MACADDR_t));
12503
Nirav Shah303ed5c2015-08-24 10:29:25 +053012504 spin_lock_bh( &pAdapter->sta_hash_lock);
12505 if (pAdapter->is_sta_id_hash_initialized != VOS_TRUE) {
12506 spin_unlock_bh( &pAdapter->sta_hash_lock);
12507 vos_mem_free(sta_info_node);
12508 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
12509 "%s: hash is not initialized for session id %d",
12510 __func__, pAdapter->sessionId);
12511 return VOS_STATUS_E_FAILURE;
12512 }
12513
Nirav Shah7e3c8132015-06-22 23:51:42 +053012514 hdd_list_insert_back ( &pAdapter->sta_id_hash.bins[index],
12515 (hdd_list_node_t*) sta_info_node );
12516 spin_unlock_bh( &pAdapter->sta_hash_lock);
12517 return VOS_STATUS_SUCCESS;
12518}
12519
12520/**
12521 * hdd_sta_id_hash_remove_entry() - remove entry from hash
12522 * @pAdapter: adapter handle
12523 * @sta_id: station id
12524 * @mac_addr: mac address
12525 *
12526 * Return: vos status
12527 */
12528VOS_STATUS hdd_sta_id_hash_remove_entry(hdd_adapter_t *pAdapter,
12529 v_U8_t sta_id, v_MACADDR_t *mac_addr)
12530{
12531 uint16 index;
12532 VOS_STATUS status;
12533 hdd_staid_hash_node_t *sta_info_node = NULL;
12534 hdd_staid_hash_node_t *next_node = NULL;
12535
12536 spin_lock_bh( &pAdapter->sta_hash_lock);
12537 if (pAdapter->is_sta_id_hash_initialized != VOS_TRUE) {
12538 spin_unlock_bh( &pAdapter->sta_hash_lock);
12539 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12540 "%s: hash is not initialized for session id %d",
12541 __func__, pAdapter->sessionId);
12542 return VOS_STATUS_E_FAILURE;
12543 }
12544
12545 index = hdd_sta_id_hash_calculate_index(pAdapter, mac_addr);
12546 status = hdd_list_peek_front ( &pAdapter->sta_id_hash.bins[index],
12547 (hdd_list_node_t**) &sta_info_node );
12548
12549 while ( NULL != sta_info_node && VOS_STATUS_SUCCESS == status )
12550 {
12551 if (sta_info_node->sta_id == sta_id) {
12552 status = hdd_list_remove_node( &pAdapter->sta_id_hash.bins[index],
12553 &sta_info_node->node);
12554 vos_mem_free(sta_info_node);
12555 break;
12556 }
12557 status = hdd_list_peek_next (&pAdapter->sta_id_hash.bins[index],
12558 (hdd_list_node_t*)sta_info_node, (hdd_list_node_t**)&next_node);
12559 sta_info_node = next_node;
12560 }
12561 spin_unlock_bh( &pAdapter->sta_hash_lock);
12562 return status;
12563}
12564
12565/**
12566 * hdd_sta_id_find_from_mac_addr() - find sta id from mac address
12567 * @pAdapter: adapter handle
12568 * @mac_addr_in: mac address
12569 *
12570 * Return: station id
12571 */
12572int hdd_sta_id_find_from_mac_addr(hdd_adapter_t *pAdapter,
12573 v_MACADDR_t *mac_addr_in)
12574{
12575 uint8 is_found = 0;
12576 uint8 sta_id = HDD_WLAN_INVALID_STA_ID;
12577 uint16 index;
12578 VOS_STATUS status;
12579 hdd_staid_hash_node_t *sta_info_node = NULL;
12580 hdd_staid_hash_node_t *next_node = NULL;
12581
12582 spin_lock_bh( &pAdapter->sta_hash_lock);
12583 if (pAdapter->is_sta_id_hash_initialized != VOS_TRUE) {
12584 spin_unlock_bh( &pAdapter->sta_hash_lock);
Bhargav Shahce3b32c2015-08-10 12:29:24 +053012585 hddLog(VOS_TRACE_LEVEL_INFO,
Nirav Shah7e3c8132015-06-22 23:51:42 +053012586 FL("hash is not initialized for session id %d"),
12587 pAdapter->sessionId);
12588 return HDD_WLAN_INVALID_STA_ID;
12589 }
12590
12591 index = hdd_sta_id_hash_calculate_index(pAdapter, mac_addr_in);
12592 status = hdd_list_peek_front ( &pAdapter->sta_id_hash.bins[index],
12593 (hdd_list_node_t**) &sta_info_node );
12594
12595 while ( NULL != sta_info_node && VOS_STATUS_SUCCESS == status )
12596 {
12597 if (vos_mem_compare(&sta_info_node->mac_addr,
12598 mac_addr_in, sizeof(v_MACADDR_t))) {
12599 is_found = 1;
12600 sta_id = sta_info_node->sta_id;
12601 break;
12602 }
12603 status = hdd_list_peek_next (&pAdapter->sta_id_hash.bins[index],
12604 (hdd_list_node_t*)sta_info_node,
12605 (hdd_list_node_t**)&next_node);
12606 sta_info_node = next_node;
12607 }
12608 spin_unlock_bh( &pAdapter->sta_hash_lock);
12609 return sta_id;
12610}
12611
c_manjeecfd1efb2015-09-25 19:32:34 +053012612/*FW memory dump feature*/
12613/**
12614 * This structure hold information about the /proc file
12615 *
12616 */
12617static struct proc_dir_entry *proc_file, *proc_dir;
12618
12619/**
12620 * memdump_read() - perform read operation in memory dump proc file
12621 *
12622 * @file - handle for the proc file.
12623 * @buf - pointer to user space buffer.
12624 * @count - number of bytes to be read.
12625 * @pos - offset in the from buffer.
12626 *
12627 * This function performs read operation for the memory dump proc file.
12628 *
12629 * Return: number of bytes read on success, error code otherwise.
12630 */
12631static ssize_t memdump_read(struct file *file, char __user *buf,
12632 size_t count, loff_t *pos)
12633{
12634 int status;
12635 hdd_context_t *hdd_ctx = (hdd_context_t *)PDE_DATA(file_inode(file));
12636 size_t ret_count;
c_manjeef1495642015-10-13 18:35:01 +053012637 loff_t bytes_left;
c_manjeecfd1efb2015-09-25 19:32:34 +053012638 ENTER();
12639
12640 hddLog(LOG1, FL("Read req for size:%zu pos:%llu"), count, *pos);
12641 status = wlan_hdd_validate_context(hdd_ctx);
12642 if (0 != status) {
12643 return -EINVAL;
12644 }
12645
12646 if (!wlan_fwr_mem_dump_test_and_set_read_allowed_bit()) {
12647 hddLog(LOGE, FL("Current mem dump request timed out/failed"));
12648 return -EINVAL;
12649 }
12650
12651 /* run fs_read_handler in an atomic context*/
12652 vos_ssr_protect(__func__);
c_manjeef1495642015-10-13 18:35:01 +053012653 ret_count = wlan_fwr_mem_dump_fsread_handler( buf, count, pos, &bytes_left);
12654 if(bytes_left == 0)
c_manjeecfd1efb2015-09-25 19:32:34 +053012655 {
12656 /*Free the fwr mem dump buffer */
12657 wlan_free_fwr_mem_dump_buffer();
12658 wlan_set_fwr_mem_dump_state(FW_MEM_DUMP_IDLE);
c_manjeef1495642015-10-13 18:35:01 +053012659 ret_count=0;
c_manjeecfd1efb2015-09-25 19:32:34 +053012660 }
12661 /*if SSR/unload code is waiting for memdump_read to finish,signal it*/
12662 vos_ssr_unprotect(__func__);
12663 EXIT();
12664 return ret_count;
12665}
12666
12667/**
12668 * struct memdump_fops - file operations for memory dump feature
12669 * @read - read function for memory dump operation.
12670 *
12671 * This structure initialize the file operation handle for memory
12672 * dump feature
12673 */
12674static const struct file_operations memdump_fops = {
12675 read: memdump_read
12676};
12677
12678/*
12679* wlan_hdd_fw_mem_dump_cb : callback for Fw mem dump request
12680* To be passed by HDD to WDA and called upon receiving of response
12681* from firmware
12682* @fwMemDumpReqContext : memory dump request context
12683* @dump_rsp : dump response from HAL
12684* Returns none
12685*/
12686void wlan_hdd_fw_mem_dump_cb(void *fwMemDumpReqContext,
12687 tAniFwrDumpRsp *dump_rsp)
12688{
c_manjeef1495642015-10-13 18:35:01 +053012689 struct hdd_fw_mem_dump_req_ctx *pHddFwMemDumpCtx = (struct hdd_fw_mem_dump_req_ctx *)fwMemDumpReqContext;
c_manjeecfd1efb2015-09-25 19:32:34 +053012690
c_manjeef1495642015-10-13 18:35:01 +053012691 ENTER();
12692 spin_lock(&hdd_context_lock);
12693 if(!pHddFwMemDumpCtx || (FW_MEM_DUMP_MAGIC != pHddFwMemDumpCtx->magic)) {
12694 spin_unlock(&hdd_context_lock);
12695 return;
12696 }
12697 /* report the status to requesting function and free mem.*/
c_manjeecfd1efb2015-09-25 19:32:34 +053012698 if (dump_rsp->dump_status != eHAL_STATUS_SUCCESS) {
c_manjeef1495642015-10-13 18:35:01 +053012699 hddLog(LOGE, FL("fw dump request declined by fwr"));
12700 //set the request completion variable
12701 complete(&(pHddFwMemDumpCtx->req_completion));
c_manjeecfd1efb2015-09-25 19:32:34 +053012702 //Free the allocated fwr dump
12703 wlan_free_fwr_mem_dump_buffer();
12704 wlan_set_fwr_mem_dump_state(FW_MEM_DUMP_IDLE);
c_manjeecfd1efb2015-09-25 19:32:34 +053012705 }
c_manjeef1495642015-10-13 18:35:01 +053012706 else {
12707 hddLog(LOG1, FL("fw dump request accepted by fwr"));
12708 /* register the HDD callback which will be called by SVC */
12709 wlan_set_svc_fw_mem_dump_req_cb((void*)wlan_hdd_fw_mem_dump_req_cb,(void*)pHddFwMemDumpCtx);
12710 }
12711 spin_unlock(&hdd_context_lock);
c_manjeecfd1efb2015-09-25 19:32:34 +053012712 EXIT();
12713
12714}
12715
12716/**
12717 * memdump_procfs_remove() - Remove file/dir under procfs for memory dump
12718 *
12719 * This function removes file/dir under proc file system that was
12720 * processing firmware memory dump
12721 *
12722 * Return: None
12723 */
12724static void memdump_procfs_remove(void)
12725{
12726 remove_proc_entry(PROCFS_MEMDUMP_NAME, proc_dir);
12727 hddLog(LOG1 , FL("/proc/%s/%s removed\n"),
12728 PROCFS_MEMDUMP_DIR, PROCFS_MEMDUMP_NAME);
12729 remove_proc_entry(PROCFS_MEMDUMP_DIR, NULL);
12730 hddLog(LOG1 , FL("/proc/%s removed\n"), PROCFS_MEMDUMP_DIR);
12731}
12732
12733/**
12734 * memdump_procfs_init() - Initialize procfs for memory dump
12735 *
12736 * @vos_ctx - Global vos context.
12737 *
12738 * This function create file under proc file system to be used later for
12739 * processing firmware memory dump
12740 *
12741 * Return: 0 on success, error code otherwise.
12742 */
12743static int memdump_procfs_init(void *vos_ctx)
12744{
12745 hdd_context_t *hdd_ctx;
12746
12747 hdd_ctx = vos_get_context(VOS_MODULE_ID_HDD, vos_ctx);
12748 if (!hdd_ctx) {
12749 hddLog(LOGE , FL("Invalid HDD context"));
12750 return -EINVAL;
12751 }
12752
12753 proc_dir = proc_mkdir(PROCFS_MEMDUMP_DIR, NULL);
12754 if (proc_dir == NULL) {
12755 remove_proc_entry(PROCFS_MEMDUMP_DIR, NULL);
12756 hddLog(LOGE , FL("Error: Could not initialize /proc/%s"),
12757 PROCFS_MEMDUMP_DIR);
12758 return -ENOMEM;
12759 }
12760
12761 proc_file = proc_create_data(PROCFS_MEMDUMP_NAME,
12762 S_IRUSR | S_IWUSR, proc_dir,
12763 &memdump_fops, hdd_ctx);
12764 if (proc_file == NULL) {
12765 remove_proc_entry(PROCFS_MEMDUMP_NAME, proc_dir);
12766 hddLog(LOGE , FL("Error: Could not initialize /proc/%s"),
12767 PROCFS_MEMDUMP_NAME);
12768 return -ENOMEM;
12769 }
12770
12771 hddLog(LOG1 , FL("/proc/%s/%s created"),
12772 PROCFS_MEMDUMP_DIR, PROCFS_MEMDUMP_NAME);
12773
12774 return 0;
12775}
12776
12777/**
12778 * memdump_init() - Initialization function for memory dump feature
12779 *
12780 * This function creates proc file for memdump feature and registers
12781 * HDD callback function with SME.
12782 *
12783 * Return - 0 on success, error otherwise
12784 */
12785int memdump_init(void)
12786{
12787 hdd_context_t *hdd_ctx;
12788 void *vos_ctx;
12789 int status = 0;
12790
12791 vos_ctx = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
12792 if (!vos_ctx) {
12793 hddLog(LOGE, FL("Invalid VOS context"));
12794 return -EINVAL;
12795 }
12796
12797 hdd_ctx = vos_get_context(VOS_MODULE_ID_HDD, vos_ctx);
12798 if (!hdd_ctx) {
12799 hddLog(LOGE , FL("Invalid HDD context"));
12800 return -EINVAL;
12801 }
12802
12803 status = memdump_procfs_init(vos_ctx);
12804 if (status) {
12805 hddLog(LOGE , FL("Failed to create proc file"));
12806 return status;
12807 }
12808
12809 return 0;
12810}
12811
12812/**
12813 * memdump_deinit() - De initialize memdump feature
12814 *
12815 * This function removes proc file created for memdump feature.
12816 *
12817 * Return: None
12818 */
12819int memdump_deinit(void)
12820{
12821 hdd_context_t *hdd_ctx;
12822 void *vos_ctx;
12823
12824 vos_ctx = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
12825 if (!vos_ctx) {
12826 hddLog(LOGE, FL("Invalid VOS context"));
12827 return -EINVAL;
12828 }
12829
12830 hdd_ctx = vos_get_context(VOS_MODULE_ID_HDD, vos_ctx);
12831 if(!hdd_ctx) {
12832 hddLog(LOGE , FL("Invalid HDD context"));
12833 return -EINVAL;
12834 }
12835
12836 memdump_procfs_remove();
12837 return 0;
12838}
12839
12840/**
12841 * wlan_hdd_fw_mem_dump_req(pHddCtx) - common API(cfg80211/ioctl) for requesting fw mem dump to SME
12842 * Return: HAL status
12843 */
12844
12845int wlan_hdd_fw_mem_dump_req(hdd_context_t * pHddCtx)
12846{
12847 tAniFwrDumpReq fw_mem_dump_req={0};
c_manjeef1495642015-10-13 18:35:01 +053012848 struct hdd_fw_mem_dump_req_ctx fw_mem_dump_ctx;
c_manjeecfd1efb2015-09-25 19:32:34 +053012849 eHalStatus status = eHAL_STATUS_FAILURE;
Abhishek Singh4eca9822015-12-09 18:07:34 +053012850 int ret=0, result;
c_manjeecfd1efb2015-09-25 19:32:34 +053012851 ENTER();
c_manjeef1495642015-10-13 18:35:01 +053012852
c_manjeecfd1efb2015-09-25 19:32:34 +053012853 /*Check whether a dump request is already going on
12854 *Caution this function will free previously held memory if new dump request is allowed*/
12855 if (!wlan_fwr_mem_dump_test_and_set_write_allowed_bit()) {
12856 hddLog(LOGE, FL("Fw memdump already in progress"));
12857 return -EBUSY;
12858 }
12859 //Allocate memory for fw mem dump buffer
12860 ret = wlan_fwr_mem_dump_buffer_allocation();
12861 if(ret == -EFAULT)
12862 {
12863 hddLog(LOGE, FL("Fwr mem dump not supported by FW"));
12864 return ret;
12865 }
12866 if (0 != ret) {
12867 hddLog(LOGE, FL("Fwr mem Allocation failed"));
12868 return -ENOMEM;
12869 }
c_manjeef1495642015-10-13 18:35:01 +053012870 init_completion(&fw_mem_dump_ctx.req_completion);
12871 fw_mem_dump_ctx.magic = FW_MEM_DUMP_MAGIC;
12872 fw_mem_dump_ctx.status = false;
12873
c_manjeecfd1efb2015-09-25 19:32:34 +053012874 fw_mem_dump_req.fwMemDumpReqCallback = wlan_hdd_fw_mem_dump_cb;
c_manjeef1495642015-10-13 18:35:01 +053012875 fw_mem_dump_req.fwMemDumpReqContext = &fw_mem_dump_ctx;
c_manjeecfd1efb2015-09-25 19:32:34 +053012876 status = sme_FwMemDumpReq(pHddCtx->hHal, &fw_mem_dump_req);
12877 if(eHAL_STATUS_SUCCESS != status)
12878 {
12879 hddLog(VOS_TRACE_LEVEL_ERROR,
12880 "%s: fw_mem_dump_req failed ", __func__);
12881 wlan_free_fwr_mem_dump_buffer();
c_manjeef1495642015-10-13 18:35:01 +053012882 ret = -EFAULT;
12883 goto cleanup;
c_manjeecfd1efb2015-09-25 19:32:34 +053012884 }
c_manjeef1495642015-10-13 18:35:01 +053012885 /*wait for fw mem dump completion to send event to userspace*/
Abhishek Singh4eca9822015-12-09 18:07:34 +053012886 result =
12887 wait_for_completion_timeout(&fw_mem_dump_ctx.req_completion,
12888 msecs_to_jiffies(FW_MEM_DUMP_TIMEOUT_MS));
12889 if (0 >= result )
c_manjeef1495642015-10-13 18:35:01 +053012890 {
12891 hddLog(VOS_TRACE_LEVEL_ERROR,
Abhishek Singh4eca9822015-12-09 18:07:34 +053012892 "%s: fw_mem_dump_req timeout %d ", __func__,result);
12893 ret = -ETIMEDOUT;
c_manjeef1495642015-10-13 18:35:01 +053012894 }
12895cleanup:
12896 spin_lock(&hdd_context_lock);
12897 fw_mem_dump_ctx.magic = 0;
Abhishek Singh4eca9822015-12-09 18:07:34 +053012898 if(!ret && !fw_mem_dump_ctx.status)
12899 ret = -EFAULT;
c_manjeef1495642015-10-13 18:35:01 +053012900 spin_unlock(&hdd_context_lock);
c_manjeecfd1efb2015-09-25 19:32:34 +053012901
c_manjeef1495642015-10-13 18:35:01 +053012902 EXIT();
Abhishek Singh4eca9822015-12-09 18:07:34 +053012903 return ret;
c_manjeef1495642015-10-13 18:35:01 +053012904}
12905
12906/**
12907 * HDD callback which will be called by SVC to indicate mem dump completion.
12908 */
12909void wlan_hdd_fw_mem_dump_req_cb(struct hdd_fw_mem_dump_req_ctx* pHddFwMemDumpCtx)
12910{
12911 if (!pHddFwMemDumpCtx) {
12912 hddLog(VOS_TRACE_LEVEL_ERROR,
12913 "%s: HDD context not valid ", __func__);
12914 return;
12915 }
12916 spin_lock(&hdd_context_lock);
12917 /* check the req magic and set status */
12918 if (pHddFwMemDumpCtx->magic == FW_MEM_DUMP_MAGIC)
12919 {
12920 pHddFwMemDumpCtx->status = true;
12921 //signal the completion
12922 complete(&(pHddFwMemDumpCtx->req_completion));
12923 }
12924 else
12925 {
12926 hddLog(VOS_TRACE_LEVEL_ERROR,
12927 "%s: fw mem dump request possible timeout ", __func__);
12928 }
12929 spin_unlock(&hdd_context_lock);
c_manjeecfd1efb2015-09-25 19:32:34 +053012930}
12931
Mahesh A Saptasagar67ab9222015-10-21 15:38:41 +053012932void hdd_initialize_adapter_common(hdd_adapter_t *pAdapter)
12933{
12934 if (NULL == pAdapter)
12935 {
12936 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: pAdapter is NULL ", __func__);
12937 return;
12938 }
12939 init_completion(&pAdapter->session_open_comp_var);
12940 init_completion(&pAdapter->session_close_comp_var);
12941 init_completion(&pAdapter->disconnect_comp_var);
12942 init_completion(&pAdapter->linkup_event_var);
12943 init_completion(&pAdapter->cancel_rem_on_chan_var);
12944 init_completion(&pAdapter->rem_on_chan_ready_event);
12945 init_completion(&pAdapter->pno_comp_var);
12946#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
12947 init_completion(&pAdapter->offchannel_tx_event);
12948#endif
12949 init_completion(&pAdapter->tx_action_cnf_event);
12950#ifdef FEATURE_WLAN_TDLS
12951 init_completion(&pAdapter->tdls_add_station_comp);
12952 init_completion(&pAdapter->tdls_del_station_comp);
12953 init_completion(&pAdapter->tdls_mgmt_comp);
12954 init_completion(&pAdapter->tdls_link_establish_req_comp);
12955#endif
12956
12957#ifdef WLAN_FEATURE_RMC
12958 init_completion(&pAdapter->ibss_peer_info_comp);
12959#endif /* WLAN_FEATURE_RMC */
12960 init_completion(&pAdapter->ula_complete);
12961 init_completion(&pAdapter->change_country_code);
12962
12963#ifdef FEATURE_WLAN_BATCH_SCAN
12964 init_completion(&pAdapter->hdd_set_batch_scan_req_var);
12965 init_completion(&pAdapter->hdd_get_batch_scan_req_var);
12966#endif
12967
12968 return;
12969}
c_manjeecfd1efb2015-09-25 19:32:34 +053012970
12971
Jeff Johnson295189b2012-06-20 16:38:30 -070012972//Register the module init/exit functions
12973module_init(hdd_module_init);
12974module_exit(hdd_module_exit);
12975
12976MODULE_LICENSE("Dual BSD/GPL");
12977MODULE_AUTHOR("Qualcomm Atheros, Inc.");
12978MODULE_DESCRIPTION("WLAN HOST DEVICE DRIVER");
12979
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070012980module_param_call(con_mode, con_mode_handler, param_get_int, &con_mode,
12981 S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
Jeff Johnson32d95a32012-09-10 13:15:23 -070012982
Jeff Johnson76052702013-04-16 13:55:05 -070012983module_param_call(fwpath, fwpath_changed_handler, param_get_string, &fwpath,
Jeff Johnson32d95a32012-09-10 13:15:23 -070012984 S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
Arif Hussain66559122013-11-21 10:11:40 -080012985
12986module_param(enable_dfs_chan_scan, int,
12987 S_IRUSR | S_IRGRP | S_IROTH);
12988
12989module_param(enable_11d, int,
12990 S_IRUSR | S_IRGRP | S_IROTH);
12991
12992module_param(country_code, charp,
12993 S_IRUSR | S_IRGRP | S_IROTH);