| .. | .. |
|---|
| 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); |
|---|