Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 /*
0003  * cfg80211 - wext compat code
0004  *
0005  * This is temporary code until all wireless functionality is migrated
0006  * into cfg80211, when that happens all the exports here go away and
0007  * we directly assign the wireless handlers of wireless interfaces.
0008  *
0009  * Copyright 2008-2009  Johannes Berg <johannes@sipsolutions.net>
0010  * Copyright (C) 2019-2022 Intel Corporation
0011  */
0012 
0013 #include <linux/export.h>
0014 #include <linux/wireless.h>
0015 #include <linux/nl80211.h>
0016 #include <linux/if_arp.h>
0017 #include <linux/etherdevice.h>
0018 #include <linux/slab.h>
0019 #include <net/iw_handler.h>
0020 #include <net/cfg80211.h>
0021 #include <net/cfg80211-wext.h>
0022 #include "wext-compat.h"
0023 #include "core.h"
0024 #include "rdev-ops.h"
0025 
0026 int cfg80211_wext_giwname(struct net_device *dev,
0027               struct iw_request_info *info,
0028               char *name, char *extra)
0029 {
0030     strcpy(name, "IEEE 802.11");
0031     return 0;
0032 }
0033 EXPORT_WEXT_HANDLER(cfg80211_wext_giwname);
0034 
0035 int cfg80211_wext_siwmode(struct net_device *dev, struct iw_request_info *info,
0036               u32 *mode, char *extra)
0037 {
0038     struct wireless_dev *wdev = dev->ieee80211_ptr;
0039     struct cfg80211_registered_device *rdev;
0040     struct vif_params vifparams;
0041     enum nl80211_iftype type;
0042     int ret;
0043 
0044     rdev = wiphy_to_rdev(wdev->wiphy);
0045 
0046     switch (*mode) {
0047     case IW_MODE_INFRA:
0048         type = NL80211_IFTYPE_STATION;
0049         break;
0050     case IW_MODE_ADHOC:
0051         type = NL80211_IFTYPE_ADHOC;
0052         break;
0053     case IW_MODE_MONITOR:
0054         type = NL80211_IFTYPE_MONITOR;
0055         break;
0056     default:
0057         return -EINVAL;
0058     }
0059 
0060     if (type == wdev->iftype)
0061         return 0;
0062 
0063     memset(&vifparams, 0, sizeof(vifparams));
0064 
0065     wiphy_lock(wdev->wiphy);
0066     ret = cfg80211_change_iface(rdev, dev, type, &vifparams);
0067     wiphy_unlock(wdev->wiphy);
0068 
0069     return ret;
0070 }
0071 EXPORT_WEXT_HANDLER(cfg80211_wext_siwmode);
0072 
0073 int cfg80211_wext_giwmode(struct net_device *dev, struct iw_request_info *info,
0074               u32 *mode, char *extra)
0075 {
0076     struct wireless_dev *wdev = dev->ieee80211_ptr;
0077 
0078     if (!wdev)
0079         return -EOPNOTSUPP;
0080 
0081     switch (wdev->iftype) {
0082     case NL80211_IFTYPE_AP:
0083         *mode = IW_MODE_MASTER;
0084         break;
0085     case NL80211_IFTYPE_STATION:
0086         *mode = IW_MODE_INFRA;
0087         break;
0088     case NL80211_IFTYPE_ADHOC:
0089         *mode = IW_MODE_ADHOC;
0090         break;
0091     case NL80211_IFTYPE_MONITOR:
0092         *mode = IW_MODE_MONITOR;
0093         break;
0094     case NL80211_IFTYPE_WDS:
0095         *mode = IW_MODE_REPEAT;
0096         break;
0097     case NL80211_IFTYPE_AP_VLAN:
0098         *mode = IW_MODE_SECOND;     /* FIXME */
0099         break;
0100     default:
0101         *mode = IW_MODE_AUTO;
0102         break;
0103     }
0104     return 0;
0105 }
0106 EXPORT_WEXT_HANDLER(cfg80211_wext_giwmode);
0107 
0108 
0109 int cfg80211_wext_giwrange(struct net_device *dev,
0110                struct iw_request_info *info,
0111                struct iw_point *data, char *extra)
0112 {
0113     struct wireless_dev *wdev = dev->ieee80211_ptr;
0114     struct iw_range *range = (struct iw_range *) extra;
0115     enum nl80211_band band;
0116     int i, c = 0;
0117 
0118     if (!wdev)
0119         return -EOPNOTSUPP;
0120 
0121     data->length = sizeof(struct iw_range);
0122     memset(range, 0, sizeof(struct iw_range));
0123 
0124     range->we_version_compiled = WIRELESS_EXT;
0125     range->we_version_source = 21;
0126     range->retry_capa = IW_RETRY_LIMIT;
0127     range->retry_flags = IW_RETRY_LIMIT;
0128     range->min_retry = 0;
0129     range->max_retry = 255;
0130     range->min_rts = 0;
0131     range->max_rts = 2347;
0132     range->min_frag = 256;
0133     range->max_frag = 2346;
0134 
0135     range->max_encoding_tokens = 4;
0136 
0137     range->max_qual.updated = IW_QUAL_NOISE_INVALID;
0138 
0139     switch (wdev->wiphy->signal_type) {
0140     case CFG80211_SIGNAL_TYPE_NONE:
0141         break;
0142     case CFG80211_SIGNAL_TYPE_MBM:
0143         range->max_qual.level = (u8)-110;
0144         range->max_qual.qual = 70;
0145         range->avg_qual.qual = 35;
0146         range->max_qual.updated |= IW_QUAL_DBM;
0147         range->max_qual.updated |= IW_QUAL_QUAL_UPDATED;
0148         range->max_qual.updated |= IW_QUAL_LEVEL_UPDATED;
0149         break;
0150     case CFG80211_SIGNAL_TYPE_UNSPEC:
0151         range->max_qual.level = 100;
0152         range->max_qual.qual = 100;
0153         range->avg_qual.qual = 50;
0154         range->max_qual.updated |= IW_QUAL_QUAL_UPDATED;
0155         range->max_qual.updated |= IW_QUAL_LEVEL_UPDATED;
0156         break;
0157     }
0158 
0159     range->avg_qual.level = range->max_qual.level / 2;
0160     range->avg_qual.noise = range->max_qual.noise / 2;
0161     range->avg_qual.updated = range->max_qual.updated;
0162 
0163     for (i = 0; i < wdev->wiphy->n_cipher_suites; i++) {
0164         switch (wdev->wiphy->cipher_suites[i]) {
0165         case WLAN_CIPHER_SUITE_TKIP:
0166             range->enc_capa |= (IW_ENC_CAPA_CIPHER_TKIP |
0167                         IW_ENC_CAPA_WPA);
0168             break;
0169 
0170         case WLAN_CIPHER_SUITE_CCMP:
0171             range->enc_capa |= (IW_ENC_CAPA_CIPHER_CCMP |
0172                         IW_ENC_CAPA_WPA2);
0173             break;
0174 
0175         case WLAN_CIPHER_SUITE_WEP40:
0176             range->encoding_size[range->num_encoding_sizes++] =
0177                 WLAN_KEY_LEN_WEP40;
0178             break;
0179 
0180         case WLAN_CIPHER_SUITE_WEP104:
0181             range->encoding_size[range->num_encoding_sizes++] =
0182                 WLAN_KEY_LEN_WEP104;
0183             break;
0184         }
0185     }
0186 
0187     for (band = 0; band < NUM_NL80211_BANDS; band ++) {
0188         struct ieee80211_supported_band *sband;
0189 
0190         sband = wdev->wiphy->bands[band];
0191 
0192         if (!sband)
0193             continue;
0194 
0195         for (i = 0; i < sband->n_channels && c < IW_MAX_FREQUENCIES; i++) {
0196             struct ieee80211_channel *chan = &sband->channels[i];
0197 
0198             if (!(chan->flags & IEEE80211_CHAN_DISABLED)) {
0199                 range->freq[c].i =
0200                     ieee80211_frequency_to_channel(
0201                         chan->center_freq);
0202                 range->freq[c].m = chan->center_freq;
0203                 range->freq[c].e = 6;
0204                 c++;
0205             }
0206         }
0207     }
0208     range->num_channels = c;
0209     range->num_frequency = c;
0210 
0211     IW_EVENT_CAPA_SET_KERNEL(range->event_capa);
0212     IW_EVENT_CAPA_SET(range->event_capa, SIOCGIWAP);
0213     IW_EVENT_CAPA_SET(range->event_capa, SIOCGIWSCAN);
0214 
0215     if (wdev->wiphy->max_scan_ssids > 0)
0216         range->scan_capa |= IW_SCAN_CAPA_ESSID;
0217 
0218     return 0;
0219 }
0220 EXPORT_WEXT_HANDLER(cfg80211_wext_giwrange);
0221 
0222 
0223 /**
0224  * cfg80211_wext_freq - get wext frequency for non-"auto"
0225  * @freq: the wext freq encoding
0226  *
0227  * Returns a frequency, or a negative error code, or 0 for auto.
0228  */
0229 int cfg80211_wext_freq(struct iw_freq *freq)
0230 {
0231     /*
0232      * Parse frequency - return 0 for auto and
0233      * -EINVAL for impossible things.
0234      */
0235     if (freq->e == 0) {
0236         enum nl80211_band band = NL80211_BAND_2GHZ;
0237         if (freq->m < 0)
0238             return 0;
0239         if (freq->m > 14)
0240             band = NL80211_BAND_5GHZ;
0241         return ieee80211_channel_to_frequency(freq->m, band);
0242     } else {
0243         int i, div = 1000000;
0244         for (i = 0; i < freq->e; i++)
0245             div /= 10;
0246         if (div <= 0)
0247             return -EINVAL;
0248         return freq->m / div;
0249     }
0250 }
0251 
0252 int cfg80211_wext_siwrts(struct net_device *dev,
0253              struct iw_request_info *info,
0254              struct iw_param *rts, char *extra)
0255 {
0256     struct wireless_dev *wdev = dev->ieee80211_ptr;
0257     struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
0258     u32 orts = wdev->wiphy->rts_threshold;
0259     int err;
0260 
0261     wiphy_lock(&rdev->wiphy);
0262     if (rts->disabled || !rts->fixed) {
0263         wdev->wiphy->rts_threshold = (u32) -1;
0264     } else if (rts->value < 0) {
0265         err = -EINVAL;
0266         goto out;
0267     } else {
0268         wdev->wiphy->rts_threshold = rts->value;
0269     }
0270 
0271     err = rdev_set_wiphy_params(rdev, WIPHY_PARAM_RTS_THRESHOLD);
0272 
0273     if (err)
0274         wdev->wiphy->rts_threshold = orts;
0275 
0276 out:
0277     wiphy_unlock(&rdev->wiphy);
0278     return err;
0279 }
0280 EXPORT_WEXT_HANDLER(cfg80211_wext_siwrts);
0281 
0282 int cfg80211_wext_giwrts(struct net_device *dev,
0283              struct iw_request_info *info,
0284              struct iw_param *rts, char *extra)
0285 {
0286     struct wireless_dev *wdev = dev->ieee80211_ptr;
0287 
0288     rts->value = wdev->wiphy->rts_threshold;
0289     rts->disabled = rts->value == (u32) -1;
0290     rts->fixed = 1;
0291 
0292     return 0;
0293 }
0294 EXPORT_WEXT_HANDLER(cfg80211_wext_giwrts);
0295 
0296 int cfg80211_wext_siwfrag(struct net_device *dev,
0297               struct iw_request_info *info,
0298               struct iw_param *frag, char *extra)
0299 {
0300     struct wireless_dev *wdev = dev->ieee80211_ptr;
0301     struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
0302     u32 ofrag = wdev->wiphy->frag_threshold;
0303     int err;
0304 
0305     wiphy_lock(&rdev->wiphy);
0306     if (frag->disabled || !frag->fixed) {
0307         wdev->wiphy->frag_threshold = (u32) -1;
0308     } else if (frag->value < 256) {
0309         err = -EINVAL;
0310         goto out;
0311     } else {
0312         /* Fragment length must be even, so strip LSB. */
0313         wdev->wiphy->frag_threshold = frag->value & ~0x1;
0314     }
0315 
0316     err = rdev_set_wiphy_params(rdev, WIPHY_PARAM_FRAG_THRESHOLD);
0317     if (err)
0318         wdev->wiphy->frag_threshold = ofrag;
0319 out:
0320     wiphy_unlock(&rdev->wiphy);
0321 
0322     return err;
0323 }
0324 EXPORT_WEXT_HANDLER(cfg80211_wext_siwfrag);
0325 
0326 int cfg80211_wext_giwfrag(struct net_device *dev,
0327               struct iw_request_info *info,
0328               struct iw_param *frag, char *extra)
0329 {
0330     struct wireless_dev *wdev = dev->ieee80211_ptr;
0331 
0332     frag->value = wdev->wiphy->frag_threshold;
0333     frag->disabled = frag->value == (u32) -1;
0334     frag->fixed = 1;
0335 
0336     return 0;
0337 }
0338 EXPORT_WEXT_HANDLER(cfg80211_wext_giwfrag);
0339 
0340 static int cfg80211_wext_siwretry(struct net_device *dev,
0341                   struct iw_request_info *info,
0342                   struct iw_param *retry, char *extra)
0343 {
0344     struct wireless_dev *wdev = dev->ieee80211_ptr;
0345     struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
0346     u32 changed = 0;
0347     u8 olong = wdev->wiphy->retry_long;
0348     u8 oshort = wdev->wiphy->retry_short;
0349     int err;
0350 
0351     if (retry->disabled || retry->value < 1 || retry->value > 255 ||
0352         (retry->flags & IW_RETRY_TYPE) != IW_RETRY_LIMIT)
0353         return -EINVAL;
0354 
0355     wiphy_lock(&rdev->wiphy);
0356     if (retry->flags & IW_RETRY_LONG) {
0357         wdev->wiphy->retry_long = retry->value;
0358         changed |= WIPHY_PARAM_RETRY_LONG;
0359     } else if (retry->flags & IW_RETRY_SHORT) {
0360         wdev->wiphy->retry_short = retry->value;
0361         changed |= WIPHY_PARAM_RETRY_SHORT;
0362     } else {
0363         wdev->wiphy->retry_short = retry->value;
0364         wdev->wiphy->retry_long = retry->value;
0365         changed |= WIPHY_PARAM_RETRY_LONG;
0366         changed |= WIPHY_PARAM_RETRY_SHORT;
0367     }
0368 
0369     err = rdev_set_wiphy_params(rdev, changed);
0370     if (err) {
0371         wdev->wiphy->retry_short = oshort;
0372         wdev->wiphy->retry_long = olong;
0373     }
0374     wiphy_unlock(&rdev->wiphy);
0375 
0376     return err;
0377 }
0378 
0379 int cfg80211_wext_giwretry(struct net_device *dev,
0380                struct iw_request_info *info,
0381                struct iw_param *retry, char *extra)
0382 {
0383     struct wireless_dev *wdev = dev->ieee80211_ptr;
0384 
0385     retry->disabled = 0;
0386 
0387     if (retry->flags == 0 || (retry->flags & IW_RETRY_SHORT)) {
0388         /*
0389          * First return short value, iwconfig will ask long value
0390          * later if needed
0391          */
0392         retry->flags |= IW_RETRY_LIMIT | IW_RETRY_SHORT;
0393         retry->value = wdev->wiphy->retry_short;
0394         if (wdev->wiphy->retry_long == wdev->wiphy->retry_short)
0395             retry->flags |= IW_RETRY_LONG;
0396 
0397         return 0;
0398     }
0399 
0400     if (retry->flags & IW_RETRY_LONG) {
0401         retry->flags = IW_RETRY_LIMIT | IW_RETRY_LONG;
0402         retry->value = wdev->wiphy->retry_long;
0403     }
0404 
0405     return 0;
0406 }
0407 EXPORT_WEXT_HANDLER(cfg80211_wext_giwretry);
0408 
0409 static int __cfg80211_set_encryption(struct cfg80211_registered_device *rdev,
0410                      struct net_device *dev, bool pairwise,
0411                      const u8 *addr, bool remove, bool tx_key,
0412                      int idx, struct key_params *params)
0413 {
0414     struct wireless_dev *wdev = dev->ieee80211_ptr;
0415     int err, i;
0416     bool rejoin = false;
0417 
0418     if (wdev->valid_links)
0419         return -EINVAL;
0420 
0421     if (pairwise && !addr)
0422         return -EINVAL;
0423 
0424     /*
0425      * In many cases we won't actually need this, but it's better
0426      * to do it first in case the allocation fails. Don't use wext.
0427      */
0428     if (!wdev->wext.keys) {
0429         wdev->wext.keys = kzalloc(sizeof(*wdev->wext.keys),
0430                       GFP_KERNEL);
0431         if (!wdev->wext.keys)
0432             return -ENOMEM;
0433         for (i = 0; i < CFG80211_MAX_WEP_KEYS; i++)
0434             wdev->wext.keys->params[i].key =
0435                 wdev->wext.keys->data[i];
0436     }
0437 
0438     if (wdev->iftype != NL80211_IFTYPE_ADHOC &&
0439         wdev->iftype != NL80211_IFTYPE_STATION)
0440         return -EOPNOTSUPP;
0441 
0442     if (params->cipher == WLAN_CIPHER_SUITE_AES_CMAC) {
0443         if (!wdev->connected)
0444             return -ENOLINK;
0445 
0446         if (!rdev->ops->set_default_mgmt_key)
0447             return -EOPNOTSUPP;
0448 
0449         if (idx < 4 || idx > 5)
0450             return -EINVAL;
0451     } else if (idx < 0 || idx > 3)
0452         return -EINVAL;
0453 
0454     if (remove) {
0455         err = 0;
0456         if (wdev->connected ||
0457             (wdev->iftype == NL80211_IFTYPE_ADHOC &&
0458              wdev->u.ibss.current_bss)) {
0459             /*
0460              * If removing the current TX key, we will need to
0461              * join a new IBSS without the privacy bit clear.
0462              */
0463             if (idx == wdev->wext.default_key &&
0464                 wdev->iftype == NL80211_IFTYPE_ADHOC) {
0465                 __cfg80211_leave_ibss(rdev, wdev->netdev, true);
0466                 rejoin = true;
0467             }
0468 
0469             if (!pairwise && addr &&
0470                 !(rdev->wiphy.flags & WIPHY_FLAG_IBSS_RSN))
0471                 err = -ENOENT;
0472             else
0473                 err = rdev_del_key(rdev, dev, idx, pairwise,
0474                            addr);
0475         }
0476         wdev->wext.connect.privacy = false;
0477         /*
0478          * Applications using wireless extensions expect to be
0479          * able to delete keys that don't exist, so allow that.
0480          */
0481         if (err == -ENOENT)
0482             err = 0;
0483         if (!err) {
0484             if (!addr && idx < 4) {
0485                 memset(wdev->wext.keys->data[idx], 0,
0486                        sizeof(wdev->wext.keys->data[idx]));
0487                 wdev->wext.keys->params[idx].key_len = 0;
0488                 wdev->wext.keys->params[idx].cipher = 0;
0489             }
0490             if (idx == wdev->wext.default_key)
0491                 wdev->wext.default_key = -1;
0492             else if (idx == wdev->wext.default_mgmt_key)
0493                 wdev->wext.default_mgmt_key = -1;
0494         }
0495 
0496         if (!err && rejoin)
0497             err = cfg80211_ibss_wext_join(rdev, wdev);
0498 
0499         return err;
0500     }
0501 
0502     if (addr)
0503         tx_key = false;
0504 
0505     if (cfg80211_validate_key_settings(rdev, params, idx, pairwise, addr))
0506         return -EINVAL;
0507 
0508     err = 0;
0509     if (wdev->connected ||
0510         (wdev->iftype == NL80211_IFTYPE_ADHOC &&
0511          wdev->u.ibss.current_bss))
0512         err = rdev_add_key(rdev, dev, idx, pairwise, addr, params);
0513     else if (params->cipher != WLAN_CIPHER_SUITE_WEP40 &&
0514          params->cipher != WLAN_CIPHER_SUITE_WEP104)
0515         return -EINVAL;
0516     if (err)
0517         return err;
0518 
0519     /*
0520      * We only need to store WEP keys, since they're the only keys that
0521      * can be set before a connection is established and persist after
0522      * disconnecting.
0523      */
0524     if (!addr && (params->cipher == WLAN_CIPHER_SUITE_WEP40 ||
0525               params->cipher == WLAN_CIPHER_SUITE_WEP104)) {
0526         wdev->wext.keys->params[idx] = *params;
0527         memcpy(wdev->wext.keys->data[idx],
0528             params->key, params->key_len);
0529         wdev->wext.keys->params[idx].key =
0530             wdev->wext.keys->data[idx];
0531     }
0532 
0533     if ((params->cipher == WLAN_CIPHER_SUITE_WEP40 ||
0534          params->cipher == WLAN_CIPHER_SUITE_WEP104) &&
0535         (tx_key || (!addr && wdev->wext.default_key == -1))) {
0536         if (wdev->connected ||
0537             (wdev->iftype == NL80211_IFTYPE_ADHOC &&
0538              wdev->u.ibss.current_bss)) {
0539             /*
0540              * If we are getting a new TX key from not having
0541              * had one before we need to join a new IBSS with
0542              * the privacy bit set.
0543              */
0544             if (wdev->iftype == NL80211_IFTYPE_ADHOC &&
0545                 wdev->wext.default_key == -1) {
0546                 __cfg80211_leave_ibss(rdev, wdev->netdev, true);
0547                 rejoin = true;
0548             }
0549             err = rdev_set_default_key(rdev, dev, idx, true, true);
0550         }
0551         if (!err) {
0552             wdev->wext.default_key = idx;
0553             if (rejoin)
0554                 err = cfg80211_ibss_wext_join(rdev, wdev);
0555         }
0556         return err;
0557     }
0558 
0559     if (params->cipher == WLAN_CIPHER_SUITE_AES_CMAC &&
0560         (tx_key || (!addr && wdev->wext.default_mgmt_key == -1))) {
0561         if (wdev->connected ||
0562             (wdev->iftype == NL80211_IFTYPE_ADHOC &&
0563              wdev->u.ibss.current_bss))
0564             err = rdev_set_default_mgmt_key(rdev, dev, idx);
0565         if (!err)
0566             wdev->wext.default_mgmt_key = idx;
0567         return err;
0568     }
0569 
0570     return 0;
0571 }
0572 
0573 static int cfg80211_set_encryption(struct cfg80211_registered_device *rdev,
0574                    struct net_device *dev, bool pairwise,
0575                    const u8 *addr, bool remove, bool tx_key,
0576                    int idx, struct key_params *params)
0577 {
0578     int err;
0579 
0580     wdev_lock(dev->ieee80211_ptr);
0581     err = __cfg80211_set_encryption(rdev, dev, pairwise, addr,
0582                     remove, tx_key, idx, params);
0583     wdev_unlock(dev->ieee80211_ptr);
0584 
0585     return err;
0586 }
0587 
0588 static int cfg80211_wext_siwencode(struct net_device *dev,
0589                    struct iw_request_info *info,
0590                    struct iw_point *erq, char *keybuf)
0591 {
0592     struct wireless_dev *wdev = dev->ieee80211_ptr;
0593     struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
0594     int idx, err;
0595     bool remove = false;
0596     struct key_params params;
0597 
0598     if (wdev->iftype != NL80211_IFTYPE_STATION &&
0599         wdev->iftype != NL80211_IFTYPE_ADHOC)
0600         return -EOPNOTSUPP;
0601 
0602     /* no use -- only MFP (set_default_mgmt_key) is optional */
0603     if (!rdev->ops->del_key ||
0604         !rdev->ops->add_key ||
0605         !rdev->ops->set_default_key)
0606         return -EOPNOTSUPP;
0607 
0608     wiphy_lock(&rdev->wiphy);
0609     if (wdev->valid_links) {
0610         err = -EOPNOTSUPP;
0611         goto out;
0612     }
0613 
0614     idx = erq->flags & IW_ENCODE_INDEX;
0615     if (idx == 0) {
0616         idx = wdev->wext.default_key;
0617         if (idx < 0)
0618             idx = 0;
0619     } else if (idx < 1 || idx > 4) {
0620         err = -EINVAL;
0621         goto out;
0622     } else {
0623         idx--;
0624     }
0625 
0626     if (erq->flags & IW_ENCODE_DISABLED)
0627         remove = true;
0628     else if (erq->length == 0) {
0629         /* No key data - just set the default TX key index */
0630         err = 0;
0631         wdev_lock(wdev);
0632         if (wdev->connected ||
0633             (wdev->iftype == NL80211_IFTYPE_ADHOC &&
0634              wdev->u.ibss.current_bss))
0635             err = rdev_set_default_key(rdev, dev, idx, true,
0636                            true);
0637         if (!err)
0638             wdev->wext.default_key = idx;
0639         wdev_unlock(wdev);
0640         goto out;
0641     }
0642 
0643     memset(&params, 0, sizeof(params));
0644     params.key = keybuf;
0645     params.key_len = erq->length;
0646     if (erq->length == 5) {
0647         params.cipher = WLAN_CIPHER_SUITE_WEP40;
0648     } else if (erq->length == 13) {
0649         params.cipher = WLAN_CIPHER_SUITE_WEP104;
0650     } else if (!remove) {
0651         err = -EINVAL;
0652         goto out;
0653     }
0654 
0655     err = cfg80211_set_encryption(rdev, dev, false, NULL, remove,
0656                       wdev->wext.default_key == -1,
0657                       idx, &params);
0658 out:
0659     wiphy_unlock(&rdev->wiphy);
0660 
0661     return err;
0662 }
0663 
0664 static int cfg80211_wext_siwencodeext(struct net_device *dev,
0665                       struct iw_request_info *info,
0666                       struct iw_point *erq, char *extra)
0667 {
0668     struct wireless_dev *wdev = dev->ieee80211_ptr;
0669     struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
0670     struct iw_encode_ext *ext = (struct iw_encode_ext *) extra;
0671     const u8 *addr;
0672     int idx;
0673     bool remove = false;
0674     struct key_params params;
0675     u32 cipher;
0676     int ret;
0677 
0678     if (wdev->iftype != NL80211_IFTYPE_STATION &&
0679         wdev->iftype != NL80211_IFTYPE_ADHOC)
0680         return -EOPNOTSUPP;
0681 
0682     /* no use -- only MFP (set_default_mgmt_key) is optional */
0683     if (!rdev->ops->del_key ||
0684         !rdev->ops->add_key ||
0685         !rdev->ops->set_default_key)
0686         return -EOPNOTSUPP;
0687 
0688     switch (ext->alg) {
0689     case IW_ENCODE_ALG_NONE:
0690         remove = true;
0691         cipher = 0;
0692         break;
0693     case IW_ENCODE_ALG_WEP:
0694         if (ext->key_len == 5)
0695             cipher = WLAN_CIPHER_SUITE_WEP40;
0696         else if (ext->key_len == 13)
0697             cipher = WLAN_CIPHER_SUITE_WEP104;
0698         else
0699             return -EINVAL;
0700         break;
0701     case IW_ENCODE_ALG_TKIP:
0702         cipher = WLAN_CIPHER_SUITE_TKIP;
0703         break;
0704     case IW_ENCODE_ALG_CCMP:
0705         cipher = WLAN_CIPHER_SUITE_CCMP;
0706         break;
0707     case IW_ENCODE_ALG_AES_CMAC:
0708         cipher = WLAN_CIPHER_SUITE_AES_CMAC;
0709         break;
0710     default:
0711         return -EOPNOTSUPP;
0712     }
0713 
0714     if (erq->flags & IW_ENCODE_DISABLED)
0715         remove = true;
0716 
0717     idx = erq->flags & IW_ENCODE_INDEX;
0718     if (cipher == WLAN_CIPHER_SUITE_AES_CMAC) {
0719         if (idx < 4 || idx > 5) {
0720             idx = wdev->wext.default_mgmt_key;
0721             if (idx < 0)
0722                 return -EINVAL;
0723         } else
0724             idx--;
0725     } else {
0726         if (idx < 1 || idx > 4) {
0727             idx = wdev->wext.default_key;
0728             if (idx < 0)
0729                 return -EINVAL;
0730         } else
0731             idx--;
0732     }
0733 
0734     addr = ext->addr.sa_data;
0735     if (is_broadcast_ether_addr(addr))
0736         addr = NULL;
0737 
0738     memset(&params, 0, sizeof(params));
0739     params.key = ext->key;
0740     params.key_len = ext->key_len;
0741     params.cipher = cipher;
0742 
0743     if (ext->ext_flags & IW_ENCODE_EXT_RX_SEQ_VALID) {
0744         params.seq = ext->rx_seq;
0745         params.seq_len = 6;
0746     }
0747 
0748     wiphy_lock(wdev->wiphy);
0749     ret = cfg80211_set_encryption(
0750             rdev, dev,
0751             !(ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY),
0752             addr, remove,
0753             ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY,
0754             idx, &params);
0755     wiphy_unlock(wdev->wiphy);
0756 
0757     return ret;
0758 }
0759 
0760 static int cfg80211_wext_giwencode(struct net_device *dev,
0761                    struct iw_request_info *info,
0762                    struct iw_point *erq, char *keybuf)
0763 {
0764     struct wireless_dev *wdev = dev->ieee80211_ptr;
0765     int idx;
0766 
0767     if (wdev->iftype != NL80211_IFTYPE_STATION &&
0768         wdev->iftype != NL80211_IFTYPE_ADHOC)
0769         return -EOPNOTSUPP;
0770 
0771     idx = erq->flags & IW_ENCODE_INDEX;
0772     if (idx == 0) {
0773         idx = wdev->wext.default_key;
0774         if (idx < 0)
0775             idx = 0;
0776     } else if (idx < 1 || idx > 4)
0777         return -EINVAL;
0778     else
0779         idx--;
0780 
0781     erq->flags = idx + 1;
0782 
0783     if (!wdev->wext.keys || !wdev->wext.keys->params[idx].cipher) {
0784         erq->flags |= IW_ENCODE_DISABLED;
0785         erq->length = 0;
0786         return 0;
0787     }
0788 
0789     erq->length = min_t(size_t, erq->length,
0790                 wdev->wext.keys->params[idx].key_len);
0791     memcpy(keybuf, wdev->wext.keys->params[idx].key, erq->length);
0792     erq->flags |= IW_ENCODE_ENABLED;
0793 
0794     return 0;
0795 }
0796 
0797 static int cfg80211_wext_siwfreq(struct net_device *dev,
0798                  struct iw_request_info *info,
0799                  struct iw_freq *wextfreq, char *extra)
0800 {
0801     struct wireless_dev *wdev = dev->ieee80211_ptr;
0802     struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
0803     struct cfg80211_chan_def chandef = {
0804         .width = NL80211_CHAN_WIDTH_20_NOHT,
0805     };
0806     int freq, ret;
0807 
0808     wiphy_lock(&rdev->wiphy);
0809 
0810     switch (wdev->iftype) {
0811     case NL80211_IFTYPE_STATION:
0812         ret = cfg80211_mgd_wext_siwfreq(dev, info, wextfreq, extra);
0813         break;
0814     case NL80211_IFTYPE_ADHOC:
0815         ret = cfg80211_ibss_wext_siwfreq(dev, info, wextfreq, extra);
0816         break;
0817     case NL80211_IFTYPE_MONITOR:
0818         freq = cfg80211_wext_freq(wextfreq);
0819         if (freq < 0) {
0820             ret = freq;
0821             break;
0822         }
0823         if (freq == 0) {
0824             ret = -EINVAL;
0825             break;
0826         }
0827         chandef.center_freq1 = freq;
0828         chandef.chan = ieee80211_get_channel(&rdev->wiphy, freq);
0829         if (!chandef.chan) {
0830             ret = -EINVAL;
0831             break;
0832         }
0833         ret = cfg80211_set_monitor_channel(rdev, &chandef);
0834         break;
0835     case NL80211_IFTYPE_MESH_POINT:
0836         freq = cfg80211_wext_freq(wextfreq);
0837         if (freq < 0) {
0838             ret = freq;
0839             break;
0840         }
0841         if (freq == 0) {
0842             ret = -EINVAL;
0843             break;
0844         }
0845         chandef.center_freq1 = freq;
0846         chandef.chan = ieee80211_get_channel(&rdev->wiphy, freq);
0847         if (!chandef.chan) {
0848             ret = -EINVAL;
0849             break;
0850         }
0851         ret = cfg80211_set_mesh_channel(rdev, wdev, &chandef);
0852         break;
0853     default:
0854         ret = -EOPNOTSUPP;
0855         break;
0856     }
0857 
0858     wiphy_unlock(&rdev->wiphy);
0859 
0860     return ret;
0861 }
0862 
0863 static int cfg80211_wext_giwfreq(struct net_device *dev,
0864                  struct iw_request_info *info,
0865                  struct iw_freq *freq, char *extra)
0866 {
0867     struct wireless_dev *wdev = dev->ieee80211_ptr;
0868     struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
0869     struct cfg80211_chan_def chandef = {};
0870     int ret;
0871 
0872     wiphy_lock(&rdev->wiphy);
0873     switch (wdev->iftype) {
0874     case NL80211_IFTYPE_STATION:
0875         ret = cfg80211_mgd_wext_giwfreq(dev, info, freq, extra);
0876         break;
0877     case NL80211_IFTYPE_ADHOC:
0878         ret = cfg80211_ibss_wext_giwfreq(dev, info, freq, extra);
0879         break;
0880     case NL80211_IFTYPE_MONITOR:
0881         if (!rdev->ops->get_channel) {
0882             ret = -EINVAL;
0883             break;
0884         }
0885 
0886         ret = rdev_get_channel(rdev, wdev, 0, &chandef);
0887         if (ret)
0888             break;
0889         freq->m = chandef.chan->center_freq;
0890         freq->e = 6;
0891         ret = 0;
0892         break;
0893     default:
0894         ret = -EINVAL;
0895         break;
0896     }
0897 
0898     wiphy_unlock(&rdev->wiphy);
0899 
0900     return ret;
0901 }
0902 
0903 static int cfg80211_wext_siwtxpower(struct net_device *dev,
0904                     struct iw_request_info *info,
0905                     union iwreq_data *data, char *extra)
0906 {
0907     struct wireless_dev *wdev = dev->ieee80211_ptr;
0908     struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
0909     enum nl80211_tx_power_setting type;
0910     int dbm = 0;
0911     int ret;
0912 
0913     if ((data->txpower.flags & IW_TXPOW_TYPE) != IW_TXPOW_DBM)
0914         return -EINVAL;
0915     if (data->txpower.flags & IW_TXPOW_RANGE)
0916         return -EINVAL;
0917 
0918     if (!rdev->ops->set_tx_power)
0919         return -EOPNOTSUPP;
0920 
0921     /* only change when not disabling */
0922     if (!data->txpower.disabled) {
0923         rfkill_set_sw_state(rdev->wiphy.rfkill, false);
0924 
0925         if (data->txpower.fixed) {
0926             /*
0927              * wext doesn't support negative values, see
0928              * below where it's for automatic
0929              */
0930             if (data->txpower.value < 0)
0931                 return -EINVAL;
0932             dbm = data->txpower.value;
0933             type = NL80211_TX_POWER_FIXED;
0934             /* TODO: do regulatory check! */
0935         } else {
0936             /*
0937              * Automatic power level setting, max being the value
0938              * passed in from userland.
0939              */
0940             if (data->txpower.value < 0) {
0941                 type = NL80211_TX_POWER_AUTOMATIC;
0942             } else {
0943                 dbm = data->txpower.value;
0944                 type = NL80211_TX_POWER_LIMITED;
0945             }
0946         }
0947     } else {
0948         if (rfkill_set_sw_state(rdev->wiphy.rfkill, true))
0949             schedule_work(&rdev->rfkill_block);
0950         return 0;
0951     }
0952 
0953     wiphy_lock(&rdev->wiphy);
0954     ret = rdev_set_tx_power(rdev, wdev, type, DBM_TO_MBM(dbm));
0955     wiphy_unlock(&rdev->wiphy);
0956 
0957     return ret;
0958 }
0959 
0960 static int cfg80211_wext_giwtxpower(struct net_device *dev,
0961                     struct iw_request_info *info,
0962                     union iwreq_data *data, char *extra)
0963 {
0964     struct wireless_dev *wdev = dev->ieee80211_ptr;
0965     struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
0966     int err, val;
0967 
0968     if ((data->txpower.flags & IW_TXPOW_TYPE) != IW_TXPOW_DBM)
0969         return -EINVAL;
0970     if (data->txpower.flags & IW_TXPOW_RANGE)
0971         return -EINVAL;
0972 
0973     if (!rdev->ops->get_tx_power)
0974         return -EOPNOTSUPP;
0975 
0976     wiphy_lock(&rdev->wiphy);
0977     err = rdev_get_tx_power(rdev, wdev, &val);
0978     wiphy_unlock(&rdev->wiphy);
0979     if (err)
0980         return err;
0981 
0982     /* well... oh well */
0983     data->txpower.fixed = 1;
0984     data->txpower.disabled = rfkill_blocked(rdev->wiphy.rfkill);
0985     data->txpower.value = val;
0986     data->txpower.flags = IW_TXPOW_DBM;
0987 
0988     return 0;
0989 }
0990 
0991 static int cfg80211_set_auth_alg(struct wireless_dev *wdev,
0992                  s32 auth_alg)
0993 {
0994     int nr_alg = 0;
0995 
0996     if (!auth_alg)
0997         return -EINVAL;
0998 
0999     if (auth_alg & ~(IW_AUTH_ALG_OPEN_SYSTEM |
1000              IW_AUTH_ALG_SHARED_KEY |
1001              IW_AUTH_ALG_LEAP))
1002         return -EINVAL;
1003 
1004     if (auth_alg & IW_AUTH_ALG_OPEN_SYSTEM) {
1005         nr_alg++;
1006         wdev->wext.connect.auth_type = NL80211_AUTHTYPE_OPEN_SYSTEM;
1007     }
1008 
1009     if (auth_alg & IW_AUTH_ALG_SHARED_KEY) {
1010         nr_alg++;
1011         wdev->wext.connect.auth_type = NL80211_AUTHTYPE_SHARED_KEY;
1012     }
1013 
1014     if (auth_alg & IW_AUTH_ALG_LEAP) {
1015         nr_alg++;
1016         wdev->wext.connect.auth_type = NL80211_AUTHTYPE_NETWORK_EAP;
1017     }
1018 
1019     if (nr_alg > 1)
1020         wdev->wext.connect.auth_type = NL80211_AUTHTYPE_AUTOMATIC;
1021 
1022     return 0;
1023 }
1024 
1025 static int cfg80211_set_wpa_version(struct wireless_dev *wdev, u32 wpa_versions)
1026 {
1027     if (wpa_versions & ~(IW_AUTH_WPA_VERSION_WPA |
1028                  IW_AUTH_WPA_VERSION_WPA2|
1029                      IW_AUTH_WPA_VERSION_DISABLED))
1030         return -EINVAL;
1031 
1032     if ((wpa_versions & IW_AUTH_WPA_VERSION_DISABLED) &&
1033         (wpa_versions & (IW_AUTH_WPA_VERSION_WPA|
1034                  IW_AUTH_WPA_VERSION_WPA2)))
1035         return -EINVAL;
1036 
1037     if (wpa_versions & IW_AUTH_WPA_VERSION_DISABLED)
1038         wdev->wext.connect.crypto.wpa_versions &=
1039             ~(NL80211_WPA_VERSION_1|NL80211_WPA_VERSION_2);
1040 
1041     if (wpa_versions & IW_AUTH_WPA_VERSION_WPA)
1042         wdev->wext.connect.crypto.wpa_versions |=
1043             NL80211_WPA_VERSION_1;
1044 
1045     if (wpa_versions & IW_AUTH_WPA_VERSION_WPA2)
1046         wdev->wext.connect.crypto.wpa_versions |=
1047             NL80211_WPA_VERSION_2;
1048 
1049     return 0;
1050 }
1051 
1052 static int cfg80211_set_cipher_group(struct wireless_dev *wdev, u32 cipher)
1053 {
1054     if (cipher & IW_AUTH_CIPHER_WEP40)
1055         wdev->wext.connect.crypto.cipher_group =
1056             WLAN_CIPHER_SUITE_WEP40;
1057     else if (cipher & IW_AUTH_CIPHER_WEP104)
1058         wdev->wext.connect.crypto.cipher_group =
1059             WLAN_CIPHER_SUITE_WEP104;
1060     else if (cipher & IW_AUTH_CIPHER_TKIP)
1061         wdev->wext.connect.crypto.cipher_group =
1062             WLAN_CIPHER_SUITE_TKIP;
1063     else if (cipher & IW_AUTH_CIPHER_CCMP)
1064         wdev->wext.connect.crypto.cipher_group =
1065             WLAN_CIPHER_SUITE_CCMP;
1066     else if (cipher & IW_AUTH_CIPHER_AES_CMAC)
1067         wdev->wext.connect.crypto.cipher_group =
1068             WLAN_CIPHER_SUITE_AES_CMAC;
1069     else if (cipher & IW_AUTH_CIPHER_NONE)
1070         wdev->wext.connect.crypto.cipher_group = 0;
1071     else
1072         return -EINVAL;
1073 
1074     return 0;
1075 }
1076 
1077 static int cfg80211_set_cipher_pairwise(struct wireless_dev *wdev, u32 cipher)
1078 {
1079     int nr_ciphers = 0;
1080     u32 *ciphers_pairwise = wdev->wext.connect.crypto.ciphers_pairwise;
1081 
1082     if (cipher & IW_AUTH_CIPHER_WEP40) {
1083         ciphers_pairwise[nr_ciphers] = WLAN_CIPHER_SUITE_WEP40;
1084         nr_ciphers++;
1085     }
1086 
1087     if (cipher & IW_AUTH_CIPHER_WEP104) {
1088         ciphers_pairwise[nr_ciphers] = WLAN_CIPHER_SUITE_WEP104;
1089         nr_ciphers++;
1090     }
1091 
1092     if (cipher & IW_AUTH_CIPHER_TKIP) {
1093         ciphers_pairwise[nr_ciphers] = WLAN_CIPHER_SUITE_TKIP;
1094         nr_ciphers++;
1095     }
1096 
1097     if (cipher & IW_AUTH_CIPHER_CCMP) {
1098         ciphers_pairwise[nr_ciphers] = WLAN_CIPHER_SUITE_CCMP;
1099         nr_ciphers++;
1100     }
1101 
1102     if (cipher & IW_AUTH_CIPHER_AES_CMAC) {
1103         ciphers_pairwise[nr_ciphers] = WLAN_CIPHER_SUITE_AES_CMAC;
1104         nr_ciphers++;
1105     }
1106 
1107     BUILD_BUG_ON(NL80211_MAX_NR_CIPHER_SUITES < 5);
1108 
1109     wdev->wext.connect.crypto.n_ciphers_pairwise = nr_ciphers;
1110 
1111     return 0;
1112 }
1113 
1114 
1115 static int cfg80211_set_key_mgt(struct wireless_dev *wdev, u32 key_mgt)
1116 {
1117     int nr_akm_suites = 0;
1118 
1119     if (key_mgt & ~(IW_AUTH_KEY_MGMT_802_1X |
1120             IW_AUTH_KEY_MGMT_PSK))
1121         return -EINVAL;
1122 
1123     if (key_mgt & IW_AUTH_KEY_MGMT_802_1X) {
1124         wdev->wext.connect.crypto.akm_suites[nr_akm_suites] =
1125             WLAN_AKM_SUITE_8021X;
1126         nr_akm_suites++;
1127     }
1128 
1129     if (key_mgt & IW_AUTH_KEY_MGMT_PSK) {
1130         wdev->wext.connect.crypto.akm_suites[nr_akm_suites] =
1131             WLAN_AKM_SUITE_PSK;
1132         nr_akm_suites++;
1133     }
1134 
1135     wdev->wext.connect.crypto.n_akm_suites = nr_akm_suites;
1136 
1137     return 0;
1138 }
1139 
1140 static int cfg80211_wext_siwauth(struct net_device *dev,
1141                  struct iw_request_info *info,
1142                  struct iw_param *data, char *extra)
1143 {
1144     struct wireless_dev *wdev = dev->ieee80211_ptr;
1145 
1146     if (wdev->iftype != NL80211_IFTYPE_STATION)
1147         return -EOPNOTSUPP;
1148 
1149     switch (data->flags & IW_AUTH_INDEX) {
1150     case IW_AUTH_PRIVACY_INVOKED:
1151         wdev->wext.connect.privacy = data->value;
1152         return 0;
1153     case IW_AUTH_WPA_VERSION:
1154         return cfg80211_set_wpa_version(wdev, data->value);
1155     case IW_AUTH_CIPHER_GROUP:
1156         return cfg80211_set_cipher_group(wdev, data->value);
1157     case IW_AUTH_KEY_MGMT:
1158         return cfg80211_set_key_mgt(wdev, data->value);
1159     case IW_AUTH_CIPHER_PAIRWISE:
1160         return cfg80211_set_cipher_pairwise(wdev, data->value);
1161     case IW_AUTH_80211_AUTH_ALG:
1162         return cfg80211_set_auth_alg(wdev, data->value);
1163     case IW_AUTH_WPA_ENABLED:
1164     case IW_AUTH_RX_UNENCRYPTED_EAPOL:
1165     case IW_AUTH_DROP_UNENCRYPTED:
1166     case IW_AUTH_MFP:
1167         return 0;
1168     default:
1169         return -EOPNOTSUPP;
1170     }
1171 }
1172 
1173 static int cfg80211_wext_giwauth(struct net_device *dev,
1174                  struct iw_request_info *info,
1175                  struct iw_param *data, char *extra)
1176 {
1177     /* XXX: what do we need? */
1178 
1179     return -EOPNOTSUPP;
1180 }
1181 
1182 static int cfg80211_wext_siwpower(struct net_device *dev,
1183                   struct iw_request_info *info,
1184                   struct iw_param *wrq, char *extra)
1185 {
1186     struct wireless_dev *wdev = dev->ieee80211_ptr;
1187     struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
1188     bool ps;
1189     int timeout = wdev->ps_timeout;
1190     int err;
1191 
1192     if (wdev->iftype != NL80211_IFTYPE_STATION)
1193         return -EINVAL;
1194 
1195     if (!rdev->ops->set_power_mgmt)
1196         return -EOPNOTSUPP;
1197 
1198     if (wrq->disabled) {
1199         ps = false;
1200     } else {
1201         switch (wrq->flags & IW_POWER_MODE) {
1202         case IW_POWER_ON:       /* If not specified */
1203         case IW_POWER_MODE:     /* If set all mask */
1204         case IW_POWER_ALL_R:    /* If explicitely state all */
1205             ps = true;
1206             break;
1207         default:                /* Otherwise we ignore */
1208             return -EINVAL;
1209         }
1210 
1211         if (wrq->flags & ~(IW_POWER_MODE | IW_POWER_TIMEOUT))
1212             return -EINVAL;
1213 
1214         if (wrq->flags & IW_POWER_TIMEOUT)
1215             timeout = wrq->value / 1000;
1216     }
1217 
1218     wiphy_lock(&rdev->wiphy);
1219     err = rdev_set_power_mgmt(rdev, dev, ps, timeout);
1220     wiphy_unlock(&rdev->wiphy);
1221     if (err)
1222         return err;
1223 
1224     wdev->ps = ps;
1225     wdev->ps_timeout = timeout;
1226 
1227     return 0;
1228 
1229 }
1230 
1231 static int cfg80211_wext_giwpower(struct net_device *dev,
1232                   struct iw_request_info *info,
1233                   struct iw_param *wrq, char *extra)
1234 {
1235     struct wireless_dev *wdev = dev->ieee80211_ptr;
1236 
1237     wrq->disabled = !wdev->ps;
1238 
1239     return 0;
1240 }
1241 
1242 static int cfg80211_wext_siwrate(struct net_device *dev,
1243                  struct iw_request_info *info,
1244                  struct iw_param *rate, char *extra)
1245 {
1246     struct wireless_dev *wdev = dev->ieee80211_ptr;
1247     struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
1248     struct cfg80211_bitrate_mask mask;
1249     u32 fixed, maxrate;
1250     struct ieee80211_supported_band *sband;
1251     int band, ridx, ret;
1252     bool match = false;
1253 
1254     if (!rdev->ops->set_bitrate_mask)
1255         return -EOPNOTSUPP;
1256 
1257     memset(&mask, 0, sizeof(mask));
1258     fixed = 0;
1259     maxrate = (u32)-1;
1260 
1261     if (rate->value < 0) {
1262         /* nothing */
1263     } else if (rate->fixed) {
1264         fixed = rate->value / 100000;
1265     } else {
1266         maxrate = rate->value / 100000;
1267     }
1268 
1269     for (band = 0; band < NUM_NL80211_BANDS; band++) {
1270         sband = wdev->wiphy->bands[band];
1271         if (sband == NULL)
1272             continue;
1273         for (ridx = 0; ridx < sband->n_bitrates; ridx++) {
1274             struct ieee80211_rate *srate = &sband->bitrates[ridx];
1275             if (fixed == srate->bitrate) {
1276                 mask.control[band].legacy = 1 << ridx;
1277                 match = true;
1278                 break;
1279             }
1280             if (srate->bitrate <= maxrate) {
1281                 mask.control[band].legacy |= 1 << ridx;
1282                 match = true;
1283             }
1284         }
1285     }
1286 
1287     if (!match)
1288         return -EINVAL;
1289 
1290     wiphy_lock(&rdev->wiphy);
1291     if (dev->ieee80211_ptr->valid_links)
1292         ret = -EOPNOTSUPP;
1293     else
1294         ret = rdev_set_bitrate_mask(rdev, dev, 0, NULL, &mask);
1295     wiphy_unlock(&rdev->wiphy);
1296 
1297     return ret;
1298 }
1299 
1300 static int cfg80211_wext_giwrate(struct net_device *dev,
1301                  struct iw_request_info *info,
1302                  struct iw_param *rate, char *extra)
1303 {
1304     struct wireless_dev *wdev = dev->ieee80211_ptr;
1305     struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
1306     struct station_info sinfo = {};
1307     u8 addr[ETH_ALEN];
1308     int err;
1309 
1310     if (wdev->iftype != NL80211_IFTYPE_STATION)
1311         return -EOPNOTSUPP;
1312 
1313     if (!rdev->ops->get_station)
1314         return -EOPNOTSUPP;
1315 
1316     err = 0;
1317     wdev_lock(wdev);
1318     if (!wdev->valid_links && wdev->links[0].client.current_bss)
1319         memcpy(addr, wdev->links[0].client.current_bss->pub.bssid,
1320                ETH_ALEN);
1321     else
1322         err = -EOPNOTSUPP;
1323     wdev_unlock(wdev);
1324     if (err)
1325         return err;
1326 
1327     wiphy_lock(&rdev->wiphy);
1328     err = rdev_get_station(rdev, dev, addr, &sinfo);
1329     wiphy_unlock(&rdev->wiphy);
1330     if (err)
1331         return err;
1332 
1333     if (!(sinfo.filled & BIT_ULL(NL80211_STA_INFO_TX_BITRATE))) {
1334         err = -EOPNOTSUPP;
1335         goto free;
1336     }
1337 
1338     rate->value = 100000 * cfg80211_calculate_bitrate(&sinfo.txrate);
1339 
1340 free:
1341     cfg80211_sinfo_release_content(&sinfo);
1342     return err;
1343 }
1344 
1345 /* Get wireless statistics.  Called by /proc/net/wireless and by SIOCGIWSTATS */
1346 static struct iw_statistics *cfg80211_wireless_stats(struct net_device *dev)
1347 {
1348     struct wireless_dev *wdev = dev->ieee80211_ptr;
1349     struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
1350     /* we are under RTNL - globally locked - so can use static structs */
1351     static struct iw_statistics wstats;
1352     static struct station_info sinfo = {};
1353     u8 bssid[ETH_ALEN];
1354     int ret;
1355 
1356     if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION)
1357         return NULL;
1358 
1359     if (!rdev->ops->get_station)
1360         return NULL;
1361 
1362     /* Grab BSSID of current BSS, if any */
1363     wdev_lock(wdev);
1364     if (wdev->valid_links || !wdev->links[0].client.current_bss) {
1365         wdev_unlock(wdev);
1366         return NULL;
1367     }
1368     memcpy(bssid, wdev->links[0].client.current_bss->pub.bssid, ETH_ALEN);
1369     wdev_unlock(wdev);
1370 
1371     memset(&sinfo, 0, sizeof(sinfo));
1372 
1373     wiphy_lock(&rdev->wiphy);
1374     ret = rdev_get_station(rdev, dev, bssid, &sinfo);
1375     wiphy_unlock(&rdev->wiphy);
1376 
1377     if (ret)
1378         return NULL;
1379 
1380     memset(&wstats, 0, sizeof(wstats));
1381 
1382     switch (rdev->wiphy.signal_type) {
1383     case CFG80211_SIGNAL_TYPE_MBM:
1384         if (sinfo.filled & BIT_ULL(NL80211_STA_INFO_SIGNAL)) {
1385             int sig = sinfo.signal;
1386             wstats.qual.updated |= IW_QUAL_LEVEL_UPDATED;
1387             wstats.qual.updated |= IW_QUAL_QUAL_UPDATED;
1388             wstats.qual.updated |= IW_QUAL_DBM;
1389             wstats.qual.level = sig;
1390             if (sig < -110)
1391                 sig = -110;
1392             else if (sig > -40)
1393                 sig = -40;
1394             wstats.qual.qual = sig + 110;
1395             break;
1396         }
1397         fallthrough;
1398     case CFG80211_SIGNAL_TYPE_UNSPEC:
1399         if (sinfo.filled & BIT_ULL(NL80211_STA_INFO_SIGNAL)) {
1400             wstats.qual.updated |= IW_QUAL_LEVEL_UPDATED;
1401             wstats.qual.updated |= IW_QUAL_QUAL_UPDATED;
1402             wstats.qual.level = sinfo.signal;
1403             wstats.qual.qual = sinfo.signal;
1404             break;
1405         }
1406         fallthrough;
1407     default:
1408         wstats.qual.updated |= IW_QUAL_LEVEL_INVALID;
1409         wstats.qual.updated |= IW_QUAL_QUAL_INVALID;
1410     }
1411 
1412     wstats.qual.updated |= IW_QUAL_NOISE_INVALID;
1413     if (sinfo.filled & BIT_ULL(NL80211_STA_INFO_RX_DROP_MISC))
1414         wstats.discard.misc = sinfo.rx_dropped_misc;
1415     if (sinfo.filled & BIT_ULL(NL80211_STA_INFO_TX_FAILED))
1416         wstats.discard.retries = sinfo.tx_failed;
1417 
1418     cfg80211_sinfo_release_content(&sinfo);
1419 
1420     return &wstats;
1421 }
1422 
1423 static int cfg80211_wext_siwap(struct net_device *dev,
1424                    struct iw_request_info *info,
1425                    struct sockaddr *ap_addr, char *extra)
1426 {
1427     struct wireless_dev *wdev = dev->ieee80211_ptr;
1428     struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
1429     int ret;
1430 
1431     wiphy_lock(&rdev->wiphy);
1432     switch (wdev->iftype) {
1433     case NL80211_IFTYPE_ADHOC:
1434         ret = cfg80211_ibss_wext_siwap(dev, info, ap_addr, extra);
1435         break;
1436     case NL80211_IFTYPE_STATION:
1437         ret = cfg80211_mgd_wext_siwap(dev, info, ap_addr, extra);
1438         break;
1439     default:
1440         ret = -EOPNOTSUPP;
1441         break;
1442     }
1443     wiphy_unlock(&rdev->wiphy);
1444 
1445     return ret;
1446 }
1447 
1448 static int cfg80211_wext_giwap(struct net_device *dev,
1449                    struct iw_request_info *info,
1450                    struct sockaddr *ap_addr, char *extra)
1451 {
1452     struct wireless_dev *wdev = dev->ieee80211_ptr;
1453     struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
1454     int ret;
1455 
1456     wiphy_lock(&rdev->wiphy);
1457     switch (wdev->iftype) {
1458     case NL80211_IFTYPE_ADHOC:
1459         ret = cfg80211_ibss_wext_giwap(dev, info, ap_addr, extra);
1460         break;
1461     case NL80211_IFTYPE_STATION:
1462         ret = cfg80211_mgd_wext_giwap(dev, info, ap_addr, extra);
1463         break;
1464     default:
1465         ret = -EOPNOTSUPP;
1466         break;
1467     }
1468     wiphy_unlock(&rdev->wiphy);
1469 
1470     return ret;
1471 }
1472 
1473 static int cfg80211_wext_siwessid(struct net_device *dev,
1474                   struct iw_request_info *info,
1475                   struct iw_point *data, char *ssid)
1476 {
1477     struct wireless_dev *wdev = dev->ieee80211_ptr;
1478     struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
1479     int ret;
1480 
1481     wiphy_lock(&rdev->wiphy);
1482     switch (wdev->iftype) {
1483     case NL80211_IFTYPE_ADHOC:
1484         ret = cfg80211_ibss_wext_siwessid(dev, info, data, ssid);
1485         break;
1486     case NL80211_IFTYPE_STATION:
1487         ret = cfg80211_mgd_wext_siwessid(dev, info, data, ssid);
1488         break;
1489     default:
1490         ret = -EOPNOTSUPP;
1491         break;
1492     }
1493     wiphy_unlock(&rdev->wiphy);
1494 
1495     return ret;
1496 }
1497 
1498 static int cfg80211_wext_giwessid(struct net_device *dev,
1499                   struct iw_request_info *info,
1500                   struct iw_point *data, char *ssid)
1501 {
1502     struct wireless_dev *wdev = dev->ieee80211_ptr;
1503     struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
1504     int ret;
1505 
1506     data->flags = 0;
1507     data->length = 0;
1508 
1509     wiphy_lock(&rdev->wiphy);
1510     switch (wdev->iftype) {
1511     case NL80211_IFTYPE_ADHOC:
1512         ret = cfg80211_ibss_wext_giwessid(dev, info, data, ssid);
1513         break;
1514     case NL80211_IFTYPE_STATION:
1515         ret = cfg80211_mgd_wext_giwessid(dev, info, data, ssid);
1516         break;
1517     default:
1518         ret = -EOPNOTSUPP;
1519         break;
1520     }
1521     wiphy_unlock(&rdev->wiphy);
1522 
1523     return ret;
1524 }
1525 
1526 static int cfg80211_wext_siwpmksa(struct net_device *dev,
1527                   struct iw_request_info *info,
1528                   struct iw_point *data, char *extra)
1529 {
1530     struct wireless_dev *wdev = dev->ieee80211_ptr;
1531     struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
1532     struct cfg80211_pmksa cfg_pmksa;
1533     struct iw_pmksa *pmksa = (struct iw_pmksa *)extra;
1534     int ret;
1535 
1536     memset(&cfg_pmksa, 0, sizeof(struct cfg80211_pmksa));
1537 
1538     if (wdev->iftype != NL80211_IFTYPE_STATION)
1539         return -EINVAL;
1540 
1541     cfg_pmksa.bssid = pmksa->bssid.sa_data;
1542     cfg_pmksa.pmkid = pmksa->pmkid;
1543 
1544     wiphy_lock(&rdev->wiphy);
1545     switch (pmksa->cmd) {
1546     case IW_PMKSA_ADD:
1547         if (!rdev->ops->set_pmksa) {
1548             ret = -EOPNOTSUPP;
1549             break;
1550         }
1551 
1552         ret = rdev_set_pmksa(rdev, dev, &cfg_pmksa);
1553         break;
1554     case IW_PMKSA_REMOVE:
1555         if (!rdev->ops->del_pmksa) {
1556             ret = -EOPNOTSUPP;
1557             break;
1558         }
1559 
1560         ret = rdev_del_pmksa(rdev, dev, &cfg_pmksa);
1561         break;
1562     case IW_PMKSA_FLUSH:
1563         if (!rdev->ops->flush_pmksa) {
1564             ret = -EOPNOTSUPP;
1565             break;
1566         }
1567 
1568         ret = rdev_flush_pmksa(rdev, dev);
1569         break;
1570     default:
1571         ret = -EOPNOTSUPP;
1572         break;
1573     }
1574     wiphy_unlock(&rdev->wiphy);
1575 
1576     return ret;
1577 }
1578 
1579 #define DEFINE_WEXT_COMPAT_STUB(func, type)         \
1580     static int __ ## func(struct net_device *dev,       \
1581                   struct iw_request_info *info, \
1582                   union iwreq_data *wrqu,       \
1583                   char *extra)          \
1584     {                           \
1585         return func(dev, info, (type *)wrqu, extra);    \
1586     }
1587 
1588 DEFINE_WEXT_COMPAT_STUB(cfg80211_wext_giwname, char)
1589 DEFINE_WEXT_COMPAT_STUB(cfg80211_wext_siwfreq, struct iw_freq)
1590 DEFINE_WEXT_COMPAT_STUB(cfg80211_wext_giwfreq, struct iw_freq)
1591 DEFINE_WEXT_COMPAT_STUB(cfg80211_wext_siwmode, u32)
1592 DEFINE_WEXT_COMPAT_STUB(cfg80211_wext_giwmode, u32)
1593 DEFINE_WEXT_COMPAT_STUB(cfg80211_wext_giwrange, struct iw_point)
1594 DEFINE_WEXT_COMPAT_STUB(cfg80211_wext_siwap, struct sockaddr)
1595 DEFINE_WEXT_COMPAT_STUB(cfg80211_wext_giwap, struct sockaddr)
1596 DEFINE_WEXT_COMPAT_STUB(cfg80211_wext_siwmlme, struct iw_point)
1597 DEFINE_WEXT_COMPAT_STUB(cfg80211_wext_giwscan, struct iw_point)
1598 DEFINE_WEXT_COMPAT_STUB(cfg80211_wext_siwessid, struct iw_point)
1599 DEFINE_WEXT_COMPAT_STUB(cfg80211_wext_giwessid, struct iw_point)
1600 DEFINE_WEXT_COMPAT_STUB(cfg80211_wext_siwrate, struct iw_param)
1601 DEFINE_WEXT_COMPAT_STUB(cfg80211_wext_giwrate, struct iw_param)
1602 DEFINE_WEXT_COMPAT_STUB(cfg80211_wext_siwrts, struct iw_param)
1603 DEFINE_WEXT_COMPAT_STUB(cfg80211_wext_giwrts, struct iw_param)
1604 DEFINE_WEXT_COMPAT_STUB(cfg80211_wext_siwfrag, struct iw_param)
1605 DEFINE_WEXT_COMPAT_STUB(cfg80211_wext_giwfrag, struct iw_param)
1606 DEFINE_WEXT_COMPAT_STUB(cfg80211_wext_siwretry, struct iw_param)
1607 DEFINE_WEXT_COMPAT_STUB(cfg80211_wext_giwretry, struct iw_param)
1608 DEFINE_WEXT_COMPAT_STUB(cfg80211_wext_siwencode, struct iw_point)
1609 DEFINE_WEXT_COMPAT_STUB(cfg80211_wext_giwencode, struct iw_point)
1610 DEFINE_WEXT_COMPAT_STUB(cfg80211_wext_giwpower, struct iw_param)
1611 DEFINE_WEXT_COMPAT_STUB(cfg80211_wext_siwpower, struct iw_param)
1612 DEFINE_WEXT_COMPAT_STUB(cfg80211_wext_siwgenie, struct iw_point)
1613 DEFINE_WEXT_COMPAT_STUB(cfg80211_wext_giwauth, struct iw_param)
1614 DEFINE_WEXT_COMPAT_STUB(cfg80211_wext_siwauth, struct iw_param)
1615 DEFINE_WEXT_COMPAT_STUB(cfg80211_wext_siwencodeext, struct iw_point)
1616 DEFINE_WEXT_COMPAT_STUB(cfg80211_wext_siwpmksa, struct iw_point)
1617 
1618 static const iw_handler cfg80211_handlers[] = {
1619     [IW_IOCTL_IDX(SIOCGIWNAME)] = __cfg80211_wext_giwname,
1620     [IW_IOCTL_IDX(SIOCSIWFREQ)] = __cfg80211_wext_siwfreq,
1621     [IW_IOCTL_IDX(SIOCGIWFREQ)] = __cfg80211_wext_giwfreq,
1622     [IW_IOCTL_IDX(SIOCSIWMODE)] = __cfg80211_wext_siwmode,
1623     [IW_IOCTL_IDX(SIOCGIWMODE)] = __cfg80211_wext_giwmode,
1624     [IW_IOCTL_IDX(SIOCGIWRANGE)]    = __cfg80211_wext_giwrange,
1625     [IW_IOCTL_IDX(SIOCSIWAP)]   = __cfg80211_wext_siwap,
1626     [IW_IOCTL_IDX(SIOCGIWAP)]   = __cfg80211_wext_giwap,
1627     [IW_IOCTL_IDX(SIOCSIWMLME)] = __cfg80211_wext_siwmlme,
1628     [IW_IOCTL_IDX(SIOCSIWSCAN)] = cfg80211_wext_siwscan,
1629     [IW_IOCTL_IDX(SIOCGIWSCAN)] = __cfg80211_wext_giwscan,
1630     [IW_IOCTL_IDX(SIOCSIWESSID)]    = __cfg80211_wext_siwessid,
1631     [IW_IOCTL_IDX(SIOCGIWESSID)]    = __cfg80211_wext_giwessid,
1632     [IW_IOCTL_IDX(SIOCSIWRATE)] = __cfg80211_wext_siwrate,
1633     [IW_IOCTL_IDX(SIOCGIWRATE)] = __cfg80211_wext_giwrate,
1634     [IW_IOCTL_IDX(SIOCSIWRTS)]  = __cfg80211_wext_siwrts,
1635     [IW_IOCTL_IDX(SIOCGIWRTS)]  = __cfg80211_wext_giwrts,
1636     [IW_IOCTL_IDX(SIOCSIWFRAG)] = __cfg80211_wext_siwfrag,
1637     [IW_IOCTL_IDX(SIOCGIWFRAG)] = __cfg80211_wext_giwfrag,
1638     [IW_IOCTL_IDX(SIOCSIWTXPOW)]    = cfg80211_wext_siwtxpower,
1639     [IW_IOCTL_IDX(SIOCGIWTXPOW)]    = cfg80211_wext_giwtxpower,
1640     [IW_IOCTL_IDX(SIOCSIWRETRY)]    = __cfg80211_wext_siwretry,
1641     [IW_IOCTL_IDX(SIOCGIWRETRY)]    = __cfg80211_wext_giwretry,
1642     [IW_IOCTL_IDX(SIOCSIWENCODE)]   = __cfg80211_wext_siwencode,
1643     [IW_IOCTL_IDX(SIOCGIWENCODE)]   = __cfg80211_wext_giwencode,
1644     [IW_IOCTL_IDX(SIOCSIWPOWER)]    = __cfg80211_wext_siwpower,
1645     [IW_IOCTL_IDX(SIOCGIWPOWER)]    = __cfg80211_wext_giwpower,
1646     [IW_IOCTL_IDX(SIOCSIWGENIE)]    = __cfg80211_wext_siwgenie,
1647     [IW_IOCTL_IDX(SIOCSIWAUTH)] = __cfg80211_wext_siwauth,
1648     [IW_IOCTL_IDX(SIOCGIWAUTH)] = __cfg80211_wext_giwauth,
1649     [IW_IOCTL_IDX(SIOCSIWENCODEEXT)]= __cfg80211_wext_siwencodeext,
1650     [IW_IOCTL_IDX(SIOCSIWPMKSA)]    = __cfg80211_wext_siwpmksa,
1651 };
1652 
1653 const struct iw_handler_def cfg80211_wext_handler = {
1654     .num_standard       = ARRAY_SIZE(cfg80211_handlers),
1655     .standard       = cfg80211_handlers,
1656     .get_wireless_stats = cfg80211_wireless_stats,
1657 };