Merge tag 'mac80211-next-for-davem-2015-01-19' of git://git.kernel.org/pub/scm/linux...
authorDavid S. Miller <davem@davemloft.net>
Mon, 19 Jan 2015 21:22:19 +0000 (16:22 -0500)
committerDavid S. Miller <davem@davemloft.net>
Mon, 19 Jan 2015 21:22:19 +0000 (16:22 -0500)
Some further updates for net-next:
 * fix network-manager which was broken by the previous changes
 * fix delete-station events, which were broken by me making the
   genlmsg_end() mistake
 * fix a timer left running during suspend in some race conditions
   that would cause an annoying (but harmless) warning
 * (less important, but in the tree already) remove 80+80 MHz rate
   reporting since the spec doesn't distinguish it from 160 MHz;
   as the bitrate they're both 160 MHz bandwidth

Signed-off-by: David S. Miller <davem@davemloft.net>
13 files changed:
drivers/net/wireless/ath/ath6kl/cfg80211.c
drivers/net/wireless/mwifiex/cfg80211.c
include/net/cfg80211.h
include/net/mac80211.h
include/uapi/linux/nl80211.h
net/mac80211/cfg.c
net/mac80211/mlme.c
net/mac80211/rx.c
net/mac80211/status.c
net/mac80211/util.c
net/wireless/core.c
net/wireless/nl80211.c
net/wireless/util.c

index 44dd6ef..85da63a 100644 (file)
@@ -1827,6 +1827,7 @@ static int ath6kl_get_station(struct wiphy *wiphy, struct net_device *dev,
                }
 
                sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
+               sinfo->txrate.bw = RATE_INFO_BW_20;
        } else if (is_rate_ht40(rate, &mcs, &sgi)) {
                if (sgi) {
                        sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
@@ -1835,7 +1836,7 @@ static int ath6kl_get_station(struct wiphy *wiphy, struct net_device *dev,
                        sinfo->txrate.mcs = mcs;
                }
 
-               sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
+               sinfo->txrate.bw = RATE_INFO_BW_40;
                sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
        } else {
                ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
index 71312ff..1996a8b 100644 (file)
@@ -856,16 +856,16 @@ mwifiex_parse_htinfo(struct mwifiex_private *priv, u8 tx_htinfo,
                        /* HT or VHT */
                        switch (tx_htinfo & (BIT(3) | BIT(2))) {
                        case 0:
-                               /* This will be 20MHz */
+                               rate->bw = RATE_INFO_BW_20;
                                break;
                        case (BIT(2)):
-                               rate->flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
+                               rate->bw = RATE_INFO_BW_40;
                                break;
                        case (BIT(3)):
-                               rate->flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
+                               rate->bw = RATE_INFO_BW_80;
                                break;
                        case (BIT(3) | BIT(2)):
-                               rate->flags |= RATE_INFO_FLAGS_160_MHZ_WIDTH;
+                               rate->bw = RATE_INFO_BW_160;
                                break;
                        }
 
@@ -885,8 +885,9 @@ mwifiex_parse_htinfo(struct mwifiex_private *priv, u8 tx_htinfo,
                if ((tx_htinfo & BIT(0)) && (priv->tx_rate < 16)) {
                        rate->mcs = priv->tx_rate;
                        rate->flags |= RATE_INFO_FLAGS_MCS;
+                       rate->bw = RATE_INFO_BW_20;
                        if (tx_htinfo & BIT(1))
-                               rate->flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
+                               rate->bw = RATE_INFO_BW_40;
                        if (tx_htinfo & BIT(2))
                                rate->flags |= RATE_INFO_FLAGS_SHORT_GI;
                }
index 38abc07..7b44ba0 100644 (file)
@@ -873,22 +873,35 @@ int cfg80211_check_station_change(struct wiphy *wiphy,
  *
  * @RATE_INFO_FLAGS_MCS: mcs field filled with HT MCS
  * @RATE_INFO_FLAGS_VHT_MCS: mcs field filled with VHT MCS
- * @RATE_INFO_FLAGS_40_MHZ_WIDTH: 40 MHz width transmission
- * @RATE_INFO_FLAGS_80_MHZ_WIDTH: 80 MHz width transmission
- * @RATE_INFO_FLAGS_80P80_MHZ_WIDTH: 80+80 MHz width transmission
- * @RATE_INFO_FLAGS_160_MHZ_WIDTH: 160 MHz width transmission
  * @RATE_INFO_FLAGS_SHORT_GI: 400ns guard interval
  * @RATE_INFO_FLAGS_60G: 60GHz MCS
  */
 enum rate_info_flags {
        RATE_INFO_FLAGS_MCS                     = BIT(0),
        RATE_INFO_FLAGS_VHT_MCS                 = BIT(1),
-       RATE_INFO_FLAGS_40_MHZ_WIDTH            = BIT(2),
-       RATE_INFO_FLAGS_80_MHZ_WIDTH            = BIT(3),
-       RATE_INFO_FLAGS_80P80_MHZ_WIDTH         = BIT(4),
-       RATE_INFO_FLAGS_160_MHZ_WIDTH           = BIT(5),
-       RATE_INFO_FLAGS_SHORT_GI                = BIT(6),
-       RATE_INFO_FLAGS_60G                     = BIT(7),
+       RATE_INFO_FLAGS_SHORT_GI                = BIT(2),
+       RATE_INFO_FLAGS_60G                     = BIT(3),
+};
+
+/**
+ * enum rate_info_bw - rate bandwidth information
+ *
+ * Used by the driver to indicate the rate bandwidth.
+ *
+ * @RATE_INFO_BW_5: 5 MHz bandwidth
+ * @RATE_INFO_BW_10: 10 MHz bandwidth
+ * @RATE_INFO_BW_20: 20 MHz bandwidth
+ * @RATE_INFO_BW_40: 40 MHz bandwidth
+ * @RATE_INFO_BW_80: 80 MHz bandwidth
+ * @RATE_INFO_BW_160: 160 MHz bandwidth
+ */
+enum rate_info_bw {
+       RATE_INFO_BW_5,
+       RATE_INFO_BW_10,
+       RATE_INFO_BW_20,
+       RATE_INFO_BW_40,
+       RATE_INFO_BW_80,
+       RATE_INFO_BW_160,
 };
 
 /**
@@ -900,12 +913,14 @@ enum rate_info_flags {
  * @mcs: mcs index if struct describes a 802.11n bitrate
  * @legacy: bitrate in 100kbit/s for 802.11abg
  * @nss: number of streams (VHT only)
+ * @bw: bandwidth (from &enum rate_info_bw)
  */
 struct rate_info {
        u8 flags;
        u8 mcs;
        u16 legacy;
        u8 nss;
+       u8 bw;
 };
 
 /**
index 123f230..275ee56 100644 (file)
@@ -931,15 +931,13 @@ enum mac80211_rx_flags {
  * These flags are used with the @vht_flag member of
  *     &struct ieee80211_rx_status.
  * @RX_VHT_FLAG_80MHZ: 80 MHz was used
- * @RX_VHT_FLAG_80P80MHZ: 80+80 MHz was used
  * @RX_VHT_FLAG_160MHZ: 160 MHz was used
  * @RX_VHT_FLAG_BF: packet was beamformed
  */
 enum mac80211_rx_vht_flags {
        RX_VHT_FLAG_80MHZ               = BIT(0),
-       RX_VHT_FLAG_80P80MHZ            = BIT(1),
-       RX_VHT_FLAG_160MHZ              = BIT(2),
-       RX_VHT_FLAG_BF                  = BIT(3),
+       RX_VHT_FLAG_160MHZ              = BIT(1),
+       RX_VHT_FLAG_BF                  = BIT(2),
 };
 
 /**
index b6c1a00..f52797a 100644 (file)
@@ -2278,8 +2278,15 @@ struct nl80211_sta_flag_update {
  * @NL80211_RATE_INFO_VHT_MCS: MCS index for VHT (u8)
  * @NL80211_RATE_INFO_VHT_NSS: number of streams in VHT (u8)
  * @NL80211_RATE_INFO_80_MHZ_WIDTH: 80 MHz VHT rate
- * @NL80211_RATE_INFO_80P80_MHZ_WIDTH: 80+80 MHz VHT rate
+ * @NL80211_RATE_INFO_80P80_MHZ_WIDTH: unused - 80+80 is treated the
+ *     same as 160 for purposes of the bitrates
  * @NL80211_RATE_INFO_160_MHZ_WIDTH: 160 MHz VHT rate
+ * @NL80211_RATE_INFO_10_MHZ_WIDTH: 10 MHz width - note that this is
+ *     a legacy rate and will be reported as the actual bitrate, i.e.
+ *     half the base (20 MHz) rate
+ * @NL80211_RATE_INFO_5_MHZ_WIDTH: 5 MHz width - note that this is
+ *     a legacy rate and will be reported as the actual bitrate, i.e.
+ *     a quarter of the base (20 MHz) rate
  * @__NL80211_RATE_INFO_AFTER_LAST: internal use
  */
 enum nl80211_rate_info {
@@ -2294,6 +2301,8 @@ enum nl80211_rate_info {
        NL80211_RATE_INFO_80_MHZ_WIDTH,
        NL80211_RATE_INFO_80P80_MHZ_WIDTH,
        NL80211_RATE_INFO_160_MHZ_WIDTH,
+       NL80211_RATE_INFO_10_MHZ_WIDTH,
+       NL80211_RATE_INFO_5_MHZ_WIDTH,
 
        /* keep last */
        __NL80211_RATE_INFO_AFTER_LAST,
index fd6860d..ff090ef 100644 (file)
@@ -428,11 +428,13 @@ void sta_set_rate_info_tx(struct sta_info *sta,
                rinfo->legacy = DIV_ROUND_UP(brate, 1 << shift);
        }
        if (rate->flags & IEEE80211_TX_RC_40_MHZ_WIDTH)
-               rinfo->flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
-       if (rate->flags & IEEE80211_TX_RC_80_MHZ_WIDTH)
-               rinfo->flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
-       if (rate->flags & IEEE80211_TX_RC_160_MHZ_WIDTH)
-               rinfo->flags |= RATE_INFO_FLAGS_160_MHZ_WIDTH;
+               rinfo->bw = RATE_INFO_BW_40;
+       else if (rate->flags & IEEE80211_TX_RC_80_MHZ_WIDTH)
+               rinfo->bw = RATE_INFO_BW_80;
+       else if (rate->flags & IEEE80211_TX_RC_160_MHZ_WIDTH)
+               rinfo->bw = RATE_INFO_BW_160;
+       else
+               rinfo->bw = RATE_INFO_BW_20;
        if (rate->flags & IEEE80211_TX_RC_SHORT_GI)
                rinfo->flags |= RATE_INFO_FLAGS_SHORT_GI;
 }
@@ -459,16 +461,21 @@ void sta_set_rate_info_rx(struct sta_info *sta, struct rate_info *rinfo)
                rinfo->legacy = DIV_ROUND_UP(brate, 1 << shift);
        }
 
-       if (sta->last_rx_rate_flag & RX_FLAG_40MHZ)
-               rinfo->flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
        if (sta->last_rx_rate_flag & RX_FLAG_SHORT_GI)
                rinfo->flags |= RATE_INFO_FLAGS_SHORT_GI;
-       if (sta->last_rx_rate_vht_flag & RX_VHT_FLAG_80MHZ)
-               rinfo->flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
-       if (sta->last_rx_rate_vht_flag & RX_VHT_FLAG_80P80MHZ)
-               rinfo->flags |= RATE_INFO_FLAGS_80P80_MHZ_WIDTH;
-       if (sta->last_rx_rate_vht_flag & RX_VHT_FLAG_160MHZ)
-               rinfo->flags |= RATE_INFO_FLAGS_160_MHZ_WIDTH;
+
+       if (sta->last_rx_rate_flag & RX_FLAG_5MHZ)
+               rinfo->bw = RATE_INFO_BW_5;
+       else if (sta->last_rx_rate_flag & RX_FLAG_10MHZ)
+               rinfo->bw = RATE_INFO_BW_10;
+       else if (sta->last_rx_rate_flag & RX_FLAG_40MHZ)
+               rinfo->bw = RATE_INFO_BW_40;
+       else if (sta->last_rx_rate_vht_flag & RX_VHT_FLAG_80MHZ)
+               rinfo->bw = RATE_INFO_BW_80;
+       else if (sta->last_rx_rate_vht_flag & RX_VHT_FLAG_160MHZ)
+               rinfo->bw = RATE_INFO_BW_160;
+       else
+               rinfo->bw = RATE_INFO_BW_20;
 }
 
 static int ieee80211_dump_station(struct wiphy *wiphy, struct net_device *dev,
index c071108..1875181 100644 (file)
@@ -2453,6 +2453,12 @@ static void ieee80211_destroy_auth_data(struct ieee80211_sub_if_data *sdata,
        sdata_assert_lock(sdata);
 
        if (!assoc) {
+               /*
+                * we are not authenticated yet, the only timer that could be
+                * running is the timeout for the authentication response which
+                * which is not relevant anymore.
+                */
+               del_timer_sync(&sdata->u.mgd.timer);
                sta_info_destroy_addr(sdata, auth_data->bss->bssid);
 
                memset(sdata->u.mgd.bssid, 0, ETH_ALEN);
@@ -2760,6 +2766,12 @@ static void ieee80211_destroy_assoc_data(struct ieee80211_sub_if_data *sdata,
        sdata_assert_lock(sdata);
 
        if (!assoc) {
+               /*
+                * we are not associated yet, the only timer that could be
+                * running is the timeout for the association response which
+                * which is not relevant anymore.
+                */
+               del_timer_sync(&sdata->u.mgd.timer);
                sta_info_destroy_addr(sdata, assoc_data->bss->bssid);
 
                memset(sdata->u.mgd.bssid, 0, ETH_ALEN);
index 3a1a3ba..3d79d49 100644 (file)
@@ -361,9 +361,6 @@ ieee80211_add_rx_radiotap_header(struct ieee80211_local *local,
                u16 known = local->hw.radiotap_vht_details;
 
                rthdr->it_present |= cpu_to_le32(1 << IEEE80211_RADIOTAP_VHT);
-               /* known field - how to handle 80+80? */
-               if (status->vht_flag & RX_VHT_FLAG_80P80MHZ)
-                       known &= ~IEEE80211_RADIOTAP_VHT_KNOWN_BANDWIDTH;
                put_unaligned_le16(known, pos);
                pos += 2;
                /* flags */
@@ -378,8 +375,6 @@ ieee80211_add_rx_radiotap_header(struct ieee80211_local *local,
                /* bandwidth */
                if (status->vht_flag & RX_VHT_FLAG_80MHZ)
                        *pos++ = 4;
-               else if (status->vht_flag & RX_VHT_FLAG_80P80MHZ)
-                       *pos++ = 0; /* marked not known above */
                else if (status->vht_flag & RX_VHT_FLAG_160MHZ)
                        *pos++ = 11;
                else if (status->flag & RX_FLAG_40MHZ)
index 788707f..e679b7c 100644 (file)
@@ -730,7 +730,7 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb)
        struct ieee80211_bar *bar;
        int rtap_len;
        int shift = 0;
-       int tid = IEEE80211_NUM_TIDS;;
+       int tid = IEEE80211_NUM_TIDS;
 
        rates_idx = ieee80211_tx_get_rates(hw, info, &retry_count);
 
index 83ba6cd..fbd37d4 100644 (file)
@@ -2541,7 +2541,9 @@ u64 ieee80211_calculate_rx_timestamp(struct ieee80211_local *local,
                ri.mcs = status->rate_idx;
                ri.flags |= RATE_INFO_FLAGS_MCS;
                if (status->flag & RX_FLAG_40MHZ)
-                       ri.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
+                       ri.bw = RATE_INFO_BW_40;
+               else
+                       ri.bw = RATE_INFO_BW_20;
                if (status->flag & RX_FLAG_SHORT_GI)
                        ri.flags |= RATE_INFO_FLAGS_SHORT_GI;
        } else if (status->flag & RX_FLAG_VHT) {
@@ -2549,13 +2551,13 @@ u64 ieee80211_calculate_rx_timestamp(struct ieee80211_local *local,
                ri.mcs = status->rate_idx;
                ri.nss = status->vht_nss;
                if (status->flag & RX_FLAG_40MHZ)
-                       ri.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
-               if (status->vht_flag & RX_VHT_FLAG_80MHZ)
-                       ri.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
-               if (status->vht_flag & RX_VHT_FLAG_80P80MHZ)
-                       ri.flags |= RATE_INFO_FLAGS_80P80_MHZ_WIDTH;
-               if (status->vht_flag & RX_VHT_FLAG_160MHZ)
-                       ri.flags |= RATE_INFO_FLAGS_160_MHZ_WIDTH;
+                       ri.bw = RATE_INFO_BW_40;
+               else if (status->vht_flag & RX_VHT_FLAG_80MHZ)
+                       ri.bw = RATE_INFO_BW_80;
+               else if (status->vht_flag & RX_VHT_FLAG_160MHZ)
+                       ri.bw = RATE_INFO_BW_160;
+               else
+                       ri.bw = RATE_INFO_BW_20;
                if (status->flag & RX_FLAG_SHORT_GI)
                        ri.flags |= RATE_INFO_FLAGS_SHORT_GI;
        } else {
@@ -2563,10 +2565,15 @@ u64 ieee80211_calculate_rx_timestamp(struct ieee80211_local *local,
                int shift = 0;
                int bitrate;
 
-               if (status->flag & RX_FLAG_10MHZ)
+               if (status->flag & RX_FLAG_10MHZ) {
                        shift = 1;
-               if (status->flag & RX_FLAG_5MHZ)
+                       ri.bw = RATE_INFO_BW_10;
+               } else if (status->flag & RX_FLAG_5MHZ) {
                        shift = 2;
+                       ri.bw = RATE_INFO_BW_5;
+               } else {
+                       ri.bw = RATE_INFO_BW_20;
+               }
 
                sband = local->hw.wiphy->bands[status->band];
                bitrate = sband->bitrates[status->rate_idx].bitrate;
index 456e4c3..3af0ecf 100644 (file)
@@ -21,7 +21,6 @@
 #include <linux/sched.h>
 #include <net/genetlink.h>
 #include <net/cfg80211.h>
-#include <net/rtnetlink.h>
 #include "nl80211.h"
 #include "core.h"
 #include "sysfs.h"
@@ -964,10 +963,6 @@ void cfg80211_stop_iface(struct wiphy *wiphy, struct wireless_dev *wdev,
 }
 EXPORT_SYMBOL(cfg80211_stop_iface);
 
-static const struct rtnl_link_ops wireless_link_ops = {
-       .kind = "wlan",
-};
-
 static int cfg80211_netdev_notifier_call(struct notifier_block *nb,
                                         unsigned long state, void *ptr)
 {
@@ -986,7 +981,6 @@ static int cfg80211_netdev_notifier_call(struct notifier_block *nb,
        switch (state) {
        case NETDEV_POST_INIT:
                SET_NETDEV_DEVTYPE(dev, &wiphy_type);
-               dev->rtnl_link_ops = &wireless_link_ops;
                break;
        case NETDEV_REGISTER:
                /*
index 4ed9039..4fc812f 100644 (file)
@@ -3580,6 +3580,7 @@ static bool nl80211_put_sta_rate(struct sk_buff *msg, struct rate_info *info,
        struct nlattr *rate;
        u32 bitrate;
        u16 bitrate_compat;
+       enum nl80211_attrs rate_flg;
 
        rate = nla_nest_start(msg, attr);
        if (!rate)
@@ -3596,12 +3597,36 @@ static bool nl80211_put_sta_rate(struct sk_buff *msg, struct rate_info *info,
            nla_put_u16(msg, NL80211_RATE_INFO_BITRATE, bitrate_compat))
                return false;
 
+       switch (info->bw) {
+       case RATE_INFO_BW_5:
+               rate_flg = NL80211_RATE_INFO_5_MHZ_WIDTH;
+               break;
+       case RATE_INFO_BW_10:
+               rate_flg = NL80211_RATE_INFO_10_MHZ_WIDTH;
+               break;
+       default:
+               WARN_ON(1);
+               /* fall through */
+       case RATE_INFO_BW_20:
+               rate_flg = 0;
+               break;
+       case RATE_INFO_BW_40:
+               rate_flg = NL80211_RATE_INFO_40_MHZ_WIDTH;
+               break;
+       case RATE_INFO_BW_80:
+               rate_flg = NL80211_RATE_INFO_80_MHZ_WIDTH;
+               break;
+       case RATE_INFO_BW_160:
+               rate_flg = NL80211_RATE_INFO_160_MHZ_WIDTH;
+               break;
+       }
+
+       if (rate_flg && nla_put_flag(msg, rate_flg))
+               return false;
+
        if (info->flags & RATE_INFO_FLAGS_MCS) {
                if (nla_put_u8(msg, NL80211_RATE_INFO_MCS, info->mcs))
                        return false;
-               if (info->flags & RATE_INFO_FLAGS_40_MHZ_WIDTH &&
-                   nla_put_flag(msg, NL80211_RATE_INFO_40_MHZ_WIDTH))
-                       return false;
                if (info->flags & RATE_INFO_FLAGS_SHORT_GI &&
                    nla_put_flag(msg, NL80211_RATE_INFO_SHORT_GI))
                        return false;
@@ -3610,18 +3635,6 @@ static bool nl80211_put_sta_rate(struct sk_buff *msg, struct rate_info *info,
                        return false;
                if (nla_put_u8(msg, NL80211_RATE_INFO_VHT_NSS, info->nss))
                        return false;
-               if (info->flags & RATE_INFO_FLAGS_40_MHZ_WIDTH &&
-                   nla_put_flag(msg, NL80211_RATE_INFO_40_MHZ_WIDTH))
-                       return false;
-               if (info->flags & RATE_INFO_FLAGS_80_MHZ_WIDTH &&
-                   nla_put_flag(msg, NL80211_RATE_INFO_80_MHZ_WIDTH))
-                       return false;
-               if (info->flags & RATE_INFO_FLAGS_80P80_MHZ_WIDTH &&
-                   nla_put_flag(msg, NL80211_RATE_INFO_80P80_MHZ_WIDTH))
-                       return false;
-               if (info->flags & RATE_INFO_FLAGS_160_MHZ_WIDTH &&
-                   nla_put_flag(msg, NL80211_RATE_INFO_160_MHZ_WIDTH))
-                       return false;
                if (info->flags & RATE_INFO_FLAGS_SHORT_GI &&
                    nla_put_flag(msg, NL80211_RATE_INFO_SHORT_GI))
                        return false;
@@ -11784,7 +11797,7 @@ void cfg80211_del_sta_sinfo(struct net_device *dev, const u8 *mac_addr,
                return;
 
        if (nl80211_send_station(msg, NL80211_CMD_DEL_STATION, 0, 0, 0,
-                                rdev, dev, mac_addr, sinfo)) {
+                                rdev, dev, mac_addr, sinfo) < 0) {
                nlmsg_free(msg);
                return;
        }
index 1d2fcfa..97c744e 100644 (file)
@@ -1073,10 +1073,24 @@ static u32 cfg80211_calculate_bitrate_vht(struct rate_info *rate)
        if (WARN_ON_ONCE(rate->mcs > 9))
                return 0;
 
-       idx = rate->flags & (RATE_INFO_FLAGS_160_MHZ_WIDTH |
-                            RATE_INFO_FLAGS_80P80_MHZ_WIDTH) ? 3 :
-                 rate->flags & RATE_INFO_FLAGS_80_MHZ_WIDTH ? 2 :
-                 rate->flags & RATE_INFO_FLAGS_40_MHZ_WIDTH ? 1 : 0;
+       switch (rate->bw) {
+       case RATE_INFO_BW_160:
+               idx = 3;
+               break;
+       case RATE_INFO_BW_80:
+               idx = 2;
+               break;
+       case RATE_INFO_BW_40:
+               idx = 1;
+               break;
+       case RATE_INFO_BW_5:
+       case RATE_INFO_BW_10:
+       default:
+               WARN_ON(1);
+               /* fall through */
+       case RATE_INFO_BW_20:
+               idx = 0;
+       }
 
        bitrate = base[idx][rate->mcs];
        bitrate *= rate->nss;
@@ -1107,8 +1121,7 @@ u32 cfg80211_calculate_bitrate(struct rate_info *rate)
        modulation = rate->mcs & 7;
        streams = (rate->mcs >> 3) + 1;
 
-       bitrate = (rate->flags & RATE_INFO_FLAGS_40_MHZ_WIDTH) ?
-                       13500000 : 6500000;
+       bitrate = (rate->bw == RATE_INFO_BW_40) ? 13500000 : 6500000;
 
        if (modulation < 4)
                bitrate *= (modulation + 1);