^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * cfg80211 - wext compat code
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * This is temporary code until all wireless functionality is migrated
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * into cfg80211, when that happens all the exports here go away and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * we directly assign the wireless handlers of wireless interfaces.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) * Copyright 2008-2009 Johannes Berg <johannes@sipsolutions.net>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) * Copyright (C) 2019 Intel Corporation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/export.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/wireless.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/nl80211.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/if_arp.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/etherdevice.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <net/iw_handler.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include <net/cfg80211.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include <net/cfg80211-wext.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include "wext-compat.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #include "core.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #include "rdev-ops.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) int cfg80211_wext_giwname(struct net_device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) struct iw_request_info *info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) char *name, char *extra)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) strcpy(name, "IEEE 802.11");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) EXPORT_WEXT_HANDLER(cfg80211_wext_giwname);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) int cfg80211_wext_siwmode(struct net_device *dev, struct iw_request_info *info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) u32 *mode, char *extra)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) struct wireless_dev *wdev = dev->ieee80211_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) struct cfg80211_registered_device *rdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) struct vif_params vifparams;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) enum nl80211_iftype type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) rdev = wiphy_to_rdev(wdev->wiphy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) switch (*mode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) case IW_MODE_INFRA:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) type = NL80211_IFTYPE_STATION;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) case IW_MODE_ADHOC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) type = NL80211_IFTYPE_ADHOC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) case IW_MODE_REPEAT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) type = NL80211_IFTYPE_WDS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) case IW_MODE_MONITOR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) type = NL80211_IFTYPE_MONITOR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) if (type == wdev->iftype)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) memset(&vifparams, 0, sizeof(vifparams));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) return cfg80211_change_iface(rdev, dev, type, &vifparams);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) EXPORT_WEXT_HANDLER(cfg80211_wext_siwmode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) int cfg80211_wext_giwmode(struct net_device *dev, struct iw_request_info *info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) u32 *mode, char *extra)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) struct wireless_dev *wdev = dev->ieee80211_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) if (!wdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) switch (wdev->iftype) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) case NL80211_IFTYPE_AP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) *mode = IW_MODE_MASTER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) case NL80211_IFTYPE_STATION:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) *mode = IW_MODE_INFRA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) case NL80211_IFTYPE_ADHOC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) *mode = IW_MODE_ADHOC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) case NL80211_IFTYPE_MONITOR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) *mode = IW_MODE_MONITOR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) case NL80211_IFTYPE_WDS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) *mode = IW_MODE_REPEAT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) case NL80211_IFTYPE_AP_VLAN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) *mode = IW_MODE_SECOND; /* FIXME */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) *mode = IW_MODE_AUTO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) EXPORT_WEXT_HANDLER(cfg80211_wext_giwmode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) int cfg80211_wext_giwrange(struct net_device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) struct iw_request_info *info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) struct iw_point *data, char *extra)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) struct wireless_dev *wdev = dev->ieee80211_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) struct iw_range *range = (struct iw_range *) extra;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) enum nl80211_band band;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) int i, c = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) if (!wdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) data->length = sizeof(struct iw_range);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) memset(range, 0, sizeof(struct iw_range));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) range->we_version_compiled = WIRELESS_EXT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) range->we_version_source = 21;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) range->retry_capa = IW_RETRY_LIMIT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) range->retry_flags = IW_RETRY_LIMIT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) range->min_retry = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) range->max_retry = 255;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) range->min_rts = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) range->max_rts = 2347;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) range->min_frag = 256;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) range->max_frag = 2346;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) range->max_encoding_tokens = 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) range->max_qual.updated = IW_QUAL_NOISE_INVALID;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) switch (wdev->wiphy->signal_type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) case CFG80211_SIGNAL_TYPE_NONE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) case CFG80211_SIGNAL_TYPE_MBM:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) range->max_qual.level = (u8)-110;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) range->max_qual.qual = 70;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) range->avg_qual.qual = 35;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) range->max_qual.updated |= IW_QUAL_DBM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) range->max_qual.updated |= IW_QUAL_QUAL_UPDATED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) range->max_qual.updated |= IW_QUAL_LEVEL_UPDATED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) case CFG80211_SIGNAL_TYPE_UNSPEC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) range->max_qual.level = 100;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) range->max_qual.qual = 100;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) range->avg_qual.qual = 50;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) range->max_qual.updated |= IW_QUAL_QUAL_UPDATED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) range->max_qual.updated |= IW_QUAL_LEVEL_UPDATED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) range->avg_qual.level = range->max_qual.level / 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) range->avg_qual.noise = range->max_qual.noise / 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) range->avg_qual.updated = range->max_qual.updated;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) for (i = 0; i < wdev->wiphy->n_cipher_suites; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) switch (wdev->wiphy->cipher_suites[i]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) case WLAN_CIPHER_SUITE_TKIP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) range->enc_capa |= (IW_ENC_CAPA_CIPHER_TKIP |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) IW_ENC_CAPA_WPA);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) case WLAN_CIPHER_SUITE_CCMP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) range->enc_capa |= (IW_ENC_CAPA_CIPHER_CCMP |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) IW_ENC_CAPA_WPA2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) case WLAN_CIPHER_SUITE_WEP40:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) range->encoding_size[range->num_encoding_sizes++] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) WLAN_KEY_LEN_WEP40;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) case WLAN_CIPHER_SUITE_WEP104:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) range->encoding_size[range->num_encoding_sizes++] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) WLAN_KEY_LEN_WEP104;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) for (band = 0; band < NUM_NL80211_BANDS; band ++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) struct ieee80211_supported_band *sband;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) sband = wdev->wiphy->bands[band];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) if (!sband)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) for (i = 0; i < sband->n_channels && c < IW_MAX_FREQUENCIES; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) struct ieee80211_channel *chan = &sband->channels[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) if (!(chan->flags & IEEE80211_CHAN_DISABLED)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) range->freq[c].i =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) ieee80211_frequency_to_channel(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) chan->center_freq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) range->freq[c].m = chan->center_freq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) range->freq[c].e = 6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) c++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) range->num_channels = c;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) range->num_frequency = c;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) IW_EVENT_CAPA_SET_KERNEL(range->event_capa);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) IW_EVENT_CAPA_SET(range->event_capa, SIOCGIWAP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) IW_EVENT_CAPA_SET(range->event_capa, SIOCGIWSCAN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) if (wdev->wiphy->max_scan_ssids > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) range->scan_capa |= IW_SCAN_CAPA_ESSID;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) EXPORT_WEXT_HANDLER(cfg80211_wext_giwrange);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) * cfg80211_wext_freq - get wext frequency for non-"auto"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) * @freq: the wext freq encoding
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) * Returns a frequency, or a negative error code, or 0 for auto.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) int cfg80211_wext_freq(struct iw_freq *freq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) * Parse frequency - return 0 for auto and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) * -EINVAL for impossible things.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) if (freq->e == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) enum nl80211_band band = NL80211_BAND_2GHZ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) if (freq->m < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) if (freq->m > 14)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) band = NL80211_BAND_5GHZ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) return ieee80211_channel_to_frequency(freq->m, band);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) int i, div = 1000000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) for (i = 0; i < freq->e; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) div /= 10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) if (div <= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) return freq->m / div;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) int cfg80211_wext_siwrts(struct net_device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) struct iw_request_info *info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) struct iw_param *rts, char *extra)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) struct wireless_dev *wdev = dev->ieee80211_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) u32 orts = wdev->wiphy->rts_threshold;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) if (rts->disabled || !rts->fixed)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) wdev->wiphy->rts_threshold = (u32) -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) else if (rts->value < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) wdev->wiphy->rts_threshold = rts->value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) err = rdev_set_wiphy_params(rdev, WIPHY_PARAM_RTS_THRESHOLD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) wdev->wiphy->rts_threshold = orts;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) EXPORT_WEXT_HANDLER(cfg80211_wext_siwrts);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) int cfg80211_wext_giwrts(struct net_device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) struct iw_request_info *info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) struct iw_param *rts, char *extra)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) struct wireless_dev *wdev = dev->ieee80211_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) rts->value = wdev->wiphy->rts_threshold;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) rts->disabled = rts->value == (u32) -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) rts->fixed = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) EXPORT_WEXT_HANDLER(cfg80211_wext_giwrts);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) int cfg80211_wext_siwfrag(struct net_device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) struct iw_request_info *info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) struct iw_param *frag, char *extra)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) struct wireless_dev *wdev = dev->ieee80211_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) u32 ofrag = wdev->wiphy->frag_threshold;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) if (frag->disabled || !frag->fixed)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) wdev->wiphy->frag_threshold = (u32) -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) else if (frag->value < 256)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) /* Fragment length must be even, so strip LSB. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) wdev->wiphy->frag_threshold = frag->value & ~0x1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) err = rdev_set_wiphy_params(rdev, WIPHY_PARAM_FRAG_THRESHOLD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) wdev->wiphy->frag_threshold = ofrag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) EXPORT_WEXT_HANDLER(cfg80211_wext_siwfrag);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) int cfg80211_wext_giwfrag(struct net_device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) struct iw_request_info *info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) struct iw_param *frag, char *extra)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) struct wireless_dev *wdev = dev->ieee80211_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) frag->value = wdev->wiphy->frag_threshold;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) frag->disabled = frag->value == (u32) -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) frag->fixed = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) EXPORT_WEXT_HANDLER(cfg80211_wext_giwfrag);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) static int cfg80211_wext_siwretry(struct net_device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) struct iw_request_info *info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) struct iw_param *retry, char *extra)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) struct wireless_dev *wdev = dev->ieee80211_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) u32 changed = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) u8 olong = wdev->wiphy->retry_long;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) u8 oshort = wdev->wiphy->retry_short;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) if (retry->disabled || retry->value < 1 || retry->value > 255 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) (retry->flags & IW_RETRY_TYPE) != IW_RETRY_LIMIT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) if (retry->flags & IW_RETRY_LONG) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) wdev->wiphy->retry_long = retry->value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) changed |= WIPHY_PARAM_RETRY_LONG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) } else if (retry->flags & IW_RETRY_SHORT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) wdev->wiphy->retry_short = retry->value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) changed |= WIPHY_PARAM_RETRY_SHORT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) wdev->wiphy->retry_short = retry->value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) wdev->wiphy->retry_long = retry->value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) changed |= WIPHY_PARAM_RETRY_LONG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) changed |= WIPHY_PARAM_RETRY_SHORT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) err = rdev_set_wiphy_params(rdev, changed);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) wdev->wiphy->retry_short = oshort;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) wdev->wiphy->retry_long = olong;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) int cfg80211_wext_giwretry(struct net_device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) struct iw_request_info *info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) struct iw_param *retry, char *extra)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) struct wireless_dev *wdev = dev->ieee80211_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) retry->disabled = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) if (retry->flags == 0 || (retry->flags & IW_RETRY_SHORT)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) * First return short value, iwconfig will ask long value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) * later if needed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) retry->flags |= IW_RETRY_LIMIT | IW_RETRY_SHORT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) retry->value = wdev->wiphy->retry_short;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) if (wdev->wiphy->retry_long == wdev->wiphy->retry_short)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) retry->flags |= IW_RETRY_LONG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) if (retry->flags & IW_RETRY_LONG) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) retry->flags = IW_RETRY_LIMIT | IW_RETRY_LONG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) retry->value = wdev->wiphy->retry_long;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) EXPORT_WEXT_HANDLER(cfg80211_wext_giwretry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) static int __cfg80211_set_encryption(struct cfg80211_registered_device *rdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) struct net_device *dev, bool pairwise,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) const u8 *addr, bool remove, bool tx_key,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) int idx, struct key_params *params)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) struct wireless_dev *wdev = dev->ieee80211_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) int err, i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) bool rejoin = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) if (pairwise && !addr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) * In many cases we won't actually need this, but it's better
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) * to do it first in case the allocation fails. Don't use wext.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) if (!wdev->wext.keys) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) wdev->wext.keys = kzalloc(sizeof(*wdev->wext.keys),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) if (!wdev->wext.keys)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) for (i = 0; i < CFG80211_MAX_WEP_KEYS; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) wdev->wext.keys->params[i].key =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) wdev->wext.keys->data[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) if (wdev->iftype != NL80211_IFTYPE_ADHOC &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) wdev->iftype != NL80211_IFTYPE_STATION)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) if (params->cipher == WLAN_CIPHER_SUITE_AES_CMAC) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) if (!wdev->current_bss)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) return -ENOLINK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) if (!rdev->ops->set_default_mgmt_key)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) if (idx < 4 || idx > 5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) } else if (idx < 0 || idx > 3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) if (remove) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) if (wdev->current_bss) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) * If removing the current TX key, we will need to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) * join a new IBSS without the privacy bit clear.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) if (idx == wdev->wext.default_key &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) wdev->iftype == NL80211_IFTYPE_ADHOC) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) __cfg80211_leave_ibss(rdev, wdev->netdev, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) rejoin = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) if (!pairwise && addr &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) !(rdev->wiphy.flags & WIPHY_FLAG_IBSS_RSN))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) err = -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) err = rdev_del_key(rdev, dev, idx, pairwise,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) wdev->wext.connect.privacy = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) * Applications using wireless extensions expect to be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) * able to delete keys that don't exist, so allow that.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) if (err == -ENOENT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) if (!err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) if (!addr && idx < 4) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) memset(wdev->wext.keys->data[idx], 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) sizeof(wdev->wext.keys->data[idx]));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) wdev->wext.keys->params[idx].key_len = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) wdev->wext.keys->params[idx].cipher = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) if (idx == wdev->wext.default_key)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) wdev->wext.default_key = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) else if (idx == wdev->wext.default_mgmt_key)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) wdev->wext.default_mgmt_key = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) if (!err && rejoin)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) err = cfg80211_ibss_wext_join(rdev, wdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) if (addr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) tx_key = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) if (cfg80211_validate_key_settings(rdev, params, idx, pairwise, addr))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) if (wdev->current_bss)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) err = rdev_add_key(rdev, dev, idx, pairwise, addr, params);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) else if (params->cipher != WLAN_CIPHER_SUITE_WEP40 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) params->cipher != WLAN_CIPHER_SUITE_WEP104)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) * We only need to store WEP keys, since they're the only keys that
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) * can be set before a connection is established and persist after
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) * disconnecting.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) if (!addr && (params->cipher == WLAN_CIPHER_SUITE_WEP40 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) params->cipher == WLAN_CIPHER_SUITE_WEP104)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) wdev->wext.keys->params[idx] = *params;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) memcpy(wdev->wext.keys->data[idx],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) params->key, params->key_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) wdev->wext.keys->params[idx].key =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) wdev->wext.keys->data[idx];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) if ((params->cipher == WLAN_CIPHER_SUITE_WEP40 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) params->cipher == WLAN_CIPHER_SUITE_WEP104) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) (tx_key || (!addr && wdev->wext.default_key == -1))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) if (wdev->current_bss) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) * If we are getting a new TX key from not having
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) * had one before we need to join a new IBSS with
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) * the privacy bit set.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) if (wdev->iftype == NL80211_IFTYPE_ADHOC &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) wdev->wext.default_key == -1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) __cfg80211_leave_ibss(rdev, wdev->netdev, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) rejoin = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) err = rdev_set_default_key(rdev, dev, idx, true, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) if (!err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) wdev->wext.default_key = idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) if (rejoin)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) err = cfg80211_ibss_wext_join(rdev, wdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) if (params->cipher == WLAN_CIPHER_SUITE_AES_CMAC &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) (tx_key || (!addr && wdev->wext.default_mgmt_key == -1))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) if (wdev->current_bss)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) err = rdev_set_default_mgmt_key(rdev, dev, idx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) if (!err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) wdev->wext.default_mgmt_key = idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) static int cfg80211_set_encryption(struct cfg80211_registered_device *rdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) struct net_device *dev, bool pairwise,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) const u8 *addr, bool remove, bool tx_key,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) int idx, struct key_params *params)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) wdev_lock(dev->ieee80211_ptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) err = __cfg80211_set_encryption(rdev, dev, pairwise, addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) remove, tx_key, idx, params);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) wdev_unlock(dev->ieee80211_ptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) static int cfg80211_wext_siwencode(struct net_device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) struct iw_request_info *info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) struct iw_point *erq, char *keybuf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) struct wireless_dev *wdev = dev->ieee80211_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) int idx, err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) bool remove = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) struct key_params params;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) if (wdev->iftype != NL80211_IFTYPE_STATION &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) wdev->iftype != NL80211_IFTYPE_ADHOC)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) /* no use -- only MFP (set_default_mgmt_key) is optional */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) if (!rdev->ops->del_key ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) !rdev->ops->add_key ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) !rdev->ops->set_default_key)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) idx = erq->flags & IW_ENCODE_INDEX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) if (idx == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) idx = wdev->wext.default_key;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) if (idx < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) idx = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) } else if (idx < 1 || idx > 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) idx--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) if (erq->flags & IW_ENCODE_DISABLED)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) remove = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) else if (erq->length == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) /* No key data - just set the default TX key index */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) wdev_lock(wdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) if (wdev->current_bss)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) err = rdev_set_default_key(rdev, dev, idx, true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) if (!err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) wdev->wext.default_key = idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) wdev_unlock(wdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) memset(¶ms, 0, sizeof(params));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) params.key = keybuf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) params.key_len = erq->length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) if (erq->length == 5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) params.cipher = WLAN_CIPHER_SUITE_WEP40;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) else if (erq->length == 13)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) params.cipher = WLAN_CIPHER_SUITE_WEP104;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) else if (!remove)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) return cfg80211_set_encryption(rdev, dev, false, NULL, remove,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) wdev->wext.default_key == -1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) idx, ¶ms);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) static int cfg80211_wext_siwencodeext(struct net_device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) struct iw_request_info *info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) struct iw_point *erq, char *extra)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) struct wireless_dev *wdev = dev->ieee80211_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) struct iw_encode_ext *ext = (struct iw_encode_ext *) extra;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) const u8 *addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) int idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) bool remove = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) struct key_params params;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) u32 cipher;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) if (wdev->iftype != NL80211_IFTYPE_STATION &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) wdev->iftype != NL80211_IFTYPE_ADHOC)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) /* no use -- only MFP (set_default_mgmt_key) is optional */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) if (!rdev->ops->del_key ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) !rdev->ops->add_key ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) !rdev->ops->set_default_key)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) switch (ext->alg) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) case IW_ENCODE_ALG_NONE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) remove = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) cipher = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) case IW_ENCODE_ALG_WEP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) if (ext->key_len == 5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) cipher = WLAN_CIPHER_SUITE_WEP40;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) else if (ext->key_len == 13)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) cipher = WLAN_CIPHER_SUITE_WEP104;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) case IW_ENCODE_ALG_TKIP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) cipher = WLAN_CIPHER_SUITE_TKIP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) case IW_ENCODE_ALG_CCMP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) cipher = WLAN_CIPHER_SUITE_CCMP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) case IW_ENCODE_ALG_AES_CMAC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) cipher = WLAN_CIPHER_SUITE_AES_CMAC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) if (erq->flags & IW_ENCODE_DISABLED)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) remove = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) idx = erq->flags & IW_ENCODE_INDEX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) if (cipher == WLAN_CIPHER_SUITE_AES_CMAC) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) if (idx < 4 || idx > 5) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) idx = wdev->wext.default_mgmt_key;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) if (idx < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) idx--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) if (idx < 1 || idx > 4) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) idx = wdev->wext.default_key;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) if (idx < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) idx--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) addr = ext->addr.sa_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) if (is_broadcast_ether_addr(addr))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) addr = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) memset(¶ms, 0, sizeof(params));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) params.key = ext->key;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) params.key_len = ext->key_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) params.cipher = cipher;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) if (ext->ext_flags & IW_ENCODE_EXT_RX_SEQ_VALID) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) params.seq = ext->rx_seq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) params.seq_len = 6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) return cfg80211_set_encryption(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) rdev, dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) !(ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) addr, remove,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) idx, ¶ms);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) static int cfg80211_wext_giwencode(struct net_device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) struct iw_request_info *info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) struct iw_point *erq, char *keybuf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) struct wireless_dev *wdev = dev->ieee80211_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) int idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) if (wdev->iftype != NL80211_IFTYPE_STATION &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) wdev->iftype != NL80211_IFTYPE_ADHOC)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) idx = erq->flags & IW_ENCODE_INDEX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) if (idx == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) idx = wdev->wext.default_key;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) if (idx < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) idx = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) } else if (idx < 1 || idx > 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) idx--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) erq->flags = idx + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) if (!wdev->wext.keys || !wdev->wext.keys->params[idx].cipher) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) erq->flags |= IW_ENCODE_DISABLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) erq->length = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) erq->length = min_t(size_t, erq->length,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) wdev->wext.keys->params[idx].key_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) memcpy(keybuf, wdev->wext.keys->params[idx].key, erq->length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) erq->flags |= IW_ENCODE_ENABLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) static int cfg80211_wext_siwfreq(struct net_device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) struct iw_request_info *info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) struct iw_freq *wextfreq, char *extra)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) struct wireless_dev *wdev = dev->ieee80211_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) struct cfg80211_chan_def chandef = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) .width = NL80211_CHAN_WIDTH_20_NOHT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) int freq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) switch (wdev->iftype) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) case NL80211_IFTYPE_STATION:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) return cfg80211_mgd_wext_siwfreq(dev, info, wextfreq, extra);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) case NL80211_IFTYPE_ADHOC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) return cfg80211_ibss_wext_siwfreq(dev, info, wextfreq, extra);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) case NL80211_IFTYPE_MONITOR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) freq = cfg80211_wext_freq(wextfreq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) if (freq < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) return freq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) if (freq == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) chandef.center_freq1 = freq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) chandef.chan = ieee80211_get_channel(&rdev->wiphy, freq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) if (!chandef.chan)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) return cfg80211_set_monitor_channel(rdev, &chandef);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) case NL80211_IFTYPE_MESH_POINT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) freq = cfg80211_wext_freq(wextfreq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) if (freq < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) return freq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) if (freq == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) chandef.center_freq1 = freq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) chandef.chan = ieee80211_get_channel(&rdev->wiphy, freq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) if (!chandef.chan)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) return cfg80211_set_mesh_channel(rdev, wdev, &chandef);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) static int cfg80211_wext_giwfreq(struct net_device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) struct iw_request_info *info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) struct iw_freq *freq, char *extra)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) struct wireless_dev *wdev = dev->ieee80211_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) struct cfg80211_chan_def chandef = {};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) switch (wdev->iftype) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) case NL80211_IFTYPE_STATION:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) return cfg80211_mgd_wext_giwfreq(dev, info, freq, extra);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) case NL80211_IFTYPE_ADHOC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) return cfg80211_ibss_wext_giwfreq(dev, info, freq, extra);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) case NL80211_IFTYPE_MONITOR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) if (!rdev->ops->get_channel)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) ret = rdev_get_channel(rdev, wdev, &chandef);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) freq->m = chandef.chan->center_freq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) freq->e = 6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) static int cfg80211_wext_siwtxpower(struct net_device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) struct iw_request_info *info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) union iwreq_data *data, char *extra)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) struct wireless_dev *wdev = dev->ieee80211_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) enum nl80211_tx_power_setting type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) int dbm = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) if ((data->txpower.flags & IW_TXPOW_TYPE) != IW_TXPOW_DBM)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) if (data->txpower.flags & IW_TXPOW_RANGE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) if (!rdev->ops->set_tx_power)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) /* only change when not disabling */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) if (!data->txpower.disabled) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) rfkill_set_sw_state(rdev->rfkill, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) if (data->txpower.fixed) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) * wext doesn't support negative values, see
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) * below where it's for automatic
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) if (data->txpower.value < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) dbm = data->txpower.value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) type = NL80211_TX_POWER_FIXED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) /* TODO: do regulatory check! */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) * Automatic power level setting, max being the value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) * passed in from userland.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) if (data->txpower.value < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) type = NL80211_TX_POWER_AUTOMATIC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) dbm = data->txpower.value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) type = NL80211_TX_POWER_LIMITED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) if (rfkill_set_sw_state(rdev->rfkill, true))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) schedule_work(&rdev->rfkill_block);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) return rdev_set_tx_power(rdev, wdev, type, DBM_TO_MBM(dbm));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) static int cfg80211_wext_giwtxpower(struct net_device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) struct iw_request_info *info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) union iwreq_data *data, char *extra)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) struct wireless_dev *wdev = dev->ieee80211_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881) int err, val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) if ((data->txpower.flags & IW_TXPOW_TYPE) != IW_TXPOW_DBM)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) if (data->txpower.flags & IW_TXPOW_RANGE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) if (!rdev->ops->get_tx_power)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889) return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) err = rdev_get_tx_power(rdev, wdev, &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895) /* well... oh well */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) data->txpower.fixed = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897) data->txpower.disabled = rfkill_blocked(rdev->rfkill);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) data->txpower.value = val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) data->txpower.flags = IW_TXPOW_DBM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904) static int cfg80211_set_auth_alg(struct wireless_dev *wdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) s32 auth_alg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) int nr_alg = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) if (!auth_alg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) if (auth_alg & ~(IW_AUTH_ALG_OPEN_SYSTEM |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913) IW_AUTH_ALG_SHARED_KEY |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) IW_AUTH_ALG_LEAP))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) if (auth_alg & IW_AUTH_ALG_OPEN_SYSTEM) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918) nr_alg++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919) wdev->wext.connect.auth_type = NL80211_AUTHTYPE_OPEN_SYSTEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922) if (auth_alg & IW_AUTH_ALG_SHARED_KEY) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) nr_alg++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924) wdev->wext.connect.auth_type = NL80211_AUTHTYPE_SHARED_KEY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927) if (auth_alg & IW_AUTH_ALG_LEAP) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) nr_alg++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929) wdev->wext.connect.auth_type = NL80211_AUTHTYPE_NETWORK_EAP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932) if (nr_alg > 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933) wdev->wext.connect.auth_type = NL80211_AUTHTYPE_AUTOMATIC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938) static int cfg80211_set_wpa_version(struct wireless_dev *wdev, u32 wpa_versions)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940) if (wpa_versions & ~(IW_AUTH_WPA_VERSION_WPA |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941) IW_AUTH_WPA_VERSION_WPA2|
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942) IW_AUTH_WPA_VERSION_DISABLED))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945) if ((wpa_versions & IW_AUTH_WPA_VERSION_DISABLED) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946) (wpa_versions & (IW_AUTH_WPA_VERSION_WPA|
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947) IW_AUTH_WPA_VERSION_WPA2)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950) if (wpa_versions & IW_AUTH_WPA_VERSION_DISABLED)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951) wdev->wext.connect.crypto.wpa_versions &=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952) ~(NL80211_WPA_VERSION_1|NL80211_WPA_VERSION_2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954) if (wpa_versions & IW_AUTH_WPA_VERSION_WPA)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955) wdev->wext.connect.crypto.wpa_versions |=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956) NL80211_WPA_VERSION_1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958) if (wpa_versions & IW_AUTH_WPA_VERSION_WPA2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959) wdev->wext.connect.crypto.wpa_versions |=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960) NL80211_WPA_VERSION_2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965) static int cfg80211_set_cipher_group(struct wireless_dev *wdev, u32 cipher)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967) if (cipher & IW_AUTH_CIPHER_WEP40)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968) wdev->wext.connect.crypto.cipher_group =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969) WLAN_CIPHER_SUITE_WEP40;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970) else if (cipher & IW_AUTH_CIPHER_WEP104)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971) wdev->wext.connect.crypto.cipher_group =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972) WLAN_CIPHER_SUITE_WEP104;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973) else if (cipher & IW_AUTH_CIPHER_TKIP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974) wdev->wext.connect.crypto.cipher_group =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975) WLAN_CIPHER_SUITE_TKIP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976) else if (cipher & IW_AUTH_CIPHER_CCMP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977) wdev->wext.connect.crypto.cipher_group =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978) WLAN_CIPHER_SUITE_CCMP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979) else if (cipher & IW_AUTH_CIPHER_AES_CMAC)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980) wdev->wext.connect.crypto.cipher_group =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981) WLAN_CIPHER_SUITE_AES_CMAC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982) else if (cipher & IW_AUTH_CIPHER_NONE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983) wdev->wext.connect.crypto.cipher_group = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990) static int cfg80211_set_cipher_pairwise(struct wireless_dev *wdev, u32 cipher)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992) int nr_ciphers = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993) u32 *ciphers_pairwise = wdev->wext.connect.crypto.ciphers_pairwise;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995) if (cipher & IW_AUTH_CIPHER_WEP40) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996) ciphers_pairwise[nr_ciphers] = WLAN_CIPHER_SUITE_WEP40;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997) nr_ciphers++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) if (cipher & IW_AUTH_CIPHER_WEP104) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) ciphers_pairwise[nr_ciphers] = WLAN_CIPHER_SUITE_WEP104;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) nr_ciphers++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) if (cipher & IW_AUTH_CIPHER_TKIP) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) ciphers_pairwise[nr_ciphers] = WLAN_CIPHER_SUITE_TKIP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) nr_ciphers++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) if (cipher & IW_AUTH_CIPHER_CCMP) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) ciphers_pairwise[nr_ciphers] = WLAN_CIPHER_SUITE_CCMP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) nr_ciphers++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) if (cipher & IW_AUTH_CIPHER_AES_CMAC) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) ciphers_pairwise[nr_ciphers] = WLAN_CIPHER_SUITE_AES_CMAC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) nr_ciphers++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) BUILD_BUG_ON(NL80211_MAX_NR_CIPHER_SUITES < 5);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) wdev->wext.connect.crypto.n_ciphers_pairwise = nr_ciphers;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) static int cfg80211_set_key_mgt(struct wireless_dev *wdev, u32 key_mgt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) int nr_akm_suites = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) if (key_mgt & ~(IW_AUTH_KEY_MGMT_802_1X |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) IW_AUTH_KEY_MGMT_PSK))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) if (key_mgt & IW_AUTH_KEY_MGMT_802_1X) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) wdev->wext.connect.crypto.akm_suites[nr_akm_suites] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) WLAN_AKM_SUITE_8021X;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) nr_akm_suites++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) if (key_mgt & IW_AUTH_KEY_MGMT_PSK) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) wdev->wext.connect.crypto.akm_suites[nr_akm_suites] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) WLAN_AKM_SUITE_PSK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) nr_akm_suites++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) wdev->wext.connect.crypto.n_akm_suites = nr_akm_suites;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) static int cfg80211_wext_siwauth(struct net_device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) struct iw_request_info *info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) struct iw_param *data, char *extra)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) struct wireless_dev *wdev = dev->ieee80211_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) if (wdev->iftype != NL80211_IFTYPE_STATION)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) switch (data->flags & IW_AUTH_INDEX) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) case IW_AUTH_PRIVACY_INVOKED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) wdev->wext.connect.privacy = data->value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) case IW_AUTH_WPA_VERSION:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) return cfg80211_set_wpa_version(wdev, data->value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) case IW_AUTH_CIPHER_GROUP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) return cfg80211_set_cipher_group(wdev, data->value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) case IW_AUTH_KEY_MGMT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) return cfg80211_set_key_mgt(wdev, data->value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) case IW_AUTH_CIPHER_PAIRWISE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) return cfg80211_set_cipher_pairwise(wdev, data->value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) case IW_AUTH_80211_AUTH_ALG:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) return cfg80211_set_auth_alg(wdev, data->value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) case IW_AUTH_WPA_ENABLED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) case IW_AUTH_RX_UNENCRYPTED_EAPOL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) case IW_AUTH_DROP_UNENCRYPTED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) case IW_AUTH_MFP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) static int cfg80211_wext_giwauth(struct net_device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) struct iw_request_info *info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) struct iw_param *data, char *extra)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) /* XXX: what do we need? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) static int cfg80211_wext_siwpower(struct net_device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) struct iw_request_info *info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) struct iw_param *wrq, char *extra)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) struct wireless_dev *wdev = dev->ieee80211_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) bool ps = wdev->ps;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) int timeout = wdev->ps_timeout;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) if (wdev->iftype != NL80211_IFTYPE_STATION)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) if (!rdev->ops->set_power_mgmt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) if (wrq->disabled) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) ps = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114) switch (wrq->flags & IW_POWER_MODE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) case IW_POWER_ON: /* If not specified */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) case IW_POWER_MODE: /* If set all mask */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117) case IW_POWER_ALL_R: /* If explicitely state all */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) ps = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) default: /* Otherwise we ignore */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) if (wrq->flags & ~(IW_POWER_MODE | IW_POWER_TIMEOUT))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) if (wrq->flags & IW_POWER_TIMEOUT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) timeout = wrq->value / 1000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131) err = rdev_set_power_mgmt(rdev, dev, ps, timeout);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135) wdev->ps = ps;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136) wdev->ps_timeout = timeout;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142) static int cfg80211_wext_giwpower(struct net_device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143) struct iw_request_info *info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144) struct iw_param *wrq, char *extra)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146) struct wireless_dev *wdev = dev->ieee80211_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148) wrq->disabled = !wdev->ps;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153) static int cfg80211_wds_wext_siwap(struct net_device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154) struct iw_request_info *info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155) struct sockaddr *addr, char *extra)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157) struct wireless_dev *wdev = dev->ieee80211_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158) struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161) if (WARN_ON(wdev->iftype != NL80211_IFTYPE_WDS))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164) if (addr->sa_family != ARPHRD_ETHER)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167) if (netif_running(dev))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168) return -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170) if (!rdev->ops->set_wds_peer)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171) return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173) err = rdev_set_wds_peer(rdev, dev, (u8 *)&addr->sa_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177) memcpy(&wdev->wext.bssid, (u8 *) &addr->sa_data, ETH_ALEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182) static int cfg80211_wds_wext_giwap(struct net_device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183) struct iw_request_info *info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184) struct sockaddr *addr, char *extra)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186) struct wireless_dev *wdev = dev->ieee80211_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188) if (WARN_ON(wdev->iftype != NL80211_IFTYPE_WDS))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191) addr->sa_family = ARPHRD_ETHER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192) memcpy(&addr->sa_data, wdev->wext.bssid, ETH_ALEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197) static int cfg80211_wext_siwrate(struct net_device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198) struct iw_request_info *info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199) struct iw_param *rate, char *extra)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201) struct wireless_dev *wdev = dev->ieee80211_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202) struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203) struct cfg80211_bitrate_mask mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204) u32 fixed, maxrate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205) struct ieee80211_supported_band *sband;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206) int band, ridx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207) bool match = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209) if (!rdev->ops->set_bitrate_mask)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210) return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212) memset(&mask, 0, sizeof(mask));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213) fixed = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214) maxrate = (u32)-1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216) if (rate->value < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217) /* nothing */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218) } else if (rate->fixed) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219) fixed = rate->value / 100000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221) maxrate = rate->value / 100000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1224) for (band = 0; band < NUM_NL80211_BANDS; band++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1225) sband = wdev->wiphy->bands[band];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1226) if (sband == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1227) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1228) for (ridx = 0; ridx < sband->n_bitrates; ridx++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1229) struct ieee80211_rate *srate = &sband->bitrates[ridx];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1230) if (fixed == srate->bitrate) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1231) mask.control[band].legacy = 1 << ridx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1232) match = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1233) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1234) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1235) if (srate->bitrate <= maxrate) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1236) mask.control[band].legacy |= 1 << ridx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1237) match = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1238) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1239) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1240) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1241)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1242) if (!match)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1243) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1244)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1245) return rdev_set_bitrate_mask(rdev, dev, NULL, &mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1246) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1247)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1248) static int cfg80211_wext_giwrate(struct net_device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1249) struct iw_request_info *info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1250) struct iw_param *rate, char *extra)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1251) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1252) struct wireless_dev *wdev = dev->ieee80211_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1253) struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1254) struct station_info sinfo = {};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1255) u8 addr[ETH_ALEN];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1256) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1257)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1258) if (wdev->iftype != NL80211_IFTYPE_STATION)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1259) return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1260)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1261) if (!rdev->ops->get_station)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1262) return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1263)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1264) err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1265) wdev_lock(wdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1266) if (wdev->current_bss)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1267) memcpy(addr, wdev->current_bss->pub.bssid, ETH_ALEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1268) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1269) err = -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1270) wdev_unlock(wdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1271) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1272) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1273)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1274) err = rdev_get_station(rdev, dev, addr, &sinfo);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1275) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1276) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1277)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1278) if (!(sinfo.filled & BIT_ULL(NL80211_STA_INFO_TX_BITRATE))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1279) err = -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1280) goto free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1281) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1282)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1283) rate->value = 100000 * cfg80211_calculate_bitrate(&sinfo.txrate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1284)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1285) free:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1286) cfg80211_sinfo_release_content(&sinfo);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1287) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1288) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1289)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1290) /* Get wireless statistics. Called by /proc/net/wireless and by SIOCGIWSTATS */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1291) static struct iw_statistics *cfg80211_wireless_stats(struct net_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1292) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1293) struct wireless_dev *wdev = dev->ieee80211_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1294) struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1295) /* we are under RTNL - globally locked - so can use static structs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1296) static struct iw_statistics wstats;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1297) static struct station_info sinfo = {};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1298) u8 bssid[ETH_ALEN];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1299)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1300) if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1301) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1302)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1303) if (!rdev->ops->get_station)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1304) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1305)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1306) /* Grab BSSID of current BSS, if any */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1307) wdev_lock(wdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1308) if (!wdev->current_bss) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1309) wdev_unlock(wdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1310) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1311) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1312) memcpy(bssid, wdev->current_bss->pub.bssid, ETH_ALEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1313) wdev_unlock(wdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1314)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1315) memset(&sinfo, 0, sizeof(sinfo));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1316)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1317) if (rdev_get_station(rdev, dev, bssid, &sinfo))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1318) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1319)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1320) memset(&wstats, 0, sizeof(wstats));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1321)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1322) switch (rdev->wiphy.signal_type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1323) case CFG80211_SIGNAL_TYPE_MBM:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1324) if (sinfo.filled & BIT_ULL(NL80211_STA_INFO_SIGNAL)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1325) int sig = sinfo.signal;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1326) wstats.qual.updated |= IW_QUAL_LEVEL_UPDATED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1327) wstats.qual.updated |= IW_QUAL_QUAL_UPDATED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1328) wstats.qual.updated |= IW_QUAL_DBM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1329) wstats.qual.level = sig;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1330) if (sig < -110)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1331) sig = -110;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1332) else if (sig > -40)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1333) sig = -40;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1334) wstats.qual.qual = sig + 110;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1335) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1336) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1337) fallthrough;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1338) case CFG80211_SIGNAL_TYPE_UNSPEC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1339) if (sinfo.filled & BIT_ULL(NL80211_STA_INFO_SIGNAL)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1340) wstats.qual.updated |= IW_QUAL_LEVEL_UPDATED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1341) wstats.qual.updated |= IW_QUAL_QUAL_UPDATED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1342) wstats.qual.level = sinfo.signal;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1343) wstats.qual.qual = sinfo.signal;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1344) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1345) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1346) fallthrough;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1347) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1348) wstats.qual.updated |= IW_QUAL_LEVEL_INVALID;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1349) wstats.qual.updated |= IW_QUAL_QUAL_INVALID;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1350) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1351)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1352) wstats.qual.updated |= IW_QUAL_NOISE_INVALID;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1353) if (sinfo.filled & BIT_ULL(NL80211_STA_INFO_RX_DROP_MISC))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1354) wstats.discard.misc = sinfo.rx_dropped_misc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1355) if (sinfo.filled & BIT_ULL(NL80211_STA_INFO_TX_FAILED))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1356) wstats.discard.retries = sinfo.tx_failed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1357)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1358) cfg80211_sinfo_release_content(&sinfo);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1359)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1360) return &wstats;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1361) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1362)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1363) static int cfg80211_wext_siwap(struct net_device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1364) struct iw_request_info *info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1365) struct sockaddr *ap_addr, char *extra)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1366) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1367) struct wireless_dev *wdev = dev->ieee80211_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1368)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1369) switch (wdev->iftype) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1370) case NL80211_IFTYPE_ADHOC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1371) return cfg80211_ibss_wext_siwap(dev, info, ap_addr, extra);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1372) case NL80211_IFTYPE_STATION:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1373) return cfg80211_mgd_wext_siwap(dev, info, ap_addr, extra);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1374) case NL80211_IFTYPE_WDS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1375) return cfg80211_wds_wext_siwap(dev, info, ap_addr, extra);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1376) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1377) return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1378) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1379) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1380)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1381) static int cfg80211_wext_giwap(struct net_device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1382) struct iw_request_info *info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1383) struct sockaddr *ap_addr, char *extra)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1384) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1385) struct wireless_dev *wdev = dev->ieee80211_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1386)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1387) switch (wdev->iftype) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1388) case NL80211_IFTYPE_ADHOC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1389) return cfg80211_ibss_wext_giwap(dev, info, ap_addr, extra);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1390) case NL80211_IFTYPE_STATION:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1391) return cfg80211_mgd_wext_giwap(dev, info, ap_addr, extra);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1392) case NL80211_IFTYPE_WDS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1393) return cfg80211_wds_wext_giwap(dev, info, ap_addr, extra);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1394) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1395) return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1396) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1397) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1398)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1399) static int cfg80211_wext_siwessid(struct net_device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1400) struct iw_request_info *info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1401) struct iw_point *data, char *ssid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1402) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1403) struct wireless_dev *wdev = dev->ieee80211_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1404)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1405) switch (wdev->iftype) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1406) case NL80211_IFTYPE_ADHOC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1407) return cfg80211_ibss_wext_siwessid(dev, info, data, ssid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1408) case NL80211_IFTYPE_STATION:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1409) return cfg80211_mgd_wext_siwessid(dev, info, data, ssid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1410) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1411) return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1412) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1413) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1414)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1415) static int cfg80211_wext_giwessid(struct net_device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1416) struct iw_request_info *info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1417) struct iw_point *data, char *ssid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1418) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1419) struct wireless_dev *wdev = dev->ieee80211_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1420)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1421) data->flags = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1422) data->length = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1423)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1424) switch (wdev->iftype) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1425) case NL80211_IFTYPE_ADHOC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1426) return cfg80211_ibss_wext_giwessid(dev, info, data, ssid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1427) case NL80211_IFTYPE_STATION:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1428) return cfg80211_mgd_wext_giwessid(dev, info, data, ssid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1429) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1430) return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1431) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1432) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1433)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1434) static int cfg80211_wext_siwpmksa(struct net_device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1435) struct iw_request_info *info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1436) struct iw_point *data, char *extra)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1437) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1438) struct wireless_dev *wdev = dev->ieee80211_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1439) struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1440) struct cfg80211_pmksa cfg_pmksa;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1441) struct iw_pmksa *pmksa = (struct iw_pmksa *)extra;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1442)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1443) memset(&cfg_pmksa, 0, sizeof(struct cfg80211_pmksa));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1444)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1445) if (wdev->iftype != NL80211_IFTYPE_STATION)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1446) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1447)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1448) cfg_pmksa.bssid = pmksa->bssid.sa_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1449) cfg_pmksa.pmkid = pmksa->pmkid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1450)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1451) switch (pmksa->cmd) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1452) case IW_PMKSA_ADD:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1453) if (!rdev->ops->set_pmksa)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1454) return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1455)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1456) return rdev_set_pmksa(rdev, dev, &cfg_pmksa);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1457)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1458) case IW_PMKSA_REMOVE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1459) if (!rdev->ops->del_pmksa)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1460) return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1461)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1462) return rdev_del_pmksa(rdev, dev, &cfg_pmksa);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1463)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1464) case IW_PMKSA_FLUSH:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1465) if (!rdev->ops->flush_pmksa)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1466) return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1467)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1468) return rdev_flush_pmksa(rdev, dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1469)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1470) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1471) return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1472) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1473) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1474)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1475) #define DEFINE_WEXT_COMPAT_STUB(func, type) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1476) static int __ ## func(struct net_device *dev, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1477) struct iw_request_info *info, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1478) union iwreq_data *wrqu, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1479) char *extra) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1480) { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1481) return func(dev, info, (type *)wrqu, extra); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1482) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1483)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1484) DEFINE_WEXT_COMPAT_STUB(cfg80211_wext_giwname, char)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1485) DEFINE_WEXT_COMPAT_STUB(cfg80211_wext_siwfreq, struct iw_freq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1486) DEFINE_WEXT_COMPAT_STUB(cfg80211_wext_giwfreq, struct iw_freq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1487) DEFINE_WEXT_COMPAT_STUB(cfg80211_wext_siwmode, u32)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1488) DEFINE_WEXT_COMPAT_STUB(cfg80211_wext_giwmode, u32)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1489) DEFINE_WEXT_COMPAT_STUB(cfg80211_wext_giwrange, struct iw_point)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1490) DEFINE_WEXT_COMPAT_STUB(cfg80211_wext_siwap, struct sockaddr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1491) DEFINE_WEXT_COMPAT_STUB(cfg80211_wext_giwap, struct sockaddr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1492) DEFINE_WEXT_COMPAT_STUB(cfg80211_wext_siwmlme, struct iw_point)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1493) DEFINE_WEXT_COMPAT_STUB(cfg80211_wext_giwscan, struct iw_point)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1494) DEFINE_WEXT_COMPAT_STUB(cfg80211_wext_siwessid, struct iw_point)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1495) DEFINE_WEXT_COMPAT_STUB(cfg80211_wext_giwessid, struct iw_point)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1496) DEFINE_WEXT_COMPAT_STUB(cfg80211_wext_siwrate, struct iw_param)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1497) DEFINE_WEXT_COMPAT_STUB(cfg80211_wext_giwrate, struct iw_param)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1498) DEFINE_WEXT_COMPAT_STUB(cfg80211_wext_siwrts, struct iw_param)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1499) DEFINE_WEXT_COMPAT_STUB(cfg80211_wext_giwrts, struct iw_param)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1500) DEFINE_WEXT_COMPAT_STUB(cfg80211_wext_siwfrag, struct iw_param)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1501) DEFINE_WEXT_COMPAT_STUB(cfg80211_wext_giwfrag, struct iw_param)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1502) DEFINE_WEXT_COMPAT_STUB(cfg80211_wext_siwretry, struct iw_param)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1503) DEFINE_WEXT_COMPAT_STUB(cfg80211_wext_giwretry, struct iw_param)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1504) DEFINE_WEXT_COMPAT_STUB(cfg80211_wext_siwencode, struct iw_point)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1505) DEFINE_WEXT_COMPAT_STUB(cfg80211_wext_giwencode, struct iw_point)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1506) DEFINE_WEXT_COMPAT_STUB(cfg80211_wext_giwpower, struct iw_param)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1507) DEFINE_WEXT_COMPAT_STUB(cfg80211_wext_siwpower, struct iw_param)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1508) DEFINE_WEXT_COMPAT_STUB(cfg80211_wext_siwgenie, struct iw_point)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1509) DEFINE_WEXT_COMPAT_STUB(cfg80211_wext_giwauth, struct iw_param)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1510) DEFINE_WEXT_COMPAT_STUB(cfg80211_wext_siwauth, struct iw_param)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1511) DEFINE_WEXT_COMPAT_STUB(cfg80211_wext_siwencodeext, struct iw_point)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1512) DEFINE_WEXT_COMPAT_STUB(cfg80211_wext_siwpmksa, struct iw_point)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1513)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1514) static const iw_handler cfg80211_handlers[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1515) [IW_IOCTL_IDX(SIOCGIWNAME)] = __cfg80211_wext_giwname,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1516) [IW_IOCTL_IDX(SIOCSIWFREQ)] = __cfg80211_wext_siwfreq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1517) [IW_IOCTL_IDX(SIOCGIWFREQ)] = __cfg80211_wext_giwfreq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1518) [IW_IOCTL_IDX(SIOCSIWMODE)] = __cfg80211_wext_siwmode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1519) [IW_IOCTL_IDX(SIOCGIWMODE)] = __cfg80211_wext_giwmode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1520) [IW_IOCTL_IDX(SIOCGIWRANGE)] = __cfg80211_wext_giwrange,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1521) [IW_IOCTL_IDX(SIOCSIWAP)] = __cfg80211_wext_siwap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1522) [IW_IOCTL_IDX(SIOCGIWAP)] = __cfg80211_wext_giwap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1523) [IW_IOCTL_IDX(SIOCSIWMLME)] = __cfg80211_wext_siwmlme,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1524) [IW_IOCTL_IDX(SIOCSIWSCAN)] = cfg80211_wext_siwscan,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1525) [IW_IOCTL_IDX(SIOCGIWSCAN)] = __cfg80211_wext_giwscan,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1526) [IW_IOCTL_IDX(SIOCSIWESSID)] = __cfg80211_wext_siwessid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1527) [IW_IOCTL_IDX(SIOCGIWESSID)] = __cfg80211_wext_giwessid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1528) [IW_IOCTL_IDX(SIOCSIWRATE)] = __cfg80211_wext_siwrate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1529) [IW_IOCTL_IDX(SIOCGIWRATE)] = __cfg80211_wext_giwrate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1530) [IW_IOCTL_IDX(SIOCSIWRTS)] = __cfg80211_wext_siwrts,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1531) [IW_IOCTL_IDX(SIOCGIWRTS)] = __cfg80211_wext_giwrts,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1532) [IW_IOCTL_IDX(SIOCSIWFRAG)] = __cfg80211_wext_siwfrag,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1533) [IW_IOCTL_IDX(SIOCGIWFRAG)] = __cfg80211_wext_giwfrag,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1534) [IW_IOCTL_IDX(SIOCSIWTXPOW)] = cfg80211_wext_siwtxpower,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1535) [IW_IOCTL_IDX(SIOCGIWTXPOW)] = cfg80211_wext_giwtxpower,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1536) [IW_IOCTL_IDX(SIOCSIWRETRY)] = __cfg80211_wext_siwretry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1537) [IW_IOCTL_IDX(SIOCGIWRETRY)] = __cfg80211_wext_giwretry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1538) [IW_IOCTL_IDX(SIOCSIWENCODE)] = __cfg80211_wext_siwencode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1539) [IW_IOCTL_IDX(SIOCGIWENCODE)] = __cfg80211_wext_giwencode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1540) [IW_IOCTL_IDX(SIOCSIWPOWER)] = __cfg80211_wext_siwpower,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1541) [IW_IOCTL_IDX(SIOCGIWPOWER)] = __cfg80211_wext_giwpower,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1542) [IW_IOCTL_IDX(SIOCSIWGENIE)] = __cfg80211_wext_siwgenie,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1543) [IW_IOCTL_IDX(SIOCSIWAUTH)] = __cfg80211_wext_siwauth,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1544) [IW_IOCTL_IDX(SIOCGIWAUTH)] = __cfg80211_wext_giwauth,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1545) [IW_IOCTL_IDX(SIOCSIWENCODEEXT)]= __cfg80211_wext_siwencodeext,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1546) [IW_IOCTL_IDX(SIOCSIWPMKSA)] = __cfg80211_wext_siwpmksa,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1547) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1548)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1549) const struct iw_handler_def cfg80211_wext_handler = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1550) .num_standard = ARRAY_SIZE(cfg80211_handlers),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1551) .standard = cfg80211_handlers,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1552) .get_wireless_stats = cfg80211_wireless_stats,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1553) };