ath9k: fix some issues with ar934x rev 3 (especially ad-hoc mode)
[openwrt/openwrt.git] / package / kernel / mac80211 / patches / 300-pending_work.patch
index 62a2d68da0907cf641728af1d96af9ed3f82f0c6..1ee8e9833a1ecd5bdf9c65dd75856cdc8a300163 100644 (file)
@@ -1,3 +1,30 @@
+commit 4c82fc569cf2f29e6c66d98ef4a1b0f3b6a98e9d
+Author: Felix Fietkau <nbd@openwrt.org>
+Date:   Sat Sep 27 22:39:27 2014 +0200
+
+    ath9k_hw: disable hardware ad-hoc flag on ar934x rev 3
+    
+    On AR934x rev 3, settin the ad-hoc flag completely messes up hardware
+    state - beacons get stuck, almost no packets make it out, hardware is
+    constantly reset.
+    
+    When leaving out that flag and setting up the hw like in AP mode, TSF
+    timers won't be automatically synced, but at least the rest works.
+    
+    AR934x rev 2 and older are not affected by this bug
+    
+    Signed-off-by: Felix Fietkau <nbd@openwrt.org>
+
+commit ecfb4b3fff006372ac5c40871f9bb182fd00444f
+Author: Felix Fietkau <nbd@openwrt.org>
+Date:   Sat Sep 27 22:15:43 2014 +0200
+
+    ath9k: use ah->get_mac_revision for all SoC devices if available
+    
+    It is needed for AR934x as well
+    
+    Signed-off-by: Felix Fietkau <nbd@openwrt.org>
+
 commit c11113bc25df22898fb995d3205bdc4f27c98073
 Author: Felix Fietkau <nbd@openwrt.org>
 Date:   Sat Sep 27 18:04:58 2014 +0200
@@ -411,3 +438,70 @@ Date:   Sat Sep 27 15:57:09 2014 +0200
  #include "debug.h"
  #include "ath5k.h"
  #include "reg.h"
+--- a/drivers/net/wireless/ath/ath9k/hw.c
++++ b/drivers/net/wireless/ath/ath9k/hw.c
+@@ -222,31 +222,28 @@ static void ath9k_hw_read_revisions(stru
+ {
+       u32 val;
++      if (ah->get_mac_revision)
++              ah->hw_version.macRev = ah->get_mac_revision();
++
+       switch (ah->hw_version.devid) {
+       case AR5416_AR9100_DEVID:
+               ah->hw_version.macVersion = AR_SREV_VERSION_9100;
+               break;
+       case AR9300_DEVID_AR9330:
+               ah->hw_version.macVersion = AR_SREV_VERSION_9330;
+-              if (ah->get_mac_revision) {
+-                      ah->hw_version.macRev = ah->get_mac_revision();
+-              } else {
++              if (!ah->get_mac_revision) {
+                       val = REG_READ(ah, AR_SREV);
+                       ah->hw_version.macRev = MS(val, AR_SREV_REVISION2);
+               }
+               return;
+       case AR9300_DEVID_AR9340:
+               ah->hw_version.macVersion = AR_SREV_VERSION_9340;
+-              val = REG_READ(ah, AR_SREV);
+-              ah->hw_version.macRev = MS(val, AR_SREV_REVISION2);
+               return;
+       case AR9300_DEVID_QCA955X:
+               ah->hw_version.macVersion = AR_SREV_VERSION_9550;
+               return;
+       case AR9300_DEVID_AR953X:
+               ah->hw_version.macVersion = AR_SREV_VERSION_9531;
+-              if (ah->get_mac_revision)
+-                      ah->hw_version.macRev = ah->get_mac_revision();
+               return;
+       }
+@@ -1192,9 +1189,12 @@ static void ath9k_hw_set_operating_mode(
+       switch (opmode) {
+       case NL80211_IFTYPE_ADHOC:
+-              set |= AR_STA_ID1_ADHOC;
+-              REG_SET_BIT(ah, AR_CFG, AR_CFG_AP_ADHOC_INDICATION);
+-              break;
++              if (!AR_SREV_9340_13(ah)) {
++                      set |= AR_STA_ID1_ADHOC;
++                      REG_SET_BIT(ah, AR_CFG, AR_CFG_AP_ADHOC_INDICATION);
++                      break;
++              }
++              /* fall through */
+       case NL80211_IFTYPE_MESH_POINT:
+       case NL80211_IFTYPE_AP:
+               set |= AR_STA_ID1_STA_AP;
+--- a/drivers/net/wireless/ath/ath9k/reg.h
++++ b/drivers/net/wireless/ath/ath9k/reg.h
+@@ -903,6 +903,10 @@
+ #define AR_SREV_9340(_ah) \
+       (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9340))
++#define AR_SREV_9340_13(_ah) \
++      (AR_SREV_9340((_ah)) && \
++       ((_ah)->hw_version.macRev == AR_SREV_REVISION_9340_13))
++
+ #define AR_SREV_9340_13_OR_LATER(_ah) \
+       (AR_SREV_9340((_ah)) && \
+        ((_ah)->hw_version.macRev >= AR_SREV_REVISION_9340_13))