-commit 8c7ae357cc5b6bd037ad2d666e9f3789cf882925
-Author: Rajkumar Manoharan <rmanohar@qti.qualcomm.com>
-Date: Wed Apr 23 15:07:57 2014 +0530
-
- ath9k: fix race in setting ATH_OP_INVALID
-
- The commit "ath9k: move sc_flags to ath_common" moved setting
- ATH_OP_INVALID flag below ieee80211_register_hw. This is causing
- the flag never being cleared randomly as the drv_start is called
- prior to setting flag. Fix this by setting the flag prior to
- register_hw.
-
- Signed-off-by: Rajkumar Manoharan <rmanohar@qti.qualcomm.com>
- Signed-off-by: John W. Linville <linville@tuxdriver.com>
-
-commit c82552c5b0cb1735dbcbad78b1ffc6d3c212dc56
-Author: Tim Harvey <tharvey@gateworks.com>
-Date: Mon Apr 21 16:14:57 2014 -0700
-
- ath9k: add a recv budget
-
- Implement a recv budget so that in cases of high traffic we still allow other
- taskets to get processed.
-
- Without this, we can encounter a host of issues during high wireless traffic
- reception depending on system load including rcu stall's detected (ARM),
- soft lockups, failure to service critical tasks such as watchdog resets,
- and triggering of the tx stuck tasklet.
-
- The same thing was proposed previously by Ben:
- http://www.spinics.net/lists/linux-wireless/msg112891.html
-
- The only difference here is that I make sure only processed packets are counted
- in the budget by checking at the end of the rx loop.
-
- Signed-off-by: Tim Harvey <tharvey@gateworks.com>
- Acked-by: Felix Fietkau <nbd@openwrt.org>
- Signed-off-by: John W. Linville <linville@tuxdriver.com>
-
-commit 3a758134e66ca74a9df792616b5288b2fa2cfd7f
-Author: Tim Harvey <tharvey@gateworks.com>
-Date: Mon Apr 21 16:14:56 2014 -0700
-
- ath9k: fix possible hang on flush
-
- If a flush is requested, make sure to clear the descriptor once we've
- processed it.
-
- This resolves a hang that will occur if all RX descriptors are full when a
- flush is requested.
-
- Signed-off-by: Tim Harvey <tharvey@gateworks.com>
- Acked-by: Felix Fietkau <nbd@openwrt.org>
- Signed-off-by: John W. Linville <linville@tuxdriver.com>
-
-commit eefb1d6adc4c60d219182b8917e4567484ce07fc
+commit 4c82fc569cf2f29e6c66d98ef4a1b0f3b6a98e9d
Author: Felix Fietkau <nbd@openwrt.org>
-Date: Mon Apr 28 18:27:41 2014 +0200
+Date: Sat Sep 27 22:39:27 2014 +0200
- ath9k: remove tid->paused flag
+ ath9k_hw: disable hardware ad-hoc flag on ar934x rev 3
- There are some corner cases where the driver could get stuck with a full
- tid queue that is paused, leading to a software tx queue hang.
+ 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.
- Since the tx queueing rework, pausing per-tid queues on aggregation
- session setup is no longer necessary. The driver will assign sequence
- numbers to buffered frames when a new session is established, in order
- to get the correct starting sequence number.
+ 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.
- mac80211 prevents new frames from entering the queue during setup.
+ AR934x rev 2 and older are not affected by this bug
Signed-off-by: Felix Fietkau <nbd@openwrt.org>
-commit 98a713933d8495f4078f561c1e651b738dd5b531
+commit ecfb4b3fff006372ac5c40871f9bb182fd00444f
Author: Felix Fietkau <nbd@openwrt.org>
-Date: Sun Apr 27 14:49:03 2014 +0200
+Date: Sat Sep 27 22:15:43 2014 +0200
- ath9k_hw: do not lower ANI setting below default on AR913x
-
- When the amount of noise fluctuates strongly, low immunity settings
- can sometimes disrupt signal detection on AR913x chips. When that
- happens, no OFDM/CCK errors are reported anymore, and ANI tunes the
- radio to the lowest immunity settings.
- Usually rx/tx fails as well in that case.
+ ath9k: use ah->get_mac_revision for all SoC devices if available
- To fix this, keep noise immunity settings at or above ANI default level,
- which will keep radio parameters at or above INI values.
+ It is needed for AR934x as well
Signed-off-by: Felix Fietkau <nbd@openwrt.org>
-commit 7cbb4c021bfd1e656f5b9953a947ab3c64e4e3b0
+commit c11113bc25df22898fb995d3205bdc4f27c98073
Author: Felix Fietkau <nbd@openwrt.org>
-Date: Thu Apr 10 10:49:01 2014 +0200
+Date: Sat Sep 27 18:04:58 2014 +0200
- mac80211: exclude AP_VLAN interfaces from tx power calculation
+ ath5k: add missing include for debug code
- Their power value is initialized to zero. This patch fixes an issue
- where the configured power drops to the minimum value when AP_VLAN
- interfaces are created/removed.
+ Needed for calling vmalloc()/vfree()
- Cc: stable@vger.kernel.org
Signed-off-by: Felix Fietkau <nbd@openwrt.org>
-commit 0ca13e26341733bf9577287fb04a3bef0d2f5cc9
+commit 83f76a9f9a42773c7eef90bb86b4b2c16b0b3755
Author: Felix Fietkau <nbd@openwrt.org>
-Date: Wed Apr 9 00:07:01 2014 +0200
+Date: Sat Sep 27 15:58:51 2014 +0200
- mac80211: suppress BSS info change notifications for AP_VLAN
-
- Fixes warnings on tx power changes
+ ath5k: fix AHB kconfig dependency
Signed-off-by: Felix Fietkau <nbd@openwrt.org>
-commit ec998e5991781ecdaad0911dc64f1c8d3749c308
+commit ddd67f2a5cfd73fad4b78190025402d419b9f0a9
Author: Felix Fietkau <nbd@openwrt.org>
-Date: Tue Apr 8 23:42:17 2014 +0200
+Date: Sat Sep 27 15:57:09 2014 +0200
- ath9k: fix a scheduling while atomic bug in CSA handling
-
- Commit "ath9k: prepare for multi-interface CSA support" added a call to
- ieee80211_iterate_active_interfaces in atomic context (beacon tasklet),
- which is crashing.
- Use ieee80211_iterate_active_interfaces_atomic instead.
+ Revert "ath5k: Remove AHB bus support"
- Signed-off-by: Felix Fietkau <nbd@openwrt.org>
-
-commit 93f310a38a1d81a4bc8fcd9bf29628bd721cf2ef
-Author: Felix Fietkau <nbd@openwrt.org>
-Date: Sun Apr 6 23:35:28 2014 +0200
+ This reverts commit 093ec3c5337434f40d77c1af06c139da3e5ba6dc.
- ath9k_hw: reduce ANI firstep range for older chips
-
- Use 0-8 instead of 0-16, which is closer to the old implementation.
- Also drop the overwrite of the firstep_low parameter to improve
- stability.
-
- Signed-off-by: Felix Fietkau <nbd@openwrt.org>
-
-
---- a/drivers/net/wireless/ath/ath9k/ar5008_phy.c
-+++ b/drivers/net/wireless/ath/ath9k/ar5008_phy.c
-@@ -1004,11 +1004,9 @@ static bool ar5008_hw_ani_control_new(st
- case ATH9K_ANI_FIRSTEP_LEVEL:{
- u32 level = param;
-
-- value = level * 2;
-+ value = level;
- REG_RMW_FIELD(ah, AR_PHY_FIND_SIG,
- AR_PHY_FIND_SIG_FIRSTEP, value);
-- REG_RMW_FIELD(ah, AR_PHY_FIND_SIG_LOW,
-- AR_PHY_FIND_SIG_FIRSTEP_LOW, value);
-
- if (level != aniState->firstepLevel) {
- ath_dbg(common, ANI,
---- a/drivers/net/wireless/ath/ath9k/beacon.c
-+++ b/drivers/net/wireless/ath/ath9k/beacon.c
-@@ -312,10 +312,9 @@ static void ath9k_csa_update_vif(void *d
-
- void ath9k_csa_update(struct ath_softc *sc)
- {
-- ieee80211_iterate_active_interfaces(sc->hw,
-- IEEE80211_IFACE_ITER_NORMAL,
-- ath9k_csa_update_vif,
-- sc);
-+ ieee80211_iterate_active_interfaces_atomic(sc->hw,
-+ IEEE80211_IFACE_ITER_NORMAL,
-+ ath9k_csa_update_vif, sc);
+--- a/drivers/net/wireless/ath/ath5k/Kconfig
++++ b/drivers/net/wireless/ath/ath5k/Kconfig
+@@ -2,12 +2,14 @@ config ATH5K
+ tristate "Atheros 5xxx wireless cards support"
+ depends on m
+ depends on PCI && MAC80211
++ depends on (PCI || ATHEROS_AR231X) && MAC80211
+ select ATH_COMMON
+ select MAC80211_LEDS
+ select BACKPORT_LEDS_CLASS
+ select BACKPORT_NEW_LEDS
+ select BACKPORT_AVERAGE
+- select ATH5K_PCI
++ select ATH5K_AHB if ATHEROS_AR231X
++ select ATH5K_PCI if !ATHEROS_AR231X
+ ---help---
+ This module adds support for wireless adapters based on
+ Atheros 5xxx chipset.
+@@ -52,9 +54,16 @@ config ATH5K_TRACER
+
+ If unsure, say N.
+
++config ATH5K_AHB
++ bool "Atheros 5xxx AHB bus support"
++ depends on ATHEROS_AR231X
++ ---help---
++ This adds support for WiSoC type chipsets of the 5xxx Atheros
++ family.
++
+ config ATH5K_PCI
+ bool "Atheros 5xxx PCI bus support"
+- depends on PCI
++ depends on !ATHEROS_AR231X
+ ---help---
+ This adds support for PCI type chipsets of the 5xxx Atheros
+ family.
+--- /dev/null
++++ b/drivers/net/wireless/ath/ath5k/ahb.c
+@@ -0,0 +1,234 @@
++/*
++ * Copyright (c) 2008-2009 Atheros Communications Inc.
++ * Copyright (c) 2009 Gabor Juhos <juhosg@openwrt.org>
++ * Copyright (c) 2009 Imre Kaloz <kaloz@openwrt.org>
++ *
++ * Permission to use, copy, modify, and/or distribute this software for any
++ * purpose with or without fee is hereby granted, provided that the above
++ * copyright notice and this permission notice appear in all copies.
++ *
++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
++ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
++ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
++ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
++ */
++
++#include <linux/nl80211.h>
++#include <linux/platform_device.h>
++#include <linux/etherdevice.h>
++#include <linux/export.h>
++#include <ar231x_platform.h>
++#include "ath5k.h"
++#include "debug.h"
++#include "base.h"
++#include "reg.h"
++
++/* return bus cachesize in 4B word units */
++static void ath5k_ahb_read_cachesize(struct ath_common *common, int *csz)
++{
++ *csz = L1_CACHE_BYTES >> 2;
++}
++
++static bool
++ath5k_ahb_eeprom_read(struct ath_common *common, u32 off, u16 *data)
++{
++ struct ath5k_hw *ah = common->priv;
++ struct platform_device *pdev = to_platform_device(ah->dev);
++ struct ar231x_board_config *bcfg = dev_get_platdata(&pdev->dev);
++ u16 *eeprom, *eeprom_end;
++
++ eeprom = (u16 *) bcfg->radio;
++ eeprom_end = ((void *) bcfg->config) + BOARD_CONFIG_BUFSZ;
++
++ eeprom += off;
++ if (eeprom > eeprom_end)
++ return false;
++
++ *data = *eeprom;
++ return true;
++}
++
++int ath5k_hw_read_srev(struct ath5k_hw *ah)
++{
++ struct platform_device *pdev = to_platform_device(ah->dev);
++ struct ar231x_board_config *bcfg = dev_get_platdata(&pdev->dev);
++ ah->ah_mac_srev = bcfg->devid;
++ return 0;
++}
++
++static int ath5k_ahb_eeprom_read_mac(struct ath5k_hw *ah, u8 *mac)
++{
++ struct platform_device *pdev = to_platform_device(ah->dev);
++ struct ar231x_board_config *bcfg = dev_get_platdata(&pdev->dev);
++ u8 *cfg_mac;
++
++ if (to_platform_device(ah->dev)->id == 0)
++ cfg_mac = bcfg->config->wlan0_mac;
++ else
++ cfg_mac = bcfg->config->wlan1_mac;
++
++ memcpy(mac, cfg_mac, ETH_ALEN);
++ return 0;
++}
++
++static const struct ath_bus_ops ath_ahb_bus_ops = {
++ .ath_bus_type = ATH_AHB,
++ .read_cachesize = ath5k_ahb_read_cachesize,
++ .eeprom_read = ath5k_ahb_eeprom_read,
++ .eeprom_read_mac = ath5k_ahb_eeprom_read_mac,
++};
++
++/*Initialization*/
++static int ath_ahb_probe(struct platform_device *pdev)
++{
++ struct ar231x_board_config *bcfg = dev_get_platdata(&pdev->dev);
++ struct ath5k_hw *ah;
++ struct ieee80211_hw *hw;
++ struct resource *res;
++ void __iomem *mem;
++ int irq;
++ int ret = 0;
++ u32 reg;
++
++ if (!dev_get_platdata(&pdev->dev)) {
++ dev_err(&pdev->dev, "no platform data specified\n");
++ ret = -EINVAL;
++ goto err_out;
++ }
++
++ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
++ if (res == NULL) {
++ dev_err(&pdev->dev, "no memory resource found\n");
++ ret = -ENXIO;
++ goto err_out;
++ }
++
++ mem = ioremap_nocache(res->start, resource_size(res));
++ if (mem == NULL) {
++ dev_err(&pdev->dev, "ioremap failed\n");
++ ret = -ENOMEM;
++ goto err_out;
++ }
++
++ res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
++ if (res == NULL) {
++ dev_err(&pdev->dev, "no IRQ resource found\n");
++ ret = -ENXIO;
++ goto err_iounmap;
++ }
++
++ irq = res->start;
++
++ hw = ieee80211_alloc_hw(sizeof(struct ath5k_hw), &ath5k_hw_ops);
++ if (hw == NULL) {
++ dev_err(&pdev->dev, "no memory for ieee80211_hw\n");
++ ret = -ENOMEM;
++ goto err_iounmap;
++ }
++
++ ah = hw->priv;
++ ah->hw = hw;
++ ah->dev = &pdev->dev;
++ ah->iobase = mem;
++ ah->irq = irq;
++ ah->devid = bcfg->devid;
++
++ if (bcfg->devid >= AR5K_SREV_AR2315_R6) {
++ /* Enable WMAC AHB arbitration */
++ reg = ioread32((void __iomem *) AR5K_AR2315_AHB_ARB_CTL);
++ reg |= AR5K_AR2315_AHB_ARB_CTL_WLAN;
++ iowrite32(reg, (void __iomem *) AR5K_AR2315_AHB_ARB_CTL);
++
++ /* Enable global WMAC swapping */
++ reg = ioread32((void __iomem *) AR5K_AR2315_BYTESWAP);
++ reg |= AR5K_AR2315_BYTESWAP_WMAC;
++ iowrite32(reg, (void __iomem *) AR5K_AR2315_BYTESWAP);
++ } else {
++ /* Enable WMAC DMA access (assuming 5312 or 231x*/
++ /* TODO: check other platforms */
++ reg = ioread32((void __iomem *) AR5K_AR5312_ENABLE);
++ if (to_platform_device(ah->dev)->id == 0)
++ reg |= AR5K_AR5312_ENABLE_WLAN0;
++ else
++ reg |= AR5K_AR5312_ENABLE_WLAN1;
++ iowrite32(reg, (void __iomem *) AR5K_AR5312_ENABLE);
++
++ /*
++ * On a dual-band AR5312, the multiband radio is only
++ * used as pass-through. Disable 2 GHz support in the
++ * driver for it
++ */
++ if (to_platform_device(ah->dev)->id == 0 &&
++ (bcfg->config->flags & (BD_WLAN0 | BD_WLAN1)) ==
++ (BD_WLAN1 | BD_WLAN0))
++ ah->ah_capabilities.cap_needs_2GHz_ovr = true;
++ else
++ ah->ah_capabilities.cap_needs_2GHz_ovr = false;
++ }
++
++ ret = ath5k_init_ah(ah, &ath_ahb_bus_ops);
++ if (ret != 0) {
++ dev_err(&pdev->dev, "failed to attach device, err=%d\n", ret);
++ ret = -ENODEV;
++ goto err_free_hw;
++ }
++
++ platform_set_drvdata(pdev, hw);
++
++ return 0;
++
++ err_free_hw:
++ ieee80211_free_hw(hw);
++ err_iounmap:
++ iounmap(mem);
++ err_out:
++ return ret;
++}
++
++static int ath_ahb_remove(struct platform_device *pdev)
++{
++ struct ar231x_board_config *bcfg = dev_get_platdata(&pdev->dev);
++ struct ieee80211_hw *hw = platform_get_drvdata(pdev);
++ struct ath5k_hw *ah;
++ u32 reg;
++
++ if (!hw)
++ return 0;
++
++ ah = hw->priv;
++
++ if (bcfg->devid >= AR5K_SREV_AR2315_R6) {
++ /* Disable WMAC AHB arbitration */
++ reg = ioread32((void __iomem *) AR5K_AR2315_AHB_ARB_CTL);
++ reg &= ~AR5K_AR2315_AHB_ARB_CTL_WLAN;
++ iowrite32(reg, (void __iomem *) AR5K_AR2315_AHB_ARB_CTL);
++ } else {
++ /*Stop DMA access */
++ reg = ioread32((void __iomem *) AR5K_AR5312_ENABLE);
++ if (to_platform_device(ah->dev)->id == 0)
++ reg &= ~AR5K_AR5312_ENABLE_WLAN0;
++ else
++ reg &= ~AR5K_AR5312_ENABLE_WLAN1;
++ iowrite32(reg, (void __iomem *) AR5K_AR5312_ENABLE);
++ }
++
++ ath5k_deinit_ah(ah);
++ iounmap(ah->iobase);
++ ieee80211_free_hw(hw);
++
++ return 0;
++}
++
++static struct platform_driver ath_ahb_driver = {
++ .probe = ath_ahb_probe,
++ .remove = ath_ahb_remove,
++ .driver = {
++ .name = "ar231x-wmac",
++ .owner = THIS_MODULE,
++ },
++};
++
++module_platform_driver(ath_ahb_driver);
+--- a/drivers/net/wireless/ath/ath5k/ath5k.h
++++ b/drivers/net/wireless/ath/ath5k/ath5k.h
+@@ -1647,6 +1647,32 @@ static inline struct ath_regulatory *ath
+ return &(ath5k_hw_common(ah)->regulatory);
}
- void ath9k_beacon_tasklet(unsigned long data)
---- a/net/mac80211/main.c
-+++ b/net/mac80211/main.c
-@@ -152,6 +152,8 @@ static u32 ieee80211_hw_conf_chan(struct
- list_for_each_entry_rcu(sdata, &local->interfaces, list) {
- if (!rcu_access_pointer(sdata->vif.chanctx_conf))
- continue;
-+ if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN)
-+ continue;
- power = min(power, sdata->vif.bss_conf.txpower);
- }
- rcu_read_unlock();
-@@ -203,7 +205,7 @@ void ieee80211_bss_info_change_notify(st
++#ifdef CONFIG_ATHEROS_AR231X
++#define AR5K_AR2315_PCI_BASE ((void __iomem *)0xb0100000)
++
++static inline void __iomem *ath5k_ahb_reg(struct ath5k_hw *ah, u16 reg)
++{
++ /* On AR2315 and AR2317 the PCI clock domain registers
++ * are outside of the WMAC register space */
++ if (unlikely((reg >= 0x4000) && (reg < 0x5000) &&
++ (ah->ah_mac_srev >= AR5K_SREV_AR2315_R6)))
++ return AR5K_AR2315_PCI_BASE + reg;
++
++ return ah->iobase + reg;
++}
++
++static inline u32 ath5k_hw_reg_read(struct ath5k_hw *ah, u16 reg)
++{
++ return ioread32(ath5k_ahb_reg(ah, reg));
++}
++
++static inline void ath5k_hw_reg_write(struct ath5k_hw *ah, u32 val, u16 reg)
++{
++ iowrite32(val, ath5k_ahb_reg(ah, reg));
++}
++
++#else
++
+ static inline u32 ath5k_hw_reg_read(struct ath5k_hw *ah, u16 reg)
{
- struct ieee80211_local *local = sdata->local;
-
-- if (!changed)
-+ if (!changed || sdata->vif.type == NL80211_IFTYPE_AP_VLAN)
- return;
-
- drv_bss_info_changed(local, sdata, &sdata->vif.bss_conf, changed);
---- a/drivers/net/wireless/ath/ath9k/ani.c
-+++ b/drivers/net/wireless/ath/ath9k/ani.c
-@@ -155,6 +155,9 @@ static void ath9k_hw_set_ofdm_nil(struct
- ATH9K_ANI_RSSI_THR_LOW,
- ATH9K_ANI_RSSI_THR_HIGH);
+ return ioread32(ah->iobase + reg);
+@@ -1657,6 +1683,8 @@ static inline void ath5k_hw_reg_write(st
+ iowrite32(val, ah->iobase + reg);
+ }
-+ if (AR_SREV_9100(ah) && immunityLevel < ATH9K_ANI_OFDM_DEF_LEVEL)
-+ immunityLevel = ATH9K_ANI_OFDM_DEF_LEVEL;
++#endif
+
- if (!scan)
- aniState->ofdmNoiseImmunityLevel = immunityLevel;
-
-@@ -235,6 +238,9 @@ static void ath9k_hw_set_cck_nil(struct
- BEACON_RSSI(ah), ATH9K_ANI_RSSI_THR_LOW,
- ATH9K_ANI_RSSI_THR_HIGH);
-
-+ if (AR_SREV_9100(ah) && immunityLevel < ATH9K_ANI_CCK_DEF_LEVEL)
-+ immunityLevel = ATH9K_ANI_CCK_DEF_LEVEL;
-+
- if (ah->opmode == NL80211_IFTYPE_STATION &&
- BEACON_RSSI(ah) <= ATH9K_ANI_RSSI_THR_LOW &&
- immunityLevel > ATH9K_ANI_CCK_MAX_LEVEL_LOW_RSSI)
---- a/drivers/net/wireless/ath/ath9k/ath9k.h
-+++ b/drivers/net/wireless/ath/ath9k/ath9k.h
-@@ -251,7 +251,6 @@ struct ath_atx_tid {
-
- s8 bar_index;
- bool sched;
-- bool paused;
- bool active;
+ static inline enum ath_bus_type ath5k_get_bus_type(struct ath5k_hw *ah)
+ {
+ return ath5k_hw_common(ah)->bus_ops->ath_bus_type;
+--- a/drivers/net/wireless/ath/ath5k/base.c
++++ b/drivers/net/wireless/ath/ath5k/base.c
+@@ -99,6 +99,15 @@ static int ath5k_reset(struct ath5k_hw *
+
+ /* Known SREVs */
+ static const struct ath5k_srev_name srev_names[] = {
++#ifdef CONFIG_ATHEROS_AR231X
++ { "5312", AR5K_VERSION_MAC, AR5K_SREV_AR5312_R2 },
++ { "5312", AR5K_VERSION_MAC, AR5K_SREV_AR5312_R7 },
++ { "2313", AR5K_VERSION_MAC, AR5K_SREV_AR2313_R8 },
++ { "2315", AR5K_VERSION_MAC, AR5K_SREV_AR2315_R6 },
++ { "2315", AR5K_VERSION_MAC, AR5K_SREV_AR2315_R7 },
++ { "2317", AR5K_VERSION_MAC, AR5K_SREV_AR2317_R1 },
++ { "2317", AR5K_VERSION_MAC, AR5K_SREV_AR2317_R2 },
++#else
+ { "5210", AR5K_VERSION_MAC, AR5K_SREV_AR5210 },
+ { "5311", AR5K_VERSION_MAC, AR5K_SREV_AR5311 },
+ { "5311A", AR5K_VERSION_MAC, AR5K_SREV_AR5311A },
+@@ -117,6 +126,7 @@ static const struct ath5k_srev_name srev
+ { "5418", AR5K_VERSION_MAC, AR5K_SREV_AR5418 },
+ { "2425", AR5K_VERSION_MAC, AR5K_SREV_AR2425 },
+ { "2417", AR5K_VERSION_MAC, AR5K_SREV_AR2417 },
++#endif
+ { "xxxxx", AR5K_VERSION_MAC, AR5K_SREV_UNKNOWN },
+ { "5110", AR5K_VERSION_RAD, AR5K_SREV_RAD_5110 },
+ { "5111", AR5K_VERSION_RAD, AR5K_SREV_RAD_5111 },
+@@ -132,6 +142,10 @@ static const struct ath5k_srev_name srev
+ { "5413", AR5K_VERSION_RAD, AR5K_SREV_RAD_5413 },
+ { "5424", AR5K_VERSION_RAD, AR5K_SREV_RAD_5424 },
+ { "5133", AR5K_VERSION_RAD, AR5K_SREV_RAD_5133 },
++#ifdef CONFIG_ATHEROS_AR231X
++ { "2316", AR5K_VERSION_RAD, AR5K_SREV_RAD_2316 },
++ { "2317", AR5K_VERSION_RAD, AR5K_SREV_RAD_2317 },
++#endif
+ { "xxxxx", AR5K_VERSION_RAD, AR5K_SREV_UNKNOWN },
};
---- a/drivers/net/wireless/ath/ath9k/xmit.c
-+++ b/drivers/net/wireless/ath/ath9k/xmit.c
-@@ -107,9 +107,6 @@ static void ath_tx_queue_tid(struct ath_
+--- a/drivers/net/wireless/ath/ath5k/led.c
++++ b/drivers/net/wireless/ath/ath5k/led.c
+@@ -163,14 +163,20 @@ int ath5k_init_leds(struct ath5k_hw *ah)
{
- struct ath_atx_ac *ac = tid->ac;
-
-- if (tid->paused)
-- return;
--
- if (tid->sched)
- return;
-
-@@ -1407,7 +1404,6 @@ int ath_tx_aggr_start(struct ath_softc *
- ath_tx_tid_change_state(sc, txtid);
-
- txtid->active = true;
-- txtid->paused = true;
- *ssn = txtid->seq_start = txtid->seq_next;
- txtid->bar_index = -1;
-
-@@ -1427,7 +1423,6 @@ void ath_tx_aggr_stop(struct ath_softc *
-
- ath_txq_lock(sc, txq);
- txtid->active = false;
-- txtid->paused = false;
- ath_tx_flush_tid(sc, txtid);
- ath_tx_tid_change_state(sc, txtid);
- ath_txq_unlock_complete(sc, txq);
-@@ -1487,7 +1482,7 @@ void ath_tx_aggr_wakeup(struct ath_softc
- ath_txq_lock(sc, txq);
- ac->clear_ps_filter = true;
-
-- if (!tid->paused && ath_tid_has_buffered(tid)) {
-+ if (ath_tid_has_buffered(tid)) {
- ath_tx_queue_tid(txq, tid);
- ath_txq_schedule(sc, txq);
- }
-@@ -1510,7 +1505,6 @@ void ath_tx_aggr_resume(struct ath_softc
- ath_txq_lock(sc, txq);
-
- tid->baw_size = IEEE80211_MIN_AMPDU_BUF << sta->ht_cap.ampdu_factor;
-- tid->paused = false;
-
- if (ath_tid_has_buffered(tid)) {
- ath_tx_queue_tid(txq, tid);
-@@ -1544,8 +1538,6 @@ void ath9k_release_buffered_frames(struc
- continue;
-
- tid = ATH_AN_2_TID(an, i);
-- if (tid->paused)
-- continue;
-
- ath_txq_lock(sc, tid->ac->txq);
- while (nframes > 0) {
-@@ -1844,9 +1836,6 @@ void ath_txq_schedule(struct ath_softc *
- list_del(&tid->list);
- tid->sched = false;
-
-- if (tid->paused)
-- continue;
--
- if (ath_tx_sched_aggr(sc, txq, tid, &stop))
- sent = true;
-
-@@ -2698,7 +2687,6 @@ void ath_tx_node_init(struct ath_softc *
- tid->baw_size = WME_MAX_BA;
- tid->baw_head = tid->baw_tail = 0;
- tid->sched = false;
-- tid->paused = false;
- tid->active = false;
- __skb_queue_head_init(&tid->buf_q);
- __skb_queue_head_init(&tid->retry_q);
---- a/drivers/net/wireless/ath/ath9k/recv.c
-+++ b/drivers/net/wireless/ath/ath9k/recv.c
-@@ -975,6 +975,7 @@ int ath_rx_tasklet(struct ath_softc *sc,
- u64 tsf = 0;
- unsigned long flags;
- dma_addr_t new_buf_addr;
-+ unsigned int budget = 512;
-
- if (edma)
- dma_type = DMA_BIDIRECTIONAL;
-@@ -1113,15 +1114,17 @@ requeue_drop_frag:
- }
- requeue:
- list_add_tail(&bf->list, &sc->rx.rxbuf);
-- if (flush)
-- continue;
-
- if (edma) {
- ath_rx_edma_buf_link(sc, qtype);
- } else {
- ath_rx_buf_relink(sc, bf);
-- ath9k_hw_rxena(ah);
-+ if (!flush)
-+ ath9k_hw_rxena(ah);
- }
-+
-+ if (!budget--)
-+ break;
- } while (1);
-
- if (!(ah->imask & ATH9K_INT_RXEOL)) {
---- a/drivers/net/wireless/ath/ath9k/ahb.c
-+++ b/drivers/net/wireless/ath/ath9k/ahb.c
-@@ -86,7 +86,6 @@ static int ath_ahb_probe(struct platform
- int irq;
int ret = 0;
- struct ath_hw *ah;
-- struct ath_common *common;
- char hw_name[64];
-
- if (!dev_get_platdata(&pdev->dev)) {
-@@ -146,9 +145,6 @@ static int ath_ahb_probe(struct platform
- wiphy_info(hw->wiphy, "%s mem=0x%lx, irq=%d\n",
- hw_name, (unsigned long)mem, irq);
-
-- common = ath9k_hw_common(sc->sc_ah);
-- /* Will be cleared in ath9k_start() */
-- set_bit(ATH_OP_INVALID, &common->op_flags);
- return 0;
-
- err_irq:
---- a/drivers/net/wireless/ath/ath9k/init.c
-+++ b/drivers/net/wireless/ath/ath9k/init.c
-@@ -781,6 +781,9 @@ int ath9k_init_device(u16 devid, struct
- common = ath9k_hw_common(ah);
- ath9k_set_hw_capab(sc, hw);
-
-+ /* Will be cleared in ath9k_start() */
-+ set_bit(ATH_OP_INVALID, &common->op_flags);
-+
- /* Initialize regulatory */
- error = ath_regd_init(&common->regulatory, sc->hw->wiphy,
- ath9k_reg_notifier);
---- a/drivers/net/wireless/ath/ath9k/pci.c
-+++ b/drivers/net/wireless/ath/ath9k/pci.c
-@@ -784,7 +784,6 @@ static int ath_pci_probe(struct pci_dev
+ struct ieee80211_hw *hw = ah->hw;
++#ifndef CONFIG_ATHEROS_AR231X
+ struct pci_dev *pdev = ah->pdev;
++#endif
+ char name[ATH5K_LED_MAX_NAME_LEN + 1];
+ const struct pci_device_id *match;
+
+ if (!ah->pdev)
+ return 0;
+
++#ifdef CONFIG_ATHEROS_AR231X
++ match = NULL;
++#else
+ match = pci_match_id(&ath5k_led_devices[0], pdev);
++#endif
+ if (match) {
+ __set_bit(ATH_STAT_LEDSOFT, ah->status);
+ ah->led_pin = ATH_PIN(match->driver_data);
+--- a/drivers/net/wireless/ath/ath5k/debug.c
++++ b/drivers/net/wireless/ath/ath5k/debug.c
+@@ -65,6 +65,7 @@
+
+ #include <linux/seq_file.h>
+ #include <linux/list.h>
++#include <linux/vmalloc.h>
+ #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
{
- struct ath_softc *sc;
- struct ieee80211_hw *hw;
-- struct ath_common *common;
- u8 csz;
u32 val;
- int ret = 0;
-@@ -877,10 +876,6 @@ static int ath_pci_probe(struct pci_dev
- wiphy_info(hw->wiphy, "%s mem=0x%lx, irq=%d\n",
- hw_name, (unsigned long)sc->mem, pdev->irq);
-- /* Will be cleared in ath9k_start() */
-- common = ath9k_hw_common(sc->sc_ah);
-- set_bit(ATH_OP_INVALID, &common->op_flags);
--
- return 0;
++ 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(
- err_init:
+ 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))