mac80211: fix various components for the new 5 and 10 MHz widths
authorSimon Wunderlich <simon.wunderlich@s2003.tu-chemnitz.de>
Thu, 16 May 2013 11:00:31 +0000 (13:00 +0200)
committerJohannes Berg <johannes.berg@intel.com>
Tue, 18 Jun 2013 14:17:11 +0000 (16:17 +0200)
This is a collection of minor fixes:
 * don't allow HT IEs in IBSS for 5/10 MHz
 * don't allow HT IEs in Mesh for 5/10 MHz
 * don't downgrade from/to 5 and 10 MHz channels
 * don't try HT rates for 5 and 10 MHz channels when selecting rates

Signed-off-by: Simon Wunderlich <siwu@hrz.tu-chemnitz.de>
Signed-off-by: Mathias Kretschmer <mathias.kretschmer@fokus.fraunhofer.de>
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
net/mac80211/ibss.c
net/mac80211/mesh.c
net/mac80211/mesh_plink.c
net/mac80211/mlme.c
net/mac80211/rate.c

index caa4b4f..3789c85 100644 (file)
@@ -176,6 +176,8 @@ static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
 
        /* add HT capability and information IEs */
        if (chandef.width != NL80211_CHAN_WIDTH_20_NOHT &&
+           chandef.width != NL80211_CHAN_WIDTH_5 &&
+           chandef.width != NL80211_CHAN_WIDTH_10 &&
            sband->ht_cap.ht_supported) {
                pos = ieee80211_ie_build_ht_cap(pos, &sband->ht_cap,
                                                sband->ht_cap.cap);
index d5dea94..447f41b 100644 (file)
@@ -416,7 +416,9 @@ int mesh_add_ht_cap_ie(struct ieee80211_sub_if_data *sdata,
 
        sband = local->hw.wiphy->bands[band];
        if (!sband->ht_cap.ht_supported ||
-           sdata->vif.bss_conf.chandef.width == NL80211_CHAN_WIDTH_20_NOHT)
+           sdata->vif.bss_conf.chandef.width == NL80211_CHAN_WIDTH_20_NOHT ||
+           sdata->vif.bss_conf.chandef.width == NL80211_CHAN_WIDTH_5 ||
+           sdata->vif.bss_conf.chandef.width == NL80211_CHAN_WIDTH_10)
                return 0;
 
        if (skb_tailroom(skb) < 2 + sizeof(struct ieee80211_ht_cap))
index 09bebed..02c05fa 100644 (file)
@@ -154,8 +154,14 @@ static u32 mesh_set_ht_prot_mode(struct ieee80211_sub_if_data *sdata)
        u16 ht_opmode;
        bool non_ht_sta = false, ht20_sta = false;
 
-       if (sdata->vif.bss_conf.chandef.width == NL80211_CHAN_WIDTH_20_NOHT)
+       switch (sdata->vif.bss_conf.chandef.width) {
+       case NL80211_CHAN_WIDTH_20_NOHT:
+       case NL80211_CHAN_WIDTH_5:
+       case NL80211_CHAN_WIDTH_10:
                return 0;
+       default:
+               break;
+       }
 
        rcu_read_lock();
        list_for_each_entry_rcu(sta, &local->sta_list, list) {
index 87f2d4d..e0939eb 100644 (file)
@@ -190,6 +190,12 @@ static u32 chandef_downgrade(struct cfg80211_chan_def *c)
                c->width = NL80211_CHAN_WIDTH_20_NOHT;
                ret = IEEE80211_STA_DISABLE_HT | IEEE80211_STA_DISABLE_VHT;
                break;
+       case NL80211_CHAN_WIDTH_5:
+       case NL80211_CHAN_WIDTH_10:
+               WARN_ON_ONCE(1);
+               /* keep c->width */
+               ret = IEEE80211_STA_DISABLE_HT | IEEE80211_STA_DISABLE_VHT;
+               break;
        }
 
        WARN_ON_ONCE(!cfg80211_chandef_valid(c));
@@ -3771,6 +3777,12 @@ static int ieee80211_prep_channel(struct ieee80211_sub_if_data *sdata,
         */
        ret = ieee80211_vif_use_channel(sdata, &chandef,
                                        IEEE80211_CHANCTX_SHARED);
+
+       /* don't downgrade for 5 and 10 MHz channels, though. */
+       if (chandef.width == NL80211_CHAN_WIDTH_5 ||
+           chandef.width == NL80211_CHAN_WIDTH_10)
+               return ret;
+
        while (ret && chandef.width != NL80211_CHAN_WIDTH_20_NOHT) {
                ifmgd->flags |= chandef_downgrade(&chandef);
                ret = ieee80211_vif_use_channel(sdata, &chandef,
index d3f414f..dbbcd57 100644 (file)
@@ -397,8 +397,14 @@ static void rate_idx_match_mask(struct ieee80211_tx_rate *rate,
                        return;
 
                /* if HT BSS, and we handle a data frame, also try HT rates */
-               if (chan_width == NL80211_CHAN_WIDTH_20_NOHT)
+               switch (chan_width) {
+               case NL80211_CHAN_WIDTH_20_NOHT:
+               case NL80211_CHAN_WIDTH_5:
+               case NL80211_CHAN_WIDTH_10:
                        return;
+               default:
+                       break;
+               }
 
                alt_rate.idx = 0;
                /* keep protection flags */