blob: 5d35da691eba66e6c0580ba9044e7ff0b04ddc16 [file] [log] [blame]
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001/*
Tushnim Bhattacharyyaca50b322015-12-28 17:14:36 -08002 * Copyright (c) 2011-2016 The Linux Foundation. All rights reserved.
Prakash Dhavali7090c5f2015-11-02 17:55:19 -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/*
23 * This file was originally distributed by Qualcomm Atheros, Inc.
24 * under proprietary terms before Copyright ownership was assigned
25 * to the Linux Foundation.
26 */
27
28/**
29 * DOC: wlan_hdd_wext.c
30 *
31 * Linux Wireless Extensions Implementation
32 */
33
Jeff Johnson99bac312016-06-28 10:38:18 -070034/* denote that this file does not allow legacy hddLog */
35#define HDD_DISALLOW_LEGACY_HDDLOG 1
36
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080037#include <linux/version.h>
38#include <linux/module.h>
39#include <linux/kernel.h>
40#include <linux/init.h>
41#include <linux/wireless.h>
42#include <mac_trace.h>
43#include <wlan_hdd_includes.h>
44#include <cds_api.h>
45#include <net/arp.h>
Manjunathappa Prakash3454fd62016-04-01 08:52:06 -070046#include <cdp_txrx_stats.h>
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080047#include "sir_params.h"
48#include "csr_api.h"
49#include "csr_inside_api.h"
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080050#include "sme_rrm_internal.h"
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080051#include <ani_global.h>
52#include "dot11f.h"
53#include <wlan_hdd_wowl.h>
54#include <wlan_hdd_cfg.h>
55#include <wlan_hdd_wmm.h>
56#include "utils_api.h"
57#include "wlan_hdd_p2p.h"
58#ifdef FEATURE_WLAN_TDLS
59#include "wlan_hdd_tdls.h"
60#endif
61
62#include "cds_ieee80211_common.h"
63#include "ol_if_athvar.h"
64#include "dbglog_host.h"
65#include "wma.h"
66
67#include "wlan_hdd_power.h"
68#include "qwlan_version.h"
69#include "wlan_hdd_host_offload.h"
70
71#include <linux/wireless.h>
72#include <net/cfg80211.h>
73
74#include "wlan_hdd_misc.h"
75
76#include "qc_sap_ioctl.h"
77#include "sme_api.h"
78#include "wma_types.h"
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +053079#include "qdf_trace.h"
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080080#include "wlan_hdd_assoc.h"
81#include "wlan_hdd_ioctl.h"
82#include "wlan_hdd_scan.h"
83#include "sme_power_save_api.h"
84#include "cds_concurrency.h"
85#include "wlan_hdd_conc_ut.h"
Manikandan Mohandcc21ba2016-03-15 14:31:56 -070086#include "wlan_hdd_tsf.h"
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080087#include "wlan_hdd_ocb.h"
88#include "wlan_hdd_napi.h"
Dhanashri Atreb08959a2016-03-01 17:28:03 -080089#include "cdp_txrx_flow_ctrl_legacy.h"
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -070090#include "wlan_hdd_nan_datapath.h"
Nirav Shahbf1b0332016-05-25 14:27:39 +053091#include "wlan_hdd_stats.h"
Rajeev Kumara78a0a42016-07-13 19:28:20 -070092#ifdef WLAN_SUSPEND_RESUME_TEST
93#include "wlan_hdd_driver_ops.h"
94#include "hif.h"
95#endif
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080096
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080097#define HDD_FINISH_ULA_TIME_OUT 800
98#define HDD_SET_MCBC_FILTERS_TO_FW 1
99#define HDD_DELETE_MCBC_FILTERS_FROM_FW 0
100
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800101static int ioctl_debug;
102module_param(ioctl_debug, int, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
103
104/* To Validate Channel against the Frequency and Vice-Versa */
105static const hdd_freq_chan_map_t freq_chan_map[] = {
106 {2412, 1}, {2417, 2}, {2422, 3}, {2427, 4}, {2432, 5}, {2437, 6},
107 {2442, 7}, {2447, 8}, {2452, 9}, {2457, 10}, {2462, 11}, {2467, 12},
108 {2472, 13}, {2484, 14}, {4920, 240}, {4940, 244}, {4960, 248},
109 {4980, 252}, {5040, 208}, {5060, 212}, {5080, 216}, {5180, 36},
110 {5200, 40}, {5220, 44}, {5240, 48}, {5260, 52}, {5280, 56},
111 {5300, 60}, {5320, 64}, {5500, 100}, {5520, 104}, {5540, 108},
112 {5560, 112}, {5580, 116}, {5600, 120}, {5620, 124}, {5640, 128},
113 {5660, 132}, {5680, 136}, {5700, 140}, {5720, 144}, {5745, 149},
114 {5765, 153}, {5785, 157}, {5805, 161}, {5825, 165}, {5852, 170},
115 {5855, 171}, {5860, 172}, {5865, 173}, {5870, 174}, {5875, 175},
116 {5880, 176}, {5885, 177}, {5890, 178}, {5895, 179}, {5900, 180},
117 {5905, 181}, {5910, 182}, {5915, 183}, {5920, 184} };
118
119#define FREQ_CHAN_MAP_TABLE_SIZE \
120 (sizeof(freq_chan_map) / sizeof(freq_chan_map[0]))
121
122/* Private ioctls and their sub-ioctls */
123#define WLAN_PRIV_SET_INT_GET_NONE (SIOCIWFIRSTPRIV + 0)
124#define WE_SET_11D_STATE 1
125#define WE_WOWL 2
126#define WE_SET_POWER 3
127#define WE_SET_MAX_ASSOC 4
128#define WE_SET_SCAN_DISABLE 5
129#define WE_SET_DATA_INACTIVITY_TO 6
130#define WE_SET_MAX_TX_POWER 7
131#define WE_SET_HIGHER_DTIM_TRANSITION 8
132#define WE_SET_TM_LEVEL 9
133#define WE_SET_PHYMODE 10
134#define WE_SET_NSS 11
135#define WE_SET_LDPC 12
136#define WE_SET_TX_STBC 13
137#define WE_SET_RX_STBC 14
138#define WE_SET_SHORT_GI 15
139#define WE_SET_RTSCTS 16
140#define WE_SET_CHWIDTH 17
141#define WE_SET_ANI_EN_DIS 18
142#define WE_SET_ANI_POLL_PERIOD 19
143#define WE_SET_ANI_LISTEN_PERIOD 20
144#define WE_SET_ANI_OFDM_LEVEL 21
145#define WE_SET_ANI_CCK_LEVEL 22
146#define WE_SET_DYNAMIC_BW 23
147#define WE_SET_TX_CHAINMASK 24
148#define WE_SET_RX_CHAINMASK 25
149#define WE_SET_11N_RATE 26
150#define WE_SET_AMPDU 27
151#define WE_SET_AMSDU 28
152#define WE_SET_TXPOW_2G 29
153#define WE_SET_TXPOW_5G 30
154/* Private ioctl for firmware debug log */
155#define WE_DBGLOG_LOG_LEVEL 31
156#define WE_DBGLOG_VAP_ENABLE 32
157#define WE_DBGLOG_VAP_DISABLE 33
158#define WE_DBGLOG_MODULE_ENABLE 34
159#define WE_DBGLOG_MODULE_DISABLE 35
160#define WE_DBGLOG_MOD_LOG_LEVEL 36
161#define WE_DBGLOG_TYPE 37
162#define WE_SET_TXRX_FWSTATS 38
163#define WE_SET_VHT_RATE 39
164#define WE_DBGLOG_REPORT_ENABLE 40
165#define WE_TXRX_FWSTATS_RESET 41
166#define WE_SET_MAX_TX_POWER_2_4 42
167#define WE_SET_MAX_TX_POWER_5_0 43
Srinivas Girigowdac34f11d2016-02-25 16:02:42 -0800168#define WE_SET_PKTLOG 44
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800169/* Private ioctl for packet powe save */
170#define WE_PPS_PAID_MATCH 45
171#define WE_PPS_GID_MATCH 46
172#define WE_PPS_EARLY_TIM_CLEAR 47
173#define WE_PPS_EARLY_DTIM_CLEAR 48
174#define WE_PPS_EOF_PAD_DELIM 49
175#define WE_PPS_MACADDR_MISMATCH 50
176#define WE_PPS_DELIM_CRC_FAIL 51
177#define WE_PPS_GID_NSTS_ZERO 52
178#define WE_PPS_RSSI_CHECK 53
179#define WE_SET_SAP_AUTO_CHANNEL_SELECTION 54
180#define WE_SET_HTSMPS 55
181/* Private ioctl for QPower */
182#define WE_SET_QPOWER_MAX_PSPOLL_COUNT 56
183#define WE_SET_QPOWER_MAX_TX_BEFORE_WAKE 57
184#define WE_SET_QPOWER_SPEC_PSPOLL_WAKE_INTERVAL 58
185#define WE_SET_QPOWER_SPEC_MAX_SPEC_NODATA_PSPOLL 59
186
187#define WE_SET_BURST_ENABLE 60
188#define WE_SET_BURST_DUR 61
189/* GTX Commands */
190#define WE_SET_GTX_HT_MCS 62
191#define WE_SET_GTX_VHT_MCS 63
192#define WE_SET_GTX_USRCFG 64
193#define WE_SET_GTX_THRE 65
194#define WE_SET_GTX_MARGIN 66
195#define WE_SET_GTX_STEP 67
196#define WE_SET_GTX_MINTPC 68
197#define WE_SET_GTX_BWMASK 69
198/* Private ioctl to configure MCC home channels time quota and latency */
199#define WE_MCC_CONFIG_LATENCY 70
200#define WE_MCC_CONFIG_QUOTA 71
201/* Private IOCTL for debug connection issues */
202#define WE_SET_DEBUG_LOG 72
203#ifdef WE_SET_TX_POWER
204#undef WE_SET_TX_POWER
205#endif
206#define WE_SET_TX_POWER 74
207/* Private ioctl for earlyrx power save feature */
208#define WE_SET_EARLY_RX_ADJUST_ENABLE 75
209#define WE_SET_EARLY_RX_TGT_BMISS_NUM 76
210#define WE_SET_EARLY_RX_BMISS_SAMPLE_CYCLE 77
211#define WE_SET_EARLY_RX_SLOP_STEP 78
212#define WE_SET_EARLY_RX_INIT_SLOP 79
213#define WE_SET_EARLY_RX_ADJUST_PAUSE 80
214#define WE_SET_MC_RATE 81
215#define WE_SET_EARLY_RX_DRIFT_SAMPLE 82
216/* Private ioctl for packet power save */
217#define WE_PPS_5G_EBT 83
218#define WE_SET_CTS_CBW 84
219#define WE_DUMP_STATS 85
220#define WE_CLEAR_STATS 86
Govind Singha471e5e2015-10-12 17:11:14 +0530221/* Private sub ioctl for starting/stopping the profiling */
222#define WE_START_FW_PROFILE 87
Abhishek Singh1bdb1572015-10-16 16:24:19 +0530223#define WE_SET_CHANNEL 88
Manishekar Chandrasekaran97e077d2016-03-23 17:10:31 +0530224#define WE_SET_CONC_SYSTEM_PREF 89
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800225
226/* Private ioctls and their sub-ioctls */
227#define WLAN_PRIV_SET_NONE_GET_INT (SIOCIWFIRSTPRIV + 1)
228#define WE_GET_11D_STATE 1
229#define WE_IBSS_STATUS 2
230#define WE_SET_SAP_CHANNELS 3
231#define WE_GET_WLAN_DBG 4
232#define WE_GET_MAX_ASSOC 6
233/* 7 is unused */
234#define WE_GET_SAP_AUTO_CHANNEL_SELECTION 8
235#define WE_GET_CONCURRENCY_MODE 9
236#define WE_GET_NSS 11
237#define WE_GET_LDPC 12
238#define WE_GET_TX_STBC 13
239#define WE_GET_RX_STBC 14
240#define WE_GET_SHORT_GI 15
241#define WE_GET_RTSCTS 16
242#define WE_GET_CHWIDTH 17
243#define WE_GET_ANI_EN_DIS 18
244#define WE_GET_ANI_POLL_PERIOD 19
245#define WE_GET_ANI_LISTEN_PERIOD 20
246#define WE_GET_ANI_OFDM_LEVEL 21
247#define WE_GET_ANI_CCK_LEVEL 22
248#define WE_GET_DYNAMIC_BW 23
249#define WE_GET_TX_CHAINMASK 24
250#define WE_GET_RX_CHAINMASK 25
251#define WE_GET_11N_RATE 26
252#define WE_GET_AMPDU 27
253#define WE_GET_AMSDU 28
254#define WE_GET_TXPOW_2G 29
255#define WE_GET_TXPOW_5G 30
Rajeev Kumar1bcfd632015-12-07 11:38:51 -0800256/* 31 is unused */
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800257#define WE_GET_PPS_PAID_MATCH 32
258#define WE_GET_PPS_GID_MATCH 33
259#define WE_GET_PPS_EARLY_TIM_CLEAR 34
260#define WE_GET_PPS_EARLY_DTIM_CLEAR 35
261#define WE_GET_PPS_EOF_PAD_DELIM 36
262#define WE_GET_PPS_MACADDR_MISMATCH 37
263#define WE_GET_PPS_DELIM_CRC_FAIL 38
264#define WE_GET_PPS_GID_NSTS_ZERO 39
265#define WE_GET_PPS_RSSI_CHECK 40
266/* Private ioctl for QPower */
267#define WE_GET_QPOWER_MAX_PSPOLL_COUNT 41
268#define WE_GET_QPOWER_MAX_TX_BEFORE_WAKE 42
269#define WE_GET_QPOWER_SPEC_PSPOLL_WAKE_INTERVAL 43
270#define WE_GET_QPOWER_SPEC_MAX_SPEC_NODATA_PSPOLL 44
271#define WE_GET_BURST_ENABLE 45
272#define WE_GET_BURST_DUR 46
273/* GTX Commands */
274#define WE_GET_GTX_HT_MCS 47
275#define WE_GET_GTX_VHT_MCS 48
276#define WE_GET_GTX_USRCFG 49
277#define WE_GET_GTX_THRE 50
278#define WE_GET_GTX_MARGIN 51
279#define WE_GET_GTX_STEP 52
280#define WE_GET_GTX_MINTPC 53
281#define WE_GET_GTX_BWMASK 54
282#define WE_GET_TEMPERATURE 56
Manikandan Mohandcc21ba2016-03-15 14:31:56 -0700283#define WE_CAP_TSF 58
Varun Reddy Yeturu5ab47462016-05-08 18:08:11 -0700284#define WE_GET_ROAM_SYNCH_DELAY 59
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800285
286/* Private ioctls and their sub-ioctls */
287#define WLAN_PRIV_SET_INT_GET_INT (SIOCIWFIRSTPRIV + 2)
288
289/* Private ioctls and their sub-ioctls */
290#define WLAN_PRIV_SET_CHAR_GET_NONE (SIOCIWFIRSTPRIV + 3)
291#define WE_WOWL_ADD_PTRN 1
292#define WE_WOWL_DEL_PTRN 2
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800293#define WE_NEIGHBOR_REPORT_REQUEST 3
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800294#define WE_SET_AP_WPS_IE 4 /* This is called in station mode to set probe rsp ie. */
295#define WE_SET_CONFIG 5
296
297/* Private ioctls and their sub-ioctls */
298#define WLAN_PRIV_SET_THREE_INT_GET_NONE (SIOCIWFIRSTPRIV + 4)
299#define WE_SET_WLAN_DBG 1
300#define WE_SET_DP_TRACE 2
301#define WE_SET_SAP_CHANNELS 3
302
303/* Private ioctls and their sub-ioctls */
304#define WLAN_PRIV_GET_CHAR_SET_NONE (SIOCIWFIRSTPRIV + 5)
305#define WE_WLAN_VERSION 1
306#define WE_GET_STATS 2
307#define WE_GET_CFG 3
308#define WE_GET_WMM_STATUS 4
309#define WE_GET_CHANNEL_LIST 5
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800310#define WE_GET_RSSI 6
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800311#ifdef FEATURE_WLAN_TDLS
312#define WE_GET_TDLS_PEERS 8
313#endif
314#ifdef WLAN_FEATURE_11W
315#define WE_GET_11W_INFO 9
316#endif
317#define WE_GET_STATES 10
Rajeev Kumar8e3e2832015-11-06 16:02:54 -0800318#define WE_GET_IBSS_STA_INFO 11
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800319#define WE_GET_PHYMODE 12
320#ifdef FEATURE_OEM_DATA_SUPPORT
321#define WE_GET_OEM_DATA_CAP 13
322#endif
323#define WE_GET_SNR 14
Govind Singha471e5e2015-10-12 17:11:14 +0530324#define WE_LIST_FW_PROFILE 15
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800325
326/* Private ioctls and their sub-ioctls */
327#define WLAN_PRIV_SET_NONE_GET_NONE (SIOCIWFIRSTPRIV + 6)
328#define WE_SET_REASSOC_TRIGGER 8
Rajeev Kumar8e3e2832015-11-06 16:02:54 -0800329#define WE_IBSS_GET_PEER_INFO_ALL 10
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800330#define WE_DUMP_AGC_START 11
331#define WE_DUMP_AGC 12
332#define WE_DUMP_CHANINFO_START 13
333#define WE_DUMP_CHANINFO 14
334#define WE_DUMP_WATCHDOG 15
335#ifdef CONFIG_ATH_PCIE_ACCESS_DEBUG
336#define WE_DUMP_PCIE_LOG 16
337#endif
338#define WE_GET_RECOVERY_STAT 17
Sandeep Puligilla93a29ec2016-02-12 16:10:56 -0800339#define WE_GET_FW_PROFILE_DATA 18
340#define WE_STOP_OBSS_SCAN 19
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800341
342/* Private ioctls and their sub-ioctls */
343#define WLAN_PRIV_SET_VAR_INT_GET_NONE (SIOCIWFIRSTPRIV + 7)
344
345#define WE_P2P_NOA_CMD 2
Manjeet Singhf82ed072016-07-08 11:40:00 +0530346/* subcommands 3 is unused */
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800347
Manjeet Singhf82ed072016-07-08 11:40:00 +0530348#define WE_MAC_PWR_DEBUG_CMD 4
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800349
350#ifdef FEATURE_WLAN_TDLS
351#define WE_TDLS_CONFIG_PARAMS 5
352#endif
Rajeev Kumar8e3e2832015-11-06 16:02:54 -0800353#define WE_IBSS_GET_PEER_INFO 6
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800354#define WE_UNIT_TEST_CMD 7
355
356#define WE_MTRACE_DUMP_CMD 8
357#define WE_MTRACE_SELECTIVE_MODULE_LOG_ENABLE_CMD 9
358
359
360#ifdef WLAN_FEATURE_GPIO_LED_FLASHING
361#define WE_LED_FLASHING_PARAM 10
362#endif
363
364#define WE_POLICY_MANAGER_CLIST_CMD 11
365#define WE_POLICY_MANAGER_DLIST_CMD 12
366#define WE_POLICY_MANAGER_DBS_CMD 13
367#define WE_POLICY_MANAGER_PCL_CMD 14
368#define WE_POLICY_MANAGER_CINFO_CMD 15
369#define WE_POLICY_MANAGER_ULIST_CMD 16
370#define WE_POLICY_MANAGER_QUERY_ACTION_CMD 17
371#define WE_POLICY_MANAGER_QUERY_ALLOW_CMD 18
372#define WE_POLICY_MANAGER_SCENARIO_CMD 19
373#define WE_POLICY_SET_HW_MODE_CMD 20
374
375#define WE_SET_DUAL_MAC_SCAN_CONFIG 21
376#define WE_SET_DUAL_MAC_FW_MODE_CONFIG 22
Manjunathappa Prakash59f861d2016-04-21 10:33:31 -0700377#define WE_SET_MON_MODE_CHAN 23
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800378
379#ifdef FEATURE_WLAN_TDLS
380#undef MAX_VAR_ARGS
381#define MAX_VAR_ARGS 11
382#else
383#undef MAX_VAR_ARGS
384#define MAX_VAR_ARGS 9
385#endif
386
387/* Private ioctls (with no sub-ioctls) */
388/* note that they must be odd so that they have "get" semantics */
389#define WLAN_PRIV_ADD_TSPEC (SIOCIWFIRSTPRIV + 9)
390#define WLAN_PRIV_DEL_TSPEC (SIOCIWFIRSTPRIV + 11)
391#define WLAN_PRIV_GET_TSPEC (SIOCIWFIRSTPRIV + 13)
392
393/* (SIOCIWFIRSTPRIV + 8) is currently unused */
394/* (SIOCIWFIRSTPRIV + 10) is currently unused */
395/* (SIOCIWFIRSTPRIV + 12) is currently unused */
396/* (SIOCIWFIRSTPRIV + 14) is currently unused */
Manikandan Mohandcc21ba2016-03-15 14:31:56 -0700397#define WLAN_PRIV_SET_NONE_GET_THREE_INT (SIOCIWFIRSTPRIV + 15)
398#define WE_GET_TSF 1
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800399/* (SIOCIWFIRSTPRIV + 16) is currently unused */
400/* (SIOCIWFIRSTPRIV + 17) is currently unused */
401/* (SIOCIWFIRSTPRIV + 19) is currently unused */
402
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800403#define WLAN_PRIV_SET_FTIES (SIOCIWFIRSTPRIV + 20)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800404
405/* Private ioctl for setting the host offload feature */
406#define WLAN_PRIV_SET_HOST_OFFLOAD (SIOCIWFIRSTPRIV + 18)
407
408/* Private ioctl to get the statistics */
409#define WLAN_GET_WLAN_STATISTICS (SIOCIWFIRSTPRIV + 21)
410
411/* Private ioctl to set the Keep Alive Params */
412#define WLAN_SET_KEEPALIVE_PARAMS (SIOCIWFIRSTPRIV + 22)
413
414#ifdef WLAN_FEATURE_PACKET_FILTERING
415/* Private ioctl to set the packet filtering params */
416#define WLAN_SET_PACKET_FILTER_PARAMS (SIOCIWFIRSTPRIV + 23)
417#endif
418
419
420#ifdef FEATURE_WLAN_SCAN_PNO
421/* Private ioctl to get the statistics */
422#define WLAN_SET_PNO (SIOCIWFIRSTPRIV + 24)
423#endif
424
425#define WLAN_SET_BAND_CONFIG (SIOCIWFIRSTPRIV + 25)
426
427/* (SIOCIWFIRSTPRIV + 26) is currently unused */
428/* (SIOCIWFIRSTPRIV + 27) is currently unused */
429
430/* Private ioctls and their sub-ioctls */
431#define WLAN_PRIV_SET_TWO_INT_GET_NONE (SIOCIWFIRSTPRIV + 28)
432#define WE_SET_SMPS_PARAM 1
433#ifdef DEBUG
434#define WE_SET_FW_CRASH_INJECT 2
435#endif
436#define WE_DUMP_DP_TRACE_LEVEL 3
Govind Singha471e5e2015-10-12 17:11:14 +0530437/* Private sub ioctl for enabling and setting histogram interval of profiling */
438#define WE_ENABLE_FW_PROFILE 4
439#define WE_SET_FW_PROFILE_HIST_INTVL 5
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800440
Rajeev Kumara78a0a42016-07-13 19:28:20 -0700441#ifdef WLAN_SUSPEND_RESUME_TEST
442#define WE_SET_WLAN_SUSPEND 6
443#define WE_SET_WLAN_RESUME 7
444#endif
445
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800446/* (SIOCIWFIRSTPRIV + 29) is currently unused */
447
448/* 802.11p IOCTL */
449#define WLAN_SET_DOT11P_CHANNEL_SCHED (SIOCIWFIRSTPRIV + 30)
450
451#define WLAN_GET_LINK_SPEED (SIOCIWFIRSTPRIV + 31)
452
453#define WLAN_STATS_INVALID 0
454#define WLAN_STATS_RETRY_CNT 1
455#define WLAN_STATS_MUL_RETRY_CNT 2
456#define WLAN_STATS_TX_FRM_CNT 3
457#define WLAN_STATS_RX_FRM_CNT 4
458#define WLAN_STATS_FRM_DUP_CNT 5
459#define WLAN_STATS_FAIL_CNT 6
460#define WLAN_STATS_RTS_FAIL_CNT 7
461#define WLAN_STATS_ACK_FAIL_CNT 8
462#define WLAN_STATS_RTS_SUC_CNT 9
463#define WLAN_STATS_RX_DISCARD_CNT 10
464#define WLAN_STATS_RX_ERROR_CNT 11
465#define WLAN_STATS_TX_BYTE_CNT 12
466
467#define WLAN_STATS_RX_BYTE_CNT 13
468#define WLAN_STATS_RX_RATE 14
469#define WLAN_STATS_TX_RATE 15
470
471#define WLAN_STATS_RX_UC_BYTE_CNT 16
472#define WLAN_STATS_RX_MC_BYTE_CNT 17
473#define WLAN_STATS_RX_BC_BYTE_CNT 18
474#define WLAN_STATS_TX_UC_BYTE_CNT 19
475#define WLAN_STATS_TX_MC_BYTE_CNT 20
476#define WLAN_STATS_TX_BC_BYTE_CNT 21
477
478#define FILL_TLV(__p, __type, __size, __val, __tlen) do { \
479 if ((__tlen + __size + 2) < WE_MAX_STR_LEN) { \
480 *__p++ = __type; \
481 *__p++ = __size; \
482 memcpy(__p, __val, __size); \
483 __p += __size; \
484 __tlen += __size + 2; \
485 } else { \
Jeff Johnson99bac312016-06-28 10:38:18 -0700486 hdd_err("FILL_TLV Failed!!!"); \
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800487 } \
488 } while (0)
489
490#define VERSION_VALUE_MAX_LEN 32
491
492#define TX_PER_TRACKING_DEFAULT_RATIO 5
493#define TX_PER_TRACKING_MAX_RATIO 10
494#define TX_PER_TRACKING_DEFAULT_WATERMARK 5
495
496#define WLAN_ADAPTER 0
497#define P2P_ADAPTER 1
498
499/**
500 * mem_alloc_copy_from_user_helper - copy from user helper
501 * @wrqu_data: wireless extensions request data
502 * @len: length of @wrqu_data
503 *
504 * Helper function to allocate buffer and copy user data.
505 *
506 * Return: On success return a pointer to a kernel buffer containing a
507 * copy of the userspace data (with an additional NUL character
508 * appended for safety). On failure return %NULL.
509 */
510void *mem_alloc_copy_from_user_helper(const __user void *wrqu_data, size_t len)
511{
512 u8 *ptr = NULL;
513
514 /* in order to protect the code, an extra byte is post
515 * appended to the buffer and the null termination is added.
516 * However, when allocating (len+1) byte of memory, we need to
517 * make sure that there is no uint overflow when doing
518 * addition. In theory check len < UINT_MAX protects the uint
519 * overflow. For wlan private ioctl, the buffer size is much
520 * less than UINT_MAX, as a good guess, now, it is assumed
521 * that the private command buffer size is no greater than 4K
522 * (4096 bytes). So we use 4096 as the upper boundary for now.
523 */
524 if (len > MAX_USER_COMMAND_SIZE) {
Jeff Johnson99bac312016-06-28 10:38:18 -0700525 hdd_err("Invalid length");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800526 return NULL;
527 }
528
529 ptr = kmalloc(len + 1, GFP_KERNEL);
530 if (NULL == ptr) {
Jeff Johnson99bac312016-06-28 10:38:18 -0700531 hdd_err("unable to allocate memory");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800532 return NULL;
533 }
534
535 if (copy_from_user(ptr, wrqu_data, len)) {
Jeff Johnson99bac312016-06-28 10:38:18 -0700536 hdd_err("failed to copy data to user buffer");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800537 kfree(ptr);
538 return NULL;
539 }
540 ptr[len] = '\0';
541 return ptr;
542}
543
544/**
545 * hdd_priv_get_data() - Get pointer to ioctl private data
546 * @p_priv_data: pointer to iw_point struct to be filled
547 * @wrqu: Pointer to IOCTL Data received from userspace
548 *
549 * Helper function to get compatible struct iw_point passed to ioctl
550 *
551 * Return - 0 if p_priv_data successfully filled, error otherwise
552 */
553int hdd_priv_get_data(struct iw_point *p_priv_data, union iwreq_data *wrqu)
554{
555 if ((NULL == p_priv_data) || (NULL == wrqu)) {
556 return -EINVAL;
557 }
558#ifdef CONFIG_COMPAT
559 if (is_compat_task()) {
560 struct compat_iw_point *p_compat_priv_data;
561
562 /* Compat task:
563 * typecast to compat structure and copy the members.
564 */
565 p_compat_priv_data = (struct compat_iw_point *)&wrqu->data;
566
567 p_priv_data->pointer = compat_ptr(p_compat_priv_data->pointer);
568 p_priv_data->length = p_compat_priv_data->length;
569 p_priv_data->flags = p_compat_priv_data->flags;
570 } else {
571#endif /* #ifdef CONFIG_COMPAT */
572
573 /* Non compat task: directly copy the structure. */
574 memcpy(p_priv_data, &wrqu->data, sizeof(struct iw_point));
575
576#ifdef CONFIG_COMPAT
577 }
578#endif /* #ifdef CONFIG_COMPAT */
579
580 return 0;
581}
582
583
584/**
585 * hdd_wlan_get_stats() - Get txrx stats in SAP mode
586 * @pAdapter: Pointer to the hdd adapter.
587 * @length: Size of the data copied
588 * @buffer: Pointer to char buffer.
589 * @buf_len: Length of the char buffer.
590 *
591 * This function called when the "iwpriv wlan0 get_stats" command is given.
592 * It used to collect the txrx stats when the device is configured in SAP mode.
593 *
594 * Return - none
595 */
596void hdd_wlan_get_stats(hdd_adapter_t *pAdapter, uint16_t *length,
597 char *buffer, uint16_t buf_len)
598{
599 hdd_tx_rx_stats_t *pStats = &pAdapter->hdd_stats.hddTxRxStats;
600 uint32_t len = 0;
601 uint32_t total_rx_pkt = 0, total_rx_dropped = 0;
602 uint32_t total_rx_delv = 0, total_rx_refused = 0;
603 int i = 0;
604
605 for (; i < NUM_CPUS; i++) {
606 total_rx_pkt += pStats->rxPackets[i];
607 total_rx_dropped += pStats->rxDropped[i];
608 total_rx_delv += pStats->rxDelivered[i];
609 total_rx_refused += pStats->rxRefused[i];
610 }
611
612 len = scnprintf(buffer, buf_len,
613 "\nTransmit"
614 "\ncalled %u, dropped %u,"
615 "\n dropped BK %u, BE %u, VI %u, VO %u"
616 "\n classified BK %u, BE %u, VI %u, VO %u"
617 "\ncompleted %u,"
618 "\n\nReceive Total"
619 "\n packets %u, dropped %u, delivered %u, refused %u"
620 "\n",
621 pStats->txXmitCalled,
622 pStats->txXmitDropped,
623
624 pStats->txXmitDroppedAC[SME_AC_BK],
625 pStats->txXmitDroppedAC[SME_AC_BE],
626 pStats->txXmitDroppedAC[SME_AC_VI],
627 pStats->txXmitDroppedAC[SME_AC_VO],
628
629 pStats->txXmitClassifiedAC[SME_AC_BK],
630 pStats->txXmitClassifiedAC[SME_AC_BE],
631 pStats->txXmitClassifiedAC[SME_AC_VI],
632 pStats->txXmitClassifiedAC[SME_AC_VO],
633
634 pStats->txCompleted,
635 total_rx_pkt, total_rx_dropped, total_rx_delv, total_rx_refused
636 );
637
638 for (i = 0; i < NUM_CPUS; i++) {
639 len += scnprintf(buffer + len, buf_len - len,
640 "\nReceive CPU: %d"
641 "\n packets %u, dropped %u, delivered %u, refused %u",
642 i, pStats->rxPackets[i], pStats->rxDropped[i],
643 pStats->rxDelivered[i], pStats->rxRefused[i]);
644 }
645
646 len += scnprintf(buffer + len, buf_len - len,
647 "\n\nTX_FLOW"
648 "\nCurrent status: %s"
649 "\ntx-flow timer start count %u"
650 "\npause count %u, unpause count %u",
651 (pStats->is_txflow_paused == true ? "PAUSED" : "UNPAUSED"),
652 pStats->txflow_timer_cnt,
653 pStats->txflow_pause_cnt,
654 pStats->txflow_unpause_cnt);
655
656 len += ol_txrx_stats(pAdapter->sessionId,
657 &buffer[len], (buf_len - len));
658
659 len += hdd_napi_stats(buffer + len, buf_len - len,
660 NULL, hdd_napi_get_all());
661
662 *length = len + 1;
663}
664
665/**
Govind Singha471e5e2015-10-12 17:11:14 +0530666 * hdd_wlan_list_fw_profile() - Get fw profiling points
667 * @length: Size of the data copied
668 * @buffer: Pointer to char buffer.
669 * @buf_len: Length of the char buffer.
670 *
671 * This function called when the "iwpriv wlan0 listProfile" command is given.
672 * It is used to get the supported profiling points in FW.
673 *
674 * Return - none
675 */
676void hdd_wlan_list_fw_profile(uint16_t *length,
677 char *buffer, uint16_t buf_len)
678{
679 uint32_t len = 0;
680
681 len = scnprintf(buffer, buf_len,
682 "PROF_CPU_IDLE: %u\n"
683 "PROF_PPDU_PROC: %u\n"
684 "PROF_PPDU_POST: %u\n"
685 "PROF_HTT_TX_INPUT: %u\n"
686 "PROF_MSDU_ENQ: %u\n"
687 "PROF_PPDU_POST_HAL: %u\n"
688 "PROF_COMPUTE_TX_TIME: %u\n",
689 PROF_CPU_IDLE,
690 PROF_PPDU_PROC,
691 PROF_PPDU_POST,
692 PROF_HTT_TX_INPUT,
693 PROF_MSDU_ENQ,
694 PROF_PPDU_POST_HAL,
695 PROF_COMPUTE_TX_TIME);
696
697 *length = len + 1;
698}
699
700/**
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800701 * hdd_wlan_dump_stats() - display dump Stats
702 * @adapter: adapter handle
703 * @value: value from user
704 *
705 * Return: none
706 */
707void hdd_wlan_dump_stats(hdd_adapter_t *adapter, int value)
708{
709 hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
710
711 switch (value) {
712
713 case WLAN_TXRX_HIST_STATS:
714 wlan_hdd_display_tx_rx_histogram(hdd_ctx);
715 break;
716 case WLAN_HDD_NETIF_OPER_HISTORY:
717 wlan_hdd_display_netif_queue_history(hdd_ctx);
718 break;
Nirav Shahbf1b0332016-05-25 14:27:39 +0530719 case WLAN_HIF_STATS:
720 hdd_display_hif_stats();
721 break;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800722 default:
723 ol_txrx_display_stats(value);
724 break;
725 }
726}
727
728/**
729 * hdd_wlan_get_version() - Get driver version information
Arun Khandavallia96c2c02016-05-17 19:15:34 +0530730 * @hdd_ctx: Global HDD context
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800731 * @wrqu: Pointer to IOCTL REQUEST Data.
732 * @extra: Pointer to destination buffer
733 *
734 * This function is used to get Wlan Driver, Firmware, & Hardware
735 * Version information. If @wrqu and @extra are specified, then the
736 * version string is returned. Otherwise it is simply printed to the
737 * kernel log.
738 *
739 * Return: none
740 */
Arun Khandavallia96c2c02016-05-17 19:15:34 +0530741void hdd_wlan_get_version(hdd_context_t *hdd_ctx, union iwreq_data *wrqu,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800742 char *extra)
743{
Arun Khandavallia96c2c02016-05-17 19:15:34 +0530744 tSirVersionString wcnss_sw_version;
745 const char *swversion;
746 const char *hwversion;
747 uint32_t msp_id = 0, mspid = 0, siid = 0, crmid = 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800748
Arun Khandavallia96c2c02016-05-17 19:15:34 +0530749 if (!hdd_ctx) {
Jeff Johnson99bac312016-06-28 10:38:18 -0700750 hdd_err("Invalid context, HDD context is null");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800751 goto error;
752 }
753
Arun Khandavallia96c2c02016-05-17 19:15:34 +0530754 snprintf(wcnss_sw_version, sizeof(wcnss_sw_version), "%08x",
755 hdd_ctx->target_fw_version);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800756
Arun Khandavallia96c2c02016-05-17 19:15:34 +0530757 swversion = wcnss_sw_version;
758 msp_id = (hdd_ctx->target_fw_version & 0xf0000000) >> 28;
759 mspid = (hdd_ctx->target_fw_version & 0xf000000) >> 24;
760 siid = (hdd_ctx->target_fw_version & 0xf00000) >> 20;
761 crmid = hdd_ctx->target_fw_version & 0x7fff;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800762
Arun Khandavallia96c2c02016-05-17 19:15:34 +0530763 hwversion = hdd_ctx->target_hw_name;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800764
765 if (wrqu && extra) {
766 wrqu->data.length =
767 scnprintf(extra, WE_MAX_STR_LEN,
768 "Host SW:%s, FW:%d.%d.%d.%d, HW:%s",
769 QWLAN_VERSIONSTR,
Arun Khandavallia96c2c02016-05-17 19:15:34 +0530770 msp_id, mspid, siid, crmid, hwversion);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800771 } else {
772 pr_info("Host SW:%s, FW:%d.%d.%d.%d, HW:%s\n",
773 QWLAN_VERSIONSTR,
Arun Khandavallia96c2c02016-05-17 19:15:34 +0530774 msp_id, mspid, siid, crmid, hwversion);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800775 }
776error:
777 return;
778}
779
780/**
Rajeev Kumar8e3e2832015-11-06 16:02:54 -0800781 * hdd_wlan_get_ibss_mac_addr_from_staid() - Get IBSS MAC address
782 * @pAdapter: Adapter upon which the IBSS client is active
783 * @staIdx: Station index of the IBSS peer
784 *
785 * Return: a pointer to the MAC address of the IBSS peer if the peer is
786 * found, otherwise %NULL.
787 */
788struct qdf_mac_addr *
789hdd_wlan_get_ibss_mac_addr_from_staid(hdd_adapter_t *pAdapter,
790 uint8_t staIdx)
791{
792 uint8_t idx;
793 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
794
Naveen Rawatc45d1622016-07-05 12:20:09 -0700795 for (idx = 0; idx < MAX_PEERS; idx++) {
Rajeev Kumar8e3e2832015-11-06 16:02:54 -0800796 if (0 != pHddStaCtx->conn_info.staId[idx] &&
797 staIdx == pHddStaCtx->conn_info.staId[idx]) {
798 return &pHddStaCtx->conn_info.peerMacAddress[idx];
799 }
800 }
801 return NULL;
802}
803
804/**
805 * hdd_wlan_get_ibss_peer_info() - Print IBSS peer information
806 * @pAdapter: Adapter upon which the IBSS client is active
807 * @staIdx: Station index of the IBSS peer
808 *
809 * Return: QDF_STATUS_STATUS if the peer was found and displayed,
810 * otherwise an appropriate QDF_STATUS_E_* failure code.
811 */
812QDF_STATUS hdd_wlan_get_ibss_peer_info(hdd_adapter_t *pAdapter, uint8_t staIdx)
813{
814 QDF_STATUS status = QDF_STATUS_E_FAILURE;
815 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
816 hdd_station_ctx_t *pStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Rajeev Kumar94c9b452016-03-24 12:58:47 -0700817 tSirPeerInfoRspParams *pPeerInfo = &pStaCtx->ibss_peer_info;
Rajeev Kumar8e3e2832015-11-06 16:02:54 -0800818
819 status =
820 sme_request_ibss_peer_info(hHal, pAdapter, hdd_get_ibss_peer_info_cb,
821 false, staIdx);
822
823 INIT_COMPLETION(pAdapter->ibss_peer_info_comp);
824
825 if (QDF_STATUS_SUCCESS == status) {
826 unsigned long rc;
827 rc = wait_for_completion_timeout
828 (&pAdapter->ibss_peer_info_comp,
829 msecs_to_jiffies(IBSS_PEER_INFO_REQ_TIMOEUT));
830 if (!rc) {
Jeff Johnson99bac312016-06-28 10:38:18 -0700831 hdd_err("failed wait on ibss_peer_info_comp");
Rajeev Kumar8e3e2832015-11-06 16:02:54 -0800832 return QDF_STATUS_E_FAILURE;
833 }
834
835 /** Print the peer info */
Rajeev Kumar94c9b452016-03-24 12:58:47 -0700836 hdd_info("pPeerInfo->numIBSSPeers = %d ", pPeerInfo->numPeers);
Rajeev Kumar8e3e2832015-11-06 16:02:54 -0800837 {
Rajeev Kumar94c9b452016-03-24 12:58:47 -0700838 uint8_t mac_addr[QDF_MAC_ADDR_SIZE];
839 uint32_t tx_rate = pPeerInfo->peerInfoParams[0].txRate;
Rajeev Kumar8e3e2832015-11-06 16:02:54 -0800840
Rajeev Kumar94c9b452016-03-24 12:58:47 -0700841 qdf_mem_copy(mac_addr, pPeerInfo->peerInfoParams[0].
842 mac_addr, sizeof(mac_addr));
843 hdd_info("PEER ADDR : %pM TxRate: %d Mbps RSSI: %d",
844 mac_addr, (int)tx_rate,
845 (int)pPeerInfo->peerInfoParams[0].rssi);
Rajeev Kumar8e3e2832015-11-06 16:02:54 -0800846 }
847 } else {
Jeff Johnson99bac312016-06-28 10:38:18 -0700848 hdd_warn("Warning: sme_request_ibss_peer_info Request failed");
Rajeev Kumar8e3e2832015-11-06 16:02:54 -0800849 }
850
851 return status;
852}
853
854/**
855 * hdd_wlan_get_ibss_peer_info_all() - Print all IBSS peers
856 * @pAdapter: Adapter upon which the IBSS clients are active
857 *
858 * Return: QDF_STATUS_STATUS if the peer information was retrieved and
859 * displayed, otherwise an appropriate QDF_STATUS_E_* failure code.
860 */
861QDF_STATUS hdd_wlan_get_ibss_peer_info_all(hdd_adapter_t *pAdapter)
862{
863 QDF_STATUS status = QDF_STATUS_E_FAILURE;
864 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
865 hdd_station_ctx_t *pStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Rajeev Kumar94c9b452016-03-24 12:58:47 -0700866 tSirPeerInfoRspParams *pPeerInfo = &pStaCtx->ibss_peer_info;
Rajeev Kumar8e3e2832015-11-06 16:02:54 -0800867 int i;
868
869 status =
870 sme_request_ibss_peer_info(hHal, pAdapter, hdd_get_ibss_peer_info_cb,
871 true, 0xFF);
872 INIT_COMPLETION(pAdapter->ibss_peer_info_comp);
873
874 if (QDF_STATUS_SUCCESS == status) {
875 unsigned long rc;
876 rc = wait_for_completion_timeout
877 (&pAdapter->ibss_peer_info_comp,
878 msecs_to_jiffies(IBSS_PEER_INFO_REQ_TIMOEUT));
879 if (!rc) {
Jeff Johnson99bac312016-06-28 10:38:18 -0700880 hdd_err("failed wait on ibss_peer_info_comp");
Rajeev Kumar8e3e2832015-11-06 16:02:54 -0800881 return QDF_STATUS_E_FAILURE;
882 }
883
884 /** Print the peer info */
Rajeev Kumar94c9b452016-03-24 12:58:47 -0700885 hdd_info("pPeerInfo->numIBSSPeers = %d ",
886 (int)pPeerInfo->numPeers);
887 for (i = 0; i < pPeerInfo->numPeers; i++) {
888 uint8_t mac_addr[QDF_MAC_ADDR_SIZE];
889 uint32_t tx_rate;
Rajeev Kumar8e3e2832015-11-06 16:02:54 -0800890
Rajeev Kumar94c9b452016-03-24 12:58:47 -0700891 tx_rate = pPeerInfo->peerInfoParams[i].txRate;
892 qdf_mem_copy(mac_addr,
893 pPeerInfo->peerInfoParams[i].mac_addr,
894 sizeof(mac_addr));
895
896 hdd_info(" PEER ADDR : %pM TxRate: %d Mbps RSSI: %d",
897 mac_addr, (int)tx_rate,
898 (int)pPeerInfo->peerInfoParams[i].rssi);
Rajeev Kumar8e3e2832015-11-06 16:02:54 -0800899 }
900 } else {
Jeff Johnson99bac312016-06-28 10:38:18 -0700901 hdd_warn("Warning: sme_request_ibss_peer_info Request failed");
Rajeev Kumar8e3e2832015-11-06 16:02:54 -0800902 }
903
904 return status;
905}
906
907/**
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800908 * hdd_wlan_get_rts_threshold() - Get RTS threshold
909 * @pAdapter: adapter upon which the request was received
910 * @wrqu: pointer to the ioctl request
911 *
912 * This function retrieves the current RTS threshold value and stores
913 * it in the ioctl request structure
914 *
915 * Return: 0 if valid data was returned, non-zero on error
916 */
917int hdd_wlan_get_rts_threshold(hdd_adapter_t *pAdapter, union iwreq_data *wrqu)
918{
919 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
920 uint32_t threshold = 0;
921 hdd_context_t *hdd_ctx;
922 int ret = 0;
923
924 ENTER();
925
926 if (NULL == pAdapter) {
Jeff Johnson99bac312016-06-28 10:38:18 -0700927 hdd_err("Adapter is NULL");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800928 return -EINVAL;
929 }
930
931 hdd_ctx = WLAN_HDD_GET_CTX(pAdapter);
932 ret = wlan_hdd_validate_context(hdd_ctx);
933 if (0 != ret)
934 return ret;
935
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530936 if (QDF_STATUS_SUCCESS !=
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800937 sme_cfg_get_int(hHal, WNI_CFG_RTS_THRESHOLD, &threshold)) {
Jeff Johnson99bac312016-06-28 10:38:18 -0700938 hdd_warn("failed to get ini parameter, WNI_CFG_RTS_THRESHOLD");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800939 return -EIO;
940 }
941 wrqu->rts.value = threshold;
942
Jeff Johnson99bac312016-06-28 10:38:18 -0700943 hdd_notice("Rts-Threshold=%d!!", wrqu->rts.value);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800944
945 EXIT();
946
947 return 0;
948}
949
950/**
951 * hdd_wlan_get_frag_threshold() - Get fragmentation threshold
952 * @pAdapter: adapter upon which the request was received
953 * @wrqu: pointer to the ioctl request
954 *
955 * This function retrieves the current fragmentation threshold value
956 * and stores it in the ioctl request structure
957 *
958 * Return: 0 if valid data was returned, non-zero on error
959 */
960int hdd_wlan_get_frag_threshold(hdd_adapter_t *pAdapter,
961 union iwreq_data *wrqu)
962{
963 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
964 uint32_t threshold = 0, status = 0;
965 hdd_context_t *hdd_ctx;
966
967 ENTER();
968
969 if (NULL == pAdapter) {
Jeff Johnson99bac312016-06-28 10:38:18 -0700970 hdd_err("Adapter is NULL");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800971 return -EINVAL;
972 }
973
974 hdd_ctx = WLAN_HDD_GET_CTX(pAdapter);
975 status = wlan_hdd_validate_context(hdd_ctx);
976 if (0 != status)
977 return status;
978
979 if (sme_cfg_get_int(hHal, WNI_CFG_FRAGMENTATION_THRESHOLD, &threshold)
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530980 != QDF_STATUS_SUCCESS) {
Jeff Johnson99bac312016-06-28 10:38:18 -0700981 hdd_warn("failed to get ini parameter, WNI_CFG_FRAGMENTATION_THRESHOLD");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800982 return -EIO;
983 }
984 wrqu->frag.value = threshold;
985
Jeff Johnson99bac312016-06-28 10:38:18 -0700986 hdd_notice("Frag-Threshold=%d!!", wrqu->frag.value);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800987
988 EXIT();
989
990 return 0;
991}
992
993/**
994 * hdd_wlan_get_freq() - Convert channel to frequency
995 * @channel: channel to be converted
996 * @pfreq: where to store the frequency
997 *
998 * Return: 1 on success, otherwise a negative errno
999 */
1000int hdd_wlan_get_freq(uint32_t channel, uint32_t *pfreq)
1001{
1002 int i;
1003 if (channel > 0) {
1004 for (i = 0; i < FREQ_CHAN_MAP_TABLE_SIZE; i++) {
1005 if (channel == freq_chan_map[i].chan) {
1006 *pfreq = freq_chan_map[i].freq;
1007 return 1;
1008 }
1009 }
1010 }
Jeff Johnson99bac312016-06-28 10:38:18 -07001011 hdd_notice("Invalid channel no=%d!!", channel);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001012 return -EINVAL;
1013}
1014
1015/**
1016 * hdd_is_auth_type_rsn() - RSN authentication type check
1017 * @authType: authentication type to be checked
1018 *
1019 * Return: true if @authType is an RSN authentication type,
1020 * false if it is not
1021 */
1022static bool hdd_is_auth_type_rsn(eCsrAuthType authType)
1023{
1024 bool rsnType = false;
1025 /* is the authType supported? */
1026 switch (authType) {
1027 case eCSR_AUTH_TYPE_NONE: /* never used */
1028 rsnType = false;
1029 break;
1030 /* MAC layer authentication types */
1031 case eCSR_AUTH_TYPE_OPEN_SYSTEM:
1032 rsnType = false;
1033 break;
1034 case eCSR_AUTH_TYPE_SHARED_KEY:
1035 rsnType = false;
1036 break;
1037 case eCSR_AUTH_TYPE_AUTOSWITCH:
1038 rsnType = false;
1039 break;
1040
1041 /* Upper layer authentication types */
1042 case eCSR_AUTH_TYPE_WPA:
1043 rsnType = true;
1044 break;
1045 case eCSR_AUTH_TYPE_WPA_PSK:
1046 rsnType = true;
1047 break;
1048 case eCSR_AUTH_TYPE_WPA_NONE:
1049 rsnType = true;
1050 break;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001051 case eCSR_AUTH_TYPE_FT_RSN:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001052 case eCSR_AUTH_TYPE_RSN:
1053 rsnType = true;
1054 break;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001055 case eCSR_AUTH_TYPE_FT_RSN_PSK:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001056 case eCSR_AUTH_TYPE_RSN_PSK:
1057#ifdef WLAN_FEATURE_11W
1058 case eCSR_AUTH_TYPE_RSN_PSK_SHA256:
1059 case eCSR_AUTH_TYPE_RSN_8021X_SHA256:
1060#endif
1061 rsnType = true;
1062 break;
1063 /* case eCSR_AUTH_TYPE_FAILED: */
1064 case eCSR_AUTH_TYPE_UNKNOWN:
1065 rsnType = false;
1066 break;
1067 default:
Jeff Johnson99bac312016-06-28 10:38:18 -07001068 hdd_err("unknown authType %d, treat as open",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001069 authType);
1070 rsnType = false;
1071 break;
1072 }
Jeff Johnson99bac312016-06-28 10:38:18 -07001073 hdd_notice("called with authType: %d, returned: %d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001074 authType, rsnType);
1075 return rsnType;
1076}
1077
1078/**
1079 * hdd_get_rssi_cb() - "Get RSSI" callback function
1080 * @rssi: Current RSSI of the station
1081 * @staId: ID of the station
1082 * @pContext: opaque context originally passed to SME. HDD always passes
1083 * a &struct statsContext
1084 *
1085 * Return: None
1086 */
1087static void hdd_get_rssi_cb(int8_t rssi, uint32_t staId, void *pContext)
1088{
1089 struct statsContext *pStatsContext;
1090 hdd_adapter_t *pAdapter;
1091
1092 if (ioctl_debug) {
1093 pr_info("%s: rssi [%d] STA [%d] pContext [%p]\n",
1094 __func__, (int)rssi, (int)staId, pContext);
1095 }
1096
1097 if (NULL == pContext) {
Jeff Johnson99bac312016-06-28 10:38:18 -07001098 hdd_err("Bad param");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001099 return;
1100 }
1101
1102 pStatsContext = pContext;
1103 pAdapter = pStatsContext->pAdapter;
1104
1105 /* there is a race condition that exists between this callback
1106 * function and the caller since the caller could time out
1107 * either before or while this code is executing. we use a
1108 * spinlock to serialize these actions
1109 */
1110 spin_lock(&hdd_context_lock);
1111
1112 if ((NULL == pAdapter) ||
1113 (RSSI_CONTEXT_MAGIC != pStatsContext->magic)) {
1114 /* the caller presumably timed out so there is nothing
1115 * we can do
1116 */
1117 spin_unlock(&hdd_context_lock);
Jeff Johnson99bac312016-06-28 10:38:18 -07001118 hdd_warn("Invalid context, pAdapter [%p] magic [%08x]",
1119 pAdapter, pStatsContext->magic);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001120 if (ioctl_debug) {
1121 pr_info("%s: Invalid context, pAdapter [%p] magic [%08x]\n",
1122 __func__, pAdapter, pStatsContext->magic);
1123 }
1124 return;
1125 }
1126
1127 /* context is valid so caller is still waiting */
1128
1129 /* paranoia: invalidate the magic */
1130 pStatsContext->magic = 0;
1131
1132 /* copy over the rssi */
1133 pAdapter->rssi = rssi;
1134
Sachin Ahujabef8c102015-11-16 15:15:49 +05301135 if (pAdapter->rssi > 0)
1136 pAdapter->rssi = 0;
1137
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001138 /* notify the caller */
1139 complete(&pStatsContext->completion);
1140
1141 /* serialization is complete */
1142 spin_unlock(&hdd_context_lock);
1143}
1144
1145/**
1146 * hdd_get_snr_cb() - "Get SNR" callback function
1147 * @snr: Current SNR of the station
1148 * @staId: ID of the station
1149 * @pContext: opaque context originally passed to SME. HDD always passes
1150 * a &struct statsContext
1151 *
1152 * Return: None
1153 */
1154static void hdd_get_snr_cb(int8_t snr, uint32_t staId, void *pContext)
1155{
1156 struct statsContext *pStatsContext;
1157 hdd_adapter_t *pAdapter;
1158
1159 if (ioctl_debug) {
1160 pr_info("%s: snr [%d] STA [%d] pContext [%p]\n",
1161 __func__, (int)snr, (int)staId, pContext);
1162 }
1163
1164 if (NULL == pContext) {
Jeff Johnson99bac312016-06-28 10:38:18 -07001165 hdd_err("Bad param");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001166 return;
1167 }
1168
1169 pStatsContext = pContext;
1170 pAdapter = pStatsContext->pAdapter;
1171
1172 /* there is a race condition that exists between this callback
1173 * function and the caller since the caller could time out
1174 * either before or while this code is executing. we use a
1175 * spinlock to serialize these actions
1176 */
1177 spin_lock(&hdd_context_lock);
1178
1179 if ((NULL == pAdapter) || (SNR_CONTEXT_MAGIC != pStatsContext->magic)) {
1180 /* the caller presumably timed out so there is nothing
1181 * we can do
1182 */
1183 spin_unlock(&hdd_context_lock);
Jeff Johnson99bac312016-06-28 10:38:18 -07001184 hdd_warn("Invalid context, pAdapter [%p] magic [%08x]",
1185 pAdapter, pStatsContext->magic);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001186 if (ioctl_debug) {
1187 pr_info("%s: Invalid context, pAdapter [%p] magic [%08x]\n",
1188 __func__, pAdapter, pStatsContext->magic);
1189 }
1190 return;
1191 }
1192
1193 /* context is valid so caller is still waiting */
1194
1195 /* paranoia: invalidate the magic */
1196 pStatsContext->magic = 0;
1197
1198 /* copy over the snr */
1199 pAdapter->snr = snr;
1200
1201 /* notify the caller */
1202 complete(&pStatsContext->completion);
1203
1204 /* serialization is complete */
1205 spin_unlock(&hdd_context_lock);
1206}
1207
1208/**
1209 * wlan_hdd_get_rssi() - Get the current RSSI
1210 * @pAdapter: adapter upon which the measurement is requested
1211 * @rssi_value: pointer to where the RSSI should be returned
1212 *
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05301213 * Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_E_** on error
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001214 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301215QDF_STATUS wlan_hdd_get_rssi(hdd_adapter_t *pAdapter, int8_t *rssi_value)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001216{
1217 struct statsContext context;
1218 hdd_context_t *pHddCtx;
1219 hdd_station_ctx_t *pHddStaCtx;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301220 QDF_STATUS hstatus;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001221 unsigned long rc;
1222
1223 if (NULL == pAdapter) {
Jeff Johnson99bac312016-06-28 10:38:18 -07001224 hdd_warn("Invalid context, pAdapter");
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301225 return QDF_STATUS_E_FAULT;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001226 }
Prashanth Bhatta9e143052015-12-04 11:56:47 -08001227 if (cds_is_driver_recovering()) {
1228 hdd_err("Recovery in Progress. State: 0x%x Ignore!!!",
1229 cds_get_driver_state());
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001230 /* return a cached value */
1231 *rssi_value = pAdapter->rssi;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301232 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001233 }
1234
1235 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
1236 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
1237
1238 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState) {
1239 hdd_err("Not associated!, return last connected AP rssi!");
1240 *rssi_value = pAdapter->rssi;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301241 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001242 }
1243
1244 if (pHddStaCtx->hdd_ReassocScenario) {
1245 hdd_info("Roaming in progress, return cached RSSI");
1246 *rssi_value = pAdapter->rssi;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301247 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001248 }
1249
1250 init_completion(&context.completion);
1251 context.pAdapter = pAdapter;
1252 context.magic = RSSI_CONTEXT_MAGIC;
1253
1254 hstatus = sme_get_rssi(pHddCtx->hHal, hdd_get_rssi_cb,
1255 pHddStaCtx->conn_info.staId[0],
1256 pHddStaCtx->conn_info.bssId, pAdapter->rssi,
1257 &context, pHddCtx->pcds_context);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301258 if (QDF_STATUS_SUCCESS != hstatus) {
Jeff Johnson99bac312016-06-28 10:38:18 -07001259 hdd_err("Unable to retrieve RSSI");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001260 /* we'll returned a cached value below */
1261 } else {
1262 /* request was sent -- wait for the response */
1263 rc = wait_for_completion_timeout(&context.completion,
1264 msecs_to_jiffies
1265 (WLAN_WAIT_TIME_STATS));
1266 if (!rc) {
Jeff Johnson99bac312016-06-28 10:38:18 -07001267 hdd_err("SME timed out while retrieving RSSI");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001268 /* we'll now returned a cached value below */
1269 }
1270 }
1271
1272 /* either we never sent a request, we sent a request and
1273 * received a response or we sent a request and timed out. if
1274 * we never sent a request or if we sent a request and got a
1275 * response, we want to clear the magic out of paranoia. if
1276 * we timed out there is a race condition such that the
1277 * callback function could be executing at the same time we
1278 * are. of primary concern is if the callback function had
1279 * already verified the "magic" but had not yet set the
1280 * completion variable when a timeout occurred. we serialize
1281 * these activities by invalidating the magic while holding a
1282 * shared spinlock which will cause us to block if the
1283 * callback is currently executing
1284 */
1285 spin_lock(&hdd_context_lock);
1286 context.magic = 0;
1287 spin_unlock(&hdd_context_lock);
1288
1289 *rssi_value = pAdapter->rssi;
1290
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301291 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001292}
1293
1294/**
1295 * wlan_hdd_get_snr() - Get the current SNR
1296 * @pAdapter: adapter upon which the measurement is requested
1297 * @snr: pointer to where the SNR should be returned
1298 *
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05301299 * Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_E_** on error
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001300 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301301QDF_STATUS wlan_hdd_get_snr(hdd_adapter_t *pAdapter, int8_t *snr)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001302{
1303 struct statsContext context;
1304 hdd_context_t *pHddCtx;
1305 hdd_station_ctx_t *pHddStaCtx;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301306 QDF_STATUS hstatus;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001307 unsigned long rc;
1308 int valid;
1309
Hanumantha Reddy Pothula2db50ed2015-11-23 10:48:33 +05301310 ENTER();
1311
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001312 if (NULL == pAdapter) {
Jeff Johnson99bac312016-06-28 10:38:18 -07001313 hdd_err("Invalid context, pAdapter");
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301314 return QDF_STATUS_E_FAULT;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001315 }
1316
1317 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
1318
1319 valid = wlan_hdd_validate_context(pHddCtx);
Hanumantha Reddy Pothula2db50ed2015-11-23 10:48:33 +05301320 if (0 != valid)
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301321 return QDF_STATUS_E_FAULT;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001322
1323 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
1324
1325 init_completion(&context.completion);
1326 context.pAdapter = pAdapter;
1327 context.magic = SNR_CONTEXT_MAGIC;
1328
1329 hstatus = sme_get_snr(pHddCtx->hHal, hdd_get_snr_cb,
1330 pHddStaCtx->conn_info.staId[0],
1331 pHddStaCtx->conn_info.bssId, &context);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301332 if (QDF_STATUS_SUCCESS != hstatus) {
Jeff Johnson99bac312016-06-28 10:38:18 -07001333 hdd_err("Unable to retrieve RSSI");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001334 /* we'll returned a cached value below */
1335 } else {
1336 /* request was sent -- wait for the response */
1337 rc = wait_for_completion_timeout(&context.completion,
1338 msecs_to_jiffies
1339 (WLAN_WAIT_TIME_STATS));
1340 if (!rc) {
Jeff Johnson99bac312016-06-28 10:38:18 -07001341 hdd_err("SME timed out while retrieving SNR");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001342 /* we'll now returned a cached value below */
1343 }
1344 }
1345
1346 /* either we never sent a request, we sent a request and
1347 * received a response or we sent a request and timed out. if
1348 * we never sent a request or if we sent a request and got a
1349 * response, we want to clear the magic out of paranoia. if
1350 * we timed out there is a race condition such that the
1351 * callback function could be executing at the same time we
1352 * are. of primary concern is if the callback function had
1353 * already verified the "magic" but had not yet set the
1354 * completion variable when a timeout occurred. we serialize
1355 * these activities by invalidating the magic while holding a
1356 * shared spinlock which will cause us to block if the
1357 * callback is currently executing
1358 */
1359 spin_lock(&hdd_context_lock);
1360 context.magic = 0;
1361 spin_unlock(&hdd_context_lock);
1362
1363 *snr = pAdapter->snr;
Hanumantha Reddy Pothula2db50ed2015-11-23 10:48:33 +05301364 EXIT();
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301365 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001366}
1367
1368/**
1369 * hdd_get_link_speed_cb() - Get link speed callback function
1370 * @pLinkSpeed: pointer to the link speed record
1371 * @pContext: pointer to the user context passed to SME
1372 *
1373 * This function is passed as the callback function to
1374 * sme_get_link_speed() by wlan_hdd_get_linkspeed_for_peermac(). By
1375 * agreement a &struct linkspeedContext is passed as @pContext. If
1376 * the context is valid, then the contents of @pLinkSpeed are copied
1377 * into the adapter record referenced by @pContext where they can be
1378 * subsequently retrieved. If the context is invalid, then this
1379 * function does nothing since it is assumed the caller has already
1380 * timed-out and destroyed the context.
1381 *
1382 * Return: None.
1383 */
1384static void
1385hdd_get_link_speed_cb(tSirLinkSpeedInfo *pLinkSpeed, void *pContext)
1386{
1387 struct linkspeedContext *pLinkSpeedContext;
1388 hdd_adapter_t *pAdapter;
1389
1390 if ((NULL == pLinkSpeed) || (NULL == pContext)) {
Jeff Johnson99bac312016-06-28 10:38:18 -07001391 hdd_err("Bad param, pLinkSpeed [%p] pContext [%p]",
1392 pLinkSpeed, pContext);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001393 return;
1394 }
1395 spin_lock(&hdd_context_lock);
1396 pLinkSpeedContext = pContext;
1397 pAdapter = pLinkSpeedContext->pAdapter;
1398
1399 /* there is a race condition that exists between this callback
1400 * function and the caller since the caller could time out either
1401 * before or while this code is executing. we use a spinlock to
1402 * serialize these actions
1403 */
1404
1405 if ((NULL == pAdapter) ||
1406 (LINK_CONTEXT_MAGIC != pLinkSpeedContext->magic)) {
1407 /* the caller presumably timed out so there is nothing
1408 * we can do
1409 */
1410 spin_unlock(&hdd_context_lock);
Jeff Johnson99bac312016-06-28 10:38:18 -07001411 hdd_warn("Invalid context, pAdapter [%p] magic [%08x]",
1412 pAdapter, pLinkSpeedContext->magic);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001413 if (ioctl_debug) {
1414 pr_info("%s: Invalid context, pAdapter [%p] magic [%08x]\n",
1415 __func__, pAdapter, pLinkSpeedContext->magic);
1416 }
1417 return;
1418 }
1419
1420 /* context is valid so caller is still waiting */
1421
1422 /* paranoia: invalidate the magic */
1423 pLinkSpeedContext->magic = 0;
1424
1425 /* copy over the stats. do so as a struct copy */
1426 pAdapter->ls_stats = *pLinkSpeed;
1427
1428 /* notify the caller */
1429 complete(&pLinkSpeedContext->completion);
1430
1431 /* serialization is complete */
1432 spin_unlock(&hdd_context_lock);
1433}
1434
1435/**
1436 * wlan_hdd_get_linkspeed_for_peermac() - Get link speed for a peer
1437 * @pAdapter: adapter upon which the peer is active
1438 * @macAddress: MAC address of the peer
1439 *
1440 * This function will send a query to SME for the linkspeed of the
1441 * given peer, and then wait for the callback to be invoked.
1442 *
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301443 * Return: QDF_STATUS_SUCCESS if linkspeed data is available,
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05301444 * otherwise a QDF_STATUS_E_** error.
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001445 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301446QDF_STATUS wlan_hdd_get_linkspeed_for_peermac(hdd_adapter_t *pAdapter,
Anurag Chouhan6d760662016-02-20 16:05:43 +05301447 struct qdf_mac_addr macAddress) {
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301448 QDF_STATUS status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001449 unsigned long rc;
1450 struct linkspeedContext context;
1451 tSirLinkSpeedInfo *linkspeed_req;
1452
1453 if (NULL == pAdapter) {
Jeff Johnson99bac312016-06-28 10:38:18 -07001454 hdd_err("pAdapter is NULL");
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301455 return QDF_STATUS_E_FAULT;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001456 }
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301457 linkspeed_req = qdf_mem_malloc(sizeof(*linkspeed_req));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001458 if (NULL == linkspeed_req) {
Jeff Johnson99bac312016-06-28 10:38:18 -07001459 hdd_err("Request Buffer Alloc Fail");
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301460 return QDF_STATUS_E_NOMEM;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001461 }
1462 init_completion(&context.completion);
1463 context.pAdapter = pAdapter;
1464 context.magic = LINK_CONTEXT_MAGIC;
1465
Anurag Chouhanc5548422016-02-24 18:33:27 +05301466 qdf_copy_macaddr(&linkspeed_req->peer_macaddr, &macAddress);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001467 status = sme_get_link_speed(WLAN_HDD_GET_HAL_CTX(pAdapter),
1468 linkspeed_req,
1469 &context, hdd_get_link_speed_cb);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301470 if (QDF_STATUS_SUCCESS != status) {
Jeff Johnson99bac312016-06-28 10:38:18 -07001471 hdd_err("Unable to retrieve statistics for link speed");
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301472 qdf_mem_free(linkspeed_req);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001473 } else {
1474 rc = wait_for_completion_timeout
1475 (&context.completion,
1476 msecs_to_jiffies(WLAN_WAIT_TIME_STATS));
1477 if (!rc) {
Jeff Johnson99bac312016-06-28 10:38:18 -07001478 hdd_err("SME timed out while retrieving link speed");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001479 }
1480 }
1481
1482 /* either we never sent a request, we sent a request and
1483 * received a response or we sent a request and timed out. if
1484 * we never sent a request or if we sent a request and got a
1485 * response, we want to clear the magic out of paranoia. if
1486 * we timed out there is a race condition such that the
1487 * callback function could be executing at the same time we
1488 * are. of primary concern is if the callback function had
1489 * already verified the "magic" but had not yet set the
1490 * completion variable when a timeout occurred. we serialize
1491 * these activities by invalidating the magic while holding a
1492 * shared spinlock which will cause us to block if the
1493 * callback is currently executing
1494 */
1495 spin_lock(&hdd_context_lock);
1496 context.magic = 0;
1497 spin_unlock(&hdd_context_lock);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301498 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001499}
1500
1501/**
1502 * wlan_hdd_get_link_speed() - get link speed
1503 * @pAdapter: pointer to the adapter
1504 * @link_speed: pointer to link speed
1505 *
1506 * This function fetches per bssid link speed.
1507 *
1508 * Return: if associated, link speed shall be returned.
1509 * if not associated, link speed of 0 is returned.
1510 * On error, error number will be returned.
1511 */
1512int wlan_hdd_get_link_speed(hdd_adapter_t *sta_adapter, uint32_t *link_speed)
1513{
1514 hdd_context_t *hddctx = WLAN_HDD_GET_CTX(sta_adapter);
1515 hdd_station_ctx_t *hdd_stactx =
1516 WLAN_HDD_GET_STATION_CTX_PTR(sta_adapter);
1517 int ret;
1518
1519 ret = wlan_hdd_validate_context(hddctx);
Abhishek Singh23edd1c2016-05-05 11:56:06 +05301520 if (ret)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001521 return ret;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001522
1523 if (eConnectionState_Associated != hdd_stactx->conn_info.connState) {
1524 /* we are not connected so we don't have a classAstats */
1525 *link_speed = 0;
1526 } else {
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301527 QDF_STATUS status;
Anurag Chouhan6d760662016-02-20 16:05:43 +05301528 struct qdf_mac_addr bssid;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001529
Anurag Chouhanc5548422016-02-24 18:33:27 +05301530 qdf_copy_macaddr(&bssid, &hdd_stactx->conn_info.bssId);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001531
1532 status = wlan_hdd_get_linkspeed_for_peermac(sta_adapter, bssid);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301533 if (!QDF_IS_STATUS_SUCCESS(status)) {
Jeff Johnson99bac312016-06-28 10:38:18 -07001534 hdd_err("Unable to retrieve SME linkspeed");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001535 return -EINVAL;
1536 }
1537 *link_speed = sta_adapter->ls_stats.estLinkSpeed;
1538 /* linkspeed in units of 500 kbps */
1539 *link_speed = (*link_speed) / 500;
1540 }
1541 return 0;
1542}
1543
1544/**
1545 * hdd_statistics_cb() - "Get statistics" callback function
1546 * @pStats: statistics payload
1547 * @pContext: opaque context originally passed to SME. HDD always passes
1548 * a pointer to an adapter
1549 *
1550 * Return: None
1551 */
1552void hdd_statistics_cb(void *pStats, void *pContext)
1553{
1554 hdd_adapter_t *pAdapter = (hdd_adapter_t *) pContext;
1555 hdd_stats_t *pStatsCache = NULL;
1556 hdd_wext_state_t *pWextState;
Anurag Chouhance0dc992016-02-16 18:18:03 +05301557 QDF_STATUS qdf_status = QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001558
1559 tCsrSummaryStatsInfo *pSummaryStats = NULL;
1560 tCsrGlobalClassAStatsInfo *pClassAStats = NULL;
1561 tCsrGlobalClassBStatsInfo *pClassBStats = NULL;
1562 tCsrGlobalClassCStatsInfo *pClassCStats = NULL;
1563 tCsrGlobalClassDStatsInfo *pClassDStats = NULL;
1564 tCsrPerStaStatsInfo *pPerStaStats = NULL;
1565
1566 if (pAdapter != NULL)
1567 pStatsCache = &pAdapter->hdd_stats;
1568
1569 pSummaryStats = (tCsrSummaryStatsInfo *) pStats;
1570 pClassAStats = (tCsrGlobalClassAStatsInfo *) (pSummaryStats + 1);
1571 pClassBStats = (tCsrGlobalClassBStatsInfo *) (pClassAStats + 1);
1572 pClassCStats = (tCsrGlobalClassCStatsInfo *) (pClassBStats + 1);
1573 pClassDStats = (tCsrGlobalClassDStatsInfo *) (pClassCStats + 1);
1574 pPerStaStats = (tCsrPerStaStatsInfo *) (pClassDStats + 1);
1575
1576 if (pStatsCache != NULL) {
1577 /* copy the stats into the cache we keep in the
1578 * adapter instance structure
1579 */
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301580 qdf_mem_copy(&pStatsCache->summary_stat, pSummaryStats,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001581 sizeof(pStatsCache->summary_stat));
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301582 qdf_mem_copy(&pStatsCache->ClassA_stat, pClassAStats,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001583 sizeof(pStatsCache->ClassA_stat));
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301584 qdf_mem_copy(&pStatsCache->ClassB_stat, pClassBStats,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001585 sizeof(pStatsCache->ClassB_stat));
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301586 qdf_mem_copy(&pStatsCache->ClassC_stat, pClassCStats,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001587 sizeof(pStatsCache->ClassC_stat));
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301588 qdf_mem_copy(&pStatsCache->ClassD_stat, pClassDStats,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001589 sizeof(pStatsCache->ClassD_stat));
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301590 qdf_mem_copy(&pStatsCache->perStaStats, pPerStaStats,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001591 sizeof(pStatsCache->perStaStats));
1592 }
1593
1594 if (pAdapter) {
1595 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05301596 qdf_status = qdf_event_set(&pWextState->hdd_qdf_event);
Anurag Chouhance0dc992016-02-16 18:18:03 +05301597 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Jeff Johnson99bac312016-06-28 10:38:18 -07001598 hdd_err("qdf_event_set failed");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001599 return;
1600 }
1601 }
1602}
1603
1604/**
1605 * hdd_clear_roam_profile_ie() - Clear Roam Profile IEs
1606 * @pAdapter: adapter who's IEs are to be cleared
1607 *
1608 * Return: None
1609 */
1610void hdd_clear_roam_profile_ie(hdd_adapter_t *pAdapter)
1611{
1612 int i = 0;
Deepak Dhamdhere8360d4c2016-06-01 13:24:31 -07001613 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001614
Deepak Dhamdhere8360d4c2016-06-01 13:24:31 -07001615 ENTER();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001616
1617 /* clear WPA/RSN/WSC IE information in the profile */
1618 pWextState->roamProfile.nWPAReqIELength = 0;
1619 pWextState->roamProfile.pWPAReqIE = (uint8_t *) NULL;
1620 pWextState->roamProfile.nRSNReqIELength = 0;
1621 pWextState->roamProfile.pRSNReqIE = (uint8_t *) NULL;
1622
1623#ifdef FEATURE_WLAN_WAPI
1624 pWextState->roamProfile.nWAPIReqIELength = 0;
1625 pWextState->roamProfile.pWAPIReqIE = (uint8_t *) NULL;
1626#endif
1627
1628 pWextState->roamProfile.bWPSAssociation = false;
1629 pWextState->roamProfile.bOSENAssociation = false;
1630 pWextState->roamProfile.pAddIEScan = (uint8_t *) NULL;
1631 pWextState->roamProfile.nAddIEScanLength = 0;
1632 pWextState->roamProfile.pAddIEAssoc = (uint8_t *) NULL;
1633 pWextState->roamProfile.nAddIEAssocLength = 0;
1634
1635 pWextState->roamProfile.EncryptionType.numEntries = 1;
1636 pWextState->roamProfile.EncryptionType.encryptionType[0]
1637 = eCSR_ENCRYPT_TYPE_NONE;
1638
1639 pWextState->roamProfile.mcEncryptionType.numEntries = 1;
1640 pWextState->roamProfile.mcEncryptionType.encryptionType[0]
1641 = eCSR_ENCRYPT_TYPE_NONE;
1642
1643 pWextState->roamProfile.AuthType.numEntries = 1;
1644 pWextState->roamProfile.AuthType.authType[0] =
1645 eCSR_AUTH_TYPE_OPEN_SYSTEM;
1646
1647#ifdef WLAN_FEATURE_11W
1648 pWextState->roamProfile.MFPEnabled = false;
1649 pWextState->roamProfile.MFPRequired = 0;
1650 pWextState->roamProfile.MFPCapable = 0;
1651#endif
1652
1653 pWextState->authKeyMgmt = 0;
1654
1655 for (i = 0; i < CSR_MAX_NUM_KEY; i++) {
1656 if (pWextState->roamProfile.Keys.KeyMaterial[i]) {
1657 pWextState->roamProfile.Keys.KeyLength[i] = 0;
1658 }
1659 }
1660#ifdef FEATURE_WLAN_WAPI
1661 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_OPEN;
1662 pAdapter->wapi_info.nWapiMode = 0;
1663#endif
1664
Anurag Chouhanc5548422016-02-24 18:33:27 +05301665 qdf_zero_macaddr(&pWextState->req_bssId);
Deepak Dhamdhere8360d4c2016-06-01 13:24:31 -07001666 EXIT();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001667}
1668
1669/**
1670 * wlan_hdd_get_vendor_oui_ie_ptr() - Find a vendor OUI
1671 * @oui: The OUI that is being searched for
1672 * @oui_size: The length of @oui
1673 * @ie: The set of IEs within which we're trying to find @oui
1674 * @ie_len: The length of @ie
1675 *
1676 * This function will scan the IEs contained within @ie looking for @oui.
1677 *
1678 * Return: Pointer to @oui embedded within @ie if it is present, NULL
1679 * if @oui is not present within @ie.
1680 */
1681uint8_t *wlan_hdd_get_vendor_oui_ie_ptr(uint8_t *oui, uint8_t oui_size,
1682 uint8_t *ie, int ie_len)
1683{
1684 int left = ie_len;
1685 uint8_t *ptr = ie;
1686 uint8_t elem_id, elem_len;
1687 uint8_t eid = 0xDD;
1688
1689 if (NULL == ie || 0 == ie_len)
1690 return NULL;
1691
1692 while (left >= 2) {
1693 elem_id = ptr[0];
1694 elem_len = ptr[1];
1695 left -= 2;
1696 if (elem_len > left) {
Jeff Johnson99bac312016-06-28 10:38:18 -07001697 hdd_alert("****Invalid IEs eid = %d elem_len=%d left=%d*****",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001698 eid, elem_len, left);
1699 return NULL;
1700 }
1701 if (elem_id == eid) {
1702 if (memcmp(&ptr[2], oui, oui_size) == 0)
1703 return ptr;
1704 }
1705
1706 left -= elem_len;
1707 ptr += (elem_len + 2);
1708 }
1709 return NULL;
1710}
1711
1712/**
1713 * __iw_set_commit() - SIOCSIWCOMMIT ioctl handler
1714 * @dev: device upon which the ioctl was received
1715 * @info: ioctl request information
1716 * @wrqu: ioctl request data
1717 * @extra: ioctl extra data
1718 *
1719 * Return: 0 on success, non-zero on error
1720 */
1721static int __iw_set_commit(struct net_device *dev, struct iw_request_info *info,
1722 union iwreq_data *wrqu, char *extra)
1723{
1724 hdd_adapter_t *adapter;
1725 hdd_context_t *hdd_ctx;
1726 int ret;
1727
Jeff Johnsonb25dcb12016-02-11 17:46:42 -08001728 ENTER_DEV(dev);
1729
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001730 adapter = WLAN_HDD_GET_PRIV_PTR(dev);
1731 hdd_ctx = WLAN_HDD_GET_CTX(adapter);
1732 ret = wlan_hdd_validate_context(hdd_ctx);
1733 if (0 != ret)
1734 return ret;
1735
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001736 /* Do nothing for now */
1737 return 0;
1738}
1739
1740/**
1741 * iw_set_commit() - SSR wrapper function for __iw_set_commit
1742 * @dev: pointer to net_device
1743 * @info: pointer to iw_request_info
1744 * @wrqu: pointer to iwreq_data
1745 * @extra: extra
1746 *
1747 * Return: 0 on success, error number otherwise
1748 */
1749int iw_set_commit(struct net_device *dev, struct iw_request_info *info,
1750 union iwreq_data *wrqu, char *extra)
1751{
1752 int ret;
1753
1754 cds_ssr_protect(__func__);
1755 ret = __iw_set_commit(dev, info, wrqu, extra);
1756 cds_ssr_unprotect(__func__);
1757
1758 return ret;
1759}
1760
1761/**
1762 * __iw_get_name() - SIOCGIWNAME ioctl handler
1763 * @dev: device upon which the ioctl was received
1764 * @info: ioctl request information
1765 * @wrqu: ioctl request data
1766 * @extra: ioctl extra data
1767 *
1768 * Return: 0 on success, non-zero on error
1769 */
1770static int __iw_get_name(struct net_device *dev,
1771 struct iw_request_info *info, char *wrqu, char *extra)
1772{
1773 hdd_adapter_t *adapter;
1774 hdd_context_t *hdd_ctx;
1775 int ret;
1776
Jeff Johnsonb25dcb12016-02-11 17:46:42 -08001777 ENTER_DEV(dev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001778
1779 adapter = WLAN_HDD_GET_PRIV_PTR(dev);
1780 hdd_ctx = WLAN_HDD_GET_CTX(adapter);
1781 ret = wlan_hdd_validate_context(hdd_ctx);
1782 if (0 != ret)
1783 return ret;
1784
1785 strlcpy(wrqu, "Qcom:802.11n", IFNAMSIZ);
1786 EXIT();
1787 return 0;
1788}
1789
1790/**
1791 * __iw_get_name() - SSR wrapper for __iw_get_name
1792 * @dev: pointer to net_device
1793 * @info: pointer to iw_request_info
1794 * @wrqu: pointer to iwreq_data
1795 * @extra: extra
1796 *
1797 * Return: 0 on success, error number otherwise
1798 */
1799static int iw_get_name(struct net_device *dev,
1800 struct iw_request_info *info,
1801 char *wrqu, char *extra)
1802{
1803 int ret;
1804
1805 cds_ssr_protect(__func__);
1806 ret = __iw_get_name(dev, info, wrqu, extra);
1807 cds_ssr_unprotect(__func__);
1808
1809 return ret;
1810}
1811
1812/**
1813 * __iw_set_mode() - ioctl handler
1814 * @dev: device upon which the ioctl was received
1815 * @info: ioctl request information
1816 * @wrqu: ioctl request data
1817 * @extra: ioctl extra data
1818 *
1819 * Return: 0 on success, non-zero on error
1820 */
1821static int __iw_set_mode(struct net_device *dev,
1822 struct iw_request_info *info,
1823 union iwreq_data *wrqu, char *extra)
1824{
1825 hdd_wext_state_t *pWextState;
1826 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
1827 hdd_context_t *hdd_ctx;
1828 tCsrRoamProfile *pRoamProfile;
1829 eCsrRoamBssType LastBSSType;
1830 eMib_dot11DesiredBssType connectedBssType;
1831 struct hdd_config *pConfig;
1832 struct wireless_dev *wdev;
1833 int ret;
1834
Jeff Johnsonb25dcb12016-02-11 17:46:42 -08001835 ENTER_DEV(dev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001836
1837 hdd_ctx = WLAN_HDD_GET_CTX(pAdapter);
1838 ret = wlan_hdd_validate_context(hdd_ctx);
1839 if (0 != ret)
1840 return ret;
1841
1842 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
1843 wdev = dev->ieee80211_ptr;
1844 pRoamProfile = &pWextState->roamProfile;
1845 LastBSSType = pRoamProfile->BSSType;
1846
Jeff Johnson99bac312016-06-28 10:38:18 -07001847 hdd_notice("Old Bss type = %d", LastBSSType);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001848
1849 switch (wrqu->mode) {
1850 case IW_MODE_ADHOC:
Jeff Johnson99bac312016-06-28 10:38:18 -07001851 hdd_notice("Setting AP Mode as IW_MODE_ADHOC");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001852 pRoamProfile->BSSType = eCSR_BSS_TYPE_START_IBSS;
1853 /* Set the phymode correctly for IBSS. */
1854 pConfig = (WLAN_HDD_GET_CTX(pAdapter))->config;
1855 pWextState->roamProfile.phyMode =
1856 hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode);
Krunal Sonif07bb382016-03-10 13:02:11 -08001857 pAdapter->device_mode = QDF_IBSS_MODE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001858 wdev->iftype = NL80211_IFTYPE_ADHOC;
1859 break;
1860 case IW_MODE_INFRA:
Jeff Johnson99bac312016-06-28 10:38:18 -07001861 hdd_notice("Setting AP Mode as IW_MODE_INFRA");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001862 pRoamProfile->BSSType = eCSR_BSS_TYPE_INFRASTRUCTURE;
1863 wdev->iftype = NL80211_IFTYPE_STATION;
1864 break;
1865 case IW_MODE_AUTO:
Jeff Johnson99bac312016-06-28 10:38:18 -07001866 hdd_notice("Setting AP Mode as IW_MODE_AUTO");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001867 pRoamProfile->BSSType = eCSR_BSS_TYPE_ANY;
1868 break;
1869 default:
Jeff Johnson99bac312016-06-28 10:38:18 -07001870 hdd_err("Unknown AP Mode value %d", wrqu->mode);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001871 return -EOPNOTSUPP;
1872 }
1873
1874 if (LastBSSType != pRoamProfile->BSSType) {
1875 /* the BSS mode changed. We need to issue disconnect
1876 * if connected or in IBSS disconnect state
1877 */
1878 if (hdd_conn_get_connected_bss_type
1879 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), &connectedBssType)
1880 || (eCSR_BSS_TYPE_START_IBSS == LastBSSType)) {
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301881 QDF_STATUS qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001882 /* need to issue a disconnect to CSR. */
1883 INIT_COMPLETION(pAdapter->disconnect_comp_var);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301884 qdf_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001885 sme_roam_disconnect(WLAN_HDD_GET_HAL_CTX(pAdapter),
1886 pAdapter->sessionId,
1887 eCSR_DISCONNECT_REASON_IBSS_LEAVE);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301888 if (QDF_STATUS_SUCCESS == qdf_status) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001889 unsigned long rc;
1890 rc = wait_for_completion_timeout(&pAdapter->
1891 disconnect_comp_var,
1892 msecs_to_jiffies
1893 (WLAN_WAIT_TIME_DISCONNECT));
1894 if (!rc)
Jeff Johnson99bac312016-06-28 10:38:18 -07001895 hdd_err("failed wait on disconnect_comp_var");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001896 }
1897 }
1898 }
1899
1900 EXIT();
1901 return 0;
1902}
1903
1904/**
1905 * iw_set_mode() - SSR wrapper for __iw_set_mode()
1906 * @dev: pointer to net_device
1907 * @info: pointer to iw_request_info
1908 * @wrqu: pointer to iwreq_data
1909 * @extra: pointer to extra ioctl payload
1910 *
1911 * Return: 0 on success, error number otherwise
1912 */
1913static int iw_set_mode(struct net_device *dev, struct iw_request_info *info,
1914 union iwreq_data *wrqu, char *extra)
1915{
1916 int ret;
1917
1918 cds_ssr_protect(__func__);
1919 ret = __iw_set_mode(dev, info, wrqu, extra);
1920 cds_ssr_unprotect(__func__);
1921
1922 return ret;
1923}
1924
1925/**
1926 * __iw_get_mode() - SIOCGIWMODE ioctl handler
1927 * @dev: device upon which the ioctl was received
1928 * @info: ioctl request information
1929 * @wrqu: ioctl request data
1930 * @extra: ioctl extra data
1931 *
1932 * Return: 0 on success, non-zero on error
1933 */
1934static int
1935__iw_get_mode(struct net_device *dev, struct iw_request_info *info,
1936 union iwreq_data *wrqu, char *extra)
1937{
1938 hdd_wext_state_t *pWextState;
1939 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
1940 hdd_context_t *hdd_ctx;
1941 int ret;
1942
Jeff Johnsonb25dcb12016-02-11 17:46:42 -08001943 ENTER_DEV(dev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001944
1945 hdd_ctx = WLAN_HDD_GET_CTX(pAdapter);
1946 ret = wlan_hdd_validate_context(hdd_ctx);
1947 if (0 != ret)
1948 return ret;
1949
1950 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
1951
1952 switch (pWextState->roamProfile.BSSType) {
1953 case eCSR_BSS_TYPE_INFRASTRUCTURE:
Jeff Johnson99bac312016-06-28 10:38:18 -07001954 hdd_notice("returns IW_MODE_INFRA");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001955 wrqu->mode = IW_MODE_INFRA;
1956 break;
1957 case eCSR_BSS_TYPE_IBSS:
1958 case eCSR_BSS_TYPE_START_IBSS:
Jeff Johnson99bac312016-06-28 10:38:18 -07001959 hdd_notice("returns IW_MODE_ADHOC");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001960 wrqu->mode = IW_MODE_ADHOC;
1961 break;
1962 case eCSR_BSS_TYPE_ANY:
1963 default:
Jeff Johnson99bac312016-06-28 10:38:18 -07001964 hdd_notice("returns IW_MODE_AUTO");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001965 wrqu->mode = IW_MODE_AUTO;
1966 break;
1967 }
1968
1969 EXIT();
1970 return 0;
1971}
1972
1973/**
1974 * iw_get_mode() - SSR wrapper for __iw_get_mode()
1975 * @dev: pointer to net_device
1976 * @info: pointer to iw_request_info
1977 * @wrqu: pointer to iwreq_data
1978 * @extra: pointer to extra ioctl payload
1979 *
1980 * Return: 0 on success, error number otherwise
1981 */
1982static int iw_get_mode(struct net_device *dev, struct iw_request_info *info,
1983 union iwreq_data *wrqu, char *extra)
1984{
1985 int ret;
1986
1987 cds_ssr_protect(__func__);
1988 ret = __iw_get_mode(dev, info, wrqu, extra);
1989 cds_ssr_unprotect(__func__);
1990
1991 return ret;
1992}
1993
1994/**
1995 * __iw_set_freq() - SIOCSIWFREQ ioctl handler
1996 * @dev: device upon which the ioctl was received
1997 * @info: ioctl request information
1998 * @wrqu: ioctl request data
1999 * @extra: ioctl extra data
2000 *
2001 * Return: 0 on success, non-zero on error
2002 */
2003static int __iw_set_freq(struct net_device *dev, struct iw_request_info *info,
2004 union iwreq_data *wrqu, char *extra)
2005{
2006 uint32_t numChans = 0;
2007 uint8_t validChan[WNI_CFG_VALID_CHANNEL_LIST_LEN];
2008 uint32_t indx = 0;
2009 int ret;
2010 hdd_wext_state_t *pWextState;
2011 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
2012 hdd_context_t *hdd_ctx;
2013 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
2014 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
2015 tCsrRoamProfile *pRoamProfile;
2016
Jeff Johnsonb25dcb12016-02-11 17:46:42 -08002017 ENTER_DEV(dev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002018
2019 hdd_ctx = WLAN_HDD_GET_CTX(pAdapter);
2020 ret = wlan_hdd_validate_context(hdd_ctx);
2021 if (0 != ret)
2022 return ret;
2023
2024 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
2025
2026 pRoamProfile = &pWextState->roamProfile;
2027
Jeff Johnson99bac312016-06-28 10:38:18 -07002028 hdd_notice("setCHANNEL ioctl");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002029
2030 /* Link is up then return cant set channel */
2031 if (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState ||
2032 eConnectionState_Associated == pHddStaCtx->conn_info.connState) {
Jeff Johnson99bac312016-06-28 10:38:18 -07002033 hdd_err("IBSS Associated");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002034 return -EOPNOTSUPP;
2035 }
2036
2037 /* Settings by Frequency as input */
2038 if ((wrqu->freq.e == 1) && (wrqu->freq.m >= (uint32_t) 2.412e8) &&
2039 (wrqu->freq.m <= (uint32_t) 5.825e8)) {
2040 uint32_t freq = wrqu->freq.m / 100000;
2041
2042 while ((indx < FREQ_CHAN_MAP_TABLE_SIZE)
2043 && (freq != freq_chan_map[indx].freq))
2044 indx++;
2045 if (indx >= FREQ_CHAN_MAP_TABLE_SIZE) {
2046 return -EINVAL;
2047 }
2048 wrqu->freq.e = 0;
2049 wrqu->freq.m = freq_chan_map[indx].chan;
2050
2051 }
2052
2053 if (wrqu->freq.e == 0) {
2054 if ((wrqu->freq.m < WNI_CFG_CURRENT_CHANNEL_STAMIN) ||
2055 (wrqu->freq.m > WNI_CFG_CURRENT_CHANNEL_STAMAX)) {
Jeff Johnson99bac312016-06-28 10:38:18 -07002056 hdd_notice("Channel %d is outside valid range from %d to %d",
2057 wrqu->freq.m,
2058 WNI_CFG_CURRENT_CHANNEL_STAMIN,
2059 WNI_CFG_CURRENT_CHANNEL_STAMAX);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002060 return -EINVAL;
2061 }
2062
2063 numChans = WNI_CFG_VALID_CHANNEL_LIST_LEN;
2064
2065 if (sme_cfg_get_str(hHal, WNI_CFG_VALID_CHANNEL_LIST,
2066 validChan, &numChans) !=
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302067 QDF_STATUS_SUCCESS) {
Jeff Johnson99bac312016-06-28 10:38:18 -07002068 hdd_warn("failed to get ini parameter, WNI_CFG_VALID_CHANNEL_LIST");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002069 return -EIO;
2070 }
2071
2072 for (indx = 0; indx < numChans; indx++) {
2073 if (wrqu->freq.m == validChan[indx]) {
2074 break;
2075 }
2076 }
2077 } else {
2078
2079 return -EINVAL;
2080 }
2081
2082 if (indx >= numChans) {
2083 return -EINVAL;
2084 }
2085
2086 /* Set the Operational Channel */
2087 numChans = pRoamProfile->ChannelInfo.numOfChannels = 1;
2088 pHddStaCtx->conn_info.operationChannel = wrqu->freq.m;
2089 pRoamProfile->ChannelInfo.ChannelList =
2090 &pHddStaCtx->conn_info.operationChannel;
2091
Jeff Johnson99bac312016-06-28 10:38:18 -07002092 hdd_notice("pRoamProfile->operationChannel = %d", wrqu->freq.m);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002093
2094 EXIT();
2095
2096 return ret;
2097}
2098
2099/**
2100 * iw_set_freq() - SSR wrapper for __iw_set_freq()
2101 * @dev: pointer to net_device
2102 * @info: pointer to iw_request_info
2103 * @wrqu: pointer to iwreq_data
2104 * @extra: pointer to extra ioctl payload
2105 *
2106 * Return: 0 on success, error number otherwise
2107 */
2108static int iw_set_freq(struct net_device *dev, struct iw_request_info *info,
2109 union iwreq_data *wrqu, char *extra)
2110{
2111 int ret;
2112
2113 cds_ssr_protect(__func__);
2114 ret = __iw_set_freq(dev, info, wrqu, extra);
2115 cds_ssr_unprotect(__func__);
2116
2117 return ret;
2118}
2119
2120/**
2121 * __iw_get_freq() - SIOCGIWFREQ ioctl handler
2122 * @dev: device upon which the ioctl was received
2123 * @info: ioctl request information
2124 * @wrqu: ioctl request data
2125 * @extra: ioctl extra data
2126 *
2127 * Return: 0 on success, non-zero on error
2128 */
2129static int __iw_get_freq(struct net_device *dev, struct iw_request_info *info,
2130 struct iw_freq *fwrq, char *extra)
2131{
2132 uint32_t status = false, channel = 0, freq = 0;
2133 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
2134 tHalHandle hHal;
2135 hdd_wext_state_t *pWextState;
2136 tCsrRoamProfile *pRoamProfile;
2137 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
2138 hdd_context_t *hdd_ctx;
2139 int ret;
2140
Jeff Johnsonb25dcb12016-02-11 17:46:42 -08002141 ENTER_DEV(dev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002142
2143 hdd_ctx = WLAN_HDD_GET_CTX(pAdapter);
2144 ret = wlan_hdd_validate_context(hdd_ctx);
2145 if (0 != ret)
2146 return ret;
2147
2148 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
2149 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
2150
2151 pRoamProfile = &pWextState->roamProfile;
2152
2153 if (pHddStaCtx->conn_info.connState == eConnectionState_Associated) {
2154 if (sme_get_operation_channel(hHal, &channel, pAdapter->sessionId)
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302155 != QDF_STATUS_SUCCESS) {
Jeff Johnson99bac312016-06-28 10:38:18 -07002156 hdd_err("failed to get operating channel %u",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002157 pAdapter->sessionId);
2158 return -EIO;
2159 } else {
2160 status = hdd_wlan_get_freq(channel, &freq);
2161 if (true == status) {
2162 /* Set Exponent parameter as 6 (MHZ)
2163 * in struct iw_freq iwlist & iwconfig
2164 * command shows frequency into proper
2165 * format (2.412 GHz instead of 246.2
2166 * MHz)
2167 */
2168 fwrq->m = freq;
2169 fwrq->e = MHZ;
2170 }
2171 }
2172 } else {
2173 /* Set Exponent parameter as 6 (MHZ) in struct iw_freq
2174 * iwlist & iwconfig command shows frequency into proper
2175 * format (2.412 GHz instead of 246.2 MHz)
2176 */
2177 fwrq->m = 0;
2178 fwrq->e = MHZ;
2179 }
2180 return 0;
2181}
2182
2183/**
2184 * iw_get_freq() - SSR wrapper for __iw_get_freq()
2185 * @dev: pointer to net_device
2186 * @info: pointer to iw_request_info
2187 * @fwrq: pointer to frequency data
2188 * @extra: pointer to extra ioctl payload
2189 *
2190 * Return: 0 on success, error number otherwise
2191 */
2192static int iw_get_freq(struct net_device *dev, struct iw_request_info *info,
2193 struct iw_freq *fwrq, char *extra)
2194{
2195 int ret;
2196
2197 cds_ssr_protect(__func__);
2198 ret = __iw_get_freq(dev, info, fwrq, extra);
2199 cds_ssr_unprotect(__func__);
2200
2201 return ret;
2202}
2203
2204/**
2205 * __iw_get_tx_power() - SIOCGIWTXPOW ioctl handler
2206 * @dev: device upon which the ioctl was received
2207 * @info: ioctl request information
2208 * @wrqu: ioctl request data
2209 * @extra: ioctl extra data
2210 *
2211 * Return: 0 on success, non-zero on error
2212 */
2213static int __iw_get_tx_power(struct net_device *dev,
2214 struct iw_request_info *info,
2215 union iwreq_data *wrqu, char *extra)
2216{
2217
2218 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
2219 hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(pAdapter);
2220 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
2221 int ret;
2222
Jeff Johnsonb25dcb12016-02-11 17:46:42 -08002223 ENTER_DEV(dev);
2224
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002225 ret = wlan_hdd_validate_context(hdd_ctx);
2226 if (0 != ret)
2227 return ret;
2228
2229 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState) {
2230 wrqu->txpower.value = 0;
2231 return 0;
2232 }
2233 wlan_hdd_get_class_astats(pAdapter);
2234 wrqu->txpower.value = pAdapter->hdd_stats.ClassA_stat.max_pwr;
2235
2236 return 0;
2237}
2238
2239/**
2240 * iw_get_tx_power() - SSR wrapper for __iw_get_tx_power()
2241 * @dev: pointer to net_device
2242 * @info: pointer to iw_request_info
2243 * @wrqu: pointer to iwreq_data
2244 * @extra: pointer to extra ioctl payload
2245 *
2246 * Return: 0 on success, error number otherwise
2247 */
2248static int iw_get_tx_power(struct net_device *dev,
2249 struct iw_request_info *info,
2250 union iwreq_data *wrqu, char *extra)
2251{
2252 int ret;
2253
2254 cds_ssr_protect(__func__);
2255 ret = __iw_get_tx_power(dev, info, wrqu, extra);
2256 cds_ssr_unprotect(__func__);
2257
2258 return ret;
2259}
2260
2261/**
2262 * __iw_set_tx_power() - SIOCSIWTXPOW ioctl handler
2263 * @dev: device upon which the ioctl was received
2264 * @info: ioctl request information
2265 * @wrqu: ioctl request data
2266 * @extra: ioctl extra data
2267 *
2268 * Return: 0 on success, non-zero on error
2269 */
2270static int __iw_set_tx_power(struct net_device *dev,
2271 struct iw_request_info *info,
2272 union iwreq_data *wrqu, char *extra)
2273{
2274 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
2275 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
2276 hdd_context_t *hdd_ctx;
2277 int ret;
2278
Jeff Johnsonb25dcb12016-02-11 17:46:42 -08002279 ENTER_DEV(dev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002280
2281 hdd_ctx = WLAN_HDD_GET_CTX(pAdapter);
2282 ret = wlan_hdd_validate_context(hdd_ctx);
2283 if (0 != ret)
2284 return ret;
2285
2286 if (sme_cfg_set_int(hHal, WNI_CFG_CURRENT_TX_POWER_LEVEL,
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302287 wrqu->txpower.value) != QDF_STATUS_SUCCESS) {
Jeff Johnson99bac312016-06-28 10:38:18 -07002288 hdd_err("failed to set ini parameter, WNI_CFG_CURRENT_TX_POWER_LEVEL");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002289 return -EIO;
2290 }
2291
2292 EXIT();
2293
2294 return 0;
2295}
2296
2297/**
2298 * iw_set_tx_power() - SSR wrapper for __iw_set_tx_power()
2299 * @dev: pointer to net_device
2300 * @info: pointer to iw_request_info
2301 * @wrqu: pointer to iwreq_data
2302 * @extra: pointer to extra ioctl payload
2303 *
2304 * Return: 0 on success, error number otherwise
2305 */
2306static int iw_set_tx_power(struct net_device *dev,
2307 struct iw_request_info *info,
2308 union iwreq_data *wrqu, char *extra)
2309{
2310 int ret;
2311
2312 cds_ssr_protect(__func__);
2313 ret = __iw_set_tx_power(dev, info, wrqu, extra);
2314 cds_ssr_unprotect(__func__);
2315
2316 return ret;
2317}
2318
2319/**
2320 * __iw_get_bitrate() - SIOCGIWRATE ioctl handler
2321 * @dev: device upon which the ioctl was received
2322 * @info: ioctl request information
2323 * @wrqu: ioctl request data
2324 * @extra: ioctl extra data
2325 *
2326 * Return: 0 on success, non-zero on error
2327 */
2328static int __iw_get_bitrate(struct net_device *dev,
2329 struct iw_request_info *info,
2330 union iwreq_data *wrqu, char *extra)
2331{
Anurag Chouhance0dc992016-02-16 18:18:03 +05302332 QDF_STATUS qdf_status = QDF_STATUS_SUCCESS;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302333 QDF_STATUS status = QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002334 hdd_wext_state_t *pWextState;
2335 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
2336 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
2337 hdd_context_t *hdd_ctx;
2338 int ret;
2339
Jeff Johnsonb25dcb12016-02-11 17:46:42 -08002340 ENTER_DEV(dev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002341
2342 hdd_ctx = WLAN_HDD_GET_CTX(pAdapter);
2343 ret = wlan_hdd_validate_context(hdd_ctx);
2344 if (0 != ret)
2345 return ret;
2346
Prashanth Bhatta9e143052015-12-04 11:56:47 -08002347 if (cds_is_driver_recovering()) {
2348 hdd_alert("Recovery in Progress. State: 0x%x Ignore!!!",
2349 cds_get_driver_state());
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002350 return status;
2351 }
2352
2353 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState) {
2354 wrqu->bitrate.value = 0;
2355 } else {
2356 status =
2357 sme_get_statistics(WLAN_HDD_GET_HAL_CTX(pAdapter),
2358 eCSR_HDD,
2359 SME_SUMMARY_STATS |
2360 SME_GLOBAL_CLASSA_STATS |
2361 SME_GLOBAL_CLASSB_STATS |
2362 SME_GLOBAL_CLASSC_STATS |
2363 SME_GLOBAL_CLASSD_STATS |
2364 SME_PER_STA_STATS,
2365 hdd_statistics_cb, 0,
2366 false,
2367 pHddStaCtx->conn_info.staId[0],
2368 pAdapter, pAdapter->sessionId);
2369
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302370 if (QDF_STATUS_SUCCESS != status) {
Jeff Johnson99bac312016-06-28 10:38:18 -07002371 hdd_err("Unable to retrieve statistics");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002372 return status;
2373 }
2374
2375 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
2376
Anurag Chouhance0dc992016-02-16 18:18:03 +05302377 qdf_status =
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05302378 qdf_wait_single_event(&pWextState->hdd_qdf_event,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002379 WLAN_WAIT_TIME_STATS);
2380
Anurag Chouhance0dc992016-02-16 18:18:03 +05302381 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Jeff Johnson99bac312016-06-28 10:38:18 -07002382 hdd_err("SME timeout while retrieving statistics");
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302383 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002384 }
2385
2386 wrqu->bitrate.value =
2387 pAdapter->hdd_stats.ClassA_stat.tx_rate * 500 * 1000;
2388 }
2389
2390 EXIT();
2391
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302392 return qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002393}
2394
2395/**
2396 * iw_get_bitrate() - SSR wrapper for __iw_get_bitrate()
2397 * @dev: pointer to net_device
2398 * @info: pointer to iw_request_info
2399 * @wrqu: pointer to iwreq_data
2400 * @extra: pointer to extra ioctl payload
2401 *
2402 * Return: 0 on success, error number otherwise
2403 */
2404static int iw_get_bitrate(struct net_device *dev,
2405 struct iw_request_info *info,
2406 union iwreq_data *wrqu, char *extra)
2407{
2408 int ret;
2409
2410 cds_ssr_protect(__func__);
2411 ret = __iw_get_bitrate(dev, info, wrqu, extra);
2412 cds_ssr_unprotect(__func__);
2413
2414 return ret;
2415}
2416
2417/**
2418 * __iw_set_bitrate() - SIOCSIWRATE ioctl handler
2419 * @dev: device upon which the ioctl was received
2420 * @info: ioctl request information
2421 * @wrqu: ioctl request data
2422 * @extra: ioctl extra data
2423 *
2424 * Return: 0 on success, non-zero on error
2425 */
2426static int __iw_set_bitrate(struct net_device *dev,
2427 struct iw_request_info *info,
2428 union iwreq_data *wrqu, char *extra)
2429{
2430 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
2431 hdd_wext_state_t *pWextState;
2432 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
2433 uint8_t supp_rates[WNI_CFG_SUPPORTED_RATES_11A_LEN];
2434 uint32_t a_len = WNI_CFG_SUPPORTED_RATES_11A_LEN;
2435 uint32_t b_len = WNI_CFG_SUPPORTED_RATES_11B_LEN;
2436 uint32_t i, rate;
2437 uint32_t valid_rate = false, active_phy_mode = 0;
2438 hdd_context_t *hdd_ctx;
2439 int ret;
2440
Jeff Johnsonb25dcb12016-02-11 17:46:42 -08002441 ENTER_DEV(dev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002442
2443 hdd_ctx = WLAN_HDD_GET_CTX(pAdapter);
2444 ret = wlan_hdd_validate_context(hdd_ctx);
2445 if (0 != ret)
2446 return ret;
2447
2448 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
2449
2450 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState) {
2451 return -ENXIO;
2452 }
2453
2454 rate = wrqu->bitrate.value;
2455
2456 if (rate == -1) {
2457 rate = WNI_CFG_FIXED_RATE_AUTO;
2458 valid_rate = true;
2459 } else if (sme_cfg_get_int(WLAN_HDD_GET_HAL_CTX(pAdapter),
2460 WNI_CFG_DOT11_MODE,
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302461 &active_phy_mode) == QDF_STATUS_SUCCESS) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002462 if (active_phy_mode == WNI_CFG_DOT11_MODE_11A
2463 || active_phy_mode == WNI_CFG_DOT11_MODE_11G
2464 || active_phy_mode == WNI_CFG_DOT11_MODE_11B) {
2465 if ((sme_cfg_get_str(WLAN_HDD_GET_HAL_CTX(pAdapter),
2466 WNI_CFG_SUPPORTED_RATES_11A, supp_rates,
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302467 &a_len) == QDF_STATUS_SUCCESS)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002468 &&
2469 (sme_cfg_get_str(WLAN_HDD_GET_HAL_CTX(pAdapter),
2470 WNI_CFG_SUPPORTED_RATES_11B, supp_rates,
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302471 &b_len) == QDF_STATUS_SUCCESS)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002472 for (i = 0; i < (b_len + a_len); ++i) {
2473 /* supported rates returned is double
2474 * the actual rate so we divide it by 2
2475 */
2476 if ((supp_rates[i] & 0x7F) / 2 ==
2477 rate) {
2478 valid_rate = true;
2479 rate = i +
2480 WNI_CFG_FIXED_RATE_1MBPS;
2481 break;
2482 }
2483 }
2484 }
2485 }
2486 }
2487 if (valid_rate != true) {
2488 return -EINVAL;
2489 }
2490 if (sme_cfg_set_int(WLAN_HDD_GET_HAL_CTX(pAdapter),
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302491 WNI_CFG_FIXED_RATE, rate) != QDF_STATUS_SUCCESS) {
Jeff Johnson99bac312016-06-28 10:38:18 -07002492 hdd_err("failed to set ini parameter, WNI_CFG_FIXED_RATE");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002493 return -EIO;
2494 }
2495 return 0;
2496}
2497
2498/**
2499 * iw_set_bitrate() - SSR wrapper for __iw_set_bitrate()
2500 * @dev: pointer to net_device
2501 * @info: pointer to iw_request_info
2502 * @wrqu: pointer to iwreq_data
2503 * @extra: pointer to extra ioctl payload
2504 *
2505 * Return: 0 on success, error number otherwise
2506 */
2507static int iw_set_bitrate(struct net_device *dev,
2508 struct iw_request_info *info,
2509 union iwreq_data *wrqu, char *extra)
2510{
2511 int ret;
2512
2513 cds_ssr_protect(__func__);
2514 ret = __iw_set_bitrate(dev, info, wrqu, extra);
2515 cds_ssr_unprotect(__func__);
2516
2517 return ret;
2518}
2519
2520/**
2521 * __iw_set_genie() - SIOCSIWGENIE ioctl handler
2522 * @dev: device upon which the ioctl was received
2523 * @info: ioctl request information
2524 * @wrqu: ioctl request data
2525 * @extra: ioctl extra data
2526 *
2527 * Return: 0 on success, non-zero on error
2528 */
2529static int __iw_set_genie(struct net_device *dev,
2530 struct iw_request_info *info,
2531 union iwreq_data *wrqu, char *extra)
2532{
2533 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
2534 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
2535 uint8_t *genie = NULL;
2536 uint8_t *base_genie = NULL;
2537 uint16_t remLen;
2538 hdd_context_t *hdd_ctx;
2539 int ret;
2540
Jeff Johnsonb25dcb12016-02-11 17:46:42 -08002541 ENTER_DEV(dev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002542
2543 hdd_ctx = WLAN_HDD_GET_CTX(pAdapter);
2544 ret = wlan_hdd_validate_context(hdd_ctx);
2545 if (0 != ret)
2546 return ret;
2547
2548 if (!wrqu->data.length) {
2549 hdd_clear_roam_profile_ie(pAdapter);
2550 EXIT();
2551 return 0;
2552 }
2553
2554 base_genie = mem_alloc_copy_from_user_helper(wrqu->data.pointer,
2555 wrqu->data.length);
2556 if (NULL == base_genie) {
Jeff Johnson99bac312016-06-28 10:38:18 -07002557 hdd_err("mem_alloc_copy_from_user_helper fail");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002558 return -ENOMEM;
2559 }
2560
2561 genie = base_genie;
2562
2563 remLen = wrqu->data.length;
2564
Jeff Johnson99bac312016-06-28 10:38:18 -07002565 hdd_notice("iw_set_genie ioctl IE[0x%X], LEN[%d]", genie[0],
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002566 genie[1]);
2567
2568 /* clear any previous genIE before this call */
2569 memset(&pWextState->genIE, 0, sizeof(pWextState->genIE));
2570
2571 while (remLen >= 2) {
2572 uint16_t eLen = 0;
2573 uint8_t elementId;
2574 elementId = *genie++;
2575 eLen = *genie++;
2576 remLen -= 2;
2577
Jeff Johnson99bac312016-06-28 10:38:18 -07002578 hdd_notice("IE[0x%X], LEN[%d]", elementId, eLen);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002579
2580 switch (elementId) {
2581 case IE_EID_VENDOR:
2582 if ((IE_LEN_SIZE + IE_EID_SIZE + IE_VENDOR_OUI_SIZE) > eLen) { /* should have at least OUI */
Mahesh A Saptasagard639dde2015-11-06 12:39:13 +05302583 ret = -EINVAL;
2584 goto exit;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002585 }
2586
2587 if (0 == memcmp(&genie[0], "\x00\x50\xf2\x04", 4)) {
2588 uint16_t curGenIELen = pWextState->genIE.length;
Jeff Johnson99bac312016-06-28 10:38:18 -07002589 hdd_notice("Set WPS OUI(%02x %02x %02x %02x) IE(len %d)",
2590 genie[0], genie[1], genie[2],
2591 genie[3], eLen + 2);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002592
2593 if (SIR_MAC_MAX_IE_LENGTH <
2594 (pWextState->genIE.length + eLen)) {
Jeff Johnson99bac312016-06-28 10:38:18 -07002595 hdd_alert("Cannot accommodate genIE. Need bigger buffer space");
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302596 QDF_ASSERT(0);
Mahesh A Saptasagard639dde2015-11-06 12:39:13 +05302597 ret = -ENOMEM;
2598 goto exit;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002599 }
2600 /* save to Additional IE ; it should be accumulated to handle WPS IE + other IE */
2601 memcpy(pWextState->genIE.addIEdata +
2602 curGenIELen, genie - 2, eLen + 2);
2603 pWextState->genIE.length += eLen + 2;
2604 } else if (0 == memcmp(&genie[0], "\x00\x50\xf2", 3)) {
Jeff Johnson99bac312016-06-28 10:38:18 -07002605 hdd_notice("Set WPA IE (len %d)", eLen + 2);
Mahesh A Saptasagard639dde2015-11-06 12:39:13 +05302606 if ((eLen + 2) > (sizeof(pWextState->WPARSNIE))) {
2607 hdd_warn("Cannot accommodate genIE, Need bigger buffer space");
2608 ret = -EINVAL;
2609 QDF_ASSERT(0);
2610 goto exit;
2611 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002612 memset(pWextState->WPARSNIE, 0,
2613 MAX_WPA_RSN_IE_LEN);
2614 memcpy(pWextState->WPARSNIE, genie - 2,
2615 (eLen + 2));
2616 pWextState->roamProfile.pWPAReqIE =
2617 pWextState->WPARSNIE;
2618 pWextState->roamProfile.nWPAReqIELength =
2619 eLen + 2;
2620 } else { /* any vendorId except WPA IE should be accumulated to genIE */
2621
2622 uint16_t curGenIELen = pWextState->genIE.length;
Jeff Johnson99bac312016-06-28 10:38:18 -07002623 hdd_notice("Set OUI(%02x %02x %02x %02x) IE(len %d)",
2624 genie[0], genie[1], genie[2],
2625 genie[3], eLen + 2);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002626
2627 if (SIR_MAC_MAX_IE_LENGTH <
2628 (pWextState->genIE.length + eLen)) {
Jeff Johnson99bac312016-06-28 10:38:18 -07002629 hdd_alert("Cannot accommodate genIE. Need bigger buffer space");
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302630 QDF_ASSERT(0);
Mahesh A Saptasagard639dde2015-11-06 12:39:13 +05302631 ret = -ENOMEM;
2632 goto exit;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002633 }
2634 /* save to Additional IE ; it should be accumulated to handle WPS IE + other IE */
2635 memcpy(pWextState->genIE.addIEdata +
2636 curGenIELen, genie - 2, eLen + 2);
2637 pWextState->genIE.length += eLen + 2;
2638 }
2639 break;
2640 case DOT11F_EID_RSN:
Jeff Johnson99bac312016-06-28 10:38:18 -07002641 hdd_notice("Set RSN IE (len %d)", eLen + 2);
Mahesh A Saptasagard639dde2015-11-06 12:39:13 +05302642 if ((eLen + 2) > (sizeof(pWextState->WPARSNIE))) {
2643 hdd_warn("Cannot accommodate genIE, Need bigger buffer space");
2644 ret = -EINVAL;
2645 QDF_ASSERT(0);
2646 goto exit;
2647 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002648 memset(pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN);
2649 memcpy(pWextState->WPARSNIE, genie - 2, (eLen + 2));
2650 pWextState->roamProfile.pRSNReqIE =
2651 pWextState->WPARSNIE;
2652 pWextState->roamProfile.nRSNReqIELength = eLen + 2;
2653 break;
2654
2655 default:
Jeff Johnson99bac312016-06-28 10:38:18 -07002656 hdd_err("Set UNKNOWN IE %X", elementId);
Mahesh A Saptasagard639dde2015-11-06 12:39:13 +05302657 goto exit;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002658 }
2659 genie += eLen;
2660 remLen -= eLen;
2661 }
Mahesh A Saptasagard639dde2015-11-06 12:39:13 +05302662exit:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002663 EXIT();
2664 kfree(base_genie);
Mahesh A Saptasagard639dde2015-11-06 12:39:13 +05302665 return ret;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002666}
2667
2668/**
2669 * iw_set_genie() - SSR wrapper for __iw_set_genie()
2670 * @dev: pointer to net_device
2671 * @info: pointer to iw_request_info
2672 * @wrqu: pointer to iwreq_data
2673 * @extra: pointer to extra ioctl payload
2674 *
2675 * Return: 0 on success, error number otherwise
2676 */
2677static int iw_set_genie(struct net_device *dev,
2678 struct iw_request_info *info,
2679 union iwreq_data *wrqu, char *extra)
2680{
2681 int ret;
2682
2683 cds_ssr_protect(__func__);
2684 ret = __iw_set_genie(dev, info, wrqu, extra);
2685 cds_ssr_unprotect(__func__);
2686
2687 return ret;
2688}
2689
2690/**
2691 * __iw_get_genie() - SIOCGIWGENIE ioctl handler
2692 * @dev: device upon which the ioctl was received
2693 * @info: ioctl request information
2694 * @wrqu: ioctl request data
2695 * @extra: ioctl extra data
2696 *
2697 * Return: 0 on success, non-zero on error
2698 */
2699static int __iw_get_genie(struct net_device *dev,
2700 struct iw_request_info *info,
2701 union iwreq_data *wrqu, char *extra)
2702{
2703 hdd_wext_state_t *pWextState;
2704 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
2705 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302706 QDF_STATUS status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002707 uint32_t length = DOT11F_IE_RSN_MAX_LEN;
2708 uint8_t genIeBytes[DOT11F_IE_RSN_MAX_LEN];
2709 hdd_context_t *hdd_ctx;
2710 int ret;
2711
Jeff Johnsonb25dcb12016-02-11 17:46:42 -08002712 ENTER_DEV(dev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002713
2714 hdd_ctx = WLAN_HDD_GET_CTX(pAdapter);
2715 ret = wlan_hdd_validate_context(hdd_ctx);
2716 if (0 != ret)
2717 return ret;
2718
Jeff Johnson99bac312016-06-28 10:38:18 -07002719 hdd_notice("getGEN_IE ioctl");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002720
2721 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
2722
2723 if (pHddStaCtx->conn_info.connState == eConnectionState_NotConnected) {
2724 return -ENXIO;
2725 }
2726
2727 /* Return something ONLY if we are associated with an RSN or
2728 * WPA network
2729 */
2730 if (!hdd_is_auth_type_rsn(pWextState->roamProfile.negotiatedAuthType)) {
2731 return -ENXIO;
2732 }
2733
2734 /* Actually retrieve the RSN IE from CSR. (We previously sent
2735 * it down in the CSR Roam Profile.)
2736 */
2737 status = csr_roam_get_wpa_rsn_req_ie(WLAN_HDD_GET_HAL_CTX(pAdapter),
2738 pAdapter->sessionId,
2739 &length, genIeBytes);
Anurag Chouhan6d760662016-02-20 16:05:43 +05302740 length = QDF_MIN((uint16_t) length, DOT11F_IE_RSN_MAX_LEN);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002741 if (wrqu->data.length < length) {
Jeff Johnson99bac312016-06-28 10:38:18 -07002742 hdd_notice("failed to copy data to user buffer");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002743 return -EFAULT;
2744 }
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302745 qdf_mem_copy(extra, (void *)genIeBytes, length);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002746 wrqu->data.length = length;
2747
Jeff Johnson99bac312016-06-28 10:38:18 -07002748 hdd_notice("RSN IE of %d bytes returned",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002749 wrqu->data.length);
2750
2751 EXIT();
2752
2753 return 0;
2754}
2755
2756/**
2757 * iw_get_genie() - SSR wrapper for __iw_get_genie()
2758 * @dev: pointer to net_device
2759 * @info: pointer to iw_request_info
2760 * @wrqu: pointer to iwreq_data
2761 * @extra: pointer to extra ioctl payload
2762 *
2763 * Return: 0 on success, error number otherwise
2764 */
2765static int iw_get_genie(struct net_device *dev,
2766 struct iw_request_info *info,
2767 union iwreq_data *wrqu, char *extra)
2768{
2769 int ret;
2770
2771 cds_ssr_protect(__func__);
2772 ret = __iw_get_genie(dev, info, wrqu, extra);
2773 cds_ssr_unprotect(__func__);
2774
2775 return ret;
2776}
2777
2778/**
2779 * __iw_get_encode() - SIOCGIWENCODE ioctl handler
2780 * @dev: device upon which the ioctl was received
2781 * @info: ioctl request information
2782 * @wrqu: ioctl request data
2783 * @extra: ioctl extra data
2784 *
2785 * Return: 0 on success, non-zero on error
2786 */
2787static int __iw_get_encode(struct net_device *dev,
2788 struct iw_request_info *info,
2789 struct iw_point *dwrq, char *extra)
2790{
2791 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
2792 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
2793 tCsrRoamProfile *pRoamProfile = &(pWextState->roamProfile);
2794 int keyId;
2795 eCsrAuthType authType = eCSR_AUTH_TYPE_NONE;
2796 int i;
2797 hdd_context_t *hdd_ctx;
2798 int ret;
2799
Jeff Johnsonb25dcb12016-02-11 17:46:42 -08002800 ENTER_DEV(dev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002801
2802 hdd_ctx = WLAN_HDD_GET_CTX(pAdapter);
2803 ret = wlan_hdd_validate_context(hdd_ctx);
2804 if (0 != ret)
2805 return ret;
2806
2807 keyId = pRoamProfile->Keys.defaultIndex;
2808
2809 if (keyId < 0 || keyId >= MAX_WEP_KEYS) {
Jeff Johnson99bac312016-06-28 10:38:18 -07002810 hdd_notice("Invalid keyId : %d", keyId);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002811 return -EINVAL;
2812 }
2813
2814 if (pRoamProfile->Keys.KeyLength[keyId] > 0) {
2815 dwrq->flags |= IW_ENCODE_ENABLED;
2816 dwrq->length = pRoamProfile->Keys.KeyLength[keyId];
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302817 qdf_mem_copy(extra, &(pRoamProfile->Keys.KeyMaterial[keyId][0]),
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002818 pRoamProfile->Keys.KeyLength[keyId]);
2819
2820 dwrq->flags |= (keyId + 1);
2821
2822 } else {
2823 dwrq->flags |= IW_ENCODE_DISABLED;
2824 }
2825
2826 for (i = 0; i < MAX_WEP_KEYS; i++) {
2827 if (pRoamProfile->Keys.KeyMaterial[i] == NULL) {
2828 continue;
2829 } else {
2830 break;
2831 }
2832 }
2833
2834 if (MAX_WEP_KEYS == i) {
2835 dwrq->flags |= IW_ENCODE_NOKEY;
2836 }
2837
2838 authType =
2839 ((hdd_station_ctx_t *) WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->
2840 conn_info.authType;
2841
2842 if (eCSR_AUTH_TYPE_OPEN_SYSTEM == authType) {
2843 dwrq->flags |= IW_ENCODE_OPEN;
2844 } else {
2845 dwrq->flags |= IW_ENCODE_RESTRICTED;
2846 }
2847 EXIT();
2848 return 0;
2849}
2850
2851/**
2852 * iw_get_encode() - SSR wrapper for __iw_get_encode()
2853 * @dev: pointer to net_device
2854 * @info: pointer to iw_request_info
2855 * @dwrq: pointer to encoding information
2856 * @extra: pointer to extra ioctl payload
2857 *
2858 * Return: 0 on success, error number otherwise
2859 */
2860static int iw_get_encode(struct net_device *dev, struct iw_request_info *info,
2861 struct iw_point *dwrq, char *extra)
2862{
2863 int ret;
2864
2865 cds_ssr_protect(__func__);
2866 ret = __iw_get_encode(dev, info, dwrq, extra);
2867 cds_ssr_unprotect(__func__);
2868
2869 return ret;
2870}
2871
2872/**
2873 * __iw_get_rts_threshold() - SIOCGIWRTS ioctl handler
2874 * @dev: device upon which the ioctl was received
2875 * @info: ioctl request information
2876 * @wrqu: ioctl request data
2877 * @extra: ioctl extra data
2878 *
2879 * Return: 0 on success, non-zero on error
2880 */
2881static int __iw_get_rts_threshold(struct net_device *dev,
2882 struct iw_request_info *info,
2883 union iwreq_data *wrqu, char *extra)
2884{
2885 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
2886 uint32_t status = 0;
2887
Jeff Johnsonb25dcb12016-02-11 17:46:42 -08002888 ENTER_DEV(dev);
2889
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002890 status = hdd_wlan_get_rts_threshold(pAdapter, wrqu);
2891
2892 return status;
2893}
2894
2895/**
2896 * __iw_set_rts_threshold() - SIOCSIWRTS ioctl handler
2897 * @dev: device upon which the ioctl was received
2898 * @info: ioctl request information
2899 * @wrqu: ioctl request data
2900 * @extra: ioctl extra data
2901 *
2902 * Return: 0 on success, non-zero on error
2903 */
2904static int __iw_set_rts_threshold(struct net_device *dev,
2905 struct iw_request_info *info,
2906 union iwreq_data *wrqu, char *extra)
2907{
2908 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
2909 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
2910 hdd_context_t *hdd_ctx;
2911 int ret;
2912
Jeff Johnsonb25dcb12016-02-11 17:46:42 -08002913 ENTER_DEV(dev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002914
2915 hdd_ctx = WLAN_HDD_GET_CTX(pAdapter);
2916 ret = wlan_hdd_validate_context(hdd_ctx);
2917 if (0 != ret)
2918 return ret;
2919
2920 if (wrqu->rts.value < WNI_CFG_RTS_THRESHOLD_STAMIN
2921 || wrqu->rts.value > WNI_CFG_RTS_THRESHOLD_STAMAX) {
2922 return -EINVAL;
2923 }
2924
2925 if (sme_cfg_set_int(hHal, WNI_CFG_RTS_THRESHOLD, wrqu->rts.value) !=
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302926 QDF_STATUS_SUCCESS) {
Jeff Johnson99bac312016-06-28 10:38:18 -07002927 hdd_err("failed to set ini parameter, WNI_CFG_RTS_THRESHOLD");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002928 return -EIO;
2929 }
2930
2931 EXIT();
2932
2933 return 0;
2934}
2935
2936/**
2937 * iw_get_rts_threshold() - SSR wrapper for __iw_get_rts_threshold()
2938 * @dev: pointer to net_device
2939 * @info: pointer to iw_request_info
2940 * @wrqu: pointer to iwreq_data
2941 * @extra: pointer to extra ioctl payload
2942 *
2943 * Return: 0 on success, error number otherwise
2944 */
2945static int iw_get_rts_threshold(struct net_device *dev,
2946 struct iw_request_info *info,
2947 union iwreq_data *wrqu, char *extra)
2948{
2949 int ret;
2950
2951 cds_ssr_protect(__func__);
2952 ret = __iw_get_rts_threshold(dev, info, wrqu, extra);
2953 cds_ssr_unprotect(__func__);
2954
2955 return ret;
2956}
2957
2958/**
2959 * iw_set_rts_threshold() - SSR wrapper for __iw_set_rts_threshold()
2960 * @dev: pointer to net_device
2961 * @info: pointer to iw_request_info
2962 * @wrqu: pointer to iwreq_data
2963 * @extra: pointer to extra ioctl payload
2964 *
2965 * Return: 0 on success, error number otherwise
2966 */
2967static int iw_set_rts_threshold(struct net_device *dev,
2968 struct iw_request_info *info,
2969 union iwreq_data *wrqu, char *extra)
2970{
2971 int ret;
2972
2973 cds_ssr_protect(__func__);
2974 ret = __iw_set_rts_threshold(dev, info, wrqu, extra);
2975 cds_ssr_unprotect(__func__);
2976
2977 return ret;
2978}
2979
2980/**
2981 * __iw_get_frag_threshold() - SIOCGIWFRAG ioctl handler
2982 * @dev: device upon which the ioctl was received
2983 * @info: ioctl request information
2984 * @wrqu: ioctl request data
2985 * @extra: ioctl extra data
2986 *
2987 * Return: 0 on success, non-zero on error
2988 */
2989static int __iw_get_frag_threshold(struct net_device *dev,
2990 struct iw_request_info *info,
2991 union iwreq_data *wrqu, char *extra)
2992{
2993 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
2994 uint32_t status = 0;
2995
Jeff Johnsonb25dcb12016-02-11 17:46:42 -08002996 ENTER_DEV(dev);
2997
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002998 status = hdd_wlan_get_frag_threshold(pAdapter, wrqu);
2999
3000 return status;
3001}
3002
3003/**
3004 * iw_get_frag_threshold() - SSR wrapper for __iw_get_frag_threshold()
3005 * @dev: pointer to net_device
3006 * @info: pointer to iw_request_info
3007 * @wrqu: pointer to iwreq_data
3008 * @extra: pointer to extra ioctl payload
3009 *
3010 * Return: 0 on success, error number otherwise
3011 */
3012static int iw_get_frag_threshold(struct net_device *dev,
3013 struct iw_request_info *info,
3014 union iwreq_data *wrqu, char *extra)
3015{
3016 int ret;
3017
3018 cds_ssr_protect(__func__);
3019 ret = __iw_get_frag_threshold(dev, info, wrqu, extra);
3020 cds_ssr_unprotect(__func__);
3021
3022 return ret;
3023}
3024
3025/**
3026 * __iw_set_frag_threshold() - SIOCSIWFRAG ioctl handler
3027 * @dev: device upon which the ioctl was received
3028 * @info: ioctl request information
3029 * @wrqu: ioctl request data
3030 * @extra: ioctl extra data
3031 *
3032 * Return: 0 on success, non-zero on error
3033 */
3034static int __iw_set_frag_threshold(struct net_device *dev,
3035 struct iw_request_info *info,
3036 union iwreq_data *wrqu, char *extra)
3037{
3038 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3039 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
3040 hdd_context_t *hdd_ctx;
3041 int ret;
3042
Jeff Johnsonb25dcb12016-02-11 17:46:42 -08003043 ENTER_DEV(dev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003044
3045 hdd_ctx = WLAN_HDD_GET_CTX(pAdapter);
3046 ret = wlan_hdd_validate_context(hdd_ctx);
3047 if (0 != ret)
3048 return ret;
3049
3050 if (wrqu->frag.value < WNI_CFG_FRAGMENTATION_THRESHOLD_STAMIN
3051 || wrqu->frag.value > WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX) {
3052 return -EINVAL;
3053 }
3054
3055 if (sme_cfg_set_int
3056 (hHal, WNI_CFG_FRAGMENTATION_THRESHOLD, wrqu->frag.value)
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303057 != QDF_STATUS_SUCCESS) {
Jeff Johnson99bac312016-06-28 10:38:18 -07003058 hdd_err("failed to set ini parameter, WNI_CFG_FRAGMENTATION_THRESHOLD");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003059 return -EIO;
3060 }
3061
3062 EXIT();
3063
3064 return 0;
3065}
3066
3067/**
3068 * iw_set_frag_threshold() - SSR wrapper for __iw_set_frag_threshold()
3069 * @dev: pointer to net_device
3070 * @info: pointer to iw_request_info
3071 * @wrqu: pointer to iwreq_data
3072 * @extra: pointer to extra ioctl payload
3073 *
3074 * Return: 0 on success, error number otherwise
3075 */
3076static int iw_set_frag_threshold(struct net_device *dev,
3077 struct iw_request_info *info,
3078 union iwreq_data *wrqu, char *extra)
3079{
3080 int ret;
3081
3082 cds_ssr_protect(__func__);
3083 ret = __iw_set_frag_threshold(dev, info, wrqu, extra);
3084 cds_ssr_unprotect(__func__);
3085
3086 return ret;
3087}
3088
3089/**
3090 * __iw_get_power_mode() - SIOCGIWPOWER ioctl handler
3091 * @dev: device upon which the ioctl was received
3092 * @info: ioctl request information
3093 * @wrqu: ioctl request data
3094 * @extra: ioctl extra data
3095 *
3096 * Return: 0 on success, non-zero on error
3097 */
3098static int __iw_get_power_mode(struct net_device *dev,
3099 struct iw_request_info *info,
3100 union iwreq_data *wrqu, char *extra)
3101{
3102 hdd_adapter_t *adapter;
3103 hdd_context_t *hdd_ctx;
3104 int ret;
3105
Jeff Johnsonb25dcb12016-02-11 17:46:42 -08003106 ENTER_DEV(dev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003107
3108 adapter = WLAN_HDD_GET_PRIV_PTR(dev);
3109 hdd_ctx = WLAN_HDD_GET_CTX(adapter);
3110 ret = wlan_hdd_validate_context(hdd_ctx);
3111 if (0 != ret)
3112 return ret;
3113
3114 return -EOPNOTSUPP;
3115}
3116
3117/**
3118 * iw_get_power_mode() - SSR wrapper function for __iw_get_power_mode
3119 * @dev: pointer to net_device
3120 * @info: pointer to iw_request_info
3121 * @wrqu: pointer to iwreq_data
3122 * @extra: extra
3123 *
3124 * Return: 0 on success, error number otherwise
3125 */
3126int iw_get_power_mode(struct net_device *dev,
3127 struct iw_request_info *info,
3128 union iwreq_data *wrqu, char *extra)
3129{
3130 int ret;
3131
3132 cds_ssr_protect(__func__);
3133 ret = __iw_get_power_mode(dev, info, wrqu, extra);
3134 cds_ssr_unprotect(__func__);
3135
3136 return ret;
3137}
3138
3139/**
3140 * __iw_set_power_mode() - SIOCSIWPOWER ioctl handler
3141 * @dev: device upon which the ioctl was received
3142 * @info: ioctl request information
3143 * @wrqu: ioctl request data
3144 * @extra: ioctl extra data
3145 *
3146 * Return: 0 on success, non-zero on error
3147 */
3148static int __iw_set_power_mode(struct net_device *dev,
3149 struct iw_request_info *info,
3150 union iwreq_data *wrqu, char *extra)
3151{
3152 hdd_adapter_t *adapter;
3153 hdd_context_t *hdd_ctx;
3154 int ret;
3155
Jeff Johnsonb25dcb12016-02-11 17:46:42 -08003156 ENTER_DEV(dev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003157
3158 adapter = WLAN_HDD_GET_PRIV_PTR(dev);
3159 hdd_ctx = WLAN_HDD_GET_CTX(adapter);
3160 ret = wlan_hdd_validate_context(hdd_ctx);
3161 if (0 != ret)
3162 return ret;
3163
3164 return -EOPNOTSUPP;
3165}
3166
3167/**
3168 * iw_set_power_mode() - SSR wrapper function for __iw_set_power_mode
3169 * @dev: pointer to net_device
3170 * @info: pointer to iw_request_info
3171 * @wrqu: pointer to iwreq_data
3172 * @extra: extra
3173 *
3174 * Return: 0 on success, error number otherwise
3175 */
3176int iw_set_power_mode(struct net_device *dev,
3177 struct iw_request_info *info,
3178 union iwreq_data *wrqu, char *extra)
3179{
3180 int ret;
3181
3182 cds_ssr_protect(__func__);
3183 ret = __iw_set_power_mode(dev, info, wrqu, extra);
3184 cds_ssr_unprotect(__func__);
3185
3186 return ret;
3187}
3188
3189/**
3190 * __iw_get_range() - SIOCGIWRANGE ioctl handler
3191 * @dev: device upon which the ioctl was received
3192 * @info: ioctl request information
3193 * @wrqu: ioctl request data
3194 * @extra: ioctl extra data
3195 *
3196 * Return: 0 on success, non-zero on error
3197 */
3198static int __iw_get_range(struct net_device *dev, struct iw_request_info *info,
3199 union iwreq_data *wrqu, char *extra)
3200{
3201 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3202 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
3203 struct iw_range *range = (struct iw_range *)extra;
3204
3205 uint8_t channels[WNI_CFG_VALID_CHANNEL_LIST_LEN];
3206
3207 uint32_t num_channels = sizeof(channels);
3208 uint8_t supp_rates[WNI_CFG_SUPPORTED_RATES_11A_LEN];
3209 uint32_t a_len;
3210 uint32_t b_len;
3211 uint32_t active_phy_mode = 0;
3212 uint8_t index = 0, i;
3213 hdd_context_t *hdd_ctx;
3214 int ret;
3215
Jeff Johnsonb25dcb12016-02-11 17:46:42 -08003216 ENTER_DEV(dev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003217
3218 hdd_ctx = WLAN_HDD_GET_CTX(pAdapter);
3219 ret = wlan_hdd_validate_context(hdd_ctx);
3220 if (0 != ret)
3221 return ret;
3222
3223 wrqu->data.length = sizeof(struct iw_range);
3224 memset(range, 0, sizeof(struct iw_range));
3225
3226
3227 /*Get the phy mode */
3228 if (sme_cfg_get_int(hHal,
3229 WNI_CFG_DOT11_MODE,
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303230 &active_phy_mode) == QDF_STATUS_SUCCESS) {
Jeff Johnson99bac312016-06-28 10:38:18 -07003231 hdd_notice("active_phy_mode = %d", active_phy_mode);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003232
3233 if (active_phy_mode == WNI_CFG_DOT11_MODE_11A
3234 || active_phy_mode == WNI_CFG_DOT11_MODE_11G) {
3235 /*Get the supported rates for 11G band */
3236 a_len = WNI_CFG_SUPPORTED_RATES_11A_LEN;
3237 if (sme_cfg_get_str(hHal,
3238 WNI_CFG_SUPPORTED_RATES_11A,
3239 supp_rates,
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303240 &a_len) == QDF_STATUS_SUCCESS) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003241 if (a_len > WNI_CFG_SUPPORTED_RATES_11A_LEN) {
3242 a_len = WNI_CFG_SUPPORTED_RATES_11A_LEN;
3243 }
3244 for (i = 0; i < a_len; i++) {
3245 range->bitrate[i] =
3246 ((supp_rates[i] & 0x7F) / 2) *
3247 1000000;
3248 }
3249 range->num_bitrates = a_len;
3250 } else {
3251 return -EIO;
3252 }
3253 } else if (active_phy_mode == WNI_CFG_DOT11_MODE_11B) {
3254 /*Get the supported rates for 11B band */
3255 b_len = WNI_CFG_SUPPORTED_RATES_11B_LEN;
3256 if (sme_cfg_get_str(hHal,
3257 WNI_CFG_SUPPORTED_RATES_11B,
3258 supp_rates,
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303259 &b_len) == QDF_STATUS_SUCCESS) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003260 if (b_len > WNI_CFG_SUPPORTED_RATES_11B_LEN) {
3261 b_len = WNI_CFG_SUPPORTED_RATES_11B_LEN;
3262 }
3263 for (i = 0; i < b_len; i++) {
3264 range->bitrate[i] =
3265 ((supp_rates[i] & 0x7F) / 2) *
3266 1000000;
3267 }
3268 range->num_bitrates = b_len;
3269 } else {
3270 return -EIO;
3271 }
3272 }
3273 }
3274
3275 range->max_rts = WNI_CFG_RTS_THRESHOLD_STAMAX;
3276 range->min_frag = WNI_CFG_FRAGMENTATION_THRESHOLD_STAMIN;
3277 range->max_frag = WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX;
3278
3279 range->encoding_size[0] = 5;
3280 range->encoding_size[1] = 13;
3281 range->num_encoding_sizes = 2;
3282 range->max_encoding_tokens = MAX_WEP_KEYS;
3283
3284 /* we support through Wireless Extensions 22 */
3285 range->we_version_compiled = WIRELESS_EXT;
3286 range->we_version_source = 22;
3287
3288 /*Supported Channels and Frequencies */
3289 if (sme_cfg_get_str
3290 ((hHal), WNI_CFG_VALID_CHANNEL_LIST, channels,
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303291 &num_channels) != QDF_STATUS_SUCCESS) {
Jeff Johnson99bac312016-06-28 10:38:18 -07003292 hdd_warn("failed to get ini parameter, WNI_CFG_VALID_CHANNEL_LIST");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003293 return -EIO;
3294 }
3295 if (num_channels > IW_MAX_FREQUENCIES) {
3296 num_channels = IW_MAX_FREQUENCIES;
3297 }
3298
3299 range->num_channels = num_channels;
3300 range->num_frequency = num_channels;
3301
3302 for (index = 0; index < num_channels; index++) {
3303 uint32_t frq_indx = 0;
3304
3305 range->freq[index].i = channels[index];
3306 while (frq_indx < FREQ_CHAN_MAP_TABLE_SIZE) {
3307 if (channels[index] == freq_chan_map[frq_indx].chan) {
3308 range->freq[index].m =
3309 freq_chan_map[frq_indx].freq * 100000;
3310 range->freq[index].e = 1;
3311 break;
3312 }
3313 frq_indx++;
3314 }
3315 }
3316
3317 /* Event capability (kernel + driver) */
3318 range->event_capa[0] = (IW_EVENT_CAPA_K_0 |
3319 IW_EVENT_CAPA_MASK(SIOCGIWAP) |
3320 IW_EVENT_CAPA_MASK(SIOCGIWSCAN));
3321 range->event_capa[1] = IW_EVENT_CAPA_K_1;
3322
3323 /*Encryption capability */
3324 range->enc_capa = IW_ENC_CAPA_WPA | IW_ENC_CAPA_WPA2 |
3325 IW_ENC_CAPA_CIPHER_TKIP | IW_ENC_CAPA_CIPHER_CCMP;
3326
3327 /* Txpower capability */
3328 range->txpower_capa = IW_TXPOW_MWATT;
3329
3330 /*Scanning capability */
3331#if WIRELESS_EXT >= 22
3332 range->scan_capa =
3333 IW_SCAN_CAPA_ESSID | IW_SCAN_CAPA_TYPE | IW_SCAN_CAPA_CHANNEL;
3334#endif
3335
3336 EXIT();
3337 return 0;
3338}
3339
3340/**
3341 * iw_get_range() - SSR wrapper for __iw_get_range()
3342 * @dev: pointer to net_device
3343 * @info: pointer to iw_request_info
3344 * @wrqu: pointer to iwreq_data
3345 * @extra: pointer to extra ioctl payload
3346 *
3347 * Return: 0 on success, error number otherwise
3348 */
3349static int iw_get_range(struct net_device *dev, struct iw_request_info *info,
3350 union iwreq_data *wrqu, char *extra)
3351{
3352 int ret;
3353
3354 cds_ssr_protect(__func__);
3355 ret = __iw_get_range(dev, info, wrqu, extra);
3356 cds_ssr_unprotect(__func__);
3357
3358 return ret;
3359}
3360
3361/**
3362 * hdd_get_class_a_statistics_cb() - Get Class A stats callback function
3363 * @pStats: pointer to Class A stats
3364 * @pContext: user context originally registered with SME
3365 *
3366 * Return: None
3367 */
3368static void hdd_get_class_a_statistics_cb(void *pStats, void *pContext)
3369{
3370 struct statsContext *pStatsContext;
3371 tCsrGlobalClassAStatsInfo *pClassAStats;
3372 hdd_adapter_t *pAdapter;
3373
3374 if (ioctl_debug) {
3375 pr_info("%s: pStats [%p] pContext [%p]\n",
3376 __func__, pStats, pContext);
3377 }
3378
3379 if ((NULL == pStats) || (NULL == pContext)) {
Jeff Johnson99bac312016-06-28 10:38:18 -07003380 hdd_err("Bad param, pStats [%p] pContext [%p]",
3381 pStats, pContext);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003382 return;
3383 }
3384
3385 pClassAStats = pStats;
3386 pStatsContext = pContext;
3387 pAdapter = pStatsContext->pAdapter;
3388
3389 /* there is a race condition that exists between this callback
3390 * function and the caller since the caller could time out
3391 * either before or while this code is executing. we use a
3392 * spinlock to serialize these actions
3393 */
3394 spin_lock(&hdd_context_lock);
3395
3396 if ((NULL == pAdapter) ||
3397 (STATS_CONTEXT_MAGIC != pStatsContext->magic)) {
3398 /* the caller presumably timed out so there is nothing
3399 * we can do
3400 */
3401 spin_unlock(&hdd_context_lock);
Jeff Johnson99bac312016-06-28 10:38:18 -07003402 hdd_warn("Invalid context, pAdapter [%p] magic [%08x]",
3403 pAdapter, pStatsContext->magic);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003404 if (ioctl_debug) {
3405 pr_info("%s: Invalid context, pAdapter [%p] magic [%08x]\n",
3406 __func__, pAdapter, pStatsContext->magic);
3407 }
3408 return;
3409 }
3410
3411 /* context is valid so caller is still waiting */
3412
3413 /* paranoia: invalidate the magic */
3414 pStatsContext->magic = 0;
3415
3416 /* copy over the stats. do so as a struct copy */
3417 pAdapter->hdd_stats.ClassA_stat = *pClassAStats;
3418
3419 /* notify the caller */
3420 complete(&pStatsContext->completion);
3421
3422 /* serialization is complete */
3423 spin_unlock(&hdd_context_lock);
3424}
3425
3426/**
3427 * wlan_hdd_get_class_astats() - Get Class A statistics
3428 * @pAdapter: adapter for which statistics are desired
3429 *
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303430 * Return: QDF_STATUS_SUCCESS if adapter's Class A statistics were updated
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003431 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303432QDF_STATUS wlan_hdd_get_class_astats(hdd_adapter_t *pAdapter)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003433{
3434 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303435 QDF_STATUS hstatus;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003436 unsigned long rc;
3437 struct statsContext context;
3438
3439 if (NULL == pAdapter) {
Jeff Johnson99bac312016-06-28 10:38:18 -07003440 hdd_err("pAdapter is NULL");
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303441 return QDF_STATUS_E_FAULT;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003442 }
Prashanth Bhatta9e143052015-12-04 11:56:47 -08003443 if (cds_is_driver_recovering()) {
3444 hdd_err("Recovery in Progress. State: 0x%x Ignore!!!",
3445 cds_get_driver_state());
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303446 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003447 }
3448
3449 /* we are connected so prepare our callback context */
3450 init_completion(&context.completion);
3451 context.pAdapter = pAdapter;
3452 context.magic = STATS_CONTEXT_MAGIC;
3453 /* query only for Class A statistics (which include link speed) */
3454 hstatus = sme_get_statistics(WLAN_HDD_GET_HAL_CTX(pAdapter),
3455 eCSR_HDD, SME_GLOBAL_CLASSA_STATS,
3456 hdd_get_class_a_statistics_cb,
3457 0, /* not periodic */
3458 false, /* non-cached results */
3459 pHddStaCtx->conn_info.staId[0],
3460 &context, pAdapter->sessionId);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303461 if (QDF_STATUS_SUCCESS != hstatus) {
Jeff Johnson99bac312016-06-28 10:38:18 -07003462 hdd_err("Unable to retrieve Class A statistics");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003463 /* we'll returned a cached value below */
3464 } else {
3465 /* request was sent -- wait for the response */
3466 rc = wait_for_completion_timeout
3467 (&context.completion,
3468 msecs_to_jiffies(WLAN_WAIT_TIME_STATS));
3469 if (!rc) {
Jeff Johnson99bac312016-06-28 10:38:18 -07003470 hdd_err("SME timed out while retrieving Class A statistics");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003471 }
3472 }
3473
3474 /* either we never sent a request, we sent a request and
3475 * received a response or we sent a request and timed out. if
3476 * we never sent a request or if we sent a request and got a
3477 * response, we want to clear the magic out of paranoia. if
3478 * we timed out there is a race condition such that the
3479 * callback function could be executing at the same time we
3480 * are. of primary concern is if the callback function had
3481 * already verified the "magic" but had not yet set the
3482 * completion variable when a timeout occurred. we serialize
3483 * these activities by invalidating the magic while holding a
3484 * shared spinlock which will cause us to block if the
3485 * callback is currently executing
3486 */
3487 spin_lock(&hdd_context_lock);
3488 context.magic = 0;
3489 spin_unlock(&hdd_context_lock);
3490
3491 /* either callback updated pAdapter stats or it has cached data */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303492 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003493}
3494
3495/**
3496 * hdd_get_station_statistics_cb() - Get stats callback function
3497 * @pStats: pointer to Class A stats
3498 * @pContext: user context originally registered with SME
3499 *
3500 * Return: None
3501 */
3502static void hdd_get_station_statistics_cb(void *pStats, void *pContext)
3503{
3504 struct statsContext *pStatsContext;
3505 tCsrSummaryStatsInfo *pSummaryStats;
3506 tCsrGlobalClassAStatsInfo *pClassAStats;
3507 hdd_adapter_t *pAdapter;
3508
3509 if (ioctl_debug) {
3510 pr_info("%s: pStats [%p] pContext [%p]\n",
3511 __func__, pStats, pContext);
3512 }
3513
3514 if ((NULL == pStats) || (NULL == pContext)) {
Jeff Johnson99bac312016-06-28 10:38:18 -07003515 hdd_err("Bad param, pStats [%p] pContext [%p]",
3516 pStats, pContext);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003517 return;
3518 }
3519
3520 /* there is a race condition that exists between this callback
3521 * function and the caller since the caller could time out
3522 * either before or while this code is executing. we use a
3523 * spinlock to serialize these actions
3524 */
3525 spin_lock(&hdd_context_lock);
3526
3527 pSummaryStats = (tCsrSummaryStatsInfo *) pStats;
3528 pClassAStats = (tCsrGlobalClassAStatsInfo *) (pSummaryStats + 1);
3529 pStatsContext = pContext;
3530 pAdapter = pStatsContext->pAdapter;
3531 if ((NULL == pAdapter) ||
3532 (STATS_CONTEXT_MAGIC != pStatsContext->magic)) {
3533 /* the caller presumably timed out so there is nothing
3534 * we can do
3535 */
3536 spin_unlock(&hdd_context_lock);
Jeff Johnson99bac312016-06-28 10:38:18 -07003537 hdd_warn("Invalid context, pAdapter [%p] magic [%08x]",
3538 pAdapter, pStatsContext->magic);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003539 if (ioctl_debug) {
3540 pr_info("%s: Invalid context, pAdapter [%p] magic [%08x]\n",
3541 __func__, pAdapter, pStatsContext->magic);
3542 }
3543 return;
3544 }
3545
3546 /* context is valid so caller is still waiting */
3547
3548 /* paranoia: invalidate the magic */
3549 pStatsContext->magic = 0;
3550
3551 /* copy over the stats. do so as a struct copy */
3552 pAdapter->hdd_stats.summary_stat = *pSummaryStats;
3553 pAdapter->hdd_stats.ClassA_stat = *pClassAStats;
3554
3555 /* notify the caller */
3556 complete(&pStatsContext->completion);
3557
3558 /* serialization is complete */
3559 spin_unlock(&hdd_context_lock);
3560}
3561
3562/**
3563 * wlan_hdd_get_station_stats() - Get station statistics
3564 * @pAdapter: adapter for which statistics are desired
3565 *
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303566 * Return: QDF_STATUS_SUCCESS if adapter's statistics were updated
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003567 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303568QDF_STATUS wlan_hdd_get_station_stats(hdd_adapter_t *pAdapter)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003569{
3570 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303571 QDF_STATUS hstatus;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003572 unsigned long rc;
3573 struct statsContext context;
3574
3575 if (NULL == pAdapter) {
Jeff Johnson99bac312016-06-28 10:38:18 -07003576 hdd_err("pAdapter is NULL");
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303577 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003578 }
3579
3580 /* we are connected so prepare our callback context */
3581 init_completion(&context.completion);
3582 context.pAdapter = pAdapter;
3583 context.magic = STATS_CONTEXT_MAGIC;
3584
3585 /* query only for Summary & Class A statistics */
3586 hstatus = sme_get_statistics(WLAN_HDD_GET_HAL_CTX(pAdapter),
3587 eCSR_HDD,
3588 SME_SUMMARY_STATS |
3589 SME_GLOBAL_CLASSA_STATS,
3590 hdd_get_station_statistics_cb,
3591 0, /* not periodic */
3592 false, /* non-cached results */
3593 pHddStaCtx->conn_info.staId[0],
3594 &context, pAdapter->sessionId);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303595 if (QDF_STATUS_SUCCESS != hstatus) {
Jeff Johnson99bac312016-06-28 10:38:18 -07003596 hdd_err("Unable to retrieve statistics");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003597 /* we'll return with cached values */
3598 } else {
3599 /* request was sent -- wait for the response */
3600 rc = wait_for_completion_timeout
3601 (&context.completion,
3602 msecs_to_jiffies(WLAN_WAIT_TIME_STATS));
3603
3604 if (!rc) {
Jeff Johnson99bac312016-06-28 10:38:18 -07003605 hdd_err("SME timed out while retrieving statistics");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003606 }
3607 }
3608
3609 /* either we never sent a request, we sent a request and
3610 * received a response or we sent a request and timed out. if
3611 * we never sent a request or if we sent a request and got a
3612 * response, we want to clear the magic out of paranoia. if
3613 * we timed out there is a race condition such that the
3614 * callback function could be executing at the same time we
3615 * are. of primary concern is if the callback function had
3616 * already verified the "magic" but had not yet set the
3617 * completion variable when a timeout occurred. we serialize
3618 * these activities by invalidating the magic while holding a
3619 * shared spinlock which will cause us to block if the
3620 * callback is currently executing
3621 */
3622 spin_lock(&hdd_context_lock);
3623 context.magic = 0;
3624 spin_unlock(&hdd_context_lock);
3625
3626 /* either callback updated pAdapter stats or it has cached data */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303627 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003628}
3629
3630/**
3631 * iw_get_linkspeed() - Get current link speed ioctl
3632 * @dev: device upon which the ioctl was received
3633 * @info: ioctl request information
3634 * @wrqu: ioctl request data
3635 * @extra: extra ioctl buffer
3636 *
3637 * Return: 0 on success, non-zero on error
3638 */
3639static int __iw_get_linkspeed(struct net_device *dev,
3640 struct iw_request_info *info,
3641 union iwreq_data *wrqu, char *extra)
3642{
3643 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3644 char *pLinkSpeed = (char *)extra;
3645 int len = sizeof(uint32_t) + 1;
3646 uint32_t link_speed = 0;
3647 hdd_context_t *hdd_ctx;
3648 int rc, valid;
3649
Jeff Johnson6ee91ee2016-02-11 18:55:30 -08003650 ENTER_DEV(dev);
Hanumantha Reddy Pothula2db50ed2015-11-23 10:48:33 +05303651
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003652 hdd_ctx = WLAN_HDD_GET_CTX(pAdapter);
3653 valid = wlan_hdd_validate_context(hdd_ctx);
3654 if (0 != valid)
3655 return valid;
3656
3657 rc = wlan_hdd_get_link_speed(pAdapter, &link_speed);
3658 if (0 != rc) {
3659 return rc;
3660 }
3661
3662 wrqu->data.length = len;
3663 /* return the linkspeed as a string */
3664 rc = snprintf(pLinkSpeed, len, "%u", link_speed);
3665 if ((rc < 0) || (rc >= len)) {
3666 /* encoding or length error? */
Jeff Johnson99bac312016-06-28 10:38:18 -07003667 hdd_err("Unable to encode link speed");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003668 return -EIO;
3669 }
3670
Hanumantha Reddy Pothula2db50ed2015-11-23 10:48:33 +05303671 EXIT();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003672 /* a value is being successfully returned */
3673 return 0;
3674}
3675
3676static int iw_get_linkspeed(struct net_device *dev,
3677 struct iw_request_info *info,
3678 union iwreq_data *wrqu, char *extra)
3679{
3680 int ret;
3681
3682 cds_ssr_protect(__func__);
3683 ret = __iw_get_linkspeed(dev, info, wrqu, extra);
3684 cds_ssr_unprotect(__func__);
3685
3686 return ret;
3687}
3688
3689/**
3690 * wlan_hdd_change_country_code_callback() - Change country code callback
3691 * @context: opaque context originally passed to SME. All functions
3692 * which use this callback pass the adapter upon which the country
3693 * code change is active
3694 *
3695 * This function is registered as the callback function when
3696 * sme_change_country_code() is invoked. Callers of
3697 * sme_change_country_code() subsequently wait for the adapter's
3698 * @change_country_code completion variable, so all this function
3699 * needs to do is set that completion variable so that execution can
3700 * continue.
3701 *
3702 * Return: none
3703 */
3704void wlan_hdd_change_country_code_callback(void *context)
3705{
3706
3707 hdd_adapter_t *adapter = context;
3708
3709 if (adapter && (WLAN_HDD_ADAPTER_MAGIC == adapter->magic))
3710 complete(&adapter->change_country_code);
3711
3712 return;
3713}
3714
3715/**
3716 * __iw_set_nick() - SIOCSIWNICKN ioctl handler
3717 * @dev: device upon which the ioctl was received
3718 * @info: ioctl request information
3719 * @wrqu: ioctl request data
3720 * @extra: ioctl extra data
3721 *
3722 * Return: 0 on success, non-zero on error
3723 */
3724static int __iw_set_nick(struct net_device *dev,
3725 struct iw_request_info *info,
3726 union iwreq_data *wrqu, char *extra)
3727{
3728 hdd_adapter_t *adapter;
3729 hdd_context_t *hdd_ctx;
3730 int ret;
3731
Jeff Johnsonb25dcb12016-02-11 17:46:42 -08003732 ENTER_DEV(dev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003733
3734 adapter = WLAN_HDD_GET_PRIV_PTR(dev);
3735 hdd_ctx = WLAN_HDD_GET_CTX(adapter);
3736 ret = wlan_hdd_validate_context(hdd_ctx);
3737 if (0 != ret)
3738 return ret;
3739
3740 return 0;
3741}
3742
3743/**
3744 * iw_set_nick() - SSR wrapper for __iw_set_nick
3745 * @dev: pointer to net_device
3746 * @info: pointer to iw_request_info
3747 * @wrqu: pointer to iwreq_data
3748 * @extra: extra
3749 *
3750 * Return: 0 on success, error number otherwise
3751 */
3752static int iw_set_nick(struct net_device *dev,
3753 struct iw_request_info *info,
3754 union iwreq_data *wrqu, char *extra)
3755{
3756 int ret;
3757
3758 cds_ssr_protect(__func__);
3759 ret = __iw_set_nick(dev, info, wrqu, extra);
3760 cds_ssr_unprotect(__func__);
3761
3762 return ret;
3763}
3764
3765/**
3766 * __iw_get_nick() - SIOCGIWNICKN ioctl handler
3767 * @dev: device upon which the ioctl was received
3768 * @info: ioctl request information
3769 * @wrqu: ioctl request data
3770 * @extra: ioctl extra data
3771 *
3772 * Return: 0 on success, non-zero on error
3773 */
3774static int __iw_get_nick(struct net_device *dev,
3775 struct iw_request_info *info,
3776 union iwreq_data *wrqu, char *extra)
3777{
3778 hdd_adapter_t *adapter;
3779 hdd_context_t *hdd_ctx;
3780 int ret;
3781
Jeff Johnsonb25dcb12016-02-11 17:46:42 -08003782 ENTER_DEV(dev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003783
3784 adapter = WLAN_HDD_GET_PRIV_PTR(dev);
3785 hdd_ctx = WLAN_HDD_GET_CTX(adapter);
3786 ret = wlan_hdd_validate_context(hdd_ctx);
3787 if (0 != ret)
3788 return ret;
3789
3790 return 0;
3791}
3792
3793/**
3794 * iw_get_nick() - SSR wrapper for __iw_get_nick
3795 * @dev: pointer to net_device
3796 * @info: pointer to iw_request_info
3797 * @wrqu: pointer to iwreq_data
3798 * @extra: extra
3799 *
3800 * Return: 0 on success, error number otherwise
3801 */
3802static int iw_get_nick(struct net_device *dev,
3803 struct iw_request_info *info,
3804 union iwreq_data *wrqu, char *extra)
3805{
3806 int ret;
3807
3808 cds_ssr_protect(__func__);
3809 ret = __iw_get_nick(dev, info, wrqu, extra);
3810 cds_ssr_unprotect(__func__);
3811
3812 return ret;
3813}
3814
3815/**
3816 * __iw_set_encode() - SIOCSIWENCODE ioctl handler
3817 * @dev: device upon which the ioctl was received
3818 * @info: ioctl request information
3819 * @wrqu: ioctl request data
3820 * @extra: ioctl extra data
3821 *
3822 * Return: 0 on success, non-zero on error
3823 */
3824static int __iw_set_encode(struct net_device *dev, struct iw_request_info *info,
3825 union iwreq_data *wrqu, char *extra)
3826{
3827 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3828 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
3829 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
3830 hdd_context_t *hdd_ctx;
3831 struct iw_point *encoderq = &(wrqu->encoding);
3832 uint32_t keyId;
3833 uint8_t key_length;
3834 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
3835 bool fKeyPresent = 0;
3836 int i;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303837 QDF_STATUS status = QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003838 int ret;
3839
Jeff Johnsonb25dcb12016-02-11 17:46:42 -08003840 ENTER_DEV(dev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003841
3842 hdd_ctx = WLAN_HDD_GET_CTX(pAdapter);
3843 ret = wlan_hdd_validate_context(hdd_ctx);
3844 if (0 != ret)
3845 return ret;
3846
3847 keyId = encoderq->flags & IW_ENCODE_INDEX;
3848
3849 if (keyId) {
3850 if (keyId > MAX_WEP_KEYS) {
3851 return -EINVAL;
3852 }
3853
3854 fKeyPresent = 1;
3855 keyId--;
3856 } else {
3857 fKeyPresent = 0;
3858 }
3859
3860 if (wrqu->data.flags & IW_ENCODE_DISABLED) {
Jeff Johnson99bac312016-06-28 10:38:18 -07003861 hdd_notice("****iwconfig wlan0 key off*****");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003862 if (!fKeyPresent) {
3863
3864 for (i = 0; i < CSR_MAX_NUM_KEY; i++) {
3865
3866 if (pWextState->roamProfile.Keys.KeyMaterial[i])
3867 pWextState->roamProfile.Keys.
3868 KeyLength[i] = 0;
3869 }
3870 }
3871 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_OPEN_SYSTEM;
3872 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
3873 pWextState->roamProfile.EncryptionType.encryptionType[0] =
3874 eCSR_ENCRYPT_TYPE_NONE;
3875 pWextState->roamProfile.mcEncryptionType.encryptionType[0] =
3876 eCSR_ENCRYPT_TYPE_NONE;
3877
3878 pHddStaCtx->conn_info.ucEncryptionType = eCSR_ENCRYPT_TYPE_NONE;
3879 pHddStaCtx->conn_info.mcEncryptionType = eCSR_ENCRYPT_TYPE_NONE;
3880
3881 if (eConnectionState_Associated ==
3882 pHddStaCtx->conn_info.connState) {
3883 INIT_COMPLETION(pAdapter->disconnect_comp_var);
3884 status =
3885 sme_roam_disconnect(WLAN_HDD_GET_HAL_CTX(pAdapter),
3886 pAdapter->sessionId,
3887 eCSR_DISCONNECT_REASON_UNSPECIFIED);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303888 if (QDF_STATUS_SUCCESS == status) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003889 unsigned long rc;
3890 rc = wait_for_completion_timeout(&pAdapter->
3891 disconnect_comp_var,
3892 msecs_to_jiffies
3893 (WLAN_WAIT_TIME_DISCONNECT));
3894 if (!rc)
Jeff Johnson99bac312016-06-28 10:38:18 -07003895 hdd_err("failed wait on disconnect_comp_var");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003896 }
3897 }
3898
3899 return status;
3900
3901 }
3902
3903 if (wrqu->data.flags & (IW_ENCODE_OPEN | IW_ENCODE_RESTRICTED)) {
Jeff Johnson99bac312016-06-28 10:38:18 -07003904 hdd_notice("iwconfig wlan0 key on");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003905
3906 pHddStaCtx->conn_info.authType =
3907 (encoderq->
3908 flags & IW_ENCODE_RESTRICTED) ? eCSR_AUTH_TYPE_SHARED_KEY :
3909 eCSR_AUTH_TYPE_OPEN_SYSTEM;
3910
3911 }
3912
3913 if (wrqu->data.length > 0) {
Jeff Johnson99bac312016-06-28 10:38:18 -07003914 hdd_notice("wrqu->data.length : %d", wrqu->data.length);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003915
3916 key_length = wrqu->data.length;
3917
3918 /* IW_ENCODING_TOKEN_MAX is the value that is set for wrqu->data.length by iwconfig.c when 'iwconfig wlan0 key on' is issued. */
3919
3920 if (5 == key_length) {
Jeff Johnson99bac312016-06-28 10:38:18 -07003921 hdd_notice("Call with WEP40,key_len=%d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003922 key_length);
3923
3924 if ((IW_AUTH_KEY_MGMT_802_1X == pWextState->authKeyMgmt)
3925 && (eCSR_AUTH_TYPE_OPEN_SYSTEM ==
3926 pHddStaCtx->conn_info.authType)) {
3927 encryptionType = eCSR_ENCRYPT_TYPE_WEP40;
3928 } else {
3929 encryptionType =
3930 eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
3931 }
3932 } else if (13 == key_length) {
Jeff Johnson99bac312016-06-28 10:38:18 -07003933 hdd_notice("Call with WEP104,key_len:%d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003934 key_length);
3935
3936 if ((IW_AUTH_KEY_MGMT_802_1X == pWextState->authKeyMgmt)
3937 && (eCSR_AUTH_TYPE_OPEN_SYSTEM ==
3938 pHddStaCtx->conn_info.authType)) {
3939 encryptionType = eCSR_ENCRYPT_TYPE_WEP104;
3940 } else {
3941 encryptionType =
3942 eCSR_ENCRYPT_TYPE_WEP104_STATICKEY;
3943 }
3944 } else {
Jeff Johnson99bac312016-06-28 10:38:18 -07003945 hdd_warn("Invalid WEP key length :%d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003946 key_length);
3947 return -EINVAL;
3948 }
3949
3950 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
3951 pHddStaCtx->conn_info.mcEncryptionType = encryptionType;
3952 pWextState->roamProfile.EncryptionType.numEntries = 1;
3953 pWextState->roamProfile.EncryptionType.encryptionType[0] =
3954 encryptionType;
3955 pWextState->roamProfile.mcEncryptionType.numEntries = 1;
3956 pWextState->roamProfile.mcEncryptionType.encryptionType[0] =
3957 encryptionType;
3958
3959 if ((eConnectionState_NotConnected ==
3960 pHddStaCtx->conn_info.connState)
3961 &&
3962 ((eCSR_AUTH_TYPE_OPEN_SYSTEM ==
3963 pHddStaCtx->conn_info.authType)
3964 || (eCSR_AUTH_TYPE_SHARED_KEY ==
3965 pHddStaCtx->conn_info.authType))) {
3966
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303967 qdf_mem_copy(&pWextState->roamProfile.Keys.
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003968 KeyMaterial[keyId][0], extra, key_length);
3969
3970 pWextState->roamProfile.Keys.KeyLength[keyId] =
3971 (uint8_t) key_length;
3972 pWextState->roamProfile.Keys.defaultIndex =
3973 (uint8_t) keyId;
3974
3975 return status;
3976 }
3977 }
3978
3979 return 0;
3980}
3981
3982/**
3983 * iw_set_encode() - SSR wrapper for __iw_set_encode()
3984 * @dev: pointer to net_device
3985 * @info: pointer to iw_request_info
3986 * @wrqu: pointer to iwreq_data
3987 * @extra: pointer to extra ioctl payload
3988 *
3989 * Return: 0 on success, error number otherwise
3990 */
3991static int iw_set_encode(struct net_device *dev, struct iw_request_info *info,
3992 union iwreq_data *wrqu, char *extra)
3993{
3994 int ret;
3995
3996 cds_ssr_protect(__func__);
3997 ret = __iw_set_encode(dev, info, wrqu, extra);
3998 cds_ssr_unprotect(__func__);
3999
4000 return ret;
4001}
4002
4003/**
4004 * __iw_get_encodeext() - SIOCGIWENCODEEXT ioctl handler
4005 * @dev: device upon which the ioctl was received
4006 * @info: ioctl request information
4007 * @wrqu: ioctl request data
4008 * @extra: ioctl extra data
4009 *
4010 * Return: 0 on success, non-zero on error
4011 */
4012static int __iw_get_encodeext(struct net_device *dev,
4013 struct iw_request_info *info,
4014 struct iw_point *dwrq, char *extra)
4015{
4016 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4017 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
4018 tCsrRoamProfile *pRoamProfile = &(pWextState->roamProfile);
4019 int keyId;
4020 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
4021 eCsrAuthType authType = eCSR_AUTH_TYPE_NONE;
4022 int i, ret;
4023 hdd_context_t *hdd_ctx;
4024
Jeff Johnsonb25dcb12016-02-11 17:46:42 -08004025 ENTER_DEV(dev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004026
4027 hdd_ctx = WLAN_HDD_GET_CTX(pAdapter);
4028 ret = wlan_hdd_validate_context(hdd_ctx);
4029 if (0 != ret)
4030 return ret;
4031
4032 keyId = pRoamProfile->Keys.defaultIndex;
4033
4034 if (keyId < 0 || keyId >= MAX_WEP_KEYS) {
Jeff Johnson99bac312016-06-28 10:38:18 -07004035 hdd_notice("Invalid keyId : %d", keyId);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004036 return -EINVAL;
4037 }
4038
4039 if (pRoamProfile->Keys.KeyLength[keyId] > 0) {
4040 dwrq->flags |= IW_ENCODE_ENABLED;
4041 dwrq->length = pRoamProfile->Keys.KeyLength[keyId];
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304042 qdf_mem_copy(extra, &(pRoamProfile->Keys.KeyMaterial[keyId][0]),
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004043 pRoamProfile->Keys.KeyLength[keyId]);
4044 } else {
4045 dwrq->flags |= IW_ENCODE_DISABLED;
4046 }
4047
4048 for (i = 0; i < MAX_WEP_KEYS; i++) {
4049 if (pRoamProfile->Keys.KeyMaterial[i] == NULL) {
4050 continue;
4051 } else {
4052 break;
4053 }
4054 }
4055
4056 if (MAX_WEP_KEYS == i) {
4057 dwrq->flags |= IW_ENCODE_NOKEY;
4058 } else {
4059 dwrq->flags |= IW_ENCODE_ENABLED;
4060 }
4061
4062 encryptionType = pRoamProfile->EncryptionType.encryptionType[0];
4063
4064 if (eCSR_ENCRYPT_TYPE_NONE == encryptionType) {
4065 dwrq->flags |= IW_ENCODE_DISABLED;
4066 }
4067
4068 authType = (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.authType;
4069
4070 if (IW_AUTH_ALG_OPEN_SYSTEM == authType) {
4071 dwrq->flags |= IW_ENCODE_OPEN;
4072 } else {
4073 dwrq->flags |= IW_ENCODE_RESTRICTED;
4074 }
4075 EXIT();
4076 return 0;
4077
4078}
4079
4080/**
4081 * iw_get_encodeext() - SSR wrapper for __iw_get_encodeext()
4082 * @dev: pointer to net_device
4083 * @info: pointer to iw_request_info
4084 * @dwrq: pointer to encoding information
4085 * @extra: pointer to extra ioctl payload
4086 *
4087 * Return: 0 on success, error number otherwise
4088 */
4089static int iw_get_encodeext(struct net_device *dev,
4090 struct iw_request_info *info,
4091 struct iw_point *dwrq, char *extra)
4092{
4093 int ret;
4094
4095 cds_ssr_protect(__func__);
4096 ret = __iw_get_encodeext(dev, info, dwrq, extra);
4097 cds_ssr_unprotect(__func__);
4098
4099 return ret;
4100}
4101
4102/**
4103 * __iw_set_encodeext() - SIOCSIWENCODEEXT ioctl handler
4104 * @dev: device upon which the ioctl was received
4105 * @info: ioctl request information
4106 * @wrqu: ioctl request data
4107 * @extra: ioctl extra data
4108 *
4109 * Return: 0 on success, non-zero on error
4110 */
4111static int __iw_set_encodeext(struct net_device *dev,
4112 struct iw_request_info *info,
4113 union iwreq_data *wrqu, char *extra)
4114{
4115 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4116 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4117 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
4118 hdd_context_t *hdd_ctx;
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05304119 QDF_STATUS qdf_ret_status = QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004120 tCsrRoamProfile *pRoamProfile = &pWextState->roamProfile;
4121 int ret;
4122 struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
4123 int key_index;
4124 struct iw_point *encoding = &wrqu->encoding;
4125 tCsrRoamSetKey setKey;
4126 uint32_t roamId = 0xFF;
4127
Jeff Johnsonb25dcb12016-02-11 17:46:42 -08004128 ENTER_DEV(dev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004129
4130 hdd_ctx = WLAN_HDD_GET_CTX(pAdapter);
4131 ret = wlan_hdd_validate_context(hdd_ctx);
4132 if (0 != ret)
4133 return ret;
4134
4135 key_index = encoding->flags & IW_ENCODE_INDEX;
4136
4137 if (key_index > 0) {
4138
4139 /*Convert from 1-based to 0-based keying */
4140 key_index--;
4141 }
4142 if (!ext->key_len) {
4143
4144 /*Set the encrytion type to NONE */
4145 pRoamProfile->EncryptionType.encryptionType[0] =
4146 eCSR_ENCRYPT_TYPE_NONE;
4147 return ret;
4148 }
4149
4150 if (eConnectionState_NotConnected == pHddStaCtx->conn_info.connState &&
4151 (IW_ENCODE_ALG_WEP == ext->alg)) {
4152 if (IW_AUTH_KEY_MGMT_802_1X == pWextState->authKeyMgmt) {
4153
Jeff Johnson99bac312016-06-28 10:38:18 -07004154 hdd_err("Invalid Configuration");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004155 return -EINVAL;
4156 } else {
4157 /*Static wep, update the roam profile with the keys */
4158 if (ext->key
4159 && (ext->key_len <=
4160 eCSR_SECURITY_WEP_KEYSIZE_MAX_BYTES)
4161 && key_index < CSR_MAX_NUM_KEY) {
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304162 qdf_mem_copy(&pRoamProfile->Keys.
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004163 KeyMaterial[key_index][0],
4164 ext->key, ext->key_len);
4165 pRoamProfile->Keys.KeyLength[key_index] =
4166 (uint8_t) ext->key_len;
4167
4168 if (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY)
4169 pRoamProfile->Keys.defaultIndex =
4170 (uint8_t) key_index;
4171
4172 }
4173 }
4174 return ret;
4175 }
4176
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304177 qdf_mem_zero(&setKey, sizeof(tCsrRoamSetKey));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004178
4179 setKey.keyId = key_index;
4180 setKey.keyLength = ext->key_len;
4181
4182 if (ext->key_len <= CSR_MAX_KEY_LEN) {
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304183 qdf_mem_copy(&setKey.Key[0], ext->key, ext->key_len);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004184 }
4185
4186 if (ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY) {
4187 /*Key direction for group is RX only */
4188 setKey.keyDirection = eSIR_RX_ONLY;
Anurag Chouhanc5548422016-02-24 18:33:27 +05304189 qdf_set_macaddr_broadcast(&setKey.peerMac);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004190 } else {
4191
4192 setKey.keyDirection = eSIR_TX_RX;
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304193 qdf_mem_copy(setKey.peerMac.bytes, ext->addr.sa_data,
Anurag Chouhan6d760662016-02-20 16:05:43 +05304194 QDF_MAC_ADDR_SIZE);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004195 }
4196
4197 /*For supplicant pae role is zero */
4198 setKey.paeRole = 0;
4199
4200 switch (ext->alg) {
4201 case IW_ENCODE_ALG_NONE:
4202 setKey.encType = eCSR_ENCRYPT_TYPE_NONE;
4203 break;
4204
4205 case IW_ENCODE_ALG_WEP:
4206 setKey.encType =
4207 (ext->key_len ==
4208 5) ? eCSR_ENCRYPT_TYPE_WEP40 : eCSR_ENCRYPT_TYPE_WEP104;
4209 break;
4210
4211 case IW_ENCODE_ALG_TKIP:
4212 {
4213 uint8_t *pKey = &setKey.Key[0];
4214
4215 setKey.encType = eCSR_ENCRYPT_TYPE_TKIP;
4216
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304217 qdf_mem_zero(pKey, CSR_MAX_KEY_LEN);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004218
4219 /* Supplicant sends the 32bytes key in this order
4220 * |--------------|----------|----------|
4221 * | Tk1 | TX MIC | RX MIC |
4222 * |--------------|----------|----------|
4223 * <---16bytes---><--8bytes--><--8bytes-->
4224 *
4225 *
4226 * Sme expects the 32 bytes key to be in the below order
4227 * |--------------|----------|----------|
4228 * | Tk1 | RX MIC | TX MIC |
4229 * |--------------|----------|----------|
4230 * <---16bytes---><--8bytes--><--8bytes-->
4231 */
4232
4233 /* Copy the Temporal Key 1 (TK1) */
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304234 qdf_mem_copy(pKey, ext->key, 16);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004235
4236 /* Copy the rx mic first */
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304237 qdf_mem_copy(&pKey[16], &ext->key[24], 8);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004238
4239 /* Copy the tx mic */
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304240 qdf_mem_copy(&pKey[24], &ext->key[16], 8);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004241
4242 }
4243 break;
4244
4245 case IW_ENCODE_ALG_CCMP:
4246 setKey.encType = eCSR_ENCRYPT_TYPE_AES;
4247 break;
4248
4249#ifdef FEATURE_WLAN_ESE
4250#define IW_ENCODE_ALG_KRK 6
4251 case IW_ENCODE_ALG_KRK:
4252 setKey.encType = eCSR_ENCRYPT_TYPE_KRK;
4253 break;
4254#endif /* FEATURE_WLAN_ESE */
4255
4256 default:
4257 setKey.encType = eCSR_ENCRYPT_TYPE_NONE;
4258 break;
4259 }
4260
Jeff Johnson99bac312016-06-28 10:38:18 -07004261 hdd_notice("cipher_alg:%d key_len:%d EncryptionType:%d",
4262 (int)ext->alg, (int)ext->key_len, setKey.encType);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004263
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004264 /* The supplicant may attempt to set the PTK once
4265 * pre-authentication is done. Save the key in the UMAC and
4266 * include it in the ADD BSS request
4267 */
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05304268 qdf_ret_status = sme_ft_update_key(WLAN_HDD_GET_HAL_CTX(pAdapter),
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004269 pAdapter->sessionId, &setKey);
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05304270 if (qdf_ret_status == QDF_STATUS_FT_PREAUTH_KEY_SUCCESS) {
Jeff Johnson99bac312016-06-28 10:38:18 -07004271 hdd_info("Update PreAuth Key success");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004272 return 0;
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05304273 } else if (qdf_ret_status == QDF_STATUS_FT_PREAUTH_KEY_FAILED) {
Jeff Johnson99bac312016-06-28 10:38:18 -07004274 hdd_err("Update PreAuth Key failed");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004275 return -EINVAL;
4276 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004277
4278 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
4279
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05304280 qdf_ret_status = sme_roam_set_key(WLAN_HDD_GET_HAL_CTX(pAdapter),
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004281 pAdapter->sessionId,
4282 &setKey, &roamId);
4283
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05304284 if (qdf_ret_status != QDF_STATUS_SUCCESS) {
Jeff Johnson99bac312016-06-28 10:38:18 -07004285 hdd_err("[%4d] sme_roam_set_key returned ERROR status= %d",
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05304286 __LINE__, qdf_ret_status);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004287
4288 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
4289 }
4290
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05304291 return qdf_ret_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004292}
4293
4294/**
4295 * iw_set_encodeext() - SSR wrapper for __iw_set_encodeext()
4296 * @dev: pointer to net_device
4297 * @info: pointer to iw_request_info
4298 * @wrqu: pointer to iwreq_data
4299 * @extra: pointer to extra ioctl payload
4300 *
4301 * Return: 0 on success, error number otherwise
4302 */
4303static int iw_set_encodeext(struct net_device *dev,
4304 struct iw_request_info *info,
4305 union iwreq_data *wrqu, char *extra)
4306{
4307 int ret;
4308
4309 cds_ssr_protect(__func__);
4310 ret = __iw_set_encodeext(dev, info, wrqu, extra);
4311 cds_ssr_unprotect(__func__);
4312
4313 return ret;
4314}
4315
4316/**
4317 * __iw_set_retry() - SIOCSIWRETRY ioctl handler
4318 * @dev: device upon which the ioctl was received
4319 * @info: ioctl request information
4320 * @wrqu: ioctl request data
4321 * @extra: ioctl extra data
4322 *
4323 * Return: 0 on success, non-zero on error
4324 */
4325static int __iw_set_retry(struct net_device *dev, struct iw_request_info *info,
4326 union iwreq_data *wrqu, char *extra)
4327{
4328 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4329 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
4330 hdd_context_t *hdd_ctx;
4331 int ret;
4332
Jeff Johnsonb25dcb12016-02-11 17:46:42 -08004333 ENTER_DEV(dev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004334
4335 hdd_ctx = WLAN_HDD_GET_CTX(pAdapter);
4336 ret = wlan_hdd_validate_context(hdd_ctx);
4337 if (0 != ret)
4338 return ret;
4339
4340 if (wrqu->retry.value < WNI_CFG_LONG_RETRY_LIMIT_STAMIN ||
4341 wrqu->retry.value > WNI_CFG_LONG_RETRY_LIMIT_STAMAX) {
4342
Jeff Johnson99bac312016-06-28 10:38:18 -07004343 hdd_err("Invalid Retry-Limit=%d!!", wrqu->retry.value);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004344
4345 return -EINVAL;
4346 }
4347
4348 if (wrqu->retry.flags & IW_RETRY_LIMIT) {
4349
4350 if ((wrqu->retry.flags & IW_RETRY_LONG)) {
4351 if (sme_cfg_set_int (hHal, WNI_CFG_LONG_RETRY_LIMIT,
4352 wrqu->retry.value) !=
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304353 QDF_STATUS_SUCCESS) {
Jeff Johnson99bac312016-06-28 10:38:18 -07004354 hdd_err("failed to set ini parameter, WNI_CFG_LONG_RETRY_LIMIT");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004355 return -EIO;
4356 }
4357 } else if ((wrqu->retry.flags & IW_RETRY_SHORT)) {
4358 if (sme_cfg_set_int (hHal, WNI_CFG_SHORT_RETRY_LIMIT,
4359 wrqu->retry.value) !=
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304360 QDF_STATUS_SUCCESS) {
Jeff Johnson99bac312016-06-28 10:38:18 -07004361 hdd_err("failed to set ini parameter, WNI_CFG_LONG_RETRY_LIMIT");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004362 return -EIO;
4363 }
4364 }
4365 } else {
4366 return -EOPNOTSUPP;
4367 }
4368
Jeff Johnson99bac312016-06-28 10:38:18 -07004369 hdd_notice("Set Retry-Limit=%d!!", wrqu->retry.value);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004370
4371 EXIT();
4372
4373 return 0;
4374
4375}
4376
4377/**
4378 * iw_set_retry() - SSR wrapper for __iw_set_retry()
4379 * @dev: pointer to net_device
4380 * @info: pointer to iw_request_info
4381 * @wrqu: pointer to iwreq_data
4382 * @extra: pointer to extra ioctl payload
4383 *
4384 * Return: 0 on success, error number otherwise
4385 */
4386static int iw_set_retry(struct net_device *dev, struct iw_request_info *info,
4387 union iwreq_data *wrqu, char *extra)
4388{
4389 int ret;
4390
4391 cds_ssr_protect(__func__);
4392 ret = __iw_set_retry(dev, info, wrqu, extra);
4393 cds_ssr_unprotect(__func__);
4394
4395 return ret;
4396}
4397
4398/**
4399 * __iw_get_retry() - SIOCGIWRETRY ioctl handler
4400 * @dev: device upon which the ioctl was received
4401 * @info: ioctl request information
4402 * @wrqu: ioctl request data
4403 * @extra: ioctl extra data
4404 *
4405 * Return: 0 on success, non-zero on error
4406 */
4407static int __iw_get_retry(struct net_device *dev, struct iw_request_info *info,
4408 union iwreq_data *wrqu, char *extra)
4409{
4410 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4411 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
4412 uint32_t retry = 0;
4413 hdd_context_t *hdd_ctx;
4414 int ret;
4415
Jeff Johnsonb25dcb12016-02-11 17:46:42 -08004416 ENTER_DEV(dev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004417
4418 hdd_ctx = WLAN_HDD_GET_CTX(pAdapter);
4419 ret = wlan_hdd_validate_context(hdd_ctx);
4420 if (0 != ret)
4421 return ret;
4422
4423 if ((wrqu->retry.flags & IW_RETRY_LONG)) {
4424 wrqu->retry.flags = IW_RETRY_LIMIT | IW_RETRY_LONG;
4425
4426 if (sme_cfg_get_int(hHal, WNI_CFG_LONG_RETRY_LIMIT, &retry) !=
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304427 QDF_STATUS_SUCCESS) {
Jeff Johnson99bac312016-06-28 10:38:18 -07004428 hdd_warn("failed to get ini parameter, WNI_CFG_LONG_RETRY_LIMIT");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004429 return -EIO;
4430 }
4431
4432 wrqu->retry.value = retry;
4433 } else if ((wrqu->retry.flags & IW_RETRY_SHORT)) {
4434 wrqu->retry.flags = IW_RETRY_LIMIT | IW_RETRY_SHORT;
4435
4436 if (sme_cfg_get_int(hHal, WNI_CFG_SHORT_RETRY_LIMIT, &retry) !=
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304437 QDF_STATUS_SUCCESS) {
Jeff Johnson99bac312016-06-28 10:38:18 -07004438 hdd_warn("failed to get ini parameter, WNI_CFG_LONG_RETRY_LIMIT");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004439 return -EIO;
4440 }
4441
4442 wrqu->retry.value = retry;
4443 } else {
4444 return -EOPNOTSUPP;
4445 }
4446
Jeff Johnson99bac312016-06-28 10:38:18 -07004447 hdd_notice("Retry-Limit=%d!!", retry);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004448
4449 EXIT();
4450
4451 return 0;
4452}
4453
4454/**
4455 * iw_get_retry() - SSR wrapper for __iw_get_retry()
4456 * @dev: pointer to net_device
4457 * @info: pointer to iw_request_info
4458 * @wrqu: pointer to iwreq_data
4459 * @extra: pointer to extra ioctl payload
4460 *
4461 * Return: 0 on success, error number otherwise
4462 */
4463static int iw_get_retry(struct net_device *dev, struct iw_request_info *info,
4464 union iwreq_data *wrqu, char *extra)
4465{
4466 int ret;
4467
4468 cds_ssr_protect(__func__);
4469 ret = __iw_get_retry(dev, info, wrqu, extra);
4470 cds_ssr_unprotect(__func__);
4471
4472 return ret;
4473}
4474
4475/**
4476 * __iw_set_mlme() - SIOCSIWMLME ioctl handler
4477 * @dev: device upon which the ioctl was received
4478 * @info: ioctl request information
4479 * @wrqu: ioctl request data
4480 * @extra: ioctl extra data
4481 *
4482 * Return: 0 on success, non-zero on error
4483 */
4484static int __iw_set_mlme(struct net_device *dev,
4485 struct iw_request_info *info,
4486 union iwreq_data *wrqu, char *extra)
4487{
4488 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4489 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4490 struct iw_mlme *mlme = (struct iw_mlme *)extra;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304491 QDF_STATUS status = QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004492 hdd_context_t *hdd_ctx;
4493 int ret;
4494
Jeff Johnsonb25dcb12016-02-11 17:46:42 -08004495 ENTER_DEV(dev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004496
4497 hdd_ctx = WLAN_HDD_GET_CTX(pAdapter);
4498 ret = wlan_hdd_validate_context(hdd_ctx);
4499 if (0 != ret)
4500 return ret;
4501
4502 /* reason_code is unused. By default it is set to
4503 * eCSR_DISCONNECT_REASON_UNSPECIFIED
4504 */
4505 switch (mlme->cmd) {
4506 case IW_MLME_DISASSOC:
4507 case IW_MLME_DEAUTH:
4508
4509 if (pHddStaCtx->conn_info.connState ==
4510 eConnectionState_Associated) {
4511 eCsrRoamDisconnectReason reason =
4512 eCSR_DISCONNECT_REASON_UNSPECIFIED;
4513
4514 if (mlme->reason_code == HDD_REASON_MICHAEL_MIC_FAILURE)
4515 reason = eCSR_DISCONNECT_REASON_MIC_ERROR;
4516
4517 INIT_COMPLETION(pAdapter->disconnect_comp_var);
4518 status =
4519 sme_roam_disconnect(WLAN_HDD_GET_HAL_CTX(pAdapter),
4520 pAdapter->sessionId, reason);
4521
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304522 if (QDF_STATUS_SUCCESS == status) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004523 unsigned long rc;
4524 rc = wait_for_completion_timeout(&pAdapter->
4525 disconnect_comp_var,
4526 msecs_to_jiffies
4527 (WLAN_WAIT_TIME_DISCONNECT));
4528 if (!rc)
Jeff Johnson99bac312016-06-28 10:38:18 -07004529 hdd_err("failed wait on disconnect_comp_var");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004530 } else
Jeff Johnson99bac312016-06-28 10:38:18 -07004531 hdd_err("%d Command Disassociate/Deauthenticate : csr_roam_disconnect failure returned %d",
4532 (int)mlme->cmd, (int)status);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004533
4534 /* Resetting authKeyMgmt */
4535 (WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter))->authKeyMgmt =
4536 0;
4537
Jeff Johnson99bac312016-06-28 10:38:18 -07004538 hdd_notice("Disabling queues");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004539 wlan_hdd_netif_queue_control(pAdapter,
4540 WLAN_NETIF_TX_DISABLE_N_CARRIER,
4541 WLAN_CONTROL_PATH);
4542
4543 } else {
Jeff Johnson99bac312016-06-28 10:38:18 -07004544 hdd_err("%d Command Disassociate/Deauthenticate called but station is not in associated state",
4545 (int)mlme->cmd);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004546 }
4547 break;
4548 default:
Jeff Johnson99bac312016-06-28 10:38:18 -07004549 hdd_err("%d Command should be Disassociate/Deauthenticate",
4550 (int)mlme->cmd);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004551 return -EINVAL;
4552 } /* end of switch */
4553
4554 EXIT();
4555
4556 return status;
4557
4558}
4559
4560/**
4561 * iw_set_mlme() - SSR wrapper for __iw_set_mlme()
4562 * @dev: pointer to net_device
4563 * @info: pointer to iw_request_info
4564 * @wrqu: pointer to iwreq_data
4565 * @extra: pointer to extra ioctl payload
4566 *
4567 * Return: 0 on success, error number otherwise
4568 */
4569static int iw_set_mlme(struct net_device *dev, struct iw_request_info *info,
4570 union iwreq_data *wrqu, char *extra)
4571{
4572 int ret;
4573
4574 cds_ssr_protect(__func__);
4575 ret = __iw_set_mlme(dev, info, wrqu, extra);
4576 cds_ssr_unprotect(__func__);
4577
4578 return ret;
4579}
4580
4581/**
4582 * wlan_hdd_update_phymode() - handle change in PHY mode
4583 * @net: device upon which PHY mode change was received
4584 * @hal: umac handle for the driver
4585 * @new_phymode: new PHY mode for the device
4586 * @phddctx: pointer to the HDD context
4587 *
4588 * This function is called when the device is set to a new PHY mode.
4589 * It takes a holistic look at the desired PHY mode along with the
4590 * configured capabilities of the driver and the reported capabilities
4591 * of the hardware in order to correctly configure all PHY-related
4592 * parameters.
4593 *
4594 * Return: 0 on success, negative errno value on error
4595 */
4596int wlan_hdd_update_phymode(struct net_device *net, tHalHandle hal,
4597 int new_phymode, hdd_context_t *phddctx)
4598{
4599#ifdef QCA_HT_2040_COEX
4600 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(net);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304601 QDF_STATUS halStatus = QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004602#endif
4603 bool band_24 = false, band_5g = false;
4604 bool ch_bond24 = false, ch_bond5g = false;
4605 tSmeConfigParams smeconfig;
4606 uint32_t chwidth = WNI_CFG_CHANNEL_BONDING_MODE_DISABLE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004607 uint32_t vhtchanwidth;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004608 eCsrPhyMode phymode = -EIO, old_phymode;
4609 eHddDot11Mode hdd_dot11mode = phddctx->config->dot11Mode;
4610 eCsrBand curr_band = eCSR_BAND_ALL;
4611
4612 old_phymode = sme_get_phy_mode(hal);
4613
4614 if (WNI_CFG_CHANNEL_BONDING_MODE_DISABLE !=
4615 sme_get_cb_phy_state_from_cb_ini_value(phddctx->config->
4616 nChannelBondingMode24GHz))
4617 ch_bond24 = true;
4618
4619 if (WNI_CFG_CHANNEL_BONDING_MODE_DISABLE !=
4620 sme_get_cb_phy_state_from_cb_ini_value(phddctx->config->
4621 nChannelBondingMode5GHz))
4622 ch_bond5g = true;
4623
4624 if (phddctx->config->nBandCapability == eCSR_BAND_ALL) {
4625 band_24 = band_5g = true;
4626 } else if (phddctx->config->nBandCapability == eCSR_BAND_24) {
4627 band_24 = true;
4628 } else if (phddctx->config->nBandCapability == eCSR_BAND_5G) {
4629 band_5g = true;
4630 }
4631
4632 vhtchanwidth = phddctx->config->vhtChannelWidth;
Jeff Johnson99bac312016-06-28 10:38:18 -07004633 hdd_warn("ch_bond24=%d ch_bond5g=%d band_24=%d band_5g=%d VHT_ch_width=%u",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004634 ch_bond24, ch_bond5g, band_24, band_5g, vhtchanwidth);
4635
4636 switch (new_phymode) {
4637 case IEEE80211_MODE_AUTO:
4638 sme_set_phy_mode(hal, eCSR_DOT11_MODE_AUTO);
4639 if (hdd_set_band(net, WLAN_HDD_UI_BAND_AUTO) == 0) {
4640 phymode = eCSR_DOT11_MODE_AUTO;
4641 hdd_dot11mode = eHDD_DOT11_MODE_AUTO;
4642 chwidth = WNI_CFG_CHANNEL_BONDING_MODE_ENABLE;
4643 curr_band = eCSR_BAND_ALL;
4644 vhtchanwidth = eHT_CHANNEL_WIDTH_80MHZ;
4645 } else {
4646 sme_set_phy_mode(hal, old_phymode);
4647 return -EIO;
4648 }
4649 break;
4650 case IEEE80211_MODE_11A:
4651 sme_set_phy_mode(hal, eCSR_DOT11_MODE_11a);
4652 if ((hdd_set_band(net, WLAN_HDD_UI_BAND_5_GHZ) == 0)) {
4653 phymode = eCSR_DOT11_MODE_11a;
4654 hdd_dot11mode = eHDD_DOT11_MODE_11a;
4655 chwidth = WNI_CFG_CHANNEL_BONDING_MODE_DISABLE;
4656 curr_band = eCSR_BAND_5G;
4657 } else {
4658 sme_set_phy_mode(hal, old_phymode);
4659 return -EIO;
4660 }
4661 break;
4662 case IEEE80211_MODE_11B:
4663 sme_set_phy_mode(hal, eCSR_DOT11_MODE_11b);
4664 if ((hdd_set_band(net, WLAN_HDD_UI_BAND_2_4_GHZ) == 0)) {
4665 phymode = eCSR_DOT11_MODE_11b;
4666 hdd_dot11mode = eHDD_DOT11_MODE_11b;
4667 chwidth = WNI_CFG_CHANNEL_BONDING_MODE_DISABLE;
4668 curr_band = eCSR_BAND_24;
4669 } else {
4670 sme_set_phy_mode(hal, old_phymode);
4671 return -EIO;
4672 }
4673 break;
4674 case IEEE80211_MODE_11G:
4675 sme_set_phy_mode(hal, eCSR_DOT11_MODE_11g);
4676 if ((hdd_set_band(net, WLAN_HDD_UI_BAND_2_4_GHZ) == 0)) {
4677 phymode = eCSR_DOT11_MODE_11g;
4678 hdd_dot11mode = eHDD_DOT11_MODE_11g;
4679 chwidth = WNI_CFG_CHANNEL_BONDING_MODE_DISABLE;
4680 curr_band = eCSR_BAND_24;
4681 } else {
4682 sme_set_phy_mode(hal, old_phymode);
4683 return -EIO;
4684 }
4685 break;
4686 /* UMAC doesnt have option to set MODE_11NA/MODE_11NG as phymode
4687 * so setting phymode as eCSR_DOT11_MODE_11n and updating the band
4688 * and channel bonding in configuration to reflect MODE_11NA/MODE_11NG
4689 */
4690 case IEEE80211_MODE_11NA_HT20:
4691 sme_set_phy_mode(hal, eCSR_DOT11_MODE_11n);
4692 if ((hdd_set_band(net, WLAN_HDD_UI_BAND_5_GHZ) == 0)) {
4693 phymode = eCSR_DOT11_MODE_11n;
4694 hdd_dot11mode = eHDD_DOT11_MODE_11n;
4695 chwidth = WNI_CFG_CHANNEL_BONDING_MODE_DISABLE;
4696 curr_band = eCSR_BAND_5G;
4697 } else {
4698 sme_set_phy_mode(hal, old_phymode);
4699 return -EIO;
4700 }
4701 break;
4702 case IEEE80211_MODE_11NA_HT40:
4703 sme_set_phy_mode(hal, eCSR_DOT11_MODE_11n);
4704 if ((hdd_set_band(net, WLAN_HDD_UI_BAND_5_GHZ) == 0)) {
4705 phymode = eCSR_DOT11_MODE_11n;
4706 hdd_dot11mode = eHDD_DOT11_MODE_11n;
4707 chwidth = WNI_CFG_CHANNEL_BONDING_MODE_ENABLE;
4708 curr_band = eCSR_BAND_5G;
4709 } else {
4710 sme_set_phy_mode(hal, old_phymode);
4711 return -EIO;
4712 }
4713 break;
4714 case IEEE80211_MODE_11NG_HT20:
4715 sme_set_phy_mode(hal, eCSR_DOT11_MODE_11n);
4716 if ((hdd_set_band(net, WLAN_HDD_UI_BAND_2_4_GHZ) == 0)) {
4717 phymode = eCSR_DOT11_MODE_11n;
4718 hdd_dot11mode = eHDD_DOT11_MODE_11n;
4719 chwidth = WNI_CFG_CHANNEL_BONDING_MODE_DISABLE;
4720 curr_band = eCSR_BAND_24;
4721 } else {
4722 sme_set_phy_mode(hal, old_phymode);
4723 return -EIO;
4724 }
4725 break;
4726 case IEEE80211_MODE_11NG_HT40:
4727 sme_set_phy_mode(hal, eCSR_DOT11_MODE_11n);
4728 if ((hdd_set_band(net, WLAN_HDD_UI_BAND_2_4_GHZ) == 0)) {
4729 phymode = eCSR_DOT11_MODE_11n;
4730 hdd_dot11mode = eHDD_DOT11_MODE_11n;
4731 chwidth = WNI_CFG_CHANNEL_BONDING_MODE_ENABLE;
4732 curr_band = eCSR_BAND_24;
4733 } else {
4734 sme_set_phy_mode(hal, old_phymode);
4735 return -EIO;
4736 }
4737 break;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004738 case IEEE80211_MODE_11AC_VHT20:
4739 case IEEE80211_MODE_11AC_VHT40:
4740 case IEEE80211_MODE_11AC_VHT80:
4741 sme_set_phy_mode(hal, eCSR_DOT11_MODE_11ac);
4742 if ((hdd_set_band(net, WLAN_HDD_UI_BAND_5_GHZ) == 0)) {
4743 phymode = eCSR_DOT11_MODE_11ac;
4744 hdd_dot11mode = eHDD_DOT11_MODE_11ac;
4745 chwidth = WNI_CFG_CHANNEL_BONDING_MODE_ENABLE;
4746 curr_band = eCSR_BAND_5G;
4747 } else {
4748 sme_set_phy_mode(hal, old_phymode);
4749 return -EIO;
4750 }
4751 break;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004752 case IEEE80211_MODE_2G_AUTO:
4753 sme_set_phy_mode(hal, eCSR_DOT11_MODE_AUTO);
4754 if ((hdd_set_band(net, WLAN_HDD_UI_BAND_2_4_GHZ) == 0)) {
4755 phymode = eCSR_DOT11_MODE_AUTO;
4756 hdd_dot11mode = eHDD_DOT11_MODE_AUTO;
4757 chwidth = WNI_CFG_CHANNEL_BONDING_MODE_ENABLE;
4758 curr_band = eCSR_BAND_24;
4759 } else {
4760 sme_set_phy_mode(hal, old_phymode);
4761 return -EIO;
4762 }
4763 break;
4764 case IEEE80211_MODE_5G_AUTO:
4765 sme_set_phy_mode(hal, eCSR_DOT11_MODE_AUTO);
4766 if ((hdd_set_band(net, WLAN_HDD_UI_BAND_5_GHZ) == 0)) {
4767 phymode = eCSR_DOT11_MODE_AUTO;
4768 hdd_dot11mode = eHDD_DOT11_MODE_AUTO;
4769 chwidth = WNI_CFG_CHANNEL_BONDING_MODE_ENABLE;
4770 vhtchanwidth = eHT_CHANNEL_WIDTH_80MHZ;
4771 curr_band = eCSR_BAND_5G;
4772 } else {
4773 sme_set_phy_mode(hal, old_phymode);
4774 return -EIO;
4775 }
4776 break;
4777 case IEEE80211_MODE_11AGN:
4778 sme_set_phy_mode(hal, eCSR_DOT11_MODE_11n);
4779 if ((hdd_set_band(net, WLAN_HDD_UI_BAND_AUTO) == 0)) {
4780 phymode = eCSR_DOT11_MODE_11n;
4781 hdd_dot11mode = eHDD_DOT11_MODE_11n;
4782 chwidth = WNI_CFG_CHANNEL_BONDING_MODE_ENABLE;
4783 curr_band = eCSR_BAND_ALL;
4784 } else {
4785 sme_set_phy_mode(hal, old_phymode);
4786 return -EIO;
4787 }
4788 break;
4789 default:
4790 return -EIO;
4791 }
4792
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004793 switch (new_phymode) {
4794 case IEEE80211_MODE_11AC_VHT20:
4795 chwidth = WNI_CFG_CHANNEL_BONDING_MODE_DISABLE;
4796 vhtchanwidth = eHT_CHANNEL_WIDTH_20MHZ;
4797 break;
4798 case IEEE80211_MODE_11AC_VHT40:
4799 vhtchanwidth = eHT_CHANNEL_WIDTH_40MHZ;
4800 break;
4801 case IEEE80211_MODE_11AC_VHT80:
4802 vhtchanwidth = eHT_CHANNEL_WIDTH_80MHZ;
4803 break;
4804 default:
4805 vhtchanwidth = phddctx->config->vhtChannelWidth;
4806 break;
4807 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004808
4809 if (phymode != -EIO) {
4810 sme_get_config_param(hal, &smeconfig);
4811 smeconfig.csrConfig.phyMode = phymode;
4812#ifdef QCA_HT_2040_COEX
4813 if (phymode == eCSR_DOT11_MODE_11n &&
4814 chwidth == WNI_CFG_CHANNEL_BONDING_MODE_DISABLE) {
4815 smeconfig.csrConfig.obssEnabled = false;
4816 halStatus = sme_set_ht2040_mode(hal,
4817 pAdapter->sessionId,
4818 eHT_CHAN_HT20, false);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304819 if (halStatus == QDF_STATUS_E_FAILURE) {
Jeff Johnson99bac312016-06-28 10:38:18 -07004820 hdd_err("Failed to disable OBSS");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004821 return -EIO;
4822 }
4823 } else if (phymode == eCSR_DOT11_MODE_11n &&
4824 chwidth == WNI_CFG_CHANNEL_BONDING_MODE_ENABLE) {
4825 smeconfig.csrConfig.obssEnabled = true;
4826 halStatus = sme_set_ht2040_mode(hal,
4827 pAdapter->sessionId,
4828 eHT_CHAN_HT20, true);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304829 if (halStatus == QDF_STATUS_E_FAILURE) {
Jeff Johnson99bac312016-06-28 10:38:18 -07004830 hdd_err("Failed to enable OBSS");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004831 return -EIO;
4832 }
4833 }
4834#endif
4835 smeconfig.csrConfig.eBand = curr_band;
4836 smeconfig.csrConfig.bandCapability = curr_band;
4837 if (curr_band == eCSR_BAND_24)
4838 smeconfig.csrConfig.Is11hSupportEnabled = 0;
4839 else
4840 smeconfig.csrConfig.Is11hSupportEnabled =
4841 phddctx->config->Is11hSupportEnabled;
4842 if (curr_band == eCSR_BAND_24)
4843 smeconfig.csrConfig.channelBondingMode24GHz = chwidth;
4844 else if (curr_band == eCSR_BAND_24)
4845 smeconfig.csrConfig.channelBondingMode5GHz = chwidth;
4846 else {
4847 smeconfig.csrConfig.channelBondingMode24GHz = chwidth;
4848 smeconfig.csrConfig.channelBondingMode5GHz = chwidth;
4849 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004850 smeconfig.csrConfig.nVhtChannelWidth = vhtchanwidth;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004851 sme_update_config(hal, &smeconfig);
4852
4853 phddctx->config->dot11Mode = hdd_dot11mode;
4854 phddctx->config->nBandCapability = curr_band;
4855 phddctx->config->nChannelBondingMode24GHz =
4856 smeconfig.csrConfig.channelBondingMode24GHz;
4857 phddctx->config->nChannelBondingMode5GHz =
4858 smeconfig.csrConfig.channelBondingMode5GHz;
4859 phddctx->config->vhtChannelWidth = vhtchanwidth;
4860 if (hdd_update_config_dat(phddctx) == false) {
Jeff Johnson99bac312016-06-28 10:38:18 -07004861 hdd_err("could not update config_dat");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004862 return -EIO;
4863 }
4864 if (phddctx->config->nChannelBondingMode5GHz)
4865 phddctx->wiphy->bands[IEEE80211_BAND_5GHZ]->ht_cap.cap
4866 |= IEEE80211_HT_CAP_SUP_WIDTH_20_40;
4867 else
4868 phddctx->wiphy->bands[IEEE80211_BAND_5GHZ]->ht_cap.cap
4869 &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40;
4870
Jeff Johnson99bac312016-06-28 10:38:18 -07004871 hdd_warn("New_Phymode= %d ch_bonding=%d band=%d VHT_ch_width=%u",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004872 phymode, chwidth, curr_band, vhtchanwidth);
4873 }
4874
4875 return 0;
4876}
4877
4878/**
4879 * hdd_get_temperature_cb() - "Get Temperature" callback function
4880 * @temperature: measured temperature
4881 * @pContext: callback context
4882 *
4883 * This function is passed to sme_get_temperature() as the callback
4884 * function to be invoked when the temperature measurement is
4885 * available.
4886 *
4887 * Return: None
4888 */
4889static void hdd_get_temperature_cb(int temperature, void *pContext)
4890{
4891 struct statsContext *pTempContext;
4892 hdd_adapter_t *pAdapter;
4893 ENTER();
4894 if (NULL == pContext) {
Jeff Johnson99bac312016-06-28 10:38:18 -07004895 hdd_err("pContext is NULL");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004896 return;
4897 }
4898 pTempContext = pContext;
4899 pAdapter = pTempContext->pAdapter;
4900 spin_lock(&hdd_context_lock);
4901 if ((NULL == pAdapter) || (TEMP_CONTEXT_MAGIC != pTempContext->magic)) {
4902 spin_unlock(&hdd_context_lock);
Jeff Johnson99bac312016-06-28 10:38:18 -07004903 hdd_warn("Invalid context, pAdapter [%p] magic [%08x]",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004904 pAdapter, pTempContext->magic);
4905 return;
4906 }
4907 if (temperature != 0) {
4908 pAdapter->temperature = temperature;
4909 }
4910 complete(&pTempContext->completion);
4911 spin_unlock(&hdd_context_lock);
4912 EXIT();
4913}
4914
4915/**
4916 * wlan_hdd_get_temperature() - get current device temperature
4917 * @pAdapter: device upon which the request was made
4918 * @temperature: pointer to where the temperature is to be returned
4919 *
4920 * Return: 0 if a temperature value (either current or cached) was
4921 * returned, otherwise a negative errno is returned.
4922 *
4923 */
4924int wlan_hdd_get_temperature(hdd_adapter_t *pAdapter, int *temperature)
4925{
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304926 QDF_STATUS status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004927 struct statsContext tempContext;
4928 unsigned long rc;
4929
4930 ENTER();
4931 if (NULL == pAdapter) {
Jeff Johnson99bac312016-06-28 10:38:18 -07004932 hdd_err("pAdapter is NULL");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004933 return -EPERM;
4934 }
4935 init_completion(&tempContext.completion);
4936 tempContext.pAdapter = pAdapter;
4937 tempContext.magic = TEMP_CONTEXT_MAGIC;
4938 status = sme_get_temperature(WLAN_HDD_GET_HAL_CTX(pAdapter),
4939 &tempContext, hdd_get_temperature_cb);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304940 if (QDF_STATUS_SUCCESS != status) {
Jeff Johnson99bac312016-06-28 10:38:18 -07004941 hdd_err("Unable to retrieve temperature");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004942 } else {
4943 rc = wait_for_completion_timeout(&tempContext.completion,
4944 msecs_to_jiffies
4945 (WLAN_WAIT_TIME_STATS));
4946 if (!rc) {
Jeff Johnson99bac312016-06-28 10:38:18 -07004947 hdd_err("SME timed out while retrieving temperature");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004948 }
4949 }
4950 spin_lock(&hdd_context_lock);
4951 tempContext.magic = 0;
4952 spin_unlock(&hdd_context_lock);
4953 *temperature = pAdapter->temperature;
4954 EXIT();
4955 return 0;
4956}
4957
4958/**
4959 * iw_setint_getnone() - Generic "set integer" private ioctl handler
4960 * @dev: device upon which the ioctl was received
4961 * @info: ioctl request information
4962 * @wrqu: ioctl request data
4963 * @extra: ioctl extra data
4964 *
4965 * Return: 0 on success, non-zero on error
4966 */
4967static int __iw_setint_getnone(struct net_device *dev,
4968 struct iw_request_info *info,
4969 union iwreq_data *wrqu, char *extra)
4970{
4971 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4972 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
4973 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4974 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
4975 hdd_context_t *hdd_ctx;
4976 tSmeConfigParams smeConfig;
4977 int *value = (int *)extra;
4978 int sub_cmd = value[0];
4979 int set_value = value[1];
4980 int ret;
4981 int enable_pbm, enable_mp;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304982 QDF_STATUS status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004983
Jeff Johnson6ee91ee2016-02-11 18:55:30 -08004984 ENTER_DEV(dev);
Hanumantha Reddy Pothula2db50ed2015-11-23 10:48:33 +05304985
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004986 INIT_COMPLETION(pWextState->completion_var);
Mukul Sharma81661ae2015-10-30 20:26:02 +05304987 memset(&smeConfig, 0x00, sizeof(smeConfig));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004988
4989 hdd_ctx = WLAN_HDD_GET_CTX(pAdapter);
4990 ret = wlan_hdd_validate_context(hdd_ctx);
4991 if (0 != ret)
4992 return ret;
4993
4994 switch (sub_cmd) {
4995 case WE_SET_11D_STATE:
4996 {
4997 if ((ENABLE_11D == set_value)
4998 || (DISABLE_11D == set_value)) {
4999
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005000 sme_get_config_param(hHal, &smeConfig);
5001 smeConfig.csrConfig.Is11dSupportEnabled =
5002 (bool) set_value;
5003
Jeff Johnson99bac312016-06-28 10:38:18 -07005004 hdd_notice("11D state=%d!!",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005005 smeConfig.csrConfig.
5006 Is11dSupportEnabled);
5007
5008 sme_update_config(hHal, &smeConfig);
5009 } else {
5010 return -EINVAL;
5011 }
5012 break;
5013 }
5014
5015 case WE_WOWL:
5016 {
5017 switch (set_value) {
5018 case 0x00:
5019 hdd_exit_wowl(pAdapter);
5020 break;
5021 case 0x01:
5022 case 0x02:
5023 case 0x03:
5024 enable_mp = (set_value & 0x01) ? 1 : 0;
5025 enable_pbm = (set_value & 0x02) ? 1 : 0;
Jeff Johnson99bac312016-06-28 10:38:18 -07005026 hdd_err("magic packet ? = %s pattern byte matching ? = %s",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005027 (enable_mp ? "YES" : "NO"),
5028 (enable_pbm ? "YES" : "NO"));
5029 hdd_enter_wowl(pAdapter, enable_mp, enable_pbm);
5030 break;
5031 default:
Jeff Johnson99bac312016-06-28 10:38:18 -07005032 hdd_err("Invalid arg %d in WE_WOWL IOCTL",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005033 set_value);
5034 ret = -EINVAL;
5035 break;
5036 }
5037
5038 break;
5039 }
5040 case WE_SET_POWER:
5041 {
5042 switch (set_value) {
5043 case 1:
5044 /* Enable PowerSave */
5045 sme_ps_enable_disable(hHal, pAdapter->sessionId,
5046 SME_PS_ENABLE);
5047 break;
5048 case 2:
5049 /* Disable PowerSave */
5050 sme_ps_enable_disable(hHal, pAdapter->sessionId,
5051 SME_PS_DISABLE);
5052 break;
5053 case 3: /* Enable UASPD */
5054 sme_ps_uapsd_enable(hHal, pAdapter->sessionId);
5055 break;
5056 case 4: /* Disable UASPD */
5057 sme_ps_uapsd_disable(hHal, pAdapter->sessionId);
5058 break;
5059 default:
Jeff Johnson99bac312016-06-28 10:38:18 -07005060 hdd_err("Invalid arg %d in WE_SET_POWER IOCTL",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005061 set_value);
5062 ret = -EINVAL;
5063 break;
5064 }
5065 break;
5066 }
5067
5068 case WE_SET_MAX_ASSOC:
5069 {
5070 if ((WNI_CFG_ASSOC_STA_LIMIT_STAMIN > set_value) ||
5071 (WNI_CFG_ASSOC_STA_LIMIT_STAMAX < set_value)) {
5072 ret = -EINVAL;
5073 } else if (sme_cfg_set_int(hHal, WNI_CFG_ASSOC_STA_LIMIT,
5074 set_value)
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05305075 != QDF_STATUS_SUCCESS) {
Jeff Johnson99bac312016-06-28 10:38:18 -07005076 hdd_err("failed to set ini parameter, WNI_CFG_ASSOC_STA_LIMIT");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005077 ret = -EIO;
5078 }
5079 break;
5080 }
5081
5082 case WE_SET_SAP_AUTO_CHANNEL_SELECTION:
5083 if (set_value == 0 || set_value == 1)
5084 (WLAN_HDD_GET_CTX(pAdapter))->config->force_sap_acs =
5085 set_value;
5086 else
5087 ret = -EINVAL;
5088 break;
5089
5090 case WE_SET_DATA_INACTIVITY_TO:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005091 if ((set_value < CFG_DATA_INACTIVITY_TIMEOUT_MIN) ||
5092 (set_value > CFG_DATA_INACTIVITY_TIMEOUT_MAX) ||
5093 (sme_cfg_set_int((WLAN_HDD_GET_CTX(pAdapter))->hHal,
5094 WNI_CFG_PS_DATA_INACTIVITY_TIMEOUT,
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05305095 set_value) == QDF_STATUS_E_FAILURE)) {
Jeff Johnson99bac312016-06-28 10:38:18 -07005096 hdd_err("Failure: Could not pass on WNI_CFG_PS_DATA_INACTIVITY_TIMEOUT configuration info to SME");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005097 ret = -EINVAL;
5098 }
5099 break;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005100 case WE_SET_MC_RATE:
5101 {
5102 ret = wlan_hdd_set_mc_rate(pAdapter, set_value);
5103 break;
5104 }
5105 case WE_SET_TX_POWER:
5106 {
Anurag Chouhan6d760662016-02-20 16:05:43 +05305107 struct qdf_mac_addr bssid;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005108
Anurag Chouhanc5548422016-02-24 18:33:27 +05305109 qdf_copy_macaddr(&bssid, &pHddStaCtx->conn_info.bssId);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005110 if (sme_set_tx_power
5111 (hHal, pAdapter->sessionId, bssid,
5112 pAdapter->device_mode,
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05305113 set_value) != QDF_STATUS_SUCCESS) {
Jeff Johnson99bac312016-06-28 10:38:18 -07005114 hdd_err("Setting tx power failed");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005115 return -EIO;
5116 }
5117 break;
5118 }
5119 case WE_SET_MAX_TX_POWER:
5120 {
Anurag Chouhan6d760662016-02-20 16:05:43 +05305121 struct qdf_mac_addr bssid;
5122 struct qdf_mac_addr selfMac;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005123
Jeff Johnson99bac312016-06-28 10:38:18 -07005124 hdd_notice("Setting maximum tx power %d dBm",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005125 set_value);
Anurag Chouhanc5548422016-02-24 18:33:27 +05305126 qdf_copy_macaddr(&bssid, &pHddStaCtx->conn_info.bssId);
5127 qdf_copy_macaddr(&selfMac, &pHddStaCtx->conn_info.bssId);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005128
5129 if (sme_set_max_tx_power(hHal, bssid, selfMac, set_value)
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05305130 != QDF_STATUS_SUCCESS) {
Jeff Johnson99bac312016-06-28 10:38:18 -07005131 hdd_err("Setting maximum tx power failed");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005132 return -EIO;
5133 }
5134
5135 break;
5136 }
5137 case WE_SET_MAX_TX_POWER_2_4:
5138 {
Jeff Johnson99bac312016-06-28 10:38:18 -07005139 hdd_notice("Setting maximum tx power %d dBm for 2.4 GHz band",
5140 set_value);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005141 if (sme_set_max_tx_power_per_band(eCSR_BAND_24, set_value) !=
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05305142 QDF_STATUS_SUCCESS) {
Jeff Johnson99bac312016-06-28 10:38:18 -07005143 hdd_err("Setting maximum tx power failed for 2.4 GHz band");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005144 return -EIO;
5145 }
5146
5147 break;
5148 }
5149 case WE_SET_MAX_TX_POWER_5_0:
5150 {
Jeff Johnson99bac312016-06-28 10:38:18 -07005151 hdd_notice("Setting maximum tx power %d dBm for 5.0 GHz band",
5152 set_value);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005153 if (sme_set_max_tx_power_per_band(eCSR_BAND_5G, set_value) !=
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05305154 QDF_STATUS_SUCCESS) {
Jeff Johnson99bac312016-06-28 10:38:18 -07005155 hdd_err("Setting maximum tx power failed for 5.0 GHz band");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005156 return -EIO;
5157 }
5158
5159 break;
5160 }
Srinivas Girigowdac34f11d2016-02-25 16:02:42 -08005161 case WE_SET_PKTLOG:
5162 {
5163 hdd_process_pktlog_command(hdd_ctx, set_value);
5164 break;
5165 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005166 case WE_SET_HIGHER_DTIM_TRANSITION:
5167 {
5168 if (!((set_value == false) || (set_value == true))) {
Jeff Johnson99bac312016-06-28 10:38:18 -07005169 hdd_err("Dynamic DTIM Incorrect data:%d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005170 set_value);
5171 ret = -EINVAL;
5172 } else {
5173 if (pAdapter->higherDtimTransition != set_value) {
5174 pAdapter->higherDtimTransition =
5175 set_value;
Jeff Johnson99bac312016-06-28 10:38:18 -07005176 hdd_notice("higherDtimTransition set to :%d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005177 pAdapter->higherDtimTransition);
5178 }
5179 }
5180
5181 break;
5182 }
5183
5184 case WE_SET_TM_LEVEL:
5185 {
Jeff Johnson99bac312016-06-28 10:38:18 -07005186 hdd_notice("Set Thermal Mitigation Level %d", set_value);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005187 (void)sme_set_thermal_level(hHal, set_value);
5188 break;
5189 }
5190
5191 case WE_SET_PHYMODE:
5192 {
5193 hdd_context_t *phddctx = WLAN_HDD_GET_CTX(pAdapter);
5194
5195 ret =
5196 wlan_hdd_update_phymode(dev, hHal, set_value,
5197 phddctx);
5198 break;
5199 }
5200
5201 case WE_SET_NSS:
5202 {
Jeff Johnson99bac312016-06-28 10:38:18 -07005203 hdd_notice("Set NSS = %d", set_value);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005204 if ((set_value > 2) || (set_value <= 0)) {
Jeff Johnson99bac312016-06-28 10:38:18 -07005205 hdd_err("NSS greater than 2 not supported");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005206 ret = -EINVAL;
5207 } else {
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05305208 if (QDF_STATUS_SUCCESS !=
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005209 hdd_update_nss(WLAN_HDD_GET_CTX(pAdapter),
5210 set_value))
5211 ret = -EINVAL;
5212 }
5213 break;
5214 }
5215
5216 case WE_SET_GTX_HT_MCS:
5217 {
Jeff Johnson99bac312016-06-28 10:38:18 -07005218 hdd_notice("WMI_VDEV_PARAM_GTX_HT_MCS %d", set_value);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005219 ret = wma_cli_set_command(pAdapter->sessionId,
5220 WMI_VDEV_PARAM_GTX_HT_MCS,
5221 set_value, GTX_CMD);
5222 break;
5223 }
5224
5225 case WE_SET_GTX_VHT_MCS:
5226 {
Jeff Johnson99bac312016-06-28 10:38:18 -07005227 hdd_notice("WMI_VDEV_PARAM_GTX_VHT_MCS %d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005228 set_value);
5229 ret = wma_cli_set_command(pAdapter->sessionId,
5230 WMI_VDEV_PARAM_GTX_VHT_MCS,
5231 set_value, GTX_CMD);
5232 break;
5233 }
5234
5235 case WE_SET_GTX_USRCFG:
5236 {
Jeff Johnson99bac312016-06-28 10:38:18 -07005237 hdd_notice("WMI_VDEV_PARAM_GTX_USR_CFG %d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005238 set_value);
5239 ret = wma_cli_set_command(pAdapter->sessionId,
5240 WMI_VDEV_PARAM_GTX_USR_CFG,
5241 set_value, GTX_CMD);
5242 break;
5243 }
5244
5245 case WE_SET_GTX_THRE:
5246 {
Jeff Johnson99bac312016-06-28 10:38:18 -07005247 hdd_notice("WMI_VDEV_PARAM_GTX_THRE %d", set_value);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005248 ret = wma_cli_set_command(pAdapter->sessionId,
5249 WMI_VDEV_PARAM_GTX_THRE,
5250 set_value, GTX_CMD);
5251 break;
5252 }
5253
5254 case WE_SET_GTX_MARGIN:
5255 {
Jeff Johnson99bac312016-06-28 10:38:18 -07005256 hdd_notice("WMI_VDEV_PARAM_GTX_MARGIN %d", set_value);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005257 ret = wma_cli_set_command(pAdapter->sessionId,
5258 WMI_VDEV_PARAM_GTX_MARGIN,
5259 set_value, GTX_CMD);
5260 break;
5261 }
5262
5263 case WE_SET_GTX_STEP:
5264 {
Jeff Johnson99bac312016-06-28 10:38:18 -07005265 hdd_notice("WMI_VDEV_PARAM_GTX_STEP %d", set_value);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005266 ret = wma_cli_set_command(pAdapter->sessionId,
5267 WMI_VDEV_PARAM_GTX_STEP,
5268 set_value, GTX_CMD);
5269 break;
5270 }
5271
5272 case WE_SET_GTX_MINTPC:
5273 {
Jeff Johnson99bac312016-06-28 10:38:18 -07005274 hdd_notice("WMI_VDEV_PARAM_GTX_MINTPC %d", set_value);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005275 ret = wma_cli_set_command(pAdapter->sessionId,
5276 WMI_VDEV_PARAM_GTX_MINTPC,
5277 set_value, GTX_CMD);
5278 break;
5279 }
5280
5281 case WE_SET_GTX_BWMASK:
5282 {
Jeff Johnson99bac312016-06-28 10:38:18 -07005283 hdd_notice("WMI_VDEV_PARAM_GTX_BWMASK %d", set_value);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005284 ret = wma_cli_set_command(pAdapter->sessionId,
5285 WMI_VDEV_PARAM_GTX_BW_MASK,
5286 set_value, GTX_CMD);
5287 break;
5288 }
5289
5290 case WE_SET_LDPC:
5291 {
5292 uint32_t value;
5293 union {
5294 uint16_t nCfgValue16;
5295 tSirMacHTCapabilityInfo htCapInfo;
5296 } uHTCapabilityInfo;
5297
Jeff Johnson99bac312016-06-28 10:38:18 -07005298 hdd_notice("LDPC val %d", set_value);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005299 /* get the HT capability info */
5300 ret = sme_cfg_get_int(hHal, WNI_CFG_HT_CAP_INFO, &value);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05305301 if (QDF_STATUS_SUCCESS != ret) {
Jeff Johnson99bac312016-06-28 10:38:18 -07005302 hdd_err("could not get HT capability info");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005303 return -EIO;
5304 }
5305
5306 uHTCapabilityInfo.nCfgValue16 = 0xFFFF & value;
5307 if ((set_value
5308 && (uHTCapabilityInfo.htCapInfo.advCodingCap))
5309 || (!set_value)) {
5310 ret =
5311 sme_update_ht_config(hHal,
5312 pAdapter->sessionId,
5313 WNI_CFG_HT_CAP_INFO_ADVANCE_CODING,
5314 set_value);
5315 }
5316
5317 if (ret)
Jeff Johnson99bac312016-06-28 10:38:18 -07005318 hdd_err("Failed to set LDPC value");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005319
5320 break;
5321 }
5322
5323 case WE_SET_TX_STBC:
5324 {
5325 uint32_t value;
5326 union {
5327 uint16_t nCfgValue16;
5328 tSirMacHTCapabilityInfo htCapInfo;
5329 } uHTCapabilityInfo;
5330
Jeff Johnson99bac312016-06-28 10:38:18 -07005331 hdd_notice("TX_STBC val %d", set_value);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005332 /* get the HT capability info */
5333 ret = sme_cfg_get_int(hHal, WNI_CFG_HT_CAP_INFO, &value);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05305334 if (QDF_STATUS_SUCCESS != ret) {
Jeff Johnson99bac312016-06-28 10:38:18 -07005335 hdd_err("could not get HT capability info");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005336 return -EIO;
5337 }
5338
5339 uHTCapabilityInfo.nCfgValue16 = 0xFFFF & value;
5340 if ((set_value && (uHTCapabilityInfo.htCapInfo.txSTBC))
5341 || (!set_value)) {
5342 ret =
5343 sme_update_ht_config(hHal,
5344 pAdapter->sessionId,
5345 WNI_CFG_HT_CAP_INFO_TX_STBC,
5346 set_value);
5347 }
5348
5349 if (ret)
Jeff Johnson99bac312016-06-28 10:38:18 -07005350 hdd_err("Failed to set TX STBC value");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005351
5352 break;
5353 }
5354
5355 case WE_SET_RX_STBC:
5356 {
5357 uint32_t value;
5358 union {
5359 uint16_t nCfgValue16;
5360 tSirMacHTCapabilityInfo htCapInfo;
5361 } uHTCapabilityInfo;
5362
Jeff Johnson99bac312016-06-28 10:38:18 -07005363 hdd_notice("WMI_VDEV_PARAM_RX_STBC val %d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005364 set_value);
5365 /* get the HT capability info */
5366 ret = sme_cfg_get_int(hHal, WNI_CFG_HT_CAP_INFO, &value);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05305367 if (QDF_STATUS_SUCCESS != ret) {
Jeff Johnson99bac312016-06-28 10:38:18 -07005368 hdd_err("could not get HT capability info");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005369 return -EIO;
5370 }
5371
5372 uHTCapabilityInfo.nCfgValue16 = 0xFFFF & value;
5373 if ((set_value && (uHTCapabilityInfo.htCapInfo.rxSTBC))
5374 || (!set_value)) {
5375 ret =
5376 sme_update_ht_config(hHal,
5377 pAdapter->sessionId,
5378 WNI_CFG_HT_CAP_INFO_RX_STBC,
5379 (!set_value) ? set_value
5380 : uHTCapabilityInfo.
5381 htCapInfo.rxSTBC);
5382 }
5383
5384 if (ret)
Jeff Johnson99bac312016-06-28 10:38:18 -07005385 hdd_err("Failed to set RX STBC value");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005386 break;
5387 }
5388
5389 case WE_SET_SHORT_GI:
5390 {
Jeff Johnson99bac312016-06-28 10:38:18 -07005391 hdd_notice("WMI_VDEV_PARAM_SGI val %d", set_value);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005392 ret = sme_update_ht_config(hHal, pAdapter->sessionId,
5393 WNI_CFG_HT_CAP_INFO_SHORT_GI_20MHZ,
5394 set_value);
5395 if (ret)
Jeff Johnson99bac312016-06-28 10:38:18 -07005396 hdd_err("Failed to set ShortGI value");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005397 break;
5398 }
5399
5400 case WE_SET_RTSCTS:
5401 {
5402 uint32_t value;
5403
Jeff Johnson99bac312016-06-28 10:38:18 -07005404 hdd_notice("WMI_VDEV_PARAM_ENABLE_RTSCTS val 0x%x",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005405 set_value);
5406
5407 if ((set_value & HDD_RTSCTS_EN_MASK) ==
5408 HDD_RTSCTS_ENABLE)
5409 value =
5410 (WLAN_HDD_GET_CTX(pAdapter))->config->
5411 RTSThreshold;
5412 else if (((set_value & HDD_RTSCTS_EN_MASK) == 0)
5413 || ((set_value & HDD_RTSCTS_EN_MASK) ==
5414 HDD_CTS_ENABLE))
5415 value = WNI_CFG_RTS_THRESHOLD_STAMAX;
5416 else
5417 return -EIO;
5418
5419 ret = wma_cli_set_command(pAdapter->sessionId,
5420 WMI_VDEV_PARAM_ENABLE_RTSCTS,
5421 set_value, VDEV_CMD);
5422 if (!ret) {
5423 if (sme_cfg_set_int
5424 (hHal, WNI_CFG_RTS_THRESHOLD, value) !=
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05305425 QDF_STATUS_SUCCESS) {
Jeff Johnson99bac312016-06-28 10:38:18 -07005426 hdd_err("FAILED TO SET RTSCTS");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005427 return -EIO;
5428 }
5429 }
5430
5431 break;
5432 }
5433
5434 case WE_SET_CHWIDTH:
5435 {
5436 bool chwidth = false;
5437 hdd_context_t *phddctx = WLAN_HDD_GET_CTX(pAdapter);
5438 /*updating channel bonding only on 5Ghz */
Jeff Johnson99bac312016-06-28 10:38:18 -07005439 hdd_notice("WMI_VDEV_PARAM_CHWIDTH val %d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005440 set_value);
5441 if (set_value > eHT_CHANNEL_WIDTH_80MHZ) {
Jeff Johnson99bac312016-06-28 10:38:18 -07005442 hdd_err("Invalid channel width 0->20 1->40 2->80");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005443 return -EINVAL;
5444 }
5445
5446 if ((WNI_CFG_CHANNEL_BONDING_MODE_DISABLE !=
5447 csr_convert_cb_ini_value_to_phy_cb_state(phddctx->config->
5448 nChannelBondingMode5GHz)))
5449 chwidth = true;
5450
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005451 sme_get_config_param(hHal, &smeConfig);
5452 switch (set_value) {
5453 case eHT_CHANNEL_WIDTH_20MHZ:
5454 smeConfig.csrConfig.channelBondingMode5GHz =
5455 WNI_CFG_CHANNEL_BONDING_MODE_DISABLE;
5456 break;
5457 case eHT_CHANNEL_WIDTH_40MHZ:
5458 if (chwidth)
5459 smeConfig.csrConfig.
5460 channelBondingMode5GHz =
5461 phddctx->config->
5462 nChannelBondingMode5GHz;
5463 else
5464 return -EINVAL;
5465
5466 break;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005467 case eHT_CHANNEL_WIDTH_80MHZ:
5468 if (chwidth)
5469 smeConfig.csrConfig.
5470 channelBondingMode5GHz =
5471 phddctx->config->
5472 nChannelBondingMode5GHz;
5473 else
5474 return -EINVAL;
5475
5476 break;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005477
5478 default:
5479 return -EINVAL;
5480 }
5481
5482 ret = wma_cli_set_command(pAdapter->sessionId,
5483 WMI_VDEV_PARAM_CHWIDTH,
5484 set_value, VDEV_CMD);
5485 if (!ret)
5486 sme_update_config(hHal, &smeConfig);
5487
5488 break;
5489 }
5490
5491 case WE_SET_ANI_EN_DIS:
5492 {
Jeff Johnson99bac312016-06-28 10:38:18 -07005493 hdd_notice("WMI_PDEV_PARAM_ANI_ENABLE val %d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005494 set_value);
5495 ret = wma_cli_set_command(pAdapter->sessionId,
5496 WMI_PDEV_PARAM_ANI_ENABLE,
5497 set_value, PDEV_CMD);
5498 break;
5499 }
5500
5501 case WE_SET_ANI_POLL_PERIOD:
5502 {
Jeff Johnson99bac312016-06-28 10:38:18 -07005503 hdd_notice("WMI_PDEV_PARAM_ANI_POLL_PERIOD val %d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005504 set_value);
5505 ret = wma_cli_set_command(pAdapter->sessionId,
5506 WMI_PDEV_PARAM_ANI_POLL_PERIOD,
5507 set_value, PDEV_CMD);
5508 break;
5509 }
5510
5511 case WE_SET_ANI_LISTEN_PERIOD:
5512 {
Jeff Johnson99bac312016-06-28 10:38:18 -07005513 hdd_notice("WMI_PDEV_PARAM_ANI_LISTEN_PERIOD val %d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005514 set_value);
5515 ret = wma_cli_set_command(pAdapter->sessionId,
5516 WMI_PDEV_PARAM_ANI_LISTEN_PERIOD,
5517 set_value, PDEV_CMD);
5518 break;
5519 }
5520
5521 case WE_SET_ANI_OFDM_LEVEL:
5522 {
Jeff Johnson99bac312016-06-28 10:38:18 -07005523 hdd_notice("WMI_PDEV_PARAM_ANI_OFDM_LEVEL val %d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005524 set_value);
5525 ret = wma_cli_set_command(pAdapter->sessionId,
5526 WMI_PDEV_PARAM_ANI_OFDM_LEVEL,
5527 set_value, PDEV_CMD);
5528 break;
5529 }
5530
5531 case WE_SET_ANI_CCK_LEVEL:
5532 {
Jeff Johnson99bac312016-06-28 10:38:18 -07005533 hdd_notice("WMI_PDEV_PARAM_ANI_CCK_LEVEL val %d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005534 set_value);
5535 ret = wma_cli_set_command(pAdapter->sessionId,
5536 WMI_PDEV_PARAM_ANI_CCK_LEVEL,
5537 set_value, PDEV_CMD);
5538 break;
5539 }
5540
5541 case WE_SET_DYNAMIC_BW:
5542 {
Jeff Johnson99bac312016-06-28 10:38:18 -07005543 hdd_notice("WMI_PDEV_PARAM_DYNAMIC_BW val %d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005544 set_value);
5545 ret = wma_cli_set_command(pAdapter->sessionId,
5546 WMI_PDEV_PARAM_DYNAMIC_BW,
5547 set_value, PDEV_CMD);
5548 break;
5549 }
5550
5551 case WE_SET_CTS_CBW:
5552 {
Jeff Johnson99bac312016-06-28 10:38:18 -07005553 hdd_notice("WE_SET_CTS_CBW val %d", set_value);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005554 ret = wma_cli_set_command(pAdapter->sessionId,
5555 WMI_PDEV_PARAM_CTS_CBW,
5556 set_value, PDEV_CMD);
5557 break;
5558 }
5559
5560 case WE_SET_11N_RATE:
5561 {
5562 uint8_t preamble = 0, nss = 0, rix = 0;
Jeff Johnson99bac312016-06-28 10:38:18 -07005563 hdd_notice("WMI_VDEV_PARAM_FIXED_RATE val %d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005564 set_value);
5565
5566 if (set_value != 0xff) {
5567 rix = RC_2_RATE_IDX(set_value);
5568 if (set_value & 0x80) {
5569 preamble = WMI_RATE_PREAMBLE_HT;
5570 nss = HT_RC_2_STREAMS(set_value) - 1;
5571 } else {
5572 nss = 0;
5573 rix = RC_2_RATE_IDX(set_value);
5574 if (set_value & 0x10) {
5575 preamble =
5576 WMI_RATE_PREAMBLE_CCK;
5577 if (rix != 0x3)
5578 /* Enable Short
5579 * preamble always for
5580 * CCK except 1mbps
5581 */
5582 rix |= 0x4;
5583 } else {
5584 preamble =
5585 WMI_RATE_PREAMBLE_OFDM;
5586 }
5587 }
5588 set_value = (preamble << 6) | (nss << 4) | rix;
5589 }
5590 hdd_info("WMI_VDEV_PARAM_FIXED_RATE val %d rix %d preamble %x nss %d",
5591 set_value, rix, preamble, nss);
5592
5593 ret = wma_cli_set_command(pAdapter->sessionId,
5594 WMI_VDEV_PARAM_FIXED_RATE,
5595 set_value, VDEV_CMD);
5596 break;
5597 }
5598
5599 case WE_SET_VHT_RATE:
5600 {
5601 uint8_t preamble = 0, nss = 0, rix = 0;
5602
5603 if (set_value != 0xff) {
5604 rix = RC_2_RATE_IDX_11AC(set_value);
5605 preamble = WMI_RATE_PREAMBLE_VHT;
5606 nss = HT_RC_2_STREAMS_11AC(set_value) - 1;
5607
5608 set_value = (preamble << 6) | (nss << 4) | rix;
5609 }
5610 hdd_info("WMI_VDEV_PARAM_FIXED_RATE val %d rix %d preamble %x nss %d",
5611 set_value, rix, preamble, nss);
5612 ret = wma_cli_set_command(pAdapter->sessionId,
5613 WMI_VDEV_PARAM_FIXED_RATE,
5614 set_value, VDEV_CMD);
5615 break;
5616 }
5617
5618 case WE_SET_AMPDU:
5619 {
Jeff Johnson99bac312016-06-28 10:38:18 -07005620 hdd_notice("SET AMPDU val %d", set_value);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005621 ret = wma_cli_set_command(pAdapter->sessionId,
5622 GEN_VDEV_PARAM_AMPDU,
5623 set_value, GEN_CMD);
5624 break;
5625 }
5626
5627 case WE_SET_AMSDU:
5628 {
Jeff Johnson99bac312016-06-28 10:38:18 -07005629 hdd_notice("SET AMSDU val %d", set_value);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005630 ret = wma_cli_set_command(pAdapter->sessionId,
5631 GEN_VDEV_PARAM_AMSDU,
5632 set_value, GEN_CMD);
5633 break;
5634 }
5635
5636 case WE_SET_BURST_ENABLE:
5637 {
Jeff Johnson99bac312016-06-28 10:38:18 -07005638 hdd_notice("SET Burst enable val %d", set_value);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005639 if ((set_value == 0) || (set_value == 1)) {
5640 ret = wma_cli_set_command(pAdapter->sessionId,
5641 WMI_PDEV_PARAM_BURST_ENABLE,
5642 set_value, PDEV_CMD);
5643 } else
5644 ret = -EINVAL;
5645 break;
5646 }
5647 case WE_SET_BURST_DUR:
5648 {
Jeff Johnson99bac312016-06-28 10:38:18 -07005649 hdd_notice("SET Burst duration val %d", set_value);
Jeff Johnsonda5ee772016-08-04 17:18:47 -07005650 if ((set_value > 0) && (set_value <= 102400))
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005651 ret = wma_cli_set_command(pAdapter->sessionId,
5652 WMI_PDEV_PARAM_BURST_DUR,
5653 set_value, PDEV_CMD);
5654 else
5655 ret = -EINVAL;
5656 break;
5657 }
5658
5659 case WE_SET_TX_CHAINMASK:
5660 {
Jeff Johnson99bac312016-06-28 10:38:18 -07005661 hdd_notice("WMI_PDEV_PARAM_TX_CHAIN_MASK val %d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005662 set_value);
5663 ret = wma_cli_set_command(pAdapter->sessionId,
5664 WMI_PDEV_PARAM_TX_CHAIN_MASK,
5665 set_value, PDEV_CMD);
5666 break;
5667 }
5668
5669 case WE_SET_RX_CHAINMASK:
5670 {
Jeff Johnson99bac312016-06-28 10:38:18 -07005671 hdd_notice("WMI_PDEV_PARAM_RX_CHAIN_MASK val %d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005672 set_value);
5673 ret = wma_cli_set_command(pAdapter->sessionId,
5674 WMI_PDEV_PARAM_RX_CHAIN_MASK,
5675 set_value, PDEV_CMD);
5676 break;
5677 }
5678
5679 case WE_SET_TXPOW_2G:
5680 {
Jeff Johnson99bac312016-06-28 10:38:18 -07005681 hdd_notice("WMI_PDEV_PARAM_TXPOWER_LIMIT2G val %d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005682 set_value);
5683 ret = wma_cli_set_command(pAdapter->sessionId,
5684 WMI_PDEV_PARAM_TXPOWER_LIMIT2G,
5685 set_value, PDEV_CMD);
5686 break;
5687 }
5688
5689 case WE_SET_TXPOW_5G:
5690 {
Jeff Johnson99bac312016-06-28 10:38:18 -07005691 hdd_notice("WMI_PDEV_PARAM_TXPOWER_LIMIT5G val %d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005692 set_value);
5693 ret = wma_cli_set_command(pAdapter->sessionId,
5694 WMI_PDEV_PARAM_TXPOWER_LIMIT5G,
5695 set_value, PDEV_CMD);
5696 break;
5697 }
5698
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005699 /* Firmware debug log */
5700 case WE_DBGLOG_LOG_LEVEL:
5701 {
Jeff Johnson99bac312016-06-28 10:38:18 -07005702 hdd_notice("WE_DBGLOG_LOG_LEVEL val %d", set_value);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005703 hdd_ctx->fw_log_settings.dl_loglevel = set_value;
5704 ret = wma_cli_set_command(pAdapter->sessionId,
5705 WMI_DBGLOG_LOG_LEVEL,
5706 set_value, DBG_CMD);
5707 break;
5708 }
5709
5710 case WE_DBGLOG_VAP_ENABLE:
5711 {
Jeff Johnson99bac312016-06-28 10:38:18 -07005712 hdd_notice("WE_DBGLOG_VAP_ENABLE val %d", set_value);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005713 ret = wma_cli_set_command(pAdapter->sessionId,
5714 WMI_DBGLOG_VAP_ENABLE,
5715 set_value, DBG_CMD);
5716 break;
5717 }
5718
5719 case WE_DBGLOG_VAP_DISABLE:
5720 {
Jeff Johnson99bac312016-06-28 10:38:18 -07005721 hdd_notice("WE_DBGLOG_VAP_DISABLE val %d", set_value);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005722 ret = wma_cli_set_command(pAdapter->sessionId,
5723 WMI_DBGLOG_VAP_DISABLE,
5724 set_value, DBG_CMD);
5725 break;
5726 }
5727
5728 case WE_DBGLOG_MODULE_ENABLE:
5729 {
Jeff Johnson99bac312016-06-28 10:38:18 -07005730 hdd_notice("WE_DBGLOG_MODULE_ENABLE val %d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005731 set_value);
5732 hdd_ctx->fw_log_settings.enable = set_value;
5733 ret = wma_cli_set_command(pAdapter->sessionId,
5734 WMI_DBGLOG_MODULE_ENABLE,
5735 set_value, DBG_CMD);
5736 break;
5737 }
5738
5739 case WE_DBGLOG_MODULE_DISABLE:
5740 {
Jeff Johnson99bac312016-06-28 10:38:18 -07005741 hdd_notice("WE_DBGLOG_MODULE_DISABLE val %d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005742 set_value);
5743 hdd_ctx->fw_log_settings.enable = set_value;
5744 ret = wma_cli_set_command(pAdapter->sessionId,
5745 WMI_DBGLOG_MODULE_DISABLE,
5746 set_value, DBG_CMD);
5747 break;
5748 }
5749 case WE_DBGLOG_MOD_LOG_LEVEL:
5750 {
Jeff Johnson99bac312016-06-28 10:38:18 -07005751 hdd_notice("WE_DBGLOG_MOD_LOG_LEVEL val %d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005752 set_value);
5753
5754 if (hdd_ctx->fw_log_settings.index >= MAX_MOD_LOGLEVEL)
5755 hdd_ctx->fw_log_settings.index = 0;
5756
5757 hdd_ctx->fw_log_settings.
5758 dl_mod_loglevel[hdd_ctx->fw_log_settings.index] =
5759 set_value;
5760 hdd_ctx->fw_log_settings.index++;
5761
5762 ret = wma_cli_set_command(pAdapter->sessionId,
5763 WMI_DBGLOG_MOD_LOG_LEVEL,
5764 set_value, DBG_CMD);
5765 break;
5766 }
5767
5768 case WE_DBGLOG_TYPE:
5769 {
Jeff Johnson99bac312016-06-28 10:38:18 -07005770 hdd_notice("WE_DBGLOG_TYPE val %d", set_value);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005771 hdd_ctx->fw_log_settings.dl_type = set_value;
5772 ret = wma_cli_set_command(pAdapter->sessionId,
5773 WMI_DBGLOG_TYPE,
5774 set_value, DBG_CMD);
5775 break;
5776 }
5777 case WE_DBGLOG_REPORT_ENABLE:
5778 {
Jeff Johnson99bac312016-06-28 10:38:18 -07005779 hdd_notice("WE_DBGLOG_REPORT_ENABLE val %d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005780 set_value);
5781 hdd_ctx->fw_log_settings.dl_report = set_value;
5782 ret = wma_cli_set_command(pAdapter->sessionId,
5783 WMI_DBGLOG_REPORT_ENABLE,
5784 set_value, DBG_CMD);
5785 break;
5786 }
5787
5788 case WE_SET_TXRX_FWSTATS:
5789 {
Jeff Johnson99bac312016-06-28 10:38:18 -07005790 hdd_notice("WE_SET_TXRX_FWSTATS val %d", set_value);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005791 ret = wma_cli_set_command(pAdapter->sessionId,
5792 WMA_VDEV_TXRX_FWSTATS_ENABLE_CMDID,
5793 set_value, VDEV_CMD);
5794 break;
5795 }
5796
5797 case WE_TXRX_FWSTATS_RESET:
5798 {
Jeff Johnson99bac312016-06-28 10:38:18 -07005799 hdd_notice("WE_TXRX_FWSTATS_RESET val %d", set_value);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005800 ret = wma_cli_set_command(pAdapter->sessionId,
5801 WMA_VDEV_TXRX_FWSTATS_RESET_CMDID,
5802 set_value, VDEV_CMD);
5803 break;
5804 }
5805
5806 case WE_DUMP_STATS:
5807 {
Jeff Johnson99bac312016-06-28 10:38:18 -07005808 hdd_notice("WE_DUMP_STATS val %d", set_value);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005809 hdd_wlan_dump_stats(pAdapter, set_value);
5810 break;
5811 }
5812
5813 case WE_CLEAR_STATS:
5814 {
Jeff Johnson99bac312016-06-28 10:38:18 -07005815 hdd_notice("WE_CLEAR_STATS val %d", set_value);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005816 switch (set_value) {
5817 case WLAN_HDD_STATS:
5818 memset(&pAdapter->stats, 0, sizeof(pAdapter->stats));
5819 memset(&pAdapter->hdd_stats, 0,
5820 sizeof(pAdapter->hdd_stats));
5821 break;
5822 case WLAN_TXRX_HIST_STATS:
5823 wlan_hdd_clear_tx_rx_histogram(hdd_ctx);
5824 break;
5825 case WLAN_HDD_NETIF_OPER_HISTORY:
5826 wlan_hdd_clear_netif_queue_history(hdd_ctx);
5827 break;
Nirav Shahbf1b0332016-05-25 14:27:39 +05305828 case WLAN_HIF_STATS:
5829 hdd_clear_hif_stats();
5830 break;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005831 default:
5832 ol_txrx_clear_stats(set_value);
5833 }
5834 break;
5835 }
5836
5837 case WE_PPS_PAID_MATCH:
5838 {
Krunal Sonif07bb382016-03-10 13:02:11 -08005839 if (pAdapter->device_mode != QDF_STA_MODE)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005840 return EINVAL;
5841
Jeff Johnson99bac312016-06-28 10:38:18 -07005842 hdd_notice("WMI_VDEV_PPS_PAID_MATCH val %d ",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005843 set_value);
5844 ret = wma_cli_set_command(pAdapter->sessionId,
5845 WMI_VDEV_PPS_PAID_MATCH,
5846 set_value, PPS_CMD);
5847 break;
5848 }
5849
5850 case WE_PPS_GID_MATCH:
5851 {
Krunal Sonif07bb382016-03-10 13:02:11 -08005852 if (pAdapter->device_mode != QDF_STA_MODE)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005853 return EINVAL;
Jeff Johnson99bac312016-06-28 10:38:18 -07005854 hdd_notice("WMI_VDEV_PPS_GID_MATCH val %d ",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005855 set_value);
5856 ret = wma_cli_set_command(pAdapter->sessionId,
5857 WMI_VDEV_PPS_GID_MATCH,
5858 set_value, PPS_CMD);
5859 break;
5860 }
5861
5862 case WE_PPS_EARLY_TIM_CLEAR:
5863 {
Krunal Sonif07bb382016-03-10 13:02:11 -08005864 if (pAdapter->device_mode != QDF_STA_MODE)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005865 return EINVAL;
Jeff Johnson99bac312016-06-28 10:38:18 -07005866 hdd_notice(" WMI_VDEV_PPS_EARLY_TIM_CLEAR val %d ",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005867 set_value);
5868 ret = wma_cli_set_command(pAdapter->sessionId,
5869 WMI_VDEV_PPS_EARLY_TIM_CLEAR,
5870 set_value, PPS_CMD);
5871 break;
5872 }
5873
5874 case WE_PPS_EARLY_DTIM_CLEAR:
5875 {
Krunal Sonif07bb382016-03-10 13:02:11 -08005876 if (pAdapter->device_mode != QDF_STA_MODE)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005877 return EINVAL;
Jeff Johnson99bac312016-06-28 10:38:18 -07005878 hdd_notice("WMI_VDEV_PPS_EARLY_DTIM_CLEAR val %d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005879 set_value);
5880 ret = wma_cli_set_command(pAdapter->sessionId,
5881 WMI_VDEV_PPS_EARLY_DTIM_CLEAR,
5882 set_value, PPS_CMD);
5883 break;
5884 }
5885
5886 case WE_PPS_EOF_PAD_DELIM:
5887 {
Krunal Sonif07bb382016-03-10 13:02:11 -08005888 if (pAdapter->device_mode != QDF_STA_MODE)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005889 return EINVAL;
Jeff Johnson99bac312016-06-28 10:38:18 -07005890 hdd_notice("WMI_VDEV_PPS_EOF_PAD_DELIM val %d ",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005891 set_value);
5892 ret = wma_cli_set_command(pAdapter->sessionId,
5893 WMI_VDEV_PPS_EOF_PAD_DELIM,
5894 set_value, PPS_CMD);
5895 break;
5896 }
5897
5898 case WE_PPS_MACADDR_MISMATCH:
5899 {
Krunal Sonif07bb382016-03-10 13:02:11 -08005900 if (pAdapter->device_mode != QDF_STA_MODE)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005901 return EINVAL;
Jeff Johnson99bac312016-06-28 10:38:18 -07005902 hdd_notice("WMI_VDEV_PPS_MACADDR_MISMATCH val %d ",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005903 set_value);
5904 ret = wma_cli_set_command(pAdapter->sessionId,
5905 WMI_VDEV_PPS_MACADDR_MISMATCH,
5906 set_value, PPS_CMD);
5907 break;
5908 }
5909
5910 case WE_PPS_DELIM_CRC_FAIL:
5911 {
Krunal Sonif07bb382016-03-10 13:02:11 -08005912 if (pAdapter->device_mode != QDF_STA_MODE)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005913 return EINVAL;
Jeff Johnson99bac312016-06-28 10:38:18 -07005914 hdd_notice("WMI_VDEV_PPS_DELIM_CRC_FAIL val %d ",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005915 set_value);
5916 ret = wma_cli_set_command(pAdapter->sessionId,
5917 WMI_VDEV_PPS_DELIM_CRC_FAIL,
5918 set_value, PPS_CMD);
5919 break;
5920 }
5921
5922 case WE_PPS_GID_NSTS_ZERO:
5923 {
Krunal Sonif07bb382016-03-10 13:02:11 -08005924 if (pAdapter->device_mode != QDF_STA_MODE)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005925 return EINVAL;
Jeff Johnson99bac312016-06-28 10:38:18 -07005926 hdd_notice("WMI_VDEV_PPS_GID_NSTS_ZERO val %d ",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005927 set_value);
5928 ret = wma_cli_set_command(pAdapter->sessionId,
5929 WMI_VDEV_PPS_GID_NSTS_ZERO,
5930 set_value, PPS_CMD);
5931 break;
5932 }
5933
5934 case WE_PPS_RSSI_CHECK:
5935 {
Krunal Sonif07bb382016-03-10 13:02:11 -08005936 if (pAdapter->device_mode != QDF_STA_MODE)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005937 return EINVAL;
Jeff Johnson99bac312016-06-28 10:38:18 -07005938 hdd_notice("WMI_VDEV_PPS_RSSI_CHECK val %d ",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005939 set_value);
5940 ret = wma_cli_set_command(pAdapter->sessionId,
5941 WMI_VDEV_PPS_RSSI_CHECK,
5942 set_value, PPS_CMD);
5943 break;
5944 }
5945
5946 case WE_PPS_5G_EBT:
5947 {
Krunal Sonif07bb382016-03-10 13:02:11 -08005948 if (pAdapter->device_mode != QDF_STA_MODE)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005949 return -EINVAL;
5950
Jeff Johnson99bac312016-06-28 10:38:18 -07005951 hdd_notice("WMI_VDEV_PPS_5G_EBT val %d", set_value);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005952 ret = wma_cli_set_command(pAdapter->sessionId,
5953 WMI_VDEV_PPS_5G_EBT,
5954 set_value, PPS_CMD);
5955 break;
5956 }
5957
5958 case WE_SET_HTSMPS:
5959 {
Jeff Johnson99bac312016-06-28 10:38:18 -07005960 hdd_notice("WE_SET_HTSMPS val %d", set_value);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005961 ret = wma_cli_set_command(pAdapter->sessionId,
5962 WMI_STA_SMPS_FORCE_MODE_CMDID,
5963 set_value, VDEV_CMD);
5964 break;
5965 }
5966
5967 case WE_SET_QPOWER_MAX_PSPOLL_COUNT:
5968 {
Jeff Johnson99bac312016-06-28 10:38:18 -07005969 hdd_notice("WE_SET_QPOWER_MAX_PSPOLL_COUNT val %d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005970 set_value);
5971 ret = wma_cli_set_command(pAdapter->sessionId,
5972 WMI_STA_PS_PARAM_QPOWER_PSPOLL_COUNT,
5973 set_value, QPOWER_CMD);
5974 break;
5975 }
5976
5977 case WE_SET_QPOWER_MAX_TX_BEFORE_WAKE:
5978 {
Jeff Johnson99bac312016-06-28 10:38:18 -07005979 hdd_notice("WE_SET_QPOWER_MAX_TX_BEFORE_WAKE val %d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005980 set_value);
5981 ret = wma_cli_set_command(
5982 pAdapter->sessionId,
5983 WMI_STA_PS_PARAM_QPOWER_MAX_TX_BEFORE_WAKE,
5984 set_value, QPOWER_CMD);
5985 break;
5986 }
5987
5988 case WE_SET_QPOWER_SPEC_PSPOLL_WAKE_INTERVAL:
5989 {
Jeff Johnson99bac312016-06-28 10:38:18 -07005990 hdd_notice("WE_SET_QPOWER_SPEC_PSPOLL_WAKE_INTERVAL val %d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005991 set_value);
5992 ret = wma_cli_set_command(
5993 pAdapter->sessionId,
5994 WMI_STA_PS_PARAM_QPOWER_SPEC_PSPOLL_WAKE_INTERVAL,
5995 set_value, QPOWER_CMD);
5996 break;
5997 }
5998
5999 case WE_SET_QPOWER_SPEC_MAX_SPEC_NODATA_PSPOLL:
6000 {
Jeff Johnson99bac312016-06-28 10:38:18 -07006001 hdd_notice("WE_SET_QPOWER_SPEC_MAX_SPEC_NODATA_PSPOLL val %d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006002 set_value);
6003 ret = wma_cli_set_command(
6004 pAdapter->sessionId,
6005 WMI_STA_PS_PARAM_QPOWER_SPEC_MAX_SPEC_NODATA_PSPOLL,
6006 set_value, QPOWER_CMD);
6007 break;
6008 }
6009
6010 case WE_MCC_CONFIG_LATENCY:
6011 {
6012 cds_set_mcc_latency(pAdapter, set_value);
6013 break;
6014 }
6015
6016 case WE_MCC_CONFIG_QUOTA:
6017 {
Jeff Johnson99bac312016-06-28 10:38:18 -07006018 hdd_notice("iwpriv cmd to set MCC quota with val %dms",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006019 set_value);
6020 ret = cds_set_mcc_p2p_quota(pAdapter, set_value);
6021 break;
6022 }
6023 case WE_SET_DEBUG_LOG:
6024 {
6025 hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(pAdapter);
Nirav Shah1da77682016-05-03 20:16:39 +05306026
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006027 hdd_ctx->config->gEnableDebugLog = set_value;
6028 sme_update_connect_debug(hdd_ctx->hHal, set_value);
6029 break;
6030 }
6031 case WE_SET_EARLY_RX_ADJUST_ENABLE:
6032 {
Jeff Johnson99bac312016-06-28 10:38:18 -07006033 hdd_notice("SET early_rx enable val %d", set_value);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006034 if ((set_value == 0) || (set_value == 1))
6035 ret = wma_cli_set_command(
6036 pAdapter->sessionId,
6037 WMI_VDEV_PARAM_EARLY_RX_ADJUST_ENABLE,
6038 set_value, VDEV_CMD);
6039 else
6040 ret = -EINVAL;
6041 break;
6042 }
6043 case WE_SET_EARLY_RX_TGT_BMISS_NUM:
6044 {
Jeff Johnson99bac312016-06-28 10:38:18 -07006045 hdd_notice("SET early_rx bmiss val %d", set_value);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006046 ret = wma_cli_set_command(pAdapter->sessionId,
6047 WMI_VDEV_PARAM_EARLY_RX_TGT_BMISS_NUM,
6048 set_value, VDEV_CMD);
6049 break;
6050 }
6051 case WE_SET_EARLY_RX_BMISS_SAMPLE_CYCLE:
6052 {
Jeff Johnson99bac312016-06-28 10:38:18 -07006053 hdd_notice("SET early_rx bmiss sample cycle %d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006054 set_value);
6055 ret = wma_cli_set_command(
6056 pAdapter->sessionId,
6057 WMI_VDEV_PARAM_EARLY_RX_BMISS_SAMPLE_CYCLE,
6058 set_value, VDEV_CMD);
6059 break;
6060 }
6061 case WE_SET_EARLY_RX_SLOP_STEP:
6062 {
Jeff Johnson99bac312016-06-28 10:38:18 -07006063 hdd_notice("SET early_rx bmiss slop step val %d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006064 set_value);
6065 ret = wma_cli_set_command(pAdapter->sessionId,
6066 WMI_VDEV_PARAM_EARLY_RX_SLOP_STEP,
6067 set_value, VDEV_CMD);
6068 break;
6069 }
6070 case WE_SET_EARLY_RX_INIT_SLOP:
6071 {
Jeff Johnson99bac312016-06-28 10:38:18 -07006072 hdd_notice("SET early_rx init slop step val %d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006073 set_value);
6074 ret = wma_cli_set_command(pAdapter->sessionId,
6075 WMI_VDEV_PARAM_EARLY_RX_INIT_SLOP,
6076 set_value, VDEV_CMD);
6077 break;
6078 }
6079 case WE_SET_EARLY_RX_ADJUST_PAUSE:
6080 {
Jeff Johnson99bac312016-06-28 10:38:18 -07006081 hdd_notice("SET early_rx adjust pause %d", set_value);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006082 if ((set_value == 0) || (set_value == 1))
6083 ret = wma_cli_set_command(
6084 pAdapter->sessionId,
6085 WMI_VDEV_PARAM_EARLY_RX_ADJUST_PAUSE,
6086 set_value, VDEV_CMD);
6087 else
6088 ret = -EINVAL;
6089 break;
6090 }
6091 case WE_SET_EARLY_RX_DRIFT_SAMPLE:
6092 {
Jeff Johnson99bac312016-06-28 10:38:18 -07006093 hdd_notice("SET early_rx drift sample %d", set_value);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006094 ret = wma_cli_set_command(pAdapter->sessionId,
6095 WMI_VDEV_PARAM_EARLY_RX_DRIFT_SAMPLE,
6096 set_value, VDEV_CMD);
6097 break;
6098 }
6099 case WE_SET_SCAN_DISABLE:
6100 {
Jeff Johnson99bac312016-06-28 10:38:18 -07006101 hdd_notice("SET SCAN DISABLE %d", set_value);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006102 sme_set_scan_disable(WLAN_HDD_GET_HAL_CTX(pAdapter), set_value);
6103 break;
6104 }
Govind Singha471e5e2015-10-12 17:11:14 +05306105 case WE_START_FW_PROFILE:
6106 {
Jeff Johnson99bac312016-06-28 10:38:18 -07006107 hdd_notice("WE_START_FW_PROFILE %d", set_value);
Govind Singha471e5e2015-10-12 17:11:14 +05306108 ret = wma_cli_set_command(pAdapter->sessionId,
6109 WMI_WLAN_PROFILE_TRIGGER_CMDID,
6110 set_value, DBG_CMD);
6111 break;
6112 }
Abhishek Singh1bdb1572015-10-16 16:24:19 +05306113 case WE_SET_CHANNEL:
6114 {
Jeff Johnson99bac312016-06-28 10:38:18 -07006115 hdd_notice("Set Channel %d Session ID %d mode %d", set_value,
Abhishek Singh1bdb1572015-10-16 16:24:19 +05306116 pAdapter->sessionId, pAdapter->device_mode);
6117
Krunal Sonif07bb382016-03-10 13:02:11 -08006118 if ((QDF_STA_MODE == pAdapter->device_mode) ||
6119 (QDF_P2P_CLIENT_MODE == pAdapter->device_mode)) {
Abhishek Singh1bdb1572015-10-16 16:24:19 +05306120
6121 status = sme_ext_change_channel(hHal,
6122 set_value, pAdapter->sessionId);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05306123 if (status != QDF_STATUS_SUCCESS) {
Jeff Johnson99bac312016-06-28 10:38:18 -07006124 hdd_err("Error in change channel status %d",
Abhishek Singh1bdb1572015-10-16 16:24:19 +05306125 status);
6126 ret = -EINVAL;
6127 }
6128 } else {
Jeff Johnson99bac312016-06-28 10:38:18 -07006129 hdd_err("change channel not supported for device mode %d",
Abhishek Singh1bdb1572015-10-16 16:24:19 +05306130 pAdapter->device_mode);
6131 ret = -EINVAL;
6132 }
6133 break;
6134 }
Manishekar Chandrasekaran97e077d2016-03-23 17:10:31 +05306135 case WE_SET_CONC_SYSTEM_PREF:
6136 {
6137 hdd_info("New preference: %d", set_value);
6138 if (!((set_value >= CFG_CONC_SYSTEM_PREF_MIN) &&
6139 (set_value <= CFG_CONC_SYSTEM_PREF_MAX))) {
6140 hdd_err("Invalid system preference %d", set_value);
6141 return -EINVAL;
6142 }
Abhishek Singh1bdb1572015-10-16 16:24:19 +05306143
Manishekar Chandrasekaran97e077d2016-03-23 17:10:31 +05306144 /* hdd_ctx, hdd_ctx->config are already checked for null */
6145 hdd_ctx->config->conc_system_pref = set_value;
6146 break;
6147 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006148 default:
6149 {
Jeff Johnson99bac312016-06-28 10:38:18 -07006150 hdd_err("Invalid sub command %d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006151 sub_cmd);
6152 ret = -EINVAL;
6153 break;
6154 }
6155 }
Hanumantha Reddy Pothula2db50ed2015-11-23 10:48:33 +05306156 EXIT();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006157 return ret;
6158}
6159
6160static int iw_setint_getnone(struct net_device *dev,
6161 struct iw_request_info *info,
6162 union iwreq_data *wrqu,
6163 char *extra)
6164{
6165 int ret;
6166
6167 cds_ssr_protect(__func__);
6168 ret = __iw_setint_getnone(dev, info, wrqu, extra);
6169 cds_ssr_unprotect(__func__);
6170
6171 return ret;
6172}
6173
6174/**
Manikandan Mohandcc21ba2016-03-15 14:31:56 -07006175 * __iw_setnone_get_threeint() - return three value to up layer.
6176 *
6177 * @dev: pointer of net_device of this wireless card
6178 * @info: meta data about Request sent
6179 * @wrqu: include request info
6180 * @extra: buf used for in/Output
6181 *
6182 * Return: execute result
6183 */
6184static int __iw_setnone_get_threeint(struct net_device *dev,
6185 struct iw_request_info *info,
6186 union iwreq_data *wrqu, char *extra)
6187{
6188 int ret = 0; /* success */
6189 uint32_t *value = (int *)extra;
6190 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
6191 hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
6192
6193 ENTER_DEV(dev);
6194 ret = wlan_hdd_validate_context(hdd_ctx);
6195 if (0 != ret)
6196 return ret;
6197
Jeff Johnson99bac312016-06-28 10:38:18 -07006198 hdd_info("param = %d", value[0]);
Manikandan Mohandcc21ba2016-03-15 14:31:56 -07006199 switch (value[0]) {
6200 case WE_GET_TSF:
6201 ret = hdd_indicate_tsf(adapter, value, 3);
6202 break;
6203 default:
6204 hdd_err("Invalid IOCTL get_value command %d", value[0]);
6205 break;
6206 }
6207 return ret;
6208}
6209
6210/**
6211 * iw_setnone_get_threeint() - return three value to up layer.
6212 *
6213 * @dev: pointer of net_device of this wireless card
6214 * @info: meta data about Request sent
6215 * @wrqu: include request info
6216 * @extra: buf used for in/Output
6217 *
6218 * Return: execute result
6219 */
6220static int iw_setnone_get_threeint(struct net_device *dev,
6221 struct iw_request_info *info,
6222 union iwreq_data *wrqu, char *extra)
6223{
6224 int ret;
6225
6226 cds_ssr_protect(__func__);
6227 ret = __iw_setnone_get_threeint(dev, info, wrqu, extra);
6228 cds_ssr_unprotect(__func__);
6229
6230 return ret;
6231}
6232
6233/**
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006234 * iw_setchar_getnone() - Generic "set string" private ioctl handler
6235 * @dev: device upon which the ioctl was received
6236 * @info: ioctl request information
6237 * @wrqu: ioctl request data
6238 * @extra: ioctl extra data
6239 *
6240 * Return: 0 on success, non-zero on error
6241 */
6242static int __iw_setchar_getnone(struct net_device *dev,
6243 struct iw_request_info *info,
6244 union iwreq_data *wrqu, char *extra)
6245{
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05306246 QDF_STATUS vstatus;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006247 int sub_cmd;
6248 int ret;
6249 char *pBuffer = NULL;
6250 hdd_adapter_t *pAdapter = (netdev_priv(dev));
6251 hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(pAdapter);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006252 struct hdd_config *pConfig = hdd_ctx->config;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006253 struct iw_point s_priv_data;
6254
Jeff Johnson6ee91ee2016-02-11 18:55:30 -08006255 ENTER_DEV(dev);
6256
Mukul Sharma34777c62015-11-02 20:22:30 +05306257 if (!capable(CAP_NET_ADMIN)) {
Jeff Johnson99bac312016-06-28 10:38:18 -07006258 hdd_err("permission check failed");
Mukul Sharma34777c62015-11-02 20:22:30 +05306259 return -EPERM;
6260 }
6261
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006262 ret = wlan_hdd_validate_context(hdd_ctx);
6263 if (0 != ret)
6264 return ret;
6265
6266 /* helper function to get iwreq_data with compat handling. */
6267 if (hdd_priv_get_data(&s_priv_data, wrqu)) {
6268 return -EINVAL;
6269 }
6270
6271 /* make sure all params are correctly passed to function */
6272 if ((NULL == s_priv_data.pointer) || (0 == s_priv_data.length)) {
6273 return -EINVAL;
6274 }
6275
6276 sub_cmd = s_priv_data.flags;
6277
6278 /* ODD number is used for set, copy data using copy_from_user */
6279 pBuffer = mem_alloc_copy_from_user_helper(s_priv_data.pointer,
6280 s_priv_data.length);
6281 if (NULL == pBuffer) {
Jeff Johnson99bac312016-06-28 10:38:18 -07006282 hdd_err("mem_alloc_copy_from_user_helper fail");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006283 return -ENOMEM;
6284 }
6285
Jeff Johnson99bac312016-06-28 10:38:18 -07006286 hdd_notice("Received length %d", s_priv_data.length);
6287 hdd_notice("Received data %s", pBuffer);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006288
6289 switch (sub_cmd) {
6290 case WE_WOWL_ADD_PTRN:
Jeff Johnson99bac312016-06-28 10:38:18 -07006291 hdd_notice("ADD_PTRN");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006292 hdd_add_wowl_ptrn(pAdapter, pBuffer);
6293 break;
6294 case WE_WOWL_DEL_PTRN:
Jeff Johnson99bac312016-06-28 10:38:18 -07006295 hdd_notice("DEL_PTRN");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006296 hdd_del_wowl_ptrn(pAdapter, pBuffer);
6297 break;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006298 case WE_NEIGHBOR_REPORT_REQUEST:
6299 {
6300 tRrmNeighborReq neighborReq;
6301 tRrmNeighborRspCallbackInfo callbackInfo;
6302
6303 if (pConfig->fRrmEnable) {
Jeff Johnson99bac312016-06-28 10:38:18 -07006304 hdd_notice("Neighbor Request");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006305 neighborReq.no_ssid =
6306 (s_priv_data.length - 1) ? false : true;
6307 if (!neighborReq.no_ssid) {
6308 neighborReq.ssid.length =
6309 (s_priv_data.length - 1) >
6310 32 ? 32 : (s_priv_data.length - 1);
Anurag Chouhan600c3a02016-03-01 10:33:54 +05306311 qdf_mem_copy(neighborReq.ssid.ssId,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006312 pBuffer,
6313 neighborReq.ssid.length);
6314 }
6315
6316 callbackInfo.neighborRspCallback = NULL;
6317 callbackInfo.neighborRspCallbackContext = NULL;
6318 callbackInfo.timeout = 5000; /* 5 seconds */
6319 sme_neighbor_report_request(WLAN_HDD_GET_HAL_CTX
6320 (pAdapter),
6321 pAdapter->sessionId,
6322 &neighborReq,
6323 &callbackInfo);
6324 } else {
Jeff Johnson99bac312016-06-28 10:38:18 -07006325 hdd_err("Ignoring neighbor request as RRM is not enabled");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006326 ret = -EINVAL;
6327 }
6328 }
6329 break;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006330 case WE_SET_AP_WPS_IE:
Jeff Johnson99bac312016-06-28 10:38:18 -07006331 hdd_err("Received WE_SET_AP_WPS_IE");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006332 sme_update_p2p_ie(WLAN_HDD_GET_HAL_CTX(pAdapter), pBuffer,
6333 s_priv_data.length);
6334 break;
6335 case WE_SET_CONFIG:
6336 vstatus = hdd_execute_global_config_command(hdd_ctx, pBuffer);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05306337 if (QDF_STATUS_SUCCESS != vstatus) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006338 ret = -EINVAL;
6339 }
6340 break;
6341 default:
6342 {
Jeff Johnson99bac312016-06-28 10:38:18 -07006343 hdd_err("Invalid sub command %d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006344 sub_cmd);
6345 ret = -EINVAL;
6346 break;
6347 }
6348 }
6349 kfree(pBuffer);
Hanumantha Reddy Pothula2db50ed2015-11-23 10:48:33 +05306350 EXIT();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006351 return ret;
6352}
6353
6354static int iw_setchar_getnone(struct net_device *dev,
6355 struct iw_request_info *info,
6356 union iwreq_data *wrqu, char *extra)
6357{
6358 int ret;
6359
6360 cds_ssr_protect(__func__);
6361 ret = __iw_setchar_getnone(dev, info, wrqu, extra);
6362 cds_ssr_unprotect(__func__);
6363
6364 return ret;
6365}
6366
6367/**
6368 * iw_setnone_getint() - Generic "get integer" private ioctl handler
6369 * @dev: device upon which the ioctl was received
6370 * @info: ioctl request information
6371 * @wrqu: ioctl request data
6372 * @extra: ioctl extra data
6373 *
6374 * Return: 0 on success, non-zero on error
6375 */
6376static int __iw_setnone_getint(struct net_device *dev,
6377 struct iw_request_info *info,
6378 union iwreq_data *wrqu, char *extra)
6379{
6380 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6381 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
6382 int *value = (int *)extra;
6383 int ret;
6384 tSmeConfigParams smeConfig;
6385 hdd_context_t *hdd_ctx;
6386
Jeff Johnson6ee91ee2016-02-11 18:55:30 -08006387 ENTER_DEV(dev);
Hanumantha Reddy Pothula2db50ed2015-11-23 10:48:33 +05306388
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006389 hdd_ctx = WLAN_HDD_GET_CTX(pAdapter);
6390 ret = wlan_hdd_validate_context(hdd_ctx);
6391 if (0 != ret)
6392 return ret;
6393
6394 switch (value[0]) {
6395 case WE_GET_11D_STATE:
6396 {
6397 sme_get_config_param(hHal, &smeConfig);
6398
6399 *value = smeConfig.csrConfig.Is11dSupportEnabled;
6400
Jeff Johnson99bac312016-06-28 10:38:18 -07006401 hdd_notice("11D state=%d!!", *value);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006402
6403 break;
6404 }
6405
6406 case WE_IBSS_STATUS:
Jeff Johnson99bac312016-06-28 10:38:18 -07006407 hdd_notice("****Return IBSS Status*****");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006408 break;
6409
6410 case WE_GET_WLAN_DBG:
6411 {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05306412 qdf_trace_display();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006413 *value = 0;
6414 break;
6415 }
6416 case WE_GET_MAX_ASSOC:
6417 {
6418 if (sme_cfg_get_int
6419 (hHal, WNI_CFG_ASSOC_STA_LIMIT,
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05306420 (uint32_t *) value) != QDF_STATUS_SUCCESS) {
Jeff Johnson99bac312016-06-28 10:38:18 -07006421 hdd_warn("failed to get ini parameter, WNI_CFG_ASSOC_STA_LIMIT");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006422 ret = -EIO;
6423 }
6424 break;
6425 }
6426 case WE_GET_SAP_AUTO_CHANNEL_SELECTION:
6427 *value = (WLAN_HDD_GET_CTX(
6428 pAdapter))->config->force_sap_acs;
6429 break;
6430
6431 case WE_GET_CONCURRENCY_MODE:
6432 {
6433 *value = cds_get_concurrency_mode();
6434
Jeff Johnson99bac312016-06-28 10:38:18 -07006435 hdd_notice("concurrency mode=%d", *value);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006436 break;
6437 }
6438
6439 case WE_GET_NSS:
6440 {
6441 sme_get_config_param(hHal, &smeConfig);
6442 *value = (smeConfig.csrConfig.enable2x2 == 0) ? 1 : 2;
Jeff Johnson99bac312016-06-28 10:38:18 -07006443 hdd_notice("GET_NSS: Current NSS:%d", *value);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006444 break;
6445 }
6446
6447 case WE_GET_GTX_HT_MCS:
6448 {
Jeff Johnson99bac312016-06-28 10:38:18 -07006449 hdd_notice("GET WMI_VDEV_PARAM_GTX_HT_MCS");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006450 *value = wma_cli_get_command(pAdapter->sessionId,
6451 WMI_VDEV_PARAM_GTX_HT_MCS,
6452 GTX_CMD);
6453 break;
6454 }
6455
6456 case WE_GET_GTX_VHT_MCS:
6457 {
Jeff Johnson99bac312016-06-28 10:38:18 -07006458 hdd_notice("GET WMI_VDEV_PARAM_GTX_VHT_MCS");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006459 *value = wma_cli_get_command(pAdapter->sessionId,
6460 WMI_VDEV_PARAM_GTX_VHT_MCS,
6461 GTX_CMD);
6462 break;
6463 }
6464
6465 case WE_GET_GTX_USRCFG:
6466 {
Jeff Johnson99bac312016-06-28 10:38:18 -07006467 hdd_notice("GET WMI_VDEV_PARAM_GTX_USR_CFG");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006468 *value = wma_cli_get_command(pAdapter->sessionId,
6469 WMI_VDEV_PARAM_GTX_USR_CFG,
6470 GTX_CMD);
6471 break;
6472 }
6473
6474 case WE_GET_GTX_THRE:
6475 {
Jeff Johnson99bac312016-06-28 10:38:18 -07006476 hdd_notice("GET WMI_VDEV_PARAM_GTX_THRE");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006477 *value = wma_cli_get_command(pAdapter->sessionId,
6478 WMI_VDEV_PARAM_GTX_THRE,
6479 GTX_CMD);
6480 break;
6481 }
6482
6483 case WE_GET_GTX_MARGIN:
6484 {
Jeff Johnson99bac312016-06-28 10:38:18 -07006485 hdd_notice("GET WMI_VDEV_PARAM_GTX_MARGIN");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006486 *value = wma_cli_get_command(pAdapter->sessionId,
6487 WMI_VDEV_PARAM_GTX_MARGIN,
6488 GTX_CMD);
6489 break;
6490 }
6491
6492 case WE_GET_GTX_STEP:
6493 {
Jeff Johnson99bac312016-06-28 10:38:18 -07006494 hdd_notice("GET WMI_VDEV_PARAM_GTX_STEP");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006495 *value = wma_cli_get_command(pAdapter->sessionId,
6496 WMI_VDEV_PARAM_GTX_STEP,
6497 GTX_CMD);
6498 break;
6499 }
6500
6501 case WE_GET_GTX_MINTPC:
6502 {
Jeff Johnson99bac312016-06-28 10:38:18 -07006503 hdd_notice("GET WMI_VDEV_PARAM_GTX_MINTPC");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006504 *value = wma_cli_get_command(pAdapter->sessionId,
6505 WMI_VDEV_PARAM_GTX_MINTPC,
6506 GTX_CMD);
6507 break;
6508 }
6509
6510 case WE_GET_GTX_BWMASK:
6511 {
Jeff Johnson99bac312016-06-28 10:38:18 -07006512 hdd_notice("GET WMI_VDEV_PARAM_GTX_BW_MASK");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006513 *value = wma_cli_get_command(pAdapter->sessionId,
6514 WMI_VDEV_PARAM_GTX_BW_MASK,
6515 GTX_CMD);
6516 break;
6517 }
6518
6519 case WE_GET_LDPC:
6520 {
Jeff Johnson99bac312016-06-28 10:38:18 -07006521 hdd_notice("GET WMI_VDEV_PARAM_LDPC");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006522 *value = sme_get_ht_config(hHal, pAdapter->sessionId,
6523 WNI_CFG_HT_CAP_INFO_ADVANCE_CODING);
6524 break;
6525 }
6526
6527 case WE_GET_TX_STBC:
6528 {
Jeff Johnson99bac312016-06-28 10:38:18 -07006529 hdd_notice("GET WMI_VDEV_PARAM_TX_STBC");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006530 *value = sme_get_ht_config(hHal, pAdapter->sessionId,
6531 WNI_CFG_HT_CAP_INFO_TX_STBC);
6532 break;
6533 }
6534
6535 case WE_GET_RX_STBC:
6536 {
Jeff Johnson99bac312016-06-28 10:38:18 -07006537 hdd_notice("GET WMI_VDEV_PARAM_RX_STBC");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006538 *value = sme_get_ht_config(hHal, pAdapter->sessionId,
6539 WNI_CFG_HT_CAP_INFO_RX_STBC);
6540 break;
6541 }
6542
6543 case WE_GET_SHORT_GI:
6544 {
Jeff Johnson99bac312016-06-28 10:38:18 -07006545 hdd_notice("GET WMI_VDEV_PARAM_SGI");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006546 *value = sme_get_ht_config(hHal, pAdapter->sessionId,
6547 WNI_CFG_HT_CAP_INFO_SHORT_GI_20MHZ);
6548 break;
6549 }
6550
6551 case WE_GET_RTSCTS:
6552 {
Jeff Johnson99bac312016-06-28 10:38:18 -07006553 hdd_notice("GET WMI_VDEV_PARAM_ENABLE_RTSCTS");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006554 *value = wma_cli_get_command(pAdapter->sessionId,
6555 WMI_VDEV_PARAM_ENABLE_RTSCTS,
6556 VDEV_CMD);
6557 break;
6558 }
6559
6560 case WE_GET_CHWIDTH:
6561 {
Jeff Johnson99bac312016-06-28 10:38:18 -07006562 hdd_notice("GET WMI_VDEV_PARAM_CHWIDTH");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006563 *value = wma_cli_get_command(pAdapter->sessionId,
6564 WMI_VDEV_PARAM_CHWIDTH,
6565 VDEV_CMD);
6566 break;
6567 }
6568
6569 case WE_GET_ANI_EN_DIS:
6570 {
Jeff Johnson99bac312016-06-28 10:38:18 -07006571 hdd_notice("GET WMI_PDEV_PARAM_ANI_ENABLE");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006572 *value = wma_cli_get_command(pAdapter->sessionId,
6573 WMI_PDEV_PARAM_ANI_ENABLE,
6574 PDEV_CMD);
6575 break;
6576 }
6577
6578 case WE_GET_ANI_POLL_PERIOD:
6579 {
Jeff Johnson99bac312016-06-28 10:38:18 -07006580 hdd_notice("GET WMI_PDEV_PARAM_ANI_POLL_PERIOD");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006581 *value = wma_cli_get_command(pAdapter->sessionId,
6582 WMI_PDEV_PARAM_ANI_POLL_PERIOD,
6583 PDEV_CMD);
6584 break;
6585 }
6586
6587 case WE_GET_ANI_LISTEN_PERIOD:
6588 {
Jeff Johnson99bac312016-06-28 10:38:18 -07006589 hdd_notice("GET WMI_PDEV_PARAM_ANI_LISTEN_PERIOD");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006590 *value = wma_cli_get_command(pAdapter->sessionId,
6591 WMI_PDEV_PARAM_ANI_LISTEN_PERIOD,
6592 PDEV_CMD);
6593 break;
6594 }
6595
6596 case WE_GET_ANI_OFDM_LEVEL:
6597 {
Jeff Johnson99bac312016-06-28 10:38:18 -07006598 hdd_notice("GET WMI_PDEV_PARAM_ANI_OFDM_LEVEL");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006599 *value = wma_cli_get_command(pAdapter->sessionId,
6600 WMI_PDEV_PARAM_ANI_OFDM_LEVEL,
6601 PDEV_CMD);
6602 break;
6603 }
6604
6605 case WE_GET_ANI_CCK_LEVEL:
6606 {
Jeff Johnson99bac312016-06-28 10:38:18 -07006607 hdd_notice("GET WMI_PDEV_PARAM_ANI_CCK_LEVEL");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006608 *value = wma_cli_get_command(pAdapter->sessionId,
6609 WMI_PDEV_PARAM_ANI_CCK_LEVEL,
6610 PDEV_CMD);
6611 break;
6612 }
6613
6614 case WE_GET_DYNAMIC_BW:
6615 {
Jeff Johnson99bac312016-06-28 10:38:18 -07006616 hdd_notice("GET WMI_PDEV_PARAM_ANI_CCK_LEVEL");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006617 *value = wma_cli_get_command(pAdapter->sessionId,
6618 WMI_PDEV_PARAM_DYNAMIC_BW,
6619 PDEV_CMD);
6620 break;
6621 }
6622
6623 case WE_GET_11N_RATE:
6624 {
Jeff Johnson99bac312016-06-28 10:38:18 -07006625 hdd_notice("GET WMI_VDEV_PARAM_FIXED_RATE");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006626 *value = wma_cli_get_command(pAdapter->sessionId,
6627 WMI_VDEV_PARAM_FIXED_RATE,
6628 VDEV_CMD);
6629 break;
6630 }
6631
6632 case WE_GET_AMPDU:
6633 {
Jeff Johnson99bac312016-06-28 10:38:18 -07006634 hdd_notice("GET AMPDU");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006635 *value = wma_cli_get_command(pAdapter->sessionId,
6636 GEN_VDEV_PARAM_AMPDU,
6637 GEN_CMD);
6638 break;
6639 }
6640
6641 case WE_GET_AMSDU:
6642 {
Jeff Johnson99bac312016-06-28 10:38:18 -07006643 hdd_notice("GET AMSDU");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006644 *value = wma_cli_get_command(pAdapter->sessionId,
6645 GEN_VDEV_PARAM_AMSDU,
6646 GEN_CMD);
6647 break;
6648 }
6649
Varun Reddy Yeturu5ab47462016-05-08 18:08:11 -07006650 case WE_GET_ROAM_SYNCH_DELAY:
6651 {
Jeff Johnson99bac312016-06-28 10:38:18 -07006652 hdd_notice("GET ROAM SYNCH DELAY");
Varun Reddy Yeturu5ab47462016-05-08 18:08:11 -07006653 *value = wma_cli_get_command(pAdapter->sessionId,
6654 GEN_VDEV_ROAM_SYNCH_DELAY,
6655 GEN_CMD);
6656 break;
6657 }
6658
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006659 case WE_GET_BURST_ENABLE:
6660 {
Jeff Johnson99bac312016-06-28 10:38:18 -07006661 hdd_notice("GET Burst enable value");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006662 *value = wma_cli_get_command(pAdapter->sessionId,
6663 WMI_PDEV_PARAM_BURST_ENABLE,
6664 PDEV_CMD);
6665 break;
6666 }
6667 case WE_GET_BURST_DUR:
6668 {
Jeff Johnson99bac312016-06-28 10:38:18 -07006669 hdd_notice("GET Burst Duration value");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006670 *value = wma_cli_get_command(pAdapter->sessionId,
6671 WMI_PDEV_PARAM_BURST_DUR,
6672 PDEV_CMD);
6673 break;
6674 }
6675
6676 case WE_GET_TX_CHAINMASK:
6677 {
Jeff Johnson99bac312016-06-28 10:38:18 -07006678 hdd_notice("GET WMI_PDEV_PARAM_TX_CHAIN_MASK");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006679 *value = wma_cli_get_command(pAdapter->sessionId,
6680 WMI_PDEV_PARAM_TX_CHAIN_MASK,
6681 PDEV_CMD);
6682 break;
6683 }
6684
6685 case WE_GET_RX_CHAINMASK:
6686 {
Jeff Johnson99bac312016-06-28 10:38:18 -07006687 hdd_notice("GET WMI_PDEV_PARAM_RX_CHAIN_MASK");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006688 *value = wma_cli_get_command(pAdapter->sessionId,
6689 WMI_PDEV_PARAM_RX_CHAIN_MASK,
6690 PDEV_CMD);
6691 break;
6692 }
6693
6694 case WE_GET_TXPOW_2G:
6695 {
6696 uint32_t txpow2g = 0;
6697 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Jeff Johnson99bac312016-06-28 10:38:18 -07006698 hdd_notice("GET WMI_PDEV_PARAM_TXPOWER_LIMIT2G");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006699 *value = wma_cli_get_command(pAdapter->sessionId,
6700 WMI_PDEV_PARAM_TXPOWER_LIMIT2G,
6701 PDEV_CMD);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05306702 if (QDF_STATUS_SUCCESS !=
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006703 sme_cfg_get_int(hHal, WNI_CFG_CURRENT_TX_POWER_LEVEL,
6704 &txpow2g)) {
6705 return -EIO;
6706 }
Jeff Johnson99bac312016-06-28 10:38:18 -07006707 hdd_notice("2G tx_power %d", txpow2g);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006708 break;
6709 }
6710
6711 case WE_GET_TXPOW_5G:
6712 {
6713 uint32_t txpow5g = 0;
6714 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Jeff Johnson99bac312016-06-28 10:38:18 -07006715 hdd_notice("GET WMI_PDEV_PARAM_TXPOWER_LIMIT5G");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006716 *value = wma_cli_get_command(pAdapter->sessionId,
6717 WMI_PDEV_PARAM_TXPOWER_LIMIT5G,
6718 PDEV_CMD);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05306719 if (QDF_STATUS_SUCCESS !=
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006720 sme_cfg_get_int(hHal, WNI_CFG_CURRENT_TX_POWER_LEVEL,
6721 &txpow5g)) {
6722 return -EIO;
6723 }
Jeff Johnson99bac312016-06-28 10:38:18 -07006724 hdd_notice("5G tx_power %d", txpow5g);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006725 break;
6726 }
6727
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006728 case WE_GET_PPS_PAID_MATCH:
6729 {
Jeff Johnson99bac312016-06-28 10:38:18 -07006730 hdd_notice("GET WMI_VDEV_PPS_PAID_MATCH");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006731 *value = wma_cli_get_command(pAdapter->sessionId,
6732 WMI_VDEV_PPS_PAID_MATCH,
6733 PPS_CMD);
6734 break;
6735 }
6736
6737 case WE_GET_PPS_GID_MATCH:
6738 {
Jeff Johnson99bac312016-06-28 10:38:18 -07006739 hdd_notice("GET WMI_VDEV_PPS_GID_MATCH");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006740 *value = wma_cli_get_command(pAdapter->sessionId,
6741 WMI_VDEV_PPS_GID_MATCH,
6742 PPS_CMD);
6743 break;
6744 }
6745
6746 case WE_GET_PPS_EARLY_TIM_CLEAR:
6747 {
Jeff Johnson99bac312016-06-28 10:38:18 -07006748 hdd_notice("GET WMI_VDEV_PPS_EARLY_TIM_CLEAR");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006749 *value = wma_cli_get_command(pAdapter->sessionId,
6750 WMI_VDEV_PPS_EARLY_TIM_CLEAR,
6751 PPS_CMD);
6752 break;
6753 }
6754
6755 case WE_GET_PPS_EARLY_DTIM_CLEAR:
6756 {
Jeff Johnson99bac312016-06-28 10:38:18 -07006757 hdd_notice("GET WMI_VDEV_PPS_EARLY_DTIM_CLEAR");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006758 *value = wma_cli_get_command(pAdapter->sessionId,
6759 WMI_VDEV_PPS_EARLY_DTIM_CLEAR,
6760 PPS_CMD);
6761 break;
6762 }
6763
6764 case WE_GET_PPS_EOF_PAD_DELIM:
6765 {
Jeff Johnson99bac312016-06-28 10:38:18 -07006766 hdd_notice("GET WMI_VDEV_PPS_EOF_PAD_DELIM");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006767 *value = wma_cli_get_command(pAdapter->sessionId,
6768 WMI_VDEV_PPS_EOF_PAD_DELIM,
6769 PPS_CMD);
6770 break;
6771 }
6772
6773 case WE_GET_PPS_MACADDR_MISMATCH:
6774 {
Jeff Johnson99bac312016-06-28 10:38:18 -07006775 hdd_notice("GET WMI_VDEV_PPS_MACADDR_MISMATCH");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006776 *value = wma_cli_get_command(pAdapter->sessionId,
6777 WMI_VDEV_PPS_MACADDR_MISMATCH,
6778 PPS_CMD);
6779 break;
6780 }
6781
6782 case WE_GET_PPS_DELIM_CRC_FAIL:
6783 {
Jeff Johnson99bac312016-06-28 10:38:18 -07006784 hdd_notice("GET WMI_VDEV_PPS_DELIM_CRC_FAIL");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006785 *value = wma_cli_get_command(pAdapter->sessionId,
6786 WMI_VDEV_PPS_DELIM_CRC_FAIL,
6787 PPS_CMD);
6788 break;
6789 }
6790
6791 case WE_GET_PPS_GID_NSTS_ZERO:
6792 {
Jeff Johnson99bac312016-06-28 10:38:18 -07006793 hdd_notice("GET WMI_VDEV_PPS_GID_NSTS_ZERO");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006794 *value = wma_cli_get_command(pAdapter->sessionId,
6795 WMI_VDEV_PPS_GID_NSTS_ZERO,
6796 PPS_CMD);
6797 break;
6798 }
6799
6800 case WE_GET_PPS_RSSI_CHECK:
6801 {
6802
Jeff Johnson99bac312016-06-28 10:38:18 -07006803 hdd_notice("GET WMI_VDEV_PPS_RSSI_CHECK");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006804 *value = wma_cli_get_command(pAdapter->sessionId,
6805 WMI_VDEV_PPS_RSSI_CHECK,
6806 PPS_CMD);
6807 break;
6808 }
6809
6810 case WE_GET_QPOWER_MAX_PSPOLL_COUNT:
6811 {
Jeff Johnson99bac312016-06-28 10:38:18 -07006812 hdd_notice("WE_GET_QPOWER_MAX_PSPOLL_COUNT");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006813 *value = wma_cli_get_command(pAdapter->sessionId,
6814 WMI_STA_PS_PARAM_QPOWER_PSPOLL_COUNT,
6815 QPOWER_CMD);
6816 break;
6817 }
6818
6819 case WE_GET_QPOWER_MAX_TX_BEFORE_WAKE:
6820 {
Jeff Johnson99bac312016-06-28 10:38:18 -07006821 hdd_notice("WE_GET_QPOWER_MAX_TX_BEFORE_WAKE");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006822 *value = wma_cli_get_command(pAdapter->sessionId,
6823 WMI_STA_PS_PARAM_QPOWER_MAX_TX_BEFORE_WAKE,
6824 QPOWER_CMD);
6825 break;
6826 }
6827
6828 case WE_GET_QPOWER_SPEC_PSPOLL_WAKE_INTERVAL:
6829 {
Jeff Johnson99bac312016-06-28 10:38:18 -07006830 hdd_notice("WE_GET_QPOWER_SPEC_PSPOLL_WAKE_INTERVAL");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006831 *value = wma_cli_get_command(pAdapter->sessionId,
6832 WMI_STA_PS_PARAM_QPOWER_SPEC_PSPOLL_WAKE_INTERVAL,
6833 QPOWER_CMD);
6834 break;
6835 }
6836
6837 case WE_GET_QPOWER_SPEC_MAX_SPEC_NODATA_PSPOLL:
6838 {
Jeff Johnson99bac312016-06-28 10:38:18 -07006839 hdd_notice("WE_GET_QPOWER_MAX_PSPOLL_COUNT");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006840 *value = wma_cli_get_command(pAdapter->sessionId,
6841 WMI_STA_PS_PARAM_QPOWER_SPEC_MAX_SPEC_NODATA_PSPOLL,
6842 QPOWER_CMD);
6843 break;
6844 }
Manikandan Mohandcc21ba2016-03-15 14:31:56 -07006845 case WE_CAP_TSF:
6846 ret = hdd_capture_tsf(pAdapter, (uint32_t *)value, 1);
6847 break;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006848 case WE_GET_TEMPERATURE:
6849 {
Jeff Johnson99bac312016-06-28 10:38:18 -07006850 hdd_notice("WE_GET_TEMPERATURE");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006851 ret = wlan_hdd_get_temperature(pAdapter, value);
6852 break;
6853 }
6854 default:
6855 {
Jeff Johnson99bac312016-06-28 10:38:18 -07006856 hdd_err("Invalid IOCTL get_value command %d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006857 value[0]);
6858 break;
6859 }
6860 }
Hanumantha Reddy Pothula2db50ed2015-11-23 10:48:33 +05306861 EXIT();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006862 return ret;
6863}
6864
6865static int iw_setnone_getint(struct net_device *dev,
6866 struct iw_request_info *info,
6867 union iwreq_data *wrqu, char *extra)
6868{
6869 int ret;
6870
6871 cds_ssr_protect(__func__);
6872 ret = __iw_setnone_getint(dev, info, wrqu, extra);
6873 cds_ssr_unprotect(__func__);
6874
6875 return ret;
6876}
6877
6878/**
6879 * iw_set_three_ints_getnone() - Generic "set 3 params" private ioctl handler
6880 * @dev: device upon which the ioctl was received
6881 * @info: ioctl request information
6882 * @wrqu: ioctl request data
6883 * @extra: ioctl extra data
6884 *
6885 * Return: 0 on success, non-zero on error
6886 */
6887static int __iw_set_three_ints_getnone(struct net_device *dev,
6888 struct iw_request_info *info,
6889 union iwreq_data *wrqu, char *extra)
6890{
6891 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6892 int *value = (int *)extra;
6893 int sub_cmd = value[0];
6894 int ret;
6895 hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(pAdapter);
6896
Jeff Johnson6ee91ee2016-02-11 18:55:30 -08006897 ENTER_DEV(dev);
Hanumantha Reddy Pothula2db50ed2015-11-23 10:48:33 +05306898
Rajeev Kumar2cce8a82016-04-14 15:10:41 -07006899 if (!capable(CAP_NET_ADMIN)) {
Jeff Johnson99bac312016-06-28 10:38:18 -07006900 hdd_err("permission check failed");
Rajeev Kumar2cce8a82016-04-14 15:10:41 -07006901 return -EPERM;
6902 }
6903
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006904 ret = wlan_hdd_validate_context(hdd_ctx);
6905 if (0 != ret)
6906 return ret;
6907
6908 switch (sub_cmd) {
6909
6910 case WE_SET_WLAN_DBG:
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05306911 qdf_trace_set_value(value[1], value[2], value[3]);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006912 break;
6913 case WE_SET_DP_TRACE:
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05306914 qdf_dp_trace_set_value(value[1], value[2], value[3]);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006915 break;
6916
6917 /* value[3] the acs band is not required as start and end channels are
6918 * enough but this cmd is maintained under set three ints for historic
6919 * reasons.
6920 */
6921 case WE_SET_SAP_CHANNELS:
6922 if (wlan_hdd_validate_operation_channel(pAdapter, value[1]) !=
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05306923 QDF_STATUS_SUCCESS ||
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006924 wlan_hdd_validate_operation_channel(pAdapter,
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05306925 value[2]) != QDF_STATUS_SUCCESS) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006926 ret = -EINVAL;
6927 } else {
6928 hdd_ctx->config->force_sap_acs_st_ch = value[1];
6929 hdd_ctx->config->force_sap_acs_end_ch = value[2];
6930 }
6931 break;
6932 case WE_SET_DUAL_MAC_SCAN_CONFIG:
6933 hdd_debug("Ioctl to set dual mac scan config");
6934 if (hdd_ctx->config->dual_mac_feature_disable) {
6935 hdd_err("Dual mac feature is disabled from INI");
6936 return -EPERM;
6937 }
6938 hdd_debug("%d %d %d", value[1], value[2], value[3]);
Tushnim Bhattacharyya4adb3682016-01-07 15:07:12 -08006939 cds_set_dual_mac_scan_config(value[1], value[2], value[3]);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006940 break;
6941 default:
Jeff Johnson99bac312016-06-28 10:38:18 -07006942 hdd_err("Invalid IOCTL command %d", sub_cmd);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006943 break;
6944
6945 }
Hanumantha Reddy Pothula2db50ed2015-11-23 10:48:33 +05306946 EXIT();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006947 return ret;
6948}
6949
6950int iw_set_three_ints_getnone(struct net_device *dev,
6951 struct iw_request_info *info,
6952 union iwreq_data *wrqu, char *extra)
6953{
6954 int ret;
6955
6956 cds_ssr_protect(__func__);
6957 ret = __iw_set_three_ints_getnone(dev, info, wrqu, extra);
6958 cds_ssr_unprotect(__func__);
6959
6960 return ret;
6961}
6962
6963/**
6964 * hdd_connection_state_string() - Get connection state string
6965 * @connection_state: enum to be converted to a string
6966 *
6967 * Return: the string equivalent of @connection_state
6968 */
6969static const char *
6970hdd_connection_state_string(eConnectionState connection_state)
6971{
6972 switch (connection_state) {
6973 CASE_RETURN_STRING(eConnectionState_NotConnected);
6974 CASE_RETURN_STRING(eConnectionState_Connecting);
6975 CASE_RETURN_STRING(eConnectionState_Associated);
6976 CASE_RETURN_STRING(eConnectionState_IbssDisconnected);
6977 CASE_RETURN_STRING(eConnectionState_IbssConnected);
6978 CASE_RETURN_STRING(eConnectionState_Disconnecting);
6979 default:
6980 return "UNKNOWN";
6981 }
6982}
6983
6984/**
6985 * iw_get_char_setnone() - Generic "get string" private ioctl handler
6986 * @dev: device upon which the ioctl was received
6987 * @info: ioctl request information
6988 * @wrqu: ioctl request data
6989 * @extra: ioctl extra data
6990 *
6991 * Return: 0 on success, non-zero on error
6992 */
6993static int __iw_get_char_setnone(struct net_device *dev,
6994 struct iw_request_info *info,
6995 union iwreq_data *wrqu, char *extra)
6996{
6997 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6998 int sub_cmd = wrqu->data.flags;
6999 hdd_context_t *hdd_ctx;
7000 int ret;
7001#ifdef WLAN_FEATURE_11W
7002 hdd_wext_state_t *pWextState;
7003#endif
7004
7005#ifdef WLAN_FEATURE_11W
7006 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
7007#endif
7008
Jeff Johnson6ee91ee2016-02-11 18:55:30 -08007009 ENTER_DEV(dev);
Hanumantha Reddy Pothula2db50ed2015-11-23 10:48:33 +05307010
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007011 hdd_ctx = WLAN_HDD_GET_CTX(pAdapter);
7012 ret = wlan_hdd_validate_context(hdd_ctx);
7013 if (0 != ret)
7014 return ret;
7015
7016 switch (sub_cmd) {
7017 case WE_WLAN_VERSION:
7018 {
Arun Khandavallia96c2c02016-05-17 19:15:34 +05307019 hdd_wlan_get_version(hdd_ctx, wrqu, extra);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007020 break;
7021 }
7022
7023 case WE_GET_STATS:
7024 {
7025 hdd_wlan_get_stats(pAdapter, &(wrqu->data.length),
7026 extra, WE_MAX_STR_LEN);
7027 break;
7028 }
7029
Govind Singha471e5e2015-10-12 17:11:14 +05307030 case WE_LIST_FW_PROFILE:
7031 hdd_wlan_list_fw_profile(&(wrqu->data.length),
7032 extra, WE_MAX_STR_LEN);
7033 break;
7034
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007035 /* The case prints the current state of the HDD, SME, CSR, PE,
7036 * TL it can be extended for WDI Global State as well. And
7037 * currently it only checks P2P_CLIENT adapter. P2P_DEVICE
7038 * and P2P_GO have not been added as of now.
7039 */
7040 case WE_GET_STATES:
7041 {
7042 int buf = 0, len = 0;
7043 int adapter_num = 0;
7044 int count = 0, check = 1;
7045
7046 tHalHandle hHal = NULL;
7047 tpAniSirGlobal pMac = NULL;
7048 hdd_station_ctx_t *pHddStaCtx = NULL;
7049
7050 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7051 hdd_adapter_t *useAdapter = NULL;
7052
7053 /* Print wlan0 or p2p0 states based on the adapter_num
7054 * by using the correct adapter
7055 */
7056 while (adapter_num < 2) {
7057 if (WLAN_ADAPTER == adapter_num) {
7058 useAdapter = pAdapter;
7059 buf =
7060 scnprintf(extra + len,
7061 WE_MAX_STR_LEN - len,
7062 "\n\n wlan0 States:-");
7063 len += buf;
7064 } else if (P2P_ADAPTER == adapter_num) {
7065 buf =
7066 scnprintf(extra + len,
7067 WE_MAX_STR_LEN - len,
7068 "\n\n p2p0 States:-");
7069 len += buf;
7070
7071 if (!pHddCtx) {
7072 buf =
7073 scnprintf(extra + len,
7074 WE_MAX_STR_LEN -
7075 len,
7076 "\n pHddCtx is NULL");
7077 len += buf;
7078 break;
7079 }
7080
7081 /* Printing p2p0 states only in the
7082 * case when the device is configured
7083 * as a p2p_client
7084 */
7085 useAdapter =
7086 hdd_get_adapter(pHddCtx,
Krunal Sonif07bb382016-03-10 13:02:11 -08007087 QDF_P2P_CLIENT_MODE);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007088 if (!useAdapter) {
7089 buf =
7090 scnprintf(extra + len,
7091 WE_MAX_STR_LEN -
7092 len,
7093 "\n Device not configured as P2P_CLIENT.");
7094 len += buf;
7095 break;
7096 }
7097 }
7098
7099 hHal = WLAN_HDD_GET_HAL_CTX(useAdapter);
7100 if (!hHal) {
7101 buf =
7102 scnprintf(extra + len,
7103 WE_MAX_STR_LEN - len,
7104 "\n pMac is NULL");
7105 len += buf;
7106 break;
7107 }
7108 pMac = PMAC_STRUCT(hHal);
7109 if (!pMac) {
7110 buf =
7111 scnprintf(extra + len,
7112 WE_MAX_STR_LEN - len,
7113 "\n pMac is NULL");
7114 len += buf;
7115 break;
7116 }
7117 pHddStaCtx =
7118 WLAN_HDD_GET_STATION_CTX_PTR(useAdapter);
7119
7120
7121 buf =
7122 scnprintf(extra + len, WE_MAX_STR_LEN - len,
7123 "\n HDD Conn State - %s "
7124 "\n \n SME State:"
7125 "\n Neighbour Roam State - %s"
7126 "\n CSR State - %s"
7127 "\n CSR Substate - %s",
7128 hdd_connection_state_string
7129 (pHddStaCtx->conn_info.connState),
7130 mac_trace_get_neighbour_roam_state
7131 (sme_get_neighbor_roam_state
7132 (hHal, useAdapter->sessionId)),
7133 mac_trace_getcsr_roam_state
7134 (sme_get_current_roam_state
7135 (hHal, useAdapter->sessionId)),
7136 mac_trace_getcsr_roam_sub_state
7137 (sme_get_current_roam_sub_state
7138 (hHal, useAdapter->sessionId))
7139 );
7140 len += buf;
7141 adapter_num++;
7142 }
7143
Mukul Sharma81661ae2015-10-30 20:26:02 +05307144 if (hHal) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007145 /* Printing Lim State starting with global lim states */
7146 buf =
7147 scnprintf(extra + len, WE_MAX_STR_LEN - len,
7148 "\n \n LIM STATES:-"
7149 "\n Global Sme State - %s "
7150 "\n Global mlm State - %s " "\n",
7151 mac_trace_get_lim_sme_state
7152 (sme_get_lim_sme_state(hHal)),
7153 mac_trace_get_lim_mlm_state
7154 (sme_get_lim_sme_state(hHal))
7155 );
7156 len += buf;
7157
7158 /* Printing the PE Sme and Mlm states for valid lim sessions */
7159 while (check < 3 && count < 255) {
7160 if (sme_is_lim_session_valid(hHal, count)) {
7161 buf =
7162 scnprintf(extra + len,
7163 WE_MAX_STR_LEN -
7164 len,
7165 "\n Lim Valid Session %d:-"
7166 "\n PE Sme State - %s "
7167 "\n PE Mlm State - %s "
7168 "\n", check,
7169 mac_trace_get_lim_sme_state
7170 (sme_get_lim_sme_session_state
7171 (hHal, count)),
7172 mac_trace_get_lim_mlm_state
7173 (sme_get_lim_mlm_session_state
7174 (hHal, count))
7175 );
7176
7177 len += buf;
7178 check++;
7179 }
7180 count++;
7181 }
7182 }
7183
7184 wrqu->data.length = strlen(extra) + 1;
7185 break;
7186 }
7187
7188 case WE_GET_CFG:
7189 {
Jeff Johnson99bac312016-06-28 10:38:18 -07007190 hdd_notice("Printing CLD global INI Config");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007191 hdd_cfg_get_global_config(WLAN_HDD_GET_CTX(pAdapter),
7192 extra,
7193 QCSAP_IOCTL_MAX_STR_LEN);
7194 wrqu->data.length = strlen(extra) + 1;
7195 break;
7196 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007197 case WE_GET_RSSI:
7198 {
7199 int8_t s7Rssi = 0;
7200 wlan_hdd_get_rssi(pAdapter, &s7Rssi);
7201 snprintf(extra, WE_MAX_STR_LEN, "rssi=%d", s7Rssi);
7202 wrqu->data.length = strlen(extra) + 1;
7203 break;
7204 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007205
7206 case WE_GET_WMM_STATUS:
7207 {
7208 snprintf(extra, WE_MAX_STR_LEN,
7209 "\nDir: 0=up, 1=down, 3=both\n"
7210 "|------------------------|\n"
7211 "|AC | ACM |Admitted| Dir |\n"
7212 "|------------------------|\n"
7213 "|VO | %d | %3s | %d |\n"
7214 "|VI | %d | %3s | %d |\n"
7215 "|BE | %d | %3s | %d |\n"
7216 "|BK | %d | %3s | %d |\n"
7217 "|------------------------|\n",
7218 pAdapter->hddWmmStatus.
7219 wmmAcStatus[SME_AC_VO].wmmAcAccessRequired,
7220 pAdapter->hddWmmStatus.
7221 wmmAcStatus[SME_AC_VO].
7222 wmmAcAccessAllowed ? "YES" : "NO",
7223 pAdapter->hddWmmStatus.
7224 wmmAcStatus[SME_AC_VO].wmmAcTspecInfo.
7225 ts_info.direction,
7226 pAdapter->hddWmmStatus.
7227 wmmAcStatus[SME_AC_VI].wmmAcAccessRequired,
7228 pAdapter->hddWmmStatus.
7229 wmmAcStatus[SME_AC_VI].
7230 wmmAcAccessAllowed ? "YES" : "NO",
7231 pAdapter->hddWmmStatus.
7232 wmmAcStatus[SME_AC_VI].wmmAcTspecInfo.
7233 ts_info.direction,
7234 pAdapter->hddWmmStatus.
7235 wmmAcStatus[SME_AC_BE].wmmAcAccessRequired,
7236 pAdapter->hddWmmStatus.
7237 wmmAcStatus[SME_AC_BE].
7238 wmmAcAccessAllowed ? "YES" : "NO",
7239 pAdapter->hddWmmStatus.
7240 wmmAcStatus[SME_AC_BE].wmmAcTspecInfo.
7241 ts_info.direction,
7242 pAdapter->hddWmmStatus.
7243 wmmAcStatus[SME_AC_BK].wmmAcAccessRequired,
7244 pAdapter->hddWmmStatus.
7245 wmmAcStatus[SME_AC_BK].
7246 wmmAcAccessAllowed ? "YES" : "NO",
7247 pAdapter->hddWmmStatus.
7248 wmmAcStatus[SME_AC_BK].wmmAcTspecInfo.
7249 ts_info.direction);
7250
7251 wrqu->data.length = strlen(extra) + 1;
7252 break;
7253 }
7254 case WE_GET_CHANNEL_LIST:
7255 {
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05307256 QDF_STATUS status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007257 uint8_t i, len;
7258 char *buf;
7259 uint8_t ubuf[WNI_CFG_COUNTRY_CODE_LEN];
7260 uint8_t ubuf_len = WNI_CFG_COUNTRY_CODE_LEN;
7261 hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(pAdapter);
7262
7263 tChannelListInfo channel_list;
7264
7265 memset(&channel_list, 0, sizeof(channel_list));
7266 status =
7267 iw_softap_get_channel_list(dev, info, wrqu,
7268 (char *)&channel_list);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05307269 if (!QDF_IS_STATUS_SUCCESS(status)) {
Jeff Johnson99bac312016-06-28 10:38:18 -07007270 hdd_err("GetChannelList Failed!!!");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007271 return -EINVAL;
7272 }
7273 buf = extra;
7274 /*
7275 * Maximum channels = WNI_CFG_VALID_CHANNEL_LIST_LEN.
7276 * Maximum buffer needed = 5 * number of channels.
7277 * Check ifsufficient buffer is available and then
7278 * proceed to fill the buffer.
7279 */
7280 if (WE_MAX_STR_LEN <
7281 (5 * WNI_CFG_VALID_CHANNEL_LIST_LEN)) {
Jeff Johnson99bac312016-06-28 10:38:18 -07007282 hdd_err("Insufficient Buffer to populate channel list");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007283 return -EINVAL;
7284 }
7285 len = scnprintf(buf, WE_MAX_STR_LEN, "%u ",
7286 channel_list.num_channels);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05307287 if (QDF_STATUS_SUCCESS == sme_get_country_code(hdd_ctx->hHal,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007288 ubuf, &ubuf_len)) {
7289 /* Printing Country code in getChannelList */
7290 for (i = 0; i < (ubuf_len - 1); i++)
7291 len += scnprintf(buf + len,
7292 WE_MAX_STR_LEN - len,
7293 "%c", ubuf[i]);
7294 }
7295 for (i = 0; i < channel_list.num_channels; i++) {
7296 len +=
7297 scnprintf(buf + len, WE_MAX_STR_LEN - len,
7298 " %u", channel_list.channels[i]);
7299 }
7300 wrqu->data.length = strlen(extra) + 1;
7301
7302 break;
7303 }
7304#ifdef FEATURE_WLAN_TDLS
7305 case WE_GET_TDLS_PEERS:
7306 {
7307 wrqu->data.length =
7308 wlan_hdd_tdls_get_all_peers(pAdapter, extra,
7309 WE_MAX_STR_LEN) + 1;
7310 break;
7311 }
7312#endif
7313#ifdef WLAN_FEATURE_11W
7314 case WE_GET_11W_INFO:
7315 {
Jeff Johnson99bac312016-06-28 10:38:18 -07007316 hdd_err("WE_GET_11W_ENABLED = %d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007317 pWextState->roamProfile.MFPEnabled);
7318
7319 snprintf(extra, WE_MAX_STR_LEN,
7320 "\n BSSID %02X:%02X:%02X:%02X:%02X:%02X, Is PMF Assoc? %d"
7321 "\n Number of Unprotected Disassocs %d"
7322 "\n Number of Unprotected Deauths %d",
7323 pWextState->roamProfile.BSSIDs.bssid->bytes[0],
7324 pWextState->roamProfile.BSSIDs.bssid->bytes[1],
7325 pWextState->roamProfile.BSSIDs.bssid->bytes[2],
7326 pWextState->roamProfile.BSSIDs.bssid->bytes[3],
7327 pWextState->roamProfile.BSSIDs.bssid->bytes[4],
7328 pWextState->roamProfile.BSSIDs.bssid->bytes[5],
7329 pWextState->roamProfile.MFPEnabled,
7330 pAdapter->hdd_stats.hddPmfStats.
7331 numUnprotDisassocRx,
7332 pAdapter->hdd_stats.hddPmfStats.
7333 numUnprotDeauthRx);
7334
7335 wrqu->data.length = strlen(extra) + 1;
7336 break;
7337 }
7338#endif
Rajeev Kumar8e3e2832015-11-06 16:02:54 -08007339 case WE_GET_IBSS_STA_INFO:
7340 {
7341 hdd_station_ctx_t *pHddStaCtx =
7342 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7343 int idx = 0;
7344 int length = 0, buf = 0;
7345
Naveen Rawatc45d1622016-07-05 12:20:09 -07007346 for (idx = 0; idx < MAX_PEERS; idx++) {
Rajeev Kumar8e3e2832015-11-06 16:02:54 -08007347 if (0 != pHddStaCtx->conn_info.staId[idx]) {
7348 buf = snprintf
7349 ((extra + length),
7350 WE_MAX_STR_LEN - length,
7351 "\n%d .%02x:%02x:%02x:%02x:%02x:%02x\n",
7352 pHddStaCtx->conn_info.staId[idx],
7353 pHddStaCtx->conn_info.
7354 peerMacAddress[idx].bytes[0],
7355 pHddStaCtx->conn_info.
7356 peerMacAddress[idx].bytes[1],
7357 pHddStaCtx->conn_info.
7358 peerMacAddress[idx].bytes[2],
7359 pHddStaCtx->conn_info.
7360 peerMacAddress[idx].bytes[3],
7361 pHddStaCtx->conn_info.
7362 peerMacAddress[idx].bytes[4],
7363 pHddStaCtx->conn_info.
7364 peerMacAddress[idx].bytes[5]
7365 );
7366 length += buf;
7367 }
7368 }
7369 wrqu->data.length = strlen(extra) + 1;
7370 break;
7371 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007372 case WE_GET_PHYMODE:
7373 {
7374 bool ch_bond24 = false, ch_bond5g = false;
7375 hdd_context_t *hddctx = WLAN_HDD_GET_CTX(pAdapter);
7376 tHalHandle hal = WLAN_HDD_GET_HAL_CTX(pAdapter);
7377 eCsrPhyMode phymode;
7378 eCsrBand currBand;
7379 tSmeConfigParams smeconfig;
7380
7381 sme_get_config_param(hal, &smeconfig);
7382 if (WNI_CFG_CHANNEL_BONDING_MODE_DISABLE !=
7383 smeconfig.csrConfig.channelBondingMode24GHz)
7384 ch_bond24 = true;
7385
7386 if (WNI_CFG_CHANNEL_BONDING_MODE_DISABLE !=
7387 smeconfig.csrConfig.channelBondingMode5GHz)
7388 ch_bond5g = true;
7389
7390 phymode = sme_get_phy_mode(hal);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05307391 if ((QDF_STATUS_SUCCESS !=
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007392 sme_get_freq_band(hal, &currBand))) {
Jeff Johnson99bac312016-06-28 10:38:18 -07007393 hdd_notice("Failed to get current band config");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007394 return -EIO;
7395 }
7396
7397 switch (phymode) {
7398 case eCSR_DOT11_MODE_AUTO:
7399 snprintf(extra, WE_MAX_STR_LEN, "AUTO MODE");
7400 break;
7401 case eCSR_DOT11_MODE_11n:
7402 case eCSR_DOT11_MODE_11n_ONLY:
7403 if (currBand == eCSR_BAND_24) {
7404 if (ch_bond24)
7405 snprintf(extra, WE_MAX_STR_LEN,
7406 "11NGHT40");
7407 else
7408 snprintf(extra, WE_MAX_STR_LEN,
7409 "11NGHT20");
7410 } else if (currBand == eCSR_BAND_5G) {
7411 if (ch_bond5g)
7412 snprintf(extra, WE_MAX_STR_LEN,
7413 "11NAHT40");
7414 else
7415 snprintf(extra, WE_MAX_STR_LEN,
7416 "11NAHT20");
7417 } else {
7418 snprintf(extra, WE_MAX_STR_LEN, "11N");
7419 }
7420 break;
7421 case eCSR_DOT11_MODE_abg:
7422 snprintf(extra, WE_MAX_STR_LEN, "11ABG");
7423 break;
7424 case eCSR_DOT11_MODE_11a:
7425 snprintf(extra, WE_MAX_STR_LEN, "11A");
7426 break;
7427 case eCSR_DOT11_MODE_11b:
7428 case eCSR_DOT11_MODE_11b_ONLY:
7429 snprintf(extra, WE_MAX_STR_LEN, "11B");
7430 break;
7431 case eCSR_DOT11_MODE_11g:
7432 case eCSR_DOT11_MODE_11g_ONLY:
7433 snprintf(extra, WE_MAX_STR_LEN, "11G");
7434 break;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007435 case eCSR_DOT11_MODE_11ac:
7436 case eCSR_DOT11_MODE_11ac_ONLY:
7437 if (hddctx->config->vhtChannelWidth ==
7438 eHT_CHANNEL_WIDTH_20MHZ)
7439 snprintf(extra, WE_MAX_STR_LEN,
7440 "11ACVHT20");
7441 else if (hddctx->config->vhtChannelWidth ==
7442 eHT_CHANNEL_WIDTH_40MHZ)
7443 snprintf(extra, WE_MAX_STR_LEN,
7444 "11ACVHT40");
7445 else if (hddctx->config->vhtChannelWidth ==
7446 eHT_CHANNEL_WIDTH_80MHZ)
7447 snprintf(extra, WE_MAX_STR_LEN,
7448 "11ACVHT80");
7449 else if (hddctx->config->vhtChannelWidth ==
7450 eHT_CHANNEL_WIDTH_160MHZ)
7451 snprintf(extra, WE_MAX_STR_LEN,
7452 "11ACVHT160");
7453 break;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007454 }
7455
7456 wrqu->data.length = strlen(extra) + 1;
7457 break;
7458 }
7459
7460#ifdef FEATURE_OEM_DATA_SUPPORT
7461 case WE_GET_OEM_DATA_CAP:
7462 {
7463 return iw_get_oem_data_cap(dev, info, wrqu, extra);
7464 }
7465#endif /* FEATURE_OEM_DATA_SUPPORT */
7466 case WE_GET_SNR:
7467 {
7468 int8_t s7snr = 0;
7469 int status = 0;
7470 hdd_context_t *pHddCtx;
7471 hdd_station_ctx_t *pHddStaCtx;
7472 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7473 status = wlan_hdd_validate_context(pHddCtx);
Abhishek Singh23edd1c2016-05-05 11:56:06 +05307474 if (status)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007475 return status;
Abhishek Singh23edd1c2016-05-05 11:56:06 +05307476
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007477 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7478 if (0 == pHddCtx->config->fEnableSNRMonitoring ||
7479 eConnectionState_Associated !=
7480 pHddStaCtx->conn_info.connState) {
Jeff Johnson99bac312016-06-28 10:38:18 -07007481 hdd_err("getSNR failed: Enable SNR Monitoring-%d, ConnectionState-%d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007482 pHddCtx->config->fEnableSNRMonitoring,
7483 pHddStaCtx->conn_info.connState);
7484 return -ENONET;
7485 }
7486 wlan_hdd_get_snr(pAdapter, &s7snr);
7487 snprintf(extra, WE_MAX_STR_LEN, "snr=%d", s7snr);
7488 wrqu->data.length = strlen(extra) + 1;
7489 break;
7490 }
7491 default:
7492 {
Jeff Johnson99bac312016-06-28 10:38:18 -07007493 hdd_err("Invalid IOCTL command %d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007494 sub_cmd);
7495 break;
7496 }
7497 }
Hanumantha Reddy Pothula2db50ed2015-11-23 10:48:33 +05307498 EXIT();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007499 return 0;
7500}
7501
7502static int iw_get_char_setnone(struct net_device *dev,
7503 struct iw_request_info *info,
7504 union iwreq_data *wrqu, char *extra)
7505{
7506 int ret;
7507
7508 cds_ssr_protect(__func__);
7509 ret = __iw_get_char_setnone(dev, info, wrqu, extra);
7510 cds_ssr_unprotect(__func__);
7511
7512 return ret;
7513}
7514
7515/**
7516 * iw_setnone_getnone() - Generic "action" private ioctl handler
7517 * @dev: device upon which the ioctl was received
7518 * @info: ioctl request information
7519 * @wrqu: ioctl request data
7520 * @extra: ioctl extra data
7521 *
7522 * Return: 0 on success, non-zero on error
7523 */
7524static int __iw_setnone_getnone(struct net_device *dev,
7525 struct iw_request_info *info,
7526 union iwreq_data *wrqu, char *extra)
7527{
Sandeep Puligilla93a29ec2016-02-12 16:10:56 -08007528 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007529 hdd_context_t *hdd_ctx;
7530 int ret;
7531 int sub_cmd;
7532
Jeff Johnson6ee91ee2016-02-11 18:55:30 -08007533 ENTER_DEV(dev);
Hanumantha Reddy Pothula2db50ed2015-11-23 10:48:33 +05307534
Sandeep Puligilla93a29ec2016-02-12 16:10:56 -08007535 hdd_ctx = WLAN_HDD_GET_CTX(adapter);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007536 ret = wlan_hdd_validate_context(hdd_ctx);
7537 if (0 != ret)
7538 return ret;
7539
7540#ifdef CONFIG_COMPAT
7541 /* this ioctl is a special case where a sub-ioctl is used and both
7542 * the number of get and set args is 0. in this specific case the
7543 * logic in iwpriv places the sub_cmd in the data.flags portion of
7544 * the iwreq. unfortunately the location of this field will be
7545 * different between 32-bit and 64-bit userspace, and the standard
7546 * compat support in the kernel does not handle this case. so we
7547 * need to explicitly handle it here.
7548 */
7549 if (is_compat_task()) {
7550 struct compat_iw_point *compat_iw_point =
7551 (struct compat_iw_point *)&wrqu->data;
7552 sub_cmd = compat_iw_point->flags;
7553 } else {
7554 sub_cmd = wrqu->data.flags;
7555 }
7556#else
7557 sub_cmd = wrqu->data.flags;
7558#endif
7559
7560 switch (sub_cmd) {
7561 case WE_GET_RECOVERY_STAT:
7562 {
Sandeep Puligilla93a29ec2016-02-12 16:10:56 -08007563 tHalHandle hal = WLAN_HDD_GET_HAL_CTX(adapter);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007564 sme_get_recovery_stats(hal);
7565 break;
7566 }
7567
Govind Singha471e5e2015-10-12 17:11:14 +05307568 case WE_GET_FW_PROFILE_DATA:
Sandeep Puligilla93a29ec2016-02-12 16:10:56 -08007569 ret = wma_cli_set_command(adapter->sessionId,
Govind Singha471e5e2015-10-12 17:11:14 +05307570 WMI_WLAN_PROFILE_GET_PROFILE_DATA_CMDID,
7571 0, DBG_CMD);
7572 break;
7573
Rajeev Kumar8e3e2832015-11-06 16:02:54 -08007574 case WE_IBSS_GET_PEER_INFO_ALL:
7575 {
7576 hdd_wlan_get_ibss_peer_info_all(adapter);
7577 break;
7578 }
7579
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007580 case WE_SET_REASSOC_TRIGGER:
7581 {
Sandeep Puligilla93a29ec2016-02-12 16:10:56 -08007582 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
7583 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(adapter);
Deepak Dhamdhere5fda0e42016-06-24 18:30:02 +05307584 tSirMacAddr bssid;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007585 uint32_t roamId = 0;
Deepak Dhamdhere5fda0e42016-06-24 18:30:02 +05307586 uint8_t operating_ch =
7587 adapter->sessionCtx.station.conn_info.operationChannel;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007588 tCsrRoamModifyProfileFields modProfileFields;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007589
Sandeep Puligilla93a29ec2016-02-12 16:10:56 -08007590 sme_get_modify_profile_fields(hHal, adapter->sessionId,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007591 &modProfileFields);
Deepak Dhamdhere5fda0e42016-06-24 18:30:02 +05307592 if (roaming_offload_enabled(hdd_ctx)) {
7593 qdf_mem_copy(bssid,
7594 &adapter->sessionCtx.station.conn_info.bssId,
7595 sizeof(bssid));
7596 hdd_wma_send_fastreassoc_cmd((int)adapter->sessionId,
7597 bssid, operating_ch);
7598 } else {
7599 sme_roam_reassoc(hdd_ctx->hHal, adapter->sessionId,
7600 NULL, modProfileFields, &roamId, 1);
7601 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007602 return 0;
7603 }
7604
7605 case WE_DUMP_AGC_START:
7606 {
Jeff Johnson99bac312016-06-28 10:38:18 -07007607 hdd_notice("WE_DUMP_AGC_START");
Sandeep Puligilla93a29ec2016-02-12 16:10:56 -08007608 ret = wma_cli_set_command(adapter->sessionId,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007609 GEN_PARAM_DUMP_AGC_START,
7610 0, GEN_CMD);
7611 break;
7612 }
7613 case WE_DUMP_AGC:
7614 {
Jeff Johnson99bac312016-06-28 10:38:18 -07007615 hdd_notice("WE_DUMP_AGC");
Sandeep Puligilla93a29ec2016-02-12 16:10:56 -08007616 ret = wma_cli_set_command(adapter->sessionId,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007617 GEN_PARAM_DUMP_AGC,
7618 0, GEN_CMD);
7619 break;
7620 }
7621
7622 case WE_DUMP_CHANINFO_START:
7623 {
Jeff Johnson99bac312016-06-28 10:38:18 -07007624 hdd_notice("WE_DUMP_CHANINFO_START");
Sandeep Puligilla93a29ec2016-02-12 16:10:56 -08007625 ret = wma_cli_set_command(adapter->sessionId,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007626 GEN_PARAM_DUMP_CHANINFO_START,
7627 0, GEN_CMD);
7628 break;
7629 }
7630 case WE_DUMP_CHANINFO:
7631 {
Jeff Johnson99bac312016-06-28 10:38:18 -07007632 hdd_notice("WE_DUMP_CHANINFO_START");
Sandeep Puligilla93a29ec2016-02-12 16:10:56 -08007633 ret = wma_cli_set_command(adapter->sessionId,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007634 GEN_PARAM_DUMP_CHANINFO,
7635 0, GEN_CMD);
7636 break;
7637 }
7638 case WE_DUMP_WATCHDOG:
7639 {
Jeff Johnson99bac312016-06-28 10:38:18 -07007640 hdd_notice("WE_DUMP_WATCHDOG");
Sandeep Puligilla93a29ec2016-02-12 16:10:56 -08007641 ret = wma_cli_set_command(adapter->sessionId,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007642 GEN_PARAM_DUMP_WATCHDOG,
7643 0, GEN_CMD);
7644 break;
7645 }
7646#ifdef CONFIG_ATH_PCIE_ACCESS_DEBUG
7647 case WE_DUMP_PCIE_LOG:
7648 {
Jeff Johnson99bac312016-06-28 10:38:18 -07007649 hdd_err("WE_DUMP_PCIE_LOG");
Sandeep Puligilla93a29ec2016-02-12 16:10:56 -08007650 ret = wma_cli_set_command(adapter->sessionId,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007651 GEN_PARAM_DUMP_PCIE_ACCESS_LOG,
7652 0, GEN_CMD);
7653 break;
7654 }
7655#endif
Sandeep Puligilla93a29ec2016-02-12 16:10:56 -08007656 case WE_STOP_OBSS_SCAN:
7657 {
7658 /*
7659 * 1.OBSS Scan is mandatory while operating in 2.4GHz
7660 * 2.OBSS scan is stopped by Firmware during the disassociation
7661 * 3.OBSS stop comamnd is added for debugging purpose
7662 */
7663 tHalHandle hal;
7664
7665 hal = WLAN_HDD_GET_HAL_CTX(adapter);
7666 if (hal == NULL) {
7667 hdd_err("hal context is NULL");
7668 return -EINVAL;
7669 }
7670 sme_ht40_stop_obss_scan(hal, adapter->sessionId);
7671 }
7672 break;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007673 default:
7674 {
Jeff Johnson99bac312016-06-28 10:38:18 -07007675 hdd_err("unknown ioctl %d", sub_cmd);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007676 break;
7677 }
7678 }
Hanumantha Reddy Pothula2db50ed2015-11-23 10:48:33 +05307679 EXIT();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007680 return ret;
7681}
7682
7683static int iw_setnone_getnone(struct net_device *dev,
7684 struct iw_request_info *info,
7685 union iwreq_data *wrqu, char *extra)
7686{
7687 int ret;
7688
7689 cds_ssr_protect(__func__);
7690 ret = __iw_setnone_getnone(dev, info, wrqu, extra);
7691 cds_ssr_unprotect(__func__);
7692
7693 return ret;
7694}
7695
7696/**
7697 * __iw_set_var_ints_getnone - Generic "set many" private ioctl handler
7698 * @dev: device upon which the ioctl was received
7699 * @info: ioctl request information
7700 * @wrqu: ioctl request data
7701 * @extra: ioctl extra data
7702 *
7703 * This is an SSR-protected generic handler for private ioctls which
7704 * take multiple arguments. Note that this implementation is also
7705 * somewhat unique in that it is shared by both STA-mode and SAP-mode
7706 * interfaces.
7707 *
7708 * Return: 0 on success, non-zero on error
7709 */
7710static int __iw_set_var_ints_getnone(struct net_device *dev,
7711 struct iw_request_info *info,
7712 union iwreq_data *wrqu, char *extra)
7713{
7714 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
7715 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
7716 int sub_cmd;
7717 int *apps_args = (int *) extra;
7718 hdd_context_t *hdd_ctx;
7719 int ret, num_args;
7720
Jeff Johnson6ee91ee2016-02-11 18:55:30 -08007721 ENTER_DEV(dev);
Hanumantha Reddy Pothula2db50ed2015-11-23 10:48:33 +05307722
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007723 hdd_ctx = WLAN_HDD_GET_CTX(pAdapter);
7724 ret = wlan_hdd_validate_context(hdd_ctx);
7725 if (0 != ret)
7726 return ret;
7727
7728 if (extra == NULL) {
Jeff Johnson99bac312016-06-28 10:38:18 -07007729 hdd_err("NULL extra buffer pointer");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007730 return -EINVAL;
7731 }
7732
7733 sub_cmd = wrqu->data.flags;
7734 num_args = wrqu->data.length;
7735
Jeff Johnson99bac312016-06-28 10:38:18 -07007736 hdd_notice("Received length %d", wrqu->data.length);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007737
7738 switch (sub_cmd) {
Rajeev Kumar8e3e2832015-11-06 16:02:54 -08007739 case WE_IBSS_GET_PEER_INFO:
7740 {
7741 pr_info("Station ID = %d\n", apps_args[0]);
7742 hdd_wlan_get_ibss_peer_info(pAdapter, apps_args[0]);
7743 }
7744 break;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007745
7746 case WE_P2P_NOA_CMD:
7747 {
7748 p2p_app_setP2pPs_t p2pNoA;
7749
Krunal Sonif07bb382016-03-10 13:02:11 -08007750 if (pAdapter->device_mode != QDF_P2P_GO_MODE) {
Rajeev Kumar274034c2015-11-23 11:28:58 -08007751 hdd_err("Setting NoA is not allowed in Device mode %s(%d)",
7752 hdd_device_mode_to_string(
7753 pAdapter->device_mode),
7754 pAdapter->device_mode);
7755 return -EINVAL;
7756 }
7757
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007758 p2pNoA.opp_ps = apps_args[0];
7759 p2pNoA.ctWindow = apps_args[1];
7760 p2pNoA.duration = apps_args[2];
7761 p2pNoA.interval = apps_args[3];
7762 p2pNoA.count = apps_args[4];
7763 p2pNoA.single_noa_duration = apps_args[5];
7764 p2pNoA.psSelection = apps_args[6];
7765
Jeff Johnson99bac312016-06-28 10:38:18 -07007766 hdd_notice("P2P_NOA_ATTR:oppPS %d ctWindow %d duration %d interval %d count %d single noa duration %d PsSelection %x",
7767 apps_args[0], apps_args[1], apps_args[2],
7768 apps_args[3], apps_args[4],
7769 apps_args[5], apps_args[6]);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007770
7771 hdd_set_p2p_ps(dev, &p2pNoA);
7772
7773 }
7774 break;
7775
7776 case WE_MTRACE_SELECTIVE_MODULE_LOG_ENABLE_CMD:
7777 {
Jeff Johnson99bac312016-06-28 10:38:18 -07007778 hdd_notice("SELECTIVE_MODULE_LOG %d arg1 %d arg2",
7779 apps_args[0], apps_args[1]);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05307780 qdf_trace_enable(apps_args[0], apps_args[1]);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007781 }
7782 break;
7783
7784 case WE_MTRACE_DUMP_CMD:
7785 {
Jeff Johnson99bac312016-06-28 10:38:18 -07007786 hdd_notice("MTRACE_DUMP code %d session %d count %d bitmask_of_module %d ",
7787 apps_args[0], apps_args[1],
7788 apps_args[2], apps_args[3]);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05307789 qdf_trace_dump_all((void *)hHal, apps_args[0],
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007790 apps_args[1], apps_args[2],
7791 apps_args[3]);
7792
7793 }
7794 break;
7795
7796 case WE_POLICY_MANAGER_CLIST_CMD:
7797 {
Jeff Johnson99bac312016-06-28 10:38:18 -07007798 hdd_err("<iwpriv wlan0 pm_clist> is called");
Tushnim Bhattacharyyaca50b322015-12-28 17:14:36 -08007799 cds_incr_connection_count_utfw(apps_args[0],
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007800 apps_args[1], apps_args[2], apps_args[3],
7801 apps_args[4], apps_args[5], apps_args[6],
7802 apps_args[7]);
7803 }
7804 break;
7805
7806 case WE_POLICY_MANAGER_DLIST_CMD:
7807 {
Jeff Johnson99bac312016-06-28 10:38:18 -07007808 hdd_err("<iwpriv wlan0 pm_dlist> is called");
Tushnim Bhattacharyyaca50b322015-12-28 17:14:36 -08007809 cds_decr_connection_count_utfw(apps_args[0],
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007810 apps_args[1]);
7811 }
7812 break;
7813
7814 case WE_POLICY_MANAGER_ULIST_CMD:
7815 {
Jeff Johnson99bac312016-06-28 10:38:18 -07007816 hdd_err("<iwpriv wlan0 pm_ulist> is called");
Tushnim Bhattacharyyaca50b322015-12-28 17:14:36 -08007817 cds_update_connection_info_utfw(apps_args[0],
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007818 apps_args[1], apps_args[2], apps_args[3],
7819 apps_args[4], apps_args[5], apps_args[6],
7820 apps_args[7]);
7821 }
7822 break;
7823
7824 case WE_POLICY_MANAGER_DBS_CMD:
7825 {
Jeff Johnson99bac312016-06-28 10:38:18 -07007826 hdd_err("<iwpriv wlan0 pm_dbs> is called");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007827 if (apps_args[0] == 0)
7828 wma_set_dbs_capability_ut(0);
7829 else
7830 wma_set_dbs_capability_ut(1);
7831
7832 if (apps_args[1] >= CDS_THROUGHPUT &&
7833 apps_args[1] <= CDS_LATENCY) {
7834 pr_info("setting system pref to [%d]\n", apps_args[1]);
7835 hdd_ctx->config->conc_system_pref = apps_args[1];
7836 }
7837 }
7838 break;
7839
7840 case WE_POLICY_MANAGER_PCL_CMD:
7841 {
Manishekar Chandrasekaran1db3abe2016-06-24 03:27:07 +05307842 uint8_t pcl[QDF_MAX_NUM_CHAN] = {0};
7843 uint8_t weight_list[QDF_MAX_NUM_CHAN] = {0};
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007844 uint32_t pcl_len = 0, i = 0;
7845
Jeff Johnson99bac312016-06-28 10:38:18 -07007846 hdd_err("<iwpriv wlan0 pm_pcl> is called");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007847
Tushnim Bhattacharyyaca50b322015-12-28 17:14:36 -08007848 cds_get_pcl(apps_args[0],
Manishekar Chandrasekaran7009f252016-04-21 19:14:15 +05307849 pcl, &pcl_len,
7850 weight_list, QDF_ARRAY_SIZE(weight_list));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007851 pr_info("PCL list for role[%d] is {", apps_args[0]);
7852 for (i = 0 ; i < pcl_len; i++)
7853 pr_info(" %d, ", pcl[i]);
7854 pr_info("}--------->\n");
7855 }
7856 break;
7857
7858 case WE_POLICY_MANAGER_CINFO_CMD:
7859 {
7860 struct cds_conc_connection_info *conn_info;
7861 uint32_t i = 0, len = 0;
7862
Jeff Johnson99bac312016-06-28 10:38:18 -07007863 hdd_err("<iwpriv wlan0 pm_cinfo> is called");
Tushnim Bhattacharyyaca50b322015-12-28 17:14:36 -08007864 conn_info = cds_get_conn_info(&len);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007865 pr_info("+-----------------------------+\n");
7866 for (i = 0; i < len; i++) {
7867 pr_info("|table_index[%d]\t\t|\n", i);
7868 pr_info("|\t|vdev_id - %d\t\t|\n", conn_info->vdev_id);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007869 pr_info("|\t|chan - %d\t\t|\n", conn_info->chan);
Tushnim Bhattacharyya7624a182016-03-30 13:30:46 -07007870 pr_info("|\t|bw - %d\t\t|\n", conn_info->bw);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007871 pr_info("|\t|mode - %d\t\t|\n", conn_info->mode);
7872 pr_info("|\t|mac - %d\t\t|\n", conn_info->mac);
7873 pr_info("|\t|in_use - %d\t\t|\n", conn_info->in_use);
7874 pr_info("+-----------------------------+\n");
7875 conn_info++;
7876 }
7877 }
7878 break;
7879
7880 case WE_POLICY_SET_HW_MODE_CMD:
7881 {
7882 if (apps_args[0] == 0) {
Jeff Johnson99bac312016-06-28 10:38:18 -07007883 hdd_err("set hw mode for single mac");
Manishekar Chandrasekarand9640342016-04-27 12:28:26 +05307884 cds_pdev_set_hw_mode(
Chandrasekaran, Manishekaref70c0d2015-10-20 19:54:55 +05307885 pAdapter->sessionId,
7886 HW_MODE_SS_2x2,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007887 HW_MODE_80_MHZ,
7888 HW_MODE_SS_0x0, HW_MODE_BW_NONE,
7889 HW_MODE_DBS_NONE,
Chandrasekaran, Manishekaref70c0d2015-10-20 19:54:55 +05307890 HW_MODE_AGILE_DFS_NONE,
Chandrasekaran, Manishekarce2172e2016-02-18 16:12:43 +05307891 SIR_UPDATE_REASON_UT);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007892 } else if (apps_args[0] == 1) {
Jeff Johnson99bac312016-06-28 10:38:18 -07007893 hdd_err("set hw mode for dual mac");
Manishekar Chandrasekarand9640342016-04-27 12:28:26 +05307894 cds_pdev_set_hw_mode(
Chandrasekaran, Manishekaref70c0d2015-10-20 19:54:55 +05307895 pAdapter->sessionId,
7896 HW_MODE_SS_1x1,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007897 HW_MODE_80_MHZ,
7898 HW_MODE_SS_1x1, HW_MODE_40_MHZ,
7899 HW_MODE_DBS,
Chandrasekaran, Manishekaref70c0d2015-10-20 19:54:55 +05307900 HW_MODE_AGILE_DFS_NONE,
Chandrasekaran, Manishekarce2172e2016-02-18 16:12:43 +05307901 SIR_UPDATE_REASON_UT);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007902 }
7903 }
7904 break;
7905
7906 case WE_POLICY_MANAGER_QUERY_ACTION_CMD:
7907 {
7908 enum cds_conc_next_action action;
Jeff Johnson99bac312016-06-28 10:38:18 -07007909 hdd_err("<iwpriv wlan0 pm_query_action> is called");
Chandrasekaran, Manishekaref70c0d2015-10-20 19:54:55 +05307910 action = cds_current_connections_update(pAdapter->sessionId,
7911 apps_args[0],
Chandrasekaran, Manishekarce2172e2016-02-18 16:12:43 +05307912 SIR_UPDATE_REASON_UT);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007913 pr_info("next action is %d {HDD_NOP = 0, HDD_DBS, HDD_DBS_DOWNGRADE, HDD_MCC, HDD_MCC_UPGRADE}", action);
7914 }
7915 break;
7916 case WE_POLICY_MANAGER_QUERY_ALLOW_CMD:
7917 {
7918 bool allow;
Jeff Johnson99bac312016-06-28 10:38:18 -07007919 hdd_err("<iwpriv wlan0 pm_query_allow> is called");
Tushnim Bhattacharyyaca50b322015-12-28 17:14:36 -08007920 allow = cds_allow_concurrency(
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007921 apps_args[0], apps_args[1], apps_args[2]);
7922 pr_info("allow %d {0 = don't allow, 1 = allow}", allow);
7923 }
7924 break;
7925
7926 case WE_POLICY_MANAGER_SCENARIO_CMD:
7927 {
7928 clean_report(hdd_ctx);
7929 if (apps_args[0] == 1) {
7930 wlan_hdd_one_connection_scenario(hdd_ctx);
7931 } else if (apps_args[0] == 2) {
7932 wlan_hdd_two_connections_scenario(hdd_ctx,
7933 6, CDS_TWO_TWO);
7934 wlan_hdd_two_connections_scenario(hdd_ctx,
7935 36, CDS_TWO_TWO);
7936 wlan_hdd_two_connections_scenario(hdd_ctx,
7937 6, CDS_ONE_ONE);
7938 wlan_hdd_two_connections_scenario(hdd_ctx,
7939 36, CDS_ONE_ONE);
7940 } else if (apps_args[0] == 3) {
7941 /* MCC on same band with 2x2 same mac*/
7942 wlan_hdd_three_connections_scenario(hdd_ctx,
7943 6, 11, CDS_TWO_TWO, 0);
7944 /* MCC on diff band with 2x2 same mac*/
7945 wlan_hdd_three_connections_scenario(hdd_ctx,
7946 6, 36, CDS_TWO_TWO, 0);
7947 /* MCC on diff band with 1x1 diff mac */
7948 wlan_hdd_three_connections_scenario(hdd_ctx,
7949 36, 6, CDS_ONE_ONE, 0);
7950 /* MCC on diff band with 1x1 same mac */
7951 wlan_hdd_three_connections_scenario(hdd_ctx,
7952 36, 6, CDS_ONE_ONE, 1);
7953 /* SCC on same band with 2x2 same mac */
7954 wlan_hdd_three_connections_scenario(hdd_ctx,
7955 36, 36, CDS_TWO_TWO, 0);
7956 /* SCC on same band with 1x1 same mac */
7957 wlan_hdd_three_connections_scenario(hdd_ctx,
7958 36, 36, CDS_ONE_ONE, 1);
7959 /* MCC on same band with 2x2 same mac */
7960 wlan_hdd_three_connections_scenario(hdd_ctx,
7961 36, 149, CDS_TWO_TWO, 0);
7962 /* MCC on same band with 1x1 same mac */
7963 wlan_hdd_three_connections_scenario(hdd_ctx,
7964 36, 149, CDS_ONE_ONE, 1);
7965 }
7966 print_report(hdd_ctx);
7967 }
7968 break;
7969
7970#ifdef FEATURE_WLAN_TDLS
7971 case WE_TDLS_CONFIG_PARAMS:
7972 {
7973 tdls_config_params_t tdlsParams;
7974
7975 tdlsParams.tdls = apps_args[0];
7976 tdlsParams.tx_period_t = apps_args[1];
7977 tdlsParams.tx_packet_n = apps_args[2];
7978 /* ignore args[3] as discovery_period is not used anymore */
7979 tdlsParams.discovery_tries_n = apps_args[4];
7980 /* ignore args[5] as idle_timeout is not used anymore */
7981 tdlsParams.idle_packet_n = apps_args[6];
7982 /* ignore args[7] as rssi_hysteresis is not used anymore */
7983 tdlsParams.rssi_trigger_threshold = apps_args[8];
7984 tdlsParams.rssi_teardown_threshold = apps_args[9];
7985 tdlsParams.rssi_delta = apps_args[10];
7986
7987 wlan_hdd_tdls_set_params(dev, &tdlsParams);
7988 }
7989 break;
7990#endif
7991 case WE_UNIT_TEST_CMD:
7992 {
7993 t_wma_unit_test_cmd *unitTestArgs;
7994 cds_msg_t msg = { 0 };
7995 int i, j;
7996 if ((apps_args[0] < WLAN_MODULE_ID_MIN) ||
7997 (apps_args[0] >= WLAN_MODULE_ID_MAX)) {
Jeff Johnson99bac312016-06-28 10:38:18 -07007998 hdd_err("Invalid MODULE ID %d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007999 apps_args[0]);
8000 return -EINVAL;
8001 }
8002 if (apps_args[1] > (WMA_MAX_NUM_ARGS)) {
Jeff Johnson99bac312016-06-28 10:38:18 -07008003 hdd_err("Too Many args %d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008004 apps_args[1]);
8005 return -EINVAL;
8006 }
Anurag Chouhan600c3a02016-03-01 10:33:54 +05308007 unitTestArgs = qdf_mem_malloc(sizeof(*unitTestArgs));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008008 if (NULL == unitTestArgs) {
Jeff Johnson99bac312016-06-28 10:38:18 -07008009 hdd_err("qdf_mem_malloc failed for unitTestArgs");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008010 return -ENOMEM;
8011 }
8012 unitTestArgs->vdev_id = (int)pAdapter->sessionId;
8013 unitTestArgs->module_id = apps_args[0];
8014 unitTestArgs->num_args = apps_args[1];
8015 for (i = 0, j = 2; i < unitTestArgs->num_args; i++, j++) {
8016 unitTestArgs->args[i] = apps_args[j];
8017 }
8018 msg.type = SIR_HAL_UNIT_TEST_CMD;
8019 msg.reserved = 0;
8020 msg.bodyptr = unitTestArgs;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05308021 if (QDF_STATUS_SUCCESS !=
Anurag Chouhan6d760662016-02-20 16:05:43 +05308022 cds_mq_post_message(QDF_MODULE_ID_WMA, &msg)) {
Anurag Chouhan600c3a02016-03-01 10:33:54 +05308023 qdf_mem_free(unitTestArgs);
Jeff Johnson99bac312016-06-28 10:38:18 -07008024 hdd_err("Not able to post UNIT_TEST_CMD message to WMA");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008025 return -EINVAL;
8026 }
8027 }
8028 break;
8029#ifdef WLAN_FEATURE_GPIO_LED_FLASHING
8030 case WE_LED_FLASHING_PARAM:
8031 {
8032 int i;
8033 if (num_args != 4) {
Jeff Johnson99bac312016-06-28 10:38:18 -07008034 hdd_err("gpio_control: 4 parameters are required");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008035 return -EINVAL;
8036 }
8037 for (i = 0; i < num_args; i++) {
8038 if (apps_args[i] >= 0x7fffffff) {
Jeff Johnson99bac312016-06-28 10:38:18 -07008039 hdd_err("gpio_control: parameter should be less than 0x7fffffff");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008040 return -EINVAL;
8041 }
8042 }
8043 sme_set_led_flashing(WLAN_HDD_GET_HAL_CTX(pAdapter),
8044 0, apps_args[0], apps_args[1]);
8045 sme_set_led_flashing(WLAN_HDD_GET_HAL_CTX(pAdapter),
8046 1, apps_args[2], apps_args[3]);
8047 }
8048 break;
8049#endif
Manjeet Singhf82ed072016-07-08 11:40:00 +05308050 case WE_MAC_PWR_DEBUG_CMD:
8051 {
8052 struct sir_mac_pwr_dbg_cmd mac_pwr_dbg_args;
8053 tHalHandle hal = WLAN_HDD_GET_HAL_CTX(pAdapter);
8054 int i, j;
8055
8056 if (num_args < 3) {
8057 hdd_err("number of arguments can't be null %d",
8058 num_args);
8059 return -EINVAL;
8060 }
8061 if (num_args - 3 != apps_args[2]) {
8062 hdd_err("arg list of size %d doesn't match num_args %d",
8063 num_args-3, apps_args[2]);
8064 return -EINVAL;
8065 }
8066 if ((apps_args[1] < WLAN_MODULE_ID_MIN) ||
8067 (apps_args[1] >= WLAN_MODULE_ID_MAX)) {
8068 hdd_err("Invalid MODULE ID %d", apps_args[1]);
8069 return -EINVAL;
8070 }
8071 if (apps_args[2] > (MAX_POWER_DBG_ARGS_SUPPORTED)) {
8072 hdd_err("Too Many args %d", apps_args[2]);
8073 return -EINVAL;
8074 }
8075 mac_pwr_dbg_args.pdev_id = apps_args[0];
8076 mac_pwr_dbg_args.module_id = apps_args[1];
8077 mac_pwr_dbg_args.num_args = apps_args[2];
8078
8079 for (i = 0, j = 3; i < mac_pwr_dbg_args.num_args; i++, j++)
8080 mac_pwr_dbg_args.args[i] = apps_args[j];
8081
8082 if (QDF_STATUS_SUCCESS !=
8083 sme_process_mac_pwr_dbg_cmd(hal, pAdapter->sessionId,
8084 &mac_pwr_dbg_args)) {
8085 return -EINVAL;
8086 }
8087 }
8088 break;
8089
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008090 default:
8091 {
Jeff Johnson99bac312016-06-28 10:38:18 -07008092 hdd_err("Invalid IOCTL command %d", sub_cmd);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008093 }
8094 break;
8095 }
Hanumantha Reddy Pothula2db50ed2015-11-23 10:48:33 +05308096 EXIT();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008097 return 0;
8098}
8099
8100/**
8101 * iw_hdd_set_var_ints_getnone() - set var ints getnone callback
8102 * @dev: pointer to net_device structure
8103 * @info: pointer to iw_request_info structure
8104 * @wrqu: pointer to iwreq_data
8105 * @extra; extra
8106 *
8107 * Return: 0 on success, error number otherwise
8108 *
8109 */
8110static int iw_hdd_set_var_ints_getnone(struct net_device *dev,
8111 struct iw_request_info *info,
8112 union iwreq_data *wrqu, char *extra)
8113{
8114 union iwreq_data u_priv_wrqu;
8115 int apps_args[MAX_VAR_ARGS] = {0};
8116 int ret, num_args;
8117
Mukul Sharma64a70e82015-11-02 20:05:09 +05308118 if (!capable(CAP_NET_ADMIN)) {
Jeff Johnson99bac312016-06-28 10:38:18 -07008119 hdd_err("permission check failed");
Mukul Sharma64a70e82015-11-02 20:05:09 +05308120 return -EPERM;
8121 }
8122
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008123 /* Helper function to get iwreq_data with compat handling. */
8124 if (hdd_priv_get_data(&u_priv_wrqu.data, wrqu))
8125 return -EINVAL;
8126
8127 if (NULL == u_priv_wrqu.data.pointer) {
Jeff Johnson99bac312016-06-28 10:38:18 -07008128 hdd_err("NULL data pointer");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008129 return -EINVAL;
8130 }
8131
8132 num_args = u_priv_wrqu.data.length;
8133 if (num_args > MAX_VAR_ARGS)
8134 num_args = MAX_VAR_ARGS;
8135
8136 if (copy_from_user(apps_args, u_priv_wrqu.data.pointer,
8137 (sizeof(int)) * num_args)) {
Jeff Johnson99bac312016-06-28 10:38:18 -07008138 hdd_err("failed to copy data from user buffer");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008139 return -EFAULT;
8140 }
8141
8142 cds_ssr_protect(__func__);
8143 ret = __iw_set_var_ints_getnone(dev, info, &u_priv_wrqu,
8144 (char *)&apps_args);
8145 cds_ssr_unprotect(__func__);
8146 return ret;
8147}
8148
8149/**
8150 * iw_set_var_ints_getnone - Generic "set many" private ioctl handler
8151 * @dev: device upon which the ioctl was received
8152 * @info: ioctl request information
8153 * @wrqu: ioctl request data
8154 * @extra: ioctl extra data
8155 *
8156 * This is a generic handler for private ioctls which take multiple
8157 * arguments. Note that this implementation is also somewhat unique
8158 * in that it is shared by both STA-mode and SAP-mode interfaces.
8159 *
8160 * Return: 0 on success, non-zero on error
8161 */
8162int iw_set_var_ints_getnone(struct net_device *dev,
8163 struct iw_request_info *info,
8164 union iwreq_data *wrqu, char *extra)
8165{
8166 int ret;
8167
8168 cds_ssr_protect(__func__);
8169 ret = __iw_set_var_ints_getnone(dev, info, wrqu, extra);
8170 cds_ssr_unprotect(__func__);
8171 return ret;
8172}
8173
8174/**
8175 * iw_add_tspec - Add TSpec private ioctl handler
8176 * @dev: device upon which the ioctl was received
8177 * @info: ioctl request information
8178 * @wrqu: ioctl request data
8179 * @extra: ioctl extra data
8180 *
8181 * Return: 0 on success, non-zero on error
8182 */
8183static int __iw_add_tspec(struct net_device *dev, struct iw_request_info *info,
8184 union iwreq_data *wrqu, char *extra)
8185{
8186 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
8187 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
8188 hdd_wlan_wmm_status_e *pStatus = (hdd_wlan_wmm_status_e *) extra;
8189 int params[HDD_WLAN_WMM_PARAM_COUNT];
8190 sme_QosWmmTspecInfo tSpec;
8191 uint32_t handle;
8192 struct iw_point s_priv_data;
8193 hdd_context_t *hdd_ctx;
8194 int ret;
8195
Jeff Johnson6ee91ee2016-02-11 18:55:30 -08008196 ENTER_DEV(dev);
Hanumantha Reddy Pothula2db50ed2015-11-23 10:48:33 +05308197
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008198 hdd_ctx = WLAN_HDD_GET_CTX(pAdapter);
8199 ret = wlan_hdd_validate_context(hdd_ctx);
8200 if (0 != ret)
8201 return ret;
8202
8203 /* make sure the application is sufficiently priviledged */
8204 /* note that the kernel will do this for "set" ioctls, but since */
8205 /* this ioctl wants to return status to user space it must be */
8206 /* defined as a "get" ioctl */
8207 if (!capable(CAP_NET_ADMIN)) {
8208 return -EPERM;
8209 }
8210
8211 /* we must be associated in order to add a tspec */
8212 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState) {
8213 *pStatus = HDD_WLAN_WMM_STATUS_SETUP_FAILED_BAD_PARAM;
8214 return 0;
8215 }
8216 /* since we are defined to be a "get" ioctl, and since the number */
8217 /* of params exceeds the number of params that wireless extensions */
8218 /* will pass down in the iwreq_data, we must copy the "set" params. */
8219 /* We must handle the compat for iwreq_data in 32U/64K environment. */
8220
8221 /* helper function to get iwreq_data with compat handling. */
8222 if (hdd_priv_get_data(&s_priv_data, wrqu)) {
8223 *pStatus = HDD_WLAN_WMM_STATUS_SETUP_FAILED_BAD_PARAM;
8224 return 0;
8225 }
8226 /* make sure all params are correctly passed to function */
8227 if ((NULL == s_priv_data.pointer) ||
8228 (HDD_WLAN_WMM_PARAM_COUNT != s_priv_data.length)) {
8229 *pStatus = HDD_WLAN_WMM_STATUS_SETUP_FAILED_BAD_PARAM;
8230 return 0;
8231 }
8232 /* from user space ourselves */
8233 if (copy_from_user(&params, s_priv_data.pointer, sizeof(params))) {
8234 /* hmmm, can't get them */
8235 return -EIO;
8236 }
8237 /* clear the tspec */
8238 memset(&tSpec, 0, sizeof(tSpec));
8239
8240 /* validate the handle */
8241 handle = params[HDD_WLAN_WMM_PARAM_HANDLE];
8242 if (HDD_WMM_HANDLE_IMPLICIT == handle) {
8243 /* that one is reserved */
8244 *pStatus = HDD_WLAN_WMM_STATUS_SETUP_FAILED_BAD_PARAM;
8245 return 0;
8246 }
8247 /* validate the TID */
8248 if (params[HDD_WLAN_WMM_PARAM_TID] > 7) {
8249 /* out of range */
8250 *pStatus = HDD_WLAN_WMM_STATUS_SETUP_FAILED_BAD_PARAM;
8251 return 0;
8252 }
8253 tSpec.ts_info.tid = params[HDD_WLAN_WMM_PARAM_TID];
8254
8255 /* validate the direction */
8256 switch (params[HDD_WLAN_WMM_PARAM_DIRECTION]) {
8257 case HDD_WLAN_WMM_DIRECTION_UPSTREAM:
8258 tSpec.ts_info.direction = SME_QOS_WMM_TS_DIR_UPLINK;
8259 break;
8260
8261 case HDD_WLAN_WMM_DIRECTION_DOWNSTREAM:
8262 tSpec.ts_info.direction = SME_QOS_WMM_TS_DIR_DOWNLINK;
8263 break;
8264
8265 case HDD_WLAN_WMM_DIRECTION_BIDIRECTIONAL:
8266 tSpec.ts_info.direction = SME_QOS_WMM_TS_DIR_BOTH;
8267 break;
8268
8269 default:
8270 /* unknown */
8271 *pStatus = HDD_WLAN_WMM_STATUS_SETUP_FAILED_BAD_PARAM;
8272 return 0;
8273 }
8274
8275 tSpec.ts_info.psb = params[HDD_WLAN_WMM_PARAM_APSD];
8276
8277 /* validate the user priority */
8278 if (params[HDD_WLAN_WMM_PARAM_USER_PRIORITY] >= SME_QOS_WMM_UP_MAX) {
8279 /* out of range */
8280 *pStatus = HDD_WLAN_WMM_STATUS_SETUP_FAILED_BAD_PARAM;
8281 return 0;
8282 }
8283 tSpec.ts_info.up = params[HDD_WLAN_WMM_PARAM_USER_PRIORITY];
8284 if (0 > tSpec.ts_info.up || SME_QOS_WMM_UP_MAX < tSpec.ts_info.up) {
Jeff Johnson99bac312016-06-28 10:38:18 -07008285 hdd_err("***ts_info.up out of bounds***");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008286 return 0;
8287 }
8288
Jeff Johnson99bac312016-06-28 10:38:18 -07008289 hdd_info("TS_INFO PSB %d UP %d !!!",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008290 tSpec.ts_info.psb, tSpec.ts_info.up);
8291
8292 tSpec.nominal_msdu_size = params[HDD_WLAN_WMM_PARAM_NOMINAL_MSDU_SIZE];
8293 tSpec.maximum_msdu_size = params[HDD_WLAN_WMM_PARAM_MAXIMUM_MSDU_SIZE];
8294 tSpec.min_data_rate = params[HDD_WLAN_WMM_PARAM_MINIMUM_DATA_RATE];
8295 tSpec.mean_data_rate = params[HDD_WLAN_WMM_PARAM_MEAN_DATA_RATE];
8296 tSpec.peak_data_rate = params[HDD_WLAN_WMM_PARAM_PEAK_DATA_RATE];
8297 tSpec.max_burst_size = params[HDD_WLAN_WMM_PARAM_MAX_BURST_SIZE];
8298 tSpec.min_phy_rate = params[HDD_WLAN_WMM_PARAM_MINIMUM_PHY_RATE];
8299 tSpec.surplus_bw_allowance =
8300 params[HDD_WLAN_WMM_PARAM_SURPLUS_BANDWIDTH_ALLOWANCE];
8301 tSpec.min_service_interval =
8302 params[HDD_WLAN_WMM_PARAM_SERVICE_INTERVAL];
8303 tSpec.max_service_interval =
8304 params[HDD_WLAN_WMM_PARAM_MAX_SERVICE_INTERVAL];
8305 tSpec.suspension_interval =
8306 params[HDD_WLAN_WMM_PARAM_SUSPENSION_INTERVAL];
8307 tSpec.inactivity_interval =
8308 params[HDD_WLAN_WMM_PARAM_INACTIVITY_INTERVAL];
8309
8310 tSpec.ts_info.burst_size_defn =
8311 params[HDD_WLAN_WMM_PARAM_BURST_SIZE_DEFN];
8312
8313 /* validate the ts info ack policy */
8314 switch (params[HDD_WLAN_WMM_PARAM_ACK_POLICY]) {
8315 case HDD_WLAN_WMM_TS_INFO_ACK_POLICY_NORMAL_ACK:
8316 tSpec.ts_info.ack_policy = SME_QOS_WMM_TS_ACK_POLICY_NORMAL_ACK;
8317 break;
8318
8319 case HDD_WLAN_WMM_TS_INFO_ACK_POLICY_HT_IMMEDIATE_BLOCK_ACK:
8320 tSpec.ts_info.ack_policy =
8321 SME_QOS_WMM_TS_ACK_POLICY_HT_IMMEDIATE_BLOCK_ACK;
8322 break;
8323
8324 default:
8325 /* unknown */
8326 *pStatus = HDD_WLAN_WMM_STATUS_SETUP_FAILED_BAD_PARAM;
8327 return 0;
8328 }
8329
8330 *pStatus = hdd_wmm_addts(pAdapter, handle, &tSpec);
Hanumantha Reddy Pothula2db50ed2015-11-23 10:48:33 +05308331 EXIT();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008332 return 0;
8333}
8334
8335static int iw_add_tspec(struct net_device *dev,
8336 struct iw_request_info *info,
8337 union iwreq_data *wrqu, char *extra)
8338{
8339 int ret;
8340
8341 cds_ssr_protect(__func__);
8342 ret = __iw_add_tspec(dev, info, wrqu, extra);
8343 cds_ssr_unprotect(__func__);
8344
8345 return ret;
8346}
8347
8348/**
8349 * iw_del_tspec - Delete TSpec private ioctl handler
8350 * @dev: device upon which the ioctl was received
8351 * @info: ioctl request information
8352 * @wrqu: ioctl request data
8353 * @extra: ioctl extra data
8354 *
8355 * Return: 0 on success, non-zero on error
8356 */
8357static int __iw_del_tspec(struct net_device *dev, struct iw_request_info *info,
8358 union iwreq_data *wrqu, char *extra)
8359{
8360 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
8361 hdd_context_t *hdd_ctx;
8362 int *params = (int *)extra;
8363 hdd_wlan_wmm_status_e *pStatus = (hdd_wlan_wmm_status_e *) extra;
8364 uint32_t handle;
8365 int ret;
8366
Jeff Johnson6ee91ee2016-02-11 18:55:30 -08008367 ENTER_DEV(dev);
Hanumantha Reddy Pothula2db50ed2015-11-23 10:48:33 +05308368
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008369 hdd_ctx = WLAN_HDD_GET_CTX(pAdapter);
8370 ret = wlan_hdd_validate_context(hdd_ctx);
8371 if (0 != ret)
8372 return ret;
8373
8374 /* make sure the application is sufficiently priviledged */
8375 /* note that the kernel will do this for "set" ioctls, but since */
8376 /* this ioctl wants to return status to user space it must be */
8377 /* defined as a "get" ioctl */
8378 if (!capable(CAP_NET_ADMIN)) {
8379 return -EPERM;
8380 }
8381
8382 /* although we are defined to be a "get" ioctl, the params we require */
8383 /* will fit in the iwreq_data, therefore unlike iw_add_tspec() there */
8384 /* is no need to copy the params from user space */
8385
8386 /* validate the handle */
8387 handle = params[HDD_WLAN_WMM_PARAM_HANDLE];
8388 if (HDD_WMM_HANDLE_IMPLICIT == handle) {
8389 /* that one is reserved */
8390 *pStatus = HDD_WLAN_WMM_STATUS_SETUP_FAILED_BAD_PARAM;
8391 return 0;
8392 }
8393
8394 *pStatus = hdd_wmm_delts(pAdapter, handle);
Hanumantha Reddy Pothula2db50ed2015-11-23 10:48:33 +05308395 EXIT();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008396 return 0;
8397}
8398
8399static int iw_del_tspec(struct net_device *dev,
8400 struct iw_request_info *info,
8401 union iwreq_data *wrqu, char *extra)
8402{
8403 int ret;
8404
8405 cds_ssr_protect(__func__);
8406 ret = __iw_del_tspec(dev, info, wrqu, extra);
8407 cds_ssr_unprotect(__func__);
8408
8409 return ret;
8410}
8411
8412/**
8413 * iw_get_tspec - Get TSpec private ioctl handler
8414 * @dev: device upon which the ioctl was received
8415 * @info: ioctl request information
8416 * @wrqu: ioctl request data
8417 * @extra: ioctl extra data
8418 *
8419 * Return: 0 on success, non-zero on error
8420 */
8421static int __iw_get_tspec(struct net_device *dev, struct iw_request_info *info,
8422 union iwreq_data *wrqu, char *extra)
8423{
8424 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
8425 hdd_context_t *hdd_ctx;
8426 int *params = (int *)extra;
8427 hdd_wlan_wmm_status_e *pStatus = (hdd_wlan_wmm_status_e *) extra;
8428 uint32_t handle;
8429 int ret;
8430
Jeff Johnson6ee91ee2016-02-11 18:55:30 -08008431 ENTER_DEV(dev);
Hanumantha Reddy Pothula2db50ed2015-11-23 10:48:33 +05308432
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008433 hdd_ctx = WLAN_HDD_GET_CTX(pAdapter);
8434 ret = wlan_hdd_validate_context(hdd_ctx);
8435 if (0 != ret)
8436 return ret;
8437
8438 /* although we are defined to be a "get" ioctl, the params we require */
8439 /* will fit in the iwreq_data, therefore unlike iw_add_tspec() there */
8440 /* is no need to copy the params from user space */
8441
8442 /* validate the handle */
8443 handle = params[HDD_WLAN_WMM_PARAM_HANDLE];
8444 if (HDD_WMM_HANDLE_IMPLICIT == handle) {
8445 /* that one is reserved */
8446 *pStatus = HDD_WLAN_WMM_STATUS_SETUP_FAILED_BAD_PARAM;
8447 return 0;
8448 }
8449
8450 *pStatus = hdd_wmm_checkts(pAdapter, handle);
Hanumantha Reddy Pothula2db50ed2015-11-23 10:48:33 +05308451 EXIT();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008452 return 0;
8453}
8454
8455static int iw_get_tspec(struct net_device *dev,
8456 struct iw_request_info *info,
8457 union iwreq_data *wrqu, char *extra)
8458{
8459 int ret;
8460
8461 cds_ssr_protect(__func__);
8462 ret = __iw_get_tspec(dev, info, wrqu, extra);
8463 cds_ssr_unprotect(__func__);
8464
8465 return ret;
8466}
8467
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008468/**
8469 * iw_set_fties - Set FT IEs private ioctl handler
8470 * @dev: device upon which the ioctl was received
8471 * @info: ioctl request information
8472 * @wrqu: ioctl request data
8473 * @extra: ioctl extra data
8474 *
8475 * Each time the supplicant has the auth_request or reassoc request
8476 * IEs ready they are pushed to the driver. The driver will in turn
8477 * use it to send out the auth req and reassoc req for 11r FT Assoc.
8478 *
8479 * Return: 0 on success, non-zero on error
8480 */
8481static int __iw_set_fties(struct net_device *dev, struct iw_request_info *info,
8482 union iwreq_data *wrqu, char *extra)
8483{
8484 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
8485 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
8486 hdd_context_t *hdd_ctx;
8487 int ret;
8488
Jeff Johnson6ee91ee2016-02-11 18:55:30 -08008489 ENTER_DEV(dev);
Hanumantha Reddy Pothula2db50ed2015-11-23 10:48:33 +05308490
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008491 hdd_ctx = WLAN_HDD_GET_CTX(pAdapter);
8492 ret = wlan_hdd_validate_context(hdd_ctx);
8493 if (0 != ret)
8494 return ret;
8495
8496 if (!wrqu->data.length) {
Jeff Johnson99bac312016-06-28 10:38:18 -07008497 hdd_err("called with 0 length IEs");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008498 return -EINVAL;
8499 }
8500 if (wrqu->data.pointer == NULL) {
Jeff Johnson99bac312016-06-28 10:38:18 -07008501 hdd_err("called with NULL IE");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008502 return -EINVAL;
8503 }
8504 /* Added for debug on reception of Re-assoc Req. */
8505 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState) {
Jeff Johnson99bac312016-06-28 10:38:18 -07008506 hdd_err("Called with Ie of length = %d when not associated",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008507 wrqu->data.length);
Jeff Johnson99bac312016-06-28 10:38:18 -07008508 hdd_err("Should be Re-assoc Req IEs");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008509 }
Jeff Johnson99bac312016-06-28 10:38:18 -07008510 hdd_notice("called with Ie of length = %d", wrqu->data.length);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008511
8512 /* Pass the received FT IEs to SME */
8513 sme_set_ft_ies(WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
8514 extra, wrqu->data.length);
Hanumantha Reddy Pothula2db50ed2015-11-23 10:48:33 +05308515 EXIT();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008516 return 0;
8517}
8518
8519static int iw_set_fties(struct net_device *dev,
8520 struct iw_request_info *info,
8521 union iwreq_data *wrqu, char *extra)
8522{
8523 int ret;
8524
8525 cds_ssr_protect(__func__);
8526 ret = __iw_set_fties(dev, info, wrqu, extra);
8527 cds_ssr_unprotect(__func__);
8528
8529 return ret;
8530}
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008531
8532/**
8533 * iw_set_host_offload - Set host offload ioctl handler
8534 * @dev: device upon which the ioctl was received
8535 * @info: ioctl request information
8536 * @wrqu: ioctl request data
8537 * @extra: ioctl extra data
8538 *
8539 * Return: 0 on success, non-zero on error
8540 */
8541static int __iw_set_host_offload(struct net_device *dev,
8542 struct iw_request_info *info,
8543 union iwreq_data *wrqu, char *extra)
8544{
8545 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
8546 tpHostOffloadRequest pRequest = (tpHostOffloadRequest) extra;
8547 tSirHostOffloadReq offloadRequest;
8548 hdd_context_t *hdd_ctx;
8549 int ret;
8550
Jeff Johnson6ee91ee2016-02-11 18:55:30 -08008551 ENTER_DEV(dev);
Hanumantha Reddy Pothula2db50ed2015-11-23 10:48:33 +05308552
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008553 hdd_ctx = WLAN_HDD_GET_CTX(pAdapter);
8554 ret = wlan_hdd_validate_context(hdd_ctx);
8555 if (0 != ret)
8556 return ret;
8557
8558 if (!hdd_conn_is_connected(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))) {
Jeff Johnson99bac312016-06-28 10:38:18 -07008559 hdd_err("dev is not in CONNECTED state, ignore!!!");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008560 return -EINVAL;
8561 }
8562
8563 /* Debug display of request components. */
8564 switch (pRequest->offloadType) {
8565 case WLAN_IPV4_ARP_REPLY_OFFLOAD:
Jeff Johnson99bac312016-06-28 10:38:18 -07008566 hdd_warn("Host offload request: ARP reply");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008567 switch (pRequest->enableOrDisable) {
8568 case WLAN_OFFLOAD_DISABLE:
Jeff Johnson99bac312016-06-28 10:38:18 -07008569 hdd_warn(" disable");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008570 break;
8571 case WLAN_OFFLOAD_ARP_AND_BC_FILTER_ENABLE:
Jeff Johnson99bac312016-06-28 10:38:18 -07008572 hdd_warn(" BC Filtering enable");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008573 case WLAN_OFFLOAD_ENABLE:
Jeff Johnson99bac312016-06-28 10:38:18 -07008574 hdd_warn(" ARP offload enable");
8575 hdd_warn(" IP address: %d.%d.%d.%d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008576 pRequest->params.hostIpv4Addr[0],
8577 pRequest->params.hostIpv4Addr[1],
8578 pRequest->params.hostIpv4Addr[2],
8579 pRequest->params.hostIpv4Addr[3]);
8580 }
8581 break;
8582
8583 case WLAN_IPV6_NEIGHBOR_DISCOVERY_OFFLOAD:
Jeff Johnson99bac312016-06-28 10:38:18 -07008584 hdd_info("Host offload request: neighbor discovery");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008585 switch (pRequest->enableOrDisable) {
8586 case WLAN_OFFLOAD_DISABLE:
Jeff Johnson99bac312016-06-28 10:38:18 -07008587 hdd_info(" disable");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008588 break;
8589 case WLAN_OFFLOAD_ENABLE:
Jeff Johnson99bac312016-06-28 10:38:18 -07008590 hdd_info(" enable");
8591 hdd_info(" IP address: %x:%x:%x:%x:%x:%x:%x:%x",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008592 *(uint16_t *) (pRequest->params.hostIpv6Addr),
8593 *(uint16_t *) (pRequest->params.hostIpv6Addr +
8594 2),
8595 *(uint16_t *) (pRequest->params.hostIpv6Addr +
8596 4),
8597 *(uint16_t *) (pRequest->params.hostIpv6Addr +
8598 6),
8599 *(uint16_t *) (pRequest->params.hostIpv6Addr +
8600 8),
8601 *(uint16_t *) (pRequest->params.hostIpv6Addr +
8602 10),
8603 *(uint16_t *) (pRequest->params.hostIpv6Addr +
8604 12),
8605 *(uint16_t *) (pRequest->params.hostIpv6Addr +
8606 14));
8607 }
8608 }
8609
8610 /* Execute offload request. The reason that we can copy the
8611 * request information from the ioctl structure to the SME
8612 * structure is that they are laid out exactly the same.
8613 * Otherwise, each piece of information would have to be
8614 * copied individually.
8615 */
8616 memcpy(&offloadRequest, pRequest, wrqu->data.length);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05308617 if (QDF_STATUS_SUCCESS !=
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008618 sme_set_host_offload(WLAN_HDD_GET_HAL_CTX(pAdapter),
8619 pAdapter->sessionId, &offloadRequest)) {
Jeff Johnson99bac312016-06-28 10:38:18 -07008620 hdd_err("Failure to execute host offload request");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008621 return -EINVAL;
8622 }
Hanumantha Reddy Pothula2db50ed2015-11-23 10:48:33 +05308623 EXIT();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008624 return 0;
8625}
8626
8627static int iw_set_host_offload(struct net_device *dev,
8628 struct iw_request_info *info,
8629 union iwreq_data *wrqu, char *extra)
8630{
8631 int ret;
8632
8633 cds_ssr_protect(__func__);
8634 ret = __iw_set_host_offload(dev, info, wrqu, extra);
8635 cds_ssr_unprotect(__func__);
8636
8637 return ret;
8638}
8639
8640/**
8641 * iw_set_keepalive_params - Set keepalive params ioctl handler
8642 * @dev: device upon which the ioctl was received
8643 * @info: ioctl request information
8644 * @wrqu: ioctl request data
8645 * @extra: ioctl extra data
8646 *
8647 * Return: 0 on success, non-zero on error
8648 */
8649static int __iw_set_keepalive_params(struct net_device *dev,
8650 struct iw_request_info *info,
8651 union iwreq_data *wrqu, char *extra)
8652{
8653 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Rajeev Kumar3ddf1c62015-11-03 14:10:13 -08008654 tpSirKeepAliveReq request = (tpSirKeepAliveReq) extra;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008655 hdd_context_t *hdd_ctx;
8656 int ret;
8657
Jeff Johnson6ee91ee2016-02-11 18:55:30 -08008658 ENTER_DEV(dev);
Hanumantha Reddy Pothula2db50ed2015-11-23 10:48:33 +05308659
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008660 hdd_ctx = WLAN_HDD_GET_CTX(pAdapter);
8661 ret = wlan_hdd_validate_context(hdd_ctx);
8662 if (0 != ret)
8663 return ret;
8664
Rajeev Kumar3ddf1c62015-11-03 14:10:13 -08008665 if (wrqu->data.length != sizeof(*request)) {
8666 hdd_err("Invalid length %d", wrqu->data.length);
8667 return -EINVAL;
8668 }
8669
8670 if (request->timePeriod > WNI_CFG_INFRA_STA_KEEP_ALIVE_PERIOD_STAMAX) {
8671 hdd_err("Value of timePeriod %d exceed Max limit %d",
8672 request->timePeriod,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008673 WNI_CFG_INFRA_STA_KEEP_ALIVE_PERIOD_STAMAX);
8674 return -EINVAL;
8675 }
8676
8677 /* Debug display of request components. */
Rajeev Kumar3ddf1c62015-11-03 14:10:13 -08008678 hdd_info("Set Keep Alive Request : TimePeriod %d size %zu",
8679 request->timePeriod, sizeof(tSirKeepAliveReq));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008680
Rajeev Kumar3ddf1c62015-11-03 14:10:13 -08008681 switch (request->packetType) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008682 case WLAN_KEEP_ALIVE_NULL_PKT:
Rajeev Kumar3ddf1c62015-11-03 14:10:13 -08008683 hdd_info("Keep Alive Request: Tx NULL");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008684 break;
8685
8686 case WLAN_KEEP_ALIVE_UNSOLICIT_ARP_RSP:
Rajeev Kumar3ddf1c62015-11-03 14:10:13 -08008687 hdd_info("Keep Alive Request: Tx UnSolicited ARP RSP");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008688
Rajeev Kumar3ddf1c62015-11-03 14:10:13 -08008689 hdd_info("Host IP address: %d.%d.%d.%d",
8690 request->hostIpv4Addr[0], request->hostIpv4Addr[1],
8691 request->hostIpv4Addr[2], request->hostIpv4Addr[3]);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008692
Rajeev Kumar3ddf1c62015-11-03 14:10:13 -08008693 hdd_info("Dest IP address: %d.%d.%d.%d",
8694 request->destIpv4Addr[0], request->destIpv4Addr[1],
8695 request->destIpv4Addr[2], request->destIpv4Addr[3]);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008696
Srinivas Girigowda9c330a92015-11-24 12:28:25 -08008697 hdd_info("Dest MAC address: "MAC_ADDRESS_STR,
8698 MAC_ADDR_ARRAY(request->dest_macaddr.bytes));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008699 break;
8700 }
8701
Rajeev Kumar3ddf1c62015-11-03 14:10:13 -08008702 hdd_info("Keep alive period %d", request->timePeriod);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008703
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05308704 if (QDF_STATUS_SUCCESS !=
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008705 sme_set_keep_alive(WLAN_HDD_GET_HAL_CTX(pAdapter),
Rajeev Kumar3ddf1c62015-11-03 14:10:13 -08008706 pAdapter->sessionId, request)) {
8707 hdd_err("Failure to execute Keep Alive");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008708 return -EINVAL;
8709 }
Hanumantha Reddy Pothula2db50ed2015-11-23 10:48:33 +05308710 EXIT();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008711 return 0;
8712}
8713
8714static int iw_set_keepalive_params(struct net_device *dev,
8715 struct iw_request_info *info,
8716 union iwreq_data *wrqu,
8717 char *extra)
8718{
8719 int ret;
8720
8721 cds_ssr_protect(__func__);
8722 ret = __iw_set_keepalive_params(dev, info, wrqu, extra);
8723 cds_ssr_unprotect(__func__);
8724
8725 return ret;
8726}
8727
8728#ifdef WLAN_FEATURE_PACKET_FILTERING
8729/**
8730 * wlan_hdd_set_filter() - Set packet filter
8731 * @hdd_ctx: Global HDD context
8732 * @request: Packet filter request struct
8733 * @sessionId: Target session for the request
8734 *
8735 * Return: 0 on success, non-zero on error
8736 */
8737static int wlan_hdd_set_filter(hdd_context_t *hdd_ctx,
8738 struct pkt_filter_cfg *request,
8739 uint8_t sessionId)
8740{
8741 tSirRcvPktFilterCfgType packetFilterSetReq = {0};
8742 tSirRcvFltPktClearParam packetFilterClrReq = {0};
8743 int i = 0;
8744
8745 if (hdd_ctx->config->disablePacketFilter) {
8746 hdd_err("packet filtering disabled in ini returning");
8747 return 0;
8748 }
8749
8750 /* Debug display of request components. */
8751 hdd_info("Packet Filter Request : FA %d params %d",
8752 request->filter_action, request->num_params);
8753
8754 switch (request->filter_action) {
8755 case HDD_RCV_FILTER_SET:
8756 hdd_info("Set Packet Filter Request for Id: %d",
8757 request->filter_id);
8758
8759 packetFilterSetReq.filterId = request->filter_id;
8760 if (request->num_params >= HDD_MAX_CMP_PER_PACKET_FILTER) {
8761 hdd_err("Number of Params exceed Max limit %d",
8762 request->num_params);
8763 return -EINVAL;
8764 }
8765 packetFilterSetReq.numFieldParams = request->num_params;
8766 packetFilterSetReq.coalesceTime = 0;
8767 packetFilterSetReq.filterType = HDD_RCV_FILTER_SET;
8768 for (i = 0; i < request->num_params; i++) {
8769 packetFilterSetReq.paramsData[i].protocolLayer =
8770 request->params_data[i].protocol_layer;
8771 packetFilterSetReq.paramsData[i].cmpFlag =
8772 request->params_data[i].compare_flag;
8773 packetFilterSetReq.paramsData[i].dataOffset =
8774 request->params_data[i].data_offset;
8775 packetFilterSetReq.paramsData[i].dataLength =
8776 request->params_data[i].data_length;
8777 packetFilterSetReq.paramsData[i].reserved = 0;
8778
8779 if (request->params_data[i].data_length >
8780 SIR_MAX_FILTER_TEST_DATA_LEN) {
8781 hdd_err("Error invalid data length %d",
8782 request->params_data[i].data_length);
8783 return -EINVAL;
8784 }
8785
8786 hdd_info("Proto %d Comp Flag %d Filter Type %d",
8787 request->params_data[i].protocol_layer,
8788 request->params_data[i].compare_flag,
8789 packetFilterSetReq.filterType);
8790
8791 hdd_info("Data Offset %d Data Len %d",
8792 request->params_data[i].data_offset,
8793 request->params_data[i].data_length);
8794
Rajeev Kumarf5b6da22016-04-15 13:24:03 -07008795 if (sizeof(packetFilterSetReq.paramsData[i].compareData)
8796 < (request->params_data[i].data_length)) {
8797 hdd_err("Error invalid data length %d",
8798 request->params_data[i].data_length);
8799 return -EINVAL;
8800 }
8801
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008802 memcpy(&packetFilterSetReq.paramsData[i].compareData,
8803 request->params_data[i].compare_data,
8804 request->params_data[i].data_length);
8805 memcpy(&packetFilterSetReq.paramsData[i].dataMask,
8806 request->params_data[i].data_mask,
8807 request->params_data[i].data_length);
8808
8809 hdd_info("CData %d CData %d CData %d CData %d CData %d CData %d",
8810 request->params_data[i].compare_data[0],
8811 request->params_data[i].compare_data[1],
8812 request->params_data[i].compare_data[2],
8813 request->params_data[i].compare_data[3],
8814 request->params_data[i].compare_data[4],
8815 request->params_data[i].compare_data[5]);
8816
8817 hdd_info("MData %d MData %d MData %d MData %d MData %d MData %d",
8818 request->params_data[i].data_mask[0],
8819 request->params_data[i].data_mask[1],
8820 request->params_data[i].data_mask[2],
8821 request->params_data[i].data_mask[3],
8822 request->params_data[i].data_mask[4],
8823 request->params_data[i].data_mask[5]);
8824 }
8825
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05308826 if (QDF_STATUS_SUCCESS !=
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008827 sme_receive_filter_set_filter(hdd_ctx->hHal,
8828 &packetFilterSetReq,
8829 sessionId)) {
8830 hdd_err("Failure to execute Set Filter");
8831 return -EINVAL;
8832 }
8833
8834 break;
8835
8836 case HDD_RCV_FILTER_CLEAR:
8837
8838 hdd_info("Clear Packet Filter Request for Id: %d",
8839 request->filter_id);
8840 packetFilterClrReq.filterId = request->filter_id;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05308841 if (QDF_STATUS_SUCCESS !=
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008842 sme_receive_filter_clear_filter(hdd_ctx->hHal,
8843 &packetFilterClrReq,
8844 sessionId)) {
8845 hdd_err("Failure to execute Clear Filter");
8846 return -EINVAL;
8847 }
8848 break;
8849
8850 default:
8851 hdd_err("Packet Filter Request: Invalid %d",
8852 request->filter_action);
8853 return -EINVAL;
8854 }
8855 return 0;
8856}
8857
8858/**
8859 * __iw_set_packet_filter_params() - set packet filter parameters in target
8860 * @dev: Pointer to netdev
8861 * @info: Pointer to iw request info
8862 * @wrqu: Pointer to data
8863 * @extra: Pointer to extra data
8864 *
8865 * Return: 0 on success, non-zero on error
8866 */
8867static int __iw_set_packet_filter_params(struct net_device *dev,
8868 struct iw_request_info *info,
8869 union iwreq_data *wrqu, char *extra)
8870{
8871 int ret;
8872 hdd_context_t *hdd_ctx;
8873 struct iw_point priv_data;
8874 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
8875 struct pkt_filter_cfg *request = NULL;
8876
Mukul Sharma472382f2015-11-02 20:16:31 +05308877 if (!capable(CAP_NET_ADMIN)) {
Jeff Johnson99bac312016-06-28 10:38:18 -07008878 hdd_err("permission check failed");
Mukul Sharma472382f2015-11-02 20:16:31 +05308879 return -EPERM;
8880 }
8881
Jeff Johnson6ee91ee2016-02-11 18:55:30 -08008882 ENTER_DEV(dev);
Hanumantha Reddy Pothula2db50ed2015-11-23 10:48:33 +05308883
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008884 hdd_ctx = WLAN_HDD_GET_CTX(adapter);
8885 ret = wlan_hdd_validate_context(hdd_ctx);
8886 if (0 != ret)
8887 return ret;
8888
8889 if (hdd_priv_get_data(&priv_data, wrqu)) {
8890 hdd_err("failed to get priv data");
8891 return -EINVAL;
8892 }
8893
8894 if ((NULL == priv_data.pointer) || (0 == priv_data.length)) {
8895 hdd_err("invalid priv data %p or invalid priv data length %d",
8896 priv_data.pointer, priv_data.length);
8897 return -EINVAL;
8898 }
8899
8900 /* copy data using copy_from_user */
8901 request = mem_alloc_copy_from_user_helper(priv_data.pointer,
8902 priv_data.length);
8903 if (NULL == request) {
8904 hdd_err("mem_alloc_copy_from_user_helper fail");
8905 return -ENOMEM;
8906 }
8907
8908 ret = wlan_hdd_set_filter(hdd_ctx, request, adapter->sessionId);
8909
8910 kfree(request);
Hanumantha Reddy Pothula2db50ed2015-11-23 10:48:33 +05308911 EXIT();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008912 return ret;
8913}
8914
8915/**
8916 * iw_set_packet_filter_params() - set packet filter parameters in target
8917 * @dev: Pointer to netdev
8918 * @info: Pointer to iw request info
8919 * @wrqu: Pointer to data
8920 * @extra: Pointer to extra data
8921 *
8922 * Return: 0 on success, non-zero on error
8923 */
8924static int iw_set_packet_filter_params(struct net_device *dev,
8925 struct iw_request_info *info,
8926 union iwreq_data *wrqu, char *extra)
8927{
8928 int ret;
8929
8930 cds_ssr_protect(__func__);
8931 ret = __iw_set_packet_filter_params(dev, info, wrqu, extra);
8932 cds_ssr_unprotect(__func__);
8933
8934 return ret;
8935}
8936#endif
8937
8938
8939static int __iw_get_statistics(struct net_device *dev,
8940 struct iw_request_info *info,
8941 union iwreq_data *wrqu, char *extra)
8942{
8943
Anurag Chouhance0dc992016-02-16 18:18:03 +05308944 QDF_STATUS qdf_status = QDF_STATUS_SUCCESS;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05308945 QDF_STATUS status = QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008946 hdd_wext_state_t *pWextState;
8947 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
8948 hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(pAdapter);
8949 char *p = extra;
8950 int tlen = 0;
8951 tCsrSummaryStatsInfo *pStats = &(pAdapter->hdd_stats.summary_stat);
8952 tCsrGlobalClassAStatsInfo *aStats = &(pAdapter->hdd_stats.ClassA_stat);
8953 tCsrGlobalClassDStatsInfo *dStats = &(pAdapter->hdd_stats.ClassD_stat);
8954 int ret;
8955
Jeff Johnson6ee91ee2016-02-11 18:55:30 -08008956 ENTER_DEV(dev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008957
8958 ret = wlan_hdd_validate_context(hdd_ctx);
8959 if (0 != ret)
8960 return ret;
8961
8962 if (eConnectionState_Associated !=
8963 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState) {
8964
8965 wrqu->txpower.value = 0;
8966 } else {
8967 status = sme_get_statistics(hdd_ctx->hHal, eCSR_HDD,
8968 SME_SUMMARY_STATS |
8969 SME_GLOBAL_CLASSA_STATS |
8970 SME_GLOBAL_CLASSB_STATS |
8971 SME_GLOBAL_CLASSC_STATS |
8972 SME_GLOBAL_CLASSD_STATS |
8973 SME_PER_STA_STATS,
8974 hdd_statistics_cb, 0, false,
8975 (WLAN_HDD_GET_STATION_CTX_PTR
8976 (pAdapter))->conn_info.staId[0],
8977 pAdapter, pAdapter->sessionId);
8978
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05308979 if (QDF_STATUS_SUCCESS != status) {
Jeff Johnson99bac312016-06-28 10:38:18 -07008980 hdd_err("Unable to retrieve SME statistics");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008981 return -EINVAL;
8982 }
8983
8984 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
8985
Anurag Chouhance0dc992016-02-16 18:18:03 +05308986 qdf_status =
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05308987 qdf_wait_single_event(&pWextState->hdd_qdf_event,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008988 WLAN_WAIT_TIME_STATS);
Anurag Chouhance0dc992016-02-16 18:18:03 +05308989 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Jeff Johnson99bac312016-06-28 10:38:18 -07008990 hdd_err("SME timeout while retrieving statistics");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008991 /*Remove the SME statistics list by passing NULL in callback argument */
8992 status = sme_get_statistics(hdd_ctx->hHal, eCSR_HDD,
8993 SME_SUMMARY_STATS |
8994 SME_GLOBAL_CLASSA_STATS |
8995 SME_GLOBAL_CLASSB_STATS |
8996 SME_GLOBAL_CLASSC_STATS |
8997 SME_GLOBAL_CLASSD_STATS |
8998 SME_PER_STA_STATS,
8999 NULL, 0, false,
9000 (WLAN_HDD_GET_STATION_CTX_PTR
9001 (pAdapter))->conn_info.
9002 staId[0], pAdapter,
9003 pAdapter->sessionId);
9004
9005 return -EINVAL;
9006 }
9007 FILL_TLV(p, (uint8_t) WLAN_STATS_RETRY_CNT,
9008 (uint8_t) sizeof(pStats->retry_cnt),
9009 (char *)&(pStats->retry_cnt[0]), tlen);
9010
9011 FILL_TLV(p, (uint8_t) WLAN_STATS_MUL_RETRY_CNT,
9012 (uint8_t) sizeof(pStats->multiple_retry_cnt),
9013 (char *)&(pStats->multiple_retry_cnt[0]), tlen);
9014
9015 FILL_TLV(p, (uint8_t) WLAN_STATS_TX_FRM_CNT,
9016 (uint8_t) sizeof(pStats->tx_frm_cnt),
9017 (char *)&(pStats->tx_frm_cnt[0]), tlen);
9018
9019 FILL_TLV(p, (uint8_t) WLAN_STATS_RX_FRM_CNT,
9020 (uint8_t) sizeof(pStats->rx_frm_cnt),
9021 (char *)&(pStats->rx_frm_cnt), tlen);
9022
9023 FILL_TLV(p, (uint8_t) WLAN_STATS_FRM_DUP_CNT,
9024 (uint8_t) sizeof(pStats->frm_dup_cnt),
9025 (char *)&(pStats->frm_dup_cnt), tlen);
9026
9027 FILL_TLV(p, (uint8_t) WLAN_STATS_FAIL_CNT,
9028 (uint8_t) sizeof(pStats->fail_cnt),
9029 (char *)&(pStats->fail_cnt[0]), tlen);
9030
9031 FILL_TLV(p, (uint8_t) WLAN_STATS_RTS_FAIL_CNT,
9032 (uint8_t) sizeof(pStats->rts_fail_cnt),
9033 (char *)&(pStats->rts_fail_cnt), tlen);
9034
9035 FILL_TLV(p, (uint8_t) WLAN_STATS_ACK_FAIL_CNT,
9036 (uint8_t) sizeof(pStats->ack_fail_cnt),
9037 (char *)&(pStats->ack_fail_cnt), tlen);
9038
9039 FILL_TLV(p, (uint8_t) WLAN_STATS_RTS_SUC_CNT,
9040 (uint8_t) sizeof(pStats->rts_succ_cnt),
9041 (char *)&(pStats->rts_succ_cnt), tlen);
9042
9043 FILL_TLV(p, (uint8_t) WLAN_STATS_RX_DISCARD_CNT,
9044 (uint8_t) sizeof(pStats->rx_discard_cnt),
9045 (char *)&(pStats->rx_discard_cnt), tlen);
9046
9047 FILL_TLV(p, (uint8_t) WLAN_STATS_RX_ERROR_CNT,
9048 (uint8_t) sizeof(pStats->rx_error_cnt),
9049 (char *)&(pStats->rx_error_cnt), tlen);
9050
9051 FILL_TLV(p, (uint8_t) WLAN_STATS_TX_BYTE_CNT,
9052 (uint8_t) sizeof(dStats->tx_uc_byte_cnt[0]),
9053 (char *)&(dStats->tx_uc_byte_cnt[0]), tlen);
9054
9055 FILL_TLV(p, (uint8_t) WLAN_STATS_RX_BYTE_CNT,
9056 (uint8_t) sizeof(dStats->rx_byte_cnt),
9057 (char *)&(dStats->rx_byte_cnt), tlen);
9058
9059 FILL_TLV(p, (uint8_t) WLAN_STATS_RX_RATE,
9060 (uint8_t) sizeof(dStats->rx_rate),
9061 (char *)&(dStats->rx_rate), tlen);
9062
9063 /* Transmit rate, in units of 500 kbit/sec */
9064 FILL_TLV(p, (uint8_t) WLAN_STATS_TX_RATE,
9065 (uint8_t) sizeof(aStats->tx_rate),
9066 (char *)&(aStats->tx_rate), tlen);
9067
9068 FILL_TLV(p, (uint8_t) WLAN_STATS_RX_UC_BYTE_CNT,
9069 (uint8_t) sizeof(dStats->rx_uc_byte_cnt[0]),
9070 (char *)&(dStats->rx_uc_byte_cnt[0]), tlen);
9071 FILL_TLV(p, (uint8_t) WLAN_STATS_RX_MC_BYTE_CNT,
9072 (uint8_t) sizeof(dStats->rx_mc_byte_cnt),
9073 (char *)&(dStats->rx_mc_byte_cnt), tlen);
9074 FILL_TLV(p, (uint8_t) WLAN_STATS_RX_BC_BYTE_CNT,
9075 (uint8_t) sizeof(dStats->rx_bc_byte_cnt),
9076 (char *)&(dStats->rx_bc_byte_cnt), tlen);
9077 FILL_TLV(p, (uint8_t) WLAN_STATS_TX_UC_BYTE_CNT,
9078 (uint8_t) sizeof(dStats->tx_uc_byte_cnt[0]),
9079 (char *)&(dStats->tx_uc_byte_cnt[0]), tlen);
9080 FILL_TLV(p, (uint8_t) WLAN_STATS_TX_MC_BYTE_CNT,
9081 (uint8_t) sizeof(dStats->tx_mc_byte_cnt),
9082 (char *)&(dStats->tx_mc_byte_cnt), tlen);
9083 FILL_TLV(p, (uint8_t) WLAN_STATS_TX_BC_BYTE_CNT,
9084 (uint8_t) sizeof(dStats->tx_bc_byte_cnt),
9085 (char *)&(dStats->tx_bc_byte_cnt), tlen);
9086
9087 wrqu->data.length = tlen;
9088
9089 }
9090
9091 EXIT();
9092
9093 return 0;
9094}
9095
9096static int iw_get_statistics(struct net_device *dev,
9097 struct iw_request_info *info,
9098 union iwreq_data *wrqu, char *extra)
9099{
9100 int ret;
9101
9102 cds_ssr_protect(__func__);
9103 ret = __iw_get_statistics(dev, info, wrqu, extra);
9104 cds_ssr_unprotect(__func__);
9105
9106 return ret;
9107}
9108
9109#ifdef FEATURE_WLAN_SCAN_PNO
9110
9111/*Max Len for PNO notification*/
9112#define MAX_PNO_NOTIFY_LEN 100
9113void found_pref_network_cb(void *callbackContext,
9114 tSirPrefNetworkFoundInd *pPrefNetworkFoundInd)
9115{
9116 hdd_adapter_t *pAdapter = (hdd_adapter_t *) callbackContext;
9117 union iwreq_data wrqu;
9118 char buf[MAX_PNO_NOTIFY_LEN + 1];
9119
Jeff Johnson99bac312016-06-28 10:38:18 -07009120 hdd_warn("A preferred network was found: %s with rssi: -%d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08009121 pPrefNetworkFoundInd->ssId.ssId, pPrefNetworkFoundInd->rssi);
9122
9123 /* create the event */
9124 memset(&wrqu, 0, sizeof(wrqu));
9125 memset(buf, 0, sizeof(buf));
9126
9127 snprintf(buf, MAX_PNO_NOTIFY_LEN,
9128 "QCOM: Found preferred network: %s with RSSI of -%u",
9129 pPrefNetworkFoundInd->ssId.ssId,
9130 (unsigned int)pPrefNetworkFoundInd->rssi);
9131
9132 wrqu.data.pointer = buf;
9133 wrqu.data.length = strlen(buf);
9134
9135 /* send the event */
9136
9137 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, buf);
9138
9139}
9140
9141/**
9142 * __iw_set_pno() - Preferred Network Offload ioctl handler
9143 * @dev: device upon which the ioctl was received
9144 * @info: ioctl request information
9145 * @wrqu: ioctl request data
9146 * @extra: ioctl extra data
9147 *
9148 * This function parses a Preferred Network Offload command
9149 * Input is string based and expected to be of the form:
9150 *
9151 * <enable(1) | disable(0)>
9152 * when enabling:
9153 * <number of networks>
9154 * for each network:
9155 * <ssid_len> <ssid> <authentication> <encryption>
9156 * <ch_num> <channel_list optional> <bcast_type> <rssi_threshold>
9157 * <number of scan timers>
9158 * for each timer:
9159 * <scan_time> <scan_repeat>
9160 * <suspend mode>
9161 *
9162 * e.g:
9163 * 1 2 4 test 0 0 3 1 6 11 2 40 5 test2 4 4 6 1 2 3 4 5 6 1 0 2 5 2 300 0 1
9164 *
9165 * this translates into:
9166 * -----------------------------
9167 * enable PNO
9168 * 2 networks
9169 * Network 1:
9170 * test - with authentication type 0 and encryption type 0,
9171 * search on 3 channels: 1 6 and 11,
9172 * SSID bcast type is unknown (directed probe will be sent if
9173 * AP not found) and must meet -40dBm RSSI
9174 * Network 2:
9175 * test2 - with authentication type 4 and encryption type 4,
9176 * search on 6 channels 1, 2, 3, 4, 5 and 6
9177 * bcast type is non-bcast (directed probe will be sent)
9178 * and must not meet any RSSI threshold
9179 * 2 scan timers:
9180 * scan every 5 seconds 2 times
9181 * then scan every 300 seconds until stopped
9182 * enable on suspend
9183 */
9184static int __iw_set_pno(struct net_device *dev,
9185 struct iw_request_info *info,
9186 union iwreq_data *wrqu, char *extra)
9187{
9188 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
9189 hdd_context_t *hdd_ctx;
9190 int ret;
9191 int offset;
9192 char *ptr;
9193 uint8_t i, j, params, mode;
9194
9195 /* request is a large struct, so we make it static to avoid
9196 * stack overflow. This API is only invoked via ioctl, so it
9197 * is serialized by the kernel rtnl_lock and hence does not
9198 * need to be reentrant
9199 */
9200 static tSirPNOScanReq request;
9201
Jeff Johnson6ee91ee2016-02-11 18:55:30 -08009202 ENTER_DEV(dev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08009203
9204 hdd_ctx = WLAN_HDD_GET_CTX(adapter);
9205 ret = wlan_hdd_validate_context(hdd_ctx);
9206 if (ret)
9207 return ret;
9208
9209 hdd_notice("PNO data len %d data %s", wrqu->data.length, extra);
9210
9211 request.enable = 0;
9212 request.ucNetworksCount = 0;
9213
9214 ptr = extra;
9215
9216 if (1 != sscanf(ptr, "%hhu%n", &(request.enable), &offset)) {
9217 hdd_err("PNO enable input is not valid %s", ptr);
9218 return -EINVAL;
9219 }
9220
9221 if (0 == request.enable) {
9222 /* Disable PNO, ignore any other params */
9223 memset(&request, 0, sizeof(request));
9224 sme_set_preferred_network_list(WLAN_HDD_GET_HAL_CTX(adapter),
9225 &request, adapter->sessionId,
9226 found_pref_network_cb, adapter);
9227 return 0;
9228 }
9229
9230 ptr += offset;
9231
9232 if (1 !=
9233 sscanf(ptr, "%hhu %n", &(request.ucNetworksCount), &offset)) {
9234 hdd_err("PNO count input not valid %s", ptr);
9235 return -EINVAL;
9236
9237 }
9238
9239 hdd_info("PNO enable %d networks count %d offset %d",
9240 request.enable, request.ucNetworksCount, offset);
9241
9242 if ((0 == request.ucNetworksCount) ||
9243 (request.ucNetworksCount > SIR_PNO_MAX_SUPP_NETWORKS)) {
9244 hdd_err("Network count %d invalid",
9245 request.ucNetworksCount);
9246 return -EINVAL;
9247 }
9248
9249 ptr += offset;
9250
9251 for (i = 0; i < request.ucNetworksCount; i++) {
9252
9253 request.aNetworks[i].ssId.length = 0;
9254
9255 params = sscanf(ptr, "%hhu %n",
9256 &(request.aNetworks[i].ssId.length),
9257 &offset);
9258
9259 if (1 != params) {
9260 hdd_err("PNO ssid length input is not valid %s", ptr);
9261 return -EINVAL;
9262 }
9263
9264 if ((0 == request.aNetworks[i].ssId.length) ||
9265 (request.aNetworks[i].ssId.length > 32)) {
9266 hdd_err("SSID Len %d is not correct for network %d",
9267 request.aNetworks[i].ssId.length, i);
9268 return -EINVAL;
9269 }
9270
9271 /* Advance to SSID */
9272 ptr += offset;
9273
9274 memcpy(request.aNetworks[i].ssId.ssId, ptr,
9275 request.aNetworks[i].ssId.length);
9276 ptr += request.aNetworks[i].ssId.length;
9277
9278 params = sscanf(ptr, "%u %u %hhu %n",
9279 &(request.aNetworks[i].authentication),
9280 &(request.aNetworks[i].encryption),
9281 &(request.aNetworks[i].ucChannelCount),
9282 &offset);
9283
9284 if (3 != params) {
9285 hdd_warn("Incorrect cmd %s", ptr);
9286 return -EINVAL;
9287 }
9288
9289 hdd_notice("PNO len %d ssid %.*s auth %d encry %d channel count %d offset %d",
9290 request.aNetworks[i].ssId.length,
9291 request.aNetworks[i].ssId.length,
9292 request.aNetworks[i].ssId.ssId,
9293 request.aNetworks[i].authentication,
9294 request.aNetworks[i].encryption,
9295 request.aNetworks[i].ucChannelCount, offset);
9296
9297 /* Advance to channel list */
9298 ptr += offset;
9299
9300 if (SIR_PNO_MAX_NETW_CHANNELS <
9301 request.aNetworks[i].ucChannelCount) {
9302 hdd_warn("Incorrect number of channels");
9303 return -EINVAL;
9304 }
9305
9306 if (0 != request.aNetworks[i].ucChannelCount) {
9307 for (j = 0; j < request.aNetworks[i].ucChannelCount;
9308 j++) {
9309 if (1 !=
9310 sscanf(ptr, "%hhu %n",
9311 &(request.aNetworks[i].
9312 aChannels[j]), &offset)) {
9313 hdd_err("PNO network channel input is not valid %s",
9314 ptr);
9315 return -EINVAL;
9316 }
9317 /* Advance to next channel number */
9318 ptr += offset;
9319 }
9320 }
9321
9322 if (1 != sscanf(ptr, "%u %n",
9323 &(request.aNetworks[i].bcastNetwType),
9324 &offset)) {
9325 hdd_err("PNO broadcast network type input is not valid %s",
9326 ptr);
9327 return -EINVAL;
9328 }
9329
9330 hdd_notice("PNO bcastNetwType %d offset %d",
9331 request.aNetworks[i].bcastNetwType, offset);
9332
9333 /* Advance to rssi Threshold */
9334 ptr += offset;
9335 if (1 != sscanf(ptr, "%d %n",
9336 &(request.aNetworks[i].rssiThreshold),
9337 &offset)) {
9338 hdd_err("PNO rssi threshold input is not valid %s",
9339 ptr);
9340 return -EINVAL;
9341 }
9342 hdd_notice("PNO rssi %d offset %d",
9343 request.aNetworks[i].rssiThreshold, offset);
9344 /* Advance to next network */
9345 ptr += offset;
9346 } /* For ucNetworkCount */
9347
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08009348 params = sscanf(ptr, "%hhu %n", &(mode), &offset);
9349
9350 request.modePNO = mode;
9351 /* for LA we just expose suspend option */
9352 if ((1 != params) || (mode >= SIR_PNO_MODE_MAX)) {
9353 request.modePNO = SIR_PNO_MODE_ON_SUSPEND;
9354 }
9355
9356 sme_set_preferred_network_list(WLAN_HDD_GET_HAL_CTX(adapter),
9357 &request,
9358 adapter->sessionId,
9359 found_pref_network_cb, adapter);
9360
9361 return 0;
9362}
9363
9364static int iw_set_pno(struct net_device *dev,
9365 struct iw_request_info *info,
9366 union iwreq_data *wrqu, char *extra)
9367{
9368 int ret;
9369
9370 cds_ssr_protect(__func__);
9371 ret = __iw_set_pno(dev, info, wrqu, extra);
9372 cds_ssr_unprotect(__func__);
9373
9374 return ret;
9375}
9376#endif /* FEATURE_WLAN_SCAN_PNO */
9377
9378/* Common function to SetBand */
9379int hdd_set_band(struct net_device *dev, u8 ui_band)
9380{
9381 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
9382 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
9383 eCsrBand band;
9384
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05309385 QDF_STATUS status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08009386 hdd_context_t *pHddCtx;
9387 hdd_adapter_list_node_t *pAdapterNode, *pNext;
9388 eCsrBand currBand = eCSR_BAND_MAX;
9389 eCsrBand connectedBand;
9390
9391 pAdapterNode = NULL;
9392 pNext = NULL;
9393 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
9394
9395 switch (ui_band) {
9396 case WLAN_HDD_UI_BAND_AUTO:
9397 band = eCSR_BAND_ALL;
9398 break;
9399 case WLAN_HDD_UI_BAND_5_GHZ:
9400 band = eCSR_BAND_5G;
9401 break;
9402 case WLAN_HDD_UI_BAND_2_4_GHZ:
9403 band = eCSR_BAND_24;
9404 break;
9405 default:
9406 band = eCSR_BAND_MAX;
9407 }
9408
Jeff Johnson99bac312016-06-28 10:38:18 -07009409 hdd_notice("change band to %u", band);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08009410
9411 if (band == eCSR_BAND_MAX) {
9412 /* Received change band request with invalid band value */
Jeff Johnson99bac312016-06-28 10:38:18 -07009413 hdd_err("Invalid band value %u", ui_band);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08009414 return -EINVAL;
9415 }
9416
9417 if ((band == eCSR_BAND_24 && pHddCtx->config->nBandCapability == 2) ||
9418 (band == eCSR_BAND_5G && pHddCtx->config->nBandCapability == 1)) {
Jeff Johnson99bac312016-06-28 10:38:18 -07009419 hdd_err("band value %u violate INI settings %u",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08009420 band, pHddCtx->config->nBandCapability);
9421 return -EIO;
9422 }
9423
9424 if (band == eCSR_BAND_ALL) {
Jeff Johnson99bac312016-06-28 10:38:18 -07009425 hdd_notice("Auto band received. Setting band same as ini value %d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08009426 pHddCtx->config->nBandCapability);
9427 band = pHddCtx->config->nBandCapability;
9428 }
9429
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05309430 if (QDF_STATUS_SUCCESS != sme_get_freq_band(hHal, &currBand)) {
Jeff Johnson99bac312016-06-28 10:38:18 -07009431 hdd_notice("Failed to get current band config");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08009432 return -EIO;
9433 }
9434
9435 if (currBand != band) {
9436 /* Change band request received.
9437 * Abort pending scan requests, flush the existing scan results,
9438 * and change the band capability
9439 */
Jeff Johnson99bac312016-06-28 10:38:18 -07009440 hdd_notice("Current band value = %u, new setting %u ",
9441 currBand, band);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08009442
9443 status = hdd_get_front_adapter(pHddCtx, &pAdapterNode);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05309444 while (NULL != pAdapterNode && QDF_STATUS_SUCCESS == status) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08009445 pAdapter = pAdapterNode->pAdapter;
9446 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
9447 hdd_abort_mac_scan(pHddCtx, pAdapter->sessionId,
9448 eCSR_SCAN_ABORT_DUE_TO_BAND_CHANGE);
9449 connectedBand =
9450 hdd_conn_get_connected_band
9451 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter));
9452
9453 /* Handling is done only for STA and P2P */
9454 if (band != eCSR_BAND_ALL &&
Krunal Sonif07bb382016-03-10 13:02:11 -08009455 ((pAdapter->device_mode == QDF_STA_MODE)
9456 || (pAdapter->device_mode == QDF_P2P_CLIENT_MODE))
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08009457 &&
9458 (hdd_conn_is_connected
9459 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter)))
9460 && (connectedBand != band)) {
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05309461 QDF_STATUS status = QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08009462 long lrc;
9463
9464 /* STA already connected on current band, So issue disconnect
9465 * first, then change the band*/
9466
Jeff Johnson99bac312016-06-28 10:38:18 -07009467 hdd_notice("STA (Device mode %s(%d)) connected in band %u, Changing band to %u, Issuing Disconnect",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08009468 hdd_device_mode_to_string(pAdapter->device_mode),
9469 pAdapter->device_mode, currBand, band);
9470 INIT_COMPLETION(pAdapter->disconnect_comp_var);
9471
9472 status =
9473 sme_roam_disconnect(WLAN_HDD_GET_HAL_CTX
9474 (pAdapter),
9475 pAdapter->sessionId,
9476 eCSR_DISCONNECT_REASON_UNSPECIFIED);
9477
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05309478 if (QDF_STATUS_SUCCESS != status) {
Jeff Johnson99bac312016-06-28 10:38:18 -07009479 hdd_err("csr_roam_disconnect failure, returned %d",
9480 (int)status);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08009481 return -EINVAL;
9482 }
9483
9484 lrc =
9485 wait_for_completion_timeout(&pAdapter->
9486 disconnect_comp_var,
9487 msecs_to_jiffies
9488 (WLAN_WAIT_TIME_DISCONNECT));
9489
9490 if (lrc == 0) {
Jeff Johnson99bac312016-06-28 10:38:18 -07009491 hdd_err("Timeout while waiting for csr_roam_disconnect");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08009492 return -ETIMEDOUT;
9493 }
9494 }
9495
9496 sme_scan_flush_result(hHal);
9497
9498 status =
9499 hdd_get_next_adapter(pHddCtx, pAdapterNode, &pNext);
9500 pAdapterNode = pNext;
9501 }
9502
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05309503 if (QDF_STATUS_SUCCESS !=
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08009504 sme_set_freq_band(hHal, pAdapter->sessionId, band)) {
Jeff Johnson99bac312016-06-28 10:38:18 -07009505 hdd_alert("Failed to set the band value to %u",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08009506 band);
9507 return -EINVAL;
9508 }
9509 wlan_hdd_cfg80211_update_band(pHddCtx->wiphy, (eCsrBand) band);
9510 }
9511 return 0;
9512}
9513
9514int hdd_set_band_helper(struct net_device *dev, const char *command)
9515{
9516 uint8_t band;
9517 int ret;
9518
9519 /* Convert the band value from ascii to integer */
9520 command += WLAN_HDD_UI_SET_BAND_VALUE_OFFSET;
9521 ret = kstrtou8(command, 10, &band);
9522 if (ret < 0) {
Jeff Johnson99bac312016-06-28 10:38:18 -07009523 hdd_err("kstrtou8 failed");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08009524 return -EINVAL;
9525 }
9526
9527 return hdd_set_band(dev, band);
9528}
9529
9530static int __iw_set_band_config(struct net_device *dev,
9531 struct iw_request_info *info,
9532 union iwreq_data *wrqu, char *extra)
9533{
9534 int *value = (int *)extra;
9535
Jeff Johnson6ee91ee2016-02-11 18:55:30 -08009536 ENTER_DEV(dev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08009537
Mukul Sharmaa5fe1982015-11-02 19:28:14 +05309538 if (!capable(CAP_NET_ADMIN)) {
Jeff Johnson99bac312016-06-28 10:38:18 -07009539 hdd_err("permission check failed");
Mukul Sharmaa5fe1982015-11-02 19:28:14 +05309540 return -EPERM;
9541 }
9542
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08009543 return hdd_set_band(dev, value[0]);
9544}
9545
9546static int iw_set_band_config(struct net_device *dev,
9547 struct iw_request_info *info,
9548 union iwreq_data *wrqu, char *extra)
9549{
9550 int ret;
9551
9552 cds_ssr_protect(__func__);
9553 ret = __iw_set_band_config(dev, info, wrqu, extra);
9554 cds_ssr_unprotect(__func__);
9555
9556 return ret;
9557}
9558
Manjunathappa Prakash59f861d2016-04-21 10:33:31 -07009559/**
9560 * wlan_hdd_set_mon_chan() - Set capture channel on the monitor mode interface.
9561 * @adapter: Handle to adapter
9562 * @chan: Monitor mode channel
9563 * @bandwidth: Capture channel bandwidth
9564 *
9565 * Return: 0 on success else error code.
9566 */
9567static int wlan_hdd_set_mon_chan(hdd_adapter_t *adapter, uint32_t chan,
9568 uint32_t bandwidth)
9569{
9570 hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
9571 hdd_station_ctx_t *sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
9572 struct hdd_mon_set_ch_info *ch_info = &sta_ctx->ch_info;
9573 QDF_STATUS status;
9574 tHalHandle hal_hdl = hdd_ctx->hHal;
9575 struct qdf_mac_addr bssid;
9576 tCsrRoamProfile roam_profile;
9577 struct ch_params_s ch_params;
9578
9579 if (QDF_GLOBAL_MONITOR_MODE != hdd_get_conparam()) {
9580 hdd_err("Not supported, device is not in monitor mode");
9581 return -EINVAL;
9582 }
9583
9584 hdd_info("Set monitor mode Channel %d", chan);
9585 hdd_select_cbmode(adapter, chan);
9586 roam_profile.ChannelInfo.ChannelList = &ch_info->channel;
9587 roam_profile.ChannelInfo.numOfChannels = 1;
9588 roam_profile.phyMode = ch_info->phy_mode;
9589 roam_profile.ch_params.ch_width = bandwidth;
9590
9591 qdf_mem_copy(bssid.bytes, adapter->macAddressCurrent.bytes,
9592 QDF_MAC_ADDR_SIZE);
9593
9594 ch_params.ch_width = bandwidth;
Sandeep Puligilla1cc23f62016-04-27 16:52:49 -07009595 cds_set_channel_params(chan, 0, &ch_params);
Manjunathappa Prakash59f861d2016-04-21 10:33:31 -07009596 status = sme_roam_channel_change_req(hal_hdl, bssid, &ch_params,
9597 &roam_profile);
9598 if (status) {
9599 hdd_err("Status: %d Failed to set sme_roam Channel for monitor mode",
9600 status);
9601 }
9602
9603 return qdf_status_to_os_return(status);
9604}
9605
Rajeev Kumara78a0a42016-07-13 19:28:20 -07009606#ifdef WLAN_SUSPEND_RESUME_TEST
9607static void *g_wiphy;
9608
9609/**
9610 * hdd_wlan_trigger_resume() - resume wlan
9611 * @val: interrupt val
9612 *
9613 * Resume wlan after getting very 1st CE interrupt from target
9614 *
9615 * Return: none
9616 */
9617static void hdd_wlan_trigger_resume(uint32_t val)
9618{
9619 hdd_err("Resume WLAN val 0x%x", val);
9620 wlan_hdd_bus_resume();
9621 wlan_hdd_cfg80211_resume_wlan(g_wiphy);
9622}
9623#endif
9624
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08009625static int __iw_set_two_ints_getnone(struct net_device *dev,
9626 struct iw_request_info *info,
9627 union iwreq_data *wrqu, char *extra)
9628{
9629 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
9630 int *value = (int *)extra;
9631 int sub_cmd = value[0];
9632 int ret;
9633 hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(pAdapter);
Rajeev Kumara78a0a42016-07-13 19:28:20 -07009634#ifdef WLAN_SUSPEND_RESUME_TEST
9635 pm_message_t state;
9636#endif
9637
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08009638
Jeff Johnson6ee91ee2016-02-11 18:55:30 -08009639 ENTER_DEV(dev);
9640
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08009641 ret = wlan_hdd_validate_context(hdd_ctx);
9642 if (0 != ret)
9643 return ret;
9644
9645 switch (sub_cmd) {
9646 case WE_SET_SMPS_PARAM:
Jeff Johnson99bac312016-06-28 10:38:18 -07009647 hdd_notice("WE_SET_SMPS_PARAM val %d %d", value[1], value[2]);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08009648 ret = wma_cli_set_command(pAdapter->sessionId,
9649 WMI_STA_SMPS_PARAM_CMDID,
9650 value[1] << WMA_SMPS_PARAM_VALUE_S
9651 | value[2],
9652 VDEV_CMD);
9653 break;
9654#ifdef DEBUG
9655 case WE_SET_FW_CRASH_INJECT:
Jeff Johnson99bac312016-06-28 10:38:18 -07009656 hdd_err("WE_SET_FW_CRASH_INJECT: %d %d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08009657 value[1], value[2]);
DARAM SUDHA7e7e91b2015-05-29 11:38:47 +05309658 pr_err("SSR is triggered by iwpriv CRASH_INJECT: %d %d\n",
9659 value[1], value[2]);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08009660 ret = wma_cli_set2_command(pAdapter->sessionId,
9661 GEN_PARAM_CRASH_INJECT,
9662 value[1], value[2], GEN_CMD);
9663 break;
9664#endif
Govind Singha471e5e2015-10-12 17:11:14 +05309665 case WE_ENABLE_FW_PROFILE:
Jeff Johnson99bac312016-06-28 10:38:18 -07009666 hdd_err("WE_ENABLE_FW_PROFILE: %d %d",
Govind Singha471e5e2015-10-12 17:11:14 +05309667 value[1], value[2]);
9668 ret = wma_cli_set2_command(pAdapter->sessionId,
9669 WMI_WLAN_PROFILE_ENABLE_PROFILE_ID_CMDID,
9670 value[1], value[2], DBG_CMD);
9671 break;
9672 case WE_SET_FW_PROFILE_HIST_INTVL:
Jeff Johnson99bac312016-06-28 10:38:18 -07009673 hdd_err("WE_SET_FW_PROFILE_HIST_INTVL: %d %d",
Govind Singha471e5e2015-10-12 17:11:14 +05309674 value[1], value[2]);
9675 ret = wma_cli_set2_command(pAdapter->sessionId,
9676 WMI_WLAN_PROFILE_SET_HIST_INTVL_CMDID,
9677 value[1], value[2], DBG_CMD);
9678 break;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08009679 case WE_SET_DUAL_MAC_FW_MODE_CONFIG:
9680 hdd_debug("Ioctl to set dual fw mode config");
9681 if (hdd_ctx->config->dual_mac_feature_disable) {
9682 hdd_err("Dual mac feature is disabled from INI");
9683 return -EPERM;
9684 }
9685 hdd_debug("%d %d", value[1], value[2]);
Tushnim Bhattacharyya4adb3682016-01-07 15:07:12 -08009686 cds_set_dual_mac_fw_mode_config(value[1], value[2]);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08009687 break;
9688 case WE_DUMP_DP_TRACE_LEVEL:
9689 hdd_info("WE_DUMP_DP_TRACE_LEVEL: %d %d",
9690 value[1], value[2]);
9691 if (value[1] == DUMP_DP_TRACE)
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05309692 qdf_dp_trace_dump_all(value[2]);
Nirav Shah0d58a7e2016-04-26 22:54:12 +05309693 else if (value[1] == ENABLE_DP_TRACE_LIVE_MODE)
9694 qdf_dp_trace_enable_live_mode();
Nirav Shahda008342016-05-17 18:50:40 +05309695 else if (value[1] == CLEAR_DP_TRACE_BUFFER)
9696 qdf_dp_trace_clear_buffer();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08009697 break;
Manjunathappa Prakash59f861d2016-04-21 10:33:31 -07009698 case WE_SET_MON_MODE_CHAN:
9699 ret = wlan_hdd_set_mon_chan(pAdapter, value[1], value[2]);
9700 break;
Rajeev Kumara78a0a42016-07-13 19:28:20 -07009701#ifdef WLAN_SUSPEND_RESUME_TEST
9702 case WE_SET_WLAN_SUSPEND:
9703 hdd_err("Suspend WLAN");
9704 g_wiphy = hdd_ctx->wiphy;
9705 state.event = PM_EVENT_SUSPEND;
9706 ret = wlan_hdd_cfg80211_suspend_wlan(hdd_ctx->wiphy, NULL);
9707 wlan_hdd_bus_suspend(state);
9708 hif_fake_apps_suspend(hdd_wlan_trigger_resume);
9709 break;
9710 case WE_SET_WLAN_RESUME:
9711 hdd_err("Resume WLAN");
9712 wlan_hdd_bus_resume();
9713 ret = wlan_hdd_cfg80211_resume_wlan(hdd_ctx->wiphy);
9714 break;
9715#endif
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08009716 default:
Jeff Johnson99bac312016-06-28 10:38:18 -07009717 hdd_err("Invalid IOCTL command %d", sub_cmd);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08009718 break;
9719 }
9720
9721 return ret;
9722}
9723
9724static int iw_set_two_ints_getnone(struct net_device *dev,
9725 struct iw_request_info *info,
9726 union iwreq_data *wrqu, char *extra)
9727{
9728 int ret;
9729
9730 cds_ssr_protect(__func__);
9731 ret = __iw_set_two_ints_getnone(dev, info, wrqu, extra);
9732 cds_ssr_unprotect(__func__);
9733
9734 return ret;
9735}
9736
9737/* Define the Wireless Extensions to the Linux Network Device structure */
9738/* A number of these routines are NULL (meaning they are not implemented.) */
9739
9740static const iw_handler we_handler[] = {
9741 (iw_handler) iw_set_commit, /* SIOCSIWCOMMIT */
9742 (iw_handler) iw_get_name, /* SIOCGIWNAME */
9743 (iw_handler) NULL, /* SIOCSIWNWID */
9744 (iw_handler) NULL, /* SIOCGIWNWID */
9745 (iw_handler) iw_set_freq, /* SIOCSIWFREQ */
9746 (iw_handler) iw_get_freq, /* SIOCGIWFREQ */
9747 (iw_handler) iw_set_mode, /* SIOCSIWMODE */
9748 (iw_handler) iw_get_mode, /* SIOCGIWMODE */
9749 (iw_handler) NULL, /* SIOCSIWSENS */
9750 (iw_handler) NULL, /* SIOCGIWSENS */
9751 (iw_handler) NULL, /* SIOCSIWRANGE */
9752 (iw_handler) iw_get_range, /* SIOCGIWRANGE */
9753 (iw_handler) NULL, /* SIOCSIWPRIV */
9754 (iw_handler) NULL, /* SIOCGIWPRIV */
9755 (iw_handler) NULL, /* SIOCSIWSTATS */
9756 (iw_handler) NULL, /* SIOCGIWSTATS */
9757 (iw_handler) NULL, /* SIOCSIWSPY */
9758 (iw_handler) NULL, /* SIOCGIWSPY */
9759 (iw_handler) NULL, /* SIOCSIWTHRSPY */
9760 (iw_handler) NULL, /* SIOCGIWTHRSPY */
9761 (iw_handler) iw_set_ap_address, /* SIOCSIWAP */
9762 (iw_handler) iw_get_ap_address, /* SIOCGIWAP */
9763 (iw_handler) iw_set_mlme, /* SIOCSIWMLME */
9764 (iw_handler) NULL, /* SIOCGIWAPLIST */
9765 (iw_handler) iw_set_scan, /* SIOCSIWSCAN */
9766 (iw_handler) iw_get_scan, /* SIOCGIWSCAN */
9767 (iw_handler) iw_set_essid, /* SIOCSIWESSID */
9768 (iw_handler) iw_get_essid, /* SIOCGIWESSID */
9769 (iw_handler) iw_set_nick, /* SIOCSIWNICKN */
9770 (iw_handler) iw_get_nick, /* SIOCGIWNICKN */
9771 (iw_handler) NULL, /* -- hole -- */
9772 (iw_handler) NULL, /* -- hole -- */
9773 (iw_handler) iw_set_bitrate, /* SIOCSIWRATE */
9774 (iw_handler) iw_get_bitrate, /* SIOCGIWRATE */
9775 (iw_handler) iw_set_rts_threshold, /* SIOCSIWRTS */
9776 (iw_handler) iw_get_rts_threshold, /* SIOCGIWRTS */
9777 (iw_handler) iw_set_frag_threshold, /* SIOCSIWFRAG */
9778 (iw_handler) iw_get_frag_threshold, /* SIOCGIWFRAG */
9779 (iw_handler) iw_set_tx_power, /* SIOCSIWTXPOW */
9780 (iw_handler) iw_get_tx_power, /* SIOCGIWTXPOW */
9781 (iw_handler) iw_set_retry, /* SIOCSIWRETRY */
9782 (iw_handler) iw_get_retry, /* SIOCGIWRETRY */
9783 (iw_handler) iw_set_encode, /* SIOCSIWENCODE */
9784 (iw_handler) iw_get_encode, /* SIOCGIWENCODE */
9785 (iw_handler) iw_set_power_mode, /* SIOCSIWPOWER */
9786 (iw_handler) iw_get_power_mode, /* SIOCGIWPOWER */
9787 (iw_handler) NULL, /* -- hole -- */
9788 (iw_handler) NULL, /* -- hole -- */
9789 (iw_handler) iw_set_genie, /* SIOCSIWGENIE */
9790 (iw_handler) iw_get_genie, /* SIOCGIWGENIE */
9791 (iw_handler) iw_set_auth, /* SIOCSIWAUTH */
9792 (iw_handler) iw_get_auth, /* SIOCGIWAUTH */
9793 (iw_handler) iw_set_encodeext, /* SIOCSIWENCODEEXT */
9794 (iw_handler) iw_get_encodeext, /* SIOCGIWENCODEEXT */
9795 (iw_handler) NULL, /* SIOCSIWPMKSA */
9796};
9797
9798static const iw_handler we_private[] = {
9799
9800 [WLAN_PRIV_SET_INT_GET_NONE - SIOCIWFIRSTPRIV] = iw_setint_getnone, /* set priv ioctl */
9801 [WLAN_PRIV_SET_NONE_GET_INT - SIOCIWFIRSTPRIV] = iw_setnone_getint, /* get priv ioctl */
9802 [WLAN_PRIV_SET_CHAR_GET_NONE - SIOCIWFIRSTPRIV] = iw_setchar_getnone, /* get priv ioctl */
9803 [WLAN_PRIV_SET_THREE_INT_GET_NONE - SIOCIWFIRSTPRIV] =
9804 iw_set_three_ints_getnone,
9805 [WLAN_PRIV_GET_CHAR_SET_NONE - SIOCIWFIRSTPRIV] = iw_get_char_setnone,
9806 [WLAN_PRIV_SET_NONE_GET_NONE - SIOCIWFIRSTPRIV] = iw_setnone_getnone, /* action priv ioctl */
9807 [WLAN_PRIV_SET_VAR_INT_GET_NONE - SIOCIWFIRSTPRIV] =
9808 iw_hdd_set_var_ints_getnone,
Manikandan Mohandcc21ba2016-03-15 14:31:56 -07009809 [WLAN_PRIV_SET_NONE_GET_THREE_INT - SIOCIWFIRSTPRIV] =
9810 iw_setnone_get_threeint,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08009811 [WLAN_PRIV_ADD_TSPEC - SIOCIWFIRSTPRIV] = iw_add_tspec,
9812 [WLAN_PRIV_DEL_TSPEC - SIOCIWFIRSTPRIV] = iw_del_tspec,
9813 [WLAN_PRIV_GET_TSPEC - SIOCIWFIRSTPRIV] = iw_get_tspec,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08009814 [WLAN_PRIV_SET_FTIES - SIOCIWFIRSTPRIV] = iw_set_fties,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08009815 [WLAN_PRIV_SET_HOST_OFFLOAD - SIOCIWFIRSTPRIV] = iw_set_host_offload,
9816 [WLAN_GET_WLAN_STATISTICS - SIOCIWFIRSTPRIV] = iw_get_statistics,
9817 [WLAN_SET_KEEPALIVE_PARAMS - SIOCIWFIRSTPRIV] =
9818 iw_set_keepalive_params,
9819#ifdef WLAN_FEATURE_PACKET_FILTERING
9820 [WLAN_SET_PACKET_FILTER_PARAMS - SIOCIWFIRSTPRIV] =
9821 iw_set_packet_filter_params,
9822#endif
9823#ifdef FEATURE_WLAN_SCAN_PNO
9824 [WLAN_SET_PNO - SIOCIWFIRSTPRIV] = iw_set_pno,
9825#endif
9826 [WLAN_SET_BAND_CONFIG - SIOCIWFIRSTPRIV] = iw_set_band_config,
9827 [WLAN_GET_LINK_SPEED - SIOCIWFIRSTPRIV] = iw_get_linkspeed,
9828 [WLAN_PRIV_SET_TWO_INT_GET_NONE - SIOCIWFIRSTPRIV] =
9829 iw_set_two_ints_getnone,
9830 [WLAN_SET_DOT11P_CHANNEL_SCHED - SIOCIWFIRSTPRIV] =
9831 iw_set_dot11p_channel_sched,
9832};
9833
9834/*Maximum command length can be only 15 */
9835static const struct iw_priv_args we_private_args[] = {
9836
9837 /* handlers for main ioctl */
9838 {WLAN_PRIV_SET_INT_GET_NONE,
9839 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
9840 0,
9841 ""},
9842
9843 /* handlers for sub-ioctl */
9844 {WE_SET_11D_STATE,
9845 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
9846 0,
9847 "set11Dstate"},
9848
9849 {WE_WOWL,
9850 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
9851 0,
9852 "wowl"},
9853
9854 {WE_SET_POWER,
9855 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
9856 0,
9857 "setPower"},
9858
9859 {WE_SET_MAX_ASSOC,
9860 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
9861 0,
9862 "setMaxAssoc"},
9863
9864 {WE_SET_SAP_AUTO_CHANNEL_SELECTION,
9865 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0,
9866 "setAutoChannel" },
9867
9868 {WE_SET_SCAN_DISABLE,
9869 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
9870 0,
9871 "scan_disable"},
9872
9873 {WE_SET_DATA_INACTIVITY_TO,
9874 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
9875 0,
9876 "inactivityTO"},
9877
9878 {WE_SET_MAX_TX_POWER,
9879 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
9880 0,
9881 "setMaxTxPower"},
9882
9883 {WE_SET_TX_POWER,
9884 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
9885 0,
9886 "setTxPower"},
9887
9888 {WE_SET_MC_RATE,
9889 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
9890 0,
9891 "setMcRate"},
9892
9893 {WE_SET_MAX_TX_POWER_2_4,
9894 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
9895 0,
9896 "setTxMaxPower2G"},
9897
9898 {WE_SET_MAX_TX_POWER_5_0,
9899 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
9900 0,
9901 "setTxMaxPower5G"},
9902
Srinivas Girigowdac34f11d2016-02-25 16:02:42 -08009903 {WE_SET_PKTLOG,
9904 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
9905 0,
9906 "pktlog"},
9907
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08009908 /* SAP has TxMax whereas STA has MaxTx, adding TxMax for STA
9909 * as well to keep same syntax as in SAP. Now onwards, STA
9910 * will support both */
9911 {WE_SET_MAX_TX_POWER,
9912 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
9913 0,
9914 "setTxMaxPower"},
9915
9916 /* set Higher DTIM Transition (DTIM1 to DTIM3)
9917 * 1 = enable and 0 = disable */
9918 {
9919 WE_SET_HIGHER_DTIM_TRANSITION,
9920 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
9921 0,
9922 "setHDtimTransn"
9923 },
9924
9925 {WE_SET_TM_LEVEL,
9926 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
9927 0,
9928 "setTmLevel"},
9929
9930 {WE_SET_PHYMODE,
9931 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
9932 0,
9933 "setphymode"},
9934
9935 {WE_SET_NSS,
9936 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
9937 0,
9938 "nss"},
9939
9940 {WE_SET_LDPC,
9941 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
9942 0,
9943 "ldpc"},
9944
9945 {WE_SET_TX_STBC,
9946 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
9947 0,
9948 "tx_stbc"},
9949
9950 {WE_SET_RX_STBC,
9951 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
9952 0,
9953 "rx_stbc"},
9954
9955 {WE_SET_SHORT_GI,
9956 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
9957 0,
9958 "shortgi"},
9959
9960 {WE_SET_RTSCTS,
9961 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
9962 0,
9963 "enablertscts"},
9964
9965 {WE_SET_CHWIDTH,
9966 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
9967 0,
9968 "chwidth"},
9969
9970 {WE_SET_ANI_EN_DIS,
9971 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
9972 0,
9973 "anienable"},
9974
9975 {WE_SET_ANI_POLL_PERIOD,
9976 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
9977 0,
9978 "aniplen"},
9979
9980 {WE_SET_ANI_LISTEN_PERIOD,
9981 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
9982 0,
9983 "anilislen"},
9984
9985 {WE_SET_ANI_OFDM_LEVEL,
9986 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
9987 0,
9988 "aniofdmlvl"},
9989
9990 {WE_SET_ANI_CCK_LEVEL,
9991 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
9992 0,
9993 "aniccklvl"},
9994
9995 {WE_SET_DYNAMIC_BW,
9996 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
9997 0,
9998 "cwmenable"},
9999
10000 {WE_SET_CTS_CBW,
10001 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10002 0,
10003 "cts_cbw" },
10004
10005 {WE_SET_GTX_HT_MCS,
10006 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10007 0,
10008 "gtxHTMcs"},
10009
10010 {WE_SET_GTX_VHT_MCS,
10011 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10012 0,
10013 "gtxVHTMcs"},
10014
10015 {WE_SET_GTX_USRCFG,
10016 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10017 0,
10018 "gtxUsrCfg"},
10019
10020 {WE_SET_GTX_THRE,
10021 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10022 0,
10023 "gtxThre"},
10024
10025 {WE_SET_GTX_MARGIN,
10026 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10027 0,
10028 "gtxMargin"},
10029
10030 {WE_SET_GTX_STEP,
10031 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10032 0,
10033 "gtxStep"},
10034
10035 {WE_SET_GTX_MINTPC,
10036 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10037 0,
10038 "gtxMinTpc"},
10039
10040 {WE_SET_GTX_BWMASK,
10041 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10042 0,
10043 "gtxBWMask"},
10044
10045 {WE_SET_TX_CHAINMASK,
10046 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10047 0,
10048 "txchainmask"},
10049
10050 {WE_SET_RX_CHAINMASK,
10051 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10052 0,
10053 "rxchainmask"},
10054
10055 {WE_SET_11N_RATE,
10056 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10057 0,
10058 "set11NRates"},
10059
10060 {WE_SET_VHT_RATE,
10061 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10062 0,
10063 "set11ACRates"},
10064
10065 {WE_SET_AMPDU,
10066 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10067 0,
10068 "ampdu"},
10069
10070 {WE_SET_AMSDU,
10071 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10072 0,
10073 "amsdu"},
10074
10075 {WE_SET_BURST_ENABLE,
10076 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10077 0,
10078 "burst_enable"},
10079
10080 {WE_SET_BURST_DUR,
10081 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10082 0,
10083 "burst_dur"},
10084
10085 {WE_SET_TXPOW_2G,
10086 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10087 0,
10088 "txpow2g"},
10089
10090 {WE_SET_TXPOW_5G,
10091 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10092 0,
10093 "txpow5g"},
10094
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080010095 /* Sub-cmds DBGLOG specific commands */
10096 {WE_DBGLOG_LOG_LEVEL,
10097 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10098 0,
10099 "dl_loglevel"},
10100
10101 {WE_DBGLOG_VAP_ENABLE,
10102 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10103 0,
10104 "dl_vapon"},
10105
10106 {WE_DBGLOG_VAP_DISABLE,
10107 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10108 0,
10109 "dl_vapoff"},
10110
10111 {WE_DBGLOG_MODULE_ENABLE,
10112 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10113 0,
10114 "dl_modon"},
10115
10116 {WE_DBGLOG_MODULE_DISABLE,
10117 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10118 0,
10119 "dl_modoff"},
10120
10121 {WE_DBGLOG_MOD_LOG_LEVEL,
10122 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10123 0,
10124 "dl_mod_loglevel"},
10125
10126 {WE_DBGLOG_TYPE,
10127 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10128 0,
10129 "dl_type"},
10130 {WE_DBGLOG_REPORT_ENABLE,
10131 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10132 0,
10133 "dl_report"},
10134
10135 {WE_SET_TXRX_FWSTATS,
10136 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10137 0,
10138 "txrx_fw_stats"},
10139
10140 {WE_TXRX_FWSTATS_RESET,
10141 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10142 0,
10143 "txrx_fw_st_rst"},
10144
10145 {WE_PPS_PAID_MATCH,
10146 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10147 0, "paid_match"},
10148
10149 {WE_PPS_GID_MATCH,
10150 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10151 0, "gid_match"},
10152
10153 {WE_PPS_EARLY_TIM_CLEAR,
10154 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10155 0, "tim_clear"},
10156
10157 {WE_PPS_EARLY_DTIM_CLEAR,
10158 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10159 0, "dtim_clear"},
10160
10161 {WE_PPS_EOF_PAD_DELIM,
10162 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10163 0, "eof_delim"},
10164
10165 {WE_PPS_MACADDR_MISMATCH,
10166 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10167 0, "mac_match"},
10168
10169 {WE_PPS_DELIM_CRC_FAIL,
10170 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10171 0, "delim_fail"},
10172
10173 {WE_PPS_GID_NSTS_ZERO,
10174 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10175 0, "nsts_zero"},
10176
10177 {WE_PPS_RSSI_CHECK,
10178 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10179 0, "rssi_chk"},
10180
10181 {WE_PPS_5G_EBT,
10182 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10183 0, "5g_ebt"},
10184
10185 {WE_SET_HTSMPS,
10186 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10187 0, "htsmps"},
10188
10189 {WE_SET_QPOWER_MAX_PSPOLL_COUNT,
10190 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10191 0, "set_qpspollcnt"},
10192
10193 {WE_SET_QPOWER_MAX_TX_BEFORE_WAKE,
10194 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10195 0, "set_qtxwake"},
10196
10197 {WE_SET_QPOWER_SPEC_PSPOLL_WAKE_INTERVAL,
10198 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10199 0, "set_qwakeintv"},
10200
10201 {WE_SET_QPOWER_SPEC_MAX_SPEC_NODATA_PSPOLL,
10202 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10203 0, "set_qnodatapoll"},
10204
10205 /* handlers for MCC time quota and latency sub ioctls */
10206 {WE_MCC_CONFIG_LATENCY,
10207 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10208 0, "setMccLatency"},
10209
10210 {WE_MCC_CONFIG_QUOTA,
10211 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10212 0, "setMccQuota"},
10213
10214 {WE_SET_DEBUG_LOG,
10215 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10216 0, "setDbgLvl"},
10217
10218 /* handlers for early_rx power save */
10219 {WE_SET_EARLY_RX_ADJUST_ENABLE,
10220 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10221 0, "erx_enable"},
10222
10223 {WE_SET_EARLY_RX_TGT_BMISS_NUM,
10224 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10225 0, "erx_bmiss_val"},
10226
10227 {WE_SET_EARLY_RX_BMISS_SAMPLE_CYCLE,
10228 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10229 0, "erx_bmiss_smpl"},
10230
10231 {WE_SET_EARLY_RX_SLOP_STEP,
10232 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10233 0, "erx_slop_step"},
10234
10235 {WE_SET_EARLY_RX_INIT_SLOP,
10236 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10237 0, "erx_init_slop"},
10238
10239 {WE_SET_EARLY_RX_ADJUST_PAUSE,
10240 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10241 0, "erx_adj_pause"},
10242
10243 {WE_SET_EARLY_RX_DRIFT_SAMPLE,
10244 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10245 0, "erx_dri_sample"},
10246
10247 {WE_DUMP_STATS,
10248 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10249 0, "dumpStats"},
10250
10251 {WE_CLEAR_STATS,
10252 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10253 0, "clearStats"},
10254
Govind Singha471e5e2015-10-12 17:11:14 +053010255 {WE_START_FW_PROFILE,
10256 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10257 0, "startProfile"},
10258
Abhishek Singh1bdb1572015-10-16 16:24:19 +053010259 {WE_SET_CHANNEL,
10260 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10261 0, "setChanChange" },
10262
Manishekar Chandrasekaran97e077d2016-03-23 17:10:31 +053010263 {WE_SET_CONC_SYSTEM_PREF,
10264 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10265 0, "setConcSysPref" },
10266
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080010267 {WLAN_PRIV_SET_NONE_GET_INT,
10268 0,
10269 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10270 ""},
10271
10272 /* handlers for sub-ioctl */
10273 {WE_GET_11D_STATE,
10274 0,
10275 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10276 "get11Dstate"},
10277
10278 {WE_IBSS_STATUS,
10279 0,
10280 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10281 "getAdhocStatus"},
10282
10283 {WE_GET_WLAN_DBG,
10284 0,
10285 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10286 "getwlandbg"},
10287
10288 {WE_GET_MAX_ASSOC,
10289 0,
10290 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10291 "getMaxAssoc"},
10292
10293 {WE_GET_SAP_AUTO_CHANNEL_SELECTION,
10294 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10295 "getAutoChannel" },
10296
10297 {WE_GET_CONCURRENCY_MODE,
10298 0,
10299 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10300 "getconcurrency"},
10301
10302 {WE_GET_NSS,
10303 0,
10304 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10305 "get_nss"},
10306
10307 {WE_GET_LDPC,
10308 0,
10309 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10310 "get_ldpc"},
10311
10312 {WE_GET_TX_STBC,
10313 0,
10314 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10315 "get_tx_stbc"},
10316
10317 {WE_GET_RX_STBC,
10318 0,
10319 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10320 "get_rx_stbc"},
10321
10322 {WE_GET_SHORT_GI,
10323 0,
10324 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10325 "get_shortgi"},
10326
10327 {WE_GET_RTSCTS,
10328 0,
10329 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10330 "get_rtscts"},
10331
10332 {WE_GET_CHWIDTH,
10333 0,
10334 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10335 "get_chwidth"},
10336
10337 {WE_GET_ANI_EN_DIS,
10338 0,
10339 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10340 "get_anienable"},
10341
10342 {WE_GET_ANI_POLL_PERIOD,
10343 0,
10344 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10345 "get_aniplen"},
10346
10347 {WE_GET_ANI_LISTEN_PERIOD,
10348 0,
10349 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10350 "get_anilislen"},
10351
10352 {WE_GET_ANI_OFDM_LEVEL,
10353 0,
10354 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10355 "get_aniofdmlvl"},
10356
10357 {WE_GET_ANI_CCK_LEVEL,
10358 0,
10359 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10360 "get_aniccklvl"},
10361
10362 {WE_GET_DYNAMIC_BW,
10363 0,
10364 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10365 "get_cwmenable"},
10366
10367 {WE_GET_GTX_HT_MCS,
10368 0,
10369 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10370 "get_gtxHTMcs"},
10371
10372 {WE_GET_GTX_VHT_MCS,
10373 0,
10374 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10375 "get_gtxVHTMcs"},
10376
10377 {WE_GET_GTX_USRCFG,
10378 0,
10379 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10380 "get_gtxUsrCfg"},
10381
10382 {WE_GET_GTX_THRE,
10383 0,
10384 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10385 "get_gtxThre"},
10386
10387 {WE_GET_GTX_MARGIN,
10388 0,
10389 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10390 "get_gtxMargin"},
10391
10392 {WE_GET_GTX_STEP,
10393 0,
10394 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10395 "get_gtxStep"},
10396
10397 {WE_GET_GTX_MINTPC,
10398 0,
10399 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10400 "get_gtxMinTpc"},
10401
10402 {WE_GET_GTX_BWMASK,
10403 0,
10404 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10405 "get_gtxBWMask"},
10406
10407 {WE_GET_TX_CHAINMASK,
10408 0,
10409 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10410 "get_txchainmask"},
10411
10412 {WE_GET_RX_CHAINMASK,
10413 0,
10414 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10415 "get_rxchainmask"},
10416
10417 {WE_GET_11N_RATE,
10418 0,
10419 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10420 "get_11nrate"},
10421
10422 {WE_GET_AMPDU,
10423 0,
10424 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10425 "get_ampdu"},
10426
10427 {WE_GET_AMSDU,
10428 0,
10429 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10430 "get_amsdu"},
10431
10432 {WE_GET_BURST_ENABLE,
10433 0,
10434 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10435 "get_burst_en"},
10436
10437 {WE_GET_BURST_DUR,
10438 0,
10439 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10440 "get_burst_dur"},
10441
10442 {WE_GET_TXPOW_2G,
10443 0,
10444 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10445 "get_txpow2g"},
10446
10447 {WE_GET_TXPOW_5G,
10448 0,
10449 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10450 "get_txpow5g"},
10451
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080010452 {WE_GET_PPS_PAID_MATCH,
10453 0,
10454 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10455 "get_paid_match"},
10456
10457 {WE_GET_PPS_GID_MATCH,
10458 0,
10459 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10460 "get_gid_match"},
10461
10462 {WE_GET_PPS_EARLY_TIM_CLEAR,
10463 0,
10464 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10465 "get_tim_clear"},
10466
10467 {WE_GET_PPS_EARLY_DTIM_CLEAR,
10468 0,
10469 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10470 "get_dtim_clear"},
10471
10472 {WE_GET_PPS_EOF_PAD_DELIM,
10473 0,
10474 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10475 "get_eof_delim"},
10476
10477 {WE_GET_PPS_MACADDR_MISMATCH,
10478 0,
10479 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10480 "get_mac_match"},
10481
10482 {WE_GET_PPS_DELIM_CRC_FAIL,
10483 0,
10484 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10485 "get_delim_fail"},
10486
10487 {WE_GET_PPS_GID_NSTS_ZERO,
10488 0,
10489 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10490 "get_nsts_zero"},
10491
10492 {WE_GET_PPS_RSSI_CHECK,
10493 0,
10494 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10495 "get_rssi_chk"},
10496
10497 {WE_GET_QPOWER_MAX_PSPOLL_COUNT,
10498 0,
10499 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10500 "get_qpspollcnt"},
10501
10502 {WE_GET_QPOWER_MAX_TX_BEFORE_WAKE,
10503 0,
10504 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10505 "get_qtxwake"},
10506
10507 {WE_GET_QPOWER_SPEC_PSPOLL_WAKE_INTERVAL,
10508 0,
10509 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10510 "get_qwakeintv"},
10511
10512 {WE_GET_QPOWER_SPEC_MAX_SPEC_NODATA_PSPOLL,
10513 0,
10514 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10515 "get_qnodatapoll"},
10516
Manikandan Mohandcc21ba2016-03-15 14:31:56 -070010517 {WE_CAP_TSF,
10518 0,
10519 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10520 "cap_tsf"},
10521
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080010522 {WE_GET_TEMPERATURE,
10523 0,
10524 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10525 "get_temp"},
10526 /* handlers for main ioctl */
10527 {WLAN_PRIV_SET_CHAR_GET_NONE,
10528 IW_PRIV_TYPE_CHAR | 512,
10529 0,
10530 ""},
10531
10532 /* handlers for sub-ioctl */
10533 {WE_WOWL_ADD_PTRN,
10534 IW_PRIV_TYPE_CHAR | 512,
10535 0,
10536 "wowlAddPtrn"},
10537
10538 {WE_WOWL_DEL_PTRN,
10539 IW_PRIV_TYPE_CHAR | 512,
10540 0,
10541 "wowlDelPtrn"},
10542
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080010543 /* handlers for sub-ioctl */
10544 {WE_NEIGHBOR_REPORT_REQUEST,
10545 IW_PRIV_TYPE_CHAR | 512,
10546 0,
10547 "neighbor"},
Deepak Dhamdhere641bf322016-01-06 15:19:03 -080010548
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080010549 {WE_SET_AP_WPS_IE,
10550 IW_PRIV_TYPE_CHAR | 512,
10551 0,
10552 "set_ap_wps_ie"},
10553
10554 {WE_SET_CONFIG,
10555 IW_PRIV_TYPE_CHAR | 512,
10556 0,
10557 "setConfig"},
10558
10559 /* handlers for main ioctl */
10560 {WLAN_PRIV_SET_THREE_INT_GET_NONE,
10561 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 3,
10562 0,
10563 ""},
10564
10565 /* handlers for sub-ioctl */
10566 {WE_SET_WLAN_DBG,
10567 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 3,
10568 0,
10569 "setwlandbg"},
10570
10571 /* handlers for sub-ioctl */
10572 {WE_SET_DP_TRACE,
10573 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 3,
10574 0,
10575 "set_dp_trace"},
10576
10577 {WE_SET_SAP_CHANNELS,
10578 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 3,
10579 0,
10580 "setsapchannels"},
Manikandan Mohandcc21ba2016-03-15 14:31:56 -070010581 /* handlers for main ioctl */
10582 {WLAN_PRIV_SET_NONE_GET_THREE_INT,
10583 0,
10584 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 3,
10585 "" },
10586 {WE_GET_TSF,
10587 0,
10588 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 3,
10589 "get_tsf" },
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080010590
10591 {WE_SET_DUAL_MAC_SCAN_CONFIG,
10592 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 3,
10593 0,
10594 "set_scan_cfg"},
10595
10596 /* handlers for main ioctl */
10597 {WLAN_PRIV_GET_CHAR_SET_NONE,
10598 0,
10599 IW_PRIV_TYPE_CHAR | WE_MAX_STR_LEN,
10600 ""},
10601
10602 /* handlers for sub-ioctl */
10603 {WE_WLAN_VERSION,
10604 0,
10605 IW_PRIV_TYPE_CHAR | WE_MAX_STR_LEN,
10606 "version"},
10607 {WE_GET_STATS,
10608 0,
10609 IW_PRIV_TYPE_CHAR | WE_MAX_STR_LEN,
10610 "getStats"},
Govind Singha471e5e2015-10-12 17:11:14 +053010611 {WE_LIST_FW_PROFILE,
10612 0,
10613 IW_PRIV_TYPE_CHAR | WE_MAX_STR_LEN,
10614 "listProfile"},
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080010615 {WE_GET_STATES,
10616 0,
10617 IW_PRIV_TYPE_CHAR | WE_MAX_STR_LEN,
10618 "getHostStates"},
10619 {WE_GET_CFG,
10620 0,
10621 IW_PRIV_TYPE_CHAR | WE_MAX_STR_LEN,
10622 "getConfig"},
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080010623 {WE_GET_RSSI,
10624 0,
10625 IW_PRIV_TYPE_CHAR | WE_MAX_STR_LEN,
10626 "getRSSI"},
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080010627 {WE_GET_WMM_STATUS,
10628 0,
10629 IW_PRIV_TYPE_CHAR | WE_MAX_STR_LEN,
10630 "getWmmStatus"},
10631 {
10632 WE_GET_CHANNEL_LIST,
10633 0,
10634 IW_PRIV_TYPE_CHAR | WE_MAX_STR_LEN,
10635 "getChannelList"
10636 },
10637#ifdef FEATURE_WLAN_TDLS
10638 {
10639 WE_GET_TDLS_PEERS,
10640 0,
10641 IW_PRIV_TYPE_CHAR | WE_MAX_STR_LEN,
10642 "getTdlsPeers"
10643 },
10644#endif
10645#ifdef WLAN_FEATURE_11W
10646 {
10647 WE_GET_11W_INFO,
10648 0,
10649 IW_PRIV_TYPE_CHAR | WE_MAX_STR_LEN,
10650 "getPMFInfo"
10651 },
10652#endif
Rajeev Kumar8e3e2832015-11-06 16:02:54 -080010653 {
10654 WE_GET_IBSS_STA_INFO,
10655 0,
10656 IW_PRIV_TYPE_CHAR | WE_MAX_STR_LEN,
10657 "getIbssSTAs"
10658 },
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080010659 {WE_GET_PHYMODE,
10660 0,
10661 IW_PRIV_TYPE_CHAR | WE_MAX_STR_LEN,
10662 "getphymode"},
10663#ifdef FEATURE_OEM_DATA_SUPPORT
10664 {WE_GET_OEM_DATA_CAP,
10665 0,
10666 IW_PRIV_TYPE_CHAR | WE_MAX_STR_LEN,
10667 "getOemDataCap"},
10668#endif /* FEATURE_OEM_DATA_SUPPORT */
10669 {WE_GET_SNR,
10670 0,
10671 IW_PRIV_TYPE_CHAR | WE_MAX_STR_LEN,
10672 "getSNR"},
10673
10674 /* handlers for main ioctl */
10675 {WLAN_PRIV_SET_NONE_GET_NONE,
10676 0,
10677 0,
10678 ""},
10679
Rajeev Kumar8e3e2832015-11-06 16:02:54 -080010680 /* handlers for sub-ioctl */
10681 {
10682 WE_IBSS_GET_PEER_INFO_ALL,
10683 0,
10684 0,
10685 "ibssPeerInfoAll"
10686 },
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080010687 {WE_GET_RECOVERY_STAT,
10688 0,
10689 0,
10690 "getRecoverStat"},
Govind Singha471e5e2015-10-12 17:11:14 +053010691
10692 {WE_GET_FW_PROFILE_DATA,
10693 0,
10694 0,
10695 "getProfileData"},
10696
10697 {WE_SET_REASSOC_TRIGGER,
10698 0,
10699 0,
10700 "reassoc"},
10701
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080010702 {WE_DUMP_AGC_START,
10703 0,
10704 0,
10705 "dump_agc_start"},
10706
10707 {WE_DUMP_AGC,
10708 0,
10709 0,
10710 "dump_agc"},
10711
10712 {WE_DUMP_CHANINFO_START,
10713 0,
10714 0,
10715 "dump_chninfo_en"},
10716
10717 {WE_DUMP_CHANINFO,
10718 0,
10719 0,
10720 "dump_chninfo"},
10721
10722 {WE_DUMP_WATCHDOG,
10723 0,
10724 0,
10725 "dump_watchdog"},
10726#ifdef CONFIG_ATH_PCIE_ACCESS_DEBUG
10727 {WE_DUMP_PCIE_LOG,
10728 0,
10729 0,
10730 "dump_pcie_log"},
10731#endif
Sandeep Puligilla93a29ec2016-02-12 16:10:56 -080010732 {WE_STOP_OBSS_SCAN,
10733 0,
10734 0,
10735 "stop_obss_scan"},
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080010736 /* handlers for main ioctl */
10737 {WLAN_PRIV_SET_VAR_INT_GET_NONE,
10738 IW_PRIV_TYPE_INT | MAX_VAR_ARGS,
10739 0,
10740 ""},
10741
10742 /* handlers for sub-ioctl */
Rajeev Kumar8e3e2832015-11-06 16:02:54 -080010743 {WE_IBSS_GET_PEER_INFO,
10744 IW_PRIV_TYPE_INT | MAX_VAR_ARGS,
10745 0,
10746 "ibssPeerInfo"},
10747
10748 /* handlers for sub-ioctl */
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080010749 {WE_MTRACE_SELECTIVE_MODULE_LOG_ENABLE_CMD,
10750 IW_PRIV_TYPE_INT | MAX_VAR_ARGS,
10751 0,
10752 "setdumplog"},
10753
10754 {WE_MTRACE_DUMP_CMD,
10755 IW_PRIV_TYPE_INT | MAX_VAR_ARGS,
10756 0,
10757 "dumplog"},
10758#ifdef MPC_UT_FRAMEWORK
10759 {WE_POLICY_MANAGER_CLIST_CMD,
10760 IW_PRIV_TYPE_INT | MAX_VAR_ARGS,
10761 0,
10762 "pm_clist"},
10763
10764 {WE_POLICY_MANAGER_DLIST_CMD,
10765 IW_PRIV_TYPE_INT | MAX_VAR_ARGS,
10766 0,
10767 "pm_dlist"},
10768
10769 {WE_POLICY_MANAGER_DBS_CMD,
10770 IW_PRIV_TYPE_INT | MAX_VAR_ARGS,
10771 0,
10772 "pm_dbs"},
10773
10774 {WE_POLICY_MANAGER_PCL_CMD,
10775 IW_PRIV_TYPE_INT | MAX_VAR_ARGS,
10776 0,
10777 "pm_pcl"},
10778
10779 {WE_POLICY_MANAGER_CINFO_CMD,
10780 IW_PRIV_TYPE_INT | MAX_VAR_ARGS,
10781 0,
10782 "pm_cinfo"},
10783
10784 {WE_POLICY_MANAGER_ULIST_CMD,
10785 IW_PRIV_TYPE_INT | MAX_VAR_ARGS,
10786 0,
10787 "pm_ulist"},
10788
10789 {WE_POLICY_MANAGER_QUERY_ACTION_CMD,
10790 IW_PRIV_TYPE_INT | MAX_VAR_ARGS,
10791 0,
10792 "pm_query_action"},
10793
10794 {WE_POLICY_MANAGER_QUERY_ALLOW_CMD,
10795 IW_PRIV_TYPE_INT | MAX_VAR_ARGS,
10796 0,
10797 "pm_query_allow"},
10798
10799 {WE_POLICY_MANAGER_SCENARIO_CMD,
10800 IW_PRIV_TYPE_INT | MAX_VAR_ARGS,
10801 0,
10802 "pm_run_scenario"},
10803
10804 {WE_POLICY_SET_HW_MODE_CMD,
10805 IW_PRIV_TYPE_INT | MAX_VAR_ARGS,
10806 0,
10807 "pm_set_hw_mode"},
10808#endif
10809#ifdef FEATURE_WLAN_TDLS
10810 /* handlers for sub ioctl */
10811 {
10812 WE_TDLS_CONFIG_PARAMS,
10813 IW_PRIV_TYPE_INT | MAX_VAR_ARGS,
10814 0,
10815 "setTdlsConfig"
10816 },
10817#endif
10818 {
10819 WE_UNIT_TEST_CMD,
10820 IW_PRIV_TYPE_INT | MAX_VAR_ARGS,
10821 0,
10822 "setUnitTestCmd"
10823 },
Manjeet Singhf82ed072016-07-08 11:40:00 +053010824 {
10825 WE_MAC_PWR_DEBUG_CMD,
10826 IW_PRIV_TYPE_INT | MAX_VAR_ARGS,
10827 0,
10828 "halPwrDebug"
10829 },
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080010830
10831#ifdef WLAN_FEATURE_GPIO_LED_FLASHING
10832 {WE_LED_FLASHING_PARAM,
10833 IW_PRIV_TYPE_INT | MAX_VAR_ARGS,
10834 0,
10835 "gpio_control"},
10836#endif
10837 /* handlers for main ioctl */
10838 {WLAN_PRIV_ADD_TSPEC,
10839 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | HDD_WLAN_WMM_PARAM_COUNT,
10840 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10841 "addTspec"},
10842
10843 /* handlers for main ioctl */
10844 {WLAN_PRIV_DEL_TSPEC,
10845 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10846 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10847 "delTspec"},
10848
10849 /* handlers for main ioctl */
10850 {WLAN_PRIV_GET_TSPEC,
10851 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10852 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10853 "getTspec"},
10854
10855 /* handlers for main ioctl - host offload */
10856 {
10857 WLAN_PRIV_SET_HOST_OFFLOAD,
10858 IW_PRIV_TYPE_BYTE | sizeof(tHostOffloadRequest),
10859 0,
10860 "setHostOffload"
10861 }
10862 ,
10863
10864 {
10865 WLAN_GET_WLAN_STATISTICS,
10866 0,
10867 IW_PRIV_TYPE_BYTE | WE_MAX_STR_LEN,
10868 "getWlanStats"
10869 }
10870 ,
10871
10872 {
10873 WLAN_SET_KEEPALIVE_PARAMS,
Mahesh A Saptasagar72d2e4b2016-04-20 12:44:17 +053010874 IW_PRIV_TYPE_BYTE | sizeof(tSirKeepAliveReq) |
10875 IW_PRIV_SIZE_FIXED,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080010876 0,
10877 "setKeepAlive"
10878 }
10879 ,
10880#ifdef WLAN_FEATURE_PACKET_FILTERING
10881 {
10882 WLAN_SET_PACKET_FILTER_PARAMS,
10883 IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED |
10884 sizeof(struct pkt_filter_cfg),
10885 0,
10886 "setPktFilter"
10887 }
10888 ,
10889#endif
10890#ifdef FEATURE_WLAN_SCAN_PNO
10891 {
10892 WLAN_SET_PNO,
10893 IW_PRIV_TYPE_CHAR | WE_MAX_STR_LEN,
10894 0,
10895 "setpno"
10896 }
10897 ,
10898#endif
10899 {
10900 WLAN_SET_BAND_CONFIG,
10901 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10902 0,
10903 "SETBAND"
10904 }
10905 ,
10906 {
10907 WLAN_GET_LINK_SPEED,
10908 IW_PRIV_TYPE_CHAR | 18,
10909 IW_PRIV_TYPE_CHAR | 5, "getLinkSpeed"
10910 }
10911 ,
10912
10913 /* handlers for main ioctl */
10914 {WLAN_PRIV_SET_TWO_INT_GET_NONE,
10915 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2,
10916 0,
10917 ""}
10918 ,
10919 {WE_SET_SMPS_PARAM,
10920 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2,
10921 0, "set_smps_param"}
10922 ,
10923 {WLAN_SET_DOT11P_CHANNEL_SCHED,
10924 IW_PRIV_TYPE_BYTE | sizeof(struct dot11p_channel_sched),
10925 0, "set_dot11p" }
10926 ,
10927#ifdef DEBUG
10928 {WE_SET_FW_CRASH_INJECT,
10929 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2,
10930 0, "crash_inject"}
10931 ,
10932#endif
Rajeev Kumara78a0a42016-07-13 19:28:20 -070010933#ifdef WLAN_SUSPEND_RESUME_TEST
10934 {WE_SET_WLAN_SUSPEND,
10935 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2,
10936 0, "wlan_suspend"}
10937 ,
10938 {WE_SET_WLAN_RESUME,
10939 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2,
10940 0, "wlan_resume"}
10941 ,
10942#endif
Govind Singha471e5e2015-10-12 17:11:14 +053010943 {WE_ENABLE_FW_PROFILE,
10944 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2,
10945 0, "enableProfile"}
10946 ,
10947 {WE_SET_FW_PROFILE_HIST_INTVL,
10948 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2,
10949 0, "set_hist_intvl"}
10950 ,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080010951 {WE_SET_DUAL_MAC_FW_MODE_CONFIG,
10952 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2,
10953 0, "set_fw_mode_cfg"}
10954 ,
10955 {WE_DUMP_DP_TRACE_LEVEL,
10956 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2,
10957 0, "dump_dp_trace"}
10958 ,
Manjunathappa Prakash59f861d2016-04-21 10:33:31 -070010959 {WE_SET_MON_MODE_CHAN,
10960 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2,
10961 0, "setMonChan"}
10962 ,
Varun Reddy Yeturu5ab47462016-05-08 18:08:11 -070010963
10964 {WE_GET_ROAM_SYNCH_DELAY,
10965 0,
10966 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10967 "hostroamdelay"}
10968 ,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080010969};
10970
10971const struct iw_handler_def we_handler_def = {
Anurag Chouhan6d760662016-02-20 16:05:43 +053010972 .num_standard = QDF_ARRAY_SIZE(we_handler),
10973 .num_private = QDF_ARRAY_SIZE(we_private),
10974 .num_private_args = QDF_ARRAY_SIZE(we_private_args),
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080010975
10976 .standard = (iw_handler *) we_handler,
10977 .private = (iw_handler *) we_private,
10978 .private_args = we_private_args,
10979 .get_wireless_stats = NULL,
10980};
10981
Deepak Dhamdhere8360d4c2016-06-01 13:24:31 -070010982/* hdd_set_wext() - configures bss parameters
10983 * @pAdapter: handle to adapter context
10984 *
10985 * Returns: none
10986 */
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080010987int hdd_set_wext(hdd_adapter_t *pAdapter)
10988{
Deepak Dhamdhere8360d4c2016-06-01 13:24:31 -070010989 hdd_wext_state_t *pwextBuf = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
10990 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080010991
Deepak Dhamdhere8360d4c2016-06-01 13:24:31 -070010992 ENTER();
10993
10994 if (!pwextBuf) {
10995 hdd_err("ERROR: pwextBuf is NULL");
10996 return QDF_STATUS_E_FAILURE;
10997 }
10998
10999 if (!pHddStaCtx) {
11000 hdd_err("ERROR: pHddStaCtx is NULL");
11001 return QDF_STATUS_E_FAILURE;
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -070011002 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011003
11004 /* Now configure the roaming profile links. To SSID and bssid. */
11005 pwextBuf->roamProfile.SSIDs.numOfSSIDs = 0;
Deepak Dhamdhere8360d4c2016-06-01 13:24:31 -070011006 pwextBuf->roamProfile.SSIDs.SSIDList = &pHddStaCtx->conn_info.SSID;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011007
11008 pwextBuf->roamProfile.BSSIDs.numOfBSSIDs = 0;
Deepak Dhamdhere8360d4c2016-06-01 13:24:31 -070011009 pwextBuf->roamProfile.BSSIDs.bssid = &pHddStaCtx->conn_info.bssId;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011010
11011 /*Set the numOfChannels to zero to scan all the channels */
11012 pwextBuf->roamProfile.ChannelInfo.numOfChannels = 0;
11013 pwextBuf->roamProfile.ChannelInfo.ChannelList = NULL;
11014
11015 /* Default is no encryption */
11016 pwextBuf->roamProfile.EncryptionType.numEntries = 1;
11017 pwextBuf->roamProfile.EncryptionType.encryptionType[0] =
11018 eCSR_ENCRYPT_TYPE_NONE;
11019
11020 pwextBuf->roamProfile.mcEncryptionType.numEntries = 1;
11021 pwextBuf->roamProfile.mcEncryptionType.encryptionType[0] =
11022 eCSR_ENCRYPT_TYPE_NONE;
11023
11024 pwextBuf->roamProfile.BSSType = eCSR_BSS_TYPE_INFRASTRUCTURE;
11025
11026 /* Default is no authentication */
11027 pwextBuf->roamProfile.AuthType.numEntries = 1;
11028 pwextBuf->roamProfile.AuthType.authType[0] = eCSR_AUTH_TYPE_OPEN_SYSTEM;
11029
11030 pwextBuf->roamProfile.phyMode = eCSR_DOT11_MODE_AUTO;
11031 pwextBuf->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
11032
11033 /*Set the default scan mode */
11034 pAdapter->scan_info.scan_mode = eSIR_ACTIVE_SCAN;
11035
11036 hdd_clear_roam_profile_ie(pAdapter);
11037
Deepak Dhamdhere8360d4c2016-06-01 13:24:31 -070011038 EXIT();
Anurag Chouhanfb54ab02016-02-18 18:00:46 +053011039 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011040
11041}
11042
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -070011043/**
11044 * hdd_register_wext() - register wext context
11045 * @dev: net device handle
11046 *
11047 * Registers wext interface context for a given net device
11048 *
11049 * Returns: 0 on success, errno on failure
11050 */
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011051int hdd_register_wext(struct net_device *dev)
11052{
11053 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Deepak Dhamdhere8360d4c2016-06-01 13:24:31 -070011054 hdd_wext_state_t *pwextBuf = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Anurag Chouhance0dc992016-02-16 18:18:03 +053011055 QDF_STATUS status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011056
11057 ENTER();
11058
Deepak Dhamdhere8360d4c2016-06-01 13:24:31 -070011059 if (!pwextBuf) {
11060 hdd_err(FL("ERROR: pwextBuf is NULL"));
11061 return QDF_STATUS_E_FAILURE;
11062 }
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -070011063
11064 /* Zero the memory. This zeros the profile structure */
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011065 memset(pwextBuf, 0, sizeof(hdd_wext_state_t));
11066
11067 init_completion(&(WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter))->
11068 completion_var);
11069
11070 status = hdd_set_wext(pAdapter);
11071
Anurag Chouhance0dc992016-02-16 18:18:03 +053011072 if (!QDF_IS_STATUS_SUCCESS(status)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011073
Jeff Johnson99bac312016-06-28 10:38:18 -070011074 hdd_err("ERROR: hdd_set_wext failed!!");
Anurag Chouhanfb54ab02016-02-18 18:00:46 +053011075 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011076 }
11077
Anurag Chouhanf04e84f2016-03-03 10:12:12 +053011078 if (!QDF_IS_STATUS_SUCCESS(qdf_event_create(&pwextBuf->hdd_qdf_event))) {
Jeff Johnson99bac312016-06-28 10:38:18 -070011079 hdd_err("ERROR: HDD qdf event init failed!!");
Anurag Chouhanfb54ab02016-02-18 18:00:46 +053011080 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011081 }
11082
Anurag Chouhance0dc992016-02-16 18:18:03 +053011083 if (!QDF_IS_STATUS_SUCCESS(qdf_event_create(&pwextBuf->scanevent))) {
Jeff Johnson99bac312016-06-28 10:38:18 -070011084 hdd_err("ERROR: HDD scan event init failed!!");
Anurag Chouhanfb54ab02016-02-18 18:00:46 +053011085 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011086 }
11087 /* Register as a wireless device */
11088 dev->wireless_handlers = (struct iw_handler_def *)&we_handler_def;
11089
11090 EXIT();
11091 return 0;
11092}
11093
11094int hdd_unregister_wext(struct net_device *dev)
11095{
Jeff Johnson99bac312016-06-28 10:38:18 -070011096 hdd_notice("dev(%p)", dev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011097
11098 if (dev != NULL) {
11099 rtnl_lock();
11100 dev->wireless_handlers = NULL;
11101 rtnl_unlock();
11102 }
11103
11104 return 0;
11105}