ath9k: fix an invalid pointer access in the tx path
authorFelix Fietkau <nbd@openwrt.org>
Thu, 14 Jun 2012 21:36:05 +0000 (21:36 +0000)
committerFelix Fietkau <nbd@openwrt.org>
Thu, 14 Jun 2012 21:36:05 +0000 (21:36 +0000)
SVN-Revision: 32376

package/mac80211/patches/300-pending_work.patch
package/mac80211/patches/512-ath9k_channelbw_debugfs.patch
package/mac80211/patches/530-ath9k_limit_qlen.patch
package/mac80211/patches/540-ath9k_extra_leds.patch

index 7319079..9044396 100644 (file)
  }
  #endif
  
+--- a/drivers/net/wireless/ath/ath9k/ath9k.h
++++ b/drivers/net/wireless/ath/ath9k/ath9k.h
+@@ -214,6 +214,7 @@ struct ath_frame_info {
+       enum ath9k_key_type keytype;
+       u8 keyix;
+       u8 retries;
++      bool short_preamble;
+ };
+ struct ath_buf_state {
+--- a/drivers/net/wireless/ath/ath9k/xmit.c
++++ b/drivers/net/wireless/ath/ath9k/xmit.c
+@@ -938,6 +938,7 @@ static void ath_buf_set_rate(struct ath_
+       struct ieee80211_tx_rate *rates;
+       const struct ieee80211_rate *rate;
+       struct ieee80211_hdr *hdr;
++      struct ath_frame_info *fi = get_frame_info(bf->bf_mpdu);
+       int i;
+       u8 rix = 0;
+@@ -957,8 +958,7 @@ static void ath_buf_set_rate(struct ath_
+       rate = ieee80211_get_rts_cts_rate(sc->hw, tx_info);
+       info->rtscts_rate = rate->hw_value;
+-      if (tx_info->control.vif &&
+-          tx_info->control.vif->bss_conf.use_short_preamble)
++      if (fi->short_preamble)
+               info->rtscts_rate |= rate->hw_value_short;
+       for (i = 0; i < 4; i++) {
+@@ -1779,6 +1779,11 @@ static void setup_frame_info(struct ieee
+       struct ath_frame_info *fi = get_frame_info(skb);
+       struct ath_node *an = NULL;
+       enum ath9k_key_type keytype;
++      bool short_preamble = false;
++
++      if (tx_info->control.vif &&
++          tx_info->control.vif->bss_conf.use_short_preamble)
++              short_preamble = true;
+       keytype = ath9k_cmn_get_hw_crypto_keytype(skb);
+@@ -1794,6 +1799,7 @@ static void setup_frame_info(struct ieee
+               fi->keyix = ATH9K_TXKEYIX_INVALID;
+       fi->keytype = keytype;
+       fi->framelen = framelen;
++      fi->short_preamble = short_preamble;
+ }
+ u8 ath_txchainmask_reduction(struct ath_softc *sc, u8 chainmask, u32 rate)
index 637fada..6410a6e 100644 (file)
@@ -1,6 +1,6 @@
 --- a/drivers/net/wireless/ath/ath9k/ath9k.h
 +++ b/drivers/net/wireless/ath/ath9k/ath9k.h
-@@ -620,6 +620,7 @@ struct ath_softc {
+@@ -621,6 +621,7 @@ struct ath_softc {
        struct ieee80211_hw *hw;
        struct device *dev;
  
@@ -8,7 +8,7 @@
        struct survey_info *cur_survey;
        struct survey_info survey[ATH9K_NUM_CHANNELS];
  
-@@ -687,6 +688,7 @@ struct ath_softc {
+@@ -688,6 +689,7 @@ struct ath_softc {
        struct dfs_pattern_detector *dfs_detector;
  };
  
index 22b4102..f4eb51e 100644 (file)
@@ -1,6 +1,6 @@
 --- a/drivers/net/wireless/ath/ath9k/ath9k.h
 +++ b/drivers/net/wireless/ath/ath9k/ath9k.h
-@@ -243,6 +243,7 @@ struct ath_atx_tid {
+@@ -244,6 +244,7 @@ struct ath_atx_tid {
        struct ath_node *an;
        struct ath_atx_ac *ac;
        unsigned long tx_buf[BITS_TO_LONGS(ATH_TID_MAX_BUFS)];
@@ -8,7 +8,7 @@
        int bar_index;
        u16 seq_start;
        u16 seq_next;
-@@ -289,6 +290,9 @@ struct ath_tx_control {
+@@ -290,6 +291,9 @@ struct ath_tx_control {
   *  (axq_qnum).
   */
  struct ath_tx {
@@ -74,7 +74,7 @@
        /* Queue to h/w without aggregation */
        TX_STAT_INC(txctl->txq->axq_qnum, a_queued_hw);
        bf->bf_lastbf = bf;
-@@ -1873,22 +1886,11 @@ error:
+@@ -1879,22 +1892,11 @@ error:
  
  /* FIXME: tx power */
  static void ath_tx_start_dma(struct ath_softc *sc, struct sk_buff *skb,
@@ -99,7 +99,7 @@
  
        if ((tx_info->flags & IEEE80211_TX_CTL_AMPDU) && tid) {
                /*
-@@ -1920,6 +1922,7 @@ int ath_tx_start(struct ieee80211_hw *hw
+@@ -1926,6 +1928,7 @@ int ath_tx_start(struct ieee80211_hw *hw
        struct ieee80211_vif *vif = info->control.vif;
        struct ath_softc *sc = hw->priv;
        struct ath_txq *txq = txctl->txq;
        int padpos, padsize;
        int frmlen = skb->len + FCS_LEN;
        int q;
-@@ -1962,6 +1965,24 @@ int ath_tx_start(struct ieee80211_hw *hw
+@@ -1968,6 +1971,24 @@ int ath_tx_start(struct ieee80211_hw *hw
  
        setup_frame_info(hw, skb, frmlen);
  
        /*
         * At this point, the vif, hw_key and sta pointers in the tx control
         * info are no longer valid (overwritten by the ath_frame_info data.
-@@ -1976,7 +1997,7 @@ int ath_tx_start(struct ieee80211_hw *hw
+@@ -1982,7 +2003,7 @@ int ath_tx_start(struct ieee80211_hw *hw
                txq->stopped = true;
        }
  
index a34a4e1..250e9cf 100644 (file)
@@ -1,6 +1,6 @@
 --- a/drivers/net/wireless/ath/ath9k/ath9k.h
 +++ b/drivers/net/wireless/ath/ath9k/ath9k.h
-@@ -507,6 +507,9 @@ static inline u16 ath9k_btcoex_aggr_limi
+@@ -508,6 +508,9 @@ static inline u16 ath9k_btcoex_aggr_limi
  #ifdef CONFIG_MAC80211_LEDS
  void ath_init_leds(struct ath_softc *sc);
  void ath_deinit_leds(struct ath_softc *sc);
@@ -10,7 +10,7 @@
  #else
  static inline void ath_init_leds(struct ath_softc *sc)
  {
-@@ -620,6 +623,13 @@ struct ath9k_vif_iter_data {
+@@ -621,6 +624,13 @@ struct ath9k_vif_iter_data {
        int nadhocs;   /* number of adhoc vifs */
  };
  
@@ -24,7 +24,7 @@
  struct ath_softc {
        struct ieee80211_hw *hw;
        struct device *dev;
-@@ -661,9 +671,8 @@ struct ath_softc {
+@@ -662,9 +672,8 @@ struct ath_softc {
        struct ieee80211_supported_band sbands[IEEE80211_NUM_BANDS];
  
  #ifdef CONFIG_MAC80211_LEDS