From: Felix Fietkau Date: Fri, 18 Jul 2008 22:57:30 +0000 (+0000) Subject: rename patches-r3776 to patches-testing X-Git-Tag: reboot~26083 X-Git-Url: http://git.lede-project.org./?a=commitdiff_plain;h=9dc4917da8a85552aa733b269c985cebb35f00c5;p=openwrt%2Fopenwrt.git rename patches-r3776 to patches-testing SVN-Revision: 11868 --- diff --git a/package/madwifi/Makefile b/package/madwifi/Makefile index 0711e6d578..48fa28e128 100644 --- a/package/madwifi/Makefile +++ b/package/madwifi/Makefile @@ -23,7 +23,7 @@ PKG_SOURCE:=$(PKG_SOURCE_SUBDIR).tar.gz PKG_BUILD_DIR:=$(KERNEL_BUILD_DIR)/$(if $(PKG_BRANCH),$(PKG_BRANCH),madwifi-trunk)-$(PKG_VERSION) -PATCH_DIR=$(if $(CONFIG_MADWIFI_TESTING),./patches-r$(PKG_REV),./patches) +PATCH_DIR=$(if $(CONFIG_MADWIFI_TESTING),./patches-testing,./patches) include $(INCLUDE_DIR)/package.mk diff --git a/package/madwifi/patches-r3776/102-multicall_binary.patch b/package/madwifi/patches-r3776/102-multicall_binary.patch deleted file mode 100644 index 7ddd45632b..0000000000 --- a/package/madwifi/patches-r3776/102-multicall_binary.patch +++ /dev/null @@ -1,359 +0,0 @@ ---- a/tools/80211debug.c -+++ b/tools/80211debug.c -@@ -48,6 +48,7 @@ - #include - #include - #include -+#include "do_multi.h" - - #undef ARRAY_SIZE - #define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0])) -@@ -185,7 +186,7 @@ - #endif /* __linux__ */ - - int --main(int argc, char *argv[]) -+CMD(a80211debug)(int argc, char *argv[]) - { - const char *ifname = "ath0"; - const char *cp, *tp; ---- a/tools/80211stats.c -+++ b/tools/80211stats.c -@@ -59,6 +59,7 @@ - #include "net80211/ieee80211.h" - #include "net80211/ieee80211_crypto.h" - #include "net80211/ieee80211_ioctl.h" -+#include "do_multi.h" - - #ifndef SIOCG80211STATS - #define SIOCG80211STATS (SIOCDEVPRIVATE + 2) -@@ -241,7 +242,7 @@ - } - - int --main(int argc, char *argv[]) -+CMD(a80211stats)(int argc, char *argv[]) - { - int c, len; - struct ieee80211req_sta_info *si; ---- a/tools/athchans.c -+++ b/tools/athchans.c -@@ -58,6 +58,7 @@ - #include "net80211/ieee80211.h" - #include "net80211/ieee80211_crypto.h" - #include "net80211/ieee80211_ioctl.h" -+#include "do_multi.h" - - static int s = -1; - static const char *progname; -@@ -140,8 +141,9 @@ - } - - #define MAXCHAN ((int)(sizeof(struct ieee80211req_chanlist) * NBBY)) -+ - int --main(int argc, char *argv[]) -+CMD(athchans)(int argc, char *argv[]) - { - const char *ifname = "wifi0"; - struct ieee80211req_chanlist chanlist; ---- a/tools/athctrl.c -+++ b/tools/athctrl.c -@@ -52,6 +52,7 @@ - #include - - #include -+#include "do_multi.h" - - static int - setsysctrl(const char *dev, const char *control , u_long value) -@@ -88,7 +89,7 @@ - } - - int --main(int argc, char *argv[]) -+CMD(athctrl)(int argc, char *argv[]) - { - char device[IFNAMSIZ + 1]; - int distance = -1; ---- a/tools/athdebug.c -+++ b/tools/athdebug.c -@@ -51,6 +51,7 @@ - #include - #include - #include -+#include "do_multi.h" - - #undef ARRAY_SIZE - #define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0])) -@@ -194,7 +195,7 @@ - #endif /* __linux__ */ - - int --main(int argc, char *argv[]) -+CMD(athdebug)(int argc, char *argv[]) - { - #ifdef __linux__ - const char *ifname = "wifi0"; ---- a/tools/athkey.c -+++ b/tools/athkey.c -@@ -58,6 +58,7 @@ - #include "net80211/ieee80211.h" - #include "net80211/ieee80211_crypto.h" - #include "net80211/ieee80211_ioctl.h" -+#include "do_multi.h" - - static int s = -1; - static const char *progname; -@@ -213,8 +214,7 @@ - exit(-1); - } - --int --main(int argc, char *argv[]) -+int CMD(athkey)(int argc, char *argv[]) - { - const char *ifname = "wifi0"; - struct ieee80211req_key setkey; ---- a/tools/athstats.c -+++ b/tools/athstats.c -@@ -65,6 +65,7 @@ - - #undef ARRAY_SIZE - #define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0])) -+#include "do_multi.h" - - static const struct { - u_int phyerr; -@@ -228,7 +229,7 @@ - } - - int --main(int argc, char *argv[]) -+CMD(athstats)(int argc, char *argv[]) - { - #ifdef __linux__ - const char *ifname = "wifi0"; ---- /dev/null -+++ b/tools/do_multi.c -@@ -0,0 +1,36 @@ -+#include -+#include "do_multi.h" -+ -+int -+main(int argc, char *argv[]) -+{ -+ char *progname; -+ int ret = 0; -+ -+ progname = basename(argv[0]); -+ -+ if(strcmp(progname, "80211debug") == 0) -+ ret = a80211debug_init(argc, argv); -+ if(strcmp(progname, "80211stats") == 0) -+ ret = a80211stats_init(argc, argv); -+ if(strcmp(progname, "athchans") == 0) -+ ret = athchans_init(argc, argv); -+ if(strcmp(progname, "athctrl") == 0) -+ ret = athctrl_init(argc, argv); -+ if(strcmp(progname, "athdebug") == 0) -+ ret = athdebug_init(argc, argv); -+ if(strcmp(progname, "athkey") == 0) -+ ret = athkey_init(argc, argv); -+ if(strcmp(progname, "athstats") == 0) -+ ret = athstats_init(argc, argv); -+ if(strcmp(progname, "wlanconfig") == 0) -+ ret = wlanconfig_init(argc, argv); -+ if(strcmp(progname, "wpakey") == 0) -+ ret = wpakey_init(argc, argv); -+ if(strcmp(progname, "athchans") == 0) -+ ret = athchans_init(argc, argv); -+ if(strcmp(progname, "ath_info") == 0) -+ ret = athinfo_init(argc, argv); -+ -+ return ret; -+} ---- /dev/null -+++ b/tools/do_multi.h -@@ -0,0 +1,15 @@ -+#ifdef DO_MULTI -+int a80211debug_init(int argc, char *argv[]); -+int a80211stats_init(int argc, char *argv[]); -+int athchans_init(int argc, char *argv[]); -+int athctrl_init(int argc, char *argv[]); -+int athdebug_init(int argc, char *argv[]); -+int athkey_init(int argc, char *argv[]); -+int athstats_init(int argc, char *argv[]); -+int wlanconfig_init(int argc, char *argv[]); -+int athinfo_init(int argc, char *argv[]); -+ -+#define CMD(name) name##_init -+#else -+#define CMD(name) main -+#endif ---- a/tools/Makefile -+++ b/tools/Makefile -@@ -50,42 +50,43 @@ - PROGRAMS = athstats 80211stats athkey athchans athctrl \ - athdebug 80211debug wlanconfig wpakey - -+OBJS = $(patsubst %,%.o,$(PROGRAMS)) ath_info/ath_info.o - SUBDIRS = ath_info - --INCS = -I. -I$(HAL) -I$(TOP) -I$(ATH_HAL) -+INCS = -I. -I$(HAL) -I$(TOP) -I$(ATH_HAL) -I$(TOP)/ath - CFLAGS = -g -O2 -Wall - ALL_CFLAGS = $(CFLAGS) $(INCS) - LDFLAGS = - --all: all-subdirs $(PROGRAMS) -+all: all-subdirs compile - - all-subdirs: - for d in $(SUBDIRS); do \ - $(MAKE) -C $$d || exit 1; \ - done - --athstats: athstats.c -- $(CC) -o athstats $(ALL_CFLAGS) -I$(TOP)/ath $(LDFLAGS) athstats.c --80211stats: 80211stats.c -- $(CC) -o 80211stats $(ALL_CFLAGS) $(LDFLAGS) 80211stats.c --athkey: athkey.c -- $(CC) -o athkey $(ALL_CFLAGS) $(LDFLAGS) athkey.c --athchans: athchans.c -- $(CC) -o athchans $(ALL_CFLAGS) $(LDFLAGS) athchans.c --athctrl: athctrl.c -- $(CC) -o athctrl $(ALL_CFLAGS) $(LDFLAGS) athctrl.c --athdebug: athdebug.c -- $(CC) -o athdebug $(ALL_CFLAGS) $(LDFLAGS) athdebug.c --wlanconfig: wlanconfig.c -- $(CC) -o wlanconfig $(ALL_CFLAGS) $(LDFLAGS) wlanconfig.c --80211debug: 80211debug.c -- $(CC) -o 80211debug $(ALL_CFLAGS) $(LDFLAGS) 80211debug.c --wpakey: wpakey.c -- $(CC) -o wpakey $(ALL_CFLAGS) $(LDFLAGS) wpakey.c -+%.o: %.c -+ ${CC} $(ALL_CFLAGS) -c -o $@ $< -+ -+ifneq ($(DO_MULTI),) -+ALL_CFLAGS += -DDO_MULTI=1 -+madwifi_multi: $(OBJS) do_multi.o -+ $(CC) $(LDFLAGS) -o $@ $^ -+ -+compile: madwifi_multi -+ for i in $(PROGRAMS); do \ -+ ln -sf madwifi_multi $$i; \ -+ done -+else -+$(PROGRAMS): -+ $(CC) $(ALL_CFLAGS) -o $@ $@.c -+ -+compile: $(PROGRAMS) -+endif - - install: all - install -d $(DESTDIR)$(BINDIR) -- for i in $(PROGRAMS); do \ -+ for i in $(PROGRAMS) $(if $(DO_MULTI),madwifi_multi); do \ - install $$i $(DESTDIR)$(BINDIR)/$$i; \ - $(STRIP) $(DESTDIR)$(BINDIR)/$$i; \ - done -@@ -97,7 +98,7 @@ - done - - uninstall: -- for i in $(PROGRAMS); do \ -+ for i in $(PROGRAMS) $(if $(DO_MULTI),madwifi_multi); do \ - rm -f $(DESTDIR)$(BINDIR)/$$i; \ - done - for i in $(PROGRAMS:=.8); do \ -@@ -108,7 +109,7 @@ - done - - clean: -- rm -f $(PROGRAMS) core a.out -+ rm -f $(if $(DO_MULTI), madwifi_multi) $(PROGRAMS) core a.out *.o - for d in $(SUBDIRS); do \ - $(MAKE) -C $$d clean; \ - done ---- a/tools/wlanconfig.c -+++ b/tools/wlanconfig.c -@@ -61,6 +61,7 @@ - #include "net80211/ieee80211.h" - #include "net80211/ieee80211_crypto.h" - #include "net80211/ieee80211_ioctl.h" -+#include "do_multi.h" - - /* - * These are taken from ieee80211_node.h -@@ -100,7 +101,7 @@ - static int verbose = 0; - - int --main(int argc, char *argv[]) -+CMD(wlanconfig)(int argc, char *argv[]) - { - const char *ifname, *cmd; - unsigned char bnounit = 0; ---- a/tools/ath_info/Makefile -+++ b/tools/ath_info/Makefile -@@ -17,11 +17,18 @@ - - all: $(PROGRAMS) - -+ -+ifneq ($(DO_MULTI),) -+ath_info: ath_info.o -+ rm -f $@ -+ ln -s ../madwifi_multi $@ -+else - ath_info: ath_info.o - $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $< -+endif - - .c.o: -- $(CC) $(CFLAGS) -c $< -+ $(CC) $(CFLAGS) $(if $(DO_MULTI),-DDO_MULTI=1 -I..) -c $< - - clean: - rm -f *.o $(PROGRAMS) ---- a/tools/ath_info/ath_info.c -+++ b/tools/ath_info/ath_info.c -@@ -28,6 +28,7 @@ - #include - #include - #include -+#include "do_multi.h" - - #undef ARRAY_SIZE - #define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0])) -@@ -1982,7 +1983,8 @@ - printf("\n"); - } - --int main(int argc, char *argv[]) -+int -+CMD(athinfo)(int argc, char *argv[]) - { - unsigned long long dev_addr; - u_int16_t srev, phy_rev_5ghz, phy_rev_2ghz, ee_magic; ---- a/tools/wpakey.c -+++ b/tools/wpakey.c -@@ -25,6 +25,7 @@ - - #include - #include -+#include "do_multi.h" - - #define MACS "%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx" - #define MACP(mac) (mac)[0], (mac)[1], (mac)[2], (mac)[3], (mac)[4], (mac)[5] -@@ -234,7 +235,8 @@ - "", dev); - } - --int main(int argc, char** argv) { -+int -+CMD(wpakey)(int argc, char** argv) { - int keyidx = 0; - uint8_t mac[6]; - int cipher = IEEE80211_CIPHER_AES_CCM; diff --git a/package/madwifi/patches-r3776/104-autocreate_none.patch b/package/madwifi/patches-r3776/104-autocreate_none.patch deleted file mode 100644 index 16ce6e8639..0000000000 --- a/package/madwifi/patches-r3776/104-autocreate_none.patch +++ /dev/null @@ -1,11 +0,0 @@ ---- a/ath/if_ath.c -+++ b/ath/if_ath.c -@@ -482,7 +482,7 @@ - HAL_STATUS status; - int error = 0; - unsigned int i; -- int autocreatemode = IEEE80211_M_STA; -+ int autocreatemode = -1; - u_int8_t csz; - - sc->devid = devid; diff --git a/package/madwifi/patches-r3776/105-ratectl_attach.patch b/package/madwifi/patches-r3776/105-ratectl_attach.patch deleted file mode 100644 index 79b08dfb82..0000000000 --- a/package/madwifi/patches-r3776/105-ratectl_attach.patch +++ /dev/null @@ -1,23 +0,0 @@ ---- a/net80211/ieee80211_rate.c -+++ b/net80211/ieee80211_rate.c -@@ -100,8 +100,18 @@ - ieee80211_load_module(buf); - - if (!ratectls[id].attach) { -- printk(KERN_ERR "Error loading module \"%s\"\n", buf); -- return NULL; -+ /* pick the first available rate control module */ -+ printk(KERN_INFO "Rate control module \"%s\" not available\n", buf); -+ for (id = 0; id < IEEE80211_RATE_MAX; id++) { -+ if (ratectls[id].attach) -+ break; -+ } -+ if (!ratectls[id].attach) { -+ printk(KERN_ERR "No rate control module available"); -+ return NULL; -+ } else { -+ printk(KERN_INFO "Using \"%s\" instead.\n", module_names[id]); -+ } - } - - ctl = ratectls[id].attach(sc); diff --git a/package/madwifi/patches-r3776/111-minstrel_crash.patch b/package/madwifi/patches-r3776/111-minstrel_crash.patch deleted file mode 100644 index dd96c4e60f..0000000000 --- a/package/madwifi/patches-r3776/111-minstrel_crash.patch +++ /dev/null @@ -1,12 +0,0 @@ ---- a/ath_rate/minstrel/minstrel.c -+++ b/ath_rate/minstrel/minstrel.c -@@ -415,6 +415,9 @@ - return; - } - -+ if (sn->num_rates <= 0) -+ return; -+ - if (sn->is_sampling) { - sn->is_sampling = 0; - if (sn->rs_sample_rate_slower) diff --git a/package/madwifi/patches-r3776/122-replayfail_workaround.patch b/package/madwifi/patches-r3776/122-replayfail_workaround.patch deleted file mode 100644 index de5a8f3160..0000000000 --- a/package/madwifi/patches-r3776/122-replayfail_workaround.patch +++ /dev/null @@ -1,12 +0,0 @@ ---- a/net80211/ieee80211_linux.c -+++ b/net80211/ieee80211_linux.c -@@ -330,6 +330,9 @@ - k->wk_cipher->ic_name, k->wk_keyix, - (unsigned long long)rsc); - -+ /* disabled for now due to bogus events for unknown reasons */ -+ return; -+ - /* TODO: needed parameters: count, keyid, key type, src address, TSC */ - snprintf(buf, sizeof(buf), "%s(keyid=%d %scast addr=" MAC_FMT ")", tag, - k->wk_keyix, diff --git a/package/madwifi/patches-r3776/123-ccmp_checks.patch b/package/madwifi/patches-r3776/123-ccmp_checks.patch deleted file mode 100644 index 6db9c2d781..0000000000 --- a/package/madwifi/patches-r3776/123-ccmp_checks.patch +++ /dev/null @@ -1,22 +0,0 @@ ---- a/net80211/ieee80211_crypto_ccmp.c -+++ b/net80211/ieee80211_crypto_ccmp.c -@@ -478,6 +478,9 @@ - uint8_t *mic, *pos; - u_int space; - -+ if (ctx->cc_tfm == NULL) -+ return 0; -+ - ctx->cc_vap->iv_stats.is_crypto_ccmp++; - - skb = skb0; -@@ -592,6 +595,9 @@ - uint8_t *pos, *mic; - u_int space; - -+ if (ctx->cc_tfm == NULL) -+ return 0; -+ - ctx->cc_vap->iv_stats.is_crypto_ccmp++; - - skb = skb0; diff --git a/package/madwifi/patches-r3776/124-linux24_compat.patch b/package/madwifi/patches-r3776/124-linux24_compat.patch deleted file mode 100644 index 2ab9364b96..0000000000 --- a/package/madwifi/patches-r3776/124-linux24_compat.patch +++ /dev/null @@ -1,202 +0,0 @@ ---- a/ath/if_athvar.h -+++ b/ath/if_athvar.h -@@ -129,6 +129,11 @@ - #define ATH_GET_NETDEV_DEV(ndev) ((ndev)->class_dev.dev) - #endif - -+#ifndef NETDEV_TX_OK -+#define NETDEV_TX_OK 0 -+#define NETDEV_TX_BUSY 1 -+#endif -+ - #if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,23) - static inline struct net_device *_alloc_netdev(int sizeof_priv, const char *mask, - void (*setup)(struct net_device *)) ---- a/ath/if_ath_radar.c -+++ b/ath/if_ath_radar.c -@@ -89,6 +89,13 @@ - #define nofloat_pct(_value, _pct) \ - ( (_value * (1000 + _pct)) / 1000 ) - -+#ifndef list_for_each_entry_reverse -+#define list_for_each_entry_reverse(pos, head, member) \ -+ for (pos = list_entry((head)->prev, typeof(*pos), member); \ -+ prefetch(pos->member.prev), &pos->member != (head); \ -+ pos = list_entry(pos->member.prev, typeof(*pos), member)) -+#endif -+ - struct radar_pattern_specification { - /* The name of the rule/specification (i.e. what did we detect) */ - const char *name; ---- a/ath/if_ath.c -+++ b/ath/if_ath.c -@@ -4878,6 +4878,46 @@ - return (txqs & (1 << qnum)); - } - -+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,15) -+static inline int atomic_cmpxchg(atomic_t *v, int old, int new) -+{ -+ int ret; -+ unsigned long flags; -+ -+ local_irq_save(flags); -+ ret = v->counter; -+ if (likely(ret == old)) -+ v->counter = new; -+ local_irq_restore(flags); -+ -+ return ret; -+} -+ -+/** -+ * atomic_add_unless - add unless the number is a given value -+ * @v: pointer of type atomic_t -+ * @a: the amount to add to v... -+ * @u: ...unless v is equal to u. -+ * -+ * Atomically adds @a to @v, so long as it was not @u. -+ * Returns non-zero if @v was not @u, and zero otherwise. -+ */ -+static __inline__ int atomic_add_unless(atomic_t *v, int a, int u) -+{ -+ int c, old; -+ c = atomic_read(v); -+ for (;;) { -+ if (unlikely(c == (u))) -+ break; -+ old = atomic_cmpxchg((v), c, c + (a)); -+ if (likely(old == c)) -+ break; -+ c = old; -+ } -+ return c != (u); -+} -+#endif -+ - /* - * Generate beacon frame and queue cab data for a VAP. - */ ---- /dev/null -+++ b/net80211/sort.c -@@ -0,0 +1,120 @@ -+/* -+ * A fast, small, non-recursive O(nlog n) sort for the Linux kernel -+ * -+ * Jan 23 2005 Matt Mackall -+ */ -+ -+#include -+#include -+#include -+ -+static void u32_swap(void *a, void *b, int size) -+{ -+ u32 t = *(u32 *)a; -+ *(u32 *)a = *(u32 *)b; -+ *(u32 *)b = t; -+} -+ -+static void generic_swap(void *a, void *b, int size) -+{ -+ char t; -+ -+ do { -+ t = *(char *)a; -+ *(char *)a++ = *(char *)b; -+ *(char *)b++ = t; -+ } while (--size > 0); -+} -+ -+/** -+ * sort - sort an array of elements -+ * @base: pointer to data to sort -+ * @num: number of elements -+ * @size: size of each element -+ * @cmp: pointer to comparison function -+ * @swap: pointer to swap function or NULL -+ * -+ * This function does a heapsort on the given array. You may provide a -+ * swap function optimized to your element type. -+ * -+ * Sorting time is O(n log n) both on average and worst-case. While -+ * qsort is about 20% faster on average, it suffers from exploitable -+ * O(n*n) worst-case behavior and extra memory requirements that make -+ * it less suitable for kernel use. -+ */ -+ -+static void sort(void *base, size_t num, size_t size, -+ int (*cmp)(const void *, const void *), -+ void (*swap)(void *, void *, int size)) -+{ -+ /* pre-scale counters for performance */ -+ int i = (num/2 - 1) * size, n = num * size, c, r; -+ -+ if (!swap) -+ swap = (size == 4 ? u32_swap : generic_swap); -+ -+ /* heapify */ -+ for ( ; i >= 0; i -= size) { -+ for (r = i; r * 2 + size < n; r = c) { -+ c = r * 2 + size; -+ if (c < n - size && cmp(base + c, base + c + size) < 0) -+ c += size; -+ if (cmp(base + r, base + c) >= 0) -+ break; -+ swap(base + r, base + c, size); -+ } -+ } -+ -+ /* sort */ -+ for (i = n - size; i >= 0; i -= size) { -+ swap(base, base + i, size); -+ for (r = 0; r * 2 + size < i; r = c) { -+ c = r * 2 + size; -+ if (c < i - size && cmp(base + c, base + c + size) < 0) -+ c += size; -+ if (cmp(base + r, base + c) >= 0) -+ break; -+ swap(base + r, base + c, size); -+ } -+ } -+} -+ -+EXPORT_SYMBOL(sort); -+ -+#if 0 -+/* a simple boot-time regression test */ -+ -+int cmpint(const void *a, const void *b) -+{ -+ return *(int *)a - *(int *)b; -+} -+ -+static int sort_test(void) -+{ -+ int *a, i, r = 1; -+ -+ a = kmalloc(1000 * sizeof(int), GFP_KERNEL); -+ BUG_ON(!a); -+ -+ printk("testing sort()\n"); -+ -+ for (i = 0; i < 1000; i++) { -+ r = (r * 725861) % 6599; -+ a[i] = r; -+ } -+ -+ sort(a, 1000, sizeof(int), cmpint, NULL); -+ -+ for (i = 0; i < 999; i++) -+ if (a[i] > a[i+1]) { -+ printk("sort() failed!\n"); -+ break; -+ } -+ -+ kfree(a); -+ -+ return 0; -+} -+ -+module_init(sort_test); -+#endif diff --git a/package/madwifi/patches-r3776/126-rxerr_frames.patch b/package/madwifi/patches-r3776/126-rxerr_frames.patch deleted file mode 100644 index f95124135a..0000000000 --- a/package/madwifi/patches-r3776/126-rxerr_frames.patch +++ /dev/null @@ -1,27 +0,0 @@ ---- a/ath/if_ath.c -+++ b/ath/if_ath.c -@@ -6451,9 +6451,6 @@ - rs = &bf->bf_dsstatus.ds_rxstat; - - len = rs->rs_datalen; -- /* DMA sync. dies spectacularly if len == 0 */ -- if (len == 0) -- goto rx_next; - if (rs->rs_more) { - /* Frame spans multiple descriptors; this - * cannot happen yet as we don't support -@@ -6513,8 +6510,12 @@ - * setup again to receive another frame. - * NB: Meta-data (rs, noise, tsf) in the ath_buf is still - * used. */ -- bus_dma_sync_single(sc->sc_bdev, -- bf->bf_skbaddr, len, BUS_DMA_FROMDEVICE); -+ -+ /* DMA sync. dies spectacularly if len == 0 */ -+ if (len != 0) { -+ bus_dma_sync_single(sc->sc_bdev, -+ bf->bf_skbaddr, len, BUS_DMA_FROMDEVICE); -+ } - skb = ath_rxbuf_take_skb(sc, bf); - - sc->sc_stats.ast_ant_rx[rs->rs_antenna]++; diff --git a/package/madwifi/patches-r3776/200-no_debug.patch b/package/madwifi/patches-r3776/200-no_debug.patch deleted file mode 100644 index 0797f8fb65..0000000000 --- a/package/madwifi/patches-r3776/200-no_debug.patch +++ /dev/null @@ -1,420 +0,0 @@ ---- a/ath/if_ath.c -+++ b/ath/if_ath.c -@@ -323,8 +323,10 @@ - static void ath_set_dfs_cac_time(struct ieee80211com *, unsigned int seconds); - - static unsigned int ath_test_radar(struct ieee80211com *); --static unsigned int ath_dump_hal_map(struct ieee80211com *ic); -+#ifdef AR_DEBUG - -+static unsigned int ath_dump_hal_map(struct ieee80211com *ic); -+#endif - static u_int32_t ath_get_clamped_maxtxpower(struct ath_softc *sc); - static u_int32_t ath_set_clamped_maxtxpower(struct ath_softc *sc, - u_int32_t new_clamped_maxtxpower); -@@ -334,7 +336,10 @@ - unsigned int param, unsigned int value); - - static u_int32_t ath_get_real_maxtxpower(struct ath_softc *sc); -+ -+#ifdef AR_DEBUG - static int ath_txq_check(struct ath_softc *sc, struct ath_txq *txq, const char *msg); -+#endif - - static int ath_countrycode = CTRY_DEFAULT; /* country code */ - static int ath_outdoor = AH_FALSE; /* enable outdoor use */ -@@ -486,9 +491,11 @@ - u_int8_t csz; - - sc->devid = devid; -+#ifdef AR_DEBUG - ath_debug_global = (ath_debug & ATH_DEBUG_GLOBAL); - sc->sc_debug = (ath_debug & ~ATH_DEBUG_GLOBAL); - DPRINTF(sc, ATH_DEBUG_ANY, "%s: devid 0x%x\n", __func__, devid); -+#endif - - /* Allocate space for dynamically determined maximum VAP count */ - sc->sc_bslot = -@@ -1014,7 +1021,9 @@ - ic->ic_vap_delete = ath_vap_delete; - - ic->ic_test_radar = ath_test_radar; -+#ifdef AR_DEBUG - ic->ic_dump_hal_map = ath_dump_hal_map; -+#endif - - ic->ic_set_dfs_testmode = ath_set_dfs_testmode; - ic->ic_get_dfs_testmode = ath_get_dfs_testmode; -@@ -1285,12 +1294,14 @@ - /* If no default VAP debug flags are passed, allow a few to - * transfer down from the driver to new VAPs so we can have load - * time debugging for VAPs too. */ -+#ifdef AR_DEBUG - vap->iv_debug = 0 | - ((sc->sc_debug & ATH_DEBUG_RATE) ? IEEE80211_MSG_XRATE : 0) | - ((sc->sc_debug & ATH_DEBUG_XMIT) ? IEEE80211_MSG_OUTPUT : 0) | - ((sc->sc_debug & ATH_DEBUG_RECV) ? IEEE80211_MSG_INPUT : 0) | - 0 - ; -+#endif - } - ic->ic_debug = (sc->sc_default_ieee80211_debug & IEEE80211_MSG_IC); - -@@ -2811,6 +2822,7 @@ - #endif - } - -+#ifdef AR_DEBUG - static void - ath_txq_dump(struct ath_softc *sc, struct ath_txq *txq) - { -@@ -2866,6 +2878,7 @@ - - return 1; - } -+#endif - - /* - * Insert a buffer on a txq -@@ -8384,7 +8397,9 @@ - ath_tx_timeout(struct net_device *dev) - { - struct ath_softc *sc = dev->priv; -+#ifdef AR_DEBUG - int i; -+#endif - - if (ath_chan_unavail(sc)) - return; -@@ -8393,12 +8408,14 @@ - (dev->flags & IFF_RUNNING) ? "" : "NOT ", - sc->sc_invalid ? "in" : ""); - -+#ifdef AR_DEBUG - for (i = 0; i < HAL_NUM_TX_QUEUES; i++) { - if (ATH_TXQ_SETUP(sc, i)) { - ath_txq_check(sc, &sc->sc_txq[i], __func__); - ath_txq_dump(sc, &sc->sc_txq[i]); - } - } -+#endif - - if ((dev->flags & IFF_RUNNING) && !sc->sc_invalid) { - sc->sc_stats.ast_watchdog++; -@@ -10638,6 +10655,7 @@ - /* XXX validate? */ - sc->sc_ledpin = val; - break; -+#ifdef AR_DEBUG - case ATH_DEBUG: - sc->sc_debug = (val & ~ATH_DEBUG_GLOBAL); - ath_debug_global = (val & ATH_DEBUG_GLOBAL); -@@ -10645,6 +10663,7 @@ - "0x%08x.\n", val); - - break; -+#endif - case ATH_TXANTENNA: - /* - * antenna can be: -@@ -10818,9 +10837,11 @@ - case ATH_REGDOMAIN: - ath_hal_getregdomain(ah, &val); - break; -+#ifdef AR_DEBUG - case ATH_DEBUG: - val = sc->sc_debug | ath_debug_global; - break; -+#endif - case ATH_TXANTENNA: - val = sc->sc_txantenna; - break; -@@ -11939,6 +11960,7 @@ - } - - /* This is called by a private ioctl (iwpriv) to dump the HAL obfuscation table */ -+#ifdef AR_DEBUG - static unsigned int - ath_dump_hal_map(struct ieee80211com *ic) - { -@@ -11947,7 +11969,7 @@ - ath_hal_dump_map(sc->sc_ah); - return 0; - } -- -+#endif - /* If we are shutting down or blowing off the DFS channel availability check - * then we call this to stop the behavior before we take the rest of the - * necessary actions (such as a DFS reaction to radar). */ ---- a/ath_rate/amrr/amrr.c -+++ b/ath_rate/amrr/amrr.c -@@ -70,7 +70,9 @@ - - #include "amrr.h" - -+#ifdef AR_DEBUG - #define AMRR_DEBUG -+#endif - #ifdef AMRR_DEBUG - #define DPRINTF(sc, _fmt, ...) do { \ - if (sc->sc_debug & 0x10) \ ---- a/ath_rate/minstrel/minstrel.c -+++ b/ath_rate/minstrel/minstrel.c -@@ -117,7 +117,9 @@ - - #include "minstrel.h" - -+#ifdef AR_DEBUG - #define MINSTREL_DEBUG -+#endif - #ifdef MINSTREL_DEBUG - enum { - ATH_DEBUG_RATE = 0x00000010 /* rate control */ -@@ -963,7 +965,9 @@ - (struct ieee80211_node_table *)&vap->iv_ic->ic_sta; - unsigned int x = 0; - unsigned int this_tp, this_prob, this_eprob; -- struct ath_softc *sc = vap->iv_ic->ic_dev->priv;; -+#ifdef AR_DEBUG -+ struct ath_softc *sc = vap->iv_ic->ic_dev->priv; -+#endif - - IEEE80211_NODE_TABLE_LOCK_IRQ(nt); - TAILQ_FOREACH(ni, &nt->nt_node, ni_list) { ---- a/ath_rate/onoe/onoe.c -+++ b/ath_rate/onoe/onoe.c -@@ -66,7 +66,9 @@ - - #include "onoe.h" - -+#ifdef AR_DEBUG - #define ONOE_DEBUG -+#endif - #ifdef ONOE_DEBUG - enum { - ATH_DEBUG_RATE = 0x00000010, /* rate control */ ---- a/ath_rate/sample/sample.c -+++ b/ath_rate/sample/sample.c -@@ -68,7 +68,9 @@ - - #include "sample.h" - --#define SAMPLE_DEBUG -+#ifdef AR_DEBUG -+#define SAMPLE_DEBUG -+#endif - #ifdef SAMPLE_DEBUG - enum { - ATH_DEBUG_RATE = 0x00000010, /* rate control */ ---- a/tools/do_multi.c -+++ b/tools/do_multi.c -@@ -9,16 +9,20 @@ - - progname = basename(argv[0]); - -+#ifdef AR_DEBUG - if(strcmp(progname, "80211debug") == 0) - ret = a80211debug_init(argc, argv); -+#endif - if(strcmp(progname, "80211stats") == 0) - ret = a80211stats_init(argc, argv); - if(strcmp(progname, "athchans") == 0) - ret = athchans_init(argc, argv); - if(strcmp(progname, "athctrl") == 0) - ret = athctrl_init(argc, argv); -+#ifdef AR_DEBUG - if(strcmp(progname, "athdebug") == 0) - ret = athdebug_init(argc, argv); -+#endif - if(strcmp(progname, "athkey") == 0) - ret = athkey_init(argc, argv); - if(strcmp(progname, "athstats") == 0) ---- a/tools/Makefile -+++ b/tools/Makefile -@@ -39,6 +39,10 @@ - - ATH_HAL = $(TOP)/ath_hal - -+ifndef ATH_DEBUG -+ATH_DEBUG=1 -+endif -+ - # - # Path to the HAL source code. - # -@@ -46,17 +50,22 @@ - HAL = $(TOP)/hal - endif - -+INCS = -I. -I$(HAL) -I$(TOP) -I$(ATH_HAL) -I$(TOP)/ath -+CFLAGS = -g -O2 -Wall -+ALL_CFLAGS = $(CFLAGS) $(INCS) -+LDFLAGS = - - PROGRAMS = athstats 80211stats athkey athchans athctrl \ -- athdebug 80211debug wlanconfig wpakey -+ wlanconfig wpakey -+ -+ifeq ($(ATH_DEBUG),1) -+ PROGRAMS += athdebug 80211debug -+ ALL_CFLAGS += -DAR_DEBUG -+endif - - OBJS = $(patsubst %,%.o,$(PROGRAMS)) ath_info/ath_info.o - SUBDIRS = ath_info - --INCS = -I. -I$(HAL) -I$(TOP) -I$(ATH_HAL) -I$(TOP)/ath --CFLAGS = -g -O2 -Wall --ALL_CFLAGS = $(CFLAGS) $(INCS) --LDFLAGS = - - all: all-subdirs compile - ---- a/ath/if_ath_hal.h -+++ b/ath/if_ath_hal.h -@@ -1263,6 +1263,7 @@ - - tail -f /var/log/messages | sed -f hal_unmangle.sed - */ -+#ifdef AR_DEBUG - static inline void ath_hal_dump_map(struct ath_hal *ah) - { - #ifdef CONFIG_KALLSYMS -@@ -1527,7 +1528,7 @@ - #endif /* #ifndef CONFIG_KALLSYMS */ - - } -- -+#endif - #include "if_ath_hal_wrappers.h" - #include "if_ath_hal_extensions.h" - ---- a/net80211/ieee80211_var.h -+++ b/net80211/ieee80211_var.h -@@ -495,9 +495,10 @@ - /* inject a fake radar signal -- used while on a 802.11h DFS channels */ - unsigned int (*ic_test_radar)(struct ieee80211com *); - -+#ifdef AR_DEBUG - /* dump HAL */ - unsigned int (*ic_dump_hal_map)(struct ieee80211com *); -- -+#endif - /* DFS channel availability check time (in seconds) */ - void (*ic_set_dfs_cac_time)(struct ieee80211com *, unsigned int); - unsigned int (*ic_get_dfs_cac_time)(struct ieee80211com *); ---- a/net80211/ieee80211_wireless.c -+++ b/net80211/ieee80211_wireless.c -@@ -1557,6 +1557,7 @@ - return 0; - } - -+#ifdef AR_DEBUG - static int - ieee80211_ioctl_hal_map(struct net_device *dev, struct iw_request_info *info, - void *w, char *extra) -@@ -1567,7 +1568,7 @@ - params[0] = ic->ic_dump_hal_map(ic); - return 0; - } -- -+#endif - - static int - ieee80211_ioctl_radar(struct net_device *dev, struct iw_request_info *info, -@@ -5296,8 +5297,10 @@ - IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getwmmparams" }, - { IEEE80211_IOCTL_RADAR, - 0, 0, "doth_radar" }, -+#ifdef AR_DEBUG - { IEEE80211_IOCTL_HALMAP, - 0, 0, "dump_hal_map" }, -+#endif - /* - * These depends on sub-ioctl support which added in version 12. - */ -@@ -5751,7 +5754,9 @@ - set_priv(IEEE80211_IOCTL_SETMLME, ieee80211_ioctl_setmlme), - set_priv(IEEE80211_IOCTL_SETKEY, ieee80211_ioctl_setkey), - set_priv(IEEE80211_IOCTL_DELKEY, ieee80211_ioctl_delkey), -+#ifdef AR_DEBUG - set_priv(IEEE80211_IOCTL_HALMAP, ieee80211_ioctl_hal_map), -+#endif - set_priv(IEEE80211_IOCTL_ADDMAC, ieee80211_ioctl_addmac), - set_priv(IEEE80211_IOCTL_DELMAC, ieee80211_ioctl_delmac), - set_priv(IEEE80211_IOCTL_WDSADDMAC, ieee80211_ioctl_wdsmac), ---- a/ath/if_ath_debug.h -+++ b/ath/if_ath_debug.h -@@ -54,6 +54,10 @@ - ATH_DEBUG_GLOBAL = (ATH_DEBUG_SKB|ATH_DEBUG_SKB_REF) - }; - -+#define EPRINTF(_sc, _fmt, ...) \ -+ printk(KERN_ERR "%s: %s: " _fmt, \ -+ SC_DEV_NAME(_sc), __func__, ## __VA_ARGS__) -+ - #ifdef AR_DEBUG - - /* DEBUG-ONLY DEFINITIONS */ -@@ -68,20 +72,9 @@ - ath_keyprint((_sc), __func__, _ix, _hk, _mac); \ - } while (0) - --#else /* #ifdef AR_DEBUG */ -- --#define DFLAG_ISSET(sc, _m) 0 --#define DPRINTF(sc, _m, _fmt, ...) --#define KEYPRINTF(sc, k, ix, mac) -- --#endif /* #ifdef AR_DEBUG */ - - #define IFF_DUMPPKTS(_sc, _m) DFLAG_ISSET((_sc), (_m)) - --#define EPRINTF(_sc, _fmt, ...) \ -- printk(KERN_ERR "%s: %s: " _fmt, \ -- SC_DEV_NAME(_sc), __func__, ## __VA_ARGS__) -- - #define WPRINTF(_sc, _fmt, ...) \ - printk(KERN_WARNING "%s: %s: " _fmt, \ - SC_DEV_NAME(_sc), __func__, ## __VA_ARGS__) -@@ -89,5 +82,14 @@ - #define IPRINTF(_sc, _fmt, ...) \ - printk(KERN_INFO "%s: %s: " _fmt, \ - SC_DEV_NAME(_sc), __func__, ## __VA_ARGS__) -+#else -+#define DFLAG_ISSET(sc, _m) 0 -+#define DPRINTF(sc, _m, _fmt, ...) -+#define KEYPRINTF(sc, k, ix, mac) -+#define WPRINTF(...) -+#define IPRINTF(...) -+#define IFF_DUMPPKTS(...) 0 -+ -+#endif - - #endif /* #ifndef _IF_ATH_DEBUG_H_ */ ---- a/ath/if_ath_pci.c -+++ b/ath/if_ath_pci.c -@@ -134,8 +134,10 @@ - u16 vdevice; - int i; - -- if (pci_enable_device(pdev)) -+ if (pci_enable_device(pdev)) { -+ printk(KERN_ERR "%s: failed to enable PCI device\n", dev_info); - return -EIO; -+ } - - /* XXX 32-bit addressing only */ - if (pci_set_dma_mask(pdev, 0xffffffff)) { -@@ -244,8 +246,10 @@ - sc->aps_sc.sc_ledpin = 1; - } - -- if (ath_attach(vdevice, dev, NULL) != 0) -+ if ((i = ath_attach(vdevice, dev, NULL)) != 0) { -+ printk(KERN_ERR "%s: ath_attach failed: %d\n", dev_info, i); - goto bad4; -+ } - - athname = ath_hal_probe(id->vendor, vdevice); - printk(KERN_INFO "%s: %s: %s: mem=0x%llx, irq=%d\n", diff --git a/package/madwifi/patches-r3776/201-no_debug_extra.patch b/package/madwifi/patches-r3776/201-no_debug_extra.patch deleted file mode 100644 index 0e26d5f398..0000000000 --- a/package/madwifi/patches-r3776/201-no_debug_extra.patch +++ /dev/null @@ -1,33 +0,0 @@ ---- a/ath/if_ath.c -+++ b/ath/if_ath.c -@@ -423,8 +423,8 @@ - "defaults to '" DEF_RATE_CTL "'"); - MODULE_PARM_DESC(intmit, "Enable interference mitigation by default. Default is 0."); - --static int ath_debug = 0; - #ifdef AR_DEBUG -+static int ath_debug = 0; - #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,52)) - MODULE_PARM(ath_debug, "i"); - #else -@@ -435,8 +435,8 @@ - static void ath_printtxbuf(const struct ath_buf *, int); - #endif /* defined(AR_DEBUG) */ - --static int ieee80211_debug = 0; - #ifdef AR_DEBUG -+static int ieee80211_debug = 0; - #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,52)) - MODULE_PARM(ieee80211_debug, "i"); - #else -@@ -853,8 +853,10 @@ - ic->ic_updateslot = ath_updateslot; - atomic_set(&ic->ic_node_counter, 0); - ic->ic_debug = 0; -+#ifdef AR_DEBUG - sc->sc_debug = (ath_debug & ~ATH_DEBUG_GLOBAL); - sc->sc_default_ieee80211_debug = ieee80211_debug; -+#endif - - ic->ic_wme.wme_update = ath_wme_update; - ic->ic_uapsd_flush = ath_uapsd_flush; diff --git a/package/madwifi/patches-r3776/300-napi_polling.patch b/package/madwifi/patches-r3776/300-napi_polling.patch deleted file mode 100644 index 27dd838db0..0000000000 --- a/package/madwifi/patches-r3776/300-napi_polling.patch +++ /dev/null @@ -1,529 +0,0 @@ ---- a/ath/if_ath.c -+++ b/ath/if_ath.c -@@ -182,7 +182,11 @@ - struct sk_buff *, int, int, u_int64_t); - static void ath_setdefantenna(struct ath_softc *, u_int); - static struct ath_txq *ath_txq_setup(struct ath_softc *, int, int); --static void ath_rx_tasklet(TQUEUE_ARG); -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24) -+static int ath_rx_poll(struct napi_struct *napi, int budget); -+#else -+static int ath_rx_poll(struct net_device *dev, int *budget); -+#endif - static int ath_hardstart(struct sk_buff *, struct net_device *); - static int ath_mgtstart(struct ieee80211com *, struct sk_buff *); - #ifdef ATH_SUPERG_COMP -@@ -331,6 +335,9 @@ - static u_int32_t ath_set_clamped_maxtxpower(struct ath_softc *sc, - u_int32_t new_clamped_maxtxpower); - -+static void ath_poll_disable(struct net_device *dev); -+static void ath_poll_enable(struct net_device *dev); -+ - static void ath_scanbufs(struct ath_softc *sc); - static int ath_debug_iwpriv(struct ieee80211com *ic, - unsigned int param, unsigned int value); -@@ -518,7 +525,6 @@ - - atomic_set(&sc->sc_txbuf_counter, 0); - -- ATH_INIT_TQUEUE(&sc->sc_rxtq, ath_rx_tasklet, dev); - ATH_INIT_TQUEUE(&sc->sc_txtq, ath_tx_tasklet, dev); - ATH_INIT_TQUEUE(&sc->sc_bmisstq, ath_bmiss_tasklet, dev); - ATH_INIT_TQUEUE(&sc->sc_bstucktq, ath_bstuck_tasklet, dev); -@@ -833,6 +839,12 @@ - dev->set_mac_address = ath_set_mac_address; - dev->change_mtu = ath_change_mtu; - dev->tx_queue_len = ATH_TXBUF - ATH_TXBUF_MGT_RESERVED; -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24) -+ netif_napi_add(dev, &sc->sc_napi, ath_rx_poll, 64); -+#else -+ dev->poll = ath_rx_poll; -+ dev->weight = 64; -+#endif - #ifdef USE_HEADERLEN_RESV - dev->hard_header_len += sizeof(struct ieee80211_qosframe) + - sizeof(struct llc) + -@@ -1770,7 +1782,7 @@ - } - - static void --ath_intr_process_rx_descriptors(struct ath_softc *sc, int *pneedmark, u_int64_t hw_tsf) -+ath_intr_process_rx_descriptors(struct ath_softc *sc, int *pneedmark, u_int64_t hw_tsf, int schedule) - { - struct ath_hal *ah = sc->sc_ah; - struct ath_desc *ds; -@@ -2252,8 +2264,25 @@ - } - - /* If we got something to process, schedule rx queue to handle it */ -- if (count) -- ATH_SCHEDULE_TQUEUE(&sc->sc_rxtq, pneedmark); -+ if (count) { -+ sc->sc_isr &= ~HAL_INT_RX; -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24) -+ if (netif_rx_schedule_prep(sc->sc_dev, &sc->sc_napi)) -+#else -+ if (netif_rx_schedule_prep(sc->sc_dev)) -+#endif -+ { -+#ifndef ATH_PRECISE_TSF -+ sc->sc_imask &= ~HAL_INT_RX; -+ ath_hal_intrset(ah, sc->sc_imask); -+#endif -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24) -+ __netif_rx_schedule(sc->sc_dev, &sc->sc_napi); -+#else -+ __netif_rx_schedule(sc->sc_dev); -+#endif -+ } -+ } - ATH_RXBUF_UNLOCK_IRQ(sc); - #undef PA2DESC - } -@@ -2343,6 +2372,7 @@ - (status & HAL_INT_GLOBAL) ? " HAL_INT_GLOBAL" : "" - ); - -+ sc->sc_isr = status; - status &= sc->sc_imask; /* discard unasked for bits */ - /* As soon as we know we have a real interrupt we intend to service, - * we will check to see if we need an initial hardware TSF reading. -@@ -2400,7 +2430,7 @@ - } - if (status & (HAL_INT_RX | HAL_INT_RXPHY)) { - /* NB: Will schedule rx tasklet if necessary. */ -- ath_intr_process_rx_descriptors(sc, &needmark, hw_tsf); -+ ath_intr_process_rx_descriptors(sc, &needmark, hw_tsf, 1); - } - if (status & HAL_INT_TX) { - #ifdef ATH_SUPERG_DYNTURBO -@@ -2426,6 +2456,11 @@ - } - } - #endif -+ /* disable transmit interrupt */ -+ sc->sc_isr &= ~HAL_INT_TX; -+ ath_hal_intrset(ah, sc->sc_imask & ~HAL_INT_TX); -+ sc->sc_imask &= ~HAL_INT_TX; -+ - ATH_SCHEDULE_TQUEUE(&sc->sc_txtq, &needmark); - } - if (status & HAL_INT_BMISS) { -@@ -2617,6 +2652,7 @@ - if (sc->sc_tx99 != NULL) - sc->sc_tx99->start(sc->sc_tx99); - #endif -+ ath_poll_enable(dev); - - done: - ATH_UNLOCK(sc); -@@ -2657,6 +2693,9 @@ - if (sc->sc_tx99 != NULL) - sc->sc_tx99->stop(sc->sc_tx99); - #endif -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24) -+ ath_poll_disable(dev); -+#endif - netif_stop_queue(dev); /* XXX re-enabled by ath_newstate */ - dev->flags &= ~IFF_RUNNING; /* NB: avoid recursion */ - ieee80211_stop_running(ic); /* stop all VAPs */ -@@ -4109,6 +4148,43 @@ - return ath_keyset(sc, k, mac, vap->iv_bss); - } - -+static void ath_poll_disable(struct net_device *dev) -+{ -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24) -+ struct ath_softc *sc = dev->priv; -+#endif -+ -+ /* -+ * XXX Using in_softirq is not right since we might -+ * be called from other soft irq contexts than -+ * ath_rx_poll -+ */ -+ if (!in_softirq()) { -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24) -+ napi_disable(&sc->sc_napi); -+#else -+ netif_poll_disable(dev); -+#endif -+ } -+} -+ -+static void ath_poll_enable(struct net_device *dev) -+{ -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24) -+ struct ath_softc *sc = dev->priv; -+#endif -+ -+ /* NB: see above */ -+ if (!in_softirq()) { -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24) -+ napi_enable(&sc->sc_napi); -+#else -+ netif_poll_enable(dev); -+#endif -+ } -+} -+ -+ - /* - * Block/unblock tx+rx processing while a key change is done. - * We assume the caller serializes key management operations -@@ -4119,33 +4195,23 @@ - ath_key_update_begin(struct ieee80211vap *vap) - { - struct net_device *dev = vap->iv_ic->ic_dev; -- struct ath_softc *sc = dev->priv; - -- DPRINTF(sc, ATH_DEBUG_KEYCACHE, "Begin\n"); - /* - * When called from the rx tasklet we cannot use - * tasklet_disable because it will block waiting - * for us to complete execution. -- * -- * XXX Using in_softirq is not right since we might -- * be called from other soft irq contexts than -- * ath_rx_tasklet. - */ -- if (!in_softirq()) -- tasklet_disable(&sc->sc_rxtq); -- netif_stop_queue(dev); -+ if ((dev->flags & (IFF_UP|IFF_RUNNING)) == (IFF_UP|IFF_RUNNING)) -+ netif_stop_queue(dev); - } - - static void - ath_key_update_end(struct ieee80211vap *vap) - { - struct net_device *dev = vap->iv_ic->ic_dev; -- struct ath_softc *sc = dev->priv; - -- DPRINTF(sc, ATH_DEBUG_KEYCACHE, "End\n"); -- netif_wake_queue(dev); -- if (!in_softirq()) /* NB: see above */ -- tasklet_enable(&sc->sc_rxtq); -+ if ((dev->flags & (IFF_UP|IFF_RUNNING)) == (IFF_UP|IFF_RUNNING)) -+ netif_wake_queue(dev); - } - - /* -@@ -6405,15 +6471,25 @@ - sc->sc_numrxotherant = 0; - } - --static void --ath_rx_tasklet(TQUEUE_ARG data) -+static int -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24) -+ath_rx_poll(struct napi_struct *napi, int budget) -+#else -+ath_rx_poll(struct net_device *dev, int *budget) -+#endif - { - #define PA2DESC(_sc, _pa) \ - ((struct ath_desc *)((caddr_t)(_sc)->sc_rxdma.dd_desc + \ - ((_pa) - (_sc)->sc_rxdma.dd_desc_paddr))) -- struct net_device *dev = (struct net_device *)data; -- struct ath_buf *bf; -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24) -+ struct ath_softc *sc = container_of(napi, struct ath_softc, sc_napi); -+ struct net_device *dev = sc->sc_dev; -+ u_int rx_limit = budget; -+#else - struct ath_softc *sc = dev->priv; -+ u_int rx_limit = min(dev->quota, *budget); -+#endif -+ struct ath_buf *bf; - struct ieee80211com *ic = &sc->sc_ic; - struct ath_hal *ah = sc ? sc->sc_ah : NULL; - struct ath_desc *ds; -@@ -6421,6 +6497,7 @@ - struct ieee80211_node *ni; - struct sk_buff *skb = NULL; - unsigned int len, phyerr, mic_fail = 0; -+ unsigned int early_stop = 0; - int type = -1; /* undefined */ - int init_ret = 0; - int bf_processed = 0; -@@ -6428,6 +6505,7 @@ - int errors = 0; - - DPRINTF(sc, ATH_DEBUG_RX_PROC, "%s started...\n", __func__); -+process_rx_again: - do { - /* Get next RX buffer pending processing by RX tasklet... - * -@@ -6457,6 +6535,10 @@ - break; - - bf_processed++; -+ if (rx_limit-- < 0) { -+ early_stop = 1; -+ break; -+ } - ds = bf->bf_desc; - - #ifdef AR_DEBUG -@@ -6491,6 +6573,7 @@ - sc->sc_stats.ast_rx_phyerr++; - phyerr = rs->rs_phyerr & 0x1f; - sc->sc_stats.ast_rx_phy[phyerr]++; -+ goto rx_next; - } - if (rs->rs_status & HAL_RXERR_DECRYPT) { - /* Decrypt error. If the error occurred -@@ -6689,6 +6772,33 @@ - STAILQ_INSERT_TAIL(&sc->sc_rxbuf, bf, bf_list); - ATH_RXBUF_UNLOCK_IRQ(sc); - } while (1); -+ if (!early_stop) { -+ unsigned long flags; -+ /* Check if more data is received while we were -+ * processing the descriptor chain. -+ */ -+#ifndef ATH_PRECISE_TSF -+ local_irq_save(flags); -+ if (sc->sc_isr & HAL_INT_RX) { -+ u_int64_t hw_tsf = ath_hal_gettsf64(ah); -+ sc->sc_isr &= ~HAL_INT_RX; -+ local_irq_restore(flags); -+ ath_intr_process_rx_descriptors(sc, NULL, hw_tsf, 0); -+ goto process_rx_again; -+ } -+ sc->sc_imask |= HAL_INT_RX; -+ ath_hal_intrset(ah, sc->sc_imask); -+ local_irq_restore(flags); -+#endif -+ } -+ -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24) -+ netif_rx_complete(dev, napi); -+#else -+ netif_rx_complete(dev); -+ *budget -= bf_processed; -+ dev->quota -= bf_processed; -+#endif - - if (sc->sc_useintmit) - ath_hal_rxmonitor(ah, &sc->sc_halstats, &sc->sc_curchan); -@@ -6701,6 +6811,12 @@ - " %d rx buf processed. %d were errors. %d skb accepted.\n", - __func__, bf_processed, errors, skb_accepted); - #undef PA2DESC -+ -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24) -+ return bf_processed; -+#else -+ return early_stop; -+#endif - } - - #ifdef ATH_SUPERG_XR -@@ -8306,12 +8422,24 @@ - { - struct net_device *dev = (struct net_device *)data; - struct ath_softc *sc = dev->priv; -+ unsigned long flags; - -+process_tx_again: - if (txqactive(sc->sc_ah, 0)) - ath_tx_processq(sc, &sc->sc_txq[0]); - if (txqactive(sc->sc_ah, sc->sc_cabq->axq_qnum)) - ath_tx_processq(sc, sc->sc_cabq); - -+ local_irq_save(flags); -+ if (sc->sc_isr & HAL_INT_TX) { -+ sc->sc_isr &= ~HAL_INT_TX; -+ local_irq_restore(flags); -+ goto process_tx_again; -+ } -+ sc->sc_imask |= HAL_INT_TX; -+ ath_hal_intrset(sc->sc_ah, sc->sc_imask); -+ local_irq_restore(flags); -+ - netif_wake_queue(dev); - - if (sc->sc_softled) -@@ -8327,7 +8455,9 @@ - { - struct net_device *dev = (struct net_device *)data; - struct ath_softc *sc = dev->priv; -+ unsigned long flags; - -+process_tx_again: - /* - * Process each active queue. - */ -@@ -8357,6 +8487,16 @@ - if (sc->sc_uapsdq && txqactive(sc->sc_ah, sc->sc_uapsdq->axq_qnum)) - ath_tx_processq(sc, sc->sc_uapsdq); - -+ local_irq_save(flags); -+ if (sc->sc_isr & HAL_INT_TX) { -+ sc->sc_isr &= ~HAL_INT_TX; -+ local_irq_restore(flags); -+ goto process_tx_again; -+ } -+ sc->sc_imask |= HAL_INT_TX; -+ ath_hal_intrset(sc->sc_ah, sc->sc_imask); -+ local_irq_restore(flags); -+ - netif_wake_queue(dev); - - if (sc->sc_softled) -@@ -10322,9 +10462,9 @@ - dev->mtu = mtu; - if ((dev->flags & IFF_RUNNING) && !sc->sc_invalid) { - /* NB: the rx buffers may need to be reallocated */ -- tasklet_disable(&sc->sc_rxtq); -+ ath_poll_disable(dev); - error = ath_reset(dev); -- tasklet_enable(&sc->sc_rxtq); -+ ath_poll_enable(dev); - } - ATH_UNLOCK(sc); - ---- a/ath/if_athvar.h -+++ b/ath/if_athvar.h -@@ -56,6 +56,10 @@ - # include - #endif - -+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0) -+#define irqs_disabled() 0 -+#endif -+ - /* - * Deduce if tasklets are available. If not then - * fall back to using the immediate work queue. -@@ -644,6 +648,9 @@ - struct ath_softc { - struct ieee80211com sc_ic; /* NB: must be first */ - struct net_device *sc_dev; -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24) -+ struct napi_struct sc_napi; -+#endif - void __iomem *sc_iobase; /* address of the device */ - struct semaphore sc_lock; /* dev-level lock */ - struct net_device_stats sc_devstats; /* device statistics */ -@@ -756,7 +763,6 @@ - struct ath_buf *sc_rxbufcur; /* current rx buffer */ - u_int32_t *sc_rxlink; /* link ptr in last RX desc */ - spinlock_t sc_rxbuflock; -- struct ATH_TQ_STRUCT sc_rxtq; /* rx intr tasklet */ - struct ATH_TQ_STRUCT sc_rxorntq; /* rxorn intr tasklet */ - u_int16_t sc_cachelsz; /* cache line size */ - -@@ -769,6 +775,7 @@ - u_int sc_txintrperiod; /* tx interrupt batching */ - struct ath_txq sc_txq[HAL_NUM_TX_QUEUES]; - struct ath_txq *sc_ac2q[WME_NUM_AC]; /* WME AC -> h/w qnum */ -+ HAL_INT sc_isr; /* unmasked ISR state */ - struct ATH_TQ_STRUCT sc_txtq; /* tx intr tasklet */ - u_int8_t sc_grppoll_str[GRPPOLL_RATE_STR_LEN]; - struct ath_descdma sc_bdma; /* beacon descriptors */ -@@ -888,6 +895,8 @@ - #define ATH_TXBUF_LOCK_CHECK(_sc) - #endif - -+#define ATH_DISABLE_INTR local_irq_disable -+#define ATH_ENABLE_INTR local_irq_enable - - #define ATH_RXBUF_LOCK_INIT(_sc) spin_lock_init(&(_sc)->sc_rxbuflock) - #define ATH_RXBUF_LOCK_DESTROY(_sc) ---- a/net80211/ieee80211_skb.c -+++ b/net80211/ieee80211_skb.c -@@ -73,7 +73,7 @@ - #undef dev_queue_xmit - #undef kfree_skb - #undef kfree_skb_fast --#undef netif_rx -+#undef netif_receive_skb - #undef pskb_copy - #undef skb_clone - #undef skb_copy -@@ -581,8 +581,8 @@ - grp, vlan_tag); - } - --int netif_rx_debug(struct sk_buff *skb, const char *func, int line) { -- return netif_rx(untrack_skb(skb, 0, __func__, __LINE__)); -+int netif_receive_skb_debug(struct sk_buff *skb, const char *func, int line) { -+ return netif_receive_skb(untrack_skb(skb, 0, __func__, __LINE__)); - } - - struct sk_buff *alloc_skb_debug(unsigned int length, gfp_t gfp_mask, -@@ -707,7 +707,7 @@ - } - - EXPORT_SYMBOL(vlan_hwaccel_rx_debug); --EXPORT_SYMBOL(netif_rx_debug); -+EXPORT_SYMBOL(netif_receive_skb_debug); - EXPORT_SYMBOL(alloc_skb_debug); - EXPORT_SYMBOL(dev_alloc_skb_debug); - EXPORT_SYMBOL(skb_clone_debug); ---- a/net80211/ieee80211_skb.h -+++ b/net80211/ieee80211_skb.h -@@ -115,7 +115,7 @@ - - int vlan_hwaccel_rx_debug(struct sk_buff *skb, struct vlan_group *grp, - unsigned short vlan_tag, const char *func, int line); --int netif_rx_debug(struct sk_buff *skb, const char *func, int line); -+int netif_receive_skb_debug(struct sk_buff *skb, const char *func, int line); - struct sk_buff *alloc_skb_debug(unsigned int length, gfp_t gfp_mask, - const char *func, int line); - struct sk_buff *dev_alloc_skb_debug(unsigned int length, -@@ -150,7 +150,7 @@ - #undef dev_queue_xmit - #undef kfree_skb - #undef kfree_skb_fast --#undef netif_rx -+#undef netif_receive_skb - #undef pskb_copy - #undef skb_clone - #undef skb_copy -@@ -167,8 +167,8 @@ - skb_copy_expand_debug(_skb, _newheadroom, _newtailroom, _gfp_mask, __func__, __LINE__) - #define vlan_hwaccel_rx(_skb, _grp, _tag) \ - vlan_hwaccel_rx_debug(_skb, _grp, _tag, __func__, __LINE__) --#define netif_rx(_skb) \ -- netif_rx_debug(_skb, __func__, __LINE__) -+#define netif_receive_skb(_skb) \ -+ netif_receive_skb_debug(_skb, __func__, __LINE__) - #define alloc_skb(_length, _gfp_mask) \ - alloc_skb_debug(_length, _gfp_mask, __func__, __LINE__) - #define dev_alloc_skb(_length) \ ---- a/net80211/ieee80211_input.c -+++ b/net80211/ieee80211_input.c -@@ -1185,7 +1185,7 @@ - ret = vlan_hwaccel_rx(skb, - vap->iv_vlgrp, ni->ni_vlan); - else -- ret = netif_rx(skb); -+ ret = netif_receive_skb(skb); - if (ret == NET_RX_DROP) - vap->iv_devstats.rx_dropped++; - if (tni != NULL) -@@ -2285,7 +2285,7 @@ - - if (SKB_NI(skb1) != NULL) - ieee80211_unref_node(&SKB_NI(skb1)); -- if (netif_rx(skb1) == NET_RX_DROP) -+ if (netif_receive_skb(skb1) == NET_RX_DROP) - vap->iv_devstats.rx_dropped++; - } - } ---- a/net80211/ieee80211_monitor.c -+++ b/net80211/ieee80211_monitor.c -@@ -580,7 +580,7 @@ - - if (SKB_NI(skb1) != NULL) - ieee80211_unref_node(&SKB_NI(skb1)); -- if (netif_rx(skb1) == NET_RX_DROP) -+ if (netif_receive_skb(skb1) == NET_RX_DROP) - vap->iv_devstats.rx_dropped++; - skb1 = NULL; - } diff --git a/package/madwifi/patches-r3776/301-pureg_fix.patch b/package/madwifi/patches-r3776/301-pureg_fix.patch deleted file mode 100644 index fb6cefe364..0000000000 --- a/package/madwifi/patches-r3776/301-pureg_fix.patch +++ /dev/null @@ -1,168 +0,0 @@ ---- a/ath/if_ath.c -+++ b/ath/if_ath.c -@@ -4251,7 +4251,9 @@ - rfilt |= HAL_RX_FILTER_PROM; - if (ic->ic_opmode == IEEE80211_M_STA || - sc->sc_opmode == HAL_M_IBSS || /* NB: AHDEMO too */ -- (sc->sc_nostabeacons) || sc->sc_scanning) -+ (sc->sc_nostabeacons) || sc->sc_scanning || -+ ((ic->ic_opmode == IEEE80211_M_HOSTAP) && -+ (ic->ic_protmode != IEEE80211_PROT_NONE))) - rfilt |= HAL_RX_FILTER_BEACON; - if (sc->sc_nmonvaps > 0) - rfilt |= (HAL_RX_FILTER_CONTROL | HAL_RX_FILTER_BEACON | ---- a/net80211/ieee80211_input.c -+++ b/net80211/ieee80211_input.c -@@ -325,11 +325,12 @@ - bssid = wh->i_addr3; - } - /* -- * Validate the bssid. -+ * Validate the bssid. Let beacons get through though for 11g protection mode. - */ --#ifdef ATH_SUPERG_XR - if (!IEEE80211_ADDR_EQ(bssid, vap->iv_bssid) && -- !IEEE80211_ADDR_EQ(bssid, dev->broadcast)) { -+ !IEEE80211_ADDR_EQ(bssid, dev->broadcast) && -+ (subtype != IEEE80211_FC0_SUBTYPE_BEACON)) { -+#ifdef ATH_SUPERG_XR - /* - * allow MGT frames to vap->iv_xrvap. - * this will allow roaming between XR and normal vaps -@@ -345,18 +346,14 @@ - vap->iv_stats.is_rx_wrongbss++; - goto out; - } -- } - #else -- if (!IEEE80211_ADDR_EQ(bssid, vap->iv_bssid) && -- !IEEE80211_ADDR_EQ(bssid, dev->broadcast)) { - /* not interested in */ - IEEE80211_DISCARD_MAC(vap, IEEE80211_MSG_INPUT, - bssid, NULL, "%s", "not to bss"); - vap->iv_stats.is_rx_wrongbss++; - goto out; -- } -- - #endif -+ } - break; - case IEEE80211_M_WDS: - if (skb->len < sizeof(struct ieee80211_frame_addr4)) { -@@ -3019,7 +3016,7 @@ - u_int8_t *frm, *efrm; - u_int8_t *ssid, *rates, *xrates, *suppchan, *wpa, *rsn, *wme, *ath; - u_int8_t rate; -- int reassoc, resp, allocbs = 0; -+ int reassoc, resp, allocbs = 0, has_erp = 0; - u_int8_t qosinfo; - - if (ni_or_null == NULL) -@@ -3049,11 +3046,15 @@ - * o station mode when associated (to collect state - * updates such as 802.11g slot time), or - * o adhoc mode (to discover neighbors) -+ * o ap mode in protection mode (beacons only) - * Frames otherwise received are discarded. - */ - if (!((ic->ic_flags & IEEE80211_F_SCAN) || - (vap->iv_opmode == IEEE80211_M_STA && ni->ni_associd) || -- vap->iv_opmode == IEEE80211_M_IBSS)) { -+ (vap->iv_opmode == IEEE80211_M_IBSS) || -+ ((subtype == IEEE80211_FC0_SUBTYPE_BEACON) && -+ (vap->iv_opmode == IEEE80211_M_HOSTAP) && -+ (ic->ic_protmode != IEEE80211_PROT_NONE)))) { - vap->iv_stats.is_rx_mgtdiscard++; - return 0; - } -@@ -3137,6 +3138,7 @@ - break; - } - scan.erp = frm[2]; -+ has_erp = 1; - break; - case IEEE80211_ELEMID_RSN: - scan.rsn = frm; -@@ -3374,6 +3376,20 @@ - ieee80211_bg_scan(vap); - return 0; - } -+ -+ /* Update AP protection mode when in 11G mode */ -+ if ((vap->iv_opmode == IEEE80211_M_HOSTAP) && -+ IEEE80211_IS_CHAN_ANYG(ic->ic_curchan)) { -+ -+ /* Assume no ERP IE == 11b AP */ -+ if ((!has_erp || (has_erp && (scan.erp & IEEE80211_ERP_NON_ERP_PRESENT))) && -+ !(ic->ic_flags & IEEE80211_F_USEPROT)) { -+ -+ ic->ic_flags |= IEEE80211_F_USEPROT; -+ ic->ic_flags_ext |= IEEE80211_FEXT_ERPUPDATE; -+ } -+ } -+ - /* - * If scanning, just pass information to the scan module. - */ ---- a/net80211/ieee80211_node.c -+++ b/net80211/ieee80211_node.c -@@ -345,10 +345,16 @@ - /* Update country ie information */ - ieee80211_build_countryie(ic); - -- if (IEEE80211_IS_CHAN_HALF(chan)) -+ if (IEEE80211_IS_CHAN_HALF(chan)) { - ni->ni_rates = ic->ic_sup_half_rates; -- else if (IEEE80211_IS_CHAN_QUARTER(chan)) -+ } else if (IEEE80211_IS_CHAN_QUARTER(chan)) { - ni->ni_rates = ic->ic_sup_quarter_rates; -+ } -+ -+ if ((vap->iv_flags & IEEE80211_F_PUREG) && -+ IEEE80211_IS_CHAN_ANYG(chan)) { -+ ieee80211_setpuregbasicrates(&ni->ni_rates); -+ } - - (void) ieee80211_sta_join1(PASS_NODE(ni)); - } ---- a/net80211/ieee80211_proto.c -+++ b/net80211/ieee80211_proto.c -@@ -599,6 +599,28 @@ - { 4, { 2, 4, 11, 22 } }, /* IEEE80211_MODE_TURBO_G (mixed b/g) */ - }; - -+static const struct ieee80211_rateset basicpureg[] = { -+ { 7, {2, 4, 11, 22, 12, 24, 48 } }, -+}; -+ -+/* -+ * Mark basic rates for the 11g rate table based on the pureg setting -+ */ -+void -+ieee80211_setpuregbasicrates(struct ieee80211_rateset *rs) -+{ -+ int i, j; -+ -+ for (i = 0; i < rs->rs_nrates; i++) { -+ rs->rs_rates[i] &= IEEE80211_RATE_VAL; -+ for (j = 0; j < basicpureg[0].rs_nrates; j++) -+ if (basicpureg[0].rs_rates[j] == rs->rs_rates[i]) { -+ rs->rs_rates[i] |= IEEE80211_RATE_BASIC; -+ break; -+ } -+ } -+} -+ - /* - * Mark the basic rates for the 11g rate table based on the - * specified mode. For 11b compatibility we mark only 11b ---- a/net80211/ieee80211_var.h -+++ b/net80211/ieee80211_var.h -@@ -712,6 +712,7 @@ - void ieee80211_build_sc_ie(struct ieee80211com *); - void ieee80211_dfs_action(struct ieee80211com *); - void ieee80211_expire_channel_excl_restrictions(struct ieee80211com *); -+void ieee80211_setpuregbasicrates(struct ieee80211_rateset *rs); - - /* - * Iterate through ic_channels to enumerate all distinct ic_ieee channel numbers. diff --git a/package/madwifi/patches-r3776/302-noise_get.patch b/package/madwifi/patches-r3776/302-noise_get.patch deleted file mode 100644 index 8c69ca24f4..0000000000 --- a/package/madwifi/patches-r3776/302-noise_get.patch +++ /dev/null @@ -1,38 +0,0 @@ ---- a/ath/if_ath.c -+++ b/ath/if_ath.c -@@ -8997,6 +8997,7 @@ - ATH_LONG_CALINTERVAL_SECS : - ATH_SHORT_CALINTERVAL_SECS; - } -+ ic->ic_channoise = ath_hal_get_channel_noise(ah, &(sc->sc_curchan)); - - DPRINTF(sc, ATH_DEBUG_CALIBRATE, "Channel %u [flags=%04x] -- IQ %s.\n", - sc->sc_curchan.channel, sc->sc_curchan.channelFlags, -@@ -9052,6 +9053,7 @@ - struct ath_softc *sc = dev->priv; - - (void) ath_chan_set(sc, ic->ic_curchan); -+ ic->ic_channoise = ath_hal_get_channel_noise(sc->sc_ah, &(sc->sc_curchan)); - /* - * If we are returning to our bss channel then mark state - * so the next recv'd beacon's TSF will be used to sync the ---- a/net80211/ieee80211_wireless.c -+++ b/net80211/ieee80211_wireless.c -@@ -4396,6 +4396,7 @@ - si->isi_state = ni->ni_flags; - si->isi_authmode = ni->ni_authmode; - si->isi_rssi = ic->ic_node_getrssi(ni); -+ si->isi_noise = ic->ic_channoise; - si->isi_capinfo = ni->ni_capinfo; - si->isi_athflags = ni->ni_ath_flags; - si->isi_erp = ni->ni_erp; ---- a/net80211/ieee80211_ioctl.h -+++ b/net80211/ieee80211_ioctl.h -@@ -312,6 +312,7 @@ - u_int16_t isi_state; /* state flags */ - u_int8_t isi_authmode; /* authentication algorithm */ - u_int8_t isi_rssi; -+ int8_t isi_noise; - u_int16_t isi_capinfo; /* capabilities */ - u_int8_t isi_athflags; /* Atheros capabilities */ - u_int8_t isi_erp; /* ERP element */ diff --git a/package/madwifi/patches-r3776/303-bssid_alloc.patch b/package/madwifi/patches-r3776/303-bssid_alloc.patch deleted file mode 100644 index 43e0d6dcf5..0000000000 --- a/package/madwifi/patches-r3776/303-bssid_alloc.patch +++ /dev/null @@ -1,40 +0,0 @@ ---- a/ath/if_ath.c -+++ b/ath/if_ath.c -@@ -1347,11 +1347,12 @@ - TAILQ_FOREACH(v, &ic->ic_vaps, iv_next) - id_mask |= (1 << ATH_GET_VAP_ID(v->iv_myaddr)); - -- for (id = 1; id < ath_maxvaps; id++) { -+ for (id = 0; id < ath_maxvaps; id++) { - /* Get the first available slot. */ - if ((id_mask & (1 << id)) == 0) { - ATH_SET_VAP_BSSID(vap->iv_myaddr, id); - ATH_SET_VAP_BSSID(vap->iv_bssid, id); -+ sc->sc_bclast = id; - break; - } - } -@@ -1359,7 +1360,12 @@ - EPRINTF(sc, "Unique BSSID requested on HW that does" - "does not support the necessary features."); - } -+ } else { -+ /* share the BSSID of the last created VAP */ -+ ATH_SET_VAP_BSSID(vap->iv_myaddr, sc->sc_bclast); -+ ATH_SET_VAP_BSSID(vap->iv_bssid, sc->sc_bclast); - } -+ - avp->av_bslot = -1; - #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,15) - atomic_set(&avp->av_beacon_alloc, 0); ---- a/ath/if_athvar.h -+++ b/ath/if_athvar.h -@@ -802,7 +802,7 @@ - } sc_updateslot; /* slot time update fsm */ - int sc_slotupdate; /* slot to next advance fsm */ - struct ieee80211vap **sc_bslot; /* beacon xmit slots */ -- int sc_bnext; /* next slot for beacon xmit */ -+ int sc_bclast; /* last used slot for beacon xmit */ - - int sc_beacon_cal; /* use beacon timer for calibration */ - long unsigned int sc_calinterval_sec; /* current interval for calibration (in seconds) */ diff --git a/package/madwifi/patches-r3776/304-erp_update.patch b/package/madwifi/patches-r3776/304-erp_update.patch deleted file mode 100644 index be64b95371..0000000000 --- a/package/madwifi/patches-r3776/304-erp_update.patch +++ /dev/null @@ -1,68 +0,0 @@ ---- a/net80211/ieee80211_beacon.c -+++ b/net80211/ieee80211_beacon.c -@@ -544,10 +544,10 @@ - vap->iv_flags &= ~IEEE80211_F_XRUPDATE; - } - #endif -- if ((ic->ic_flags_ext & IEEE80211_FEXT_ERPUPDATE) && -+ if ((vap->iv_flags_ext & IEEE80211_FEXT_ERPUPDATE) && - (bo->bo_erp != NULL)) { - (void)ieee80211_add_erp(bo->bo_erp, ic); -- ic->ic_flags_ext &= ~IEEE80211_FEXT_ERPUPDATE; -+ vap->iv_flags_ext &= ~IEEE80211_FEXT_ERPUPDATE; - } - } - /* if it is a mode change beacon for dynamic turbo case */ ---- a/net80211/ieee80211_input.c -+++ b/net80211/ieee80211_input.c -@@ -3384,9 +3384,12 @@ - /* Assume no ERP IE == 11b AP */ - if ((!has_erp || (has_erp && (scan.erp & IEEE80211_ERP_NON_ERP_PRESENT))) && - !(ic->ic_flags & IEEE80211_F_USEPROT)) { -+ struct ieee80211vap *tmpvap; - - ic->ic_flags |= IEEE80211_F_USEPROT; -- ic->ic_flags_ext |= IEEE80211_FEXT_ERPUPDATE; -+ TAILQ_FOREACH(tmpvap, &ic->ic_vaps, iv_next) { -+ tmpvap->iv_flags_ext |= IEEE80211_FEXT_ERPUPDATE; -+ } - } - } - ---- a/net80211/ieee80211_node.c -+++ b/net80211/ieee80211_node.c -@@ -1741,8 +1741,12 @@ - } - - /* Update ERP element if this is first non ERP station */ -- if (ic->ic_nonerpsta == 1) -- ic->ic_flags_ext |= IEEE80211_FEXT_ERPUPDATE; -+ if (ic->ic_nonerpsta == 1) { -+ struct ieee80211vap *tmpvap; -+ TAILQ_FOREACH(tmpvap, &ic->ic_vaps, iv_next) { -+ tmpvap->iv_flags_ext |= IEEE80211_FEXT_ERPUPDATE; -+ } -+ } - } else - ni->ni_flags |= IEEE80211_NODE_ERP; - } -@@ -1945,6 +1949,8 @@ - IEEE80211_NOTE(vap, IEEE80211_MSG_ASSOC, ni, - "non-ERP station leaves, count now %d", ic->ic_nonerpsta); - if (ic->ic_nonerpsta == 0) { -+ struct ieee80211vap *tmpvap; -+ - IEEE80211_DPRINTF(vap, IEEE80211_MSG_ASSOC, - "%s: disable use of protection\n", __func__); - ic->ic_flags &= ~IEEE80211_F_USEPROT; -@@ -1956,7 +1962,9 @@ - ic->ic_flags |= IEEE80211_F_SHPREAMBLE; - ic->ic_flags &= ~IEEE80211_F_USEBARKER; - } -- ic->ic_flags_ext |= IEEE80211_FEXT_ERPUPDATE; -+ TAILQ_FOREACH(tmpvap, &ic->ic_vaps, iv_next) { -+ tmpvap->iv_flags_ext |= IEEE80211_FEXT_ERPUPDATE; -+ } - } - } - } diff --git a/package/madwifi/patches-r3776/305-bssid_mask.patch b/package/madwifi/patches-r3776/305-bssid_mask.patch deleted file mode 100644 index bc02462a33..0000000000 --- a/package/madwifi/patches-r3776/305-bssid_mask.patch +++ /dev/null @@ -1,13 +0,0 @@ ---- a/ath/if_ath.c -+++ b/ath/if_ath.c -@@ -8717,6 +8717,10 @@ - - sc->sc_rxbufcur = NULL; - -+ /* configure bssid mask */ -+ if (sc->sc_hasbmask) -+ ath_hal_setbssidmask(ah, sc->sc_bssidmask); -+ - bf = STAILQ_FIRST(&sc->sc_rxbuf); - ath_hal_putrxbuf(ah, bf->bf_daddr); - ath_hal_rxena(ah); /* enable recv descriptors */ diff --git a/package/madwifi/patches-r3776/306-queue.patch b/package/madwifi/patches-r3776/306-queue.patch deleted file mode 100644 index 3341f01b88..0000000000 --- a/package/madwifi/patches-r3776/306-queue.patch +++ /dev/null @@ -1,42 +0,0 @@ ---- a/ath/if_ath.c -+++ b/ath/if_ath.c -@@ -8448,8 +8448,6 @@ - ath_hal_intrset(sc->sc_ah, sc->sc_imask); - local_irq_restore(flags); - -- netif_wake_queue(dev); -- - if (sc->sc_softled) - ath_led_event(sc, ATH_LED_TX); - } -@@ -8505,8 +8503,6 @@ - ath_hal_intrset(sc->sc_ah, sc->sc_imask); - local_irq_restore(flags); - -- netif_wake_queue(dev); -- - if (sc->sc_softled) - ath_led_event(sc, ATH_LED_TX); - } -@@ -8537,7 +8533,9 @@ - STAILQ_FIRST(&sc->sc_cabq->axq_q) ? "not setup" : "empty"); - } - } -- netif_wake_queue(dev); -+ -+ if (ath_get_buffers_available(sc) > ATH_TXBUF_MGT_RESERVED) -+ netif_wake_queue(dev); - - if (sc->sc_softled) - ath_led_event(sc, ATH_LED_TX); ---- a/net80211/ieee80211_input.c -+++ b/net80211/ieee80211_input.c -@@ -1116,7 +1116,7 @@ - (vap->iv_flags & IEEE80211_F_NOBRIDGE) == 0) { - struct sk_buff *skb1 = NULL; - -- if (ETHER_IS_MULTICAST(eh->ether_dhost)) { -+ if (ETHER_IS_MULTICAST(eh->ether_dhost) && !netif_queue_stopped(dev)) { - /* Create a SKB for the BSS to send out. */ - skb1 = skb_copy(skb, GFP_ATOMIC); - if (skb1) diff --git a/package/madwifi/patches-r3776/307-maxrate.patch b/package/madwifi/patches-r3776/307-maxrate.patch deleted file mode 100644 index a5a1db02fb..0000000000 --- a/package/madwifi/patches-r3776/307-maxrate.patch +++ /dev/null @@ -1,96 +0,0 @@ ---- a/ath/if_ath.c -+++ b/ath/if_ath.c -@@ -1299,6 +1299,7 @@ - vap->iv_key_set = ath_key_set; - vap->iv_key_update_begin = ath_key_update_begin; - vap->iv_key_update_end = ath_key_update_end; -+ vap->iv_maxrateindex = 0; - if (sc->sc_default_ieee80211_debug) { - /* User specified defaults for new VAPs were provided, so - * use those (only). */ ---- a/ath_rate/sample/sample.c -+++ b/ath_rate/sample/sample.c -@@ -838,7 +838,12 @@ - } - sn->static_rate_ndx = -1; - -- sn->num_rates = ni->ni_rates.rs_nrates; -+ if (vap->iv_maxrateindex == 0 || ni->ni_rates.rs_nrates <= 0 -+ || vap->iv_maxrateindex > ni->ni_rates.rs_nrates) -+ sn->num_rates = ni->ni_rates.rs_nrates; -+ else -+ sn->num_rates = vap->iv_maxrateindex; -+ - for (x = 0; x < ni->ni_rates.rs_nrates; x++) { - sn->rates[x].rate = ni->ni_rates.rs_rates[x] & IEEE80211_RATE_VAL; - sn->rates[x].rix = sc->sc_rixmap[sn->rates[x].rate]; ---- a/net80211/ieee80211_var.h -+++ b/net80211/ieee80211_var.h -@@ -291,6 +291,7 @@ - struct ieee80211_spy iv_spy; /* IWSPY support */ - struct ieee80211_app_ie app_ie[IEEE80211_APPIE_NUM_OF_FRAME]; /* app-specified IEs by frame type */ - u_int32_t app_filter; /* filters which management frames are forwarded to app */ -+ int iv_maxrateindex; - }; - - /* Debug functions need the defintion of struct ieee80211vap because iv_debug ---- a/net80211/ieee80211_wireless.c -+++ b/net80211/ieee80211_wireless.c -@@ -2873,6 +2873,12 @@ - else - ic->ic_flags_ext &= ~IEEE80211_FEXT_MARKDFS; - break; -+ case IEEE80211_PARAM_MAXRATE: -+ if (value > 0) -+ vap->iv_maxrateindex = value; -+ else -+ vap->iv_maxrateindex = 0; -+ break; - #ifdef ATH_REVERSE_ENGINEERING - case IEEE80211_PARAM_DUMPREGS: - ieee80211_dump_registers(dev, info, w, extra); -@@ -3211,6 +3217,9 @@ - else - param[0] = 0; - break; -+ case IEEE80211_PARAM_MAXRATE: -+ param[0] = vap->iv_maxrateindex; -+ break; - default: - return -EOPNOTSUPP; - } -@@ -5666,6 +5675,10 @@ - IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "debug_scanbufs" }, - { IEEE80211_PARAM_LEAKTXBUFS, - IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "debug_leaktxbufs" }, -+ {IEEE80211_PARAM_MAXRATE, -+ IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "maxrate"}, -+ {IEEE80211_PARAM_MAXRATE, -+ 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "get_maxrate"}, - - #ifdef ATH_REVERSE_ENGINEERING - /* ---- a/net80211/ieee80211_ioctl.h -+++ b/net80211/ieee80211_ioctl.h -@@ -650,6 +650,7 @@ - IEEE80211_PARAM_RESETTXBUFS = 80, /* Reset transmit DMA */ - IEEE80211_PARAM_SCANBUFS = 81, /* Heap analysis for TX DMA */ - IEEE80211_PARAM_LEAKTXBUFS = 82, /* Leak tx buffers */ -+ IEEE80211_PARAM_MAXRATE = 83, /* Maximum rate (by table index) */ - }; - - #define SIOCG80211STATS (SIOCDEVPRIVATE+2) ---- a/ath_rate/minstrel/minstrel.c -+++ b/ath_rate/minstrel/minstrel.c -@@ -644,6 +644,11 @@ - return; - } - sn->static_rate_ndx = -1; -+ if (vap->iv_maxrateindex == 0 || ni->ni_rates.rs_nrates <= 0 -+ || vap->iv_maxrateindex > ni->ni_rates.rs_nrates) -+ sn->num_rates = ni->ni_rates.rs_nrates; -+ else -+ sn->num_rates = vap->iv_maxrateindex; - - sn->num_rates = ni->ni_rates.rs_nrates; - for (x = 0; x < ni->ni_rates.rs_nrates; x++) { diff --git a/package/madwifi/patches-r3776/308-minrate.patch b/package/madwifi/patches-r3776/308-minrate.patch deleted file mode 100644 index 8e7b6066a8..0000000000 --- a/package/madwifi/patches-r3776/308-minrate.patch +++ /dev/null @@ -1,112 +0,0 @@ ---- a/ath/if_ath.c -+++ b/ath/if_ath.c -@@ -1300,6 +1300,7 @@ - vap->iv_key_update_begin = ath_key_update_begin; - vap->iv_key_update_end = ath_key_update_end; - vap->iv_maxrateindex = 0; -+ vap->iv_minrateindex = 0; - if (sc->sc_default_ieee80211_debug) { - /* User specified defaults for new VAPs were provided, so - * use those (only). */ ---- a/ath_rate/minstrel/minstrel.c -+++ b/ath_rate/minstrel/minstrel.c -@@ -652,6 +652,8 @@ - - sn->num_rates = ni->ni_rates.rs_nrates; - for (x = 0; x < ni->ni_rates.rs_nrates; x++) { -+ int idx = x; -+ - sn->rs_rateattempts [x] = 0; - sn->rs_thisprob [x] = 0; - sn->rs_ratesuccess [x] = 0; -@@ -662,8 +664,12 @@ - sn->rs_att_hist [x] = 0; - sn->rs_this_tp [x] = 0; - -- sn->rates[x].rate = ni->ni_rates.rs_rates[x] & IEEE80211_RATE_VAL; -- sn->rates[x].rix = sc->sc_rixmap[sn->rates[x].rate]; -+ if (vap->iv_minrateindex && (vap->iv_minrateindex < -+ ni->ni_rates.rs_nrates)) -+ idx = vap->iv_minrateindex; -+ -+ sn->rates[x].rate = ni->ni_rates.rs_rates[idx] & IEEE80211_RATE_VAL; -+ sn->rates[x].rix = sc->sc_rixmap[sn->rates[idx].rate]; - if (sn->rates[x].rix == 0xff) { - DPRINTF(sc, "%s: %s ignore bogus rix at %d\n", - dev_info, __func__, x); ---- a/ath_rate/sample/sample.c -+++ b/ath_rate/sample/sample.c -@@ -845,8 +845,15 @@ - sn->num_rates = vap->iv_maxrateindex; - - for (x = 0; x < ni->ni_rates.rs_nrates; x++) { -- sn->rates[x].rate = ni->ni_rates.rs_rates[x] & IEEE80211_RATE_VAL; -- sn->rates[x].rix = sc->sc_rixmap[sn->rates[x].rate]; -+ int idx = x; -+ -+ if (vap->iv_minrateindex && vap->iv_minrateindex < -+ ni->ni_rates.rs_nrates) -+ idx = vap->iv_minrateindex; -+ -+ sn->rates[x].rate = ni->ni_rates.rs_rates[idx] & IEEE80211_RATE_VAL; -+ sn->rates[x].rix = sc->sc_rixmap[sn->rates[idx].rate]; -+ - if (sn->rates[x].rix == 0xff) { - DPRINTF(sc, ATH_DEBUG_RATE, "%s: %s ignore bogus rix at %u\n", - dev_info, __func__, x); ---- a/net80211/ieee80211_ioctl.h -+++ b/net80211/ieee80211_ioctl.h -@@ -651,6 +651,7 @@ - IEEE80211_PARAM_SCANBUFS = 81, /* Heap analysis for TX DMA */ - IEEE80211_PARAM_LEAKTXBUFS = 82, /* Leak tx buffers */ - IEEE80211_PARAM_MAXRATE = 83, /* Maximum rate (by table index) */ -+ IEEE80211_PARAM_MINRATE = 84, /* Minimum rate (by table index) */ - }; - - #define SIOCG80211STATS (SIOCDEVPRIVATE+2) ---- a/net80211/ieee80211_var.h -+++ b/net80211/ieee80211_var.h -@@ -292,6 +292,7 @@ - struct ieee80211_app_ie app_ie[IEEE80211_APPIE_NUM_OF_FRAME]; /* app-specified IEs by frame type */ - u_int32_t app_filter; /* filters which management frames are forwarded to app */ - int iv_maxrateindex; -+ int iv_minrateindex; - }; - - /* Debug functions need the defintion of struct ieee80211vap because iv_debug ---- a/net80211/ieee80211_wireless.c -+++ b/net80211/ieee80211_wireless.c -@@ -2879,6 +2879,12 @@ - else - vap->iv_maxrateindex = 0; - break; -+ case IEEE80211_PARAM_MINRATE: -+ if (value > 0) -+ vap->iv_minrateindex = value; -+ else -+ vap->iv_minrateindex = 0; -+ break; - #ifdef ATH_REVERSE_ENGINEERING - case IEEE80211_PARAM_DUMPREGS: - ieee80211_dump_registers(dev, info, w, extra); -@@ -3220,6 +3226,9 @@ - case IEEE80211_PARAM_MAXRATE: - param[0] = vap->iv_maxrateindex; - break; -+ case IEEE80211_PARAM_MINRATE: -+ param[0] = vap->iv_minrateindex; -+ break; - default: - return -EOPNOTSUPP; - } -@@ -5679,6 +5688,10 @@ - IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "maxrate"}, - {IEEE80211_PARAM_MAXRATE, - 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "get_maxrate"}, -+ {IEEE80211_PARAM_MINRATE, -+ IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "minrate"}, -+ {IEEE80211_PARAM_MINRATE, -+ 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "get_minrate"}, - - #ifdef ATH_REVERSE_ENGINEERING - /* diff --git a/package/madwifi/patches-r3776/309-performance.patch b/package/madwifi/patches-r3776/309-performance.patch deleted file mode 100644 index ec22085258..0000000000 --- a/package/madwifi/patches-r3776/309-performance.patch +++ /dev/null @@ -1,215 +0,0 @@ ---- a/ath/if_ath.c -+++ b/ath/if_ath.c -@@ -3334,7 +3334,6 @@ - struct ath_softc *sc = dev->priv; - struct ieee80211_node *ni = NULL; - struct ath_buf *bf = NULL; -- struct ether_header *eh; - ath_bufhead bf_head; - struct ath_buf *tbf; - struct sk_buff *tskb; -@@ -3349,6 +3348,7 @@ - */ - int requeue = 0; - #ifdef ATH_SUPERG_FF -+ struct ether_header *eh; - unsigned int pktlen; - struct ieee80211com *ic = &sc->sc_ic; - struct ath_txq *txq = NULL; ---- a/net80211/ieee80211_output.c -+++ b/net80211/ieee80211_output.c -@@ -280,7 +280,7 @@ - * normal vap. */ - if (vap->iv_xrvap && (ni == vap->iv_bss) && - vap->iv_xrvap->iv_sta_assoc) { -- struct sk_buff *skb1 = skb_copy(skb, GFP_ATOMIC); -+ struct sk_buff *skb1 = skb_clone(skb, GFP_ATOMIC); - if (skb1) { - memset(SKB_CB(skb1), 0, sizeof(struct ieee80211_cb)); - #ifdef IEEE80211_DEBUG_REFCNT -@@ -561,7 +561,7 @@ - struct ieee80211_key *key, struct sk_buff *skb, int ismulticast) - { - /* XXX pre-calculate per node? */ -- int need_headroom = LLC_SNAPFRAMELEN + hdrsize + IEEE80211_ADDR_LEN; -+ int need_headroom = LLC_SNAPFRAMELEN + hdrsize; - int need_tailroom = 0; - #ifdef ATH_SUPERG_FF - int isff = ATH_FF_MAGIC_PRESENT(skb); -@@ -603,109 +603,56 @@ - need_tailroom += cip->ic_miclen; - } - -- if (skb_shared(skb)) { -- /* Take our own reference to the node in the clone */ -- ieee80211_ref_node(SKB_NI(skb)); -- /* Unshare the node, decrementing users in the old skb */ -- skb = skb_unshare(skb, GFP_ATOMIC); -+ need_headroom -= skb_headroom(skb); -+ if (isff) -+ need_tailroom -= skb_tailroom(skb2); -+ else -+ need_tailroom -= skb_tailroom(skb); -+ -+ if (need_headroom < 0) -+ need_headroom = 0; -+ if (need_tailroom < 0) -+ need_tailroom = 0; -+ -+ if (skb_cloned(skb) || (need_headroom > 0) || -+ (!isff && (need_tailroom > 0))) { -+ -+ if (pskb_expand_head(skb, need_headroom, need_tailroom, GFP_ATOMIC)) { -+ IEEE80211_DPRINTF(vap, IEEE80211_MSG_OUTPUT, -+ "%s: cannot expand storage (tail)\n", __func__); -+ goto error; -+ } - } - - #ifdef ATH_SUPERG_FF - if (isff) { -- if (skb == NULL) { -- IEEE80211_DPRINTF(vap, IEEE80211_MSG_OUTPUT, -- "%s: cannot unshare for encapsulation\n", -- __func__); -- vap->iv_stats.is_tx_nobuf++; -- ieee80211_dev_kfree_skb(&skb2); -- -- return NULL; -- } -+ inter_headroom -= skb_headroom(skb2); -+ if (inter_headroom < 0) -+ inter_headroom = 0; -+ if ((skb_cloned(skb2) || -+ (inter_headroom > 0) || (need_tailroom > 0))) { - -- /* first skb header */ -- if (skb_headroom(skb) < need_headroom) { -- struct sk_buff *tmp = skb; -- skb = skb_realloc_headroom(skb, need_headroom); -- if (skb == NULL) { -+ if (pskb_expand_head(skb2, inter_headroom, -+ need_tailroom, GFP_ATOMIC)) { - IEEE80211_DPRINTF(vap, IEEE80211_MSG_OUTPUT, -- "%s: cannot expand storage (head1)\n", -- __func__); -- vap->iv_stats.is_tx_nobuf++; -- ieee80211_dev_kfree_skb(&skb2); -- return NULL; -- } else -- ieee80211_skb_copy_noderef(tmp, skb); -- ieee80211_dev_kfree_skb(&tmp); -- /* NB: cb[] area was copied, but not next ptr. must do that -- * prior to return on success. */ -- } -- -- /* second skb with header and tail adjustments possible */ -- if (skb_tailroom(skb2) < need_tailroom) { -- int n = 0; -- if (inter_headroom > skb_headroom(skb2)) -- n = inter_headroom - skb_headroom(skb2); -- if (pskb_expand_head(skb2, n, -- need_tailroom - skb_tailroom(skb2), GFP_ATOMIC)) { -- ieee80211_dev_kfree_skb(&skb2); -- IEEE80211_DPRINTF(vap, IEEE80211_MSG_OUTPUT, -- "%s: cannot expand storage (tail2)\n", -- __func__); -- vap->iv_stats.is_tx_nobuf++; -- /* this shouldn't happen, but don't send first ff either */ -- ieee80211_dev_kfree_skb(&skb); -+ "%s: cannot expand storage (tail)\n", __func__); -+ goto error; - } -- } else if (skb_headroom(skb2) < inter_headroom) { -- struct sk_buff *tmp = skb2; -- -- skb2 = skb_realloc_headroom(skb2, inter_headroom); -- if (skb2 == NULL) { -- IEEE80211_DPRINTF(vap, IEEE80211_MSG_OUTPUT, -- "%s: cannot expand storage (head2)\n", -- __func__); -- vap->iv_stats.is_tx_nobuf++; -- /* this shouldn't happen, but don't send first ff either */ -- ieee80211_dev_kfree_skb(&skb); -- skb = NULL; -- } else -- ieee80211_skb_copy_noderef(tmp, skb); -- ieee80211_dev_kfree_skb(&tmp); - } -- if (skb) { -- skb->next = skb2; -- } -- return skb; -+ skb->next = skb2; - } - #endif /* ATH_SUPERG_FF */ -- if (skb == NULL) { -- IEEE80211_DPRINTF(vap, IEEE80211_MSG_OUTPUT, -- "%s: cannot unshare for encapsulation\n", __func__); -- vap->iv_stats.is_tx_nobuf++; -- } else if (skb_tailroom(skb) < need_tailroom) { -- int n = 0; -- if (need_headroom > skb_headroom(skb)) -- n = need_headroom - skb_headroom(skb); -- if (pskb_expand_head(skb, n, need_tailroom - -- skb_tailroom(skb), GFP_ATOMIC)) { -- IEEE80211_DPRINTF(vap, IEEE80211_MSG_OUTPUT, -- "%s: cannot expand storage (tail)\n", __func__); -- vap->iv_stats.is_tx_nobuf++; -- ieee80211_dev_kfree_skb(&skb); -- } -- } else if (skb_headroom(skb) < need_headroom) { -- struct sk_buff *tmp = skb; -- skb = skb_realloc_headroom(skb, need_headroom); -- /* Increment reference count after copy */ -- if (skb == NULL) { -- IEEE80211_DPRINTF(vap, IEEE80211_MSG_OUTPUT, -- "%s: cannot expand storage (head)\n", __func__); -- vap->iv_stats.is_tx_nobuf++; -- } else -- ieee80211_skb_copy_noderef(tmp, skb); -- ieee80211_dev_kfree_skb(&tmp); -- } - - return skb; -+ -+error: -+ vap->iv_stats.is_tx_nobuf++; -+ ieee80211_dev_kfree_skb(&skb); -+#ifdef ATH_SUPERG_FF -+ if (skb2) -+ ieee80211_dev_kfree_skb(&skb2); -+#endif -+ return NULL; - } - - #define KEY_UNDEFINED(k) ((k).wk_cipher == &ieee80211_cipher_none) ---- a/net80211/ieee80211_input.c -+++ b/net80211/ieee80211_input.c -@@ -713,7 +713,7 @@ - /* ether_type must be length as FF frames are always LLC/SNAP encap'd */ - frame_len = ntohs(eh_tmp->ether_type); - -- skb1 = skb_copy(skb, GFP_ATOMIC); -+ skb1 = skb_clone(skb, GFP_ATOMIC); - if (skb1 == NULL) - goto err; - ieee80211_skb_copy_noderef(skb, skb1); -@@ -1118,7 +1118,7 @@ - - if (ETHER_IS_MULTICAST(eh->ether_dhost) && !netif_queue_stopped(dev)) { - /* Create a SKB for the BSS to send out. */ -- skb1 = skb_copy(skb, GFP_ATOMIC); -+ skb1 = skb_clone(skb, GFP_ATOMIC); - if (skb1) - SKB_NI(skb1) = ieee80211_ref_node(vap->iv_bss); - } -@@ -2265,7 +2265,7 @@ - if (filter_type && ((vap->app_filter & filter_type) == filter_type)) { - struct sk_buff *skb1; - -- skb1 = skb_copy(skb, GFP_ATOMIC); -+ skb1 = skb_clone(skb, GFP_ATOMIC); - if (skb1 == NULL) - return; - /* We duplicate the reference after skb_copy */ diff --git a/package/madwifi/patches-r3776/310-minstrel_sampling.patch b/package/madwifi/patches-r3776/310-minstrel_sampling.patch deleted file mode 100644 index b7f55d5005..0000000000 --- a/package/madwifi/patches-r3776/310-minstrel_sampling.patch +++ /dev/null @@ -1,84 +0,0 @@ ---- a/ath/if_ath.c -+++ b/ath/if_ath.c -@@ -8110,6 +8110,7 @@ - ath_hal_setupxtxdesc(sc->sc_ah, ds, mrr.rate1, mrr.retries1, - mrr.rate2, mrr.retries2, - mrr.rate3, mrr.retries3); -+ bf->rcflags = mrr.privflags; - } - - #ifndef ATH_SUPERG_FF ---- a/ath/if_athvar.h -+++ b/ath/if_athvar.h -@@ -454,6 +454,7 @@ - u_int16_t bf_flags; /* tx descriptor flags */ - u_int64_t bf_tsf; - int16_t bf_channoise; -+ unsigned int rcflags; - #ifdef ATH_SUPERG_FF - /* XXX: combine this with bf_skbaddr if it ever changes to accommodate - * multiple segments. ---- a/ath_rate/minstrel/minstrel.c -+++ b/ath_rate/minstrel/minstrel.c -@@ -341,18 +341,21 @@ - if (sn->static_rate_ndx >= 0) { - ndx = sn->static_rate_ndx; - } else { -+ int delta; -+ - sn->packet_count++; - sn->random_n = (sn->a * sn->random_n) + sn->b; - offset = sn->random_n & 0xf; - -- if ((((100 * sn->sample_count) / sn->packet_count) < -- ath_lookaround_rate) && -- (offset < 2)) { -+ delta = (sn->packet_count * ath_lookaround_rate / 100) - sn->sample_count; -+ if ((delta > 0) && (offset < 2)) { - sn->sample_count++; - sn->is_sampling = 1; - if (sn->packet_count >= 10000) { - sn->sample_count = 0; - sn->packet_count = 0; -+ } else if (delta > sn->num_rates * 2) { -+ sn->sample_count += ((delta - sn->num_rates * 2) * ath_lookaround_rate) / 100; - } - - /* Don't look for slowest rate (i.e. slowest -@@ -420,11 +423,14 @@ - if (sn->num_rates <= 0) - return; - -+ mrr->privflags = sn->is_sampling; - if (sn->is_sampling) { - sn->is_sampling = 0; -- if (sn->rs_sample_rate_slower) -+ if (sn->rs_sample_rate_slower) { - rc1 = sn->rs_sample_rate; -- else -+ if (sn->sample_count > 0) -+ sn->sample_count--; -+ } else - rc1 = sn->max_tp_rate; - } else { - rc1 = sn->max_tp_rate2; -@@ -552,6 +558,9 @@ - if (tries <= tries1) - return; - -+ if (bf->rcflags) -+ sn->sample_count++; -+ - if (tries2 < 0) - return; - tries = tries - tries1; ---- a/net80211/ieee80211_rate.h -+++ b/net80211/ieee80211_rate.h -@@ -87,6 +87,7 @@ - int retries2; - int rate3; - int retries3; -+ int privflags; - }; - - struct ieee80211_rate_ops { diff --git a/package/madwifi/patches-r3776/311-protmode_trigger.patch b/package/madwifi/patches-r3776/311-protmode_trigger.patch deleted file mode 100644 index 2f462b9a6c..0000000000 --- a/package/madwifi/patches-r3776/311-protmode_trigger.patch +++ /dev/null @@ -1,135 +0,0 @@ ---- a/net80211/ieee80211.c -+++ b/net80211/ieee80211.c -@@ -347,7 +347,9 @@ - IEEE80211_MS_TO_TU(IEEE80211_BMISSTHRESH_DEFAULT_MS), - ic->ic_lintval), ic->ic_lintval); - } -- -+ ic->ic_protmode_timeout = IEEE80211_PROTMODE_TIMEOUT; -+ ic->ic_protmode_rssi = IEEE80211_PROTMODE_RSSITHR; -+ - IEEE80211_LOCK_INIT(ic, "ieee80211com"); - IEEE80211_VAPS_LOCK_INIT(ic, "ieee80211com_vaps"); - TAILQ_INIT(&ic->ic_vaps); ---- a/net80211/ieee80211_input.c -+++ b/net80211/ieee80211_input.c -@@ -3382,14 +3382,18 @@ - IEEE80211_IS_CHAN_ANYG(ic->ic_curchan)) { - - /* Assume no ERP IE == 11b AP */ -- if ((!has_erp || (has_erp && (scan.erp & IEEE80211_ERP_NON_ERP_PRESENT))) && -- !(ic->ic_flags & IEEE80211_F_USEPROT)) { -+ if ((!has_erp || (has_erp && -+ (scan.erp & IEEE80211_ERP_NON_ERP_PRESENT))) && -+ (rssi > ic->ic_protmode_rssi)) { - struct ieee80211vap *tmpvap; - -- ic->ic_flags |= IEEE80211_F_USEPROT; -- TAILQ_FOREACH(tmpvap, &ic->ic_vaps, iv_next) { -- tmpvap->iv_flags_ext |= IEEE80211_FEXT_ERPUPDATE; -+ if (!(ic->ic_flags & IEEE80211_F_USEPROT)) { -+ ic->ic_flags |= IEEE80211_F_USEPROT; -+ TAILQ_FOREACH(tmpvap, &ic->ic_vaps, iv_next) { -+ tmpvap->iv_flags_ext |= IEEE80211_FEXT_ERPUPDATE; -+ } - } -+ ic->ic_protmode_lasttrig = jiffies; - } - } - ---- a/net80211/ieee80211_ioctl.h -+++ b/net80211/ieee80211_ioctl.h -@@ -652,6 +652,8 @@ - IEEE80211_PARAM_LEAKTXBUFS = 82, /* Leak tx buffers */ - IEEE80211_PARAM_MAXRATE = 83, /* Maximum rate (by table index) */ - IEEE80211_PARAM_MINRATE = 84, /* Minimum rate (by table index) */ -+ IEEE80211_PARAM_PROTMODE_RSSI = 85, /* RSSI Threshold for enabling protection mode */ -+ IEEE80211_PARAM_PROTMODE_TIMEOUT = 86, /* Timeout for expiring protection mode */ - }; - - #define SIOCG80211STATS (SIOCDEVPRIVATE+2) ---- a/net80211/ieee80211_var.h -+++ b/net80211/ieee80211_var.h -@@ -138,6 +138,9 @@ - - #define IEEE80211_APPIE_MAX 1024 - -+#define IEEE80211_PROTMODE_RSSITHR 15 /* default rssi threshold for protection mode trigger */ -+#define IEEE80211_PROTMODE_TIMEOUT 30 /* timeout for keeping protection mode alive */ -+ - #define IEEE80211_PWRCONSTRAINT_VAL(ic) \ - (((ic)->ic_bsschan->ic_maxregpower > (ic)->ic_curchanmaxpwr) ? \ - (ic)->ic_bsschan->ic_maxregpower - (ic)->ic_curchanmaxpwr : 0) -@@ -335,6 +338,9 @@ - u_int16_t ic_newtxpowlimit; /* tx power limit to change to (in 0.5 dBm) */ - u_int16_t ic_uapsdmaxtriggers; /* max triggers that could arrive */ - u_int8_t ic_coverageclass; /* coverage class */ -+ u_int8_t ic_protmode_rssi; /* rssi threshold for protection mode */ -+ u_int64_t ic_protmode_lasttrig; /* last trigger for protection mode */ -+ u_int16_t ic_protmode_timeout; /* protection mode timeout */ - - /* Channel state: - * ---- a/net80211/ieee80211_wireless.c -+++ b/net80211/ieee80211_wireless.c -@@ -2336,6 +2336,12 @@ - case IEEE80211_PARAM_RSSI_EWMA: - ic->ic_rssi_ewma = value; - break; -+ case IEEE80211_PARAM_PROTMODE_TIMEOUT: -+ ic->ic_protmode_timeout = value; -+ break; -+ case IEEE80211_PARAM_PROTMODE_RSSI: -+ ic->ic_protmode_rssi = value; -+ break; - case IEEE80211_PARAM_MCASTCIPHER: - if ((vap->iv_caps & cipher2cap(value)) == 0 && - !ieee80211_crypto_available(vap, value)) -@@ -2992,6 +2998,12 @@ - case IEEE80211_PARAM_RSSI_EWMA: - param[0] = ic->ic_rssi_ewma; - break; -+ case IEEE80211_PARAM_PROTMODE_TIMEOUT: -+ param[0] = ic->ic_protmode_timeout; -+ break; -+ case IEEE80211_PARAM_PROTMODE_RSSI: -+ param[0] = ic->ic_protmode_rssi; -+ break; - case IEEE80211_PARAM_MCASTCIPHER: - param[0] = rsn->rsn_mcastcipher; - break; -@@ -5384,6 +5396,14 @@ - IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "protmode" }, - { IEEE80211_PARAM_PROTMODE, - 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "get_protmode" }, -+ { IEEE80211_PARAM_PROTMODE_RSSI, -+ IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "protrssi" }, -+ { IEEE80211_PARAM_PROTMODE_RSSI, -+ 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "get_protrssi" }, -+ { IEEE80211_PARAM_PROTMODE_TIMEOUT, -+ IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "prottime" }, -+ { IEEE80211_PARAM_PROTMODE_TIMEOUT, -+ 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "get_prottime" }, - { IEEE80211_PARAM_MCASTCIPHER, - IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "mcastcipher" }, - { IEEE80211_PARAM_MCASTCIPHER, ---- a/net80211/ieee80211_node.c -+++ b/net80211/ieee80211_node.c -@@ -1591,6 +1591,17 @@ - - ieee80211_scan_timeout(ic); - ieee80211_timeout_stations(&ic->ic_sta); -+ if ((ic->ic_flags & IEEE80211_F_USEPROT) && -+ (ic->ic_protmode_lasttrig + ic->ic_protmode_timeout * HZ < -+ jiffies)) { -+ struct ieee80211vap *tmpvap; -+ -+ /* expire protection mode */ -+ ic->ic_flags &= ~IEEE80211_F_USEPROT; -+ TAILQ_FOREACH(tmpvap, &ic->ic_vaps, iv_next) { -+ tmpvap->iv_flags_ext |= IEEE80211_FEXT_ERPUPDATE; -+ } -+ } - - mod_timer(&ic->ic_inact, jiffies + IEEE80211_INACT_WAIT * HZ); - } diff --git a/package/madwifi/patches-r3776/312-ack_cts_rate.patch b/package/madwifi/patches-r3776/312-ack_cts_rate.patch deleted file mode 100644 index 42bb4c1711..0000000000 --- a/package/madwifi/patches-r3776/312-ack_cts_rate.patch +++ /dev/null @@ -1,40 +0,0 @@ ---- a/ath/if_ath.c -+++ b/ath/if_ath.c -@@ -10890,8 +10890,13 @@ - break; - #endif - case ATH_ACKRATE: -- sc->sc_ackrate = val; -- ath_set_ack_bitrate(sc, sc->sc_ackrate); -+ if (val == -1) -+ sc->sc_ackrate_override = 0; -+ else { -+ sc->sc_ackrate_override = 1; -+ sc->sc_ackrate = val; -+ ath_set_ack_bitrate(sc, sc->sc_ackrate); -+ } - break; - case ATH_RP: - ath_rp_record(sc, ---- a/ath/if_athvar.h -+++ b/ath/if_athvar.h -@@ -698,6 +698,7 @@ - unsigned int sc_hasclrkey:1; /* CLR key supported */ - unsigned int sc_stagbeacons:1; /* use staggered beacons */ - unsigned int sc_dfswait:1; /* waiting on channel for radar detect */ -+ unsigned int sc_ackrate_override:1; /* override ack rate */ - unsigned int sc_ackrate:1; /* send acks at high bitrate */ - unsigned int sc_dfs_cac:1; /* waiting on channel for radar detect */ - unsigned int sc_hasintmit:1; /* Interference mitigation */ ---- a/ath/if_ath_hal_extensions.c -+++ b/ath/if_ath_hal_extensions.c -@@ -129,6 +129,9 @@ - int - ath_set_ack_bitrate(struct ath_softc *sc, int high) - { -+ if (!sc->sc_ackrate_override) -+ return 0; -+ - if (ar_device(sc->devid) == 5212 || ar_device(sc->devid) == 5213) { - /* set ack to be sent at low bit-rate */ - u_int32_t v = AR5K_STA_ID1_BASE_RATE_11B | AR5K_STA_ID1_ACKCTS_6MB; diff --git a/package/madwifi/patches-r3776/313-reset_channelchange.patch b/package/madwifi/patches-r3776/313-reset_channelchange.patch deleted file mode 100644 index 42d18ece07..0000000000 --- a/package/madwifi/patches-r3776/313-reset_channelchange.patch +++ /dev/null @@ -1,18 +0,0 @@ ---- a/ath/if_ath.c -+++ b/ath/if_ath.c -@@ -8866,14 +8866,7 @@ - hchan.channel, - jiffies); - -- /* ath_hal_reset with chanchange = AH_TRUE doesn't seem to -- * completely reset the state of the card. According to -- * reports from ticket #1106, kismet and aircrack people they -- * needed to do the reset with chanchange = AH_FALSE in order -- * to receive traffic when peforming high velocity channel -- * changes. */ -- if (!ath_hw_reset(sc, sc->sc_opmode, &hchan, AH_TRUE, &status) || -- !ath_hw_reset(sc, sc->sc_opmode, &hchan, AH_FALSE, &status)) { -+ if (!ath_hw_reset(sc, sc->sc_opmode, &hchan, AH_TRUE, &status)) { - EPRINTF(sc, "Unable to reset channel %u (%u MHz) " - "flags 0x%x '%s' (HAL status %u)\n", - ieee80211_chan2ieee(ic, chan), chan->ic_freq, diff --git a/package/madwifi/patches-r3776/314-wisoc_softled.patch b/package/madwifi/patches-r3776/314-wisoc_softled.patch deleted file mode 100644 index ca5ffdce4b..0000000000 --- a/package/madwifi/patches-r3776/314-wisoc_softled.patch +++ /dev/null @@ -1,11 +0,0 @@ ---- a/ath/if_ath_ahb.c -+++ b/ath/if_ath_ahb.c -@@ -245,6 +245,8 @@ - num_activesc++; - /* Ready to process interrupts */ - -+ sc->aps_sc.sc_softled = 1; /* SoftLED over GPIO */ -+ sc->aps_sc.sc_ledpin = config->board->sysLedGpio; - sc->aps_sc.sc_invalid = 0; - return 0; - diff --git a/package/madwifi/patches-r3776/315-scanlist.patch b/package/madwifi/patches-r3776/315-scanlist.patch deleted file mode 100644 index 0ae0ed010a..0000000000 --- a/package/madwifi/patches-r3776/315-scanlist.patch +++ /dev/null @@ -1,876 +0,0 @@ ---- a/net80211/ieee80211_scan_sta.c -+++ b/net80211/ieee80211_scan_sta.c -@@ -318,147 +318,6 @@ - #undef ISPROBE - } - --static struct ieee80211_channel * --find11gchannel(struct ieee80211com *ic, int i, int freq) --{ -- struct ieee80211_channel *c; -- int j; -- -- /* -- * The normal ordering in the channel list is b channel -- * immediately followed by g so optimize the search for -- * this. We'll still do a full search just in case. -- */ -- for (j = i+1; j < ic->ic_nchans; j++) { -- c = &ic->ic_channels[j]; -- if (c->ic_freq == freq && IEEE80211_IS_CHAN_ANYG(c)) -- return c; -- } -- for (j = 0; j < i; j++) { -- c = &ic->ic_channels[j]; -- if (c->ic_freq == freq && IEEE80211_IS_CHAN_ANYG(c)) -- return c; -- } -- return NULL; --} --static const u_int chanflags[] = { -- IEEE80211_CHAN_B, /* IEEE80211_MODE_AUTO */ -- IEEE80211_CHAN_A, /* IEEE80211_MODE_11A */ -- IEEE80211_CHAN_B, /* IEEE80211_MODE_11B */ -- IEEE80211_CHAN_PUREG, /* IEEE80211_MODE_11G */ -- IEEE80211_CHAN_FHSS, /* IEEE80211_MODE_FH */ -- IEEE80211_CHAN_A, /* IEEE80211_MODE_TURBO_A */ /* for turbo mode look for AP in normal channel */ -- IEEE80211_CHAN_PUREG, /* IEEE80211_MODE_TURBO_G */ -- IEEE80211_CHAN_ST, /* IEEE80211_MODE_TURBO_STATIC_A */ --}; -- --static void --add_channels(struct ieee80211com *ic, -- struct ieee80211_scan_state *ss, -- enum ieee80211_phymode mode, const u_int16_t freq[], int nfreq) --{ -- struct ieee80211_channel *c, *cg; -- u_int modeflags; -- int i; -- -- KASSERT(mode < ARRAY_SIZE(chanflags), ("Unexpected mode %u", mode)); -- modeflags = chanflags[mode]; -- for (i = 0; i < nfreq; i++) { -- c = ieee80211_find_channel(ic, freq[i], modeflags); -- if (c == NULL || isclr(ic->ic_chan_active, c->ic_ieee)) -- continue; -- if (mode == IEEE80211_MODE_AUTO) { -- /* -- * XXX special-case 11b/g channels so we select -- * the g channel if both are present. -- */ -- if (IEEE80211_IS_CHAN_B(c) && -- (cg = find11gchannel(ic, i, c->ic_freq)) != NULL) -- c = cg; -- } -- if (ss->ss_last >= IEEE80211_SCAN_MAX) -- break; -- ss->ss_chans[ss->ss_last++] = c; -- } --} -- --static const u_int16_t rcl1[] = /* 8 FCC channel: 52, 56, 60, 64, 36, 40, 44, 48 */ --{ 5260, 5280, 5300, 5320, 5180, 5200, 5220, 5240 }; --static const u_int16_t rcl2[] = /* 4 MKK channels: 34, 38, 42, 46 */ --{ 5170, 5190, 5210, 5230 }; --static const u_int16_t rcl3[] = /* 2.4Ghz ch: 1,6,11,7,13 */ --{ 2412, 2437, 2462, 2442, 2472 }; --static const u_int16_t rcl4[] = /* 5 FCC channel: 149, 153, 161, 165 */ --{ 5745, 5765, 5785, 5805, 5825 }; --static const u_int16_t rcl7[] = /* 11 ETSI channel: 100,104,108,112,116,120,124,128,132,136,140 */ --{ 5500, 5520, 5540, 5560, 5580, 5600, 5620, 5640, 5660, 5680, 5700 }; --static const u_int16_t rcl8[] = /* 2.4Ghz ch: 2,3,4,5,8,9,10,12 */ --{ 2417, 2422, 2427, 2432, 2447, 2452, 2457, 2467 }; --static const u_int16_t rcl9[] = /* 2.4Ghz ch: 14 */ --{ 2484 }; --static const u_int16_t rcl10[] = /* Added Korean channels 2312-2372 */ --{ 2312, 2317, 2322, 2327, 2332, 2337, 2342, 2347, 2352, 2357, 2362, 2367, 2372 }; --static const u_int16_t rcl11[] = /* Added Japan channels in 4.9/5.0 spectrum */ --{ 5040, 5060, 5080, 4920, 4940, 4960, 4980 }; --#ifdef ATH_TURBO_SCAN --static const u_int16_t rcl5[] = /* 3 static turbo channels */ --{ 5210, 5250, 5290 }; --static const u_int16_t rcl6[] = /* 2 static turbo channels */ --{ 5760, 5800 }; --static const u_int16_t rcl6x[] = /* 4 FCC3 turbo channels */ --{ 5540, 5580, 5620, 5660 }; --static const u_int16_t rcl12[] = /* 2.4Ghz Turbo channel 6 */ --{ 2437 }; --static const u_int16_t rcl13[] = /* dynamic Turbo channels */ --{ 5200, 5240, 5280, 5765, 5805 }; --#endif /* ATH_TURBO_SCAN */ -- --struct scanlist { -- u_int16_t mode; -- u_int16_t count; -- const u_int16_t *list; --}; -- --#define IEEE80211_MODE_TURBO_STATIC_A IEEE80211_MODE_MAX --#define X(a) .count = sizeof(a)/sizeof(a[0]), .list = a -- --static const struct scanlist staScanTable[] = { -- { IEEE80211_MODE_11B, X(rcl3) }, -- { IEEE80211_MODE_11A, X(rcl1) }, -- { IEEE80211_MODE_11A, X(rcl2) }, -- { IEEE80211_MODE_11B, X(rcl8) }, -- { IEEE80211_MODE_11B, X(rcl9) }, -- { IEEE80211_MODE_11A, X(rcl4) }, --#ifdef ATH_TURBO_SCAN -- { IEEE80211_MODE_TURBO_STATIC_A, X(rcl5) }, -- { IEEE80211_MODE_TURBO_STATIC_A, X(rcl6) }, -- { IEEE80211_MODE_TURBO_A, X(rcl6x) }, -- { IEEE80211_MODE_TURBO_A, X(rcl13) }, --#endif /* ATH_TURBO_SCAN */ -- { IEEE80211_MODE_11A, X(rcl7) }, -- { IEEE80211_MODE_11B, X(rcl10) }, -- { IEEE80211_MODE_11A, X(rcl11) }, --#ifdef ATH_TURBO_SCAN -- { IEEE80211_MODE_TURBO_G, X(rcl12) }, --#endif /* ATH_TURBO_SCAN */ -- { .list = NULL } --}; -- --#undef X -- --static int --checktable(const struct scanlist *scan, const struct ieee80211_channel *c) --{ -- int i; -- -- for (; scan->list != NULL; scan++) { -- for (i = 0; i < scan->count; i++) -- if (scan->list[i] == c->ic_freq) -- return 1; -- } -- return 0; --} -- - /* - * Start a station-mode scan by populating the channel list. - */ -@@ -467,81 +326,11 @@ - { - struct ieee80211com *ic = vap->iv_ic; - struct sta_table *st = ss->ss_priv; -- const struct scanlist *scan; -- enum ieee80211_phymode mode; -- struct ieee80211_channel *c; -- int i; - - ss->ss_last = 0; -- /* -- * Use the table of ordered channels to construct the list -- * of channels for scanning. Any channels in the ordered -- * list not in the master list will be discarded. -- */ -- for (scan = staScanTable; scan->list != NULL; scan++) { -- mode = scan->mode; -- if (vap->iv_des_mode != IEEE80211_MODE_AUTO) { -- /* -- * If a desired mode was specified, scan only -- * channels that satisfy that constraint. -- */ -- if (vap->iv_des_mode != mode) { -- /* -- * The scan table marks 2.4Ghz channels as b -- * so if the desired mode is 11g, then use -- * the 11b channel list but upgrade the mode. -- */ -- if (vap->iv_des_mode != IEEE80211_MODE_11G || -- mode != IEEE80211_MODE_11B) -- continue; -- mode = IEEE80211_MODE_11G; /* upgrade */ -- } -- } else { -- /* -- * This lets ieee80211_scan_add_channels -- * upgrade an 11b channel to 11g if available. -- */ -- if (mode == IEEE80211_MODE_11B) -- mode = IEEE80211_MODE_AUTO; -- } -- /* XR does not operate on turbo channels */ -- if ((vap->iv_flags & IEEE80211_F_XR) && -- (mode == IEEE80211_MODE_TURBO_A || -- mode == IEEE80211_MODE_TURBO_G)) -- continue; -- /* -- * Add the list of the channels; any that are not -- * in the master channel list will be discarded. -- */ -- add_channels(ic, ss, mode, scan->list, scan->count); -- } -- -- /* -- * Add the channels from the ic (from HAL) that are not present -- * in the staScanTable. -- */ -- for (i = 0; i < ic->ic_nchans; i++) { -- c = &ic->ic_channels[i]; -- /* -- * scan dynamic turbo channels in normal mode. -- */ -- if (IEEE80211_IS_CHAN_DTURBO(c)) -- continue; -- mode = ieee80211_chan2mode(c); -- if (vap->iv_des_mode != IEEE80211_MODE_AUTO) { -- /* -- * If a desired mode was specified, scan only -- * channels that satisfy that constraint. -- */ -- if (vap->iv_des_mode != mode) -- continue; -- -- } -- if (!checktable(staScanTable, c)) -- ss->ss_chans[ss->ss_last++] = c; -- } -- -+ ieee80211_scan_add_channels(ic, ss, vap->iv_des_mode); - ss->ss_next = 0; -+ - /* XXX tunables */ - /* - * The scanner will stay on station for ss_maxdwell ms (using a -@@ -750,17 +539,7 @@ - fail = 0; - if (isclr(ic->ic_chan_active, ieee80211_chan2ieee(ic, se->se_chan))) - fail |= 0x01; -- /* -- * NB: normally the desired mode is used to construct -- * the channel list, but it's possible for the scan -- * cache to include entries for stations outside this -- * list so we check the desired mode here to weed them -- * out. -- */ -- if (vap->iv_des_mode != IEEE80211_MODE_AUTO && -- (se->se_chan->ic_flags & IEEE80211_CHAN_ALLTURBO) != -- chanflags[vap->iv_des_mode]) -- fail |= 0x01; -+ - if (vap->iv_opmode == IEEE80211_M_IBSS) { - if ((se->se_capinfo & IEEE80211_CAPINFO_IBSS) == 0) - fail |= 0x02; -@@ -1175,78 +954,6 @@ - .scan_default = ieee80211_sta_join, - }; - --/* -- * Start an adhoc-mode scan by populating the channel list. -- */ --static int --adhoc_start(struct ieee80211_scan_state *ss, struct ieee80211vap *vap) --{ -- struct ieee80211com *ic = vap->iv_ic; -- struct sta_table *st = ss->ss_priv; -- const struct scanlist *scan; -- enum ieee80211_phymode mode; -- -- ss->ss_last = 0; -- /* -- * Use the table of ordered channels to construct the list -- * of channels for scanning. Any channels in the ordered -- * list not in the master list will be discarded. -- */ -- for (scan = staScanTable; scan->list != NULL; scan++) { -- mode = scan->mode; -- if (vap->iv_des_mode != IEEE80211_MODE_AUTO) { -- /* -- * If a desired mode was specified, scan only -- * channels that satisfy that constraint. -- */ -- if (vap->iv_des_mode != mode) { -- /* -- * The scan table marks 2.4Ghz channels as b -- * so if the desired mode is 11g, then use -- * the 11b channel list but upgrade the mode. -- */ -- if (vap->iv_des_mode != IEEE80211_MODE_11G || -- mode != IEEE80211_MODE_11B) -- continue; -- mode = IEEE80211_MODE_11G; /* upgrade */ -- } -- } else { -- /* -- * This lets ieee80211_scan_add_channels -- * upgrade an 11b channel to 11g if available. -- */ -- if (mode == IEEE80211_MODE_11B) -- mode = IEEE80211_MODE_AUTO; -- } -- /* XR does not operate on turbo channels */ -- if ((vap->iv_flags & IEEE80211_F_XR) && -- (mode == IEEE80211_MODE_TURBO_A || -- mode == IEEE80211_MODE_TURBO_G)) -- continue; -- /* -- * Add the list of the channels; any that are not -- * in the master channel list will be discarded. -- */ -- add_channels(ic, ss, mode, scan->list, scan->count); -- } -- ss->ss_next = 0; -- /* XXX tunables */ -- ss->ss_mindwell = msecs_to_jiffies(200); /* 200ms */ -- ss->ss_maxdwell = msecs_to_jiffies(200); /* 200ms */ -- --#ifdef IEEE80211_DEBUG -- if (ieee80211_msg_scan(vap)) { -- printk("%s: scan set ", vap->iv_dev->name); -- ieee80211_scan_dump_channels(ss); -- printk(" dwell min %ld max %ld\n", -- ss->ss_mindwell, ss->ss_maxdwell); -- } --#endif /* IEEE80211_DEBUG */ -- -- st->st_newscan = 1; -- -- return 0; --} - - /* - * Select a channel to start an adhoc network on. -@@ -1412,7 +1119,7 @@ - .scan_name = "default", - .scan_attach = sta_attach, - .scan_detach = sta_detach, -- .scan_start = adhoc_start, -+ .scan_start = sta_start, - .scan_restart = sta_restart, - .scan_cancel = sta_cancel, - .scan_end = adhoc_pick_bss, ---- a/net80211/ieee80211.c -+++ b/net80211/ieee80211.c -@@ -292,6 +292,11 @@ - ("channel with bogus ieee number %u", c->ic_ieee)); - setbit(ic->ic_chan_avail, c->ic_ieee); - -+ if (c->ic_scanflags & IEEE80211_NOSCAN_DEFAULT) -+ c->ic_scanflags |= IEEE80211_NOSCAN_SET; -+ else -+ c->ic_scanflags &= ~IEEE80211_NOSCAN_SET; -+ - /* Identify mode capabilities. */ - if (IEEE80211_IS_CHAN_A(c)) - ic->ic_modecaps |= 1 << IEEE80211_MODE_11A; ---- a/net80211/_ieee80211.h -+++ b/net80211/_ieee80211.h -@@ -132,6 +132,11 @@ - IEEE80211_SCAN_FIRST = 2, /* take first suitable candidate */ - }; - -+enum ieee80211_scanflags { -+ IEEE80211_NOSCAN_DEFAULT = (1 << 0), -+ IEEE80211_NOSCAN_SET = (1 << 1), -+}; -+ - /* - * Channels are specified by frequency and attributes. - */ -@@ -142,6 +147,7 @@ - int8_t ic_maxregpower; /* maximum regulatory tx power in dBm */ - int8_t ic_maxpower; /* maximum tx power in dBm */ - int8_t ic_minpower; /* minimum tx power in dBm */ -+ u_int8_t ic_scanflags; - }; - - #define IEEE80211_CHAN_MAX 255 ---- a/net80211/ieee80211_ioctl.h -+++ b/net80211/ieee80211_ioctl.h -@@ -556,6 +556,7 @@ - #define IEEE80211_IOCTL_WDSADDMAC (SIOCIWFIRSTPRIV+26) - #define IEEE80211_IOCTL_WDSDELMAC (SIOCIWFIRSTPRIV+28) - #define IEEE80211_IOCTL_KICKMAC (SIOCIWFIRSTPRIV+30) -+#define IEEE80211_IOCTL_SETSCANLIST (SIOCIWFIRSTPRIV+31) - - enum { - IEEE80211_WMMPARAMS_CWMIN = 1, ---- a/net80211/ieee80211_scan_ap.c -+++ b/net80211/ieee80211_scan_ap.c -@@ -200,131 +200,7 @@ - - static int ap_flush(struct ieee80211_scan_state *); - static void action_tasklet(IEEE80211_TQUEUE_ARG); --static struct ieee80211_channel *find11gchannel(struct ieee80211com *ic, -- int i, int freq); - --static const u_int chanflags[] = { -- IEEE80211_CHAN_B, /* IEEE80211_MODE_AUTO */ -- IEEE80211_CHAN_A, /* IEEE80211_MODE_11A */ -- IEEE80211_CHAN_B, /* IEEE80211_MODE_11B */ -- IEEE80211_CHAN_PUREG, /* IEEE80211_MODE_11G */ -- IEEE80211_CHAN_FHSS, /* IEEE80211_MODE_FH */ -- IEEE80211_CHAN_A, /* IEEE80211_MODE_TURBO_A */ /* for turbo mode -- * look for AP in -- * normal channel -- */ -- IEEE80211_CHAN_PUREG, /* IEEE80211_MODE_TURBO_G */ -- IEEE80211_CHAN_ST, /* IEEE80211_MODE_TURBO_STATIC_A */ --}; -- --static const u_int16_t rcl1[] = /* 8 FCC channel: 52, 56, 60, 64, -- * 36, 40, 44, 48 */ --{ 5260, 5280, 5300, 5320, 5180, 5200, 5220, 5240 }; --static const u_int16_t rcl2[] = /* 4 MKK channels: 34, 38, 42, 46 */ --{ 5170, 5190, 5210, 5230 }; --static const u_int16_t rcl3[] = /* 2.4Ghz ch: 1,6,11,7,13 */ --{ 2412, 2437, 2462, 2442, 2472 }; --static const u_int16_t rcl4[] = /* 5 FCC channel: 149, 153, 161, 165 */ --{ 5745, 5765, 5785, 5805, 5825 }; --static const u_int16_t rcl7[] = /* 11 ETSI channel: 100, 104, 108, 112, -- * 116, 120, 124, 128, -- * 132, 136, 140 */ --{ 5500, 5520, 5540, 5560, 5580, 5600, 5620, 5640, 5660, 5680, 5700 }; --static const u_int16_t rcl8[] = /* 2.4Ghz ch: 2,3,4,5,8,9,10,12 */ --{ 2417, 2422, 2427, 2432, 2447, 2452, 2457, 2467 }; --static const u_int16_t rcl9[] = /* 2.4Ghz ch: 14 */ --{ 2484 }; --static const u_int16_t rcl10[] = /* Added Korean channels 2312-2372 */ --{ 2312, 2317, 2322, 2327, 2332, 2337, 2342, 2347, 2352, 2357, 2362, 2367, 2372 }; --static const u_int16_t rcl11[] = /* Added Japan channels in 4.9/5.0 spectrum */ --{ 5040, 5060, 5080, 4920, 4940, 4960, 4980 }; --#ifdef ATH_TURBO_SCAN --static const u_int16_t rcl5[] = /* 3 static turbo channels */ --{ 5210, 5250, 5290 }; --static const u_int16_t rcl6[] = /* 2 static turbo channels */ --{ 5760, 5800 }; --static const u_int16_t rcl6x[] = /* 4 FCC3 turbo channels */ --{ 5540, 5580, 5620, 5660 }; --static const u_int16_t rcl12[] = /* 2.4Ghz Turbo channel 6 */ --{ 2437 }; --static const u_int16_t rcl13[] = /* dynamic Turbo channels */ --{ 5200, 5240, 5280, 5765, 5805 }; --#endif /* ATH_TURBO_SCAN */ -- --struct scanlist { -- u_int16_t mode; -- u_int16_t count; -- const u_int16_t *list; --}; -- --#define IEEE80211_MODE_TURBO_STATIC_A IEEE80211_MODE_MAX --#define X(a) .count = ARRAY_SIZE(a), .list = a -- --static const struct scanlist staScanTable[] = { -- { IEEE80211_MODE_11B, X(rcl3) }, -- { IEEE80211_MODE_11A, X(rcl1) }, -- { IEEE80211_MODE_11A, X(rcl2) }, -- { IEEE80211_MODE_11B, X(rcl8) }, -- { IEEE80211_MODE_11B, X(rcl9) }, -- { IEEE80211_MODE_11A, X(rcl4) }, --#ifdef ATH_TURBO_SCAN -- { IEEE80211_MODE_TURBO_STATIC_A, X(rcl5) }, -- { IEEE80211_MODE_TURBO_STATIC_A, X(rcl6) }, -- { IEEE80211_MODE_TURBO_A, X(rcl6x) }, -- { IEEE80211_MODE_TURBO_A, X(rcl13) }, --#endif /* ATH_TURBO_SCAN */ -- { IEEE80211_MODE_11A, X(rcl7) }, -- { IEEE80211_MODE_11B, X(rcl10) }, -- { IEEE80211_MODE_11A, X(rcl11) }, --#ifdef ATH_TURBO_SCAN -- { IEEE80211_MODE_TURBO_G, X(rcl12) }, --#endif /* ATH_TURBO_SCAN */ -- { .list = NULL } --}; -- --#undef X --/* This function must be invoked with locks acquired */ --static void --add_channels(struct ieee80211com *ic, -- struct ieee80211_scan_state *ss, -- enum ieee80211_phymode mode, const u_int16_t freq[], int nfreq) --{ -- struct ieee80211_channel *c, *cg; -- u_int modeflags; -- int i; -- -- KASSERT(mode < ARRAY_SIZE(chanflags), ("Unexpected mode %u", mode)); -- modeflags = chanflags[mode]; -- for (i = 0; i < nfreq; i++) { -- c = ieee80211_find_channel(ic, freq[i], modeflags); -- if ((c == NULL) || isclr(ic->ic_chan_active, c->ic_ieee)) -- continue; -- if (mode == IEEE80211_MODE_AUTO) { -- /* XXX special-case 11b/g channels so we select -- * the g channel if both are present. */ -- if (IEEE80211_IS_CHAN_B(c) && -- (cg = find11gchannel(ic, i, c->ic_freq)) != NULL) -- c = cg; -- } -- if (ss->ss_last >= IEEE80211_SCAN_MAX) -- break; -- ss->ss_chans[ss->ss_last++] = c; -- } --} -- --/* This function must be invoked with locks acquired */ --static int --checktable(const struct scanlist *scan, const struct ieee80211_channel *c) --{ -- int i; -- -- for (; scan->list != NULL; scan++) { -- for (i = 0; i < scan->count; i++) -- if (scan->list[i] == c->ic_freq) -- return 1; -- } -- return 0; --} - - /* - * Attach prior to any scanning work. -@@ -398,29 +274,6 @@ - ieee80211_saveie(iep, ie); - } - --/* This function must be invoked with locks acquired */ --static struct ieee80211_channel * --find11gchannel(struct ieee80211com *ic, int i, int freq) --{ -- struct ieee80211_channel *c; -- int j; -- -- /* The normal ordering in the channel list is b channel -- * immediately followed by g so optimize the search for -- * this. We'll still do a full search just in case. */ -- for (j = i + 1; j < ic->ic_nchans; j++) { -- c = &ic->ic_channels[j]; -- if ((c->ic_freq == freq) && IEEE80211_IS_CHAN_ANYG(c)) -- return c; -- } -- for (j = 0; j < i; j++) { -- c = &ic->ic_channels[j]; -- if ((c->ic_freq == freq) && IEEE80211_IS_CHAN_ANYG(c)) -- return c; -- } -- return NULL; --} -- - /* - * Start an ap scan by populating the channel list. - */ -@@ -429,90 +282,14 @@ - { - struct ap_state *as = ss->ss_priv; - struct ieee80211com *ic = NULL; -- const struct scanlist *sl = NULL; -- struct ieee80211_channel *c = NULL; -- int i; -- unsigned int mode = 0; - - SCAN_AP_LOCK_IRQ(as); - ic = vap->iv_ic; - /* Determine mode flags to match, or leave zero for auto mode */ - as->as_vap_desired_mode = vap->iv_des_mode; - as->as_required_mode = 0; -- if (as->as_vap_desired_mode != IEEE80211_MODE_AUTO) { -- as->as_required_mode = chanflags[as->as_vap_desired_mode]; -- if ((vap->iv_ath_cap & IEEE80211_ATHC_TURBOP) && -- (as->as_required_mode != IEEE80211_CHAN_ST)) { -- /* Fixup for dynamic turbo flags */ -- if (as->as_vap_desired_mode == IEEE80211_MODE_11G) -- as->as_required_mode = IEEE80211_CHAN_108G; -- else -- as->as_required_mode = IEEE80211_CHAN_108A; -- } -- } -- -- ss->ss_last = 0; -- /* Use the table of ordered channels to construct the list -- * of channels for scanning. Any channels in the ordered -- * list not in the master list will be discarded. */ -- for (sl = staScanTable; sl->list != NULL; sl++) { -- mode = sl->mode; -- -- /* The scan table marks 2.4Ghz channels as b -- * so if the desired mode is 11g, then use -- * the 11b channel list but upgrade the mode. */ -- if (as->as_vap_desired_mode && -- (as->as_vap_desired_mode != mode) && -- (as->as_vap_desired_mode == IEEE80211_MODE_11G) && -- (mode == IEEE80211_MODE_11B)) -- mode = IEEE80211_MODE_11G; -- -- /* If we are in "AUTO" mode, upgrade the mode to auto. -- * This lets add_channels upgrade an 11b channel to -- * 11g if available. */ -- if (!as->as_vap_desired_mode && (mode == IEEE80211_MODE_11B)) -- mode = IEEE80211_MODE_AUTO; -- -- /* Add the list of the channels; any that are not -- * in the master channel list will be discarded. */ -- add_channels(ic, ss, mode, sl->list, sl->count); -- } -- -- /* Add the channels from the ic (from HAL) that are not present -- * in the staScanTable, assuming they pass the sanity checks... */ -- for (i = 0; i < ic->ic_nchans; i++) { -- c = &ic->ic_channels[i]; -- -- /* XR is not supported on turbo channels */ -- if (IEEE80211_IS_CHAN_TURBO(c) && vap->iv_flags & IEEE80211_F_XR) -- continue; -+ ieee80211_scan_add_channels(ic, ss, vap->iv_des_mode); - -- /* Dynamic channels are scanned in base mode */ -- if (!as->as_required_mode && !IEEE80211_IS_CHAN_ST(c)) -- continue; -- -- /* Use any 11g channel instead of 11b one. */ -- if (vap->iv_des_mode == IEEE80211_MODE_AUTO && -- IEEE80211_IS_CHAN_B(c) && -- find11gchannel(ic, i, c->ic_freq)) -- continue; -- -- /* Do not add channels already put into the scan list by the -- * scan table - these have already been filtered by mode -- * and for whether they are in the active channel list. */ -- if (checktable(staScanTable, c)) -- continue; -- -- /* Make sure the channel is active */ -- if ((c == NULL) || isclr(ic->ic_chan_active, c->ic_ieee)) -- continue; -- -- /* Don't overrun */ -- if (ss->ss_last >= IEEE80211_SCAN_MAX) -- break; -- -- ss->ss_chans[ss->ss_last++] = c; -- } - ss->ss_next = 0; - /* XXX tunables */ - ss->ss_mindwell = msecs_to_jiffies(200); /* 200ms */ -@@ -831,13 +608,6 @@ - if (IEEE80211_IS_CHAN_RADAR(c->chan)) - continue; - -- /* Do not select 802.11a ST if mode is specified and is not -- * 802.11a ST */ -- if (as->as_required_mode && -- IEEE80211_IS_CHAN_STURBO(c->chan) && -- (as->as_vap_desired_mode != IEEE80211_MODE_TURBO_STATIC_A)) -- continue; -- - /* Verify mode matches any fixed mode specified */ - if ((c->chan->ic_flags & as->as_required_mode) != - as->as_required_mode) ---- a/net80211/ieee80211_scan.c -+++ b/net80211/ieee80211_scan.c -@@ -969,6 +969,80 @@ - } - } - -+static const u_int chanflags[] = { -+ 0, /* IEEE80211_MODE_AUTO */ -+ IEEE80211_CHAN_A, /* IEEE80211_MODE_11A */ -+ IEEE80211_CHAN_B, /* IEEE80211_MODE_11B */ -+ IEEE80211_CHAN_PUREG, /* IEEE80211_MODE_11G */ -+ IEEE80211_CHAN_FHSS, /* IEEE80211_MODE_FH */ -+ IEEE80211_CHAN_A, /* IEEE80211_MODE_TURBO_A */ /* for turbo mode look for AP in normal channel */ -+ IEEE80211_CHAN_PUREG, /* IEEE80211_MODE_TURBO_G */ -+ IEEE80211_CHAN_ST, /* IEEE80211_MODE_TURBO_STATIC_A */ -+}; -+ -+static struct ieee80211_channel * -+find11gchannel(struct ieee80211com *ic, int i, int freq) -+{ -+ struct ieee80211_channel *c; -+ int j; -+ -+ /* -+ * The normal ordering in the channel list is b channel -+ * immediately followed by g so optimize the search for -+ * this. We'll still do a full search just in case. -+ */ -+ for (j = i+1; j < ic->ic_nchans; j++) { -+ c = &ic->ic_channels[j]; -+ if (c->ic_freq == freq && IEEE80211_IS_CHAN_ANYG(c)) -+ return c; -+ } -+ for (j = 0; j < i; j++) { -+ c = &ic->ic_channels[j]; -+ if (c->ic_freq == freq && IEEE80211_IS_CHAN_ANYG(c)) -+ return c; -+ } -+ return NULL; -+} -+ -+ -+void -+ieee80211_scan_add_channels(struct ieee80211com *ic, -+ struct ieee80211_scan_state *ss, -+ enum ieee80211_phymode mode) -+{ -+ struct ieee80211_channel *c, *cg; -+ u_int modeflags; -+ int i; -+ -+ KASSERT(mode < ARRAY_SIZE(chanflags), ("Unexpected mode %u", mode)); -+ modeflags = chanflags[mode]; -+ for (i = 0; i < ic->ic_nchans; i++) { -+ c = &ic->ic_channels[i]; -+ if (c == NULL || isclr(ic->ic_chan_active, c->ic_ieee)) -+ continue; -+ if (c->ic_scanflags & IEEE80211_NOSCAN_SET) -+ continue; -+ if (modeflags && -+ ((c->ic_flags & IEEE80211_CHAN_ALLTURBO) != -+ (modeflags & IEEE80211_CHAN_ALLTURBO))) -+ continue; -+ if (mode == IEEE80211_MODE_AUTO) { -+ /* -+ * XXX special-case 11b/g channels so we select -+ * the g channel if both are present. -+ */ -+ if (IEEE80211_IS_CHAN_B(c) && -+ (cg = find11gchannel(ic, i, c->ic_freq)) != NULL) -+ continue; -+ } -+ if (ss->ss_last >= IEEE80211_SCAN_MAX) -+ break; -+ ss->ss_chans[ss->ss_last++] = c; -+ } -+} -+EXPORT_SYMBOL(ieee80211_scan_add_channels); -+ -+ - /* - * Execute radar channel change. This is called when a radar/dfs - * signal is detected. AP mode only. Return 1 on success, 0 on ---- a/net80211/ieee80211_scan.h -+++ b/net80211/ieee80211_scan.h -@@ -219,4 +219,7 @@ - void ieee80211_scanner_unregister(enum ieee80211_opmode, - const struct ieee80211_scanner *); - void ieee80211_scanner_unregister_all(const struct ieee80211_scanner *); -+void ieee80211_scan_add_channels(struct ieee80211com *ic, -+ struct ieee80211_scan_state *ss, -+ enum ieee80211_phymode mode); - #endif /* _NET80211_IEEE80211_SCAN_H_ */ ---- a/net80211/ieee80211_wireless.c -+++ b/net80211/ieee80211_wireless.c -@@ -3911,6 +3911,106 @@ - return ieee80211_ioctl_setmlme(dev, info, w, (char *)&mlme); - } - -+static inline void setflag(struct ieee80211_channel *c, int flag) -+{ -+ if (flag) -+ c->ic_scanflags |= IEEE80211_NOSCAN_SET; -+ else -+ c->ic_scanflags &= ~IEEE80211_NOSCAN_SET; -+} -+ -+static void setscanflag(struct ieee80211com *ic, int min, int max, int set) -+{ -+ int i; -+ -+ for (i = 0; i < ic->ic_nchans; i++) { -+ struct ieee80211_channel *c = &ic->ic_channels[i]; -+ -+ if (min == -1) { -+ if (!(c->ic_scanflags & IEEE80211_NOSCAN_DEFAULT)) -+ setflag(c, set); -+ } else if ((c->ic_freq >= min) && (c->ic_freq <= max)) { -+ setflag(c, set); -+ } -+ } -+} -+ -+static int -+ieee80211_ioctl_setscanlist(struct net_device *dev, -+ struct iw_request_info *info, -+ struct iw_point *data, char *extra) -+{ -+ struct ieee80211vap *vap = dev->priv; -+ struct ieee80211com *ic = vap->iv_ic; -+ char *s, *next; -+ int val = 1; -+ -+ if (data->length <= 0) -+ return -EINVAL; -+ -+ s = kmalloc(data->length + 1, GFP_KERNEL); -+ if (!s) -+ return -ENOMEM; -+ -+ memset(s, 0, data->length + 1); -+ if (copy_from_user(s, data->pointer, data->length)) -+ return -EFAULT; -+ -+ s[data->length - 1] = '\0'; /* ensure null termination */ -+ -+ switch(*s) { -+ case '-': -+ val = 1; -+ break; -+ case '+': -+ val = 0; -+ break; -+ default: -+ goto error; -+ } -+ s++; -+ next = s; -+ do { -+ next = strchr(s, ','); -+ if (next) { -+ *next = 0; -+ next++; -+ } -+ if (!strcmp(s, "ALL")) { -+ setscanflag(ic, 0, 10000, val); -+ } else if (!strcmp(s, "REG")) { -+ setscanflag(ic, -1, -1, val); -+ } else { -+ int min, max; -+ char *n, *end = NULL; -+ -+ n = strchr(s, '-'); -+ if (n) { -+ *n = 0; -+ n++; -+ } -+ min = simple_strtoul(s, &end, 10); -+ if (end && *end) -+ goto error; -+ if (n) { -+ max = simple_strtoul(n, &end, 10); -+ if (end && *end) -+ goto error; -+ } else { -+ max = min; -+ } -+ setscanflag(ic, min, max, val); -+ } -+ s = next; -+ } while (next); -+ return 0; -+ -+error: -+ if (s) -+ kfree(s); -+ return -EINVAL; -+} -+ - static int - ieee80211_ioctl_addmac(struct net_device *dev, struct iw_request_info *info, - void *w, char *extra) -@@ -5712,6 +5812,8 @@ - IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "minrate"}, - {IEEE80211_PARAM_MINRATE, - 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "get_minrate"}, -+ { IEEE80211_IOCTL_SETSCANLIST, -+ IW_PRIV_TYPE_CHAR | 255, 0, "setscanlist"}, - - #ifdef ATH_REVERSE_ENGINEERING - /* -@@ -5809,6 +5911,7 @@ - set_priv(IEEE80211_IOCTL_WDSADDMAC, ieee80211_ioctl_wdsmac), - set_priv(IEEE80211_IOCTL_WDSDELMAC, ieee80211_ioctl_wdsdelmac), - set_priv(IEEE80211_IOCTL_KICKMAC, ieee80211_ioctl_kickmac), -+ set_priv(IEEE80211_IOCTL_SETSCANLIST, ieee80211_ioctl_setscanlist), - #ifdef ATH_REVERSE_ENGINEERING - set_priv(IEEE80211_IOCTL_READREG, ieee80211_ioctl_readreg), - set_priv(IEEE80211_IOCTL_WRITEREG, ieee80211_ioctl_writereg), diff --git a/package/madwifi/patches-r3776/316-ani_fix.patch b/package/madwifi/patches-r3776/316-ani_fix.patch deleted file mode 100644 index ad7deb036c..0000000000 --- a/package/madwifi/patches-r3776/316-ani_fix.patch +++ /dev/null @@ -1,730 +0,0 @@ ---- a/ath/if_ath.c -+++ b/ath/if_ath.c -@@ -343,6 +343,8 @@ - unsigned int param, unsigned int value); - - static u_int32_t ath_get_real_maxtxpower(struct ath_softc *sc); -+static int ath_setintmit(struct ath_softc *sc); -+static u_int32_t ath_calcrxfilter(struct ath_softc *sc); - - #ifdef AR_DEBUG - static int ath_txq_check(struct ath_softc *sc, struct ath_txq *txq, const char *msg); -@@ -356,7 +358,6 @@ - static char *ratectl = DEF_RATE_CTL; - static int rfkill = 0; - static int hal_tpc = 0; --static int intmit = 0; - static int countrycode = CTRY_DEFAULT; - static int maxvaps = ATH_MAXVAPS_DEFAULT; - static int outdoor = 0; -@@ -398,7 +399,6 @@ - #endif - MODULE_PARM(autocreate, "s"); - MODULE_PARM(ratectl, "s"); --MODULE_PARM(intmit, "i"); - #else - #include - module_param(beacon_cal, int, 0600); -@@ -412,7 +412,6 @@ - #endif - module_param(autocreate, charp, 0600); - module_param(ratectl, charp, 0600); --module_param(intmit, int, 0600); - #endif - MODULE_PARM_DESC(countrycode, "Override default country code. Default is 0."); - MODULE_PARM_DESC(maxvaps, "Maximum VAPs. Default is 4."); -@@ -428,7 +427,6 @@ - "'none' to disable"); - MODULE_PARM_DESC(ratectl, "Rate control algorithm [amrr|minstrel|onoe|sample], " - "defaults to '" DEF_RATE_CTL "'"); --MODULE_PARM_DESC(intmit, "Enable interference mitigation by default. Default is 0."); - - #ifdef AR_DEBUG - static int ath_debug = 0; -@@ -585,23 +583,13 @@ - if (ath_hal_hastxpowlimit(ah)) { - ic->ic_caps |= IEEE80211_C_TXPMGT; - } -- /* Interference mitigation/ambient noise immunity (ANI). -- * In modes other than HAL_M_STA, it causes receive sensitivity -- * problems for OFDM. */ -+ /* Interference mitigation/ambient noise immunity (ANI). */ - sc->sc_hasintmit = ath_hal_hasintmit(ah); -- sc->sc_useintmit = (intmit && sc->sc_hasintmit); -- if (!sc->sc_hasintmit && intmit) { -- WPRINTF(sc, "Interference mitigation was requested, but is not" -- "supported by the HAL/hardware.\n"); -- intmit = 0; /* Stop use in future ath_attach(). */ -- } -- else { -- ath_hal_setintmit(ah, sc->sc_useintmit); -- DPRINTF(sc, ATH_DEBUG_ANY, "Interference mitigation is " -- "supported. Currently %s.\n", -- (sc->sc_useintmit ? "enabled" : "disabled")); -- } - -+ /* auto, mode dependent */ -+ sc->sc_useintmit = -1; -+ sc->sc_noise_immunity = -1; -+ sc->sc_ofdm_weak_det = -1; - sc->sc_dmasize_stomp = 0; - - /* -@@ -614,15 +602,6 @@ - sc->sc_mrretry = ath_hal_setupxtxdesc(ah, NULL, 0,0, 0,0, 0,0); - - /* -- * Check if the device has hardware counters for PHY -- * errors. If so we need to enable the MIB interrupt -- * so we can act on stat triggers. -- */ -- sc->sc_needmib = ath_hal_hwphycounters(ah) && -- sc->sc_hasintmit && -- sc->sc_useintmit; -- -- /* - * Get the hardware key cache size. - */ - sc->sc_keymax = ath_hal_keycachesize(ah); -@@ -1593,37 +1572,6 @@ - ath_init(dev); - } - --/* NB: Int. mit. was not implemented so that it could be enabled/disabled, -- * and actually in 0.9.30.13 HAL it really can't even be disabled because -- * it will start adjusting registers even when we turn off the capability -- * in the HAL. -- * -- * NB: This helper function basically clobbers all the related registers -- * if we have disabled int. mit. cap, allowing us to turn it on and off and -- * work around the bug preventing it from being disabled. */ --static inline void ath_override_intmit_if_disabled(struct ath_softc *sc) { -- /* Restore int. mit. registers if they were turned off. */ -- if (sc->sc_hasintmit && !sc->sc_useintmit) -- ath_hal_restore_default_intmit(sc->sc_ah); -- /* Sanity check... remove later. */ -- if (!sc->sc_useintmit) { -- ath_hal_verify_default_intmit(sc->sc_ah); -- /* If we don't have int. mit. and we don't have DFS on channel, -- * it is safe to filter error packets. */ -- if (!ath_radar_is_dfs_required(sc, &sc->sc_curchan)) { -- ath_hal_setrxfilter(sc->sc_ah, -- ath_hal_getrxfilter(sc->sc_ah) & -- ~HAL_RX_FILTER_PHYERR); -- } -- } -- else { -- /* Make sure that we have errors in RX filter because ANI needs -- * them. */ -- ath_hal_setrxfilter(sc->sc_ah, -- ath_hal_getrxfilter(sc->sc_ah) | HAL_RX_FILTER_PHYERR); -- } --} -- - static HAL_BOOL ath_hw_reset(struct ath_softc *sc, HAL_OPMODE opmode, - HAL_CHANNEL *channel, HAL_BOOL bChannelChange, - HAL_STATUS *status) -@@ -1698,11 +1646,7 @@ - ath_hal_settpc(sc->sc_ah, hal_tpc); - } - #endif --#if 0 /* Setting via HAL does not work, so it is done manually below. */ -- if (sc->sc_hasintmit) -- ath_hal_setintmit(sc->sc_ah, sc->sc_useintmit); --#endif -- ath_override_intmit_if_disabled(sc); -+ ath_setintmit(sc); - if (sc->sc_dmasize_stomp) - ath_hal_set_dmasize_pcie(sc->sc_ah); - if (sc->sc_softled) -@@ -2496,7 +2440,6 @@ - - /* Let the HAL handle the event. */ - ath_hal_mibevent(ah, &sc->sc_halstats); -- ath_override_intmit_if_disabled(sc); - } - } - if (needmark) -@@ -2564,6 +2507,55 @@ - return flags; - } - -+static int ath_setintmit(struct ath_softc *sc) -+{ -+ struct ath_hal *ah = sc->sc_ah; -+ int ret; -+ int val; -+ -+ if (!sc->sc_hasintmit) -+ return 0; -+ -+ switch(sc->sc_useintmit) { -+ case 0: /* disabled */ -+ case 1: /* enabled */ -+ val = sc->sc_useintmit; -+ break; -+ default: -+ if (sc->sc_opmode != IEEE80211_M_MONITOR) -+ val = 1; -+ else -+ val = 0; -+ break; -+ } -+ ret = ath_hal_setintmit(ah, val); -+ if (val) -+ goto done; -+ -+ /* manual settings */ -+ if ((sc->sc_noise_immunity >= 0) && (sc->sc_noise_immunity <= 5)) -+ ath_hal_setcapability(ah, HAL_CAP_INTMIT, 2, sc->sc_noise_immunity, NULL); -+ if ((sc->sc_ofdm_weak_det == 0) || (sc->sc_ofdm_weak_det == 1)) -+ ath_hal_setcapability(ah, HAL_CAP_INTMIT, 3, sc->sc_ofdm_weak_det, NULL); -+ -+done: -+ if (!sc->sc_imask) -+ goto out; -+ -+ /* MIB interrupt handling */ -+ sc->sc_needmib = ath_hal_hwphycounters(ah) && -+ sc->sc_useintmit; -+ if (sc->sc_needmib) -+ sc->sc_imask |= HAL_INT_MIB; -+ else -+ sc->sc_imask &= ~HAL_INT_MIB; -+ ath_hal_intrset(sc->sc_ah, sc->sc_imask); -+ ath_calcrxfilter(sc); -+ -+out: -+ return ret; -+} -+ - /* - * Context: process context - */ -@@ -4249,8 +4241,7 @@ - u_int32_t rfilt; - - /* Preserve the current Phy. radar and err. filters. */ -- rfilt = (ath_hal_getrxfilter(ah) & -- (HAL_RX_FILTER_PHYERR | HAL_RX_FILTER_PHYRADAR)) | -+ rfilt = (ath_hal_getrxfilter(ah) & HAL_RX_FILTER_PHYRADAR) | - HAL_RX_FILTER_UCAST | HAL_RX_FILTER_BCAST | - HAL_RX_FILTER_MCAST; - if (ic->ic_opmode != IEEE80211_M_STA) -@@ -4266,6 +4257,8 @@ - if (sc->sc_nmonvaps > 0) - rfilt |= (HAL_RX_FILTER_CONTROL | HAL_RX_FILTER_BEACON | - HAL_RX_FILTER_PROBEREQ | HAL_RX_FILTER_PROM); -+ if (sc->sc_hasintmit && !sc->sc_needmib && ath_hal_getintmit(ah, NULL)) -+ rfilt |= HAL_RX_FILTER_PHYERR; - if (sc->sc_curchan.privFlags & CHANNEL_DFS) - rfilt |= (HAL_RX_FILTER_PHYERR | HAL_RX_FILTER_PHYRADAR); - return rfilt; -@@ -6810,8 +6803,7 @@ - dev->quota -= bf_processed; - #endif - -- if (sc->sc_useintmit) -- ath_hal_rxmonitor(ah, &sc->sc_halstats, &sc->sc_curchan); -+ ath_hal_rxmonitor(ah, &sc->sc_halstats, &sc->sc_curchan); - if (!bf_processed) - DPRINTF(sc, ATH_DEBUG_RX_PROC, - "Warning: %s got scheduled when no receive " -@@ -8727,7 +8719,6 @@ - ath_hal_rxena(ah); /* enable recv descriptors */ - ath_mode_init(dev); /* set filters, etc. */ - ath_hal_startpcurecv(ah); /* re-enable PCU/DMA engine */ -- ath_override_intmit_if_disabled(sc); - return 0; - } - -@@ -10633,8 +10624,10 @@ - ATH_RP_IGNORED = 24, - ATH_RADAR_IGNORED = 25, - ATH_MAXVAPS = 26, -- ATH_INTMIT = 27, -- ATH_DISTANCE = 28, -+ ATH_DISTANCE = 27, -+ ATH_INTMIT = 28, -+ ATH_NOISE_IMMUNITY = 29, -+ ATH_OFDM_WEAK_DET = 30 - }; - - static inline int -@@ -10696,6 +10689,48 @@ - } - - static int -+ath_sysctl_set_intmit(struct ath_softc *sc, long ctl, u_int val) -+{ -+ int ret; -+ -+ switch(ctl) { -+ case ATH_INTMIT: -+ sc->sc_intmit = val; -+ break; -+ case ATH_NOISE_IMMUNITY: -+ sc->sc_noise_immunity = val; -+ break; -+ case ATH_OFDM_WEAK_DET: -+ sc->sc_ofdm_weak_det = val; -+ break; -+ default: -+ return -EINVAL; -+ } -+ ret = ath_setintmit(sc); -+ return ret; -+} -+ -+static int -+ath_sysctl_get_intmit(struct ath_softc *sc, long ctl, u_int *val) -+{ -+ struct ath_hal *ah = sc->sc_ah; -+ -+ switch(ctl) { -+ case ATH_INTMIT: -+ *val = (ath_hal_getcapability(ah, HAL_CAP_INTMIT, 1, NULL) == HAL_OK); -+ break; -+ case ATH_NOISE_IMMUNITY: -+ return ath_hal_getcapability(ah, HAL_CAP_INTMIT, 2, val); -+ case ATH_OFDM_WEAK_DET: -+ return ath_hal_getcapability(ah, HAL_CAP_INTMIT, 3, val); -+ default: -+ return -EINVAL; -+ } -+ return 0; -+} -+ -+ -+static int - ATH_SYSCTL_DECL(ath_sysctl_halparam, ctl, write, filp, buffer, lenp, ppos) - { - struct ath_softc *sc = ctl->extra1; -@@ -10934,30 +10969,13 @@ - sc->sc_radar_ignored = val; - break; - case ATH_INTMIT: -- if (!sc->sc_hasintmit) { -+ case ATH_NOISE_IMMUNITY: -+ case ATH_OFDM_WEAK_DET: -+ if (!sc->sc_hasintmit) - ret = -EOPNOTSUPP; -- break; -- } -- if (sc->sc_useintmit == val) -- break; -- sc->sc_useintmit = val; -- sc->sc_needmib = ath_hal_hwphycounters(ah) && -- sc->sc_useintmit; -- /* Update the HAL and MIB interrupt mask bits */ -- ath_hal_setintmit(ah, !!val); -- sc->sc_imask = (sc->sc_imask & ~HAL_INT_MIB) | -- (sc->sc_needmib ? HAL_INT_MIB : 0); -- ath_hal_intrset(sc->sc_ah, sc->sc_imask); -- /* Only do a reset if device is valid and UP -- * and we just made a change to the settings. */ -- if (sc->sc_dev && !sc->sc_invalid && -- (sc->sc_dev->flags & IFF_RUNNING)) -- ath_reset(sc->sc_dev); -- /* NB: Run this step to cleanup if HAL doesn't -- * obey capability flags and hangs onto ANI -- * settings. */ -- ath_override_intmit_if_disabled(sc); -- break; -+ else -+ ret = ath_sysctl_set_intmit(sc, (long)ctl->extra2, val); -+ break; - default: - ret = -EINVAL; - break; -@@ -11029,9 +11047,14 @@ - case ATH_RADAR_IGNORED: - val = sc->sc_radar_ignored; - break; -- case ATH_INTMIT: -- val = sc->sc_useintmit; -- break; -+ case ATH_INTMIT: -+ case ATH_NOISE_IMMUNITY: -+ case ATH_OFDM_WEAK_DET: -+ if (!sc->sc_hasintmit) -+ ret = -EOPNOTSUPP; -+ else -+ ret = ath_sysctl_get_intmit(sc, (long)ctl->extra2, &val); -+ break; - default: - ret = -EINVAL; - break; -@@ -11413,6 +11436,24 @@ - .maxlen = sizeof(ath_xchanmode), - .proc_handler = proc_dointvec - }, -+ { .ctl_name = CTL_AUTO, -+ .procname = "intmit", -+ .mode = 0644, -+ .proc_handler = ath_sysctl_halparam, -+ .extra2 = (void *)ATH_INTMIT, -+ }, -+ { .ctl_name = CTL_AUTO, -+ .procname = "noise_immunity", -+ .mode = 0644, -+ .proc_handler = ath_sysctl_halparam, -+ .extra2 = (void *)ATH_NOISE_IMMUNITY, -+ }, -+ { .ctl_name = CTL_AUTO, -+ .procname = "ofdm_weak_det", -+ .mode = 0644, -+ .proc_handler = ath_sysctl_halparam, -+ .extra2 = (void *)ATH_OFDM_WEAK_DET, -+ }, - { 0 } - }; - static ctl_table ath_ath_table[] = { ---- a/ath/if_athvar.h -+++ b/ath/if_athvar.h -@@ -712,6 +712,10 @@ - unsigned int sc_txcont_power; /* Continuous transmit power in 0.5dBm units */ - unsigned int sc_txcont_rate; /* Continuous transmit rate in Mbps */ - -+ int8_t sc_intmit; /* Interference mitigation enabled, -1 = auto, based on mode, 0/1 = off/on */ -+ int8_t sc_noise_immunity; /* Noise immunity level, 0-4, -1 == auto) */ -+ int8_t sc_ofdm_weak_det; /* OFDM weak frames detection, -1 == auto */ -+ - /* rate tables */ - const HAL_RATE_TABLE *sc_rates[IEEE80211_MODE_MAX]; - const HAL_RATE_TABLE *sc_currates; /* current rate table */ ---- a/ath/if_ath_hal_extensions.h -+++ b/ath/if_ath_hal_extensions.h -@@ -237,296 +237,18 @@ - AR5K_DMASIZE_512B - }; - -- --int ath_set_ack_bitrate(struct ath_softc *sc, int); --int ar_device(int devid); --const char * ath5k_chip_name(enum ath5k_srev_type type, u_int16_t val); -- --static inline unsigned long field_width(unsigned long mask, unsigned long shift) --{ -- unsigned long r = 0; -- unsigned long x = mask >> shift; -- if ( 0 == mask ) return 0; --#if BITS_PER_LONG >= 64 -- if ( x & (~0UL<<32) ) { x >>= 32; r += 32; } --#endif -- if ( x & 0xffff0000 ) { x >>= 16; r += 16; } -- if ( x & 0x0000ff00 ) { x >>= 8; r += 8; } -- if ( x & 0x000000f0 ) { x >>= 4; r += 4; } -- if ( x & 0x0000000c ) { x >>= 2; r += 2; } -- if ( x & 0x00000002 ) { r += 1; } -- return r+1; --} -- --static inline u_int32_t get_field(struct ath_hal *ah, u_int32_t reg, u_int32_t mask, u_int32_t shift, int is_signed) { -- unsigned long x = ((OS_REG_READ(ah, reg) & mask) >> shift); -- if (is_signed) { -- unsigned long c =(-1) << (field_width(mask, shift)-1); -- return (x + c) ^ c; -- } -- return x; --} -- - static inline void set_field(struct ath_hal *ah, u_int32_t reg, u_int32_t mask, u_int32_t shift, u_int32_t value) { - OS_REG_WRITE(ah, reg, - (OS_REG_READ(ah, reg) & ~mask) | - ((value << shift) & mask)); - } - --static inline u_int32_t field_eq(struct ath_hal *ah, u_int32_t reg, -- u_int32_t mask, u_int32_t shift, -- u_int32_t value, int is_signed) { -- return (get_field(ah, reg, mask, shift, is_signed) & (mask >> shift)) == -- (value & (mask >> shift)); --} -- --static inline void override_warning(struct ath_hal *ah, const char *name, -- u_int32_t reg, u_int32_t mask, -- u_int32_t shift, u_int32_t expected, int is_signed) { -- -- if (!field_eq(ah, reg, mask, shift, expected, is_signed)) -- printk("%s: Correcting 0x%04x[%s] from 0x%x (%d) to 0x%x (%d).\n", -- SC_DEV_NAME(ah->ah_sc), -- reg, -- name, -- (get_field(ah, reg, mask, shift, is_signed) & (mask >> shift)), -- get_field(ah, reg, mask, shift, is_signed), -- (expected & (mask >> shift)), /* not sign extended */ -- expected); --#if 0 /* NB: For checking to see if HAL is fixed or not */ -- else { -- printk("%s: Keeping 0x%04x[%s] - 0x%x (%d).\n", -- SC_DEV_NAME(ah->ah_sc), -- reg, -- name, -- (get_field(ah, reg, mask, shift, is_signed) & (mask >> shift)), -- get_field(ah, reg, mask, shift, is_signed)); -- } --#endif --} -- --static inline void verification_warning(struct ath_hal *ah, const char *name, -- u_int32_t reg, u_int32_t mask, -- u_int32_t shift, u_int32_t expected, int is_signed) { -- -- int ret = field_eq(ah, reg, mask, shift, expected, is_signed); -- if (!ret) { -- printk("%s: %s verification of %s default value " -- "[found=0x%x (%d) expected=0x%x (%d)].\n", -- SC_DEV_NAME(ah->ah_sc), -- (ret ? "PASSED" : "FAILED"), -- name, -- (get_field(ah, reg, mask, shift, is_signed) & (mask >> shift)), -- get_field(ah, reg, mask, shift, is_signed), -- (expected & (mask >> shift)), /* not sign extended */ -- expected); -- ath_hal_print_decoded_register(ah, NULL, reg, -- OS_REG_READ(ah, reg), OS_REG_READ(ah, reg), 0); -- } --} -- --#define GET_FIELD(ah, __reg, __mask, __signed) \ -- get_field(ah, __reg, __mask, __mask ## _S, __signed) - #define SET_FIELD(ah, __reg, __mask, __value) \ - set_field(ah, __reg, __mask, __mask ## _S, __value); --#define FIELD_EQ(ah, __reg, __mask, __value, __signed) \ -- field_eq(ah, __reg, __mask, __mask ## _S, __value, __signed) -- --#if 0 /* NB: These are working at this point, and HAL tweaks them a lot */ --#define OVERRIDE_WARNING(ah, __reg, __mask, __expected, __signed) \ -- override_warning(ah, #__mask, __reg, __mask, __mask ## _S, __expected, __signed) --#else --#define OVERRIDE_WARNING(ah, __reg, __mask, __expected, __signed) --#endif -- --#define VERIFICATION_WARNING(ah, __reg, __mask, __signed) \ -- verification_warning(ah, #__mask, __reg, __mask, __mask ## _S, DEFAULT_ ## __mask, __signed) --#define VERIFICATION_WARNING_SW(ah, __reg, __mask, __signed) \ -- verification_warning(ah, #__mask, __reg, __mask, __mask ## _S, DEFAULT_ENABLE_ ## __reg ? __mask ## _ON : __mask ## _OFF, __signed) -- --static inline void ath_hal_set_noise_immunity(struct ath_hal *ah, -- int agc_desired_size, -- int agc_coarse_hi, -- int agc_coarse_lo, -- int sig_firpwr) --{ -- ATH_HAL_LOCK_IRQ(ah->ah_sc); -- ath_hal_set_function(__func__); -- ath_hal_set_device(SC_DEV_NAME(ah->ah_sc)); -- --#if 0 /* NB: These are working at this point, and HAL tweaks them a lot */ -- OVERRIDE_WARNING(ah, AR5K_PHY_AGCSIZE, AR5K_PHY_AGCSIZE_DESIRED, agc_desired_size, 1); -- OVERRIDE_WARNING(ah, AR5K_PHY_AGCCOARSE, AR5K_PHY_AGCCOARSE_LO, agc_coarse_lo, 1); -- OVERRIDE_WARNING(ah, AR5K_PHY_AGCCOARSE, AR5K_PHY_AGCCOARSE_HI, agc_coarse_hi, 1); -- OVERRIDE_WARNING(ah, AR5K_PHY_SIG, AR5K_PHY_SIG_FIRPWR, sig_firpwr, 1); --#endif -- -- SET_FIELD(ah, AR5K_PHY_AGCSIZE, AR5K_PHY_AGCSIZE_DESIRED, agc_desired_size); -- SET_FIELD(ah, AR5K_PHY_AGCCOARSE, AR5K_PHY_AGCCOARSE_LO, agc_coarse_lo); -- SET_FIELD(ah, AR5K_PHY_AGCCOARSE, AR5K_PHY_AGCCOARSE_HI, agc_coarse_hi); -- SET_FIELD(ah, AR5K_PHY_SIG, AR5K_PHY_SIG_FIRPWR, sig_firpwr); -- -- ath_hal_set_function(NULL); -- ath_hal_set_device(NULL); -- ATH_HAL_UNLOCK_IRQ(ah->ah_sc); --} -- --static inline void ath_hal_set_ofdm_weak_det(struct ath_hal *ah, -- int low_m1, int low_m2, int low_m2_count, int low_self_corr, -- int high_m1, int high_m2, int high_m2_count) --{ -- ATH_HAL_LOCK_IRQ(ah->ah_sc); -- ath_hal_set_function(__func__); -- ath_hal_set_device(SC_DEV_NAME(ah->ah_sc)); -- -- OVERRIDE_WARNING(ah, AR5K_PHY_WEAK_OFDM_LOW, AR5K_PHY_WEAK_OFDM_LOW_M1, low_m1, 0); -- OVERRIDE_WARNING(ah, AR5K_PHY_WEAK_OFDM_LOW, AR5K_PHY_WEAK_OFDM_LOW_M2, low_m2, 0); -- OVERRIDE_WARNING(ah, AR5K_PHY_WEAK_OFDM_LOW, AR5K_PHY_WEAK_OFDM_LOW_M2_COUNT, low_m2_count, 0); -- OVERRIDE_WARNING(ah, AR5K_PHY_WEAK_OFDM_LOW, AR5K_PHY_WEAK_OFDM_LOW_SELFCOR, low_self_corr, 0); -- OVERRIDE_WARNING(ah, AR5K_PHY_WEAK_OFDM_HIGH, AR5K_PHY_WEAK_OFDM_HIGH_M1, high_m1, 0); -- OVERRIDE_WARNING(ah, AR5K_PHY_WEAK_OFDM_HIGH, AR5K_PHY_WEAK_OFDM_HIGH_M2, high_m2, 0); -- OVERRIDE_WARNING(ah, AR5K_PHY_WEAK_OFDM_HIGH, AR5K_PHY_WEAK_OFDM_HIGH_M2_COUNT, high_m2_count, 0); -- -- SET_FIELD(ah, AR5K_PHY_WEAK_OFDM_LOW, AR5K_PHY_WEAK_OFDM_LOW_M1, low_m1); -- SET_FIELD(ah, AR5K_PHY_WEAK_OFDM_LOW, AR5K_PHY_WEAK_OFDM_LOW_M2, low_m2); -- SET_FIELD(ah, AR5K_PHY_WEAK_OFDM_LOW, AR5K_PHY_WEAK_OFDM_LOW_M2_COUNT, low_m2_count); -- SET_FIELD(ah, AR5K_PHY_WEAK_OFDM_LOW, AR5K_PHY_WEAK_OFDM_LOW_SELFCOR, low_self_corr); -- SET_FIELD(ah, AR5K_PHY_WEAK_OFDM_HIGH, AR5K_PHY_WEAK_OFDM_HIGH_M1, high_m1); -- SET_FIELD(ah, AR5K_PHY_WEAK_OFDM_HIGH, AR5K_PHY_WEAK_OFDM_HIGH_M2, high_m2); -- SET_FIELD(ah, AR5K_PHY_WEAK_OFDM_HIGH, AR5K_PHY_WEAK_OFDM_HIGH_M2_COUNT, high_m2_count); -- -- ath_hal_set_function(NULL); -- ath_hal_set_device(NULL); -- ATH_HAL_UNLOCK_IRQ(ah->ah_sc); --} -- --static inline void ath_hal_set_cck_weak_det(struct ath_hal *ah, int thresh) --{ -- ATH_HAL_LOCK_IRQ(ah->ah_sc); -- ath_hal_set_function(__func__); -- ath_hal_set_device(SC_DEV_NAME(ah->ah_sc)); -- -- OVERRIDE_WARNING(ah, AR5K_PHY_WEAK_CCK, AR5K_PHY_WEAK_CCK_THRESH, thresh, 0); -- -- SET_FIELD(ah, AR5K_PHY_WEAK_CCK, AR5K_PHY_WEAK_CCK_THRESH, thresh); -- -- ath_hal_set_function(NULL); -- ath_hal_set_device(NULL); -- ATH_HAL_UNLOCK_IRQ(ah->ah_sc); --} -- --static inline void ath_hal_set_sig_firstep(struct ath_hal *ah, int firstep) --{ -- ATH_HAL_LOCK_IRQ(ah->ah_sc); -- ath_hal_set_function(__func__); -- ath_hal_set_device(SC_DEV_NAME(ah->ah_sc)); - -- OVERRIDE_WARNING(ah, AR5K_PHY_SIG, AR5K_PHY_SIG_FIRSTEP, firstep, 0); -- -- SET_FIELD(ah, AR5K_PHY_SIG, AR5K_PHY_SIG_FIRSTEP, firstep); -- -- ath_hal_set_function(NULL); -- ath_hal_set_device(NULL); -- ATH_HAL_UNLOCK_IRQ(ah->ah_sc); --} -- --static inline void ath_hal_set_spur_immunity(struct ath_hal *ah, int thresh) --{ -- ATH_HAL_LOCK_IRQ(ah->ah_sc); -- ath_hal_set_function(__func__); -- ath_hal_set_device(SC_DEV_NAME(ah->ah_sc)); -- -- OVERRIDE_WARNING(ah, AR5K_PHY_SPUR, AR5K_PHY_SPUR_THRESH, thresh, 0); -- -- SET_FIELD(ah, AR5K_PHY_SPUR, AR5K_PHY_SPUR_THRESH, thresh); -- -- ath_hal_set_function(NULL); -- ath_hal_set_device(NULL); -- ATH_HAL_UNLOCK_IRQ(ah->ah_sc); --} -- --static inline void ath_hal_restore_default_noise_immunity(struct ath_hal *ah) { -- -- ath_hal_set_noise_immunity(ah, -- DEFAULT_AR5K_PHY_AGCSIZE_DESIRED, -- DEFAULT_AR5K_PHY_AGCCOARSE_HI, -- DEFAULT_AR5K_PHY_AGCCOARSE_LO, -- DEFAULT_AR5K_PHY_SIG_FIRPWR); --} -- --static inline void ath_hal_enable_ofdm_weak_det(struct ath_hal *ah, int enable) { -- if (enable) -- ath_hal_set_ofdm_weak_det(ah, -- AR5K_PHY_WEAK_OFDM_LOW_M1_ON, -- AR5K_PHY_WEAK_OFDM_LOW_M2_ON, -- AR5K_PHY_WEAK_OFDM_LOW_M2_COUNT_ON, -- AR5K_PHY_WEAK_OFDM_LOW_SELFCOR_ON, -- AR5K_PHY_WEAK_OFDM_HIGH_M1_ON, -- AR5K_PHY_WEAK_OFDM_HIGH_M2_ON, -- AR5K_PHY_WEAK_OFDM_HIGH_M2_COUNT_ON); -- else -- ath_hal_set_ofdm_weak_det(ah, -- AR5K_PHY_WEAK_OFDM_LOW_M1_OFF, -- AR5K_PHY_WEAK_OFDM_LOW_M2_OFF, -- AR5K_PHY_WEAK_OFDM_LOW_M2_COUNT_OFF, -- AR5K_PHY_WEAK_OFDM_LOW_SELFCOR_OFF, -- AR5K_PHY_WEAK_OFDM_HIGH_M1_OFF, -- AR5K_PHY_WEAK_OFDM_HIGH_M2_OFF, -- AR5K_PHY_WEAK_OFDM_HIGH_M2_COUNT_OFF); --} -- --static inline void ath_hal_enable_cck_weak_det(struct ath_hal *ah, int enable) { -- ath_hal_set_cck_weak_det(ah, enable -- ? AR5K_PHY_WEAK_CCK_THRESH_ON -- : AR5K_PHY_WEAK_CCK_THRESH_OFF); --} -- --static inline void ath_hal_restore_default_ofdm_weak_det(struct ath_hal *ah) { -- ath_hal_enable_ofdm_weak_det(ah, DEFAULT_ENABLE_AR5K_PHY_WEAK_OFDM); --} -- --static inline void ath_hal_restore_default_cck_weak_det(struct ath_hal *ah) { -- ath_hal_enable_cck_weak_det(ah, DEFAULT_ENABLE_AR5K_PHY_WEAK_CCK); --} -- --static inline void ath_hal_restore_default_sig_firstep(struct ath_hal *ah) { -- -- ath_hal_set_sig_firstep(ah, -- DEFAULT_AR5K_PHY_SIG_FIRSTEP); --} -- --static inline void ath_hal_restore_default_spur_immunity(struct ath_hal *ah) { -- -- ath_hal_set_spur_immunity(ah, -- DEFAULT_AR5K_PHY_SPUR_THRESH); --} -- --static inline void ath_hal_restore_default_intmit(struct ath_hal *ah) { -- ath_hal_restore_default_noise_immunity(ah); -- ath_hal_restore_default_ofdm_weak_det(ah); -- ath_hal_restore_default_cck_weak_det(ah); -- ath_hal_restore_default_sig_firstep(ah); -- ath_hal_restore_default_spur_immunity(ah); -- --} -- --static inline void ath_hal_verify_default_intmit(struct ath_hal *ah) { -- /* Just a list of all the fields above, for sanity checks... */ -- VERIFICATION_WARNING(ah, AR5K_PHY_AGCSIZE, AR5K_PHY_AGCSIZE_DESIRED, 1); -- VERIFICATION_WARNING(ah, AR5K_PHY_AGCCOARSE, AR5K_PHY_AGCCOARSE_LO, 1); -- VERIFICATION_WARNING(ah, AR5K_PHY_AGCCOARSE, AR5K_PHY_AGCCOARSE_HI, 1); -- VERIFICATION_WARNING(ah, AR5K_PHY_SIG, AR5K_PHY_SIG_FIRPWR, 1); -- VERIFICATION_WARNING_SW(ah, AR5K_PHY_WEAK_OFDM_LOW, AR5K_PHY_WEAK_OFDM_LOW_M1, 0); -- VERIFICATION_WARNING_SW(ah, AR5K_PHY_WEAK_OFDM_LOW, AR5K_PHY_WEAK_OFDM_LOW_M2, 0); -- VERIFICATION_WARNING_SW(ah, AR5K_PHY_WEAK_OFDM_LOW, AR5K_PHY_WEAK_OFDM_LOW_M2_COUNT, 0); -- VERIFICATION_WARNING_SW(ah, AR5K_PHY_WEAK_OFDM_LOW, AR5K_PHY_WEAK_OFDM_LOW_SELFCOR, 0); -- VERIFICATION_WARNING_SW(ah, AR5K_PHY_WEAK_OFDM_HIGH, AR5K_PHY_WEAK_OFDM_HIGH_M1, 0); -- VERIFICATION_WARNING_SW(ah, AR5K_PHY_WEAK_OFDM_HIGH, AR5K_PHY_WEAK_OFDM_HIGH_M2, 0); -- VERIFICATION_WARNING_SW(ah, AR5K_PHY_WEAK_OFDM_HIGH, AR5K_PHY_WEAK_OFDM_HIGH_M2_COUNT, 0); -- VERIFICATION_WARNING_SW(ah, AR5K_PHY_WEAK_CCK, AR5K_PHY_WEAK_CCK_THRESH, 0); -- VERIFICATION_WARNING(ah, AR5K_PHY_SIG, AR5K_PHY_SIG_FIRSTEP, 0); -- VERIFICATION_WARNING(ah, AR5K_PHY_SPUR, AR5K_PHY_SPUR_THRESH, 0); --} -+int ath_set_ack_bitrate(struct ath_softc *sc, int); -+int ar_device(int devid); -+const char * ath5k_chip_name(enum ath5k_srev_type type, u_int16_t val); - - static inline void ath_hal_set_dmasize_pcie(struct ath_hal *ah) { - SET_FIELD(ah, AR5K_TXCFG, AR5K_TXCFG_SDMAMR, AR5K_DMASIZE_128B); ---- a/ath/if_ath_hal.h -+++ b/ath/if_ath_hal.h -@@ -79,7 +79,7 @@ - ath_hal_set_function(__func__); - ath_hal_set_device(SC_DEV_NAME(ah->ah_sc)); - ret = -- ah->ah_getDiagState(ah, request, args, argsize, *result, -+ ah->ah_getDiagState(ah, request, args, argsize, result, - resultsize); - ath_hal_set_function(NULL); - ath_hal_set_device(NULL); ---- a/scripts/if_ath_hal_generator.pl -+++ b/scripts/if_ath_hal_generator.pl -@@ -145,7 +145,9 @@ - "ah_waitForBeaconDone" => "ath_hal_waitforbeacon", - "ah_writeAssocid" => "ath_hal_setassocid", - "ah_clrMulticastFilterIndex" => "ath_hal_clearmcastfilter", -- "ah_detectCardPresent" => "ath_hal_detectcardpresent" -+ "ah_detectCardPresent" => "ath_hal_detectcardpresent", -+ "ah_setSifsTime" => "ath_hal_setsifstime", -+ "ah_getSifsTime" => "ath_hal_getsifstime" - ); - - # -@@ -254,7 +256,7 @@ - - foreach (@parameters) { - s/ \*/\* /; -- /^((?:(?:const|struct|\*)\s*)*)([^\s]+\*?)\s*([^\s]*)\s*/; -+ /^((?:(?:const|struct|\*)\s*)*)([^\s]+\**)\s*([^\s]*)\s*/; - my $type = "$1$2"; - my $name = "$3"; - if ( 0 == length($name) ) { diff --git a/package/madwifi/patches-r3776/317-devid.patch b/package/madwifi/patches-r3776/317-devid.patch deleted file mode 100644 index 281e348f83..0000000000 --- a/package/madwifi/patches-r3776/317-devid.patch +++ /dev/null @@ -1,17 +0,0 @@ ---- a/ath/if_ath_pci.c -+++ b/ath/if_ath_pci.c -@@ -114,11 +114,13 @@ - { 0x168c, 0x0023, PCI_ANY_ID, PCI_ANY_ID }, - { 0x168c, 0x0024, PCI_ANY_ID, PCI_ANY_ID }, - { 0x168c, 0x9013, PCI_ANY_ID, PCI_ANY_ID }, /* sonicwall */ -+ { 0x168c, 0xff1a, PCI_ANY_ID, PCI_ANY_ID }, - { 0 } - }; - - static u16 ath_devidmap[][2] = { -- { 0x9013, 0x0013 } -+ { 0x9013, 0x0013 }, -+ { 0xff1a, 0x001a } - }; - - static int diff --git a/package/madwifi/patches-r3776/318-ifxmips_eeprom.patch b/package/madwifi/patches-r3776/318-ifxmips_eeprom.patch deleted file mode 100644 index 412ceadeb6..0000000000 --- a/package/madwifi/patches-r3776/318-ifxmips_eeprom.patch +++ /dev/null @@ -1,85 +0,0 @@ ---- a/ath_hal/ah_os.c -+++ b/ath_hal/ah_os.c -@@ -917,9 +917,56 @@ - * NB: see the comments in ah_osdep.h about byte-swapping register - * reads and writes to understand what's going on below. - */ -+ -+#ifdef CONFIG_IFXMIPS -+extern int ifxmips_has_brn_block(void); -+static int ifxmips_emulate = 0; -+#define EEPROM_EMULATION 1 -+#endif -+ -+#ifdef EEPROM_EMULATION -+static int ath_hal_eeprom(struct ath_hal *ah, unsigned long addr, int val, int write) -+{ -+ static int addrsel = 0; -+ static int rc = 0; -+ -+ if (write) { -+ if(addr == 0x6000) { -+ addrsel = val * 2; -+ rc = 0; -+ } -+ } else { -+ switch(addr) -+ { -+ case 0x600c: -+ if(rc++ < 2) -+ val = 0x00000000; -+ else -+ val = 0x00000002; -+ break; -+ case 0x6004: -+ val = cpu_to_le16(__raw_readw((u16 *) KSEG1ADDR(0xb07f0400 + addrsel))); -+ /* this forces the regdomain to 0x00 (worldwide), as the original setting -+ * causes issues with the HAL */ -+ if (addrsel == 0x17e) -+ val = 0; -+ break; -+ } -+ } -+ return val; -+} -+#endif -+ - void __ahdecl - ath_hal_reg_write(struct ath_hal *ah, u_int address, u_int32_t value) - { -+#ifdef EEPROM_EMULATION -+ if((address >= 0x6000) && (address <= 0x6010) && ifxmips_emulate) { -+ ath_hal_eeprom(ah, address, value, 1); -+ return; -+ } -+#endif -+ - _trace_regop(ah, REGOP_WRITE, address, value); - _OS_REG_WRITE(ah, address, value); - } -@@ -929,7 +976,14 @@ - u_int32_t __ahdecl - ath_hal_reg_read(struct ath_hal *ah, u_int address) - { -- u_int32_t val = _OS_REG_READ(ah, address); -+ u_int32_t val; -+ -+#ifdef EEPROM_EMULATION -+ if((address >= 0x6000) && (address <= 0x6010) && ifxmips_emulate) -+ val = ath_hal_eeprom(ah, address, 0, 0); -+ else -+#endif -+ val = _OS_REG_READ(ah, address); - _trace_regop(ah, REGOP_READ, address, val); - return val; - } -@@ -1123,6 +1177,9 @@ - #ifdef MMIOTRACE - kmmio_logmsg = _kmmio_logmsg; - #endif -+#ifdef CONFIG_IFXMIPS -+ ifxmips_emulate = ifxmips_has_brn_block(); -+#endif - - sep = ""; - for (i = 0; ath_hal_buildopts[i] != NULL; i++) { diff --git a/package/madwifi/patches-r3776/319-eap_auth_disassoc.patch b/package/madwifi/patches-r3776/319-eap_auth_disassoc.patch deleted file mode 100644 index a1d9b0ba4e..0000000000 --- a/package/madwifi/patches-r3776/319-eap_auth_disassoc.patch +++ /dev/null @@ -1,81 +0,0 @@ -This patch causes STA mode interfaces to disassociate if transmission of assoc/auth -critical packets failed. - -Signed-off-by: Felix Fietkau - ---- a/ath/if_ath.c -+++ b/ath/if_ath.c -@@ -8273,6 +8273,18 @@ - #endif - if (ts->ts_status & HAL_TXERR_XRETRY) { - sc->sc_stats.ast_tx_xretries++; -+ if (SKB_CB(bf->bf_skb)->auth_pkt && (ni->ni_vap->iv_opmode == IEEE80211_M_STA)) { -+ struct ieee80211com *ic = &sc->sc_ic; -+ -+ /* if roaming is enabled, try reassociating, otherwise -+ * disassociate and go back to the scan state */ -+ IEEE80211_VAPS_LOCK_BH(ic); -+ if (ic->ic_roaming == IEEE80211_ROAMING_AUTO) -+ ni->ni_vap->iv_newstate(ni->ni_vap, IEEE80211_S_ASSOC, 1); -+ else -+ ni->ni_vap->iv_newstate(ni->ni_vap, IEEE80211_S_SCAN, 0); -+ IEEE80211_VAPS_UNLOCK_BH(ic); -+ } - if (ni->ni_flags & IEEE80211_NODE_UAPSD_TRIG) { - ni->ni_stats.ns_tx_eosplost++; - DPRINTF(sc, ATH_DEBUG_UAPSD, ---- a/net80211/ieee80211_linux.c -+++ b/net80211/ieee80211_linux.c -@@ -158,6 +158,7 @@ - - SKB_NI(skb) = NULL; - SKB_CB(skb)->flags = 0; -+ SKB_CB(skb)->auth_pkt = 0; - - skb_reserve(skb, sizeof(struct ieee80211_frame)); - *frm = skb_put(skb, pktlen); ---- a/net80211/ieee80211_linux.h -+++ b/net80211/ieee80211_linux.h -@@ -411,6 +411,7 @@ - #define M_SKB_TRACKED 0x20 - void (*next_destructor)(struct sk_buff *skb); - #endif -+ u_int8_t auth_pkt; - }; - - struct __assert { ---- a/net80211/ieee80211_output.c -+++ b/net80211/ieee80211_output.c -@@ -773,6 +773,8 @@ - else - hdrsize = sizeof(struct ieee80211_frame); - -+ SKB_CB(skb)->auth_pkt = (eh.ether_type == __constant_htons(ETHERTYPE_PAE)); -+ - switch (vap->iv_opmode) { - case IEEE80211_M_IBSS: - case IEEE80211_M_AHDEMO: -@@ -1617,6 +1619,7 @@ - ie->param_len = frm - &ie->param_oui[0]; - return frm; - } -+ - #endif - /* - * Send a probe request frame with the specified ssid -@@ -1881,6 +1884,7 @@ - sizeof(u_int16_t)+IEEE80211_CHALLENGE_LEN : 0)); - if (skb == NULL) - senderr(ENOMEM, is_tx_nobuf); -+ SKB_CB(skb)->auth_pkt = 1; - - ((__le16 *)frm)[0] = - (is_shared_key) ? htole16(IEEE80211_AUTH_ALG_SHARED) -@@ -1955,6 +1959,7 @@ - vap->app_ie[IEEE80211_APPIE_FRAME_ASSOC_REQ].length); - if (skb == NULL) - senderr(ENOMEM, is_tx_nobuf); -+ SKB_CB(skb)->auth_pkt = 1; - - capinfo = 0; - if (vap->iv_opmode == IEEE80211_M_IBSS) diff --git a/package/madwifi/patches-r3776/320-hidden_ssid.patch b/package/madwifi/patches-r3776/320-hidden_ssid.patch deleted file mode 100644 index 92d0480d26..0000000000 --- a/package/madwifi/patches-r3776/320-hidden_ssid.patch +++ /dev/null @@ -1,38 +0,0 @@ -This patch fixes the detection of hidden SSIDs as transmitted -by some cisco systems. - -Signed-off-by: Felix Fietkau - ---- a/net80211/ieee80211_scan_sta.c -+++ b/net80211/ieee80211_scan_sta.c -@@ -209,6 +209,19 @@ - ieee80211_saveie(iep, ie); - } - -+ -+static inline int is_empty_ssid(u_int8_t *ssid) -+{ -+ if (!ssid) -+ return 1; -+ if (ssid[1] == 0) -+ return 1; -+ if ((ssid[1] == 1) && (ssid[2] == 0)) -+ return 1; -+ return 0; -+} -+ -+ - /* - * Process a beacon or probe response frame; create an - * entry in the scan cache or update any previous entry. -@@ -252,8 +265,8 @@ - ise = &se->base; - - /* XXX ap beaconing multiple ssid w/ same bssid */ -- if (sp->ssid[1] != 0 && -- (ISPROBE(subtype) || ise->se_ssid[1] == 0)) -+ if (!is_empty_ssid(sp->ssid) && -+ (ISPROBE(subtype) || is_empty_ssid(ise->se_ssid))) - memcpy(ise->se_ssid, sp->ssid, 2 + sp->ssid[1]); - - memcpy(ise->se_rates, sp->rates, diff --git a/package/madwifi/patches-r3776/321-bgscan_rssi_thresh.patch b/package/madwifi/patches-r3776/321-bgscan_rssi_thresh.patch deleted file mode 100644 index 7020305ea8..0000000000 --- a/package/madwifi/patches-r3776/321-bgscan_rssi_thresh.patch +++ /dev/null @@ -1,127 +0,0 @@ -Add an optional background scanning threshold triggered by low rssi -(useful for passing updated scan results to the supplicant ahead of -time, before losing connectivity entirely) - -Signed-off-by: Felix Fietkau - ---- a/net80211/ieee80211_ioctl.h -+++ b/net80211/ieee80211_ioctl.h -@@ -655,6 +655,7 @@ - IEEE80211_PARAM_MINRATE = 84, /* Minimum rate (by table index) */ - IEEE80211_PARAM_PROTMODE_RSSI = 85, /* RSSI Threshold for enabling protection mode */ - IEEE80211_PARAM_PROTMODE_TIMEOUT = 86, /* Timeout for expiring protection mode */ -+ IEEE80211_PARAM_BGSCAN_THRESH = 87, /* bg scan rssi threshold */ - }; - - #define SIOCG80211STATS (SIOCDEVPRIVATE+2) ---- a/net80211/ieee80211_var.h -+++ b/net80211/ieee80211_var.h -@@ -92,6 +92,8 @@ - #define IEEE80211_BGSCAN_IDLE_MIN 100 /* min idle time (ms) */ - #define IEEE80211_BGSCAN_IDLE_DEFAULT 250 /* default idle time (ms) */ - -+#define IEEE80211_BGSCAN_TRIGGER_INTVL 20 /* min trigger interval for thresh based bgscan (secs) */ -+ - #define IEEE80211_COVERAGE_CLASS_MAX 31 /* max coverage class */ - #define IEEE80211_REGCLASSIDS_MAX 10 /* max regclass id list */ - -@@ -229,6 +231,9 @@ - u_int8_t iv_nickname[IEEE80211_NWID_LEN]; - u_int iv_bgscanidle; /* bg scan idle threshold */ - u_int iv_bgscanintvl; /* bg scan min interval */ -+ u_int iv_bgscanthr; /* bg scan rssi threshold */ -+ u_int iv_bgscantrintvl; /* bg scan trigger interval */ -+ unsigned long iv_bgscanthr_next; /* last trigger for bgscan */ - u_int iv_scanvalid; /* scan cache valid threshold */ - struct ieee80211_roam iv_roam; /* sta-mode roaming state */ - -@@ -612,6 +617,7 @@ - #define IEEE80211_FEXT_SWBMISS 0x00000400 /* CONF: use software beacon timer */ - #define IEEE80211_FEXT_DROPUNENC_EAPOL 0x00000800 /* CONF: drop unencrypted eapol frames */ - #define IEEE80211_FEXT_APPIE_UPDATE 0x00001000 /* STATE: beacon APP IE updated */ -+#define IEEE80211_FEXT_BGSCAN_THR 0x00002000 /* bgscan due to low rssi */ - - #define IEEE80211_COM_UAPSD_ENABLE(_ic) ((_ic)->ic_flags_ext |= IEEE80211_FEXT_UAPSD) - #define IEEE80211_COM_UAPSD_DISABLE(_ic) ((_ic)->ic_flags_ext &= ~IEEE80211_FEXT_UAPSD) ---- a/net80211/ieee80211_wireless.c -+++ b/net80211/ieee80211_wireless.c -@@ -2778,6 +2778,9 @@ - else - retv = EINVAL; - break; -+ case IEEE80211_PARAM_BGSCAN_THRESH: -+ vap->iv_bgscanthr = value; -+ break; - case IEEE80211_PARAM_MCAST_RATE: - /* units are in KILObits per second */ - if (value >= 256 && value <= 54000) -@@ -3181,6 +3184,9 @@ - case IEEE80211_PARAM_BGSCAN_INTERVAL: - param[0] = vap->iv_bgscanintvl / HZ; /* seconds */ - break; -+ case IEEE80211_PARAM_BGSCAN_THRESH: -+ param[0] = vap->iv_bgscanthr; /* rssi */ -+ break; - case IEEE80211_PARAM_MCAST_RATE: - param[0] = vap->iv_mcast_rate; /* seconds */ - break; -@@ -5704,6 +5710,10 @@ - IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "bgscanintvl" }, - { IEEE80211_PARAM_BGSCAN_INTERVAL, - 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "get_bgscanintvl" }, -+ { IEEE80211_PARAM_BGSCAN_THRESH, -+ IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "bgscanthr" }, -+ { IEEE80211_PARAM_BGSCAN_THRESH, -+ 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "get_bgscanthr" }, - { IEEE80211_PARAM_MCAST_RATE, - IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "mcast_rate" }, - { IEEE80211_PARAM_MCAST_RATE, ---- a/net80211/ieee80211_input.c -+++ b/net80211/ieee80211_input.c -@@ -2984,8 +2984,10 @@ - { - struct ieee80211com *ic = vap->iv_ic; - -+ vap->iv_bgscantrintvl = (vap->iv_bgscantrintvl + 1) % 4; - return ((ic->ic_flags_ext & IEEE80211_FEXT_BGSCAN) && -- time_after(jiffies, ic->ic_lastdata + vap->iv_bgscanidle)); -+ (((ic->ic_flags_ext & IEEE80211_FEXT_BGSCAN_THR) && !vap->iv_bgscantrintvl) || -+ time_after(jiffies, ic->ic_lastdata + vap->iv_bgscanidle))); - } - - static __inline int -@@ -3229,6 +3231,23 @@ - /* record tsf of last beacon */ - memcpy(ni->ni_tstamp.data, scan.tstamp, - sizeof(ni->ni_tstamp)); -+ -+ /* When rssi is low, start doing bgscans more frequently to allow -+ * the supplicant to make a better switching decision */ -+ if ((rssi < vap->iv_bgscanthr) && -+ (!vap->iv_bgscanthr_next || -+ !time_before(jiffies, vap->iv_bgscanthr_next)) && -+ !(ic->ic_flags & IEEE80211_F_SCAN)) { -+ int ret; -+ -+ ic->ic_lastdata = 0; -+ ic->ic_lastscan = 0; -+ ic->ic_flags_ext |= IEEE80211_FEXT_BGSCAN_THR; -+ ret = ieee80211_bg_scan(vap); -+ if (ret) -+ vap->iv_bgscanthr_next = jiffies + msecs_to_jiffies(IEEE80211_BGSCAN_TRIGGER_INTVL * 1000); -+ } -+ - if (ni->ni_intval != scan.bintval) { - IEEE80211_NOTE(vap, IEEE80211_MSG_ASSOC, ni, - "beacon interval divergence: " ---- a/net80211/ieee80211_scan.c -+++ b/net80211/ieee80211_scan.c -@@ -793,7 +793,7 @@ - ieee80211_sta_pwrsave(vap, 0); - if (ss->ss_next >= ss->ss_last) { - ieee80211_notify_scan_done(vap); -- ic->ic_flags_ext &= ~IEEE80211_FEXT_BGSCAN; -+ ic->ic_flags_ext &= ~(IEEE80211_FEXT_BGSCAN|IEEE80211_FEXT_BGSCAN_THR); - } - } - SCAN_PRIVATE(ss)->ss_iflags &= ~ISCAN_CANCEL; diff --git a/package/madwifi/patches-r3776/322-ignore_broken_bssid.patch b/package/madwifi/patches-r3776/322-ignore_broken_bssid.patch deleted file mode 100644 index 0bae461f6b..0000000000 --- a/package/madwifi/patches-r3776/322-ignore_broken_bssid.patch +++ /dev/null @@ -1,18 +0,0 @@ -Some misconfigured APs broadcast NULL BSSIDs, which can confuse the STA -Ignore those when scanning. - -Signed-off-by: Felix Fietkau - ---- a/net80211/ieee80211_scan_sta.c -+++ b/net80211/ieee80211_scan_sta.c -@@ -242,6 +242,10 @@ - struct ieee80211_scan_entry *ise; - int hash; - -+ /* workaround for broken APs that broadcast NULL BSSIDs */ -+ if (memcmp(wh->i_addr3, "\x00\x00\x00\x00\x00\x00", 6) == 0) -+ return 0; -+ - hash = STA_HASH(macaddr); - SCAN_STA_LOCK_IRQ(st); - LIST_FOREACH(se, &st->st_hash[hash], se_hash) diff --git a/package/madwifi/patches-r3776/323-crash_fix.patch b/package/madwifi/patches-r3776/323-crash_fix.patch deleted file mode 100644 index 2da3bf3525..0000000000 --- a/package/madwifi/patches-r3776/323-crash_fix.patch +++ /dev/null @@ -1,21 +0,0 @@ ---- a/net80211/ieee80211_node.c -+++ b/net80211/ieee80211_node.c -@@ -1999,11 +1999,13 @@ - /* From this point onwards we can no longer find the node, - * so no more references are generated - */ -- ieee80211_remove_wds_addr(nt, ni->ni_macaddr); -- ieee80211_del_wds_node(nt, ni); -- IEEE80211_NODE_TABLE_LOCK_IRQ(nt); -- node_table_leave_locked(nt, ni); -- IEEE80211_NODE_TABLE_UNLOCK_IRQ(nt); -+ if (nt) { -+ ieee80211_remove_wds_addr(nt, ni->ni_macaddr); -+ ieee80211_del_wds_node(nt, ni); -+ IEEE80211_NODE_TABLE_LOCK_IRQ(nt); -+ node_table_leave_locked(nt, ni); -+ IEEE80211_NODE_TABLE_UNLOCK_IRQ(nt); -+ } - - /* - * If node wasn't previously associated all diff --git a/package/madwifi/patches-r3776/324-reassoc.patch b/package/madwifi/patches-r3776/324-reassoc.patch deleted file mode 100644 index 7d1ade3dd7..0000000000 --- a/package/madwifi/patches-r3776/324-reassoc.patch +++ /dev/null @@ -1,31 +0,0 @@ -Add a preliminary fix for the reassoc check, but disable reassoc entirely for now -until we've figured out why it fails frequently. - -Signed-off-by: Felix Fietkau - ---- a/net80211/ieee80211_node.c -+++ b/net80211/ieee80211_node.c -@@ -561,10 +561,9 @@ - EXPORT_SYMBOL(ieee80211_ibss_merge); - - static __inline int --ssid_equal(const struct ieee80211_node *a, const struct ieee80211_node *b) -+bssid_equal(const struct ieee80211_node *a, const struct ieee80211_node *b) - { -- return (a->ni_esslen == b->ni_esslen && -- memcmp(a->ni_essid, b->ni_essid, a->ni_esslen) == 0); -+ return (memcmp(a->ni_bssid, b->ni_bssid, IEEE80211_ADDR_LEN) == 0); - } - - /* -@@ -596,8 +595,8 @@ - * Check if old+new node have the same ssid in which - * case we can reassociate when operating in sta mode. - */ -- canreassoc = ((obss != NULL) && -- (vap->iv_state == IEEE80211_S_RUN) && ssid_equal(obss, selbs)); -+ canreassoc = 0; /* ((obss != NULL) && -+ (vap->iv_state == IEEE80211_S_RUN) && bssid_equal(obss, selbs)); */ - vap->iv_bss = selbs; - IEEE80211_ADDR_COPY(vap->iv_bssid, selbs->ni_bssid); - if (obss != NULL) diff --git a/package/madwifi/patches-r3776/325-sta_node_leave.patch b/package/madwifi/patches-r3776/325-sta_node_leave.patch deleted file mode 100644 index 6b0dcb8e80..0000000000 --- a/package/madwifi/patches-r3776/325-sta_node_leave.patch +++ /dev/null @@ -1,59 +0,0 @@ -Drop stale AP nodes from the client list when disconnecting. -Fixes some reassoc issues. - -Signed-off-by: Felix Fietkau - ---- a/net80211/ieee80211_proto.c -+++ b/net80211/ieee80211_proto.c -@@ -1352,7 +1352,7 @@ - IEEE80211_SEND_MGMT(ni, - IEEE80211_FC0_SUBTYPE_DISASSOC, - IEEE80211_REASON_ASSOC_LEAVE); -- ieee80211_sta_leave(ni); -+ ieee80211_node_leave(ni); - break; - case IEEE80211_M_HOSTAP: - ieee80211_iterate_nodes(&ic->ic_sta, -@@ -1362,6 +1362,7 @@ - break; - } - goto reset; -+ case IEEE80211_S_AUTH: - case IEEE80211_S_ASSOC: - switch (vap->iv_opmode) { - case IEEE80211_M_STA: -@@ -1380,7 +1381,6 @@ - case IEEE80211_S_SCAN: - ieee80211_cancel_scan(vap); - goto reset; -- case IEEE80211_S_AUTH: - reset: - ieee80211_reset_bss(vap); - break; -@@ -1436,7 +1436,7 @@ - break; - case IEEE80211_S_RUN: /* beacon miss */ - if (vap->iv_opmode == IEEE80211_M_STA) { -- ieee80211_sta_leave(ni); -+ ieee80211_node_leave(ni); - vap->iv_flags &= ~IEEE80211_F_SIBSS; /* XXX */ - if (ic->ic_roaming == IEEE80211_ROAMING_AUTO) - ieee80211_check_scan(vap, -@@ -1487,7 +1487,7 @@ - vap->iv_state = ostate; /* stay RUN */ - break; - case IEEE80211_FC0_SUBTYPE_DEAUTH: -- ieee80211_sta_leave(ni); -+ ieee80211_node_leave(ni); - if (ic->ic_roaming == IEEE80211_ROAMING_AUTO) { - /* try to reauth */ - IEEE80211_SEND_MGMT(ni, -@@ -1514,7 +1514,7 @@ - IEEE80211_FC0_SUBTYPE_ASSOC_REQ, 0); - break; - case IEEE80211_S_RUN: -- ieee80211_sta_leave(ni); -+ ieee80211_node_leave(ni); - if (ic->ic_roaming == IEEE80211_ROAMING_AUTO) { - /* NB: caller specifies ASSOC/REASSOC by arg */ - IEEE80211_SEND_MGMT(ni, arg ? diff --git a/package/madwifi/patches-r3776/326-bmiss_handling.patch b/package/madwifi/patches-r3776/326-bmiss_handling.patch deleted file mode 100644 index 0c72630503..0000000000 --- a/package/madwifi/patches-r3776/326-bmiss_handling.patch +++ /dev/null @@ -1,102 +0,0 @@ -Improve the beacon miss handling. Instead of just dropping the connection, -send a directed probe request to the AP to see if it's still responding. -Schedule a software beacon miss timer in this case, which adds a timeout -for the APs probe response. - -Signed-off-by: Felix Fietkau - ---- a/net80211/ieee80211_input.c -+++ b/net80211/ieee80211_input.c -@@ -3369,12 +3369,17 @@ - } - - /* WDS/Repeater: re-schedule software beacon timer for -- * STA. */ -- if ((vap->iv_state == IEEE80211_S_RUN) && -- (vap->iv_flags_ext & IEEE80211_FEXT_SWBMISS)) { -- mod_timer(&vap->iv_swbmiss, -+ * STA. Reset consecutive bmiss counter as well */ -+ IEEE80211_LOCK_IRQ(ic); -+ if (vap->iv_state == IEEE80211_S_RUN) { -+ vap->iv_bmiss_count = 0; -+ if (vap->iv_flags_ext & IEEE80211_FEXT_SWBMISS) -+ mod_timer(&vap->iv_swbmiss, - jiffies + vap->iv_swbmiss_period); -+ else -+ del_timer(&vap->iv_swbmiss); - } -+ IEEE80211_UNLOCK_IRQ(ic); - - /* If scanning, pass the info to the scan module. - * Otherwise, check if it's the right time to do ---- a/net80211/ieee80211_proto.c -+++ b/net80211/ieee80211_proto.c -@@ -1213,6 +1213,8 @@ - } - /* XXX locking */ - TAILQ_FOREACH(vap, &ic->ic_vaps, iv_next) { -+ int count; -+ - IEEE80211_DPRINTF(vap, - IEEE80211_MSG_STATE | IEEE80211_MSG_DEBUG, - "%s\n", "beacon miss"); -@@ -1225,6 +1227,29 @@ - if (vap->iv_opmode != IEEE80211_M_STA || - vap->iv_state != IEEE80211_S_RUN) - continue; -+ -+ IEEE80211_LOCK_IRQ(ic); -+ count = vap->iv_bmiss_count++; -+ if (count) { -+ /* if the counter was already above zero, reset it -+ * here, since we're going to do the bmiss handling -+ * in any case */ -+ vap->iv_bmiss_count = 0; -+ } else { -+ /* schedule the software beacon miss timer, it will be -+ * cancelled, if the probe request is acked */ -+ mod_timer(&vap->iv_swbmiss, jiffies + vap->iv_swbmiss_period); -+ } -+ IEEE80211_UNLOCK_IRQ(ic); -+ -+ if (!count) { -+ ieee80211_send_probereq(vap->iv_bss, vap->iv_myaddr, -+ vap->iv_bss->ni_bssid, vap->iv_bss->ni_bssid, -+ vap->iv_bss->ni_essid, vap->iv_bss->ni_esslen, -+ NULL, 0); -+ continue; -+ } -+ - if (ic->ic_roaming == IEEE80211_ROAMING_AUTO) { - #ifdef ATH_SUPERG_DYNTURBO - /* -@@ -1621,14 +1646,14 @@ - } - - /* WDS/Repeater: Start software beacon timer for STA */ -+ vap->iv_swbmiss.function = ieee80211_sta_swbmiss; -+ vap->iv_swbmiss.data = (unsigned long) vap; -+ vap->iv_swbmiss_period = IEEE80211_TU_TO_JIFFIES( -+ vap->iv_ic->ic_bmissthreshold * ni->ni_intval); -+ - if (ostate != IEEE80211_S_RUN && - (vap->iv_opmode == IEEE80211_M_STA && - vap->iv_flags_ext & IEEE80211_FEXT_SWBMISS)) { -- vap->iv_swbmiss.function = ieee80211_sta_swbmiss; -- vap->iv_swbmiss.data = (unsigned long) vap; -- vap->iv_swbmiss_period = IEEE80211_TU_TO_JIFFIES( -- vap->iv_ic->ic_bmissthreshold * ni->ni_intval); -- - mod_timer(&vap->iv_swbmiss, jiffies + vap->iv_swbmiss_period); - } - ---- a/net80211/ieee80211_var.h -+++ b/net80211/ieee80211_var.h -@@ -292,6 +292,7 @@ - - struct timer_list iv_swbmiss; /* software beacon miss timer */ - u_int16_t iv_swbmiss_period; /* software beacon miss timer period */ -+ u_int16_t iv_bmiss_count; /* consecutive beacon miss counter */ - struct ieee80211_nsparams iv_nsparams; /* new state parameters for tasklet for stajoin1 */ - struct IEEE80211_TQ_STRUCT iv_stajoin1tq; /* tasklet for newstate action called from stajoin1tq */ - unsigned int iv_nsdone; /* Done with scheduled newstate tasklet */ diff --git a/package/madwifi/patches-r3776/327-rssi_disconnect.patch b/package/madwifi/patches-r3776/327-rssi_disconnect.patch deleted file mode 100644 index b7e406cb04..0000000000 --- a/package/madwifi/patches-r3776/327-rssi_disconnect.patch +++ /dev/null @@ -1,91 +0,0 @@ -Add an optional threshold for low-rssi disconnection. This can be useful -when letting wpa_supplicant control roaming. - -Signed-off-by: Felix Fietkau - ---- a/net80211/ieee80211_ioctl.h -+++ b/net80211/ieee80211_ioctl.h -@@ -656,6 +656,8 @@ - IEEE80211_PARAM_PROTMODE_RSSI = 85, /* RSSI Threshold for enabling protection mode */ - IEEE80211_PARAM_PROTMODE_TIMEOUT = 86, /* Timeout for expiring protection mode */ - IEEE80211_PARAM_BGSCAN_THRESH = 87, /* bg scan rssi threshold */ -+ IEEE80211_PARAM_RSSI_DIS_THR = 88, /* rssi threshold for disconnection */ -+ IEEE80211_PARAM_RSSI_DIS_COUNT = 89, /* counter for rssi threshold */ - }; - - #define SIOCG80211STATS (SIOCDEVPRIVATE+2) ---- a/net80211/ieee80211_wireless.c -+++ b/net80211/ieee80211_wireless.c -@@ -2832,6 +2832,12 @@ - case IEEE80211_PARAM_ROAM_RATE_11G: - vap->iv_roam.rate11g = value; - break; -+ case IEEE80211_PARAM_RSSI_DIS_THR: -+ vap->iv_rssi_dis_thr = value; -+ break; -+ case IEEE80211_PARAM_RSSI_DIS_COUNT: -+ vap->iv_rssi_dis_max = value; -+ break; - case IEEE80211_PARAM_UAPSDINFO: - if (vap->iv_opmode == IEEE80211_M_HOSTAP) { - if (ic->ic_caps & IEEE80211_C_UAPSD) { -@@ -3220,6 +3226,12 @@ - case IEEE80211_PARAM_ROAM_RATE_11G: - param[0] = vap->iv_roam.rate11g; - break; -+ case IEEE80211_PARAM_RSSI_DIS_THR: -+ param[0] = vap->iv_rssi_dis_thr; -+ break; -+ case IEEE80211_PARAM_RSSI_DIS_COUNT: -+ param[0] = vap->iv_rssi_dis_max; -+ break; - case IEEE80211_PARAM_UAPSDINFO: - if (vap->iv_opmode == IEEE80211_M_HOSTAP) { - if (IEEE80211_VAP_UAPSD_ENABLED(vap)) -@@ -5770,6 +5782,14 @@ - IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "rate11g_x2" }, - { IEEE80211_PARAM_ROAM_RATE_11G, - 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "get_rate11g_x2" }, -+ { IEEE80211_PARAM_RSSI_DIS_THR, -+ IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "rssi_disthr" }, -+ { IEEE80211_PARAM_RSSI_DIS_THR, -+ 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "get_rssi_disthr" }, -+ { IEEE80211_PARAM_RSSI_DIS_COUNT, -+ IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "rssi_discnt" }, -+ { IEEE80211_PARAM_RSSI_DIS_COUNT, -+ 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "get_rssi_discnt" }, - { IEEE80211_PARAM_UAPSDINFO, - IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "uapsd" }, - { IEEE80211_PARAM_UAPSDINFO, ---- a/net80211/ieee80211_input.c -+++ b/net80211/ieee80211_input.c -@@ -3234,6 +3234,17 @@ - - /* When rssi is low, start doing bgscans more frequently to allow - * the supplicant to make a better switching decision */ -+ if ((vap->iv_rssi_dis_thr > 0) && (vap->iv_rssi_dis_max > 0)) { -+ if ((rssi > 0) && (rssi < vap->iv_rssi_dis_thr)) { -+ if (++vap->iv_rssi_dis_trig > vap->iv_rssi_dis_max) { -+ vap->iv_rssi_dis_trig = 0; -+ ieee80211_node_leave(ni); -+ return 0; -+ } -+ } else { -+ vap->iv_rssi_dis_trig = 0; -+ } -+ } - if ((rssi < vap->iv_bgscanthr) && - (!vap->iv_bgscanthr_next || - !time_before(jiffies, vap->iv_bgscanthr_next)) && ---- a/net80211/ieee80211_var.h -+++ b/net80211/ieee80211_var.h -@@ -233,6 +233,9 @@ - u_int iv_bgscanintvl; /* bg scan min interval */ - u_int iv_bgscanthr; /* bg scan rssi threshold */ - u_int iv_bgscantrintvl; /* bg scan trigger interval */ -+ u_int iv_rssi_dis_thr; /* rssi disassoc threshold */ -+ u_int iv_rssi_dis_max; /* max beacons below disconnect threshold */ -+ u_int iv_rssi_dis_trig; /* rssi disassoc trigger count */ - unsigned long iv_bgscanthr_next; /* last trigger for bgscan */ - u_int iv_scanvalid; /* scan cache valid threshold */ - struct ieee80211_roam iv_roam; /* sta-mode roaming state */ diff --git a/package/madwifi/patches-r3776/328-memory_alloc.patch b/package/madwifi/patches-r3776/328-memory_alloc.patch deleted file mode 100644 index ff60dbdb37..0000000000 --- a/package/madwifi/patches-r3776/328-memory_alloc.patch +++ /dev/null @@ -1,11 +0,0 @@ ---- a/ath/if_ath.c -+++ b/ath/if_ath.c -@@ -504,7 +504,7 @@ - - /* Allocate space for dynamically determined maximum VAP count */ - sc->sc_bslot = -- kzalloc(ath_maxvaps * sizeof(struct ieee80211vap), GFP_KERNEL); -+ kzalloc(ath_maxvaps * sizeof(struct ieee80211vap *), GFP_KERNEL); - - /* - * Cache line size is used to size and align various diff --git a/package/madwifi/patches-r3776/329-turbo_chansearch.patch b/package/madwifi/patches-r3776/329-turbo_chansearch.patch deleted file mode 100644 index ba8b01c12f..0000000000 --- a/package/madwifi/patches-r3776/329-turbo_chansearch.patch +++ /dev/null @@ -1,10 +0,0 @@ ---- a/net80211/ieee80211.c -+++ b/net80211/ieee80211.c -@@ -695,6 +695,7 @@ - int i; - - /* Brute force search */ -+ flags &= IEEE80211_CHAN_ALLTURBO; - for (i = 0; i < ic->ic_nchans; i++) { - c = &ic->ic_channels[i]; - if (c->ic_freq == freq && diff --git a/package/madwifi/patches-r3776/330-bstuck_thresh.patch b/package/madwifi/patches-r3776/330-bstuck_thresh.patch deleted file mode 100644 index 5f864bb59f..0000000000 --- a/package/madwifi/patches-r3776/330-bstuck_thresh.patch +++ /dev/null @@ -1,52 +0,0 @@ ---- a/ath/if_ath.c -+++ b/ath/if_ath.c -@@ -354,6 +354,7 @@ - static int ath_outdoor = AH_FALSE; /* enable outdoor use */ - static int ath_xchanmode = AH_TRUE; /* enable extended channels */ - static int ath_maxvaps = ATH_MAXVAPS_DEFAULT; /* set default maximum vaps */ -+static int bstuck_thresh = BSTUCK_THRESH; /* Stuck beacon count required for reset */ - static char *autocreate = "sta"; - static char *ratectl = DEF_RATE_CTL; - static int rfkill = 0; -@@ -397,6 +398,7 @@ - #ifdef ATH_CAP_TPC - MODULE_PARM(hal_tpc, "i"); - #endif -+MODULE_PARM(bstuck_thresh, "i"); - MODULE_PARM(autocreate, "s"); - MODULE_PARM(ratectl, "s"); - #else -@@ -410,6 +412,7 @@ - #ifdef ATH_CAP_TPC - module_param(hal_tpc, int, 0600); - #endif -+module_param(bstuck_thresh, int, 0600); - module_param(autocreate, charp, 0600); - module_param(ratectl, charp, 0600); - #endif -@@ -422,6 +425,7 @@ - MODULE_PARM_DESC(hal_tpc, "Disables manual per-packet transmit power control and " - "lets this be managed by the HAL. Default is OFF."); - #endif -+MODULE_PARM_DESC(bstuck_thresh, "Override default stuck beacon threshold"); - MODULE_PARM_DESC(autocreate, "Create ath device in " - "[sta|ap|wds|adhoc|ahdemo|monitor] mode. defaults to sta, use " - "'none' to disable"); -@@ -5239,7 +5243,7 @@ - DPRINTF(sc, ATH_DEBUG_BEACON_PROC, - "Missed %u consecutive beacons (n_beacon=%u)\n", - sc->sc_bmisscount, n_beacon); -- if (sc->sc_bmisscount > BSTUCK_THRESH) -+ if (sc->sc_bmisscount > bstuck_thresh) - ATH_SCHEDULE_TQUEUE(&sc->sc_bstucktq, needmark); - return; - } -@@ -5410,7 +5414,7 @@ - * check will be true, in which case return - * without resetting the driver. - */ -- if (sc->sc_bmisscount <= BSTUCK_THRESH) -+ if (sc->sc_bmisscount <= bstuck_thresh) - return; - EPRINTF(sc, "Stuck beacon; resetting (beacon miss count: %u)\n", - sc->sc_bmisscount); diff --git a/package/madwifi/patches-r3776/331-linux24_fix.patch b/package/madwifi/patches-r3776/331-linux24_fix.patch deleted file mode 100644 index 1d9a2d06c1..0000000000 --- a/package/madwifi/patches-r3776/331-linux24_fix.patch +++ /dev/null @@ -1,15 +0,0 @@ ---- a/ath_hal/Makefile -+++ b/ath_hal/Makefile -@@ -79,10 +79,11 @@ - quiet_cmd_uudecode = UUDECODE $@ - cmd_uudecode = $(obj)/uudecode -o $@ $< - --$(obj)/$(TARGET).hal.o: $(HAL)/public/$(TARGET).hal.o.uu $(obj)/uudecode - ifdef LINUX24 -+$(TARGET).hal.o: $(HAL)/public/$(TARGET).hal.o.uu $(obj)/uudecode - $(Q)$(obj)/uudecode -o $@ $< - else -+$(obj)/$(TARGET).hal.o: $(HAL)/public/$(TARGET).hal.o.uu $(obj)/uudecode - $(call if_changed,uudecode) - endif - # Replace as many hashed names as possible with meaningful diff --git a/package/madwifi/patches-r3776/332-retransmit_check.patch b/package/madwifi/patches-r3776/332-retransmit_check.patch deleted file mode 100644 index ec1fcf9c72..0000000000 --- a/package/madwifi/patches-r3776/332-retransmit_check.patch +++ /dev/null @@ -1,22 +0,0 @@ ---- a/net80211/ieee80211.h -+++ b/net80211/ieee80211.h -@@ -174,8 +174,6 @@ - #define IEEE80211_SEQ_SEQ_MASK 0xfff0 - #define IEEE80211_SEQ_SEQ_SHIFT 4 - --#define IEEE80211_SEQ_LEQ(a,b) ((int)((a)-(b)) <= 0) -- - #define IEEE80211_NWID_LEN 32 - - #define IEEE80211_QOS_TXOP 0x00ff ---- a/net80211/ieee80211_input.c -+++ b/net80211/ieee80211_input.c -@@ -406,7 +406,7 @@ - tid = 0; - rxseq = le16toh(*(__le16 *)wh->i_seq); - if ((wh->i_fc[1] & IEEE80211_FC1_RETRY) && -- IEEE80211_SEQ_LEQ(rxseq, ni->ni_rxseqs[tid])) { -+ (rxseq == ni->ni_rxseqs[tid])) { - /* duplicate, discard */ - IEEE80211_DISCARD_MAC(vap, IEEE80211_MSG_INPUT, - bssid, "duplicate", diff --git a/package/madwifi/patches-r3776/333-hal_init_msg.patch b/package/madwifi/patches-r3776/333-hal_init_msg.patch deleted file mode 100644 index 1369dcfc19..0000000000 --- a/package/madwifi/patches-r3776/333-hal_init_msg.patch +++ /dev/null @@ -1,30 +0,0 @@ ---- a/ath_hal/ah_os.c -+++ b/ath_hal/ah_os.c -@@ -1136,9 +1136,6 @@ - * Module glue. - */ - #include "version.h" --#if 0 --static char *dev_info = "ath_hal"; --#endif - - MODULE_AUTHOR("Errno Consulting, Sam Leffler"); - MODULE_DESCRIPTION("Atheros Hardware Access Layer (HAL)"); -@@ -1172,7 +1169,7 @@ - static int __init - init_ath_hal(void) - { -- const char *sep; -+ const char *sep = ""; - int i; - #ifdef MMIOTRACE - kmmio_logmsg = _kmmio_logmsg; -@@ -1181,7 +1178,7 @@ - ifxmips_emulate = ifxmips_has_brn_block(); - #endif - -- sep = ""; -+ printk(KERN_INFO "hal: %s (", ath_hal_version); - for (i = 0; ath_hal_buildopts[i] != NULL; i++) { - printk("%s%s", sep, ath_hal_buildopts[i]); - sep = ", "; diff --git a/package/madwifi/patches-testing/102-multicall_binary.patch b/package/madwifi/patches-testing/102-multicall_binary.patch new file mode 100644 index 0000000000..7ddd45632b --- /dev/null +++ b/package/madwifi/patches-testing/102-multicall_binary.patch @@ -0,0 +1,359 @@ +--- a/tools/80211debug.c ++++ b/tools/80211debug.c +@@ -48,6 +48,7 @@ + #include + #include + #include ++#include "do_multi.h" + + #undef ARRAY_SIZE + #define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0])) +@@ -185,7 +186,7 @@ + #endif /* __linux__ */ + + int +-main(int argc, char *argv[]) ++CMD(a80211debug)(int argc, char *argv[]) + { + const char *ifname = "ath0"; + const char *cp, *tp; +--- a/tools/80211stats.c ++++ b/tools/80211stats.c +@@ -59,6 +59,7 @@ + #include "net80211/ieee80211.h" + #include "net80211/ieee80211_crypto.h" + #include "net80211/ieee80211_ioctl.h" ++#include "do_multi.h" + + #ifndef SIOCG80211STATS + #define SIOCG80211STATS (SIOCDEVPRIVATE + 2) +@@ -241,7 +242,7 @@ + } + + int +-main(int argc, char *argv[]) ++CMD(a80211stats)(int argc, char *argv[]) + { + int c, len; + struct ieee80211req_sta_info *si; +--- a/tools/athchans.c ++++ b/tools/athchans.c +@@ -58,6 +58,7 @@ + #include "net80211/ieee80211.h" + #include "net80211/ieee80211_crypto.h" + #include "net80211/ieee80211_ioctl.h" ++#include "do_multi.h" + + static int s = -1; + static const char *progname; +@@ -140,8 +141,9 @@ + } + + #define MAXCHAN ((int)(sizeof(struct ieee80211req_chanlist) * NBBY)) ++ + int +-main(int argc, char *argv[]) ++CMD(athchans)(int argc, char *argv[]) + { + const char *ifname = "wifi0"; + struct ieee80211req_chanlist chanlist; +--- a/tools/athctrl.c ++++ b/tools/athctrl.c +@@ -52,6 +52,7 @@ + #include + + #include ++#include "do_multi.h" + + static int + setsysctrl(const char *dev, const char *control , u_long value) +@@ -88,7 +89,7 @@ + } + + int +-main(int argc, char *argv[]) ++CMD(athctrl)(int argc, char *argv[]) + { + char device[IFNAMSIZ + 1]; + int distance = -1; +--- a/tools/athdebug.c ++++ b/tools/athdebug.c +@@ -51,6 +51,7 @@ + #include + #include + #include ++#include "do_multi.h" + + #undef ARRAY_SIZE + #define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0])) +@@ -194,7 +195,7 @@ + #endif /* __linux__ */ + + int +-main(int argc, char *argv[]) ++CMD(athdebug)(int argc, char *argv[]) + { + #ifdef __linux__ + const char *ifname = "wifi0"; +--- a/tools/athkey.c ++++ b/tools/athkey.c +@@ -58,6 +58,7 @@ + #include "net80211/ieee80211.h" + #include "net80211/ieee80211_crypto.h" + #include "net80211/ieee80211_ioctl.h" ++#include "do_multi.h" + + static int s = -1; + static const char *progname; +@@ -213,8 +214,7 @@ + exit(-1); + } + +-int +-main(int argc, char *argv[]) ++int CMD(athkey)(int argc, char *argv[]) + { + const char *ifname = "wifi0"; + struct ieee80211req_key setkey; +--- a/tools/athstats.c ++++ b/tools/athstats.c +@@ -65,6 +65,7 @@ + + #undef ARRAY_SIZE + #define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0])) ++#include "do_multi.h" + + static const struct { + u_int phyerr; +@@ -228,7 +229,7 @@ + } + + int +-main(int argc, char *argv[]) ++CMD(athstats)(int argc, char *argv[]) + { + #ifdef __linux__ + const char *ifname = "wifi0"; +--- /dev/null ++++ b/tools/do_multi.c +@@ -0,0 +1,36 @@ ++#include ++#include "do_multi.h" ++ ++int ++main(int argc, char *argv[]) ++{ ++ char *progname; ++ int ret = 0; ++ ++ progname = basename(argv[0]); ++ ++ if(strcmp(progname, "80211debug") == 0) ++ ret = a80211debug_init(argc, argv); ++ if(strcmp(progname, "80211stats") == 0) ++ ret = a80211stats_init(argc, argv); ++ if(strcmp(progname, "athchans") == 0) ++ ret = athchans_init(argc, argv); ++ if(strcmp(progname, "athctrl") == 0) ++ ret = athctrl_init(argc, argv); ++ if(strcmp(progname, "athdebug") == 0) ++ ret = athdebug_init(argc, argv); ++ if(strcmp(progname, "athkey") == 0) ++ ret = athkey_init(argc, argv); ++ if(strcmp(progname, "athstats") == 0) ++ ret = athstats_init(argc, argv); ++ if(strcmp(progname, "wlanconfig") == 0) ++ ret = wlanconfig_init(argc, argv); ++ if(strcmp(progname, "wpakey") == 0) ++ ret = wpakey_init(argc, argv); ++ if(strcmp(progname, "athchans") == 0) ++ ret = athchans_init(argc, argv); ++ if(strcmp(progname, "ath_info") == 0) ++ ret = athinfo_init(argc, argv); ++ ++ return ret; ++} +--- /dev/null ++++ b/tools/do_multi.h +@@ -0,0 +1,15 @@ ++#ifdef DO_MULTI ++int a80211debug_init(int argc, char *argv[]); ++int a80211stats_init(int argc, char *argv[]); ++int athchans_init(int argc, char *argv[]); ++int athctrl_init(int argc, char *argv[]); ++int athdebug_init(int argc, char *argv[]); ++int athkey_init(int argc, char *argv[]); ++int athstats_init(int argc, char *argv[]); ++int wlanconfig_init(int argc, char *argv[]); ++int athinfo_init(int argc, char *argv[]); ++ ++#define CMD(name) name##_init ++#else ++#define CMD(name) main ++#endif +--- a/tools/Makefile ++++ b/tools/Makefile +@@ -50,42 +50,43 @@ + PROGRAMS = athstats 80211stats athkey athchans athctrl \ + athdebug 80211debug wlanconfig wpakey + ++OBJS = $(patsubst %,%.o,$(PROGRAMS)) ath_info/ath_info.o + SUBDIRS = ath_info + +-INCS = -I. -I$(HAL) -I$(TOP) -I$(ATH_HAL) ++INCS = -I. -I$(HAL) -I$(TOP) -I$(ATH_HAL) -I$(TOP)/ath + CFLAGS = -g -O2 -Wall + ALL_CFLAGS = $(CFLAGS) $(INCS) + LDFLAGS = + +-all: all-subdirs $(PROGRAMS) ++all: all-subdirs compile + + all-subdirs: + for d in $(SUBDIRS); do \ + $(MAKE) -C $$d || exit 1; \ + done + +-athstats: athstats.c +- $(CC) -o athstats $(ALL_CFLAGS) -I$(TOP)/ath $(LDFLAGS) athstats.c +-80211stats: 80211stats.c +- $(CC) -o 80211stats $(ALL_CFLAGS) $(LDFLAGS) 80211stats.c +-athkey: athkey.c +- $(CC) -o athkey $(ALL_CFLAGS) $(LDFLAGS) athkey.c +-athchans: athchans.c +- $(CC) -o athchans $(ALL_CFLAGS) $(LDFLAGS) athchans.c +-athctrl: athctrl.c +- $(CC) -o athctrl $(ALL_CFLAGS) $(LDFLAGS) athctrl.c +-athdebug: athdebug.c +- $(CC) -o athdebug $(ALL_CFLAGS) $(LDFLAGS) athdebug.c +-wlanconfig: wlanconfig.c +- $(CC) -o wlanconfig $(ALL_CFLAGS) $(LDFLAGS) wlanconfig.c +-80211debug: 80211debug.c +- $(CC) -o 80211debug $(ALL_CFLAGS) $(LDFLAGS) 80211debug.c +-wpakey: wpakey.c +- $(CC) -o wpakey $(ALL_CFLAGS) $(LDFLAGS) wpakey.c ++%.o: %.c ++ ${CC} $(ALL_CFLAGS) -c -o $@ $< ++ ++ifneq ($(DO_MULTI),) ++ALL_CFLAGS += -DDO_MULTI=1 ++madwifi_multi: $(OBJS) do_multi.o ++ $(CC) $(LDFLAGS) -o $@ $^ ++ ++compile: madwifi_multi ++ for i in $(PROGRAMS); do \ ++ ln -sf madwifi_multi $$i; \ ++ done ++else ++$(PROGRAMS): ++ $(CC) $(ALL_CFLAGS) -o $@ $@.c ++ ++compile: $(PROGRAMS) ++endif + + install: all + install -d $(DESTDIR)$(BINDIR) +- for i in $(PROGRAMS); do \ ++ for i in $(PROGRAMS) $(if $(DO_MULTI),madwifi_multi); do \ + install $$i $(DESTDIR)$(BINDIR)/$$i; \ + $(STRIP) $(DESTDIR)$(BINDIR)/$$i; \ + done +@@ -97,7 +98,7 @@ + done + + uninstall: +- for i in $(PROGRAMS); do \ ++ for i in $(PROGRAMS) $(if $(DO_MULTI),madwifi_multi); do \ + rm -f $(DESTDIR)$(BINDIR)/$$i; \ + done + for i in $(PROGRAMS:=.8); do \ +@@ -108,7 +109,7 @@ + done + + clean: +- rm -f $(PROGRAMS) core a.out ++ rm -f $(if $(DO_MULTI), madwifi_multi) $(PROGRAMS) core a.out *.o + for d in $(SUBDIRS); do \ + $(MAKE) -C $$d clean; \ + done +--- a/tools/wlanconfig.c ++++ b/tools/wlanconfig.c +@@ -61,6 +61,7 @@ + #include "net80211/ieee80211.h" + #include "net80211/ieee80211_crypto.h" + #include "net80211/ieee80211_ioctl.h" ++#include "do_multi.h" + + /* + * These are taken from ieee80211_node.h +@@ -100,7 +101,7 @@ + static int verbose = 0; + + int +-main(int argc, char *argv[]) ++CMD(wlanconfig)(int argc, char *argv[]) + { + const char *ifname, *cmd; + unsigned char bnounit = 0; +--- a/tools/ath_info/Makefile ++++ b/tools/ath_info/Makefile +@@ -17,11 +17,18 @@ + + all: $(PROGRAMS) + ++ ++ifneq ($(DO_MULTI),) ++ath_info: ath_info.o ++ rm -f $@ ++ ln -s ../madwifi_multi $@ ++else + ath_info: ath_info.o + $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $< ++endif + + .c.o: +- $(CC) $(CFLAGS) -c $< ++ $(CC) $(CFLAGS) $(if $(DO_MULTI),-DDO_MULTI=1 -I..) -c $< + + clean: + rm -f *.o $(PROGRAMS) +--- a/tools/ath_info/ath_info.c ++++ b/tools/ath_info/ath_info.c +@@ -28,6 +28,7 @@ + #include + #include + #include ++#include "do_multi.h" + + #undef ARRAY_SIZE + #define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0])) +@@ -1982,7 +1983,8 @@ + printf("\n"); + } + +-int main(int argc, char *argv[]) ++int ++CMD(athinfo)(int argc, char *argv[]) + { + unsigned long long dev_addr; + u_int16_t srev, phy_rev_5ghz, phy_rev_2ghz, ee_magic; +--- a/tools/wpakey.c ++++ b/tools/wpakey.c +@@ -25,6 +25,7 @@ + + #include + #include ++#include "do_multi.h" + + #define MACS "%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx" + #define MACP(mac) (mac)[0], (mac)[1], (mac)[2], (mac)[3], (mac)[4], (mac)[5] +@@ -234,7 +235,8 @@ + "", dev); + } + +-int main(int argc, char** argv) { ++int ++CMD(wpakey)(int argc, char** argv) { + int keyidx = 0; + uint8_t mac[6]; + int cipher = IEEE80211_CIPHER_AES_CCM; diff --git a/package/madwifi/patches-testing/104-autocreate_none.patch b/package/madwifi/patches-testing/104-autocreate_none.patch new file mode 100644 index 0000000000..16ce6e8639 --- /dev/null +++ b/package/madwifi/patches-testing/104-autocreate_none.patch @@ -0,0 +1,11 @@ +--- a/ath/if_ath.c ++++ b/ath/if_ath.c +@@ -482,7 +482,7 @@ + HAL_STATUS status; + int error = 0; + unsigned int i; +- int autocreatemode = IEEE80211_M_STA; ++ int autocreatemode = -1; + u_int8_t csz; + + sc->devid = devid; diff --git a/package/madwifi/patches-testing/105-ratectl_attach.patch b/package/madwifi/patches-testing/105-ratectl_attach.patch new file mode 100644 index 0000000000..79b08dfb82 --- /dev/null +++ b/package/madwifi/patches-testing/105-ratectl_attach.patch @@ -0,0 +1,23 @@ +--- a/net80211/ieee80211_rate.c ++++ b/net80211/ieee80211_rate.c +@@ -100,8 +100,18 @@ + ieee80211_load_module(buf); + + if (!ratectls[id].attach) { +- printk(KERN_ERR "Error loading module \"%s\"\n", buf); +- return NULL; ++ /* pick the first available rate control module */ ++ printk(KERN_INFO "Rate control module \"%s\" not available\n", buf); ++ for (id = 0; id < IEEE80211_RATE_MAX; id++) { ++ if (ratectls[id].attach) ++ break; ++ } ++ if (!ratectls[id].attach) { ++ printk(KERN_ERR "No rate control module available"); ++ return NULL; ++ } else { ++ printk(KERN_INFO "Using \"%s\" instead.\n", module_names[id]); ++ } + } + + ctl = ratectls[id].attach(sc); diff --git a/package/madwifi/patches-testing/111-minstrel_crash.patch b/package/madwifi/patches-testing/111-minstrel_crash.patch new file mode 100644 index 0000000000..dd96c4e60f --- /dev/null +++ b/package/madwifi/patches-testing/111-minstrel_crash.patch @@ -0,0 +1,12 @@ +--- a/ath_rate/minstrel/minstrel.c ++++ b/ath_rate/minstrel/minstrel.c +@@ -415,6 +415,9 @@ + return; + } + ++ if (sn->num_rates <= 0) ++ return; ++ + if (sn->is_sampling) { + sn->is_sampling = 0; + if (sn->rs_sample_rate_slower) diff --git a/package/madwifi/patches-testing/122-replayfail_workaround.patch b/package/madwifi/patches-testing/122-replayfail_workaround.patch new file mode 100644 index 0000000000..de5a8f3160 --- /dev/null +++ b/package/madwifi/patches-testing/122-replayfail_workaround.patch @@ -0,0 +1,12 @@ +--- a/net80211/ieee80211_linux.c ++++ b/net80211/ieee80211_linux.c +@@ -330,6 +330,9 @@ + k->wk_cipher->ic_name, k->wk_keyix, + (unsigned long long)rsc); + ++ /* disabled for now due to bogus events for unknown reasons */ ++ return; ++ + /* TODO: needed parameters: count, keyid, key type, src address, TSC */ + snprintf(buf, sizeof(buf), "%s(keyid=%d %scast addr=" MAC_FMT ")", tag, + k->wk_keyix, diff --git a/package/madwifi/patches-testing/123-ccmp_checks.patch b/package/madwifi/patches-testing/123-ccmp_checks.patch new file mode 100644 index 0000000000..6db9c2d781 --- /dev/null +++ b/package/madwifi/patches-testing/123-ccmp_checks.patch @@ -0,0 +1,22 @@ +--- a/net80211/ieee80211_crypto_ccmp.c ++++ b/net80211/ieee80211_crypto_ccmp.c +@@ -478,6 +478,9 @@ + uint8_t *mic, *pos; + u_int space; + ++ if (ctx->cc_tfm == NULL) ++ return 0; ++ + ctx->cc_vap->iv_stats.is_crypto_ccmp++; + + skb = skb0; +@@ -592,6 +595,9 @@ + uint8_t *pos, *mic; + u_int space; + ++ if (ctx->cc_tfm == NULL) ++ return 0; ++ + ctx->cc_vap->iv_stats.is_crypto_ccmp++; + + skb = skb0; diff --git a/package/madwifi/patches-testing/124-linux24_compat.patch b/package/madwifi/patches-testing/124-linux24_compat.patch new file mode 100644 index 0000000000..2ab9364b96 --- /dev/null +++ b/package/madwifi/patches-testing/124-linux24_compat.patch @@ -0,0 +1,202 @@ +--- a/ath/if_athvar.h ++++ b/ath/if_athvar.h +@@ -129,6 +129,11 @@ + #define ATH_GET_NETDEV_DEV(ndev) ((ndev)->class_dev.dev) + #endif + ++#ifndef NETDEV_TX_OK ++#define NETDEV_TX_OK 0 ++#define NETDEV_TX_BUSY 1 ++#endif ++ + #if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,23) + static inline struct net_device *_alloc_netdev(int sizeof_priv, const char *mask, + void (*setup)(struct net_device *)) +--- a/ath/if_ath_radar.c ++++ b/ath/if_ath_radar.c +@@ -89,6 +89,13 @@ + #define nofloat_pct(_value, _pct) \ + ( (_value * (1000 + _pct)) / 1000 ) + ++#ifndef list_for_each_entry_reverse ++#define list_for_each_entry_reverse(pos, head, member) \ ++ for (pos = list_entry((head)->prev, typeof(*pos), member); \ ++ prefetch(pos->member.prev), &pos->member != (head); \ ++ pos = list_entry(pos->member.prev, typeof(*pos), member)) ++#endif ++ + struct radar_pattern_specification { + /* The name of the rule/specification (i.e. what did we detect) */ + const char *name; +--- a/ath/if_ath.c ++++ b/ath/if_ath.c +@@ -4878,6 +4878,46 @@ + return (txqs & (1 << qnum)); + } + ++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,15) ++static inline int atomic_cmpxchg(atomic_t *v, int old, int new) ++{ ++ int ret; ++ unsigned long flags; ++ ++ local_irq_save(flags); ++ ret = v->counter; ++ if (likely(ret == old)) ++ v->counter = new; ++ local_irq_restore(flags); ++ ++ return ret; ++} ++ ++/** ++ * atomic_add_unless - add unless the number is a given value ++ * @v: pointer of type atomic_t ++ * @a: the amount to add to v... ++ * @u: ...unless v is equal to u. ++ * ++ * Atomically adds @a to @v, so long as it was not @u. ++ * Returns non-zero if @v was not @u, and zero otherwise. ++ */ ++static __inline__ int atomic_add_unless(atomic_t *v, int a, int u) ++{ ++ int c, old; ++ c = atomic_read(v); ++ for (;;) { ++ if (unlikely(c == (u))) ++ break; ++ old = atomic_cmpxchg((v), c, c + (a)); ++ if (likely(old == c)) ++ break; ++ c = old; ++ } ++ return c != (u); ++} ++#endif ++ + /* + * Generate beacon frame and queue cab data for a VAP. + */ +--- /dev/null ++++ b/net80211/sort.c +@@ -0,0 +1,120 @@ ++/* ++ * A fast, small, non-recursive O(nlog n) sort for the Linux kernel ++ * ++ * Jan 23 2005 Matt Mackall ++ */ ++ ++#include ++#include ++#include ++ ++static void u32_swap(void *a, void *b, int size) ++{ ++ u32 t = *(u32 *)a; ++ *(u32 *)a = *(u32 *)b; ++ *(u32 *)b = t; ++} ++ ++static void generic_swap(void *a, void *b, int size) ++{ ++ char t; ++ ++ do { ++ t = *(char *)a; ++ *(char *)a++ = *(char *)b; ++ *(char *)b++ = t; ++ } while (--size > 0); ++} ++ ++/** ++ * sort - sort an array of elements ++ * @base: pointer to data to sort ++ * @num: number of elements ++ * @size: size of each element ++ * @cmp: pointer to comparison function ++ * @swap: pointer to swap function or NULL ++ * ++ * This function does a heapsort on the given array. You may provide a ++ * swap function optimized to your element type. ++ * ++ * Sorting time is O(n log n) both on average and worst-case. While ++ * qsort is about 20% faster on average, it suffers from exploitable ++ * O(n*n) worst-case behavior and extra memory requirements that make ++ * it less suitable for kernel use. ++ */ ++ ++static void sort(void *base, size_t num, size_t size, ++ int (*cmp)(const void *, const void *), ++ void (*swap)(void *, void *, int size)) ++{ ++ /* pre-scale counters for performance */ ++ int i = (num/2 - 1) * size, n = num * size, c, r; ++ ++ if (!swap) ++ swap = (size == 4 ? u32_swap : generic_swap); ++ ++ /* heapify */ ++ for ( ; i >= 0; i -= size) { ++ for (r = i; r * 2 + size < n; r = c) { ++ c = r * 2 + size; ++ if (c < n - size && cmp(base + c, base + c + size) < 0) ++ c += size; ++ if (cmp(base + r, base + c) >= 0) ++ break; ++ swap(base + r, base + c, size); ++ } ++ } ++ ++ /* sort */ ++ for (i = n - size; i >= 0; i -= size) { ++ swap(base, base + i, size); ++ for (r = 0; r * 2 + size < i; r = c) { ++ c = r * 2 + size; ++ if (c < i - size && cmp(base + c, base + c + size) < 0) ++ c += size; ++ if (cmp(base + r, base + c) >= 0) ++ break; ++ swap(base + r, base + c, size); ++ } ++ } ++} ++ ++EXPORT_SYMBOL(sort); ++ ++#if 0 ++/* a simple boot-time regression test */ ++ ++int cmpint(const void *a, const void *b) ++{ ++ return *(int *)a - *(int *)b; ++} ++ ++static int sort_test(void) ++{ ++ int *a, i, r = 1; ++ ++ a = kmalloc(1000 * sizeof(int), GFP_KERNEL); ++ BUG_ON(!a); ++ ++ printk("testing sort()\n"); ++ ++ for (i = 0; i < 1000; i++) { ++ r = (r * 725861) % 6599; ++ a[i] = r; ++ } ++ ++ sort(a, 1000, sizeof(int), cmpint, NULL); ++ ++ for (i = 0; i < 999; i++) ++ if (a[i] > a[i+1]) { ++ printk("sort() failed!\n"); ++ break; ++ } ++ ++ kfree(a); ++ ++ return 0; ++} ++ ++module_init(sort_test); ++#endif diff --git a/package/madwifi/patches-testing/126-rxerr_frames.patch b/package/madwifi/patches-testing/126-rxerr_frames.patch new file mode 100644 index 0000000000..f95124135a --- /dev/null +++ b/package/madwifi/patches-testing/126-rxerr_frames.patch @@ -0,0 +1,27 @@ +--- a/ath/if_ath.c ++++ b/ath/if_ath.c +@@ -6451,9 +6451,6 @@ + rs = &bf->bf_dsstatus.ds_rxstat; + + len = rs->rs_datalen; +- /* DMA sync. dies spectacularly if len == 0 */ +- if (len == 0) +- goto rx_next; + if (rs->rs_more) { + /* Frame spans multiple descriptors; this + * cannot happen yet as we don't support +@@ -6513,8 +6510,12 @@ + * setup again to receive another frame. + * NB: Meta-data (rs, noise, tsf) in the ath_buf is still + * used. */ +- bus_dma_sync_single(sc->sc_bdev, +- bf->bf_skbaddr, len, BUS_DMA_FROMDEVICE); ++ ++ /* DMA sync. dies spectacularly if len == 0 */ ++ if (len != 0) { ++ bus_dma_sync_single(sc->sc_bdev, ++ bf->bf_skbaddr, len, BUS_DMA_FROMDEVICE); ++ } + skb = ath_rxbuf_take_skb(sc, bf); + + sc->sc_stats.ast_ant_rx[rs->rs_antenna]++; diff --git a/package/madwifi/patches-testing/200-no_debug.patch b/package/madwifi/patches-testing/200-no_debug.patch new file mode 100644 index 0000000000..0797f8fb65 --- /dev/null +++ b/package/madwifi/patches-testing/200-no_debug.patch @@ -0,0 +1,420 @@ +--- a/ath/if_ath.c ++++ b/ath/if_ath.c +@@ -323,8 +323,10 @@ + static void ath_set_dfs_cac_time(struct ieee80211com *, unsigned int seconds); + + static unsigned int ath_test_radar(struct ieee80211com *); +-static unsigned int ath_dump_hal_map(struct ieee80211com *ic); ++#ifdef AR_DEBUG + ++static unsigned int ath_dump_hal_map(struct ieee80211com *ic); ++#endif + static u_int32_t ath_get_clamped_maxtxpower(struct ath_softc *sc); + static u_int32_t ath_set_clamped_maxtxpower(struct ath_softc *sc, + u_int32_t new_clamped_maxtxpower); +@@ -334,7 +336,10 @@ + unsigned int param, unsigned int value); + + static u_int32_t ath_get_real_maxtxpower(struct ath_softc *sc); ++ ++#ifdef AR_DEBUG + static int ath_txq_check(struct ath_softc *sc, struct ath_txq *txq, const char *msg); ++#endif + + static int ath_countrycode = CTRY_DEFAULT; /* country code */ + static int ath_outdoor = AH_FALSE; /* enable outdoor use */ +@@ -486,9 +491,11 @@ + u_int8_t csz; + + sc->devid = devid; ++#ifdef AR_DEBUG + ath_debug_global = (ath_debug & ATH_DEBUG_GLOBAL); + sc->sc_debug = (ath_debug & ~ATH_DEBUG_GLOBAL); + DPRINTF(sc, ATH_DEBUG_ANY, "%s: devid 0x%x\n", __func__, devid); ++#endif + + /* Allocate space for dynamically determined maximum VAP count */ + sc->sc_bslot = +@@ -1014,7 +1021,9 @@ + ic->ic_vap_delete = ath_vap_delete; + + ic->ic_test_radar = ath_test_radar; ++#ifdef AR_DEBUG + ic->ic_dump_hal_map = ath_dump_hal_map; ++#endif + + ic->ic_set_dfs_testmode = ath_set_dfs_testmode; + ic->ic_get_dfs_testmode = ath_get_dfs_testmode; +@@ -1285,12 +1294,14 @@ + /* If no default VAP debug flags are passed, allow a few to + * transfer down from the driver to new VAPs so we can have load + * time debugging for VAPs too. */ ++#ifdef AR_DEBUG + vap->iv_debug = 0 | + ((sc->sc_debug & ATH_DEBUG_RATE) ? IEEE80211_MSG_XRATE : 0) | + ((sc->sc_debug & ATH_DEBUG_XMIT) ? IEEE80211_MSG_OUTPUT : 0) | + ((sc->sc_debug & ATH_DEBUG_RECV) ? IEEE80211_MSG_INPUT : 0) | + 0 + ; ++#endif + } + ic->ic_debug = (sc->sc_default_ieee80211_debug & IEEE80211_MSG_IC); + +@@ -2811,6 +2822,7 @@ + #endif + } + ++#ifdef AR_DEBUG + static void + ath_txq_dump(struct ath_softc *sc, struct ath_txq *txq) + { +@@ -2866,6 +2878,7 @@ + + return 1; + } ++#endif + + /* + * Insert a buffer on a txq +@@ -8384,7 +8397,9 @@ + ath_tx_timeout(struct net_device *dev) + { + struct ath_softc *sc = dev->priv; ++#ifdef AR_DEBUG + int i; ++#endif + + if (ath_chan_unavail(sc)) + return; +@@ -8393,12 +8408,14 @@ + (dev->flags & IFF_RUNNING) ? "" : "NOT ", + sc->sc_invalid ? "in" : ""); + ++#ifdef AR_DEBUG + for (i = 0; i < HAL_NUM_TX_QUEUES; i++) { + if (ATH_TXQ_SETUP(sc, i)) { + ath_txq_check(sc, &sc->sc_txq[i], __func__); + ath_txq_dump(sc, &sc->sc_txq[i]); + } + } ++#endif + + if ((dev->flags & IFF_RUNNING) && !sc->sc_invalid) { + sc->sc_stats.ast_watchdog++; +@@ -10638,6 +10655,7 @@ + /* XXX validate? */ + sc->sc_ledpin = val; + break; ++#ifdef AR_DEBUG + case ATH_DEBUG: + sc->sc_debug = (val & ~ATH_DEBUG_GLOBAL); + ath_debug_global = (val & ATH_DEBUG_GLOBAL); +@@ -10645,6 +10663,7 @@ + "0x%08x.\n", val); + + break; ++#endif + case ATH_TXANTENNA: + /* + * antenna can be: +@@ -10818,9 +10837,11 @@ + case ATH_REGDOMAIN: + ath_hal_getregdomain(ah, &val); + break; ++#ifdef AR_DEBUG + case ATH_DEBUG: + val = sc->sc_debug | ath_debug_global; + break; ++#endif + case ATH_TXANTENNA: + val = sc->sc_txantenna; + break; +@@ -11939,6 +11960,7 @@ + } + + /* This is called by a private ioctl (iwpriv) to dump the HAL obfuscation table */ ++#ifdef AR_DEBUG + static unsigned int + ath_dump_hal_map(struct ieee80211com *ic) + { +@@ -11947,7 +11969,7 @@ + ath_hal_dump_map(sc->sc_ah); + return 0; + } +- ++#endif + /* If we are shutting down or blowing off the DFS channel availability check + * then we call this to stop the behavior before we take the rest of the + * necessary actions (such as a DFS reaction to radar). */ +--- a/ath_rate/amrr/amrr.c ++++ b/ath_rate/amrr/amrr.c +@@ -70,7 +70,9 @@ + + #include "amrr.h" + ++#ifdef AR_DEBUG + #define AMRR_DEBUG ++#endif + #ifdef AMRR_DEBUG + #define DPRINTF(sc, _fmt, ...) do { \ + if (sc->sc_debug & 0x10) \ +--- a/ath_rate/minstrel/minstrel.c ++++ b/ath_rate/minstrel/minstrel.c +@@ -117,7 +117,9 @@ + + #include "minstrel.h" + ++#ifdef AR_DEBUG + #define MINSTREL_DEBUG ++#endif + #ifdef MINSTREL_DEBUG + enum { + ATH_DEBUG_RATE = 0x00000010 /* rate control */ +@@ -963,7 +965,9 @@ + (struct ieee80211_node_table *)&vap->iv_ic->ic_sta; + unsigned int x = 0; + unsigned int this_tp, this_prob, this_eprob; +- struct ath_softc *sc = vap->iv_ic->ic_dev->priv;; ++#ifdef AR_DEBUG ++ struct ath_softc *sc = vap->iv_ic->ic_dev->priv; ++#endif + + IEEE80211_NODE_TABLE_LOCK_IRQ(nt); + TAILQ_FOREACH(ni, &nt->nt_node, ni_list) { +--- a/ath_rate/onoe/onoe.c ++++ b/ath_rate/onoe/onoe.c +@@ -66,7 +66,9 @@ + + #include "onoe.h" + ++#ifdef AR_DEBUG + #define ONOE_DEBUG ++#endif + #ifdef ONOE_DEBUG + enum { + ATH_DEBUG_RATE = 0x00000010, /* rate control */ +--- a/ath_rate/sample/sample.c ++++ b/ath_rate/sample/sample.c +@@ -68,7 +68,9 @@ + + #include "sample.h" + +-#define SAMPLE_DEBUG ++#ifdef AR_DEBUG ++#define SAMPLE_DEBUG ++#endif + #ifdef SAMPLE_DEBUG + enum { + ATH_DEBUG_RATE = 0x00000010, /* rate control */ +--- a/tools/do_multi.c ++++ b/tools/do_multi.c +@@ -9,16 +9,20 @@ + + progname = basename(argv[0]); + ++#ifdef AR_DEBUG + if(strcmp(progname, "80211debug") == 0) + ret = a80211debug_init(argc, argv); ++#endif + if(strcmp(progname, "80211stats") == 0) + ret = a80211stats_init(argc, argv); + if(strcmp(progname, "athchans") == 0) + ret = athchans_init(argc, argv); + if(strcmp(progname, "athctrl") == 0) + ret = athctrl_init(argc, argv); ++#ifdef AR_DEBUG + if(strcmp(progname, "athdebug") == 0) + ret = athdebug_init(argc, argv); ++#endif + if(strcmp(progname, "athkey") == 0) + ret = athkey_init(argc, argv); + if(strcmp(progname, "athstats") == 0) +--- a/tools/Makefile ++++ b/tools/Makefile +@@ -39,6 +39,10 @@ + + ATH_HAL = $(TOP)/ath_hal + ++ifndef ATH_DEBUG ++ATH_DEBUG=1 ++endif ++ + # + # Path to the HAL source code. + # +@@ -46,17 +50,22 @@ + HAL = $(TOP)/hal + endif + ++INCS = -I. -I$(HAL) -I$(TOP) -I$(ATH_HAL) -I$(TOP)/ath ++CFLAGS = -g -O2 -Wall ++ALL_CFLAGS = $(CFLAGS) $(INCS) ++LDFLAGS = + + PROGRAMS = athstats 80211stats athkey athchans athctrl \ +- athdebug 80211debug wlanconfig wpakey ++ wlanconfig wpakey ++ ++ifeq ($(ATH_DEBUG),1) ++ PROGRAMS += athdebug 80211debug ++ ALL_CFLAGS += -DAR_DEBUG ++endif + + OBJS = $(patsubst %,%.o,$(PROGRAMS)) ath_info/ath_info.o + SUBDIRS = ath_info + +-INCS = -I. -I$(HAL) -I$(TOP) -I$(ATH_HAL) -I$(TOP)/ath +-CFLAGS = -g -O2 -Wall +-ALL_CFLAGS = $(CFLAGS) $(INCS) +-LDFLAGS = + + all: all-subdirs compile + +--- a/ath/if_ath_hal.h ++++ b/ath/if_ath_hal.h +@@ -1263,6 +1263,7 @@ + + tail -f /var/log/messages | sed -f hal_unmangle.sed + */ ++#ifdef AR_DEBUG + static inline void ath_hal_dump_map(struct ath_hal *ah) + { + #ifdef CONFIG_KALLSYMS +@@ -1527,7 +1528,7 @@ + #endif /* #ifndef CONFIG_KALLSYMS */ + + } +- ++#endif + #include "if_ath_hal_wrappers.h" + #include "if_ath_hal_extensions.h" + +--- a/net80211/ieee80211_var.h ++++ b/net80211/ieee80211_var.h +@@ -495,9 +495,10 @@ + /* inject a fake radar signal -- used while on a 802.11h DFS channels */ + unsigned int (*ic_test_radar)(struct ieee80211com *); + ++#ifdef AR_DEBUG + /* dump HAL */ + unsigned int (*ic_dump_hal_map)(struct ieee80211com *); +- ++#endif + /* DFS channel availability check time (in seconds) */ + void (*ic_set_dfs_cac_time)(struct ieee80211com *, unsigned int); + unsigned int (*ic_get_dfs_cac_time)(struct ieee80211com *); +--- a/net80211/ieee80211_wireless.c ++++ b/net80211/ieee80211_wireless.c +@@ -1557,6 +1557,7 @@ + return 0; + } + ++#ifdef AR_DEBUG + static int + ieee80211_ioctl_hal_map(struct net_device *dev, struct iw_request_info *info, + void *w, char *extra) +@@ -1567,7 +1568,7 @@ + params[0] = ic->ic_dump_hal_map(ic); + return 0; + } +- ++#endif + + static int + ieee80211_ioctl_radar(struct net_device *dev, struct iw_request_info *info, +@@ -5296,8 +5297,10 @@ + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getwmmparams" }, + { IEEE80211_IOCTL_RADAR, + 0, 0, "doth_radar" }, ++#ifdef AR_DEBUG + { IEEE80211_IOCTL_HALMAP, + 0, 0, "dump_hal_map" }, ++#endif + /* + * These depends on sub-ioctl support which added in version 12. + */ +@@ -5751,7 +5754,9 @@ + set_priv(IEEE80211_IOCTL_SETMLME, ieee80211_ioctl_setmlme), + set_priv(IEEE80211_IOCTL_SETKEY, ieee80211_ioctl_setkey), + set_priv(IEEE80211_IOCTL_DELKEY, ieee80211_ioctl_delkey), ++#ifdef AR_DEBUG + set_priv(IEEE80211_IOCTL_HALMAP, ieee80211_ioctl_hal_map), ++#endif + set_priv(IEEE80211_IOCTL_ADDMAC, ieee80211_ioctl_addmac), + set_priv(IEEE80211_IOCTL_DELMAC, ieee80211_ioctl_delmac), + set_priv(IEEE80211_IOCTL_WDSADDMAC, ieee80211_ioctl_wdsmac), +--- a/ath/if_ath_debug.h ++++ b/ath/if_ath_debug.h +@@ -54,6 +54,10 @@ + ATH_DEBUG_GLOBAL = (ATH_DEBUG_SKB|ATH_DEBUG_SKB_REF) + }; + ++#define EPRINTF(_sc, _fmt, ...) \ ++ printk(KERN_ERR "%s: %s: " _fmt, \ ++ SC_DEV_NAME(_sc), __func__, ## __VA_ARGS__) ++ + #ifdef AR_DEBUG + + /* DEBUG-ONLY DEFINITIONS */ +@@ -68,20 +72,9 @@ + ath_keyprint((_sc), __func__, _ix, _hk, _mac); \ + } while (0) + +-#else /* #ifdef AR_DEBUG */ +- +-#define DFLAG_ISSET(sc, _m) 0 +-#define DPRINTF(sc, _m, _fmt, ...) +-#define KEYPRINTF(sc, k, ix, mac) +- +-#endif /* #ifdef AR_DEBUG */ + + #define IFF_DUMPPKTS(_sc, _m) DFLAG_ISSET((_sc), (_m)) + +-#define EPRINTF(_sc, _fmt, ...) \ +- printk(KERN_ERR "%s: %s: " _fmt, \ +- SC_DEV_NAME(_sc), __func__, ## __VA_ARGS__) +- + #define WPRINTF(_sc, _fmt, ...) \ + printk(KERN_WARNING "%s: %s: " _fmt, \ + SC_DEV_NAME(_sc), __func__, ## __VA_ARGS__) +@@ -89,5 +82,14 @@ + #define IPRINTF(_sc, _fmt, ...) \ + printk(KERN_INFO "%s: %s: " _fmt, \ + SC_DEV_NAME(_sc), __func__, ## __VA_ARGS__) ++#else ++#define DFLAG_ISSET(sc, _m) 0 ++#define DPRINTF(sc, _m, _fmt, ...) ++#define KEYPRINTF(sc, k, ix, mac) ++#define WPRINTF(...) ++#define IPRINTF(...) ++#define IFF_DUMPPKTS(...) 0 ++ ++#endif + + #endif /* #ifndef _IF_ATH_DEBUG_H_ */ +--- a/ath/if_ath_pci.c ++++ b/ath/if_ath_pci.c +@@ -134,8 +134,10 @@ + u16 vdevice; + int i; + +- if (pci_enable_device(pdev)) ++ if (pci_enable_device(pdev)) { ++ printk(KERN_ERR "%s: failed to enable PCI device\n", dev_info); + return -EIO; ++ } + + /* XXX 32-bit addressing only */ + if (pci_set_dma_mask(pdev, 0xffffffff)) { +@@ -244,8 +246,10 @@ + sc->aps_sc.sc_ledpin = 1; + } + +- if (ath_attach(vdevice, dev, NULL) != 0) ++ if ((i = ath_attach(vdevice, dev, NULL)) != 0) { ++ printk(KERN_ERR "%s: ath_attach failed: %d\n", dev_info, i); + goto bad4; ++ } + + athname = ath_hal_probe(id->vendor, vdevice); + printk(KERN_INFO "%s: %s: %s: mem=0x%llx, irq=%d\n", diff --git a/package/madwifi/patches-testing/201-no_debug_extra.patch b/package/madwifi/patches-testing/201-no_debug_extra.patch new file mode 100644 index 0000000000..0e26d5f398 --- /dev/null +++ b/package/madwifi/patches-testing/201-no_debug_extra.patch @@ -0,0 +1,33 @@ +--- a/ath/if_ath.c ++++ b/ath/if_ath.c +@@ -423,8 +423,8 @@ + "defaults to '" DEF_RATE_CTL "'"); + MODULE_PARM_DESC(intmit, "Enable interference mitigation by default. Default is 0."); + +-static int ath_debug = 0; + #ifdef AR_DEBUG ++static int ath_debug = 0; + #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,52)) + MODULE_PARM(ath_debug, "i"); + #else +@@ -435,8 +435,8 @@ + static void ath_printtxbuf(const struct ath_buf *, int); + #endif /* defined(AR_DEBUG) */ + +-static int ieee80211_debug = 0; + #ifdef AR_DEBUG ++static int ieee80211_debug = 0; + #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,52)) + MODULE_PARM(ieee80211_debug, "i"); + #else +@@ -853,8 +853,10 @@ + ic->ic_updateslot = ath_updateslot; + atomic_set(&ic->ic_node_counter, 0); + ic->ic_debug = 0; ++#ifdef AR_DEBUG + sc->sc_debug = (ath_debug & ~ATH_DEBUG_GLOBAL); + sc->sc_default_ieee80211_debug = ieee80211_debug; ++#endif + + ic->ic_wme.wme_update = ath_wme_update; + ic->ic_uapsd_flush = ath_uapsd_flush; diff --git a/package/madwifi/patches-testing/300-napi_polling.patch b/package/madwifi/patches-testing/300-napi_polling.patch new file mode 100644 index 0000000000..27dd838db0 --- /dev/null +++ b/package/madwifi/patches-testing/300-napi_polling.patch @@ -0,0 +1,529 @@ +--- a/ath/if_ath.c ++++ b/ath/if_ath.c +@@ -182,7 +182,11 @@ + struct sk_buff *, int, int, u_int64_t); + static void ath_setdefantenna(struct ath_softc *, u_int); + static struct ath_txq *ath_txq_setup(struct ath_softc *, int, int); +-static void ath_rx_tasklet(TQUEUE_ARG); ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24) ++static int ath_rx_poll(struct napi_struct *napi, int budget); ++#else ++static int ath_rx_poll(struct net_device *dev, int *budget); ++#endif + static int ath_hardstart(struct sk_buff *, struct net_device *); + static int ath_mgtstart(struct ieee80211com *, struct sk_buff *); + #ifdef ATH_SUPERG_COMP +@@ -331,6 +335,9 @@ + static u_int32_t ath_set_clamped_maxtxpower(struct ath_softc *sc, + u_int32_t new_clamped_maxtxpower); + ++static void ath_poll_disable(struct net_device *dev); ++static void ath_poll_enable(struct net_device *dev); ++ + static void ath_scanbufs(struct ath_softc *sc); + static int ath_debug_iwpriv(struct ieee80211com *ic, + unsigned int param, unsigned int value); +@@ -518,7 +525,6 @@ + + atomic_set(&sc->sc_txbuf_counter, 0); + +- ATH_INIT_TQUEUE(&sc->sc_rxtq, ath_rx_tasklet, dev); + ATH_INIT_TQUEUE(&sc->sc_txtq, ath_tx_tasklet, dev); + ATH_INIT_TQUEUE(&sc->sc_bmisstq, ath_bmiss_tasklet, dev); + ATH_INIT_TQUEUE(&sc->sc_bstucktq, ath_bstuck_tasklet, dev); +@@ -833,6 +839,12 @@ + dev->set_mac_address = ath_set_mac_address; + dev->change_mtu = ath_change_mtu; + dev->tx_queue_len = ATH_TXBUF - ATH_TXBUF_MGT_RESERVED; ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24) ++ netif_napi_add(dev, &sc->sc_napi, ath_rx_poll, 64); ++#else ++ dev->poll = ath_rx_poll; ++ dev->weight = 64; ++#endif + #ifdef USE_HEADERLEN_RESV + dev->hard_header_len += sizeof(struct ieee80211_qosframe) + + sizeof(struct llc) + +@@ -1770,7 +1782,7 @@ + } + + static void +-ath_intr_process_rx_descriptors(struct ath_softc *sc, int *pneedmark, u_int64_t hw_tsf) ++ath_intr_process_rx_descriptors(struct ath_softc *sc, int *pneedmark, u_int64_t hw_tsf, int schedule) + { + struct ath_hal *ah = sc->sc_ah; + struct ath_desc *ds; +@@ -2252,8 +2264,25 @@ + } + + /* If we got something to process, schedule rx queue to handle it */ +- if (count) +- ATH_SCHEDULE_TQUEUE(&sc->sc_rxtq, pneedmark); ++ if (count) { ++ sc->sc_isr &= ~HAL_INT_RX; ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24) ++ if (netif_rx_schedule_prep(sc->sc_dev, &sc->sc_napi)) ++#else ++ if (netif_rx_schedule_prep(sc->sc_dev)) ++#endif ++ { ++#ifndef ATH_PRECISE_TSF ++ sc->sc_imask &= ~HAL_INT_RX; ++ ath_hal_intrset(ah, sc->sc_imask); ++#endif ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24) ++ __netif_rx_schedule(sc->sc_dev, &sc->sc_napi); ++#else ++ __netif_rx_schedule(sc->sc_dev); ++#endif ++ } ++ } + ATH_RXBUF_UNLOCK_IRQ(sc); + #undef PA2DESC + } +@@ -2343,6 +2372,7 @@ + (status & HAL_INT_GLOBAL) ? " HAL_INT_GLOBAL" : "" + ); + ++ sc->sc_isr = status; + status &= sc->sc_imask; /* discard unasked for bits */ + /* As soon as we know we have a real interrupt we intend to service, + * we will check to see if we need an initial hardware TSF reading. +@@ -2400,7 +2430,7 @@ + } + if (status & (HAL_INT_RX | HAL_INT_RXPHY)) { + /* NB: Will schedule rx tasklet if necessary. */ +- ath_intr_process_rx_descriptors(sc, &needmark, hw_tsf); ++ ath_intr_process_rx_descriptors(sc, &needmark, hw_tsf, 1); + } + if (status & HAL_INT_TX) { + #ifdef ATH_SUPERG_DYNTURBO +@@ -2426,6 +2456,11 @@ + } + } + #endif ++ /* disable transmit interrupt */ ++ sc->sc_isr &= ~HAL_INT_TX; ++ ath_hal_intrset(ah, sc->sc_imask & ~HAL_INT_TX); ++ sc->sc_imask &= ~HAL_INT_TX; ++ + ATH_SCHEDULE_TQUEUE(&sc->sc_txtq, &needmark); + } + if (status & HAL_INT_BMISS) { +@@ -2617,6 +2652,7 @@ + if (sc->sc_tx99 != NULL) + sc->sc_tx99->start(sc->sc_tx99); + #endif ++ ath_poll_enable(dev); + + done: + ATH_UNLOCK(sc); +@@ -2657,6 +2693,9 @@ + if (sc->sc_tx99 != NULL) + sc->sc_tx99->stop(sc->sc_tx99); + #endif ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24) ++ ath_poll_disable(dev); ++#endif + netif_stop_queue(dev); /* XXX re-enabled by ath_newstate */ + dev->flags &= ~IFF_RUNNING; /* NB: avoid recursion */ + ieee80211_stop_running(ic); /* stop all VAPs */ +@@ -4109,6 +4148,43 @@ + return ath_keyset(sc, k, mac, vap->iv_bss); + } + ++static void ath_poll_disable(struct net_device *dev) ++{ ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24) ++ struct ath_softc *sc = dev->priv; ++#endif ++ ++ /* ++ * XXX Using in_softirq is not right since we might ++ * be called from other soft irq contexts than ++ * ath_rx_poll ++ */ ++ if (!in_softirq()) { ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24) ++ napi_disable(&sc->sc_napi); ++#else ++ netif_poll_disable(dev); ++#endif ++ } ++} ++ ++static void ath_poll_enable(struct net_device *dev) ++{ ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24) ++ struct ath_softc *sc = dev->priv; ++#endif ++ ++ /* NB: see above */ ++ if (!in_softirq()) { ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24) ++ napi_enable(&sc->sc_napi); ++#else ++ netif_poll_enable(dev); ++#endif ++ } ++} ++ ++ + /* + * Block/unblock tx+rx processing while a key change is done. + * We assume the caller serializes key management operations +@@ -4119,33 +4195,23 @@ + ath_key_update_begin(struct ieee80211vap *vap) + { + struct net_device *dev = vap->iv_ic->ic_dev; +- struct ath_softc *sc = dev->priv; + +- DPRINTF(sc, ATH_DEBUG_KEYCACHE, "Begin\n"); + /* + * When called from the rx tasklet we cannot use + * tasklet_disable because it will block waiting + * for us to complete execution. +- * +- * XXX Using in_softirq is not right since we might +- * be called from other soft irq contexts than +- * ath_rx_tasklet. + */ +- if (!in_softirq()) +- tasklet_disable(&sc->sc_rxtq); +- netif_stop_queue(dev); ++ if ((dev->flags & (IFF_UP|IFF_RUNNING)) == (IFF_UP|IFF_RUNNING)) ++ netif_stop_queue(dev); + } + + static void + ath_key_update_end(struct ieee80211vap *vap) + { + struct net_device *dev = vap->iv_ic->ic_dev; +- struct ath_softc *sc = dev->priv; + +- DPRINTF(sc, ATH_DEBUG_KEYCACHE, "End\n"); +- netif_wake_queue(dev); +- if (!in_softirq()) /* NB: see above */ +- tasklet_enable(&sc->sc_rxtq); ++ if ((dev->flags & (IFF_UP|IFF_RUNNING)) == (IFF_UP|IFF_RUNNING)) ++ netif_wake_queue(dev); + } + + /* +@@ -6405,15 +6471,25 @@ + sc->sc_numrxotherant = 0; + } + +-static void +-ath_rx_tasklet(TQUEUE_ARG data) ++static int ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24) ++ath_rx_poll(struct napi_struct *napi, int budget) ++#else ++ath_rx_poll(struct net_device *dev, int *budget) ++#endif + { + #define PA2DESC(_sc, _pa) \ + ((struct ath_desc *)((caddr_t)(_sc)->sc_rxdma.dd_desc + \ + ((_pa) - (_sc)->sc_rxdma.dd_desc_paddr))) +- struct net_device *dev = (struct net_device *)data; +- struct ath_buf *bf; ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24) ++ struct ath_softc *sc = container_of(napi, struct ath_softc, sc_napi); ++ struct net_device *dev = sc->sc_dev; ++ u_int rx_limit = budget; ++#else + struct ath_softc *sc = dev->priv; ++ u_int rx_limit = min(dev->quota, *budget); ++#endif ++ struct ath_buf *bf; + struct ieee80211com *ic = &sc->sc_ic; + struct ath_hal *ah = sc ? sc->sc_ah : NULL; + struct ath_desc *ds; +@@ -6421,6 +6497,7 @@ + struct ieee80211_node *ni; + struct sk_buff *skb = NULL; + unsigned int len, phyerr, mic_fail = 0; ++ unsigned int early_stop = 0; + int type = -1; /* undefined */ + int init_ret = 0; + int bf_processed = 0; +@@ -6428,6 +6505,7 @@ + int errors = 0; + + DPRINTF(sc, ATH_DEBUG_RX_PROC, "%s started...\n", __func__); ++process_rx_again: + do { + /* Get next RX buffer pending processing by RX tasklet... + * +@@ -6457,6 +6535,10 @@ + break; + + bf_processed++; ++ if (rx_limit-- < 0) { ++ early_stop = 1; ++ break; ++ } + ds = bf->bf_desc; + + #ifdef AR_DEBUG +@@ -6491,6 +6573,7 @@ + sc->sc_stats.ast_rx_phyerr++; + phyerr = rs->rs_phyerr & 0x1f; + sc->sc_stats.ast_rx_phy[phyerr]++; ++ goto rx_next; + } + if (rs->rs_status & HAL_RXERR_DECRYPT) { + /* Decrypt error. If the error occurred +@@ -6689,6 +6772,33 @@ + STAILQ_INSERT_TAIL(&sc->sc_rxbuf, bf, bf_list); + ATH_RXBUF_UNLOCK_IRQ(sc); + } while (1); ++ if (!early_stop) { ++ unsigned long flags; ++ /* Check if more data is received while we were ++ * processing the descriptor chain. ++ */ ++#ifndef ATH_PRECISE_TSF ++ local_irq_save(flags); ++ if (sc->sc_isr & HAL_INT_RX) { ++ u_int64_t hw_tsf = ath_hal_gettsf64(ah); ++ sc->sc_isr &= ~HAL_INT_RX; ++ local_irq_restore(flags); ++ ath_intr_process_rx_descriptors(sc, NULL, hw_tsf, 0); ++ goto process_rx_again; ++ } ++ sc->sc_imask |= HAL_INT_RX; ++ ath_hal_intrset(ah, sc->sc_imask); ++ local_irq_restore(flags); ++#endif ++ } ++ ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24) ++ netif_rx_complete(dev, napi); ++#else ++ netif_rx_complete(dev); ++ *budget -= bf_processed; ++ dev->quota -= bf_processed; ++#endif + + if (sc->sc_useintmit) + ath_hal_rxmonitor(ah, &sc->sc_halstats, &sc->sc_curchan); +@@ -6701,6 +6811,12 @@ + " %d rx buf processed. %d were errors. %d skb accepted.\n", + __func__, bf_processed, errors, skb_accepted); + #undef PA2DESC ++ ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24) ++ return bf_processed; ++#else ++ return early_stop; ++#endif + } + + #ifdef ATH_SUPERG_XR +@@ -8306,12 +8422,24 @@ + { + struct net_device *dev = (struct net_device *)data; + struct ath_softc *sc = dev->priv; ++ unsigned long flags; + ++process_tx_again: + if (txqactive(sc->sc_ah, 0)) + ath_tx_processq(sc, &sc->sc_txq[0]); + if (txqactive(sc->sc_ah, sc->sc_cabq->axq_qnum)) + ath_tx_processq(sc, sc->sc_cabq); + ++ local_irq_save(flags); ++ if (sc->sc_isr & HAL_INT_TX) { ++ sc->sc_isr &= ~HAL_INT_TX; ++ local_irq_restore(flags); ++ goto process_tx_again; ++ } ++ sc->sc_imask |= HAL_INT_TX; ++ ath_hal_intrset(sc->sc_ah, sc->sc_imask); ++ local_irq_restore(flags); ++ + netif_wake_queue(dev); + + if (sc->sc_softled) +@@ -8327,7 +8455,9 @@ + { + struct net_device *dev = (struct net_device *)data; + struct ath_softc *sc = dev->priv; ++ unsigned long flags; + ++process_tx_again: + /* + * Process each active queue. + */ +@@ -8357,6 +8487,16 @@ + if (sc->sc_uapsdq && txqactive(sc->sc_ah, sc->sc_uapsdq->axq_qnum)) + ath_tx_processq(sc, sc->sc_uapsdq); + ++ local_irq_save(flags); ++ if (sc->sc_isr & HAL_INT_TX) { ++ sc->sc_isr &= ~HAL_INT_TX; ++ local_irq_restore(flags); ++ goto process_tx_again; ++ } ++ sc->sc_imask |= HAL_INT_TX; ++ ath_hal_intrset(sc->sc_ah, sc->sc_imask); ++ local_irq_restore(flags); ++ + netif_wake_queue(dev); + + if (sc->sc_softled) +@@ -10322,9 +10462,9 @@ + dev->mtu = mtu; + if ((dev->flags & IFF_RUNNING) && !sc->sc_invalid) { + /* NB: the rx buffers may need to be reallocated */ +- tasklet_disable(&sc->sc_rxtq); ++ ath_poll_disable(dev); + error = ath_reset(dev); +- tasklet_enable(&sc->sc_rxtq); ++ ath_poll_enable(dev); + } + ATH_UNLOCK(sc); + +--- a/ath/if_athvar.h ++++ b/ath/if_athvar.h +@@ -56,6 +56,10 @@ + # include + #endif + ++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0) ++#define irqs_disabled() 0 ++#endif ++ + /* + * Deduce if tasklets are available. If not then + * fall back to using the immediate work queue. +@@ -644,6 +648,9 @@ + struct ath_softc { + struct ieee80211com sc_ic; /* NB: must be first */ + struct net_device *sc_dev; ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24) ++ struct napi_struct sc_napi; ++#endif + void __iomem *sc_iobase; /* address of the device */ + struct semaphore sc_lock; /* dev-level lock */ + struct net_device_stats sc_devstats; /* device statistics */ +@@ -756,7 +763,6 @@ + struct ath_buf *sc_rxbufcur; /* current rx buffer */ + u_int32_t *sc_rxlink; /* link ptr in last RX desc */ + spinlock_t sc_rxbuflock; +- struct ATH_TQ_STRUCT sc_rxtq; /* rx intr tasklet */ + struct ATH_TQ_STRUCT sc_rxorntq; /* rxorn intr tasklet */ + u_int16_t sc_cachelsz; /* cache line size */ + +@@ -769,6 +775,7 @@ + u_int sc_txintrperiod; /* tx interrupt batching */ + struct ath_txq sc_txq[HAL_NUM_TX_QUEUES]; + struct ath_txq *sc_ac2q[WME_NUM_AC]; /* WME AC -> h/w qnum */ ++ HAL_INT sc_isr; /* unmasked ISR state */ + struct ATH_TQ_STRUCT sc_txtq; /* tx intr tasklet */ + u_int8_t sc_grppoll_str[GRPPOLL_RATE_STR_LEN]; + struct ath_descdma sc_bdma; /* beacon descriptors */ +@@ -888,6 +895,8 @@ + #define ATH_TXBUF_LOCK_CHECK(_sc) + #endif + ++#define ATH_DISABLE_INTR local_irq_disable ++#define ATH_ENABLE_INTR local_irq_enable + + #define ATH_RXBUF_LOCK_INIT(_sc) spin_lock_init(&(_sc)->sc_rxbuflock) + #define ATH_RXBUF_LOCK_DESTROY(_sc) +--- a/net80211/ieee80211_skb.c ++++ b/net80211/ieee80211_skb.c +@@ -73,7 +73,7 @@ + #undef dev_queue_xmit + #undef kfree_skb + #undef kfree_skb_fast +-#undef netif_rx ++#undef netif_receive_skb + #undef pskb_copy + #undef skb_clone + #undef skb_copy +@@ -581,8 +581,8 @@ + grp, vlan_tag); + } + +-int netif_rx_debug(struct sk_buff *skb, const char *func, int line) { +- return netif_rx(untrack_skb(skb, 0, __func__, __LINE__)); ++int netif_receive_skb_debug(struct sk_buff *skb, const char *func, int line) { ++ return netif_receive_skb(untrack_skb(skb, 0, __func__, __LINE__)); + } + + struct sk_buff *alloc_skb_debug(unsigned int length, gfp_t gfp_mask, +@@ -707,7 +707,7 @@ + } + + EXPORT_SYMBOL(vlan_hwaccel_rx_debug); +-EXPORT_SYMBOL(netif_rx_debug); ++EXPORT_SYMBOL(netif_receive_skb_debug); + EXPORT_SYMBOL(alloc_skb_debug); + EXPORT_SYMBOL(dev_alloc_skb_debug); + EXPORT_SYMBOL(skb_clone_debug); +--- a/net80211/ieee80211_skb.h ++++ b/net80211/ieee80211_skb.h +@@ -115,7 +115,7 @@ + + int vlan_hwaccel_rx_debug(struct sk_buff *skb, struct vlan_group *grp, + unsigned short vlan_tag, const char *func, int line); +-int netif_rx_debug(struct sk_buff *skb, const char *func, int line); ++int netif_receive_skb_debug(struct sk_buff *skb, const char *func, int line); + struct sk_buff *alloc_skb_debug(unsigned int length, gfp_t gfp_mask, + const char *func, int line); + struct sk_buff *dev_alloc_skb_debug(unsigned int length, +@@ -150,7 +150,7 @@ + #undef dev_queue_xmit + #undef kfree_skb + #undef kfree_skb_fast +-#undef netif_rx ++#undef netif_receive_skb + #undef pskb_copy + #undef skb_clone + #undef skb_copy +@@ -167,8 +167,8 @@ + skb_copy_expand_debug(_skb, _newheadroom, _newtailroom, _gfp_mask, __func__, __LINE__) + #define vlan_hwaccel_rx(_skb, _grp, _tag) \ + vlan_hwaccel_rx_debug(_skb, _grp, _tag, __func__, __LINE__) +-#define netif_rx(_skb) \ +- netif_rx_debug(_skb, __func__, __LINE__) ++#define netif_receive_skb(_skb) \ ++ netif_receive_skb_debug(_skb, __func__, __LINE__) + #define alloc_skb(_length, _gfp_mask) \ + alloc_skb_debug(_length, _gfp_mask, __func__, __LINE__) + #define dev_alloc_skb(_length) \ +--- a/net80211/ieee80211_input.c ++++ b/net80211/ieee80211_input.c +@@ -1185,7 +1185,7 @@ + ret = vlan_hwaccel_rx(skb, + vap->iv_vlgrp, ni->ni_vlan); + else +- ret = netif_rx(skb); ++ ret = netif_receive_skb(skb); + if (ret == NET_RX_DROP) + vap->iv_devstats.rx_dropped++; + if (tni != NULL) +@@ -2285,7 +2285,7 @@ + + if (SKB_NI(skb1) != NULL) + ieee80211_unref_node(&SKB_NI(skb1)); +- if (netif_rx(skb1) == NET_RX_DROP) ++ if (netif_receive_skb(skb1) == NET_RX_DROP) + vap->iv_devstats.rx_dropped++; + } + } +--- a/net80211/ieee80211_monitor.c ++++ b/net80211/ieee80211_monitor.c +@@ -580,7 +580,7 @@ + + if (SKB_NI(skb1) != NULL) + ieee80211_unref_node(&SKB_NI(skb1)); +- if (netif_rx(skb1) == NET_RX_DROP) ++ if (netif_receive_skb(skb1) == NET_RX_DROP) + vap->iv_devstats.rx_dropped++; + skb1 = NULL; + } diff --git a/package/madwifi/patches-testing/301-pureg_fix.patch b/package/madwifi/patches-testing/301-pureg_fix.patch new file mode 100644 index 0000000000..fb6cefe364 --- /dev/null +++ b/package/madwifi/patches-testing/301-pureg_fix.patch @@ -0,0 +1,168 @@ +--- a/ath/if_ath.c ++++ b/ath/if_ath.c +@@ -4251,7 +4251,9 @@ + rfilt |= HAL_RX_FILTER_PROM; + if (ic->ic_opmode == IEEE80211_M_STA || + sc->sc_opmode == HAL_M_IBSS || /* NB: AHDEMO too */ +- (sc->sc_nostabeacons) || sc->sc_scanning) ++ (sc->sc_nostabeacons) || sc->sc_scanning || ++ ((ic->ic_opmode == IEEE80211_M_HOSTAP) && ++ (ic->ic_protmode != IEEE80211_PROT_NONE))) + rfilt |= HAL_RX_FILTER_BEACON; + if (sc->sc_nmonvaps > 0) + rfilt |= (HAL_RX_FILTER_CONTROL | HAL_RX_FILTER_BEACON | +--- a/net80211/ieee80211_input.c ++++ b/net80211/ieee80211_input.c +@@ -325,11 +325,12 @@ + bssid = wh->i_addr3; + } + /* +- * Validate the bssid. ++ * Validate the bssid. Let beacons get through though for 11g protection mode. + */ +-#ifdef ATH_SUPERG_XR + if (!IEEE80211_ADDR_EQ(bssid, vap->iv_bssid) && +- !IEEE80211_ADDR_EQ(bssid, dev->broadcast)) { ++ !IEEE80211_ADDR_EQ(bssid, dev->broadcast) && ++ (subtype != IEEE80211_FC0_SUBTYPE_BEACON)) { ++#ifdef ATH_SUPERG_XR + /* + * allow MGT frames to vap->iv_xrvap. + * this will allow roaming between XR and normal vaps +@@ -345,18 +346,14 @@ + vap->iv_stats.is_rx_wrongbss++; + goto out; + } +- } + #else +- if (!IEEE80211_ADDR_EQ(bssid, vap->iv_bssid) && +- !IEEE80211_ADDR_EQ(bssid, dev->broadcast)) { + /* not interested in */ + IEEE80211_DISCARD_MAC(vap, IEEE80211_MSG_INPUT, + bssid, NULL, "%s", "not to bss"); + vap->iv_stats.is_rx_wrongbss++; + goto out; +- } +- + #endif ++ } + break; + case IEEE80211_M_WDS: + if (skb->len < sizeof(struct ieee80211_frame_addr4)) { +@@ -3019,7 +3016,7 @@ + u_int8_t *frm, *efrm; + u_int8_t *ssid, *rates, *xrates, *suppchan, *wpa, *rsn, *wme, *ath; + u_int8_t rate; +- int reassoc, resp, allocbs = 0; ++ int reassoc, resp, allocbs = 0, has_erp = 0; + u_int8_t qosinfo; + + if (ni_or_null == NULL) +@@ -3049,11 +3046,15 @@ + * o station mode when associated (to collect state + * updates such as 802.11g slot time), or + * o adhoc mode (to discover neighbors) ++ * o ap mode in protection mode (beacons only) + * Frames otherwise received are discarded. + */ + if (!((ic->ic_flags & IEEE80211_F_SCAN) || + (vap->iv_opmode == IEEE80211_M_STA && ni->ni_associd) || +- vap->iv_opmode == IEEE80211_M_IBSS)) { ++ (vap->iv_opmode == IEEE80211_M_IBSS) || ++ ((subtype == IEEE80211_FC0_SUBTYPE_BEACON) && ++ (vap->iv_opmode == IEEE80211_M_HOSTAP) && ++ (ic->ic_protmode != IEEE80211_PROT_NONE)))) { + vap->iv_stats.is_rx_mgtdiscard++; + return 0; + } +@@ -3137,6 +3138,7 @@ + break; + } + scan.erp = frm[2]; ++ has_erp = 1; + break; + case IEEE80211_ELEMID_RSN: + scan.rsn = frm; +@@ -3374,6 +3376,20 @@ + ieee80211_bg_scan(vap); + return 0; + } ++ ++ /* Update AP protection mode when in 11G mode */ ++ if ((vap->iv_opmode == IEEE80211_M_HOSTAP) && ++ IEEE80211_IS_CHAN_ANYG(ic->ic_curchan)) { ++ ++ /* Assume no ERP IE == 11b AP */ ++ if ((!has_erp || (has_erp && (scan.erp & IEEE80211_ERP_NON_ERP_PRESENT))) && ++ !(ic->ic_flags & IEEE80211_F_USEPROT)) { ++ ++ ic->ic_flags |= IEEE80211_F_USEPROT; ++ ic->ic_flags_ext |= IEEE80211_FEXT_ERPUPDATE; ++ } ++ } ++ + /* + * If scanning, just pass information to the scan module. + */ +--- a/net80211/ieee80211_node.c ++++ b/net80211/ieee80211_node.c +@@ -345,10 +345,16 @@ + /* Update country ie information */ + ieee80211_build_countryie(ic); + +- if (IEEE80211_IS_CHAN_HALF(chan)) ++ if (IEEE80211_IS_CHAN_HALF(chan)) { + ni->ni_rates = ic->ic_sup_half_rates; +- else if (IEEE80211_IS_CHAN_QUARTER(chan)) ++ } else if (IEEE80211_IS_CHAN_QUARTER(chan)) { + ni->ni_rates = ic->ic_sup_quarter_rates; ++ } ++ ++ if ((vap->iv_flags & IEEE80211_F_PUREG) && ++ IEEE80211_IS_CHAN_ANYG(chan)) { ++ ieee80211_setpuregbasicrates(&ni->ni_rates); ++ } + + (void) ieee80211_sta_join1(PASS_NODE(ni)); + } +--- a/net80211/ieee80211_proto.c ++++ b/net80211/ieee80211_proto.c +@@ -599,6 +599,28 @@ + { 4, { 2, 4, 11, 22 } }, /* IEEE80211_MODE_TURBO_G (mixed b/g) */ + }; + ++static const struct ieee80211_rateset basicpureg[] = { ++ { 7, {2, 4, 11, 22, 12, 24, 48 } }, ++}; ++ ++/* ++ * Mark basic rates for the 11g rate table based on the pureg setting ++ */ ++void ++ieee80211_setpuregbasicrates(struct ieee80211_rateset *rs) ++{ ++ int i, j; ++ ++ for (i = 0; i < rs->rs_nrates; i++) { ++ rs->rs_rates[i] &= IEEE80211_RATE_VAL; ++ for (j = 0; j < basicpureg[0].rs_nrates; j++) ++ if (basicpureg[0].rs_rates[j] == rs->rs_rates[i]) { ++ rs->rs_rates[i] |= IEEE80211_RATE_BASIC; ++ break; ++ } ++ } ++} ++ + /* + * Mark the basic rates for the 11g rate table based on the + * specified mode. For 11b compatibility we mark only 11b +--- a/net80211/ieee80211_var.h ++++ b/net80211/ieee80211_var.h +@@ -712,6 +712,7 @@ + void ieee80211_build_sc_ie(struct ieee80211com *); + void ieee80211_dfs_action(struct ieee80211com *); + void ieee80211_expire_channel_excl_restrictions(struct ieee80211com *); ++void ieee80211_setpuregbasicrates(struct ieee80211_rateset *rs); + + /* + * Iterate through ic_channels to enumerate all distinct ic_ieee channel numbers. diff --git a/package/madwifi/patches-testing/302-noise_get.patch b/package/madwifi/patches-testing/302-noise_get.patch new file mode 100644 index 0000000000..8c69ca24f4 --- /dev/null +++ b/package/madwifi/patches-testing/302-noise_get.patch @@ -0,0 +1,38 @@ +--- a/ath/if_ath.c ++++ b/ath/if_ath.c +@@ -8997,6 +8997,7 @@ + ATH_LONG_CALINTERVAL_SECS : + ATH_SHORT_CALINTERVAL_SECS; + } ++ ic->ic_channoise = ath_hal_get_channel_noise(ah, &(sc->sc_curchan)); + + DPRINTF(sc, ATH_DEBUG_CALIBRATE, "Channel %u [flags=%04x] -- IQ %s.\n", + sc->sc_curchan.channel, sc->sc_curchan.channelFlags, +@@ -9052,6 +9053,7 @@ + struct ath_softc *sc = dev->priv; + + (void) ath_chan_set(sc, ic->ic_curchan); ++ ic->ic_channoise = ath_hal_get_channel_noise(sc->sc_ah, &(sc->sc_curchan)); + /* + * If we are returning to our bss channel then mark state + * so the next recv'd beacon's TSF will be used to sync the +--- a/net80211/ieee80211_wireless.c ++++ b/net80211/ieee80211_wireless.c +@@ -4396,6 +4396,7 @@ + si->isi_state = ni->ni_flags; + si->isi_authmode = ni->ni_authmode; + si->isi_rssi = ic->ic_node_getrssi(ni); ++ si->isi_noise = ic->ic_channoise; + si->isi_capinfo = ni->ni_capinfo; + si->isi_athflags = ni->ni_ath_flags; + si->isi_erp = ni->ni_erp; +--- a/net80211/ieee80211_ioctl.h ++++ b/net80211/ieee80211_ioctl.h +@@ -312,6 +312,7 @@ + u_int16_t isi_state; /* state flags */ + u_int8_t isi_authmode; /* authentication algorithm */ + u_int8_t isi_rssi; ++ int8_t isi_noise; + u_int16_t isi_capinfo; /* capabilities */ + u_int8_t isi_athflags; /* Atheros capabilities */ + u_int8_t isi_erp; /* ERP element */ diff --git a/package/madwifi/patches-testing/303-bssid_alloc.patch b/package/madwifi/patches-testing/303-bssid_alloc.patch new file mode 100644 index 0000000000..43e0d6dcf5 --- /dev/null +++ b/package/madwifi/patches-testing/303-bssid_alloc.patch @@ -0,0 +1,40 @@ +--- a/ath/if_ath.c ++++ b/ath/if_ath.c +@@ -1347,11 +1347,12 @@ + TAILQ_FOREACH(v, &ic->ic_vaps, iv_next) + id_mask |= (1 << ATH_GET_VAP_ID(v->iv_myaddr)); + +- for (id = 1; id < ath_maxvaps; id++) { ++ for (id = 0; id < ath_maxvaps; id++) { + /* Get the first available slot. */ + if ((id_mask & (1 << id)) == 0) { + ATH_SET_VAP_BSSID(vap->iv_myaddr, id); + ATH_SET_VAP_BSSID(vap->iv_bssid, id); ++ sc->sc_bclast = id; + break; + } + } +@@ -1359,7 +1360,12 @@ + EPRINTF(sc, "Unique BSSID requested on HW that does" + "does not support the necessary features."); + } ++ } else { ++ /* share the BSSID of the last created VAP */ ++ ATH_SET_VAP_BSSID(vap->iv_myaddr, sc->sc_bclast); ++ ATH_SET_VAP_BSSID(vap->iv_bssid, sc->sc_bclast); + } ++ + avp->av_bslot = -1; + #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,15) + atomic_set(&avp->av_beacon_alloc, 0); +--- a/ath/if_athvar.h ++++ b/ath/if_athvar.h +@@ -802,7 +802,7 @@ + } sc_updateslot; /* slot time update fsm */ + int sc_slotupdate; /* slot to next advance fsm */ + struct ieee80211vap **sc_bslot; /* beacon xmit slots */ +- int sc_bnext; /* next slot for beacon xmit */ ++ int sc_bclast; /* last used slot for beacon xmit */ + + int sc_beacon_cal; /* use beacon timer for calibration */ + long unsigned int sc_calinterval_sec; /* current interval for calibration (in seconds) */ diff --git a/package/madwifi/patches-testing/304-erp_update.patch b/package/madwifi/patches-testing/304-erp_update.patch new file mode 100644 index 0000000000..be64b95371 --- /dev/null +++ b/package/madwifi/patches-testing/304-erp_update.patch @@ -0,0 +1,68 @@ +--- a/net80211/ieee80211_beacon.c ++++ b/net80211/ieee80211_beacon.c +@@ -544,10 +544,10 @@ + vap->iv_flags &= ~IEEE80211_F_XRUPDATE; + } + #endif +- if ((ic->ic_flags_ext & IEEE80211_FEXT_ERPUPDATE) && ++ if ((vap->iv_flags_ext & IEEE80211_FEXT_ERPUPDATE) && + (bo->bo_erp != NULL)) { + (void)ieee80211_add_erp(bo->bo_erp, ic); +- ic->ic_flags_ext &= ~IEEE80211_FEXT_ERPUPDATE; ++ vap->iv_flags_ext &= ~IEEE80211_FEXT_ERPUPDATE; + } + } + /* if it is a mode change beacon for dynamic turbo case */ +--- a/net80211/ieee80211_input.c ++++ b/net80211/ieee80211_input.c +@@ -3384,9 +3384,12 @@ + /* Assume no ERP IE == 11b AP */ + if ((!has_erp || (has_erp && (scan.erp & IEEE80211_ERP_NON_ERP_PRESENT))) && + !(ic->ic_flags & IEEE80211_F_USEPROT)) { ++ struct ieee80211vap *tmpvap; + + ic->ic_flags |= IEEE80211_F_USEPROT; +- ic->ic_flags_ext |= IEEE80211_FEXT_ERPUPDATE; ++ TAILQ_FOREACH(tmpvap, &ic->ic_vaps, iv_next) { ++ tmpvap->iv_flags_ext |= IEEE80211_FEXT_ERPUPDATE; ++ } + } + } + +--- a/net80211/ieee80211_node.c ++++ b/net80211/ieee80211_node.c +@@ -1741,8 +1741,12 @@ + } + + /* Update ERP element if this is first non ERP station */ +- if (ic->ic_nonerpsta == 1) +- ic->ic_flags_ext |= IEEE80211_FEXT_ERPUPDATE; ++ if (ic->ic_nonerpsta == 1) { ++ struct ieee80211vap *tmpvap; ++ TAILQ_FOREACH(tmpvap, &ic->ic_vaps, iv_next) { ++ tmpvap->iv_flags_ext |= IEEE80211_FEXT_ERPUPDATE; ++ } ++ } + } else + ni->ni_flags |= IEEE80211_NODE_ERP; + } +@@ -1945,6 +1949,8 @@ + IEEE80211_NOTE(vap, IEEE80211_MSG_ASSOC, ni, + "non-ERP station leaves, count now %d", ic->ic_nonerpsta); + if (ic->ic_nonerpsta == 0) { ++ struct ieee80211vap *tmpvap; ++ + IEEE80211_DPRINTF(vap, IEEE80211_MSG_ASSOC, + "%s: disable use of protection\n", __func__); + ic->ic_flags &= ~IEEE80211_F_USEPROT; +@@ -1956,7 +1962,9 @@ + ic->ic_flags |= IEEE80211_F_SHPREAMBLE; + ic->ic_flags &= ~IEEE80211_F_USEBARKER; + } +- ic->ic_flags_ext |= IEEE80211_FEXT_ERPUPDATE; ++ TAILQ_FOREACH(tmpvap, &ic->ic_vaps, iv_next) { ++ tmpvap->iv_flags_ext |= IEEE80211_FEXT_ERPUPDATE; ++ } + } + } + } diff --git a/package/madwifi/patches-testing/305-bssid_mask.patch b/package/madwifi/patches-testing/305-bssid_mask.patch new file mode 100644 index 0000000000..bc02462a33 --- /dev/null +++ b/package/madwifi/patches-testing/305-bssid_mask.patch @@ -0,0 +1,13 @@ +--- a/ath/if_ath.c ++++ b/ath/if_ath.c +@@ -8717,6 +8717,10 @@ + + sc->sc_rxbufcur = NULL; + ++ /* configure bssid mask */ ++ if (sc->sc_hasbmask) ++ ath_hal_setbssidmask(ah, sc->sc_bssidmask); ++ + bf = STAILQ_FIRST(&sc->sc_rxbuf); + ath_hal_putrxbuf(ah, bf->bf_daddr); + ath_hal_rxena(ah); /* enable recv descriptors */ diff --git a/package/madwifi/patches-testing/306-queue.patch b/package/madwifi/patches-testing/306-queue.patch new file mode 100644 index 0000000000..3341f01b88 --- /dev/null +++ b/package/madwifi/patches-testing/306-queue.patch @@ -0,0 +1,42 @@ +--- a/ath/if_ath.c ++++ b/ath/if_ath.c +@@ -8448,8 +8448,6 @@ + ath_hal_intrset(sc->sc_ah, sc->sc_imask); + local_irq_restore(flags); + +- netif_wake_queue(dev); +- + if (sc->sc_softled) + ath_led_event(sc, ATH_LED_TX); + } +@@ -8505,8 +8503,6 @@ + ath_hal_intrset(sc->sc_ah, sc->sc_imask); + local_irq_restore(flags); + +- netif_wake_queue(dev); +- + if (sc->sc_softled) + ath_led_event(sc, ATH_LED_TX); + } +@@ -8537,7 +8533,9 @@ + STAILQ_FIRST(&sc->sc_cabq->axq_q) ? "not setup" : "empty"); + } + } +- netif_wake_queue(dev); ++ ++ if (ath_get_buffers_available(sc) > ATH_TXBUF_MGT_RESERVED) ++ netif_wake_queue(dev); + + if (sc->sc_softled) + ath_led_event(sc, ATH_LED_TX); +--- a/net80211/ieee80211_input.c ++++ b/net80211/ieee80211_input.c +@@ -1116,7 +1116,7 @@ + (vap->iv_flags & IEEE80211_F_NOBRIDGE) == 0) { + struct sk_buff *skb1 = NULL; + +- if (ETHER_IS_MULTICAST(eh->ether_dhost)) { ++ if (ETHER_IS_MULTICAST(eh->ether_dhost) && !netif_queue_stopped(dev)) { + /* Create a SKB for the BSS to send out. */ + skb1 = skb_copy(skb, GFP_ATOMIC); + if (skb1) diff --git a/package/madwifi/patches-testing/307-maxrate.patch b/package/madwifi/patches-testing/307-maxrate.patch new file mode 100644 index 0000000000..a5a1db02fb --- /dev/null +++ b/package/madwifi/patches-testing/307-maxrate.patch @@ -0,0 +1,96 @@ +--- a/ath/if_ath.c ++++ b/ath/if_ath.c +@@ -1299,6 +1299,7 @@ + vap->iv_key_set = ath_key_set; + vap->iv_key_update_begin = ath_key_update_begin; + vap->iv_key_update_end = ath_key_update_end; ++ vap->iv_maxrateindex = 0; + if (sc->sc_default_ieee80211_debug) { + /* User specified defaults for new VAPs were provided, so + * use those (only). */ +--- a/ath_rate/sample/sample.c ++++ b/ath_rate/sample/sample.c +@@ -838,7 +838,12 @@ + } + sn->static_rate_ndx = -1; + +- sn->num_rates = ni->ni_rates.rs_nrates; ++ if (vap->iv_maxrateindex == 0 || ni->ni_rates.rs_nrates <= 0 ++ || vap->iv_maxrateindex > ni->ni_rates.rs_nrates) ++ sn->num_rates = ni->ni_rates.rs_nrates; ++ else ++ sn->num_rates = vap->iv_maxrateindex; ++ + for (x = 0; x < ni->ni_rates.rs_nrates; x++) { + sn->rates[x].rate = ni->ni_rates.rs_rates[x] & IEEE80211_RATE_VAL; + sn->rates[x].rix = sc->sc_rixmap[sn->rates[x].rate]; +--- a/net80211/ieee80211_var.h ++++ b/net80211/ieee80211_var.h +@@ -291,6 +291,7 @@ + struct ieee80211_spy iv_spy; /* IWSPY support */ + struct ieee80211_app_ie app_ie[IEEE80211_APPIE_NUM_OF_FRAME]; /* app-specified IEs by frame type */ + u_int32_t app_filter; /* filters which management frames are forwarded to app */ ++ int iv_maxrateindex; + }; + + /* Debug functions need the defintion of struct ieee80211vap because iv_debug +--- a/net80211/ieee80211_wireless.c ++++ b/net80211/ieee80211_wireless.c +@@ -2873,6 +2873,12 @@ + else + ic->ic_flags_ext &= ~IEEE80211_FEXT_MARKDFS; + break; ++ case IEEE80211_PARAM_MAXRATE: ++ if (value > 0) ++ vap->iv_maxrateindex = value; ++ else ++ vap->iv_maxrateindex = 0; ++ break; + #ifdef ATH_REVERSE_ENGINEERING + case IEEE80211_PARAM_DUMPREGS: + ieee80211_dump_registers(dev, info, w, extra); +@@ -3211,6 +3217,9 @@ + else + param[0] = 0; + break; ++ case IEEE80211_PARAM_MAXRATE: ++ param[0] = vap->iv_maxrateindex; ++ break; + default: + return -EOPNOTSUPP; + } +@@ -5666,6 +5675,10 @@ + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "debug_scanbufs" }, + { IEEE80211_PARAM_LEAKTXBUFS, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "debug_leaktxbufs" }, ++ {IEEE80211_PARAM_MAXRATE, ++ IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "maxrate"}, ++ {IEEE80211_PARAM_MAXRATE, ++ 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "get_maxrate"}, + + #ifdef ATH_REVERSE_ENGINEERING + /* +--- a/net80211/ieee80211_ioctl.h ++++ b/net80211/ieee80211_ioctl.h +@@ -650,6 +650,7 @@ + IEEE80211_PARAM_RESETTXBUFS = 80, /* Reset transmit DMA */ + IEEE80211_PARAM_SCANBUFS = 81, /* Heap analysis for TX DMA */ + IEEE80211_PARAM_LEAKTXBUFS = 82, /* Leak tx buffers */ ++ IEEE80211_PARAM_MAXRATE = 83, /* Maximum rate (by table index) */ + }; + + #define SIOCG80211STATS (SIOCDEVPRIVATE+2) +--- a/ath_rate/minstrel/minstrel.c ++++ b/ath_rate/minstrel/minstrel.c +@@ -644,6 +644,11 @@ + return; + } + sn->static_rate_ndx = -1; ++ if (vap->iv_maxrateindex == 0 || ni->ni_rates.rs_nrates <= 0 ++ || vap->iv_maxrateindex > ni->ni_rates.rs_nrates) ++ sn->num_rates = ni->ni_rates.rs_nrates; ++ else ++ sn->num_rates = vap->iv_maxrateindex; + + sn->num_rates = ni->ni_rates.rs_nrates; + for (x = 0; x < ni->ni_rates.rs_nrates; x++) { diff --git a/package/madwifi/patches-testing/308-minrate.patch b/package/madwifi/patches-testing/308-minrate.patch new file mode 100644 index 0000000000..8e7b6066a8 --- /dev/null +++ b/package/madwifi/patches-testing/308-minrate.patch @@ -0,0 +1,112 @@ +--- a/ath/if_ath.c ++++ b/ath/if_ath.c +@@ -1300,6 +1300,7 @@ + vap->iv_key_update_begin = ath_key_update_begin; + vap->iv_key_update_end = ath_key_update_end; + vap->iv_maxrateindex = 0; ++ vap->iv_minrateindex = 0; + if (sc->sc_default_ieee80211_debug) { + /* User specified defaults for new VAPs were provided, so + * use those (only). */ +--- a/ath_rate/minstrel/minstrel.c ++++ b/ath_rate/minstrel/minstrel.c +@@ -652,6 +652,8 @@ + + sn->num_rates = ni->ni_rates.rs_nrates; + for (x = 0; x < ni->ni_rates.rs_nrates; x++) { ++ int idx = x; ++ + sn->rs_rateattempts [x] = 0; + sn->rs_thisprob [x] = 0; + sn->rs_ratesuccess [x] = 0; +@@ -662,8 +664,12 @@ + sn->rs_att_hist [x] = 0; + sn->rs_this_tp [x] = 0; + +- sn->rates[x].rate = ni->ni_rates.rs_rates[x] & IEEE80211_RATE_VAL; +- sn->rates[x].rix = sc->sc_rixmap[sn->rates[x].rate]; ++ if (vap->iv_minrateindex && (vap->iv_minrateindex < ++ ni->ni_rates.rs_nrates)) ++ idx = vap->iv_minrateindex; ++ ++ sn->rates[x].rate = ni->ni_rates.rs_rates[idx] & IEEE80211_RATE_VAL; ++ sn->rates[x].rix = sc->sc_rixmap[sn->rates[idx].rate]; + if (sn->rates[x].rix == 0xff) { + DPRINTF(sc, "%s: %s ignore bogus rix at %d\n", + dev_info, __func__, x); +--- a/ath_rate/sample/sample.c ++++ b/ath_rate/sample/sample.c +@@ -845,8 +845,15 @@ + sn->num_rates = vap->iv_maxrateindex; + + for (x = 0; x < ni->ni_rates.rs_nrates; x++) { +- sn->rates[x].rate = ni->ni_rates.rs_rates[x] & IEEE80211_RATE_VAL; +- sn->rates[x].rix = sc->sc_rixmap[sn->rates[x].rate]; ++ int idx = x; ++ ++ if (vap->iv_minrateindex && vap->iv_minrateindex < ++ ni->ni_rates.rs_nrates) ++ idx = vap->iv_minrateindex; ++ ++ sn->rates[x].rate = ni->ni_rates.rs_rates[idx] & IEEE80211_RATE_VAL; ++ sn->rates[x].rix = sc->sc_rixmap[sn->rates[idx].rate]; ++ + if (sn->rates[x].rix == 0xff) { + DPRINTF(sc, ATH_DEBUG_RATE, "%s: %s ignore bogus rix at %u\n", + dev_info, __func__, x); +--- a/net80211/ieee80211_ioctl.h ++++ b/net80211/ieee80211_ioctl.h +@@ -651,6 +651,7 @@ + IEEE80211_PARAM_SCANBUFS = 81, /* Heap analysis for TX DMA */ + IEEE80211_PARAM_LEAKTXBUFS = 82, /* Leak tx buffers */ + IEEE80211_PARAM_MAXRATE = 83, /* Maximum rate (by table index) */ ++ IEEE80211_PARAM_MINRATE = 84, /* Minimum rate (by table index) */ + }; + + #define SIOCG80211STATS (SIOCDEVPRIVATE+2) +--- a/net80211/ieee80211_var.h ++++ b/net80211/ieee80211_var.h +@@ -292,6 +292,7 @@ + struct ieee80211_app_ie app_ie[IEEE80211_APPIE_NUM_OF_FRAME]; /* app-specified IEs by frame type */ + u_int32_t app_filter; /* filters which management frames are forwarded to app */ + int iv_maxrateindex; ++ int iv_minrateindex; + }; + + /* Debug functions need the defintion of struct ieee80211vap because iv_debug +--- a/net80211/ieee80211_wireless.c ++++ b/net80211/ieee80211_wireless.c +@@ -2879,6 +2879,12 @@ + else + vap->iv_maxrateindex = 0; + break; ++ case IEEE80211_PARAM_MINRATE: ++ if (value > 0) ++ vap->iv_minrateindex = value; ++ else ++ vap->iv_minrateindex = 0; ++ break; + #ifdef ATH_REVERSE_ENGINEERING + case IEEE80211_PARAM_DUMPREGS: + ieee80211_dump_registers(dev, info, w, extra); +@@ -3220,6 +3226,9 @@ + case IEEE80211_PARAM_MAXRATE: + param[0] = vap->iv_maxrateindex; + break; ++ case IEEE80211_PARAM_MINRATE: ++ param[0] = vap->iv_minrateindex; ++ break; + default: + return -EOPNOTSUPP; + } +@@ -5679,6 +5688,10 @@ + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "maxrate"}, + {IEEE80211_PARAM_MAXRATE, + 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "get_maxrate"}, ++ {IEEE80211_PARAM_MINRATE, ++ IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "minrate"}, ++ {IEEE80211_PARAM_MINRATE, ++ 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "get_minrate"}, + + #ifdef ATH_REVERSE_ENGINEERING + /* diff --git a/package/madwifi/patches-testing/309-performance.patch b/package/madwifi/patches-testing/309-performance.patch new file mode 100644 index 0000000000..ec22085258 --- /dev/null +++ b/package/madwifi/patches-testing/309-performance.patch @@ -0,0 +1,215 @@ +--- a/ath/if_ath.c ++++ b/ath/if_ath.c +@@ -3334,7 +3334,6 @@ + struct ath_softc *sc = dev->priv; + struct ieee80211_node *ni = NULL; + struct ath_buf *bf = NULL; +- struct ether_header *eh; + ath_bufhead bf_head; + struct ath_buf *tbf; + struct sk_buff *tskb; +@@ -3349,6 +3348,7 @@ + */ + int requeue = 0; + #ifdef ATH_SUPERG_FF ++ struct ether_header *eh; + unsigned int pktlen; + struct ieee80211com *ic = &sc->sc_ic; + struct ath_txq *txq = NULL; +--- a/net80211/ieee80211_output.c ++++ b/net80211/ieee80211_output.c +@@ -280,7 +280,7 @@ + * normal vap. */ + if (vap->iv_xrvap && (ni == vap->iv_bss) && + vap->iv_xrvap->iv_sta_assoc) { +- struct sk_buff *skb1 = skb_copy(skb, GFP_ATOMIC); ++ struct sk_buff *skb1 = skb_clone(skb, GFP_ATOMIC); + if (skb1) { + memset(SKB_CB(skb1), 0, sizeof(struct ieee80211_cb)); + #ifdef IEEE80211_DEBUG_REFCNT +@@ -561,7 +561,7 @@ + struct ieee80211_key *key, struct sk_buff *skb, int ismulticast) + { + /* XXX pre-calculate per node? */ +- int need_headroom = LLC_SNAPFRAMELEN + hdrsize + IEEE80211_ADDR_LEN; ++ int need_headroom = LLC_SNAPFRAMELEN + hdrsize; + int need_tailroom = 0; + #ifdef ATH_SUPERG_FF + int isff = ATH_FF_MAGIC_PRESENT(skb); +@@ -603,109 +603,56 @@ + need_tailroom += cip->ic_miclen; + } + +- if (skb_shared(skb)) { +- /* Take our own reference to the node in the clone */ +- ieee80211_ref_node(SKB_NI(skb)); +- /* Unshare the node, decrementing users in the old skb */ +- skb = skb_unshare(skb, GFP_ATOMIC); ++ need_headroom -= skb_headroom(skb); ++ if (isff) ++ need_tailroom -= skb_tailroom(skb2); ++ else ++ need_tailroom -= skb_tailroom(skb); ++ ++ if (need_headroom < 0) ++ need_headroom = 0; ++ if (need_tailroom < 0) ++ need_tailroom = 0; ++ ++ if (skb_cloned(skb) || (need_headroom > 0) || ++ (!isff && (need_tailroom > 0))) { ++ ++ if (pskb_expand_head(skb, need_headroom, need_tailroom, GFP_ATOMIC)) { ++ IEEE80211_DPRINTF(vap, IEEE80211_MSG_OUTPUT, ++ "%s: cannot expand storage (tail)\n", __func__); ++ goto error; ++ } + } + + #ifdef ATH_SUPERG_FF + if (isff) { +- if (skb == NULL) { +- IEEE80211_DPRINTF(vap, IEEE80211_MSG_OUTPUT, +- "%s: cannot unshare for encapsulation\n", +- __func__); +- vap->iv_stats.is_tx_nobuf++; +- ieee80211_dev_kfree_skb(&skb2); +- +- return NULL; +- } ++ inter_headroom -= skb_headroom(skb2); ++ if (inter_headroom < 0) ++ inter_headroom = 0; ++ if ((skb_cloned(skb2) || ++ (inter_headroom > 0) || (need_tailroom > 0))) { + +- /* first skb header */ +- if (skb_headroom(skb) < need_headroom) { +- struct sk_buff *tmp = skb; +- skb = skb_realloc_headroom(skb, need_headroom); +- if (skb == NULL) { ++ if (pskb_expand_head(skb2, inter_headroom, ++ need_tailroom, GFP_ATOMIC)) { + IEEE80211_DPRINTF(vap, IEEE80211_MSG_OUTPUT, +- "%s: cannot expand storage (head1)\n", +- __func__); +- vap->iv_stats.is_tx_nobuf++; +- ieee80211_dev_kfree_skb(&skb2); +- return NULL; +- } else +- ieee80211_skb_copy_noderef(tmp, skb); +- ieee80211_dev_kfree_skb(&tmp); +- /* NB: cb[] area was copied, but not next ptr. must do that +- * prior to return on success. */ +- } +- +- /* second skb with header and tail adjustments possible */ +- if (skb_tailroom(skb2) < need_tailroom) { +- int n = 0; +- if (inter_headroom > skb_headroom(skb2)) +- n = inter_headroom - skb_headroom(skb2); +- if (pskb_expand_head(skb2, n, +- need_tailroom - skb_tailroom(skb2), GFP_ATOMIC)) { +- ieee80211_dev_kfree_skb(&skb2); +- IEEE80211_DPRINTF(vap, IEEE80211_MSG_OUTPUT, +- "%s: cannot expand storage (tail2)\n", +- __func__); +- vap->iv_stats.is_tx_nobuf++; +- /* this shouldn't happen, but don't send first ff either */ +- ieee80211_dev_kfree_skb(&skb); ++ "%s: cannot expand storage (tail)\n", __func__); ++ goto error; + } +- } else if (skb_headroom(skb2) < inter_headroom) { +- struct sk_buff *tmp = skb2; +- +- skb2 = skb_realloc_headroom(skb2, inter_headroom); +- if (skb2 == NULL) { +- IEEE80211_DPRINTF(vap, IEEE80211_MSG_OUTPUT, +- "%s: cannot expand storage (head2)\n", +- __func__); +- vap->iv_stats.is_tx_nobuf++; +- /* this shouldn't happen, but don't send first ff either */ +- ieee80211_dev_kfree_skb(&skb); +- skb = NULL; +- } else +- ieee80211_skb_copy_noderef(tmp, skb); +- ieee80211_dev_kfree_skb(&tmp); + } +- if (skb) { +- skb->next = skb2; +- } +- return skb; ++ skb->next = skb2; + } + #endif /* ATH_SUPERG_FF */ +- if (skb == NULL) { +- IEEE80211_DPRINTF(vap, IEEE80211_MSG_OUTPUT, +- "%s: cannot unshare for encapsulation\n", __func__); +- vap->iv_stats.is_tx_nobuf++; +- } else if (skb_tailroom(skb) < need_tailroom) { +- int n = 0; +- if (need_headroom > skb_headroom(skb)) +- n = need_headroom - skb_headroom(skb); +- if (pskb_expand_head(skb, n, need_tailroom - +- skb_tailroom(skb), GFP_ATOMIC)) { +- IEEE80211_DPRINTF(vap, IEEE80211_MSG_OUTPUT, +- "%s: cannot expand storage (tail)\n", __func__); +- vap->iv_stats.is_tx_nobuf++; +- ieee80211_dev_kfree_skb(&skb); +- } +- } else if (skb_headroom(skb) < need_headroom) { +- struct sk_buff *tmp = skb; +- skb = skb_realloc_headroom(skb, need_headroom); +- /* Increment reference count after copy */ +- if (skb == NULL) { +- IEEE80211_DPRINTF(vap, IEEE80211_MSG_OUTPUT, +- "%s: cannot expand storage (head)\n", __func__); +- vap->iv_stats.is_tx_nobuf++; +- } else +- ieee80211_skb_copy_noderef(tmp, skb); +- ieee80211_dev_kfree_skb(&tmp); +- } + + return skb; ++ ++error: ++ vap->iv_stats.is_tx_nobuf++; ++ ieee80211_dev_kfree_skb(&skb); ++#ifdef ATH_SUPERG_FF ++ if (skb2) ++ ieee80211_dev_kfree_skb(&skb2); ++#endif ++ return NULL; + } + + #define KEY_UNDEFINED(k) ((k).wk_cipher == &ieee80211_cipher_none) +--- a/net80211/ieee80211_input.c ++++ b/net80211/ieee80211_input.c +@@ -713,7 +713,7 @@ + /* ether_type must be length as FF frames are always LLC/SNAP encap'd */ + frame_len = ntohs(eh_tmp->ether_type); + +- skb1 = skb_copy(skb, GFP_ATOMIC); ++ skb1 = skb_clone(skb, GFP_ATOMIC); + if (skb1 == NULL) + goto err; + ieee80211_skb_copy_noderef(skb, skb1); +@@ -1118,7 +1118,7 @@ + + if (ETHER_IS_MULTICAST(eh->ether_dhost) && !netif_queue_stopped(dev)) { + /* Create a SKB for the BSS to send out. */ +- skb1 = skb_copy(skb, GFP_ATOMIC); ++ skb1 = skb_clone(skb, GFP_ATOMIC); + if (skb1) + SKB_NI(skb1) = ieee80211_ref_node(vap->iv_bss); + } +@@ -2265,7 +2265,7 @@ + if (filter_type && ((vap->app_filter & filter_type) == filter_type)) { + struct sk_buff *skb1; + +- skb1 = skb_copy(skb, GFP_ATOMIC); ++ skb1 = skb_clone(skb, GFP_ATOMIC); + if (skb1 == NULL) + return; + /* We duplicate the reference after skb_copy */ diff --git a/package/madwifi/patches-testing/310-minstrel_sampling.patch b/package/madwifi/patches-testing/310-minstrel_sampling.patch new file mode 100644 index 0000000000..b7f55d5005 --- /dev/null +++ b/package/madwifi/patches-testing/310-minstrel_sampling.patch @@ -0,0 +1,84 @@ +--- a/ath/if_ath.c ++++ b/ath/if_ath.c +@@ -8110,6 +8110,7 @@ + ath_hal_setupxtxdesc(sc->sc_ah, ds, mrr.rate1, mrr.retries1, + mrr.rate2, mrr.retries2, + mrr.rate3, mrr.retries3); ++ bf->rcflags = mrr.privflags; + } + + #ifndef ATH_SUPERG_FF +--- a/ath/if_athvar.h ++++ b/ath/if_athvar.h +@@ -454,6 +454,7 @@ + u_int16_t bf_flags; /* tx descriptor flags */ + u_int64_t bf_tsf; + int16_t bf_channoise; ++ unsigned int rcflags; + #ifdef ATH_SUPERG_FF + /* XXX: combine this with bf_skbaddr if it ever changes to accommodate + * multiple segments. +--- a/ath_rate/minstrel/minstrel.c ++++ b/ath_rate/minstrel/minstrel.c +@@ -341,18 +341,21 @@ + if (sn->static_rate_ndx >= 0) { + ndx = sn->static_rate_ndx; + } else { ++ int delta; ++ + sn->packet_count++; + sn->random_n = (sn->a * sn->random_n) + sn->b; + offset = sn->random_n & 0xf; + +- if ((((100 * sn->sample_count) / sn->packet_count) < +- ath_lookaround_rate) && +- (offset < 2)) { ++ delta = (sn->packet_count * ath_lookaround_rate / 100) - sn->sample_count; ++ if ((delta > 0) && (offset < 2)) { + sn->sample_count++; + sn->is_sampling = 1; + if (sn->packet_count >= 10000) { + sn->sample_count = 0; + sn->packet_count = 0; ++ } else if (delta > sn->num_rates * 2) { ++ sn->sample_count += ((delta - sn->num_rates * 2) * ath_lookaround_rate) / 100; + } + + /* Don't look for slowest rate (i.e. slowest +@@ -420,11 +423,14 @@ + if (sn->num_rates <= 0) + return; + ++ mrr->privflags = sn->is_sampling; + if (sn->is_sampling) { + sn->is_sampling = 0; +- if (sn->rs_sample_rate_slower) ++ if (sn->rs_sample_rate_slower) { + rc1 = sn->rs_sample_rate; +- else ++ if (sn->sample_count > 0) ++ sn->sample_count--; ++ } else + rc1 = sn->max_tp_rate; + } else { + rc1 = sn->max_tp_rate2; +@@ -552,6 +558,9 @@ + if (tries <= tries1) + return; + ++ if (bf->rcflags) ++ sn->sample_count++; ++ + if (tries2 < 0) + return; + tries = tries - tries1; +--- a/net80211/ieee80211_rate.h ++++ b/net80211/ieee80211_rate.h +@@ -87,6 +87,7 @@ + int retries2; + int rate3; + int retries3; ++ int privflags; + }; + + struct ieee80211_rate_ops { diff --git a/package/madwifi/patches-testing/311-protmode_trigger.patch b/package/madwifi/patches-testing/311-protmode_trigger.patch new file mode 100644 index 0000000000..2f462b9a6c --- /dev/null +++ b/package/madwifi/patches-testing/311-protmode_trigger.patch @@ -0,0 +1,135 @@ +--- a/net80211/ieee80211.c ++++ b/net80211/ieee80211.c +@@ -347,7 +347,9 @@ + IEEE80211_MS_TO_TU(IEEE80211_BMISSTHRESH_DEFAULT_MS), + ic->ic_lintval), ic->ic_lintval); + } +- ++ ic->ic_protmode_timeout = IEEE80211_PROTMODE_TIMEOUT; ++ ic->ic_protmode_rssi = IEEE80211_PROTMODE_RSSITHR; ++ + IEEE80211_LOCK_INIT(ic, "ieee80211com"); + IEEE80211_VAPS_LOCK_INIT(ic, "ieee80211com_vaps"); + TAILQ_INIT(&ic->ic_vaps); +--- a/net80211/ieee80211_input.c ++++ b/net80211/ieee80211_input.c +@@ -3382,14 +3382,18 @@ + IEEE80211_IS_CHAN_ANYG(ic->ic_curchan)) { + + /* Assume no ERP IE == 11b AP */ +- if ((!has_erp || (has_erp && (scan.erp & IEEE80211_ERP_NON_ERP_PRESENT))) && +- !(ic->ic_flags & IEEE80211_F_USEPROT)) { ++ if ((!has_erp || (has_erp && ++ (scan.erp & IEEE80211_ERP_NON_ERP_PRESENT))) && ++ (rssi > ic->ic_protmode_rssi)) { + struct ieee80211vap *tmpvap; + +- ic->ic_flags |= IEEE80211_F_USEPROT; +- TAILQ_FOREACH(tmpvap, &ic->ic_vaps, iv_next) { +- tmpvap->iv_flags_ext |= IEEE80211_FEXT_ERPUPDATE; ++ if (!(ic->ic_flags & IEEE80211_F_USEPROT)) { ++ ic->ic_flags |= IEEE80211_F_USEPROT; ++ TAILQ_FOREACH(tmpvap, &ic->ic_vaps, iv_next) { ++ tmpvap->iv_flags_ext |= IEEE80211_FEXT_ERPUPDATE; ++ } + } ++ ic->ic_protmode_lasttrig = jiffies; + } + } + +--- a/net80211/ieee80211_ioctl.h ++++ b/net80211/ieee80211_ioctl.h +@@ -652,6 +652,8 @@ + IEEE80211_PARAM_LEAKTXBUFS = 82, /* Leak tx buffers */ + IEEE80211_PARAM_MAXRATE = 83, /* Maximum rate (by table index) */ + IEEE80211_PARAM_MINRATE = 84, /* Minimum rate (by table index) */ ++ IEEE80211_PARAM_PROTMODE_RSSI = 85, /* RSSI Threshold for enabling protection mode */ ++ IEEE80211_PARAM_PROTMODE_TIMEOUT = 86, /* Timeout for expiring protection mode */ + }; + + #define SIOCG80211STATS (SIOCDEVPRIVATE+2) +--- a/net80211/ieee80211_var.h ++++ b/net80211/ieee80211_var.h +@@ -138,6 +138,9 @@ + + #define IEEE80211_APPIE_MAX 1024 + ++#define IEEE80211_PROTMODE_RSSITHR 15 /* default rssi threshold for protection mode trigger */ ++#define IEEE80211_PROTMODE_TIMEOUT 30 /* timeout for keeping protection mode alive */ ++ + #define IEEE80211_PWRCONSTRAINT_VAL(ic) \ + (((ic)->ic_bsschan->ic_maxregpower > (ic)->ic_curchanmaxpwr) ? \ + (ic)->ic_bsschan->ic_maxregpower - (ic)->ic_curchanmaxpwr : 0) +@@ -335,6 +338,9 @@ + u_int16_t ic_newtxpowlimit; /* tx power limit to change to (in 0.5 dBm) */ + u_int16_t ic_uapsdmaxtriggers; /* max triggers that could arrive */ + u_int8_t ic_coverageclass; /* coverage class */ ++ u_int8_t ic_protmode_rssi; /* rssi threshold for protection mode */ ++ u_int64_t ic_protmode_lasttrig; /* last trigger for protection mode */ ++ u_int16_t ic_protmode_timeout; /* protection mode timeout */ + + /* Channel state: + * +--- a/net80211/ieee80211_wireless.c ++++ b/net80211/ieee80211_wireless.c +@@ -2336,6 +2336,12 @@ + case IEEE80211_PARAM_RSSI_EWMA: + ic->ic_rssi_ewma = value; + break; ++ case IEEE80211_PARAM_PROTMODE_TIMEOUT: ++ ic->ic_protmode_timeout = value; ++ break; ++ case IEEE80211_PARAM_PROTMODE_RSSI: ++ ic->ic_protmode_rssi = value; ++ break; + case IEEE80211_PARAM_MCASTCIPHER: + if ((vap->iv_caps & cipher2cap(value)) == 0 && + !ieee80211_crypto_available(vap, value)) +@@ -2992,6 +2998,12 @@ + case IEEE80211_PARAM_RSSI_EWMA: + param[0] = ic->ic_rssi_ewma; + break; ++ case IEEE80211_PARAM_PROTMODE_TIMEOUT: ++ param[0] = ic->ic_protmode_timeout; ++ break; ++ case IEEE80211_PARAM_PROTMODE_RSSI: ++ param[0] = ic->ic_protmode_rssi; ++ break; + case IEEE80211_PARAM_MCASTCIPHER: + param[0] = rsn->rsn_mcastcipher; + break; +@@ -5384,6 +5396,14 @@ + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "protmode" }, + { IEEE80211_PARAM_PROTMODE, + 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "get_protmode" }, ++ { IEEE80211_PARAM_PROTMODE_RSSI, ++ IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "protrssi" }, ++ { IEEE80211_PARAM_PROTMODE_RSSI, ++ 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "get_protrssi" }, ++ { IEEE80211_PARAM_PROTMODE_TIMEOUT, ++ IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "prottime" }, ++ { IEEE80211_PARAM_PROTMODE_TIMEOUT, ++ 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "get_prottime" }, + { IEEE80211_PARAM_MCASTCIPHER, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "mcastcipher" }, + { IEEE80211_PARAM_MCASTCIPHER, +--- a/net80211/ieee80211_node.c ++++ b/net80211/ieee80211_node.c +@@ -1591,6 +1591,17 @@ + + ieee80211_scan_timeout(ic); + ieee80211_timeout_stations(&ic->ic_sta); ++ if ((ic->ic_flags & IEEE80211_F_USEPROT) && ++ (ic->ic_protmode_lasttrig + ic->ic_protmode_timeout * HZ < ++ jiffies)) { ++ struct ieee80211vap *tmpvap; ++ ++ /* expire protection mode */ ++ ic->ic_flags &= ~IEEE80211_F_USEPROT; ++ TAILQ_FOREACH(tmpvap, &ic->ic_vaps, iv_next) { ++ tmpvap->iv_flags_ext |= IEEE80211_FEXT_ERPUPDATE; ++ } ++ } + + mod_timer(&ic->ic_inact, jiffies + IEEE80211_INACT_WAIT * HZ); + } diff --git a/package/madwifi/patches-testing/312-ack_cts_rate.patch b/package/madwifi/patches-testing/312-ack_cts_rate.patch new file mode 100644 index 0000000000..42bb4c1711 --- /dev/null +++ b/package/madwifi/patches-testing/312-ack_cts_rate.patch @@ -0,0 +1,40 @@ +--- a/ath/if_ath.c ++++ b/ath/if_ath.c +@@ -10890,8 +10890,13 @@ + break; + #endif + case ATH_ACKRATE: +- sc->sc_ackrate = val; +- ath_set_ack_bitrate(sc, sc->sc_ackrate); ++ if (val == -1) ++ sc->sc_ackrate_override = 0; ++ else { ++ sc->sc_ackrate_override = 1; ++ sc->sc_ackrate = val; ++ ath_set_ack_bitrate(sc, sc->sc_ackrate); ++ } + break; + case ATH_RP: + ath_rp_record(sc, +--- a/ath/if_athvar.h ++++ b/ath/if_athvar.h +@@ -698,6 +698,7 @@ + unsigned int sc_hasclrkey:1; /* CLR key supported */ + unsigned int sc_stagbeacons:1; /* use staggered beacons */ + unsigned int sc_dfswait:1; /* waiting on channel for radar detect */ ++ unsigned int sc_ackrate_override:1; /* override ack rate */ + unsigned int sc_ackrate:1; /* send acks at high bitrate */ + unsigned int sc_dfs_cac:1; /* waiting on channel for radar detect */ + unsigned int sc_hasintmit:1; /* Interference mitigation */ +--- a/ath/if_ath_hal_extensions.c ++++ b/ath/if_ath_hal_extensions.c +@@ -129,6 +129,9 @@ + int + ath_set_ack_bitrate(struct ath_softc *sc, int high) + { ++ if (!sc->sc_ackrate_override) ++ return 0; ++ + if (ar_device(sc->devid) == 5212 || ar_device(sc->devid) == 5213) { + /* set ack to be sent at low bit-rate */ + u_int32_t v = AR5K_STA_ID1_BASE_RATE_11B | AR5K_STA_ID1_ACKCTS_6MB; diff --git a/package/madwifi/patches-testing/313-reset_channelchange.patch b/package/madwifi/patches-testing/313-reset_channelchange.patch new file mode 100644 index 0000000000..42d18ece07 --- /dev/null +++ b/package/madwifi/patches-testing/313-reset_channelchange.patch @@ -0,0 +1,18 @@ +--- a/ath/if_ath.c ++++ b/ath/if_ath.c +@@ -8866,14 +8866,7 @@ + hchan.channel, + jiffies); + +- /* ath_hal_reset with chanchange = AH_TRUE doesn't seem to +- * completely reset the state of the card. According to +- * reports from ticket #1106, kismet and aircrack people they +- * needed to do the reset with chanchange = AH_FALSE in order +- * to receive traffic when peforming high velocity channel +- * changes. */ +- if (!ath_hw_reset(sc, sc->sc_opmode, &hchan, AH_TRUE, &status) || +- !ath_hw_reset(sc, sc->sc_opmode, &hchan, AH_FALSE, &status)) { ++ if (!ath_hw_reset(sc, sc->sc_opmode, &hchan, AH_TRUE, &status)) { + EPRINTF(sc, "Unable to reset channel %u (%u MHz) " + "flags 0x%x '%s' (HAL status %u)\n", + ieee80211_chan2ieee(ic, chan), chan->ic_freq, diff --git a/package/madwifi/patches-testing/314-wisoc_softled.patch b/package/madwifi/patches-testing/314-wisoc_softled.patch new file mode 100644 index 0000000000..ca5ffdce4b --- /dev/null +++ b/package/madwifi/patches-testing/314-wisoc_softled.patch @@ -0,0 +1,11 @@ +--- a/ath/if_ath_ahb.c ++++ b/ath/if_ath_ahb.c +@@ -245,6 +245,8 @@ + num_activesc++; + /* Ready to process interrupts */ + ++ sc->aps_sc.sc_softled = 1; /* SoftLED over GPIO */ ++ sc->aps_sc.sc_ledpin = config->board->sysLedGpio; + sc->aps_sc.sc_invalid = 0; + return 0; + diff --git a/package/madwifi/patches-testing/315-scanlist.patch b/package/madwifi/patches-testing/315-scanlist.patch new file mode 100644 index 0000000000..0ae0ed010a --- /dev/null +++ b/package/madwifi/patches-testing/315-scanlist.patch @@ -0,0 +1,876 @@ +--- a/net80211/ieee80211_scan_sta.c ++++ b/net80211/ieee80211_scan_sta.c +@@ -318,147 +318,6 @@ + #undef ISPROBE + } + +-static struct ieee80211_channel * +-find11gchannel(struct ieee80211com *ic, int i, int freq) +-{ +- struct ieee80211_channel *c; +- int j; +- +- /* +- * The normal ordering in the channel list is b channel +- * immediately followed by g so optimize the search for +- * this. We'll still do a full search just in case. +- */ +- for (j = i+1; j < ic->ic_nchans; j++) { +- c = &ic->ic_channels[j]; +- if (c->ic_freq == freq && IEEE80211_IS_CHAN_ANYG(c)) +- return c; +- } +- for (j = 0; j < i; j++) { +- c = &ic->ic_channels[j]; +- if (c->ic_freq == freq && IEEE80211_IS_CHAN_ANYG(c)) +- return c; +- } +- return NULL; +-} +-static const u_int chanflags[] = { +- IEEE80211_CHAN_B, /* IEEE80211_MODE_AUTO */ +- IEEE80211_CHAN_A, /* IEEE80211_MODE_11A */ +- IEEE80211_CHAN_B, /* IEEE80211_MODE_11B */ +- IEEE80211_CHAN_PUREG, /* IEEE80211_MODE_11G */ +- IEEE80211_CHAN_FHSS, /* IEEE80211_MODE_FH */ +- IEEE80211_CHAN_A, /* IEEE80211_MODE_TURBO_A */ /* for turbo mode look for AP in normal channel */ +- IEEE80211_CHAN_PUREG, /* IEEE80211_MODE_TURBO_G */ +- IEEE80211_CHAN_ST, /* IEEE80211_MODE_TURBO_STATIC_A */ +-}; +- +-static void +-add_channels(struct ieee80211com *ic, +- struct ieee80211_scan_state *ss, +- enum ieee80211_phymode mode, const u_int16_t freq[], int nfreq) +-{ +- struct ieee80211_channel *c, *cg; +- u_int modeflags; +- int i; +- +- KASSERT(mode < ARRAY_SIZE(chanflags), ("Unexpected mode %u", mode)); +- modeflags = chanflags[mode]; +- for (i = 0; i < nfreq; i++) { +- c = ieee80211_find_channel(ic, freq[i], modeflags); +- if (c == NULL || isclr(ic->ic_chan_active, c->ic_ieee)) +- continue; +- if (mode == IEEE80211_MODE_AUTO) { +- /* +- * XXX special-case 11b/g channels so we select +- * the g channel if both are present. +- */ +- if (IEEE80211_IS_CHAN_B(c) && +- (cg = find11gchannel(ic, i, c->ic_freq)) != NULL) +- c = cg; +- } +- if (ss->ss_last >= IEEE80211_SCAN_MAX) +- break; +- ss->ss_chans[ss->ss_last++] = c; +- } +-} +- +-static const u_int16_t rcl1[] = /* 8 FCC channel: 52, 56, 60, 64, 36, 40, 44, 48 */ +-{ 5260, 5280, 5300, 5320, 5180, 5200, 5220, 5240 }; +-static const u_int16_t rcl2[] = /* 4 MKK channels: 34, 38, 42, 46 */ +-{ 5170, 5190, 5210, 5230 }; +-static const u_int16_t rcl3[] = /* 2.4Ghz ch: 1,6,11,7,13 */ +-{ 2412, 2437, 2462, 2442, 2472 }; +-static const u_int16_t rcl4[] = /* 5 FCC channel: 149, 153, 161, 165 */ +-{ 5745, 5765, 5785, 5805, 5825 }; +-static const u_int16_t rcl7[] = /* 11 ETSI channel: 100,104,108,112,116,120,124,128,132,136,140 */ +-{ 5500, 5520, 5540, 5560, 5580, 5600, 5620, 5640, 5660, 5680, 5700 }; +-static const u_int16_t rcl8[] = /* 2.4Ghz ch: 2,3,4,5,8,9,10,12 */ +-{ 2417, 2422, 2427, 2432, 2447, 2452, 2457, 2467 }; +-static const u_int16_t rcl9[] = /* 2.4Ghz ch: 14 */ +-{ 2484 }; +-static const u_int16_t rcl10[] = /* Added Korean channels 2312-2372 */ +-{ 2312, 2317, 2322, 2327, 2332, 2337, 2342, 2347, 2352, 2357, 2362, 2367, 2372 }; +-static const u_int16_t rcl11[] = /* Added Japan channels in 4.9/5.0 spectrum */ +-{ 5040, 5060, 5080, 4920, 4940, 4960, 4980 }; +-#ifdef ATH_TURBO_SCAN +-static const u_int16_t rcl5[] = /* 3 static turbo channels */ +-{ 5210, 5250, 5290 }; +-static const u_int16_t rcl6[] = /* 2 static turbo channels */ +-{ 5760, 5800 }; +-static const u_int16_t rcl6x[] = /* 4 FCC3 turbo channels */ +-{ 5540, 5580, 5620, 5660 }; +-static const u_int16_t rcl12[] = /* 2.4Ghz Turbo channel 6 */ +-{ 2437 }; +-static const u_int16_t rcl13[] = /* dynamic Turbo channels */ +-{ 5200, 5240, 5280, 5765, 5805 }; +-#endif /* ATH_TURBO_SCAN */ +- +-struct scanlist { +- u_int16_t mode; +- u_int16_t count; +- const u_int16_t *list; +-}; +- +-#define IEEE80211_MODE_TURBO_STATIC_A IEEE80211_MODE_MAX +-#define X(a) .count = sizeof(a)/sizeof(a[0]), .list = a +- +-static const struct scanlist staScanTable[] = { +- { IEEE80211_MODE_11B, X(rcl3) }, +- { IEEE80211_MODE_11A, X(rcl1) }, +- { IEEE80211_MODE_11A, X(rcl2) }, +- { IEEE80211_MODE_11B, X(rcl8) }, +- { IEEE80211_MODE_11B, X(rcl9) }, +- { IEEE80211_MODE_11A, X(rcl4) }, +-#ifdef ATH_TURBO_SCAN +- { IEEE80211_MODE_TURBO_STATIC_A, X(rcl5) }, +- { IEEE80211_MODE_TURBO_STATIC_A, X(rcl6) }, +- { IEEE80211_MODE_TURBO_A, X(rcl6x) }, +- { IEEE80211_MODE_TURBO_A, X(rcl13) }, +-#endif /* ATH_TURBO_SCAN */ +- { IEEE80211_MODE_11A, X(rcl7) }, +- { IEEE80211_MODE_11B, X(rcl10) }, +- { IEEE80211_MODE_11A, X(rcl11) }, +-#ifdef ATH_TURBO_SCAN +- { IEEE80211_MODE_TURBO_G, X(rcl12) }, +-#endif /* ATH_TURBO_SCAN */ +- { .list = NULL } +-}; +- +-#undef X +- +-static int +-checktable(const struct scanlist *scan, const struct ieee80211_channel *c) +-{ +- int i; +- +- for (; scan->list != NULL; scan++) { +- for (i = 0; i < scan->count; i++) +- if (scan->list[i] == c->ic_freq) +- return 1; +- } +- return 0; +-} +- + /* + * Start a station-mode scan by populating the channel list. + */ +@@ -467,81 +326,11 @@ + { + struct ieee80211com *ic = vap->iv_ic; + struct sta_table *st = ss->ss_priv; +- const struct scanlist *scan; +- enum ieee80211_phymode mode; +- struct ieee80211_channel *c; +- int i; + + ss->ss_last = 0; +- /* +- * Use the table of ordered channels to construct the list +- * of channels for scanning. Any channels in the ordered +- * list not in the master list will be discarded. +- */ +- for (scan = staScanTable; scan->list != NULL; scan++) { +- mode = scan->mode; +- if (vap->iv_des_mode != IEEE80211_MODE_AUTO) { +- /* +- * If a desired mode was specified, scan only +- * channels that satisfy that constraint. +- */ +- if (vap->iv_des_mode != mode) { +- /* +- * The scan table marks 2.4Ghz channels as b +- * so if the desired mode is 11g, then use +- * the 11b channel list but upgrade the mode. +- */ +- if (vap->iv_des_mode != IEEE80211_MODE_11G || +- mode != IEEE80211_MODE_11B) +- continue; +- mode = IEEE80211_MODE_11G; /* upgrade */ +- } +- } else { +- /* +- * This lets ieee80211_scan_add_channels +- * upgrade an 11b channel to 11g if available. +- */ +- if (mode == IEEE80211_MODE_11B) +- mode = IEEE80211_MODE_AUTO; +- } +- /* XR does not operate on turbo channels */ +- if ((vap->iv_flags & IEEE80211_F_XR) && +- (mode == IEEE80211_MODE_TURBO_A || +- mode == IEEE80211_MODE_TURBO_G)) +- continue; +- /* +- * Add the list of the channels; any that are not +- * in the master channel list will be discarded. +- */ +- add_channels(ic, ss, mode, scan->list, scan->count); +- } +- +- /* +- * Add the channels from the ic (from HAL) that are not present +- * in the staScanTable. +- */ +- for (i = 0; i < ic->ic_nchans; i++) { +- c = &ic->ic_channels[i]; +- /* +- * scan dynamic turbo channels in normal mode. +- */ +- if (IEEE80211_IS_CHAN_DTURBO(c)) +- continue; +- mode = ieee80211_chan2mode(c); +- if (vap->iv_des_mode != IEEE80211_MODE_AUTO) { +- /* +- * If a desired mode was specified, scan only +- * channels that satisfy that constraint. +- */ +- if (vap->iv_des_mode != mode) +- continue; +- +- } +- if (!checktable(staScanTable, c)) +- ss->ss_chans[ss->ss_last++] = c; +- } +- ++ ieee80211_scan_add_channels(ic, ss, vap->iv_des_mode); + ss->ss_next = 0; ++ + /* XXX tunables */ + /* + * The scanner will stay on station for ss_maxdwell ms (using a +@@ -750,17 +539,7 @@ + fail = 0; + if (isclr(ic->ic_chan_active, ieee80211_chan2ieee(ic, se->se_chan))) + fail |= 0x01; +- /* +- * NB: normally the desired mode is used to construct +- * the channel list, but it's possible for the scan +- * cache to include entries for stations outside this +- * list so we check the desired mode here to weed them +- * out. +- */ +- if (vap->iv_des_mode != IEEE80211_MODE_AUTO && +- (se->se_chan->ic_flags & IEEE80211_CHAN_ALLTURBO) != +- chanflags[vap->iv_des_mode]) +- fail |= 0x01; ++ + if (vap->iv_opmode == IEEE80211_M_IBSS) { + if ((se->se_capinfo & IEEE80211_CAPINFO_IBSS) == 0) + fail |= 0x02; +@@ -1175,78 +954,6 @@ + .scan_default = ieee80211_sta_join, + }; + +-/* +- * Start an adhoc-mode scan by populating the channel list. +- */ +-static int +-adhoc_start(struct ieee80211_scan_state *ss, struct ieee80211vap *vap) +-{ +- struct ieee80211com *ic = vap->iv_ic; +- struct sta_table *st = ss->ss_priv; +- const struct scanlist *scan; +- enum ieee80211_phymode mode; +- +- ss->ss_last = 0; +- /* +- * Use the table of ordered channels to construct the list +- * of channels for scanning. Any channels in the ordered +- * list not in the master list will be discarded. +- */ +- for (scan = staScanTable; scan->list != NULL; scan++) { +- mode = scan->mode; +- if (vap->iv_des_mode != IEEE80211_MODE_AUTO) { +- /* +- * If a desired mode was specified, scan only +- * channels that satisfy that constraint. +- */ +- if (vap->iv_des_mode != mode) { +- /* +- * The scan table marks 2.4Ghz channels as b +- * so if the desired mode is 11g, then use +- * the 11b channel list but upgrade the mode. +- */ +- if (vap->iv_des_mode != IEEE80211_MODE_11G || +- mode != IEEE80211_MODE_11B) +- continue; +- mode = IEEE80211_MODE_11G; /* upgrade */ +- } +- } else { +- /* +- * This lets ieee80211_scan_add_channels +- * upgrade an 11b channel to 11g if available. +- */ +- if (mode == IEEE80211_MODE_11B) +- mode = IEEE80211_MODE_AUTO; +- } +- /* XR does not operate on turbo channels */ +- if ((vap->iv_flags & IEEE80211_F_XR) && +- (mode == IEEE80211_MODE_TURBO_A || +- mode == IEEE80211_MODE_TURBO_G)) +- continue; +- /* +- * Add the list of the channels; any that are not +- * in the master channel list will be discarded. +- */ +- add_channels(ic, ss, mode, scan->list, scan->count); +- } +- ss->ss_next = 0; +- /* XXX tunables */ +- ss->ss_mindwell = msecs_to_jiffies(200); /* 200ms */ +- ss->ss_maxdwell = msecs_to_jiffies(200); /* 200ms */ +- +-#ifdef IEEE80211_DEBUG +- if (ieee80211_msg_scan(vap)) { +- printk("%s: scan set ", vap->iv_dev->name); +- ieee80211_scan_dump_channels(ss); +- printk(" dwell min %ld max %ld\n", +- ss->ss_mindwell, ss->ss_maxdwell); +- } +-#endif /* IEEE80211_DEBUG */ +- +- st->st_newscan = 1; +- +- return 0; +-} + + /* + * Select a channel to start an adhoc network on. +@@ -1412,7 +1119,7 @@ + .scan_name = "default", + .scan_attach = sta_attach, + .scan_detach = sta_detach, +- .scan_start = adhoc_start, ++ .scan_start = sta_start, + .scan_restart = sta_restart, + .scan_cancel = sta_cancel, + .scan_end = adhoc_pick_bss, +--- a/net80211/ieee80211.c ++++ b/net80211/ieee80211.c +@@ -292,6 +292,11 @@ + ("channel with bogus ieee number %u", c->ic_ieee)); + setbit(ic->ic_chan_avail, c->ic_ieee); + ++ if (c->ic_scanflags & IEEE80211_NOSCAN_DEFAULT) ++ c->ic_scanflags |= IEEE80211_NOSCAN_SET; ++ else ++ c->ic_scanflags &= ~IEEE80211_NOSCAN_SET; ++ + /* Identify mode capabilities. */ + if (IEEE80211_IS_CHAN_A(c)) + ic->ic_modecaps |= 1 << IEEE80211_MODE_11A; +--- a/net80211/_ieee80211.h ++++ b/net80211/_ieee80211.h +@@ -132,6 +132,11 @@ + IEEE80211_SCAN_FIRST = 2, /* take first suitable candidate */ + }; + ++enum ieee80211_scanflags { ++ IEEE80211_NOSCAN_DEFAULT = (1 << 0), ++ IEEE80211_NOSCAN_SET = (1 << 1), ++}; ++ + /* + * Channels are specified by frequency and attributes. + */ +@@ -142,6 +147,7 @@ + int8_t ic_maxregpower; /* maximum regulatory tx power in dBm */ + int8_t ic_maxpower; /* maximum tx power in dBm */ + int8_t ic_minpower; /* minimum tx power in dBm */ ++ u_int8_t ic_scanflags; + }; + + #define IEEE80211_CHAN_MAX 255 +--- a/net80211/ieee80211_ioctl.h ++++ b/net80211/ieee80211_ioctl.h +@@ -556,6 +556,7 @@ + #define IEEE80211_IOCTL_WDSADDMAC (SIOCIWFIRSTPRIV+26) + #define IEEE80211_IOCTL_WDSDELMAC (SIOCIWFIRSTPRIV+28) + #define IEEE80211_IOCTL_KICKMAC (SIOCIWFIRSTPRIV+30) ++#define IEEE80211_IOCTL_SETSCANLIST (SIOCIWFIRSTPRIV+31) + + enum { + IEEE80211_WMMPARAMS_CWMIN = 1, +--- a/net80211/ieee80211_scan_ap.c ++++ b/net80211/ieee80211_scan_ap.c +@@ -200,131 +200,7 @@ + + static int ap_flush(struct ieee80211_scan_state *); + static void action_tasklet(IEEE80211_TQUEUE_ARG); +-static struct ieee80211_channel *find11gchannel(struct ieee80211com *ic, +- int i, int freq); + +-static const u_int chanflags[] = { +- IEEE80211_CHAN_B, /* IEEE80211_MODE_AUTO */ +- IEEE80211_CHAN_A, /* IEEE80211_MODE_11A */ +- IEEE80211_CHAN_B, /* IEEE80211_MODE_11B */ +- IEEE80211_CHAN_PUREG, /* IEEE80211_MODE_11G */ +- IEEE80211_CHAN_FHSS, /* IEEE80211_MODE_FH */ +- IEEE80211_CHAN_A, /* IEEE80211_MODE_TURBO_A */ /* for turbo mode +- * look for AP in +- * normal channel +- */ +- IEEE80211_CHAN_PUREG, /* IEEE80211_MODE_TURBO_G */ +- IEEE80211_CHAN_ST, /* IEEE80211_MODE_TURBO_STATIC_A */ +-}; +- +-static const u_int16_t rcl1[] = /* 8 FCC channel: 52, 56, 60, 64, +- * 36, 40, 44, 48 */ +-{ 5260, 5280, 5300, 5320, 5180, 5200, 5220, 5240 }; +-static const u_int16_t rcl2[] = /* 4 MKK channels: 34, 38, 42, 46 */ +-{ 5170, 5190, 5210, 5230 }; +-static const u_int16_t rcl3[] = /* 2.4Ghz ch: 1,6,11,7,13 */ +-{ 2412, 2437, 2462, 2442, 2472 }; +-static const u_int16_t rcl4[] = /* 5 FCC channel: 149, 153, 161, 165 */ +-{ 5745, 5765, 5785, 5805, 5825 }; +-static const u_int16_t rcl7[] = /* 11 ETSI channel: 100, 104, 108, 112, +- * 116, 120, 124, 128, +- * 132, 136, 140 */ +-{ 5500, 5520, 5540, 5560, 5580, 5600, 5620, 5640, 5660, 5680, 5700 }; +-static const u_int16_t rcl8[] = /* 2.4Ghz ch: 2,3,4,5,8,9,10,12 */ +-{ 2417, 2422, 2427, 2432, 2447, 2452, 2457, 2467 }; +-static const u_int16_t rcl9[] = /* 2.4Ghz ch: 14 */ +-{ 2484 }; +-static const u_int16_t rcl10[] = /* Added Korean channels 2312-2372 */ +-{ 2312, 2317, 2322, 2327, 2332, 2337, 2342, 2347, 2352, 2357, 2362, 2367, 2372 }; +-static const u_int16_t rcl11[] = /* Added Japan channels in 4.9/5.0 spectrum */ +-{ 5040, 5060, 5080, 4920, 4940, 4960, 4980 }; +-#ifdef ATH_TURBO_SCAN +-static const u_int16_t rcl5[] = /* 3 static turbo channels */ +-{ 5210, 5250, 5290 }; +-static const u_int16_t rcl6[] = /* 2 static turbo channels */ +-{ 5760, 5800 }; +-static const u_int16_t rcl6x[] = /* 4 FCC3 turbo channels */ +-{ 5540, 5580, 5620, 5660 }; +-static const u_int16_t rcl12[] = /* 2.4Ghz Turbo channel 6 */ +-{ 2437 }; +-static const u_int16_t rcl13[] = /* dynamic Turbo channels */ +-{ 5200, 5240, 5280, 5765, 5805 }; +-#endif /* ATH_TURBO_SCAN */ +- +-struct scanlist { +- u_int16_t mode; +- u_int16_t count; +- const u_int16_t *list; +-}; +- +-#define IEEE80211_MODE_TURBO_STATIC_A IEEE80211_MODE_MAX +-#define X(a) .count = ARRAY_SIZE(a), .list = a +- +-static const struct scanlist staScanTable[] = { +- { IEEE80211_MODE_11B, X(rcl3) }, +- { IEEE80211_MODE_11A, X(rcl1) }, +- { IEEE80211_MODE_11A, X(rcl2) }, +- { IEEE80211_MODE_11B, X(rcl8) }, +- { IEEE80211_MODE_11B, X(rcl9) }, +- { IEEE80211_MODE_11A, X(rcl4) }, +-#ifdef ATH_TURBO_SCAN +- { IEEE80211_MODE_TURBO_STATIC_A, X(rcl5) }, +- { IEEE80211_MODE_TURBO_STATIC_A, X(rcl6) }, +- { IEEE80211_MODE_TURBO_A, X(rcl6x) }, +- { IEEE80211_MODE_TURBO_A, X(rcl13) }, +-#endif /* ATH_TURBO_SCAN */ +- { IEEE80211_MODE_11A, X(rcl7) }, +- { IEEE80211_MODE_11B, X(rcl10) }, +- { IEEE80211_MODE_11A, X(rcl11) }, +-#ifdef ATH_TURBO_SCAN +- { IEEE80211_MODE_TURBO_G, X(rcl12) }, +-#endif /* ATH_TURBO_SCAN */ +- { .list = NULL } +-}; +- +-#undef X +-/* This function must be invoked with locks acquired */ +-static void +-add_channels(struct ieee80211com *ic, +- struct ieee80211_scan_state *ss, +- enum ieee80211_phymode mode, const u_int16_t freq[], int nfreq) +-{ +- struct ieee80211_channel *c, *cg; +- u_int modeflags; +- int i; +- +- KASSERT(mode < ARRAY_SIZE(chanflags), ("Unexpected mode %u", mode)); +- modeflags = chanflags[mode]; +- for (i = 0; i < nfreq; i++) { +- c = ieee80211_find_channel(ic, freq[i], modeflags); +- if ((c == NULL) || isclr(ic->ic_chan_active, c->ic_ieee)) +- continue; +- if (mode == IEEE80211_MODE_AUTO) { +- /* XXX special-case 11b/g channels so we select +- * the g channel if both are present. */ +- if (IEEE80211_IS_CHAN_B(c) && +- (cg = find11gchannel(ic, i, c->ic_freq)) != NULL) +- c = cg; +- } +- if (ss->ss_last >= IEEE80211_SCAN_MAX) +- break; +- ss->ss_chans[ss->ss_last++] = c; +- } +-} +- +-/* This function must be invoked with locks acquired */ +-static int +-checktable(const struct scanlist *scan, const struct ieee80211_channel *c) +-{ +- int i; +- +- for (; scan->list != NULL; scan++) { +- for (i = 0; i < scan->count; i++) +- if (scan->list[i] == c->ic_freq) +- return 1; +- } +- return 0; +-} + + /* + * Attach prior to any scanning work. +@@ -398,29 +274,6 @@ + ieee80211_saveie(iep, ie); + } + +-/* This function must be invoked with locks acquired */ +-static struct ieee80211_channel * +-find11gchannel(struct ieee80211com *ic, int i, int freq) +-{ +- struct ieee80211_channel *c; +- int j; +- +- /* The normal ordering in the channel list is b channel +- * immediately followed by g so optimize the search for +- * this. We'll still do a full search just in case. */ +- for (j = i + 1; j < ic->ic_nchans; j++) { +- c = &ic->ic_channels[j]; +- if ((c->ic_freq == freq) && IEEE80211_IS_CHAN_ANYG(c)) +- return c; +- } +- for (j = 0; j < i; j++) { +- c = &ic->ic_channels[j]; +- if ((c->ic_freq == freq) && IEEE80211_IS_CHAN_ANYG(c)) +- return c; +- } +- return NULL; +-} +- + /* + * Start an ap scan by populating the channel list. + */ +@@ -429,90 +282,14 @@ + { + struct ap_state *as = ss->ss_priv; + struct ieee80211com *ic = NULL; +- const struct scanlist *sl = NULL; +- struct ieee80211_channel *c = NULL; +- int i; +- unsigned int mode = 0; + + SCAN_AP_LOCK_IRQ(as); + ic = vap->iv_ic; + /* Determine mode flags to match, or leave zero for auto mode */ + as->as_vap_desired_mode = vap->iv_des_mode; + as->as_required_mode = 0; +- if (as->as_vap_desired_mode != IEEE80211_MODE_AUTO) { +- as->as_required_mode = chanflags[as->as_vap_desired_mode]; +- if ((vap->iv_ath_cap & IEEE80211_ATHC_TURBOP) && +- (as->as_required_mode != IEEE80211_CHAN_ST)) { +- /* Fixup for dynamic turbo flags */ +- if (as->as_vap_desired_mode == IEEE80211_MODE_11G) +- as->as_required_mode = IEEE80211_CHAN_108G; +- else +- as->as_required_mode = IEEE80211_CHAN_108A; +- } +- } +- +- ss->ss_last = 0; +- /* Use the table of ordered channels to construct the list +- * of channels for scanning. Any channels in the ordered +- * list not in the master list will be discarded. */ +- for (sl = staScanTable; sl->list != NULL; sl++) { +- mode = sl->mode; +- +- /* The scan table marks 2.4Ghz channels as b +- * so if the desired mode is 11g, then use +- * the 11b channel list but upgrade the mode. */ +- if (as->as_vap_desired_mode && +- (as->as_vap_desired_mode != mode) && +- (as->as_vap_desired_mode == IEEE80211_MODE_11G) && +- (mode == IEEE80211_MODE_11B)) +- mode = IEEE80211_MODE_11G; +- +- /* If we are in "AUTO" mode, upgrade the mode to auto. +- * This lets add_channels upgrade an 11b channel to +- * 11g if available. */ +- if (!as->as_vap_desired_mode && (mode == IEEE80211_MODE_11B)) +- mode = IEEE80211_MODE_AUTO; +- +- /* Add the list of the channels; any that are not +- * in the master channel list will be discarded. */ +- add_channels(ic, ss, mode, sl->list, sl->count); +- } +- +- /* Add the channels from the ic (from HAL) that are not present +- * in the staScanTable, assuming they pass the sanity checks... */ +- for (i = 0; i < ic->ic_nchans; i++) { +- c = &ic->ic_channels[i]; +- +- /* XR is not supported on turbo channels */ +- if (IEEE80211_IS_CHAN_TURBO(c) && vap->iv_flags & IEEE80211_F_XR) +- continue; ++ ieee80211_scan_add_channels(ic, ss, vap->iv_des_mode); + +- /* Dynamic channels are scanned in base mode */ +- if (!as->as_required_mode && !IEEE80211_IS_CHAN_ST(c)) +- continue; +- +- /* Use any 11g channel instead of 11b one. */ +- if (vap->iv_des_mode == IEEE80211_MODE_AUTO && +- IEEE80211_IS_CHAN_B(c) && +- find11gchannel(ic, i, c->ic_freq)) +- continue; +- +- /* Do not add channels already put into the scan list by the +- * scan table - these have already been filtered by mode +- * and for whether they are in the active channel list. */ +- if (checktable(staScanTable, c)) +- continue; +- +- /* Make sure the channel is active */ +- if ((c == NULL) || isclr(ic->ic_chan_active, c->ic_ieee)) +- continue; +- +- /* Don't overrun */ +- if (ss->ss_last >= IEEE80211_SCAN_MAX) +- break; +- +- ss->ss_chans[ss->ss_last++] = c; +- } + ss->ss_next = 0; + /* XXX tunables */ + ss->ss_mindwell = msecs_to_jiffies(200); /* 200ms */ +@@ -831,13 +608,6 @@ + if (IEEE80211_IS_CHAN_RADAR(c->chan)) + continue; + +- /* Do not select 802.11a ST if mode is specified and is not +- * 802.11a ST */ +- if (as->as_required_mode && +- IEEE80211_IS_CHAN_STURBO(c->chan) && +- (as->as_vap_desired_mode != IEEE80211_MODE_TURBO_STATIC_A)) +- continue; +- + /* Verify mode matches any fixed mode specified */ + if ((c->chan->ic_flags & as->as_required_mode) != + as->as_required_mode) +--- a/net80211/ieee80211_scan.c ++++ b/net80211/ieee80211_scan.c +@@ -969,6 +969,80 @@ + } + } + ++static const u_int chanflags[] = { ++ 0, /* IEEE80211_MODE_AUTO */ ++ IEEE80211_CHAN_A, /* IEEE80211_MODE_11A */ ++ IEEE80211_CHAN_B, /* IEEE80211_MODE_11B */ ++ IEEE80211_CHAN_PUREG, /* IEEE80211_MODE_11G */ ++ IEEE80211_CHAN_FHSS, /* IEEE80211_MODE_FH */ ++ IEEE80211_CHAN_A, /* IEEE80211_MODE_TURBO_A */ /* for turbo mode look for AP in normal channel */ ++ IEEE80211_CHAN_PUREG, /* IEEE80211_MODE_TURBO_G */ ++ IEEE80211_CHAN_ST, /* IEEE80211_MODE_TURBO_STATIC_A */ ++}; ++ ++static struct ieee80211_channel * ++find11gchannel(struct ieee80211com *ic, int i, int freq) ++{ ++ struct ieee80211_channel *c; ++ int j; ++ ++ /* ++ * The normal ordering in the channel list is b channel ++ * immediately followed by g so optimize the search for ++ * this. We'll still do a full search just in case. ++ */ ++ for (j = i+1; j < ic->ic_nchans; j++) { ++ c = &ic->ic_channels[j]; ++ if (c->ic_freq == freq && IEEE80211_IS_CHAN_ANYG(c)) ++ return c; ++ } ++ for (j = 0; j < i; j++) { ++ c = &ic->ic_channels[j]; ++ if (c->ic_freq == freq && IEEE80211_IS_CHAN_ANYG(c)) ++ return c; ++ } ++ return NULL; ++} ++ ++ ++void ++ieee80211_scan_add_channels(struct ieee80211com *ic, ++ struct ieee80211_scan_state *ss, ++ enum ieee80211_phymode mode) ++{ ++ struct ieee80211_channel *c, *cg; ++ u_int modeflags; ++ int i; ++ ++ KASSERT(mode < ARRAY_SIZE(chanflags), ("Unexpected mode %u", mode)); ++ modeflags = chanflags[mode]; ++ for (i = 0; i < ic->ic_nchans; i++) { ++ c = &ic->ic_channels[i]; ++ if (c == NULL || isclr(ic->ic_chan_active, c->ic_ieee)) ++ continue; ++ if (c->ic_scanflags & IEEE80211_NOSCAN_SET) ++ continue; ++ if (modeflags && ++ ((c->ic_flags & IEEE80211_CHAN_ALLTURBO) != ++ (modeflags & IEEE80211_CHAN_ALLTURBO))) ++ continue; ++ if (mode == IEEE80211_MODE_AUTO) { ++ /* ++ * XXX special-case 11b/g channels so we select ++ * the g channel if both are present. ++ */ ++ if (IEEE80211_IS_CHAN_B(c) && ++ (cg = find11gchannel(ic, i, c->ic_freq)) != NULL) ++ continue; ++ } ++ if (ss->ss_last >= IEEE80211_SCAN_MAX) ++ break; ++ ss->ss_chans[ss->ss_last++] = c; ++ } ++} ++EXPORT_SYMBOL(ieee80211_scan_add_channels); ++ ++ + /* + * Execute radar channel change. This is called when a radar/dfs + * signal is detected. AP mode only. Return 1 on success, 0 on +--- a/net80211/ieee80211_scan.h ++++ b/net80211/ieee80211_scan.h +@@ -219,4 +219,7 @@ + void ieee80211_scanner_unregister(enum ieee80211_opmode, + const struct ieee80211_scanner *); + void ieee80211_scanner_unregister_all(const struct ieee80211_scanner *); ++void ieee80211_scan_add_channels(struct ieee80211com *ic, ++ struct ieee80211_scan_state *ss, ++ enum ieee80211_phymode mode); + #endif /* _NET80211_IEEE80211_SCAN_H_ */ +--- a/net80211/ieee80211_wireless.c ++++ b/net80211/ieee80211_wireless.c +@@ -3911,6 +3911,106 @@ + return ieee80211_ioctl_setmlme(dev, info, w, (char *)&mlme); + } + ++static inline void setflag(struct ieee80211_channel *c, int flag) ++{ ++ if (flag) ++ c->ic_scanflags |= IEEE80211_NOSCAN_SET; ++ else ++ c->ic_scanflags &= ~IEEE80211_NOSCAN_SET; ++} ++ ++static void setscanflag(struct ieee80211com *ic, int min, int max, int set) ++{ ++ int i; ++ ++ for (i = 0; i < ic->ic_nchans; i++) { ++ struct ieee80211_channel *c = &ic->ic_channels[i]; ++ ++ if (min == -1) { ++ if (!(c->ic_scanflags & IEEE80211_NOSCAN_DEFAULT)) ++ setflag(c, set); ++ } else if ((c->ic_freq >= min) && (c->ic_freq <= max)) { ++ setflag(c, set); ++ } ++ } ++} ++ ++static int ++ieee80211_ioctl_setscanlist(struct net_device *dev, ++ struct iw_request_info *info, ++ struct iw_point *data, char *extra) ++{ ++ struct ieee80211vap *vap = dev->priv; ++ struct ieee80211com *ic = vap->iv_ic; ++ char *s, *next; ++ int val = 1; ++ ++ if (data->length <= 0) ++ return -EINVAL; ++ ++ s = kmalloc(data->length + 1, GFP_KERNEL); ++ if (!s) ++ return -ENOMEM; ++ ++ memset(s, 0, data->length + 1); ++ if (copy_from_user(s, data->pointer, data->length)) ++ return -EFAULT; ++ ++ s[data->length - 1] = '\0'; /* ensure null termination */ ++ ++ switch(*s) { ++ case '-': ++ val = 1; ++ break; ++ case '+': ++ val = 0; ++ break; ++ default: ++ goto error; ++ } ++ s++; ++ next = s; ++ do { ++ next = strchr(s, ','); ++ if (next) { ++ *next = 0; ++ next++; ++ } ++ if (!strcmp(s, "ALL")) { ++ setscanflag(ic, 0, 10000, val); ++ } else if (!strcmp(s, "REG")) { ++ setscanflag(ic, -1, -1, val); ++ } else { ++ int min, max; ++ char *n, *end = NULL; ++ ++ n = strchr(s, '-'); ++ if (n) { ++ *n = 0; ++ n++; ++ } ++ min = simple_strtoul(s, &end, 10); ++ if (end && *end) ++ goto error; ++ if (n) { ++ max = simple_strtoul(n, &end, 10); ++ if (end && *end) ++ goto error; ++ } else { ++ max = min; ++ } ++ setscanflag(ic, min, max, val); ++ } ++ s = next; ++ } while (next); ++ return 0; ++ ++error: ++ if (s) ++ kfree(s); ++ return -EINVAL; ++} ++ + static int + ieee80211_ioctl_addmac(struct net_device *dev, struct iw_request_info *info, + void *w, char *extra) +@@ -5712,6 +5812,8 @@ + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "minrate"}, + {IEEE80211_PARAM_MINRATE, + 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "get_minrate"}, ++ { IEEE80211_IOCTL_SETSCANLIST, ++ IW_PRIV_TYPE_CHAR | 255, 0, "setscanlist"}, + + #ifdef ATH_REVERSE_ENGINEERING + /* +@@ -5809,6 +5911,7 @@ + set_priv(IEEE80211_IOCTL_WDSADDMAC, ieee80211_ioctl_wdsmac), + set_priv(IEEE80211_IOCTL_WDSDELMAC, ieee80211_ioctl_wdsdelmac), + set_priv(IEEE80211_IOCTL_KICKMAC, ieee80211_ioctl_kickmac), ++ set_priv(IEEE80211_IOCTL_SETSCANLIST, ieee80211_ioctl_setscanlist), + #ifdef ATH_REVERSE_ENGINEERING + set_priv(IEEE80211_IOCTL_READREG, ieee80211_ioctl_readreg), + set_priv(IEEE80211_IOCTL_WRITEREG, ieee80211_ioctl_writereg), diff --git a/package/madwifi/patches-testing/316-ani_fix.patch b/package/madwifi/patches-testing/316-ani_fix.patch new file mode 100644 index 0000000000..ad7deb036c --- /dev/null +++ b/package/madwifi/patches-testing/316-ani_fix.patch @@ -0,0 +1,730 @@ +--- a/ath/if_ath.c ++++ b/ath/if_ath.c +@@ -343,6 +343,8 @@ + unsigned int param, unsigned int value); + + static u_int32_t ath_get_real_maxtxpower(struct ath_softc *sc); ++static int ath_setintmit(struct ath_softc *sc); ++static u_int32_t ath_calcrxfilter(struct ath_softc *sc); + + #ifdef AR_DEBUG + static int ath_txq_check(struct ath_softc *sc, struct ath_txq *txq, const char *msg); +@@ -356,7 +358,6 @@ + static char *ratectl = DEF_RATE_CTL; + static int rfkill = 0; + static int hal_tpc = 0; +-static int intmit = 0; + static int countrycode = CTRY_DEFAULT; + static int maxvaps = ATH_MAXVAPS_DEFAULT; + static int outdoor = 0; +@@ -398,7 +399,6 @@ + #endif + MODULE_PARM(autocreate, "s"); + MODULE_PARM(ratectl, "s"); +-MODULE_PARM(intmit, "i"); + #else + #include + module_param(beacon_cal, int, 0600); +@@ -412,7 +412,6 @@ + #endif + module_param(autocreate, charp, 0600); + module_param(ratectl, charp, 0600); +-module_param(intmit, int, 0600); + #endif + MODULE_PARM_DESC(countrycode, "Override default country code. Default is 0."); + MODULE_PARM_DESC(maxvaps, "Maximum VAPs. Default is 4."); +@@ -428,7 +427,6 @@ + "'none' to disable"); + MODULE_PARM_DESC(ratectl, "Rate control algorithm [amrr|minstrel|onoe|sample], " + "defaults to '" DEF_RATE_CTL "'"); +-MODULE_PARM_DESC(intmit, "Enable interference mitigation by default. Default is 0."); + + #ifdef AR_DEBUG + static int ath_debug = 0; +@@ -585,23 +583,13 @@ + if (ath_hal_hastxpowlimit(ah)) { + ic->ic_caps |= IEEE80211_C_TXPMGT; + } +- /* Interference mitigation/ambient noise immunity (ANI). +- * In modes other than HAL_M_STA, it causes receive sensitivity +- * problems for OFDM. */ ++ /* Interference mitigation/ambient noise immunity (ANI). */ + sc->sc_hasintmit = ath_hal_hasintmit(ah); +- sc->sc_useintmit = (intmit && sc->sc_hasintmit); +- if (!sc->sc_hasintmit && intmit) { +- WPRINTF(sc, "Interference mitigation was requested, but is not" +- "supported by the HAL/hardware.\n"); +- intmit = 0; /* Stop use in future ath_attach(). */ +- } +- else { +- ath_hal_setintmit(ah, sc->sc_useintmit); +- DPRINTF(sc, ATH_DEBUG_ANY, "Interference mitigation is " +- "supported. Currently %s.\n", +- (sc->sc_useintmit ? "enabled" : "disabled")); +- } + ++ /* auto, mode dependent */ ++ sc->sc_useintmit = -1; ++ sc->sc_noise_immunity = -1; ++ sc->sc_ofdm_weak_det = -1; + sc->sc_dmasize_stomp = 0; + + /* +@@ -614,15 +602,6 @@ + sc->sc_mrretry = ath_hal_setupxtxdesc(ah, NULL, 0,0, 0,0, 0,0); + + /* +- * Check if the device has hardware counters for PHY +- * errors. If so we need to enable the MIB interrupt +- * so we can act on stat triggers. +- */ +- sc->sc_needmib = ath_hal_hwphycounters(ah) && +- sc->sc_hasintmit && +- sc->sc_useintmit; +- +- /* + * Get the hardware key cache size. + */ + sc->sc_keymax = ath_hal_keycachesize(ah); +@@ -1593,37 +1572,6 @@ + ath_init(dev); + } + +-/* NB: Int. mit. was not implemented so that it could be enabled/disabled, +- * and actually in 0.9.30.13 HAL it really can't even be disabled because +- * it will start adjusting registers even when we turn off the capability +- * in the HAL. +- * +- * NB: This helper function basically clobbers all the related registers +- * if we have disabled int. mit. cap, allowing us to turn it on and off and +- * work around the bug preventing it from being disabled. */ +-static inline void ath_override_intmit_if_disabled(struct ath_softc *sc) { +- /* Restore int. mit. registers if they were turned off. */ +- if (sc->sc_hasintmit && !sc->sc_useintmit) +- ath_hal_restore_default_intmit(sc->sc_ah); +- /* Sanity check... remove later. */ +- if (!sc->sc_useintmit) { +- ath_hal_verify_default_intmit(sc->sc_ah); +- /* If we don't have int. mit. and we don't have DFS on channel, +- * it is safe to filter error packets. */ +- if (!ath_radar_is_dfs_required(sc, &sc->sc_curchan)) { +- ath_hal_setrxfilter(sc->sc_ah, +- ath_hal_getrxfilter(sc->sc_ah) & +- ~HAL_RX_FILTER_PHYERR); +- } +- } +- else { +- /* Make sure that we have errors in RX filter because ANI needs +- * them. */ +- ath_hal_setrxfilter(sc->sc_ah, +- ath_hal_getrxfilter(sc->sc_ah) | HAL_RX_FILTER_PHYERR); +- } +-} +- + static HAL_BOOL ath_hw_reset(struct ath_softc *sc, HAL_OPMODE opmode, + HAL_CHANNEL *channel, HAL_BOOL bChannelChange, + HAL_STATUS *status) +@@ -1698,11 +1646,7 @@ + ath_hal_settpc(sc->sc_ah, hal_tpc); + } + #endif +-#if 0 /* Setting via HAL does not work, so it is done manually below. */ +- if (sc->sc_hasintmit) +- ath_hal_setintmit(sc->sc_ah, sc->sc_useintmit); +-#endif +- ath_override_intmit_if_disabled(sc); ++ ath_setintmit(sc); + if (sc->sc_dmasize_stomp) + ath_hal_set_dmasize_pcie(sc->sc_ah); + if (sc->sc_softled) +@@ -2496,7 +2440,6 @@ + + /* Let the HAL handle the event. */ + ath_hal_mibevent(ah, &sc->sc_halstats); +- ath_override_intmit_if_disabled(sc); + } + } + if (needmark) +@@ -2564,6 +2507,55 @@ + return flags; + } + ++static int ath_setintmit(struct ath_softc *sc) ++{ ++ struct ath_hal *ah = sc->sc_ah; ++ int ret; ++ int val; ++ ++ if (!sc->sc_hasintmit) ++ return 0; ++ ++ switch(sc->sc_useintmit) { ++ case 0: /* disabled */ ++ case 1: /* enabled */ ++ val = sc->sc_useintmit; ++ break; ++ default: ++ if (sc->sc_opmode != IEEE80211_M_MONITOR) ++ val = 1; ++ else ++ val = 0; ++ break; ++ } ++ ret = ath_hal_setintmit(ah, val); ++ if (val) ++ goto done; ++ ++ /* manual settings */ ++ if ((sc->sc_noise_immunity >= 0) && (sc->sc_noise_immunity <= 5)) ++ ath_hal_setcapability(ah, HAL_CAP_INTMIT, 2, sc->sc_noise_immunity, NULL); ++ if ((sc->sc_ofdm_weak_det == 0) || (sc->sc_ofdm_weak_det == 1)) ++ ath_hal_setcapability(ah, HAL_CAP_INTMIT, 3, sc->sc_ofdm_weak_det, NULL); ++ ++done: ++ if (!sc->sc_imask) ++ goto out; ++ ++ /* MIB interrupt handling */ ++ sc->sc_needmib = ath_hal_hwphycounters(ah) && ++ sc->sc_useintmit; ++ if (sc->sc_needmib) ++ sc->sc_imask |= HAL_INT_MIB; ++ else ++ sc->sc_imask &= ~HAL_INT_MIB; ++ ath_hal_intrset(sc->sc_ah, sc->sc_imask); ++ ath_calcrxfilter(sc); ++ ++out: ++ return ret; ++} ++ + /* + * Context: process context + */ +@@ -4249,8 +4241,7 @@ + u_int32_t rfilt; + + /* Preserve the current Phy. radar and err. filters. */ +- rfilt = (ath_hal_getrxfilter(ah) & +- (HAL_RX_FILTER_PHYERR | HAL_RX_FILTER_PHYRADAR)) | ++ rfilt = (ath_hal_getrxfilter(ah) & HAL_RX_FILTER_PHYRADAR) | + HAL_RX_FILTER_UCAST | HAL_RX_FILTER_BCAST | + HAL_RX_FILTER_MCAST; + if (ic->ic_opmode != IEEE80211_M_STA) +@@ -4266,6 +4257,8 @@ + if (sc->sc_nmonvaps > 0) + rfilt |= (HAL_RX_FILTER_CONTROL | HAL_RX_FILTER_BEACON | + HAL_RX_FILTER_PROBEREQ | HAL_RX_FILTER_PROM); ++ if (sc->sc_hasintmit && !sc->sc_needmib && ath_hal_getintmit(ah, NULL)) ++ rfilt |= HAL_RX_FILTER_PHYERR; + if (sc->sc_curchan.privFlags & CHANNEL_DFS) + rfilt |= (HAL_RX_FILTER_PHYERR | HAL_RX_FILTER_PHYRADAR); + return rfilt; +@@ -6810,8 +6803,7 @@ + dev->quota -= bf_processed; + #endif + +- if (sc->sc_useintmit) +- ath_hal_rxmonitor(ah, &sc->sc_halstats, &sc->sc_curchan); ++ ath_hal_rxmonitor(ah, &sc->sc_halstats, &sc->sc_curchan); + if (!bf_processed) + DPRINTF(sc, ATH_DEBUG_RX_PROC, + "Warning: %s got scheduled when no receive " +@@ -8727,7 +8719,6 @@ + ath_hal_rxena(ah); /* enable recv descriptors */ + ath_mode_init(dev); /* set filters, etc. */ + ath_hal_startpcurecv(ah); /* re-enable PCU/DMA engine */ +- ath_override_intmit_if_disabled(sc); + return 0; + } + +@@ -10633,8 +10624,10 @@ + ATH_RP_IGNORED = 24, + ATH_RADAR_IGNORED = 25, + ATH_MAXVAPS = 26, +- ATH_INTMIT = 27, +- ATH_DISTANCE = 28, ++ ATH_DISTANCE = 27, ++ ATH_INTMIT = 28, ++ ATH_NOISE_IMMUNITY = 29, ++ ATH_OFDM_WEAK_DET = 30 + }; + + static inline int +@@ -10696,6 +10689,48 @@ + } + + static int ++ath_sysctl_set_intmit(struct ath_softc *sc, long ctl, u_int val) ++{ ++ int ret; ++ ++ switch(ctl) { ++ case ATH_INTMIT: ++ sc->sc_intmit = val; ++ break; ++ case ATH_NOISE_IMMUNITY: ++ sc->sc_noise_immunity = val; ++ break; ++ case ATH_OFDM_WEAK_DET: ++ sc->sc_ofdm_weak_det = val; ++ break; ++ default: ++ return -EINVAL; ++ } ++ ret = ath_setintmit(sc); ++ return ret; ++} ++ ++static int ++ath_sysctl_get_intmit(struct ath_softc *sc, long ctl, u_int *val) ++{ ++ struct ath_hal *ah = sc->sc_ah; ++ ++ switch(ctl) { ++ case ATH_INTMIT: ++ *val = (ath_hal_getcapability(ah, HAL_CAP_INTMIT, 1, NULL) == HAL_OK); ++ break; ++ case ATH_NOISE_IMMUNITY: ++ return ath_hal_getcapability(ah, HAL_CAP_INTMIT, 2, val); ++ case ATH_OFDM_WEAK_DET: ++ return ath_hal_getcapability(ah, HAL_CAP_INTMIT, 3, val); ++ default: ++ return -EINVAL; ++ } ++ return 0; ++} ++ ++ ++static int + ATH_SYSCTL_DECL(ath_sysctl_halparam, ctl, write, filp, buffer, lenp, ppos) + { + struct ath_softc *sc = ctl->extra1; +@@ -10934,30 +10969,13 @@ + sc->sc_radar_ignored = val; + break; + case ATH_INTMIT: +- if (!sc->sc_hasintmit) { ++ case ATH_NOISE_IMMUNITY: ++ case ATH_OFDM_WEAK_DET: ++ if (!sc->sc_hasintmit) + ret = -EOPNOTSUPP; +- break; +- } +- if (sc->sc_useintmit == val) +- break; +- sc->sc_useintmit = val; +- sc->sc_needmib = ath_hal_hwphycounters(ah) && +- sc->sc_useintmit; +- /* Update the HAL and MIB interrupt mask bits */ +- ath_hal_setintmit(ah, !!val); +- sc->sc_imask = (sc->sc_imask & ~HAL_INT_MIB) | +- (sc->sc_needmib ? HAL_INT_MIB : 0); +- ath_hal_intrset(sc->sc_ah, sc->sc_imask); +- /* Only do a reset if device is valid and UP +- * and we just made a change to the settings. */ +- if (sc->sc_dev && !sc->sc_invalid && +- (sc->sc_dev->flags & IFF_RUNNING)) +- ath_reset(sc->sc_dev); +- /* NB: Run this step to cleanup if HAL doesn't +- * obey capability flags and hangs onto ANI +- * settings. */ +- ath_override_intmit_if_disabled(sc); +- break; ++ else ++ ret = ath_sysctl_set_intmit(sc, (long)ctl->extra2, val); ++ break; + default: + ret = -EINVAL; + break; +@@ -11029,9 +11047,14 @@ + case ATH_RADAR_IGNORED: + val = sc->sc_radar_ignored; + break; +- case ATH_INTMIT: +- val = sc->sc_useintmit; +- break; ++ case ATH_INTMIT: ++ case ATH_NOISE_IMMUNITY: ++ case ATH_OFDM_WEAK_DET: ++ if (!sc->sc_hasintmit) ++ ret = -EOPNOTSUPP; ++ else ++ ret = ath_sysctl_get_intmit(sc, (long)ctl->extra2, &val); ++ break; + default: + ret = -EINVAL; + break; +@@ -11413,6 +11436,24 @@ + .maxlen = sizeof(ath_xchanmode), + .proc_handler = proc_dointvec + }, ++ { .ctl_name = CTL_AUTO, ++ .procname = "intmit", ++ .mode = 0644, ++ .proc_handler = ath_sysctl_halparam, ++ .extra2 = (void *)ATH_INTMIT, ++ }, ++ { .ctl_name = CTL_AUTO, ++ .procname = "noise_immunity", ++ .mode = 0644, ++ .proc_handler = ath_sysctl_halparam, ++ .extra2 = (void *)ATH_NOISE_IMMUNITY, ++ }, ++ { .ctl_name = CTL_AUTO, ++ .procname = "ofdm_weak_det", ++ .mode = 0644, ++ .proc_handler = ath_sysctl_halparam, ++ .extra2 = (void *)ATH_OFDM_WEAK_DET, ++ }, + { 0 } + }; + static ctl_table ath_ath_table[] = { +--- a/ath/if_athvar.h ++++ b/ath/if_athvar.h +@@ -712,6 +712,10 @@ + unsigned int sc_txcont_power; /* Continuous transmit power in 0.5dBm units */ + unsigned int sc_txcont_rate; /* Continuous transmit rate in Mbps */ + ++ int8_t sc_intmit; /* Interference mitigation enabled, -1 = auto, based on mode, 0/1 = off/on */ ++ int8_t sc_noise_immunity; /* Noise immunity level, 0-4, -1 == auto) */ ++ int8_t sc_ofdm_weak_det; /* OFDM weak frames detection, -1 == auto */ ++ + /* rate tables */ + const HAL_RATE_TABLE *sc_rates[IEEE80211_MODE_MAX]; + const HAL_RATE_TABLE *sc_currates; /* current rate table */ +--- a/ath/if_ath_hal_extensions.h ++++ b/ath/if_ath_hal_extensions.h +@@ -237,296 +237,18 @@ + AR5K_DMASIZE_512B + }; + +- +-int ath_set_ack_bitrate(struct ath_softc *sc, int); +-int ar_device(int devid); +-const char * ath5k_chip_name(enum ath5k_srev_type type, u_int16_t val); +- +-static inline unsigned long field_width(unsigned long mask, unsigned long shift) +-{ +- unsigned long r = 0; +- unsigned long x = mask >> shift; +- if ( 0 == mask ) return 0; +-#if BITS_PER_LONG >= 64 +- if ( x & (~0UL<<32) ) { x >>= 32; r += 32; } +-#endif +- if ( x & 0xffff0000 ) { x >>= 16; r += 16; } +- if ( x & 0x0000ff00 ) { x >>= 8; r += 8; } +- if ( x & 0x000000f0 ) { x >>= 4; r += 4; } +- if ( x & 0x0000000c ) { x >>= 2; r += 2; } +- if ( x & 0x00000002 ) { r += 1; } +- return r+1; +-} +- +-static inline u_int32_t get_field(struct ath_hal *ah, u_int32_t reg, u_int32_t mask, u_int32_t shift, int is_signed) { +- unsigned long x = ((OS_REG_READ(ah, reg) & mask) >> shift); +- if (is_signed) { +- unsigned long c =(-1) << (field_width(mask, shift)-1); +- return (x + c) ^ c; +- } +- return x; +-} +- + static inline void set_field(struct ath_hal *ah, u_int32_t reg, u_int32_t mask, u_int32_t shift, u_int32_t value) { + OS_REG_WRITE(ah, reg, + (OS_REG_READ(ah, reg) & ~mask) | + ((value << shift) & mask)); + } + +-static inline u_int32_t field_eq(struct ath_hal *ah, u_int32_t reg, +- u_int32_t mask, u_int32_t shift, +- u_int32_t value, int is_signed) { +- return (get_field(ah, reg, mask, shift, is_signed) & (mask >> shift)) == +- (value & (mask >> shift)); +-} +- +-static inline void override_warning(struct ath_hal *ah, const char *name, +- u_int32_t reg, u_int32_t mask, +- u_int32_t shift, u_int32_t expected, int is_signed) { +- +- if (!field_eq(ah, reg, mask, shift, expected, is_signed)) +- printk("%s: Correcting 0x%04x[%s] from 0x%x (%d) to 0x%x (%d).\n", +- SC_DEV_NAME(ah->ah_sc), +- reg, +- name, +- (get_field(ah, reg, mask, shift, is_signed) & (mask >> shift)), +- get_field(ah, reg, mask, shift, is_signed), +- (expected & (mask >> shift)), /* not sign extended */ +- expected); +-#if 0 /* NB: For checking to see if HAL is fixed or not */ +- else { +- printk("%s: Keeping 0x%04x[%s] - 0x%x (%d).\n", +- SC_DEV_NAME(ah->ah_sc), +- reg, +- name, +- (get_field(ah, reg, mask, shift, is_signed) & (mask >> shift)), +- get_field(ah, reg, mask, shift, is_signed)); +- } +-#endif +-} +- +-static inline void verification_warning(struct ath_hal *ah, const char *name, +- u_int32_t reg, u_int32_t mask, +- u_int32_t shift, u_int32_t expected, int is_signed) { +- +- int ret = field_eq(ah, reg, mask, shift, expected, is_signed); +- if (!ret) { +- printk("%s: %s verification of %s default value " +- "[found=0x%x (%d) expected=0x%x (%d)].\n", +- SC_DEV_NAME(ah->ah_sc), +- (ret ? "PASSED" : "FAILED"), +- name, +- (get_field(ah, reg, mask, shift, is_signed) & (mask >> shift)), +- get_field(ah, reg, mask, shift, is_signed), +- (expected & (mask >> shift)), /* not sign extended */ +- expected); +- ath_hal_print_decoded_register(ah, NULL, reg, +- OS_REG_READ(ah, reg), OS_REG_READ(ah, reg), 0); +- } +-} +- +-#define GET_FIELD(ah, __reg, __mask, __signed) \ +- get_field(ah, __reg, __mask, __mask ## _S, __signed) + #define SET_FIELD(ah, __reg, __mask, __value) \ + set_field(ah, __reg, __mask, __mask ## _S, __value); +-#define FIELD_EQ(ah, __reg, __mask, __value, __signed) \ +- field_eq(ah, __reg, __mask, __mask ## _S, __value, __signed) +- +-#if 0 /* NB: These are working at this point, and HAL tweaks them a lot */ +-#define OVERRIDE_WARNING(ah, __reg, __mask, __expected, __signed) \ +- override_warning(ah, #__mask, __reg, __mask, __mask ## _S, __expected, __signed) +-#else +-#define OVERRIDE_WARNING(ah, __reg, __mask, __expected, __signed) +-#endif +- +-#define VERIFICATION_WARNING(ah, __reg, __mask, __signed) \ +- verification_warning(ah, #__mask, __reg, __mask, __mask ## _S, DEFAULT_ ## __mask, __signed) +-#define VERIFICATION_WARNING_SW(ah, __reg, __mask, __signed) \ +- verification_warning(ah, #__mask, __reg, __mask, __mask ## _S, DEFAULT_ENABLE_ ## __reg ? __mask ## _ON : __mask ## _OFF, __signed) +- +-static inline void ath_hal_set_noise_immunity(struct ath_hal *ah, +- int agc_desired_size, +- int agc_coarse_hi, +- int agc_coarse_lo, +- int sig_firpwr) +-{ +- ATH_HAL_LOCK_IRQ(ah->ah_sc); +- ath_hal_set_function(__func__); +- ath_hal_set_device(SC_DEV_NAME(ah->ah_sc)); +- +-#if 0 /* NB: These are working at this point, and HAL tweaks them a lot */ +- OVERRIDE_WARNING(ah, AR5K_PHY_AGCSIZE, AR5K_PHY_AGCSIZE_DESIRED, agc_desired_size, 1); +- OVERRIDE_WARNING(ah, AR5K_PHY_AGCCOARSE, AR5K_PHY_AGCCOARSE_LO, agc_coarse_lo, 1); +- OVERRIDE_WARNING(ah, AR5K_PHY_AGCCOARSE, AR5K_PHY_AGCCOARSE_HI, agc_coarse_hi, 1); +- OVERRIDE_WARNING(ah, AR5K_PHY_SIG, AR5K_PHY_SIG_FIRPWR, sig_firpwr, 1); +-#endif +- +- SET_FIELD(ah, AR5K_PHY_AGCSIZE, AR5K_PHY_AGCSIZE_DESIRED, agc_desired_size); +- SET_FIELD(ah, AR5K_PHY_AGCCOARSE, AR5K_PHY_AGCCOARSE_LO, agc_coarse_lo); +- SET_FIELD(ah, AR5K_PHY_AGCCOARSE, AR5K_PHY_AGCCOARSE_HI, agc_coarse_hi); +- SET_FIELD(ah, AR5K_PHY_SIG, AR5K_PHY_SIG_FIRPWR, sig_firpwr); +- +- ath_hal_set_function(NULL); +- ath_hal_set_device(NULL); +- ATH_HAL_UNLOCK_IRQ(ah->ah_sc); +-} +- +-static inline void ath_hal_set_ofdm_weak_det(struct ath_hal *ah, +- int low_m1, int low_m2, int low_m2_count, int low_self_corr, +- int high_m1, int high_m2, int high_m2_count) +-{ +- ATH_HAL_LOCK_IRQ(ah->ah_sc); +- ath_hal_set_function(__func__); +- ath_hal_set_device(SC_DEV_NAME(ah->ah_sc)); +- +- OVERRIDE_WARNING(ah, AR5K_PHY_WEAK_OFDM_LOW, AR5K_PHY_WEAK_OFDM_LOW_M1, low_m1, 0); +- OVERRIDE_WARNING(ah, AR5K_PHY_WEAK_OFDM_LOW, AR5K_PHY_WEAK_OFDM_LOW_M2, low_m2, 0); +- OVERRIDE_WARNING(ah, AR5K_PHY_WEAK_OFDM_LOW, AR5K_PHY_WEAK_OFDM_LOW_M2_COUNT, low_m2_count, 0); +- OVERRIDE_WARNING(ah, AR5K_PHY_WEAK_OFDM_LOW, AR5K_PHY_WEAK_OFDM_LOW_SELFCOR, low_self_corr, 0); +- OVERRIDE_WARNING(ah, AR5K_PHY_WEAK_OFDM_HIGH, AR5K_PHY_WEAK_OFDM_HIGH_M1, high_m1, 0); +- OVERRIDE_WARNING(ah, AR5K_PHY_WEAK_OFDM_HIGH, AR5K_PHY_WEAK_OFDM_HIGH_M2, high_m2, 0); +- OVERRIDE_WARNING(ah, AR5K_PHY_WEAK_OFDM_HIGH, AR5K_PHY_WEAK_OFDM_HIGH_M2_COUNT, high_m2_count, 0); +- +- SET_FIELD(ah, AR5K_PHY_WEAK_OFDM_LOW, AR5K_PHY_WEAK_OFDM_LOW_M1, low_m1); +- SET_FIELD(ah, AR5K_PHY_WEAK_OFDM_LOW, AR5K_PHY_WEAK_OFDM_LOW_M2, low_m2); +- SET_FIELD(ah, AR5K_PHY_WEAK_OFDM_LOW, AR5K_PHY_WEAK_OFDM_LOW_M2_COUNT, low_m2_count); +- SET_FIELD(ah, AR5K_PHY_WEAK_OFDM_LOW, AR5K_PHY_WEAK_OFDM_LOW_SELFCOR, low_self_corr); +- SET_FIELD(ah, AR5K_PHY_WEAK_OFDM_HIGH, AR5K_PHY_WEAK_OFDM_HIGH_M1, high_m1); +- SET_FIELD(ah, AR5K_PHY_WEAK_OFDM_HIGH, AR5K_PHY_WEAK_OFDM_HIGH_M2, high_m2); +- SET_FIELD(ah, AR5K_PHY_WEAK_OFDM_HIGH, AR5K_PHY_WEAK_OFDM_HIGH_M2_COUNT, high_m2_count); +- +- ath_hal_set_function(NULL); +- ath_hal_set_device(NULL); +- ATH_HAL_UNLOCK_IRQ(ah->ah_sc); +-} +- +-static inline void ath_hal_set_cck_weak_det(struct ath_hal *ah, int thresh) +-{ +- ATH_HAL_LOCK_IRQ(ah->ah_sc); +- ath_hal_set_function(__func__); +- ath_hal_set_device(SC_DEV_NAME(ah->ah_sc)); +- +- OVERRIDE_WARNING(ah, AR5K_PHY_WEAK_CCK, AR5K_PHY_WEAK_CCK_THRESH, thresh, 0); +- +- SET_FIELD(ah, AR5K_PHY_WEAK_CCK, AR5K_PHY_WEAK_CCK_THRESH, thresh); +- +- ath_hal_set_function(NULL); +- ath_hal_set_device(NULL); +- ATH_HAL_UNLOCK_IRQ(ah->ah_sc); +-} +- +-static inline void ath_hal_set_sig_firstep(struct ath_hal *ah, int firstep) +-{ +- ATH_HAL_LOCK_IRQ(ah->ah_sc); +- ath_hal_set_function(__func__); +- ath_hal_set_device(SC_DEV_NAME(ah->ah_sc)); + +- OVERRIDE_WARNING(ah, AR5K_PHY_SIG, AR5K_PHY_SIG_FIRSTEP, firstep, 0); +- +- SET_FIELD(ah, AR5K_PHY_SIG, AR5K_PHY_SIG_FIRSTEP, firstep); +- +- ath_hal_set_function(NULL); +- ath_hal_set_device(NULL); +- ATH_HAL_UNLOCK_IRQ(ah->ah_sc); +-} +- +-static inline void ath_hal_set_spur_immunity(struct ath_hal *ah, int thresh) +-{ +- ATH_HAL_LOCK_IRQ(ah->ah_sc); +- ath_hal_set_function(__func__); +- ath_hal_set_device(SC_DEV_NAME(ah->ah_sc)); +- +- OVERRIDE_WARNING(ah, AR5K_PHY_SPUR, AR5K_PHY_SPUR_THRESH, thresh, 0); +- +- SET_FIELD(ah, AR5K_PHY_SPUR, AR5K_PHY_SPUR_THRESH, thresh); +- +- ath_hal_set_function(NULL); +- ath_hal_set_device(NULL); +- ATH_HAL_UNLOCK_IRQ(ah->ah_sc); +-} +- +-static inline void ath_hal_restore_default_noise_immunity(struct ath_hal *ah) { +- +- ath_hal_set_noise_immunity(ah, +- DEFAULT_AR5K_PHY_AGCSIZE_DESIRED, +- DEFAULT_AR5K_PHY_AGCCOARSE_HI, +- DEFAULT_AR5K_PHY_AGCCOARSE_LO, +- DEFAULT_AR5K_PHY_SIG_FIRPWR); +-} +- +-static inline void ath_hal_enable_ofdm_weak_det(struct ath_hal *ah, int enable) { +- if (enable) +- ath_hal_set_ofdm_weak_det(ah, +- AR5K_PHY_WEAK_OFDM_LOW_M1_ON, +- AR5K_PHY_WEAK_OFDM_LOW_M2_ON, +- AR5K_PHY_WEAK_OFDM_LOW_M2_COUNT_ON, +- AR5K_PHY_WEAK_OFDM_LOW_SELFCOR_ON, +- AR5K_PHY_WEAK_OFDM_HIGH_M1_ON, +- AR5K_PHY_WEAK_OFDM_HIGH_M2_ON, +- AR5K_PHY_WEAK_OFDM_HIGH_M2_COUNT_ON); +- else +- ath_hal_set_ofdm_weak_det(ah, +- AR5K_PHY_WEAK_OFDM_LOW_M1_OFF, +- AR5K_PHY_WEAK_OFDM_LOW_M2_OFF, +- AR5K_PHY_WEAK_OFDM_LOW_M2_COUNT_OFF, +- AR5K_PHY_WEAK_OFDM_LOW_SELFCOR_OFF, +- AR5K_PHY_WEAK_OFDM_HIGH_M1_OFF, +- AR5K_PHY_WEAK_OFDM_HIGH_M2_OFF, +- AR5K_PHY_WEAK_OFDM_HIGH_M2_COUNT_OFF); +-} +- +-static inline void ath_hal_enable_cck_weak_det(struct ath_hal *ah, int enable) { +- ath_hal_set_cck_weak_det(ah, enable +- ? AR5K_PHY_WEAK_CCK_THRESH_ON +- : AR5K_PHY_WEAK_CCK_THRESH_OFF); +-} +- +-static inline void ath_hal_restore_default_ofdm_weak_det(struct ath_hal *ah) { +- ath_hal_enable_ofdm_weak_det(ah, DEFAULT_ENABLE_AR5K_PHY_WEAK_OFDM); +-} +- +-static inline void ath_hal_restore_default_cck_weak_det(struct ath_hal *ah) { +- ath_hal_enable_cck_weak_det(ah, DEFAULT_ENABLE_AR5K_PHY_WEAK_CCK); +-} +- +-static inline void ath_hal_restore_default_sig_firstep(struct ath_hal *ah) { +- +- ath_hal_set_sig_firstep(ah, +- DEFAULT_AR5K_PHY_SIG_FIRSTEP); +-} +- +-static inline void ath_hal_restore_default_spur_immunity(struct ath_hal *ah) { +- +- ath_hal_set_spur_immunity(ah, +- DEFAULT_AR5K_PHY_SPUR_THRESH); +-} +- +-static inline void ath_hal_restore_default_intmit(struct ath_hal *ah) { +- ath_hal_restore_default_noise_immunity(ah); +- ath_hal_restore_default_ofdm_weak_det(ah); +- ath_hal_restore_default_cck_weak_det(ah); +- ath_hal_restore_default_sig_firstep(ah); +- ath_hal_restore_default_spur_immunity(ah); +- +-} +- +-static inline void ath_hal_verify_default_intmit(struct ath_hal *ah) { +- /* Just a list of all the fields above, for sanity checks... */ +- VERIFICATION_WARNING(ah, AR5K_PHY_AGCSIZE, AR5K_PHY_AGCSIZE_DESIRED, 1); +- VERIFICATION_WARNING(ah, AR5K_PHY_AGCCOARSE, AR5K_PHY_AGCCOARSE_LO, 1); +- VERIFICATION_WARNING(ah, AR5K_PHY_AGCCOARSE, AR5K_PHY_AGCCOARSE_HI, 1); +- VERIFICATION_WARNING(ah, AR5K_PHY_SIG, AR5K_PHY_SIG_FIRPWR, 1); +- VERIFICATION_WARNING_SW(ah, AR5K_PHY_WEAK_OFDM_LOW, AR5K_PHY_WEAK_OFDM_LOW_M1, 0); +- VERIFICATION_WARNING_SW(ah, AR5K_PHY_WEAK_OFDM_LOW, AR5K_PHY_WEAK_OFDM_LOW_M2, 0); +- VERIFICATION_WARNING_SW(ah, AR5K_PHY_WEAK_OFDM_LOW, AR5K_PHY_WEAK_OFDM_LOW_M2_COUNT, 0); +- VERIFICATION_WARNING_SW(ah, AR5K_PHY_WEAK_OFDM_LOW, AR5K_PHY_WEAK_OFDM_LOW_SELFCOR, 0); +- VERIFICATION_WARNING_SW(ah, AR5K_PHY_WEAK_OFDM_HIGH, AR5K_PHY_WEAK_OFDM_HIGH_M1, 0); +- VERIFICATION_WARNING_SW(ah, AR5K_PHY_WEAK_OFDM_HIGH, AR5K_PHY_WEAK_OFDM_HIGH_M2, 0); +- VERIFICATION_WARNING_SW(ah, AR5K_PHY_WEAK_OFDM_HIGH, AR5K_PHY_WEAK_OFDM_HIGH_M2_COUNT, 0); +- VERIFICATION_WARNING_SW(ah, AR5K_PHY_WEAK_CCK, AR5K_PHY_WEAK_CCK_THRESH, 0); +- VERIFICATION_WARNING(ah, AR5K_PHY_SIG, AR5K_PHY_SIG_FIRSTEP, 0); +- VERIFICATION_WARNING(ah, AR5K_PHY_SPUR, AR5K_PHY_SPUR_THRESH, 0); +-} ++int ath_set_ack_bitrate(struct ath_softc *sc, int); ++int ar_device(int devid); ++const char * ath5k_chip_name(enum ath5k_srev_type type, u_int16_t val); + + static inline void ath_hal_set_dmasize_pcie(struct ath_hal *ah) { + SET_FIELD(ah, AR5K_TXCFG, AR5K_TXCFG_SDMAMR, AR5K_DMASIZE_128B); +--- a/ath/if_ath_hal.h ++++ b/ath/if_ath_hal.h +@@ -79,7 +79,7 @@ + ath_hal_set_function(__func__); + ath_hal_set_device(SC_DEV_NAME(ah->ah_sc)); + ret = +- ah->ah_getDiagState(ah, request, args, argsize, *result, ++ ah->ah_getDiagState(ah, request, args, argsize, result, + resultsize); + ath_hal_set_function(NULL); + ath_hal_set_device(NULL); +--- a/scripts/if_ath_hal_generator.pl ++++ b/scripts/if_ath_hal_generator.pl +@@ -145,7 +145,9 @@ + "ah_waitForBeaconDone" => "ath_hal_waitforbeacon", + "ah_writeAssocid" => "ath_hal_setassocid", + "ah_clrMulticastFilterIndex" => "ath_hal_clearmcastfilter", +- "ah_detectCardPresent" => "ath_hal_detectcardpresent" ++ "ah_detectCardPresent" => "ath_hal_detectcardpresent", ++ "ah_setSifsTime" => "ath_hal_setsifstime", ++ "ah_getSifsTime" => "ath_hal_getsifstime" + ); + + # +@@ -254,7 +256,7 @@ + + foreach (@parameters) { + s/ \*/\* /; +- /^((?:(?:const|struct|\*)\s*)*)([^\s]+\*?)\s*([^\s]*)\s*/; ++ /^((?:(?:const|struct|\*)\s*)*)([^\s]+\**)\s*([^\s]*)\s*/; + my $type = "$1$2"; + my $name = "$3"; + if ( 0 == length($name) ) { diff --git a/package/madwifi/patches-testing/317-devid.patch b/package/madwifi/patches-testing/317-devid.patch new file mode 100644 index 0000000000..281e348f83 --- /dev/null +++ b/package/madwifi/patches-testing/317-devid.patch @@ -0,0 +1,17 @@ +--- a/ath/if_ath_pci.c ++++ b/ath/if_ath_pci.c +@@ -114,11 +114,13 @@ + { 0x168c, 0x0023, PCI_ANY_ID, PCI_ANY_ID }, + { 0x168c, 0x0024, PCI_ANY_ID, PCI_ANY_ID }, + { 0x168c, 0x9013, PCI_ANY_ID, PCI_ANY_ID }, /* sonicwall */ ++ { 0x168c, 0xff1a, PCI_ANY_ID, PCI_ANY_ID }, + { 0 } + }; + + static u16 ath_devidmap[][2] = { +- { 0x9013, 0x0013 } ++ { 0x9013, 0x0013 }, ++ { 0xff1a, 0x001a } + }; + + static int diff --git a/package/madwifi/patches-testing/318-ifxmips_eeprom.patch b/package/madwifi/patches-testing/318-ifxmips_eeprom.patch new file mode 100644 index 0000000000..412ceadeb6 --- /dev/null +++ b/package/madwifi/patches-testing/318-ifxmips_eeprom.patch @@ -0,0 +1,85 @@ +--- a/ath_hal/ah_os.c ++++ b/ath_hal/ah_os.c +@@ -917,9 +917,56 @@ + * NB: see the comments in ah_osdep.h about byte-swapping register + * reads and writes to understand what's going on below. + */ ++ ++#ifdef CONFIG_IFXMIPS ++extern int ifxmips_has_brn_block(void); ++static int ifxmips_emulate = 0; ++#define EEPROM_EMULATION 1 ++#endif ++ ++#ifdef EEPROM_EMULATION ++static int ath_hal_eeprom(struct ath_hal *ah, unsigned long addr, int val, int write) ++{ ++ static int addrsel = 0; ++ static int rc = 0; ++ ++ if (write) { ++ if(addr == 0x6000) { ++ addrsel = val * 2; ++ rc = 0; ++ } ++ } else { ++ switch(addr) ++ { ++ case 0x600c: ++ if(rc++ < 2) ++ val = 0x00000000; ++ else ++ val = 0x00000002; ++ break; ++ case 0x6004: ++ val = cpu_to_le16(__raw_readw((u16 *) KSEG1ADDR(0xb07f0400 + addrsel))); ++ /* this forces the regdomain to 0x00 (worldwide), as the original setting ++ * causes issues with the HAL */ ++ if (addrsel == 0x17e) ++ val = 0; ++ break; ++ } ++ } ++ return val; ++} ++#endif ++ + void __ahdecl + ath_hal_reg_write(struct ath_hal *ah, u_int address, u_int32_t value) + { ++#ifdef EEPROM_EMULATION ++ if((address >= 0x6000) && (address <= 0x6010) && ifxmips_emulate) { ++ ath_hal_eeprom(ah, address, value, 1); ++ return; ++ } ++#endif ++ + _trace_regop(ah, REGOP_WRITE, address, value); + _OS_REG_WRITE(ah, address, value); + } +@@ -929,7 +976,14 @@ + u_int32_t __ahdecl + ath_hal_reg_read(struct ath_hal *ah, u_int address) + { +- u_int32_t val = _OS_REG_READ(ah, address); ++ u_int32_t val; ++ ++#ifdef EEPROM_EMULATION ++ if((address >= 0x6000) && (address <= 0x6010) && ifxmips_emulate) ++ val = ath_hal_eeprom(ah, address, 0, 0); ++ else ++#endif ++ val = _OS_REG_READ(ah, address); + _trace_regop(ah, REGOP_READ, address, val); + return val; + } +@@ -1123,6 +1177,9 @@ + #ifdef MMIOTRACE + kmmio_logmsg = _kmmio_logmsg; + #endif ++#ifdef CONFIG_IFXMIPS ++ ifxmips_emulate = ifxmips_has_brn_block(); ++#endif + + sep = ""; + for (i = 0; ath_hal_buildopts[i] != NULL; i++) { diff --git a/package/madwifi/patches-testing/319-eap_auth_disassoc.patch b/package/madwifi/patches-testing/319-eap_auth_disassoc.patch new file mode 100644 index 0000000000..a1d9b0ba4e --- /dev/null +++ b/package/madwifi/patches-testing/319-eap_auth_disassoc.patch @@ -0,0 +1,81 @@ +This patch causes STA mode interfaces to disassociate if transmission of assoc/auth +critical packets failed. + +Signed-off-by: Felix Fietkau + +--- a/ath/if_ath.c ++++ b/ath/if_ath.c +@@ -8273,6 +8273,18 @@ + #endif + if (ts->ts_status & HAL_TXERR_XRETRY) { + sc->sc_stats.ast_tx_xretries++; ++ if (SKB_CB(bf->bf_skb)->auth_pkt && (ni->ni_vap->iv_opmode == IEEE80211_M_STA)) { ++ struct ieee80211com *ic = &sc->sc_ic; ++ ++ /* if roaming is enabled, try reassociating, otherwise ++ * disassociate and go back to the scan state */ ++ IEEE80211_VAPS_LOCK_BH(ic); ++ if (ic->ic_roaming == IEEE80211_ROAMING_AUTO) ++ ni->ni_vap->iv_newstate(ni->ni_vap, IEEE80211_S_ASSOC, 1); ++ else ++ ni->ni_vap->iv_newstate(ni->ni_vap, IEEE80211_S_SCAN, 0); ++ IEEE80211_VAPS_UNLOCK_BH(ic); ++ } + if (ni->ni_flags & IEEE80211_NODE_UAPSD_TRIG) { + ni->ni_stats.ns_tx_eosplost++; + DPRINTF(sc, ATH_DEBUG_UAPSD, +--- a/net80211/ieee80211_linux.c ++++ b/net80211/ieee80211_linux.c +@@ -158,6 +158,7 @@ + + SKB_NI(skb) = NULL; + SKB_CB(skb)->flags = 0; ++ SKB_CB(skb)->auth_pkt = 0; + + skb_reserve(skb, sizeof(struct ieee80211_frame)); + *frm = skb_put(skb, pktlen); +--- a/net80211/ieee80211_linux.h ++++ b/net80211/ieee80211_linux.h +@@ -411,6 +411,7 @@ + #define M_SKB_TRACKED 0x20 + void (*next_destructor)(struct sk_buff *skb); + #endif ++ u_int8_t auth_pkt; + }; + + struct __assert { +--- a/net80211/ieee80211_output.c ++++ b/net80211/ieee80211_output.c +@@ -773,6 +773,8 @@ + else + hdrsize = sizeof(struct ieee80211_frame); + ++ SKB_CB(skb)->auth_pkt = (eh.ether_type == __constant_htons(ETHERTYPE_PAE)); ++ + switch (vap->iv_opmode) { + case IEEE80211_M_IBSS: + case IEEE80211_M_AHDEMO: +@@ -1617,6 +1619,7 @@ + ie->param_len = frm - &ie->param_oui[0]; + return frm; + } ++ + #endif + /* + * Send a probe request frame with the specified ssid +@@ -1881,6 +1884,7 @@ + sizeof(u_int16_t)+IEEE80211_CHALLENGE_LEN : 0)); + if (skb == NULL) + senderr(ENOMEM, is_tx_nobuf); ++ SKB_CB(skb)->auth_pkt = 1; + + ((__le16 *)frm)[0] = + (is_shared_key) ? htole16(IEEE80211_AUTH_ALG_SHARED) +@@ -1955,6 +1959,7 @@ + vap->app_ie[IEEE80211_APPIE_FRAME_ASSOC_REQ].length); + if (skb == NULL) + senderr(ENOMEM, is_tx_nobuf); ++ SKB_CB(skb)->auth_pkt = 1; + + capinfo = 0; + if (vap->iv_opmode == IEEE80211_M_IBSS) diff --git a/package/madwifi/patches-testing/320-hidden_ssid.patch b/package/madwifi/patches-testing/320-hidden_ssid.patch new file mode 100644 index 0000000000..92d0480d26 --- /dev/null +++ b/package/madwifi/patches-testing/320-hidden_ssid.patch @@ -0,0 +1,38 @@ +This patch fixes the detection of hidden SSIDs as transmitted +by some cisco systems. + +Signed-off-by: Felix Fietkau + +--- a/net80211/ieee80211_scan_sta.c ++++ b/net80211/ieee80211_scan_sta.c +@@ -209,6 +209,19 @@ + ieee80211_saveie(iep, ie); + } + ++ ++static inline int is_empty_ssid(u_int8_t *ssid) ++{ ++ if (!ssid) ++ return 1; ++ if (ssid[1] == 0) ++ return 1; ++ if ((ssid[1] == 1) && (ssid[2] == 0)) ++ return 1; ++ return 0; ++} ++ ++ + /* + * Process a beacon or probe response frame; create an + * entry in the scan cache or update any previous entry. +@@ -252,8 +265,8 @@ + ise = &se->base; + + /* XXX ap beaconing multiple ssid w/ same bssid */ +- if (sp->ssid[1] != 0 && +- (ISPROBE(subtype) || ise->se_ssid[1] == 0)) ++ if (!is_empty_ssid(sp->ssid) && ++ (ISPROBE(subtype) || is_empty_ssid(ise->se_ssid))) + memcpy(ise->se_ssid, sp->ssid, 2 + sp->ssid[1]); + + memcpy(ise->se_rates, sp->rates, diff --git a/package/madwifi/patches-testing/321-bgscan_rssi_thresh.patch b/package/madwifi/patches-testing/321-bgscan_rssi_thresh.patch new file mode 100644 index 0000000000..7020305ea8 --- /dev/null +++ b/package/madwifi/patches-testing/321-bgscan_rssi_thresh.patch @@ -0,0 +1,127 @@ +Add an optional background scanning threshold triggered by low rssi +(useful for passing updated scan results to the supplicant ahead of +time, before losing connectivity entirely) + +Signed-off-by: Felix Fietkau + +--- a/net80211/ieee80211_ioctl.h ++++ b/net80211/ieee80211_ioctl.h +@@ -655,6 +655,7 @@ + IEEE80211_PARAM_MINRATE = 84, /* Minimum rate (by table index) */ + IEEE80211_PARAM_PROTMODE_RSSI = 85, /* RSSI Threshold for enabling protection mode */ + IEEE80211_PARAM_PROTMODE_TIMEOUT = 86, /* Timeout for expiring protection mode */ ++ IEEE80211_PARAM_BGSCAN_THRESH = 87, /* bg scan rssi threshold */ + }; + + #define SIOCG80211STATS (SIOCDEVPRIVATE+2) +--- a/net80211/ieee80211_var.h ++++ b/net80211/ieee80211_var.h +@@ -92,6 +92,8 @@ + #define IEEE80211_BGSCAN_IDLE_MIN 100 /* min idle time (ms) */ + #define IEEE80211_BGSCAN_IDLE_DEFAULT 250 /* default idle time (ms) */ + ++#define IEEE80211_BGSCAN_TRIGGER_INTVL 20 /* min trigger interval for thresh based bgscan (secs) */ ++ + #define IEEE80211_COVERAGE_CLASS_MAX 31 /* max coverage class */ + #define IEEE80211_REGCLASSIDS_MAX 10 /* max regclass id list */ + +@@ -229,6 +231,9 @@ + u_int8_t iv_nickname[IEEE80211_NWID_LEN]; + u_int iv_bgscanidle; /* bg scan idle threshold */ + u_int iv_bgscanintvl; /* bg scan min interval */ ++ u_int iv_bgscanthr; /* bg scan rssi threshold */ ++ u_int iv_bgscantrintvl; /* bg scan trigger interval */ ++ unsigned long iv_bgscanthr_next; /* last trigger for bgscan */ + u_int iv_scanvalid; /* scan cache valid threshold */ + struct ieee80211_roam iv_roam; /* sta-mode roaming state */ + +@@ -612,6 +617,7 @@ + #define IEEE80211_FEXT_SWBMISS 0x00000400 /* CONF: use software beacon timer */ + #define IEEE80211_FEXT_DROPUNENC_EAPOL 0x00000800 /* CONF: drop unencrypted eapol frames */ + #define IEEE80211_FEXT_APPIE_UPDATE 0x00001000 /* STATE: beacon APP IE updated */ ++#define IEEE80211_FEXT_BGSCAN_THR 0x00002000 /* bgscan due to low rssi */ + + #define IEEE80211_COM_UAPSD_ENABLE(_ic) ((_ic)->ic_flags_ext |= IEEE80211_FEXT_UAPSD) + #define IEEE80211_COM_UAPSD_DISABLE(_ic) ((_ic)->ic_flags_ext &= ~IEEE80211_FEXT_UAPSD) +--- a/net80211/ieee80211_wireless.c ++++ b/net80211/ieee80211_wireless.c +@@ -2778,6 +2778,9 @@ + else + retv = EINVAL; + break; ++ case IEEE80211_PARAM_BGSCAN_THRESH: ++ vap->iv_bgscanthr = value; ++ break; + case IEEE80211_PARAM_MCAST_RATE: + /* units are in KILObits per second */ + if (value >= 256 && value <= 54000) +@@ -3181,6 +3184,9 @@ + case IEEE80211_PARAM_BGSCAN_INTERVAL: + param[0] = vap->iv_bgscanintvl / HZ; /* seconds */ + break; ++ case IEEE80211_PARAM_BGSCAN_THRESH: ++ param[0] = vap->iv_bgscanthr; /* rssi */ ++ break; + case IEEE80211_PARAM_MCAST_RATE: + param[0] = vap->iv_mcast_rate; /* seconds */ + break; +@@ -5704,6 +5710,10 @@ + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "bgscanintvl" }, + { IEEE80211_PARAM_BGSCAN_INTERVAL, + 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "get_bgscanintvl" }, ++ { IEEE80211_PARAM_BGSCAN_THRESH, ++ IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "bgscanthr" }, ++ { IEEE80211_PARAM_BGSCAN_THRESH, ++ 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "get_bgscanthr" }, + { IEEE80211_PARAM_MCAST_RATE, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "mcast_rate" }, + { IEEE80211_PARAM_MCAST_RATE, +--- a/net80211/ieee80211_input.c ++++ b/net80211/ieee80211_input.c +@@ -2984,8 +2984,10 @@ + { + struct ieee80211com *ic = vap->iv_ic; + ++ vap->iv_bgscantrintvl = (vap->iv_bgscantrintvl + 1) % 4; + return ((ic->ic_flags_ext & IEEE80211_FEXT_BGSCAN) && +- time_after(jiffies, ic->ic_lastdata + vap->iv_bgscanidle)); ++ (((ic->ic_flags_ext & IEEE80211_FEXT_BGSCAN_THR) && !vap->iv_bgscantrintvl) || ++ time_after(jiffies, ic->ic_lastdata + vap->iv_bgscanidle))); + } + + static __inline int +@@ -3229,6 +3231,23 @@ + /* record tsf of last beacon */ + memcpy(ni->ni_tstamp.data, scan.tstamp, + sizeof(ni->ni_tstamp)); ++ ++ /* When rssi is low, start doing bgscans more frequently to allow ++ * the supplicant to make a better switching decision */ ++ if ((rssi < vap->iv_bgscanthr) && ++ (!vap->iv_bgscanthr_next || ++ !time_before(jiffies, vap->iv_bgscanthr_next)) && ++ !(ic->ic_flags & IEEE80211_F_SCAN)) { ++ int ret; ++ ++ ic->ic_lastdata = 0; ++ ic->ic_lastscan = 0; ++ ic->ic_flags_ext |= IEEE80211_FEXT_BGSCAN_THR; ++ ret = ieee80211_bg_scan(vap); ++ if (ret) ++ vap->iv_bgscanthr_next = jiffies + msecs_to_jiffies(IEEE80211_BGSCAN_TRIGGER_INTVL * 1000); ++ } ++ + if (ni->ni_intval != scan.bintval) { + IEEE80211_NOTE(vap, IEEE80211_MSG_ASSOC, ni, + "beacon interval divergence: " +--- a/net80211/ieee80211_scan.c ++++ b/net80211/ieee80211_scan.c +@@ -793,7 +793,7 @@ + ieee80211_sta_pwrsave(vap, 0); + if (ss->ss_next >= ss->ss_last) { + ieee80211_notify_scan_done(vap); +- ic->ic_flags_ext &= ~IEEE80211_FEXT_BGSCAN; ++ ic->ic_flags_ext &= ~(IEEE80211_FEXT_BGSCAN|IEEE80211_FEXT_BGSCAN_THR); + } + } + SCAN_PRIVATE(ss)->ss_iflags &= ~ISCAN_CANCEL; diff --git a/package/madwifi/patches-testing/322-ignore_broken_bssid.patch b/package/madwifi/patches-testing/322-ignore_broken_bssid.patch new file mode 100644 index 0000000000..0bae461f6b --- /dev/null +++ b/package/madwifi/patches-testing/322-ignore_broken_bssid.patch @@ -0,0 +1,18 @@ +Some misconfigured APs broadcast NULL BSSIDs, which can confuse the STA +Ignore those when scanning. + +Signed-off-by: Felix Fietkau + +--- a/net80211/ieee80211_scan_sta.c ++++ b/net80211/ieee80211_scan_sta.c +@@ -242,6 +242,10 @@ + struct ieee80211_scan_entry *ise; + int hash; + ++ /* workaround for broken APs that broadcast NULL BSSIDs */ ++ if (memcmp(wh->i_addr3, "\x00\x00\x00\x00\x00\x00", 6) == 0) ++ return 0; ++ + hash = STA_HASH(macaddr); + SCAN_STA_LOCK_IRQ(st); + LIST_FOREACH(se, &st->st_hash[hash], se_hash) diff --git a/package/madwifi/patches-testing/323-crash_fix.patch b/package/madwifi/patches-testing/323-crash_fix.patch new file mode 100644 index 0000000000..2da3bf3525 --- /dev/null +++ b/package/madwifi/patches-testing/323-crash_fix.patch @@ -0,0 +1,21 @@ +--- a/net80211/ieee80211_node.c ++++ b/net80211/ieee80211_node.c +@@ -1999,11 +1999,13 @@ + /* From this point onwards we can no longer find the node, + * so no more references are generated + */ +- ieee80211_remove_wds_addr(nt, ni->ni_macaddr); +- ieee80211_del_wds_node(nt, ni); +- IEEE80211_NODE_TABLE_LOCK_IRQ(nt); +- node_table_leave_locked(nt, ni); +- IEEE80211_NODE_TABLE_UNLOCK_IRQ(nt); ++ if (nt) { ++ ieee80211_remove_wds_addr(nt, ni->ni_macaddr); ++ ieee80211_del_wds_node(nt, ni); ++ IEEE80211_NODE_TABLE_LOCK_IRQ(nt); ++ node_table_leave_locked(nt, ni); ++ IEEE80211_NODE_TABLE_UNLOCK_IRQ(nt); ++ } + + /* + * If node wasn't previously associated all diff --git a/package/madwifi/patches-testing/324-reassoc.patch b/package/madwifi/patches-testing/324-reassoc.patch new file mode 100644 index 0000000000..7d1ade3dd7 --- /dev/null +++ b/package/madwifi/patches-testing/324-reassoc.patch @@ -0,0 +1,31 @@ +Add a preliminary fix for the reassoc check, but disable reassoc entirely for now +until we've figured out why it fails frequently. + +Signed-off-by: Felix Fietkau + +--- a/net80211/ieee80211_node.c ++++ b/net80211/ieee80211_node.c +@@ -561,10 +561,9 @@ + EXPORT_SYMBOL(ieee80211_ibss_merge); + + static __inline int +-ssid_equal(const struct ieee80211_node *a, const struct ieee80211_node *b) ++bssid_equal(const struct ieee80211_node *a, const struct ieee80211_node *b) + { +- return (a->ni_esslen == b->ni_esslen && +- memcmp(a->ni_essid, b->ni_essid, a->ni_esslen) == 0); ++ return (memcmp(a->ni_bssid, b->ni_bssid, IEEE80211_ADDR_LEN) == 0); + } + + /* +@@ -596,8 +595,8 @@ + * Check if old+new node have the same ssid in which + * case we can reassociate when operating in sta mode. + */ +- canreassoc = ((obss != NULL) && +- (vap->iv_state == IEEE80211_S_RUN) && ssid_equal(obss, selbs)); ++ canreassoc = 0; /* ((obss != NULL) && ++ (vap->iv_state == IEEE80211_S_RUN) && bssid_equal(obss, selbs)); */ + vap->iv_bss = selbs; + IEEE80211_ADDR_COPY(vap->iv_bssid, selbs->ni_bssid); + if (obss != NULL) diff --git a/package/madwifi/patches-testing/325-sta_node_leave.patch b/package/madwifi/patches-testing/325-sta_node_leave.patch new file mode 100644 index 0000000000..6b0dcb8e80 --- /dev/null +++ b/package/madwifi/patches-testing/325-sta_node_leave.patch @@ -0,0 +1,59 @@ +Drop stale AP nodes from the client list when disconnecting. +Fixes some reassoc issues. + +Signed-off-by: Felix Fietkau + +--- a/net80211/ieee80211_proto.c ++++ b/net80211/ieee80211_proto.c +@@ -1352,7 +1352,7 @@ + IEEE80211_SEND_MGMT(ni, + IEEE80211_FC0_SUBTYPE_DISASSOC, + IEEE80211_REASON_ASSOC_LEAVE); +- ieee80211_sta_leave(ni); ++ ieee80211_node_leave(ni); + break; + case IEEE80211_M_HOSTAP: + ieee80211_iterate_nodes(&ic->ic_sta, +@@ -1362,6 +1362,7 @@ + break; + } + goto reset; ++ case IEEE80211_S_AUTH: + case IEEE80211_S_ASSOC: + switch (vap->iv_opmode) { + case IEEE80211_M_STA: +@@ -1380,7 +1381,6 @@ + case IEEE80211_S_SCAN: + ieee80211_cancel_scan(vap); + goto reset; +- case IEEE80211_S_AUTH: + reset: + ieee80211_reset_bss(vap); + break; +@@ -1436,7 +1436,7 @@ + break; + case IEEE80211_S_RUN: /* beacon miss */ + if (vap->iv_opmode == IEEE80211_M_STA) { +- ieee80211_sta_leave(ni); ++ ieee80211_node_leave(ni); + vap->iv_flags &= ~IEEE80211_F_SIBSS; /* XXX */ + if (ic->ic_roaming == IEEE80211_ROAMING_AUTO) + ieee80211_check_scan(vap, +@@ -1487,7 +1487,7 @@ + vap->iv_state = ostate; /* stay RUN */ + break; + case IEEE80211_FC0_SUBTYPE_DEAUTH: +- ieee80211_sta_leave(ni); ++ ieee80211_node_leave(ni); + if (ic->ic_roaming == IEEE80211_ROAMING_AUTO) { + /* try to reauth */ + IEEE80211_SEND_MGMT(ni, +@@ -1514,7 +1514,7 @@ + IEEE80211_FC0_SUBTYPE_ASSOC_REQ, 0); + break; + case IEEE80211_S_RUN: +- ieee80211_sta_leave(ni); ++ ieee80211_node_leave(ni); + if (ic->ic_roaming == IEEE80211_ROAMING_AUTO) { + /* NB: caller specifies ASSOC/REASSOC by arg */ + IEEE80211_SEND_MGMT(ni, arg ? diff --git a/package/madwifi/patches-testing/326-bmiss_handling.patch b/package/madwifi/patches-testing/326-bmiss_handling.patch new file mode 100644 index 0000000000..0c72630503 --- /dev/null +++ b/package/madwifi/patches-testing/326-bmiss_handling.patch @@ -0,0 +1,102 @@ +Improve the beacon miss handling. Instead of just dropping the connection, +send a directed probe request to the AP to see if it's still responding. +Schedule a software beacon miss timer in this case, which adds a timeout +for the APs probe response. + +Signed-off-by: Felix Fietkau + +--- a/net80211/ieee80211_input.c ++++ b/net80211/ieee80211_input.c +@@ -3369,12 +3369,17 @@ + } + + /* WDS/Repeater: re-schedule software beacon timer for +- * STA. */ +- if ((vap->iv_state == IEEE80211_S_RUN) && +- (vap->iv_flags_ext & IEEE80211_FEXT_SWBMISS)) { +- mod_timer(&vap->iv_swbmiss, ++ * STA. Reset consecutive bmiss counter as well */ ++ IEEE80211_LOCK_IRQ(ic); ++ if (vap->iv_state == IEEE80211_S_RUN) { ++ vap->iv_bmiss_count = 0; ++ if (vap->iv_flags_ext & IEEE80211_FEXT_SWBMISS) ++ mod_timer(&vap->iv_swbmiss, + jiffies + vap->iv_swbmiss_period); ++ else ++ del_timer(&vap->iv_swbmiss); + } ++ IEEE80211_UNLOCK_IRQ(ic); + + /* If scanning, pass the info to the scan module. + * Otherwise, check if it's the right time to do +--- a/net80211/ieee80211_proto.c ++++ b/net80211/ieee80211_proto.c +@@ -1213,6 +1213,8 @@ + } + /* XXX locking */ + TAILQ_FOREACH(vap, &ic->ic_vaps, iv_next) { ++ int count; ++ + IEEE80211_DPRINTF(vap, + IEEE80211_MSG_STATE | IEEE80211_MSG_DEBUG, + "%s\n", "beacon miss"); +@@ -1225,6 +1227,29 @@ + if (vap->iv_opmode != IEEE80211_M_STA || + vap->iv_state != IEEE80211_S_RUN) + continue; ++ ++ IEEE80211_LOCK_IRQ(ic); ++ count = vap->iv_bmiss_count++; ++ if (count) { ++ /* if the counter was already above zero, reset it ++ * here, since we're going to do the bmiss handling ++ * in any case */ ++ vap->iv_bmiss_count = 0; ++ } else { ++ /* schedule the software beacon miss timer, it will be ++ * cancelled, if the probe request is acked */ ++ mod_timer(&vap->iv_swbmiss, jiffies + vap->iv_swbmiss_period); ++ } ++ IEEE80211_UNLOCK_IRQ(ic); ++ ++ if (!count) { ++ ieee80211_send_probereq(vap->iv_bss, vap->iv_myaddr, ++ vap->iv_bss->ni_bssid, vap->iv_bss->ni_bssid, ++ vap->iv_bss->ni_essid, vap->iv_bss->ni_esslen, ++ NULL, 0); ++ continue; ++ } ++ + if (ic->ic_roaming == IEEE80211_ROAMING_AUTO) { + #ifdef ATH_SUPERG_DYNTURBO + /* +@@ -1621,14 +1646,14 @@ + } + + /* WDS/Repeater: Start software beacon timer for STA */ ++ vap->iv_swbmiss.function = ieee80211_sta_swbmiss; ++ vap->iv_swbmiss.data = (unsigned long) vap; ++ vap->iv_swbmiss_period = IEEE80211_TU_TO_JIFFIES( ++ vap->iv_ic->ic_bmissthreshold * ni->ni_intval); ++ + if (ostate != IEEE80211_S_RUN && + (vap->iv_opmode == IEEE80211_M_STA && + vap->iv_flags_ext & IEEE80211_FEXT_SWBMISS)) { +- vap->iv_swbmiss.function = ieee80211_sta_swbmiss; +- vap->iv_swbmiss.data = (unsigned long) vap; +- vap->iv_swbmiss_period = IEEE80211_TU_TO_JIFFIES( +- vap->iv_ic->ic_bmissthreshold * ni->ni_intval); +- + mod_timer(&vap->iv_swbmiss, jiffies + vap->iv_swbmiss_period); + } + +--- a/net80211/ieee80211_var.h ++++ b/net80211/ieee80211_var.h +@@ -292,6 +292,7 @@ + + struct timer_list iv_swbmiss; /* software beacon miss timer */ + u_int16_t iv_swbmiss_period; /* software beacon miss timer period */ ++ u_int16_t iv_bmiss_count; /* consecutive beacon miss counter */ + struct ieee80211_nsparams iv_nsparams; /* new state parameters for tasklet for stajoin1 */ + struct IEEE80211_TQ_STRUCT iv_stajoin1tq; /* tasklet for newstate action called from stajoin1tq */ + unsigned int iv_nsdone; /* Done with scheduled newstate tasklet */ diff --git a/package/madwifi/patches-testing/327-rssi_disconnect.patch b/package/madwifi/patches-testing/327-rssi_disconnect.patch new file mode 100644 index 0000000000..b7e406cb04 --- /dev/null +++ b/package/madwifi/patches-testing/327-rssi_disconnect.patch @@ -0,0 +1,91 @@ +Add an optional threshold for low-rssi disconnection. This can be useful +when letting wpa_supplicant control roaming. + +Signed-off-by: Felix Fietkau + +--- a/net80211/ieee80211_ioctl.h ++++ b/net80211/ieee80211_ioctl.h +@@ -656,6 +656,8 @@ + IEEE80211_PARAM_PROTMODE_RSSI = 85, /* RSSI Threshold for enabling protection mode */ + IEEE80211_PARAM_PROTMODE_TIMEOUT = 86, /* Timeout for expiring protection mode */ + IEEE80211_PARAM_BGSCAN_THRESH = 87, /* bg scan rssi threshold */ ++ IEEE80211_PARAM_RSSI_DIS_THR = 88, /* rssi threshold for disconnection */ ++ IEEE80211_PARAM_RSSI_DIS_COUNT = 89, /* counter for rssi threshold */ + }; + + #define SIOCG80211STATS (SIOCDEVPRIVATE+2) +--- a/net80211/ieee80211_wireless.c ++++ b/net80211/ieee80211_wireless.c +@@ -2832,6 +2832,12 @@ + case IEEE80211_PARAM_ROAM_RATE_11G: + vap->iv_roam.rate11g = value; + break; ++ case IEEE80211_PARAM_RSSI_DIS_THR: ++ vap->iv_rssi_dis_thr = value; ++ break; ++ case IEEE80211_PARAM_RSSI_DIS_COUNT: ++ vap->iv_rssi_dis_max = value; ++ break; + case IEEE80211_PARAM_UAPSDINFO: + if (vap->iv_opmode == IEEE80211_M_HOSTAP) { + if (ic->ic_caps & IEEE80211_C_UAPSD) { +@@ -3220,6 +3226,12 @@ + case IEEE80211_PARAM_ROAM_RATE_11G: + param[0] = vap->iv_roam.rate11g; + break; ++ case IEEE80211_PARAM_RSSI_DIS_THR: ++ param[0] = vap->iv_rssi_dis_thr; ++ break; ++ case IEEE80211_PARAM_RSSI_DIS_COUNT: ++ param[0] = vap->iv_rssi_dis_max; ++ break; + case IEEE80211_PARAM_UAPSDINFO: + if (vap->iv_opmode == IEEE80211_M_HOSTAP) { + if (IEEE80211_VAP_UAPSD_ENABLED(vap)) +@@ -5770,6 +5782,14 @@ + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "rate11g_x2" }, + { IEEE80211_PARAM_ROAM_RATE_11G, + 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "get_rate11g_x2" }, ++ { IEEE80211_PARAM_RSSI_DIS_THR, ++ IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "rssi_disthr" }, ++ { IEEE80211_PARAM_RSSI_DIS_THR, ++ 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "get_rssi_disthr" }, ++ { IEEE80211_PARAM_RSSI_DIS_COUNT, ++ IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "rssi_discnt" }, ++ { IEEE80211_PARAM_RSSI_DIS_COUNT, ++ 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "get_rssi_discnt" }, + { IEEE80211_PARAM_UAPSDINFO, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "uapsd" }, + { IEEE80211_PARAM_UAPSDINFO, +--- a/net80211/ieee80211_input.c ++++ b/net80211/ieee80211_input.c +@@ -3234,6 +3234,17 @@ + + /* When rssi is low, start doing bgscans more frequently to allow + * the supplicant to make a better switching decision */ ++ if ((vap->iv_rssi_dis_thr > 0) && (vap->iv_rssi_dis_max > 0)) { ++ if ((rssi > 0) && (rssi < vap->iv_rssi_dis_thr)) { ++ if (++vap->iv_rssi_dis_trig > vap->iv_rssi_dis_max) { ++ vap->iv_rssi_dis_trig = 0; ++ ieee80211_node_leave(ni); ++ return 0; ++ } ++ } else { ++ vap->iv_rssi_dis_trig = 0; ++ } ++ } + if ((rssi < vap->iv_bgscanthr) && + (!vap->iv_bgscanthr_next || + !time_before(jiffies, vap->iv_bgscanthr_next)) && +--- a/net80211/ieee80211_var.h ++++ b/net80211/ieee80211_var.h +@@ -233,6 +233,9 @@ + u_int iv_bgscanintvl; /* bg scan min interval */ + u_int iv_bgscanthr; /* bg scan rssi threshold */ + u_int iv_bgscantrintvl; /* bg scan trigger interval */ ++ u_int iv_rssi_dis_thr; /* rssi disassoc threshold */ ++ u_int iv_rssi_dis_max; /* max beacons below disconnect threshold */ ++ u_int iv_rssi_dis_trig; /* rssi disassoc trigger count */ + unsigned long iv_bgscanthr_next; /* last trigger for bgscan */ + u_int iv_scanvalid; /* scan cache valid threshold */ + struct ieee80211_roam iv_roam; /* sta-mode roaming state */ diff --git a/package/madwifi/patches-testing/328-memory_alloc.patch b/package/madwifi/patches-testing/328-memory_alloc.patch new file mode 100644 index 0000000000..ff60dbdb37 --- /dev/null +++ b/package/madwifi/patches-testing/328-memory_alloc.patch @@ -0,0 +1,11 @@ +--- a/ath/if_ath.c ++++ b/ath/if_ath.c +@@ -504,7 +504,7 @@ + + /* Allocate space for dynamically determined maximum VAP count */ + sc->sc_bslot = +- kzalloc(ath_maxvaps * sizeof(struct ieee80211vap), GFP_KERNEL); ++ kzalloc(ath_maxvaps * sizeof(struct ieee80211vap *), GFP_KERNEL); + + /* + * Cache line size is used to size and align various diff --git a/package/madwifi/patches-testing/329-turbo_chansearch.patch b/package/madwifi/patches-testing/329-turbo_chansearch.patch new file mode 100644 index 0000000000..ba8b01c12f --- /dev/null +++ b/package/madwifi/patches-testing/329-turbo_chansearch.patch @@ -0,0 +1,10 @@ +--- a/net80211/ieee80211.c ++++ b/net80211/ieee80211.c +@@ -695,6 +695,7 @@ + int i; + + /* Brute force search */ ++ flags &= IEEE80211_CHAN_ALLTURBO; + for (i = 0; i < ic->ic_nchans; i++) { + c = &ic->ic_channels[i]; + if (c->ic_freq == freq && diff --git a/package/madwifi/patches-testing/330-bstuck_thresh.patch b/package/madwifi/patches-testing/330-bstuck_thresh.patch new file mode 100644 index 0000000000..5f864bb59f --- /dev/null +++ b/package/madwifi/patches-testing/330-bstuck_thresh.patch @@ -0,0 +1,52 @@ +--- a/ath/if_ath.c ++++ b/ath/if_ath.c +@@ -354,6 +354,7 @@ + static int ath_outdoor = AH_FALSE; /* enable outdoor use */ + static int ath_xchanmode = AH_TRUE; /* enable extended channels */ + static int ath_maxvaps = ATH_MAXVAPS_DEFAULT; /* set default maximum vaps */ ++static int bstuck_thresh = BSTUCK_THRESH; /* Stuck beacon count required for reset */ + static char *autocreate = "sta"; + static char *ratectl = DEF_RATE_CTL; + static int rfkill = 0; +@@ -397,6 +398,7 @@ + #ifdef ATH_CAP_TPC + MODULE_PARM(hal_tpc, "i"); + #endif ++MODULE_PARM(bstuck_thresh, "i"); + MODULE_PARM(autocreate, "s"); + MODULE_PARM(ratectl, "s"); + #else +@@ -410,6 +412,7 @@ + #ifdef ATH_CAP_TPC + module_param(hal_tpc, int, 0600); + #endif ++module_param(bstuck_thresh, int, 0600); + module_param(autocreate, charp, 0600); + module_param(ratectl, charp, 0600); + #endif +@@ -422,6 +425,7 @@ + MODULE_PARM_DESC(hal_tpc, "Disables manual per-packet transmit power control and " + "lets this be managed by the HAL. Default is OFF."); + #endif ++MODULE_PARM_DESC(bstuck_thresh, "Override default stuck beacon threshold"); + MODULE_PARM_DESC(autocreate, "Create ath device in " + "[sta|ap|wds|adhoc|ahdemo|monitor] mode. defaults to sta, use " + "'none' to disable"); +@@ -5239,7 +5243,7 @@ + DPRINTF(sc, ATH_DEBUG_BEACON_PROC, + "Missed %u consecutive beacons (n_beacon=%u)\n", + sc->sc_bmisscount, n_beacon); +- if (sc->sc_bmisscount > BSTUCK_THRESH) ++ if (sc->sc_bmisscount > bstuck_thresh) + ATH_SCHEDULE_TQUEUE(&sc->sc_bstucktq, needmark); + return; + } +@@ -5410,7 +5414,7 @@ + * check will be true, in which case return + * without resetting the driver. + */ +- if (sc->sc_bmisscount <= BSTUCK_THRESH) ++ if (sc->sc_bmisscount <= bstuck_thresh) + return; + EPRINTF(sc, "Stuck beacon; resetting (beacon miss count: %u)\n", + sc->sc_bmisscount); diff --git a/package/madwifi/patches-testing/331-linux24_fix.patch b/package/madwifi/patches-testing/331-linux24_fix.patch new file mode 100644 index 0000000000..1d9a2d06c1 --- /dev/null +++ b/package/madwifi/patches-testing/331-linux24_fix.patch @@ -0,0 +1,15 @@ +--- a/ath_hal/Makefile ++++ b/ath_hal/Makefile +@@ -79,10 +79,11 @@ + quiet_cmd_uudecode = UUDECODE $@ + cmd_uudecode = $(obj)/uudecode -o $@ $< + +-$(obj)/$(TARGET).hal.o: $(HAL)/public/$(TARGET).hal.o.uu $(obj)/uudecode + ifdef LINUX24 ++$(TARGET).hal.o: $(HAL)/public/$(TARGET).hal.o.uu $(obj)/uudecode + $(Q)$(obj)/uudecode -o $@ $< + else ++$(obj)/$(TARGET).hal.o: $(HAL)/public/$(TARGET).hal.o.uu $(obj)/uudecode + $(call if_changed,uudecode) + endif + # Replace as many hashed names as possible with meaningful diff --git a/package/madwifi/patches-testing/332-retransmit_check.patch b/package/madwifi/patches-testing/332-retransmit_check.patch new file mode 100644 index 0000000000..ec1fcf9c72 --- /dev/null +++ b/package/madwifi/patches-testing/332-retransmit_check.patch @@ -0,0 +1,22 @@ +--- a/net80211/ieee80211.h ++++ b/net80211/ieee80211.h +@@ -174,8 +174,6 @@ + #define IEEE80211_SEQ_SEQ_MASK 0xfff0 + #define IEEE80211_SEQ_SEQ_SHIFT 4 + +-#define IEEE80211_SEQ_LEQ(a,b) ((int)((a)-(b)) <= 0) +- + #define IEEE80211_NWID_LEN 32 + + #define IEEE80211_QOS_TXOP 0x00ff +--- a/net80211/ieee80211_input.c ++++ b/net80211/ieee80211_input.c +@@ -406,7 +406,7 @@ + tid = 0; + rxseq = le16toh(*(__le16 *)wh->i_seq); + if ((wh->i_fc[1] & IEEE80211_FC1_RETRY) && +- IEEE80211_SEQ_LEQ(rxseq, ni->ni_rxseqs[tid])) { ++ (rxseq == ni->ni_rxseqs[tid])) { + /* duplicate, discard */ + IEEE80211_DISCARD_MAC(vap, IEEE80211_MSG_INPUT, + bssid, "duplicate", diff --git a/package/madwifi/patches-testing/333-hal_init_msg.patch b/package/madwifi/patches-testing/333-hal_init_msg.patch new file mode 100644 index 0000000000..1369dcfc19 --- /dev/null +++ b/package/madwifi/patches-testing/333-hal_init_msg.patch @@ -0,0 +1,30 @@ +--- a/ath_hal/ah_os.c ++++ b/ath_hal/ah_os.c +@@ -1136,9 +1136,6 @@ + * Module glue. + */ + #include "version.h" +-#if 0 +-static char *dev_info = "ath_hal"; +-#endif + + MODULE_AUTHOR("Errno Consulting, Sam Leffler"); + MODULE_DESCRIPTION("Atheros Hardware Access Layer (HAL)"); +@@ -1172,7 +1169,7 @@ + static int __init + init_ath_hal(void) + { +- const char *sep; ++ const char *sep = ""; + int i; + #ifdef MMIOTRACE + kmmio_logmsg = _kmmio_logmsg; +@@ -1181,7 +1178,7 @@ + ifxmips_emulate = ifxmips_has_brn_block(); + #endif + +- sep = ""; ++ printk(KERN_INFO "hal: %s (", ath_hal_version); + for (i = 0; ath_hal_buildopts[i] != NULL; i++) { + printk("%s%s", sep, ath_hal_buildopts[i]); + sep = ", ";