blob: b88b01bf11ed89e58e60417e780dcb9d3ce2d620 [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
34#include <linux/version.h>
35#include <linux/module.h>
36#include <linux/kernel.h>
37#include <linux/init.h>
38#include <linux/wireless.h>
39#include <mac_trace.h>
40#include <wlan_hdd_includes.h>
41#include <cds_api.h>
42#include <net/arp.h>
Manjunathappa Prakash3454fd62016-04-01 08:52:06 -070043#include <cdp_txrx_stats.h>
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080044#include "sir_params.h"
45#include "csr_api.h"
46#include "csr_inside_api.h"
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080047#include "sme_rrm_internal.h"
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080048#include <ani_global.h>
49#include "dot11f.h"
50#include <wlan_hdd_wowl.h>
51#include <wlan_hdd_cfg.h>
52#include <wlan_hdd_wmm.h>
53#include "utils_api.h"
54#include "wlan_hdd_p2p.h"
55#ifdef FEATURE_WLAN_TDLS
56#include "wlan_hdd_tdls.h"
57#endif
58
59#include "cds_ieee80211_common.h"
60#include "ol_if_athvar.h"
61#include "dbglog_host.h"
62#include "wma.h"
63
64#include "wlan_hdd_power.h"
65#include "qwlan_version.h"
66#include "wlan_hdd_host_offload.h"
67
68#include <linux/wireless.h>
69#include <net/cfg80211.h>
70
71#include "wlan_hdd_misc.h"
72
73#include "qc_sap_ioctl.h"
74#include "sme_api.h"
75#include "wma_types.h"
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +053076#include "qdf_trace.h"
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080077#include "wlan_hdd_assoc.h"
78#include "wlan_hdd_ioctl.h"
79#include "wlan_hdd_scan.h"
80#include "sme_power_save_api.h"
81#include "cds_concurrency.h"
82#include "wlan_hdd_conc_ut.h"
Manikandan Mohandcc21ba2016-03-15 14:31:56 -070083#include "wlan_hdd_tsf.h"
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080084#include "wlan_hdd_ocb.h"
85#include "wlan_hdd_napi.h"
Dhanashri Atreb08959a2016-03-01 17:28:03 -080086#include "cdp_txrx_flow_ctrl_legacy.h"
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080087
88#ifdef QCA_PKT_PROTO_TRACE
89#include "cds_packet.h"
90#endif /* QCA_PKT_PROTO_TRACE */
91
92#define HDD_FINISH_ULA_TIME_OUT 800
93#define HDD_SET_MCBC_FILTERS_TO_FW 1
94#define HDD_DELETE_MCBC_FILTERS_FROM_FW 0
95
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080096static int ioctl_debug;
97module_param(ioctl_debug, int, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
98
99/* To Validate Channel against the Frequency and Vice-Versa */
100static const hdd_freq_chan_map_t freq_chan_map[] = {
101 {2412, 1}, {2417, 2}, {2422, 3}, {2427, 4}, {2432, 5}, {2437, 6},
102 {2442, 7}, {2447, 8}, {2452, 9}, {2457, 10}, {2462, 11}, {2467, 12},
103 {2472, 13}, {2484, 14}, {4920, 240}, {4940, 244}, {4960, 248},
104 {4980, 252}, {5040, 208}, {5060, 212}, {5080, 216}, {5180, 36},
105 {5200, 40}, {5220, 44}, {5240, 48}, {5260, 52}, {5280, 56},
106 {5300, 60}, {5320, 64}, {5500, 100}, {5520, 104}, {5540, 108},
107 {5560, 112}, {5580, 116}, {5600, 120}, {5620, 124}, {5640, 128},
108 {5660, 132}, {5680, 136}, {5700, 140}, {5720, 144}, {5745, 149},
109 {5765, 153}, {5785, 157}, {5805, 161}, {5825, 165}, {5852, 170},
110 {5855, 171}, {5860, 172}, {5865, 173}, {5870, 174}, {5875, 175},
111 {5880, 176}, {5885, 177}, {5890, 178}, {5895, 179}, {5900, 180},
112 {5905, 181}, {5910, 182}, {5915, 183}, {5920, 184} };
113
114#define FREQ_CHAN_MAP_TABLE_SIZE \
115 (sizeof(freq_chan_map) / sizeof(freq_chan_map[0]))
116
117/* Private ioctls and their sub-ioctls */
118#define WLAN_PRIV_SET_INT_GET_NONE (SIOCIWFIRSTPRIV + 0)
119#define WE_SET_11D_STATE 1
120#define WE_WOWL 2
121#define WE_SET_POWER 3
122#define WE_SET_MAX_ASSOC 4
123#define WE_SET_SCAN_DISABLE 5
124#define WE_SET_DATA_INACTIVITY_TO 6
125#define WE_SET_MAX_TX_POWER 7
126#define WE_SET_HIGHER_DTIM_TRANSITION 8
127#define WE_SET_TM_LEVEL 9
128#define WE_SET_PHYMODE 10
129#define WE_SET_NSS 11
130#define WE_SET_LDPC 12
131#define WE_SET_TX_STBC 13
132#define WE_SET_RX_STBC 14
133#define WE_SET_SHORT_GI 15
134#define WE_SET_RTSCTS 16
135#define WE_SET_CHWIDTH 17
136#define WE_SET_ANI_EN_DIS 18
137#define WE_SET_ANI_POLL_PERIOD 19
138#define WE_SET_ANI_LISTEN_PERIOD 20
139#define WE_SET_ANI_OFDM_LEVEL 21
140#define WE_SET_ANI_CCK_LEVEL 22
141#define WE_SET_DYNAMIC_BW 23
142#define WE_SET_TX_CHAINMASK 24
143#define WE_SET_RX_CHAINMASK 25
144#define WE_SET_11N_RATE 26
145#define WE_SET_AMPDU 27
146#define WE_SET_AMSDU 28
147#define WE_SET_TXPOW_2G 29
148#define WE_SET_TXPOW_5G 30
149/* Private ioctl for firmware debug log */
150#define WE_DBGLOG_LOG_LEVEL 31
151#define WE_DBGLOG_VAP_ENABLE 32
152#define WE_DBGLOG_VAP_DISABLE 33
153#define WE_DBGLOG_MODULE_ENABLE 34
154#define WE_DBGLOG_MODULE_DISABLE 35
155#define WE_DBGLOG_MOD_LOG_LEVEL 36
156#define WE_DBGLOG_TYPE 37
157#define WE_SET_TXRX_FWSTATS 38
158#define WE_SET_VHT_RATE 39
159#define WE_DBGLOG_REPORT_ENABLE 40
160#define WE_TXRX_FWSTATS_RESET 41
161#define WE_SET_MAX_TX_POWER_2_4 42
162#define WE_SET_MAX_TX_POWER_5_0 43
Rajeev Kumar1bcfd632015-12-07 11:38:51 -0800163/* 44 is unused */
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800164/* Private ioctl for packet powe save */
165#define WE_PPS_PAID_MATCH 45
166#define WE_PPS_GID_MATCH 46
167#define WE_PPS_EARLY_TIM_CLEAR 47
168#define WE_PPS_EARLY_DTIM_CLEAR 48
169#define WE_PPS_EOF_PAD_DELIM 49
170#define WE_PPS_MACADDR_MISMATCH 50
171#define WE_PPS_DELIM_CRC_FAIL 51
172#define WE_PPS_GID_NSTS_ZERO 52
173#define WE_PPS_RSSI_CHECK 53
174#define WE_SET_SAP_AUTO_CHANNEL_SELECTION 54
175#define WE_SET_HTSMPS 55
176/* Private ioctl for QPower */
177#define WE_SET_QPOWER_MAX_PSPOLL_COUNT 56
178#define WE_SET_QPOWER_MAX_TX_BEFORE_WAKE 57
179#define WE_SET_QPOWER_SPEC_PSPOLL_WAKE_INTERVAL 58
180#define WE_SET_QPOWER_SPEC_MAX_SPEC_NODATA_PSPOLL 59
181
182#define WE_SET_BURST_ENABLE 60
183#define WE_SET_BURST_DUR 61
184/* GTX Commands */
185#define WE_SET_GTX_HT_MCS 62
186#define WE_SET_GTX_VHT_MCS 63
187#define WE_SET_GTX_USRCFG 64
188#define WE_SET_GTX_THRE 65
189#define WE_SET_GTX_MARGIN 66
190#define WE_SET_GTX_STEP 67
191#define WE_SET_GTX_MINTPC 68
192#define WE_SET_GTX_BWMASK 69
193/* Private ioctl to configure MCC home channels time quota and latency */
194#define WE_MCC_CONFIG_LATENCY 70
195#define WE_MCC_CONFIG_QUOTA 71
196/* Private IOCTL for debug connection issues */
197#define WE_SET_DEBUG_LOG 72
198#ifdef WE_SET_TX_POWER
199#undef WE_SET_TX_POWER
200#endif
201#define WE_SET_TX_POWER 74
202/* Private ioctl for earlyrx power save feature */
203#define WE_SET_EARLY_RX_ADJUST_ENABLE 75
204#define WE_SET_EARLY_RX_TGT_BMISS_NUM 76
205#define WE_SET_EARLY_RX_BMISS_SAMPLE_CYCLE 77
206#define WE_SET_EARLY_RX_SLOP_STEP 78
207#define WE_SET_EARLY_RX_INIT_SLOP 79
208#define WE_SET_EARLY_RX_ADJUST_PAUSE 80
209#define WE_SET_MC_RATE 81
210#define WE_SET_EARLY_RX_DRIFT_SAMPLE 82
211/* Private ioctl for packet power save */
212#define WE_PPS_5G_EBT 83
213#define WE_SET_CTS_CBW 84
214#define WE_DUMP_STATS 85
215#define WE_CLEAR_STATS 86
Govind Singha471e5e2015-10-12 17:11:14 +0530216/* Private sub ioctl for starting/stopping the profiling */
217#define WE_START_FW_PROFILE 87
Abhishek Singh1bdb1572015-10-16 16:24:19 +0530218#define WE_SET_CHANNEL 88
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800219
220/* Private ioctls and their sub-ioctls */
221#define WLAN_PRIV_SET_NONE_GET_INT (SIOCIWFIRSTPRIV + 1)
222#define WE_GET_11D_STATE 1
223#define WE_IBSS_STATUS 2
224#define WE_SET_SAP_CHANNELS 3
225#define WE_GET_WLAN_DBG 4
226#define WE_GET_MAX_ASSOC 6
227/* 7 is unused */
228#define WE_GET_SAP_AUTO_CHANNEL_SELECTION 8
229#define WE_GET_CONCURRENCY_MODE 9
230#define WE_GET_NSS 11
231#define WE_GET_LDPC 12
232#define WE_GET_TX_STBC 13
233#define WE_GET_RX_STBC 14
234#define WE_GET_SHORT_GI 15
235#define WE_GET_RTSCTS 16
236#define WE_GET_CHWIDTH 17
237#define WE_GET_ANI_EN_DIS 18
238#define WE_GET_ANI_POLL_PERIOD 19
239#define WE_GET_ANI_LISTEN_PERIOD 20
240#define WE_GET_ANI_OFDM_LEVEL 21
241#define WE_GET_ANI_CCK_LEVEL 22
242#define WE_GET_DYNAMIC_BW 23
243#define WE_GET_TX_CHAINMASK 24
244#define WE_GET_RX_CHAINMASK 25
245#define WE_GET_11N_RATE 26
246#define WE_GET_AMPDU 27
247#define WE_GET_AMSDU 28
248#define WE_GET_TXPOW_2G 29
249#define WE_GET_TXPOW_5G 30
Rajeev Kumar1bcfd632015-12-07 11:38:51 -0800250/* 31 is unused */
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800251#define WE_GET_PPS_PAID_MATCH 32
252#define WE_GET_PPS_GID_MATCH 33
253#define WE_GET_PPS_EARLY_TIM_CLEAR 34
254#define WE_GET_PPS_EARLY_DTIM_CLEAR 35
255#define WE_GET_PPS_EOF_PAD_DELIM 36
256#define WE_GET_PPS_MACADDR_MISMATCH 37
257#define WE_GET_PPS_DELIM_CRC_FAIL 38
258#define WE_GET_PPS_GID_NSTS_ZERO 39
259#define WE_GET_PPS_RSSI_CHECK 40
260/* Private ioctl for QPower */
261#define WE_GET_QPOWER_MAX_PSPOLL_COUNT 41
262#define WE_GET_QPOWER_MAX_TX_BEFORE_WAKE 42
263#define WE_GET_QPOWER_SPEC_PSPOLL_WAKE_INTERVAL 43
264#define WE_GET_QPOWER_SPEC_MAX_SPEC_NODATA_PSPOLL 44
265#define WE_GET_BURST_ENABLE 45
266#define WE_GET_BURST_DUR 46
267/* GTX Commands */
268#define WE_GET_GTX_HT_MCS 47
269#define WE_GET_GTX_VHT_MCS 48
270#define WE_GET_GTX_USRCFG 49
271#define WE_GET_GTX_THRE 50
272#define WE_GET_GTX_MARGIN 51
273#define WE_GET_GTX_STEP 52
274#define WE_GET_GTX_MINTPC 53
275#define WE_GET_GTX_BWMASK 54
276#define WE_GET_TEMPERATURE 56
Manikandan Mohandcc21ba2016-03-15 14:31:56 -0700277#define WE_CAP_TSF 58
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800278
279/* Private ioctls and their sub-ioctls */
280#define WLAN_PRIV_SET_INT_GET_INT (SIOCIWFIRSTPRIV + 2)
281
282/* Private ioctls and their sub-ioctls */
283#define WLAN_PRIV_SET_CHAR_GET_NONE (SIOCIWFIRSTPRIV + 3)
284#define WE_WOWL_ADD_PTRN 1
285#define WE_WOWL_DEL_PTRN 2
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800286#define WE_NEIGHBOR_REPORT_REQUEST 3
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800287#define WE_SET_AP_WPS_IE 4 /* This is called in station mode to set probe rsp ie. */
288#define WE_SET_CONFIG 5
289
290/* Private ioctls and their sub-ioctls */
291#define WLAN_PRIV_SET_THREE_INT_GET_NONE (SIOCIWFIRSTPRIV + 4)
292#define WE_SET_WLAN_DBG 1
293#define WE_SET_DP_TRACE 2
294#define WE_SET_SAP_CHANNELS 3
295
296/* Private ioctls and their sub-ioctls */
297#define WLAN_PRIV_GET_CHAR_SET_NONE (SIOCIWFIRSTPRIV + 5)
298#define WE_WLAN_VERSION 1
299#define WE_GET_STATS 2
300#define WE_GET_CFG 3
301#define WE_GET_WMM_STATUS 4
302#define WE_GET_CHANNEL_LIST 5
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800303#define WE_GET_RSSI 6
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800304#ifdef FEATURE_WLAN_TDLS
305#define WE_GET_TDLS_PEERS 8
306#endif
307#ifdef WLAN_FEATURE_11W
308#define WE_GET_11W_INFO 9
309#endif
310#define WE_GET_STATES 10
Rajeev Kumar8e3e2832015-11-06 16:02:54 -0800311#define WE_GET_IBSS_STA_INFO 11
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800312#define WE_GET_PHYMODE 12
313#ifdef FEATURE_OEM_DATA_SUPPORT
314#define WE_GET_OEM_DATA_CAP 13
315#endif
316#define WE_GET_SNR 14
Govind Singha471e5e2015-10-12 17:11:14 +0530317#define WE_LIST_FW_PROFILE 15
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800318
319/* Private ioctls and their sub-ioctls */
320#define WLAN_PRIV_SET_NONE_GET_NONE (SIOCIWFIRSTPRIV + 6)
321#define WE_SET_REASSOC_TRIGGER 8
Rajeev Kumar8e3e2832015-11-06 16:02:54 -0800322#define WE_IBSS_GET_PEER_INFO_ALL 10
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800323#define WE_DUMP_AGC_START 11
324#define WE_DUMP_AGC 12
325#define WE_DUMP_CHANINFO_START 13
326#define WE_DUMP_CHANINFO 14
327#define WE_DUMP_WATCHDOG 15
328#ifdef CONFIG_ATH_PCIE_ACCESS_DEBUG
329#define WE_DUMP_PCIE_LOG 16
330#endif
331#define WE_GET_RECOVERY_STAT 17
Sandeep Puligilla93a29ec2016-02-12 16:10:56 -0800332#define WE_GET_FW_PROFILE_DATA 18
333#define WE_STOP_OBSS_SCAN 19
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800334
335/* Private ioctls and their sub-ioctls */
336#define WLAN_PRIV_SET_VAR_INT_GET_NONE (SIOCIWFIRSTPRIV + 7)
337
338#define WE_P2P_NOA_CMD 2
339
340/* subcommands 3 and 4 are unused */
341
342#ifdef FEATURE_WLAN_TDLS
343#define WE_TDLS_CONFIG_PARAMS 5
344#endif
Rajeev Kumar8e3e2832015-11-06 16:02:54 -0800345#define WE_IBSS_GET_PEER_INFO 6
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800346#define WE_UNIT_TEST_CMD 7
347
348#define WE_MTRACE_DUMP_CMD 8
349#define WE_MTRACE_SELECTIVE_MODULE_LOG_ENABLE_CMD 9
350
351
352#ifdef WLAN_FEATURE_GPIO_LED_FLASHING
353#define WE_LED_FLASHING_PARAM 10
354#endif
355
356#define WE_POLICY_MANAGER_CLIST_CMD 11
357#define WE_POLICY_MANAGER_DLIST_CMD 12
358#define WE_POLICY_MANAGER_DBS_CMD 13
359#define WE_POLICY_MANAGER_PCL_CMD 14
360#define WE_POLICY_MANAGER_CINFO_CMD 15
361#define WE_POLICY_MANAGER_ULIST_CMD 16
362#define WE_POLICY_MANAGER_QUERY_ACTION_CMD 17
363#define WE_POLICY_MANAGER_QUERY_ALLOW_CMD 18
364#define WE_POLICY_MANAGER_SCENARIO_CMD 19
365#define WE_POLICY_SET_HW_MODE_CMD 20
366
367#define WE_SET_DUAL_MAC_SCAN_CONFIG 21
368#define WE_SET_DUAL_MAC_FW_MODE_CONFIG 22
369
370#ifdef FEATURE_WLAN_TDLS
371#undef MAX_VAR_ARGS
372#define MAX_VAR_ARGS 11
373#else
374#undef MAX_VAR_ARGS
375#define MAX_VAR_ARGS 9
376#endif
377
378/* Private ioctls (with no sub-ioctls) */
379/* note that they must be odd so that they have "get" semantics */
380#define WLAN_PRIV_ADD_TSPEC (SIOCIWFIRSTPRIV + 9)
381#define WLAN_PRIV_DEL_TSPEC (SIOCIWFIRSTPRIV + 11)
382#define WLAN_PRIV_GET_TSPEC (SIOCIWFIRSTPRIV + 13)
383
384/* (SIOCIWFIRSTPRIV + 8) is currently unused */
385/* (SIOCIWFIRSTPRIV + 10) is currently unused */
386/* (SIOCIWFIRSTPRIV + 12) is currently unused */
387/* (SIOCIWFIRSTPRIV + 14) is currently unused */
Manikandan Mohandcc21ba2016-03-15 14:31:56 -0700388#define WLAN_PRIV_SET_NONE_GET_THREE_INT (SIOCIWFIRSTPRIV + 15)
389#define WE_GET_TSF 1
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800390/* (SIOCIWFIRSTPRIV + 16) is currently unused */
391/* (SIOCIWFIRSTPRIV + 17) is currently unused */
392/* (SIOCIWFIRSTPRIV + 19) is currently unused */
393
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800394#define WLAN_PRIV_SET_FTIES (SIOCIWFIRSTPRIV + 20)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800395
396/* Private ioctl for setting the host offload feature */
397#define WLAN_PRIV_SET_HOST_OFFLOAD (SIOCIWFIRSTPRIV + 18)
398
399/* Private ioctl to get the statistics */
400#define WLAN_GET_WLAN_STATISTICS (SIOCIWFIRSTPRIV + 21)
401
402/* Private ioctl to set the Keep Alive Params */
403#define WLAN_SET_KEEPALIVE_PARAMS (SIOCIWFIRSTPRIV + 22)
404
405#ifdef WLAN_FEATURE_PACKET_FILTERING
406/* Private ioctl to set the packet filtering params */
407#define WLAN_SET_PACKET_FILTER_PARAMS (SIOCIWFIRSTPRIV + 23)
408#endif
409
410
411#ifdef FEATURE_WLAN_SCAN_PNO
412/* Private ioctl to get the statistics */
413#define WLAN_SET_PNO (SIOCIWFIRSTPRIV + 24)
414#endif
415
416#define WLAN_SET_BAND_CONFIG (SIOCIWFIRSTPRIV + 25)
417
418/* (SIOCIWFIRSTPRIV + 26) is currently unused */
419/* (SIOCIWFIRSTPRIV + 27) is currently unused */
420
421/* Private ioctls and their sub-ioctls */
422#define WLAN_PRIV_SET_TWO_INT_GET_NONE (SIOCIWFIRSTPRIV + 28)
423#define WE_SET_SMPS_PARAM 1
424#ifdef DEBUG
425#define WE_SET_FW_CRASH_INJECT 2
426#endif
427#define WE_DUMP_DP_TRACE_LEVEL 3
428#define DUMP_DP_TRACE 0
Govind Singha471e5e2015-10-12 17:11:14 +0530429/* Private sub ioctl for enabling and setting histogram interval of profiling */
430#define WE_ENABLE_FW_PROFILE 4
431#define WE_SET_FW_PROFILE_HIST_INTVL 5
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800432
433/* (SIOCIWFIRSTPRIV + 29) is currently unused */
434
435/* 802.11p IOCTL */
436#define WLAN_SET_DOT11P_CHANNEL_SCHED (SIOCIWFIRSTPRIV + 30)
437
438#define WLAN_GET_LINK_SPEED (SIOCIWFIRSTPRIV + 31)
439
440#define WLAN_STATS_INVALID 0
441#define WLAN_STATS_RETRY_CNT 1
442#define WLAN_STATS_MUL_RETRY_CNT 2
443#define WLAN_STATS_TX_FRM_CNT 3
444#define WLAN_STATS_RX_FRM_CNT 4
445#define WLAN_STATS_FRM_DUP_CNT 5
446#define WLAN_STATS_FAIL_CNT 6
447#define WLAN_STATS_RTS_FAIL_CNT 7
448#define WLAN_STATS_ACK_FAIL_CNT 8
449#define WLAN_STATS_RTS_SUC_CNT 9
450#define WLAN_STATS_RX_DISCARD_CNT 10
451#define WLAN_STATS_RX_ERROR_CNT 11
452#define WLAN_STATS_TX_BYTE_CNT 12
453
454#define WLAN_STATS_RX_BYTE_CNT 13
455#define WLAN_STATS_RX_RATE 14
456#define WLAN_STATS_TX_RATE 15
457
458#define WLAN_STATS_RX_UC_BYTE_CNT 16
459#define WLAN_STATS_RX_MC_BYTE_CNT 17
460#define WLAN_STATS_RX_BC_BYTE_CNT 18
461#define WLAN_STATS_TX_UC_BYTE_CNT 19
462#define WLAN_STATS_TX_MC_BYTE_CNT 20
463#define WLAN_STATS_TX_BC_BYTE_CNT 21
464
465#define FILL_TLV(__p, __type, __size, __val, __tlen) do { \
466 if ((__tlen + __size + 2) < WE_MAX_STR_LEN) { \
467 *__p++ = __type; \
468 *__p++ = __size; \
469 memcpy(__p, __val, __size); \
470 __p += __size; \
471 __tlen += __size + 2; \
472 } else { \
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530473 hddLog(QDF_TRACE_LEVEL_ERROR, "FILL_TLV Failed!!!"); \
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800474 } \
475 } while (0)
476
477#define VERSION_VALUE_MAX_LEN 32
478
479#define TX_PER_TRACKING_DEFAULT_RATIO 5
480#define TX_PER_TRACKING_MAX_RATIO 10
481#define TX_PER_TRACKING_DEFAULT_WATERMARK 5
482
483#define WLAN_ADAPTER 0
484#define P2P_ADAPTER 1
485
486/**
487 * mem_alloc_copy_from_user_helper - copy from user helper
488 * @wrqu_data: wireless extensions request data
489 * @len: length of @wrqu_data
490 *
491 * Helper function to allocate buffer and copy user data.
492 *
493 * Return: On success return a pointer to a kernel buffer containing a
494 * copy of the userspace data (with an additional NUL character
495 * appended for safety). On failure return %NULL.
496 */
497void *mem_alloc_copy_from_user_helper(const __user void *wrqu_data, size_t len)
498{
499 u8 *ptr = NULL;
500
501 /* in order to protect the code, an extra byte is post
502 * appended to the buffer and the null termination is added.
503 * However, when allocating (len+1) byte of memory, we need to
504 * make sure that there is no uint overflow when doing
505 * addition. In theory check len < UINT_MAX protects the uint
506 * overflow. For wlan private ioctl, the buffer size is much
507 * less than UINT_MAX, as a good guess, now, it is assumed
508 * that the private command buffer size is no greater than 4K
509 * (4096 bytes). So we use 4096 as the upper boundary for now.
510 */
511 if (len > MAX_USER_COMMAND_SIZE) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530512 QDF_TRACE(QDF_MODULE_ID_HDD, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800513 "Invalid length");
514 return NULL;
515 }
516
517 ptr = kmalloc(len + 1, GFP_KERNEL);
518 if (NULL == ptr) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530519 QDF_TRACE(QDF_MODULE_ID_HDD, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800520 "unable to allocate memory");
521 return NULL;
522 }
523
524 if (copy_from_user(ptr, wrqu_data, len)) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530525 QDF_TRACE(QDF_MODULE_ID_HDD, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800526 "%s: failed to copy data to user buffer", __func__);
527 kfree(ptr);
528 return NULL;
529 }
530 ptr[len] = '\0';
531 return ptr;
532}
533
534/**
535 * hdd_priv_get_data() - Get pointer to ioctl private data
536 * @p_priv_data: pointer to iw_point struct to be filled
537 * @wrqu: Pointer to IOCTL Data received from userspace
538 *
539 * Helper function to get compatible struct iw_point passed to ioctl
540 *
541 * Return - 0 if p_priv_data successfully filled, error otherwise
542 */
543int hdd_priv_get_data(struct iw_point *p_priv_data, union iwreq_data *wrqu)
544{
545 if ((NULL == p_priv_data) || (NULL == wrqu)) {
546 return -EINVAL;
547 }
548#ifdef CONFIG_COMPAT
549 if (is_compat_task()) {
550 struct compat_iw_point *p_compat_priv_data;
551
552 /* Compat task:
553 * typecast to compat structure and copy the members.
554 */
555 p_compat_priv_data = (struct compat_iw_point *)&wrqu->data;
556
557 p_priv_data->pointer = compat_ptr(p_compat_priv_data->pointer);
558 p_priv_data->length = p_compat_priv_data->length;
559 p_priv_data->flags = p_compat_priv_data->flags;
560 } else {
561#endif /* #ifdef CONFIG_COMPAT */
562
563 /* Non compat task: directly copy the structure. */
564 memcpy(p_priv_data, &wrqu->data, sizeof(struct iw_point));
565
566#ifdef CONFIG_COMPAT
567 }
568#endif /* #ifdef CONFIG_COMPAT */
569
570 return 0;
571}
572
573
574/**
575 * hdd_wlan_get_stats() - Get txrx stats in SAP mode
576 * @pAdapter: Pointer to the hdd adapter.
577 * @length: Size of the data copied
578 * @buffer: Pointer to char buffer.
579 * @buf_len: Length of the char buffer.
580 *
581 * This function called when the "iwpriv wlan0 get_stats" command is given.
582 * It used to collect the txrx stats when the device is configured in SAP mode.
583 *
584 * Return - none
585 */
586void hdd_wlan_get_stats(hdd_adapter_t *pAdapter, uint16_t *length,
587 char *buffer, uint16_t buf_len)
588{
589 hdd_tx_rx_stats_t *pStats = &pAdapter->hdd_stats.hddTxRxStats;
590 uint32_t len = 0;
591 uint32_t total_rx_pkt = 0, total_rx_dropped = 0;
592 uint32_t total_rx_delv = 0, total_rx_refused = 0;
593 int i = 0;
594
595 for (; i < NUM_CPUS; i++) {
596 total_rx_pkt += pStats->rxPackets[i];
597 total_rx_dropped += pStats->rxDropped[i];
598 total_rx_delv += pStats->rxDelivered[i];
599 total_rx_refused += pStats->rxRefused[i];
600 }
601
602 len = scnprintf(buffer, buf_len,
603 "\nTransmit"
604 "\ncalled %u, dropped %u,"
605 "\n dropped BK %u, BE %u, VI %u, VO %u"
606 "\n classified BK %u, BE %u, VI %u, VO %u"
607 "\ncompleted %u,"
608 "\n\nReceive Total"
609 "\n packets %u, dropped %u, delivered %u, refused %u"
610 "\n",
611 pStats->txXmitCalled,
612 pStats->txXmitDropped,
613
614 pStats->txXmitDroppedAC[SME_AC_BK],
615 pStats->txXmitDroppedAC[SME_AC_BE],
616 pStats->txXmitDroppedAC[SME_AC_VI],
617 pStats->txXmitDroppedAC[SME_AC_VO],
618
619 pStats->txXmitClassifiedAC[SME_AC_BK],
620 pStats->txXmitClassifiedAC[SME_AC_BE],
621 pStats->txXmitClassifiedAC[SME_AC_VI],
622 pStats->txXmitClassifiedAC[SME_AC_VO],
623
624 pStats->txCompleted,
625 total_rx_pkt, total_rx_dropped, total_rx_delv, total_rx_refused
626 );
627
628 for (i = 0; i < NUM_CPUS; i++) {
629 len += scnprintf(buffer + len, buf_len - len,
630 "\nReceive CPU: %d"
631 "\n packets %u, dropped %u, delivered %u, refused %u",
632 i, pStats->rxPackets[i], pStats->rxDropped[i],
633 pStats->rxDelivered[i], pStats->rxRefused[i]);
634 }
635
636 len += scnprintf(buffer + len, buf_len - len,
637 "\n\nTX_FLOW"
638 "\nCurrent status: %s"
639 "\ntx-flow timer start count %u"
640 "\npause count %u, unpause count %u",
641 (pStats->is_txflow_paused == true ? "PAUSED" : "UNPAUSED"),
642 pStats->txflow_timer_cnt,
643 pStats->txflow_pause_cnt,
644 pStats->txflow_unpause_cnt);
645
646 len += ol_txrx_stats(pAdapter->sessionId,
647 &buffer[len], (buf_len - len));
648
649 len += hdd_napi_stats(buffer + len, buf_len - len,
650 NULL, hdd_napi_get_all());
651
652 *length = len + 1;
653}
654
655/**
Govind Singha471e5e2015-10-12 17:11:14 +0530656 * hdd_wlan_list_fw_profile() - Get fw profiling points
657 * @length: Size of the data copied
658 * @buffer: Pointer to char buffer.
659 * @buf_len: Length of the char buffer.
660 *
661 * This function called when the "iwpriv wlan0 listProfile" command is given.
662 * It is used to get the supported profiling points in FW.
663 *
664 * Return - none
665 */
666void hdd_wlan_list_fw_profile(uint16_t *length,
667 char *buffer, uint16_t buf_len)
668{
669 uint32_t len = 0;
670
671 len = scnprintf(buffer, buf_len,
672 "PROF_CPU_IDLE: %u\n"
673 "PROF_PPDU_PROC: %u\n"
674 "PROF_PPDU_POST: %u\n"
675 "PROF_HTT_TX_INPUT: %u\n"
676 "PROF_MSDU_ENQ: %u\n"
677 "PROF_PPDU_POST_HAL: %u\n"
678 "PROF_COMPUTE_TX_TIME: %u\n",
679 PROF_CPU_IDLE,
680 PROF_PPDU_PROC,
681 PROF_PPDU_POST,
682 PROF_HTT_TX_INPUT,
683 PROF_MSDU_ENQ,
684 PROF_PPDU_POST_HAL,
685 PROF_COMPUTE_TX_TIME);
686
687 *length = len + 1;
688}
689
690/**
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800691 * hdd_wlan_dump_stats() - display dump Stats
692 * @adapter: adapter handle
693 * @value: value from user
694 *
695 * Return: none
696 */
697void hdd_wlan_dump_stats(hdd_adapter_t *adapter, int value)
698{
699 hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
700
701 switch (value) {
702
703 case WLAN_TXRX_HIST_STATS:
704 wlan_hdd_display_tx_rx_histogram(hdd_ctx);
705 break;
706 case WLAN_HDD_NETIF_OPER_HISTORY:
707 wlan_hdd_display_netif_queue_history(hdd_ctx);
708 break;
709 default:
710 ol_txrx_display_stats(value);
711 break;
712 }
713}
714
715/**
716 * hdd_wlan_get_version() - Get driver version information
717 * @pAdapter: Pointer to the adapter.
718 * @wrqu: Pointer to IOCTL REQUEST Data.
719 * @extra: Pointer to destination buffer
720 *
721 * This function is used to get Wlan Driver, Firmware, & Hardware
722 * Version information. If @wrqu and @extra are specified, then the
723 * version string is returned. Otherwise it is simply printed to the
724 * kernel log.
725 *
726 * Return: none
727 */
728void hdd_wlan_get_version(hdd_adapter_t *pAdapter, union iwreq_data *wrqu,
729 char *extra)
730{
731 tSirVersionString wcnss_SW_version;
732 const char *pSWversion;
733 const char *pHWversion;
734 uint32_t MSPId = 0, mSPId = 0, SIId = 0, CRMId = 0;
735
736 hdd_context_t *pHddContext;
737
738 pHddContext = WLAN_HDD_GET_CTX(pAdapter);
739 if (!pHddContext) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530740 QDF_TRACE(QDF_MODULE_ID_HDD, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800741 "%s:Invalid context, HDD context is null", __func__);
742 goto error;
743 }
744
745 snprintf(wcnss_SW_version, sizeof(tSirVersionString), "%08x",
746 pHddContext->target_fw_version);
747
748 pSWversion = wcnss_SW_version;
749 MSPId = (pHddContext->target_fw_version & 0xf0000000) >> 28;
750 mSPId = (pHddContext->target_fw_version & 0xf000000) >> 24;
751 SIId = (pHddContext->target_fw_version & 0xf00000) >> 20;
752 CRMId = pHddContext->target_fw_version & 0x7fff;
753
754 pHWversion = pHddContext->target_hw_name;
755
756 if (wrqu && extra) {
757 wrqu->data.length =
758 scnprintf(extra, WE_MAX_STR_LEN,
759 "Host SW:%s, FW:%d.%d.%d.%d, HW:%s",
760 QWLAN_VERSIONSTR,
761 MSPId, mSPId, SIId, CRMId, pHWversion);
762 } else {
763 pr_info("Host SW:%s, FW:%d.%d.%d.%d, HW:%s\n",
764 QWLAN_VERSIONSTR,
765 MSPId, mSPId, SIId, CRMId, pHWversion);
766 }
767error:
768 return;
769}
770
771/**
Rajeev Kumar8e3e2832015-11-06 16:02:54 -0800772 * hdd_wlan_get_ibss_mac_addr_from_staid() - Get IBSS MAC address
773 * @pAdapter: Adapter upon which the IBSS client is active
774 * @staIdx: Station index of the IBSS peer
775 *
776 * Return: a pointer to the MAC address of the IBSS peer if the peer is
777 * found, otherwise %NULL.
778 */
779struct qdf_mac_addr *
780hdd_wlan_get_ibss_mac_addr_from_staid(hdd_adapter_t *pAdapter,
781 uint8_t staIdx)
782{
783 uint8_t idx;
784 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
785
786 for (idx = 0; idx < MAX_IBSS_PEERS; idx++) {
787 if (0 != pHddStaCtx->conn_info.staId[idx] &&
788 staIdx == pHddStaCtx->conn_info.staId[idx]) {
789 return &pHddStaCtx->conn_info.peerMacAddress[idx];
790 }
791 }
792 return NULL;
793}
794
795/**
796 * hdd_wlan_get_ibss_peer_info() - Print IBSS peer information
797 * @pAdapter: Adapter upon which the IBSS client is active
798 * @staIdx: Station index of the IBSS peer
799 *
800 * Return: QDF_STATUS_STATUS if the peer was found and displayed,
801 * otherwise an appropriate QDF_STATUS_E_* failure code.
802 */
803QDF_STATUS hdd_wlan_get_ibss_peer_info(hdd_adapter_t *pAdapter, uint8_t staIdx)
804{
805 QDF_STATUS status = QDF_STATUS_E_FAILURE;
806 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
807 hdd_station_ctx_t *pStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Rajeev Kumar94c9b452016-03-24 12:58:47 -0700808 tSirPeerInfoRspParams *pPeerInfo = &pStaCtx->ibss_peer_info;
Rajeev Kumar8e3e2832015-11-06 16:02:54 -0800809
810 status =
811 sme_request_ibss_peer_info(hHal, pAdapter, hdd_get_ibss_peer_info_cb,
812 false, staIdx);
813
814 INIT_COMPLETION(pAdapter->ibss_peer_info_comp);
815
816 if (QDF_STATUS_SUCCESS == status) {
817 unsigned long rc;
818 rc = wait_for_completion_timeout
819 (&pAdapter->ibss_peer_info_comp,
820 msecs_to_jiffies(IBSS_PEER_INFO_REQ_TIMOEUT));
821 if (!rc) {
822 hddLog(QDF_TRACE_LEVEL_ERROR,
823 FL("failed wait on ibss_peer_info_comp"));
824 return QDF_STATUS_E_FAILURE;
825 }
826
827 /** Print the peer info */
Rajeev Kumar94c9b452016-03-24 12:58:47 -0700828 hdd_info("pPeerInfo->numIBSSPeers = %d ", pPeerInfo->numPeers);
Rajeev Kumar8e3e2832015-11-06 16:02:54 -0800829 {
Rajeev Kumar94c9b452016-03-24 12:58:47 -0700830 uint8_t mac_addr[QDF_MAC_ADDR_SIZE];
831 uint32_t tx_rate = pPeerInfo->peerInfoParams[0].txRate;
Rajeev Kumar8e3e2832015-11-06 16:02:54 -0800832
Rajeev Kumar94c9b452016-03-24 12:58:47 -0700833 qdf_mem_copy(mac_addr, pPeerInfo->peerInfoParams[0].
834 mac_addr, sizeof(mac_addr));
835 hdd_info("PEER ADDR : %pM TxRate: %d Mbps RSSI: %d",
836 mac_addr, (int)tx_rate,
837 (int)pPeerInfo->peerInfoParams[0].rssi);
Rajeev Kumar8e3e2832015-11-06 16:02:54 -0800838 }
839 } else {
840 hddLog(QDF_TRACE_LEVEL_WARN,
841 "%s: Warning: sme_request_ibss_peer_info Request failed",
842 __func__);
843 }
844
845 return status;
846}
847
848/**
849 * hdd_wlan_get_ibss_peer_info_all() - Print all IBSS peers
850 * @pAdapter: Adapter upon which the IBSS clients are active
851 *
852 * Return: QDF_STATUS_STATUS if the peer information was retrieved and
853 * displayed, otherwise an appropriate QDF_STATUS_E_* failure code.
854 */
855QDF_STATUS hdd_wlan_get_ibss_peer_info_all(hdd_adapter_t *pAdapter)
856{
857 QDF_STATUS status = QDF_STATUS_E_FAILURE;
858 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
859 hdd_station_ctx_t *pStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Rajeev Kumar94c9b452016-03-24 12:58:47 -0700860 tSirPeerInfoRspParams *pPeerInfo = &pStaCtx->ibss_peer_info;
Rajeev Kumar8e3e2832015-11-06 16:02:54 -0800861 int i;
862
863 status =
864 sme_request_ibss_peer_info(hHal, pAdapter, hdd_get_ibss_peer_info_cb,
865 true, 0xFF);
866 INIT_COMPLETION(pAdapter->ibss_peer_info_comp);
867
868 if (QDF_STATUS_SUCCESS == status) {
869 unsigned long rc;
870 rc = wait_for_completion_timeout
871 (&pAdapter->ibss_peer_info_comp,
872 msecs_to_jiffies(IBSS_PEER_INFO_REQ_TIMOEUT));
873 if (!rc) {
874 hddLog(QDF_TRACE_LEVEL_ERROR,
875 FL("failed wait on ibss_peer_info_comp"));
876 return QDF_STATUS_E_FAILURE;
877 }
878
879 /** Print the peer info */
Rajeev Kumar94c9b452016-03-24 12:58:47 -0700880 hdd_info("pPeerInfo->numIBSSPeers = %d ",
881 (int)pPeerInfo->numPeers);
882 for (i = 0; i < pPeerInfo->numPeers; i++) {
883 uint8_t mac_addr[QDF_MAC_ADDR_SIZE];
884 uint32_t tx_rate;
Rajeev Kumar8e3e2832015-11-06 16:02:54 -0800885
Rajeev Kumar94c9b452016-03-24 12:58:47 -0700886 tx_rate = pPeerInfo->peerInfoParams[i].txRate;
887 qdf_mem_copy(mac_addr,
888 pPeerInfo->peerInfoParams[i].mac_addr,
889 sizeof(mac_addr));
890
891 hdd_info(" PEER ADDR : %pM TxRate: %d Mbps RSSI: %d",
892 mac_addr, (int)tx_rate,
893 (int)pPeerInfo->peerInfoParams[i].rssi);
Rajeev Kumar8e3e2832015-11-06 16:02:54 -0800894 }
895 } else {
896 hddLog(QDF_TRACE_LEVEL_WARN,
897 "%s: Warning: sme_request_ibss_peer_info Request failed",
898 __func__);
899 }
900
901 return status;
902}
903
904/**
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800905 * hdd_wlan_get_rts_threshold() - Get RTS threshold
906 * @pAdapter: adapter upon which the request was received
907 * @wrqu: pointer to the ioctl request
908 *
909 * This function retrieves the current RTS threshold value and stores
910 * it in the ioctl request structure
911 *
912 * Return: 0 if valid data was returned, non-zero on error
913 */
914int hdd_wlan_get_rts_threshold(hdd_adapter_t *pAdapter, union iwreq_data *wrqu)
915{
916 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
917 uint32_t threshold = 0;
918 hdd_context_t *hdd_ctx;
919 int ret = 0;
920
921 ENTER();
922
923 if (NULL == pAdapter) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530924 QDF_TRACE(QDF_MODULE_ID_HDD, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800925 "%s: Adapter is NULL", __func__);
926 return -EINVAL;
927 }
928
929 hdd_ctx = WLAN_HDD_GET_CTX(pAdapter);
930 ret = wlan_hdd_validate_context(hdd_ctx);
931 if (0 != ret)
932 return ret;
933
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530934 if (QDF_STATUS_SUCCESS !=
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800935 sme_cfg_get_int(hHal, WNI_CFG_RTS_THRESHOLD, &threshold)) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530936 QDF_TRACE(QDF_MODULE_ID_HDD, QDF_TRACE_LEVEL_WARN,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800937 FL
938 ("failed to get ini parameter, WNI_CFG_RTS_THRESHOLD"));
939 return -EIO;
940 }
941 wrqu->rts.value = threshold;
942
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530943 QDF_TRACE(QDF_MODULE_ID_HDD, QDF_TRACE_LEVEL_INFO,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800944 ("Rts-Threshold=%d!!"), wrqu->rts.value);
945
946 EXIT();
947
948 return 0;
949}
950
951/**
952 * hdd_wlan_get_frag_threshold() - Get fragmentation threshold
953 * @pAdapter: adapter upon which the request was received
954 * @wrqu: pointer to the ioctl request
955 *
956 * This function retrieves the current fragmentation threshold value
957 * and stores it in the ioctl request structure
958 *
959 * Return: 0 if valid data was returned, non-zero on error
960 */
961int hdd_wlan_get_frag_threshold(hdd_adapter_t *pAdapter,
962 union iwreq_data *wrqu)
963{
964 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
965 uint32_t threshold = 0, status = 0;
966 hdd_context_t *hdd_ctx;
967
968 ENTER();
969
970 if (NULL == pAdapter) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530971 QDF_TRACE(QDF_MODULE_ID_HDD, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800972 "%s: Adapter is NULL", __func__);
973 return -EINVAL;
974 }
975
976 hdd_ctx = WLAN_HDD_GET_CTX(pAdapter);
977 status = wlan_hdd_validate_context(hdd_ctx);
978 if (0 != status)
979 return status;
980
981 if (sme_cfg_get_int(hHal, WNI_CFG_FRAGMENTATION_THRESHOLD, &threshold)
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530982 != QDF_STATUS_SUCCESS) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530983 QDF_TRACE(QDF_MODULE_ID_HDD, QDF_TRACE_LEVEL_WARN,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800984 FL
985 ("failed to get ini parameter, WNI_CFG_FRAGMENTATION_THRESHOLD"));
986 return -EIO;
987 }
988 wrqu->frag.value = threshold;
989
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530990 QDF_TRACE(QDF_MODULE_ID_HDD, QDF_TRACE_LEVEL_INFO,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800991 ("Frag-Threshold=%d!!"), wrqu->frag.value);
992
993 EXIT();
994
995 return 0;
996}
997
998/**
999 * hdd_wlan_get_freq() - Convert channel to frequency
1000 * @channel: channel to be converted
1001 * @pfreq: where to store the frequency
1002 *
1003 * Return: 1 on success, otherwise a negative errno
1004 */
1005int hdd_wlan_get_freq(uint32_t channel, uint32_t *pfreq)
1006{
1007 int i;
1008 if (channel > 0) {
1009 for (i = 0; i < FREQ_CHAN_MAP_TABLE_SIZE; i++) {
1010 if (channel == freq_chan_map[i].chan) {
1011 *pfreq = freq_chan_map[i].freq;
1012 return 1;
1013 }
1014 }
1015 }
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301016 QDF_TRACE(QDF_MODULE_ID_HDD, QDF_TRACE_LEVEL_INFO,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001017 ("Invalid channel no=%d!!"), channel);
1018 return -EINVAL;
1019}
1020
1021/**
1022 * hdd_is_auth_type_rsn() - RSN authentication type check
1023 * @authType: authentication type to be checked
1024 *
1025 * Return: true if @authType is an RSN authentication type,
1026 * false if it is not
1027 */
1028static bool hdd_is_auth_type_rsn(eCsrAuthType authType)
1029{
1030 bool rsnType = false;
1031 /* is the authType supported? */
1032 switch (authType) {
1033 case eCSR_AUTH_TYPE_NONE: /* never used */
1034 rsnType = false;
1035 break;
1036 /* MAC layer authentication types */
1037 case eCSR_AUTH_TYPE_OPEN_SYSTEM:
1038 rsnType = false;
1039 break;
1040 case eCSR_AUTH_TYPE_SHARED_KEY:
1041 rsnType = false;
1042 break;
1043 case eCSR_AUTH_TYPE_AUTOSWITCH:
1044 rsnType = false;
1045 break;
1046
1047 /* Upper layer authentication types */
1048 case eCSR_AUTH_TYPE_WPA:
1049 rsnType = true;
1050 break;
1051 case eCSR_AUTH_TYPE_WPA_PSK:
1052 rsnType = true;
1053 break;
1054 case eCSR_AUTH_TYPE_WPA_NONE:
1055 rsnType = true;
1056 break;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001057 case eCSR_AUTH_TYPE_FT_RSN:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001058 case eCSR_AUTH_TYPE_RSN:
1059 rsnType = true;
1060 break;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001061 case eCSR_AUTH_TYPE_FT_RSN_PSK:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001062 case eCSR_AUTH_TYPE_RSN_PSK:
1063#ifdef WLAN_FEATURE_11W
1064 case eCSR_AUTH_TYPE_RSN_PSK_SHA256:
1065 case eCSR_AUTH_TYPE_RSN_8021X_SHA256:
1066#endif
1067 rsnType = true;
1068 break;
1069 /* case eCSR_AUTH_TYPE_FAILED: */
1070 case eCSR_AUTH_TYPE_UNKNOWN:
1071 rsnType = false;
1072 break;
1073 default:
1074 hddLog(LOGE, FL("unknown authType %d, treat as open"),
1075 authType);
1076 rsnType = false;
1077 break;
1078 }
1079 hddLog(LOG1, FL("called with authType: %d, returned: %d"),
1080 authType, rsnType);
1081 return rsnType;
1082}
1083
1084/**
1085 * hdd_get_rssi_cb() - "Get RSSI" callback function
1086 * @rssi: Current RSSI of the station
1087 * @staId: ID of the station
1088 * @pContext: opaque context originally passed to SME. HDD always passes
1089 * a &struct statsContext
1090 *
1091 * Return: None
1092 */
1093static void hdd_get_rssi_cb(int8_t rssi, uint32_t staId, void *pContext)
1094{
1095 struct statsContext *pStatsContext;
1096 hdd_adapter_t *pAdapter;
1097
1098 if (ioctl_debug) {
1099 pr_info("%s: rssi [%d] STA [%d] pContext [%p]\n",
1100 __func__, (int)rssi, (int)staId, pContext);
1101 }
1102
1103 if (NULL == pContext) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301104 hddLog(QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001105 "%s: Bad param, pContext [%p]", __func__, pContext);
1106 return;
1107 }
1108
1109 pStatsContext = pContext;
1110 pAdapter = pStatsContext->pAdapter;
1111
1112 /* there is a race condition that exists between this callback
1113 * function and the caller since the caller could time out
1114 * either before or while this code is executing. we use a
1115 * spinlock to serialize these actions
1116 */
1117 spin_lock(&hdd_context_lock);
1118
1119 if ((NULL == pAdapter) ||
1120 (RSSI_CONTEXT_MAGIC != pStatsContext->magic)) {
1121 /* the caller presumably timed out so there is nothing
1122 * we can do
1123 */
1124 spin_unlock(&hdd_context_lock);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301125 hddLog(QDF_TRACE_LEVEL_WARN,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001126 "%s: Invalid context, pAdapter [%p] magic [%08x]",
1127 __func__, pAdapter, pStatsContext->magic);
1128 if (ioctl_debug) {
1129 pr_info("%s: Invalid context, pAdapter [%p] magic [%08x]\n",
1130 __func__, pAdapter, pStatsContext->magic);
1131 }
1132 return;
1133 }
1134
1135 /* context is valid so caller is still waiting */
1136
1137 /* paranoia: invalidate the magic */
1138 pStatsContext->magic = 0;
1139
1140 /* copy over the rssi */
1141 pAdapter->rssi = rssi;
1142
Sachin Ahujabef8c102015-11-16 15:15:49 +05301143 if (pAdapter->rssi > 0)
1144 pAdapter->rssi = 0;
1145
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001146 /* notify the caller */
1147 complete(&pStatsContext->completion);
1148
1149 /* serialization is complete */
1150 spin_unlock(&hdd_context_lock);
1151}
1152
1153/**
1154 * hdd_get_snr_cb() - "Get SNR" callback function
1155 * @snr: Current SNR of the station
1156 * @staId: ID of the station
1157 * @pContext: opaque context originally passed to SME. HDD always passes
1158 * a &struct statsContext
1159 *
1160 * Return: None
1161 */
1162static void hdd_get_snr_cb(int8_t snr, uint32_t staId, void *pContext)
1163{
1164 struct statsContext *pStatsContext;
1165 hdd_adapter_t *pAdapter;
1166
1167 if (ioctl_debug) {
1168 pr_info("%s: snr [%d] STA [%d] pContext [%p]\n",
1169 __func__, (int)snr, (int)staId, pContext);
1170 }
1171
1172 if (NULL == pContext) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301173 hddLog(QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001174 "%s: Bad param, pContext [%p]", __func__, pContext);
1175 return;
1176 }
1177
1178 pStatsContext = pContext;
1179 pAdapter = pStatsContext->pAdapter;
1180
1181 /* there is a race condition that exists between this callback
1182 * function and the caller since the caller could time out
1183 * either before or while this code is executing. we use a
1184 * spinlock to serialize these actions
1185 */
1186 spin_lock(&hdd_context_lock);
1187
1188 if ((NULL == pAdapter) || (SNR_CONTEXT_MAGIC != pStatsContext->magic)) {
1189 /* the caller presumably timed out so there is nothing
1190 * we can do
1191 */
1192 spin_unlock(&hdd_context_lock);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301193 hddLog(QDF_TRACE_LEVEL_WARN,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001194 "%s: Invalid context, pAdapter [%p] magic [%08x]",
1195 __func__, pAdapter, pStatsContext->magic);
1196 if (ioctl_debug) {
1197 pr_info("%s: Invalid context, pAdapter [%p] magic [%08x]\n",
1198 __func__, pAdapter, pStatsContext->magic);
1199 }
1200 return;
1201 }
1202
1203 /* context is valid so caller is still waiting */
1204
1205 /* paranoia: invalidate the magic */
1206 pStatsContext->magic = 0;
1207
1208 /* copy over the snr */
1209 pAdapter->snr = snr;
1210
1211 /* notify the caller */
1212 complete(&pStatsContext->completion);
1213
1214 /* serialization is complete */
1215 spin_unlock(&hdd_context_lock);
1216}
1217
1218/**
1219 * wlan_hdd_get_rssi() - Get the current RSSI
1220 * @pAdapter: adapter upon which the measurement is requested
1221 * @rssi_value: pointer to where the RSSI should be returned
1222 *
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05301223 * Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_E_** on error
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001224 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301225QDF_STATUS wlan_hdd_get_rssi(hdd_adapter_t *pAdapter, int8_t *rssi_value)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001226{
1227 struct statsContext context;
1228 hdd_context_t *pHddCtx;
1229 hdd_station_ctx_t *pHddStaCtx;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301230 QDF_STATUS hstatus;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001231 unsigned long rc;
1232
1233 if (NULL == pAdapter) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301234 hddLog(QDF_TRACE_LEVEL_WARN,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001235 "%s: Invalid context, pAdapter", __func__);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301236 return QDF_STATUS_E_FAULT;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001237 }
Prashanth Bhatta9e143052015-12-04 11:56:47 -08001238 if (cds_is_driver_recovering()) {
1239 hdd_err("Recovery in Progress. State: 0x%x Ignore!!!",
1240 cds_get_driver_state());
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001241 /* return a cached value */
1242 *rssi_value = pAdapter->rssi;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301243 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001244 }
1245
1246 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
1247 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
1248
1249 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState) {
1250 hdd_err("Not associated!, return last connected AP rssi!");
1251 *rssi_value = pAdapter->rssi;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301252 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001253 }
1254
1255 if (pHddStaCtx->hdd_ReassocScenario) {
1256 hdd_info("Roaming in progress, return cached RSSI");
1257 *rssi_value = pAdapter->rssi;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301258 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001259 }
1260
1261 init_completion(&context.completion);
1262 context.pAdapter = pAdapter;
1263 context.magic = RSSI_CONTEXT_MAGIC;
1264
1265 hstatus = sme_get_rssi(pHddCtx->hHal, hdd_get_rssi_cb,
1266 pHddStaCtx->conn_info.staId[0],
1267 pHddStaCtx->conn_info.bssId, pAdapter->rssi,
1268 &context, pHddCtx->pcds_context);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301269 if (QDF_STATUS_SUCCESS != hstatus) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301270 hddLog(QDF_TRACE_LEVEL_ERROR, "%s: Unable to retrieve RSSI",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001271 __func__);
1272 /* we'll returned a cached value below */
1273 } else {
1274 /* request was sent -- wait for the response */
1275 rc = wait_for_completion_timeout(&context.completion,
1276 msecs_to_jiffies
1277 (WLAN_WAIT_TIME_STATS));
1278 if (!rc) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301279 hddLog(QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001280 FL("SME timed out while retrieving RSSI"));
1281 /* we'll now returned a cached value below */
1282 }
1283 }
1284
1285 /* either we never sent a request, we sent a request and
1286 * received a response or we sent a request and timed out. if
1287 * we never sent a request or if we sent a request and got a
1288 * response, we want to clear the magic out of paranoia. if
1289 * we timed out there is a race condition such that the
1290 * callback function could be executing at the same time we
1291 * are. of primary concern is if the callback function had
1292 * already verified the "magic" but had not yet set the
1293 * completion variable when a timeout occurred. we serialize
1294 * these activities by invalidating the magic while holding a
1295 * shared spinlock which will cause us to block if the
1296 * callback is currently executing
1297 */
1298 spin_lock(&hdd_context_lock);
1299 context.magic = 0;
1300 spin_unlock(&hdd_context_lock);
1301
1302 *rssi_value = pAdapter->rssi;
1303
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301304 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001305}
1306
1307/**
1308 * wlan_hdd_get_snr() - Get the current SNR
1309 * @pAdapter: adapter upon which the measurement is requested
1310 * @snr: pointer to where the SNR should be returned
1311 *
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05301312 * Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_E_** on error
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001313 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301314QDF_STATUS wlan_hdd_get_snr(hdd_adapter_t *pAdapter, int8_t *snr)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001315{
1316 struct statsContext context;
1317 hdd_context_t *pHddCtx;
1318 hdd_station_ctx_t *pHddStaCtx;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301319 QDF_STATUS hstatus;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001320 unsigned long rc;
1321 int valid;
1322
Hanumantha Reddy Pothula2db50ed2015-11-23 10:48:33 +05301323 ENTER();
1324
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001325 if (NULL == pAdapter) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301326 hddLog(QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001327 "%s: Invalid context, pAdapter", __func__);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301328 return QDF_STATUS_E_FAULT;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001329 }
1330
1331 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
1332
1333 valid = wlan_hdd_validate_context(pHddCtx);
Hanumantha Reddy Pothula2db50ed2015-11-23 10:48:33 +05301334 if (0 != valid)
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301335 return QDF_STATUS_E_FAULT;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001336
1337 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
1338
1339 init_completion(&context.completion);
1340 context.pAdapter = pAdapter;
1341 context.magic = SNR_CONTEXT_MAGIC;
1342
1343 hstatus = sme_get_snr(pHddCtx->hHal, hdd_get_snr_cb,
1344 pHddStaCtx->conn_info.staId[0],
1345 pHddStaCtx->conn_info.bssId, &context);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301346 if (QDF_STATUS_SUCCESS != hstatus) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301347 hddLog(QDF_TRACE_LEVEL_ERROR, "%s: Unable to retrieve RSSI",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001348 __func__);
1349 /* we'll returned a cached value below */
1350 } else {
1351 /* request was sent -- wait for the response */
1352 rc = wait_for_completion_timeout(&context.completion,
1353 msecs_to_jiffies
1354 (WLAN_WAIT_TIME_STATS));
1355 if (!rc) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301356 hddLog(QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001357 FL("SME timed out while retrieving SNR"));
1358 /* we'll now returned a cached value below */
1359 }
1360 }
1361
1362 /* either we never sent a request, we sent a request and
1363 * received a response or we sent a request and timed out. if
1364 * we never sent a request or if we sent a request and got a
1365 * response, we want to clear the magic out of paranoia. if
1366 * we timed out there is a race condition such that the
1367 * callback function could be executing at the same time we
1368 * are. of primary concern is if the callback function had
1369 * already verified the "magic" but had not yet set the
1370 * completion variable when a timeout occurred. we serialize
1371 * these activities by invalidating the magic while holding a
1372 * shared spinlock which will cause us to block if the
1373 * callback is currently executing
1374 */
1375 spin_lock(&hdd_context_lock);
1376 context.magic = 0;
1377 spin_unlock(&hdd_context_lock);
1378
1379 *snr = pAdapter->snr;
Hanumantha Reddy Pothula2db50ed2015-11-23 10:48:33 +05301380 EXIT();
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301381 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001382}
1383
1384/**
1385 * hdd_get_link_speed_cb() - Get link speed callback function
1386 * @pLinkSpeed: pointer to the link speed record
1387 * @pContext: pointer to the user context passed to SME
1388 *
1389 * This function is passed as the callback function to
1390 * sme_get_link_speed() by wlan_hdd_get_linkspeed_for_peermac(). By
1391 * agreement a &struct linkspeedContext is passed as @pContext. If
1392 * the context is valid, then the contents of @pLinkSpeed are copied
1393 * into the adapter record referenced by @pContext where they can be
1394 * subsequently retrieved. If the context is invalid, then this
1395 * function does nothing since it is assumed the caller has already
1396 * timed-out and destroyed the context.
1397 *
1398 * Return: None.
1399 */
1400static void
1401hdd_get_link_speed_cb(tSirLinkSpeedInfo *pLinkSpeed, void *pContext)
1402{
1403 struct linkspeedContext *pLinkSpeedContext;
1404 hdd_adapter_t *pAdapter;
1405
1406 if ((NULL == pLinkSpeed) || (NULL == pContext)) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301407 hddLog(QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001408 "%s: Bad param, pLinkSpeed [%p] pContext [%p]",
1409 __func__, pLinkSpeed, pContext);
1410 return;
1411 }
1412 spin_lock(&hdd_context_lock);
1413 pLinkSpeedContext = pContext;
1414 pAdapter = pLinkSpeedContext->pAdapter;
1415
1416 /* there is a race condition that exists between this callback
1417 * function and the caller since the caller could time out either
1418 * before or while this code is executing. we use a spinlock to
1419 * serialize these actions
1420 */
1421
1422 if ((NULL == pAdapter) ||
1423 (LINK_CONTEXT_MAGIC != pLinkSpeedContext->magic)) {
1424 /* the caller presumably timed out so there is nothing
1425 * we can do
1426 */
1427 spin_unlock(&hdd_context_lock);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301428 hddLog(QDF_TRACE_LEVEL_WARN,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001429 "%s: Invalid context, pAdapter [%p] magic [%08x]",
1430 __func__, pAdapter, pLinkSpeedContext->magic);
1431 if (ioctl_debug) {
1432 pr_info("%s: Invalid context, pAdapter [%p] magic [%08x]\n",
1433 __func__, pAdapter, pLinkSpeedContext->magic);
1434 }
1435 return;
1436 }
1437
1438 /* context is valid so caller is still waiting */
1439
1440 /* paranoia: invalidate the magic */
1441 pLinkSpeedContext->magic = 0;
1442
1443 /* copy over the stats. do so as a struct copy */
1444 pAdapter->ls_stats = *pLinkSpeed;
1445
1446 /* notify the caller */
1447 complete(&pLinkSpeedContext->completion);
1448
1449 /* serialization is complete */
1450 spin_unlock(&hdd_context_lock);
1451}
1452
1453/**
1454 * wlan_hdd_get_linkspeed_for_peermac() - Get link speed for a peer
1455 * @pAdapter: adapter upon which the peer is active
1456 * @macAddress: MAC address of the peer
1457 *
1458 * This function will send a query to SME for the linkspeed of the
1459 * given peer, and then wait for the callback to be invoked.
1460 *
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301461 * Return: QDF_STATUS_SUCCESS if linkspeed data is available,
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05301462 * otherwise a QDF_STATUS_E_** error.
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001463 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301464QDF_STATUS wlan_hdd_get_linkspeed_for_peermac(hdd_adapter_t *pAdapter,
Anurag Chouhan6d760662016-02-20 16:05:43 +05301465 struct qdf_mac_addr macAddress) {
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301466 QDF_STATUS status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001467 unsigned long rc;
1468 struct linkspeedContext context;
1469 tSirLinkSpeedInfo *linkspeed_req;
1470
1471 if (NULL == pAdapter) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301472 hddLog(QDF_TRACE_LEVEL_ERROR, "%s: pAdapter is NULL", __func__);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301473 return QDF_STATUS_E_FAULT;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001474 }
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301475 linkspeed_req = qdf_mem_malloc(sizeof(*linkspeed_req));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001476 if (NULL == linkspeed_req) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301477 QDF_TRACE(QDF_MODULE_ID_HDD, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001478 "%s Request Buffer Alloc Fail", __func__);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301479 return QDF_STATUS_E_NOMEM;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001480 }
1481 init_completion(&context.completion);
1482 context.pAdapter = pAdapter;
1483 context.magic = LINK_CONTEXT_MAGIC;
1484
Anurag Chouhanc5548422016-02-24 18:33:27 +05301485 qdf_copy_macaddr(&linkspeed_req->peer_macaddr, &macAddress);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001486 status = sme_get_link_speed(WLAN_HDD_GET_HAL_CTX(pAdapter),
1487 linkspeed_req,
1488 &context, hdd_get_link_speed_cb);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301489 if (QDF_STATUS_SUCCESS != status) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301490 hddLog(QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001491 "%s: Unable to retrieve statistics for link speed",
1492 __func__);
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301493 qdf_mem_free(linkspeed_req);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001494 } else {
1495 rc = wait_for_completion_timeout
1496 (&context.completion,
1497 msecs_to_jiffies(WLAN_WAIT_TIME_STATS));
1498 if (!rc) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301499 hddLog(QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001500 "%s: SME timed out while retrieving link speed",
1501 __func__);
1502 }
1503 }
1504
1505 /* either we never sent a request, we sent a request and
1506 * received a response or we sent a request and timed out. if
1507 * we never sent a request or if we sent a request and got a
1508 * response, we want to clear the magic out of paranoia. if
1509 * we timed out there is a race condition such that the
1510 * callback function could be executing at the same time we
1511 * are. of primary concern is if the callback function had
1512 * already verified the "magic" but had not yet set the
1513 * completion variable when a timeout occurred. we serialize
1514 * these activities by invalidating the magic while holding a
1515 * shared spinlock which will cause us to block if the
1516 * callback is currently executing
1517 */
1518 spin_lock(&hdd_context_lock);
1519 context.magic = 0;
1520 spin_unlock(&hdd_context_lock);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301521 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001522}
1523
1524/**
1525 * wlan_hdd_get_link_speed() - get link speed
1526 * @pAdapter: pointer to the adapter
1527 * @link_speed: pointer to link speed
1528 *
1529 * This function fetches per bssid link speed.
1530 *
1531 * Return: if associated, link speed shall be returned.
1532 * if not associated, link speed of 0 is returned.
1533 * On error, error number will be returned.
1534 */
1535int wlan_hdd_get_link_speed(hdd_adapter_t *sta_adapter, uint32_t *link_speed)
1536{
1537 hdd_context_t *hddctx = WLAN_HDD_GET_CTX(sta_adapter);
1538 hdd_station_ctx_t *hdd_stactx =
1539 WLAN_HDD_GET_STATION_CTX_PTR(sta_adapter);
1540 int ret;
1541
1542 ret = wlan_hdd_validate_context(hddctx);
1543
1544 if (0 != ret) {
1545 hddLog(LOGE, FL("HDD context is not valid"));
1546 return ret;
1547 }
1548
1549 if (eConnectionState_Associated != hdd_stactx->conn_info.connState) {
1550 /* we are not connected so we don't have a classAstats */
1551 *link_speed = 0;
1552 } else {
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301553 QDF_STATUS status;
Anurag Chouhan6d760662016-02-20 16:05:43 +05301554 struct qdf_mac_addr bssid;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001555
Anurag Chouhanc5548422016-02-24 18:33:27 +05301556 qdf_copy_macaddr(&bssid, &hdd_stactx->conn_info.bssId);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001557
1558 status = wlan_hdd_get_linkspeed_for_peermac(sta_adapter, bssid);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301559 if (!QDF_IS_STATUS_SUCCESS(status)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001560 hddLog(LOGE, FL("Unable to retrieve SME linkspeed"));
1561 return -EINVAL;
1562 }
1563 *link_speed = sta_adapter->ls_stats.estLinkSpeed;
1564 /* linkspeed in units of 500 kbps */
1565 *link_speed = (*link_speed) / 500;
1566 }
1567 return 0;
1568}
1569
1570/**
1571 * hdd_statistics_cb() - "Get statistics" callback function
1572 * @pStats: statistics payload
1573 * @pContext: opaque context originally passed to SME. HDD always passes
1574 * a pointer to an adapter
1575 *
1576 * Return: None
1577 */
1578void hdd_statistics_cb(void *pStats, void *pContext)
1579{
1580 hdd_adapter_t *pAdapter = (hdd_adapter_t *) pContext;
1581 hdd_stats_t *pStatsCache = NULL;
1582 hdd_wext_state_t *pWextState;
Anurag Chouhance0dc992016-02-16 18:18:03 +05301583 QDF_STATUS qdf_status = QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001584
1585 tCsrSummaryStatsInfo *pSummaryStats = NULL;
1586 tCsrGlobalClassAStatsInfo *pClassAStats = NULL;
1587 tCsrGlobalClassBStatsInfo *pClassBStats = NULL;
1588 tCsrGlobalClassCStatsInfo *pClassCStats = NULL;
1589 tCsrGlobalClassDStatsInfo *pClassDStats = NULL;
1590 tCsrPerStaStatsInfo *pPerStaStats = NULL;
1591
1592 if (pAdapter != NULL)
1593 pStatsCache = &pAdapter->hdd_stats;
1594
1595 pSummaryStats = (tCsrSummaryStatsInfo *) pStats;
1596 pClassAStats = (tCsrGlobalClassAStatsInfo *) (pSummaryStats + 1);
1597 pClassBStats = (tCsrGlobalClassBStatsInfo *) (pClassAStats + 1);
1598 pClassCStats = (tCsrGlobalClassCStatsInfo *) (pClassBStats + 1);
1599 pClassDStats = (tCsrGlobalClassDStatsInfo *) (pClassCStats + 1);
1600 pPerStaStats = (tCsrPerStaStatsInfo *) (pClassDStats + 1);
1601
1602 if (pStatsCache != NULL) {
1603 /* copy the stats into the cache we keep in the
1604 * adapter instance structure
1605 */
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301606 qdf_mem_copy(&pStatsCache->summary_stat, pSummaryStats,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001607 sizeof(pStatsCache->summary_stat));
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301608 qdf_mem_copy(&pStatsCache->ClassA_stat, pClassAStats,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001609 sizeof(pStatsCache->ClassA_stat));
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301610 qdf_mem_copy(&pStatsCache->ClassB_stat, pClassBStats,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001611 sizeof(pStatsCache->ClassB_stat));
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301612 qdf_mem_copy(&pStatsCache->ClassC_stat, pClassCStats,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001613 sizeof(pStatsCache->ClassC_stat));
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301614 qdf_mem_copy(&pStatsCache->ClassD_stat, pClassDStats,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001615 sizeof(pStatsCache->ClassD_stat));
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301616 qdf_mem_copy(&pStatsCache->perStaStats, pPerStaStats,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001617 sizeof(pStatsCache->perStaStats));
1618 }
1619
1620 if (pAdapter) {
1621 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05301622 qdf_status = qdf_event_set(&pWextState->hdd_qdf_event);
Anurag Chouhance0dc992016-02-16 18:18:03 +05301623 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
1624 hddLog(LOGE, FL("qdf_event_set failed"));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001625 return;
1626 }
1627 }
1628}
1629
1630/**
1631 * hdd_clear_roam_profile_ie() - Clear Roam Profile IEs
1632 * @pAdapter: adapter who's IEs are to be cleared
1633 *
1634 * Return: None
1635 */
1636void hdd_clear_roam_profile_ie(hdd_adapter_t *pAdapter)
1637{
1638 int i = 0;
1639 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
1640
1641 /* clear WPA/RSN/WSC IE information in the profile */
1642 pWextState->roamProfile.nWPAReqIELength = 0;
1643 pWextState->roamProfile.pWPAReqIE = (uint8_t *) NULL;
1644 pWextState->roamProfile.nRSNReqIELength = 0;
1645 pWextState->roamProfile.pRSNReqIE = (uint8_t *) NULL;
1646
1647#ifdef FEATURE_WLAN_WAPI
1648 pWextState->roamProfile.nWAPIReqIELength = 0;
1649 pWextState->roamProfile.pWAPIReqIE = (uint8_t *) NULL;
1650#endif
1651
1652 pWextState->roamProfile.bWPSAssociation = false;
1653 pWextState->roamProfile.bOSENAssociation = false;
1654 pWextState->roamProfile.pAddIEScan = (uint8_t *) NULL;
1655 pWextState->roamProfile.nAddIEScanLength = 0;
1656 pWextState->roamProfile.pAddIEAssoc = (uint8_t *) NULL;
1657 pWextState->roamProfile.nAddIEAssocLength = 0;
1658
1659 pWextState->roamProfile.EncryptionType.numEntries = 1;
1660 pWextState->roamProfile.EncryptionType.encryptionType[0]
1661 = eCSR_ENCRYPT_TYPE_NONE;
1662
1663 pWextState->roamProfile.mcEncryptionType.numEntries = 1;
1664 pWextState->roamProfile.mcEncryptionType.encryptionType[0]
1665 = eCSR_ENCRYPT_TYPE_NONE;
1666
1667 pWextState->roamProfile.AuthType.numEntries = 1;
1668 pWextState->roamProfile.AuthType.authType[0] =
1669 eCSR_AUTH_TYPE_OPEN_SYSTEM;
1670
1671#ifdef WLAN_FEATURE_11W
1672 pWextState->roamProfile.MFPEnabled = false;
1673 pWextState->roamProfile.MFPRequired = 0;
1674 pWextState->roamProfile.MFPCapable = 0;
1675#endif
1676
1677 pWextState->authKeyMgmt = 0;
1678
1679 for (i = 0; i < CSR_MAX_NUM_KEY; i++) {
1680 if (pWextState->roamProfile.Keys.KeyMaterial[i]) {
1681 pWextState->roamProfile.Keys.KeyLength[i] = 0;
1682 }
1683 }
1684#ifdef FEATURE_WLAN_WAPI
1685 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_OPEN;
1686 pAdapter->wapi_info.nWapiMode = 0;
1687#endif
1688
Anurag Chouhanc5548422016-02-24 18:33:27 +05301689 qdf_zero_macaddr(&pWextState->req_bssId);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001690
1691}
1692
1693/**
1694 * wlan_hdd_get_vendor_oui_ie_ptr() - Find a vendor OUI
1695 * @oui: The OUI that is being searched for
1696 * @oui_size: The length of @oui
1697 * @ie: The set of IEs within which we're trying to find @oui
1698 * @ie_len: The length of @ie
1699 *
1700 * This function will scan the IEs contained within @ie looking for @oui.
1701 *
1702 * Return: Pointer to @oui embedded within @ie if it is present, NULL
1703 * if @oui is not present within @ie.
1704 */
1705uint8_t *wlan_hdd_get_vendor_oui_ie_ptr(uint8_t *oui, uint8_t oui_size,
1706 uint8_t *ie, int ie_len)
1707{
1708 int left = ie_len;
1709 uint8_t *ptr = ie;
1710 uint8_t elem_id, elem_len;
1711 uint8_t eid = 0xDD;
1712
1713 if (NULL == ie || 0 == ie_len)
1714 return NULL;
1715
1716 while (left >= 2) {
1717 elem_id = ptr[0];
1718 elem_len = ptr[1];
1719 left -= 2;
1720 if (elem_len > left) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301721 hddLog(QDF_TRACE_LEVEL_FATAL,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001722 FL
1723 ("****Invalid IEs eid = %d elem_len=%d left=%d*****"),
1724 eid, elem_len, left);
1725 return NULL;
1726 }
1727 if (elem_id == eid) {
1728 if (memcmp(&ptr[2], oui, oui_size) == 0)
1729 return ptr;
1730 }
1731
1732 left -= elem_len;
1733 ptr += (elem_len + 2);
1734 }
1735 return NULL;
1736}
1737
1738/**
1739 * __iw_set_commit() - SIOCSIWCOMMIT ioctl handler
1740 * @dev: device upon which the ioctl was received
1741 * @info: ioctl request information
1742 * @wrqu: ioctl request data
1743 * @extra: ioctl extra data
1744 *
1745 * Return: 0 on success, non-zero on error
1746 */
1747static int __iw_set_commit(struct net_device *dev, struct iw_request_info *info,
1748 union iwreq_data *wrqu, char *extra)
1749{
1750 hdd_adapter_t *adapter;
1751 hdd_context_t *hdd_ctx;
1752 int ret;
1753
Jeff Johnsonb25dcb12016-02-11 17:46:42 -08001754 ENTER_DEV(dev);
1755
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001756 adapter = WLAN_HDD_GET_PRIV_PTR(dev);
1757 hdd_ctx = WLAN_HDD_GET_CTX(adapter);
1758 ret = wlan_hdd_validate_context(hdd_ctx);
1759 if (0 != ret)
1760 return ret;
1761
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001762 /* Do nothing for now */
1763 return 0;
1764}
1765
1766/**
1767 * iw_set_commit() - SSR wrapper function for __iw_set_commit
1768 * @dev: pointer to net_device
1769 * @info: pointer to iw_request_info
1770 * @wrqu: pointer to iwreq_data
1771 * @extra: extra
1772 *
1773 * Return: 0 on success, error number otherwise
1774 */
1775int iw_set_commit(struct net_device *dev, struct iw_request_info *info,
1776 union iwreq_data *wrqu, char *extra)
1777{
1778 int ret;
1779
1780 cds_ssr_protect(__func__);
1781 ret = __iw_set_commit(dev, info, wrqu, extra);
1782 cds_ssr_unprotect(__func__);
1783
1784 return ret;
1785}
1786
1787/**
1788 * __iw_get_name() - SIOCGIWNAME ioctl handler
1789 * @dev: device upon which the ioctl was received
1790 * @info: ioctl request information
1791 * @wrqu: ioctl request data
1792 * @extra: ioctl extra data
1793 *
1794 * Return: 0 on success, non-zero on error
1795 */
1796static int __iw_get_name(struct net_device *dev,
1797 struct iw_request_info *info, char *wrqu, char *extra)
1798{
1799 hdd_adapter_t *adapter;
1800 hdd_context_t *hdd_ctx;
1801 int ret;
1802
Jeff Johnsonb25dcb12016-02-11 17:46:42 -08001803 ENTER_DEV(dev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001804
1805 adapter = WLAN_HDD_GET_PRIV_PTR(dev);
1806 hdd_ctx = WLAN_HDD_GET_CTX(adapter);
1807 ret = wlan_hdd_validate_context(hdd_ctx);
1808 if (0 != ret)
1809 return ret;
1810
1811 strlcpy(wrqu, "Qcom:802.11n", IFNAMSIZ);
1812 EXIT();
1813 return 0;
1814}
1815
1816/**
1817 * __iw_get_name() - SSR wrapper for __iw_get_name
1818 * @dev: pointer to net_device
1819 * @info: pointer to iw_request_info
1820 * @wrqu: pointer to iwreq_data
1821 * @extra: extra
1822 *
1823 * Return: 0 on success, error number otherwise
1824 */
1825static int iw_get_name(struct net_device *dev,
1826 struct iw_request_info *info,
1827 char *wrqu, char *extra)
1828{
1829 int ret;
1830
1831 cds_ssr_protect(__func__);
1832 ret = __iw_get_name(dev, info, wrqu, extra);
1833 cds_ssr_unprotect(__func__);
1834
1835 return ret;
1836}
1837
1838/**
1839 * __iw_set_mode() - ioctl handler
1840 * @dev: device upon which the ioctl was received
1841 * @info: ioctl request information
1842 * @wrqu: ioctl request data
1843 * @extra: ioctl extra data
1844 *
1845 * Return: 0 on success, non-zero on error
1846 */
1847static int __iw_set_mode(struct net_device *dev,
1848 struct iw_request_info *info,
1849 union iwreq_data *wrqu, char *extra)
1850{
1851 hdd_wext_state_t *pWextState;
1852 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
1853 hdd_context_t *hdd_ctx;
1854 tCsrRoamProfile *pRoamProfile;
1855 eCsrRoamBssType LastBSSType;
1856 eMib_dot11DesiredBssType connectedBssType;
1857 struct hdd_config *pConfig;
1858 struct wireless_dev *wdev;
1859 int ret;
1860
Jeff Johnsonb25dcb12016-02-11 17:46:42 -08001861 ENTER_DEV(dev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001862
1863 hdd_ctx = WLAN_HDD_GET_CTX(pAdapter);
1864 ret = wlan_hdd_validate_context(hdd_ctx);
1865 if (0 != ret)
1866 return ret;
1867
1868 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
1869 wdev = dev->ieee80211_ptr;
1870 pRoamProfile = &pWextState->roamProfile;
1871 LastBSSType = pRoamProfile->BSSType;
1872
1873 hddLog(LOG1, "%s Old Bss type = %d", __func__, LastBSSType);
1874
1875 switch (wrqu->mode) {
1876 case IW_MODE_ADHOC:
1877 hddLog(LOG1, "%s Setting AP Mode as IW_MODE_ADHOC", __func__);
1878 pRoamProfile->BSSType = eCSR_BSS_TYPE_START_IBSS;
1879 /* Set the phymode correctly for IBSS. */
1880 pConfig = (WLAN_HDD_GET_CTX(pAdapter))->config;
1881 pWextState->roamProfile.phyMode =
1882 hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode);
Krunal Sonif07bb382016-03-10 13:02:11 -08001883 pAdapter->device_mode = QDF_IBSS_MODE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001884 wdev->iftype = NL80211_IFTYPE_ADHOC;
1885 break;
1886 case IW_MODE_INFRA:
1887 hddLog(LOG1, "%s Setting AP Mode as IW_MODE_INFRA", __func__);
1888 pRoamProfile->BSSType = eCSR_BSS_TYPE_INFRASTRUCTURE;
1889 wdev->iftype = NL80211_IFTYPE_STATION;
1890 break;
1891 case IW_MODE_AUTO:
1892 hddLog(LOG1, "%s Setting AP Mode as IW_MODE_AUTO", __func__);
1893 pRoamProfile->BSSType = eCSR_BSS_TYPE_ANY;
1894 break;
1895 default:
1896 hddLog(LOGE, "%s Unknown AP Mode value %d ", __func__,
1897 wrqu->mode);
1898 return -EOPNOTSUPP;
1899 }
1900
1901 if (LastBSSType != pRoamProfile->BSSType) {
1902 /* the BSS mode changed. We need to issue disconnect
1903 * if connected or in IBSS disconnect state
1904 */
1905 if (hdd_conn_get_connected_bss_type
1906 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), &connectedBssType)
1907 || (eCSR_BSS_TYPE_START_IBSS == LastBSSType)) {
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301908 QDF_STATUS qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001909 /* need to issue a disconnect to CSR. */
1910 INIT_COMPLETION(pAdapter->disconnect_comp_var);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301911 qdf_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001912 sme_roam_disconnect(WLAN_HDD_GET_HAL_CTX(pAdapter),
1913 pAdapter->sessionId,
1914 eCSR_DISCONNECT_REASON_IBSS_LEAVE);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301915 if (QDF_STATUS_SUCCESS == qdf_status) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001916 unsigned long rc;
1917 rc = wait_for_completion_timeout(&pAdapter->
1918 disconnect_comp_var,
1919 msecs_to_jiffies
1920 (WLAN_WAIT_TIME_DISCONNECT));
1921 if (!rc)
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301922 hddLog(QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001923 FL
1924 ("failed wait on disconnect_comp_var"));
1925 }
1926 }
1927 }
1928
1929 EXIT();
1930 return 0;
1931}
1932
1933/**
1934 * iw_set_mode() - SSR wrapper for __iw_set_mode()
1935 * @dev: pointer to net_device
1936 * @info: pointer to iw_request_info
1937 * @wrqu: pointer to iwreq_data
1938 * @extra: pointer to extra ioctl payload
1939 *
1940 * Return: 0 on success, error number otherwise
1941 */
1942static int iw_set_mode(struct net_device *dev, struct iw_request_info *info,
1943 union iwreq_data *wrqu, char *extra)
1944{
1945 int ret;
1946
1947 cds_ssr_protect(__func__);
1948 ret = __iw_set_mode(dev, info, wrqu, extra);
1949 cds_ssr_unprotect(__func__);
1950
1951 return ret;
1952}
1953
1954/**
1955 * __iw_get_mode() - SIOCGIWMODE ioctl handler
1956 * @dev: device upon which the ioctl was received
1957 * @info: ioctl request information
1958 * @wrqu: ioctl request data
1959 * @extra: ioctl extra data
1960 *
1961 * Return: 0 on success, non-zero on error
1962 */
1963static int
1964__iw_get_mode(struct net_device *dev, struct iw_request_info *info,
1965 union iwreq_data *wrqu, char *extra)
1966{
1967 hdd_wext_state_t *pWextState;
1968 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
1969 hdd_context_t *hdd_ctx;
1970 int ret;
1971
Jeff Johnsonb25dcb12016-02-11 17:46:42 -08001972 ENTER_DEV(dev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001973
1974 hdd_ctx = WLAN_HDD_GET_CTX(pAdapter);
1975 ret = wlan_hdd_validate_context(hdd_ctx);
1976 if (0 != ret)
1977 return ret;
1978
1979 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
1980
1981 switch (pWextState->roamProfile.BSSType) {
1982 case eCSR_BSS_TYPE_INFRASTRUCTURE:
1983 hddLog(LOG1, FL("returns IW_MODE_INFRA"));
1984 wrqu->mode = IW_MODE_INFRA;
1985 break;
1986 case eCSR_BSS_TYPE_IBSS:
1987 case eCSR_BSS_TYPE_START_IBSS:
1988 hddLog(LOG1, FL("returns IW_MODE_ADHOC"));
1989 wrqu->mode = IW_MODE_ADHOC;
1990 break;
1991 case eCSR_BSS_TYPE_ANY:
1992 default:
1993 hddLog(LOG1, FL("returns IW_MODE_AUTO"));
1994 wrqu->mode = IW_MODE_AUTO;
1995 break;
1996 }
1997
1998 EXIT();
1999 return 0;
2000}
2001
2002/**
2003 * iw_get_mode() - SSR wrapper for __iw_get_mode()
2004 * @dev: pointer to net_device
2005 * @info: pointer to iw_request_info
2006 * @wrqu: pointer to iwreq_data
2007 * @extra: pointer to extra ioctl payload
2008 *
2009 * Return: 0 on success, error number otherwise
2010 */
2011static int iw_get_mode(struct net_device *dev, struct iw_request_info *info,
2012 union iwreq_data *wrqu, char *extra)
2013{
2014 int ret;
2015
2016 cds_ssr_protect(__func__);
2017 ret = __iw_get_mode(dev, info, wrqu, extra);
2018 cds_ssr_unprotect(__func__);
2019
2020 return ret;
2021}
2022
2023/**
2024 * __iw_set_freq() - SIOCSIWFREQ ioctl handler
2025 * @dev: device upon which the ioctl was received
2026 * @info: ioctl request information
2027 * @wrqu: ioctl request data
2028 * @extra: ioctl extra data
2029 *
2030 * Return: 0 on success, non-zero on error
2031 */
2032static int __iw_set_freq(struct net_device *dev, struct iw_request_info *info,
2033 union iwreq_data *wrqu, char *extra)
2034{
2035 uint32_t numChans = 0;
2036 uint8_t validChan[WNI_CFG_VALID_CHANNEL_LIST_LEN];
2037 uint32_t indx = 0;
2038 int ret;
2039 hdd_wext_state_t *pWextState;
2040 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
2041 hdd_context_t *hdd_ctx;
2042 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
2043 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
2044 tCsrRoamProfile *pRoamProfile;
2045
Jeff Johnsonb25dcb12016-02-11 17:46:42 -08002046 ENTER_DEV(dev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002047
2048 hdd_ctx = WLAN_HDD_GET_CTX(pAdapter);
2049 ret = wlan_hdd_validate_context(hdd_ctx);
2050 if (0 != ret)
2051 return ret;
2052
2053 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
2054
2055 pRoamProfile = &pWextState->roamProfile;
2056
2057 hddLog(LOG1, "setCHANNEL ioctl");
2058
2059 /* Link is up then return cant set channel */
2060 if (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState ||
2061 eConnectionState_Associated == pHddStaCtx->conn_info.connState) {
2062 hddLog(LOGE, "IBSS Associated");
2063 return -EOPNOTSUPP;
2064 }
2065
2066 /* Settings by Frequency as input */
2067 if ((wrqu->freq.e == 1) && (wrqu->freq.m >= (uint32_t) 2.412e8) &&
2068 (wrqu->freq.m <= (uint32_t) 5.825e8)) {
2069 uint32_t freq = wrqu->freq.m / 100000;
2070
2071 while ((indx < FREQ_CHAN_MAP_TABLE_SIZE)
2072 && (freq != freq_chan_map[indx].freq))
2073 indx++;
2074 if (indx >= FREQ_CHAN_MAP_TABLE_SIZE) {
2075 return -EINVAL;
2076 }
2077 wrqu->freq.e = 0;
2078 wrqu->freq.m = freq_chan_map[indx].chan;
2079
2080 }
2081
2082 if (wrqu->freq.e == 0) {
2083 if ((wrqu->freq.m < WNI_CFG_CURRENT_CHANNEL_STAMIN) ||
2084 (wrqu->freq.m > WNI_CFG_CURRENT_CHANNEL_STAMAX)) {
2085 hddLog(LOG1,
2086 "%s: Channel [%d] is outside valid range from %d to %d",
2087 __func__, wrqu->freq.m,
2088 WNI_CFG_CURRENT_CHANNEL_STAMIN,
2089 WNI_CFG_CURRENT_CHANNEL_STAMAX);
2090 return -EINVAL;
2091 }
2092
2093 numChans = WNI_CFG_VALID_CHANNEL_LIST_LEN;
2094
2095 if (sme_cfg_get_str(hHal, WNI_CFG_VALID_CHANNEL_LIST,
2096 validChan, &numChans) !=
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302097 QDF_STATUS_SUCCESS) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302098 QDF_TRACE(QDF_MODULE_ID_HDD, QDF_TRACE_LEVEL_WARN, FL
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002099 ("failed to get ini parameter, WNI_CFG_VALID_CHANNEL_LIST"));
2100 return -EIO;
2101 }
2102
2103 for (indx = 0; indx < numChans; indx++) {
2104 if (wrqu->freq.m == validChan[indx]) {
2105 break;
2106 }
2107 }
2108 } else {
2109
2110 return -EINVAL;
2111 }
2112
2113 if (indx >= numChans) {
2114 return -EINVAL;
2115 }
2116
2117 /* Set the Operational Channel */
2118 numChans = pRoamProfile->ChannelInfo.numOfChannels = 1;
2119 pHddStaCtx->conn_info.operationChannel = wrqu->freq.m;
2120 pRoamProfile->ChannelInfo.ChannelList =
2121 &pHddStaCtx->conn_info.operationChannel;
2122
2123 hddLog(LOG1, "pRoamProfile->operationChannel = %d", wrqu->freq.m);
2124
2125 EXIT();
2126
2127 return ret;
2128}
2129
2130/**
2131 * iw_set_freq() - SSR wrapper for __iw_set_freq()
2132 * @dev: pointer to net_device
2133 * @info: pointer to iw_request_info
2134 * @wrqu: pointer to iwreq_data
2135 * @extra: pointer to extra ioctl payload
2136 *
2137 * Return: 0 on success, error number otherwise
2138 */
2139static int iw_set_freq(struct net_device *dev, struct iw_request_info *info,
2140 union iwreq_data *wrqu, char *extra)
2141{
2142 int ret;
2143
2144 cds_ssr_protect(__func__);
2145 ret = __iw_set_freq(dev, info, wrqu, extra);
2146 cds_ssr_unprotect(__func__);
2147
2148 return ret;
2149}
2150
2151/**
2152 * __iw_get_freq() - SIOCGIWFREQ ioctl handler
2153 * @dev: device upon which the ioctl was received
2154 * @info: ioctl request information
2155 * @wrqu: ioctl request data
2156 * @extra: ioctl extra data
2157 *
2158 * Return: 0 on success, non-zero on error
2159 */
2160static int __iw_get_freq(struct net_device *dev, struct iw_request_info *info,
2161 struct iw_freq *fwrq, char *extra)
2162{
2163 uint32_t status = false, channel = 0, freq = 0;
2164 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
2165 tHalHandle hHal;
2166 hdd_wext_state_t *pWextState;
2167 tCsrRoamProfile *pRoamProfile;
2168 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
2169 hdd_context_t *hdd_ctx;
2170 int ret;
2171
Jeff Johnsonb25dcb12016-02-11 17:46:42 -08002172 ENTER_DEV(dev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002173
2174 hdd_ctx = WLAN_HDD_GET_CTX(pAdapter);
2175 ret = wlan_hdd_validate_context(hdd_ctx);
2176 if (0 != ret)
2177 return ret;
2178
2179 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
2180 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
2181
2182 pRoamProfile = &pWextState->roamProfile;
2183
2184 if (pHddStaCtx->conn_info.connState == eConnectionState_Associated) {
2185 if (sme_get_operation_channel(hHal, &channel, pAdapter->sessionId)
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302186 != QDF_STATUS_SUCCESS) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302187 QDF_TRACE(QDF_MODULE_ID_HDD, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002188 FL("failed to get operating channel %u"),
2189 pAdapter->sessionId);
2190 return -EIO;
2191 } else {
2192 status = hdd_wlan_get_freq(channel, &freq);
2193 if (true == status) {
2194 /* Set Exponent parameter as 6 (MHZ)
2195 * in struct iw_freq iwlist & iwconfig
2196 * command shows frequency into proper
2197 * format (2.412 GHz instead of 246.2
2198 * MHz)
2199 */
2200 fwrq->m = freq;
2201 fwrq->e = MHZ;
2202 }
2203 }
2204 } else {
2205 /* Set Exponent parameter as 6 (MHZ) in struct iw_freq
2206 * iwlist & iwconfig command shows frequency into proper
2207 * format (2.412 GHz instead of 246.2 MHz)
2208 */
2209 fwrq->m = 0;
2210 fwrq->e = MHZ;
2211 }
2212 return 0;
2213}
2214
2215/**
2216 * iw_get_freq() - SSR wrapper for __iw_get_freq()
2217 * @dev: pointer to net_device
2218 * @info: pointer to iw_request_info
2219 * @fwrq: pointer to frequency data
2220 * @extra: pointer to extra ioctl payload
2221 *
2222 * Return: 0 on success, error number otherwise
2223 */
2224static int iw_get_freq(struct net_device *dev, struct iw_request_info *info,
2225 struct iw_freq *fwrq, char *extra)
2226{
2227 int ret;
2228
2229 cds_ssr_protect(__func__);
2230 ret = __iw_get_freq(dev, info, fwrq, extra);
2231 cds_ssr_unprotect(__func__);
2232
2233 return ret;
2234}
2235
2236/**
2237 * __iw_get_tx_power() - SIOCGIWTXPOW ioctl handler
2238 * @dev: device upon which the ioctl was received
2239 * @info: ioctl request information
2240 * @wrqu: ioctl request data
2241 * @extra: ioctl extra data
2242 *
2243 * Return: 0 on success, non-zero on error
2244 */
2245static int __iw_get_tx_power(struct net_device *dev,
2246 struct iw_request_info *info,
2247 union iwreq_data *wrqu, char *extra)
2248{
2249
2250 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
2251 hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(pAdapter);
2252 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
2253 int ret;
2254
Jeff Johnsonb25dcb12016-02-11 17:46:42 -08002255 ENTER_DEV(dev);
2256
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002257 ret = wlan_hdd_validate_context(hdd_ctx);
2258 if (0 != ret)
2259 return ret;
2260
2261 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState) {
2262 wrqu->txpower.value = 0;
2263 return 0;
2264 }
2265 wlan_hdd_get_class_astats(pAdapter);
2266 wrqu->txpower.value = pAdapter->hdd_stats.ClassA_stat.max_pwr;
2267
2268 return 0;
2269}
2270
2271/**
2272 * iw_get_tx_power() - SSR wrapper for __iw_get_tx_power()
2273 * @dev: pointer to net_device
2274 * @info: pointer to iw_request_info
2275 * @wrqu: pointer to iwreq_data
2276 * @extra: pointer to extra ioctl payload
2277 *
2278 * Return: 0 on success, error number otherwise
2279 */
2280static int iw_get_tx_power(struct net_device *dev,
2281 struct iw_request_info *info,
2282 union iwreq_data *wrqu, char *extra)
2283{
2284 int ret;
2285
2286 cds_ssr_protect(__func__);
2287 ret = __iw_get_tx_power(dev, info, wrqu, extra);
2288 cds_ssr_unprotect(__func__);
2289
2290 return ret;
2291}
2292
2293/**
2294 * __iw_set_tx_power() - SIOCSIWTXPOW ioctl handler
2295 * @dev: device upon which the ioctl was received
2296 * @info: ioctl request information
2297 * @wrqu: ioctl request data
2298 * @extra: ioctl extra data
2299 *
2300 * Return: 0 on success, non-zero on error
2301 */
2302static int __iw_set_tx_power(struct net_device *dev,
2303 struct iw_request_info *info,
2304 union iwreq_data *wrqu, char *extra)
2305{
2306 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
2307 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
2308 hdd_context_t *hdd_ctx;
2309 int ret;
2310
Jeff Johnsonb25dcb12016-02-11 17:46:42 -08002311 ENTER_DEV(dev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002312
2313 hdd_ctx = WLAN_HDD_GET_CTX(pAdapter);
2314 ret = wlan_hdd_validate_context(hdd_ctx);
2315 if (0 != ret)
2316 return ret;
2317
2318 if (sme_cfg_set_int(hHal, WNI_CFG_CURRENT_TX_POWER_LEVEL,
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302319 wrqu->txpower.value) != QDF_STATUS_SUCCESS) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302320 QDF_TRACE(QDF_MODULE_ID_HDD, QDF_TRACE_LEVEL_ERROR, FL
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002321 ("failed to set ini parameter, WNI_CFG_CURRENT_TX_POWER_LEVEL"));
2322 return -EIO;
2323 }
2324
2325 EXIT();
2326
2327 return 0;
2328}
2329
2330/**
2331 * iw_set_tx_power() - SSR wrapper for __iw_set_tx_power()
2332 * @dev: pointer to net_device
2333 * @info: pointer to iw_request_info
2334 * @wrqu: pointer to iwreq_data
2335 * @extra: pointer to extra ioctl payload
2336 *
2337 * Return: 0 on success, error number otherwise
2338 */
2339static int iw_set_tx_power(struct net_device *dev,
2340 struct iw_request_info *info,
2341 union iwreq_data *wrqu, char *extra)
2342{
2343 int ret;
2344
2345 cds_ssr_protect(__func__);
2346 ret = __iw_set_tx_power(dev, info, wrqu, extra);
2347 cds_ssr_unprotect(__func__);
2348
2349 return ret;
2350}
2351
2352/**
2353 * __iw_get_bitrate() - SIOCGIWRATE ioctl handler
2354 * @dev: device upon which the ioctl was received
2355 * @info: ioctl request information
2356 * @wrqu: ioctl request data
2357 * @extra: ioctl extra data
2358 *
2359 * Return: 0 on success, non-zero on error
2360 */
2361static int __iw_get_bitrate(struct net_device *dev,
2362 struct iw_request_info *info,
2363 union iwreq_data *wrqu, char *extra)
2364{
Anurag Chouhance0dc992016-02-16 18:18:03 +05302365 QDF_STATUS qdf_status = QDF_STATUS_SUCCESS;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302366 QDF_STATUS status = QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002367 hdd_wext_state_t *pWextState;
2368 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
2369 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
2370 hdd_context_t *hdd_ctx;
2371 int ret;
2372
Jeff Johnsonb25dcb12016-02-11 17:46:42 -08002373 ENTER_DEV(dev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002374
2375 hdd_ctx = WLAN_HDD_GET_CTX(pAdapter);
2376 ret = wlan_hdd_validate_context(hdd_ctx);
2377 if (0 != ret)
2378 return ret;
2379
Prashanth Bhatta9e143052015-12-04 11:56:47 -08002380 if (cds_is_driver_recovering()) {
2381 hdd_alert("Recovery in Progress. State: 0x%x Ignore!!!",
2382 cds_get_driver_state());
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002383 return status;
2384 }
2385
2386 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState) {
2387 wrqu->bitrate.value = 0;
2388 } else {
2389 status =
2390 sme_get_statistics(WLAN_HDD_GET_HAL_CTX(pAdapter),
2391 eCSR_HDD,
2392 SME_SUMMARY_STATS |
2393 SME_GLOBAL_CLASSA_STATS |
2394 SME_GLOBAL_CLASSB_STATS |
2395 SME_GLOBAL_CLASSC_STATS |
2396 SME_GLOBAL_CLASSD_STATS |
2397 SME_PER_STA_STATS,
2398 hdd_statistics_cb, 0,
2399 false,
2400 pHddStaCtx->conn_info.staId[0],
2401 pAdapter, pAdapter->sessionId);
2402
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302403 if (QDF_STATUS_SUCCESS != status) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302404 hddLog(QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002405 "%s: Unable to retrieve statistics", __func__);
2406 return status;
2407 }
2408
2409 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
2410
Anurag Chouhance0dc992016-02-16 18:18:03 +05302411 qdf_status =
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05302412 qdf_wait_single_event(&pWextState->hdd_qdf_event,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002413 WLAN_WAIT_TIME_STATS);
2414
Anurag Chouhance0dc992016-02-16 18:18:03 +05302415 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302416 hddLog(QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002417 "%s: SME timeout while retrieving statistics",
2418 __func__);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302419 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002420 }
2421
2422 wrqu->bitrate.value =
2423 pAdapter->hdd_stats.ClassA_stat.tx_rate * 500 * 1000;
2424 }
2425
2426 EXIT();
2427
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302428 return qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002429}
2430
2431/**
2432 * iw_get_bitrate() - SSR wrapper for __iw_get_bitrate()
2433 * @dev: pointer to net_device
2434 * @info: pointer to iw_request_info
2435 * @wrqu: pointer to iwreq_data
2436 * @extra: pointer to extra ioctl payload
2437 *
2438 * Return: 0 on success, error number otherwise
2439 */
2440static int iw_get_bitrate(struct net_device *dev,
2441 struct iw_request_info *info,
2442 union iwreq_data *wrqu, char *extra)
2443{
2444 int ret;
2445
2446 cds_ssr_protect(__func__);
2447 ret = __iw_get_bitrate(dev, info, wrqu, extra);
2448 cds_ssr_unprotect(__func__);
2449
2450 return ret;
2451}
2452
2453/**
2454 * __iw_set_bitrate() - SIOCSIWRATE ioctl handler
2455 * @dev: device upon which the ioctl was received
2456 * @info: ioctl request information
2457 * @wrqu: ioctl request data
2458 * @extra: ioctl extra data
2459 *
2460 * Return: 0 on success, non-zero on error
2461 */
2462static int __iw_set_bitrate(struct net_device *dev,
2463 struct iw_request_info *info,
2464 union iwreq_data *wrqu, char *extra)
2465{
2466 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
2467 hdd_wext_state_t *pWextState;
2468 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
2469 uint8_t supp_rates[WNI_CFG_SUPPORTED_RATES_11A_LEN];
2470 uint32_t a_len = WNI_CFG_SUPPORTED_RATES_11A_LEN;
2471 uint32_t b_len = WNI_CFG_SUPPORTED_RATES_11B_LEN;
2472 uint32_t i, rate;
2473 uint32_t valid_rate = false, active_phy_mode = 0;
2474 hdd_context_t *hdd_ctx;
2475 int ret;
2476
Jeff Johnsonb25dcb12016-02-11 17:46:42 -08002477 ENTER_DEV(dev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002478
2479 hdd_ctx = WLAN_HDD_GET_CTX(pAdapter);
2480 ret = wlan_hdd_validate_context(hdd_ctx);
2481 if (0 != ret)
2482 return ret;
2483
2484 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
2485
2486 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState) {
2487 return -ENXIO;
2488 }
2489
2490 rate = wrqu->bitrate.value;
2491
2492 if (rate == -1) {
2493 rate = WNI_CFG_FIXED_RATE_AUTO;
2494 valid_rate = true;
2495 } else if (sme_cfg_get_int(WLAN_HDD_GET_HAL_CTX(pAdapter),
2496 WNI_CFG_DOT11_MODE,
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302497 &active_phy_mode) == QDF_STATUS_SUCCESS) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002498 if (active_phy_mode == WNI_CFG_DOT11_MODE_11A
2499 || active_phy_mode == WNI_CFG_DOT11_MODE_11G
2500 || active_phy_mode == WNI_CFG_DOT11_MODE_11B) {
2501 if ((sme_cfg_get_str(WLAN_HDD_GET_HAL_CTX(pAdapter),
2502 WNI_CFG_SUPPORTED_RATES_11A, supp_rates,
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302503 &a_len) == QDF_STATUS_SUCCESS)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002504 &&
2505 (sme_cfg_get_str(WLAN_HDD_GET_HAL_CTX(pAdapter),
2506 WNI_CFG_SUPPORTED_RATES_11B, supp_rates,
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302507 &b_len) == QDF_STATUS_SUCCESS)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002508 for (i = 0; i < (b_len + a_len); ++i) {
2509 /* supported rates returned is double
2510 * the actual rate so we divide it by 2
2511 */
2512 if ((supp_rates[i] & 0x7F) / 2 ==
2513 rate) {
2514 valid_rate = true;
2515 rate = i +
2516 WNI_CFG_FIXED_RATE_1MBPS;
2517 break;
2518 }
2519 }
2520 }
2521 }
2522 }
2523 if (valid_rate != true) {
2524 return -EINVAL;
2525 }
2526 if (sme_cfg_set_int(WLAN_HDD_GET_HAL_CTX(pAdapter),
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302527 WNI_CFG_FIXED_RATE, rate) != QDF_STATUS_SUCCESS) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302528 QDF_TRACE(QDF_MODULE_ID_HDD, QDF_TRACE_LEVEL_ERROR, FL
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002529 ("failed to set ini parameter, WNI_CFG_FIXED_RATE"));
2530 return -EIO;
2531 }
2532 return 0;
2533}
2534
2535/**
2536 * iw_set_bitrate() - SSR wrapper for __iw_set_bitrate()
2537 * @dev: pointer to net_device
2538 * @info: pointer to iw_request_info
2539 * @wrqu: pointer to iwreq_data
2540 * @extra: pointer to extra ioctl payload
2541 *
2542 * Return: 0 on success, error number otherwise
2543 */
2544static int iw_set_bitrate(struct net_device *dev,
2545 struct iw_request_info *info,
2546 union iwreq_data *wrqu, char *extra)
2547{
2548 int ret;
2549
2550 cds_ssr_protect(__func__);
2551 ret = __iw_set_bitrate(dev, info, wrqu, extra);
2552 cds_ssr_unprotect(__func__);
2553
2554 return ret;
2555}
2556
2557/**
2558 * __iw_set_genie() - SIOCSIWGENIE ioctl handler
2559 * @dev: device upon which the ioctl was received
2560 * @info: ioctl request information
2561 * @wrqu: ioctl request data
2562 * @extra: ioctl extra data
2563 *
2564 * Return: 0 on success, non-zero on error
2565 */
2566static int __iw_set_genie(struct net_device *dev,
2567 struct iw_request_info *info,
2568 union iwreq_data *wrqu, char *extra)
2569{
2570 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
2571 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
2572 uint8_t *genie = NULL;
2573 uint8_t *base_genie = NULL;
2574 uint16_t remLen;
2575 hdd_context_t *hdd_ctx;
2576 int ret;
2577
Jeff Johnsonb25dcb12016-02-11 17:46:42 -08002578 ENTER_DEV(dev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002579
2580 hdd_ctx = WLAN_HDD_GET_CTX(pAdapter);
2581 ret = wlan_hdd_validate_context(hdd_ctx);
2582 if (0 != ret)
2583 return ret;
2584
2585 if (!wrqu->data.length) {
2586 hdd_clear_roam_profile_ie(pAdapter);
2587 EXIT();
2588 return 0;
2589 }
2590
2591 base_genie = mem_alloc_copy_from_user_helper(wrqu->data.pointer,
2592 wrqu->data.length);
2593 if (NULL == base_genie) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302594 QDF_TRACE(QDF_MODULE_ID_HDD, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002595 "mem_alloc_copy_from_user_helper fail");
2596 return -ENOMEM;
2597 }
2598
2599 genie = base_genie;
2600
2601 remLen = wrqu->data.length;
2602
2603 hddLog(LOG1, "iw_set_genie ioctl IE[0x%X], LEN[%d]", genie[0],
2604 genie[1]);
2605
2606 /* clear any previous genIE before this call */
2607 memset(&pWextState->genIE, 0, sizeof(pWextState->genIE));
2608
2609 while (remLen >= 2) {
2610 uint16_t eLen = 0;
2611 uint8_t elementId;
2612 elementId = *genie++;
2613 eLen = *genie++;
2614 remLen -= 2;
2615
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302616 hddLog(QDF_TRACE_LEVEL_INFO, "%s: IE[0x%X], LEN[%d]",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002617 __func__, elementId, eLen);
2618
2619 switch (elementId) {
2620 case IE_EID_VENDOR:
2621 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 +05302622 ret = -EINVAL;
2623 goto exit;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002624 }
2625
2626 if (0 == memcmp(&genie[0], "\x00\x50\xf2\x04", 4)) {
2627 uint16_t curGenIELen = pWextState->genIE.length;
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302628 hddLog(QDF_TRACE_LEVEL_INFO,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002629 "%s Set WPS OUI(%02x %02x %02x %02x) IE(len %d)",
2630 __func__, genie[0], genie[1], genie[2],
2631 genie[3], eLen + 2);
2632
2633 if (SIR_MAC_MAX_IE_LENGTH <
2634 (pWextState->genIE.length + eLen)) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302635 hddLog(QDF_TRACE_LEVEL_FATAL,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002636 "Cannot accommodate genIE. "
2637 "Need bigger buffer space");
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302638 QDF_ASSERT(0);
Mahesh A Saptasagard639dde2015-11-06 12:39:13 +05302639 ret = -ENOMEM;
2640 goto exit;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002641 }
2642 /* save to Additional IE ; it should be accumulated to handle WPS IE + other IE */
2643 memcpy(pWextState->genIE.addIEdata +
2644 curGenIELen, genie - 2, eLen + 2);
2645 pWextState->genIE.length += eLen + 2;
2646 } else if (0 == memcmp(&genie[0], "\x00\x50\xf2", 3)) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302647 hddLog(QDF_TRACE_LEVEL_INFO,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002648 "%s Set WPA IE (len %d)", __func__,
2649 eLen + 2);
Mahesh A Saptasagard639dde2015-11-06 12:39:13 +05302650 if ((eLen + 2) > (sizeof(pWextState->WPARSNIE))) {
2651 hdd_warn("Cannot accommodate genIE, Need bigger buffer space");
2652 ret = -EINVAL;
2653 QDF_ASSERT(0);
2654 goto exit;
2655 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002656 memset(pWextState->WPARSNIE, 0,
2657 MAX_WPA_RSN_IE_LEN);
2658 memcpy(pWextState->WPARSNIE, genie - 2,
2659 (eLen + 2));
2660 pWextState->roamProfile.pWPAReqIE =
2661 pWextState->WPARSNIE;
2662 pWextState->roamProfile.nWPAReqIELength =
2663 eLen + 2;
2664 } else { /* any vendorId except WPA IE should be accumulated to genIE */
2665
2666 uint16_t curGenIELen = pWextState->genIE.length;
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302667 hddLog(QDF_TRACE_LEVEL_INFO,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002668 "%s Set OUI(%02x %02x %02x %02x) IE(len %d)",
2669 __func__, genie[0], genie[1], genie[2],
2670 genie[3], eLen + 2);
2671
2672 if (SIR_MAC_MAX_IE_LENGTH <
2673 (pWextState->genIE.length + eLen)) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302674 hddLog(QDF_TRACE_LEVEL_FATAL,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002675 "Cannot accommodate genIE. "
2676 "Need bigger buffer space");
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302677 QDF_ASSERT(0);
Mahesh A Saptasagard639dde2015-11-06 12:39:13 +05302678 ret = -ENOMEM;
2679 goto exit;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002680 }
2681 /* save to Additional IE ; it should be accumulated to handle WPS IE + other IE */
2682 memcpy(pWextState->genIE.addIEdata +
2683 curGenIELen, genie - 2, eLen + 2);
2684 pWextState->genIE.length += eLen + 2;
2685 }
2686 break;
2687 case DOT11F_EID_RSN:
2688 hddLog(LOG1, "%s Set RSN IE (len %d)", __func__,
2689 eLen + 2);
Mahesh A Saptasagard639dde2015-11-06 12:39:13 +05302690 if ((eLen + 2) > (sizeof(pWextState->WPARSNIE))) {
2691 hdd_warn("Cannot accommodate genIE, Need bigger buffer space");
2692 ret = -EINVAL;
2693 QDF_ASSERT(0);
2694 goto exit;
2695 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002696 memset(pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN);
2697 memcpy(pWextState->WPARSNIE, genie - 2, (eLen + 2));
2698 pWextState->roamProfile.pRSNReqIE =
2699 pWextState->WPARSNIE;
2700 pWextState->roamProfile.nRSNReqIELength = eLen + 2;
2701 break;
2702
2703 default:
2704 hddLog(LOGE, "%s Set UNKNOWN IE %X", __func__,
2705 elementId);
Mahesh A Saptasagard639dde2015-11-06 12:39:13 +05302706 goto exit;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002707 }
2708 genie += eLen;
2709 remLen -= eLen;
2710 }
Mahesh A Saptasagard639dde2015-11-06 12:39:13 +05302711exit:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002712 EXIT();
2713 kfree(base_genie);
Mahesh A Saptasagard639dde2015-11-06 12:39:13 +05302714 return ret;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002715}
2716
2717/**
2718 * iw_set_genie() - SSR wrapper for __iw_set_genie()
2719 * @dev: pointer to net_device
2720 * @info: pointer to iw_request_info
2721 * @wrqu: pointer to iwreq_data
2722 * @extra: pointer to extra ioctl payload
2723 *
2724 * Return: 0 on success, error number otherwise
2725 */
2726static int iw_set_genie(struct net_device *dev,
2727 struct iw_request_info *info,
2728 union iwreq_data *wrqu, char *extra)
2729{
2730 int ret;
2731
2732 cds_ssr_protect(__func__);
2733 ret = __iw_set_genie(dev, info, wrqu, extra);
2734 cds_ssr_unprotect(__func__);
2735
2736 return ret;
2737}
2738
2739/**
2740 * __iw_get_genie() - SIOCGIWGENIE ioctl handler
2741 * @dev: device upon which the ioctl was received
2742 * @info: ioctl request information
2743 * @wrqu: ioctl request data
2744 * @extra: ioctl extra data
2745 *
2746 * Return: 0 on success, non-zero on error
2747 */
2748static int __iw_get_genie(struct net_device *dev,
2749 struct iw_request_info *info,
2750 union iwreq_data *wrqu, char *extra)
2751{
2752 hdd_wext_state_t *pWextState;
2753 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
2754 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302755 QDF_STATUS status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002756 uint32_t length = DOT11F_IE_RSN_MAX_LEN;
2757 uint8_t genIeBytes[DOT11F_IE_RSN_MAX_LEN];
2758 hdd_context_t *hdd_ctx;
2759 int ret;
2760
Jeff Johnsonb25dcb12016-02-11 17:46:42 -08002761 ENTER_DEV(dev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002762
2763 hdd_ctx = WLAN_HDD_GET_CTX(pAdapter);
2764 ret = wlan_hdd_validate_context(hdd_ctx);
2765 if (0 != ret)
2766 return ret;
2767
2768 hddLog(LOG1, "getGEN_IE ioctl");
2769
2770 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
2771
2772 if (pHddStaCtx->conn_info.connState == eConnectionState_NotConnected) {
2773 return -ENXIO;
2774 }
2775
2776 /* Return something ONLY if we are associated with an RSN or
2777 * WPA network
2778 */
2779 if (!hdd_is_auth_type_rsn(pWextState->roamProfile.negotiatedAuthType)) {
2780 return -ENXIO;
2781 }
2782
2783 /* Actually retrieve the RSN IE from CSR. (We previously sent
2784 * it down in the CSR Roam Profile.)
2785 */
2786 status = csr_roam_get_wpa_rsn_req_ie(WLAN_HDD_GET_HAL_CTX(pAdapter),
2787 pAdapter->sessionId,
2788 &length, genIeBytes);
Anurag Chouhan6d760662016-02-20 16:05:43 +05302789 length = QDF_MIN((uint16_t) length, DOT11F_IE_RSN_MAX_LEN);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002790 if (wrqu->data.length < length) {
2791 hddLog(LOG1, "%s: failed to copy data to user buffer",
2792 __func__);
2793 return -EFAULT;
2794 }
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302795 qdf_mem_copy(extra, (void *)genIeBytes, length);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002796 wrqu->data.length = length;
2797
2798 hddLog(LOG1, "%s: RSN IE of %d bytes returned", __func__,
2799 wrqu->data.length);
2800
2801 EXIT();
2802
2803 return 0;
2804}
2805
2806/**
2807 * iw_get_genie() - SSR wrapper for __iw_get_genie()
2808 * @dev: pointer to net_device
2809 * @info: pointer to iw_request_info
2810 * @wrqu: pointer to iwreq_data
2811 * @extra: pointer to extra ioctl payload
2812 *
2813 * Return: 0 on success, error number otherwise
2814 */
2815static int iw_get_genie(struct net_device *dev,
2816 struct iw_request_info *info,
2817 union iwreq_data *wrqu, char *extra)
2818{
2819 int ret;
2820
2821 cds_ssr_protect(__func__);
2822 ret = __iw_get_genie(dev, info, wrqu, extra);
2823 cds_ssr_unprotect(__func__);
2824
2825 return ret;
2826}
2827
2828/**
2829 * __iw_get_encode() - SIOCGIWENCODE ioctl handler
2830 * @dev: device upon which the ioctl was received
2831 * @info: ioctl request information
2832 * @wrqu: ioctl request data
2833 * @extra: ioctl extra data
2834 *
2835 * Return: 0 on success, non-zero on error
2836 */
2837static int __iw_get_encode(struct net_device *dev,
2838 struct iw_request_info *info,
2839 struct iw_point *dwrq, char *extra)
2840{
2841 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
2842 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
2843 tCsrRoamProfile *pRoamProfile = &(pWextState->roamProfile);
2844 int keyId;
2845 eCsrAuthType authType = eCSR_AUTH_TYPE_NONE;
2846 int i;
2847 hdd_context_t *hdd_ctx;
2848 int ret;
2849
Jeff Johnsonb25dcb12016-02-11 17:46:42 -08002850 ENTER_DEV(dev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002851
2852 hdd_ctx = WLAN_HDD_GET_CTX(pAdapter);
2853 ret = wlan_hdd_validate_context(hdd_ctx);
2854 if (0 != ret)
2855 return ret;
2856
2857 keyId = pRoamProfile->Keys.defaultIndex;
2858
2859 if (keyId < 0 || keyId >= MAX_WEP_KEYS) {
2860 hddLog(LOG1, "%s: Invalid keyId : %d", __func__, keyId);
2861 return -EINVAL;
2862 }
2863
2864 if (pRoamProfile->Keys.KeyLength[keyId] > 0) {
2865 dwrq->flags |= IW_ENCODE_ENABLED;
2866 dwrq->length = pRoamProfile->Keys.KeyLength[keyId];
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302867 qdf_mem_copy(extra, &(pRoamProfile->Keys.KeyMaterial[keyId][0]),
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002868 pRoamProfile->Keys.KeyLength[keyId]);
2869
2870 dwrq->flags |= (keyId + 1);
2871
2872 } else {
2873 dwrq->flags |= IW_ENCODE_DISABLED;
2874 }
2875
2876 for (i = 0; i < MAX_WEP_KEYS; i++) {
2877 if (pRoamProfile->Keys.KeyMaterial[i] == NULL) {
2878 continue;
2879 } else {
2880 break;
2881 }
2882 }
2883
2884 if (MAX_WEP_KEYS == i) {
2885 dwrq->flags |= IW_ENCODE_NOKEY;
2886 }
2887
2888 authType =
2889 ((hdd_station_ctx_t *) WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->
2890 conn_info.authType;
2891
2892 if (eCSR_AUTH_TYPE_OPEN_SYSTEM == authType) {
2893 dwrq->flags |= IW_ENCODE_OPEN;
2894 } else {
2895 dwrq->flags |= IW_ENCODE_RESTRICTED;
2896 }
2897 EXIT();
2898 return 0;
2899}
2900
2901/**
2902 * iw_get_encode() - SSR wrapper for __iw_get_encode()
2903 * @dev: pointer to net_device
2904 * @info: pointer to iw_request_info
2905 * @dwrq: pointer to encoding information
2906 * @extra: pointer to extra ioctl payload
2907 *
2908 * Return: 0 on success, error number otherwise
2909 */
2910static int iw_get_encode(struct net_device *dev, struct iw_request_info *info,
2911 struct iw_point *dwrq, char *extra)
2912{
2913 int ret;
2914
2915 cds_ssr_protect(__func__);
2916 ret = __iw_get_encode(dev, info, dwrq, extra);
2917 cds_ssr_unprotect(__func__);
2918
2919 return ret;
2920}
2921
2922/**
2923 * __iw_get_rts_threshold() - SIOCGIWRTS ioctl handler
2924 * @dev: device upon which the ioctl was received
2925 * @info: ioctl request information
2926 * @wrqu: ioctl request data
2927 * @extra: ioctl extra data
2928 *
2929 * Return: 0 on success, non-zero on error
2930 */
2931static int __iw_get_rts_threshold(struct net_device *dev,
2932 struct iw_request_info *info,
2933 union iwreq_data *wrqu, char *extra)
2934{
2935 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
2936 uint32_t status = 0;
2937
Jeff Johnsonb25dcb12016-02-11 17:46:42 -08002938 ENTER_DEV(dev);
2939
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002940 status = hdd_wlan_get_rts_threshold(pAdapter, wrqu);
2941
2942 return status;
2943}
2944
2945/**
2946 * __iw_set_rts_threshold() - SIOCSIWRTS ioctl handler
2947 * @dev: device upon which the ioctl was received
2948 * @info: ioctl request information
2949 * @wrqu: ioctl request data
2950 * @extra: ioctl extra data
2951 *
2952 * Return: 0 on success, non-zero on error
2953 */
2954static int __iw_set_rts_threshold(struct net_device *dev,
2955 struct iw_request_info *info,
2956 union iwreq_data *wrqu, char *extra)
2957{
2958 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
2959 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
2960 hdd_context_t *hdd_ctx;
2961 int ret;
2962
Jeff Johnsonb25dcb12016-02-11 17:46:42 -08002963 ENTER_DEV(dev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002964
2965 hdd_ctx = WLAN_HDD_GET_CTX(pAdapter);
2966 ret = wlan_hdd_validate_context(hdd_ctx);
2967 if (0 != ret)
2968 return ret;
2969
2970 if (wrqu->rts.value < WNI_CFG_RTS_THRESHOLD_STAMIN
2971 || wrqu->rts.value > WNI_CFG_RTS_THRESHOLD_STAMAX) {
2972 return -EINVAL;
2973 }
2974
2975 if (sme_cfg_set_int(hHal, WNI_CFG_RTS_THRESHOLD, wrqu->rts.value) !=
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302976 QDF_STATUS_SUCCESS) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302977 QDF_TRACE(QDF_MODULE_ID_HDD, QDF_TRACE_LEVEL_ERROR, FL
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002978 ("failed to set ini parameter, WNI_CFG_RTS_THRESHOLD"));
2979 return -EIO;
2980 }
2981
2982 EXIT();
2983
2984 return 0;
2985}
2986
2987/**
2988 * iw_get_rts_threshold() - SSR wrapper for __iw_get_rts_threshold()
2989 * @dev: pointer to net_device
2990 * @info: pointer to iw_request_info
2991 * @wrqu: pointer to iwreq_data
2992 * @extra: pointer to extra ioctl payload
2993 *
2994 * Return: 0 on success, error number otherwise
2995 */
2996static int iw_get_rts_threshold(struct net_device *dev,
2997 struct iw_request_info *info,
2998 union iwreq_data *wrqu, char *extra)
2999{
3000 int ret;
3001
3002 cds_ssr_protect(__func__);
3003 ret = __iw_get_rts_threshold(dev, info, wrqu, extra);
3004 cds_ssr_unprotect(__func__);
3005
3006 return ret;
3007}
3008
3009/**
3010 * iw_set_rts_threshold() - SSR wrapper for __iw_set_rts_threshold()
3011 * @dev: pointer to net_device
3012 * @info: pointer to iw_request_info
3013 * @wrqu: pointer to iwreq_data
3014 * @extra: pointer to extra ioctl payload
3015 *
3016 * Return: 0 on success, error number otherwise
3017 */
3018static int iw_set_rts_threshold(struct net_device *dev,
3019 struct iw_request_info *info,
3020 union iwreq_data *wrqu, char *extra)
3021{
3022 int ret;
3023
3024 cds_ssr_protect(__func__);
3025 ret = __iw_set_rts_threshold(dev, info, wrqu, extra);
3026 cds_ssr_unprotect(__func__);
3027
3028 return ret;
3029}
3030
3031/**
3032 * __iw_get_frag_threshold() - SIOCGIWFRAG ioctl handler
3033 * @dev: device upon which the ioctl was received
3034 * @info: ioctl request information
3035 * @wrqu: ioctl request data
3036 * @extra: ioctl extra data
3037 *
3038 * Return: 0 on success, non-zero on error
3039 */
3040static int __iw_get_frag_threshold(struct net_device *dev,
3041 struct iw_request_info *info,
3042 union iwreq_data *wrqu, char *extra)
3043{
3044 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3045 uint32_t status = 0;
3046
Jeff Johnsonb25dcb12016-02-11 17:46:42 -08003047 ENTER_DEV(dev);
3048
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003049 status = hdd_wlan_get_frag_threshold(pAdapter, wrqu);
3050
3051 return status;
3052}
3053
3054/**
3055 * iw_get_frag_threshold() - SSR wrapper for __iw_get_frag_threshold()
3056 * @dev: pointer to net_device
3057 * @info: pointer to iw_request_info
3058 * @wrqu: pointer to iwreq_data
3059 * @extra: pointer to extra ioctl payload
3060 *
3061 * Return: 0 on success, error number otherwise
3062 */
3063static int iw_get_frag_threshold(struct net_device *dev,
3064 struct iw_request_info *info,
3065 union iwreq_data *wrqu, char *extra)
3066{
3067 int ret;
3068
3069 cds_ssr_protect(__func__);
3070 ret = __iw_get_frag_threshold(dev, info, wrqu, extra);
3071 cds_ssr_unprotect(__func__);
3072
3073 return ret;
3074}
3075
3076/**
3077 * __iw_set_frag_threshold() - SIOCSIWFRAG ioctl handler
3078 * @dev: device upon which the ioctl was received
3079 * @info: ioctl request information
3080 * @wrqu: ioctl request data
3081 * @extra: ioctl extra data
3082 *
3083 * Return: 0 on success, non-zero on error
3084 */
3085static int __iw_set_frag_threshold(struct net_device *dev,
3086 struct iw_request_info *info,
3087 union iwreq_data *wrqu, char *extra)
3088{
3089 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3090 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
3091 hdd_context_t *hdd_ctx;
3092 int ret;
3093
Jeff Johnsonb25dcb12016-02-11 17:46:42 -08003094 ENTER_DEV(dev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003095
3096 hdd_ctx = WLAN_HDD_GET_CTX(pAdapter);
3097 ret = wlan_hdd_validate_context(hdd_ctx);
3098 if (0 != ret)
3099 return ret;
3100
3101 if (wrqu->frag.value < WNI_CFG_FRAGMENTATION_THRESHOLD_STAMIN
3102 || wrqu->frag.value > WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX) {
3103 return -EINVAL;
3104 }
3105
3106 if (sme_cfg_set_int
3107 (hHal, WNI_CFG_FRAGMENTATION_THRESHOLD, wrqu->frag.value)
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303108 != QDF_STATUS_SUCCESS) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05303109 QDF_TRACE(QDF_MODULE_ID_HDD, QDF_TRACE_LEVEL_ERROR, FL
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003110 ("failed to set ini parameter, WNI_CFG_FRAGMENTATION_THRESHOLD"));
3111 return -EIO;
3112 }
3113
3114 EXIT();
3115
3116 return 0;
3117}
3118
3119/**
3120 * iw_set_frag_threshold() - SSR wrapper for __iw_set_frag_threshold()
3121 * @dev: pointer to net_device
3122 * @info: pointer to iw_request_info
3123 * @wrqu: pointer to iwreq_data
3124 * @extra: pointer to extra ioctl payload
3125 *
3126 * Return: 0 on success, error number otherwise
3127 */
3128static int iw_set_frag_threshold(struct net_device *dev,
3129 struct iw_request_info *info,
3130 union iwreq_data *wrqu, char *extra)
3131{
3132 int ret;
3133
3134 cds_ssr_protect(__func__);
3135 ret = __iw_set_frag_threshold(dev, info, wrqu, extra);
3136 cds_ssr_unprotect(__func__);
3137
3138 return ret;
3139}
3140
3141/**
3142 * __iw_get_power_mode() - SIOCGIWPOWER ioctl handler
3143 * @dev: device upon which the ioctl was received
3144 * @info: ioctl request information
3145 * @wrqu: ioctl request data
3146 * @extra: ioctl extra data
3147 *
3148 * Return: 0 on success, non-zero on error
3149 */
3150static int __iw_get_power_mode(struct net_device *dev,
3151 struct iw_request_info *info,
3152 union iwreq_data *wrqu, char *extra)
3153{
3154 hdd_adapter_t *adapter;
3155 hdd_context_t *hdd_ctx;
3156 int ret;
3157
Jeff Johnsonb25dcb12016-02-11 17:46:42 -08003158 ENTER_DEV(dev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003159
3160 adapter = WLAN_HDD_GET_PRIV_PTR(dev);
3161 hdd_ctx = WLAN_HDD_GET_CTX(adapter);
3162 ret = wlan_hdd_validate_context(hdd_ctx);
3163 if (0 != ret)
3164 return ret;
3165
3166 return -EOPNOTSUPP;
3167}
3168
3169/**
3170 * iw_get_power_mode() - SSR wrapper function for __iw_get_power_mode
3171 * @dev: pointer to net_device
3172 * @info: pointer to iw_request_info
3173 * @wrqu: pointer to iwreq_data
3174 * @extra: extra
3175 *
3176 * Return: 0 on success, error number otherwise
3177 */
3178int iw_get_power_mode(struct net_device *dev,
3179 struct iw_request_info *info,
3180 union iwreq_data *wrqu, char *extra)
3181{
3182 int ret;
3183
3184 cds_ssr_protect(__func__);
3185 ret = __iw_get_power_mode(dev, info, wrqu, extra);
3186 cds_ssr_unprotect(__func__);
3187
3188 return ret;
3189}
3190
3191/**
3192 * __iw_set_power_mode() - SIOCSIWPOWER ioctl handler
3193 * @dev: device upon which the ioctl was received
3194 * @info: ioctl request information
3195 * @wrqu: ioctl request data
3196 * @extra: ioctl extra data
3197 *
3198 * Return: 0 on success, non-zero on error
3199 */
3200static int __iw_set_power_mode(struct net_device *dev,
3201 struct iw_request_info *info,
3202 union iwreq_data *wrqu, char *extra)
3203{
3204 hdd_adapter_t *adapter;
3205 hdd_context_t *hdd_ctx;
3206 int ret;
3207
Jeff Johnsonb25dcb12016-02-11 17:46:42 -08003208 ENTER_DEV(dev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003209
3210 adapter = WLAN_HDD_GET_PRIV_PTR(dev);
3211 hdd_ctx = WLAN_HDD_GET_CTX(adapter);
3212 ret = wlan_hdd_validate_context(hdd_ctx);
3213 if (0 != ret)
3214 return ret;
3215
3216 return -EOPNOTSUPP;
3217}
3218
3219/**
3220 * iw_set_power_mode() - SSR wrapper function for __iw_set_power_mode
3221 * @dev: pointer to net_device
3222 * @info: pointer to iw_request_info
3223 * @wrqu: pointer to iwreq_data
3224 * @extra: extra
3225 *
3226 * Return: 0 on success, error number otherwise
3227 */
3228int iw_set_power_mode(struct net_device *dev,
3229 struct iw_request_info *info,
3230 union iwreq_data *wrqu, char *extra)
3231{
3232 int ret;
3233
3234 cds_ssr_protect(__func__);
3235 ret = __iw_set_power_mode(dev, info, wrqu, extra);
3236 cds_ssr_unprotect(__func__);
3237
3238 return ret;
3239}
3240
3241/**
3242 * __iw_get_range() - SIOCGIWRANGE ioctl handler
3243 * @dev: device upon which the ioctl was received
3244 * @info: ioctl request information
3245 * @wrqu: ioctl request data
3246 * @extra: ioctl extra data
3247 *
3248 * Return: 0 on success, non-zero on error
3249 */
3250static int __iw_get_range(struct net_device *dev, struct iw_request_info *info,
3251 union iwreq_data *wrqu, char *extra)
3252{
3253 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3254 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
3255 struct iw_range *range = (struct iw_range *)extra;
3256
3257 uint8_t channels[WNI_CFG_VALID_CHANNEL_LIST_LEN];
3258
3259 uint32_t num_channels = sizeof(channels);
3260 uint8_t supp_rates[WNI_CFG_SUPPORTED_RATES_11A_LEN];
3261 uint32_t a_len;
3262 uint32_t b_len;
3263 uint32_t active_phy_mode = 0;
3264 uint8_t index = 0, i;
3265 hdd_context_t *hdd_ctx;
3266 int ret;
3267
Jeff Johnsonb25dcb12016-02-11 17:46:42 -08003268 ENTER_DEV(dev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003269
3270 hdd_ctx = WLAN_HDD_GET_CTX(pAdapter);
3271 ret = wlan_hdd_validate_context(hdd_ctx);
3272 if (0 != ret)
3273 return ret;
3274
3275 wrqu->data.length = sizeof(struct iw_range);
3276 memset(range, 0, sizeof(struct iw_range));
3277
3278
3279 /*Get the phy mode */
3280 if (sme_cfg_get_int(hHal,
3281 WNI_CFG_DOT11_MODE,
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303282 &active_phy_mode) == QDF_STATUS_SUCCESS) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05303283 QDF_TRACE(QDF_MODULE_ID_HDD, QDF_TRACE_LEVEL_INFO,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003284 "active_phy_mode = %d", active_phy_mode);
3285
3286 if (active_phy_mode == WNI_CFG_DOT11_MODE_11A
3287 || active_phy_mode == WNI_CFG_DOT11_MODE_11G) {
3288 /*Get the supported rates for 11G band */
3289 a_len = WNI_CFG_SUPPORTED_RATES_11A_LEN;
3290 if (sme_cfg_get_str(hHal,
3291 WNI_CFG_SUPPORTED_RATES_11A,
3292 supp_rates,
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303293 &a_len) == QDF_STATUS_SUCCESS) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003294 if (a_len > WNI_CFG_SUPPORTED_RATES_11A_LEN) {
3295 a_len = WNI_CFG_SUPPORTED_RATES_11A_LEN;
3296 }
3297 for (i = 0; i < a_len; i++) {
3298 range->bitrate[i] =
3299 ((supp_rates[i] & 0x7F) / 2) *
3300 1000000;
3301 }
3302 range->num_bitrates = a_len;
3303 } else {
3304 return -EIO;
3305 }
3306 } else if (active_phy_mode == WNI_CFG_DOT11_MODE_11B) {
3307 /*Get the supported rates for 11B band */
3308 b_len = WNI_CFG_SUPPORTED_RATES_11B_LEN;
3309 if (sme_cfg_get_str(hHal,
3310 WNI_CFG_SUPPORTED_RATES_11B,
3311 supp_rates,
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303312 &b_len) == QDF_STATUS_SUCCESS) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003313 if (b_len > WNI_CFG_SUPPORTED_RATES_11B_LEN) {
3314 b_len = WNI_CFG_SUPPORTED_RATES_11B_LEN;
3315 }
3316 for (i = 0; i < b_len; i++) {
3317 range->bitrate[i] =
3318 ((supp_rates[i] & 0x7F) / 2) *
3319 1000000;
3320 }
3321 range->num_bitrates = b_len;
3322 } else {
3323 return -EIO;
3324 }
3325 }
3326 }
3327
3328 range->max_rts = WNI_CFG_RTS_THRESHOLD_STAMAX;
3329 range->min_frag = WNI_CFG_FRAGMENTATION_THRESHOLD_STAMIN;
3330 range->max_frag = WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX;
3331
3332 range->encoding_size[0] = 5;
3333 range->encoding_size[1] = 13;
3334 range->num_encoding_sizes = 2;
3335 range->max_encoding_tokens = MAX_WEP_KEYS;
3336
3337 /* we support through Wireless Extensions 22 */
3338 range->we_version_compiled = WIRELESS_EXT;
3339 range->we_version_source = 22;
3340
3341 /*Supported Channels and Frequencies */
3342 if (sme_cfg_get_str
3343 ((hHal), WNI_CFG_VALID_CHANNEL_LIST, channels,
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303344 &num_channels) != QDF_STATUS_SUCCESS) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05303345 QDF_TRACE(QDF_MODULE_ID_HDD, QDF_TRACE_LEVEL_WARN,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003346 FL
3347 ("failed to get ini parameter, WNI_CFG_VALID_CHANNEL_LIST"));
3348 return -EIO;
3349 }
3350 if (num_channels > IW_MAX_FREQUENCIES) {
3351 num_channels = IW_MAX_FREQUENCIES;
3352 }
3353
3354 range->num_channels = num_channels;
3355 range->num_frequency = num_channels;
3356
3357 for (index = 0; index < num_channels; index++) {
3358 uint32_t frq_indx = 0;
3359
3360 range->freq[index].i = channels[index];
3361 while (frq_indx < FREQ_CHAN_MAP_TABLE_SIZE) {
3362 if (channels[index] == freq_chan_map[frq_indx].chan) {
3363 range->freq[index].m =
3364 freq_chan_map[frq_indx].freq * 100000;
3365 range->freq[index].e = 1;
3366 break;
3367 }
3368 frq_indx++;
3369 }
3370 }
3371
3372 /* Event capability (kernel + driver) */
3373 range->event_capa[0] = (IW_EVENT_CAPA_K_0 |
3374 IW_EVENT_CAPA_MASK(SIOCGIWAP) |
3375 IW_EVENT_CAPA_MASK(SIOCGIWSCAN));
3376 range->event_capa[1] = IW_EVENT_CAPA_K_1;
3377
3378 /*Encryption capability */
3379 range->enc_capa = IW_ENC_CAPA_WPA | IW_ENC_CAPA_WPA2 |
3380 IW_ENC_CAPA_CIPHER_TKIP | IW_ENC_CAPA_CIPHER_CCMP;
3381
3382 /* Txpower capability */
3383 range->txpower_capa = IW_TXPOW_MWATT;
3384
3385 /*Scanning capability */
3386#if WIRELESS_EXT >= 22
3387 range->scan_capa =
3388 IW_SCAN_CAPA_ESSID | IW_SCAN_CAPA_TYPE | IW_SCAN_CAPA_CHANNEL;
3389#endif
3390
3391 EXIT();
3392 return 0;
3393}
3394
3395/**
3396 * iw_get_range() - SSR wrapper for __iw_get_range()
3397 * @dev: pointer to net_device
3398 * @info: pointer to iw_request_info
3399 * @wrqu: pointer to iwreq_data
3400 * @extra: pointer to extra ioctl payload
3401 *
3402 * Return: 0 on success, error number otherwise
3403 */
3404static int iw_get_range(struct net_device *dev, struct iw_request_info *info,
3405 union iwreq_data *wrqu, char *extra)
3406{
3407 int ret;
3408
3409 cds_ssr_protect(__func__);
3410 ret = __iw_get_range(dev, info, wrqu, extra);
3411 cds_ssr_unprotect(__func__);
3412
3413 return ret;
3414}
3415
3416/**
3417 * hdd_get_class_a_statistics_cb() - Get Class A stats callback function
3418 * @pStats: pointer to Class A stats
3419 * @pContext: user context originally registered with SME
3420 *
3421 * Return: None
3422 */
3423static void hdd_get_class_a_statistics_cb(void *pStats, void *pContext)
3424{
3425 struct statsContext *pStatsContext;
3426 tCsrGlobalClassAStatsInfo *pClassAStats;
3427 hdd_adapter_t *pAdapter;
3428
3429 if (ioctl_debug) {
3430 pr_info("%s: pStats [%p] pContext [%p]\n",
3431 __func__, pStats, pContext);
3432 }
3433
3434 if ((NULL == pStats) || (NULL == pContext)) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05303435 hddLog(QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003436 "%s: Bad param, pStats [%p] pContext [%p]",
3437 __func__, pStats, pContext);
3438 return;
3439 }
3440
3441 pClassAStats = pStats;
3442 pStatsContext = pContext;
3443 pAdapter = pStatsContext->pAdapter;
3444
3445 /* there is a race condition that exists between this callback
3446 * function and the caller since the caller could time out
3447 * either before or while this code is executing. we use a
3448 * spinlock to serialize these actions
3449 */
3450 spin_lock(&hdd_context_lock);
3451
3452 if ((NULL == pAdapter) ||
3453 (STATS_CONTEXT_MAGIC != pStatsContext->magic)) {
3454 /* the caller presumably timed out so there is nothing
3455 * we can do
3456 */
3457 spin_unlock(&hdd_context_lock);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05303458 hddLog(QDF_TRACE_LEVEL_WARN,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003459 "%s: Invalid context, pAdapter [%p] magic [%08x]",
3460 __func__, pAdapter, pStatsContext->magic);
3461 if (ioctl_debug) {
3462 pr_info("%s: Invalid context, pAdapter [%p] magic [%08x]\n",
3463 __func__, pAdapter, pStatsContext->magic);
3464 }
3465 return;
3466 }
3467
3468 /* context is valid so caller is still waiting */
3469
3470 /* paranoia: invalidate the magic */
3471 pStatsContext->magic = 0;
3472
3473 /* copy over the stats. do so as a struct copy */
3474 pAdapter->hdd_stats.ClassA_stat = *pClassAStats;
3475
3476 /* notify the caller */
3477 complete(&pStatsContext->completion);
3478
3479 /* serialization is complete */
3480 spin_unlock(&hdd_context_lock);
3481}
3482
3483/**
3484 * wlan_hdd_get_class_astats() - Get Class A statistics
3485 * @pAdapter: adapter for which statistics are desired
3486 *
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303487 * Return: QDF_STATUS_SUCCESS if adapter's Class A statistics were updated
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003488 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303489QDF_STATUS wlan_hdd_get_class_astats(hdd_adapter_t *pAdapter)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003490{
3491 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303492 QDF_STATUS hstatus;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003493 unsigned long rc;
3494 struct statsContext context;
3495
3496 if (NULL == pAdapter) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05303497 hddLog(QDF_TRACE_LEVEL_ERROR, "%s: pAdapter is NULL", __func__);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303498 return QDF_STATUS_E_FAULT;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003499 }
Prashanth Bhatta9e143052015-12-04 11:56:47 -08003500 if (cds_is_driver_recovering()) {
3501 hdd_err("Recovery in Progress. State: 0x%x Ignore!!!",
3502 cds_get_driver_state());
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303503 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003504 }
3505
3506 /* we are connected so prepare our callback context */
3507 init_completion(&context.completion);
3508 context.pAdapter = pAdapter;
3509 context.magic = STATS_CONTEXT_MAGIC;
3510 /* query only for Class A statistics (which include link speed) */
3511 hstatus = sme_get_statistics(WLAN_HDD_GET_HAL_CTX(pAdapter),
3512 eCSR_HDD, SME_GLOBAL_CLASSA_STATS,
3513 hdd_get_class_a_statistics_cb,
3514 0, /* not periodic */
3515 false, /* non-cached results */
3516 pHddStaCtx->conn_info.staId[0],
3517 &context, pAdapter->sessionId);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303518 if (QDF_STATUS_SUCCESS != hstatus) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05303519 hddLog(QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003520 "%s: Unable to retrieve Class A statistics", __func__);
3521 /* we'll returned a cached value below */
3522 } else {
3523 /* request was sent -- wait for the response */
3524 rc = wait_for_completion_timeout
3525 (&context.completion,
3526 msecs_to_jiffies(WLAN_WAIT_TIME_STATS));
3527 if (!rc) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05303528 hddLog(QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003529 FL("SME timed out while retrieving Class A statistics"));
3530 }
3531 }
3532
3533 /* either we never sent a request, we sent a request and
3534 * received a response or we sent a request and timed out. if
3535 * we never sent a request or if we sent a request and got a
3536 * response, we want to clear the magic out of paranoia. if
3537 * we timed out there is a race condition such that the
3538 * callback function could be executing at the same time we
3539 * are. of primary concern is if the callback function had
3540 * already verified the "magic" but had not yet set the
3541 * completion variable when a timeout occurred. we serialize
3542 * these activities by invalidating the magic while holding a
3543 * shared spinlock which will cause us to block if the
3544 * callback is currently executing
3545 */
3546 spin_lock(&hdd_context_lock);
3547 context.magic = 0;
3548 spin_unlock(&hdd_context_lock);
3549
3550 /* either callback updated pAdapter stats or it has cached data */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303551 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003552}
3553
3554/**
3555 * hdd_get_station_statistics_cb() - Get stats callback function
3556 * @pStats: pointer to Class A stats
3557 * @pContext: user context originally registered with SME
3558 *
3559 * Return: None
3560 */
3561static void hdd_get_station_statistics_cb(void *pStats, void *pContext)
3562{
3563 struct statsContext *pStatsContext;
3564 tCsrSummaryStatsInfo *pSummaryStats;
3565 tCsrGlobalClassAStatsInfo *pClassAStats;
3566 hdd_adapter_t *pAdapter;
3567
3568 if (ioctl_debug) {
3569 pr_info("%s: pStats [%p] pContext [%p]\n",
3570 __func__, pStats, pContext);
3571 }
3572
3573 if ((NULL == pStats) || (NULL == pContext)) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05303574 hddLog(QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003575 "%s: Bad param, pStats [%p] pContext [%p]",
3576 __func__, pStats, pContext);
3577 return;
3578 }
3579
3580 /* there is a race condition that exists between this callback
3581 * function and the caller since the caller could time out
3582 * either before or while this code is executing. we use a
3583 * spinlock to serialize these actions
3584 */
3585 spin_lock(&hdd_context_lock);
3586
3587 pSummaryStats = (tCsrSummaryStatsInfo *) pStats;
3588 pClassAStats = (tCsrGlobalClassAStatsInfo *) (pSummaryStats + 1);
3589 pStatsContext = pContext;
3590 pAdapter = pStatsContext->pAdapter;
3591 if ((NULL == pAdapter) ||
3592 (STATS_CONTEXT_MAGIC != pStatsContext->magic)) {
3593 /* the caller presumably timed out so there is nothing
3594 * we can do
3595 */
3596 spin_unlock(&hdd_context_lock);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05303597 hddLog(QDF_TRACE_LEVEL_WARN,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003598 "%s: Invalid context, pAdapter [%p] magic [%08x]",
3599 __func__, pAdapter, pStatsContext->magic);
3600 if (ioctl_debug) {
3601 pr_info("%s: Invalid context, pAdapter [%p] magic [%08x]\n",
3602 __func__, pAdapter, pStatsContext->magic);
3603 }
3604 return;
3605 }
3606
3607 /* context is valid so caller is still waiting */
3608
3609 /* paranoia: invalidate the magic */
3610 pStatsContext->magic = 0;
3611
3612 /* copy over the stats. do so as a struct copy */
3613 pAdapter->hdd_stats.summary_stat = *pSummaryStats;
3614 pAdapter->hdd_stats.ClassA_stat = *pClassAStats;
3615
3616 /* notify the caller */
3617 complete(&pStatsContext->completion);
3618
3619 /* serialization is complete */
3620 spin_unlock(&hdd_context_lock);
3621}
3622
3623/**
3624 * wlan_hdd_get_station_stats() - Get station statistics
3625 * @pAdapter: adapter for which statistics are desired
3626 *
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303627 * Return: QDF_STATUS_SUCCESS if adapter's statistics were updated
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003628 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303629QDF_STATUS wlan_hdd_get_station_stats(hdd_adapter_t *pAdapter)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003630{
3631 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303632 QDF_STATUS hstatus;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003633 unsigned long rc;
3634 struct statsContext context;
3635
3636 if (NULL == pAdapter) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05303637 hddLog(QDF_TRACE_LEVEL_ERROR, "%s: pAdapter is NULL", __func__);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303638 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003639 }
3640
3641 /* we are connected so prepare our callback context */
3642 init_completion(&context.completion);
3643 context.pAdapter = pAdapter;
3644 context.magic = STATS_CONTEXT_MAGIC;
3645
3646 /* query only for Summary & Class A statistics */
3647 hstatus = sme_get_statistics(WLAN_HDD_GET_HAL_CTX(pAdapter),
3648 eCSR_HDD,
3649 SME_SUMMARY_STATS |
3650 SME_GLOBAL_CLASSA_STATS,
3651 hdd_get_station_statistics_cb,
3652 0, /* not periodic */
3653 false, /* non-cached results */
3654 pHddStaCtx->conn_info.staId[0],
3655 &context, pAdapter->sessionId);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303656 if (QDF_STATUS_SUCCESS != hstatus) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05303657 hddLog(QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003658 "%s: Unable to retrieve statistics", __func__);
3659 /* we'll return with cached values */
3660 } else {
3661 /* request was sent -- wait for the response */
3662 rc = wait_for_completion_timeout
3663 (&context.completion,
3664 msecs_to_jiffies(WLAN_WAIT_TIME_STATS));
3665
3666 if (!rc) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05303667 hddLog(QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003668 FL("SME timed out while retrieving statistics"));
3669 }
3670 }
3671
3672 /* either we never sent a request, we sent a request and
3673 * received a response or we sent a request and timed out. if
3674 * we never sent a request or if we sent a request and got a
3675 * response, we want to clear the magic out of paranoia. if
3676 * we timed out there is a race condition such that the
3677 * callback function could be executing at the same time we
3678 * are. of primary concern is if the callback function had
3679 * already verified the "magic" but had not yet set the
3680 * completion variable when a timeout occurred. we serialize
3681 * these activities by invalidating the magic while holding a
3682 * shared spinlock which will cause us to block if the
3683 * callback is currently executing
3684 */
3685 spin_lock(&hdd_context_lock);
3686 context.magic = 0;
3687 spin_unlock(&hdd_context_lock);
3688
3689 /* either callback updated pAdapter stats or it has cached data */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303690 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003691}
3692
3693/**
3694 * iw_get_linkspeed() - Get current link speed ioctl
3695 * @dev: device upon which the ioctl was received
3696 * @info: ioctl request information
3697 * @wrqu: ioctl request data
3698 * @extra: extra ioctl buffer
3699 *
3700 * Return: 0 on success, non-zero on error
3701 */
3702static int __iw_get_linkspeed(struct net_device *dev,
3703 struct iw_request_info *info,
3704 union iwreq_data *wrqu, char *extra)
3705{
3706 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3707 char *pLinkSpeed = (char *)extra;
3708 int len = sizeof(uint32_t) + 1;
3709 uint32_t link_speed = 0;
3710 hdd_context_t *hdd_ctx;
3711 int rc, valid;
3712
Jeff Johnson6ee91ee2016-02-11 18:55:30 -08003713 ENTER_DEV(dev);
Hanumantha Reddy Pothula2db50ed2015-11-23 10:48:33 +05303714
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003715 hdd_ctx = WLAN_HDD_GET_CTX(pAdapter);
3716 valid = wlan_hdd_validate_context(hdd_ctx);
3717 if (0 != valid)
3718 return valid;
3719
3720 rc = wlan_hdd_get_link_speed(pAdapter, &link_speed);
3721 if (0 != rc) {
3722 return rc;
3723 }
3724
3725 wrqu->data.length = len;
3726 /* return the linkspeed as a string */
3727 rc = snprintf(pLinkSpeed, len, "%u", link_speed);
3728 if ((rc < 0) || (rc >= len)) {
3729 /* encoding or length error? */
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05303730 hddLog(QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003731 FL("Unable to encode link speed"));
3732 return -EIO;
3733 }
3734
Hanumantha Reddy Pothula2db50ed2015-11-23 10:48:33 +05303735 EXIT();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003736 /* a value is being successfully returned */
3737 return 0;
3738}
3739
3740static int iw_get_linkspeed(struct net_device *dev,
3741 struct iw_request_info *info,
3742 union iwreq_data *wrqu, char *extra)
3743{
3744 int ret;
3745
3746 cds_ssr_protect(__func__);
3747 ret = __iw_get_linkspeed(dev, info, wrqu, extra);
3748 cds_ssr_unprotect(__func__);
3749
3750 return ret;
3751}
3752
3753/**
3754 * wlan_hdd_change_country_code_callback() - Change country code callback
3755 * @context: opaque context originally passed to SME. All functions
3756 * which use this callback pass the adapter upon which the country
3757 * code change is active
3758 *
3759 * This function is registered as the callback function when
3760 * sme_change_country_code() is invoked. Callers of
3761 * sme_change_country_code() subsequently wait for the adapter's
3762 * @change_country_code completion variable, so all this function
3763 * needs to do is set that completion variable so that execution can
3764 * continue.
3765 *
3766 * Return: none
3767 */
3768void wlan_hdd_change_country_code_callback(void *context)
3769{
3770
3771 hdd_adapter_t *adapter = context;
3772
3773 if (adapter && (WLAN_HDD_ADAPTER_MAGIC == adapter->magic))
3774 complete(&adapter->change_country_code);
3775
3776 return;
3777}
3778
3779/**
3780 * __iw_set_nick() - SIOCSIWNICKN ioctl handler
3781 * @dev: device upon which the ioctl was received
3782 * @info: ioctl request information
3783 * @wrqu: ioctl request data
3784 * @extra: ioctl extra data
3785 *
3786 * Return: 0 on success, non-zero on error
3787 */
3788static int __iw_set_nick(struct net_device *dev,
3789 struct iw_request_info *info,
3790 union iwreq_data *wrqu, char *extra)
3791{
3792 hdd_adapter_t *adapter;
3793 hdd_context_t *hdd_ctx;
3794 int ret;
3795
Jeff Johnsonb25dcb12016-02-11 17:46:42 -08003796 ENTER_DEV(dev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003797
3798 adapter = WLAN_HDD_GET_PRIV_PTR(dev);
3799 hdd_ctx = WLAN_HDD_GET_CTX(adapter);
3800 ret = wlan_hdd_validate_context(hdd_ctx);
3801 if (0 != ret)
3802 return ret;
3803
3804 return 0;
3805}
3806
3807/**
3808 * iw_set_nick() - SSR wrapper for __iw_set_nick
3809 * @dev: pointer to net_device
3810 * @info: pointer to iw_request_info
3811 * @wrqu: pointer to iwreq_data
3812 * @extra: extra
3813 *
3814 * Return: 0 on success, error number otherwise
3815 */
3816static int iw_set_nick(struct net_device *dev,
3817 struct iw_request_info *info,
3818 union iwreq_data *wrqu, char *extra)
3819{
3820 int ret;
3821
3822 cds_ssr_protect(__func__);
3823 ret = __iw_set_nick(dev, info, wrqu, extra);
3824 cds_ssr_unprotect(__func__);
3825
3826 return ret;
3827}
3828
3829/**
3830 * __iw_get_nick() - SIOCGIWNICKN ioctl handler
3831 * @dev: device upon which the ioctl was received
3832 * @info: ioctl request information
3833 * @wrqu: ioctl request data
3834 * @extra: ioctl extra data
3835 *
3836 * Return: 0 on success, non-zero on error
3837 */
3838static int __iw_get_nick(struct net_device *dev,
3839 struct iw_request_info *info,
3840 union iwreq_data *wrqu, char *extra)
3841{
3842 hdd_adapter_t *adapter;
3843 hdd_context_t *hdd_ctx;
3844 int ret;
3845
Jeff Johnsonb25dcb12016-02-11 17:46:42 -08003846 ENTER_DEV(dev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003847
3848 adapter = WLAN_HDD_GET_PRIV_PTR(dev);
3849 hdd_ctx = WLAN_HDD_GET_CTX(adapter);
3850 ret = wlan_hdd_validate_context(hdd_ctx);
3851 if (0 != ret)
3852 return ret;
3853
3854 return 0;
3855}
3856
3857/**
3858 * iw_get_nick() - SSR wrapper for __iw_get_nick
3859 * @dev: pointer to net_device
3860 * @info: pointer to iw_request_info
3861 * @wrqu: pointer to iwreq_data
3862 * @extra: extra
3863 *
3864 * Return: 0 on success, error number otherwise
3865 */
3866static int iw_get_nick(struct net_device *dev,
3867 struct iw_request_info *info,
3868 union iwreq_data *wrqu, char *extra)
3869{
3870 int ret;
3871
3872 cds_ssr_protect(__func__);
3873 ret = __iw_get_nick(dev, info, wrqu, extra);
3874 cds_ssr_unprotect(__func__);
3875
3876 return ret;
3877}
3878
3879/**
3880 * __iw_set_encode() - SIOCSIWENCODE ioctl handler
3881 * @dev: device upon which the ioctl was received
3882 * @info: ioctl request information
3883 * @wrqu: ioctl request data
3884 * @extra: ioctl extra data
3885 *
3886 * Return: 0 on success, non-zero on error
3887 */
3888static int __iw_set_encode(struct net_device *dev, struct iw_request_info *info,
3889 union iwreq_data *wrqu, char *extra)
3890{
3891 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3892 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
3893 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
3894 hdd_context_t *hdd_ctx;
3895 struct iw_point *encoderq = &(wrqu->encoding);
3896 uint32_t keyId;
3897 uint8_t key_length;
3898 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
3899 bool fKeyPresent = 0;
3900 int i;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303901 QDF_STATUS status = QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003902 int ret;
3903
Jeff Johnsonb25dcb12016-02-11 17:46:42 -08003904 ENTER_DEV(dev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003905
3906 hdd_ctx = WLAN_HDD_GET_CTX(pAdapter);
3907 ret = wlan_hdd_validate_context(hdd_ctx);
3908 if (0 != ret)
3909 return ret;
3910
3911 keyId = encoderq->flags & IW_ENCODE_INDEX;
3912
3913 if (keyId) {
3914 if (keyId > MAX_WEP_KEYS) {
3915 return -EINVAL;
3916 }
3917
3918 fKeyPresent = 1;
3919 keyId--;
3920 } else {
3921 fKeyPresent = 0;
3922 }
3923
3924 if (wrqu->data.flags & IW_ENCODE_DISABLED) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05303925 QDF_TRACE(QDF_MODULE_ID_HDD, QDF_TRACE_LEVEL_INFO,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003926 "****iwconfig wlan0 key off*****");
3927 if (!fKeyPresent) {
3928
3929 for (i = 0; i < CSR_MAX_NUM_KEY; i++) {
3930
3931 if (pWextState->roamProfile.Keys.KeyMaterial[i])
3932 pWextState->roamProfile.Keys.
3933 KeyLength[i] = 0;
3934 }
3935 }
3936 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_OPEN_SYSTEM;
3937 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
3938 pWextState->roamProfile.EncryptionType.encryptionType[0] =
3939 eCSR_ENCRYPT_TYPE_NONE;
3940 pWextState->roamProfile.mcEncryptionType.encryptionType[0] =
3941 eCSR_ENCRYPT_TYPE_NONE;
3942
3943 pHddStaCtx->conn_info.ucEncryptionType = eCSR_ENCRYPT_TYPE_NONE;
3944 pHddStaCtx->conn_info.mcEncryptionType = eCSR_ENCRYPT_TYPE_NONE;
3945
3946 if (eConnectionState_Associated ==
3947 pHddStaCtx->conn_info.connState) {
3948 INIT_COMPLETION(pAdapter->disconnect_comp_var);
3949 status =
3950 sme_roam_disconnect(WLAN_HDD_GET_HAL_CTX(pAdapter),
3951 pAdapter->sessionId,
3952 eCSR_DISCONNECT_REASON_UNSPECIFIED);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303953 if (QDF_STATUS_SUCCESS == status) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003954 unsigned long rc;
3955 rc = wait_for_completion_timeout(&pAdapter->
3956 disconnect_comp_var,
3957 msecs_to_jiffies
3958 (WLAN_WAIT_TIME_DISCONNECT));
3959 if (!rc)
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05303960 hddLog(QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003961 FL
3962 ("failed wait on disconnect_comp_var"));
3963 }
3964 }
3965
3966 return status;
3967
3968 }
3969
3970 if (wrqu->data.flags & (IW_ENCODE_OPEN | IW_ENCODE_RESTRICTED)) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05303971 hddLog(QDF_TRACE_LEVEL_INFO, "iwconfig wlan0 key on");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003972
3973 pHddStaCtx->conn_info.authType =
3974 (encoderq->
3975 flags & IW_ENCODE_RESTRICTED) ? eCSR_AUTH_TYPE_SHARED_KEY :
3976 eCSR_AUTH_TYPE_OPEN_SYSTEM;
3977
3978 }
3979
3980 if (wrqu->data.length > 0) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05303981 hddLog(QDF_TRACE_LEVEL_INFO, "%s : wrqu->data.length : %d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003982 __func__, wrqu->data.length);
3983
3984 key_length = wrqu->data.length;
3985
3986 /* IW_ENCODING_TOKEN_MAX is the value that is set for wrqu->data.length by iwconfig.c when 'iwconfig wlan0 key on' is issued. */
3987
3988 if (5 == key_length) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05303989 hddLog(QDF_TRACE_LEVEL_INFO,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003990 "%s: Call with WEP40,key_len=%d", __func__,
3991 key_length);
3992
3993 if ((IW_AUTH_KEY_MGMT_802_1X == pWextState->authKeyMgmt)
3994 && (eCSR_AUTH_TYPE_OPEN_SYSTEM ==
3995 pHddStaCtx->conn_info.authType)) {
3996 encryptionType = eCSR_ENCRYPT_TYPE_WEP40;
3997 } else {
3998 encryptionType =
3999 eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
4000 }
4001 } else if (13 == key_length) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05304002 hddLog(QDF_TRACE_LEVEL_INFO,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004003 "%s:Call with WEP104,key_len:%d", __func__,
4004 key_length);
4005
4006 if ((IW_AUTH_KEY_MGMT_802_1X == pWextState->authKeyMgmt)
4007 && (eCSR_AUTH_TYPE_OPEN_SYSTEM ==
4008 pHddStaCtx->conn_info.authType)) {
4009 encryptionType = eCSR_ENCRYPT_TYPE_WEP104;
4010 } else {
4011 encryptionType =
4012 eCSR_ENCRYPT_TYPE_WEP104_STATICKEY;
4013 }
4014 } else {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05304015 hddLog(QDF_TRACE_LEVEL_WARN,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004016 "%s: Invalid WEP key length :%d", __func__,
4017 key_length);
4018 return -EINVAL;
4019 }
4020
4021 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
4022 pHddStaCtx->conn_info.mcEncryptionType = encryptionType;
4023 pWextState->roamProfile.EncryptionType.numEntries = 1;
4024 pWextState->roamProfile.EncryptionType.encryptionType[0] =
4025 encryptionType;
4026 pWextState->roamProfile.mcEncryptionType.numEntries = 1;
4027 pWextState->roamProfile.mcEncryptionType.encryptionType[0] =
4028 encryptionType;
4029
4030 if ((eConnectionState_NotConnected ==
4031 pHddStaCtx->conn_info.connState)
4032 &&
4033 ((eCSR_AUTH_TYPE_OPEN_SYSTEM ==
4034 pHddStaCtx->conn_info.authType)
4035 || (eCSR_AUTH_TYPE_SHARED_KEY ==
4036 pHddStaCtx->conn_info.authType))) {
4037
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304038 qdf_mem_copy(&pWextState->roamProfile.Keys.
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004039 KeyMaterial[keyId][0], extra, key_length);
4040
4041 pWextState->roamProfile.Keys.KeyLength[keyId] =
4042 (uint8_t) key_length;
4043 pWextState->roamProfile.Keys.defaultIndex =
4044 (uint8_t) keyId;
4045
4046 return status;
4047 }
4048 }
4049
4050 return 0;
4051}
4052
4053/**
4054 * iw_set_encode() - SSR wrapper for __iw_set_encode()
4055 * @dev: pointer to net_device
4056 * @info: pointer to iw_request_info
4057 * @wrqu: pointer to iwreq_data
4058 * @extra: pointer to extra ioctl payload
4059 *
4060 * Return: 0 on success, error number otherwise
4061 */
4062static int iw_set_encode(struct net_device *dev, struct iw_request_info *info,
4063 union iwreq_data *wrqu, char *extra)
4064{
4065 int ret;
4066
4067 cds_ssr_protect(__func__);
4068 ret = __iw_set_encode(dev, info, wrqu, extra);
4069 cds_ssr_unprotect(__func__);
4070
4071 return ret;
4072}
4073
4074/**
4075 * __iw_get_encodeext() - SIOCGIWENCODEEXT ioctl handler
4076 * @dev: device upon which the ioctl was received
4077 * @info: ioctl request information
4078 * @wrqu: ioctl request data
4079 * @extra: ioctl extra data
4080 *
4081 * Return: 0 on success, non-zero on error
4082 */
4083static int __iw_get_encodeext(struct net_device *dev,
4084 struct iw_request_info *info,
4085 struct iw_point *dwrq, char *extra)
4086{
4087 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4088 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
4089 tCsrRoamProfile *pRoamProfile = &(pWextState->roamProfile);
4090 int keyId;
4091 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
4092 eCsrAuthType authType = eCSR_AUTH_TYPE_NONE;
4093 int i, ret;
4094 hdd_context_t *hdd_ctx;
4095
Jeff Johnsonb25dcb12016-02-11 17:46:42 -08004096 ENTER_DEV(dev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004097
4098 hdd_ctx = WLAN_HDD_GET_CTX(pAdapter);
4099 ret = wlan_hdd_validate_context(hdd_ctx);
4100 if (0 != ret)
4101 return ret;
4102
4103 keyId = pRoamProfile->Keys.defaultIndex;
4104
4105 if (keyId < 0 || keyId >= MAX_WEP_KEYS) {
4106 hddLog(LOG1, "%s: Invalid keyId : %d", __func__, keyId);
4107 return -EINVAL;
4108 }
4109
4110 if (pRoamProfile->Keys.KeyLength[keyId] > 0) {
4111 dwrq->flags |= IW_ENCODE_ENABLED;
4112 dwrq->length = pRoamProfile->Keys.KeyLength[keyId];
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304113 qdf_mem_copy(extra, &(pRoamProfile->Keys.KeyMaterial[keyId][0]),
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004114 pRoamProfile->Keys.KeyLength[keyId]);
4115 } else {
4116 dwrq->flags |= IW_ENCODE_DISABLED;
4117 }
4118
4119 for (i = 0; i < MAX_WEP_KEYS; i++) {
4120 if (pRoamProfile->Keys.KeyMaterial[i] == NULL) {
4121 continue;
4122 } else {
4123 break;
4124 }
4125 }
4126
4127 if (MAX_WEP_KEYS == i) {
4128 dwrq->flags |= IW_ENCODE_NOKEY;
4129 } else {
4130 dwrq->flags |= IW_ENCODE_ENABLED;
4131 }
4132
4133 encryptionType = pRoamProfile->EncryptionType.encryptionType[0];
4134
4135 if (eCSR_ENCRYPT_TYPE_NONE == encryptionType) {
4136 dwrq->flags |= IW_ENCODE_DISABLED;
4137 }
4138
4139 authType = (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.authType;
4140
4141 if (IW_AUTH_ALG_OPEN_SYSTEM == authType) {
4142 dwrq->flags |= IW_ENCODE_OPEN;
4143 } else {
4144 dwrq->flags |= IW_ENCODE_RESTRICTED;
4145 }
4146 EXIT();
4147 return 0;
4148
4149}
4150
4151/**
4152 * iw_get_encodeext() - SSR wrapper for __iw_get_encodeext()
4153 * @dev: pointer to net_device
4154 * @info: pointer to iw_request_info
4155 * @dwrq: pointer to encoding information
4156 * @extra: pointer to extra ioctl payload
4157 *
4158 * Return: 0 on success, error number otherwise
4159 */
4160static int iw_get_encodeext(struct net_device *dev,
4161 struct iw_request_info *info,
4162 struct iw_point *dwrq, char *extra)
4163{
4164 int ret;
4165
4166 cds_ssr_protect(__func__);
4167 ret = __iw_get_encodeext(dev, info, dwrq, extra);
4168 cds_ssr_unprotect(__func__);
4169
4170 return ret;
4171}
4172
4173/**
4174 * __iw_set_encodeext() - SIOCSIWENCODEEXT ioctl handler
4175 * @dev: device upon which the ioctl was received
4176 * @info: ioctl request information
4177 * @wrqu: ioctl request data
4178 * @extra: ioctl extra data
4179 *
4180 * Return: 0 on success, non-zero on error
4181 */
4182static int __iw_set_encodeext(struct net_device *dev,
4183 struct iw_request_info *info,
4184 union iwreq_data *wrqu, char *extra)
4185{
4186 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4187 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4188 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
4189 hdd_context_t *hdd_ctx;
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05304190 QDF_STATUS qdf_ret_status = QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004191 tCsrRoamProfile *pRoamProfile = &pWextState->roamProfile;
4192 int ret;
4193 struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
4194 int key_index;
4195 struct iw_point *encoding = &wrqu->encoding;
4196 tCsrRoamSetKey setKey;
4197 uint32_t roamId = 0xFF;
4198
Jeff Johnsonb25dcb12016-02-11 17:46:42 -08004199 ENTER_DEV(dev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004200
4201 hdd_ctx = WLAN_HDD_GET_CTX(pAdapter);
4202 ret = wlan_hdd_validate_context(hdd_ctx);
4203 if (0 != ret)
4204 return ret;
4205
4206 key_index = encoding->flags & IW_ENCODE_INDEX;
4207
4208 if (key_index > 0) {
4209
4210 /*Convert from 1-based to 0-based keying */
4211 key_index--;
4212 }
4213 if (!ext->key_len) {
4214
4215 /*Set the encrytion type to NONE */
4216 pRoamProfile->EncryptionType.encryptionType[0] =
4217 eCSR_ENCRYPT_TYPE_NONE;
4218 return ret;
4219 }
4220
4221 if (eConnectionState_NotConnected == pHddStaCtx->conn_info.connState &&
4222 (IW_ENCODE_ALG_WEP == ext->alg)) {
4223 if (IW_AUTH_KEY_MGMT_802_1X == pWextState->authKeyMgmt) {
4224
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05304225 QDF_TRACE(QDF_MODULE_ID_HDD, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004226 ("Invalid Configuration:%s"), __func__);
4227 return -EINVAL;
4228 } else {
4229 /*Static wep, update the roam profile with the keys */
4230 if (ext->key
4231 && (ext->key_len <=
4232 eCSR_SECURITY_WEP_KEYSIZE_MAX_BYTES)
4233 && key_index < CSR_MAX_NUM_KEY) {
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304234 qdf_mem_copy(&pRoamProfile->Keys.
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004235 KeyMaterial[key_index][0],
4236 ext->key, ext->key_len);
4237 pRoamProfile->Keys.KeyLength[key_index] =
4238 (uint8_t) ext->key_len;
4239
4240 if (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY)
4241 pRoamProfile->Keys.defaultIndex =
4242 (uint8_t) key_index;
4243
4244 }
4245 }
4246 return ret;
4247 }
4248
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304249 qdf_mem_zero(&setKey, sizeof(tCsrRoamSetKey));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004250
4251 setKey.keyId = key_index;
4252 setKey.keyLength = ext->key_len;
4253
4254 if (ext->key_len <= CSR_MAX_KEY_LEN) {
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304255 qdf_mem_copy(&setKey.Key[0], ext->key, ext->key_len);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004256 }
4257
4258 if (ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY) {
4259 /*Key direction for group is RX only */
4260 setKey.keyDirection = eSIR_RX_ONLY;
Anurag Chouhanc5548422016-02-24 18:33:27 +05304261 qdf_set_macaddr_broadcast(&setKey.peerMac);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004262 } else {
4263
4264 setKey.keyDirection = eSIR_TX_RX;
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304265 qdf_mem_copy(setKey.peerMac.bytes, ext->addr.sa_data,
Anurag Chouhan6d760662016-02-20 16:05:43 +05304266 QDF_MAC_ADDR_SIZE);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004267 }
4268
4269 /*For supplicant pae role is zero */
4270 setKey.paeRole = 0;
4271
4272 switch (ext->alg) {
4273 case IW_ENCODE_ALG_NONE:
4274 setKey.encType = eCSR_ENCRYPT_TYPE_NONE;
4275 break;
4276
4277 case IW_ENCODE_ALG_WEP:
4278 setKey.encType =
4279 (ext->key_len ==
4280 5) ? eCSR_ENCRYPT_TYPE_WEP40 : eCSR_ENCRYPT_TYPE_WEP104;
4281 break;
4282
4283 case IW_ENCODE_ALG_TKIP:
4284 {
4285 uint8_t *pKey = &setKey.Key[0];
4286
4287 setKey.encType = eCSR_ENCRYPT_TYPE_TKIP;
4288
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304289 qdf_mem_zero(pKey, CSR_MAX_KEY_LEN);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004290
4291 /* Supplicant sends the 32bytes key in this order
4292 * |--------------|----------|----------|
4293 * | Tk1 | TX MIC | RX MIC |
4294 * |--------------|----------|----------|
4295 * <---16bytes---><--8bytes--><--8bytes-->
4296 *
4297 *
4298 * Sme expects the 32 bytes key to be in the below order
4299 * |--------------|----------|----------|
4300 * | Tk1 | RX MIC | TX MIC |
4301 * |--------------|----------|----------|
4302 * <---16bytes---><--8bytes--><--8bytes-->
4303 */
4304
4305 /* Copy the Temporal Key 1 (TK1) */
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304306 qdf_mem_copy(pKey, ext->key, 16);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004307
4308 /* Copy the rx mic first */
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304309 qdf_mem_copy(&pKey[16], &ext->key[24], 8);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004310
4311 /* Copy the tx mic */
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304312 qdf_mem_copy(&pKey[24], &ext->key[16], 8);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004313
4314 }
4315 break;
4316
4317 case IW_ENCODE_ALG_CCMP:
4318 setKey.encType = eCSR_ENCRYPT_TYPE_AES;
4319 break;
4320
4321#ifdef FEATURE_WLAN_ESE
4322#define IW_ENCODE_ALG_KRK 6
4323 case IW_ENCODE_ALG_KRK:
4324 setKey.encType = eCSR_ENCRYPT_TYPE_KRK;
4325 break;
4326#endif /* FEATURE_WLAN_ESE */
4327
4328 default:
4329 setKey.encType = eCSR_ENCRYPT_TYPE_NONE;
4330 break;
4331 }
4332
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05304333 QDF_TRACE(QDF_MODULE_ID_HDD, QDF_TRACE_LEVEL_INFO,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004334 ("%s:cipher_alg:%d key_len[%d] *pEncryptionType :%d"),
4335 __func__, (int)ext->alg, (int)ext->key_len, setKey.encType);
4336
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004337 /* The supplicant may attempt to set the PTK once
4338 * pre-authentication is done. Save the key in the UMAC and
4339 * include it in the ADD BSS request
4340 */
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05304341 qdf_ret_status = sme_ft_update_key(WLAN_HDD_GET_HAL_CTX(pAdapter),
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004342 pAdapter->sessionId, &setKey);
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05304343 if (qdf_ret_status == QDF_STATUS_FT_PREAUTH_KEY_SUCCESS) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05304344 hddLog(QDF_TRACE_LEVEL_INFO_MED,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004345 "%s: Update PreAuth Key success", __func__);
4346 return 0;
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05304347 } else if (qdf_ret_status == QDF_STATUS_FT_PREAUTH_KEY_FAILED) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05304348 hddLog(QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004349 "%s: Update PreAuth Key failed", __func__);
4350 return -EINVAL;
4351 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004352
4353 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
4354
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05304355 qdf_ret_status = sme_roam_set_key(WLAN_HDD_GET_HAL_CTX(pAdapter),
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004356 pAdapter->sessionId,
4357 &setKey, &roamId);
4358
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05304359 if (qdf_ret_status != QDF_STATUS_SUCCESS) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05304360 QDF_TRACE(QDF_MODULE_ID_HDD, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004361 "[%4d] sme_roam_set_key returned ERROR status= %d",
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05304362 __LINE__, qdf_ret_status);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004363
4364 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
4365 }
4366
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05304367 return qdf_ret_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004368}
4369
4370/**
4371 * iw_set_encodeext() - SSR wrapper for __iw_set_encodeext()
4372 * @dev: pointer to net_device
4373 * @info: pointer to iw_request_info
4374 * @wrqu: pointer to iwreq_data
4375 * @extra: pointer to extra ioctl payload
4376 *
4377 * Return: 0 on success, error number otherwise
4378 */
4379static int iw_set_encodeext(struct net_device *dev,
4380 struct iw_request_info *info,
4381 union iwreq_data *wrqu, char *extra)
4382{
4383 int ret;
4384
4385 cds_ssr_protect(__func__);
4386 ret = __iw_set_encodeext(dev, info, wrqu, extra);
4387 cds_ssr_unprotect(__func__);
4388
4389 return ret;
4390}
4391
4392/**
4393 * __iw_set_retry() - SIOCSIWRETRY ioctl handler
4394 * @dev: device upon which the ioctl was received
4395 * @info: ioctl request information
4396 * @wrqu: ioctl request data
4397 * @extra: ioctl extra data
4398 *
4399 * Return: 0 on success, non-zero on error
4400 */
4401static int __iw_set_retry(struct net_device *dev, struct iw_request_info *info,
4402 union iwreq_data *wrqu, char *extra)
4403{
4404 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4405 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
4406 hdd_context_t *hdd_ctx;
4407 int ret;
4408
Jeff Johnsonb25dcb12016-02-11 17:46:42 -08004409 ENTER_DEV(dev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004410
4411 hdd_ctx = WLAN_HDD_GET_CTX(pAdapter);
4412 ret = wlan_hdd_validate_context(hdd_ctx);
4413 if (0 != ret)
4414 return ret;
4415
4416 if (wrqu->retry.value < WNI_CFG_LONG_RETRY_LIMIT_STAMIN ||
4417 wrqu->retry.value > WNI_CFG_LONG_RETRY_LIMIT_STAMAX) {
4418
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05304419 QDF_TRACE(QDF_MODULE_ID_HDD, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004420 ("Invalid Retry-Limit=%d!!"), wrqu->retry.value);
4421
4422 return -EINVAL;
4423 }
4424
4425 if (wrqu->retry.flags & IW_RETRY_LIMIT) {
4426
4427 if ((wrqu->retry.flags & IW_RETRY_LONG)) {
4428 if (sme_cfg_set_int (hHal, WNI_CFG_LONG_RETRY_LIMIT,
4429 wrqu->retry.value) !=
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304430 QDF_STATUS_SUCCESS) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05304431 QDF_TRACE(QDF_MODULE_ID_HDD,
4432 QDF_TRACE_LEVEL_ERROR, FL
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004433 ("failed to set ini parameter, WNI_CFG_LONG_RETRY_LIMIT"));
4434 return -EIO;
4435 }
4436 } else if ((wrqu->retry.flags & IW_RETRY_SHORT)) {
4437 if (sme_cfg_set_int (hHal, WNI_CFG_SHORT_RETRY_LIMIT,
4438 wrqu->retry.value) !=
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304439 QDF_STATUS_SUCCESS) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05304440 QDF_TRACE(QDF_MODULE_ID_HDD,
4441 QDF_TRACE_LEVEL_ERROR, FL
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004442 ("failed to set ini parameter, WNI_CFG_LONG_RETRY_LIMIT"));
4443 return -EIO;
4444 }
4445 }
4446 } else {
4447 return -EOPNOTSUPP;
4448 }
4449
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05304450 QDF_TRACE(QDF_MODULE_ID_HDD, QDF_TRACE_LEVEL_INFO,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004451 ("Set Retry-Limit=%d!!"), wrqu->retry.value);
4452
4453 EXIT();
4454
4455 return 0;
4456
4457}
4458
4459/**
4460 * iw_set_retry() - SSR wrapper for __iw_set_retry()
4461 * @dev: pointer to net_device
4462 * @info: pointer to iw_request_info
4463 * @wrqu: pointer to iwreq_data
4464 * @extra: pointer to extra ioctl payload
4465 *
4466 * Return: 0 on success, error number otherwise
4467 */
4468static int iw_set_retry(struct net_device *dev, struct iw_request_info *info,
4469 union iwreq_data *wrqu, char *extra)
4470{
4471 int ret;
4472
4473 cds_ssr_protect(__func__);
4474 ret = __iw_set_retry(dev, info, wrqu, extra);
4475 cds_ssr_unprotect(__func__);
4476
4477 return ret;
4478}
4479
4480/**
4481 * __iw_get_retry() - SIOCGIWRETRY ioctl handler
4482 * @dev: device upon which the ioctl was received
4483 * @info: ioctl request information
4484 * @wrqu: ioctl request data
4485 * @extra: ioctl extra data
4486 *
4487 * Return: 0 on success, non-zero on error
4488 */
4489static int __iw_get_retry(struct net_device *dev, struct iw_request_info *info,
4490 union iwreq_data *wrqu, char *extra)
4491{
4492 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4493 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
4494 uint32_t retry = 0;
4495 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 if ((wrqu->retry.flags & IW_RETRY_LONG)) {
4506 wrqu->retry.flags = IW_RETRY_LIMIT | IW_RETRY_LONG;
4507
4508 if (sme_cfg_get_int(hHal, WNI_CFG_LONG_RETRY_LIMIT, &retry) !=
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304509 QDF_STATUS_SUCCESS) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05304510 QDF_TRACE(QDF_MODULE_ID_HDD, QDF_TRACE_LEVEL_WARN,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004511 FL
4512 ("failed to get ini parameter, WNI_CFG_LONG_RETRY_LIMIT"));
4513 return -EIO;
4514 }
4515
4516 wrqu->retry.value = retry;
4517 } else if ((wrqu->retry.flags & IW_RETRY_SHORT)) {
4518 wrqu->retry.flags = IW_RETRY_LIMIT | IW_RETRY_SHORT;
4519
4520 if (sme_cfg_get_int(hHal, WNI_CFG_SHORT_RETRY_LIMIT, &retry) !=
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304521 QDF_STATUS_SUCCESS) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05304522 QDF_TRACE(QDF_MODULE_ID_HDD, QDF_TRACE_LEVEL_WARN,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004523 FL
4524 ("failed to get ini parameter, WNI_CFG_LONG_RETRY_LIMIT"));
4525 return -EIO;
4526 }
4527
4528 wrqu->retry.value = retry;
4529 } else {
4530 return -EOPNOTSUPP;
4531 }
4532
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05304533 QDF_TRACE(QDF_MODULE_ID_HDD, QDF_TRACE_LEVEL_INFO, ("Retry-Limit=%d!!"),
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004534 retry);
4535
4536 EXIT();
4537
4538 return 0;
4539}
4540
4541/**
4542 * iw_get_retry() - SSR wrapper for __iw_get_retry()
4543 * @dev: pointer to net_device
4544 * @info: pointer to iw_request_info
4545 * @wrqu: pointer to iwreq_data
4546 * @extra: pointer to extra ioctl payload
4547 *
4548 * Return: 0 on success, error number otherwise
4549 */
4550static int iw_get_retry(struct net_device *dev, struct iw_request_info *info,
4551 union iwreq_data *wrqu, char *extra)
4552{
4553 int ret;
4554
4555 cds_ssr_protect(__func__);
4556 ret = __iw_get_retry(dev, info, wrqu, extra);
4557 cds_ssr_unprotect(__func__);
4558
4559 return ret;
4560}
4561
4562/**
4563 * __iw_set_mlme() - SIOCSIWMLME ioctl handler
4564 * @dev: device upon which the ioctl was received
4565 * @info: ioctl request information
4566 * @wrqu: ioctl request data
4567 * @extra: ioctl extra data
4568 *
4569 * Return: 0 on success, non-zero on error
4570 */
4571static int __iw_set_mlme(struct net_device *dev,
4572 struct iw_request_info *info,
4573 union iwreq_data *wrqu, char *extra)
4574{
4575 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4576 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4577 struct iw_mlme *mlme = (struct iw_mlme *)extra;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304578 QDF_STATUS status = QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004579 hdd_context_t *hdd_ctx;
4580 int ret;
4581
Jeff Johnsonb25dcb12016-02-11 17:46:42 -08004582 ENTER_DEV(dev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004583
4584 hdd_ctx = WLAN_HDD_GET_CTX(pAdapter);
4585 ret = wlan_hdd_validate_context(hdd_ctx);
4586 if (0 != ret)
4587 return ret;
4588
4589 /* reason_code is unused. By default it is set to
4590 * eCSR_DISCONNECT_REASON_UNSPECIFIED
4591 */
4592 switch (mlme->cmd) {
4593 case IW_MLME_DISASSOC:
4594 case IW_MLME_DEAUTH:
4595
4596 if (pHddStaCtx->conn_info.connState ==
4597 eConnectionState_Associated) {
4598 eCsrRoamDisconnectReason reason =
4599 eCSR_DISCONNECT_REASON_UNSPECIFIED;
4600
4601 if (mlme->reason_code == HDD_REASON_MICHAEL_MIC_FAILURE)
4602 reason = eCSR_DISCONNECT_REASON_MIC_ERROR;
4603
4604 INIT_COMPLETION(pAdapter->disconnect_comp_var);
4605 status =
4606 sme_roam_disconnect(WLAN_HDD_GET_HAL_CTX(pAdapter),
4607 pAdapter->sessionId, reason);
4608
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304609 if (QDF_STATUS_SUCCESS == status) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004610 unsigned long rc;
4611 rc = wait_for_completion_timeout(&pAdapter->
4612 disconnect_comp_var,
4613 msecs_to_jiffies
4614 (WLAN_WAIT_TIME_DISCONNECT));
4615 if (!rc)
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05304616 hddLog(QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004617 FL
4618 ("failed wait on disconnect_comp_var"));
4619 } else
4620 hddLog(LOGE,
4621 "%s %d Command Disassociate/Deauthenticate : csr_roam_disconnect failure returned %d",
4622 __func__, (int)mlme->cmd, (int)status);
4623
4624 /* Resetting authKeyMgmt */
4625 (WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter))->authKeyMgmt =
4626 0;
4627
4628 hddLog(LOG1, FL("Disabling queues"));
4629 wlan_hdd_netif_queue_control(pAdapter,
4630 WLAN_NETIF_TX_DISABLE_N_CARRIER,
4631 WLAN_CONTROL_PATH);
4632
4633 } else {
4634 hddLog(LOGE,
4635 "%s %d Command Disassociate/Deauthenticate called but station is not in associated state",
4636 __func__, (int)mlme->cmd);
4637 }
4638 break;
4639 default:
4640 hddLog(LOGE,
4641 "%s %d Command should be Disassociate/Deauthenticate",
4642 __func__, (int)mlme->cmd);
4643 return -EINVAL;
4644 } /* end of switch */
4645
4646 EXIT();
4647
4648 return status;
4649
4650}
4651
4652/**
4653 * iw_set_mlme() - SSR wrapper for __iw_set_mlme()
4654 * @dev: pointer to net_device
4655 * @info: pointer to iw_request_info
4656 * @wrqu: pointer to iwreq_data
4657 * @extra: pointer to extra ioctl payload
4658 *
4659 * Return: 0 on success, error number otherwise
4660 */
4661static int iw_set_mlme(struct net_device *dev, struct iw_request_info *info,
4662 union iwreq_data *wrqu, char *extra)
4663{
4664 int ret;
4665
4666 cds_ssr_protect(__func__);
4667 ret = __iw_set_mlme(dev, info, wrqu, extra);
4668 cds_ssr_unprotect(__func__);
4669
4670 return ret;
4671}
4672
4673/**
4674 * wlan_hdd_update_phymode() - handle change in PHY mode
4675 * @net: device upon which PHY mode change was received
4676 * @hal: umac handle for the driver
4677 * @new_phymode: new PHY mode for the device
4678 * @phddctx: pointer to the HDD context
4679 *
4680 * This function is called when the device is set to a new PHY mode.
4681 * It takes a holistic look at the desired PHY mode along with the
4682 * configured capabilities of the driver and the reported capabilities
4683 * of the hardware in order to correctly configure all PHY-related
4684 * parameters.
4685 *
4686 * Return: 0 on success, negative errno value on error
4687 */
4688int wlan_hdd_update_phymode(struct net_device *net, tHalHandle hal,
4689 int new_phymode, hdd_context_t *phddctx)
4690{
4691#ifdef QCA_HT_2040_COEX
4692 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(net);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304693 QDF_STATUS halStatus = QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004694#endif
4695 bool band_24 = false, band_5g = false;
4696 bool ch_bond24 = false, ch_bond5g = false;
4697 tSmeConfigParams smeconfig;
4698 uint32_t chwidth = WNI_CFG_CHANNEL_BONDING_MODE_DISABLE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004699 uint32_t vhtchanwidth;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004700 eCsrPhyMode phymode = -EIO, old_phymode;
4701 eHddDot11Mode hdd_dot11mode = phddctx->config->dot11Mode;
4702 eCsrBand curr_band = eCSR_BAND_ALL;
4703
4704 old_phymode = sme_get_phy_mode(hal);
4705
4706 if (WNI_CFG_CHANNEL_BONDING_MODE_DISABLE !=
4707 sme_get_cb_phy_state_from_cb_ini_value(phddctx->config->
4708 nChannelBondingMode24GHz))
4709 ch_bond24 = true;
4710
4711 if (WNI_CFG_CHANNEL_BONDING_MODE_DISABLE !=
4712 sme_get_cb_phy_state_from_cb_ini_value(phddctx->config->
4713 nChannelBondingMode5GHz))
4714 ch_bond5g = true;
4715
4716 if (phddctx->config->nBandCapability == eCSR_BAND_ALL) {
4717 band_24 = band_5g = true;
4718 } else if (phddctx->config->nBandCapability == eCSR_BAND_24) {
4719 band_24 = true;
4720 } else if (phddctx->config->nBandCapability == eCSR_BAND_5G) {
4721 band_5g = true;
4722 }
4723
4724 vhtchanwidth = phddctx->config->vhtChannelWidth;
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05304725 QDF_TRACE(QDF_MODULE_ID_HDD, QDF_TRACE_LEVEL_WARN, ("ch_bond24=%d "
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004726 "ch_bond5g=%d band_24=%d band_5g=%d VHT_ch_width=%u"),
4727 ch_bond24, ch_bond5g, band_24, band_5g, vhtchanwidth);
4728
4729 switch (new_phymode) {
4730 case IEEE80211_MODE_AUTO:
4731 sme_set_phy_mode(hal, eCSR_DOT11_MODE_AUTO);
4732 if (hdd_set_band(net, WLAN_HDD_UI_BAND_AUTO) == 0) {
4733 phymode = eCSR_DOT11_MODE_AUTO;
4734 hdd_dot11mode = eHDD_DOT11_MODE_AUTO;
4735 chwidth = WNI_CFG_CHANNEL_BONDING_MODE_ENABLE;
4736 curr_band = eCSR_BAND_ALL;
4737 vhtchanwidth = eHT_CHANNEL_WIDTH_80MHZ;
4738 } else {
4739 sme_set_phy_mode(hal, old_phymode);
4740 return -EIO;
4741 }
4742 break;
4743 case IEEE80211_MODE_11A:
4744 sme_set_phy_mode(hal, eCSR_DOT11_MODE_11a);
4745 if ((hdd_set_band(net, WLAN_HDD_UI_BAND_5_GHZ) == 0)) {
4746 phymode = eCSR_DOT11_MODE_11a;
4747 hdd_dot11mode = eHDD_DOT11_MODE_11a;
4748 chwidth = WNI_CFG_CHANNEL_BONDING_MODE_DISABLE;
4749 curr_band = eCSR_BAND_5G;
4750 } else {
4751 sme_set_phy_mode(hal, old_phymode);
4752 return -EIO;
4753 }
4754 break;
4755 case IEEE80211_MODE_11B:
4756 sme_set_phy_mode(hal, eCSR_DOT11_MODE_11b);
4757 if ((hdd_set_band(net, WLAN_HDD_UI_BAND_2_4_GHZ) == 0)) {
4758 phymode = eCSR_DOT11_MODE_11b;
4759 hdd_dot11mode = eHDD_DOT11_MODE_11b;
4760 chwidth = WNI_CFG_CHANNEL_BONDING_MODE_DISABLE;
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_11G:
4768 sme_set_phy_mode(hal, eCSR_DOT11_MODE_11g);
4769 if ((hdd_set_band(net, WLAN_HDD_UI_BAND_2_4_GHZ) == 0)) {
4770 phymode = eCSR_DOT11_MODE_11g;
4771 hdd_dot11mode = eHDD_DOT11_MODE_11g;
4772 chwidth = WNI_CFG_CHANNEL_BONDING_MODE_DISABLE;
4773 curr_band = eCSR_BAND_24;
4774 } else {
4775 sme_set_phy_mode(hal, old_phymode);
4776 return -EIO;
4777 }
4778 break;
4779 /* UMAC doesnt have option to set MODE_11NA/MODE_11NG as phymode
4780 * so setting phymode as eCSR_DOT11_MODE_11n and updating the band
4781 * and channel bonding in configuration to reflect MODE_11NA/MODE_11NG
4782 */
4783 case IEEE80211_MODE_11NA_HT20:
4784 sme_set_phy_mode(hal, eCSR_DOT11_MODE_11n);
4785 if ((hdd_set_band(net, WLAN_HDD_UI_BAND_5_GHZ) == 0)) {
4786 phymode = eCSR_DOT11_MODE_11n;
4787 hdd_dot11mode = eHDD_DOT11_MODE_11n;
4788 chwidth = WNI_CFG_CHANNEL_BONDING_MODE_DISABLE;
4789 curr_band = eCSR_BAND_5G;
4790 } else {
4791 sme_set_phy_mode(hal, old_phymode);
4792 return -EIO;
4793 }
4794 break;
4795 case IEEE80211_MODE_11NA_HT40:
4796 sme_set_phy_mode(hal, eCSR_DOT11_MODE_11n);
4797 if ((hdd_set_band(net, WLAN_HDD_UI_BAND_5_GHZ) == 0)) {
4798 phymode = eCSR_DOT11_MODE_11n;
4799 hdd_dot11mode = eHDD_DOT11_MODE_11n;
4800 chwidth = WNI_CFG_CHANNEL_BONDING_MODE_ENABLE;
4801 curr_band = eCSR_BAND_5G;
4802 } else {
4803 sme_set_phy_mode(hal, old_phymode);
4804 return -EIO;
4805 }
4806 break;
4807 case IEEE80211_MODE_11NG_HT20:
4808 sme_set_phy_mode(hal, eCSR_DOT11_MODE_11n);
4809 if ((hdd_set_band(net, WLAN_HDD_UI_BAND_2_4_GHZ) == 0)) {
4810 phymode = eCSR_DOT11_MODE_11n;
4811 hdd_dot11mode = eHDD_DOT11_MODE_11n;
4812 chwidth = WNI_CFG_CHANNEL_BONDING_MODE_DISABLE;
4813 curr_band = eCSR_BAND_24;
4814 } else {
4815 sme_set_phy_mode(hal, old_phymode);
4816 return -EIO;
4817 }
4818 break;
4819 case IEEE80211_MODE_11NG_HT40:
4820 sme_set_phy_mode(hal, eCSR_DOT11_MODE_11n);
4821 if ((hdd_set_band(net, WLAN_HDD_UI_BAND_2_4_GHZ) == 0)) {
4822 phymode = eCSR_DOT11_MODE_11n;
4823 hdd_dot11mode = eHDD_DOT11_MODE_11n;
4824 chwidth = WNI_CFG_CHANNEL_BONDING_MODE_ENABLE;
4825 curr_band = eCSR_BAND_24;
4826 } else {
4827 sme_set_phy_mode(hal, old_phymode);
4828 return -EIO;
4829 }
4830 break;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004831 case IEEE80211_MODE_11AC_VHT20:
4832 case IEEE80211_MODE_11AC_VHT40:
4833 case IEEE80211_MODE_11AC_VHT80:
4834 sme_set_phy_mode(hal, eCSR_DOT11_MODE_11ac);
4835 if ((hdd_set_band(net, WLAN_HDD_UI_BAND_5_GHZ) == 0)) {
4836 phymode = eCSR_DOT11_MODE_11ac;
4837 hdd_dot11mode = eHDD_DOT11_MODE_11ac;
4838 chwidth = WNI_CFG_CHANNEL_BONDING_MODE_ENABLE;
4839 curr_band = eCSR_BAND_5G;
4840 } else {
4841 sme_set_phy_mode(hal, old_phymode);
4842 return -EIO;
4843 }
4844 break;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004845 case IEEE80211_MODE_2G_AUTO:
4846 sme_set_phy_mode(hal, eCSR_DOT11_MODE_AUTO);
4847 if ((hdd_set_band(net, WLAN_HDD_UI_BAND_2_4_GHZ) == 0)) {
4848 phymode = eCSR_DOT11_MODE_AUTO;
4849 hdd_dot11mode = eHDD_DOT11_MODE_AUTO;
4850 chwidth = WNI_CFG_CHANNEL_BONDING_MODE_ENABLE;
4851 curr_band = eCSR_BAND_24;
4852 } else {
4853 sme_set_phy_mode(hal, old_phymode);
4854 return -EIO;
4855 }
4856 break;
4857 case IEEE80211_MODE_5G_AUTO:
4858 sme_set_phy_mode(hal, eCSR_DOT11_MODE_AUTO);
4859 if ((hdd_set_band(net, WLAN_HDD_UI_BAND_5_GHZ) == 0)) {
4860 phymode = eCSR_DOT11_MODE_AUTO;
4861 hdd_dot11mode = eHDD_DOT11_MODE_AUTO;
4862 chwidth = WNI_CFG_CHANNEL_BONDING_MODE_ENABLE;
4863 vhtchanwidth = eHT_CHANNEL_WIDTH_80MHZ;
4864 curr_band = eCSR_BAND_5G;
4865 } else {
4866 sme_set_phy_mode(hal, old_phymode);
4867 return -EIO;
4868 }
4869 break;
4870 case IEEE80211_MODE_11AGN:
4871 sme_set_phy_mode(hal, eCSR_DOT11_MODE_11n);
4872 if ((hdd_set_band(net, WLAN_HDD_UI_BAND_AUTO) == 0)) {
4873 phymode = eCSR_DOT11_MODE_11n;
4874 hdd_dot11mode = eHDD_DOT11_MODE_11n;
4875 chwidth = WNI_CFG_CHANNEL_BONDING_MODE_ENABLE;
4876 curr_band = eCSR_BAND_ALL;
4877 } else {
4878 sme_set_phy_mode(hal, old_phymode);
4879 return -EIO;
4880 }
4881 break;
4882 default:
4883 return -EIO;
4884 }
4885
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004886 switch (new_phymode) {
4887 case IEEE80211_MODE_11AC_VHT20:
4888 chwidth = WNI_CFG_CHANNEL_BONDING_MODE_DISABLE;
4889 vhtchanwidth = eHT_CHANNEL_WIDTH_20MHZ;
4890 break;
4891 case IEEE80211_MODE_11AC_VHT40:
4892 vhtchanwidth = eHT_CHANNEL_WIDTH_40MHZ;
4893 break;
4894 case IEEE80211_MODE_11AC_VHT80:
4895 vhtchanwidth = eHT_CHANNEL_WIDTH_80MHZ;
4896 break;
4897 default:
4898 vhtchanwidth = phddctx->config->vhtChannelWidth;
4899 break;
4900 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004901
4902 if (phymode != -EIO) {
4903 sme_get_config_param(hal, &smeconfig);
4904 smeconfig.csrConfig.phyMode = phymode;
4905#ifdef QCA_HT_2040_COEX
4906 if (phymode == eCSR_DOT11_MODE_11n &&
4907 chwidth == WNI_CFG_CHANNEL_BONDING_MODE_DISABLE) {
4908 smeconfig.csrConfig.obssEnabled = false;
4909 halStatus = sme_set_ht2040_mode(hal,
4910 pAdapter->sessionId,
4911 eHT_CHAN_HT20, false);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304912 if (halStatus == QDF_STATUS_E_FAILURE) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004913 hddLog(LOGE, FL("Failed to disable OBSS"));
4914 return -EIO;
4915 }
4916 } else if (phymode == eCSR_DOT11_MODE_11n &&
4917 chwidth == WNI_CFG_CHANNEL_BONDING_MODE_ENABLE) {
4918 smeconfig.csrConfig.obssEnabled = true;
4919 halStatus = sme_set_ht2040_mode(hal,
4920 pAdapter->sessionId,
4921 eHT_CHAN_HT20, true);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304922 if (halStatus == QDF_STATUS_E_FAILURE) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004923 hddLog(LOGE, FL("Failed to enable OBSS"));
4924 return -EIO;
4925 }
4926 }
4927#endif
4928 smeconfig.csrConfig.eBand = curr_band;
4929 smeconfig.csrConfig.bandCapability = curr_band;
4930 if (curr_band == eCSR_BAND_24)
4931 smeconfig.csrConfig.Is11hSupportEnabled = 0;
4932 else
4933 smeconfig.csrConfig.Is11hSupportEnabled =
4934 phddctx->config->Is11hSupportEnabled;
4935 if (curr_band == eCSR_BAND_24)
4936 smeconfig.csrConfig.channelBondingMode24GHz = chwidth;
4937 else if (curr_band == eCSR_BAND_24)
4938 smeconfig.csrConfig.channelBondingMode5GHz = chwidth;
4939 else {
4940 smeconfig.csrConfig.channelBondingMode24GHz = chwidth;
4941 smeconfig.csrConfig.channelBondingMode5GHz = chwidth;
4942 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004943 smeconfig.csrConfig.nVhtChannelWidth = vhtchanwidth;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004944 sme_update_config(hal, &smeconfig);
4945
4946 phddctx->config->dot11Mode = hdd_dot11mode;
4947 phddctx->config->nBandCapability = curr_band;
4948 phddctx->config->nChannelBondingMode24GHz =
4949 smeconfig.csrConfig.channelBondingMode24GHz;
4950 phddctx->config->nChannelBondingMode5GHz =
4951 smeconfig.csrConfig.channelBondingMode5GHz;
4952 phddctx->config->vhtChannelWidth = vhtchanwidth;
4953 if (hdd_update_config_dat(phddctx) == false) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05304954 QDF_TRACE(QDF_MODULE_ID_HDD, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004955 "%s: could not update config_dat", __func__);
4956 return -EIO;
4957 }
4958 if (phddctx->config->nChannelBondingMode5GHz)
4959 phddctx->wiphy->bands[IEEE80211_BAND_5GHZ]->ht_cap.cap
4960 |= IEEE80211_HT_CAP_SUP_WIDTH_20_40;
4961 else
4962 phddctx->wiphy->bands[IEEE80211_BAND_5GHZ]->ht_cap.cap
4963 &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40;
4964
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05304965 QDF_TRACE(QDF_MODULE_ID_HDD, QDF_TRACE_LEVEL_WARN,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004966 "New_Phymode= %d ch_bonding=%d band=%d VHT_ch_width=%u",
4967 phymode, chwidth, curr_band, vhtchanwidth);
4968 }
4969
4970 return 0;
4971}
4972
4973/**
4974 * hdd_get_temperature_cb() - "Get Temperature" callback function
4975 * @temperature: measured temperature
4976 * @pContext: callback context
4977 *
4978 * This function is passed to sme_get_temperature() as the callback
4979 * function to be invoked when the temperature measurement is
4980 * available.
4981 *
4982 * Return: None
4983 */
4984static void hdd_get_temperature_cb(int temperature, void *pContext)
4985{
4986 struct statsContext *pTempContext;
4987 hdd_adapter_t *pAdapter;
4988 ENTER();
4989 if (NULL == pContext) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05304990 hddLog(QDF_TRACE_LEVEL_ERROR, FL("pContext is NULL"));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004991 return;
4992 }
4993 pTempContext = pContext;
4994 pAdapter = pTempContext->pAdapter;
4995 spin_lock(&hdd_context_lock);
4996 if ((NULL == pAdapter) || (TEMP_CONTEXT_MAGIC != pTempContext->magic)) {
4997 spin_unlock(&hdd_context_lock);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05304998 hddLog(QDF_TRACE_LEVEL_WARN,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004999 FL("Invalid context, pAdapter [%p] magic [%08x]"),
5000 pAdapter, pTempContext->magic);
5001 return;
5002 }
5003 if (temperature != 0) {
5004 pAdapter->temperature = temperature;
5005 }
5006 complete(&pTempContext->completion);
5007 spin_unlock(&hdd_context_lock);
5008 EXIT();
5009}
5010
5011/**
5012 * wlan_hdd_get_temperature() - get current device temperature
5013 * @pAdapter: device upon which the request was made
5014 * @temperature: pointer to where the temperature is to be returned
5015 *
5016 * Return: 0 if a temperature value (either current or cached) was
5017 * returned, otherwise a negative errno is returned.
5018 *
5019 */
5020int wlan_hdd_get_temperature(hdd_adapter_t *pAdapter, int *temperature)
5021{
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05305022 QDF_STATUS status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005023 struct statsContext tempContext;
5024 unsigned long rc;
5025
5026 ENTER();
5027 if (NULL == pAdapter) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05305028 hddLog(QDF_TRACE_LEVEL_ERROR, FL("pAdapter is NULL"));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005029 return -EPERM;
5030 }
5031 init_completion(&tempContext.completion);
5032 tempContext.pAdapter = pAdapter;
5033 tempContext.magic = TEMP_CONTEXT_MAGIC;
5034 status = sme_get_temperature(WLAN_HDD_GET_HAL_CTX(pAdapter),
5035 &tempContext, hdd_get_temperature_cb);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05305036 if (QDF_STATUS_SUCCESS != status) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05305037 hddLog(QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005038 FL("Unable to retrieve temperature"));
5039 } else {
5040 rc = wait_for_completion_timeout(&tempContext.completion,
5041 msecs_to_jiffies
5042 (WLAN_WAIT_TIME_STATS));
5043 if (!rc) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05305044 hddLog(QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005045 FL
5046 ("SME timed out while retrieving temperature"));
5047 }
5048 }
5049 spin_lock(&hdd_context_lock);
5050 tempContext.magic = 0;
5051 spin_unlock(&hdd_context_lock);
5052 *temperature = pAdapter->temperature;
5053 EXIT();
5054 return 0;
5055}
5056
5057/**
5058 * iw_setint_getnone() - Generic "set integer" private ioctl handler
5059 * @dev: device upon which the ioctl was received
5060 * @info: ioctl request information
5061 * @wrqu: ioctl request data
5062 * @extra: ioctl extra data
5063 *
5064 * Return: 0 on success, non-zero on error
5065 */
5066static int __iw_setint_getnone(struct net_device *dev,
5067 struct iw_request_info *info,
5068 union iwreq_data *wrqu, char *extra)
5069{
5070 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5071 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
5072 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
5073 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
5074 hdd_context_t *hdd_ctx;
5075 tSmeConfigParams smeConfig;
5076 int *value = (int *)extra;
5077 int sub_cmd = value[0];
5078 int set_value = value[1];
5079 int ret;
5080 int enable_pbm, enable_mp;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05305081 QDF_STATUS status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005082
Jeff Johnson6ee91ee2016-02-11 18:55:30 -08005083 ENTER_DEV(dev);
Hanumantha Reddy Pothula2db50ed2015-11-23 10:48:33 +05305084
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005085 INIT_COMPLETION(pWextState->completion_var);
Mukul Sharma81661ae2015-10-30 20:26:02 +05305086 memset(&smeConfig, 0x00, sizeof(smeConfig));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005087
5088 hdd_ctx = WLAN_HDD_GET_CTX(pAdapter);
5089 ret = wlan_hdd_validate_context(hdd_ctx);
5090 if (0 != ret)
5091 return ret;
5092
5093 switch (sub_cmd) {
5094 case WE_SET_11D_STATE:
5095 {
5096 if ((ENABLE_11D == set_value)
5097 || (DISABLE_11D == set_value)) {
5098
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005099 sme_get_config_param(hHal, &smeConfig);
5100 smeConfig.csrConfig.Is11dSupportEnabled =
5101 (bool) set_value;
5102
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05305103 QDF_TRACE(QDF_MODULE_ID_HDD,
5104 QDF_TRACE_LEVEL_INFO,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005105 ("11D state=%d!!"),
5106 smeConfig.csrConfig.
5107 Is11dSupportEnabled);
5108
5109 sme_update_config(hHal, &smeConfig);
5110 } else {
5111 return -EINVAL;
5112 }
5113 break;
5114 }
5115
5116 case WE_WOWL:
5117 {
5118 switch (set_value) {
5119 case 0x00:
5120 hdd_exit_wowl(pAdapter);
5121 break;
5122 case 0x01:
5123 case 0x02:
5124 case 0x03:
5125 enable_mp = (set_value & 0x01) ? 1 : 0;
5126 enable_pbm = (set_value & 0x02) ? 1 : 0;
5127 hddLog(LOGE,
5128 "magic packet ? = %s pattern byte matching ? = %s",
5129 (enable_mp ? "YES" : "NO"),
5130 (enable_pbm ? "YES" : "NO"));
5131 hdd_enter_wowl(pAdapter, enable_mp, enable_pbm);
5132 break;
5133 default:
5134 hddLog(LOGE, "Invalid arg %d in WE_WOWL IOCTL",
5135 set_value);
5136 ret = -EINVAL;
5137 break;
5138 }
5139
5140 break;
5141 }
5142 case WE_SET_POWER:
5143 {
5144 switch (set_value) {
5145 case 1:
5146 /* Enable PowerSave */
5147 sme_ps_enable_disable(hHal, pAdapter->sessionId,
5148 SME_PS_ENABLE);
5149 break;
5150 case 2:
5151 /* Disable PowerSave */
5152 sme_ps_enable_disable(hHal, pAdapter->sessionId,
5153 SME_PS_DISABLE);
5154 break;
5155 case 3: /* Enable UASPD */
5156 sme_ps_uapsd_enable(hHal, pAdapter->sessionId);
5157 break;
5158 case 4: /* Disable UASPD */
5159 sme_ps_uapsd_disable(hHal, pAdapter->sessionId);
5160 break;
5161 default:
5162 hddLog(LOGE,
5163 "Invalid arg %d in WE_SET_POWER IOCTL",
5164 set_value);
5165 ret = -EINVAL;
5166 break;
5167 }
5168 break;
5169 }
5170
5171 case WE_SET_MAX_ASSOC:
5172 {
5173 if ((WNI_CFG_ASSOC_STA_LIMIT_STAMIN > set_value) ||
5174 (WNI_CFG_ASSOC_STA_LIMIT_STAMAX < set_value)) {
5175 ret = -EINVAL;
5176 } else if (sme_cfg_set_int(hHal, WNI_CFG_ASSOC_STA_LIMIT,
5177 set_value)
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05305178 != QDF_STATUS_SUCCESS) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05305179 QDF_TRACE(QDF_MODULE_ID_HDD,
5180 QDF_TRACE_LEVEL_ERROR, FL
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005181 ("failed to set ini parameter, WNI_CFG_ASSOC_STA_LIMIT"));
5182 ret = -EIO;
5183 }
5184 break;
5185 }
5186
5187 case WE_SET_SAP_AUTO_CHANNEL_SELECTION:
5188 if (set_value == 0 || set_value == 1)
5189 (WLAN_HDD_GET_CTX(pAdapter))->config->force_sap_acs =
5190 set_value;
5191 else
5192 ret = -EINVAL;
5193 break;
5194
5195 case WE_SET_DATA_INACTIVITY_TO:
5196 {
5197 if ((set_value < CFG_DATA_INACTIVITY_TIMEOUT_MIN) ||
5198 (set_value > CFG_DATA_INACTIVITY_TIMEOUT_MAX) ||
5199 (sme_cfg_set_int((WLAN_HDD_GET_CTX(pAdapter))->hHal,
5200 WNI_CFG_PS_DATA_INACTIVITY_TIMEOUT,
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05305201 set_value) == QDF_STATUS_E_FAILURE)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005202 hddLog(LOGE, "Failure: Could not pass on "
5203 "WNI_CFG_PS_DATA_INACTIVITY_TIMEOUT configuration info "
5204 "to CCM");
5205 ret = -EINVAL;
5206 }
5207 break;
5208 }
5209 case WE_SET_MC_RATE:
5210 {
5211 ret = wlan_hdd_set_mc_rate(pAdapter, set_value);
5212 break;
5213 }
5214 case WE_SET_TX_POWER:
5215 {
Anurag Chouhan6d760662016-02-20 16:05:43 +05305216 struct qdf_mac_addr bssid;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005217
Anurag Chouhanc5548422016-02-24 18:33:27 +05305218 qdf_copy_macaddr(&bssid, &pHddStaCtx->conn_info.bssId);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005219 if (sme_set_tx_power
5220 (hHal, pAdapter->sessionId, bssid,
5221 pAdapter->device_mode,
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05305222 set_value) != QDF_STATUS_SUCCESS) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05305223 hddLog(QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005224 "%s: Setting tx power failed", __func__);
5225 return -EIO;
5226 }
5227 break;
5228 }
5229 case WE_SET_MAX_TX_POWER:
5230 {
Anurag Chouhan6d760662016-02-20 16:05:43 +05305231 struct qdf_mac_addr bssid;
5232 struct qdf_mac_addr selfMac;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005233
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05305234 hddLog(QDF_TRACE_LEVEL_INFO,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005235 "%s: Setting maximum tx power %d dBm", __func__,
5236 set_value);
Anurag Chouhanc5548422016-02-24 18:33:27 +05305237 qdf_copy_macaddr(&bssid, &pHddStaCtx->conn_info.bssId);
5238 qdf_copy_macaddr(&selfMac, &pHddStaCtx->conn_info.bssId);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005239
5240 if (sme_set_max_tx_power(hHal, bssid, selfMac, set_value)
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05305241 != QDF_STATUS_SUCCESS) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05305242 hddLog(QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005243 "%s: Setting maximum tx power failed",
5244 __func__);
5245 return -EIO;
5246 }
5247
5248 break;
5249 }
5250 case WE_SET_MAX_TX_POWER_2_4:
5251 {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05305252 hddLog(QDF_TRACE_LEVEL_INFO,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005253 "%s: Setting maximum tx power %d dBm for 2.4 GHz band",
5254 __func__, set_value);
5255 if (sme_set_max_tx_power_per_band(eCSR_BAND_24, set_value) !=
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05305256 QDF_STATUS_SUCCESS) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05305257 hddLog(QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005258 "%s: Setting maximum tx power failed for 2.4 GHz band",
5259 __func__);
5260 return -EIO;
5261 }
5262
5263 break;
5264 }
5265 case WE_SET_MAX_TX_POWER_5_0:
5266 {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05305267 hddLog(QDF_TRACE_LEVEL_INFO,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005268 "%s: Setting maximum tx power %d dBm for 5.0 GHz band",
5269 __func__, set_value);
5270 if (sme_set_max_tx_power_per_band(eCSR_BAND_5G, set_value) !=
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05305271 QDF_STATUS_SUCCESS) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05305272 hddLog(QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005273 "%s: Setting maximum tx power failed for 5.0 GHz band",
5274 __func__);
5275 return -EIO;
5276 }
5277
5278 break;
5279 }
5280 case WE_SET_HIGHER_DTIM_TRANSITION:
5281 {
5282 if (!((set_value == false) || (set_value == true))) {
5283 hddLog(LOGE, "Dynamic DTIM Incorrect data:%d",
5284 set_value);
5285 ret = -EINVAL;
5286 } else {
5287 if (pAdapter->higherDtimTransition != set_value) {
5288 pAdapter->higherDtimTransition =
5289 set_value;
5290 hddLog(LOG1,
5291 "%s: higherDtimTransition set to :%d",
5292 __func__,
5293 pAdapter->higherDtimTransition);
5294 }
5295 }
5296
5297 break;
5298 }
5299
5300 case WE_SET_TM_LEVEL:
5301 {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05305302 hddLog(QDF_TRACE_LEVEL_INFO,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005303 "Set Thermal Mitigation Level %d", set_value);
5304 (void)sme_set_thermal_level(hHal, set_value);
5305 break;
5306 }
5307
5308 case WE_SET_PHYMODE:
5309 {
5310 hdd_context_t *phddctx = WLAN_HDD_GET_CTX(pAdapter);
5311
5312 ret =
5313 wlan_hdd_update_phymode(dev, hHal, set_value,
5314 phddctx);
5315 break;
5316 }
5317
5318 case WE_SET_NSS:
5319 {
5320 hddLog(LOG1, "Set NSS = %d", set_value);
5321 if ((set_value > 2) || (set_value <= 0)) {
5322 hddLog(LOGE, "NSS greater than 2 not supported");
5323 ret = -EINVAL;
5324 } else {
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05305325 if (QDF_STATUS_SUCCESS !=
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005326 hdd_update_nss(WLAN_HDD_GET_CTX(pAdapter),
5327 set_value))
5328 ret = -EINVAL;
5329 }
5330 break;
5331 }
5332
5333 case WE_SET_GTX_HT_MCS:
5334 {
5335 hddLog(LOG1, "WMI_VDEV_PARAM_GTX_HT_MCS %d", set_value);
5336 ret = wma_cli_set_command(pAdapter->sessionId,
5337 WMI_VDEV_PARAM_GTX_HT_MCS,
5338 set_value, GTX_CMD);
5339 break;
5340 }
5341
5342 case WE_SET_GTX_VHT_MCS:
5343 {
5344 hddLog(LOG1, "WMI_VDEV_PARAM_GTX_VHT_MCS %d",
5345 set_value);
5346 ret = wma_cli_set_command(pAdapter->sessionId,
5347 WMI_VDEV_PARAM_GTX_VHT_MCS,
5348 set_value, GTX_CMD);
5349 break;
5350 }
5351
5352 case WE_SET_GTX_USRCFG:
5353 {
5354 hddLog(LOG1, "WMI_VDEV_PARAM_GTX_USR_CFG %d",
5355 set_value);
5356 ret = wma_cli_set_command(pAdapter->sessionId,
5357 WMI_VDEV_PARAM_GTX_USR_CFG,
5358 set_value, GTX_CMD);
5359 break;
5360 }
5361
5362 case WE_SET_GTX_THRE:
5363 {
5364 hddLog(LOG1, "WMI_VDEV_PARAM_GTX_THRE %d", set_value);
5365 ret = wma_cli_set_command(pAdapter->sessionId,
5366 WMI_VDEV_PARAM_GTX_THRE,
5367 set_value, GTX_CMD);
5368 break;
5369 }
5370
5371 case WE_SET_GTX_MARGIN:
5372 {
5373 hddLog(LOG1, "WMI_VDEV_PARAM_GTX_MARGIN %d", set_value);
5374 ret = wma_cli_set_command(pAdapter->sessionId,
5375 WMI_VDEV_PARAM_GTX_MARGIN,
5376 set_value, GTX_CMD);
5377 break;
5378 }
5379
5380 case WE_SET_GTX_STEP:
5381 {
5382 hddLog(LOG1, "WMI_VDEV_PARAM_GTX_STEP %d", set_value);
5383 ret = wma_cli_set_command(pAdapter->sessionId,
5384 WMI_VDEV_PARAM_GTX_STEP,
5385 set_value, GTX_CMD);
5386 break;
5387 }
5388
5389 case WE_SET_GTX_MINTPC:
5390 {
5391 hddLog(LOG1, "WMI_VDEV_PARAM_GTX_MINTPC %d", set_value);
5392 ret = wma_cli_set_command(pAdapter->sessionId,
5393 WMI_VDEV_PARAM_GTX_MINTPC,
5394 set_value, GTX_CMD);
5395 break;
5396 }
5397
5398 case WE_SET_GTX_BWMASK:
5399 {
5400 hddLog(LOG1, "WMI_VDEV_PARAM_GTX_BWMASK %d", set_value);
5401 ret = wma_cli_set_command(pAdapter->sessionId,
5402 WMI_VDEV_PARAM_GTX_BW_MASK,
5403 set_value, GTX_CMD);
5404 break;
5405 }
5406
5407 case WE_SET_LDPC:
5408 {
5409 uint32_t value;
5410 union {
5411 uint16_t nCfgValue16;
5412 tSirMacHTCapabilityInfo htCapInfo;
5413 } uHTCapabilityInfo;
5414
5415 hddLog(LOG1, "LDPC val %d", set_value);
5416 /* get the HT capability info */
5417 ret = sme_cfg_get_int(hHal, WNI_CFG_HT_CAP_INFO, &value);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05305418 if (QDF_STATUS_SUCCESS != ret) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05305419 QDF_TRACE(QDF_MODULE_ID_HDD,
5420 QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005421 "%s: could not get HT capability info",
5422 __func__);
5423 return -EIO;
5424 }
5425
5426 uHTCapabilityInfo.nCfgValue16 = 0xFFFF & value;
5427 if ((set_value
5428 && (uHTCapabilityInfo.htCapInfo.advCodingCap))
5429 || (!set_value)) {
5430 ret =
5431 sme_update_ht_config(hHal,
5432 pAdapter->sessionId,
5433 WNI_CFG_HT_CAP_INFO_ADVANCE_CODING,
5434 set_value);
5435 }
5436
5437 if (ret)
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05305438 QDF_TRACE(QDF_MODULE_ID_HDD,
5439 QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005440 "Failed to set LDPC value");
5441
5442 break;
5443 }
5444
5445 case WE_SET_TX_STBC:
5446 {
5447 uint32_t value;
5448 union {
5449 uint16_t nCfgValue16;
5450 tSirMacHTCapabilityInfo htCapInfo;
5451 } uHTCapabilityInfo;
5452
5453 hddLog(LOG1, "TX_STBC val %d", set_value);
5454 /* get the HT capability info */
5455 ret = sme_cfg_get_int(hHal, WNI_CFG_HT_CAP_INFO, &value);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05305456 if (QDF_STATUS_SUCCESS != ret) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05305457 QDF_TRACE(QDF_MODULE_ID_HDD,
5458 QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005459 "%s: could not get HT capability info",
5460 __func__);
5461 return -EIO;
5462 }
5463
5464 uHTCapabilityInfo.nCfgValue16 = 0xFFFF & value;
5465 if ((set_value && (uHTCapabilityInfo.htCapInfo.txSTBC))
5466 || (!set_value)) {
5467 ret =
5468 sme_update_ht_config(hHal,
5469 pAdapter->sessionId,
5470 WNI_CFG_HT_CAP_INFO_TX_STBC,
5471 set_value);
5472 }
5473
5474 if (ret)
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05305475 QDF_TRACE(QDF_MODULE_ID_HDD,
5476 QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005477 "Failed to set TX STBC value");
5478
5479 break;
5480 }
5481
5482 case WE_SET_RX_STBC:
5483 {
5484 uint32_t value;
5485 union {
5486 uint16_t nCfgValue16;
5487 tSirMacHTCapabilityInfo htCapInfo;
5488 } uHTCapabilityInfo;
5489
5490 hddLog(LOG1, "WMI_VDEV_PARAM_RX_STBC val %d",
5491 set_value);
5492 /* get the HT capability info */
5493 ret = sme_cfg_get_int(hHal, WNI_CFG_HT_CAP_INFO, &value);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05305494 if (QDF_STATUS_SUCCESS != ret) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05305495 QDF_TRACE(QDF_MODULE_ID_QDF,
5496 QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005497 "%s: could not get HT capability info",
5498 __func__);
5499 return -EIO;
5500 }
5501
5502 uHTCapabilityInfo.nCfgValue16 = 0xFFFF & value;
5503 if ((set_value && (uHTCapabilityInfo.htCapInfo.rxSTBC))
5504 || (!set_value)) {
5505 ret =
5506 sme_update_ht_config(hHal,
5507 pAdapter->sessionId,
5508 WNI_CFG_HT_CAP_INFO_RX_STBC,
5509 (!set_value) ? set_value
5510 : uHTCapabilityInfo.
5511 htCapInfo.rxSTBC);
5512 }
5513
5514 if (ret)
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05305515 QDF_TRACE(QDF_MODULE_ID_HDD,
5516 QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005517 "Failed to set RX STBC value");
5518 break;
5519 }
5520
5521 case WE_SET_SHORT_GI:
5522 {
5523 hddLog(LOG1, "WMI_VDEV_PARAM_SGI val %d", set_value);
5524 ret = sme_update_ht_config(hHal, pAdapter->sessionId,
5525 WNI_CFG_HT_CAP_INFO_SHORT_GI_20MHZ,
5526 set_value);
5527 if (ret)
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05305528 QDF_TRACE(QDF_MODULE_ID_HDD,
5529 QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005530 "Failed to set ShortGI value");
5531 break;
5532 }
5533
5534 case WE_SET_RTSCTS:
5535 {
5536 uint32_t value;
5537
5538 hddLog(LOG1, "WMI_VDEV_PARAM_ENABLE_RTSCTS val 0x%x",
5539 set_value);
5540
5541 if ((set_value & HDD_RTSCTS_EN_MASK) ==
5542 HDD_RTSCTS_ENABLE)
5543 value =
5544 (WLAN_HDD_GET_CTX(pAdapter))->config->
5545 RTSThreshold;
5546 else if (((set_value & HDD_RTSCTS_EN_MASK) == 0)
5547 || ((set_value & HDD_RTSCTS_EN_MASK) ==
5548 HDD_CTS_ENABLE))
5549 value = WNI_CFG_RTS_THRESHOLD_STAMAX;
5550 else
5551 return -EIO;
5552
5553 ret = wma_cli_set_command(pAdapter->sessionId,
5554 WMI_VDEV_PARAM_ENABLE_RTSCTS,
5555 set_value, VDEV_CMD);
5556 if (!ret) {
5557 if (sme_cfg_set_int
5558 (hHal, WNI_CFG_RTS_THRESHOLD, value) !=
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05305559 QDF_STATUS_SUCCESS) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005560 hddLog(LOGE, "FAILED TO SET RTSCTS");
5561 return -EIO;
5562 }
5563 }
5564
5565 break;
5566 }
5567
5568 case WE_SET_CHWIDTH:
5569 {
5570 bool chwidth = false;
5571 hdd_context_t *phddctx = WLAN_HDD_GET_CTX(pAdapter);
5572 /*updating channel bonding only on 5Ghz */
5573 hddLog(LOG1, "WMI_VDEV_PARAM_CHWIDTH val %d",
5574 set_value);
5575 if (set_value > eHT_CHANNEL_WIDTH_80MHZ) {
5576 hddLog(LOGE,
5577 "Invalid channel width 0->20 1->40 2->80");
5578 return -EINVAL;
5579 }
5580
5581 if ((WNI_CFG_CHANNEL_BONDING_MODE_DISABLE !=
5582 csr_convert_cb_ini_value_to_phy_cb_state(phddctx->config->
5583 nChannelBondingMode5GHz)))
5584 chwidth = true;
5585
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005586 sme_get_config_param(hHal, &smeConfig);
5587 switch (set_value) {
5588 case eHT_CHANNEL_WIDTH_20MHZ:
5589 smeConfig.csrConfig.channelBondingMode5GHz =
5590 WNI_CFG_CHANNEL_BONDING_MODE_DISABLE;
5591 break;
5592 case eHT_CHANNEL_WIDTH_40MHZ:
5593 if (chwidth)
5594 smeConfig.csrConfig.
5595 channelBondingMode5GHz =
5596 phddctx->config->
5597 nChannelBondingMode5GHz;
5598 else
5599 return -EINVAL;
5600
5601 break;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005602 case eHT_CHANNEL_WIDTH_80MHZ:
5603 if (chwidth)
5604 smeConfig.csrConfig.
5605 channelBondingMode5GHz =
5606 phddctx->config->
5607 nChannelBondingMode5GHz;
5608 else
5609 return -EINVAL;
5610
5611 break;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005612
5613 default:
5614 return -EINVAL;
5615 }
5616
5617 ret = wma_cli_set_command(pAdapter->sessionId,
5618 WMI_VDEV_PARAM_CHWIDTH,
5619 set_value, VDEV_CMD);
5620 if (!ret)
5621 sme_update_config(hHal, &smeConfig);
5622
5623 break;
5624 }
5625
5626 case WE_SET_ANI_EN_DIS:
5627 {
5628 hddLog(LOG1, "WMI_PDEV_PARAM_ANI_ENABLE val %d",
5629 set_value);
5630 ret = wma_cli_set_command(pAdapter->sessionId,
5631 WMI_PDEV_PARAM_ANI_ENABLE,
5632 set_value, PDEV_CMD);
5633 break;
5634 }
5635
5636 case WE_SET_ANI_POLL_PERIOD:
5637 {
5638 hddLog(LOG1, "WMI_PDEV_PARAM_ANI_POLL_PERIOD val %d",
5639 set_value);
5640 ret = wma_cli_set_command(pAdapter->sessionId,
5641 WMI_PDEV_PARAM_ANI_POLL_PERIOD,
5642 set_value, PDEV_CMD);
5643 break;
5644 }
5645
5646 case WE_SET_ANI_LISTEN_PERIOD:
5647 {
5648 hddLog(LOG1, "WMI_PDEV_PARAM_ANI_LISTEN_PERIOD val %d",
5649 set_value);
5650 ret = wma_cli_set_command(pAdapter->sessionId,
5651 WMI_PDEV_PARAM_ANI_LISTEN_PERIOD,
5652 set_value, PDEV_CMD);
5653 break;
5654 }
5655
5656 case WE_SET_ANI_OFDM_LEVEL:
5657 {
5658 hddLog(LOG1, "WMI_PDEV_PARAM_ANI_OFDM_LEVEL val %d",
5659 set_value);
5660 ret = wma_cli_set_command(pAdapter->sessionId,
5661 WMI_PDEV_PARAM_ANI_OFDM_LEVEL,
5662 set_value, PDEV_CMD);
5663 break;
5664 }
5665
5666 case WE_SET_ANI_CCK_LEVEL:
5667 {
5668 hddLog(LOG1, "WMI_PDEV_PARAM_ANI_CCK_LEVEL val %d",
5669 set_value);
5670 ret = wma_cli_set_command(pAdapter->sessionId,
5671 WMI_PDEV_PARAM_ANI_CCK_LEVEL,
5672 set_value, PDEV_CMD);
5673 break;
5674 }
5675
5676 case WE_SET_DYNAMIC_BW:
5677 {
5678 hddLog(LOG1, "WMI_PDEV_PARAM_DYNAMIC_BW val %d",
5679 set_value);
5680 ret = wma_cli_set_command(pAdapter->sessionId,
5681 WMI_PDEV_PARAM_DYNAMIC_BW,
5682 set_value, PDEV_CMD);
5683 break;
5684 }
5685
5686 case WE_SET_CTS_CBW:
5687 {
5688 hddLog(LOG1, "WE_SET_CTS_CBW val %d", set_value);
5689 ret = wma_cli_set_command(pAdapter->sessionId,
5690 WMI_PDEV_PARAM_CTS_CBW,
5691 set_value, PDEV_CMD);
5692 break;
5693 }
5694
5695 case WE_SET_11N_RATE:
5696 {
5697 uint8_t preamble = 0, nss = 0, rix = 0;
5698 hddLog(LOG1, "WMI_VDEV_PARAM_FIXED_RATE val %d",
5699 set_value);
5700
5701 if (set_value != 0xff) {
5702 rix = RC_2_RATE_IDX(set_value);
5703 if (set_value & 0x80) {
5704 preamble = WMI_RATE_PREAMBLE_HT;
5705 nss = HT_RC_2_STREAMS(set_value) - 1;
5706 } else {
5707 nss = 0;
5708 rix = RC_2_RATE_IDX(set_value);
5709 if (set_value & 0x10) {
5710 preamble =
5711 WMI_RATE_PREAMBLE_CCK;
5712 if (rix != 0x3)
5713 /* Enable Short
5714 * preamble always for
5715 * CCK except 1mbps
5716 */
5717 rix |= 0x4;
5718 } else {
5719 preamble =
5720 WMI_RATE_PREAMBLE_OFDM;
5721 }
5722 }
5723 set_value = (preamble << 6) | (nss << 4) | rix;
5724 }
5725 hdd_info("WMI_VDEV_PARAM_FIXED_RATE val %d rix %d preamble %x nss %d",
5726 set_value, rix, preamble, nss);
5727
5728 ret = wma_cli_set_command(pAdapter->sessionId,
5729 WMI_VDEV_PARAM_FIXED_RATE,
5730 set_value, VDEV_CMD);
5731 break;
5732 }
5733
5734 case WE_SET_VHT_RATE:
5735 {
5736 uint8_t preamble = 0, nss = 0, rix = 0;
5737
5738 if (set_value != 0xff) {
5739 rix = RC_2_RATE_IDX_11AC(set_value);
5740 preamble = WMI_RATE_PREAMBLE_VHT;
5741 nss = HT_RC_2_STREAMS_11AC(set_value) - 1;
5742
5743 set_value = (preamble << 6) | (nss << 4) | rix;
5744 }
5745 hdd_info("WMI_VDEV_PARAM_FIXED_RATE val %d rix %d preamble %x nss %d",
5746 set_value, rix, preamble, nss);
5747 ret = wma_cli_set_command(pAdapter->sessionId,
5748 WMI_VDEV_PARAM_FIXED_RATE,
5749 set_value, VDEV_CMD);
5750 break;
5751 }
5752
5753 case WE_SET_AMPDU:
5754 {
5755 hddLog(LOG1, "SET AMPDU val %d", set_value);
5756 ret = wma_cli_set_command(pAdapter->sessionId,
5757 GEN_VDEV_PARAM_AMPDU,
5758 set_value, GEN_CMD);
5759 break;
5760 }
5761
5762 case WE_SET_AMSDU:
5763 {
5764 hddLog(LOG1, "SET AMSDU val %d", set_value);
5765 ret = wma_cli_set_command(pAdapter->sessionId,
5766 GEN_VDEV_PARAM_AMSDU,
5767 set_value, GEN_CMD);
5768 break;
5769 }
5770
5771 case WE_SET_BURST_ENABLE:
5772 {
5773 hddLog(LOG1, "SET Burst enable val %d", set_value);
5774 if ((set_value == 0) || (set_value == 1)) {
5775 ret = wma_cli_set_command(pAdapter->sessionId,
5776 WMI_PDEV_PARAM_BURST_ENABLE,
5777 set_value, PDEV_CMD);
5778 } else
5779 ret = -EINVAL;
5780 break;
5781 }
5782 case WE_SET_BURST_DUR:
5783 {
5784 hddLog(LOG1, "SET Burst duration val %d", set_value);
5785 if ((set_value > 0) && (set_value <= 8192))
5786 ret = wma_cli_set_command(pAdapter->sessionId,
5787 WMI_PDEV_PARAM_BURST_DUR,
5788 set_value, PDEV_CMD);
5789 else
5790 ret = -EINVAL;
5791 break;
5792 }
5793
5794 case WE_SET_TX_CHAINMASK:
5795 {
5796 hddLog(LOG1, "WMI_PDEV_PARAM_TX_CHAIN_MASK val %d",
5797 set_value);
5798 ret = wma_cli_set_command(pAdapter->sessionId,
5799 WMI_PDEV_PARAM_TX_CHAIN_MASK,
5800 set_value, PDEV_CMD);
5801 break;
5802 }
5803
5804 case WE_SET_RX_CHAINMASK:
5805 {
5806 hddLog(LOG1, "WMI_PDEV_PARAM_RX_CHAIN_MASK val %d",
5807 set_value);
5808 ret = wma_cli_set_command(pAdapter->sessionId,
5809 WMI_PDEV_PARAM_RX_CHAIN_MASK,
5810 set_value, PDEV_CMD);
5811 break;
5812 }
5813
5814 case WE_SET_TXPOW_2G:
5815 {
5816 hddLog(LOG1, "WMI_PDEV_PARAM_TXPOWER_LIMIT2G val %d",
5817 set_value);
5818 ret = wma_cli_set_command(pAdapter->sessionId,
5819 WMI_PDEV_PARAM_TXPOWER_LIMIT2G,
5820 set_value, PDEV_CMD);
5821 break;
5822 }
5823
5824 case WE_SET_TXPOW_5G:
5825 {
5826 hddLog(LOG1, "WMI_PDEV_PARAM_TXPOWER_LIMIT5G val %d",
5827 set_value);
5828 ret = wma_cli_set_command(pAdapter->sessionId,
5829 WMI_PDEV_PARAM_TXPOWER_LIMIT5G,
5830 set_value, PDEV_CMD);
5831 break;
5832 }
5833
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005834 /* Firmware debug log */
5835 case WE_DBGLOG_LOG_LEVEL:
5836 {
5837 hddLog(LOG1, "WE_DBGLOG_LOG_LEVEL val %d", set_value);
5838 hdd_ctx->fw_log_settings.dl_loglevel = set_value;
5839 ret = wma_cli_set_command(pAdapter->sessionId,
5840 WMI_DBGLOG_LOG_LEVEL,
5841 set_value, DBG_CMD);
5842 break;
5843 }
5844
5845 case WE_DBGLOG_VAP_ENABLE:
5846 {
5847 hddLog(LOG1, "WE_DBGLOG_VAP_ENABLE val %d", set_value);
5848 ret = wma_cli_set_command(pAdapter->sessionId,
5849 WMI_DBGLOG_VAP_ENABLE,
5850 set_value, DBG_CMD);
5851 break;
5852 }
5853
5854 case WE_DBGLOG_VAP_DISABLE:
5855 {
5856 hddLog(LOG1, "WE_DBGLOG_VAP_DISABLE val %d", set_value);
5857 ret = wma_cli_set_command(pAdapter->sessionId,
5858 WMI_DBGLOG_VAP_DISABLE,
5859 set_value, DBG_CMD);
5860 break;
5861 }
5862
5863 case WE_DBGLOG_MODULE_ENABLE:
5864 {
5865 hddLog(LOG1, "WE_DBGLOG_MODULE_ENABLE val %d",
5866 set_value);
5867 hdd_ctx->fw_log_settings.enable = set_value;
5868 ret = wma_cli_set_command(pAdapter->sessionId,
5869 WMI_DBGLOG_MODULE_ENABLE,
5870 set_value, DBG_CMD);
5871 break;
5872 }
5873
5874 case WE_DBGLOG_MODULE_DISABLE:
5875 {
5876 hddLog(LOG1, "WE_DBGLOG_MODULE_DISABLE val %d",
5877 set_value);
5878 hdd_ctx->fw_log_settings.enable = set_value;
5879 ret = wma_cli_set_command(pAdapter->sessionId,
5880 WMI_DBGLOG_MODULE_DISABLE,
5881 set_value, DBG_CMD);
5882 break;
5883 }
5884 case WE_DBGLOG_MOD_LOG_LEVEL:
5885 {
5886 hddLog(LOG1, "WE_DBGLOG_MOD_LOG_LEVEL val %d",
5887 set_value);
5888
5889 if (hdd_ctx->fw_log_settings.index >= MAX_MOD_LOGLEVEL)
5890 hdd_ctx->fw_log_settings.index = 0;
5891
5892 hdd_ctx->fw_log_settings.
5893 dl_mod_loglevel[hdd_ctx->fw_log_settings.index] =
5894 set_value;
5895 hdd_ctx->fw_log_settings.index++;
5896
5897 ret = wma_cli_set_command(pAdapter->sessionId,
5898 WMI_DBGLOG_MOD_LOG_LEVEL,
5899 set_value, DBG_CMD);
5900 break;
5901 }
5902
5903 case WE_DBGLOG_TYPE:
5904 {
5905 hddLog(LOG1, "WE_DBGLOG_TYPE val %d", set_value);
5906 hdd_ctx->fw_log_settings.dl_type = set_value;
5907 ret = wma_cli_set_command(pAdapter->sessionId,
5908 WMI_DBGLOG_TYPE,
5909 set_value, DBG_CMD);
5910 break;
5911 }
5912 case WE_DBGLOG_REPORT_ENABLE:
5913 {
5914 hddLog(LOG1, "WE_DBGLOG_REPORT_ENABLE val %d",
5915 set_value);
5916 hdd_ctx->fw_log_settings.dl_report = set_value;
5917 ret = wma_cli_set_command(pAdapter->sessionId,
5918 WMI_DBGLOG_REPORT_ENABLE,
5919 set_value, DBG_CMD);
5920 break;
5921 }
5922
5923 case WE_SET_TXRX_FWSTATS:
5924 {
5925 hddLog(LOG1, "WE_SET_TXRX_FWSTATS val %d", set_value);
5926 ret = wma_cli_set_command(pAdapter->sessionId,
5927 WMA_VDEV_TXRX_FWSTATS_ENABLE_CMDID,
5928 set_value, VDEV_CMD);
5929 break;
5930 }
5931
5932 case WE_TXRX_FWSTATS_RESET:
5933 {
5934 hddLog(LOG1, "WE_TXRX_FWSTATS_RESET val %d", set_value);
5935 ret = wma_cli_set_command(pAdapter->sessionId,
5936 WMA_VDEV_TXRX_FWSTATS_RESET_CMDID,
5937 set_value, VDEV_CMD);
5938 break;
5939 }
5940
5941 case WE_DUMP_STATS:
5942 {
5943 hddLog(LOG1, "WE_DUMP_STATS val %d", set_value);
5944 hdd_wlan_dump_stats(pAdapter, set_value);
5945 break;
5946 }
5947
5948 case WE_CLEAR_STATS:
5949 {
5950 hddLog(LOG1, "WE_CLEAR_STATS val %d", set_value);
5951 switch (set_value) {
5952 case WLAN_HDD_STATS:
5953 memset(&pAdapter->stats, 0, sizeof(pAdapter->stats));
5954 memset(&pAdapter->hdd_stats, 0,
5955 sizeof(pAdapter->hdd_stats));
5956 break;
5957 case WLAN_TXRX_HIST_STATS:
5958 wlan_hdd_clear_tx_rx_histogram(hdd_ctx);
5959 break;
5960 case WLAN_HDD_NETIF_OPER_HISTORY:
5961 wlan_hdd_clear_netif_queue_history(hdd_ctx);
5962 break;
5963 default:
5964 ol_txrx_clear_stats(set_value);
5965 }
5966 break;
5967 }
5968
5969 case WE_PPS_PAID_MATCH:
5970 {
Krunal Sonif07bb382016-03-10 13:02:11 -08005971 if (pAdapter->device_mode != QDF_STA_MODE)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005972 return EINVAL;
5973
5974 hddLog(LOG1, "WMI_VDEV_PPS_PAID_MATCH val %d ",
5975 set_value);
5976 ret = wma_cli_set_command(pAdapter->sessionId,
5977 WMI_VDEV_PPS_PAID_MATCH,
5978 set_value, PPS_CMD);
5979 break;
5980 }
5981
5982 case WE_PPS_GID_MATCH:
5983 {
Krunal Sonif07bb382016-03-10 13:02:11 -08005984 if (pAdapter->device_mode != QDF_STA_MODE)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005985 return EINVAL;
5986 hddLog(LOG1, "WMI_VDEV_PPS_GID_MATCH val %d ",
5987 set_value);
5988 ret = wma_cli_set_command(pAdapter->sessionId,
5989 WMI_VDEV_PPS_GID_MATCH,
5990 set_value, PPS_CMD);
5991 break;
5992 }
5993
5994 case WE_PPS_EARLY_TIM_CLEAR:
5995 {
Krunal Sonif07bb382016-03-10 13:02:11 -08005996 if (pAdapter->device_mode != QDF_STA_MODE)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005997 return EINVAL;
5998 hddLog(LOG1, " WMI_VDEV_PPS_EARLY_TIM_CLEAR val %d ",
5999 set_value);
6000 ret = wma_cli_set_command(pAdapter->sessionId,
6001 WMI_VDEV_PPS_EARLY_TIM_CLEAR,
6002 set_value, PPS_CMD);
6003 break;
6004 }
6005
6006 case WE_PPS_EARLY_DTIM_CLEAR:
6007 {
Krunal Sonif07bb382016-03-10 13:02:11 -08006008 if (pAdapter->device_mode != QDF_STA_MODE)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006009 return EINVAL;
6010 hddLog(LOG1, "WMI_VDEV_PPS_EARLY_DTIM_CLEAR val %d",
6011 set_value);
6012 ret = wma_cli_set_command(pAdapter->sessionId,
6013 WMI_VDEV_PPS_EARLY_DTIM_CLEAR,
6014 set_value, PPS_CMD);
6015 break;
6016 }
6017
6018 case WE_PPS_EOF_PAD_DELIM:
6019 {
Krunal Sonif07bb382016-03-10 13:02:11 -08006020 if (pAdapter->device_mode != QDF_STA_MODE)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006021 return EINVAL;
6022 hddLog(LOG1, "WMI_VDEV_PPS_EOF_PAD_DELIM val %d ",
6023 set_value);
6024 ret = wma_cli_set_command(pAdapter->sessionId,
6025 WMI_VDEV_PPS_EOF_PAD_DELIM,
6026 set_value, PPS_CMD);
6027 break;
6028 }
6029
6030 case WE_PPS_MACADDR_MISMATCH:
6031 {
Krunal Sonif07bb382016-03-10 13:02:11 -08006032 if (pAdapter->device_mode != QDF_STA_MODE)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006033 return EINVAL;
6034 hddLog(LOG1, "WMI_VDEV_PPS_MACADDR_MISMATCH val %d ",
6035 set_value);
6036 ret = wma_cli_set_command(pAdapter->sessionId,
6037 WMI_VDEV_PPS_MACADDR_MISMATCH,
6038 set_value, PPS_CMD);
6039 break;
6040 }
6041
6042 case WE_PPS_DELIM_CRC_FAIL:
6043 {
Krunal Sonif07bb382016-03-10 13:02:11 -08006044 if (pAdapter->device_mode != QDF_STA_MODE)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006045 return EINVAL;
6046 hddLog(LOG1, "WMI_VDEV_PPS_DELIM_CRC_FAIL val %d ",
6047 set_value);
6048 ret = wma_cli_set_command(pAdapter->sessionId,
6049 WMI_VDEV_PPS_DELIM_CRC_FAIL,
6050 set_value, PPS_CMD);
6051 break;
6052 }
6053
6054 case WE_PPS_GID_NSTS_ZERO:
6055 {
Krunal Sonif07bb382016-03-10 13:02:11 -08006056 if (pAdapter->device_mode != QDF_STA_MODE)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006057 return EINVAL;
6058 hddLog(LOG1, "WMI_VDEV_PPS_GID_NSTS_ZERO val %d ",
6059 set_value);
6060 ret = wma_cli_set_command(pAdapter->sessionId,
6061 WMI_VDEV_PPS_GID_NSTS_ZERO,
6062 set_value, PPS_CMD);
6063 break;
6064 }
6065
6066 case WE_PPS_RSSI_CHECK:
6067 {
Krunal Sonif07bb382016-03-10 13:02:11 -08006068 if (pAdapter->device_mode != QDF_STA_MODE)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006069 return EINVAL;
6070 hddLog(LOG1, "WMI_VDEV_PPS_RSSI_CHECK val %d ",
6071 set_value);
6072 ret = wma_cli_set_command(pAdapter->sessionId,
6073 WMI_VDEV_PPS_RSSI_CHECK,
6074 set_value, PPS_CMD);
6075 break;
6076 }
6077
6078 case WE_PPS_5G_EBT:
6079 {
Krunal Sonif07bb382016-03-10 13:02:11 -08006080 if (pAdapter->device_mode != QDF_STA_MODE)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006081 return -EINVAL;
6082
6083 hddLog(LOG1, "WMI_VDEV_PPS_5G_EBT val %d", set_value);
6084 ret = wma_cli_set_command(pAdapter->sessionId,
6085 WMI_VDEV_PPS_5G_EBT,
6086 set_value, PPS_CMD);
6087 break;
6088 }
6089
6090 case WE_SET_HTSMPS:
6091 {
6092 hddLog(LOG1, "WE_SET_HTSMPS val %d", set_value);
6093 ret = wma_cli_set_command(pAdapter->sessionId,
6094 WMI_STA_SMPS_FORCE_MODE_CMDID,
6095 set_value, VDEV_CMD);
6096 break;
6097 }
6098
6099 case WE_SET_QPOWER_MAX_PSPOLL_COUNT:
6100 {
6101 hddLog(LOG1, "WE_SET_QPOWER_MAX_PSPOLL_COUNT val %d",
6102 set_value);
6103 ret = wma_cli_set_command(pAdapter->sessionId,
6104 WMI_STA_PS_PARAM_QPOWER_PSPOLL_COUNT,
6105 set_value, QPOWER_CMD);
6106 break;
6107 }
6108
6109 case WE_SET_QPOWER_MAX_TX_BEFORE_WAKE:
6110 {
6111 hddLog(LOG1, "WE_SET_QPOWER_MAX_TX_BEFORE_WAKE val %d",
6112 set_value);
6113 ret = wma_cli_set_command(
6114 pAdapter->sessionId,
6115 WMI_STA_PS_PARAM_QPOWER_MAX_TX_BEFORE_WAKE,
6116 set_value, QPOWER_CMD);
6117 break;
6118 }
6119
6120 case WE_SET_QPOWER_SPEC_PSPOLL_WAKE_INTERVAL:
6121 {
6122 hddLog(LOG1,
6123 "WE_SET_QPOWER_SPEC_PSPOLL_WAKE_INTERVAL val %d",
6124 set_value);
6125 ret = wma_cli_set_command(
6126 pAdapter->sessionId,
6127 WMI_STA_PS_PARAM_QPOWER_SPEC_PSPOLL_WAKE_INTERVAL,
6128 set_value, QPOWER_CMD);
6129 break;
6130 }
6131
6132 case WE_SET_QPOWER_SPEC_MAX_SPEC_NODATA_PSPOLL:
6133 {
6134 hddLog(LOG1,
6135 "WE_SET_QPOWER_SPEC_MAX_SPEC_NODATA_PSPOLL val %d",
6136 set_value);
6137 ret = wma_cli_set_command(
6138 pAdapter->sessionId,
6139 WMI_STA_PS_PARAM_QPOWER_SPEC_MAX_SPEC_NODATA_PSPOLL,
6140 set_value, QPOWER_CMD);
6141 break;
6142 }
6143
6144 case WE_MCC_CONFIG_LATENCY:
6145 {
6146 cds_set_mcc_latency(pAdapter, set_value);
6147 break;
6148 }
6149
6150 case WE_MCC_CONFIG_QUOTA:
6151 {
6152 hddLog(LOG1, "iwpriv cmd to set MCC quota with val %dms",
6153 set_value);
6154 ret = cds_set_mcc_p2p_quota(pAdapter, set_value);
6155 break;
6156 }
6157 case WE_SET_DEBUG_LOG:
6158 {
6159 hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(pAdapter);
6160#ifdef QCA_PKT_PROTO_TRACE
6161 /* Trace buffer dump only */
6162 if (CDS_PKT_TRAC_DUMP_CMD == set_value) {
6163 cds_pkt_trace_buf_dump();
6164 break;
6165 }
6166#endif /* QCA_PKT_PROTO_TRACE */
6167 hdd_ctx->config->gEnableDebugLog = set_value;
6168 sme_update_connect_debug(hdd_ctx->hHal, set_value);
6169 break;
6170 }
6171 case WE_SET_EARLY_RX_ADJUST_ENABLE:
6172 {
6173 hddLog(LOG1, "SET early_rx enable val %d", set_value);
6174 if ((set_value == 0) || (set_value == 1))
6175 ret = wma_cli_set_command(
6176 pAdapter->sessionId,
6177 WMI_VDEV_PARAM_EARLY_RX_ADJUST_ENABLE,
6178 set_value, VDEV_CMD);
6179 else
6180 ret = -EINVAL;
6181 break;
6182 }
6183 case WE_SET_EARLY_RX_TGT_BMISS_NUM:
6184 {
6185 hddLog(LOG1, "SET early_rx bmiss val %d", set_value);
6186 ret = wma_cli_set_command(pAdapter->sessionId,
6187 WMI_VDEV_PARAM_EARLY_RX_TGT_BMISS_NUM,
6188 set_value, VDEV_CMD);
6189 break;
6190 }
6191 case WE_SET_EARLY_RX_BMISS_SAMPLE_CYCLE:
6192 {
6193 hddLog(LOG1, "SET early_rx bmiss sample cycle %d",
6194 set_value);
6195 ret = wma_cli_set_command(
6196 pAdapter->sessionId,
6197 WMI_VDEV_PARAM_EARLY_RX_BMISS_SAMPLE_CYCLE,
6198 set_value, VDEV_CMD);
6199 break;
6200 }
6201 case WE_SET_EARLY_RX_SLOP_STEP:
6202 {
6203 hddLog(LOG1, "SET early_rx bmiss slop step val %d",
6204 set_value);
6205 ret = wma_cli_set_command(pAdapter->sessionId,
6206 WMI_VDEV_PARAM_EARLY_RX_SLOP_STEP,
6207 set_value, VDEV_CMD);
6208 break;
6209 }
6210 case WE_SET_EARLY_RX_INIT_SLOP:
6211 {
6212 hddLog(LOG1, "SET early_rx init slop step val %d",
6213 set_value);
6214 ret = wma_cli_set_command(pAdapter->sessionId,
6215 WMI_VDEV_PARAM_EARLY_RX_INIT_SLOP,
6216 set_value, VDEV_CMD);
6217 break;
6218 }
6219 case WE_SET_EARLY_RX_ADJUST_PAUSE:
6220 {
6221 hddLog(LOG1, "SET early_rx adjust pause %d", set_value);
6222 if ((set_value == 0) || (set_value == 1))
6223 ret = wma_cli_set_command(
6224 pAdapter->sessionId,
6225 WMI_VDEV_PARAM_EARLY_RX_ADJUST_PAUSE,
6226 set_value, VDEV_CMD);
6227 else
6228 ret = -EINVAL;
6229 break;
6230 }
6231 case WE_SET_EARLY_RX_DRIFT_SAMPLE:
6232 {
6233 hddLog(LOG1, "SET early_rx drift sample %d", set_value);
6234 ret = wma_cli_set_command(pAdapter->sessionId,
6235 WMI_VDEV_PARAM_EARLY_RX_DRIFT_SAMPLE,
6236 set_value, VDEV_CMD);
6237 break;
6238 }
6239 case WE_SET_SCAN_DISABLE:
6240 {
6241 hddLog(LOG1, "SET SCAN DISABLE %d", set_value);
6242 sme_set_scan_disable(WLAN_HDD_GET_HAL_CTX(pAdapter), set_value);
6243 break;
6244 }
Govind Singha471e5e2015-10-12 17:11:14 +05306245 case WE_START_FW_PROFILE:
6246 {
6247 hddLog(LOG1, "WE_START_FW_PROFILE %d", set_value);
6248 ret = wma_cli_set_command(pAdapter->sessionId,
6249 WMI_WLAN_PROFILE_TRIGGER_CMDID,
6250 set_value, DBG_CMD);
6251 break;
6252 }
Abhishek Singh1bdb1572015-10-16 16:24:19 +05306253 case WE_SET_CHANNEL:
6254 {
6255 hddLog(LOG1, "Set Channel %d Session ID %d mode %d", set_value,
6256 pAdapter->sessionId, pAdapter->device_mode);
6257
Krunal Sonif07bb382016-03-10 13:02:11 -08006258 if ((QDF_STA_MODE == pAdapter->device_mode) ||
6259 (QDF_P2P_CLIENT_MODE == pAdapter->device_mode)) {
Abhishek Singh1bdb1572015-10-16 16:24:19 +05306260
6261 status = sme_ext_change_channel(hHal,
6262 set_value, pAdapter->sessionId);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05306263 if (status != QDF_STATUS_SUCCESS) {
Abhishek Singh1bdb1572015-10-16 16:24:19 +05306264 hddLog(LOGE,
6265 FL("Error in change channel status %d"),
6266 status);
6267 ret = -EINVAL;
6268 }
6269 } else {
6270 hddLog(LOGE,
6271 FL("change channel not supported for device mode %d"),
6272 pAdapter->device_mode);
6273 ret = -EINVAL;
6274 }
6275 break;
6276 }
6277
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006278 default:
6279 {
6280 hddLog(LOGE, "%s: Invalid sub command %d", __func__,
6281 sub_cmd);
6282 ret = -EINVAL;
6283 break;
6284 }
6285 }
Hanumantha Reddy Pothula2db50ed2015-11-23 10:48:33 +05306286 EXIT();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006287 return ret;
6288}
6289
6290static int iw_setint_getnone(struct net_device *dev,
6291 struct iw_request_info *info,
6292 union iwreq_data *wrqu,
6293 char *extra)
6294{
6295 int ret;
6296
6297 cds_ssr_protect(__func__);
6298 ret = __iw_setint_getnone(dev, info, wrqu, extra);
6299 cds_ssr_unprotect(__func__);
6300
6301 return ret;
6302}
6303
6304/**
Manikandan Mohandcc21ba2016-03-15 14:31:56 -07006305 * __iw_setnone_get_threeint() - return three value to up layer.
6306 *
6307 * @dev: pointer of net_device of this wireless card
6308 * @info: meta data about Request sent
6309 * @wrqu: include request info
6310 * @extra: buf used for in/Output
6311 *
6312 * Return: execute result
6313 */
6314static int __iw_setnone_get_threeint(struct net_device *dev,
6315 struct iw_request_info *info,
6316 union iwreq_data *wrqu, char *extra)
6317{
6318 int ret = 0; /* success */
6319 uint32_t *value = (int *)extra;
6320 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
6321 hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
6322
6323 ENTER_DEV(dev);
6324 ret = wlan_hdd_validate_context(hdd_ctx);
6325 if (0 != ret)
6326 return ret;
6327
6328 hdd_info(FL("param = %d"), value[0]);
6329 switch (value[0]) {
6330 case WE_GET_TSF:
6331 ret = hdd_indicate_tsf(adapter, value, 3);
6332 break;
6333 default:
6334 hdd_err("Invalid IOCTL get_value command %d", value[0]);
6335 break;
6336 }
6337 return ret;
6338}
6339
6340/**
6341 * iw_setnone_get_threeint() - return three value to up layer.
6342 *
6343 * @dev: pointer of net_device of this wireless card
6344 * @info: meta data about Request sent
6345 * @wrqu: include request info
6346 * @extra: buf used for in/Output
6347 *
6348 * Return: execute result
6349 */
6350static int iw_setnone_get_threeint(struct net_device *dev,
6351 struct iw_request_info *info,
6352 union iwreq_data *wrqu, char *extra)
6353{
6354 int ret;
6355
6356 cds_ssr_protect(__func__);
6357 ret = __iw_setnone_get_threeint(dev, info, wrqu, extra);
6358 cds_ssr_unprotect(__func__);
6359
6360 return ret;
6361}
6362
6363/**
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006364 * iw_setchar_getnone() - Generic "set string" private ioctl handler
6365 * @dev: device upon which the ioctl was received
6366 * @info: ioctl request information
6367 * @wrqu: ioctl request data
6368 * @extra: ioctl extra data
6369 *
6370 * Return: 0 on success, non-zero on error
6371 */
6372static int __iw_setchar_getnone(struct net_device *dev,
6373 struct iw_request_info *info,
6374 union iwreq_data *wrqu, char *extra)
6375{
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05306376 QDF_STATUS vstatus;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006377 int sub_cmd;
6378 int ret;
6379 char *pBuffer = NULL;
6380 hdd_adapter_t *pAdapter = (netdev_priv(dev));
6381 hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(pAdapter);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006382 struct hdd_config *pConfig = hdd_ctx->config;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006383 struct iw_point s_priv_data;
6384
Jeff Johnson6ee91ee2016-02-11 18:55:30 -08006385 ENTER_DEV(dev);
6386
Mukul Sharma34777c62015-11-02 20:22:30 +05306387 if (!capable(CAP_NET_ADMIN)) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05306388 QDF_TRACE(QDF_MODULE_ID_HDD, QDF_TRACE_LEVEL_ERROR,
Mukul Sharma34777c62015-11-02 20:22:30 +05306389 FL("permission check failed"));
6390 return -EPERM;
6391 }
6392
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006393 ret = wlan_hdd_validate_context(hdd_ctx);
6394 if (0 != ret)
6395 return ret;
6396
6397 /* helper function to get iwreq_data with compat handling. */
6398 if (hdd_priv_get_data(&s_priv_data, wrqu)) {
6399 return -EINVAL;
6400 }
6401
6402 /* make sure all params are correctly passed to function */
6403 if ((NULL == s_priv_data.pointer) || (0 == s_priv_data.length)) {
6404 return -EINVAL;
6405 }
6406
6407 sub_cmd = s_priv_data.flags;
6408
6409 /* ODD number is used for set, copy data using copy_from_user */
6410 pBuffer = mem_alloc_copy_from_user_helper(s_priv_data.pointer,
6411 s_priv_data.length);
6412 if (NULL == pBuffer) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05306413 QDF_TRACE(QDF_MODULE_ID_HDD, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006414 "mem_alloc_copy_from_user_helper fail");
6415 return -ENOMEM;
6416 }
6417
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05306418 QDF_TRACE(QDF_MODULE_ID_HDD, QDF_TRACE_LEVEL_INFO,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006419 "%s: Received length %d", __func__, s_priv_data.length);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05306420 QDF_TRACE(QDF_MODULE_ID_HDD, QDF_TRACE_LEVEL_INFO,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006421 "%s: Received data %s", __func__, pBuffer);
6422
6423 switch (sub_cmd) {
6424 case WE_WOWL_ADD_PTRN:
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05306425 QDF_TRACE(QDF_MODULE_ID_HDD, QDF_TRACE_LEVEL_INFO, "ADD_PTRN");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006426 hdd_add_wowl_ptrn(pAdapter, pBuffer);
6427 break;
6428 case WE_WOWL_DEL_PTRN:
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05306429 QDF_TRACE(QDF_MODULE_ID_HDD, QDF_TRACE_LEVEL_INFO, "DEL_PTRN");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006430 hdd_del_wowl_ptrn(pAdapter, pBuffer);
6431 break;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006432 case WE_NEIGHBOR_REPORT_REQUEST:
6433 {
6434 tRrmNeighborReq neighborReq;
6435 tRrmNeighborRspCallbackInfo callbackInfo;
6436
6437 if (pConfig->fRrmEnable) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05306438 QDF_TRACE(QDF_MODULE_ID_HDD,
6439 QDF_TRACE_LEVEL_INFO,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006440 "Neighbor Request");
6441 neighborReq.no_ssid =
6442 (s_priv_data.length - 1) ? false : true;
6443 if (!neighborReq.no_ssid) {
6444 neighborReq.ssid.length =
6445 (s_priv_data.length - 1) >
6446 32 ? 32 : (s_priv_data.length - 1);
Anurag Chouhan600c3a02016-03-01 10:33:54 +05306447 qdf_mem_copy(neighborReq.ssid.ssId,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006448 pBuffer,
6449 neighborReq.ssid.length);
6450 }
6451
6452 callbackInfo.neighborRspCallback = NULL;
6453 callbackInfo.neighborRspCallbackContext = NULL;
6454 callbackInfo.timeout = 5000; /* 5 seconds */
6455 sme_neighbor_report_request(WLAN_HDD_GET_HAL_CTX
6456 (pAdapter),
6457 pAdapter->sessionId,
6458 &neighborReq,
6459 &callbackInfo);
6460 } else {
6461 hddLog(LOGE,
6462 "%s: Ignoring neighbor request as RRM is not enabled",
6463 __func__);
6464 ret = -EINVAL;
6465 }
6466 }
6467 break;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006468 case WE_SET_AP_WPS_IE:
6469 hddLog(LOGE, "Received WE_SET_AP_WPS_IE");
6470 sme_update_p2p_ie(WLAN_HDD_GET_HAL_CTX(pAdapter), pBuffer,
6471 s_priv_data.length);
6472 break;
6473 case WE_SET_CONFIG:
6474 vstatus = hdd_execute_global_config_command(hdd_ctx, pBuffer);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05306475 if (QDF_STATUS_SUCCESS != vstatus) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006476 ret = -EINVAL;
6477 }
6478 break;
6479 default:
6480 {
6481 hddLog(LOGE, "%s: Invalid sub command %d", __func__,
6482 sub_cmd);
6483 ret = -EINVAL;
6484 break;
6485 }
6486 }
6487 kfree(pBuffer);
Hanumantha Reddy Pothula2db50ed2015-11-23 10:48:33 +05306488 EXIT();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006489 return ret;
6490}
6491
6492static int iw_setchar_getnone(struct net_device *dev,
6493 struct iw_request_info *info,
6494 union iwreq_data *wrqu, char *extra)
6495{
6496 int ret;
6497
6498 cds_ssr_protect(__func__);
6499 ret = __iw_setchar_getnone(dev, info, wrqu, extra);
6500 cds_ssr_unprotect(__func__);
6501
6502 return ret;
6503}
6504
6505/**
6506 * iw_setnone_getint() - Generic "get integer" private ioctl handler
6507 * @dev: device upon which the ioctl was received
6508 * @info: ioctl request information
6509 * @wrqu: ioctl request data
6510 * @extra: ioctl extra data
6511 *
6512 * Return: 0 on success, non-zero on error
6513 */
6514static int __iw_setnone_getint(struct net_device *dev,
6515 struct iw_request_info *info,
6516 union iwreq_data *wrqu, char *extra)
6517{
6518 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6519 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
6520 int *value = (int *)extra;
6521 int ret;
6522 tSmeConfigParams smeConfig;
6523 hdd_context_t *hdd_ctx;
6524
Jeff Johnson6ee91ee2016-02-11 18:55:30 -08006525 ENTER_DEV(dev);
Hanumantha Reddy Pothula2db50ed2015-11-23 10:48:33 +05306526
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006527 hdd_ctx = WLAN_HDD_GET_CTX(pAdapter);
6528 ret = wlan_hdd_validate_context(hdd_ctx);
6529 if (0 != ret)
6530 return ret;
6531
6532 switch (value[0]) {
6533 case WE_GET_11D_STATE:
6534 {
6535 sme_get_config_param(hHal, &smeConfig);
6536
6537 *value = smeConfig.csrConfig.Is11dSupportEnabled;
6538
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05306539 QDF_TRACE(QDF_MODULE_ID_HDD, QDF_TRACE_LEVEL_INFO,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006540 ("11D state=%d!!"), *value);
6541
6542 break;
6543 }
6544
6545 case WE_IBSS_STATUS:
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05306546 QDF_TRACE(QDF_MODULE_ID_HDD, QDF_TRACE_LEVEL_INFO,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006547 "****Return IBSS Status*****");
6548 break;
6549
6550 case WE_GET_WLAN_DBG:
6551 {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05306552 qdf_trace_display();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006553 *value = 0;
6554 break;
6555 }
6556 case WE_GET_MAX_ASSOC:
6557 {
6558 if (sme_cfg_get_int
6559 (hHal, WNI_CFG_ASSOC_STA_LIMIT,
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05306560 (uint32_t *) value) != QDF_STATUS_SUCCESS) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05306561 QDF_TRACE(QDF_MODULE_ID_HDD,
6562 QDF_TRACE_LEVEL_WARN, FL
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006563 ("failed to get ini parameter, WNI_CFG_ASSOC_STA_LIMIT"));
6564 ret = -EIO;
6565 }
6566 break;
6567 }
6568 case WE_GET_SAP_AUTO_CHANNEL_SELECTION:
6569 *value = (WLAN_HDD_GET_CTX(
6570 pAdapter))->config->force_sap_acs;
6571 break;
6572
6573 case WE_GET_CONCURRENCY_MODE:
6574 {
6575 *value = cds_get_concurrency_mode();
6576
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05306577 QDF_TRACE(QDF_MODULE_ID_HDD, QDF_TRACE_LEVEL_INFO,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006578 ("concurrency mode=%d"), *value);
6579 break;
6580 }
6581
6582 case WE_GET_NSS:
6583 {
6584 sme_get_config_param(hHal, &smeConfig);
6585 *value = (smeConfig.csrConfig.enable2x2 == 0) ? 1 : 2;
6586 hddLog(LOG1, "GET_NSS: Current NSS:%d", *value);
6587 break;
6588 }
6589
6590 case WE_GET_GTX_HT_MCS:
6591 {
6592 hddLog(LOG1, "GET WMI_VDEV_PARAM_GTX_HT_MCS");
6593 *value = wma_cli_get_command(pAdapter->sessionId,
6594 WMI_VDEV_PARAM_GTX_HT_MCS,
6595 GTX_CMD);
6596 break;
6597 }
6598
6599 case WE_GET_GTX_VHT_MCS:
6600 {
6601 hddLog(LOG1, "GET WMI_VDEV_PARAM_GTX_VHT_MCS");
6602 *value = wma_cli_get_command(pAdapter->sessionId,
6603 WMI_VDEV_PARAM_GTX_VHT_MCS,
6604 GTX_CMD);
6605 break;
6606 }
6607
6608 case WE_GET_GTX_USRCFG:
6609 {
6610 hddLog(LOG1, "GET WMI_VDEV_PARAM_GTX_USR_CFG");
6611 *value = wma_cli_get_command(pAdapter->sessionId,
6612 WMI_VDEV_PARAM_GTX_USR_CFG,
6613 GTX_CMD);
6614 break;
6615 }
6616
6617 case WE_GET_GTX_THRE:
6618 {
6619 hddLog(LOG1, "GET WMI_VDEV_PARAM_GTX_THRE");
6620 *value = wma_cli_get_command(pAdapter->sessionId,
6621 WMI_VDEV_PARAM_GTX_THRE,
6622 GTX_CMD);
6623 break;
6624 }
6625
6626 case WE_GET_GTX_MARGIN:
6627 {
6628 hddLog(LOG1, "GET WMI_VDEV_PARAM_GTX_MARGIN");
6629 *value = wma_cli_get_command(pAdapter->sessionId,
6630 WMI_VDEV_PARAM_GTX_MARGIN,
6631 GTX_CMD);
6632 break;
6633 }
6634
6635 case WE_GET_GTX_STEP:
6636 {
6637 hddLog(LOG1, "GET WMI_VDEV_PARAM_GTX_STEP");
6638 *value = wma_cli_get_command(pAdapter->sessionId,
6639 WMI_VDEV_PARAM_GTX_STEP,
6640 GTX_CMD);
6641 break;
6642 }
6643
6644 case WE_GET_GTX_MINTPC:
6645 {
6646 hddLog(LOG1, "GET WMI_VDEV_PARAM_GTX_MINTPC");
6647 *value = wma_cli_get_command(pAdapter->sessionId,
6648 WMI_VDEV_PARAM_GTX_MINTPC,
6649 GTX_CMD);
6650 break;
6651 }
6652
6653 case WE_GET_GTX_BWMASK:
6654 {
6655 hddLog(LOG1, "GET WMI_VDEV_PARAM_GTX_BW_MASK");
6656 *value = wma_cli_get_command(pAdapter->sessionId,
6657 WMI_VDEV_PARAM_GTX_BW_MASK,
6658 GTX_CMD);
6659 break;
6660 }
6661
6662 case WE_GET_LDPC:
6663 {
6664 hddLog(LOG1, "GET WMI_VDEV_PARAM_LDPC");
6665 *value = sme_get_ht_config(hHal, pAdapter->sessionId,
6666 WNI_CFG_HT_CAP_INFO_ADVANCE_CODING);
6667 break;
6668 }
6669
6670 case WE_GET_TX_STBC:
6671 {
6672 hddLog(LOG1, "GET WMI_VDEV_PARAM_TX_STBC");
6673 *value = sme_get_ht_config(hHal, pAdapter->sessionId,
6674 WNI_CFG_HT_CAP_INFO_TX_STBC);
6675 break;
6676 }
6677
6678 case WE_GET_RX_STBC:
6679 {
6680 hddLog(LOG1, "GET WMI_VDEV_PARAM_RX_STBC");
6681 *value = sme_get_ht_config(hHal, pAdapter->sessionId,
6682 WNI_CFG_HT_CAP_INFO_RX_STBC);
6683 break;
6684 }
6685
6686 case WE_GET_SHORT_GI:
6687 {
6688 hddLog(LOG1, "GET WMI_VDEV_PARAM_SGI");
6689 *value = sme_get_ht_config(hHal, pAdapter->sessionId,
6690 WNI_CFG_HT_CAP_INFO_SHORT_GI_20MHZ);
6691 break;
6692 }
6693
6694 case WE_GET_RTSCTS:
6695 {
6696 hddLog(LOG1, "GET WMI_VDEV_PARAM_ENABLE_RTSCTS");
6697 *value = wma_cli_get_command(pAdapter->sessionId,
6698 WMI_VDEV_PARAM_ENABLE_RTSCTS,
6699 VDEV_CMD);
6700 break;
6701 }
6702
6703 case WE_GET_CHWIDTH:
6704 {
6705 hddLog(LOG1, "GET WMI_VDEV_PARAM_CHWIDTH");
6706 *value = wma_cli_get_command(pAdapter->sessionId,
6707 WMI_VDEV_PARAM_CHWIDTH,
6708 VDEV_CMD);
6709 break;
6710 }
6711
6712 case WE_GET_ANI_EN_DIS:
6713 {
6714 hddLog(LOG1, "GET WMI_PDEV_PARAM_ANI_ENABLE");
6715 *value = wma_cli_get_command(pAdapter->sessionId,
6716 WMI_PDEV_PARAM_ANI_ENABLE,
6717 PDEV_CMD);
6718 break;
6719 }
6720
6721 case WE_GET_ANI_POLL_PERIOD:
6722 {
6723 hddLog(LOG1, "GET WMI_PDEV_PARAM_ANI_POLL_PERIOD");
6724 *value = wma_cli_get_command(pAdapter->sessionId,
6725 WMI_PDEV_PARAM_ANI_POLL_PERIOD,
6726 PDEV_CMD);
6727 break;
6728 }
6729
6730 case WE_GET_ANI_LISTEN_PERIOD:
6731 {
6732 hddLog(LOG1, "GET WMI_PDEV_PARAM_ANI_LISTEN_PERIOD");
6733 *value = wma_cli_get_command(pAdapter->sessionId,
6734 WMI_PDEV_PARAM_ANI_LISTEN_PERIOD,
6735 PDEV_CMD);
6736 break;
6737 }
6738
6739 case WE_GET_ANI_OFDM_LEVEL:
6740 {
6741 hddLog(LOG1, "GET WMI_PDEV_PARAM_ANI_OFDM_LEVEL");
6742 *value = wma_cli_get_command(pAdapter->sessionId,
6743 WMI_PDEV_PARAM_ANI_OFDM_LEVEL,
6744 PDEV_CMD);
6745 break;
6746 }
6747
6748 case WE_GET_ANI_CCK_LEVEL:
6749 {
6750 hddLog(LOG1, "GET WMI_PDEV_PARAM_ANI_CCK_LEVEL");
6751 *value = wma_cli_get_command(pAdapter->sessionId,
6752 WMI_PDEV_PARAM_ANI_CCK_LEVEL,
6753 PDEV_CMD);
6754 break;
6755 }
6756
6757 case WE_GET_DYNAMIC_BW:
6758 {
6759 hddLog(LOG1, "GET WMI_PDEV_PARAM_ANI_CCK_LEVEL");
6760 *value = wma_cli_get_command(pAdapter->sessionId,
6761 WMI_PDEV_PARAM_DYNAMIC_BW,
6762 PDEV_CMD);
6763 break;
6764 }
6765
6766 case WE_GET_11N_RATE:
6767 {
6768 hddLog(LOG1, "GET WMI_VDEV_PARAM_FIXED_RATE");
6769 *value = wma_cli_get_command(pAdapter->sessionId,
6770 WMI_VDEV_PARAM_FIXED_RATE,
6771 VDEV_CMD);
6772 break;
6773 }
6774
6775 case WE_GET_AMPDU:
6776 {
6777 hddLog(LOG1, "GET AMPDU");
6778 *value = wma_cli_get_command(pAdapter->sessionId,
6779 GEN_VDEV_PARAM_AMPDU,
6780 GEN_CMD);
6781 break;
6782 }
6783
6784 case WE_GET_AMSDU:
6785 {
6786 hddLog(LOG1, "GET AMSDU");
6787 *value = wma_cli_get_command(pAdapter->sessionId,
6788 GEN_VDEV_PARAM_AMSDU,
6789 GEN_CMD);
6790 break;
6791 }
6792
6793 case WE_GET_BURST_ENABLE:
6794 {
6795 hddLog(LOG1, "GET Burst enable value");
6796 *value = wma_cli_get_command(pAdapter->sessionId,
6797 WMI_PDEV_PARAM_BURST_ENABLE,
6798 PDEV_CMD);
6799 break;
6800 }
6801 case WE_GET_BURST_DUR:
6802 {
6803 hddLog(LOG1, "GET Burst Duration value");
6804 *value = wma_cli_get_command(pAdapter->sessionId,
6805 WMI_PDEV_PARAM_BURST_DUR,
6806 PDEV_CMD);
6807 break;
6808 }
6809
6810 case WE_GET_TX_CHAINMASK:
6811 {
6812 hddLog(LOG1, "GET WMI_PDEV_PARAM_TX_CHAIN_MASK");
6813 *value = wma_cli_get_command(pAdapter->sessionId,
6814 WMI_PDEV_PARAM_TX_CHAIN_MASK,
6815 PDEV_CMD);
6816 break;
6817 }
6818
6819 case WE_GET_RX_CHAINMASK:
6820 {
6821 hddLog(LOG1, "GET WMI_PDEV_PARAM_RX_CHAIN_MASK");
6822 *value = wma_cli_get_command(pAdapter->sessionId,
6823 WMI_PDEV_PARAM_RX_CHAIN_MASK,
6824 PDEV_CMD);
6825 break;
6826 }
6827
6828 case WE_GET_TXPOW_2G:
6829 {
6830 uint32_t txpow2g = 0;
6831 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
6832 hddLog(LOG1, "GET WMI_PDEV_PARAM_TXPOWER_LIMIT2G");
6833 *value = wma_cli_get_command(pAdapter->sessionId,
6834 WMI_PDEV_PARAM_TXPOWER_LIMIT2G,
6835 PDEV_CMD);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05306836 if (QDF_STATUS_SUCCESS !=
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006837 sme_cfg_get_int(hHal, WNI_CFG_CURRENT_TX_POWER_LEVEL,
6838 &txpow2g)) {
6839 return -EIO;
6840 }
6841 hddLog(LOG1, "2G tx_power %d", txpow2g);
6842 break;
6843 }
6844
6845 case WE_GET_TXPOW_5G:
6846 {
6847 uint32_t txpow5g = 0;
6848 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
6849 hddLog(LOG1, "GET WMI_PDEV_PARAM_TXPOWER_LIMIT5G");
6850 *value = wma_cli_get_command(pAdapter->sessionId,
6851 WMI_PDEV_PARAM_TXPOWER_LIMIT5G,
6852 PDEV_CMD);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05306853 if (QDF_STATUS_SUCCESS !=
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006854 sme_cfg_get_int(hHal, WNI_CFG_CURRENT_TX_POWER_LEVEL,
6855 &txpow5g)) {
6856 return -EIO;
6857 }
6858 hddLog(LOG1, "5G tx_power %d", txpow5g);
6859 break;
6860 }
6861
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006862 case WE_GET_PPS_PAID_MATCH:
6863 {
6864 hddLog(LOG1, "GET WMI_VDEV_PPS_PAID_MATCH");
6865 *value = wma_cli_get_command(pAdapter->sessionId,
6866 WMI_VDEV_PPS_PAID_MATCH,
6867 PPS_CMD);
6868 break;
6869 }
6870
6871 case WE_GET_PPS_GID_MATCH:
6872 {
6873 hddLog(LOG1, "GET WMI_VDEV_PPS_GID_MATCH");
6874 *value = wma_cli_get_command(pAdapter->sessionId,
6875 WMI_VDEV_PPS_GID_MATCH,
6876 PPS_CMD);
6877 break;
6878 }
6879
6880 case WE_GET_PPS_EARLY_TIM_CLEAR:
6881 {
6882 hddLog(LOG1, "GET WMI_VDEV_PPS_EARLY_TIM_CLEAR");
6883 *value = wma_cli_get_command(pAdapter->sessionId,
6884 WMI_VDEV_PPS_EARLY_TIM_CLEAR,
6885 PPS_CMD);
6886 break;
6887 }
6888
6889 case WE_GET_PPS_EARLY_DTIM_CLEAR:
6890 {
6891 hddLog(LOG1, "GET WMI_VDEV_PPS_EARLY_DTIM_CLEAR");
6892 *value = wma_cli_get_command(pAdapter->sessionId,
6893 WMI_VDEV_PPS_EARLY_DTIM_CLEAR,
6894 PPS_CMD);
6895 break;
6896 }
6897
6898 case WE_GET_PPS_EOF_PAD_DELIM:
6899 {
6900 hddLog(LOG1, "GET WMI_VDEV_PPS_EOF_PAD_DELIM");
6901 *value = wma_cli_get_command(pAdapter->sessionId,
6902 WMI_VDEV_PPS_EOF_PAD_DELIM,
6903 PPS_CMD);
6904 break;
6905 }
6906
6907 case WE_GET_PPS_MACADDR_MISMATCH:
6908 {
6909 hddLog(LOG1, "GET WMI_VDEV_PPS_MACADDR_MISMATCH");
6910 *value = wma_cli_get_command(pAdapter->sessionId,
6911 WMI_VDEV_PPS_MACADDR_MISMATCH,
6912 PPS_CMD);
6913 break;
6914 }
6915
6916 case WE_GET_PPS_DELIM_CRC_FAIL:
6917 {
6918 hddLog(LOG1, "GET WMI_VDEV_PPS_DELIM_CRC_FAIL");
6919 *value = wma_cli_get_command(pAdapter->sessionId,
6920 WMI_VDEV_PPS_DELIM_CRC_FAIL,
6921 PPS_CMD);
6922 break;
6923 }
6924
6925 case WE_GET_PPS_GID_NSTS_ZERO:
6926 {
6927 hddLog(LOG1, "GET WMI_VDEV_PPS_GID_NSTS_ZERO");
6928 *value = wma_cli_get_command(pAdapter->sessionId,
6929 WMI_VDEV_PPS_GID_NSTS_ZERO,
6930 PPS_CMD);
6931 break;
6932 }
6933
6934 case WE_GET_PPS_RSSI_CHECK:
6935 {
6936
6937 hddLog(LOG1, "GET WMI_VDEV_PPS_RSSI_CHECK");
6938 *value = wma_cli_get_command(pAdapter->sessionId,
6939 WMI_VDEV_PPS_RSSI_CHECK,
6940 PPS_CMD);
6941 break;
6942 }
6943
6944 case WE_GET_QPOWER_MAX_PSPOLL_COUNT:
6945 {
6946 hddLog(LOG1, "WE_GET_QPOWER_MAX_PSPOLL_COUNT");
6947 *value = wma_cli_get_command(pAdapter->sessionId,
6948 WMI_STA_PS_PARAM_QPOWER_PSPOLL_COUNT,
6949 QPOWER_CMD);
6950 break;
6951 }
6952
6953 case WE_GET_QPOWER_MAX_TX_BEFORE_WAKE:
6954 {
6955 hddLog(LOG1, "WE_GET_QPOWER_MAX_TX_BEFORE_WAKE");
6956 *value = wma_cli_get_command(pAdapter->sessionId,
6957 WMI_STA_PS_PARAM_QPOWER_MAX_TX_BEFORE_WAKE,
6958 QPOWER_CMD);
6959 break;
6960 }
6961
6962 case WE_GET_QPOWER_SPEC_PSPOLL_WAKE_INTERVAL:
6963 {
6964 hddLog(LOG1, "WE_GET_QPOWER_SPEC_PSPOLL_WAKE_INTERVAL");
6965 *value = wma_cli_get_command(pAdapter->sessionId,
6966 WMI_STA_PS_PARAM_QPOWER_SPEC_PSPOLL_WAKE_INTERVAL,
6967 QPOWER_CMD);
6968 break;
6969 }
6970
6971 case WE_GET_QPOWER_SPEC_MAX_SPEC_NODATA_PSPOLL:
6972 {
6973 hddLog(LOG1, "WE_GET_QPOWER_MAX_PSPOLL_COUNT");
6974 *value = wma_cli_get_command(pAdapter->sessionId,
6975 WMI_STA_PS_PARAM_QPOWER_SPEC_MAX_SPEC_NODATA_PSPOLL,
6976 QPOWER_CMD);
6977 break;
6978 }
Manikandan Mohandcc21ba2016-03-15 14:31:56 -07006979 case WE_CAP_TSF:
6980 ret = hdd_capture_tsf(pAdapter, (uint32_t *)value, 1);
6981 break;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006982 case WE_GET_TEMPERATURE:
6983 {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05306984 hddLog(QDF_TRACE_LEVEL_INFO, "WE_GET_TEMPERATURE");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006985 ret = wlan_hdd_get_temperature(pAdapter, value);
6986 break;
6987 }
6988 default:
6989 {
6990 hddLog(LOGE, "Invalid IOCTL get_value command %d",
6991 value[0]);
6992 break;
6993 }
6994 }
Hanumantha Reddy Pothula2db50ed2015-11-23 10:48:33 +05306995 EXIT();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006996 return ret;
6997}
6998
6999static int iw_setnone_getint(struct net_device *dev,
7000 struct iw_request_info *info,
7001 union iwreq_data *wrqu, char *extra)
7002{
7003 int ret;
7004
7005 cds_ssr_protect(__func__);
7006 ret = __iw_setnone_getint(dev, info, wrqu, extra);
7007 cds_ssr_unprotect(__func__);
7008
7009 return ret;
7010}
7011
7012/**
7013 * iw_set_three_ints_getnone() - Generic "set 3 params" private ioctl handler
7014 * @dev: device upon which the ioctl was received
7015 * @info: ioctl request information
7016 * @wrqu: ioctl request data
7017 * @extra: ioctl extra data
7018 *
7019 * Return: 0 on success, non-zero on error
7020 */
7021static int __iw_set_three_ints_getnone(struct net_device *dev,
7022 struct iw_request_info *info,
7023 union iwreq_data *wrqu, char *extra)
7024{
7025 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
7026 int *value = (int *)extra;
7027 int sub_cmd = value[0];
7028 int ret;
7029 hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(pAdapter);
7030
Jeff Johnson6ee91ee2016-02-11 18:55:30 -08007031 ENTER_DEV(dev);
Hanumantha Reddy Pothula2db50ed2015-11-23 10:48:33 +05307032
Rajeev Kumar2cce8a82016-04-14 15:10:41 -07007033 if (!capable(CAP_NET_ADMIN)) {
7034 hddLog(LOGE, FL("permission check failed"));
7035 return -EPERM;
7036 }
7037
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007038 ret = wlan_hdd_validate_context(hdd_ctx);
7039 if (0 != ret)
7040 return ret;
7041
7042 switch (sub_cmd) {
7043
7044 case WE_SET_WLAN_DBG:
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05307045 qdf_trace_set_value(value[1], value[2], value[3]);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007046 break;
7047 case WE_SET_DP_TRACE:
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05307048 qdf_dp_trace_set_value(value[1], value[2], value[3]);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007049 break;
7050
7051 /* value[3] the acs band is not required as start and end channels are
7052 * enough but this cmd is maintained under set three ints for historic
7053 * reasons.
7054 */
7055 case WE_SET_SAP_CHANNELS:
7056 if (wlan_hdd_validate_operation_channel(pAdapter, value[1]) !=
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05307057 QDF_STATUS_SUCCESS ||
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007058 wlan_hdd_validate_operation_channel(pAdapter,
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05307059 value[2]) != QDF_STATUS_SUCCESS) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007060 ret = -EINVAL;
7061 } else {
7062 hdd_ctx->config->force_sap_acs_st_ch = value[1];
7063 hdd_ctx->config->force_sap_acs_end_ch = value[2];
7064 }
7065 break;
7066 case WE_SET_DUAL_MAC_SCAN_CONFIG:
7067 hdd_debug("Ioctl to set dual mac scan config");
7068 if (hdd_ctx->config->dual_mac_feature_disable) {
7069 hdd_err("Dual mac feature is disabled from INI");
7070 return -EPERM;
7071 }
7072 hdd_debug("%d %d %d", value[1], value[2], value[3]);
Tushnim Bhattacharyya4adb3682016-01-07 15:07:12 -08007073 cds_set_dual_mac_scan_config(value[1], value[2], value[3]);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007074 break;
7075 default:
7076 hddLog(LOGE, "%s: Invalid IOCTL command %d", __func__, sub_cmd);
7077 break;
7078
7079 }
Hanumantha Reddy Pothula2db50ed2015-11-23 10:48:33 +05307080 EXIT();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007081 return ret;
7082}
7083
7084int iw_set_three_ints_getnone(struct net_device *dev,
7085 struct iw_request_info *info,
7086 union iwreq_data *wrqu, char *extra)
7087{
7088 int ret;
7089
7090 cds_ssr_protect(__func__);
7091 ret = __iw_set_three_ints_getnone(dev, info, wrqu, extra);
7092 cds_ssr_unprotect(__func__);
7093
7094 return ret;
7095}
7096
7097/**
7098 * hdd_connection_state_string() - Get connection state string
7099 * @connection_state: enum to be converted to a string
7100 *
7101 * Return: the string equivalent of @connection_state
7102 */
7103static const char *
7104hdd_connection_state_string(eConnectionState connection_state)
7105{
7106 switch (connection_state) {
7107 CASE_RETURN_STRING(eConnectionState_NotConnected);
7108 CASE_RETURN_STRING(eConnectionState_Connecting);
7109 CASE_RETURN_STRING(eConnectionState_Associated);
7110 CASE_RETURN_STRING(eConnectionState_IbssDisconnected);
7111 CASE_RETURN_STRING(eConnectionState_IbssConnected);
7112 CASE_RETURN_STRING(eConnectionState_Disconnecting);
7113 default:
7114 return "UNKNOWN";
7115 }
7116}
7117
7118/**
7119 * iw_get_char_setnone() - Generic "get string" private ioctl handler
7120 * @dev: device upon which the ioctl was received
7121 * @info: ioctl request information
7122 * @wrqu: ioctl request data
7123 * @extra: ioctl extra data
7124 *
7125 * Return: 0 on success, non-zero on error
7126 */
7127static int __iw_get_char_setnone(struct net_device *dev,
7128 struct iw_request_info *info,
7129 union iwreq_data *wrqu, char *extra)
7130{
7131 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
7132 int sub_cmd = wrqu->data.flags;
7133 hdd_context_t *hdd_ctx;
7134 int ret;
7135#ifdef WLAN_FEATURE_11W
7136 hdd_wext_state_t *pWextState;
7137#endif
7138
7139#ifdef WLAN_FEATURE_11W
7140 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
7141#endif
7142
Jeff Johnson6ee91ee2016-02-11 18:55:30 -08007143 ENTER_DEV(dev);
Hanumantha Reddy Pothula2db50ed2015-11-23 10:48:33 +05307144
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007145 hdd_ctx = WLAN_HDD_GET_CTX(pAdapter);
7146 ret = wlan_hdd_validate_context(hdd_ctx);
7147 if (0 != ret)
7148 return ret;
7149
7150 switch (sub_cmd) {
7151 case WE_WLAN_VERSION:
7152 {
7153 hdd_wlan_get_version(pAdapter, wrqu, extra);
7154 break;
7155 }
7156
7157 case WE_GET_STATS:
7158 {
7159 hdd_wlan_get_stats(pAdapter, &(wrqu->data.length),
7160 extra, WE_MAX_STR_LEN);
7161 break;
7162 }
7163
Govind Singha471e5e2015-10-12 17:11:14 +05307164 case WE_LIST_FW_PROFILE:
7165 hdd_wlan_list_fw_profile(&(wrqu->data.length),
7166 extra, WE_MAX_STR_LEN);
7167 break;
7168
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007169 /* The case prints the current state of the HDD, SME, CSR, PE,
7170 * TL it can be extended for WDI Global State as well. And
7171 * currently it only checks P2P_CLIENT adapter. P2P_DEVICE
7172 * and P2P_GO have not been added as of now.
7173 */
7174 case WE_GET_STATES:
7175 {
7176 int buf = 0, len = 0;
7177 int adapter_num = 0;
7178 int count = 0, check = 1;
7179
7180 tHalHandle hHal = NULL;
7181 tpAniSirGlobal pMac = NULL;
7182 hdd_station_ctx_t *pHddStaCtx = NULL;
7183
7184 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7185 hdd_adapter_t *useAdapter = NULL;
7186
7187 /* Print wlan0 or p2p0 states based on the adapter_num
7188 * by using the correct adapter
7189 */
7190 while (adapter_num < 2) {
7191 if (WLAN_ADAPTER == adapter_num) {
7192 useAdapter = pAdapter;
7193 buf =
7194 scnprintf(extra + len,
7195 WE_MAX_STR_LEN - len,
7196 "\n\n wlan0 States:-");
7197 len += buf;
7198 } else if (P2P_ADAPTER == adapter_num) {
7199 buf =
7200 scnprintf(extra + len,
7201 WE_MAX_STR_LEN - len,
7202 "\n\n p2p0 States:-");
7203 len += buf;
7204
7205 if (!pHddCtx) {
7206 buf =
7207 scnprintf(extra + len,
7208 WE_MAX_STR_LEN -
7209 len,
7210 "\n pHddCtx is NULL");
7211 len += buf;
7212 break;
7213 }
7214
7215 /* Printing p2p0 states only in the
7216 * case when the device is configured
7217 * as a p2p_client
7218 */
7219 useAdapter =
7220 hdd_get_adapter(pHddCtx,
Krunal Sonif07bb382016-03-10 13:02:11 -08007221 QDF_P2P_CLIENT_MODE);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007222 if (!useAdapter) {
7223 buf =
7224 scnprintf(extra + len,
7225 WE_MAX_STR_LEN -
7226 len,
7227 "\n Device not configured as P2P_CLIENT.");
7228 len += buf;
7229 break;
7230 }
7231 }
7232
7233 hHal = WLAN_HDD_GET_HAL_CTX(useAdapter);
7234 if (!hHal) {
7235 buf =
7236 scnprintf(extra + len,
7237 WE_MAX_STR_LEN - len,
7238 "\n pMac is NULL");
7239 len += buf;
7240 break;
7241 }
7242 pMac = PMAC_STRUCT(hHal);
7243 if (!pMac) {
7244 buf =
7245 scnprintf(extra + len,
7246 WE_MAX_STR_LEN - len,
7247 "\n pMac is NULL");
7248 len += buf;
7249 break;
7250 }
7251 pHddStaCtx =
7252 WLAN_HDD_GET_STATION_CTX_PTR(useAdapter);
7253
7254
7255 buf =
7256 scnprintf(extra + len, WE_MAX_STR_LEN - len,
7257 "\n HDD Conn State - %s "
7258 "\n \n SME State:"
7259 "\n Neighbour Roam State - %s"
7260 "\n CSR State - %s"
7261 "\n CSR Substate - %s",
7262 hdd_connection_state_string
7263 (pHddStaCtx->conn_info.connState),
7264 mac_trace_get_neighbour_roam_state
7265 (sme_get_neighbor_roam_state
7266 (hHal, useAdapter->sessionId)),
7267 mac_trace_getcsr_roam_state
7268 (sme_get_current_roam_state
7269 (hHal, useAdapter->sessionId)),
7270 mac_trace_getcsr_roam_sub_state
7271 (sme_get_current_roam_sub_state
7272 (hHal, useAdapter->sessionId))
7273 );
7274 len += buf;
7275 adapter_num++;
7276 }
7277
Mukul Sharma81661ae2015-10-30 20:26:02 +05307278 if (hHal) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007279 /* Printing Lim State starting with global lim states */
7280 buf =
7281 scnprintf(extra + len, WE_MAX_STR_LEN - len,
7282 "\n \n LIM STATES:-"
7283 "\n Global Sme State - %s "
7284 "\n Global mlm State - %s " "\n",
7285 mac_trace_get_lim_sme_state
7286 (sme_get_lim_sme_state(hHal)),
7287 mac_trace_get_lim_mlm_state
7288 (sme_get_lim_sme_state(hHal))
7289 );
7290 len += buf;
7291
7292 /* Printing the PE Sme and Mlm states for valid lim sessions */
7293 while (check < 3 && count < 255) {
7294 if (sme_is_lim_session_valid(hHal, count)) {
7295 buf =
7296 scnprintf(extra + len,
7297 WE_MAX_STR_LEN -
7298 len,
7299 "\n Lim Valid Session %d:-"
7300 "\n PE Sme State - %s "
7301 "\n PE Mlm State - %s "
7302 "\n", check,
7303 mac_trace_get_lim_sme_state
7304 (sme_get_lim_sme_session_state
7305 (hHal, count)),
7306 mac_trace_get_lim_mlm_state
7307 (sme_get_lim_mlm_session_state
7308 (hHal, count))
7309 );
7310
7311 len += buf;
7312 check++;
7313 }
7314 count++;
7315 }
7316 }
7317
7318 wrqu->data.length = strlen(extra) + 1;
7319 break;
7320 }
7321
7322 case WE_GET_CFG:
7323 {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05307324 QDF_TRACE(QDF_MODULE_ID_HDD, QDF_TRACE_LEVEL_INFO,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007325 "%s: Printing CLD global INI Config",
7326 __func__);
7327 hdd_cfg_get_global_config(WLAN_HDD_GET_CTX(pAdapter),
7328 extra,
7329 QCSAP_IOCTL_MAX_STR_LEN);
7330 wrqu->data.length = strlen(extra) + 1;
7331 break;
7332 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007333 case WE_GET_RSSI:
7334 {
7335 int8_t s7Rssi = 0;
7336 wlan_hdd_get_rssi(pAdapter, &s7Rssi);
7337 snprintf(extra, WE_MAX_STR_LEN, "rssi=%d", s7Rssi);
7338 wrqu->data.length = strlen(extra) + 1;
7339 break;
7340 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007341
7342 case WE_GET_WMM_STATUS:
7343 {
7344 snprintf(extra, WE_MAX_STR_LEN,
7345 "\nDir: 0=up, 1=down, 3=both\n"
7346 "|------------------------|\n"
7347 "|AC | ACM |Admitted| Dir |\n"
7348 "|------------------------|\n"
7349 "|VO | %d | %3s | %d |\n"
7350 "|VI | %d | %3s | %d |\n"
7351 "|BE | %d | %3s | %d |\n"
7352 "|BK | %d | %3s | %d |\n"
7353 "|------------------------|\n",
7354 pAdapter->hddWmmStatus.
7355 wmmAcStatus[SME_AC_VO].wmmAcAccessRequired,
7356 pAdapter->hddWmmStatus.
7357 wmmAcStatus[SME_AC_VO].
7358 wmmAcAccessAllowed ? "YES" : "NO",
7359 pAdapter->hddWmmStatus.
7360 wmmAcStatus[SME_AC_VO].wmmAcTspecInfo.
7361 ts_info.direction,
7362 pAdapter->hddWmmStatus.
7363 wmmAcStatus[SME_AC_VI].wmmAcAccessRequired,
7364 pAdapter->hddWmmStatus.
7365 wmmAcStatus[SME_AC_VI].
7366 wmmAcAccessAllowed ? "YES" : "NO",
7367 pAdapter->hddWmmStatus.
7368 wmmAcStatus[SME_AC_VI].wmmAcTspecInfo.
7369 ts_info.direction,
7370 pAdapter->hddWmmStatus.
7371 wmmAcStatus[SME_AC_BE].wmmAcAccessRequired,
7372 pAdapter->hddWmmStatus.
7373 wmmAcStatus[SME_AC_BE].
7374 wmmAcAccessAllowed ? "YES" : "NO",
7375 pAdapter->hddWmmStatus.
7376 wmmAcStatus[SME_AC_BE].wmmAcTspecInfo.
7377 ts_info.direction,
7378 pAdapter->hddWmmStatus.
7379 wmmAcStatus[SME_AC_BK].wmmAcAccessRequired,
7380 pAdapter->hddWmmStatus.
7381 wmmAcStatus[SME_AC_BK].
7382 wmmAcAccessAllowed ? "YES" : "NO",
7383 pAdapter->hddWmmStatus.
7384 wmmAcStatus[SME_AC_BK].wmmAcTspecInfo.
7385 ts_info.direction);
7386
7387 wrqu->data.length = strlen(extra) + 1;
7388 break;
7389 }
7390 case WE_GET_CHANNEL_LIST:
7391 {
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05307392 QDF_STATUS status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007393 uint8_t i, len;
7394 char *buf;
7395 uint8_t ubuf[WNI_CFG_COUNTRY_CODE_LEN];
7396 uint8_t ubuf_len = WNI_CFG_COUNTRY_CODE_LEN;
7397 hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(pAdapter);
7398
7399 tChannelListInfo channel_list;
7400
7401 memset(&channel_list, 0, sizeof(channel_list));
7402 status =
7403 iw_softap_get_channel_list(dev, info, wrqu,
7404 (char *)&channel_list);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05307405 if (!QDF_IS_STATUS_SUCCESS(status)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007406 hddLog(LOGE, FL("GetChannelList Failed!!!"));
7407 return -EINVAL;
7408 }
7409 buf = extra;
7410 /*
7411 * Maximum channels = WNI_CFG_VALID_CHANNEL_LIST_LEN.
7412 * Maximum buffer needed = 5 * number of channels.
7413 * Check ifsufficient buffer is available and then
7414 * proceed to fill the buffer.
7415 */
7416 if (WE_MAX_STR_LEN <
7417 (5 * WNI_CFG_VALID_CHANNEL_LIST_LEN)) {
7418 hddLog(LOGE,
7419 FL("Insufficient Buffer to populate channel list"));
7420 return -EINVAL;
7421 }
7422 len = scnprintf(buf, WE_MAX_STR_LEN, "%u ",
7423 channel_list.num_channels);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05307424 if (QDF_STATUS_SUCCESS == sme_get_country_code(hdd_ctx->hHal,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007425 ubuf, &ubuf_len)) {
7426 /* Printing Country code in getChannelList */
7427 for (i = 0; i < (ubuf_len - 1); i++)
7428 len += scnprintf(buf + len,
7429 WE_MAX_STR_LEN - len,
7430 "%c", ubuf[i]);
7431 }
7432 for (i = 0; i < channel_list.num_channels; i++) {
7433 len +=
7434 scnprintf(buf + len, WE_MAX_STR_LEN - len,
7435 " %u", channel_list.channels[i]);
7436 }
7437 wrqu->data.length = strlen(extra) + 1;
7438
7439 break;
7440 }
7441#ifdef FEATURE_WLAN_TDLS
7442 case WE_GET_TDLS_PEERS:
7443 {
7444 wrqu->data.length =
7445 wlan_hdd_tdls_get_all_peers(pAdapter, extra,
7446 WE_MAX_STR_LEN) + 1;
7447 break;
7448 }
7449#endif
7450#ifdef WLAN_FEATURE_11W
7451 case WE_GET_11W_INFO:
7452 {
7453 hddLog(LOGE, "WE_GET_11W_ENABLED = %d",
7454 pWextState->roamProfile.MFPEnabled);
7455
7456 snprintf(extra, WE_MAX_STR_LEN,
7457 "\n BSSID %02X:%02X:%02X:%02X:%02X:%02X, Is PMF Assoc? %d"
7458 "\n Number of Unprotected Disassocs %d"
7459 "\n Number of Unprotected Deauths %d",
7460 pWextState->roamProfile.BSSIDs.bssid->bytes[0],
7461 pWextState->roamProfile.BSSIDs.bssid->bytes[1],
7462 pWextState->roamProfile.BSSIDs.bssid->bytes[2],
7463 pWextState->roamProfile.BSSIDs.bssid->bytes[3],
7464 pWextState->roamProfile.BSSIDs.bssid->bytes[4],
7465 pWextState->roamProfile.BSSIDs.bssid->bytes[5],
7466 pWextState->roamProfile.MFPEnabled,
7467 pAdapter->hdd_stats.hddPmfStats.
7468 numUnprotDisassocRx,
7469 pAdapter->hdd_stats.hddPmfStats.
7470 numUnprotDeauthRx);
7471
7472 wrqu->data.length = strlen(extra) + 1;
7473 break;
7474 }
7475#endif
Rajeev Kumar8e3e2832015-11-06 16:02:54 -08007476 case WE_GET_IBSS_STA_INFO:
7477 {
7478 hdd_station_ctx_t *pHddStaCtx =
7479 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7480 int idx = 0;
7481 int length = 0, buf = 0;
7482
7483 for (idx = 0; idx < MAX_IBSS_PEERS; idx++) {
7484 if (0 != pHddStaCtx->conn_info.staId[idx]) {
7485 buf = snprintf
7486 ((extra + length),
7487 WE_MAX_STR_LEN - length,
7488 "\n%d .%02x:%02x:%02x:%02x:%02x:%02x\n",
7489 pHddStaCtx->conn_info.staId[idx],
7490 pHddStaCtx->conn_info.
7491 peerMacAddress[idx].bytes[0],
7492 pHddStaCtx->conn_info.
7493 peerMacAddress[idx].bytes[1],
7494 pHddStaCtx->conn_info.
7495 peerMacAddress[idx].bytes[2],
7496 pHddStaCtx->conn_info.
7497 peerMacAddress[idx].bytes[3],
7498 pHddStaCtx->conn_info.
7499 peerMacAddress[idx].bytes[4],
7500 pHddStaCtx->conn_info.
7501 peerMacAddress[idx].bytes[5]
7502 );
7503 length += buf;
7504 }
7505 }
7506 wrqu->data.length = strlen(extra) + 1;
7507 break;
7508 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007509 case WE_GET_PHYMODE:
7510 {
7511 bool ch_bond24 = false, ch_bond5g = false;
7512 hdd_context_t *hddctx = WLAN_HDD_GET_CTX(pAdapter);
7513 tHalHandle hal = WLAN_HDD_GET_HAL_CTX(pAdapter);
7514 eCsrPhyMode phymode;
7515 eCsrBand currBand;
7516 tSmeConfigParams smeconfig;
7517
7518 sme_get_config_param(hal, &smeconfig);
7519 if (WNI_CFG_CHANNEL_BONDING_MODE_DISABLE !=
7520 smeconfig.csrConfig.channelBondingMode24GHz)
7521 ch_bond24 = true;
7522
7523 if (WNI_CFG_CHANNEL_BONDING_MODE_DISABLE !=
7524 smeconfig.csrConfig.channelBondingMode5GHz)
7525 ch_bond5g = true;
7526
7527 phymode = sme_get_phy_mode(hal);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05307528 if ((QDF_STATUS_SUCCESS !=
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007529 sme_get_freq_band(hal, &currBand))) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05307530 QDF_TRACE(QDF_MODULE_ID_HDD,
7531 QDF_TRACE_LEVEL_INFO,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007532 "%s: Failed to get current band config",
7533 __func__);
7534 return -EIO;
7535 }
7536
7537 switch (phymode) {
7538 case eCSR_DOT11_MODE_AUTO:
7539 snprintf(extra, WE_MAX_STR_LEN, "AUTO MODE");
7540 break;
7541 case eCSR_DOT11_MODE_11n:
7542 case eCSR_DOT11_MODE_11n_ONLY:
7543 if (currBand == eCSR_BAND_24) {
7544 if (ch_bond24)
7545 snprintf(extra, WE_MAX_STR_LEN,
7546 "11NGHT40");
7547 else
7548 snprintf(extra, WE_MAX_STR_LEN,
7549 "11NGHT20");
7550 } else if (currBand == eCSR_BAND_5G) {
7551 if (ch_bond5g)
7552 snprintf(extra, WE_MAX_STR_LEN,
7553 "11NAHT40");
7554 else
7555 snprintf(extra, WE_MAX_STR_LEN,
7556 "11NAHT20");
7557 } else {
7558 snprintf(extra, WE_MAX_STR_LEN, "11N");
7559 }
7560 break;
7561 case eCSR_DOT11_MODE_abg:
7562 snprintf(extra, WE_MAX_STR_LEN, "11ABG");
7563 break;
7564 case eCSR_DOT11_MODE_11a:
7565 snprintf(extra, WE_MAX_STR_LEN, "11A");
7566 break;
7567 case eCSR_DOT11_MODE_11b:
7568 case eCSR_DOT11_MODE_11b_ONLY:
7569 snprintf(extra, WE_MAX_STR_LEN, "11B");
7570 break;
7571 case eCSR_DOT11_MODE_11g:
7572 case eCSR_DOT11_MODE_11g_ONLY:
7573 snprintf(extra, WE_MAX_STR_LEN, "11G");
7574 break;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007575 case eCSR_DOT11_MODE_11ac:
7576 case eCSR_DOT11_MODE_11ac_ONLY:
7577 if (hddctx->config->vhtChannelWidth ==
7578 eHT_CHANNEL_WIDTH_20MHZ)
7579 snprintf(extra, WE_MAX_STR_LEN,
7580 "11ACVHT20");
7581 else if (hddctx->config->vhtChannelWidth ==
7582 eHT_CHANNEL_WIDTH_40MHZ)
7583 snprintf(extra, WE_MAX_STR_LEN,
7584 "11ACVHT40");
7585 else if (hddctx->config->vhtChannelWidth ==
7586 eHT_CHANNEL_WIDTH_80MHZ)
7587 snprintf(extra, WE_MAX_STR_LEN,
7588 "11ACVHT80");
7589 else if (hddctx->config->vhtChannelWidth ==
7590 eHT_CHANNEL_WIDTH_160MHZ)
7591 snprintf(extra, WE_MAX_STR_LEN,
7592 "11ACVHT160");
7593 break;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007594 }
7595
7596 wrqu->data.length = strlen(extra) + 1;
7597 break;
7598 }
7599
7600#ifdef FEATURE_OEM_DATA_SUPPORT
7601 case WE_GET_OEM_DATA_CAP:
7602 {
7603 return iw_get_oem_data_cap(dev, info, wrqu, extra);
7604 }
7605#endif /* FEATURE_OEM_DATA_SUPPORT */
7606 case WE_GET_SNR:
7607 {
7608 int8_t s7snr = 0;
7609 int status = 0;
7610 hdd_context_t *pHddCtx;
7611 hdd_station_ctx_t *pHddStaCtx;
7612 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7613 status = wlan_hdd_validate_context(pHddCtx);
7614 if (0 != status) {
7615 hddLog(LOGE,
7616 "%s: getSNR: HDD context is not valid",
7617 __func__);
7618 return status;
7619 }
7620 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7621 if (0 == pHddCtx->config->fEnableSNRMonitoring ||
7622 eConnectionState_Associated !=
7623 pHddStaCtx->conn_info.connState) {
7624 hddLog(LOGE,
7625 "%s: getSNR failed: Enable SNR Monitoring-%d,"
7626 " ConnectionState-%d", __func__,
7627 pHddCtx->config->fEnableSNRMonitoring,
7628 pHddStaCtx->conn_info.connState);
7629 return -ENONET;
7630 }
7631 wlan_hdd_get_snr(pAdapter, &s7snr);
7632 snprintf(extra, WE_MAX_STR_LEN, "snr=%d", s7snr);
7633 wrqu->data.length = strlen(extra) + 1;
7634 break;
7635 }
7636 default:
7637 {
7638 hddLog(LOGE, "%s: Invalid IOCTL command %d", __func__,
7639 sub_cmd);
7640 break;
7641 }
7642 }
Hanumantha Reddy Pothula2db50ed2015-11-23 10:48:33 +05307643 EXIT();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007644 return 0;
7645}
7646
7647static int iw_get_char_setnone(struct net_device *dev,
7648 struct iw_request_info *info,
7649 union iwreq_data *wrqu, char *extra)
7650{
7651 int ret;
7652
7653 cds_ssr_protect(__func__);
7654 ret = __iw_get_char_setnone(dev, info, wrqu, extra);
7655 cds_ssr_unprotect(__func__);
7656
7657 return ret;
7658}
7659
7660/**
7661 * iw_setnone_getnone() - Generic "action" private ioctl handler
7662 * @dev: device upon which the ioctl was received
7663 * @info: ioctl request information
7664 * @wrqu: ioctl request data
7665 * @extra: ioctl extra data
7666 *
7667 * Return: 0 on success, non-zero on error
7668 */
7669static int __iw_setnone_getnone(struct net_device *dev,
7670 struct iw_request_info *info,
7671 union iwreq_data *wrqu, char *extra)
7672{
Sandeep Puligilla93a29ec2016-02-12 16:10:56 -08007673 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007674 hdd_context_t *hdd_ctx;
7675 int ret;
7676 int sub_cmd;
7677
Jeff Johnson6ee91ee2016-02-11 18:55:30 -08007678 ENTER_DEV(dev);
Hanumantha Reddy Pothula2db50ed2015-11-23 10:48:33 +05307679
Sandeep Puligilla93a29ec2016-02-12 16:10:56 -08007680 hdd_ctx = WLAN_HDD_GET_CTX(adapter);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007681 ret = wlan_hdd_validate_context(hdd_ctx);
7682 if (0 != ret)
7683 return ret;
7684
7685#ifdef CONFIG_COMPAT
7686 /* this ioctl is a special case where a sub-ioctl is used and both
7687 * the number of get and set args is 0. in this specific case the
7688 * logic in iwpriv places the sub_cmd in the data.flags portion of
7689 * the iwreq. unfortunately the location of this field will be
7690 * different between 32-bit and 64-bit userspace, and the standard
7691 * compat support in the kernel does not handle this case. so we
7692 * need to explicitly handle it here.
7693 */
7694 if (is_compat_task()) {
7695 struct compat_iw_point *compat_iw_point =
7696 (struct compat_iw_point *)&wrqu->data;
7697 sub_cmd = compat_iw_point->flags;
7698 } else {
7699 sub_cmd = wrqu->data.flags;
7700 }
7701#else
7702 sub_cmd = wrqu->data.flags;
7703#endif
7704
7705 switch (sub_cmd) {
7706 case WE_GET_RECOVERY_STAT:
7707 {
Sandeep Puligilla93a29ec2016-02-12 16:10:56 -08007708 tHalHandle hal = WLAN_HDD_GET_HAL_CTX(adapter);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007709 sme_get_recovery_stats(hal);
7710 break;
7711 }
7712
Govind Singha471e5e2015-10-12 17:11:14 +05307713 case WE_GET_FW_PROFILE_DATA:
Sandeep Puligilla93a29ec2016-02-12 16:10:56 -08007714 ret = wma_cli_set_command(adapter->sessionId,
Govind Singha471e5e2015-10-12 17:11:14 +05307715 WMI_WLAN_PROFILE_GET_PROFILE_DATA_CMDID,
7716 0, DBG_CMD);
7717 break;
7718
Rajeev Kumar8e3e2832015-11-06 16:02:54 -08007719 case WE_IBSS_GET_PEER_INFO_ALL:
7720 {
7721 hdd_wlan_get_ibss_peer_info_all(adapter);
7722 break;
7723 }
7724
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007725 case WE_SET_REASSOC_TRIGGER:
7726 {
Sandeep Puligilla93a29ec2016-02-12 16:10:56 -08007727 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
7728 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(adapter);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007729 uint32_t roamId = 0;
7730 tCsrRoamModifyProfileFields modProfileFields;
7731 hdd_station_ctx_t *hdd_sta_ctx =
Sandeep Puligilla93a29ec2016-02-12 16:10:56 -08007732 WLAN_HDD_GET_STATION_CTX_PTR(adapter);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007733
7734 /* Reassoc to same AP, only supported for Open Security*/
7735 if ((hdd_sta_ctx->conn_info.ucEncryptionType ||
7736 hdd_sta_ctx->conn_info.mcEncryptionType)) {
7737 hddLog(LOGE,
7738 FL("Reassoc to same AP, only supported for Open Security"));
7739 return -ENOTSUPP;
7740 }
7741
Sandeep Puligilla93a29ec2016-02-12 16:10:56 -08007742 sme_get_modify_profile_fields(hHal, adapter->sessionId,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007743 &modProfileFields);
Sandeep Puligilla93a29ec2016-02-12 16:10:56 -08007744 sme_roam_reassoc(hHal, adapter->sessionId,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007745 NULL, modProfileFields, &roamId, 1);
7746 return 0;
7747 }
7748
7749 case WE_DUMP_AGC_START:
7750 {
7751 hddLog(LOG1, "WE_DUMP_AGC_START");
Sandeep Puligilla93a29ec2016-02-12 16:10:56 -08007752 ret = wma_cli_set_command(adapter->sessionId,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007753 GEN_PARAM_DUMP_AGC_START,
7754 0, GEN_CMD);
7755 break;
7756 }
7757 case WE_DUMP_AGC:
7758 {
7759 hddLog(LOG1, "WE_DUMP_AGC");
Sandeep Puligilla93a29ec2016-02-12 16:10:56 -08007760 ret = wma_cli_set_command(adapter->sessionId,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007761 GEN_PARAM_DUMP_AGC,
7762 0, GEN_CMD);
7763 break;
7764 }
7765
7766 case WE_DUMP_CHANINFO_START:
7767 {
7768 hddLog(LOG1, "WE_DUMP_CHANINFO_START");
Sandeep Puligilla93a29ec2016-02-12 16:10:56 -08007769 ret = wma_cli_set_command(adapter->sessionId,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007770 GEN_PARAM_DUMP_CHANINFO_START,
7771 0, GEN_CMD);
7772 break;
7773 }
7774 case WE_DUMP_CHANINFO:
7775 {
7776 hddLog(LOG1, "WE_DUMP_CHANINFO_START");
Sandeep Puligilla93a29ec2016-02-12 16:10:56 -08007777 ret = wma_cli_set_command(adapter->sessionId,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007778 GEN_PARAM_DUMP_CHANINFO,
7779 0, GEN_CMD);
7780 break;
7781 }
7782 case WE_DUMP_WATCHDOG:
7783 {
7784 hddLog(LOG1, "WE_DUMP_WATCHDOG");
Sandeep Puligilla93a29ec2016-02-12 16:10:56 -08007785 ret = wma_cli_set_command(adapter->sessionId,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007786 GEN_PARAM_DUMP_WATCHDOG,
7787 0, GEN_CMD);
7788 break;
7789 }
7790#ifdef CONFIG_ATH_PCIE_ACCESS_DEBUG
7791 case WE_DUMP_PCIE_LOG:
7792 {
7793 hddLog(LOGE, "WE_DUMP_PCIE_LOG");
Sandeep Puligilla93a29ec2016-02-12 16:10:56 -08007794 ret = wma_cli_set_command(adapter->sessionId,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007795 GEN_PARAM_DUMP_PCIE_ACCESS_LOG,
7796 0, GEN_CMD);
7797 break;
7798 }
7799#endif
Sandeep Puligilla93a29ec2016-02-12 16:10:56 -08007800 case WE_STOP_OBSS_SCAN:
7801 {
7802 /*
7803 * 1.OBSS Scan is mandatory while operating in 2.4GHz
7804 * 2.OBSS scan is stopped by Firmware during the disassociation
7805 * 3.OBSS stop comamnd is added for debugging purpose
7806 */
7807 tHalHandle hal;
7808
7809 hal = WLAN_HDD_GET_HAL_CTX(adapter);
7810 if (hal == NULL) {
7811 hdd_err("hal context is NULL");
7812 return -EINVAL;
7813 }
7814 sme_ht40_stop_obss_scan(hal, adapter->sessionId);
7815 }
7816 break;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007817 default:
7818 {
7819 hddLog(LOGE, "%s: unknown ioctl %d", __func__, sub_cmd);
7820 break;
7821 }
7822 }
Hanumantha Reddy Pothula2db50ed2015-11-23 10:48:33 +05307823 EXIT();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007824 return ret;
7825}
7826
7827static int iw_setnone_getnone(struct net_device *dev,
7828 struct iw_request_info *info,
7829 union iwreq_data *wrqu, char *extra)
7830{
7831 int ret;
7832
7833 cds_ssr_protect(__func__);
7834 ret = __iw_setnone_getnone(dev, info, wrqu, extra);
7835 cds_ssr_unprotect(__func__);
7836
7837 return ret;
7838}
7839
7840/**
7841 * __iw_set_var_ints_getnone - Generic "set many" private ioctl handler
7842 * @dev: device upon which the ioctl was received
7843 * @info: ioctl request information
7844 * @wrqu: ioctl request data
7845 * @extra: ioctl extra data
7846 *
7847 * This is an SSR-protected generic handler for private ioctls which
7848 * take multiple arguments. Note that this implementation is also
7849 * somewhat unique in that it is shared by both STA-mode and SAP-mode
7850 * interfaces.
7851 *
7852 * Return: 0 on success, non-zero on error
7853 */
7854static int __iw_set_var_ints_getnone(struct net_device *dev,
7855 struct iw_request_info *info,
7856 union iwreq_data *wrqu, char *extra)
7857{
7858 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
7859 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
7860 int sub_cmd;
7861 int *apps_args = (int *) extra;
7862 hdd_context_t *hdd_ctx;
7863 int ret, num_args;
7864
Jeff Johnson6ee91ee2016-02-11 18:55:30 -08007865 ENTER_DEV(dev);
Hanumantha Reddy Pothula2db50ed2015-11-23 10:48:33 +05307866
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007867 hdd_ctx = WLAN_HDD_GET_CTX(pAdapter);
7868 ret = wlan_hdd_validate_context(hdd_ctx);
7869 if (0 != ret)
7870 return ret;
7871
7872 if (extra == NULL) {
7873 hddLog(LOGE, FL("NULL extra buffer pointer"));
7874 return -EINVAL;
7875 }
7876
7877 sub_cmd = wrqu->data.flags;
7878 num_args = wrqu->data.length;
7879
7880 hddLog(LOG1, FL("Received length %d"), wrqu->data.length);
7881
7882 switch (sub_cmd) {
Rajeev Kumar8e3e2832015-11-06 16:02:54 -08007883 case WE_IBSS_GET_PEER_INFO:
7884 {
7885 pr_info("Station ID = %d\n", apps_args[0]);
7886 hdd_wlan_get_ibss_peer_info(pAdapter, apps_args[0]);
7887 }
7888 break;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007889
7890 case WE_P2P_NOA_CMD:
7891 {
7892 p2p_app_setP2pPs_t p2pNoA;
7893
Krunal Sonif07bb382016-03-10 13:02:11 -08007894 if (pAdapter->device_mode != QDF_P2P_GO_MODE) {
Rajeev Kumar274034c2015-11-23 11:28:58 -08007895 hdd_err("Setting NoA is not allowed in Device mode %s(%d)",
7896 hdd_device_mode_to_string(
7897 pAdapter->device_mode),
7898 pAdapter->device_mode);
7899 return -EINVAL;
7900 }
7901
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007902 p2pNoA.opp_ps = apps_args[0];
7903 p2pNoA.ctWindow = apps_args[1];
7904 p2pNoA.duration = apps_args[2];
7905 p2pNoA.interval = apps_args[3];
7906 p2pNoA.count = apps_args[4];
7907 p2pNoA.single_noa_duration = apps_args[5];
7908 p2pNoA.psSelection = apps_args[6];
7909
7910 hddLog(LOG1,
7911 "%s: P2P_NOA_ATTR:oppPS %d ctWindow %d duration %d "
7912 "interval %d count %d single noa duration %d PsSelection %x",
7913 __func__, apps_args[0], apps_args[1],
7914 apps_args[2], apps_args[3], apps_args[4],
7915 apps_args[5], apps_args[6]);
7916
7917 hdd_set_p2p_ps(dev, &p2pNoA);
7918
7919 }
7920 break;
7921
7922 case WE_MTRACE_SELECTIVE_MODULE_LOG_ENABLE_CMD:
7923 {
7924 hddLog(LOG1, "%s: SELECTIVE_MODULE_LOG %d arg1 %d arg2",
7925 __func__, apps_args[0], apps_args[1]);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05307926 qdf_trace_enable(apps_args[0], apps_args[1]);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007927 }
7928 break;
7929
7930 case WE_MTRACE_DUMP_CMD:
7931 {
7932 hddLog(LOG1,
7933 "%s: MTRACE_DUMP code %d session %d count %d "
7934 "bitmask_of_module %d ", __func__, apps_args[0],
7935 apps_args[1], apps_args[2], apps_args[3]);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05307936 qdf_trace_dump_all((void *)hHal, apps_args[0],
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007937 apps_args[1], apps_args[2],
7938 apps_args[3]);
7939
7940 }
7941 break;
7942
7943 case WE_POLICY_MANAGER_CLIST_CMD:
7944 {
7945 hddLog(LOGE,
7946 FL("<iwpriv wlan0 pm_clist> is called\n"));
Tushnim Bhattacharyyaca50b322015-12-28 17:14:36 -08007947 cds_incr_connection_count_utfw(apps_args[0],
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007948 apps_args[1], apps_args[2], apps_args[3],
7949 apps_args[4], apps_args[5], apps_args[6],
7950 apps_args[7]);
7951 }
7952 break;
7953
7954 case WE_POLICY_MANAGER_DLIST_CMD:
7955 {
7956 hddLog(LOGE,
7957 FL("<iwpriv wlan0 pm_dlist> is called\n"));
Tushnim Bhattacharyyaca50b322015-12-28 17:14:36 -08007958 cds_decr_connection_count_utfw(apps_args[0],
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007959 apps_args[1]);
7960 }
7961 break;
7962
7963 case WE_POLICY_MANAGER_ULIST_CMD:
7964 {
7965 hddLog(LOGE,
7966 FL("<iwpriv wlan0 pm_ulist> is called\n"));
Tushnim Bhattacharyyaca50b322015-12-28 17:14:36 -08007967 cds_update_connection_info_utfw(apps_args[0],
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007968 apps_args[1], apps_args[2], apps_args[3],
7969 apps_args[4], apps_args[5], apps_args[6],
7970 apps_args[7]);
7971 }
7972 break;
7973
7974 case WE_POLICY_MANAGER_DBS_CMD:
7975 {
7976 hddLog(LOGE,
7977 FL("<iwpriv wlan0 pm_dbs> is called\n"));
7978 if (apps_args[0] == 0)
7979 wma_set_dbs_capability_ut(0);
7980 else
7981 wma_set_dbs_capability_ut(1);
7982
7983 if (apps_args[1] >= CDS_THROUGHPUT &&
7984 apps_args[1] <= CDS_LATENCY) {
7985 pr_info("setting system pref to [%d]\n", apps_args[1]);
7986 hdd_ctx->config->conc_system_pref = apps_args[1];
7987 }
7988 }
7989 break;
7990
7991 case WE_POLICY_MANAGER_PCL_CMD:
7992 {
7993 uint8_t pcl[MAX_NUM_CHAN] = {0};
Manishekar Chandrasekaran7009f252016-04-21 19:14:15 +05307994 uint8_t weight_list[MAX_NUM_CHAN] = {0};
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007995 uint32_t pcl_len = 0, i = 0;
7996
7997 hddLog(LOGE,
7998 FL("<iwpriv wlan0 pm_pcl> is called\n"));
7999
Tushnim Bhattacharyyaca50b322015-12-28 17:14:36 -08008000 cds_get_pcl(apps_args[0],
Manishekar Chandrasekaran7009f252016-04-21 19:14:15 +05308001 pcl, &pcl_len,
8002 weight_list, QDF_ARRAY_SIZE(weight_list));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008003 pr_info("PCL list for role[%d] is {", apps_args[0]);
8004 for (i = 0 ; i < pcl_len; i++)
8005 pr_info(" %d, ", pcl[i]);
8006 pr_info("}--------->\n");
8007 }
8008 break;
8009
8010 case WE_POLICY_MANAGER_CINFO_CMD:
8011 {
8012 struct cds_conc_connection_info *conn_info;
8013 uint32_t i = 0, len = 0;
8014
8015 hddLog(LOGE,
8016 FL("<iwpriv wlan0 pm_cinfo> is called\n"));
Tushnim Bhattacharyyaca50b322015-12-28 17:14:36 -08008017 conn_info = cds_get_conn_info(&len);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008018 pr_info("+-----------------------------+\n");
8019 for (i = 0; i < len; i++) {
8020 pr_info("|table_index[%d]\t\t|\n", i);
8021 pr_info("|\t|vdev_id - %d\t\t|\n", conn_info->vdev_id);
8022 pr_info("|\t|tx_spatial_stream - %d\t|\n",
8023 conn_info->tx_spatial_stream);
8024 pr_info("|\t|rx_spatial_stream - %d\t|\n",
8025 conn_info->rx_spatial_stream);
8026 pr_info("|\t|chain_mask - %d\t\t|\n",
8027 conn_info->chain_mask);
8028 pr_info("|\t|chan - %d\t\t|\n", conn_info->chan);
Tushnim Bhattacharyya7624a182016-03-30 13:30:46 -07008029 pr_info("|\t|bw - %d\t\t|\n", conn_info->bw);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008030 pr_info("|\t|mode - %d\t\t|\n", conn_info->mode);
8031 pr_info("|\t|mac - %d\t\t|\n", conn_info->mac);
8032 pr_info("|\t|in_use - %d\t\t|\n", conn_info->in_use);
8033 pr_info("+-----------------------------+\n");
8034 conn_info++;
8035 }
8036 }
8037 break;
8038
8039 case WE_POLICY_SET_HW_MODE_CMD:
8040 {
8041 if (apps_args[0] == 0) {
8042 hddLog(LOGE,
8043 FL("set hw mode for single mac\n"));
Tushnim Bhattacharyyaca50b322015-12-28 17:14:36 -08008044 cds_soc_set_hw_mode(
Chandrasekaran, Manishekaref70c0d2015-10-20 19:54:55 +05308045 pAdapter->sessionId,
8046 HW_MODE_SS_2x2,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008047 HW_MODE_80_MHZ,
8048 HW_MODE_SS_0x0, HW_MODE_BW_NONE,
8049 HW_MODE_DBS_NONE,
Chandrasekaran, Manishekaref70c0d2015-10-20 19:54:55 +05308050 HW_MODE_AGILE_DFS_NONE,
Chandrasekaran, Manishekarce2172e2016-02-18 16:12:43 +05308051 SIR_UPDATE_REASON_UT);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008052 } else if (apps_args[0] == 1) {
8053 hddLog(LOGE,
8054 FL("set hw mode for dual mac\n"));
Tushnim Bhattacharyyaca50b322015-12-28 17:14:36 -08008055 cds_soc_set_hw_mode(
Chandrasekaran, Manishekaref70c0d2015-10-20 19:54:55 +05308056 pAdapter->sessionId,
8057 HW_MODE_SS_1x1,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008058 HW_MODE_80_MHZ,
8059 HW_MODE_SS_1x1, HW_MODE_40_MHZ,
8060 HW_MODE_DBS,
Chandrasekaran, Manishekaref70c0d2015-10-20 19:54:55 +05308061 HW_MODE_AGILE_DFS_NONE,
Chandrasekaran, Manishekarce2172e2016-02-18 16:12:43 +05308062 SIR_UPDATE_REASON_UT);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008063 }
8064 }
8065 break;
8066
8067 case WE_POLICY_MANAGER_QUERY_ACTION_CMD:
8068 {
8069 enum cds_conc_next_action action;
8070 hddLog(LOGE,
8071 FL("<iwpriv wlan0 pm_query_action> is called\n"));
Chandrasekaran, Manishekaref70c0d2015-10-20 19:54:55 +05308072 action = cds_current_connections_update(pAdapter->sessionId,
8073 apps_args[0],
Chandrasekaran, Manishekarce2172e2016-02-18 16:12:43 +05308074 SIR_UPDATE_REASON_UT);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008075 pr_info("next action is %d {HDD_NOP = 0, HDD_DBS, HDD_DBS_DOWNGRADE, HDD_MCC, HDD_MCC_UPGRADE}", action);
8076 }
8077 break;
8078 case WE_POLICY_MANAGER_QUERY_ALLOW_CMD:
8079 {
8080 bool allow;
8081 hddLog(LOGE,
8082 FL("<iwpriv wlan0 pm_query_allow> is called\n"));
Tushnim Bhattacharyyaca50b322015-12-28 17:14:36 -08008083 allow = cds_allow_concurrency(
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008084 apps_args[0], apps_args[1], apps_args[2]);
8085 pr_info("allow %d {0 = don't allow, 1 = allow}", allow);
8086 }
8087 break;
8088
8089 case WE_POLICY_MANAGER_SCENARIO_CMD:
8090 {
8091 clean_report(hdd_ctx);
8092 if (apps_args[0] == 1) {
8093 wlan_hdd_one_connection_scenario(hdd_ctx);
8094 } else if (apps_args[0] == 2) {
8095 wlan_hdd_two_connections_scenario(hdd_ctx,
8096 6, CDS_TWO_TWO);
8097 wlan_hdd_two_connections_scenario(hdd_ctx,
8098 36, CDS_TWO_TWO);
8099 wlan_hdd_two_connections_scenario(hdd_ctx,
8100 6, CDS_ONE_ONE);
8101 wlan_hdd_two_connections_scenario(hdd_ctx,
8102 36, CDS_ONE_ONE);
8103 } else if (apps_args[0] == 3) {
8104 /* MCC on same band with 2x2 same mac*/
8105 wlan_hdd_three_connections_scenario(hdd_ctx,
8106 6, 11, CDS_TWO_TWO, 0);
8107 /* MCC on diff band with 2x2 same mac*/
8108 wlan_hdd_three_connections_scenario(hdd_ctx,
8109 6, 36, CDS_TWO_TWO, 0);
8110 /* MCC on diff band with 1x1 diff mac */
8111 wlan_hdd_three_connections_scenario(hdd_ctx,
8112 36, 6, CDS_ONE_ONE, 0);
8113 /* MCC on diff band with 1x1 same mac */
8114 wlan_hdd_three_connections_scenario(hdd_ctx,
8115 36, 6, CDS_ONE_ONE, 1);
8116 /* SCC on same band with 2x2 same mac */
8117 wlan_hdd_three_connections_scenario(hdd_ctx,
8118 36, 36, CDS_TWO_TWO, 0);
8119 /* SCC on same band with 1x1 same mac */
8120 wlan_hdd_three_connections_scenario(hdd_ctx,
8121 36, 36, CDS_ONE_ONE, 1);
8122 /* MCC on same band with 2x2 same mac */
8123 wlan_hdd_three_connections_scenario(hdd_ctx,
8124 36, 149, CDS_TWO_TWO, 0);
8125 /* MCC on same band with 1x1 same mac */
8126 wlan_hdd_three_connections_scenario(hdd_ctx,
8127 36, 149, CDS_ONE_ONE, 1);
8128 }
8129 print_report(hdd_ctx);
8130 }
8131 break;
8132
8133#ifdef FEATURE_WLAN_TDLS
8134 case WE_TDLS_CONFIG_PARAMS:
8135 {
8136 tdls_config_params_t tdlsParams;
8137
8138 tdlsParams.tdls = apps_args[0];
8139 tdlsParams.tx_period_t = apps_args[1];
8140 tdlsParams.tx_packet_n = apps_args[2];
8141 /* ignore args[3] as discovery_period is not used anymore */
8142 tdlsParams.discovery_tries_n = apps_args[4];
8143 /* ignore args[5] as idle_timeout is not used anymore */
8144 tdlsParams.idle_packet_n = apps_args[6];
8145 /* ignore args[7] as rssi_hysteresis is not used anymore */
8146 tdlsParams.rssi_trigger_threshold = apps_args[8];
8147 tdlsParams.rssi_teardown_threshold = apps_args[9];
8148 tdlsParams.rssi_delta = apps_args[10];
8149
8150 wlan_hdd_tdls_set_params(dev, &tdlsParams);
8151 }
8152 break;
8153#endif
8154 case WE_UNIT_TEST_CMD:
8155 {
8156 t_wma_unit_test_cmd *unitTestArgs;
8157 cds_msg_t msg = { 0 };
8158 int i, j;
8159 if ((apps_args[0] < WLAN_MODULE_ID_MIN) ||
8160 (apps_args[0] >= WLAN_MODULE_ID_MAX)) {
8161 hddLog(LOGE, FL("Invalid MODULE ID %d"),
8162 apps_args[0]);
8163 return -EINVAL;
8164 }
8165 if (apps_args[1] > (WMA_MAX_NUM_ARGS)) {
8166 hddLog(LOGE, FL("Too Many args %d"),
8167 apps_args[1]);
8168 return -EINVAL;
8169 }
Anurag Chouhan600c3a02016-03-01 10:33:54 +05308170 unitTestArgs = qdf_mem_malloc(sizeof(*unitTestArgs));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008171 if (NULL == unitTestArgs) {
8172 hddLog(LOGE,
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05308173 FL("qdf_mem_malloc failed for unitTestArgs"));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008174 return -ENOMEM;
8175 }
8176 unitTestArgs->vdev_id = (int)pAdapter->sessionId;
8177 unitTestArgs->module_id = apps_args[0];
8178 unitTestArgs->num_args = apps_args[1];
8179 for (i = 0, j = 2; i < unitTestArgs->num_args; i++, j++) {
8180 unitTestArgs->args[i] = apps_args[j];
8181 }
8182 msg.type = SIR_HAL_UNIT_TEST_CMD;
8183 msg.reserved = 0;
8184 msg.bodyptr = unitTestArgs;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05308185 if (QDF_STATUS_SUCCESS !=
Anurag Chouhan6d760662016-02-20 16:05:43 +05308186 cds_mq_post_message(QDF_MODULE_ID_WMA, &msg)) {
Anurag Chouhan600c3a02016-03-01 10:33:54 +05308187 qdf_mem_free(unitTestArgs);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05308188 QDF_TRACE(QDF_MODULE_ID_HDD,
8189 QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008190 FL
8191 ("Not able to post UNIT_TEST_CMD message to WMA"));
8192 return -EINVAL;
8193 }
8194 }
8195 break;
8196#ifdef WLAN_FEATURE_GPIO_LED_FLASHING
8197 case WE_LED_FLASHING_PARAM:
8198 {
8199 int i;
8200 if (num_args != 4) {
8201 hddLog(LOGE,
8202 FL("gpio_control: 4 parameters are required"));
8203 return -EINVAL;
8204 }
8205 for (i = 0; i < num_args; i++) {
8206 if (apps_args[i] >= 0x7fffffff) {
8207 hddLog(LOGE,
8208 FL("gpio_control: parameter should be less than 0x7fffffff"));
8209 return -EINVAL;
8210 }
8211 }
8212 sme_set_led_flashing(WLAN_HDD_GET_HAL_CTX(pAdapter),
8213 0, apps_args[0], apps_args[1]);
8214 sme_set_led_flashing(WLAN_HDD_GET_HAL_CTX(pAdapter),
8215 1, apps_args[2], apps_args[3]);
8216 }
8217 break;
8218#endif
8219 default:
8220 {
8221 hddLog(LOGE, FL("Invalid IOCTL command %d"), sub_cmd);
8222 }
8223 break;
8224 }
Hanumantha Reddy Pothula2db50ed2015-11-23 10:48:33 +05308225 EXIT();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008226 return 0;
8227}
8228
8229/**
8230 * iw_hdd_set_var_ints_getnone() - set var ints getnone callback
8231 * @dev: pointer to net_device structure
8232 * @info: pointer to iw_request_info structure
8233 * @wrqu: pointer to iwreq_data
8234 * @extra; extra
8235 *
8236 * Return: 0 on success, error number otherwise
8237 *
8238 */
8239static int iw_hdd_set_var_ints_getnone(struct net_device *dev,
8240 struct iw_request_info *info,
8241 union iwreq_data *wrqu, char *extra)
8242{
8243 union iwreq_data u_priv_wrqu;
8244 int apps_args[MAX_VAR_ARGS] = {0};
8245 int ret, num_args;
8246
Mukul Sharma64a70e82015-11-02 20:05:09 +05308247 if (!capable(CAP_NET_ADMIN)) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05308248 QDF_TRACE(QDF_MODULE_ID_HDD, QDF_TRACE_LEVEL_ERROR,
Mukul Sharma64a70e82015-11-02 20:05:09 +05308249 FL("permission check failed"));
8250 return -EPERM;
8251 }
8252
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008253 /* Helper function to get iwreq_data with compat handling. */
8254 if (hdd_priv_get_data(&u_priv_wrqu.data, wrqu))
8255 return -EINVAL;
8256
8257 if (NULL == u_priv_wrqu.data.pointer) {
8258 hddLog(LOGE, FL("NULL data pointer"));
8259 return -EINVAL;
8260 }
8261
8262 num_args = u_priv_wrqu.data.length;
8263 if (num_args > MAX_VAR_ARGS)
8264 num_args = MAX_VAR_ARGS;
8265
8266 if (copy_from_user(apps_args, u_priv_wrqu.data.pointer,
8267 (sizeof(int)) * num_args)) {
8268 hddLog(LOGE, FL("failed to copy data from user buffer"));
8269 return -EFAULT;
8270 }
8271
8272 cds_ssr_protect(__func__);
8273 ret = __iw_set_var_ints_getnone(dev, info, &u_priv_wrqu,
8274 (char *)&apps_args);
8275 cds_ssr_unprotect(__func__);
8276 return ret;
8277}
8278
8279/**
8280 * iw_set_var_ints_getnone - Generic "set many" private ioctl handler
8281 * @dev: device upon which the ioctl was received
8282 * @info: ioctl request information
8283 * @wrqu: ioctl request data
8284 * @extra: ioctl extra data
8285 *
8286 * This is a generic handler for private ioctls which take multiple
8287 * arguments. Note that this implementation is also somewhat unique
8288 * in that it is shared by both STA-mode and SAP-mode interfaces.
8289 *
8290 * Return: 0 on success, non-zero on error
8291 */
8292int iw_set_var_ints_getnone(struct net_device *dev,
8293 struct iw_request_info *info,
8294 union iwreq_data *wrqu, char *extra)
8295{
8296 int ret;
8297
8298 cds_ssr_protect(__func__);
8299 ret = __iw_set_var_ints_getnone(dev, info, wrqu, extra);
8300 cds_ssr_unprotect(__func__);
8301 return ret;
8302}
8303
8304/**
8305 * iw_add_tspec - Add TSpec private ioctl handler
8306 * @dev: device upon which the ioctl was received
8307 * @info: ioctl request information
8308 * @wrqu: ioctl request data
8309 * @extra: ioctl extra data
8310 *
8311 * Return: 0 on success, non-zero on error
8312 */
8313static int __iw_add_tspec(struct net_device *dev, struct iw_request_info *info,
8314 union iwreq_data *wrqu, char *extra)
8315{
8316 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
8317 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
8318 hdd_wlan_wmm_status_e *pStatus = (hdd_wlan_wmm_status_e *) extra;
8319 int params[HDD_WLAN_WMM_PARAM_COUNT];
8320 sme_QosWmmTspecInfo tSpec;
8321 uint32_t handle;
8322 struct iw_point s_priv_data;
8323 hdd_context_t *hdd_ctx;
8324 int ret;
8325
Jeff Johnson6ee91ee2016-02-11 18:55:30 -08008326 ENTER_DEV(dev);
Hanumantha Reddy Pothula2db50ed2015-11-23 10:48:33 +05308327
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008328 hdd_ctx = WLAN_HDD_GET_CTX(pAdapter);
8329 ret = wlan_hdd_validate_context(hdd_ctx);
8330 if (0 != ret)
8331 return ret;
8332
8333 /* make sure the application is sufficiently priviledged */
8334 /* note that the kernel will do this for "set" ioctls, but since */
8335 /* this ioctl wants to return status to user space it must be */
8336 /* defined as a "get" ioctl */
8337 if (!capable(CAP_NET_ADMIN)) {
8338 return -EPERM;
8339 }
8340
8341 /* we must be associated in order to add a tspec */
8342 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState) {
8343 *pStatus = HDD_WLAN_WMM_STATUS_SETUP_FAILED_BAD_PARAM;
8344 return 0;
8345 }
8346 /* since we are defined to be a "get" ioctl, and since the number */
8347 /* of params exceeds the number of params that wireless extensions */
8348 /* will pass down in the iwreq_data, we must copy the "set" params. */
8349 /* We must handle the compat for iwreq_data in 32U/64K environment. */
8350
8351 /* helper function to get iwreq_data with compat handling. */
8352 if (hdd_priv_get_data(&s_priv_data, wrqu)) {
8353 *pStatus = HDD_WLAN_WMM_STATUS_SETUP_FAILED_BAD_PARAM;
8354 return 0;
8355 }
8356 /* make sure all params are correctly passed to function */
8357 if ((NULL == s_priv_data.pointer) ||
8358 (HDD_WLAN_WMM_PARAM_COUNT != s_priv_data.length)) {
8359 *pStatus = HDD_WLAN_WMM_STATUS_SETUP_FAILED_BAD_PARAM;
8360 return 0;
8361 }
8362 /* from user space ourselves */
8363 if (copy_from_user(&params, s_priv_data.pointer, sizeof(params))) {
8364 /* hmmm, can't get them */
8365 return -EIO;
8366 }
8367 /* clear the tspec */
8368 memset(&tSpec, 0, sizeof(tSpec));
8369
8370 /* validate the handle */
8371 handle = params[HDD_WLAN_WMM_PARAM_HANDLE];
8372 if (HDD_WMM_HANDLE_IMPLICIT == handle) {
8373 /* that one is reserved */
8374 *pStatus = HDD_WLAN_WMM_STATUS_SETUP_FAILED_BAD_PARAM;
8375 return 0;
8376 }
8377 /* validate the TID */
8378 if (params[HDD_WLAN_WMM_PARAM_TID] > 7) {
8379 /* out of range */
8380 *pStatus = HDD_WLAN_WMM_STATUS_SETUP_FAILED_BAD_PARAM;
8381 return 0;
8382 }
8383 tSpec.ts_info.tid = params[HDD_WLAN_WMM_PARAM_TID];
8384
8385 /* validate the direction */
8386 switch (params[HDD_WLAN_WMM_PARAM_DIRECTION]) {
8387 case HDD_WLAN_WMM_DIRECTION_UPSTREAM:
8388 tSpec.ts_info.direction = SME_QOS_WMM_TS_DIR_UPLINK;
8389 break;
8390
8391 case HDD_WLAN_WMM_DIRECTION_DOWNSTREAM:
8392 tSpec.ts_info.direction = SME_QOS_WMM_TS_DIR_DOWNLINK;
8393 break;
8394
8395 case HDD_WLAN_WMM_DIRECTION_BIDIRECTIONAL:
8396 tSpec.ts_info.direction = SME_QOS_WMM_TS_DIR_BOTH;
8397 break;
8398
8399 default:
8400 /* unknown */
8401 *pStatus = HDD_WLAN_WMM_STATUS_SETUP_FAILED_BAD_PARAM;
8402 return 0;
8403 }
8404
8405 tSpec.ts_info.psb = params[HDD_WLAN_WMM_PARAM_APSD];
8406
8407 /* validate the user priority */
8408 if (params[HDD_WLAN_WMM_PARAM_USER_PRIORITY] >= SME_QOS_WMM_UP_MAX) {
8409 /* out of range */
8410 *pStatus = HDD_WLAN_WMM_STATUS_SETUP_FAILED_BAD_PARAM;
8411 return 0;
8412 }
8413 tSpec.ts_info.up = params[HDD_WLAN_WMM_PARAM_USER_PRIORITY];
8414 if (0 > tSpec.ts_info.up || SME_QOS_WMM_UP_MAX < tSpec.ts_info.up) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05308415 hddLog(QDF_TRACE_LEVEL_ERROR, "***ts_info.up out of bounds***");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008416 return 0;
8417 }
8418
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05308419 QDF_TRACE(QDF_MODULE_ID_HDD, QDF_TRACE_LEVEL_INFO_HIGH,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008420 "%s:TS_INFO PSB %d UP %d !!!", __func__,
8421 tSpec.ts_info.psb, tSpec.ts_info.up);
8422
8423 tSpec.nominal_msdu_size = params[HDD_WLAN_WMM_PARAM_NOMINAL_MSDU_SIZE];
8424 tSpec.maximum_msdu_size = params[HDD_WLAN_WMM_PARAM_MAXIMUM_MSDU_SIZE];
8425 tSpec.min_data_rate = params[HDD_WLAN_WMM_PARAM_MINIMUM_DATA_RATE];
8426 tSpec.mean_data_rate = params[HDD_WLAN_WMM_PARAM_MEAN_DATA_RATE];
8427 tSpec.peak_data_rate = params[HDD_WLAN_WMM_PARAM_PEAK_DATA_RATE];
8428 tSpec.max_burst_size = params[HDD_WLAN_WMM_PARAM_MAX_BURST_SIZE];
8429 tSpec.min_phy_rate = params[HDD_WLAN_WMM_PARAM_MINIMUM_PHY_RATE];
8430 tSpec.surplus_bw_allowance =
8431 params[HDD_WLAN_WMM_PARAM_SURPLUS_BANDWIDTH_ALLOWANCE];
8432 tSpec.min_service_interval =
8433 params[HDD_WLAN_WMM_PARAM_SERVICE_INTERVAL];
8434 tSpec.max_service_interval =
8435 params[HDD_WLAN_WMM_PARAM_MAX_SERVICE_INTERVAL];
8436 tSpec.suspension_interval =
8437 params[HDD_WLAN_WMM_PARAM_SUSPENSION_INTERVAL];
8438 tSpec.inactivity_interval =
8439 params[HDD_WLAN_WMM_PARAM_INACTIVITY_INTERVAL];
8440
8441 tSpec.ts_info.burst_size_defn =
8442 params[HDD_WLAN_WMM_PARAM_BURST_SIZE_DEFN];
8443
8444 /* validate the ts info ack policy */
8445 switch (params[HDD_WLAN_WMM_PARAM_ACK_POLICY]) {
8446 case HDD_WLAN_WMM_TS_INFO_ACK_POLICY_NORMAL_ACK:
8447 tSpec.ts_info.ack_policy = SME_QOS_WMM_TS_ACK_POLICY_NORMAL_ACK;
8448 break;
8449
8450 case HDD_WLAN_WMM_TS_INFO_ACK_POLICY_HT_IMMEDIATE_BLOCK_ACK:
8451 tSpec.ts_info.ack_policy =
8452 SME_QOS_WMM_TS_ACK_POLICY_HT_IMMEDIATE_BLOCK_ACK;
8453 break;
8454
8455 default:
8456 /* unknown */
8457 *pStatus = HDD_WLAN_WMM_STATUS_SETUP_FAILED_BAD_PARAM;
8458 return 0;
8459 }
8460
8461 *pStatus = hdd_wmm_addts(pAdapter, handle, &tSpec);
Hanumantha Reddy Pothula2db50ed2015-11-23 10:48:33 +05308462 EXIT();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008463 return 0;
8464}
8465
8466static int iw_add_tspec(struct net_device *dev,
8467 struct iw_request_info *info,
8468 union iwreq_data *wrqu, char *extra)
8469{
8470 int ret;
8471
8472 cds_ssr_protect(__func__);
8473 ret = __iw_add_tspec(dev, info, wrqu, extra);
8474 cds_ssr_unprotect(__func__);
8475
8476 return ret;
8477}
8478
8479/**
8480 * iw_del_tspec - Delete TSpec private ioctl handler
8481 * @dev: device upon which the ioctl was received
8482 * @info: ioctl request information
8483 * @wrqu: ioctl request data
8484 * @extra: ioctl extra data
8485 *
8486 * Return: 0 on success, non-zero on error
8487 */
8488static int __iw_del_tspec(struct net_device *dev, struct iw_request_info *info,
8489 union iwreq_data *wrqu, char *extra)
8490{
8491 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
8492 hdd_context_t *hdd_ctx;
8493 int *params = (int *)extra;
8494 hdd_wlan_wmm_status_e *pStatus = (hdd_wlan_wmm_status_e *) extra;
8495 uint32_t handle;
8496 int ret;
8497
Jeff Johnson6ee91ee2016-02-11 18:55:30 -08008498 ENTER_DEV(dev);
Hanumantha Reddy Pothula2db50ed2015-11-23 10:48:33 +05308499
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008500 hdd_ctx = WLAN_HDD_GET_CTX(pAdapter);
8501 ret = wlan_hdd_validate_context(hdd_ctx);
8502 if (0 != ret)
8503 return ret;
8504
8505 /* make sure the application is sufficiently priviledged */
8506 /* note that the kernel will do this for "set" ioctls, but since */
8507 /* this ioctl wants to return status to user space it must be */
8508 /* defined as a "get" ioctl */
8509 if (!capable(CAP_NET_ADMIN)) {
8510 return -EPERM;
8511 }
8512
8513 /* although we are defined to be a "get" ioctl, the params we require */
8514 /* will fit in the iwreq_data, therefore unlike iw_add_tspec() there */
8515 /* is no need to copy the params from user space */
8516
8517 /* validate the handle */
8518 handle = params[HDD_WLAN_WMM_PARAM_HANDLE];
8519 if (HDD_WMM_HANDLE_IMPLICIT == handle) {
8520 /* that one is reserved */
8521 *pStatus = HDD_WLAN_WMM_STATUS_SETUP_FAILED_BAD_PARAM;
8522 return 0;
8523 }
8524
8525 *pStatus = hdd_wmm_delts(pAdapter, handle);
Hanumantha Reddy Pothula2db50ed2015-11-23 10:48:33 +05308526 EXIT();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008527 return 0;
8528}
8529
8530static int iw_del_tspec(struct net_device *dev,
8531 struct iw_request_info *info,
8532 union iwreq_data *wrqu, char *extra)
8533{
8534 int ret;
8535
8536 cds_ssr_protect(__func__);
8537 ret = __iw_del_tspec(dev, info, wrqu, extra);
8538 cds_ssr_unprotect(__func__);
8539
8540 return ret;
8541}
8542
8543/**
8544 * iw_get_tspec - Get TSpec private ioctl handler
8545 * @dev: device upon which the ioctl was received
8546 * @info: ioctl request information
8547 * @wrqu: ioctl request data
8548 * @extra: ioctl extra data
8549 *
8550 * Return: 0 on success, non-zero on error
8551 */
8552static int __iw_get_tspec(struct net_device *dev, struct iw_request_info *info,
8553 union iwreq_data *wrqu, char *extra)
8554{
8555 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
8556 hdd_context_t *hdd_ctx;
8557 int *params = (int *)extra;
8558 hdd_wlan_wmm_status_e *pStatus = (hdd_wlan_wmm_status_e *) extra;
8559 uint32_t handle;
8560 int ret;
8561
Jeff Johnson6ee91ee2016-02-11 18:55:30 -08008562 ENTER_DEV(dev);
Hanumantha Reddy Pothula2db50ed2015-11-23 10:48:33 +05308563
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008564 hdd_ctx = WLAN_HDD_GET_CTX(pAdapter);
8565 ret = wlan_hdd_validate_context(hdd_ctx);
8566 if (0 != ret)
8567 return ret;
8568
8569 /* although we are defined to be a "get" ioctl, the params we require */
8570 /* will fit in the iwreq_data, therefore unlike iw_add_tspec() there */
8571 /* is no need to copy the params from user space */
8572
8573 /* validate the handle */
8574 handle = params[HDD_WLAN_WMM_PARAM_HANDLE];
8575 if (HDD_WMM_HANDLE_IMPLICIT == handle) {
8576 /* that one is reserved */
8577 *pStatus = HDD_WLAN_WMM_STATUS_SETUP_FAILED_BAD_PARAM;
8578 return 0;
8579 }
8580
8581 *pStatus = hdd_wmm_checkts(pAdapter, handle);
Hanumantha Reddy Pothula2db50ed2015-11-23 10:48:33 +05308582 EXIT();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008583 return 0;
8584}
8585
8586static int iw_get_tspec(struct net_device *dev,
8587 struct iw_request_info *info,
8588 union iwreq_data *wrqu, char *extra)
8589{
8590 int ret;
8591
8592 cds_ssr_protect(__func__);
8593 ret = __iw_get_tspec(dev, info, wrqu, extra);
8594 cds_ssr_unprotect(__func__);
8595
8596 return ret;
8597}
8598
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008599/**
8600 * iw_set_fties - Set FT IEs private ioctl handler
8601 * @dev: device upon which the ioctl was received
8602 * @info: ioctl request information
8603 * @wrqu: ioctl request data
8604 * @extra: ioctl extra data
8605 *
8606 * Each time the supplicant has the auth_request or reassoc request
8607 * IEs ready they are pushed to the driver. The driver will in turn
8608 * use it to send out the auth req and reassoc req for 11r FT Assoc.
8609 *
8610 * Return: 0 on success, non-zero on error
8611 */
8612static int __iw_set_fties(struct net_device *dev, struct iw_request_info *info,
8613 union iwreq_data *wrqu, char *extra)
8614{
8615 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
8616 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
8617 hdd_context_t *hdd_ctx;
8618 int ret;
8619
Jeff Johnson6ee91ee2016-02-11 18:55:30 -08008620 ENTER_DEV(dev);
Hanumantha Reddy Pothula2db50ed2015-11-23 10:48:33 +05308621
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008622 hdd_ctx = WLAN_HDD_GET_CTX(pAdapter);
8623 ret = wlan_hdd_validate_context(hdd_ctx);
8624 if (0 != ret)
8625 return ret;
8626
8627 if (!wrqu->data.length) {
8628 hddLog(LOGE, FL("called with 0 length IEs"));
8629 return -EINVAL;
8630 }
8631 if (wrqu->data.pointer == NULL) {
8632 hddLog(LOGE, FL("called with NULL IE"));
8633 return -EINVAL;
8634 }
8635 /* Added for debug on reception of Re-assoc Req. */
8636 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState) {
8637 hddLog(LOGE,
8638 FL("Called with Ie of length = %d when not associated"),
8639 wrqu->data.length);
8640 hddLog(LOGE, FL("Should be Re-assoc Req IEs"));
8641 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008642 hddLog(LOG1, FL("%s called with Ie of length = %d"), __func__,
8643 wrqu->data.length);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008644
8645 /* Pass the received FT IEs to SME */
8646 sme_set_ft_ies(WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
8647 extra, wrqu->data.length);
Hanumantha Reddy Pothula2db50ed2015-11-23 10:48:33 +05308648 EXIT();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008649 return 0;
8650}
8651
8652static int iw_set_fties(struct net_device *dev,
8653 struct iw_request_info *info,
8654 union iwreq_data *wrqu, char *extra)
8655{
8656 int ret;
8657
8658 cds_ssr_protect(__func__);
8659 ret = __iw_set_fties(dev, info, wrqu, extra);
8660 cds_ssr_unprotect(__func__);
8661
8662 return ret;
8663}
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008664
8665/**
8666 * iw_set_host_offload - Set host offload ioctl handler
8667 * @dev: device upon which the ioctl was received
8668 * @info: ioctl request information
8669 * @wrqu: ioctl request data
8670 * @extra: ioctl extra data
8671 *
8672 * Return: 0 on success, non-zero on error
8673 */
8674static int __iw_set_host_offload(struct net_device *dev,
8675 struct iw_request_info *info,
8676 union iwreq_data *wrqu, char *extra)
8677{
8678 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
8679 tpHostOffloadRequest pRequest = (tpHostOffloadRequest) extra;
8680 tSirHostOffloadReq offloadRequest;
8681 hdd_context_t *hdd_ctx;
8682 int ret;
8683
Jeff Johnson6ee91ee2016-02-11 18:55:30 -08008684 ENTER_DEV(dev);
Hanumantha Reddy Pothula2db50ed2015-11-23 10:48:33 +05308685
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008686 hdd_ctx = WLAN_HDD_GET_CTX(pAdapter);
8687 ret = wlan_hdd_validate_context(hdd_ctx);
8688 if (0 != ret)
8689 return ret;
8690
8691 if (!hdd_conn_is_connected(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05308692 QDF_TRACE(QDF_MODULE_ID_HDD, QDF_TRACE_LEVEL_FATAL,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008693 "%s:LOGP dev is not in CONNECTED state, ignore!!!",
8694 __func__);
8695 return -EINVAL;
8696 }
8697
8698 /* Debug display of request components. */
8699 switch (pRequest->offloadType) {
8700 case WLAN_IPV4_ARP_REPLY_OFFLOAD:
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05308701 hddLog(QDF_TRACE_LEVEL_WARN,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008702 "%s: Host offload request: ARP reply", __func__);
8703 switch (pRequest->enableOrDisable) {
8704 case WLAN_OFFLOAD_DISABLE:
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05308705 hddLog(QDF_TRACE_LEVEL_WARN, " disable");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008706 break;
8707 case WLAN_OFFLOAD_ARP_AND_BC_FILTER_ENABLE:
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05308708 hddLog(QDF_TRACE_LEVEL_WARN, " BC Filtering enable");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008709 case WLAN_OFFLOAD_ENABLE:
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05308710 hddLog(QDF_TRACE_LEVEL_WARN, " ARP offload enable");
8711 hddLog(QDF_TRACE_LEVEL_WARN,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008712 " IP address: %d.%d.%d.%d",
8713 pRequest->params.hostIpv4Addr[0],
8714 pRequest->params.hostIpv4Addr[1],
8715 pRequest->params.hostIpv4Addr[2],
8716 pRequest->params.hostIpv4Addr[3]);
8717 }
8718 break;
8719
8720 case WLAN_IPV6_NEIGHBOR_DISCOVERY_OFFLOAD:
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05308721 hddLog(QDF_TRACE_LEVEL_INFO_HIGH,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008722 "%s: Host offload request: neighbor discovery",
8723 __func__);
8724 switch (pRequest->enableOrDisable) {
8725 case WLAN_OFFLOAD_DISABLE:
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05308726 hddLog(QDF_TRACE_LEVEL_INFO_HIGH, " disable");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008727 break;
8728 case WLAN_OFFLOAD_ENABLE:
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05308729 hddLog(QDF_TRACE_LEVEL_INFO_HIGH, " enable");
8730 hddLog(QDF_TRACE_LEVEL_INFO_HIGH,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008731 " IP address: %x:%x:%x:%x:%x:%x:%x:%x",
8732 *(uint16_t *) (pRequest->params.hostIpv6Addr),
8733 *(uint16_t *) (pRequest->params.hostIpv6Addr +
8734 2),
8735 *(uint16_t *) (pRequest->params.hostIpv6Addr +
8736 4),
8737 *(uint16_t *) (pRequest->params.hostIpv6Addr +
8738 6),
8739 *(uint16_t *) (pRequest->params.hostIpv6Addr +
8740 8),
8741 *(uint16_t *) (pRequest->params.hostIpv6Addr +
8742 10),
8743 *(uint16_t *) (pRequest->params.hostIpv6Addr +
8744 12),
8745 *(uint16_t *) (pRequest->params.hostIpv6Addr +
8746 14));
8747 }
8748 }
8749
8750 /* Execute offload request. The reason that we can copy the
8751 * request information from the ioctl structure to the SME
8752 * structure is that they are laid out exactly the same.
8753 * Otherwise, each piece of information would have to be
8754 * copied individually.
8755 */
8756 memcpy(&offloadRequest, pRequest, wrqu->data.length);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05308757 if (QDF_STATUS_SUCCESS !=
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008758 sme_set_host_offload(WLAN_HDD_GET_HAL_CTX(pAdapter),
8759 pAdapter->sessionId, &offloadRequest)) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05308760 hddLog(QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008761 "%s: Failure to execute host offload request", __func__);
8762 return -EINVAL;
8763 }
Hanumantha Reddy Pothula2db50ed2015-11-23 10:48:33 +05308764 EXIT();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008765 return 0;
8766}
8767
8768static int iw_set_host_offload(struct net_device *dev,
8769 struct iw_request_info *info,
8770 union iwreq_data *wrqu, char *extra)
8771{
8772 int ret;
8773
8774 cds_ssr_protect(__func__);
8775 ret = __iw_set_host_offload(dev, info, wrqu, extra);
8776 cds_ssr_unprotect(__func__);
8777
8778 return ret;
8779}
8780
8781/**
8782 * iw_set_keepalive_params - Set keepalive params ioctl handler
8783 * @dev: device upon which the ioctl was received
8784 * @info: ioctl request information
8785 * @wrqu: ioctl request data
8786 * @extra: ioctl extra data
8787 *
8788 * Return: 0 on success, non-zero on error
8789 */
8790static int __iw_set_keepalive_params(struct net_device *dev,
8791 struct iw_request_info *info,
8792 union iwreq_data *wrqu, char *extra)
8793{
8794 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Rajeev Kumar3ddf1c62015-11-03 14:10:13 -08008795 tpSirKeepAliveReq request = (tpSirKeepAliveReq) extra;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008796 hdd_context_t *hdd_ctx;
8797 int ret;
8798
Jeff Johnson6ee91ee2016-02-11 18:55:30 -08008799 ENTER_DEV(dev);
Hanumantha Reddy Pothula2db50ed2015-11-23 10:48:33 +05308800
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008801 hdd_ctx = WLAN_HDD_GET_CTX(pAdapter);
8802 ret = wlan_hdd_validate_context(hdd_ctx);
8803 if (0 != ret)
8804 return ret;
8805
Rajeev Kumar3ddf1c62015-11-03 14:10:13 -08008806 if (wrqu->data.length != sizeof(*request)) {
8807 hdd_err("Invalid length %d", wrqu->data.length);
8808 return -EINVAL;
8809 }
8810
8811 if (request->timePeriod > WNI_CFG_INFRA_STA_KEEP_ALIVE_PERIOD_STAMAX) {
8812 hdd_err("Value of timePeriod %d exceed Max limit %d",
8813 request->timePeriod,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008814 WNI_CFG_INFRA_STA_KEEP_ALIVE_PERIOD_STAMAX);
8815 return -EINVAL;
8816 }
8817
8818 /* Debug display of request components. */
Rajeev Kumar3ddf1c62015-11-03 14:10:13 -08008819 hdd_info("Set Keep Alive Request : TimePeriod %d size %zu",
8820 request->timePeriod, sizeof(tSirKeepAliveReq));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008821
Rajeev Kumar3ddf1c62015-11-03 14:10:13 -08008822 switch (request->packetType) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008823 case WLAN_KEEP_ALIVE_NULL_PKT:
Rajeev Kumar3ddf1c62015-11-03 14:10:13 -08008824 hdd_info("Keep Alive Request: Tx NULL");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008825 break;
8826
8827 case WLAN_KEEP_ALIVE_UNSOLICIT_ARP_RSP:
Rajeev Kumar3ddf1c62015-11-03 14:10:13 -08008828 hdd_info("Keep Alive Request: Tx UnSolicited ARP RSP");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008829
Rajeev Kumar3ddf1c62015-11-03 14:10:13 -08008830 hdd_info("Host IP address: %d.%d.%d.%d",
8831 request->hostIpv4Addr[0], request->hostIpv4Addr[1],
8832 request->hostIpv4Addr[2], request->hostIpv4Addr[3]);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008833
Rajeev Kumar3ddf1c62015-11-03 14:10:13 -08008834 hdd_info("Dest IP address: %d.%d.%d.%d",
8835 request->destIpv4Addr[0], request->destIpv4Addr[1],
8836 request->destIpv4Addr[2], request->destIpv4Addr[3]);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008837
Srinivas Girigowda9c330a92015-11-24 12:28:25 -08008838 hdd_info("Dest MAC address: "MAC_ADDRESS_STR,
8839 MAC_ADDR_ARRAY(request->dest_macaddr.bytes));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008840 break;
8841 }
8842
Rajeev Kumar3ddf1c62015-11-03 14:10:13 -08008843 hdd_info("Keep alive period %d", request->timePeriod);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008844
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05308845 if (QDF_STATUS_SUCCESS !=
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008846 sme_set_keep_alive(WLAN_HDD_GET_HAL_CTX(pAdapter),
Rajeev Kumar3ddf1c62015-11-03 14:10:13 -08008847 pAdapter->sessionId, request)) {
8848 hdd_err("Failure to execute Keep Alive");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008849 return -EINVAL;
8850 }
Hanumantha Reddy Pothula2db50ed2015-11-23 10:48:33 +05308851 EXIT();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008852 return 0;
8853}
8854
8855static int iw_set_keepalive_params(struct net_device *dev,
8856 struct iw_request_info *info,
8857 union iwreq_data *wrqu,
8858 char *extra)
8859{
8860 int ret;
8861
8862 cds_ssr_protect(__func__);
8863 ret = __iw_set_keepalive_params(dev, info, wrqu, extra);
8864 cds_ssr_unprotect(__func__);
8865
8866 return ret;
8867}
8868
8869#ifdef WLAN_FEATURE_PACKET_FILTERING
8870/**
8871 * wlan_hdd_set_filter() - Set packet filter
8872 * @hdd_ctx: Global HDD context
8873 * @request: Packet filter request struct
8874 * @sessionId: Target session for the request
8875 *
8876 * Return: 0 on success, non-zero on error
8877 */
8878static int wlan_hdd_set_filter(hdd_context_t *hdd_ctx,
8879 struct pkt_filter_cfg *request,
8880 uint8_t sessionId)
8881{
8882 tSirRcvPktFilterCfgType packetFilterSetReq = {0};
8883 tSirRcvFltPktClearParam packetFilterClrReq = {0};
8884 int i = 0;
8885
8886 if (hdd_ctx->config->disablePacketFilter) {
8887 hdd_err("packet filtering disabled in ini returning");
8888 return 0;
8889 }
8890
8891 /* Debug display of request components. */
8892 hdd_info("Packet Filter Request : FA %d params %d",
8893 request->filter_action, request->num_params);
8894
8895 switch (request->filter_action) {
8896 case HDD_RCV_FILTER_SET:
8897 hdd_info("Set Packet Filter Request for Id: %d",
8898 request->filter_id);
8899
8900 packetFilterSetReq.filterId = request->filter_id;
8901 if (request->num_params >= HDD_MAX_CMP_PER_PACKET_FILTER) {
8902 hdd_err("Number of Params exceed Max limit %d",
8903 request->num_params);
8904 return -EINVAL;
8905 }
8906 packetFilterSetReq.numFieldParams = request->num_params;
8907 packetFilterSetReq.coalesceTime = 0;
8908 packetFilterSetReq.filterType = HDD_RCV_FILTER_SET;
8909 for (i = 0; i < request->num_params; i++) {
8910 packetFilterSetReq.paramsData[i].protocolLayer =
8911 request->params_data[i].protocol_layer;
8912 packetFilterSetReq.paramsData[i].cmpFlag =
8913 request->params_data[i].compare_flag;
8914 packetFilterSetReq.paramsData[i].dataOffset =
8915 request->params_data[i].data_offset;
8916 packetFilterSetReq.paramsData[i].dataLength =
8917 request->params_data[i].data_length;
8918 packetFilterSetReq.paramsData[i].reserved = 0;
8919
8920 if (request->params_data[i].data_length >
8921 SIR_MAX_FILTER_TEST_DATA_LEN) {
8922 hdd_err("Error invalid data length %d",
8923 request->params_data[i].data_length);
8924 return -EINVAL;
8925 }
8926
8927 hdd_info("Proto %d Comp Flag %d Filter Type %d",
8928 request->params_data[i].protocol_layer,
8929 request->params_data[i].compare_flag,
8930 packetFilterSetReq.filterType);
8931
8932 hdd_info("Data Offset %d Data Len %d",
8933 request->params_data[i].data_offset,
8934 request->params_data[i].data_length);
8935
Rajeev Kumarf5b6da22016-04-15 13:24:03 -07008936 if (sizeof(packetFilterSetReq.paramsData[i].compareData)
8937 < (request->params_data[i].data_length)) {
8938 hdd_err("Error invalid data length %d",
8939 request->params_data[i].data_length);
8940 return -EINVAL;
8941 }
8942
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008943 memcpy(&packetFilterSetReq.paramsData[i].compareData,
8944 request->params_data[i].compare_data,
8945 request->params_data[i].data_length);
8946 memcpy(&packetFilterSetReq.paramsData[i].dataMask,
8947 request->params_data[i].data_mask,
8948 request->params_data[i].data_length);
8949
8950 hdd_info("CData %d CData %d CData %d CData %d CData %d CData %d",
8951 request->params_data[i].compare_data[0],
8952 request->params_data[i].compare_data[1],
8953 request->params_data[i].compare_data[2],
8954 request->params_data[i].compare_data[3],
8955 request->params_data[i].compare_data[4],
8956 request->params_data[i].compare_data[5]);
8957
8958 hdd_info("MData %d MData %d MData %d MData %d MData %d MData %d",
8959 request->params_data[i].data_mask[0],
8960 request->params_data[i].data_mask[1],
8961 request->params_data[i].data_mask[2],
8962 request->params_data[i].data_mask[3],
8963 request->params_data[i].data_mask[4],
8964 request->params_data[i].data_mask[5]);
8965 }
8966
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05308967 if (QDF_STATUS_SUCCESS !=
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008968 sme_receive_filter_set_filter(hdd_ctx->hHal,
8969 &packetFilterSetReq,
8970 sessionId)) {
8971 hdd_err("Failure to execute Set Filter");
8972 return -EINVAL;
8973 }
8974
8975 break;
8976
8977 case HDD_RCV_FILTER_CLEAR:
8978
8979 hdd_info("Clear Packet Filter Request for Id: %d",
8980 request->filter_id);
8981 packetFilterClrReq.filterId = request->filter_id;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05308982 if (QDF_STATUS_SUCCESS !=
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008983 sme_receive_filter_clear_filter(hdd_ctx->hHal,
8984 &packetFilterClrReq,
8985 sessionId)) {
8986 hdd_err("Failure to execute Clear Filter");
8987 return -EINVAL;
8988 }
8989 break;
8990
8991 default:
8992 hdd_err("Packet Filter Request: Invalid %d",
8993 request->filter_action);
8994 return -EINVAL;
8995 }
8996 return 0;
8997}
8998
8999/**
9000 * __iw_set_packet_filter_params() - set packet filter parameters in target
9001 * @dev: Pointer to netdev
9002 * @info: Pointer to iw request info
9003 * @wrqu: Pointer to data
9004 * @extra: Pointer to extra data
9005 *
9006 * Return: 0 on success, non-zero on error
9007 */
9008static int __iw_set_packet_filter_params(struct net_device *dev,
9009 struct iw_request_info *info,
9010 union iwreq_data *wrqu, char *extra)
9011{
9012 int ret;
9013 hdd_context_t *hdd_ctx;
9014 struct iw_point priv_data;
9015 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
9016 struct pkt_filter_cfg *request = NULL;
9017
Mukul Sharma472382f2015-11-02 20:16:31 +05309018 if (!capable(CAP_NET_ADMIN)) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05309019 QDF_TRACE(QDF_MODULE_ID_HDD, QDF_TRACE_LEVEL_ERROR,
Mukul Sharma472382f2015-11-02 20:16:31 +05309020 FL("permission check failed"));
9021 return -EPERM;
9022 }
9023
Jeff Johnson6ee91ee2016-02-11 18:55:30 -08009024 ENTER_DEV(dev);
Hanumantha Reddy Pothula2db50ed2015-11-23 10:48:33 +05309025
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08009026 hdd_ctx = WLAN_HDD_GET_CTX(adapter);
9027 ret = wlan_hdd_validate_context(hdd_ctx);
9028 if (0 != ret)
9029 return ret;
9030
9031 if (hdd_priv_get_data(&priv_data, wrqu)) {
9032 hdd_err("failed to get priv data");
9033 return -EINVAL;
9034 }
9035
9036 if ((NULL == priv_data.pointer) || (0 == priv_data.length)) {
9037 hdd_err("invalid priv data %p or invalid priv data length %d",
9038 priv_data.pointer, priv_data.length);
9039 return -EINVAL;
9040 }
9041
9042 /* copy data using copy_from_user */
9043 request = mem_alloc_copy_from_user_helper(priv_data.pointer,
9044 priv_data.length);
9045 if (NULL == request) {
9046 hdd_err("mem_alloc_copy_from_user_helper fail");
9047 return -ENOMEM;
9048 }
9049
9050 ret = wlan_hdd_set_filter(hdd_ctx, request, adapter->sessionId);
9051
9052 kfree(request);
Hanumantha Reddy Pothula2db50ed2015-11-23 10:48:33 +05309053 EXIT();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08009054 return ret;
9055}
9056
9057/**
9058 * iw_set_packet_filter_params() - set packet filter parameters in target
9059 * @dev: Pointer to netdev
9060 * @info: Pointer to iw request info
9061 * @wrqu: Pointer to data
9062 * @extra: Pointer to extra data
9063 *
9064 * Return: 0 on success, non-zero on error
9065 */
9066static int iw_set_packet_filter_params(struct net_device *dev,
9067 struct iw_request_info *info,
9068 union iwreq_data *wrqu, char *extra)
9069{
9070 int ret;
9071
9072 cds_ssr_protect(__func__);
9073 ret = __iw_set_packet_filter_params(dev, info, wrqu, extra);
9074 cds_ssr_unprotect(__func__);
9075
9076 return ret;
9077}
9078#endif
9079
9080
9081static int __iw_get_statistics(struct net_device *dev,
9082 struct iw_request_info *info,
9083 union iwreq_data *wrqu, char *extra)
9084{
9085
Anurag Chouhance0dc992016-02-16 18:18:03 +05309086 QDF_STATUS qdf_status = QDF_STATUS_SUCCESS;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05309087 QDF_STATUS status = QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08009088 hdd_wext_state_t *pWextState;
9089 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
9090 hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(pAdapter);
9091 char *p = extra;
9092 int tlen = 0;
9093 tCsrSummaryStatsInfo *pStats = &(pAdapter->hdd_stats.summary_stat);
9094 tCsrGlobalClassAStatsInfo *aStats = &(pAdapter->hdd_stats.ClassA_stat);
9095 tCsrGlobalClassDStatsInfo *dStats = &(pAdapter->hdd_stats.ClassD_stat);
9096 int ret;
9097
Jeff Johnson6ee91ee2016-02-11 18:55:30 -08009098 ENTER_DEV(dev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08009099
9100 ret = wlan_hdd_validate_context(hdd_ctx);
9101 if (0 != ret)
9102 return ret;
9103
9104 if (eConnectionState_Associated !=
9105 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState) {
9106
9107 wrqu->txpower.value = 0;
9108 } else {
9109 status = sme_get_statistics(hdd_ctx->hHal, eCSR_HDD,
9110 SME_SUMMARY_STATS |
9111 SME_GLOBAL_CLASSA_STATS |
9112 SME_GLOBAL_CLASSB_STATS |
9113 SME_GLOBAL_CLASSC_STATS |
9114 SME_GLOBAL_CLASSD_STATS |
9115 SME_PER_STA_STATS,
9116 hdd_statistics_cb, 0, false,
9117 (WLAN_HDD_GET_STATION_CTX_PTR
9118 (pAdapter))->conn_info.staId[0],
9119 pAdapter, pAdapter->sessionId);
9120
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05309121 if (QDF_STATUS_SUCCESS != status) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05309122 hddLog(QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08009123 "%s: Unable to retrieve SME statistics",
9124 __func__);
9125 return -EINVAL;
9126 }
9127
9128 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
9129
Anurag Chouhance0dc992016-02-16 18:18:03 +05309130 qdf_status =
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05309131 qdf_wait_single_event(&pWextState->hdd_qdf_event,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08009132 WLAN_WAIT_TIME_STATS);
Anurag Chouhance0dc992016-02-16 18:18:03 +05309133 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05309134 hddLog(QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08009135 "%s: SME timeout while retrieving statistics",
9136 __func__);
9137 /*Remove the SME statistics list by passing NULL in callback argument */
9138 status = sme_get_statistics(hdd_ctx->hHal, eCSR_HDD,
9139 SME_SUMMARY_STATS |
9140 SME_GLOBAL_CLASSA_STATS |
9141 SME_GLOBAL_CLASSB_STATS |
9142 SME_GLOBAL_CLASSC_STATS |
9143 SME_GLOBAL_CLASSD_STATS |
9144 SME_PER_STA_STATS,
9145 NULL, 0, false,
9146 (WLAN_HDD_GET_STATION_CTX_PTR
9147 (pAdapter))->conn_info.
9148 staId[0], pAdapter,
9149 pAdapter->sessionId);
9150
9151 return -EINVAL;
9152 }
9153 FILL_TLV(p, (uint8_t) WLAN_STATS_RETRY_CNT,
9154 (uint8_t) sizeof(pStats->retry_cnt),
9155 (char *)&(pStats->retry_cnt[0]), tlen);
9156
9157 FILL_TLV(p, (uint8_t) WLAN_STATS_MUL_RETRY_CNT,
9158 (uint8_t) sizeof(pStats->multiple_retry_cnt),
9159 (char *)&(pStats->multiple_retry_cnt[0]), tlen);
9160
9161 FILL_TLV(p, (uint8_t) WLAN_STATS_TX_FRM_CNT,
9162 (uint8_t) sizeof(pStats->tx_frm_cnt),
9163 (char *)&(pStats->tx_frm_cnt[0]), tlen);
9164
9165 FILL_TLV(p, (uint8_t) WLAN_STATS_RX_FRM_CNT,
9166 (uint8_t) sizeof(pStats->rx_frm_cnt),
9167 (char *)&(pStats->rx_frm_cnt), tlen);
9168
9169 FILL_TLV(p, (uint8_t) WLAN_STATS_FRM_DUP_CNT,
9170 (uint8_t) sizeof(pStats->frm_dup_cnt),
9171 (char *)&(pStats->frm_dup_cnt), tlen);
9172
9173 FILL_TLV(p, (uint8_t) WLAN_STATS_FAIL_CNT,
9174 (uint8_t) sizeof(pStats->fail_cnt),
9175 (char *)&(pStats->fail_cnt[0]), tlen);
9176
9177 FILL_TLV(p, (uint8_t) WLAN_STATS_RTS_FAIL_CNT,
9178 (uint8_t) sizeof(pStats->rts_fail_cnt),
9179 (char *)&(pStats->rts_fail_cnt), tlen);
9180
9181 FILL_TLV(p, (uint8_t) WLAN_STATS_ACK_FAIL_CNT,
9182 (uint8_t) sizeof(pStats->ack_fail_cnt),
9183 (char *)&(pStats->ack_fail_cnt), tlen);
9184
9185 FILL_TLV(p, (uint8_t) WLAN_STATS_RTS_SUC_CNT,
9186 (uint8_t) sizeof(pStats->rts_succ_cnt),
9187 (char *)&(pStats->rts_succ_cnt), tlen);
9188
9189 FILL_TLV(p, (uint8_t) WLAN_STATS_RX_DISCARD_CNT,
9190 (uint8_t) sizeof(pStats->rx_discard_cnt),
9191 (char *)&(pStats->rx_discard_cnt), tlen);
9192
9193 FILL_TLV(p, (uint8_t) WLAN_STATS_RX_ERROR_CNT,
9194 (uint8_t) sizeof(pStats->rx_error_cnt),
9195 (char *)&(pStats->rx_error_cnt), tlen);
9196
9197 FILL_TLV(p, (uint8_t) WLAN_STATS_TX_BYTE_CNT,
9198 (uint8_t) sizeof(dStats->tx_uc_byte_cnt[0]),
9199 (char *)&(dStats->tx_uc_byte_cnt[0]), tlen);
9200
9201 FILL_TLV(p, (uint8_t) WLAN_STATS_RX_BYTE_CNT,
9202 (uint8_t) sizeof(dStats->rx_byte_cnt),
9203 (char *)&(dStats->rx_byte_cnt), tlen);
9204
9205 FILL_TLV(p, (uint8_t) WLAN_STATS_RX_RATE,
9206 (uint8_t) sizeof(dStats->rx_rate),
9207 (char *)&(dStats->rx_rate), tlen);
9208
9209 /* Transmit rate, in units of 500 kbit/sec */
9210 FILL_TLV(p, (uint8_t) WLAN_STATS_TX_RATE,
9211 (uint8_t) sizeof(aStats->tx_rate),
9212 (char *)&(aStats->tx_rate), tlen);
9213
9214 FILL_TLV(p, (uint8_t) WLAN_STATS_RX_UC_BYTE_CNT,
9215 (uint8_t) sizeof(dStats->rx_uc_byte_cnt[0]),
9216 (char *)&(dStats->rx_uc_byte_cnt[0]), tlen);
9217 FILL_TLV(p, (uint8_t) WLAN_STATS_RX_MC_BYTE_CNT,
9218 (uint8_t) sizeof(dStats->rx_mc_byte_cnt),
9219 (char *)&(dStats->rx_mc_byte_cnt), tlen);
9220 FILL_TLV(p, (uint8_t) WLAN_STATS_RX_BC_BYTE_CNT,
9221 (uint8_t) sizeof(dStats->rx_bc_byte_cnt),
9222 (char *)&(dStats->rx_bc_byte_cnt), tlen);
9223 FILL_TLV(p, (uint8_t) WLAN_STATS_TX_UC_BYTE_CNT,
9224 (uint8_t) sizeof(dStats->tx_uc_byte_cnt[0]),
9225 (char *)&(dStats->tx_uc_byte_cnt[0]), tlen);
9226 FILL_TLV(p, (uint8_t) WLAN_STATS_TX_MC_BYTE_CNT,
9227 (uint8_t) sizeof(dStats->tx_mc_byte_cnt),
9228 (char *)&(dStats->tx_mc_byte_cnt), tlen);
9229 FILL_TLV(p, (uint8_t) WLAN_STATS_TX_BC_BYTE_CNT,
9230 (uint8_t) sizeof(dStats->tx_bc_byte_cnt),
9231 (char *)&(dStats->tx_bc_byte_cnt), tlen);
9232
9233 wrqu->data.length = tlen;
9234
9235 }
9236
9237 EXIT();
9238
9239 return 0;
9240}
9241
9242static int iw_get_statistics(struct net_device *dev,
9243 struct iw_request_info *info,
9244 union iwreq_data *wrqu, char *extra)
9245{
9246 int ret;
9247
9248 cds_ssr_protect(__func__);
9249 ret = __iw_get_statistics(dev, info, wrqu, extra);
9250 cds_ssr_unprotect(__func__);
9251
9252 return ret;
9253}
9254
9255#ifdef FEATURE_WLAN_SCAN_PNO
9256
9257/*Max Len for PNO notification*/
9258#define MAX_PNO_NOTIFY_LEN 100
9259void found_pref_network_cb(void *callbackContext,
9260 tSirPrefNetworkFoundInd *pPrefNetworkFoundInd)
9261{
9262 hdd_adapter_t *pAdapter = (hdd_adapter_t *) callbackContext;
9263 union iwreq_data wrqu;
9264 char buf[MAX_PNO_NOTIFY_LEN + 1];
9265
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05309266 hddLog(QDF_TRACE_LEVEL_WARN,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08009267 "A preferred network was found: %s with rssi: -%d",
9268 pPrefNetworkFoundInd->ssId.ssId, pPrefNetworkFoundInd->rssi);
9269
9270 /* create the event */
9271 memset(&wrqu, 0, sizeof(wrqu));
9272 memset(buf, 0, sizeof(buf));
9273
9274 snprintf(buf, MAX_PNO_NOTIFY_LEN,
9275 "QCOM: Found preferred network: %s with RSSI of -%u",
9276 pPrefNetworkFoundInd->ssId.ssId,
9277 (unsigned int)pPrefNetworkFoundInd->rssi);
9278
9279 wrqu.data.pointer = buf;
9280 wrqu.data.length = strlen(buf);
9281
9282 /* send the event */
9283
9284 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, buf);
9285
9286}
9287
9288/**
9289 * __iw_set_pno() - Preferred Network Offload ioctl handler
9290 * @dev: device upon which the ioctl was received
9291 * @info: ioctl request information
9292 * @wrqu: ioctl request data
9293 * @extra: ioctl extra data
9294 *
9295 * This function parses a Preferred Network Offload command
9296 * Input is string based and expected to be of the form:
9297 *
9298 * <enable(1) | disable(0)>
9299 * when enabling:
9300 * <number of networks>
9301 * for each network:
9302 * <ssid_len> <ssid> <authentication> <encryption>
9303 * <ch_num> <channel_list optional> <bcast_type> <rssi_threshold>
9304 * <number of scan timers>
9305 * for each timer:
9306 * <scan_time> <scan_repeat>
9307 * <suspend mode>
9308 *
9309 * e.g:
9310 * 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
9311 *
9312 * this translates into:
9313 * -----------------------------
9314 * enable PNO
9315 * 2 networks
9316 * Network 1:
9317 * test - with authentication type 0 and encryption type 0,
9318 * search on 3 channels: 1 6 and 11,
9319 * SSID bcast type is unknown (directed probe will be sent if
9320 * AP not found) and must meet -40dBm RSSI
9321 * Network 2:
9322 * test2 - with authentication type 4 and encryption type 4,
9323 * search on 6 channels 1, 2, 3, 4, 5 and 6
9324 * bcast type is non-bcast (directed probe will be sent)
9325 * and must not meet any RSSI threshold
9326 * 2 scan timers:
9327 * scan every 5 seconds 2 times
9328 * then scan every 300 seconds until stopped
9329 * enable on suspend
9330 */
9331static int __iw_set_pno(struct net_device *dev,
9332 struct iw_request_info *info,
9333 union iwreq_data *wrqu, char *extra)
9334{
9335 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
9336 hdd_context_t *hdd_ctx;
9337 int ret;
9338 int offset;
9339 char *ptr;
9340 uint8_t i, j, params, mode;
9341
9342 /* request is a large struct, so we make it static to avoid
9343 * stack overflow. This API is only invoked via ioctl, so it
9344 * is serialized by the kernel rtnl_lock and hence does not
9345 * need to be reentrant
9346 */
9347 static tSirPNOScanReq request;
9348
Jeff Johnson6ee91ee2016-02-11 18:55:30 -08009349 ENTER_DEV(dev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08009350
9351 hdd_ctx = WLAN_HDD_GET_CTX(adapter);
9352 ret = wlan_hdd_validate_context(hdd_ctx);
9353 if (ret)
9354 return ret;
9355
9356 hdd_notice("PNO data len %d data %s", wrqu->data.length, extra);
9357
9358 request.enable = 0;
9359 request.ucNetworksCount = 0;
9360
9361 ptr = extra;
9362
9363 if (1 != sscanf(ptr, "%hhu%n", &(request.enable), &offset)) {
9364 hdd_err("PNO enable input is not valid %s", ptr);
9365 return -EINVAL;
9366 }
9367
9368 if (0 == request.enable) {
9369 /* Disable PNO, ignore any other params */
9370 memset(&request, 0, sizeof(request));
9371 sme_set_preferred_network_list(WLAN_HDD_GET_HAL_CTX(adapter),
9372 &request, adapter->sessionId,
9373 found_pref_network_cb, adapter);
9374 return 0;
9375 }
9376
9377 ptr += offset;
9378
9379 if (1 !=
9380 sscanf(ptr, "%hhu %n", &(request.ucNetworksCount), &offset)) {
9381 hdd_err("PNO count input not valid %s", ptr);
9382 return -EINVAL;
9383
9384 }
9385
9386 hdd_info("PNO enable %d networks count %d offset %d",
9387 request.enable, request.ucNetworksCount, offset);
9388
9389 if ((0 == request.ucNetworksCount) ||
9390 (request.ucNetworksCount > SIR_PNO_MAX_SUPP_NETWORKS)) {
9391 hdd_err("Network count %d invalid",
9392 request.ucNetworksCount);
9393 return -EINVAL;
9394 }
9395
9396 ptr += offset;
9397
9398 for (i = 0; i < request.ucNetworksCount; i++) {
9399
9400 request.aNetworks[i].ssId.length = 0;
9401
9402 params = sscanf(ptr, "%hhu %n",
9403 &(request.aNetworks[i].ssId.length),
9404 &offset);
9405
9406 if (1 != params) {
9407 hdd_err("PNO ssid length input is not valid %s", ptr);
9408 return -EINVAL;
9409 }
9410
9411 if ((0 == request.aNetworks[i].ssId.length) ||
9412 (request.aNetworks[i].ssId.length > 32)) {
9413 hdd_err("SSID Len %d is not correct for network %d",
9414 request.aNetworks[i].ssId.length, i);
9415 return -EINVAL;
9416 }
9417
9418 /* Advance to SSID */
9419 ptr += offset;
9420
9421 memcpy(request.aNetworks[i].ssId.ssId, ptr,
9422 request.aNetworks[i].ssId.length);
9423 ptr += request.aNetworks[i].ssId.length;
9424
9425 params = sscanf(ptr, "%u %u %hhu %n",
9426 &(request.aNetworks[i].authentication),
9427 &(request.aNetworks[i].encryption),
9428 &(request.aNetworks[i].ucChannelCount),
9429 &offset);
9430
9431 if (3 != params) {
9432 hdd_warn("Incorrect cmd %s", ptr);
9433 return -EINVAL;
9434 }
9435
9436 hdd_notice("PNO len %d ssid %.*s auth %d encry %d channel count %d offset %d",
9437 request.aNetworks[i].ssId.length,
9438 request.aNetworks[i].ssId.length,
9439 request.aNetworks[i].ssId.ssId,
9440 request.aNetworks[i].authentication,
9441 request.aNetworks[i].encryption,
9442 request.aNetworks[i].ucChannelCount, offset);
9443
9444 /* Advance to channel list */
9445 ptr += offset;
9446
9447 if (SIR_PNO_MAX_NETW_CHANNELS <
9448 request.aNetworks[i].ucChannelCount) {
9449 hdd_warn("Incorrect number of channels");
9450 return -EINVAL;
9451 }
9452
9453 if (0 != request.aNetworks[i].ucChannelCount) {
9454 for (j = 0; j < request.aNetworks[i].ucChannelCount;
9455 j++) {
9456 if (1 !=
9457 sscanf(ptr, "%hhu %n",
9458 &(request.aNetworks[i].
9459 aChannels[j]), &offset)) {
9460 hdd_err("PNO network channel input is not valid %s",
9461 ptr);
9462 return -EINVAL;
9463 }
9464 /* Advance to next channel number */
9465 ptr += offset;
9466 }
9467 }
9468
9469 if (1 != sscanf(ptr, "%u %n",
9470 &(request.aNetworks[i].bcastNetwType),
9471 &offset)) {
9472 hdd_err("PNO broadcast network type input is not valid %s",
9473 ptr);
9474 return -EINVAL;
9475 }
9476
9477 hdd_notice("PNO bcastNetwType %d offset %d",
9478 request.aNetworks[i].bcastNetwType, offset);
9479
9480 /* Advance to rssi Threshold */
9481 ptr += offset;
9482 if (1 != sscanf(ptr, "%d %n",
9483 &(request.aNetworks[i].rssiThreshold),
9484 &offset)) {
9485 hdd_err("PNO rssi threshold input is not valid %s",
9486 ptr);
9487 return -EINVAL;
9488 }
9489 hdd_notice("PNO rssi %d offset %d",
9490 request.aNetworks[i].rssiThreshold, offset);
9491 /* Advance to next network */
9492 ptr += offset;
9493 } /* For ucNetworkCount */
9494
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08009495 params = sscanf(ptr, "%hhu %n", &(mode), &offset);
9496
9497 request.modePNO = mode;
9498 /* for LA we just expose suspend option */
9499 if ((1 != params) || (mode >= SIR_PNO_MODE_MAX)) {
9500 request.modePNO = SIR_PNO_MODE_ON_SUSPEND;
9501 }
9502
9503 sme_set_preferred_network_list(WLAN_HDD_GET_HAL_CTX(adapter),
9504 &request,
9505 adapter->sessionId,
9506 found_pref_network_cb, adapter);
9507
9508 return 0;
9509}
9510
9511static int iw_set_pno(struct net_device *dev,
9512 struct iw_request_info *info,
9513 union iwreq_data *wrqu, char *extra)
9514{
9515 int ret;
9516
9517 cds_ssr_protect(__func__);
9518 ret = __iw_set_pno(dev, info, wrqu, extra);
9519 cds_ssr_unprotect(__func__);
9520
9521 return ret;
9522}
9523#endif /* FEATURE_WLAN_SCAN_PNO */
9524
9525/* Common function to SetBand */
9526int hdd_set_band(struct net_device *dev, u8 ui_band)
9527{
9528 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
9529 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
9530 eCsrBand band;
9531
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05309532 QDF_STATUS status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08009533 hdd_context_t *pHddCtx;
9534 hdd_adapter_list_node_t *pAdapterNode, *pNext;
9535 eCsrBand currBand = eCSR_BAND_MAX;
9536 eCsrBand connectedBand;
9537
9538 pAdapterNode = NULL;
9539 pNext = NULL;
9540 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
9541
9542 switch (ui_band) {
9543 case WLAN_HDD_UI_BAND_AUTO:
9544 band = eCSR_BAND_ALL;
9545 break;
9546 case WLAN_HDD_UI_BAND_5_GHZ:
9547 band = eCSR_BAND_5G;
9548 break;
9549 case WLAN_HDD_UI_BAND_2_4_GHZ:
9550 band = eCSR_BAND_24;
9551 break;
9552 default:
9553 band = eCSR_BAND_MAX;
9554 }
9555
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05309556 QDF_TRACE(QDF_MODULE_ID_HDD, QDF_TRACE_LEVEL_INFO,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08009557 "%s: change band to %u", __func__, band);
9558
9559 if (band == eCSR_BAND_MAX) {
9560 /* Received change band request with invalid band value */
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05309561 QDF_TRACE(QDF_MODULE_ID_HDD, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08009562 "%s: Invalid band value %u", __func__, ui_band);
9563 return -EINVAL;
9564 }
9565
9566 if ((band == eCSR_BAND_24 && pHddCtx->config->nBandCapability == 2) ||
9567 (band == eCSR_BAND_5G && pHddCtx->config->nBandCapability == 1)) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05309568 QDF_TRACE(QDF_MODULE_ID_HDD, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08009569 "%s: band value %u violate INI settings %u", __func__,
9570 band, pHddCtx->config->nBandCapability);
9571 return -EIO;
9572 }
9573
9574 if (band == eCSR_BAND_ALL) {
9575 hddLog(LOG1,
9576 FL("Auto band received. Setting band same as ini value %d"),
9577 pHddCtx->config->nBandCapability);
9578 band = pHddCtx->config->nBandCapability;
9579 }
9580
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05309581 if (QDF_STATUS_SUCCESS != sme_get_freq_band(hHal, &currBand)) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05309582 QDF_TRACE(QDF_MODULE_ID_HDD, QDF_TRACE_LEVEL_INFO,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08009583 "%s: Failed to get current band config", __func__);
9584 return -EIO;
9585 }
9586
9587 if (currBand != band) {
9588 /* Change band request received.
9589 * Abort pending scan requests, flush the existing scan results,
9590 * and change the band capability
9591 */
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05309592 QDF_TRACE(QDF_MODULE_ID_HDD, QDF_TRACE_LEVEL_INFO,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08009593 "%s: Current band value = %u, new setting %u ",
9594 __func__, currBand, band);
9595
9596 status = hdd_get_front_adapter(pHddCtx, &pAdapterNode);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05309597 while (NULL != pAdapterNode && QDF_STATUS_SUCCESS == status) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08009598 pAdapter = pAdapterNode->pAdapter;
9599 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
9600 hdd_abort_mac_scan(pHddCtx, pAdapter->sessionId,
9601 eCSR_SCAN_ABORT_DUE_TO_BAND_CHANGE);
9602 connectedBand =
9603 hdd_conn_get_connected_band
9604 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter));
9605
9606 /* Handling is done only for STA and P2P */
9607 if (band != eCSR_BAND_ALL &&
Krunal Sonif07bb382016-03-10 13:02:11 -08009608 ((pAdapter->device_mode == QDF_STA_MODE)
9609 || (pAdapter->device_mode == QDF_P2P_CLIENT_MODE))
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08009610 &&
9611 (hdd_conn_is_connected
9612 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter)))
9613 && (connectedBand != band)) {
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05309614 QDF_STATUS status = QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08009615 long lrc;
9616
9617 /* STA already connected on current band, So issue disconnect
9618 * first, then change the band*/
9619
9620 hddLog(LOG1,
9621 FL("STA (Device mode %s(%d)) connected in band %u, Changing band to %u, Issuing Disconnect"),
9622 hdd_device_mode_to_string(pAdapter->device_mode),
9623 pAdapter->device_mode, currBand, band);
9624 INIT_COMPLETION(pAdapter->disconnect_comp_var);
9625
9626 status =
9627 sme_roam_disconnect(WLAN_HDD_GET_HAL_CTX
9628 (pAdapter),
9629 pAdapter->sessionId,
9630 eCSR_DISCONNECT_REASON_UNSPECIFIED);
9631
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05309632 if (QDF_STATUS_SUCCESS != status) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05309633 hddLog(QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08009634 "%s csr_roam_disconnect failure, returned %d",
9635 __func__, (int)status);
9636 return -EINVAL;
9637 }
9638
9639 lrc =
9640 wait_for_completion_timeout(&pAdapter->
9641 disconnect_comp_var,
9642 msecs_to_jiffies
9643 (WLAN_WAIT_TIME_DISCONNECT));
9644
9645 if (lrc == 0) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05309646 hddLog(QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08009647 "%s:Timeout while waiting for csr_roam_disconnect",
9648 __func__);
9649 return -ETIMEDOUT;
9650 }
9651 }
9652
9653 sme_scan_flush_result(hHal);
9654
9655 status =
9656 hdd_get_next_adapter(pHddCtx, pAdapterNode, &pNext);
9657 pAdapterNode = pNext;
9658 }
9659
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05309660 if (QDF_STATUS_SUCCESS !=
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08009661 sme_set_freq_band(hHal, pAdapter->sessionId, band)) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05309662 QDF_TRACE(QDF_MODULE_ID_HDD, QDF_TRACE_LEVEL_FATAL,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08009663 FL("Failed to set the band value to %u"),
9664 band);
9665 return -EINVAL;
9666 }
9667 wlan_hdd_cfg80211_update_band(pHddCtx->wiphy, (eCsrBand) band);
9668 }
9669 return 0;
9670}
9671
9672int hdd_set_band_helper(struct net_device *dev, const char *command)
9673{
9674 uint8_t band;
9675 int ret;
9676
9677 /* Convert the band value from ascii to integer */
9678 command += WLAN_HDD_UI_SET_BAND_VALUE_OFFSET;
9679 ret = kstrtou8(command, 10, &band);
9680 if (ret < 0) {
9681 hddLog(LOGE, FL("kstrtou8 failed"));
9682 return -EINVAL;
9683 }
9684
9685 return hdd_set_band(dev, band);
9686}
9687
9688static int __iw_set_band_config(struct net_device *dev,
9689 struct iw_request_info *info,
9690 union iwreq_data *wrqu, char *extra)
9691{
9692 int *value = (int *)extra;
9693
Jeff Johnson6ee91ee2016-02-11 18:55:30 -08009694 ENTER_DEV(dev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08009695
Mukul Sharmaa5fe1982015-11-02 19:28:14 +05309696 if (!capable(CAP_NET_ADMIN)) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05309697 QDF_TRACE(QDF_MODULE_ID_HDD, QDF_TRACE_LEVEL_ERROR,
Mukul Sharmaa5fe1982015-11-02 19:28:14 +05309698 FL("permission check failed"));
9699 return -EPERM;
9700 }
9701
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08009702 return hdd_set_band(dev, value[0]);
9703}
9704
9705static int iw_set_band_config(struct net_device *dev,
9706 struct iw_request_info *info,
9707 union iwreq_data *wrqu, char *extra)
9708{
9709 int ret;
9710
9711 cds_ssr_protect(__func__);
9712 ret = __iw_set_band_config(dev, info, wrqu, extra);
9713 cds_ssr_unprotect(__func__);
9714
9715 return ret;
9716}
9717
9718static int __iw_set_two_ints_getnone(struct net_device *dev,
9719 struct iw_request_info *info,
9720 union iwreq_data *wrqu, char *extra)
9721{
9722 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
9723 int *value = (int *)extra;
9724 int sub_cmd = value[0];
9725 int ret;
9726 hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(pAdapter);
9727
Jeff Johnson6ee91ee2016-02-11 18:55:30 -08009728 ENTER_DEV(dev);
9729
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08009730 ret = wlan_hdd_validate_context(hdd_ctx);
9731 if (0 != ret)
9732 return ret;
9733
9734 switch (sub_cmd) {
9735 case WE_SET_SMPS_PARAM:
9736 hddLog(LOG1, "WE_SET_SMPS_PARAM val %d %d", value[1], value[2]);
9737 ret = wma_cli_set_command(pAdapter->sessionId,
9738 WMI_STA_SMPS_PARAM_CMDID,
9739 value[1] << WMA_SMPS_PARAM_VALUE_S
9740 | value[2],
9741 VDEV_CMD);
9742 break;
9743#ifdef DEBUG
9744 case WE_SET_FW_CRASH_INJECT:
9745 hddLog(LOGE, "WE_SET_FW_CRASH_INJECT: %d %d",
9746 value[1], value[2]);
DARAM SUDHA7e7e91b2015-05-29 11:38:47 +05309747 pr_err("SSR is triggered by iwpriv CRASH_INJECT: %d %d\n",
9748 value[1], value[2]);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08009749 ret = wma_cli_set2_command(pAdapter->sessionId,
9750 GEN_PARAM_CRASH_INJECT,
9751 value[1], value[2], GEN_CMD);
9752 break;
9753#endif
Govind Singha471e5e2015-10-12 17:11:14 +05309754 case WE_ENABLE_FW_PROFILE:
9755 hddLog(LOGE, "WE_ENABLE_FW_PROFILE: %d %d",
9756 value[1], value[2]);
9757 ret = wma_cli_set2_command(pAdapter->sessionId,
9758 WMI_WLAN_PROFILE_ENABLE_PROFILE_ID_CMDID,
9759 value[1], value[2], DBG_CMD);
9760 break;
9761 case WE_SET_FW_PROFILE_HIST_INTVL:
9762 hddLog(LOGE, "WE_SET_FW_PROFILE_HIST_INTVL: %d %d",
9763 value[1], value[2]);
9764 ret = wma_cli_set2_command(pAdapter->sessionId,
9765 WMI_WLAN_PROFILE_SET_HIST_INTVL_CMDID,
9766 value[1], value[2], DBG_CMD);
9767 break;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08009768 case WE_SET_DUAL_MAC_FW_MODE_CONFIG:
9769 hdd_debug("Ioctl to set dual fw mode config");
9770 if (hdd_ctx->config->dual_mac_feature_disable) {
9771 hdd_err("Dual mac feature is disabled from INI");
9772 return -EPERM;
9773 }
9774 hdd_debug("%d %d", value[1], value[2]);
Tushnim Bhattacharyya4adb3682016-01-07 15:07:12 -08009775 cds_set_dual_mac_fw_mode_config(value[1], value[2]);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08009776 break;
9777 case WE_DUMP_DP_TRACE_LEVEL:
9778 hdd_info("WE_DUMP_DP_TRACE_LEVEL: %d %d",
9779 value[1], value[2]);
9780 if (value[1] == DUMP_DP_TRACE)
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05309781 qdf_dp_trace_dump_all(value[2]);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08009782 break;
9783 default:
9784 hddLog(LOGE, "%s: Invalid IOCTL command %d", __func__, sub_cmd);
9785 break;
9786 }
9787
9788 return ret;
9789}
9790
9791static int iw_set_two_ints_getnone(struct net_device *dev,
9792 struct iw_request_info *info,
9793 union iwreq_data *wrqu, char *extra)
9794{
9795 int ret;
9796
9797 cds_ssr_protect(__func__);
9798 ret = __iw_set_two_ints_getnone(dev, info, wrqu, extra);
9799 cds_ssr_unprotect(__func__);
9800
9801 return ret;
9802}
9803
9804/* Define the Wireless Extensions to the Linux Network Device structure */
9805/* A number of these routines are NULL (meaning they are not implemented.) */
9806
9807static const iw_handler we_handler[] = {
9808 (iw_handler) iw_set_commit, /* SIOCSIWCOMMIT */
9809 (iw_handler) iw_get_name, /* SIOCGIWNAME */
9810 (iw_handler) NULL, /* SIOCSIWNWID */
9811 (iw_handler) NULL, /* SIOCGIWNWID */
9812 (iw_handler) iw_set_freq, /* SIOCSIWFREQ */
9813 (iw_handler) iw_get_freq, /* SIOCGIWFREQ */
9814 (iw_handler) iw_set_mode, /* SIOCSIWMODE */
9815 (iw_handler) iw_get_mode, /* SIOCGIWMODE */
9816 (iw_handler) NULL, /* SIOCSIWSENS */
9817 (iw_handler) NULL, /* SIOCGIWSENS */
9818 (iw_handler) NULL, /* SIOCSIWRANGE */
9819 (iw_handler) iw_get_range, /* SIOCGIWRANGE */
9820 (iw_handler) NULL, /* SIOCSIWPRIV */
9821 (iw_handler) NULL, /* SIOCGIWPRIV */
9822 (iw_handler) NULL, /* SIOCSIWSTATS */
9823 (iw_handler) NULL, /* SIOCGIWSTATS */
9824 (iw_handler) NULL, /* SIOCSIWSPY */
9825 (iw_handler) NULL, /* SIOCGIWSPY */
9826 (iw_handler) NULL, /* SIOCSIWTHRSPY */
9827 (iw_handler) NULL, /* SIOCGIWTHRSPY */
9828 (iw_handler) iw_set_ap_address, /* SIOCSIWAP */
9829 (iw_handler) iw_get_ap_address, /* SIOCGIWAP */
9830 (iw_handler) iw_set_mlme, /* SIOCSIWMLME */
9831 (iw_handler) NULL, /* SIOCGIWAPLIST */
9832 (iw_handler) iw_set_scan, /* SIOCSIWSCAN */
9833 (iw_handler) iw_get_scan, /* SIOCGIWSCAN */
9834 (iw_handler) iw_set_essid, /* SIOCSIWESSID */
9835 (iw_handler) iw_get_essid, /* SIOCGIWESSID */
9836 (iw_handler) iw_set_nick, /* SIOCSIWNICKN */
9837 (iw_handler) iw_get_nick, /* SIOCGIWNICKN */
9838 (iw_handler) NULL, /* -- hole -- */
9839 (iw_handler) NULL, /* -- hole -- */
9840 (iw_handler) iw_set_bitrate, /* SIOCSIWRATE */
9841 (iw_handler) iw_get_bitrate, /* SIOCGIWRATE */
9842 (iw_handler) iw_set_rts_threshold, /* SIOCSIWRTS */
9843 (iw_handler) iw_get_rts_threshold, /* SIOCGIWRTS */
9844 (iw_handler) iw_set_frag_threshold, /* SIOCSIWFRAG */
9845 (iw_handler) iw_get_frag_threshold, /* SIOCGIWFRAG */
9846 (iw_handler) iw_set_tx_power, /* SIOCSIWTXPOW */
9847 (iw_handler) iw_get_tx_power, /* SIOCGIWTXPOW */
9848 (iw_handler) iw_set_retry, /* SIOCSIWRETRY */
9849 (iw_handler) iw_get_retry, /* SIOCGIWRETRY */
9850 (iw_handler) iw_set_encode, /* SIOCSIWENCODE */
9851 (iw_handler) iw_get_encode, /* SIOCGIWENCODE */
9852 (iw_handler) iw_set_power_mode, /* SIOCSIWPOWER */
9853 (iw_handler) iw_get_power_mode, /* SIOCGIWPOWER */
9854 (iw_handler) NULL, /* -- hole -- */
9855 (iw_handler) NULL, /* -- hole -- */
9856 (iw_handler) iw_set_genie, /* SIOCSIWGENIE */
9857 (iw_handler) iw_get_genie, /* SIOCGIWGENIE */
9858 (iw_handler) iw_set_auth, /* SIOCSIWAUTH */
9859 (iw_handler) iw_get_auth, /* SIOCGIWAUTH */
9860 (iw_handler) iw_set_encodeext, /* SIOCSIWENCODEEXT */
9861 (iw_handler) iw_get_encodeext, /* SIOCGIWENCODEEXT */
9862 (iw_handler) NULL, /* SIOCSIWPMKSA */
9863};
9864
9865static const iw_handler we_private[] = {
9866
9867 [WLAN_PRIV_SET_INT_GET_NONE - SIOCIWFIRSTPRIV] = iw_setint_getnone, /* set priv ioctl */
9868 [WLAN_PRIV_SET_NONE_GET_INT - SIOCIWFIRSTPRIV] = iw_setnone_getint, /* get priv ioctl */
9869 [WLAN_PRIV_SET_CHAR_GET_NONE - SIOCIWFIRSTPRIV] = iw_setchar_getnone, /* get priv ioctl */
9870 [WLAN_PRIV_SET_THREE_INT_GET_NONE - SIOCIWFIRSTPRIV] =
9871 iw_set_three_ints_getnone,
9872 [WLAN_PRIV_GET_CHAR_SET_NONE - SIOCIWFIRSTPRIV] = iw_get_char_setnone,
9873 [WLAN_PRIV_SET_NONE_GET_NONE - SIOCIWFIRSTPRIV] = iw_setnone_getnone, /* action priv ioctl */
9874 [WLAN_PRIV_SET_VAR_INT_GET_NONE - SIOCIWFIRSTPRIV] =
9875 iw_hdd_set_var_ints_getnone,
Manikandan Mohandcc21ba2016-03-15 14:31:56 -07009876 [WLAN_PRIV_SET_NONE_GET_THREE_INT - SIOCIWFIRSTPRIV] =
9877 iw_setnone_get_threeint,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08009878 [WLAN_PRIV_ADD_TSPEC - SIOCIWFIRSTPRIV] = iw_add_tspec,
9879 [WLAN_PRIV_DEL_TSPEC - SIOCIWFIRSTPRIV] = iw_del_tspec,
9880 [WLAN_PRIV_GET_TSPEC - SIOCIWFIRSTPRIV] = iw_get_tspec,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08009881 [WLAN_PRIV_SET_FTIES - SIOCIWFIRSTPRIV] = iw_set_fties,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08009882 [WLAN_PRIV_SET_HOST_OFFLOAD - SIOCIWFIRSTPRIV] = iw_set_host_offload,
9883 [WLAN_GET_WLAN_STATISTICS - SIOCIWFIRSTPRIV] = iw_get_statistics,
9884 [WLAN_SET_KEEPALIVE_PARAMS - SIOCIWFIRSTPRIV] =
9885 iw_set_keepalive_params,
9886#ifdef WLAN_FEATURE_PACKET_FILTERING
9887 [WLAN_SET_PACKET_FILTER_PARAMS - SIOCIWFIRSTPRIV] =
9888 iw_set_packet_filter_params,
9889#endif
9890#ifdef FEATURE_WLAN_SCAN_PNO
9891 [WLAN_SET_PNO - SIOCIWFIRSTPRIV] = iw_set_pno,
9892#endif
9893 [WLAN_SET_BAND_CONFIG - SIOCIWFIRSTPRIV] = iw_set_band_config,
9894 [WLAN_GET_LINK_SPEED - SIOCIWFIRSTPRIV] = iw_get_linkspeed,
9895 [WLAN_PRIV_SET_TWO_INT_GET_NONE - SIOCIWFIRSTPRIV] =
9896 iw_set_two_ints_getnone,
9897 [WLAN_SET_DOT11P_CHANNEL_SCHED - SIOCIWFIRSTPRIV] =
9898 iw_set_dot11p_channel_sched,
9899};
9900
9901/*Maximum command length can be only 15 */
9902static const struct iw_priv_args we_private_args[] = {
9903
9904 /* handlers for main ioctl */
9905 {WLAN_PRIV_SET_INT_GET_NONE,
9906 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
9907 0,
9908 ""},
9909
9910 /* handlers for sub-ioctl */
9911 {WE_SET_11D_STATE,
9912 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
9913 0,
9914 "set11Dstate"},
9915
9916 {WE_WOWL,
9917 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
9918 0,
9919 "wowl"},
9920
9921 {WE_SET_POWER,
9922 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
9923 0,
9924 "setPower"},
9925
9926 {WE_SET_MAX_ASSOC,
9927 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
9928 0,
9929 "setMaxAssoc"},
9930
9931 {WE_SET_SAP_AUTO_CHANNEL_SELECTION,
9932 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0,
9933 "setAutoChannel" },
9934
9935 {WE_SET_SCAN_DISABLE,
9936 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
9937 0,
9938 "scan_disable"},
9939
9940 {WE_SET_DATA_INACTIVITY_TO,
9941 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
9942 0,
9943 "inactivityTO"},
9944
9945 {WE_SET_MAX_TX_POWER,
9946 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
9947 0,
9948 "setMaxTxPower"},
9949
9950 {WE_SET_TX_POWER,
9951 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
9952 0,
9953 "setTxPower"},
9954
9955 {WE_SET_MC_RATE,
9956 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
9957 0,
9958 "setMcRate"},
9959
9960 {WE_SET_MAX_TX_POWER_2_4,
9961 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
9962 0,
9963 "setTxMaxPower2G"},
9964
9965 {WE_SET_MAX_TX_POWER_5_0,
9966 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
9967 0,
9968 "setTxMaxPower5G"},
9969
9970 /* SAP has TxMax whereas STA has MaxTx, adding TxMax for STA
9971 * as well to keep same syntax as in SAP. Now onwards, STA
9972 * will support both */
9973 {WE_SET_MAX_TX_POWER,
9974 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
9975 0,
9976 "setTxMaxPower"},
9977
9978 /* set Higher DTIM Transition (DTIM1 to DTIM3)
9979 * 1 = enable and 0 = disable */
9980 {
9981 WE_SET_HIGHER_DTIM_TRANSITION,
9982 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
9983 0,
9984 "setHDtimTransn"
9985 },
9986
9987 {WE_SET_TM_LEVEL,
9988 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
9989 0,
9990 "setTmLevel"},
9991
9992 {WE_SET_PHYMODE,
9993 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
9994 0,
9995 "setphymode"},
9996
9997 {WE_SET_NSS,
9998 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
9999 0,
10000 "nss"},
10001
10002 {WE_SET_LDPC,
10003 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10004 0,
10005 "ldpc"},
10006
10007 {WE_SET_TX_STBC,
10008 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10009 0,
10010 "tx_stbc"},
10011
10012 {WE_SET_RX_STBC,
10013 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10014 0,
10015 "rx_stbc"},
10016
10017 {WE_SET_SHORT_GI,
10018 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10019 0,
10020 "shortgi"},
10021
10022 {WE_SET_RTSCTS,
10023 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10024 0,
10025 "enablertscts"},
10026
10027 {WE_SET_CHWIDTH,
10028 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10029 0,
10030 "chwidth"},
10031
10032 {WE_SET_ANI_EN_DIS,
10033 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10034 0,
10035 "anienable"},
10036
10037 {WE_SET_ANI_POLL_PERIOD,
10038 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10039 0,
10040 "aniplen"},
10041
10042 {WE_SET_ANI_LISTEN_PERIOD,
10043 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10044 0,
10045 "anilislen"},
10046
10047 {WE_SET_ANI_OFDM_LEVEL,
10048 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10049 0,
10050 "aniofdmlvl"},
10051
10052 {WE_SET_ANI_CCK_LEVEL,
10053 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10054 0,
10055 "aniccklvl"},
10056
10057 {WE_SET_DYNAMIC_BW,
10058 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10059 0,
10060 "cwmenable"},
10061
10062 {WE_SET_CTS_CBW,
10063 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10064 0,
10065 "cts_cbw" },
10066
10067 {WE_SET_GTX_HT_MCS,
10068 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10069 0,
10070 "gtxHTMcs"},
10071
10072 {WE_SET_GTX_VHT_MCS,
10073 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10074 0,
10075 "gtxVHTMcs"},
10076
10077 {WE_SET_GTX_USRCFG,
10078 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10079 0,
10080 "gtxUsrCfg"},
10081
10082 {WE_SET_GTX_THRE,
10083 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10084 0,
10085 "gtxThre"},
10086
10087 {WE_SET_GTX_MARGIN,
10088 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10089 0,
10090 "gtxMargin"},
10091
10092 {WE_SET_GTX_STEP,
10093 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10094 0,
10095 "gtxStep"},
10096
10097 {WE_SET_GTX_MINTPC,
10098 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10099 0,
10100 "gtxMinTpc"},
10101
10102 {WE_SET_GTX_BWMASK,
10103 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10104 0,
10105 "gtxBWMask"},
10106
10107 {WE_SET_TX_CHAINMASK,
10108 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10109 0,
10110 "txchainmask"},
10111
10112 {WE_SET_RX_CHAINMASK,
10113 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10114 0,
10115 "rxchainmask"},
10116
10117 {WE_SET_11N_RATE,
10118 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10119 0,
10120 "set11NRates"},
10121
10122 {WE_SET_VHT_RATE,
10123 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10124 0,
10125 "set11ACRates"},
10126
10127 {WE_SET_AMPDU,
10128 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10129 0,
10130 "ampdu"},
10131
10132 {WE_SET_AMSDU,
10133 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10134 0,
10135 "amsdu"},
10136
10137 {WE_SET_BURST_ENABLE,
10138 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10139 0,
10140 "burst_enable"},
10141
10142 {WE_SET_BURST_DUR,
10143 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10144 0,
10145 "burst_dur"},
10146
10147 {WE_SET_TXPOW_2G,
10148 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10149 0,
10150 "txpow2g"},
10151
10152 {WE_SET_TXPOW_5G,
10153 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10154 0,
10155 "txpow5g"},
10156
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080010157 /* Sub-cmds DBGLOG specific commands */
10158 {WE_DBGLOG_LOG_LEVEL,
10159 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10160 0,
10161 "dl_loglevel"},
10162
10163 {WE_DBGLOG_VAP_ENABLE,
10164 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10165 0,
10166 "dl_vapon"},
10167
10168 {WE_DBGLOG_VAP_DISABLE,
10169 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10170 0,
10171 "dl_vapoff"},
10172
10173 {WE_DBGLOG_MODULE_ENABLE,
10174 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10175 0,
10176 "dl_modon"},
10177
10178 {WE_DBGLOG_MODULE_DISABLE,
10179 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10180 0,
10181 "dl_modoff"},
10182
10183 {WE_DBGLOG_MOD_LOG_LEVEL,
10184 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10185 0,
10186 "dl_mod_loglevel"},
10187
10188 {WE_DBGLOG_TYPE,
10189 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10190 0,
10191 "dl_type"},
10192 {WE_DBGLOG_REPORT_ENABLE,
10193 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10194 0,
10195 "dl_report"},
10196
10197 {WE_SET_TXRX_FWSTATS,
10198 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10199 0,
10200 "txrx_fw_stats"},
10201
10202 {WE_TXRX_FWSTATS_RESET,
10203 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10204 0,
10205 "txrx_fw_st_rst"},
10206
10207 {WE_PPS_PAID_MATCH,
10208 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10209 0, "paid_match"},
10210
10211 {WE_PPS_GID_MATCH,
10212 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10213 0, "gid_match"},
10214
10215 {WE_PPS_EARLY_TIM_CLEAR,
10216 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10217 0, "tim_clear"},
10218
10219 {WE_PPS_EARLY_DTIM_CLEAR,
10220 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10221 0, "dtim_clear"},
10222
10223 {WE_PPS_EOF_PAD_DELIM,
10224 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10225 0, "eof_delim"},
10226
10227 {WE_PPS_MACADDR_MISMATCH,
10228 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10229 0, "mac_match"},
10230
10231 {WE_PPS_DELIM_CRC_FAIL,
10232 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10233 0, "delim_fail"},
10234
10235 {WE_PPS_GID_NSTS_ZERO,
10236 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10237 0, "nsts_zero"},
10238
10239 {WE_PPS_RSSI_CHECK,
10240 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10241 0, "rssi_chk"},
10242
10243 {WE_PPS_5G_EBT,
10244 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10245 0, "5g_ebt"},
10246
10247 {WE_SET_HTSMPS,
10248 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10249 0, "htsmps"},
10250
10251 {WE_SET_QPOWER_MAX_PSPOLL_COUNT,
10252 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10253 0, "set_qpspollcnt"},
10254
10255 {WE_SET_QPOWER_MAX_TX_BEFORE_WAKE,
10256 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10257 0, "set_qtxwake"},
10258
10259 {WE_SET_QPOWER_SPEC_PSPOLL_WAKE_INTERVAL,
10260 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10261 0, "set_qwakeintv"},
10262
10263 {WE_SET_QPOWER_SPEC_MAX_SPEC_NODATA_PSPOLL,
10264 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10265 0, "set_qnodatapoll"},
10266
10267 /* handlers for MCC time quota and latency sub ioctls */
10268 {WE_MCC_CONFIG_LATENCY,
10269 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10270 0, "setMccLatency"},
10271
10272 {WE_MCC_CONFIG_QUOTA,
10273 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10274 0, "setMccQuota"},
10275
10276 {WE_SET_DEBUG_LOG,
10277 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10278 0, "setDbgLvl"},
10279
10280 /* handlers for early_rx power save */
10281 {WE_SET_EARLY_RX_ADJUST_ENABLE,
10282 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10283 0, "erx_enable"},
10284
10285 {WE_SET_EARLY_RX_TGT_BMISS_NUM,
10286 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10287 0, "erx_bmiss_val"},
10288
10289 {WE_SET_EARLY_RX_BMISS_SAMPLE_CYCLE,
10290 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10291 0, "erx_bmiss_smpl"},
10292
10293 {WE_SET_EARLY_RX_SLOP_STEP,
10294 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10295 0, "erx_slop_step"},
10296
10297 {WE_SET_EARLY_RX_INIT_SLOP,
10298 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10299 0, "erx_init_slop"},
10300
10301 {WE_SET_EARLY_RX_ADJUST_PAUSE,
10302 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10303 0, "erx_adj_pause"},
10304
10305 {WE_SET_EARLY_RX_DRIFT_SAMPLE,
10306 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10307 0, "erx_dri_sample"},
10308
10309 {WE_DUMP_STATS,
10310 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10311 0, "dumpStats"},
10312
10313 {WE_CLEAR_STATS,
10314 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10315 0, "clearStats"},
10316
Govind Singha471e5e2015-10-12 17:11:14 +053010317 {WE_START_FW_PROFILE,
10318 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10319 0, "startProfile"},
10320
Abhishek Singh1bdb1572015-10-16 16:24:19 +053010321 {WE_SET_CHANNEL,
10322 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10323 0, "setChanChange" },
10324
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080010325 {WLAN_PRIV_SET_NONE_GET_INT,
10326 0,
10327 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10328 ""},
10329
10330 /* handlers for sub-ioctl */
10331 {WE_GET_11D_STATE,
10332 0,
10333 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10334 "get11Dstate"},
10335
10336 {WE_IBSS_STATUS,
10337 0,
10338 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10339 "getAdhocStatus"},
10340
10341 {WE_GET_WLAN_DBG,
10342 0,
10343 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10344 "getwlandbg"},
10345
10346 {WE_GET_MAX_ASSOC,
10347 0,
10348 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10349 "getMaxAssoc"},
10350
10351 {WE_GET_SAP_AUTO_CHANNEL_SELECTION,
10352 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10353 "getAutoChannel" },
10354
10355 {WE_GET_CONCURRENCY_MODE,
10356 0,
10357 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10358 "getconcurrency"},
10359
10360 {WE_GET_NSS,
10361 0,
10362 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10363 "get_nss"},
10364
10365 {WE_GET_LDPC,
10366 0,
10367 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10368 "get_ldpc"},
10369
10370 {WE_GET_TX_STBC,
10371 0,
10372 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10373 "get_tx_stbc"},
10374
10375 {WE_GET_RX_STBC,
10376 0,
10377 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10378 "get_rx_stbc"},
10379
10380 {WE_GET_SHORT_GI,
10381 0,
10382 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10383 "get_shortgi"},
10384
10385 {WE_GET_RTSCTS,
10386 0,
10387 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10388 "get_rtscts"},
10389
10390 {WE_GET_CHWIDTH,
10391 0,
10392 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10393 "get_chwidth"},
10394
10395 {WE_GET_ANI_EN_DIS,
10396 0,
10397 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10398 "get_anienable"},
10399
10400 {WE_GET_ANI_POLL_PERIOD,
10401 0,
10402 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10403 "get_aniplen"},
10404
10405 {WE_GET_ANI_LISTEN_PERIOD,
10406 0,
10407 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10408 "get_anilislen"},
10409
10410 {WE_GET_ANI_OFDM_LEVEL,
10411 0,
10412 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10413 "get_aniofdmlvl"},
10414
10415 {WE_GET_ANI_CCK_LEVEL,
10416 0,
10417 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10418 "get_aniccklvl"},
10419
10420 {WE_GET_DYNAMIC_BW,
10421 0,
10422 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10423 "get_cwmenable"},
10424
10425 {WE_GET_GTX_HT_MCS,
10426 0,
10427 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10428 "get_gtxHTMcs"},
10429
10430 {WE_GET_GTX_VHT_MCS,
10431 0,
10432 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10433 "get_gtxVHTMcs"},
10434
10435 {WE_GET_GTX_USRCFG,
10436 0,
10437 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10438 "get_gtxUsrCfg"},
10439
10440 {WE_GET_GTX_THRE,
10441 0,
10442 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10443 "get_gtxThre"},
10444
10445 {WE_GET_GTX_MARGIN,
10446 0,
10447 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10448 "get_gtxMargin"},
10449
10450 {WE_GET_GTX_STEP,
10451 0,
10452 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10453 "get_gtxStep"},
10454
10455 {WE_GET_GTX_MINTPC,
10456 0,
10457 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10458 "get_gtxMinTpc"},
10459
10460 {WE_GET_GTX_BWMASK,
10461 0,
10462 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10463 "get_gtxBWMask"},
10464
10465 {WE_GET_TX_CHAINMASK,
10466 0,
10467 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10468 "get_txchainmask"},
10469
10470 {WE_GET_RX_CHAINMASK,
10471 0,
10472 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10473 "get_rxchainmask"},
10474
10475 {WE_GET_11N_RATE,
10476 0,
10477 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10478 "get_11nrate"},
10479
10480 {WE_GET_AMPDU,
10481 0,
10482 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10483 "get_ampdu"},
10484
10485 {WE_GET_AMSDU,
10486 0,
10487 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10488 "get_amsdu"},
10489
10490 {WE_GET_BURST_ENABLE,
10491 0,
10492 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10493 "get_burst_en"},
10494
10495 {WE_GET_BURST_DUR,
10496 0,
10497 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10498 "get_burst_dur"},
10499
10500 {WE_GET_TXPOW_2G,
10501 0,
10502 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10503 "get_txpow2g"},
10504
10505 {WE_GET_TXPOW_5G,
10506 0,
10507 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10508 "get_txpow5g"},
10509
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080010510 {WE_GET_PPS_PAID_MATCH,
10511 0,
10512 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10513 "get_paid_match"},
10514
10515 {WE_GET_PPS_GID_MATCH,
10516 0,
10517 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10518 "get_gid_match"},
10519
10520 {WE_GET_PPS_EARLY_TIM_CLEAR,
10521 0,
10522 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10523 "get_tim_clear"},
10524
10525 {WE_GET_PPS_EARLY_DTIM_CLEAR,
10526 0,
10527 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10528 "get_dtim_clear"},
10529
10530 {WE_GET_PPS_EOF_PAD_DELIM,
10531 0,
10532 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10533 "get_eof_delim"},
10534
10535 {WE_GET_PPS_MACADDR_MISMATCH,
10536 0,
10537 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10538 "get_mac_match"},
10539
10540 {WE_GET_PPS_DELIM_CRC_FAIL,
10541 0,
10542 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10543 "get_delim_fail"},
10544
10545 {WE_GET_PPS_GID_NSTS_ZERO,
10546 0,
10547 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10548 "get_nsts_zero"},
10549
10550 {WE_GET_PPS_RSSI_CHECK,
10551 0,
10552 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10553 "get_rssi_chk"},
10554
10555 {WE_GET_QPOWER_MAX_PSPOLL_COUNT,
10556 0,
10557 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10558 "get_qpspollcnt"},
10559
10560 {WE_GET_QPOWER_MAX_TX_BEFORE_WAKE,
10561 0,
10562 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10563 "get_qtxwake"},
10564
10565 {WE_GET_QPOWER_SPEC_PSPOLL_WAKE_INTERVAL,
10566 0,
10567 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10568 "get_qwakeintv"},
10569
10570 {WE_GET_QPOWER_SPEC_MAX_SPEC_NODATA_PSPOLL,
10571 0,
10572 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10573 "get_qnodatapoll"},
10574
Manikandan Mohandcc21ba2016-03-15 14:31:56 -070010575 {WE_CAP_TSF,
10576 0,
10577 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10578 "cap_tsf"},
10579
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080010580 {WE_GET_TEMPERATURE,
10581 0,
10582 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10583 "get_temp"},
10584 /* handlers for main ioctl */
10585 {WLAN_PRIV_SET_CHAR_GET_NONE,
10586 IW_PRIV_TYPE_CHAR | 512,
10587 0,
10588 ""},
10589
10590 /* handlers for sub-ioctl */
10591 {WE_WOWL_ADD_PTRN,
10592 IW_PRIV_TYPE_CHAR | 512,
10593 0,
10594 "wowlAddPtrn"},
10595
10596 {WE_WOWL_DEL_PTRN,
10597 IW_PRIV_TYPE_CHAR | 512,
10598 0,
10599 "wowlDelPtrn"},
10600
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080010601 /* handlers for sub-ioctl */
10602 {WE_NEIGHBOR_REPORT_REQUEST,
10603 IW_PRIV_TYPE_CHAR | 512,
10604 0,
10605 "neighbor"},
Deepak Dhamdhere641bf322016-01-06 15:19:03 -080010606
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080010607 {WE_SET_AP_WPS_IE,
10608 IW_PRIV_TYPE_CHAR | 512,
10609 0,
10610 "set_ap_wps_ie"},
10611
10612 {WE_SET_CONFIG,
10613 IW_PRIV_TYPE_CHAR | 512,
10614 0,
10615 "setConfig"},
10616
10617 /* handlers for main ioctl */
10618 {WLAN_PRIV_SET_THREE_INT_GET_NONE,
10619 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 3,
10620 0,
10621 ""},
10622
10623 /* handlers for sub-ioctl */
10624 {WE_SET_WLAN_DBG,
10625 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 3,
10626 0,
10627 "setwlandbg"},
10628
10629 /* handlers for sub-ioctl */
10630 {WE_SET_DP_TRACE,
10631 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 3,
10632 0,
10633 "set_dp_trace"},
10634
10635 {WE_SET_SAP_CHANNELS,
10636 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 3,
10637 0,
10638 "setsapchannels"},
Manikandan Mohandcc21ba2016-03-15 14:31:56 -070010639 /* handlers for main ioctl */
10640 {WLAN_PRIV_SET_NONE_GET_THREE_INT,
10641 0,
10642 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 3,
10643 "" },
10644 {WE_GET_TSF,
10645 0,
10646 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 3,
10647 "get_tsf" },
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080010648
10649 {WE_SET_DUAL_MAC_SCAN_CONFIG,
10650 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 3,
10651 0,
10652 "set_scan_cfg"},
10653
10654 /* handlers for main ioctl */
10655 {WLAN_PRIV_GET_CHAR_SET_NONE,
10656 0,
10657 IW_PRIV_TYPE_CHAR | WE_MAX_STR_LEN,
10658 ""},
10659
10660 /* handlers for sub-ioctl */
10661 {WE_WLAN_VERSION,
10662 0,
10663 IW_PRIV_TYPE_CHAR | WE_MAX_STR_LEN,
10664 "version"},
10665 {WE_GET_STATS,
10666 0,
10667 IW_PRIV_TYPE_CHAR | WE_MAX_STR_LEN,
10668 "getStats"},
Govind Singha471e5e2015-10-12 17:11:14 +053010669 {WE_LIST_FW_PROFILE,
10670 0,
10671 IW_PRIV_TYPE_CHAR | WE_MAX_STR_LEN,
10672 "listProfile"},
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080010673 {WE_GET_STATES,
10674 0,
10675 IW_PRIV_TYPE_CHAR | WE_MAX_STR_LEN,
10676 "getHostStates"},
10677 {WE_GET_CFG,
10678 0,
10679 IW_PRIV_TYPE_CHAR | WE_MAX_STR_LEN,
10680 "getConfig"},
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080010681 {WE_GET_RSSI,
10682 0,
10683 IW_PRIV_TYPE_CHAR | WE_MAX_STR_LEN,
10684 "getRSSI"},
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080010685 {WE_GET_WMM_STATUS,
10686 0,
10687 IW_PRIV_TYPE_CHAR | WE_MAX_STR_LEN,
10688 "getWmmStatus"},
10689 {
10690 WE_GET_CHANNEL_LIST,
10691 0,
10692 IW_PRIV_TYPE_CHAR | WE_MAX_STR_LEN,
10693 "getChannelList"
10694 },
10695#ifdef FEATURE_WLAN_TDLS
10696 {
10697 WE_GET_TDLS_PEERS,
10698 0,
10699 IW_PRIV_TYPE_CHAR | WE_MAX_STR_LEN,
10700 "getTdlsPeers"
10701 },
10702#endif
10703#ifdef WLAN_FEATURE_11W
10704 {
10705 WE_GET_11W_INFO,
10706 0,
10707 IW_PRIV_TYPE_CHAR | WE_MAX_STR_LEN,
10708 "getPMFInfo"
10709 },
10710#endif
Rajeev Kumar8e3e2832015-11-06 16:02:54 -080010711 {
10712 WE_GET_IBSS_STA_INFO,
10713 0,
10714 IW_PRIV_TYPE_CHAR | WE_MAX_STR_LEN,
10715 "getIbssSTAs"
10716 },
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080010717 {WE_GET_PHYMODE,
10718 0,
10719 IW_PRIV_TYPE_CHAR | WE_MAX_STR_LEN,
10720 "getphymode"},
10721#ifdef FEATURE_OEM_DATA_SUPPORT
10722 {WE_GET_OEM_DATA_CAP,
10723 0,
10724 IW_PRIV_TYPE_CHAR | WE_MAX_STR_LEN,
10725 "getOemDataCap"},
10726#endif /* FEATURE_OEM_DATA_SUPPORT */
10727 {WE_GET_SNR,
10728 0,
10729 IW_PRIV_TYPE_CHAR | WE_MAX_STR_LEN,
10730 "getSNR"},
10731
10732 /* handlers for main ioctl */
10733 {WLAN_PRIV_SET_NONE_GET_NONE,
10734 0,
10735 0,
10736 ""},
10737
Rajeev Kumar8e3e2832015-11-06 16:02:54 -080010738 /* handlers for sub-ioctl */
10739 {
10740 WE_IBSS_GET_PEER_INFO_ALL,
10741 0,
10742 0,
10743 "ibssPeerInfoAll"
10744 },
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080010745 {WE_GET_RECOVERY_STAT,
10746 0,
10747 0,
10748 "getRecoverStat"},
Govind Singha471e5e2015-10-12 17:11:14 +053010749
10750 {WE_GET_FW_PROFILE_DATA,
10751 0,
10752 0,
10753 "getProfileData"},
10754
10755 {WE_SET_REASSOC_TRIGGER,
10756 0,
10757 0,
10758 "reassoc"},
10759
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080010760 {WE_DUMP_AGC_START,
10761 0,
10762 0,
10763 "dump_agc_start"},
10764
10765 {WE_DUMP_AGC,
10766 0,
10767 0,
10768 "dump_agc"},
10769
10770 {WE_DUMP_CHANINFO_START,
10771 0,
10772 0,
10773 "dump_chninfo_en"},
10774
10775 {WE_DUMP_CHANINFO,
10776 0,
10777 0,
10778 "dump_chninfo"},
10779
10780 {WE_DUMP_WATCHDOG,
10781 0,
10782 0,
10783 "dump_watchdog"},
10784#ifdef CONFIG_ATH_PCIE_ACCESS_DEBUG
10785 {WE_DUMP_PCIE_LOG,
10786 0,
10787 0,
10788 "dump_pcie_log"},
10789#endif
Sandeep Puligilla93a29ec2016-02-12 16:10:56 -080010790 {WE_STOP_OBSS_SCAN,
10791 0,
10792 0,
10793 "stop_obss_scan"},
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080010794 /* handlers for main ioctl */
10795 {WLAN_PRIV_SET_VAR_INT_GET_NONE,
10796 IW_PRIV_TYPE_INT | MAX_VAR_ARGS,
10797 0,
10798 ""},
10799
10800 /* handlers for sub-ioctl */
Rajeev Kumar8e3e2832015-11-06 16:02:54 -080010801 {WE_IBSS_GET_PEER_INFO,
10802 IW_PRIV_TYPE_INT | MAX_VAR_ARGS,
10803 0,
10804 "ibssPeerInfo"},
10805
10806 /* handlers for sub-ioctl */
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080010807 {WE_MTRACE_SELECTIVE_MODULE_LOG_ENABLE_CMD,
10808 IW_PRIV_TYPE_INT | MAX_VAR_ARGS,
10809 0,
10810 "setdumplog"},
10811
10812 {WE_MTRACE_DUMP_CMD,
10813 IW_PRIV_TYPE_INT | MAX_VAR_ARGS,
10814 0,
10815 "dumplog"},
10816#ifdef MPC_UT_FRAMEWORK
10817 {WE_POLICY_MANAGER_CLIST_CMD,
10818 IW_PRIV_TYPE_INT | MAX_VAR_ARGS,
10819 0,
10820 "pm_clist"},
10821
10822 {WE_POLICY_MANAGER_DLIST_CMD,
10823 IW_PRIV_TYPE_INT | MAX_VAR_ARGS,
10824 0,
10825 "pm_dlist"},
10826
10827 {WE_POLICY_MANAGER_DBS_CMD,
10828 IW_PRIV_TYPE_INT | MAX_VAR_ARGS,
10829 0,
10830 "pm_dbs"},
10831
10832 {WE_POLICY_MANAGER_PCL_CMD,
10833 IW_PRIV_TYPE_INT | MAX_VAR_ARGS,
10834 0,
10835 "pm_pcl"},
10836
10837 {WE_POLICY_MANAGER_CINFO_CMD,
10838 IW_PRIV_TYPE_INT | MAX_VAR_ARGS,
10839 0,
10840 "pm_cinfo"},
10841
10842 {WE_POLICY_MANAGER_ULIST_CMD,
10843 IW_PRIV_TYPE_INT | MAX_VAR_ARGS,
10844 0,
10845 "pm_ulist"},
10846
10847 {WE_POLICY_MANAGER_QUERY_ACTION_CMD,
10848 IW_PRIV_TYPE_INT | MAX_VAR_ARGS,
10849 0,
10850 "pm_query_action"},
10851
10852 {WE_POLICY_MANAGER_QUERY_ALLOW_CMD,
10853 IW_PRIV_TYPE_INT | MAX_VAR_ARGS,
10854 0,
10855 "pm_query_allow"},
10856
10857 {WE_POLICY_MANAGER_SCENARIO_CMD,
10858 IW_PRIV_TYPE_INT | MAX_VAR_ARGS,
10859 0,
10860 "pm_run_scenario"},
10861
10862 {WE_POLICY_SET_HW_MODE_CMD,
10863 IW_PRIV_TYPE_INT | MAX_VAR_ARGS,
10864 0,
10865 "pm_set_hw_mode"},
10866#endif
10867#ifdef FEATURE_WLAN_TDLS
10868 /* handlers for sub ioctl */
10869 {
10870 WE_TDLS_CONFIG_PARAMS,
10871 IW_PRIV_TYPE_INT | MAX_VAR_ARGS,
10872 0,
10873 "setTdlsConfig"
10874 },
10875#endif
10876 {
10877 WE_UNIT_TEST_CMD,
10878 IW_PRIV_TYPE_INT | MAX_VAR_ARGS,
10879 0,
10880 "setUnitTestCmd"
10881 },
10882
10883#ifdef WLAN_FEATURE_GPIO_LED_FLASHING
10884 {WE_LED_FLASHING_PARAM,
10885 IW_PRIV_TYPE_INT | MAX_VAR_ARGS,
10886 0,
10887 "gpio_control"},
10888#endif
10889 /* handlers for main ioctl */
10890 {WLAN_PRIV_ADD_TSPEC,
10891 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | HDD_WLAN_WMM_PARAM_COUNT,
10892 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10893 "addTspec"},
10894
10895 /* handlers for main ioctl */
10896 {WLAN_PRIV_DEL_TSPEC,
10897 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10898 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10899 "delTspec"},
10900
10901 /* handlers for main ioctl */
10902 {WLAN_PRIV_GET_TSPEC,
10903 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10904 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10905 "getTspec"},
10906
10907 /* handlers for main ioctl - host offload */
10908 {
10909 WLAN_PRIV_SET_HOST_OFFLOAD,
10910 IW_PRIV_TYPE_BYTE | sizeof(tHostOffloadRequest),
10911 0,
10912 "setHostOffload"
10913 }
10914 ,
10915
10916 {
10917 WLAN_GET_WLAN_STATISTICS,
10918 0,
10919 IW_PRIV_TYPE_BYTE | WE_MAX_STR_LEN,
10920 "getWlanStats"
10921 }
10922 ,
10923
10924 {
10925 WLAN_SET_KEEPALIVE_PARAMS,
Rajeev Kumar3ddf1c62015-11-03 14:10:13 -080010926 sizeof(tSirKeepAliveReq) | IW_PRIV_SIZE_FIXED,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080010927 0,
10928 "setKeepAlive"
10929 }
10930 ,
10931#ifdef WLAN_FEATURE_PACKET_FILTERING
10932 {
10933 WLAN_SET_PACKET_FILTER_PARAMS,
10934 IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED |
10935 sizeof(struct pkt_filter_cfg),
10936 0,
10937 "setPktFilter"
10938 }
10939 ,
10940#endif
10941#ifdef FEATURE_WLAN_SCAN_PNO
10942 {
10943 WLAN_SET_PNO,
10944 IW_PRIV_TYPE_CHAR | WE_MAX_STR_LEN,
10945 0,
10946 "setpno"
10947 }
10948 ,
10949#endif
10950 {
10951 WLAN_SET_BAND_CONFIG,
10952 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10953 0,
10954 "SETBAND"
10955 }
10956 ,
10957 {
10958 WLAN_GET_LINK_SPEED,
10959 IW_PRIV_TYPE_CHAR | 18,
10960 IW_PRIV_TYPE_CHAR | 5, "getLinkSpeed"
10961 }
10962 ,
10963
10964 /* handlers for main ioctl */
10965 {WLAN_PRIV_SET_TWO_INT_GET_NONE,
10966 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2,
10967 0,
10968 ""}
10969 ,
10970 {WE_SET_SMPS_PARAM,
10971 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2,
10972 0, "set_smps_param"}
10973 ,
10974 {WLAN_SET_DOT11P_CHANNEL_SCHED,
10975 IW_PRIV_TYPE_BYTE | sizeof(struct dot11p_channel_sched),
10976 0, "set_dot11p" }
10977 ,
10978#ifdef DEBUG
10979 {WE_SET_FW_CRASH_INJECT,
10980 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2,
10981 0, "crash_inject"}
10982 ,
10983#endif
Govind Singha471e5e2015-10-12 17:11:14 +053010984 {WE_ENABLE_FW_PROFILE,
10985 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2,
10986 0, "enableProfile"}
10987 ,
10988 {WE_SET_FW_PROFILE_HIST_INTVL,
10989 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2,
10990 0, "set_hist_intvl"}
10991 ,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080010992 {WE_SET_DUAL_MAC_FW_MODE_CONFIG,
10993 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2,
10994 0, "set_fw_mode_cfg"}
10995 ,
10996 {WE_DUMP_DP_TRACE_LEVEL,
10997 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2,
10998 0, "dump_dp_trace"}
10999 ,
11000};
11001
11002const struct iw_handler_def we_handler_def = {
Anurag Chouhan6d760662016-02-20 16:05:43 +053011003 .num_standard = QDF_ARRAY_SIZE(we_handler),
11004 .num_private = QDF_ARRAY_SIZE(we_private),
11005 .num_private_args = QDF_ARRAY_SIZE(we_private_args),
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011006
11007 .standard = (iw_handler *) we_handler,
11008 .private = (iw_handler *) we_private,
11009 .private_args = we_private_args,
11010 .get_wireless_stats = NULL,
11011};
11012
11013int hdd_set_wext(hdd_adapter_t *pAdapter)
11014{
11015 hdd_wext_state_t *pwextBuf;
11016 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
11017
11018 pwextBuf = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
11019
11020 /* Now configure the roaming profile links. To SSID and bssid. */
11021 pwextBuf->roamProfile.SSIDs.numOfSSIDs = 0;
11022 pwextBuf->roamProfile.SSIDs.SSIDList = &pHddStaCtx->conn_info.SSID;
11023
11024 pwextBuf->roamProfile.BSSIDs.numOfBSSIDs = 0;
11025 pwextBuf->roamProfile.BSSIDs.bssid = &pHddStaCtx->conn_info.bssId;
11026
11027 /*Set the numOfChannels to zero to scan all the channels */
11028 pwextBuf->roamProfile.ChannelInfo.numOfChannels = 0;
11029 pwextBuf->roamProfile.ChannelInfo.ChannelList = NULL;
11030
11031 /* Default is no encryption */
11032 pwextBuf->roamProfile.EncryptionType.numEntries = 1;
11033 pwextBuf->roamProfile.EncryptionType.encryptionType[0] =
11034 eCSR_ENCRYPT_TYPE_NONE;
11035
11036 pwextBuf->roamProfile.mcEncryptionType.numEntries = 1;
11037 pwextBuf->roamProfile.mcEncryptionType.encryptionType[0] =
11038 eCSR_ENCRYPT_TYPE_NONE;
11039
11040 pwextBuf->roamProfile.BSSType = eCSR_BSS_TYPE_INFRASTRUCTURE;
11041
11042 /* Default is no authentication */
11043 pwextBuf->roamProfile.AuthType.numEntries = 1;
11044 pwextBuf->roamProfile.AuthType.authType[0] = eCSR_AUTH_TYPE_OPEN_SYSTEM;
11045
11046 pwextBuf->roamProfile.phyMode = eCSR_DOT11_MODE_AUTO;
11047 pwextBuf->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
11048
11049 /*Set the default scan mode */
11050 pAdapter->scan_info.scan_mode = eSIR_ACTIVE_SCAN;
11051
11052 hdd_clear_roam_profile_ie(pAdapter);
11053
Anurag Chouhanfb54ab02016-02-18 18:00:46 +053011054 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011055
11056}
11057
11058int hdd_register_wext(struct net_device *dev)
11059{
11060 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
11061 hdd_wext_state_t *pwextBuf = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Anurag Chouhance0dc992016-02-16 18:18:03 +053011062 QDF_STATUS status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011063
11064 ENTER();
11065
11066 /* Zero the memory. This zeros the profile structure. */
11067 memset(pwextBuf, 0, sizeof(hdd_wext_state_t));
11068
11069 init_completion(&(WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter))->
11070 completion_var);
11071
11072 status = hdd_set_wext(pAdapter);
11073
Anurag Chouhance0dc992016-02-16 18:18:03 +053011074 if (!QDF_IS_STATUS_SUCCESS(status)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011075
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +053011076 QDF_TRACE(QDF_MODULE_ID_HDD, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011077 ("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))) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +053011082 QDF_TRACE(QDF_MODULE_ID_HDD, QDF_TRACE_LEVEL_ERROR,
Anurag Chouhanf04e84f2016-03-03 10:12:12 +053011083 ("ERROR: HDD qdf event init failed!!"));
Anurag Chouhanfb54ab02016-02-18 18:00:46 +053011084 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011085 }
11086
Anurag Chouhance0dc992016-02-16 18:18:03 +053011087 if (!QDF_IS_STATUS_SUCCESS(qdf_event_create(&pwextBuf->scanevent))) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +053011088 QDF_TRACE(QDF_MODULE_ID_HDD, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011089 ("ERROR: HDD scan event init failed!!"));
Anurag Chouhanfb54ab02016-02-18 18:00:46 +053011090 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011091 }
11092 /* Register as a wireless device */
11093 dev->wireless_handlers = (struct iw_handler_def *)&we_handler_def;
11094
11095 EXIT();
11096 return 0;
11097}
11098
11099int hdd_unregister_wext(struct net_device *dev)
11100{
11101 hddLog(LOG1, FL("dev(%p)"), dev);
11102
11103 if (dev != NULL) {
11104 rtnl_lock();
11105 dev->wireless_handlers = NULL;
11106 rtnl_unlock();
11107 }
11108
11109 return 0;
11110}