blob: ecb1fcfaf5e6c0091641453f3102dc8453d6bdf3 [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>
43#include "sir_params.h"
44#include "csr_api.h"
45#include "csr_inside_api.h"
46#if defined WLAN_FEATURE_VOWIFI
47#include "sme_rrm_internal.h"
48#endif
49#include <ani_global.h>
50#include "dot11f.h"
51#include <wlan_hdd_wowl.h>
52#include <wlan_hdd_cfg.h>
53#include <wlan_hdd_wmm.h>
54#include "utils_api.h"
55#include "wlan_hdd_p2p.h"
56#ifdef FEATURE_WLAN_TDLS
57#include "wlan_hdd_tdls.h"
58#endif
59
60#include "cds_ieee80211_common.h"
61#include "ol_if_athvar.h"
62#include "dbglog_host.h"
63#include "wma.h"
64
65#include "wlan_hdd_power.h"
66#include "qwlan_version.h"
67#include "wlan_hdd_host_offload.h"
68
69#include <linux/wireless.h>
70#include <net/cfg80211.h>
71
72#include "wlan_hdd_misc.h"
73
74#include "qc_sap_ioctl.h"
75#include "sme_api.h"
76#include "wma_types.h"
77#include "cdf_trace.h"
78#include "wlan_hdd_assoc.h"
79#include "wlan_hdd_ioctl.h"
80#include "wlan_hdd_scan.h"
81#include "sme_power_save_api.h"
82#include "cds_concurrency.h"
83#include "wlan_hdd_conc_ut.h"
84#include "wlan_hdd_ocb.h"
85#include "wlan_hdd_napi.h"
86
87#ifdef QCA_PKT_PROTO_TRACE
88#include "cds_packet.h"
89#endif /* QCA_PKT_PROTO_TRACE */
90
91#define HDD_FINISH_ULA_TIME_OUT 800
92#define HDD_SET_MCBC_FILTERS_TO_FW 1
93#define HDD_DELETE_MCBC_FILTERS_FROM_FW 0
94
95extern int wlan_hdd_cfg80211_update_band(struct wiphy *wiphy, eCsrBand eBand);
96static 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
277
278/* Private ioctls and their sub-ioctls */
279#define WLAN_PRIV_SET_INT_GET_INT (SIOCIWFIRSTPRIV + 2)
280
281/* Private ioctls and their sub-ioctls */
282#define WLAN_PRIV_SET_CHAR_GET_NONE (SIOCIWFIRSTPRIV + 3)
283#define WE_WOWL_ADD_PTRN 1
284#define WE_WOWL_DEL_PTRN 2
285#if defined WLAN_FEATURE_VOWIFI
286#define WE_NEIGHBOR_REPORT_REQUEST 3
287#endif
288#define WE_SET_AP_WPS_IE 4 /* This is called in station mode to set probe rsp ie. */
289#define WE_SET_CONFIG 5
290
291/* Private ioctls and their sub-ioctls */
292#define WLAN_PRIV_SET_THREE_INT_GET_NONE (SIOCIWFIRSTPRIV + 4)
293#define WE_SET_WLAN_DBG 1
294#define WE_SET_DP_TRACE 2
295#define WE_SET_SAP_CHANNELS 3
296
297/* Private ioctls and their sub-ioctls */
298#define WLAN_PRIV_GET_CHAR_SET_NONE (SIOCIWFIRSTPRIV + 5)
299#define WE_WLAN_VERSION 1
300#define WE_GET_STATS 2
301#define WE_GET_CFG 3
302#define WE_GET_WMM_STATUS 4
303#define WE_GET_CHANNEL_LIST 5
304#ifdef WLAN_FEATURE_11AC
305#define WE_GET_RSSI 6
306#endif
307#ifdef FEATURE_WLAN_TDLS
308#define WE_GET_TDLS_PEERS 8
309#endif
310#ifdef WLAN_FEATURE_11W
311#define WE_GET_11W_INFO 9
312#endif
313#define WE_GET_STATES 10
314
315#define WE_GET_PHYMODE 12
316#ifdef FEATURE_OEM_DATA_SUPPORT
317#define WE_GET_OEM_DATA_CAP 13
318#endif
319#define WE_GET_SNR 14
Govind Singha471e5e2015-10-12 17:11:14 +0530320#define WE_LIST_FW_PROFILE 15
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800321
322/* Private ioctls and their sub-ioctls */
323#define WLAN_PRIV_SET_NONE_GET_NONE (SIOCIWFIRSTPRIV + 6)
324#define WE_SET_REASSOC_TRIGGER 8
325
326#define WE_DUMP_AGC_START 11
327#define WE_DUMP_AGC 12
328#define WE_DUMP_CHANINFO_START 13
329#define WE_DUMP_CHANINFO 14
330#define WE_DUMP_WATCHDOG 15
331#ifdef CONFIG_ATH_PCIE_ACCESS_DEBUG
332#define WE_DUMP_PCIE_LOG 16
333#endif
334#define WE_GET_RECOVERY_STAT 17
Govind Singha471e5e2015-10-12 17:11:14 +0530335#define WE_GET_FW_PROFILE_DATA 18
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800336
337/* Private ioctls and their sub-ioctls */
338#define WLAN_PRIV_SET_VAR_INT_GET_NONE (SIOCIWFIRSTPRIV + 7)
339
340#define WE_P2P_NOA_CMD 2
341
342/* subcommands 3 and 4 are unused */
343
344#ifdef FEATURE_WLAN_TDLS
345#define WE_TDLS_CONFIG_PARAMS 5
346#endif
347
348#define WE_UNIT_TEST_CMD 7
349
350#define WE_MTRACE_DUMP_CMD 8
351#define WE_MTRACE_SELECTIVE_MODULE_LOG_ENABLE_CMD 9
352
353
354#ifdef WLAN_FEATURE_GPIO_LED_FLASHING
355#define WE_LED_FLASHING_PARAM 10
356#endif
357
358#define WE_POLICY_MANAGER_CLIST_CMD 11
359#define WE_POLICY_MANAGER_DLIST_CMD 12
360#define WE_POLICY_MANAGER_DBS_CMD 13
361#define WE_POLICY_MANAGER_PCL_CMD 14
362#define WE_POLICY_MANAGER_CINFO_CMD 15
363#define WE_POLICY_MANAGER_ULIST_CMD 16
364#define WE_POLICY_MANAGER_QUERY_ACTION_CMD 17
365#define WE_POLICY_MANAGER_QUERY_ALLOW_CMD 18
366#define WE_POLICY_MANAGER_SCENARIO_CMD 19
367#define WE_POLICY_SET_HW_MODE_CMD 20
368
369#define WE_SET_DUAL_MAC_SCAN_CONFIG 21
370#define WE_SET_DUAL_MAC_FW_MODE_CONFIG 22
371
372#ifdef FEATURE_WLAN_TDLS
373#undef MAX_VAR_ARGS
374#define MAX_VAR_ARGS 11
375#else
376#undef MAX_VAR_ARGS
377#define MAX_VAR_ARGS 9
378#endif
379
380/* Private ioctls (with no sub-ioctls) */
381/* note that they must be odd so that they have "get" semantics */
382#define WLAN_PRIV_ADD_TSPEC (SIOCIWFIRSTPRIV + 9)
383#define WLAN_PRIV_DEL_TSPEC (SIOCIWFIRSTPRIV + 11)
384#define WLAN_PRIV_GET_TSPEC (SIOCIWFIRSTPRIV + 13)
385
386/* (SIOCIWFIRSTPRIV + 8) is currently unused */
387/* (SIOCIWFIRSTPRIV + 10) is currently unused */
388/* (SIOCIWFIRSTPRIV + 12) is currently unused */
389/* (SIOCIWFIRSTPRIV + 14) is currently unused */
390/* (SIOCIWFIRSTPRIV + 15) is currently unused */
391/* (SIOCIWFIRSTPRIV + 16) is currently unused */
392/* (SIOCIWFIRSTPRIV + 17) is currently unused */
393/* (SIOCIWFIRSTPRIV + 19) is currently unused */
394
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800395#define WLAN_PRIV_SET_FTIES (SIOCIWFIRSTPRIV + 20)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800396
397/* Private ioctl for setting the host offload feature */
398#define WLAN_PRIV_SET_HOST_OFFLOAD (SIOCIWFIRSTPRIV + 18)
399
400/* Private ioctl to get the statistics */
401#define WLAN_GET_WLAN_STATISTICS (SIOCIWFIRSTPRIV + 21)
402
403/* Private ioctl to set the Keep Alive Params */
404#define WLAN_SET_KEEPALIVE_PARAMS (SIOCIWFIRSTPRIV + 22)
405
406#ifdef WLAN_FEATURE_PACKET_FILTERING
407/* Private ioctl to set the packet filtering params */
408#define WLAN_SET_PACKET_FILTER_PARAMS (SIOCIWFIRSTPRIV + 23)
409#endif
410
411
412#ifdef FEATURE_WLAN_SCAN_PNO
413/* Private ioctl to get the statistics */
414#define WLAN_SET_PNO (SIOCIWFIRSTPRIV + 24)
415#endif
416
417#define WLAN_SET_BAND_CONFIG (SIOCIWFIRSTPRIV + 25)
418
419/* (SIOCIWFIRSTPRIV + 26) is currently unused */
420/* (SIOCIWFIRSTPRIV + 27) is currently unused */
421
422/* Private ioctls and their sub-ioctls */
423#define WLAN_PRIV_SET_TWO_INT_GET_NONE (SIOCIWFIRSTPRIV + 28)
424#define WE_SET_SMPS_PARAM 1
425#ifdef DEBUG
426#define WE_SET_FW_CRASH_INJECT 2
427#endif
428#define WE_DUMP_DP_TRACE_LEVEL 3
429#define DUMP_DP_TRACE 0
Govind Singha471e5e2015-10-12 17:11:14 +0530430/* Private sub ioctl for enabling and setting histogram interval of profiling */
431#define WE_ENABLE_FW_PROFILE 4
432#define WE_SET_FW_PROFILE_HIST_INTVL 5
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800433
434/* (SIOCIWFIRSTPRIV + 29) is currently unused */
435
436/* 802.11p IOCTL */
437#define WLAN_SET_DOT11P_CHANNEL_SCHED (SIOCIWFIRSTPRIV + 30)
438
439#define WLAN_GET_LINK_SPEED (SIOCIWFIRSTPRIV + 31)
440
441#define WLAN_STATS_INVALID 0
442#define WLAN_STATS_RETRY_CNT 1
443#define WLAN_STATS_MUL_RETRY_CNT 2
444#define WLAN_STATS_TX_FRM_CNT 3
445#define WLAN_STATS_RX_FRM_CNT 4
446#define WLAN_STATS_FRM_DUP_CNT 5
447#define WLAN_STATS_FAIL_CNT 6
448#define WLAN_STATS_RTS_FAIL_CNT 7
449#define WLAN_STATS_ACK_FAIL_CNT 8
450#define WLAN_STATS_RTS_SUC_CNT 9
451#define WLAN_STATS_RX_DISCARD_CNT 10
452#define WLAN_STATS_RX_ERROR_CNT 11
453#define WLAN_STATS_TX_BYTE_CNT 12
454
455#define WLAN_STATS_RX_BYTE_CNT 13
456#define WLAN_STATS_RX_RATE 14
457#define WLAN_STATS_TX_RATE 15
458
459#define WLAN_STATS_RX_UC_BYTE_CNT 16
460#define WLAN_STATS_RX_MC_BYTE_CNT 17
461#define WLAN_STATS_RX_BC_BYTE_CNT 18
462#define WLAN_STATS_TX_UC_BYTE_CNT 19
463#define WLAN_STATS_TX_MC_BYTE_CNT 20
464#define WLAN_STATS_TX_BC_BYTE_CNT 21
465
466#define FILL_TLV(__p, __type, __size, __val, __tlen) do { \
467 if ((__tlen + __size + 2) < WE_MAX_STR_LEN) { \
468 *__p++ = __type; \
469 *__p++ = __size; \
470 memcpy(__p, __val, __size); \
471 __p += __size; \
472 __tlen += __size + 2; \
473 } else { \
474 hddLog(CDF_TRACE_LEVEL_ERROR, "FILL_TLV Failed!!!"); \
475 } \
476 } while (0)
477
478#define VERSION_VALUE_MAX_LEN 32
479
480#define TX_PER_TRACKING_DEFAULT_RATIO 5
481#define TX_PER_TRACKING_MAX_RATIO 10
482#define TX_PER_TRACKING_DEFAULT_WATERMARK 5
483
484#define WLAN_ADAPTER 0
485#define P2P_ADAPTER 1
486
487/**
488 * mem_alloc_copy_from_user_helper - copy from user helper
489 * @wrqu_data: wireless extensions request data
490 * @len: length of @wrqu_data
491 *
492 * Helper function to allocate buffer and copy user data.
493 *
494 * Return: On success return a pointer to a kernel buffer containing a
495 * copy of the userspace data (with an additional NUL character
496 * appended for safety). On failure return %NULL.
497 */
498void *mem_alloc_copy_from_user_helper(const __user void *wrqu_data, size_t len)
499{
500 u8 *ptr = NULL;
501
502 /* in order to protect the code, an extra byte is post
503 * appended to the buffer and the null termination is added.
504 * However, when allocating (len+1) byte of memory, we need to
505 * make sure that there is no uint overflow when doing
506 * addition. In theory check len < UINT_MAX protects the uint
507 * overflow. For wlan private ioctl, the buffer size is much
508 * less than UINT_MAX, as a good guess, now, it is assumed
509 * that the private command buffer size is no greater than 4K
510 * (4096 bytes). So we use 4096 as the upper boundary for now.
511 */
512 if (len > MAX_USER_COMMAND_SIZE) {
513 CDF_TRACE(CDF_MODULE_ID_HDD, CDF_TRACE_LEVEL_ERROR,
514 "Invalid length");
515 return NULL;
516 }
517
518 ptr = kmalloc(len + 1, GFP_KERNEL);
519 if (NULL == ptr) {
520 CDF_TRACE(CDF_MODULE_ID_HDD, CDF_TRACE_LEVEL_ERROR,
521 "unable to allocate memory");
522 return NULL;
523 }
524
525 if (copy_from_user(ptr, wrqu_data, len)) {
526 CDF_TRACE(CDF_MODULE_ID_HDD, CDF_TRACE_LEVEL_ERROR,
527 "%s: failed to copy data to user buffer", __func__);
528 kfree(ptr);
529 return NULL;
530 }
531 ptr[len] = '\0';
532 return ptr;
533}
534
535/**
536 * hdd_priv_get_data() - Get pointer to ioctl private data
537 * @p_priv_data: pointer to iw_point struct to be filled
538 * @wrqu: Pointer to IOCTL Data received from userspace
539 *
540 * Helper function to get compatible struct iw_point passed to ioctl
541 *
542 * Return - 0 if p_priv_data successfully filled, error otherwise
543 */
544int hdd_priv_get_data(struct iw_point *p_priv_data, union iwreq_data *wrqu)
545{
546 if ((NULL == p_priv_data) || (NULL == wrqu)) {
547 return -EINVAL;
548 }
549#ifdef CONFIG_COMPAT
550 if (is_compat_task()) {
551 struct compat_iw_point *p_compat_priv_data;
552
553 /* Compat task:
554 * typecast to compat structure and copy the members.
555 */
556 p_compat_priv_data = (struct compat_iw_point *)&wrqu->data;
557
558 p_priv_data->pointer = compat_ptr(p_compat_priv_data->pointer);
559 p_priv_data->length = p_compat_priv_data->length;
560 p_priv_data->flags = p_compat_priv_data->flags;
561 } else {
562#endif /* #ifdef CONFIG_COMPAT */
563
564 /* Non compat task: directly copy the structure. */
565 memcpy(p_priv_data, &wrqu->data, sizeof(struct iw_point));
566
567#ifdef CONFIG_COMPAT
568 }
569#endif /* #ifdef CONFIG_COMPAT */
570
571 return 0;
572}
573
574
575/**
576 * hdd_wlan_get_stats() - Get txrx stats in SAP mode
577 * @pAdapter: Pointer to the hdd adapter.
578 * @length: Size of the data copied
579 * @buffer: Pointer to char buffer.
580 * @buf_len: Length of the char buffer.
581 *
582 * This function called when the "iwpriv wlan0 get_stats" command is given.
583 * It used to collect the txrx stats when the device is configured in SAP mode.
584 *
585 * Return - none
586 */
587void hdd_wlan_get_stats(hdd_adapter_t *pAdapter, uint16_t *length,
588 char *buffer, uint16_t buf_len)
589{
590 hdd_tx_rx_stats_t *pStats = &pAdapter->hdd_stats.hddTxRxStats;
591 uint32_t len = 0;
592 uint32_t total_rx_pkt = 0, total_rx_dropped = 0;
593 uint32_t total_rx_delv = 0, total_rx_refused = 0;
594 int i = 0;
595
596 for (; i < NUM_CPUS; i++) {
597 total_rx_pkt += pStats->rxPackets[i];
598 total_rx_dropped += pStats->rxDropped[i];
599 total_rx_delv += pStats->rxDelivered[i];
600 total_rx_refused += pStats->rxRefused[i];
601 }
602
603 len = scnprintf(buffer, buf_len,
604 "\nTransmit"
605 "\ncalled %u, dropped %u,"
606 "\n dropped BK %u, BE %u, VI %u, VO %u"
607 "\n classified BK %u, BE %u, VI %u, VO %u"
608 "\ncompleted %u,"
609 "\n\nReceive Total"
610 "\n packets %u, dropped %u, delivered %u, refused %u"
611 "\n",
612 pStats->txXmitCalled,
613 pStats->txXmitDropped,
614
615 pStats->txXmitDroppedAC[SME_AC_BK],
616 pStats->txXmitDroppedAC[SME_AC_BE],
617 pStats->txXmitDroppedAC[SME_AC_VI],
618 pStats->txXmitDroppedAC[SME_AC_VO],
619
620 pStats->txXmitClassifiedAC[SME_AC_BK],
621 pStats->txXmitClassifiedAC[SME_AC_BE],
622 pStats->txXmitClassifiedAC[SME_AC_VI],
623 pStats->txXmitClassifiedAC[SME_AC_VO],
624
625 pStats->txCompleted,
626 total_rx_pkt, total_rx_dropped, total_rx_delv, total_rx_refused
627 );
628
629 for (i = 0; i < NUM_CPUS; i++) {
630 len += scnprintf(buffer + len, buf_len - len,
631 "\nReceive CPU: %d"
632 "\n packets %u, dropped %u, delivered %u, refused %u",
633 i, pStats->rxPackets[i], pStats->rxDropped[i],
634 pStats->rxDelivered[i], pStats->rxRefused[i]);
635 }
636
637 len += scnprintf(buffer + len, buf_len - len,
638 "\n\nTX_FLOW"
639 "\nCurrent status: %s"
640 "\ntx-flow timer start count %u"
641 "\npause count %u, unpause count %u",
642 (pStats->is_txflow_paused == true ? "PAUSED" : "UNPAUSED"),
643 pStats->txflow_timer_cnt,
644 pStats->txflow_pause_cnt,
645 pStats->txflow_unpause_cnt);
646
647 len += ol_txrx_stats(pAdapter->sessionId,
648 &buffer[len], (buf_len - len));
649
650 len += hdd_napi_stats(buffer + len, buf_len - len,
651 NULL, hdd_napi_get_all());
652
653 *length = len + 1;
654}
655
656/**
Govind Singha471e5e2015-10-12 17:11:14 +0530657 * hdd_wlan_list_fw_profile() - Get fw profiling points
658 * @length: Size of the data copied
659 * @buffer: Pointer to char buffer.
660 * @buf_len: Length of the char buffer.
661 *
662 * This function called when the "iwpriv wlan0 listProfile" command is given.
663 * It is used to get the supported profiling points in FW.
664 *
665 * Return - none
666 */
667void hdd_wlan_list_fw_profile(uint16_t *length,
668 char *buffer, uint16_t buf_len)
669{
670 uint32_t len = 0;
671
672 len = scnprintf(buffer, buf_len,
673 "PROF_CPU_IDLE: %u\n"
674 "PROF_PPDU_PROC: %u\n"
675 "PROF_PPDU_POST: %u\n"
676 "PROF_HTT_TX_INPUT: %u\n"
677 "PROF_MSDU_ENQ: %u\n"
678 "PROF_PPDU_POST_HAL: %u\n"
679 "PROF_COMPUTE_TX_TIME: %u\n",
680 PROF_CPU_IDLE,
681 PROF_PPDU_PROC,
682 PROF_PPDU_POST,
683 PROF_HTT_TX_INPUT,
684 PROF_MSDU_ENQ,
685 PROF_PPDU_POST_HAL,
686 PROF_COMPUTE_TX_TIME);
687
688 *length = len + 1;
689}
690
691/**
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800692 * hdd_wlan_dump_stats() - display dump Stats
693 * @adapter: adapter handle
694 * @value: value from user
695 *
696 * Return: none
697 */
698void hdd_wlan_dump_stats(hdd_adapter_t *adapter, int value)
699{
700 hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
701
702 switch (value) {
703
704 case WLAN_TXRX_HIST_STATS:
705 wlan_hdd_display_tx_rx_histogram(hdd_ctx);
706 break;
707 case WLAN_HDD_NETIF_OPER_HISTORY:
708 wlan_hdd_display_netif_queue_history(hdd_ctx);
709 break;
710 default:
711 ol_txrx_display_stats(value);
712 break;
713 }
714}
715
716/**
717 * hdd_wlan_get_version() - Get driver version information
718 * @pAdapter: Pointer to the adapter.
719 * @wrqu: Pointer to IOCTL REQUEST Data.
720 * @extra: Pointer to destination buffer
721 *
722 * This function is used to get Wlan Driver, Firmware, & Hardware
723 * Version information. If @wrqu and @extra are specified, then the
724 * version string is returned. Otherwise it is simply printed to the
725 * kernel log.
726 *
727 * Return: none
728 */
729void hdd_wlan_get_version(hdd_adapter_t *pAdapter, union iwreq_data *wrqu,
730 char *extra)
731{
732 tSirVersionString wcnss_SW_version;
733 const char *pSWversion;
734 const char *pHWversion;
735 uint32_t MSPId = 0, mSPId = 0, SIId = 0, CRMId = 0;
736
737 hdd_context_t *pHddContext;
738
739 pHddContext = WLAN_HDD_GET_CTX(pAdapter);
740 if (!pHddContext) {
741 CDF_TRACE(CDF_MODULE_ID_HDD, CDF_TRACE_LEVEL_ERROR,
742 "%s:Invalid context, HDD context is null", __func__);
743 goto error;
744 }
745
746 snprintf(wcnss_SW_version, sizeof(tSirVersionString), "%08x",
747 pHddContext->target_fw_version);
748
749 pSWversion = wcnss_SW_version;
750 MSPId = (pHddContext->target_fw_version & 0xf0000000) >> 28;
751 mSPId = (pHddContext->target_fw_version & 0xf000000) >> 24;
752 SIId = (pHddContext->target_fw_version & 0xf00000) >> 20;
753 CRMId = pHddContext->target_fw_version & 0x7fff;
754
755 pHWversion = pHddContext->target_hw_name;
756
757 if (wrqu && extra) {
758 wrqu->data.length =
759 scnprintf(extra, WE_MAX_STR_LEN,
760 "Host SW:%s, FW:%d.%d.%d.%d, HW:%s",
761 QWLAN_VERSIONSTR,
762 MSPId, mSPId, SIId, CRMId, pHWversion);
763 } else {
764 pr_info("Host SW:%s, FW:%d.%d.%d.%d, HW:%s\n",
765 QWLAN_VERSIONSTR,
766 MSPId, mSPId, SIId, CRMId, pHWversion);
767 }
768error:
769 return;
770}
771
772/**
773 * hdd_wlan_get_rts_threshold() - Get RTS threshold
774 * @pAdapter: adapter upon which the request was received
775 * @wrqu: pointer to the ioctl request
776 *
777 * This function retrieves the current RTS threshold value and stores
778 * it in the ioctl request structure
779 *
780 * Return: 0 if valid data was returned, non-zero on error
781 */
782int hdd_wlan_get_rts_threshold(hdd_adapter_t *pAdapter, union iwreq_data *wrqu)
783{
784 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
785 uint32_t threshold = 0;
786 hdd_context_t *hdd_ctx;
787 int ret = 0;
788
789 ENTER();
790
791 if (NULL == pAdapter) {
792 CDF_TRACE(CDF_MODULE_ID_HDD, CDF_TRACE_LEVEL_ERROR,
793 "%s: Adapter is NULL", __func__);
794 return -EINVAL;
795 }
796
797 hdd_ctx = WLAN_HDD_GET_CTX(pAdapter);
798 ret = wlan_hdd_validate_context(hdd_ctx);
799 if (0 != ret)
800 return ret;
801
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530802 if (QDF_STATUS_SUCCESS !=
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800803 sme_cfg_get_int(hHal, WNI_CFG_RTS_THRESHOLD, &threshold)) {
804 CDF_TRACE(CDF_MODULE_ID_HDD, CDF_TRACE_LEVEL_WARN,
805 FL
806 ("failed to get ini parameter, WNI_CFG_RTS_THRESHOLD"));
807 return -EIO;
808 }
809 wrqu->rts.value = threshold;
810
811 CDF_TRACE(CDF_MODULE_ID_HDD, CDF_TRACE_LEVEL_INFO,
812 ("Rts-Threshold=%d!!"), wrqu->rts.value);
813
814 EXIT();
815
816 return 0;
817}
818
819/**
820 * hdd_wlan_get_frag_threshold() - Get fragmentation threshold
821 * @pAdapter: adapter upon which the request was received
822 * @wrqu: pointer to the ioctl request
823 *
824 * This function retrieves the current fragmentation threshold value
825 * and stores it in the ioctl request structure
826 *
827 * Return: 0 if valid data was returned, non-zero on error
828 */
829int hdd_wlan_get_frag_threshold(hdd_adapter_t *pAdapter,
830 union iwreq_data *wrqu)
831{
832 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
833 uint32_t threshold = 0, status = 0;
834 hdd_context_t *hdd_ctx;
835
836 ENTER();
837
838 if (NULL == pAdapter) {
839 CDF_TRACE(CDF_MODULE_ID_HDD, CDF_TRACE_LEVEL_ERROR,
840 "%s: Adapter is NULL", __func__);
841 return -EINVAL;
842 }
843
844 hdd_ctx = WLAN_HDD_GET_CTX(pAdapter);
845 status = wlan_hdd_validate_context(hdd_ctx);
846 if (0 != status)
847 return status;
848
849 if (sme_cfg_get_int(hHal, WNI_CFG_FRAGMENTATION_THRESHOLD, &threshold)
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530850 != QDF_STATUS_SUCCESS) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800851 CDF_TRACE(CDF_MODULE_ID_HDD, CDF_TRACE_LEVEL_WARN,
852 FL
853 ("failed to get ini parameter, WNI_CFG_FRAGMENTATION_THRESHOLD"));
854 return -EIO;
855 }
856 wrqu->frag.value = threshold;
857
858 CDF_TRACE(CDF_MODULE_ID_HDD, CDF_TRACE_LEVEL_INFO,
859 ("Frag-Threshold=%d!!"), wrqu->frag.value);
860
861 EXIT();
862
863 return 0;
864}
865
866/**
867 * hdd_wlan_get_freq() - Convert channel to frequency
868 * @channel: channel to be converted
869 * @pfreq: where to store the frequency
870 *
871 * Return: 1 on success, otherwise a negative errno
872 */
873int hdd_wlan_get_freq(uint32_t channel, uint32_t *pfreq)
874{
875 int i;
876 if (channel > 0) {
877 for (i = 0; i < FREQ_CHAN_MAP_TABLE_SIZE; i++) {
878 if (channel == freq_chan_map[i].chan) {
879 *pfreq = freq_chan_map[i].freq;
880 return 1;
881 }
882 }
883 }
884 CDF_TRACE(CDF_MODULE_ID_HDD, CDF_TRACE_LEVEL_INFO,
885 ("Invalid channel no=%d!!"), channel);
886 return -EINVAL;
887}
888
889/**
890 * hdd_is_auth_type_rsn() - RSN authentication type check
891 * @authType: authentication type to be checked
892 *
893 * Return: true if @authType is an RSN authentication type,
894 * false if it is not
895 */
896static bool hdd_is_auth_type_rsn(eCsrAuthType authType)
897{
898 bool rsnType = false;
899 /* is the authType supported? */
900 switch (authType) {
901 case eCSR_AUTH_TYPE_NONE: /* never used */
902 rsnType = false;
903 break;
904 /* MAC layer authentication types */
905 case eCSR_AUTH_TYPE_OPEN_SYSTEM:
906 rsnType = false;
907 break;
908 case eCSR_AUTH_TYPE_SHARED_KEY:
909 rsnType = false;
910 break;
911 case eCSR_AUTH_TYPE_AUTOSWITCH:
912 rsnType = false;
913 break;
914
915 /* Upper layer authentication types */
916 case eCSR_AUTH_TYPE_WPA:
917 rsnType = true;
918 break;
919 case eCSR_AUTH_TYPE_WPA_PSK:
920 rsnType = true;
921 break;
922 case eCSR_AUTH_TYPE_WPA_NONE:
923 rsnType = true;
924 break;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800925 case eCSR_AUTH_TYPE_FT_RSN:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800926 case eCSR_AUTH_TYPE_RSN:
927 rsnType = true;
928 break;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800929 case eCSR_AUTH_TYPE_FT_RSN_PSK:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800930 case eCSR_AUTH_TYPE_RSN_PSK:
931#ifdef WLAN_FEATURE_11W
932 case eCSR_AUTH_TYPE_RSN_PSK_SHA256:
933 case eCSR_AUTH_TYPE_RSN_8021X_SHA256:
934#endif
935 rsnType = true;
936 break;
937 /* case eCSR_AUTH_TYPE_FAILED: */
938 case eCSR_AUTH_TYPE_UNKNOWN:
939 rsnType = false;
940 break;
941 default:
942 hddLog(LOGE, FL("unknown authType %d, treat as open"),
943 authType);
944 rsnType = false;
945 break;
946 }
947 hddLog(LOG1, FL("called with authType: %d, returned: %d"),
948 authType, rsnType);
949 return rsnType;
950}
951
952/**
953 * hdd_get_rssi_cb() - "Get RSSI" callback function
954 * @rssi: Current RSSI of the station
955 * @staId: ID of the station
956 * @pContext: opaque context originally passed to SME. HDD always passes
957 * a &struct statsContext
958 *
959 * Return: None
960 */
961static void hdd_get_rssi_cb(int8_t rssi, uint32_t staId, void *pContext)
962{
963 struct statsContext *pStatsContext;
964 hdd_adapter_t *pAdapter;
965
966 if (ioctl_debug) {
967 pr_info("%s: rssi [%d] STA [%d] pContext [%p]\n",
968 __func__, (int)rssi, (int)staId, pContext);
969 }
970
971 if (NULL == pContext) {
972 hddLog(CDF_TRACE_LEVEL_ERROR,
973 "%s: Bad param, pContext [%p]", __func__, pContext);
974 return;
975 }
976
977 pStatsContext = pContext;
978 pAdapter = pStatsContext->pAdapter;
979
980 /* there is a race condition that exists between this callback
981 * function and the caller since the caller could time out
982 * either before or while this code is executing. we use a
983 * spinlock to serialize these actions
984 */
985 spin_lock(&hdd_context_lock);
986
987 if ((NULL == pAdapter) ||
988 (RSSI_CONTEXT_MAGIC != pStatsContext->magic)) {
989 /* the caller presumably timed out so there is nothing
990 * we can do
991 */
992 spin_unlock(&hdd_context_lock);
993 hddLog(CDF_TRACE_LEVEL_WARN,
994 "%s: Invalid context, pAdapter [%p] magic [%08x]",
995 __func__, pAdapter, pStatsContext->magic);
996 if (ioctl_debug) {
997 pr_info("%s: Invalid context, pAdapter [%p] magic [%08x]\n",
998 __func__, pAdapter, pStatsContext->magic);
999 }
1000 return;
1001 }
1002
1003 /* context is valid so caller is still waiting */
1004
1005 /* paranoia: invalidate the magic */
1006 pStatsContext->magic = 0;
1007
1008 /* copy over the rssi */
1009 pAdapter->rssi = rssi;
1010
Sachin Ahujabef8c102015-11-16 15:15:49 +05301011 if (pAdapter->rssi > 0)
1012 pAdapter->rssi = 0;
1013
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001014 /* notify the caller */
1015 complete(&pStatsContext->completion);
1016
1017 /* serialization is complete */
1018 spin_unlock(&hdd_context_lock);
1019}
1020
1021/**
1022 * hdd_get_snr_cb() - "Get SNR" callback function
1023 * @snr: Current SNR of the station
1024 * @staId: ID of the station
1025 * @pContext: opaque context originally passed to SME. HDD always passes
1026 * a &struct statsContext
1027 *
1028 * Return: None
1029 */
1030static void hdd_get_snr_cb(int8_t snr, uint32_t staId, void *pContext)
1031{
1032 struct statsContext *pStatsContext;
1033 hdd_adapter_t *pAdapter;
1034
1035 if (ioctl_debug) {
1036 pr_info("%s: snr [%d] STA [%d] pContext [%p]\n",
1037 __func__, (int)snr, (int)staId, pContext);
1038 }
1039
1040 if (NULL == pContext) {
1041 hddLog(CDF_TRACE_LEVEL_ERROR,
1042 "%s: Bad param, pContext [%p]", __func__, pContext);
1043 return;
1044 }
1045
1046 pStatsContext = pContext;
1047 pAdapter = pStatsContext->pAdapter;
1048
1049 /* there is a race condition that exists between this callback
1050 * function and the caller since the caller could time out
1051 * either before or while this code is executing. we use a
1052 * spinlock to serialize these actions
1053 */
1054 spin_lock(&hdd_context_lock);
1055
1056 if ((NULL == pAdapter) || (SNR_CONTEXT_MAGIC != pStatsContext->magic)) {
1057 /* the caller presumably timed out so there is nothing
1058 * we can do
1059 */
1060 spin_unlock(&hdd_context_lock);
1061 hddLog(CDF_TRACE_LEVEL_WARN,
1062 "%s: Invalid context, pAdapter [%p] magic [%08x]",
1063 __func__, pAdapter, pStatsContext->magic);
1064 if (ioctl_debug) {
1065 pr_info("%s: Invalid context, pAdapter [%p] magic [%08x]\n",
1066 __func__, pAdapter, pStatsContext->magic);
1067 }
1068 return;
1069 }
1070
1071 /* context is valid so caller is still waiting */
1072
1073 /* paranoia: invalidate the magic */
1074 pStatsContext->magic = 0;
1075
1076 /* copy over the snr */
1077 pAdapter->snr = snr;
1078
1079 /* notify the caller */
1080 complete(&pStatsContext->completion);
1081
1082 /* serialization is complete */
1083 spin_unlock(&hdd_context_lock);
1084}
1085
1086/**
1087 * wlan_hdd_get_rssi() - Get the current RSSI
1088 * @pAdapter: adapter upon which the measurement is requested
1089 * @rssi_value: pointer to where the RSSI should be returned
1090 *
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301091 * Return: QDF_STATUS_SUCCESS on success, CDF_STATUS_E_* on error
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001092 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301093QDF_STATUS wlan_hdd_get_rssi(hdd_adapter_t *pAdapter, int8_t *rssi_value)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001094{
1095 struct statsContext context;
1096 hdd_context_t *pHddCtx;
1097 hdd_station_ctx_t *pHddStaCtx;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301098 QDF_STATUS hstatus;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001099 unsigned long rc;
1100
1101 if (NULL == pAdapter) {
1102 hddLog(CDF_TRACE_LEVEL_WARN,
1103 "%s: Invalid context, pAdapter", __func__);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301104 return QDF_STATUS_E_FAULT;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001105 }
Prashanth Bhatta9e143052015-12-04 11:56:47 -08001106 if (cds_is_driver_recovering()) {
1107 hdd_err("Recovery in Progress. State: 0x%x Ignore!!!",
1108 cds_get_driver_state());
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001109 /* return a cached value */
1110 *rssi_value = pAdapter->rssi;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301111 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001112 }
1113
1114 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
1115 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
1116
1117 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState) {
1118 hdd_err("Not associated!, return last connected AP rssi!");
1119 *rssi_value = pAdapter->rssi;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301120 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001121 }
1122
1123 if (pHddStaCtx->hdd_ReassocScenario) {
1124 hdd_info("Roaming in progress, return cached RSSI");
1125 *rssi_value = pAdapter->rssi;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301126 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001127 }
1128
1129 init_completion(&context.completion);
1130 context.pAdapter = pAdapter;
1131 context.magic = RSSI_CONTEXT_MAGIC;
1132
1133 hstatus = sme_get_rssi(pHddCtx->hHal, hdd_get_rssi_cb,
1134 pHddStaCtx->conn_info.staId[0],
1135 pHddStaCtx->conn_info.bssId, pAdapter->rssi,
1136 &context, pHddCtx->pcds_context);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301137 if (QDF_STATUS_SUCCESS != hstatus) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001138 hddLog(CDF_TRACE_LEVEL_ERROR, "%s: Unable to retrieve RSSI",
1139 __func__);
1140 /* we'll returned a cached value below */
1141 } else {
1142 /* request was sent -- wait for the response */
1143 rc = wait_for_completion_timeout(&context.completion,
1144 msecs_to_jiffies
1145 (WLAN_WAIT_TIME_STATS));
1146 if (!rc) {
1147 hddLog(CDF_TRACE_LEVEL_ERROR,
1148 FL("SME timed out while retrieving RSSI"));
1149 /* we'll now returned a cached value below */
1150 }
1151 }
1152
1153 /* either we never sent a request, we sent a request and
1154 * received a response or we sent a request and timed out. if
1155 * we never sent a request or if we sent a request and got a
1156 * response, we want to clear the magic out of paranoia. if
1157 * we timed out there is a race condition such that the
1158 * callback function could be executing at the same time we
1159 * are. of primary concern is if the callback function had
1160 * already verified the "magic" but had not yet set the
1161 * completion variable when a timeout occurred. we serialize
1162 * these activities by invalidating the magic while holding a
1163 * shared spinlock which will cause us to block if the
1164 * callback is currently executing
1165 */
1166 spin_lock(&hdd_context_lock);
1167 context.magic = 0;
1168 spin_unlock(&hdd_context_lock);
1169
1170 *rssi_value = pAdapter->rssi;
1171
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301172 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001173}
1174
1175/**
1176 * wlan_hdd_get_snr() - Get the current SNR
1177 * @pAdapter: adapter upon which the measurement is requested
1178 * @snr: pointer to where the SNR should be returned
1179 *
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301180 * Return: QDF_STATUS_SUCCESS on success, CDF_STATUS_E_* on error
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001181 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301182QDF_STATUS wlan_hdd_get_snr(hdd_adapter_t *pAdapter, int8_t *snr)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001183{
1184 struct statsContext context;
1185 hdd_context_t *pHddCtx;
1186 hdd_station_ctx_t *pHddStaCtx;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301187 QDF_STATUS hstatus;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001188 unsigned long rc;
1189 int valid;
1190
Hanumantha Reddy Pothula2db50ed2015-11-23 10:48:33 +05301191 ENTER();
1192
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001193 if (NULL == pAdapter) {
1194 hddLog(CDF_TRACE_LEVEL_ERROR,
1195 "%s: Invalid context, pAdapter", __func__);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301196 return QDF_STATUS_E_FAULT;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001197 }
1198
1199 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
1200
1201 valid = wlan_hdd_validate_context(pHddCtx);
Hanumantha Reddy Pothula2db50ed2015-11-23 10:48:33 +05301202 if (0 != valid)
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301203 return QDF_STATUS_E_FAULT;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001204
1205 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
1206
1207 init_completion(&context.completion);
1208 context.pAdapter = pAdapter;
1209 context.magic = SNR_CONTEXT_MAGIC;
1210
1211 hstatus = sme_get_snr(pHddCtx->hHal, hdd_get_snr_cb,
1212 pHddStaCtx->conn_info.staId[0],
1213 pHddStaCtx->conn_info.bssId, &context);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301214 if (QDF_STATUS_SUCCESS != hstatus) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001215 hddLog(CDF_TRACE_LEVEL_ERROR, "%s: Unable to retrieve RSSI",
1216 __func__);
1217 /* we'll returned a cached value below */
1218 } else {
1219 /* request was sent -- wait for the response */
1220 rc = wait_for_completion_timeout(&context.completion,
1221 msecs_to_jiffies
1222 (WLAN_WAIT_TIME_STATS));
1223 if (!rc) {
1224 hddLog(CDF_TRACE_LEVEL_ERROR,
1225 FL("SME timed out while retrieving SNR"));
1226 /* we'll now returned a cached value below */
1227 }
1228 }
1229
1230 /* either we never sent a request, we sent a request and
1231 * received a response or we sent a request and timed out. if
1232 * we never sent a request or if we sent a request and got a
1233 * response, we want to clear the magic out of paranoia. if
1234 * we timed out there is a race condition such that the
1235 * callback function could be executing at the same time we
1236 * are. of primary concern is if the callback function had
1237 * already verified the "magic" but had not yet set the
1238 * completion variable when a timeout occurred. we serialize
1239 * these activities by invalidating the magic while holding a
1240 * shared spinlock which will cause us to block if the
1241 * callback is currently executing
1242 */
1243 spin_lock(&hdd_context_lock);
1244 context.magic = 0;
1245 spin_unlock(&hdd_context_lock);
1246
1247 *snr = pAdapter->snr;
Hanumantha Reddy Pothula2db50ed2015-11-23 10:48:33 +05301248 EXIT();
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301249 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001250}
1251
1252/**
1253 * hdd_get_link_speed_cb() - Get link speed callback function
1254 * @pLinkSpeed: pointer to the link speed record
1255 * @pContext: pointer to the user context passed to SME
1256 *
1257 * This function is passed as the callback function to
1258 * sme_get_link_speed() by wlan_hdd_get_linkspeed_for_peermac(). By
1259 * agreement a &struct linkspeedContext is passed as @pContext. If
1260 * the context is valid, then the contents of @pLinkSpeed are copied
1261 * into the adapter record referenced by @pContext where they can be
1262 * subsequently retrieved. If the context is invalid, then this
1263 * function does nothing since it is assumed the caller has already
1264 * timed-out and destroyed the context.
1265 *
1266 * Return: None.
1267 */
1268static void
1269hdd_get_link_speed_cb(tSirLinkSpeedInfo *pLinkSpeed, void *pContext)
1270{
1271 struct linkspeedContext *pLinkSpeedContext;
1272 hdd_adapter_t *pAdapter;
1273
1274 if ((NULL == pLinkSpeed) || (NULL == pContext)) {
1275 hddLog(CDF_TRACE_LEVEL_ERROR,
1276 "%s: Bad param, pLinkSpeed [%p] pContext [%p]",
1277 __func__, pLinkSpeed, pContext);
1278 return;
1279 }
1280 spin_lock(&hdd_context_lock);
1281 pLinkSpeedContext = pContext;
1282 pAdapter = pLinkSpeedContext->pAdapter;
1283
1284 /* there is a race condition that exists between this callback
1285 * function and the caller since the caller could time out either
1286 * before or while this code is executing. we use a spinlock to
1287 * serialize these actions
1288 */
1289
1290 if ((NULL == pAdapter) ||
1291 (LINK_CONTEXT_MAGIC != pLinkSpeedContext->magic)) {
1292 /* the caller presumably timed out so there is nothing
1293 * we can do
1294 */
1295 spin_unlock(&hdd_context_lock);
1296 hddLog(CDF_TRACE_LEVEL_WARN,
1297 "%s: Invalid context, pAdapter [%p] magic [%08x]",
1298 __func__, pAdapter, pLinkSpeedContext->magic);
1299 if (ioctl_debug) {
1300 pr_info("%s: Invalid context, pAdapter [%p] magic [%08x]\n",
1301 __func__, pAdapter, pLinkSpeedContext->magic);
1302 }
1303 return;
1304 }
1305
1306 /* context is valid so caller is still waiting */
1307
1308 /* paranoia: invalidate the magic */
1309 pLinkSpeedContext->magic = 0;
1310
1311 /* copy over the stats. do so as a struct copy */
1312 pAdapter->ls_stats = *pLinkSpeed;
1313
1314 /* notify the caller */
1315 complete(&pLinkSpeedContext->completion);
1316
1317 /* serialization is complete */
1318 spin_unlock(&hdd_context_lock);
1319}
1320
1321/**
1322 * wlan_hdd_get_linkspeed_for_peermac() - Get link speed for a peer
1323 * @pAdapter: adapter upon which the peer is active
1324 * @macAddress: MAC address of the peer
1325 *
1326 * This function will send a query to SME for the linkspeed of the
1327 * given peer, and then wait for the callback to be invoked.
1328 *
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301329 * Return: QDF_STATUS_SUCCESS if linkspeed data is available,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001330 * otherwise a CDF_STATUS_E_* error.
1331 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301332QDF_STATUS wlan_hdd_get_linkspeed_for_peermac(hdd_adapter_t *pAdapter,
Srinivas Girigowdadccab9a2015-11-19 14:31:14 -08001333 struct cdf_mac_addr macAddress) {
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301334 QDF_STATUS status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001335 unsigned long rc;
1336 struct linkspeedContext context;
1337 tSirLinkSpeedInfo *linkspeed_req;
1338
1339 if (NULL == pAdapter) {
1340 hddLog(CDF_TRACE_LEVEL_ERROR, "%s: pAdapter is NULL", __func__);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301341 return QDF_STATUS_E_FAULT;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001342 }
1343 linkspeed_req = cdf_mem_malloc(sizeof(*linkspeed_req));
1344 if (NULL == linkspeed_req) {
1345 CDF_TRACE(CDF_MODULE_ID_HDD, CDF_TRACE_LEVEL_ERROR,
1346 "%s Request Buffer Alloc Fail", __func__);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301347 return QDF_STATUS_E_NOMEM;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001348 }
1349 init_completion(&context.completion);
1350 context.pAdapter = pAdapter;
1351 context.magic = LINK_CONTEXT_MAGIC;
1352
Srinivas Girigowdadccab9a2015-11-19 14:31:14 -08001353 cdf_copy_macaddr(&linkspeed_req->peer_macaddr, &macAddress);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001354 status = sme_get_link_speed(WLAN_HDD_GET_HAL_CTX(pAdapter),
1355 linkspeed_req,
1356 &context, hdd_get_link_speed_cb);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301357 if (QDF_STATUS_SUCCESS != status) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001358 hddLog(CDF_TRACE_LEVEL_ERROR,
1359 "%s: Unable to retrieve statistics for link speed",
1360 __func__);
1361 cdf_mem_free(linkspeed_req);
1362 } else {
1363 rc = wait_for_completion_timeout
1364 (&context.completion,
1365 msecs_to_jiffies(WLAN_WAIT_TIME_STATS));
1366 if (!rc) {
1367 hddLog(CDF_TRACE_LEVEL_ERROR,
1368 "%s: SME timed out while retrieving link speed",
1369 __func__);
1370 }
1371 }
1372
1373 /* either we never sent a request, we sent a request and
1374 * received a response or we sent a request and timed out. if
1375 * we never sent a request or if we sent a request and got a
1376 * response, we want to clear the magic out of paranoia. if
1377 * we timed out there is a race condition such that the
1378 * callback function could be executing at the same time we
1379 * are. of primary concern is if the callback function had
1380 * already verified the "magic" but had not yet set the
1381 * completion variable when a timeout occurred. we serialize
1382 * these activities by invalidating the magic while holding a
1383 * shared spinlock which will cause us to block if the
1384 * callback is currently executing
1385 */
1386 spin_lock(&hdd_context_lock);
1387 context.magic = 0;
1388 spin_unlock(&hdd_context_lock);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301389 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001390}
1391
1392/**
1393 * wlan_hdd_get_link_speed() - get link speed
1394 * @pAdapter: pointer to the adapter
1395 * @link_speed: pointer to link speed
1396 *
1397 * This function fetches per bssid link speed.
1398 *
1399 * Return: if associated, link speed shall be returned.
1400 * if not associated, link speed of 0 is returned.
1401 * On error, error number will be returned.
1402 */
1403int wlan_hdd_get_link_speed(hdd_adapter_t *sta_adapter, uint32_t *link_speed)
1404{
1405 hdd_context_t *hddctx = WLAN_HDD_GET_CTX(sta_adapter);
1406 hdd_station_ctx_t *hdd_stactx =
1407 WLAN_HDD_GET_STATION_CTX_PTR(sta_adapter);
1408 int ret;
1409
1410 ret = wlan_hdd_validate_context(hddctx);
1411
1412 if (0 != ret) {
1413 hddLog(LOGE, FL("HDD context is not valid"));
1414 return ret;
1415 }
1416
1417 if (eConnectionState_Associated != hdd_stactx->conn_info.connState) {
1418 /* we are not connected so we don't have a classAstats */
1419 *link_speed = 0;
1420 } else {
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301421 QDF_STATUS status;
Srinivas Girigowdadccab9a2015-11-19 14:31:14 -08001422 struct cdf_mac_addr bssid;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001423
Srinivas Girigowdadccab9a2015-11-19 14:31:14 -08001424 cdf_copy_macaddr(&bssid, &hdd_stactx->conn_info.bssId);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001425
1426 status = wlan_hdd_get_linkspeed_for_peermac(sta_adapter, bssid);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301427 if (!QDF_IS_STATUS_SUCCESS(status)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001428 hddLog(LOGE, FL("Unable to retrieve SME linkspeed"));
1429 return -EINVAL;
1430 }
1431 *link_speed = sta_adapter->ls_stats.estLinkSpeed;
1432 /* linkspeed in units of 500 kbps */
1433 *link_speed = (*link_speed) / 500;
1434 }
1435 return 0;
1436}
1437
1438/**
1439 * hdd_statistics_cb() - "Get statistics" callback function
1440 * @pStats: statistics payload
1441 * @pContext: opaque context originally passed to SME. HDD always passes
1442 * a pointer to an adapter
1443 *
1444 * Return: None
1445 */
1446void hdd_statistics_cb(void *pStats, void *pContext)
1447{
1448 hdd_adapter_t *pAdapter = (hdd_adapter_t *) pContext;
1449 hdd_stats_t *pStatsCache = NULL;
1450 hdd_wext_state_t *pWextState;
Anurag Chouhance0dc992016-02-16 18:18:03 +05301451 QDF_STATUS qdf_status = QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001452
1453 tCsrSummaryStatsInfo *pSummaryStats = NULL;
1454 tCsrGlobalClassAStatsInfo *pClassAStats = NULL;
1455 tCsrGlobalClassBStatsInfo *pClassBStats = NULL;
1456 tCsrGlobalClassCStatsInfo *pClassCStats = NULL;
1457 tCsrGlobalClassDStatsInfo *pClassDStats = NULL;
1458 tCsrPerStaStatsInfo *pPerStaStats = NULL;
1459
1460 if (pAdapter != NULL)
1461 pStatsCache = &pAdapter->hdd_stats;
1462
1463 pSummaryStats = (tCsrSummaryStatsInfo *) pStats;
1464 pClassAStats = (tCsrGlobalClassAStatsInfo *) (pSummaryStats + 1);
1465 pClassBStats = (tCsrGlobalClassBStatsInfo *) (pClassAStats + 1);
1466 pClassCStats = (tCsrGlobalClassCStatsInfo *) (pClassBStats + 1);
1467 pClassDStats = (tCsrGlobalClassDStatsInfo *) (pClassCStats + 1);
1468 pPerStaStats = (tCsrPerStaStatsInfo *) (pClassDStats + 1);
1469
1470 if (pStatsCache != NULL) {
1471 /* copy the stats into the cache we keep in the
1472 * adapter instance structure
1473 */
1474 cdf_mem_copy(&pStatsCache->summary_stat, pSummaryStats,
1475 sizeof(pStatsCache->summary_stat));
1476 cdf_mem_copy(&pStatsCache->ClassA_stat, pClassAStats,
1477 sizeof(pStatsCache->ClassA_stat));
1478 cdf_mem_copy(&pStatsCache->ClassB_stat, pClassBStats,
1479 sizeof(pStatsCache->ClassB_stat));
1480 cdf_mem_copy(&pStatsCache->ClassC_stat, pClassCStats,
1481 sizeof(pStatsCache->ClassC_stat));
1482 cdf_mem_copy(&pStatsCache->ClassD_stat, pClassDStats,
1483 sizeof(pStatsCache->ClassD_stat));
1484 cdf_mem_copy(&pStatsCache->perStaStats, pPerStaStats,
1485 sizeof(pStatsCache->perStaStats));
1486 }
1487
1488 if (pAdapter) {
1489 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Anurag Chouhance0dc992016-02-16 18:18:03 +05301490 qdf_status = qdf_event_set(&pWextState->hdd_cdf_event);
1491 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
1492 hddLog(LOGE, FL("qdf_event_set failed"));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001493 return;
1494 }
1495 }
1496}
1497
1498/**
1499 * hdd_clear_roam_profile_ie() - Clear Roam Profile IEs
1500 * @pAdapter: adapter who's IEs are to be cleared
1501 *
1502 * Return: None
1503 */
1504void hdd_clear_roam_profile_ie(hdd_adapter_t *pAdapter)
1505{
1506 int i = 0;
1507 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
1508
1509 /* clear WPA/RSN/WSC IE information in the profile */
1510 pWextState->roamProfile.nWPAReqIELength = 0;
1511 pWextState->roamProfile.pWPAReqIE = (uint8_t *) NULL;
1512 pWextState->roamProfile.nRSNReqIELength = 0;
1513 pWextState->roamProfile.pRSNReqIE = (uint8_t *) NULL;
1514
1515#ifdef FEATURE_WLAN_WAPI
1516 pWextState->roamProfile.nWAPIReqIELength = 0;
1517 pWextState->roamProfile.pWAPIReqIE = (uint8_t *) NULL;
1518#endif
1519
1520 pWextState->roamProfile.bWPSAssociation = false;
1521 pWextState->roamProfile.bOSENAssociation = false;
1522 pWextState->roamProfile.pAddIEScan = (uint8_t *) NULL;
1523 pWextState->roamProfile.nAddIEScanLength = 0;
1524 pWextState->roamProfile.pAddIEAssoc = (uint8_t *) NULL;
1525 pWextState->roamProfile.nAddIEAssocLength = 0;
1526
1527 pWextState->roamProfile.EncryptionType.numEntries = 1;
1528 pWextState->roamProfile.EncryptionType.encryptionType[0]
1529 = eCSR_ENCRYPT_TYPE_NONE;
1530
1531 pWextState->roamProfile.mcEncryptionType.numEntries = 1;
1532 pWextState->roamProfile.mcEncryptionType.encryptionType[0]
1533 = eCSR_ENCRYPT_TYPE_NONE;
1534
1535 pWextState->roamProfile.AuthType.numEntries = 1;
1536 pWextState->roamProfile.AuthType.authType[0] =
1537 eCSR_AUTH_TYPE_OPEN_SYSTEM;
1538
1539#ifdef WLAN_FEATURE_11W
1540 pWextState->roamProfile.MFPEnabled = false;
1541 pWextState->roamProfile.MFPRequired = 0;
1542 pWextState->roamProfile.MFPCapable = 0;
1543#endif
1544
1545 pWextState->authKeyMgmt = 0;
1546
1547 for (i = 0; i < CSR_MAX_NUM_KEY; i++) {
1548 if (pWextState->roamProfile.Keys.KeyMaterial[i]) {
1549 pWextState->roamProfile.Keys.KeyLength[i] = 0;
1550 }
1551 }
1552#ifdef FEATURE_WLAN_WAPI
1553 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_OPEN;
1554 pAdapter->wapi_info.nWapiMode = 0;
1555#endif
1556
1557 cdf_zero_macaddr(&pWextState->req_bssId);
1558
1559}
1560
1561/**
1562 * wlan_hdd_get_vendor_oui_ie_ptr() - Find a vendor OUI
1563 * @oui: The OUI that is being searched for
1564 * @oui_size: The length of @oui
1565 * @ie: The set of IEs within which we're trying to find @oui
1566 * @ie_len: The length of @ie
1567 *
1568 * This function will scan the IEs contained within @ie looking for @oui.
1569 *
1570 * Return: Pointer to @oui embedded within @ie if it is present, NULL
1571 * if @oui is not present within @ie.
1572 */
1573uint8_t *wlan_hdd_get_vendor_oui_ie_ptr(uint8_t *oui, uint8_t oui_size,
1574 uint8_t *ie, int ie_len)
1575{
1576 int left = ie_len;
1577 uint8_t *ptr = ie;
1578 uint8_t elem_id, elem_len;
1579 uint8_t eid = 0xDD;
1580
1581 if (NULL == ie || 0 == ie_len)
1582 return NULL;
1583
1584 while (left >= 2) {
1585 elem_id = ptr[0];
1586 elem_len = ptr[1];
1587 left -= 2;
1588 if (elem_len > left) {
1589 hddLog(CDF_TRACE_LEVEL_FATAL,
1590 FL
1591 ("****Invalid IEs eid = %d elem_len=%d left=%d*****"),
1592 eid, elem_len, left);
1593 return NULL;
1594 }
1595 if (elem_id == eid) {
1596 if (memcmp(&ptr[2], oui, oui_size) == 0)
1597 return ptr;
1598 }
1599
1600 left -= elem_len;
1601 ptr += (elem_len + 2);
1602 }
1603 return NULL;
1604}
1605
1606/**
1607 * __iw_set_commit() - SIOCSIWCOMMIT ioctl handler
1608 * @dev: device upon which the ioctl was received
1609 * @info: ioctl request information
1610 * @wrqu: ioctl request data
1611 * @extra: ioctl extra data
1612 *
1613 * Return: 0 on success, non-zero on error
1614 */
1615static int __iw_set_commit(struct net_device *dev, struct iw_request_info *info,
1616 union iwreq_data *wrqu, char *extra)
1617{
1618 hdd_adapter_t *adapter;
1619 hdd_context_t *hdd_ctx;
1620 int ret;
1621
1622 adapter = WLAN_HDD_GET_PRIV_PTR(dev);
1623 hdd_ctx = WLAN_HDD_GET_CTX(adapter);
1624 ret = wlan_hdd_validate_context(hdd_ctx);
1625 if (0 != ret)
1626 return ret;
1627
1628 hddLog(LOG1, "In %s", __func__);
1629 /* Do nothing for now */
1630 return 0;
1631}
1632
1633/**
1634 * iw_set_commit() - SSR wrapper function for __iw_set_commit
1635 * @dev: pointer to net_device
1636 * @info: pointer to iw_request_info
1637 * @wrqu: pointer to iwreq_data
1638 * @extra: extra
1639 *
1640 * Return: 0 on success, error number otherwise
1641 */
1642int iw_set_commit(struct net_device *dev, struct iw_request_info *info,
1643 union iwreq_data *wrqu, char *extra)
1644{
1645 int ret;
1646
1647 cds_ssr_protect(__func__);
1648 ret = __iw_set_commit(dev, info, wrqu, extra);
1649 cds_ssr_unprotect(__func__);
1650
1651 return ret;
1652}
1653
1654/**
1655 * __iw_get_name() - SIOCGIWNAME ioctl handler
1656 * @dev: device upon which the ioctl was received
1657 * @info: ioctl request information
1658 * @wrqu: ioctl request data
1659 * @extra: ioctl extra data
1660 *
1661 * Return: 0 on success, non-zero on error
1662 */
1663static int __iw_get_name(struct net_device *dev,
1664 struct iw_request_info *info, char *wrqu, char *extra)
1665{
1666 hdd_adapter_t *adapter;
1667 hdd_context_t *hdd_ctx;
1668 int ret;
1669
1670 ENTER();
1671
1672 adapter = WLAN_HDD_GET_PRIV_PTR(dev);
1673 hdd_ctx = WLAN_HDD_GET_CTX(adapter);
1674 ret = wlan_hdd_validate_context(hdd_ctx);
1675 if (0 != ret)
1676 return ret;
1677
1678 strlcpy(wrqu, "Qcom:802.11n", IFNAMSIZ);
1679 EXIT();
1680 return 0;
1681}
1682
1683/**
1684 * __iw_get_name() - SSR wrapper for __iw_get_name
1685 * @dev: pointer to net_device
1686 * @info: pointer to iw_request_info
1687 * @wrqu: pointer to iwreq_data
1688 * @extra: extra
1689 *
1690 * Return: 0 on success, error number otherwise
1691 */
1692static int iw_get_name(struct net_device *dev,
1693 struct iw_request_info *info,
1694 char *wrqu, char *extra)
1695{
1696 int ret;
1697
1698 cds_ssr_protect(__func__);
1699 ret = __iw_get_name(dev, info, wrqu, extra);
1700 cds_ssr_unprotect(__func__);
1701
1702 return ret;
1703}
1704
1705/**
1706 * __iw_set_mode() - ioctl handler
1707 * @dev: device upon which the ioctl was received
1708 * @info: ioctl request information
1709 * @wrqu: ioctl request data
1710 * @extra: ioctl extra data
1711 *
1712 * Return: 0 on success, non-zero on error
1713 */
1714static int __iw_set_mode(struct net_device *dev,
1715 struct iw_request_info *info,
1716 union iwreq_data *wrqu, char *extra)
1717{
1718 hdd_wext_state_t *pWextState;
1719 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
1720 hdd_context_t *hdd_ctx;
1721 tCsrRoamProfile *pRoamProfile;
1722 eCsrRoamBssType LastBSSType;
1723 eMib_dot11DesiredBssType connectedBssType;
1724 struct hdd_config *pConfig;
1725 struct wireless_dev *wdev;
1726 int ret;
1727
1728 ENTER();
1729
1730 hdd_ctx = WLAN_HDD_GET_CTX(pAdapter);
1731 ret = wlan_hdd_validate_context(hdd_ctx);
1732 if (0 != ret)
1733 return ret;
1734
1735 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
1736 wdev = dev->ieee80211_ptr;
1737 pRoamProfile = &pWextState->roamProfile;
1738 LastBSSType = pRoamProfile->BSSType;
1739
1740 hddLog(LOG1, "%s Old Bss type = %d", __func__, LastBSSType);
1741
1742 switch (wrqu->mode) {
1743 case IW_MODE_ADHOC:
1744 hddLog(LOG1, "%s Setting AP Mode as IW_MODE_ADHOC", __func__);
1745 pRoamProfile->BSSType = eCSR_BSS_TYPE_START_IBSS;
1746 /* Set the phymode correctly for IBSS. */
1747 pConfig = (WLAN_HDD_GET_CTX(pAdapter))->config;
1748 pWextState->roamProfile.phyMode =
1749 hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode);
1750 pAdapter->device_mode = WLAN_HDD_IBSS;
1751 wdev->iftype = NL80211_IFTYPE_ADHOC;
1752 break;
1753 case IW_MODE_INFRA:
1754 hddLog(LOG1, "%s Setting AP Mode as IW_MODE_INFRA", __func__);
1755 pRoamProfile->BSSType = eCSR_BSS_TYPE_INFRASTRUCTURE;
1756 wdev->iftype = NL80211_IFTYPE_STATION;
1757 break;
1758 case IW_MODE_AUTO:
1759 hddLog(LOG1, "%s Setting AP Mode as IW_MODE_AUTO", __func__);
1760 pRoamProfile->BSSType = eCSR_BSS_TYPE_ANY;
1761 break;
1762 default:
1763 hddLog(LOGE, "%s Unknown AP Mode value %d ", __func__,
1764 wrqu->mode);
1765 return -EOPNOTSUPP;
1766 }
1767
1768 if (LastBSSType != pRoamProfile->BSSType) {
1769 /* the BSS mode changed. We need to issue disconnect
1770 * if connected or in IBSS disconnect state
1771 */
1772 if (hdd_conn_get_connected_bss_type
1773 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), &connectedBssType)
1774 || (eCSR_BSS_TYPE_START_IBSS == LastBSSType)) {
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301775 QDF_STATUS qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001776 /* need to issue a disconnect to CSR. */
1777 INIT_COMPLETION(pAdapter->disconnect_comp_var);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301778 qdf_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001779 sme_roam_disconnect(WLAN_HDD_GET_HAL_CTX(pAdapter),
1780 pAdapter->sessionId,
1781 eCSR_DISCONNECT_REASON_IBSS_LEAVE);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301782 if (QDF_STATUS_SUCCESS == qdf_status) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001783 unsigned long rc;
1784 rc = wait_for_completion_timeout(&pAdapter->
1785 disconnect_comp_var,
1786 msecs_to_jiffies
1787 (WLAN_WAIT_TIME_DISCONNECT));
1788 if (!rc)
1789 hddLog(CDF_TRACE_LEVEL_ERROR,
1790 FL
1791 ("failed wait on disconnect_comp_var"));
1792 }
1793 }
1794 }
1795
1796 EXIT();
1797 return 0;
1798}
1799
1800/**
1801 * iw_set_mode() - SSR wrapper for __iw_set_mode()
1802 * @dev: pointer to net_device
1803 * @info: pointer to iw_request_info
1804 * @wrqu: pointer to iwreq_data
1805 * @extra: pointer to extra ioctl payload
1806 *
1807 * Return: 0 on success, error number otherwise
1808 */
1809static int iw_set_mode(struct net_device *dev, struct iw_request_info *info,
1810 union iwreq_data *wrqu, char *extra)
1811{
1812 int ret;
1813
1814 cds_ssr_protect(__func__);
1815 ret = __iw_set_mode(dev, info, wrqu, extra);
1816 cds_ssr_unprotect(__func__);
1817
1818 return ret;
1819}
1820
1821/**
1822 * __iw_get_mode() - SIOCGIWMODE ioctl handler
1823 * @dev: device upon which the ioctl was received
1824 * @info: ioctl request information
1825 * @wrqu: ioctl request data
1826 * @extra: ioctl extra data
1827 *
1828 * Return: 0 on success, non-zero on error
1829 */
1830static int
1831__iw_get_mode(struct net_device *dev, struct iw_request_info *info,
1832 union iwreq_data *wrqu, char *extra)
1833{
1834 hdd_wext_state_t *pWextState;
1835 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
1836 hdd_context_t *hdd_ctx;
1837 int ret;
1838
1839 ENTER();
1840
1841 hdd_ctx = WLAN_HDD_GET_CTX(pAdapter);
1842 ret = wlan_hdd_validate_context(hdd_ctx);
1843 if (0 != ret)
1844 return ret;
1845
1846 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
1847
1848 switch (pWextState->roamProfile.BSSType) {
1849 case eCSR_BSS_TYPE_INFRASTRUCTURE:
1850 hddLog(LOG1, FL("returns IW_MODE_INFRA"));
1851 wrqu->mode = IW_MODE_INFRA;
1852 break;
1853 case eCSR_BSS_TYPE_IBSS:
1854 case eCSR_BSS_TYPE_START_IBSS:
1855 hddLog(LOG1, FL("returns IW_MODE_ADHOC"));
1856 wrqu->mode = IW_MODE_ADHOC;
1857 break;
1858 case eCSR_BSS_TYPE_ANY:
1859 default:
1860 hddLog(LOG1, FL("returns IW_MODE_AUTO"));
1861 wrqu->mode = IW_MODE_AUTO;
1862 break;
1863 }
1864
1865 EXIT();
1866 return 0;
1867}
1868
1869/**
1870 * iw_get_mode() - SSR wrapper for __iw_get_mode()
1871 * @dev: pointer to net_device
1872 * @info: pointer to iw_request_info
1873 * @wrqu: pointer to iwreq_data
1874 * @extra: pointer to extra ioctl payload
1875 *
1876 * Return: 0 on success, error number otherwise
1877 */
1878static int iw_get_mode(struct net_device *dev, struct iw_request_info *info,
1879 union iwreq_data *wrqu, char *extra)
1880{
1881 int ret;
1882
1883 cds_ssr_protect(__func__);
1884 ret = __iw_get_mode(dev, info, wrqu, extra);
1885 cds_ssr_unprotect(__func__);
1886
1887 return ret;
1888}
1889
1890/**
1891 * __iw_set_freq() - SIOCSIWFREQ ioctl handler
1892 * @dev: device upon which the ioctl was received
1893 * @info: ioctl request information
1894 * @wrqu: ioctl request data
1895 * @extra: ioctl extra data
1896 *
1897 * Return: 0 on success, non-zero on error
1898 */
1899static int __iw_set_freq(struct net_device *dev, struct iw_request_info *info,
1900 union iwreq_data *wrqu, char *extra)
1901{
1902 uint32_t numChans = 0;
1903 uint8_t validChan[WNI_CFG_VALID_CHANNEL_LIST_LEN];
1904 uint32_t indx = 0;
1905 int ret;
1906 hdd_wext_state_t *pWextState;
1907 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
1908 hdd_context_t *hdd_ctx;
1909 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
1910 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
1911 tCsrRoamProfile *pRoamProfile;
1912
1913 ENTER();
1914
1915 hdd_ctx = WLAN_HDD_GET_CTX(pAdapter);
1916 ret = wlan_hdd_validate_context(hdd_ctx);
1917 if (0 != ret)
1918 return ret;
1919
1920 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
1921
1922 pRoamProfile = &pWextState->roamProfile;
1923
1924 hddLog(LOG1, "setCHANNEL ioctl");
1925
1926 /* Link is up then return cant set channel */
1927 if (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState ||
1928 eConnectionState_Associated == pHddStaCtx->conn_info.connState) {
1929 hddLog(LOGE, "IBSS Associated");
1930 return -EOPNOTSUPP;
1931 }
1932
1933 /* Settings by Frequency as input */
1934 if ((wrqu->freq.e == 1) && (wrqu->freq.m >= (uint32_t) 2.412e8) &&
1935 (wrqu->freq.m <= (uint32_t) 5.825e8)) {
1936 uint32_t freq = wrqu->freq.m / 100000;
1937
1938 while ((indx < FREQ_CHAN_MAP_TABLE_SIZE)
1939 && (freq != freq_chan_map[indx].freq))
1940 indx++;
1941 if (indx >= FREQ_CHAN_MAP_TABLE_SIZE) {
1942 return -EINVAL;
1943 }
1944 wrqu->freq.e = 0;
1945 wrqu->freq.m = freq_chan_map[indx].chan;
1946
1947 }
1948
1949 if (wrqu->freq.e == 0) {
1950 if ((wrqu->freq.m < WNI_CFG_CURRENT_CHANNEL_STAMIN) ||
1951 (wrqu->freq.m > WNI_CFG_CURRENT_CHANNEL_STAMAX)) {
1952 hddLog(LOG1,
1953 "%s: Channel [%d] is outside valid range from %d to %d",
1954 __func__, wrqu->freq.m,
1955 WNI_CFG_CURRENT_CHANNEL_STAMIN,
1956 WNI_CFG_CURRENT_CHANNEL_STAMAX);
1957 return -EINVAL;
1958 }
1959
1960 numChans = WNI_CFG_VALID_CHANNEL_LIST_LEN;
1961
1962 if (sme_cfg_get_str(hHal, WNI_CFG_VALID_CHANNEL_LIST,
1963 validChan, &numChans) !=
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301964 QDF_STATUS_SUCCESS) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001965 CDF_TRACE(CDF_MODULE_ID_HDD, CDF_TRACE_LEVEL_WARN, FL
1966 ("failed to get ini parameter, WNI_CFG_VALID_CHANNEL_LIST"));
1967 return -EIO;
1968 }
1969
1970 for (indx = 0; indx < numChans; indx++) {
1971 if (wrqu->freq.m == validChan[indx]) {
1972 break;
1973 }
1974 }
1975 } else {
1976
1977 return -EINVAL;
1978 }
1979
1980 if (indx >= numChans) {
1981 return -EINVAL;
1982 }
1983
1984 /* Set the Operational Channel */
1985 numChans = pRoamProfile->ChannelInfo.numOfChannels = 1;
1986 pHddStaCtx->conn_info.operationChannel = wrqu->freq.m;
1987 pRoamProfile->ChannelInfo.ChannelList =
1988 &pHddStaCtx->conn_info.operationChannel;
1989
1990 hddLog(LOG1, "pRoamProfile->operationChannel = %d", wrqu->freq.m);
1991
1992 EXIT();
1993
1994 return ret;
1995}
1996
1997/**
1998 * iw_set_freq() - SSR wrapper for __iw_set_freq()
1999 * @dev: pointer to net_device
2000 * @info: pointer to iw_request_info
2001 * @wrqu: pointer to iwreq_data
2002 * @extra: pointer to extra ioctl payload
2003 *
2004 * Return: 0 on success, error number otherwise
2005 */
2006static int iw_set_freq(struct net_device *dev, struct iw_request_info *info,
2007 union iwreq_data *wrqu, char *extra)
2008{
2009 int ret;
2010
2011 cds_ssr_protect(__func__);
2012 ret = __iw_set_freq(dev, info, wrqu, extra);
2013 cds_ssr_unprotect(__func__);
2014
2015 return ret;
2016}
2017
2018/**
2019 * __iw_get_freq() - SIOCGIWFREQ ioctl handler
2020 * @dev: device upon which the ioctl was received
2021 * @info: ioctl request information
2022 * @wrqu: ioctl request data
2023 * @extra: ioctl extra data
2024 *
2025 * Return: 0 on success, non-zero on error
2026 */
2027static int __iw_get_freq(struct net_device *dev, struct iw_request_info *info,
2028 struct iw_freq *fwrq, char *extra)
2029{
2030 uint32_t status = false, channel = 0, freq = 0;
2031 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
2032 tHalHandle hHal;
2033 hdd_wext_state_t *pWextState;
2034 tCsrRoamProfile *pRoamProfile;
2035 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
2036 hdd_context_t *hdd_ctx;
2037 int ret;
2038
2039 ENTER();
2040
2041 hdd_ctx = WLAN_HDD_GET_CTX(pAdapter);
2042 ret = wlan_hdd_validate_context(hdd_ctx);
2043 if (0 != ret)
2044 return ret;
2045
2046 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
2047 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
2048
2049 pRoamProfile = &pWextState->roamProfile;
2050
2051 if (pHddStaCtx->conn_info.connState == eConnectionState_Associated) {
2052 if (sme_get_operation_channel(hHal, &channel, pAdapter->sessionId)
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302053 != QDF_STATUS_SUCCESS) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002054 CDF_TRACE(CDF_MODULE_ID_HDD, CDF_TRACE_LEVEL_ERROR,
2055 FL("failed to get operating channel %u"),
2056 pAdapter->sessionId);
2057 return -EIO;
2058 } else {
2059 status = hdd_wlan_get_freq(channel, &freq);
2060 if (true == status) {
2061 /* Set Exponent parameter as 6 (MHZ)
2062 * in struct iw_freq iwlist & iwconfig
2063 * command shows frequency into proper
2064 * format (2.412 GHz instead of 246.2
2065 * MHz)
2066 */
2067 fwrq->m = freq;
2068 fwrq->e = MHZ;
2069 }
2070 }
2071 } else {
2072 /* Set Exponent parameter as 6 (MHZ) in struct iw_freq
2073 * iwlist & iwconfig command shows frequency into proper
2074 * format (2.412 GHz instead of 246.2 MHz)
2075 */
2076 fwrq->m = 0;
2077 fwrq->e = MHZ;
2078 }
2079 return 0;
2080}
2081
2082/**
2083 * iw_get_freq() - SSR wrapper for __iw_get_freq()
2084 * @dev: pointer to net_device
2085 * @info: pointer to iw_request_info
2086 * @fwrq: pointer to frequency data
2087 * @extra: pointer to extra ioctl payload
2088 *
2089 * Return: 0 on success, error number otherwise
2090 */
2091static int iw_get_freq(struct net_device *dev, struct iw_request_info *info,
2092 struct iw_freq *fwrq, char *extra)
2093{
2094 int ret;
2095
2096 cds_ssr_protect(__func__);
2097 ret = __iw_get_freq(dev, info, fwrq, extra);
2098 cds_ssr_unprotect(__func__);
2099
2100 return ret;
2101}
2102
2103/**
2104 * __iw_get_tx_power() - SIOCGIWTXPOW ioctl handler
2105 * @dev: device upon which the ioctl was received
2106 * @info: ioctl request information
2107 * @wrqu: ioctl request data
2108 * @extra: ioctl extra data
2109 *
2110 * Return: 0 on success, non-zero on error
2111 */
2112static int __iw_get_tx_power(struct net_device *dev,
2113 struct iw_request_info *info,
2114 union iwreq_data *wrqu, char *extra)
2115{
2116
2117 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
2118 hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(pAdapter);
2119 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
2120 int ret;
2121
2122 ret = wlan_hdd_validate_context(hdd_ctx);
2123 if (0 != ret)
2124 return ret;
2125
2126 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState) {
2127 wrqu->txpower.value = 0;
2128 return 0;
2129 }
2130 wlan_hdd_get_class_astats(pAdapter);
2131 wrqu->txpower.value = pAdapter->hdd_stats.ClassA_stat.max_pwr;
2132
2133 return 0;
2134}
2135
2136/**
2137 * iw_get_tx_power() - SSR wrapper for __iw_get_tx_power()
2138 * @dev: pointer to net_device
2139 * @info: pointer to iw_request_info
2140 * @wrqu: pointer to iwreq_data
2141 * @extra: pointer to extra ioctl payload
2142 *
2143 * Return: 0 on success, error number otherwise
2144 */
2145static int iw_get_tx_power(struct net_device *dev,
2146 struct iw_request_info *info,
2147 union iwreq_data *wrqu, char *extra)
2148{
2149 int ret;
2150
2151 cds_ssr_protect(__func__);
2152 ret = __iw_get_tx_power(dev, info, wrqu, extra);
2153 cds_ssr_unprotect(__func__);
2154
2155 return ret;
2156}
2157
2158/**
2159 * __iw_set_tx_power() - SIOCSIWTXPOW ioctl handler
2160 * @dev: device upon which the ioctl was received
2161 * @info: ioctl request information
2162 * @wrqu: ioctl request data
2163 * @extra: ioctl extra data
2164 *
2165 * Return: 0 on success, non-zero on error
2166 */
2167static int __iw_set_tx_power(struct net_device *dev,
2168 struct iw_request_info *info,
2169 union iwreq_data *wrqu, char *extra)
2170{
2171 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
2172 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
2173 hdd_context_t *hdd_ctx;
2174 int ret;
2175
2176 ENTER();
2177
2178 hdd_ctx = WLAN_HDD_GET_CTX(pAdapter);
2179 ret = wlan_hdd_validate_context(hdd_ctx);
2180 if (0 != ret)
2181 return ret;
2182
2183 if (sme_cfg_set_int(hHal, WNI_CFG_CURRENT_TX_POWER_LEVEL,
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302184 wrqu->txpower.value) != QDF_STATUS_SUCCESS) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002185 CDF_TRACE(CDF_MODULE_ID_HDD, CDF_TRACE_LEVEL_ERROR, FL
2186 ("failed to set ini parameter, WNI_CFG_CURRENT_TX_POWER_LEVEL"));
2187 return -EIO;
2188 }
2189
2190 EXIT();
2191
2192 return 0;
2193}
2194
2195/**
2196 * iw_set_tx_power() - SSR wrapper for __iw_set_tx_power()
2197 * @dev: pointer to net_device
2198 * @info: pointer to iw_request_info
2199 * @wrqu: pointer to iwreq_data
2200 * @extra: pointer to extra ioctl payload
2201 *
2202 * Return: 0 on success, error number otherwise
2203 */
2204static int iw_set_tx_power(struct net_device *dev,
2205 struct iw_request_info *info,
2206 union iwreq_data *wrqu, char *extra)
2207{
2208 int ret;
2209
2210 cds_ssr_protect(__func__);
2211 ret = __iw_set_tx_power(dev, info, wrqu, extra);
2212 cds_ssr_unprotect(__func__);
2213
2214 return ret;
2215}
2216
2217/**
2218 * __iw_get_bitrate() - SIOCGIWRATE ioctl handler
2219 * @dev: device upon which the ioctl was received
2220 * @info: ioctl request information
2221 * @wrqu: ioctl request data
2222 * @extra: ioctl extra data
2223 *
2224 * Return: 0 on success, non-zero on error
2225 */
2226static int __iw_get_bitrate(struct net_device *dev,
2227 struct iw_request_info *info,
2228 union iwreq_data *wrqu, char *extra)
2229{
Anurag Chouhance0dc992016-02-16 18:18:03 +05302230 QDF_STATUS qdf_status = QDF_STATUS_SUCCESS;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302231 QDF_STATUS status = QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002232 hdd_wext_state_t *pWextState;
2233 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
2234 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
2235 hdd_context_t *hdd_ctx;
2236 int ret;
2237
2238 ENTER();
2239
2240 hdd_ctx = WLAN_HDD_GET_CTX(pAdapter);
2241 ret = wlan_hdd_validate_context(hdd_ctx);
2242 if (0 != ret)
2243 return ret;
2244
Prashanth Bhatta9e143052015-12-04 11:56:47 -08002245 if (cds_is_driver_recovering()) {
2246 hdd_alert("Recovery in Progress. State: 0x%x Ignore!!!",
2247 cds_get_driver_state());
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002248 return status;
2249 }
2250
2251 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState) {
2252 wrqu->bitrate.value = 0;
2253 } else {
2254 status =
2255 sme_get_statistics(WLAN_HDD_GET_HAL_CTX(pAdapter),
2256 eCSR_HDD,
2257 SME_SUMMARY_STATS |
2258 SME_GLOBAL_CLASSA_STATS |
2259 SME_GLOBAL_CLASSB_STATS |
2260 SME_GLOBAL_CLASSC_STATS |
2261 SME_GLOBAL_CLASSD_STATS |
2262 SME_PER_STA_STATS,
2263 hdd_statistics_cb, 0,
2264 false,
2265 pHddStaCtx->conn_info.staId[0],
2266 pAdapter, pAdapter->sessionId);
2267
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302268 if (QDF_STATUS_SUCCESS != status) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002269 hddLog(CDF_TRACE_LEVEL_ERROR,
2270 "%s: Unable to retrieve statistics", __func__);
2271 return status;
2272 }
2273
2274 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
2275
Anurag Chouhance0dc992016-02-16 18:18:03 +05302276 qdf_status =
2277 qdf_wait_single_event(&pWextState->hdd_cdf_event,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002278 WLAN_WAIT_TIME_STATS);
2279
Anurag Chouhance0dc992016-02-16 18:18:03 +05302280 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002281 hddLog(CDF_TRACE_LEVEL_ERROR,
2282 "%s: SME timeout while retrieving statistics",
2283 __func__);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302284 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002285 }
2286
2287 wrqu->bitrate.value =
2288 pAdapter->hdd_stats.ClassA_stat.tx_rate * 500 * 1000;
2289 }
2290
2291 EXIT();
2292
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302293 return qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002294}
2295
2296/**
2297 * iw_get_bitrate() - SSR wrapper for __iw_get_bitrate()
2298 * @dev: pointer to net_device
2299 * @info: pointer to iw_request_info
2300 * @wrqu: pointer to iwreq_data
2301 * @extra: pointer to extra ioctl payload
2302 *
2303 * Return: 0 on success, error number otherwise
2304 */
2305static int iw_get_bitrate(struct net_device *dev,
2306 struct iw_request_info *info,
2307 union iwreq_data *wrqu, char *extra)
2308{
2309 int ret;
2310
2311 cds_ssr_protect(__func__);
2312 ret = __iw_get_bitrate(dev, info, wrqu, extra);
2313 cds_ssr_unprotect(__func__);
2314
2315 return ret;
2316}
2317
2318/**
2319 * __iw_set_bitrate() - SIOCSIWRATE ioctl handler
2320 * @dev: device upon which the ioctl was received
2321 * @info: ioctl request information
2322 * @wrqu: ioctl request data
2323 * @extra: ioctl extra data
2324 *
2325 * Return: 0 on success, non-zero on error
2326 */
2327static int __iw_set_bitrate(struct net_device *dev,
2328 struct iw_request_info *info,
2329 union iwreq_data *wrqu, char *extra)
2330{
2331 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
2332 hdd_wext_state_t *pWextState;
2333 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
2334 uint8_t supp_rates[WNI_CFG_SUPPORTED_RATES_11A_LEN];
2335 uint32_t a_len = WNI_CFG_SUPPORTED_RATES_11A_LEN;
2336 uint32_t b_len = WNI_CFG_SUPPORTED_RATES_11B_LEN;
2337 uint32_t i, rate;
2338 uint32_t valid_rate = false, active_phy_mode = 0;
2339 hdd_context_t *hdd_ctx;
2340 int ret;
2341
2342 ENTER();
2343
2344 hdd_ctx = WLAN_HDD_GET_CTX(pAdapter);
2345 ret = wlan_hdd_validate_context(hdd_ctx);
2346 if (0 != ret)
2347 return ret;
2348
2349 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
2350
2351 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState) {
2352 return -ENXIO;
2353 }
2354
2355 rate = wrqu->bitrate.value;
2356
2357 if (rate == -1) {
2358 rate = WNI_CFG_FIXED_RATE_AUTO;
2359 valid_rate = true;
2360 } else if (sme_cfg_get_int(WLAN_HDD_GET_HAL_CTX(pAdapter),
2361 WNI_CFG_DOT11_MODE,
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302362 &active_phy_mode) == QDF_STATUS_SUCCESS) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002363 if (active_phy_mode == WNI_CFG_DOT11_MODE_11A
2364 || active_phy_mode == WNI_CFG_DOT11_MODE_11G
2365 || active_phy_mode == WNI_CFG_DOT11_MODE_11B) {
2366 if ((sme_cfg_get_str(WLAN_HDD_GET_HAL_CTX(pAdapter),
2367 WNI_CFG_SUPPORTED_RATES_11A, supp_rates,
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302368 &a_len) == QDF_STATUS_SUCCESS)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002369 &&
2370 (sme_cfg_get_str(WLAN_HDD_GET_HAL_CTX(pAdapter),
2371 WNI_CFG_SUPPORTED_RATES_11B, supp_rates,
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302372 &b_len) == QDF_STATUS_SUCCESS)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002373 for (i = 0; i < (b_len + a_len); ++i) {
2374 /* supported rates returned is double
2375 * the actual rate so we divide it by 2
2376 */
2377 if ((supp_rates[i] & 0x7F) / 2 ==
2378 rate) {
2379 valid_rate = true;
2380 rate = i +
2381 WNI_CFG_FIXED_RATE_1MBPS;
2382 break;
2383 }
2384 }
2385 }
2386 }
2387 }
2388 if (valid_rate != true) {
2389 return -EINVAL;
2390 }
2391 if (sme_cfg_set_int(WLAN_HDD_GET_HAL_CTX(pAdapter),
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302392 WNI_CFG_FIXED_RATE, rate) != QDF_STATUS_SUCCESS) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002393 CDF_TRACE(CDF_MODULE_ID_HDD, CDF_TRACE_LEVEL_ERROR, FL
2394 ("failed to set ini parameter, WNI_CFG_FIXED_RATE"));
2395 return -EIO;
2396 }
2397 return 0;
2398}
2399
2400/**
2401 * iw_set_bitrate() - SSR wrapper for __iw_set_bitrate()
2402 * @dev: pointer to net_device
2403 * @info: pointer to iw_request_info
2404 * @wrqu: pointer to iwreq_data
2405 * @extra: pointer to extra ioctl payload
2406 *
2407 * Return: 0 on success, error number otherwise
2408 */
2409static int iw_set_bitrate(struct net_device *dev,
2410 struct iw_request_info *info,
2411 union iwreq_data *wrqu, char *extra)
2412{
2413 int ret;
2414
2415 cds_ssr_protect(__func__);
2416 ret = __iw_set_bitrate(dev, info, wrqu, extra);
2417 cds_ssr_unprotect(__func__);
2418
2419 return ret;
2420}
2421
2422/**
2423 * __iw_set_genie() - SIOCSIWGENIE ioctl handler
2424 * @dev: device upon which the ioctl was received
2425 * @info: ioctl request information
2426 * @wrqu: ioctl request data
2427 * @extra: ioctl extra data
2428 *
2429 * Return: 0 on success, non-zero on error
2430 */
2431static int __iw_set_genie(struct net_device *dev,
2432 struct iw_request_info *info,
2433 union iwreq_data *wrqu, char *extra)
2434{
2435 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
2436 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
2437 uint8_t *genie = NULL;
2438 uint8_t *base_genie = NULL;
2439 uint16_t remLen;
2440 hdd_context_t *hdd_ctx;
2441 int ret;
2442
2443 ENTER();
2444
2445 hdd_ctx = WLAN_HDD_GET_CTX(pAdapter);
2446 ret = wlan_hdd_validate_context(hdd_ctx);
2447 if (0 != ret)
2448 return ret;
2449
2450 if (!wrqu->data.length) {
2451 hdd_clear_roam_profile_ie(pAdapter);
2452 EXIT();
2453 return 0;
2454 }
2455
2456 base_genie = mem_alloc_copy_from_user_helper(wrqu->data.pointer,
2457 wrqu->data.length);
2458 if (NULL == base_genie) {
2459 CDF_TRACE(CDF_MODULE_ID_HDD, CDF_TRACE_LEVEL_ERROR,
2460 "mem_alloc_copy_from_user_helper fail");
2461 return -ENOMEM;
2462 }
2463
2464 genie = base_genie;
2465
2466 remLen = wrqu->data.length;
2467
2468 hddLog(LOG1, "iw_set_genie ioctl IE[0x%X], LEN[%d]", genie[0],
2469 genie[1]);
2470
2471 /* clear any previous genIE before this call */
2472 memset(&pWextState->genIE, 0, sizeof(pWextState->genIE));
2473
2474 while (remLen >= 2) {
2475 uint16_t eLen = 0;
2476 uint8_t elementId;
2477 elementId = *genie++;
2478 eLen = *genie++;
2479 remLen -= 2;
2480
2481 hddLog(CDF_TRACE_LEVEL_INFO, "%s: IE[0x%X], LEN[%d]",
2482 __func__, elementId, eLen);
2483
2484 switch (elementId) {
2485 case IE_EID_VENDOR:
2486 if ((IE_LEN_SIZE + IE_EID_SIZE + IE_VENDOR_OUI_SIZE) > eLen) { /* should have at least OUI */
2487 kfree(base_genie);
2488 return -EINVAL;
2489 }
2490
2491 if (0 == memcmp(&genie[0], "\x00\x50\xf2\x04", 4)) {
2492 uint16_t curGenIELen = pWextState->genIE.length;
2493 hddLog(CDF_TRACE_LEVEL_INFO,
2494 "%s Set WPS OUI(%02x %02x %02x %02x) IE(len %d)",
2495 __func__, genie[0], genie[1], genie[2],
2496 genie[3], eLen + 2);
2497
2498 if (SIR_MAC_MAX_IE_LENGTH <
2499 (pWextState->genIE.length + eLen)) {
2500 hddLog(CDF_TRACE_LEVEL_FATAL,
2501 "Cannot accommodate genIE. "
2502 "Need bigger buffer space");
2503 CDF_ASSERT(0);
2504 kfree(base_genie);
2505 return -ENOMEM;
2506 }
2507 /* save to Additional IE ; it should be accumulated to handle WPS IE + other IE */
2508 memcpy(pWextState->genIE.addIEdata +
2509 curGenIELen, genie - 2, eLen + 2);
2510 pWextState->genIE.length += eLen + 2;
2511 } else if (0 == memcmp(&genie[0], "\x00\x50\xf2", 3)) {
2512 hddLog(CDF_TRACE_LEVEL_INFO,
2513 "%s Set WPA IE (len %d)", __func__,
2514 eLen + 2);
2515 memset(pWextState->WPARSNIE, 0,
2516 MAX_WPA_RSN_IE_LEN);
2517 memcpy(pWextState->WPARSNIE, genie - 2,
2518 (eLen + 2));
2519 pWextState->roamProfile.pWPAReqIE =
2520 pWextState->WPARSNIE;
2521 pWextState->roamProfile.nWPAReqIELength =
2522 eLen + 2;
2523 } else { /* any vendorId except WPA IE should be accumulated to genIE */
2524
2525 uint16_t curGenIELen = pWextState->genIE.length;
2526 hddLog(CDF_TRACE_LEVEL_INFO,
2527 "%s Set OUI(%02x %02x %02x %02x) IE(len %d)",
2528 __func__, genie[0], genie[1], genie[2],
2529 genie[3], eLen + 2);
2530
2531 if (SIR_MAC_MAX_IE_LENGTH <
2532 (pWextState->genIE.length + eLen)) {
2533 hddLog(CDF_TRACE_LEVEL_FATAL,
2534 "Cannot accommodate genIE. "
2535 "Need bigger buffer space");
2536 CDF_ASSERT(0);
2537 kfree(base_genie);
2538 return -ENOMEM;
2539 }
2540 /* save to Additional IE ; it should be accumulated to handle WPS IE + other IE */
2541 memcpy(pWextState->genIE.addIEdata +
2542 curGenIELen, genie - 2, eLen + 2);
2543 pWextState->genIE.length += eLen + 2;
2544 }
2545 break;
2546 case DOT11F_EID_RSN:
2547 hddLog(LOG1, "%s Set RSN IE (len %d)", __func__,
2548 eLen + 2);
2549 memset(pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN);
2550 memcpy(pWextState->WPARSNIE, genie - 2, (eLen + 2));
2551 pWextState->roamProfile.pRSNReqIE =
2552 pWextState->WPARSNIE;
2553 pWextState->roamProfile.nRSNReqIELength = eLen + 2;
2554 break;
2555
2556 default:
2557 hddLog(LOGE, "%s Set UNKNOWN IE %X", __func__,
2558 elementId);
2559 kfree(base_genie);
2560 return 0;
2561 }
2562 genie += eLen;
2563 remLen -= eLen;
2564 }
2565 EXIT();
2566 kfree(base_genie);
2567 return 0;
2568}
2569
2570/**
2571 * iw_set_genie() - SSR wrapper for __iw_set_genie()
2572 * @dev: pointer to net_device
2573 * @info: pointer to iw_request_info
2574 * @wrqu: pointer to iwreq_data
2575 * @extra: pointer to extra ioctl payload
2576 *
2577 * Return: 0 on success, error number otherwise
2578 */
2579static int iw_set_genie(struct net_device *dev,
2580 struct iw_request_info *info,
2581 union iwreq_data *wrqu, char *extra)
2582{
2583 int ret;
2584
2585 cds_ssr_protect(__func__);
2586 ret = __iw_set_genie(dev, info, wrqu, extra);
2587 cds_ssr_unprotect(__func__);
2588
2589 return ret;
2590}
2591
2592/**
2593 * __iw_get_genie() - SIOCGIWGENIE ioctl handler
2594 * @dev: device upon which the ioctl was received
2595 * @info: ioctl request information
2596 * @wrqu: ioctl request data
2597 * @extra: ioctl extra data
2598 *
2599 * Return: 0 on success, non-zero on error
2600 */
2601static int __iw_get_genie(struct net_device *dev,
2602 struct iw_request_info *info,
2603 union iwreq_data *wrqu, char *extra)
2604{
2605 hdd_wext_state_t *pWextState;
2606 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
2607 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302608 QDF_STATUS status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002609 uint32_t length = DOT11F_IE_RSN_MAX_LEN;
2610 uint8_t genIeBytes[DOT11F_IE_RSN_MAX_LEN];
2611 hdd_context_t *hdd_ctx;
2612 int ret;
2613
2614 ENTER();
2615
2616 hdd_ctx = WLAN_HDD_GET_CTX(pAdapter);
2617 ret = wlan_hdd_validate_context(hdd_ctx);
2618 if (0 != ret)
2619 return ret;
2620
2621 hddLog(LOG1, "getGEN_IE ioctl");
2622
2623 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
2624
2625 if (pHddStaCtx->conn_info.connState == eConnectionState_NotConnected) {
2626 return -ENXIO;
2627 }
2628
2629 /* Return something ONLY if we are associated with an RSN or
2630 * WPA network
2631 */
2632 if (!hdd_is_auth_type_rsn(pWextState->roamProfile.negotiatedAuthType)) {
2633 return -ENXIO;
2634 }
2635
2636 /* Actually retrieve the RSN IE from CSR. (We previously sent
2637 * it down in the CSR Roam Profile.)
2638 */
2639 status = csr_roam_get_wpa_rsn_req_ie(WLAN_HDD_GET_HAL_CTX(pAdapter),
2640 pAdapter->sessionId,
2641 &length, genIeBytes);
2642 length = CDF_MIN((uint16_t) length, DOT11F_IE_RSN_MAX_LEN);
2643 if (wrqu->data.length < length) {
2644 hddLog(LOG1, "%s: failed to copy data to user buffer",
2645 __func__);
2646 return -EFAULT;
2647 }
2648 cdf_mem_copy(extra, (void *)genIeBytes, length);
2649 wrqu->data.length = length;
2650
2651 hddLog(LOG1, "%s: RSN IE of %d bytes returned", __func__,
2652 wrqu->data.length);
2653
2654 EXIT();
2655
2656 return 0;
2657}
2658
2659/**
2660 * iw_get_genie() - SSR wrapper for __iw_get_genie()
2661 * @dev: pointer to net_device
2662 * @info: pointer to iw_request_info
2663 * @wrqu: pointer to iwreq_data
2664 * @extra: pointer to extra ioctl payload
2665 *
2666 * Return: 0 on success, error number otherwise
2667 */
2668static int iw_get_genie(struct net_device *dev,
2669 struct iw_request_info *info,
2670 union iwreq_data *wrqu, char *extra)
2671{
2672 int ret;
2673
2674 cds_ssr_protect(__func__);
2675 ret = __iw_get_genie(dev, info, wrqu, extra);
2676 cds_ssr_unprotect(__func__);
2677
2678 return ret;
2679}
2680
2681/**
2682 * __iw_get_encode() - SIOCGIWENCODE ioctl handler
2683 * @dev: device upon which the ioctl was received
2684 * @info: ioctl request information
2685 * @wrqu: ioctl request data
2686 * @extra: ioctl extra data
2687 *
2688 * Return: 0 on success, non-zero on error
2689 */
2690static int __iw_get_encode(struct net_device *dev,
2691 struct iw_request_info *info,
2692 struct iw_point *dwrq, char *extra)
2693{
2694 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
2695 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
2696 tCsrRoamProfile *pRoamProfile = &(pWextState->roamProfile);
2697 int keyId;
2698 eCsrAuthType authType = eCSR_AUTH_TYPE_NONE;
2699 int i;
2700 hdd_context_t *hdd_ctx;
2701 int ret;
2702
2703 ENTER();
2704
2705 hdd_ctx = WLAN_HDD_GET_CTX(pAdapter);
2706 ret = wlan_hdd_validate_context(hdd_ctx);
2707 if (0 != ret)
2708 return ret;
2709
2710 keyId = pRoamProfile->Keys.defaultIndex;
2711
2712 if (keyId < 0 || keyId >= MAX_WEP_KEYS) {
2713 hddLog(LOG1, "%s: Invalid keyId : %d", __func__, keyId);
2714 return -EINVAL;
2715 }
2716
2717 if (pRoamProfile->Keys.KeyLength[keyId] > 0) {
2718 dwrq->flags |= IW_ENCODE_ENABLED;
2719 dwrq->length = pRoamProfile->Keys.KeyLength[keyId];
2720 cdf_mem_copy(extra, &(pRoamProfile->Keys.KeyMaterial[keyId][0]),
2721 pRoamProfile->Keys.KeyLength[keyId]);
2722
2723 dwrq->flags |= (keyId + 1);
2724
2725 } else {
2726 dwrq->flags |= IW_ENCODE_DISABLED;
2727 }
2728
2729 for (i = 0; i < MAX_WEP_KEYS; i++) {
2730 if (pRoamProfile->Keys.KeyMaterial[i] == NULL) {
2731 continue;
2732 } else {
2733 break;
2734 }
2735 }
2736
2737 if (MAX_WEP_KEYS == i) {
2738 dwrq->flags |= IW_ENCODE_NOKEY;
2739 }
2740
2741 authType =
2742 ((hdd_station_ctx_t *) WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->
2743 conn_info.authType;
2744
2745 if (eCSR_AUTH_TYPE_OPEN_SYSTEM == authType) {
2746 dwrq->flags |= IW_ENCODE_OPEN;
2747 } else {
2748 dwrq->flags |= IW_ENCODE_RESTRICTED;
2749 }
2750 EXIT();
2751 return 0;
2752}
2753
2754/**
2755 * iw_get_encode() - SSR wrapper for __iw_get_encode()
2756 * @dev: pointer to net_device
2757 * @info: pointer to iw_request_info
2758 * @dwrq: pointer to encoding information
2759 * @extra: pointer to extra ioctl payload
2760 *
2761 * Return: 0 on success, error number otherwise
2762 */
2763static int iw_get_encode(struct net_device *dev, struct iw_request_info *info,
2764 struct iw_point *dwrq, char *extra)
2765{
2766 int ret;
2767
2768 cds_ssr_protect(__func__);
2769 ret = __iw_get_encode(dev, info, dwrq, extra);
2770 cds_ssr_unprotect(__func__);
2771
2772 return ret;
2773}
2774
2775/**
2776 * __iw_get_rts_threshold() - SIOCGIWRTS ioctl handler
2777 * @dev: device upon which the ioctl was received
2778 * @info: ioctl request information
2779 * @wrqu: ioctl request data
2780 * @extra: ioctl extra data
2781 *
2782 * Return: 0 on success, non-zero on error
2783 */
2784static int __iw_get_rts_threshold(struct net_device *dev,
2785 struct iw_request_info *info,
2786 union iwreq_data *wrqu, char *extra)
2787{
2788 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
2789 uint32_t status = 0;
2790
2791 status = hdd_wlan_get_rts_threshold(pAdapter, wrqu);
2792
2793 return status;
2794}
2795
2796/**
2797 * __iw_set_rts_threshold() - SIOCSIWRTS ioctl handler
2798 * @dev: device upon which the ioctl was received
2799 * @info: ioctl request information
2800 * @wrqu: ioctl request data
2801 * @extra: ioctl extra data
2802 *
2803 * Return: 0 on success, non-zero on error
2804 */
2805static int __iw_set_rts_threshold(struct net_device *dev,
2806 struct iw_request_info *info,
2807 union iwreq_data *wrqu, char *extra)
2808{
2809 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
2810 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
2811 hdd_context_t *hdd_ctx;
2812 int ret;
2813
2814 ENTER();
2815
2816 hdd_ctx = WLAN_HDD_GET_CTX(pAdapter);
2817 ret = wlan_hdd_validate_context(hdd_ctx);
2818 if (0 != ret)
2819 return ret;
2820
2821 if (wrqu->rts.value < WNI_CFG_RTS_THRESHOLD_STAMIN
2822 || wrqu->rts.value > WNI_CFG_RTS_THRESHOLD_STAMAX) {
2823 return -EINVAL;
2824 }
2825
2826 if (sme_cfg_set_int(hHal, WNI_CFG_RTS_THRESHOLD, wrqu->rts.value) !=
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302827 QDF_STATUS_SUCCESS) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002828 CDF_TRACE(CDF_MODULE_ID_HDD, CDF_TRACE_LEVEL_ERROR, FL
2829 ("failed to set ini parameter, WNI_CFG_RTS_THRESHOLD"));
2830 return -EIO;
2831 }
2832
2833 EXIT();
2834
2835 return 0;
2836}
2837
2838/**
2839 * iw_get_rts_threshold() - SSR wrapper for __iw_get_rts_threshold()
2840 * @dev: pointer to net_device
2841 * @info: pointer to iw_request_info
2842 * @wrqu: pointer to iwreq_data
2843 * @extra: pointer to extra ioctl payload
2844 *
2845 * Return: 0 on success, error number otherwise
2846 */
2847static int iw_get_rts_threshold(struct net_device *dev,
2848 struct iw_request_info *info,
2849 union iwreq_data *wrqu, char *extra)
2850{
2851 int ret;
2852
2853 cds_ssr_protect(__func__);
2854 ret = __iw_get_rts_threshold(dev, info, wrqu, extra);
2855 cds_ssr_unprotect(__func__);
2856
2857 return ret;
2858}
2859
2860/**
2861 * iw_set_rts_threshold() - SSR wrapper for __iw_set_rts_threshold()
2862 * @dev: pointer to net_device
2863 * @info: pointer to iw_request_info
2864 * @wrqu: pointer to iwreq_data
2865 * @extra: pointer to extra ioctl payload
2866 *
2867 * Return: 0 on success, error number otherwise
2868 */
2869static int iw_set_rts_threshold(struct net_device *dev,
2870 struct iw_request_info *info,
2871 union iwreq_data *wrqu, char *extra)
2872{
2873 int ret;
2874
2875 cds_ssr_protect(__func__);
2876 ret = __iw_set_rts_threshold(dev, info, wrqu, extra);
2877 cds_ssr_unprotect(__func__);
2878
2879 return ret;
2880}
2881
2882/**
2883 * __iw_get_frag_threshold() - SIOCGIWFRAG ioctl handler
2884 * @dev: device upon which the ioctl was received
2885 * @info: ioctl request information
2886 * @wrqu: ioctl request data
2887 * @extra: ioctl extra data
2888 *
2889 * Return: 0 on success, non-zero on error
2890 */
2891static int __iw_get_frag_threshold(struct net_device *dev,
2892 struct iw_request_info *info,
2893 union iwreq_data *wrqu, char *extra)
2894{
2895 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
2896 uint32_t status = 0;
2897
2898 status = hdd_wlan_get_frag_threshold(pAdapter, wrqu);
2899
2900 return status;
2901}
2902
2903/**
2904 * iw_get_frag_threshold() - SSR wrapper for __iw_get_frag_threshold()
2905 * @dev: pointer to net_device
2906 * @info: pointer to iw_request_info
2907 * @wrqu: pointer to iwreq_data
2908 * @extra: pointer to extra ioctl payload
2909 *
2910 * Return: 0 on success, error number otherwise
2911 */
2912static int iw_get_frag_threshold(struct net_device *dev,
2913 struct iw_request_info *info,
2914 union iwreq_data *wrqu, char *extra)
2915{
2916 int ret;
2917
2918 cds_ssr_protect(__func__);
2919 ret = __iw_get_frag_threshold(dev, info, wrqu, extra);
2920 cds_ssr_unprotect(__func__);
2921
2922 return ret;
2923}
2924
2925/**
2926 * __iw_set_frag_threshold() - SIOCSIWFRAG ioctl handler
2927 * @dev: device upon which the ioctl was received
2928 * @info: ioctl request information
2929 * @wrqu: ioctl request data
2930 * @extra: ioctl extra data
2931 *
2932 * Return: 0 on success, non-zero on error
2933 */
2934static int __iw_set_frag_threshold(struct net_device *dev,
2935 struct iw_request_info *info,
2936 union iwreq_data *wrqu, char *extra)
2937{
2938 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
2939 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
2940 hdd_context_t *hdd_ctx;
2941 int ret;
2942
2943 ENTER();
2944
2945 hdd_ctx = WLAN_HDD_GET_CTX(pAdapter);
2946 ret = wlan_hdd_validate_context(hdd_ctx);
2947 if (0 != ret)
2948 return ret;
2949
2950 if (wrqu->frag.value < WNI_CFG_FRAGMENTATION_THRESHOLD_STAMIN
2951 || wrqu->frag.value > WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX) {
2952 return -EINVAL;
2953 }
2954
2955 if (sme_cfg_set_int
2956 (hHal, WNI_CFG_FRAGMENTATION_THRESHOLD, wrqu->frag.value)
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302957 != QDF_STATUS_SUCCESS) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002958 CDF_TRACE(CDF_MODULE_ID_HDD, CDF_TRACE_LEVEL_ERROR, FL
2959 ("failed to set ini parameter, WNI_CFG_FRAGMENTATION_THRESHOLD"));
2960 return -EIO;
2961 }
2962
2963 EXIT();
2964
2965 return 0;
2966}
2967
2968/**
2969 * iw_set_frag_threshold() - SSR wrapper for __iw_set_frag_threshold()
2970 * @dev: pointer to net_device
2971 * @info: pointer to iw_request_info
2972 * @wrqu: pointer to iwreq_data
2973 * @extra: pointer to extra ioctl payload
2974 *
2975 * Return: 0 on success, error number otherwise
2976 */
2977static int iw_set_frag_threshold(struct net_device *dev,
2978 struct iw_request_info *info,
2979 union iwreq_data *wrqu, char *extra)
2980{
2981 int ret;
2982
2983 cds_ssr_protect(__func__);
2984 ret = __iw_set_frag_threshold(dev, info, wrqu, extra);
2985 cds_ssr_unprotect(__func__);
2986
2987 return ret;
2988}
2989
2990/**
2991 * __iw_get_power_mode() - SIOCGIWPOWER ioctl handler
2992 * @dev: device upon which the ioctl was received
2993 * @info: ioctl request information
2994 * @wrqu: ioctl request data
2995 * @extra: ioctl extra data
2996 *
2997 * Return: 0 on success, non-zero on error
2998 */
2999static int __iw_get_power_mode(struct net_device *dev,
3000 struct iw_request_info *info,
3001 union iwreq_data *wrqu, char *extra)
3002{
3003 hdd_adapter_t *adapter;
3004 hdd_context_t *hdd_ctx;
3005 int ret;
3006
3007 ENTER();
3008
3009 adapter = WLAN_HDD_GET_PRIV_PTR(dev);
3010 hdd_ctx = WLAN_HDD_GET_CTX(adapter);
3011 ret = wlan_hdd_validate_context(hdd_ctx);
3012 if (0 != ret)
3013 return ret;
3014
3015 return -EOPNOTSUPP;
3016}
3017
3018/**
3019 * iw_get_power_mode() - SSR wrapper function for __iw_get_power_mode
3020 * @dev: pointer to net_device
3021 * @info: pointer to iw_request_info
3022 * @wrqu: pointer to iwreq_data
3023 * @extra: extra
3024 *
3025 * Return: 0 on success, error number otherwise
3026 */
3027int iw_get_power_mode(struct net_device *dev,
3028 struct iw_request_info *info,
3029 union iwreq_data *wrqu, char *extra)
3030{
3031 int ret;
3032
3033 cds_ssr_protect(__func__);
3034 ret = __iw_get_power_mode(dev, info, wrqu, extra);
3035 cds_ssr_unprotect(__func__);
3036
3037 return ret;
3038}
3039
3040/**
3041 * __iw_set_power_mode() - SIOCSIWPOWER ioctl handler
3042 * @dev: device upon which the ioctl was received
3043 * @info: ioctl request information
3044 * @wrqu: ioctl request data
3045 * @extra: ioctl extra data
3046 *
3047 * Return: 0 on success, non-zero on error
3048 */
3049static int __iw_set_power_mode(struct net_device *dev,
3050 struct iw_request_info *info,
3051 union iwreq_data *wrqu, char *extra)
3052{
3053 hdd_adapter_t *adapter;
3054 hdd_context_t *hdd_ctx;
3055 int ret;
3056
3057 ENTER();
3058
3059 adapter = WLAN_HDD_GET_PRIV_PTR(dev);
3060 hdd_ctx = WLAN_HDD_GET_CTX(adapter);
3061 ret = wlan_hdd_validate_context(hdd_ctx);
3062 if (0 != ret)
3063 return ret;
3064
3065 return -EOPNOTSUPP;
3066}
3067
3068/**
3069 * iw_set_power_mode() - SSR wrapper function for __iw_set_power_mode
3070 * @dev: pointer to net_device
3071 * @info: pointer to iw_request_info
3072 * @wrqu: pointer to iwreq_data
3073 * @extra: extra
3074 *
3075 * Return: 0 on success, error number otherwise
3076 */
3077int iw_set_power_mode(struct net_device *dev,
3078 struct iw_request_info *info,
3079 union iwreq_data *wrqu, char *extra)
3080{
3081 int ret;
3082
3083 cds_ssr_protect(__func__);
3084 ret = __iw_set_power_mode(dev, info, wrqu, extra);
3085 cds_ssr_unprotect(__func__);
3086
3087 return ret;
3088}
3089
3090/**
3091 * __iw_get_range() - SIOCGIWRANGE ioctl handler
3092 * @dev: device upon which the ioctl was received
3093 * @info: ioctl request information
3094 * @wrqu: ioctl request data
3095 * @extra: ioctl extra data
3096 *
3097 * Return: 0 on success, non-zero on error
3098 */
3099static int __iw_get_range(struct net_device *dev, struct iw_request_info *info,
3100 union iwreq_data *wrqu, char *extra)
3101{
3102 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3103 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
3104 struct iw_range *range = (struct iw_range *)extra;
3105
3106 uint8_t channels[WNI_CFG_VALID_CHANNEL_LIST_LEN];
3107
3108 uint32_t num_channels = sizeof(channels);
3109 uint8_t supp_rates[WNI_CFG_SUPPORTED_RATES_11A_LEN];
3110 uint32_t a_len;
3111 uint32_t b_len;
3112 uint32_t active_phy_mode = 0;
3113 uint8_t index = 0, i;
3114 hdd_context_t *hdd_ctx;
3115 int ret;
3116
3117 ENTER();
3118
3119 hdd_ctx = WLAN_HDD_GET_CTX(pAdapter);
3120 ret = wlan_hdd_validate_context(hdd_ctx);
3121 if (0 != ret)
3122 return ret;
3123
3124 wrqu->data.length = sizeof(struct iw_range);
3125 memset(range, 0, sizeof(struct iw_range));
3126
3127
3128 /*Get the phy mode */
3129 if (sme_cfg_get_int(hHal,
3130 WNI_CFG_DOT11_MODE,
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303131 &active_phy_mode) == QDF_STATUS_SUCCESS) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003132 CDF_TRACE(CDF_MODULE_ID_HDD, CDF_TRACE_LEVEL_INFO,
3133 "active_phy_mode = %d", active_phy_mode);
3134
3135 if (active_phy_mode == WNI_CFG_DOT11_MODE_11A
3136 || active_phy_mode == WNI_CFG_DOT11_MODE_11G) {
3137 /*Get the supported rates for 11G band */
3138 a_len = WNI_CFG_SUPPORTED_RATES_11A_LEN;
3139 if (sme_cfg_get_str(hHal,
3140 WNI_CFG_SUPPORTED_RATES_11A,
3141 supp_rates,
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303142 &a_len) == QDF_STATUS_SUCCESS) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003143 if (a_len > WNI_CFG_SUPPORTED_RATES_11A_LEN) {
3144 a_len = WNI_CFG_SUPPORTED_RATES_11A_LEN;
3145 }
3146 for (i = 0; i < a_len; i++) {
3147 range->bitrate[i] =
3148 ((supp_rates[i] & 0x7F) / 2) *
3149 1000000;
3150 }
3151 range->num_bitrates = a_len;
3152 } else {
3153 return -EIO;
3154 }
3155 } else if (active_phy_mode == WNI_CFG_DOT11_MODE_11B) {
3156 /*Get the supported rates for 11B band */
3157 b_len = WNI_CFG_SUPPORTED_RATES_11B_LEN;
3158 if (sme_cfg_get_str(hHal,
3159 WNI_CFG_SUPPORTED_RATES_11B,
3160 supp_rates,
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303161 &b_len) == QDF_STATUS_SUCCESS) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003162 if (b_len > WNI_CFG_SUPPORTED_RATES_11B_LEN) {
3163 b_len = WNI_CFG_SUPPORTED_RATES_11B_LEN;
3164 }
3165 for (i = 0; i < b_len; i++) {
3166 range->bitrate[i] =
3167 ((supp_rates[i] & 0x7F) / 2) *
3168 1000000;
3169 }
3170 range->num_bitrates = b_len;
3171 } else {
3172 return -EIO;
3173 }
3174 }
3175 }
3176
3177 range->max_rts = WNI_CFG_RTS_THRESHOLD_STAMAX;
3178 range->min_frag = WNI_CFG_FRAGMENTATION_THRESHOLD_STAMIN;
3179 range->max_frag = WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX;
3180
3181 range->encoding_size[0] = 5;
3182 range->encoding_size[1] = 13;
3183 range->num_encoding_sizes = 2;
3184 range->max_encoding_tokens = MAX_WEP_KEYS;
3185
3186 /* we support through Wireless Extensions 22 */
3187 range->we_version_compiled = WIRELESS_EXT;
3188 range->we_version_source = 22;
3189
3190 /*Supported Channels and Frequencies */
3191 if (sme_cfg_get_str
3192 ((hHal), WNI_CFG_VALID_CHANNEL_LIST, channels,
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303193 &num_channels) != QDF_STATUS_SUCCESS) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003194 CDF_TRACE(CDF_MODULE_ID_HDD, CDF_TRACE_LEVEL_WARN,
3195 FL
3196 ("failed to get ini parameter, WNI_CFG_VALID_CHANNEL_LIST"));
3197 return -EIO;
3198 }
3199 if (num_channels > IW_MAX_FREQUENCIES) {
3200 num_channels = IW_MAX_FREQUENCIES;
3201 }
3202
3203 range->num_channels = num_channels;
3204 range->num_frequency = num_channels;
3205
3206 for (index = 0; index < num_channels; index++) {
3207 uint32_t frq_indx = 0;
3208
3209 range->freq[index].i = channels[index];
3210 while (frq_indx < FREQ_CHAN_MAP_TABLE_SIZE) {
3211 if (channels[index] == freq_chan_map[frq_indx].chan) {
3212 range->freq[index].m =
3213 freq_chan_map[frq_indx].freq * 100000;
3214 range->freq[index].e = 1;
3215 break;
3216 }
3217 frq_indx++;
3218 }
3219 }
3220
3221 /* Event capability (kernel + driver) */
3222 range->event_capa[0] = (IW_EVENT_CAPA_K_0 |
3223 IW_EVENT_CAPA_MASK(SIOCGIWAP) |
3224 IW_EVENT_CAPA_MASK(SIOCGIWSCAN));
3225 range->event_capa[1] = IW_EVENT_CAPA_K_1;
3226
3227 /*Encryption capability */
3228 range->enc_capa = IW_ENC_CAPA_WPA | IW_ENC_CAPA_WPA2 |
3229 IW_ENC_CAPA_CIPHER_TKIP | IW_ENC_CAPA_CIPHER_CCMP;
3230
3231 /* Txpower capability */
3232 range->txpower_capa = IW_TXPOW_MWATT;
3233
3234 /*Scanning capability */
3235#if WIRELESS_EXT >= 22
3236 range->scan_capa =
3237 IW_SCAN_CAPA_ESSID | IW_SCAN_CAPA_TYPE | IW_SCAN_CAPA_CHANNEL;
3238#endif
3239
3240 EXIT();
3241 return 0;
3242}
3243
3244/**
3245 * iw_get_range() - SSR wrapper for __iw_get_range()
3246 * @dev: pointer to net_device
3247 * @info: pointer to iw_request_info
3248 * @wrqu: pointer to iwreq_data
3249 * @extra: pointer to extra ioctl payload
3250 *
3251 * Return: 0 on success, error number otherwise
3252 */
3253static int iw_get_range(struct net_device *dev, struct iw_request_info *info,
3254 union iwreq_data *wrqu, char *extra)
3255{
3256 int ret;
3257
3258 cds_ssr_protect(__func__);
3259 ret = __iw_get_range(dev, info, wrqu, extra);
3260 cds_ssr_unprotect(__func__);
3261
3262 return ret;
3263}
3264
3265/**
3266 * hdd_get_class_a_statistics_cb() - Get Class A stats callback function
3267 * @pStats: pointer to Class A stats
3268 * @pContext: user context originally registered with SME
3269 *
3270 * Return: None
3271 */
3272static void hdd_get_class_a_statistics_cb(void *pStats, void *pContext)
3273{
3274 struct statsContext *pStatsContext;
3275 tCsrGlobalClassAStatsInfo *pClassAStats;
3276 hdd_adapter_t *pAdapter;
3277
3278 if (ioctl_debug) {
3279 pr_info("%s: pStats [%p] pContext [%p]\n",
3280 __func__, pStats, pContext);
3281 }
3282
3283 if ((NULL == pStats) || (NULL == pContext)) {
3284 hddLog(CDF_TRACE_LEVEL_ERROR,
3285 "%s: Bad param, pStats [%p] pContext [%p]",
3286 __func__, pStats, pContext);
3287 return;
3288 }
3289
3290 pClassAStats = pStats;
3291 pStatsContext = pContext;
3292 pAdapter = pStatsContext->pAdapter;
3293
3294 /* there is a race condition that exists between this callback
3295 * function and the caller since the caller could time out
3296 * either before or while this code is executing. we use a
3297 * spinlock to serialize these actions
3298 */
3299 spin_lock(&hdd_context_lock);
3300
3301 if ((NULL == pAdapter) ||
3302 (STATS_CONTEXT_MAGIC != pStatsContext->magic)) {
3303 /* the caller presumably timed out so there is nothing
3304 * we can do
3305 */
3306 spin_unlock(&hdd_context_lock);
3307 hddLog(CDF_TRACE_LEVEL_WARN,
3308 "%s: Invalid context, pAdapter [%p] magic [%08x]",
3309 __func__, pAdapter, pStatsContext->magic);
3310 if (ioctl_debug) {
3311 pr_info("%s: Invalid context, pAdapter [%p] magic [%08x]\n",
3312 __func__, pAdapter, pStatsContext->magic);
3313 }
3314 return;
3315 }
3316
3317 /* context is valid so caller is still waiting */
3318
3319 /* paranoia: invalidate the magic */
3320 pStatsContext->magic = 0;
3321
3322 /* copy over the stats. do so as a struct copy */
3323 pAdapter->hdd_stats.ClassA_stat = *pClassAStats;
3324
3325 /* notify the caller */
3326 complete(&pStatsContext->completion);
3327
3328 /* serialization is complete */
3329 spin_unlock(&hdd_context_lock);
3330}
3331
3332/**
3333 * wlan_hdd_get_class_astats() - Get Class A statistics
3334 * @pAdapter: adapter for which statistics are desired
3335 *
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303336 * Return: QDF_STATUS_SUCCESS if adapter's Class A statistics were updated
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003337 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303338QDF_STATUS wlan_hdd_get_class_astats(hdd_adapter_t *pAdapter)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003339{
3340 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303341 QDF_STATUS hstatus;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003342 unsigned long rc;
3343 struct statsContext context;
3344
3345 if (NULL == pAdapter) {
3346 hddLog(CDF_TRACE_LEVEL_ERROR, "%s: pAdapter is NULL", __func__);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303347 return QDF_STATUS_E_FAULT;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003348 }
Prashanth Bhatta9e143052015-12-04 11:56:47 -08003349 if (cds_is_driver_recovering()) {
3350 hdd_err("Recovery in Progress. State: 0x%x Ignore!!!",
3351 cds_get_driver_state());
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303352 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003353 }
3354
3355 /* we are connected so prepare our callback context */
3356 init_completion(&context.completion);
3357 context.pAdapter = pAdapter;
3358 context.magic = STATS_CONTEXT_MAGIC;
3359 /* query only for Class A statistics (which include link speed) */
3360 hstatus = sme_get_statistics(WLAN_HDD_GET_HAL_CTX(pAdapter),
3361 eCSR_HDD, SME_GLOBAL_CLASSA_STATS,
3362 hdd_get_class_a_statistics_cb,
3363 0, /* not periodic */
3364 false, /* non-cached results */
3365 pHddStaCtx->conn_info.staId[0],
3366 &context, pAdapter->sessionId);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303367 if (QDF_STATUS_SUCCESS != hstatus) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003368 hddLog(CDF_TRACE_LEVEL_ERROR,
3369 "%s: Unable to retrieve Class A statistics", __func__);
3370 /* we'll returned a cached value below */
3371 } else {
3372 /* request was sent -- wait for the response */
3373 rc = wait_for_completion_timeout
3374 (&context.completion,
3375 msecs_to_jiffies(WLAN_WAIT_TIME_STATS));
3376 if (!rc) {
3377 hddLog(CDF_TRACE_LEVEL_ERROR,
3378 FL("SME timed out while retrieving Class A statistics"));
3379 }
3380 }
3381
3382 /* either we never sent a request, we sent a request and
3383 * received a response or we sent a request and timed out. if
3384 * we never sent a request or if we sent a request and got a
3385 * response, we want to clear the magic out of paranoia. if
3386 * we timed out there is a race condition such that the
3387 * callback function could be executing at the same time we
3388 * are. of primary concern is if the callback function had
3389 * already verified the "magic" but had not yet set the
3390 * completion variable when a timeout occurred. we serialize
3391 * these activities by invalidating the magic while holding a
3392 * shared spinlock which will cause us to block if the
3393 * callback is currently executing
3394 */
3395 spin_lock(&hdd_context_lock);
3396 context.magic = 0;
3397 spin_unlock(&hdd_context_lock);
3398
3399 /* either callback updated pAdapter stats or it has cached data */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303400 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003401}
3402
3403/**
3404 * hdd_get_station_statistics_cb() - Get stats callback function
3405 * @pStats: pointer to Class A stats
3406 * @pContext: user context originally registered with SME
3407 *
3408 * Return: None
3409 */
3410static void hdd_get_station_statistics_cb(void *pStats, void *pContext)
3411{
3412 struct statsContext *pStatsContext;
3413 tCsrSummaryStatsInfo *pSummaryStats;
3414 tCsrGlobalClassAStatsInfo *pClassAStats;
3415 hdd_adapter_t *pAdapter;
3416
3417 if (ioctl_debug) {
3418 pr_info("%s: pStats [%p] pContext [%p]\n",
3419 __func__, pStats, pContext);
3420 }
3421
3422 if ((NULL == pStats) || (NULL == pContext)) {
3423 hddLog(CDF_TRACE_LEVEL_ERROR,
3424 "%s: Bad param, pStats [%p] pContext [%p]",
3425 __func__, pStats, pContext);
3426 return;
3427 }
3428
3429 /* there is a race condition that exists between this callback
3430 * function and the caller since the caller could time out
3431 * either before or while this code is executing. we use a
3432 * spinlock to serialize these actions
3433 */
3434 spin_lock(&hdd_context_lock);
3435
3436 pSummaryStats = (tCsrSummaryStatsInfo *) pStats;
3437 pClassAStats = (tCsrGlobalClassAStatsInfo *) (pSummaryStats + 1);
3438 pStatsContext = pContext;
3439 pAdapter = pStatsContext->pAdapter;
3440 if ((NULL == pAdapter) ||
3441 (STATS_CONTEXT_MAGIC != pStatsContext->magic)) {
3442 /* the caller presumably timed out so there is nothing
3443 * we can do
3444 */
3445 spin_unlock(&hdd_context_lock);
3446 hddLog(CDF_TRACE_LEVEL_WARN,
3447 "%s: Invalid context, pAdapter [%p] magic [%08x]",
3448 __func__, pAdapter, pStatsContext->magic);
3449 if (ioctl_debug) {
3450 pr_info("%s: Invalid context, pAdapter [%p] magic [%08x]\n",
3451 __func__, pAdapter, pStatsContext->magic);
3452 }
3453 return;
3454 }
3455
3456 /* context is valid so caller is still waiting */
3457
3458 /* paranoia: invalidate the magic */
3459 pStatsContext->magic = 0;
3460
3461 /* copy over the stats. do so as a struct copy */
3462 pAdapter->hdd_stats.summary_stat = *pSummaryStats;
3463 pAdapter->hdd_stats.ClassA_stat = *pClassAStats;
3464
3465 /* notify the caller */
3466 complete(&pStatsContext->completion);
3467
3468 /* serialization is complete */
3469 spin_unlock(&hdd_context_lock);
3470}
3471
3472/**
3473 * wlan_hdd_get_station_stats() - Get station statistics
3474 * @pAdapter: adapter for which statistics are desired
3475 *
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303476 * Return: QDF_STATUS_SUCCESS if adapter's statistics were updated
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003477 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303478QDF_STATUS wlan_hdd_get_station_stats(hdd_adapter_t *pAdapter)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003479{
3480 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303481 QDF_STATUS hstatus;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003482 unsigned long rc;
3483 struct statsContext context;
3484
3485 if (NULL == pAdapter) {
3486 hddLog(CDF_TRACE_LEVEL_ERROR, "%s: pAdapter is NULL", __func__);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303487 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003488 }
3489
3490 /* we are connected so prepare our callback context */
3491 init_completion(&context.completion);
3492 context.pAdapter = pAdapter;
3493 context.magic = STATS_CONTEXT_MAGIC;
3494
3495 /* query only for Summary & Class A statistics */
3496 hstatus = sme_get_statistics(WLAN_HDD_GET_HAL_CTX(pAdapter),
3497 eCSR_HDD,
3498 SME_SUMMARY_STATS |
3499 SME_GLOBAL_CLASSA_STATS,
3500 hdd_get_station_statistics_cb,
3501 0, /* not periodic */
3502 false, /* non-cached results */
3503 pHddStaCtx->conn_info.staId[0],
3504 &context, pAdapter->sessionId);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303505 if (QDF_STATUS_SUCCESS != hstatus) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003506 hddLog(CDF_TRACE_LEVEL_ERROR,
3507 "%s: Unable to retrieve statistics", __func__);
3508 /* we'll return with cached values */
3509 } else {
3510 /* request was sent -- wait for the response */
3511 rc = wait_for_completion_timeout
3512 (&context.completion,
3513 msecs_to_jiffies(WLAN_WAIT_TIME_STATS));
3514
3515 if (!rc) {
3516 hddLog(CDF_TRACE_LEVEL_ERROR,
3517 FL("SME timed out while retrieving statistics"));
3518 }
3519 }
3520
3521 /* either we never sent a request, we sent a request and
3522 * received a response or we sent a request and timed out. if
3523 * we never sent a request or if we sent a request and got a
3524 * response, we want to clear the magic out of paranoia. if
3525 * we timed out there is a race condition such that the
3526 * callback function could be executing at the same time we
3527 * are. of primary concern is if the callback function had
3528 * already verified the "magic" but had not yet set the
3529 * completion variable when a timeout occurred. we serialize
3530 * these activities by invalidating the magic while holding a
3531 * shared spinlock which will cause us to block if the
3532 * callback is currently executing
3533 */
3534 spin_lock(&hdd_context_lock);
3535 context.magic = 0;
3536 spin_unlock(&hdd_context_lock);
3537
3538 /* either callback updated pAdapter stats or it has cached data */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303539 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003540}
3541
3542/**
3543 * iw_get_linkspeed() - Get current link speed ioctl
3544 * @dev: device upon which the ioctl was received
3545 * @info: ioctl request information
3546 * @wrqu: ioctl request data
3547 * @extra: extra ioctl buffer
3548 *
3549 * Return: 0 on success, non-zero on error
3550 */
3551static int __iw_get_linkspeed(struct net_device *dev,
3552 struct iw_request_info *info,
3553 union iwreq_data *wrqu, char *extra)
3554{
3555 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3556 char *pLinkSpeed = (char *)extra;
3557 int len = sizeof(uint32_t) + 1;
3558 uint32_t link_speed = 0;
3559 hdd_context_t *hdd_ctx;
3560 int rc, valid;
3561
Hanumantha Reddy Pothula2db50ed2015-11-23 10:48:33 +05303562 ENTER();
3563
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003564 hdd_ctx = WLAN_HDD_GET_CTX(pAdapter);
3565 valid = wlan_hdd_validate_context(hdd_ctx);
3566 if (0 != valid)
3567 return valid;
3568
3569 rc = wlan_hdd_get_link_speed(pAdapter, &link_speed);
3570 if (0 != rc) {
3571 return rc;
3572 }
3573
3574 wrqu->data.length = len;
3575 /* return the linkspeed as a string */
3576 rc = snprintf(pLinkSpeed, len, "%u", link_speed);
3577 if ((rc < 0) || (rc >= len)) {
3578 /* encoding or length error? */
3579 hddLog(CDF_TRACE_LEVEL_ERROR,
3580 FL("Unable to encode link speed"));
3581 return -EIO;
3582 }
3583
Hanumantha Reddy Pothula2db50ed2015-11-23 10:48:33 +05303584 EXIT();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003585 /* a value is being successfully returned */
3586 return 0;
3587}
3588
3589static int iw_get_linkspeed(struct net_device *dev,
3590 struct iw_request_info *info,
3591 union iwreq_data *wrqu, char *extra)
3592{
3593 int ret;
3594
3595 cds_ssr_protect(__func__);
3596 ret = __iw_get_linkspeed(dev, info, wrqu, extra);
3597 cds_ssr_unprotect(__func__);
3598
3599 return ret;
3600}
3601
3602/**
3603 * wlan_hdd_change_country_code_callback() - Change country code callback
3604 * @context: opaque context originally passed to SME. All functions
3605 * which use this callback pass the adapter upon which the country
3606 * code change is active
3607 *
3608 * This function is registered as the callback function when
3609 * sme_change_country_code() is invoked. Callers of
3610 * sme_change_country_code() subsequently wait for the adapter's
3611 * @change_country_code completion variable, so all this function
3612 * needs to do is set that completion variable so that execution can
3613 * continue.
3614 *
3615 * Return: none
3616 */
3617void wlan_hdd_change_country_code_callback(void *context)
3618{
3619
3620 hdd_adapter_t *adapter = context;
3621
3622 if (adapter && (WLAN_HDD_ADAPTER_MAGIC == adapter->magic))
3623 complete(&adapter->change_country_code);
3624
3625 return;
3626}
3627
3628/**
3629 * __iw_set_nick() - SIOCSIWNICKN ioctl handler
3630 * @dev: device upon which the ioctl was received
3631 * @info: ioctl request information
3632 * @wrqu: ioctl request data
3633 * @extra: ioctl extra data
3634 *
3635 * Return: 0 on success, non-zero on error
3636 */
3637static int __iw_set_nick(struct net_device *dev,
3638 struct iw_request_info *info,
3639 union iwreq_data *wrqu, char *extra)
3640{
3641 hdd_adapter_t *adapter;
3642 hdd_context_t *hdd_ctx;
3643 int ret;
3644
3645 ENTER();
3646
3647 adapter = WLAN_HDD_GET_PRIV_PTR(dev);
3648 hdd_ctx = WLAN_HDD_GET_CTX(adapter);
3649 ret = wlan_hdd_validate_context(hdd_ctx);
3650 if (0 != ret)
3651 return ret;
3652
3653 return 0;
3654}
3655
3656/**
3657 * iw_set_nick() - SSR wrapper for __iw_set_nick
3658 * @dev: pointer to net_device
3659 * @info: pointer to iw_request_info
3660 * @wrqu: pointer to iwreq_data
3661 * @extra: extra
3662 *
3663 * Return: 0 on success, error number otherwise
3664 */
3665static int iw_set_nick(struct net_device *dev,
3666 struct iw_request_info *info,
3667 union iwreq_data *wrqu, char *extra)
3668{
3669 int ret;
3670
3671 cds_ssr_protect(__func__);
3672 ret = __iw_set_nick(dev, info, wrqu, extra);
3673 cds_ssr_unprotect(__func__);
3674
3675 return ret;
3676}
3677
3678/**
3679 * __iw_get_nick() - SIOCGIWNICKN ioctl handler
3680 * @dev: device upon which the ioctl was received
3681 * @info: ioctl request information
3682 * @wrqu: ioctl request data
3683 * @extra: ioctl extra data
3684 *
3685 * Return: 0 on success, non-zero on error
3686 */
3687static int __iw_get_nick(struct net_device *dev,
3688 struct iw_request_info *info,
3689 union iwreq_data *wrqu, char *extra)
3690{
3691 hdd_adapter_t *adapter;
3692 hdd_context_t *hdd_ctx;
3693 int ret;
3694
3695 ENTER();
3696
3697 adapter = WLAN_HDD_GET_PRIV_PTR(dev);
3698 hdd_ctx = WLAN_HDD_GET_CTX(adapter);
3699 ret = wlan_hdd_validate_context(hdd_ctx);
3700 if (0 != ret)
3701 return ret;
3702
3703 return 0;
3704}
3705
3706/**
3707 * iw_get_nick() - SSR wrapper for __iw_get_nick
3708 * @dev: pointer to net_device
3709 * @info: pointer to iw_request_info
3710 * @wrqu: pointer to iwreq_data
3711 * @extra: extra
3712 *
3713 * Return: 0 on success, error number otherwise
3714 */
3715static int iw_get_nick(struct net_device *dev,
3716 struct iw_request_info *info,
3717 union iwreq_data *wrqu, char *extra)
3718{
3719 int ret;
3720
3721 cds_ssr_protect(__func__);
3722 ret = __iw_get_nick(dev, info, wrqu, extra);
3723 cds_ssr_unprotect(__func__);
3724
3725 return ret;
3726}
3727
3728/**
3729 * __iw_set_encode() - SIOCSIWENCODE ioctl handler
3730 * @dev: device upon which the ioctl was received
3731 * @info: ioctl request information
3732 * @wrqu: ioctl request data
3733 * @extra: ioctl extra data
3734 *
3735 * Return: 0 on success, non-zero on error
3736 */
3737static int __iw_set_encode(struct net_device *dev, struct iw_request_info *info,
3738 union iwreq_data *wrqu, char *extra)
3739{
3740 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3741 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
3742 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
3743 hdd_context_t *hdd_ctx;
3744 struct iw_point *encoderq = &(wrqu->encoding);
3745 uint32_t keyId;
3746 uint8_t key_length;
3747 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
3748 bool fKeyPresent = 0;
3749 int i;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303750 QDF_STATUS status = QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003751 int ret;
3752
3753 ENTER();
3754
3755 hdd_ctx = WLAN_HDD_GET_CTX(pAdapter);
3756 ret = wlan_hdd_validate_context(hdd_ctx);
3757 if (0 != ret)
3758 return ret;
3759
3760 keyId = encoderq->flags & IW_ENCODE_INDEX;
3761
3762 if (keyId) {
3763 if (keyId > MAX_WEP_KEYS) {
3764 return -EINVAL;
3765 }
3766
3767 fKeyPresent = 1;
3768 keyId--;
3769 } else {
3770 fKeyPresent = 0;
3771 }
3772
3773 if (wrqu->data.flags & IW_ENCODE_DISABLED) {
3774 CDF_TRACE(CDF_MODULE_ID_HDD, CDF_TRACE_LEVEL_INFO,
3775 "****iwconfig wlan0 key off*****");
3776 if (!fKeyPresent) {
3777
3778 for (i = 0; i < CSR_MAX_NUM_KEY; i++) {
3779
3780 if (pWextState->roamProfile.Keys.KeyMaterial[i])
3781 pWextState->roamProfile.Keys.
3782 KeyLength[i] = 0;
3783 }
3784 }
3785 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_OPEN_SYSTEM;
3786 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
3787 pWextState->roamProfile.EncryptionType.encryptionType[0] =
3788 eCSR_ENCRYPT_TYPE_NONE;
3789 pWextState->roamProfile.mcEncryptionType.encryptionType[0] =
3790 eCSR_ENCRYPT_TYPE_NONE;
3791
3792 pHddStaCtx->conn_info.ucEncryptionType = eCSR_ENCRYPT_TYPE_NONE;
3793 pHddStaCtx->conn_info.mcEncryptionType = eCSR_ENCRYPT_TYPE_NONE;
3794
3795 if (eConnectionState_Associated ==
3796 pHddStaCtx->conn_info.connState) {
3797 INIT_COMPLETION(pAdapter->disconnect_comp_var);
3798 status =
3799 sme_roam_disconnect(WLAN_HDD_GET_HAL_CTX(pAdapter),
3800 pAdapter->sessionId,
3801 eCSR_DISCONNECT_REASON_UNSPECIFIED);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303802 if (QDF_STATUS_SUCCESS == status) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003803 unsigned long rc;
3804 rc = wait_for_completion_timeout(&pAdapter->
3805 disconnect_comp_var,
3806 msecs_to_jiffies
3807 (WLAN_WAIT_TIME_DISCONNECT));
3808 if (!rc)
3809 hddLog(CDF_TRACE_LEVEL_ERROR,
3810 FL
3811 ("failed wait on disconnect_comp_var"));
3812 }
3813 }
3814
3815 return status;
3816
3817 }
3818
3819 if (wrqu->data.flags & (IW_ENCODE_OPEN | IW_ENCODE_RESTRICTED)) {
3820 hddLog(CDF_TRACE_LEVEL_INFO, "iwconfig wlan0 key on");
3821
3822 pHddStaCtx->conn_info.authType =
3823 (encoderq->
3824 flags & IW_ENCODE_RESTRICTED) ? eCSR_AUTH_TYPE_SHARED_KEY :
3825 eCSR_AUTH_TYPE_OPEN_SYSTEM;
3826
3827 }
3828
3829 if (wrqu->data.length > 0) {
3830 hddLog(CDF_TRACE_LEVEL_INFO, "%s : wrqu->data.length : %d",
3831 __func__, wrqu->data.length);
3832
3833 key_length = wrqu->data.length;
3834
3835 /* IW_ENCODING_TOKEN_MAX is the value that is set for wrqu->data.length by iwconfig.c when 'iwconfig wlan0 key on' is issued. */
3836
3837 if (5 == key_length) {
3838 hddLog(CDF_TRACE_LEVEL_INFO,
3839 "%s: Call with WEP40,key_len=%d", __func__,
3840 key_length);
3841
3842 if ((IW_AUTH_KEY_MGMT_802_1X == pWextState->authKeyMgmt)
3843 && (eCSR_AUTH_TYPE_OPEN_SYSTEM ==
3844 pHddStaCtx->conn_info.authType)) {
3845 encryptionType = eCSR_ENCRYPT_TYPE_WEP40;
3846 } else {
3847 encryptionType =
3848 eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
3849 }
3850 } else if (13 == key_length) {
3851 hddLog(CDF_TRACE_LEVEL_INFO,
3852 "%s:Call with WEP104,key_len:%d", __func__,
3853 key_length);
3854
3855 if ((IW_AUTH_KEY_MGMT_802_1X == pWextState->authKeyMgmt)
3856 && (eCSR_AUTH_TYPE_OPEN_SYSTEM ==
3857 pHddStaCtx->conn_info.authType)) {
3858 encryptionType = eCSR_ENCRYPT_TYPE_WEP104;
3859 } else {
3860 encryptionType =
3861 eCSR_ENCRYPT_TYPE_WEP104_STATICKEY;
3862 }
3863 } else {
3864 hddLog(CDF_TRACE_LEVEL_WARN,
3865 "%s: Invalid WEP key length :%d", __func__,
3866 key_length);
3867 return -EINVAL;
3868 }
3869
3870 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
3871 pHddStaCtx->conn_info.mcEncryptionType = encryptionType;
3872 pWextState->roamProfile.EncryptionType.numEntries = 1;
3873 pWextState->roamProfile.EncryptionType.encryptionType[0] =
3874 encryptionType;
3875 pWextState->roamProfile.mcEncryptionType.numEntries = 1;
3876 pWextState->roamProfile.mcEncryptionType.encryptionType[0] =
3877 encryptionType;
3878
3879 if ((eConnectionState_NotConnected ==
3880 pHddStaCtx->conn_info.connState)
3881 &&
3882 ((eCSR_AUTH_TYPE_OPEN_SYSTEM ==
3883 pHddStaCtx->conn_info.authType)
3884 || (eCSR_AUTH_TYPE_SHARED_KEY ==
3885 pHddStaCtx->conn_info.authType))) {
3886
3887 cdf_mem_copy(&pWextState->roamProfile.Keys.
3888 KeyMaterial[keyId][0], extra, key_length);
3889
3890 pWextState->roamProfile.Keys.KeyLength[keyId] =
3891 (uint8_t) key_length;
3892 pWextState->roamProfile.Keys.defaultIndex =
3893 (uint8_t) keyId;
3894
3895 return status;
3896 }
3897 }
3898
3899 return 0;
3900}
3901
3902/**
3903 * iw_set_encode() - SSR wrapper for __iw_set_encode()
3904 * @dev: pointer to net_device
3905 * @info: pointer to iw_request_info
3906 * @wrqu: pointer to iwreq_data
3907 * @extra: pointer to extra ioctl payload
3908 *
3909 * Return: 0 on success, error number otherwise
3910 */
3911static int iw_set_encode(struct net_device *dev, struct iw_request_info *info,
3912 union iwreq_data *wrqu, char *extra)
3913{
3914 int ret;
3915
3916 cds_ssr_protect(__func__);
3917 ret = __iw_set_encode(dev, info, wrqu, extra);
3918 cds_ssr_unprotect(__func__);
3919
3920 return ret;
3921}
3922
3923/**
3924 * __iw_get_encodeext() - SIOCGIWENCODEEXT ioctl handler
3925 * @dev: device upon which the ioctl was received
3926 * @info: ioctl request information
3927 * @wrqu: ioctl request data
3928 * @extra: ioctl extra data
3929 *
3930 * Return: 0 on success, non-zero on error
3931 */
3932static int __iw_get_encodeext(struct net_device *dev,
3933 struct iw_request_info *info,
3934 struct iw_point *dwrq, char *extra)
3935{
3936 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3937 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
3938 tCsrRoamProfile *pRoamProfile = &(pWextState->roamProfile);
3939 int keyId;
3940 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
3941 eCsrAuthType authType = eCSR_AUTH_TYPE_NONE;
3942 int i, ret;
3943 hdd_context_t *hdd_ctx;
3944
3945 ENTER();
3946
3947 hdd_ctx = WLAN_HDD_GET_CTX(pAdapter);
3948 ret = wlan_hdd_validate_context(hdd_ctx);
3949 if (0 != ret)
3950 return ret;
3951
3952 keyId = pRoamProfile->Keys.defaultIndex;
3953
3954 if (keyId < 0 || keyId >= MAX_WEP_KEYS) {
3955 hddLog(LOG1, "%s: Invalid keyId : %d", __func__, keyId);
3956 return -EINVAL;
3957 }
3958
3959 if (pRoamProfile->Keys.KeyLength[keyId] > 0) {
3960 dwrq->flags |= IW_ENCODE_ENABLED;
3961 dwrq->length = pRoamProfile->Keys.KeyLength[keyId];
3962 cdf_mem_copy(extra, &(pRoamProfile->Keys.KeyMaterial[keyId][0]),
3963 pRoamProfile->Keys.KeyLength[keyId]);
3964 } else {
3965 dwrq->flags |= IW_ENCODE_DISABLED;
3966 }
3967
3968 for (i = 0; i < MAX_WEP_KEYS; i++) {
3969 if (pRoamProfile->Keys.KeyMaterial[i] == NULL) {
3970 continue;
3971 } else {
3972 break;
3973 }
3974 }
3975
3976 if (MAX_WEP_KEYS == i) {
3977 dwrq->flags |= IW_ENCODE_NOKEY;
3978 } else {
3979 dwrq->flags |= IW_ENCODE_ENABLED;
3980 }
3981
3982 encryptionType = pRoamProfile->EncryptionType.encryptionType[0];
3983
3984 if (eCSR_ENCRYPT_TYPE_NONE == encryptionType) {
3985 dwrq->flags |= IW_ENCODE_DISABLED;
3986 }
3987
3988 authType = (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.authType;
3989
3990 if (IW_AUTH_ALG_OPEN_SYSTEM == authType) {
3991 dwrq->flags |= IW_ENCODE_OPEN;
3992 } else {
3993 dwrq->flags |= IW_ENCODE_RESTRICTED;
3994 }
3995 EXIT();
3996 return 0;
3997
3998}
3999
4000/**
4001 * iw_get_encodeext() - SSR wrapper for __iw_get_encodeext()
4002 * @dev: pointer to net_device
4003 * @info: pointer to iw_request_info
4004 * @dwrq: pointer to encoding information
4005 * @extra: pointer to extra ioctl payload
4006 *
4007 * Return: 0 on success, error number otherwise
4008 */
4009static int iw_get_encodeext(struct net_device *dev,
4010 struct iw_request_info *info,
4011 struct iw_point *dwrq, char *extra)
4012{
4013 int ret;
4014
4015 cds_ssr_protect(__func__);
4016 ret = __iw_get_encodeext(dev, info, dwrq, extra);
4017 cds_ssr_unprotect(__func__);
4018
4019 return ret;
4020}
4021
4022/**
4023 * __iw_set_encodeext() - SIOCSIWENCODEEXT ioctl handler
4024 * @dev: device upon which the ioctl was received
4025 * @info: ioctl request information
4026 * @wrqu: ioctl request data
4027 * @extra: ioctl extra data
4028 *
4029 * Return: 0 on success, non-zero on error
4030 */
4031static int __iw_set_encodeext(struct net_device *dev,
4032 struct iw_request_info *info,
4033 union iwreq_data *wrqu, char *extra)
4034{
4035 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4036 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4037 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
4038 hdd_context_t *hdd_ctx;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304039 QDF_STATUS cdf_ret_status = QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004040 tCsrRoamProfile *pRoamProfile = &pWextState->roamProfile;
4041 int ret;
4042 struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
4043 int key_index;
4044 struct iw_point *encoding = &wrqu->encoding;
4045 tCsrRoamSetKey setKey;
4046 uint32_t roamId = 0xFF;
4047
4048 ENTER();
4049
4050 hdd_ctx = WLAN_HDD_GET_CTX(pAdapter);
4051 ret = wlan_hdd_validate_context(hdd_ctx);
4052 if (0 != ret)
4053 return ret;
4054
4055 key_index = encoding->flags & IW_ENCODE_INDEX;
4056
4057 if (key_index > 0) {
4058
4059 /*Convert from 1-based to 0-based keying */
4060 key_index--;
4061 }
4062 if (!ext->key_len) {
4063
4064 /*Set the encrytion type to NONE */
4065 pRoamProfile->EncryptionType.encryptionType[0] =
4066 eCSR_ENCRYPT_TYPE_NONE;
4067 return ret;
4068 }
4069
4070 if (eConnectionState_NotConnected == pHddStaCtx->conn_info.connState &&
4071 (IW_ENCODE_ALG_WEP == ext->alg)) {
4072 if (IW_AUTH_KEY_MGMT_802_1X == pWextState->authKeyMgmt) {
4073
4074 CDF_TRACE(CDF_MODULE_ID_HDD, CDF_TRACE_LEVEL_ERROR,
4075 ("Invalid Configuration:%s"), __func__);
4076 return -EINVAL;
4077 } else {
4078 /*Static wep, update the roam profile with the keys */
4079 if (ext->key
4080 && (ext->key_len <=
4081 eCSR_SECURITY_WEP_KEYSIZE_MAX_BYTES)
4082 && key_index < CSR_MAX_NUM_KEY) {
4083 cdf_mem_copy(&pRoamProfile->Keys.
4084 KeyMaterial[key_index][0],
4085 ext->key, ext->key_len);
4086 pRoamProfile->Keys.KeyLength[key_index] =
4087 (uint8_t) ext->key_len;
4088
4089 if (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY)
4090 pRoamProfile->Keys.defaultIndex =
4091 (uint8_t) key_index;
4092
4093 }
4094 }
4095 return ret;
4096 }
4097
4098 cdf_mem_zero(&setKey, sizeof(tCsrRoamSetKey));
4099
4100 setKey.keyId = key_index;
4101 setKey.keyLength = ext->key_len;
4102
4103 if (ext->key_len <= CSR_MAX_KEY_LEN) {
4104 cdf_mem_copy(&setKey.Key[0], ext->key, ext->key_len);
4105 }
4106
4107 if (ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY) {
4108 /*Key direction for group is RX only */
4109 setKey.keyDirection = eSIR_RX_ONLY;
4110 cdf_set_macaddr_broadcast(&setKey.peerMac);
4111 } else {
4112
4113 setKey.keyDirection = eSIR_TX_RX;
4114 cdf_mem_copy(setKey.peerMac.bytes, ext->addr.sa_data,
4115 CDF_MAC_ADDR_SIZE);
4116 }
4117
4118 /*For supplicant pae role is zero */
4119 setKey.paeRole = 0;
4120
4121 switch (ext->alg) {
4122 case IW_ENCODE_ALG_NONE:
4123 setKey.encType = eCSR_ENCRYPT_TYPE_NONE;
4124 break;
4125
4126 case IW_ENCODE_ALG_WEP:
4127 setKey.encType =
4128 (ext->key_len ==
4129 5) ? eCSR_ENCRYPT_TYPE_WEP40 : eCSR_ENCRYPT_TYPE_WEP104;
4130 break;
4131
4132 case IW_ENCODE_ALG_TKIP:
4133 {
4134 uint8_t *pKey = &setKey.Key[0];
4135
4136 setKey.encType = eCSR_ENCRYPT_TYPE_TKIP;
4137
4138 cdf_mem_zero(pKey, CSR_MAX_KEY_LEN);
4139
4140 /* Supplicant sends the 32bytes key in this order
4141 * |--------------|----------|----------|
4142 * | Tk1 | TX MIC | RX MIC |
4143 * |--------------|----------|----------|
4144 * <---16bytes---><--8bytes--><--8bytes-->
4145 *
4146 *
4147 * Sme expects the 32 bytes key to be in the below order
4148 * |--------------|----------|----------|
4149 * | Tk1 | RX MIC | TX MIC |
4150 * |--------------|----------|----------|
4151 * <---16bytes---><--8bytes--><--8bytes-->
4152 */
4153
4154 /* Copy the Temporal Key 1 (TK1) */
4155 cdf_mem_copy(pKey, ext->key, 16);
4156
4157 /* Copy the rx mic first */
4158 cdf_mem_copy(&pKey[16], &ext->key[24], 8);
4159
4160 /* Copy the tx mic */
4161 cdf_mem_copy(&pKey[24], &ext->key[16], 8);
4162
4163 }
4164 break;
4165
4166 case IW_ENCODE_ALG_CCMP:
4167 setKey.encType = eCSR_ENCRYPT_TYPE_AES;
4168 break;
4169
4170#ifdef FEATURE_WLAN_ESE
4171#define IW_ENCODE_ALG_KRK 6
4172 case IW_ENCODE_ALG_KRK:
4173 setKey.encType = eCSR_ENCRYPT_TYPE_KRK;
4174 break;
4175#endif /* FEATURE_WLAN_ESE */
4176
4177 default:
4178 setKey.encType = eCSR_ENCRYPT_TYPE_NONE;
4179 break;
4180 }
4181
4182 CDF_TRACE(CDF_MODULE_ID_HDD, CDF_TRACE_LEVEL_INFO,
4183 ("%s:cipher_alg:%d key_len[%d] *pEncryptionType :%d"),
4184 __func__, (int)ext->alg, (int)ext->key_len, setKey.encType);
4185
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004186 /* The supplicant may attempt to set the PTK once
4187 * pre-authentication is done. Save the key in the UMAC and
4188 * include it in the ADD BSS request
4189 */
4190 cdf_ret_status = sme_ft_update_key(WLAN_HDD_GET_HAL_CTX(pAdapter),
4191 pAdapter->sessionId, &setKey);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304192 if (cdf_ret_status == QDF_STATUS_FT_PREAUTH_KEY_SUCCESS) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004193 hddLog(CDF_TRACE_LEVEL_INFO_MED,
4194 "%s: Update PreAuth Key success", __func__);
4195 return 0;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304196 } else if (cdf_ret_status == QDF_STATUS_FT_PREAUTH_KEY_FAILED) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004197 hddLog(CDF_TRACE_LEVEL_ERROR,
4198 "%s: Update PreAuth Key failed", __func__);
4199 return -EINVAL;
4200 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004201
4202 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
4203
4204 cdf_ret_status = sme_roam_set_key(WLAN_HDD_GET_HAL_CTX(pAdapter),
4205 pAdapter->sessionId,
4206 &setKey, &roamId);
4207
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304208 if (cdf_ret_status != QDF_STATUS_SUCCESS) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004209 CDF_TRACE(CDF_MODULE_ID_HDD, CDF_TRACE_LEVEL_ERROR,
4210 "[%4d] sme_roam_set_key returned ERROR status= %d",
4211 __LINE__, cdf_ret_status);
4212
4213 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
4214 }
4215
4216 return cdf_ret_status;
4217}
4218
4219/**
4220 * iw_set_encodeext() - SSR wrapper for __iw_set_encodeext()
4221 * @dev: pointer to net_device
4222 * @info: pointer to iw_request_info
4223 * @wrqu: pointer to iwreq_data
4224 * @extra: pointer to extra ioctl payload
4225 *
4226 * Return: 0 on success, error number otherwise
4227 */
4228static int iw_set_encodeext(struct net_device *dev,
4229 struct iw_request_info *info,
4230 union iwreq_data *wrqu, char *extra)
4231{
4232 int ret;
4233
4234 cds_ssr_protect(__func__);
4235 ret = __iw_set_encodeext(dev, info, wrqu, extra);
4236 cds_ssr_unprotect(__func__);
4237
4238 return ret;
4239}
4240
4241/**
4242 * __iw_set_retry() - SIOCSIWRETRY ioctl handler
4243 * @dev: device upon which the ioctl was received
4244 * @info: ioctl request information
4245 * @wrqu: ioctl request data
4246 * @extra: ioctl extra data
4247 *
4248 * Return: 0 on success, non-zero on error
4249 */
4250static int __iw_set_retry(struct net_device *dev, struct iw_request_info *info,
4251 union iwreq_data *wrqu, char *extra)
4252{
4253 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4254 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
4255 hdd_context_t *hdd_ctx;
4256 int ret;
4257
4258 ENTER();
4259
4260 hdd_ctx = WLAN_HDD_GET_CTX(pAdapter);
4261 ret = wlan_hdd_validate_context(hdd_ctx);
4262 if (0 != ret)
4263 return ret;
4264
4265 if (wrqu->retry.value < WNI_CFG_LONG_RETRY_LIMIT_STAMIN ||
4266 wrqu->retry.value > WNI_CFG_LONG_RETRY_LIMIT_STAMAX) {
4267
4268 CDF_TRACE(CDF_MODULE_ID_HDD, CDF_TRACE_LEVEL_ERROR,
4269 ("Invalid Retry-Limit=%d!!"), wrqu->retry.value);
4270
4271 return -EINVAL;
4272 }
4273
4274 if (wrqu->retry.flags & IW_RETRY_LIMIT) {
4275
4276 if ((wrqu->retry.flags & IW_RETRY_LONG)) {
4277 if (sme_cfg_set_int (hHal, WNI_CFG_LONG_RETRY_LIMIT,
4278 wrqu->retry.value) !=
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304279 QDF_STATUS_SUCCESS) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004280 CDF_TRACE(CDF_MODULE_ID_HDD,
4281 CDF_TRACE_LEVEL_ERROR, FL
4282 ("failed to set ini parameter, WNI_CFG_LONG_RETRY_LIMIT"));
4283 return -EIO;
4284 }
4285 } else if ((wrqu->retry.flags & IW_RETRY_SHORT)) {
4286 if (sme_cfg_set_int (hHal, WNI_CFG_SHORT_RETRY_LIMIT,
4287 wrqu->retry.value) !=
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304288 QDF_STATUS_SUCCESS) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004289 CDF_TRACE(CDF_MODULE_ID_HDD,
4290 CDF_TRACE_LEVEL_ERROR, FL
4291 ("failed to set ini parameter, WNI_CFG_LONG_RETRY_LIMIT"));
4292 return -EIO;
4293 }
4294 }
4295 } else {
4296 return -EOPNOTSUPP;
4297 }
4298
4299 CDF_TRACE(CDF_MODULE_ID_HDD, CDF_TRACE_LEVEL_INFO,
4300 ("Set Retry-Limit=%d!!"), wrqu->retry.value);
4301
4302 EXIT();
4303
4304 return 0;
4305
4306}
4307
4308/**
4309 * iw_set_retry() - SSR wrapper for __iw_set_retry()
4310 * @dev: pointer to net_device
4311 * @info: pointer to iw_request_info
4312 * @wrqu: pointer to iwreq_data
4313 * @extra: pointer to extra ioctl payload
4314 *
4315 * Return: 0 on success, error number otherwise
4316 */
4317static int iw_set_retry(struct net_device *dev, struct iw_request_info *info,
4318 union iwreq_data *wrqu, char *extra)
4319{
4320 int ret;
4321
4322 cds_ssr_protect(__func__);
4323 ret = __iw_set_retry(dev, info, wrqu, extra);
4324 cds_ssr_unprotect(__func__);
4325
4326 return ret;
4327}
4328
4329/**
4330 * __iw_get_retry() - SIOCGIWRETRY ioctl handler
4331 * @dev: device upon which the ioctl was received
4332 * @info: ioctl request information
4333 * @wrqu: ioctl request data
4334 * @extra: ioctl extra data
4335 *
4336 * Return: 0 on success, non-zero on error
4337 */
4338static int __iw_get_retry(struct net_device *dev, struct iw_request_info *info,
4339 union iwreq_data *wrqu, char *extra)
4340{
4341 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4342 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
4343 uint32_t retry = 0;
4344 hdd_context_t *hdd_ctx;
4345 int ret;
4346
4347 ENTER();
4348
4349 hdd_ctx = WLAN_HDD_GET_CTX(pAdapter);
4350 ret = wlan_hdd_validate_context(hdd_ctx);
4351 if (0 != ret)
4352 return ret;
4353
4354 if ((wrqu->retry.flags & IW_RETRY_LONG)) {
4355 wrqu->retry.flags = IW_RETRY_LIMIT | IW_RETRY_LONG;
4356
4357 if (sme_cfg_get_int(hHal, WNI_CFG_LONG_RETRY_LIMIT, &retry) !=
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304358 QDF_STATUS_SUCCESS) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004359 CDF_TRACE(CDF_MODULE_ID_HDD, CDF_TRACE_LEVEL_WARN,
4360 FL
4361 ("failed to get ini parameter, WNI_CFG_LONG_RETRY_LIMIT"));
4362 return -EIO;
4363 }
4364
4365 wrqu->retry.value = retry;
4366 } else if ((wrqu->retry.flags & IW_RETRY_SHORT)) {
4367 wrqu->retry.flags = IW_RETRY_LIMIT | IW_RETRY_SHORT;
4368
4369 if (sme_cfg_get_int(hHal, WNI_CFG_SHORT_RETRY_LIMIT, &retry) !=
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304370 QDF_STATUS_SUCCESS) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004371 CDF_TRACE(CDF_MODULE_ID_HDD, CDF_TRACE_LEVEL_WARN,
4372 FL
4373 ("failed to get ini parameter, WNI_CFG_LONG_RETRY_LIMIT"));
4374 return -EIO;
4375 }
4376
4377 wrqu->retry.value = retry;
4378 } else {
4379 return -EOPNOTSUPP;
4380 }
4381
4382 CDF_TRACE(CDF_MODULE_ID_HDD, CDF_TRACE_LEVEL_INFO, ("Retry-Limit=%d!!"),
4383 retry);
4384
4385 EXIT();
4386
4387 return 0;
4388}
4389
4390/**
4391 * iw_get_retry() - SSR wrapper for __iw_get_retry()
4392 * @dev: pointer to net_device
4393 * @info: pointer to iw_request_info
4394 * @wrqu: pointer to iwreq_data
4395 * @extra: pointer to extra ioctl payload
4396 *
4397 * Return: 0 on success, error number otherwise
4398 */
4399static int iw_get_retry(struct net_device *dev, struct iw_request_info *info,
4400 union iwreq_data *wrqu, char *extra)
4401{
4402 int ret;
4403
4404 cds_ssr_protect(__func__);
4405 ret = __iw_get_retry(dev, info, wrqu, extra);
4406 cds_ssr_unprotect(__func__);
4407
4408 return ret;
4409}
4410
4411/**
4412 * __iw_set_mlme() - SIOCSIWMLME ioctl handler
4413 * @dev: device upon which the ioctl was received
4414 * @info: ioctl request information
4415 * @wrqu: ioctl request data
4416 * @extra: ioctl extra data
4417 *
4418 * Return: 0 on success, non-zero on error
4419 */
4420static int __iw_set_mlme(struct net_device *dev,
4421 struct iw_request_info *info,
4422 union iwreq_data *wrqu, char *extra)
4423{
4424 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4425 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4426 struct iw_mlme *mlme = (struct iw_mlme *)extra;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304427 QDF_STATUS status = QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004428 hdd_context_t *hdd_ctx;
4429 int ret;
4430
4431 ENTER();
4432
4433 hdd_ctx = WLAN_HDD_GET_CTX(pAdapter);
4434 ret = wlan_hdd_validate_context(hdd_ctx);
4435 if (0 != ret)
4436 return ret;
4437
4438 /* reason_code is unused. By default it is set to
4439 * eCSR_DISCONNECT_REASON_UNSPECIFIED
4440 */
4441 switch (mlme->cmd) {
4442 case IW_MLME_DISASSOC:
4443 case IW_MLME_DEAUTH:
4444
4445 if (pHddStaCtx->conn_info.connState ==
4446 eConnectionState_Associated) {
4447 eCsrRoamDisconnectReason reason =
4448 eCSR_DISCONNECT_REASON_UNSPECIFIED;
4449
4450 if (mlme->reason_code == HDD_REASON_MICHAEL_MIC_FAILURE)
4451 reason = eCSR_DISCONNECT_REASON_MIC_ERROR;
4452
4453 INIT_COMPLETION(pAdapter->disconnect_comp_var);
4454 status =
4455 sme_roam_disconnect(WLAN_HDD_GET_HAL_CTX(pAdapter),
4456 pAdapter->sessionId, reason);
4457
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304458 if (QDF_STATUS_SUCCESS == status) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004459 unsigned long rc;
4460 rc = wait_for_completion_timeout(&pAdapter->
4461 disconnect_comp_var,
4462 msecs_to_jiffies
4463 (WLAN_WAIT_TIME_DISCONNECT));
4464 if (!rc)
4465 hddLog(CDF_TRACE_LEVEL_ERROR,
4466 FL
4467 ("failed wait on disconnect_comp_var"));
4468 } else
4469 hddLog(LOGE,
4470 "%s %d Command Disassociate/Deauthenticate : csr_roam_disconnect failure returned %d",
4471 __func__, (int)mlme->cmd, (int)status);
4472
4473 /* Resetting authKeyMgmt */
4474 (WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter))->authKeyMgmt =
4475 0;
4476
4477 hddLog(LOG1, FL("Disabling queues"));
4478 wlan_hdd_netif_queue_control(pAdapter,
4479 WLAN_NETIF_TX_DISABLE_N_CARRIER,
4480 WLAN_CONTROL_PATH);
4481
4482 } else {
4483 hddLog(LOGE,
4484 "%s %d Command Disassociate/Deauthenticate called but station is not in associated state",
4485 __func__, (int)mlme->cmd);
4486 }
4487 break;
4488 default:
4489 hddLog(LOGE,
4490 "%s %d Command should be Disassociate/Deauthenticate",
4491 __func__, (int)mlme->cmd);
4492 return -EINVAL;
4493 } /* end of switch */
4494
4495 EXIT();
4496
4497 return status;
4498
4499}
4500
4501/**
4502 * iw_set_mlme() - SSR wrapper for __iw_set_mlme()
4503 * @dev: pointer to net_device
4504 * @info: pointer to iw_request_info
4505 * @wrqu: pointer to iwreq_data
4506 * @extra: pointer to extra ioctl payload
4507 *
4508 * Return: 0 on success, error number otherwise
4509 */
4510static int iw_set_mlme(struct net_device *dev, struct iw_request_info *info,
4511 union iwreq_data *wrqu, char *extra)
4512{
4513 int ret;
4514
4515 cds_ssr_protect(__func__);
4516 ret = __iw_set_mlme(dev, info, wrqu, extra);
4517 cds_ssr_unprotect(__func__);
4518
4519 return ret;
4520}
4521
4522/**
4523 * wlan_hdd_update_phymode() - handle change in PHY mode
4524 * @net: device upon which PHY mode change was received
4525 * @hal: umac handle for the driver
4526 * @new_phymode: new PHY mode for the device
4527 * @phddctx: pointer to the HDD context
4528 *
4529 * This function is called when the device is set to a new PHY mode.
4530 * It takes a holistic look at the desired PHY mode along with the
4531 * configured capabilities of the driver and the reported capabilities
4532 * of the hardware in order to correctly configure all PHY-related
4533 * parameters.
4534 *
4535 * Return: 0 on success, negative errno value on error
4536 */
4537int wlan_hdd_update_phymode(struct net_device *net, tHalHandle hal,
4538 int new_phymode, hdd_context_t *phddctx)
4539{
4540#ifdef QCA_HT_2040_COEX
4541 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(net);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304542 QDF_STATUS halStatus = QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004543#endif
4544 bool band_24 = false, band_5g = false;
4545 bool ch_bond24 = false, ch_bond5g = false;
4546 tSmeConfigParams smeconfig;
4547 uint32_t chwidth = WNI_CFG_CHANNEL_BONDING_MODE_DISABLE;
4548#ifdef WLAN_FEATURE_11AC
4549 uint32_t vhtchanwidth;
4550#endif
4551 eCsrPhyMode phymode = -EIO, old_phymode;
4552 eHddDot11Mode hdd_dot11mode = phddctx->config->dot11Mode;
4553 eCsrBand curr_band = eCSR_BAND_ALL;
4554
4555 old_phymode = sme_get_phy_mode(hal);
4556
4557 if (WNI_CFG_CHANNEL_BONDING_MODE_DISABLE !=
4558 sme_get_cb_phy_state_from_cb_ini_value(phddctx->config->
4559 nChannelBondingMode24GHz))
4560 ch_bond24 = true;
4561
4562 if (WNI_CFG_CHANNEL_BONDING_MODE_DISABLE !=
4563 sme_get_cb_phy_state_from_cb_ini_value(phddctx->config->
4564 nChannelBondingMode5GHz))
4565 ch_bond5g = true;
4566
4567 if (phddctx->config->nBandCapability == eCSR_BAND_ALL) {
4568 band_24 = band_5g = true;
4569 } else if (phddctx->config->nBandCapability == eCSR_BAND_24) {
4570 band_24 = true;
4571 } else if (phddctx->config->nBandCapability == eCSR_BAND_5G) {
4572 band_5g = true;
4573 }
4574
4575 vhtchanwidth = phddctx->config->vhtChannelWidth;
4576 CDF_TRACE(CDF_MODULE_ID_HDD, CDF_TRACE_LEVEL_WARN, ("ch_bond24=%d "
4577 "ch_bond5g=%d band_24=%d band_5g=%d VHT_ch_width=%u"),
4578 ch_bond24, ch_bond5g, band_24, band_5g, vhtchanwidth);
4579
4580 switch (new_phymode) {
4581 case IEEE80211_MODE_AUTO:
4582 sme_set_phy_mode(hal, eCSR_DOT11_MODE_AUTO);
4583 if (hdd_set_band(net, WLAN_HDD_UI_BAND_AUTO) == 0) {
4584 phymode = eCSR_DOT11_MODE_AUTO;
4585 hdd_dot11mode = eHDD_DOT11_MODE_AUTO;
4586 chwidth = WNI_CFG_CHANNEL_BONDING_MODE_ENABLE;
4587 curr_band = eCSR_BAND_ALL;
4588 vhtchanwidth = eHT_CHANNEL_WIDTH_80MHZ;
4589 } else {
4590 sme_set_phy_mode(hal, old_phymode);
4591 return -EIO;
4592 }
4593 break;
4594 case IEEE80211_MODE_11A:
4595 sme_set_phy_mode(hal, eCSR_DOT11_MODE_11a);
4596 if ((hdd_set_band(net, WLAN_HDD_UI_BAND_5_GHZ) == 0)) {
4597 phymode = eCSR_DOT11_MODE_11a;
4598 hdd_dot11mode = eHDD_DOT11_MODE_11a;
4599 chwidth = WNI_CFG_CHANNEL_BONDING_MODE_DISABLE;
4600 curr_band = eCSR_BAND_5G;
4601 } else {
4602 sme_set_phy_mode(hal, old_phymode);
4603 return -EIO;
4604 }
4605 break;
4606 case IEEE80211_MODE_11B:
4607 sme_set_phy_mode(hal, eCSR_DOT11_MODE_11b);
4608 if ((hdd_set_band(net, WLAN_HDD_UI_BAND_2_4_GHZ) == 0)) {
4609 phymode = eCSR_DOT11_MODE_11b;
4610 hdd_dot11mode = eHDD_DOT11_MODE_11b;
4611 chwidth = WNI_CFG_CHANNEL_BONDING_MODE_DISABLE;
4612 curr_band = eCSR_BAND_24;
4613 } else {
4614 sme_set_phy_mode(hal, old_phymode);
4615 return -EIO;
4616 }
4617 break;
4618 case IEEE80211_MODE_11G:
4619 sme_set_phy_mode(hal, eCSR_DOT11_MODE_11g);
4620 if ((hdd_set_band(net, WLAN_HDD_UI_BAND_2_4_GHZ) == 0)) {
4621 phymode = eCSR_DOT11_MODE_11g;
4622 hdd_dot11mode = eHDD_DOT11_MODE_11g;
4623 chwidth = WNI_CFG_CHANNEL_BONDING_MODE_DISABLE;
4624 curr_band = eCSR_BAND_24;
4625 } else {
4626 sme_set_phy_mode(hal, old_phymode);
4627 return -EIO;
4628 }
4629 break;
4630 /* UMAC doesnt have option to set MODE_11NA/MODE_11NG as phymode
4631 * so setting phymode as eCSR_DOT11_MODE_11n and updating the band
4632 * and channel bonding in configuration to reflect MODE_11NA/MODE_11NG
4633 */
4634 case IEEE80211_MODE_11NA_HT20:
4635 sme_set_phy_mode(hal, eCSR_DOT11_MODE_11n);
4636 if ((hdd_set_band(net, WLAN_HDD_UI_BAND_5_GHZ) == 0)) {
4637 phymode = eCSR_DOT11_MODE_11n;
4638 hdd_dot11mode = eHDD_DOT11_MODE_11n;
4639 chwidth = WNI_CFG_CHANNEL_BONDING_MODE_DISABLE;
4640 curr_band = eCSR_BAND_5G;
4641 } else {
4642 sme_set_phy_mode(hal, old_phymode);
4643 return -EIO;
4644 }
4645 break;
4646 case IEEE80211_MODE_11NA_HT40:
4647 sme_set_phy_mode(hal, eCSR_DOT11_MODE_11n);
4648 if ((hdd_set_band(net, WLAN_HDD_UI_BAND_5_GHZ) == 0)) {
4649 phymode = eCSR_DOT11_MODE_11n;
4650 hdd_dot11mode = eHDD_DOT11_MODE_11n;
4651 chwidth = WNI_CFG_CHANNEL_BONDING_MODE_ENABLE;
4652 curr_band = eCSR_BAND_5G;
4653 } else {
4654 sme_set_phy_mode(hal, old_phymode);
4655 return -EIO;
4656 }
4657 break;
4658 case IEEE80211_MODE_11NG_HT20:
4659 sme_set_phy_mode(hal, eCSR_DOT11_MODE_11n);
4660 if ((hdd_set_band(net, WLAN_HDD_UI_BAND_2_4_GHZ) == 0)) {
4661 phymode = eCSR_DOT11_MODE_11n;
4662 hdd_dot11mode = eHDD_DOT11_MODE_11n;
4663 chwidth = WNI_CFG_CHANNEL_BONDING_MODE_DISABLE;
4664 curr_band = eCSR_BAND_24;
4665 } else {
4666 sme_set_phy_mode(hal, old_phymode);
4667 return -EIO;
4668 }
4669 break;
4670 case IEEE80211_MODE_11NG_HT40:
4671 sme_set_phy_mode(hal, eCSR_DOT11_MODE_11n);
4672 if ((hdd_set_band(net, WLAN_HDD_UI_BAND_2_4_GHZ) == 0)) {
4673 phymode = eCSR_DOT11_MODE_11n;
4674 hdd_dot11mode = eHDD_DOT11_MODE_11n;
4675 chwidth = WNI_CFG_CHANNEL_BONDING_MODE_ENABLE;
4676 curr_band = eCSR_BAND_24;
4677 } else {
4678 sme_set_phy_mode(hal, old_phymode);
4679 return -EIO;
4680 }
4681 break;
4682#ifdef WLAN_FEATURE_11AC
4683 case IEEE80211_MODE_11AC_VHT20:
4684 case IEEE80211_MODE_11AC_VHT40:
4685 case IEEE80211_MODE_11AC_VHT80:
4686 sme_set_phy_mode(hal, eCSR_DOT11_MODE_11ac);
4687 if ((hdd_set_band(net, WLAN_HDD_UI_BAND_5_GHZ) == 0)) {
4688 phymode = eCSR_DOT11_MODE_11ac;
4689 hdd_dot11mode = eHDD_DOT11_MODE_11ac;
4690 chwidth = WNI_CFG_CHANNEL_BONDING_MODE_ENABLE;
4691 curr_band = eCSR_BAND_5G;
4692 } else {
4693 sme_set_phy_mode(hal, old_phymode);
4694 return -EIO;
4695 }
4696 break;
4697#endif
4698 case IEEE80211_MODE_2G_AUTO:
4699 sme_set_phy_mode(hal, eCSR_DOT11_MODE_AUTO);
4700 if ((hdd_set_band(net, WLAN_HDD_UI_BAND_2_4_GHZ) == 0)) {
4701 phymode = eCSR_DOT11_MODE_AUTO;
4702 hdd_dot11mode = eHDD_DOT11_MODE_AUTO;
4703 chwidth = WNI_CFG_CHANNEL_BONDING_MODE_ENABLE;
4704 curr_band = eCSR_BAND_24;
4705 } else {
4706 sme_set_phy_mode(hal, old_phymode);
4707 return -EIO;
4708 }
4709 break;
4710 case IEEE80211_MODE_5G_AUTO:
4711 sme_set_phy_mode(hal, eCSR_DOT11_MODE_AUTO);
4712 if ((hdd_set_band(net, WLAN_HDD_UI_BAND_5_GHZ) == 0)) {
4713 phymode = eCSR_DOT11_MODE_AUTO;
4714 hdd_dot11mode = eHDD_DOT11_MODE_AUTO;
4715 chwidth = WNI_CFG_CHANNEL_BONDING_MODE_ENABLE;
4716 vhtchanwidth = eHT_CHANNEL_WIDTH_80MHZ;
4717 curr_band = eCSR_BAND_5G;
4718 } else {
4719 sme_set_phy_mode(hal, old_phymode);
4720 return -EIO;
4721 }
4722 break;
4723 case IEEE80211_MODE_11AGN:
4724 sme_set_phy_mode(hal, eCSR_DOT11_MODE_11n);
4725 if ((hdd_set_band(net, WLAN_HDD_UI_BAND_AUTO) == 0)) {
4726 phymode = eCSR_DOT11_MODE_11n;
4727 hdd_dot11mode = eHDD_DOT11_MODE_11n;
4728 chwidth = WNI_CFG_CHANNEL_BONDING_MODE_ENABLE;
4729 curr_band = eCSR_BAND_ALL;
4730 } else {
4731 sme_set_phy_mode(hal, old_phymode);
4732 return -EIO;
4733 }
4734 break;
4735 default:
4736 return -EIO;
4737 }
4738
4739#ifdef WLAN_FEATURE_11AC
4740 switch (new_phymode) {
4741 case IEEE80211_MODE_11AC_VHT20:
4742 chwidth = WNI_CFG_CHANNEL_BONDING_MODE_DISABLE;
4743 vhtchanwidth = eHT_CHANNEL_WIDTH_20MHZ;
4744 break;
4745 case IEEE80211_MODE_11AC_VHT40:
4746 vhtchanwidth = eHT_CHANNEL_WIDTH_40MHZ;
4747 break;
4748 case IEEE80211_MODE_11AC_VHT80:
4749 vhtchanwidth = eHT_CHANNEL_WIDTH_80MHZ;
4750 break;
4751 default:
4752 vhtchanwidth = phddctx->config->vhtChannelWidth;
4753 break;
4754 }
4755#endif
4756
4757 if (phymode != -EIO) {
4758 sme_get_config_param(hal, &smeconfig);
4759 smeconfig.csrConfig.phyMode = phymode;
4760#ifdef QCA_HT_2040_COEX
4761 if (phymode == eCSR_DOT11_MODE_11n &&
4762 chwidth == WNI_CFG_CHANNEL_BONDING_MODE_DISABLE) {
4763 smeconfig.csrConfig.obssEnabled = false;
4764 halStatus = sme_set_ht2040_mode(hal,
4765 pAdapter->sessionId,
4766 eHT_CHAN_HT20, false);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304767 if (halStatus == QDF_STATUS_E_FAILURE) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004768 hddLog(LOGE, FL("Failed to disable OBSS"));
4769 return -EIO;
4770 }
4771 } else if (phymode == eCSR_DOT11_MODE_11n &&
4772 chwidth == WNI_CFG_CHANNEL_BONDING_MODE_ENABLE) {
4773 smeconfig.csrConfig.obssEnabled = true;
4774 halStatus = sme_set_ht2040_mode(hal,
4775 pAdapter->sessionId,
4776 eHT_CHAN_HT20, true);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304777 if (halStatus == QDF_STATUS_E_FAILURE) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004778 hddLog(LOGE, FL("Failed to enable OBSS"));
4779 return -EIO;
4780 }
4781 }
4782#endif
4783 smeconfig.csrConfig.eBand = curr_band;
4784 smeconfig.csrConfig.bandCapability = curr_band;
4785 if (curr_band == eCSR_BAND_24)
4786 smeconfig.csrConfig.Is11hSupportEnabled = 0;
4787 else
4788 smeconfig.csrConfig.Is11hSupportEnabled =
4789 phddctx->config->Is11hSupportEnabled;
4790 if (curr_band == eCSR_BAND_24)
4791 smeconfig.csrConfig.channelBondingMode24GHz = chwidth;
4792 else if (curr_band == eCSR_BAND_24)
4793 smeconfig.csrConfig.channelBondingMode5GHz = chwidth;
4794 else {
4795 smeconfig.csrConfig.channelBondingMode24GHz = chwidth;
4796 smeconfig.csrConfig.channelBondingMode5GHz = chwidth;
4797 }
4798#ifdef WLAN_FEATURE_11AC
4799 smeconfig.csrConfig.nVhtChannelWidth = vhtchanwidth;
4800#endif
4801 sme_update_config(hal, &smeconfig);
4802
4803 phddctx->config->dot11Mode = hdd_dot11mode;
4804 phddctx->config->nBandCapability = curr_band;
4805 phddctx->config->nChannelBondingMode24GHz =
4806 smeconfig.csrConfig.channelBondingMode24GHz;
4807 phddctx->config->nChannelBondingMode5GHz =
4808 smeconfig.csrConfig.channelBondingMode5GHz;
4809 phddctx->config->vhtChannelWidth = vhtchanwidth;
4810 if (hdd_update_config_dat(phddctx) == false) {
4811 CDF_TRACE(CDF_MODULE_ID_HDD, CDF_TRACE_LEVEL_ERROR,
4812 "%s: could not update config_dat", __func__);
4813 return -EIO;
4814 }
4815 if (phddctx->config->nChannelBondingMode5GHz)
4816 phddctx->wiphy->bands[IEEE80211_BAND_5GHZ]->ht_cap.cap
4817 |= IEEE80211_HT_CAP_SUP_WIDTH_20_40;
4818 else
4819 phddctx->wiphy->bands[IEEE80211_BAND_5GHZ]->ht_cap.cap
4820 &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40;
4821
4822 CDF_TRACE(CDF_MODULE_ID_HDD, CDF_TRACE_LEVEL_WARN,
4823 "New_Phymode= %d ch_bonding=%d band=%d VHT_ch_width=%u",
4824 phymode, chwidth, curr_band, vhtchanwidth);
4825 }
4826
4827 return 0;
4828}
4829
4830/**
4831 * hdd_get_temperature_cb() - "Get Temperature" callback function
4832 * @temperature: measured temperature
4833 * @pContext: callback context
4834 *
4835 * This function is passed to sme_get_temperature() as the callback
4836 * function to be invoked when the temperature measurement is
4837 * available.
4838 *
4839 * Return: None
4840 */
4841static void hdd_get_temperature_cb(int temperature, void *pContext)
4842{
4843 struct statsContext *pTempContext;
4844 hdd_adapter_t *pAdapter;
4845 ENTER();
4846 if (NULL == pContext) {
4847 hddLog(CDF_TRACE_LEVEL_ERROR, FL("pContext is NULL"));
4848 return;
4849 }
4850 pTempContext = pContext;
4851 pAdapter = pTempContext->pAdapter;
4852 spin_lock(&hdd_context_lock);
4853 if ((NULL == pAdapter) || (TEMP_CONTEXT_MAGIC != pTempContext->magic)) {
4854 spin_unlock(&hdd_context_lock);
4855 hddLog(CDF_TRACE_LEVEL_WARN,
4856 FL("Invalid context, pAdapter [%p] magic [%08x]"),
4857 pAdapter, pTempContext->magic);
4858 return;
4859 }
4860 if (temperature != 0) {
4861 pAdapter->temperature = temperature;
4862 }
4863 complete(&pTempContext->completion);
4864 spin_unlock(&hdd_context_lock);
4865 EXIT();
4866}
4867
4868/**
4869 * wlan_hdd_get_temperature() - get current device temperature
4870 * @pAdapter: device upon which the request was made
4871 * @temperature: pointer to where the temperature is to be returned
4872 *
4873 * Return: 0 if a temperature value (either current or cached) was
4874 * returned, otherwise a negative errno is returned.
4875 *
4876 */
4877int wlan_hdd_get_temperature(hdd_adapter_t *pAdapter, int *temperature)
4878{
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304879 QDF_STATUS status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004880 struct statsContext tempContext;
4881 unsigned long rc;
4882
4883 ENTER();
4884 if (NULL == pAdapter) {
4885 hddLog(CDF_TRACE_LEVEL_ERROR, FL("pAdapter is NULL"));
4886 return -EPERM;
4887 }
4888 init_completion(&tempContext.completion);
4889 tempContext.pAdapter = pAdapter;
4890 tempContext.magic = TEMP_CONTEXT_MAGIC;
4891 status = sme_get_temperature(WLAN_HDD_GET_HAL_CTX(pAdapter),
4892 &tempContext, hdd_get_temperature_cb);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304893 if (QDF_STATUS_SUCCESS != status) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004894 hddLog(CDF_TRACE_LEVEL_ERROR,
4895 FL("Unable to retrieve temperature"));
4896 } else {
4897 rc = wait_for_completion_timeout(&tempContext.completion,
4898 msecs_to_jiffies
4899 (WLAN_WAIT_TIME_STATS));
4900 if (!rc) {
4901 hddLog(CDF_TRACE_LEVEL_ERROR,
4902 FL
4903 ("SME timed out while retrieving temperature"));
4904 }
4905 }
4906 spin_lock(&hdd_context_lock);
4907 tempContext.magic = 0;
4908 spin_unlock(&hdd_context_lock);
4909 *temperature = pAdapter->temperature;
4910 EXIT();
4911 return 0;
4912}
4913
4914/**
4915 * iw_setint_getnone() - Generic "set integer" private ioctl handler
4916 * @dev: device upon which the ioctl was received
4917 * @info: ioctl request information
4918 * @wrqu: ioctl request data
4919 * @extra: ioctl extra data
4920 *
4921 * Return: 0 on success, non-zero on error
4922 */
4923static int __iw_setint_getnone(struct net_device *dev,
4924 struct iw_request_info *info,
4925 union iwreq_data *wrqu, char *extra)
4926{
4927 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4928 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
4929 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4930 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
4931 hdd_context_t *hdd_ctx;
4932 tSmeConfigParams smeConfig;
4933 int *value = (int *)extra;
4934 int sub_cmd = value[0];
4935 int set_value = value[1];
4936 int ret;
4937 int enable_pbm, enable_mp;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304938 QDF_STATUS status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004939
Hanumantha Reddy Pothula2db50ed2015-11-23 10:48:33 +05304940 ENTER();
4941
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004942 INIT_COMPLETION(pWextState->completion_var);
Mukul Sharma81661ae2015-10-30 20:26:02 +05304943 memset(&smeConfig, 0x00, sizeof(smeConfig));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004944
4945 hdd_ctx = WLAN_HDD_GET_CTX(pAdapter);
4946 ret = wlan_hdd_validate_context(hdd_ctx);
4947 if (0 != ret)
4948 return ret;
4949
4950 switch (sub_cmd) {
4951 case WE_SET_11D_STATE:
4952 {
4953 if ((ENABLE_11D == set_value)
4954 || (DISABLE_11D == set_value)) {
4955
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004956 sme_get_config_param(hHal, &smeConfig);
4957 smeConfig.csrConfig.Is11dSupportEnabled =
4958 (bool) set_value;
4959
4960 CDF_TRACE(CDF_MODULE_ID_HDD,
4961 CDF_TRACE_LEVEL_INFO,
4962 ("11D state=%d!!"),
4963 smeConfig.csrConfig.
4964 Is11dSupportEnabled);
4965
4966 sme_update_config(hHal, &smeConfig);
4967 } else {
4968 return -EINVAL;
4969 }
4970 break;
4971 }
4972
4973 case WE_WOWL:
4974 {
4975 switch (set_value) {
4976 case 0x00:
4977 hdd_exit_wowl(pAdapter);
4978 break;
4979 case 0x01:
4980 case 0x02:
4981 case 0x03:
4982 enable_mp = (set_value & 0x01) ? 1 : 0;
4983 enable_pbm = (set_value & 0x02) ? 1 : 0;
4984 hddLog(LOGE,
4985 "magic packet ? = %s pattern byte matching ? = %s",
4986 (enable_mp ? "YES" : "NO"),
4987 (enable_pbm ? "YES" : "NO"));
4988 hdd_enter_wowl(pAdapter, enable_mp, enable_pbm);
4989 break;
4990 default:
4991 hddLog(LOGE, "Invalid arg %d in WE_WOWL IOCTL",
4992 set_value);
4993 ret = -EINVAL;
4994 break;
4995 }
4996
4997 break;
4998 }
4999 case WE_SET_POWER:
5000 {
5001 switch (set_value) {
5002 case 1:
5003 /* Enable PowerSave */
5004 sme_ps_enable_disable(hHal, pAdapter->sessionId,
5005 SME_PS_ENABLE);
5006 break;
5007 case 2:
5008 /* Disable PowerSave */
5009 sme_ps_enable_disable(hHal, pAdapter->sessionId,
5010 SME_PS_DISABLE);
5011 break;
5012 case 3: /* Enable UASPD */
5013 sme_ps_uapsd_enable(hHal, pAdapter->sessionId);
5014 break;
5015 case 4: /* Disable UASPD */
5016 sme_ps_uapsd_disable(hHal, pAdapter->sessionId);
5017 break;
5018 default:
5019 hddLog(LOGE,
5020 "Invalid arg %d in WE_SET_POWER IOCTL",
5021 set_value);
5022 ret = -EINVAL;
5023 break;
5024 }
5025 break;
5026 }
5027
5028 case WE_SET_MAX_ASSOC:
5029 {
5030 if ((WNI_CFG_ASSOC_STA_LIMIT_STAMIN > set_value) ||
5031 (WNI_CFG_ASSOC_STA_LIMIT_STAMAX < set_value)) {
5032 ret = -EINVAL;
5033 } else if (sme_cfg_set_int(hHal, WNI_CFG_ASSOC_STA_LIMIT,
5034 set_value)
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05305035 != QDF_STATUS_SUCCESS) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005036 CDF_TRACE(CDF_MODULE_ID_HDD,
5037 CDF_TRACE_LEVEL_ERROR, FL
5038 ("failed to set ini parameter, WNI_CFG_ASSOC_STA_LIMIT"));
5039 ret = -EIO;
5040 }
5041 break;
5042 }
5043
5044 case WE_SET_SAP_AUTO_CHANNEL_SELECTION:
5045 if (set_value == 0 || set_value == 1)
5046 (WLAN_HDD_GET_CTX(pAdapter))->config->force_sap_acs =
5047 set_value;
5048 else
5049 ret = -EINVAL;
5050 break;
5051
5052 case WE_SET_DATA_INACTIVITY_TO:
5053 {
5054 if ((set_value < CFG_DATA_INACTIVITY_TIMEOUT_MIN) ||
5055 (set_value > CFG_DATA_INACTIVITY_TIMEOUT_MAX) ||
5056 (sme_cfg_set_int((WLAN_HDD_GET_CTX(pAdapter))->hHal,
5057 WNI_CFG_PS_DATA_INACTIVITY_TIMEOUT,
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05305058 set_value) == QDF_STATUS_E_FAILURE)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005059 hddLog(LOGE, "Failure: Could not pass on "
5060 "WNI_CFG_PS_DATA_INACTIVITY_TIMEOUT configuration info "
5061 "to CCM");
5062 ret = -EINVAL;
5063 }
5064 break;
5065 }
5066 case WE_SET_MC_RATE:
5067 {
5068 ret = wlan_hdd_set_mc_rate(pAdapter, set_value);
5069 break;
5070 }
5071 case WE_SET_TX_POWER:
5072 {
Srinivas Girigowda97215232015-09-24 12:26:28 -07005073 struct cdf_mac_addr bssid;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005074
Srinivas Girigowda97215232015-09-24 12:26:28 -07005075 cdf_copy_macaddr(&bssid, &pHddStaCtx->conn_info.bssId);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005076 if (sme_set_tx_power
5077 (hHal, pAdapter->sessionId, bssid,
5078 pAdapter->device_mode,
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05305079 set_value) != QDF_STATUS_SUCCESS) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005080 hddLog(CDF_TRACE_LEVEL_ERROR,
5081 "%s: Setting tx power failed", __func__);
5082 return -EIO;
5083 }
5084 break;
5085 }
5086 case WE_SET_MAX_TX_POWER:
5087 {
Srinivas Girigowda97215232015-09-24 12:26:28 -07005088 struct cdf_mac_addr bssid;
5089 struct cdf_mac_addr selfMac;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005090
5091 hddLog(CDF_TRACE_LEVEL_INFO,
5092 "%s: Setting maximum tx power %d dBm", __func__,
5093 set_value);
Srinivas Girigowda97215232015-09-24 12:26:28 -07005094 cdf_copy_macaddr(&bssid, &pHddStaCtx->conn_info.bssId);
5095 cdf_copy_macaddr(&selfMac, &pHddStaCtx->conn_info.bssId);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005096
5097 if (sme_set_max_tx_power(hHal, bssid, selfMac, set_value)
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05305098 != QDF_STATUS_SUCCESS) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005099 hddLog(CDF_TRACE_LEVEL_ERROR,
5100 "%s: Setting maximum tx power failed",
5101 __func__);
5102 return -EIO;
5103 }
5104
5105 break;
5106 }
5107 case WE_SET_MAX_TX_POWER_2_4:
5108 {
5109 hddLog(CDF_TRACE_LEVEL_INFO,
5110 "%s: Setting maximum tx power %d dBm for 2.4 GHz band",
5111 __func__, set_value);
5112 if (sme_set_max_tx_power_per_band(eCSR_BAND_24, set_value) !=
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05305113 QDF_STATUS_SUCCESS) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005114 hddLog(CDF_TRACE_LEVEL_ERROR,
5115 "%s: Setting maximum tx power failed for 2.4 GHz band",
5116 __func__);
5117 return -EIO;
5118 }
5119
5120 break;
5121 }
5122 case WE_SET_MAX_TX_POWER_5_0:
5123 {
5124 hddLog(CDF_TRACE_LEVEL_INFO,
5125 "%s: Setting maximum tx power %d dBm for 5.0 GHz band",
5126 __func__, set_value);
5127 if (sme_set_max_tx_power_per_band(eCSR_BAND_5G, set_value) !=
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05305128 QDF_STATUS_SUCCESS) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005129 hddLog(CDF_TRACE_LEVEL_ERROR,
5130 "%s: Setting maximum tx power failed for 5.0 GHz band",
5131 __func__);
5132 return -EIO;
5133 }
5134
5135 break;
5136 }
5137 case WE_SET_HIGHER_DTIM_TRANSITION:
5138 {
5139 if (!((set_value == false) || (set_value == true))) {
5140 hddLog(LOGE, "Dynamic DTIM Incorrect data:%d",
5141 set_value);
5142 ret = -EINVAL;
5143 } else {
5144 if (pAdapter->higherDtimTransition != set_value) {
5145 pAdapter->higherDtimTransition =
5146 set_value;
5147 hddLog(LOG1,
5148 "%s: higherDtimTransition set to :%d",
5149 __func__,
5150 pAdapter->higherDtimTransition);
5151 }
5152 }
5153
5154 break;
5155 }
5156
5157 case WE_SET_TM_LEVEL:
5158 {
5159 hddLog(CDF_TRACE_LEVEL_INFO,
5160 "Set Thermal Mitigation Level %d", set_value);
5161 (void)sme_set_thermal_level(hHal, set_value);
5162 break;
5163 }
5164
5165 case WE_SET_PHYMODE:
5166 {
5167 hdd_context_t *phddctx = WLAN_HDD_GET_CTX(pAdapter);
5168
5169 ret =
5170 wlan_hdd_update_phymode(dev, hHal, set_value,
5171 phddctx);
5172 break;
5173 }
5174
5175 case WE_SET_NSS:
5176 {
5177 hddLog(LOG1, "Set NSS = %d", set_value);
5178 if ((set_value > 2) || (set_value <= 0)) {
5179 hddLog(LOGE, "NSS greater than 2 not supported");
5180 ret = -EINVAL;
5181 } else {
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05305182 if (QDF_STATUS_SUCCESS !=
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005183 hdd_update_nss(WLAN_HDD_GET_CTX(pAdapter),
5184 set_value))
5185 ret = -EINVAL;
5186 }
5187 break;
5188 }
5189
5190 case WE_SET_GTX_HT_MCS:
5191 {
5192 hddLog(LOG1, "WMI_VDEV_PARAM_GTX_HT_MCS %d", set_value);
5193 ret = wma_cli_set_command(pAdapter->sessionId,
5194 WMI_VDEV_PARAM_GTX_HT_MCS,
5195 set_value, GTX_CMD);
5196 break;
5197 }
5198
5199 case WE_SET_GTX_VHT_MCS:
5200 {
5201 hddLog(LOG1, "WMI_VDEV_PARAM_GTX_VHT_MCS %d",
5202 set_value);
5203 ret = wma_cli_set_command(pAdapter->sessionId,
5204 WMI_VDEV_PARAM_GTX_VHT_MCS,
5205 set_value, GTX_CMD);
5206 break;
5207 }
5208
5209 case WE_SET_GTX_USRCFG:
5210 {
5211 hddLog(LOG1, "WMI_VDEV_PARAM_GTX_USR_CFG %d",
5212 set_value);
5213 ret = wma_cli_set_command(pAdapter->sessionId,
5214 WMI_VDEV_PARAM_GTX_USR_CFG,
5215 set_value, GTX_CMD);
5216 break;
5217 }
5218
5219 case WE_SET_GTX_THRE:
5220 {
5221 hddLog(LOG1, "WMI_VDEV_PARAM_GTX_THRE %d", set_value);
5222 ret = wma_cli_set_command(pAdapter->sessionId,
5223 WMI_VDEV_PARAM_GTX_THRE,
5224 set_value, GTX_CMD);
5225 break;
5226 }
5227
5228 case WE_SET_GTX_MARGIN:
5229 {
5230 hddLog(LOG1, "WMI_VDEV_PARAM_GTX_MARGIN %d", set_value);
5231 ret = wma_cli_set_command(pAdapter->sessionId,
5232 WMI_VDEV_PARAM_GTX_MARGIN,
5233 set_value, GTX_CMD);
5234 break;
5235 }
5236
5237 case WE_SET_GTX_STEP:
5238 {
5239 hddLog(LOG1, "WMI_VDEV_PARAM_GTX_STEP %d", set_value);
5240 ret = wma_cli_set_command(pAdapter->sessionId,
5241 WMI_VDEV_PARAM_GTX_STEP,
5242 set_value, GTX_CMD);
5243 break;
5244 }
5245
5246 case WE_SET_GTX_MINTPC:
5247 {
5248 hddLog(LOG1, "WMI_VDEV_PARAM_GTX_MINTPC %d", set_value);
5249 ret = wma_cli_set_command(pAdapter->sessionId,
5250 WMI_VDEV_PARAM_GTX_MINTPC,
5251 set_value, GTX_CMD);
5252 break;
5253 }
5254
5255 case WE_SET_GTX_BWMASK:
5256 {
5257 hddLog(LOG1, "WMI_VDEV_PARAM_GTX_BWMASK %d", set_value);
5258 ret = wma_cli_set_command(pAdapter->sessionId,
5259 WMI_VDEV_PARAM_GTX_BW_MASK,
5260 set_value, GTX_CMD);
5261 break;
5262 }
5263
5264 case WE_SET_LDPC:
5265 {
5266 uint32_t value;
5267 union {
5268 uint16_t nCfgValue16;
5269 tSirMacHTCapabilityInfo htCapInfo;
5270 } uHTCapabilityInfo;
5271
5272 hddLog(LOG1, "LDPC val %d", set_value);
5273 /* get the HT capability info */
5274 ret = sme_cfg_get_int(hHal, WNI_CFG_HT_CAP_INFO, &value);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05305275 if (QDF_STATUS_SUCCESS != ret) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005276 CDF_TRACE(CDF_MODULE_ID_HDD,
5277 CDF_TRACE_LEVEL_ERROR,
5278 "%s: could not get HT capability info",
5279 __func__);
5280 return -EIO;
5281 }
5282
5283 uHTCapabilityInfo.nCfgValue16 = 0xFFFF & value;
5284 if ((set_value
5285 && (uHTCapabilityInfo.htCapInfo.advCodingCap))
5286 || (!set_value)) {
5287 ret =
5288 sme_update_ht_config(hHal,
5289 pAdapter->sessionId,
5290 WNI_CFG_HT_CAP_INFO_ADVANCE_CODING,
5291 set_value);
5292 }
5293
5294 if (ret)
5295 CDF_TRACE(CDF_MODULE_ID_HDD,
5296 CDF_TRACE_LEVEL_ERROR,
5297 "Failed to set LDPC value");
5298
5299 break;
5300 }
5301
5302 case WE_SET_TX_STBC:
5303 {
5304 uint32_t value;
5305 union {
5306 uint16_t nCfgValue16;
5307 tSirMacHTCapabilityInfo htCapInfo;
5308 } uHTCapabilityInfo;
5309
5310 hddLog(LOG1, "TX_STBC val %d", set_value);
5311 /* get the HT capability info */
5312 ret = sme_cfg_get_int(hHal, WNI_CFG_HT_CAP_INFO, &value);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05305313 if (QDF_STATUS_SUCCESS != ret) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005314 CDF_TRACE(CDF_MODULE_ID_HDD,
5315 CDF_TRACE_LEVEL_ERROR,
5316 "%s: could not get HT capability info",
5317 __func__);
5318 return -EIO;
5319 }
5320
5321 uHTCapabilityInfo.nCfgValue16 = 0xFFFF & value;
5322 if ((set_value && (uHTCapabilityInfo.htCapInfo.txSTBC))
5323 || (!set_value)) {
5324 ret =
5325 sme_update_ht_config(hHal,
5326 pAdapter->sessionId,
5327 WNI_CFG_HT_CAP_INFO_TX_STBC,
5328 set_value);
5329 }
5330
5331 if (ret)
5332 CDF_TRACE(CDF_MODULE_ID_HDD,
5333 CDF_TRACE_LEVEL_ERROR,
5334 "Failed to set TX STBC value");
5335
5336 break;
5337 }
5338
5339 case WE_SET_RX_STBC:
5340 {
5341 uint32_t value;
5342 union {
5343 uint16_t nCfgValue16;
5344 tSirMacHTCapabilityInfo htCapInfo;
5345 } uHTCapabilityInfo;
5346
5347 hddLog(LOG1, "WMI_VDEV_PARAM_RX_STBC val %d",
5348 set_value);
5349 /* get the HT capability info */
5350 ret = sme_cfg_get_int(hHal, WNI_CFG_HT_CAP_INFO, &value);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05305351 if (QDF_STATUS_SUCCESS != ret) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005352 CDF_TRACE(CDF_MODULE_ID_CDF,
5353 CDF_TRACE_LEVEL_ERROR,
5354 "%s: could not get HT capability info",
5355 __func__);
5356 return -EIO;
5357 }
5358
5359 uHTCapabilityInfo.nCfgValue16 = 0xFFFF & value;
5360 if ((set_value && (uHTCapabilityInfo.htCapInfo.rxSTBC))
5361 || (!set_value)) {
5362 ret =
5363 sme_update_ht_config(hHal,
5364 pAdapter->sessionId,
5365 WNI_CFG_HT_CAP_INFO_RX_STBC,
5366 (!set_value) ? set_value
5367 : uHTCapabilityInfo.
5368 htCapInfo.rxSTBC);
5369 }
5370
5371 if (ret)
5372 CDF_TRACE(CDF_MODULE_ID_HDD,
5373 CDF_TRACE_LEVEL_ERROR,
5374 "Failed to set RX STBC value");
5375 break;
5376 }
5377
5378 case WE_SET_SHORT_GI:
5379 {
5380 hddLog(LOG1, "WMI_VDEV_PARAM_SGI val %d", set_value);
5381 ret = sme_update_ht_config(hHal, pAdapter->sessionId,
5382 WNI_CFG_HT_CAP_INFO_SHORT_GI_20MHZ,
5383 set_value);
5384 if (ret)
5385 CDF_TRACE(CDF_MODULE_ID_HDD,
5386 CDF_TRACE_LEVEL_ERROR,
5387 "Failed to set ShortGI value");
5388 break;
5389 }
5390
5391 case WE_SET_RTSCTS:
5392 {
5393 uint32_t value;
5394
5395 hddLog(LOG1, "WMI_VDEV_PARAM_ENABLE_RTSCTS val 0x%x",
5396 set_value);
5397
5398 if ((set_value & HDD_RTSCTS_EN_MASK) ==
5399 HDD_RTSCTS_ENABLE)
5400 value =
5401 (WLAN_HDD_GET_CTX(pAdapter))->config->
5402 RTSThreshold;
5403 else if (((set_value & HDD_RTSCTS_EN_MASK) == 0)
5404 || ((set_value & HDD_RTSCTS_EN_MASK) ==
5405 HDD_CTS_ENABLE))
5406 value = WNI_CFG_RTS_THRESHOLD_STAMAX;
5407 else
5408 return -EIO;
5409
5410 ret = wma_cli_set_command(pAdapter->sessionId,
5411 WMI_VDEV_PARAM_ENABLE_RTSCTS,
5412 set_value, VDEV_CMD);
5413 if (!ret) {
5414 if (sme_cfg_set_int
5415 (hHal, WNI_CFG_RTS_THRESHOLD, value) !=
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05305416 QDF_STATUS_SUCCESS) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005417 hddLog(LOGE, "FAILED TO SET RTSCTS");
5418 return -EIO;
5419 }
5420 }
5421
5422 break;
5423 }
5424
5425 case WE_SET_CHWIDTH:
5426 {
5427 bool chwidth = false;
5428 hdd_context_t *phddctx = WLAN_HDD_GET_CTX(pAdapter);
5429 /*updating channel bonding only on 5Ghz */
5430 hddLog(LOG1, "WMI_VDEV_PARAM_CHWIDTH val %d",
5431 set_value);
5432 if (set_value > eHT_CHANNEL_WIDTH_80MHZ) {
5433 hddLog(LOGE,
5434 "Invalid channel width 0->20 1->40 2->80");
5435 return -EINVAL;
5436 }
5437
5438 if ((WNI_CFG_CHANNEL_BONDING_MODE_DISABLE !=
5439 csr_convert_cb_ini_value_to_phy_cb_state(phddctx->config->
5440 nChannelBondingMode5GHz)))
5441 chwidth = true;
5442
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005443 sme_get_config_param(hHal, &smeConfig);
5444 switch (set_value) {
5445 case eHT_CHANNEL_WIDTH_20MHZ:
5446 smeConfig.csrConfig.channelBondingMode5GHz =
5447 WNI_CFG_CHANNEL_BONDING_MODE_DISABLE;
5448 break;
5449 case eHT_CHANNEL_WIDTH_40MHZ:
5450 if (chwidth)
5451 smeConfig.csrConfig.
5452 channelBondingMode5GHz =
5453 phddctx->config->
5454 nChannelBondingMode5GHz;
5455 else
5456 return -EINVAL;
5457
5458 break;
5459#ifdef WLAN_FEATURE_11AC
5460 case eHT_CHANNEL_WIDTH_80MHZ:
5461 if (chwidth)
5462 smeConfig.csrConfig.
5463 channelBondingMode5GHz =
5464 phddctx->config->
5465 nChannelBondingMode5GHz;
5466 else
5467 return -EINVAL;
5468
5469 break;
5470#endif
5471
5472 default:
5473 return -EINVAL;
5474 }
5475
5476 ret = wma_cli_set_command(pAdapter->sessionId,
5477 WMI_VDEV_PARAM_CHWIDTH,
5478 set_value, VDEV_CMD);
5479 if (!ret)
5480 sme_update_config(hHal, &smeConfig);
5481
5482 break;
5483 }
5484
5485 case WE_SET_ANI_EN_DIS:
5486 {
5487 hddLog(LOG1, "WMI_PDEV_PARAM_ANI_ENABLE val %d",
5488 set_value);
5489 ret = wma_cli_set_command(pAdapter->sessionId,
5490 WMI_PDEV_PARAM_ANI_ENABLE,
5491 set_value, PDEV_CMD);
5492 break;
5493 }
5494
5495 case WE_SET_ANI_POLL_PERIOD:
5496 {
5497 hddLog(LOG1, "WMI_PDEV_PARAM_ANI_POLL_PERIOD val %d",
5498 set_value);
5499 ret = wma_cli_set_command(pAdapter->sessionId,
5500 WMI_PDEV_PARAM_ANI_POLL_PERIOD,
5501 set_value, PDEV_CMD);
5502 break;
5503 }
5504
5505 case WE_SET_ANI_LISTEN_PERIOD:
5506 {
5507 hddLog(LOG1, "WMI_PDEV_PARAM_ANI_LISTEN_PERIOD val %d",
5508 set_value);
5509 ret = wma_cli_set_command(pAdapter->sessionId,
5510 WMI_PDEV_PARAM_ANI_LISTEN_PERIOD,
5511 set_value, PDEV_CMD);
5512 break;
5513 }
5514
5515 case WE_SET_ANI_OFDM_LEVEL:
5516 {
5517 hddLog(LOG1, "WMI_PDEV_PARAM_ANI_OFDM_LEVEL val %d",
5518 set_value);
5519 ret = wma_cli_set_command(pAdapter->sessionId,
5520 WMI_PDEV_PARAM_ANI_OFDM_LEVEL,
5521 set_value, PDEV_CMD);
5522 break;
5523 }
5524
5525 case WE_SET_ANI_CCK_LEVEL:
5526 {
5527 hddLog(LOG1, "WMI_PDEV_PARAM_ANI_CCK_LEVEL val %d",
5528 set_value);
5529 ret = wma_cli_set_command(pAdapter->sessionId,
5530 WMI_PDEV_PARAM_ANI_CCK_LEVEL,
5531 set_value, PDEV_CMD);
5532 break;
5533 }
5534
5535 case WE_SET_DYNAMIC_BW:
5536 {
5537 hddLog(LOG1, "WMI_PDEV_PARAM_DYNAMIC_BW val %d",
5538 set_value);
5539 ret = wma_cli_set_command(pAdapter->sessionId,
5540 WMI_PDEV_PARAM_DYNAMIC_BW,
5541 set_value, PDEV_CMD);
5542 break;
5543 }
5544
5545 case WE_SET_CTS_CBW:
5546 {
5547 hddLog(LOG1, "WE_SET_CTS_CBW val %d", set_value);
5548 ret = wma_cli_set_command(pAdapter->sessionId,
5549 WMI_PDEV_PARAM_CTS_CBW,
5550 set_value, PDEV_CMD);
5551 break;
5552 }
5553
5554 case WE_SET_11N_RATE:
5555 {
5556 uint8_t preamble = 0, nss = 0, rix = 0;
5557 hddLog(LOG1, "WMI_VDEV_PARAM_FIXED_RATE val %d",
5558 set_value);
5559
5560 if (set_value != 0xff) {
5561 rix = RC_2_RATE_IDX(set_value);
5562 if (set_value & 0x80) {
5563 preamble = WMI_RATE_PREAMBLE_HT;
5564 nss = HT_RC_2_STREAMS(set_value) - 1;
5565 } else {
5566 nss = 0;
5567 rix = RC_2_RATE_IDX(set_value);
5568 if (set_value & 0x10) {
5569 preamble =
5570 WMI_RATE_PREAMBLE_CCK;
5571 if (rix != 0x3)
5572 /* Enable Short
5573 * preamble always for
5574 * CCK except 1mbps
5575 */
5576 rix |= 0x4;
5577 } else {
5578 preamble =
5579 WMI_RATE_PREAMBLE_OFDM;
5580 }
5581 }
5582 set_value = (preamble << 6) | (nss << 4) | rix;
5583 }
5584 hdd_info("WMI_VDEV_PARAM_FIXED_RATE val %d rix %d preamble %x nss %d",
5585 set_value, rix, preamble, nss);
5586
5587 ret = wma_cli_set_command(pAdapter->sessionId,
5588 WMI_VDEV_PARAM_FIXED_RATE,
5589 set_value, VDEV_CMD);
5590 break;
5591 }
5592
5593 case WE_SET_VHT_RATE:
5594 {
5595 uint8_t preamble = 0, nss = 0, rix = 0;
5596
5597 if (set_value != 0xff) {
5598 rix = RC_2_RATE_IDX_11AC(set_value);
5599 preamble = WMI_RATE_PREAMBLE_VHT;
5600 nss = HT_RC_2_STREAMS_11AC(set_value) - 1;
5601
5602 set_value = (preamble << 6) | (nss << 4) | rix;
5603 }
5604 hdd_info("WMI_VDEV_PARAM_FIXED_RATE val %d rix %d preamble %x nss %d",
5605 set_value, rix, preamble, nss);
5606 ret = wma_cli_set_command(pAdapter->sessionId,
5607 WMI_VDEV_PARAM_FIXED_RATE,
5608 set_value, VDEV_CMD);
5609 break;
5610 }
5611
5612 case WE_SET_AMPDU:
5613 {
5614 hddLog(LOG1, "SET AMPDU val %d", set_value);
5615 ret = wma_cli_set_command(pAdapter->sessionId,
5616 GEN_VDEV_PARAM_AMPDU,
5617 set_value, GEN_CMD);
5618 break;
5619 }
5620
5621 case WE_SET_AMSDU:
5622 {
5623 hddLog(LOG1, "SET AMSDU val %d", set_value);
5624 ret = wma_cli_set_command(pAdapter->sessionId,
5625 GEN_VDEV_PARAM_AMSDU,
5626 set_value, GEN_CMD);
5627 break;
5628 }
5629
5630 case WE_SET_BURST_ENABLE:
5631 {
5632 hddLog(LOG1, "SET Burst enable val %d", set_value);
5633 if ((set_value == 0) || (set_value == 1)) {
5634 ret = wma_cli_set_command(pAdapter->sessionId,
5635 WMI_PDEV_PARAM_BURST_ENABLE,
5636 set_value, PDEV_CMD);
5637 } else
5638 ret = -EINVAL;
5639 break;
5640 }
5641 case WE_SET_BURST_DUR:
5642 {
5643 hddLog(LOG1, "SET Burst duration val %d", set_value);
5644 if ((set_value > 0) && (set_value <= 8192))
5645 ret = wma_cli_set_command(pAdapter->sessionId,
5646 WMI_PDEV_PARAM_BURST_DUR,
5647 set_value, PDEV_CMD);
5648 else
5649 ret = -EINVAL;
5650 break;
5651 }
5652
5653 case WE_SET_TX_CHAINMASK:
5654 {
5655 hddLog(LOG1, "WMI_PDEV_PARAM_TX_CHAIN_MASK val %d",
5656 set_value);
5657 ret = wma_cli_set_command(pAdapter->sessionId,
5658 WMI_PDEV_PARAM_TX_CHAIN_MASK,
5659 set_value, PDEV_CMD);
5660 break;
5661 }
5662
5663 case WE_SET_RX_CHAINMASK:
5664 {
5665 hddLog(LOG1, "WMI_PDEV_PARAM_RX_CHAIN_MASK val %d",
5666 set_value);
5667 ret = wma_cli_set_command(pAdapter->sessionId,
5668 WMI_PDEV_PARAM_RX_CHAIN_MASK,
5669 set_value, PDEV_CMD);
5670 break;
5671 }
5672
5673 case WE_SET_TXPOW_2G:
5674 {
5675 hddLog(LOG1, "WMI_PDEV_PARAM_TXPOWER_LIMIT2G val %d",
5676 set_value);
5677 ret = wma_cli_set_command(pAdapter->sessionId,
5678 WMI_PDEV_PARAM_TXPOWER_LIMIT2G,
5679 set_value, PDEV_CMD);
5680 break;
5681 }
5682
5683 case WE_SET_TXPOW_5G:
5684 {
5685 hddLog(LOG1, "WMI_PDEV_PARAM_TXPOWER_LIMIT5G val %d",
5686 set_value);
5687 ret = wma_cli_set_command(pAdapter->sessionId,
5688 WMI_PDEV_PARAM_TXPOWER_LIMIT5G,
5689 set_value, PDEV_CMD);
5690 break;
5691 }
5692
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005693 /* Firmware debug log */
5694 case WE_DBGLOG_LOG_LEVEL:
5695 {
5696 hddLog(LOG1, "WE_DBGLOG_LOG_LEVEL val %d", set_value);
5697 hdd_ctx->fw_log_settings.dl_loglevel = set_value;
5698 ret = wma_cli_set_command(pAdapter->sessionId,
5699 WMI_DBGLOG_LOG_LEVEL,
5700 set_value, DBG_CMD);
5701 break;
5702 }
5703
5704 case WE_DBGLOG_VAP_ENABLE:
5705 {
5706 hddLog(LOG1, "WE_DBGLOG_VAP_ENABLE val %d", set_value);
5707 ret = wma_cli_set_command(pAdapter->sessionId,
5708 WMI_DBGLOG_VAP_ENABLE,
5709 set_value, DBG_CMD);
5710 break;
5711 }
5712
5713 case WE_DBGLOG_VAP_DISABLE:
5714 {
5715 hddLog(LOG1, "WE_DBGLOG_VAP_DISABLE val %d", set_value);
5716 ret = wma_cli_set_command(pAdapter->sessionId,
5717 WMI_DBGLOG_VAP_DISABLE,
5718 set_value, DBG_CMD);
5719 break;
5720 }
5721
5722 case WE_DBGLOG_MODULE_ENABLE:
5723 {
5724 hddLog(LOG1, "WE_DBGLOG_MODULE_ENABLE val %d",
5725 set_value);
5726 hdd_ctx->fw_log_settings.enable = set_value;
5727 ret = wma_cli_set_command(pAdapter->sessionId,
5728 WMI_DBGLOG_MODULE_ENABLE,
5729 set_value, DBG_CMD);
5730 break;
5731 }
5732
5733 case WE_DBGLOG_MODULE_DISABLE:
5734 {
5735 hddLog(LOG1, "WE_DBGLOG_MODULE_DISABLE val %d",
5736 set_value);
5737 hdd_ctx->fw_log_settings.enable = set_value;
5738 ret = wma_cli_set_command(pAdapter->sessionId,
5739 WMI_DBGLOG_MODULE_DISABLE,
5740 set_value, DBG_CMD);
5741 break;
5742 }
5743 case WE_DBGLOG_MOD_LOG_LEVEL:
5744 {
5745 hddLog(LOG1, "WE_DBGLOG_MOD_LOG_LEVEL val %d",
5746 set_value);
5747
5748 if (hdd_ctx->fw_log_settings.index >= MAX_MOD_LOGLEVEL)
5749 hdd_ctx->fw_log_settings.index = 0;
5750
5751 hdd_ctx->fw_log_settings.
5752 dl_mod_loglevel[hdd_ctx->fw_log_settings.index] =
5753 set_value;
5754 hdd_ctx->fw_log_settings.index++;
5755
5756 ret = wma_cli_set_command(pAdapter->sessionId,
5757 WMI_DBGLOG_MOD_LOG_LEVEL,
5758 set_value, DBG_CMD);
5759 break;
5760 }
5761
5762 case WE_DBGLOG_TYPE:
5763 {
5764 hddLog(LOG1, "WE_DBGLOG_TYPE val %d", set_value);
5765 hdd_ctx->fw_log_settings.dl_type = set_value;
5766 ret = wma_cli_set_command(pAdapter->sessionId,
5767 WMI_DBGLOG_TYPE,
5768 set_value, DBG_CMD);
5769 break;
5770 }
5771 case WE_DBGLOG_REPORT_ENABLE:
5772 {
5773 hddLog(LOG1, "WE_DBGLOG_REPORT_ENABLE val %d",
5774 set_value);
5775 hdd_ctx->fw_log_settings.dl_report = set_value;
5776 ret = wma_cli_set_command(pAdapter->sessionId,
5777 WMI_DBGLOG_REPORT_ENABLE,
5778 set_value, DBG_CMD);
5779 break;
5780 }
5781
5782 case WE_SET_TXRX_FWSTATS:
5783 {
5784 hddLog(LOG1, "WE_SET_TXRX_FWSTATS val %d", set_value);
5785 ret = wma_cli_set_command(pAdapter->sessionId,
5786 WMA_VDEV_TXRX_FWSTATS_ENABLE_CMDID,
5787 set_value, VDEV_CMD);
5788 break;
5789 }
5790
5791 case WE_TXRX_FWSTATS_RESET:
5792 {
5793 hddLog(LOG1, "WE_TXRX_FWSTATS_RESET val %d", set_value);
5794 ret = wma_cli_set_command(pAdapter->sessionId,
5795 WMA_VDEV_TXRX_FWSTATS_RESET_CMDID,
5796 set_value, VDEV_CMD);
5797 break;
5798 }
5799
5800 case WE_DUMP_STATS:
5801 {
5802 hddLog(LOG1, "WE_DUMP_STATS val %d", set_value);
5803 hdd_wlan_dump_stats(pAdapter, set_value);
5804 break;
5805 }
5806
5807 case WE_CLEAR_STATS:
5808 {
5809 hddLog(LOG1, "WE_CLEAR_STATS val %d", set_value);
5810 switch (set_value) {
5811 case WLAN_HDD_STATS:
5812 memset(&pAdapter->stats, 0, sizeof(pAdapter->stats));
5813 memset(&pAdapter->hdd_stats, 0,
5814 sizeof(pAdapter->hdd_stats));
5815 break;
5816 case WLAN_TXRX_HIST_STATS:
5817 wlan_hdd_clear_tx_rx_histogram(hdd_ctx);
5818 break;
5819 case WLAN_HDD_NETIF_OPER_HISTORY:
5820 wlan_hdd_clear_netif_queue_history(hdd_ctx);
5821 break;
5822 default:
5823 ol_txrx_clear_stats(set_value);
5824 }
5825 break;
5826 }
5827
5828 case WE_PPS_PAID_MATCH:
5829 {
5830 if (pAdapter->device_mode != WLAN_HDD_INFRA_STATION)
5831 return EINVAL;
5832
5833 hddLog(LOG1, "WMI_VDEV_PPS_PAID_MATCH val %d ",
5834 set_value);
5835 ret = wma_cli_set_command(pAdapter->sessionId,
5836 WMI_VDEV_PPS_PAID_MATCH,
5837 set_value, PPS_CMD);
5838 break;
5839 }
5840
5841 case WE_PPS_GID_MATCH:
5842 {
5843 if (pAdapter->device_mode != WLAN_HDD_INFRA_STATION)
5844 return EINVAL;
5845 hddLog(LOG1, "WMI_VDEV_PPS_GID_MATCH val %d ",
5846 set_value);
5847 ret = wma_cli_set_command(pAdapter->sessionId,
5848 WMI_VDEV_PPS_GID_MATCH,
5849 set_value, PPS_CMD);
5850 break;
5851 }
5852
5853 case WE_PPS_EARLY_TIM_CLEAR:
5854 {
5855 if (pAdapter->device_mode != WLAN_HDD_INFRA_STATION)
5856 return EINVAL;
5857 hddLog(LOG1, " WMI_VDEV_PPS_EARLY_TIM_CLEAR val %d ",
5858 set_value);
5859 ret = wma_cli_set_command(pAdapter->sessionId,
5860 WMI_VDEV_PPS_EARLY_TIM_CLEAR,
5861 set_value, PPS_CMD);
5862 break;
5863 }
5864
5865 case WE_PPS_EARLY_DTIM_CLEAR:
5866 {
5867 if (pAdapter->device_mode != WLAN_HDD_INFRA_STATION)
5868 return EINVAL;
5869 hddLog(LOG1, "WMI_VDEV_PPS_EARLY_DTIM_CLEAR val %d",
5870 set_value);
5871 ret = wma_cli_set_command(pAdapter->sessionId,
5872 WMI_VDEV_PPS_EARLY_DTIM_CLEAR,
5873 set_value, PPS_CMD);
5874 break;
5875 }
5876
5877 case WE_PPS_EOF_PAD_DELIM:
5878 {
5879 if (pAdapter->device_mode != WLAN_HDD_INFRA_STATION)
5880 return EINVAL;
5881 hddLog(LOG1, "WMI_VDEV_PPS_EOF_PAD_DELIM val %d ",
5882 set_value);
5883 ret = wma_cli_set_command(pAdapter->sessionId,
5884 WMI_VDEV_PPS_EOF_PAD_DELIM,
5885 set_value, PPS_CMD);
5886 break;
5887 }
5888
5889 case WE_PPS_MACADDR_MISMATCH:
5890 {
5891 if (pAdapter->device_mode != WLAN_HDD_INFRA_STATION)
5892 return EINVAL;
5893 hddLog(LOG1, "WMI_VDEV_PPS_MACADDR_MISMATCH val %d ",
5894 set_value);
5895 ret = wma_cli_set_command(pAdapter->sessionId,
5896 WMI_VDEV_PPS_MACADDR_MISMATCH,
5897 set_value, PPS_CMD);
5898 break;
5899 }
5900
5901 case WE_PPS_DELIM_CRC_FAIL:
5902 {
5903 if (pAdapter->device_mode != WLAN_HDD_INFRA_STATION)
5904 return EINVAL;
5905 hddLog(LOG1, "WMI_VDEV_PPS_DELIM_CRC_FAIL val %d ",
5906 set_value);
5907 ret = wma_cli_set_command(pAdapter->sessionId,
5908 WMI_VDEV_PPS_DELIM_CRC_FAIL,
5909 set_value, PPS_CMD);
5910 break;
5911 }
5912
5913 case WE_PPS_GID_NSTS_ZERO:
5914 {
5915 if (pAdapter->device_mode != WLAN_HDD_INFRA_STATION)
5916 return EINVAL;
5917 hddLog(LOG1, "WMI_VDEV_PPS_GID_NSTS_ZERO val %d ",
5918 set_value);
5919 ret = wma_cli_set_command(pAdapter->sessionId,
5920 WMI_VDEV_PPS_GID_NSTS_ZERO,
5921 set_value, PPS_CMD);
5922 break;
5923 }
5924
5925 case WE_PPS_RSSI_CHECK:
5926 {
5927 if (pAdapter->device_mode != WLAN_HDD_INFRA_STATION)
5928 return EINVAL;
5929 hddLog(LOG1, "WMI_VDEV_PPS_RSSI_CHECK val %d ",
5930 set_value);
5931 ret = wma_cli_set_command(pAdapter->sessionId,
5932 WMI_VDEV_PPS_RSSI_CHECK,
5933 set_value, PPS_CMD);
5934 break;
5935 }
5936
5937 case WE_PPS_5G_EBT:
5938 {
5939 if (pAdapter->device_mode != WLAN_HDD_INFRA_STATION)
5940 return -EINVAL;
5941
5942 hddLog(LOG1, "WMI_VDEV_PPS_5G_EBT val %d", set_value);
5943 ret = wma_cli_set_command(pAdapter->sessionId,
5944 WMI_VDEV_PPS_5G_EBT,
5945 set_value, PPS_CMD);
5946 break;
5947 }
5948
5949 case WE_SET_HTSMPS:
5950 {
5951 hddLog(LOG1, "WE_SET_HTSMPS val %d", set_value);
5952 ret = wma_cli_set_command(pAdapter->sessionId,
5953 WMI_STA_SMPS_FORCE_MODE_CMDID,
5954 set_value, VDEV_CMD);
5955 break;
5956 }
5957
5958 case WE_SET_QPOWER_MAX_PSPOLL_COUNT:
5959 {
5960 hddLog(LOG1, "WE_SET_QPOWER_MAX_PSPOLL_COUNT val %d",
5961 set_value);
5962 ret = wma_cli_set_command(pAdapter->sessionId,
5963 WMI_STA_PS_PARAM_QPOWER_PSPOLL_COUNT,
5964 set_value, QPOWER_CMD);
5965 break;
5966 }
5967
5968 case WE_SET_QPOWER_MAX_TX_BEFORE_WAKE:
5969 {
5970 hddLog(LOG1, "WE_SET_QPOWER_MAX_TX_BEFORE_WAKE val %d",
5971 set_value);
5972 ret = wma_cli_set_command(
5973 pAdapter->sessionId,
5974 WMI_STA_PS_PARAM_QPOWER_MAX_TX_BEFORE_WAKE,
5975 set_value, QPOWER_CMD);
5976 break;
5977 }
5978
5979 case WE_SET_QPOWER_SPEC_PSPOLL_WAKE_INTERVAL:
5980 {
5981 hddLog(LOG1,
5982 "WE_SET_QPOWER_SPEC_PSPOLL_WAKE_INTERVAL val %d",
5983 set_value);
5984 ret = wma_cli_set_command(
5985 pAdapter->sessionId,
5986 WMI_STA_PS_PARAM_QPOWER_SPEC_PSPOLL_WAKE_INTERVAL,
5987 set_value, QPOWER_CMD);
5988 break;
5989 }
5990
5991 case WE_SET_QPOWER_SPEC_MAX_SPEC_NODATA_PSPOLL:
5992 {
5993 hddLog(LOG1,
5994 "WE_SET_QPOWER_SPEC_MAX_SPEC_NODATA_PSPOLL val %d",
5995 set_value);
5996 ret = wma_cli_set_command(
5997 pAdapter->sessionId,
5998 WMI_STA_PS_PARAM_QPOWER_SPEC_MAX_SPEC_NODATA_PSPOLL,
5999 set_value, QPOWER_CMD);
6000 break;
6001 }
6002
6003 case WE_MCC_CONFIG_LATENCY:
6004 {
6005 cds_set_mcc_latency(pAdapter, set_value);
6006 break;
6007 }
6008
6009 case WE_MCC_CONFIG_QUOTA:
6010 {
6011 hddLog(LOG1, "iwpriv cmd to set MCC quota with val %dms",
6012 set_value);
6013 ret = cds_set_mcc_p2p_quota(pAdapter, set_value);
6014 break;
6015 }
6016 case WE_SET_DEBUG_LOG:
6017 {
6018 hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(pAdapter);
6019#ifdef QCA_PKT_PROTO_TRACE
6020 /* Trace buffer dump only */
6021 if (CDS_PKT_TRAC_DUMP_CMD == set_value) {
6022 cds_pkt_trace_buf_dump();
6023 break;
6024 }
6025#endif /* QCA_PKT_PROTO_TRACE */
6026 hdd_ctx->config->gEnableDebugLog = set_value;
6027 sme_update_connect_debug(hdd_ctx->hHal, set_value);
6028 break;
6029 }
6030 case WE_SET_EARLY_RX_ADJUST_ENABLE:
6031 {
6032 hddLog(LOG1, "SET early_rx enable val %d", set_value);
6033 if ((set_value == 0) || (set_value == 1))
6034 ret = wma_cli_set_command(
6035 pAdapter->sessionId,
6036 WMI_VDEV_PARAM_EARLY_RX_ADJUST_ENABLE,
6037 set_value, VDEV_CMD);
6038 else
6039 ret = -EINVAL;
6040 break;
6041 }
6042 case WE_SET_EARLY_RX_TGT_BMISS_NUM:
6043 {
6044 hddLog(LOG1, "SET early_rx bmiss val %d", set_value);
6045 ret = wma_cli_set_command(pAdapter->sessionId,
6046 WMI_VDEV_PARAM_EARLY_RX_TGT_BMISS_NUM,
6047 set_value, VDEV_CMD);
6048 break;
6049 }
6050 case WE_SET_EARLY_RX_BMISS_SAMPLE_CYCLE:
6051 {
6052 hddLog(LOG1, "SET early_rx bmiss sample cycle %d",
6053 set_value);
6054 ret = wma_cli_set_command(
6055 pAdapter->sessionId,
6056 WMI_VDEV_PARAM_EARLY_RX_BMISS_SAMPLE_CYCLE,
6057 set_value, VDEV_CMD);
6058 break;
6059 }
6060 case WE_SET_EARLY_RX_SLOP_STEP:
6061 {
6062 hddLog(LOG1, "SET early_rx bmiss slop step val %d",
6063 set_value);
6064 ret = wma_cli_set_command(pAdapter->sessionId,
6065 WMI_VDEV_PARAM_EARLY_RX_SLOP_STEP,
6066 set_value, VDEV_CMD);
6067 break;
6068 }
6069 case WE_SET_EARLY_RX_INIT_SLOP:
6070 {
6071 hddLog(LOG1, "SET early_rx init slop step val %d",
6072 set_value);
6073 ret = wma_cli_set_command(pAdapter->sessionId,
6074 WMI_VDEV_PARAM_EARLY_RX_INIT_SLOP,
6075 set_value, VDEV_CMD);
6076 break;
6077 }
6078 case WE_SET_EARLY_RX_ADJUST_PAUSE:
6079 {
6080 hddLog(LOG1, "SET early_rx adjust pause %d", set_value);
6081 if ((set_value == 0) || (set_value == 1))
6082 ret = wma_cli_set_command(
6083 pAdapter->sessionId,
6084 WMI_VDEV_PARAM_EARLY_RX_ADJUST_PAUSE,
6085 set_value, VDEV_CMD);
6086 else
6087 ret = -EINVAL;
6088 break;
6089 }
6090 case WE_SET_EARLY_RX_DRIFT_SAMPLE:
6091 {
6092 hddLog(LOG1, "SET early_rx drift sample %d", set_value);
6093 ret = wma_cli_set_command(pAdapter->sessionId,
6094 WMI_VDEV_PARAM_EARLY_RX_DRIFT_SAMPLE,
6095 set_value, VDEV_CMD);
6096 break;
6097 }
6098 case WE_SET_SCAN_DISABLE:
6099 {
6100 hddLog(LOG1, "SET SCAN DISABLE %d", set_value);
6101 sme_set_scan_disable(WLAN_HDD_GET_HAL_CTX(pAdapter), set_value);
6102 break;
6103 }
Govind Singha471e5e2015-10-12 17:11:14 +05306104 case WE_START_FW_PROFILE:
6105 {
6106 hddLog(LOG1, "WE_START_FW_PROFILE %d", set_value);
6107 ret = wma_cli_set_command(pAdapter->sessionId,
6108 WMI_WLAN_PROFILE_TRIGGER_CMDID,
6109 set_value, DBG_CMD);
6110 break;
6111 }
Abhishek Singh1bdb1572015-10-16 16:24:19 +05306112 case WE_SET_CHANNEL:
6113 {
6114 hddLog(LOG1, "Set Channel %d Session ID %d mode %d", set_value,
6115 pAdapter->sessionId, pAdapter->device_mode);
6116
6117 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
6118 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode)) {
6119
6120 status = sme_ext_change_channel(hHal,
6121 set_value, pAdapter->sessionId);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05306122 if (status != QDF_STATUS_SUCCESS) {
Abhishek Singh1bdb1572015-10-16 16:24:19 +05306123 hddLog(LOGE,
6124 FL("Error in change channel status %d"),
6125 status);
6126 ret = -EINVAL;
6127 }
6128 } else {
6129 hddLog(LOGE,
6130 FL("change channel not supported for device mode %d"),
6131 pAdapter->device_mode);
6132 ret = -EINVAL;
6133 }
6134 break;
6135 }
6136
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006137 default:
6138 {
6139 hddLog(LOGE, "%s: Invalid sub command %d", __func__,
6140 sub_cmd);
6141 ret = -EINVAL;
6142 break;
6143 }
6144 }
Hanumantha Reddy Pothula2db50ed2015-11-23 10:48:33 +05306145 EXIT();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006146 return ret;
6147}
6148
6149static int iw_setint_getnone(struct net_device *dev,
6150 struct iw_request_info *info,
6151 union iwreq_data *wrqu,
6152 char *extra)
6153{
6154 int ret;
6155
6156 cds_ssr_protect(__func__);
6157 ret = __iw_setint_getnone(dev, info, wrqu, extra);
6158 cds_ssr_unprotect(__func__);
6159
6160 return ret;
6161}
6162
6163/**
6164 * iw_setchar_getnone() - Generic "set string" private ioctl handler
6165 * @dev: device upon which the ioctl was received
6166 * @info: ioctl request information
6167 * @wrqu: ioctl request data
6168 * @extra: ioctl extra data
6169 *
6170 * Return: 0 on success, non-zero on error
6171 */
6172static int __iw_setchar_getnone(struct net_device *dev,
6173 struct iw_request_info *info,
6174 union iwreq_data *wrqu, char *extra)
6175{
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05306176 QDF_STATUS vstatus;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006177 int sub_cmd;
6178 int ret;
6179 char *pBuffer = NULL;
6180 hdd_adapter_t *pAdapter = (netdev_priv(dev));
6181 hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(pAdapter);
6182#ifdef WLAN_FEATURE_VOWIFI
6183 struct hdd_config *pConfig = hdd_ctx->config;
6184#endif /* WLAN_FEATURE_VOWIFI */
6185 struct iw_point s_priv_data;
6186
Mukul Sharma34777c62015-11-02 20:22:30 +05306187 if (!capable(CAP_NET_ADMIN)) {
6188 CDF_TRACE(CDF_MODULE_ID_HDD, CDF_TRACE_LEVEL_ERROR,
6189 FL("permission check failed"));
6190 return -EPERM;
6191 }
6192
Hanumantha Reddy Pothula2db50ed2015-11-23 10:48:33 +05306193 ENTER();
6194
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006195 ret = wlan_hdd_validate_context(hdd_ctx);
6196 if (0 != ret)
6197 return ret;
6198
6199 /* helper function to get iwreq_data with compat handling. */
6200 if (hdd_priv_get_data(&s_priv_data, wrqu)) {
6201 return -EINVAL;
6202 }
6203
6204 /* make sure all params are correctly passed to function */
6205 if ((NULL == s_priv_data.pointer) || (0 == s_priv_data.length)) {
6206 return -EINVAL;
6207 }
6208
6209 sub_cmd = s_priv_data.flags;
6210
6211 /* ODD number is used for set, copy data using copy_from_user */
6212 pBuffer = mem_alloc_copy_from_user_helper(s_priv_data.pointer,
6213 s_priv_data.length);
6214 if (NULL == pBuffer) {
6215 CDF_TRACE(CDF_MODULE_ID_HDD, CDF_TRACE_LEVEL_ERROR,
6216 "mem_alloc_copy_from_user_helper fail");
6217 return -ENOMEM;
6218 }
6219
6220 CDF_TRACE(CDF_MODULE_ID_HDD, CDF_TRACE_LEVEL_INFO,
6221 "%s: Received length %d", __func__, s_priv_data.length);
6222 CDF_TRACE(CDF_MODULE_ID_HDD, CDF_TRACE_LEVEL_INFO,
6223 "%s: Received data %s", __func__, pBuffer);
6224
6225 switch (sub_cmd) {
6226 case WE_WOWL_ADD_PTRN:
6227 CDF_TRACE(CDF_MODULE_ID_HDD, CDF_TRACE_LEVEL_INFO, "ADD_PTRN");
6228 hdd_add_wowl_ptrn(pAdapter, pBuffer);
6229 break;
6230 case WE_WOWL_DEL_PTRN:
6231 CDF_TRACE(CDF_MODULE_ID_HDD, CDF_TRACE_LEVEL_INFO, "DEL_PTRN");
6232 hdd_del_wowl_ptrn(pAdapter, pBuffer);
6233 break;
6234#if defined WLAN_FEATURE_VOWIFI
6235 case WE_NEIGHBOR_REPORT_REQUEST:
6236 {
6237 tRrmNeighborReq neighborReq;
6238 tRrmNeighborRspCallbackInfo callbackInfo;
6239
6240 if (pConfig->fRrmEnable) {
6241 CDF_TRACE(CDF_MODULE_ID_HDD,
6242 CDF_TRACE_LEVEL_INFO,
6243 "Neighbor Request");
6244 neighborReq.no_ssid =
6245 (s_priv_data.length - 1) ? false : true;
6246 if (!neighborReq.no_ssid) {
6247 neighborReq.ssid.length =
6248 (s_priv_data.length - 1) >
6249 32 ? 32 : (s_priv_data.length - 1);
6250 cdf_mem_copy(neighborReq.ssid.ssId,
6251 pBuffer,
6252 neighborReq.ssid.length);
6253 }
6254
6255 callbackInfo.neighborRspCallback = NULL;
6256 callbackInfo.neighborRspCallbackContext = NULL;
6257 callbackInfo.timeout = 5000; /* 5 seconds */
6258 sme_neighbor_report_request(WLAN_HDD_GET_HAL_CTX
6259 (pAdapter),
6260 pAdapter->sessionId,
6261 &neighborReq,
6262 &callbackInfo);
6263 } else {
6264 hddLog(LOGE,
6265 "%s: Ignoring neighbor request as RRM is not enabled",
6266 __func__);
6267 ret = -EINVAL;
6268 }
6269 }
6270 break;
6271#endif
6272 case WE_SET_AP_WPS_IE:
6273 hddLog(LOGE, "Received WE_SET_AP_WPS_IE");
6274 sme_update_p2p_ie(WLAN_HDD_GET_HAL_CTX(pAdapter), pBuffer,
6275 s_priv_data.length);
6276 break;
6277 case WE_SET_CONFIG:
6278 vstatus = hdd_execute_global_config_command(hdd_ctx, pBuffer);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05306279 if (QDF_STATUS_SUCCESS != vstatus) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006280 ret = -EINVAL;
6281 }
6282 break;
6283 default:
6284 {
6285 hddLog(LOGE, "%s: Invalid sub command %d", __func__,
6286 sub_cmd);
6287 ret = -EINVAL;
6288 break;
6289 }
6290 }
6291 kfree(pBuffer);
Hanumantha Reddy Pothula2db50ed2015-11-23 10:48:33 +05306292 EXIT();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006293 return ret;
6294}
6295
6296static int iw_setchar_getnone(struct net_device *dev,
6297 struct iw_request_info *info,
6298 union iwreq_data *wrqu, char *extra)
6299{
6300 int ret;
6301
6302 cds_ssr_protect(__func__);
6303 ret = __iw_setchar_getnone(dev, info, wrqu, extra);
6304 cds_ssr_unprotect(__func__);
6305
6306 return ret;
6307}
6308
6309/**
6310 * iw_setnone_getint() - Generic "get integer" private ioctl handler
6311 * @dev: device upon which the ioctl was received
6312 * @info: ioctl request information
6313 * @wrqu: ioctl request data
6314 * @extra: ioctl extra data
6315 *
6316 * Return: 0 on success, non-zero on error
6317 */
6318static int __iw_setnone_getint(struct net_device *dev,
6319 struct iw_request_info *info,
6320 union iwreq_data *wrqu, char *extra)
6321{
6322 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6323 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
6324 int *value = (int *)extra;
6325 int ret;
6326 tSmeConfigParams smeConfig;
6327 hdd_context_t *hdd_ctx;
6328
Hanumantha Reddy Pothula2db50ed2015-11-23 10:48:33 +05306329 ENTER();
6330
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006331 hdd_ctx = WLAN_HDD_GET_CTX(pAdapter);
6332 ret = wlan_hdd_validate_context(hdd_ctx);
6333 if (0 != ret)
6334 return ret;
6335
6336 switch (value[0]) {
6337 case WE_GET_11D_STATE:
6338 {
6339 sme_get_config_param(hHal, &smeConfig);
6340
6341 *value = smeConfig.csrConfig.Is11dSupportEnabled;
6342
6343 CDF_TRACE(CDF_MODULE_ID_HDD, CDF_TRACE_LEVEL_INFO,
6344 ("11D state=%d!!"), *value);
6345
6346 break;
6347 }
6348
6349 case WE_IBSS_STATUS:
6350 CDF_TRACE(CDF_MODULE_ID_HDD, CDF_TRACE_LEVEL_INFO,
6351 "****Return IBSS Status*****");
6352 break;
6353
6354 case WE_GET_WLAN_DBG:
6355 {
6356 cdf_trace_display();
6357 *value = 0;
6358 break;
6359 }
6360 case WE_GET_MAX_ASSOC:
6361 {
6362 if (sme_cfg_get_int
6363 (hHal, WNI_CFG_ASSOC_STA_LIMIT,
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05306364 (uint32_t *) value) != QDF_STATUS_SUCCESS) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006365 CDF_TRACE(CDF_MODULE_ID_HDD,
6366 CDF_TRACE_LEVEL_WARN, FL
6367 ("failed to get ini parameter, WNI_CFG_ASSOC_STA_LIMIT"));
6368 ret = -EIO;
6369 }
6370 break;
6371 }
6372 case WE_GET_SAP_AUTO_CHANNEL_SELECTION:
6373 *value = (WLAN_HDD_GET_CTX(
6374 pAdapter))->config->force_sap_acs;
6375 break;
6376
6377 case WE_GET_CONCURRENCY_MODE:
6378 {
6379 *value = cds_get_concurrency_mode();
6380
6381 CDF_TRACE(CDF_MODULE_ID_HDD, CDF_TRACE_LEVEL_INFO,
6382 ("concurrency mode=%d"), *value);
6383 break;
6384 }
6385
6386 case WE_GET_NSS:
6387 {
6388 sme_get_config_param(hHal, &smeConfig);
6389 *value = (smeConfig.csrConfig.enable2x2 == 0) ? 1 : 2;
6390 hddLog(LOG1, "GET_NSS: Current NSS:%d", *value);
6391 break;
6392 }
6393
6394 case WE_GET_GTX_HT_MCS:
6395 {
6396 hddLog(LOG1, "GET WMI_VDEV_PARAM_GTX_HT_MCS");
6397 *value = wma_cli_get_command(pAdapter->sessionId,
6398 WMI_VDEV_PARAM_GTX_HT_MCS,
6399 GTX_CMD);
6400 break;
6401 }
6402
6403 case WE_GET_GTX_VHT_MCS:
6404 {
6405 hddLog(LOG1, "GET WMI_VDEV_PARAM_GTX_VHT_MCS");
6406 *value = wma_cli_get_command(pAdapter->sessionId,
6407 WMI_VDEV_PARAM_GTX_VHT_MCS,
6408 GTX_CMD);
6409 break;
6410 }
6411
6412 case WE_GET_GTX_USRCFG:
6413 {
6414 hddLog(LOG1, "GET WMI_VDEV_PARAM_GTX_USR_CFG");
6415 *value = wma_cli_get_command(pAdapter->sessionId,
6416 WMI_VDEV_PARAM_GTX_USR_CFG,
6417 GTX_CMD);
6418 break;
6419 }
6420
6421 case WE_GET_GTX_THRE:
6422 {
6423 hddLog(LOG1, "GET WMI_VDEV_PARAM_GTX_THRE");
6424 *value = wma_cli_get_command(pAdapter->sessionId,
6425 WMI_VDEV_PARAM_GTX_THRE,
6426 GTX_CMD);
6427 break;
6428 }
6429
6430 case WE_GET_GTX_MARGIN:
6431 {
6432 hddLog(LOG1, "GET WMI_VDEV_PARAM_GTX_MARGIN");
6433 *value = wma_cli_get_command(pAdapter->sessionId,
6434 WMI_VDEV_PARAM_GTX_MARGIN,
6435 GTX_CMD);
6436 break;
6437 }
6438
6439 case WE_GET_GTX_STEP:
6440 {
6441 hddLog(LOG1, "GET WMI_VDEV_PARAM_GTX_STEP");
6442 *value = wma_cli_get_command(pAdapter->sessionId,
6443 WMI_VDEV_PARAM_GTX_STEP,
6444 GTX_CMD);
6445 break;
6446 }
6447
6448 case WE_GET_GTX_MINTPC:
6449 {
6450 hddLog(LOG1, "GET WMI_VDEV_PARAM_GTX_MINTPC");
6451 *value = wma_cli_get_command(pAdapter->sessionId,
6452 WMI_VDEV_PARAM_GTX_MINTPC,
6453 GTX_CMD);
6454 break;
6455 }
6456
6457 case WE_GET_GTX_BWMASK:
6458 {
6459 hddLog(LOG1, "GET WMI_VDEV_PARAM_GTX_BW_MASK");
6460 *value = wma_cli_get_command(pAdapter->sessionId,
6461 WMI_VDEV_PARAM_GTX_BW_MASK,
6462 GTX_CMD);
6463 break;
6464 }
6465
6466 case WE_GET_LDPC:
6467 {
6468 hddLog(LOG1, "GET WMI_VDEV_PARAM_LDPC");
6469 *value = sme_get_ht_config(hHal, pAdapter->sessionId,
6470 WNI_CFG_HT_CAP_INFO_ADVANCE_CODING);
6471 break;
6472 }
6473
6474 case WE_GET_TX_STBC:
6475 {
6476 hddLog(LOG1, "GET WMI_VDEV_PARAM_TX_STBC");
6477 *value = sme_get_ht_config(hHal, pAdapter->sessionId,
6478 WNI_CFG_HT_CAP_INFO_TX_STBC);
6479 break;
6480 }
6481
6482 case WE_GET_RX_STBC:
6483 {
6484 hddLog(LOG1, "GET WMI_VDEV_PARAM_RX_STBC");
6485 *value = sme_get_ht_config(hHal, pAdapter->sessionId,
6486 WNI_CFG_HT_CAP_INFO_RX_STBC);
6487 break;
6488 }
6489
6490 case WE_GET_SHORT_GI:
6491 {
6492 hddLog(LOG1, "GET WMI_VDEV_PARAM_SGI");
6493 *value = sme_get_ht_config(hHal, pAdapter->sessionId,
6494 WNI_CFG_HT_CAP_INFO_SHORT_GI_20MHZ);
6495 break;
6496 }
6497
6498 case WE_GET_RTSCTS:
6499 {
6500 hddLog(LOG1, "GET WMI_VDEV_PARAM_ENABLE_RTSCTS");
6501 *value = wma_cli_get_command(pAdapter->sessionId,
6502 WMI_VDEV_PARAM_ENABLE_RTSCTS,
6503 VDEV_CMD);
6504 break;
6505 }
6506
6507 case WE_GET_CHWIDTH:
6508 {
6509 hddLog(LOG1, "GET WMI_VDEV_PARAM_CHWIDTH");
6510 *value = wma_cli_get_command(pAdapter->sessionId,
6511 WMI_VDEV_PARAM_CHWIDTH,
6512 VDEV_CMD);
6513 break;
6514 }
6515
6516 case WE_GET_ANI_EN_DIS:
6517 {
6518 hddLog(LOG1, "GET WMI_PDEV_PARAM_ANI_ENABLE");
6519 *value = wma_cli_get_command(pAdapter->sessionId,
6520 WMI_PDEV_PARAM_ANI_ENABLE,
6521 PDEV_CMD);
6522 break;
6523 }
6524
6525 case WE_GET_ANI_POLL_PERIOD:
6526 {
6527 hddLog(LOG1, "GET WMI_PDEV_PARAM_ANI_POLL_PERIOD");
6528 *value = wma_cli_get_command(pAdapter->sessionId,
6529 WMI_PDEV_PARAM_ANI_POLL_PERIOD,
6530 PDEV_CMD);
6531 break;
6532 }
6533
6534 case WE_GET_ANI_LISTEN_PERIOD:
6535 {
6536 hddLog(LOG1, "GET WMI_PDEV_PARAM_ANI_LISTEN_PERIOD");
6537 *value = wma_cli_get_command(pAdapter->sessionId,
6538 WMI_PDEV_PARAM_ANI_LISTEN_PERIOD,
6539 PDEV_CMD);
6540 break;
6541 }
6542
6543 case WE_GET_ANI_OFDM_LEVEL:
6544 {
6545 hddLog(LOG1, "GET WMI_PDEV_PARAM_ANI_OFDM_LEVEL");
6546 *value = wma_cli_get_command(pAdapter->sessionId,
6547 WMI_PDEV_PARAM_ANI_OFDM_LEVEL,
6548 PDEV_CMD);
6549 break;
6550 }
6551
6552 case WE_GET_ANI_CCK_LEVEL:
6553 {
6554 hddLog(LOG1, "GET WMI_PDEV_PARAM_ANI_CCK_LEVEL");
6555 *value = wma_cli_get_command(pAdapter->sessionId,
6556 WMI_PDEV_PARAM_ANI_CCK_LEVEL,
6557 PDEV_CMD);
6558 break;
6559 }
6560
6561 case WE_GET_DYNAMIC_BW:
6562 {
6563 hddLog(LOG1, "GET WMI_PDEV_PARAM_ANI_CCK_LEVEL");
6564 *value = wma_cli_get_command(pAdapter->sessionId,
6565 WMI_PDEV_PARAM_DYNAMIC_BW,
6566 PDEV_CMD);
6567 break;
6568 }
6569
6570 case WE_GET_11N_RATE:
6571 {
6572 hddLog(LOG1, "GET WMI_VDEV_PARAM_FIXED_RATE");
6573 *value = wma_cli_get_command(pAdapter->sessionId,
6574 WMI_VDEV_PARAM_FIXED_RATE,
6575 VDEV_CMD);
6576 break;
6577 }
6578
6579 case WE_GET_AMPDU:
6580 {
6581 hddLog(LOG1, "GET AMPDU");
6582 *value = wma_cli_get_command(pAdapter->sessionId,
6583 GEN_VDEV_PARAM_AMPDU,
6584 GEN_CMD);
6585 break;
6586 }
6587
6588 case WE_GET_AMSDU:
6589 {
6590 hddLog(LOG1, "GET AMSDU");
6591 *value = wma_cli_get_command(pAdapter->sessionId,
6592 GEN_VDEV_PARAM_AMSDU,
6593 GEN_CMD);
6594 break;
6595 }
6596
6597 case WE_GET_BURST_ENABLE:
6598 {
6599 hddLog(LOG1, "GET Burst enable value");
6600 *value = wma_cli_get_command(pAdapter->sessionId,
6601 WMI_PDEV_PARAM_BURST_ENABLE,
6602 PDEV_CMD);
6603 break;
6604 }
6605 case WE_GET_BURST_DUR:
6606 {
6607 hddLog(LOG1, "GET Burst Duration value");
6608 *value = wma_cli_get_command(pAdapter->sessionId,
6609 WMI_PDEV_PARAM_BURST_DUR,
6610 PDEV_CMD);
6611 break;
6612 }
6613
6614 case WE_GET_TX_CHAINMASK:
6615 {
6616 hddLog(LOG1, "GET WMI_PDEV_PARAM_TX_CHAIN_MASK");
6617 *value = wma_cli_get_command(pAdapter->sessionId,
6618 WMI_PDEV_PARAM_TX_CHAIN_MASK,
6619 PDEV_CMD);
6620 break;
6621 }
6622
6623 case WE_GET_RX_CHAINMASK:
6624 {
6625 hddLog(LOG1, "GET WMI_PDEV_PARAM_RX_CHAIN_MASK");
6626 *value = wma_cli_get_command(pAdapter->sessionId,
6627 WMI_PDEV_PARAM_RX_CHAIN_MASK,
6628 PDEV_CMD);
6629 break;
6630 }
6631
6632 case WE_GET_TXPOW_2G:
6633 {
6634 uint32_t txpow2g = 0;
6635 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
6636 hddLog(LOG1, "GET WMI_PDEV_PARAM_TXPOWER_LIMIT2G");
6637 *value = wma_cli_get_command(pAdapter->sessionId,
6638 WMI_PDEV_PARAM_TXPOWER_LIMIT2G,
6639 PDEV_CMD);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05306640 if (QDF_STATUS_SUCCESS !=
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006641 sme_cfg_get_int(hHal, WNI_CFG_CURRENT_TX_POWER_LEVEL,
6642 &txpow2g)) {
6643 return -EIO;
6644 }
6645 hddLog(LOG1, "2G tx_power %d", txpow2g);
6646 break;
6647 }
6648
6649 case WE_GET_TXPOW_5G:
6650 {
6651 uint32_t txpow5g = 0;
6652 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
6653 hddLog(LOG1, "GET WMI_PDEV_PARAM_TXPOWER_LIMIT5G");
6654 *value = wma_cli_get_command(pAdapter->sessionId,
6655 WMI_PDEV_PARAM_TXPOWER_LIMIT5G,
6656 PDEV_CMD);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05306657 if (QDF_STATUS_SUCCESS !=
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006658 sme_cfg_get_int(hHal, WNI_CFG_CURRENT_TX_POWER_LEVEL,
6659 &txpow5g)) {
6660 return -EIO;
6661 }
6662 hddLog(LOG1, "5G tx_power %d", txpow5g);
6663 break;
6664 }
6665
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006666 case WE_GET_PPS_PAID_MATCH:
6667 {
6668 hddLog(LOG1, "GET WMI_VDEV_PPS_PAID_MATCH");
6669 *value = wma_cli_get_command(pAdapter->sessionId,
6670 WMI_VDEV_PPS_PAID_MATCH,
6671 PPS_CMD);
6672 break;
6673 }
6674
6675 case WE_GET_PPS_GID_MATCH:
6676 {
6677 hddLog(LOG1, "GET WMI_VDEV_PPS_GID_MATCH");
6678 *value = wma_cli_get_command(pAdapter->sessionId,
6679 WMI_VDEV_PPS_GID_MATCH,
6680 PPS_CMD);
6681 break;
6682 }
6683
6684 case WE_GET_PPS_EARLY_TIM_CLEAR:
6685 {
6686 hddLog(LOG1, "GET WMI_VDEV_PPS_EARLY_TIM_CLEAR");
6687 *value = wma_cli_get_command(pAdapter->sessionId,
6688 WMI_VDEV_PPS_EARLY_TIM_CLEAR,
6689 PPS_CMD);
6690 break;
6691 }
6692
6693 case WE_GET_PPS_EARLY_DTIM_CLEAR:
6694 {
6695 hddLog(LOG1, "GET WMI_VDEV_PPS_EARLY_DTIM_CLEAR");
6696 *value = wma_cli_get_command(pAdapter->sessionId,
6697 WMI_VDEV_PPS_EARLY_DTIM_CLEAR,
6698 PPS_CMD);
6699 break;
6700 }
6701
6702 case WE_GET_PPS_EOF_PAD_DELIM:
6703 {
6704 hddLog(LOG1, "GET WMI_VDEV_PPS_EOF_PAD_DELIM");
6705 *value = wma_cli_get_command(pAdapter->sessionId,
6706 WMI_VDEV_PPS_EOF_PAD_DELIM,
6707 PPS_CMD);
6708 break;
6709 }
6710
6711 case WE_GET_PPS_MACADDR_MISMATCH:
6712 {
6713 hddLog(LOG1, "GET WMI_VDEV_PPS_MACADDR_MISMATCH");
6714 *value = wma_cli_get_command(pAdapter->sessionId,
6715 WMI_VDEV_PPS_MACADDR_MISMATCH,
6716 PPS_CMD);
6717 break;
6718 }
6719
6720 case WE_GET_PPS_DELIM_CRC_FAIL:
6721 {
6722 hddLog(LOG1, "GET WMI_VDEV_PPS_DELIM_CRC_FAIL");
6723 *value = wma_cli_get_command(pAdapter->sessionId,
6724 WMI_VDEV_PPS_DELIM_CRC_FAIL,
6725 PPS_CMD);
6726 break;
6727 }
6728
6729 case WE_GET_PPS_GID_NSTS_ZERO:
6730 {
6731 hddLog(LOG1, "GET WMI_VDEV_PPS_GID_NSTS_ZERO");
6732 *value = wma_cli_get_command(pAdapter->sessionId,
6733 WMI_VDEV_PPS_GID_NSTS_ZERO,
6734 PPS_CMD);
6735 break;
6736 }
6737
6738 case WE_GET_PPS_RSSI_CHECK:
6739 {
6740
6741 hddLog(LOG1, "GET WMI_VDEV_PPS_RSSI_CHECK");
6742 *value = wma_cli_get_command(pAdapter->sessionId,
6743 WMI_VDEV_PPS_RSSI_CHECK,
6744 PPS_CMD);
6745 break;
6746 }
6747
6748 case WE_GET_QPOWER_MAX_PSPOLL_COUNT:
6749 {
6750 hddLog(LOG1, "WE_GET_QPOWER_MAX_PSPOLL_COUNT");
6751 *value = wma_cli_get_command(pAdapter->sessionId,
6752 WMI_STA_PS_PARAM_QPOWER_PSPOLL_COUNT,
6753 QPOWER_CMD);
6754 break;
6755 }
6756
6757 case WE_GET_QPOWER_MAX_TX_BEFORE_WAKE:
6758 {
6759 hddLog(LOG1, "WE_GET_QPOWER_MAX_TX_BEFORE_WAKE");
6760 *value = wma_cli_get_command(pAdapter->sessionId,
6761 WMI_STA_PS_PARAM_QPOWER_MAX_TX_BEFORE_WAKE,
6762 QPOWER_CMD);
6763 break;
6764 }
6765
6766 case WE_GET_QPOWER_SPEC_PSPOLL_WAKE_INTERVAL:
6767 {
6768 hddLog(LOG1, "WE_GET_QPOWER_SPEC_PSPOLL_WAKE_INTERVAL");
6769 *value = wma_cli_get_command(pAdapter->sessionId,
6770 WMI_STA_PS_PARAM_QPOWER_SPEC_PSPOLL_WAKE_INTERVAL,
6771 QPOWER_CMD);
6772 break;
6773 }
6774
6775 case WE_GET_QPOWER_SPEC_MAX_SPEC_NODATA_PSPOLL:
6776 {
6777 hddLog(LOG1, "WE_GET_QPOWER_MAX_PSPOLL_COUNT");
6778 *value = wma_cli_get_command(pAdapter->sessionId,
6779 WMI_STA_PS_PARAM_QPOWER_SPEC_MAX_SPEC_NODATA_PSPOLL,
6780 QPOWER_CMD);
6781 break;
6782 }
6783
6784 case WE_GET_TEMPERATURE:
6785 {
6786 hddLog(CDF_TRACE_LEVEL_INFO, "WE_GET_TEMPERATURE");
6787 ret = wlan_hdd_get_temperature(pAdapter, value);
6788 break;
6789 }
6790 default:
6791 {
6792 hddLog(LOGE, "Invalid IOCTL get_value command %d",
6793 value[0]);
6794 break;
6795 }
6796 }
Hanumantha Reddy Pothula2db50ed2015-11-23 10:48:33 +05306797 EXIT();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006798 return ret;
6799}
6800
6801static int iw_setnone_getint(struct net_device *dev,
6802 struct iw_request_info *info,
6803 union iwreq_data *wrqu, char *extra)
6804{
6805 int ret;
6806
6807 cds_ssr_protect(__func__);
6808 ret = __iw_setnone_getint(dev, info, wrqu, extra);
6809 cds_ssr_unprotect(__func__);
6810
6811 return ret;
6812}
6813
6814/**
6815 * iw_set_three_ints_getnone() - Generic "set 3 params" private ioctl handler
6816 * @dev: device upon which the ioctl was received
6817 * @info: ioctl request information
6818 * @wrqu: ioctl request data
6819 * @extra: ioctl extra data
6820 *
6821 * Return: 0 on success, non-zero on error
6822 */
6823static int __iw_set_three_ints_getnone(struct net_device *dev,
6824 struct iw_request_info *info,
6825 union iwreq_data *wrqu, char *extra)
6826{
6827 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6828 int *value = (int *)extra;
6829 int sub_cmd = value[0];
6830 int ret;
6831 hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(pAdapter);
6832
Hanumantha Reddy Pothula2db50ed2015-11-23 10:48:33 +05306833 ENTER();
6834
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006835 ret = wlan_hdd_validate_context(hdd_ctx);
6836 if (0 != ret)
6837 return ret;
6838
6839 switch (sub_cmd) {
6840
6841 case WE_SET_WLAN_DBG:
6842 cdf_trace_set_value(value[1], value[2], value[3]);
6843 break;
6844 case WE_SET_DP_TRACE:
6845 cdf_dp_trace_set_value(value[1], value[2], value[3]);
6846 break;
6847
6848 /* value[3] the acs band is not required as start and end channels are
6849 * enough but this cmd is maintained under set three ints for historic
6850 * reasons.
6851 */
6852 case WE_SET_SAP_CHANNELS:
6853 if (wlan_hdd_validate_operation_channel(pAdapter, value[1]) !=
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05306854 QDF_STATUS_SUCCESS ||
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006855 wlan_hdd_validate_operation_channel(pAdapter,
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05306856 value[2]) != QDF_STATUS_SUCCESS) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006857 ret = -EINVAL;
6858 } else {
6859 hdd_ctx->config->force_sap_acs_st_ch = value[1];
6860 hdd_ctx->config->force_sap_acs_end_ch = value[2];
6861 }
6862 break;
6863 case WE_SET_DUAL_MAC_SCAN_CONFIG:
6864 hdd_debug("Ioctl to set dual mac scan config");
6865 if (hdd_ctx->config->dual_mac_feature_disable) {
6866 hdd_err("Dual mac feature is disabled from INI");
6867 return -EPERM;
6868 }
6869 hdd_debug("%d %d %d", value[1], value[2], value[3]);
Tushnim Bhattacharyya4adb3682016-01-07 15:07:12 -08006870 cds_set_dual_mac_scan_config(value[1], value[2], value[3]);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006871 break;
6872 default:
6873 hddLog(LOGE, "%s: Invalid IOCTL command %d", __func__, sub_cmd);
6874 break;
6875
6876 }
Hanumantha Reddy Pothula2db50ed2015-11-23 10:48:33 +05306877 EXIT();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006878 return ret;
6879}
6880
6881int iw_set_three_ints_getnone(struct net_device *dev,
6882 struct iw_request_info *info,
6883 union iwreq_data *wrqu, char *extra)
6884{
6885 int ret;
6886
6887 cds_ssr_protect(__func__);
6888 ret = __iw_set_three_ints_getnone(dev, info, wrqu, extra);
6889 cds_ssr_unprotect(__func__);
6890
6891 return ret;
6892}
6893
6894/**
6895 * hdd_connection_state_string() - Get connection state string
6896 * @connection_state: enum to be converted to a string
6897 *
6898 * Return: the string equivalent of @connection_state
6899 */
6900static const char *
6901hdd_connection_state_string(eConnectionState connection_state)
6902{
6903 switch (connection_state) {
6904 CASE_RETURN_STRING(eConnectionState_NotConnected);
6905 CASE_RETURN_STRING(eConnectionState_Connecting);
6906 CASE_RETURN_STRING(eConnectionState_Associated);
6907 CASE_RETURN_STRING(eConnectionState_IbssDisconnected);
6908 CASE_RETURN_STRING(eConnectionState_IbssConnected);
6909 CASE_RETURN_STRING(eConnectionState_Disconnecting);
6910 default:
6911 return "UNKNOWN";
6912 }
6913}
6914
6915/**
6916 * iw_get_char_setnone() - Generic "get string" private ioctl handler
6917 * @dev: device upon which the ioctl was received
6918 * @info: ioctl request information
6919 * @wrqu: ioctl request data
6920 * @extra: ioctl extra data
6921 *
6922 * Return: 0 on success, non-zero on error
6923 */
6924static int __iw_get_char_setnone(struct net_device *dev,
6925 struct iw_request_info *info,
6926 union iwreq_data *wrqu, char *extra)
6927{
6928 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6929 int sub_cmd = wrqu->data.flags;
6930 hdd_context_t *hdd_ctx;
6931 int ret;
6932#ifdef WLAN_FEATURE_11W
6933 hdd_wext_state_t *pWextState;
6934#endif
6935
6936#ifdef WLAN_FEATURE_11W
6937 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
6938#endif
6939
Hanumantha Reddy Pothula2db50ed2015-11-23 10:48:33 +05306940 ENTER();
6941
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006942 hdd_ctx = WLAN_HDD_GET_CTX(pAdapter);
6943 ret = wlan_hdd_validate_context(hdd_ctx);
6944 if (0 != ret)
6945 return ret;
6946
6947 switch (sub_cmd) {
6948 case WE_WLAN_VERSION:
6949 {
6950 hdd_wlan_get_version(pAdapter, wrqu, extra);
6951 break;
6952 }
6953
6954 case WE_GET_STATS:
6955 {
6956 hdd_wlan_get_stats(pAdapter, &(wrqu->data.length),
6957 extra, WE_MAX_STR_LEN);
6958 break;
6959 }
6960
Govind Singha471e5e2015-10-12 17:11:14 +05306961 case WE_LIST_FW_PROFILE:
6962 hdd_wlan_list_fw_profile(&(wrqu->data.length),
6963 extra, WE_MAX_STR_LEN);
6964 break;
6965
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006966 /* The case prints the current state of the HDD, SME, CSR, PE,
6967 * TL it can be extended for WDI Global State as well. And
6968 * currently it only checks P2P_CLIENT adapter. P2P_DEVICE
6969 * and P2P_GO have not been added as of now.
6970 */
6971 case WE_GET_STATES:
6972 {
6973 int buf = 0, len = 0;
6974 int adapter_num = 0;
6975 int count = 0, check = 1;
6976
6977 tHalHandle hHal = NULL;
6978 tpAniSirGlobal pMac = NULL;
6979 hdd_station_ctx_t *pHddStaCtx = NULL;
6980
6981 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
6982 hdd_adapter_t *useAdapter = NULL;
6983
6984 /* Print wlan0 or p2p0 states based on the adapter_num
6985 * by using the correct adapter
6986 */
6987 while (adapter_num < 2) {
6988 if (WLAN_ADAPTER == adapter_num) {
6989 useAdapter = pAdapter;
6990 buf =
6991 scnprintf(extra + len,
6992 WE_MAX_STR_LEN - len,
6993 "\n\n wlan0 States:-");
6994 len += buf;
6995 } else if (P2P_ADAPTER == adapter_num) {
6996 buf =
6997 scnprintf(extra + len,
6998 WE_MAX_STR_LEN - len,
6999 "\n\n p2p0 States:-");
7000 len += buf;
7001
7002 if (!pHddCtx) {
7003 buf =
7004 scnprintf(extra + len,
7005 WE_MAX_STR_LEN -
7006 len,
7007 "\n pHddCtx is NULL");
7008 len += buf;
7009 break;
7010 }
7011
7012 /* Printing p2p0 states only in the
7013 * case when the device is configured
7014 * as a p2p_client
7015 */
7016 useAdapter =
7017 hdd_get_adapter(pHddCtx,
7018 WLAN_HDD_P2P_CLIENT);
7019 if (!useAdapter) {
7020 buf =
7021 scnprintf(extra + len,
7022 WE_MAX_STR_LEN -
7023 len,
7024 "\n Device not configured as P2P_CLIENT.");
7025 len += buf;
7026 break;
7027 }
7028 }
7029
7030 hHal = WLAN_HDD_GET_HAL_CTX(useAdapter);
7031 if (!hHal) {
7032 buf =
7033 scnprintf(extra + len,
7034 WE_MAX_STR_LEN - len,
7035 "\n pMac is NULL");
7036 len += buf;
7037 break;
7038 }
7039 pMac = PMAC_STRUCT(hHal);
7040 if (!pMac) {
7041 buf =
7042 scnprintf(extra + len,
7043 WE_MAX_STR_LEN - len,
7044 "\n pMac is NULL");
7045 len += buf;
7046 break;
7047 }
7048 pHddStaCtx =
7049 WLAN_HDD_GET_STATION_CTX_PTR(useAdapter);
7050
7051
7052 buf =
7053 scnprintf(extra + len, WE_MAX_STR_LEN - len,
7054 "\n HDD Conn State - %s "
7055 "\n \n SME State:"
7056 "\n Neighbour Roam State - %s"
7057 "\n CSR State - %s"
7058 "\n CSR Substate - %s",
7059 hdd_connection_state_string
7060 (pHddStaCtx->conn_info.connState),
7061 mac_trace_get_neighbour_roam_state
7062 (sme_get_neighbor_roam_state
7063 (hHal, useAdapter->sessionId)),
7064 mac_trace_getcsr_roam_state
7065 (sme_get_current_roam_state
7066 (hHal, useAdapter->sessionId)),
7067 mac_trace_getcsr_roam_sub_state
7068 (sme_get_current_roam_sub_state
7069 (hHal, useAdapter->sessionId))
7070 );
7071 len += buf;
7072 adapter_num++;
7073 }
7074
Mukul Sharma81661ae2015-10-30 20:26:02 +05307075 if (hHal) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007076 /* Printing Lim State starting with global lim states */
7077 buf =
7078 scnprintf(extra + len, WE_MAX_STR_LEN - len,
7079 "\n \n LIM STATES:-"
7080 "\n Global Sme State - %s "
7081 "\n Global mlm State - %s " "\n",
7082 mac_trace_get_lim_sme_state
7083 (sme_get_lim_sme_state(hHal)),
7084 mac_trace_get_lim_mlm_state
7085 (sme_get_lim_sme_state(hHal))
7086 );
7087 len += buf;
7088
7089 /* Printing the PE Sme and Mlm states for valid lim sessions */
7090 while (check < 3 && count < 255) {
7091 if (sme_is_lim_session_valid(hHal, count)) {
7092 buf =
7093 scnprintf(extra + len,
7094 WE_MAX_STR_LEN -
7095 len,
7096 "\n Lim Valid Session %d:-"
7097 "\n PE Sme State - %s "
7098 "\n PE Mlm State - %s "
7099 "\n", check,
7100 mac_trace_get_lim_sme_state
7101 (sme_get_lim_sme_session_state
7102 (hHal, count)),
7103 mac_trace_get_lim_mlm_state
7104 (sme_get_lim_mlm_session_state
7105 (hHal, count))
7106 );
7107
7108 len += buf;
7109 check++;
7110 }
7111 count++;
7112 }
7113 }
7114
7115 wrqu->data.length = strlen(extra) + 1;
7116 break;
7117 }
7118
7119 case WE_GET_CFG:
7120 {
7121 CDF_TRACE(CDF_MODULE_ID_HDD, CDF_TRACE_LEVEL_INFO,
7122 "%s: Printing CLD global INI Config",
7123 __func__);
7124 hdd_cfg_get_global_config(WLAN_HDD_GET_CTX(pAdapter),
7125 extra,
7126 QCSAP_IOCTL_MAX_STR_LEN);
7127 wrqu->data.length = strlen(extra) + 1;
7128 break;
7129 }
7130#ifdef WLAN_FEATURE_11AC
7131 case WE_GET_RSSI:
7132 {
7133 int8_t s7Rssi = 0;
7134 wlan_hdd_get_rssi(pAdapter, &s7Rssi);
7135 snprintf(extra, WE_MAX_STR_LEN, "rssi=%d", s7Rssi);
7136 wrqu->data.length = strlen(extra) + 1;
7137 break;
7138 }
7139#endif
7140
7141 case WE_GET_WMM_STATUS:
7142 {
7143 snprintf(extra, WE_MAX_STR_LEN,
7144 "\nDir: 0=up, 1=down, 3=both\n"
7145 "|------------------------|\n"
7146 "|AC | ACM |Admitted| Dir |\n"
7147 "|------------------------|\n"
7148 "|VO | %d | %3s | %d |\n"
7149 "|VI | %d | %3s | %d |\n"
7150 "|BE | %d | %3s | %d |\n"
7151 "|BK | %d | %3s | %d |\n"
7152 "|------------------------|\n",
7153 pAdapter->hddWmmStatus.
7154 wmmAcStatus[SME_AC_VO].wmmAcAccessRequired,
7155 pAdapter->hddWmmStatus.
7156 wmmAcStatus[SME_AC_VO].
7157 wmmAcAccessAllowed ? "YES" : "NO",
7158 pAdapter->hddWmmStatus.
7159 wmmAcStatus[SME_AC_VO].wmmAcTspecInfo.
7160 ts_info.direction,
7161 pAdapter->hddWmmStatus.
7162 wmmAcStatus[SME_AC_VI].wmmAcAccessRequired,
7163 pAdapter->hddWmmStatus.
7164 wmmAcStatus[SME_AC_VI].
7165 wmmAcAccessAllowed ? "YES" : "NO",
7166 pAdapter->hddWmmStatus.
7167 wmmAcStatus[SME_AC_VI].wmmAcTspecInfo.
7168 ts_info.direction,
7169 pAdapter->hddWmmStatus.
7170 wmmAcStatus[SME_AC_BE].wmmAcAccessRequired,
7171 pAdapter->hddWmmStatus.
7172 wmmAcStatus[SME_AC_BE].
7173 wmmAcAccessAllowed ? "YES" : "NO",
7174 pAdapter->hddWmmStatus.
7175 wmmAcStatus[SME_AC_BE].wmmAcTspecInfo.
7176 ts_info.direction,
7177 pAdapter->hddWmmStatus.
7178 wmmAcStatus[SME_AC_BK].wmmAcAccessRequired,
7179 pAdapter->hddWmmStatus.
7180 wmmAcStatus[SME_AC_BK].
7181 wmmAcAccessAllowed ? "YES" : "NO",
7182 pAdapter->hddWmmStatus.
7183 wmmAcStatus[SME_AC_BK].wmmAcTspecInfo.
7184 ts_info.direction);
7185
7186 wrqu->data.length = strlen(extra) + 1;
7187 break;
7188 }
7189 case WE_GET_CHANNEL_LIST:
7190 {
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05307191 QDF_STATUS status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007192 uint8_t i, len;
7193 char *buf;
7194 uint8_t ubuf[WNI_CFG_COUNTRY_CODE_LEN];
7195 uint8_t ubuf_len = WNI_CFG_COUNTRY_CODE_LEN;
7196 hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(pAdapter);
7197
7198 tChannelListInfo channel_list;
7199
7200 memset(&channel_list, 0, sizeof(channel_list));
7201 status =
7202 iw_softap_get_channel_list(dev, info, wrqu,
7203 (char *)&channel_list);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05307204 if (!QDF_IS_STATUS_SUCCESS(status)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007205 hddLog(LOGE, FL("GetChannelList Failed!!!"));
7206 return -EINVAL;
7207 }
7208 buf = extra;
7209 /*
7210 * Maximum channels = WNI_CFG_VALID_CHANNEL_LIST_LEN.
7211 * Maximum buffer needed = 5 * number of channels.
7212 * Check ifsufficient buffer is available and then
7213 * proceed to fill the buffer.
7214 */
7215 if (WE_MAX_STR_LEN <
7216 (5 * WNI_CFG_VALID_CHANNEL_LIST_LEN)) {
7217 hddLog(LOGE,
7218 FL("Insufficient Buffer to populate channel list"));
7219 return -EINVAL;
7220 }
7221 len = scnprintf(buf, WE_MAX_STR_LEN, "%u ",
7222 channel_list.num_channels);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05307223 if (QDF_STATUS_SUCCESS == sme_get_country_code(hdd_ctx->hHal,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007224 ubuf, &ubuf_len)) {
7225 /* Printing Country code in getChannelList */
7226 for (i = 0; i < (ubuf_len - 1); i++)
7227 len += scnprintf(buf + len,
7228 WE_MAX_STR_LEN - len,
7229 "%c", ubuf[i]);
7230 }
7231 for (i = 0; i < channel_list.num_channels; i++) {
7232 len +=
7233 scnprintf(buf + len, WE_MAX_STR_LEN - len,
7234 " %u", channel_list.channels[i]);
7235 }
7236 wrqu->data.length = strlen(extra) + 1;
7237
7238 break;
7239 }
7240#ifdef FEATURE_WLAN_TDLS
7241 case WE_GET_TDLS_PEERS:
7242 {
7243 wrqu->data.length =
7244 wlan_hdd_tdls_get_all_peers(pAdapter, extra,
7245 WE_MAX_STR_LEN) + 1;
7246 break;
7247 }
7248#endif
7249#ifdef WLAN_FEATURE_11W
7250 case WE_GET_11W_INFO:
7251 {
7252 hddLog(LOGE, "WE_GET_11W_ENABLED = %d",
7253 pWextState->roamProfile.MFPEnabled);
7254
7255 snprintf(extra, WE_MAX_STR_LEN,
7256 "\n BSSID %02X:%02X:%02X:%02X:%02X:%02X, Is PMF Assoc? %d"
7257 "\n Number of Unprotected Disassocs %d"
7258 "\n Number of Unprotected Deauths %d",
7259 pWextState->roamProfile.BSSIDs.bssid->bytes[0],
7260 pWextState->roamProfile.BSSIDs.bssid->bytes[1],
7261 pWextState->roamProfile.BSSIDs.bssid->bytes[2],
7262 pWextState->roamProfile.BSSIDs.bssid->bytes[3],
7263 pWextState->roamProfile.BSSIDs.bssid->bytes[4],
7264 pWextState->roamProfile.BSSIDs.bssid->bytes[5],
7265 pWextState->roamProfile.MFPEnabled,
7266 pAdapter->hdd_stats.hddPmfStats.
7267 numUnprotDisassocRx,
7268 pAdapter->hdd_stats.hddPmfStats.
7269 numUnprotDeauthRx);
7270
7271 wrqu->data.length = strlen(extra) + 1;
7272 break;
7273 }
7274#endif
7275 case WE_GET_PHYMODE:
7276 {
7277 bool ch_bond24 = false, ch_bond5g = false;
7278 hdd_context_t *hddctx = WLAN_HDD_GET_CTX(pAdapter);
7279 tHalHandle hal = WLAN_HDD_GET_HAL_CTX(pAdapter);
7280 eCsrPhyMode phymode;
7281 eCsrBand currBand;
7282 tSmeConfigParams smeconfig;
7283
7284 sme_get_config_param(hal, &smeconfig);
7285 if (WNI_CFG_CHANNEL_BONDING_MODE_DISABLE !=
7286 smeconfig.csrConfig.channelBondingMode24GHz)
7287 ch_bond24 = true;
7288
7289 if (WNI_CFG_CHANNEL_BONDING_MODE_DISABLE !=
7290 smeconfig.csrConfig.channelBondingMode5GHz)
7291 ch_bond5g = true;
7292
7293 phymode = sme_get_phy_mode(hal);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05307294 if ((QDF_STATUS_SUCCESS !=
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007295 sme_get_freq_band(hal, &currBand))) {
7296 CDF_TRACE(CDF_MODULE_ID_HDD,
7297 CDF_TRACE_LEVEL_INFO,
7298 "%s: Failed to get current band config",
7299 __func__);
7300 return -EIO;
7301 }
7302
7303 switch (phymode) {
7304 case eCSR_DOT11_MODE_AUTO:
7305 snprintf(extra, WE_MAX_STR_LEN, "AUTO MODE");
7306 break;
7307 case eCSR_DOT11_MODE_11n:
7308 case eCSR_DOT11_MODE_11n_ONLY:
7309 if (currBand == eCSR_BAND_24) {
7310 if (ch_bond24)
7311 snprintf(extra, WE_MAX_STR_LEN,
7312 "11NGHT40");
7313 else
7314 snprintf(extra, WE_MAX_STR_LEN,
7315 "11NGHT20");
7316 } else if (currBand == eCSR_BAND_5G) {
7317 if (ch_bond5g)
7318 snprintf(extra, WE_MAX_STR_LEN,
7319 "11NAHT40");
7320 else
7321 snprintf(extra, WE_MAX_STR_LEN,
7322 "11NAHT20");
7323 } else {
7324 snprintf(extra, WE_MAX_STR_LEN, "11N");
7325 }
7326 break;
7327 case eCSR_DOT11_MODE_abg:
7328 snprintf(extra, WE_MAX_STR_LEN, "11ABG");
7329 break;
7330 case eCSR_DOT11_MODE_11a:
7331 snprintf(extra, WE_MAX_STR_LEN, "11A");
7332 break;
7333 case eCSR_DOT11_MODE_11b:
7334 case eCSR_DOT11_MODE_11b_ONLY:
7335 snprintf(extra, WE_MAX_STR_LEN, "11B");
7336 break;
7337 case eCSR_DOT11_MODE_11g:
7338 case eCSR_DOT11_MODE_11g_ONLY:
7339 snprintf(extra, WE_MAX_STR_LEN, "11G");
7340 break;
7341#ifdef WLAN_FEATURE_11AC
7342 case eCSR_DOT11_MODE_11ac:
7343 case eCSR_DOT11_MODE_11ac_ONLY:
7344 if (hddctx->config->vhtChannelWidth ==
7345 eHT_CHANNEL_WIDTH_20MHZ)
7346 snprintf(extra, WE_MAX_STR_LEN,
7347 "11ACVHT20");
7348 else if (hddctx->config->vhtChannelWidth ==
7349 eHT_CHANNEL_WIDTH_40MHZ)
7350 snprintf(extra, WE_MAX_STR_LEN,
7351 "11ACVHT40");
7352 else if (hddctx->config->vhtChannelWidth ==
7353 eHT_CHANNEL_WIDTH_80MHZ)
7354 snprintf(extra, WE_MAX_STR_LEN,
7355 "11ACVHT80");
7356 else if (hddctx->config->vhtChannelWidth ==
7357 eHT_CHANNEL_WIDTH_160MHZ)
7358 snprintf(extra, WE_MAX_STR_LEN,
7359 "11ACVHT160");
7360 break;
7361#endif
7362 }
7363
7364 wrqu->data.length = strlen(extra) + 1;
7365 break;
7366 }
7367
7368#ifdef FEATURE_OEM_DATA_SUPPORT
7369 case WE_GET_OEM_DATA_CAP:
7370 {
7371 return iw_get_oem_data_cap(dev, info, wrqu, extra);
7372 }
7373#endif /* FEATURE_OEM_DATA_SUPPORT */
7374 case WE_GET_SNR:
7375 {
7376 int8_t s7snr = 0;
7377 int status = 0;
7378 hdd_context_t *pHddCtx;
7379 hdd_station_ctx_t *pHddStaCtx;
7380 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7381 status = wlan_hdd_validate_context(pHddCtx);
7382 if (0 != status) {
7383 hddLog(LOGE,
7384 "%s: getSNR: HDD context is not valid",
7385 __func__);
7386 return status;
7387 }
7388 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7389 if (0 == pHddCtx->config->fEnableSNRMonitoring ||
7390 eConnectionState_Associated !=
7391 pHddStaCtx->conn_info.connState) {
7392 hddLog(LOGE,
7393 "%s: getSNR failed: Enable SNR Monitoring-%d,"
7394 " ConnectionState-%d", __func__,
7395 pHddCtx->config->fEnableSNRMonitoring,
7396 pHddStaCtx->conn_info.connState);
7397 return -ENONET;
7398 }
7399 wlan_hdd_get_snr(pAdapter, &s7snr);
7400 snprintf(extra, WE_MAX_STR_LEN, "snr=%d", s7snr);
7401 wrqu->data.length = strlen(extra) + 1;
7402 break;
7403 }
7404 default:
7405 {
7406 hddLog(LOGE, "%s: Invalid IOCTL command %d", __func__,
7407 sub_cmd);
7408 break;
7409 }
7410 }
Hanumantha Reddy Pothula2db50ed2015-11-23 10:48:33 +05307411 EXIT();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007412 return 0;
7413}
7414
7415static int iw_get_char_setnone(struct net_device *dev,
7416 struct iw_request_info *info,
7417 union iwreq_data *wrqu, char *extra)
7418{
7419 int ret;
7420
7421 cds_ssr_protect(__func__);
7422 ret = __iw_get_char_setnone(dev, info, wrqu, extra);
7423 cds_ssr_unprotect(__func__);
7424
7425 return ret;
7426}
7427
7428/**
7429 * iw_setnone_getnone() - Generic "action" private ioctl handler
7430 * @dev: device upon which the ioctl was received
7431 * @info: ioctl request information
7432 * @wrqu: ioctl request data
7433 * @extra: ioctl extra data
7434 *
7435 * Return: 0 on success, non-zero on error
7436 */
7437static int __iw_setnone_getnone(struct net_device *dev,
7438 struct iw_request_info *info,
7439 union iwreq_data *wrqu, char *extra)
7440{
7441 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
7442 hdd_context_t *hdd_ctx;
7443 int ret;
7444 int sub_cmd;
7445
Hanumantha Reddy Pothula2db50ed2015-11-23 10:48:33 +05307446 ENTER();
7447
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007448 hdd_ctx = WLAN_HDD_GET_CTX(pAdapter);
7449 ret = wlan_hdd_validate_context(hdd_ctx);
7450 if (0 != ret)
7451 return ret;
7452
7453#ifdef CONFIG_COMPAT
7454 /* this ioctl is a special case where a sub-ioctl is used and both
7455 * the number of get and set args is 0. in this specific case the
7456 * logic in iwpriv places the sub_cmd in the data.flags portion of
7457 * the iwreq. unfortunately the location of this field will be
7458 * different between 32-bit and 64-bit userspace, and the standard
7459 * compat support in the kernel does not handle this case. so we
7460 * need to explicitly handle it here.
7461 */
7462 if (is_compat_task()) {
7463 struct compat_iw_point *compat_iw_point =
7464 (struct compat_iw_point *)&wrqu->data;
7465 sub_cmd = compat_iw_point->flags;
7466 } else {
7467 sub_cmd = wrqu->data.flags;
7468 }
7469#else
7470 sub_cmd = wrqu->data.flags;
7471#endif
7472
7473 switch (sub_cmd) {
7474 case WE_GET_RECOVERY_STAT:
7475 {
7476 tHalHandle hal = WLAN_HDD_GET_HAL_CTX(pAdapter);
7477 sme_get_recovery_stats(hal);
7478 break;
7479 }
7480
Govind Singha471e5e2015-10-12 17:11:14 +05307481 case WE_GET_FW_PROFILE_DATA:
7482 ret = wma_cli_set_command(pAdapter->sessionId,
7483 WMI_WLAN_PROFILE_GET_PROFILE_DATA_CMDID,
7484 0, DBG_CMD);
7485 break;
7486
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007487 case WE_SET_REASSOC_TRIGGER:
7488 {
7489 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
7490 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
7491 uint32_t roamId = 0;
7492 tCsrRoamModifyProfileFields modProfileFields;
7493 hdd_station_ctx_t *hdd_sta_ctx =
7494 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7495
7496 /* Reassoc to same AP, only supported for Open Security*/
7497 if ((hdd_sta_ctx->conn_info.ucEncryptionType ||
7498 hdd_sta_ctx->conn_info.mcEncryptionType)) {
7499 hddLog(LOGE,
7500 FL("Reassoc to same AP, only supported for Open Security"));
7501 return -ENOTSUPP;
7502 }
7503
7504 sme_get_modify_profile_fields(hHal, pAdapter->sessionId,
7505 &modProfileFields);
7506 sme_roam_reassoc(hHal, pAdapter->sessionId,
7507 NULL, modProfileFields, &roamId, 1);
7508 return 0;
7509 }
7510
7511 case WE_DUMP_AGC_START:
7512 {
7513 hddLog(LOG1, "WE_DUMP_AGC_START");
7514 ret = wma_cli_set_command(pAdapter->sessionId,
7515 GEN_PARAM_DUMP_AGC_START,
7516 0, GEN_CMD);
7517 break;
7518 }
7519 case WE_DUMP_AGC:
7520 {
7521 hddLog(LOG1, "WE_DUMP_AGC");
7522 ret = wma_cli_set_command(pAdapter->sessionId,
7523 GEN_PARAM_DUMP_AGC,
7524 0, GEN_CMD);
7525 break;
7526 }
7527
7528 case WE_DUMP_CHANINFO_START:
7529 {
7530 hddLog(LOG1, "WE_DUMP_CHANINFO_START");
7531 ret = wma_cli_set_command(pAdapter->sessionId,
7532 GEN_PARAM_DUMP_CHANINFO_START,
7533 0, GEN_CMD);
7534 break;
7535 }
7536 case WE_DUMP_CHANINFO:
7537 {
7538 hddLog(LOG1, "WE_DUMP_CHANINFO_START");
7539 ret = wma_cli_set_command(pAdapter->sessionId,
7540 GEN_PARAM_DUMP_CHANINFO,
7541 0, GEN_CMD);
7542 break;
7543 }
7544 case WE_DUMP_WATCHDOG:
7545 {
7546 hddLog(LOG1, "WE_DUMP_WATCHDOG");
7547 ret = wma_cli_set_command(pAdapter->sessionId,
7548 GEN_PARAM_DUMP_WATCHDOG,
7549 0, GEN_CMD);
7550 break;
7551 }
7552#ifdef CONFIG_ATH_PCIE_ACCESS_DEBUG
7553 case WE_DUMP_PCIE_LOG:
7554 {
7555 hddLog(LOGE, "WE_DUMP_PCIE_LOG");
7556 ret = wma_cli_set_command(pAdapter->sessionId,
7557 GEN_PARAM_DUMP_PCIE_ACCESS_LOG,
7558 0, GEN_CMD);
7559 break;
7560 }
7561#endif
7562 default:
7563 {
7564 hddLog(LOGE, "%s: unknown ioctl %d", __func__, sub_cmd);
7565 break;
7566 }
7567 }
Hanumantha Reddy Pothula2db50ed2015-11-23 10:48:33 +05307568 EXIT();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007569 return ret;
7570}
7571
7572static int iw_setnone_getnone(struct net_device *dev,
7573 struct iw_request_info *info,
7574 union iwreq_data *wrqu, char *extra)
7575{
7576 int ret;
7577
7578 cds_ssr_protect(__func__);
7579 ret = __iw_setnone_getnone(dev, info, wrqu, extra);
7580 cds_ssr_unprotect(__func__);
7581
7582 return ret;
7583}
7584
7585/**
7586 * __iw_set_var_ints_getnone - Generic "set many" private ioctl handler
7587 * @dev: device upon which the ioctl was received
7588 * @info: ioctl request information
7589 * @wrqu: ioctl request data
7590 * @extra: ioctl extra data
7591 *
7592 * This is an SSR-protected generic handler for private ioctls which
7593 * take multiple arguments. Note that this implementation is also
7594 * somewhat unique in that it is shared by both STA-mode and SAP-mode
7595 * interfaces.
7596 *
7597 * Return: 0 on success, non-zero on error
7598 */
7599static int __iw_set_var_ints_getnone(struct net_device *dev,
7600 struct iw_request_info *info,
7601 union iwreq_data *wrqu, char *extra)
7602{
7603 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
7604 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
7605 int sub_cmd;
7606 int *apps_args = (int *) extra;
7607 hdd_context_t *hdd_ctx;
7608 int ret, num_args;
7609
Hanumantha Reddy Pothula2db50ed2015-11-23 10:48:33 +05307610 ENTER();
7611
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007612 hdd_ctx = WLAN_HDD_GET_CTX(pAdapter);
7613 ret = wlan_hdd_validate_context(hdd_ctx);
7614 if (0 != ret)
7615 return ret;
7616
7617 if (extra == NULL) {
7618 hddLog(LOGE, FL("NULL extra buffer pointer"));
7619 return -EINVAL;
7620 }
7621
7622 sub_cmd = wrqu->data.flags;
7623 num_args = wrqu->data.length;
7624
7625 hddLog(LOG1, FL("Received length %d"), wrqu->data.length);
7626
7627 switch (sub_cmd) {
7628
7629 case WE_P2P_NOA_CMD:
7630 {
7631 p2p_app_setP2pPs_t p2pNoA;
7632
Rajeev Kumar274034c2015-11-23 11:28:58 -08007633 if (pAdapter->device_mode != WLAN_HDD_P2P_GO) {
7634 hdd_err("Setting NoA is not allowed in Device mode %s(%d)",
7635 hdd_device_mode_to_string(
7636 pAdapter->device_mode),
7637 pAdapter->device_mode);
7638 return -EINVAL;
7639 }
7640
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007641 p2pNoA.opp_ps = apps_args[0];
7642 p2pNoA.ctWindow = apps_args[1];
7643 p2pNoA.duration = apps_args[2];
7644 p2pNoA.interval = apps_args[3];
7645 p2pNoA.count = apps_args[4];
7646 p2pNoA.single_noa_duration = apps_args[5];
7647 p2pNoA.psSelection = apps_args[6];
7648
7649 hddLog(LOG1,
7650 "%s: P2P_NOA_ATTR:oppPS %d ctWindow %d duration %d "
7651 "interval %d count %d single noa duration %d PsSelection %x",
7652 __func__, apps_args[0], apps_args[1],
7653 apps_args[2], apps_args[3], apps_args[4],
7654 apps_args[5], apps_args[6]);
7655
7656 hdd_set_p2p_ps(dev, &p2pNoA);
7657
7658 }
7659 break;
7660
7661 case WE_MTRACE_SELECTIVE_MODULE_LOG_ENABLE_CMD:
7662 {
7663 hddLog(LOG1, "%s: SELECTIVE_MODULE_LOG %d arg1 %d arg2",
7664 __func__, apps_args[0], apps_args[1]);
7665 cdf_trace_enable(apps_args[0], apps_args[1]);
7666 }
7667 break;
7668
7669 case WE_MTRACE_DUMP_CMD:
7670 {
7671 hddLog(LOG1,
7672 "%s: MTRACE_DUMP code %d session %d count %d "
7673 "bitmask_of_module %d ", __func__, apps_args[0],
7674 apps_args[1], apps_args[2], apps_args[3]);
7675 cdf_trace_dump_all((void *)hHal, apps_args[0],
7676 apps_args[1], apps_args[2],
7677 apps_args[3]);
7678
7679 }
7680 break;
7681
7682 case WE_POLICY_MANAGER_CLIST_CMD:
7683 {
7684 hddLog(LOGE,
7685 FL("<iwpriv wlan0 pm_clist> is called\n"));
Tushnim Bhattacharyyaca50b322015-12-28 17:14:36 -08007686 cds_incr_connection_count_utfw(apps_args[0],
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007687 apps_args[1], apps_args[2], apps_args[3],
7688 apps_args[4], apps_args[5], apps_args[6],
7689 apps_args[7]);
7690 }
7691 break;
7692
7693 case WE_POLICY_MANAGER_DLIST_CMD:
7694 {
7695 hddLog(LOGE,
7696 FL("<iwpriv wlan0 pm_dlist> is called\n"));
Tushnim Bhattacharyyaca50b322015-12-28 17:14:36 -08007697 cds_decr_connection_count_utfw(apps_args[0],
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007698 apps_args[1]);
7699 }
7700 break;
7701
7702 case WE_POLICY_MANAGER_ULIST_CMD:
7703 {
7704 hddLog(LOGE,
7705 FL("<iwpriv wlan0 pm_ulist> is called\n"));
Tushnim Bhattacharyyaca50b322015-12-28 17:14:36 -08007706 cds_update_connection_info_utfw(apps_args[0],
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007707 apps_args[1], apps_args[2], apps_args[3],
7708 apps_args[4], apps_args[5], apps_args[6],
7709 apps_args[7]);
7710 }
7711 break;
7712
7713 case WE_POLICY_MANAGER_DBS_CMD:
7714 {
7715 hddLog(LOGE,
7716 FL("<iwpriv wlan0 pm_dbs> is called\n"));
7717 if (apps_args[0] == 0)
7718 wma_set_dbs_capability_ut(0);
7719 else
7720 wma_set_dbs_capability_ut(1);
7721
7722 if (apps_args[1] >= CDS_THROUGHPUT &&
7723 apps_args[1] <= CDS_LATENCY) {
7724 pr_info("setting system pref to [%d]\n", apps_args[1]);
7725 hdd_ctx->config->conc_system_pref = apps_args[1];
7726 }
7727 }
7728 break;
7729
7730 case WE_POLICY_MANAGER_PCL_CMD:
7731 {
7732 uint8_t pcl[MAX_NUM_CHAN] = {0};
7733 uint32_t pcl_len = 0, i = 0;
7734
7735 hddLog(LOGE,
7736 FL("<iwpriv wlan0 pm_pcl> is called\n"));
7737
Tushnim Bhattacharyyaca50b322015-12-28 17:14:36 -08007738 cds_get_pcl(apps_args[0],
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007739 pcl, &pcl_len);
7740 pr_info("PCL list for role[%d] is {", apps_args[0]);
7741 for (i = 0 ; i < pcl_len; i++)
7742 pr_info(" %d, ", pcl[i]);
7743 pr_info("}--------->\n");
7744 }
7745 break;
7746
7747 case WE_POLICY_MANAGER_CINFO_CMD:
7748 {
7749 struct cds_conc_connection_info *conn_info;
7750 uint32_t i = 0, len = 0;
7751
7752 hddLog(LOGE,
7753 FL("<iwpriv wlan0 pm_cinfo> is called\n"));
Tushnim Bhattacharyyaca50b322015-12-28 17:14:36 -08007754 conn_info = cds_get_conn_info(&len);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007755 pr_info("+-----------------------------+\n");
7756 for (i = 0; i < len; i++) {
7757 pr_info("|table_index[%d]\t\t|\n", i);
7758 pr_info("|\t|vdev_id - %d\t\t|\n", conn_info->vdev_id);
7759 pr_info("|\t|tx_spatial_stream - %d\t|\n",
7760 conn_info->tx_spatial_stream);
7761 pr_info("|\t|rx_spatial_stream - %d\t|\n",
7762 conn_info->rx_spatial_stream);
7763 pr_info("|\t|chain_mask - %d\t\t|\n",
7764 conn_info->chain_mask);
7765 pr_info("|\t|chan - %d\t\t|\n", conn_info->chan);
7766 pr_info("|\t|mode - %d\t\t|\n", conn_info->mode);
7767 pr_info("|\t|mac - %d\t\t|\n", conn_info->mac);
7768 pr_info("|\t|in_use - %d\t\t|\n", conn_info->in_use);
7769 pr_info("+-----------------------------+\n");
7770 conn_info++;
7771 }
7772 }
7773 break;
7774
7775 case WE_POLICY_SET_HW_MODE_CMD:
7776 {
7777 if (apps_args[0] == 0) {
7778 hddLog(LOGE,
7779 FL("set hw mode for single mac\n"));
Tushnim Bhattacharyyaca50b322015-12-28 17:14:36 -08007780 cds_soc_set_hw_mode(
Chandrasekaran, Manishekaref70c0d2015-10-20 19:54:55 +05307781 pAdapter->sessionId,
7782 HW_MODE_SS_2x2,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007783 HW_MODE_80_MHZ,
7784 HW_MODE_SS_0x0, HW_MODE_BW_NONE,
7785 HW_MODE_DBS_NONE,
Chandrasekaran, Manishekaref70c0d2015-10-20 19:54:55 +05307786 HW_MODE_AGILE_DFS_NONE,
7787 CDS_UPDATE_REASON_UT);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007788 } else if (apps_args[0] == 1) {
7789 hddLog(LOGE,
7790 FL("set hw mode for dual mac\n"));
Tushnim Bhattacharyyaca50b322015-12-28 17:14:36 -08007791 cds_soc_set_hw_mode(
Chandrasekaran, Manishekaref70c0d2015-10-20 19:54:55 +05307792 pAdapter->sessionId,
7793 HW_MODE_SS_1x1,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007794 HW_MODE_80_MHZ,
7795 HW_MODE_SS_1x1, HW_MODE_40_MHZ,
7796 HW_MODE_DBS,
Chandrasekaran, Manishekaref70c0d2015-10-20 19:54:55 +05307797 HW_MODE_AGILE_DFS_NONE,
7798 CDS_UPDATE_REASON_UT);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007799 }
7800 }
7801 break;
7802
7803 case WE_POLICY_MANAGER_QUERY_ACTION_CMD:
7804 {
7805 enum cds_conc_next_action action;
7806 hddLog(LOGE,
7807 FL("<iwpriv wlan0 pm_query_action> is called\n"));
Chandrasekaran, Manishekaref70c0d2015-10-20 19:54:55 +05307808 action = cds_current_connections_update(pAdapter->sessionId,
7809 apps_args[0],
7810 CDS_UPDATE_REASON_UT);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007811 pr_info("next action is %d {HDD_NOP = 0, HDD_DBS, HDD_DBS_DOWNGRADE, HDD_MCC, HDD_MCC_UPGRADE}", action);
7812 }
7813 break;
7814 case WE_POLICY_MANAGER_QUERY_ALLOW_CMD:
7815 {
7816 bool allow;
7817 hddLog(LOGE,
7818 FL("<iwpriv wlan0 pm_query_allow> is called\n"));
Tushnim Bhattacharyyaca50b322015-12-28 17:14:36 -08007819 allow = cds_allow_concurrency(
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007820 apps_args[0], apps_args[1], apps_args[2]);
7821 pr_info("allow %d {0 = don't allow, 1 = allow}", allow);
7822 }
7823 break;
7824
7825 case WE_POLICY_MANAGER_SCENARIO_CMD:
7826 {
7827 clean_report(hdd_ctx);
7828 if (apps_args[0] == 1) {
7829 wlan_hdd_one_connection_scenario(hdd_ctx);
7830 } else if (apps_args[0] == 2) {
7831 wlan_hdd_two_connections_scenario(hdd_ctx,
7832 6, CDS_TWO_TWO);
7833 wlan_hdd_two_connections_scenario(hdd_ctx,
7834 36, CDS_TWO_TWO);
7835 wlan_hdd_two_connections_scenario(hdd_ctx,
7836 6, CDS_ONE_ONE);
7837 wlan_hdd_two_connections_scenario(hdd_ctx,
7838 36, CDS_ONE_ONE);
7839 } else if (apps_args[0] == 3) {
7840 /* MCC on same band with 2x2 same mac*/
7841 wlan_hdd_three_connections_scenario(hdd_ctx,
7842 6, 11, CDS_TWO_TWO, 0);
7843 /* MCC on diff band with 2x2 same mac*/
7844 wlan_hdd_three_connections_scenario(hdd_ctx,
7845 6, 36, CDS_TWO_TWO, 0);
7846 /* MCC on diff band with 1x1 diff mac */
7847 wlan_hdd_three_connections_scenario(hdd_ctx,
7848 36, 6, CDS_ONE_ONE, 0);
7849 /* MCC on diff band with 1x1 same mac */
7850 wlan_hdd_three_connections_scenario(hdd_ctx,
7851 36, 6, CDS_ONE_ONE, 1);
7852 /* SCC on same band with 2x2 same mac */
7853 wlan_hdd_three_connections_scenario(hdd_ctx,
7854 36, 36, CDS_TWO_TWO, 0);
7855 /* SCC on same band with 1x1 same mac */
7856 wlan_hdd_three_connections_scenario(hdd_ctx,
7857 36, 36, CDS_ONE_ONE, 1);
7858 /* MCC on same band with 2x2 same mac */
7859 wlan_hdd_three_connections_scenario(hdd_ctx,
7860 36, 149, CDS_TWO_TWO, 0);
7861 /* MCC on same band with 1x1 same mac */
7862 wlan_hdd_three_connections_scenario(hdd_ctx,
7863 36, 149, CDS_ONE_ONE, 1);
7864 }
7865 print_report(hdd_ctx);
7866 }
7867 break;
7868
7869#ifdef FEATURE_WLAN_TDLS
7870 case WE_TDLS_CONFIG_PARAMS:
7871 {
7872 tdls_config_params_t tdlsParams;
7873
7874 tdlsParams.tdls = apps_args[0];
7875 tdlsParams.tx_period_t = apps_args[1];
7876 tdlsParams.tx_packet_n = apps_args[2];
7877 /* ignore args[3] as discovery_period is not used anymore */
7878 tdlsParams.discovery_tries_n = apps_args[4];
7879 /* ignore args[5] as idle_timeout is not used anymore */
7880 tdlsParams.idle_packet_n = apps_args[6];
7881 /* ignore args[7] as rssi_hysteresis is not used anymore */
7882 tdlsParams.rssi_trigger_threshold = apps_args[8];
7883 tdlsParams.rssi_teardown_threshold = apps_args[9];
7884 tdlsParams.rssi_delta = apps_args[10];
7885
7886 wlan_hdd_tdls_set_params(dev, &tdlsParams);
7887 }
7888 break;
7889#endif
7890 case WE_UNIT_TEST_CMD:
7891 {
7892 t_wma_unit_test_cmd *unitTestArgs;
7893 cds_msg_t msg = { 0 };
7894 int i, j;
7895 if ((apps_args[0] < WLAN_MODULE_ID_MIN) ||
7896 (apps_args[0] >= WLAN_MODULE_ID_MAX)) {
7897 hddLog(LOGE, FL("Invalid MODULE ID %d"),
7898 apps_args[0]);
7899 return -EINVAL;
7900 }
7901 if (apps_args[1] > (WMA_MAX_NUM_ARGS)) {
7902 hddLog(LOGE, FL("Too Many args %d"),
7903 apps_args[1]);
7904 return -EINVAL;
7905 }
7906 unitTestArgs = cdf_mem_malloc(sizeof(*unitTestArgs));
7907 if (NULL == unitTestArgs) {
7908 hddLog(LOGE,
7909 FL("cdf_mem_alloc failed for unitTestArgs"));
7910 return -ENOMEM;
7911 }
7912 unitTestArgs->vdev_id = (int)pAdapter->sessionId;
7913 unitTestArgs->module_id = apps_args[0];
7914 unitTestArgs->num_args = apps_args[1];
7915 for (i = 0, j = 2; i < unitTestArgs->num_args; i++, j++) {
7916 unitTestArgs->args[i] = apps_args[j];
7917 }
7918 msg.type = SIR_HAL_UNIT_TEST_CMD;
7919 msg.reserved = 0;
7920 msg.bodyptr = unitTestArgs;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05307921 if (QDF_STATUS_SUCCESS !=
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007922 cds_mq_post_message(CDF_MODULE_ID_WMA, &msg)) {
7923 cdf_mem_free(unitTestArgs);
7924 CDF_TRACE(CDF_MODULE_ID_HDD,
7925 CDF_TRACE_LEVEL_ERROR,
7926 FL
7927 ("Not able to post UNIT_TEST_CMD message to WMA"));
7928 return -EINVAL;
7929 }
7930 }
7931 break;
7932#ifdef WLAN_FEATURE_GPIO_LED_FLASHING
7933 case WE_LED_FLASHING_PARAM:
7934 {
7935 int i;
7936 if (num_args != 4) {
7937 hddLog(LOGE,
7938 FL("gpio_control: 4 parameters are required"));
7939 return -EINVAL;
7940 }
7941 for (i = 0; i < num_args; i++) {
7942 if (apps_args[i] >= 0x7fffffff) {
7943 hddLog(LOGE,
7944 FL("gpio_control: parameter should be less than 0x7fffffff"));
7945 return -EINVAL;
7946 }
7947 }
7948 sme_set_led_flashing(WLAN_HDD_GET_HAL_CTX(pAdapter),
7949 0, apps_args[0], apps_args[1]);
7950 sme_set_led_flashing(WLAN_HDD_GET_HAL_CTX(pAdapter),
7951 1, apps_args[2], apps_args[3]);
7952 }
7953 break;
7954#endif
7955 default:
7956 {
7957 hddLog(LOGE, FL("Invalid IOCTL command %d"), sub_cmd);
7958 }
7959 break;
7960 }
Hanumantha Reddy Pothula2db50ed2015-11-23 10:48:33 +05307961 EXIT();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007962 return 0;
7963}
7964
7965/**
7966 * iw_hdd_set_var_ints_getnone() - set var ints getnone callback
7967 * @dev: pointer to net_device structure
7968 * @info: pointer to iw_request_info structure
7969 * @wrqu: pointer to iwreq_data
7970 * @extra; extra
7971 *
7972 * Return: 0 on success, error number otherwise
7973 *
7974 */
7975static int iw_hdd_set_var_ints_getnone(struct net_device *dev,
7976 struct iw_request_info *info,
7977 union iwreq_data *wrqu, char *extra)
7978{
7979 union iwreq_data u_priv_wrqu;
7980 int apps_args[MAX_VAR_ARGS] = {0};
7981 int ret, num_args;
7982
Mukul Sharma64a70e82015-11-02 20:05:09 +05307983 if (!capable(CAP_NET_ADMIN)) {
7984 CDF_TRACE(CDF_MODULE_ID_HDD, CDF_TRACE_LEVEL_ERROR,
7985 FL("permission check failed"));
7986 return -EPERM;
7987 }
7988
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007989 /* Helper function to get iwreq_data with compat handling. */
7990 if (hdd_priv_get_data(&u_priv_wrqu.data, wrqu))
7991 return -EINVAL;
7992
7993 if (NULL == u_priv_wrqu.data.pointer) {
7994 hddLog(LOGE, FL("NULL data pointer"));
7995 return -EINVAL;
7996 }
7997
7998 num_args = u_priv_wrqu.data.length;
7999 if (num_args > MAX_VAR_ARGS)
8000 num_args = MAX_VAR_ARGS;
8001
8002 if (copy_from_user(apps_args, u_priv_wrqu.data.pointer,
8003 (sizeof(int)) * num_args)) {
8004 hddLog(LOGE, FL("failed to copy data from user buffer"));
8005 return -EFAULT;
8006 }
8007
8008 cds_ssr_protect(__func__);
8009 ret = __iw_set_var_ints_getnone(dev, info, &u_priv_wrqu,
8010 (char *)&apps_args);
8011 cds_ssr_unprotect(__func__);
8012 return ret;
8013}
8014
8015/**
8016 * iw_set_var_ints_getnone - Generic "set many" private ioctl handler
8017 * @dev: device upon which the ioctl was received
8018 * @info: ioctl request information
8019 * @wrqu: ioctl request data
8020 * @extra: ioctl extra data
8021 *
8022 * This is a generic handler for private ioctls which take multiple
8023 * arguments. Note that this implementation is also somewhat unique
8024 * in that it is shared by both STA-mode and SAP-mode interfaces.
8025 *
8026 * Return: 0 on success, non-zero on error
8027 */
8028int iw_set_var_ints_getnone(struct net_device *dev,
8029 struct iw_request_info *info,
8030 union iwreq_data *wrqu, char *extra)
8031{
8032 int ret;
8033
8034 cds_ssr_protect(__func__);
8035 ret = __iw_set_var_ints_getnone(dev, info, wrqu, extra);
8036 cds_ssr_unprotect(__func__);
8037 return ret;
8038}
8039
8040/**
8041 * iw_add_tspec - Add TSpec private ioctl handler
8042 * @dev: device upon which the ioctl was received
8043 * @info: ioctl request information
8044 * @wrqu: ioctl request data
8045 * @extra: ioctl extra data
8046 *
8047 * Return: 0 on success, non-zero on error
8048 */
8049static int __iw_add_tspec(struct net_device *dev, struct iw_request_info *info,
8050 union iwreq_data *wrqu, char *extra)
8051{
8052 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
8053 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
8054 hdd_wlan_wmm_status_e *pStatus = (hdd_wlan_wmm_status_e *) extra;
8055 int params[HDD_WLAN_WMM_PARAM_COUNT];
8056 sme_QosWmmTspecInfo tSpec;
8057 uint32_t handle;
8058 struct iw_point s_priv_data;
8059 hdd_context_t *hdd_ctx;
8060 int ret;
8061
Hanumantha Reddy Pothula2db50ed2015-11-23 10:48:33 +05308062 ENTER();
8063
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008064 hdd_ctx = WLAN_HDD_GET_CTX(pAdapter);
8065 ret = wlan_hdd_validate_context(hdd_ctx);
8066 if (0 != ret)
8067 return ret;
8068
8069 /* make sure the application is sufficiently priviledged */
8070 /* note that the kernel will do this for "set" ioctls, but since */
8071 /* this ioctl wants to return status to user space it must be */
8072 /* defined as a "get" ioctl */
8073 if (!capable(CAP_NET_ADMIN)) {
8074 return -EPERM;
8075 }
8076
8077 /* we must be associated in order to add a tspec */
8078 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState) {
8079 *pStatus = HDD_WLAN_WMM_STATUS_SETUP_FAILED_BAD_PARAM;
8080 return 0;
8081 }
8082 /* since we are defined to be a "get" ioctl, and since the number */
8083 /* of params exceeds the number of params that wireless extensions */
8084 /* will pass down in the iwreq_data, we must copy the "set" params. */
8085 /* We must handle the compat for iwreq_data in 32U/64K environment. */
8086
8087 /* helper function to get iwreq_data with compat handling. */
8088 if (hdd_priv_get_data(&s_priv_data, wrqu)) {
8089 *pStatus = HDD_WLAN_WMM_STATUS_SETUP_FAILED_BAD_PARAM;
8090 return 0;
8091 }
8092 /* make sure all params are correctly passed to function */
8093 if ((NULL == s_priv_data.pointer) ||
8094 (HDD_WLAN_WMM_PARAM_COUNT != s_priv_data.length)) {
8095 *pStatus = HDD_WLAN_WMM_STATUS_SETUP_FAILED_BAD_PARAM;
8096 return 0;
8097 }
8098 /* from user space ourselves */
8099 if (copy_from_user(&params, s_priv_data.pointer, sizeof(params))) {
8100 /* hmmm, can't get them */
8101 return -EIO;
8102 }
8103 /* clear the tspec */
8104 memset(&tSpec, 0, sizeof(tSpec));
8105
8106 /* validate the handle */
8107 handle = params[HDD_WLAN_WMM_PARAM_HANDLE];
8108 if (HDD_WMM_HANDLE_IMPLICIT == handle) {
8109 /* that one is reserved */
8110 *pStatus = HDD_WLAN_WMM_STATUS_SETUP_FAILED_BAD_PARAM;
8111 return 0;
8112 }
8113 /* validate the TID */
8114 if (params[HDD_WLAN_WMM_PARAM_TID] > 7) {
8115 /* out of range */
8116 *pStatus = HDD_WLAN_WMM_STATUS_SETUP_FAILED_BAD_PARAM;
8117 return 0;
8118 }
8119 tSpec.ts_info.tid = params[HDD_WLAN_WMM_PARAM_TID];
8120
8121 /* validate the direction */
8122 switch (params[HDD_WLAN_WMM_PARAM_DIRECTION]) {
8123 case HDD_WLAN_WMM_DIRECTION_UPSTREAM:
8124 tSpec.ts_info.direction = SME_QOS_WMM_TS_DIR_UPLINK;
8125 break;
8126
8127 case HDD_WLAN_WMM_DIRECTION_DOWNSTREAM:
8128 tSpec.ts_info.direction = SME_QOS_WMM_TS_DIR_DOWNLINK;
8129 break;
8130
8131 case HDD_WLAN_WMM_DIRECTION_BIDIRECTIONAL:
8132 tSpec.ts_info.direction = SME_QOS_WMM_TS_DIR_BOTH;
8133 break;
8134
8135 default:
8136 /* unknown */
8137 *pStatus = HDD_WLAN_WMM_STATUS_SETUP_FAILED_BAD_PARAM;
8138 return 0;
8139 }
8140
8141 tSpec.ts_info.psb = params[HDD_WLAN_WMM_PARAM_APSD];
8142
8143 /* validate the user priority */
8144 if (params[HDD_WLAN_WMM_PARAM_USER_PRIORITY] >= SME_QOS_WMM_UP_MAX) {
8145 /* out of range */
8146 *pStatus = HDD_WLAN_WMM_STATUS_SETUP_FAILED_BAD_PARAM;
8147 return 0;
8148 }
8149 tSpec.ts_info.up = params[HDD_WLAN_WMM_PARAM_USER_PRIORITY];
8150 if (0 > tSpec.ts_info.up || SME_QOS_WMM_UP_MAX < tSpec.ts_info.up) {
8151 hddLog(CDF_TRACE_LEVEL_ERROR, "***ts_info.up out of bounds***");
8152 return 0;
8153 }
8154
8155 CDF_TRACE(CDF_MODULE_ID_HDD, CDF_TRACE_LEVEL_INFO_HIGH,
8156 "%s:TS_INFO PSB %d UP %d !!!", __func__,
8157 tSpec.ts_info.psb, tSpec.ts_info.up);
8158
8159 tSpec.nominal_msdu_size = params[HDD_WLAN_WMM_PARAM_NOMINAL_MSDU_SIZE];
8160 tSpec.maximum_msdu_size = params[HDD_WLAN_WMM_PARAM_MAXIMUM_MSDU_SIZE];
8161 tSpec.min_data_rate = params[HDD_WLAN_WMM_PARAM_MINIMUM_DATA_RATE];
8162 tSpec.mean_data_rate = params[HDD_WLAN_WMM_PARAM_MEAN_DATA_RATE];
8163 tSpec.peak_data_rate = params[HDD_WLAN_WMM_PARAM_PEAK_DATA_RATE];
8164 tSpec.max_burst_size = params[HDD_WLAN_WMM_PARAM_MAX_BURST_SIZE];
8165 tSpec.min_phy_rate = params[HDD_WLAN_WMM_PARAM_MINIMUM_PHY_RATE];
8166 tSpec.surplus_bw_allowance =
8167 params[HDD_WLAN_WMM_PARAM_SURPLUS_BANDWIDTH_ALLOWANCE];
8168 tSpec.min_service_interval =
8169 params[HDD_WLAN_WMM_PARAM_SERVICE_INTERVAL];
8170 tSpec.max_service_interval =
8171 params[HDD_WLAN_WMM_PARAM_MAX_SERVICE_INTERVAL];
8172 tSpec.suspension_interval =
8173 params[HDD_WLAN_WMM_PARAM_SUSPENSION_INTERVAL];
8174 tSpec.inactivity_interval =
8175 params[HDD_WLAN_WMM_PARAM_INACTIVITY_INTERVAL];
8176
8177 tSpec.ts_info.burst_size_defn =
8178 params[HDD_WLAN_WMM_PARAM_BURST_SIZE_DEFN];
8179
8180 /* validate the ts info ack policy */
8181 switch (params[HDD_WLAN_WMM_PARAM_ACK_POLICY]) {
8182 case HDD_WLAN_WMM_TS_INFO_ACK_POLICY_NORMAL_ACK:
8183 tSpec.ts_info.ack_policy = SME_QOS_WMM_TS_ACK_POLICY_NORMAL_ACK;
8184 break;
8185
8186 case HDD_WLAN_WMM_TS_INFO_ACK_POLICY_HT_IMMEDIATE_BLOCK_ACK:
8187 tSpec.ts_info.ack_policy =
8188 SME_QOS_WMM_TS_ACK_POLICY_HT_IMMEDIATE_BLOCK_ACK;
8189 break;
8190
8191 default:
8192 /* unknown */
8193 *pStatus = HDD_WLAN_WMM_STATUS_SETUP_FAILED_BAD_PARAM;
8194 return 0;
8195 }
8196
8197 *pStatus = hdd_wmm_addts(pAdapter, handle, &tSpec);
Hanumantha Reddy Pothula2db50ed2015-11-23 10:48:33 +05308198 EXIT();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008199 return 0;
8200}
8201
8202static int iw_add_tspec(struct net_device *dev,
8203 struct iw_request_info *info,
8204 union iwreq_data *wrqu, char *extra)
8205{
8206 int ret;
8207
8208 cds_ssr_protect(__func__);
8209 ret = __iw_add_tspec(dev, info, wrqu, extra);
8210 cds_ssr_unprotect(__func__);
8211
8212 return ret;
8213}
8214
8215/**
8216 * iw_del_tspec - Delete TSpec private ioctl handler
8217 * @dev: device upon which the ioctl was received
8218 * @info: ioctl request information
8219 * @wrqu: ioctl request data
8220 * @extra: ioctl extra data
8221 *
8222 * Return: 0 on success, non-zero on error
8223 */
8224static int __iw_del_tspec(struct net_device *dev, struct iw_request_info *info,
8225 union iwreq_data *wrqu, char *extra)
8226{
8227 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
8228 hdd_context_t *hdd_ctx;
8229 int *params = (int *)extra;
8230 hdd_wlan_wmm_status_e *pStatus = (hdd_wlan_wmm_status_e *) extra;
8231 uint32_t handle;
8232 int ret;
8233
Hanumantha Reddy Pothula2db50ed2015-11-23 10:48:33 +05308234 ENTER();
8235
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008236 hdd_ctx = WLAN_HDD_GET_CTX(pAdapter);
8237 ret = wlan_hdd_validate_context(hdd_ctx);
8238 if (0 != ret)
8239 return ret;
8240
8241 /* make sure the application is sufficiently priviledged */
8242 /* note that the kernel will do this for "set" ioctls, but since */
8243 /* this ioctl wants to return status to user space it must be */
8244 /* defined as a "get" ioctl */
8245 if (!capable(CAP_NET_ADMIN)) {
8246 return -EPERM;
8247 }
8248
8249 /* although we are defined to be a "get" ioctl, the params we require */
8250 /* will fit in the iwreq_data, therefore unlike iw_add_tspec() there */
8251 /* is no need to copy the params from user space */
8252
8253 /* validate the handle */
8254 handle = params[HDD_WLAN_WMM_PARAM_HANDLE];
8255 if (HDD_WMM_HANDLE_IMPLICIT == handle) {
8256 /* that one is reserved */
8257 *pStatus = HDD_WLAN_WMM_STATUS_SETUP_FAILED_BAD_PARAM;
8258 return 0;
8259 }
8260
8261 *pStatus = hdd_wmm_delts(pAdapter, handle);
Hanumantha Reddy Pothula2db50ed2015-11-23 10:48:33 +05308262 EXIT();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008263 return 0;
8264}
8265
8266static int iw_del_tspec(struct net_device *dev,
8267 struct iw_request_info *info,
8268 union iwreq_data *wrqu, char *extra)
8269{
8270 int ret;
8271
8272 cds_ssr_protect(__func__);
8273 ret = __iw_del_tspec(dev, info, wrqu, extra);
8274 cds_ssr_unprotect(__func__);
8275
8276 return ret;
8277}
8278
8279/**
8280 * iw_get_tspec - Get TSpec 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 * Return: 0 on success, non-zero on error
8287 */
8288static int __iw_get_tspec(struct net_device *dev, struct iw_request_info *info,
8289 union iwreq_data *wrqu, char *extra)
8290{
8291 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
8292 hdd_context_t *hdd_ctx;
8293 int *params = (int *)extra;
8294 hdd_wlan_wmm_status_e *pStatus = (hdd_wlan_wmm_status_e *) extra;
8295 uint32_t handle;
8296 int ret;
8297
Hanumantha Reddy Pothula2db50ed2015-11-23 10:48:33 +05308298 ENTER();
8299
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008300 hdd_ctx = WLAN_HDD_GET_CTX(pAdapter);
8301 ret = wlan_hdd_validate_context(hdd_ctx);
8302 if (0 != ret)
8303 return ret;
8304
8305 /* although we are defined to be a "get" ioctl, the params we require */
8306 /* will fit in the iwreq_data, therefore unlike iw_add_tspec() there */
8307 /* is no need to copy the params from user space */
8308
8309 /* validate the handle */
8310 handle = params[HDD_WLAN_WMM_PARAM_HANDLE];
8311 if (HDD_WMM_HANDLE_IMPLICIT == handle) {
8312 /* that one is reserved */
8313 *pStatus = HDD_WLAN_WMM_STATUS_SETUP_FAILED_BAD_PARAM;
8314 return 0;
8315 }
8316
8317 *pStatus = hdd_wmm_checkts(pAdapter, handle);
Hanumantha Reddy Pothula2db50ed2015-11-23 10:48:33 +05308318 EXIT();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008319 return 0;
8320}
8321
8322static int iw_get_tspec(struct net_device *dev,
8323 struct iw_request_info *info,
8324 union iwreq_data *wrqu, char *extra)
8325{
8326 int ret;
8327
8328 cds_ssr_protect(__func__);
8329 ret = __iw_get_tspec(dev, info, wrqu, extra);
8330 cds_ssr_unprotect(__func__);
8331
8332 return ret;
8333}
8334
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008335/**
8336 * iw_set_fties - Set FT IEs private ioctl handler
8337 * @dev: device upon which the ioctl was received
8338 * @info: ioctl request information
8339 * @wrqu: ioctl request data
8340 * @extra: ioctl extra data
8341 *
8342 * Each time the supplicant has the auth_request or reassoc request
8343 * IEs ready they are pushed to the driver. The driver will in turn
8344 * use it to send out the auth req and reassoc req for 11r FT Assoc.
8345 *
8346 * Return: 0 on success, non-zero on error
8347 */
8348static int __iw_set_fties(struct net_device *dev, struct iw_request_info *info,
8349 union iwreq_data *wrqu, char *extra)
8350{
8351 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
8352 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
8353 hdd_context_t *hdd_ctx;
8354 int ret;
8355
Hanumantha Reddy Pothula2db50ed2015-11-23 10:48:33 +05308356 ENTER();
8357
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008358 hdd_ctx = WLAN_HDD_GET_CTX(pAdapter);
8359 ret = wlan_hdd_validate_context(hdd_ctx);
8360 if (0 != ret)
8361 return ret;
8362
8363 if (!wrqu->data.length) {
8364 hddLog(LOGE, FL("called with 0 length IEs"));
8365 return -EINVAL;
8366 }
8367 if (wrqu->data.pointer == NULL) {
8368 hddLog(LOGE, FL("called with NULL IE"));
8369 return -EINVAL;
8370 }
8371 /* Added for debug on reception of Re-assoc Req. */
8372 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState) {
8373 hddLog(LOGE,
8374 FL("Called with Ie of length = %d when not associated"),
8375 wrqu->data.length);
8376 hddLog(LOGE, FL("Should be Re-assoc Req IEs"));
8377 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008378 hddLog(LOG1, FL("%s called with Ie of length = %d"), __func__,
8379 wrqu->data.length);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008380
8381 /* Pass the received FT IEs to SME */
8382 sme_set_ft_ies(WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
8383 extra, wrqu->data.length);
Hanumantha Reddy Pothula2db50ed2015-11-23 10:48:33 +05308384 EXIT();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008385 return 0;
8386}
8387
8388static int iw_set_fties(struct net_device *dev,
8389 struct iw_request_info *info,
8390 union iwreq_data *wrqu, char *extra)
8391{
8392 int ret;
8393
8394 cds_ssr_protect(__func__);
8395 ret = __iw_set_fties(dev, info, wrqu, extra);
8396 cds_ssr_unprotect(__func__);
8397
8398 return ret;
8399}
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008400
8401/**
8402 * iw_set_host_offload - Set host offload ioctl handler
8403 * @dev: device upon which the ioctl was received
8404 * @info: ioctl request information
8405 * @wrqu: ioctl request data
8406 * @extra: ioctl extra data
8407 *
8408 * Return: 0 on success, non-zero on error
8409 */
8410static int __iw_set_host_offload(struct net_device *dev,
8411 struct iw_request_info *info,
8412 union iwreq_data *wrqu, char *extra)
8413{
8414 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
8415 tpHostOffloadRequest pRequest = (tpHostOffloadRequest) extra;
8416 tSirHostOffloadReq offloadRequest;
8417 hdd_context_t *hdd_ctx;
8418 int ret;
8419
Hanumantha Reddy Pothula2db50ed2015-11-23 10:48:33 +05308420 ENTER();
8421
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008422 hdd_ctx = WLAN_HDD_GET_CTX(pAdapter);
8423 ret = wlan_hdd_validate_context(hdd_ctx);
8424 if (0 != ret)
8425 return ret;
8426
8427 if (!hdd_conn_is_connected(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))) {
8428 CDF_TRACE(CDF_MODULE_ID_HDD, CDF_TRACE_LEVEL_FATAL,
8429 "%s:LOGP dev is not in CONNECTED state, ignore!!!",
8430 __func__);
8431 return -EINVAL;
8432 }
8433
8434 /* Debug display of request components. */
8435 switch (pRequest->offloadType) {
8436 case WLAN_IPV4_ARP_REPLY_OFFLOAD:
8437 hddLog(CDF_TRACE_LEVEL_WARN,
8438 "%s: Host offload request: ARP reply", __func__);
8439 switch (pRequest->enableOrDisable) {
8440 case WLAN_OFFLOAD_DISABLE:
8441 hddLog(CDF_TRACE_LEVEL_WARN, " disable");
8442 break;
8443 case WLAN_OFFLOAD_ARP_AND_BC_FILTER_ENABLE:
8444 hddLog(CDF_TRACE_LEVEL_WARN, " BC Filtering enable");
8445 case WLAN_OFFLOAD_ENABLE:
8446 hddLog(CDF_TRACE_LEVEL_WARN, " ARP offload enable");
8447 hddLog(CDF_TRACE_LEVEL_WARN,
8448 " IP address: %d.%d.%d.%d",
8449 pRequest->params.hostIpv4Addr[0],
8450 pRequest->params.hostIpv4Addr[1],
8451 pRequest->params.hostIpv4Addr[2],
8452 pRequest->params.hostIpv4Addr[3]);
8453 }
8454 break;
8455
8456 case WLAN_IPV6_NEIGHBOR_DISCOVERY_OFFLOAD:
8457 hddLog(CDF_TRACE_LEVEL_INFO_HIGH,
8458 "%s: Host offload request: neighbor discovery",
8459 __func__);
8460 switch (pRequest->enableOrDisable) {
8461 case WLAN_OFFLOAD_DISABLE:
8462 hddLog(CDF_TRACE_LEVEL_INFO_HIGH, " disable");
8463 break;
8464 case WLAN_OFFLOAD_ENABLE:
8465 hddLog(CDF_TRACE_LEVEL_INFO_HIGH, " enable");
8466 hddLog(CDF_TRACE_LEVEL_INFO_HIGH,
8467 " IP address: %x:%x:%x:%x:%x:%x:%x:%x",
8468 *(uint16_t *) (pRequest->params.hostIpv6Addr),
8469 *(uint16_t *) (pRequest->params.hostIpv6Addr +
8470 2),
8471 *(uint16_t *) (pRequest->params.hostIpv6Addr +
8472 4),
8473 *(uint16_t *) (pRequest->params.hostIpv6Addr +
8474 6),
8475 *(uint16_t *) (pRequest->params.hostIpv6Addr +
8476 8),
8477 *(uint16_t *) (pRequest->params.hostIpv6Addr +
8478 10),
8479 *(uint16_t *) (pRequest->params.hostIpv6Addr +
8480 12),
8481 *(uint16_t *) (pRequest->params.hostIpv6Addr +
8482 14));
8483 }
8484 }
8485
8486 /* Execute offload request. The reason that we can copy the
8487 * request information from the ioctl structure to the SME
8488 * structure is that they are laid out exactly the same.
8489 * Otherwise, each piece of information would have to be
8490 * copied individually.
8491 */
8492 memcpy(&offloadRequest, pRequest, wrqu->data.length);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05308493 if (QDF_STATUS_SUCCESS !=
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008494 sme_set_host_offload(WLAN_HDD_GET_HAL_CTX(pAdapter),
8495 pAdapter->sessionId, &offloadRequest)) {
8496 hddLog(CDF_TRACE_LEVEL_ERROR,
8497 "%s: Failure to execute host offload request", __func__);
8498 return -EINVAL;
8499 }
Hanumantha Reddy Pothula2db50ed2015-11-23 10:48:33 +05308500 EXIT();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008501 return 0;
8502}
8503
8504static int iw_set_host_offload(struct net_device *dev,
8505 struct iw_request_info *info,
8506 union iwreq_data *wrqu, char *extra)
8507{
8508 int ret;
8509
8510 cds_ssr_protect(__func__);
8511 ret = __iw_set_host_offload(dev, info, wrqu, extra);
8512 cds_ssr_unprotect(__func__);
8513
8514 return ret;
8515}
8516
8517/**
8518 * iw_set_keepalive_params - Set keepalive params ioctl handler
8519 * @dev: device upon which the ioctl was received
8520 * @info: ioctl request information
8521 * @wrqu: ioctl request data
8522 * @extra: ioctl extra data
8523 *
8524 * Return: 0 on success, non-zero on error
8525 */
8526static int __iw_set_keepalive_params(struct net_device *dev,
8527 struct iw_request_info *info,
8528 union iwreq_data *wrqu, char *extra)
8529{
8530 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Rajeev Kumar3ddf1c62015-11-03 14:10:13 -08008531 tpSirKeepAliveReq request = (tpSirKeepAliveReq) extra;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008532 hdd_context_t *hdd_ctx;
8533 int ret;
8534
Hanumantha Reddy Pothula2db50ed2015-11-23 10:48:33 +05308535 ENTER();
8536
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008537 hdd_ctx = WLAN_HDD_GET_CTX(pAdapter);
8538 ret = wlan_hdd_validate_context(hdd_ctx);
8539 if (0 != ret)
8540 return ret;
8541
Rajeev Kumar3ddf1c62015-11-03 14:10:13 -08008542 if (wrqu->data.length != sizeof(*request)) {
8543 hdd_err("Invalid length %d", wrqu->data.length);
8544 return -EINVAL;
8545 }
8546
8547 if (request->timePeriod > WNI_CFG_INFRA_STA_KEEP_ALIVE_PERIOD_STAMAX) {
8548 hdd_err("Value of timePeriod %d exceed Max limit %d",
8549 request->timePeriod,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008550 WNI_CFG_INFRA_STA_KEEP_ALIVE_PERIOD_STAMAX);
8551 return -EINVAL;
8552 }
8553
8554 /* Debug display of request components. */
Rajeev Kumar3ddf1c62015-11-03 14:10:13 -08008555 hdd_info("Set Keep Alive Request : TimePeriod %d size %zu",
8556 request->timePeriod, sizeof(tSirKeepAliveReq));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008557
Rajeev Kumar3ddf1c62015-11-03 14:10:13 -08008558 switch (request->packetType) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008559 case WLAN_KEEP_ALIVE_NULL_PKT:
Rajeev Kumar3ddf1c62015-11-03 14:10:13 -08008560 hdd_info("Keep Alive Request: Tx NULL");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008561 break;
8562
8563 case WLAN_KEEP_ALIVE_UNSOLICIT_ARP_RSP:
Rajeev Kumar3ddf1c62015-11-03 14:10:13 -08008564 hdd_info("Keep Alive Request: Tx UnSolicited ARP RSP");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008565
Rajeev Kumar3ddf1c62015-11-03 14:10:13 -08008566 hdd_info("Host IP address: %d.%d.%d.%d",
8567 request->hostIpv4Addr[0], request->hostIpv4Addr[1],
8568 request->hostIpv4Addr[2], request->hostIpv4Addr[3]);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008569
Rajeev Kumar3ddf1c62015-11-03 14:10:13 -08008570 hdd_info("Dest IP address: %d.%d.%d.%d",
8571 request->destIpv4Addr[0], request->destIpv4Addr[1],
8572 request->destIpv4Addr[2], request->destIpv4Addr[3]);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008573
Srinivas Girigowda9c330a92015-11-24 12:28:25 -08008574 hdd_info("Dest MAC address: "MAC_ADDRESS_STR,
8575 MAC_ADDR_ARRAY(request->dest_macaddr.bytes));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008576 break;
8577 }
8578
Rajeev Kumar3ddf1c62015-11-03 14:10:13 -08008579 hdd_info("Keep alive period %d", request->timePeriod);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008580
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05308581 if (QDF_STATUS_SUCCESS !=
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008582 sme_set_keep_alive(WLAN_HDD_GET_HAL_CTX(pAdapter),
Rajeev Kumar3ddf1c62015-11-03 14:10:13 -08008583 pAdapter->sessionId, request)) {
8584 hdd_err("Failure to execute Keep Alive");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008585 return -EINVAL;
8586 }
Hanumantha Reddy Pothula2db50ed2015-11-23 10:48:33 +05308587 EXIT();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008588 return 0;
8589}
8590
8591static int iw_set_keepalive_params(struct net_device *dev,
8592 struct iw_request_info *info,
8593 union iwreq_data *wrqu,
8594 char *extra)
8595{
8596 int ret;
8597
8598 cds_ssr_protect(__func__);
8599 ret = __iw_set_keepalive_params(dev, info, wrqu, extra);
8600 cds_ssr_unprotect(__func__);
8601
8602 return ret;
8603}
8604
8605#ifdef WLAN_FEATURE_PACKET_FILTERING
8606/**
8607 * wlan_hdd_set_filter() - Set packet filter
8608 * @hdd_ctx: Global HDD context
8609 * @request: Packet filter request struct
8610 * @sessionId: Target session for the request
8611 *
8612 * Return: 0 on success, non-zero on error
8613 */
8614static int wlan_hdd_set_filter(hdd_context_t *hdd_ctx,
8615 struct pkt_filter_cfg *request,
8616 uint8_t sessionId)
8617{
8618 tSirRcvPktFilterCfgType packetFilterSetReq = {0};
8619 tSirRcvFltPktClearParam packetFilterClrReq = {0};
8620 int i = 0;
8621
8622 if (hdd_ctx->config->disablePacketFilter) {
8623 hdd_err("packet filtering disabled in ini returning");
8624 return 0;
8625 }
8626
8627 /* Debug display of request components. */
8628 hdd_info("Packet Filter Request : FA %d params %d",
8629 request->filter_action, request->num_params);
8630
8631 switch (request->filter_action) {
8632 case HDD_RCV_FILTER_SET:
8633 hdd_info("Set Packet Filter Request for Id: %d",
8634 request->filter_id);
8635
8636 packetFilterSetReq.filterId = request->filter_id;
8637 if (request->num_params >= HDD_MAX_CMP_PER_PACKET_FILTER) {
8638 hdd_err("Number of Params exceed Max limit %d",
8639 request->num_params);
8640 return -EINVAL;
8641 }
8642 packetFilterSetReq.numFieldParams = request->num_params;
8643 packetFilterSetReq.coalesceTime = 0;
8644 packetFilterSetReq.filterType = HDD_RCV_FILTER_SET;
8645 for (i = 0; i < request->num_params; i++) {
8646 packetFilterSetReq.paramsData[i].protocolLayer =
8647 request->params_data[i].protocol_layer;
8648 packetFilterSetReq.paramsData[i].cmpFlag =
8649 request->params_data[i].compare_flag;
8650 packetFilterSetReq.paramsData[i].dataOffset =
8651 request->params_data[i].data_offset;
8652 packetFilterSetReq.paramsData[i].dataLength =
8653 request->params_data[i].data_length;
8654 packetFilterSetReq.paramsData[i].reserved = 0;
8655
8656 if (request->params_data[i].data_length >
8657 SIR_MAX_FILTER_TEST_DATA_LEN) {
8658 hdd_err("Error invalid data length %d",
8659 request->params_data[i].data_length);
8660 return -EINVAL;
8661 }
8662
8663 hdd_info("Proto %d Comp Flag %d Filter Type %d",
8664 request->params_data[i].protocol_layer,
8665 request->params_data[i].compare_flag,
8666 packetFilterSetReq.filterType);
8667
8668 hdd_info("Data Offset %d Data Len %d",
8669 request->params_data[i].data_offset,
8670 request->params_data[i].data_length);
8671
8672 memcpy(&packetFilterSetReq.paramsData[i].compareData,
8673 request->params_data[i].compare_data,
8674 request->params_data[i].data_length);
8675 memcpy(&packetFilterSetReq.paramsData[i].dataMask,
8676 request->params_data[i].data_mask,
8677 request->params_data[i].data_length);
8678
8679 hdd_info("CData %d CData %d CData %d CData %d CData %d CData %d",
8680 request->params_data[i].compare_data[0],
8681 request->params_data[i].compare_data[1],
8682 request->params_data[i].compare_data[2],
8683 request->params_data[i].compare_data[3],
8684 request->params_data[i].compare_data[4],
8685 request->params_data[i].compare_data[5]);
8686
8687 hdd_info("MData %d MData %d MData %d MData %d MData %d MData %d",
8688 request->params_data[i].data_mask[0],
8689 request->params_data[i].data_mask[1],
8690 request->params_data[i].data_mask[2],
8691 request->params_data[i].data_mask[3],
8692 request->params_data[i].data_mask[4],
8693 request->params_data[i].data_mask[5]);
8694 }
8695
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05308696 if (QDF_STATUS_SUCCESS !=
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008697 sme_receive_filter_set_filter(hdd_ctx->hHal,
8698 &packetFilterSetReq,
8699 sessionId)) {
8700 hdd_err("Failure to execute Set Filter");
8701 return -EINVAL;
8702 }
8703
8704 break;
8705
8706 case HDD_RCV_FILTER_CLEAR:
8707
8708 hdd_info("Clear Packet Filter Request for Id: %d",
8709 request->filter_id);
8710 packetFilterClrReq.filterId = request->filter_id;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05308711 if (QDF_STATUS_SUCCESS !=
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008712 sme_receive_filter_clear_filter(hdd_ctx->hHal,
8713 &packetFilterClrReq,
8714 sessionId)) {
8715 hdd_err("Failure to execute Clear Filter");
8716 return -EINVAL;
8717 }
8718 break;
8719
8720 default:
8721 hdd_err("Packet Filter Request: Invalid %d",
8722 request->filter_action);
8723 return -EINVAL;
8724 }
8725 return 0;
8726}
8727
8728/**
8729 * __iw_set_packet_filter_params() - set packet filter parameters in target
8730 * @dev: Pointer to netdev
8731 * @info: Pointer to iw request info
8732 * @wrqu: Pointer to data
8733 * @extra: Pointer to extra data
8734 *
8735 * Return: 0 on success, non-zero on error
8736 */
8737static int __iw_set_packet_filter_params(struct net_device *dev,
8738 struct iw_request_info *info,
8739 union iwreq_data *wrqu, char *extra)
8740{
8741 int ret;
8742 hdd_context_t *hdd_ctx;
8743 struct iw_point priv_data;
8744 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
8745 struct pkt_filter_cfg *request = NULL;
8746
Mukul Sharma472382f2015-11-02 20:16:31 +05308747 if (!capable(CAP_NET_ADMIN)) {
8748 CDF_TRACE(CDF_MODULE_ID_HDD, CDF_TRACE_LEVEL_ERROR,
8749 FL("permission check failed"));
8750 return -EPERM;
8751 }
8752
Hanumantha Reddy Pothula2db50ed2015-11-23 10:48:33 +05308753 ENTER();
8754
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008755 hdd_ctx = WLAN_HDD_GET_CTX(adapter);
8756 ret = wlan_hdd_validate_context(hdd_ctx);
8757 if (0 != ret)
8758 return ret;
8759
8760 if (hdd_priv_get_data(&priv_data, wrqu)) {
8761 hdd_err("failed to get priv data");
8762 return -EINVAL;
8763 }
8764
8765 if ((NULL == priv_data.pointer) || (0 == priv_data.length)) {
8766 hdd_err("invalid priv data %p or invalid priv data length %d",
8767 priv_data.pointer, priv_data.length);
8768 return -EINVAL;
8769 }
8770
8771 /* copy data using copy_from_user */
8772 request = mem_alloc_copy_from_user_helper(priv_data.pointer,
8773 priv_data.length);
8774 if (NULL == request) {
8775 hdd_err("mem_alloc_copy_from_user_helper fail");
8776 return -ENOMEM;
8777 }
8778
8779 ret = wlan_hdd_set_filter(hdd_ctx, request, adapter->sessionId);
8780
8781 kfree(request);
Hanumantha Reddy Pothula2db50ed2015-11-23 10:48:33 +05308782 EXIT();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008783 return ret;
8784}
8785
8786/**
8787 * iw_set_packet_filter_params() - set packet filter parameters in target
8788 * @dev: Pointer to netdev
8789 * @info: Pointer to iw request info
8790 * @wrqu: Pointer to data
8791 * @extra: Pointer to extra data
8792 *
8793 * Return: 0 on success, non-zero on error
8794 */
8795static int iw_set_packet_filter_params(struct net_device *dev,
8796 struct iw_request_info *info,
8797 union iwreq_data *wrqu, char *extra)
8798{
8799 int ret;
8800
8801 cds_ssr_protect(__func__);
8802 ret = __iw_set_packet_filter_params(dev, info, wrqu, extra);
8803 cds_ssr_unprotect(__func__);
8804
8805 return ret;
8806}
8807#endif
8808
8809
8810static int __iw_get_statistics(struct net_device *dev,
8811 struct iw_request_info *info,
8812 union iwreq_data *wrqu, char *extra)
8813{
8814
Anurag Chouhance0dc992016-02-16 18:18:03 +05308815 QDF_STATUS qdf_status = QDF_STATUS_SUCCESS;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05308816 QDF_STATUS status = QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008817 hdd_wext_state_t *pWextState;
8818 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
8819 hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(pAdapter);
8820 char *p = extra;
8821 int tlen = 0;
8822 tCsrSummaryStatsInfo *pStats = &(pAdapter->hdd_stats.summary_stat);
8823 tCsrGlobalClassAStatsInfo *aStats = &(pAdapter->hdd_stats.ClassA_stat);
8824 tCsrGlobalClassDStatsInfo *dStats = &(pAdapter->hdd_stats.ClassD_stat);
8825 int ret;
8826
8827 ENTER();
8828
8829 ret = wlan_hdd_validate_context(hdd_ctx);
8830 if (0 != ret)
8831 return ret;
8832
8833 if (eConnectionState_Associated !=
8834 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState) {
8835
8836 wrqu->txpower.value = 0;
8837 } else {
8838 status = sme_get_statistics(hdd_ctx->hHal, eCSR_HDD,
8839 SME_SUMMARY_STATS |
8840 SME_GLOBAL_CLASSA_STATS |
8841 SME_GLOBAL_CLASSB_STATS |
8842 SME_GLOBAL_CLASSC_STATS |
8843 SME_GLOBAL_CLASSD_STATS |
8844 SME_PER_STA_STATS,
8845 hdd_statistics_cb, 0, false,
8846 (WLAN_HDD_GET_STATION_CTX_PTR
8847 (pAdapter))->conn_info.staId[0],
8848 pAdapter, pAdapter->sessionId);
8849
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05308850 if (QDF_STATUS_SUCCESS != status) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008851 hddLog(CDF_TRACE_LEVEL_ERROR,
8852 "%s: Unable to retrieve SME statistics",
8853 __func__);
8854 return -EINVAL;
8855 }
8856
8857 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
8858
Anurag Chouhance0dc992016-02-16 18:18:03 +05308859 qdf_status =
8860 qdf_wait_single_event(&pWextState->hdd_cdf_event,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008861 WLAN_WAIT_TIME_STATS);
Anurag Chouhance0dc992016-02-16 18:18:03 +05308862 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008863 hddLog(CDF_TRACE_LEVEL_ERROR,
8864 "%s: SME timeout while retrieving statistics",
8865 __func__);
8866 /*Remove the SME statistics list by passing NULL in callback argument */
8867 status = sme_get_statistics(hdd_ctx->hHal, eCSR_HDD,
8868 SME_SUMMARY_STATS |
8869 SME_GLOBAL_CLASSA_STATS |
8870 SME_GLOBAL_CLASSB_STATS |
8871 SME_GLOBAL_CLASSC_STATS |
8872 SME_GLOBAL_CLASSD_STATS |
8873 SME_PER_STA_STATS,
8874 NULL, 0, false,
8875 (WLAN_HDD_GET_STATION_CTX_PTR
8876 (pAdapter))->conn_info.
8877 staId[0], pAdapter,
8878 pAdapter->sessionId);
8879
8880 return -EINVAL;
8881 }
8882 FILL_TLV(p, (uint8_t) WLAN_STATS_RETRY_CNT,
8883 (uint8_t) sizeof(pStats->retry_cnt),
8884 (char *)&(pStats->retry_cnt[0]), tlen);
8885
8886 FILL_TLV(p, (uint8_t) WLAN_STATS_MUL_RETRY_CNT,
8887 (uint8_t) sizeof(pStats->multiple_retry_cnt),
8888 (char *)&(pStats->multiple_retry_cnt[0]), tlen);
8889
8890 FILL_TLV(p, (uint8_t) WLAN_STATS_TX_FRM_CNT,
8891 (uint8_t) sizeof(pStats->tx_frm_cnt),
8892 (char *)&(pStats->tx_frm_cnt[0]), tlen);
8893
8894 FILL_TLV(p, (uint8_t) WLAN_STATS_RX_FRM_CNT,
8895 (uint8_t) sizeof(pStats->rx_frm_cnt),
8896 (char *)&(pStats->rx_frm_cnt), tlen);
8897
8898 FILL_TLV(p, (uint8_t) WLAN_STATS_FRM_DUP_CNT,
8899 (uint8_t) sizeof(pStats->frm_dup_cnt),
8900 (char *)&(pStats->frm_dup_cnt), tlen);
8901
8902 FILL_TLV(p, (uint8_t) WLAN_STATS_FAIL_CNT,
8903 (uint8_t) sizeof(pStats->fail_cnt),
8904 (char *)&(pStats->fail_cnt[0]), tlen);
8905
8906 FILL_TLV(p, (uint8_t) WLAN_STATS_RTS_FAIL_CNT,
8907 (uint8_t) sizeof(pStats->rts_fail_cnt),
8908 (char *)&(pStats->rts_fail_cnt), tlen);
8909
8910 FILL_TLV(p, (uint8_t) WLAN_STATS_ACK_FAIL_CNT,
8911 (uint8_t) sizeof(pStats->ack_fail_cnt),
8912 (char *)&(pStats->ack_fail_cnt), tlen);
8913
8914 FILL_TLV(p, (uint8_t) WLAN_STATS_RTS_SUC_CNT,
8915 (uint8_t) sizeof(pStats->rts_succ_cnt),
8916 (char *)&(pStats->rts_succ_cnt), tlen);
8917
8918 FILL_TLV(p, (uint8_t) WLAN_STATS_RX_DISCARD_CNT,
8919 (uint8_t) sizeof(pStats->rx_discard_cnt),
8920 (char *)&(pStats->rx_discard_cnt), tlen);
8921
8922 FILL_TLV(p, (uint8_t) WLAN_STATS_RX_ERROR_CNT,
8923 (uint8_t) sizeof(pStats->rx_error_cnt),
8924 (char *)&(pStats->rx_error_cnt), tlen);
8925
8926 FILL_TLV(p, (uint8_t) WLAN_STATS_TX_BYTE_CNT,
8927 (uint8_t) sizeof(dStats->tx_uc_byte_cnt[0]),
8928 (char *)&(dStats->tx_uc_byte_cnt[0]), tlen);
8929
8930 FILL_TLV(p, (uint8_t) WLAN_STATS_RX_BYTE_CNT,
8931 (uint8_t) sizeof(dStats->rx_byte_cnt),
8932 (char *)&(dStats->rx_byte_cnt), tlen);
8933
8934 FILL_TLV(p, (uint8_t) WLAN_STATS_RX_RATE,
8935 (uint8_t) sizeof(dStats->rx_rate),
8936 (char *)&(dStats->rx_rate), tlen);
8937
8938 /* Transmit rate, in units of 500 kbit/sec */
8939 FILL_TLV(p, (uint8_t) WLAN_STATS_TX_RATE,
8940 (uint8_t) sizeof(aStats->tx_rate),
8941 (char *)&(aStats->tx_rate), tlen);
8942
8943 FILL_TLV(p, (uint8_t) WLAN_STATS_RX_UC_BYTE_CNT,
8944 (uint8_t) sizeof(dStats->rx_uc_byte_cnt[0]),
8945 (char *)&(dStats->rx_uc_byte_cnt[0]), tlen);
8946 FILL_TLV(p, (uint8_t) WLAN_STATS_RX_MC_BYTE_CNT,
8947 (uint8_t) sizeof(dStats->rx_mc_byte_cnt),
8948 (char *)&(dStats->rx_mc_byte_cnt), tlen);
8949 FILL_TLV(p, (uint8_t) WLAN_STATS_RX_BC_BYTE_CNT,
8950 (uint8_t) sizeof(dStats->rx_bc_byte_cnt),
8951 (char *)&(dStats->rx_bc_byte_cnt), tlen);
8952 FILL_TLV(p, (uint8_t) WLAN_STATS_TX_UC_BYTE_CNT,
8953 (uint8_t) sizeof(dStats->tx_uc_byte_cnt[0]),
8954 (char *)&(dStats->tx_uc_byte_cnt[0]), tlen);
8955 FILL_TLV(p, (uint8_t) WLAN_STATS_TX_MC_BYTE_CNT,
8956 (uint8_t) sizeof(dStats->tx_mc_byte_cnt),
8957 (char *)&(dStats->tx_mc_byte_cnt), tlen);
8958 FILL_TLV(p, (uint8_t) WLAN_STATS_TX_BC_BYTE_CNT,
8959 (uint8_t) sizeof(dStats->tx_bc_byte_cnt),
8960 (char *)&(dStats->tx_bc_byte_cnt), tlen);
8961
8962 wrqu->data.length = tlen;
8963
8964 }
8965
8966 EXIT();
8967
8968 return 0;
8969}
8970
8971static int iw_get_statistics(struct net_device *dev,
8972 struct iw_request_info *info,
8973 union iwreq_data *wrqu, char *extra)
8974{
8975 int ret;
8976
8977 cds_ssr_protect(__func__);
8978 ret = __iw_get_statistics(dev, info, wrqu, extra);
8979 cds_ssr_unprotect(__func__);
8980
8981 return ret;
8982}
8983
8984#ifdef FEATURE_WLAN_SCAN_PNO
8985
8986/*Max Len for PNO notification*/
8987#define MAX_PNO_NOTIFY_LEN 100
8988void found_pref_network_cb(void *callbackContext,
8989 tSirPrefNetworkFoundInd *pPrefNetworkFoundInd)
8990{
8991 hdd_adapter_t *pAdapter = (hdd_adapter_t *) callbackContext;
8992 union iwreq_data wrqu;
8993 char buf[MAX_PNO_NOTIFY_LEN + 1];
8994
8995 hddLog(CDF_TRACE_LEVEL_WARN,
8996 "A preferred network was found: %s with rssi: -%d",
8997 pPrefNetworkFoundInd->ssId.ssId, pPrefNetworkFoundInd->rssi);
8998
8999 /* create the event */
9000 memset(&wrqu, 0, sizeof(wrqu));
9001 memset(buf, 0, sizeof(buf));
9002
9003 snprintf(buf, MAX_PNO_NOTIFY_LEN,
9004 "QCOM: Found preferred network: %s with RSSI of -%u",
9005 pPrefNetworkFoundInd->ssId.ssId,
9006 (unsigned int)pPrefNetworkFoundInd->rssi);
9007
9008 wrqu.data.pointer = buf;
9009 wrqu.data.length = strlen(buf);
9010
9011 /* send the event */
9012
9013 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, buf);
9014
9015}
9016
9017/**
9018 * __iw_set_pno() - Preferred Network Offload ioctl handler
9019 * @dev: device upon which the ioctl was received
9020 * @info: ioctl request information
9021 * @wrqu: ioctl request data
9022 * @extra: ioctl extra data
9023 *
9024 * This function parses a Preferred Network Offload command
9025 * Input is string based and expected to be of the form:
9026 *
9027 * <enable(1) | disable(0)>
9028 * when enabling:
9029 * <number of networks>
9030 * for each network:
9031 * <ssid_len> <ssid> <authentication> <encryption>
9032 * <ch_num> <channel_list optional> <bcast_type> <rssi_threshold>
9033 * <number of scan timers>
9034 * for each timer:
9035 * <scan_time> <scan_repeat>
9036 * <suspend mode>
9037 *
9038 * e.g:
9039 * 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
9040 *
9041 * this translates into:
9042 * -----------------------------
9043 * enable PNO
9044 * 2 networks
9045 * Network 1:
9046 * test - with authentication type 0 and encryption type 0,
9047 * search on 3 channels: 1 6 and 11,
9048 * SSID bcast type is unknown (directed probe will be sent if
9049 * AP not found) and must meet -40dBm RSSI
9050 * Network 2:
9051 * test2 - with authentication type 4 and encryption type 4,
9052 * search on 6 channels 1, 2, 3, 4, 5 and 6
9053 * bcast type is non-bcast (directed probe will be sent)
9054 * and must not meet any RSSI threshold
9055 * 2 scan timers:
9056 * scan every 5 seconds 2 times
9057 * then scan every 300 seconds until stopped
9058 * enable on suspend
9059 */
9060static int __iw_set_pno(struct net_device *dev,
9061 struct iw_request_info *info,
9062 union iwreq_data *wrqu, char *extra)
9063{
9064 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
9065 hdd_context_t *hdd_ctx;
9066 int ret;
9067 int offset;
9068 char *ptr;
9069 uint8_t i, j, params, mode;
9070
9071 /* request is a large struct, so we make it static to avoid
9072 * stack overflow. This API is only invoked via ioctl, so it
9073 * is serialized by the kernel rtnl_lock and hence does not
9074 * need to be reentrant
9075 */
9076 static tSirPNOScanReq request;
9077
9078 ENTER();
9079
9080 hdd_ctx = WLAN_HDD_GET_CTX(adapter);
9081 ret = wlan_hdd_validate_context(hdd_ctx);
9082 if (ret)
9083 return ret;
9084
9085 hdd_notice("PNO data len %d data %s", wrqu->data.length, extra);
9086
9087 request.enable = 0;
9088 request.ucNetworksCount = 0;
9089
9090 ptr = extra;
9091
9092 if (1 != sscanf(ptr, "%hhu%n", &(request.enable), &offset)) {
9093 hdd_err("PNO enable input is not valid %s", ptr);
9094 return -EINVAL;
9095 }
9096
9097 if (0 == request.enable) {
9098 /* Disable PNO, ignore any other params */
9099 memset(&request, 0, sizeof(request));
9100 sme_set_preferred_network_list(WLAN_HDD_GET_HAL_CTX(adapter),
9101 &request, adapter->sessionId,
9102 found_pref_network_cb, adapter);
9103 return 0;
9104 }
9105
9106 ptr += offset;
9107
9108 if (1 !=
9109 sscanf(ptr, "%hhu %n", &(request.ucNetworksCount), &offset)) {
9110 hdd_err("PNO count input not valid %s", ptr);
9111 return -EINVAL;
9112
9113 }
9114
9115 hdd_info("PNO enable %d networks count %d offset %d",
9116 request.enable, request.ucNetworksCount, offset);
9117
9118 if ((0 == request.ucNetworksCount) ||
9119 (request.ucNetworksCount > SIR_PNO_MAX_SUPP_NETWORKS)) {
9120 hdd_err("Network count %d invalid",
9121 request.ucNetworksCount);
9122 return -EINVAL;
9123 }
9124
9125 ptr += offset;
9126
9127 for (i = 0; i < request.ucNetworksCount; i++) {
9128
9129 request.aNetworks[i].ssId.length = 0;
9130
9131 params = sscanf(ptr, "%hhu %n",
9132 &(request.aNetworks[i].ssId.length),
9133 &offset);
9134
9135 if (1 != params) {
9136 hdd_err("PNO ssid length input is not valid %s", ptr);
9137 return -EINVAL;
9138 }
9139
9140 if ((0 == request.aNetworks[i].ssId.length) ||
9141 (request.aNetworks[i].ssId.length > 32)) {
9142 hdd_err("SSID Len %d is not correct for network %d",
9143 request.aNetworks[i].ssId.length, i);
9144 return -EINVAL;
9145 }
9146
9147 /* Advance to SSID */
9148 ptr += offset;
9149
9150 memcpy(request.aNetworks[i].ssId.ssId, ptr,
9151 request.aNetworks[i].ssId.length);
9152 ptr += request.aNetworks[i].ssId.length;
9153
9154 params = sscanf(ptr, "%u %u %hhu %n",
9155 &(request.aNetworks[i].authentication),
9156 &(request.aNetworks[i].encryption),
9157 &(request.aNetworks[i].ucChannelCount),
9158 &offset);
9159
9160 if (3 != params) {
9161 hdd_warn("Incorrect cmd %s", ptr);
9162 return -EINVAL;
9163 }
9164
9165 hdd_notice("PNO len %d ssid %.*s auth %d encry %d channel count %d offset %d",
9166 request.aNetworks[i].ssId.length,
9167 request.aNetworks[i].ssId.length,
9168 request.aNetworks[i].ssId.ssId,
9169 request.aNetworks[i].authentication,
9170 request.aNetworks[i].encryption,
9171 request.aNetworks[i].ucChannelCount, offset);
9172
9173 /* Advance to channel list */
9174 ptr += offset;
9175
9176 if (SIR_PNO_MAX_NETW_CHANNELS <
9177 request.aNetworks[i].ucChannelCount) {
9178 hdd_warn("Incorrect number of channels");
9179 return -EINVAL;
9180 }
9181
9182 if (0 != request.aNetworks[i].ucChannelCount) {
9183 for (j = 0; j < request.aNetworks[i].ucChannelCount;
9184 j++) {
9185 if (1 !=
9186 sscanf(ptr, "%hhu %n",
9187 &(request.aNetworks[i].
9188 aChannels[j]), &offset)) {
9189 hdd_err("PNO network channel input is not valid %s",
9190 ptr);
9191 return -EINVAL;
9192 }
9193 /* Advance to next channel number */
9194 ptr += offset;
9195 }
9196 }
9197
9198 if (1 != sscanf(ptr, "%u %n",
9199 &(request.aNetworks[i].bcastNetwType),
9200 &offset)) {
9201 hdd_err("PNO broadcast network type input is not valid %s",
9202 ptr);
9203 return -EINVAL;
9204 }
9205
9206 hdd_notice("PNO bcastNetwType %d offset %d",
9207 request.aNetworks[i].bcastNetwType, offset);
9208
9209 /* Advance to rssi Threshold */
9210 ptr += offset;
9211 if (1 != sscanf(ptr, "%d %n",
9212 &(request.aNetworks[i].rssiThreshold),
9213 &offset)) {
9214 hdd_err("PNO rssi threshold input is not valid %s",
9215 ptr);
9216 return -EINVAL;
9217 }
9218 hdd_notice("PNO rssi %d offset %d",
9219 request.aNetworks[i].rssiThreshold, offset);
9220 /* Advance to next network */
9221 ptr += offset;
9222 } /* For ucNetworkCount */
9223
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08009224 params = sscanf(ptr, "%hhu %n", &(mode), &offset);
9225
9226 request.modePNO = mode;
9227 /* for LA we just expose suspend option */
9228 if ((1 != params) || (mode >= SIR_PNO_MODE_MAX)) {
9229 request.modePNO = SIR_PNO_MODE_ON_SUSPEND;
9230 }
9231
9232 sme_set_preferred_network_list(WLAN_HDD_GET_HAL_CTX(adapter),
9233 &request,
9234 adapter->sessionId,
9235 found_pref_network_cb, adapter);
9236
9237 return 0;
9238}
9239
9240static int iw_set_pno(struct net_device *dev,
9241 struct iw_request_info *info,
9242 union iwreq_data *wrqu, char *extra)
9243{
9244 int ret;
9245
9246 cds_ssr_protect(__func__);
9247 ret = __iw_set_pno(dev, info, wrqu, extra);
9248 cds_ssr_unprotect(__func__);
9249
9250 return ret;
9251}
9252#endif /* FEATURE_WLAN_SCAN_PNO */
9253
9254/* Common function to SetBand */
9255int hdd_set_band(struct net_device *dev, u8 ui_band)
9256{
9257 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
9258 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
9259 eCsrBand band;
9260
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05309261 QDF_STATUS status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08009262 hdd_context_t *pHddCtx;
9263 hdd_adapter_list_node_t *pAdapterNode, *pNext;
9264 eCsrBand currBand = eCSR_BAND_MAX;
9265 eCsrBand connectedBand;
9266
9267 pAdapterNode = NULL;
9268 pNext = NULL;
9269 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
9270
9271 switch (ui_band) {
9272 case WLAN_HDD_UI_BAND_AUTO:
9273 band = eCSR_BAND_ALL;
9274 break;
9275 case WLAN_HDD_UI_BAND_5_GHZ:
9276 band = eCSR_BAND_5G;
9277 break;
9278 case WLAN_HDD_UI_BAND_2_4_GHZ:
9279 band = eCSR_BAND_24;
9280 break;
9281 default:
9282 band = eCSR_BAND_MAX;
9283 }
9284
9285 CDF_TRACE(CDF_MODULE_ID_HDD, CDF_TRACE_LEVEL_INFO,
9286 "%s: change band to %u", __func__, band);
9287
9288 if (band == eCSR_BAND_MAX) {
9289 /* Received change band request with invalid band value */
9290 CDF_TRACE(CDF_MODULE_ID_HDD, CDF_TRACE_LEVEL_ERROR,
9291 "%s: Invalid band value %u", __func__, ui_band);
9292 return -EINVAL;
9293 }
9294
9295 if ((band == eCSR_BAND_24 && pHddCtx->config->nBandCapability == 2) ||
9296 (band == eCSR_BAND_5G && pHddCtx->config->nBandCapability == 1)) {
9297 CDF_TRACE(CDF_MODULE_ID_HDD, CDF_TRACE_LEVEL_ERROR,
9298 "%s: band value %u violate INI settings %u", __func__,
9299 band, pHddCtx->config->nBandCapability);
9300 return -EIO;
9301 }
9302
9303 if (band == eCSR_BAND_ALL) {
9304 hddLog(LOG1,
9305 FL("Auto band received. Setting band same as ini value %d"),
9306 pHddCtx->config->nBandCapability);
9307 band = pHddCtx->config->nBandCapability;
9308 }
9309
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05309310 if (QDF_STATUS_SUCCESS != sme_get_freq_band(hHal, &currBand)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08009311 CDF_TRACE(CDF_MODULE_ID_HDD, CDF_TRACE_LEVEL_INFO,
9312 "%s: Failed to get current band config", __func__);
9313 return -EIO;
9314 }
9315
9316 if (currBand != band) {
9317 /* Change band request received.
9318 * Abort pending scan requests, flush the existing scan results,
9319 * and change the band capability
9320 */
9321 CDF_TRACE(CDF_MODULE_ID_HDD, CDF_TRACE_LEVEL_INFO,
9322 "%s: Current band value = %u, new setting %u ",
9323 __func__, currBand, band);
9324
9325 status = hdd_get_front_adapter(pHddCtx, &pAdapterNode);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05309326 while (NULL != pAdapterNode && QDF_STATUS_SUCCESS == status) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08009327 pAdapter = pAdapterNode->pAdapter;
9328 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
9329 hdd_abort_mac_scan(pHddCtx, pAdapter->sessionId,
9330 eCSR_SCAN_ABORT_DUE_TO_BAND_CHANGE);
9331 connectedBand =
9332 hdd_conn_get_connected_band
9333 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter));
9334
9335 /* Handling is done only for STA and P2P */
9336 if (band != eCSR_BAND_ALL &&
9337 ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
9338 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT))
9339 &&
9340 (hdd_conn_is_connected
9341 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter)))
9342 && (connectedBand != band)) {
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05309343 QDF_STATUS status = QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08009344 long lrc;
9345
9346 /* STA already connected on current band, So issue disconnect
9347 * first, then change the band*/
9348
9349 hddLog(LOG1,
9350 FL("STA (Device mode %s(%d)) connected in band %u, Changing band to %u, Issuing Disconnect"),
9351 hdd_device_mode_to_string(pAdapter->device_mode),
9352 pAdapter->device_mode, currBand, band);
9353 INIT_COMPLETION(pAdapter->disconnect_comp_var);
9354
9355 status =
9356 sme_roam_disconnect(WLAN_HDD_GET_HAL_CTX
9357 (pAdapter),
9358 pAdapter->sessionId,
9359 eCSR_DISCONNECT_REASON_UNSPECIFIED);
9360
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05309361 if (QDF_STATUS_SUCCESS != status) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08009362 hddLog(CDF_TRACE_LEVEL_ERROR,
9363 "%s csr_roam_disconnect failure, returned %d",
9364 __func__, (int)status);
9365 return -EINVAL;
9366 }
9367
9368 lrc =
9369 wait_for_completion_timeout(&pAdapter->
9370 disconnect_comp_var,
9371 msecs_to_jiffies
9372 (WLAN_WAIT_TIME_DISCONNECT));
9373
9374 if (lrc == 0) {
9375 hddLog(CDF_TRACE_LEVEL_ERROR,
9376 "%s:Timeout while waiting for csr_roam_disconnect",
9377 __func__);
9378 return -ETIMEDOUT;
9379 }
9380 }
9381
9382 sme_scan_flush_result(hHal);
9383
9384 status =
9385 hdd_get_next_adapter(pHddCtx, pAdapterNode, &pNext);
9386 pAdapterNode = pNext;
9387 }
9388
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05309389 if (QDF_STATUS_SUCCESS !=
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08009390 sme_set_freq_band(hHal, pAdapter->sessionId, band)) {
9391 CDF_TRACE(CDF_MODULE_ID_HDD, CDF_TRACE_LEVEL_FATAL,
9392 FL("Failed to set the band value to %u"),
9393 band);
9394 return -EINVAL;
9395 }
9396 wlan_hdd_cfg80211_update_band(pHddCtx->wiphy, (eCsrBand) band);
9397 }
9398 return 0;
9399}
9400
9401int hdd_set_band_helper(struct net_device *dev, const char *command)
9402{
9403 uint8_t band;
9404 int ret;
9405
9406 /* Convert the band value from ascii to integer */
9407 command += WLAN_HDD_UI_SET_BAND_VALUE_OFFSET;
9408 ret = kstrtou8(command, 10, &band);
9409 if (ret < 0) {
9410 hddLog(LOGE, FL("kstrtou8 failed"));
9411 return -EINVAL;
9412 }
9413
9414 return hdd_set_band(dev, band);
9415}
9416
9417static int __iw_set_band_config(struct net_device *dev,
9418 struct iw_request_info *info,
9419 union iwreq_data *wrqu, char *extra)
9420{
9421 int *value = (int *)extra;
9422
9423 ENTER();
9424
Mukul Sharmaa5fe1982015-11-02 19:28:14 +05309425 if (!capable(CAP_NET_ADMIN)) {
9426 CDF_TRACE(CDF_MODULE_ID_HDD, CDF_TRACE_LEVEL_ERROR,
9427 FL("permission check failed"));
9428 return -EPERM;
9429 }
9430
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08009431 return hdd_set_band(dev, value[0]);
9432}
9433
9434static int iw_set_band_config(struct net_device *dev,
9435 struct iw_request_info *info,
9436 union iwreq_data *wrqu, char *extra)
9437{
9438 int ret;
9439
9440 cds_ssr_protect(__func__);
9441 ret = __iw_set_band_config(dev, info, wrqu, extra);
9442 cds_ssr_unprotect(__func__);
9443
9444 return ret;
9445}
9446
9447static int __iw_set_two_ints_getnone(struct net_device *dev,
9448 struct iw_request_info *info,
9449 union iwreq_data *wrqu, char *extra)
9450{
9451 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
9452 int *value = (int *)extra;
9453 int sub_cmd = value[0];
9454 int ret;
9455 hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(pAdapter);
9456
9457 ret = wlan_hdd_validate_context(hdd_ctx);
9458 if (0 != ret)
9459 return ret;
9460
9461 switch (sub_cmd) {
9462 case WE_SET_SMPS_PARAM:
9463 hddLog(LOG1, "WE_SET_SMPS_PARAM val %d %d", value[1], value[2]);
9464 ret = wma_cli_set_command(pAdapter->sessionId,
9465 WMI_STA_SMPS_PARAM_CMDID,
9466 value[1] << WMA_SMPS_PARAM_VALUE_S
9467 | value[2],
9468 VDEV_CMD);
9469 break;
9470#ifdef DEBUG
9471 case WE_SET_FW_CRASH_INJECT:
9472 hddLog(LOGE, "WE_SET_FW_CRASH_INJECT: %d %d",
9473 value[1], value[2]);
DARAM SUDHA7e7e91b2015-05-29 11:38:47 +05309474 pr_err("SSR is triggered by iwpriv CRASH_INJECT: %d %d\n",
9475 value[1], value[2]);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08009476 ret = wma_cli_set2_command(pAdapter->sessionId,
9477 GEN_PARAM_CRASH_INJECT,
9478 value[1], value[2], GEN_CMD);
9479 break;
9480#endif
Govind Singha471e5e2015-10-12 17:11:14 +05309481 case WE_ENABLE_FW_PROFILE:
9482 hddLog(LOGE, "WE_ENABLE_FW_PROFILE: %d %d",
9483 value[1], value[2]);
9484 ret = wma_cli_set2_command(pAdapter->sessionId,
9485 WMI_WLAN_PROFILE_ENABLE_PROFILE_ID_CMDID,
9486 value[1], value[2], DBG_CMD);
9487 break;
9488 case WE_SET_FW_PROFILE_HIST_INTVL:
9489 hddLog(LOGE, "WE_SET_FW_PROFILE_HIST_INTVL: %d %d",
9490 value[1], value[2]);
9491 ret = wma_cli_set2_command(pAdapter->sessionId,
9492 WMI_WLAN_PROFILE_SET_HIST_INTVL_CMDID,
9493 value[1], value[2], DBG_CMD);
9494 break;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08009495 case WE_SET_DUAL_MAC_FW_MODE_CONFIG:
9496 hdd_debug("Ioctl to set dual fw mode config");
9497 if (hdd_ctx->config->dual_mac_feature_disable) {
9498 hdd_err("Dual mac feature is disabled from INI");
9499 return -EPERM;
9500 }
9501 hdd_debug("%d %d", value[1], value[2]);
Tushnim Bhattacharyya4adb3682016-01-07 15:07:12 -08009502 cds_set_dual_mac_fw_mode_config(value[1], value[2]);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08009503 break;
9504 case WE_DUMP_DP_TRACE_LEVEL:
9505 hdd_info("WE_DUMP_DP_TRACE_LEVEL: %d %d",
9506 value[1], value[2]);
9507 if (value[1] == DUMP_DP_TRACE)
9508 cdf_dp_trace_dump_all(value[2]);
9509 break;
9510 default:
9511 hddLog(LOGE, "%s: Invalid IOCTL command %d", __func__, sub_cmd);
9512 break;
9513 }
9514
9515 return ret;
9516}
9517
9518static int iw_set_two_ints_getnone(struct net_device *dev,
9519 struct iw_request_info *info,
9520 union iwreq_data *wrqu, char *extra)
9521{
9522 int ret;
9523
9524 cds_ssr_protect(__func__);
9525 ret = __iw_set_two_ints_getnone(dev, info, wrqu, extra);
9526 cds_ssr_unprotect(__func__);
9527
9528 return ret;
9529}
9530
9531/* Define the Wireless Extensions to the Linux Network Device structure */
9532/* A number of these routines are NULL (meaning they are not implemented.) */
9533
9534static const iw_handler we_handler[] = {
9535 (iw_handler) iw_set_commit, /* SIOCSIWCOMMIT */
9536 (iw_handler) iw_get_name, /* SIOCGIWNAME */
9537 (iw_handler) NULL, /* SIOCSIWNWID */
9538 (iw_handler) NULL, /* SIOCGIWNWID */
9539 (iw_handler) iw_set_freq, /* SIOCSIWFREQ */
9540 (iw_handler) iw_get_freq, /* SIOCGIWFREQ */
9541 (iw_handler) iw_set_mode, /* SIOCSIWMODE */
9542 (iw_handler) iw_get_mode, /* SIOCGIWMODE */
9543 (iw_handler) NULL, /* SIOCSIWSENS */
9544 (iw_handler) NULL, /* SIOCGIWSENS */
9545 (iw_handler) NULL, /* SIOCSIWRANGE */
9546 (iw_handler) iw_get_range, /* SIOCGIWRANGE */
9547 (iw_handler) NULL, /* SIOCSIWPRIV */
9548 (iw_handler) NULL, /* SIOCGIWPRIV */
9549 (iw_handler) NULL, /* SIOCSIWSTATS */
9550 (iw_handler) NULL, /* SIOCGIWSTATS */
9551 (iw_handler) NULL, /* SIOCSIWSPY */
9552 (iw_handler) NULL, /* SIOCGIWSPY */
9553 (iw_handler) NULL, /* SIOCSIWTHRSPY */
9554 (iw_handler) NULL, /* SIOCGIWTHRSPY */
9555 (iw_handler) iw_set_ap_address, /* SIOCSIWAP */
9556 (iw_handler) iw_get_ap_address, /* SIOCGIWAP */
9557 (iw_handler) iw_set_mlme, /* SIOCSIWMLME */
9558 (iw_handler) NULL, /* SIOCGIWAPLIST */
9559 (iw_handler) iw_set_scan, /* SIOCSIWSCAN */
9560 (iw_handler) iw_get_scan, /* SIOCGIWSCAN */
9561 (iw_handler) iw_set_essid, /* SIOCSIWESSID */
9562 (iw_handler) iw_get_essid, /* SIOCGIWESSID */
9563 (iw_handler) iw_set_nick, /* SIOCSIWNICKN */
9564 (iw_handler) iw_get_nick, /* SIOCGIWNICKN */
9565 (iw_handler) NULL, /* -- hole -- */
9566 (iw_handler) NULL, /* -- hole -- */
9567 (iw_handler) iw_set_bitrate, /* SIOCSIWRATE */
9568 (iw_handler) iw_get_bitrate, /* SIOCGIWRATE */
9569 (iw_handler) iw_set_rts_threshold, /* SIOCSIWRTS */
9570 (iw_handler) iw_get_rts_threshold, /* SIOCGIWRTS */
9571 (iw_handler) iw_set_frag_threshold, /* SIOCSIWFRAG */
9572 (iw_handler) iw_get_frag_threshold, /* SIOCGIWFRAG */
9573 (iw_handler) iw_set_tx_power, /* SIOCSIWTXPOW */
9574 (iw_handler) iw_get_tx_power, /* SIOCGIWTXPOW */
9575 (iw_handler) iw_set_retry, /* SIOCSIWRETRY */
9576 (iw_handler) iw_get_retry, /* SIOCGIWRETRY */
9577 (iw_handler) iw_set_encode, /* SIOCSIWENCODE */
9578 (iw_handler) iw_get_encode, /* SIOCGIWENCODE */
9579 (iw_handler) iw_set_power_mode, /* SIOCSIWPOWER */
9580 (iw_handler) iw_get_power_mode, /* SIOCGIWPOWER */
9581 (iw_handler) NULL, /* -- hole -- */
9582 (iw_handler) NULL, /* -- hole -- */
9583 (iw_handler) iw_set_genie, /* SIOCSIWGENIE */
9584 (iw_handler) iw_get_genie, /* SIOCGIWGENIE */
9585 (iw_handler) iw_set_auth, /* SIOCSIWAUTH */
9586 (iw_handler) iw_get_auth, /* SIOCGIWAUTH */
9587 (iw_handler) iw_set_encodeext, /* SIOCSIWENCODEEXT */
9588 (iw_handler) iw_get_encodeext, /* SIOCGIWENCODEEXT */
9589 (iw_handler) NULL, /* SIOCSIWPMKSA */
9590};
9591
9592static const iw_handler we_private[] = {
9593
9594 [WLAN_PRIV_SET_INT_GET_NONE - SIOCIWFIRSTPRIV] = iw_setint_getnone, /* set priv ioctl */
9595 [WLAN_PRIV_SET_NONE_GET_INT - SIOCIWFIRSTPRIV] = iw_setnone_getint, /* get priv ioctl */
9596 [WLAN_PRIV_SET_CHAR_GET_NONE - SIOCIWFIRSTPRIV] = iw_setchar_getnone, /* get priv ioctl */
9597 [WLAN_PRIV_SET_THREE_INT_GET_NONE - SIOCIWFIRSTPRIV] =
9598 iw_set_three_ints_getnone,
9599 [WLAN_PRIV_GET_CHAR_SET_NONE - SIOCIWFIRSTPRIV] = iw_get_char_setnone,
9600 [WLAN_PRIV_SET_NONE_GET_NONE - SIOCIWFIRSTPRIV] = iw_setnone_getnone, /* action priv ioctl */
9601 [WLAN_PRIV_SET_VAR_INT_GET_NONE - SIOCIWFIRSTPRIV] =
9602 iw_hdd_set_var_ints_getnone,
9603 [WLAN_PRIV_ADD_TSPEC - SIOCIWFIRSTPRIV] = iw_add_tspec,
9604 [WLAN_PRIV_DEL_TSPEC - SIOCIWFIRSTPRIV] = iw_del_tspec,
9605 [WLAN_PRIV_GET_TSPEC - SIOCIWFIRSTPRIV] = iw_get_tspec,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08009606 [WLAN_PRIV_SET_FTIES - SIOCIWFIRSTPRIV] = iw_set_fties,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08009607 [WLAN_PRIV_SET_HOST_OFFLOAD - SIOCIWFIRSTPRIV] = iw_set_host_offload,
9608 [WLAN_GET_WLAN_STATISTICS - SIOCIWFIRSTPRIV] = iw_get_statistics,
9609 [WLAN_SET_KEEPALIVE_PARAMS - SIOCIWFIRSTPRIV] =
9610 iw_set_keepalive_params,
9611#ifdef WLAN_FEATURE_PACKET_FILTERING
9612 [WLAN_SET_PACKET_FILTER_PARAMS - SIOCIWFIRSTPRIV] =
9613 iw_set_packet_filter_params,
9614#endif
9615#ifdef FEATURE_WLAN_SCAN_PNO
9616 [WLAN_SET_PNO - SIOCIWFIRSTPRIV] = iw_set_pno,
9617#endif
9618 [WLAN_SET_BAND_CONFIG - SIOCIWFIRSTPRIV] = iw_set_band_config,
9619 [WLAN_GET_LINK_SPEED - SIOCIWFIRSTPRIV] = iw_get_linkspeed,
9620 [WLAN_PRIV_SET_TWO_INT_GET_NONE - SIOCIWFIRSTPRIV] =
9621 iw_set_two_ints_getnone,
9622 [WLAN_SET_DOT11P_CHANNEL_SCHED - SIOCIWFIRSTPRIV] =
9623 iw_set_dot11p_channel_sched,
9624};
9625
9626/*Maximum command length can be only 15 */
9627static const struct iw_priv_args we_private_args[] = {
9628
9629 /* handlers for main ioctl */
9630 {WLAN_PRIV_SET_INT_GET_NONE,
9631 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
9632 0,
9633 ""},
9634
9635 /* handlers for sub-ioctl */
9636 {WE_SET_11D_STATE,
9637 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
9638 0,
9639 "set11Dstate"},
9640
9641 {WE_WOWL,
9642 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
9643 0,
9644 "wowl"},
9645
9646 {WE_SET_POWER,
9647 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
9648 0,
9649 "setPower"},
9650
9651 {WE_SET_MAX_ASSOC,
9652 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
9653 0,
9654 "setMaxAssoc"},
9655
9656 {WE_SET_SAP_AUTO_CHANNEL_SELECTION,
9657 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0,
9658 "setAutoChannel" },
9659
9660 {WE_SET_SCAN_DISABLE,
9661 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
9662 0,
9663 "scan_disable"},
9664
9665 {WE_SET_DATA_INACTIVITY_TO,
9666 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
9667 0,
9668 "inactivityTO"},
9669
9670 {WE_SET_MAX_TX_POWER,
9671 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
9672 0,
9673 "setMaxTxPower"},
9674
9675 {WE_SET_TX_POWER,
9676 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
9677 0,
9678 "setTxPower"},
9679
9680 {WE_SET_MC_RATE,
9681 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
9682 0,
9683 "setMcRate"},
9684
9685 {WE_SET_MAX_TX_POWER_2_4,
9686 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
9687 0,
9688 "setTxMaxPower2G"},
9689
9690 {WE_SET_MAX_TX_POWER_5_0,
9691 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
9692 0,
9693 "setTxMaxPower5G"},
9694
9695 /* SAP has TxMax whereas STA has MaxTx, adding TxMax for STA
9696 * as well to keep same syntax as in SAP. Now onwards, STA
9697 * will support both */
9698 {WE_SET_MAX_TX_POWER,
9699 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
9700 0,
9701 "setTxMaxPower"},
9702
9703 /* set Higher DTIM Transition (DTIM1 to DTIM3)
9704 * 1 = enable and 0 = disable */
9705 {
9706 WE_SET_HIGHER_DTIM_TRANSITION,
9707 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
9708 0,
9709 "setHDtimTransn"
9710 },
9711
9712 {WE_SET_TM_LEVEL,
9713 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
9714 0,
9715 "setTmLevel"},
9716
9717 {WE_SET_PHYMODE,
9718 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
9719 0,
9720 "setphymode"},
9721
9722 {WE_SET_NSS,
9723 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
9724 0,
9725 "nss"},
9726
9727 {WE_SET_LDPC,
9728 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
9729 0,
9730 "ldpc"},
9731
9732 {WE_SET_TX_STBC,
9733 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
9734 0,
9735 "tx_stbc"},
9736
9737 {WE_SET_RX_STBC,
9738 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
9739 0,
9740 "rx_stbc"},
9741
9742 {WE_SET_SHORT_GI,
9743 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
9744 0,
9745 "shortgi"},
9746
9747 {WE_SET_RTSCTS,
9748 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
9749 0,
9750 "enablertscts"},
9751
9752 {WE_SET_CHWIDTH,
9753 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
9754 0,
9755 "chwidth"},
9756
9757 {WE_SET_ANI_EN_DIS,
9758 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
9759 0,
9760 "anienable"},
9761
9762 {WE_SET_ANI_POLL_PERIOD,
9763 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
9764 0,
9765 "aniplen"},
9766
9767 {WE_SET_ANI_LISTEN_PERIOD,
9768 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
9769 0,
9770 "anilislen"},
9771
9772 {WE_SET_ANI_OFDM_LEVEL,
9773 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
9774 0,
9775 "aniofdmlvl"},
9776
9777 {WE_SET_ANI_CCK_LEVEL,
9778 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
9779 0,
9780 "aniccklvl"},
9781
9782 {WE_SET_DYNAMIC_BW,
9783 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
9784 0,
9785 "cwmenable"},
9786
9787 {WE_SET_CTS_CBW,
9788 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
9789 0,
9790 "cts_cbw" },
9791
9792 {WE_SET_GTX_HT_MCS,
9793 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
9794 0,
9795 "gtxHTMcs"},
9796
9797 {WE_SET_GTX_VHT_MCS,
9798 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
9799 0,
9800 "gtxVHTMcs"},
9801
9802 {WE_SET_GTX_USRCFG,
9803 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
9804 0,
9805 "gtxUsrCfg"},
9806
9807 {WE_SET_GTX_THRE,
9808 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
9809 0,
9810 "gtxThre"},
9811
9812 {WE_SET_GTX_MARGIN,
9813 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
9814 0,
9815 "gtxMargin"},
9816
9817 {WE_SET_GTX_STEP,
9818 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
9819 0,
9820 "gtxStep"},
9821
9822 {WE_SET_GTX_MINTPC,
9823 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
9824 0,
9825 "gtxMinTpc"},
9826
9827 {WE_SET_GTX_BWMASK,
9828 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
9829 0,
9830 "gtxBWMask"},
9831
9832 {WE_SET_TX_CHAINMASK,
9833 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
9834 0,
9835 "txchainmask"},
9836
9837 {WE_SET_RX_CHAINMASK,
9838 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
9839 0,
9840 "rxchainmask"},
9841
9842 {WE_SET_11N_RATE,
9843 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
9844 0,
9845 "set11NRates"},
9846
9847 {WE_SET_VHT_RATE,
9848 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
9849 0,
9850 "set11ACRates"},
9851
9852 {WE_SET_AMPDU,
9853 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
9854 0,
9855 "ampdu"},
9856
9857 {WE_SET_AMSDU,
9858 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
9859 0,
9860 "amsdu"},
9861
9862 {WE_SET_BURST_ENABLE,
9863 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
9864 0,
9865 "burst_enable"},
9866
9867 {WE_SET_BURST_DUR,
9868 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
9869 0,
9870 "burst_dur"},
9871
9872 {WE_SET_TXPOW_2G,
9873 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
9874 0,
9875 "txpow2g"},
9876
9877 {WE_SET_TXPOW_5G,
9878 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
9879 0,
9880 "txpow5g"},
9881
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08009882 /* Sub-cmds DBGLOG specific commands */
9883 {WE_DBGLOG_LOG_LEVEL,
9884 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
9885 0,
9886 "dl_loglevel"},
9887
9888 {WE_DBGLOG_VAP_ENABLE,
9889 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
9890 0,
9891 "dl_vapon"},
9892
9893 {WE_DBGLOG_VAP_DISABLE,
9894 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
9895 0,
9896 "dl_vapoff"},
9897
9898 {WE_DBGLOG_MODULE_ENABLE,
9899 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
9900 0,
9901 "dl_modon"},
9902
9903 {WE_DBGLOG_MODULE_DISABLE,
9904 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
9905 0,
9906 "dl_modoff"},
9907
9908 {WE_DBGLOG_MOD_LOG_LEVEL,
9909 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
9910 0,
9911 "dl_mod_loglevel"},
9912
9913 {WE_DBGLOG_TYPE,
9914 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
9915 0,
9916 "dl_type"},
9917 {WE_DBGLOG_REPORT_ENABLE,
9918 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
9919 0,
9920 "dl_report"},
9921
9922 {WE_SET_TXRX_FWSTATS,
9923 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
9924 0,
9925 "txrx_fw_stats"},
9926
9927 {WE_TXRX_FWSTATS_RESET,
9928 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
9929 0,
9930 "txrx_fw_st_rst"},
9931
9932 {WE_PPS_PAID_MATCH,
9933 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
9934 0, "paid_match"},
9935
9936 {WE_PPS_GID_MATCH,
9937 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
9938 0, "gid_match"},
9939
9940 {WE_PPS_EARLY_TIM_CLEAR,
9941 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
9942 0, "tim_clear"},
9943
9944 {WE_PPS_EARLY_DTIM_CLEAR,
9945 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
9946 0, "dtim_clear"},
9947
9948 {WE_PPS_EOF_PAD_DELIM,
9949 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
9950 0, "eof_delim"},
9951
9952 {WE_PPS_MACADDR_MISMATCH,
9953 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
9954 0, "mac_match"},
9955
9956 {WE_PPS_DELIM_CRC_FAIL,
9957 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
9958 0, "delim_fail"},
9959
9960 {WE_PPS_GID_NSTS_ZERO,
9961 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
9962 0, "nsts_zero"},
9963
9964 {WE_PPS_RSSI_CHECK,
9965 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
9966 0, "rssi_chk"},
9967
9968 {WE_PPS_5G_EBT,
9969 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
9970 0, "5g_ebt"},
9971
9972 {WE_SET_HTSMPS,
9973 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
9974 0, "htsmps"},
9975
9976 {WE_SET_QPOWER_MAX_PSPOLL_COUNT,
9977 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
9978 0, "set_qpspollcnt"},
9979
9980 {WE_SET_QPOWER_MAX_TX_BEFORE_WAKE,
9981 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
9982 0, "set_qtxwake"},
9983
9984 {WE_SET_QPOWER_SPEC_PSPOLL_WAKE_INTERVAL,
9985 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
9986 0, "set_qwakeintv"},
9987
9988 {WE_SET_QPOWER_SPEC_MAX_SPEC_NODATA_PSPOLL,
9989 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
9990 0, "set_qnodatapoll"},
9991
9992 /* handlers for MCC time quota and latency sub ioctls */
9993 {WE_MCC_CONFIG_LATENCY,
9994 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
9995 0, "setMccLatency"},
9996
9997 {WE_MCC_CONFIG_QUOTA,
9998 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
9999 0, "setMccQuota"},
10000
10001 {WE_SET_DEBUG_LOG,
10002 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10003 0, "setDbgLvl"},
10004
10005 /* handlers for early_rx power save */
10006 {WE_SET_EARLY_RX_ADJUST_ENABLE,
10007 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10008 0, "erx_enable"},
10009
10010 {WE_SET_EARLY_RX_TGT_BMISS_NUM,
10011 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10012 0, "erx_bmiss_val"},
10013
10014 {WE_SET_EARLY_RX_BMISS_SAMPLE_CYCLE,
10015 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10016 0, "erx_bmiss_smpl"},
10017
10018 {WE_SET_EARLY_RX_SLOP_STEP,
10019 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10020 0, "erx_slop_step"},
10021
10022 {WE_SET_EARLY_RX_INIT_SLOP,
10023 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10024 0, "erx_init_slop"},
10025
10026 {WE_SET_EARLY_RX_ADJUST_PAUSE,
10027 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10028 0, "erx_adj_pause"},
10029
10030 {WE_SET_EARLY_RX_DRIFT_SAMPLE,
10031 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10032 0, "erx_dri_sample"},
10033
10034 {WE_DUMP_STATS,
10035 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10036 0, "dumpStats"},
10037
10038 {WE_CLEAR_STATS,
10039 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10040 0, "clearStats"},
10041
Govind Singha471e5e2015-10-12 17:11:14 +053010042 {WE_START_FW_PROFILE,
10043 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10044 0, "startProfile"},
10045
Abhishek Singh1bdb1572015-10-16 16:24:19 +053010046 {WE_SET_CHANNEL,
10047 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10048 0, "setChanChange" },
10049
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080010050 {WLAN_PRIV_SET_NONE_GET_INT,
10051 0,
10052 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10053 ""},
10054
10055 /* handlers for sub-ioctl */
10056 {WE_GET_11D_STATE,
10057 0,
10058 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10059 "get11Dstate"},
10060
10061 {WE_IBSS_STATUS,
10062 0,
10063 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10064 "getAdhocStatus"},
10065
10066 {WE_GET_WLAN_DBG,
10067 0,
10068 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10069 "getwlandbg"},
10070
10071 {WE_GET_MAX_ASSOC,
10072 0,
10073 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10074 "getMaxAssoc"},
10075
10076 {WE_GET_SAP_AUTO_CHANNEL_SELECTION,
10077 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10078 "getAutoChannel" },
10079
10080 {WE_GET_CONCURRENCY_MODE,
10081 0,
10082 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10083 "getconcurrency"},
10084
10085 {WE_GET_NSS,
10086 0,
10087 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10088 "get_nss"},
10089
10090 {WE_GET_LDPC,
10091 0,
10092 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10093 "get_ldpc"},
10094
10095 {WE_GET_TX_STBC,
10096 0,
10097 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10098 "get_tx_stbc"},
10099
10100 {WE_GET_RX_STBC,
10101 0,
10102 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10103 "get_rx_stbc"},
10104
10105 {WE_GET_SHORT_GI,
10106 0,
10107 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10108 "get_shortgi"},
10109
10110 {WE_GET_RTSCTS,
10111 0,
10112 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10113 "get_rtscts"},
10114
10115 {WE_GET_CHWIDTH,
10116 0,
10117 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10118 "get_chwidth"},
10119
10120 {WE_GET_ANI_EN_DIS,
10121 0,
10122 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10123 "get_anienable"},
10124
10125 {WE_GET_ANI_POLL_PERIOD,
10126 0,
10127 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10128 "get_aniplen"},
10129
10130 {WE_GET_ANI_LISTEN_PERIOD,
10131 0,
10132 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10133 "get_anilislen"},
10134
10135 {WE_GET_ANI_OFDM_LEVEL,
10136 0,
10137 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10138 "get_aniofdmlvl"},
10139
10140 {WE_GET_ANI_CCK_LEVEL,
10141 0,
10142 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10143 "get_aniccklvl"},
10144
10145 {WE_GET_DYNAMIC_BW,
10146 0,
10147 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10148 "get_cwmenable"},
10149
10150 {WE_GET_GTX_HT_MCS,
10151 0,
10152 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10153 "get_gtxHTMcs"},
10154
10155 {WE_GET_GTX_VHT_MCS,
10156 0,
10157 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10158 "get_gtxVHTMcs"},
10159
10160 {WE_GET_GTX_USRCFG,
10161 0,
10162 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10163 "get_gtxUsrCfg"},
10164
10165 {WE_GET_GTX_THRE,
10166 0,
10167 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10168 "get_gtxThre"},
10169
10170 {WE_GET_GTX_MARGIN,
10171 0,
10172 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10173 "get_gtxMargin"},
10174
10175 {WE_GET_GTX_STEP,
10176 0,
10177 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10178 "get_gtxStep"},
10179
10180 {WE_GET_GTX_MINTPC,
10181 0,
10182 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10183 "get_gtxMinTpc"},
10184
10185 {WE_GET_GTX_BWMASK,
10186 0,
10187 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10188 "get_gtxBWMask"},
10189
10190 {WE_GET_TX_CHAINMASK,
10191 0,
10192 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10193 "get_txchainmask"},
10194
10195 {WE_GET_RX_CHAINMASK,
10196 0,
10197 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10198 "get_rxchainmask"},
10199
10200 {WE_GET_11N_RATE,
10201 0,
10202 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10203 "get_11nrate"},
10204
10205 {WE_GET_AMPDU,
10206 0,
10207 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10208 "get_ampdu"},
10209
10210 {WE_GET_AMSDU,
10211 0,
10212 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10213 "get_amsdu"},
10214
10215 {WE_GET_BURST_ENABLE,
10216 0,
10217 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10218 "get_burst_en"},
10219
10220 {WE_GET_BURST_DUR,
10221 0,
10222 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10223 "get_burst_dur"},
10224
10225 {WE_GET_TXPOW_2G,
10226 0,
10227 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10228 "get_txpow2g"},
10229
10230 {WE_GET_TXPOW_5G,
10231 0,
10232 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10233 "get_txpow5g"},
10234
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080010235 {WE_GET_PPS_PAID_MATCH,
10236 0,
10237 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10238 "get_paid_match"},
10239
10240 {WE_GET_PPS_GID_MATCH,
10241 0,
10242 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10243 "get_gid_match"},
10244
10245 {WE_GET_PPS_EARLY_TIM_CLEAR,
10246 0,
10247 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10248 "get_tim_clear"},
10249
10250 {WE_GET_PPS_EARLY_DTIM_CLEAR,
10251 0,
10252 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10253 "get_dtim_clear"},
10254
10255 {WE_GET_PPS_EOF_PAD_DELIM,
10256 0,
10257 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10258 "get_eof_delim"},
10259
10260 {WE_GET_PPS_MACADDR_MISMATCH,
10261 0,
10262 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10263 "get_mac_match"},
10264
10265 {WE_GET_PPS_DELIM_CRC_FAIL,
10266 0,
10267 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10268 "get_delim_fail"},
10269
10270 {WE_GET_PPS_GID_NSTS_ZERO,
10271 0,
10272 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10273 "get_nsts_zero"},
10274
10275 {WE_GET_PPS_RSSI_CHECK,
10276 0,
10277 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10278 "get_rssi_chk"},
10279
10280 {WE_GET_QPOWER_MAX_PSPOLL_COUNT,
10281 0,
10282 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10283 "get_qpspollcnt"},
10284
10285 {WE_GET_QPOWER_MAX_TX_BEFORE_WAKE,
10286 0,
10287 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10288 "get_qtxwake"},
10289
10290 {WE_GET_QPOWER_SPEC_PSPOLL_WAKE_INTERVAL,
10291 0,
10292 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10293 "get_qwakeintv"},
10294
10295 {WE_GET_QPOWER_SPEC_MAX_SPEC_NODATA_PSPOLL,
10296 0,
10297 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10298 "get_qnodatapoll"},
10299
10300 {WE_GET_TEMPERATURE,
10301 0,
10302 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10303 "get_temp"},
10304 /* handlers for main ioctl */
10305 {WLAN_PRIV_SET_CHAR_GET_NONE,
10306 IW_PRIV_TYPE_CHAR | 512,
10307 0,
10308 ""},
10309
10310 /* handlers for sub-ioctl */
10311 {WE_WOWL_ADD_PTRN,
10312 IW_PRIV_TYPE_CHAR | 512,
10313 0,
10314 "wowlAddPtrn"},
10315
10316 {WE_WOWL_DEL_PTRN,
10317 IW_PRIV_TYPE_CHAR | 512,
10318 0,
10319 "wowlDelPtrn"},
10320
10321#if defined WLAN_FEATURE_VOWIFI
10322 /* handlers for sub-ioctl */
10323 {WE_NEIGHBOR_REPORT_REQUEST,
10324 IW_PRIV_TYPE_CHAR | 512,
10325 0,
10326 "neighbor"},
10327#endif
10328 {WE_SET_AP_WPS_IE,
10329 IW_PRIV_TYPE_CHAR | 512,
10330 0,
10331 "set_ap_wps_ie"},
10332
10333 {WE_SET_CONFIG,
10334 IW_PRIV_TYPE_CHAR | 512,
10335 0,
10336 "setConfig"},
10337
10338 /* handlers for main ioctl */
10339 {WLAN_PRIV_SET_THREE_INT_GET_NONE,
10340 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 3,
10341 0,
10342 ""},
10343
10344 /* handlers for sub-ioctl */
10345 {WE_SET_WLAN_DBG,
10346 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 3,
10347 0,
10348 "setwlandbg"},
10349
10350 /* handlers for sub-ioctl */
10351 {WE_SET_DP_TRACE,
10352 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 3,
10353 0,
10354 "set_dp_trace"},
10355
10356 {WE_SET_SAP_CHANNELS,
10357 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 3,
10358 0,
10359 "setsapchannels"},
10360
10361 {WE_SET_DUAL_MAC_SCAN_CONFIG,
10362 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 3,
10363 0,
10364 "set_scan_cfg"},
10365
10366 /* handlers for main ioctl */
10367 {WLAN_PRIV_GET_CHAR_SET_NONE,
10368 0,
10369 IW_PRIV_TYPE_CHAR | WE_MAX_STR_LEN,
10370 ""},
10371
10372 /* handlers for sub-ioctl */
10373 {WE_WLAN_VERSION,
10374 0,
10375 IW_PRIV_TYPE_CHAR | WE_MAX_STR_LEN,
10376 "version"},
10377 {WE_GET_STATS,
10378 0,
10379 IW_PRIV_TYPE_CHAR | WE_MAX_STR_LEN,
10380 "getStats"},
Govind Singha471e5e2015-10-12 17:11:14 +053010381 {WE_LIST_FW_PROFILE,
10382 0,
10383 IW_PRIV_TYPE_CHAR | WE_MAX_STR_LEN,
10384 "listProfile"},
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080010385 {WE_GET_STATES,
10386 0,
10387 IW_PRIV_TYPE_CHAR | WE_MAX_STR_LEN,
10388 "getHostStates"},
10389 {WE_GET_CFG,
10390 0,
10391 IW_PRIV_TYPE_CHAR | WE_MAX_STR_LEN,
10392 "getConfig"},
10393#ifdef WLAN_FEATURE_11AC
10394 {WE_GET_RSSI,
10395 0,
10396 IW_PRIV_TYPE_CHAR | WE_MAX_STR_LEN,
10397 "getRSSI"},
10398#endif
10399 {WE_GET_WMM_STATUS,
10400 0,
10401 IW_PRIV_TYPE_CHAR | WE_MAX_STR_LEN,
10402 "getWmmStatus"},
10403 {
10404 WE_GET_CHANNEL_LIST,
10405 0,
10406 IW_PRIV_TYPE_CHAR | WE_MAX_STR_LEN,
10407 "getChannelList"
10408 },
10409#ifdef FEATURE_WLAN_TDLS
10410 {
10411 WE_GET_TDLS_PEERS,
10412 0,
10413 IW_PRIV_TYPE_CHAR | WE_MAX_STR_LEN,
10414 "getTdlsPeers"
10415 },
10416#endif
10417#ifdef WLAN_FEATURE_11W
10418 {
10419 WE_GET_11W_INFO,
10420 0,
10421 IW_PRIV_TYPE_CHAR | WE_MAX_STR_LEN,
10422 "getPMFInfo"
10423 },
10424#endif
10425
10426 {WE_GET_PHYMODE,
10427 0,
10428 IW_PRIV_TYPE_CHAR | WE_MAX_STR_LEN,
10429 "getphymode"},
10430#ifdef FEATURE_OEM_DATA_SUPPORT
10431 {WE_GET_OEM_DATA_CAP,
10432 0,
10433 IW_PRIV_TYPE_CHAR | WE_MAX_STR_LEN,
10434 "getOemDataCap"},
10435#endif /* FEATURE_OEM_DATA_SUPPORT */
10436 {WE_GET_SNR,
10437 0,
10438 IW_PRIV_TYPE_CHAR | WE_MAX_STR_LEN,
10439 "getSNR"},
10440
10441 /* handlers for main ioctl */
10442 {WLAN_PRIV_SET_NONE_GET_NONE,
10443 0,
10444 0,
10445 ""},
10446
10447 {WE_GET_RECOVERY_STAT,
10448 0,
10449 0,
10450 "getRecoverStat"},
Govind Singha471e5e2015-10-12 17:11:14 +053010451
10452 {WE_GET_FW_PROFILE_DATA,
10453 0,
10454 0,
10455 "getProfileData"},
10456
10457 {WE_SET_REASSOC_TRIGGER,
10458 0,
10459 0,
10460 "reassoc"},
10461
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080010462 {WE_DUMP_AGC_START,
10463 0,
10464 0,
10465 "dump_agc_start"},
10466
10467 {WE_DUMP_AGC,
10468 0,
10469 0,
10470 "dump_agc"},
10471
10472 {WE_DUMP_CHANINFO_START,
10473 0,
10474 0,
10475 "dump_chninfo_en"},
10476
10477 {WE_DUMP_CHANINFO,
10478 0,
10479 0,
10480 "dump_chninfo"},
10481
10482 {WE_DUMP_WATCHDOG,
10483 0,
10484 0,
10485 "dump_watchdog"},
10486#ifdef CONFIG_ATH_PCIE_ACCESS_DEBUG
10487 {WE_DUMP_PCIE_LOG,
10488 0,
10489 0,
10490 "dump_pcie_log"},
10491#endif
10492 /* handlers for main ioctl */
10493 {WLAN_PRIV_SET_VAR_INT_GET_NONE,
10494 IW_PRIV_TYPE_INT | MAX_VAR_ARGS,
10495 0,
10496 ""},
10497
10498 /* handlers for sub-ioctl */
10499 {WE_MTRACE_SELECTIVE_MODULE_LOG_ENABLE_CMD,
10500 IW_PRIV_TYPE_INT | MAX_VAR_ARGS,
10501 0,
10502 "setdumplog"},
10503
10504 {WE_MTRACE_DUMP_CMD,
10505 IW_PRIV_TYPE_INT | MAX_VAR_ARGS,
10506 0,
10507 "dumplog"},
10508#ifdef MPC_UT_FRAMEWORK
10509 {WE_POLICY_MANAGER_CLIST_CMD,
10510 IW_PRIV_TYPE_INT | MAX_VAR_ARGS,
10511 0,
10512 "pm_clist"},
10513
10514 {WE_POLICY_MANAGER_DLIST_CMD,
10515 IW_PRIV_TYPE_INT | MAX_VAR_ARGS,
10516 0,
10517 "pm_dlist"},
10518
10519 {WE_POLICY_MANAGER_DBS_CMD,
10520 IW_PRIV_TYPE_INT | MAX_VAR_ARGS,
10521 0,
10522 "pm_dbs"},
10523
10524 {WE_POLICY_MANAGER_PCL_CMD,
10525 IW_PRIV_TYPE_INT | MAX_VAR_ARGS,
10526 0,
10527 "pm_pcl"},
10528
10529 {WE_POLICY_MANAGER_CINFO_CMD,
10530 IW_PRIV_TYPE_INT | MAX_VAR_ARGS,
10531 0,
10532 "pm_cinfo"},
10533
10534 {WE_POLICY_MANAGER_ULIST_CMD,
10535 IW_PRIV_TYPE_INT | MAX_VAR_ARGS,
10536 0,
10537 "pm_ulist"},
10538
10539 {WE_POLICY_MANAGER_QUERY_ACTION_CMD,
10540 IW_PRIV_TYPE_INT | MAX_VAR_ARGS,
10541 0,
10542 "pm_query_action"},
10543
10544 {WE_POLICY_MANAGER_QUERY_ALLOW_CMD,
10545 IW_PRIV_TYPE_INT | MAX_VAR_ARGS,
10546 0,
10547 "pm_query_allow"},
10548
10549 {WE_POLICY_MANAGER_SCENARIO_CMD,
10550 IW_PRIV_TYPE_INT | MAX_VAR_ARGS,
10551 0,
10552 "pm_run_scenario"},
10553
10554 {WE_POLICY_SET_HW_MODE_CMD,
10555 IW_PRIV_TYPE_INT | MAX_VAR_ARGS,
10556 0,
10557 "pm_set_hw_mode"},
10558#endif
10559#ifdef FEATURE_WLAN_TDLS
10560 /* handlers for sub ioctl */
10561 {
10562 WE_TDLS_CONFIG_PARAMS,
10563 IW_PRIV_TYPE_INT | MAX_VAR_ARGS,
10564 0,
10565 "setTdlsConfig"
10566 },
10567#endif
10568 {
10569 WE_UNIT_TEST_CMD,
10570 IW_PRIV_TYPE_INT | MAX_VAR_ARGS,
10571 0,
10572 "setUnitTestCmd"
10573 },
10574
10575#ifdef WLAN_FEATURE_GPIO_LED_FLASHING
10576 {WE_LED_FLASHING_PARAM,
10577 IW_PRIV_TYPE_INT | MAX_VAR_ARGS,
10578 0,
10579 "gpio_control"},
10580#endif
10581 /* handlers for main ioctl */
10582 {WLAN_PRIV_ADD_TSPEC,
10583 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | HDD_WLAN_WMM_PARAM_COUNT,
10584 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10585 "addTspec"},
10586
10587 /* handlers for main ioctl */
10588 {WLAN_PRIV_DEL_TSPEC,
10589 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10590 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10591 "delTspec"},
10592
10593 /* handlers for main ioctl */
10594 {WLAN_PRIV_GET_TSPEC,
10595 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10596 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10597 "getTspec"},
10598
10599 /* handlers for main ioctl - host offload */
10600 {
10601 WLAN_PRIV_SET_HOST_OFFLOAD,
10602 IW_PRIV_TYPE_BYTE | sizeof(tHostOffloadRequest),
10603 0,
10604 "setHostOffload"
10605 }
10606 ,
10607
10608 {
10609 WLAN_GET_WLAN_STATISTICS,
10610 0,
10611 IW_PRIV_TYPE_BYTE | WE_MAX_STR_LEN,
10612 "getWlanStats"
10613 }
10614 ,
10615
10616 {
10617 WLAN_SET_KEEPALIVE_PARAMS,
Rajeev Kumar3ddf1c62015-11-03 14:10:13 -080010618 sizeof(tSirKeepAliveReq) | IW_PRIV_SIZE_FIXED,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080010619 0,
10620 "setKeepAlive"
10621 }
10622 ,
10623#ifdef WLAN_FEATURE_PACKET_FILTERING
10624 {
10625 WLAN_SET_PACKET_FILTER_PARAMS,
10626 IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED |
10627 sizeof(struct pkt_filter_cfg),
10628 0,
10629 "setPktFilter"
10630 }
10631 ,
10632#endif
10633#ifdef FEATURE_WLAN_SCAN_PNO
10634 {
10635 WLAN_SET_PNO,
10636 IW_PRIV_TYPE_CHAR | WE_MAX_STR_LEN,
10637 0,
10638 "setpno"
10639 }
10640 ,
10641#endif
10642 {
10643 WLAN_SET_BAND_CONFIG,
10644 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
10645 0,
10646 "SETBAND"
10647 }
10648 ,
10649 {
10650 WLAN_GET_LINK_SPEED,
10651 IW_PRIV_TYPE_CHAR | 18,
10652 IW_PRIV_TYPE_CHAR | 5, "getLinkSpeed"
10653 }
10654 ,
10655
10656 /* handlers for main ioctl */
10657 {WLAN_PRIV_SET_TWO_INT_GET_NONE,
10658 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2,
10659 0,
10660 ""}
10661 ,
10662 {WE_SET_SMPS_PARAM,
10663 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2,
10664 0, "set_smps_param"}
10665 ,
10666 {WLAN_SET_DOT11P_CHANNEL_SCHED,
10667 IW_PRIV_TYPE_BYTE | sizeof(struct dot11p_channel_sched),
10668 0, "set_dot11p" }
10669 ,
10670#ifdef DEBUG
10671 {WE_SET_FW_CRASH_INJECT,
10672 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2,
10673 0, "crash_inject"}
10674 ,
10675#endif
Govind Singha471e5e2015-10-12 17:11:14 +053010676 {WE_ENABLE_FW_PROFILE,
10677 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2,
10678 0, "enableProfile"}
10679 ,
10680 {WE_SET_FW_PROFILE_HIST_INTVL,
10681 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2,
10682 0, "set_hist_intvl"}
10683 ,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080010684 {WE_SET_DUAL_MAC_FW_MODE_CONFIG,
10685 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2,
10686 0, "set_fw_mode_cfg"}
10687 ,
10688 {WE_DUMP_DP_TRACE_LEVEL,
10689 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2,
10690 0, "dump_dp_trace"}
10691 ,
10692};
10693
10694const struct iw_handler_def we_handler_def = {
10695 .num_standard = CDF_ARRAY_SIZE(we_handler),
10696 .num_private = CDF_ARRAY_SIZE(we_private),
10697 .num_private_args = CDF_ARRAY_SIZE(we_private_args),
10698
10699 .standard = (iw_handler *) we_handler,
10700 .private = (iw_handler *) we_private,
10701 .private_args = we_private_args,
10702 .get_wireless_stats = NULL,
10703};
10704
10705int hdd_set_wext(hdd_adapter_t *pAdapter)
10706{
10707 hdd_wext_state_t *pwextBuf;
10708 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
10709
10710 pwextBuf = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
10711
10712 /* Now configure the roaming profile links. To SSID and bssid. */
10713 pwextBuf->roamProfile.SSIDs.numOfSSIDs = 0;
10714 pwextBuf->roamProfile.SSIDs.SSIDList = &pHddStaCtx->conn_info.SSID;
10715
10716 pwextBuf->roamProfile.BSSIDs.numOfBSSIDs = 0;
10717 pwextBuf->roamProfile.BSSIDs.bssid = &pHddStaCtx->conn_info.bssId;
10718
10719 /*Set the numOfChannels to zero to scan all the channels */
10720 pwextBuf->roamProfile.ChannelInfo.numOfChannels = 0;
10721 pwextBuf->roamProfile.ChannelInfo.ChannelList = NULL;
10722
10723 /* Default is no encryption */
10724 pwextBuf->roamProfile.EncryptionType.numEntries = 1;
10725 pwextBuf->roamProfile.EncryptionType.encryptionType[0] =
10726 eCSR_ENCRYPT_TYPE_NONE;
10727
10728 pwextBuf->roamProfile.mcEncryptionType.numEntries = 1;
10729 pwextBuf->roamProfile.mcEncryptionType.encryptionType[0] =
10730 eCSR_ENCRYPT_TYPE_NONE;
10731
10732 pwextBuf->roamProfile.BSSType = eCSR_BSS_TYPE_INFRASTRUCTURE;
10733
10734 /* Default is no authentication */
10735 pwextBuf->roamProfile.AuthType.numEntries = 1;
10736 pwextBuf->roamProfile.AuthType.authType[0] = eCSR_AUTH_TYPE_OPEN_SYSTEM;
10737
10738 pwextBuf->roamProfile.phyMode = eCSR_DOT11_MODE_AUTO;
10739 pwextBuf->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
10740
10741 /*Set the default scan mode */
10742 pAdapter->scan_info.scan_mode = eSIR_ACTIVE_SCAN;
10743
10744 hdd_clear_roam_profile_ie(pAdapter);
10745
Anurag Chouhanfb54ab02016-02-18 18:00:46 +053010746 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080010747
10748}
10749
10750int hdd_register_wext(struct net_device *dev)
10751{
10752 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
10753 hdd_wext_state_t *pwextBuf = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Anurag Chouhance0dc992016-02-16 18:18:03 +053010754 QDF_STATUS status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080010755
10756 ENTER();
10757
10758 /* Zero the memory. This zeros the profile structure. */
10759 memset(pwextBuf, 0, sizeof(hdd_wext_state_t));
10760
10761 init_completion(&(WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter))->
10762 completion_var);
10763
10764 status = hdd_set_wext(pAdapter);
10765
Anurag Chouhance0dc992016-02-16 18:18:03 +053010766 if (!QDF_IS_STATUS_SUCCESS(status)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080010767
10768 CDF_TRACE(CDF_MODULE_ID_HDD, CDF_TRACE_LEVEL_ERROR,
10769 ("ERROR: hdd_set_wext failed!!"));
Anurag Chouhanfb54ab02016-02-18 18:00:46 +053010770 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080010771 }
10772
Anurag Chouhance0dc992016-02-16 18:18:03 +053010773 if (!QDF_IS_STATUS_SUCCESS(qdf_event_create(&pwextBuf->hdd_cdf_event))) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080010774 CDF_TRACE(CDF_MODULE_ID_HDD, CDF_TRACE_LEVEL_ERROR,
10775 ("ERROR: HDD cdf event init failed!!"));
Anurag Chouhanfb54ab02016-02-18 18:00:46 +053010776 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080010777 }
10778
Anurag Chouhance0dc992016-02-16 18:18:03 +053010779 if (!QDF_IS_STATUS_SUCCESS(qdf_event_create(&pwextBuf->scanevent))) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080010780 CDF_TRACE(CDF_MODULE_ID_HDD, CDF_TRACE_LEVEL_ERROR,
10781 ("ERROR: HDD scan event init failed!!"));
Anurag Chouhanfb54ab02016-02-18 18:00:46 +053010782 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080010783 }
10784 /* Register as a wireless device */
10785 dev->wireless_handlers = (struct iw_handler_def *)&we_handler_def;
10786
10787 EXIT();
10788 return 0;
10789}
10790
10791int hdd_unregister_wext(struct net_device *dev)
10792{
10793 hddLog(LOG1, FL("dev(%p)"), dev);
10794
10795 if (dev != NULL) {
10796 rtnl_lock();
10797 dev->wireless_handlers = NULL;
10798 rtnl_unlock();
10799 }
10800
10801 return 0;
10802}