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