mac80211: merge a few ad-hoc mode fixes
authorFelix Fietkau <nbd@openwrt.org>
Mon, 26 Aug 2013 17:31:23 +0000 (17:31 +0000)
committerFelix Fietkau <nbd@openwrt.org>
Mon, 26 Aug 2013 17:31:23 +0000 (17:31 +0000)
Signed-off-by: Felix Fietkau <nbd@openwrt.org>
SVN-Revision: 37840

package/kernel/mac80211/patches/300-pending_work.patch

index 071d62f583bb8f6fd4870f1b55dee2a51c56eae9..11b9ec4c3bc4d3f9d79168cdcb397f8d8eaef5ca 100644 (file)
  
        /*
         * Downgrade the new channel if we associated with restricted
-@@ -3394,10 +3405,13 @@ static int ieee80211_probe_auth(struct i
+@@ -1043,6 +1054,13 @@ ieee80211_sta_process_chanswitch(struct 
+               if (!ieee80211_operating_class_to_band(
+                               elems->ext_chansw_ie->new_operating_class,
+                               &new_band)) {
++                      /*
++                       * Some APs send invalid ECSA IEs in probe response
++                       * frames, so check for these and ignore them.
++                       */
++                      if (beacon && elems->ext_chansw_ie->new_ch_num == 0 &&
++                          elems->ext_chansw_ie->new_operating_class == 0)
++                              return;
+                       sdata_info(sdata,
+                                  "cannot understand ECSA IE operating class %d, disconnecting\n",
+                                  elems->ext_chansw_ie->new_operating_class);
+@@ -3394,10 +3412,13 @@ static int ieee80211_probe_auth(struct i
  
        if (tx_flags == 0) {
                auth_data->timeout = jiffies + IEEE80211_AUTH_TIMEOUT;
        }
  
        return 0;
-@@ -3434,7 +3448,11 @@ static int ieee80211_do_assoc(struct iee
+@@ -3434,7 +3455,11 @@ static int ieee80211_do_assoc(struct iee
                assoc_data->timeout_started = true;
                run_again(sdata, assoc_data->timeout);
        } else {
        }
  
        return 0;
-@@ -3829,7 +3847,7 @@ static int ieee80211_prep_channel(struct
+@@ -3829,7 +3854,7 @@ static int ieee80211_prep_channel(struct
        ifmgd->flags |= ieee80211_determine_chantype(sdata, sband,
                                                     cbss->channel,
                                                     ht_oper, vht_oper,
  
 --- a/net/mac80211/ibss.c
 +++ b/net/mac80211/ibss.c
-@@ -792,6 +792,17 @@ static void ieee80211_sta_find_ibss(stru
+@@ -36,7 +36,7 @@
+ static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
+                                     const u8 *bssid, const int beacon_int,
+-                                    struct ieee80211_channel *chan,
++                                    struct cfg80211_chan_def *req_chandef,
+                                     const u32 basic_rates,
+                                     const u16 capability, u64 tsf,
+                                     bool creator)
+@@ -51,6 +51,7 @@ static void __ieee80211_sta_join_ibss(st
+       u32 bss_change;
+       u8 supp_rates[IEEE80211_MAX_SUPP_RATES];
+       struct cfg80211_chan_def chandef;
++      struct ieee80211_channel *chan;
+       struct beacon_data *presp;
+       int frame_len;
+@@ -81,7 +82,9 @@ static void __ieee80211_sta_join_ibss(st
+       sdata->drop_unencrypted = capability & WLAN_CAPABILITY_PRIVACY ? 1 : 0;
+-      chandef = ifibss->chandef;
++      /* make a copy of the chandef, it could be modified below. */
++      chandef = *req_chandef;
++      chan = chandef.chan;
+       if (!cfg80211_reg_can_beacon(local->hw.wiphy, &chandef)) {
+               chandef.width = NL80211_CHAN_WIDTH_20;
+               chandef.center_freq1 = chan->center_freq;
+@@ -259,10 +262,12 @@ static void ieee80211_sta_join_ibss(stru
+       struct cfg80211_bss *cbss =
+               container_of((void *)bss, struct cfg80211_bss, priv);
+       struct ieee80211_supported_band *sband;
++      struct cfg80211_chan_def chandef;
+       u32 basic_rates;
+       int i, j;
+       u16 beacon_int = cbss->beacon_interval;
+       const struct cfg80211_bss_ies *ies;
++      enum nl80211_channel_type chan_type;
+       u64 tsf;
+       sdata_assert_lock(sdata);
+@@ -270,6 +275,26 @@ static void ieee80211_sta_join_ibss(stru
+       if (beacon_int < 10)
+               beacon_int = 10;
++      switch (sdata->u.ibss.chandef.width) {
++      case NL80211_CHAN_WIDTH_20_NOHT:
++      case NL80211_CHAN_WIDTH_20:
++      case NL80211_CHAN_WIDTH_40:
++              chan_type = cfg80211_get_chandef_type(&sdata->u.ibss.chandef);
++              cfg80211_chandef_create(&chandef, cbss->channel, chan_type);
++              break;
++      case NL80211_CHAN_WIDTH_5:
++      case NL80211_CHAN_WIDTH_10:
++              cfg80211_chandef_create(&chandef, cbss->channel,
++                                      NL80211_CHAN_WIDTH_20_NOHT);
++              chandef.width = sdata->u.ibss.chandef.width;
++              break;
++      default:
++              /* fall back to 20 MHz for unsupported modes */
++              cfg80211_chandef_create(&chandef, cbss->channel,
++                                      NL80211_CHAN_WIDTH_20_NOHT);
++              break;
++      }
++
+       sband = sdata->local->hw.wiphy->bands[cbss->channel->band];
+       basic_rates = 0;
+@@ -294,7 +319,7 @@ static void ieee80211_sta_join_ibss(stru
+       __ieee80211_sta_join_ibss(sdata, cbss->bssid,
+                                 beacon_int,
+-                                cbss->channel,
++                                &chandef,
+                                 basic_rates,
+                                 cbss->capability,
+                                 tsf, false);
+@@ -736,7 +761,7 @@ static void ieee80211_sta_create_ibss(st
+               sdata->drop_unencrypted = 0;
+       __ieee80211_sta_join_ibss(sdata, bssid, sdata->vif.bss_conf.beacon_int,
+-                                ifibss->chandef.chan, ifibss->basic_rates,
++                                &ifibss->chandef, ifibss->basic_rates,
+                                 capability, 0, true);
+ }
+@@ -792,6 +817,17 @@ static void ieee80211_sta_find_ibss(stru
                return;
        }
  
        ibss_dbg(sdata, "sta_find_ibss: did not try to join ibss\n");
  
        /* Selected IBSS not found in current scan results - try to scan */
+@@ -1138,6 +1174,7 @@ int ieee80211_ibss_leave(struct ieee8021
+       clear_bit(SDATA_STATE_OFFCHANNEL_BEACON_STOPPED, &sdata->state);
+       ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BEACON_ENABLED |
+                                               BSS_CHANGED_IBSS);
++      ieee80211_vif_release_channel(sdata);
+       synchronize_rcu();
+       kfree(presp);
 --- a/drivers/net/wireless/ath/ath9k/ar9003_phy.c
 +++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.c
 @@ -1173,6 +1173,10 @@ skip_ws_det: