From 613e530afeab2eb78d7b4100420fd305662beab1 Mon Sep 17 00:00:00 2001 From: nbd Date: Thu, 17 Jul 2008 02:30:08 +0000 Subject: huge madwifi update (work in progress, disabled by default, compiles but breaks at run time) git-svn-id: svn://svn.openwrt.org/openwrt/trunk@11851 3c298f89-4303-0410-b956-a3cf2f4a3e73 --- .../patches-r3776/102-multicall_binary.patch | 383 +++++++++ .../patches-r3776/104-autocreate_none.patch | 13 + .../madwifi/patches-r3776/105-ratectl_attach.patch | 25 + .../madwifi/patches-r3776/111-minstrel_crash.patch | 14 + .../patches-r3776/122-replayfail_workaround.patch | 14 + .../madwifi/patches-r3776/123-ccmp_checks.patch | 24 + .../madwifi/patches-r3776/124-linux24_compat.patch | 210 +++++ .../madwifi/patches-r3776/126-rxerr_frames.patch | 29 + package/madwifi/patches-r3776/200-no_debug.patch | 444 ++++++++++ .../madwifi/patches-r3776/201-no_debug_extra.patch | 59 ++ .../madwifi/patches-r3776/300-napi_polling.patch | 538 +++++++++++++ package/madwifi/patches-r3776/301-pureg_fix.patch | 178 ++++ package/madwifi/patches-r3776/302-noise_get.patch | 44 + .../madwifi/patches-r3776/303-bssid_alloc.patch | 53 ++ package/madwifi/patches-r3776/304-erp_update.patch | 74 ++ package/madwifi/patches-r3776/305-bssid_mask.patch | 13 + package/madwifi/patches-r3776/306-queue.patch | 46 ++ package/madwifi/patches-r3776/307-maxrate.patch | 108 +++ package/madwifi/patches-r3776/308-minrate.patch | 124 +++ .../madwifi/patches-r3776/309-performance.patch | 221 +++++ .../patches-r3776/310-minstrel_sampling.patch | 92 +++ .../patches-r3776/311-protmode_trigger.patch | 147 ++++ .../madwifi/patches-r3776/312-ack_cts_rate.patch | 46 ++ .../patches-r3776/313-reset_channelchange.patch | 20 + .../madwifi/patches-r3776/314-wisoc_softled.patch | 11 + package/madwifi/patches-r3776/315-scanlist.patch | 892 +++++++++++++++++++++ package/madwifi/patches-r3776/316-ani_fix.patch | 740 +++++++++++++++++ package/madwifi/patches-r3776/317-devid.patch | 19 + .../madwifi/patches-r3776/318-ifxmips_eeprom.patch | 87 ++ .../patches-r3776/319-eap_auth_disassoc.patch | 89 ++ .../madwifi/patches-r3776/320-hidden_ssid.patch | 40 + .../patches-r3776/321-bgscan_rssi_thresh.patch | 137 ++++ .../patches-r3776/322-ignore_broken_bssid.patch | 20 + package/madwifi/patches-r3776/323-crash_fix.patch | 23 + package/madwifi/patches-r3776/324-reassoc.patch | 33 + .../madwifi/patches-r3776/325-sta_node_leave.patch | 61 ++ .../madwifi/patches-r3776/326-bmiss_handling.patch | 108 +++ .../patches-r3776/327-rssi_disconnect.patch | 99 +++ .../madwifi/patches-r3776/328-memory_alloc.patch | 13 + .../patches-r3776/329-turbo_chansearch.patch | 12 + .../madwifi/patches-r3776/330-bstuck_thresh.patch | 54 ++ .../madwifi/patches-r3776/331-linux24_fix.patch | 17 + .../patches-r3776/332-retransmit_check.patch | 26 + 43 files changed, 5400 insertions(+) create mode 100644 package/madwifi/patches-r3776/102-multicall_binary.patch create mode 100644 package/madwifi/patches-r3776/104-autocreate_none.patch create mode 100644 package/madwifi/patches-r3776/105-ratectl_attach.patch create mode 100644 package/madwifi/patches-r3776/111-minstrel_crash.patch create mode 100644 package/madwifi/patches-r3776/122-replayfail_workaround.patch create mode 100644 package/madwifi/patches-r3776/123-ccmp_checks.patch create mode 100644 package/madwifi/patches-r3776/124-linux24_compat.patch create mode 100644 package/madwifi/patches-r3776/126-rxerr_frames.patch create mode 100644 package/madwifi/patches-r3776/200-no_debug.patch create mode 100644 package/madwifi/patches-r3776/201-no_debug_extra.patch create mode 100644 package/madwifi/patches-r3776/300-napi_polling.patch create mode 100644 package/madwifi/patches-r3776/301-pureg_fix.patch create mode 100644 package/madwifi/patches-r3776/302-noise_get.patch create mode 100644 package/madwifi/patches-r3776/303-bssid_alloc.patch create mode 100644 package/madwifi/patches-r3776/304-erp_update.patch create mode 100644 package/madwifi/patches-r3776/305-bssid_mask.patch create mode 100644 package/madwifi/patches-r3776/306-queue.patch create mode 100644 package/madwifi/patches-r3776/307-maxrate.patch create mode 100644 package/madwifi/patches-r3776/308-minrate.patch create mode 100644 package/madwifi/patches-r3776/309-performance.patch create mode 100644 package/madwifi/patches-r3776/310-minstrel_sampling.patch create mode 100644 package/madwifi/patches-r3776/311-protmode_trigger.patch create mode 100644 package/madwifi/patches-r3776/312-ack_cts_rate.patch create mode 100644 package/madwifi/patches-r3776/313-reset_channelchange.patch create mode 100644 package/madwifi/patches-r3776/314-wisoc_softled.patch create mode 100644 package/madwifi/patches-r3776/315-scanlist.patch create mode 100644 package/madwifi/patches-r3776/316-ani_fix.patch create mode 100644 package/madwifi/patches-r3776/317-devid.patch create mode 100644 package/madwifi/patches-r3776/318-ifxmips_eeprom.patch create mode 100644 package/madwifi/patches-r3776/319-eap_auth_disassoc.patch create mode 100644 package/madwifi/patches-r3776/320-hidden_ssid.patch create mode 100644 package/madwifi/patches-r3776/321-bgscan_rssi_thresh.patch create mode 100644 package/madwifi/patches-r3776/322-ignore_broken_bssid.patch create mode 100644 package/madwifi/patches-r3776/323-crash_fix.patch create mode 100644 package/madwifi/patches-r3776/324-reassoc.patch create mode 100644 package/madwifi/patches-r3776/325-sta_node_leave.patch create mode 100644 package/madwifi/patches-r3776/326-bmiss_handling.patch create mode 100644 package/madwifi/patches-r3776/327-rssi_disconnect.patch create mode 100644 package/madwifi/patches-r3776/328-memory_alloc.patch create mode 100644 package/madwifi/patches-r3776/329-turbo_chansearch.patch create mode 100644 package/madwifi/patches-r3776/330-bstuck_thresh.patch create mode 100644 package/madwifi/patches-r3776/331-linux24_fix.patch create mode 100644 package/madwifi/patches-r3776/332-retransmit_check.patch (limited to 'package/madwifi/patches-r3776') diff --git a/package/madwifi/patches-r3776/102-multicall_binary.patch b/package/madwifi/patches-r3776/102-multicall_binary.patch new file mode 100644 index 0000000000..3dcbb04f98 --- /dev/null +++ b/package/madwifi/patches-r3776/102-multicall_binary.patch @@ -0,0 +1,383 @@ +Index: madwifi-trunk-r3776/tools/80211debug.c +=================================================================== +--- madwifi-trunk-r3776.orig/tools/80211debug.c 2008-07-17 00:22:03.000000000 +0200 ++++ madwifi-trunk-r3776/tools/80211debug.c 2008-07-17 00:23:16.000000000 +0200 +@@ -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; +Index: madwifi-trunk-r3776/tools/80211stats.c +=================================================================== +--- madwifi-trunk-r3776.orig/tools/80211stats.c 2008-07-17 00:22:03.000000000 +0200 ++++ madwifi-trunk-r3776/tools/80211stats.c 2008-07-17 00:23:16.000000000 +0200 +@@ -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; +Index: madwifi-trunk-r3776/tools/athchans.c +=================================================================== +--- madwifi-trunk-r3776.orig/tools/athchans.c 2008-07-17 00:22:03.000000000 +0200 ++++ madwifi-trunk-r3776/tools/athchans.c 2008-07-17 00:23:16.000000000 +0200 +@@ -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; +Index: madwifi-trunk-r3776/tools/athctrl.c +=================================================================== +--- madwifi-trunk-r3776.orig/tools/athctrl.c 2008-07-17 00:22:03.000000000 +0200 ++++ madwifi-trunk-r3776/tools/athctrl.c 2008-07-17 00:23:16.000000000 +0200 +@@ -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; +Index: madwifi-trunk-r3776/tools/athdebug.c +=================================================================== +--- madwifi-trunk-r3776.orig/tools/athdebug.c 2008-07-17 00:22:03.000000000 +0200 ++++ madwifi-trunk-r3776/tools/athdebug.c 2008-07-17 00:23:16.000000000 +0200 +@@ -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"; +Index: madwifi-trunk-r3776/tools/athkey.c +=================================================================== +--- madwifi-trunk-r3776.orig/tools/athkey.c 2008-07-17 00:22:03.000000000 +0200 ++++ madwifi-trunk-r3776/tools/athkey.c 2008-07-17 00:23:16.000000000 +0200 +@@ -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; +Index: madwifi-trunk-r3776/tools/athstats.c +=================================================================== +--- madwifi-trunk-r3776.orig/tools/athstats.c 2008-07-17 00:22:03.000000000 +0200 ++++ madwifi-trunk-r3776/tools/athstats.c 2008-07-17 00:23:16.000000000 +0200 +@@ -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"; +Index: madwifi-trunk-r3776/tools/do_multi.c +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ madwifi-trunk-r3776/tools/do_multi.c 2008-07-17 00:46:52.000000000 +0200 +@@ -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; ++} +Index: madwifi-trunk-r3776/tools/do_multi.h +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ madwifi-trunk-r3776/tools/do_multi.h 2008-07-17 00:23:16.000000000 +0200 +@@ -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 +Index: madwifi-trunk-r3776/tools/Makefile +=================================================================== +--- madwifi-trunk-r3776.orig/tools/Makefile 2008-07-17 00:22:03.000000000 +0200 ++++ madwifi-trunk-r3776/tools/Makefile 2008-07-17 00:45:15.000000000 +0200 +@@ -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 +Index: madwifi-trunk-r3776/tools/wlanconfig.c +=================================================================== +--- madwifi-trunk-r3776.orig/tools/wlanconfig.c 2008-07-17 00:22:03.000000000 +0200 ++++ madwifi-trunk-r3776/tools/wlanconfig.c 2008-07-17 00:45:42.000000000 +0200 +@@ -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; +Index: madwifi-trunk-r3776/tools/ath_info/Makefile +=================================================================== +--- madwifi-trunk-r3776.orig/tools/ath_info/Makefile 2008-07-17 00:21:42.000000000 +0200 ++++ madwifi-trunk-r3776/tools/ath_info/Makefile 2008-07-17 00:36:23.000000000 +0200 +@@ -15,13 +15,13 @@ + PROGRAMS = ath_info + MANS = ath_info.8 + +-all: $(PROGRAMS) ++all: $(if $(DO_MULTI),ath_info.o,$(PROGRAMS)) + + ath_info: ath_info.o + $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $< + + .c.o: +- $(CC) $(CFLAGS) -c $< ++ $(CC) $(CFLAGS) $(if $(DO_MULTI),-DDO_MULTI=1 -I..) -c $< + + clean: + rm -f *.o $(PROGRAMS) +Index: madwifi-trunk-r3776/tools/ath_info/ath_info.c +=================================================================== +--- madwifi-trunk-r3776.orig/tools/ath_info/ath_info.c 2008-07-17 00:24:08.000000000 +0200 ++++ madwifi-trunk-r3776/tools/ath_info/ath_info.c 2008-07-17 00:24:15.000000000 +0200 +@@ -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; +Index: madwifi-trunk-r3776/tools/wpakey.c +=================================================================== +--- madwifi-trunk-r3776.orig/tools/wpakey.c 2008-07-17 00:21:30.000000000 +0200 ++++ madwifi-trunk-r3776/tools/wpakey.c 2008-07-17 00:46:18.000000000 +0200 +@@ -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 new file mode 100644 index 0000000000..5796787eb1 --- /dev/null +++ b/package/madwifi/patches-r3776/104-autocreate_none.patch @@ -0,0 +1,13 @@ +Index: madwifi-trunk-r3776/ath/if_ath.c +=================================================================== +--- madwifi-trunk-r3776.orig/ath/if_ath.c 2008-07-17 00:36:00.000000000 +0200 ++++ madwifi-trunk-r3776/ath/if_ath.c 2008-07-17 00:47:22.000000000 +0200 +@@ -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 new file mode 100644 index 0000000000..3748599611 --- /dev/null +++ b/package/madwifi/patches-r3776/105-ratectl_attach.patch @@ -0,0 +1,25 @@ +Index: madwifi-trunk-r3776/net80211/ieee80211_rate.c +=================================================================== +--- madwifi-trunk-r3776.orig/net80211/ieee80211_rate.c 2008-07-17 00:35:59.000000000 +0200 ++++ madwifi-trunk-r3776/net80211/ieee80211_rate.c 2008-07-17 00:47:27.000000000 +0200 +@@ -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 new file mode 100644 index 0000000000..250a21ff25 --- /dev/null +++ b/package/madwifi/patches-r3776/111-minstrel_crash.patch @@ -0,0 +1,14 @@ +Index: madwifi-trunk-r3776/ath_rate/minstrel/minstrel.c +=================================================================== +--- madwifi-trunk-r3776.orig/ath_rate/minstrel/minstrel.c 2008-07-17 00:35:59.000000000 +0200 ++++ madwifi-trunk-r3776/ath_rate/minstrel/minstrel.c 2008-07-17 00:47:36.000000000 +0200 +@@ -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 new file mode 100644 index 0000000000..c016e723b3 --- /dev/null +++ b/package/madwifi/patches-r3776/122-replayfail_workaround.patch @@ -0,0 +1,14 @@ +Index: madwifi-trunk-r3776/net80211/ieee80211_linux.c +=================================================================== +--- madwifi-trunk-r3776.orig/net80211/ieee80211_linux.c 2008-07-17 00:21:29.000000000 +0200 ++++ madwifi-trunk-r3776/net80211/ieee80211_linux.c 2008-07-17 00:49:54.000000000 +0200 +@@ -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 new file mode 100644 index 0000000000..a0dba1ca60 --- /dev/null +++ b/package/madwifi/patches-r3776/123-ccmp_checks.patch @@ -0,0 +1,24 @@ +Index: madwifi-trunk-r3776/net80211/ieee80211_crypto_ccmp.c +=================================================================== +--- madwifi-trunk-r3776.orig/net80211/ieee80211_crypto_ccmp.c 2008-07-17 00:21:29.000000000 +0200 ++++ madwifi-trunk-r3776/net80211/ieee80211_crypto_ccmp.c 2008-07-17 00:49:59.000000000 +0200 +@@ -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 new file mode 100644 index 0000000000..0ef7d92741 --- /dev/null +++ b/package/madwifi/patches-r3776/124-linux24_compat.patch @@ -0,0 +1,210 @@ +Index: madwifi-trunk-r3776/ath/if_athvar.h +=================================================================== +--- madwifi-trunk-r3776.orig/ath/if_athvar.h 2008-07-17 00:21:39.000000000 +0200 ++++ madwifi-trunk-r3776/ath/if_athvar.h 2008-07-17 00:50:03.000000000 +0200 +@@ -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 *)) +Index: madwifi-trunk-r3776/ath/if_ath_radar.c +=================================================================== +--- madwifi-trunk-r3776.orig/ath/if_ath_radar.c 2008-07-17 00:21:39.000000000 +0200 ++++ madwifi-trunk-r3776/ath/if_ath_radar.c 2008-07-17 00:50:03.000000000 +0200 +@@ -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; +Index: madwifi-trunk-r3776/ath/if_ath.c +=================================================================== +--- madwifi-trunk-r3776.orig/ath/if_ath.c 2008-07-17 00:47:22.000000000 +0200 ++++ madwifi-trunk-r3776/ath/if_ath.c 2008-07-17 00:50:03.000000000 +0200 +@@ -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. + */ +Index: madwifi-trunk-r3776/net80211/sort.c +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ madwifi-trunk-r3776/net80211/sort.c 2008-07-17 00:50:03.000000000 +0200 +@@ -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 new file mode 100644 index 0000000000..4639b5abfb --- /dev/null +++ b/package/madwifi/patches-r3776/126-rxerr_frames.patch @@ -0,0 +1,29 @@ +Index: madwifi-trunk-r3776/ath/if_ath.c +=================================================================== +--- madwifi-trunk-r3776.orig/ath/if_ath.c 2008-07-17 00:52:28.000000000 +0200 ++++ madwifi-trunk-r3776/ath/if_ath.c 2008-07-17 00:53:04.000000000 +0200 +@@ -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 new file mode 100644 index 0000000000..b28782cfe6 --- /dev/null +++ b/package/madwifi/patches-r3776/200-no_debug.patch @@ -0,0 +1,444 @@ +Index: madwifi-trunk-r3776/ath/if_ath.c +=================================================================== +--- madwifi-trunk-r3776.orig/ath/if_ath.c 2008-07-17 00:53:04.000000000 +0200 ++++ madwifi-trunk-r3776/ath/if_ath.c 2008-07-17 01:15:21.000000000 +0200 +@@ -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). */ +Index: madwifi-trunk-r3776/ath_rate/amrr/amrr.c +=================================================================== +--- madwifi-trunk-r3776.orig/ath_rate/amrr/amrr.c 2008-07-17 00:21:30.000000000 +0200 ++++ madwifi-trunk-r3776/ath_rate/amrr/amrr.c 2008-07-17 00:53:20.000000000 +0200 +@@ -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) \ +Index: madwifi-trunk-r3776/ath_rate/minstrel/minstrel.c +=================================================================== +--- madwifi-trunk-r3776.orig/ath_rate/minstrel/minstrel.c 2008-07-17 00:47:36.000000000 +0200 ++++ madwifi-trunk-r3776/ath_rate/minstrel/minstrel.c 2008-07-17 01:16:06.000000000 +0200 +@@ -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) { +Index: madwifi-trunk-r3776/ath_rate/onoe/onoe.c +=================================================================== +--- madwifi-trunk-r3776.orig/ath_rate/onoe/onoe.c 2008-07-17 00:21:29.000000000 +0200 ++++ madwifi-trunk-r3776/ath_rate/onoe/onoe.c 2008-07-17 00:53:20.000000000 +0200 +@@ -66,7 +66,9 @@ + + #include "onoe.h" + ++#ifdef AR_DEBUG + #define ONOE_DEBUG ++#endif + #ifdef ONOE_DEBUG + enum { + ATH_DEBUG_RATE = 0x00000010, /* rate control */ +Index: madwifi-trunk-r3776/ath_rate/sample/sample.c +=================================================================== +--- madwifi-trunk-r3776.orig/ath_rate/sample/sample.c 2008-07-17 00:21:30.000000000 +0200 ++++ madwifi-trunk-r3776/ath_rate/sample/sample.c 2008-07-17 00:53:20.000000000 +0200 +@@ -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 */ +Index: madwifi-trunk-r3776/tools/do_multi.c +=================================================================== +--- madwifi-trunk-r3776.orig/tools/do_multi.c 2008-07-17 00:46:52.000000000 +0200 ++++ madwifi-trunk-r3776/tools/do_multi.c 2008-07-17 00:53:20.000000000 +0200 +@@ -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) +Index: madwifi-trunk-r3776/tools/Makefile +=================================================================== +--- madwifi-trunk-r3776.orig/tools/Makefile 2008-07-17 00:45:15.000000000 +0200 ++++ madwifi-trunk-r3776/tools/Makefile 2008-07-17 01:10:33.000000000 +0200 +@@ -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 + +Index: madwifi-trunk-r3776/ath/if_ath_hal.h +=================================================================== +--- madwifi-trunk-r3776.orig/ath/if_ath_hal.h 2008-07-17 00:21:39.000000000 +0200 ++++ madwifi-trunk-r3776/ath/if_ath_hal.h 2008-07-17 00:53:20.000000000 +0200 +@@ -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" + +Index: madwifi-trunk-r3776/net80211/ieee80211_var.h +=================================================================== +--- madwifi-trunk-r3776.orig/net80211/ieee80211_var.h 2008-07-17 00:21:29.000000000 +0200 ++++ madwifi-trunk-r3776/net80211/ieee80211_var.h 2008-07-17 00:53:20.000000000 +0200 +@@ -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 *); +Index: madwifi-trunk-r3776/net80211/ieee80211_wireless.c +=================================================================== +--- madwifi-trunk-r3776.orig/net80211/ieee80211_wireless.c 2008-07-17 00:21:29.000000000 +0200 ++++ madwifi-trunk-r3776/net80211/ieee80211_wireless.c 2008-07-17 00:53:20.000000000 +0200 +@@ -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), +Index: madwifi-trunk-r3776/ath/if_ath_debug.h +=================================================================== +--- madwifi-trunk-r3776.orig/ath/if_ath_debug.h 2008-07-17 00:21:39.000000000 +0200 ++++ madwifi-trunk-r3776/ath/if_ath_debug.h 2008-07-17 00:53:20.000000000 +0200 +@@ -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_ */ +Index: madwifi-trunk-r3776/ath/if_ath_pci.c +=================================================================== +--- madwifi-trunk-r3776.orig/ath/if_ath_pci.c 2008-07-17 00:21:39.000000000 +0200 ++++ madwifi-trunk-r3776/ath/if_ath_pci.c 2008-07-17 00:53:20.000000000 +0200 +@@ -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 new file mode 100644 index 0000000000..693c1f9eec --- /dev/null +++ b/package/madwifi/patches-r3776/201-no_debug_extra.patch @@ -0,0 +1,59 @@ +Index: madwifi-trunk-r3776/ath/if_ath.c +=================================================================== +--- madwifi-trunk-r3776.orig/ath/if_ath.c 2008-07-17 01:15:21.000000000 +0200 ++++ madwifi-trunk-r3776/ath/if_ath.c 2008-07-17 01:20:11.000000000 +0200 +@@ -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; +Index: madwifi-trunk-r3776/net80211/ieee80211_scan_ap.c +=================================================================== +--- madwifi-trunk-r3776.orig/net80211/ieee80211_scan_ap.c 2008-07-17 00:21:29.000000000 +0200 ++++ madwifi-trunk-r3776/net80211/ieee80211_scan_ap.c 2008-07-17 01:25:32.000000000 +0200 +@@ -790,15 +790,18 @@ + struct ap_state *as = ss->ss_priv; + struct channel chans[ss_last]; /* actually ss_last-1 is required */ + struct channel *c = NULL; +- struct pc_params params = { vap, ss, flags }; + int benefit = 0; + int sta_assoc = 0; + ++#ifdef IEEE80211_DEBUG ++ struct pc_params params = { vap, ss, flags }; ++ + for (i = 0; i < ss_last; i++) { + chans[i].chan = ss->ss_chans[i]; + chans[i].orig = i; + chans[i].params = ¶ms; + } ++#endif + + sort(chans, ss_last, sizeof(*chans), pc_cmp, pc_swap); + diff --git a/package/madwifi/patches-r3776/300-napi_polling.patch b/package/madwifi/patches-r3776/300-napi_polling.patch new file mode 100644 index 0000000000..e7e5bfd0b2 --- /dev/null +++ b/package/madwifi/patches-r3776/300-napi_polling.patch @@ -0,0 +1,538 @@ +Index: madwifi-trunk-r3776/ath/if_ath.c +=================================================================== +--- madwifi-trunk-r3776.orig/ath/if_ath.c 2008-07-17 01:20:11.000000000 +0200 ++++ madwifi-trunk-r3776/ath/if_ath.c 2008-07-17 01:46:37.000000000 +0200 +@@ -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,39 @@ + return ath_keyset(sc, k, mac, vap->iv_bss); + } + ++static void ath_poll_disable(struct net_device *dev) ++{ ++ struct ath_softc *sc = dev->priv; ++ ++ /* ++ * 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) ++{ ++ struct ath_softc *sc = dev->priv; ++ ++ /* 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 +4191,26 @@ + 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 +6470,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 +6496,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 +6504,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 +6534,10 @@ + break; + + bf_processed++; ++ if (rx_limit-- < 0) { ++ early_stop = 1; ++ break; ++ } + ds = bf->bf_desc; + + #ifdef AR_DEBUG +@@ -6491,6 +6572,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 +6771,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 +6810,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 +8421,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 +8454,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 +8486,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 +10461,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); + +Index: madwifi-trunk-r3776/ath/if_athvar.h +=================================================================== +--- madwifi-trunk-r3776.orig/ath/if_athvar.h 2008-07-17 00:52:28.000000000 +0200 ++++ madwifi-trunk-r3776/ath/if_athvar.h 2008-07-17 01:27:21.000000000 +0200 +@@ -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) +Index: madwifi-trunk-r3776/net80211/ieee80211_skb.c +=================================================================== +--- madwifi-trunk-r3776.orig/net80211/ieee80211_skb.c 2008-07-17 00:21:29.000000000 +0200 ++++ madwifi-trunk-r3776/net80211/ieee80211_skb.c 2008-07-17 01:42:17.000000000 +0200 +@@ -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); +Index: madwifi-trunk-r3776/net80211/ieee80211_skb.h +=================================================================== +--- madwifi-trunk-r3776.orig/net80211/ieee80211_skb.h 2008-07-17 00:21:29.000000000 +0200 ++++ madwifi-trunk-r3776/net80211/ieee80211_skb.h 2008-07-17 01:42:43.000000000 +0200 +@@ -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) \ +Index: madwifi-trunk-r3776/net80211/ieee80211_input.c +=================================================================== +--- madwifi-trunk-r3776.orig/net80211/ieee80211_input.c 2008-07-17 00:21:29.000000000 +0200 ++++ madwifi-trunk-r3776/net80211/ieee80211_input.c 2008-07-17 01:41:16.000000000 +0200 +@@ -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++; + } + } +Index: madwifi-trunk-r3776/net80211/ieee80211_monitor.c +=================================================================== +--- madwifi-trunk-r3776.orig/net80211/ieee80211_monitor.c 2008-07-17 00:21:29.000000000 +0200 ++++ madwifi-trunk-r3776/net80211/ieee80211_monitor.c 2008-07-17 01:41:51.000000000 +0200 +@@ -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 new file mode 100644 index 0000000000..de8d83c052 --- /dev/null +++ b/package/madwifi/patches-r3776/301-pureg_fix.patch @@ -0,0 +1,178 @@ +Index: madwifi-trunk-r3776/ath/if_ath.c +=================================================================== +--- madwifi-trunk-r3776.orig/ath/if_ath.c 2008-07-17 01:46:37.000000000 +0200 ++++ madwifi-trunk-r3776/ath/if_ath.c 2008-07-17 01:46:44.000000000 +0200 +@@ -4250,7 +4250,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 | +Index: madwifi-trunk-r3776/net80211/ieee80211_input.c +=================================================================== +--- madwifi-trunk-r3776.orig/net80211/ieee80211_input.c 2008-07-17 01:41:16.000000000 +0200 ++++ madwifi-trunk-r3776/net80211/ieee80211_input.c 2008-07-17 01:46:44.000000000 +0200 +@@ -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. + */ +Index: madwifi-trunk-r3776/net80211/ieee80211_node.c +=================================================================== +--- madwifi-trunk-r3776.orig/net80211/ieee80211_node.c 2008-07-17 00:53:20.000000000 +0200 ++++ madwifi-trunk-r3776/net80211/ieee80211_node.c 2008-07-17 01:46:44.000000000 +0200 +@@ -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)); + } +Index: madwifi-trunk-r3776/net80211/ieee80211_proto.c +=================================================================== +--- madwifi-trunk-r3776.orig/net80211/ieee80211_proto.c 2008-07-17 00:21:29.000000000 +0200 ++++ madwifi-trunk-r3776/net80211/ieee80211_proto.c 2008-07-17 01:46:44.000000000 +0200 +@@ -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 +Index: madwifi-trunk-r3776/net80211/ieee80211_var.h +=================================================================== +--- madwifi-trunk-r3776.orig/net80211/ieee80211_var.h 2008-07-17 00:53:20.000000000 +0200 ++++ madwifi-trunk-r3776/net80211/ieee80211_var.h 2008-07-17 01:46:44.000000000 +0200 +@@ -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 new file mode 100644 index 0000000000..98440f76a0 --- /dev/null +++ b/package/madwifi/patches-r3776/302-noise_get.patch @@ -0,0 +1,44 @@ +Index: madwifi-trunk-r3776/ath/if_ath.c +=================================================================== +--- madwifi-trunk-r3776.orig/ath/if_ath.c 2008-07-17 01:46:44.000000000 +0200 ++++ madwifi-trunk-r3776/ath/if_ath.c 2008-07-17 01:49:58.000000000 +0200 +@@ -8996,6 +8996,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, +@@ -9051,6 +9052,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 +Index: madwifi-trunk-r3776/net80211/ieee80211_wireless.c +=================================================================== +--- madwifi-trunk-r3776.orig/net80211/ieee80211_wireless.c 2008-07-17 00:53:20.000000000 +0200 ++++ madwifi-trunk-r3776/net80211/ieee80211_wireless.c 2008-07-17 01:49:58.000000000 +0200 +@@ -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; +Index: madwifi-trunk-r3776/net80211/ieee80211_ioctl.h +=================================================================== +--- madwifi-trunk-r3776.orig/net80211/ieee80211_ioctl.h 2008-07-17 00:21:29.000000000 +0200 ++++ madwifi-trunk-r3776/net80211/ieee80211_ioctl.h 2008-07-17 01:49:58.000000000 +0200 +@@ -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 new file mode 100644 index 0000000000..c10a21cf9b --- /dev/null +++ b/package/madwifi/patches-r3776/303-bssid_alloc.patch @@ -0,0 +1,53 @@ +Index: madwifi-trunk-r3776/ath/if_ath.c +=================================================================== +--- madwifi-trunk-r3776.orig/ath/if_ath.c 2008-07-17 01:49:58.000000000 +0200 ++++ madwifi-trunk-r3776/ath/if_ath.c 2008-07-17 01:57:39.000000000 +0200 +@@ -1333,7 +1333,7 @@ + /* Use RadioTAP interface type for monitor mode. */ + dev->type = ARPHRD_IEEE80211_RADIOTAP; + +- if (flags & IEEE80211_CLONE_BSSID) { ++ if (!(flags & IEEE80211_CLONE_BSSID)) { + if (sc->sc_hasbmask) { + struct ieee80211vap *v; + uint64_t id_mask = 0; +@@ -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); +Index: madwifi-trunk-r3776/ath/if_athvar.h +=================================================================== +--- madwifi-trunk-r3776.orig/ath/if_athvar.h 2008-07-17 01:27:21.000000000 +0200 ++++ madwifi-trunk-r3776/ath/if_athvar.h 2008-07-17 01:57:15.000000000 +0200 +@@ -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 new file mode 100644 index 0000000000..796406ecf7 --- /dev/null +++ b/package/madwifi/patches-r3776/304-erp_update.patch @@ -0,0 +1,74 @@ +Index: madwifi-trunk-r3776/net80211/ieee80211_beacon.c +=================================================================== +--- madwifi-trunk-r3776.orig/net80211/ieee80211_beacon.c 2008-07-17 00:21:29.000000000 +0200 ++++ madwifi-trunk-r3776/net80211/ieee80211_beacon.c 2008-07-17 01:58:24.000000000 +0200 +@@ -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 */ +Index: madwifi-trunk-r3776/net80211/ieee80211_input.c +=================================================================== +--- madwifi-trunk-r3776.orig/net80211/ieee80211_input.c 2008-07-17 01:46:44.000000000 +0200 ++++ madwifi-trunk-r3776/net80211/ieee80211_input.c 2008-07-17 01:58:24.000000000 +0200 +@@ -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; ++ } + } + } + +Index: madwifi-trunk-r3776/net80211/ieee80211_node.c +=================================================================== +--- madwifi-trunk-r3776.orig/net80211/ieee80211_node.c 2008-07-17 01:46:44.000000000 +0200 ++++ madwifi-trunk-r3776/net80211/ieee80211_node.c 2008-07-17 01:58:24.000000000 +0200 +@@ -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 new file mode 100644 index 0000000000..24d2f9f22c --- /dev/null +++ b/package/madwifi/patches-r3776/305-bssid_mask.patch @@ -0,0 +1,13 @@ +--- a/ath/if_ath.c ++++ b/ath/if_ath.c +@@ -8692,6 +8692,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 new file mode 100644 index 0000000000..4b9665f99e --- /dev/null +++ b/package/madwifi/patches-r3776/306-queue.patch @@ -0,0 +1,46 @@ +Index: madwifi-trunk-r3776/ath/if_ath.c +=================================================================== +--- madwifi-trunk-r3776.orig/ath/if_ath.c 2008-07-17 02:00:09.000000000 +0200 ++++ madwifi-trunk-r3776/ath/if_ath.c 2008-07-17 02:09:38.000000000 +0200 +@@ -8447,8 +8447,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); + } +@@ -8504,8 +8502,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); + } +@@ -8536,7 +8532,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); +Index: madwifi-trunk-r3776/net80211/ieee80211_input.c +=================================================================== +--- madwifi-trunk-r3776.orig/net80211/ieee80211_input.c 2008-07-17 02:04:20.000000000 +0200 ++++ madwifi-trunk-r3776/net80211/ieee80211_input.c 2008-07-17 02:05:45.000000000 +0200 +@@ -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 new file mode 100644 index 0000000000..fc3363dc17 --- /dev/null +++ b/package/madwifi/patches-r3776/307-maxrate.patch @@ -0,0 +1,108 @@ +Index: madwifi-trunk-r3776/ath/if_ath.c +=================================================================== +--- madwifi-trunk-r3776.orig/ath/if_ath.c 2008-07-17 02:20:52.000000000 +0200 ++++ madwifi-trunk-r3776/ath/if_ath.c 2008-07-17 02:20:53.000000000 +0200 +@@ -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). */ +Index: madwifi-trunk-r3776/ath_rate/sample/sample.c +=================================================================== +--- madwifi-trunk-r3776.orig/ath_rate/sample/sample.c 2008-07-17 02:20:26.000000000 +0200 ++++ madwifi-trunk-r3776/ath_rate/sample/sample.c 2008-07-17 02:20:53.000000000 +0200 +@@ -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]; +Index: madwifi-trunk-r3776/net80211/ieee80211_var.h +=================================================================== +--- madwifi-trunk-r3776.orig/net80211/ieee80211_var.h 2008-07-17 02:20:51.000000000 +0200 ++++ madwifi-trunk-r3776/net80211/ieee80211_var.h 2008-07-17 02:20:53.000000000 +0200 +@@ -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 +Index: madwifi-trunk-r3776/net80211/ieee80211_wireless.c +=================================================================== +--- madwifi-trunk-r3776.orig/net80211/ieee80211_wireless.c 2008-07-17 02:20:51.000000000 +0200 ++++ madwifi-trunk-r3776/net80211/ieee80211_wireless.c 2008-07-17 02:20:53.000000000 +0200 +@@ -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 + /* +Index: madwifi-trunk-r3776/net80211/ieee80211_ioctl.h +=================================================================== +--- madwifi-trunk-r3776.orig/net80211/ieee80211_ioctl.h 2008-07-17 02:20:51.000000000 +0200 ++++ madwifi-trunk-r3776/net80211/ieee80211_ioctl.h 2008-07-17 02:20:53.000000000 +0200 +@@ -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) +Index: madwifi-trunk-r3776/ath_rate/minstrel/minstrel.c +=================================================================== +--- madwifi-trunk-r3776.orig/ath_rate/minstrel/minstrel.c 2008-07-17 02:22:27.000000000 +0200 ++++ madwifi-trunk-r3776/ath_rate/minstrel/minstrel.c 2008-07-17 02:22:33.000000000 +0200 +@@ -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 new file mode 100644 index 0000000000..616aec90a5 --- /dev/null +++ b/package/madwifi/patches-r3776/308-minrate.patch @@ -0,0 +1,124 @@ +Index: madwifi-trunk-r3776/ath/if_ath.c +=================================================================== +--- madwifi-trunk-r3776.orig/ath/if_ath.c 2008-07-17 02:20:53.000000000 +0200 ++++ madwifi-trunk-r3776/ath/if_ath.c 2008-07-17 02:23:00.000000000 +0200 +@@ -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). */ +Index: madwifi-trunk-r3776/ath_rate/minstrel/minstrel.c +=================================================================== +--- madwifi-trunk-r3776.orig/ath_rate/minstrel/minstrel.c 2008-07-17 02:22:33.000000000 +0200 ++++ madwifi-trunk-r3776/ath_rate/minstrel/minstrel.c 2008-07-17 02:27:44.000000000 +0200 +@@ -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); +Index: madwifi-trunk-r3776/ath_rate/sample/sample.c +=================================================================== +--- madwifi-trunk-r3776.orig/ath_rate/sample/sample.c 2008-07-17 02:20:53.000000000 +0200 ++++ madwifi-trunk-r3776/ath_rate/sample/sample.c 2008-07-17 02:27:08.000000000 +0200 +@@ -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); +Index: madwifi-trunk-r3776/net80211/ieee80211_ioctl.h +=================================================================== +--- madwifi-trunk-r3776.orig/net80211/ieee80211_ioctl.h 2008-07-17 02:20:53.000000000 +0200 ++++ madwifi-trunk-r3776/net80211/ieee80211_ioctl.h 2008-07-17 02:25:53.000000000 +0200 +@@ -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) +Index: madwifi-trunk-r3776/net80211/ieee80211_var.h +=================================================================== +--- madwifi-trunk-r3776.orig/net80211/ieee80211_var.h 2008-07-17 02:20:53.000000000 +0200 ++++ madwifi-trunk-r3776/net80211/ieee80211_var.h 2008-07-17 02:23:00.000000000 +0200 +@@ -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 +Index: madwifi-trunk-r3776/net80211/ieee80211_wireless.c +=================================================================== +--- madwifi-trunk-r3776.orig/net80211/ieee80211_wireless.c 2008-07-17 02:20:53.000000000 +0200 ++++ madwifi-trunk-r3776/net80211/ieee80211_wireless.c 2008-07-17 02:26:17.000000000 +0200 +@@ -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 new file mode 100644 index 0000000000..517c336bea --- /dev/null +++ b/package/madwifi/patches-r3776/309-performance.patch @@ -0,0 +1,221 @@ +Index: madwifi-trunk-r3776/ath/if_ath.c +=================================================================== +--- madwifi-trunk-r3776.orig/ath/if_ath.c 2008-07-17 02:23:00.000000000 +0200 ++++ madwifi-trunk-r3776/ath/if_ath.c 2008-07-17 02:28:06.000000000 +0200 +@@ -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; +Index: madwifi-trunk-r3776/net80211/ieee80211_output.c +=================================================================== +--- madwifi-trunk-r3776.orig/net80211/ieee80211_output.c 2008-07-17 00:21:29.000000000 +0200 ++++ madwifi-trunk-r3776/net80211/ieee80211_output.c 2008-07-17 02:35:10.000000000 +0200 +@@ -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) +Index: madwifi-trunk-r3776/net80211/ieee80211_input.c +=================================================================== +--- madwifi-trunk-r3776.orig/net80211/ieee80211_input.c 2008-07-17 02:20:52.000000000 +0200 ++++ madwifi-trunk-r3776/net80211/ieee80211_input.c 2008-07-17 02:30:28.000000000 +0200 +@@ -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 new file mode 100644 index 0000000000..a395b3cbef --- /dev/null +++ b/package/madwifi/patches-r3776/310-minstrel_sampling.patch @@ -0,0 +1,92 @@ +Index: madwifi-trunk-r3776/ath/if_ath.c +=================================================================== +--- madwifi-trunk-r3776.orig/ath/if_ath.c 2008-07-17 02:28:06.000000000 +0200 ++++ madwifi-trunk-r3776/ath/if_ath.c 2008-07-17 02:37:41.000000000 +0200 +@@ -8109,6 +8109,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 +Index: madwifi-trunk-r3776/ath/if_athvar.h +=================================================================== +--- madwifi-trunk-r3776.orig/ath/if_athvar.h 2008-07-17 02:20:51.000000000 +0200 ++++ madwifi-trunk-r3776/ath/if_athvar.h 2008-07-17 02:37:41.000000000 +0200 +@@ -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. +Index: madwifi-trunk-r3776/ath_rate/minstrel/minstrel.c +=================================================================== +--- madwifi-trunk-r3776.orig/ath_rate/minstrel/minstrel.c 2008-07-17 02:27:44.000000000 +0200 ++++ madwifi-trunk-r3776/ath_rate/minstrel/minstrel.c 2008-07-17 02:39:20.000000000 +0200 +@@ -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; +Index: madwifi-trunk-r3776/net80211/ieee80211_rate.h +=================================================================== +--- madwifi-trunk-r3776.orig/net80211/ieee80211_rate.h 2008-07-17 00:21:29.000000000 +0200 ++++ madwifi-trunk-r3776/net80211/ieee80211_rate.h 2008-07-17 02:37:41.000000000 +0200 +@@ -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 new file mode 100644 index 0000000000..29fc629089 --- /dev/null +++ b/package/madwifi/patches-r3776/311-protmode_trigger.patch @@ -0,0 +1,147 @@ +Index: madwifi-trunk-r3776/net80211/ieee80211.c +=================================================================== +--- madwifi-trunk-r3776.orig/net80211/ieee80211.c 2008-07-17 00:21:29.000000000 +0200 ++++ madwifi-trunk-r3776/net80211/ieee80211.c 2008-07-17 02:56:18.000000000 +0200 +@@ -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); +Index: madwifi-trunk-r3776/net80211/ieee80211_input.c +=================================================================== +--- madwifi-trunk-r3776.orig/net80211/ieee80211_input.c 2008-07-17 02:30:28.000000000 +0200 ++++ madwifi-trunk-r3776/net80211/ieee80211_input.c 2008-07-17 02:56:18.000000000 +0200 +@@ -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; + } + } + +Index: madwifi-trunk-r3776/net80211/ieee80211_ioctl.h +=================================================================== +--- madwifi-trunk-r3776.orig/net80211/ieee80211_ioctl.h 2008-07-17 02:25:53.000000000 +0200 ++++ madwifi-trunk-r3776/net80211/ieee80211_ioctl.h 2008-07-17 02:56:52.000000000 +0200 +@@ -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) +Index: madwifi-trunk-r3776/net80211/ieee80211_var.h +=================================================================== +--- madwifi-trunk-r3776.orig/net80211/ieee80211_var.h 2008-07-17 02:23:00.000000000 +0200 ++++ madwifi-trunk-r3776/net80211/ieee80211_var.h 2008-07-17 02:56:18.000000000 +0200 +@@ -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: + * +Index: madwifi-trunk-r3776/net80211/ieee80211_wireless.c +=================================================================== +--- madwifi-trunk-r3776.orig/net80211/ieee80211_wireless.c 2008-07-17 02:26:17.000000000 +0200 ++++ madwifi-trunk-r3776/net80211/ieee80211_wireless.c 2008-07-17 02:56:18.000000000 +0200 +@@ -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, +Index: madwifi-trunk-r3776/net80211/ieee80211_node.c +=================================================================== +--- madwifi-trunk-r3776.orig/net80211/ieee80211_node.c 2008-07-17 02:20:51.000000000 +0200 ++++ madwifi-trunk-r3776/net80211/ieee80211_node.c 2008-07-17 02:56:18.000000000 +0200 +@@ -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 new file mode 100644 index 0000000000..3f172ca0b7 --- /dev/null +++ b/package/madwifi/patches-r3776/312-ack_cts_rate.patch @@ -0,0 +1,46 @@ +Index: madwifi-trunk-r3776/ath/if_ath.c +=================================================================== +--- madwifi-trunk-r3776.orig/ath/if_ath.c 2008-07-17 02:37:41.000000000 +0200 ++++ madwifi-trunk-r3776/ath/if_ath.c 2008-07-17 03:04:02.000000000 +0200 +@@ -10889,8 +10889,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, +Index: madwifi-trunk-r3776/ath/if_athvar.h +=================================================================== +--- madwifi-trunk-r3776.orig/ath/if_athvar.h 2008-07-17 02:37:41.000000000 +0200 ++++ madwifi-trunk-r3776/ath/if_athvar.h 2008-07-17 03:04:02.000000000 +0200 +@@ -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 */ +Index: madwifi-trunk-r3776/ath/if_ath_hal_extensions.c +=================================================================== +--- madwifi-trunk-r3776.orig/ath/if_ath_hal_extensions.c 2008-07-17 00:21:39.000000000 +0200 ++++ madwifi-trunk-r3776/ath/if_ath_hal_extensions.c 2008-07-17 03:04:48.000000000 +0200 +@@ -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 new file mode 100644 index 0000000000..20a9c269d2 --- /dev/null +++ b/package/madwifi/patches-r3776/313-reset_channelchange.patch @@ -0,0 +1,20 @@ +Index: madwifi-trunk-r3776/ath/if_ath.c +=================================================================== +--- madwifi-trunk-r3776.orig/ath/if_ath.c 2008-07-17 03:04:02.000000000 +0200 ++++ madwifi-trunk-r3776/ath/if_ath.c 2008-07-17 03:06:03.000000000 +0200 +@@ -8865,14 +8865,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 new file mode 100644 index 0000000000..ca5ffdce4b --- /dev/null +++ b/package/madwifi/patches-r3776/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-r3776/315-scanlist.patch b/package/madwifi/patches-r3776/315-scanlist.patch new file mode 100644 index 0000000000..470a9bc8b2 --- /dev/null +++ b/package/madwifi/patches-r3776/315-scanlist.patch @@ -0,0 +1,892 @@ +Index: madwifi-trunk-r3776/net80211/ieee80211_scan_sta.c +=================================================================== +--- madwifi-trunk-r3776.orig/net80211/ieee80211_scan_sta.c 2008-07-17 00:21:29.000000000 +0200 ++++ madwifi-trunk-r3776/net80211/ieee80211_scan_sta.c 2008-07-17 03:10:02.000000000 +0200 +@@ -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, +Index: madwifi-trunk-r3776/net80211/ieee80211.c +=================================================================== +--- madwifi-trunk-r3776.orig/net80211/ieee80211.c 2008-07-17 02:56:18.000000000 +0200 ++++ madwifi-trunk-r3776/net80211/ieee80211.c 2008-07-17 03:07:53.000000000 +0200 +@@ -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; +Index: madwifi-trunk-r3776/net80211/_ieee80211.h +=================================================================== +--- madwifi-trunk-r3776.orig/net80211/_ieee80211.h 2008-07-17 00:21:29.000000000 +0200 ++++ madwifi-trunk-r3776/net80211/_ieee80211.h 2008-07-17 03:07:53.000000000 +0200 +@@ -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 +Index: madwifi-trunk-r3776/net80211/ieee80211_ioctl.h +=================================================================== +--- madwifi-trunk-r3776.orig/net80211/ieee80211_ioctl.h 2008-07-17 02:56:52.000000000 +0200 ++++ madwifi-trunk-r3776/net80211/ieee80211_ioctl.h 2008-07-17 03:07:53.000000000 +0200 +@@ -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, +Index: madwifi-trunk-r3776/net80211/ieee80211_scan_ap.c +=================================================================== +--- madwifi-trunk-r3776.orig/net80211/ieee80211_scan_ap.c 2008-07-17 02:20:50.000000000 +0200 ++++ madwifi-trunk-r3776/net80211/ieee80211_scan_ap.c 2008-07-17 03:09:25.000000000 +0200 +@@ -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 */ +@@ -834,13 +611,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) +Index: madwifi-trunk-r3776/net80211/ieee80211_scan.c +=================================================================== +--- madwifi-trunk-r3776.orig/net80211/ieee80211_scan.c 2008-07-17 00:49:51.000000000 +0200 ++++ madwifi-trunk-r3776/net80211/ieee80211_scan.c 2008-07-17 03:07:53.000000000 +0200 +@@ -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 +Index: madwifi-trunk-r3776/net80211/ieee80211_scan.h +=================================================================== +--- madwifi-trunk-r3776.orig/net80211/ieee80211_scan.h 2008-07-17 00:21:29.000000000 +0200 ++++ madwifi-trunk-r3776/net80211/ieee80211_scan.h 2008-07-17 03:07:53.000000000 +0200 +@@ -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_ */ +Index: madwifi-trunk-r3776/net80211/ieee80211_wireless.c +=================================================================== +--- madwifi-trunk-r3776.orig/net80211/ieee80211_wireless.c 2008-07-17 02:56:18.000000000 +0200 ++++ madwifi-trunk-r3776/net80211/ieee80211_wireless.c 2008-07-17 03:08:16.000000000 +0200 +@@ -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 new file mode 100644 index 0000000000..d14deac528 --- /dev/null +++ b/package/madwifi/patches-r3776/316-ani_fix.patch @@ -0,0 +1,740 @@ +Index: madwifi-trunk-r3776/ath/if_ath.c +=================================================================== +--- madwifi-trunk-r3776.orig/ath/if_ath.c 2008-07-17 03:06:03.000000000 +0200 ++++ madwifi-trunk-r3776/ath/if_ath.c 2008-07-17 03:53:09.000000000 +0200 +@@ -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 + */ +@@ -4248,8 +4240,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) +@@ -4265,6 +4256,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; +@@ -6809,8 +6802,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 " +@@ -8726,7 +8718,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; + } + +@@ -10632,8 +10623,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 +@@ -10695,6 +10688,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; +@@ -10933,30 +10968,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; +@@ -11028,9 +11046,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; +@@ -11412,6 +11435,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[] = { +Index: madwifi-trunk-r3776/ath/if_athvar.h +=================================================================== +--- madwifi-trunk-r3776.orig/ath/if_athvar.h 2008-07-17 03:04:02.000000000 +0200 ++++ madwifi-trunk-r3776/ath/if_athvar.h 2008-07-17 03:12:36.000000000 +0200 +@@ -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 */ +Index: madwifi-trunk-r3776/ath/if_ath_hal_extensions.h +=================================================================== +--- madwifi-trunk-r3776.orig/ath/if_ath_hal_extensions.h 2008-07-17 00:21:39.000000000 +0200 ++++ madwifi-trunk-r3776/ath/if_ath_hal_extensions.h 2008-07-17 03:50:03.000000000 +0200 +@@ -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); +Index: madwifi-trunk-r3776/ath/if_ath_hal.h +=================================================================== +--- madwifi-trunk-r3776.orig/ath/if_ath_hal.h 2008-07-17 00:53:20.000000000 +0200 ++++ madwifi-trunk-r3776/ath/if_ath_hal.h 2008-07-17 03:41:25.000000000 +0200 +@@ -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); +Index: madwifi-trunk-r3776/scripts/if_ath_hal_generator.pl +=================================================================== +--- madwifi-trunk-r3776.orig/scripts/if_ath_hal_generator.pl 2008-07-17 00:21:30.000000000 +0200 ++++ madwifi-trunk-r3776/scripts/if_ath_hal_generator.pl 2008-07-17 03:46:30.000000000 +0200 +@@ -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 new file mode 100644 index 0000000000..d22d00545d --- /dev/null +++ b/package/madwifi/patches-r3776/317-devid.patch @@ -0,0 +1,19 @@ +Index: madwifi-trunk-r3776/ath/if_ath_pci.c +=================================================================== +--- madwifi-trunk-r3776.orig/ath/if_ath_pci.c 2008-07-17 00:53:20.000000000 +0200 ++++ madwifi-trunk-r3776/ath/if_ath_pci.c 2008-07-17 03:54:06.000000000 +0200 +@@ -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 new file mode 100644 index 0000000000..4fcc5926f6 --- /dev/null +++ b/package/madwifi/patches-r3776/318-ifxmips_eeprom.patch @@ -0,0 +1,87 @@ +Index: madwifi-trunk-r3776/ath_hal/ah_os.c +=================================================================== +--- madwifi-trunk-r3776.orig/ath_hal/ah_os.c 2008-07-17 00:21:30.000000000 +0200 ++++ madwifi-trunk-r3776/ath_hal/ah_os.c 2008-07-17 04:00:18.000000000 +0200 +@@ -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 new file mode 100644 index 0000000000..38f39d51ec --- /dev/null +++ b/package/madwifi/patches-r3776/319-eap_auth_disassoc.patch @@ -0,0 +1,89 @@ +This patch causes STA mode interfaces to disassociate if transmission of assoc/auth +critical packets failed. + +Signed-off-by: Felix Fietkau + +Index: madwifi-trunk-r3776/ath/if_ath.c +=================================================================== +--- madwifi-trunk-r3776.orig/ath/if_ath.c 2008-07-17 03:53:09.000000000 +0200 ++++ madwifi-trunk-r3776/ath/if_ath.c 2008-07-17 04:00:42.000000000 +0200 +@@ -8272,6 +8272,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, +Index: madwifi-trunk-r3776/net80211/ieee80211_linux.c +=================================================================== +--- madwifi-trunk-r3776.orig/net80211/ieee80211_linux.c 2008-07-17 00:49:54.000000000 +0200 ++++ madwifi-trunk-r3776/net80211/ieee80211_linux.c 2008-07-17 04:01:27.000000000 +0200 +@@ -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); +Index: madwifi-trunk-r3776/net80211/ieee80211_linux.h +=================================================================== +--- madwifi-trunk-r3776.orig/net80211/ieee80211_linux.h 2008-07-17 00:53:20.000000000 +0200 ++++ madwifi-trunk-r3776/net80211/ieee80211_linux.h 2008-07-17 04:02:15.000000000 +0200 +@@ -411,6 +411,7 @@ + #define M_SKB_TRACKED 0x20 + void (*next_destructor)(struct sk_buff *skb); + #endif ++ u_int8_t auth_pkt; + }; + + struct __assert { +Index: madwifi-trunk-r3776/net80211/ieee80211_output.c +=================================================================== +--- madwifi-trunk-r3776.orig/net80211/ieee80211_output.c 2008-07-17 02:35:10.000000000 +0200 ++++ madwifi-trunk-r3776/net80211/ieee80211_output.c 2008-07-17 04:00:42.000000000 +0200 +@@ -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 new file mode 100644 index 0000000000..d5a70832f5 --- /dev/null +++ b/package/madwifi/patches-r3776/320-hidden_ssid.patch @@ -0,0 +1,40 @@ +This patch fixes the detection of hidden SSIDs as transmitted +by some cisco systems. + +Signed-off-by: Felix Fietkau + +Index: madwifi-trunk-r3776/net80211/ieee80211_scan_sta.c +=================================================================== +--- madwifi-trunk-r3776.orig/net80211/ieee80211_scan_sta.c 2008-07-17 03:10:02.000000000 +0200 ++++ madwifi-trunk-r3776/net80211/ieee80211_scan_sta.c 2008-07-17 04:02:41.000000000 +0200 +@@ -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 new file mode 100644 index 0000000000..5819193ed9 --- /dev/null +++ b/package/madwifi/patches-r3776/321-bgscan_rssi_thresh.patch @@ -0,0 +1,137 @@ +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 + +Index: madwifi-trunk-r3776/net80211/ieee80211_ioctl.h +=================================================================== +--- madwifi-trunk-r3776.orig/net80211/ieee80211_ioctl.h 2008-07-17 03:07:53.000000000 +0200 ++++ madwifi-trunk-r3776/net80211/ieee80211_ioctl.h 2008-07-17 04:03:30.000000000 +0200 +@@ -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) +Index: madwifi-trunk-r3776/net80211/ieee80211_var.h +=================================================================== +--- madwifi-trunk-r3776.orig/net80211/ieee80211_var.h 2008-07-17 02:56:18.000000000 +0200 ++++ madwifi-trunk-r3776/net80211/ieee80211_var.h 2008-07-17 04:03:07.000000000 +0200 +@@ -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) +Index: madwifi-trunk-r3776/net80211/ieee80211_wireless.c +=================================================================== +--- madwifi-trunk-r3776.orig/net80211/ieee80211_wireless.c 2008-07-17 03:08:16.000000000 +0200 ++++ madwifi-trunk-r3776/net80211/ieee80211_wireless.c 2008-07-17 04:03:07.000000000 +0200 +@@ -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, +Index: madwifi-trunk-r3776/net80211/ieee80211_input.c +=================================================================== +--- madwifi-trunk-r3776.orig/net80211/ieee80211_input.c 2008-07-17 02:56:18.000000000 +0200 ++++ madwifi-trunk-r3776/net80211/ieee80211_input.c 2008-07-17 04:03:07.000000000 +0200 +@@ -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: " +Index: madwifi-trunk-r3776/net80211/ieee80211_scan.c +=================================================================== +--- madwifi-trunk-r3776.orig/net80211/ieee80211_scan.c 2008-07-17 03:07:53.000000000 +0200 ++++ madwifi-trunk-r3776/net80211/ieee80211_scan.c 2008-07-17 04:03:07.000000000 +0200 +@@ -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 new file mode 100644 index 0000000000..f185dbfd25 --- /dev/null +++ b/package/madwifi/patches-r3776/322-ignore_broken_bssid.patch @@ -0,0 +1,20 @@ +Some misconfigured APs broadcast NULL BSSIDs, which can confuse the STA +Ignore those when scanning. + +Signed-off-by: Felix Fietkau + +Index: madwifi-trunk-r3776/net80211/ieee80211_scan_sta.c +=================================================================== +--- madwifi-trunk-r3776.orig/net80211/ieee80211_scan_sta.c 2008-07-17 04:02:41.000000000 +0200 ++++ madwifi-trunk-r3776/net80211/ieee80211_scan_sta.c 2008-07-17 04:03:54.000000000 +0200 +@@ -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 new file mode 100644 index 0000000000..ad75bff96f --- /dev/null +++ b/package/madwifi/patches-r3776/323-crash_fix.patch @@ -0,0 +1,23 @@ +Index: madwifi-trunk-r3776/net80211/ieee80211_node.c +=================================================================== +--- madwifi-trunk-r3776.orig/net80211/ieee80211_node.c 2008-07-17 02:56:18.000000000 +0200 ++++ madwifi-trunk-r3776/net80211/ieee80211_node.c 2008-07-17 04:05:43.000000000 +0200 +@@ -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 new file mode 100644 index 0000000000..12c5b913c5 --- /dev/null +++ b/package/madwifi/patches-r3776/324-reassoc.patch @@ -0,0 +1,33 @@ +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 + +Index: madwifi-trunk-r3776/net80211/ieee80211_node.c +=================================================================== +--- madwifi-trunk-r3776.orig/net80211/ieee80211_node.c 2008-07-17 04:05:43.000000000 +0200 ++++ madwifi-trunk-r3776/net80211/ieee80211_node.c 2008-07-17 04:05:55.000000000 +0200 +@@ -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 new file mode 100644 index 0000000000..e1f51b61b2 --- /dev/null +++ b/package/madwifi/patches-r3776/325-sta_node_leave.patch @@ -0,0 +1,61 @@ +Drop stale AP nodes from the client list when disconnecting. +Fixes some reassoc issues. + +Signed-off-by: Felix Fietkau + +Index: madwifi-trunk-r3776/net80211/ieee80211_proto.c +=================================================================== +--- madwifi-trunk-r3776.orig/net80211/ieee80211_proto.c 2008-07-17 02:20:51.000000000 +0200 ++++ madwifi-trunk-r3776/net80211/ieee80211_proto.c 2008-07-17 04:06:47.000000000 +0200 +@@ -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 new file mode 100644 index 0000000000..668c935547 --- /dev/null +++ b/package/madwifi/patches-r3776/326-bmiss_handling.patch @@ -0,0 +1,108 @@ +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 + +Index: madwifi-trunk-r3776/net80211/ieee80211_input.c +=================================================================== +--- madwifi-trunk-r3776.orig/net80211/ieee80211_input.c 2008-07-17 04:03:07.000000000 +0200 ++++ madwifi-trunk-r3776/net80211/ieee80211_input.c 2008-07-17 04:06:33.000000000 +0200 +@@ -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 +Index: madwifi-trunk-r3776/net80211/ieee80211_proto.c +=================================================================== +--- madwifi-trunk-r3776.orig/net80211/ieee80211_proto.c 2008-07-17 04:06:18.000000000 +0200 ++++ madwifi-trunk-r3776/net80211/ieee80211_proto.c 2008-07-17 04:06:33.000000000 +0200 +@@ -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); + } + +Index: madwifi-trunk-r3776/net80211/ieee80211_var.h +=================================================================== +--- madwifi-trunk-r3776.orig/net80211/ieee80211_var.h 2008-07-17 04:03:07.000000000 +0200 ++++ madwifi-trunk-r3776/net80211/ieee80211_var.h 2008-07-17 04:06:33.000000000 +0200 +@@ -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 new file mode 100644 index 0000000000..1ce8e2a718 --- /dev/null +++ b/package/madwifi/patches-r3776/327-rssi_disconnect.patch @@ -0,0 +1,99 @@ +Add an optional threshold for low-rssi disconnection. This can be useful +when letting wpa_supplicant control roaming. + +Signed-off-by: Felix Fietkau + +Index: madwifi-trunk-r3776/net80211/ieee80211_ioctl.h +=================================================================== +--- madwifi-trunk-r3776.orig/net80211/ieee80211_ioctl.h 2008-07-17 04:03:30.000000000 +0200 ++++ madwifi-trunk-r3776/net80211/ieee80211_ioctl.h 2008-07-17 04:07:29.000000000 +0200 +@@ -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) +Index: madwifi-trunk-r3776/net80211/ieee80211_wireless.c +=================================================================== +--- madwifi-trunk-r3776.orig/net80211/ieee80211_wireless.c 2008-07-17 04:03:07.000000000 +0200 ++++ madwifi-trunk-r3776/net80211/ieee80211_wireless.c 2008-07-17 04:07:56.000000000 +0200 +@@ -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, +Index: madwifi-trunk-r3776/net80211/ieee80211_input.c +=================================================================== +--- madwifi-trunk-r3776.orig/net80211/ieee80211_input.c 2008-07-17 04:07:08.000000000 +0200 ++++ madwifi-trunk-r3776/net80211/ieee80211_input.c 2008-07-17 04:09:03.000000000 +0200 +@@ -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)) && +Index: madwifi-trunk-r3776/net80211/ieee80211_var.h +=================================================================== +--- madwifi-trunk-r3776.orig/net80211/ieee80211_var.h 2008-07-17 04:07:08.000000000 +0200 ++++ madwifi-trunk-r3776/net80211/ieee80211_var.h 2008-07-17 04:07:10.000000000 +0200 +@@ -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 new file mode 100644 index 0000000000..18d648c613 --- /dev/null +++ b/package/madwifi/patches-r3776/328-memory_alloc.patch @@ -0,0 +1,13 @@ +Index: madwifi-trunk-r3776/ath/if_ath.c +=================================================================== +--- madwifi-trunk-r3776.orig/ath/if_ath.c 2008-07-17 04:00:42.000000000 +0200 ++++ madwifi-trunk-r3776/ath/if_ath.c 2008-07-17 04:11:45.000000000 +0200 +@@ -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 new file mode 100644 index 0000000000..2c718c06e6 --- /dev/null +++ b/package/madwifi/patches-r3776/329-turbo_chansearch.patch @@ -0,0 +1,12 @@ +Index: madwifi-trunk-r3776/net80211/ieee80211.c +=================================================================== +--- madwifi-trunk-r3776.orig/net80211/ieee80211.c 2008-07-17 03:07:53.000000000 +0200 ++++ madwifi-trunk-r3776/net80211/ieee80211.c 2008-07-17 04:12:08.000000000 +0200 +@@ -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 new file mode 100644 index 0000000000..e2e502dfbf --- /dev/null +++ b/package/madwifi/patches-r3776/330-bstuck_thresh.patch @@ -0,0 +1,54 @@ +Index: madwifi-trunk-r3776/ath/if_ath.c +=================================================================== +--- madwifi-trunk-r3776.orig/ath/if_ath.c 2008-07-17 04:11:45.000000000 +0200 ++++ madwifi-trunk-r3776/ath/if_ath.c 2008-07-17 04:12:51.000000000 +0200 +@@ -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"); +@@ -5238,7 +5242,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; + } +@@ -5409,7 +5413,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 new file mode 100644 index 0000000000..968f37d71c --- /dev/null +++ b/package/madwifi/patches-r3776/331-linux24_fix.patch @@ -0,0 +1,17 @@ +Index: madwifi-trunk-r3776/ath_hal/Makefile +=================================================================== +--- madwifi-trunk-r3776.orig/ath_hal/Makefile 2008-07-17 00:21:30.000000000 +0200 ++++ madwifi-trunk-r3776/ath_hal/Makefile 2008-07-17 04:13:34.000000000 +0200 +@@ -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 new file mode 100644 index 0000000000..2e2f919538 --- /dev/null +++ b/package/madwifi/patches-r3776/332-retransmit_check.patch @@ -0,0 +1,26 @@ +Index: madwifi-trunk-r3776/net80211/ieee80211.h +=================================================================== +--- madwifi-trunk-r3776.orig/net80211/ieee80211.h 2008-07-17 04:14:08.000000000 +0200 ++++ madwifi-trunk-r3776/net80211/ieee80211.h 2008-07-17 04:14:13.000000000 +0200 +@@ -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 +Index: madwifi-trunk-r3776/net80211/ieee80211_input.c +=================================================================== +--- madwifi-trunk-r3776.orig/net80211/ieee80211_input.c 2008-07-17 04:14:08.000000000 +0200 ++++ madwifi-trunk-r3776/net80211/ieee80211_input.c 2008-07-17 04:14:13.000000000 +0200 +@@ -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", -- cgit v1.2.3