blob: 4eb2ff14732be959b6f2aa0e75f683563dbfb8c9 [file] [log] [blame]
Jeff Johnson295189b2012-06-20 16:38:30 -07001/*
Mukul Sharma1fd6efd2015-02-14 00:29:14 +05302 * Copyright (c) 2012-2015 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__);
3508 ret = -EINVAL;
3509 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);
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003518 return -EINVAL;
3519 }
3520
3521 /* Proceed with reassoc */
Varun Reddy Yeturucc661d22013-05-20 11:47:10 -07003522#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
3523 handoffInfo.channel = channel;
3524 vos_mem_copy(handoffInfo.bssid, targetApBssid, sizeof(tSirMacAddr));
3525 sme_HandoffRequest(pHddCtx->hHal, &handoffInfo);
3526#endif
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003527 }
Srinivas Girigowdaad34ca92013-10-22 10:54:29 -07003528 else if (strncmp(command, "SETWESMODE", 10) == 0)
3529 {
3530 tANI_U8 *value = command;
3531 tANI_BOOLEAN wesMode = CFG_ENABLE_WES_MODE_NAME_DEFAULT;
3532
3533 /* Move pointer to ahead of SETWESMODE<delimiter> */
3534 value = value + 11;
3535 /* Convert the value from ascii to integer */
3536 ret = kstrtou8(value, 10, &wesMode);
3537 if (ret < 0)
3538 {
3539 /* If the input value is greater than max value of datatype, then also
3540 kstrtou8 fails */
3541 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3542 "%s: kstrtou8 failed range [%d - %d]", __func__,
3543 CFG_ENABLE_WES_MODE_NAME_MIN,
3544 CFG_ENABLE_WES_MODE_NAME_MAX);
3545 ret = -EINVAL;
3546 goto exit;
3547 }
3548
3549 if ((wesMode < CFG_ENABLE_WES_MODE_NAME_MIN) ||
3550 (wesMode > CFG_ENABLE_WES_MODE_NAME_MAX))
3551 {
3552 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3553 "WES Mode value %d is out of range"
3554 " (Min: %d Max: %d)", wesMode,
3555 CFG_ENABLE_WES_MODE_NAME_MIN,
3556 CFG_ENABLE_WES_MODE_NAME_MAX);
3557 ret = -EINVAL;
3558 goto exit;
3559 }
3560 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3561 "%s: Received Command to Set WES Mode rssi diff = %d", __func__, wesMode);
3562
3563 pHddCtx->cfg_ini->isWESModeEnabled = wesMode;
3564 sme_UpdateWESMode((tHalHandle)(pHddCtx->hHal), wesMode);
3565 }
Mahesh A Saptasagarec7d1092015-04-02 13:41:34 +05303566 else if (strncmp(command, "GETWESMODE", 10) == 0)
Srinivas Girigowdaad34ca92013-10-22 10:54:29 -07003567 {
3568 tANI_BOOLEAN wesMode = sme_GetWESMode((tHalHandle)(pHddCtx->hHal));
3569 char extra[32];
3570 tANI_U8 len = 0;
3571
Arif Hussain826d9412013-11-12 16:44:54 -08003572 len = scnprintf(extra, sizeof(extra), "%s %d", command, wesMode);
Ratnam Rachuri8fe90c62015-08-07 14:03:26 +05303573 len = VOS_MIN(priv_data.total_len, len + 1);
3574 if (copy_to_user(priv_data.buf, &extra, len)) {
Srinivas Girigowdaad34ca92013-10-22 10:54:29 -07003575 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3576 "%s: failed to copy data to user buffer", __func__);
3577 ret = -EFAULT;
3578 goto exit;
3579 }
3580 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003581#endif /* WLAN_FEATURE_VOWIFI_11R || FEATURE_WLAN_ESE || FEATURE_WLAN_LFR */
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003582#ifdef FEATURE_WLAN_LFR
3583 else if (strncmp(command, "SETFASTROAM", 11) == 0)
3584 {
3585 tANI_U8 *value = command;
3586 tANI_U8 lfrMode = CFG_LFR_FEATURE_ENABLED_DEFAULT;
3587
3588 /* Move pointer to ahead of SETFASTROAM<delimiter> */
3589 value = value + 12;
3590 /* Convert the value from ascii to integer */
3591 ret = kstrtou8(value, 10, &lfrMode);
3592 if (ret < 0)
3593 {
3594 /* If the input value is greater than max value of datatype, then also
3595 kstrtou8 fails */
3596 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3597 "%s: kstrtou8 failed range [%d - %d]", __func__,
3598 CFG_LFR_FEATURE_ENABLED_MIN,
3599 CFG_LFR_FEATURE_ENABLED_MAX);
3600 ret = -EINVAL;
3601 goto exit;
3602 }
3603
3604 if ((lfrMode < CFG_LFR_FEATURE_ENABLED_MIN) ||
3605 (lfrMode > CFG_LFR_FEATURE_ENABLED_MAX))
3606 {
3607 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3608 "lfr mode value %d is out of range"
3609 " (Min: %d Max: %d)", lfrMode,
3610 CFG_LFR_FEATURE_ENABLED_MIN,
3611 CFG_LFR_FEATURE_ENABLED_MAX);
3612 ret = -EINVAL;
3613 goto exit;
3614 }
3615
3616 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3617 "%s: Received Command to change lfr mode = %d", __func__, lfrMode);
3618
3619 pHddCtx->cfg_ini->isFastRoamIniFeatureEnabled = lfrMode;
3620 sme_UpdateIsFastRoamIniFeatureEnabled((tHalHandle)(pHddCtx->hHal), lfrMode);
3621 }
3622#endif
3623#ifdef WLAN_FEATURE_VOWIFI_11R
3624 else if (strncmp(command, "SETFASTTRANSITION", 17) == 0)
3625 {
3626 tANI_U8 *value = command;
3627 tANI_U8 ft = CFG_FAST_TRANSITION_ENABLED_NAME_DEFAULT;
3628
3629 /* Move pointer to ahead of SETFASTROAM<delimiter> */
3630 value = value + 18;
3631 /* Convert the value from ascii to integer */
3632 ret = kstrtou8(value, 10, &ft);
3633 if (ret < 0)
3634 {
3635 /* If the input value is greater than max value of datatype, then also
3636 kstrtou8 fails */
3637 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3638 "%s: kstrtou8 failed range [%d - %d]", __func__,
3639 CFG_FAST_TRANSITION_ENABLED_NAME_MIN,
3640 CFG_FAST_TRANSITION_ENABLED_NAME_MAX);
3641 ret = -EINVAL;
3642 goto exit;
3643 }
3644
3645 if ((ft < CFG_FAST_TRANSITION_ENABLED_NAME_MIN) ||
3646 (ft > CFG_FAST_TRANSITION_ENABLED_NAME_MAX))
3647 {
3648 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3649 "ft mode value %d is out of range"
3650 " (Min: %d Max: %d)", ft,
3651 CFG_FAST_TRANSITION_ENABLED_NAME_MIN,
3652 CFG_FAST_TRANSITION_ENABLED_NAME_MAX);
3653 ret = -EINVAL;
3654 goto exit;
3655 }
3656
3657 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3658 "%s: Received Command to change ft mode = %d", __func__, ft);
3659
3660 pHddCtx->cfg_ini->isFastTransitionEnabled = ft;
3661 sme_UpdateFastTransitionEnabled((tHalHandle)(pHddCtx->hHal), ft);
3662 }
Padma, Santhosh Kumar778d8382015-03-04 17:41:22 +05303663 else if (strncmp(command, "SETDFSSCANMODE", 14) == 0)
3664 {
3665 tANI_U8 *value = command;
3666 tANI_U8 dfsScanMode = DFS_CHNL_SCAN_ENABLED_NORMAL;
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05303667
Padma, Santhosh Kumar778d8382015-03-04 17:41:22 +05303668 /* Move pointer to ahead of SETDFSSCANMODE<delimiter> */
3669 value = value + 15;
3670 /* Convert the value from ascii to integer */
3671 ret = kstrtou8(value, 10, &dfsScanMode);
3672 if (ret < 0)
3673 {
3674 /* If the input value is greater than max value of
3675 datatype, then also kstrtou8 fails
3676 */
3677 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3678 "%s: kstrtou8 failed range [%d - %d]", __func__,
3679 CFG_ENABLE_DFS_CHNL_SCAN_MIN,
3680 CFG_ENABLE_DFS_CHNL_SCAN_MAX);
3681 ret = -EINVAL;
3682 goto exit;
3683 }
3684
3685 if ((dfsScanMode < CFG_ENABLE_DFS_CHNL_SCAN_MIN) ||
3686 (dfsScanMode > CFG_ENABLE_DFS_CHNL_SCAN_MAX))
3687 {
3688 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3689 "dfsScanMode value %d is out of range"
3690 " (Min: %d Max: %d)", dfsScanMode,
3691 CFG_ENABLE_DFS_CHNL_SCAN_MIN,
3692 CFG_ENABLE_DFS_CHNL_SCAN_MAX);
3693 ret = -EINVAL;
3694 goto exit;
3695 }
3696 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3697 "%s: Received Command to Set DFS Scan Mode = %d",
3698 __func__, dfsScanMode);
3699
3700 ret = wlan_hdd_handle_dfs_chan_scan(pHddCtx, dfsScanMode);
3701 }
3702 else if (strncmp(command, "GETDFSSCANMODE", 14) == 0)
3703 {
3704 tANI_U8 dfsScanMode = sme_GetDFSScanMode(pHddCtx->hHal);
3705 char extra[32];
3706 tANI_U8 len = 0;
3707
3708 len = scnprintf(extra, sizeof(extra), "%s %d", command, dfsScanMode);
Ratheesh S P767224e2015-07-16 15:35:51 +05303709 len = VOS_MIN(priv_data.total_len, len + 1);
3710 if (copy_to_user(priv_data.buf, &extra, len))
Padma, Santhosh Kumar778d8382015-03-04 17:41:22 +05303711 {
3712 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3713 "%s: failed to copy data to user buffer", __func__);
3714 ret = -EFAULT;
3715 goto exit;
3716 }
3717 }
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05303718 else if (strncmp(command, "FASTREASSOC", 11) == 0)
3719 {
3720 tANI_U8 *value = command;
Padma, Santhosh Kumarf4582d32014-11-06 19:24:51 +05303721 tANI_U8 channel = 0;
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05303722 tSirMacAddr targetApBssid;
3723 tANI_U8 trigger = 0;
3724 eHalStatus status = eHAL_STATUS_SUCCESS;
Padma, Santhosh Kumarb980a6f2014-11-06 19:07:24 +05303725 tHalHandle hHal;
3726 v_U32_t roamId = 0;
3727 tCsrRoamModifyProfileFields modProfileFields;
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05303728 hdd_station_ctx_t *pHddStaCtx = NULL;
3729 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Padma, Santhosh Kumarb980a6f2014-11-06 19:07:24 +05303730 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05303731
3732 /* if not associated, no need to proceed with reassoc */
3733 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
3734 {
3735 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s:Not associated!",__func__);
3736 ret = -EINVAL;
3737 goto exit;
3738 }
3739
Padma, Santhosh Kumarf4582d32014-11-06 19:24:51 +05303740 status = hdd_parse_reassoc_command_data(value, targetApBssid, &channel);
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05303741 if (eHAL_STATUS_SUCCESS != status)
3742 {
3743 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3744 "%s: Failed to parse reassoc command data", __func__);
3745 ret = -EINVAL;
3746 goto exit;
3747 }
3748
3749 /* if the target bssid is same as currently associated AP,
Padma, Santhosh Kumarb980a6f2014-11-06 19:07:24 +05303750 issue reassoc to same AP */
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05303751 if (VOS_TRUE == vos_mem_compare(targetApBssid,
3752 pHddStaCtx->conn_info.bssId, sizeof(tSirMacAddr)))
3753 {
Abhishek Singh5333d472015-10-15 15:49:24 +05303754 /* Reassoc to same AP, only supported for Open Security*/
3755 if ((pHddStaCtx->conn_info.ucEncryptionType ||
3756 pHddStaCtx->conn_info.mcEncryptionType))
3757 {
3758 hddLog(LOGE,
3759 FL("Reassoc to same AP, only supported for Open Security"));
3760 ret = -ENOTSUPP;
3761 goto exit;
3762 }
3763 hddLog(LOG1,
3764 FL("11r Reassoc BSSID is same as currently associated AP bssid"));
Padma, Santhosh Kumarb980a6f2014-11-06 19:07:24 +05303765 sme_GetModifyProfileFields(hHal, pAdapter->sessionId,
3766 &modProfileFields);
3767 sme_RoamReassoc(hHal, pAdapter->sessionId,
3768 NULL, modProfileFields, &roamId, 1);
Abhishek Singh5333d472015-10-15 15:49:24 +05303769 goto exit;
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05303770 }
Padma, Santhosh Kumar0fa809b2014-11-13 14:56:56 +05303771
3772 /* Check channel number is a valid channel number */
3773 if(VOS_STATUS_SUCCESS !=
3774 wlan_hdd_validate_operation_channel(pAdapter, channel))
3775 {
3776 hddLog(VOS_TRACE_LEVEL_ERROR,
3777 "%s: Invalid Channel [%d]", __func__, channel);
Abhishek Singh5333d472015-10-15 15:49:24 +05303778 ret = -EINVAL;
3779 goto exit;
Padma, Santhosh Kumar0fa809b2014-11-13 14:56:56 +05303780 }
3781
Padma, Santhosh Kumarf4582d32014-11-06 19:24:51 +05303782 trigger = eSME_ROAM_TRIGGER_SCAN;
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05303783
3784 /* Proceed with scan/roam */
3785 smeIssueFastRoamNeighborAPEvent(WLAN_HDD_GET_HAL_CTX(pAdapter),
3786 &targetApBssid[0],
Mukul Sharma9e4e0f92015-02-13 18:45:20 +05303787 (tSmeFastRoamTrigger)(trigger),
3788 channel);
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05303789 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003790#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003791#ifdef FEATURE_WLAN_ESE
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003792 else if (strncmp(command, "SETCCXMODE", 10) == 0)
3793 {
3794 tANI_U8 *value = command;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003795 tANI_U8 eseMode = CFG_ESE_FEATURE_ENABLED_DEFAULT;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003796
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003797 /* Check if the features OKC/ESE/11R are supported simultaneously,
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07003798 then this operation is not permitted (return FAILURE) */
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003799 if (sme_getIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal)) &&
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07003800 hdd_is_okc_mode_enabled(pHddCtx) &&
3801 sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal)))
3802 {
3803 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003804 "%s: OKC/ESE/11R are supported simultaneously"
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07003805 " hence this operation is not permitted!", __func__);
3806 ret = -EPERM;
3807 goto exit;
3808 }
3809
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003810 /* Move pointer to ahead of SETCCXMODE<delimiter> */
3811 value = value + 11;
3812 /* Convert the value from ascii to integer */
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003813 ret = kstrtou8(value, 10, &eseMode);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003814 if (ret < 0)
3815 {
3816 /* If the input value is greater than max value of datatype, then also
3817 kstrtou8 fails */
3818 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3819 "%s: kstrtou8 failed range [%d - %d]", __func__,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003820 CFG_ESE_FEATURE_ENABLED_MIN,
3821 CFG_ESE_FEATURE_ENABLED_MAX);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003822 ret = -EINVAL;
3823 goto exit;
3824 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003825 if ((eseMode < CFG_ESE_FEATURE_ENABLED_MIN) ||
3826 (eseMode > CFG_ESE_FEATURE_ENABLED_MAX))
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003827 {
3828 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003829 "Ese mode value %d is out of range"
3830 " (Min: %d Max: %d)", eseMode,
3831 CFG_ESE_FEATURE_ENABLED_MIN,
3832 CFG_ESE_FEATURE_ENABLED_MAX);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003833 ret = -EINVAL;
3834 goto exit;
3835 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003836 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003837 "%s: Received Command to change ese mode = %d", __func__, eseMode);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003838
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003839 pHddCtx->cfg_ini->isEseIniFeatureEnabled = eseMode;
3840 sme_UpdateIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal), eseMode);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003841 }
3842#endif
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003843 else if (strncmp(command, "SETROAMSCANCONTROL", 18) == 0)
3844 {
3845 tANI_U8 *value = command;
3846 tANI_BOOLEAN roamScanControl = 0;
3847
3848 /* Move pointer to ahead of SETROAMSCANCONTROL<delimiter> */
3849 value = value + 19;
3850 /* Convert the value from ascii to integer */
3851 ret = kstrtou8(value, 10, &roamScanControl);
3852 if (ret < 0)
3853 {
3854 /* If the input value is greater than max value of datatype, then also
3855 kstrtou8 fails */
3856 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3857 "%s: kstrtou8 failed ", __func__);
3858 ret = -EINVAL;
3859 goto exit;
3860 }
3861
3862 if (0 != roamScanControl)
3863 {
3864 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3865 "roam scan control invalid value = %d",
3866 roamScanControl);
3867 ret = -EINVAL;
3868 goto exit;
3869 }
3870 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3871 "%s: Received Command to Set roam scan control = %d", __func__, roamScanControl);
3872
3873 sme_SetRoamScanControl((tHalHandle)(pHddCtx->hHal), roamScanControl);
3874 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003875#ifdef FEATURE_WLAN_OKC
3876 else if (strncmp(command, "SETOKCMODE", 10) == 0)
3877 {
3878 tANI_U8 *value = command;
3879 tANI_U8 okcMode = CFG_OKC_FEATURE_ENABLED_DEFAULT;
3880
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003881 /* Check if the features OKC/ESE/11R are supported simultaneously,
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07003882 then this operation is not permitted (return FAILURE) */
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003883 if (sme_getIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal)) &&
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07003884 hdd_is_okc_mode_enabled(pHddCtx) &&
3885 sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal)))
3886 {
3887 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003888 "%s: OKC/ESE/11R are supported simultaneously"
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07003889 " hence this operation is not permitted!", __func__);
3890 ret = -EPERM;
3891 goto exit;
3892 }
3893
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003894 /* Move pointer to ahead of SETOKCMODE<delimiter> */
3895 value = value + 11;
3896 /* Convert the value from ascii to integer */
3897 ret = kstrtou8(value, 10, &okcMode);
3898 if (ret < 0)
3899 {
3900 /* If the input value is greater than max value of datatype, then also
3901 kstrtou8 fails */
3902 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3903 "%s: kstrtou8 failed range [%d - %d]", __func__,
3904 CFG_OKC_FEATURE_ENABLED_MIN,
3905 CFG_OKC_FEATURE_ENABLED_MAX);
3906 ret = -EINVAL;
3907 goto exit;
3908 }
3909
3910 if ((okcMode < CFG_OKC_FEATURE_ENABLED_MIN) ||
3911 (okcMode > CFG_OKC_FEATURE_ENABLED_MAX))
3912 {
3913 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3914 "Okc mode value %d is out of range"
3915 " (Min: %d Max: %d)", okcMode,
3916 CFG_OKC_FEATURE_ENABLED_MIN,
3917 CFG_OKC_FEATURE_ENABLED_MAX);
3918 ret = -EINVAL;
3919 goto exit;
3920 }
3921
3922 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3923 "%s: Received Command to change okc mode = %d", __func__, okcMode);
3924
3925 pHddCtx->cfg_ini->isOkcIniFeatureEnabled = okcMode;
3926 }
Srinivas Girigowdaad34ca92013-10-22 10:54:29 -07003927#endif /* FEATURE_WLAN_OKC */
Mahesh A Saptasagarec7d1092015-04-02 13:41:34 +05303928 else if (strncmp(command, "GETROAMSCANCONTROL", 18) == 0)
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003929 {
3930 tANI_BOOLEAN roamScanControl = sme_GetRoamScanControl((tHalHandle)(pHddCtx->hHal));
3931 char extra[32];
3932 tANI_U8 len = 0;
3933
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003934 len = scnprintf(extra, sizeof(extra), "%s %d",
3935 command, roamScanControl);
Ratnam Rachuri083ada82015-08-07 14:01:05 +05303936 len = VOS_MIN(priv_data.total_len, len + 1);
3937 if (copy_to_user(priv_data.buf, &extra, len)) {
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003938 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3939 "%s: failed to copy data to user buffer", __func__);
3940 ret = -EFAULT;
3941 goto exit;
3942 }
3943 }
Gopichand Nakkala227c7f32013-06-26 22:44:57 +05303944#ifdef WLAN_FEATURE_PACKET_FILTERING
3945 else if (strncmp(command, "ENABLE_PKTFILTER_IPV6", 21) == 0)
3946 {
3947 tANI_U8 filterType = 0;
3948 tANI_U8 *value = command;
3949
3950 /* Move pointer to ahead of ENABLE_PKTFILTER_IPV6<delimiter> */
3951 value = value + 22;
3952
3953 /* Convert the value from ascii to integer */
3954 ret = kstrtou8(value, 10, &filterType);
3955 if (ret < 0)
3956 {
3957 /* If the input value is greater than max value of datatype,
3958 * then also kstrtou8 fails
3959 */
3960 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3961 "%s: kstrtou8 failed range ", __func__);
3962 ret = -EINVAL;
3963 goto exit;
3964 }
3965
3966 if (filterType != 0 && filterType != 1)
3967 {
3968 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3969 "%s: Accepted Values are 0 and 1 ", __func__);
3970 ret = -EINVAL;
3971 goto exit;
3972 }
3973 wlan_hdd_setIPv6Filter(WLAN_HDD_GET_CTX(pAdapter), filterType,
3974 pAdapter->sessionId);
3975 }
3976#endif
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05303977 else if (strncmp(command, "BTCOEXMODE", 10) == 0 )
3978 {
Kiet Lamad161252014-07-22 11:23:32 -07003979 char *dhcpPhase;
Satyanarayana Dash1faea4f2014-09-22 16:21:04 +05303980 int ret;
3981
Kiet Lamad161252014-07-22 11:23:32 -07003982 dhcpPhase = command + 11;
3983 if ('1' == *dhcpPhase)
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05303984 {
Deepthi Gowribfd17132014-11-14 17:59:04 +05303985 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Kiet Lamad161252014-07-22 11:23:32 -07003986 FL("send DHCP START indication"));
c_hpothu9b781ba2013-12-30 20:57:45 +05303987
3988 pHddCtx->btCoexModeSet = TRUE;
Kiet Lamad161252014-07-22 11:23:32 -07003989
Satyanarayana Dash1faea4f2014-09-22 16:21:04 +05303990 ret = wlan_hdd_scan_abort(pAdapter);
3991 if (ret < 0)
3992 {
3993 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3994 FL("failed to abort existing scan %d"), ret);
3995 }
3996
Kiet Lamad161252014-07-22 11:23:32 -07003997 sme_DHCPStartInd(pHddCtx->hHal, pAdapter->device_mode,
3998 pAdapter->sessionId);
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05303999 }
Kiet Lamad161252014-07-22 11:23:32 -07004000 else if ('2' == *dhcpPhase)
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05304001 {
Deepthi Gowribfd17132014-11-14 17:59:04 +05304002 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Kiet Lamad161252014-07-22 11:23:32 -07004003 FL("send DHCP STOP indication"));
c_hpothu9b781ba2013-12-30 20:57:45 +05304004
4005 pHddCtx->btCoexModeSet = FALSE;
Kiet Lamad161252014-07-22 11:23:32 -07004006
4007 sme_DHCPStopInd(pHddCtx->hHal, pAdapter->device_mode,
4008 pAdapter->sessionId);
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05304009 }
4010 }
Jeff Johnsonf54df2c2013-07-24 11:43:39 -07004011 else if (strncmp(command, "SCAN-ACTIVE", 11) == 0)
4012 {
c_hpothudbefd3e2014-04-28 15:59:47 +05304013 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4014 FL("making default scan to ACTIVE"));
4015 pHddCtx->scan_info.scan_mode = eSIR_ACTIVE_SCAN;
Jeff Johnsonf54df2c2013-07-24 11:43:39 -07004016 }
4017 else if (strncmp(command, "SCAN-PASSIVE", 12) == 0)
4018 {
c_hpothudbefd3e2014-04-28 15:59:47 +05304019 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4020 FL("making default scan to PASSIVE"));
4021 pHddCtx->scan_info.scan_mode = eSIR_PASSIVE_SCAN;
Jeff Johnsonf54df2c2013-07-24 11:43:39 -07004022 }
Hanumantha Reddy Pothula212243c2013-08-01 17:28:31 +05304023 else if (strncmp(command, "GETDWELLTIME", 12) == 0)
4024 {
4025 hdd_config_t *pCfg = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
4026 char extra[32];
4027 tANI_U8 len = 0;
4028
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05304029 memset(extra, 0, sizeof(extra));
4030 ret = hdd_get_dwell_time(pCfg, command, extra, sizeof(extra), &len);
Ratnam Rachuri12d5d462015-08-07 14:10:23 +05304031 len = VOS_MIN(priv_data.total_len, len + 1);
4032 if (ret != 0 || copy_to_user(priv_data.buf, &extra, len)) {
Hanumantha Reddy Pothula212243c2013-08-01 17:28:31 +05304033 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4034 "%s: failed to copy data to user buffer", __func__);
4035 ret = -EFAULT;
4036 goto exit;
4037 }
4038 ret = len;
4039 }
4040 else if (strncmp(command, "SETDWELLTIME", 12) == 0)
4041 {
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05304042 ret = hdd_set_dwell_time(pAdapter, command);
Hanumantha Reddy Pothula212243c2013-08-01 17:28:31 +05304043 }
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07004044 else if ( strncasecmp(command, "MIRACAST", 8) == 0 )
4045 {
4046 tANI_U8 filterType = 0;
4047 tANI_U8 *value;
4048 value = command + 9;
4049
4050 /* Convert the value from ascii to integer */
4051 ret = kstrtou8(value, 10, &filterType);
4052 if (ret < 0)
4053 {
4054 /* If the input value is greater than max value of datatype,
4055 * then also kstrtou8 fails
4056 */
4057 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4058 "%s: kstrtou8 failed range ", __func__);
4059 ret = -EINVAL;
4060 goto exit;
4061 }
4062 if ((filterType < WLAN_HDD_DRIVER_MIRACAST_CFG_MIN_VAL ) ||
4063 (filterType > WLAN_HDD_DRIVER_MIRACAST_CFG_MAX_VAL))
4064 {
4065 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4066 "%s: Accepted Values are 0 to 2. 0-Disabled, 1-Source,"
4067 " 2-Sink ", __func__);
4068 ret = -EINVAL;
4069 goto exit;
4070 }
4071 //Filtertype value should be either 0-Disabled, 1-Source, 2-sink
4072 pHddCtx->drvr_miracast = filterType;
Kaushik, Sushant96122442014-10-21 16:40:18 +05304073 pScanInfo = &pHddCtx->scan_info;
4074 if (filterType && pScanInfo != NULL &&
4075 pHddCtx->scan_info.mScanPending)
4076 {
4077 /*Miracast Session started. Abort Scan */
4078 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4079 "%s, Aborting Scan For Miracast",__func__);
4080 hdd_abort_mac_scan(pHddCtx, pScanInfo->sessionId,
4081 eCSR_SCAN_ABORT_DEFAULT);
4082 }
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07004083 hdd_tx_rx_pkt_cnt_stat_timer_handler(pHddCtx);
Ganesh Kondabattini8f6e3b32014-08-25 16:07:54 +05304084 sme_SetMiracastMode(pHddCtx->hHal, pHddCtx->drvr_miracast);
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07004085 }
Leo Chang614d2072013-08-22 14:59:44 -07004086 else if (strncmp(command, "SETMCRATE", 9) == 0)
4087 {
Leo Chang614d2072013-08-22 14:59:44 -07004088 tANI_U8 *value = command;
4089 int targetRate;
Leo Chang1f98cbd2013-10-17 15:03:52 -07004090 tSirRateUpdateInd *rateUpdate;
4091 eHalStatus status;
Leo Chang614d2072013-08-22 14:59:44 -07004092
4093 /* Only valid for SAP mode */
4094 if (WLAN_HDD_SOFTAP != pAdapter->device_mode)
4095 {
4096 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4097 "%s: SAP mode is not running", __func__);
4098 ret = -EFAULT;
4099 goto exit;
4100 }
4101
4102 /* Move pointer to ahead of SETMCRATE<delimiter> */
4103 /* input value is in units of hundred kbps */
4104 value = value + 10;
4105 /* Convert the value from ascii to integer, decimal base */
4106 ret = kstrtouint(value, 10, &targetRate);
4107
Leo Chang1f98cbd2013-10-17 15:03:52 -07004108 rateUpdate = (tSirRateUpdateInd *)vos_mem_malloc(sizeof(tSirRateUpdateInd));
4109 if (NULL == rateUpdate)
Leo Chang614d2072013-08-22 14:59:44 -07004110 {
Leo Chang1f98cbd2013-10-17 15:03:52 -07004111 hddLog(VOS_TRACE_LEVEL_ERROR,
4112 "%s: SETMCRATE indication alloc fail", __func__);
4113 ret = -EFAULT;
4114 goto exit;
4115 }
4116 vos_mem_zero(rateUpdate, sizeof(tSirRateUpdateInd ));
4117
4118 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4119 "MC Target rate %d", targetRate);
4120 /* Ignore unicast */
4121 rateUpdate->ucastDataRate = -1;
4122 rateUpdate->mcastDataRate24GHz = targetRate;
4123 rateUpdate->mcastDataRate5GHz = targetRate;
4124 rateUpdate->mcastDataRate24GHzTxFlag = 0;
4125 rateUpdate->mcastDataRate5GHzTxFlag = 0;
4126 status = sme_SendRateUpdateInd(pHddCtx->hHal, rateUpdate);
4127 if (eHAL_STATUS_SUCCESS != status)
4128 {
4129 hddLog(VOS_TRACE_LEVEL_ERROR,
4130 "%s: SET_MC_RATE failed", __func__);
4131 vos_mem_free(rateUpdate);
4132 ret = -EFAULT;
4133 goto exit;
Leo Chang614d2072013-08-22 14:59:44 -07004134 }
4135 }
Rajeev79dbe4c2013-10-05 11:03:42 +05304136#ifdef FEATURE_WLAN_BATCH_SCAN
Rajeev Kumar8b373292014-01-08 20:36:55 -08004137 else if (strncmp(command, "WLS_BATCHING", 12) == 0)
Rajeev79dbe4c2013-10-05 11:03:42 +05304138 {
Rajeev Kumar8b373292014-01-08 20:36:55 -08004139 ret = hdd_handle_batch_scan_ioctl(pAdapter, &priv_data, command);
Rajeev79dbe4c2013-10-05 11:03:42 +05304140 }
4141#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004142#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004143 else if (strncmp(command, "SETCCXROAMSCANCHANNELS", 22) == 0)
4144 {
4145 tANI_U8 *value = command;
4146 tANI_U8 ChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
4147 tANI_U8 numChannels = 0;
4148 eHalStatus status = eHAL_STATUS_SUCCESS;
4149
4150 status = hdd_parse_channellist(value, ChannelList, &numChannels);
4151 if (eHAL_STATUS_SUCCESS != status)
4152 {
4153 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4154 "%s: Failed to parse channel list information", __func__);
4155 ret = -EINVAL;
4156 goto exit;
4157 }
4158
4159 if (numChannels > WNI_CFG_VALID_CHANNEL_LIST_LEN)
4160 {
4161 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4162 "%s: number of channels (%d) supported exceeded max (%d)", __func__,
4163 numChannels, WNI_CFG_VALID_CHANNEL_LIST_LEN);
4164 ret = -EINVAL;
4165 goto exit;
4166 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004167 status = sme_SetEseRoamScanChannelList((tHalHandle)(pHddCtx->hHal),
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004168 ChannelList,
4169 numChannels);
4170 if (eHAL_STATUS_SUCCESS != status)
4171 {
4172 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4173 "%s: Failed to update channel list information", __func__);
4174 ret = -EINVAL;
4175 goto exit;
4176 }
4177 }
4178 else if (strncmp(command, "GETTSMSTATS", 11) == 0)
4179 {
4180 tANI_U8 *value = command;
4181 char extra[128] = {0};
4182 int len = 0;
4183 tANI_U8 tid = 0;
4184 hdd_station_ctx_t *pHddStaCtx = NULL;
4185 tAniTrafStrmMetrics tsmMetrics;
4186 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4187
4188 /* if not associated, return error */
4189 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
4190 {
4191 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "%s:Not associated!",__func__);
4192 ret = -EINVAL;
4193 goto exit;
4194 }
4195
4196 /* Move pointer to ahead of GETTSMSTATS<delimiter> */
4197 value = value + 12;
4198 /* Convert the value from ascii to integer */
4199 ret = kstrtou8(value, 10, &tid);
4200 if (ret < 0)
4201 {
4202 /* If the input value is greater than max value of datatype, then also
4203 kstrtou8 fails */
4204 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4205 "%s: kstrtou8 failed range [%d - %d]", __func__,
4206 TID_MIN_VALUE,
4207 TID_MAX_VALUE);
4208 ret = -EINVAL;
4209 goto exit;
4210 }
4211
4212 if ((tid < TID_MIN_VALUE) || (tid > TID_MAX_VALUE))
4213 {
4214 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4215 "tid value %d is out of range"
4216 " (Min: %d Max: %d)", tid,
4217 TID_MIN_VALUE,
4218 TID_MAX_VALUE);
4219 ret = -EINVAL;
4220 goto exit;
4221 }
4222
4223 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4224 "%s: Received Command to get tsm stats tid = %d", __func__, tid);
4225
4226 if (VOS_STATUS_SUCCESS != hdd_get_tsm_stats(pAdapter, tid, &tsmMetrics))
4227 {
4228 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4229 "%s: failed to get tsm stats", __func__);
4230 ret = -EFAULT;
4231 goto exit;
4232 }
4233
4234 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4235 "UplinkPktQueueDly(%d)\n"
4236 "UplinkPktQueueDlyHist[0](%d)\n"
4237 "UplinkPktQueueDlyHist[1](%d)\n"
4238 "UplinkPktQueueDlyHist[2](%d)\n"
4239 "UplinkPktQueueDlyHist[3](%d)\n"
Arun Kumar Khandavallie8768212014-02-17 16:43:34 +05304240 "UplinkPktTxDly(%u)\n"
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004241 "UplinkPktLoss(%d)\n"
4242 "UplinkPktCount(%d)\n"
4243 "RoamingCount(%d)\n"
4244 "RoamingDly(%d)", tsmMetrics.UplinkPktQueueDly,
4245 tsmMetrics.UplinkPktQueueDlyHist[0],
4246 tsmMetrics.UplinkPktQueueDlyHist[1],
4247 tsmMetrics.UplinkPktQueueDlyHist[2],
4248 tsmMetrics.UplinkPktQueueDlyHist[3],
4249 tsmMetrics.UplinkPktTxDly, tsmMetrics.UplinkPktLoss,
4250 tsmMetrics.UplinkPktCount, tsmMetrics.RoamingCount, tsmMetrics.RoamingDly);
4251
4252 /* Output TSM stats is of the format
4253 GETTSMSTATS [PktQueueDly] [PktQueueDlyHist[0]]:[PktQueueDlyHist[1]] ...[RoamingDly]
4254 eg., GETTSMSTATS 10 1:0:0:161 20 1 17 8 39800 */
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004255 len = scnprintf(extra, sizeof(extra), "%s %d %d:%d:%d:%d %u %d %d %d %d", command,
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004256 tsmMetrics.UplinkPktQueueDly, tsmMetrics.UplinkPktQueueDlyHist[0],
4257 tsmMetrics.UplinkPktQueueDlyHist[1], tsmMetrics.UplinkPktQueueDlyHist[2],
4258 tsmMetrics.UplinkPktQueueDlyHist[3], tsmMetrics.UplinkPktTxDly,
4259 tsmMetrics.UplinkPktLoss, tsmMetrics.UplinkPktCount, tsmMetrics.RoamingCount,
4260 tsmMetrics.RoamingDly);
4261
Ratnam Rachurid53009c2015-08-07 13:59:00 +05304262 len = VOS_MIN(priv_data.total_len, len + 1);
4263 if (copy_to_user(priv_data.buf, &extra, len)) {
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004264 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4265 "%s: failed to copy data to user buffer", __func__);
4266 ret = -EFAULT;
4267 goto exit;
4268 }
4269 }
4270 else if (strncmp(command, "SETCCKMIE", 9) == 0)
4271 {
4272 tANI_U8 *value = command;
4273 tANI_U8 *cckmIe = NULL;
4274 tANI_U8 cckmIeLen = 0;
4275 eHalStatus status = eHAL_STATUS_SUCCESS;
4276
4277 status = hdd_parse_get_cckm_ie(value, &cckmIe, &cckmIeLen);
4278 if (eHAL_STATUS_SUCCESS != status)
4279 {
4280 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4281 "%s: Failed to parse cckm ie data", __func__);
4282 ret = -EINVAL;
4283 goto exit;
4284 }
4285
4286 if (cckmIeLen > DOT11F_IE_RSN_MAX_LEN)
4287 {
4288 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4289 "%s: CCKM Ie input length is more than max[%d]", __func__,
4290 DOT11F_IE_RSN_MAX_LEN);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08004291 vos_mem_free(cckmIe);
4292 cckmIe = NULL;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004293 ret = -EINVAL;
4294 goto exit;
4295 }
4296 sme_SetCCKMIe((tHalHandle)(pHddCtx->hHal), pAdapter->sessionId, cckmIe, cckmIeLen);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08004297 vos_mem_free(cckmIe);
4298 cckmIe = NULL;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004299 }
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004300 else if (strncmp(command, "CCXBEACONREQ", 12) == 0)
4301 {
4302 tANI_U8 *value = command;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004303 tCsrEseBeaconReq eseBcnReq;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004304 eHalStatus status = eHAL_STATUS_SUCCESS;
Srinivas Girigowda0c6d7fe2014-05-28 18:18:10 -07004305
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004306 status = hdd_parse_ese_beacon_req(value, &eseBcnReq);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004307 if (eHAL_STATUS_SUCCESS != status)
4308 {
4309 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004310 "%s: Failed to parse ese beacon req", __func__);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004311 ret = -EINVAL;
4312 goto exit;
4313 }
Srinivas Girigowda0c6d7fe2014-05-28 18:18:10 -07004314 if (!hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))) {
4315 hddLog(VOS_TRACE_LEVEL_INFO, FL("Not associated"));
4316 hdd_indicateEseBcnReportNoResults (pAdapter,
4317 eseBcnReq.bcnReq[0].measurementToken,
4318 0x02, //BIT(1) set for measurement done
4319 0); // no BSS
4320 goto exit;
4321 }
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004322
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004323 status = sme_SetEseBeaconRequest((tHalHandle)(pHddCtx->hHal), pAdapter->sessionId, &eseBcnReq);
4324 if (eHAL_STATUS_SUCCESS != status)
4325 {
4326 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4327 "%s: sme_SetEseBeaconRequest failed (%d)", __func__, status);
4328 ret = -EINVAL;
4329 goto exit;
4330 }
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004331 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004332#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
c_hpothu92367912014-05-01 15:18:17 +05304333 else if (strncmp(command, "GETBCNMISSRATE", 14) == 0)
4334 {
4335 eHalStatus status;
4336 char buf[32], len;
4337 long waitRet;
4338 bcnMissRateContext_t getBcnMissRateCtx;
4339
4340 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4341
4342 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
4343 {
4344 hddLog(VOS_TRACE_LEVEL_WARN,
4345 FL("GETBCNMISSRATE: STA is not in connected state"));
4346 ret = -1;
4347 goto exit;
4348 }
4349
4350 init_completion(&(getBcnMissRateCtx.completion));
4351 getBcnMissRateCtx.magic = BCN_MISS_RATE_CONTEXT_MAGIC;
4352
4353 status = sme_getBcnMissRate((tHalHandle)(pHddCtx->hHal),
4354 pAdapter->sessionId,
4355 (void *)getBcnMissRateCB,
4356 (void *)(&getBcnMissRateCtx));
4357 if( eHAL_STATUS_SUCCESS != status)
4358 {
4359 hddLog(VOS_TRACE_LEVEL_INFO,
4360 FL("GETBCNMISSRATE: fail to post WDA cmd"));
4361 ret = -EINVAL;
4362 goto exit;
4363 }
4364
4365 waitRet = wait_for_completion_interruptible_timeout
4366 (&getBcnMissRateCtx.completion, BCN_MISS_RATE_TIME);
4367 if(waitRet <= 0)
4368 {
4369 hddLog(VOS_TRACE_LEVEL_ERROR,
4370 FL("failed to wait on bcnMissRateComp %d"), ret);
4371
4372 //Make magic number to zero so that callback is not called.
4373 spin_lock(&hdd_context_lock);
4374 getBcnMissRateCtx.magic = 0x0;
4375 spin_unlock(&hdd_context_lock);
4376 ret = -EINVAL;
4377 goto exit;
4378 }
4379
4380 hddLog(VOS_TRACE_LEVEL_INFO,
4381 FL("GETBCNMISSRATE: bcnMissRate: %d"), gbcnMissRate);
4382
4383 len = snprintf(buf, sizeof(buf), "GETBCNMISSRATE %d", gbcnMissRate);
4384 if (copy_to_user(priv_data.buf, &buf, len + 1))
4385 {
4386 hddLog(VOS_TRACE_LEVEL_ERROR,
4387 "%s: failed to copy data to user buffer", __func__);
4388 ret = -EFAULT;
4389 goto exit;
4390 }
4391 ret = len;
4392 }
Atul Mittal87ec2422014-09-24 13:12:50 +05304393#ifdef FEATURE_WLAN_TDLS
4394 else if (strncmp(command, "TDLSSECONDARYCHANNELOFFSET", 26) == 0) {
4395 tANI_U8 *value = command;
4396 int set_value;
4397 /* Move pointer to ahead of TDLSOFFCH*/
4398 value += 26;
4399 sscanf(value, "%d", &set_value);
4400 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4401 "%s: Tdls offchannel offset:%d",
4402 __func__, set_value);
4403 ret = iw_set_tdlssecoffchanneloffset(pHddCtx, set_value);
4404 if (ret < 0)
4405 {
4406 ret = -EINVAL;
4407 goto exit;
4408 }
4409
4410 } else if (strncmp(command, "TDLSOFFCHANNELMODE", 18) == 0) {
4411 tANI_U8 *value = command;
4412 int set_value;
4413 /* Move pointer to ahead of tdlsoffchnmode*/
4414 value += 18;
4415 sscanf(value, "%d", &set_value);
4416 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4417 "%s: Tdls offchannel mode:%d",
4418 __func__, set_value);
4419 ret = iw_set_tdlsoffchannelmode(pAdapter, set_value);
4420 if (ret < 0)
4421 {
4422 ret = -EINVAL;
4423 goto exit;
4424 }
4425 } else if (strncmp(command, "TDLSOFFCHANNEL", 14) == 0) {
4426 tANI_U8 *value = command;
4427 int set_value;
4428 /* Move pointer to ahead of TDLSOFFCH*/
4429 value += 14;
4430 sscanf(value, "%d", &set_value);
4431 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4432 "%s: Tdls offchannel num: %d",
4433 __func__, set_value);
4434 ret = iw_set_tdlsoffchannel(pHddCtx, set_value);
4435 if (ret < 0)
4436 {
4437 ret = -EINVAL;
4438 goto exit;
4439 }
4440 }
4441#endif
Satyanarayana Dash72806012014-12-02 14:30:08 +05304442 else if (strncmp(command, "GETFWSTATS", 10) == 0)
4443 {
4444 eHalStatus status;
4445 char *buf = NULL;
4446 char len;
4447 long waitRet;
4448 fwStatsContext_t fwStatsCtx;
Abhishek Singh08aa7762014-12-16 13:59:03 +05304449 tSirFwStatsResult *fwStatsRsp = &(pAdapter->fwStatsRsp);
Satyanarayana Dash72806012014-12-02 14:30:08 +05304450 tANI_U8 *ptr = command;
4451 int stats = *(ptr + 11) - '0';
4452
4453 hddLog(VOS_TRACE_LEVEL_INFO, FL("stats = %d "),stats);
4454 if (!IS_FEATURE_FW_STATS_ENABLE)
4455 {
4456 hddLog(VOS_TRACE_LEVEL_INFO,
4457 FL("Get Firmware stats feature not supported"));
4458 ret = -EINVAL;
4459 goto exit;
4460 }
4461
4462 if (FW_STATS_MAX <= stats || 0 >= stats)
4463 {
4464 hddLog(VOS_TRACE_LEVEL_INFO,
4465 FL(" stats %d not supported"),stats);
4466 ret = -EINVAL;
4467 goto exit;
4468 }
4469
4470 init_completion(&(fwStatsCtx.completion));
4471 fwStatsCtx.magic = FW_STATS_CONTEXT_MAGIC;
4472 fwStatsCtx.pAdapter = pAdapter;
4473 fwStatsRsp->type = 0;
4474 status = sme_GetFwStats( (tHalHandle)pHddCtx->hHal, stats,
Abhishek Singh08aa7762014-12-16 13:59:03 +05304475 &fwStatsCtx, hdd_FWStatisCB);
Satyanarayana Dash72806012014-12-02 14:30:08 +05304476 if (eHAL_STATUS_SUCCESS != status)
4477 {
4478 hddLog(VOS_TRACE_LEVEL_ERROR,
4479 FL(" fail to post WDA cmd status = %d"), status);
4480 ret = -EINVAL;
4481 goto exit;
4482 }
4483 waitRet = wait_for_completion_timeout
4484 (&(fwStatsCtx.completion), FW_STATE_WAIT_TIME);
4485 if (waitRet <= 0)
4486 {
4487 hddLog(VOS_TRACE_LEVEL_ERROR,
4488 FL("failed to wait on GwtFwstats"));
4489 //Make magic number to zero so that callback is not executed.
4490 spin_lock(&hdd_context_lock);
4491 fwStatsCtx.magic = 0x0;
4492 spin_unlock(&hdd_context_lock);
4493 ret = -EINVAL;
4494 goto exit;
4495 }
4496 if (fwStatsRsp->type)
4497 {
4498 buf = kmalloc(FW_STATE_RSP_LEN, GFP_KERNEL);
4499 if (!buf)
4500 {
4501 hddLog(VOS_TRACE_LEVEL_ERROR,
4502 FL(" failed to allocate memory"));
4503 ret = -ENOMEM;
4504 goto exit;
4505 }
4506 switch( fwStatsRsp->type )
4507 {
4508 case FW_UBSP_STATS:
4509 {
4510 len = snprintf(buf, FW_STATE_RSP_LEN,
4511 "GETFWSTATS: ubsp_enter_cnt %d ubsp_jump_ddr_cnt %d",
Abhishek Singh08aa7762014-12-16 13:59:03 +05304512 fwStatsRsp->fwStatsData.ubspStats.ubsp_enter_cnt,
4513 fwStatsRsp->fwStatsData.ubspStats.ubsp_jump_ddr_cnt);
Satyanarayana Dash72806012014-12-02 14:30:08 +05304514 }
4515 break;
4516 default:
4517 {
4518 hddLog(VOS_TRACE_LEVEL_ERROR, FL( "No handling for stats type %d"),fwStatsRsp->type);
4519 ret = -EFAULT;
4520 kfree(buf);
4521 goto exit;
4522 }
4523 }
4524 if (copy_to_user(priv_data.buf, buf, len + 1))
4525 {
4526 hddLog(VOS_TRACE_LEVEL_ERROR,
4527 FL(" failed to copy data to user buffer"));
4528 ret = -EFAULT;
4529 kfree(buf);
4530 goto exit;
4531 }
4532 ret = len;
4533 kfree(buf);
4534 }
4535 else
4536 {
4537 hddLog(VOS_TRACE_LEVEL_ERROR,
4538 FL("failed to fetch the stats"));
4539 ret = -EFAULT;
4540 goto exit;
4541 }
4542
4543 }
Agarwal Ashish8bd53ae2015-06-12 18:03:45 +05304544 else if (strncasecmp(command, "SET_FCC_CHANNEL", 15) == 0)
4545 {
4546 /*
4547 * this command wld be called by user-space when it detects WLAN
4548 * ON after airplane mode is set. When APM is set, WLAN turns off.
4549 * But it can be turned back on. Otherwise; when APM is turned back
4550 * off, WLAN wld turn back on. So at that point the command is
4551 * expected to come down. 0 means disable, 1 means enable. The
4552 * constraint is removed when parameter 1 is set or different
4553 * country code is set
4554 */
4555 ret = hdd_cmd_setFccChannel(pHddCtx, command, 15);
4556 }
Mahesh A Saptasagarbeca12c2015-09-07 16:21:06 +05304557 else if (strncasecmp(command, "DISABLE_CA_EVENT", 16) == 0)
4558 {
4559 ret = hdd_enable_disable_ca_event(pHddCtx, command, 16);
4560 }
Madan Mohan Koyyalamudif9bdd4e2012-10-30 18:05:03 -07004561 else {
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05304562 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
4563 TRACE_CODE_HDD_UNSUPPORTED_IOCTL,
4564 pAdapter->sessionId, 0));
Satyanarayana Dash72806012014-12-02 14:30:08 +05304565 hddLog( VOS_TRACE_LEVEL_WARN, FL("Unsupported GUI command %s"),
4566 command);
Madan Mohan Koyyalamudif9bdd4e2012-10-30 18:05:03 -07004567 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004568 }
4569exit:
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304570 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07004571 if (command)
4572 {
4573 kfree(command);
4574 }
4575 return ret;
4576}
4577
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07004578#ifdef CONFIG_COMPAT
4579static int hdd_driver_compat_ioctl(hdd_adapter_t *pAdapter, struct ifreq *ifr)
4580{
4581 struct {
4582 compat_uptr_t buf;
4583 int used_len;
4584 int total_len;
4585 } compat_priv_data;
4586 hdd_priv_data_t priv_data;
4587 int ret = 0;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004588
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07004589 /*
4590 * Note that pAdapter and ifr have already been verified by caller,
4591 * and HDD context has also been validated
4592 */
4593 if (copy_from_user(&compat_priv_data, ifr->ifr_data,
4594 sizeof(compat_priv_data))) {
4595 ret = -EFAULT;
4596 goto exit;
4597 }
4598 priv_data.buf = compat_ptr(compat_priv_data.buf);
4599 priv_data.used_len = compat_priv_data.used_len;
4600 priv_data.total_len = compat_priv_data.total_len;
4601 ret = hdd_driver_command(pAdapter, &priv_data);
4602 exit:
4603 return ret;
4604}
4605#else /* CONFIG_COMPAT */
4606static int hdd_driver_compat_ioctl(hdd_adapter_t *pAdapter, struct ifreq *ifr)
4607{
4608 /* will never be invoked */
4609 return 0;
4610}
4611#endif /* CONFIG_COMPAT */
4612
4613static int hdd_driver_ioctl(hdd_adapter_t *pAdapter, struct ifreq *ifr)
4614{
4615 hdd_priv_data_t priv_data;
4616 int ret = 0;
4617
4618 /*
4619 * Note that pAdapter and ifr have already been verified by caller,
4620 * and HDD context has also been validated
4621 */
4622 if (copy_from_user(&priv_data, ifr->ifr_data, sizeof(priv_data))) {
4623 ret = -EFAULT;
4624 } else {
4625 ret = hdd_driver_command(pAdapter, &priv_data);
4626 }
4627 return ret;
4628}
4629
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05304630int __hdd_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07004631{
4632 hdd_adapter_t *pAdapter;
4633 hdd_context_t *pHddCtx;
4634 int ret;
4635
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304636 ENTER();
4637
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07004638 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4639 if (NULL == pAdapter) {
4640 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
4641 "%s: HDD adapter context is Null", __func__);
4642 ret = -ENODEV;
4643 goto exit;
4644 }
4645 if (dev != pAdapter->dev) {
4646 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
4647 "%s: HDD adapter/dev inconsistency", __func__);
4648 ret = -ENODEV;
4649 goto exit;
4650 }
4651
4652 if ((!ifr) || (!ifr->ifr_data)) {
4653 ret = -EINVAL;
4654 goto exit;
4655 }
4656
4657 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
4658 ret = wlan_hdd_validate_context(pHddCtx);
4659 if (ret) {
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07004660 ret = -EBUSY;
4661 goto exit;
4662 }
4663
4664 switch (cmd) {
4665 case (SIOCDEVPRIVATE + 1):
4666 if (is_compat_task())
4667 ret = hdd_driver_compat_ioctl(pAdapter, ifr);
4668 else
4669 ret = hdd_driver_ioctl(pAdapter, ifr);
4670 break;
4671 default:
4672 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unknown ioctl %d",
4673 __func__, cmd);
4674 ret = -EINVAL;
4675 break;
4676 }
4677 exit:
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304678 EXIT();
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07004679 return ret;
4680}
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004681
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05304682int hdd_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
4683{
4684 int ret;
4685
4686 vos_ssr_protect(__func__);
4687 ret = __hdd_ioctl(dev, ifr, cmd);
4688 vos_ssr_unprotect(__func__);
4689
4690 return ret;
4691}
4692
Katya Nigame7b69a82015-04-28 15:24:06 +05304693int hdd_mon_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
4694{
4695 return 0;
4696}
4697
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004698#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004699/**---------------------------------------------------------------------------
4700
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004701 \brief hdd_parse_ese_beacon_req() - Parse ese beacon request
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004702
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004703 This function parses the ese beacon request passed in the format
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004704 CCXBEACONREQ<space><Number of fields><space><Measurement token>
4705 <space>Channel 1<space>Scan Mode <space>Meas Duration<space>Channel N
4706 <space>Scan Mode N<space>Meas Duration N
4707 if the Number of bcn req fields (N) does not match with the actual number of fields passed
4708 then take N.
4709 <Meas Token><Channel><Scan Mode> and <Meas Duration> are treated as one pair
4710 For example, CCXBEACONREQ 2 1 1 1 30 2 44 0 40.
4711 This function does not take care of removing duplicate channels from the list
4712
4713 \param - pValue Pointer to data
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004714 \param - pEseBcnReq output pointer to store parsed ie information
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004715
4716 \return - 0 for success non-zero for failure
4717
4718 --------------------------------------------------------------------------*/
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004719static VOS_STATUS hdd_parse_ese_beacon_req(tANI_U8 *pValue,
4720 tCsrEseBeaconReq *pEseBcnReq)
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004721{
4722 tANI_U8 *inPtr = pValue;
4723 int tempInt = 0;
4724 int j = 0, i = 0, v = 0;
4725 char buf[32];
4726
4727 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
4728 /*no argument after the command*/
4729 if (NULL == inPtr)
4730 {
4731 return -EINVAL;
4732 }
4733 /*no space after the command*/
4734 else if (SPACE_ASCII_VALUE != *inPtr)
4735 {
4736 return -EINVAL;
4737 }
4738
4739 /*removing empty spaces*/
4740 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
4741
4742 /*no argument followed by spaces*/
4743 if ('\0' == *inPtr) return -EINVAL;
4744
4745 /*getting the first argument ie measurement token*/
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08004746 v = sscanf(inPtr, "%31s ", buf);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004747 if (1 != v) return -EINVAL;
4748
4749 v = kstrtos32(buf, 10, &tempInt);
4750 if ( v < 0) return -EINVAL;
4751
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004752 pEseBcnReq->numBcnReqIe = tempInt;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004753
4754 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004755 "Number of Bcn Req Ie fields(%d)", pEseBcnReq->numBcnReqIe);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004756
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004757 for (j = 0; j < (pEseBcnReq->numBcnReqIe); j++)
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004758 {
4759 for (i = 0; i < 4; i++)
4760 {
4761 /*inPtr pointing to the beginning of first space after number of ie fields*/
4762 inPtr = strpbrk( inPtr, " " );
4763 /*no ie data after the number of ie fields argument*/
4764 if (NULL == inPtr) return -EINVAL;
4765
4766 /*removing empty space*/
4767 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
4768
4769 /*no ie data after the number of ie fields argument and spaces*/
4770 if ( '\0' == *inPtr ) return -EINVAL;
4771
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08004772 v = sscanf(inPtr, "%31s ", buf);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004773 if (1 != v) return -EINVAL;
4774
4775 v = kstrtos32(buf, 10, &tempInt);
4776 if (v < 0) return -EINVAL;
4777
4778 switch (i)
4779 {
4780 case 0: /* Measurement token */
4781 if (tempInt <= 0)
4782 {
4783 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4784 "Invalid Measurement Token(%d)", tempInt);
4785 return -EINVAL;
4786 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004787 pEseBcnReq->bcnReq[j].measurementToken = tempInt;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004788 break;
4789
4790 case 1: /* Channel number */
4791 if ((tempInt <= 0) ||
4792 (tempInt > WNI_CFG_CURRENT_CHANNEL_STAMAX))
4793 {
4794 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4795 "Invalid Channel Number(%d)", tempInt);
4796 return -EINVAL;
4797 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004798 pEseBcnReq->bcnReq[j].channel = tempInt;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004799 break;
4800
4801 case 2: /* Scan mode */
Varun Reddy Yeturu0b18d5a2013-12-04 11:42:23 -08004802 if ((tempInt < eSIR_PASSIVE_SCAN) || (tempInt > eSIR_BEACON_TABLE))
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004803 {
4804 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4805 "Invalid Scan Mode(%d) Expected{0|1|2}", tempInt);
4806 return -EINVAL;
4807 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004808 pEseBcnReq->bcnReq[j].scanMode= tempInt;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004809 break;
4810
4811 case 3: /* Measurement duration */
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004812 if (((tempInt <= 0) && (pEseBcnReq->bcnReq[j].scanMode != eSIR_BEACON_TABLE)) ||
4813 ((tempInt < 0) && (pEseBcnReq->bcnReq[j].scanMode == eSIR_BEACON_TABLE)))
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004814 {
4815 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4816 "Invalid Measurement Duration(%d)", tempInt);
4817 return -EINVAL;
4818 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004819 pEseBcnReq->bcnReq[j].measurementDuration = tempInt;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004820 break;
4821 }
4822 }
4823 }
4824
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004825 for (j = 0; j < pEseBcnReq->numBcnReqIe; j++)
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004826 {
4827 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Arun Kumar Khandavallie8768212014-02-17 16:43:34 +05304828 "Index(%d) Measurement Token(%u)Channel(%u) Scan Mode(%u) Measurement Duration(%u)\n",
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004829 j,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004830 pEseBcnReq->bcnReq[j].measurementToken,
4831 pEseBcnReq->bcnReq[j].channel,
4832 pEseBcnReq->bcnReq[j].scanMode,
4833 pEseBcnReq->bcnReq[j].measurementDuration);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004834 }
4835
4836 return VOS_STATUS_SUCCESS;
4837}
4838
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004839static void hdd_GetTsmStatsCB( tAniTrafStrmMetrics tsmMetrics, const tANI_U32 staId, void *pContext )
4840{
4841 struct statsContext *pStatsContext = NULL;
4842 hdd_adapter_t *pAdapter = NULL;
4843
4844 if (NULL == pContext)
4845 {
4846 hddLog(VOS_TRACE_LEVEL_ERROR,
4847 "%s: Bad param, pContext [%p]",
4848 __func__, pContext);
4849 return;
4850 }
4851
Jeff Johnson72a40512013-12-19 10:14:15 -08004852 /* there is a race condition that exists between this callback
4853 function and the caller since the caller could time out either
4854 before or while this code is executing. we use a spinlock to
4855 serialize these actions */
4856 spin_lock(&hdd_context_lock);
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004857
4858 pStatsContext = pContext;
4859 pAdapter = pStatsContext->pAdapter;
4860 if ((NULL == pAdapter) || (STATS_CONTEXT_MAGIC != pStatsContext->magic))
4861 {
4862 /* the caller presumably timed out so there is nothing we can do */
Jeff Johnson72a40512013-12-19 10:14:15 -08004863 spin_unlock(&hdd_context_lock);
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004864 hddLog(VOS_TRACE_LEVEL_WARN,
4865 "%s: Invalid context, pAdapter [%p] magic [%08x]",
4866 __func__, pAdapter, pStatsContext->magic);
4867 return;
4868 }
4869
Jeff Johnson72a40512013-12-19 10:14:15 -08004870 /* context is valid so caller is still waiting */
4871
4872 /* paranoia: invalidate the magic */
4873 pStatsContext->magic = 0;
4874
4875 /* copy over the tsm stats */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004876 pAdapter->tsmStats.UplinkPktQueueDly = tsmMetrics.UplinkPktQueueDly;
4877 vos_mem_copy(pAdapter->tsmStats.UplinkPktQueueDlyHist,
4878 tsmMetrics.UplinkPktQueueDlyHist,
4879 sizeof(pAdapter->tsmStats.UplinkPktQueueDlyHist)/
4880 sizeof(pAdapter->tsmStats.UplinkPktQueueDlyHist[0]));
4881 pAdapter->tsmStats.UplinkPktTxDly = tsmMetrics.UplinkPktTxDly;
4882 pAdapter->tsmStats.UplinkPktLoss = tsmMetrics.UplinkPktLoss;
4883 pAdapter->tsmStats.UplinkPktCount = tsmMetrics.UplinkPktCount;
4884 pAdapter->tsmStats.RoamingCount = tsmMetrics.RoamingCount;
4885 pAdapter->tsmStats.RoamingDly = tsmMetrics.RoamingDly;
4886
Jeff Johnson72a40512013-12-19 10:14:15 -08004887 /* notify the caller */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004888 complete(&pStatsContext->completion);
Jeff Johnson72a40512013-12-19 10:14:15 -08004889
4890 /* serialization is complete */
4891 spin_unlock(&hdd_context_lock);
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004892}
4893
4894
4895
4896static VOS_STATUS hdd_get_tsm_stats(hdd_adapter_t *pAdapter, const tANI_U8 tid,
4897 tAniTrafStrmMetrics* pTsmMetrics)
4898{
4899 hdd_station_ctx_t *pHddStaCtx = NULL;
4900 eHalStatus hstatus;
Jeff Johnson72a40512013-12-19 10:14:15 -08004901 VOS_STATUS vstatus = VOS_STATUS_SUCCESS;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004902 long lrc;
4903 struct statsContext context;
4904 hdd_context_t *pHddCtx = NULL;
4905
4906 if (NULL == pAdapter)
4907 {
4908 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: pAdapter is NULL", __func__);
4909 return VOS_STATUS_E_FAULT;
4910 }
4911
4912 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
4913 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4914
4915 /* we are connected prepare our callback context */
4916 init_completion(&context.completion);
4917 context.pAdapter = pAdapter;
4918 context.magic = STATS_CONTEXT_MAGIC;
4919
4920 /* query tsm stats */
4921 hstatus = sme_GetTsmStats(pHddCtx->hHal, hdd_GetTsmStatsCB,
4922 pHddStaCtx->conn_info.staId[ 0 ],
4923 pHddStaCtx->conn_info.bssId,
4924 &context, pHddCtx->pvosContext, tid);
4925
4926 if (eHAL_STATUS_SUCCESS != hstatus)
4927 {
Jeff Johnson72a40512013-12-19 10:14:15 -08004928 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unable to retrieve statistics",
4929 __func__);
4930 vstatus = VOS_STATUS_E_FAULT;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004931 }
4932 else
4933 {
4934 /* request was sent -- wait for the response */
4935 lrc = wait_for_completion_interruptible_timeout(&context.completion,
4936 msecs_to_jiffies(WLAN_WAIT_TIME_STATS));
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004937 if (lrc <= 0)
4938 {
4939 hddLog(VOS_TRACE_LEVEL_ERROR,
4940 "%s: SME %s while retrieving statistics",
4941 __func__, (0 == lrc) ? "timeout" : "interrupt");
Jeff Johnson72a40512013-12-19 10:14:15 -08004942 vstatus = VOS_STATUS_E_TIMEOUT;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004943 }
4944 }
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004945
Jeff Johnson72a40512013-12-19 10:14:15 -08004946 /* either we never sent a request, we sent a request and received a
4947 response or we sent a request and timed out. if we never sent a
4948 request or if we sent a request and got a response, we want to
4949 clear the magic out of paranoia. if we timed out there is a
4950 race condition such that the callback function could be
4951 executing at the same time we are. of primary concern is if the
4952 callback function had already verified the "magic" but had not
4953 yet set the completion variable when a timeout occurred. we
4954 serialize these activities by invalidating the magic while
4955 holding a shared spinlock which will cause us to block if the
4956 callback is currently executing */
4957 spin_lock(&hdd_context_lock);
4958 context.magic = 0;
4959 spin_unlock(&hdd_context_lock);
4960
4961 if (VOS_STATUS_SUCCESS == vstatus)
4962 {
4963 pTsmMetrics->UplinkPktQueueDly = pAdapter->tsmStats.UplinkPktQueueDly;
4964 vos_mem_copy(pTsmMetrics->UplinkPktQueueDlyHist,
4965 pAdapter->tsmStats.UplinkPktQueueDlyHist,
4966 sizeof(pAdapter->tsmStats.UplinkPktQueueDlyHist)/
4967 sizeof(pAdapter->tsmStats.UplinkPktQueueDlyHist[0]));
4968 pTsmMetrics->UplinkPktTxDly = pAdapter->tsmStats.UplinkPktTxDly;
4969 pTsmMetrics->UplinkPktLoss = pAdapter->tsmStats.UplinkPktLoss;
4970 pTsmMetrics->UplinkPktCount = pAdapter->tsmStats.UplinkPktCount;
4971 pTsmMetrics->RoamingCount = pAdapter->tsmStats.RoamingCount;
4972 pTsmMetrics->RoamingDly = pAdapter->tsmStats.RoamingDly;
4973 }
4974 return vstatus;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004975}
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004976#endif /*FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004977
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004978#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowdade697412013-02-14 16:31:48 -08004979void hdd_getBand_helper(hdd_context_t *pHddCtx, int *pBand)
4980{
4981 eCsrBand band = -1;
4982 sme_GetFreqBand((tHalHandle)(pHddCtx->hHal), &band);
4983 switch (band)
4984 {
4985 case eCSR_BAND_ALL:
4986 *pBand = WLAN_HDD_UI_BAND_AUTO;
4987 break;
4988
4989 case eCSR_BAND_24:
4990 *pBand = WLAN_HDD_UI_BAND_2_4_GHZ;
4991 break;
4992
4993 case eCSR_BAND_5G:
4994 *pBand = WLAN_HDD_UI_BAND_5_GHZ;
4995 break;
4996
4997 default:
4998 hddLog( VOS_TRACE_LEVEL_WARN, "%s: Invalid Band %d", __func__, band);
4999 *pBand = -1;
5000 break;
5001 }
5002}
5003
5004/**---------------------------------------------------------------------------
5005
Srinivas Girigowda100eb322013-03-15 16:48:20 -07005006 \brief hdd_parse_send_action_frame_data() - HDD Parse send action frame data
5007
5008 This function parses the send action frame data passed in the format
5009 SENDACTIONFRAME<space><bssid><space><channel><space><dwelltime><space><data>
5010
Srinivas Girigowda56076852013-08-20 14:00:50 -07005011 \param - pValue Pointer to input data
Srinivas Girigowda100eb322013-03-15 16:48:20 -07005012 \param - pTargetApBssid Pointer to target Ap bssid
5013 \param - pChannel Pointer to the Target AP channel
5014 \param - pDwellTime Pointer to the time to stay off-channel after transmitting action frame
5015 \param - pBuf Pointer to data
5016 \param - pBufLen Pointer to data length
5017
5018 \return - 0 for success non-zero for failure
5019
5020 --------------------------------------------------------------------------*/
5021VOS_STATUS hdd_parse_send_action_frame_data(tANI_U8 *pValue, tANI_U8 *pTargetApBssid, tANI_U8 *pChannel,
5022 tANI_U8 *pDwellTime, tANI_U8 **pBuf, tANI_U8 *pBufLen)
5023{
5024 tANI_U8 *inPtr = pValue;
5025 tANI_U8 *dataEnd;
5026 int tempInt;
5027 int j = 0;
5028 int i = 0;
5029 int v = 0;
5030 tANI_U8 tempBuf[32];
5031 tANI_U8 tempByte = 0;
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08005032 /* 12 hexa decimal digits, 5 ':' and '\0' */
5033 tANI_U8 macAddress[18];
Srinivas Girigowda100eb322013-03-15 16:48:20 -07005034
5035 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
5036 /*no argument after the command*/
5037 if (NULL == inPtr)
5038 {
5039 return -EINVAL;
5040 }
5041
5042 /*no space after the command*/
5043 else if (SPACE_ASCII_VALUE != *inPtr)
5044 {
5045 return -EINVAL;
5046 }
5047
5048 /*removing empty spaces*/
5049 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
5050
5051 /*no argument followed by spaces*/
5052 if ('\0' == *inPtr)
5053 {
5054 return -EINVAL;
5055 }
5056
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005057 v = sscanf(inPtr, "%17s", macAddress);
5058 if (!((1 == v) && hdd_is_valid_mac_address(macAddress)))
Srinivas Girigowda100eb322013-03-15 16:48:20 -07005059 {
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005060 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5061 "Invalid MAC address or All hex inputs are not read (%d)", v);
5062 return -EINVAL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07005063 }
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005064
5065 pTargetApBssid[0] = hdd_parse_hex(macAddress[0]) << 4 | hdd_parse_hex(macAddress[1]);
5066 pTargetApBssid[1] = hdd_parse_hex(macAddress[3]) << 4 | hdd_parse_hex(macAddress[4]);
5067 pTargetApBssid[2] = hdd_parse_hex(macAddress[6]) << 4 | hdd_parse_hex(macAddress[7]);
5068 pTargetApBssid[3] = hdd_parse_hex(macAddress[9]) << 4 | hdd_parse_hex(macAddress[10]);
5069 pTargetApBssid[4] = hdd_parse_hex(macAddress[12]) << 4 | hdd_parse_hex(macAddress[13]);
5070 pTargetApBssid[5] = hdd_parse_hex(macAddress[15]) << 4 | hdd_parse_hex(macAddress[16]);
Srinivas Girigowda100eb322013-03-15 16:48:20 -07005071
5072 /* point to the next argument */
5073 inPtr = strnchr(inPtr, strlen(inPtr), SPACE_ASCII_VALUE);
5074 /*no argument after the command*/
5075 if (NULL == inPtr) return -EINVAL;
5076
5077 /*removing empty spaces*/
5078 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
5079
5080 /*no argument followed by spaces*/
5081 if ('\0' == *inPtr)
5082 {
5083 return -EINVAL;
5084 }
5085
5086 /*getting the next argument ie the channel number */
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08005087 v = sscanf(inPtr, "%31s ", tempBuf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005088 if (1 != v) return -EINVAL;
5089
Srinivas Girigowda100eb322013-03-15 16:48:20 -07005090 v = kstrtos32(tempBuf, 10, &tempInt);
Agarwal Ashish353b3a82014-04-08 14:55:11 +05305091 if ( v < 0 || tempInt <= 0 || tempInt > WNI_CFG_CURRENT_CHANNEL_STAMAX )
Kiet Lambe150c22013-11-21 16:30:32 +05305092 return -EINVAL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07005093
5094 *pChannel = tempInt;
5095
5096 /* point to the next argument */
5097 inPtr = strnchr(inPtr, strlen(inPtr), SPACE_ASCII_VALUE);
5098 /*no argument after the command*/
5099 if (NULL == inPtr) return -EINVAL;
5100 /*removing empty spaces*/
5101 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
5102
5103 /*no argument followed by spaces*/
5104 if ('\0' == *inPtr)
5105 {
5106 return -EINVAL;
5107 }
5108
5109 /*getting the next argument ie the dwell time */
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08005110 v = sscanf(inPtr, "%31s ", tempBuf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005111 if (1 != v) return -EINVAL;
5112
Srinivas Girigowda100eb322013-03-15 16:48:20 -07005113 v = kstrtos32(tempBuf, 10, &tempInt);
Srinivas Girigowda5a6e0672014-01-09 14:42:57 -08005114 if ( v < 0 || tempInt < 0) return -EINVAL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07005115
5116 *pDwellTime = tempInt;
5117
5118 /* point to the next argument */
5119 inPtr = strnchr(inPtr, strlen(inPtr), SPACE_ASCII_VALUE);
5120 /*no argument after the command*/
5121 if (NULL == inPtr) return -EINVAL;
5122 /*removing empty spaces*/
5123 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
5124
5125 /*no argument followed by spaces*/
5126 if ('\0' == *inPtr)
5127 {
5128 return -EINVAL;
5129 }
5130
5131 /* find the length of data */
5132 dataEnd = inPtr;
5133 while(('\0' != *dataEnd) )
5134 {
5135 dataEnd++;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07005136 }
Kiet Lambe150c22013-11-21 16:30:32 +05305137 *pBufLen = dataEnd - inPtr ;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07005138 if ( *pBufLen <= 0) return -EINVAL;
5139
Srinivas Girigowdab5ae85d2013-06-03 10:51:45 -07005140 /* Allocate the number of bytes based on the number of input characters
5141 whether it is even or odd.
5142 if the number of input characters are even, then we need N/2 byte.
5143 if the number of input characters are odd, then we need do (N+1)/2 to
5144 compensate rounding off.
5145 For example, if N = 18, then (18 + 1)/2 = 9 bytes are enough.
5146 If N = 19, then we need 10 bytes, hence (19 + 1)/2 = 10 bytes */
5147 *pBuf = vos_mem_malloc((*pBufLen + 1)/2);
Srinivas Girigowda100eb322013-03-15 16:48:20 -07005148 if (NULL == *pBuf)
5149 {
5150 hddLog(VOS_TRACE_LEVEL_FATAL,
5151 "%s: vos_mem_alloc failed ", __func__);
5152 return -EINVAL;
5153 }
5154
5155 /* the buffer received from the upper layer is character buffer,
5156 we need to prepare the buffer taking 2 characters in to a U8 hex decimal number
5157 for example 7f0000f0...form a buffer to contain 7f in 0th location, 00 in 1st
5158 and f0 in 3rd location */
5159 for (i = 0, j = 0; j < *pBufLen; j += 2)
5160 {
Kiet Lambe150c22013-11-21 16:30:32 +05305161 if( j+1 == *pBufLen)
5162 {
5163 tempByte = hdd_parse_hex(inPtr[j]);
5164 }
5165 else
5166 {
5167 tempByte = (hdd_parse_hex(inPtr[j]) << 4) | (hdd_parse_hex(inPtr[j + 1]));
5168 }
Srinivas Girigowda100eb322013-03-15 16:48:20 -07005169 (*pBuf)[i++] = tempByte;
5170 }
5171 *pBufLen = i;
5172 return VOS_STATUS_SUCCESS;
5173}
5174
Srinivas Girigowda100eb322013-03-15 16:48:20 -07005175/**---------------------------------------------------------------------------
5176
Srinivas Girigowdade697412013-02-14 16:31:48 -08005177 \brief hdd_parse_channellist() - HDD Parse channel list
5178
5179 This function parses the channel list passed in the format
5180 SETROAMSCANCHANNELS<space><Number of channels><space>Channel 1<space>Channel 2<space>Channel N
Srinivas Girigowdacf9a9b42013-03-21 11:55:24 -07005181 if the Number of channels (N) does not match with the actual number of channels passed
5182 then take the minimum of N and count of (Ch1, Ch2, ...Ch M)
5183 For example, if SETROAMSCANCHANNELS 3 36 40 44 48, only 36, 40 and 44 shall be taken.
5184 If SETROAMSCANCHANNELS 5 36 40 44 48, ignore 5 and take 36, 40, 44 and 48.
5185 This function does not take care of removing duplicate channels from the list
Srinivas Girigowdade697412013-02-14 16:31:48 -08005186
5187 \param - pValue Pointer to input channel list
5188 \param - ChannelList Pointer to local output array to record channel list
5189 \param - pNumChannels Pointer to number of roam scan channels
5190
5191 \return - 0 for success non-zero for failure
5192
5193 --------------------------------------------------------------------------*/
5194VOS_STATUS hdd_parse_channellist(tANI_U8 *pValue, tANI_U8 *pChannelList, tANI_U8 *pNumChannels)
5195{
5196 tANI_U8 *inPtr = pValue;
5197 int tempInt;
5198 int j = 0;
5199 int v = 0;
5200 char buf[32];
5201
5202 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
5203 /*no argument after the command*/
5204 if (NULL == inPtr)
5205 {
5206 return -EINVAL;
5207 }
5208
5209 /*no space after the command*/
5210 else if (SPACE_ASCII_VALUE != *inPtr)
5211 {
5212 return -EINVAL;
5213 }
5214
5215 /*removing empty spaces*/
Jeff Johnsona1f9afb2013-04-03 09:13:31 -07005216 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
Srinivas Girigowdade697412013-02-14 16:31:48 -08005217
5218 /*no argument followed by spaces*/
5219 if ('\0' == *inPtr)
5220 {
5221 return -EINVAL;
5222 }
5223
5224 /*getting the first argument ie the number of channels*/
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08005225 v = sscanf(inPtr, "%31s ", buf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005226 if (1 != v) return -EINVAL;
5227
Srinivas Girigowdade697412013-02-14 16:31:48 -08005228 v = kstrtos32(buf, 10, &tempInt);
Jeff Johnsona1f9afb2013-04-03 09:13:31 -07005229 if ((v < 0) ||
5230 (tempInt <= 0) ||
5231 (tempInt > WNI_CFG_VALID_CHANNEL_LIST_LEN))
5232 {
5233 return -EINVAL;
5234 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08005235
5236 *pNumChannels = tempInt;
5237
5238 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
5239 "Number of channels are: %d", *pNumChannels);
5240
5241 for (j = 0; j < (*pNumChannels); j++)
5242 {
5243 /*inPtr pointing to the beginning of first space after number of channels*/
5244 inPtr = strpbrk( inPtr, " " );
5245 /*no channel list after the number of channels argument*/
5246 if (NULL == inPtr)
5247 {
Srinivas Girigowdacf9a9b42013-03-21 11:55:24 -07005248 if (0 != j)
5249 {
5250 *pNumChannels = j;
5251 return VOS_STATUS_SUCCESS;
5252 }
5253 else
5254 {
5255 return -EINVAL;
5256 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08005257 }
5258
5259 /*removing empty space*/
Jeff Johnsona1f9afb2013-04-03 09:13:31 -07005260 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
Srinivas Girigowdade697412013-02-14 16:31:48 -08005261
5262 /*no channel list after the number of channels argument and spaces*/
5263 if ( '\0' == *inPtr )
5264 {
Srinivas Girigowdacf9a9b42013-03-21 11:55:24 -07005265 if (0 != j)
5266 {
5267 *pNumChannels = j;
5268 return VOS_STATUS_SUCCESS;
5269 }
5270 else
5271 {
5272 return -EINVAL;
5273 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08005274 }
5275
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08005276 v = sscanf(inPtr, "%31s ", buf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005277 if (1 != v) return -EINVAL;
5278
Srinivas Girigowdade697412013-02-14 16:31:48 -08005279 v = kstrtos32(buf, 10, &tempInt);
Jeff Johnsona1f9afb2013-04-03 09:13:31 -07005280 if ((v < 0) ||
5281 (tempInt <= 0) ||
5282 (tempInt > WNI_CFG_CURRENT_CHANNEL_STAMAX))
5283 {
5284 return -EINVAL;
5285 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08005286 pChannelList[j] = tempInt;
5287
5288 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
5289 "Channel %d added to preferred channel list",
5290 pChannelList[j] );
5291 }
5292
Srinivas Girigowdade697412013-02-14 16:31:48 -08005293 return VOS_STATUS_SUCCESS;
5294}
5295
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005296
5297/**---------------------------------------------------------------------------
5298
5299 \brief hdd_parse_reassoc_command_data() - HDD Parse reassoc command data
5300
5301 This function parses the reasoc command data passed in the format
5302 REASSOC<space><bssid><space><channel>
5303
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005304 \param - pValue Pointer to input data (its a NUL terminated string)
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005305 \param - pTargetApBssid Pointer to target Ap bssid
5306 \param - pChannel Pointer to the Target AP channel
5307
5308 \return - 0 for success non-zero for failure
5309
5310 --------------------------------------------------------------------------*/
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005311VOS_STATUS hdd_parse_reassoc_command_data(tANI_U8 *pValue,
5312 tANI_U8 *pTargetApBssid, tANI_U8 *pChannel)
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005313{
5314 tANI_U8 *inPtr = pValue;
5315 int tempInt;
5316 int v = 0;
5317 tANI_U8 tempBuf[32];
Kiet Lamaa8e15a2014-02-11 23:30:06 -08005318 /* 12 hexa decimal digits, 5 ':' and '\0' */
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08005319 tANI_U8 macAddress[18];
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005320
5321 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
5322 /*no argument after the command*/
5323 if (NULL == inPtr)
5324 {
5325 return -EINVAL;
5326 }
5327
5328 /*no space after the command*/
5329 else if (SPACE_ASCII_VALUE != *inPtr)
5330 {
5331 return -EINVAL;
5332 }
5333
5334 /*removing empty spaces*/
5335 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
5336
5337 /*no argument followed by spaces*/
5338 if ('\0' == *inPtr)
5339 {
5340 return -EINVAL;
5341 }
5342
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005343 v = sscanf(inPtr, "%17s", macAddress);
5344 if (!((1 == v) && hdd_is_valid_mac_address(macAddress)))
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005345 {
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005346 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5347 "Invalid MAC address or All hex inputs are not read (%d)", v);
5348 return -EINVAL;
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005349 }
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005350
5351 pTargetApBssid[0] = hdd_parse_hex(macAddress[0]) << 4 | hdd_parse_hex(macAddress[1]);
5352 pTargetApBssid[1] = hdd_parse_hex(macAddress[3]) << 4 | hdd_parse_hex(macAddress[4]);
5353 pTargetApBssid[2] = hdd_parse_hex(macAddress[6]) << 4 | hdd_parse_hex(macAddress[7]);
5354 pTargetApBssid[3] = hdd_parse_hex(macAddress[9]) << 4 | hdd_parse_hex(macAddress[10]);
5355 pTargetApBssid[4] = hdd_parse_hex(macAddress[12]) << 4 | hdd_parse_hex(macAddress[13]);
5356 pTargetApBssid[5] = hdd_parse_hex(macAddress[15]) << 4 | hdd_parse_hex(macAddress[16]);
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005357
5358 /* point to the next argument */
5359 inPtr = strnchr(inPtr, strlen(inPtr), SPACE_ASCII_VALUE);
5360 /*no argument after the command*/
5361 if (NULL == inPtr) return -EINVAL;
5362
5363 /*removing empty spaces*/
5364 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
5365
5366 /*no argument followed by spaces*/
5367 if ('\0' == *inPtr)
5368 {
5369 return -EINVAL;
5370 }
5371
5372 /*getting the next argument ie the channel number */
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08005373 v = sscanf(inPtr, "%31s ", tempBuf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005374 if (1 != v) return -EINVAL;
5375
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005376 v = kstrtos32(tempBuf, 10, &tempInt);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005377 if ((v < 0) ||
Padma, Santhosh Kumar0fa809b2014-11-13 14:56:56 +05305378 (tempInt < 0) ||
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005379 (tempInt > WNI_CFG_CURRENT_CHANNEL_STAMAX))
5380 {
5381 return -EINVAL;
5382 }
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005383
5384 *pChannel = tempInt;
5385 return VOS_STATUS_SUCCESS;
5386}
5387
5388#endif
5389
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005390#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07005391/**---------------------------------------------------------------------------
5392
5393 \brief hdd_parse_get_cckm_ie() - HDD Parse and fetch the CCKM IE
5394
5395 This function parses the SETCCKM IE command
5396 SETCCKMIE<space><ie data>
5397
5398 \param - pValue Pointer to input data
5399 \param - pCckmIe Pointer to output cckm Ie
5400 \param - pCckmIeLen Pointer to output cckm ie length
5401
5402 \return - 0 for success non-zero for failure
5403
5404 --------------------------------------------------------------------------*/
5405VOS_STATUS hdd_parse_get_cckm_ie(tANI_U8 *pValue, tANI_U8 **pCckmIe,
5406 tANI_U8 *pCckmIeLen)
5407{
5408 tANI_U8 *inPtr = pValue;
5409 tANI_U8 *dataEnd;
5410 int j = 0;
5411 int i = 0;
5412 tANI_U8 tempByte = 0;
5413
5414 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
5415 /*no argument after the command*/
5416 if (NULL == inPtr)
5417 {
5418 return -EINVAL;
5419 }
5420
5421 /*no space after the command*/
5422 else if (SPACE_ASCII_VALUE != *inPtr)
5423 {
5424 return -EINVAL;
5425 }
5426
5427 /*removing empty spaces*/
5428 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
5429
5430 /*no argument followed by spaces*/
5431 if ('\0' == *inPtr)
5432 {
5433 return -EINVAL;
5434 }
5435
5436 /* find the length of data */
5437 dataEnd = inPtr;
5438 while(('\0' != *dataEnd) )
5439 {
5440 dataEnd++;
5441 ++(*pCckmIeLen);
5442 }
5443 if ( *pCckmIeLen <= 0) return -EINVAL;
5444
5445 /* Allocate the number of bytes based on the number of input characters
5446 whether it is even or odd.
5447 if the number of input characters are even, then we need N/2 byte.
5448 if the number of input characters are odd, then we need do (N+1)/2 to
5449 compensate rounding off.
5450 For example, if N = 18, then (18 + 1)/2 = 9 bytes are enough.
5451 If N = 19, then we need 10 bytes, hence (19 + 1)/2 = 10 bytes */
5452 *pCckmIe = vos_mem_malloc((*pCckmIeLen + 1)/2);
5453 if (NULL == *pCckmIe)
5454 {
5455 hddLog(VOS_TRACE_LEVEL_FATAL,
5456 "%s: vos_mem_alloc failed ", __func__);
5457 return -EINVAL;
5458 }
5459 vos_mem_zero(*pCckmIe, (*pCckmIeLen + 1)/2);
5460 /* the buffer received from the upper layer is character buffer,
5461 we need to prepare the buffer taking 2 characters in to a U8 hex decimal number
5462 for example 7f0000f0...form a buffer to contain 7f in 0th location, 00 in 1st
5463 and f0 in 3rd location */
5464 for (i = 0, j = 0; j < *pCckmIeLen; j += 2)
5465 {
5466 tempByte = (hdd_parse_hex(inPtr[j]) << 4) | (hdd_parse_hex(inPtr[j + 1]));
5467 (*pCckmIe)[i++] = tempByte;
5468 }
5469 *pCckmIeLen = i;
5470
5471 return VOS_STATUS_SUCCESS;
5472}
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005473#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07005474
Jeff Johnson295189b2012-06-20 16:38:30 -07005475/**---------------------------------------------------------------------------
5476
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005477 \brief hdd_is_valid_mac_address() - Validate MAC address
5478
5479 This function validates whether the given MAC address is valid or not
5480 Expected MAC address is of the format XX:XX:XX:XX:XX:XX
5481 where X is the hexa decimal digit character and separated by ':'
5482 This algorithm works even if MAC address is not separated by ':'
5483
5484 This code checks given input string mac contains exactly 12 hexadecimal digits.
5485 and a separator colon : appears in the input string only after
5486 an even number of hex digits.
5487
5488 \param - pMacAddr pointer to the input MAC address
5489 \return - 1 for valid and 0 for invalid
5490
5491 --------------------------------------------------------------------------*/
5492
5493v_BOOL_t hdd_is_valid_mac_address(const tANI_U8 *pMacAddr)
5494{
5495 int xdigit = 0;
5496 int separator = 0;
5497 while (*pMacAddr)
5498 {
5499 if (isxdigit(*pMacAddr))
5500 {
5501 xdigit++;
5502 }
5503 else if (':' == *pMacAddr)
5504 {
5505 if (0 == xdigit || ((xdigit / 2) - 1) != separator)
5506 break;
5507
5508 ++separator;
5509 }
5510 else
5511 {
5512 separator = -1;
5513 /* Invalid MAC found */
5514 return 0;
5515 }
5516 ++pMacAddr;
5517 }
5518 return (xdigit == 12 && (separator == 5 || separator == 0));
5519}
5520
5521/**---------------------------------------------------------------------------
5522
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305523 \brief __hdd_open() - HDD Open function
Jeff Johnson295189b2012-06-20 16:38:30 -07005524
5525 \param - dev Pointer to net_device structure
5526
5527 \return - 0 for success non-zero for failure
5528
5529 --------------------------------------------------------------------------*/
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305530int __hdd_open(struct net_device *dev)
Jeff Johnson295189b2012-06-20 16:38:30 -07005531{
5532 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5533 hdd_context_t *pHddCtx;
5534 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
5535 VOS_STATUS status;
5536 v_BOOL_t in_standby = TRUE;
5537
5538 if (NULL == pAdapter)
5539 {
5540 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Agarwal Ashish971c2882013-10-30 20:11:12 +05305541 "%s: pAdapter is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005542 return -ENODEV;
5543 }
5544
5545 pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05305546 MTRACE(vos_trace(VOS_MODULE_ID_HDD, TRACE_CODE_HDD_OPEN_REQUEST,
5547 pAdapter->sessionId, pAdapter->device_mode));
Jeff Johnson295189b2012-06-20 16:38:30 -07005548 if (NULL == pHddCtx)
5549 {
5550 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005551 "%s: HDD context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005552 return -ENODEV;
5553 }
5554
5555 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
5556 while ( (NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status) )
5557 {
Jeff Johnson6a81ca42013-04-05 10:37:08 -07005558 if (test_bit(DEVICE_IFACE_OPENED, &pAdapterNode->pAdapter->event_flags))
5559 {
5560 hddLog(VOS_TRACE_LEVEL_INFO, "%s: chip already out of standby",
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05305561 __func__);
Jeff Johnson6a81ca42013-04-05 10:37:08 -07005562 in_standby = FALSE;
5563 break;
5564 }
5565 else
5566 {
5567 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
5568 pAdapterNode = pNext;
5569 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005570 }
5571
5572 if (TRUE == in_standby)
5573 {
5574 if (VOS_STATUS_SUCCESS != wlan_hdd_exit_lowpower(pHddCtx, pAdapter))
5575 {
5576 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Failed to bring "
5577 "wlan out of power save", __func__);
5578 return -EINVAL;
5579 }
5580 }
5581
Jeff Johnson6a81ca42013-04-05 10:37:08 -07005582 set_bit(DEVICE_IFACE_OPENED, &pAdapter->event_flags);
Jeff Johnson295189b2012-06-20 16:38:30 -07005583 if (hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter)))
5584 {
5585 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005586 "%s: Enabling Tx Queues", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005587 /* Enable TX queues only when we are connected */
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +05305588 hddLog(VOS_TRACE_LEVEL_INFO, FL("Enabling queues"));
Jeff Johnson295189b2012-06-20 16:38:30 -07005589 netif_tx_start_all_queues(dev);
5590 }
5591
5592 return 0;
5593}
5594
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305595/**---------------------------------------------------------------------------
5596
5597 \brief hdd_open() - Wrapper function for __hdd_open to protect it from SSR
5598
5599 This is called in response to ifconfig up
5600
5601 \param - dev Pointer to net_device structure
5602
5603 \return - 0 for success non-zero for failure
5604
5605 --------------------------------------------------------------------------*/
5606int hdd_open(struct net_device *dev)
5607{
5608 int ret;
5609
5610 vos_ssr_protect(__func__);
5611 ret = __hdd_open(dev);
5612 vos_ssr_unprotect(__func__);
5613
5614 return ret;
5615}
5616
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05305617int __hdd_mon_open (struct net_device *dev)
Jeff Johnson295189b2012-06-20 16:38:30 -07005618{
5619 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5620
5621 if(pAdapter == NULL) {
5622 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005623 "%s: HDD adapter context is Null", __func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08005624 return -EINVAL;
Jeff Johnson295189b2012-06-20 16:38:30 -07005625 }
5626
Jeff Johnson295189b2012-06-20 16:38:30 -07005627 return 0;
5628}
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05305629
5630int hdd_mon_open (struct net_device *dev)
5631{
5632 int ret;
5633
5634 vos_ssr_protect(__func__);
5635 ret = __hdd_mon_open(dev);
5636 vos_ssr_unprotect(__func__);
5637
5638 return ret;
5639}
5640
Katya Nigame7b69a82015-04-28 15:24:06 +05305641int hdd_mon_stop(struct net_device *dev)
5642{
5643 return 0;
5644}
5645
Jeff Johnson295189b2012-06-20 16:38:30 -07005646/**---------------------------------------------------------------------------
5647
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305648 \brief __hdd_stop() - HDD stop function
Jeff Johnson295189b2012-06-20 16:38:30 -07005649
5650 \param - dev Pointer to net_device structure
5651
5652 \return - 0 for success non-zero for failure
5653
5654 --------------------------------------------------------------------------*/
5655
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305656int __hdd_stop (struct net_device *dev)
Jeff Johnson295189b2012-06-20 16:38:30 -07005657{
Vinay Krishna Eranna90f43532014-10-27 16:45:54 +05305658 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07005659 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5660 hdd_context_t *pHddCtx;
5661 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
5662 VOS_STATUS status;
5663 v_BOOL_t enter_standby = TRUE;
5664
5665 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07005666 if (NULL == pAdapter)
5667 {
5668 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Agarwal Ashish971c2882013-10-30 20:11:12 +05305669 "%s: pAdapter is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005670 return -ENODEV;
5671 }
Sachin Ahuja9b4958f2015-01-15 21:37:00 +05305672 MTRACE(vos_trace(VOS_MODULE_ID_HDD, TRACE_CODE_HDD_STOP_REQUEST,
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05305673 pAdapter->sessionId, pAdapter->device_mode));
Vinay Krishna Eranna90f43532014-10-27 16:45:54 +05305674
5675 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
5676 ret = wlan_hdd_validate_context(pHddCtx);
5677 if (ret)
Jeff Johnson295189b2012-06-20 16:38:30 -07005678 {
Vinay Krishna Eranna90f43532014-10-27 16:45:54 +05305679 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07005680 }
5681
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05305682 /* Nothing to be done if the interface is not opened */
5683 if (VOS_FALSE == test_bit(DEVICE_IFACE_OPENED, &pAdapter->event_flags))
5684 {
5685 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5686 "%s: NETDEV Interface is not OPENED", __func__);
5687 return -ENODEV;
5688 }
5689
5690 /* Make sure the interface is marked as closed */
Jeff Johnson6a81ca42013-04-05 10:37:08 -07005691 clear_bit(DEVICE_IFACE_OPENED, &pAdapter->event_flags);
Jeff Johnson295189b2012-06-20 16:38:30 -07005692 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Disabling OS Tx queues", __func__);
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05305693
5694 /* Disable TX on the interface, after this hard_start_xmit() will not
5695 * be called on that interface
5696 */
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +05305697 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Jeff Johnson295189b2012-06-20 16:38:30 -07005698 netif_tx_disable(pAdapter->dev);
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05305699
5700 /* Mark the interface status as "down" for outside world */
Jeff Johnson295189b2012-06-20 16:38:30 -07005701 netif_carrier_off(pAdapter->dev);
5702
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05305703 /* The interface is marked as down for outside world (aka kernel)
5704 * But the driver is pretty much alive inside. The driver needs to
5705 * tear down the existing connection on the netdev (session)
5706 * cleanup the data pipes and wait until the control plane is stabilized
5707 * for this interface. The call also needs to wait until the above
5708 * mentioned actions are completed before returning to the caller.
5709 * Notice that the hdd_stop_adapter is requested not to close the session
5710 * That is intentional to be able to scan if it is a STA/P2P interface
5711 */
5712 hdd_stop_adapter(pHddCtx, pAdapter, VOS_FALSE);
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05305713#ifdef FEATURE_WLAN_TDLS
5714 mutex_lock(&pHddCtx->tdls_lock);
5715#endif
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05305716 /* DeInit the adapter. This ensures datapath cleanup as well */
c_hpothu002231a2015-02-05 14:58:51 +05305717 hdd_deinit_adapter(pHddCtx, pAdapter, TRUE);
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05305718#ifdef FEATURE_WLAN_TDLS
5719 mutex_unlock(&pHddCtx->tdls_lock);
5720#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07005721 /* SoftAP ifaces should never go in power save mode
5722 making sure same here. */
5723 if ( (WLAN_HDD_SOFTAP == pAdapter->device_mode )
5724 || (WLAN_HDD_MONITOR == pAdapter->device_mode )
Jeff Johnson295189b2012-06-20 16:38:30 -07005725 || (WLAN_HDD_P2P_GO == pAdapter->device_mode )
Jeff Johnson295189b2012-06-20 16:38:30 -07005726 )
5727 {
5728 /* SoftAP mode, so return from here */
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305729 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
5730 "%s: In SAP MODE", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005731 EXIT();
5732 return 0;
5733 }
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05305734 /* Find if any iface is up. If any iface is up then can't put device to
5735 * sleep/power save mode
5736 */
Jeff Johnson295189b2012-06-20 16:38:30 -07005737 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
5738 while ( (NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status) )
5739 {
Jeff Johnson6a81ca42013-04-05 10:37:08 -07005740 if (test_bit(DEVICE_IFACE_OPENED, &pAdapterNode->pAdapter->event_flags))
5741 {
5742 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Still other ifaces are up cannot "
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05305743 "put device to sleep", __func__);
Jeff Johnson6a81ca42013-04-05 10:37:08 -07005744 enter_standby = FALSE;
5745 break;
5746 }
5747 else
5748 {
5749 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
5750 pAdapterNode = pNext;
5751 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005752 }
5753
5754 if (TRUE == enter_standby)
5755 {
5756 hddLog(VOS_TRACE_LEVEL_INFO, "%s: All Interfaces are Down "
5757 "entering standby", __func__);
5758 if (VOS_STATUS_SUCCESS != wlan_hdd_enter_lowpower(pHddCtx))
5759 {
5760 /*log and return success*/
5761 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Failed to put "
5762 "wlan in power save", __func__);
5763 }
5764 }
5765
5766 EXIT();
5767 return 0;
5768}
5769
5770/**---------------------------------------------------------------------------
5771
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305772 \brief hdd_stop() - wrapper_function for __hdd_stop to protect it from SSR
Jeff Johnson295189b2012-06-20 16:38:30 -07005773
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305774 This is called in response to ifconfig down
5775
5776 \param - dev Pointer to net_device structure
5777
5778 \return - 0 for success non-zero for failure
5779-----------------------------------------------------------------------------*/
5780int hdd_stop (struct net_device *dev)
5781{
5782 int ret;
5783
5784 vos_ssr_protect(__func__);
5785 ret = __hdd_stop(dev);
5786 vos_ssr_unprotect(__func__);
5787
5788 return ret;
5789}
5790
5791/**---------------------------------------------------------------------------
5792
5793 \brief __hdd_uninit() - HDD uninit function
Jeff Johnson295189b2012-06-20 16:38:30 -07005794
5795 \param - dev Pointer to net_device structure
5796
5797 \return - void
5798
5799 --------------------------------------------------------------------------*/
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305800static void __hdd_uninit (struct net_device *dev)
Jeff Johnson295189b2012-06-20 16:38:30 -07005801{
5802 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05305803 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07005804 ENTER();
5805
5806 do
5807 {
5808 if (NULL == pAdapter)
5809 {
5810 hddLog(VOS_TRACE_LEVEL_FATAL,
5811 "%s: NULL pAdapter", __func__);
5812 break;
5813 }
5814
5815 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
5816 {
5817 hddLog(VOS_TRACE_LEVEL_FATAL,
5818 "%s: Invalid magic", __func__);
5819 break;
5820 }
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05305821 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
5822 if (NULL == pHddCtx)
Jeff Johnson295189b2012-06-20 16:38:30 -07005823 {
5824 hddLog(VOS_TRACE_LEVEL_FATAL,
5825 "%s: NULL pHddCtx", __func__);
5826 break;
5827 }
5828
5829 if (dev != pAdapter->dev)
5830 {
5831 hddLog(VOS_TRACE_LEVEL_FATAL,
5832 "%s: Invalid device reference", __func__);
5833 /* we haven't validated all cases so let this go for now */
5834 }
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05305835#ifdef FEATURE_WLAN_TDLS
5836 mutex_lock(&pHddCtx->tdls_lock);
5837#endif
c_hpothu002231a2015-02-05 14:58:51 +05305838 hdd_deinit_adapter(pHddCtx, pAdapter, TRUE);
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05305839#ifdef FEATURE_WLAN_TDLS
5840 mutex_unlock(&pHddCtx->tdls_lock);
5841#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07005842
5843 /* after uninit our adapter structure will no longer be valid */
5844 pAdapter->dev = NULL;
5845 pAdapter->magic = 0;
5846 } while (0);
5847
5848 EXIT();
5849}
5850
5851/**---------------------------------------------------------------------------
5852
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305853 \brief hdd_uninit() - Wrapper function to protect __hdd_uninit from SSR
5854
5855 This is called during the netdev unregister to uninitialize all data
5856associated with the device
5857
5858 \param - dev Pointer to net_device structure
5859
5860 \return - void
5861
5862 --------------------------------------------------------------------------*/
5863static void hdd_uninit (struct net_device *dev)
5864{
5865 vos_ssr_protect(__func__);
5866 __hdd_uninit(dev);
5867 vos_ssr_unprotect(__func__);
5868}
5869
5870/**---------------------------------------------------------------------------
5871
Jeff Johnson295189b2012-06-20 16:38:30 -07005872 \brief hdd_release_firmware() -
5873
5874 This function calls the release firmware API to free the firmware buffer.
5875
5876 \param - pFileName Pointer to the File Name.
5877 pCtx - Pointer to the adapter .
5878
5879
5880 \return - 0 for success, non zero for failure
5881
5882 --------------------------------------------------------------------------*/
5883
5884VOS_STATUS hdd_release_firmware(char *pFileName,v_VOID_t *pCtx)
5885{
5886 VOS_STATUS status = VOS_STATUS_SUCCESS;
5887 hdd_context_t *pHddCtx = (hdd_context_t*)pCtx;
5888 ENTER();
5889
5890
5891 if (!strcmp(WLAN_FW_FILE, pFileName)) {
5892
5893 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,"%s: Loaded firmware file is %s",__func__,pFileName);
5894
5895 if(pHddCtx->fw) {
5896 release_firmware(pHddCtx->fw);
5897 pHddCtx->fw = NULL;
5898 }
5899 else
5900 status = VOS_STATUS_E_FAILURE;
5901 }
5902 else if (!strcmp(WLAN_NV_FILE,pFileName)) {
5903 if(pHddCtx->nv) {
5904 release_firmware(pHddCtx->nv);
5905 pHddCtx->nv = NULL;
5906 }
5907 else
5908 status = VOS_STATUS_E_FAILURE;
5909
5910 }
5911
5912 EXIT();
5913 return status;
5914}
5915
5916/**---------------------------------------------------------------------------
5917
5918 \brief hdd_request_firmware() -
5919
5920 This function reads the firmware file using the request firmware
5921 API and returns the the firmware data and the firmware file size.
5922
5923 \param - pfileName - Pointer to the file name.
5924 - pCtx - Pointer to the adapter .
5925 - ppfw_data - Pointer to the pointer of the firmware data.
5926 - pSize - Pointer to the file size.
5927
5928 \return - VOS_STATUS_SUCCESS for success, VOS_STATUS_E_FAILURE for failure
5929
5930 --------------------------------------------------------------------------*/
5931
5932
5933VOS_STATUS hdd_request_firmware(char *pfileName,v_VOID_t *pCtx,v_VOID_t **ppfw_data, v_SIZE_t *pSize)
5934{
5935 int status;
5936 VOS_STATUS retval = VOS_STATUS_SUCCESS;
5937 hdd_context_t *pHddCtx = (hdd_context_t*)pCtx;
5938 ENTER();
5939
5940 if( (!strcmp(WLAN_FW_FILE, pfileName)) ) {
5941
5942 status = request_firmware(&pHddCtx->fw, pfileName, pHddCtx->parent_dev);
5943
5944 if(status || !pHddCtx->fw || !pHddCtx->fw->data) {
5945 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Firmware %s download failed",
5946 __func__, pfileName);
5947 retval = VOS_STATUS_E_FAILURE;
5948 }
5949
5950 else {
5951 *ppfw_data = (v_VOID_t *)pHddCtx->fw->data;
5952 *pSize = pHddCtx->fw->size;
5953 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Firmware size = %d",
5954 __func__, *pSize);
5955 }
5956 }
5957 else if(!strcmp(WLAN_NV_FILE, pfileName)) {
5958
5959 status = request_firmware(&pHddCtx->nv, pfileName, pHddCtx->parent_dev);
5960
5961 if(status || !pHddCtx->nv || !pHddCtx->nv->data) {
5962 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: nv %s download failed",
5963 __func__, pfileName);
5964 retval = VOS_STATUS_E_FAILURE;
5965 }
5966
5967 else {
5968 *ppfw_data = (v_VOID_t *)pHddCtx->nv->data;
5969 *pSize = pHddCtx->nv->size;
5970 hddLog(VOS_TRACE_LEVEL_INFO, "%s: nv file size = %d",
5971 __func__, *pSize);
5972 }
5973 }
5974
5975 EXIT();
5976 return retval;
5977}
5978/**---------------------------------------------------------------------------
5979 \brief hdd_full_pwr_cbk() - HDD full power callbackfunction
5980
5981 This is the function invoked by SME to inform the result of a full power
5982 request issued by HDD
5983
5984 \param - callbackcontext - Pointer to cookie
5985 status - result of request
5986
5987 \return - None
5988
5989--------------------------------------------------------------------------*/
5990void hdd_full_pwr_cbk(void *callbackContext, eHalStatus status)
5991{
5992 hdd_context_t *pHddCtx = (hdd_context_t*)callbackContext;
5993
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07005994 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,"HDD full Power callback status = %d", status);
Jeff Johnson295189b2012-06-20 16:38:30 -07005995 if(&pHddCtx->full_pwr_comp_var)
5996 {
5997 complete(&pHddCtx->full_pwr_comp_var);
5998 }
5999}
6000
6001/**---------------------------------------------------------------------------
6002
6003 \brief hdd_req_bmps_cbk() - HDD Request BMPS callback function
6004
6005 This is the function invoked by SME to inform the result of BMPS
6006 request issued by HDD
6007
6008 \param - callbackcontext - Pointer to cookie
6009 status - result of request
6010
6011 \return - None
6012
6013--------------------------------------------------------------------------*/
6014void hdd_req_bmps_cbk(void *callbackContext, eHalStatus status)
6015{
6016
6017 struct completion *completion_var = (struct completion*) callbackContext;
6018
Arif Hussain6d2a3322013-11-17 19:50:10 -08006019 hddLog(VOS_TRACE_LEVEL_ERROR, "HDD BMPS request Callback, status = %d", status);
Jeff Johnson295189b2012-06-20 16:38:30 -07006020 if(completion_var != NULL)
6021 {
6022 complete(completion_var);
6023 }
6024}
6025
6026/**---------------------------------------------------------------------------
6027
6028 \brief hdd_get_cfg_file_size() -
6029
6030 This function reads the configuration file using the request firmware
6031 API and returns the configuration file size.
6032
6033 \param - pCtx - Pointer to the adapter .
6034 - pFileName - Pointer to the file name.
6035 - pBufSize - Pointer to the buffer size.
6036
6037 \return - 0 for success, non zero for failure
6038
6039 --------------------------------------------------------------------------*/
6040
6041VOS_STATUS hdd_get_cfg_file_size(v_VOID_t *pCtx, char *pFileName, v_SIZE_t *pBufSize)
6042{
6043 int status;
6044 hdd_context_t *pHddCtx = (hdd_context_t*)pCtx;
6045
6046 ENTER();
6047
6048 status = request_firmware(&pHddCtx->fw, pFileName, pHddCtx->parent_dev);
6049
6050 if(status || !pHddCtx->fw || !pHddCtx->fw->data) {
6051 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: CFG download failed",__func__);
6052 status = VOS_STATUS_E_FAILURE;
6053 }
6054 else {
6055 *pBufSize = pHddCtx->fw->size;
6056 hddLog(VOS_TRACE_LEVEL_INFO, "%s: CFG size = %d", __func__, *pBufSize);
6057 release_firmware(pHddCtx->fw);
6058 pHddCtx->fw = NULL;
6059 }
6060
6061 EXIT();
6062 return VOS_STATUS_SUCCESS;
6063}
6064
6065/**---------------------------------------------------------------------------
6066
6067 \brief hdd_read_cfg_file() -
6068
6069 This function reads the configuration file using the request firmware
6070 API and returns the cfg data and the buffer size of the configuration file.
6071
6072 \param - pCtx - Pointer to the adapter .
6073 - pFileName - Pointer to the file name.
6074 - pBuffer - Pointer to the data buffer.
6075 - pBufSize - Pointer to the buffer size.
6076
6077 \return - 0 for success, non zero for failure
6078
6079 --------------------------------------------------------------------------*/
6080
6081VOS_STATUS hdd_read_cfg_file(v_VOID_t *pCtx, char *pFileName,
6082 v_VOID_t *pBuffer, v_SIZE_t *pBufSize)
6083{
6084 int status;
6085 hdd_context_t *pHddCtx = (hdd_context_t*)pCtx;
6086
6087 ENTER();
6088
6089 status = request_firmware(&pHddCtx->fw, pFileName, pHddCtx->parent_dev);
6090
6091 if(status || !pHddCtx->fw || !pHddCtx->fw->data) {
6092 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: CFG download failed",__func__);
6093 return VOS_STATUS_E_FAILURE;
6094 }
6095 else {
6096 if(*pBufSize != pHddCtx->fw->size) {
6097 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Caller sets invalid CFG "
6098 "file size", __func__);
6099 release_firmware(pHddCtx->fw);
6100 pHddCtx->fw = NULL;
6101 return VOS_STATUS_E_FAILURE;
6102 }
6103 else {
6104 if(pBuffer) {
6105 vos_mem_copy(pBuffer,pHddCtx->fw->data,*pBufSize);
6106 }
6107 release_firmware(pHddCtx->fw);
6108 pHddCtx->fw = NULL;
6109 }
6110 }
6111
6112 EXIT();
6113
6114 return VOS_STATUS_SUCCESS;
6115}
6116
6117/**---------------------------------------------------------------------------
6118
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05306119 \brief __hdd_set_mac_address() -
Jeff Johnson295189b2012-06-20 16:38:30 -07006120
6121 This function sets the user specified mac address using
6122 the command ifconfig wlanX hw ether <mac adress>.
6123
6124 \param - dev - Pointer to the net device.
6125 - addr - Pointer to the sockaddr.
6126 \return - 0 for success, non zero for failure
6127
6128 --------------------------------------------------------------------------*/
6129
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05306130static int __hdd_set_mac_address(struct net_device *dev, void *addr)
Jeff Johnson295189b2012-06-20 16:38:30 -07006131{
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05306132 hdd_adapter_t *pAdapter;
6133 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07006134 struct sockaddr *psta_mac_addr = addr;
6135 eHalStatus halStatus = eHAL_STATUS_SUCCESS;
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05306136 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07006137
6138 ENTER();
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05306139 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6140 if (NULL == pAdapter)
6141 {
6142 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6143 "%s: Adapter is NULL",__func__);
6144 return -EINVAL;
6145 }
6146 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
6147 ret = wlan_hdd_validate_context(pHddCtx);
6148 if (0 != ret)
6149 {
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05306150 return ret;
6151 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006152
6153 memcpy(&pAdapter->macAddressCurrent, psta_mac_addr->sa_data, ETH_ALEN);
Jeff Johnson295189b2012-06-20 16:38:30 -07006154 memcpy(dev->dev_addr, psta_mac_addr->sa_data, ETH_ALEN);
6155
6156 EXIT();
6157 return halStatus;
6158}
6159
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05306160/**---------------------------------------------------------------------------
6161
6162 \brief hdd_set_mac_address() -
6163
6164 Wrapper function to protect __hdd_set_mac_address() function from ssr
6165
6166 \param - dev - Pointer to the net device.
6167 - addr - Pointer to the sockaddr.
6168 \return - 0 for success, non zero for failure
6169
6170 --------------------------------------------------------------------------*/
6171static int hdd_set_mac_address(struct net_device *dev, void *addr)
6172{
6173 int ret;
6174
6175 vos_ssr_protect(__func__);
6176 ret = __hdd_set_mac_address(dev, addr);
6177 vos_ssr_unprotect(__func__);
6178
6179 return ret;
6180}
6181
Jeff Johnson295189b2012-06-20 16:38:30 -07006182tANI_U8* wlan_hdd_get_intf_addr(hdd_context_t* pHddCtx)
6183{
6184 int i;
6185 for ( i = 0; i < VOS_MAX_CONCURRENCY_PERSONA; i++)
6186 {
Abhishek Singheb183782014-02-06 13:37:21 +05306187 if( 0 == ((pHddCtx->cfg_ini->intfAddrMask) & (1 << i)) )
Jeff Johnson295189b2012-06-20 16:38:30 -07006188 break;
6189 }
6190
6191 if( VOS_MAX_CONCURRENCY_PERSONA == i)
6192 return NULL;
6193
6194 pHddCtx->cfg_ini->intfAddrMask |= (1 << i);
6195 return &pHddCtx->cfg_ini->intfMacAddr[i].bytes[0];
6196}
6197
6198void wlan_hdd_release_intf_addr(hdd_context_t* pHddCtx, tANI_U8* releaseAddr)
6199{
6200 int i;
6201 for ( i = 0; i < VOS_MAX_CONCURRENCY_PERSONA; i++)
6202 {
6203 if ( !memcmp(releaseAddr, &pHddCtx->cfg_ini->intfMacAddr[i].bytes[0], 6) )
6204 {
6205 pHddCtx->cfg_ini->intfAddrMask &= ~(1 << i);
6206 break;
6207 }
6208 }
6209 return;
6210}
6211
6212#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29))
6213 static struct net_device_ops wlan_drv_ops = {
6214 .ndo_open = hdd_open,
6215 .ndo_stop = hdd_stop,
6216 .ndo_uninit = hdd_uninit,
6217 .ndo_start_xmit = hdd_hard_start_xmit,
6218 .ndo_tx_timeout = hdd_tx_timeout,
6219 .ndo_get_stats = hdd_stats,
6220 .ndo_do_ioctl = hdd_ioctl,
6221 .ndo_set_mac_address = hdd_set_mac_address,
6222 .ndo_select_queue = hdd_select_queue,
6223#ifdef WLAN_FEATURE_PACKET_FILTERING
6224#if (LINUX_VERSION_CODE > KERNEL_VERSION(3,1,0))
6225 .ndo_set_rx_mode = hdd_set_multicast_list,
6226#else
6227 .ndo_set_multicast_list = hdd_set_multicast_list,
6228#endif //LINUX_VERSION_CODE
6229#endif
6230 };
Jeff Johnson295189b2012-06-20 16:38:30 -07006231 static struct net_device_ops wlan_mon_drv_ops = {
6232 .ndo_open = hdd_mon_open,
Katya Nigame7b69a82015-04-28 15:24:06 +05306233 .ndo_stop = hdd_mon_stop,
Jeff Johnson295189b2012-06-20 16:38:30 -07006234 .ndo_uninit = hdd_uninit,
6235 .ndo_start_xmit = hdd_mon_hard_start_xmit,
6236 .ndo_tx_timeout = hdd_tx_timeout,
6237 .ndo_get_stats = hdd_stats,
Katya Nigame7b69a82015-04-28 15:24:06 +05306238 .ndo_do_ioctl = hdd_mon_ioctl,
Jeff Johnson295189b2012-06-20 16:38:30 -07006239 .ndo_set_mac_address = hdd_set_mac_address,
6240 };
Mahesh A Saptasagar305e2632015-03-04 12:57:33 +05306241
Jeff Johnson295189b2012-06-20 16:38:30 -07006242#endif
6243
6244void hdd_set_station_ops( struct net_device *pWlanDev )
6245{
6246#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29))
Jeff Johnson295189b2012-06-20 16:38:30 -07006247 pWlanDev->netdev_ops = &wlan_drv_ops;
6248#else
6249 pWlanDev->open = hdd_open;
6250 pWlanDev->stop = hdd_stop;
6251 pWlanDev->uninit = hdd_uninit;
6252 pWlanDev->hard_start_xmit = NULL;
6253 pWlanDev->tx_timeout = hdd_tx_timeout;
6254 pWlanDev->get_stats = hdd_stats;
6255 pWlanDev->do_ioctl = hdd_ioctl;
Jeff Johnson295189b2012-06-20 16:38:30 -07006256 pWlanDev->set_mac_address = hdd_set_mac_address;
6257#endif
6258}
6259
Katya Nigam1fd24402015-02-16 14:52:19 +05306260void hdd_set_ibss_ops( hdd_adapter_t *pAdapter )
6261{
6262 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29))
6263 wlan_drv_ops.ndo_start_xmit = hdd_ibss_hard_start_xmit;
6264 #else
6265 pAdapter->dev->hard_start_xmit = hdd_ibss_hard_start_xmit;
6266 #endif
6267}
6268
Jeff Johnsoneed415b2013-01-18 16:11:20 -08006269static hdd_adapter_t* hdd_alloc_station_adapter( hdd_context_t *pHddCtx, tSirMacAddr macAddr, const char* name )
Jeff Johnson295189b2012-06-20 16:38:30 -07006270{
6271 struct net_device *pWlanDev = NULL;
6272 hdd_adapter_t *pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07006273 /*
6274 * cfg80211 initialization and registration....
6275 */
Anand N Sunkadc34abbd2015-07-29 09:52:59 +05306276 pWlanDev = alloc_netdev_mq(sizeof( hdd_adapter_t ), name,
6277#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,17,0))
6278 NET_NAME_UNKNOWN,
6279#endif
6280 ether_setup, NUM_TX_QUEUES);
Jeff Johnson295189b2012-06-20 16:38:30 -07006281 if(pWlanDev != NULL)
6282 {
6283
6284 //Save the pointer to the net_device in the HDD adapter
6285 pAdapter = (hdd_adapter_t*) netdev_priv( pWlanDev );
6286
Jeff Johnson295189b2012-06-20 16:38:30 -07006287 vos_mem_zero( pAdapter, sizeof( hdd_adapter_t ) );
6288
6289 pAdapter->dev = pWlanDev;
6290 pAdapter->pHddCtx = pHddCtx;
6291 pAdapter->magic = WLAN_HDD_ADAPTER_MAGIC;
Agarwal Ashish47d18112014-08-04 19:55:07 +05306292 spin_lock_init(&pAdapter->lock_for_active_session);
Jeff Johnson295189b2012-06-20 16:38:30 -07006293
Rajeev79dbe4c2013-10-05 11:03:42 +05306294#ifdef FEATURE_WLAN_BATCH_SCAN
Rajeev79dbe4c2013-10-05 11:03:42 +05306295 pAdapter->pBatchScanRsp = NULL;
6296 pAdapter->numScanList = 0;
Rajeev Kumar20140c12013-10-21 19:39:02 -07006297 pAdapter->batchScanState = eHDD_BATCH_SCAN_STATE_STOPPED;
Kiet Lamaa8e15a2014-02-11 23:30:06 -08006298 pAdapter->prev_batch_id = 0;
Rajeev79dbe4c2013-10-05 11:03:42 +05306299 mutex_init(&pAdapter->hdd_batch_scan_lock);
6300#endif
6301
Jeff Johnson295189b2012-06-20 16:38:30 -07006302 pAdapter->isLinkUpSvcNeeded = FALSE;
6303 pAdapter->higherDtimTransition = eANI_BOOLEAN_TRUE;
6304 //Init the net_device structure
6305 strlcpy(pWlanDev->name, name, IFNAMSIZ);
6306
6307 vos_mem_copy(pWlanDev->dev_addr, (void *)macAddr, sizeof(tSirMacAddr));
6308 vos_mem_copy( pAdapter->macAddressCurrent.bytes, macAddr, sizeof(tSirMacAddr));
6309 pWlanDev->watchdog_timeo = HDD_TX_TIMEOUT;
6310 pWlanDev->hard_header_len += LIBRA_HW_NEEDED_HEADROOM;
6311
6312 hdd_set_station_ops( pAdapter->dev );
6313
6314 pWlanDev->destructor = free_netdev;
Jeff Johnson295189b2012-06-20 16:38:30 -07006315 pWlanDev->ieee80211_ptr = &pAdapter->wdev ;
6316 pAdapter->wdev.wiphy = pHddCtx->wiphy;
6317 pAdapter->wdev.netdev = pWlanDev;
Jeff Johnson295189b2012-06-20 16:38:30 -07006318 /* set pWlanDev's parent to underlying device */
6319 SET_NETDEV_DEV(pWlanDev, pHddCtx->parent_dev);
Kumar Anand82c009f2014-05-29 00:29:42 -07006320
6321 hdd_wmm_init( pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -07006322 }
6323
6324 return pAdapter;
6325}
6326
6327VOS_STATUS hdd_register_interface( hdd_adapter_t *pAdapter, tANI_U8 rtnl_lock_held )
6328{
6329 struct net_device *pWlanDev = pAdapter->dev;
6330 //hdd_station_ctx_t *pHddStaCtx = &pAdapter->sessionCtx.station;
6331 //hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
6332 //eHalStatus halStatus = eHAL_STATUS_SUCCESS;
6333
6334 if( rtnl_lock_held )
6335 {
Madan Mohan Koyyalamudid8ac8662012-11-06 19:04:56 -08006336 if (strnchr(pWlanDev->name, strlen(pWlanDev->name), '%')) {
Jeff Johnson295189b2012-06-20 16:38:30 -07006337 if( dev_alloc_name(pWlanDev, pWlanDev->name) < 0 )
6338 {
6339 hddLog(VOS_TRACE_LEVEL_ERROR,"%s:Failed:dev_alloc_name",__func__);
6340 return VOS_STATUS_E_FAILURE;
6341 }
6342 }
6343 if (register_netdevice(pWlanDev))
6344 {
6345 hddLog(VOS_TRACE_LEVEL_ERROR,"%s:Failed:register_netdev",__func__);
6346 return VOS_STATUS_E_FAILURE;
6347 }
6348 }
6349 else
6350 {
6351 if(register_netdev(pWlanDev))
6352 {
6353 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Failed:register_netdev",__func__);
6354 return VOS_STATUS_E_FAILURE;
6355 }
6356 }
6357 set_bit(NET_DEVICE_REGISTERED, &pAdapter->event_flags);
6358
6359 return VOS_STATUS_SUCCESS;
6360}
6361
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006362static eHalStatus hdd_smeCloseSessionCallback(void *pContext)
Jeff Johnson295189b2012-06-20 16:38:30 -07006363{
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006364 hdd_adapter_t *pAdapter = pContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07006365
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006366 if (NULL == pAdapter)
6367 {
6368 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: NULL pAdapter", __func__);
6369 return eHAL_STATUS_INVALID_PARAMETER;
Jeff Johnson295189b2012-06-20 16:38:30 -07006370 }
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006371
6372 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
6373 {
6374 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Invalid magic", __func__);
6375 return eHAL_STATUS_NOT_INITIALIZED;
6376 }
6377
6378 clear_bit(SME_SESSION_OPENED, &pAdapter->event_flags);
6379
Sameer Thalappilbee426e2013-10-30 10:30:30 -07006380#ifndef WLAN_OPEN_SOURCE
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006381 /* need to make sure all of our scheduled work has completed.
6382 * This callback is called from MC thread context, so it is safe to
6383 * to call below flush workqueue API from here.
Sameer Thalappilbee426e2013-10-30 10:30:30 -07006384 *
6385 * Even though this is called from MC thread context, if there is a faulty
6386 * work item in the system, that can hang this call forever. So flushing
6387 * this global work queue is not safe; and now we make sure that
6388 * individual work queues are stopped correctly. But the cancel work queue
6389 * is a GPL only API, so the proprietary version of the driver would still
6390 * rely on the global work queue flush.
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006391 */
6392 flush_scheduled_work();
Sameer Thalappilbee426e2013-10-30 10:30:30 -07006393#endif
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006394
6395 /* We can be blocked while waiting for scheduled work to be
6396 * flushed, and the adapter structure can potentially be freed, in
6397 * which case the magic will have been reset. So make sure the
6398 * magic is still good, and hence the adapter structure is still
6399 * valid, before signaling completion */
6400 if (WLAN_HDD_ADAPTER_MAGIC == pAdapter->magic)
6401 {
6402 complete(&pAdapter->session_close_comp_var);
6403 }
6404
Jeff Johnson295189b2012-06-20 16:38:30 -07006405 return eHAL_STATUS_SUCCESS;
6406}
6407
6408VOS_STATUS hdd_init_station_mode( hdd_adapter_t *pAdapter )
6409{
6410 struct net_device *pWlanDev = pAdapter->dev;
6411 hdd_station_ctx_t *pHddStaCtx = &pAdapter->sessionCtx.station;
6412 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
6413 eHalStatus halStatus = eHAL_STATUS_SUCCESS;
6414 VOS_STATUS status = VOS_STATUS_E_FAILURE;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306415 long rc = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07006416
Nirav Shah7e3c8132015-06-22 23:51:42 +05306417 spin_lock_init( &pAdapter->sta_hash_lock);
6418 pAdapter->is_sta_id_hash_initialized = VOS_FALSE;
6419
Jeff Johnson295189b2012-06-20 16:38:30 -07006420 INIT_COMPLETION(pAdapter->session_open_comp_var);
Kiran Kumar Lokere0ad5cd32013-06-25 11:26:22 -07006421 sme_SetCurrDeviceMode(pHddCtx->hHal, pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07006422 //Open a SME session for future operation
6423 halStatus = sme_OpenSession( pHddCtx->hHal, hdd_smeRoamCallback, pAdapter,
Kiran Kumar Lokere0ad5cd32013-06-25 11:26:22 -07006424 (tANI_U8 *)&pAdapter->macAddressCurrent, &pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07006425 if ( !HAL_STATUS_SUCCESS( halStatus ) )
6426 {
6427 hddLog(VOS_TRACE_LEVEL_FATAL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07006428 "sme_OpenSession() failed with status code %08d [x%08x]",
Jeff Johnson295189b2012-06-20 16:38:30 -07006429 halStatus, halStatus );
6430 status = VOS_STATUS_E_FAILURE;
6431 goto error_sme_open;
6432 }
6433
6434 //Block on a completion variable. Can't wait forever though.
Vinay Krishna Eranna0fe2e7c2014-04-09 21:32:08 +05306435 rc = wait_for_completion_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -07006436 &pAdapter->session_open_comp_var,
6437 msecs_to_jiffies(WLAN_WAIT_TIME_SESSIONOPENCLOSE));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306438 if (rc <= 0)
Jeff Johnson295189b2012-06-20 16:38:30 -07006439 {
6440 hddLog(VOS_TRACE_LEVEL_FATAL,
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306441 "Session is not opened within timeout period code %ld", rc );
Jeff Johnson295189b2012-06-20 16:38:30 -07006442 status = VOS_STATUS_E_FAILURE;
6443 goto error_sme_open;
6444 }
6445
6446 // Register wireless extensions
6447 if( eHAL_STATUS_SUCCESS != (halStatus = hdd_register_wext(pWlanDev)))
6448 {
6449 hddLog(VOS_TRACE_LEVEL_FATAL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07006450 "hdd_register_wext() failed with status code %08d [x%08x]",
Jeff Johnson295189b2012-06-20 16:38:30 -07006451 halStatus, halStatus );
6452 status = VOS_STATUS_E_FAILURE;
6453 goto error_register_wext;
6454 }
Katya Nigam1fd24402015-02-16 14:52:19 +05306455
Jeff Johnson295189b2012-06-20 16:38:30 -07006456 //Safe to register the hard_start_xmit function again
Katya Nigam1fd24402015-02-16 14:52:19 +05306457 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29))
6458 wlan_drv_ops.ndo_start_xmit = hdd_hard_start_xmit;
6459 #else
6460 pWlanDev->hard_start_xmit = hdd_hard_start_xmit;
6461 #endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006462
6463 //Set the Connection State to Not Connected
Abhishek Singhf4669da2014-05-26 15:07:49 +05306464 hddLog(VOS_TRACE_LEVEL_INFO,
6465 "%s: Set HDD connState to eConnectionState_NotConnected",
6466 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006467 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
6468
6469 //Set the default operation channel
6470 pHddStaCtx->conn_info.operationChannel = pHddCtx->cfg_ini->OperatingChannel;
6471
6472 /* Make the default Auth Type as OPEN*/
6473 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_OPEN_SYSTEM;
6474
6475 if( VOS_STATUS_SUCCESS != ( status = hdd_init_tx_rx( pAdapter ) ) )
6476 {
6477 hddLog(VOS_TRACE_LEVEL_FATAL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07006478 "hdd_init_tx_rx() failed with status code %08d [x%08x]",
Jeff Johnson295189b2012-06-20 16:38:30 -07006479 status, status );
6480 goto error_init_txrx;
6481 }
6482
6483 set_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
6484
6485 if( VOS_STATUS_SUCCESS != ( status = hdd_wmm_adapter_init( pAdapter ) ) )
6486 {
6487 hddLog(VOS_TRACE_LEVEL_FATAL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07006488 "hdd_wmm_adapter_init() failed with status code %08d [x%08x]",
Jeff Johnson295189b2012-06-20 16:38:30 -07006489 status, status );
6490 goto error_wmm_init;
6491 }
6492
6493 set_bit(WMM_INIT_DONE, &pAdapter->event_flags);
6494
6495 return VOS_STATUS_SUCCESS;
6496
6497error_wmm_init:
6498 clear_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
6499 hdd_deinit_tx_rx(pAdapter);
6500error_init_txrx:
6501 hdd_UnregisterWext(pWlanDev);
6502error_register_wext:
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006503 if (test_bit(SME_SESSION_OPENED, &pAdapter->event_flags))
Jeff Johnson295189b2012-06-20 16:38:30 -07006504 {
6505 INIT_COMPLETION(pAdapter->session_close_comp_var);
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006506 if (eHAL_STATUS_SUCCESS == sme_CloseSession(pHddCtx->hHal,
mukul sharmabab477d2015-06-11 17:14:55 +05306507 pAdapter->sessionId, VOS_TRUE,
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006508 hdd_smeCloseSessionCallback, pAdapter))
Jeff Johnson295189b2012-06-20 16:38:30 -07006509 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306510 unsigned long rc;
6511
Jeff Johnson295189b2012-06-20 16:38:30 -07006512 //Block on a completion variable. Can't wait forever though.
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306513 rc = wait_for_completion_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -07006514 &pAdapter->session_close_comp_var,
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006515 msecs_to_jiffies(WLAN_WAIT_TIME_SESSIONOPENCLOSE));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306516 if (rc <= 0)
6517 hddLog(VOS_TRACE_LEVEL_ERROR,
6518 FL("Session is not opened within timeout period code %ld"), rc);
Jeff Johnson295189b2012-06-20 16:38:30 -07006519 }
6520}
6521error_sme_open:
6522 return status;
6523}
6524
Jeff Johnson295189b2012-06-20 16:38:30 -07006525void hdd_cleanup_actionframe( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter )
6526{
6527 hdd_cfg80211_state_t *cfgState;
6528
6529 cfgState = WLAN_HDD_GET_CFG_STATE_PTR( pAdapter );
6530
6531 if( NULL != cfgState->buf )
6532 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306533 long rc;
Jeff Johnson295189b2012-06-20 16:38:30 -07006534 INIT_COMPLETION(pAdapter->tx_action_cnf_event);
6535 rc = wait_for_completion_interruptible_timeout(
6536 &pAdapter->tx_action_cnf_event,
6537 msecs_to_jiffies(ACTION_FRAME_TX_TIMEOUT));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306538 if (rc <= 0)
Jeff Johnson295189b2012-06-20 16:38:30 -07006539 {
Deepthi Gowri91b3e9c2015-08-25 13:14:58 +05306540 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6541 "%s ERROR: HDD Wait for Action Confirmation Failed!! %ld"
6542 , __func__, rc);
6543
6544 // Inform tx status as FAILURE to upper layer and free cfgState->buf
6545 hdd_sendActionCnf( pAdapter, FALSE );
Jeff Johnson295189b2012-06-20 16:38:30 -07006546 }
6547 }
6548 return;
6549}
Jeff Johnson295189b2012-06-20 16:38:30 -07006550
c_hpothu002231a2015-02-05 14:58:51 +05306551void hdd_deinit_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter, tANI_U8 rtnl_held )
Jeff Johnson295189b2012-06-20 16:38:30 -07006552{
6553 ENTER();
6554 switch ( pAdapter->device_mode )
6555 {
Katya Nigam1fd24402015-02-16 14:52:19 +05306556 case WLAN_HDD_IBSS:
6557 {
6558 if(test_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags))
6559 {
6560 hdd_ibss_deinit_tx_rx( pAdapter );
6561 clear_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
6562 }
6563 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006564 case WLAN_HDD_INFRA_STATION:
6565 case WLAN_HDD_P2P_CLIENT:
Jeff Johnsone7245742012-09-05 17:12:55 -07006566 case WLAN_HDD_P2P_DEVICE:
Jeff Johnson295189b2012-06-20 16:38:30 -07006567 {
6568 if(test_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags))
6569 {
6570 hdd_deinit_tx_rx( pAdapter );
6571 clear_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
6572 }
6573
6574 if(test_bit(WMM_INIT_DONE, &pAdapter->event_flags))
6575 {
6576 hdd_wmm_adapter_close( pAdapter );
6577 clear_bit(WMM_INIT_DONE, &pAdapter->event_flags);
6578 }
6579
Jeff Johnson295189b2012-06-20 16:38:30 -07006580 hdd_cleanup_actionframe(pHddCtx, pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07006581 break;
6582 }
6583
6584 case WLAN_HDD_SOFTAP:
6585 case WLAN_HDD_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07006586 {
Madan Mohan Koyyalamudi8c6dec82013-09-26 15:56:13 +05306587
6588 if (test_bit(WMM_INIT_DONE, &pAdapter->event_flags))
6589 {
6590 hdd_wmm_adapter_close( pAdapter );
6591 clear_bit(WMM_INIT_DONE, &pAdapter->event_flags);
6592 }
6593
Jeff Johnson295189b2012-06-20 16:38:30 -07006594 hdd_cleanup_actionframe(pHddCtx, pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07006595
c_hpothu002231a2015-02-05 14:58:51 +05306596 hdd_unregister_hostapd(pAdapter, rtnl_held);
Jeff Johnson295189b2012-06-20 16:38:30 -07006597 hdd_set_conparam( 0 );
Jeff Johnson295189b2012-06-20 16:38:30 -07006598 break;
6599 }
6600
6601 case WLAN_HDD_MONITOR:
6602 {
Jeff Johnson295189b2012-06-20 16:38:30 -07006603 if(test_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags))
6604 {
6605 hdd_deinit_tx_rx( pAdapter );
6606 clear_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
6607 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006608 break;
6609 }
6610
6611
6612 default:
6613 break;
6614 }
6615
6616 EXIT();
6617}
6618
6619void hdd_cleanup_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter, tANI_U8 rtnl_held )
6620{
Mingcheng Zhu87f22fc2014-01-30 19:23:32 -08006621 struct net_device *pWlanDev = NULL;
Srinivas, Dasari693dfc52013-12-27 17:29:09 +05306622
6623 ENTER();
6624 if (NULL == pAdapter)
6625 {
6626 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6627 "%s: HDD adapter is Null", __func__);
6628 return;
6629 }
6630
6631 pWlanDev = pAdapter->dev;
Jeff Johnson295189b2012-06-20 16:38:30 -07006632
Rajeev79dbe4c2013-10-05 11:03:42 +05306633#ifdef FEATURE_WLAN_BATCH_SCAN
Srinivas, Dasari693dfc52013-12-27 17:29:09 +05306634 if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
6635 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Rajeev Kumarf999e582014-01-09 17:33:29 -08006636 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Srinivas, Dasari693dfc52013-12-27 17:29:09 +05306637 || (pAdapter->device_mode == WLAN_HDD_P2P_DEVICE)
6638 )
6639 {
Rajeev Kumarf999e582014-01-09 17:33:29 -08006640 if (pAdapter)
Rajeev79dbe4c2013-10-05 11:03:42 +05306641 {
Rajeev Kumarf999e582014-01-09 17:33:29 -08006642 if (eHDD_BATCH_SCAN_STATE_STARTED == pAdapter->batchScanState)
6643 {
6644 hdd_deinit_batch_scan(pAdapter);
6645 }
Rajeev79dbe4c2013-10-05 11:03:42 +05306646 }
Rajeev Kumarf999e582014-01-09 17:33:29 -08006647 }
Rajeev79dbe4c2013-10-05 11:03:42 +05306648#endif
6649
Jeff Johnson295189b2012-06-20 16:38:30 -07006650 if(test_bit(NET_DEVICE_REGISTERED, &pAdapter->event_flags)) {
6651 if( rtnl_held )
6652 {
6653 unregister_netdevice(pWlanDev);
6654 }
6655 else
6656 {
6657 unregister_netdev(pWlanDev);
6658 }
6659 // note that the pAdapter is no longer valid at this point
6660 // since the memory has been reclaimed
6661 }
6662
Srinivas, Dasari693dfc52013-12-27 17:29:09 +05306663 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07006664}
6665
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006666void hdd_set_pwrparams(hdd_context_t *pHddCtx)
6667{
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306668 VOS_STATUS status;
6669 hdd_adapter_t *pAdapter = NULL;
6670 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006671
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306672 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006673
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306674 /*loop through all adapters.*/
6675 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006676 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306677 pAdapter = pAdapterNode->pAdapter;
6678 if ( (WLAN_HDD_INFRA_STATION != pAdapter->device_mode)
6679 && (WLAN_HDD_P2P_CLIENT != pAdapter->device_mode) )
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006680
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306681 { // we skip this registration for modes other than STA and P2P client modes.
6682 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
6683 pAdapterNode = pNext;
6684 continue;
6685 }
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006686
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306687 //Apply Dynamic DTIM For P2P
6688 //Only if ignoreDynamicDtimInP2pMode is not set in ini
6689 if ((pHddCtx->cfg_ini->enableDynamicDTIM ||
6690 pHddCtx->cfg_ini->enableModulatedDTIM) &&
6691 ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
6692 ((WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) &&
6693 !(pHddCtx->cfg_ini->ignoreDynamicDtimInP2pMode))) &&
6694 (eANI_BOOLEAN_TRUE == pAdapter->higherDtimTransition) &&
6695 (eConnectionState_Associated ==
6696 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState) &&
6697 (pHddCtx->cfg_ini->fIsBmpsEnabled))
6698 {
6699 tSirSetPowerParamsReq powerRequest = { 0 };
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006700
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306701 powerRequest.uIgnoreDTIM = 1;
6702 powerRequest.uMaxLIModulatedDTIM = pHddCtx->cfg_ini->fMaxLIModulatedDTIM;
6703
6704 if (pHddCtx->cfg_ini->enableModulatedDTIM)
6705 {
6706 powerRequest.uDTIMPeriod = pHddCtx->cfg_ini->enableModulatedDTIM;
6707 powerRequest.uListenInterval = pHddCtx->hdd_actual_LI_value;
6708 }
6709 else
6710 {
6711 powerRequest.uListenInterval = pHddCtx->cfg_ini->enableDynamicDTIM;
6712 }
6713
6714 /* Update ignoreDTIM and ListedInterval in CFG to remain at the DTIM
6715 * specified during Enter/Exit BMPS when LCD off*/
6716 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IGNORE_DTIM, powerRequest.uIgnoreDTIM,
6717 NULL, eANI_BOOLEAN_FALSE);
6718 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_LISTEN_INTERVAL, powerRequest.uListenInterval,
6719 NULL, eANI_BOOLEAN_FALSE);
6720
6721 /* switch to the DTIM specified in cfg.ini */
6722 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Abhishek Singh1e390cf2015-10-27 13:45:17 +05306723 "Switch to DTIM %d Listen interval %d",
6724 powerRequest.uDTIMPeriod,
6725 powerRequest.uListenInterval);
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306726 sme_SetPowerParams( pHddCtx->hHal, &powerRequest, TRUE);
6727 break;
6728
6729 }
6730
6731 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
6732 pAdapterNode = pNext;
6733 }
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006734}
6735
6736void hdd_reset_pwrparams(hdd_context_t *pHddCtx)
6737{
6738 /*Switch back to DTIM 1*/
6739 tSirSetPowerParamsReq powerRequest = { 0 };
6740
6741 powerRequest.uIgnoreDTIM = pHddCtx->hdd_actual_ignore_DTIM_value;
6742 powerRequest.uListenInterval = pHddCtx->hdd_actual_LI_value;
Yue Mac24062f2013-05-13 17:01:29 -07006743 powerRequest.uMaxLIModulatedDTIM = pHddCtx->cfg_ini->fMaxLIModulatedDTIM;
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006744
6745 /* Update ignoreDTIM and ListedInterval in CFG with default values */
6746 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IGNORE_DTIM, powerRequest.uIgnoreDTIM,
6747 NULL, eANI_BOOLEAN_FALSE);
6748 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_LISTEN_INTERVAL, powerRequest.uListenInterval,
6749 NULL, eANI_BOOLEAN_FALSE);
6750
6751 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6752 "Switch to DTIM%d",powerRequest.uListenInterval);
6753 sme_SetPowerParams( pHddCtx->hHal, &powerRequest, TRUE);
6754
6755}
6756
Jeff Johnson295189b2012-06-20 16:38:30 -07006757VOS_STATUS hdd_enable_bmps_imps(hdd_context_t *pHddCtx)
6758{
6759 VOS_STATUS status = VOS_STATUS_SUCCESS;
Sushant Kaushik4928e542014-12-29 15:25:54 +05306760 if (WLAN_HDD_IS_UNLOAD_IN_PROGRESS(pHddCtx))
6761 {
6762 hddLog( LOGE, FL("Wlan Unload in progress"));
6763 return VOS_STATUS_E_PERM;
6764 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006765 if(pHddCtx->cfg_ini->fIsBmpsEnabled)
6766 {
6767 sme_EnablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
6768 }
6769
6770 if(pHddCtx->cfg_ini->fIsAutoBmpsTimerEnabled)
6771 {
6772 sme_StartAutoBmpsTimer(pHddCtx->hHal);
6773 }
6774
6775 if (pHddCtx->cfg_ini->fIsImpsEnabled)
6776 {
6777 sme_EnablePowerSave (pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
6778 }
6779
6780 return status;
6781}
6782
6783VOS_STATUS hdd_disable_bmps_imps(hdd_context_t *pHddCtx, tANI_U8 session_type)
6784{
6785 hdd_adapter_t *pAdapter = NULL;
6786 eHalStatus halStatus;
6787 VOS_STATUS status = VOS_STATUS_E_INVAL;
6788 v_BOOL_t disableBmps = FALSE;
6789 v_BOOL_t disableImps = FALSE;
6790
6791 switch(session_type)
6792 {
6793 case WLAN_HDD_INFRA_STATION:
6794 case WLAN_HDD_SOFTAP:
Jeff Johnson295189b2012-06-20 16:38:30 -07006795 case WLAN_HDD_P2P_CLIENT:
6796 case WLAN_HDD_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07006797 //Exit BMPS -> Is Sta/P2P Client is already connected
6798 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION);
6799 if((NULL != pAdapter)&&
6800 hdd_connIsConnected( WLAN_HDD_GET_STATION_CTX_PTR(pAdapter)))
6801 {
6802 disableBmps = TRUE;
6803 }
6804
6805 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_CLIENT);
6806 if((NULL != pAdapter)&&
6807 hdd_connIsConnected( WLAN_HDD_GET_STATION_CTX_PTR(pAdapter)))
6808 {
6809 disableBmps = TRUE;
6810 }
6811
6812 //Exit both Bmps and Imps incase of Go/SAP Mode
6813 if((WLAN_HDD_SOFTAP == session_type) ||
6814 (WLAN_HDD_P2P_GO == session_type))
6815 {
6816 disableBmps = TRUE;
6817 disableImps = TRUE;
6818 }
6819
6820 if(TRUE == disableImps)
6821 {
6822 if (pHddCtx->cfg_ini->fIsImpsEnabled)
6823 {
6824 sme_DisablePowerSave (pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
6825 }
6826 }
6827
6828 if(TRUE == disableBmps)
6829 {
6830 if(pHddCtx->cfg_ini->fIsBmpsEnabled)
6831 {
6832 halStatus = sme_DisablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
6833
6834 if(eHAL_STATUS_SUCCESS != halStatus)
6835 {
6836 status = VOS_STATUS_E_FAILURE;
Arif Hussain6d2a3322013-11-17 19:50:10 -08006837 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Fail to Disable Power Save", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006838 VOS_ASSERT(0);
6839 return status;
6840 }
6841 }
6842
6843 if(pHddCtx->cfg_ini->fIsAutoBmpsTimerEnabled)
6844 {
6845 halStatus = sme_StopAutoBmpsTimer(pHddCtx->hHal);
6846
6847 if(eHAL_STATUS_SUCCESS != halStatus)
6848 {
6849 status = VOS_STATUS_E_FAILURE;
Arif Hussain6d2a3322013-11-17 19:50:10 -08006850 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Fail to Stop Auto Bmps Timer", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006851 VOS_ASSERT(0);
6852 return status;
6853 }
6854 }
6855 }
6856
6857 if((TRUE == disableBmps) ||
6858 (TRUE == disableImps))
6859 {
6860 /* Now, get the chip into Full Power now */
6861 INIT_COMPLETION(pHddCtx->full_pwr_comp_var);
6862 halStatus = sme_RequestFullPower(pHddCtx->hHal, hdd_full_pwr_cbk,
6863 pHddCtx, eSME_FULL_PWR_NEEDED_BY_HDD);
6864
6865 if(halStatus != eHAL_STATUS_SUCCESS)
6866 {
6867 if(halStatus == eHAL_STATUS_PMC_PENDING)
6868 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306869 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07006870 //Block on a completion variable. Can't wait forever though
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306871 ret = wait_for_completion_interruptible_timeout(
6872 &pHddCtx->full_pwr_comp_var,
6873 msecs_to_jiffies(1000));
6874 if (ret <= 0)
6875 {
6876 hddLog(VOS_TRACE_LEVEL_ERROR,
6877 "%s: wait on full_pwr_comp_var failed %ld",
6878 __func__, ret);
6879 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006880 }
6881 else
6882 {
6883 status = VOS_STATUS_E_FAILURE;
Arif Hussain6d2a3322013-11-17 19:50:10 -08006884 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Request for Full Power failed", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006885 VOS_ASSERT(0);
6886 return status;
6887 }
6888 }
6889
6890 status = VOS_STATUS_SUCCESS;
6891 }
6892
6893 break;
6894 }
6895 return status;
6896}
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +05306897
6898void hdd_monPostMsgCb(tANI_U32 *magic, struct completion *cmpVar)
6899{
6900 if (magic == NULL || cmpVar == NULL) {
6901 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6902 FL("invalid arguments %p %p"), magic, cmpVar);
6903 return;
6904 }
6905 if (*magic != MON_MODE_MSG_MAGIC) {
6906 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6907 FL("maic: %x"), *magic);
6908 return;
6909 }
6910
6911 complete(cmpVar);
6912 return;
6913}
6914
Katya Nigame7b69a82015-04-28 15:24:06 +05306915void hdd_init_mon_mode (hdd_adapter_t *pAdapter)
6916 {
6917 hdd_mon_ctx_t *pMonCtx = NULL;
6918 pMonCtx = WLAN_HDD_GET_MONITOR_CTX_PTR(pAdapter);
6919
6920 pMonCtx->state = 0;
6921 pMonCtx->ChannelNo = 1;
6922 pMonCtx->ChannelBW = 20;
Katya Nigamd7d3a1f2015-06-11 14:04:24 +05306923 pMonCtx->crcCheckEnabled = 1;
6924 pMonCtx->typeSubtypeBitmap = 0xFFFF00000000;
6925 pMonCtx->is80211to803ConReq = 1;
Katya Nigame7b69a82015-04-28 15:24:06 +05306926 pMonCtx->numOfMacFilters = 0;
6927 }
6928
Jeff Johnson295189b2012-06-20 16:38:30 -07006929
6930hdd_adapter_t* hdd_open_adapter( hdd_context_t *pHddCtx, tANI_U8 session_type,
Jeff Johnsoneed415b2013-01-18 16:11:20 -08006931 const char *iface_name, tSirMacAddr macAddr,
Jeff Johnson295189b2012-06-20 16:38:30 -07006932 tANI_U8 rtnl_held )
6933{
6934 hdd_adapter_t *pAdapter = NULL;
6935 hdd_adapter_list_node_t *pHddAdapterNode = NULL;
6936 VOS_STATUS status = VOS_STATUS_E_FAILURE;
6937 VOS_STATUS exitbmpsStatus;
6938
Arif Hussain6d2a3322013-11-17 19:50:10 -08006939 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s iface =%s type = %d",__func__,iface_name,session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07006940
Nirav Shah436658f2014-02-28 17:05:45 +05306941 if(macAddr == NULL)
6942 {
6943 /* Not received valid macAddr */
6944 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6945 "%s:Unable to add virtual intf: Not able to get"
6946 "valid mac address",__func__);
6947 return NULL;
6948 }
6949
Jeff Johnson295189b2012-06-20 16:38:30 -07006950 //Disable BMPS incase of Concurrency
6951 exitbmpsStatus = hdd_disable_bmps_imps(pHddCtx, session_type);
6952
6953 if(VOS_STATUS_E_FAILURE == exitbmpsStatus)
6954 {
6955 //Fail to Exit BMPS
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306956 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Fail to Exit BMPS", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006957 VOS_ASSERT(0);
6958 return NULL;
6959 }
6960
6961 switch(session_type)
6962 {
6963 case WLAN_HDD_INFRA_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -07006964 case WLAN_HDD_P2P_CLIENT:
Jeff Johnsone7245742012-09-05 17:12:55 -07006965 case WLAN_HDD_P2P_DEVICE:
Jeff Johnson295189b2012-06-20 16:38:30 -07006966 {
6967 pAdapter = hdd_alloc_station_adapter( pHddCtx, macAddr, iface_name );
6968
6969 if( NULL == pAdapter )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306970 {
6971 hddLog(VOS_TRACE_LEVEL_FATAL,
6972 FL("failed to allocate adapter for session %d"), session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07006973 return NULL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306974 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006975
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306976#ifdef FEATURE_WLAN_TDLS
6977 /* A Mutex Lock is introduced while changing/initializing the mode to
6978 * protect the concurrent access for the Adapters by TDLS module.
6979 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05306980 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306981#endif
6982
Jeff Johnsone7245742012-09-05 17:12:55 -07006983 pAdapter->wdev.iftype = (session_type == WLAN_HDD_P2P_CLIENT) ?
6984 NL80211_IFTYPE_P2P_CLIENT:
6985 NL80211_IFTYPE_STATION;
Jeff Johnson295189b2012-06-20 16:38:30 -07006986
Jeff Johnson295189b2012-06-20 16:38:30 -07006987 pAdapter->device_mode = session_type;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306988#ifdef FEATURE_WLAN_TDLS
6989 mutex_unlock(&pHddCtx->tdls_lock);
6990#endif
Sunil Dutt66485cb2013-12-19 19:05:03 +05306991
Mahesh A Saptasagar67ab9222015-10-21 15:38:41 +05306992 hdd_initialize_adapter_common(pAdapter);
Sunil Dutt66485cb2013-12-19 19:05:03 +05306993 status = hdd_init_station_mode( pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -07006994 if( VOS_STATUS_SUCCESS != status )
6995 goto err_free_netdev;
6996
6997 status = hdd_register_interface( pAdapter, rtnl_held );
6998 if( VOS_STATUS_SUCCESS != status )
6999 {
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05307000#ifdef FEATURE_WLAN_TDLS
7001 mutex_lock(&pHddCtx->tdls_lock);
7002#endif
c_hpothu002231a2015-02-05 14:58:51 +05307003 hdd_deinit_adapter(pHddCtx, pAdapter, rtnl_held);
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05307004#ifdef FEATURE_WLAN_TDLS
7005 mutex_unlock(&pHddCtx->tdls_lock);
7006#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007007 goto err_free_netdev;
7008 }
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05307009
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +05307010 // Workqueue which gets scheduled in IPv4 notification callback.
Anand N Sunkaddc63c792015-06-03 14:33:24 +05307011 vos_init_work(&pAdapter->ipv4NotifierWorkQueue, hdd_ipv4_notifier_work_queue);
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +05307012
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05307013#ifdef WLAN_NS_OFFLOAD
7014 // Workqueue which gets scheduled in IPv6 notification callback.
Anand N Sunkaddc63c792015-06-03 14:33:24 +05307015 vos_init_work(&pAdapter->ipv6NotifierWorkQueue, hdd_ipv6_notifier_work_queue);
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05307016#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007017 //Stop the Interface TX queue.
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +05307018 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Jeff Johnson295189b2012-06-20 16:38:30 -07007019 netif_tx_disable(pAdapter->dev);
7020 //netif_tx_disable(pWlanDev);
7021 netif_carrier_off(pAdapter->dev);
7022
Ganesh Kondabattinibabfb492014-12-17 20:25:29 +05307023 if (WLAN_HDD_P2P_CLIENT == session_type ||
7024 WLAN_HDD_P2P_DEVICE == session_type)
7025 {
7026 /* Initialize the work queue to defer the
7027 * back to back RoC request */
Anand N Sunkaddc63c792015-06-03 14:33:24 +05307028 vos_init_delayed_work(&pAdapter->roc_work,
Ganesh Kondabattinibabfb492014-12-17 20:25:29 +05307029 hdd_p2p_roc_work_queue);
7030 }
7031
Jeff Johnson295189b2012-06-20 16:38:30 -07007032 break;
7033 }
7034
Jeff Johnson295189b2012-06-20 16:38:30 -07007035 case WLAN_HDD_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07007036 case WLAN_HDD_SOFTAP:
7037 {
7038 pAdapter = hdd_wlan_create_ap_dev( pHddCtx, macAddr, (tANI_U8 *)iface_name );
7039 if( NULL == pAdapter )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307040 {
7041 hddLog(VOS_TRACE_LEVEL_FATAL,
7042 FL("failed to allocate adapter for session %d"), session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07007043 return NULL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307044 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007045
Jeff Johnson295189b2012-06-20 16:38:30 -07007046 pAdapter->wdev.iftype = (session_type == WLAN_HDD_SOFTAP) ?
7047 NL80211_IFTYPE_AP:
7048 NL80211_IFTYPE_P2P_GO;
Jeff Johnson295189b2012-06-20 16:38:30 -07007049 pAdapter->device_mode = session_type;
7050
Mahesh A Saptasagar67ab9222015-10-21 15:38:41 +05307051 hdd_initialize_adapter_common(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07007052 status = hdd_init_ap_mode(pAdapter);
7053 if( VOS_STATUS_SUCCESS != status )
7054 goto err_free_netdev;
7055
Nirav Shah7e3c8132015-06-22 23:51:42 +05307056 status = hdd_sta_id_hash_attach(pAdapter);
7057 if (VOS_STATUS_SUCCESS != status)
7058 {
7059 hddLog(VOS_TRACE_LEVEL_FATAL,
7060 FL("failed to attach hash for session %d"), session_type);
7061 hdd_deinit_adapter(pHddCtx, pAdapter, rtnl_held);
7062 goto err_free_netdev;
7063 }
7064
Jeff Johnson295189b2012-06-20 16:38:30 -07007065 status = hdd_register_hostapd( pAdapter, rtnl_held );
7066 if( VOS_STATUS_SUCCESS != status )
7067 {
c_hpothu002231a2015-02-05 14:58:51 +05307068 hdd_deinit_adapter(pHddCtx, pAdapter, rtnl_held);
Jeff Johnson295189b2012-06-20 16:38:30 -07007069 goto err_free_netdev;
7070 }
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +05307071 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Jeff Johnson295189b2012-06-20 16:38:30 -07007072 netif_tx_disable(pAdapter->dev);
7073 netif_carrier_off(pAdapter->dev);
7074
7075 hdd_set_conparam( 1 );
Ganesh Kondabattinibabfb492014-12-17 20:25:29 +05307076
7077 if (WLAN_HDD_P2P_GO == session_type)
7078 {
7079 /* Initialize the work queue to
7080 * defer the back to back RoC request */
7081 INIT_DELAYED_WORK(&pAdapter->roc_work,
7082 hdd_p2p_roc_work_queue);
7083 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007084 break;
7085 }
7086 case WLAN_HDD_MONITOR:
7087 {
Jeff Johnson295189b2012-06-20 16:38:30 -07007088 pAdapter = hdd_alloc_station_adapter( pHddCtx, macAddr, iface_name );
7089 if( NULL == pAdapter )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307090 {
7091 hddLog(VOS_TRACE_LEVEL_FATAL,
7092 FL("failed to allocate adapter for session %d"), session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07007093 return NULL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307094 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007095
Katya Nigame7b69a82015-04-28 15:24:06 +05307096 // Register wireless extensions
7097 if( VOS_STATUS_SUCCESS != (status = hdd_register_wext(pAdapter->dev)))
7098 {
7099 hddLog(VOS_TRACE_LEVEL_FATAL,
7100 "hdd_register_wext() failed with status code %08d [x%08x]",
7101 status, status );
7102 status = VOS_STATUS_E_FAILURE;
7103 }
7104
Jeff Johnson295189b2012-06-20 16:38:30 -07007105 pAdapter->wdev.iftype = NL80211_IFTYPE_MONITOR;
7106 pAdapter->device_mode = session_type;
Jeff Johnson295189b2012-06-20 16:38:30 -07007107#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29)
7108 pAdapter->dev->netdev_ops = &wlan_mon_drv_ops;
7109#else
7110 pAdapter->dev->open = hdd_mon_open;
7111 pAdapter->dev->hard_start_xmit = hdd_mon_hard_start_xmit;
Katya Nigame7b69a82015-04-28 15:24:06 +05307112 pAdapter->dev->stop = hdd_mon_stop;
7113 pAdapter->dev->do_ioctl = hdd_mon_ioctl;
Jeff Johnson295189b2012-06-20 16:38:30 -07007114#endif
Katya Nigame7b69a82015-04-28 15:24:06 +05307115 status = hdd_register_interface( pAdapter, rtnl_held );
7116 hdd_init_mon_mode( pAdapter );
Mahesh A Saptasagar67ab9222015-10-21 15:38:41 +05307117 hdd_initialize_adapter_common(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07007118 hdd_init_tx_rx( pAdapter );
7119 set_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
Katya Nigame7b69a82015-04-28 15:24:06 +05307120 //Stop the Interface TX queue.
7121 netif_tx_disable(pAdapter->dev);
7122 netif_carrier_off(pAdapter->dev);
Jeff Johnson295189b2012-06-20 16:38:30 -07007123 }
7124 break;
Jeff Johnson295189b2012-06-20 16:38:30 -07007125 case WLAN_HDD_FTM:
7126 {
7127 pAdapter = hdd_alloc_station_adapter( pHddCtx, macAddr, iface_name );
7128
7129 if( NULL == pAdapter )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307130 {
7131 hddLog(VOS_TRACE_LEVEL_FATAL,
7132 FL("failed to allocate adapter for session %d"), session_type);
7133 return NULL;
7134 }
7135
Jeff Johnson295189b2012-06-20 16:38:30 -07007136 /* Assign NL80211_IFTYPE_STATION as interface type to resolve Kernel Warning
7137 * message while loading driver in FTM mode. */
7138 pAdapter->wdev.iftype = NL80211_IFTYPE_STATION;
7139 pAdapter->device_mode = session_type;
7140 status = hdd_register_interface( pAdapter, rtnl_held );
Madan Mohan Koyyalamudif89ac9f2013-09-19 16:58:12 +05307141
Mahesh A Saptasagar67ab9222015-10-21 15:38:41 +05307142 hdd_initialize_adapter_common(pAdapter);
Madan Mohan Koyyalamudif89ac9f2013-09-19 16:58:12 +05307143 hdd_init_tx_rx( pAdapter );
7144
7145 //Stop the Interface TX queue.
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +05307146 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Madan Mohan Koyyalamudif89ac9f2013-09-19 16:58:12 +05307147 netif_tx_disable(pAdapter->dev);
7148 netif_carrier_off(pAdapter->dev);
Jeff Johnson295189b2012-06-20 16:38:30 -07007149 }
7150 break;
Jeff Johnson295189b2012-06-20 16:38:30 -07007151 default:
7152 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307153 hddLog(VOS_TRACE_LEVEL_FATAL,"%s Invalid session type %d",
7154 __func__, session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07007155 VOS_ASSERT(0);
7156 return NULL;
7157 }
7158 }
7159
Jeff Johnson295189b2012-06-20 16:38:30 -07007160 if( VOS_STATUS_SUCCESS == status )
7161 {
Mahesh A Saptasagar67ab9222015-10-21 15:38:41 +05307162 //Add it to the hdd's session list.
Jeff Johnson295189b2012-06-20 16:38:30 -07007163 pHddAdapterNode = vos_mem_malloc( sizeof( hdd_adapter_list_node_t ) );
7164 if( NULL == pHddAdapterNode )
7165 {
7166 status = VOS_STATUS_E_NOMEM;
7167 }
7168 else
7169 {
7170 pHddAdapterNode->pAdapter = pAdapter;
7171 status = hdd_add_adapter_back ( pHddCtx,
7172 pHddAdapterNode );
7173 }
7174 }
7175
7176 if( VOS_STATUS_SUCCESS != status )
7177 {
7178 if( NULL != pAdapter )
7179 {
7180 hdd_cleanup_adapter( pHddCtx, pAdapter, rtnl_held );
7181 pAdapter = NULL;
7182 }
7183 if( NULL != pHddAdapterNode )
7184 {
7185 vos_mem_free( pHddAdapterNode );
7186 }
7187
7188 goto resume_bmps;
7189 }
7190
7191 if(VOS_STATUS_SUCCESS == status)
7192 {
7193 wlan_hdd_set_concurrency_mode(pHddCtx, session_type);
7194
Madan Mohan Koyyalamudi96dd30d2012-10-05 17:24:51 -07007195 //Initialize the WoWL service
7196 if(!hdd_init_wowl(pAdapter))
7197 {
7198 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hdd_init_wowl failed",__func__);
7199 goto err_free_netdev;
7200 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007201 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007202 return pAdapter;
7203
7204err_free_netdev:
7205 free_netdev(pAdapter->dev);
7206 wlan_hdd_release_intf_addr( pHddCtx,
7207 pAdapter->macAddressCurrent.bytes );
7208
7209resume_bmps:
7210 //If bmps disabled enable it
7211 if(VOS_STATUS_SUCCESS == exitbmpsStatus)
7212 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05307213 if (pHddCtx->hdd_wlan_suspended)
7214 {
7215 hdd_set_pwrparams(pHddCtx);
7216 }
7217 hdd_enable_bmps_imps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07007218 }
7219 return NULL;
7220}
7221
7222VOS_STATUS hdd_close_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter,
7223 tANI_U8 rtnl_held )
7224{
7225 hdd_adapter_list_node_t *pAdapterNode, *pCurrent, *pNext;
7226 VOS_STATUS status;
7227
7228 status = hdd_get_front_adapter ( pHddCtx, &pCurrent );
7229 if( VOS_STATUS_SUCCESS != status )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307230 {
7231 hddLog(VOS_TRACE_LEVEL_WARN,"%s: adapter list empty %d",
7232 __func__, status);
Jeff Johnson295189b2012-06-20 16:38:30 -07007233 return status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307234 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007235
7236 while ( pCurrent->pAdapter != pAdapter )
7237 {
7238 status = hdd_get_next_adapter ( pHddCtx, pCurrent, &pNext );
7239 if( VOS_STATUS_SUCCESS != status )
7240 break;
7241
7242 pCurrent = pNext;
7243 }
7244 pAdapterNode = pCurrent;
7245 if( VOS_STATUS_SUCCESS == status )
7246 {
7247 wlan_hdd_clear_concurrency_mode(pHddCtx, pAdapter->device_mode);
7248 hdd_cleanup_adapter( pHddCtx, pAdapterNode->pAdapter, rtnl_held );
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05307249
7250#ifdef FEATURE_WLAN_TDLS
7251
7252 /* A Mutex Lock is introduced while changing/initializing the mode to
7253 * protect the concurrent access for the Adapters by TDLS module.
7254 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05307255 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05307256#endif
7257
Jeff Johnson295189b2012-06-20 16:38:30 -07007258 hdd_remove_adapter( pHddCtx, pAdapterNode );
7259 vos_mem_free( pAdapterNode );
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08007260 pAdapterNode = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07007261
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05307262#ifdef FEATURE_WLAN_TDLS
7263 mutex_unlock(&pHddCtx->tdls_lock);
7264#endif
7265
Jeff Johnson295189b2012-06-20 16:38:30 -07007266
7267 /* If there is a single session of STA/P2P client, re-enable BMPS */
Agarwal Ashish51325b52014-06-16 16:50:49 +05307268 if ((!vos_concurrent_open_sessions_running()) &&
7269 ((pHddCtx->no_of_open_sessions[VOS_STA_MODE] >= 1) ||
7270 (pHddCtx->no_of_open_sessions[VOS_P2P_CLIENT_MODE] >= 1)))
Jeff Johnson295189b2012-06-20 16:38:30 -07007271 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05307272 if (pHddCtx->hdd_wlan_suspended)
7273 {
7274 hdd_set_pwrparams(pHddCtx);
7275 }
7276 hdd_enable_bmps_imps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07007277 }
7278
7279 return VOS_STATUS_SUCCESS;
7280 }
7281
7282 return VOS_STATUS_E_FAILURE;
7283}
7284
7285VOS_STATUS hdd_close_all_adapters( hdd_context_t *pHddCtx )
7286{
7287 hdd_adapter_list_node_t *pHddAdapterNode;
7288 VOS_STATUS status;
7289
7290 ENTER();
7291
7292 do
7293 {
7294 status = hdd_remove_front_adapter( pHddCtx, &pHddAdapterNode );
7295 if( pHddAdapterNode && VOS_STATUS_SUCCESS == status )
7296 {
7297 hdd_cleanup_adapter( pHddCtx, pHddAdapterNode->pAdapter, FALSE );
7298 vos_mem_free( pHddAdapterNode );
7299 }
7300 }while( NULL != pHddAdapterNode && VOS_STATUS_E_EMPTY != status );
7301
7302 EXIT();
7303
7304 return VOS_STATUS_SUCCESS;
7305}
7306
7307void wlan_hdd_reset_prob_rspies(hdd_adapter_t* pHostapdAdapter)
7308{
7309 v_U8_t addIE[1] = {0};
7310
7311 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
7312 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,(tANI_U8*)addIE, 0, NULL,
7313 eANI_BOOLEAN_FALSE) )
7314 {
7315 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007316 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07007317 }
7318
7319 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
7320 WNI_CFG_PROBE_RSP_ADDNIE_DATA2, (tANI_U8*)addIE, 0, NULL,
7321 eANI_BOOLEAN_FALSE) )
7322 {
7323 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007324 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07007325 }
7326
7327 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
7328 WNI_CFG_PROBE_RSP_ADDNIE_DATA3, (tANI_U8*)addIE, 0, NULL,
7329 eANI_BOOLEAN_FALSE) )
7330 {
7331 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007332 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07007333 }
7334}
7335
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05307336VOS_STATUS hdd_stop_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter,
7337 const v_BOOL_t bCloseSession )
Jeff Johnson295189b2012-06-20 16:38:30 -07007338{
7339 eHalStatus halStatus = eHAL_STATUS_SUCCESS;
7340 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Kaushik, Sushant4975a572014-10-21 16:07:48 +05307341 hdd_scaninfo_t *pScanInfo = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07007342 union iwreq_data wrqu;
Kaushik, Sushant7005e372014-04-08 11:36:54 +05307343 v_U8_t retry = 0;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307344 long ret;
Nirav Shah7e3c8132015-06-22 23:51:42 +05307345 VOS_STATUS status;
Jeff Johnson295189b2012-06-20 16:38:30 -07007346
Anand N Sunkad26d71b92014-12-24 18:08:22 +05307347 if (pHddCtx->isLogpInProgress) {
7348 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
7349 "%s:LOGP in Progress. Ignore!!!",__func__);
7350 return VOS_STATUS_E_FAILURE;
7351 }
7352
Jeff Johnson295189b2012-06-20 16:38:30 -07007353 ENTER();
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +05307354
Bhargav Shah784e6a52015-07-22 16:52:35 +05307355 if ( VOS_TRUE == bCloseSession )
7356 {
7357 status = hdd_sta_id_hash_detach(pAdapter);
7358 if (status != VOS_STATUS_SUCCESS)
7359 hddLog(VOS_TRACE_LEVEL_ERROR,
7360 FL("sta id hash detach failed"));
7361 }
Nirav Shah7e3c8132015-06-22 23:51:42 +05307362
Kaushik, Sushant4975a572014-10-21 16:07:48 +05307363 pScanInfo = &pHddCtx->scan_info;
Jeff Johnson295189b2012-06-20 16:38:30 -07007364 switch(pAdapter->device_mode)
7365 {
7366 case WLAN_HDD_INFRA_STATION:
7367 case WLAN_HDD_P2P_CLIENT:
Abhishek Singh3ac179b2015-09-21 10:01:34 +05307368 case WLAN_HDD_IBSS:
Jeff Johnsone7245742012-09-05 17:12:55 -07007369 case WLAN_HDD_P2P_DEVICE:
Vinay Krishna Erannab09d3e72014-03-26 21:23:55 +05307370 {
7371 hdd_station_ctx_t *pstation = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Mahesh A Saptasagare4d05d42015-07-02 16:17:20 +05307372#ifdef FEATURE_WLAN_TDLS
7373 mutex_lock(&pHddCtx->tdls_lock);
7374 wlan_hdd_tdls_exit(pAdapter, TRUE);
7375 mutex_unlock(&pHddCtx->tdls_lock);
7376#endif
Vinay Krishna Erannab09d3e72014-03-26 21:23:55 +05307377 if( hdd_connIsConnected(pstation) ||
7378 (pstation->conn_info.connState == eConnectionState_Connecting) )
Jeff Johnson295189b2012-06-20 16:38:30 -07007379 {
7380 if (pWextState->roamProfile.BSSType == eCSR_BSS_TYPE_START_IBSS)
7381 halStatus = sme_RoamDisconnect(pHddCtx->hHal,
7382 pAdapter->sessionId,
7383 eCSR_DISCONNECT_REASON_IBSS_LEAVE);
7384 else
7385 halStatus = sme_RoamDisconnect(pHddCtx->hHal,
7386 pAdapter->sessionId,
7387 eCSR_DISCONNECT_REASON_UNSPECIFIED);
7388 //success implies disconnect command got queued up successfully
7389 if(halStatus == eHAL_STATUS_SUCCESS)
7390 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307391 ret = wait_for_completion_interruptible_timeout(
7392 &pAdapter->disconnect_comp_var,
7393 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
7394 if (ret <= 0)
7395 {
7396 hddLog(VOS_TRACE_LEVEL_ERROR,
7397 "%s: wait on disconnect_comp_var failed %ld",
7398 __func__, ret);
7399 }
7400 }
7401 else
7402 {
7403 hddLog(LOGE, "%s: failed to post disconnect event to SME",
7404 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007405 }
7406 memset(&wrqu, '\0', sizeof(wrqu));
7407 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
7408 memset(wrqu.ap_addr.sa_data,'\0',ETH_ALEN);
7409 wireless_send_event(pAdapter->dev, SIOCGIWAP, &wrqu, NULL);
7410 }
Vinay Krishna Erannab09d3e72014-03-26 21:23:55 +05307411 else if(pstation->conn_info.connState ==
7412 eConnectionState_Disconnecting)
7413 {
7414 ret = wait_for_completion_interruptible_timeout(
7415 &pAdapter->disconnect_comp_var,
7416 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
7417 if (ret <= 0)
7418 {
7419 hddLog(VOS_TRACE_LEVEL_ERROR,
7420 FL("wait on disconnect_comp_var failed %ld"), ret);
7421 }
7422 }
Kaushik, Sushant4975a572014-10-21 16:07:48 +05307423 else if(pScanInfo != NULL && pHddCtx->scan_info.mScanPending)
Jeff Johnson295189b2012-06-20 16:38:30 -07007424 {
Kaushik, Sushant4975a572014-10-21 16:07:48 +05307425 hdd_abort_mac_scan(pHddCtx, pScanInfo->sessionId,
Srinivas, Dasari138af4f2014-02-07 11:13:45 +05307426 eCSR_SCAN_ABORT_DEFAULT);
Jeff Johnson295189b2012-06-20 16:38:30 -07007427 }
Abhishek Singh3ac179b2015-09-21 10:01:34 +05307428 if ((pAdapter->device_mode != WLAN_HDD_INFRA_STATION) &&
7429 (pAdapter->device_mode != WLAN_HDD_IBSS))
Kaushik, Sushant7005e372014-04-08 11:36:54 +05307430 {
7431 while (pAdapter->is_roc_inprogress)
7432 {
7433 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7434 "%s: ROC in progress for session %d!!!",
7435 __func__, pAdapter->sessionId);
7436 // waiting for ROC to expire
7437 msleep(500);
7438 /* In GO present case , if retry exceeds 3,
7439 it means something went wrong. */
7440 if ( retry++ > MAX_WAIT_FOR_ROC_COMPLETION )
7441 {
7442 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7443 "%s: ROC completion is not received.!!!", __func__);
Deepthi Gowri70498252015-01-20 15:56:45 +05307444 if (eHAL_STATUS_SUCCESS !=
7445 sme_CancelRemainOnChannel( WLAN_HDD_GET_HAL_CTX( pAdapter),
7446 pAdapter->sessionId ))
7447 {
7448 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7449 FL("Failed to Cancel Remain on Channel"));
7450 }
Kaushik, Sushant7005e372014-04-08 11:36:54 +05307451 wait_for_completion_interruptible_timeout(
7452 &pAdapter->cancel_rem_on_chan_var,
7453 msecs_to_jiffies(WAIT_CANCEL_REM_CHAN));
7454 break;
7455 }
7456 }
Anand N Sunkaddc63c792015-06-03 14:33:24 +05307457 vos_flush_delayed_work(&pAdapter->roc_work);
Kaushik, Sushant7005e372014-04-08 11:36:54 +05307458 }
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05307459#ifdef WLAN_NS_OFFLOAD
Anand N Sunkaddc63c792015-06-03 14:33:24 +05307460 vos_flush_work(&pAdapter->ipv6NotifierWorkQueue);
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05307461#endif
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +05307462
Anand N Sunkaddc63c792015-06-03 14:33:24 +05307463 vos_flush_work(&pAdapter->ipv4NotifierWorkQueue);
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +05307464
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05307465 /* It is possible that the caller of this function does not
7466 * wish to close the session
7467 */
7468 if (VOS_TRUE == bCloseSession &&
7469 test_bit(SME_SESSION_OPENED, &pAdapter->event_flags))
Jeff Johnson295189b2012-06-20 16:38:30 -07007470 {
7471 INIT_COMPLETION(pAdapter->session_close_comp_var);
7472 if (eHAL_STATUS_SUCCESS ==
mukul sharmabab477d2015-06-11 17:14:55 +05307473 sme_CloseSession(pHddCtx->hHal, pAdapter->sessionId, VOS_FALSE,
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05307474 hdd_smeCloseSessionCallback, pAdapter))
Jeff Johnson295189b2012-06-20 16:38:30 -07007475 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307476 unsigned long ret;
7477
Jeff Johnson295189b2012-06-20 16:38:30 -07007478 //Block on a completion variable. Can't wait forever though.
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307479 ret = wait_for_completion_timeout(
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05307480 &pAdapter->session_close_comp_var,
7481 msecs_to_jiffies(WLAN_WAIT_TIME_SESSIONOPENCLOSE));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307482 if ( 0 >= ret)
7483 {
7484 hddLog(LOGE, "%s: failure waiting for session_close_comp_var %ld",
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05307485 __func__, ret);
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307486 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007487 }
7488 }
Vinay Krishna Erannab09d3e72014-03-26 21:23:55 +05307489 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007490 break;
7491
7492 case WLAN_HDD_SOFTAP:
7493 case WLAN_HDD_P2P_GO:
7494 //Any softap specific cleanup here...
Kaushik, Sushant7005e372014-04-08 11:36:54 +05307495 if (pAdapter->device_mode == WLAN_HDD_P2P_GO) {
7496 while (pAdapter->is_roc_inprogress) {
7497 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7498 "%s: ROC in progress for session %d!!!",
7499 __func__, pAdapter->sessionId);
7500 msleep(500);
7501 if ( retry++ > MAX_WAIT_FOR_ROC_COMPLETION ) {
7502 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7503 "%s: ROC completion is not received.!!!", __func__);
7504 WLANSAP_CancelRemainOnChannel(
7505 (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
7506 wait_for_completion_interruptible_timeout(
7507 &pAdapter->cancel_rem_on_chan_var,
7508 msecs_to_jiffies(WAIT_CANCEL_REM_CHAN));
7509 break;
7510 }
7511 }
Ganesh Kondabattinibabfb492014-12-17 20:25:29 +05307512
Anand N Sunkaddc63c792015-06-03 14:33:24 +05307513 vos_flush_delayed_work(&pAdapter->roc_work);
Kaushik, Sushant7005e372014-04-08 11:36:54 +05307514 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007515 mutex_lock(&pHddCtx->sap_lock);
7516 if (test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
7517 {
7518 VOS_STATUS status;
7519 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7520
7521 //Stop Bss.
7522 status = WLANSAP_StopBss(pHddCtx->pvosContext);
7523 if (VOS_IS_STATUS_SUCCESS(status))
7524 {
7525 hdd_hostapd_state_t *pHostapdState =
7526 WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
7527
7528 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
7529
7530 if (!VOS_IS_STATUS_SUCCESS(status))
7531 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307532 hddLog(LOGE, "%s: failure waiting for WLANSAP_StopBss %d",
7533 __func__, status);
Jeff Johnson295189b2012-06-20 16:38:30 -07007534 }
7535 }
7536 else
7537 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007538 hddLog(LOGE, "%s: failure in WLANSAP_StopBss", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007539 }
7540 clear_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags);
Agarwal Ashish51325b52014-06-16 16:50:49 +05307541 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07007542
7543 if (eHAL_STATUS_FAILURE ==
7544 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG,
7545 0, NULL, eANI_BOOLEAN_FALSE))
7546 {
7547 hddLog(LOGE,
7548 "%s: Failed to set WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007549 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007550 }
7551
7552 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt((WLAN_HDD_GET_CTX(pAdapter))->hHal,
7553 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
7554 eANI_BOOLEAN_FALSE) )
7555 {
7556 hddLog(LOGE,
7557 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
7558 }
7559
7560 // Reset WNI_CFG_PROBE_RSP Flags
7561 wlan_hdd_reset_prob_rspies(pAdapter);
7562 kfree(pAdapter->sessionCtx.ap.beacon);
7563 pAdapter->sessionCtx.ap.beacon = NULL;
7564 }
7565 mutex_unlock(&pHddCtx->sap_lock);
7566 break;
Sameer Thalappilbee426e2013-10-30 10:30:30 -07007567
Jeff Johnson295189b2012-06-20 16:38:30 -07007568 case WLAN_HDD_MONITOR:
7569 break;
Sameer Thalappilbee426e2013-10-30 10:30:30 -07007570
Jeff Johnson295189b2012-06-20 16:38:30 -07007571 default:
7572 break;
7573 }
7574
7575 EXIT();
7576 return VOS_STATUS_SUCCESS;
7577}
7578
7579VOS_STATUS hdd_stop_all_adapters( hdd_context_t *pHddCtx )
7580{
7581 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7582 VOS_STATUS status;
7583 hdd_adapter_t *pAdapter;
7584
7585 ENTER();
7586
7587 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7588
7589 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7590 {
7591 pAdapter = pAdapterNode->pAdapter;
Jeff Johnson295189b2012-06-20 16:38:30 -07007592
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05307593 hdd_stop_adapter( pHddCtx, pAdapter, VOS_TRUE );
Jeff Johnson295189b2012-06-20 16:38:30 -07007594
7595 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7596 pAdapterNode = pNext;
7597 }
7598
7599 EXIT();
7600
7601 return VOS_STATUS_SUCCESS;
7602}
7603
Rajeev Kumarf999e582014-01-09 17:33:29 -08007604
7605#ifdef FEATURE_WLAN_BATCH_SCAN
7606/**---------------------------------------------------------------------------
7607
7608 \brief hdd_deinit_batch_scan () - This function cleans up batch scan data
7609 structures
7610
7611 \param - pAdapter Pointer to HDD adapter
7612
7613 \return - None
7614
7615 --------------------------------------------------------------------------*/
7616void hdd_deinit_batch_scan(hdd_adapter_t *pAdapter)
7617{
7618 tHddBatchScanRsp *pNode;
7619 tHddBatchScanRsp *pPrev;
7620
Siddharth Bhalb3e9b792014-02-24 15:14:16 +05307621 if (NULL == pAdapter)
Rajeev Kumarf999e582014-01-09 17:33:29 -08007622 {
Siddharth Bhalb3e9b792014-02-24 15:14:16 +05307623 hddLog(VOS_TRACE_LEVEL_ERROR,
7624 "%s: Adapter context is Null", __func__);
7625 return;
7626 }
7627
7628 pNode = pAdapter->pBatchScanRsp;
7629 while (pNode)
7630 {
7631 pPrev = pNode;
7632 pNode = pNode->pNext;
7633 vos_mem_free((v_VOID_t * )pPrev);
Rajeev Kumarf999e582014-01-09 17:33:29 -08007634 }
7635
7636 pAdapter->pBatchScanRsp = NULL;
7637 pAdapter->numScanList = 0;
7638 pAdapter->batchScanState = eHDD_BATCH_SCAN_STATE_STOPPED;
7639 pAdapter->prev_batch_id = 0;
7640
7641 return;
7642}
7643#endif
7644
7645
Jeff Johnson295189b2012-06-20 16:38:30 -07007646VOS_STATUS hdd_reset_all_adapters( hdd_context_t *pHddCtx )
7647{
7648 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7649 VOS_STATUS status;
7650 hdd_adapter_t *pAdapter;
7651
7652 ENTER();
7653
7654 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7655
7656 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7657 {
7658 pAdapter = pAdapterNode->pAdapter;
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +05307659 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Jeff Johnson295189b2012-06-20 16:38:30 -07007660 netif_tx_disable(pAdapter->dev);
7661 netif_carrier_off(pAdapter->dev);
7662
Srinivas Girigowda66c05eb2013-07-14 13:06:01 -07007663 pAdapter->sessionCtx.station.hdd_ReassocScenario = VOS_FALSE;
7664
Jeff Johnson295189b2012-06-20 16:38:30 -07007665 hdd_deinit_tx_rx(pAdapter);
Agarwal Ashish6267caa2014-08-06 19:16:21 +05307666
Katya Nigam1fd24402015-02-16 14:52:19 +05307667 if(pAdapter->device_mode == WLAN_HDD_IBSS )
7668 hdd_ibss_deinit_tx_rx(pAdapter);
7669
Nirav Shah7e3c8132015-06-22 23:51:42 +05307670 status = hdd_sta_id_hash_detach(pAdapter);
7671 if (status != VOS_STATUS_SUCCESS)
7672 hddLog(VOS_TRACE_LEVEL_ERROR,
7673 FL("sta id hash detach failed for session id %d"),
7674 pAdapter->sessionId);
7675
Agarwal Ashish6267caa2014-08-06 19:16:21 +05307676 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
7677
Madan Mohan Koyyalamudi8c6dec82013-09-26 15:56:13 +05307678 if (test_bit(WMM_INIT_DONE, &pAdapter->event_flags))
7679 {
7680 hdd_wmm_adapter_close( pAdapter );
7681 clear_bit(WMM_INIT_DONE, &pAdapter->event_flags);
7682 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007683
Siddharth Bhal2db319d2014-12-03 12:37:18 +05307684 if (test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
7685 {
7686 clear_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags);
7687 }
7688
Rajeev Kumarf999e582014-01-09 17:33:29 -08007689#ifdef FEATURE_WLAN_BATCH_SCAN
7690 if (eHDD_BATCH_SCAN_STATE_STARTED == pAdapter->batchScanState)
7691 {
7692 hdd_deinit_batch_scan(pAdapter);
7693 }
7694#endif
7695
Mahesh A Saptasagarf5b8eff2015-01-31 01:07:07 +05307696#ifdef FEATURE_WLAN_TDLS
7697 mutex_lock(&pHddCtx->tdls_lock);
Pradeep Reddy POTTETI2d4d5c42015-03-03 14:34:19 +05307698 wlan_hdd_tdls_exit(pAdapter, TRUE);
Mahesh A Saptasagarf5b8eff2015-01-31 01:07:07 +05307699 mutex_unlock(&pHddCtx->tdls_lock);
7700#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007701 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7702 pAdapterNode = pNext;
7703 }
7704
7705 EXIT();
7706
7707 return VOS_STATUS_SUCCESS;
7708}
7709
7710VOS_STATUS hdd_start_all_adapters( hdd_context_t *pHddCtx )
7711{
7712 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7713 VOS_STATUS status;
7714 hdd_adapter_t *pAdapter;
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05307715 eConnectionState connState;
Jeff Johnson295189b2012-06-20 16:38:30 -07007716
7717 ENTER();
7718
7719 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7720
7721 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7722 {
7723 pAdapter = pAdapterNode->pAdapter;
7724
Kumar Anand82c009f2014-05-29 00:29:42 -07007725 hdd_wmm_init( pAdapter );
7726
Jeff Johnson295189b2012-06-20 16:38:30 -07007727 switch(pAdapter->device_mode)
7728 {
7729 case WLAN_HDD_INFRA_STATION:
7730 case WLAN_HDD_P2P_CLIENT:
Jeff Johnsone7245742012-09-05 17:12:55 -07007731 case WLAN_HDD_P2P_DEVICE:
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05307732
7733 connState = (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState;
7734
Jeff Johnson295189b2012-06-20 16:38:30 -07007735 hdd_init_station_mode(pAdapter);
7736 /* Open the gates for HDD to receive Wext commands */
7737 pAdapter->isLinkUpSvcNeeded = FALSE;
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07007738 pHddCtx->scan_info.mScanPending = FALSE;
7739 pHddCtx->scan_info.waitScanResult = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07007740
7741 //Trigger the initial scan
Mukul Sharmae74e42c2015-08-06 23:55:49 +05307742 if (!pHddCtx->isLogpInProgress)
7743 hdd_wlan_initial_scan(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07007744
7745 //Indicate disconnect event to supplicant if associated previously
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05307746 if (eConnectionState_Associated == connState ||
7747 eConnectionState_IbssConnected == connState )
Jeff Johnson295189b2012-06-20 16:38:30 -07007748 {
7749 union iwreq_data wrqu;
7750 memset(&wrqu, '\0', sizeof(wrqu));
7751 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
7752 memset(wrqu.ap_addr.sa_data,'\0',ETH_ALEN);
7753 wireless_send_event(pAdapter->dev, SIOCGIWAP, &wrqu, NULL);
Srinivas Girigowda66c05eb2013-07-14 13:06:01 -07007754 pAdapter->sessionCtx.station.hdd_ReassocScenario = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07007755
Jeff Johnson295189b2012-06-20 16:38:30 -07007756 /* indicate disconnected event to nl80211 */
7757 cfg80211_disconnected(pAdapter->dev, WLAN_REASON_UNSPECIFIED,
7758 NULL, 0, GFP_KERNEL);
Jeff Johnson295189b2012-06-20 16:38:30 -07007759 }
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05307760 else if (eConnectionState_Connecting == connState)
7761 {
7762 /*
7763 * Indicate connect failure to supplicant if we were in the
7764 * process of connecting
7765 */
7766 cfg80211_connect_result(pAdapter->dev, NULL,
7767 NULL, 0, NULL, 0,
7768 WLAN_STATUS_ASSOC_DENIED_UNSPEC,
7769 GFP_KERNEL);
7770 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007771 break;
7772
7773 case WLAN_HDD_SOFTAP:
7774 /* softAP can handle SSR */
7775 break;
7776
7777 case WLAN_HDD_P2P_GO:
Sameer Thalappiledf0d792013-08-09 14:31:03 -07007778 hddLog(VOS_TRACE_LEVEL_ERROR, "%s [SSR] send stop ap to supplicant",
Jeff Johnson295189b2012-06-20 16:38:30 -07007779 __func__);
Sameer Thalappiledf0d792013-08-09 14:31:03 -07007780 cfg80211_ap_stopped(pAdapter->dev, GFP_KERNEL);
Jeff Johnson295189b2012-06-20 16:38:30 -07007781 break;
7782
7783 case WLAN_HDD_MONITOR:
7784 /* monitor interface start */
7785 break;
7786 default:
7787 break;
7788 }
7789
7790 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7791 pAdapterNode = pNext;
7792 }
7793
7794 EXIT();
7795
7796 return VOS_STATUS_SUCCESS;
7797}
7798
7799VOS_STATUS hdd_reconnect_all_adapters( hdd_context_t *pHddCtx )
7800{
7801 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7802 hdd_adapter_t *pAdapter;
7803 VOS_STATUS status;
7804 v_U32_t roamId;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307805 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07007806
7807 ENTER();
7808
7809 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7810
7811 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7812 {
7813 pAdapter = pAdapterNode->pAdapter;
7814
7815 if( (WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
7816 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
7817 {
7818 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7819 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
7820
Abhishek Singhf4669da2014-05-26 15:07:49 +05307821 hddLog(VOS_TRACE_LEVEL_INFO,
7822 "%s: Set HDD connState to eConnectionState_NotConnected",
7823 __func__);
Ganesh Kondabattini04338412015-09-14 15:39:09 +05307824 spin_lock_bh(&pAdapter->lock_for_active_session);
7825 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState)
7826 {
7827 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
7828 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007829 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
Ganesh Kondabattini04338412015-09-14 15:39:09 +05307830 spin_unlock_bh(&pAdapter->lock_for_active_session);
Jeff Johnson295189b2012-06-20 16:38:30 -07007831 init_completion(&pAdapter->disconnect_comp_var);
7832 sme_RoamDisconnect(pHddCtx->hHal, pAdapter->sessionId,
7833 eCSR_DISCONNECT_REASON_UNSPECIFIED);
7834
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307835 ret = wait_for_completion_interruptible_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -07007836 &pAdapter->disconnect_comp_var,
7837 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307838 if (0 >= ret)
7839 hddLog(LOGE, "%s: failure waiting for disconnect_comp_var %ld",
7840 __func__, ret);
Jeff Johnson295189b2012-06-20 16:38:30 -07007841
7842 pWextState->roamProfile.csrPersona = pAdapter->device_mode;
7843 pHddCtx->isAmpAllowed = VOS_FALSE;
7844 sme_RoamConnect(pHddCtx->hHal,
7845 pAdapter->sessionId, &(pWextState->roamProfile),
7846 &roamId);
7847 }
7848
7849 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7850 pAdapterNode = pNext;
7851 }
7852
7853 EXIT();
7854
7855 return VOS_STATUS_SUCCESS;
7856}
7857
Sudhir Sattayappa Kohalli90e4c752013-03-21 14:25:04 -07007858void hdd_dump_concurrency_info(hdd_context_t *pHddCtx)
7859{
7860 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7861 VOS_STATUS status;
7862 hdd_adapter_t *pAdapter;
7863 hdd_station_ctx_t *pHddStaCtx;
7864 hdd_ap_ctx_t *pHddApCtx;
7865 hdd_hostapd_state_t * pHostapdState;
7866 tCsrBssid staBssid = { 0 }, p2pBssid = { 0 }, apBssid = { 0 };
7867 v_U8_t staChannel = 0, p2pChannel = 0, apChannel = 0;
7868 const char *p2pMode = "DEV";
7869 const char *ccMode = "Standalone";
Sudhir Sattayappa Kohalli90e4c752013-03-21 14:25:04 -07007870
7871 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7872 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7873 {
7874 pAdapter = pAdapterNode->pAdapter;
7875 switch (pAdapter->device_mode) {
7876 case WLAN_HDD_INFRA_STATION:
7877 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7878 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState) {
7879 staChannel = pHddStaCtx->conn_info.operationChannel;
7880 memcpy(staBssid, pHddStaCtx->conn_info.bssId, sizeof(staBssid));
7881 }
7882 break;
7883 case WLAN_HDD_P2P_CLIENT:
7884 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7885 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState) {
7886 p2pChannel = pHddStaCtx->conn_info.operationChannel;
7887 memcpy(p2pBssid, pHddStaCtx->conn_info.bssId, sizeof(p2pBssid));
7888 p2pMode = "CLI";
7889 }
7890 break;
7891 case WLAN_HDD_P2P_GO:
7892 pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
7893 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
7894 if (pHostapdState->bssState == BSS_START && pHostapdState->vosStatus==VOS_STATUS_SUCCESS) {
7895 p2pChannel = pHddApCtx->operatingChannel;
7896 memcpy(p2pBssid, pAdapter->macAddressCurrent.bytes, sizeof(p2pBssid));
7897 }
7898 p2pMode = "GO";
7899 break;
7900 case WLAN_HDD_SOFTAP:
7901 pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
7902 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
7903 if (pHostapdState->bssState == BSS_START && pHostapdState->vosStatus==VOS_STATUS_SUCCESS) {
7904 apChannel = pHddApCtx->operatingChannel;
7905 memcpy(apBssid, pAdapter->macAddressCurrent.bytes, sizeof(apBssid));
7906 }
7907 break;
7908 default:
7909 break;
7910 }
7911 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7912 pAdapterNode = pNext;
7913 }
7914 if (staChannel > 0 && (apChannel > 0 || p2pChannel > 0)) {
7915 ccMode = (p2pChannel==staChannel||apChannel==staChannel) ? "SCC" : "MCC";
7916 }
Sushant Kaushikdc3184b2015-10-09 12:00:21 +05307917 hddLog(VOS_TRACE_LEVEL_ERROR, "wlan(%d) " MAC_ADDRESS_STR " %s",
Sudhir Sattayappa Kohalli90e4c752013-03-21 14:25:04 -07007918 staChannel, MAC_ADDR_ARRAY(staBssid), ccMode);
7919 if (p2pChannel > 0) {
Sushant Kaushikdc3184b2015-10-09 12:00:21 +05307920 hddLog(VOS_TRACE_LEVEL_ERROR, "p2p-%s(%d) " MAC_ADDRESS_STR,
Sudhir Sattayappa Kohalli90e4c752013-03-21 14:25:04 -07007921 p2pMode, p2pChannel, MAC_ADDR_ARRAY(p2pBssid));
7922 }
7923 if (apChannel > 0) {
Sushant Kaushikdc3184b2015-10-09 12:00:21 +05307924 hddLog(VOS_TRACE_LEVEL_ERROR, "AP(%d) " MAC_ADDRESS_STR,
Sudhir Sattayappa Kohalli90e4c752013-03-21 14:25:04 -07007925 apChannel, MAC_ADDR_ARRAY(apBssid));
7926 }
7927
7928 if (p2pChannel > 0 && apChannel > 0) {
7929 hddLog(VOS_TRACE_LEVEL_ERROR, "Error concurrent SAP %d and P2P %d which is not support", apChannel, p2pChannel);
7930 }
7931}
7932
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -07007933bool hdd_is_ssr_required( void)
Jeff Johnson295189b2012-06-20 16:38:30 -07007934{
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -07007935 return (isSsrRequired == HDD_SSR_REQUIRED);
Jeff Johnson295189b2012-06-20 16:38:30 -07007936}
7937
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -07007938/* Once SSR is disabled then it cannot be set. */
7939void hdd_set_ssr_required( e_hdd_ssr_required value)
Jeff Johnson295189b2012-06-20 16:38:30 -07007940{
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -07007941 if (HDD_SSR_DISABLED == isSsrRequired)
7942 return;
7943
Jeff Johnson295189b2012-06-20 16:38:30 -07007944 isSsrRequired = value;
7945}
7946
Hema Aparna Medicharla6b4d4f32015-06-23 04:09:12 +05307947void hdd_set_pre_close( hdd_context_t *pHddCtx)
7948{
7949 sme_PreClose(pHddCtx->hHal);
7950}
7951
Jeff Johnson295189b2012-06-20 16:38:30 -07007952VOS_STATUS hdd_get_front_adapter( hdd_context_t *pHddCtx,
7953 hdd_adapter_list_node_t** ppAdapterNode)
7954{
7955 VOS_STATUS status;
Mukul Sharmaae1266d2015-06-26 15:29:53 +05307956 spin_lock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07007957 status = hdd_list_peek_front ( &pHddCtx->hddAdapters,
7958 (hdd_list_node_t**) ppAdapterNode );
Mukul Sharmaae1266d2015-06-26 15:29:53 +05307959 spin_unlock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07007960 return status;
7961}
7962
7963VOS_STATUS hdd_get_next_adapter( hdd_context_t *pHddCtx,
7964 hdd_adapter_list_node_t* pAdapterNode,
7965 hdd_adapter_list_node_t** pNextAdapterNode)
7966{
7967 VOS_STATUS status;
Mukul Sharmaae1266d2015-06-26 15:29:53 +05307968 spin_lock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07007969 status = hdd_list_peek_next ( &pHddCtx->hddAdapters,
7970 (hdd_list_node_t*) pAdapterNode,
7971 (hdd_list_node_t**)pNextAdapterNode );
7972
Mukul Sharmaae1266d2015-06-26 15:29:53 +05307973 spin_unlock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07007974 return status;
7975}
7976
7977VOS_STATUS hdd_remove_adapter( hdd_context_t *pHddCtx,
7978 hdd_adapter_list_node_t* pAdapterNode)
7979{
7980 VOS_STATUS status;
Mukul Sharmaae1266d2015-06-26 15:29:53 +05307981 spin_lock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07007982 status = hdd_list_remove_node ( &pHddCtx->hddAdapters,
7983 &pAdapterNode->node );
Mukul Sharmaae1266d2015-06-26 15:29:53 +05307984 spin_unlock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07007985 return status;
7986}
7987
7988VOS_STATUS hdd_remove_front_adapter( hdd_context_t *pHddCtx,
7989 hdd_adapter_list_node_t** ppAdapterNode)
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_remove_front( &pHddCtx->hddAdapters,
7994 (hdd_list_node_t**) ppAdapterNode );
Mukul Sharmaae1266d2015-06-26 15:29:53 +05307995 spin_unlock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07007996 return status;
7997}
7998
7999VOS_STATUS hdd_add_adapter_back( hdd_context_t *pHddCtx,
8000 hdd_adapter_list_node_t* pAdapterNode)
8001{
8002 VOS_STATUS status;
Mukul Sharmaae1266d2015-06-26 15:29:53 +05308003 spin_lock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07008004 status = hdd_list_insert_back ( &pHddCtx->hddAdapters,
8005 (hdd_list_node_t*) pAdapterNode );
Mukul Sharmaae1266d2015-06-26 15:29:53 +05308006 spin_unlock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07008007 return status;
8008}
8009
8010VOS_STATUS hdd_add_adapter_front( hdd_context_t *pHddCtx,
8011 hdd_adapter_list_node_t* pAdapterNode)
8012{
8013 VOS_STATUS status;
Mukul Sharmaae1266d2015-06-26 15:29:53 +05308014 spin_lock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07008015 status = hdd_list_insert_front ( &pHddCtx->hddAdapters,
8016 (hdd_list_node_t*) pAdapterNode );
Mukul Sharmaae1266d2015-06-26 15:29:53 +05308017 spin_unlock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07008018 return status;
8019}
8020
8021hdd_adapter_t * hdd_get_adapter_by_macaddr( hdd_context_t *pHddCtx,
8022 tSirMacAddr macAddr )
8023{
8024 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
8025 hdd_adapter_t *pAdapter;
8026 VOS_STATUS status;
8027
8028 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
8029
8030 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
8031 {
8032 pAdapter = pAdapterNode->pAdapter;
8033
8034 if( pAdapter && vos_mem_compare( pAdapter->macAddressCurrent.bytes,
8035 macAddr, sizeof(tSirMacAddr) ) )
8036 {
8037 return pAdapter;
8038 }
8039 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
8040 pAdapterNode = pNext;
8041 }
8042
8043 return NULL;
8044
8045}
8046
8047hdd_adapter_t * hdd_get_adapter_by_name( hdd_context_t *pHddCtx, tANI_U8 *name )
8048{
8049 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
8050 hdd_adapter_t *pAdapter;
8051 VOS_STATUS status;
8052
8053 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
8054
8055 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
8056 {
8057 pAdapter = pAdapterNode->pAdapter;
8058
8059 if( pAdapter && !strncmp( pAdapter->dev->name, (const char *)name,
8060 IFNAMSIZ ) )
8061 {
8062 return pAdapter;
8063 }
8064 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
8065 pAdapterNode = pNext;
8066 }
8067
8068 return NULL;
8069
8070}
8071
Ganesh Kondabattinicbfdc392015-09-11 19:12:59 +05308072hdd_adapter_t *hdd_get_adapter_by_sme_session_id( hdd_context_t *pHddCtx,
8073 tANI_U32 sme_session_id )
8074{
8075 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
8076 hdd_adapter_t *pAdapter;
8077 VOS_STATUS vos_status;
8078
8079
8080 vos_status = hdd_get_front_adapter( pHddCtx, &pAdapterNode);
8081
8082 while ((NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == vos_status))
8083 {
8084 pAdapter = pAdapterNode->pAdapter;
8085
8086 if (pAdapter->sessionId == sme_session_id)
8087 return pAdapter;
8088
8089 vos_status = hdd_get_next_adapter(pHddCtx, pAdapterNode, &pNext);
8090 pAdapterNode = pNext;
8091 }
8092
8093 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8094 "%s: sme_session_id %d does not exist with host",
8095 __func__, sme_session_id);
8096
8097 return NULL;
8098}
8099
Jeff Johnson295189b2012-06-20 16:38:30 -07008100hdd_adapter_t * hdd_get_adapter( hdd_context_t *pHddCtx, device_mode_t mode )
8101{
8102 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
8103 hdd_adapter_t *pAdapter;
8104 VOS_STATUS status;
8105
8106 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
8107
8108 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
8109 {
8110 pAdapter = pAdapterNode->pAdapter;
8111
8112 if( pAdapter && (mode == pAdapter->device_mode) )
8113 {
8114 return pAdapter;
8115 }
8116 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
8117 pAdapterNode = pNext;
8118 }
8119
8120 return NULL;
8121
8122}
8123
8124//Remove this function later
8125hdd_adapter_t * hdd_get_mon_adapter( hdd_context_t *pHddCtx )
8126{
8127 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
8128 hdd_adapter_t *pAdapter;
8129 VOS_STATUS status;
8130
8131 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
8132
8133 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
8134 {
8135 pAdapter = pAdapterNode->pAdapter;
8136
8137 if( pAdapter && WLAN_HDD_MONITOR == pAdapter->device_mode )
8138 {
8139 return pAdapter;
8140 }
8141
8142 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
8143 pAdapterNode = pNext;
8144 }
8145
8146 return NULL;
8147
8148}
8149
Jeff Johnson295189b2012-06-20 16:38:30 -07008150/**---------------------------------------------------------------------------
8151
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05308152 \brief hdd_get_operating_channel() -
Jeff Johnson295189b2012-06-20 16:38:30 -07008153
8154 This API returns the operating channel of the requested device mode
8155
8156 \param - pHddCtx - Pointer to the HDD context.
8157 - mode - Device mode for which operating channel is required
8158 suported modes - WLAN_HDD_INFRA_STATION, WLAN_HDD_P2P_CLIENT
8159 WLAN_HDD_SOFTAP, WLAN_HDD_P2P_GO.
8160 \return - channel number. "0" id the requested device is not found OR it is not connected.
8161 --------------------------------------------------------------------------*/
8162v_U8_t hdd_get_operating_channel( hdd_context_t *pHddCtx, device_mode_t mode )
8163{
8164 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
8165 VOS_STATUS status;
8166 hdd_adapter_t *pAdapter;
8167 v_U8_t operatingChannel = 0;
8168
8169 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
8170
8171 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
8172 {
8173 pAdapter = pAdapterNode->pAdapter;
8174
8175 if( mode == pAdapter->device_mode )
8176 {
8177 switch(pAdapter->device_mode)
8178 {
8179 case WLAN_HDD_INFRA_STATION:
8180 case WLAN_HDD_P2P_CLIENT:
8181 if( hdd_connIsConnected( WLAN_HDD_GET_STATION_CTX_PTR( pAdapter )) )
8182 operatingChannel = (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.operationChannel;
8183 break;
8184 case WLAN_HDD_SOFTAP:
8185 case WLAN_HDD_P2P_GO:
8186 /*softap connection info */
8187 if(test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
8188 operatingChannel = (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->operatingChannel;
8189 break;
8190 default:
8191 break;
8192 }
8193
8194 break; //Found the device of interest. break the loop
8195 }
8196
8197 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
8198 pAdapterNode = pNext;
8199 }
8200 return operatingChannel;
8201}
8202
8203#ifdef WLAN_FEATURE_PACKET_FILTERING
8204/**---------------------------------------------------------------------------
8205
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05308206 \brief __hdd_set_multicast_list() -
Jeff Johnson295189b2012-06-20 16:38:30 -07008207
8208 This used to set the multicast address list.
8209
8210 \param - dev - Pointer to the WLAN device.
8211 - skb - Pointer to OS packet (sk_buff).
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05308212 \return - success/fail
Jeff Johnson295189b2012-06-20 16:38:30 -07008213
8214 --------------------------------------------------------------------------*/
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05308215static void __hdd_set_multicast_list(struct net_device *dev)
Jeff Johnson295189b2012-06-20 16:38:30 -07008216{
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05308217 hdd_adapter_t *pAdapter;
8218 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07008219 int mc_count;
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05308220 int i = 0, ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07008221 struct netdev_hw_addr *ha;
Gopichand Nakkala0f276812013-02-24 14:45:51 +05308222
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05308223 ENTER();
8224
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05308225 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkala0f276812013-02-24 14:45:51 +05308226 if (NULL == pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07008227 {
8228 hddLog(VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala0f276812013-02-24 14:45:51 +05308229 "%s: Adapter context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07008230 return;
8231 }
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05308232 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8233 ret = wlan_hdd_validate_context(pHddCtx);
8234 if (0 != ret)
8235 {
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05308236 return;
8237 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008238 if (dev->flags & IFF_ALLMULTI)
8239 {
8240 hddLog(VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008241 "%s: allow all multicast frames", __func__);
Gopichand Nakkala0f276812013-02-24 14:45:51 +05308242 pAdapter->mc_addr_list.mc_cnt = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07008243 }
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05308244 else
Jeff Johnson295189b2012-06-20 16:38:30 -07008245 {
8246 mc_count = netdev_mc_count(dev);
8247 hddLog(VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008248 "%s: mc_count = %u", __func__, mc_count);
Jeff Johnson295189b2012-06-20 16:38:30 -07008249 if (mc_count > WLAN_HDD_MAX_MC_ADDR_LIST)
8250 {
8251 hddLog(VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008252 "%s: No free filter available; allow all multicast frames", __func__);
Gopichand Nakkala0f276812013-02-24 14:45:51 +05308253 pAdapter->mc_addr_list.mc_cnt = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07008254 return;
8255 }
8256
Gopichand Nakkala0f276812013-02-24 14:45:51 +05308257 pAdapter->mc_addr_list.mc_cnt = mc_count;
Jeff Johnson295189b2012-06-20 16:38:30 -07008258
8259 netdev_for_each_mc_addr(ha, dev) {
8260 if (i == mc_count)
8261 break;
Gopichand Nakkala0f276812013-02-24 14:45:51 +05308262 memset(&(pAdapter->mc_addr_list.addr[i][0]), 0, ETH_ALEN);
8263 memcpy(&(pAdapter->mc_addr_list.addr[i][0]), ha->addr, ETH_ALEN);
Arif Hussain6d2a3322013-11-17 19:50:10 -08008264 hddLog(VOS_TRACE_LEVEL_INFO, "%s: mlist[%d] = "MAC_ADDRESS_STR,
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05308265 __func__, i,
Gopichand Nakkala0f276812013-02-24 14:45:51 +05308266 MAC_ADDR_ARRAY(pAdapter->mc_addr_list.addr[i]));
Jeff Johnson295189b2012-06-20 16:38:30 -07008267 i++;
8268 }
8269 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05308270
Ganesh Kondabattinifb37e652015-10-09 15:46:47 +05308271 if (pHddCtx->hdd_wlan_suspended)
8272 {
8273 /*
8274 * Configure the Mcast address list to FW
8275 * If wlan is already in suspend mode
8276 */
8277 wlan_hdd_set_mc_addr_list(pAdapter, TRUE);
8278 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05308279 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07008280 return;
8281}
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05308282
8283static void hdd_set_multicast_list(struct net_device *dev)
8284{
8285 vos_ssr_protect(__func__);
8286 __hdd_set_multicast_list(dev);
8287 vos_ssr_unprotect(__func__);
8288}
Jeff Johnson295189b2012-06-20 16:38:30 -07008289#endif
8290
8291/**---------------------------------------------------------------------------
8292
8293 \brief hdd_select_queue() -
8294
8295 This function is registered with the Linux OS for network
8296 core to decide which queue to use first.
8297
8298 \param - dev - Pointer to the WLAN device.
8299 - skb - Pointer to OS packet (sk_buff).
8300 \return - ac, Queue Index/access category corresponding to UP in IP header
8301
8302 --------------------------------------------------------------------------*/
8303v_U16_t hdd_select_queue(struct net_device *dev,
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05308304 struct sk_buff *skb
8305#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,13,0))
8306 , void *accel_priv
8307#endif
8308#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
8309 , select_queue_fallback_t fallback
8310#endif
8311)
Jeff Johnson295189b2012-06-20 16:38:30 -07008312{
8313 return hdd_wmm_select_queue(dev, skb);
8314}
8315
8316
8317/**---------------------------------------------------------------------------
8318
8319 \brief hdd_wlan_initial_scan() -
8320
8321 This function triggers the initial scan
8322
8323 \param - pAdapter - Pointer to the HDD adapter.
8324
8325 --------------------------------------------------------------------------*/
8326void hdd_wlan_initial_scan(hdd_adapter_t *pAdapter)
8327{
8328 tCsrScanRequest scanReq;
8329 tCsrChannelInfo channelInfo;
8330 eHalStatus halStatus;
Jeff Johnson02797792013-10-26 19:17:13 -07008331 tANI_U32 scanId;
Jeff Johnson295189b2012-06-20 16:38:30 -07008332 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8333
8334 vos_mem_zero(&scanReq, sizeof(tCsrScanRequest));
8335 vos_mem_set(&scanReq.bssid, sizeof(tCsrBssid), 0xff);
8336 scanReq.BSSType = eCSR_BSS_TYPE_ANY;
8337
8338 if(sme_Is11dSupported(pHddCtx->hHal))
8339 {
8340 halStatus = sme_ScanGetBaseChannels( pHddCtx->hHal, &channelInfo );
8341 if ( HAL_STATUS_SUCCESS( halStatus ) )
8342 {
8343 scanReq.ChannelInfo.ChannelList = vos_mem_malloc(channelInfo.numOfChannels);
8344 if( !scanReq.ChannelInfo.ChannelList )
8345 {
8346 hddLog(VOS_TRACE_LEVEL_ERROR, "%s kmalloc failed", __func__);
8347 vos_mem_free(channelInfo.ChannelList);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08008348 channelInfo.ChannelList = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07008349 return;
8350 }
8351 vos_mem_copy(scanReq.ChannelInfo.ChannelList, channelInfo.ChannelList,
8352 channelInfo.numOfChannels);
8353 scanReq.ChannelInfo.numOfChannels = channelInfo.numOfChannels;
8354 vos_mem_free(channelInfo.ChannelList);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08008355 channelInfo.ChannelList = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07008356 }
8357
8358 scanReq.scanType = eSIR_PASSIVE_SCAN;
8359 scanReq.requestType = eCSR_SCAN_REQUEST_11D_SCAN;
8360 scanReq.maxChnTime = pHddCtx->cfg_ini->nPassiveMaxChnTime;
8361 scanReq.minChnTime = pHddCtx->cfg_ini->nPassiveMinChnTime;
8362 }
8363 else
8364 {
8365 scanReq.scanType = eSIR_ACTIVE_SCAN;
8366 scanReq.requestType = eCSR_SCAN_REQUEST_FULL_SCAN;
8367 scanReq.maxChnTime = pHddCtx->cfg_ini->nActiveMaxChnTime;
8368 scanReq.minChnTime = pHddCtx->cfg_ini->nActiveMinChnTime;
8369 }
8370
8371 halStatus = sme_ScanRequest(pHddCtx->hHal, pAdapter->sessionId, &scanReq, &scanId, NULL, NULL);
8372 if ( !HAL_STATUS_SUCCESS( halStatus ) )
8373 {
8374 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: sme_ScanRequest failed status code %d",
8375 __func__, halStatus );
8376 }
8377
8378 if(sme_Is11dSupported(pHddCtx->hHal))
8379 vos_mem_free(scanReq.ChannelInfo.ChannelList);
8380}
8381
mukul sharmabab477d2015-06-11 17:14:55 +05308382void hdd_purge_cmd_list_all_adapters( hdd_context_t *pHddCtx )
8383{
8384 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
8385 VOS_STATUS status;
8386 hdd_adapter_t *pAdapter;
8387
8388 ENTER();
8389
8390 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
8391
8392 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
8393 {
8394 pAdapter = pAdapterNode->pAdapter;
8395
8396 status = sme_PurgeCmdList(pHddCtx->hHal, pAdapter->sessionId);
8397 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
8398 pAdapterNode = pNext;
8399 }
8400
8401 EXIT();
8402}
Jeff Johnson295189b2012-06-20 16:38:30 -07008403/**---------------------------------------------------------------------------
8404
8405 \brief hdd_full_power_callback() - HDD full power callback function
8406
8407 This is the function invoked by SME to inform the result of a full power
8408 request issued by HDD
8409
8410 \param - callbackcontext - Pointer to cookie
8411 \param - status - result of request
8412
8413 \return - None
8414
8415 --------------------------------------------------------------------------*/
8416static void hdd_full_power_callback(void *callbackContext, eHalStatus status)
8417{
Jeff Johnson72a40512013-12-19 10:14:15 -08008418 struct statsContext *pContext = callbackContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07008419
8420 hddLog(VOS_TRACE_LEVEL_INFO,
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05308421 "%s: context = %p, status = %d", __func__, pContext, status);
Jeff Johnson295189b2012-06-20 16:38:30 -07008422
8423 if (NULL == callbackContext)
8424 {
8425 hddLog(VOS_TRACE_LEVEL_ERROR,
8426 "%s: Bad param, context [%p]",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008427 __func__, callbackContext);
Jeff Johnson295189b2012-06-20 16:38:30 -07008428 return;
8429 }
8430
Jeff Johnson72a40512013-12-19 10:14:15 -08008431 /* there is a race condition that exists between this callback
8432 function and the caller since the caller could time out either
8433 before or while this code is executing. we use a spinlock to
8434 serialize these actions */
8435 spin_lock(&hdd_context_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07008436
8437 if (POWER_CONTEXT_MAGIC != pContext->magic)
8438 {
8439 /* the caller presumably timed out so there is nothing we can do */
Jeff Johnson72a40512013-12-19 10:14:15 -08008440 spin_unlock(&hdd_context_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07008441 hddLog(VOS_TRACE_LEVEL_WARN,
8442 "%s: Invalid context, magic [%08x]",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008443 __func__, pContext->magic);
Jeff Johnson295189b2012-06-20 16:38:30 -07008444 return;
8445 }
8446
Jeff Johnson72a40512013-12-19 10:14:15 -08008447 /* context is valid so caller is still waiting */
8448
8449 /* paranoia: invalidate the magic */
8450 pContext->magic = 0;
8451
8452 /* notify the caller */
Jeff Johnson295189b2012-06-20 16:38:30 -07008453 complete(&pContext->completion);
Jeff Johnson72a40512013-12-19 10:14:15 -08008454
8455 /* serialization is complete */
8456 spin_unlock(&hdd_context_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07008457}
8458
Katya Nigamf0511f62015-05-05 16:40:57 +05308459void wlan_hdd_mon_set_typesubtype( hdd_mon_ctx_t *pMonCtx,int type)
8460{
8461 pMonCtx->typeSubtypeBitmap = 0;
8462 if( type%10 ) /* Management Packets */
8463 pMonCtx->typeSubtypeBitmap |= 0xFFFF;
8464 type/=10;
8465 if( type%10 ) /* Control Packets */
8466 pMonCtx->typeSubtypeBitmap |= 0xFFFF0000;
8467 type/=10;
8468 if( type%10 ) /* Data Packets */
8469 pMonCtx->typeSubtypeBitmap |= 0xFFFF00000000;
8470}
8471
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +05308472VOS_STATUS wlan_hdd_mon_postMsg(tANI_U32 *magic, struct completion *cmpVar,
8473 hdd_mon_ctx_t *pMonCtx , void* callback)
Katya Nigamf0511f62015-05-05 16:40:57 +05308474{
8475 vos_msg_t monMsg;
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +05308476 tSirMonModeReq *pMonModeReq;
Katya Nigamf0511f62015-05-05 16:40:57 +05308477
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +05308478 if (MON_MODE_START == pMonCtx->state)
8479 monMsg.type = WDA_MON_START_REQ;
8480 else if (MON_MODE_STOP == pMonCtx->state)
8481 monMsg.type = WDA_MON_STOP_REQ;
8482 else {
8483 hddLog(VOS_TRACE_LEVEL_ERROR,
8484 FL("invalid monitor state %d"), pMonCtx->state);
Katya Nigamf0511f62015-05-05 16:40:57 +05308485 return VOS_STATUS_E_FAILURE;
8486 }
8487
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +05308488 pMonModeReq = vos_mem_malloc(sizeof(tSirMonModeReq));
8489 if (pMonModeReq == NULL) {
8490 hddLog(VOS_TRACE_LEVEL_ERROR,
8491 FL("fail to allocate memory for monitor mode req"));
8492 return VOS_STATUS_E_FAILURE;
8493 }
Katya Nigamf0511f62015-05-05 16:40:57 +05308494
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +05308495 pMonModeReq->magic = magic;
8496 pMonModeReq->cmpVar = cmpVar;
8497 pMonModeReq->data = pMonCtx;
8498 pMonModeReq->callback = callback;
Katya Nigamf0511f62015-05-05 16:40:57 +05308499
Katya Nigamf0511f62015-05-05 16:40:57 +05308500 monMsg.reserved = 0;
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +05308501 monMsg.bodyptr = pMonModeReq;
Katya Nigamf0511f62015-05-05 16:40:57 +05308502 monMsg.bodyval = 0;
8503
8504 if (VOS_STATUS_SUCCESS != vos_mq_post_message(
8505 VOS_MODULE_ID_WDA,(vos_msg_t *)&monMsg)) {
8506 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: : Failed to post Msg to HAL",__func__);
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +05308507 vos_mem_free(pMonModeReq);
Katya Nigamf0511f62015-05-05 16:40:57 +05308508 }
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +05308509 return VOS_STATUS_SUCCESS;
Katya Nigamf0511f62015-05-05 16:40:57 +05308510}
8511
Katya Nigame7b69a82015-04-28 15:24:06 +05308512void wlan_hdd_mon_close(hdd_context_t *pHddCtx)
8513{
8514 VOS_STATUS vosStatus;
8515 v_CONTEXT_t pVosContext = pHddCtx->pvosContext;
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +05308516 long ret;
8517 hdd_mon_ctx_t *pMonCtx = NULL;
8518 v_U32_t magic;
8519 struct completion cmpVar;
Hanumantha Reddy Pothulac99bc062015-09-08 14:59:26 +05308520
Katya Nigame7b69a82015-04-28 15:24:06 +05308521 hdd_adapter_t *pAdapter = hdd_get_adapter(pHddCtx,WLAN_HDD_MONITOR);
8522 if(pAdapter == NULL || pVosContext == NULL)
8523 {
8524 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, "%s:pAdapter is NULL",__func__);
8525 return ;
8526 }
Katya Nigamf0511f62015-05-05 16:40:57 +05308527
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +05308528 pMonCtx = WLAN_HDD_GET_MONITOR_CTX_PTR(pAdapter);
8529 if (pMonCtx!= NULL && pMonCtx->state == MON_MODE_START) {
8530 pMonCtx->state = MON_MODE_STOP;
8531 magic = MON_MODE_MSG_MAGIC;
8532 init_completion(&cmpVar);
8533 if (VOS_STATUS_SUCCESS !=
8534 wlan_hdd_mon_postMsg(&magic, &cmpVar,
8535 pMonCtx, hdd_monPostMsgCb)) {
8536 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8537 FL("failed to post MON MODE REQ"));
8538 pMonCtx->state = MON_MODE_START;
8539 magic = 0;
8540 return;
8541 }
8542 ret = wait_for_completion_timeout(&cmpVar, MON_MODE_MSG_TIMEOUT);
8543 magic = 0;
8544 if (ret <= 0 ) {
8545 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8546 FL("timeout on monitor mode completion %ld"), ret);
8547 }
8548 }
8549
Katya Nigame7b69a82015-04-28 15:24:06 +05308550 hdd_UnregisterWext(pAdapter->dev);
8551
8552 vos_mon_stop( pVosContext );
8553
8554 vosStatus = vos_sched_close( pVosContext );
8555 if (!VOS_IS_STATUS_SUCCESS(vosStatus)) {
8556 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
8557 "%s: Failed to close VOSS Scheduler",__func__);
8558 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
8559 }
8560
8561 vosStatus = vos_nv_close();
8562 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
8563 {
8564 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
8565 "%s: Failed to close NV", __func__);
8566 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
8567 }
8568
8569 vos_close(pVosContext);
8570
8571 #ifdef WLAN_KD_READY_NOTIFIER
8572 nl_srv_exit(pHddCtx->ptt_pid);
8573 #else
8574 nl_srv_exit();
8575 #endif
8576
Katya Nigame7b69a82015-04-28 15:24:06 +05308577 hdd_close_all_adapters( pHddCtx );
Katya Nigame7b69a82015-04-28 15:24:06 +05308578}
Jeff Johnson295189b2012-06-20 16:38:30 -07008579/**---------------------------------------------------------------------------
8580
8581 \brief hdd_wlan_exit() - HDD WLAN exit function
8582
8583 This is the driver exit point (invoked during rmmod)
8584
8585 \param - pHddCtx - Pointer to the HDD Context
8586
8587 \return - None
8588
8589 --------------------------------------------------------------------------*/
8590void hdd_wlan_exit(hdd_context_t *pHddCtx)
8591{
8592 eHalStatus halStatus;
8593 v_CONTEXT_t pVosContext = pHddCtx->pvosContext;
8594 VOS_STATUS vosStatus;
Gopichand Nakkala66923aa2013-03-06 23:17:24 +05308595 struct wiphy *wiphy = pHddCtx->wiphy;
Mingcheng Zhu87f22fc2014-01-30 19:23:32 -08008596 hdd_adapter_t* pAdapter = NULL;
Jeff Johnson72a40512013-12-19 10:14:15 -08008597 struct statsContext powerContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07008598 long lrc;
c_hpothu5ab05e92014-06-13 17:34:05 +05308599 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07008600
8601 ENTER();
8602
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +05308603
Katya Nigame7b69a82015-04-28 15:24:06 +05308604 if (VOS_MONITOR_MODE == hdd_get_conparam())
8605 {
8606 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: MONITOR MODE",__func__);
8607 wlan_hdd_mon_close(pHddCtx);
Hanumantha Reddy Pothulac99bc062015-09-08 14:59:26 +05308608 goto free_hdd_ctx;
Katya Nigame7b69a82015-04-28 15:24:06 +05308609 }
8610 else if (VOS_FTM_MODE != hdd_get_conparam())
Jeff Johnson88ba7742013-02-27 14:36:02 -08008611 {
8612 // Unloading, restart logic is no more required.
8613 wlan_hdd_restart_deinit(pHddCtx);
Jeff Johnsone7245742012-09-05 17:12:55 -07008614
Agarwal Ashishb20e0ff2014-12-17 22:50:19 +05308615#ifdef FEATURE_WLAN_TDLS
8616 /* At the time of driver unloading; if tdls connection is present;
8617 * hdd_rx_packet_cbk calls wlan_hdd_tdls_find_peer.
8618 * wlan_hdd_tdls_find_peer always checks for valid context;
8619 * as load/unload in progress there can be a race condition.
8620 * hdd_rx_packet_cbk calls wlan_hdd_tdls_find_peer only
8621 * when tdls state is enabled.
8622 * As soon as driver set load/unload flag; tdls flag also needs
8623 * to be disabled so that hdd_rx_packet_cbk won't call
8624 * wlan_hdd_tdls_find_peer.
8625 */
8626 wlan_hdd_tdls_set_mode(pHddCtx, eTDLS_SUPPORT_DISABLED, FALSE);
8627#endif
8628
c_hpothu5ab05e92014-06-13 17:34:05 +05308629 vosStatus = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
8630 while (NULL != pAdapterNode && VOS_STATUS_E_EMPTY != vosStatus)
Jeff Johnson295189b2012-06-20 16:38:30 -07008631 {
c_hpothu5ab05e92014-06-13 17:34:05 +05308632 pAdapter = pAdapterNode->pAdapter;
8633 if (NULL != pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07008634 {
Mahesh A Saptasagar305e2632015-03-04 12:57:33 +05308635 /* Disable TX on the interface, after this hard_start_xmit() will
8636 * not be called on that interface
8637 */
8638 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
8639 netif_tx_disable(pAdapter->dev);
8640
8641 /* Mark the interface status as "down" for outside world */
8642 netif_carrier_off(pAdapter->dev);
8643
Agarwal Ashish9ffa5b92014-11-18 21:07:02 +05308644 /* DeInit the adapter. This ensures that all data packets
8645 * are freed.
8646 */
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05308647#ifdef FEATURE_WLAN_TDLS
8648 mutex_lock(&pHddCtx->tdls_lock);
8649#endif
c_hpothu002231a2015-02-05 14:58:51 +05308650 hdd_deinit_adapter(pHddCtx, pAdapter, FALSE);
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05308651#ifdef FEATURE_WLAN_TDLS
8652 mutex_unlock(&pHddCtx->tdls_lock);
8653#endif
Agarwal Ashish9ffa5b92014-11-18 21:07:02 +05308654
c_hpothu5ab05e92014-06-13 17:34:05 +05308655 if (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
8656 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode)
8657 {
8658 wlan_hdd_cfg80211_deregister_frames(pAdapter);
8659 hdd_UnregisterWext(pAdapter->dev);
8660 }
Kaushik, Sushant4975a572014-10-21 16:07:48 +05308661
Jeff Johnson295189b2012-06-20 16:38:30 -07008662 }
c_hpothu5ab05e92014-06-13 17:34:05 +05308663 vosStatus = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
8664 pAdapterNode = pNext;
Jeff Johnson295189b2012-06-20 16:38:30 -07008665 }
mukul sharmabab477d2015-06-11 17:14:55 +05308666
8667 //Purge all sme cmd's for all interface
8668 hdd_purge_cmd_list_all_adapters(pHddCtx);
8669
Kaushik, Sushant4975a572014-10-21 16:07:48 +05308670 // Cancel any outstanding scan requests. We are about to close all
8671 // of our adapters, but an adapter structure is what SME passes back
8672 // to our callback function. Hence if there are any outstanding scan
8673 // requests then there is a race condition between when the adapter
8674 // is closed and when the callback is invoked.We try to resolve that
8675 // race condition here by canceling any outstanding scans before we
8676 // close the adapters.
8677 // Note that the scans may be cancelled in an asynchronous manner,
8678 // so ideally there needs to be some kind of synchronization. Rather
8679 // than introduce a new synchronization here, we will utilize the
8680 // fact that we are about to Request Full Power, and since that is
8681 // synchronized, the expectation is that by the time Request Full
8682 // Power has completed all scans will be cancelled.
8683 if (pHddCtx->scan_info.mScanPending)
8684 {
Hema Aparna Medicharlaf05f6cd2015-01-21 14:44:19 +05308685 if(NULL != pAdapter)
8686 {
8687 hddLog(VOS_TRACE_LEVEL_INFO,
8688 FL("abort scan mode: %d sessionId: %d"),
8689 pAdapter->device_mode,
8690 pAdapter->sessionId);
8691 }
8692 hdd_abort_mac_scan(pHddCtx,
8693 pHddCtx->scan_info.sessionId,
8694 eCSR_SCAN_ABORT_DEFAULT);
Kaushik, Sushant4975a572014-10-21 16:07:48 +05308695 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008696 }
c_hpothu5ab05e92014-06-13 17:34:05 +05308697 else
Jeff Johnson88ba7742013-02-27 14:36:02 -08008698 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308699 hddLog(VOS_TRACE_LEVEL_INFO,"%s: FTM MODE",__func__);
Hanumantha Reddy Pothula45af96b2015-02-12 16:07:58 +05308700 if (pHddCtx->ftm.ftm_state == WLAN_FTM_STARTING)
8701 {
8702 INIT_COMPLETION(pHddCtx->ftm.startCmpVar);
8703 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8704 "%s: in middle of FTM START", __func__);
8705 lrc = wait_for_completion_timeout(&pHddCtx->ftm.startCmpVar,
8706 msecs_to_jiffies(20000));
8707 if(!lrc)
8708 {
8709 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
8710 "%s: timedout on ftmStartCmpVar fatal error", __func__);
8711 }
8712 }
Jeff Johnson88ba7742013-02-27 14:36:02 -08008713 wlan_hdd_ftm_close(pHddCtx);
8714 goto free_hdd_ctx;
8715 }
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308716
Jeff Johnson295189b2012-06-20 16:38:30 -07008717 /* DeRegister with platform driver as client for Suspend/Resume */
8718 vosStatus = hddDeregisterPmOps(pHddCtx);
8719 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
8720 {
8721 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddDeregisterPmOps failed",__func__);
8722 VOS_ASSERT(0);
8723 }
8724
8725 vosStatus = hddDevTmUnregisterNotifyCallback(pHddCtx);
8726 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
8727 {
8728 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddDevTmUnregisterNotifyCallback failed",__func__);
8729 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008730
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07008731 //Stop the traffic monitor timer
8732 if ( VOS_TIMER_STATE_RUNNING ==
8733 vos_timer_getCurrentState(&pHddCtx->tx_rx_trafficTmr))
8734 {
8735 vos_timer_stop(&pHddCtx->tx_rx_trafficTmr);
8736 }
8737
8738 // Destroy the traffic monitor timer
8739 if (!VOS_IS_STATUS_SUCCESS(vos_timer_destroy(
8740 &pHddCtx->tx_rx_trafficTmr)))
8741 {
8742 hddLog(VOS_TRACE_LEVEL_ERROR,
8743 "%s: Cannot deallocate Traffic monitor timer", __func__);
8744 }
8745
Jeff Johnson295189b2012-06-20 16:38:30 -07008746 //Disable IMPS/BMPS as we do not want the device to enter any power
8747 //save mode during shutdown
8748 sme_DisablePowerSave(pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
8749 sme_DisablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
8750 sme_DisablePowerSave(pHddCtx->hHal, ePMC_UAPSD_MODE_POWER_SAVE);
8751
8752 //Ensure that device is in full power as we will touch H/W during vos_Stop
8753 init_completion(&powerContext.completion);
8754 powerContext.magic = POWER_CONTEXT_MAGIC;
8755
8756 halStatus = sme_RequestFullPower(pHddCtx->hHal, hdd_full_power_callback,
8757 &powerContext, eSME_FULL_PWR_NEEDED_BY_HDD);
8758
8759 if (eHAL_STATUS_SUCCESS != halStatus)
8760 {
8761 if (eHAL_STATUS_PMC_PENDING == halStatus)
8762 {
8763 /* request was sent -- wait for the response */
8764 lrc = wait_for_completion_interruptible_timeout(
8765 &powerContext.completion,
8766 msecs_to_jiffies(WLAN_WAIT_TIME_POWER));
Jeff Johnson295189b2012-06-20 16:38:30 -07008767 if (lrc <= 0)
8768 {
8769 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: %s while requesting full power",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008770 __func__, (0 == lrc) ? "timeout" : "interrupt");
Jeff Johnson295189b2012-06-20 16:38:30 -07008771 }
8772 }
8773 else
8774 {
8775 hddLog(VOS_TRACE_LEVEL_ERROR,
8776 "%s: Request for Full Power failed, status %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008777 __func__, halStatus);
Jeff Johnson295189b2012-06-20 16:38:30 -07008778 /* continue -- need to clean up as much as possible */
8779 }
8780 }
Hanumantha Reddy Pothula81b42b22015-05-12 13:52:00 +05308781 if ((eHAL_STATUS_SUCCESS == halStatus) ||
8782 (eHAL_STATUS_PMC_PENDING == halStatus && lrc > 0))
8783 {
8784 /* This will issue a dump command which will clean up
8785 BTQM queues and unblock MC thread */
8786 vos_fwDumpReq(274, 0, 0, 0, 0, 1);
8787 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008788
Jeff Johnson72a40512013-12-19 10:14:15 -08008789 /* either we never sent a request, we sent a request and received a
8790 response or we sent a request and timed out. if we never sent a
8791 request or if we sent a request and got a response, we want to
8792 clear the magic out of paranoia. if we timed out there is a
8793 race condition such that the callback function could be
8794 executing at the same time we are. of primary concern is if the
8795 callback function had already verified the "magic" but had not
8796 yet set the completion variable when a timeout occurred. we
8797 serialize these activities by invalidating the magic while
8798 holding a shared spinlock which will cause us to block if the
8799 callback is currently executing */
8800 spin_lock(&hdd_context_lock);
8801 powerContext.magic = 0;
8802 spin_unlock(&hdd_context_lock);
8803
Hema Aparna Medicharlaa6cf65e2015-06-01 16:23:28 +05308804 /* If Device is shutdown, no point for SME to wait for responses
8805 from device. Pre Close SME */
8806 if(wcnss_device_is_shutdown())
8807 {
8808 sme_PreClose(pHddCtx->hHal);
8809 }
Yue Ma0d4891e2013-08-06 17:01:45 -07008810 hdd_debugfs_exit(pHddCtx);
8811
Ratheesh S P35ed8b12015-04-27 14:01:07 +05308812#ifdef WLAN_NS_OFFLOAD
Ratheesh S P36dbc932015-08-07 14:28:57 +05308813 hddLog(LOG1, FL("Unregister IPv6 notifier"));
Ratheesh S P35ed8b12015-04-27 14:01:07 +05308814 unregister_inet6addr_notifier(&pHddCtx->ipv6_notifier);
8815#endif
Ratheesh S P36dbc932015-08-07 14:28:57 +05308816 hddLog(LOG1, FL("Unregister IPv4 notifier"));
Ratheesh S P35ed8b12015-04-27 14:01:07 +05308817 unregister_inetaddr_notifier(&pHddCtx->ipv4_notifier);
8818
Jeff Johnson295189b2012-06-20 16:38:30 -07008819 // Unregister the Net Device Notifier
8820 unregister_netdevice_notifier(&hdd_netdev_notifier);
8821
Jeff Johnson295189b2012-06-20 16:38:30 -07008822 hdd_stop_all_adapters( pHddCtx );
8823
Jeff Johnson295189b2012-06-20 16:38:30 -07008824#ifdef WLAN_BTAMP_FEATURE
8825 vosStatus = WLANBAP_Stop(pVosContext);
8826 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
8827 {
8828 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
8829 "%s: Failed to stop BAP",__func__);
8830 }
8831#endif //WLAN_BTAMP_FEATURE
8832
8833 //Stop all the modules
8834 vosStatus = vos_stop( pVosContext );
8835 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
8836 {
8837 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
8838 "%s: Failed to stop VOSS",__func__);
8839 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
Hanumantha Reddy Pothula013bb412015-09-22 14:05:18 +05308840 VOS_BUG(0);
Jeff Johnson295189b2012-06-20 16:38:30 -07008841 }
8842
Jeff Johnson295189b2012-06-20 16:38:30 -07008843 //This requires pMac access, Call this before vos_close().
Jeff Johnson295189b2012-06-20 16:38:30 -07008844 hdd_unregister_mcast_bcast_filter(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07008845
8846 //Close the scheduler before calling vos_close to make sure no thread is
8847 // scheduled after the each module close is called i.e after all the data
8848 // structures are freed.
8849 vosStatus = vos_sched_close( pVosContext );
8850 if (!VOS_IS_STATUS_SUCCESS(vosStatus)) {
8851 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
8852 "%s: Failed to close VOSS Scheduler",__func__);
8853 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
8854 }
Jeff Johnsone7245742012-09-05 17:12:55 -07008855#ifdef WLAN_FEATURE_HOLD_RX_WAKELOCK
8856 /* Destroy the wake lock */
Sushant Kaushik83392fa2015-05-05 17:44:40 +05308857 vos_wake_lock_destroy(&pHddCtx->rx_wake_lock);
Jeff Johnsone7245742012-09-05 17:12:55 -07008858#endif
Madan Mohan Koyyalamudi69fc3ad2012-11-28 16:04:56 -08008859 /* Destroy the wake lock */
Sushant Kaushik83392fa2015-05-05 17:44:40 +05308860 vos_wake_lock_destroy(&pHddCtx->sap_wake_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07008861
Mihir Shete7a24b5f2013-12-21 12:18:31 +05308862#ifdef CONFIG_ENABLE_LINUX_REG
8863 vosStatus = vos_nv_close();
8864 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
8865 {
8866 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
8867 "%s: Failed to close NV", __func__);
8868 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
8869 }
8870#endif
8871
Jeff Johnson295189b2012-06-20 16:38:30 -07008872 //Close VOSS
8873 //This frees pMac(HAL) context. There should not be any call that requires pMac access after this.
8874 vos_close(pVosContext);
8875
Jeff Johnson295189b2012-06-20 16:38:30 -07008876 //Close Watchdog
8877 if(pHddCtx->cfg_ini->fIsLogpEnabled)
8878 vos_watchdog_close(pVosContext);
8879
Gopichand Nakkalaa0358482013-06-12 17:05:47 +05308880 //Clean up HDD Nlink Service
8881 send_btc_nlink_msg(WLAN_MODULE_DOWN_IND, 0);
Gopichand Nakkalaa0358482013-06-12 17:05:47 +05308882
c_manjeecfd1efb2015-09-25 19:32:34 +05308883 wlan_free_fwr_mem_dump_buffer();
8884 memdump_deinit();
8885
Vinay Krishna Erannad938c422014-03-10 17:14:21 +05308886#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +05308887 if (pHddCtx->cfg_ini->wlanLoggingEnable)
Vinay Krishna Erannad938c422014-03-10 17:14:21 +05308888 {
8889 wlan_logging_sock_deactivate_svc();
8890 }
8891#endif
8892
Vinay Krishna Erannaef30b522014-08-26 17:48:16 +05308893#ifdef WLAN_KD_READY_NOTIFIER
8894 nl_srv_exit(pHddCtx->ptt_pid);
8895#else
8896 nl_srv_exit();
8897#endif /* WLAN_KD_READY_NOTIFIER */
8898
8899
Jeff Johnson295189b2012-06-20 16:38:30 -07008900 hdd_close_all_adapters( pHddCtx );
8901
Hanumantha Reddy Pothula97f9bc92015-08-10 17:21:20 +05308902free_hdd_ctx:
Jeff Johnson295189b2012-06-20 16:38:30 -07008903 /* free the power on lock from platform driver */
8904 if (free_riva_power_on_lock("wlan"))
8905 {
8906 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to free power on lock",
8907 __func__);
8908 }
8909
c_hpothu78c7b602014-05-17 17:35:49 +05308910 //Free up dynamically allocated members inside HDD Adapter
8911 if (pHddCtx->cfg_ini)
8912 {
8913 kfree(pHddCtx->cfg_ini);
8914 pHddCtx->cfg_ini= NULL;
8915 }
8916
Leo Changf04ddad2013-09-18 13:46:38 -07008917 /* FTM mode, WIPHY did not registered
8918 If un-register here, system crash will happen */
8919 if (VOS_FTM_MODE != hdd_get_conparam())
8920 {
8921 wiphy_unregister(wiphy) ;
8922 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008923 wiphy_free(wiphy) ;
Jeff Johnson295189b2012-06-20 16:38:30 -07008924 if (hdd_is_ssr_required())
8925 {
8926 /* WDI timeout had happened during unload, so SSR is needed here */
Madan Mohan Koyyalamudi3246f5b2012-10-15 15:40:02 -07008927 subsystem_restart("wcnss");
Jeff Johnson295189b2012-06-20 16:38:30 -07008928 msleep(5000);
8929 }
8930 hdd_set_ssr_required (VOS_FALSE);
8931}
8932
8933
8934/**---------------------------------------------------------------------------
8935
8936 \brief hdd_update_config_from_nv() - Function to update the contents of
8937 the running configuration with parameters taken from NV storage
8938
8939 \param - pHddCtx - Pointer to the HDD global context
8940
8941 \return - VOS_STATUS_SUCCESS if successful
8942
8943 --------------------------------------------------------------------------*/
8944static VOS_STATUS hdd_update_config_from_nv(hdd_context_t* pHddCtx)
8945{
Jeff Johnson295189b2012-06-20 16:38:30 -07008946 v_BOOL_t itemIsValid = VOS_FALSE;
8947 VOS_STATUS status;
8948 v_MACADDR_t macFromNV[VOS_MAX_CONCURRENCY_PERSONA];
8949 v_U8_t macLoop;
8950
8951 /*If the NV is valid then get the macaddress from nv else get it from qcom_cfg.ini*/
8952 status = vos_nv_getValidity(VNV_FIELD_IMAGE, &itemIsValid);
8953 if(status != VOS_STATUS_SUCCESS)
8954 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08008955 hddLog(VOS_TRACE_LEVEL_ERROR," vos_nv_getValidity() failed");
Jeff Johnson295189b2012-06-20 16:38:30 -07008956 return VOS_STATUS_E_FAILURE;
8957 }
8958
8959 if (itemIsValid == VOS_TRUE)
8960 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08008961 hddLog(VOS_TRACE_LEVEL_INFO_HIGH," Reading the Macaddress from NV");
Jeff Johnson295189b2012-06-20 16:38:30 -07008962 status = vos_nv_readMultiMacAddress((v_U8_t *)&macFromNV[0].bytes[0],
8963 VOS_MAX_CONCURRENCY_PERSONA);
8964 if(status != VOS_STATUS_SUCCESS)
8965 {
8966 /* Get MAC from NV fail, not update CFG info
8967 * INI MAC value will be used for MAC setting */
Arif Hussain6d2a3322013-11-17 19:50:10 -08008968 hddLog(VOS_TRACE_LEVEL_ERROR," vos_nv_readMacAddress() failed");
Jeff Johnson295189b2012-06-20 16:38:30 -07008969 return VOS_STATUS_E_FAILURE;
8970 }
8971
8972 /* If first MAC is not valid, treat all others are not valid
8973 * Then all MACs will be got from ini file */
8974 if(vos_is_macaddr_zero(&macFromNV[0]))
8975 {
8976 /* MAC address in NV file is not configured yet */
8977 hddLog(VOS_TRACE_LEVEL_WARN, "Invalid MAC in NV file");
8978 return VOS_STATUS_E_INVAL;
8979 }
8980
8981 /* Get MAC address from NV, update CFG info */
8982 for(macLoop = 0; macLoop < VOS_MAX_CONCURRENCY_PERSONA; macLoop++)
8983 {
8984 if(vos_is_macaddr_zero(&macFromNV[macLoop]))
8985 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308986 hddLog(VOS_TRACE_LEVEL_ERROR,"not valid MAC from NV for %d", macLoop);
Jeff Johnson295189b2012-06-20 16:38:30 -07008987 /* This MAC is not valid, skip it
8988 * This MAC will be got from ini file */
8989 }
8990 else
8991 {
8992 vos_mem_copy((v_U8_t *)&pHddCtx->cfg_ini->intfMacAddr[macLoop].bytes[0],
8993 (v_U8_t *)&macFromNV[macLoop].bytes[0],
8994 VOS_MAC_ADDR_SIZE);
8995 }
8996 }
8997 }
8998 else
8999 {
9000 hddLog(VOS_TRACE_LEVEL_ERROR, "NV ITEM, MAC Not valid");
9001 return VOS_STATUS_E_FAILURE;
9002 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009003
Jeff Johnson295189b2012-06-20 16:38:30 -07009004
9005 return VOS_STATUS_SUCCESS;
9006}
9007
9008/**---------------------------------------------------------------------------
9009
9010 \brief hdd_post_voss_start_config() - HDD post voss start config helper
9011
9012 \param - pAdapter - Pointer to the HDD
9013
9014 \return - None
9015
9016 --------------------------------------------------------------------------*/
9017VOS_STATUS hdd_post_voss_start_config(hdd_context_t* pHddCtx)
9018{
9019 eHalStatus halStatus;
9020 v_U32_t listenInterval;
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05309021 tANI_U32 ignoreDtim;
Jeff Johnson295189b2012-06-20 16:38:30 -07009022
Jeff Johnson295189b2012-06-20 16:38:30 -07009023
9024 // Send ready indication to the HDD. This will kick off the MAC
9025 // into a 'running' state and should kick off an initial scan.
9026 halStatus = sme_HDDReadyInd( pHddCtx->hHal );
9027 if ( !HAL_STATUS_SUCCESS( halStatus ) )
9028 {
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05309029 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: sme_HDDReadyInd() failed with status "
Jeff Johnson295189b2012-06-20 16:38:30 -07009030 "code %08d [x%08x]",__func__, halStatus, halStatus );
9031 return VOS_STATUS_E_FAILURE;
9032 }
9033
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05309034 // Set default LI and ignoreDtim into HDD context,
Jeff Johnson295189b2012-06-20 16:38:30 -07009035 // otherwise under some race condition, HDD will set 0 LI value into RIVA,
9036 // And RIVA will crash
9037 wlan_cfgGetInt(pHddCtx->hHal, WNI_CFG_LISTEN_INTERVAL, &listenInterval);
9038 pHddCtx->hdd_actual_LI_value = listenInterval;
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05309039 wlan_cfgGetInt(pHddCtx->hHal, WNI_CFG_IGNORE_DTIM, &ignoreDtim);
9040 pHddCtx->hdd_actual_ignore_DTIM_value = ignoreDtim;
9041
9042
Jeff Johnson295189b2012-06-20 16:38:30 -07009043 return VOS_STATUS_SUCCESS;
9044}
9045
Jeff Johnson295189b2012-06-20 16:38:30 -07009046/* wake lock APIs for HDD */
Sushant Kaushik83392fa2015-05-05 17:44:40 +05309047void hdd_prevent_suspend(uint32_t reason)
Jeff Johnson295189b2012-06-20 16:38:30 -07009048{
Sushant Kaushik83392fa2015-05-05 17:44:40 +05309049
9050 vos_wake_lock_acquire(&wlan_wake_lock, reason);
9051
Jeff Johnson295189b2012-06-20 16:38:30 -07009052}
9053
Sushant Kaushik83392fa2015-05-05 17:44:40 +05309054void hdd_allow_suspend(uint32_t reason)
Jeff Johnson295189b2012-06-20 16:38:30 -07009055{
Sushant Kaushik83392fa2015-05-05 17:44:40 +05309056
9057 vos_wake_lock_release(&wlan_wake_lock, reason);
9058
Jeff Johnson295189b2012-06-20 16:38:30 -07009059}
9060
Sushant Kaushik83392fa2015-05-05 17:44:40 +05309061void hdd_prevent_suspend_timeout(v_U32_t timeout, uint32_t reason)
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -07009062{
Sushant Kaushik83392fa2015-05-05 17:44:40 +05309063
9064 vos_wake_lock_timeout_release(&wlan_wake_lock, timeout,
9065 reason);
9066
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -07009067}
9068
Jeff Johnson295189b2012-06-20 16:38:30 -07009069/**---------------------------------------------------------------------------
9070
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07009071 \brief hdd_exchange_version_and_caps() - HDD function to exchange version and capability
9072 information between Host and Riva
9073
9074 This function gets reported version of FW
9075 It also finds the version of Riva headers used to compile the host
9076 It compares the above two and prints a warning if they are different
9077 It gets the SW and HW version string
9078 Finally, it exchanges capabilities between host and Riva i.e. host and riva exchange a msg
9079 indicating the features they support through a bitmap
9080
9081 \param - pHddCtx - Pointer to HDD context
9082
9083 \return - void
9084
9085 --------------------------------------------------------------------------*/
9086
9087void hdd_exchange_version_and_caps(hdd_context_t *pHddCtx)
9088{
9089
9090 tSirVersionType versionCompiled;
9091 tSirVersionType versionReported;
9092 tSirVersionString versionString;
9093 tANI_U8 fwFeatCapsMsgSupported = 0;
9094 VOS_STATUS vstatus;
9095
Mingcheng Zhu87f22fc2014-01-30 19:23:32 -08009096 memset(&versionCompiled, 0, sizeof(versionCompiled));
9097 memset(&versionReported, 0, sizeof(versionReported));
9098
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07009099 /* retrieve and display WCNSS version information */
9100 do {
9101
9102 vstatus = sme_GetWcnssWlanCompiledVersion(pHddCtx->hHal,
9103 &versionCompiled);
9104 if (!VOS_IS_STATUS_SUCCESS(vstatus))
9105 {
9106 hddLog(VOS_TRACE_LEVEL_FATAL,
9107 "%s: unable to retrieve WCNSS WLAN compiled version",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07009108 __func__);
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07009109 break;
9110 }
9111
9112 vstatus = sme_GetWcnssWlanReportedVersion(pHddCtx->hHal,
9113 &versionReported);
9114 if (!VOS_IS_STATUS_SUCCESS(vstatus))
9115 {
9116 hddLog(VOS_TRACE_LEVEL_FATAL,
9117 "%s: unable to retrieve WCNSS WLAN reported version",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07009118 __func__);
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07009119 break;
9120 }
9121
9122 if ((versionCompiled.major != versionReported.major) ||
9123 (versionCompiled.minor != versionReported.minor) ||
9124 (versionCompiled.version != versionReported.version) ||
9125 (versionCompiled.revision != versionReported.revision))
9126 {
9127 pr_err("%s: WCNSS WLAN Version %u.%u.%u.%u, "
9128 "Host expected %u.%u.%u.%u\n",
9129 WLAN_MODULE_NAME,
9130 (int)versionReported.major,
9131 (int)versionReported.minor,
9132 (int)versionReported.version,
9133 (int)versionReported.revision,
9134 (int)versionCompiled.major,
9135 (int)versionCompiled.minor,
9136 (int)versionCompiled.version,
9137 (int)versionCompiled.revision);
9138 }
9139 else
9140 {
9141 pr_info("%s: WCNSS WLAN version %u.%u.%u.%u\n",
9142 WLAN_MODULE_NAME,
9143 (int)versionReported.major,
9144 (int)versionReported.minor,
9145 (int)versionReported.version,
9146 (int)versionReported.revision);
9147 }
9148
9149 vstatus = sme_GetWcnssSoftwareVersion(pHddCtx->hHal,
9150 versionString,
9151 sizeof(versionString));
9152 if (!VOS_IS_STATUS_SUCCESS(vstatus))
9153 {
9154 hddLog(VOS_TRACE_LEVEL_FATAL,
9155 "%s: unable to retrieve WCNSS software version string",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07009156 __func__);
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07009157 break;
9158 }
9159
9160 pr_info("%s: WCNSS software version %s\n",
9161 WLAN_MODULE_NAME, versionString);
Sushant Kaushik084f6592015-09-10 13:11:56 +05309162 vos_mem_copy(pHddCtx->fw_Version, versionString, sizeof(versionString));
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07009163
9164 vstatus = sme_GetWcnssHardwareVersion(pHddCtx->hHal,
9165 versionString,
9166 sizeof(versionString));
9167 if (!VOS_IS_STATUS_SUCCESS(vstatus))
9168 {
9169 hddLog(VOS_TRACE_LEVEL_FATAL,
9170 "%s: unable to retrieve WCNSS hardware version string",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07009171 __func__);
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07009172 break;
9173 }
9174
9175 pr_info("%s: WCNSS hardware version %s\n",
9176 WLAN_MODULE_NAME, versionString);
9177
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -07009178 /* 1.Check if FW version is greater than 0.1.1.0. Only then send host-FW capability exchange message
9179 2.Host-FW capability exchange message is only present on riva 1.1 so
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07009180 send the message only if it the riva is 1.1
9181 minor numbers for different riva branches:
9182 0 -> (1.0)Mainline Build
9183 1 -> (1.1)Mainline Build
9184 2->(1.04) Stability Build
9185 */
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -07009186 if (((versionReported.major>0) || (versionReported.minor>1) ||
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07009187 ((versionReported.minor>=1) && (versionReported.version>=1)))
9188 && ((versionReported.major == 1) && (versionReported.minor >= 1)))
9189 fwFeatCapsMsgSupported = 1;
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -07009190
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07009191 if (fwFeatCapsMsgSupported)
Yathish9f22e662012-12-10 14:21:35 -08009192 {
9193#ifdef WLAN_ACTIVEMODE_OFFLOAD_FEATURE
9194 if(!pHddCtx->cfg_ini->fEnableActiveModeOffload)
9195 sme_disableFeatureCapablity(WLANACTIVE_OFFLOAD);
9196#endif
Ravi Joshid2ca7c42013-07-23 08:37:49 -07009197 /* Indicate if IBSS heartbeat monitoring needs to be offloaded */
9198 if (!pHddCtx->cfg_ini->enableIbssHeartBeatOffload)
9199 {
9200 sme_disableFeatureCapablity(IBSS_HEARTBEAT_OFFLOAD);
9201 }
9202
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07009203 sme_featureCapsExchange(pHddCtx->hHal);
Yathish9f22e662012-12-10 14:21:35 -08009204 }
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07009205
9206 } while (0);
9207
9208}
Neelansh Mittaledafed22014-09-04 18:54:39 +05309209void wlan_hdd_send_svc_nlink_msg(int type, void *data, int len)
9210{
9211 struct sk_buff *skb;
9212 struct nlmsghdr *nlh;
9213 tAniMsgHdr *ani_hdr;
Hanumantha Reddy Pothulacf2c7ea2015-04-27 14:50:47 +05309214 int flags = GFP_KERNEL;
Bhargav shah23c94942015-10-13 12:48:35 +05309215 void *nl_data = NULL;
Neelansh Mittaledafed22014-09-04 18:54:39 +05309216
Hanumantha Reddy Pothulacf2c7ea2015-04-27 14:50:47 +05309217 if (in_interrupt() || irqs_disabled() || in_atomic())
9218 flags = GFP_ATOMIC;
9219
9220 skb = alloc_skb(NLMSG_SPACE(WLAN_NL_MAX_PAYLOAD), flags);
Neelansh Mittaledafed22014-09-04 18:54:39 +05309221
9222 if(skb == NULL) {
9223 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9224 "%s: alloc_skb failed", __func__);
9225 return;
9226 }
9227
9228 nlh = (struct nlmsghdr *)skb->data;
9229 nlh->nlmsg_pid = 0; /* from kernel */
9230 nlh->nlmsg_flags = 0;
9231 nlh->nlmsg_seq = 0;
9232 nlh->nlmsg_type = WLAN_NL_MSG_SVC;
9233
9234 ani_hdr = NLMSG_DATA(nlh);
9235 ani_hdr->type = type;
9236
9237 switch(type) {
9238 case WLAN_SVC_SAP_RESTART_IND:
9239 ani_hdr->length = 0;
9240 nlh->nlmsg_len = NLMSG_LENGTH((sizeof(tAniMsgHdr)));
9241 skb_put(skb, NLMSG_SPACE(sizeof(tAniMsgHdr)));
9242 break;
Bhargav shah23c94942015-10-13 12:48:35 +05309243 case WLAN_MSG_RPS_ENABLE_IND:
9244 ani_hdr->length = len;
9245 nlh->nlmsg_len = NLMSG_LENGTH((sizeof(tAniMsgHdr) + len));
9246 nl_data = (char *)ani_hdr + sizeof(tAniMsgHdr);
9247 memcpy(nl_data, data, len);
9248 skb_put(skb, NLMSG_SPACE(sizeof(tAniMsgHdr) + len));
9249 break;
Neelansh Mittaledafed22014-09-04 18:54:39 +05309250 default:
9251 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9252 "Attempt to send unknown nlink message %d", type);
9253 kfree_skb(skb);
9254 return;
9255 }
9256
9257 nl_srv_bcast(skb);
9258
9259 return;
9260}
9261
9262
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07009263
9264/**---------------------------------------------------------------------------
9265
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05309266 \brief hdd_is_5g_supported() - HDD function to know if hardware supports 5GHz
9267
9268 \param - pHddCtx - Pointer to the hdd context
9269
9270 \return - true if hardware supports 5GHz
9271
9272 --------------------------------------------------------------------------*/
Vinay Krishna Erannafacf5e22014-02-24 13:16:25 +05309273boolean hdd_is_5g_supported(hdd_context_t * pHddCtx)
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05309274{
9275 /* If wcnss_wlan_iris_xo_mode() returns WCNSS_XO_48MHZ(1);
9276 * then hardware support 5Ghz.
9277 */
9278 if (WCNSS_XO_48MHZ == wcnss_wlan_iris_xo_mode())
9279 {
Ratheesh S P36dbc932015-08-07 14:28:57 +05309280 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Hardware supports 5Ghz", __func__);
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05309281 return true;
9282 }
9283 else
9284 {
Ratheesh S P36dbc932015-08-07 14:28:57 +05309285 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Hardware doesn't supports 5Ghz",
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05309286 __func__);
9287 return false;
9288 }
9289}
9290
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05309291/**---------------------------------------------------------------------------
9292
9293 \brief hdd_generate_iface_mac_addr_auto() - HDD Mac Interface Auto
9294 generate function
9295
9296 This is generate the random mac address for WLAN interface
9297
9298 \param - pHddCtx - Pointer to HDD context
9299 idx - Start interface index to get auto
9300 generated mac addr.
9301 mac_addr - Mac address
9302
9303 \return - 0 for success, < 0 for failure
9304
9305 --------------------------------------------------------------------------*/
9306
9307static int hdd_generate_iface_mac_addr_auto(hdd_context_t *pHddCtx,
9308 int idx, v_MACADDR_t mac_addr)
9309{
9310 int i;
9311 unsigned int serialno;
9312 serialno = wcnss_get_serial_number();
9313
9314 if (0 != serialno)
9315 {
9316 /* MAC address has 3 bytes of OUI so we have a maximum of 3
9317 bytes of the serial number that can be used to generate
9318 the other 3 bytes of the MAC address. Mask off all but
9319 the lower 3 bytes (this will also make sure we don't
9320 overflow in the next step) */
9321 serialno &= 0x00FFFFFF;
9322
9323 /* we need a unique address for each session */
9324 serialno *= VOS_MAX_CONCURRENCY_PERSONA;
9325
9326 /* autogen other Mac addresses */
9327 for (i = idx; i < VOS_MAX_CONCURRENCY_PERSONA; i++)
9328 {
9329 /* start with the entire default address */
9330 pHddCtx->cfg_ini->intfMacAddr[i] = mac_addr;
9331 /* then replace the lower 3 bytes */
9332 pHddCtx->cfg_ini->intfMacAddr[i].bytes[3] = (serialno >> 16) & 0xFF;
9333 pHddCtx->cfg_ini->intfMacAddr[i].bytes[4] = (serialno >> 8) & 0xFF;
9334 pHddCtx->cfg_ini->intfMacAddr[i].bytes[5] = serialno & 0xFF;
9335
9336 serialno++;
9337 hddLog(VOS_TRACE_LEVEL_ERROR,
9338 "%s: Derived Mac Addr: "
9339 MAC_ADDRESS_STR, __func__,
9340 MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[i].bytes));
9341 }
9342
9343 }
9344 else
9345 {
9346 hddLog(LOGE, FL("Failed to Get Serial NO"));
9347 return -1;
9348 }
9349 return 0;
9350}
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05309351
Katya Nigame7b69a82015-04-28 15:24:06 +05309352int wlan_hdd_mon_open(hdd_context_t *pHddCtx)
9353{
9354 VOS_STATUS status;
9355 v_CONTEXT_t pVosContext= NULL;
9356 hdd_adapter_t *pAdapter= NULL;
9357
9358 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
9359
9360 if (NULL == pVosContext)
9361 {
9362 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9363 "%s: Trying to open VOSS without a PreOpen", __func__);
9364 VOS_ASSERT(0);
9365 return VOS_STATUS_E_FAILURE;
9366 }
9367
9368 status = vos_nv_open();
9369 if (!VOS_IS_STATUS_SUCCESS(status))
9370 {
9371 /* NV module cannot be initialized */
9372 hddLog( VOS_TRACE_LEVEL_FATAL,
9373 "%s: vos_nv_open failed", __func__);
9374 return VOS_STATUS_E_FAILURE;
9375 }
9376
9377 status = vos_init_wiphy_from_nv_bin();
9378 if (!VOS_IS_STATUS_SUCCESS(status))
9379 {
9380 /* NV module cannot be initialized */
9381 hddLog( VOS_TRACE_LEVEL_FATAL,
9382 "%s: vos_init_wiphy failed", __func__);
9383 goto err_vos_nv_close;
9384 }
9385
9386 status = vos_open( &pVosContext, pHddCtx->parent_dev);
9387 if ( !VOS_IS_STATUS_SUCCESS( status ))
9388 {
9389 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: vos_open failed", __func__);
9390 goto err_vos_nv_close;
9391 }
9392
9393 status = vos_mon_start( pVosContext );
9394 if ( !VOS_IS_STATUS_SUCCESS( status ) )
9395 {
9396 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: vos_start failed",__func__);
9397 goto err_vosclose;
9398 }
9399
9400 WLANTL_SetMonRxCbk( pVosContext, hdd_rx_packet_monitor_cbk );
9401 WDA_featureCapsExchange(pVosContext);
9402 wcnss_wlan_set_drvdata(pHddCtx->parent_dev, pHddCtx);
9403
9404 pAdapter = hdd_open_adapter( pHddCtx, WLAN_HDD_MONITOR, "wlan%d",
9405 wlan_hdd_get_intf_addr(pHddCtx), FALSE );
9406 if( pAdapter == NULL )
9407 {
9408 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: hdd_open_adapter failed", __func__);
9409 goto err_close_adapter;
9410 }
9411
9412 //Initialize the nlink service
9413 if(nl_srv_init() != 0)
9414 {
9415 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: nl_srv_init failed", __func__);
9416 goto err_close_adapter;
9417 }
9418 return VOS_STATUS_SUCCESS;
9419
9420err_close_adapter:
9421 hdd_close_all_adapters( pHddCtx );
9422 vos_mon_stop( pVosContext );
9423err_vosclose:
9424 status = vos_sched_close( pVosContext );
9425 if (!VOS_IS_STATUS_SUCCESS(status)) {
9426 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
9427 "%s: Failed to close VOSS Scheduler", __func__);
9428 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( status ) );
9429 }
9430 vos_close(pVosContext );
9431
9432err_vos_nv_close:
9433 vos_nv_close();
9434
9435return status;
9436}
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05309437/**---------------------------------------------------------------------------
9438
Mihir Shetefc7ff5b2014-01-27 11:30:05 +05309439 \brief hdd_11d_scan_done - callback to be executed when 11d scan is
9440 completed to flush out the scan results
9441
9442 11d scan is done during driver load and is a passive scan on all
9443 channels supported by the device, 11d scans may find some APs on
9444 frequencies which are forbidden to be used in the regulatory domain
9445 the device is operating in. If these APs are notified to the supplicant
9446 it may try to connect to these APs, thus flush out all the scan results
9447 which are present in SME after 11d scan is done.
9448
9449 \return - eHalStatus
9450
9451 --------------------------------------------------------------------------*/
9452static eHalStatus hdd_11d_scan_done(tHalHandle halHandle, void *pContext,
9453 tANI_U32 scanId, eCsrScanStatus status)
9454{
9455 ENTER();
9456
9457 sme_ScanFlushResult(halHandle, 0);
9458
9459 EXIT();
9460
9461 return eHAL_STATUS_SUCCESS;
9462}
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309463/**---------------------------------------------------------------------------
9464
9465 \brief hdd_init_frame_logging_done - callback to be executed when mgmt frame
9466 logging is completed successfully.
9467
9468 \return - None
9469
9470 --------------------------------------------------------------------------*/
c_manjeecfd1efb2015-09-25 19:32:34 +05309471void hdd_init_frame_logging_done(void *fwlogInitCbContext, tAniLoggingInitRsp *pRsp)
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309472{
Siddharth Bhald1be97f2015-05-27 22:39:59 +05309473 hdd_context_t* pHddCtx = (hdd_context_t*)fwlogInitCbContext;
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309474
9475 if (NULL == pHddCtx)
9476 {
9477 hddLog(VOS_TRACE_LEVEL_ERROR,
9478 "%s: HDD context is NULL",__func__);
9479 return;
9480 }
9481
c_manjeecfd1efb2015-09-25 19:32:34 +05309482 if ((pRsp->status == VOS_STATUS_SUCCESS) &&
Mahesh A Saptasagarfabb1a02015-06-29 12:17:04 +05309483 (TRUE == pHddCtx->cfg_ini->enableMgmtLogging))
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309484 {
9485 hddLog(VOS_TRACE_LEVEL_INFO, FL("Mgmt Frame Logging init successful"));
9486 pHddCtx->mgmt_frame_logging = TRUE;
9487 }
9488 else
9489 {
9490 hddLog(VOS_TRACE_LEVEL_INFO, FL("Mgmt Frame Logging init not success"));
9491 pHddCtx->mgmt_frame_logging = FALSE;
c_manjeecfd1efb2015-09-25 19:32:34 +05309492 return;
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309493 }
9494
c_manjeecfd1efb2015-09-25 19:32:34 +05309495 /*Check feature supported by FW*/
9496 if(TRUE == sme_IsFeatureSupportedByFW(MEMORY_DUMP_SUPPORTED))
9497 {
9498 //Store fwr mem dump size given by firmware.
9499 wlan_store_fwr_mem_dump_size(pRsp->fw_mem_dump_max_size);
9500 }
9501 else
9502 {
9503 wlan_store_fwr_mem_dump_size(0);
9504 }
9505
9506
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309507}
9508/**---------------------------------------------------------------------------
9509
9510 \brief hdd_init_frame_logging - function to initialize frame logging.
9511 Currently only Mgmt Frames are logged in both TX
9512 and Rx direction and are sent to userspace
9513 application using logger thread when queried.
9514
9515 \return - None
9516
9517 --------------------------------------------------------------------------*/
Siddharth Bhald1be97f2015-05-27 22:39:59 +05309518void hdd_init_frame_logging(hdd_context_t* pHddCtx)
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309519{
9520 eHalStatus halStatus = eHAL_STATUS_FAILURE;
Siddharth Bhald1be97f2015-05-27 22:39:59 +05309521 tpSirFWLoggingInitParam wlanFWLoggingInitParam;
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309522
Siddharth Bhald1be97f2015-05-27 22:39:59 +05309523 if (TRUE != sme_IsFeatureSupportedByFW(MGMT_FRAME_LOGGING) &&
9524 TRUE != sme_IsFeatureSupportedByFW(LOGGING_ENHANCEMENT))
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309525 {
9526 hddLog(VOS_TRACE_LEVEL_INFO, FL("MGMT_FRAME_LOGGING not supp by FW"));
9527 return;
9528 }
9529
Siddharth Bhald1be97f2015-05-27 22:39:59 +05309530 wlanFWLoggingInitParam = vos_mem_malloc(sizeof(tSirFWLoggingInitParam));
9531 if(NULL == wlanFWLoggingInitParam)
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309532 {
9533 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: vos_mem_alloc failed ", __func__);
9534 return;
9535 }
9536
Siddharth Bhald1be97f2015-05-27 22:39:59 +05309537 vos_mem_set(wlanFWLoggingInitParam, sizeof(tSirFWLoggingInitParam), 0);
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309538
c_manjeecfd1efb2015-09-25 19:32:34 +05309539 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Configuring %s %s %s %s Logging",__func__,
Siddharth Bhald1be97f2015-05-27 22:39:59 +05309540 pHddCtx->cfg_ini->enableFWLogging?"FW Log,":"",
9541 pHddCtx->cfg_ini->enableContFWLogging ? "Cont FW log,":"",
c_manjeecfd1efb2015-09-25 19:32:34 +05309542 pHddCtx->cfg_ini->enableMgmtLogging ? "Mgmt Pkt Log":"",
9543 pHddCtx->cfg_ini->enableFwrMemDump ? "Fw Mem dump":"");
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309544
Siddharth Bhald1be97f2015-05-27 22:39:59 +05309545 if (pHddCtx->cfg_ini->enableFWLogging ||
9546 pHddCtx->cfg_ini->enableContFWLogging)
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309547 {
Siddharth Bhald1be97f2015-05-27 22:39:59 +05309548 wlanFWLoggingInitParam->enableFlag |= WLAN_QXDM_LOG_EN;
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309549 }
9550
Sushant Kaushik46804902015-07-08 14:46:03 +05309551 if (pHddCtx->cfg_ini->enableMgmtLogging)
9552 {
9553 wlanFWLoggingInitParam->enableFlag |= WLAN_FRAME_LOG_EN;
9554 }
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309555 if (pHddCtx->cfg_ini->enableBMUHWtracing)
9556 {
Siddharth Bhald1be97f2015-05-27 22:39:59 +05309557 wlanFWLoggingInitParam->enableFlag |= WLAN_BMUHW_TRACE_LOG_EN;
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309558 }
c_manjeecfd1efb2015-09-25 19:32:34 +05309559 if(pHddCtx->cfg_ini->enableFwrMemDump &&
9560 (TRUE == sme_IsFeatureSupportedByFW(MEMORY_DUMP_SUPPORTED)))
9561 {
9562 wlanFWLoggingInitParam->enableFlag |= WLAN_FW_MEM_DUMP_EN;
9563 }
9564 if( wlanFWLoggingInitParam->enableFlag == 0 )
9565 {
9566 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Logging not enabled", __func__);
9567 return;
9568 }
Siddharth Bhald1be97f2015-05-27 22:39:59 +05309569 wlanFWLoggingInitParam->frameType = WLAN_FRAME_LOGGING_FRAMETYPE_MGMT;
9570 wlanFWLoggingInitParam->frameSize = WLAN_MGMT_LOGGING_FRAMESIZE_128BYTES;
9571 wlanFWLoggingInitParam->bufferMode = WLAN_FRAME_LOGGING_BUFFERMODE_CIRCULAR;
9572 wlanFWLoggingInitParam->continuousFrameLogging =
9573 pHddCtx->cfg_ini->enableContFWLogging;
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309574
Siddharth Bhald1be97f2015-05-27 22:39:59 +05309575 wlanFWLoggingInitParam->enableFlag &= ~WLAN_DPU_TXP_LOG_EN;
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309576
Siddharth Bhald1be97f2015-05-27 22:39:59 +05309577 wlanFWLoggingInitParam->minLogBufferSize =
9578 pHddCtx->cfg_ini->minLoggingBufferSize;
9579 wlanFWLoggingInitParam->maxLogBufferSize =
9580 pHddCtx->cfg_ini->maxLoggingBufferSize;
9581 wlanFWLoggingInitParam->fwlogInitCallback = hdd_init_frame_logging_done;
9582 wlanFWLoggingInitParam->fwlogInitCbContext= pHddCtx;
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309583
Siddharth Bhald1be97f2015-05-27 22:39:59 +05309584 halStatus = sme_InitMgmtFrameLogging(pHddCtx->hHal, wlanFWLoggingInitParam);
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309585
9586 if (eHAL_STATUS_SUCCESS != halStatus)
9587 {
Siddharth Bhald1be97f2015-05-27 22:39:59 +05309588 vos_mem_free(wlanFWLoggingInitParam);
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309589 }
9590
9591 return;
9592}
Mihir Shetefc7ff5b2014-01-27 11:30:05 +05309593
Bhargav shah23c94942015-10-13 12:48:35 +05309594static void hdd_dp_util_send_rps_ind(hdd_context_t *hdd_ctxt)
9595{
9596 hdd_adapter_t *adapter;
9597 hdd_adapter_list_node_t *adapter_node, *next;
9598 VOS_STATUS status = VOS_STATUS_SUCCESS;
9599 struct wlan_rps_data rps_data;
9600 int count;
9601
9602 if(!hdd_ctxt->cfg_ini->rps_mask)
9603 {
9604 return;
9605 }
9606
9607 for (count=0; count < WLAN_SVC_IFACE_NUM_QUEUES; count++)
9608 {
9609 rps_data.cpu_map[count] = hdd_ctxt->cfg_ini->rps_mask;
9610 }
9611
9612 rps_data.num_queues = WLAN_SVC_IFACE_NUM_QUEUES;
9613
9614 hddLog(LOG1, FL("0x%x 0x%x 0x%x 0x%x 0x%x 0x%x"),
9615 rps_data.cpu_map[0], rps_data.cpu_map[1],rps_data.cpu_map[2],
9616 rps_data.cpu_map[3], rps_data.cpu_map[4], rps_data.cpu_map[5]);
9617
9618 status = hdd_get_front_adapter (hdd_ctxt, &adapter_node);
9619
9620 while (NULL != adapter_node && VOS_STATUS_SUCCESS == status)
9621 {
9622 adapter = adapter_node->pAdapter;
9623 if (NULL != adapter) {
9624 strlcpy(rps_data.ifname, adapter->dev->name,
9625 sizeof(rps_data.ifname));
9626 wlan_hdd_send_svc_nlink_msg(WLAN_MSG_RPS_ENABLE_IND,
9627 (void *)&rps_data,sizeof(rps_data));
9628 }
9629 status = hdd_get_next_adapter (hdd_ctxt, adapter_node, &next);
9630 adapter_node = next;
9631 }
9632}
9633
Mihir Shetefc7ff5b2014-01-27 11:30:05 +05309634/**---------------------------------------------------------------------------
9635
Jeff Johnson295189b2012-06-20 16:38:30 -07009636 \brief hdd_wlan_startup() - HDD init function
9637
9638 This is the driver startup code executed once a WLAN device has been detected
9639
9640 \param - dev - Pointer to the underlying device
9641
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08009642 \return - 0 for success, < 0 for failure
Jeff Johnson295189b2012-06-20 16:38:30 -07009643
9644 --------------------------------------------------------------------------*/
9645
9646int hdd_wlan_startup(struct device *dev )
9647{
9648 VOS_STATUS status;
9649 hdd_adapter_t *pAdapter = NULL;
Jeff Johnsone7245742012-09-05 17:12:55 -07009650 hdd_adapter_t *pP2pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07009651 hdd_context_t *pHddCtx = NULL;
9652 v_CONTEXT_t pVosContext= NULL;
9653#ifdef WLAN_BTAMP_FEATURE
9654 VOS_STATUS vStatus = VOS_STATUS_SUCCESS;
9655 WLANBAP_ConfigType btAmpConfig;
9656 hdd_config_t *pConfig;
9657#endif
9658 int ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07009659 struct wiphy *wiphy;
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05309660 v_MACADDR_t mac_addr;
Jeff Johnson295189b2012-06-20 16:38:30 -07009661
9662 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07009663 /*
9664 * cfg80211: wiphy allocation
9665 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309666 wiphy = wlan_hdd_cfg80211_wiphy_alloc(sizeof(hdd_context_t)) ;
Jeff Johnson295189b2012-06-20 16:38:30 -07009667
9668 if(wiphy == NULL)
9669 {
9670 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: cfg80211 init failed", __func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08009671 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -07009672 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009673 pHddCtx = wiphy_priv(wiphy);
9674
Jeff Johnson295189b2012-06-20 16:38:30 -07009675 //Initialize the adapter context to zeros.
9676 vos_mem_zero(pHddCtx, sizeof( hdd_context_t ));
9677
Jeff Johnson295189b2012-06-20 16:38:30 -07009678 pHddCtx->wiphy = wiphy;
Sushant Kaushik83392fa2015-05-05 17:44:40 +05309679 hdd_prevent_suspend(WIFI_POWER_EVENT_WAKELOCK_DRIVER_INIT);
Mihir Shete18156292014-03-11 15:38:30 +05309680 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_LOAD_IN_PROGRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07009681
9682 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, TRUE);
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05309683 pHddCtx->wifi_turn_on_time_since_boot = vos_get_monotonic_boottime();
Jeff Johnson295189b2012-06-20 16:38:30 -07009684
Siddharth Bhalcd92b782015-06-29 12:25:40 +05309685 /* register for riva power on lock to platform driver
9686 * Locking power early to ensure FW doesn't reset by kernel while
9687 * host driver is busy initializing itself */
9688 if (req_riva_power_on_lock("wlan"))
9689 {
9690 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: req riva power on lock failed",
9691 __func__);
9692 goto err_free_hdd_context;
9693 }
9694
Jeff Johnson295189b2012-06-20 16:38:30 -07009695 /*Get vos context here bcoz vos_open requires it*/
9696 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
9697
Madan Mohan Koyyalamudi0b78e152012-11-28 15:46:51 -08009698 if(pVosContext == NULL)
9699 {
9700 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Failed vos_get_global_context",__func__);
9701 goto err_free_hdd_context;
9702 }
9703
Jeff Johnson295189b2012-06-20 16:38:30 -07009704 //Save the Global VOSS context in adapter context for future.
9705 pHddCtx->pvosContext = pVosContext;
9706
9707 //Save the adapter context in global context for future.
9708 ((VosContextType*)(pVosContext))->pHDDContext = (v_VOID_t*)pHddCtx;
9709
Jeff Johnson295189b2012-06-20 16:38:30 -07009710 pHddCtx->parent_dev = dev;
9711
9712 init_completion(&pHddCtx->full_pwr_comp_var);
9713 init_completion(&pHddCtx->standby_comp_var);
9714 init_completion(&pHddCtx->req_bmps_comp_var);
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07009715 init_completion(&pHddCtx->scan_info.scan_req_completion_event);
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -08009716 init_completion(&pHddCtx->scan_info.abortscan_event_var);
Kiet Lam46b8e4e2013-11-06 21:49:53 +05309717 init_completion(&pHddCtx->wiphy_channel_update_event);
Arun Kumar Khandavallie0b046d2014-03-01 21:54:25 +05309718 init_completion(&pHddCtx->ssr_comp_var);
Mahesh A Saptasagar67ab9222015-10-21 15:38:41 +05309719 init_completion(&pHddCtx->mc_sus_event_var);
9720 init_completion(&pHddCtx->tx_sus_event_var);
9721 init_completion(&pHddCtx->rx_sus_event_var);
9722
Amar Singhala49cbc52013-10-08 18:37:44 -07009723
mukul sharma4bd8d2e2015-08-13 20:33:25 +05309724 hdd_init_ll_stats_ctx(pHddCtx);
9725
Amar Singhala49cbc52013-10-08 18:37:44 -07009726#ifdef CONFIG_ENABLE_LINUX_REG
Amar Singhalfddc28c2013-09-05 13:03:40 -07009727 init_completion(&pHddCtx->linux_reg_req);
Amar Singhala49cbc52013-10-08 18:37:44 -07009728#else
9729 init_completion(&pHddCtx->driver_crda_req);
9730#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009731
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05309732#ifdef WLAN_FEATURE_EXTSCAN
9733 init_completion(&pHddCtx->ext_scan_context.response_event);
9734#endif /* WLAN_FEATURE_EXTSCAN */
9735
Kamath Vinayak4000c9a2013-08-23 14:24:27 +05309736 spin_lock_init(&pHddCtx->schedScan_lock);
9737
Jeff Johnson295189b2012-06-20 16:38:30 -07009738 hdd_list_init( &pHddCtx->hddAdapters, MAX_NUMBER_OF_ADAPTERS );
9739
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05309740#ifdef FEATURE_WLAN_TDLS
9741 /* tdls_lock is initialized before an hdd_open_adapter ( which is
9742 * invoked by other instances also) to protect the concurrent
9743 * access for the Adapters by TDLS module.
9744 */
9745 mutex_init(&pHddCtx->tdls_lock);
9746#endif
Siddharth Bhal76972212014-10-15 16:22:51 +05309747 mutex_init(&pHddCtx->spoofMacAddr.macSpoofingLock);
Mukul Sharma1fd6efd2015-02-14 00:29:14 +05309748 mutex_init(&pHddCtx->wmmLock);
9749
Srinivas Girigowda8bf64cb2015-09-30 19:50:09 +05309750 hdd_init_offloaded_packets_ctx(pHddCtx);
Agarwal Ashish1f422872014-07-22 00:11:55 +05309751 /* By default Strict Regulatory For FCC should be false */
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05309752
Agarwal Ashish1f422872014-07-22 00:11:55 +05309753 pHddCtx->nEnableStrictRegulatoryForFCC = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07009754 // Load all config first as TL config is needed during vos_open
9755 pHddCtx->cfg_ini = (hdd_config_t*) kmalloc(sizeof(hdd_config_t), GFP_KERNEL);
9756 if(pHddCtx->cfg_ini == NULL)
9757 {
9758 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Failed kmalloc hdd_config_t",__func__);
9759 goto err_free_hdd_context;
9760 }
9761
9762 vos_mem_zero(pHddCtx->cfg_ini, sizeof( hdd_config_t ));
9763
9764 // Read and parse the qcom_cfg.ini file
9765 status = hdd_parse_config_ini( pHddCtx );
9766 if ( VOS_STATUS_SUCCESS != status )
9767 {
9768 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: error parsing %s",
9769 __func__, WLAN_INI_FILE);
9770 goto err_config;
9771 }
Arif Hussaind5218912013-12-05 01:10:55 -08009772#ifdef MEMORY_DEBUG
9773 if (pHddCtx->cfg_ini->IsMemoryDebugSupportEnabled)
9774 vos_mem_init();
9775
9776 hddLog(VOS_TRACE_LEVEL_INFO, "%s: gEnableMemoryDebug=%d",
9777 __func__, pHddCtx->cfg_ini->IsMemoryDebugSupportEnabled);
9778#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009779
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +05309780 /* INI has been read, initialise the configuredMcastBcastFilter with
9781 * INI value as this will serve as the default value
9782 */
9783 pHddCtx->configuredMcastBcastFilter = pHddCtx->cfg_ini->mcastBcastFilterSetting;
9784 hddLog(VOS_TRACE_LEVEL_INFO, "Setting configuredMcastBcastFilter: %d",
9785 pHddCtx->cfg_ini->mcastBcastFilterSetting);
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05309786
9787 if (false == hdd_is_5g_supported(pHddCtx))
9788 {
9789 //5Ghz is not supported.
9790 if (1 != pHddCtx->cfg_ini->nBandCapability)
9791 {
9792 hddLog(VOS_TRACE_LEVEL_INFO,
9793 "%s: Setting pHddCtx->cfg_ini->nBandCapability = 1", __func__);
9794 pHddCtx->cfg_ini->nBandCapability = 1;
9795 }
9796 }
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +05309797
9798 /* If SNR Monitoring is enabled, FW has to parse all beacons
9799 * for calcaluting and storing the average SNR, so set Nth beacon
9800 * filter to 1 to enable FW to parse all the beaocons
9801 */
9802 if (1 == pHddCtx->cfg_ini->fEnableSNRMonitoring)
9803 {
9804 /* The log level is deliberately set to WARN as overriding
9805 * nthBeaconFilter to 1 will increase power cosumption and this
9806 * might just prove helpful to detect the power issue.
9807 */
9808 hddLog(VOS_TRACE_LEVEL_WARN,
9809 "%s: Setting pHddCtx->cfg_ini->nthBeaconFilter = 1", __func__);
9810 pHddCtx->cfg_ini->nthBeaconFilter = 1;
9811 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009812 /*
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309813 * cfg80211: Initialization ...
Jeff Johnson295189b2012-06-20 16:38:30 -07009814 */
Manjunathappa Prakasheec4ddf2014-01-13 18:23:51 -08009815 if (VOS_FTM_MODE != hdd_get_conparam())
Jeff Johnson295189b2012-06-20 16:38:30 -07009816 {
Manjunathappa Prakasheec4ddf2014-01-13 18:23:51 -08009817 if (0 < wlan_hdd_cfg80211_init(dev, wiphy, pHddCtx->cfg_ini))
9818 {
9819 hddLog(VOS_TRACE_LEVEL_FATAL,
9820 "%s: wlan_hdd_cfg80211_init return failure", __func__);
9821 goto err_config;
9822 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009823 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009824
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -08009825 // Update VOS trace levels based upon the cfg.ini
9826 hdd_vos_trace_enable(VOS_MODULE_ID_BAP,
9827 pHddCtx->cfg_ini->vosTraceEnableBAP);
9828 hdd_vos_trace_enable(VOS_MODULE_ID_TL,
9829 pHddCtx->cfg_ini->vosTraceEnableTL);
9830 hdd_vos_trace_enable(VOS_MODULE_ID_WDI,
9831 pHddCtx->cfg_ini->vosTraceEnableWDI);
9832 hdd_vos_trace_enable(VOS_MODULE_ID_HDD,
9833 pHddCtx->cfg_ini->vosTraceEnableHDD);
9834 hdd_vos_trace_enable(VOS_MODULE_ID_SME,
9835 pHddCtx->cfg_ini->vosTraceEnableSME);
9836 hdd_vos_trace_enable(VOS_MODULE_ID_PE,
9837 pHddCtx->cfg_ini->vosTraceEnablePE);
Katya Nigam70d68332013-09-16 16:49:45 +05309838 hdd_vos_trace_enable(VOS_MODULE_ID_PMC,
9839 pHddCtx->cfg_ini->vosTraceEnablePMC);
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -08009840 hdd_vos_trace_enable(VOS_MODULE_ID_WDA,
9841 pHddCtx->cfg_ini->vosTraceEnableWDA);
9842 hdd_vos_trace_enable(VOS_MODULE_ID_SYS,
9843 pHddCtx->cfg_ini->vosTraceEnableSYS);
9844 hdd_vos_trace_enable(VOS_MODULE_ID_VOSS,
9845 pHddCtx->cfg_ini->vosTraceEnableVOSS);
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -08009846 hdd_vos_trace_enable(VOS_MODULE_ID_SAP,
9847 pHddCtx->cfg_ini->vosTraceEnableSAP);
9848 hdd_vos_trace_enable(VOS_MODULE_ID_HDD_SOFTAP,
9849 pHddCtx->cfg_ini->vosTraceEnableHDDSAP);
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -08009850
Jeff Johnson295189b2012-06-20 16:38:30 -07009851 // Update WDI trace levels based upon the cfg.ini
9852 hdd_wdi_trace_enable(eWLAN_MODULE_DAL,
9853 pHddCtx->cfg_ini->wdiTraceEnableDAL);
9854 hdd_wdi_trace_enable(eWLAN_MODULE_DAL_CTRL,
9855 pHddCtx->cfg_ini->wdiTraceEnableCTL);
9856 hdd_wdi_trace_enable(eWLAN_MODULE_DAL_DATA,
9857 pHddCtx->cfg_ini->wdiTraceEnableDAT);
9858 hdd_wdi_trace_enable(eWLAN_MODULE_PAL,
9859 pHddCtx->cfg_ini->wdiTraceEnablePAL);
Jeff Johnson295189b2012-06-20 16:38:30 -07009860
Jeff Johnson88ba7742013-02-27 14:36:02 -08009861 if (VOS_FTM_MODE == hdd_get_conparam())
9862 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009863 if ( VOS_STATUS_SUCCESS != wlan_hdd_ftm_open(pHddCtx) )
9864 {
9865 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: wlan_hdd_ftm_open Failed",__func__);
9866 goto err_free_hdd_context;
9867 }
9868 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: FTM driver loaded success fully",__func__);
Sachin Ahuja38ef5e02015-03-13 17:31:16 +05309869 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_NO_LOAD_UNLOAD_IN_PROGRESS;
c_hpothu2de0ef62014-04-15 16:16:15 +05309870 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, FALSE);
Jeff Johnson295189b2012-06-20 16:38:30 -07009871 return VOS_STATUS_SUCCESS;
Jeff Johnson88ba7742013-02-27 14:36:02 -08009872 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009873
Katya Nigame7b69a82015-04-28 15:24:06 +05309874 if( VOS_MONITOR_MODE == hdd_get_conparam())
9875 {
9876 if ( VOS_STATUS_SUCCESS != wlan_hdd_mon_open(pHddCtx))
9877 {
9878 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: wlan_hdd_mon_open Failed",__func__);
9879 goto err_free_hdd_context;
9880 }
9881 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Driver loaded in Monitor Mode",__func__);
9882 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_NO_LOAD_UNLOAD_IN_PROGRESS;
9883 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, FALSE);
9884 return VOS_STATUS_SUCCESS;
9885 }
9886
Jeff Johnson88ba7742013-02-27 14:36:02 -08009887 //Open watchdog module
Jeff Johnson295189b2012-06-20 16:38:30 -07009888 if(pHddCtx->cfg_ini->fIsLogpEnabled)
9889 {
9890 status = vos_watchdog_open(pVosContext,
9891 &((VosContextType*)pVosContext)->vosWatchdog, sizeof(VosWatchdogContext));
9892
9893 if(!VOS_IS_STATUS_SUCCESS( status ))
9894 {
9895 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: vos_watchdog_open failed",__func__);
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309896 goto err_wdclose;
Jeff Johnson295189b2012-06-20 16:38:30 -07009897 }
9898 }
9899
9900 pHddCtx->isLogpInProgress = FALSE;
9901 vos_set_logp_in_progress(VOS_MODULE_ID_VOSS, FALSE);
9902
Amar Singhala49cbc52013-10-08 18:37:44 -07009903#ifdef CONFIG_ENABLE_LINUX_REG
Amar Singhal0a402232013-10-11 20:57:16 -07009904 /* initialize the NV module. This is required so that
9905 we can initialize the channel information in wiphy
9906 from the NV.bin data. The channel information in
9907 wiphy needs to be initialized before wiphy registration */
9908
9909 status = vos_nv_open();
9910 if (!VOS_IS_STATUS_SUCCESS(status))
9911 {
9912 /* NV module cannot be initialized */
9913 hddLog( VOS_TRACE_LEVEL_FATAL,
9914 "%s: vos_nv_open failed", __func__);
Vinay Krishna Eranna2025d892014-09-18 16:51:42 +05309915 goto err_wdclose;
Amar Singhal0a402232013-10-11 20:57:16 -07009916 }
9917
9918 status = vos_init_wiphy_from_nv_bin();
9919 if (!VOS_IS_STATUS_SUCCESS(status))
9920 {
9921 /* NV module cannot be initialized */
9922 hddLog( VOS_TRACE_LEVEL_FATAL,
9923 "%s: vos_init_wiphy failed", __func__);
9924 goto err_vos_nv_close;
9925 }
9926
Amar Singhala49cbc52013-10-08 18:37:44 -07009927#endif
Girish Gowlibf0e1ab2015-01-19 16:05:16 +05309928 vos_set_roam_delay_stats_enabled(pHddCtx->cfg_ini->gEnableRoamDelayStats);
Arun Kumar Khandavalliebb19482014-03-25 13:56:53 +05309929 status = vos_open( &pVosContext, pHddCtx->parent_dev);
Jeff Johnson295189b2012-06-20 16:38:30 -07009930 if ( !VOS_IS_STATUS_SUCCESS( status ))
9931 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009932 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: vos_open failed", __func__);
Mihir Shetee1093ba2014-01-21 20:13:32 +05309933 goto err_vos_nv_close;
Jeff Johnson295189b2012-06-20 16:38:30 -07009934 }
9935
Jeff Johnson295189b2012-06-20 16:38:30 -07009936 pHddCtx->hHal = (tHalHandle)vos_get_context( VOS_MODULE_ID_SME, pVosContext );
9937
9938 if ( NULL == pHddCtx->hHal )
9939 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009940 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: HAL context is null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009941 goto err_vosclose;
9942 }
9943
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009944 status = vos_preStart( pHddCtx->pvosContext );
9945 if ( !VOS_IS_STATUS_SUCCESS( status ) )
9946 {
9947 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: vos_preStart failed", __func__);
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05309948 goto err_vosclose;
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009949 }
Jeff Johnsone7245742012-09-05 17:12:55 -07009950
Arif Hussaineaf68602013-12-30 23:10:44 -08009951 if (0 == enable_dfs_chan_scan || 1 == enable_dfs_chan_scan)
9952 {
9953 pHddCtx->cfg_ini->enableDFSChnlScan = enable_dfs_chan_scan;
9954 hddLog(VOS_TRACE_LEVEL_INFO, "%s: module enable_dfs_chan_scan set to %d",
9955 __func__, enable_dfs_chan_scan);
9956 }
9957 if (0 == enable_11d || 1 == enable_11d)
9958 {
9959 pHddCtx->cfg_ini->Is11dSupportEnabled = enable_11d;
9960 hddLog(VOS_TRACE_LEVEL_INFO, "%s: module enable_11d set to %d",
9961 __func__, enable_11d);
9962 }
9963
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009964 /* Note that the vos_preStart() sequence triggers the cfg download.
9965 The cfg download must occur before we update the SME config
9966 since the SME config operation must access the cfg database */
Jeff Johnson295189b2012-06-20 16:38:30 -07009967 status = hdd_set_sme_config( pHddCtx );
9968
9969 if ( VOS_STATUS_SUCCESS != status )
9970 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009971 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Failed hdd_set_sme_config", __func__);
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05309972 goto err_vosclose;
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009973 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009974
Jeff Johnson295189b2012-06-20 16:38:30 -07009975 /* In the integrated architecture we update the configuration from
9976 the INI file and from NV before vOSS has been started so that
9977 the final contents are available to send down to the cCPU */
9978
9979 // Apply the cfg.ini to cfg.dat
9980 if (FALSE == hdd_update_config_dat(pHddCtx))
9981 {
9982 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: config update failed",__func__ );
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05309983 goto err_vosclose;
Jeff Johnson295189b2012-06-20 16:38:30 -07009984 }
9985
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05309986 // Get mac addr from platform driver
9987 ret = wcnss_get_wlan_mac_address((char*)&mac_addr.bytes);
9988
9989 if ((0 == ret) && (!vos_is_macaddr_zero(&mac_addr)))
Jeff Johnson295189b2012-06-20 16:38:30 -07009990 {
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05309991 /* Store the mac addr for first interface */
9992 pHddCtx->cfg_ini->intfMacAddr[0] = mac_addr;
9993
9994 hddLog(VOS_TRACE_LEVEL_ERROR,
9995 "%s: WLAN Mac Addr: "
9996 MAC_ADDRESS_STR, __func__,
9997 MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[0].bytes));
9998
9999 /* Here, passing Arg2 as 1 because we do not want to change the
10000 last 3 bytes (means non OUI bytes) of first interface mac
10001 addr.
10002 */
10003 if (0 != hdd_generate_iface_mac_addr_auto(pHddCtx, 1, mac_addr))
10004 {
10005 hddLog(VOS_TRACE_LEVEL_ERROR,
10006 "%s: Failed to generate wlan interface mac addr "
10007 "using MAC from ini file ", __func__);
10008 }
10009 }
10010 else if (VOS_STATUS_SUCCESS != hdd_update_config_from_nv(pHddCtx))
10011 {
10012 // Apply the NV to cfg.dat
10013 /* Prima Update MAC address only at here */
Jeff Johnson295189b2012-06-20 16:38:30 -070010014#ifdef WLAN_AUTOGEN_MACADDR_FEATURE
10015 /* There was not a valid set of MAC Addresses in NV. See if the
10016 default addresses were modified by the cfg.ini settings. If so,
10017 we'll use them, but if not, we'll autogenerate a set of MAC
10018 addresses based upon the device serial number */
10019
10020 static const v_MACADDR_t default_address =
10021 {{0x00, 0x0A, 0xF5, 0x89, 0x89, 0xFF}};
Jeff Johnson295189b2012-06-20 16:38:30 -070010022
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +053010023 if (0 == memcmp(&default_address, &pHddCtx->cfg_ini->intfMacAddr[0],
10024 sizeof(default_address)))
Jeff Johnson295189b2012-06-20 16:38:30 -070010025 {
10026 /* cfg.ini has the default address, invoke autogen logic */
10027
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +053010028 /* Here, passing Arg2 as 0 because we want to change the
10029 last 3 bytes (means non OUI bytes) of all the interfaces
10030 mac addr.
10031 */
10032 if (0 != hdd_generate_iface_mac_addr_auto(pHddCtx, 0,
10033 default_address))
Jeff Johnson295189b2012-06-20 16:38:30 -070010034 {
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +053010035 hddLog(VOS_TRACE_LEVEL_ERROR,
10036 "%s: Failed to generate wlan interface mac addr "
10037 "using MAC from ini file " MAC_ADDRESS_STR, __func__,
10038 MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[0].bytes));
Jeff Johnson295189b2012-06-20 16:38:30 -070010039 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010040 }
10041 else
10042#endif //WLAN_AUTOGEN_MACADDR_FEATURE
10043 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -080010044 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070010045 "%s: Invalid MAC address in NV, using MAC from ini file "
10046 MAC_ADDRESS_STR, __func__,
10047 MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[0].bytes));
10048 }
10049 }
10050 {
10051 eHalStatus halStatus;
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +053010052
10053 /* Set the MAC Address Currently this is used by HAL to
10054 * add self sta. Remove this once self sta is added as
10055 * part of session open.
10056 */
Jeff Johnson295189b2012-06-20 16:38:30 -070010057 halStatus = cfgSetStr( pHddCtx->hHal, WNI_CFG_STA_ID,
10058 (v_U8_t *)&pHddCtx->cfg_ini->intfMacAddr[0],
10059 sizeof( pHddCtx->cfg_ini->intfMacAddr[0]) );
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +053010060
Jeff Johnson295189b2012-06-20 16:38:30 -070010061 if (!HAL_STATUS_SUCCESS( halStatus ))
10062 {
10063 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Failed to set MAC Address. "
10064 "HALStatus is %08d [x%08x]",__func__, halStatus, halStatus );
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053010065 goto err_vosclose;
Jeff Johnson295189b2012-06-20 16:38:30 -070010066 }
10067 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010068
10069 /*Start VOSS which starts up the SME/MAC/HAL modules and everything else
10070 Note: Firmware image will be read and downloaded inside vos_start API */
10071 status = vos_start( pHddCtx->pvosContext );
10072 if ( !VOS_IS_STATUS_SUCCESS( status ) )
10073 {
10074 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: vos_start failed",__func__);
Hanumantha Reddy Pothula013bb412015-09-22 14:05:18 +053010075 VOS_BUG(0);
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053010076 goto err_vosclose;
Jeff Johnson295189b2012-06-20 16:38:30 -070010077 }
10078
Leo Chang6cec3e22014-01-21 15:33:49 -080010079#ifdef FEATURE_WLAN_CH_AVOID
10080 /* Plug in avoid channel notification callback
10081 * This should happen before ADD_SELF_STA
10082 * FW will send first IND with ADD_SELF_STA REQ from host */
Pradeep Reddy POTTETI5c2e16d2014-06-27 16:47:38 +053010083
10084 /* check the Channel Avoidance is enabled */
10085 if (TRUE == pHddCtx->cfg_ini->fenableCHAvoidance)
10086 {
10087 sme_AddChAvoidCallback(pHddCtx->hHal,
10088 hdd_hostapd_ch_avoid_cb);
10089 }
Leo Chang6cec3e22014-01-21 15:33:49 -080010090#endif /* FEATURE_WLAN_CH_AVOID */
10091
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -070010092 /* Exchange capability info between Host and FW and also get versioning info from FW */
10093 hdd_exchange_version_and_caps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -070010094
Agarwal Ashishad9281b2014-06-10 14:57:30 +053010095#ifdef CONFIG_ENABLE_LINUX_REG
10096 status = wlan_hdd_init_channels(pHddCtx);
10097 if ( !VOS_IS_STATUS_SUCCESS( status ) )
10098 {
10099 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: wlan_hdd_init_channels failed",
10100 __func__);
10101 goto err_vosstop;
10102 }
10103#endif
10104
Jeff Johnson295189b2012-06-20 16:38:30 -070010105 status = hdd_post_voss_start_config( pHddCtx );
10106 if ( !VOS_IS_STATUS_SUCCESS( status ) )
10107 {
10108 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hdd_post_voss_start_config failed",
10109 __func__);
10110 goto err_vosstop;
10111 }
Amar Singhala49cbc52013-10-08 18:37:44 -070010112
10113#ifndef CONFIG_ENABLE_LINUX_REG
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +053010114 wlan_hdd_cfg80211_update_reg_info( wiphy );
10115
10116 /* registration of wiphy dev with cfg80211 */
10117 if (0 > wlan_hdd_cfg80211_register(wiphy))
10118 {
10119 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy register failed", __func__);
10120 goto err_vosstop;
10121 }
Amar Singhala49cbc52013-10-08 18:37:44 -070010122#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010123
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053010124#ifdef CONFIG_ENABLE_LINUX_REG
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053010125 /* registration of wiphy dev with cfg80211 */
10126 if (0 > wlan_hdd_cfg80211_register(wiphy))
10127 {
10128 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy register failed", __func__);
10129 goto err_vosstop;
10130 }
10131
Agarwal Ashish6db9d532014-09-30 18:19:10 +053010132 status = wlan_hdd_init_channels_for_cc(pHddCtx, INIT);
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053010133 if ( !VOS_IS_STATUS_SUCCESS( status ) )
10134 {
10135 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: wlan_hdd_init_channels_for_cc failed",
10136 __func__);
10137 goto err_unregister_wiphy;
10138 }
10139#endif
10140
c_hpothu4a298be2014-12-22 21:12:51 +053010141 wcnss_wlan_set_drvdata(pHddCtx->parent_dev, pHddCtx);
10142
Jeff Johnson295189b2012-06-20 16:38:30 -070010143 if (VOS_STA_SAP_MODE == hdd_get_conparam())
10144 {
10145 pAdapter = hdd_open_adapter( pHddCtx, WLAN_HDD_SOFTAP, "softap.%d",
10146 wlan_hdd_get_intf_addr(pHddCtx), FALSE );
10147 }
10148 else
10149 {
Jeff Johnson295189b2012-06-20 16:38:30 -070010150 pAdapter = hdd_open_adapter( pHddCtx, WLAN_HDD_INFRA_STATION, "wlan%d",
10151 wlan_hdd_get_intf_addr(pHddCtx), FALSE );
10152 if (pAdapter != NULL)
10153 {
Katya Nigama7d81d72014-11-12 12:44:34 +053010154 if (pHddCtx->cfg_ini->isP2pDeviceAddrAdministrated && !(pHddCtx->cfg_ini->intfMacAddr[0].bytes[0] & 0x02))
Jeff Johnson295189b2012-06-20 16:38:30 -070010155 {
Gopichand Nakkala49f96f62013-02-06 14:38:17 +053010156 vos_mem_copy( pHddCtx->p2pDeviceAddress.bytes,
10157 pHddCtx->cfg_ini->intfMacAddr[0].bytes,
10158 sizeof(tSirMacAddr));
Madan Mohan Koyyalamudiedfc1b72012-10-18 20:25:55 -070010159
Gopichand Nakkala49f96f62013-02-06 14:38:17 +053010160 /* Generate the P2P Device Address. This consists of the device's
10161 * primary MAC address with the locally administered bit set.
10162 */
10163 pHddCtx->p2pDeviceAddress.bytes[0] |= 0x02;
Jeff Johnsone7245742012-09-05 17:12:55 -070010164 }
10165 else
10166 {
Gopichand Nakkala49f96f62013-02-06 14:38:17 +053010167 tANI_U8* p2p_dev_addr = wlan_hdd_get_intf_addr(pHddCtx);
10168 if (p2p_dev_addr != NULL)
10169 {
10170 vos_mem_copy(&pHddCtx->p2pDeviceAddress.bytes[0],
10171 p2p_dev_addr, VOS_MAC_ADDR_SIZE);
10172 }
10173 else
10174 {
10175 hddLog(VOS_TRACE_LEVEL_FATAL,
10176 "%s: Failed to allocate mac_address for p2p_device",
10177 __func__);
10178 goto err_close_adapter;
10179 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010180 }
Jeff Johnsone7245742012-09-05 17:12:55 -070010181
10182 pP2pAdapter = hdd_open_adapter( pHddCtx, WLAN_HDD_P2P_DEVICE, "p2p%d",
10183 &pHddCtx->p2pDeviceAddress.bytes[0], FALSE );
10184 if ( NULL == pP2pAdapter )
10185 {
10186 hddLog(VOS_TRACE_LEVEL_FATAL,
10187 "%s: Failed to do hdd_open_adapter for P2P Device Interface",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070010188 __func__);
Jeff Johnsone7245742012-09-05 17:12:55 -070010189 goto err_close_adapter;
10190 }
Jeff Johnsone7245742012-09-05 17:12:55 -070010191 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010192 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010193
10194 if( pAdapter == NULL )
10195 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -080010196 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: hdd_open_adapter failed", __func__);
10197 goto err_close_adapter;
Jeff Johnson295189b2012-06-20 16:38:30 -070010198 }
Jeff Johnsone7245742012-09-05 17:12:55 -070010199
Arif Hussain66559122013-11-21 10:11:40 -080010200 if (country_code)
10201 {
10202 eHalStatus ret;
Arif Hussaincb607082013-12-20 11:57:42 -080010203 INIT_COMPLETION(pAdapter->change_country_code);
Arif Hussain66559122013-11-21 10:11:40 -080010204 hdd_checkandupdate_dfssetting(pAdapter, country_code);
10205#ifndef CONFIG_ENABLE_LINUX_REG
10206 hdd_checkandupdate_phymode(pAdapter, country_code);
10207#endif
Arif Hussaineaf68602013-12-30 23:10:44 -080010208 ret = sme_ChangeCountryCode(pHddCtx->hHal,
10209 (void *)(tSmeChangeCountryCallback)
10210 wlan_hdd_change_country_code_callback,
Arif Hussain66559122013-11-21 10:11:40 -080010211 country_code,
10212 pAdapter, pHddCtx->pvosContext,
Abhishek Singha306a442013-11-07 18:39:01 +053010213 eSIR_TRUE, eSIR_TRUE);
Arif Hussain66559122013-11-21 10:11:40 -080010214 if (eHAL_STATUS_SUCCESS == ret)
10215 {
Arif Hussaincb607082013-12-20 11:57:42 -080010216 ret = wait_for_completion_interruptible_timeout(
10217 &pAdapter->change_country_code,
10218 msecs_to_jiffies(WLAN_WAIT_TIME_COUNTRY));
10219
10220 if (0 >= ret)
10221 {
10222 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
10223 "%s: SME while setting country code timed out", __func__);
10224 }
Arif Hussain66559122013-11-21 10:11:40 -080010225 }
10226 else
10227 {
Arif Hussaincb607082013-12-20 11:57:42 -080010228 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
10229 "%s: SME Change Country code from module param fail ret=%d",
10230 __func__, ret);
Arif Hussain66559122013-11-21 10:11:40 -080010231 }
10232 }
10233
Jeff Johnson295189b2012-06-20 16:38:30 -070010234#ifdef WLAN_BTAMP_FEATURE
10235 vStatus = WLANBAP_Open(pVosContext);
10236 if(!VOS_IS_STATUS_SUCCESS(vStatus))
10237 {
10238 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
10239 "%s: Failed to open BAP",__func__);
Jeff Johnsone7245742012-09-05 17:12:55 -070010240 goto err_close_adapter;
Jeff Johnson295189b2012-06-20 16:38:30 -070010241 }
10242
10243 vStatus = BSL_Init(pVosContext);
10244 if(!VOS_IS_STATUS_SUCCESS(vStatus))
10245 {
10246 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
10247 "%s: Failed to Init BSL",__func__);
10248 goto err_bap_close;
10249 }
10250 vStatus = WLANBAP_Start(pVosContext);
10251 if (!VOS_IS_STATUS_SUCCESS(vStatus))
10252 {
10253 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
10254 "%s: Failed to start TL",__func__);
10255 goto err_bap_close;
10256 }
10257
10258 pConfig = pHddCtx->cfg_ini;
10259 btAmpConfig.ucPreferredChannel = pConfig->preferredChannel;
10260 status = WLANBAP_SetConfig(&btAmpConfig);
10261
10262#endif //WLAN_BTAMP_FEATURE
Jeff Johnsone7245742012-09-05 17:12:55 -070010263
Mihir Shete9c238772014-10-15 14:35:16 +053010264 /*
10265 * UapsdMask is 0xf if U-APSD is enbaled for all AC's...
10266 * The value of CFG_QOS_WMM_UAPSD_MASK_DEFAULT is 0xaa(Magic Value)
10267 * which is greater than 0xf. So the below check is safe to make
10268 * sure that there is no entry for UapsdMask in the ini
10269 */
10270 if (CFG_QOS_WMM_UAPSD_MASK_DEFAULT == pHddCtx->cfg_ini->UapsdMask)
10271 {
10272 if(IS_DYNAMIC_WMM_PS_ENABLED)
10273 {
10274 hddLog(VOS_TRACE_LEVEL_DEBUG,"%s: Enable UAPSD for VI & VO",
10275 __func__);
10276 pHddCtx->cfg_ini->UapsdMask =
10277 CFG_QOS_WMM_UAPSD_MASK_DYMANIC_WMM_PS_DEFAULT;
10278 }
10279 else
10280 {
10281 hddLog(VOS_TRACE_LEVEL_DEBUG,"%s: Do not enable UAPSD",
10282 __func__);
10283 pHddCtx->cfg_ini->UapsdMask =
10284 CFG_QOS_WMM_UAPSD_MASK_LEGACY_WMM_PS_DEFAULT;
10285 }
10286 }
10287
Varun Reddy Yeturud0a3f252013-04-15 21:58:13 -070010288#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
10289 if(!(IS_ROAM_SCAN_OFFLOAD_FEATURE_ENABLE))
10290 {
10291 hddLog(VOS_TRACE_LEVEL_DEBUG,"%s: ROAM_SCAN_OFFLOAD Feature not supported",__func__);
10292 pHddCtx->cfg_ini->isRoamOffloadScanEnabled = 0;
10293 sme_UpdateRoamScanOffloadEnabled((tHalHandle)(pHddCtx->hHal),
10294 pHddCtx->cfg_ini->isRoamOffloadScanEnabled);
10295 }
10296#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010297
Agarwal Ashish4b87f922014-06-18 03:03:21 +053010298 wlan_hdd_tdls_init(pHddCtx);
10299
Mihir Shetefc7ff5b2014-01-27 11:30:05 +053010300 sme_Register11dScanDoneCallback(pHddCtx->hHal, hdd_11d_scan_done);
10301
Jeff Johnson295189b2012-06-20 16:38:30 -070010302 /* Register with platform driver as client for Suspend/Resume */
10303 status = hddRegisterPmOps(pHddCtx);
10304 if ( !VOS_IS_STATUS_SUCCESS( status ) )
10305 {
10306 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddRegisterPmOps failed",__func__);
10307#ifdef WLAN_BTAMP_FEATURE
10308 goto err_bap_stop;
10309#else
Jeff Johnsone7245742012-09-05 17:12:55 -070010310 goto err_close_adapter;
Jeff Johnson295189b2012-06-20 16:38:30 -070010311#endif //WLAN_BTAMP_FEATURE
10312 }
10313
Yue Ma0d4891e2013-08-06 17:01:45 -070010314 /* Open debugfs interface */
10315 if (VOS_STATUS_SUCCESS != hdd_debugfs_init(pAdapter))
10316 {
10317 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
10318 "%s: hdd_debugfs_init failed!", __func__);
Yue Ma0d4891e2013-08-06 17:01:45 -070010319 }
10320
Jeff Johnson295189b2012-06-20 16:38:30 -070010321 /* Register TM level change handler function to the platform */
10322 status = hddDevTmRegisterNotifyCallback(pHddCtx);
10323 if ( !VOS_IS_STATUS_SUCCESS( status ) )
10324 {
10325 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddDevTmRegisterNotifyCallback failed",__func__);
10326 goto err_unregister_pmops;
10327 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010328
Jeff Johnson295189b2012-06-20 16:38:30 -070010329 // register net device notifier for device change notification
10330 ret = register_netdevice_notifier(&hdd_netdev_notifier);
10331
10332 if(ret < 0)
10333 {
10334 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: register_netdevice_notifier failed",__func__);
Siddharth Bhalcd92b782015-06-29 12:25:40 +053010335 goto err_unregister_pmops;
Jeff Johnson295189b2012-06-20 16:38:30 -070010336 }
10337
10338 //Initialize the nlink service
10339 if(nl_srv_init() != 0)
10340 {
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +053010341 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: nl_srv_init failed", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070010342 goto err_reg_netdev;
10343 }
10344
Leo Chang4ce1cc52013-10-21 18:27:15 -070010345#ifdef WLAN_KD_READY_NOTIFIER
10346 pHddCtx->kd_nl_init = 1;
10347#endif /* WLAN_KD_READY_NOTIFIER */
10348
Jeff Johnson295189b2012-06-20 16:38:30 -070010349 //Initialize the BTC service
10350 if(btc_activate_service(pHddCtx) != 0)
10351 {
10352 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: btc_activate_service failed",__func__);
10353 goto err_nl_srv;
10354 }
10355
Padma, Santhosh Kumar2762e9d2015-10-20 15:02:57 +053010356#ifdef FEATURE_OEM_DATA_SUPPORT
10357 //Initialize the OEM service
10358 if (oem_activate_service(pHddCtx) != 0)
10359 {
10360 hddLog(VOS_TRACE_LEVEL_FATAL,
10361 "%s: oem_activate_service failed", __func__);
10362 goto err_nl_srv;
10363 }
10364#endif
10365
Jeff Johnson295189b2012-06-20 16:38:30 -070010366#ifdef PTT_SOCK_SVC_ENABLE
10367 //Initialize the PTT service
10368 if(ptt_sock_activate_svc(pHddCtx) != 0)
10369 {
10370 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: ptt_sock_activate_svc failed",__func__);
10371 goto err_nl_srv;
10372 }
10373#endif
10374
Vinay Krishna Erannad938c422014-03-10 17:14:21 +053010375#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
10376 if(pHddCtx->cfg_ini && pHddCtx->cfg_ini->wlanLoggingEnable)
10377 {
Deepthi Gowri78083a32014-11-04 12:55:51 +053010378 if(wlan_logging_sock_activate_svc(
10379 pHddCtx->cfg_ini->wlanLoggingFEToConsole,
Sushant Kaushik33200572015-08-05 16:46:20 +053010380 pHddCtx->cfg_ini->wlanLoggingNumBuf,
10381 pHddCtx->cfg_ini->wlanPerPktStatsLogEnable,
10382 pHddCtx->cfg_ini->wlanPerPktStatsNumBuf))
Deepthi Gowri78083a32014-11-04 12:55:51 +053010383 {
10384 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wlan_logging_sock_activate_svc"
10385 " failed", __func__);
10386 goto err_nl_srv;
10387 }
10388 //TODO: To Remove enableDhcpDebug and use gEnableDebugLog for
10389 //EAPOL and DHCP
Sachin Ahuja8c65f382014-12-12 15:34:21 +053010390 if (!pHddCtx->cfg_ini->gEnableDebugLog)
10391 pHddCtx->cfg_ini->gEnableDebugLog =
Sushant Kaushik6e4e2bc2015-10-05 17:23:07 +053010392 VOS_PKT_PROTO_TYPE_EAPOL | VOS_PKT_PROTO_TYPE_DHCP |
10393 VOS_PKT_PROTO_TYPE_ARP;
Vinay Krishna Erannad938c422014-03-10 17:14:21 +053010394 }
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053010395
Siddharth Bhald1be97f2015-05-27 22:39:59 +053010396 if (pHddCtx->cfg_ini->wlanLoggingEnable &&
10397 (pHddCtx->cfg_ini->enableFWLogging ||
Siddharth Bhaldb963232015-06-25 19:34:35 +053010398 pHddCtx->cfg_ini->enableMgmtLogging ||
c_manjeecfd1efb2015-09-25 19:32:34 +053010399 pHddCtx->cfg_ini->enableContFWLogging ||
10400 pHddCtx->cfg_ini->enableFwrMemDump )
10401 )
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053010402 {
Siddharth Bhald1be97f2015-05-27 22:39:59 +053010403 hdd_init_frame_logging(pHddCtx);
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053010404 }
10405 else
10406 {
Siddharth Bhald1be97f2015-05-27 22:39:59 +053010407 hddLog(VOS_TRACE_LEVEL_INFO, FL("Logging disabled in ini"));
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053010408 }
10409
Vinay Krishna Erannad938c422014-03-10 17:14:21 +053010410#endif
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053010411
10412
Sushant Kaushik215778f2015-05-21 14:05:36 +053010413 if (vos_is_multicast_logging())
10414 wlan_logging_set_log_level();
10415
Jeff Johnson295189b2012-06-20 16:38:30 -070010416 hdd_register_mcast_bcast_filter(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -070010417 if (VOS_STA_SAP_MODE != hdd_get_conparam())
Jeff Johnson295189b2012-06-20 16:38:30 -070010418 {
Madan Mohan Koyyalamudic537df22012-10-22 15:07:08 -070010419 /* Action frame registered in one adapter which will
10420 * applicable to all interfaces
10421 */
Agarwal Ashish8fa0e9a2014-05-23 00:40:12 +053010422 wlan_hdd_cfg80211_register_frames(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070010423 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010424
10425 mutex_init(&pHddCtx->sap_lock);
Mahesh A Saptasagar60627942014-10-13 13:55:14 +053010426 mutex_init(&pHddCtx->roc_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -070010427
Jeff Johnsone7245742012-09-05 17:12:55 -070010428#ifdef WLAN_FEATURE_HOLD_RX_WAKELOCK
10429 /* Initialize the wake lcok */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053010430 vos_wake_lock_init(&pHddCtx->rx_wake_lock,
Jeff Johnsone7245742012-09-05 17:12:55 -070010431 "qcom_rx_wakelock");
Sushant Kaushik83392fa2015-05-05 17:44:40 +053010432
Jeff Johnsone7245742012-09-05 17:12:55 -070010433#endif
Madan Mohan Koyyalamudi69fc3ad2012-11-28 16:04:56 -080010434 /* Initialize the wake lcok */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053010435 vos_wake_lock_init(&pHddCtx->sap_wake_lock,
Madan Mohan Koyyalamudi69fc3ad2012-11-28 16:04:56 -080010436 "qcom_sap_wakelock");
Sushant Kaushik83392fa2015-05-05 17:44:40 +053010437
Jeff Johnsone7245742012-09-05 17:12:55 -070010438
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070010439 vos_event_init(&pHddCtx->scan_info.scan_finished_event);
10440 pHddCtx->scan_info.scan_pending_option = WEXT_SCAN_PENDING_GIVEUP;
Jeff Johnson295189b2012-06-20 16:38:30 -070010441
Katya Nigam5c306ea2014-06-19 15:39:54 +053010442 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_NO_LOAD_UNLOAD_IN_PROGRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -070010443 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, FALSE);
Sushant Kaushik83392fa2015-05-05 17:44:40 +053010444 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_DRIVER_INIT);
Katya Nigam5c306ea2014-06-19 15:39:54 +053010445
10446#ifdef FEATURE_WLAN_SCAN_PNO
10447 /*SME must send channel update configuration to RIVA*/
10448 sme_UpdateChannelConfig(pHddCtx->hHal);
10449#endif
Abhishek Singhf644b272014-08-21 02:59:39 +053010450 /* Send the update default channel list to the FW*/
10451 sme_UpdateChannelList(pHddCtx->hHal);
Mukul Sharma45063942015-04-01 20:07:59 +053010452
10453 /* Fwr capabilities received, Set the Dot11 mode */
10454 sme_SetDefDot11Mode(pHddCtx->hHal);
10455
Abhishek Singha306a442013-11-07 18:39:01 +053010456#ifndef CONFIG_ENABLE_LINUX_REG
10457 /*updating wiphy so that regulatory user hints can be processed*/
10458 if (wiphy)
10459 {
10460 regulatory_hint(wiphy, "00");
10461 }
10462#endif
Jeff Johnsone7245742012-09-05 17:12:55 -070010463 // Initialize the restart logic
10464 wlan_hdd_restart_init(pHddCtx);
Chilam NG571c65a2013-01-19 12:27:36 +053010465
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -070010466 //Register the traffic monitor timer now
10467 if ( pHddCtx->cfg_ini->dynSplitscan)
10468 {
10469 vos_timer_init(&pHddCtx->tx_rx_trafficTmr,
10470 VOS_TIMER_TYPE_SW,
10471 hdd_tx_rx_pkt_cnt_stat_timer_handler,
10472 (void *)pHddCtx);
10473 }
Srinivas Dasari030bad32015-02-18 23:23:54 +053010474 wlan_hdd_cfg80211_nan_init(pHddCtx);
10475
Dino Mycle6fb96c12014-06-10 11:52:40 +053010476#ifdef WLAN_FEATURE_EXTSCAN
10477 sme_EXTScanRegisterCallback(pHddCtx->hHal,
10478 wlan_hdd_cfg80211_extscan_callback,
10479 pHddCtx);
10480#endif /* WLAN_FEATURE_EXTSCAN */
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +053010481
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053010482#ifdef FEATURE_OEM_DATA_SUPPORT
10483 sme_OemDataRegisterCallback(pHddCtx->hHal,
10484 wlan_hdd_cfg80211_oemdata_callback,
10485 pHddCtx);
10486#endif /* FEATURE_OEM_DATA_SUPPORT */
10487
Gupta, Kapil7c34b322015-09-30 13:12:35 +053010488 sme_set_rssi_threshold_breached_cb(pHddCtx->hHal, hdd_rssi_threshold_breached_cb);
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +053010489#ifdef WLAN_NS_OFFLOAD
10490 // Register IPv6 notifier to notify if any change in IP
10491 // So that we can reconfigure the offload parameters
10492 pHddCtx->ipv6_notifier.notifier_call = wlan_hdd_ipv6_changed;
10493 ret = register_inet6addr_notifier(&pHddCtx->ipv6_notifier);
10494 if (ret)
10495 {
Ratheesh S P36dbc932015-08-07 14:28:57 +053010496 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to register IPv6 notifier"));
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +053010497 }
10498 else
10499 {
Ratheesh S P36dbc932015-08-07 14:28:57 +053010500 hddLog(VOS_TRACE_LEVEL_INFO, FL("Registered IPv6 notifier"));
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +053010501 }
10502#endif
10503
10504 // Register IPv4 notifier to notify if any change in IP
10505 // So that we can reconfigure the offload parameters
10506 pHddCtx->ipv4_notifier.notifier_call = wlan_hdd_ipv4_changed;
10507 ret = register_inetaddr_notifier(&pHddCtx->ipv4_notifier);
10508 if (ret)
10509 {
Ratheesh S P36dbc932015-08-07 14:28:57 +053010510 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to register IPv4 notifier"));
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +053010511 }
10512 else
10513 {
Ratheesh S P36dbc932015-08-07 14:28:57 +053010514 hddLog(VOS_TRACE_LEVEL_INFO, FL("Registered IPv4 notifier"));
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +053010515 }
c_manjeecfd1efb2015-09-25 19:32:34 +053010516 /*Fw mem dump procfs initialization*/
10517 memdump_init();
Bhargav shah23c94942015-10-13 12:48:35 +053010518 hdd_dp_util_send_rps_ind(pHddCtx);
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +053010519
Jeff Johnson295189b2012-06-20 16:38:30 -070010520 goto success;
10521
10522err_nl_srv:
Leo Chang59cdc7e2013-07-10 10:08:21 -070010523#ifdef WLAN_KD_READY_NOTIFIER
10524 nl_srv_exit(pHddCtx->ptt_pid);
10525#else
Jeff Johnson295189b2012-06-20 16:38:30 -070010526 nl_srv_exit();
Leo Chang59cdc7e2013-07-10 10:08:21 -070010527#endif /* WLAN_KD_READY_NOTIFIER */
Jeff Johnson295189b2012-06-20 16:38:30 -070010528err_reg_netdev:
10529 unregister_netdevice_notifier(&hdd_netdev_notifier);
10530
Jeff Johnson295189b2012-06-20 16:38:30 -070010531err_unregister_pmops:
10532 hddDevTmUnregisterNotifyCallback(pHddCtx);
10533 hddDeregisterPmOps(pHddCtx);
10534
Yue Ma0d4891e2013-08-06 17:01:45 -070010535 hdd_debugfs_exit(pHddCtx);
10536
Jeff Johnson295189b2012-06-20 16:38:30 -070010537#ifdef WLAN_BTAMP_FEATURE
10538err_bap_stop:
10539 WLANBAP_Stop(pVosContext);
10540#endif
10541
10542#ifdef WLAN_BTAMP_FEATURE
10543err_bap_close:
10544 WLANBAP_Close(pVosContext);
10545#endif
10546
Jeff Johnson295189b2012-06-20 16:38:30 -070010547err_close_adapter:
10548 hdd_close_all_adapters( pHddCtx );
Mahesh A Saptasagar9ecefe42014-07-15 18:43:49 +053010549#ifdef CONFIG_ENABLE_LINUX_REG
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053010550err_unregister_wiphy:
Mahesh A Saptasagar9ecefe42014-07-15 18:43:49 +053010551#endif
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +053010552 wiphy_unregister(wiphy) ;
Jeff Johnson295189b2012-06-20 16:38:30 -070010553err_vosstop:
10554 vos_stop(pVosContext);
10555
Amar Singhala49cbc52013-10-08 18:37:44 -070010556err_vosclose:
Jeff Johnson295189b2012-06-20 16:38:30 -070010557 status = vos_sched_close( pVosContext );
10558 if (!VOS_IS_STATUS_SUCCESS(status)) {
10559 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
10560 "%s: Failed to close VOSS Scheduler", __func__);
10561 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( status ) );
10562 }
Amar Singhala49cbc52013-10-08 18:37:44 -070010563 vos_close(pVosContext );
10564
Amar Singhal0a402232013-10-11 20:57:16 -070010565err_vos_nv_close:
10566
c_hpothue6a36282014-03-19 12:27:38 +053010567#ifdef CONFIG_ENABLE_LINUX_REG
Amar Singhal0a402232013-10-11 20:57:16 -070010568 vos_nv_close();
10569
c_hpothu70f8d812014-03-22 22:59:23 +053010570#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010571
10572err_wdclose:
10573 if(pHddCtx->cfg_ini->fIsLogpEnabled)
10574 vos_watchdog_close(pVosContext);
10575
Jeff Johnson295189b2012-06-20 16:38:30 -070010576err_config:
10577 kfree(pHddCtx->cfg_ini);
10578 pHddCtx->cfg_ini= NULL;
10579
10580err_free_hdd_context:
Sushant Kaushik83392fa2015-05-05 17:44:40 +053010581 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_DRIVER_INIT);
Siddharth Bhalcd92b782015-06-29 12:25:40 +053010582 free_riva_power_on_lock("wlan");
Jeff Johnson295189b2012-06-20 16:38:30 -070010583 wiphy_free(wiphy) ;
10584 //kfree(wdev) ;
Jeff Johnson295189b2012-06-20 16:38:30 -070010585 VOS_BUG(1);
10586
Madan Mohan Koyyalamudid57ae632012-11-06 18:42:48 -080010587 if (hdd_is_ssr_required())
10588 {
10589 /* WDI timeout had happened during load, so SSR is needed here */
10590 subsystem_restart("wcnss");
10591 msleep(5000);
10592 }
10593 hdd_set_ssr_required (VOS_FALSE);
10594
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -080010595 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -070010596
10597success:
10598 EXIT();
10599 return 0;
10600}
10601
10602/**---------------------------------------------------------------------------
10603
Jeff Johnson32d95a32012-09-10 13:15:23 -070010604 \brief hdd_driver_init() - Core Driver Init Function
Jeff Johnson295189b2012-06-20 16:38:30 -070010605
Jeff Johnson32d95a32012-09-10 13:15:23 -070010606 This is the driver entry point - called in different timeline depending
10607 on whether the driver is statically or dynamically linked
Jeff Johnson295189b2012-06-20 16:38:30 -070010608
10609 \param - None
10610
10611 \return - 0 for success, non zero for failure
10612
10613 --------------------------------------------------------------------------*/
Jeff Johnson32d95a32012-09-10 13:15:23 -070010614static int hdd_driver_init( void)
Jeff Johnson295189b2012-06-20 16:38:30 -070010615{
10616 VOS_STATUS status;
10617 v_CONTEXT_t pVosContext = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070010618 struct device *dev = NULL;
10619 int ret_status = 0;
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -070010620#ifdef HAVE_WCNSS_CAL_DOWNLOAD
10621 int max_retries = 0;
10622#endif
Siddharth Bhalc7e79b62014-10-10 22:37:38 +053010623#ifdef HAVE_CBC_DONE
10624 int max_cbc_retries = 0;
10625#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010626
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +053010627#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
10628 wlan_logging_sock_init_svc();
10629#endif
10630
Jeff Johnson295189b2012-06-20 16:38:30 -070010631 ENTER();
10632
Sushant Kaushik83392fa2015-05-05 17:44:40 +053010633 vos_wake_lock_init(&wlan_wake_lock, "wlan");
Jeff Johnson295189b2012-06-20 16:38:30 -070010634
10635 pr_info("%s: loading driver v%s\n", WLAN_MODULE_NAME,
10636 QWLAN_VERSIONSTR TIMER_MANAGER_STR MEMORY_DEBUG_STR);
10637
Jeff Johnson295189b2012-06-20 16:38:30 -070010638#ifdef ANI_BUS_TYPE_PCI
10639
10640 dev = wcnss_wlan_get_device();
10641
10642#endif // ANI_BUS_TYPE_PCI
10643
10644#ifdef ANI_BUS_TYPE_PLATFORM
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -070010645
10646#ifdef HAVE_WCNSS_CAL_DOWNLOAD
10647 /* wait until WCNSS driver downloads NV */
10648 while (!wcnss_device_ready() && 5 >= ++max_retries) {
10649 msleep(1000);
10650 }
Siddharth Bhalc7e79b62014-10-10 22:37:38 +053010651
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -070010652 if (max_retries >= 5) {
10653 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: WCNSS driver not ready", __func__);
Sushant Kaushik83392fa2015-05-05 17:44:40 +053010654 vos_wake_lock_destroy(&wlan_wake_lock);
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +053010655#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
10656 wlan_logging_sock_deinit_svc();
10657#endif
10658
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -070010659 return -ENODEV;
10660 }
10661#endif
10662
Siddharth Bhalc7e79b62014-10-10 22:37:38 +053010663#ifdef HAVE_CBC_DONE
10664 while (!wcnss_cbc_complete() && 10 >= ++max_cbc_retries) {
10665 msleep(1000);
10666 }
10667 if (max_cbc_retries >= 10) {
10668 hddLog(VOS_TRACE_LEVEL_FATAL, "%s:CBC not completed", __func__);
10669 }
10670#endif
10671
Jeff Johnson295189b2012-06-20 16:38:30 -070010672 dev = wcnss_wlan_get_device();
10673#endif // ANI_BUS_TYPE_PLATFORM
10674
10675
10676 do {
10677 if (NULL == dev) {
10678 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: WLAN device not found!!",__func__);
10679 ret_status = -1;
10680 break;
10681 }
10682
Jeff Johnson295189b2012-06-20 16:38:30 -070010683#ifdef TIMER_MANAGER
10684 vos_timer_manager_init();
10685#endif
10686
10687 /* Preopen VOSS so that it is ready to start at least SAL */
10688 status = vos_preOpen(&pVosContext);
10689
10690 if (!VOS_IS_STATUS_SUCCESS(status))
10691 {
10692 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Failed to preOpen VOSS", __func__);
10693 ret_status = -1;
10694 break;
10695 }
10696
Sushant Kaushik02beb352015-06-04 15:15:01 +053010697 hddTraceInit();
Padma, Santhosh Kumar9093b202015-07-21 15:37:38 +053010698 hdd_register_debug_callback();
10699
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010700#ifndef MODULE
10701 /* For statically linked driver, call hdd_set_conparam to update curr_con_mode
10702 */
10703 hdd_set_conparam((v_UINT_t)con_mode);
10704#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010705
10706 // Call our main init function
Jeff Johnsonbc676b42013-02-14 16:04:08 -080010707 if (hdd_wlan_startup(dev))
10708 {
Jeff Johnson295189b2012-06-20 16:38:30 -070010709 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: WLAN Driver Initialization failed",
Jeff Johnsonbc676b42013-02-14 16:04:08 -080010710 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070010711 vos_preClose( &pVosContext );
10712 ret_status = -1;
10713 break;
10714 }
10715
Jeff Johnson295189b2012-06-20 16:38:30 -070010716 } while (0);
10717
10718 if (0 != ret_status)
10719 {
Jeff Johnson295189b2012-06-20 16:38:30 -070010720#ifdef TIMER_MANAGER
10721 vos_timer_exit();
10722#endif
10723#ifdef MEMORY_DEBUG
10724 vos_mem_exit();
10725#endif
Sushant Kaushik83392fa2015-05-05 17:44:40 +053010726 vos_wake_lock_destroy(&wlan_wake_lock);
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +053010727#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
10728 wlan_logging_sock_deinit_svc();
10729#endif
10730
Jeff Johnson295189b2012-06-20 16:38:30 -070010731 pr_err("%s: driver load failure\n", WLAN_MODULE_NAME);
10732 }
10733 else
10734 {
10735 //Send WLAN UP indication to Nlink Service
10736 send_btc_nlink_msg(WLAN_MODULE_UP_IND, 0);
10737
10738 pr_info("%s: driver loaded\n", WLAN_MODULE_NAME);
Jeff Johnson295189b2012-06-20 16:38:30 -070010739 }
10740
10741 EXIT();
10742
10743 return ret_status;
10744}
10745
Jeff Johnson32d95a32012-09-10 13:15:23 -070010746/**---------------------------------------------------------------------------
10747
10748 \brief hdd_module_init() - Init Function
10749
10750 This is the driver entry point (invoked when module is loaded using insmod)
10751
10752 \param - None
10753
10754 \return - 0 for success, non zero for failure
10755
10756 --------------------------------------------------------------------------*/
10757#ifdef MODULE
10758static int __init hdd_module_init ( void)
10759{
10760 return hdd_driver_init();
10761}
Jeff Johnson32d95a32012-09-10 13:15:23 -070010762#else /* #ifdef MODULE */
10763static int __init hdd_module_init ( void)
10764{
10765 /* Driver initialization is delayed to fwpath_changed_handler */
10766 return 0;
10767}
Jeff Johnson32d95a32012-09-10 13:15:23 -070010768#endif /* #ifdef MODULE */
10769
Jeff Johnson295189b2012-06-20 16:38:30 -070010770
10771/**---------------------------------------------------------------------------
10772
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010773 \brief hdd_driver_exit() - Exit function
Jeff Johnson295189b2012-06-20 16:38:30 -070010774
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010775 This is the driver exit point (invoked when module is unloaded using rmmod
10776 or con_mode was changed by userspace)
Jeff Johnson295189b2012-06-20 16:38:30 -070010777
10778 \param - None
10779
10780 \return - None
10781
10782 --------------------------------------------------------------------------*/
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010783static void hdd_driver_exit(void)
Jeff Johnson295189b2012-06-20 16:38:30 -070010784{
10785 hdd_context_t *pHddCtx = NULL;
10786 v_CONTEXT_t pVosContext = NULL;
Agarwal Ashish5e414792014-06-08 15:25:23 +053010787 v_REGDOMAIN_t regId;
Arun Kumar Khandavallie0b046d2014-03-01 21:54:25 +053010788 unsigned long rc = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070010789
10790 pr_info("%s: unloading driver v%s\n", WLAN_MODULE_NAME, QWLAN_VERSIONSTR);
10791
10792 //Get the global vos context
10793 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
10794
10795 if(!pVosContext)
10796 {
10797 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Global VOS context is Null", __func__);
10798 goto done;
10799 }
10800
10801 //Get the HDD context.
10802 pHddCtx = (hdd_context_t *)vos_get_context(VOS_MODULE_ID_HDD, pVosContext );
10803
10804 if(!pHddCtx)
10805 {
10806 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: module exit called before probe",__func__);
10807 }
Katya Nigame7b69a82015-04-28 15:24:06 +053010808 else if (VOS_MONITOR_MODE == hdd_get_conparam())
10809 {
10810 hddLog(VOS_TRACE_LEVEL_INFO,"%s: MONITOR MODE",__func__);
10811 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_UNLOAD_IN_PROGRESS;
10812 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, TRUE);
10813 hdd_wlan_exit(pHddCtx);
10814 vos_preClose( &pVosContext );
10815 goto done;
10816 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010817 else
10818 {
Siddharth Bhal2e5871b2015-03-24 16:20:51 +053010819 /* We wait for active entry threads to exit from driver
10820 * by waiting until rtnl_lock is available.
10821 */
10822 rtnl_lock();
10823 rtnl_unlock();
10824
Siddharth Bhal3c29dca2015-02-19 00:41:40 +053010825 INIT_COMPLETION(pHddCtx->ssr_comp_var);
10826 if ((pHddCtx->isLogpInProgress) && (FALSE ==
10827 vos_is_wlan_in_badState(VOS_MODULE_ID_HDD, NULL)))
10828 {
Siddharth Bhala204f572015-01-17 02:03:36 +053010829 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Siddharth Bhal3c29dca2015-02-19 00:41:40 +053010830 "%s:SSR in Progress; block rmmod !!!", __func__);
Siddharth Bhala204f572015-01-17 02:03:36 +053010831 rc = wait_for_completion_timeout(&pHddCtx->ssr_comp_var,
10832 msecs_to_jiffies(30000));
10833 if(!rc)
10834 {
10835 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
10836 "%s:SSR timedout, fatal error", __func__);
10837 VOS_BUG(0);
10838 }
10839 }
10840
Siddharth Bhal3c29dca2015-02-19 00:41:40 +053010841 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_UNLOAD_IN_PROGRESS;
10842 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, TRUE);
Jeff Johnson295189b2012-06-20 16:38:30 -070010843
c_hpothu8adb97b2014-12-08 19:38:20 +053010844 /* Driver Need to send country code 00 in below condition
10845 * 1) If gCountryCodePriority is set to 1; and last country
10846 * code set is through 11d. This needs to be done in case
10847 * when NV country code is 00.
10848 * This Needs to be done as when kernel store last country
10849 * code and if stored country code is not through 11d,
10850 * in sme_HandleChangeCountryCodeByUser we will disable 11d
10851 * in next load/unload as soon as we get any country through
10852 * 11d. In sme_HandleChangeCountryCodeByUser
10853 * pMsg->countryCode will be last countryCode and
10854 * pMac->scan.countryCode11d will be country through 11d so
10855 * due to mismatch driver will disable 11d.
10856 *
10857 */
Agarwal Ashish8db39882014-07-30 21:56:07 +053010858
c_hpothu8adb97b2014-12-08 19:38:20 +053010859 if ((eANI_BOOLEAN_TRUE == sme_Is11dCountrycode(pHddCtx->hHal) &&
Agarwal Ashish8dcd2862014-07-25 11:58:52 +053010860 pHddCtx->cfg_ini->fSupplicantCountryCodeHasPriority &&
Abhishek Singh2a705962014-10-30 14:47:28 +053010861 sme_Is11dSupported(pHddCtx->hHal)))
c_hpothu8adb97b2014-12-08 19:38:20 +053010862 {
10863 hddLog(VOS_TRACE_LEVEL_INFO,
Agarwal Ashish8dcd2862014-07-25 11:58:52 +053010864 FL("CountryCode 00 is being set while unloading driver"));
c_hpothu8adb97b2014-12-08 19:38:20 +053010865 vos_nv_getRegDomainFromCountryCode(&regId , "00", COUNTRY_USER);
10866 }
Agarwal Ashish5e414792014-06-08 15:25:23 +053010867
c_hpothu8adb97b2014-12-08 19:38:20 +053010868 //Do all the cleanup before deregistering the driver
10869 hdd_wlan_exit(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -070010870 }
10871
Jeff Johnson295189b2012-06-20 16:38:30 -070010872 vos_preClose( &pVosContext );
10873
10874#ifdef TIMER_MANAGER
10875 vos_timer_exit();
10876#endif
10877#ifdef MEMORY_DEBUG
10878 vos_mem_exit();
10879#endif
10880
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +053010881#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
10882 wlan_logging_sock_deinit_svc();
10883#endif
10884
Jeff Johnson295189b2012-06-20 16:38:30 -070010885done:
Sushant Kaushik83392fa2015-05-05 17:44:40 +053010886 vos_wake_lock_destroy(&wlan_wake_lock);
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +053010887
Jeff Johnson295189b2012-06-20 16:38:30 -070010888 pr_info("%s: driver unloaded\n", WLAN_MODULE_NAME);
10889}
10890
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010891/**---------------------------------------------------------------------------
10892
10893 \brief hdd_module_exit() - Exit function
10894
10895 This is the driver exit point (invoked when module is unloaded using rmmod)
10896
10897 \param - None
10898
10899 \return - None
10900
10901 --------------------------------------------------------------------------*/
10902static void __exit hdd_module_exit(void)
10903{
10904 hdd_driver_exit();
10905}
10906
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070010907#ifdef MODULE
10908static int fwpath_changed_handler(const char *kmessage,
10909 struct kernel_param *kp)
10910{
Jeff Johnson76052702013-04-16 13:55:05 -070010911 return param_set_copystring(kmessage, kp);
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070010912}
10913
10914static int con_mode_handler(const char *kmessage,
10915 struct kernel_param *kp)
10916{
Madan Mohan Koyyalamudif2f8d8b2012-10-11 17:06:59 -070010917 return param_set_int(kmessage, kp);
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070010918}
10919#else /* #ifdef MODULE */
10920/**---------------------------------------------------------------------------
10921
Jeff Johnson76052702013-04-16 13:55:05 -070010922 \brief kickstart_driver
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070010923
Jeff Johnson76052702013-04-16 13:55:05 -070010924 This is the driver entry point
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070010925 - delayed driver initialization when driver is statically linked
Jeff Johnson76052702013-04-16 13:55:05 -070010926 - invoked when module parameter fwpath is modified from userspace to signal
10927 initializing the WLAN driver or when con_mode is modified from userspace
10928 to signal a switch in operating mode
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070010929
10930 \return - 0 for success, non zero for failure
10931
10932 --------------------------------------------------------------------------*/
Jeff Johnson76052702013-04-16 13:55:05 -070010933static int kickstart_driver(void)
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070010934{
Madan Mohan Koyyalamudi62e60052012-10-05 14:27:22 -070010935 int ret_status;
10936
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070010937 if (!wlan_hdd_inited) {
Madan Mohan Koyyalamudi62e60052012-10-05 14:27:22 -070010938 ret_status = hdd_driver_init();
10939 wlan_hdd_inited = ret_status ? 0 : 1;
10940 return ret_status;
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070010941 }
10942
10943 hdd_driver_exit();
Jeff Johnson76052702013-04-16 13:55:05 -070010944
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070010945 msleep(200);
Jeff Johnson76052702013-04-16 13:55:05 -070010946
Madan Mohan Koyyalamudi62e60052012-10-05 14:27:22 -070010947 ret_status = hdd_driver_init();
10948 wlan_hdd_inited = ret_status ? 0 : 1;
10949 return ret_status;
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070010950}
10951
Jeff Johnson295189b2012-06-20 16:38:30 -070010952/**---------------------------------------------------------------------------
10953
Jeff Johnson76052702013-04-16 13:55:05 -070010954 \brief fwpath_changed_handler() - Handler Function
10955
10956 Handle changes to the fwpath parameter
10957
10958 \return - 0 for success, non zero for failure
10959
10960 --------------------------------------------------------------------------*/
10961static int fwpath_changed_handler(const char *kmessage,
10962 struct kernel_param *kp)
10963{
10964 int ret;
10965
10966 ret = param_set_copystring(kmessage, kp);
10967 if (0 == ret)
10968 ret = kickstart_driver();
10969 return ret;
10970}
10971
10972/**---------------------------------------------------------------------------
10973
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010974 \brief con_mode_handler() -
10975
10976 Handler function for module param con_mode when it is changed by userspace
10977 Dynamically linked - do nothing
10978 Statically linked - exit and init driver, as in rmmod and insmod
10979
Jeff Johnson76052702013-04-16 13:55:05 -070010980 \param -
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010981
Jeff Johnson76052702013-04-16 13:55:05 -070010982 \return -
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010983
10984 --------------------------------------------------------------------------*/
Jeff Johnson76052702013-04-16 13:55:05 -070010985static int con_mode_handler(const char *kmessage, struct kernel_param *kp)
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010986{
Jeff Johnson76052702013-04-16 13:55:05 -070010987 int ret;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010988
Jeff Johnson76052702013-04-16 13:55:05 -070010989 ret = param_set_int(kmessage, kp);
10990 if (0 == ret)
10991 ret = kickstart_driver();
10992 return ret;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010993}
10994#endif /* #ifdef MODULE */
10995
10996/**---------------------------------------------------------------------------
10997
Jeff Johnson295189b2012-06-20 16:38:30 -070010998 \brief hdd_get_conparam() -
10999
11000 This is the driver exit point (invoked when module is unloaded using rmmod)
11001
11002 \param - None
11003
11004 \return - tVOS_CON_MODE
11005
11006 --------------------------------------------------------------------------*/
11007tVOS_CON_MODE hdd_get_conparam ( void )
11008{
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070011009#ifdef MODULE
Jeff Johnson295189b2012-06-20 16:38:30 -070011010 return (tVOS_CON_MODE)con_mode;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070011011#else
11012 return (tVOS_CON_MODE)curr_con_mode;
11013#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070011014}
11015void hdd_set_conparam ( v_UINT_t newParam )
11016{
11017 con_mode = newParam;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070011018#ifndef MODULE
11019 curr_con_mode = con_mode;
11020#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070011021}
11022/**---------------------------------------------------------------------------
11023
11024 \brief hdd_softap_sta_deauth() - function
11025
11026 This to take counter measure to handle deauth req from HDD
11027
11028 \param - pAdapter - Pointer to the HDD
11029
11030 \param - enable - boolean value
11031
11032 \return - None
11033
11034 --------------------------------------------------------------------------*/
11035
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053011036VOS_STATUS hdd_softap_sta_deauth(hdd_adapter_t *pAdapter,
11037 struct tagCsrDelStaParams *pDelStaParams)
Jeff Johnson295189b2012-06-20 16:38:30 -070011038{
Jeff Johnson295189b2012-06-20 16:38:30 -070011039 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080011040 VOS_STATUS vosStatus = VOS_STATUS_E_FAULT;
Jeff Johnson295189b2012-06-20 16:38:30 -070011041
11042 ENTER();
11043
Rajesh Chauhan18488fc2013-08-22 10:15:03 -070011044 hddLog(LOG1, "hdd_softap_sta_deauth:(%p, false)",
11045 (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -070011046
11047 //Ignore request to deauth bcmc station
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053011048 if (pDelStaParams->peerMacAddr[0] & 0x1)
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080011049 return vosStatus;
Jeff Johnson295189b2012-06-20 16:38:30 -070011050
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053011051 vosStatus = WLANSAP_DeauthSta(pVosContext, pDelStaParams);
Jeff Johnson295189b2012-06-20 16:38:30 -070011052
11053 EXIT();
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080011054 return vosStatus;
Jeff Johnson295189b2012-06-20 16:38:30 -070011055}
11056
11057/**---------------------------------------------------------------------------
11058
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +053011059 \brief hdd_del_all_sta() - function
11060
11061 This function removes all the stations associated on stopping AP/P2P GO.
11062
11063 \param - pAdapter - Pointer to the HDD
11064
11065 \return - None
11066
11067 --------------------------------------------------------------------------*/
11068
11069int hdd_del_all_sta(hdd_adapter_t *pAdapter)
11070{
11071 v_U16_t i;
11072 VOS_STATUS vos_status;
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053011073 v_CONTEXT_t pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
11074 ptSapContext pSapCtx = NULL;
11075 pSapCtx = VOS_GET_SAP_CB(pVosContext);
11076 if(pSapCtx == NULL){
11077 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11078 FL("psapCtx is NULL"));
11079 return 1;
11080 }
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +053011081 ENTER();
11082
11083 hddLog(VOS_TRACE_LEVEL_INFO,
11084 "%s: Delete all STAs associated.",__func__);
11085 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
11086 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
11087 )
11088 {
11089 for(i = 0; i < WLAN_MAX_STA_COUNT; i++)
11090 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053011091 if ((pSapCtx->aStaInfo[i].isUsed) &&
11092 (!pSapCtx->aStaInfo[i].isDeauthInProgress))
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +053011093 {
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053011094 struct tagCsrDelStaParams delStaParams;
11095
11096 WLANSAP_PopulateDelStaParams(
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053011097 pSapCtx->aStaInfo[i].macAddrSTA.bytes,
Sushant Kaushik4cd28f62014-12-26 14:23:50 +053011098 eSIR_MAC_DEAUTH_LEAVING_BSS_REASON,
11099 SIR_MAC_MGMT_DEAUTH >> 4,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053011100 &delStaParams);
11101 vos_status = hdd_softap_sta_deauth(pAdapter, &delStaParams);
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +053011102 if (VOS_IS_STATUS_SUCCESS(vos_status))
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053011103 pSapCtx->aStaInfo[i].isDeauthInProgress = TRUE;
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +053011104 }
11105 }
11106 }
11107
11108 EXIT();
11109 return 0;
11110}
11111
11112/**---------------------------------------------------------------------------
11113
Jeff Johnson295189b2012-06-20 16:38:30 -070011114 \brief hdd_softap_sta_disassoc() - function
11115
11116 This to take counter measure to handle deauth req from HDD
11117
11118 \param - pAdapter - Pointer to the HDD
11119
11120 \param - enable - boolean value
11121
11122 \return - None
11123
11124 --------------------------------------------------------------------------*/
11125
11126void hdd_softap_sta_disassoc(hdd_adapter_t *pAdapter,v_U8_t *pDestMacAddress)
11127{
11128 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
11129
11130 ENTER();
11131
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +053011132 hddLog( LOGE, "hdd_softap_sta_disassoc:(%p, false)", (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -070011133
11134 //Ignore request to disassoc bcmc station
11135 if( pDestMacAddress[0] & 0x1 )
11136 return;
11137
11138 WLANSAP_DisassocSta(pVosContext,pDestMacAddress);
11139}
11140
11141void hdd_softap_tkip_mic_fail_counter_measure(hdd_adapter_t *pAdapter,v_BOOL_t enable)
11142{
11143 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
11144
11145 ENTER();
11146
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +053011147 hddLog( LOGE, "hdd_softap_tkip_mic_fail_counter_measure:(%p, false)", (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -070011148
11149 WLANSAP_SetCounterMeasure(pVosContext, (v_BOOL_t)enable);
11150}
11151
Jeff Johnson295189b2012-06-20 16:38:30 -070011152/**---------------------------------------------------------------------------
11153 *
11154 * \brief hdd_get__concurrency_mode() -
11155 *
11156 *
11157 * \param - None
11158 *
11159 * \return - CONCURRENCY MODE
11160 *
11161 * --------------------------------------------------------------------------*/
11162tVOS_CONCURRENCY_MODE hdd_get_concurrency_mode ( void )
11163{
11164 v_CONTEXT_t pVosContext = vos_get_global_context( VOS_MODULE_ID_HDD, NULL );
11165 hdd_context_t *pHddCtx;
11166
11167 if (NULL != pVosContext)
11168 {
11169 pHddCtx = vos_get_context( VOS_MODULE_ID_HDD, pVosContext);
11170 if (NULL != pHddCtx)
11171 {
11172 return (tVOS_CONCURRENCY_MODE)pHddCtx->concurrency_mode;
11173 }
11174 }
11175
11176 /* we are in an invalid state :( */
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070011177 hddLog(LOGE, "%s: Invalid context", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070011178 return VOS_STA;
11179}
Sushant Kaushikabb7ee62014-07-18 16:20:12 +053011180v_BOOL_t
11181wlan_hdd_is_GO_power_collapse_allowed (hdd_context_t* pHddCtx)
11182{
11183 hdd_adapter_t *pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070011184
Sushant Kaushikabb7ee62014-07-18 16:20:12 +053011185 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_GO);
11186 if (pAdapter == NULL)
11187 {
11188 hddLog(VOS_TRACE_LEVEL_INFO,
11189 FL("GO doesn't exist"));
11190 return TRUE;
11191 }
11192 if (test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
11193 {
11194 hddLog(VOS_TRACE_LEVEL_INFO,
11195 FL("GO started"));
11196 return TRUE;
11197 }
11198 else
11199 /* wait till GO changes its interface to p2p device */
11200 hddLog(VOS_TRACE_LEVEL_INFO,
11201 FL("Del_bss called, avoid apps suspend"));
11202 return FALSE;
11203
11204}
Jeff Johnson295189b2012-06-20 16:38:30 -070011205/* Decide whether to allow/not the apps power collapse.
11206 * Allow apps power collapse if we are in connected state.
11207 * if not, allow only if we are in IMPS */
11208v_BOOL_t hdd_is_apps_power_collapse_allowed(hdd_context_t* pHddCtx)
11209{
11210 tPmcState pmcState = pmcGetPmcState(pHddCtx->hHal);
Srikant Kuppafef66a72013-01-30 17:32:44 -080011211 tANI_BOOLEAN scanRspPending = csrNeighborRoamScanRspPending(pHddCtx->hHal);
Srinivas Girigowdaa553c462013-03-07 19:42:52 -080011212 tANI_BOOLEAN inMiddleOfRoaming = csrNeighborMiddleOfRoaming(pHddCtx->hHal);
Jeff Johnson295189b2012-06-20 16:38:30 -070011213 hdd_config_t *pConfig = pHddCtx->cfg_ini;
11214 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
11215 hdd_adapter_t *pAdapter = NULL;
11216 VOS_STATUS status;
Yathish9f22e662012-12-10 14:21:35 -080011217 tVOS_CONCURRENCY_MODE concurrent_state = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070011218
Jeff Johnson295189b2012-06-20 16:38:30 -070011219 if (VOS_STA_SAP_MODE == hdd_get_conparam())
11220 return TRUE;
Jeff Johnson295189b2012-06-20 16:38:30 -070011221
Yathish9f22e662012-12-10 14:21:35 -080011222 concurrent_state = hdd_get_concurrency_mode();
11223
Sushant Kaushikabb7ee62014-07-18 16:20:12 +053011224 if ((concurrent_state == (VOS_STA | VOS_P2P_GO)) &&
11225 !(wlan_hdd_is_GO_power_collapse_allowed(pHddCtx)))
11226 return FALSE;
Yathish9f22e662012-12-10 14:21:35 -080011227#ifdef WLAN_ACTIVEMODE_OFFLOAD_FEATURE
Sushant Kaushikabb7ee62014-07-18 16:20:12 +053011228
Yathish9f22e662012-12-10 14:21:35 -080011229 if(((concurrent_state == (VOS_STA | VOS_P2P_CLIENT)) ||
Sushant Kaushikabb7ee62014-07-18 16:20:12 +053011230 (concurrent_state == (VOS_STA | VOS_P2P_GO)))&&
Yathish9f22e662012-12-10 14:21:35 -080011231 (IS_ACTIVEMODE_OFFLOAD_FEATURE_ENABLE))
11232 return TRUE;
11233#endif
11234
Jeff Johnson295189b2012-06-20 16:38:30 -070011235 /*loop through all adapters. TBD fix for Concurrency */
11236 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
11237 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
11238 {
11239 pAdapter = pAdapterNode->pAdapter;
11240 if ( (WLAN_HDD_INFRA_STATION == pAdapter->device_mode)
11241 || (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
11242 {
Srikant Kuppafef66a72013-01-30 17:32:44 -080011243 if (((pConfig->fIsImpsEnabled || pConfig->fIsBmpsEnabled)
c_hpothu4e8faac2014-05-16 17:38:44 +053011244 && (pmcState != IMPS && pmcState != BMPS && pmcState != UAPSD
c_hpothu1c6957d2015-01-06 18:19:47 +053011245 && pmcState != STOPPED && pmcState != STANDBY &&
11246 pmcState != WOWL)) ||
Srinivas Girigowdaa553c462013-03-07 19:42:52 -080011247 (eANI_BOOLEAN_TRUE == scanRspPending) ||
11248 (eANI_BOOLEAN_TRUE == inMiddleOfRoaming))
Jeff Johnson295189b2012-06-20 16:38:30 -070011249 {
Mukul Sharma4be88422015-03-09 20:29:07 +053011250 if(pmcState == FULL_POWER &&
11251 sme_IsCoexScoIndicationSet(pHddCtx->hHal))
11252 {
11253 /*
11254 * When SCO indication comes from Coex module , host will
11255 * enter in to full power mode, but this should not prevent
11256 * apps processor power collapse.
11257 */
11258 hddLog(LOG1,
11259 FL("Allow apps power collapse"
11260 "even when sco indication is set"));
11261 return TRUE;
11262 }
Srikant Kuppafef66a72013-01-30 17:32:44 -080011263 hddLog( LOGE, "%s: do not allow APPS power collapse-"
Srinivas Girigowdaa553c462013-03-07 19:42:52 -080011264 "pmcState = %d scanRspPending = %d inMiddleOfRoaming = %d",
11265 __func__, pmcState, scanRspPending, inMiddleOfRoaming );
Jeff Johnson295189b2012-06-20 16:38:30 -070011266 return FALSE;
11267 }
11268 }
11269 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
11270 pAdapterNode = pNext;
11271 }
11272 return TRUE;
11273}
11274
Madan Mohan Koyyalamudic72a4d62012-11-08 14:59:34 -080011275/* Decides whether to send suspend notification to Riva
11276 * if any adapter is in BMPS; then it is required */
11277v_BOOL_t hdd_is_suspend_notify_allowed(hdd_context_t* pHddCtx)
11278{
11279 tPmcState pmcState = pmcGetPmcState(pHddCtx->hHal);
11280 hdd_config_t *pConfig = pHddCtx->cfg_ini;
11281
11282 if (pConfig->fIsBmpsEnabled && (pmcState == BMPS))
11283 {
11284 return TRUE;
11285 }
11286 return FALSE;
11287}
11288
Jeff Johnson295189b2012-06-20 16:38:30 -070011289void wlan_hdd_set_concurrency_mode(hdd_context_t *pHddCtx, tVOS_CON_MODE mode)
11290{
11291 switch(mode)
11292 {
Chilam Ngc4244af2013-04-01 15:37:32 -070011293 case VOS_STA_MODE:
11294 case VOS_P2P_CLIENT_MODE:
11295 case VOS_P2P_GO_MODE:
11296 case VOS_STA_SAP_MODE:
Jeff Johnsone7245742012-09-05 17:12:55 -070011297 pHddCtx->concurrency_mode |= (1 << mode);
Agarwal Ashish51325b52014-06-16 16:50:49 +053011298 pHddCtx->no_of_open_sessions[mode]++;
Jeff Johnson295189b2012-06-20 16:38:30 -070011299 break;
11300 default:
11301 break;
Jeff Johnson295189b2012-06-20 16:38:30 -070011302 }
Agarwal Ashish51325b52014-06-16 16:50:49 +053011303 hddLog(VOS_TRACE_LEVEL_INFO, FL("concurrency_mode = 0x%x "
11304 "Number of open sessions for mode %d = %d"),
11305 pHddCtx->concurrency_mode, mode,
11306 pHddCtx->no_of_open_sessions[mode]);
Jeff Johnson295189b2012-06-20 16:38:30 -070011307}
11308
11309
11310void wlan_hdd_clear_concurrency_mode(hdd_context_t *pHddCtx, tVOS_CON_MODE mode)
11311{
11312 switch(mode)
11313 {
Chilam Ngc4244af2013-04-01 15:37:32 -070011314 case VOS_STA_MODE:
11315 case VOS_P2P_CLIENT_MODE:
11316 case VOS_P2P_GO_MODE:
11317 case VOS_STA_SAP_MODE:
Agarwal Ashish51325b52014-06-16 16:50:49 +053011318 pHddCtx->no_of_open_sessions[mode]--;
11319 if (!(pHddCtx->no_of_open_sessions[mode]))
11320 pHddCtx->concurrency_mode &= (~(1 << mode));
Jeff Johnson295189b2012-06-20 16:38:30 -070011321 break;
11322 default:
11323 break;
11324 }
Agarwal Ashish51325b52014-06-16 16:50:49 +053011325 hddLog(VOS_TRACE_LEVEL_INFO, FL("concurrency_mode = 0x%x "
11326 "Number of open sessions for mode %d = %d"),
11327 pHddCtx->concurrency_mode, mode, pHddCtx->no_of_open_sessions[mode]);
11328
11329}
11330/**---------------------------------------------------------------------------
11331 *
11332 * \brief wlan_hdd_incr_active_session()
11333 *
11334 * This function increments the number of active sessions
11335 * maintained per device mode
11336 * Incase of STA/P2P CLI/IBSS upon connection indication it is incremented
11337 * Incase of SAP/P2P GO upon bss start it is incremented
11338 *
11339 * \param pHddCtx - HDD Context
11340 * \param mode - device mode
11341 *
11342 * \return - None
11343 *
11344 * --------------------------------------------------------------------------*/
11345void wlan_hdd_incr_active_session(hdd_context_t *pHddCtx, tVOS_CON_MODE mode)
11346{
11347 switch (mode) {
11348 case VOS_STA_MODE:
11349 case VOS_P2P_CLIENT_MODE:
11350 case VOS_P2P_GO_MODE:
11351 case VOS_STA_SAP_MODE:
11352 pHddCtx->no_of_active_sessions[mode]++;
11353 break;
11354 default:
11355 hddLog(VOS_TRACE_LEVEL_INFO, FL("Not Expected Mode %d"), mode);
11356 break;
11357 }
11358 hddLog(VOS_TRACE_LEVEL_INFO, FL("No.# of active sessions for mode %d = %d"),
11359 mode,
11360 pHddCtx->no_of_active_sessions[mode]);
11361}
11362
11363/**---------------------------------------------------------------------------
11364 *
11365 * \brief wlan_hdd_decr_active_session()
11366 *
11367 * This function decrements the number of active sessions
11368 * maintained per device mode
11369 * Incase of STA/P2P CLI/IBSS upon disconnection it is decremented
11370 * Incase of SAP/P2P GO upon bss stop it is decremented
11371 *
11372 * \param pHddCtx - HDD Context
11373 * \param mode - device mode
11374 *
11375 * \return - None
11376 *
11377 * --------------------------------------------------------------------------*/
11378void wlan_hdd_decr_active_session(hdd_context_t *pHddCtx, tVOS_CON_MODE mode)
11379{
11380 switch (mode) {
11381 case VOS_STA_MODE:
11382 case VOS_P2P_CLIENT_MODE:
11383 case VOS_P2P_GO_MODE:
11384 case VOS_STA_SAP_MODE:
Agarwal Ashish5325f522014-08-06 00:58:44 +053011385 if (pHddCtx->no_of_active_sessions[mode] > 0)
11386 pHddCtx->no_of_active_sessions[mode]--;
11387 else
11388 hddLog(VOS_TRACE_LEVEL_INFO, FL(" No.# of Active sessions"
11389 "is already Zero"));
Agarwal Ashish51325b52014-06-16 16:50:49 +053011390 break;
11391 default:
11392 hddLog(VOS_TRACE_LEVEL_INFO, FL("Not Expected Mode %d"), mode);
11393 break;
11394 }
11395 hddLog(VOS_TRACE_LEVEL_INFO, FL("No.# of active sessions for mode %d = %d"),
11396 mode,
11397 pHddCtx->no_of_active_sessions[mode]);
Jeff Johnson295189b2012-06-20 16:38:30 -070011398}
11399
Jeff Johnsone7245742012-09-05 17:12:55 -070011400/**---------------------------------------------------------------------------
11401 *
11402 * \brief wlan_hdd_restart_init
11403 *
11404 * This function initalizes restart timer/flag. An internal function.
11405 *
11406 * \param - pHddCtx
11407 *
11408 * \return - None
11409 *
11410 * --------------------------------------------------------------------------*/
11411
11412static void wlan_hdd_restart_init(hdd_context_t *pHddCtx)
11413{
11414 /* Initialize */
11415 pHddCtx->hdd_restart_retries = 0;
11416 atomic_set(&pHddCtx->isRestartInProgress, 0);
11417 vos_timer_init(&pHddCtx->hdd_restart_timer,
11418 VOS_TIMER_TYPE_SW,
11419 wlan_hdd_restart_timer_cb,
11420 pHddCtx);
11421}
11422/**---------------------------------------------------------------------------
11423 *
11424 * \brief wlan_hdd_restart_deinit
11425 *
11426 * This function cleans up the resources used. An internal function.
11427 *
11428 * \param - pHddCtx
11429 *
11430 * \return - None
11431 *
11432 * --------------------------------------------------------------------------*/
11433
11434static void wlan_hdd_restart_deinit(hdd_context_t* pHddCtx)
11435{
11436
11437 VOS_STATUS vos_status;
11438 /* Block any further calls */
11439 atomic_set(&pHddCtx->isRestartInProgress, 1);
11440 /* Cleanup */
11441 vos_status = vos_timer_stop( &pHddCtx->hdd_restart_timer );
11442 if (!VOS_IS_STATUS_SUCCESS(vos_status))
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011443 hddLog(LOGE, FL("Failed to stop HDD restart timer"));
Jeff Johnsone7245742012-09-05 17:12:55 -070011444 vos_status = vos_timer_destroy(&pHddCtx->hdd_restart_timer);
11445 if (!VOS_IS_STATUS_SUCCESS(vos_status))
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011446 hddLog(LOGE, FL("Failed to destroy HDD restart timer"));
Jeff Johnsone7245742012-09-05 17:12:55 -070011447
11448}
11449
11450/**---------------------------------------------------------------------------
11451 *
11452 * \brief wlan_hdd_framework_restart
11453 *
11454 * This function uses a cfg80211 API to start a framework initiated WLAN
11455 * driver module unload/load.
11456 *
11457 * Also this API keep retrying (WLAN_HDD_RESTART_RETRY_MAX_CNT).
11458 *
11459 *
11460 * \param - pHddCtx
11461 *
11462 * \return - VOS_STATUS_SUCCESS: Success
11463 * VOS_STATUS_E_EMPTY: Adapter is Empty
11464 * VOS_STATUS_E_NOMEM: No memory
11465
11466 * --------------------------------------------------------------------------*/
11467
11468static VOS_STATUS wlan_hdd_framework_restart(hdd_context_t *pHddCtx)
11469{
11470 VOS_STATUS status = VOS_STATUS_SUCCESS;
11471 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
Madan Mohan Koyyalamudifc19e442013-05-09 18:24:08 -070011472 int len = (sizeof (struct ieee80211_mgmt));
11473 struct ieee80211_mgmt *mgmt = NULL;
11474
11475 /* Prepare the DEAUTH managment frame with reason code */
11476 mgmt = kzalloc(len, GFP_KERNEL);
11477 if(mgmt == NULL)
11478 {
11479 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
11480 "%s: memory allocation failed (%d bytes)", __func__, len);
11481 return VOS_STATUS_E_NOMEM;
11482 }
11483 mgmt->u.deauth.reason_code = WLAN_REASON_DISASSOC_LOW_ACK;
Jeff Johnsone7245742012-09-05 17:12:55 -070011484
11485 /* Iterate over all adapters/devices */
11486 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
Hanumantha Reddy Pothulada0fe362015-02-27 18:37:03 +053011487 if ((NULL == pAdapterNode) || (VOS_STATUS_SUCCESS != status))
11488 {
11489 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11490 FL("fail to get adapter: %p %d"), pAdapterNode, status);
11491 goto end;
11492 }
11493
Jeff Johnsone7245742012-09-05 17:12:55 -070011494 do
11495 {
Hanumantha Reddy Pothulada0fe362015-02-27 18:37:03 +053011496 if(pAdapterNode->pAdapter &&
11497 WLAN_HDD_ADAPTER_MAGIC == pAdapterNode->pAdapter->magic)
Jeff Johnsone7245742012-09-05 17:12:55 -070011498 {
11499 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
11500 "restarting the driver(intf:\'%s\' mode:%d :try %d)",
11501 pAdapterNode->pAdapter->dev->name,
11502 pAdapterNode->pAdapter->device_mode,
11503 pHddCtx->hdd_restart_retries + 1);
Madan Mohan Koyyalamudifc19e442013-05-09 18:24:08 -070011504 /*
11505 * CFG80211 event to restart the driver
11506 *
11507 * 'cfg80211_send_unprot_deauth' sends a
11508 * NL80211_CMD_UNPROT_DEAUTHENTICATE event to supplicant at any state
11509 * of SME(Linux Kernel) state machine.
11510 *
11511 * Reason code WLAN_REASON_DISASSOC_LOW_ACK is currently used to restart
11512 * the driver.
11513 *
11514 */
Anand N Sunkade9adb1b2015-07-29 09:56:45 +053011515#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 11, 0))
11516 cfg80211_rx_unprot_mlme_mgmt(pAdapterNode->pAdapter->dev, (u_int8_t*)mgmt, len);
11517#else
Madan Mohan Koyyalamudifc19e442013-05-09 18:24:08 -070011518 cfg80211_send_unprot_deauth(pAdapterNode->pAdapter->dev, (u_int8_t*)mgmt, len );
Anand N Sunkade9adb1b2015-07-29 09:56:45 +053011519#endif
Jeff Johnsone7245742012-09-05 17:12:55 -070011520 }
11521 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
11522 pAdapterNode = pNext;
11523 } while((NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status));
11524
Hanumantha Reddy Pothulada0fe362015-02-27 18:37:03 +053011525 end:
Madan Mohan Koyyalamudifc19e442013-05-09 18:24:08 -070011526 /* Free the allocated management frame */
11527 kfree(mgmt);
11528
Jeff Johnsone7245742012-09-05 17:12:55 -070011529 /* Retry until we unload or reach max count */
11530 if(++pHddCtx->hdd_restart_retries < WLAN_HDD_RESTART_RETRY_MAX_CNT)
11531 vos_timer_start(&pHddCtx->hdd_restart_timer, WLAN_HDD_RESTART_RETRY_DELAY_MS);
11532
11533 return status;
11534
11535}
11536/**---------------------------------------------------------------------------
11537 *
11538 * \brief wlan_hdd_restart_timer_cb
11539 *
11540 * Restart timer callback. An internal function.
11541 *
11542 * \param - User data:
11543 *
11544 * \return - None
11545 *
11546 * --------------------------------------------------------------------------*/
11547
11548void wlan_hdd_restart_timer_cb(v_PVOID_t usrDataForCallback)
11549{
11550 hdd_context_t *pHddCtx = usrDataForCallback;
11551 wlan_hdd_framework_restart(pHddCtx);
11552 return;
11553
11554}
11555
11556
11557/**---------------------------------------------------------------------------
11558 *
11559 * \brief wlan_hdd_restart_driver
11560 *
11561 * This function sends an event to supplicant to restart the WLAN driver.
11562 *
11563 * This function is called from vos_wlanRestart.
11564 *
11565 * \param - pHddCtx
11566 *
11567 * \return - VOS_STATUS_SUCCESS: Success
11568 * VOS_STATUS_E_EMPTY: Adapter is Empty
11569 * VOS_STATUS_E_ALREADY: Request already in progress
11570
11571 * --------------------------------------------------------------------------*/
11572VOS_STATUS wlan_hdd_restart_driver(hdd_context_t *pHddCtx)
11573{
11574 VOS_STATUS status = VOS_STATUS_SUCCESS;
11575
11576 /* A tight check to make sure reentrancy */
11577 if(atomic_xchg(&pHddCtx->isRestartInProgress, 1))
11578 {
Mihir Shetefd528652014-06-23 19:07:50 +053011579 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnsone7245742012-09-05 17:12:55 -070011580 "%s: WLAN restart is already in progress", __func__);
11581
11582 return VOS_STATUS_E_ALREADY;
11583 }
Sameer Thalappil0c164f52013-03-28 15:27:56 -070011584 /* Send reset FIQ to WCNSS to invoke SSR. */
Madan Mohan Koyyalamudie388b342012-11-08 15:03:16 -080011585#ifdef HAVE_WCNSS_RESET_INTR
Siddharth Bhal864e7e82015-04-07 20:07:24 +053011586 wcnss_reset_fiq(TRUE);
Madan Mohan Koyyalamudibb8f0172012-09-28 15:36:06 -070011587#endif
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -070011588
Jeff Johnsone7245742012-09-05 17:12:55 -070011589 return status;
11590}
11591
Mihir Shetee1093ba2014-01-21 20:13:32 +053011592/**---------------------------------------------------------------------------
11593 *
11594 * \brief wlan_hdd_init_channels
11595 *
11596 * This function is used to initialize the channel list in CSR
11597 *
11598 * This function is called from hdd_wlan_startup
11599 *
11600 * \param - pHddCtx: HDD context
11601 *
11602 * \return - VOS_STATUS_SUCCESS: Success
11603 * VOS_STATUS_E_FAULT: Failure reported by SME
11604
11605 * --------------------------------------------------------------------------*/
11606static VOS_STATUS wlan_hdd_init_channels(hdd_context_t *pHddCtx)
11607{
11608 eHalStatus status;
11609
11610 status = sme_InitChannels(pHddCtx->hHal);
11611 if (HAL_STATUS_SUCCESS(status))
11612 {
11613 return VOS_STATUS_SUCCESS;
11614 }
11615 else
11616 {
11617 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Channel initialization failed(%d)",
11618 __func__, status);
11619 return VOS_STATUS_E_FAULT;
11620 }
11621}
11622
Mihir Shete04206452014-11-20 17:50:58 +053011623#ifdef CONFIG_ENABLE_LINUX_REG
Agarwal Ashish6db9d532014-09-30 18:19:10 +053011624VOS_STATUS wlan_hdd_init_channels_for_cc(hdd_context_t *pHddCtx, driver_load_type init )
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053011625{
11626 eHalStatus status;
11627
Agarwal Ashish6db9d532014-09-30 18:19:10 +053011628 status = sme_InitChannelsForCC(pHddCtx->hHal, init);
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053011629 if (HAL_STATUS_SUCCESS(status))
11630 {
11631 return VOS_STATUS_SUCCESS;
11632 }
11633 else
11634 {
11635 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Issue reg hint failed(%d)",
11636 __func__, status);
11637 return VOS_STATUS_E_FAULT;
11638 }
11639}
Mihir Shete04206452014-11-20 17:50:58 +053011640#endif
Sudhir Sattayappa Kohallib1d8c3a2013-06-18 14:47:20 -070011641/*
11642 * API to find if there is any STA or P2P-Client is connected
11643 */
11644VOS_STATUS hdd_issta_p2p_clientconnected(hdd_context_t *pHddCtx)
11645{
11646 return sme_isSta_p2p_clientConnected(pHddCtx->hHal);
11647}
Jeff Johnsone7245742012-09-05 17:12:55 -070011648
Mihir Shetee2ae82a2015-03-16 14:08:49 +053011649
11650/*
11651 * API to find if the firmware will send logs using DXE channel
11652 */
11653v_U8_t hdd_is_fw_logging_enabled(void)
11654{
11655 hdd_context_t *pHddCtx;
11656
11657 pHddCtx = vos_get_context(VOS_MODULE_ID_HDD,
11658 vos_get_global_context(VOS_MODULE_ID_HDD, NULL));
11659
Sachin Ahuja084313e2015-05-21 17:57:10 +053011660 return (pHddCtx && pHddCtx->cfg_ini->enableMgmtLogging);
Mihir Shetee2ae82a2015-03-16 14:08:49 +053011661}
11662
Agarwal Ashish57e84372014-12-05 18:26:53 +053011663/*
Mihir Shetebe94ebb2015-05-26 12:07:14 +053011664 * API to find if the firmware will send trace logs using DXE channel
11665 */
11666v_U8_t hdd_is_fw_ev_logging_enabled(void)
11667{
11668 hdd_context_t *pHddCtx;
11669
11670 pHddCtx = vos_get_context(VOS_MODULE_ID_HDD,
11671 vos_get_global_context(VOS_MODULE_ID_HDD, NULL));
11672
11673 return (pHddCtx && pHddCtx->cfg_ini->enableFWLogging);
11674}
11675/*
Agarwal Ashish57e84372014-12-05 18:26:53 +053011676 * API to find if there is any session connected
11677 */
11678VOS_STATUS hdd_is_any_session_connected(hdd_context_t *pHddCtx)
11679{
11680 return sme_is_any_session_connected(pHddCtx->hHal);
11681}
11682
11683
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011684int wlan_hdd_scan_abort(hdd_adapter_t *pAdapter)
11685{
11686 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
11687 hdd_scaninfo_t *pScanInfo = NULL;
Girish Gowli4bf7a632014-06-12 13:42:11 +053011688 long status = 0;
c_hpothua3d45d52015-01-05 14:11:17 +053011689 tSirAbortScanStatus abortScanStatus;
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011690
11691 pScanInfo = &pHddCtx->scan_info;
Ratnam Rachuric7681132015-06-30 10:35:13 +053011692 INIT_COMPLETION(pScanInfo->abortscan_event_var);
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011693 if (pScanInfo->mScanPending)
11694 {
c_hpothua3d45d52015-01-05 14:11:17 +053011695 abortScanStatus = hdd_abort_mac_scan(pHddCtx, pScanInfo->sessionId,
11696 eCSR_SCAN_ABORT_DEFAULT);
11697 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
11698 FL("abortScanStatus: %d"), abortScanStatus);
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011699
c_hpothua3d45d52015-01-05 14:11:17 +053011700 /* If there is active scan command lets wait for the completion else
11701 * there is no need to wait as scan command might be in the SME pending
11702 * command list.
11703 */
11704 if (abortScanStatus == eSIR_ABORT_ACTIVE_SCAN_LIST_NOT_EMPTY)
11705 {
c_hpothua3d45d52015-01-05 14:11:17 +053011706 status = wait_for_completion_interruptible_timeout(
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011707 &pScanInfo->abortscan_event_var,
11708 msecs_to_jiffies(5000));
c_hpothua3d45d52015-01-05 14:11:17 +053011709 if (0 >= status)
11710 {
11711 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Girish Gowli4bf7a632014-06-12 13:42:11 +053011712 "%s: Timeout or Interrupt occurred while waiting for abort"
11713 "scan, status- %ld", __func__, status);
c_hpothua3d45d52015-01-05 14:11:17 +053011714 return -ETIMEDOUT;
11715 }
11716 }
11717 else if (abortScanStatus == eSIR_ABORT_SCAN_FAILURE)
11718 {
11719 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11720 FL("hdd_abort_mac_scan failed"));
11721 return -VOS_STATUS_E_FAILURE;
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011722 }
11723 }
Girish Gowli4bf7a632014-06-12 13:42:11 +053011724 return 0;
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011725}
11726
c_hpothu225aa7c2014-10-22 17:45:13 +053011727VOS_STATUS wlan_hdd_cancel_remain_on_channel(hdd_context_t *pHddCtx)
11728{
11729 hdd_adapter_t *pAdapter;
11730 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
11731 VOS_STATUS vosStatus;
11732
11733 vosStatus = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
11734 while (NULL != pAdapterNode && VOS_STATUS_E_EMPTY != vosStatus)
11735 {
11736 pAdapter = pAdapterNode->pAdapter;
11737 if (NULL != pAdapter)
11738 {
11739 if (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode ||
11740 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode ||
11741 WLAN_HDD_P2P_GO == pAdapter->device_mode)
11742 {
11743 hddLog(LOG1, FL("abort ROC deviceMode: %d"),
11744 pAdapter->device_mode);
11745 if (VOS_STATUS_SUCCESS !=
11746 wlan_hdd_cancel_existing_remain_on_channel(pAdapter))
11747 {
11748 hddLog(LOGE, FL("failed to abort ROC"));
11749 return VOS_STATUS_E_FAILURE;
11750 }
11751 }
11752 }
11753 vosStatus = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
11754 pAdapterNode = pNext;
11755 }
11756 return VOS_STATUS_SUCCESS;
11757}
Mahesh A Saptasagard477b092015-02-06 15:12:16 +053011758
Mihir Shete0be28772015-02-17 18:42:14 +053011759hdd_remain_on_chan_ctx_t *hdd_get_remain_on_channel_ctx(hdd_context_t *pHddCtx)
11760{
11761 hdd_adapter_t *pAdapter;
11762 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
11763 hdd_cfg80211_state_t *cfgState;
11764 hdd_remain_on_chan_ctx_t *pRemainChanCtx = NULL;
11765 VOS_STATUS vosStatus;
11766
11767 vosStatus = hdd_get_front_adapter (pHddCtx, &pAdapterNode);
11768 while (NULL != pAdapterNode && VOS_STATUS_E_EMPTY != vosStatus)
11769 {
11770 pAdapter = pAdapterNode->pAdapter;
11771 if (NULL != pAdapter)
11772 {
11773 cfgState = WLAN_HDD_GET_CFG_STATE_PTR(pAdapter);
11774 pRemainChanCtx = cfgState->remain_on_chan_ctx;
11775 if (pRemainChanCtx)
11776 break;
11777 }
11778 vosStatus = hdd_get_next_adapter (pHddCtx, pAdapterNode, &pNext);
11779 pAdapterNode = pNext;
11780 }
11781 return pRemainChanCtx;
11782}
11783
Padma, Santhosh Kumar778d8382015-03-04 17:41:22 +053011784/**
11785 * wlan_hdd_handle_dfs_chan_scan () - handles disable/enable DFS channels
11786 *
11787 * @pHddCtx: HDD context within host driver
11788 * @dfsScanMode: dfsScanMode passed from ioctl
11789 *
11790 */
11791
11792VOS_STATUS wlan_hdd_handle_dfs_chan_scan(hdd_context_t *pHddCtx,
11793 tANI_U8 dfsScanMode)
11794{
11795 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
11796 hdd_adapter_t *pAdapter;
11797 VOS_STATUS vosStatus;
11798 hdd_station_ctx_t *pHddStaCtx;
11799 eHalStatus status = eHAL_STATUS_SUCCESS;
11800
11801 if(!pHddCtx)
11802 {
11803 hddLog(LOGE, FL("HDD context is Null"));
11804 return eHAL_STATUS_FAILURE;
11805 }
11806
11807 if (pHddCtx->scan_info.mScanPending)
11808 {
11809 hddLog(LOG1, FL("Aborting scan for sessionId: %d"),
11810 pHddCtx->scan_info.sessionId);
11811 hdd_abort_mac_scan(pHddCtx,
11812 pHddCtx->scan_info.sessionId,
11813 eCSR_SCAN_ABORT_DEFAULT);
11814 }
11815
11816 if (!dfsScanMode)
11817 {
11818 vosStatus = hdd_get_front_adapter( pHddCtx, &pAdapterNode);
11819 while ((NULL != pAdapterNode) &&
11820 (VOS_STATUS_SUCCESS == vosStatus))
11821 {
11822 pAdapter = pAdapterNode->pAdapter;
11823
11824 if (WLAN_HDD_INFRA_STATION == pAdapter->device_mode)
11825 {
11826 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
11827
11828 if(!pHddStaCtx)
11829 {
11830 hddLog(LOGE, FL("HDD STA context is Null"));
11831 return eHAL_STATUS_FAILURE;
11832 }
11833
11834 /* if STA is already connected on DFS channel,
11835 disconnect immediately*/
11836 if (hdd_connIsConnected(pHddStaCtx) &&
11837 (NV_CHANNEL_DFS ==
11838 vos_nv_getChannelEnabledState(
11839 pHddStaCtx->conn_info.operationChannel)))
11840 {
11841 status = sme_RoamDisconnect(pHddCtx->hHal,
11842 pAdapter->sessionId,
11843 eCSR_DISCONNECT_REASON_UNSPECIFIED);
11844 hddLog(LOG1, FL("Client connected on DFS channel %d,"
11845 "sme_RoamDisconnect returned with status: %d"
11846 "for sessionid: %d"), pHddStaCtx->conn_info.
11847 operationChannel, status, pAdapter->sessionId);
11848 }
11849 }
11850
11851 vosStatus = hdd_get_next_adapter(pHddCtx, pAdapterNode,
11852 &pNext);
11853 pAdapterNode = pNext;
11854 }
11855 }
11856
11857 sme_UpdateDFSScanMode(pHddCtx->hHal, dfsScanMode);
11858 sme_UpdateDFSRoamMode(pHddCtx->hHal,
11859 (dfsScanMode != DFS_CHNL_SCAN_DISABLED));
11860
11861 status = sme_HandleDFSChanScan(pHddCtx->hHal);
11862 if (!HAL_STATUS_SUCCESS(status))
11863 {
11864 hddLog(LOGE,
11865 FL("Failed in sme_HandleDFSChanScan (err=%d)"), status);
11866 return status;
11867 }
11868
11869 return status;
11870}
11871
Nirav Shah7e3c8132015-06-22 23:51:42 +053011872static int hdd_log2_ceil(unsigned value)
11873{
11874 /* need to switch to unsigned math so that negative values
11875 * will right-shift towards 0 instead of -1
11876 */
11877 unsigned tmp = value;
11878 int log2 = -1;
11879
11880 if (value == 0)
11881 return 0;
11882
11883 while (tmp) {
11884 log2++;
11885 tmp >>= 1;
11886 }
11887 if (1U << log2 != value)
11888 log2++;
11889
11890 return log2;
11891}
11892
11893/**
11894 * hdd_sta_id_hash_attach() - initialize sta id to macaddr hash
11895 * @pAdapter: adapter handle
11896 *
11897 * Return: vos status
11898 */
11899VOS_STATUS hdd_sta_id_hash_attach(hdd_adapter_t *pAdapter)
11900{
11901 int hash_elem, log2, i;
11902
11903 spin_lock_bh( &pAdapter->sta_hash_lock);
11904 if (pAdapter->is_sta_id_hash_initialized == VOS_TRUE) {
11905 spin_unlock_bh( &pAdapter->sta_hash_lock);
11906 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11907 "%s: hash already attached for session id %d",
11908 __func__, pAdapter->sessionId);
11909 return VOS_STATUS_SUCCESS;
11910 }
11911 spin_unlock_bh( &pAdapter->sta_hash_lock);
11912
11913 hash_elem = WLAN_MAX_STA_COUNT;
11914 hash_elem *= HDD_STA_ID_HASH_MULTIPLIER;
11915 log2 = hdd_log2_ceil(hash_elem);
11916 hash_elem = 1 << log2;
11917
11918 pAdapter->sta_id_hash.mask = hash_elem - 1;
11919 pAdapter->sta_id_hash.idx_bits = log2;
11920 pAdapter->sta_id_hash.bins =
11921 vos_mem_malloc(hash_elem *sizeof(hdd_list_t));
11922 if (!pAdapter->sta_id_hash.bins) {
11923 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11924 "%s: malloc failed for session %d",
11925 __func__, pAdapter->sessionId);
11926 return VOS_STATUS_E_NOMEM;
11927 }
11928
11929 for (i = 0; i < hash_elem; i++)
11930 hdd_list_init(&pAdapter->sta_id_hash.bins[i], WLAN_MAX_STA_COUNT);
11931
11932 spin_lock_bh( &pAdapter->sta_hash_lock);
11933 pAdapter->is_sta_id_hash_initialized = VOS_TRUE;
11934 spin_unlock_bh( &pAdapter->sta_hash_lock);
11935 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
11936 "%s: Station ID Hash attached for session id %d",
11937 __func__, pAdapter->sessionId);
11938
11939 return VOS_STATUS_SUCCESS;
11940}
11941
11942/**
11943 * hdd_sta_id_hash_detach() - deinit sta_id to macaddr hash
11944 * @pAdapter: adapter handle
11945 *
11946 * Return: vos status
11947 */
11948VOS_STATUS hdd_sta_id_hash_detach(hdd_adapter_t *pAdapter)
11949{
11950 int hash_elem, i;
11951 v_SIZE_t size;
11952
11953 spin_lock_bh( &pAdapter->sta_hash_lock);
11954 if (pAdapter->is_sta_id_hash_initialized != VOS_TRUE) {
11955 spin_unlock_bh( &pAdapter->sta_hash_lock);
11956 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
11957 "%s: hash not initialized for session id %d",
11958 __func__, pAdapter->sessionId);
11959 return VOS_STATUS_SUCCESS;
11960 }
11961
11962 pAdapter->is_sta_id_hash_initialized = VOS_FALSE;
11963 spin_unlock_bh( &pAdapter->sta_hash_lock);
11964
11965 hash_elem = 1 << pAdapter->sta_id_hash.idx_bits;
11966
11967 /* free all station info*/
11968 for (i = 0; i < hash_elem; i++) {
11969 hdd_list_size(&pAdapter->sta_id_hash.bins[i], &size);
11970 if (size != 0) {
11971 VOS_STATUS status;
11972 hdd_staid_hash_node_t *sta_info_node = NULL;
11973 hdd_staid_hash_node_t *next_node = NULL;
11974 status = hdd_list_peek_front ( &pAdapter->sta_id_hash.bins[i],
11975 (hdd_list_node_t**) &sta_info_node );
11976
11977 while ( NULL != sta_info_node && VOS_STATUS_SUCCESS == status )
11978 {
11979 status = hdd_list_remove_node( &pAdapter->sta_id_hash.bins[i],
11980 &sta_info_node->node);
11981 vos_mem_free(sta_info_node);
11982
11983 status = hdd_list_peek_next (&pAdapter->sta_id_hash.bins[i],
11984 (hdd_list_node_t*)sta_info_node,
11985 (hdd_list_node_t**)&next_node);
11986 sta_info_node = next_node;
11987 }
11988 }
11989 }
11990
11991 vos_mem_free(pAdapter->sta_id_hash.bins);
11992 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
11993 "%s: Station ID Hash detached for session id %d",
11994 __func__, pAdapter->sessionId);
11995 return VOS_STATUS_SUCCESS;
11996}
11997
11998/**
11999 * hdd_sta_id_hash_calculate_index() - derive index from macaddr
12000 * @pAdapter: adapter handle
12001 * @mac_addr_in: input mac address
12002 *
12003 * Return: index derived from mac address
12004 */
12005int hdd_sta_id_hash_calculate_index(hdd_adapter_t *pAdapter,
12006 v_MACADDR_t *mac_addr_in)
12007{
12008 uint16 index;
12009 struct hdd_align_mac_addr_t * mac_addr =
12010 (struct hdd_align_mac_addr_t *)mac_addr_in;
12011
12012 index = mac_addr->bytes_ab ^
12013 mac_addr->bytes_cd ^ mac_addr->bytes_ef;
12014 index ^= index >> pAdapter->sta_id_hash.idx_bits;
12015 index &= pAdapter->sta_id_hash.mask;
12016 return index;
12017}
12018
12019/**
12020 * hdd_sta_id_hash_add_entry() - add entry in hash
12021 * @pAdapter: adapter handle
12022 * @sta_id: station id
12023 * @mac_addr: mac address
12024 *
12025 * Return: vos status
12026 */
12027VOS_STATUS hdd_sta_id_hash_add_entry(hdd_adapter_t *pAdapter,
12028 v_U8_t sta_id, v_MACADDR_t *mac_addr)
12029{
12030 uint16 index;
12031 hdd_staid_hash_node_t *sta_info_node = NULL;
12032
Nirav Shah7e3c8132015-06-22 23:51:42 +053012033 index = hdd_sta_id_hash_calculate_index(pAdapter, mac_addr);
12034 sta_info_node = vos_mem_malloc(sizeof(hdd_staid_hash_node_t));
12035 if (!sta_info_node) {
Nirav Shah7e3c8132015-06-22 23:51:42 +053012036 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12037 "%s: malloc failed", __func__);
12038 return VOS_STATUS_E_NOMEM;
12039 }
12040
12041 sta_info_node->sta_id = sta_id;
12042 vos_mem_copy(&sta_info_node->mac_addr, mac_addr, sizeof(v_MACADDR_t));
12043
Nirav Shah303ed5c2015-08-24 10:29:25 +053012044 spin_lock_bh( &pAdapter->sta_hash_lock);
12045 if (pAdapter->is_sta_id_hash_initialized != VOS_TRUE) {
12046 spin_unlock_bh( &pAdapter->sta_hash_lock);
12047 vos_mem_free(sta_info_node);
12048 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
12049 "%s: hash is not initialized for session id %d",
12050 __func__, pAdapter->sessionId);
12051 return VOS_STATUS_E_FAILURE;
12052 }
12053
Nirav Shah7e3c8132015-06-22 23:51:42 +053012054 hdd_list_insert_back ( &pAdapter->sta_id_hash.bins[index],
12055 (hdd_list_node_t*) sta_info_node );
12056 spin_unlock_bh( &pAdapter->sta_hash_lock);
12057 return VOS_STATUS_SUCCESS;
12058}
12059
12060/**
12061 * hdd_sta_id_hash_remove_entry() - remove entry from hash
12062 * @pAdapter: adapter handle
12063 * @sta_id: station id
12064 * @mac_addr: mac address
12065 *
12066 * Return: vos status
12067 */
12068VOS_STATUS hdd_sta_id_hash_remove_entry(hdd_adapter_t *pAdapter,
12069 v_U8_t sta_id, v_MACADDR_t *mac_addr)
12070{
12071 uint16 index;
12072 VOS_STATUS status;
12073 hdd_staid_hash_node_t *sta_info_node = NULL;
12074 hdd_staid_hash_node_t *next_node = NULL;
12075
12076 spin_lock_bh( &pAdapter->sta_hash_lock);
12077 if (pAdapter->is_sta_id_hash_initialized != VOS_TRUE) {
12078 spin_unlock_bh( &pAdapter->sta_hash_lock);
12079 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12080 "%s: hash is not initialized for session id %d",
12081 __func__, pAdapter->sessionId);
12082 return VOS_STATUS_E_FAILURE;
12083 }
12084
12085 index = hdd_sta_id_hash_calculate_index(pAdapter, mac_addr);
12086 status = hdd_list_peek_front ( &pAdapter->sta_id_hash.bins[index],
12087 (hdd_list_node_t**) &sta_info_node );
12088
12089 while ( NULL != sta_info_node && VOS_STATUS_SUCCESS == status )
12090 {
12091 if (sta_info_node->sta_id == sta_id) {
12092 status = hdd_list_remove_node( &pAdapter->sta_id_hash.bins[index],
12093 &sta_info_node->node);
12094 vos_mem_free(sta_info_node);
12095 break;
12096 }
12097 status = hdd_list_peek_next (&pAdapter->sta_id_hash.bins[index],
12098 (hdd_list_node_t*)sta_info_node, (hdd_list_node_t**)&next_node);
12099 sta_info_node = next_node;
12100 }
12101 spin_unlock_bh( &pAdapter->sta_hash_lock);
12102 return status;
12103}
12104
12105/**
12106 * hdd_sta_id_find_from_mac_addr() - find sta id from mac address
12107 * @pAdapter: adapter handle
12108 * @mac_addr_in: mac address
12109 *
12110 * Return: station id
12111 */
12112int hdd_sta_id_find_from_mac_addr(hdd_adapter_t *pAdapter,
12113 v_MACADDR_t *mac_addr_in)
12114{
12115 uint8 is_found = 0;
12116 uint8 sta_id = HDD_WLAN_INVALID_STA_ID;
12117 uint16 index;
12118 VOS_STATUS status;
12119 hdd_staid_hash_node_t *sta_info_node = NULL;
12120 hdd_staid_hash_node_t *next_node = NULL;
12121
12122 spin_lock_bh( &pAdapter->sta_hash_lock);
12123 if (pAdapter->is_sta_id_hash_initialized != VOS_TRUE) {
12124 spin_unlock_bh( &pAdapter->sta_hash_lock);
Bhargav Shahce3b32c2015-08-10 12:29:24 +053012125 hddLog(VOS_TRACE_LEVEL_INFO,
Nirav Shah7e3c8132015-06-22 23:51:42 +053012126 FL("hash is not initialized for session id %d"),
12127 pAdapter->sessionId);
12128 return HDD_WLAN_INVALID_STA_ID;
12129 }
12130
12131 index = hdd_sta_id_hash_calculate_index(pAdapter, mac_addr_in);
12132 status = hdd_list_peek_front ( &pAdapter->sta_id_hash.bins[index],
12133 (hdd_list_node_t**) &sta_info_node );
12134
12135 while ( NULL != sta_info_node && VOS_STATUS_SUCCESS == status )
12136 {
12137 if (vos_mem_compare(&sta_info_node->mac_addr,
12138 mac_addr_in, sizeof(v_MACADDR_t))) {
12139 is_found = 1;
12140 sta_id = sta_info_node->sta_id;
12141 break;
12142 }
12143 status = hdd_list_peek_next (&pAdapter->sta_id_hash.bins[index],
12144 (hdd_list_node_t*)sta_info_node,
12145 (hdd_list_node_t**)&next_node);
12146 sta_info_node = next_node;
12147 }
12148 spin_unlock_bh( &pAdapter->sta_hash_lock);
12149 return sta_id;
12150}
12151
c_manjeecfd1efb2015-09-25 19:32:34 +053012152/*FW memory dump feature*/
12153/**
12154 * This structure hold information about the /proc file
12155 *
12156 */
12157static struct proc_dir_entry *proc_file, *proc_dir;
12158
12159/**
12160 * memdump_read() - perform read operation in memory dump proc file
12161 *
12162 * @file - handle for the proc file.
12163 * @buf - pointer to user space buffer.
12164 * @count - number of bytes to be read.
12165 * @pos - offset in the from buffer.
12166 *
12167 * This function performs read operation for the memory dump proc file.
12168 *
12169 * Return: number of bytes read on success, error code otherwise.
12170 */
12171static ssize_t memdump_read(struct file *file, char __user *buf,
12172 size_t count, loff_t *pos)
12173{
12174 int status;
12175 hdd_context_t *hdd_ctx = (hdd_context_t *)PDE_DATA(file_inode(file));
12176 size_t ret_count;
12177 ENTER();
12178
12179 hddLog(LOG1, FL("Read req for size:%zu pos:%llu"), count, *pos);
12180 status = wlan_hdd_validate_context(hdd_ctx);
12181 if (0 != status) {
12182 return -EINVAL;
12183 }
12184
12185 if (!wlan_fwr_mem_dump_test_and_set_read_allowed_bit()) {
12186 hddLog(LOGE, FL("Current mem dump request timed out/failed"));
12187 return -EINVAL;
12188 }
12189
12190 /* run fs_read_handler in an atomic context*/
12191 vos_ssr_protect(__func__);
12192 ret_count = wlan_fwr_mem_dump_fsread_handler( buf, count, pos);
12193 if(ret_count == 0)
12194 {
12195 /*Free the fwr mem dump buffer */
12196 wlan_free_fwr_mem_dump_buffer();
12197 wlan_set_fwr_mem_dump_state(FW_MEM_DUMP_IDLE);
12198 }
12199 /*if SSR/unload code is waiting for memdump_read to finish,signal it*/
12200 vos_ssr_unprotect(__func__);
12201 EXIT();
12202 return ret_count;
12203}
12204
12205/**
12206 * struct memdump_fops - file operations for memory dump feature
12207 * @read - read function for memory dump operation.
12208 *
12209 * This structure initialize the file operation handle for memory
12210 * dump feature
12211 */
12212static const struct file_operations memdump_fops = {
12213 read: memdump_read
12214};
12215
12216/*
12217* wlan_hdd_fw_mem_dump_cb : callback for Fw mem dump request
12218* To be passed by HDD to WDA and called upon receiving of response
12219* from firmware
12220* @fwMemDumpReqContext : memory dump request context
12221* @dump_rsp : dump response from HAL
12222* Returns none
12223*/
12224void wlan_hdd_fw_mem_dump_cb(void *fwMemDumpReqContext,
12225 tAniFwrDumpRsp *dump_rsp)
12226{
12227 hdd_context_t *pHddCtx = (hdd_context_t *)fwMemDumpReqContext;
12228 int status;
12229 ENTER();
12230 status = wlan_hdd_validate_context(pHddCtx);
12231 if (0 != status) {
12232 return;
12233 }
12234
12235 if (dump_rsp->dump_status != eHAL_STATUS_SUCCESS) {
12236 hddLog(LOGE, FL("fw dump request declined by fwr"));
12237 //report failure to user space
12238 wlan_indicate_mem_dump_complete(false);
12239 //Free the allocated fwr dump
12240 wlan_free_fwr_mem_dump_buffer();
12241 wlan_set_fwr_mem_dump_state(FW_MEM_DUMP_IDLE);
12242 return;
12243 }
12244 else
12245 hddLog(LOG1, FL("fw dump request accepted by fwr"));
12246 EXIT();
12247
12248}
12249
12250/**
12251 * memdump_procfs_remove() - Remove file/dir under procfs for memory dump
12252 *
12253 * This function removes file/dir under proc file system that was
12254 * processing firmware memory dump
12255 *
12256 * Return: None
12257 */
12258static void memdump_procfs_remove(void)
12259{
12260 remove_proc_entry(PROCFS_MEMDUMP_NAME, proc_dir);
12261 hddLog(LOG1 , FL("/proc/%s/%s removed\n"),
12262 PROCFS_MEMDUMP_DIR, PROCFS_MEMDUMP_NAME);
12263 remove_proc_entry(PROCFS_MEMDUMP_DIR, NULL);
12264 hddLog(LOG1 , FL("/proc/%s removed\n"), PROCFS_MEMDUMP_DIR);
12265}
12266
12267/**
12268 * memdump_procfs_init() - Initialize procfs for memory dump
12269 *
12270 * @vos_ctx - Global vos context.
12271 *
12272 * This function create file under proc file system to be used later for
12273 * processing firmware memory dump
12274 *
12275 * Return: 0 on success, error code otherwise.
12276 */
12277static int memdump_procfs_init(void *vos_ctx)
12278{
12279 hdd_context_t *hdd_ctx;
12280
12281 hdd_ctx = vos_get_context(VOS_MODULE_ID_HDD, vos_ctx);
12282 if (!hdd_ctx) {
12283 hddLog(LOGE , FL("Invalid HDD context"));
12284 return -EINVAL;
12285 }
12286
12287 proc_dir = proc_mkdir(PROCFS_MEMDUMP_DIR, NULL);
12288 if (proc_dir == NULL) {
12289 remove_proc_entry(PROCFS_MEMDUMP_DIR, NULL);
12290 hddLog(LOGE , FL("Error: Could not initialize /proc/%s"),
12291 PROCFS_MEMDUMP_DIR);
12292 return -ENOMEM;
12293 }
12294
12295 proc_file = proc_create_data(PROCFS_MEMDUMP_NAME,
12296 S_IRUSR | S_IWUSR, proc_dir,
12297 &memdump_fops, hdd_ctx);
12298 if (proc_file == NULL) {
12299 remove_proc_entry(PROCFS_MEMDUMP_NAME, proc_dir);
12300 hddLog(LOGE , FL("Error: Could not initialize /proc/%s"),
12301 PROCFS_MEMDUMP_NAME);
12302 return -ENOMEM;
12303 }
12304
12305 hddLog(LOG1 , FL("/proc/%s/%s created"),
12306 PROCFS_MEMDUMP_DIR, PROCFS_MEMDUMP_NAME);
12307
12308 return 0;
12309}
12310
12311/**
12312 * memdump_init() - Initialization function for memory dump feature
12313 *
12314 * This function creates proc file for memdump feature and registers
12315 * HDD callback function with SME.
12316 *
12317 * Return - 0 on success, error otherwise
12318 */
12319int memdump_init(void)
12320{
12321 hdd_context_t *hdd_ctx;
12322 void *vos_ctx;
12323 int status = 0;
12324
12325 vos_ctx = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
12326 if (!vos_ctx) {
12327 hddLog(LOGE, FL("Invalid VOS context"));
12328 return -EINVAL;
12329 }
12330
12331 hdd_ctx = vos_get_context(VOS_MODULE_ID_HDD, vos_ctx);
12332 if (!hdd_ctx) {
12333 hddLog(LOGE , FL("Invalid HDD context"));
12334 return -EINVAL;
12335 }
12336
12337 status = memdump_procfs_init(vos_ctx);
12338 if (status) {
12339 hddLog(LOGE , FL("Failed to create proc file"));
12340 return status;
12341 }
12342
12343 return 0;
12344}
12345
12346/**
12347 * memdump_deinit() - De initialize memdump feature
12348 *
12349 * This function removes proc file created for memdump feature.
12350 *
12351 * Return: None
12352 */
12353int memdump_deinit(void)
12354{
12355 hdd_context_t *hdd_ctx;
12356 void *vos_ctx;
12357
12358 vos_ctx = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
12359 if (!vos_ctx) {
12360 hddLog(LOGE, FL("Invalid VOS context"));
12361 return -EINVAL;
12362 }
12363
12364 hdd_ctx = vos_get_context(VOS_MODULE_ID_HDD, vos_ctx);
12365 if(!hdd_ctx) {
12366 hddLog(LOGE , FL("Invalid HDD context"));
12367 return -EINVAL;
12368 }
12369
12370 memdump_procfs_remove();
12371 return 0;
12372}
12373
12374/**
12375 * wlan_hdd_fw_mem_dump_req(pHddCtx) - common API(cfg80211/ioctl) for requesting fw mem dump to SME
12376 * Return: HAL status
12377 */
12378
12379int wlan_hdd_fw_mem_dump_req(hdd_context_t * pHddCtx)
12380{
12381 tAniFwrDumpReq fw_mem_dump_req={0};
12382 eHalStatus status = eHAL_STATUS_FAILURE;
12383 int ret=0;
12384 ENTER();
12385 /*Check whether a dump request is already going on
12386 *Caution this function will free previously held memory if new dump request is allowed*/
12387 if (!wlan_fwr_mem_dump_test_and_set_write_allowed_bit()) {
12388 hddLog(LOGE, FL("Fw memdump already in progress"));
12389 return -EBUSY;
12390 }
12391 //Allocate memory for fw mem dump buffer
12392 ret = wlan_fwr_mem_dump_buffer_allocation();
12393 if(ret == -EFAULT)
12394 {
12395 hddLog(LOGE, FL("Fwr mem dump not supported by FW"));
12396 return ret;
12397 }
12398 if (0 != ret) {
12399 hddLog(LOGE, FL("Fwr mem Allocation failed"));
12400 return -ENOMEM;
12401 }
12402 fw_mem_dump_req.fwMemDumpReqCallback = wlan_hdd_fw_mem_dump_cb;
12403 fw_mem_dump_req.fwMemDumpReqContext = pHddCtx;
12404 status = sme_FwMemDumpReq(pHddCtx->hHal, &fw_mem_dump_req);
12405 if(eHAL_STATUS_SUCCESS != status)
12406 {
12407 hddLog(VOS_TRACE_LEVEL_ERROR,
12408 "%s: fw_mem_dump_req failed ", __func__);
12409 wlan_free_fwr_mem_dump_buffer();
12410 }
12411 EXIT();
12412
12413 return status;
12414}
12415
Mahesh A Saptasagar67ab9222015-10-21 15:38:41 +053012416void hdd_initialize_adapter_common(hdd_adapter_t *pAdapter)
12417{
12418 if (NULL == pAdapter)
12419 {
12420 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: pAdapter is NULL ", __func__);
12421 return;
12422 }
12423 init_completion(&pAdapter->session_open_comp_var);
12424 init_completion(&pAdapter->session_close_comp_var);
12425 init_completion(&pAdapter->disconnect_comp_var);
12426 init_completion(&pAdapter->linkup_event_var);
12427 init_completion(&pAdapter->cancel_rem_on_chan_var);
12428 init_completion(&pAdapter->rem_on_chan_ready_event);
12429 init_completion(&pAdapter->pno_comp_var);
12430#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
12431 init_completion(&pAdapter->offchannel_tx_event);
12432#endif
12433 init_completion(&pAdapter->tx_action_cnf_event);
12434#ifdef FEATURE_WLAN_TDLS
12435 init_completion(&pAdapter->tdls_add_station_comp);
12436 init_completion(&pAdapter->tdls_del_station_comp);
12437 init_completion(&pAdapter->tdls_mgmt_comp);
12438 init_completion(&pAdapter->tdls_link_establish_req_comp);
12439#endif
12440
12441#ifdef WLAN_FEATURE_RMC
12442 init_completion(&pAdapter->ibss_peer_info_comp);
12443#endif /* WLAN_FEATURE_RMC */
12444 init_completion(&pAdapter->ula_complete);
12445 init_completion(&pAdapter->change_country_code);
12446
12447#ifdef FEATURE_WLAN_BATCH_SCAN
12448 init_completion(&pAdapter->hdd_set_batch_scan_req_var);
12449 init_completion(&pAdapter->hdd_get_batch_scan_req_var);
12450#endif
12451
12452 return;
12453}
c_manjeecfd1efb2015-09-25 19:32:34 +053012454
12455
Jeff Johnson295189b2012-06-20 16:38:30 -070012456//Register the module init/exit functions
12457module_init(hdd_module_init);
12458module_exit(hdd_module_exit);
12459
12460MODULE_LICENSE("Dual BSD/GPL");
12461MODULE_AUTHOR("Qualcomm Atheros, Inc.");
12462MODULE_DESCRIPTION("WLAN HOST DEVICE DRIVER");
12463
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070012464module_param_call(con_mode, con_mode_handler, param_get_int, &con_mode,
12465 S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
Jeff Johnson32d95a32012-09-10 13:15:23 -070012466
Jeff Johnson76052702013-04-16 13:55:05 -070012467module_param_call(fwpath, fwpath_changed_handler, param_get_string, &fwpath,
Jeff Johnson32d95a32012-09-10 13:15:23 -070012468 S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
Arif Hussain66559122013-11-21 10:11:40 -080012469
12470module_param(enable_dfs_chan_scan, int,
12471 S_IRUSR | S_IRGRP | S_IROTH);
12472
12473module_param(enable_11d, int,
12474 S_IRUSR | S_IRGRP | S_IROTH);
12475
12476module_param(country_code, charp,
12477 S_IRUSR | S_IRGRP | S_IROTH);