PKG_NAME:=mac80211
-PKG_VERSION:=2010-01-15
+PKG_VERSION:=2010-01-25
PKG_RELEASE:=1
PKG_SOURCE_URL:=http://mirror2.openwrt.org/sources
# http://www.orbit-lab.org/kernel/compat-wireless-2.6/2010/11 \
# http://wireless.kernel.org/download/compat-wireless-2.6
-PKG_MD5SUM:=aa6f80ad3fcc2b663e62c7b80d37abd3
+PKG_MD5SUM:=66a1d519e7ebcbadd4e47e6e56f705af
PKG_SOURCE:=compat-wireless-$(PKG_VERSION).tar.bz2
PKG_BUILD_DIR:=$(KERNEL_BUILD_DIR)/compat-wireless-$(PKG_VERSION)
--- a/config.mk
+++ b/config.mk
-@@ -281,10 +281,10 @@ endif
+@@ -283,10 +283,10 @@ endif
CONFIG_P54_PCI=m
ifeq ($(CONFIG_MAC80211),y)
$(error "ERROR: you have MAC80211 compiled into the kernel, CONFIG_MAC80211=y, as such you cannot replace its mac80211 driver. You need this set to CONFIG_MAC80211=m. If you are using Fedora upgrade your kernel as later version should this set as modular. For further information on Fedora see https://bugzilla.redhat.com/show_bug.cgi?id=470143. If you are using your own kernel recompile it and make mac80211 modular")
-@@ -474,8 +474,8 @@ endif
+@@ -476,8 +476,8 @@ endif
# We need the backported rfkill module on kernel < 2.6.31.
# In more recent kernel versions use the in kernel rfkill module.
ifdef CONFIG_COMPAT_KERNEL_31
--- a/config.mk
+++ b/config.mk
-@@ -314,10 +314,10 @@ CONFIG_PCI_ATMEL=m
+@@ -316,10 +316,10 @@ CONFIG_PCI_ATMEL=m
CONFIG_MWL8K=m
# Ethernet drivers go here
endif
## end of PCI
-@@ -356,10 +356,10 @@ CONFIG_USB_NET_COMPAT_RNDIS_HOST=n
+@@ -358,10 +358,10 @@ CONFIG_USB_NET_COMPAT_RNDIS_HOST=n
CONFIG_USB_NET_COMPAT_RNDIS_WLAN=n
CONFIG_USB_NET_COMPAT_CDCETHER=n
else
--- a/config.mk
+++ b/config.mk
-@@ -199,9 +199,9 @@ CONFIG_B43_HWRNG=y
+@@ -201,9 +201,9 @@ CONFIG_B43_HWRNG=y
CONFIG_B43_PCI_AUTOSELECT=y
CONFIG_B43_PCICORE_AUTOSELECT=y
ifneq ($(CONFIG_PCMCIA),)
CONFIG_B43_LEDS=y
CONFIG_B43_PHY_LP=y
# CONFIG_B43_DEBUG=y
-@@ -256,8 +256,8 @@ CONFIG_SSB_PCIHOST_POSSIBLE=y
+@@ -258,8 +258,8 @@ CONFIG_SSB_PCIHOST_POSSIBLE=y
CONFIG_SSB_PCIHOST=y
CONFIG_SSB_B43_PCI_BRIDGE=y
ifneq ($(CONFIG_PCMCIA),)
+++ /dev/null
---- a/include/linux/compat-2.6.32.h
-+++ b/include/linux/compat-2.6.32.h
-@@ -6,7 +6,7 @@
- #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,32))
-
- #include <linux/netdevice.h>
--#include <asm/compat.h>
-+#include <linux/compat.h>
- #include <net/iw_handler.h>
- #include <linux/workqueue.h>
- #include <linux/firmware.h>
+++ /dev/null
---- a/include/linux/compat-2.6.32.h
-+++ b/include/linux/compat-2.6.32.h
-@@ -9,40 +9,6 @@
- #include <linux/compat.h>
- #include <net/iw_handler.h>
- #include <linux/workqueue.h>
--#include <linux/firmware.h>
--
--#define release_firmware compat_release_firmware
--#define request_firmware compat_request_firmware
--#define request_firmware_nowait compat_request_firmware_nowait
--
--#if defined(CONFIG_FW_LOADER) || (defined(CONFIG_FW_LOADER_MODULE) && defined(MODULE))
--int compat_request_firmware(const struct firmware **fw, const char *name,
-- struct device *device);
--int compat_request_firmware_nowait(
-- struct module *module, int uevent,
-- const char *name, struct device *device, gfp_t gfp, void *context,
-- void (*cont)(const struct firmware *fw, void *context));
--
--void compat_release_firmware(const struct firmware *fw);
--#else
--static inline int compat_request_firmware(const struct firmware **fw,
-- const char *name,
-- struct device *device)
--{
-- return -EINVAL;
--}
--static inline int request_firmware_nowait(
-- struct module *module, int uevent,
-- const char *name, struct device *device, gfp_t gfp, void *context,
-- void (*cont)(const struct firmware *fw, void *context))
--{
-- return -EINVAL;
--}
--
--static inline void compat_release_firmware(const struct firmware *fw)
--{
--}
--#endif
-
- #define SDIO_VENDOR_ID_INTEL 0x0089
- #define SDIO_DEVICE_ID_INTEL_IWMC3200WIMAX 0x1402
---- a/include/linux/compat-2.6.33.h
-+++ b/include/linux/compat-2.6.33.h
-@@ -10,6 +10,40 @@
- #include <pcmcia/cistpl.h>
- #include <pcmcia/ds.h>
- #include <linux/kfifo.h>
-+#include <linux/firmware.h>
-+
-+#define release_firmware compat_release_firmware
-+#define request_firmware compat_request_firmware
-+#define request_firmware_nowait compat_request_firmware_nowait
-+
-+#if defined(CONFIG_FW_LOADER) || defined(CONFIG_FW_LOADER_MODULE)
-+int compat_request_firmware(const struct firmware **fw, const char *name,
-+ struct device *device);
-+int compat_request_firmware_nowait(
-+ struct module *module, int uevent,
-+ const char *name, struct device *device, gfp_t gfp, void *context,
-+ void (*cont)(const struct firmware *fw, void *context));
-+
-+void compat_release_firmware(const struct firmware *fw);
-+#else
-+static inline int compat_request_firmware(const struct firmware **fw,
-+ const char *name,
-+ struct device *device)
-+{
-+ return -EINVAL;
-+}
-+static inline int request_firmware_nowait(
-+ struct module *module, int uevent,
-+ const char *name, struct device *device, gfp_t gfp, void *context,
-+ void (*cont)(const struct firmware *fw, void *context))
-+{
-+ return -EINVAL;
-+}
-+
-+static inline void compat_release_firmware(const struct firmware *fw)
-+{
-+}
-+#endif
-
- #define IFF_DONT_BRIDGE 0x800 /* disallow bridging this ether dev */
- /* source: include/linux/if.h */
---- a/compat/compat_firmware_class.c
-+++ b/compat/compat_firmware_class.c
-@@ -20,6 +20,8 @@
- #include <linux/highmem.h>
- #include <linux/firmware.h>
-
-+#if defined(CONFIG_FW_LOADER) || defined(CONFIG_FW_LOADER_MODULE)
-+
- #define to_dev(obj) container_of(obj, struct device, kobj)
-
- MODULE_AUTHOR("Manuel Estrada Sainz");
-@@ -724,3 +726,5 @@ module_exit(firmware_class_exit);
- EXPORT_SYMBOL(release_firmware);
- EXPORT_SYMBOL(request_firmware);
- EXPORT_SYMBOL(request_firmware_nowait);
-+
-+#endif
--- a/drivers/net/wireless/ath/ath9k/hw.c
+++ b/drivers/net/wireless/ath/ath9k/hw.c
-@@ -2088,7 +2088,7 @@ int ath9k_hw_reset(struct ath_hw *ah, st
+@@ -2087,7 +2087,7 @@ int ath9k_hw_reset(struct ath_hw *ah, st
if (ah->config.rx_intr_mitigation) {
REG_RMW_FIELD(ah, AR_RIMT, AR_RIMT_LAST, 500);
--- /dev/null
+--- a/drivers/net/wireless/ath/ath9k/debug.c
++++ b/drivers/net/wireless/ath/ath9k/debug.c
+@@ -75,6 +75,90 @@ static const struct file_operations fops
+
+ #endif
+
++static ssize_t read_file_tx_chainmask(struct file *file, char __user *user_buf,
++ size_t count, loff_t *ppos)
++{
++ struct ath_softc *sc = file->private_data;
++ struct ath_common *common = ath9k_hw_common(sc->sc_ah);
++ char buf[32];
++ unsigned int len;
++
++ len = snprintf(buf, sizeof(buf), "0x%08x\n", common->tx_chainmask);
++ return simple_read_from_buffer(user_buf, count, ppos, buf, len);
++}
++
++static ssize_t write_file_tx_chainmask(struct file *file, const char __user *user_buf,
++ size_t count, loff_t *ppos)
++{
++ struct ath_softc *sc = file->private_data;
++ struct ath_common *common = ath9k_hw_common(sc->sc_ah);
++ unsigned long mask;
++ char buf[32];
++ ssize_t len;
++
++ len = min(count, sizeof(buf) - 1);
++ if (copy_from_user(buf, user_buf, len))
++ return -EINVAL;
++
++ buf[len] = '\0';
++ if (strict_strtoul(buf, 0, &mask))
++ return -EINVAL;
++
++ common->tx_chainmask = mask;
++ sc->sc_ah->caps.tx_chainmask = mask;
++ return count;
++}
++
++static const struct file_operations fops_tx_chainmask = {
++ .read = read_file_tx_chainmask,
++ .write = write_file_tx_chainmask,
++ .open = ath9k_debugfs_open,
++ .owner = THIS_MODULE
++};
++
++
++static ssize_t read_file_rx_chainmask(struct file *file, char __user *user_buf,
++ size_t count, loff_t *ppos)
++{
++ struct ath_softc *sc = file->private_data;
++ struct ath_common *common = ath9k_hw_common(sc->sc_ah);
++ char buf[32];
++ unsigned int len;
++
++ len = snprintf(buf, sizeof(buf), "0x%08x\n", common->rx_chainmask);
++ return simple_read_from_buffer(user_buf, count, ppos, buf, len);
++}
++
++static ssize_t write_file_rx_chainmask(struct file *file, const char __user *user_buf,
++ size_t count, loff_t *ppos)
++{
++ struct ath_softc *sc = file->private_data;
++ struct ath_common *common = ath9k_hw_common(sc->sc_ah);
++ unsigned long mask;
++ char buf[32];
++ ssize_t len;
++
++ len = min(count, sizeof(buf) - 1);
++ if (copy_from_user(buf, user_buf, len))
++ return -EINVAL;
++
++ buf[len] = '\0';
++ if (strict_strtoul(buf, 0, &mask))
++ return -EINVAL;
++
++ common->rx_chainmask = mask;
++ sc->sc_ah->caps.rx_chainmask = mask;
++ return count;
++}
++
++static const struct file_operations fops_rx_chainmask = {
++ .read = read_file_rx_chainmask,
++ .write = write_file_rx_chainmask,
++ .open = ath9k_debugfs_open,
++ .owner = THIS_MODULE
++};
++
++
+ static ssize_t read_file_dma(struct file *file, char __user *user_buf,
+ size_t count, loff_t *ppos)
+ {
+@@ -710,6 +794,16 @@ int ath9k_init_debug(struct ath_hw *ah)
+ goto err;
+ #endif
+
++ sc->debug.debugfs_rx_chainmask = debugfs_create_file("rx_chainmask",
++ S_IRUSR | S_IWUSR, sc->debug.debugfs_phy, sc, &fops_rx_chainmask);
++ if (!sc->debug.debugfs_rx_chainmask)
++ goto err;
++
++ sc->debug.debugfs_tx_chainmask = debugfs_create_file("tx_chainmask",
++ S_IRUSR | S_IWUSR, sc->debug.debugfs_phy, sc, &fops_tx_chainmask);
++ if (!sc->debug.debugfs_tx_chainmask)
++ goto err;
++
+ sc->debug.debugfs_dma = debugfs_create_file("dma", S_IRUSR,
+ sc->debug.debugfs_phy, sc, &fops_dma);
+ if (!sc->debug.debugfs_dma)
+@@ -760,6 +854,8 @@ void ath9k_exit_debug(struct ath_hw *ah)
+ struct ath_common *common = ath9k_hw_common(ah);
+ struct ath_softc *sc = (struct ath_softc *) common->priv;
+
++ debugfs_remove(sc->debug.debugfs_tx_chainmask);
++ debugfs_remove(sc->debug.debugfs_rx_chainmask);
+ debugfs_remove(sc->debug.debugfs_recv);
+ debugfs_remove(sc->debug.debugfs_xmit);
+ debugfs_remove(sc->debug.debugfs_wiphy);
+--- a/drivers/net/wireless/ath/ath9k/debug.h
++++ b/drivers/net/wireless/ath/ath9k/debug.h
+@@ -148,6 +148,8 @@ struct ath_stats {
+ };
+
+ struct ath9k_debug {
++ struct dentry *debugfs_rx_chainmask;
++ struct dentry *debugfs_tx_chainmask;
+ struct dentry *debugfs_phy;
+ struct dentry *debugfs_debug;
+ struct dentry *debugfs_dma;
+++ /dev/null
---- a/drivers/net/wireless/ath/ath9k/debug.c
-+++ b/drivers/net/wireless/ath/ath9k/debug.c
-@@ -75,6 +75,90 @@ static const struct file_operations fops
-
- #endif
-
-+static ssize_t read_file_tx_chainmask(struct file *file, char __user *user_buf,
-+ size_t count, loff_t *ppos)
-+{
-+ struct ath_softc *sc = file->private_data;
-+ struct ath_common *common = ath9k_hw_common(sc->sc_ah);
-+ char buf[32];
-+ unsigned int len;
-+
-+ len = snprintf(buf, sizeof(buf), "0x%08x\n", common->tx_chainmask);
-+ return simple_read_from_buffer(user_buf, count, ppos, buf, len);
-+}
-+
-+static ssize_t write_file_tx_chainmask(struct file *file, const char __user *user_buf,
-+ size_t count, loff_t *ppos)
-+{
-+ struct ath_softc *sc = file->private_data;
-+ struct ath_common *common = ath9k_hw_common(sc->sc_ah);
-+ unsigned long mask;
-+ char buf[32];
-+ ssize_t len;
-+
-+ len = min(count, sizeof(buf) - 1);
-+ if (copy_from_user(buf, user_buf, len))
-+ return -EINVAL;
-+
-+ buf[len] = '\0';
-+ if (strict_strtoul(buf, 0, &mask))
-+ return -EINVAL;
-+
-+ common->tx_chainmask = mask;
-+ sc->sc_ah->caps.tx_chainmask = mask;
-+ return count;
-+}
-+
-+static const struct file_operations fops_tx_chainmask = {
-+ .read = read_file_tx_chainmask,
-+ .write = write_file_tx_chainmask,
-+ .open = ath9k_debugfs_open,
-+ .owner = THIS_MODULE
-+};
-+
-+
-+static ssize_t read_file_rx_chainmask(struct file *file, char __user *user_buf,
-+ size_t count, loff_t *ppos)
-+{
-+ struct ath_softc *sc = file->private_data;
-+ struct ath_common *common = ath9k_hw_common(sc->sc_ah);
-+ char buf[32];
-+ unsigned int len;
-+
-+ len = snprintf(buf, sizeof(buf), "0x%08x\n", common->rx_chainmask);
-+ return simple_read_from_buffer(user_buf, count, ppos, buf, len);
-+}
-+
-+static ssize_t write_file_rx_chainmask(struct file *file, const char __user *user_buf,
-+ size_t count, loff_t *ppos)
-+{
-+ struct ath_softc *sc = file->private_data;
-+ struct ath_common *common = ath9k_hw_common(sc->sc_ah);
-+ unsigned long mask;
-+ char buf[32];
-+ ssize_t len;
-+
-+ len = min(count, sizeof(buf) - 1);
-+ if (copy_from_user(buf, user_buf, len))
-+ return -EINVAL;
-+
-+ buf[len] = '\0';
-+ if (strict_strtoul(buf, 0, &mask))
-+ return -EINVAL;
-+
-+ common->rx_chainmask = mask;
-+ sc->sc_ah->caps.rx_chainmask = mask;
-+ return count;
-+}
-+
-+static const struct file_operations fops_rx_chainmask = {
-+ .read = read_file_rx_chainmask,
-+ .write = write_file_rx_chainmask,
-+ .open = ath9k_debugfs_open,
-+ .owner = THIS_MODULE
-+};
-+
-+
- static ssize_t read_file_dma(struct file *file, char __user *user_buf,
- size_t count, loff_t *ppos)
- {
-@@ -710,6 +794,16 @@ int ath9k_init_debug(struct ath_hw *ah)
- goto err;
- #endif
-
-+ sc->debug.debugfs_rx_chainmask = debugfs_create_file("rx_chainmask",
-+ S_IRUSR | S_IWUSR, sc->debug.debugfs_phy, sc, &fops_rx_chainmask);
-+ if (!sc->debug.debugfs_rx_chainmask)
-+ goto err;
-+
-+ sc->debug.debugfs_tx_chainmask = debugfs_create_file("tx_chainmask",
-+ S_IRUSR | S_IWUSR, sc->debug.debugfs_phy, sc, &fops_tx_chainmask);
-+ if (!sc->debug.debugfs_tx_chainmask)
-+ goto err;
-+
- sc->debug.debugfs_dma = debugfs_create_file("dma", S_IRUSR,
- sc->debug.debugfs_phy, sc, &fops_dma);
- if (!sc->debug.debugfs_dma)
-@@ -760,6 +854,8 @@ void ath9k_exit_debug(struct ath_hw *ah)
- struct ath_common *common = ath9k_hw_common(ah);
- struct ath_softc *sc = (struct ath_softc *) common->priv;
-
-+ debugfs_remove(sc->debug.debugfs_tx_chainmask);
-+ debugfs_remove(sc->debug.debugfs_rx_chainmask);
- debugfs_remove(sc->debug.debugfs_recv);
- debugfs_remove(sc->debug.debugfs_xmit);
- debugfs_remove(sc->debug.debugfs_wiphy);
---- a/drivers/net/wireless/ath/ath9k/debug.h
-+++ b/drivers/net/wireless/ath/ath9k/debug.h
-@@ -148,6 +148,8 @@ struct ath_stats {
- };
-
- struct ath9k_debug {
-+ struct dentry *debugfs_rx_chainmask;
-+ struct dentry *debugfs_tx_chainmask;
- struct dentry *debugfs_phy;
- struct dentry *debugfs_debug;
- struct dentry *debugfs_dma;
--- /dev/null
+--- a/drivers/net/wireless/ath/ath9k/debug.c
++++ b/drivers/net/wireless/ath/ath9k/debug.c
+@@ -774,6 +774,86 @@ static const struct file_operations fops
+ .owner = THIS_MODULE
+ };
+
++static ssize_t read_file_regidx(struct file *file, char __user *user_buf,
++ size_t count, loff_t *ppos)
++{
++ struct ath_softc *sc = file->private_data;
++ char buf[32];
++ unsigned int len;
++
++ len = snprintf(buf, sizeof(buf), "0x%08x\n", sc->debug.regidx);
++ return simple_read_from_buffer(user_buf, count, ppos, buf, len);
++}
++
++static ssize_t write_file_regidx(struct file *file, const char __user *user_buf,
++ size_t count, loff_t *ppos)
++{
++ struct ath_softc *sc = file->private_data;
++ unsigned long regidx;
++ char buf[32];
++ ssize_t len;
++
++ len = min(count, sizeof(buf) - 1);
++ if (copy_from_user(buf, user_buf, len))
++ return -EINVAL;
++
++ buf[len] = '\0';
++ if (strict_strtoul(buf, 0, ®idx))
++ return -EINVAL;
++
++ sc->debug.regidx = regidx;
++ return count;
++}
++
++static const struct file_operations fops_regidx = {
++ .read = read_file_regidx,
++ .write = write_file_regidx,
++ .open = ath9k_debugfs_open,
++ .owner = THIS_MODULE
++};
++
++static ssize_t read_file_regval(struct file *file, char __user *user_buf,
++ size_t count, loff_t *ppos)
++{
++ struct ath_softc *sc = file->private_data;
++ struct ath_hw *ah = sc->sc_ah;
++ char buf[32];
++ unsigned int len;
++ u32 regval;
++
++ regval = REG_READ_D(ah, sc->debug.regidx);
++ len = snprintf(buf, sizeof(buf), "0x%08x\n", regval);
++ return simple_read_from_buffer(user_buf, count, ppos, buf, len);
++}
++
++static ssize_t write_file_regval(struct file *file, const char __user *user_buf,
++ size_t count, loff_t *ppos)
++{
++ struct ath_softc *sc = file->private_data;
++ struct ath_hw *ah = sc->sc_ah;
++ unsigned long regval;
++ char buf[32];
++ ssize_t len;
++
++ len = min(count, sizeof(buf) - 1);
++ if (copy_from_user(buf, user_buf, len))
++ return -EINVAL;
++
++ buf[len] = '\0';
++ if (strict_strtoul(buf, 0, ®val))
++ return -EINVAL;
++
++ REG_WRITE_D(ah, sc->debug.regidx, regval);
++ return count;
++}
++
++static const struct file_operations fops_regval = {
++ .read = read_file_regval,
++ .write = write_file_regval,
++ .open = ath9k_debugfs_open,
++ .owner = THIS_MODULE
++};
++
+ int ath9k_init_debug(struct ath_hw *ah)
+ {
+ struct ath_common *common = ath9k_hw_common(ah);
+@@ -843,6 +923,17 @@ int ath9k_init_debug(struct ath_hw *ah)
+ if (!sc->debug.debugfs_recv)
+ goto err;
+
++ sc->debug.regidx = 0;
++ sc->debug.debugfs_regidx = debugfs_create_file("regidx",
++ S_IRUSR|S_IWUSR, sc->debug.debugfs_phy, sc, &fops_regidx);
++ if (!sc->debug.debugfs_regidx)
++ goto err;
++
++ sc->debug.debugfs_regval = debugfs_create_file("regval",
++ S_IRUSR|S_IWUSR, sc->debug.debugfs_phy, sc, &fops_regval);
++ if (!sc->debug.debugfs_regval)
++ goto err;
++
+ return 0;
+ err:
+ ath9k_exit_debug(ah);
+@@ -856,6 +947,8 @@ void ath9k_exit_debug(struct ath_hw *ah)
+
+ debugfs_remove(sc->debug.debugfs_tx_chainmask);
+ debugfs_remove(sc->debug.debugfs_rx_chainmask);
++ debugfs_remove(sc->debug.debugfs_regval);
++ debugfs_remove(sc->debug.debugfs_regidx);
+ debugfs_remove(sc->debug.debugfs_recv);
+ debugfs_remove(sc->debug.debugfs_xmit);
+ debugfs_remove(sc->debug.debugfs_wiphy);
+--- a/drivers/net/wireless/ath/ath9k/debug.h
++++ b/drivers/net/wireless/ath/ath9k/debug.h
+@@ -158,6 +158,9 @@ struct ath9k_debug {
+ struct dentry *debugfs_wiphy;
+ struct dentry *debugfs_xmit;
+ struct dentry *debugfs_recv;
++ struct dentry *debugfs_regidx;
++ struct dentry *debugfs_regval;
++ u32 regidx;
+ struct ath_stats stats;
+ };
+
--- /dev/null
+--- a/drivers/net/wireless/ath/ath9k/hw.c
++++ b/drivers/net/wireless/ath/ath9k/hw.c
+@@ -1228,6 +1228,11 @@ void ath9k_hw_init_global_settings(struc
+ /* As defined by IEEE 802.11-2007 17.3.8.6 */
+ slottime = ah->slottime + 3 * ah->coverage_class;
+ acktimeout = slottime + sifstime;
++
++ /* Workaround for a hw issue */
++ if (conf->channel && conf->channel->band == IEEE80211_BAND_2GHZ)
++ acktimeout = max(64, acktimeout);
++
+ ath9k_hw_setslottime(ah, slottime);
+ ath9k_hw_set_ack_timeout(ah, acktimeout);
+ ath9k_hw_set_cts_timeout(ah, acktimeout);
+++ /dev/null
---- a/drivers/net/wireless/ath/ath9k/debug.c
-+++ b/drivers/net/wireless/ath/ath9k/debug.c
-@@ -774,6 +774,86 @@ static const struct file_operations fops
- .owner = THIS_MODULE
- };
-
-+static ssize_t read_file_regidx(struct file *file, char __user *user_buf,
-+ size_t count, loff_t *ppos)
-+{
-+ struct ath_softc *sc = file->private_data;
-+ char buf[32];
-+ unsigned int len;
-+
-+ len = snprintf(buf, sizeof(buf), "0x%08x\n", sc->debug.regidx);
-+ return simple_read_from_buffer(user_buf, count, ppos, buf, len);
-+}
-+
-+static ssize_t write_file_regidx(struct file *file, const char __user *user_buf,
-+ size_t count, loff_t *ppos)
-+{
-+ struct ath_softc *sc = file->private_data;
-+ unsigned long regidx;
-+ char buf[32];
-+ ssize_t len;
-+
-+ len = min(count, sizeof(buf) - 1);
-+ if (copy_from_user(buf, user_buf, len))
-+ return -EINVAL;
-+
-+ buf[len] = '\0';
-+ if (strict_strtoul(buf, 0, ®idx))
-+ return -EINVAL;
-+
-+ sc->debug.regidx = regidx;
-+ return count;
-+}
-+
-+static const struct file_operations fops_regidx = {
-+ .read = read_file_regidx,
-+ .write = write_file_regidx,
-+ .open = ath9k_debugfs_open,
-+ .owner = THIS_MODULE
-+};
-+
-+static ssize_t read_file_regval(struct file *file, char __user *user_buf,
-+ size_t count, loff_t *ppos)
-+{
-+ struct ath_softc *sc = file->private_data;
-+ struct ath_hw *ah = sc->sc_ah;
-+ char buf[32];
-+ unsigned int len;
-+ u32 regval;
-+
-+ regval = REG_READ_D(ah, sc->debug.regidx);
-+ len = snprintf(buf, sizeof(buf), "0x%08x\n", regval);
-+ return simple_read_from_buffer(user_buf, count, ppos, buf, len);
-+}
-+
-+static ssize_t write_file_regval(struct file *file, const char __user *user_buf,
-+ size_t count, loff_t *ppos)
-+{
-+ struct ath_softc *sc = file->private_data;
-+ struct ath_hw *ah = sc->sc_ah;
-+ unsigned long regval;
-+ char buf[32];
-+ ssize_t len;
-+
-+ len = min(count, sizeof(buf) - 1);
-+ if (copy_from_user(buf, user_buf, len))
-+ return -EINVAL;
-+
-+ buf[len] = '\0';
-+ if (strict_strtoul(buf, 0, ®val))
-+ return -EINVAL;
-+
-+ REG_WRITE_D(ah, sc->debug.regidx, regval);
-+ return count;
-+}
-+
-+static const struct file_operations fops_regval = {
-+ .read = read_file_regval,
-+ .write = write_file_regval,
-+ .open = ath9k_debugfs_open,
-+ .owner = THIS_MODULE
-+};
-+
- int ath9k_init_debug(struct ath_hw *ah)
- {
- struct ath_common *common = ath9k_hw_common(ah);
-@@ -843,6 +923,17 @@ int ath9k_init_debug(struct ath_hw *ah)
- if (!sc->debug.debugfs_recv)
- goto err;
-
-+ sc->debug.regidx = 0;
-+ sc->debug.debugfs_regidx = debugfs_create_file("regidx",
-+ S_IRUSR|S_IWUSR, sc->debug.debugfs_phy, sc, &fops_regidx);
-+ if (!sc->debug.debugfs_regidx)
-+ goto err;
-+
-+ sc->debug.debugfs_regval = debugfs_create_file("regval",
-+ S_IRUSR|S_IWUSR, sc->debug.debugfs_phy, sc, &fops_regval);
-+ if (!sc->debug.debugfs_regval)
-+ goto err;
-+
- return 0;
- err:
- ath9k_exit_debug(ah);
-@@ -856,6 +947,8 @@ void ath9k_exit_debug(struct ath_hw *ah)
-
- debugfs_remove(sc->debug.debugfs_tx_chainmask);
- debugfs_remove(sc->debug.debugfs_rx_chainmask);
-+ debugfs_remove(sc->debug.debugfs_regval);
-+ debugfs_remove(sc->debug.debugfs_regidx);
- debugfs_remove(sc->debug.debugfs_recv);
- debugfs_remove(sc->debug.debugfs_xmit);
- debugfs_remove(sc->debug.debugfs_wiphy);
---- a/drivers/net/wireless/ath/ath9k/debug.h
-+++ b/drivers/net/wireless/ath/ath9k/debug.h
-@@ -158,6 +158,9 @@ struct ath9k_debug {
- struct dentry *debugfs_wiphy;
- struct dentry *debugfs_xmit;
- struct dentry *debugfs_recv;
-+ struct dentry *debugfs_regidx;
-+ struct dentry *debugfs_regval;
-+ u32 regidx;
- struct ath_stats stats;
- };
-
--- /dev/null
+--- a/net/wireless/core.h
++++ b/net/wireless/core.h
+@@ -76,6 +76,7 @@ struct cfg80211_registered_device {
+
+ /* current channel */
+ struct ieee80211_channel *channel;
++ enum nl80211_channel_type channel_type;
+
+ /* must be last because of the way we do wiphy_priv(),
+ * and it should at least be aligned to NETDEV_ALIGN */
+--- a/net/wireless/chan.c
++++ b/net/wireless/chan.c
+@@ -97,6 +97,7 @@ int rdev_set_freq(struct cfg80211_regist
+ return result;
+
+ rdev->channel = chan;
++ rdev->channel_type = channel_type;
+
+ return 0;
+ }
+--- a/net/wireless/nl80211.c
++++ b/net/wireless/nl80211.c
+@@ -881,6 +881,11 @@ static int nl80211_send_iface(struct sk_
+ NLA_PUT_U32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx);
+ NLA_PUT_STRING(msg, NL80211_ATTR_IFNAME, dev->name);
+ NLA_PUT_U32(msg, NL80211_ATTR_IFTYPE, dev->ieee80211_ptr->iftype);
++ if (rdev->channel) {
++ NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_FREQ, rdev->channel->center_freq);
++ NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_CHANNEL_TYPE, rdev->channel_type);
++ }
++
+
+ NLA_PUT_U32(msg, NL80211_ATTR_GENERATION,
+ rdev->devlist_generation ^
+++ /dev/null
---- a/net/mac80211/iface.c
-+++ b/net/mac80211/iface.c
-@@ -697,10 +697,14 @@ static u16 ieee80211_monitor_select_queu
-
- hdr = (void *)((u8 *)skb->data + le16_to_cpu(rtap->it_len));
-
-- if (!ieee80211_is_data_qos(hdr->frame_control)) {
-+ if (!ieee80211_is_data(hdr->frame_control)) {
- skb->priority = 7;
- return ieee802_1d_to_ac[skb->priority];
- }
-+ if (!ieee80211_is_data_qos(hdr->frame_control)) {
-+ skb->priority = 0;
-+ return ieee802_1d_to_ac[skb->priority];
-+ }
-
- p = ieee80211_get_qos_ctl(hdr);
- skb->priority = *p & IEEE80211_QOS_CTL_TAG1D_MASK;
+++ /dev/null
---- a/drivers/net/wireless/ath/ath9k/xmit.c
-+++ b/drivers/net/wireless/ath/ath9k/xmit.c
-@@ -1498,26 +1498,6 @@ static void ath_buf_set_rate(struct ath_
- if (sc->sc_flags & SC_OP_PREAMBLE_SHORT)
- ctsrate |= rate->hw_value_short;
-
-- /*
-- * ATH9K_TXDESC_RTSENA and ATH9K_TXDESC_CTSENA are mutually exclusive.
-- * Check the first rate in the series to decide whether RTS/CTS
-- * or CTS-to-self has to be used.
-- */
-- if (rates[0].flags & IEEE80211_TX_RC_USE_CTS_PROTECT)
-- flags = ATH9K_TXDESC_CTSENA;
-- else if (rates[0].flags & IEEE80211_TX_RC_USE_RTS_CTS)
-- flags = ATH9K_TXDESC_RTSENA;
--
-- /* FIXME: Handle aggregation protection */
-- if (sc->config.ath_aggr_prot &&
-- (!bf_isaggr(bf) || (bf_isaggr(bf) && bf->bf_al < 8192))) {
-- flags = ATH9K_TXDESC_RTSENA;
-- }
--
-- /* For AR5416 - RTS cannot be followed by a frame larger than 8K */
-- if (bf_isaggr(bf) && (bf->bf_al > sc->sc_ah->caps.rts_aggr_limit))
-- flags &= ~(ATH9K_TXDESC_RTSENA);
--
- for (i = 0; i < 4; i++) {
- bool is_40, is_sgi, is_sp;
- int phy;
-@@ -1529,8 +1509,15 @@ static void ath_buf_set_rate(struct ath_
- series[i].Tries = rates[i].count;
- series[i].ChSel = common->tx_chainmask;
-
-- if (rates[i].flags & IEEE80211_TX_RC_USE_RTS_CTS)
-+ if ((sc->config.ath_aggr_prot && bf_isaggr(bf)) ||
-+ (rates[i].flags & IEEE80211_TX_RC_USE_RTS_CTS)) {
- series[i].RateFlags |= ATH9K_RATESERIES_RTS_CTS;
-+ flags |= ATH9K_TXDESC_RTSENA;
-+ } else if (rates[i].flags & IEEE80211_TX_RC_USE_CTS_PROTECT) {
-+ series[i].RateFlags |= ATH9K_RATESERIES_RTS_CTS;
-+ flags |= ATH9K_TXDESC_CTSENA;
-+ }
-+
- if (rates[i].flags & IEEE80211_TX_RC_40_MHZ_WIDTH)
- series[i].RateFlags |= ATH9K_RATESERIES_2040;
- if (rates[i].flags & IEEE80211_TX_RC_SHORT_GI)
-@@ -1568,6 +1555,14 @@ static void ath_buf_set_rate(struct ath_
- phy, rate->bitrate * 100, bf->bf_frmlen, rix, is_sp);
- }
-
-+ /* For AR5416 - RTS cannot be followed by a frame larger than 8K */
-+ if (bf_isaggr(bf) && (bf->bf_al > sc->sc_ah->caps.rts_aggr_limit))
-+ flags &= ~ATH9K_TXDESC_RTSENA;
-+
-+ /* ATH9K_TXDESC_RTSENA and ATH9K_TXDESC_CTSENA are mutually exclusive. */
-+ if (flags & ATH9K_TXDESC_RTSENA)
-+ flags &= ~ATH9K_TXDESC_CTSENA;
-+
- /* set dur_update_en for l-sig computation except for PS-Poll frames */
- ath9k_hw_set11n_ratescenario(sc->sc_ah, bf->bf_desc,
- bf->bf_lastbf->bf_desc,
+++ /dev/null
---- a/drivers/net/wireless/ath/ath9k/hw.c
-+++ b/drivers/net/wireless/ath/ath9k/hw.c
-@@ -1229,6 +1229,11 @@ void ath9k_hw_init_global_settings(struc
- /* As defined by IEEE 802.11-2007 17.3.8.6 */
- slottime = ah->slottime + 3 * ah->coverage_class;
- acktimeout = slottime + sifstime;
-+
-+ /* Workaround for a hw issue */
-+ if (conf->channel && conf->channel->band == IEEE80211_BAND_2GHZ)
-+ acktimeout = max(64, acktimeout);
-+
- ath9k_hw_setslottime(ah, slottime);
- ath9k_hw_set_ack_timeout(ah, acktimeout);
- ath9k_hw_set_cts_timeout(ah, acktimeout);
+++ /dev/null
---- a/net/wireless/core.h
-+++ b/net/wireless/core.h
-@@ -75,6 +75,7 @@ struct cfg80211_registered_device {
-
- /* current channel */
- struct ieee80211_channel *channel;
-+ enum nl80211_channel_type channel_type;
-
- /* must be last because of the way we do wiphy_priv(),
- * and it should at least be aligned to NETDEV_ALIGN */
---- a/net/wireless/chan.c
-+++ b/net/wireless/chan.c
-@@ -97,6 +97,7 @@ int rdev_set_freq(struct cfg80211_regist
- return result;
-
- rdev->channel = chan;
-+ rdev->channel_type = channel_type;
-
- return 0;
- }
---- a/net/wireless/nl80211.c
-+++ b/net/wireless/nl80211.c
-@@ -881,6 +881,11 @@ static int nl80211_send_iface(struct sk_
- NLA_PUT_U32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx);
- NLA_PUT_STRING(msg, NL80211_ATTR_IFNAME, dev->name);
- NLA_PUT_U32(msg, NL80211_ATTR_IFTYPE, dev->ieee80211_ptr->iftype);
-+ if (rdev->channel) {
-+ NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_FREQ, rdev->channel->center_freq);
-+ NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_CHANNEL_TYPE, rdev->channel_type);
-+ }
-+
-
- NLA_PUT_U32(msg, NL80211_ATTR_GENERATION,
- rdev->devlist_generation ^
+++ /dev/null
---- a/drivers/net/wireless/ath/ath9k/main.c
-+++ b/drivers/net/wireless/ath/ath9k/main.c
-@@ -1471,10 +1471,10 @@ static void ath9k_remove_interface(struc
- (sc->sc_ah->opmode == NL80211_IFTYPE_MESH_POINT)) {
- ath9k_ps_wakeup(sc);
- ath9k_hw_stoptxdma(sc->sc_ah, sc->beacon.beaconq);
-- ath_beacon_return(sc, avp);
- ath9k_ps_restore(sc);
- }
-
-+ ath_beacon_return(sc, avp);
- sc->sc_flags &= ~SC_OP_BEACONS;
-
- for (i = 0; i < ARRAY_SIZE(sc->beacon.bslot); i++) {
+++ /dev/null
---- a/net/mac80211/rx.c
-+++ b/net/mac80211/rx.c
-@@ -2348,22 +2348,6 @@ static void __ieee80211_rx_handle_packet
- sdata->vif.type == NL80211_IFTYPE_AP_VLAN)
- continue;
-
-- rx.sta = sta_info_get(sdata, hdr->addr2);
--
-- rx.flags |= IEEE80211_RX_RA_MATCH;
-- prepares = prepare_for_handlers(sdata, &rx, hdr);
--
-- if (!prepares)
-- continue;
--
-- if (status->flag & RX_FLAG_MMIC_ERROR) {
-- rx.sdata = sdata;
-- if (rx.flags & IEEE80211_RX_RA_MATCH)
-- ieee80211_rx_michael_mic_report(hdr,
-- &rx);
-- continue;
-- }
--
- /*
- * frame is destined for this interface, but if it's
- * not also for the previous one we handle that after
-@@ -2375,6 +2359,22 @@ static void __ieee80211_rx_handle_packet
- continue;
- }
-
-+ rx.sta = sta_info_get(prev, hdr->addr2);
-+
-+ rx.flags |= IEEE80211_RX_RA_MATCH;
-+ prepares = prepare_for_handlers(prev, &rx, hdr);
-+
-+ if (!prepares)
-+ goto next;
-+
-+ if (status->flag & RX_FLAG_MMIC_ERROR) {
-+ rx.sdata = prev;
-+ if (rx.flags & IEEE80211_RX_RA_MATCH)
-+ ieee80211_rx_michael_mic_report(hdr,
-+ &rx);
-+ goto next;
-+ }
-+
- /*
- * frame was destined for the previous interface
- * so invoke RX handlers for it
-@@ -2387,11 +2387,22 @@ static void __ieee80211_rx_handle_packet
- "multicast frame for %s\n",
- wiphy_name(local->hw.wiphy),
- prev->name);
-- continue;
-+ goto next;
- }
- ieee80211_invoke_rx_handlers(prev, &rx, skb_new, rate);
-+next:
- prev = sdata;
- }
-+
-+ if (prev) {
-+ rx.sta = sta_info_get(prev, hdr->addr2);
-+
-+ rx.flags |= IEEE80211_RX_RA_MATCH;
-+ prepares = prepare_for_handlers(prev, &rx, hdr);
-+
-+ if (!prepares)
-+ prev = NULL;
-+ }
- }
- if (prev)
- ieee80211_invoke_rx_handlers(prev, &rx, skb, rate);
+++ /dev/null
---- a/drivers/net/wireless/ath/ath9k/hw.c
-+++ b/drivers/net/wireless/ath/ath9k/hw.c
-@@ -823,12 +823,11 @@ static void ath9k_hw_init_mode_gain_regs
- }
- }
-
--static void ath9k_hw_init_11a_eeprom_fix(struct ath_hw *ah)
-+static void ath9k_hw_init_eeprom_fix(struct ath_hw *ah)
- {
- u32 i, j;
-
-- if ((ah->hw_version.devid == AR9280_DEVID_PCI) &&
-- test_bit(ATH9K_MODE_11A, ah->caps.wireless_modes)) {
-+ if (ah->hw_version.devid == AR9280_DEVID_PCI) {
-
- /* EEPROM Fixup */
- for (i = 0; i < ah->iniModes.ia_rows; i++) {
-@@ -948,7 +947,7 @@ int ath9k_hw_init(struct ath_hw *ah)
- if (r)
- return r;
-
-- ath9k_hw_init_11a_eeprom_fix(ah);
-+ ath9k_hw_init_eeprom_fix(ah);
-
- r = ath9k_hw_init_macaddr(ah);
- if (r) {
+++ /dev/null
---- a/drivers/net/wireless/ath/ath9k/init.c
-+++ b/drivers/net/wireless/ath/ath9k/init.c
-@@ -645,8 +645,7 @@ void ath9k_set_hw_capab(struct ath_softc
- hw->max_rates = 4;
- hw->channel_change_time = 5000;
- hw->max_listen_interval = 10;
-- /* Hardware supports 10 but we use 4 */
-- hw->max_rate_tries = 4;
-+ hw->max_rate_tries = 10;
- hw->sta_data_size = sizeof(struct ath_node);
- hw->vif_data_size = sizeof(struct ath_vif);
-
---- a/drivers/net/wireless/ath/ath9k/rc.c
-+++ b/drivers/net/wireless/ath/ath9k/rc.c
-@@ -678,13 +678,13 @@ static void ath_get_rate(void *priv, str
- * For Multi Rate Retry we use a different number of
- * retry attempt counts. This ends up looking like this:
- *
-- * MRR[0] = 2
-- * MRR[1] = 2
-- * MRR[2] = 2
-- * MRR[3] = 4
-+ * MRR[0] = 4
-+ * MRR[1] = 4
-+ * MRR[2] = 4
-+ * MRR[3] = 8
- *
- */
-- try_per_rate = sc->hw->max_rate_tries;
-+ try_per_rate = 4;
-
- rate_table = sc->cur_rate_table;
- rix = ath_rc_get_highest_rix(sc, ath_rc_priv, rate_table, &is_probe);
-@@ -714,7 +714,7 @@ static void ath_get_rate(void *priv, str
- for ( ; i < 4; i++) {
- /* Use twice the number of tries for the last MRR segment. */
- if (i + 1 == 4)
-- try_per_rate = 4;
-+ try_per_rate = 8;
-
- ath_rc_get_lower_rix(rate_table, ath_rc_priv, rix, &nrix);
- /* All other rates in the series have RTS enabled */
+++ /dev/null
---- a/net/mac80211/work.c
-+++ b/net/mac80211/work.c
-@@ -1022,8 +1022,6 @@ ieee80211_rx_result ieee80211_work_rx_mg
- case IEEE80211_STYPE_PROBE_RESP:
- case IEEE80211_STYPE_ASSOC_RESP:
- case IEEE80211_STYPE_REASSOC_RESP:
-- case IEEE80211_STYPE_DEAUTH:
-- case IEEE80211_STYPE_DISASSOC:
- skb_queue_tail(&local->work_skb_queue, skb);
- ieee80211_queue_work(&local->hw, &local->work_work);
- return RX_QUEUED;