.. | .. |
---|
1 | | -/* SPDX-License-Identifier: GPL-2.0 */ |
---|
2 | 1 | /* |
---|
3 | 2 | * Linux Wireless Extensions support |
---|
4 | 3 | * |
---|
5 | | - * Copyright (C) 1999-2019, Broadcom Corporation |
---|
6 | | - * |
---|
| 4 | + * Portions of this code are copyright (c) 2022 Cypress Semiconductor Corporation |
---|
| 5 | + * |
---|
| 6 | + * Copyright (C) 1999-2017, Broadcom Corporation |
---|
| 7 | + * |
---|
7 | 8 | * Unless you and Broadcom execute a separate written software license |
---|
8 | 9 | * agreement governing use of this software, this software is licensed to you |
---|
9 | 10 | * under the terms of the GNU General Public License version 2 (the "GPL"), |
---|
10 | 11 | * available at http://www.broadcom.com/licenses/GPLv2.php, with the |
---|
11 | 12 | * following added to such license: |
---|
12 | | - * |
---|
| 13 | + * |
---|
13 | 14 | * As a special exception, the copyright holders of this software give you |
---|
14 | 15 | * permission to link this software with independent modules, and to copy and |
---|
15 | 16 | * distribute the resulting executable under terms of your choice, provided that |
---|
.. | .. |
---|
17 | 18 | * the license of that module. An independent module is a module which is not |
---|
18 | 19 | * derived from this software. The special exception does not apply to any |
---|
19 | 20 | * modifications of the software. |
---|
20 | | - * |
---|
| 21 | + * |
---|
21 | 22 | * Notwithstanding the above, under no circumstances may you combine this |
---|
22 | 23 | * software in any way with any other Broadcom software provided under a license |
---|
23 | 24 | * other than the GPL, without Broadcom's express prior written consent. |
---|
.. | .. |
---|
25 | 26 | * |
---|
26 | 27 | * <<Broadcom-WL-IPTag/Open:>> |
---|
27 | 28 | * |
---|
28 | | - * $Id: wl_iw.c 709309 2019-01-17 09:04:00Z $ |
---|
| 29 | + * $Id: wl_iw.c 693575 2017-04-04 06:45:00Z $ |
---|
29 | 30 | */ |
---|
30 | 31 | |
---|
31 | 32 | #if defined(USE_IW) |
---|
.. | .. |
---|
37 | 38 | |
---|
38 | 39 | #include <bcmutils.h> |
---|
39 | 40 | #include <bcmendian.h> |
---|
40 | | -#include <proto/ethernet.h> |
---|
41 | | - |
---|
42 | | -#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 11, 0) |
---|
43 | | -#include <linux/sched/signal.h> |
---|
44 | | -#endif |
---|
| 41 | +#include <ethernet.h> |
---|
45 | 42 | |
---|
46 | 43 | #include <linux/if_arp.h> |
---|
47 | | -#include <linux/uaccess.h> |
---|
48 | | - |
---|
| 44 | +#include <asm/uaccess.h> |
---|
| 45 | +#include <linux/signal.h> |
---|
| 46 | +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 11, 0)) |
---|
| 47 | +#include <linux/sched/signal.h> |
---|
| 48 | +#endif // endif |
---|
49 | 49 | #include <wlioctl.h> |
---|
50 | 50 | #include <wlioctl_utils.h> |
---|
51 | 51 | |
---|
.. | .. |
---|
54 | 54 | #include <wl_dbg.h> |
---|
55 | 55 | #include <wl_iw.h> |
---|
56 | 56 | |
---|
| 57 | +#ifdef BCMWAPI_WPI |
---|
| 58 | +/* these items should evetually go into wireless.h of the linux system headfile dir */ |
---|
| 59 | +#ifndef IW_ENCODE_ALG_SM4 |
---|
| 60 | +#define IW_ENCODE_ALG_SM4 0x20 |
---|
| 61 | +#endif // endif |
---|
| 62 | + |
---|
| 63 | +#ifndef IW_AUTH_WAPI_ENABLED |
---|
| 64 | +#define IW_AUTH_WAPI_ENABLED 0x20 |
---|
| 65 | +#endif // endif |
---|
| 66 | + |
---|
| 67 | +#ifndef IW_AUTH_WAPI_VERSION_1 |
---|
| 68 | +#define IW_AUTH_WAPI_VERSION_1 0x00000008 |
---|
| 69 | +#endif // endif |
---|
| 70 | + |
---|
| 71 | +#ifndef IW_AUTH_CIPHER_SMS4 |
---|
| 72 | +#define IW_AUTH_CIPHER_SMS4 0x00000020 |
---|
| 73 | +#endif // endif |
---|
| 74 | + |
---|
| 75 | +#ifndef IW_AUTH_KEY_MGMT_WAPI_PSK |
---|
| 76 | +#define IW_AUTH_KEY_MGMT_WAPI_PSK 4 |
---|
| 77 | +#endif // endif |
---|
| 78 | + |
---|
| 79 | +#ifndef IW_AUTH_KEY_MGMT_WAPI_CERT |
---|
| 80 | +#define IW_AUTH_KEY_MGMT_WAPI_CERT 8 |
---|
| 81 | +#endif // endif |
---|
| 82 | +#endif /* BCMWAPI_WPI */ |
---|
57 | 83 | |
---|
58 | 84 | /* Broadcom extensions to WEXT, linux upstream has obsoleted WEXT */ |
---|
59 | 85 | #ifndef IW_AUTH_KEY_MGMT_FT_802_1X |
---|
60 | 86 | #define IW_AUTH_KEY_MGMT_FT_802_1X 0x04 |
---|
61 | | -#endif |
---|
| 87 | +#endif // endif |
---|
62 | 88 | |
---|
63 | 89 | #ifndef IW_AUTH_KEY_MGMT_FT_PSK |
---|
64 | 90 | #define IW_AUTH_KEY_MGMT_FT_PSK 0x08 |
---|
65 | | -#endif |
---|
| 91 | +#endif // endif |
---|
66 | 92 | |
---|
67 | 93 | #ifndef IW_ENC_CAPA_FW_ROAM_ENABLE |
---|
68 | 94 | #define IW_ENC_CAPA_FW_ROAM_ENABLE 0x00000020 |
---|
69 | | -#endif |
---|
70 | | - |
---|
| 95 | +#endif // endif |
---|
71 | 96 | |
---|
72 | 97 | /* FC9: wireless.h 2.6.25-14.fc9.i686 is missing these, even though WIRELESS_EXT is set to latest |
---|
73 | 98 | * version 22. |
---|
74 | 99 | */ |
---|
75 | 100 | #ifndef IW_ENCODE_ALG_PMK |
---|
76 | 101 | #define IW_ENCODE_ALG_PMK 4 |
---|
77 | | -#endif |
---|
| 102 | +#endif // endif |
---|
78 | 103 | #ifndef IW_ENC_CAPA_4WAY_HANDSHAKE |
---|
79 | 104 | #define IW_ENC_CAPA_4WAY_HANDSHAKE 0x00000010 |
---|
80 | | -#endif |
---|
| 105 | +#endif // endif |
---|
81 | 106 | /* End FC9. */ |
---|
82 | 107 | |
---|
83 | 108 | #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) |
---|
84 | 109 | #include <linux/rtnetlink.h> |
---|
85 | | -#endif |
---|
| 110 | +#endif // endif |
---|
86 | 111 | #if defined(SOFTAP) |
---|
87 | 112 | struct net_device *ap_net_dev = NULL; |
---|
88 | 113 | tsk_ctl_t ap_eth_ctl; /* apsta AP netdev waiter thread */ |
---|
.. | .. |
---|
93 | 118 | |
---|
94 | 119 | uint wl_msg_level = WL_ERROR_VAL; |
---|
95 | 120 | |
---|
96 | | -#define MAX_WLIW_IOCTL_LEN 1024 |
---|
| 121 | +#define MAX_WLIW_IOCTL_LEN WLC_IOCTL_MEDLEN |
---|
97 | 122 | |
---|
98 | 123 | /* IOCTL swapping mode for Big Endian host with Little Endian dongle. Default to off */ |
---|
99 | 124 | #define htod32(i) (i) |
---|
.. | .. |
---|
110 | 135 | #define IW_IOCTL_IDX(cmd) ((cmd) - SIOCIWFIRST) |
---|
111 | 136 | #define IW_EVENT_IDX(cmd) ((cmd) - IWEVFIRST) |
---|
112 | 137 | #endif /* WIRELESS_EXT < 19 */ |
---|
113 | | - |
---|
114 | 138 | |
---|
115 | 139 | #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 8, 0)) |
---|
116 | 140 | #define DAEMONIZE(a) do { \ |
---|
.. | .. |
---|
143 | 167 | |
---|
144 | 168 | typedef struct iscan_info { |
---|
145 | 169 | struct net_device *dev; |
---|
146 | | - struct timer_list timer; |
---|
| 170 | + timer_list_compat_t timer; |
---|
147 | 171 | uint32 timer_ms; |
---|
148 | 172 | uint32 timer_on; |
---|
149 | 173 | int iscan_state; |
---|
.. | .. |
---|
153 | 177 | /* Thread to work on iscan */ |
---|
154 | 178 | #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 7, 0)) |
---|
155 | 179 | struct task_struct *kthread; |
---|
156 | | -#endif |
---|
| 180 | +#endif // endif |
---|
157 | 181 | long sysioc_pid; |
---|
158 | 182 | struct semaphore sysioc_sem; |
---|
159 | 183 | struct completion sysioc_exited; |
---|
160 | | - |
---|
161 | 184 | |
---|
162 | 185 | char ioctlbuf[WLC_IOCTL_SMLEN]; |
---|
163 | 186 | } iscan_info_t; |
---|
.. | .. |
---|
176 | 199 | #define WL_DEV_LINK(dev) (priv_link_t*)(dev->priv) |
---|
177 | 200 | #else |
---|
178 | 201 | #define WL_DEV_LINK(dev) (priv_link_t*)netdev_priv(dev) |
---|
179 | | -#endif |
---|
| 202 | +#endif // endif |
---|
180 | 203 | |
---|
181 | 204 | /* dev to wl_iw_t */ |
---|
182 | 205 | #define IW_DEV_IF(dev) ((wl_iw_t*)(WL_DEV_LINK(dev))->wliw) |
---|
.. | .. |
---|
217 | 240 | { |
---|
218 | 241 | struct ifreq ifr; |
---|
219 | 242 | wl_ioctl_t ioc; |
---|
| 243 | +#if defined(KERNEL_DS) && defined(USER_DS) |
---|
220 | 244 | mm_segment_t fs; |
---|
| 245 | +#endif /* KERNEL_DS && USER_DS */ |
---|
221 | 246 | int ret; |
---|
222 | 247 | |
---|
223 | 248 | memset(&ioc, 0, sizeof(ioc)); |
---|
.. | .. |
---|
229 | 254 | ifr.ifr_name[sizeof(ifr.ifr_name) - 1] = '\0'; |
---|
230 | 255 | ifr.ifr_data = (caddr_t) &ioc; |
---|
231 | 256 | |
---|
| 257 | +#if defined(KERNEL_DS) && defined(USER_DS) |
---|
232 | 258 | fs = get_fs(); |
---|
233 | | - set_fs(KERNEL_DS); |
---|
| 259 | +#if LINUX_VERSION_CODE <= KERNEL_VERSION(5, 0, 21) |
---|
| 260 | + set_fs(get_ds()); |
---|
| 261 | +#endif // endif |
---|
| 262 | +#endif /* KERNEL_DS && USER_DS */ |
---|
234 | 263 | #if defined(WL_USE_NETDEV_OPS) |
---|
235 | 264 | ret = dev->netdev_ops->ndo_do_ioctl(dev, &ifr, SIOCDEVPRIVATE); |
---|
236 | 265 | #else |
---|
237 | 266 | ret = dev->do_ioctl(dev, &ifr, SIOCDEVPRIVATE); |
---|
238 | | -#endif |
---|
| 267 | +#endif // endif |
---|
| 268 | +#if defined(KERNEL_DS) && defined(USER_DS) |
---|
239 | 269 | set_fs(fs); |
---|
| 270 | +#endif /* KERNEL_DS && USER_DS */ |
---|
240 | 271 | |
---|
241 | 272 | return ret; |
---|
242 | 273 | } |
---|
.. | .. |
---|
576 | 607 | while (fwrq->e++ < 6) |
---|
577 | 608 | fwrq->m /= 10; |
---|
578 | 609 | } |
---|
579 | | - /* handle 4.9GHz frequencies as Japan 4 GHz based channelization */ |
---|
580 | | - if (fwrq->m > 4000 && fwrq->m < 5000) |
---|
581 | | - sf = WF_CHAN_FACTOR_4_G; /* start factor for 4 GHz */ |
---|
| 610 | + /* handle 4.9GHz frequencies as Japan 4 GHz based channelization */ |
---|
| 611 | + if (fwrq->m > 4000 && fwrq->m < 5000) { |
---|
| 612 | + sf = WF_CHAN_FACTOR_4_G; /* start factor for 4 GHz */ |
---|
| 613 | + } |
---|
582 | 614 | |
---|
583 | 615 | chan = wf_mhz2channel(fwrq->m, sf); |
---|
584 | 616 | } |
---|
.. | .. |
---|
683 | 715 | static int channels[MAXCHANNEL+1]; |
---|
684 | 716 | wl_uint32_list_t *list = (wl_uint32_list_t *) channels; |
---|
685 | 717 | wl_rateset_t rateset; |
---|
686 | | - int error, i, k; |
---|
| 718 | + int error, i; |
---|
687 | 719 | uint sf, ch; |
---|
688 | 720 | |
---|
689 | 721 | int phytype; |
---|
690 | | - int bw_cap = 0, sgi_tx = 0, nmode = 0; |
---|
691 | | - channel_info_t ci; |
---|
692 | | - uint8 nrate_list2copy = 0; |
---|
693 | | - uint16 nrate_list[4][8] = { {13, 26, 39, 52, 78, 104, 117, 130}, |
---|
694 | | - {14, 29, 43, 58, 87, 116, 130, 144}, |
---|
695 | | - {27, 54, 81, 108, 162, 216, 243, 270}, |
---|
696 | | - {30, 60, 90, 120, 180, 240, 270, 300}}; |
---|
697 | 722 | int fbt_cap = 0; |
---|
698 | 723 | |
---|
699 | 724 | WL_TRACE(("%s: SIOCGIWRANGE\n", dev->name)); |
---|
.. | .. |
---|
750 | 775 | range->num_bitrates = rateset.count; |
---|
751 | 776 | for (i = 0; i < rateset.count && i < IW_MAX_BITRATES; i++) |
---|
752 | 777 | range->bitrate[i] = (rateset.rates[i] & 0x7f) * 500000; /* convert to bps */ |
---|
753 | | - if ((error = dev_wlc_intvar_get(dev, "nmode", &nmode))) |
---|
754 | | - return error; |
---|
755 | 778 | if ((error = dev_wlc_ioctl(dev, WLC_GET_PHYTYPE, &phytype, sizeof(phytype)))) |
---|
756 | 779 | return error; |
---|
757 | | - if (nmode == 1 && (((phytype == WLC_PHY_TYPE_LCN) || |
---|
758 | | - (phytype == WLC_PHY_TYPE_LCN40)))) { |
---|
759 | | - if ((error = dev_wlc_intvar_get(dev, "mimo_bw_cap", &bw_cap))) |
---|
760 | | - return error; |
---|
761 | | - if ((error = dev_wlc_intvar_get(dev, "sgi_tx", &sgi_tx))) |
---|
762 | | - return error; |
---|
763 | | - if ((error = dev_wlc_ioctl(dev, WLC_GET_CHANNEL, &ci, sizeof(channel_info_t)))) |
---|
764 | | - return error; |
---|
765 | | - ci.hw_channel = dtoh32(ci.hw_channel); |
---|
766 | | - |
---|
767 | | - if (bw_cap == 0 || |
---|
768 | | - (bw_cap == 2 && ci.hw_channel <= 14)) { |
---|
769 | | - if (sgi_tx == 0) |
---|
770 | | - nrate_list2copy = 0; |
---|
771 | | - else |
---|
772 | | - nrate_list2copy = 1; |
---|
773 | | - } |
---|
774 | | - if (bw_cap == 1 || |
---|
775 | | - (bw_cap == 2 && ci.hw_channel >= 36)) { |
---|
776 | | - if (sgi_tx == 0) |
---|
777 | | - nrate_list2copy = 2; |
---|
778 | | - else |
---|
779 | | - nrate_list2copy = 3; |
---|
780 | | - } |
---|
781 | | - range->num_bitrates += 8; |
---|
782 | | - ASSERT(range->num_bitrates < IW_MAX_BITRATES); |
---|
783 | | - for (k = 0; i < range->num_bitrates; k++, i++) { |
---|
784 | | - /* convert to bps */ |
---|
785 | | - range->bitrate[i] = (nrate_list[nrate_list2copy][k]) * 500000; |
---|
786 | | - } |
---|
787 | | - } |
---|
788 | 780 | |
---|
789 | 781 | /* Set an indication of the max TCP throughput |
---|
790 | 782 | * in bit/s that we can expect using this interface. |
---|
.. | .. |
---|
812 | 804 | range->encoding_size[2] = TKIP_KEY_SIZE; |
---|
813 | 805 | #else |
---|
814 | 806 | range->encoding_size[2] = 0; |
---|
815 | | -#endif |
---|
| 807 | +#endif // endif |
---|
816 | 808 | range->encoding_size[3] = AES_KEY_SIZE; |
---|
817 | 809 | |
---|
818 | 810 | /* Do not support power micro-management */ |
---|
.. | .. |
---|
878 | 870 | #if WIRELESS_EXT >= 22 && defined(IW_SCAN_CAPA_ESSID) |
---|
879 | 871 | /* FC7 wireless.h defines EXT 22 but doesn't define scan_capa bits */ |
---|
880 | 872 | range->scan_capa = IW_SCAN_CAPA_ESSID; |
---|
881 | | -#endif |
---|
| 873 | +#endif // endif |
---|
882 | 874 | #endif /* WIRELESS_EXT > 17 */ |
---|
883 | 875 | |
---|
884 | 876 | return 0; |
---|
.. | .. |
---|
1091 | 1083 | ASSERT(list->version == WL_BSS_INFO_VERSION); |
---|
1092 | 1084 | |
---|
1093 | 1085 | for (i = 0, dwrq->length = 0; i < list->count && dwrq->length < IW_MAX_AP; i++) { |
---|
1094 | | - bi = bi ? (wl_bss_info_t *)((uintptr)bi + dtoh32(bi->length)) : list->bss_info; |
---|
| 1086 | + bi = (bi ? (wl_bss_info_t *)((uintptr)bi + dtoh32(bi->length)) : |
---|
| 1087 | + (wl_bss_info_t*)list->bss_info); |
---|
1095 | 1088 | ASSERT(((uintptr)bi + dtoh32(bi->length)) <= ((uintptr)list + |
---|
1096 | 1089 | buflen)); |
---|
1097 | 1090 | |
---|
.. | .. |
---|
1222 | 1215 | ssid.SSID_len = htod32(ssid.SSID_len); |
---|
1223 | 1216 | } |
---|
1224 | 1217 | } |
---|
1225 | | -#endif |
---|
| 1218 | +#endif // endif |
---|
1226 | 1219 | /* Ignore error (most likely scan in progress) */ |
---|
1227 | 1220 | (void) dev_wlc_ioctl(dev, WLC_SCAN, &ssid, sizeof(ssid)); |
---|
1228 | 1221 | |
---|
.. | .. |
---|
1263 | 1256 | ssid.SSID_len = htod32(ssid.SSID_len); |
---|
1264 | 1257 | } |
---|
1265 | 1258 | } |
---|
1266 | | -#endif |
---|
| 1259 | +#endif // endif |
---|
1267 | 1260 | |
---|
1268 | 1261 | iscan->list_cur = iscan->list_hdr; |
---|
1269 | 1262 | iscan->iscan_state = ISCAN_STATE_SCANING; |
---|
1270 | 1263 | |
---|
1271 | | - |
---|
1272 | 1264 | wl_iw_set_event_mask(dev); |
---|
1273 | 1265 | wl_iw_iscan(iscan, &ssid, WL_SCAN_ACTION_START); |
---|
1274 | | - |
---|
| 1266 | +#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 15, 0) |
---|
1275 | 1267 | iscan->timer.expires = jiffies + msecs_to_jiffies(iscan->timer_ms); |
---|
| 1268 | +#else |
---|
| 1269 | + iscan->timer.timer.expires = jiffies + msecs_to_jiffies(iscan->timer_ms); |
---|
| 1270 | +#endif // endif |
---|
1276 | 1271 | add_timer(&iscan->timer); |
---|
1277 | 1272 | iscan->timer_on = 1; |
---|
1278 | 1273 | |
---|
.. | .. |
---|
1325 | 1320 | } |
---|
1326 | 1321 | #endif /* WIRELESS_EXT > 17 */ |
---|
1327 | 1322 | |
---|
| 1323 | +#ifdef BCMWAPI_WPI |
---|
| 1324 | +static inline int _wpa_snprintf_hex(char *buf, size_t buf_size, const u8 *data, |
---|
| 1325 | + size_t len, int uppercase) |
---|
| 1326 | +{ |
---|
| 1327 | + size_t i; |
---|
| 1328 | + char *pos = buf, *end = buf + buf_size; |
---|
| 1329 | + int ret; |
---|
| 1330 | + if (buf_size == 0) |
---|
| 1331 | + return 0; |
---|
| 1332 | + for (i = 0; i < len; i++) { |
---|
| 1333 | + ret = snprintf(pos, end - pos, uppercase ? "%02X" : "%02x", |
---|
| 1334 | + data[i]); |
---|
| 1335 | + if (ret < 0 || ret >= end - pos) { |
---|
| 1336 | + end[-1] = '\0'; |
---|
| 1337 | + return pos - buf; |
---|
| 1338 | + } |
---|
| 1339 | + pos += ret; |
---|
| 1340 | + } |
---|
| 1341 | + end[-1] = '\0'; |
---|
| 1342 | + return pos - buf; |
---|
| 1343 | +} |
---|
| 1344 | + |
---|
| 1345 | +/** |
---|
| 1346 | + * wpa_snprintf_hex - Print data as a hex string into a buffer |
---|
| 1347 | + * @buf: Memory area to use as the output buffer |
---|
| 1348 | + * @buf_size: Maximum buffer size in bytes (should be at least 2 * len + 1) |
---|
| 1349 | + * @data: Data to be printed |
---|
| 1350 | + * @len: Length of data in bytes |
---|
| 1351 | + * Returns: Number of bytes written |
---|
| 1352 | + */ |
---|
| 1353 | +static int |
---|
| 1354 | +wpa_snprintf_hex(char *buf, size_t buf_size, const u8 *data, size_t len) |
---|
| 1355 | +{ |
---|
| 1356 | + return _wpa_snprintf_hex(buf, buf_size, data, len, 0); |
---|
| 1357 | +} |
---|
| 1358 | +#endif /* BCMWAPI_WPI */ |
---|
1328 | 1359 | |
---|
1329 | 1360 | static int |
---|
1330 | 1361 | wl_iw_handle_scanresults_ies(char **event_p, char *end, |
---|
.. | .. |
---|
1333 | 1364 | #if WIRELESS_EXT > 17 |
---|
1334 | 1365 | struct iw_event iwe; |
---|
1335 | 1366 | char *event; |
---|
| 1367 | +#ifdef BCMWAPI_WPI |
---|
| 1368 | + char *buf; |
---|
| 1369 | + int custom_event_len; |
---|
| 1370 | +#endif // endif |
---|
1336 | 1371 | |
---|
1337 | 1372 | event = *event_p; |
---|
1338 | 1373 | if (bi->ie_length) { |
---|
1339 | 1374 | /* look for wpa/rsn ies in the ie list... */ |
---|
1340 | 1375 | bcm_tlv_t *ie; |
---|
1341 | 1376 | uint8 *ptr = ((uint8 *)bi) + bi->ie_offset; |
---|
1342 | | - int ptr_len = bi->ie_length; |
---|
| 1377 | + uint ptr_len = bi->ie_length; |
---|
1343 | 1378 | |
---|
1344 | 1379 | /* OSEN IE */ |
---|
1345 | 1380 | if ((ie = bcm_parse_tlvs(ptr, ptr_len, DOT11_MNG_VS_ID)) && |
---|
.. | .. |
---|
1387 | 1422 | } |
---|
1388 | 1423 | } |
---|
1389 | 1424 | |
---|
| 1425 | +#ifdef BCMWAPI_WPI |
---|
| 1426 | + ptr = ((uint8 *)bi) + sizeof(wl_bss_info_t); |
---|
| 1427 | + ptr_len = bi->ie_length; |
---|
| 1428 | + |
---|
| 1429 | + while ((ie = bcm_parse_tlvs(ptr, ptr_len, DOT11_MNG_WAPI_ID))) { |
---|
| 1430 | + WL_TRACE(("%s: found a WAPI IE...\n", __FUNCTION__)); |
---|
| 1431 | +#ifdef WAPI_IE_USE_GENIE |
---|
| 1432 | + iwe.cmd = IWEVGENIE; |
---|
| 1433 | + iwe.u.data.length = ie->len + 2; |
---|
| 1434 | + event = IWE_STREAM_ADD_POINT(info, event, end, &iwe, (char *)ie); |
---|
| 1435 | +#else /* using CUSTOM event */ |
---|
| 1436 | + iwe.cmd = IWEVCUSTOM; |
---|
| 1437 | + custom_event_len = strlen("wapi_ie=") + 2*(ie->len + 2); |
---|
| 1438 | + iwe.u.data.length = custom_event_len; |
---|
| 1439 | + |
---|
| 1440 | + buf = kmalloc(custom_event_len+1, GFP_KERNEL); |
---|
| 1441 | + if (buf == NULL) |
---|
| 1442 | + { |
---|
| 1443 | + WL_ERROR(("malloc(%d) returned NULL...\n", custom_event_len)); |
---|
| 1444 | + break; |
---|
| 1445 | + } |
---|
| 1446 | + |
---|
| 1447 | + memcpy(buf, "wapi_ie=", 8); |
---|
| 1448 | + wpa_snprintf_hex(buf + 8, 2+1, &(ie->id), 1); |
---|
| 1449 | + wpa_snprintf_hex(buf + 10, 2+1, &(ie->len), 1); |
---|
| 1450 | + wpa_snprintf_hex(buf + 12, 2*ie->len+1, ie->data, ie->len); |
---|
| 1451 | + event = IWE_STREAM_ADD_POINT(info, event, end, &iwe, buf); |
---|
| 1452 | + kfree(buf); |
---|
| 1453 | +#endif /* WAPI_IE_USE_GENIE */ |
---|
| 1454 | + break; |
---|
| 1455 | + } |
---|
| 1456 | +#endif /* BCMWAPI_WPI */ |
---|
1390 | 1457 | *event_p = event; |
---|
1391 | 1458 | } |
---|
1392 | 1459 | |
---|
.. | .. |
---|
1438 | 1505 | ASSERT(list->version == WL_BSS_INFO_VERSION); |
---|
1439 | 1506 | |
---|
1440 | 1507 | for (i = 0; i < list->count && i < IW_MAX_AP; i++) { |
---|
1441 | | - bi = bi ? (wl_bss_info_t *)((uintptr)bi + dtoh32(bi->length)) : list->bss_info; |
---|
| 1508 | + bi = (bi ? (wl_bss_info_t *)((uintptr)bi + dtoh32(bi->length)) : |
---|
| 1509 | + (wl_bss_info_t *)list->bss_info); |
---|
1442 | 1510 | ASSERT(((uintptr)bi + dtoh32(bi->length)) <= ((uintptr)list + |
---|
1443 | 1511 | buflen)); |
---|
1444 | 1512 | |
---|
.. | .. |
---|
1480 | 1548 | iwe.u.qual.noise = 0x100 + bi->phy_noise; |
---|
1481 | 1549 | event = IWE_STREAM_ADD_EVENT(info, event, end, &iwe, IW_EV_QUAL_LEN); |
---|
1482 | 1550 | |
---|
1483 | | - /* WPA, WPA2, WPS, WAPI IEs */ |
---|
1484 | 1551 | wl_iw_handle_scanresults_ies(&event, end, info, bi); |
---|
1485 | 1552 | |
---|
1486 | 1553 | /* Encryption */ |
---|
.. | .. |
---|
1604 | 1671 | iwe.u.qual.noise = 0x100 + bi->phy_noise; |
---|
1605 | 1672 | event = IWE_STREAM_ADD_EVENT(info, event, end, &iwe, IW_EV_QUAL_LEN); |
---|
1606 | 1673 | |
---|
1607 | | - /* WPA, WPA2, WPS, WAPI IEs */ |
---|
1608 | 1674 | wl_iw_handle_scanresults_ies(&event, end, info, bi); |
---|
1609 | 1675 | |
---|
1610 | 1676 | /* Encryption */ |
---|
.. | .. |
---|
1644 | 1710 | |
---|
1645 | 1711 | #endif /* WIRELESS_EXT > 13 */ |
---|
1646 | 1712 | |
---|
1647 | | - |
---|
1648 | 1713 | static int |
---|
1649 | 1714 | wl_iw_set_essid( |
---|
1650 | 1715 | struct net_device *dev, |
---|
.. | .. |
---|
1665 | 1730 | ssid.SSID_len = MIN(sizeof(ssid.SSID), dwrq->length); |
---|
1666 | 1731 | #else |
---|
1667 | 1732 | ssid.SSID_len = MIN(sizeof(ssid.SSID), dwrq->length-1); |
---|
1668 | | -#endif |
---|
| 1733 | +#endif // endif |
---|
1669 | 1734 | memcpy(ssid.SSID, extra, ssid.SSID_len); |
---|
1670 | 1735 | ssid.SSID_len = htod32(ssid.SSID_len); |
---|
1671 | 1736 | |
---|
.. | .. |
---|
1705 | 1770 | |
---|
1706 | 1771 | ssid.SSID_len = dtoh32(ssid.SSID_len); |
---|
1707 | 1772 | |
---|
| 1773 | + /* Max SSID length check */ |
---|
| 1774 | + if (ssid.SSID_len > IW_ESSID_MAX_SIZE) { |
---|
| 1775 | + ssid.SSID_len = IW_ESSID_MAX_SIZE; |
---|
| 1776 | + } |
---|
| 1777 | + |
---|
1708 | 1778 | /* Get the current SSID */ |
---|
1709 | 1779 | memcpy(extra, ssid.SSID, ssid.SSID_len); |
---|
| 1780 | + |
---|
| 1781 | + /* NULL terminating as length of extra buffer is IW_ESSID_MAX_SIZE ie 32 */ |
---|
| 1782 | + extra[IW_ESSID_MAX_SIZE] = '\0'; |
---|
1710 | 1783 | |
---|
1711 | 1784 | dwrq->length = ssid.SSID_len; |
---|
1712 | 1785 | |
---|
.. | .. |
---|
1974 | 2047 | if (vwrq->value > 0xffff) txpwrmw = 0xffff; |
---|
1975 | 2048 | else txpwrmw = (uint16)vwrq->value; |
---|
1976 | 2049 | |
---|
1977 | | - |
---|
1978 | 2050 | error = dev_wlc_intvar_set(dev, "qtxpower", (int)(bcm_mw_to_qdbm(txpwrmw))); |
---|
1979 | 2051 | return error; |
---|
1980 | 2052 | } |
---|
.. | .. |
---|
2161 | 2233 | case TKIP_KEY_SIZE: |
---|
2162 | 2234 | key.algo = CRYPTO_ALGO_TKIP; |
---|
2163 | 2235 | break; |
---|
2164 | | -#endif |
---|
| 2236 | +#endif // endif |
---|
2165 | 2237 | case AES_KEY_SIZE: |
---|
2166 | 2238 | key.algo = CRYPTO_ALGO_AES_CCM; |
---|
2167 | 2239 | break; |
---|
.. | .. |
---|
2299 | 2371 | char *extra |
---|
2300 | 2372 | ) |
---|
2301 | 2373 | { |
---|
| 2374 | +#if defined(BCMWAPI_WPI) |
---|
| 2375 | + uchar buf[WLC_IOCTL_SMLEN] = {0}; |
---|
| 2376 | + uchar *p = buf; |
---|
| 2377 | + int wapi_ie_size; |
---|
| 2378 | + |
---|
| 2379 | + WL_TRACE(("%s: SIOCSIWGENIE\n", dev->name)); |
---|
| 2380 | + |
---|
| 2381 | + if (extra[0] == DOT11_MNG_WAPI_ID) |
---|
| 2382 | + { |
---|
| 2383 | + wapi_ie_size = iwp->length; |
---|
| 2384 | + memcpy(p, extra, iwp->length); |
---|
| 2385 | + dev_wlc_bufvar_set(dev, "wapiie", buf, wapi_ie_size); |
---|
| 2386 | + } |
---|
| 2387 | + else |
---|
| 2388 | +#endif // endif |
---|
2302 | 2389 | dev_wlc_bufvar_set(dev, "wpaie", extra, iwp->length); |
---|
2303 | 2390 | |
---|
2304 | 2391 | return 0; |
---|
.. | .. |
---|
2441 | 2528 | case IW_ENCODE_ALG_CCMP: |
---|
2442 | 2529 | key.algo = CRYPTO_ALGO_AES_CCM; |
---|
2443 | 2530 | break; |
---|
| 2531 | +#ifdef BCMWAPI_WPI |
---|
| 2532 | + case IW_ENCODE_ALG_SM4: |
---|
| 2533 | + key.algo = CRYPTO_ALGO_SMS4; |
---|
| 2534 | + if (iwe->ext_flags & IW_ENCODE_EXT_GROUP_KEY) { |
---|
| 2535 | + key.flags &= ~WL_PRIMARY_KEY; |
---|
| 2536 | + } |
---|
| 2537 | + break; |
---|
| 2538 | +#endif // endif |
---|
2444 | 2539 | default: |
---|
2445 | 2540 | break; |
---|
2446 | 2541 | } |
---|
.. | .. |
---|
2454 | 2549 | } |
---|
2455 | 2550 | return 0; |
---|
2456 | 2551 | } |
---|
2457 | | - |
---|
2458 | 2552 | |
---|
2459 | 2553 | #if WIRELESS_EXT > 17 |
---|
2460 | 2554 | struct { |
---|
.. | .. |
---|
2590 | 2684 | val = WPA_AUTH_PSK | WPA_AUTH_UNSPECIFIED; |
---|
2591 | 2685 | else if (paramval & IW_AUTH_WPA_VERSION_WPA2) |
---|
2592 | 2686 | val = WPA2_AUTH_PSK | WPA2_AUTH_UNSPECIFIED; |
---|
| 2687 | +#ifdef BCMWAPI_WPI |
---|
| 2688 | + else if (paramval & IW_AUTH_WAPI_VERSION_1) |
---|
| 2689 | + val = WAPI_AUTH_UNSPECIFIED; |
---|
| 2690 | +#endif // endif |
---|
2593 | 2691 | WL_TRACE(("%s: %d: setting wpa_auth to 0x%0x\n", __FUNCTION__, __LINE__, val)); |
---|
2594 | 2692 | if ((error = dev_wlc_intvar_set(dev, "wpa_auth", val))) |
---|
2595 | 2693 | return error; |
---|
.. | .. |
---|
2617 | 2715 | val |= TKIP_ENABLED; |
---|
2618 | 2716 | if (cipher_combined & IW_AUTH_CIPHER_CCMP) |
---|
2619 | 2717 | val |= AES_ENABLED; |
---|
| 2718 | +#ifdef BCMWAPI_WPI |
---|
| 2719 | + val &= ~SMS4_ENABLED; |
---|
| 2720 | + if (cipher_combined & IW_AUTH_CIPHER_SMS4) |
---|
| 2721 | + val |= SMS4_ENABLED; |
---|
| 2722 | +#endif // endif |
---|
2620 | 2723 | |
---|
2621 | 2724 | if (iw->privacy_invoked && !val) { |
---|
2622 | 2725 | WL_WSEC(("%s: %s: 'Privacy invoked' TRUE but clearing wsec, assuming " |
---|
.. | .. |
---|
2673 | 2776 | if (paramval & (IW_AUTH_KEY_MGMT_FT_802_1X | IW_AUTH_KEY_MGMT_FT_PSK)) |
---|
2674 | 2777 | val |= WPA2_AUTH_FT; |
---|
2675 | 2778 | } |
---|
| 2779 | +#ifdef BCMWAPI_WPI |
---|
| 2780 | + if (paramval & (IW_AUTH_KEY_MGMT_WAPI_PSK | IW_AUTH_KEY_MGMT_WAPI_CERT)) |
---|
| 2781 | + val = WAPI_AUTH_UNSPECIFIED; |
---|
| 2782 | +#endif // endif |
---|
2676 | 2783 | WL_TRACE(("%s: %d: setting wpa_auth to %d\n", __FUNCTION__, __LINE__, val)); |
---|
2677 | 2784 | if ((error = dev_wlc_intvar_set(dev, "wpa_auth", val))) |
---|
2678 | 2785 | return error; |
---|
.. | .. |
---|
2752 | 2859 | break; |
---|
2753 | 2860 | } |
---|
2754 | 2861 | |
---|
2755 | | - |
---|
2756 | 2862 | #endif /* WIRELESS_EXT > 17 */ |
---|
2757 | 2863 | |
---|
| 2864 | +#ifdef BCMWAPI_WPI |
---|
| 2865 | + |
---|
| 2866 | + case IW_AUTH_WAPI_ENABLED: |
---|
| 2867 | + if ((error = dev_wlc_intvar_get(dev, "wsec", &val))) |
---|
| 2868 | + return error; |
---|
| 2869 | + if (paramval) { |
---|
| 2870 | + val |= SMS4_ENABLED; |
---|
| 2871 | + if ((error = dev_wlc_intvar_set(dev, "wsec", val))) { |
---|
| 2872 | + WL_ERROR(("%s: setting wsec to 0x%0x returned error %d\n", |
---|
| 2873 | + __FUNCTION__, val, error)); |
---|
| 2874 | + return error; |
---|
| 2875 | + } |
---|
| 2876 | + if ((error = dev_wlc_intvar_set(dev, "wpa_auth", WAPI_AUTH_UNSPECIFIED))) { |
---|
| 2877 | + WL_ERROR(("%s: setting wpa_auth(%d) returned %d\n", |
---|
| 2878 | + __FUNCTION__, WAPI_AUTH_UNSPECIFIED, |
---|
| 2879 | + error)); |
---|
| 2880 | + return error; |
---|
| 2881 | + } |
---|
| 2882 | + } |
---|
| 2883 | + |
---|
| 2884 | + break; |
---|
| 2885 | + |
---|
| 2886 | +#endif /* BCMWAPI_WPI */ |
---|
2758 | 2887 | |
---|
2759 | 2888 | default: |
---|
2760 | 2889 | break; |
---|
.. | .. |
---|
2888 | 3017 | (iw_handler) wl_iw_mlme, /* SIOCSIWMLME */ |
---|
2889 | 3018 | #else |
---|
2890 | 3019 | (iw_handler) NULL, /* -- hole -- */ |
---|
2891 | | -#endif |
---|
| 3020 | +#endif // endif |
---|
2892 | 3021 | (iw_handler) wl_iw_iscan_get_aplist, /* SIOCGIWAPLIST */ |
---|
2893 | 3022 | #if WIRELESS_EXT > 13 |
---|
2894 | 3023 | (iw_handler) wl_iw_iscan_set_scan, /* SIOCSIWSCAN */ |
---|
.. | .. |
---|
3022 | 3151 | #if WIRELESS_EXT > 17 |
---|
3023 | 3152 | case SIOCSIWENCODEEXT: |
---|
3024 | 3153 | case SIOCGIWENCODEEXT: |
---|
3025 | | -#endif |
---|
| 3154 | +#endif // endif |
---|
3026 | 3155 | max_tokens = IW_ENCODING_TOKEN_MAX; |
---|
3027 | 3156 | break; |
---|
3028 | 3157 | |
---|
.. | .. |
---|
3037 | 3166 | |
---|
3038 | 3167 | #if WIRELESS_EXT > 13 |
---|
3039 | 3168 | case SIOCGIWSCAN: |
---|
3040 | | - if (g_iscan) |
---|
| 3169 | + if (g_iscan) { |
---|
3041 | 3170 | max_tokens = wrq->u.data.length; |
---|
| 3171 | + } |
---|
3042 | 3172 | else |
---|
3043 | | - max_tokens = IW_SCAN_MAX_DATA; |
---|
| 3173 | + { |
---|
| 3174 | + max_tokens = IW_SCAN_MAX_DATA; |
---|
| 3175 | + } |
---|
3044 | 3176 | break; |
---|
3045 | 3177 | #endif /* WIRELESS_EXT > 13 */ |
---|
3046 | 3178 | |
---|
.. | .. |
---|
3317 | 3449 | case WLC_E_SCAN_COMPLETE: |
---|
3318 | 3450 | #if WIRELESS_EXT > 14 |
---|
3319 | 3451 | cmd = SIOCGIWSCAN; |
---|
3320 | | -#endif |
---|
| 3452 | +#endif // endif |
---|
3321 | 3453 | WL_TRACE(("event WLC_E_SCAN_COMPLETE\n")); |
---|
3322 | 3454 | if ((g_iscan) && (g_iscan->sysioc_pid >= 0) && |
---|
3323 | 3455 | (g_iscan->iscan_state != ISCAN_STATE_IDLE)) |
---|
.. | .. |
---|
3351 | 3483 | #endif /* WIRELESS_EXT > 13 */ |
---|
3352 | 3484 | } |
---|
3353 | 3485 | |
---|
3354 | | -static int wl_iw_get_wireless_stats_cbfn(void *ctx, uint8 *data, uint16 type, uint16 len) |
---|
| 3486 | +static int wl_iw_get_wireless_stats_cbfn(void *ctx, const uint8 *data, |
---|
| 3487 | + uint16 type, uint16 len) |
---|
3355 | 3488 | { |
---|
3356 | 3489 | struct iw_statistics *wstats = ctx; |
---|
3357 | 3490 | int res = BCME_OK; |
---|
3358 | 3491 | |
---|
3359 | 3492 | switch (type) { |
---|
3360 | 3493 | case WL_CNT_XTLV_WLC: { |
---|
3361 | | - wl_cnt_wlc_t *cnt = (wl_cnt_wlc_t *)data; |
---|
| 3494 | + const wl_cnt_wlc_t *cnt = (const wl_cnt_wlc_t *)data; |
---|
3362 | 3495 | if (len > sizeof(wl_cnt_wlc_t)) { |
---|
3363 | 3496 | printf("counter structure length invalid! %d > %d\n", |
---|
3364 | 3497 | len, (int)sizeof(wl_cnt_wlc_t)); |
---|
.. | .. |
---|
3391 | 3524 | * wl_cnt_v_le10_mcst_t, wl_cnt_lt40mcst_v1_t, and wl_cnt_ge40mcst_v1_t. |
---|
3392 | 3525 | * So we can just cast to wl_cnt_v_le10_mcst_t here. |
---|
3393 | 3526 | */ |
---|
3394 | | - wl_cnt_v_le10_mcst_t *cnt = (wl_cnt_v_le10_mcst_t *)data; |
---|
| 3527 | + const wl_cnt_v_le10_mcst_t *cnt = (const wl_cnt_v_le10_mcst_t *)data; |
---|
3395 | 3528 | if (len != WL_CNT_MCST_STRUCT_SZ) { |
---|
3396 | 3529 | printf("counter structure length mismatch! %d != %d\n", |
---|
3397 | 3530 | len, WL_CNT_MCST_STRUCT_SZ); |
---|
.. | .. |
---|
3459 | 3592 | #endif /* WIRELESS_EXT > 18 */ |
---|
3460 | 3593 | |
---|
3461 | 3594 | #if WIRELESS_EXT > 11 |
---|
3462 | | - WL_TRACE(("wl_iw_get_wireless_stats counters=%d\n *****", WL_CNTBUF_MAX_SIZE)); |
---|
| 3595 | + WL_TRACE(("wl_iw_get_wireless_stats counters\n *****")); |
---|
3463 | 3596 | |
---|
3464 | | - if (WL_CNTBUF_MAX_SIZE > MAX_WLIW_IOCTL_LEN) |
---|
3465 | | - { |
---|
3466 | | - WL_ERROR(("wl_iw_get_wireless_stats buffer too short %d < %d\n", |
---|
3467 | | - WL_CNTBUF_MAX_SIZE, MAX_WLIW_IOCTL_LEN)); |
---|
3468 | | - res = BCME_BUFTOOSHORT; |
---|
3469 | | - goto done; |
---|
3470 | | - } |
---|
3471 | | - |
---|
3472 | | - cntbuf = kmalloc(WL_CNTBUF_MAX_SIZE, GFP_KERNEL); |
---|
| 3597 | + cntbuf = kmalloc(MAX_WLIW_IOCTL_LEN, GFP_KERNEL); |
---|
3473 | 3598 | if (!cntbuf) { |
---|
3474 | 3599 | res = BCME_NOMEM; |
---|
3475 | 3600 | goto done; |
---|
3476 | 3601 | } |
---|
3477 | 3602 | |
---|
3478 | | - memset(cntbuf, 0, WL_CNTBUF_MAX_SIZE); |
---|
3479 | | - res = dev_wlc_bufvar_get(dev, "counters", cntbuf, WL_CNTBUF_MAX_SIZE); |
---|
| 3603 | + memset(cntbuf, 0, MAX_WLIW_IOCTL_LEN); |
---|
| 3604 | + res = dev_wlc_bufvar_get(dev, "counters", cntbuf, MAX_WLIW_IOCTL_LEN); |
---|
3480 | 3605 | if (res) |
---|
3481 | 3606 | { |
---|
3482 | 3607 | WL_ERROR(("wl_iw_get_wireless_stats counters failed error=%d ****** \n", res)); |
---|
.. | .. |
---|
3487 | 3612 | cntinfo->version = dtoh16(cntinfo->version); |
---|
3488 | 3613 | cntinfo->datalen = dtoh16(cntinfo->datalen); |
---|
3489 | 3614 | ver = cntinfo->version; |
---|
| 3615 | + CHK_CNTBUF_DATALEN(cntbuf, MAX_WLIW_IOCTL_LEN); |
---|
3490 | 3616 | if (ver > WL_CNT_T_VERSION) { |
---|
3491 | 3617 | WL_TRACE(("\tIncorrect version of counters struct: expected %d; got %d\n", |
---|
3492 | 3618 | WL_CNT_T_VERSION, ver)); |
---|
.. | .. |
---|
3505 | 3631 | corerev = dtoh32(revinfo.corerev); |
---|
3506 | 3632 | } |
---|
3507 | 3633 | |
---|
3508 | | - res = wl_cntbuf_to_xtlv_format(NULL, cntinfo, WL_CNTBUF_MAX_SIZE, corerev); |
---|
| 3634 | + res = wl_cntbuf_to_xtlv_format(NULL, cntinfo, MAX_WLIW_IOCTL_LEN, corerev); |
---|
3509 | 3635 | if (res) { |
---|
3510 | 3636 | WL_ERROR(("%s: wl_cntbuf_to_xtlv_format failed %d\n", __FUNCTION__, res)); |
---|
3511 | 3637 | goto done; |
---|
.. | .. |
---|
3691 | 3817 | |
---|
3692 | 3818 | #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) |
---|
3693 | 3819 | rtnl_lock(); |
---|
3694 | | -#endif |
---|
| 3820 | +#endif // endif |
---|
3695 | 3821 | status = wl_iw_iscan_get(iscan); |
---|
3696 | 3822 | #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) |
---|
3697 | 3823 | rtnl_unlock(); |
---|
3698 | | -#endif |
---|
| 3824 | +#endif // endif |
---|
3699 | 3825 | |
---|
3700 | 3826 | switch (status) { |
---|
3701 | 3827 | case WL_SCAN_RESULTS_PARTIAL: |
---|
3702 | 3828 | WL_TRACE(("iscanresults incomplete\n")); |
---|
3703 | 3829 | #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) |
---|
3704 | 3830 | rtnl_lock(); |
---|
3705 | | -#endif |
---|
| 3831 | +#endif // endif |
---|
3706 | 3832 | /* make sure our buffer size is enough before going next round */ |
---|
3707 | 3833 | wl_iw_iscan(iscan, NULL, WL_SCAN_ACTION_CONTINUE); |
---|
3708 | 3834 | #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) |
---|
3709 | 3835 | rtnl_unlock(); |
---|
3710 | | -#endif |
---|
| 3836 | +#endif // endif |
---|
3711 | 3837 | /* Reschedule the timer */ |
---|
| 3838 | +#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 15, 0) |
---|
3712 | 3839 | iscan->timer.expires = jiffies + msecs_to_jiffies(iscan->timer_ms); |
---|
| 3840 | +#else |
---|
| 3841 | + iscan->timer.timer.expires = jiffies + |
---|
| 3842 | + msecs_to_jiffies(iscan->timer_ms); |
---|
| 3843 | +#endif // endif |
---|
3713 | 3844 | add_timer(&iscan->timer); |
---|
3714 | 3845 | iscan->timer_on = 1; |
---|
3715 | 3846 | break; |
---|
.. | .. |
---|
3721 | 3852 | case WL_SCAN_RESULTS_PENDING: |
---|
3722 | 3853 | WL_TRACE(("iscanresults pending\n")); |
---|
3723 | 3854 | /* Reschedule the timer */ |
---|
| 3855 | +#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 15, 0) |
---|
3724 | 3856 | iscan->timer.expires = jiffies + msecs_to_jiffies(iscan->timer_ms); |
---|
| 3857 | +#else |
---|
| 3858 | + iscan->timer.timer.expires = jiffies + |
---|
| 3859 | + msecs_to_jiffies(iscan->timer_ms); |
---|
| 3860 | +#endif // endif |
---|
3725 | 3861 | add_timer(&iscan->timer); |
---|
3726 | 3862 | iscan->timer_on = 1; |
---|
3727 | 3863 | break; |
---|
.. | .. |
---|
3752 | 3888 | memset(iscan, 0, sizeof(iscan_info_t)); |
---|
3753 | 3889 | #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 7, 0)) |
---|
3754 | 3890 | iscan->kthread = NULL; |
---|
3755 | | -#endif |
---|
| 3891 | +#endif // endif |
---|
3756 | 3892 | iscan->sysioc_pid = -1; |
---|
3757 | 3893 | /* we only care about main interface so save a global here */ |
---|
3758 | 3894 | g_iscan = iscan; |
---|
3759 | 3895 | iscan->dev = dev; |
---|
3760 | 3896 | iscan->iscan_state = ISCAN_STATE_IDLE; |
---|
3761 | 3897 | |
---|
3762 | | - |
---|
3763 | 3898 | /* Set up the timer */ |
---|
3764 | 3899 | iscan->timer_ms = 2000; |
---|
| 3900 | +#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 15, 0)) |
---|
3765 | 3901 | init_timer(&iscan->timer); |
---|
3766 | 3902 | iscan->timer.data = (ulong)iscan; |
---|
3767 | 3903 | iscan->timer.function = wl_iw_timerfunc; |
---|
3768 | | - |
---|
| 3904 | +#else |
---|
| 3905 | + init_timer_compat(&iscan->timer, wl_iw_timerfunc, iscan); |
---|
| 3906 | +#endif // endif |
---|
3769 | 3907 | sema_init(&iscan->sysioc_sem, 0); |
---|
3770 | 3908 | init_completion(&iscan->sysioc_exited); |
---|
3771 | 3909 | #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 7, 0)) |
---|
.. | .. |
---|
3773 | 3911 | iscan->sysioc_pid = iscan->kthread->pid; |
---|
3774 | 3912 | #else |
---|
3775 | 3913 | iscan->sysioc_pid = kernel_thread(_iscan_sysioc_thread, iscan, 0); |
---|
3776 | | -#endif |
---|
| 3914 | +#endif // endif |
---|
3777 | 3915 | if (iscan->sysioc_pid < 0) |
---|
3778 | 3916 | return -ENOMEM; |
---|
3779 | 3917 | return 0; |
---|
.. | .. |
---|
3785 | 3923 | iscan_info_t *iscan = g_iscan; |
---|
3786 | 3924 | if (!iscan) |
---|
3787 | 3925 | return; |
---|
| 3926 | + /* Delete iscan timer */ |
---|
| 3927 | + if (iscan->timer_on) { |
---|
| 3928 | + del_timer_sync(&iscan->timer); |
---|
| 3929 | + iscan->timer_on = 0; |
---|
| 3930 | + } |
---|
3788 | 3931 | if (iscan->sysioc_pid >= 0) { |
---|
3789 | 3932 | KILL_PROC(iscan->sysioc_pid, SIGTERM); |
---|
3790 | 3933 | wait_for_completion(&iscan->sysioc_exited); |
---|