Upgrade b43 and mac80211.
[openwrt/staging/lynxis/omap.git] / package / mac80211 / src / net / mac80211 / ieee80211_ioctl.c
index f95d488726b59cc06cebaf88b4b97fbaf9908e47..54ad07aafe2d4de3a1a53eaa3f1348a928a21765 100644 (file)
@@ -21,6 +21,7 @@
 
 #include <net/mac80211.h>
 #include "ieee80211_i.h"
+#include "ieee80211_led.h"
 #include "ieee80211_rate.h"
 #include "wpa.h"
 #include "aes_ccm.h"
@@ -64,9 +65,10 @@ static int ieee80211_set_encryption(struct net_device *dev, u8 *sta_addr,
                sta = sta_info_get(local, sta_addr);
                if (!sta) {
 #ifdef CONFIG_MAC80211_VERBOSE_DEBUG
+                       DECLARE_MAC_BUF(mac);
                        printk(KERN_DEBUG "%s: set_encrypt - unknown addr "
-                              MAC_FMT "\n",
-                              dev->name, MAC_ARG(sta_addr));
+                              "%s\n",
+                              dev->name, print_mac(mac, sta_addr));
 #endif /* CONFIG_MAC80211_VERBOSE_DEBUG */
 
                        return -ENOENT;
@@ -110,8 +112,8 @@ static int ieee80211_ioctl_siwgenie(struct net_device *dev,
        if (sdata->flags & IEEE80211_SDATA_USERSPACE_MLME)
                return -EOPNOTSUPP;
 
-       if (sdata->type == IEEE80211_IF_TYPE_STA ||
-           sdata->type == IEEE80211_IF_TYPE_IBSS) {
+       if (sdata->vif.type == IEEE80211_IF_TYPE_STA ||
+           sdata->vif.type == IEEE80211_IF_TYPE_IBSS) {
                int ret = ieee80211_sta_set_extra_ie(dev, extra, data->length);
                if (ret)
                        return ret;
@@ -127,22 +129,7 @@ static int ieee80211_ioctl_giwname(struct net_device *dev,
                                   struct iw_request_info *info,
                                   char *name, char *extra)
 {
-       struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
-
-       switch (local->hw.conf.phymode) {
-       case MODE_IEEE80211A:
-               strcpy(name, "IEEE 802.11a");
-               break;
-       case MODE_IEEE80211B:
-               strcpy(name, "IEEE 802.11b");
-               break;
-       case MODE_IEEE80211G:
-               strcpy(name, "IEEE 802.11g");
-               break;
-       default:
-               strcpy(name, "IEEE 802.11");
-               break;
-       }
+       strcpy(name, "IEEE 802.11");
 
        return 0;
 }
@@ -154,7 +141,7 @@ static int ieee80211_ioctl_giwrange(struct net_device *dev,
 {
        struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
        struct iw_range *range = (struct iw_range *) extra;
-       struct ieee80211_hw_mode *mode = NULL;
+       enum ieee80211_band band;
        int c = 0;
 
        data->length = sizeof(struct iw_range);
@@ -189,24 +176,27 @@ static int ieee80211_ioctl_giwrange(struct net_device *dev,
        range->enc_capa = IW_ENC_CAPA_WPA | IW_ENC_CAPA_WPA2 |
                          IW_ENC_CAPA_CIPHER_TKIP | IW_ENC_CAPA_CIPHER_CCMP;
 
-       list_for_each_entry(mode, &local->modes_list, list) {
-               int i = 0;
 
-               if (!(local->enabled_modes & (1 << mode->mode)) ||
-                   (local->hw_modes & local->enabled_modes &
-                    (1 << MODE_IEEE80211G) && mode->mode == MODE_IEEE80211B))
+       for (band = 0; band < IEEE80211_NUM_BANDS; band ++) {
+               int i;
+               struct ieee80211_supported_band *sband;
+
+               sband = local->hw.wiphy->bands[band];
+
+               if (!sband)
                        continue;
 
-               while (i < mode->num_channels && c < IW_MAX_FREQUENCIES) {
-                       struct ieee80211_channel *chan = &mode->channels[i];
+               for (i = 0; i < sband->n_channels && c < IW_MAX_FREQUENCIES; i++) {
+                       struct ieee80211_channel *chan = &sband->channels[i];
 
-                       if (chan->flag & IEEE80211_CHAN_W_SCAN) {
-                               range->freq[c].i = chan->chan;
-                               range->freq[c].m = chan->freq * 100000;
-                               range->freq[c].e = 1;
+                       if (!(chan->flags & IEEE80211_CHAN_DISABLED)) {
+                               range->freq[c].i =
+                                       ieee80211_frequency_to_channel(
+                                               chan->center_freq);
+                               range->freq[c].m = chan->center_freq;
+                               range->freq[c].e = 6;
                                c++;
                        }
-                       i++;
                }
        }
        range->num_channels = c;
@@ -217,6 +207,8 @@ static int ieee80211_ioctl_giwrange(struct net_device *dev,
        IW_EVENT_CAPA_SET(range->event_capa, SIOCGIWAP);
        IW_EVENT_CAPA_SET(range->event_capa, SIOCGIWSCAN);
 
+       range->scan_capa |= IW_SCAN_CAPA_ESSID;
+
        return 0;
 }
 
@@ -228,7 +220,7 @@ static int ieee80211_ioctl_siwmode(struct net_device *dev,
        struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
        int type;
 
-       if (sdata->type == IEEE80211_IF_TYPE_VLAN)
+       if (sdata->vif.type == IEEE80211_IF_TYPE_VLAN)
                return -EOPNOTSUPP;
 
        switch (*mode) {
@@ -245,7 +237,7 @@ static int ieee80211_ioctl_siwmode(struct net_device *dev,
                return -EINVAL;
        }
 
-       if (type == sdata->type)
+       if (type == sdata->vif.type)
                return 0;
        if (netif_running(dev))
                return -EBUSY;
@@ -264,7 +256,7 @@ static int ieee80211_ioctl_giwmode(struct net_device *dev,
        struct ieee80211_sub_if_data *sdata;
 
        sdata = IEEE80211_DEV_TO_SUB_IF(dev);
-       switch (sdata->type) {
+       switch (sdata->vif.type) {
        case IEEE80211_IF_TYPE_AP:
                *mode = IW_MODE_MASTER;
                break;
@@ -290,28 +282,38 @@ static int ieee80211_ioctl_giwmode(struct net_device *dev,
        return 0;
 }
 
-int ieee80211_set_channel(struct ieee80211_local *local, int channel, int freq)
+int ieee80211_set_freq(struct ieee80211_local *local, int freqMHz)
 {
-       struct ieee80211_hw_mode *mode;
-       int c, set = 0;
+       int set = 0;
        int ret = -EINVAL;
+       enum ieee80211_band band;
+       struct ieee80211_supported_band *sband;
+       int i;
 
-       list_for_each_entry(mode, &local->modes_list, list) {
-               if (!(local->enabled_modes & (1 << mode->mode)))
+       for (band = 0; band < IEEE80211_NUM_BANDS; band ++) {
+               sband = local->hw.wiphy->bands[band];
+
+               if (!sband)
                        continue;
-               for (c = 0; c < mode->num_channels; c++) {
-                       struct ieee80211_channel *chan = &mode->channels[c];
-                       if (chan->flag & IEEE80211_CHAN_W_SCAN &&
-                           ((chan->chan == channel) || (chan->freq == freq))) {
+
+               for (i = 0; i < sband->n_channels; i++) {
+                       struct ieee80211_channel *chan = &sband->channels[i];
+
+                       if (chan->flags & IEEE80211_CHAN_DISABLED)
+                               continue;
+
+                       if (chan->center_freq == freqMHz) {
+                               set = 1;
                                local->oper_channel = chan;
-                               local->oper_hw_mode = mode;
-                               set++;
+                               break;
                        }
                }
+               if (set)
+                       break;
        }
 
        if (set) {
-               if (local->sta_scanning)
+               if (local->sta_sw_scanning)
                        ret = 0;
                else
                        ret = ieee80211_hw_config(local);
@@ -329,24 +331,25 @@ static int ieee80211_ioctl_siwfreq(struct net_device *dev,
        struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
        struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
 
-       if (sdata->type == IEEE80211_IF_TYPE_STA)
+       if (sdata->vif.type == IEEE80211_IF_TYPE_STA)
                sdata->u.sta.flags &= ~IEEE80211_STA_AUTO_CHANNEL_SEL;
 
        /* freq->e == 0: freq->m = channel; otherwise freq = m * 10^e */
        if (freq->e == 0) {
                if (freq->m < 0) {
-                       if (sdata->type == IEEE80211_IF_TYPE_STA)
+                       if (sdata->vif.type == IEEE80211_IF_TYPE_STA)
                                sdata->u.sta.flags |=
                                        IEEE80211_STA_AUTO_CHANNEL_SEL;
                        return 0;
                } else
-                       return ieee80211_set_channel(local, freq->m, -1);
+                       return ieee80211_set_freq(local,
+                               ieee80211_channel_to_frequency(freq->m));
        } else {
                int i, div = 1000000;
                for (i = 0; i < freq->e; i++)
                        div /= 10;
                if (div > 0)
-                       return ieee80211_set_channel(local, -1, freq->m / div);
+                       return ieee80211_set_freq(local, freq->m / div);
                else
                        return -EINVAL;
        }
@@ -359,10 +362,7 @@ static int ieee80211_ioctl_giwfreq(struct net_device *dev,
 {
        struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
 
-       /* TODO: in station mode (Managed/Ad-hoc) might need to poll low-level
-        * driver for the current channel with firmware-based management */
-
-       freq->m = local->hw.conf.freq;
+       freq->m = local->hw.conf.channel->center_freq;
        freq->e = 6;
 
        return 0;
@@ -381,8 +381,8 @@ static int ieee80211_ioctl_siwessid(struct net_device *dev,
                len--;
 
        sdata = IEEE80211_DEV_TO_SUB_IF(dev);
-       if (sdata->type == IEEE80211_IF_TYPE_STA ||
-           sdata->type == IEEE80211_IF_TYPE_IBSS) {
+       if (sdata->vif.type == IEEE80211_IF_TYPE_STA ||
+           sdata->vif.type == IEEE80211_IF_TYPE_IBSS) {
                int ret;
                if (sdata->flags & IEEE80211_SDATA_USERSPACE_MLME) {
                        if (len > IEEE80211_MAX_SSID_LEN)
@@ -402,7 +402,7 @@ static int ieee80211_ioctl_siwessid(struct net_device *dev,
                return 0;
        }
 
-       if (sdata->type == IEEE80211_IF_TYPE_AP) {
+       if (sdata->vif.type == IEEE80211_IF_TYPE_AP) {
                memcpy(sdata->u.ap.ssid, ssid, len);
                memset(sdata->u.ap.ssid + len, 0,
                       IEEE80211_MAX_SSID_LEN - len);
@@ -421,8 +421,8 @@ static int ieee80211_ioctl_giwessid(struct net_device *dev,
 
        struct ieee80211_sub_if_data *sdata;
        sdata = IEEE80211_DEV_TO_SUB_IF(dev);
-       if (sdata->type == IEEE80211_IF_TYPE_STA ||
-           sdata->type == IEEE80211_IF_TYPE_IBSS) {
+       if (sdata->vif.type == IEEE80211_IF_TYPE_STA ||
+           sdata->vif.type == IEEE80211_IF_TYPE_IBSS) {
                int res = ieee80211_sta_get_ssid(dev, ssid, &len);
                if (res == 0) {
                        data->length = len;
@@ -432,7 +432,7 @@ static int ieee80211_ioctl_giwessid(struct net_device *dev,
                return res;
        }
 
-       if (sdata->type == IEEE80211_IF_TYPE_AP) {
+       if (sdata->vif.type == IEEE80211_IF_TYPE_AP) {
                len = sdata->u.ap.ssid_len;
                if (len > IW_ESSID_MAX_SIZE)
                        len = IW_ESSID_MAX_SIZE;
@@ -452,8 +452,8 @@ static int ieee80211_ioctl_siwap(struct net_device *dev,
        struct ieee80211_sub_if_data *sdata;
 
        sdata = IEEE80211_DEV_TO_SUB_IF(dev);
-       if (sdata->type == IEEE80211_IF_TYPE_STA ||
-           sdata->type == IEEE80211_IF_TYPE_IBSS) {
+       if (sdata->vif.type == IEEE80211_IF_TYPE_STA ||
+           sdata->vif.type == IEEE80211_IF_TYPE_IBSS) {
                int ret;
                if (sdata->flags & IEEE80211_SDATA_USERSPACE_MLME) {
                        memcpy(sdata->u.sta.bssid, (u8 *) &ap_addr->sa_data,
@@ -472,7 +472,7 @@ static int ieee80211_ioctl_siwap(struct net_device *dev,
                        return ret;
                ieee80211_sta_req_auth(dev, &sdata->u.sta);
                return 0;
-       } else if (sdata->type == IEEE80211_IF_TYPE_WDS) {
+       } else if (sdata->vif.type == IEEE80211_IF_TYPE_WDS) {
                if (memcmp(sdata->u.wds.remote_addr, (u8 *) &ap_addr->sa_data,
                           ETH_ALEN) == 0)
                        return 0;
@@ -490,12 +490,12 @@ static int ieee80211_ioctl_giwap(struct net_device *dev,
        struct ieee80211_sub_if_data *sdata;
 
        sdata = IEEE80211_DEV_TO_SUB_IF(dev);
-       if (sdata->type == IEEE80211_IF_TYPE_STA ||
-           sdata->type == IEEE80211_IF_TYPE_IBSS) {
+       if (sdata->vif.type == IEEE80211_IF_TYPE_STA ||
+           sdata->vif.type == IEEE80211_IF_TYPE_IBSS) {
                ap_addr->sa_family = ARPHRD_ETHER;
                memcpy(&ap_addr->sa_data, sdata->u.sta.bssid, ETH_ALEN);
                return 0;
-       } else if (sdata->type == IEEE80211_IF_TYPE_WDS) {
+       } else if (sdata->vif.type == IEEE80211_IF_TYPE_WDS) {
                ap_addr->sa_family = ARPHRD_ETHER;
                memcpy(&ap_addr->sa_data, sdata->u.wds.remote_addr, ETH_ALEN);
                return 0;
@@ -507,32 +507,27 @@ static int ieee80211_ioctl_giwap(struct net_device *dev,
 
 static int ieee80211_ioctl_siwscan(struct net_device *dev,
                                   struct iw_request_info *info,
-                                  struct iw_point *data, char *extra)
+                                  union iwreq_data *wrqu, char *extra)
 {
-       struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
        struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
+       struct iw_scan_req *req = NULL;
        u8 *ssid = NULL;
        size_t ssid_len = 0;
 
        if (!netif_running(dev))
                return -ENETDOWN;
 
-       switch (sdata->type) {
-       case IEEE80211_IF_TYPE_STA:
-       case IEEE80211_IF_TYPE_IBSS:
-               if (local->scan_flags & IEEE80211_SCAN_MATCH_SSID) {
-                       ssid = sdata->u.sta.ssid;
-                       ssid_len = sdata->u.sta.ssid_len;
-               }
-               break;
-       case IEEE80211_IF_TYPE_AP:
-               if (local->scan_flags & IEEE80211_SCAN_MATCH_SSID) {
-                       ssid = sdata->u.ap.ssid;
-                       ssid_len = sdata->u.ap.ssid_len;
-               }
-               break;
-       default:
+       if (sdata->vif.type != IEEE80211_IF_TYPE_STA &&
+           sdata->vif.type != IEEE80211_IF_TYPE_IBSS &&
+           sdata->vif.type != IEEE80211_IF_TYPE_AP)
                return -EOPNOTSUPP;
+
+       /* if SSID was specified explicitly then use that */
+       if (wrqu->data.length == sizeof(struct iw_scan_req) &&
+           wrqu->data.flags & IW_SCAN_THIS_ESSID) {
+               req = (struct iw_scan_req *)extra;
+               ssid = req->essid;
+               ssid_len = req->essid_len;
        }
 
        return ieee80211_sta_req_scan(dev, ssid, ssid_len);
@@ -545,8 +540,10 @@ static int ieee80211_ioctl_giwscan(struct net_device *dev,
 {
        int res;
        struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
-       if (local->sta_scanning)
+
+       if (local->sta_sw_scanning || local->sta_hw_scanning)
                return -EAGAIN;
+
        res = ieee80211_sta_scan_results(dev, extra, data->length);
        if (res >= 0) {
                data->length = res;
@@ -562,15 +559,17 @@ static int ieee80211_ioctl_siwrate(struct net_device *dev,
                                  struct iw_param *rate, char *extra)
 {
        struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
-       struct ieee80211_hw_mode *mode;
-       int i;
+       int i, err = -EINVAL;
        u32 target_rate = rate->value / 100000;
        struct ieee80211_sub_if_data *sdata;
+       struct ieee80211_supported_band *sband;
 
        sdata = IEEE80211_DEV_TO_SUB_IF(dev);
        if (!sdata->bss)
                return -ENODEV;
-       mode = local->oper_hw_mode;
+
+       sband = local->hw.wiphy->bands[local->hw.conf.channel->band];
+
        /* target_rate = -1, rate->fixed = 0 means auto only, so use all rates
         * target_rate = X, rate->fixed = 1 means only rate X
         * target_rate = X, rate->fixed = 0 means all rates <= X */
@@ -578,18 +577,20 @@ static int ieee80211_ioctl_siwrate(struct net_device *dev,
        sdata->bss->force_unicast_rateidx = -1;
        if (rate->value < 0)
                return 0;
-       for (i=0; i< mode->num_rates; i++) {
-               struct ieee80211_rate *rates = &mode->rates[i];
-               int this_rate = rates->rate;
+
+       for (i=0; i< sband->n_bitrates; i++) {
+               struct ieee80211_rate *brate = &sband->bitrates[i];
+               int this_rate = brate->bitrate;
 
                if (target_rate == this_rate) {
                        sdata->bss->max_ratectrl_rateidx = i;
                        if (rate->fixed)
                                sdata->bss->force_unicast_rateidx = i;
+                       err = 0;
                        break;
                }
        }
-       return 0;
+       return err;
 }
 
 static int ieee80211_ioctl_giwrate(struct net_device *dev,
@@ -599,18 +600,24 @@ static int ieee80211_ioctl_giwrate(struct net_device *dev,
        struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
        struct sta_info *sta;
        struct ieee80211_sub_if_data *sdata;
+       struct ieee80211_supported_band *sband;
 
        sdata = IEEE80211_DEV_TO_SUB_IF(dev);
-       if (sdata->type == IEEE80211_IF_TYPE_STA)
+
+       if (sdata->vif.type == IEEE80211_IF_TYPE_STA)
                sta = sta_info_get(local, sdata->u.sta.bssid);
        else
                return -EOPNOTSUPP;
        if (!sta)
                return -ENODEV;
-       if (sta->txrate < local->oper_hw_mode->num_rates)
-               rate->value = local->oper_hw_mode->rates[sta->txrate].rate * 100000;
+
+       sband = local->hw.wiphy->bands[local->hw.conf.channel->band];
+
+       if (sta->txrate_idx < sband->n_bitrates)
+               rate->value = sband->bitrates[sta->txrate_idx].bitrate;
        else
                rate->value = 0;
+       rate->value *= 100000;
        sta_info_put(sta);
        return 0;
 }
@@ -621,22 +628,38 @@ static int ieee80211_ioctl_siwtxpower(struct net_device *dev,
 {
        struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
        bool need_reconfig = 0;
+       int new_power_level;
 
        if ((data->txpower.flags & IW_TXPOW_TYPE) != IW_TXPOW_DBM)
                return -EINVAL;
        if (data->txpower.flags & IW_TXPOW_RANGE)
                return -EINVAL;
-       if (!data->txpower.fixed)
-               return -EINVAL;
 
-       if (local->hw.conf.power_level != data->txpower.value) {
-               local->hw.conf.power_level = data->txpower.value;
+       if (data->txpower.fixed) {
+               new_power_level = data->txpower.value;
+       } else {
+               /*
+                * Automatic power level. Use maximum power for the current
+                * channel. Should be part of rate control.
+                */
+               struct ieee80211_channel* chan = local->hw.conf.channel;
+               if (!chan)
+                       return -EINVAL;
+
+               new_power_level = chan->max_power;
+       }
+
+       if (local->hw.conf.power_level != new_power_level) {
+               local->hw.conf.power_level = new_power_level;
                need_reconfig = 1;
        }
+
        if (local->hw.conf.radio_enabled != !(data->txpower.disabled)) {
                local->hw.conf.radio_enabled = !(data->txpower.disabled);
                need_reconfig = 1;
+               ieee80211_led_radio(local, local->hw.conf.radio_enabled);
        }
+
        if (need_reconfig) {
                ieee80211_hw_config(local);
                /* The return value of hw_config is not of big interest here,
@@ -801,8 +824,8 @@ static int ieee80211_ioctl_siwmlme(struct net_device *dev,
        struct iw_mlme *mlme = (struct iw_mlme *) extra;
 
        sdata = IEEE80211_DEV_TO_SUB_IF(dev);
-       if (sdata->type != IEEE80211_IF_TYPE_STA &&
-           sdata->type != IEEE80211_IF_TYPE_IBSS)
+       if (sdata->vif.type != IEEE80211_IF_TYPE_STA &&
+           sdata->vif.type != IEEE80211_IF_TYPE_IBSS)
                return -EINVAL;
 
        switch (mlme->cmd) {
@@ -904,7 +927,6 @@ static int ieee80211_ioctl_siwauth(struct net_device *dev,
                                   struct iw_request_info *info,
                                   struct iw_param *data, char *extra)
 {
-       struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
        struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
        int ret = 0;
 
@@ -914,32 +936,33 @@ static int ieee80211_ioctl_siwauth(struct net_device *dev,
        case IW_AUTH_CIPHER_GROUP:
        case IW_AUTH_WPA_ENABLED:
        case IW_AUTH_RX_UNENCRYPTED_EAPOL:
-               break;
        case IW_AUTH_KEY_MGMT:
-               if (sdata->type != IEEE80211_IF_TYPE_STA)
+               break;
+       case IW_AUTH_DROP_UNENCRYPTED:
+               sdata->drop_unencrypted = !!data->value;
+               break;
+       case IW_AUTH_PRIVACY_INVOKED:
+               if (sdata->vif.type != IEEE80211_IF_TYPE_STA)
                        ret = -EINVAL;
                else {
+                       sdata->u.sta.flags &= ~IEEE80211_STA_PRIVACY_INVOKED;
                        /*
-                        * Key management was set by wpa_supplicant,
-                        * we only need this to associate to a network
-                        * that has privacy enabled regardless of not
-                        * having a key.
+                        * Privacy invoked by wpa_supplicant, store the
+                        * value and allow associating to a protected
+                        * network without having a key up front.
                         */
-                       sdata->u.sta.key_management_enabled = !!data->value;
+                       if (data->value)
+                               sdata->u.sta.flags |=
+                                       IEEE80211_STA_PRIVACY_INVOKED;
                }
                break;
        case IW_AUTH_80211_AUTH_ALG:
-               if (sdata->type == IEEE80211_IF_TYPE_STA ||
-                   sdata->type == IEEE80211_IF_TYPE_IBSS)
+               if (sdata->vif.type == IEEE80211_IF_TYPE_STA ||
+                   sdata->vif.type == IEEE80211_IF_TYPE_IBSS)
                        sdata->u.sta.auth_algs = data->value;
                else
                        ret = -EOPNOTSUPP;
                break;
-       case IW_AUTH_PRIVACY_INVOKED:
-               if (local->ops->set_privacy_invoked)
-                       ret = local->ops->set_privacy_invoked(
-                                       local_to_hw(local), data->value);
-               break;
        default:
                ret = -EOPNOTSUPP;
                break;
@@ -955,8 +978,8 @@ static struct iw_statistics *ieee80211_get_wireless_stats(struct net_device *dev
        struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
        struct sta_info *sta = NULL;
 
-       if (sdata->type == IEEE80211_IF_TYPE_STA ||
-           sdata->type == IEEE80211_IF_TYPE_IBSS)
+       if (sdata->vif.type == IEEE80211_IF_TYPE_STA ||
+           sdata->vif.type == IEEE80211_IF_TYPE_IBSS)
                sta = sta_info_get(local, sdata->u.sta.bssid);
        if (!sta) {
                wstats->discard.fragment = 0;
@@ -984,8 +1007,8 @@ static int ieee80211_ioctl_giwauth(struct net_device *dev,
 
        switch (data->flags & IW_AUTH_INDEX) {
        case IW_AUTH_80211_AUTH_ALG:
-               if (sdata->type == IEEE80211_IF_TYPE_STA ||
-                   sdata->type == IEEE80211_IF_TYPE_IBSS)
+               if (sdata->vif.type == IEEE80211_IF_TYPE_STA ||
+                   sdata->vif.type == IEEE80211_IF_TYPE_IBSS)
                        data->value = sdata->u.sta.auth_algs;
                else
                        ret = -EOPNOTSUPP;