PKG_NAME:=mac80211
-PKG_VERSION:=2011-04-19
-PKG_RELEASE:=3
+PKG_VERSION:=2011-05-13
+PKG_RELEASE:=1
PKG_SOURCE_URL:=http://mirror2.openwrt.org/sources
-PKG_MD5SUM:=7b789b726927bcc8e3b06c7df40214d9
+PKG_MD5SUM:=8670d18633dbd28b19168abe3ecd0357
PKG_SOURCE:=compat-wireless-$(PKG_VERSION).tar.bz2
PKG_BUILD_DIR:=$(KERNEL_BUILD_DIR)/compat-wireless-$(PKG_VERSION)
$(TAR) -C $(PKG_BUILD_DIR) -xjf $(DL_DIR)/$(ZD1211FW_NAME)-$(ZD1211FW_VERSION).tar.bz2
rm -rf $(PKG_BUILD_DIR)/include/linux/ssb
rm -f $(PKG_BUILD_DIR)/include/net/ieee80211.h
- rm $(PKG_BUILD_DIR)/include/linux/eeprom_93cx6.h
endef
ifneq ($(CONFIG_PACKAGE_kmod-cfg80211),)
--- a/config.mk
+++ b/config.mk
-@@ -311,8 +311,8 @@ endif #CONFIG_SSB
+@@ -314,8 +314,8 @@ endif #CONFIG_SSB
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")
-@@ -614,10 +614,10 @@ endif #CONFIG_COMPAT_KERNEL_27
+@@ -617,10 +617,10 @@ endif #CONFIG_COMPAT_KERNEL_27
# 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
else
include $(KLIB_BUILD)/.config
endif
-@@ -295,19 +294,18 @@ CONFIG_IPW2200_QOS=y
+@@ -298,19 +297,18 @@ CONFIG_IPW2200_QOS=y
# % echo 1 > /sys/bus/pci/drivers/ipw2200/*/rtap_iface
endif #CONFIG_WIRELESS_EXT
CONFIG_P54_PCI=m
-@@ -502,7 +500,6 @@ endif #CONFIG_SPI_MASTER end of SPI driv
+@@ -507,7 +505,6 @@ endif #CONFIG_SPI_MASTER end of SPI driv
ifdef CONFIG_MMC
endif #CONFIG_STAGING
# mac80211 test driver
-@@ -337,13 +337,13 @@ endif #CONFIG_CRC_ITU_T
+@@ -340,13 +340,13 @@ endif #CONFIG_CRC_ITU_T
CONFIG_MWL8K=m
# Ethernet drivers go here
endif #CONFIG_COMPAT_KERNEL_27
ifdef CONFIG_WIRELESS_EXT
-@@ -398,21 +398,21 @@ endif #CONFIG_COMPAT_KERNEL_29
+@@ -402,21 +402,21 @@ endif #CONFIG_COMPAT_KERNEL_29
# Note: this depends on CONFIG_USB_NET_RNDIS_HOST and CONFIG_USB_NET_CDCETHER
# it also requires new RNDIS_HOST and CDC_ETHER modules which we add
ifdef CONFIG_COMPAT_KERNEL_29
else
include $(KLIB_BUILD)/.config
endif
-@@ -229,7 +229,7 @@ CONFIG_B43=m
+@@ -232,7 +232,7 @@ CONFIG_B43=m
CONFIG_B43_HWRNG=y
CONFIG_B43_PCI_AUTOSELECT=y
ifdef CONFIG_PCMCIA
--- a/config.mk
+++ b/config.mk
-@@ -483,7 +483,7 @@ endif #CONFIG_SPI_MASTER end of SPI driv
+@@ -488,7 +488,7 @@ endif #CONFIG_SPI_MASTER end of SPI driv
ifdef CONFIG_MMC
--- a/config.mk
+++ b/config.mk
-@@ -235,7 +235,7 @@ ifdef CONFIG_MAC80211_LEDS
+@@ -238,7 +238,7 @@ ifdef CONFIG_MAC80211_LEDS
CONFIG_B43_LEDS=y
endif #CONFIG_MAC80211_LEDS
CONFIG_B43_PHY_LP=y
--- a/config.mk
+++ b/config.mk
-@@ -299,7 +299,7 @@ CONFIG_RTL8180=m
+@@ -302,7 +302,7 @@ CONFIG_RTL8180=m
CONFIG_ADM8211=m
CONFIG_RT2400PCI=m
CONFIG_RT2500PCI=m
ifdef CONFIG_CRC_CCITT
-@@ -432,7 +432,7 @@ CONFIG_RT2800USB=m
- # CONFIG_RT2800USB_RT35XX=y
+@@ -437,7 +437,7 @@ CONFIG_RT2800USB_RT33XX=y
+ # CONFIG_RT2800USB_RT53XX=y
CONFIG_RT2800USB_UNKNOWN=y
endif #CONFIG_CRC_CCITT
-CONFIG_RT2X00_LIB_USB=m
--- a/config.mk
+++ b/config.mk
-@@ -202,7 +202,7 @@ CONFIG_ATH9K_COMMON=m
+@@ -205,7 +205,7 @@ CONFIG_ATH9K_COMMON=m
# as default once we get minstrel properly tested and blessed by
# our systems engineering team. CCK rates also need to be used
# for long range considerations.
--- a/drivers/net/wireless/b43/main.c
+++ b/drivers/net/wireless/b43/main.c
-@@ -322,83 +322,59 @@ static int b43_ratelimit(struct b43_wl *
+@@ -323,83 +323,59 @@ static int b43_ratelimit(struct b43_wl *
void b43info(struct b43_wl *wl, const char *fmt, ...)
{
--- a/config.mk
+++ b/config.mk
-@@ -207,7 +207,7 @@ CONFIG_ATH9K_COMMON=m
+@@ -210,7 +210,7 @@ CONFIG_ATH9K_COMMON=m
# PCI Drivers
ifdef CONFIG_PCI
-CONFIG_ATH5K_PCI=y
+# CONFIG_ATH5K_PCI=y
- CONFIG_ATH9K=m
+ CONFIG_ATH9K_PCI=y
CONFIG_IWLAGN=m
--- a/compat/compat-2.6.39.c
+++ b/compat/compat-2.6.39.c
-@@ -11,6 +11,7 @@
- #include <linux/compat.h>
+@@ -12,6 +12,7 @@
#include <linux/tty.h>
+ #include <linux/sched.h>
+#ifdef CONFIG_COMPAT_BLUETOOTH
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27))
/*
* Termios Helper Methods
-@@ -110,4 +111,4 @@ int tty_set_termios(struct tty_struct *t
+@@ -111,4 +112,4 @@ int tty_set_termios(struct tty_struct *t
}
EXPORT_SYMBOL_GPL(tty_set_termios);
#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27)) */
+++ /dev/null
---- a/compat/compat-2.6.32.c
-+++ b/compat/compat-2.6.32.c
-@@ -117,3 +117,100 @@ void __dev_addr_unsync(struct dev_addr_l
- }
- EXPORT_SYMBOL_GPL(__dev_addr_unsync);
-
-+/*
-+ * Nonzero if YEAR is a leap year (every 4 years,
-+ * except every 100th isn't, and every 400th is).
-+ */
-+static int __isleap(long year)
-+{
-+ return (year) % 4 == 0 && ((year) % 100 != 0 || (year) % 400 == 0);
-+}
-+
-+/* do a mathdiv for long type */
-+static long math_div(long a, long b)
-+{
-+ return a / b - (a % b < 0);
-+}
-+
-+/* How many leap years between y1 and y2, y1 must less or equal to y2 */
-+static long leaps_between(long y1, long y2)
-+{
-+ long leaps1 = math_div(y1 - 1, 4) - math_div(y1 - 1, 100)
-+ + math_div(y1 - 1, 400);
-+ long leaps2 = math_div(y2 - 1, 4) - math_div(y2 - 1, 100)
-+ + math_div(y2 - 1, 400);
-+ return leaps2 - leaps1;
-+}
-+
-+/* How many days come before each month (0-12). */
-+static const unsigned short __mon_yday[2][13] = {
-+ /* Normal years. */
-+ {0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365},
-+ /* Leap years. */
-+ {0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366}
-+};
-+
-+#define SECS_PER_HOUR (60 * 60)
-+#define SECS_PER_DAY (SECS_PER_HOUR * 24)
-+
-+/**
-+ * time_to_tm - converts the calendar time to local broken-down time
-+ *
-+ * @totalsecs the number of seconds elapsed since 00:00:00 on January 1, 1970,
-+ * Coordinated Universal Time (UTC).
-+ * @offset offset seconds adding to totalsecs.
-+ * @result pointer to struct tm variable to receive broken-down time
-+ */
-+void time_to_tm(time_t totalsecs, int offset, struct tm *result)
-+{
-+ long days, rem, y;
-+ const unsigned short *ip;
-+
-+ days = totalsecs / SECS_PER_DAY;
-+ rem = totalsecs % SECS_PER_DAY;
-+ rem += offset;
-+ while (rem < 0) {
-+ rem += SECS_PER_DAY;
-+ --days;
-+ }
-+ while (rem >= SECS_PER_DAY) {
-+ rem -= SECS_PER_DAY;
-+ ++days;
-+ }
-+
-+ result->tm_hour = rem / SECS_PER_HOUR;
-+ rem %= SECS_PER_HOUR;
-+ result->tm_min = rem / 60;
-+ result->tm_sec = rem % 60;
-+
-+ /* January 1, 1970 was a Thursday. */
-+ result->tm_wday = (4 + days) % 7;
-+ if (result->tm_wday < 0)
-+ result->tm_wday += 7;
-+
-+ y = 1970;
-+
-+ while (days < 0 || days >= (__isleap(y) ? 366 : 365)) {
-+ /* Guess a corrected year, assuming 365 days per year. */
-+ long yg = y + math_div(days, 365);
-+
-+ /* Adjust DAYS and Y to match the guessed year. */
-+ days -= (yg - y) * 365 + leaps_between(y, yg);
-+ y = yg;
-+ }
-+
-+ result->tm_year = y - 1900;
-+
-+ result->tm_yday = days;
-+
-+ ip = __mon_yday[__isleap(y)];
-+ for (y = 11; days < ip[y]; y--)
-+ continue;
-+ days -= ip[y];
-+
-+ result->tm_mon = y;
-+ result->tm_mday = days + 1;
-+}
-+EXPORT_SYMBOL(time_to_tm);
-+/* source: kernel/time/timeconv.c*/
-+
---- a/compat/compat-2.6.39.c
-+++ b/compat/compat-2.6.39.c
-@@ -10,6 +10,7 @@
-
- #include <linux/compat.h>
- #include <linux/tty.h>
-+#include <linux/sched.h>
-
- #ifdef CONFIG_COMPAT_BLUETOOTH
- #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27))
---- a/compat/kstrtox.c
-+++ b/compat/kstrtox.c
-@@ -11,6 +11,14 @@
- *
- * If -E is returned, result is not touched.
- */
-+#include <linux/kernel.h>
-+/*
-+ * kstrto* was included in kernel 2.6.38.4 and causes conflicts with the
-+ * version included in compat-wireless. We use strict_strtol to check if
-+ * kstrto* is already available.
-+ */
-+#ifndef strict_strtol
-+
- #include <linux/ctype.h>
- #include <linux/errno.h>
- #include <linux/kernel.h>
-@@ -225,3 +233,4 @@ int kstrtos8(const char *s, unsigned int
- return 0;
- }
- EXPORT_SYMBOL(kstrtos8);
-+#endif /* #ifndef strict_strtol */
---- a/include/linux/compat-2.6.32.h
-+++ b/include/linux/compat-2.6.32.h
-@@ -96,6 +96,34 @@ struct dev_pm_ops name = { \
-
- #define lockdep_assert_held(l) do { } while (0)
-
-+/*
-+ * Similar to the struct tm in userspace <time.h>, but it needs to be here so
-+ * that the kernel source is self contained.
-+ */
-+struct tm {
-+ /*
-+ * the number of seconds after the minute, normally in the range
-+ * 0 to 59, but can be up to 60 to allow for leap seconds
-+ */
-+ int tm_sec;
-+ /* the number of minutes after the hour, in the range 0 to 59*/
-+ int tm_min;
-+ /* the number of hours past midnight, in the range 0 to 23 */
-+ int tm_hour;
-+ /* the day of the month, in the range 1 to 31 */
-+ int tm_mday;
-+ /* the number of months since January, in the range 0 to 11 */
-+ int tm_mon;
-+ /* the number of years since 1900 */
-+ long tm_year;
-+ /* the number of days since Sunday, in the range 0 to 6 */
-+ int tm_wday;
-+ /* the number of days since January 1, in the range 0 to 365 */
-+ int tm_yday;
-+};
-+
-+void time_to_tm(time_t totalsecs, int offset, struct tm *result);
-+
- #endif /* (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,32)) */
-
- #endif /* LINUX_26_32_COMPAT_H */
---- a/include/linux/compat-2.6.39.h
-+++ b/include/linux/compat-2.6.39.h
-@@ -94,6 +94,12 @@ static inline struct msi_desc *irq_desc_
- }
- #endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,29)) */
-
-+/*
-+ * kstrto* was included in kernel 2.6.38.4 and causes conflicts with the
-+ * version included in compat-wireless. We use strict_strtol to check if
-+ * kstrto* is already available.
-+ */
-+#ifndef strict_strtol
- /* Internal, do not use. */
- int __must_check _kstrtoul(const char *s, unsigned int base, unsigned long *res);
- int __must_check _kstrtol(const char *s, unsigned int base, long *res);
-@@ -153,6 +159,7 @@ int __must_check kstrtou16(const char *s
- int __must_check kstrtos16(const char *s, unsigned int base, s16 *res);
- int __must_check kstrtou8(const char *s, unsigned int base, u8 *res);
- int __must_check kstrtos8(const char *s, unsigned int base, s8 *res);
-+#endif /* ifndef strict_strtol */
-
- #endif /* (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,39)) */
-
+++ /dev/null
---- a/include/linux/compat-2.6.36.h
-+++ b/include/linux/compat-2.6.36.h
-@@ -120,6 +120,9 @@ static inline void tty_unlock(void) __re
- #define tty_locked() (kernel_locked())
-
- #define usleep_range(_min, _max) msleep((_max) / 1000)
-+
-+#define PCI_EEPROM_WIDTH_93C86 8
-+
- #endif /* (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,36)) */
-
- #endif /* LINUX_26_36_COMPAT_H */
#endif
--- a/config.mk
+++ b/config.mk
-@@ -419,7 +419,7 @@ endif #CONFIG_COMPAT_KERNEL_29
+@@ -423,7 +423,7 @@ endif #CONFIG_COMPAT_KERNEL_29
# This activates a threading fix for usb urb.
# this is mainline commit: b3e670443b7fb8a2d29831b62b44a039c283e351
# This fix will be included in some stable releases.
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
#include <linux/kernel.h>
+--- a/drivers/net/wireless/libertas/cfg.c
++++ b/drivers/net/wireless/libertas/cfg.c
+@@ -6,6 +6,7 @@
+ *
+ */
+
++#undef pr_fmt
+ #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+ #include <linux/sched.h>
+--- a/drivers/net/wireless/libertas/if_cs.c
++++ b/drivers/net/wireless/libertas/if_cs.c
+@@ -21,6 +21,7 @@
+
+ */
+
++#undef pr_fmt
+ #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+ #include <linux/module.h>
+--- a/drivers/net/wireless/libertas/if_sdio.c
++++ b/drivers/net/wireless/libertas/if_sdio.c
+@@ -26,6 +26,7 @@
+ * if_sdio_card_to_host() to pad the data.
+ */
+
++#undef pr_fmt
+ #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+ #include <linux/kernel.h>
+--- a/drivers/net/wireless/libertas/if_spi.c
++++ b/drivers/net/wireless/libertas/if_spi.c
+@@ -17,6 +17,7 @@
+ * (at your option) any later version.
+ */
+
++#undef pr_fmt
+ #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+ #include <linux/moduleparam.h>
+--- a/drivers/net/wireless/libertas/if_usb.c
++++ b/drivers/net/wireless/libertas/if_usb.c
+@@ -2,6 +2,7 @@
+ * This file contains functions used in USB interface module.
+ */
+
++#undef pr_fmt
+ #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+ #include <linux/delay.h>
+--- a/drivers/net/wireless/libertas/main.c
++++ b/drivers/net/wireless/libertas/main.c
+@@ -4,6 +4,7 @@
+ * thread etc..
+ */
+
++#undef pr_fmt
+ #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+ #include <linux/moduleparam.h>
+--- a/drivers/net/wireless/libertas/mesh.c
++++ b/drivers/net/wireless/libertas/mesh.c
+@@ -1,3 +1,4 @@
++#undef pr_fmt
+ #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+ #include <linux/delay.h>
+--- a/drivers/net/wireless/libertas/rx.c
++++ b/drivers/net/wireless/libertas/rx.c
+@@ -2,6 +2,7 @@
+ * This file contains the handling of RX in wlan driver.
+ */
+
++#undef pr_fmt
+ #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+ #include <linux/etherdevice.h>
+++ /dev/null
---- a/net/wireless/reg.c
-+++ b/net/wireless/reg.c
-@@ -1456,7 +1456,8 @@ static void reg_process_hint(struct regu
- * We only time out user hints, given that they should be the only
- * source of bogus requests.
- */
-- if (reg_request->initiator == NL80211_REGDOM_SET_BY_USER)
-+ if (r != -EALREADY &&
-+ reg_request->initiator == NL80211_REGDOM_SET_BY_USER)
- schedule_delayed_work(®_timeout, msecs_to_jiffies(3142));
- }
-
---- a/drivers/net/wireless/ath/ath9k/ar9003_calib.c
-+++ b/drivers/net/wireless/ath/ath9k/ar9003_calib.c
-@@ -18,13 +18,13 @@
- #include "hw-ops.h"
- #include "ar9003_phy.h"
-
--#define MPASS 3
- #define MAX_MEASUREMENT 8
--#define MAX_DIFFERENCE 10
-+#define MAX_MAG_DELTA 11
-+#define MAX_PHS_DELTA 10
-
- struct coeff {
-- int mag_coeff[AR9300_MAX_CHAINS][MAX_MEASUREMENT][MPASS];
-- int phs_coeff[AR9300_MAX_CHAINS][MAX_MEASUREMENT][MPASS];
-+ int mag_coeff[AR9300_MAX_CHAINS][MAX_MEASUREMENT];
-+ int phs_coeff[AR9300_MAX_CHAINS][MAX_MEASUREMENT];
- int iqc_coeff[2];
- };
-
-@@ -608,36 +608,48 @@ static bool ar9003_hw_calc_iq_corr(struc
- return true;
- }
-
--static bool ar9003_hw_compute_closest_pass_and_avg(int *mp_coeff, int *mp_avg)
-+static void ar9003_hw_detect_outlier(int *mp_coeff, int nmeasurement,
-+ int max_delta)
- {
-- int diff[MPASS];
--
-- diff[0] = abs(mp_coeff[0] - mp_coeff[1]);
-- diff[1] = abs(mp_coeff[1] - mp_coeff[2]);
-- diff[2] = abs(mp_coeff[2] - mp_coeff[0]);
--
-- if (diff[0] > MAX_DIFFERENCE &&
-- diff[1] > MAX_DIFFERENCE &&
-- diff[2] > MAX_DIFFERENCE)
-- return false;
--
-- if (diff[0] <= diff[1] && diff[0] <= diff[2])
-- *mp_avg = (mp_coeff[0] + mp_coeff[1]) / 2;
-- else if (diff[1] <= diff[2])
-- *mp_avg = (mp_coeff[1] + mp_coeff[2]) / 2;
-- else
-- *mp_avg = (mp_coeff[2] + mp_coeff[0]) / 2;
-+ int mp_max = -64, max_idx = 0;
-+ int mp_min = 63, min_idx = 0;
-+ int mp_avg = 0, i, outlier_idx = 0;
-+
-+ /* find min/max mismatch across all calibrated gains */
-+ for (i = 0; i < nmeasurement; i++) {
-+ mp_avg += mp_coeff[i];
-+ if (mp_coeff[i] > mp_max) {
-+ mp_max = mp_coeff[i];
-+ max_idx = i;
-+ } else if (mp_coeff[i] < mp_min) {
-+ mp_min = mp_coeff[i];
-+ min_idx = i;
-+ }
-+ }
-
-- return true;
-+ /* find average (exclude max abs value) */
-+ for (i = 0; i < nmeasurement; i++) {
-+ if ((abs(mp_coeff[i]) < abs(mp_max)) ||
-+ (abs(mp_coeff[i]) < abs(mp_min)))
-+ mp_avg += mp_coeff[i];
-+ }
-+ mp_avg /= (nmeasurement - 1);
-+
-+ /* detect outlier */
-+ if (abs(mp_max - mp_min) > max_delta) {
-+ if (abs(mp_max - mp_avg) > abs(mp_min - mp_avg))
-+ outlier_idx = max_idx;
-+ else
-+ outlier_idx = min_idx;
-+ }
-+ mp_coeff[outlier_idx] = mp_avg;
- }
-
- static void ar9003_hw_tx_iqcal_load_avg_2_passes(struct ath_hw *ah,
- u8 num_chains,
- struct coeff *coeff)
- {
-- struct ath_common *common = ath9k_hw_common(ah);
- int i, im, nmeasurement;
-- int magnitude, phase;
- u32 tx_corr_coeff[MAX_MEASUREMENT][AR9300_MAX_CHAINS];
-
- memset(tx_corr_coeff, 0, sizeof(tx_corr_coeff));
-@@ -657,37 +669,28 @@ static void ar9003_hw_tx_iqcal_load_avg_
-
- /* Load the average of 2 passes */
- for (i = 0; i < num_chains; i++) {
-- if (AR_SREV_9485(ah))
-- nmeasurement = REG_READ_FIELD(ah,
-- AR_PHY_TX_IQCAL_STATUS_B0_9485,
-- AR_PHY_CALIBRATED_GAINS_0);
-- else
-- nmeasurement = REG_READ_FIELD(ah,
-- AR_PHY_TX_IQCAL_STATUS_B0,
-- AR_PHY_CALIBRATED_GAINS_0);
-+ nmeasurement = REG_READ_FIELD(ah,
-+ AR_PHY_TX_IQCAL_STATUS_B0,
-+ AR_PHY_CALIBRATED_GAINS_0);
-
- if (nmeasurement > MAX_MEASUREMENT)
- nmeasurement = MAX_MEASUREMENT;
-
-- for (im = 0; im < nmeasurement; im++) {
-- /*
-- * Determine which 2 passes are closest and compute avg
-- * magnitude
-- */
-- if (!ar9003_hw_compute_closest_pass_and_avg(coeff->mag_coeff[i][im],
-- &magnitude))
-- goto disable_txiqcal;
-+ /* detect outlier only if nmeasurement > 1 */
-+ if (nmeasurement > 1) {
-+ /* Detect magnitude outlier */
-+ ar9003_hw_detect_outlier(coeff->mag_coeff[i],
-+ nmeasurement, MAX_MAG_DELTA);
-+
-+ /* Detect phase outlier */
-+ ar9003_hw_detect_outlier(coeff->phs_coeff[i],
-+ nmeasurement, MAX_PHS_DELTA);
-+ }
-
-- /*
-- * Determine which 2 passes are closest and compute avg
-- * phase
-- */
-- if (!ar9003_hw_compute_closest_pass_and_avg(coeff->phs_coeff[i][im],
-- &phase))
-- goto disable_txiqcal;
-+ for (im = 0; im < nmeasurement; im++) {
-
-- coeff->iqc_coeff[0] = (magnitude & 0x7f) |
-- ((phase & 0x7f) << 7);
-+ coeff->iqc_coeff[0] = (coeff->mag_coeff[i][im] & 0x7f) |
-+ ((coeff->phs_coeff[i][im] & 0x7f) << 7);
-
- if ((im % 2) == 0)
- REG_RMW_FIELD(ah, tx_corr_coeff[im][i],
-@@ -707,141 +710,37 @@ static void ar9003_hw_tx_iqcal_load_avg_
-
- return;
-
--disable_txiqcal:
-- REG_RMW_FIELD(ah, AR_PHY_TX_IQCAL_CONTROL_3,
-- AR_PHY_TX_IQCAL_CONTROL_3_IQCORR_EN, 0x0);
-- REG_RMW_FIELD(ah, AR_PHY_RX_IQCAL_CORR_B0,
-- AR_PHY_RX_IQCAL_CORR_B0_LOOPBACK_IQCORR_EN, 0x0);
--
-- ath_dbg(common, ATH_DBG_CALIBRATE, "TX IQ Cal disabled\n");
- }
-
--static void ar9003_hw_tx_iq_cal(struct ath_hw *ah)
-+static bool ar9003_hw_tx_iq_cal_run(struct ath_hw *ah)
- {
- struct ath_common *common = ath9k_hw_common(ah);
-- static const u32 txiqcal_status[AR9300_MAX_CHAINS] = {
-- AR_PHY_TX_IQCAL_STATUS_B0,
-- AR_PHY_TX_IQCAL_STATUS_B1,
-- AR_PHY_TX_IQCAL_STATUS_B2,
-- };
-- static const u32 chan_info_tab[] = {
-- AR_PHY_CHAN_INFO_TAB_0,
-- AR_PHY_CHAN_INFO_TAB_1,
-- AR_PHY_CHAN_INFO_TAB_2,
-- };
-- struct coeff coeff;
-- s32 iq_res[6];
-- s32 i, j, ip, im, nmeasurement;
-- u8 nchains = get_streams(common->tx_chainmask);
--
-- for (ip = 0; ip < MPASS; ip++) {
-- REG_RMW_FIELD(ah, AR_PHY_TX_IQCAL_CONTROL_1,
-- AR_PHY_TX_IQCAQL_CONTROL_1_IQCORR_I_Q_COFF_DELPT,
-- DELPT);
-- REG_RMW_FIELD(ah, AR_PHY_TX_IQCAL_START,
-- AR_PHY_TX_IQCAL_START_DO_CAL,
-- AR_PHY_TX_IQCAL_START_DO_CAL);
--
-- if (!ath9k_hw_wait(ah, AR_PHY_TX_IQCAL_START,
-- AR_PHY_TX_IQCAL_START_DO_CAL,
-- 0, AH_WAIT_TIMEOUT)) {
-- ath_dbg(common, ATH_DBG_CALIBRATE,
-- "Tx IQ Cal not complete.\n");
-- goto TX_IQ_CAL_FAILED;
-- }
--
-- nmeasurement = REG_READ_FIELD(ah, AR_PHY_TX_IQCAL_STATUS_B0,
-- AR_PHY_CALIBRATED_GAINS_0);
-- if (nmeasurement > MAX_MEASUREMENT)
-- nmeasurement = MAX_MEASUREMENT;
--
-- for (i = 0; i < nchains; i++) {
-- ath_dbg(common, ATH_DBG_CALIBRATE,
-- "Doing Tx IQ Cal for chain %d.\n", i);
-- for (im = 0; im < nmeasurement; im++) {
-- if (REG_READ(ah, txiqcal_status[i]) &
-- AR_PHY_TX_IQCAL_STATUS_FAILED) {
-- ath_dbg(common, ATH_DBG_CALIBRATE,
-- "Tx IQ Cal failed for chain %d.\n", i);
-- goto TX_IQ_CAL_FAILED;
-- }
--
-- for (j = 0; j < 3; j++) {
-- u8 idx = 2 * j,
-- offset = 4 * (3 * im + j);
--
-- REG_RMW_FIELD(ah, AR_PHY_CHAN_INFO_MEMORY,
-- AR_PHY_CHAN_INFO_TAB_S2_READ,
-- 0);
--
-- /* 32 bits */
-- iq_res[idx] = REG_READ(ah,
-- chan_info_tab[i] +
-- offset);
--
-- REG_RMW_FIELD(ah, AR_PHY_CHAN_INFO_MEMORY,
-- AR_PHY_CHAN_INFO_TAB_S2_READ,
-- 1);
--
-- /* 16 bits */
-- iq_res[idx+1] = 0xffff & REG_READ(ah,
-- chan_info_tab[i] +
-- offset);
--
-- ath_dbg(common, ATH_DBG_CALIBRATE,
-- "IQ RES[%d]=0x%x IQ_RES[%d]=0x%x\n",
-- idx, iq_res[idx], idx+1, iq_res[idx+1]);
-- }
--
-- if (!ar9003_hw_calc_iq_corr(ah, i, iq_res,
-- coeff.iqc_coeff)) {
-- ath_dbg(common, ATH_DBG_CALIBRATE,
-- "Failed in calculation of IQ correction.\n");
-- goto TX_IQ_CAL_FAILED;
-- }
-- coeff.mag_coeff[i][im][ip] =
-- coeff.iqc_coeff[0] & 0x7f;
-- coeff.phs_coeff[i][im][ip] =
-- (coeff.iqc_coeff[0] >> 7) & 0x7f;
--
-- if (coeff.mag_coeff[i][im][ip] > 63)
-- coeff.mag_coeff[i][im][ip] -= 128;
-- if (coeff.phs_coeff[i][im][ip] > 63)
-- coeff.phs_coeff[i][im][ip] -= 128;
--
-- }
-- }
-- }
--
-- ar9003_hw_tx_iqcal_load_avg_2_passes(ah, nchains, &coeff);
--
-- return;
--
--TX_IQ_CAL_FAILED:
-- ath_dbg(common, ATH_DBG_CALIBRATE, "Tx IQ Cal failed\n");
--}
--
--static void ar9003_hw_tx_iq_cal_run(struct ath_hw *ah)
--{
- u8 tx_gain_forced;
-
-- REG_RMW_FIELD(ah, AR_PHY_TX_IQCAL_CONTROL_1_9485,
-- AR_PHY_TX_IQCAQL_CONTROL_1_IQCORR_I_Q_COFF_DELPT, DELPT);
- tx_gain_forced = REG_READ_FIELD(ah, AR_PHY_TX_FORCED_GAIN,
- AR_PHY_TXGAIN_FORCE);
- if (tx_gain_forced)
- REG_RMW_FIELD(ah, AR_PHY_TX_FORCED_GAIN,
- AR_PHY_TXGAIN_FORCE, 0);
-
-- REG_RMW_FIELD(ah, AR_PHY_TX_IQCAL_START_9485,
-- AR_PHY_TX_IQCAL_START_DO_CAL_9485, 1);
-+ REG_RMW_FIELD(ah, AR_PHY_TX_IQCAL_START,
-+ AR_PHY_TX_IQCAL_START_DO_CAL, 1);
-+
-+ if (!ath9k_hw_wait(ah, AR_PHY_TX_IQCAL_START,
-+ AR_PHY_TX_IQCAL_START_DO_CAL, 0,
-+ AH_WAIT_TIMEOUT)) {
-+ ath_dbg(common, ATH_DBG_CALIBRATE,
-+ "Tx IQ Cal is not completed.\n");
-+ return false;
-+ }
-+ return true;
- }
-
- static void ar9003_hw_tx_iq_cal_post_proc(struct ath_hw *ah)
- {
- struct ath_common *common = ath9k_hw_common(ah);
- const u32 txiqcal_status[AR9300_MAX_CHAINS] = {
-- AR_PHY_TX_IQCAL_STATUS_B0_9485,
-+ AR_PHY_TX_IQCAL_STATUS_B0,
- AR_PHY_TX_IQCAL_STATUS_B1,
- AR_PHY_TX_IQCAL_STATUS_B2,
- };
-@@ -853,7 +752,7 @@ static void ar9003_hw_tx_iq_cal_post_pro
- struct coeff coeff;
- s32 iq_res[6];
- u8 num_chains = 0;
-- int i, ip, im, j;
-+ int i, im, j;
- int nmeasurement;
-
- for (i = 0; i < AR9300_MAX_CHAINS; i++) {
-@@ -861,71 +760,69 @@ static void ar9003_hw_tx_iq_cal_post_pro
- num_chains++;
- }
-
-- for (ip = 0; ip < MPASS; ip++) {
-- for (i = 0; i < num_chains; i++) {
-- nmeasurement = REG_READ_FIELD(ah,
-- AR_PHY_TX_IQCAL_STATUS_B0_9485,
-- AR_PHY_CALIBRATED_GAINS_0);
-- if (nmeasurement > MAX_MEASUREMENT)
-- nmeasurement = MAX_MEASUREMENT;
-+ for (i = 0; i < num_chains; i++) {
-+ nmeasurement = REG_READ_FIELD(ah,
-+ AR_PHY_TX_IQCAL_STATUS_B0,
-+ AR_PHY_CALIBRATED_GAINS_0);
-+ if (nmeasurement > MAX_MEASUREMENT)
-+ nmeasurement = MAX_MEASUREMENT;
-+
-+ for (im = 0; im < nmeasurement; im++) {
-+ ath_dbg(common, ATH_DBG_CALIBRATE,
-+ "Doing Tx IQ Cal for chain %d.\n", i);
-
-- for (im = 0; im < nmeasurement; im++) {
-+ if (REG_READ(ah, txiqcal_status[i]) &
-+ AR_PHY_TX_IQCAL_STATUS_FAILED) {
- ath_dbg(common, ATH_DBG_CALIBRATE,
-- "Doing Tx IQ Cal for chain %d.\n", i);
--
-- if (REG_READ(ah, txiqcal_status[i]) &
-- AR_PHY_TX_IQCAL_STATUS_FAILED) {
-- ath_dbg(common, ATH_DBG_CALIBRATE,
- "Tx IQ Cal failed for chain %d.\n", i);
-- goto tx_iqcal_fail;
-- }
-+ goto tx_iqcal_fail;
-+ }
-
-- for (j = 0; j < 3; j++) {
-- u32 idx = 2 * j, offset = 4 * (3 * im + j);
-+ for (j = 0; j < 3; j++) {
-+ u32 idx = 2 * j, offset = 4 * (3 * im + j);
-
-- REG_RMW_FIELD(ah,
-+ REG_RMW_FIELD(ah,
- AR_PHY_CHAN_INFO_MEMORY,
- AR_PHY_CHAN_INFO_TAB_S2_READ,
- 0);
-
-- /* 32 bits */
-- iq_res[idx] = REG_READ(ah,
-- chan_info_tab[i] +
-- offset);
-+ /* 32 bits */
-+ iq_res[idx] = REG_READ(ah,
-+ chan_info_tab[i] +
-+ offset);
-
-- REG_RMW_FIELD(ah,
-+ REG_RMW_FIELD(ah,
- AR_PHY_CHAN_INFO_MEMORY,
- AR_PHY_CHAN_INFO_TAB_S2_READ,
- 1);
-
-- /* 16 bits */
-- iq_res[idx + 1] = 0xffff & REG_READ(ah,
-- chan_info_tab[i] + offset);
--
-- ath_dbg(common, ATH_DBG_CALIBRATE,
-- "IQ RES[%d]=0x%x"
-- "IQ_RES[%d]=0x%x\n",
-- idx, iq_res[idx], idx + 1,
-- iq_res[idx + 1]);
-- }
-+ /* 16 bits */
-+ iq_res[idx + 1] = 0xffff & REG_READ(ah,
-+ chan_info_tab[i] + offset);
-
-- if (!ar9003_hw_calc_iq_corr(ah, i, iq_res,
-- coeff.iqc_coeff)) {
-- ath_dbg(common, ATH_DBG_CALIBRATE,
-- "Failed in calculation of IQ correction.\n");
-- goto tx_iqcal_fail;
-- }
-+ ath_dbg(common, ATH_DBG_CALIBRATE,
-+ "IQ RES[%d]=0x%x"
-+ "IQ_RES[%d]=0x%x\n",
-+ idx, iq_res[idx], idx + 1,
-+ iq_res[idx + 1]);
-+ }
-
-- coeff.mag_coeff[i][im][ip] =
-- coeff.iqc_coeff[0] & 0x7f;
-- coeff.phs_coeff[i][im][ip] =
-- (coeff.iqc_coeff[0] >> 7) & 0x7f;
--
-- if (coeff.mag_coeff[i][im][ip] > 63)
-- coeff.mag_coeff[i][im][ip] -= 128;
-- if (coeff.phs_coeff[i][im][ip] > 63)
-- coeff.phs_coeff[i][im][ip] -= 128;
-+ if (!ar9003_hw_calc_iq_corr(ah, i, iq_res,
-+ coeff.iqc_coeff)) {
-+ ath_dbg(common, ATH_DBG_CALIBRATE,
-+ "Failed in calculation of \
-+ IQ correction.\n");
-+ goto tx_iqcal_fail;
- }
-+
-+ coeff.mag_coeff[i][im] = coeff.iqc_coeff[0] & 0x7f;
-+ coeff.phs_coeff[i][im] =
-+ (coeff.iqc_coeff[0] >> 7) & 0x7f;
-+
-+ if (coeff.mag_coeff[i][im] > 63)
-+ coeff.mag_coeff[i][im] -= 128;
-+ if (coeff.phs_coeff[i][im] > 63)
-+ coeff.phs_coeff[i][im] -= 128;
- }
- }
- ar9003_hw_tx_iqcal_load_avg_2_passes(ah, num_chains, &coeff);
-@@ -941,6 +838,7 @@ static bool ar9003_hw_init_cal(struct at
- {
- struct ath_common *common = ath9k_hw_common(ah);
- int val;
-+ bool txiqcal_done = false;
-
- val = REG_READ(ah, AR_ENT_OTP);
- ath_dbg(common, ATH_DBG_CALIBRATE, "ath9k: AR_ENT_OTP 0x%x\n", val);
-@@ -957,14 +855,22 @@ static bool ar9003_hw_init_cal(struct at
- ar9003_hw_set_chain_masks(ah, 0x7, 0x7);
-
- /* Do Tx IQ Calibration */
-- if (AR_SREV_9485(ah))
-- ar9003_hw_tx_iq_cal_run(ah);
-- else
-- ar9003_hw_tx_iq_cal(ah);
-+ REG_RMW_FIELD(ah, AR_PHY_TX_IQCAL_CONTROL_1,
-+ AR_PHY_TX_IQCAL_CONTROL_1_IQCORR_I_Q_COFF_DELPT,
-+ DELPT);
-
-- REG_WRITE(ah, AR_PHY_ACTIVE, AR_PHY_ACTIVE_DIS);
-- udelay(5);
-- REG_WRITE(ah, AR_PHY_ACTIVE, AR_PHY_ACTIVE_EN);
-+ /*
-+ * For AR9485 or later chips, TxIQ cal runs as part of
-+ * AGC calibration
-+ */
-+ if (AR_SREV_9485_OR_LATER(ah))
-+ txiqcal_done = true;
-+ else {
-+ txiqcal_done = ar9003_hw_tx_iq_cal_run(ah);
-+ REG_WRITE(ah, AR_PHY_ACTIVE, AR_PHY_ACTIVE_DIS);
-+ udelay(5);
-+ REG_WRITE(ah, AR_PHY_ACTIVE, AR_PHY_ACTIVE_EN);
-+ }
-
- /* Calibrate the AGC */
- REG_WRITE(ah, AR_PHY_AGC_CONTROL,
-@@ -979,7 +885,7 @@ static bool ar9003_hw_init_cal(struct at
- return false;
- }
-
-- if (AR_SREV_9485(ah))
-+ if (txiqcal_done)
- ar9003_hw_tx_iq_cal_post_proc(ah);
-
- /* Revert chainmasks to their original values before NF cal */
---- a/drivers/net/wireless/ath/ath9k/ar9003_phy.h
-+++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.h
-@@ -548,15 +548,12 @@
-
- #define AR_PHY_TXGAIN_TABLE (AR_SM_BASE + 0x300)
-
--#define AR_PHY_TX_IQCAL_START_9485 (AR_SM_BASE + 0x3c4)
--#define AR_PHY_TX_IQCAL_START_DO_CAL_9485 0x80000000
--#define AR_PHY_TX_IQCAL_START_DO_CAL_9485_S 31
--#define AR_PHY_TX_IQCAL_CONTROL_1_9485 (AR_SM_BASE + 0x3c8)
--#define AR_PHY_TX_IQCAL_STATUS_B0_9485 (AR_SM_BASE + 0x3f0)
--
--#define AR_PHY_TX_IQCAL_CONTROL_1 (AR_SM_BASE + 0x448)
--#define AR_PHY_TX_IQCAL_START (AR_SM_BASE + 0x440)
--#define AR_PHY_TX_IQCAL_STATUS_B0 (AR_SM_BASE + 0x48c)
-+#define AR_PHY_TX_IQCAL_CONTROL_1 (AR_SM_BASE + AR_SREV_9485(ah) ? \
-+ 0x3c8 : 0x448)
-+#define AR_PHY_TX_IQCAL_START (AR_SM_BASE + AR_SREV_9485(ah) ? \
-+ 0x3c4 : 0x440)
-+#define AR_PHY_TX_IQCAL_STATUS_B0 (AR_SM_BASE + AR_SREV_9485(ah) ? \
-+ 0x3f0 : 0x48c)
- #define AR_PHY_TX_IQCAL_CORR_COEFF_B0(_i) (AR_SM_BASE + \
- (AR_SREV_9485(ah) ? \
- 0x3d0 : 0x450) + ((_i) << 2))
-@@ -758,10 +755,10 @@
- #define AR_PHY_SPECTRAL_SCAN_SHORT_REPEAT 0x01000000
- #define AR_PHY_SPECTRAL_SCAN_SHORT_REPEAT_S 24
- #define AR_PHY_CHANNEL_STATUS_RX_CLEAR 0x00000004
--#define AR_PHY_TX_IQCAQL_CONTROL_1_IQCORR_I_Q_COFF_DELPT 0x01fc0000
--#define AR_PHY_TX_IQCAQL_CONTROL_1_IQCORR_I_Q_COFF_DELPT_S 18
--#define AR_PHY_TX_IQCAL_START_DO_CAL 0x00000001
--#define AR_PHY_TX_IQCAL_START_DO_CAL_S 0
-+#define AR_PHY_TX_IQCAL_CONTROL_1_IQCORR_I_Q_COFF_DELPT 0x01fc0000
-+#define AR_PHY_TX_IQCAL_CONTROL_1_IQCORR_I_Q_COFF_DELPT_S 18
-+#define AR_PHY_TX_IQCAL_START_DO_CAL 0x00000001
-+#define AR_PHY_TX_IQCAL_START_DO_CAL_S 0
-
- #define AR_PHY_TX_IQCAL_STATUS_FAILED 0x00000001
- #define AR_PHY_CALIBRATED_GAINS_0 0x3e
---- a/drivers/net/wireless/ath/ath9k/ath9k.h
-+++ b/drivers/net/wireless/ath/ath9k/ath9k.h
-@@ -453,6 +453,7 @@ void ath9k_btcoex_timer_pause(struct ath
-
- #define ATH_LED_PIN_DEF 1
- #define ATH_LED_PIN_9287 8
-+#define ATH_LED_PIN_9300 10
- #define ATH_LED_PIN_9485 6
-
- #ifdef CONFIG_MAC80211_LEDS
---- a/drivers/net/wireless/ath/ath9k/gpio.c
-+++ b/drivers/net/wireless/ath/ath9k/gpio.c
-@@ -46,6 +46,8 @@ void ath_init_leds(struct ath_softc *sc)
- sc->sc_ah->led_pin = ATH_LED_PIN_9287;
- else if (AR_SREV_9485(sc->sc_ah))
- sc->sc_ah->led_pin = ATH_LED_PIN_9485;
-+ else if (AR_SREV_9300(sc->sc_ah))
-+ sc->sc_ah->led_pin = ATH_LED_PIN_9300;
- else
- sc->sc_ah->led_pin = ATH_LED_PIN_DEF;
- }
---- a/drivers/net/wireless/ath/ath9k/reg.h
-+++ b/drivers/net/wireless/ath/ath9k/reg.h
-@@ -868,6 +868,8 @@
- #define AR_SREV_9485_11(_ah) \
- (AR_SREV_9485(_ah) && \
- ((_ah)->hw_version.macRev == AR_SREV_REVISION_9485_11))
-+#define AR_SREV_9485_OR_LATER(_ah) \
-+ (((_ah)->hw_version.macVersion >= AR_SREV_VERSION_9485))
-
- #define AR_SREV_9285E_20(_ah) \
- (AR_SREV_9285_12_OR_LATER(_ah) && \
---- a/net/mac80211/rx.c
-+++ b/net/mac80211/rx.c
-@@ -652,7 +652,7 @@ static void ieee80211_sta_reorder_releas
- set_release_timer:
-
- mod_timer(&tid_agg_rx->reorder_timer,
-- tid_agg_rx->reorder_time[j] +
-+ tid_agg_rx->reorder_time[j] + 1 +
- HT_RX_REORDER_BUF_TIMEOUT);
- } else {
- del_timer(&tid_agg_rx->reorder_timer);
---- a/drivers/net/wireless/ath/ath9k/calib.c
-+++ b/drivers/net/wireless/ath/ath9k/calib.c
-@@ -69,15 +69,21 @@ static void ath9k_hw_update_nfcal_hist_b
- int16_t *nfarray)
- {
- struct ath_common *common = ath9k_hw_common(ah);
-+ struct ieee80211_conf *conf = &common->hw->conf;
- struct ath_nf_limits *limit;
- struct ath9k_nfcal_hist *h;
- bool high_nf_mid = false;
-+ u8 chainmask = (ah->rxchainmask << 3) | ah->rxchainmask;
- int i;
-
- h = cal->nfCalHist;
- limit = ath9k_hw_get_nf_limits(ah, ah->curchan);
-
- for (i = 0; i < NUM_NF_READINGS; i++) {
-+ if (!(chainmask & (1 << i)) ||
-+ ((i >= AR5416_MAX_CHAINS) && !conf_is_ht40(conf)))
-+ continue;
-+
- h[i].nfCalBuffer[h[i].currIndex] = nfarray[i];
-
- if (++h[i].currIndex >= ATH9K_NF_CAL_HIST_MAX)
-@@ -225,6 +231,7 @@ void ath9k_hw_loadnf(struct ath_hw *ah,
- int32_t val;
- u8 chainmask = (ah->rxchainmask << 3) | ah->rxchainmask;
- struct ath_common *common = ath9k_hw_common(ah);
-+ struct ieee80211_conf *conf = &common->hw->conf;
- s16 default_nf = ath9k_hw_get_default_nf(ah, chan);
-
- if (ah->caldata)
-@@ -234,6 +241,9 @@ void ath9k_hw_loadnf(struct ath_hw *ah,
- if (chainmask & (1 << i)) {
- s16 nfval;
-
-+ if ((i >= AR5416_MAX_CHAINS) && !conf_is_ht40(conf))
-+ continue;
-+
- if (h)
- nfval = h[i].privNF;
- else
-@@ -293,6 +303,9 @@ void ath9k_hw_loadnf(struct ath_hw *ah,
- ENABLE_REGWRITE_BUFFER(ah);
- for (i = 0; i < NUM_NF_READINGS; i++) {
- if (chainmask & (1 << i)) {
-+ if ((i >= AR5416_MAX_CHAINS) && !conf_is_ht40(conf))
-+ continue;
-+
- val = REG_READ(ah, ah->nf_regs[i]);
- val &= 0xFFFFFE00;
- val |= (((u32) (-50) << 1) & 0x1ff);
#include <asm/unaligned.h>
#include "hw.h"
-@@ -423,8 +424,16 @@ static int ath9k_hw_init_macaddr(struct
+@@ -434,8 +435,16 @@ static int ath9k_hw_init_macaddr(struct
common->macaddr[2 * i] = eeval >> 8;
common->macaddr[2 * i + 1] = eeval & 0xff;
}
--- a/net/wireless/reg.c
+++ b/net/wireless/reg.c
-@@ -1629,6 +1629,8 @@ void regulatory_hint_11d(struct wiphy *w
+@@ -1643,6 +1643,8 @@ void regulatory_hint_11d(struct wiphy *w
enum environment_cap env = ENVIRON_ANY;
struct regulatory_request *request;
mutex_lock(®_mutex);
if (unlikely(!last_request))
-@@ -1835,6 +1837,8 @@ static void restore_regulatory_settings(
+@@ -1849,6 +1851,8 @@ static void restore_regulatory_settings(
void regulatory_hint_disconnect(void)
{
--- a/drivers/net/wireless/ath/ath9k/main.c
+++ b/drivers/net/wireless/ath/ath9k/main.c
-@@ -1439,15 +1439,6 @@ static int ath9k_add_interface(struct ie
+@@ -1480,15 +1480,6 @@ static int ath9k_add_interface(struct ie
}
}
ath_dbg(common, ATH_DBG_CONFIG,
"Attach a VIF of type: %d\n", vif->type);
-@@ -1473,15 +1464,6 @@ static int ath9k_change_interface(struct
+@@ -1514,15 +1505,6 @@ static int ath9k_change_interface(struct
mutex_lock(&sc->mutex);
ath9k_ps_wakeup(sc);
/* scratch buffers for virt_to_page() (crypto API) */
--- a/net/mac80211/wpa.c
+++ b/net/mac80211/wpa.c
-@@ -407,6 +407,13 @@ ieee80211_crypto_ccmp_encrypt(struct iee
+@@ -441,6 +441,13 @@ ieee80211_crypto_ccmp_encrypt(struct iee
return TX_CONTINUE;
}
ieee80211_rx_result
ieee80211_crypto_ccmp_decrypt(struct ieee80211_rx_data *rx)
-@@ -419,6 +426,7 @@ ieee80211_crypto_ccmp_decrypt(struct iee
+@@ -453,6 +460,7 @@ ieee80211_crypto_ccmp_decrypt(struct iee
u8 pn[CCMP_PN_LEN];
int data_len;
int queue;
hdrlen = ieee80211_hdrlen(hdr->frame_control);
-@@ -452,6 +460,11 @@ ieee80211_crypto_ccmp_decrypt(struct iee
+@@ -486,6 +494,11 @@ ieee80211_crypto_ccmp_decrypt(struct iee
return RX_DROP_UNUSABLE;
}
--- a/drivers/net/wireless/ath/ath9k/debug.c
+++ b/drivers/net/wireless/ath/ath9k/debug.c
-@@ -1115,6 +1115,53 @@ static const struct file_operations fops
+@@ -1120,6 +1120,53 @@ static const struct file_operations fops
.llseek = default_llseek,/* read accesses f_pos */
};
int ath9k_init_debug(struct ath_hw *ah)
{
struct ath_common *common = ath9k_hw_common(ah);
-@@ -1163,6 +1210,9 @@ int ath9k_init_debug(struct ath_hw *ah)
+@@ -1168,6 +1215,9 @@ int ath9k_init_debug(struct ath_hw *ah)
debugfs_create_u32("gpio_val", S_IRUSR | S_IWUSR,
sc->debug.debugfs_phy, &sc->sc_ah->gpio_val);
--- a/drivers/net/wireless/ath/ath9k/hw.c
+++ b/drivers/net/wireless/ath/ath9k/hw.c
-@@ -1450,8 +1450,8 @@ int ath9k_hw_reset(struct ath_hw *ah, st
+@@ -1508,8 +1508,8 @@ int ath9k_hw_reset(struct ath_hw *ah, st
REG_WRITE(ah, AR_OBS, 8);
if (ah->config.rx_intr_mitigation) {
--- a/drivers/net/wireless/ath/ath9k/ath9k.h
+++ b/drivers/net/wireless/ath/ath9k/ath9k.h
-@@ -367,7 +367,7 @@ struct ath_vif {
+@@ -366,7 +366,7 @@ struct ath_vif {
* number of beacon intervals, the game's up.
*/
#define BSTUCK_THRESH 9
#define IEEE80211_MS_TO_TU(x) (((x) * 1000) / 1024)
--- a/drivers/net/wireless/ath/ath9k/hw.c
+++ b/drivers/net/wireless/ath/ath9k/hw.c
-@@ -344,8 +344,8 @@ static void ath9k_hw_init_config(struct
+@@ -355,8 +355,8 @@ static void ath9k_hw_init_config(struct
{
int i;
--- /dev/null
+--- a/net/mac80211/sta_info.h
++++ b/net/mac80211/sta_info.h
+@@ -31,7 +31,6 @@
+ * frames.
+ * @WLAN_STA_ASSOC_AP: We're associated to that station, it is an AP.
+ * @WLAN_STA_WME: Station is a QoS-STA.
+- * @WLAN_STA_WDS: Station is one of our WDS peers.
+ * @WLAN_STA_CLEAR_PS_FILT: Clear PS filter in hardware (using the
+ * IEEE80211_TX_CTL_CLEAR_PS_FILT control flag) when the next
+ * frame to this station is transmitted.
+@@ -54,7 +53,6 @@ enum ieee80211_sta_info_flags {
+ WLAN_STA_SHORT_PREAMBLE = 1<<4,
+ WLAN_STA_ASSOC_AP = 1<<5,
+ WLAN_STA_WME = 1<<6,
+- WLAN_STA_WDS = 1<<7,
+ WLAN_STA_CLEAR_PS_FILT = 1<<9,
+ WLAN_STA_MFP = 1<<10,
+ WLAN_STA_BLOCK_BA = 1<<11,
+--- a/net/mac80211/debugfs_sta.c
++++ b/net/mac80211/debugfs_sta.c
+@@ -59,7 +59,7 @@ static ssize_t sta_flags_read(struct fil
+ char buf[100];
+ struct sta_info *sta = file->private_data;
+ u32 staflags = get_sta_flags(sta);
+- int res = scnprintf(buf, sizeof(buf), "%s%s%s%s%s%s%s%s%s",
++ int res = scnprintf(buf, sizeof(buf), "%s%s%s%s%s%s%s%s",
+ staflags & WLAN_STA_AUTH ? "AUTH\n" : "",
+ staflags & WLAN_STA_ASSOC ? "ASSOC\n" : "",
+ staflags & WLAN_STA_PS_STA ? "PS (sta)\n" : "",
+@@ -67,7 +67,6 @@ static ssize_t sta_flags_read(struct fil
+ staflags & WLAN_STA_AUTHORIZED ? "AUTHORIZED\n" : "",
+ staflags & WLAN_STA_SHORT_PREAMBLE ? "SHORT PREAMBLE\n" : "",
+ staflags & WLAN_STA_WME ? "WME\n" : "",
+- staflags & WLAN_STA_WDS ? "WDS\n" : "",
+ staflags & WLAN_STA_MFP ? "MFP\n" : "");
+ return simple_read_from_buffer(userbuf, count, ppos, buf, res);
+ }
--- /dev/null
+--- a/net/mac80211/rx.c
++++ b/net/mac80211/rx.c
+@@ -2335,13 +2335,14 @@ ieee80211_rx_h_mgmt(struct ieee80211_rx_
+
+ if (!ieee80211_vif_is_mesh(&sdata->vif) &&
+ sdata->vif.type != NL80211_IFTYPE_ADHOC &&
+- sdata->vif.type != NL80211_IFTYPE_STATION)
++ sdata->vif.type != NL80211_IFTYPE_STATION &&
++ sdata->vif.type != NL80211_IFTYPE_WDS)
+ return RX_DROP_MONITOR;
+
+ switch (stype) {
+ case cpu_to_le16(IEEE80211_STYPE_BEACON):
+ case cpu_to_le16(IEEE80211_STYPE_PROBE_RESP):
+- /* process for all: mesh, mlme, ibss */
++ /* process for all: mesh, mlme, ibss, wds */
+ break;
+ case cpu_to_le16(IEEE80211_STYPE_DEAUTH):
+ case cpu_to_le16(IEEE80211_STYPE_DISASSOC):
+@@ -2680,7 +2681,10 @@ static int prepare_for_handlers(struct i
+ }
+ break;
+ case NL80211_IFTYPE_WDS:
+- if (bssid || !ieee80211_is_data(hdr->frame_control))
++ if (bssid) {
++ if (!ieee80211_is_beacon(hdr->frame_control))
++ return 0;
++ } else if (!ieee80211_is_data(hdr->frame_control))
+ return 0;
+ if (compare_ether_addr(sdata->u.wds.remote_addr, hdr->addr2))
+ return 0;
+--- a/net/mac80211/iface.c
++++ b/net/mac80211/iface.c
+@@ -178,7 +178,6 @@ static int ieee80211_do_open(struct net_
+ {
+ struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
+ struct ieee80211_local *local = sdata->local;
+- struct sta_info *sta;
+ u32 changed = 0;
+ int res;
+ u32 hw_reconf_flags = 0;
+@@ -290,27 +289,6 @@ static int ieee80211_do_open(struct net_
+
+ set_bit(SDATA_STATE_RUNNING, &sdata->state);
+
+- if (sdata->vif.type == NL80211_IFTYPE_WDS) {
+- /* Create STA entry for the WDS peer */
+- sta = sta_info_alloc(sdata, sdata->u.wds.remote_addr,
+- GFP_KERNEL);
+- if (!sta) {
+- res = -ENOMEM;
+- goto err_del_interface;
+- }
+-
+- /* no locking required since STA is not live yet */
+- sta->flags |= WLAN_STA_AUTHORIZED;
+-
+- res = sta_info_insert(sta);
+- if (res) {
+- /* STA has been freed */
+- goto err_del_interface;
+- }
+-
+- rate_control_rate_init(sta);
+- }
+-
+ /*
+ * set_multicast_list will be invoked by the networking core
+ * which will check whether any increments here were done in
+@@ -344,8 +322,7 @@ static int ieee80211_do_open(struct net_
+ netif_tx_start_all_queues(dev);
+
+ return 0;
+- err_del_interface:
+- drv_remove_interface(local, &sdata->vif);
++
+ err_stop:
+ if (!local->open_count)
+ drv_stop(local);
+@@ -718,6 +695,70 @@ static void ieee80211_if_setup(struct ne
+ dev->destructor = free_netdev;
+ }
+
++static void ieee80211_wds_rx_queued_mgmt(struct ieee80211_sub_if_data *sdata,
++ struct sk_buff *skb)
++{
++ struct ieee80211_local *local = sdata->local;
++ struct ieee80211_rx_status *rx_status;
++ struct ieee802_11_elems elems;
++ struct ieee80211_mgmt *mgmt;
++ struct sta_info *sta;
++ size_t baselen;
++ u32 rates = 0;
++ u16 stype;
++ bool new = false;
++ enum ieee80211_band band = local->hw.conf.channel->band;
++ struct ieee80211_supported_band *sband = local->hw.wiphy->bands[band];
++
++ rx_status = IEEE80211_SKB_RXCB(skb);
++ mgmt = (struct ieee80211_mgmt *) skb->data;
++ stype = le16_to_cpu(mgmt->frame_control) & IEEE80211_FCTL_STYPE;
++
++ if (stype != IEEE80211_STYPE_BEACON)
++ return;
++
++ baselen = (u8 *) mgmt->u.probe_resp.variable - (u8 *) mgmt;
++ if (baselen > skb->len)
++ return;
++
++ ieee802_11_parse_elems(mgmt->u.probe_resp.variable,
++ skb->len - baselen, &elems);
++
++ rates = ieee80211_sta_get_rates(local, &elems, band);
++
++ rcu_read_lock();
++
++ sta = sta_info_get(sdata, sdata->u.wds.remote_addr);
++
++ if (!sta) {
++ rcu_read_unlock();
++ sta = sta_info_alloc(sdata, sdata->u.wds.remote_addr,
++ GFP_KERNEL);
++ if (!sta)
++ return;
++
++ new = true;
++ }
++
++ sta->last_rx = jiffies;
++ sta->sta.supp_rates[local->hw.conf.channel->band] = rates;
++
++ if (elems.ht_cap_elem)
++ ieee80211_ht_cap_ie_to_sta_ht_cap(sband,
++ elems.ht_cap_elem, &sta->sta.ht_cap);
++
++ if (elems.wmm_param)
++ set_sta_flags(sta, WLAN_STA_WME);
++
++ if (new) {
++ sta->flags = WLAN_STA_AUTHORIZED;
++ rate_control_rate_init(sta);
++ sta_info_insert_rcu(sta);
++ }
++
++ rcu_read_unlock();
++}
++
+ static void ieee80211_iface_work(struct work_struct *work)
+ {
+ struct ieee80211_sub_if_data *sdata =
+@@ -822,6 +863,9 @@ static void ieee80211_iface_work(struct
+ break;
+ ieee80211_mesh_rx_queued_mgmt(sdata, skb);
+ break;
++ case NL80211_IFTYPE_WDS:
++ ieee80211_wds_rx_queued_mgmt(sdata, skb);
++ break;
+ default:
+ WARN(1, "frame for unexpected interface type");
+ break;
--- /dev/null
+--- a/net/mac80211/agg-tx.c
++++ b/net/mac80211/agg-tx.c
+@@ -79,7 +79,8 @@ static void ieee80211_send_addba_request
+ memcpy(mgmt->da, da, ETH_ALEN);
+ memcpy(mgmt->sa, sdata->vif.addr, ETH_ALEN);
+ if (sdata->vif.type == NL80211_IFTYPE_AP ||
+- sdata->vif.type == NL80211_IFTYPE_AP_VLAN)
++ sdata->vif.type == NL80211_IFTYPE_AP_VLAN ||
++ sdata->vif.type == NL80211_IFTYPE_WDS)
+ memcpy(mgmt->bssid, sdata->vif.addr, ETH_ALEN);
+ else if (sdata->vif.type == NL80211_IFTYPE_STATION)
+ memcpy(mgmt->bssid, sdata->u.mgd.bssid, ETH_ALEN);
+@@ -388,7 +389,8 @@ int ieee80211_start_tx_ba_session(struct
+ */
+ if (sdata->vif.type != NL80211_IFTYPE_STATION &&
+ sdata->vif.type != NL80211_IFTYPE_AP_VLAN &&
+- sdata->vif.type != NL80211_IFTYPE_AP)
++ sdata->vif.type != NL80211_IFTYPE_AP &&
++ sdata->vif.type != NL80211_IFTYPE_WDS)
+ return -EINVAL;
+
+ if (test_sta_flags(sta, WLAN_STA_BLOCK_BA)) {
+--- a/net/mac80211/agg-rx.c
++++ b/net/mac80211/agg-rx.c
+@@ -161,6 +161,8 @@ static void ieee80211_send_addba_resp(st
+ memcpy(mgmt->bssid, sdata->vif.addr, ETH_ALEN);
+ else if (sdata->vif.type == NL80211_IFTYPE_STATION)
+ memcpy(mgmt->bssid, sdata->u.mgd.bssid, ETH_ALEN);
++ else if (sdata->vif.type == NL80211_IFTYPE_WDS)
++ memcpy(mgmt->bssid, da, ETH_ALEN);
+
+ mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
+ IEEE80211_STYPE_ACTION);
+--- a/net/mac80211/rx.c
++++ b/net/mac80211/rx.c
+@@ -2137,7 +2137,8 @@ ieee80211_rx_h_action(struct ieee80211_r
+ */
+ if (sdata->vif.type != NL80211_IFTYPE_STATION &&
+ sdata->vif.type != NL80211_IFTYPE_AP_VLAN &&
+- sdata->vif.type != NL80211_IFTYPE_AP)
++ sdata->vif.type != NL80211_IFTYPE_AP &&
++ sdata->vif.type != NL80211_IFTYPE_WDS)
+ break;
+
+ /* verify action_code is present */
+@@ -2681,13 +2682,16 @@ static int prepare_for_handlers(struct i
+ }
+ break;
+ case NL80211_IFTYPE_WDS:
+- if (bssid) {
+- if (!ieee80211_is_beacon(hdr->frame_control))
+- return 0;
+- } else if (!ieee80211_is_data(hdr->frame_control))
+- return 0;
+ if (compare_ether_addr(sdata->u.wds.remote_addr, hdr->addr2))
+ return 0;
++
++ if (ieee80211_is_data(hdr->frame_control) ||
++ ieee80211_is_action(hdr->frame_control)) {
++ if (compare_ether_addr(sdata->vif.addr, hdr->addr1))
++ return 0;
++ } else if (!ieee80211_is_beacon(hdr->frame_control))
++ return 0;
++
+ break;
+ default:
+ /* should never get here */
--- /dev/null
+--- a/drivers/net/wireless/ath/ath9k/debug.c
++++ b/drivers/net/wireless/ath/ath9k/debug.c
+@@ -548,6 +548,7 @@ static ssize_t read_file_xmit(struct fil
+
+ PR("MPDUs Queued: ", queued);
+ PR("MPDUs Completed: ", completed);
++ PR("MPDUs XRetried: ", xretries);
+ PR("Aggregates: ", a_aggr);
+ PR("AMPDUs Queued HW:", a_queued_hw);
+ PR("AMPDUs Queued SW:", a_queued_sw);
+@@ -803,7 +804,10 @@ void ath_debug_stat_tx(struct ath_softc
+ else
+ TX_STAT_INC(qnum, a_completed);
+ } else {
+- TX_STAT_INC(qnum, completed);
++ if (bf_isxretried(bf))
++ TX_STAT_INC(qnum, xretries);
++ else
++ TX_STAT_INC(qnum, completed);
+ }
+
+ if (ts->ts_status & ATH9K_TXERR_FIFO)
+--- a/drivers/net/wireless/ath/ath9k/debug.h
++++ b/drivers/net/wireless/ath/ath9k/debug.h
+@@ -116,6 +116,7 @@ struct ath_tx_stats {
+ u32 tx_bytes_all;
+ u32 queued;
+ u32 completed;
++ u32 xretries;
+ u32 a_aggr;
+ u32 a_queued_hw;
+ u32 a_queued_sw;
+++ /dev/null
---- a/net/mac80211/sta_info.h
-+++ b/net/mac80211/sta_info.h
-@@ -31,7 +31,6 @@
- * frames.
- * @WLAN_STA_ASSOC_AP: We're associated to that station, it is an AP.
- * @WLAN_STA_WME: Station is a QoS-STA.
-- * @WLAN_STA_WDS: Station is one of our WDS peers.
- * @WLAN_STA_CLEAR_PS_FILT: Clear PS filter in hardware (using the
- * IEEE80211_TX_CTL_CLEAR_PS_FILT control flag) when the next
- * frame to this station is transmitted.
-@@ -54,7 +53,6 @@ enum ieee80211_sta_info_flags {
- WLAN_STA_SHORT_PREAMBLE = 1<<4,
- WLAN_STA_ASSOC_AP = 1<<5,
- WLAN_STA_WME = 1<<6,
-- WLAN_STA_WDS = 1<<7,
- WLAN_STA_CLEAR_PS_FILT = 1<<9,
- WLAN_STA_MFP = 1<<10,
- WLAN_STA_BLOCK_BA = 1<<11,
---- a/net/mac80211/debugfs_sta.c
-+++ b/net/mac80211/debugfs_sta.c
-@@ -59,7 +59,7 @@ static ssize_t sta_flags_read(struct fil
- char buf[100];
- struct sta_info *sta = file->private_data;
- u32 staflags = get_sta_flags(sta);
-- int res = scnprintf(buf, sizeof(buf), "%s%s%s%s%s%s%s%s%s",
-+ int res = scnprintf(buf, sizeof(buf), "%s%s%s%s%s%s%s%s",
- staflags & WLAN_STA_AUTH ? "AUTH\n" : "",
- staflags & WLAN_STA_ASSOC ? "ASSOC\n" : "",
- staflags & WLAN_STA_PS_STA ? "PS (sta)\n" : "",
-@@ -67,7 +67,6 @@ static ssize_t sta_flags_read(struct fil
- staflags & WLAN_STA_AUTHORIZED ? "AUTHORIZED\n" : "",
- staflags & WLAN_STA_SHORT_PREAMBLE ? "SHORT PREAMBLE\n" : "",
- staflags & WLAN_STA_WME ? "WME\n" : "",
-- staflags & WLAN_STA_WDS ? "WDS\n" : "",
- staflags & WLAN_STA_MFP ? "MFP\n" : "");
- return simple_read_from_buffer(userbuf, count, ppos, buf, res);
- }
+++ /dev/null
---- a/net/mac80211/rx.c
-+++ b/net/mac80211/rx.c
-@@ -2330,13 +2330,14 @@ ieee80211_rx_h_mgmt(struct ieee80211_rx_
-
- if (!ieee80211_vif_is_mesh(&sdata->vif) &&
- sdata->vif.type != NL80211_IFTYPE_ADHOC &&
-- sdata->vif.type != NL80211_IFTYPE_STATION)
-+ sdata->vif.type != NL80211_IFTYPE_STATION &&
-+ sdata->vif.type != NL80211_IFTYPE_WDS)
- return RX_DROP_MONITOR;
-
- switch (stype) {
- case cpu_to_le16(IEEE80211_STYPE_BEACON):
- case cpu_to_le16(IEEE80211_STYPE_PROBE_RESP):
-- /* process for all: mesh, mlme, ibss */
-+ /* process for all: mesh, mlme, ibss, wds */
- break;
- case cpu_to_le16(IEEE80211_STYPE_DEAUTH):
- case cpu_to_le16(IEEE80211_STYPE_DISASSOC):
-@@ -2716,7 +2717,10 @@ static int prepare_for_handlers(struct i
- }
- break;
- case NL80211_IFTYPE_WDS:
-- if (bssid || !ieee80211_is_data(hdr->frame_control))
-+ if (bssid) {
-+ if (!ieee80211_is_beacon(hdr->frame_control))
-+ return 0;
-+ } else if (!ieee80211_is_data(hdr->frame_control))
- return 0;
- if (compare_ether_addr(sdata->u.wds.remote_addr, hdr->addr2))
- return 0;
---- a/net/mac80211/iface.c
-+++ b/net/mac80211/iface.c
-@@ -178,7 +178,6 @@ static int ieee80211_do_open(struct net_
- {
- struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
- struct ieee80211_local *local = sdata->local;
-- struct sta_info *sta;
- u32 changed = 0;
- int res;
- u32 hw_reconf_flags = 0;
-@@ -290,27 +289,6 @@ static int ieee80211_do_open(struct net_
-
- set_bit(SDATA_STATE_RUNNING, &sdata->state);
-
-- if (sdata->vif.type == NL80211_IFTYPE_WDS) {
-- /* Create STA entry for the WDS peer */
-- sta = sta_info_alloc(sdata, sdata->u.wds.remote_addr,
-- GFP_KERNEL);
-- if (!sta) {
-- res = -ENOMEM;
-- goto err_del_interface;
-- }
--
-- /* no locking required since STA is not live yet */
-- sta->flags |= WLAN_STA_AUTHORIZED;
--
-- res = sta_info_insert(sta);
-- if (res) {
-- /* STA has been freed */
-- goto err_del_interface;
-- }
--
-- rate_control_rate_init(sta);
-- }
--
- /*
- * set_multicast_list will be invoked by the networking core
- * which will check whether any increments here were done in
-@@ -344,8 +322,7 @@ static int ieee80211_do_open(struct net_
- netif_tx_start_all_queues(dev);
-
- return 0;
-- err_del_interface:
-- drv_remove_interface(local, &sdata->vif);
-+
- err_stop:
- if (!local->open_count)
- drv_stop(local);
-@@ -717,6 +694,70 @@ static void ieee80211_if_setup(struct ne
- dev->destructor = free_netdev;
- }
-
-+static void ieee80211_wds_rx_queued_mgmt(struct ieee80211_sub_if_data *sdata,
-+ struct sk_buff *skb)
-+{
-+ struct ieee80211_local *local = sdata->local;
-+ struct ieee80211_rx_status *rx_status;
-+ struct ieee802_11_elems elems;
-+ struct ieee80211_mgmt *mgmt;
-+ struct sta_info *sta;
-+ size_t baselen;
-+ u32 rates = 0;
-+ u16 stype;
-+ bool new = false;
-+ enum ieee80211_band band = local->hw.conf.channel->band;
-+ struct ieee80211_supported_band *sband = local->hw.wiphy->bands[band];
-+
-+ rx_status = IEEE80211_SKB_RXCB(skb);
-+ mgmt = (struct ieee80211_mgmt *) skb->data;
-+ stype = le16_to_cpu(mgmt->frame_control) & IEEE80211_FCTL_STYPE;
-+
-+ if (stype != IEEE80211_STYPE_BEACON)
-+ return;
-+
-+ baselen = (u8 *) mgmt->u.probe_resp.variable - (u8 *) mgmt;
-+ if (baselen > skb->len)
-+ return;
-+
-+ ieee802_11_parse_elems(mgmt->u.probe_resp.variable,
-+ skb->len - baselen, &elems);
-+
-+ rates = ieee80211_sta_get_rates(local, &elems, band);
-+
-+ rcu_read_lock();
-+
-+ sta = sta_info_get(sdata, sdata->u.wds.remote_addr);
-+
-+ if (!sta) {
-+ rcu_read_unlock();
-+ sta = sta_info_alloc(sdata, sdata->u.wds.remote_addr,
-+ GFP_KERNEL);
-+ if (!sta)
-+ return;
-+
-+ new = true;
-+ }
-+
-+ sta->last_rx = jiffies;
-+ sta->sta.supp_rates[local->hw.conf.channel->band] = rates;
-+
-+ if (elems.ht_cap_elem)
-+ ieee80211_ht_cap_ie_to_sta_ht_cap(sband,
-+ elems.ht_cap_elem, &sta->sta.ht_cap);
-+
-+ if (elems.wmm_param)
-+ set_sta_flags(sta, WLAN_STA_WME);
-+
-+ if (new) {
-+ sta->flags = WLAN_STA_AUTHORIZED;
-+ rate_control_rate_init(sta);
-+ sta_info_insert_rcu(sta);
-+ }
-+
-+ rcu_read_unlock();
-+}
-+
- static void ieee80211_iface_work(struct work_struct *work)
- {
- struct ieee80211_sub_if_data *sdata =
-@@ -821,6 +862,9 @@ static void ieee80211_iface_work(struct
- break;
- ieee80211_mesh_rx_queued_mgmt(sdata, skb);
- break;
-+ case NL80211_IFTYPE_WDS:
-+ ieee80211_wds_rx_queued_mgmt(sdata, skb);
-+ break;
- default:
- WARN(1, "frame for unexpected interface type");
- break;
+++ /dev/null
---- a/net/mac80211/agg-tx.c
-+++ b/net/mac80211/agg-tx.c
-@@ -79,7 +79,8 @@ static void ieee80211_send_addba_request
- memcpy(mgmt->da, da, ETH_ALEN);
- memcpy(mgmt->sa, sdata->vif.addr, ETH_ALEN);
- if (sdata->vif.type == NL80211_IFTYPE_AP ||
-- sdata->vif.type == NL80211_IFTYPE_AP_VLAN)
-+ sdata->vif.type == NL80211_IFTYPE_AP_VLAN ||
-+ sdata->vif.type == NL80211_IFTYPE_WDS)
- memcpy(mgmt->bssid, sdata->vif.addr, ETH_ALEN);
- else if (sdata->vif.type == NL80211_IFTYPE_STATION)
- memcpy(mgmt->bssid, sdata->u.mgd.bssid, ETH_ALEN);
-@@ -377,7 +378,8 @@ int ieee80211_start_tx_ba_session(struct
- */
- if (sdata->vif.type != NL80211_IFTYPE_STATION &&
- sdata->vif.type != NL80211_IFTYPE_AP_VLAN &&
-- sdata->vif.type != NL80211_IFTYPE_AP)
-+ sdata->vif.type != NL80211_IFTYPE_AP &&
-+ sdata->vif.type != NL80211_IFTYPE_WDS)
- return -EINVAL;
-
- if (test_sta_flags(sta, WLAN_STA_BLOCK_BA)) {
---- a/net/mac80211/agg-rx.c
-+++ b/net/mac80211/agg-rx.c
-@@ -160,6 +160,8 @@ static void ieee80211_send_addba_resp(st
- memcpy(mgmt->bssid, sdata->vif.addr, ETH_ALEN);
- else if (sdata->vif.type == NL80211_IFTYPE_STATION)
- memcpy(mgmt->bssid, sdata->u.mgd.bssid, ETH_ALEN);
-+ else if (sdata->vif.type == NL80211_IFTYPE_WDS)
-+ memcpy(mgmt->bssid, da, ETH_ALEN);
-
- mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
- IEEE80211_STYPE_ACTION);
---- a/net/mac80211/rx.c
-+++ b/net/mac80211/rx.c
-@@ -2132,7 +2132,8 @@ ieee80211_rx_h_action(struct ieee80211_r
- */
- if (sdata->vif.type != NL80211_IFTYPE_STATION &&
- sdata->vif.type != NL80211_IFTYPE_AP_VLAN &&
-- sdata->vif.type != NL80211_IFTYPE_AP)
-+ sdata->vif.type != NL80211_IFTYPE_AP &&
-+ sdata->vif.type != NL80211_IFTYPE_WDS)
- break;
-
- /* verify action_code is present */
-@@ -2717,13 +2718,16 @@ static int prepare_for_handlers(struct i
- }
- break;
- case NL80211_IFTYPE_WDS:
-- if (bssid) {
-- if (!ieee80211_is_beacon(hdr->frame_control))
-- return 0;
-- } else if (!ieee80211_is_data(hdr->frame_control))
-- return 0;
- if (compare_ether_addr(sdata->u.wds.remote_addr, hdr->addr2))
- return 0;
-+
-+ if (ieee80211_is_data(hdr->frame_control) ||
-+ ieee80211_is_action(hdr->frame_control)) {
-+ if (compare_ether_addr(sdata->vif.addr, hdr->addr1))
-+ return 0;
-+ } else if (!ieee80211_is_beacon(hdr->frame_control))
-+ return 0;
-+
- break;
- default:
- /* should never get here */
+++ /dev/null
---- a/drivers/net/wireless/ath/ath9k/debug.c
-+++ b/drivers/net/wireless/ath/ath9k/debug.c
-@@ -543,6 +543,7 @@ static ssize_t read_file_xmit(struct fil
-
- PR("MPDUs Queued: ", queued);
- PR("MPDUs Completed: ", completed);
-+ PR("MPDUs XRetried: ", xretries);
- PR("Aggregates: ", a_aggr);
- PR("AMPDUs Queued HW:", a_queued_hw);
- PR("AMPDUs Queued SW:", a_queued_sw);
-@@ -798,7 +799,10 @@ void ath_debug_stat_tx(struct ath_softc
- else
- TX_STAT_INC(qnum, a_completed);
- } else {
-- TX_STAT_INC(qnum, completed);
-+ if (bf_isxretried(bf))
-+ TX_STAT_INC(qnum, xretries);
-+ else
-+ TX_STAT_INC(qnum, completed);
- }
-
- if (ts->ts_status & ATH9K_TXERR_FIFO)
---- a/drivers/net/wireless/ath/ath9k/debug.h
-+++ b/drivers/net/wireless/ath/ath9k/debug.h
-@@ -112,6 +112,7 @@ struct ath_tx_stats {
- u32 tx_bytes_all;
- u32 queued;
- u32 completed;
-+ u32 xretries;
- u32 a_aggr;
- u32 a_queued_hw;
- u32 a_queued_sw;
--- /dev/null
+--- a/net/mac80211/main.c
++++ b/net/mac80211/main.c
+@@ -239,7 +239,9 @@ void ieee80211_bss_info_change_notify(st
+ u32 changed)
+ {
+ struct ieee80211_local *local = sdata->local;
++ struct ieee80211_supported_band *sband;
+ static const u8 zero[ETH_ALEN] = { 0 };
++ struct sta_info *sta;
+
+ if (!changed)
+ return;
+@@ -269,6 +271,22 @@ void ieee80211_bss_info_change_notify(st
+
+ switch (sdata->vif.type) {
+ case NL80211_IFTYPE_AP:
++ if (!(changed & BSS_CHANGED_HT))
++ break;
++
++ sband = local->hw.wiphy->bands[local->hw.conf.channel->band];
++ rcu_read_lock();
++ list_for_each_entry(sta, &local->sta_list, list) {
++ if (sta->sdata != sdata &&
++ (!sdata->bss || sta->sdata->bss != sdata->bss))
++ continue;
++
++ rate_control_rate_update(local, sband, sta,
++ IEEE80211_RC_HT_CHANGED,
++ local->_oper_channel_type);
++ }
++ rcu_read_unlock();
++ break;
+ case NL80211_IFTYPE_ADHOC:
+ case NL80211_IFTYPE_WDS:
+ case NL80211_IFTYPE_MESH_POINT:
--- /dev/null
+--- a/drivers/net/wireless/ath/ath9k/calib.c
++++ b/drivers/net/wireless/ath/ath9k/calib.c
+@@ -63,6 +63,19 @@ static s16 ath9k_hw_get_default_nf(struc
+ return ath9k_hw_get_nf_limits(ah, chan)->nominal;
+ }
+
++s16 ath9k_hw_getchan_noise(struct ath_hw *ah, struct ath9k_channel *chan)
++{
++ s8 noise = ATH_DEFAULT_NOISE_FLOOR;
++
++ if (chan && chan->noisefloor) {
++ s8 delta = chan->noisefloor -
++ ath9k_hw_get_default_nf(ah, chan);
++ if (delta > 0)
++ noise += delta;
++ }
++ return noise;
++}
++EXPORT_SYMBOL(ath9k_hw_getchan_noise);
+
+ static void ath9k_hw_update_nfcal_hist_buffer(struct ath_hw *ah,
+ struct ath9k_hw_cal_data *cal,
+@@ -378,6 +391,7 @@ bool ath9k_hw_getnf(struct ath_hw *ah, s
+
+ if (!caldata) {
+ chan->noisefloor = nf;
++ ah->noise = ath9k_hw_getchan_noise(ah, chan);
+ return false;
+ }
+
+@@ -385,6 +399,7 @@ bool ath9k_hw_getnf(struct ath_hw *ah, s
+ caldata->nfcal_pending = false;
+ ath9k_hw_update_nfcal_hist_buffer(ah, caldata, nfarray);
+ chan->noisefloor = h[0].privNF;
++ ah->noise = ath9k_hw_getchan_noise(ah, chan);
+ return true;
+ }
+
+--- a/drivers/net/wireless/ath/ath9k/hw.c
++++ b/drivers/net/wireless/ath/ath9k/hw.c
+@@ -1344,6 +1344,7 @@ int ath9k_hw_reset(struct ath_hw *ah, st
+ memset(caldata, 0, sizeof(*caldata));
+ ath9k_init_nfcal_hist_buffer(ah, chan);
+ }
++ ah->noise = ath9k_hw_getchan_noise(ah, chan);
+
+ if (bChannelChange &&
+ (ah->chip_fullsleep != true) &&
+--- a/drivers/net/wireless/ath/ath9k/hw.h
++++ b/drivers/net/wireless/ath/ath9k/hw.h
+@@ -688,6 +688,7 @@ struct ath_hw {
+ enum nl80211_iftype opmode;
+ enum ath9k_power_mode power_mode;
+
++ s8 noise;
+ struct ath9k_hw_cal_data *caldata;
+ struct ath9k_pacal_info pacal_info;
+ struct ar5416Stats stats;
+--- a/drivers/net/wireless/ath/ath9k/main.c
++++ b/drivers/net/wireless/ath/ath9k/main.c
+@@ -165,7 +165,7 @@ static void ath_update_survey_nf(struct
+
+ if (chan->noisefloor) {
+ survey->filled |= SURVEY_INFO_NOISE_DBM;
+- survey->noise = chan->noisefloor;
++ survey->noise = ath9k_hw_getchan_noise(ah, chan);
+ }
+ }
+
+--- a/drivers/net/wireless/ath/ath9k/recv.c
++++ b/drivers/net/wireless/ath/ath9k/recv.c
+@@ -985,6 +985,8 @@ static int ath9k_rx_skb_preprocess(struc
+ struct ieee80211_rx_status *rx_status,
+ bool *decrypt_error)
+ {
++ struct ath_hw *ah = common->ah;
++
+ memset(rx_status, 0, sizeof(struct ieee80211_rx_status));
+
+ /*
+@@ -1005,7 +1007,7 @@ static int ath9k_rx_skb_preprocess(struc
+
+ rx_status->band = hw->conf.channel->band;
+ rx_status->freq = hw->conf.channel->center_freq;
+- rx_status->signal = ATH_DEFAULT_NOISE_FLOOR + rx_stats->rs_rssi;
++ rx_status->signal = ah->noise + rx_stats->rs_rssi;
+ rx_status->antenna = rx_stats->rs_antenna;
+ rx_status->flag |= RX_FLAG_MACTIME_MPDU;
+
+--- a/drivers/net/wireless/ath/ath9k/calib.h
++++ b/drivers/net/wireless/ath/ath9k/calib.h
+@@ -108,6 +108,7 @@ void ath9k_init_nfcal_hist_buffer(struct
+ void ath9k_hw_bstuck_nfcal(struct ath_hw *ah);
+ void ath9k_hw_reset_calibration(struct ath_hw *ah,
+ struct ath9k_cal_list *currCal);
++s16 ath9k_hw_getchan_noise(struct ath_hw *ah, struct ath9k_channel *chan);
+
+
+ #endif /* CALIB_H */
+++ /dev/null
---- a/net/mac80211/main.c
-+++ b/net/mac80211/main.c
-@@ -245,7 +245,9 @@ void ieee80211_bss_info_change_notify(st
- u32 changed)
- {
- struct ieee80211_local *local = sdata->local;
-+ struct ieee80211_supported_band *sband;
- static const u8 zero[ETH_ALEN] = { 0 };
-+ struct sta_info *sta;
-
- if (!changed)
- return;
-@@ -275,6 +277,22 @@ void ieee80211_bss_info_change_notify(st
-
- switch (sdata->vif.type) {
- case NL80211_IFTYPE_AP:
-+ if (!(changed & BSS_CHANGED_HT))
-+ break;
-+
-+ sband = local->hw.wiphy->bands[local->hw.conf.channel->band];
-+ rcu_read_lock();
-+ list_for_each_entry(sta, &local->sta_list, list) {
-+ if (sta->sdata != sdata &&
-+ (!sdata->bss || sta->sdata->bss != sdata->bss))
-+ continue;
-+
-+ rate_control_rate_update(local, sband, sta,
-+ IEEE80211_RC_HT_CHANGED,
-+ local->_oper_channel_type);
-+ }
-+ rcu_read_unlock();
-+ break;
- case NL80211_IFTYPE_ADHOC:
- case NL80211_IFTYPE_WDS:
- case NL80211_IFTYPE_MESH_POINT:
+++ /dev/null
---- a/drivers/net/wireless/ath/ath9k/calib.c
-+++ b/drivers/net/wireless/ath/ath9k/calib.c
-@@ -365,6 +365,7 @@ bool ath9k_hw_getnf(struct ath_hw *ah, s
-
- if (!caldata) {
- chan->noisefloor = nf;
-+ ah->noise = ath9k_hw_getchan_noise(ah, chan);
- return false;
- }
-
-@@ -372,6 +373,7 @@ bool ath9k_hw_getnf(struct ath_hw *ah, s
- caldata->nfcal_pending = false;
- ath9k_hw_update_nfcal_hist_buffer(ah, caldata, nfarray);
- chan->noisefloor = h[0].privNF;
-+ ah->noise = ath9k_hw_getchan_noise(ah, chan);
- return true;
- }
-
-@@ -398,10 +400,15 @@ void ath9k_init_nfcal_hist_buffer(struct
-
- s16 ath9k_hw_getchan_noise(struct ath_hw *ah, struct ath9k_channel *chan)
- {
-- if (!ah->curchan || !ah->curchan->noisefloor)
-- return ath9k_hw_get_default_nf(ah, chan);
-+ s8 noise = ATH_DEFAULT_NOISE_FLOOR;
-
-- return ah->curchan->noisefloor;
-+ if (chan && chan->noisefloor) {
-+ s8 delta = chan->noisefloor -
-+ ath9k_hw_get_default_nf(ah, chan);
-+ if (delta > 0)
-+ noise += delta;
-+ }
-+ return noise;
- }
- EXPORT_SYMBOL(ath9k_hw_getchan_noise);
-
---- a/drivers/net/wireless/ath/ath9k/hw.c
-+++ b/drivers/net/wireless/ath/ath9k/hw.c
-@@ -1286,6 +1286,7 @@ int ath9k_hw_reset(struct ath_hw *ah, st
- memset(caldata, 0, sizeof(*caldata));
- ath9k_init_nfcal_hist_buffer(ah, chan);
- }
-+ ah->noise = ath9k_hw_getchan_noise(ah, chan);
-
- if (bChannelChange &&
- (ah->chip_fullsleep != true) &&
---- a/drivers/net/wireless/ath/ath9k/hw.h
-+++ b/drivers/net/wireless/ath/ath9k/hw.h
-@@ -677,6 +677,7 @@ struct ath_hw {
- enum nl80211_iftype opmode;
- enum ath9k_power_mode power_mode;
-
-+ s8 noise;
- struct ath9k_hw_cal_data *caldata;
- struct ath9k_pacal_info pacal_info;
- struct ar5416Stats stats;
---- a/drivers/net/wireless/ath/ath9k/main.c
-+++ b/drivers/net/wireless/ath/ath9k/main.c
-@@ -165,7 +165,7 @@ static void ath_update_survey_nf(struct
-
- if (chan->noisefloor) {
- survey->filled |= SURVEY_INFO_NOISE_DBM;
-- survey->noise = chan->noisefloor;
-+ survey->noise = ath9k_hw_getchan_noise(ah, chan);
- }
- }
-
---- a/drivers/net/wireless/ath/ath9k/recv.c
-+++ b/drivers/net/wireless/ath/ath9k/recv.c
-@@ -956,6 +956,8 @@ static int ath9k_rx_skb_preprocess(struc
- struct ieee80211_rx_status *rx_status,
- bool *decrypt_error)
- {
-+ struct ath_hw *ah = common->ah;
-+
- memset(rx_status, 0, sizeof(struct ieee80211_rx_status));
-
- /*
-@@ -976,7 +978,7 @@ static int ath9k_rx_skb_preprocess(struc
-
- rx_status->band = hw->conf.channel->band;
- rx_status->freq = hw->conf.channel->center_freq;
-- rx_status->signal = ATH_DEFAULT_NOISE_FLOOR + rx_stats->rs_rssi;
-+ rx_status->signal = ah->noise + rx_stats->rs_rssi;
- rx_status->antenna = rx_stats->rs_antenna;
- rx_status->flag |= RX_FLAG_MACTIME_MPDU;
-
--- a/drivers/net/wireless/mwl8k.c
+++ b/drivers/net/wireless/mwl8k.c
-@@ -5165,6 +5165,7 @@ MODULE_FIRMWARE("mwl8k/fmimage_8366.fw")
+@@ -5192,6 +5192,7 @@ MODULE_FIRMWARE("mwl8k/fmimage_8366.fw")
MODULE_FIRMWARE(MWL8K_8366_AP_FW(MWL8K_8366_AP_FW_API));
static DEFINE_PCI_DEVICE_TABLE(mwl8k_pci_id_table) = {
struct b43_phy phy;
--- a/drivers/net/wireless/b43/main.c
+++ b/drivers/net/wireless/b43/main.c
-@@ -75,6 +75,11 @@ MODULE_FIRMWARE("b43/ucode15.fw");
+@@ -76,6 +76,11 @@ MODULE_FIRMWARE("b43/ucode16_mimo.fw");
MODULE_FIRMWARE("b43/ucode5.fw");
MODULE_FIRMWARE("b43/ucode9.fw");
static int modparam_bad_frames_preempt;
module_param_named(bad_frames_preempt, modparam_bad_frames_preempt, int, 0444);
MODULE_PARM_DESC(bad_frames_preempt,
-@@ -2542,10 +2547,10 @@ static int b43_gpio_init(struct b43_wlde
+@@ -2543,10 +2548,10 @@ static int b43_gpio_init(struct b43_wlde
& ~B43_MACCTL_GPOUTSMSK);
b43_write16(dev, B43_MMIO_GPIO_MASK, b43_read16(dev, B43_MMIO_GPIO_MASK)
if (dev->dev->bus->chip_id == 0x4301) {
mask |= 0x0060;
set |= 0x0060;
-@@ -5100,10 +5105,10 @@ static void b43_print_driverinfo(void)
+@@ -5078,10 +5083,10 @@ static void b43_print_driverinfo(void)
feat_sdio = "S";
#endif
printk(KERN_INFO "Broadcom 43xx driver loaded "
b43-$(CONFIG_B43_PCMCIA) += pcmcia.o
--- a/drivers/net/wireless/b43/main.c
+++ b/drivers/net/wireless/b43/main.c
-@@ -1812,9 +1812,11 @@ static void b43_do_interrupt_thread(stru
+@@ -1813,9 +1813,11 @@ static void b43_do_interrupt_thread(stru
dma_reason[4], dma_reason[5]);
b43err(dev->wl, "This device does not support DMA "
"on your system. It will now be switched to PIO.\n");