ath9k: fix rx issues introduced in my last commit (fixes #14307)
[openwrt.git] / package / kernel / mac80211 / patches / 300-pending_work.patch
index 28f6a5b..94b3076 100644 (file)
  
  bool is_ath9k_unloaded;
  /* We use the hw_value as an index into our private channel structure */
-@@ -429,7 +429,6 @@ static int ath9k_init_queues(struct ath_
+@@ -339,7 +339,6 @@ int ath_descdma_setup(struct ath_softc *
+ {
+       struct ath_common *common = ath9k_hw_common(sc->sc_ah);
+       u8 *ds;
+-      struct ath_buf *bf;
+       int i, bsize, desc_len;
+       ath_dbg(common, CONFIG, "%s DMA: %u buffers %u desc/buf\n",
+@@ -391,33 +390,68 @@ int ath_descdma_setup(struct ath_softc *
+               ito64(dd->dd_desc_paddr), /*XXX*/(u32) dd->dd_desc_len);
+       /* allocate buffers */
+-      bsize = sizeof(struct ath_buf) * nbuf;
+-      bf = devm_kzalloc(sc->dev, bsize, GFP_KERNEL);
+-      if (!bf)
+-              return -ENOMEM;
++      if (is_tx) {
++              struct ath_buf *bf;
++
++              bsize = sizeof(struct ath_buf) * nbuf;
++              bf = devm_kzalloc(sc->dev, bsize, GFP_KERNEL);
++              if (!bf)
++                      return -ENOMEM;
++
++              for (i = 0; i < nbuf; i++, bf++, ds += (desc_len * ndesc)) {
++                      bf->bf_desc = ds;
++                      bf->bf_daddr = DS2PHYS(dd, ds);
++
++                      if (!(sc->sc_ah->caps.hw_caps &
++                                ATH9K_HW_CAP_4KB_SPLITTRANS)) {
++                              /*
++                               * Skip descriptor addresses which can cause 4KB
++                               * boundary crossing (addr + length) with a 32 dword
++                               * descriptor fetch.
++                               */
++                              while (ATH_DESC_4KB_BOUND_CHECK(bf->bf_daddr)) {
++                                      BUG_ON((caddr_t) bf->bf_desc >=
++                                                 ((caddr_t) dd->dd_desc +
++                                              dd->dd_desc_len));
++
++                                      ds += (desc_len * ndesc);
++                                      bf->bf_desc = ds;
++                                      bf->bf_daddr = DS2PHYS(dd, ds);
++                              }
++                      }
++                      list_add_tail(&bf->list, head);
++              }
++      } else {
++              struct ath_rxbuf *bf;
+-      for (i = 0; i < nbuf; i++, bf++, ds += (desc_len * ndesc)) {
+-              bf->bf_desc = ds;
+-              bf->bf_daddr = DS2PHYS(dd, ds);
+-
+-              if (!(sc->sc_ah->caps.hw_caps &
+-                    ATH9K_HW_CAP_4KB_SPLITTRANS)) {
+-                      /*
+-                       * Skip descriptor addresses which can cause 4KB
+-                       * boundary crossing (addr + length) with a 32 dword
+-                       * descriptor fetch.
+-                       */
+-                      while (ATH_DESC_4KB_BOUND_CHECK(bf->bf_daddr)) {
+-                              BUG_ON((caddr_t) bf->bf_desc >=
+-                                     ((caddr_t) dd->dd_desc +
+-                                      dd->dd_desc_len));
+-
+-                              ds += (desc_len * ndesc);
+-                              bf->bf_desc = ds;
+-                              bf->bf_daddr = DS2PHYS(dd, ds);
++              bsize = sizeof(struct ath_buf) * nbuf;
++              bf = devm_kzalloc(sc->dev, bsize, GFP_KERNEL);
++              if (!bf)
++                      return -ENOMEM;
++
++              for (i = 0; i < nbuf; i++, bf++, ds += (desc_len * ndesc)) {
++                      bf->bf_desc = ds;
++                      bf->bf_daddr = DS2PHYS(dd, ds);
++
++                      if (!(sc->sc_ah->caps.hw_caps &
++                                ATH9K_HW_CAP_4KB_SPLITTRANS)) {
++                              /*
++                               * Skip descriptor addresses which can cause 4KB
++                               * boundary crossing (addr + length) with a 32 dword
++                               * descriptor fetch.
++                               */
++                              while (ATH_DESC_4KB_BOUND_CHECK(bf->bf_daddr)) {
++                                      BUG_ON((caddr_t) bf->bf_desc >=
++                                                 ((caddr_t) dd->dd_desc +
++                                              dd->dd_desc_len));
++
++                                      ds += (desc_len * ndesc);
++                                      bf->bf_desc = ds;
++                                      bf->bf_daddr = DS2PHYS(dd, ds);
++                              }
+                       }
++                      list_add_tail(&bf->list, head);
+               }
+-              list_add_tail(&bf->list, head);
+       }
+       return 0;
+ }
+@@ -429,7 +463,6 @@ static int ath9k_init_queues(struct ath_
        sc->beacon.beaconq = ath9k_hw_beaconq_setup(sc->sc_ah);
        sc->beacon.cabq = ath_txq_setup(sc, ATH9K_TX_QUEUE_CAB, 0);
  
        ath_cabq_update(sc);
  
        sc->tx.uapsdq = ath_txq_setup(sc, ATH9K_TX_QUEUE_UAPSD, 0);
-@@ -516,6 +515,7 @@ static void ath9k_init_misc(struct ath_s
+@@ -516,6 +549,7 @@ static void ath9k_init_misc(struct ath_s
  static void ath9k_init_platform(struct ath_softc *sc)
  {
        struct ath_hw *ah = sc->sc_ah;
        struct ath_common *common = ath9k_hw_common(ah);
  
        if (common->bus_ops->ath_bus_type != ATH_PCI)
-@@ -525,12 +525,27 @@ static void ath9k_init_platform(struct a
+@@ -525,12 +559,27 @@ static void ath9k_init_platform(struct a
                               ATH9K_PCI_CUS230)) {
                ah->config.xlna_gpio = 9;
                ah->config.xatten_margin_cfg = true;
        }
  }
  
-@@ -584,6 +599,7 @@ static int ath9k_init_softc(u16 devid, s
+@@ -584,6 +633,7 @@ static int ath9k_init_softc(u16 devid, s
  {
        struct ath9k_platform_data *pdata = sc->dev->platform_data;
        struct ath_hw *ah = NULL;
        struct ath_common *common;
        int ret = 0, i;
        int csz = 0;
-@@ -600,6 +616,7 @@ static int ath9k_init_softc(u16 devid, s
+@@ -600,6 +650,7 @@ static int ath9k_init_softc(u16 devid, s
        ah->reg_ops.rmw = ath9k_reg_rmw;
        atomic_set(&ah->intr_ref_cnt, -1);
        sc->sc_ah = ah;
  
        sc->dfs_detector = dfs_pattern_detector_init(ah, NL80211_DFS_UNSET);
  
-@@ -631,11 +648,15 @@ static int ath9k_init_softc(u16 devid, s
+@@ -631,11 +682,15 @@ static int ath9k_init_softc(u16 devid, s
        ath9k_init_platform(sc);
  
        /*
  
        spin_lock_init(&common->cc_lock);
  
-@@ -710,13 +731,15 @@ static void ath9k_init_band_txpower(stru
+@@ -710,13 +765,15 @@ static void ath9k_init_band_txpower(stru
        struct ieee80211_supported_band *sband;
        struct ieee80211_channel *chan;
        struct ath_hw *ah = sc->sc_ah;
                ath9k_hw_set_txpowerlimit(ah, MAX_RATE_POWER, true);
        }
  }
-@@ -802,7 +825,8 @@ void ath9k_set_hw_capab(struct ath_softc
+@@ -802,7 +859,8 @@ void ath9k_set_hw_capab(struct ath_softc
                IEEE80211_HW_PS_NULLFUNC_STACK |
                IEEE80211_HW_SPECTRUM_MGMT |
                IEEE80211_HW_REPORTS_TX_ACK_STATUS |