blob: bc5a26a8b1bce7181cb0b0ae79c804a822efb571 [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);
Manjeet Singhfde0c042016-09-03 12:08:09 +05302740 if (QDF_STATUS_SUCCESS != status) {
2741 hdd_notice("failed to get WPA-RSN IE data");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002742 return -EFAULT;
2743 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002744 wrqu->data.length = length;
Manjeet Singhfde0c042016-09-03 12:08:09 +05302745 if (length > DOT11F_IE_RSN_MAX_LEN) {
2746 hdd_notice("invalid buffer length length:%d", length);
2747 return -E2BIG;
2748 }
2749 qdf_mem_copy(extra, (void *)genIeBytes, length);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002750
Jeff Johnson99bac312016-06-28 10:38:18 -07002751 hdd_notice("RSN IE of %d bytes returned",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002752 wrqu->data.length);
2753
2754 EXIT();
2755
2756 return 0;
2757}
2758
2759/**
2760 * iw_get_genie() - SSR wrapper for __iw_get_genie()
2761 * @dev: pointer to net_device
2762 * @info: pointer to iw_request_info
2763 * @wrqu: pointer to iwreq_data
2764 * @extra: pointer to extra ioctl payload
2765 *
2766 * Return: 0 on success, error number otherwise
2767 */
2768static int iw_get_genie(struct net_device *dev,
2769 struct iw_request_info *info,
2770 union iwreq_data *wrqu, char *extra)
2771{
2772 int ret;
2773
2774 cds_ssr_protect(__func__);
2775 ret = __iw_get_genie(dev, info, wrqu, extra);
2776 cds_ssr_unprotect(__func__);
2777
2778 return ret;
2779}
2780
2781/**
2782 * __iw_get_encode() - SIOCGIWENCODE ioctl handler
2783 * @dev: device upon which the ioctl was received
2784 * @info: ioctl request information
2785 * @wrqu: ioctl request data
2786 * @extra: ioctl extra data
2787 *
2788 * Return: 0 on success, non-zero on error
2789 */
2790static int __iw_get_encode(struct net_device *dev,
2791 struct iw_request_info *info,
2792 struct iw_point *dwrq, char *extra)
2793{
2794 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
2795 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
2796 tCsrRoamProfile *pRoamProfile = &(pWextState->roamProfile);
2797 int keyId;
2798 eCsrAuthType authType = eCSR_AUTH_TYPE_NONE;
2799 int i;
2800 hdd_context_t *hdd_ctx;
2801 int ret;
2802
Jeff Johnsonb25dcb12016-02-11 17:46:42 -08002803 ENTER_DEV(dev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002804
2805 hdd_ctx = WLAN_HDD_GET_CTX(pAdapter);
2806 ret = wlan_hdd_validate_context(hdd_ctx);
2807 if (0 != ret)
2808 return ret;
2809
2810 keyId = pRoamProfile->Keys.defaultIndex;
2811
2812 if (keyId < 0 || keyId >= MAX_WEP_KEYS) {
Jeff Johnson99bac312016-06-28 10:38:18 -07002813 hdd_notice("Invalid keyId : %d", keyId);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002814 return -EINVAL;
2815 }
2816
2817 if (pRoamProfile->Keys.KeyLength[keyId] > 0) {
2818 dwrq->flags |= IW_ENCODE_ENABLED;
2819 dwrq->length = pRoamProfile->Keys.KeyLength[keyId];
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302820 qdf_mem_copy(extra, &(pRoamProfile->Keys.KeyMaterial[keyId][0]),
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002821 pRoamProfile->Keys.KeyLength[keyId]);
2822
2823 dwrq->flags |= (keyId + 1);
2824
2825 } else {
2826 dwrq->flags |= IW_ENCODE_DISABLED;
2827 }
2828
2829 for (i = 0; i < MAX_WEP_KEYS; i++) {
2830 if (pRoamProfile->Keys.KeyMaterial[i] == NULL) {
2831 continue;
2832 } else {
2833 break;
2834 }
2835 }
2836
2837 if (MAX_WEP_KEYS == i) {
2838 dwrq->flags |= IW_ENCODE_NOKEY;
2839 }
2840
2841 authType =
2842 ((hdd_station_ctx_t *) WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->
2843 conn_info.authType;
2844
2845 if (eCSR_AUTH_TYPE_OPEN_SYSTEM == authType) {
2846 dwrq->flags |= IW_ENCODE_OPEN;
2847 } else {
2848 dwrq->flags |= IW_ENCODE_RESTRICTED;
2849 }
2850 EXIT();
2851 return 0;
2852}
2853
2854/**
2855 * iw_get_encode() - SSR wrapper for __iw_get_encode()
2856 * @dev: pointer to net_device
2857 * @info: pointer to iw_request_info
2858 * @dwrq: pointer to encoding information
2859 * @extra: pointer to extra ioctl payload
2860 *
2861 * Return: 0 on success, error number otherwise
2862 */
2863static int iw_get_encode(struct net_device *dev, struct iw_request_info *info,
2864 struct iw_point *dwrq, char *extra)
2865{
2866 int ret;
2867
2868 cds_ssr_protect(__func__);
2869 ret = __iw_get_encode(dev, info, dwrq, extra);
2870 cds_ssr_unprotect(__func__);
2871
2872 return ret;
2873}
2874
2875/**
2876 * __iw_get_rts_threshold() - SIOCGIWRTS ioctl handler
2877 * @dev: device upon which the ioctl was received
2878 * @info: ioctl request information
2879 * @wrqu: ioctl request data
2880 * @extra: ioctl extra data
2881 *
2882 * Return: 0 on success, non-zero on error
2883 */
2884static int __iw_get_rts_threshold(struct net_device *dev,
2885 struct iw_request_info *info,
2886 union iwreq_data *wrqu, char *extra)
2887{
2888 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
2889 uint32_t status = 0;
2890
Jeff Johnsonb25dcb12016-02-11 17:46:42 -08002891 ENTER_DEV(dev);
2892
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002893 status = hdd_wlan_get_rts_threshold(pAdapter, wrqu);
2894
2895 return status;
2896}
2897
2898/**
2899 * __iw_set_rts_threshold() - SIOCSIWRTS ioctl handler
2900 * @dev: device upon which the ioctl was received
2901 * @info: ioctl request information
2902 * @wrqu: ioctl request data
2903 * @extra: ioctl extra data
2904 *
2905 * Return: 0 on success, non-zero on error
2906 */
2907static int __iw_set_rts_threshold(struct net_device *dev,
2908 struct iw_request_info *info,
2909 union iwreq_data *wrqu, char *extra)
2910{
2911 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
2912 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
2913 hdd_context_t *hdd_ctx;
2914 int ret;
2915
Jeff Johnsonb25dcb12016-02-11 17:46:42 -08002916 ENTER_DEV(dev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002917
2918 hdd_ctx = WLAN_HDD_GET_CTX(pAdapter);
2919 ret = wlan_hdd_validate_context(hdd_ctx);
2920 if (0 != ret)
2921 return ret;
2922
2923 if (wrqu->rts.value < WNI_CFG_RTS_THRESHOLD_STAMIN
2924 || wrqu->rts.value > WNI_CFG_RTS_THRESHOLD_STAMAX) {
2925 return -EINVAL;
2926 }
2927
2928 if (sme_cfg_set_int(hHal, WNI_CFG_RTS_THRESHOLD, wrqu->rts.value) !=
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302929 QDF_STATUS_SUCCESS) {
Jeff Johnson99bac312016-06-28 10:38:18 -07002930 hdd_err("failed to set ini parameter, WNI_CFG_RTS_THRESHOLD");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002931 return -EIO;
2932 }
2933
2934 EXIT();
2935
2936 return 0;
2937}
2938
2939/**
2940 * iw_get_rts_threshold() - SSR wrapper for __iw_get_rts_threshold()
2941 * @dev: pointer to net_device
2942 * @info: pointer to iw_request_info
2943 * @wrqu: pointer to iwreq_data
2944 * @extra: pointer to extra ioctl payload
2945 *
2946 * Return: 0 on success, error number otherwise
2947 */
2948static int iw_get_rts_threshold(struct net_device *dev,
2949 struct iw_request_info *info,
2950 union iwreq_data *wrqu, char *extra)
2951{
2952 int ret;
2953
2954 cds_ssr_protect(__func__);
2955 ret = __iw_get_rts_threshold(dev, info, wrqu, extra);
2956 cds_ssr_unprotect(__func__);
2957
2958 return ret;
2959}
2960
2961/**
2962 * iw_set_rts_threshold() - SSR wrapper for __iw_set_rts_threshold()
2963 * @dev: pointer to net_device
2964 * @info: pointer to iw_request_info
2965 * @wrqu: pointer to iwreq_data
2966 * @extra: pointer to extra ioctl payload
2967 *
2968 * Return: 0 on success, error number otherwise
2969 */
2970static int iw_set_rts_threshold(struct net_device *dev,
2971 struct iw_request_info *info,
2972 union iwreq_data *wrqu, char *extra)
2973{
2974 int ret;
2975
2976 cds_ssr_protect(__func__);
2977 ret = __iw_set_rts_threshold(dev, info, wrqu, extra);
2978 cds_ssr_unprotect(__func__);
2979
2980 return ret;
2981}
2982
2983/**
2984 * __iw_get_frag_threshold() - SIOCGIWFRAG ioctl handler
2985 * @dev: device upon which the ioctl was received
2986 * @info: ioctl request information
2987 * @wrqu: ioctl request data
2988 * @extra: ioctl extra data
2989 *
2990 * Return: 0 on success, non-zero on error
2991 */
2992static int __iw_get_frag_threshold(struct net_device *dev,
2993 struct iw_request_info *info,
2994 union iwreq_data *wrqu, char *extra)
2995{
2996 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
2997 uint32_t status = 0;
2998
Jeff Johnsonb25dcb12016-02-11 17:46:42 -08002999 ENTER_DEV(dev);
3000
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003001 status = hdd_wlan_get_frag_threshold(pAdapter, wrqu);
3002
3003 return status;
3004}
3005
3006/**
3007 * iw_get_frag_threshold() - SSR wrapper for __iw_get_frag_threshold()
3008 * @dev: pointer to net_device
3009 * @info: pointer to iw_request_info
3010 * @wrqu: pointer to iwreq_data
3011 * @extra: pointer to extra ioctl payload
3012 *
3013 * Return: 0 on success, error number otherwise
3014 */
3015static int iw_get_frag_threshold(struct net_device *dev,
3016 struct iw_request_info *info,
3017 union iwreq_data *wrqu, char *extra)
3018{
3019 int ret;
3020
3021 cds_ssr_protect(__func__);
3022 ret = __iw_get_frag_threshold(dev, info, wrqu, extra);
3023 cds_ssr_unprotect(__func__);
3024
3025 return ret;
3026}
3027
3028/**
3029 * __iw_set_frag_threshold() - SIOCSIWFRAG ioctl handler
3030 * @dev: device upon which the ioctl was received
3031 * @info: ioctl request information
3032 * @wrqu: ioctl request data
3033 * @extra: ioctl extra data
3034 *
3035 * Return: 0 on success, non-zero on error
3036 */
3037static int __iw_set_frag_threshold(struct net_device *dev,
3038 struct iw_request_info *info,
3039 union iwreq_data *wrqu, char *extra)
3040{
3041 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3042 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
3043 hdd_context_t *hdd_ctx;
3044 int ret;
3045
Jeff Johnsonb25dcb12016-02-11 17:46:42 -08003046 ENTER_DEV(dev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003047
3048 hdd_ctx = WLAN_HDD_GET_CTX(pAdapter);
3049 ret = wlan_hdd_validate_context(hdd_ctx);
3050 if (0 != ret)
3051 return ret;
3052
3053 if (wrqu->frag.value < WNI_CFG_FRAGMENTATION_THRESHOLD_STAMIN
3054 || wrqu->frag.value > WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX) {
3055 return -EINVAL;
3056 }
3057
3058 if (sme_cfg_set_int
3059 (hHal, WNI_CFG_FRAGMENTATION_THRESHOLD, wrqu->frag.value)
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303060 != QDF_STATUS_SUCCESS) {
Jeff Johnson99bac312016-06-28 10:38:18 -07003061 hdd_err("failed to set ini parameter, WNI_CFG_FRAGMENTATION_THRESHOLD");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003062 return -EIO;
3063 }
3064
3065 EXIT();
3066
3067 return 0;
3068}
3069
3070/**
3071 * iw_set_frag_threshold() - SSR wrapper for __iw_set_frag_threshold()
3072 * @dev: pointer to net_device
3073 * @info: pointer to iw_request_info
3074 * @wrqu: pointer to iwreq_data
3075 * @extra: pointer to extra ioctl payload
3076 *
3077 * Return: 0 on success, error number otherwise
3078 */
3079static int iw_set_frag_threshold(struct net_device *dev,
3080 struct iw_request_info *info,
3081 union iwreq_data *wrqu, char *extra)
3082{
3083 int ret;
3084
3085 cds_ssr_protect(__func__);
3086 ret = __iw_set_frag_threshold(dev, info, wrqu, extra);
3087 cds_ssr_unprotect(__func__);
3088
3089 return ret;
3090}
3091
3092/**
3093 * __iw_get_power_mode() - SIOCGIWPOWER ioctl handler
3094 * @dev: device upon which the ioctl was received
3095 * @info: ioctl request information
3096 * @wrqu: ioctl request data
3097 * @extra: ioctl extra data
3098 *
3099 * Return: 0 on success, non-zero on error
3100 */
3101static int __iw_get_power_mode(struct net_device *dev,
3102 struct iw_request_info *info,
3103 union iwreq_data *wrqu, char *extra)
3104{
3105 hdd_adapter_t *adapter;
3106 hdd_context_t *hdd_ctx;
3107 int ret;
3108
Jeff Johnsonb25dcb12016-02-11 17:46:42 -08003109 ENTER_DEV(dev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003110
3111 adapter = WLAN_HDD_GET_PRIV_PTR(dev);
3112 hdd_ctx = WLAN_HDD_GET_CTX(adapter);
3113 ret = wlan_hdd_validate_context(hdd_ctx);
3114 if (0 != ret)
3115 return ret;
3116
3117 return -EOPNOTSUPP;
3118}
3119
3120/**
3121 * iw_get_power_mode() - SSR wrapper function for __iw_get_power_mode
3122 * @dev: pointer to net_device
3123 * @info: pointer to iw_request_info
3124 * @wrqu: pointer to iwreq_data
3125 * @extra: extra
3126 *
3127 * Return: 0 on success, error number otherwise
3128 */
3129int iw_get_power_mode(struct net_device *dev,
3130 struct iw_request_info *info,
3131 union iwreq_data *wrqu, char *extra)
3132{
3133 int ret;
3134
3135 cds_ssr_protect(__func__);
3136 ret = __iw_get_power_mode(dev, info, wrqu, extra);
3137 cds_ssr_unprotect(__func__);
3138
3139 return ret;
3140}
3141
3142/**
3143 * __iw_set_power_mode() - SIOCSIWPOWER ioctl handler
3144 * @dev: device upon which the ioctl was received
3145 * @info: ioctl request information
3146 * @wrqu: ioctl request data
3147 * @extra: ioctl extra data
3148 *
3149 * Return: 0 on success, non-zero on error
3150 */
3151static int __iw_set_power_mode(struct net_device *dev,
3152 struct iw_request_info *info,
3153 union iwreq_data *wrqu, char *extra)
3154{
3155 hdd_adapter_t *adapter;
3156 hdd_context_t *hdd_ctx;
3157 int ret;
3158
Jeff Johnsonb25dcb12016-02-11 17:46:42 -08003159 ENTER_DEV(dev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003160
3161 adapter = WLAN_HDD_GET_PRIV_PTR(dev);
3162 hdd_ctx = WLAN_HDD_GET_CTX(adapter);
3163 ret = wlan_hdd_validate_context(hdd_ctx);
3164 if (0 != ret)
3165 return ret;
3166
3167 return -EOPNOTSUPP;
3168}
3169
3170/**
3171 * iw_set_power_mode() - SSR wrapper function for __iw_set_power_mode
3172 * @dev: pointer to net_device
3173 * @info: pointer to iw_request_info
3174 * @wrqu: pointer to iwreq_data
3175 * @extra: extra
3176 *
3177 * Return: 0 on success, error number otherwise
3178 */
3179int iw_set_power_mode(struct net_device *dev,
3180 struct iw_request_info *info,
3181 union iwreq_data *wrqu, char *extra)
3182{
3183 int ret;
3184
3185 cds_ssr_protect(__func__);
3186 ret = __iw_set_power_mode(dev, info, wrqu, extra);
3187 cds_ssr_unprotect(__func__);
3188
3189 return ret;
3190}
3191
3192/**
3193 * __iw_get_range() - SIOCGIWRANGE ioctl handler
3194 * @dev: device upon which the ioctl was received
3195 * @info: ioctl request information
3196 * @wrqu: ioctl request data
3197 * @extra: ioctl extra data
3198 *
3199 * Return: 0 on success, non-zero on error
3200 */
3201static int __iw_get_range(struct net_device *dev, struct iw_request_info *info,
3202 union iwreq_data *wrqu, char *extra)
3203{
3204 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3205 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
3206 struct iw_range *range = (struct iw_range *)extra;
3207
3208 uint8_t channels[WNI_CFG_VALID_CHANNEL_LIST_LEN];
3209
3210 uint32_t num_channels = sizeof(channels);
3211 uint8_t supp_rates[WNI_CFG_SUPPORTED_RATES_11A_LEN];
3212 uint32_t a_len;
3213 uint32_t b_len;
3214 uint32_t active_phy_mode = 0;
3215 uint8_t index = 0, i;
3216 hdd_context_t *hdd_ctx;
3217 int ret;
3218
Jeff Johnsonb25dcb12016-02-11 17:46:42 -08003219 ENTER_DEV(dev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003220
3221 hdd_ctx = WLAN_HDD_GET_CTX(pAdapter);
3222 ret = wlan_hdd_validate_context(hdd_ctx);
3223 if (0 != ret)
3224 return ret;
3225
3226 wrqu->data.length = sizeof(struct iw_range);
3227 memset(range, 0, sizeof(struct iw_range));
3228
3229
3230 /*Get the phy mode */
3231 if (sme_cfg_get_int(hHal,
3232 WNI_CFG_DOT11_MODE,
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303233 &active_phy_mode) == QDF_STATUS_SUCCESS) {
Jeff Johnson99bac312016-06-28 10:38:18 -07003234 hdd_notice("active_phy_mode = %d", active_phy_mode);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003235
3236 if (active_phy_mode == WNI_CFG_DOT11_MODE_11A
3237 || active_phy_mode == WNI_CFG_DOT11_MODE_11G) {
3238 /*Get the supported rates for 11G band */
3239 a_len = WNI_CFG_SUPPORTED_RATES_11A_LEN;
3240 if (sme_cfg_get_str(hHal,
3241 WNI_CFG_SUPPORTED_RATES_11A,
3242 supp_rates,
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303243 &a_len) == QDF_STATUS_SUCCESS) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003244 if (a_len > WNI_CFG_SUPPORTED_RATES_11A_LEN) {
3245 a_len = WNI_CFG_SUPPORTED_RATES_11A_LEN;
3246 }
3247 for (i = 0; i < a_len; i++) {
3248 range->bitrate[i] =
3249 ((supp_rates[i] & 0x7F) / 2) *
3250 1000000;
3251 }
3252 range->num_bitrates = a_len;
3253 } else {
3254 return -EIO;
3255 }
3256 } else if (active_phy_mode == WNI_CFG_DOT11_MODE_11B) {
3257 /*Get the supported rates for 11B band */
3258 b_len = WNI_CFG_SUPPORTED_RATES_11B_LEN;
3259 if (sme_cfg_get_str(hHal,
3260 WNI_CFG_SUPPORTED_RATES_11B,
3261 supp_rates,
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303262 &b_len) == QDF_STATUS_SUCCESS) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003263 if (b_len > WNI_CFG_SUPPORTED_RATES_11B_LEN) {
3264 b_len = WNI_CFG_SUPPORTED_RATES_11B_LEN;
3265 }
3266 for (i = 0; i < b_len; i++) {
3267 range->bitrate[i] =
3268 ((supp_rates[i] & 0x7F) / 2) *
3269 1000000;
3270 }
3271 range->num_bitrates = b_len;
3272 } else {
3273 return -EIO;
3274 }
3275 }
3276 }
3277
3278 range->max_rts = WNI_CFG_RTS_THRESHOLD_STAMAX;
3279 range->min_frag = WNI_CFG_FRAGMENTATION_THRESHOLD_STAMIN;
3280 range->max_frag = WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX;
3281
3282 range->encoding_size[0] = 5;
3283 range->encoding_size[1] = 13;
3284 range->num_encoding_sizes = 2;
3285 range->max_encoding_tokens = MAX_WEP_KEYS;
3286
3287 /* we support through Wireless Extensions 22 */
3288 range->we_version_compiled = WIRELESS_EXT;
3289 range->we_version_source = 22;
3290
3291 /*Supported Channels and Frequencies */
3292 if (sme_cfg_get_str
3293 ((hHal), WNI_CFG_VALID_CHANNEL_LIST, channels,
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303294 &num_channels) != QDF_STATUS_SUCCESS) {
Jeff Johnson99bac312016-06-28 10:38:18 -07003295 hdd_warn("failed to get ini parameter, WNI_CFG_VALID_CHANNEL_LIST");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003296 return -EIO;
3297 }
3298 if (num_channels > IW_MAX_FREQUENCIES) {
3299 num_channels = IW_MAX_FREQUENCIES;
3300 }
3301
3302 range->num_channels = num_channels;
3303 range->num_frequency = num_channels;
3304
3305 for (index = 0; index < num_channels; index++) {
3306 uint32_t frq_indx = 0;
3307
3308 range->freq[index].i = channels[index];
3309 while (frq_indx < FREQ_CHAN_MAP_TABLE_SIZE) {
3310 if (channels[index] == freq_chan_map[frq_indx].chan) {
3311 range->freq[index].m =
3312 freq_chan_map[frq_indx].freq * 100000;
3313 range->freq[index].e = 1;
3314 break;
3315 }
3316 frq_indx++;
3317 }
3318 }
3319
3320 /* Event capability (kernel + driver) */
3321 range->event_capa[0] = (IW_EVENT_CAPA_K_0 |
3322 IW_EVENT_CAPA_MASK(SIOCGIWAP) |
3323 IW_EVENT_CAPA_MASK(SIOCGIWSCAN));
3324 range->event_capa[1] = IW_EVENT_CAPA_K_1;
3325
3326 /*Encryption capability */
3327 range->enc_capa = IW_ENC_CAPA_WPA | IW_ENC_CAPA_WPA2 |
3328 IW_ENC_CAPA_CIPHER_TKIP | IW_ENC_CAPA_CIPHER_CCMP;
3329
3330 /* Txpower capability */
3331 range->txpower_capa = IW_TXPOW_MWATT;
3332
3333 /*Scanning capability */
3334#if WIRELESS_EXT >= 22
3335 range->scan_capa =
3336 IW_SCAN_CAPA_ESSID | IW_SCAN_CAPA_TYPE | IW_SCAN_CAPA_CHANNEL;
3337#endif
3338
3339 EXIT();
3340 return 0;
3341}
3342
3343/**
3344 * iw_get_range() - SSR wrapper for __iw_get_range()
3345 * @dev: pointer to net_device
3346 * @info: pointer to iw_request_info
3347 * @wrqu: pointer to iwreq_data
3348 * @extra: pointer to extra ioctl payload
3349 *
3350 * Return: 0 on success, error number otherwise
3351 */
3352static int iw_get_range(struct net_device *dev, struct iw_request_info *info,
3353 union iwreq_data *wrqu, char *extra)
3354{
3355 int ret;
3356
3357 cds_ssr_protect(__func__);
3358 ret = __iw_get_range(dev, info, wrqu, extra);
3359 cds_ssr_unprotect(__func__);
3360
3361 return ret;
3362}
3363
3364/**
3365 * hdd_get_class_a_statistics_cb() - Get Class A stats callback function
3366 * @pStats: pointer to Class A stats
3367 * @pContext: user context originally registered with SME
3368 *
3369 * Return: None
3370 */
3371static void hdd_get_class_a_statistics_cb(void *pStats, void *pContext)
3372{
3373 struct statsContext *pStatsContext;
3374 tCsrGlobalClassAStatsInfo *pClassAStats;
3375 hdd_adapter_t *pAdapter;
3376
3377 if (ioctl_debug) {
3378 pr_info("%s: pStats [%p] pContext [%p]\n",
3379 __func__, pStats, pContext);
3380 }
3381
3382 if ((NULL == pStats) || (NULL == pContext)) {
Jeff Johnson99bac312016-06-28 10:38:18 -07003383 hdd_err("Bad param, pStats [%p] pContext [%p]",
3384 pStats, pContext);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003385 return;
3386 }
3387
3388 pClassAStats = pStats;
3389 pStatsContext = pContext;
3390 pAdapter = pStatsContext->pAdapter;
3391
3392 /* there is a race condition that exists between this callback
3393 * function and the caller since the caller could time out
3394 * either before or while this code is executing. we use a
3395 * spinlock to serialize these actions
3396 */
3397 spin_lock(&hdd_context_lock);
3398
3399 if ((NULL == pAdapter) ||
3400 (STATS_CONTEXT_MAGIC != pStatsContext->magic)) {
3401 /* the caller presumably timed out so there is nothing
3402 * we can do
3403 */
3404 spin_unlock(&hdd_context_lock);
Jeff Johnson99bac312016-06-28 10:38:18 -07003405 hdd_warn("Invalid context, pAdapter [%p] magic [%08x]",
3406 pAdapter, pStatsContext->magic);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003407 if (ioctl_debug) {
3408 pr_info("%s: Invalid context, pAdapter [%p] magic [%08x]\n",
3409 __func__, pAdapter, pStatsContext->magic);
3410 }
3411 return;
3412 }
3413
3414 /* context is valid so caller is still waiting */
3415
3416 /* paranoia: invalidate the magic */
3417 pStatsContext->magic = 0;
3418
3419 /* copy over the stats. do so as a struct copy */
3420 pAdapter->hdd_stats.ClassA_stat = *pClassAStats;
3421
3422 /* notify the caller */
3423 complete(&pStatsContext->completion);
3424
3425 /* serialization is complete */
3426 spin_unlock(&hdd_context_lock);
3427}
3428
3429/**
3430 * wlan_hdd_get_class_astats() - Get Class A statistics
3431 * @pAdapter: adapter for which statistics are desired
3432 *
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303433 * Return: QDF_STATUS_SUCCESS if adapter's Class A statistics were updated
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003434 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303435QDF_STATUS wlan_hdd_get_class_astats(hdd_adapter_t *pAdapter)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003436{
3437 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303438 QDF_STATUS hstatus;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003439 unsigned long rc;
3440 struct statsContext context;
3441
3442 if (NULL == pAdapter) {
Jeff Johnson99bac312016-06-28 10:38:18 -07003443 hdd_err("pAdapter is NULL");
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303444 return QDF_STATUS_E_FAULT;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003445 }
Prashanth Bhatta9e143052015-12-04 11:56:47 -08003446 if (cds_is_driver_recovering()) {
3447 hdd_err("Recovery in Progress. State: 0x%x Ignore!!!",
3448 cds_get_driver_state());
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303449 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003450 }
3451
3452 /* we are connected so prepare our callback context */
3453 init_completion(&context.completion);
3454 context.pAdapter = pAdapter;
3455 context.magic = STATS_CONTEXT_MAGIC;
3456 /* query only for Class A statistics (which include link speed) */
3457 hstatus = sme_get_statistics(WLAN_HDD_GET_HAL_CTX(pAdapter),
3458 eCSR_HDD, SME_GLOBAL_CLASSA_STATS,
3459 hdd_get_class_a_statistics_cb,
3460 0, /* not periodic */
3461 false, /* non-cached results */
3462 pHddStaCtx->conn_info.staId[0],
3463 &context, pAdapter->sessionId);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303464 if (QDF_STATUS_SUCCESS != hstatus) {
Jeff Johnson99bac312016-06-28 10:38:18 -07003465 hdd_err("Unable to retrieve Class A statistics");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003466 /* we'll returned a cached value below */
3467 } else {
3468 /* request was sent -- wait for the response */
3469 rc = wait_for_completion_timeout
3470 (&context.completion,
3471 msecs_to_jiffies(WLAN_WAIT_TIME_STATS));
3472 if (!rc) {
Jeff Johnson99bac312016-06-28 10:38:18 -07003473 hdd_err("SME timed out while retrieving Class A statistics");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003474 }
3475 }
3476
3477 /* either we never sent a request, we sent a request and
3478 * received a response or we sent a request and timed out. if
3479 * we never sent a request or if we sent a request and got a
3480 * response, we want to clear the magic out of paranoia. if
3481 * we timed out there is a race condition such that the
3482 * callback function could be executing at the same time we
3483 * are. of primary concern is if the callback function had
3484 * already verified the "magic" but had not yet set the
3485 * completion variable when a timeout occurred. we serialize
3486 * these activities by invalidating the magic while holding a
3487 * shared spinlock which will cause us to block if the
3488 * callback is currently executing
3489 */
3490 spin_lock(&hdd_context_lock);
3491 context.magic = 0;
3492 spin_unlock(&hdd_context_lock);
3493
3494 /* either callback updated pAdapter stats or it has cached data */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303495 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003496}
3497
3498/**
3499 * hdd_get_station_statistics_cb() - Get stats callback function
3500 * @pStats: pointer to Class A stats
3501 * @pContext: user context originally registered with SME
3502 *
3503 * Return: None
3504 */
3505static void hdd_get_station_statistics_cb(void *pStats, void *pContext)
3506{
3507 struct statsContext *pStatsContext;
3508 tCsrSummaryStatsInfo *pSummaryStats;
3509 tCsrGlobalClassAStatsInfo *pClassAStats;
3510 hdd_adapter_t *pAdapter;
3511
3512 if (ioctl_debug) {
3513 pr_info("%s: pStats [%p] pContext [%p]\n",
3514 __func__, pStats, pContext);
3515 }
3516
3517 if ((NULL == pStats) || (NULL == pContext)) {
Jeff Johnson99bac312016-06-28 10:38:18 -07003518 hdd_err("Bad param, pStats [%p] pContext [%p]",
3519 pStats, pContext);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003520 return;
3521 }
3522
3523 /* there is a race condition that exists between this callback
3524 * function and the caller since the caller could time out
3525 * either before or while this code is executing. we use a
3526 * spinlock to serialize these actions
3527 */
3528 spin_lock(&hdd_context_lock);
3529
3530 pSummaryStats = (tCsrSummaryStatsInfo *) pStats;
3531 pClassAStats = (tCsrGlobalClassAStatsInfo *) (pSummaryStats + 1);
3532 pStatsContext = pContext;
3533 pAdapter = pStatsContext->pAdapter;
3534 if ((NULL == pAdapter) ||
3535 (STATS_CONTEXT_MAGIC != pStatsContext->magic)) {
3536 /* the caller presumably timed out so there is nothing
3537 * we can do
3538 */
3539 spin_unlock(&hdd_context_lock);
Jeff Johnson99bac312016-06-28 10:38:18 -07003540 hdd_warn("Invalid context, pAdapter [%p] magic [%08x]",
3541 pAdapter, pStatsContext->magic);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003542 if (ioctl_debug) {
3543 pr_info("%s: Invalid context, pAdapter [%p] magic [%08x]\n",
3544 __func__, pAdapter, pStatsContext->magic);
3545 }
3546 return;
3547 }
3548
3549 /* context is valid so caller is still waiting */
3550
3551 /* paranoia: invalidate the magic */
3552 pStatsContext->magic = 0;
3553
3554 /* copy over the stats. do so as a struct copy */
3555 pAdapter->hdd_stats.summary_stat = *pSummaryStats;
3556 pAdapter->hdd_stats.ClassA_stat = *pClassAStats;
3557
3558 /* notify the caller */
3559 complete(&pStatsContext->completion);
3560
3561 /* serialization is complete */
3562 spin_unlock(&hdd_context_lock);
3563}
3564
3565/**
3566 * wlan_hdd_get_station_stats() - Get station statistics
3567 * @pAdapter: adapter for which statistics are desired
3568 *
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303569 * Return: QDF_STATUS_SUCCESS if adapter's statistics were updated
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003570 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303571QDF_STATUS wlan_hdd_get_station_stats(hdd_adapter_t *pAdapter)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003572{
3573 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303574 QDF_STATUS hstatus;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003575 unsigned long rc;
3576 struct statsContext context;
3577
3578 if (NULL == pAdapter) {
Jeff Johnson99bac312016-06-28 10:38:18 -07003579 hdd_err("pAdapter is NULL");
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303580 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003581 }
3582
3583 /* we are connected so prepare our callback context */
3584 init_completion(&context.completion);
3585 context.pAdapter = pAdapter;
3586 context.magic = STATS_CONTEXT_MAGIC;
3587
3588 /* query only for Summary & Class A statistics */
3589 hstatus = sme_get_statistics(WLAN_HDD_GET_HAL_CTX(pAdapter),
3590 eCSR_HDD,
3591 SME_SUMMARY_STATS |
3592 SME_GLOBAL_CLASSA_STATS,
3593 hdd_get_station_statistics_cb,
3594 0, /* not periodic */
3595 false, /* non-cached results */
3596 pHddStaCtx->conn_info.staId[0],
3597 &context, pAdapter->sessionId);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303598 if (QDF_STATUS_SUCCESS != hstatus) {
Jeff Johnson99bac312016-06-28 10:38:18 -07003599 hdd_err("Unable to retrieve statistics");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003600 /* we'll return with cached values */
3601 } else {
3602 /* request was sent -- wait for the response */
3603 rc = wait_for_completion_timeout
3604 (&context.completion,
3605 msecs_to_jiffies(WLAN_WAIT_TIME_STATS));
3606
3607 if (!rc) {
Jeff Johnson99bac312016-06-28 10:38:18 -07003608 hdd_err("SME timed out while retrieving statistics");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003609 }
3610 }
3611
3612 /* either we never sent a request, we sent a request and
3613 * received a response or we sent a request and timed out. if
3614 * we never sent a request or if we sent a request and got a
3615 * response, we want to clear the magic out of paranoia. if
3616 * we timed out there is a race condition such that the
3617 * callback function could be executing at the same time we
3618 * are. of primary concern is if the callback function had
3619 * already verified the "magic" but had not yet set the
3620 * completion variable when a timeout occurred. we serialize
3621 * these activities by invalidating the magic while holding a
3622 * shared spinlock which will cause us to block if the
3623 * callback is currently executing
3624 */
3625 spin_lock(&hdd_context_lock);
3626 context.magic = 0;
3627 spin_unlock(&hdd_context_lock);
3628
3629 /* either callback updated pAdapter stats or it has cached data */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303630 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003631}
3632
3633/**
3634 * iw_get_linkspeed() - Get current link speed ioctl
3635 * @dev: device upon which the ioctl was received
3636 * @info: ioctl request information
3637 * @wrqu: ioctl request data
3638 * @extra: extra ioctl buffer
3639 *
3640 * Return: 0 on success, non-zero on error
3641 */
3642static int __iw_get_linkspeed(struct net_device *dev,
3643 struct iw_request_info *info,
3644 union iwreq_data *wrqu, char *extra)
3645{
3646 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3647 char *pLinkSpeed = (char *)extra;
3648 int len = sizeof(uint32_t) + 1;
3649 uint32_t link_speed = 0;
3650 hdd_context_t *hdd_ctx;
3651 int rc, valid;
3652
Jeff Johnson6ee91ee2016-02-11 18:55:30 -08003653 ENTER_DEV(dev);
Hanumantha Reddy Pothula2db50ed2015-11-23 10:48:33 +05303654
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003655 hdd_ctx = WLAN_HDD_GET_CTX(pAdapter);
3656 valid = wlan_hdd_validate_context(hdd_ctx);
3657 if (0 != valid)
3658 return valid;
3659
3660 rc = wlan_hdd_get_link_speed(pAdapter, &link_speed);
3661 if (0 != rc) {
3662 return rc;
3663 }
3664
3665 wrqu->data.length = len;
3666 /* return the linkspeed as a string */
3667 rc = snprintf(pLinkSpeed, len, "%u", link_speed);
3668 if ((rc < 0) || (rc >= len)) {
3669 /* encoding or length error? */
Jeff Johnson99bac312016-06-28 10:38:18 -07003670 hdd_err("Unable to encode link speed");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003671 return -EIO;
3672 }
3673
Hanumantha Reddy Pothula2db50ed2015-11-23 10:48:33 +05303674 EXIT();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003675 /* a value is being successfully returned */
3676 return 0;
3677}
3678
3679static int iw_get_linkspeed(struct net_device *dev,
3680 struct iw_request_info *info,
3681 union iwreq_data *wrqu, char *extra)
3682{
3683 int ret;
3684
3685 cds_ssr_protect(__func__);
3686 ret = __iw_get_linkspeed(dev, info, wrqu, extra);
3687 cds_ssr_unprotect(__func__);
3688
3689 return ret;
3690}
3691
3692/**
3693 * wlan_hdd_change_country_code_callback() - Change country code callback
3694 * @context: opaque context originally passed to SME. All functions
3695 * which use this callback pass the adapter upon which the country
3696 * code change is active
3697 *
3698 * This function is registered as the callback function when
3699 * sme_change_country_code() is invoked. Callers of
3700 * sme_change_country_code() subsequently wait for the adapter's
3701 * @change_country_code completion variable, so all this function
3702 * needs to do is set that completion variable so that execution can
3703 * continue.
3704 *
3705 * Return: none
3706 */
3707void wlan_hdd_change_country_code_callback(void *context)
3708{
3709
3710 hdd_adapter_t *adapter = context;
3711
3712 if (adapter && (WLAN_HDD_ADAPTER_MAGIC == adapter->magic))
3713 complete(&adapter->change_country_code);
3714
3715 return;
3716}
3717
3718/**
3719 * __iw_set_nick() - SIOCSIWNICKN ioctl handler
3720 * @dev: device upon which the ioctl was received
3721 * @info: ioctl request information
3722 * @wrqu: ioctl request data
3723 * @extra: ioctl extra data
3724 *
3725 * Return: 0 on success, non-zero on error
3726 */
3727static int __iw_set_nick(struct net_device *dev,
3728 struct iw_request_info *info,
3729 union iwreq_data *wrqu, char *extra)
3730{
3731 hdd_adapter_t *adapter;
3732 hdd_context_t *hdd_ctx;
3733 int ret;
3734
Jeff Johnsonb25dcb12016-02-11 17:46:42 -08003735 ENTER_DEV(dev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003736
3737 adapter = WLAN_HDD_GET_PRIV_PTR(dev);
3738 hdd_ctx = WLAN_HDD_GET_CTX(adapter);
3739 ret = wlan_hdd_validate_context(hdd_ctx);
3740 if (0 != ret)
3741 return ret;
3742
3743 return 0;
3744}
3745
3746/**
3747 * iw_set_nick() - SSR wrapper for __iw_set_nick
3748 * @dev: pointer to net_device
3749 * @info: pointer to iw_request_info
3750 * @wrqu: pointer to iwreq_data
3751 * @extra: extra
3752 *
3753 * Return: 0 on success, error number otherwise
3754 */
3755static int iw_set_nick(struct net_device *dev,
3756 struct iw_request_info *info,
3757 union iwreq_data *wrqu, char *extra)
3758{
3759 int ret;
3760
3761 cds_ssr_protect(__func__);
3762 ret = __iw_set_nick(dev, info, wrqu, extra);
3763 cds_ssr_unprotect(__func__);
3764
3765 return ret;
3766}
3767
3768/**
3769 * __iw_get_nick() - SIOCGIWNICKN ioctl handler
3770 * @dev: device upon which the ioctl was received
3771 * @info: ioctl request information
3772 * @wrqu: ioctl request data
3773 * @extra: ioctl extra data
3774 *
3775 * Return: 0 on success, non-zero on error
3776 */
3777static int __iw_get_nick(struct net_device *dev,
3778 struct iw_request_info *info,
3779 union iwreq_data *wrqu, char *extra)
3780{
3781 hdd_adapter_t *adapter;
3782 hdd_context_t *hdd_ctx;
3783 int ret;
3784
Jeff Johnsonb25dcb12016-02-11 17:46:42 -08003785 ENTER_DEV(dev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003786
3787 adapter = WLAN_HDD_GET_PRIV_PTR(dev);
3788 hdd_ctx = WLAN_HDD_GET_CTX(adapter);
3789 ret = wlan_hdd_validate_context(hdd_ctx);
3790 if (0 != ret)
3791 return ret;
3792
3793 return 0;
3794}
3795
3796/**
3797 * iw_get_nick() - SSR wrapper for __iw_get_nick
3798 * @dev: pointer to net_device
3799 * @info: pointer to iw_request_info
3800 * @wrqu: pointer to iwreq_data
3801 * @extra: extra
3802 *
3803 * Return: 0 on success, error number otherwise
3804 */
3805static int iw_get_nick(struct net_device *dev,
3806 struct iw_request_info *info,
3807 union iwreq_data *wrqu, char *extra)
3808{
3809 int ret;
3810
3811 cds_ssr_protect(__func__);
3812 ret = __iw_get_nick(dev, info, wrqu, extra);
3813 cds_ssr_unprotect(__func__);
3814
3815 return ret;
3816}
3817
3818/**
3819 * __iw_set_encode() - SIOCSIWENCODE ioctl handler
3820 * @dev: device upon which the ioctl was received
3821 * @info: ioctl request information
3822 * @wrqu: ioctl request data
3823 * @extra: ioctl extra data
3824 *
3825 * Return: 0 on success, non-zero on error
3826 */
3827static int __iw_set_encode(struct net_device *dev, struct iw_request_info *info,
3828 union iwreq_data *wrqu, char *extra)
3829{
3830 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3831 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
3832 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
3833 hdd_context_t *hdd_ctx;
3834 struct iw_point *encoderq = &(wrqu->encoding);
3835 uint32_t keyId;
3836 uint8_t key_length;
3837 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
3838 bool fKeyPresent = 0;
3839 int i;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303840 QDF_STATUS status = QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003841 int ret;
3842
Jeff Johnsonb25dcb12016-02-11 17:46:42 -08003843 ENTER_DEV(dev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003844
3845 hdd_ctx = WLAN_HDD_GET_CTX(pAdapter);
3846 ret = wlan_hdd_validate_context(hdd_ctx);
3847 if (0 != ret)
3848 return ret;
3849
3850 keyId = encoderq->flags & IW_ENCODE_INDEX;
3851
3852 if (keyId) {
3853 if (keyId > MAX_WEP_KEYS) {
3854 return -EINVAL;
3855 }
3856
3857 fKeyPresent = 1;
3858 keyId--;
3859 } else {
3860 fKeyPresent = 0;
3861 }
3862
3863 if (wrqu->data.flags & IW_ENCODE_DISABLED) {
Jeff Johnson99bac312016-06-28 10:38:18 -07003864 hdd_notice("****iwconfig wlan0 key off*****");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003865 if (!fKeyPresent) {
3866
3867 for (i = 0; i < CSR_MAX_NUM_KEY; i++) {
3868
3869 if (pWextState->roamProfile.Keys.KeyMaterial[i])
3870 pWextState->roamProfile.Keys.
3871 KeyLength[i] = 0;
3872 }
3873 }
3874 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_OPEN_SYSTEM;
3875 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
3876 pWextState->roamProfile.EncryptionType.encryptionType[0] =
3877 eCSR_ENCRYPT_TYPE_NONE;
3878 pWextState->roamProfile.mcEncryptionType.encryptionType[0] =
3879 eCSR_ENCRYPT_TYPE_NONE;
3880
3881 pHddStaCtx->conn_info.ucEncryptionType = eCSR_ENCRYPT_TYPE_NONE;
3882 pHddStaCtx->conn_info.mcEncryptionType = eCSR_ENCRYPT_TYPE_NONE;
3883
3884 if (eConnectionState_Associated ==
3885 pHddStaCtx->conn_info.connState) {
3886 INIT_COMPLETION(pAdapter->disconnect_comp_var);
3887 status =
3888 sme_roam_disconnect(WLAN_HDD_GET_HAL_CTX(pAdapter),
3889 pAdapter->sessionId,
3890 eCSR_DISCONNECT_REASON_UNSPECIFIED);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303891 if (QDF_STATUS_SUCCESS == status) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003892 unsigned long rc;
3893 rc = wait_for_completion_timeout(&pAdapter->
3894 disconnect_comp_var,
3895 msecs_to_jiffies
3896 (WLAN_WAIT_TIME_DISCONNECT));
3897 if (!rc)
Jeff Johnson99bac312016-06-28 10:38:18 -07003898 hdd_err("failed wait on disconnect_comp_var");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003899 }
3900 }
3901
3902 return status;
3903
3904 }
3905
3906 if (wrqu->data.flags & (IW_ENCODE_OPEN | IW_ENCODE_RESTRICTED)) {
Jeff Johnson99bac312016-06-28 10:38:18 -07003907 hdd_notice("iwconfig wlan0 key on");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003908
3909 pHddStaCtx->conn_info.authType =
3910 (encoderq->
3911 flags & IW_ENCODE_RESTRICTED) ? eCSR_AUTH_TYPE_SHARED_KEY :
3912 eCSR_AUTH_TYPE_OPEN_SYSTEM;
3913
3914 }
3915
3916 if (wrqu->data.length > 0) {
Jeff Johnson99bac312016-06-28 10:38:18 -07003917 hdd_notice("wrqu->data.length : %d", wrqu->data.length);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003918
3919 key_length = wrqu->data.length;
3920
3921 /* IW_ENCODING_TOKEN_MAX is the value that is set for wrqu->data.length by iwconfig.c when 'iwconfig wlan0 key on' is issued. */
3922
3923 if (5 == key_length) {
Jeff Johnson99bac312016-06-28 10:38:18 -07003924 hdd_notice("Call with WEP40,key_len=%d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003925 key_length);
3926
3927 if ((IW_AUTH_KEY_MGMT_802_1X == pWextState->authKeyMgmt)
3928 && (eCSR_AUTH_TYPE_OPEN_SYSTEM ==
3929 pHddStaCtx->conn_info.authType)) {
3930 encryptionType = eCSR_ENCRYPT_TYPE_WEP40;
3931 } else {
3932 encryptionType =
3933 eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
3934 }
3935 } else if (13 == key_length) {
Jeff Johnson99bac312016-06-28 10:38:18 -07003936 hdd_notice("Call with WEP104,key_len:%d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003937 key_length);
3938
3939 if ((IW_AUTH_KEY_MGMT_802_1X == pWextState->authKeyMgmt)
3940 && (eCSR_AUTH_TYPE_OPEN_SYSTEM ==
3941 pHddStaCtx->conn_info.authType)) {
3942 encryptionType = eCSR_ENCRYPT_TYPE_WEP104;
3943 } else {
3944 encryptionType =
3945 eCSR_ENCRYPT_TYPE_WEP104_STATICKEY;
3946 }
3947 } else {
Jeff Johnson99bac312016-06-28 10:38:18 -07003948 hdd_warn("Invalid WEP key length :%d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003949 key_length);
3950 return -EINVAL;
3951 }
3952
3953 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
3954 pHddStaCtx->conn_info.mcEncryptionType = encryptionType;
3955 pWextState->roamProfile.EncryptionType.numEntries = 1;
3956 pWextState->roamProfile.EncryptionType.encryptionType[0] =
3957 encryptionType;
3958 pWextState->roamProfile.mcEncryptionType.numEntries = 1;
3959 pWextState->roamProfile.mcEncryptionType.encryptionType[0] =
3960 encryptionType;
3961
3962 if ((eConnectionState_NotConnected ==
3963 pHddStaCtx->conn_info.connState)
3964 &&
3965 ((eCSR_AUTH_TYPE_OPEN_SYSTEM ==
3966 pHddStaCtx->conn_info.authType)
3967 || (eCSR_AUTH_TYPE_SHARED_KEY ==
3968 pHddStaCtx->conn_info.authType))) {
3969
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303970 qdf_mem_copy(&pWextState->roamProfile.Keys.
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003971 KeyMaterial[keyId][0], extra, key_length);
3972
3973 pWextState->roamProfile.Keys.KeyLength[keyId] =
3974 (uint8_t) key_length;
3975 pWextState->roamProfile.Keys.defaultIndex =
3976 (uint8_t) keyId;
3977
3978 return status;
3979 }
3980 }
3981
3982 return 0;
3983}
3984
3985/**
3986 * iw_set_encode() - SSR wrapper for __iw_set_encode()
3987 * @dev: pointer to net_device
3988 * @info: pointer to iw_request_info
3989 * @wrqu: pointer to iwreq_data
3990 * @extra: pointer to extra ioctl payload
3991 *
3992 * Return: 0 on success, error number otherwise
3993 */
3994static int iw_set_encode(struct net_device *dev, struct iw_request_info *info,
3995 union iwreq_data *wrqu, char *extra)
3996{
3997 int ret;
3998
3999 cds_ssr_protect(__func__);
4000 ret = __iw_set_encode(dev, info, wrqu, extra);
4001 cds_ssr_unprotect(__func__);
4002
4003 return ret;
4004}
4005
4006/**
4007 * __iw_get_encodeext() - SIOCGIWENCODEEXT ioctl handler
4008 * @dev: device upon which the ioctl was received
4009 * @info: ioctl request information
4010 * @wrqu: ioctl request data
4011 * @extra: ioctl extra data
4012 *
4013 * Return: 0 on success, non-zero on error
4014 */
4015static int __iw_get_encodeext(struct net_device *dev,
4016 struct iw_request_info *info,
4017 struct iw_point *dwrq, char *extra)
4018{
4019 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4020 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
4021 tCsrRoamProfile *pRoamProfile = &(pWextState->roamProfile);
4022 int keyId;
4023 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
4024 eCsrAuthType authType = eCSR_AUTH_TYPE_NONE;
4025 int i, ret;
4026 hdd_context_t *hdd_ctx;
4027
Jeff Johnsonb25dcb12016-02-11 17:46:42 -08004028 ENTER_DEV(dev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004029
4030 hdd_ctx = WLAN_HDD_GET_CTX(pAdapter);
4031 ret = wlan_hdd_validate_context(hdd_ctx);
4032 if (0 != ret)
4033 return ret;
4034
4035 keyId = pRoamProfile->Keys.defaultIndex;
4036
4037 if (keyId < 0 || keyId >= MAX_WEP_KEYS) {
Jeff Johnson99bac312016-06-28 10:38:18 -07004038 hdd_notice("Invalid keyId : %d", keyId);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004039 return -EINVAL;
4040 }
4041
4042 if (pRoamProfile->Keys.KeyLength[keyId] > 0) {
4043 dwrq->flags |= IW_ENCODE_ENABLED;
4044 dwrq->length = pRoamProfile->Keys.KeyLength[keyId];
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304045 qdf_mem_copy(extra, &(pRoamProfile->Keys.KeyMaterial[keyId][0]),
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004046 pRoamProfile->Keys.KeyLength[keyId]);
4047 } else {
4048 dwrq->flags |= IW_ENCODE_DISABLED;
4049 }
4050
4051 for (i = 0; i < MAX_WEP_KEYS; i++) {
4052 if (pRoamProfile->Keys.KeyMaterial[i] == NULL) {
4053 continue;
4054 } else {
4055 break;
4056 }
4057 }
4058
4059 if (MAX_WEP_KEYS == i) {
4060 dwrq->flags |= IW_ENCODE_NOKEY;
4061 } else {
4062 dwrq->flags |= IW_ENCODE_ENABLED;
4063 }
4064
4065 encryptionType = pRoamProfile->EncryptionType.encryptionType[0];
4066
4067 if (eCSR_ENCRYPT_TYPE_NONE == encryptionType) {
4068 dwrq->flags |= IW_ENCODE_DISABLED;
4069 }
4070
4071 authType = (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.authType;
4072
4073 if (IW_AUTH_ALG_OPEN_SYSTEM == authType) {
4074 dwrq->flags |= IW_ENCODE_OPEN;
4075 } else {
4076 dwrq->flags |= IW_ENCODE_RESTRICTED;
4077 }
4078 EXIT();
4079 return 0;
4080
4081}
4082
4083/**
4084 * iw_get_encodeext() - SSR wrapper for __iw_get_encodeext()
4085 * @dev: pointer to net_device
4086 * @info: pointer to iw_request_info
4087 * @dwrq: pointer to encoding information
4088 * @extra: pointer to extra ioctl payload
4089 *
4090 * Return: 0 on success, error number otherwise
4091 */
4092static int iw_get_encodeext(struct net_device *dev,
4093 struct iw_request_info *info,
4094 struct iw_point *dwrq, char *extra)
4095{
4096 int ret;
4097
4098 cds_ssr_protect(__func__);
4099 ret = __iw_get_encodeext(dev, info, dwrq, extra);
4100 cds_ssr_unprotect(__func__);
4101
4102 return ret;
4103}
4104
4105/**
4106 * __iw_set_encodeext() - SIOCSIWENCODEEXT ioctl handler
4107 * @dev: device upon which the ioctl was received
4108 * @info: ioctl request information
4109 * @wrqu: ioctl request data
4110 * @extra: ioctl extra data
4111 *
4112 * Return: 0 on success, non-zero on error
4113 */
4114static int __iw_set_encodeext(struct net_device *dev,
4115 struct iw_request_info *info,
4116 union iwreq_data *wrqu, char *extra)
4117{
4118 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4119 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4120 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
4121 hdd_context_t *hdd_ctx;
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05304122 QDF_STATUS qdf_ret_status = QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004123 tCsrRoamProfile *pRoamProfile = &pWextState->roamProfile;
4124 int ret;
4125 struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
4126 int key_index;
4127 struct iw_point *encoding = &wrqu->encoding;
4128 tCsrRoamSetKey setKey;
4129 uint32_t roamId = 0xFF;
4130
Jeff Johnsonb25dcb12016-02-11 17:46:42 -08004131 ENTER_DEV(dev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004132
4133 hdd_ctx = WLAN_HDD_GET_CTX(pAdapter);
4134 ret = wlan_hdd_validate_context(hdd_ctx);
4135 if (0 != ret)
4136 return ret;
4137
4138 key_index = encoding->flags & IW_ENCODE_INDEX;
4139
4140 if (key_index > 0) {
4141
4142 /*Convert from 1-based to 0-based keying */
4143 key_index--;
4144 }
4145 if (!ext->key_len) {
4146
4147 /*Set the encrytion type to NONE */
4148 pRoamProfile->EncryptionType.encryptionType[0] =
4149 eCSR_ENCRYPT_TYPE_NONE;
4150 return ret;
4151 }
4152
4153 if (eConnectionState_NotConnected == pHddStaCtx->conn_info.connState &&
4154 (IW_ENCODE_ALG_WEP == ext->alg)) {
4155 if (IW_AUTH_KEY_MGMT_802_1X == pWextState->authKeyMgmt) {
4156
Jeff Johnson99bac312016-06-28 10:38:18 -07004157 hdd_err("Invalid Configuration");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004158 return -EINVAL;
4159 } else {
4160 /*Static wep, update the roam profile with the keys */
4161 if (ext->key
4162 && (ext->key_len <=
4163 eCSR_SECURITY_WEP_KEYSIZE_MAX_BYTES)
4164 && key_index < CSR_MAX_NUM_KEY) {
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304165 qdf_mem_copy(&pRoamProfile->Keys.
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004166 KeyMaterial[key_index][0],
4167 ext->key, ext->key_len);
4168 pRoamProfile->Keys.KeyLength[key_index] =
4169 (uint8_t) ext->key_len;
4170
4171 if (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY)
4172 pRoamProfile->Keys.defaultIndex =
4173 (uint8_t) key_index;
4174
4175 }
4176 }
4177 return ret;
4178 }
4179
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304180 qdf_mem_zero(&setKey, sizeof(tCsrRoamSetKey));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004181
4182 setKey.keyId = key_index;
4183 setKey.keyLength = ext->key_len;
4184
4185 if (ext->key_len <= CSR_MAX_KEY_LEN) {
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304186 qdf_mem_copy(&setKey.Key[0], ext->key, ext->key_len);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004187 }
4188
4189 if (ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY) {
4190 /*Key direction for group is RX only */
4191 setKey.keyDirection = eSIR_RX_ONLY;
Anurag Chouhanc5548422016-02-24 18:33:27 +05304192 qdf_set_macaddr_broadcast(&setKey.peerMac);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004193 } else {
4194
4195 setKey.keyDirection = eSIR_TX_RX;
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304196 qdf_mem_copy(setKey.peerMac.bytes, ext->addr.sa_data,
Anurag Chouhan6d760662016-02-20 16:05:43 +05304197 QDF_MAC_ADDR_SIZE);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004198 }
4199
4200 /*For supplicant pae role is zero */
4201 setKey.paeRole = 0;
4202
4203 switch (ext->alg) {
4204 case IW_ENCODE_ALG_NONE:
4205 setKey.encType = eCSR_ENCRYPT_TYPE_NONE;
4206 break;
4207
4208 case IW_ENCODE_ALG_WEP:
4209 setKey.encType =
4210 (ext->key_len ==
4211 5) ? eCSR_ENCRYPT_TYPE_WEP40 : eCSR_ENCRYPT_TYPE_WEP104;
4212 break;
4213
4214 case IW_ENCODE_ALG_TKIP:
4215 {
4216 uint8_t *pKey = &setKey.Key[0];
4217
4218 setKey.encType = eCSR_ENCRYPT_TYPE_TKIP;
4219
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304220 qdf_mem_zero(pKey, CSR_MAX_KEY_LEN);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004221
4222 /* Supplicant sends the 32bytes key in this order
4223 * |--------------|----------|----------|
4224 * | Tk1 | TX MIC | RX MIC |
4225 * |--------------|----------|----------|
4226 * <---16bytes---><--8bytes--><--8bytes-->
4227 *
4228 *
4229 * Sme expects the 32 bytes key to be in the below order
4230 * |--------------|----------|----------|
4231 * | Tk1 | RX MIC | TX MIC |
4232 * |--------------|----------|----------|
4233 * <---16bytes---><--8bytes--><--8bytes-->
4234 */
4235
4236 /* Copy the Temporal Key 1 (TK1) */
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304237 qdf_mem_copy(pKey, ext->key, 16);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004238
4239 /* Copy the rx mic first */
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304240 qdf_mem_copy(&pKey[16], &ext->key[24], 8);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004241
4242 /* Copy the tx mic */
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304243 qdf_mem_copy(&pKey[24], &ext->key[16], 8);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004244
4245 }
4246 break;
4247
4248 case IW_ENCODE_ALG_CCMP:
4249 setKey.encType = eCSR_ENCRYPT_TYPE_AES;
4250 break;
4251
4252#ifdef FEATURE_WLAN_ESE
4253#define IW_ENCODE_ALG_KRK 6
4254 case IW_ENCODE_ALG_KRK:
4255 setKey.encType = eCSR_ENCRYPT_TYPE_KRK;
4256 break;
4257#endif /* FEATURE_WLAN_ESE */
4258
4259 default:
4260 setKey.encType = eCSR_ENCRYPT_TYPE_NONE;
4261 break;
4262 }
4263
Jeff Johnson99bac312016-06-28 10:38:18 -07004264 hdd_notice("cipher_alg:%d key_len:%d EncryptionType:%d",
4265 (int)ext->alg, (int)ext->key_len, setKey.encType);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004266
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004267 /* The supplicant may attempt to set the PTK once
4268 * pre-authentication is done. Save the key in the UMAC and
4269 * include it in the ADD BSS request
4270 */
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05304271 qdf_ret_status = sme_ft_update_key(WLAN_HDD_GET_HAL_CTX(pAdapter),
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004272 pAdapter->sessionId, &setKey);
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05304273 if (qdf_ret_status == QDF_STATUS_FT_PREAUTH_KEY_SUCCESS) {
Jeff Johnson99bac312016-06-28 10:38:18 -07004274 hdd_info("Update PreAuth Key success");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004275 return 0;
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05304276 } else if (qdf_ret_status == QDF_STATUS_FT_PREAUTH_KEY_FAILED) {
Jeff Johnson99bac312016-06-28 10:38:18 -07004277 hdd_err("Update PreAuth Key failed");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004278 return -EINVAL;
4279 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004280
4281 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
4282
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05304283 qdf_ret_status = sme_roam_set_key(WLAN_HDD_GET_HAL_CTX(pAdapter),
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004284 pAdapter->sessionId,
4285 &setKey, &roamId);
4286
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05304287 if (qdf_ret_status != QDF_STATUS_SUCCESS) {
Jeff Johnson99bac312016-06-28 10:38:18 -07004288 hdd_err("[%4d] sme_roam_set_key returned ERROR status= %d",
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05304289 __LINE__, qdf_ret_status);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004290
4291 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
4292 }
4293
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05304294 return qdf_ret_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004295}
4296
4297/**
4298 * iw_set_encodeext() - SSR wrapper for __iw_set_encodeext()
4299 * @dev: pointer to net_device
4300 * @info: pointer to iw_request_info
4301 * @wrqu: pointer to iwreq_data
4302 * @extra: pointer to extra ioctl payload
4303 *
4304 * Return: 0 on success, error number otherwise
4305 */
4306static int iw_set_encodeext(struct net_device *dev,
4307 struct iw_request_info *info,
4308 union iwreq_data *wrqu, char *extra)
4309{
4310 int ret;
4311
4312 cds_ssr_protect(__func__);
4313 ret = __iw_set_encodeext(dev, info, wrqu, extra);
4314 cds_ssr_unprotect(__func__);
4315
4316 return ret;
4317}
4318
4319/**
4320 * __iw_set_retry() - SIOCSIWRETRY ioctl handler
4321 * @dev: device upon which the ioctl was received
4322 * @info: ioctl request information
4323 * @wrqu: ioctl request data
4324 * @extra: ioctl extra data
4325 *
4326 * Return: 0 on success, non-zero on error
4327 */
4328static int __iw_set_retry(struct net_device *dev, struct iw_request_info *info,
4329 union iwreq_data *wrqu, char *extra)
4330{
4331 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4332 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
4333 hdd_context_t *hdd_ctx;
4334 int ret;
4335
Jeff Johnsonb25dcb12016-02-11 17:46:42 -08004336 ENTER_DEV(dev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004337
4338 hdd_ctx = WLAN_HDD_GET_CTX(pAdapter);
4339 ret = wlan_hdd_validate_context(hdd_ctx);
4340 if (0 != ret)
4341 return ret;
4342
4343 if (wrqu->retry.value < WNI_CFG_LONG_RETRY_LIMIT_STAMIN ||
4344 wrqu->retry.value > WNI_CFG_LONG_RETRY_LIMIT_STAMAX) {
4345
Jeff Johnson99bac312016-06-28 10:38:18 -07004346 hdd_err("Invalid Retry-Limit=%d!!", wrqu->retry.value);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004347
4348 return -EINVAL;
4349 }
4350
4351 if (wrqu->retry.flags & IW_RETRY_LIMIT) {
4352
4353 if ((wrqu->retry.flags & IW_RETRY_LONG)) {
4354 if (sme_cfg_set_int (hHal, WNI_CFG_LONG_RETRY_LIMIT,
4355 wrqu->retry.value) !=
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304356 QDF_STATUS_SUCCESS) {
Jeff Johnson99bac312016-06-28 10:38:18 -07004357 hdd_err("failed to set ini parameter, WNI_CFG_LONG_RETRY_LIMIT");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004358 return -EIO;
4359 }
4360 } else if ((wrqu->retry.flags & IW_RETRY_SHORT)) {
4361 if (sme_cfg_set_int (hHal, WNI_CFG_SHORT_RETRY_LIMIT,
4362 wrqu->retry.value) !=
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304363 QDF_STATUS_SUCCESS) {
Jeff Johnson99bac312016-06-28 10:38:18 -07004364 hdd_err("failed to set ini parameter, WNI_CFG_LONG_RETRY_LIMIT");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004365 return -EIO;
4366 }
4367 }
4368 } else {
4369 return -EOPNOTSUPP;
4370 }
4371
Jeff Johnson99bac312016-06-28 10:38:18 -07004372 hdd_notice("Set Retry-Limit=%d!!", wrqu->retry.value);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004373
4374 EXIT();
4375
4376 return 0;
4377
4378}
4379
4380/**
4381 * iw_set_retry() - SSR wrapper for __iw_set_retry()
4382 * @dev: pointer to net_device
4383 * @info: pointer to iw_request_info
4384 * @wrqu: pointer to iwreq_data
4385 * @extra: pointer to extra ioctl payload
4386 *
4387 * Return: 0 on success, error number otherwise
4388 */
4389static int iw_set_retry(struct net_device *dev, struct iw_request_info *info,
4390 union iwreq_data *wrqu, char *extra)
4391{
4392 int ret;
4393
4394 cds_ssr_protect(__func__);
4395 ret = __iw_set_retry(dev, info, wrqu, extra);
4396 cds_ssr_unprotect(__func__);
4397
4398 return ret;
4399}
4400
4401/**
4402 * __iw_get_retry() - SIOCGIWRETRY ioctl handler
4403 * @dev: device upon which the ioctl was received
4404 * @info: ioctl request information
4405 * @wrqu: ioctl request data
4406 * @extra: ioctl extra data
4407 *
4408 * Return: 0 on success, non-zero on error
4409 */
4410static int __iw_get_retry(struct net_device *dev, struct iw_request_info *info,
4411 union iwreq_data *wrqu, char *extra)
4412{
4413 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4414 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
4415 uint32_t retry = 0;
4416 hdd_context_t *hdd_ctx;
4417 int ret;
4418
Jeff Johnsonb25dcb12016-02-11 17:46:42 -08004419 ENTER_DEV(dev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004420
4421 hdd_ctx = WLAN_HDD_GET_CTX(pAdapter);
4422 ret = wlan_hdd_validate_context(hdd_ctx);
4423 if (0 != ret)
4424 return ret;
4425
4426 if ((wrqu->retry.flags & IW_RETRY_LONG)) {
4427 wrqu->retry.flags = IW_RETRY_LIMIT | IW_RETRY_LONG;
4428
4429 if (sme_cfg_get_int(hHal, WNI_CFG_LONG_RETRY_LIMIT, &retry) !=
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304430 QDF_STATUS_SUCCESS) {
Jeff Johnson99bac312016-06-28 10:38:18 -07004431 hdd_warn("failed to get ini parameter, WNI_CFG_LONG_RETRY_LIMIT");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004432 return -EIO;
4433 }
4434
4435 wrqu->retry.value = retry;
4436 } else if ((wrqu->retry.flags & IW_RETRY_SHORT)) {
4437 wrqu->retry.flags = IW_RETRY_LIMIT | IW_RETRY_SHORT;
4438
4439 if (sme_cfg_get_int(hHal, WNI_CFG_SHORT_RETRY_LIMIT, &retry) !=
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304440 QDF_STATUS_SUCCESS) {
Jeff Johnson99bac312016-06-28 10:38:18 -07004441 hdd_warn("failed to get ini parameter, WNI_CFG_LONG_RETRY_LIMIT");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004442 return -EIO;
4443 }
4444
4445 wrqu->retry.value = retry;
4446 } else {
4447 return -EOPNOTSUPP;
4448 }
4449
Jeff Johnson99bac312016-06-28 10:38:18 -07004450 hdd_notice("Retry-Limit=%d!!", retry);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004451
4452 EXIT();
4453
4454 return 0;
4455}
4456
4457/**
4458 * iw_get_retry() - SSR wrapper for __iw_get_retry()
4459 * @dev: pointer to net_device
4460 * @info: pointer to iw_request_info
4461 * @wrqu: pointer to iwreq_data
4462 * @extra: pointer to extra ioctl payload
4463 *
4464 * Return: 0 on success, error number otherwise
4465 */
4466static int iw_get_retry(struct net_device *dev, struct iw_request_info *info,
4467 union iwreq_data *wrqu, char *extra)
4468{
4469 int ret;
4470
4471 cds_ssr_protect(__func__);
4472 ret = __iw_get_retry(dev, info, wrqu, extra);
4473 cds_ssr_unprotect(__func__);
4474
4475 return ret;
4476}
4477
4478/**
4479 * __iw_set_mlme() - SIOCSIWMLME ioctl handler
4480 * @dev: device upon which the ioctl was received
4481 * @info: ioctl request information
4482 * @wrqu: ioctl request data
4483 * @extra: ioctl extra data
4484 *
4485 * Return: 0 on success, non-zero on error
4486 */
4487static int __iw_set_mlme(struct net_device *dev,
4488 struct iw_request_info *info,
4489 union iwreq_data *wrqu, char *extra)
4490{
4491 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4492 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4493 struct iw_mlme *mlme = (struct iw_mlme *)extra;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304494 QDF_STATUS status = QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004495 hdd_context_t *hdd_ctx;
4496 int ret;
4497
Jeff Johnsonb25dcb12016-02-11 17:46:42 -08004498 ENTER_DEV(dev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004499
4500 hdd_ctx = WLAN_HDD_GET_CTX(pAdapter);
4501 ret = wlan_hdd_validate_context(hdd_ctx);
4502 if (0 != ret)
4503 return ret;
4504
4505 /* reason_code is unused. By default it is set to
4506 * eCSR_DISCONNECT_REASON_UNSPECIFIED
4507 */
4508 switch (mlme->cmd) {
4509 case IW_MLME_DISASSOC:
4510 case IW_MLME_DEAUTH:
4511
4512 if (pHddStaCtx->conn_info.connState ==
4513 eConnectionState_Associated) {
4514 eCsrRoamDisconnectReason reason =
4515 eCSR_DISCONNECT_REASON_UNSPECIFIED;
4516
4517 if (mlme->reason_code == HDD_REASON_MICHAEL_MIC_FAILURE)
4518 reason = eCSR_DISCONNECT_REASON_MIC_ERROR;
4519
4520 INIT_COMPLETION(pAdapter->disconnect_comp_var);
4521 status =
4522 sme_roam_disconnect(WLAN_HDD_GET_HAL_CTX(pAdapter),
4523 pAdapter->sessionId, reason);
4524
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304525 if (QDF_STATUS_SUCCESS == status) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004526 unsigned long rc;
4527 rc = wait_for_completion_timeout(&pAdapter->
4528 disconnect_comp_var,
4529 msecs_to_jiffies
4530 (WLAN_WAIT_TIME_DISCONNECT));
4531 if (!rc)
Jeff Johnson99bac312016-06-28 10:38:18 -07004532 hdd_err("failed wait on disconnect_comp_var");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004533 } else
Jeff Johnson99bac312016-06-28 10:38:18 -07004534 hdd_err("%d Command Disassociate/Deauthenticate : csr_roam_disconnect failure returned %d",
4535 (int)mlme->cmd, (int)status);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004536
4537 /* Resetting authKeyMgmt */
4538 (WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter))->authKeyMgmt =
4539 0;
4540
Jeff Johnson99bac312016-06-28 10:38:18 -07004541 hdd_notice("Disabling queues");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004542 wlan_hdd_netif_queue_control(pAdapter,
4543 WLAN_NETIF_TX_DISABLE_N_CARRIER,
4544 WLAN_CONTROL_PATH);
4545
4546 } else {
Jeff Johnson99bac312016-06-28 10:38:18 -07004547 hdd_err("%d Command Disassociate/Deauthenticate called but station is not in associated state",
4548 (int)mlme->cmd);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004549 }
4550 break;
4551 default:
Jeff Johnson99bac312016-06-28 10:38:18 -07004552 hdd_err("%d Command should be Disassociate/Deauthenticate",
4553 (int)mlme->cmd);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004554 return -EINVAL;
4555 } /* end of switch */
4556
4557 EXIT();
4558
4559 return status;
4560
4561}
4562
4563/**
4564 * iw_set_mlme() - SSR wrapper for __iw_set_mlme()
4565 * @dev: pointer to net_device
4566 * @info: pointer to iw_request_info
4567 * @wrqu: pointer to iwreq_data
4568 * @extra: pointer to extra ioctl payload
4569 *
4570 * Return: 0 on success, error number otherwise
4571 */
4572static int iw_set_mlme(struct net_device *dev, struct iw_request_info *info,
4573 union iwreq_data *wrqu, char *extra)
4574{
4575 int ret;
4576
4577 cds_ssr_protect(__func__);
4578 ret = __iw_set_mlme(dev, info, wrqu, extra);
4579 cds_ssr_unprotect(__func__);
4580
4581 return ret;
4582}
4583
4584/**
4585 * wlan_hdd_update_phymode() - handle change in PHY mode
4586 * @net: device upon which PHY mode change was received
4587 * @hal: umac handle for the driver
4588 * @new_phymode: new PHY mode for the device
4589 * @phddctx: pointer to the HDD context
4590 *
4591 * This function is called when the device is set to a new PHY mode.
4592 * It takes a holistic look at the desired PHY mode along with the
4593 * configured capabilities of the driver and the reported capabilities
4594 * of the hardware in order to correctly configure all PHY-related
4595 * parameters.
4596 *
4597 * Return: 0 on success, negative errno value on error
4598 */
4599int wlan_hdd_update_phymode(struct net_device *net, tHalHandle hal,
4600 int new_phymode, hdd_context_t *phddctx)
4601{
4602#ifdef QCA_HT_2040_COEX
4603 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(net);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304604 QDF_STATUS halStatus = QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004605#endif
4606 bool band_24 = false, band_5g = false;
4607 bool ch_bond24 = false, ch_bond5g = false;
4608 tSmeConfigParams smeconfig;
4609 uint32_t chwidth = WNI_CFG_CHANNEL_BONDING_MODE_DISABLE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004610 uint32_t vhtchanwidth;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004611 eCsrPhyMode phymode = -EIO, old_phymode;
4612 eHddDot11Mode hdd_dot11mode = phddctx->config->dot11Mode;
4613 eCsrBand curr_band = eCSR_BAND_ALL;
4614
4615 old_phymode = sme_get_phy_mode(hal);
4616
4617 if (WNI_CFG_CHANNEL_BONDING_MODE_DISABLE !=
4618 sme_get_cb_phy_state_from_cb_ini_value(phddctx->config->
4619 nChannelBondingMode24GHz))
4620 ch_bond24 = true;
4621
4622 if (WNI_CFG_CHANNEL_BONDING_MODE_DISABLE !=
4623 sme_get_cb_phy_state_from_cb_ini_value(phddctx->config->
4624 nChannelBondingMode5GHz))
4625 ch_bond5g = true;
4626
4627 if (phddctx->config->nBandCapability == eCSR_BAND_ALL) {
4628 band_24 = band_5g = true;
4629 } else if (phddctx->config->nBandCapability == eCSR_BAND_24) {
4630 band_24 = true;
4631 } else if (phddctx->config->nBandCapability == eCSR_BAND_5G) {
4632 band_5g = true;
4633 }
4634
4635 vhtchanwidth = phddctx->config->vhtChannelWidth;
Jeff Johnson99bac312016-06-28 10:38:18 -07004636 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 -08004637 ch_bond24, ch_bond5g, band_24, band_5g, vhtchanwidth);
4638
4639 switch (new_phymode) {
4640 case IEEE80211_MODE_AUTO:
4641 sme_set_phy_mode(hal, eCSR_DOT11_MODE_AUTO);
4642 if (hdd_set_band(net, WLAN_HDD_UI_BAND_AUTO) == 0) {
4643 phymode = eCSR_DOT11_MODE_AUTO;
4644 hdd_dot11mode = eHDD_DOT11_MODE_AUTO;
4645 chwidth = WNI_CFG_CHANNEL_BONDING_MODE_ENABLE;
4646 curr_band = eCSR_BAND_ALL;
4647 vhtchanwidth = eHT_CHANNEL_WIDTH_80MHZ;
4648 } else {
4649 sme_set_phy_mode(hal, old_phymode);
4650 return -EIO;
4651 }
4652 break;
4653 case IEEE80211_MODE_11A:
4654 sme_set_phy_mode(hal, eCSR_DOT11_MODE_11a);
4655 if ((hdd_set_band(net, WLAN_HDD_UI_BAND_5_GHZ) == 0)) {
4656 phymode = eCSR_DOT11_MODE_11a;
4657 hdd_dot11mode = eHDD_DOT11_MODE_11a;
4658 chwidth = WNI_CFG_CHANNEL_BONDING_MODE_DISABLE;
4659 curr_band = eCSR_BAND_5G;
4660 } else {
4661 sme_set_phy_mode(hal, old_phymode);
4662 return -EIO;
4663 }
4664 break;
4665 case IEEE80211_MODE_11B:
4666 sme_set_phy_mode(hal, eCSR_DOT11_MODE_11b);
4667 if ((hdd_set_band(net, WLAN_HDD_UI_BAND_2_4_GHZ) == 0)) {
4668 phymode = eCSR_DOT11_MODE_11b;
4669 hdd_dot11mode = eHDD_DOT11_MODE_11b;
4670 chwidth = WNI_CFG_CHANNEL_BONDING_MODE_DISABLE;
4671 curr_band = eCSR_BAND_24;
4672 } else {
4673 sme_set_phy_mode(hal, old_phymode);
4674 return -EIO;
4675 }
4676 break;
4677 case IEEE80211_MODE_11G:
4678 sme_set_phy_mode(hal, eCSR_DOT11_MODE_11g);
4679 if ((hdd_set_band(net, WLAN_HDD_UI_BAND_2_4_GHZ) == 0)) {
4680 phymode = eCSR_DOT11_MODE_11g;
4681 hdd_dot11mode = eHDD_DOT11_MODE_11g;
4682 chwidth = WNI_CFG_CHANNEL_BONDING_MODE_DISABLE;
4683 curr_band = eCSR_BAND_24;
4684 } else {
4685 sme_set_phy_mode(hal, old_phymode);
4686 return -EIO;
4687 }
4688 break;
4689 /* UMAC doesnt have option to set MODE_11NA/MODE_11NG as phymode
4690 * so setting phymode as eCSR_DOT11_MODE_11n and updating the band
4691 * and channel bonding in configuration to reflect MODE_11NA/MODE_11NG
4692 */
4693 case IEEE80211_MODE_11NA_HT20:
4694 sme_set_phy_mode(hal, eCSR_DOT11_MODE_11n);
4695 if ((hdd_set_band(net, WLAN_HDD_UI_BAND_5_GHZ) == 0)) {
4696 phymode = eCSR_DOT11_MODE_11n;
4697 hdd_dot11mode = eHDD_DOT11_MODE_11n;
4698 chwidth = WNI_CFG_CHANNEL_BONDING_MODE_DISABLE;
4699 curr_band = eCSR_BAND_5G;
4700 } else {
4701 sme_set_phy_mode(hal, old_phymode);
4702 return -EIO;
4703 }
4704 break;
4705 case IEEE80211_MODE_11NA_HT40:
4706 sme_set_phy_mode(hal, eCSR_DOT11_MODE_11n);
4707 if ((hdd_set_band(net, WLAN_HDD_UI_BAND_5_GHZ) == 0)) {
4708 phymode = eCSR_DOT11_MODE_11n;
4709 hdd_dot11mode = eHDD_DOT11_MODE_11n;
4710 chwidth = WNI_CFG_CHANNEL_BONDING_MODE_ENABLE;
4711 curr_band = eCSR_BAND_5G;
4712 } else {
4713 sme_set_phy_mode(hal, old_phymode);
4714 return -EIO;
4715 }
4716 break;
4717 case IEEE80211_MODE_11NG_HT20:
4718 sme_set_phy_mode(hal, eCSR_DOT11_MODE_11n);
4719 if ((hdd_set_band(net, WLAN_HDD_UI_BAND_2_4_GHZ) == 0)) {
4720 phymode = eCSR_DOT11_MODE_11n;
4721 hdd_dot11mode = eHDD_DOT11_MODE_11n;
4722 chwidth = WNI_CFG_CHANNEL_BONDING_MODE_DISABLE;
4723 curr_band = eCSR_BAND_24;
4724 } else {
4725 sme_set_phy_mode(hal, old_phymode);
4726 return -EIO;
4727 }
4728 break;
4729 case IEEE80211_MODE_11NG_HT40:
4730 sme_set_phy_mode(hal, eCSR_DOT11_MODE_11n);
4731 if ((hdd_set_band(net, WLAN_HDD_UI_BAND_2_4_GHZ) == 0)) {
4732 phymode = eCSR_DOT11_MODE_11n;
4733 hdd_dot11mode = eHDD_DOT11_MODE_11n;
4734 chwidth = WNI_CFG_CHANNEL_BONDING_MODE_ENABLE;
4735 curr_band = eCSR_BAND_24;
4736 } else {
4737 sme_set_phy_mode(hal, old_phymode);
4738 return -EIO;
4739 }
4740 break;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004741 case IEEE80211_MODE_11AC_VHT20:
4742 case IEEE80211_MODE_11AC_VHT40:
4743 case IEEE80211_MODE_11AC_VHT80:
4744 sme_set_phy_mode(hal, eCSR_DOT11_MODE_11ac);
4745 if ((hdd_set_band(net, WLAN_HDD_UI_BAND_5_GHZ) == 0)) {
4746 phymode = eCSR_DOT11_MODE_11ac;
4747 hdd_dot11mode = eHDD_DOT11_MODE_11ac;
4748 chwidth = WNI_CFG_CHANNEL_BONDING_MODE_ENABLE;
4749 curr_band = eCSR_BAND_5G;
4750 } else {
4751 sme_set_phy_mode(hal, old_phymode);
4752 return -EIO;
4753 }
4754 break;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004755 case IEEE80211_MODE_2G_AUTO:
4756 sme_set_phy_mode(hal, eCSR_DOT11_MODE_AUTO);
4757 if ((hdd_set_band(net, WLAN_HDD_UI_BAND_2_4_GHZ) == 0)) {
4758 phymode = eCSR_DOT11_MODE_AUTO;
4759 hdd_dot11mode = eHDD_DOT11_MODE_AUTO;
4760 chwidth = WNI_CFG_CHANNEL_BONDING_MODE_ENABLE;
4761 curr_band = eCSR_BAND_24;
4762 } else {
4763 sme_set_phy_mode(hal, old_phymode);
4764 return -EIO;
4765 }
4766 break;
4767 case IEEE80211_MODE_5G_AUTO:
4768 sme_set_phy_mode(hal, eCSR_DOT11_MODE_AUTO);
4769 if ((hdd_set_band(net, WLAN_HDD_UI_BAND_5_GHZ) == 0)) {
4770 phymode = eCSR_DOT11_MODE_AUTO;
4771 hdd_dot11mode = eHDD_DOT11_MODE_AUTO;
4772 chwidth = WNI_CFG_CHANNEL_BONDING_MODE_ENABLE;
4773 vhtchanwidth = eHT_CHANNEL_WIDTH_80MHZ;
4774 curr_band = eCSR_BAND_5G;
4775 } else {
4776 sme_set_phy_mode(hal, old_phymode);
4777 return -EIO;
4778 }
4779 break;
4780 case IEEE80211_MODE_11AGN:
4781 sme_set_phy_mode(hal, eCSR_DOT11_MODE_11n);
4782 if ((hdd_set_band(net, WLAN_HDD_UI_BAND_AUTO) == 0)) {
4783 phymode = eCSR_DOT11_MODE_11n;
4784 hdd_dot11mode = eHDD_DOT11_MODE_11n;
4785 chwidth = WNI_CFG_CHANNEL_BONDING_MODE_ENABLE;
4786 curr_band = eCSR_BAND_ALL;
4787 } else {
4788 sme_set_phy_mode(hal, old_phymode);
4789 return -EIO;
4790 }
4791 break;
4792 default:
4793 return -EIO;
4794 }
4795
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004796 switch (new_phymode) {
4797 case IEEE80211_MODE_11AC_VHT20:
4798 chwidth = WNI_CFG_CHANNEL_BONDING_MODE_DISABLE;
4799 vhtchanwidth = eHT_CHANNEL_WIDTH_20MHZ;
4800 break;
4801 case IEEE80211_MODE_11AC_VHT40:
4802 vhtchanwidth = eHT_CHANNEL_WIDTH_40MHZ;
4803 break;
4804 case IEEE80211_MODE_11AC_VHT80:
4805 vhtchanwidth = eHT_CHANNEL_WIDTH_80MHZ;
4806 break;
4807 default:
4808 vhtchanwidth = phddctx->config->vhtChannelWidth;
4809 break;
4810 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004811
4812 if (phymode != -EIO) {
4813 sme_get_config_param(hal, &smeconfig);
4814 smeconfig.csrConfig.phyMode = phymode;
4815#ifdef QCA_HT_2040_COEX
4816 if (phymode == eCSR_DOT11_MODE_11n &&
4817 chwidth == WNI_CFG_CHANNEL_BONDING_MODE_DISABLE) {
4818 smeconfig.csrConfig.obssEnabled = false;
4819 halStatus = sme_set_ht2040_mode(hal,
4820 pAdapter->sessionId,
4821 eHT_CHAN_HT20, false);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304822 if (halStatus == QDF_STATUS_E_FAILURE) {
Jeff Johnson99bac312016-06-28 10:38:18 -07004823 hdd_err("Failed to disable OBSS");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004824 return -EIO;
4825 }
4826 } else if (phymode == eCSR_DOT11_MODE_11n &&
4827 chwidth == WNI_CFG_CHANNEL_BONDING_MODE_ENABLE) {
4828 smeconfig.csrConfig.obssEnabled = true;
4829 halStatus = sme_set_ht2040_mode(hal,
4830 pAdapter->sessionId,
4831 eHT_CHAN_HT20, true);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304832 if (halStatus == QDF_STATUS_E_FAILURE) {
Jeff Johnson99bac312016-06-28 10:38:18 -07004833 hdd_err("Failed to enable OBSS");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004834 return -EIO;
4835 }
4836 }
4837#endif
4838 smeconfig.csrConfig.eBand = curr_band;
4839 smeconfig.csrConfig.bandCapability = curr_band;
4840 if (curr_band == eCSR_BAND_24)
4841 smeconfig.csrConfig.Is11hSupportEnabled = 0;
4842 else
4843 smeconfig.csrConfig.Is11hSupportEnabled =
4844 phddctx->config->Is11hSupportEnabled;
4845 if (curr_band == eCSR_BAND_24)
4846 smeconfig.csrConfig.channelBondingMode24GHz = chwidth;
4847 else if (curr_band == eCSR_BAND_24)
4848 smeconfig.csrConfig.channelBondingMode5GHz = chwidth;
4849 else {
4850 smeconfig.csrConfig.channelBondingMode24GHz = chwidth;
4851 smeconfig.csrConfig.channelBondingMode5GHz = chwidth;
4852 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004853 smeconfig.csrConfig.nVhtChannelWidth = vhtchanwidth;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004854 sme_update_config(hal, &smeconfig);
4855
4856 phddctx->config->dot11Mode = hdd_dot11mode;
4857 phddctx->config->nBandCapability = curr_band;
4858 phddctx->config->nChannelBondingMode24GHz =
4859 smeconfig.csrConfig.channelBondingMode24GHz;
4860 phddctx->config->nChannelBondingMode5GHz =
4861 smeconfig.csrConfig.channelBondingMode5GHz;
4862 phddctx->config->vhtChannelWidth = vhtchanwidth;
4863 if (hdd_update_config_dat(phddctx) == false) {
Jeff Johnson99bac312016-06-28 10:38:18 -07004864 hdd_err("could not update config_dat");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004865 return -EIO;
4866 }
4867 if (phddctx->config->nChannelBondingMode5GHz)
4868 phddctx->wiphy->bands[IEEE80211_BAND_5GHZ]->ht_cap.cap
4869 |= IEEE80211_HT_CAP_SUP_WIDTH_20_40;
4870 else
4871 phddctx->wiphy->bands[IEEE80211_BAND_5GHZ]->ht_cap.cap
4872 &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40;
4873
Jeff Johnson99bac312016-06-28 10:38:18 -07004874 hdd_warn("New_Phymode= %d ch_bonding=%d band=%d VHT_ch_width=%u",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004875 phymode, chwidth, curr_band, vhtchanwidth);
4876 }
4877
4878 return 0;
4879}
4880
4881/**
4882 * hdd_get_temperature_cb() - "Get Temperature" callback function
4883 * @temperature: measured temperature
4884 * @pContext: callback context
4885 *
4886 * This function is passed to sme_get_temperature() as the callback
4887 * function to be invoked when the temperature measurement is
4888 * available.
4889 *
4890 * Return: None
4891 */
4892static void hdd_get_temperature_cb(int temperature, void *pContext)
4893{
4894 struct statsContext *pTempContext;
4895 hdd_adapter_t *pAdapter;
4896 ENTER();
4897 if (NULL == pContext) {
Jeff Johnson99bac312016-06-28 10:38:18 -07004898 hdd_err("pContext is NULL");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004899 return;
4900 }
4901 pTempContext = pContext;
4902 pAdapter = pTempContext->pAdapter;
4903 spin_lock(&hdd_context_lock);
4904 if ((NULL == pAdapter) || (TEMP_CONTEXT_MAGIC != pTempContext->magic)) {
4905 spin_unlock(&hdd_context_lock);
Jeff Johnson99bac312016-06-28 10:38:18 -07004906 hdd_warn("Invalid context, pAdapter [%p] magic [%08x]",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004907 pAdapter, pTempContext->magic);
4908 return;
4909 }
4910 if (temperature != 0) {
4911 pAdapter->temperature = temperature;
4912 }
4913 complete(&pTempContext->completion);
4914 spin_unlock(&hdd_context_lock);
4915 EXIT();
4916}
4917
4918/**
4919 * wlan_hdd_get_temperature() - get current device temperature
4920 * @pAdapter: device upon which the request was made
4921 * @temperature: pointer to where the temperature is to be returned
4922 *
4923 * Return: 0 if a temperature value (either current or cached) was
4924 * returned, otherwise a negative errno is returned.
4925 *
4926 */
4927int wlan_hdd_get_temperature(hdd_adapter_t *pAdapter, int *temperature)
4928{
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304929 QDF_STATUS status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004930 struct statsContext tempContext;
4931 unsigned long rc;
4932
4933 ENTER();
4934 if (NULL == pAdapter) {
Jeff Johnson99bac312016-06-28 10:38:18 -07004935 hdd_err("pAdapter is NULL");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004936 return -EPERM;
4937 }
4938 init_completion(&tempContext.completion);
4939 tempContext.pAdapter = pAdapter;
4940 tempContext.magic = TEMP_CONTEXT_MAGIC;
4941 status = sme_get_temperature(WLAN_HDD_GET_HAL_CTX(pAdapter),
4942 &tempContext, hdd_get_temperature_cb);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304943 if (QDF_STATUS_SUCCESS != status) {
Jeff Johnson99bac312016-06-28 10:38:18 -07004944 hdd_err("Unable to retrieve temperature");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004945 } else {
4946 rc = wait_for_completion_timeout(&tempContext.completion,
4947 msecs_to_jiffies
4948 (WLAN_WAIT_TIME_STATS));
4949 if (!rc) {
Jeff Johnson99bac312016-06-28 10:38:18 -07004950 hdd_err("SME timed out while retrieving temperature");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004951 }
4952 }
4953 spin_lock(&hdd_context_lock);
4954 tempContext.magic = 0;
4955 spin_unlock(&hdd_context_lock);
4956 *temperature = pAdapter->temperature;
4957 EXIT();
4958 return 0;
4959}
4960
4961/**
4962 * iw_setint_getnone() - Generic "set integer" private ioctl handler
4963 * @dev: device upon which the ioctl was received
4964 * @info: ioctl request information
4965 * @wrqu: ioctl request data
4966 * @extra: ioctl extra data
4967 *
4968 * Return: 0 on success, non-zero on error
4969 */
4970static int __iw_setint_getnone(struct net_device *dev,
4971 struct iw_request_info *info,
4972 union iwreq_data *wrqu, char *extra)
4973{
4974 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4975 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
4976 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4977 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
4978 hdd_context_t *hdd_ctx;
4979 tSmeConfigParams smeConfig;
4980 int *value = (int *)extra;
4981 int sub_cmd = value[0];
4982 int set_value = value[1];
4983 int ret;
4984 int enable_pbm, enable_mp;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304985 QDF_STATUS status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004986
Jeff Johnson6ee91ee2016-02-11 18:55:30 -08004987 ENTER_DEV(dev);
Hanumantha Reddy Pothula2db50ed2015-11-23 10:48:33 +05304988
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004989 INIT_COMPLETION(pWextState->completion_var);
Mukul Sharma81661ae2015-10-30 20:26:02 +05304990 memset(&smeConfig, 0x00, sizeof(smeConfig));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004991
4992 hdd_ctx = WLAN_HDD_GET_CTX(pAdapter);
4993 ret = wlan_hdd_validate_context(hdd_ctx);
4994 if (0 != ret)
4995 return ret;
4996
4997 switch (sub_cmd) {
4998 case WE_SET_11D_STATE:
4999 {
5000 if ((ENABLE_11D == set_value)
5001 || (DISABLE_11D == set_value)) {
5002
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005003 sme_get_config_param(hHal, &smeConfig);
5004 smeConfig.csrConfig.Is11dSupportEnabled =
5005 (bool) set_value;
5006
Jeff Johnson99bac312016-06-28 10:38:18 -07005007 hdd_notice("11D state=%d!!",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005008 smeConfig.csrConfig.
5009 Is11dSupportEnabled);
5010
5011 sme_update_config(hHal, &smeConfig);
5012 } else {
5013 return -EINVAL;
5014 }
5015 break;
5016 }
5017
5018 case WE_WOWL:
5019 {
5020 switch (set_value) {
5021 case 0x00:
5022 hdd_exit_wowl(pAdapter);
5023 break;
5024 case 0x01:
5025 case 0x02:
5026 case 0x03:
5027 enable_mp = (set_value & 0x01) ? 1 : 0;
5028 enable_pbm = (set_value & 0x02) ? 1 : 0;
Jeff Johnson99bac312016-06-28 10:38:18 -07005029 hdd_err("magic packet ? = %s pattern byte matching ? = %s",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005030 (enable_mp ? "YES" : "NO"),
5031 (enable_pbm ? "YES" : "NO"));
5032 hdd_enter_wowl(pAdapter, enable_mp, enable_pbm);
5033 break;
5034 default:
Jeff Johnson99bac312016-06-28 10:38:18 -07005035 hdd_err("Invalid arg %d in WE_WOWL IOCTL",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005036 set_value);
5037 ret = -EINVAL;
5038 break;
5039 }
5040
5041 break;
5042 }
5043 case WE_SET_POWER:
5044 {
5045 switch (set_value) {
5046 case 1:
5047 /* Enable PowerSave */
5048 sme_ps_enable_disable(hHal, pAdapter->sessionId,
5049 SME_PS_ENABLE);
5050 break;
5051 case 2:
5052 /* Disable PowerSave */
5053 sme_ps_enable_disable(hHal, pAdapter->sessionId,
5054 SME_PS_DISABLE);
5055 break;
5056 case 3: /* Enable UASPD */
5057 sme_ps_uapsd_enable(hHal, pAdapter->sessionId);
5058 break;
5059 case 4: /* Disable UASPD */
5060 sme_ps_uapsd_disable(hHal, pAdapter->sessionId);
5061 break;
5062 default:
Jeff Johnson99bac312016-06-28 10:38:18 -07005063 hdd_err("Invalid arg %d in WE_SET_POWER IOCTL",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005064 set_value);
5065 ret = -EINVAL;
5066 break;
5067 }
5068 break;
5069 }
5070
5071 case WE_SET_MAX_ASSOC:
5072 {
5073 if ((WNI_CFG_ASSOC_STA_LIMIT_STAMIN > set_value) ||
5074 (WNI_CFG_ASSOC_STA_LIMIT_STAMAX < set_value)) {
5075 ret = -EINVAL;
5076 } else if (sme_cfg_set_int(hHal, WNI_CFG_ASSOC_STA_LIMIT,
5077 set_value)
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05305078 != QDF_STATUS_SUCCESS) {
Jeff Johnson99bac312016-06-28 10:38:18 -07005079 hdd_err("failed to set ini parameter, WNI_CFG_ASSOC_STA_LIMIT");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005080 ret = -EIO;
5081 }
5082 break;
5083 }
5084
5085 case WE_SET_SAP_AUTO_CHANNEL_SELECTION:
5086 if (set_value == 0 || set_value == 1)
5087 (WLAN_HDD_GET_CTX(pAdapter))->config->force_sap_acs =
5088 set_value;
5089 else
5090 ret = -EINVAL;
5091 break;
5092
5093 case WE_SET_DATA_INACTIVITY_TO:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005094 if ((set_value < CFG_DATA_INACTIVITY_TIMEOUT_MIN) ||
5095 (set_value > CFG_DATA_INACTIVITY_TIMEOUT_MAX) ||
5096 (sme_cfg_set_int((WLAN_HDD_GET_CTX(pAdapter))->hHal,
5097 WNI_CFG_PS_DATA_INACTIVITY_TIMEOUT,
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05305098 set_value) == QDF_STATUS_E_FAILURE)) {
Jeff Johnson99bac312016-06-28 10:38:18 -07005099 hdd_err("Failure: Could not pass on WNI_CFG_PS_DATA_INACTIVITY_TIMEOUT configuration info to SME");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005100 ret = -EINVAL;
5101 }
5102 break;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005103 case WE_SET_MC_RATE:
5104 {
5105 ret = wlan_hdd_set_mc_rate(pAdapter, set_value);
5106 break;
5107 }
5108 case WE_SET_TX_POWER:
5109 {
Anurag Chouhan6d760662016-02-20 16:05:43 +05305110 struct qdf_mac_addr bssid;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005111
Anurag Chouhanc5548422016-02-24 18:33:27 +05305112 qdf_copy_macaddr(&bssid, &pHddStaCtx->conn_info.bssId);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005113 if (sme_set_tx_power
5114 (hHal, pAdapter->sessionId, bssid,
5115 pAdapter->device_mode,
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05305116 set_value) != QDF_STATUS_SUCCESS) {
Jeff Johnson99bac312016-06-28 10:38:18 -07005117 hdd_err("Setting tx power failed");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005118 return -EIO;
5119 }
5120 break;
5121 }
5122 case WE_SET_MAX_TX_POWER:
5123 {
Anurag Chouhan6d760662016-02-20 16:05:43 +05305124 struct qdf_mac_addr bssid;
5125 struct qdf_mac_addr selfMac;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005126
Jeff Johnson99bac312016-06-28 10:38:18 -07005127 hdd_notice("Setting maximum tx power %d dBm",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005128 set_value);
Anurag Chouhanc5548422016-02-24 18:33:27 +05305129 qdf_copy_macaddr(&bssid, &pHddStaCtx->conn_info.bssId);
5130 qdf_copy_macaddr(&selfMac, &pHddStaCtx->conn_info.bssId);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005131
5132 if (sme_set_max_tx_power(hHal, bssid, selfMac, set_value)
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05305133 != QDF_STATUS_SUCCESS) {
Jeff Johnson99bac312016-06-28 10:38:18 -07005134 hdd_err("Setting maximum tx power failed");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005135 return -EIO;
5136 }
5137
5138 break;
5139 }
5140 case WE_SET_MAX_TX_POWER_2_4:
5141 {
Jeff Johnson99bac312016-06-28 10:38:18 -07005142 hdd_notice("Setting maximum tx power %d dBm for 2.4 GHz band",
5143 set_value);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005144 if (sme_set_max_tx_power_per_band(eCSR_BAND_24, set_value) !=
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05305145 QDF_STATUS_SUCCESS) {
Jeff Johnson99bac312016-06-28 10:38:18 -07005146 hdd_err("Setting maximum tx power failed for 2.4 GHz band");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005147 return -EIO;
5148 }
5149
5150 break;
5151 }
5152 case WE_SET_MAX_TX_POWER_5_0:
5153 {
Jeff Johnson99bac312016-06-28 10:38:18 -07005154 hdd_notice("Setting maximum tx power %d dBm for 5.0 GHz band",
5155 set_value);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005156 if (sme_set_max_tx_power_per_band(eCSR_BAND_5G, set_value) !=
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05305157 QDF_STATUS_SUCCESS) {
Jeff Johnson99bac312016-06-28 10:38:18 -07005158 hdd_err("Setting maximum tx power failed for 5.0 GHz band");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005159 return -EIO;
5160 }
5161
5162 break;
5163 }
Srinivas Girigowdac34f11d2016-02-25 16:02:42 -08005164 case WE_SET_PKTLOG:
5165 {
5166 hdd_process_pktlog_command(hdd_ctx, set_value);
5167 break;
5168 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005169 case WE_SET_HIGHER_DTIM_TRANSITION:
5170 {
5171 if (!((set_value == false) || (set_value == true))) {
Jeff Johnson99bac312016-06-28 10:38:18 -07005172 hdd_err("Dynamic DTIM Incorrect data:%d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005173 set_value);
5174 ret = -EINVAL;
5175 } else {
5176 if (pAdapter->higherDtimTransition != set_value) {
5177 pAdapter->higherDtimTransition =
5178 set_value;
Jeff Johnson99bac312016-06-28 10:38:18 -07005179 hdd_notice("higherDtimTransition set to :%d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005180 pAdapter->higherDtimTransition);
5181 }
5182 }
5183
5184 break;
5185 }
5186
5187 case WE_SET_TM_LEVEL:
5188 {
Jeff Johnson99bac312016-06-28 10:38:18 -07005189 hdd_notice("Set Thermal Mitigation Level %d", set_value);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005190 (void)sme_set_thermal_level(hHal, set_value);
5191 break;
5192 }
5193
5194 case WE_SET_PHYMODE:
5195 {
5196 hdd_context_t *phddctx = WLAN_HDD_GET_CTX(pAdapter);
5197
5198 ret =
5199 wlan_hdd_update_phymode(dev, hHal, set_value,
5200 phddctx);
5201 break;
5202 }
5203
5204 case WE_SET_NSS:
5205 {
Jeff Johnson99bac312016-06-28 10:38:18 -07005206 hdd_notice("Set NSS = %d", set_value);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005207 if ((set_value > 2) || (set_value <= 0)) {
Jeff Johnson99bac312016-06-28 10:38:18 -07005208 hdd_err("NSS greater than 2 not supported");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005209 ret = -EINVAL;
5210 } else {
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05305211 if (QDF_STATUS_SUCCESS !=
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005212 hdd_update_nss(WLAN_HDD_GET_CTX(pAdapter),
5213 set_value))
5214 ret = -EINVAL;
5215 }
5216 break;
5217 }
5218
5219 case WE_SET_GTX_HT_MCS:
5220 {
Jeff Johnson99bac312016-06-28 10:38:18 -07005221 hdd_notice("WMI_VDEV_PARAM_GTX_HT_MCS %d", set_value);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005222 ret = wma_cli_set_command(pAdapter->sessionId,
5223 WMI_VDEV_PARAM_GTX_HT_MCS,
5224 set_value, GTX_CMD);
5225 break;
5226 }
5227
5228 case WE_SET_GTX_VHT_MCS:
5229 {
Jeff Johnson99bac312016-06-28 10:38:18 -07005230 hdd_notice("WMI_VDEV_PARAM_GTX_VHT_MCS %d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005231 set_value);
5232 ret = wma_cli_set_command(pAdapter->sessionId,
5233 WMI_VDEV_PARAM_GTX_VHT_MCS,
5234 set_value, GTX_CMD);
5235 break;
5236 }
5237
5238 case WE_SET_GTX_USRCFG:
5239 {
Jeff Johnson99bac312016-06-28 10:38:18 -07005240 hdd_notice("WMI_VDEV_PARAM_GTX_USR_CFG %d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005241 set_value);
5242 ret = wma_cli_set_command(pAdapter->sessionId,
5243 WMI_VDEV_PARAM_GTX_USR_CFG,
5244 set_value, GTX_CMD);
5245 break;
5246 }
5247
5248 case WE_SET_GTX_THRE:
5249 {
Jeff Johnson99bac312016-06-28 10:38:18 -07005250 hdd_notice("WMI_VDEV_PARAM_GTX_THRE %d", set_value);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005251 ret = wma_cli_set_command(pAdapter->sessionId,
5252 WMI_VDEV_PARAM_GTX_THRE,
5253 set_value, GTX_CMD);
5254 break;
5255 }
5256
5257 case WE_SET_GTX_MARGIN:
5258 {
Jeff Johnson99bac312016-06-28 10:38:18 -07005259 hdd_notice("WMI_VDEV_PARAM_GTX_MARGIN %d", set_value);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005260 ret = wma_cli_set_command(pAdapter->sessionId,
5261 WMI_VDEV_PARAM_GTX_MARGIN,
5262 set_value, GTX_CMD);
5263 break;
5264 }
5265
5266 case WE_SET_GTX_STEP:
5267 {
Jeff Johnson99bac312016-06-28 10:38:18 -07005268 hdd_notice("WMI_VDEV_PARAM_GTX_STEP %d", set_value);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005269 ret = wma_cli_set_command(pAdapter->sessionId,
5270 WMI_VDEV_PARAM_GTX_STEP,
5271 set_value, GTX_CMD);
5272 break;
5273 }
5274
5275 case WE_SET_GTX_MINTPC:
5276 {
Jeff Johnson99bac312016-06-28 10:38:18 -07005277 hdd_notice("WMI_VDEV_PARAM_GTX_MINTPC %d", set_value);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005278 ret = wma_cli_set_command(pAdapter->sessionId,
5279 WMI_VDEV_PARAM_GTX_MINTPC,
5280 set_value, GTX_CMD);
5281 break;
5282 }
5283
5284 case WE_SET_GTX_BWMASK:
5285 {
Jeff Johnson99bac312016-06-28 10:38:18 -07005286 hdd_notice("WMI_VDEV_PARAM_GTX_BWMASK %d", set_value);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005287 ret = wma_cli_set_command(pAdapter->sessionId,
5288 WMI_VDEV_PARAM_GTX_BW_MASK,
5289 set_value, GTX_CMD);
5290 break;
5291 }
5292
5293 case WE_SET_LDPC:
5294 {
5295 uint32_t value;
5296 union {
5297 uint16_t nCfgValue16;
5298 tSirMacHTCapabilityInfo htCapInfo;
5299 } uHTCapabilityInfo;
5300
Jeff Johnson99bac312016-06-28 10:38:18 -07005301 hdd_notice("LDPC val %d", set_value);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005302 /* get the HT capability info */
5303 ret = sme_cfg_get_int(hHal, WNI_CFG_HT_CAP_INFO, &value);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05305304 if (QDF_STATUS_SUCCESS != ret) {
Jeff Johnson99bac312016-06-28 10:38:18 -07005305 hdd_err("could not get HT capability info");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005306 return -EIO;
5307 }
5308
5309 uHTCapabilityInfo.nCfgValue16 = 0xFFFF & value;
5310 if ((set_value
5311 && (uHTCapabilityInfo.htCapInfo.advCodingCap))
5312 || (!set_value)) {
5313 ret =
5314 sme_update_ht_config(hHal,
5315 pAdapter->sessionId,
5316 WNI_CFG_HT_CAP_INFO_ADVANCE_CODING,
5317 set_value);
5318 }
5319
5320 if (ret)
Jeff Johnson99bac312016-06-28 10:38:18 -07005321 hdd_err("Failed to set LDPC value");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005322
5323 break;
5324 }
5325
5326 case WE_SET_TX_STBC:
5327 {
5328 uint32_t value;
5329 union {
5330 uint16_t nCfgValue16;
5331 tSirMacHTCapabilityInfo htCapInfo;
5332 } uHTCapabilityInfo;
5333
Jeff Johnson99bac312016-06-28 10:38:18 -07005334 hdd_notice("TX_STBC val %d", set_value);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005335 /* get the HT capability info */
5336 ret = sme_cfg_get_int(hHal, WNI_CFG_HT_CAP_INFO, &value);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05305337 if (QDF_STATUS_SUCCESS != ret) {
Jeff Johnson99bac312016-06-28 10:38:18 -07005338 hdd_err("could not get HT capability info");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005339 return -EIO;
5340 }
5341
5342 uHTCapabilityInfo.nCfgValue16 = 0xFFFF & value;
5343 if ((set_value && (uHTCapabilityInfo.htCapInfo.txSTBC))
5344 || (!set_value)) {
5345 ret =
5346 sme_update_ht_config(hHal,
5347 pAdapter->sessionId,
5348 WNI_CFG_HT_CAP_INFO_TX_STBC,
5349 set_value);
5350 }
5351
5352 if (ret)
Jeff Johnson99bac312016-06-28 10:38:18 -07005353 hdd_err("Failed to set TX STBC value");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005354
5355 break;
5356 }
5357
5358 case WE_SET_RX_STBC:
5359 {
5360 uint32_t value;
5361 union {
5362 uint16_t nCfgValue16;
5363 tSirMacHTCapabilityInfo htCapInfo;
5364 } uHTCapabilityInfo;
5365
Jeff Johnson99bac312016-06-28 10:38:18 -07005366 hdd_notice("WMI_VDEV_PARAM_RX_STBC val %d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005367 set_value);
5368 /* get the HT capability info */
5369 ret = sme_cfg_get_int(hHal, WNI_CFG_HT_CAP_INFO, &value);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05305370 if (QDF_STATUS_SUCCESS != ret) {
Jeff Johnson99bac312016-06-28 10:38:18 -07005371 hdd_err("could not get HT capability info");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005372 return -EIO;
5373 }
5374
5375 uHTCapabilityInfo.nCfgValue16 = 0xFFFF & value;
5376 if ((set_value && (uHTCapabilityInfo.htCapInfo.rxSTBC))
5377 || (!set_value)) {
5378 ret =
5379 sme_update_ht_config(hHal,
5380 pAdapter->sessionId,
5381 WNI_CFG_HT_CAP_INFO_RX_STBC,
5382 (!set_value) ? set_value
5383 : uHTCapabilityInfo.
5384 htCapInfo.rxSTBC);
5385 }
5386
5387 if (ret)
Jeff Johnson99bac312016-06-28 10:38:18 -07005388 hdd_err("Failed to set RX STBC value");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005389 break;
5390 }
5391
5392 case WE_SET_SHORT_GI:
5393 {
Jeff Johnson99bac312016-06-28 10:38:18 -07005394 hdd_notice("WMI_VDEV_PARAM_SGI val %d", set_value);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005395 ret = sme_update_ht_config(hHal, pAdapter->sessionId,
5396 WNI_CFG_HT_CAP_INFO_SHORT_GI_20MHZ,
5397 set_value);
5398 if (ret)
Jeff Johnson99bac312016-06-28 10:38:18 -07005399 hdd_err("Failed to set ShortGI value");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005400 break;
5401 }
5402
5403 case WE_SET_RTSCTS:
5404 {
5405 uint32_t value;
5406
Jeff Johnson99bac312016-06-28 10:38:18 -07005407 hdd_notice("WMI_VDEV_PARAM_ENABLE_RTSCTS val 0x%x",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005408 set_value);
5409
5410 if ((set_value & HDD_RTSCTS_EN_MASK) ==
5411 HDD_RTSCTS_ENABLE)
5412 value =
5413 (WLAN_HDD_GET_CTX(pAdapter))->config->
5414 RTSThreshold;
5415 else if (((set_value & HDD_RTSCTS_EN_MASK) == 0)
5416 || ((set_value & HDD_RTSCTS_EN_MASK) ==
5417 HDD_CTS_ENABLE))
5418 value = WNI_CFG_RTS_THRESHOLD_STAMAX;
5419 else
5420 return -EIO;
5421
5422 ret = wma_cli_set_command(pAdapter->sessionId,
5423 WMI_VDEV_PARAM_ENABLE_RTSCTS,
5424 set_value, VDEV_CMD);
5425 if (!ret) {
5426 if (sme_cfg_set_int
5427 (hHal, WNI_CFG_RTS_THRESHOLD, value) !=
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05305428 QDF_STATUS_SUCCESS) {
Jeff Johnson99bac312016-06-28 10:38:18 -07005429 hdd_err("FAILED TO SET RTSCTS");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005430 return -EIO;
5431 }
5432 }
5433
5434 break;
5435 }
5436
5437 case WE_SET_CHWIDTH:
5438 {
5439 bool chwidth = false;
5440 hdd_context_t *phddctx = WLAN_HDD_GET_CTX(pAdapter);
5441 /*updating channel bonding only on 5Ghz */
Jeff Johnson99bac312016-06-28 10:38:18 -07005442 hdd_notice("WMI_VDEV_PARAM_CHWIDTH val %d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005443 set_value);
5444 if (set_value > eHT_CHANNEL_WIDTH_80MHZ) {
Jeff Johnson99bac312016-06-28 10:38:18 -07005445 hdd_err("Invalid channel width 0->20 1->40 2->80");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005446 return -EINVAL;
5447 }
5448
5449 if ((WNI_CFG_CHANNEL_BONDING_MODE_DISABLE !=
5450 csr_convert_cb_ini_value_to_phy_cb_state(phddctx->config->
5451 nChannelBondingMode5GHz)))
5452 chwidth = true;
5453
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005454 sme_get_config_param(hHal, &smeConfig);
5455 switch (set_value) {
5456 case eHT_CHANNEL_WIDTH_20MHZ:
5457 smeConfig.csrConfig.channelBondingMode5GHz =
5458 WNI_CFG_CHANNEL_BONDING_MODE_DISABLE;
5459 break;
5460 case eHT_CHANNEL_WIDTH_40MHZ:
5461 if (chwidth)
5462 smeConfig.csrConfig.
5463 channelBondingMode5GHz =
5464 phddctx->config->
5465 nChannelBondingMode5GHz;
5466 else
5467 return -EINVAL;
5468
5469 break;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005470 case eHT_CHANNEL_WIDTH_80MHZ:
5471 if (chwidth)
5472 smeConfig.csrConfig.
5473 channelBondingMode5GHz =
5474 phddctx->config->
5475 nChannelBondingMode5GHz;
5476 else
5477 return -EINVAL;
5478
5479 break;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005480
5481 default:
5482 return -EINVAL;
5483 }
5484
5485 ret = wma_cli_set_command(pAdapter->sessionId,
5486 WMI_VDEV_PARAM_CHWIDTH,
5487 set_value, VDEV_CMD);
5488 if (!ret)
5489 sme_update_config(hHal, &smeConfig);
5490
5491 break;
5492 }
5493
5494 case WE_SET_ANI_EN_DIS:
5495 {
Jeff Johnson99bac312016-06-28 10:38:18 -07005496 hdd_notice("WMI_PDEV_PARAM_ANI_ENABLE val %d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005497 set_value);
5498 ret = wma_cli_set_command(pAdapter->sessionId,
5499 WMI_PDEV_PARAM_ANI_ENABLE,
5500 set_value, PDEV_CMD);
5501 break;
5502 }
5503
5504 case WE_SET_ANI_POLL_PERIOD:
5505 {
Jeff Johnson99bac312016-06-28 10:38:18 -07005506 hdd_notice("WMI_PDEV_PARAM_ANI_POLL_PERIOD val %d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005507 set_value);
5508 ret = wma_cli_set_command(pAdapter->sessionId,
5509 WMI_PDEV_PARAM_ANI_POLL_PERIOD,
5510 set_value, PDEV_CMD);
5511 break;
5512 }
5513
5514 case WE_SET_ANI_LISTEN_PERIOD:
5515 {
Jeff Johnson99bac312016-06-28 10:38:18 -07005516 hdd_notice("WMI_PDEV_PARAM_ANI_LISTEN_PERIOD val %d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005517 set_value);
5518 ret = wma_cli_set_command(pAdapter->sessionId,
5519 WMI_PDEV_PARAM_ANI_LISTEN_PERIOD,
5520 set_value, PDEV_CMD);
5521 break;
5522 }
5523
5524 case WE_SET_ANI_OFDM_LEVEL:
5525 {
Jeff Johnson99bac312016-06-28 10:38:18 -07005526 hdd_notice("WMI_PDEV_PARAM_ANI_OFDM_LEVEL val %d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005527 set_value);
5528 ret = wma_cli_set_command(pAdapter->sessionId,
5529 WMI_PDEV_PARAM_ANI_OFDM_LEVEL,
5530 set_value, PDEV_CMD);
5531 break;
5532 }
5533
5534 case WE_SET_ANI_CCK_LEVEL:
5535 {
Jeff Johnson99bac312016-06-28 10:38:18 -07005536 hdd_notice("WMI_PDEV_PARAM_ANI_CCK_LEVEL val %d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005537 set_value);
5538 ret = wma_cli_set_command(pAdapter->sessionId,
5539 WMI_PDEV_PARAM_ANI_CCK_LEVEL,
5540 set_value, PDEV_CMD);
5541 break;
5542 }
5543
5544 case WE_SET_DYNAMIC_BW:
5545 {
Jeff Johnson99bac312016-06-28 10:38:18 -07005546 hdd_notice("WMI_PDEV_PARAM_DYNAMIC_BW val %d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005547 set_value);
5548 ret = wma_cli_set_command(pAdapter->sessionId,
5549 WMI_PDEV_PARAM_DYNAMIC_BW,
5550 set_value, PDEV_CMD);
5551 break;
5552 }
5553
5554 case WE_SET_CTS_CBW:
5555 {
Jeff Johnson99bac312016-06-28 10:38:18 -07005556 hdd_notice("WE_SET_CTS_CBW val %d", set_value);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005557 ret = wma_cli_set_command(pAdapter->sessionId,
5558 WMI_PDEV_PARAM_CTS_CBW,
5559 set_value, PDEV_CMD);
5560 break;
5561 }
5562
5563 case WE_SET_11N_RATE:
5564 {
5565 uint8_t preamble = 0, nss = 0, rix = 0;
Jeff Johnson99bac312016-06-28 10:38:18 -07005566 hdd_notice("WMI_VDEV_PARAM_FIXED_RATE val %d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005567 set_value);
5568
5569 if (set_value != 0xff) {
5570 rix = RC_2_RATE_IDX(set_value);
5571 if (set_value & 0x80) {
5572 preamble = WMI_RATE_PREAMBLE_HT;
5573 nss = HT_RC_2_STREAMS(set_value) - 1;
5574 } else {
5575 nss = 0;
5576 rix = RC_2_RATE_IDX(set_value);
5577 if (set_value & 0x10) {
5578 preamble =
5579 WMI_RATE_PREAMBLE_CCK;
5580 if (rix != 0x3)
5581 /* Enable Short
5582 * preamble always for
5583 * CCK except 1mbps
5584 */
5585 rix |= 0x4;
5586 } else {
5587 preamble =
5588 WMI_RATE_PREAMBLE_OFDM;
5589 }
5590 }
5591 set_value = (preamble << 6) | (nss << 4) | rix;
5592 }
5593 hdd_info("WMI_VDEV_PARAM_FIXED_RATE val %d rix %d preamble %x nss %d",
5594 set_value, rix, preamble, nss);
5595
5596 ret = wma_cli_set_command(pAdapter->sessionId,
5597 WMI_VDEV_PARAM_FIXED_RATE,
5598 set_value, VDEV_CMD);
5599 break;
5600 }
5601
5602 case WE_SET_VHT_RATE:
5603 {
5604 uint8_t preamble = 0, nss = 0, rix = 0;
5605
5606 if (set_value != 0xff) {
5607 rix = RC_2_RATE_IDX_11AC(set_value);
5608 preamble = WMI_RATE_PREAMBLE_VHT;
5609 nss = HT_RC_2_STREAMS_11AC(set_value) - 1;
5610
5611 set_value = (preamble << 6) | (nss << 4) | rix;
5612 }
5613 hdd_info("WMI_VDEV_PARAM_FIXED_RATE val %d rix %d preamble %x nss %d",
5614 set_value, rix, preamble, nss);
5615 ret = wma_cli_set_command(pAdapter->sessionId,
5616 WMI_VDEV_PARAM_FIXED_RATE,
5617 set_value, VDEV_CMD);
5618 break;
5619 }
5620
5621 case WE_SET_AMPDU:
5622 {
Jeff Johnson99bac312016-06-28 10:38:18 -07005623 hdd_notice("SET AMPDU val %d", set_value);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005624 ret = wma_cli_set_command(pAdapter->sessionId,
5625 GEN_VDEV_PARAM_AMPDU,
5626 set_value, GEN_CMD);
5627 break;
5628 }
5629
5630 case WE_SET_AMSDU:
5631 {
Jeff Johnson99bac312016-06-28 10:38:18 -07005632 hdd_notice("SET AMSDU val %d", set_value);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005633 ret = wma_cli_set_command(pAdapter->sessionId,
5634 GEN_VDEV_PARAM_AMSDU,
5635 set_value, GEN_CMD);
5636 break;
5637 }
5638
5639 case WE_SET_BURST_ENABLE:
5640 {
Jeff Johnson99bac312016-06-28 10:38:18 -07005641 hdd_notice("SET Burst enable val %d", set_value);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005642 if ((set_value == 0) || (set_value == 1)) {
5643 ret = wma_cli_set_command(pAdapter->sessionId,
5644 WMI_PDEV_PARAM_BURST_ENABLE,
5645 set_value, PDEV_CMD);
5646 } else
5647 ret = -EINVAL;
5648 break;
5649 }
5650 case WE_SET_BURST_DUR:
5651 {
Jeff Johnson99bac312016-06-28 10:38:18 -07005652 hdd_notice("SET Burst duration val %d", set_value);
Jeff Johnsonda5ee772016-08-04 17:18:47 -07005653 if ((set_value > 0) && (set_value <= 102400))
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005654 ret = wma_cli_set_command(pAdapter->sessionId,
5655 WMI_PDEV_PARAM_BURST_DUR,
5656 set_value, PDEV_CMD);
5657 else
5658 ret = -EINVAL;
5659 break;
5660 }
5661
5662 case WE_SET_TX_CHAINMASK:
5663 {
Jeff Johnson99bac312016-06-28 10:38:18 -07005664 hdd_notice("WMI_PDEV_PARAM_TX_CHAIN_MASK val %d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005665 set_value);
5666 ret = wma_cli_set_command(pAdapter->sessionId,
5667 WMI_PDEV_PARAM_TX_CHAIN_MASK,
5668 set_value, PDEV_CMD);
5669 break;
5670 }
5671
5672 case WE_SET_RX_CHAINMASK:
5673 {
Jeff Johnson99bac312016-06-28 10:38:18 -07005674 hdd_notice("WMI_PDEV_PARAM_RX_CHAIN_MASK val %d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005675 set_value);
5676 ret = wma_cli_set_command(pAdapter->sessionId,
5677 WMI_PDEV_PARAM_RX_CHAIN_MASK,
5678 set_value, PDEV_CMD);
5679 break;
5680 }
5681
5682 case WE_SET_TXPOW_2G:
5683 {
Jeff Johnson99bac312016-06-28 10:38:18 -07005684 hdd_notice("WMI_PDEV_PARAM_TXPOWER_LIMIT2G val %d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005685 set_value);
5686 ret = wma_cli_set_command(pAdapter->sessionId,
5687 WMI_PDEV_PARAM_TXPOWER_LIMIT2G,
5688 set_value, PDEV_CMD);
5689 break;
5690 }
5691
5692 case WE_SET_TXPOW_5G:
5693 {
Jeff Johnson99bac312016-06-28 10:38:18 -07005694 hdd_notice("WMI_PDEV_PARAM_TXPOWER_LIMIT5G val %d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005695 set_value);
5696 ret = wma_cli_set_command(pAdapter->sessionId,
5697 WMI_PDEV_PARAM_TXPOWER_LIMIT5G,
5698 set_value, PDEV_CMD);
5699 break;
5700 }
5701
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005702 /* Firmware debug log */
5703 case WE_DBGLOG_LOG_LEVEL:
5704 {
Jeff Johnson99bac312016-06-28 10:38:18 -07005705 hdd_notice("WE_DBGLOG_LOG_LEVEL val %d", set_value);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005706 hdd_ctx->fw_log_settings.dl_loglevel = set_value;
5707 ret = wma_cli_set_command(pAdapter->sessionId,
5708 WMI_DBGLOG_LOG_LEVEL,
5709 set_value, DBG_CMD);
5710 break;
5711 }
5712
5713 case WE_DBGLOG_VAP_ENABLE:
5714 {
Jeff Johnson99bac312016-06-28 10:38:18 -07005715 hdd_notice("WE_DBGLOG_VAP_ENABLE val %d", set_value);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005716 ret = wma_cli_set_command(pAdapter->sessionId,
5717 WMI_DBGLOG_VAP_ENABLE,
5718 set_value, DBG_CMD);
5719 break;
5720 }
5721
5722 case WE_DBGLOG_VAP_DISABLE:
5723 {
Jeff Johnson99bac312016-06-28 10:38:18 -07005724 hdd_notice("WE_DBGLOG_VAP_DISABLE val %d", set_value);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005725 ret = wma_cli_set_command(pAdapter->sessionId,
5726 WMI_DBGLOG_VAP_DISABLE,
5727 set_value, DBG_CMD);
5728 break;
5729 }
5730
5731 case WE_DBGLOG_MODULE_ENABLE:
5732 {
Jeff Johnson99bac312016-06-28 10:38:18 -07005733 hdd_notice("WE_DBGLOG_MODULE_ENABLE val %d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005734 set_value);
5735 hdd_ctx->fw_log_settings.enable = set_value;
5736 ret = wma_cli_set_command(pAdapter->sessionId,
5737 WMI_DBGLOG_MODULE_ENABLE,
5738 set_value, DBG_CMD);
5739 break;
5740 }
5741
5742 case WE_DBGLOG_MODULE_DISABLE:
5743 {
Jeff Johnson99bac312016-06-28 10:38:18 -07005744 hdd_notice("WE_DBGLOG_MODULE_DISABLE val %d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005745 set_value);
5746 hdd_ctx->fw_log_settings.enable = set_value;
5747 ret = wma_cli_set_command(pAdapter->sessionId,
5748 WMI_DBGLOG_MODULE_DISABLE,
5749 set_value, DBG_CMD);
5750 break;
5751 }
5752 case WE_DBGLOG_MOD_LOG_LEVEL:
5753 {
Jeff Johnson99bac312016-06-28 10:38:18 -07005754 hdd_notice("WE_DBGLOG_MOD_LOG_LEVEL val %d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005755 set_value);
5756
5757 if (hdd_ctx->fw_log_settings.index >= MAX_MOD_LOGLEVEL)
5758 hdd_ctx->fw_log_settings.index = 0;
5759
5760 hdd_ctx->fw_log_settings.
5761 dl_mod_loglevel[hdd_ctx->fw_log_settings.index] =
5762 set_value;
5763 hdd_ctx->fw_log_settings.index++;
5764
5765 ret = wma_cli_set_command(pAdapter->sessionId,
5766 WMI_DBGLOG_MOD_LOG_LEVEL,
5767 set_value, DBG_CMD);
5768 break;
5769 }
5770
5771 case WE_DBGLOG_TYPE:
5772 {
Jeff Johnson99bac312016-06-28 10:38:18 -07005773 hdd_notice("WE_DBGLOG_TYPE val %d", set_value);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005774 hdd_ctx->fw_log_settings.dl_type = set_value;
5775 ret = wma_cli_set_command(pAdapter->sessionId,
5776 WMI_DBGLOG_TYPE,
5777 set_value, DBG_CMD);
5778 break;
5779 }
5780 case WE_DBGLOG_REPORT_ENABLE:
5781 {
Jeff Johnson99bac312016-06-28 10:38:18 -07005782 hdd_notice("WE_DBGLOG_REPORT_ENABLE val %d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005783 set_value);
5784 hdd_ctx->fw_log_settings.dl_report = set_value;
5785 ret = wma_cli_set_command(pAdapter->sessionId,
5786 WMI_DBGLOG_REPORT_ENABLE,
5787 set_value, DBG_CMD);
5788 break;
5789 }
5790
5791 case WE_SET_TXRX_FWSTATS:
5792 {
Jeff Johnson99bac312016-06-28 10:38:18 -07005793 hdd_notice("WE_SET_TXRX_FWSTATS val %d", set_value);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005794 ret = wma_cli_set_command(pAdapter->sessionId,
5795 WMA_VDEV_TXRX_FWSTATS_ENABLE_CMDID,
5796 set_value, VDEV_CMD);
5797 break;
5798 }
5799
5800 case WE_TXRX_FWSTATS_RESET:
5801 {
Jeff Johnson99bac312016-06-28 10:38:18 -07005802 hdd_notice("WE_TXRX_FWSTATS_RESET val %d", set_value);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005803 ret = wma_cli_set_command(pAdapter->sessionId,
5804 WMA_VDEV_TXRX_FWSTATS_RESET_CMDID,
5805 set_value, VDEV_CMD);
5806 break;
5807 }
5808
5809 case WE_DUMP_STATS:
5810 {
Jeff Johnson99bac312016-06-28 10:38:18 -07005811 hdd_notice("WE_DUMP_STATS val %d", set_value);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005812 hdd_wlan_dump_stats(pAdapter, set_value);
5813 break;
5814 }
5815
5816 case WE_CLEAR_STATS:
5817 {
Jeff Johnson99bac312016-06-28 10:38:18 -07005818 hdd_notice("WE_CLEAR_STATS val %d", set_value);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005819 switch (set_value) {
5820 case WLAN_HDD_STATS:
5821 memset(&pAdapter->stats, 0, sizeof(pAdapter->stats));
5822 memset(&pAdapter->hdd_stats, 0,
5823 sizeof(pAdapter->hdd_stats));
5824 break;
5825 case WLAN_TXRX_HIST_STATS:
5826 wlan_hdd_clear_tx_rx_histogram(hdd_ctx);
5827 break;
5828 case WLAN_HDD_NETIF_OPER_HISTORY:
5829 wlan_hdd_clear_netif_queue_history(hdd_ctx);
5830 break;
Nirav Shahbf1b0332016-05-25 14:27:39 +05305831 case WLAN_HIF_STATS:
5832 hdd_clear_hif_stats();
5833 break;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005834 default:
5835 ol_txrx_clear_stats(set_value);
5836 }
5837 break;
5838 }
5839
5840 case WE_PPS_PAID_MATCH:
5841 {
Krunal Sonif07bb382016-03-10 13:02:11 -08005842 if (pAdapter->device_mode != QDF_STA_MODE)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005843 return EINVAL;
5844
Jeff Johnson99bac312016-06-28 10:38:18 -07005845 hdd_notice("WMI_VDEV_PPS_PAID_MATCH val %d ",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005846 set_value);
5847 ret = wma_cli_set_command(pAdapter->sessionId,
5848 WMI_VDEV_PPS_PAID_MATCH,
5849 set_value, PPS_CMD);
5850 break;
5851 }
5852
5853 case WE_PPS_GID_MATCH:
5854 {
Krunal Sonif07bb382016-03-10 13:02:11 -08005855 if (pAdapter->device_mode != QDF_STA_MODE)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005856 return EINVAL;
Jeff Johnson99bac312016-06-28 10:38:18 -07005857 hdd_notice("WMI_VDEV_PPS_GID_MATCH val %d ",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005858 set_value);
5859 ret = wma_cli_set_command(pAdapter->sessionId,
5860 WMI_VDEV_PPS_GID_MATCH,
5861 set_value, PPS_CMD);
5862 break;
5863 }
5864
5865 case WE_PPS_EARLY_TIM_CLEAR:
5866 {
Krunal Sonif07bb382016-03-10 13:02:11 -08005867 if (pAdapter->device_mode != QDF_STA_MODE)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005868 return EINVAL;
Jeff Johnson99bac312016-06-28 10:38:18 -07005869 hdd_notice(" WMI_VDEV_PPS_EARLY_TIM_CLEAR val %d ",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005870 set_value);
5871 ret = wma_cli_set_command(pAdapter->sessionId,
5872 WMI_VDEV_PPS_EARLY_TIM_CLEAR,
5873 set_value, PPS_CMD);
5874 break;
5875 }
5876
5877 case WE_PPS_EARLY_DTIM_CLEAR:
5878 {
Krunal Sonif07bb382016-03-10 13:02:11 -08005879 if (pAdapter->device_mode != QDF_STA_MODE)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005880 return EINVAL;
Jeff Johnson99bac312016-06-28 10:38:18 -07005881 hdd_notice("WMI_VDEV_PPS_EARLY_DTIM_CLEAR val %d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005882 set_value);
5883 ret = wma_cli_set_command(pAdapter->sessionId,
5884 WMI_VDEV_PPS_EARLY_DTIM_CLEAR,
5885 set_value, PPS_CMD);
5886 break;
5887 }
5888
5889 case WE_PPS_EOF_PAD_DELIM:
5890 {
Krunal Sonif07bb382016-03-10 13:02:11 -08005891 if (pAdapter->device_mode != QDF_STA_MODE)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005892 return EINVAL;
Jeff Johnson99bac312016-06-28 10:38:18 -07005893 hdd_notice("WMI_VDEV_PPS_EOF_PAD_DELIM val %d ",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005894 set_value);
5895 ret = wma_cli_set_command(pAdapter->sessionId,
5896 WMI_VDEV_PPS_EOF_PAD_DELIM,
5897 set_value, PPS_CMD);
5898 break;
5899 }
5900
5901 case WE_PPS_MACADDR_MISMATCH:
5902 {
Krunal Sonif07bb382016-03-10 13:02:11 -08005903 if (pAdapter->device_mode != QDF_STA_MODE)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005904 return EINVAL;
Jeff Johnson99bac312016-06-28 10:38:18 -07005905 hdd_notice("WMI_VDEV_PPS_MACADDR_MISMATCH val %d ",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005906 set_value);
5907 ret = wma_cli_set_command(pAdapter->sessionId,
5908 WMI_VDEV_PPS_MACADDR_MISMATCH,
5909 set_value, PPS_CMD);
5910 break;
5911 }
5912
5913 case WE_PPS_DELIM_CRC_FAIL:
5914 {
Krunal Sonif07bb382016-03-10 13:02:11 -08005915 if (pAdapter->device_mode != QDF_STA_MODE)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005916 return EINVAL;
Jeff Johnson99bac312016-06-28 10:38:18 -07005917 hdd_notice("WMI_VDEV_PPS_DELIM_CRC_FAIL val %d ",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005918 set_value);
5919 ret = wma_cli_set_command(pAdapter->sessionId,
5920 WMI_VDEV_PPS_DELIM_CRC_FAIL,
5921 set_value, PPS_CMD);
5922 break;
5923 }
5924
5925 case WE_PPS_GID_NSTS_ZERO:
5926 {
Krunal Sonif07bb382016-03-10 13:02:11 -08005927 if (pAdapter->device_mode != QDF_STA_MODE)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005928 return EINVAL;
Jeff Johnson99bac312016-06-28 10:38:18 -07005929 hdd_notice("WMI_VDEV_PPS_GID_NSTS_ZERO val %d ",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005930 set_value);
5931 ret = wma_cli_set_command(pAdapter->sessionId,
5932 WMI_VDEV_PPS_GID_NSTS_ZERO,
5933 set_value, PPS_CMD);
5934 break;
5935 }
5936
5937 case WE_PPS_RSSI_CHECK:
5938 {
Krunal Sonif07bb382016-03-10 13:02:11 -08005939 if (pAdapter->device_mode != QDF_STA_MODE)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005940 return EINVAL;
Jeff Johnson99bac312016-06-28 10:38:18 -07005941 hdd_notice("WMI_VDEV_PPS_RSSI_CHECK val %d ",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005942 set_value);
5943 ret = wma_cli_set_command(pAdapter->sessionId,
5944 WMI_VDEV_PPS_RSSI_CHECK,
5945 set_value, PPS_CMD);
5946 break;
5947 }
5948
5949 case WE_PPS_5G_EBT:
5950 {
Krunal Sonif07bb382016-03-10 13:02:11 -08005951 if (pAdapter->device_mode != QDF_STA_MODE)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005952 return -EINVAL;
5953
Jeff Johnson99bac312016-06-28 10:38:18 -07005954 hdd_notice("WMI_VDEV_PPS_5G_EBT val %d", set_value);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005955 ret = wma_cli_set_command(pAdapter->sessionId,
5956 WMI_VDEV_PPS_5G_EBT,
5957 set_value, PPS_CMD);
5958 break;
5959 }
5960
5961 case WE_SET_HTSMPS:
5962 {
Jeff Johnson99bac312016-06-28 10:38:18 -07005963 hdd_notice("WE_SET_HTSMPS val %d", set_value);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005964 ret = wma_cli_set_command(pAdapter->sessionId,
5965 WMI_STA_SMPS_FORCE_MODE_CMDID,
5966 set_value, VDEV_CMD);
5967 break;
5968 }
5969
5970 case WE_SET_QPOWER_MAX_PSPOLL_COUNT:
5971 {
Jeff Johnson99bac312016-06-28 10:38:18 -07005972 hdd_notice("WE_SET_QPOWER_MAX_PSPOLL_COUNT val %d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005973 set_value);
5974 ret = wma_cli_set_command(pAdapter->sessionId,
5975 WMI_STA_PS_PARAM_QPOWER_PSPOLL_COUNT,
5976 set_value, QPOWER_CMD);
5977 break;
5978 }
5979
5980 case WE_SET_QPOWER_MAX_TX_BEFORE_WAKE:
5981 {
Jeff Johnson99bac312016-06-28 10:38:18 -07005982 hdd_notice("WE_SET_QPOWER_MAX_TX_BEFORE_WAKE val %d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005983 set_value);
5984 ret = wma_cli_set_command(
5985 pAdapter->sessionId,
5986 WMI_STA_PS_PARAM_QPOWER_MAX_TX_BEFORE_WAKE,
5987 set_value, QPOWER_CMD);
5988 break;
5989 }
5990
5991 case WE_SET_QPOWER_SPEC_PSPOLL_WAKE_INTERVAL:
5992 {
Jeff Johnson99bac312016-06-28 10:38:18 -07005993 hdd_notice("WE_SET_QPOWER_SPEC_PSPOLL_WAKE_INTERVAL val %d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005994 set_value);
5995 ret = wma_cli_set_command(
5996 pAdapter->sessionId,
5997 WMI_STA_PS_PARAM_QPOWER_SPEC_PSPOLL_WAKE_INTERVAL,
5998 set_value, QPOWER_CMD);
5999 break;
6000 }
6001
6002 case WE_SET_QPOWER_SPEC_MAX_SPEC_NODATA_PSPOLL:
6003 {
Jeff Johnson99bac312016-06-28 10:38:18 -07006004 hdd_notice("WE_SET_QPOWER_SPEC_MAX_SPEC_NODATA_PSPOLL val %d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006005 set_value);
6006 ret = wma_cli_set_command(
6007 pAdapter->sessionId,
6008 WMI_STA_PS_PARAM_QPOWER_SPEC_MAX_SPEC_NODATA_PSPOLL,
6009 set_value, QPOWER_CMD);
6010 break;
6011 }
6012
6013 case WE_MCC_CONFIG_LATENCY:
6014 {
6015 cds_set_mcc_latency(pAdapter, set_value);
6016 break;
6017 }
6018
6019 case WE_MCC_CONFIG_QUOTA:
6020 {
Jeff Johnson99bac312016-06-28 10:38:18 -07006021 hdd_notice("iwpriv cmd to set MCC quota with val %dms",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006022 set_value);
6023 ret = cds_set_mcc_p2p_quota(pAdapter, set_value);
6024 break;
6025 }
6026 case WE_SET_DEBUG_LOG:
6027 {
6028 hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(pAdapter);
Nirav Shah1da77682016-05-03 20:16:39 +05306029
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006030 hdd_ctx->config->gEnableDebugLog = set_value;
6031 sme_update_connect_debug(hdd_ctx->hHal, set_value);
6032 break;
6033 }
6034 case WE_SET_EARLY_RX_ADJUST_ENABLE:
6035 {
Jeff Johnson99bac312016-06-28 10:38:18 -07006036 hdd_notice("SET early_rx enable val %d", set_value);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006037 if ((set_value == 0) || (set_value == 1))
6038 ret = wma_cli_set_command(
6039 pAdapter->sessionId,
6040 WMI_VDEV_PARAM_EARLY_RX_ADJUST_ENABLE,
6041 set_value, VDEV_CMD);
6042 else
6043 ret = -EINVAL;
6044 break;
6045 }
6046 case WE_SET_EARLY_RX_TGT_BMISS_NUM:
6047 {
Jeff Johnson99bac312016-06-28 10:38:18 -07006048 hdd_notice("SET early_rx bmiss val %d", set_value);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006049 ret = wma_cli_set_command(pAdapter->sessionId,
6050 WMI_VDEV_PARAM_EARLY_RX_TGT_BMISS_NUM,
6051 set_value, VDEV_CMD);
6052 break;
6053 }
6054 case WE_SET_EARLY_RX_BMISS_SAMPLE_CYCLE:
6055 {
Jeff Johnson99bac312016-06-28 10:38:18 -07006056 hdd_notice("SET early_rx bmiss sample cycle %d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006057 set_value);
6058 ret = wma_cli_set_command(
6059 pAdapter->sessionId,
6060 WMI_VDEV_PARAM_EARLY_RX_BMISS_SAMPLE_CYCLE,
6061 set_value, VDEV_CMD);
6062 break;
6063 }
6064 case WE_SET_EARLY_RX_SLOP_STEP:
6065 {
Jeff Johnson99bac312016-06-28 10:38:18 -07006066 hdd_notice("SET early_rx bmiss slop step val %d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006067 set_value);
6068 ret = wma_cli_set_command(pAdapter->sessionId,
6069 WMI_VDEV_PARAM_EARLY_RX_SLOP_STEP,
6070 set_value, VDEV_CMD);
6071 break;
6072 }
6073 case WE_SET_EARLY_RX_INIT_SLOP:
6074 {
Jeff Johnson99bac312016-06-28 10:38:18 -07006075 hdd_notice("SET early_rx init slop step val %d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006076 set_value);
6077 ret = wma_cli_set_command(pAdapter->sessionId,
6078 WMI_VDEV_PARAM_EARLY_RX_INIT_SLOP,
6079 set_value, VDEV_CMD);
6080 break;
6081 }
6082 case WE_SET_EARLY_RX_ADJUST_PAUSE:
6083 {
Jeff Johnson99bac312016-06-28 10:38:18 -07006084 hdd_notice("SET early_rx adjust pause %d", set_value);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006085 if ((set_value == 0) || (set_value == 1))
6086 ret = wma_cli_set_command(
6087 pAdapter->sessionId,
6088 WMI_VDEV_PARAM_EARLY_RX_ADJUST_PAUSE,
6089 set_value, VDEV_CMD);
6090 else
6091 ret = -EINVAL;
6092 break;
6093 }
6094 case WE_SET_EARLY_RX_DRIFT_SAMPLE:
6095 {
Jeff Johnson99bac312016-06-28 10:38:18 -07006096 hdd_notice("SET early_rx drift sample %d", set_value);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006097 ret = wma_cli_set_command(pAdapter->sessionId,
6098 WMI_VDEV_PARAM_EARLY_RX_DRIFT_SAMPLE,
6099 set_value, VDEV_CMD);
6100 break;
6101 }
6102 case WE_SET_SCAN_DISABLE:
6103 {
Jeff Johnson99bac312016-06-28 10:38:18 -07006104 hdd_notice("SET SCAN DISABLE %d", set_value);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006105 sme_set_scan_disable(WLAN_HDD_GET_HAL_CTX(pAdapter), set_value);
6106 break;
6107 }
Govind Singha471e5e2015-10-12 17:11:14 +05306108 case WE_START_FW_PROFILE:
6109 {
Jeff Johnson99bac312016-06-28 10:38:18 -07006110 hdd_notice("WE_START_FW_PROFILE %d", set_value);
Govind Singha471e5e2015-10-12 17:11:14 +05306111 ret = wma_cli_set_command(pAdapter->sessionId,
6112 WMI_WLAN_PROFILE_TRIGGER_CMDID,
6113 set_value, DBG_CMD);
6114 break;
6115 }
Abhishek Singh1bdb1572015-10-16 16:24:19 +05306116 case WE_SET_CHANNEL:
6117 {
Jeff Johnson99bac312016-06-28 10:38:18 -07006118 hdd_notice("Set Channel %d Session ID %d mode %d", set_value,
Abhishek Singh1bdb1572015-10-16 16:24:19 +05306119 pAdapter->sessionId, pAdapter->device_mode);
6120
Krunal Sonif07bb382016-03-10 13:02:11 -08006121 if ((QDF_STA_MODE == pAdapter->device_mode) ||
6122 (QDF_P2P_CLIENT_MODE == pAdapter->device_mode)) {
Abhishek Singh1bdb1572015-10-16 16:24:19 +05306123
6124 status = sme_ext_change_channel(hHal,
6125 set_value, pAdapter->sessionId);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05306126 if (status != QDF_STATUS_SUCCESS) {
Jeff Johnson99bac312016-06-28 10:38:18 -07006127 hdd_err("Error in change channel status %d",
Abhishek Singh1bdb1572015-10-16 16:24:19 +05306128 status);
6129 ret = -EINVAL;
6130 }
6131 } else {
Jeff Johnson99bac312016-06-28 10:38:18 -07006132 hdd_err("change channel not supported for device mode %d",
Abhishek Singh1bdb1572015-10-16 16:24:19 +05306133 pAdapter->device_mode);
6134 ret = -EINVAL;
6135 }
6136 break;
6137 }
Manishekar Chandrasekaran97e077d2016-03-23 17:10:31 +05306138 case WE_SET_CONC_SYSTEM_PREF:
6139 {
6140 hdd_info("New preference: %d", set_value);
6141 if (!((set_value >= CFG_CONC_SYSTEM_PREF_MIN) &&
6142 (set_value <= CFG_CONC_SYSTEM_PREF_MAX))) {
6143 hdd_err("Invalid system preference %d", set_value);
6144 return -EINVAL;
6145 }
Abhishek Singh1bdb1572015-10-16 16:24:19 +05306146
Manishekar Chandrasekaran97e077d2016-03-23 17:10:31 +05306147 /* hdd_ctx, hdd_ctx->config are already checked for null */
6148 hdd_ctx->config->conc_system_pref = set_value;
6149 break;
6150 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006151 default:
6152 {
Jeff Johnson99bac312016-06-28 10:38:18 -07006153 hdd_err("Invalid sub command %d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006154 sub_cmd);
6155 ret = -EINVAL;
6156 break;
6157 }
6158 }
Hanumantha Reddy Pothula2db50ed2015-11-23 10:48:33 +05306159 EXIT();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006160 return ret;
6161}
6162
6163static int iw_setint_getnone(struct net_device *dev,
6164 struct iw_request_info *info,
6165 union iwreq_data *wrqu,
6166 char *extra)
6167{
6168 int ret;
6169
6170 cds_ssr_protect(__func__);
6171 ret = __iw_setint_getnone(dev, info, wrqu, extra);
6172 cds_ssr_unprotect(__func__);
6173
6174 return ret;
6175}
6176
6177/**
Manikandan Mohandcc21ba2016-03-15 14:31:56 -07006178 * __iw_setnone_get_threeint() - return three value to up layer.
6179 *
6180 * @dev: pointer of net_device of this wireless card
6181 * @info: meta data about Request sent
6182 * @wrqu: include request info
6183 * @extra: buf used for in/Output
6184 *
6185 * Return: execute result
6186 */
6187static int __iw_setnone_get_threeint(struct net_device *dev,
6188 struct iw_request_info *info,
6189 union iwreq_data *wrqu, char *extra)
6190{
6191 int ret = 0; /* success */
6192 uint32_t *value = (int *)extra;
6193 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
6194 hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
6195
6196 ENTER_DEV(dev);
6197 ret = wlan_hdd_validate_context(hdd_ctx);
6198 if (0 != ret)
6199 return ret;
6200
Jeff Johnson99bac312016-06-28 10:38:18 -07006201 hdd_info("param = %d", value[0]);
Manikandan Mohandcc21ba2016-03-15 14:31:56 -07006202 switch (value[0]) {
6203 case WE_GET_TSF:
6204 ret = hdd_indicate_tsf(adapter, value, 3);
6205 break;
6206 default:
6207 hdd_err("Invalid IOCTL get_value command %d", value[0]);
6208 break;
6209 }
6210 return ret;
6211}
6212
6213/**
6214 * iw_setnone_get_threeint() - return three value to up layer.
6215 *
6216 * @dev: pointer of net_device of this wireless card
6217 * @info: meta data about Request sent
6218 * @wrqu: include request info
6219 * @extra: buf used for in/Output
6220 *
6221 * Return: execute result
6222 */
6223static int iw_setnone_get_threeint(struct net_device *dev,
6224 struct iw_request_info *info,
6225 union iwreq_data *wrqu, char *extra)
6226{
6227 int ret;
6228
6229 cds_ssr_protect(__func__);
6230 ret = __iw_setnone_get_threeint(dev, info, wrqu, extra);
6231 cds_ssr_unprotect(__func__);
6232
6233 return ret;
6234}
6235
6236/**
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006237 * iw_setchar_getnone() - Generic "set string" private ioctl handler
6238 * @dev: device upon which the ioctl was received
6239 * @info: ioctl request information
6240 * @wrqu: ioctl request data
6241 * @extra: ioctl extra data
6242 *
6243 * Return: 0 on success, non-zero on error
6244 */
6245static int __iw_setchar_getnone(struct net_device *dev,
6246 struct iw_request_info *info,
6247 union iwreq_data *wrqu, char *extra)
6248{
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05306249 QDF_STATUS vstatus;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006250 int sub_cmd;
6251 int ret;
6252 char *pBuffer = NULL;
6253 hdd_adapter_t *pAdapter = (netdev_priv(dev));
6254 hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(pAdapter);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006255 struct hdd_config *pConfig = hdd_ctx->config;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006256 struct iw_point s_priv_data;
6257
Jeff Johnson6ee91ee2016-02-11 18:55:30 -08006258 ENTER_DEV(dev);
6259
Mukul Sharma34777c62015-11-02 20:22:30 +05306260 if (!capable(CAP_NET_ADMIN)) {
Jeff Johnson99bac312016-06-28 10:38:18 -07006261 hdd_err("permission check failed");
Mukul Sharma34777c62015-11-02 20:22:30 +05306262 return -EPERM;
6263 }
6264
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006265 ret = wlan_hdd_validate_context(hdd_ctx);
6266 if (0 != ret)
6267 return ret;
6268
6269 /* helper function to get iwreq_data with compat handling. */
6270 if (hdd_priv_get_data(&s_priv_data, wrqu)) {
6271 return -EINVAL;
6272 }
6273
6274 /* make sure all params are correctly passed to function */
6275 if ((NULL == s_priv_data.pointer) || (0 == s_priv_data.length)) {
6276 return -EINVAL;
6277 }
6278
6279 sub_cmd = s_priv_data.flags;
6280
6281 /* ODD number is used for set, copy data using copy_from_user */
6282 pBuffer = mem_alloc_copy_from_user_helper(s_priv_data.pointer,
6283 s_priv_data.length);
6284 if (NULL == pBuffer) {
Jeff Johnson99bac312016-06-28 10:38:18 -07006285 hdd_err("mem_alloc_copy_from_user_helper fail");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006286 return -ENOMEM;
6287 }
6288
Jeff Johnson99bac312016-06-28 10:38:18 -07006289 hdd_notice("Received length %d", s_priv_data.length);
6290 hdd_notice("Received data %s", pBuffer);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006291
6292 switch (sub_cmd) {
6293 case WE_WOWL_ADD_PTRN:
Jeff Johnson99bac312016-06-28 10:38:18 -07006294 hdd_notice("ADD_PTRN");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006295 hdd_add_wowl_ptrn(pAdapter, pBuffer);
6296 break;
6297 case WE_WOWL_DEL_PTRN:
Jeff Johnson99bac312016-06-28 10:38:18 -07006298 hdd_notice("DEL_PTRN");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006299 hdd_del_wowl_ptrn(pAdapter, pBuffer);
6300 break;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006301 case WE_NEIGHBOR_REPORT_REQUEST:
6302 {
6303 tRrmNeighborReq neighborReq;
6304 tRrmNeighborRspCallbackInfo callbackInfo;
6305
6306 if (pConfig->fRrmEnable) {
Jeff Johnson99bac312016-06-28 10:38:18 -07006307 hdd_notice("Neighbor Request");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006308 neighborReq.no_ssid =
6309 (s_priv_data.length - 1) ? false : true;
6310 if (!neighborReq.no_ssid) {
6311 neighborReq.ssid.length =
6312 (s_priv_data.length - 1) >
6313 32 ? 32 : (s_priv_data.length - 1);
Anurag Chouhan600c3a02016-03-01 10:33:54 +05306314 qdf_mem_copy(neighborReq.ssid.ssId,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006315 pBuffer,
6316 neighborReq.ssid.length);
6317 }
6318
6319 callbackInfo.neighborRspCallback = NULL;
6320 callbackInfo.neighborRspCallbackContext = NULL;
6321 callbackInfo.timeout = 5000; /* 5 seconds */
6322 sme_neighbor_report_request(WLAN_HDD_GET_HAL_CTX
6323 (pAdapter),
6324 pAdapter->sessionId,
6325 &neighborReq,
6326 &callbackInfo);
6327 } else {
Jeff Johnson99bac312016-06-28 10:38:18 -07006328 hdd_err("Ignoring neighbor request as RRM is not enabled");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006329 ret = -EINVAL;
6330 }
6331 }
6332 break;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006333 case WE_SET_AP_WPS_IE:
Jeff Johnson99bac312016-06-28 10:38:18 -07006334 hdd_err("Received WE_SET_AP_WPS_IE");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006335 sme_update_p2p_ie(WLAN_HDD_GET_HAL_CTX(pAdapter), pBuffer,
6336 s_priv_data.length);
6337 break;
6338 case WE_SET_CONFIG:
6339 vstatus = hdd_execute_global_config_command(hdd_ctx, pBuffer);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05306340 if (QDF_STATUS_SUCCESS != vstatus) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006341 ret = -EINVAL;
6342 }
6343 break;
6344 default:
6345 {
Jeff Johnson99bac312016-06-28 10:38:18 -07006346 hdd_err("Invalid sub command %d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006347 sub_cmd);
6348 ret = -EINVAL;
6349 break;
6350 }
6351 }
6352 kfree(pBuffer);
Hanumantha Reddy Pothula2db50ed2015-11-23 10:48:33 +05306353 EXIT();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006354 return ret;
6355}
6356
6357static int iw_setchar_getnone(struct net_device *dev,
6358 struct iw_request_info *info,
6359 union iwreq_data *wrqu, char *extra)
6360{
6361 int ret;
6362
6363 cds_ssr_protect(__func__);
6364 ret = __iw_setchar_getnone(dev, info, wrqu, extra);
6365 cds_ssr_unprotect(__func__);
6366
6367 return ret;
6368}
6369
6370/**
6371 * iw_setnone_getint() - Generic "get integer" private ioctl handler
6372 * @dev: device upon which the ioctl was received
6373 * @info: ioctl request information
6374 * @wrqu: ioctl request data
6375 * @extra: ioctl extra data
6376 *
6377 * Return: 0 on success, non-zero on error
6378 */
6379static int __iw_setnone_getint(struct net_device *dev,
6380 struct iw_request_info *info,
6381 union iwreq_data *wrqu, char *extra)
6382{
6383 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6384 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
6385 int *value = (int *)extra;
6386 int ret;
6387 tSmeConfigParams smeConfig;
6388 hdd_context_t *hdd_ctx;
6389
Jeff Johnson6ee91ee2016-02-11 18:55:30 -08006390 ENTER_DEV(dev);
Hanumantha Reddy Pothula2db50ed2015-11-23 10:48:33 +05306391
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006392 hdd_ctx = WLAN_HDD_GET_CTX(pAdapter);
6393 ret = wlan_hdd_validate_context(hdd_ctx);
6394 if (0 != ret)
6395 return ret;
6396
6397 switch (value[0]) {
6398 case WE_GET_11D_STATE:
6399 {
6400 sme_get_config_param(hHal, &smeConfig);
6401
6402 *value = smeConfig.csrConfig.Is11dSupportEnabled;
6403
Jeff Johnson99bac312016-06-28 10:38:18 -07006404 hdd_notice("11D state=%d!!", *value);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006405
6406 break;
6407 }
6408
6409 case WE_IBSS_STATUS:
Jeff Johnson99bac312016-06-28 10:38:18 -07006410 hdd_notice("****Return IBSS Status*****");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006411 break;
6412
6413 case WE_GET_WLAN_DBG:
6414 {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05306415 qdf_trace_display();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006416 *value = 0;
6417 break;
6418 }
6419 case WE_GET_MAX_ASSOC:
6420 {
6421 if (sme_cfg_get_int
6422 (hHal, WNI_CFG_ASSOC_STA_LIMIT,
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05306423 (uint32_t *) value) != QDF_STATUS_SUCCESS) {
Jeff Johnson99bac312016-06-28 10:38:18 -07006424 hdd_warn("failed to get ini parameter, WNI_CFG_ASSOC_STA_LIMIT");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006425 ret = -EIO;
6426 }
6427 break;
6428 }
6429 case WE_GET_SAP_AUTO_CHANNEL_SELECTION:
6430 *value = (WLAN_HDD_GET_CTX(
6431 pAdapter))->config->force_sap_acs;
6432 break;
6433
6434 case WE_GET_CONCURRENCY_MODE:
6435 {
6436 *value = cds_get_concurrency_mode();
6437
Jeff Johnson99bac312016-06-28 10:38:18 -07006438 hdd_notice("concurrency mode=%d", *value);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006439 break;
6440 }
6441
6442 case WE_GET_NSS:
6443 {
6444 sme_get_config_param(hHal, &smeConfig);
6445 *value = (smeConfig.csrConfig.enable2x2 == 0) ? 1 : 2;
Jeff Johnson99bac312016-06-28 10:38:18 -07006446 hdd_notice("GET_NSS: Current NSS:%d", *value);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006447 break;
6448 }
6449
6450 case WE_GET_GTX_HT_MCS:
6451 {
Jeff Johnson99bac312016-06-28 10:38:18 -07006452 hdd_notice("GET WMI_VDEV_PARAM_GTX_HT_MCS");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006453 *value = wma_cli_get_command(pAdapter->sessionId,
6454 WMI_VDEV_PARAM_GTX_HT_MCS,
6455 GTX_CMD);
6456 break;
6457 }
6458
6459 case WE_GET_GTX_VHT_MCS:
6460 {
Jeff Johnson99bac312016-06-28 10:38:18 -07006461 hdd_notice("GET WMI_VDEV_PARAM_GTX_VHT_MCS");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006462 *value = wma_cli_get_command(pAdapter->sessionId,
6463 WMI_VDEV_PARAM_GTX_VHT_MCS,
6464 GTX_CMD);
6465 break;
6466 }
6467
6468 case WE_GET_GTX_USRCFG:
6469 {
Jeff Johnson99bac312016-06-28 10:38:18 -07006470 hdd_notice("GET WMI_VDEV_PARAM_GTX_USR_CFG");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006471 *value = wma_cli_get_command(pAdapter->sessionId,
6472 WMI_VDEV_PARAM_GTX_USR_CFG,
6473 GTX_CMD);
6474 break;
6475 }
6476
6477 case WE_GET_GTX_THRE:
6478 {
Jeff Johnson99bac312016-06-28 10:38:18 -07006479 hdd_notice("GET WMI_VDEV_PARAM_GTX_THRE");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006480 *value = wma_cli_get_command(pAdapter->sessionId,
6481 WMI_VDEV_PARAM_GTX_THRE,
6482 GTX_CMD);
6483 break;
6484 }
6485
6486 case WE_GET_GTX_MARGIN:
6487 {
Jeff Johnson99bac312016-06-28 10:38:18 -07006488 hdd_notice("GET WMI_VDEV_PARAM_GTX_MARGIN");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006489 *value = wma_cli_get_command(pAdapter->sessionId,
6490 WMI_VDEV_PARAM_GTX_MARGIN,
6491 GTX_CMD);
6492 break;
6493 }
6494
6495 case WE_GET_GTX_STEP:
6496 {
Jeff Johnson99bac312016-06-28 10:38:18 -07006497 hdd_notice("GET WMI_VDEV_PARAM_GTX_STEP");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006498 *value = wma_cli_get_command(pAdapter->sessionId,
6499 WMI_VDEV_PARAM_GTX_STEP,
6500 GTX_CMD);
6501 break;
6502 }
6503
6504 case WE_GET_GTX_MINTPC:
6505 {
Jeff Johnson99bac312016-06-28 10:38:18 -07006506 hdd_notice("GET WMI_VDEV_PARAM_GTX_MINTPC");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006507 *value = wma_cli_get_command(pAdapter->sessionId,
6508 WMI_VDEV_PARAM_GTX_MINTPC,
6509 GTX_CMD);
6510 break;
6511 }
6512
6513 case WE_GET_GTX_BWMASK:
6514 {
Jeff Johnson99bac312016-06-28 10:38:18 -07006515 hdd_notice("GET WMI_VDEV_PARAM_GTX_BW_MASK");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006516 *value = wma_cli_get_command(pAdapter->sessionId,
6517 WMI_VDEV_PARAM_GTX_BW_MASK,
6518 GTX_CMD);
6519 break;
6520 }
6521
6522 case WE_GET_LDPC:
6523 {
Jeff Johnson99bac312016-06-28 10:38:18 -07006524 hdd_notice("GET WMI_VDEV_PARAM_LDPC");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006525 *value = sme_get_ht_config(hHal, pAdapter->sessionId,
6526 WNI_CFG_HT_CAP_INFO_ADVANCE_CODING);
6527 break;
6528 }
6529
6530 case WE_GET_TX_STBC:
6531 {
Jeff Johnson99bac312016-06-28 10:38:18 -07006532 hdd_notice("GET WMI_VDEV_PARAM_TX_STBC");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006533 *value = sme_get_ht_config(hHal, pAdapter->sessionId,
6534 WNI_CFG_HT_CAP_INFO_TX_STBC);
6535 break;
6536 }
6537
6538 case WE_GET_RX_STBC:
6539 {
Jeff Johnson99bac312016-06-28 10:38:18 -07006540 hdd_notice("GET WMI_VDEV_PARAM_RX_STBC");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006541 *value = sme_get_ht_config(hHal, pAdapter->sessionId,
6542 WNI_CFG_HT_CAP_INFO_RX_STBC);
6543 break;
6544 }
6545
6546 case WE_GET_SHORT_GI:
6547 {
Jeff Johnson99bac312016-06-28 10:38:18 -07006548 hdd_notice("GET WMI_VDEV_PARAM_SGI");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006549 *value = sme_get_ht_config(hHal, pAdapter->sessionId,
6550 WNI_CFG_HT_CAP_INFO_SHORT_GI_20MHZ);
6551 break;
6552 }
6553
6554 case WE_GET_RTSCTS:
6555 {
Jeff Johnson99bac312016-06-28 10:38:18 -07006556 hdd_notice("GET WMI_VDEV_PARAM_ENABLE_RTSCTS");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006557 *value = wma_cli_get_command(pAdapter->sessionId,
6558 WMI_VDEV_PARAM_ENABLE_RTSCTS,
6559 VDEV_CMD);
6560 break;
6561 }
6562
6563 case WE_GET_CHWIDTH:
6564 {
Jeff Johnson99bac312016-06-28 10:38:18 -07006565 hdd_notice("GET WMI_VDEV_PARAM_CHWIDTH");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006566 *value = wma_cli_get_command(pAdapter->sessionId,
6567 WMI_VDEV_PARAM_CHWIDTH,
6568 VDEV_CMD);
6569 break;
6570 }
6571
6572 case WE_GET_ANI_EN_DIS:
6573 {
Jeff Johnson99bac312016-06-28 10:38:18 -07006574 hdd_notice("GET WMI_PDEV_PARAM_ANI_ENABLE");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006575 *value = wma_cli_get_command(pAdapter->sessionId,
6576 WMI_PDEV_PARAM_ANI_ENABLE,
6577 PDEV_CMD);
6578 break;
6579 }
6580
6581 case WE_GET_ANI_POLL_PERIOD:
6582 {
Jeff Johnson99bac312016-06-28 10:38:18 -07006583 hdd_notice("GET WMI_PDEV_PARAM_ANI_POLL_PERIOD");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006584 *value = wma_cli_get_command(pAdapter->sessionId,
6585 WMI_PDEV_PARAM_ANI_POLL_PERIOD,
6586 PDEV_CMD);
6587 break;
6588 }
6589
6590 case WE_GET_ANI_LISTEN_PERIOD:
6591 {
Jeff Johnson99bac312016-06-28 10:38:18 -07006592 hdd_notice("GET WMI_PDEV_PARAM_ANI_LISTEN_PERIOD");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006593 *value = wma_cli_get_command(pAdapter->sessionId,
6594 WMI_PDEV_PARAM_ANI_LISTEN_PERIOD,
6595 PDEV_CMD);
6596 break;
6597 }
6598
6599 case WE_GET_ANI_OFDM_LEVEL:
6600 {
Jeff Johnson99bac312016-06-28 10:38:18 -07006601 hdd_notice("GET WMI_PDEV_PARAM_ANI_OFDM_LEVEL");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006602 *value = wma_cli_get_command(pAdapter->sessionId,
6603 WMI_PDEV_PARAM_ANI_OFDM_LEVEL,
6604 PDEV_CMD);
6605 break;
6606 }
6607
6608 case WE_GET_ANI_CCK_LEVEL:
6609 {
Jeff Johnson99bac312016-06-28 10:38:18 -07006610 hdd_notice("GET WMI_PDEV_PARAM_ANI_CCK_LEVEL");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006611 *value = wma_cli_get_command(pAdapter->sessionId,
6612 WMI_PDEV_PARAM_ANI_CCK_LEVEL,
6613 PDEV_CMD);
6614 break;
6615 }
6616
6617 case WE_GET_DYNAMIC_BW:
6618 {
Jeff Johnson99bac312016-06-28 10:38:18 -07006619 hdd_notice("GET WMI_PDEV_PARAM_ANI_CCK_LEVEL");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006620 *value = wma_cli_get_command(pAdapter->sessionId,
6621 WMI_PDEV_PARAM_DYNAMIC_BW,
6622 PDEV_CMD);
6623 break;
6624 }
6625
6626 case WE_GET_11N_RATE:
6627 {
Jeff Johnson99bac312016-06-28 10:38:18 -07006628 hdd_notice("GET WMI_VDEV_PARAM_FIXED_RATE");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006629 *value = wma_cli_get_command(pAdapter->sessionId,
6630 WMI_VDEV_PARAM_FIXED_RATE,
6631 VDEV_CMD);
6632 break;
6633 }
6634
6635 case WE_GET_AMPDU:
6636 {
Jeff Johnson99bac312016-06-28 10:38:18 -07006637 hdd_notice("GET AMPDU");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006638 *value = wma_cli_get_command(pAdapter->sessionId,
6639 GEN_VDEV_PARAM_AMPDU,
6640 GEN_CMD);
6641 break;
6642 }
6643
6644 case WE_GET_AMSDU:
6645 {
Jeff Johnson99bac312016-06-28 10:38:18 -07006646 hdd_notice("GET AMSDU");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006647 *value = wma_cli_get_command(pAdapter->sessionId,
6648 GEN_VDEV_PARAM_AMSDU,
6649 GEN_CMD);
6650 break;
6651 }
6652
Varun Reddy Yeturu5ab47462016-05-08 18:08:11 -07006653 case WE_GET_ROAM_SYNCH_DELAY:
6654 {
Jeff Johnson99bac312016-06-28 10:38:18 -07006655 hdd_notice("GET ROAM SYNCH DELAY");
Varun Reddy Yeturu5ab47462016-05-08 18:08:11 -07006656 *value = wma_cli_get_command(pAdapter->sessionId,
6657 GEN_VDEV_ROAM_SYNCH_DELAY,
6658 GEN_CMD);
6659 break;
6660 }
6661
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006662 case WE_GET_BURST_ENABLE:
6663 {
Jeff Johnson99bac312016-06-28 10:38:18 -07006664 hdd_notice("GET Burst enable value");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006665 *value = wma_cli_get_command(pAdapter->sessionId,
6666 WMI_PDEV_PARAM_BURST_ENABLE,
6667 PDEV_CMD);
6668 break;
6669 }
6670 case WE_GET_BURST_DUR:
6671 {
Jeff Johnson99bac312016-06-28 10:38:18 -07006672 hdd_notice("GET Burst Duration value");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006673 *value = wma_cli_get_command(pAdapter->sessionId,
6674 WMI_PDEV_PARAM_BURST_DUR,
6675 PDEV_CMD);
6676 break;
6677 }
6678
6679 case WE_GET_TX_CHAINMASK:
6680 {
Jeff Johnson99bac312016-06-28 10:38:18 -07006681 hdd_notice("GET WMI_PDEV_PARAM_TX_CHAIN_MASK");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006682 *value = wma_cli_get_command(pAdapter->sessionId,
6683 WMI_PDEV_PARAM_TX_CHAIN_MASK,
6684 PDEV_CMD);
6685 break;
6686 }
6687
6688 case WE_GET_RX_CHAINMASK:
6689 {
Jeff Johnson99bac312016-06-28 10:38:18 -07006690 hdd_notice("GET WMI_PDEV_PARAM_RX_CHAIN_MASK");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006691 *value = wma_cli_get_command(pAdapter->sessionId,
6692 WMI_PDEV_PARAM_RX_CHAIN_MASK,
6693 PDEV_CMD);
6694 break;
6695 }
6696
6697 case WE_GET_TXPOW_2G:
6698 {
6699 uint32_t txpow2g = 0;
6700 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Jeff Johnson99bac312016-06-28 10:38:18 -07006701 hdd_notice("GET WMI_PDEV_PARAM_TXPOWER_LIMIT2G");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006702 *value = wma_cli_get_command(pAdapter->sessionId,
6703 WMI_PDEV_PARAM_TXPOWER_LIMIT2G,
6704 PDEV_CMD);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05306705 if (QDF_STATUS_SUCCESS !=
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006706 sme_cfg_get_int(hHal, WNI_CFG_CURRENT_TX_POWER_LEVEL,
6707 &txpow2g)) {
6708 return -EIO;
6709 }
Jeff Johnson99bac312016-06-28 10:38:18 -07006710 hdd_notice("2G tx_power %d", txpow2g);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006711 break;
6712 }
6713
6714 case WE_GET_TXPOW_5G:
6715 {
6716 uint32_t txpow5g = 0;
6717 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Jeff Johnson99bac312016-06-28 10:38:18 -07006718 hdd_notice("GET WMI_PDEV_PARAM_TXPOWER_LIMIT5G");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006719 *value = wma_cli_get_command(pAdapter->sessionId,
6720 WMI_PDEV_PARAM_TXPOWER_LIMIT5G,
6721 PDEV_CMD);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05306722 if (QDF_STATUS_SUCCESS !=
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006723 sme_cfg_get_int(hHal, WNI_CFG_CURRENT_TX_POWER_LEVEL,
6724 &txpow5g)) {
6725 return -EIO;
6726 }
Jeff Johnson99bac312016-06-28 10:38:18 -07006727 hdd_notice("5G tx_power %d", txpow5g);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006728 break;
6729 }
6730
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006731 case WE_GET_PPS_PAID_MATCH:
6732 {
Jeff Johnson99bac312016-06-28 10:38:18 -07006733 hdd_notice("GET WMI_VDEV_PPS_PAID_MATCH");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006734 *value = wma_cli_get_command(pAdapter->sessionId,
6735 WMI_VDEV_PPS_PAID_MATCH,
6736 PPS_CMD);
6737 break;
6738 }
6739
6740 case WE_GET_PPS_GID_MATCH:
6741 {
Jeff Johnson99bac312016-06-28 10:38:18 -07006742 hdd_notice("GET WMI_VDEV_PPS_GID_MATCH");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006743 *value = wma_cli_get_command(pAdapter->sessionId,
6744 WMI_VDEV_PPS_GID_MATCH,
6745 PPS_CMD);
6746 break;
6747 }
6748
6749 case WE_GET_PPS_EARLY_TIM_CLEAR:
6750 {
Jeff Johnson99bac312016-06-28 10:38:18 -07006751 hdd_notice("GET WMI_VDEV_PPS_EARLY_TIM_CLEAR");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006752 *value = wma_cli_get_command(pAdapter->sessionId,
6753 WMI_VDEV_PPS_EARLY_TIM_CLEAR,
6754 PPS_CMD);
6755 break;
6756 }
6757
6758 case WE_GET_PPS_EARLY_DTIM_CLEAR:
6759 {
Jeff Johnson99bac312016-06-28 10:38:18 -07006760 hdd_notice("GET WMI_VDEV_PPS_EARLY_DTIM_CLEAR");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006761 *value = wma_cli_get_command(pAdapter->sessionId,
6762 WMI_VDEV_PPS_EARLY_DTIM_CLEAR,
6763 PPS_CMD);
6764 break;
6765 }
6766
6767 case WE_GET_PPS_EOF_PAD_DELIM:
6768 {
Jeff Johnson99bac312016-06-28 10:38:18 -07006769 hdd_notice("GET WMI_VDEV_PPS_EOF_PAD_DELIM");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006770 *value = wma_cli_get_command(pAdapter->sessionId,
6771 WMI_VDEV_PPS_EOF_PAD_DELIM,
6772 PPS_CMD);
6773 break;
6774 }
6775
6776 case WE_GET_PPS_MACADDR_MISMATCH:
6777 {
Jeff Johnson99bac312016-06-28 10:38:18 -07006778 hdd_notice("GET WMI_VDEV_PPS_MACADDR_MISMATCH");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006779 *value = wma_cli_get_command(pAdapter->sessionId,
6780 WMI_VDEV_PPS_MACADDR_MISMATCH,
6781 PPS_CMD);
6782 break;
6783 }
6784
6785 case WE_GET_PPS_DELIM_CRC_FAIL:
6786 {
Jeff Johnson99bac312016-06-28 10:38:18 -07006787 hdd_notice("GET WMI_VDEV_PPS_DELIM_CRC_FAIL");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006788 *value = wma_cli_get_command(pAdapter->sessionId,
6789 WMI_VDEV_PPS_DELIM_CRC_FAIL,
6790 PPS_CMD);
6791 break;
6792 }
6793
6794 case WE_GET_PPS_GID_NSTS_ZERO:
6795 {
Jeff Johnson99bac312016-06-28 10:38:18 -07006796 hdd_notice("GET WMI_VDEV_PPS_GID_NSTS_ZERO");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006797 *value = wma_cli_get_command(pAdapter->sessionId,
6798 WMI_VDEV_PPS_GID_NSTS_ZERO,
6799 PPS_CMD);
6800 break;
6801 }
6802
6803 case WE_GET_PPS_RSSI_CHECK:
6804 {
6805
Jeff Johnson99bac312016-06-28 10:38:18 -07006806 hdd_notice("GET WMI_VDEV_PPS_RSSI_CHECK");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006807 *value = wma_cli_get_command(pAdapter->sessionId,
6808 WMI_VDEV_PPS_RSSI_CHECK,
6809 PPS_CMD);
6810 break;
6811 }
6812
6813 case WE_GET_QPOWER_MAX_PSPOLL_COUNT:
6814 {
Jeff Johnson99bac312016-06-28 10:38:18 -07006815 hdd_notice("WE_GET_QPOWER_MAX_PSPOLL_COUNT");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006816 *value = wma_cli_get_command(pAdapter->sessionId,
6817 WMI_STA_PS_PARAM_QPOWER_PSPOLL_COUNT,
6818 QPOWER_CMD);
6819 break;
6820 }
6821
6822 case WE_GET_QPOWER_MAX_TX_BEFORE_WAKE:
6823 {
Jeff Johnson99bac312016-06-28 10:38:18 -07006824 hdd_notice("WE_GET_QPOWER_MAX_TX_BEFORE_WAKE");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006825 *value = wma_cli_get_command(pAdapter->sessionId,
6826 WMI_STA_PS_PARAM_QPOWER_MAX_TX_BEFORE_WAKE,
6827 QPOWER_CMD);
6828 break;
6829 }
6830
6831 case WE_GET_QPOWER_SPEC_PSPOLL_WAKE_INTERVAL:
6832 {
Jeff Johnson99bac312016-06-28 10:38:18 -07006833 hdd_notice("WE_GET_QPOWER_SPEC_PSPOLL_WAKE_INTERVAL");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006834 *value = wma_cli_get_command(pAdapter->sessionId,
6835 WMI_STA_PS_PARAM_QPOWER_SPEC_PSPOLL_WAKE_INTERVAL,
6836 QPOWER_CMD);
6837 break;
6838 }
6839
6840 case WE_GET_QPOWER_SPEC_MAX_SPEC_NODATA_PSPOLL:
6841 {
Jeff Johnson99bac312016-06-28 10:38:18 -07006842 hdd_notice("WE_GET_QPOWER_MAX_PSPOLL_COUNT");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006843 *value = wma_cli_get_command(pAdapter->sessionId,
6844 WMI_STA_PS_PARAM_QPOWER_SPEC_MAX_SPEC_NODATA_PSPOLL,
6845 QPOWER_CMD);
6846 break;
6847 }
Manikandan Mohandcc21ba2016-03-15 14:31:56 -07006848 case WE_CAP_TSF:
6849 ret = hdd_capture_tsf(pAdapter, (uint32_t *)value, 1);
6850 break;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006851 case WE_GET_TEMPERATURE:
6852 {
Jeff Johnson99bac312016-06-28 10:38:18 -07006853 hdd_notice("WE_GET_TEMPERATURE");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006854 ret = wlan_hdd_get_temperature(pAdapter, value);
6855 break;
6856 }
6857 default:
6858 {
Jeff Johnson99bac312016-06-28 10:38:18 -07006859 hdd_err("Invalid IOCTL get_value command %d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006860 value[0]);
6861 break;
6862 }
6863 }
Hanumantha Reddy Pothula2db50ed2015-11-23 10:48:33 +05306864 EXIT();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006865 return ret;
6866}
6867
6868static int iw_setnone_getint(struct net_device *dev,
6869 struct iw_request_info *info,
6870 union iwreq_data *wrqu, char *extra)
6871{
6872 int ret;
6873
6874 cds_ssr_protect(__func__);
6875 ret = __iw_setnone_getint(dev, info, wrqu, extra);
6876 cds_ssr_unprotect(__func__);
6877
6878 return ret;
6879}
6880
6881/**
6882 * iw_set_three_ints_getnone() - Generic "set 3 params" private ioctl handler
6883 * @dev: device upon which the ioctl was received
6884 * @info: ioctl request information
6885 * @wrqu: ioctl request data
6886 * @extra: ioctl extra data
6887 *
6888 * Return: 0 on success, non-zero on error
6889 */
6890static int __iw_set_three_ints_getnone(struct net_device *dev,
6891 struct iw_request_info *info,
6892 union iwreq_data *wrqu, char *extra)
6893{
6894 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6895 int *value = (int *)extra;
6896 int sub_cmd = value[0];
6897 int ret;
6898 hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(pAdapter);
6899
Jeff Johnson6ee91ee2016-02-11 18:55:30 -08006900 ENTER_DEV(dev);
Hanumantha Reddy Pothula2db50ed2015-11-23 10:48:33 +05306901
Rajeev Kumar2cce8a82016-04-14 15:10:41 -07006902 if (!capable(CAP_NET_ADMIN)) {
Jeff Johnson99bac312016-06-28 10:38:18 -07006903 hdd_err("permission check failed");
Rajeev Kumar2cce8a82016-04-14 15:10:41 -07006904 return -EPERM;
6905 }
6906
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006907 ret = wlan_hdd_validate_context(hdd_ctx);
6908 if (0 != ret)
6909 return ret;
6910
6911 switch (sub_cmd) {
6912
6913 case WE_SET_WLAN_DBG:
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05306914 qdf_trace_set_value(value[1], value[2], value[3]);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006915 break;
6916 case WE_SET_DP_TRACE:
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05306917 qdf_dp_trace_set_value(value[1], value[2], value[3]);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006918 break;
6919
6920 /* value[3] the acs band is not required as start and end channels are
6921 * enough but this cmd is maintained under set three ints for historic
6922 * reasons.
6923 */
6924 case WE_SET_SAP_CHANNELS:
6925 if (wlan_hdd_validate_operation_channel(pAdapter, value[1]) !=
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05306926 QDF_STATUS_SUCCESS ||
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006927 wlan_hdd_validate_operation_channel(pAdapter,
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05306928 value[2]) != QDF_STATUS_SUCCESS) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006929 ret = -EINVAL;
6930 } else {
6931 hdd_ctx->config->force_sap_acs_st_ch = value[1];
6932 hdd_ctx->config->force_sap_acs_end_ch = value[2];
6933 }
6934 break;
6935 case WE_SET_DUAL_MAC_SCAN_CONFIG:
6936 hdd_debug("Ioctl to set dual mac scan config");
6937 if (hdd_ctx->config->dual_mac_feature_disable) {
6938 hdd_err("Dual mac feature is disabled from INI");
6939 return -EPERM;
6940 }
6941 hdd_debug("%d %d %d", value[1], value[2], value[3]);
Tushnim Bhattacharyya4adb3682016-01-07 15:07:12 -08006942 cds_set_dual_mac_scan_config(value[1], value[2], value[3]);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006943 break;
6944 default:
Jeff Johnson99bac312016-06-28 10:38:18 -07006945 hdd_err("Invalid IOCTL command %d", sub_cmd);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006946 break;
6947
6948 }
Hanumantha Reddy Pothula2db50ed2015-11-23 10:48:33 +05306949 EXIT();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006950 return ret;
6951}
6952
6953int iw_set_three_ints_getnone(struct net_device *dev,
6954 struct iw_request_info *info,
6955 union iwreq_data *wrqu, char *extra)
6956{
6957 int ret;
6958
6959 cds_ssr_protect(__func__);
6960 ret = __iw_set_three_ints_getnone(dev, info, wrqu, extra);
6961 cds_ssr_unprotect(__func__);
6962
6963 return ret;
6964}
6965
6966/**
6967 * hdd_connection_state_string() - Get connection state string
6968 * @connection_state: enum to be converted to a string
6969 *
6970 * Return: the string equivalent of @connection_state
6971 */
6972static const char *
6973hdd_connection_state_string(eConnectionState connection_state)
6974{
6975 switch (connection_state) {
6976 CASE_RETURN_STRING(eConnectionState_NotConnected);
6977 CASE_RETURN_STRING(eConnectionState_Connecting);
6978 CASE_RETURN_STRING(eConnectionState_Associated);
6979 CASE_RETURN_STRING(eConnectionState_IbssDisconnected);
6980 CASE_RETURN_STRING(eConnectionState_IbssConnected);
6981 CASE_RETURN_STRING(eConnectionState_Disconnecting);
6982 default:
6983 return "UNKNOWN";
6984 }
6985}
6986
6987/**
6988 * iw_get_char_setnone() - Generic "get string" private ioctl handler
6989 * @dev: device upon which the ioctl was received
6990 * @info: ioctl request information
6991 * @wrqu: ioctl request data
6992 * @extra: ioctl extra data
6993 *
6994 * Return: 0 on success, non-zero on error
6995 */
6996static int __iw_get_char_setnone(struct net_device *dev,
6997 struct iw_request_info *info,
6998 union iwreq_data *wrqu, char *extra)
6999{
7000 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
7001 int sub_cmd = wrqu->data.flags;
7002 hdd_context_t *hdd_ctx;
7003 int ret;
7004#ifdef WLAN_FEATURE_11W
7005 hdd_wext_state_t *pWextState;
7006#endif
7007
7008#ifdef WLAN_FEATURE_11W
7009 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
7010#endif
7011
Jeff Johnson6ee91ee2016-02-11 18:55:30 -08007012 ENTER_DEV(dev);
Hanumantha Reddy Pothula2db50ed2015-11-23 10:48:33 +05307013
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007014 hdd_ctx = WLAN_HDD_GET_CTX(pAdapter);
7015 ret = wlan_hdd_validate_context(hdd_ctx);
7016 if (0 != ret)
7017 return ret;
7018
7019 switch (sub_cmd) {
7020 case WE_WLAN_VERSION:
7021 {
Arun Khandavallia96c2c02016-05-17 19:15:34 +05307022 hdd_wlan_get_version(hdd_ctx, wrqu, extra);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007023 break;
7024 }
7025
7026 case WE_GET_STATS:
7027 {
7028 hdd_wlan_get_stats(pAdapter, &(wrqu->data.length),
7029 extra, WE_MAX_STR_LEN);
7030 break;
7031 }
7032
Govind Singha471e5e2015-10-12 17:11:14 +05307033 case WE_LIST_FW_PROFILE:
7034 hdd_wlan_list_fw_profile(&(wrqu->data.length),
7035 extra, WE_MAX_STR_LEN);
7036 break;
7037
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007038 /* The case prints the current state of the HDD, SME, CSR, PE,
7039 * TL it can be extended for WDI Global State as well. And
7040 * currently it only checks P2P_CLIENT adapter. P2P_DEVICE
7041 * and P2P_GO have not been added as of now.
7042 */
7043 case WE_GET_STATES:
7044 {
7045 int buf = 0, len = 0;
7046 int adapter_num = 0;
7047 int count = 0, check = 1;
7048
7049 tHalHandle hHal = NULL;
7050 tpAniSirGlobal pMac = NULL;
7051 hdd_station_ctx_t *pHddStaCtx = NULL;
7052
7053 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7054 hdd_adapter_t *useAdapter = NULL;
7055
7056 /* Print wlan0 or p2p0 states based on the adapter_num
7057 * by using the correct adapter
7058 */
7059 while (adapter_num < 2) {
7060 if (WLAN_ADAPTER == adapter_num) {
7061 useAdapter = pAdapter;
7062 buf =
7063 scnprintf(extra + len,
7064 WE_MAX_STR_LEN - len,
7065 "\n\n wlan0 States:-");
7066 len += buf;
7067 } else if (P2P_ADAPTER == adapter_num) {
7068 buf =
7069 scnprintf(extra + len,
7070 WE_MAX_STR_LEN - len,
7071 "\n\n p2p0 States:-");
7072 len += buf;
7073
7074 if (!pHddCtx) {
7075 buf =
7076 scnprintf(extra + len,
7077 WE_MAX_STR_LEN -
7078 len,
7079 "\n pHddCtx is NULL");
7080 len += buf;
7081 break;
7082 }
7083
7084 /* Printing p2p0 states only in the
7085 * case when the device is configured
7086 * as a p2p_client
7087 */
7088 useAdapter =
7089 hdd_get_adapter(pHddCtx,
Krunal Sonif07bb382016-03-10 13:02:11 -08007090 QDF_P2P_CLIENT_MODE);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007091 if (!useAdapter) {
7092 buf =
7093 scnprintf(extra + len,
7094 WE_MAX_STR_LEN -
7095 len,
7096 "\n Device not configured as P2P_CLIENT.");
7097 len += buf;
7098 break;
7099 }
7100 }
7101
7102 hHal = WLAN_HDD_GET_HAL_CTX(useAdapter);
7103 if (!hHal) {
7104 buf =
7105 scnprintf(extra + len,
7106 WE_MAX_STR_LEN - len,
7107 "\n pMac is NULL");
7108 len += buf;
7109 break;
7110 }
7111 pMac = PMAC_STRUCT(hHal);
7112 if (!pMac) {
7113 buf =
7114 scnprintf(extra + len,
7115 WE_MAX_STR_LEN - len,
7116 "\n pMac is NULL");
7117 len += buf;
7118 break;
7119 }
7120 pHddStaCtx =
7121 WLAN_HDD_GET_STATION_CTX_PTR(useAdapter);
7122
7123
7124 buf =
7125 scnprintf(extra + len, WE_MAX_STR_LEN - len,
7126 "\n HDD Conn State - %s "
7127 "\n \n SME State:"
7128 "\n Neighbour Roam State - %s"
7129 "\n CSR State - %s"
7130 "\n CSR Substate - %s",
7131 hdd_connection_state_string
7132 (pHddStaCtx->conn_info.connState),
7133 mac_trace_get_neighbour_roam_state
7134 (sme_get_neighbor_roam_state
7135 (hHal, useAdapter->sessionId)),
7136 mac_trace_getcsr_roam_state
7137 (sme_get_current_roam_state
7138 (hHal, useAdapter->sessionId)),
7139 mac_trace_getcsr_roam_sub_state
7140 (sme_get_current_roam_sub_state
7141 (hHal, useAdapter->sessionId))
7142 );
7143 len += buf;
7144 adapter_num++;
7145 }
7146
Mukul Sharma81661ae2015-10-30 20:26:02 +05307147 if (hHal) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007148 /* Printing Lim State starting with global lim states */
7149 buf =
7150 scnprintf(extra + len, WE_MAX_STR_LEN - len,
7151 "\n \n LIM STATES:-"
7152 "\n Global Sme State - %s "
7153 "\n Global mlm State - %s " "\n",
7154 mac_trace_get_lim_sme_state
7155 (sme_get_lim_sme_state(hHal)),
7156 mac_trace_get_lim_mlm_state
7157 (sme_get_lim_sme_state(hHal))
7158 );
7159 len += buf;
7160
7161 /* Printing the PE Sme and Mlm states for valid lim sessions */
7162 while (check < 3 && count < 255) {
7163 if (sme_is_lim_session_valid(hHal, count)) {
7164 buf =
7165 scnprintf(extra + len,
7166 WE_MAX_STR_LEN -
7167 len,
7168 "\n Lim Valid Session %d:-"
7169 "\n PE Sme State - %s "
7170 "\n PE Mlm State - %s "
7171 "\n", check,
7172 mac_trace_get_lim_sme_state
7173 (sme_get_lim_sme_session_state
7174 (hHal, count)),
7175 mac_trace_get_lim_mlm_state
7176 (sme_get_lim_mlm_session_state
7177 (hHal, count))
7178 );
7179
7180 len += buf;
7181 check++;
7182 }
7183 count++;
7184 }
7185 }
7186
7187 wrqu->data.length = strlen(extra) + 1;
7188 break;
7189 }
7190
7191 case WE_GET_CFG:
7192 {
Jeff Johnson99bac312016-06-28 10:38:18 -07007193 hdd_notice("Printing CLD global INI Config");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007194 hdd_cfg_get_global_config(WLAN_HDD_GET_CTX(pAdapter),
7195 extra,
7196 QCSAP_IOCTL_MAX_STR_LEN);
7197 wrqu->data.length = strlen(extra) + 1;
7198 break;
7199 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007200 case WE_GET_RSSI:
7201 {
7202 int8_t s7Rssi = 0;
7203 wlan_hdd_get_rssi(pAdapter, &s7Rssi);
7204 snprintf(extra, WE_MAX_STR_LEN, "rssi=%d", s7Rssi);
7205 wrqu->data.length = strlen(extra) + 1;
7206 break;
7207 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007208
7209 case WE_GET_WMM_STATUS:
7210 {
7211 snprintf(extra, WE_MAX_STR_LEN,
7212 "\nDir: 0=up, 1=down, 3=both\n"
7213 "|------------------------|\n"
7214 "|AC | ACM |Admitted| Dir |\n"
7215 "|------------------------|\n"
7216 "|VO | %d | %3s | %d |\n"
7217 "|VI | %d | %3s | %d |\n"
7218 "|BE | %d | %3s | %d |\n"
7219 "|BK | %d | %3s | %d |\n"
7220 "|------------------------|\n",
7221 pAdapter->hddWmmStatus.
7222 wmmAcStatus[SME_AC_VO].wmmAcAccessRequired,
7223 pAdapter->hddWmmStatus.
7224 wmmAcStatus[SME_AC_VO].
7225 wmmAcAccessAllowed ? "YES" : "NO",
7226 pAdapter->hddWmmStatus.
7227 wmmAcStatus[SME_AC_VO].wmmAcTspecInfo.
7228 ts_info.direction,
7229 pAdapter->hddWmmStatus.
7230 wmmAcStatus[SME_AC_VI].wmmAcAccessRequired,
7231 pAdapter->hddWmmStatus.
7232 wmmAcStatus[SME_AC_VI].
7233 wmmAcAccessAllowed ? "YES" : "NO",
7234 pAdapter->hddWmmStatus.
7235 wmmAcStatus[SME_AC_VI].wmmAcTspecInfo.
7236 ts_info.direction,
7237 pAdapter->hddWmmStatus.
7238 wmmAcStatus[SME_AC_BE].wmmAcAccessRequired,
7239 pAdapter->hddWmmStatus.
7240 wmmAcStatus[SME_AC_BE].
7241 wmmAcAccessAllowed ? "YES" : "NO",
7242 pAdapter->hddWmmStatus.
7243 wmmAcStatus[SME_AC_BE].wmmAcTspecInfo.
7244 ts_info.direction,
7245 pAdapter->hddWmmStatus.
7246 wmmAcStatus[SME_AC_BK].wmmAcAccessRequired,
7247 pAdapter->hddWmmStatus.
7248 wmmAcStatus[SME_AC_BK].
7249 wmmAcAccessAllowed ? "YES" : "NO",
7250 pAdapter->hddWmmStatus.
7251 wmmAcStatus[SME_AC_BK].wmmAcTspecInfo.
7252 ts_info.direction);
7253
7254 wrqu->data.length = strlen(extra) + 1;
7255 break;
7256 }
7257 case WE_GET_CHANNEL_LIST:
7258 {
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05307259 QDF_STATUS status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007260 uint8_t i, len;
7261 char *buf;
7262 uint8_t ubuf[WNI_CFG_COUNTRY_CODE_LEN];
7263 uint8_t ubuf_len = WNI_CFG_COUNTRY_CODE_LEN;
7264 hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(pAdapter);
7265
7266 tChannelListInfo channel_list;
7267
7268 memset(&channel_list, 0, sizeof(channel_list));
7269 status =
7270 iw_softap_get_channel_list(dev, info, wrqu,
7271 (char *)&channel_list);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05307272 if (!QDF_IS_STATUS_SUCCESS(status)) {
Jeff Johnson99bac312016-06-28 10:38:18 -07007273 hdd_err("GetChannelList Failed!!!");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007274 return -EINVAL;
7275 }
7276 buf = extra;
7277 /*
7278 * Maximum channels = WNI_CFG_VALID_CHANNEL_LIST_LEN.
7279 * Maximum buffer needed = 5 * number of channels.
7280 * Check ifsufficient buffer is available and then
7281 * proceed to fill the buffer.
7282 */
7283 if (WE_MAX_STR_LEN <
7284 (5 * WNI_CFG_VALID_CHANNEL_LIST_LEN)) {
Jeff Johnson99bac312016-06-28 10:38:18 -07007285 hdd_err("Insufficient Buffer to populate channel list");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007286 return -EINVAL;
7287 }
7288 len = scnprintf(buf, WE_MAX_STR_LEN, "%u ",
7289 channel_list.num_channels);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05307290 if (QDF_STATUS_SUCCESS == sme_get_country_code(hdd_ctx->hHal,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007291 ubuf, &ubuf_len)) {
7292 /* Printing Country code in getChannelList */
7293 for (i = 0; i < (ubuf_len - 1); i++)
7294 len += scnprintf(buf + len,
7295 WE_MAX_STR_LEN - len,
7296 "%c", ubuf[i]);
7297 }
7298 for (i = 0; i < channel_list.num_channels; i++) {
7299 len +=
7300 scnprintf(buf + len, WE_MAX_STR_LEN - len,
7301 " %u", channel_list.channels[i]);
7302 }
7303 wrqu->data.length = strlen(extra) + 1;
7304
7305 break;
7306 }
7307#ifdef FEATURE_WLAN_TDLS
7308 case WE_GET_TDLS_PEERS:
7309 {
7310 wrqu->data.length =
7311 wlan_hdd_tdls_get_all_peers(pAdapter, extra,
7312 WE_MAX_STR_LEN) + 1;
7313 break;
7314 }
7315#endif
7316#ifdef WLAN_FEATURE_11W
7317 case WE_GET_11W_INFO:
7318 {
Jeff Johnson99bac312016-06-28 10:38:18 -07007319 hdd_err("WE_GET_11W_ENABLED = %d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007320 pWextState->roamProfile.MFPEnabled);
7321
7322 snprintf(extra, WE_MAX_STR_LEN,
7323 "\n BSSID %02X:%02X:%02X:%02X:%02X:%02X, Is PMF Assoc? %d"
7324 "\n Number of Unprotected Disassocs %d"
7325 "\n Number of Unprotected Deauths %d",
7326 pWextState->roamProfile.BSSIDs.bssid->bytes[0],
7327 pWextState->roamProfile.BSSIDs.bssid->bytes[1],
7328 pWextState->roamProfile.BSSIDs.bssid->bytes[2],
7329 pWextState->roamProfile.BSSIDs.bssid->bytes[3],
7330 pWextState->roamProfile.BSSIDs.bssid->bytes[4],
7331 pWextState->roamProfile.BSSIDs.bssid->bytes[5],
7332 pWextState->roamProfile.MFPEnabled,
7333 pAdapter->hdd_stats.hddPmfStats.
7334 numUnprotDisassocRx,
7335 pAdapter->hdd_stats.hddPmfStats.
7336 numUnprotDeauthRx);
7337
7338 wrqu->data.length = strlen(extra) + 1;
7339 break;
7340 }
7341#endif
Rajeev Kumar8e3e2832015-11-06 16:02:54 -08007342 case WE_GET_IBSS_STA_INFO:
7343 {
7344 hdd_station_ctx_t *pHddStaCtx =
7345 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7346 int idx = 0;
7347 int length = 0, buf = 0;
7348
Naveen Rawatc45d1622016-07-05 12:20:09 -07007349 for (idx = 0; idx < MAX_PEERS; idx++) {
Rajeev Kumar8e3e2832015-11-06 16:02:54 -08007350 if (0 != pHddStaCtx->conn_info.staId[idx]) {
7351 buf = snprintf
7352 ((extra + length),
7353 WE_MAX_STR_LEN - length,
7354 "\n%d .%02x:%02x:%02x:%02x:%02x:%02x\n",
7355 pHddStaCtx->conn_info.staId[idx],
7356 pHddStaCtx->conn_info.
7357 peerMacAddress[idx].bytes[0],
7358 pHddStaCtx->conn_info.
7359 peerMacAddress[idx].bytes[1],
7360 pHddStaCtx->conn_info.
7361 peerMacAddress[idx].bytes[2],
7362 pHddStaCtx->conn_info.
7363 peerMacAddress[idx].bytes[3],
7364 pHddStaCtx->conn_info.
7365 peerMacAddress[idx].bytes[4],
7366 pHddStaCtx->conn_info.
7367 peerMacAddress[idx].bytes[5]
7368 );
7369 length += buf;
7370 }
7371 }
7372 wrqu->data.length = strlen(extra) + 1;
7373 break;
7374 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007375 case WE_GET_PHYMODE:
7376 {
7377 bool ch_bond24 = false, ch_bond5g = false;
7378 hdd_context_t *hddctx = WLAN_HDD_GET_CTX(pAdapter);
7379 tHalHandle hal = WLAN_HDD_GET_HAL_CTX(pAdapter);
7380 eCsrPhyMode phymode;
7381 eCsrBand currBand;
7382 tSmeConfigParams smeconfig;
7383
7384 sme_get_config_param(hal, &smeconfig);
7385 if (WNI_CFG_CHANNEL_BONDING_MODE_DISABLE !=
7386 smeconfig.csrConfig.channelBondingMode24GHz)
7387 ch_bond24 = true;
7388
7389 if (WNI_CFG_CHANNEL_BONDING_MODE_DISABLE !=
7390 smeconfig.csrConfig.channelBondingMode5GHz)
7391 ch_bond5g = true;
7392
7393 phymode = sme_get_phy_mode(hal);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05307394 if ((QDF_STATUS_SUCCESS !=
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007395 sme_get_freq_band(hal, &currBand))) {
Jeff Johnson99bac312016-06-28 10:38:18 -07007396 hdd_notice("Failed to get current band config");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007397 return -EIO;
7398 }
7399
7400 switch (phymode) {
7401 case eCSR_DOT11_MODE_AUTO:
7402 snprintf(extra, WE_MAX_STR_LEN, "AUTO MODE");
7403 break;
7404 case eCSR_DOT11_MODE_11n:
7405 case eCSR_DOT11_MODE_11n_ONLY:
7406 if (currBand == eCSR_BAND_24) {
7407 if (ch_bond24)
7408 snprintf(extra, WE_MAX_STR_LEN,
7409 "11NGHT40");
7410 else
7411 snprintf(extra, WE_MAX_STR_LEN,
7412 "11NGHT20");
7413 } else if (currBand == eCSR_BAND_5G) {
7414 if (ch_bond5g)
7415 snprintf(extra, WE_MAX_STR_LEN,
7416 "11NAHT40");
7417 else
7418 snprintf(extra, WE_MAX_STR_LEN,
7419 "11NAHT20");
7420 } else {
7421 snprintf(extra, WE_MAX_STR_LEN, "11N");
7422 }
7423 break;
7424 case eCSR_DOT11_MODE_abg:
7425 snprintf(extra, WE_MAX_STR_LEN, "11ABG");
7426 break;
7427 case eCSR_DOT11_MODE_11a:
7428 snprintf(extra, WE_MAX_STR_LEN, "11A");
7429 break;
7430 case eCSR_DOT11_MODE_11b:
7431 case eCSR_DOT11_MODE_11b_ONLY:
7432 snprintf(extra, WE_MAX_STR_LEN, "11B");
7433 break;
7434 case eCSR_DOT11_MODE_11g:
7435 case eCSR_DOT11_MODE_11g_ONLY:
7436 snprintf(extra, WE_MAX_STR_LEN, "11G");
7437 break;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007438 case eCSR_DOT11_MODE_11ac:
7439 case eCSR_DOT11_MODE_11ac_ONLY:
7440 if (hddctx->config->vhtChannelWidth ==
7441 eHT_CHANNEL_WIDTH_20MHZ)
7442 snprintf(extra, WE_MAX_STR_LEN,
7443 "11ACVHT20");
7444 else if (hddctx->config->vhtChannelWidth ==
7445 eHT_CHANNEL_WIDTH_40MHZ)
7446 snprintf(extra, WE_MAX_STR_LEN,
7447 "11ACVHT40");
7448 else if (hddctx->config->vhtChannelWidth ==
7449 eHT_CHANNEL_WIDTH_80MHZ)
7450 snprintf(extra, WE_MAX_STR_LEN,
7451 "11ACVHT80");
7452 else if (hddctx->config->vhtChannelWidth ==
7453 eHT_CHANNEL_WIDTH_160MHZ)
7454 snprintf(extra, WE_MAX_STR_LEN,
7455 "11ACVHT160");
7456 break;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007457 }
7458
7459 wrqu->data.length = strlen(extra) + 1;
7460 break;
7461 }
7462
7463#ifdef FEATURE_OEM_DATA_SUPPORT
7464 case WE_GET_OEM_DATA_CAP:
7465 {
7466 return iw_get_oem_data_cap(dev, info, wrqu, extra);
7467 }
7468#endif /* FEATURE_OEM_DATA_SUPPORT */
7469 case WE_GET_SNR:
7470 {
7471 int8_t s7snr = 0;
7472 int status = 0;
7473 hdd_context_t *pHddCtx;
7474 hdd_station_ctx_t *pHddStaCtx;
7475 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7476 status = wlan_hdd_validate_context(pHddCtx);
Abhishek Singh23edd1c2016-05-05 11:56:06 +05307477 if (status)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007478 return status;
Abhishek Singh23edd1c2016-05-05 11:56:06 +05307479
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007480 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7481 if (0 == pHddCtx->config->fEnableSNRMonitoring ||
7482 eConnectionState_Associated !=
7483 pHddStaCtx->conn_info.connState) {
Jeff Johnson99bac312016-06-28 10:38:18 -07007484 hdd_err("getSNR failed: Enable SNR Monitoring-%d, ConnectionState-%d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007485 pHddCtx->config->fEnableSNRMonitoring,
7486 pHddStaCtx->conn_info.connState);
7487 return -ENONET;
7488 }
7489 wlan_hdd_get_snr(pAdapter, &s7snr);
7490 snprintf(extra, WE_MAX_STR_LEN, "snr=%d", s7snr);
7491 wrqu->data.length = strlen(extra) + 1;
7492 break;
7493 }
7494 default:
7495 {
Jeff Johnson99bac312016-06-28 10:38:18 -07007496 hdd_err("Invalid IOCTL command %d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007497 sub_cmd);
7498 break;
7499 }
7500 }
Hanumantha Reddy Pothula2db50ed2015-11-23 10:48:33 +05307501 EXIT();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007502 return 0;
7503}
7504
7505static int iw_get_char_setnone(struct net_device *dev,
7506 struct iw_request_info *info,
7507 union iwreq_data *wrqu, char *extra)
7508{
7509 int ret;
7510
7511 cds_ssr_protect(__func__);
7512 ret = __iw_get_char_setnone(dev, info, wrqu, extra);
7513 cds_ssr_unprotect(__func__);
7514
7515 return ret;
7516}
7517
7518/**
7519 * iw_setnone_getnone() - Generic "action" private ioctl handler
7520 * @dev: device upon which the ioctl was received
7521 * @info: ioctl request information
7522 * @wrqu: ioctl request data
7523 * @extra: ioctl extra data
7524 *
7525 * Return: 0 on success, non-zero on error
7526 */
7527static int __iw_setnone_getnone(struct net_device *dev,
7528 struct iw_request_info *info,
7529 union iwreq_data *wrqu, char *extra)
7530{
Sandeep Puligilla93a29ec2016-02-12 16:10:56 -08007531 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007532 hdd_context_t *hdd_ctx;
7533 int ret;
7534 int sub_cmd;
7535
Jeff Johnson6ee91ee2016-02-11 18:55:30 -08007536 ENTER_DEV(dev);
Hanumantha Reddy Pothula2db50ed2015-11-23 10:48:33 +05307537
Sandeep Puligilla93a29ec2016-02-12 16:10:56 -08007538 hdd_ctx = WLAN_HDD_GET_CTX(adapter);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007539 ret = wlan_hdd_validate_context(hdd_ctx);
7540 if (0 != ret)
7541 return ret;
7542
7543#ifdef CONFIG_COMPAT
7544 /* this ioctl is a special case where a sub-ioctl is used and both
7545 * the number of get and set args is 0. in this specific case the
7546 * logic in iwpriv places the sub_cmd in the data.flags portion of
7547 * the iwreq. unfortunately the location of this field will be
7548 * different between 32-bit and 64-bit userspace, and the standard
7549 * compat support in the kernel does not handle this case. so we
7550 * need to explicitly handle it here.
7551 */
7552 if (is_compat_task()) {
7553 struct compat_iw_point *compat_iw_point =
7554 (struct compat_iw_point *)&wrqu->data;
7555 sub_cmd = compat_iw_point->flags;
7556 } else {
7557 sub_cmd = wrqu->data.flags;
7558 }
7559#else
7560 sub_cmd = wrqu->data.flags;
7561#endif
7562
7563 switch (sub_cmd) {
7564 case WE_GET_RECOVERY_STAT:
7565 {
Sandeep Puligilla93a29ec2016-02-12 16:10:56 -08007566 tHalHandle hal = WLAN_HDD_GET_HAL_CTX(adapter);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007567 sme_get_recovery_stats(hal);
7568 break;
7569 }
7570
Govind Singha471e5e2015-10-12 17:11:14 +05307571 case WE_GET_FW_PROFILE_DATA:
Sandeep Puligilla93a29ec2016-02-12 16:10:56 -08007572 ret = wma_cli_set_command(adapter->sessionId,
Govind Singha471e5e2015-10-12 17:11:14 +05307573 WMI_WLAN_PROFILE_GET_PROFILE_DATA_CMDID,
7574 0, DBG_CMD);
7575 break;
7576
Rajeev Kumar8e3e2832015-11-06 16:02:54 -08007577 case WE_IBSS_GET_PEER_INFO_ALL:
7578 {
7579 hdd_wlan_get_ibss_peer_info_all(adapter);
7580 break;
7581 }
7582
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007583 case WE_SET_REASSOC_TRIGGER:
7584 {
Sandeep Puligilla93a29ec2016-02-12 16:10:56 -08007585 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
7586 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(adapter);
Deepak Dhamdhere5fda0e42016-06-24 18:30:02 +05307587 tSirMacAddr bssid;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007588 uint32_t roamId = 0;
Deepak Dhamdhere5fda0e42016-06-24 18:30:02 +05307589 uint8_t operating_ch =
7590 adapter->sessionCtx.station.conn_info.operationChannel;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007591 tCsrRoamModifyProfileFields modProfileFields;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007592
Sandeep Puligilla93a29ec2016-02-12 16:10:56 -08007593 sme_get_modify_profile_fields(hHal, adapter->sessionId,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007594 &modProfileFields);
Deepak Dhamdhere5fda0e42016-06-24 18:30:02 +05307595 if (roaming_offload_enabled(hdd_ctx)) {
7596 qdf_mem_copy(bssid,
7597 &adapter->sessionCtx.station.conn_info.bssId,
7598 sizeof(bssid));
7599 hdd_wma_send_fastreassoc_cmd((int)adapter->sessionId,
7600 bssid, operating_ch);
7601 } else {
7602 sme_roam_reassoc(hdd_ctx->hHal, adapter->sessionId,
7603 NULL, modProfileFields, &roamId, 1);
7604 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007605 return 0;
7606 }
7607
7608 case WE_DUMP_AGC_START:
7609 {
Jeff Johnson99bac312016-06-28 10:38:18 -07007610 hdd_notice("WE_DUMP_AGC_START");
Sandeep Puligilla93a29ec2016-02-12 16:10:56 -08007611 ret = wma_cli_set_command(adapter->sessionId,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007612 GEN_PARAM_DUMP_AGC_START,
7613 0, GEN_CMD);
7614 break;
7615 }
7616 case WE_DUMP_AGC:
7617 {
Jeff Johnson99bac312016-06-28 10:38:18 -07007618 hdd_notice("WE_DUMP_AGC");
Sandeep Puligilla93a29ec2016-02-12 16:10:56 -08007619 ret = wma_cli_set_command(adapter->sessionId,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007620 GEN_PARAM_DUMP_AGC,
7621 0, GEN_CMD);
7622 break;
7623 }
7624
7625 case WE_DUMP_CHANINFO_START:
7626 {
Jeff Johnson99bac312016-06-28 10:38:18 -07007627 hdd_notice("WE_DUMP_CHANINFO_START");
Sandeep Puligilla93a29ec2016-02-12 16:10:56 -08007628 ret = wma_cli_set_command(adapter->sessionId,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007629 GEN_PARAM_DUMP_CHANINFO_START,
7630 0, GEN_CMD);
7631 break;
7632 }
7633 case WE_DUMP_CHANINFO:
7634 {
Jeff Johnson99bac312016-06-28 10:38:18 -07007635 hdd_notice("WE_DUMP_CHANINFO_START");
Sandeep Puligilla93a29ec2016-02-12 16:10:56 -08007636 ret = wma_cli_set_command(adapter->sessionId,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007637 GEN_PARAM_DUMP_CHANINFO,
7638 0, GEN_CMD);
7639 break;
7640 }
7641 case WE_DUMP_WATCHDOG:
7642 {
Jeff Johnson99bac312016-06-28 10:38:18 -07007643 hdd_notice("WE_DUMP_WATCHDOG");
Sandeep Puligilla93a29ec2016-02-12 16:10:56 -08007644 ret = wma_cli_set_command(adapter->sessionId,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007645 GEN_PARAM_DUMP_WATCHDOG,
7646 0, GEN_CMD);
7647 break;
7648 }
7649#ifdef CONFIG_ATH_PCIE_ACCESS_DEBUG
7650 case WE_DUMP_PCIE_LOG:
7651 {
Jeff Johnson99bac312016-06-28 10:38:18 -07007652 hdd_err("WE_DUMP_PCIE_LOG");
Sandeep Puligilla93a29ec2016-02-12 16:10:56 -08007653 ret = wma_cli_set_command(adapter->sessionId,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007654 GEN_PARAM_DUMP_PCIE_ACCESS_LOG,
7655 0, GEN_CMD);
7656 break;
7657 }
7658#endif
Sandeep Puligilla93a29ec2016-02-12 16:10:56 -08007659 case WE_STOP_OBSS_SCAN:
7660 {
7661 /*
7662 * 1.OBSS Scan is mandatory while operating in 2.4GHz
7663 * 2.OBSS scan is stopped by Firmware during the disassociation
7664 * 3.OBSS stop comamnd is added for debugging purpose
7665 */
7666 tHalHandle hal;
7667
7668 hal = WLAN_HDD_GET_HAL_CTX(adapter);
7669 if (hal == NULL) {
7670 hdd_err("hal context is NULL");
7671 return -EINVAL;
7672 }
7673 sme_ht40_stop_obss_scan(hal, adapter->sessionId);
7674 }
7675 break;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007676 default:
7677 {
Jeff Johnson99bac312016-06-28 10:38:18 -07007678 hdd_err("unknown ioctl %d", sub_cmd);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007679 break;
7680 }
7681 }
Hanumantha Reddy Pothula2db50ed2015-11-23 10:48:33 +05307682 EXIT();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007683 return ret;
7684}
7685
7686static int iw_setnone_getnone(struct net_device *dev,
7687 struct iw_request_info *info,
7688 union iwreq_data *wrqu, char *extra)
7689{
7690 int ret;
7691
7692 cds_ssr_protect(__func__);
7693 ret = __iw_setnone_getnone(dev, info, wrqu, extra);
7694 cds_ssr_unprotect(__func__);
7695
7696 return ret;
7697}
7698
7699/**
7700 * __iw_set_var_ints_getnone - Generic "set many" private ioctl handler
7701 * @dev: device upon which the ioctl was received
7702 * @info: ioctl request information
7703 * @wrqu: ioctl request data
7704 * @extra: ioctl extra data
7705 *
7706 * This is an SSR-protected generic handler for private ioctls which
7707 * take multiple arguments. Note that this implementation is also
7708 * somewhat unique in that it is shared by both STA-mode and SAP-mode
7709 * interfaces.
7710 *
7711 * Return: 0 on success, non-zero on error
7712 */
7713static int __iw_set_var_ints_getnone(struct net_device *dev,
7714 struct iw_request_info *info,
7715 union iwreq_data *wrqu, char *extra)
7716{
7717 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
7718 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
7719 int sub_cmd;
7720 int *apps_args = (int *) extra;
7721 hdd_context_t *hdd_ctx;
7722 int ret, num_args;
7723
Jeff Johnson6ee91ee2016-02-11 18:55:30 -08007724 ENTER_DEV(dev);
Hanumantha Reddy Pothula2db50ed2015-11-23 10:48:33 +05307725
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007726 hdd_ctx = WLAN_HDD_GET_CTX(pAdapter);
7727 ret = wlan_hdd_validate_context(hdd_ctx);
7728 if (0 != ret)
7729 return ret;
7730
7731 if (extra == NULL) {
Jeff Johnson99bac312016-06-28 10:38:18 -07007732 hdd_err("NULL extra buffer pointer");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007733 return -EINVAL;
7734 }
7735
7736 sub_cmd = wrqu->data.flags;
7737 num_args = wrqu->data.length;
7738
Jeff Johnson99bac312016-06-28 10:38:18 -07007739 hdd_notice("Received length %d", wrqu->data.length);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007740
7741 switch (sub_cmd) {
Rajeev Kumar8e3e2832015-11-06 16:02:54 -08007742 case WE_IBSS_GET_PEER_INFO:
7743 {
7744 pr_info("Station ID = %d\n", apps_args[0]);
7745 hdd_wlan_get_ibss_peer_info(pAdapter, apps_args[0]);
7746 }
7747 break;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007748
7749 case WE_P2P_NOA_CMD:
7750 {
7751 p2p_app_setP2pPs_t p2pNoA;
7752
Krunal Sonif07bb382016-03-10 13:02:11 -08007753 if (pAdapter->device_mode != QDF_P2P_GO_MODE) {
Rajeev Kumar274034c2015-11-23 11:28:58 -08007754 hdd_err("Setting NoA is not allowed in Device mode %s(%d)",
7755 hdd_device_mode_to_string(
7756 pAdapter->device_mode),
7757 pAdapter->device_mode);
7758 return -EINVAL;
7759 }
7760
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007761 p2pNoA.opp_ps = apps_args[0];
7762 p2pNoA.ctWindow = apps_args[1];
7763 p2pNoA.duration = apps_args[2];
7764 p2pNoA.interval = apps_args[3];
7765 p2pNoA.count = apps_args[4];
7766 p2pNoA.single_noa_duration = apps_args[5];
7767 p2pNoA.psSelection = apps_args[6];
7768
Jeff Johnson99bac312016-06-28 10:38:18 -07007769 hdd_notice("P2P_NOA_ATTR:oppPS %d ctWindow %d duration %d interval %d count %d single noa duration %d PsSelection %x",
7770 apps_args[0], apps_args[1], apps_args[2],
7771 apps_args[3], apps_args[4],
7772 apps_args[5], apps_args[6]);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007773
7774 hdd_set_p2p_ps(dev, &p2pNoA);
7775
7776 }
7777 break;
7778
7779 case WE_MTRACE_SELECTIVE_MODULE_LOG_ENABLE_CMD:
7780 {
Jeff Johnson99bac312016-06-28 10:38:18 -07007781 hdd_notice("SELECTIVE_MODULE_LOG %d arg1 %d arg2",
7782 apps_args[0], apps_args[1]);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05307783 qdf_trace_enable(apps_args[0], apps_args[1]);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007784 }
7785 break;
7786
7787 case WE_MTRACE_DUMP_CMD:
7788 {
Jeff Johnson99bac312016-06-28 10:38:18 -07007789 hdd_notice("MTRACE_DUMP code %d session %d count %d bitmask_of_module %d ",
7790 apps_args[0], apps_args[1],
7791 apps_args[2], apps_args[3]);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05307792 qdf_trace_dump_all((void *)hHal, apps_args[0],
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007793 apps_args[1], apps_args[2],
7794 apps_args[3]);
7795
7796 }
7797 break;
7798
7799 case WE_POLICY_MANAGER_CLIST_CMD:
7800 {
Jeff Johnson99bac312016-06-28 10:38:18 -07007801 hdd_err("<iwpriv wlan0 pm_clist> is called");
Tushnim Bhattacharyyaca50b322015-12-28 17:14:36 -08007802 cds_incr_connection_count_utfw(apps_args[0],
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007803 apps_args[1], apps_args[2], apps_args[3],
7804 apps_args[4], apps_args[5], apps_args[6],
7805 apps_args[7]);
7806 }
7807 break;
7808
7809 case WE_POLICY_MANAGER_DLIST_CMD:
7810 {
Jeff Johnson99bac312016-06-28 10:38:18 -07007811 hdd_err("<iwpriv wlan0 pm_dlist> is called");
Tushnim Bhattacharyyaca50b322015-12-28 17:14:36 -08007812 cds_decr_connection_count_utfw(apps_args[0],
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007813 apps_args[1]);
7814 }
7815 break;
7816
7817 case WE_POLICY_MANAGER_ULIST_CMD:
7818 {
Jeff Johnson99bac312016-06-28 10:38:18 -07007819 hdd_err("<iwpriv wlan0 pm_ulist> is called");
Tushnim Bhattacharyyaca50b322015-12-28 17:14:36 -08007820 cds_update_connection_info_utfw(apps_args[0],
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007821 apps_args[1], apps_args[2], apps_args[3],
7822 apps_args[4], apps_args[5], apps_args[6],
7823 apps_args[7]);
7824 }
7825 break;
7826
7827 case WE_POLICY_MANAGER_DBS_CMD:
7828 {
Jeff Johnson99bac312016-06-28 10:38:18 -07007829 hdd_err("<iwpriv wlan0 pm_dbs> is called");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007830 if (apps_args[0] == 0)
7831 wma_set_dbs_capability_ut(0);
7832 else
7833 wma_set_dbs_capability_ut(1);
7834
7835 if (apps_args[1] >= CDS_THROUGHPUT &&
7836 apps_args[1] <= CDS_LATENCY) {
7837 pr_info("setting system pref to [%d]\n", apps_args[1]);
7838 hdd_ctx->config->conc_system_pref = apps_args[1];
7839 }
7840 }
7841 break;
7842
7843 case WE_POLICY_MANAGER_PCL_CMD:
7844 {
Manishekar Chandrasekaran1db3abe2016-06-24 03:27:07 +05307845 uint8_t pcl[QDF_MAX_NUM_CHAN] = {0};
7846 uint8_t weight_list[QDF_MAX_NUM_CHAN] = {0};
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007847 uint32_t pcl_len = 0, i = 0;
7848
Jeff Johnson99bac312016-06-28 10:38:18 -07007849 hdd_err("<iwpriv wlan0 pm_pcl> is called");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007850
Tushnim Bhattacharyyaca50b322015-12-28 17:14:36 -08007851 cds_get_pcl(apps_args[0],
Manishekar Chandrasekaran7009f252016-04-21 19:14:15 +05307852 pcl, &pcl_len,
7853 weight_list, QDF_ARRAY_SIZE(weight_list));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007854 pr_info("PCL list for role[%d] is {", apps_args[0]);
7855 for (i = 0 ; i < pcl_len; i++)
7856 pr_info(" %d, ", pcl[i]);
7857 pr_info("}--------->\n");
7858 }
7859 break;
7860
7861 case WE_POLICY_MANAGER_CINFO_CMD:
7862 {
7863 struct cds_conc_connection_info *conn_info;
7864 uint32_t i = 0, len = 0;
7865
Jeff Johnson99bac312016-06-28 10:38:18 -07007866 hdd_err("<iwpriv wlan0 pm_cinfo> is called");
Tushnim Bhattacharyyaca50b322015-12-28 17:14:36 -08007867 conn_info = cds_get_conn_info(&len);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007868 pr_info("+-----------------------------+\n");
7869 for (i = 0; i < len; i++) {
7870 pr_info("|table_index[%d]\t\t|\n", i);
7871 pr_info("|\t|vdev_id - %d\t\t|\n", conn_info->vdev_id);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007872 pr_info("|\t|chan - %d\t\t|\n", conn_info->chan);
Tushnim Bhattacharyya7624a182016-03-30 13:30:46 -07007873 pr_info("|\t|bw - %d\t\t|\n", conn_info->bw);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007874 pr_info("|\t|mode - %d\t\t|\n", conn_info->mode);
7875 pr_info("|\t|mac - %d\t\t|\n", conn_info->mac);
7876 pr_info("|\t|in_use - %d\t\t|\n", conn_info->in_use);
7877 pr_info("+-----------------------------+\n");
7878 conn_info++;
7879 }
7880 }
7881 break;
7882
7883 case WE_POLICY_SET_HW_MODE_CMD:
7884 {
7885 if (apps_args[0] == 0) {
Jeff Johnson99bac312016-06-28 10:38:18 -07007886 hdd_err("set hw mode for single mac");
Manishekar Chandrasekarand9640342016-04-27 12:28:26 +05307887 cds_pdev_set_hw_mode(
Chandrasekaran, Manishekaref70c0d2015-10-20 19:54:55 +05307888 pAdapter->sessionId,
7889 HW_MODE_SS_2x2,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007890 HW_MODE_80_MHZ,
7891 HW_MODE_SS_0x0, HW_MODE_BW_NONE,
7892 HW_MODE_DBS_NONE,
Chandrasekaran, Manishekaref70c0d2015-10-20 19:54:55 +05307893 HW_MODE_AGILE_DFS_NONE,
Chandrasekaran, Manishekarce2172e2016-02-18 16:12:43 +05307894 SIR_UPDATE_REASON_UT);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007895 } else if (apps_args[0] == 1) {
Jeff Johnson99bac312016-06-28 10:38:18 -07007896 hdd_err("set hw mode for dual mac");
Manishekar Chandrasekarand9640342016-04-27 12:28:26 +05307897 cds_pdev_set_hw_mode(
Chandrasekaran, Manishekaref70c0d2015-10-20 19:54:55 +05307898 pAdapter->sessionId,
7899 HW_MODE_SS_1x1,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007900 HW_MODE_80_MHZ,
7901 HW_MODE_SS_1x1, HW_MODE_40_MHZ,
7902 HW_MODE_DBS,
Chandrasekaran, Manishekaref70c0d2015-10-20 19:54:55 +05307903 HW_MODE_AGILE_DFS_NONE,
Chandrasekaran, Manishekarce2172e2016-02-18 16:12:43 +05307904 SIR_UPDATE_REASON_UT);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007905 }
7906 }
7907 break;
7908
7909 case WE_POLICY_MANAGER_QUERY_ACTION_CMD:
7910 {
7911 enum cds_conc_next_action action;
Jeff Johnson99bac312016-06-28 10:38:18 -07007912 hdd_err("<iwpriv wlan0 pm_query_action> is called");
Chandrasekaran, Manishekaref70c0d2015-10-20 19:54:55 +05307913 action = cds_current_connections_update(pAdapter->sessionId,
7914 apps_args[0],
Chandrasekaran, Manishekarce2172e2016-02-18 16:12:43 +05307915 SIR_UPDATE_REASON_UT);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007916 pr_info("next action is %d {HDD_NOP = 0, HDD_DBS, HDD_DBS_DOWNGRADE, HDD_MCC, HDD_MCC_UPGRADE}", action);
7917 }
7918 break;
7919 case WE_POLICY_MANAGER_QUERY_ALLOW_CMD:
7920 {
7921 bool allow;
Jeff Johnson99bac312016-06-28 10:38:18 -07007922 hdd_err("<iwpriv wlan0 pm_query_allow> is called");
Tushnim Bhattacharyyaca50b322015-12-28 17:14:36 -08007923 allow = cds_allow_concurrency(
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007924 apps_args[0], apps_args[1], apps_args[2]);
7925 pr_info("allow %d {0 = don't allow, 1 = allow}", allow);
7926 }
7927 break;
7928
7929 case WE_POLICY_MANAGER_SCENARIO_CMD:
7930 {
7931 clean_report(hdd_ctx);
7932 if (apps_args[0] == 1) {
7933 wlan_hdd_one_connection_scenario(hdd_ctx);
7934 } else if (apps_args[0] == 2) {
7935 wlan_hdd_two_connections_scenario(hdd_ctx,
7936 6, CDS_TWO_TWO);
7937 wlan_hdd_two_connections_scenario(hdd_ctx,
7938 36, CDS_TWO_TWO);
7939 wlan_hdd_two_connections_scenario(hdd_ctx,
7940 6, CDS_ONE_ONE);
7941 wlan_hdd_two_connections_scenario(hdd_ctx,
7942 36, CDS_ONE_ONE);
7943 } else if (apps_args[0] == 3) {
7944 /* MCC on same band with 2x2 same mac*/
7945 wlan_hdd_three_connections_scenario(hdd_ctx,
7946 6, 11, CDS_TWO_TWO, 0);
7947 /* MCC on diff band with 2x2 same mac*/
7948 wlan_hdd_three_connections_scenario(hdd_ctx,
7949 6, 36, CDS_TWO_TWO, 0);
7950 /* MCC on diff band with 1x1 diff mac */
7951 wlan_hdd_three_connections_scenario(hdd_ctx,
7952 36, 6, CDS_ONE_ONE, 0);
7953 /* MCC on diff band with 1x1 same mac */
7954 wlan_hdd_three_connections_scenario(hdd_ctx,
7955 36, 6, CDS_ONE_ONE, 1);
7956 /* SCC on same band with 2x2 same mac */
7957 wlan_hdd_three_connections_scenario(hdd_ctx,
7958 36, 36, CDS_TWO_TWO, 0);
7959 /* SCC on same band with 1x1 same mac */
7960 wlan_hdd_three_connections_scenario(hdd_ctx,
7961 36, 36, CDS_ONE_ONE, 1);
7962 /* MCC on same band with 2x2 same mac */
7963 wlan_hdd_three_connections_scenario(hdd_ctx,
7964 36, 149, CDS_TWO_TWO, 0);
7965 /* MCC on same band with 1x1 same mac */
7966 wlan_hdd_three_connections_scenario(hdd_ctx,
7967 36, 149, CDS_ONE_ONE, 1);
7968 }
7969 print_report(hdd_ctx);
7970 }
7971 break;
7972
7973#ifdef FEATURE_WLAN_TDLS
7974 case WE_TDLS_CONFIG_PARAMS:
7975 {
7976 tdls_config_params_t tdlsParams;
7977
7978 tdlsParams.tdls = apps_args[0];
7979 tdlsParams.tx_period_t = apps_args[1];
7980 tdlsParams.tx_packet_n = apps_args[2];
7981 /* ignore args[3] as discovery_period is not used anymore */
7982 tdlsParams.discovery_tries_n = apps_args[4];
7983 /* ignore args[5] as idle_timeout is not used anymore */
7984 tdlsParams.idle_packet_n = apps_args[6];
7985 /* ignore args[7] as rssi_hysteresis is not used anymore */
7986 tdlsParams.rssi_trigger_threshold = apps_args[8];
7987 tdlsParams.rssi_teardown_threshold = apps_args[9];
7988 tdlsParams.rssi_delta = apps_args[10];
7989
7990 wlan_hdd_tdls_set_params(dev, &tdlsParams);
7991 }
7992 break;
7993#endif
7994 case WE_UNIT_TEST_CMD:
7995 {
7996 t_wma_unit_test_cmd *unitTestArgs;
7997 cds_msg_t msg = { 0 };
7998 int i, j;
7999 if ((apps_args[0] < WLAN_MODULE_ID_MIN) ||
8000 (apps_args[0] >= WLAN_MODULE_ID_MAX)) {
Jeff Johnson99bac312016-06-28 10:38:18 -07008001 hdd_err("Invalid MODULE ID %d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008002 apps_args[0]);
8003 return -EINVAL;
8004 }
8005 if (apps_args[1] > (WMA_MAX_NUM_ARGS)) {
Jeff Johnson99bac312016-06-28 10:38:18 -07008006 hdd_err("Too Many args %d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008007 apps_args[1]);
8008 return -EINVAL;
8009 }
Anurag Chouhan600c3a02016-03-01 10:33:54 +05308010 unitTestArgs = qdf_mem_malloc(sizeof(*unitTestArgs));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008011 if (NULL == unitTestArgs) {
Jeff Johnson99bac312016-06-28 10:38:18 -07008012 hdd_err("qdf_mem_malloc failed for unitTestArgs");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008013 return -ENOMEM;
8014 }
8015 unitTestArgs->vdev_id = (int)pAdapter->sessionId;
8016 unitTestArgs->module_id = apps_args[0];
8017 unitTestArgs->num_args = apps_args[1];
8018 for (i = 0, j = 2; i < unitTestArgs->num_args; i++, j++) {
8019 unitTestArgs->args[i] = apps_args[j];
8020 }
8021 msg.type = SIR_HAL_UNIT_TEST_CMD;
8022 msg.reserved = 0;
8023 msg.bodyptr = unitTestArgs;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05308024 if (QDF_STATUS_SUCCESS !=
Anurag Chouhan6d760662016-02-20 16:05:43 +05308025 cds_mq_post_message(QDF_MODULE_ID_WMA, &msg)) {
Anurag Chouhan600c3a02016-03-01 10:33:54 +05308026 qdf_mem_free(unitTestArgs);
Jeff Johnson99bac312016-06-28 10:38:18 -07008027 hdd_err("Not able to post UNIT_TEST_CMD message to WMA");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008028 return -EINVAL;
8029 }
8030 }
8031 break;
8032#ifdef WLAN_FEATURE_GPIO_LED_FLASHING
8033 case WE_LED_FLASHING_PARAM:
8034 {
8035 int i;
8036 if (num_args != 4) {
Jeff Johnson99bac312016-06-28 10:38:18 -07008037 hdd_err("gpio_control: 4 parameters are required");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008038 return -EINVAL;
8039 }
8040 for (i = 0; i < num_args; i++) {
8041 if (apps_args[i] >= 0x7fffffff) {
Jeff Johnson99bac312016-06-28 10:38:18 -07008042 hdd_err("gpio_control: parameter should be less than 0x7fffffff");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008043 return -EINVAL;
8044 }
8045 }
8046 sme_set_led_flashing(WLAN_HDD_GET_HAL_CTX(pAdapter),
8047 0, apps_args[0], apps_args[1]);
8048 sme_set_led_flashing(WLAN_HDD_GET_HAL_CTX(pAdapter),
8049 1, apps_args[2], apps_args[3]);
8050 }
8051 break;
8052#endif
Manjeet Singhf82ed072016-07-08 11:40:00 +05308053 case WE_MAC_PWR_DEBUG_CMD:
8054 {
8055 struct sir_mac_pwr_dbg_cmd mac_pwr_dbg_args;
8056 tHalHandle hal = WLAN_HDD_GET_HAL_CTX(pAdapter);
8057 int i, j;
8058
8059 if (num_args < 3) {
8060 hdd_err("number of arguments can't be null %d",
8061 num_args);
8062 return -EINVAL;
8063 }
8064 if (num_args - 3 != apps_args[2]) {
8065 hdd_err("arg list of size %d doesn't match num_args %d",
8066 num_args-3, apps_args[2]);
8067 return -EINVAL;
8068 }
8069 if ((apps_args[1] < WLAN_MODULE_ID_MIN) ||
8070 (apps_args[1] >= WLAN_MODULE_ID_MAX)) {
8071 hdd_err("Invalid MODULE ID %d", apps_args[1]);
8072 return -EINVAL;
8073 }
8074 if (apps_args[2] > (MAX_POWER_DBG_ARGS_SUPPORTED)) {
8075 hdd_err("Too Many args %d", apps_args[2]);
8076 return -EINVAL;
8077 }
8078 mac_pwr_dbg_args.pdev_id = apps_args[0];
8079 mac_pwr_dbg_args.module_id = apps_args[1];
8080 mac_pwr_dbg_args.num_args = apps_args[2];
8081
8082 for (i = 0, j = 3; i < mac_pwr_dbg_args.num_args; i++, j++)
8083 mac_pwr_dbg_args.args[i] = apps_args[j];
8084
8085 if (QDF_STATUS_SUCCESS !=
8086 sme_process_mac_pwr_dbg_cmd(hal, pAdapter->sessionId,
8087 &mac_pwr_dbg_args)) {
8088 return -EINVAL;
8089 }
8090 }
8091 break;
8092
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008093 default:
8094 {
Jeff Johnson99bac312016-06-28 10:38:18 -07008095 hdd_err("Invalid IOCTL command %d", sub_cmd);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008096 }
8097 break;
8098 }
Hanumantha Reddy Pothula2db50ed2015-11-23 10:48:33 +05308099 EXIT();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008100 return 0;
8101}
8102
8103/**
8104 * iw_hdd_set_var_ints_getnone() - set var ints getnone callback
8105 * @dev: pointer to net_device structure
8106 * @info: pointer to iw_request_info structure
8107 * @wrqu: pointer to iwreq_data
8108 * @extra; extra
8109 *
8110 * Return: 0 on success, error number otherwise
8111 *
8112 */
8113static int iw_hdd_set_var_ints_getnone(struct net_device *dev,
8114 struct iw_request_info *info,
8115 union iwreq_data *wrqu, char *extra)
8116{
8117 union iwreq_data u_priv_wrqu;
8118 int apps_args[MAX_VAR_ARGS] = {0};
8119 int ret, num_args;
8120
Mukul Sharma64a70e82015-11-02 20:05:09 +05308121 if (!capable(CAP_NET_ADMIN)) {
Jeff Johnson99bac312016-06-28 10:38:18 -07008122 hdd_err("permission check failed");
Mukul Sharma64a70e82015-11-02 20:05:09 +05308123 return -EPERM;
8124 }
8125
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008126 /* Helper function to get iwreq_data with compat handling. */
8127 if (hdd_priv_get_data(&u_priv_wrqu.data, wrqu))
8128 return -EINVAL;
8129
8130 if (NULL == u_priv_wrqu.data.pointer) {
Jeff Johnson99bac312016-06-28 10:38:18 -07008131 hdd_err("NULL data pointer");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008132 return -EINVAL;
8133 }
8134
8135 num_args = u_priv_wrqu.data.length;
8136 if (num_args > MAX_VAR_ARGS)
8137 num_args = MAX_VAR_ARGS;
8138
8139 if (copy_from_user(apps_args, u_priv_wrqu.data.pointer,
8140 (sizeof(int)) * num_args)) {
Jeff Johnson99bac312016-06-28 10:38:18 -07008141 hdd_err("failed to copy data from user buffer");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008142 return -EFAULT;
8143 }
8144
8145 cds_ssr_protect(__func__);
8146 ret = __iw_set_var_ints_getnone(dev, info, &u_priv_wrqu,
8147 (char *)&apps_args);
8148 cds_ssr_unprotect(__func__);
8149 return ret;
8150}
8151
8152/**
8153 * iw_set_var_ints_getnone - Generic "set many" private ioctl handler
8154 * @dev: device upon which the ioctl was received
8155 * @info: ioctl request information
8156 * @wrqu: ioctl request data
8157 * @extra: ioctl extra data
8158 *
8159 * This is a generic handler for private ioctls which take multiple
8160 * arguments. Note that this implementation is also somewhat unique
8161 * in that it is shared by both STA-mode and SAP-mode interfaces.
8162 *
8163 * Return: 0 on success, non-zero on error
8164 */
8165int iw_set_var_ints_getnone(struct net_device *dev,
8166 struct iw_request_info *info,
8167 union iwreq_data *wrqu, char *extra)
8168{
8169 int ret;
8170
8171 cds_ssr_protect(__func__);
8172 ret = __iw_set_var_ints_getnone(dev, info, wrqu, extra);
8173 cds_ssr_unprotect(__func__);
8174 return ret;
8175}
8176
8177/**
8178 * iw_add_tspec - Add TSpec private ioctl handler
8179 * @dev: device upon which the ioctl was received
8180 * @info: ioctl request information
8181 * @wrqu: ioctl request data
8182 * @extra: ioctl extra data
8183 *
8184 * Return: 0 on success, non-zero on error
8185 */
8186static int __iw_add_tspec(struct net_device *dev, struct iw_request_info *info,
8187 union iwreq_data *wrqu, char *extra)
8188{
8189 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
8190 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
8191 hdd_wlan_wmm_status_e *pStatus = (hdd_wlan_wmm_status_e *) extra;
8192 int params[HDD_WLAN_WMM_PARAM_COUNT];
8193 sme_QosWmmTspecInfo tSpec;
8194 uint32_t handle;
8195 struct iw_point s_priv_data;
8196 hdd_context_t *hdd_ctx;
8197 int ret;
8198
Jeff Johnson6ee91ee2016-02-11 18:55:30 -08008199 ENTER_DEV(dev);
Hanumantha Reddy Pothula2db50ed2015-11-23 10:48:33 +05308200
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008201 hdd_ctx = WLAN_HDD_GET_CTX(pAdapter);
8202 ret = wlan_hdd_validate_context(hdd_ctx);
8203 if (0 != ret)
8204 return ret;
8205
8206 /* make sure the application is sufficiently priviledged */
8207 /* note that the kernel will do this for "set" ioctls, but since */
8208 /* this ioctl wants to return status to user space it must be */
8209 /* defined as a "get" ioctl */
8210 if (!capable(CAP_NET_ADMIN)) {
8211 return -EPERM;
8212 }
8213
8214 /* we must be associated in order to add a tspec */
8215 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState) {
8216 *pStatus = HDD_WLAN_WMM_STATUS_SETUP_FAILED_BAD_PARAM;
8217 return 0;
8218 }
8219 /* since we are defined to be a "get" ioctl, and since the number */
8220 /* of params exceeds the number of params that wireless extensions */
8221 /* will pass down in the iwreq_data, we must copy the "set" params. */
8222 /* We must handle the compat for iwreq_data in 32U/64K environment. */
8223
8224 /* helper function to get iwreq_data with compat handling. */
8225 if (hdd_priv_get_data(&s_priv_data, wrqu)) {
8226 *pStatus = HDD_WLAN_WMM_STATUS_SETUP_FAILED_BAD_PARAM;
8227 return 0;
8228 }
8229 /* make sure all params are correctly passed to function */
8230 if ((NULL == s_priv_data.pointer) ||
8231 (HDD_WLAN_WMM_PARAM_COUNT != s_priv_data.length)) {
8232 *pStatus = HDD_WLAN_WMM_STATUS_SETUP_FAILED_BAD_PARAM;
8233 return 0;
8234 }
8235 /* from user space ourselves */
8236 if (copy_from_user(&params, s_priv_data.pointer, sizeof(params))) {
8237 /* hmmm, can't get them */
8238 return -EIO;
8239 }
8240 /* clear the tspec */
8241 memset(&tSpec, 0, sizeof(tSpec));
8242
8243 /* validate the handle */
8244 handle = params[HDD_WLAN_WMM_PARAM_HANDLE];
8245 if (HDD_WMM_HANDLE_IMPLICIT == handle) {
8246 /* that one is reserved */
8247 *pStatus = HDD_WLAN_WMM_STATUS_SETUP_FAILED_BAD_PARAM;
8248 return 0;
8249 }
8250 /* validate the TID */
8251 if (params[HDD_WLAN_WMM_PARAM_TID] > 7) {
8252 /* out of range */
8253 *pStatus = HDD_WLAN_WMM_STATUS_SETUP_FAILED_BAD_PARAM;
8254 return 0;
8255 }
8256 tSpec.ts_info.tid = params[HDD_WLAN_WMM_PARAM_TID];
8257
8258 /* validate the direction */
8259 switch (params[HDD_WLAN_WMM_PARAM_DIRECTION]) {
8260 case HDD_WLAN_WMM_DIRECTION_UPSTREAM:
8261 tSpec.ts_info.direction = SME_QOS_WMM_TS_DIR_UPLINK;
8262 break;
8263
8264 case HDD_WLAN_WMM_DIRECTION_DOWNSTREAM:
8265 tSpec.ts_info.direction = SME_QOS_WMM_TS_DIR_DOWNLINK;
8266 break;
8267
8268 case HDD_WLAN_WMM_DIRECTION_BIDIRECTIONAL:
8269 tSpec.ts_info.direction = SME_QOS_WMM_TS_DIR_BOTH;
8270 break;
8271
8272 default:
8273 /* unknown */
8274 *pStatus = HDD_WLAN_WMM_STATUS_SETUP_FAILED_BAD_PARAM;
8275 return 0;
8276 }
8277
8278 tSpec.ts_info.psb = params[HDD_WLAN_WMM_PARAM_APSD];
8279
8280 /* validate the user priority */
8281 if (params[HDD_WLAN_WMM_PARAM_USER_PRIORITY] >= SME_QOS_WMM_UP_MAX) {
8282 /* out of range */
8283 *pStatus = HDD_WLAN_WMM_STATUS_SETUP_FAILED_BAD_PARAM;
8284 return 0;
8285 }
8286 tSpec.ts_info.up = params[HDD_WLAN_WMM_PARAM_USER_PRIORITY];
8287 if (0 > tSpec.ts_info.up || SME_QOS_WMM_UP_MAX < tSpec.ts_info.up) {
Jeff Johnson99bac312016-06-28 10:38:18 -07008288 hdd_err("***ts_info.up out of bounds***");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008289 return 0;
8290 }
8291
Jeff Johnson99bac312016-06-28 10:38:18 -07008292 hdd_info("TS_INFO PSB %d UP %d !!!",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008293 tSpec.ts_info.psb, tSpec.ts_info.up);
8294
8295 tSpec.nominal_msdu_size = params[HDD_WLAN_WMM_PARAM_NOMINAL_MSDU_SIZE];
8296 tSpec.maximum_msdu_size = params[HDD_WLAN_WMM_PARAM_MAXIMUM_MSDU_SIZE];
8297 tSpec.min_data_rate = params[HDD_WLAN_WMM_PARAM_MINIMUM_DATA_RATE];
8298 tSpec.mean_data_rate = params[HDD_WLAN_WMM_PARAM_MEAN_DATA_RATE];
8299 tSpec.peak_data_rate = params[HDD_WLAN_WMM_PARAM_PEAK_DATA_RATE];
8300 tSpec.max_burst_size = params[HDD_WLAN_WMM_PARAM_MAX_BURST_SIZE];
8301 tSpec.min_phy_rate = params[HDD_WLAN_WMM_PARAM_MINIMUM_PHY_RATE];
8302 tSpec.surplus_bw_allowance =
8303 params[HDD_WLAN_WMM_PARAM_SURPLUS_BANDWIDTH_ALLOWANCE];
8304 tSpec.min_service_interval =
8305 params[HDD_WLAN_WMM_PARAM_SERVICE_INTERVAL];
8306 tSpec.max_service_interval =
8307 params[HDD_WLAN_WMM_PARAM_MAX_SERVICE_INTERVAL];
8308 tSpec.suspension_interval =
8309 params[HDD_WLAN_WMM_PARAM_SUSPENSION_INTERVAL];
8310 tSpec.inactivity_interval =
8311 params[HDD_WLAN_WMM_PARAM_INACTIVITY_INTERVAL];
8312
8313 tSpec.ts_info.burst_size_defn =
8314 params[HDD_WLAN_WMM_PARAM_BURST_SIZE_DEFN];
8315
8316 /* validate the ts info ack policy */
8317 switch (params[HDD_WLAN_WMM_PARAM_ACK_POLICY]) {
8318 case HDD_WLAN_WMM_TS_INFO_ACK_POLICY_NORMAL_ACK:
8319 tSpec.ts_info.ack_policy = SME_QOS_WMM_TS_ACK_POLICY_NORMAL_ACK;
8320 break;
8321
8322 case HDD_WLAN_WMM_TS_INFO_ACK_POLICY_HT_IMMEDIATE_BLOCK_ACK:
8323 tSpec.ts_info.ack_policy =
8324 SME_QOS_WMM_TS_ACK_POLICY_HT_IMMEDIATE_BLOCK_ACK;
8325 break;
8326
8327 default:
8328 /* unknown */
8329 *pStatus = HDD_WLAN_WMM_STATUS_SETUP_FAILED_BAD_PARAM;
8330 return 0;
8331 }
8332
8333 *pStatus = hdd_wmm_addts(pAdapter, handle, &tSpec);
Hanumantha Reddy Pothula2db50ed2015-11-23 10:48:33 +05308334 EXIT();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008335 return 0;
8336}
8337
8338static int iw_add_tspec(struct net_device *dev,
8339 struct iw_request_info *info,
8340 union iwreq_data *wrqu, char *extra)
8341{
8342 int ret;
8343
8344 cds_ssr_protect(__func__);
8345 ret = __iw_add_tspec(dev, info, wrqu, extra);
8346 cds_ssr_unprotect(__func__);
8347
8348 return ret;
8349}
8350
8351/**
8352 * iw_del_tspec - Delete TSpec private ioctl handler
8353 * @dev: device upon which the ioctl was received
8354 * @info: ioctl request information
8355 * @wrqu: ioctl request data
8356 * @extra: ioctl extra data
8357 *
8358 * Return: 0 on success, non-zero on error
8359 */
8360static int __iw_del_tspec(struct net_device *dev, struct iw_request_info *info,
8361 union iwreq_data *wrqu, char *extra)
8362{
8363 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
8364 hdd_context_t *hdd_ctx;
8365 int *params = (int *)extra;
8366 hdd_wlan_wmm_status_e *pStatus = (hdd_wlan_wmm_status_e *) extra;
8367 uint32_t handle;
8368 int ret;
8369
Jeff Johnson6ee91ee2016-02-11 18:55:30 -08008370 ENTER_DEV(dev);
Hanumantha Reddy Pothula2db50ed2015-11-23 10:48:33 +05308371
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008372 hdd_ctx = WLAN_HDD_GET_CTX(pAdapter);
8373 ret = wlan_hdd_validate_context(hdd_ctx);
8374 if (0 != ret)
8375 return ret;
8376
8377 /* make sure the application is sufficiently priviledged */
8378 /* note that the kernel will do this for "set" ioctls, but since */
8379 /* this ioctl wants to return status to user space it must be */
8380 /* defined as a "get" ioctl */
8381 if (!capable(CAP_NET_ADMIN)) {
8382 return -EPERM;
8383 }
8384
8385 /* although we are defined to be a "get" ioctl, the params we require */
8386 /* will fit in the iwreq_data, therefore unlike iw_add_tspec() there */
8387 /* is no need to copy the params from user space */
8388
8389 /* validate the handle */
8390 handle = params[HDD_WLAN_WMM_PARAM_HANDLE];
8391 if (HDD_WMM_HANDLE_IMPLICIT == handle) {
8392 /* that one is reserved */
8393 *pStatus = HDD_WLAN_WMM_STATUS_SETUP_FAILED_BAD_PARAM;
8394 return 0;
8395 }
8396
8397 *pStatus = hdd_wmm_delts(pAdapter, handle);
Hanumantha Reddy Pothula2db50ed2015-11-23 10:48:33 +05308398 EXIT();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008399 return 0;
8400}
8401
8402static int iw_del_tspec(struct net_device *dev,
8403 struct iw_request_info *info,
8404 union iwreq_data *wrqu, char *extra)
8405{
8406 int ret;
8407
8408 cds_ssr_protect(__func__);
8409 ret = __iw_del_tspec(dev, info, wrqu, extra);
8410 cds_ssr_unprotect(__func__);
8411
8412 return ret;
8413}
8414
8415/**
8416 * iw_get_tspec - Get TSpec private ioctl handler
8417 * @dev: device upon which the ioctl was received
8418 * @info: ioctl request information
8419 * @wrqu: ioctl request data
8420 * @extra: ioctl extra data
8421 *
8422 * Return: 0 on success, non-zero on error
8423 */
8424static int __iw_get_tspec(struct net_device *dev, struct iw_request_info *info,
8425 union iwreq_data *wrqu, char *extra)
8426{
8427 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
8428 hdd_context_t *hdd_ctx;
8429 int *params = (int *)extra;
8430 hdd_wlan_wmm_status_e *pStatus = (hdd_wlan_wmm_status_e *) extra;
8431 uint32_t handle;
8432 int ret;
8433
Jeff Johnson6ee91ee2016-02-11 18:55:30 -08008434 ENTER_DEV(dev);
Hanumantha Reddy Pothula2db50ed2015-11-23 10:48:33 +05308435
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008436 hdd_ctx = WLAN_HDD_GET_CTX(pAdapter);
8437 ret = wlan_hdd_validate_context(hdd_ctx);
8438 if (0 != ret)
8439 return ret;
8440
8441 /* although we are defined to be a "get" ioctl, the params we require */
8442 /* will fit in the iwreq_data, therefore unlike iw_add_tspec() there */
8443 /* is no need to copy the params from user space */
8444
8445 /* validate the handle */
8446 handle = params[HDD_WLAN_WMM_PARAM_HANDLE];
8447 if (HDD_WMM_HANDLE_IMPLICIT == handle) {
8448 /* that one is reserved */
8449 *pStatus = HDD_WLAN_WMM_STATUS_SETUP_FAILED_BAD_PARAM;
8450 return 0;
8451 }
8452
8453 *pStatus = hdd_wmm_checkts(pAdapter, handle);
Hanumantha Reddy Pothula2db50ed2015-11-23 10:48:33 +05308454 EXIT();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008455 return 0;
8456}
8457
8458static int iw_get_tspec(struct net_device *dev,
8459 struct iw_request_info *info,
8460 union iwreq_data *wrqu, char *extra)
8461{
8462 int ret;
8463
8464 cds_ssr_protect(__func__);
8465 ret = __iw_get_tspec(dev, info, wrqu, extra);
8466 cds_ssr_unprotect(__func__);
8467
8468 return ret;
8469}
8470
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008471/**
8472 * iw_set_fties - Set FT IEs private ioctl handler
8473 * @dev: device upon which the ioctl was received
8474 * @info: ioctl request information
8475 * @wrqu: ioctl request data
8476 * @extra: ioctl extra data
8477 *
8478 * Each time the supplicant has the auth_request or reassoc request
8479 * IEs ready they are pushed to the driver. The driver will in turn
8480 * use it to send out the auth req and reassoc req for 11r FT Assoc.
8481 *
8482 * Return: 0 on success, non-zero on error
8483 */
8484static int __iw_set_fties(struct net_device *dev, struct iw_request_info *info,
8485 union iwreq_data *wrqu, char *extra)
8486{
8487 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
8488 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
8489 hdd_context_t *hdd_ctx;
8490 int ret;
8491
Jeff Johnson6ee91ee2016-02-11 18:55:30 -08008492 ENTER_DEV(dev);
Hanumantha Reddy Pothula2db50ed2015-11-23 10:48:33 +05308493
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008494 hdd_ctx = WLAN_HDD_GET_CTX(pAdapter);
8495 ret = wlan_hdd_validate_context(hdd_ctx);
8496 if (0 != ret)
8497 return ret;
8498
8499 if (!wrqu->data.length) {
Jeff Johnson99bac312016-06-28 10:38:18 -07008500 hdd_err("called with 0 length IEs");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008501 return -EINVAL;
8502 }
8503 if (wrqu->data.pointer == NULL) {
Jeff Johnson99bac312016-06-28 10:38:18 -07008504 hdd_err("called with NULL IE");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008505 return -EINVAL;
8506 }
8507 /* Added for debug on reception of Re-assoc Req. */
8508 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState) {
Jeff Johnson99bac312016-06-28 10:38:18 -07008509 hdd_err("Called with Ie of length = %d when not associated",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008510 wrqu->data.length);
Jeff Johnson99bac312016-06-28 10:38:18 -07008511 hdd_err("Should be Re-assoc Req IEs");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008512 }
Jeff Johnson99bac312016-06-28 10:38:18 -07008513 hdd_notice("called with Ie of length = %d", wrqu->data.length);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008514
8515 /* Pass the received FT IEs to SME */
8516 sme_set_ft_ies(WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
8517 extra, wrqu->data.length);
Hanumantha Reddy Pothula2db50ed2015-11-23 10:48:33 +05308518 EXIT();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008519 return 0;
8520}
8521
8522static int iw_set_fties(struct net_device *dev,
8523 struct iw_request_info *info,
8524 union iwreq_data *wrqu, char *extra)
8525{
8526 int ret;
8527
8528 cds_ssr_protect(__func__);
8529 ret = __iw_set_fties(dev, info, wrqu, extra);
8530 cds_ssr_unprotect(__func__);
8531
8532 return ret;
8533}
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008534
8535/**
8536 * iw_set_host_offload - Set host offload ioctl handler
8537 * @dev: device upon which the ioctl was received
8538 * @info: ioctl request information
8539 * @wrqu: ioctl request data
8540 * @extra: ioctl extra data
8541 *
8542 * Return: 0 on success, non-zero on error
8543 */
8544static int __iw_set_host_offload(struct net_device *dev,
8545 struct iw_request_info *info,
8546 union iwreq_data *wrqu, char *extra)
8547{
8548 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
8549 tpHostOffloadRequest pRequest = (tpHostOffloadRequest) extra;
8550 tSirHostOffloadReq offloadRequest;
8551 hdd_context_t *hdd_ctx;
8552 int ret;
8553
Jeff Johnson6ee91ee2016-02-11 18:55:30 -08008554 ENTER_DEV(dev);
Hanumantha Reddy Pothula2db50ed2015-11-23 10:48:33 +05308555
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008556 hdd_ctx = WLAN_HDD_GET_CTX(pAdapter);
8557 ret = wlan_hdd_validate_context(hdd_ctx);
8558 if (0 != ret)
8559 return ret;
8560
8561 if (!hdd_conn_is_connected(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))) {
Jeff Johnson99bac312016-06-28 10:38:18 -07008562 hdd_err("dev is not in CONNECTED state, ignore!!!");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008563 return -EINVAL;
8564 }
8565
8566 /* Debug display of request components. */
8567 switch (pRequest->offloadType) {
8568 case WLAN_IPV4_ARP_REPLY_OFFLOAD:
Jeff Johnson99bac312016-06-28 10:38:18 -07008569 hdd_warn("Host offload request: ARP reply");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008570 switch (pRequest->enableOrDisable) {
8571 case WLAN_OFFLOAD_DISABLE:
Jeff Johnson99bac312016-06-28 10:38:18 -07008572 hdd_warn(" disable");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008573 break;
8574 case WLAN_OFFLOAD_ARP_AND_BC_FILTER_ENABLE:
Jeff Johnson99bac312016-06-28 10:38:18 -07008575 hdd_warn(" BC Filtering enable");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008576 case WLAN_OFFLOAD_ENABLE:
Jeff Johnson99bac312016-06-28 10:38:18 -07008577 hdd_warn(" ARP offload enable");
8578 hdd_warn(" IP address: %d.%d.%d.%d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008579 pRequest->params.hostIpv4Addr[0],
8580 pRequest->params.hostIpv4Addr[1],
8581 pRequest->params.hostIpv4Addr[2],
8582 pRequest->params.hostIpv4Addr[3]);
8583 }
8584 break;
8585
8586 case WLAN_IPV6_NEIGHBOR_DISCOVERY_OFFLOAD:
Jeff Johnson99bac312016-06-28 10:38:18 -07008587 hdd_info("Host offload request: neighbor discovery");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008588 switch (pRequest->enableOrDisable) {
8589 case WLAN_OFFLOAD_DISABLE:
Jeff Johnson99bac312016-06-28 10:38:18 -07008590 hdd_info(" disable");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008591 break;
8592 case WLAN_OFFLOAD_ENABLE:
Jeff Johnson99bac312016-06-28 10:38:18 -07008593 hdd_info(" enable");
8594 hdd_info(" IP address: %x:%x:%x:%x:%x:%x:%x:%x",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008595 *(uint16_t *) (pRequest->params.hostIpv6Addr),
8596 *(uint16_t *) (pRequest->params.hostIpv6Addr +
8597 2),
8598 *(uint16_t *) (pRequest->params.hostIpv6Addr +
8599 4),
8600 *(uint16_t *) (pRequest->params.hostIpv6Addr +
8601 6),
8602 *(uint16_t *) (pRequest->params.hostIpv6Addr +
8603 8),
8604 *(uint16_t *) (pRequest->params.hostIpv6Addr +
8605 10),
8606 *(uint16_t *) (pRequest->params.hostIpv6Addr +
8607 12),
8608 *(uint16_t *) (pRequest->params.hostIpv6Addr +
8609 14));
8610 }
8611 }
8612
8613 /* Execute offload request. The reason that we can copy the
8614 * request information from the ioctl structure to the SME
8615 * structure is that they are laid out exactly the same.
8616 * Otherwise, each piece of information would have to be
8617 * copied individually.
8618 */
8619 memcpy(&offloadRequest, pRequest, wrqu->data.length);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05308620 if (QDF_STATUS_SUCCESS !=
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008621 sme_set_host_offload(WLAN_HDD_GET_HAL_CTX(pAdapter),
8622 pAdapter->sessionId, &offloadRequest)) {
Jeff Johnson99bac312016-06-28 10:38:18 -07008623 hdd_err("Failure to execute host offload request");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008624 return -EINVAL;
8625 }
Hanumantha Reddy Pothula2db50ed2015-11-23 10:48:33 +05308626 EXIT();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008627 return 0;
8628}
8629
8630static int iw_set_host_offload(struct net_device *dev,
8631 struct iw_request_info *info,
8632 union iwreq_data *wrqu, char *extra)
8633{
8634 int ret;
8635
8636 cds_ssr_protect(__func__);
8637 ret = __iw_set_host_offload(dev, info, wrqu, extra);
8638 cds_ssr_unprotect(__func__);
8639
8640 return ret;
8641}
8642
8643/**
8644 * iw_set_keepalive_params - Set keepalive params ioctl handler
8645 * @dev: device upon which the ioctl was received
8646 * @info: ioctl request information
8647 * @wrqu: ioctl request data
8648 * @extra: ioctl extra data
8649 *
8650 * Return: 0 on success, non-zero on error
8651 */
8652static int __iw_set_keepalive_params(struct net_device *dev,
8653 struct iw_request_info *info,
8654 union iwreq_data *wrqu, char *extra)
8655{
8656 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Rajeev Kumar3ddf1c62015-11-03 14:10:13 -08008657 tpSirKeepAliveReq request = (tpSirKeepAliveReq) extra;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008658 hdd_context_t *hdd_ctx;
8659 int ret;
8660
Jeff Johnson6ee91ee2016-02-11 18:55:30 -08008661 ENTER_DEV(dev);
Hanumantha Reddy Pothula2db50ed2015-11-23 10:48:33 +05308662
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008663 hdd_ctx = WLAN_HDD_GET_CTX(pAdapter);
8664 ret = wlan_hdd_validate_context(hdd_ctx);
8665 if (0 != ret)
8666 return ret;
8667
Rajeev Kumar3ddf1c62015-11-03 14:10:13 -08008668 if (wrqu->data.length != sizeof(*request)) {
8669 hdd_err("Invalid length %d", wrqu->data.length);
8670 return -EINVAL;
8671 }
8672
8673 if (request->timePeriod > WNI_CFG_INFRA_STA_KEEP_ALIVE_PERIOD_STAMAX) {
8674 hdd_err("Value of timePeriod %d exceed Max limit %d",
8675 request->timePeriod,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008676 WNI_CFG_INFRA_STA_KEEP_ALIVE_PERIOD_STAMAX);
8677 return -EINVAL;
8678 }
8679
8680 /* Debug display of request components. */
Rajeev Kumar3ddf1c62015-11-03 14:10:13 -08008681 hdd_info("Set Keep Alive Request : TimePeriod %d size %zu",
8682 request->timePeriod, sizeof(tSirKeepAliveReq));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008683
Rajeev Kumar3ddf1c62015-11-03 14:10:13 -08008684 switch (request->packetType) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008685 case WLAN_KEEP_ALIVE_NULL_PKT:
Rajeev Kumar3ddf1c62015-11-03 14:10:13 -08008686 hdd_info("Keep Alive Request: Tx NULL");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008687 break;
8688
8689 case WLAN_KEEP_ALIVE_UNSOLICIT_ARP_RSP:
Rajeev Kumar3ddf1c62015-11-03 14:10:13 -08008690 hdd_info("Keep Alive Request: Tx UnSolicited ARP RSP");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008691
Rajeev Kumar3ddf1c62015-11-03 14:10:13 -08008692 hdd_info("Host IP address: %d.%d.%d.%d",
8693 request->hostIpv4Addr[0], request->hostIpv4Addr[1],
8694 request->hostIpv4Addr[2], request->hostIpv4Addr[3]);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008695
Rajeev Kumar3ddf1c62015-11-03 14:10:13 -08008696 hdd_info("Dest IP address: %d.%d.%d.%d",
8697 request->destIpv4Addr[0], request->destIpv4Addr[1],
8698 request->destIpv4Addr[2], request->destIpv4Addr[3]);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008699
Srinivas Girigowda9c330a92015-11-24 12:28:25 -08008700 hdd_info("Dest MAC address: "MAC_ADDRESS_STR,
8701 MAC_ADDR_ARRAY(request->dest_macaddr.bytes));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008702 break;
8703 }
8704
Rajeev Kumar3ddf1c62015-11-03 14:10:13 -08008705 hdd_info("Keep alive period %d", request->timePeriod);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008706
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05308707 if (QDF_STATUS_SUCCESS !=
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008708 sme_set_keep_alive(WLAN_HDD_GET_HAL_CTX(pAdapter),
Rajeev Kumar3ddf1c62015-11-03 14:10:13 -08008709 pAdapter->sessionId, request)) {
8710 hdd_err("Failure to execute Keep Alive");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008711 return -EINVAL;
8712 }
Hanumantha Reddy Pothula2db50ed2015-11-23 10:48:33 +05308713 EXIT();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008714 return 0;
8715}
8716
8717static int iw_set_keepalive_params(struct net_device *dev,
8718 struct iw_request_info *info,
8719 union iwreq_data *wrqu,
8720 char *extra)
8721{
8722 int ret;
8723
8724 cds_ssr_protect(__func__);
8725 ret = __iw_set_keepalive_params(dev, info, wrqu, extra);
8726 cds_ssr_unprotect(__func__);
8727
8728 return ret;
8729}
8730
8731#ifdef WLAN_FEATURE_PACKET_FILTERING
8732/**
8733 * wlan_hdd_set_filter() - Set packet filter
8734 * @hdd_ctx: Global HDD context
8735 * @request: Packet filter request struct
8736 * @sessionId: Target session for the request
8737 *
8738 * Return: 0 on success, non-zero on error
8739 */
8740static int wlan_hdd_set_filter(hdd_context_t *hdd_ctx,
8741 struct pkt_filter_cfg *request,
8742 uint8_t sessionId)
8743{
8744 tSirRcvPktFilterCfgType packetFilterSetReq = {0};
8745 tSirRcvFltPktClearParam packetFilterClrReq = {0};
8746 int i = 0;
8747
8748 if (hdd_ctx->config->disablePacketFilter) {
8749 hdd_err("packet filtering disabled in ini returning");
8750 return 0;
8751 }
8752
8753 /* Debug display of request components. */
8754 hdd_info("Packet Filter Request : FA %d params %d",
8755 request->filter_action, request->num_params);
8756
8757 switch (request->filter_action) {
8758 case HDD_RCV_FILTER_SET:
8759 hdd_info("Set Packet Filter Request for Id: %d",
8760 request->filter_id);
8761
8762 packetFilterSetReq.filterId = request->filter_id;
8763 if (request->num_params >= HDD_MAX_CMP_PER_PACKET_FILTER) {
8764 hdd_err("Number of Params exceed Max limit %d",
8765 request->num_params);
8766 return -EINVAL;
8767 }
8768 packetFilterSetReq.numFieldParams = request->num_params;
8769 packetFilterSetReq.coalesceTime = 0;
8770 packetFilterSetReq.filterType = HDD_RCV_FILTER_SET;
8771 for (i = 0; i < request->num_params; i++) {
8772 packetFilterSetReq.paramsData[i].protocolLayer =
8773 request->params_data[i].protocol_layer;
8774 packetFilterSetReq.paramsData[i].cmpFlag =
8775 request->params_data[i].compare_flag;
8776 packetFilterSetReq.paramsData[i].dataOffset =
8777 request->params_data[i].data_offset;
8778 packetFilterSetReq.paramsData[i].dataLength =
8779 request->params_data[i].data_length;
8780 packetFilterSetReq.paramsData[i].reserved = 0;
8781
8782 if (request->params_data[i].data_length >
8783 SIR_MAX_FILTER_TEST_DATA_LEN) {
8784 hdd_err("Error invalid data length %d",
8785 request->params_data[i].data_length);
8786 return -EINVAL;
8787 }
8788
8789 hdd_info("Proto %d Comp Flag %d Filter Type %d",
8790 request->params_data[i].protocol_layer,
8791 request->params_data[i].compare_flag,
8792 packetFilterSetReq.filterType);
8793
8794 hdd_info("Data Offset %d Data Len %d",
8795 request->params_data[i].data_offset,
8796 request->params_data[i].data_length);
8797
Rajeev Kumarf5b6da22016-04-15 13:24:03 -07008798 if (sizeof(packetFilterSetReq.paramsData[i].compareData)
8799 < (request->params_data[i].data_length)) {
8800 hdd_err("Error invalid data length %d",
8801 request->params_data[i].data_length);
8802 return -EINVAL;
8803 }
8804
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008805 memcpy(&packetFilterSetReq.paramsData[i].compareData,
8806 request->params_data[i].compare_data,
8807 request->params_data[i].data_length);
8808 memcpy(&packetFilterSetReq.paramsData[i].dataMask,
8809 request->params_data[i].data_mask,
8810 request->params_data[i].data_length);
8811
8812 hdd_info("CData %d CData %d CData %d CData %d CData %d CData %d",
8813 request->params_data[i].compare_data[0],
8814 request->params_data[i].compare_data[1],
8815 request->params_data[i].compare_data[2],
8816 request->params_data[i].compare_data[3],
8817 request->params_data[i].compare_data[4],
8818 request->params_data[i].compare_data[5]);
8819
8820 hdd_info("MData %d MData %d MData %d MData %d MData %d MData %d",
8821 request->params_data[i].data_mask[0],
8822 request->params_data[i].data_mask[1],
8823 request->params_data[i].data_mask[2],
8824 request->params_data[i].data_mask[3],
8825 request->params_data[i].data_mask[4],
8826 request->params_data[i].data_mask[5]);
8827 }
8828
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05308829 if (QDF_STATUS_SUCCESS !=
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008830 sme_receive_filter_set_filter(hdd_ctx->hHal,
8831 &packetFilterSetReq,
8832 sessionId)) {
8833 hdd_err("Failure to execute Set Filter");
8834 return -EINVAL;
8835 }
8836
8837 break;
8838
8839 case HDD_RCV_FILTER_CLEAR:
8840
8841 hdd_info("Clear Packet Filter Request for Id: %d",
8842 request->filter_id);
8843 packetFilterClrReq.filterId = request->filter_id;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05308844 if (QDF_STATUS_SUCCESS !=
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008845 sme_receive_filter_clear_filter(hdd_ctx->hHal,
8846 &packetFilterClrReq,
8847 sessionId)) {
8848 hdd_err("Failure to execute Clear Filter");
8849 return -EINVAL;
8850 }
8851 break;
8852
8853 default:
8854 hdd_err("Packet Filter Request: Invalid %d",
8855 request->filter_action);
8856 return -EINVAL;
8857 }
8858 return 0;
8859}
8860
8861/**
8862 * __iw_set_packet_filter_params() - set packet filter parameters in target
8863 * @dev: Pointer to netdev
8864 * @info: Pointer to iw request info
8865 * @wrqu: Pointer to data
8866 * @extra: Pointer to extra data
8867 *
8868 * Return: 0 on success, non-zero on error
8869 */
8870static int __iw_set_packet_filter_params(struct net_device *dev,
8871 struct iw_request_info *info,
8872 union iwreq_data *wrqu, char *extra)
8873{
8874 int ret;
8875 hdd_context_t *hdd_ctx;
8876 struct iw_point priv_data;
8877 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
8878 struct pkt_filter_cfg *request = NULL;
8879
Mukul Sharma472382f2015-11-02 20:16:31 +05308880 if (!capable(CAP_NET_ADMIN)) {
Jeff Johnson99bac312016-06-28 10:38:18 -07008881 hdd_err("permission check failed");
Mukul Sharma472382f2015-11-02 20:16:31 +05308882 return -EPERM;
8883 }
8884
Jeff Johnson6ee91ee2016-02-11 18:55:30 -08008885 ENTER_DEV(dev);
Hanumantha Reddy Pothula2db50ed2015-11-23 10:48:33 +05308886
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008887 hdd_ctx = WLAN_HDD_GET_CTX(adapter);
8888 ret = wlan_hdd_validate_context(hdd_ctx);
8889 if (0 != ret)
8890 return ret;
8891
8892 if (hdd_priv_get_data(&priv_data, wrqu)) {
8893 hdd_err("failed to get priv data");
8894 return -EINVAL;
8895 }
8896
8897 if ((NULL == priv_data.pointer) || (0 == priv_data.length)) {
8898 hdd_err("invalid priv data %p or invalid priv data length %d",
8899 priv_data.pointer, priv_data.length);
8900 return -EINVAL;
8901 }
8902
8903 /* copy data using copy_from_user */
8904 request = mem_alloc_copy_from_user_helper(priv_data.pointer,
8905 priv_data.length);
8906 if (NULL == request) {
8907 hdd_err("mem_alloc_copy_from_user_helper fail");
8908 return -ENOMEM;
8909 }
8910
8911 ret = wlan_hdd_set_filter(hdd_ctx, request, adapter->sessionId);
8912
8913 kfree(request);
Hanumantha Reddy Pothula2db50ed2015-11-23 10:48:33 +05308914 EXIT();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008915 return ret;
8916}
8917
8918/**
8919 * iw_set_packet_filter_params() - set packet filter parameters in target
8920 * @dev: Pointer to netdev
8921 * @info: Pointer to iw request info
8922 * @wrqu: Pointer to data
8923 * @extra: Pointer to extra data
8924 *
8925 * Return: 0 on success, non-zero on error
8926 */
8927static int iw_set_packet_filter_params(struct net_device *dev,
8928 struct iw_request_info *info,
8929 union iwreq_data *wrqu, char *extra)
8930{
8931 int ret;
8932
8933 cds_ssr_protect(__func__);
8934 ret = __iw_set_packet_filter_params(dev, info, wrqu, extra);
8935 cds_ssr_unprotect(__func__);
8936
8937 return ret;
8938}
8939#endif
8940
8941
8942static int __iw_get_statistics(struct net_device *dev,
8943 struct iw_request_info *info,
8944 union iwreq_data *wrqu, char *extra)
8945{
8946
Anurag Chouhance0dc992016-02-16 18:18:03 +05308947 QDF_STATUS qdf_status = QDF_STATUS_SUCCESS;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05308948 QDF_STATUS status = QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008949 hdd_wext_state_t *pWextState;
8950 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
8951 hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(pAdapter);
8952 char *p = extra;
8953 int tlen = 0;
8954 tCsrSummaryStatsInfo *pStats = &(pAdapter->hdd_stats.summary_stat);
8955 tCsrGlobalClassAStatsInfo *aStats = &(pAdapter->hdd_stats.ClassA_stat);
8956 tCsrGlobalClassDStatsInfo *dStats = &(pAdapter->hdd_stats.ClassD_stat);
8957 int ret;
8958
Jeff Johnson6ee91ee2016-02-11 18:55:30 -08008959 ENTER_DEV(dev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008960
8961 ret = wlan_hdd_validate_context(hdd_ctx);
8962 if (0 != ret)
8963 return ret;
8964
8965 if (eConnectionState_Associated !=
8966 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState) {
8967
8968 wrqu->txpower.value = 0;
8969 } else {
8970 status = sme_get_statistics(hdd_ctx->hHal, eCSR_HDD,
8971 SME_SUMMARY_STATS |
8972 SME_GLOBAL_CLASSA_STATS |
8973 SME_GLOBAL_CLASSB_STATS |
8974 SME_GLOBAL_CLASSC_STATS |
8975 SME_GLOBAL_CLASSD_STATS |
8976 SME_PER_STA_STATS,
8977 hdd_statistics_cb, 0, false,
8978 (WLAN_HDD_GET_STATION_CTX_PTR
8979 (pAdapter))->conn_info.staId[0],
8980 pAdapter, pAdapter->sessionId);
8981
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05308982 if (QDF_STATUS_SUCCESS != status) {
Jeff Johnson99bac312016-06-28 10:38:18 -07008983 hdd_err("Unable to retrieve SME statistics");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008984 return -EINVAL;
8985 }
8986
8987 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
8988
Anurag Chouhance0dc992016-02-16 18:18:03 +05308989 qdf_status =
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05308990 qdf_wait_single_event(&pWextState->hdd_qdf_event,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008991 WLAN_WAIT_TIME_STATS);
Anurag Chouhance0dc992016-02-16 18:18:03 +05308992 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Jeff Johnson99bac312016-06-28 10:38:18 -07008993 hdd_err("SME timeout while retrieving statistics");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008994 /*Remove the SME statistics list by passing NULL in callback argument */
8995 status = sme_get_statistics(hdd_ctx->hHal, eCSR_HDD,
8996 SME_SUMMARY_STATS |
8997 SME_GLOBAL_CLASSA_STATS |
8998 SME_GLOBAL_CLASSB_STATS |
8999 SME_GLOBAL_CLASSC_STATS |
9000 SME_GLOBAL_CLASSD_STATS |
9001 SME_PER_STA_STATS,
9002 NULL, 0, false,
9003 (WLAN_HDD_GET_STATION_CTX_PTR
9004 (pAdapter))->conn_info.
9005 staId[0], pAdapter,
9006 pAdapter->sessionId);
9007
9008 return -EINVAL;
9009 }
9010 FILL_TLV(p, (uint8_t) WLAN_STATS_RETRY_CNT,
9011 (uint8_t) sizeof(pStats->retry_cnt),
9012 (char *)&(pStats->retry_cnt[0]), tlen);
9013
9014 FILL_TLV(p, (uint8_t) WLAN_STATS_MUL_RETRY_CNT,
9015 (uint8_t) sizeof(pStats->multiple_retry_cnt),
9016 (char *)&(pStats->multiple_retry_cnt[0]), tlen);
9017
9018 FILL_TLV(p, (uint8_t) WLAN_STATS_TX_FRM_CNT,
9019 (uint8_t) sizeof(pStats->tx_frm_cnt),
9020 (char *)&(pStats->tx_frm_cnt[0]), tlen);
9021
9022 FILL_TLV(p, (uint8_t) WLAN_STATS_RX_FRM_CNT,
9023 (uint8_t) sizeof(pStats->rx_frm_cnt),
9024 (char *)&(pStats->rx_frm_cnt), tlen);
9025
9026 FILL_TLV(p, (uint8_t) WLAN_STATS_FRM_DUP_CNT,
9027 (uint8_t) sizeof(pStats->frm_dup_cnt),
9028 (char *)&(pStats->frm_dup_cnt), tlen);
9029
9030 FILL_TLV(p, (uint8_t) WLAN_STATS_FAIL_CNT,
9031 (uint8_t) sizeof(pStats->fail_cnt),
9032 (char *)&(pStats->fail_cnt[0]), tlen);
9033
9034 FILL_TLV(p, (uint8_t) WLAN_STATS_RTS_FAIL_CNT,
9035 (uint8_t) sizeof(pStats->rts_fail_cnt),
9036 (char *)&(pStats->rts_fail_cnt), tlen);
9037
9038 FILL_TLV(p, (uint8_t) WLAN_STATS_ACK_FAIL_CNT,
9039 (uint8_t) sizeof(pStats->ack_fail_cnt),
9040 (char *)&(pStats->ack_fail_cnt), tlen);
9041
9042 FILL_TLV(p, (uint8_t) WLAN_STATS_RTS_SUC_CNT,
9043 (uint8_t) sizeof(pStats->rts_succ_cnt),
9044 (char *)&(pStats->rts_succ_cnt), tlen);
9045
9046 FILL_TLV(p, (uint8_t) WLAN_STATS_RX_DISCARD_CNT,
9047 (uint8_t) sizeof(pStats->rx_discard_cnt),
9048 (char *)&(pStats->rx_discard_cnt), tlen);
9049
9050 FILL_TLV(p, (uint8_t) WLAN_STATS_RX_ERROR_CNT,
9051 (uint8_t) sizeof(pStats->rx_error_cnt),
9052 (char *)&(pStats->rx_error_cnt), tlen);
9053
9054 FILL_TLV(p, (uint8_t) WLAN_STATS_TX_BYTE_CNT,
9055 (uint8_t) sizeof(dStats->tx_uc_byte_cnt[0]),
9056 (char *)&(dStats->tx_uc_byte_cnt[0]), tlen);
9057
9058 FILL_TLV(p, (uint8_t) WLAN_STATS_RX_BYTE_CNT,
9059 (uint8_t) sizeof(dStats->rx_byte_cnt),
9060 (char *)&(dStats->rx_byte_cnt), tlen);
9061
9062 FILL_TLV(p, (uint8_t) WLAN_STATS_RX_RATE,
9063 (uint8_t) sizeof(dStats->rx_rate),
9064 (char *)&(dStats->rx_rate), tlen);
9065
9066 /* Transmit rate, in units of 500 kbit/sec */
9067 FILL_TLV(p, (uint8_t) WLAN_STATS_TX_RATE,
9068 (uint8_t) sizeof(aStats->tx_rate),
9069 (char *)&(aStats->tx_rate), tlen);
9070
9071 FILL_TLV(p, (uint8_t) WLAN_STATS_RX_UC_BYTE_CNT,
9072 (uint8_t) sizeof(dStats->rx_uc_byte_cnt[0]),
9073 (char *)&(dStats->rx_uc_byte_cnt[0]), tlen);
9074 FILL_TLV(p, (uint8_t) WLAN_STATS_RX_MC_BYTE_CNT,
9075 (uint8_t) sizeof(dStats->rx_mc_byte_cnt),
9076 (char *)&(dStats->rx_mc_byte_cnt), tlen);
9077 FILL_TLV(p, (uint8_t) WLAN_STATS_RX_BC_BYTE_CNT,
9078 (uint8_t) sizeof(dStats->rx_bc_byte_cnt),
9079 (char *)&(dStats->rx_bc_byte_cnt), tlen);
9080 FILL_TLV(p, (uint8_t) WLAN_STATS_TX_UC_BYTE_CNT,
9081 (uint8_t) sizeof(dStats->tx_uc_byte_cnt[0]),
9082 (char *)&(dStats->tx_uc_byte_cnt[0]), tlen);
9083 FILL_TLV(p, (uint8_t) WLAN_STATS_TX_MC_BYTE_CNT,
9084 (uint8_t) sizeof(dStats->tx_mc_byte_cnt),
9085 (char *)&(dStats->tx_mc_byte_cnt), tlen);
9086 FILL_TLV(p, (uint8_t) WLAN_STATS_TX_BC_BYTE_CNT,
9087 (uint8_t) sizeof(dStats->tx_bc_byte_cnt),
9088 (char *)&(dStats->tx_bc_byte_cnt), tlen);
9089
9090 wrqu->data.length = tlen;
9091
9092 }
9093
9094 EXIT();
9095
9096 return 0;
9097}
9098
9099static int iw_get_statistics(struct net_device *dev,
9100 struct iw_request_info *info,
9101 union iwreq_data *wrqu, char *extra)
9102{
9103 int ret;
9104
9105 cds_ssr_protect(__func__);
9106 ret = __iw_get_statistics(dev, info, wrqu, extra);
9107 cds_ssr_unprotect(__func__);
9108
9109 return ret;
9110}
9111
9112#ifdef FEATURE_WLAN_SCAN_PNO
9113
9114/*Max Len for PNO notification*/
9115#define MAX_PNO_NOTIFY_LEN 100
9116void found_pref_network_cb(void *callbackContext,
9117 tSirPrefNetworkFoundInd *pPrefNetworkFoundInd)
9118{
9119 hdd_adapter_t *pAdapter = (hdd_adapter_t *) callbackContext;
9120 union iwreq_data wrqu;
9121 char buf[MAX_PNO_NOTIFY_LEN + 1];
9122
Jeff Johnson99bac312016-06-28 10:38:18 -07009123 hdd_warn("A preferred network was found: %s with rssi: -%d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08009124 pPrefNetworkFoundInd->ssId.ssId, pPrefNetworkFoundInd->rssi);
9125
9126 /* create the event */
9127 memset(&wrqu, 0, sizeof(wrqu));
9128 memset(buf, 0, sizeof(buf));
9129
9130 snprintf(buf, MAX_PNO_NOTIFY_LEN,
9131 "QCOM: Found preferred network: %s with RSSI of -%u",
9132 pPrefNetworkFoundInd->ssId.ssId,
9133 (unsigned int)pPrefNetworkFoundInd->rssi);
9134
9135 wrqu.data.pointer = buf;
9136 wrqu.data.length = strlen(buf);
9137
9138 /* send the event */
9139
9140 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, buf);
9141
9142}
9143
9144/**
9145 * __iw_set_pno() - Preferred Network Offload ioctl handler
9146 * @dev: device upon which the ioctl was received
9147 * @info: ioctl request information
9148 * @wrqu: ioctl request data
9149 * @extra: ioctl extra data
9150 *
9151 * This function parses a Preferred Network Offload command
9152 * Input is string based and expected to be of the form:
9153 *
9154 * <enable(1) | disable(0)>
9155 * when enabling:
9156 * <number of networks>
9157 * for each network:
9158 * <ssid_len> <ssid> <authentication> <encryption>
9159 * <ch_num> <channel_list optional> <bcast_type> <rssi_threshold>
9160 * <number of scan timers>
9161 * for each timer:
9162 * <scan_time> <scan_repeat>
9163 * <suspend mode>
9164 *
9165 * e.g:
9166 * 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
9167 *
9168 * this translates into:
9169 * -----------------------------
9170 * enable PNO
9171 * 2 networks
9172 * Network 1:
9173 * test - with authentication type 0 and encryption type 0,
9174 * search on 3 channels: 1 6 and 11,
9175 * SSID bcast type is unknown (directed probe will be sent if
9176 * AP not found) and must meet -40dBm RSSI
9177 * Network 2:
9178 * test2 - with authentication type 4 and encryption type 4,
9179 * search on 6 channels 1, 2, 3, 4, 5 and 6
9180 * bcast type is non-bcast (directed probe will be sent)
9181 * and must not meet any RSSI threshold
9182 * 2 scan timers:
9183 * scan every 5 seconds 2 times
9184 * then scan every 300 seconds until stopped
9185 * enable on suspend
9186 */
9187static int __iw_set_pno(struct net_device *dev,
9188 struct iw_request_info *info,
9189 union iwreq_data *wrqu, char *extra)
9190{
9191 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
9192 hdd_context_t *hdd_ctx;
9193 int ret;
9194 int offset;
9195 char *ptr;
9196 uint8_t i, j, params, mode;
9197
9198 /* request is a large struct, so we make it static to avoid
9199 * stack overflow. This API is only invoked via ioctl, so it
9200 * is serialized by the kernel rtnl_lock and hence does not
9201 * need to be reentrant
9202 */
9203 static tSirPNOScanReq request;
9204
Jeff Johnson6ee91ee2016-02-11 18:55:30 -08009205 ENTER_DEV(dev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08009206
9207 hdd_ctx = WLAN_HDD_GET_CTX(adapter);
9208 ret = wlan_hdd_validate_context(hdd_ctx);
9209 if (ret)
9210 return ret;
9211
9212 hdd_notice("PNO data len %d data %s", wrqu->data.length, extra);
9213
9214 request.enable = 0;
9215 request.ucNetworksCount = 0;
9216
9217 ptr = extra;
9218
9219 if (1 != sscanf(ptr, "%hhu%n", &(request.enable), &offset)) {
9220 hdd_err("PNO enable input is not valid %s", ptr);
9221 return -EINVAL;
9222 }
9223
9224 if (0 == request.enable) {
9225 /* Disable PNO, ignore any other params */
9226 memset(&request, 0, sizeof(request));
9227 sme_set_preferred_network_list(WLAN_HDD_GET_HAL_CTX(adapter),
9228 &request, adapter->sessionId,
9229 found_pref_network_cb, adapter);
9230 return 0;
9231 }
9232
9233 ptr += offset;
9234
9235 if (1 !=
9236 sscanf(ptr, "%hhu %n", &(request.ucNetworksCount), &offset)) {
9237 hdd_err("PNO count input not valid %s", ptr);
9238 return -EINVAL;
9239
9240 }
9241
9242 hdd_info("PNO enable %d networks count %d offset %d",
9243 request.enable, request.ucNetworksCount, offset);
9244
9245 if ((0 == request.ucNetworksCount) ||
9246 (request.ucNetworksCount > SIR_PNO_MAX_SUPP_NETWORKS)) {
9247 hdd_err("Network count %d invalid",
9248 request.ucNetworksCount);
9249 return -EINVAL;
9250 }
9251
9252 ptr += offset;
9253
9254 for (i = 0; i < request.ucNetworksCount; i++) {
9255
9256 request.aNetworks[i].ssId.length = 0;
9257
9258 params = sscanf(ptr, "%hhu %n",
9259 &(request.aNetworks[i].ssId.length),
9260 &offset);
9261
9262 if (1 != params) {
9263 hdd_err("PNO ssid length input is not valid %s", ptr);
9264 return -EINVAL;
9265 }
9266
9267 if ((0 == request.aNetworks[i].ssId.length) ||
9268 (request.aNetworks[i].ssId.length > 32)) {
9269 hdd_err("SSID Len %d is not correct for network %d",
9270 request.aNetworks[i].ssId.length, i);
9271 return -EINVAL;
9272 }
9273
9274 /* Advance to SSID */
9275 ptr += offset;
9276
9277 memcpy(request.aNetworks[i].ssId.ssId, ptr,
9278 request.aNetworks[i].ssId.length);
9279 ptr += request.aNetworks[i].ssId.length;
9280
9281 params = sscanf(ptr, "%u %u %hhu %n",
9282 &(request.aNetworks[i].authentication),
9283 &(request.aNetworks[i].encryption),
9284 &(request.aNetworks[i].ucChannelCount),
9285 &offset);
9286
9287 if (3 != params) {
9288 hdd_warn("Incorrect cmd %s", ptr);
9289 return -EINVAL;
9290 }
9291
9292 hdd_notice("PNO len %d ssid %.*s auth %d encry %d channel count %d offset %d",
9293 request.aNetworks[i].ssId.length,
9294 request.aNetworks[i].ssId.length,
9295 request.aNetworks[i].ssId.ssId,
9296 request.aNetworks[i].authentication,
9297 request.aNetworks[i].encryption,
9298 request.aNetworks[i].ucChannelCount, offset);
9299
9300 /* Advance to channel list */
9301 ptr += offset;
9302
9303 if (SIR_PNO_MAX_NETW_CHANNELS <
9304 request.aNetworks[i].ucChannelCount) {
9305 hdd_warn("Incorrect number of channels");
9306 return -EINVAL;
9307 }
9308
9309 if (0 != request.aNetworks[i].ucChannelCount) {
9310 for (j = 0; j < request.aNetworks[i].ucChannelCount;
9311 j++) {
9312 if (1 !=
9313 sscanf(ptr, "%hhu %n",
9314 &(request.aNetworks[i].
9315 aChannels[j]), &offset)) {
9316 hdd_err("PNO network channel input is not valid %s",
9317 ptr);
9318 return -EINVAL;
9319 }
9320 /* Advance to next channel number */
9321 ptr += offset;
9322 }
9323 }
9324
9325 if (1 != sscanf(ptr, "%u %n",
9326 &(request.aNetworks[i].bcastNetwType),
9327 &offset)) {
9328 hdd_err("PNO broadcast network type input is not valid %s",
9329 ptr);
9330 return -EINVAL;
9331 }
9332
9333 hdd_notice("PNO bcastNetwType %d offset %d",
9334 request.aNetworks[i].bcastNetwType, offset);
9335
9336 /* Advance to rssi Threshold */
9337 ptr += offset;
9338 if (1 != sscanf(ptr, "%d %n",
9339 &(request.aNetworks[i].rssiThreshold),
9340 &offset)) {
9341 hdd_err("PNO rssi threshold input is not valid %s",
9342 ptr);
9343 return -EINVAL;
9344 }
9345 hdd_notice("PNO rssi %d offset %d",
9346 request.aNetworks[i].rssiThreshold, offset);
9347 /* Advance to next network */
9348 ptr += offset;
9349 } /* For ucNetworkCount */
9350
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08009351 params = sscanf(ptr, "%hhu %n", &(mode), &offset);
9352
9353 request.modePNO = mode;
9354 /* for LA we just expose suspend option */
9355 if ((1 != params) || (mode >= SIR_PNO_MODE_MAX)) {
9356 request.modePNO = SIR_PNO_MODE_ON_SUSPEND;
9357 }
9358
9359 sme_set_preferred_network_list(WLAN_HDD_GET_HAL_CTX(adapter),
9360 &request,
9361 adapter->sessionId,
9362 found_pref_network_cb, adapter);
9363
9364 return 0;
9365}
9366
9367static int iw_set_pno(struct net_device *dev,
9368 struct iw_request_info *info,
9369 union iwreq_data *wrqu, char *extra)
9370{
9371 int ret;
9372
9373 cds_ssr_protect(__func__);
9374 ret = __iw_set_pno(dev, info, wrqu, extra);
9375 cds_ssr_unprotect(__func__);
9376
9377 return ret;
9378}
9379#endif /* FEATURE_WLAN_SCAN_PNO */
9380
9381/* Common function to SetBand */
9382int hdd_set_band(struct net_device *dev, u8 ui_band)
9383{
9384 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
9385 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
9386 eCsrBand band;
9387
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05309388 QDF_STATUS status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08009389 hdd_context_t *pHddCtx;
9390 hdd_adapter_list_node_t *pAdapterNode, *pNext;
9391 eCsrBand currBand = eCSR_BAND_MAX;
9392 eCsrBand connectedBand;
9393
9394 pAdapterNode = NULL;
9395 pNext = NULL;
9396 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
9397
9398 switch (ui_band) {
9399 case WLAN_HDD_UI_BAND_AUTO:
9400 band = eCSR_BAND_ALL;
9401 break;
9402 case WLAN_HDD_UI_BAND_5_GHZ:
9403 band = eCSR_BAND_5G;
9404 break;
9405 case WLAN_HDD_UI_BAND_2_4_GHZ:
9406 band = eCSR_BAND_24;
9407 break;
9408 default:
9409 band = eCSR_BAND_MAX;
9410 }
9411
Jeff Johnson99bac312016-06-28 10:38:18 -07009412 hdd_notice("change band to %u", band);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08009413
9414 if (band == eCSR_BAND_MAX) {
9415 /* Received change band request with invalid band value */
Jeff Johnson99bac312016-06-28 10:38:18 -07009416 hdd_err("Invalid band value %u", ui_band);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08009417 return -EINVAL;
9418 }
9419
9420 if ((band == eCSR_BAND_24 && pHddCtx->config->nBandCapability == 2) ||
9421 (band == eCSR_BAND_5G && pHddCtx->config->nBandCapability == 1)) {
Jeff Johnson99bac312016-06-28 10:38:18 -07009422 hdd_err("band value %u violate INI settings %u",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08009423 band, pHddCtx->config->nBandCapability);
9424 return -EIO;
9425 }
9426
9427 if (band == eCSR_BAND_ALL) {
Jeff Johnson99bac312016-06-28 10:38:18 -07009428 hdd_notice("Auto band received. Setting band same as ini value %d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08009429 pHddCtx->config->nBandCapability);
9430 band = pHddCtx->config->nBandCapability;
9431 }
9432
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05309433 if (QDF_STATUS_SUCCESS != sme_get_freq_band(hHal, &currBand)) {
Jeff Johnson99bac312016-06-28 10:38:18 -07009434 hdd_notice("Failed to get current band config");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08009435 return -EIO;
9436 }
9437
9438 if (currBand != band) {
9439 /* Change band request received.
9440 * Abort pending scan requests, flush the existing scan results,
9441 * and change the band capability
9442 */
Jeff Johnson99bac312016-06-28 10:38:18 -07009443 hdd_notice("Current band value = %u, new setting %u ",
9444 currBand, band);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08009445
9446 status = hdd_get_front_adapter(pHddCtx, &pAdapterNode);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05309447 while (NULL != pAdapterNode && QDF_STATUS_SUCCESS == status) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08009448 pAdapter = pAdapterNode->pAdapter;
9449 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
9450 hdd_abort_mac_scan(pHddCtx, pAdapter->sessionId,
9451 eCSR_SCAN_ABORT_DUE_TO_BAND_CHANGE);
9452 connectedBand =
9453 hdd_conn_get_connected_band
9454 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter));
9455
9456 /* Handling is done only for STA and P2P */
9457 if (band != eCSR_BAND_ALL &&
Krunal Sonif07bb382016-03-10 13:02:11 -08009458 ((pAdapter->device_mode == QDF_STA_MODE)
9459 || (pAdapter->device_mode == QDF_P2P_CLIENT_MODE))
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08009460 &&
9461 (hdd_conn_is_connected
9462 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter)))
9463 && (connectedBand != band)) {
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05309464 QDF_STATUS status = QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08009465 long lrc;
9466
9467 /* STA already connected on current band, So issue disconnect
9468 * first, then change the band*/
9469
Jeff Johnson99bac312016-06-28 10:38:18 -07009470 hdd_notice("STA (Device mode %s(%d)) connected in band %u, Changing band to %u, Issuing Disconnect",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08009471 hdd_device_mode_to_string(pAdapter->device_mode),
9472 pAdapter->device_mode, currBand, band);
9473 INIT_COMPLETION(pAdapter->disconnect_comp_var);
9474
9475 status =
9476 sme_roam_disconnect(WLAN_HDD_GET_HAL_CTX
9477 (pAdapter),
9478 pAdapter->sessionId,
9479 eCSR_DISCONNECT_REASON_UNSPECIFIED);
9480
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05309481 if (QDF_STATUS_SUCCESS != status) {
Jeff Johnson99bac312016-06-28 10:38:18 -07009482 hdd_err("csr_roam_disconnect failure, returned %d",
9483 (int)status);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08009484 return -EINVAL;
9485 }
9486
9487 lrc =
9488 wait_for_completion_timeout(&pAdapter->
9489 disconnect_comp_var,
9490 msecs_to_jiffies
9491 (WLAN_WAIT_TIME_DISCONNECT));
9492
9493 if (lrc == 0) {
Jeff Johnson99bac312016-06-28 10:38:18 -07009494 hdd_err("Timeout while waiting for csr_roam_disconnect");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08009495 return -ETIMEDOUT;
9496 }
9497 }
9498
9499 sme_scan_flush_result(hHal);
9500
9501 status =
9502 hdd_get_next_adapter(pHddCtx, pAdapterNode, &pNext);
9503 pAdapterNode = pNext;
9504 }
9505
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05309506 if (QDF_STATUS_SUCCESS !=
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08009507 sme_set_freq_band(hHal, pAdapter->sessionId, band)) {
Jeff Johnson99bac312016-06-28 10:38:18 -07009508 hdd_alert("Failed to set the band value to %u",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08009509 band);
9510 return -EINVAL;
9511 }
9512 wlan_hdd_cfg80211_update_band(pHddCtx->wiphy, (eCsrBand) band);
9513 }
9514 return 0;
9515}
9516
9517int hdd_set_band_helper(struct net_device *dev, const char *command)
9518{
9519 uint8_t band;
9520 int ret;
9521
9522 /* Convert the band value from ascii to integer */
9523 command += WLAN_HDD_UI_SET_BAND_VALUE_OFFSET;
9524 ret = kstrtou8(command, 10, &band);
9525 if (ret < 0) {
Jeff Johnson99bac312016-06-28 10:38:18 -07009526 hdd_err("kstrtou8 failed");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08009527 return -EINVAL;
9528 }
9529
9530 return hdd_set_band(dev, band);
9531}
9532
9533static int __iw_set_band_config(struct net_device *dev,
9534 struct iw_request_info *info,
9535 union iwreq_data *wrqu, char *extra)
9536{
9537 int *value = (int *)extra;
9538
Jeff Johnson6ee91ee2016-02-11 18:55:30 -08009539 ENTER_DEV(dev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08009540
Mukul Sharmaa5fe1982015-11-02 19:28:14 +05309541 if (!capable(CAP_NET_ADMIN)) {
Jeff Johnson99bac312016-06-28 10:38:18 -07009542 hdd_err("permission check failed");
Mukul Sharmaa5fe1982015-11-02 19:28:14 +05309543 return -EPERM;
9544 }
9545
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08009546 return hdd_set_band(dev, value[0]);
9547}
9548
9549static int iw_set_band_config(struct net_device *dev,
9550 struct iw_request_info *info,
9551 union iwreq_data *wrqu, char *extra)
9552{
9553 int ret;
9554
9555 cds_ssr_protect(__func__);
9556 ret = __iw_set_band_config(dev, info, wrqu, extra);
9557 cds_ssr_unprotect(__func__);
9558
9559 return ret;
9560}
9561
Manjunathappa Prakash59f861d2016-04-21 10:33:31 -07009562/**
9563 * wlan_hdd_set_mon_chan() - Set capture channel on the monitor mode interface.
9564 * @adapter: Handle to adapter
9565 * @chan: Monitor mode channel
9566 * @bandwidth: Capture channel bandwidth
9567 *
9568 * Return: 0 on success else error code.
9569 */
9570static int wlan_hdd_set_mon_chan(hdd_adapter_t *adapter, uint32_t chan,
9571 uint32_t bandwidth)
9572{
9573 hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
9574 hdd_station_ctx_t *sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
9575 struct hdd_mon_set_ch_info *ch_info = &sta_ctx->ch_info;
9576 QDF_STATUS status;
9577 tHalHandle hal_hdl = hdd_ctx->hHal;
9578 struct qdf_mac_addr bssid;
9579 tCsrRoamProfile roam_profile;
9580 struct ch_params_s ch_params;
9581
9582 if (QDF_GLOBAL_MONITOR_MODE != hdd_get_conparam()) {
9583 hdd_err("Not supported, device is not in monitor mode");
9584 return -EINVAL;
9585 }
9586
9587 hdd_info("Set monitor mode Channel %d", chan);
Manjunathappa Prakash59f861d2016-04-21 10:33:31 -07009588 roam_profile.ChannelInfo.ChannelList = &ch_info->channel;
9589 roam_profile.ChannelInfo.numOfChannels = 1;
9590 roam_profile.phyMode = ch_info->phy_mode;
9591 roam_profile.ch_params.ch_width = bandwidth;
Naveen Rawatc77e6e72016-08-05 15:19:03 -07009592 hdd_select_cbmode(adapter, chan, &roam_profile.ch_params);
Manjunathappa Prakash59f861d2016-04-21 10:33:31 -07009593
9594 qdf_mem_copy(bssid.bytes, adapter->macAddressCurrent.bytes,
9595 QDF_MAC_ADDR_SIZE);
9596
9597 ch_params.ch_width = bandwidth;
Sandeep Puligilla1cc23f62016-04-27 16:52:49 -07009598 cds_set_channel_params(chan, 0, &ch_params);
Manjunathappa Prakash59f861d2016-04-21 10:33:31 -07009599 status = sme_roam_channel_change_req(hal_hdl, bssid, &ch_params,
9600 &roam_profile);
9601 if (status) {
9602 hdd_err("Status: %d Failed to set sme_roam Channel for monitor mode",
9603 status);
9604 }
9605
9606 return qdf_status_to_os_return(status);
9607}
9608
Rajeev Kumara78a0a42016-07-13 19:28:20 -07009609#ifdef WLAN_SUSPEND_RESUME_TEST
9610static void *g_wiphy;
9611
9612/**
9613 * hdd_wlan_trigger_resume() - resume wlan
9614 * @val: interrupt val
9615 *
9616 * Resume wlan after getting very 1st CE interrupt from target
9617 *
9618 * Return: none
9619 */
9620static void hdd_wlan_trigger_resume(uint32_t val)
9621{
9622 hdd_err("Resume WLAN val 0x%x", val);
9623 wlan_hdd_bus_resume();
9624 wlan_hdd_cfg80211_resume_wlan(g_wiphy);
9625}
9626#endif
9627
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08009628static int __iw_set_two_ints_getnone(struct net_device *dev,
9629 struct iw_request_info *info,
9630 union iwreq_data *wrqu, char *extra)
9631{
9632 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
9633 int *value = (int *)extra;
9634 int sub_cmd = value[0];
9635 int ret;
9636 hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(pAdapter);
Rajeev Kumara78a0a42016-07-13 19:28:20 -07009637#ifdef WLAN_SUSPEND_RESUME_TEST
9638 pm_message_t state;
9639#endif
9640
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08009641
Jeff Johnson6ee91ee2016-02-11 18:55:30 -08009642 ENTER_DEV(dev);
9643
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08009644 ret = wlan_hdd_validate_context(hdd_ctx);
9645 if (0 != ret)
9646 return ret;
9647
9648 switch (sub_cmd) {
9649 case WE_SET_SMPS_PARAM:
Jeff Johnson99bac312016-06-28 10:38:18 -07009650 hdd_notice("WE_SET_SMPS_PARAM val %d %d", value[1], value[2]);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08009651 ret = wma_cli_set_command(pAdapter->sessionId,
9652 WMI_STA_SMPS_PARAM_CMDID,
9653 value[1] << WMA_SMPS_PARAM_VALUE_S
9654 | value[2],
9655 VDEV_CMD);
9656 break;
9657#ifdef DEBUG
9658 case WE_SET_FW_CRASH_INJECT:
Jeff Johnson99bac312016-06-28 10:38:18 -07009659 hdd_err("WE_SET_FW_CRASH_INJECT: %d %d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08009660 value[1], value[2]);
DARAM SUDHA7e7e91b2015-05-29 11:38:47 +05309661 pr_err("SSR is triggered by iwpriv CRASH_INJECT: %d %d\n",
9662 value[1], value[2]);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08009663 ret = wma_cli_set2_command(pAdapter->sessionId,
9664 GEN_PARAM_CRASH_INJECT,
9665 value[1], value[2], GEN_CMD);
9666 break;
9667#endif
Govind Singha471e5e2015-10-12 17:11:14 +05309668 case WE_ENABLE_FW_PROFILE:
Jeff Johnson99bac312016-06-28 10:38:18 -07009669 hdd_err("WE_ENABLE_FW_PROFILE: %d %d",
Govind Singha471e5e2015-10-12 17:11:14 +05309670 value[1], value[2]);
9671 ret = wma_cli_set2_command(pAdapter->sessionId,
9672 WMI_WLAN_PROFILE_ENABLE_PROFILE_ID_CMDID,
9673 value[1], value[2], DBG_CMD);
9674 break;
9675 case WE_SET_FW_PROFILE_HIST_INTVL:
Jeff Johnson99bac312016-06-28 10:38:18 -07009676 hdd_err("WE_SET_FW_PROFILE_HIST_INTVL: %d %d",
Govind Singha471e5e2015-10-12 17:11:14 +05309677 value[1], value[2]);
9678 ret = wma_cli_set2_command(pAdapter->sessionId,
9679 WMI_WLAN_PROFILE_SET_HIST_INTVL_CMDID,
9680 value[1], value[2], DBG_CMD);
9681 break;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08009682 case WE_SET_DUAL_MAC_FW_MODE_CONFIG:
9683 hdd_debug("Ioctl to set dual fw mode config");
9684 if (hdd_ctx->config->dual_mac_feature_disable) {
9685 hdd_err("Dual mac feature is disabled from INI");
9686 return -EPERM;
9687 }
9688 hdd_debug("%d %d", value[1], value[2]);
Tushnim Bhattacharyya4adb3682016-01-07 15:07:12 -08009689 cds_set_dual_mac_fw_mode_config(value[1], value[2]);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08009690 break;
9691 case WE_DUMP_DP_TRACE_LEVEL:
9692 hdd_info("WE_DUMP_DP_TRACE_LEVEL: %d %d",
9693 value[1], value[2]);
9694 if (value[1] == DUMP_DP_TRACE)
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05309695 qdf_dp_trace_dump_all(value[2]);
Nirav Shah0d58a7e2016-04-26 22:54:12 +05309696 else if (value[1] == ENABLE_DP_TRACE_LIVE_MODE)
9697 qdf_dp_trace_enable_live_mode();
Nirav Shahda008342016-05-17 18:50:40 +05309698 else if (value[1] == CLEAR_DP_TRACE_BUFFER)
9699 qdf_dp_trace_clear_buffer();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08009700 break;
Manjunathappa Prakash59f861d2016-04-21 10:33:31 -07009701 case WE_SET_MON_MODE_CHAN:
9702 ret = wlan_hdd_set_mon_chan(pAdapter, value[1], value[2]);
9703 break;
Rajeev Kumara78a0a42016-07-13 19:28:20 -07009704#ifdef WLAN_SUSPEND_RESUME_TEST
9705 case WE_SET_WLAN_SUSPEND:
9706 hdd_err("Suspend WLAN");
9707 g_wiphy = hdd_ctx->wiphy;
9708 state.event = PM_EVENT_SUSPEND;
9709 ret = wlan_hdd_cfg80211_suspend_wlan(hdd_ctx->wiphy, NULL);
9710 wlan_hdd_bus_suspend(state);
9711 hif_fake_apps_suspend(hdd_wlan_trigger_resume);
9712 break;
9713 case WE_SET_WLAN_RESUME:
9714 hdd_err("Resume WLAN");
9715 wlan_hdd_bus_resume();
9716 ret = wlan_hdd_cfg80211_resume_wlan(hdd_ctx->wiphy);
9717 break;
9718#endif
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08009719 default:
Jeff Johnson99bac312016-06-28 10:38:18 -07009720 hdd_err("Invalid IOCTL command %d", sub_cmd);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08009721 break;
9722 }
9723
9724 return ret;
9725}
9726
9727static int iw_set_two_ints_getnone(struct net_device *dev,
9728 struct iw_request_info *info,
9729 union iwreq_data *wrqu, char *extra)
9730{
9731 int ret;
9732
9733 cds_ssr_protect(__func__);
9734 ret = __iw_set_two_ints_getnone(dev, info, wrqu, extra);
9735 cds_ssr_unprotect(__func__);
9736
9737 return ret;
9738}
9739
9740/* Define the Wireless Extensions to the Linux Network Device structure */
9741/* A number of these routines are NULL (meaning they are not implemented.) */
9742
9743static const iw_handler we_handler[] = {
9744 (iw_handler) iw_set_commit, /* SIOCSIWCOMMIT */
9745 (iw_handler) iw_get_name, /* SIOCGIWNAME */
9746 (iw_handler) NULL, /* SIOCSIWNWID */
9747 (iw_handler) NULL, /* SIOCGIWNWID */
9748 (iw_handler) iw_set_freq, /* SIOCSIWFREQ */
9749 (iw_handler) iw_get_freq, /* SIOCGIWFREQ */
9750 (iw_handler) iw_set_mode, /* SIOCSIWMODE */
9751 (iw_handler) iw_get_mode, /* SIOCGIWMODE */
9752 (iw_handler) NULL, /* SIOCSIWSENS */
9753 (iw_handler) NULL, /* SIOCGIWSENS */
9754 (iw_handler) NULL, /* SIOCSIWRANGE */
9755 (iw_handler) iw_get_range, /* SIOCGIWRANGE */
9756 (iw_handler) NULL, /* SIOCSIWPRIV */
9757 (iw_handler) NULL, /* SIOCGIWPRIV */
9758 (iw_handler) NULL, /* SIOCSIWSTATS */
9759 (iw_handler) NULL, /* SIOCGIWSTATS */
9760 (iw_handler) NULL, /* SIOCSIWSPY */
9761 (iw_handler) NULL, /* SIOCGIWSPY */
9762 (iw_handler) NULL, /* SIOCSIWTHRSPY */
9763 (iw_handler) NULL, /* SIOCGIWTHRSPY */
9764 (iw_handler) iw_set_ap_address, /* SIOCSIWAP */
9765 (iw_handler) iw_get_ap_address, /* SIOCGIWAP */
9766 (iw_handler) iw_set_mlme, /* SIOCSIWMLME */
9767 (iw_handler) NULL, /* SIOCGIWAPLIST */
9768 (iw_handler) iw_set_scan, /* SIOCSIWSCAN */
9769 (iw_handler) iw_get_scan, /* SIOCGIWSCAN */
9770 (iw_handler) iw_set_essid, /* SIOCSIWESSID */
9771 (iw_handler) iw_get_essid, /* SIOCGIWESSID */
9772 (iw_handler) iw_set_nick, /* SIOCSIWNICKN */
9773 (iw_handler) iw_get_nick, /* SIOCGIWNICKN */
9774 (iw_handler) NULL, /* -- hole -- */
9775 (iw_handler) NULL, /* -- hole -- */
9776 (iw_handler) iw_set_bitrate, /* SIOCSIWRATE */
9777 (iw_handler) iw_get_bitrate, /* SIOCGIWRATE */
9778 (iw_handler) iw_set_rts_threshold, /* SIOCSIWRTS */
9779 (iw_handler) iw_get_rts_threshold, /* SIOCGIWRTS */
9780 (iw_handler) iw_set_frag_threshold, /* SIOCSIWFRAG */
9781 (iw_handler) iw_get_frag_threshold, /* SIOCGIWFRAG */
9782 (iw_handler) iw_set_tx_power, /* SIOCSIWTXPOW */
9783 (iw_handler) iw_get_tx_power, /* SIOCGIWTXPOW */
9784 (iw_handler) iw_set_retry, /* SIOCSIWRETRY */
9785 (iw_handler) iw_get_retry, /* SIOCGIWRETRY */
9786 (iw_handler) iw_set_encode, /* SIOCSIWENCODE */
9787 (iw_handler) iw_get_encode, /* SIOCGIWENCODE */
9788 (iw_handler) iw_set_power_mode, /* SIOCSIWPOWER */
9789 (iw_handler) iw_get_power_mode, /* SIOCGIWPOWER */
9790 (iw_handler) NULL, /* -- hole -- */
9791 (iw_handler) NULL, /* -- hole -- */
9792 (iw_handler) iw_set_genie, /* SIOCSIWGENIE */
9793 (iw_handler) iw_get_genie, /* SIOCGIWGENIE */
9794 (iw_handler) iw_set_auth, /* SIOCSIWAUTH */
9795 (iw_handler) iw_get_auth, /* SIOCGIWAUTH */
9796 (iw_handler) iw_set_encodeext, /* SIOCSIWENCODEEXT */
9797 (iw_handler) iw_get_encodeext, /* SIOCGIWENCODEEXT */
9798 (iw_handler) NULL, /* SIOCSIWPMKSA */
9799};
9800
9801static const iw_handler we_private[] = {
9802
9803 [WLAN_PRIV_SET_INT_GET_NONE - SIOCIWFIRSTPRIV] = iw_setint_getnone, /* set priv ioctl */
9804 [WLAN_PRIV_SET_NONE_GET_INT - SIOCIWFIRSTPRIV] = iw_setnone_getint, /* get priv ioctl */
9805 [WLAN_PRIV_SET_CHAR_GET_NONE - SIOCIWFIRSTPRIV] = iw_setchar_getnone, /* get priv ioctl */
9806 [WLAN_PRIV_SET_THREE_INT_GET_NONE - SIOCIWFIRSTPRIV] =
9807 iw_set_three_ints_getnone,
9808 [WLAN_PRIV_GET_CHAR_SET_NONE - SIOCIWFIRSTPRIV] = iw_get_char_setnone,
9809 [WLAN_PRIV_SET_NONE_GET_NONE - SIOCIWFIRSTPRIV] = iw_setnone_getnone, /* action priv ioctl */
9810 [WLAN_PRIV_SET_VAR_INT_GET_NONE - SIOCIWFIRSTPRIV] =
9811 iw_hdd_set_var_ints_getnone,
Manikandan Mohandcc21ba2016-03-15 14:31:56 -07009812 [WLAN_PRIV_SET_NONE_GET_THREE_INT - SIOCIWFIRSTPRIV] =
9813 iw_setnone_get_threeint,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08009814 [WLAN_PRIV_ADD_TSPEC - SIOCIWFIRSTPRIV] = iw_add_tspec,
9815 [WLAN_PRIV_DEL_TSPEC - SIOCIWFIRSTPRIV] = iw_del_tspec,
9816 [WLAN_PRIV_GET_TSPEC - SIOCIWFIRSTPRIV] = iw_get_tspec,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08009817 [WLAN_PRIV_SET_FTIES - SIOCIWFIRSTPRIV] = iw_set_fties,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08009818 [WLAN_PRIV_SET_HOST_OFFLOAD - SIOCIWFIRSTPRIV] = iw_set_host_offload,
9819 [WLAN_GET_WLAN_STATISTICS - SIOCIWFIRSTPRIV] = iw_get_statistics,
9820 [WLAN_SET_KEEPALIVE_PARAMS - SIOCIWFIRSTPRIV] =
9821 iw_set_keepalive_params,
9822#ifdef WLAN_FEATURE_PACKET_FILTERING
9823 [WLAN_SET_PACKET_FILTER_PARAMS - SIOCIWFIRSTPRIV] =
9824 iw_set_packet_filter_params,
9825#endif
9826#ifdef FEATURE_WLAN_SCAN_PNO
9827 [WLAN_SET_PNO - SIOCIWFIRSTPRIV] = iw_set_pno,
9828#endif
9829 [WLAN_SET_BAND_CONFIG - SIOCIWFIRSTPRIV] = iw_set_band_config,
9830 [WLAN_GET_LINK_SPEED - SIOCIWFIRSTPRIV] = iw_get_linkspeed,
9831 [WLAN_PRIV_SET_TWO_INT_GET_NONE - SIOCIWFIRSTPRIV] =
9832 iw_set_two_ints_getnone,
9833 [WLAN_SET_DOT11P_CHANNEL_SCHED - SIOCIWFIRSTPRIV] =
9834 iw_set_dot11p_channel_sched,
9835};
9836
9837/*Maximum command length can be only 15 */
9838static const struct iw_priv_args we_private_args[] = {
9839
9840 /* handlers for main ioctl */
9841 {WLAN_PRIV_SET_INT_GET_NONE,
9842 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
9843 0,
9844 ""},
9845
9846 /* handlers for sub-ioctl */
9847 {WE_SET_11D_STATE,
9848 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
9849 0,
9850 "set11Dstate"},
9851
9852 {WE_WOWL,
9853 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
9854 0,
9855 "wowl"},
9856
9857 {WE_SET_POWER,
9858 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
9859 0,
9860 "setPower"},
9861
9862 {WE_SET_MAX_ASSOC,
9863 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
9864 0,
9865 "setMaxAssoc"},
9866
9867 {WE_SET_SAP_AUTO_CHANNEL_SELECTION,
9868 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0,
9869 "setAutoChannel" },
9870
9871 {WE_SET_SCAN_DISABLE,
9872 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
9873 0,
9874 "scan_disable"},
9875
9876 {WE_SET_DATA_INACTIVITY_TO,
9877 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
9878 0,
9879 "inactivityTO"},
9880
9881 {WE_SET_MAX_TX_POWER,
9882 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
9883 0,
9884 "setMaxTxPower"},
9885
9886 {WE_SET_TX_POWER,
9887 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
9888 0,
9889 "setTxPower"},
9890
9891 {WE_SET_MC_RATE,
9892 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
9893 0,
9894 "setMcRate"},
9895
9896 {WE_SET_MAX_TX_POWER_2_4,
9897 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
9898 0,
9899 "setTxMaxPower2G"},
9900
9901 {WE_SET_MAX_TX_POWER_5_0,
9902 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
9903 0,
9904 "setTxMaxPower5G"},
9905
Srinivas Girigowdac34f11d2016-02-25 16:02:42 -08009906 {WE_SET_PKTLOG,
9907 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
9908 0,
9909 "pktlog"},
9910
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08009911 /* SAP has TxMax whereas STA has MaxTx, adding TxMax for STA
9912 * as well to keep same syntax as in SAP. Now onwards, STA
9913 * will support both */
9914 {WE_SET_MAX_TX_POWER,
9915 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
9916 0,
9917 "setTxMaxPower"},
9918
9919 /* set Higher DTIM Transition (DTIM1 to DTIM3)
9920 * 1 = enable and 0 = disable */
9921 {
9922 WE_SET_HIGHER_DTIM_TRANSITION,
9923 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
9924 0,
9925 "setHDtimTransn"
9926 },
9927
9928 {WE_SET_TM_LEVEL,
9929 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
9930 0,
9931 "setTmLevel"},
9932
9933 {WE_SET_PHYMODE,
9934 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
9935 0,
9936 "setphymode"},
9937
9938 {WE_SET_NSS,
9939 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
9940 0,
9941 "nss"},
9942
9943 {WE_SET_LDPC,
9944 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
9945 0,
9946 "ldpc"},
9947
9948 {WE_SET_TX_STBC,
9949 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
9950 0,
9951 "tx_stbc"},
9952
9953 {WE_SET_RX_STBC,
9954 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
9955 0,
9956 "rx_stbc"},
9957
9958 {WE_SET_SHORT_GI,
9959 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
9960 0,
9961 "shortgi"},
9962
9963 {WE_SET_RTSCTS,
9964 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
9965 0,
9966 "enablertscts"},
9967
9968 {WE_SET_CHWIDTH,
9969 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
9970 0,
9971 "chwidth"},
9972
9973 {WE_SET_ANI_EN_DIS,
9974 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
9975 0,
9976 "anienable"},
9977
9978 {WE_SET_ANI_POLL_PERIOD,
9979 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
9980 0,
9981 "aniplen"},
9982
9983 {WE_SET_ANI_LISTEN_PERIOD,
9984 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
9985 0,
9986 "anilislen"},
9987
9988 {WE_SET_ANI_OFDM_LEVEL,
9989 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
9990 0,
9991 "aniofdmlvl"},
9992
9993 {WE_SET_ANI_CCK_LEVEL,
9994 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
9995 0,
9996 "aniccklvl"},
9997
9998 {WE_SET_DYNAMIC_BW,
9999 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10000 0,
10001 "cwmenable"},
10002
10003 {WE_SET_CTS_CBW,
10004 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10005 0,
10006 "cts_cbw" },
10007
10008 {WE_SET_GTX_HT_MCS,
10009 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10010 0,
10011 "gtxHTMcs"},
10012
10013 {WE_SET_GTX_VHT_MCS,
10014 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10015 0,
10016 "gtxVHTMcs"},
10017
10018 {WE_SET_GTX_USRCFG,
10019 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10020 0,
10021 "gtxUsrCfg"},
10022
10023 {WE_SET_GTX_THRE,
10024 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10025 0,
10026 "gtxThre"},
10027
10028 {WE_SET_GTX_MARGIN,
10029 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10030 0,
10031 "gtxMargin"},
10032
10033 {WE_SET_GTX_STEP,
10034 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10035 0,
10036 "gtxStep"},
10037
10038 {WE_SET_GTX_MINTPC,
10039 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10040 0,
10041 "gtxMinTpc"},
10042
10043 {WE_SET_GTX_BWMASK,
10044 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10045 0,
10046 "gtxBWMask"},
10047
10048 {WE_SET_TX_CHAINMASK,
10049 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10050 0,
10051 "txchainmask"},
10052
10053 {WE_SET_RX_CHAINMASK,
10054 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10055 0,
10056 "rxchainmask"},
10057
10058 {WE_SET_11N_RATE,
10059 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10060 0,
10061 "set11NRates"},
10062
10063 {WE_SET_VHT_RATE,
10064 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10065 0,
10066 "set11ACRates"},
10067
10068 {WE_SET_AMPDU,
10069 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10070 0,
10071 "ampdu"},
10072
10073 {WE_SET_AMSDU,
10074 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10075 0,
10076 "amsdu"},
10077
10078 {WE_SET_BURST_ENABLE,
10079 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10080 0,
10081 "burst_enable"},
10082
10083 {WE_SET_BURST_DUR,
10084 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10085 0,
10086 "burst_dur"},
10087
10088 {WE_SET_TXPOW_2G,
10089 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10090 0,
10091 "txpow2g"},
10092
10093 {WE_SET_TXPOW_5G,
10094 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10095 0,
10096 "txpow5g"},
10097
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080010098 /* Sub-cmds DBGLOG specific commands */
10099 {WE_DBGLOG_LOG_LEVEL,
10100 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10101 0,
10102 "dl_loglevel"},
10103
10104 {WE_DBGLOG_VAP_ENABLE,
10105 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10106 0,
10107 "dl_vapon"},
10108
10109 {WE_DBGLOG_VAP_DISABLE,
10110 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10111 0,
10112 "dl_vapoff"},
10113
10114 {WE_DBGLOG_MODULE_ENABLE,
10115 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10116 0,
10117 "dl_modon"},
10118
10119 {WE_DBGLOG_MODULE_DISABLE,
10120 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10121 0,
10122 "dl_modoff"},
10123
10124 {WE_DBGLOG_MOD_LOG_LEVEL,
10125 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10126 0,
10127 "dl_mod_loglevel"},
10128
10129 {WE_DBGLOG_TYPE,
10130 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10131 0,
10132 "dl_type"},
10133 {WE_DBGLOG_REPORT_ENABLE,
10134 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10135 0,
10136 "dl_report"},
10137
10138 {WE_SET_TXRX_FWSTATS,
10139 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10140 0,
10141 "txrx_fw_stats"},
10142
10143 {WE_TXRX_FWSTATS_RESET,
10144 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10145 0,
10146 "txrx_fw_st_rst"},
10147
10148 {WE_PPS_PAID_MATCH,
10149 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10150 0, "paid_match"},
10151
10152 {WE_PPS_GID_MATCH,
10153 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10154 0, "gid_match"},
10155
10156 {WE_PPS_EARLY_TIM_CLEAR,
10157 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10158 0, "tim_clear"},
10159
10160 {WE_PPS_EARLY_DTIM_CLEAR,
10161 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10162 0, "dtim_clear"},
10163
10164 {WE_PPS_EOF_PAD_DELIM,
10165 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10166 0, "eof_delim"},
10167
10168 {WE_PPS_MACADDR_MISMATCH,
10169 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10170 0, "mac_match"},
10171
10172 {WE_PPS_DELIM_CRC_FAIL,
10173 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10174 0, "delim_fail"},
10175
10176 {WE_PPS_GID_NSTS_ZERO,
10177 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10178 0, "nsts_zero"},
10179
10180 {WE_PPS_RSSI_CHECK,
10181 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10182 0, "rssi_chk"},
10183
10184 {WE_PPS_5G_EBT,
10185 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10186 0, "5g_ebt"},
10187
10188 {WE_SET_HTSMPS,
10189 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10190 0, "htsmps"},
10191
10192 {WE_SET_QPOWER_MAX_PSPOLL_COUNT,
10193 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10194 0, "set_qpspollcnt"},
10195
10196 {WE_SET_QPOWER_MAX_TX_BEFORE_WAKE,
10197 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10198 0, "set_qtxwake"},
10199
10200 {WE_SET_QPOWER_SPEC_PSPOLL_WAKE_INTERVAL,
10201 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10202 0, "set_qwakeintv"},
10203
10204 {WE_SET_QPOWER_SPEC_MAX_SPEC_NODATA_PSPOLL,
10205 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10206 0, "set_qnodatapoll"},
10207
10208 /* handlers for MCC time quota and latency sub ioctls */
10209 {WE_MCC_CONFIG_LATENCY,
10210 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10211 0, "setMccLatency"},
10212
10213 {WE_MCC_CONFIG_QUOTA,
10214 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10215 0, "setMccQuota"},
10216
10217 {WE_SET_DEBUG_LOG,
10218 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10219 0, "setDbgLvl"},
10220
10221 /* handlers for early_rx power save */
10222 {WE_SET_EARLY_RX_ADJUST_ENABLE,
10223 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10224 0, "erx_enable"},
10225
10226 {WE_SET_EARLY_RX_TGT_BMISS_NUM,
10227 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10228 0, "erx_bmiss_val"},
10229
10230 {WE_SET_EARLY_RX_BMISS_SAMPLE_CYCLE,
10231 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10232 0, "erx_bmiss_smpl"},
10233
10234 {WE_SET_EARLY_RX_SLOP_STEP,
10235 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10236 0, "erx_slop_step"},
10237
10238 {WE_SET_EARLY_RX_INIT_SLOP,
10239 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10240 0, "erx_init_slop"},
10241
10242 {WE_SET_EARLY_RX_ADJUST_PAUSE,
10243 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10244 0, "erx_adj_pause"},
10245
10246 {WE_SET_EARLY_RX_DRIFT_SAMPLE,
10247 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10248 0, "erx_dri_sample"},
10249
10250 {WE_DUMP_STATS,
10251 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10252 0, "dumpStats"},
10253
10254 {WE_CLEAR_STATS,
10255 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10256 0, "clearStats"},
10257
Govind Singha471e5e2015-10-12 17:11:14 +053010258 {WE_START_FW_PROFILE,
10259 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10260 0, "startProfile"},
10261
Abhishek Singh1bdb1572015-10-16 16:24:19 +053010262 {WE_SET_CHANNEL,
10263 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10264 0, "setChanChange" },
10265
Manishekar Chandrasekaran97e077d2016-03-23 17:10:31 +053010266 {WE_SET_CONC_SYSTEM_PREF,
10267 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10268 0, "setConcSysPref" },
10269
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080010270 {WLAN_PRIV_SET_NONE_GET_INT,
10271 0,
10272 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10273 ""},
10274
10275 /* handlers for sub-ioctl */
10276 {WE_GET_11D_STATE,
10277 0,
10278 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10279 "get11Dstate"},
10280
10281 {WE_IBSS_STATUS,
10282 0,
10283 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10284 "getAdhocStatus"},
10285
10286 {WE_GET_WLAN_DBG,
10287 0,
10288 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10289 "getwlandbg"},
10290
10291 {WE_GET_MAX_ASSOC,
10292 0,
10293 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10294 "getMaxAssoc"},
10295
10296 {WE_GET_SAP_AUTO_CHANNEL_SELECTION,
10297 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10298 "getAutoChannel" },
10299
10300 {WE_GET_CONCURRENCY_MODE,
10301 0,
10302 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10303 "getconcurrency"},
10304
10305 {WE_GET_NSS,
10306 0,
10307 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10308 "get_nss"},
10309
10310 {WE_GET_LDPC,
10311 0,
10312 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10313 "get_ldpc"},
10314
10315 {WE_GET_TX_STBC,
10316 0,
10317 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10318 "get_tx_stbc"},
10319
10320 {WE_GET_RX_STBC,
10321 0,
10322 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10323 "get_rx_stbc"},
10324
10325 {WE_GET_SHORT_GI,
10326 0,
10327 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10328 "get_shortgi"},
10329
10330 {WE_GET_RTSCTS,
10331 0,
10332 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10333 "get_rtscts"},
10334
10335 {WE_GET_CHWIDTH,
10336 0,
10337 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10338 "get_chwidth"},
10339
10340 {WE_GET_ANI_EN_DIS,
10341 0,
10342 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10343 "get_anienable"},
10344
10345 {WE_GET_ANI_POLL_PERIOD,
10346 0,
10347 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10348 "get_aniplen"},
10349
10350 {WE_GET_ANI_LISTEN_PERIOD,
10351 0,
10352 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10353 "get_anilislen"},
10354
10355 {WE_GET_ANI_OFDM_LEVEL,
10356 0,
10357 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10358 "get_aniofdmlvl"},
10359
10360 {WE_GET_ANI_CCK_LEVEL,
10361 0,
10362 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10363 "get_aniccklvl"},
10364
10365 {WE_GET_DYNAMIC_BW,
10366 0,
10367 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10368 "get_cwmenable"},
10369
10370 {WE_GET_GTX_HT_MCS,
10371 0,
10372 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10373 "get_gtxHTMcs"},
10374
10375 {WE_GET_GTX_VHT_MCS,
10376 0,
10377 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10378 "get_gtxVHTMcs"},
10379
10380 {WE_GET_GTX_USRCFG,
10381 0,
10382 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10383 "get_gtxUsrCfg"},
10384
10385 {WE_GET_GTX_THRE,
10386 0,
10387 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10388 "get_gtxThre"},
10389
10390 {WE_GET_GTX_MARGIN,
10391 0,
10392 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10393 "get_gtxMargin"},
10394
10395 {WE_GET_GTX_STEP,
10396 0,
10397 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10398 "get_gtxStep"},
10399
10400 {WE_GET_GTX_MINTPC,
10401 0,
10402 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10403 "get_gtxMinTpc"},
10404
10405 {WE_GET_GTX_BWMASK,
10406 0,
10407 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10408 "get_gtxBWMask"},
10409
10410 {WE_GET_TX_CHAINMASK,
10411 0,
10412 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10413 "get_txchainmask"},
10414
10415 {WE_GET_RX_CHAINMASK,
10416 0,
10417 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10418 "get_rxchainmask"},
10419
10420 {WE_GET_11N_RATE,
10421 0,
10422 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10423 "get_11nrate"},
10424
10425 {WE_GET_AMPDU,
10426 0,
10427 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10428 "get_ampdu"},
10429
10430 {WE_GET_AMSDU,
10431 0,
10432 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10433 "get_amsdu"},
10434
10435 {WE_GET_BURST_ENABLE,
10436 0,
10437 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10438 "get_burst_en"},
10439
10440 {WE_GET_BURST_DUR,
10441 0,
10442 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10443 "get_burst_dur"},
10444
10445 {WE_GET_TXPOW_2G,
10446 0,
10447 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10448 "get_txpow2g"},
10449
10450 {WE_GET_TXPOW_5G,
10451 0,
10452 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10453 "get_txpow5g"},
10454
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080010455 {WE_GET_PPS_PAID_MATCH,
10456 0,
10457 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10458 "get_paid_match"},
10459
10460 {WE_GET_PPS_GID_MATCH,
10461 0,
10462 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10463 "get_gid_match"},
10464
10465 {WE_GET_PPS_EARLY_TIM_CLEAR,
10466 0,
10467 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10468 "get_tim_clear"},
10469
10470 {WE_GET_PPS_EARLY_DTIM_CLEAR,
10471 0,
10472 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10473 "get_dtim_clear"},
10474
10475 {WE_GET_PPS_EOF_PAD_DELIM,
10476 0,
10477 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10478 "get_eof_delim"},
10479
10480 {WE_GET_PPS_MACADDR_MISMATCH,
10481 0,
10482 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10483 "get_mac_match"},
10484
10485 {WE_GET_PPS_DELIM_CRC_FAIL,
10486 0,
10487 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10488 "get_delim_fail"},
10489
10490 {WE_GET_PPS_GID_NSTS_ZERO,
10491 0,
10492 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10493 "get_nsts_zero"},
10494
10495 {WE_GET_PPS_RSSI_CHECK,
10496 0,
10497 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10498 "get_rssi_chk"},
10499
10500 {WE_GET_QPOWER_MAX_PSPOLL_COUNT,
10501 0,
10502 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10503 "get_qpspollcnt"},
10504
10505 {WE_GET_QPOWER_MAX_TX_BEFORE_WAKE,
10506 0,
10507 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10508 "get_qtxwake"},
10509
10510 {WE_GET_QPOWER_SPEC_PSPOLL_WAKE_INTERVAL,
10511 0,
10512 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10513 "get_qwakeintv"},
10514
10515 {WE_GET_QPOWER_SPEC_MAX_SPEC_NODATA_PSPOLL,
10516 0,
10517 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10518 "get_qnodatapoll"},
10519
Manikandan Mohandcc21ba2016-03-15 14:31:56 -070010520 {WE_CAP_TSF,
10521 0,
10522 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10523 "cap_tsf"},
10524
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080010525 {WE_GET_TEMPERATURE,
10526 0,
10527 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10528 "get_temp"},
10529 /* handlers for main ioctl */
10530 {WLAN_PRIV_SET_CHAR_GET_NONE,
10531 IW_PRIV_TYPE_CHAR | 512,
10532 0,
10533 ""},
10534
10535 /* handlers for sub-ioctl */
10536 {WE_WOWL_ADD_PTRN,
10537 IW_PRIV_TYPE_CHAR | 512,
10538 0,
10539 "wowlAddPtrn"},
10540
10541 {WE_WOWL_DEL_PTRN,
10542 IW_PRIV_TYPE_CHAR | 512,
10543 0,
10544 "wowlDelPtrn"},
10545
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080010546 /* handlers for sub-ioctl */
10547 {WE_NEIGHBOR_REPORT_REQUEST,
10548 IW_PRIV_TYPE_CHAR | 512,
10549 0,
10550 "neighbor"},
Deepak Dhamdhere641bf322016-01-06 15:19:03 -080010551
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080010552 {WE_SET_AP_WPS_IE,
10553 IW_PRIV_TYPE_CHAR | 512,
10554 0,
10555 "set_ap_wps_ie"},
10556
10557 {WE_SET_CONFIG,
10558 IW_PRIV_TYPE_CHAR | 512,
10559 0,
10560 "setConfig"},
10561
10562 /* handlers for main ioctl */
10563 {WLAN_PRIV_SET_THREE_INT_GET_NONE,
10564 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 3,
10565 0,
10566 ""},
10567
10568 /* handlers for sub-ioctl */
10569 {WE_SET_WLAN_DBG,
10570 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 3,
10571 0,
10572 "setwlandbg"},
10573
10574 /* handlers for sub-ioctl */
10575 {WE_SET_DP_TRACE,
10576 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 3,
10577 0,
10578 "set_dp_trace"},
10579
10580 {WE_SET_SAP_CHANNELS,
10581 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 3,
10582 0,
10583 "setsapchannels"},
Manikandan Mohandcc21ba2016-03-15 14:31:56 -070010584 /* handlers for main ioctl */
10585 {WLAN_PRIV_SET_NONE_GET_THREE_INT,
10586 0,
10587 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 3,
10588 "" },
10589 {WE_GET_TSF,
10590 0,
10591 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 3,
10592 "get_tsf" },
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080010593
10594 {WE_SET_DUAL_MAC_SCAN_CONFIG,
10595 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 3,
10596 0,
10597 "set_scan_cfg"},
10598
10599 /* handlers for main ioctl */
10600 {WLAN_PRIV_GET_CHAR_SET_NONE,
10601 0,
10602 IW_PRIV_TYPE_CHAR | WE_MAX_STR_LEN,
10603 ""},
10604
10605 /* handlers for sub-ioctl */
10606 {WE_WLAN_VERSION,
10607 0,
10608 IW_PRIV_TYPE_CHAR | WE_MAX_STR_LEN,
10609 "version"},
10610 {WE_GET_STATS,
10611 0,
10612 IW_PRIV_TYPE_CHAR | WE_MAX_STR_LEN,
10613 "getStats"},
Govind Singha471e5e2015-10-12 17:11:14 +053010614 {WE_LIST_FW_PROFILE,
10615 0,
10616 IW_PRIV_TYPE_CHAR | WE_MAX_STR_LEN,
10617 "listProfile"},
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080010618 {WE_GET_STATES,
10619 0,
10620 IW_PRIV_TYPE_CHAR | WE_MAX_STR_LEN,
10621 "getHostStates"},
10622 {WE_GET_CFG,
10623 0,
10624 IW_PRIV_TYPE_CHAR | WE_MAX_STR_LEN,
10625 "getConfig"},
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080010626 {WE_GET_RSSI,
10627 0,
10628 IW_PRIV_TYPE_CHAR | WE_MAX_STR_LEN,
10629 "getRSSI"},
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080010630 {WE_GET_WMM_STATUS,
10631 0,
10632 IW_PRIV_TYPE_CHAR | WE_MAX_STR_LEN,
10633 "getWmmStatus"},
10634 {
10635 WE_GET_CHANNEL_LIST,
10636 0,
10637 IW_PRIV_TYPE_CHAR | WE_MAX_STR_LEN,
10638 "getChannelList"
10639 },
10640#ifdef FEATURE_WLAN_TDLS
10641 {
10642 WE_GET_TDLS_PEERS,
10643 0,
10644 IW_PRIV_TYPE_CHAR | WE_MAX_STR_LEN,
10645 "getTdlsPeers"
10646 },
10647#endif
10648#ifdef WLAN_FEATURE_11W
10649 {
10650 WE_GET_11W_INFO,
10651 0,
10652 IW_PRIV_TYPE_CHAR | WE_MAX_STR_LEN,
10653 "getPMFInfo"
10654 },
10655#endif
Rajeev Kumar8e3e2832015-11-06 16:02:54 -080010656 {
10657 WE_GET_IBSS_STA_INFO,
10658 0,
10659 IW_PRIV_TYPE_CHAR | WE_MAX_STR_LEN,
10660 "getIbssSTAs"
10661 },
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080010662 {WE_GET_PHYMODE,
10663 0,
10664 IW_PRIV_TYPE_CHAR | WE_MAX_STR_LEN,
10665 "getphymode"},
10666#ifdef FEATURE_OEM_DATA_SUPPORT
10667 {WE_GET_OEM_DATA_CAP,
10668 0,
10669 IW_PRIV_TYPE_CHAR | WE_MAX_STR_LEN,
10670 "getOemDataCap"},
10671#endif /* FEATURE_OEM_DATA_SUPPORT */
10672 {WE_GET_SNR,
10673 0,
10674 IW_PRIV_TYPE_CHAR | WE_MAX_STR_LEN,
10675 "getSNR"},
10676
10677 /* handlers for main ioctl */
10678 {WLAN_PRIV_SET_NONE_GET_NONE,
10679 0,
10680 0,
10681 ""},
10682
Rajeev Kumar8e3e2832015-11-06 16:02:54 -080010683 /* handlers for sub-ioctl */
10684 {
10685 WE_IBSS_GET_PEER_INFO_ALL,
10686 0,
10687 0,
10688 "ibssPeerInfoAll"
10689 },
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080010690 {WE_GET_RECOVERY_STAT,
10691 0,
10692 0,
10693 "getRecoverStat"},
Govind Singha471e5e2015-10-12 17:11:14 +053010694
10695 {WE_GET_FW_PROFILE_DATA,
10696 0,
10697 0,
10698 "getProfileData"},
10699
10700 {WE_SET_REASSOC_TRIGGER,
10701 0,
10702 0,
10703 "reassoc"},
10704
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080010705 {WE_DUMP_AGC_START,
10706 0,
10707 0,
10708 "dump_agc_start"},
10709
10710 {WE_DUMP_AGC,
10711 0,
10712 0,
10713 "dump_agc"},
10714
10715 {WE_DUMP_CHANINFO_START,
10716 0,
10717 0,
10718 "dump_chninfo_en"},
10719
10720 {WE_DUMP_CHANINFO,
10721 0,
10722 0,
10723 "dump_chninfo"},
10724
10725 {WE_DUMP_WATCHDOG,
10726 0,
10727 0,
10728 "dump_watchdog"},
10729#ifdef CONFIG_ATH_PCIE_ACCESS_DEBUG
10730 {WE_DUMP_PCIE_LOG,
10731 0,
10732 0,
10733 "dump_pcie_log"},
10734#endif
Sandeep Puligilla93a29ec2016-02-12 16:10:56 -080010735 {WE_STOP_OBSS_SCAN,
10736 0,
10737 0,
10738 "stop_obss_scan"},
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080010739 /* handlers for main ioctl */
10740 {WLAN_PRIV_SET_VAR_INT_GET_NONE,
10741 IW_PRIV_TYPE_INT | MAX_VAR_ARGS,
10742 0,
10743 ""},
10744
10745 /* handlers for sub-ioctl */
Rajeev Kumar8e3e2832015-11-06 16:02:54 -080010746 {WE_IBSS_GET_PEER_INFO,
10747 IW_PRIV_TYPE_INT | MAX_VAR_ARGS,
10748 0,
10749 "ibssPeerInfo"},
10750
10751 /* handlers for sub-ioctl */
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080010752 {WE_MTRACE_SELECTIVE_MODULE_LOG_ENABLE_CMD,
10753 IW_PRIV_TYPE_INT | MAX_VAR_ARGS,
10754 0,
10755 "setdumplog"},
10756
10757 {WE_MTRACE_DUMP_CMD,
10758 IW_PRIV_TYPE_INT | MAX_VAR_ARGS,
10759 0,
10760 "dumplog"},
10761#ifdef MPC_UT_FRAMEWORK
10762 {WE_POLICY_MANAGER_CLIST_CMD,
10763 IW_PRIV_TYPE_INT | MAX_VAR_ARGS,
10764 0,
10765 "pm_clist"},
10766
10767 {WE_POLICY_MANAGER_DLIST_CMD,
10768 IW_PRIV_TYPE_INT | MAX_VAR_ARGS,
10769 0,
10770 "pm_dlist"},
10771
10772 {WE_POLICY_MANAGER_DBS_CMD,
10773 IW_PRIV_TYPE_INT | MAX_VAR_ARGS,
10774 0,
10775 "pm_dbs"},
10776
10777 {WE_POLICY_MANAGER_PCL_CMD,
10778 IW_PRIV_TYPE_INT | MAX_VAR_ARGS,
10779 0,
10780 "pm_pcl"},
10781
10782 {WE_POLICY_MANAGER_CINFO_CMD,
10783 IW_PRIV_TYPE_INT | MAX_VAR_ARGS,
10784 0,
10785 "pm_cinfo"},
10786
10787 {WE_POLICY_MANAGER_ULIST_CMD,
10788 IW_PRIV_TYPE_INT | MAX_VAR_ARGS,
10789 0,
10790 "pm_ulist"},
10791
10792 {WE_POLICY_MANAGER_QUERY_ACTION_CMD,
10793 IW_PRIV_TYPE_INT | MAX_VAR_ARGS,
10794 0,
10795 "pm_query_action"},
10796
10797 {WE_POLICY_MANAGER_QUERY_ALLOW_CMD,
10798 IW_PRIV_TYPE_INT | MAX_VAR_ARGS,
10799 0,
10800 "pm_query_allow"},
10801
10802 {WE_POLICY_MANAGER_SCENARIO_CMD,
10803 IW_PRIV_TYPE_INT | MAX_VAR_ARGS,
10804 0,
10805 "pm_run_scenario"},
10806
10807 {WE_POLICY_SET_HW_MODE_CMD,
10808 IW_PRIV_TYPE_INT | MAX_VAR_ARGS,
10809 0,
10810 "pm_set_hw_mode"},
10811#endif
10812#ifdef FEATURE_WLAN_TDLS
10813 /* handlers for sub ioctl */
10814 {
10815 WE_TDLS_CONFIG_PARAMS,
10816 IW_PRIV_TYPE_INT | MAX_VAR_ARGS,
10817 0,
10818 "setTdlsConfig"
10819 },
10820#endif
10821 {
10822 WE_UNIT_TEST_CMD,
10823 IW_PRIV_TYPE_INT | MAX_VAR_ARGS,
10824 0,
10825 "setUnitTestCmd"
10826 },
Manjeet Singhf82ed072016-07-08 11:40:00 +053010827 {
10828 WE_MAC_PWR_DEBUG_CMD,
10829 IW_PRIV_TYPE_INT | MAX_VAR_ARGS,
10830 0,
10831 "halPwrDebug"
10832 },
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080010833
10834#ifdef WLAN_FEATURE_GPIO_LED_FLASHING
10835 {WE_LED_FLASHING_PARAM,
10836 IW_PRIV_TYPE_INT | MAX_VAR_ARGS,
10837 0,
10838 "gpio_control"},
10839#endif
10840 /* handlers for main ioctl */
10841 {WLAN_PRIV_ADD_TSPEC,
10842 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | HDD_WLAN_WMM_PARAM_COUNT,
10843 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10844 "addTspec"},
10845
10846 /* handlers for main ioctl */
10847 {WLAN_PRIV_DEL_TSPEC,
10848 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10849 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10850 "delTspec"},
10851
10852 /* handlers for main ioctl */
10853 {WLAN_PRIV_GET_TSPEC,
10854 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10855 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10856 "getTspec"},
10857
10858 /* handlers for main ioctl - host offload */
10859 {
10860 WLAN_PRIV_SET_HOST_OFFLOAD,
10861 IW_PRIV_TYPE_BYTE | sizeof(tHostOffloadRequest),
10862 0,
10863 "setHostOffload"
10864 }
10865 ,
10866
10867 {
10868 WLAN_GET_WLAN_STATISTICS,
10869 0,
10870 IW_PRIV_TYPE_BYTE | WE_MAX_STR_LEN,
10871 "getWlanStats"
10872 }
10873 ,
10874
10875 {
10876 WLAN_SET_KEEPALIVE_PARAMS,
Mahesh A Saptasagar72d2e4b2016-04-20 12:44:17 +053010877 IW_PRIV_TYPE_BYTE | sizeof(tSirKeepAliveReq) |
10878 IW_PRIV_SIZE_FIXED,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080010879 0,
10880 "setKeepAlive"
10881 }
10882 ,
10883#ifdef WLAN_FEATURE_PACKET_FILTERING
10884 {
10885 WLAN_SET_PACKET_FILTER_PARAMS,
10886 IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED |
10887 sizeof(struct pkt_filter_cfg),
10888 0,
10889 "setPktFilter"
10890 }
10891 ,
10892#endif
10893#ifdef FEATURE_WLAN_SCAN_PNO
10894 {
10895 WLAN_SET_PNO,
10896 IW_PRIV_TYPE_CHAR | WE_MAX_STR_LEN,
10897 0,
10898 "setpno"
10899 }
10900 ,
10901#endif
10902 {
10903 WLAN_SET_BAND_CONFIG,
10904 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10905 0,
10906 "SETBAND"
10907 }
10908 ,
10909 {
10910 WLAN_GET_LINK_SPEED,
10911 IW_PRIV_TYPE_CHAR | 18,
10912 IW_PRIV_TYPE_CHAR | 5, "getLinkSpeed"
10913 }
10914 ,
10915
10916 /* handlers for main ioctl */
10917 {WLAN_PRIV_SET_TWO_INT_GET_NONE,
10918 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2,
10919 0,
10920 ""}
10921 ,
10922 {WE_SET_SMPS_PARAM,
10923 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2,
10924 0, "set_smps_param"}
10925 ,
10926 {WLAN_SET_DOT11P_CHANNEL_SCHED,
10927 IW_PRIV_TYPE_BYTE | sizeof(struct dot11p_channel_sched),
10928 0, "set_dot11p" }
10929 ,
10930#ifdef DEBUG
10931 {WE_SET_FW_CRASH_INJECT,
10932 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2,
10933 0, "crash_inject"}
10934 ,
10935#endif
Rajeev Kumara78a0a42016-07-13 19:28:20 -070010936#ifdef WLAN_SUSPEND_RESUME_TEST
10937 {WE_SET_WLAN_SUSPEND,
10938 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2,
10939 0, "wlan_suspend"}
10940 ,
10941 {WE_SET_WLAN_RESUME,
10942 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2,
10943 0, "wlan_resume"}
10944 ,
10945#endif
Govind Singha471e5e2015-10-12 17:11:14 +053010946 {WE_ENABLE_FW_PROFILE,
10947 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2,
10948 0, "enableProfile"}
10949 ,
10950 {WE_SET_FW_PROFILE_HIST_INTVL,
10951 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2,
10952 0, "set_hist_intvl"}
10953 ,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080010954 {WE_SET_DUAL_MAC_FW_MODE_CONFIG,
10955 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2,
10956 0, "set_fw_mode_cfg"}
10957 ,
10958 {WE_DUMP_DP_TRACE_LEVEL,
10959 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2,
10960 0, "dump_dp_trace"}
10961 ,
Manjunathappa Prakash59f861d2016-04-21 10:33:31 -070010962 {WE_SET_MON_MODE_CHAN,
10963 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2,
10964 0, "setMonChan"}
10965 ,
Varun Reddy Yeturu5ab47462016-05-08 18:08:11 -070010966
10967 {WE_GET_ROAM_SYNCH_DELAY,
10968 0,
10969 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10970 "hostroamdelay"}
10971 ,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080010972};
10973
10974const struct iw_handler_def we_handler_def = {
Anurag Chouhan6d760662016-02-20 16:05:43 +053010975 .num_standard = QDF_ARRAY_SIZE(we_handler),
10976 .num_private = QDF_ARRAY_SIZE(we_private),
10977 .num_private_args = QDF_ARRAY_SIZE(we_private_args),
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080010978
10979 .standard = (iw_handler *) we_handler,
10980 .private = (iw_handler *) we_private,
10981 .private_args = we_private_args,
10982 .get_wireless_stats = NULL,
10983};
10984
Deepak Dhamdhere8360d4c2016-06-01 13:24:31 -070010985/* hdd_set_wext() - configures bss parameters
10986 * @pAdapter: handle to adapter context
10987 *
10988 * Returns: none
10989 */
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080010990int hdd_set_wext(hdd_adapter_t *pAdapter)
10991{
Deepak Dhamdhere8360d4c2016-06-01 13:24:31 -070010992 hdd_wext_state_t *pwextBuf = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
10993 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080010994
Deepak Dhamdhere8360d4c2016-06-01 13:24:31 -070010995 ENTER();
10996
10997 if (!pwextBuf) {
10998 hdd_err("ERROR: pwextBuf is NULL");
10999 return QDF_STATUS_E_FAILURE;
11000 }
11001
11002 if (!pHddStaCtx) {
11003 hdd_err("ERROR: pHddStaCtx is NULL");
11004 return QDF_STATUS_E_FAILURE;
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -070011005 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011006
11007 /* Now configure the roaming profile links. To SSID and bssid. */
11008 pwextBuf->roamProfile.SSIDs.numOfSSIDs = 0;
Deepak Dhamdhere8360d4c2016-06-01 13:24:31 -070011009 pwextBuf->roamProfile.SSIDs.SSIDList = &pHddStaCtx->conn_info.SSID;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011010
11011 pwextBuf->roamProfile.BSSIDs.numOfBSSIDs = 0;
Deepak Dhamdhere8360d4c2016-06-01 13:24:31 -070011012 pwextBuf->roamProfile.BSSIDs.bssid = &pHddStaCtx->conn_info.bssId;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011013
11014 /*Set the numOfChannels to zero to scan all the channels */
11015 pwextBuf->roamProfile.ChannelInfo.numOfChannels = 0;
11016 pwextBuf->roamProfile.ChannelInfo.ChannelList = NULL;
11017
11018 /* Default is no encryption */
11019 pwextBuf->roamProfile.EncryptionType.numEntries = 1;
11020 pwextBuf->roamProfile.EncryptionType.encryptionType[0] =
11021 eCSR_ENCRYPT_TYPE_NONE;
11022
11023 pwextBuf->roamProfile.mcEncryptionType.numEntries = 1;
11024 pwextBuf->roamProfile.mcEncryptionType.encryptionType[0] =
11025 eCSR_ENCRYPT_TYPE_NONE;
11026
11027 pwextBuf->roamProfile.BSSType = eCSR_BSS_TYPE_INFRASTRUCTURE;
11028
11029 /* Default is no authentication */
11030 pwextBuf->roamProfile.AuthType.numEntries = 1;
11031 pwextBuf->roamProfile.AuthType.authType[0] = eCSR_AUTH_TYPE_OPEN_SYSTEM;
11032
11033 pwextBuf->roamProfile.phyMode = eCSR_DOT11_MODE_AUTO;
11034 pwextBuf->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
11035
11036 /*Set the default scan mode */
11037 pAdapter->scan_info.scan_mode = eSIR_ACTIVE_SCAN;
11038
11039 hdd_clear_roam_profile_ie(pAdapter);
11040
Deepak Dhamdhere8360d4c2016-06-01 13:24:31 -070011041 EXIT();
Anurag Chouhanfb54ab02016-02-18 18:00:46 +053011042 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011043
11044}
11045
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -070011046/**
11047 * hdd_register_wext() - register wext context
11048 * @dev: net device handle
11049 *
11050 * Registers wext interface context for a given net device
11051 *
11052 * Returns: 0 on success, errno on failure
11053 */
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011054int hdd_register_wext(struct net_device *dev)
11055{
11056 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Deepak Dhamdhere8360d4c2016-06-01 13:24:31 -070011057 hdd_wext_state_t *pwextBuf = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Anurag Chouhance0dc992016-02-16 18:18:03 +053011058 QDF_STATUS status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011059
11060 ENTER();
11061
Deepak Dhamdhere8360d4c2016-06-01 13:24:31 -070011062 if (!pwextBuf) {
11063 hdd_err(FL("ERROR: pwextBuf is NULL"));
11064 return QDF_STATUS_E_FAILURE;
11065 }
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -070011066
11067 /* Zero the memory. This zeros the profile structure */
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011068 memset(pwextBuf, 0, sizeof(hdd_wext_state_t));
11069
11070 init_completion(&(WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter))->
11071 completion_var);
11072
11073 status = hdd_set_wext(pAdapter);
11074
Anurag Chouhance0dc992016-02-16 18:18:03 +053011075 if (!QDF_IS_STATUS_SUCCESS(status)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011076
Jeff Johnson99bac312016-06-28 10:38:18 -070011077 hdd_err("ERROR: hdd_set_wext failed!!");
Anurag Chouhanfb54ab02016-02-18 18:00:46 +053011078 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011079 }
11080
Anurag Chouhanf04e84f2016-03-03 10:12:12 +053011081 if (!QDF_IS_STATUS_SUCCESS(qdf_event_create(&pwextBuf->hdd_qdf_event))) {
Jeff Johnson99bac312016-06-28 10:38:18 -070011082 hdd_err("ERROR: HDD qdf event init failed!!");
Anurag Chouhanfb54ab02016-02-18 18:00:46 +053011083 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011084 }
11085
Anurag Chouhance0dc992016-02-16 18:18:03 +053011086 if (!QDF_IS_STATUS_SUCCESS(qdf_event_create(&pwextBuf->scanevent))) {
Jeff Johnson99bac312016-06-28 10:38:18 -070011087 hdd_err("ERROR: HDD scan event init failed!!");
Anurag Chouhanfb54ab02016-02-18 18:00:46 +053011088 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011089 }
11090 /* Register as a wireless device */
11091 dev->wireless_handlers = (struct iw_handler_def *)&we_handler_def;
11092
11093 EXIT();
11094 return 0;
11095}
11096
11097int hdd_unregister_wext(struct net_device *dev)
11098{
Jeff Johnson99bac312016-06-28 10:38:18 -070011099 hdd_notice("dev(%p)", dev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011100
11101 if (dev != NULL) {
11102 rtnl_lock();
11103 dev->wireless_handlers = NULL;
11104 rtnl_unlock();
11105 }
11106
11107 return 0;
11108}