linux/net/wireless/wext-compat.c
<<
>>
Prefs
   1/*
   2 * cfg80211 - wext compat code
   3 *
   4 * This is temporary code until all wireless functionality is migrated
   5 * into cfg80211, when that happens all the exports here go away and
   6 * we directly assign the wireless handlers of wireless interfaces.
   7 *
   8 * Copyright 2008       Johannes Berg <johannes@sipsolutions.net>
   9 */
  10
  11#include <linux/wireless.h>
  12#include <linux/nl80211.h>
  13#include <net/iw_handler.h>
  14#include <net/wireless.h>
  15#include <net/cfg80211.h>
  16#include "core.h"
  17
  18int cfg80211_wext_giwname(struct net_device *dev,
  19                          struct iw_request_info *info,
  20                          char *name, char *extra)
  21{
  22        struct wireless_dev *wdev = dev->ieee80211_ptr;
  23        struct ieee80211_supported_band *sband;
  24        bool is_ht = false, is_a = false, is_b = false, is_g = false;
  25
  26        if (!wdev)
  27                return -EOPNOTSUPP;
  28
  29        sband = wdev->wiphy->bands[IEEE80211_BAND_5GHZ];
  30        if (sband) {
  31                is_a = true;
  32                is_ht |= sband->ht_cap.ht_supported;
  33        }
  34
  35        sband = wdev->wiphy->bands[IEEE80211_BAND_2GHZ];
  36        if (sband) {
  37                int i;
  38                /* Check for mandatory rates */
  39                for (i = 0; i < sband->n_bitrates; i++) {
  40                        if (sband->bitrates[i].bitrate == 10)
  41                                is_b = true;
  42                        if (sband->bitrates[i].bitrate == 60)
  43                                is_g = true;
  44                }
  45                is_ht |= sband->ht_cap.ht_supported;
  46        }
  47
  48        strcpy(name, "IEEE 802.11");
  49        if (is_a)
  50                strcat(name, "a");
  51        if (is_b)
  52                strcat(name, "b");
  53        if (is_g)
  54                strcat(name, "g");
  55        if (is_ht)
  56                strcat(name, "n");
  57
  58        return 0;
  59}
  60EXPORT_SYMBOL(cfg80211_wext_giwname);
  61
  62int cfg80211_wext_siwmode(struct net_device *dev, struct iw_request_info *info,
  63                          u32 *mode, char *extra)
  64{
  65        struct wireless_dev *wdev = dev->ieee80211_ptr;
  66        struct cfg80211_registered_device *rdev;
  67        struct vif_params vifparams;
  68        enum nl80211_iftype type;
  69        int ret;
  70
  71        if (!wdev)
  72                return -EOPNOTSUPP;
  73
  74        rdev = wiphy_to_dev(wdev->wiphy);
  75
  76        if (!rdev->ops->change_virtual_intf)
  77                return -EOPNOTSUPP;
  78
  79        /* don't support changing VLANs, you just re-create them */
  80        if (wdev->iftype == NL80211_IFTYPE_AP_VLAN)
  81                return -EOPNOTSUPP;
  82
  83        switch (*mode) {
  84        case IW_MODE_INFRA:
  85                type = NL80211_IFTYPE_STATION;
  86                break;
  87        case IW_MODE_ADHOC:
  88                type = NL80211_IFTYPE_ADHOC;
  89                break;
  90        case IW_MODE_REPEAT:
  91                type = NL80211_IFTYPE_WDS;
  92                break;
  93        case IW_MODE_MONITOR:
  94                type = NL80211_IFTYPE_MONITOR;
  95                break;
  96        default:
  97                return -EINVAL;
  98        }
  99
 100        if (type == wdev->iftype)
 101                return 0;
 102
 103        memset(&vifparams, 0, sizeof(vifparams));
 104
 105        ret = rdev->ops->change_virtual_intf(wdev->wiphy, dev->ifindex, type,
 106                                             NULL, &vifparams);
 107        WARN_ON(!ret && wdev->iftype != type);
 108
 109        return ret;
 110}
 111EXPORT_SYMBOL(cfg80211_wext_siwmode);
 112
 113int cfg80211_wext_giwmode(struct net_device *dev, struct iw_request_info *info,
 114                          u32 *mode, char *extra)
 115{
 116        struct wireless_dev *wdev = dev->ieee80211_ptr;
 117
 118        if (!wdev)
 119                return -EOPNOTSUPP;
 120
 121        switch (wdev->iftype) {
 122        case NL80211_IFTYPE_AP:
 123                *mode = IW_MODE_MASTER;
 124                break;
 125        case NL80211_IFTYPE_STATION:
 126                *mode = IW_MODE_INFRA;
 127                break;
 128        case NL80211_IFTYPE_ADHOC:
 129                *mode = IW_MODE_ADHOC;
 130                break;
 131        case NL80211_IFTYPE_MONITOR:
 132                *mode = IW_MODE_MONITOR;
 133                break;
 134        case NL80211_IFTYPE_WDS:
 135                *mode = IW_MODE_REPEAT;
 136                break;
 137        case NL80211_IFTYPE_AP_VLAN:
 138                *mode = IW_MODE_SECOND;         /* FIXME */
 139                break;
 140        default:
 141                *mode = IW_MODE_AUTO;
 142                break;
 143        }
 144        return 0;
 145}
 146EXPORT_SYMBOL(cfg80211_wext_giwmode);
 147
 148
 149int cfg80211_wext_giwrange(struct net_device *dev,
 150                           struct iw_request_info *info,
 151                           struct iw_point *data, char *extra)
 152{
 153        struct wireless_dev *wdev = dev->ieee80211_ptr;
 154        struct iw_range *range = (struct iw_range *) extra;
 155        enum ieee80211_band band;
 156        int c = 0;
 157
 158        if (!wdev)
 159                return -EOPNOTSUPP;
 160
 161        data->length = sizeof(struct iw_range);
 162        memset(range, 0, sizeof(struct iw_range));
 163
 164        range->we_version_compiled = WIRELESS_EXT;
 165        range->we_version_source = 21;
 166        range->retry_capa = IW_RETRY_LIMIT;
 167        range->retry_flags = IW_RETRY_LIMIT;
 168        range->min_retry = 0;
 169        range->max_retry = 255;
 170        range->min_rts = 0;
 171        range->max_rts = 2347;
 172        range->min_frag = 256;
 173        range->max_frag = 2346;
 174
 175        range->encoding_size[0] = 5;
 176        range->encoding_size[1] = 13;
 177        range->num_encoding_sizes = 2;
 178        range->max_encoding_tokens = 4;
 179
 180        range->max_qual.updated = IW_QUAL_NOISE_INVALID;
 181
 182        switch (wdev->wiphy->signal_type) {
 183        case CFG80211_SIGNAL_TYPE_NONE:
 184                break;
 185        case CFG80211_SIGNAL_TYPE_MBM:
 186                range->max_qual.level = -110;
 187                range->max_qual.qual = 70;
 188                range->avg_qual.qual = 35;
 189                range->max_qual.updated |= IW_QUAL_DBM;
 190                range->max_qual.updated |= IW_QUAL_QUAL_UPDATED;
 191                range->max_qual.updated |= IW_QUAL_LEVEL_UPDATED;
 192                break;
 193        case CFG80211_SIGNAL_TYPE_UNSPEC:
 194                range->max_qual.level = 100;
 195                range->max_qual.qual = 100;
 196                range->avg_qual.qual = 50;
 197                range->max_qual.updated |= IW_QUAL_QUAL_UPDATED;
 198                range->max_qual.updated |= IW_QUAL_LEVEL_UPDATED;
 199                break;
 200        }
 201
 202        range->avg_qual.level = range->max_qual.level / 2;
 203        range->avg_qual.noise = range->max_qual.noise / 2;
 204        range->avg_qual.updated = range->max_qual.updated;
 205
 206        range->enc_capa = IW_ENC_CAPA_WPA | IW_ENC_CAPA_WPA2 |
 207                          IW_ENC_CAPA_CIPHER_TKIP | IW_ENC_CAPA_CIPHER_CCMP;
 208
 209
 210        for (band = 0; band < IEEE80211_NUM_BANDS; band ++) {
 211                int i;
 212                struct ieee80211_supported_band *sband;
 213
 214                sband = wdev->wiphy->bands[band];
 215
 216                if (!sband)
 217                        continue;
 218
 219                for (i = 0; i < sband->n_channels && c < IW_MAX_FREQUENCIES; i++) {
 220                        struct ieee80211_channel *chan = &sband->channels[i];
 221
 222                        if (!(chan->flags & IEEE80211_CHAN_DISABLED)) {
 223                                range->freq[c].i =
 224                                        ieee80211_frequency_to_channel(
 225                                                chan->center_freq);
 226                                range->freq[c].m = chan->center_freq;
 227                                range->freq[c].e = 6;
 228                                c++;
 229                        }
 230                }
 231        }
 232        range->num_channels = c;
 233        range->num_frequency = c;
 234
 235        IW_EVENT_CAPA_SET_KERNEL(range->event_capa);
 236        IW_EVENT_CAPA_SET(range->event_capa, SIOCGIWAP);
 237        IW_EVENT_CAPA_SET(range->event_capa, SIOCGIWSCAN);
 238
 239        range->scan_capa |= IW_SCAN_CAPA_ESSID;
 240
 241        return 0;
 242}
 243EXPORT_SYMBOL(cfg80211_wext_giwrange);
 244