summaryrefslogtreecommitdiff
path: root/package
diff options
context:
space:
mode:
Diffstat (limited to 'package')
-rw-r--r--package/madwifi/Config.in41
-rw-r--r--package/madwifi/Makefile19
-rw-r--r--package/madwifi/patches/446-single_module.patch778
3 files changed, 801 insertions, 37 deletions
diff --git a/package/madwifi/Config.in b/package/madwifi/Config.in
index 23cc433..802e52a 100644
--- a/package/madwifi/Config.in
+++ b/package/madwifi/Config.in
@@ -30,6 +30,15 @@ config MADWIFI_UPSTREAM
endchoice
+config MADWIFI_SINGLE_MODULE
+ bool "Combine driver and net80211 into a single module"
+ depends on PACKAGE_kmod-madwifi
+ default y
+ help
+ This option combines all driver and stack related code (except for HAL)
+ into a single module, thus saving space and removing unnecessary kernel
+ exports
+
choice
prompt "Rate control algorithm selection"
depends on PACKAGE_kmod-madwifi
@@ -46,38 +55,6 @@ config MADWIFI_RCA_MINSTREL
always wander in directions where he/she feels he/she will get paid
the best for his/her work.
-config MADWIFI_RCA_ONOE
- bool "Use the Onoe rate control algorithm"
- help
- Onoe is a credit based RCA where the value of the credit is determined
- by the frequency of successful, erroneous and retransmissions
- accumulated during a fixed invocation period of 1000 ms. If less than
- 10% of the packets need to be retransmitted at a particular rate, Onoe
- keeps increasing its credit point till the threshold value of 10 is
- reached. At this point, the current transmission rate is increased to
- the next available higher rate and the process repeated with credit
- score of zero. Similar logic holds for deducting the credit score and
- moving to a lower bit-rate for failed packet
- transmission/retransmission attempts. However, once a bit-rate has
- been marked as failure in the previous attempt, Onoe will not attempt
- to select that bit-rate until 10 seconds have elapsed since the last
- attempt. Due to the manner in which it operates, Onoe is conservative
- in rate selection and is less sensitive to individual packet failure.
-
-config MADWIFI_RCA_AMRR
- bool "Use the AMRR rate control algorithm"
- help
- AMRR uses Binary Exponential Backoff (BEB) technique to adapt the
- length (threshold) of the sampling period used to change the values of
- bit-rate and transmission count parameters. It uses probe packets and
- depending on their transmission status adaptively changes the threshold
- value. The adaptation mechanism ensures fewer failed
- transmission/retransmission and higher throughput by not switching to a
- higher rate as specified by the backoff mechanism. In addition to this,
- the AMRR employs heuristics to capture the short-term variations of the
- channel by judiciously setting the rate and transmission count
- parameters.
-
config MADWIFI_RCA_SAMPLERATE
bool "Use the SampleRate rate control algorithm"
help
diff --git a/package/madwifi/Makefile b/package/madwifi/Makefile
index 250c6fd..632b77f 100644
--- a/package/madwifi/Makefile
+++ b/package/madwifi/Makefile
@@ -124,6 +124,9 @@ ifdef CONFIG_MADWIFI_RCA_SAMPLERATE
RATE_CONTROL:=sample
endif
+ifneq ($(CONFIG_MADWIFI_SINGLE_MODULE),)
+MADWIFI_FILES:= $(PKG_BUILD_DIR)/ath_hal/ath_hal.$(LINUX_KMOD_SUFFIX)
+else
MADWIFI_FILES:= \
$(PKG_BUILD_DIR)/net80211/wlan.$(LINUX_KMOD_SUFFIX) \
$(PKG_BUILD_DIR)/net80211/wlan_scan_ap.$(LINUX_KMOD_SUFFIX) \
@@ -134,9 +137,13 @@ MADWIFI_FILES:= \
$(PKG_BUILD_DIR)/net80211/wlan_ccmp.$(LINUX_KMOD_SUFFIX) \
$(PKG_BUILD_DIR)/net80211/wlan_tkip.$(LINUX_KMOD_SUFFIX) \
$(PKG_BUILD_DIR)/net80211/wlan_wep.$(LINUX_KMOD_SUFFIX) \
- $(PKG_BUILD_DIR)/net80211/wlan_xauth.$(LINUX_KMOD_SUFFIX) \
+ $(PKG_BUILD_DIR)/net80211/wlan_xauth.$(LINUX_KMOD_SUFFIX)
+endif
-MADWIFI_AUTOLOAD:= \
+ifneq ($(CONFIG_MADWIFI_SINGLE_MODULE),)
+ MADWIFI_AUTOLOAD:= ath_hal
+else
+ MADWIFI_AUTOLOAD:= \
wlan \
wlan_scan_ap \
wlan_scan_sta \
@@ -146,7 +153,8 @@ MADWIFI_AUTOLOAD:= \
wlan_ccmp \
wlan_tkip \
wlan_wep \
- wlan_xauth \
+ wlan_xauth
+endif
ifeq ($(findstring AHB,$(BUS)),AHB)
MADWIFI_FILES+= $(PKG_BUILD_DIR)/ath/ath_ahb.$(LINUX_KMOD_SUFFIX)
@@ -202,14 +210,15 @@ MAKE_ARGS:= \
TOOLPATH="$(KERNEL_CROSS)" \
KERNELPATH="$(LINUX_DIR)" \
LDOPTS="--no-warn-mismatch " \
- ATH_RATE="ath_rate/$(RATE_CONTROL)" \
+ ATH_RATE="$(RATE_CONTROL)" \
ATH_CAP_SUPERG_COMP="$(COMPRESSION)" \
DO_MULTI=1 \
+ SINGLE_MODULE=$(if $(CONFIG_MADWIFI_SINGLE_MODULE),1) \
INCS="$(MADWIFI_INC)" \
$(if $(CONFIG_MADWIFI_DEBUG),,DEBUG=) WARNINGS="-Wno-unused"
MAKE_VARS:= \
- COPTS="-DCONFIG_ATHEROS_RATE_DEFAULT='\"$(RATE_CONTROL)\"' -DATH_REVERSE_ENGINEERING=1" \
+ COPTS="-DATH_REVERSE_ENGINEERING=1" \
ifeq ($(CONFIG_MADWIFI_UPSTREAM),)
define Build/Prepare/HAL
diff --git a/package/madwifi/patches/446-single_module.patch b/package/madwifi/patches/446-single_module.patch
new file mode 100644
index 0000000..2ad9af8
--- /dev/null
+++ b/package/madwifi/patches/446-single_module.patch
@@ -0,0 +1,778 @@
+--- a/ath/Makefile
++++ b/ath/Makefile
+@@ -41,7 +41,6 @@
+ #
+
+ obj := $(firstword $(obj) $(SUBDIRS) .)
+-TOP = $(obj)/..
+
+ ifeq ($(strip $(BUS)),AHB)
+ BUSNAME=ahb
+@@ -57,7 +56,24 @@ COPTS += -DDFS_DOMAIN_ETSI -DDFS_DOMAIN_
+ include $(TOP)/Makefile.inc
+
+ obj-m += ath_$(BUSNAME).o
+-ath_$(BUSNAME)-objs := if_ath.o if_ath_radar.o if_ath_$(BUSNAME).o
++ath_objs := if_ath.o if_ath_radar.o if_ath_$(BUSNAME).o
++ath_$(BUSNAME)-objs := $(ath_objs)
++
++ifneq ($(SINGLE_MODULE),)
++include $(TOP)/net80211/Makefile
++include $(TOP)/ath_rate/sample/Makefile
++include $(TOP)/ath_rate/minstrel/Makefile
++RC_DECLARE=$(foreach R,$(ATH_RATE),extern void ath_rate_$(R)_init(void);extern void ath_rate_$(R)_exit(void);)
++RC_INIT=$(foreach R,$(ATH_RATE),ath_rate_$(R)_init();)
++RC_EXIT=$(foreach R,$(ATH_RATE),ath_rate_$(R)_exit();)
++
++ath_$(BUSNAME)-objs += $(patsubst %,../net80211/%,$(wlan-objs) $(foreach var,wep tkip ccmp acl xauth scan_sta scan_ap,$(wlan_$(var)-objs))) $(foreach RC,$(ATH_RATE),$(patsubst %,../ath_rate/$(RC)/%,$(ath_rate_$(RC)-objs)))
++ifdef LINUX24
++ ath_$(BUSNAME)-linkobjs := $(ath_objs) $(wlan-objs) $(foreach var,wep tkip ccmp acl xauth scan_sta scan_ap,$(wlan_$(var)-objs)) $(foreach RC,$(ATH_RATE),$(ath_rate_$(RC)-objs))
++endif
++
++EXTRA_CFLAGS += -DSINGLE_MODULE -DRC_INIT="$(RC_INIT)" -DRC_EXIT="$(RC_EXIT)" -DRC_DECLARE="$(RC_DECLARE)"
++endif
+
+ INCS += -I$(TOP) -I$(ATH_HAL) -I$(HAL) -I$(WLAN)
+
+@@ -72,13 +88,8 @@ install:
+ test -d $(DESTDIR)/$(KMODPATH) || mkdir -p $(DESTDIR)/$(KMODPATH)
+ install -m 0644 ath_$(BUSNAME).$(KMODSUF) $(DESTDIR)/$(KMODPATH)
+
+-clean:
+- rm -f *~ *.o *.ko *.mod.c .*.cmd
+- rm -f .depend .version .*.o.flags .*.o.d
+- rm -rf .tmp_versions
+-
+ ath_$(BUSNAME).o: $(ath_$(BUSNAME)-objs)
+- $(LD) $(LDOPTS) -o ath_$(BUSNAME).$(KMODSUF) -r $(ath_$(BUSNAME)-objs)
++ $(LD) $(LDOPTS) -o ath_$(BUSNAME).$(KMODSUF) -r $(if $(ath_$(BUSNAME)-linkobjs),$(ath_$(BUSNAME)-linkobjs),$(ath_$(BUSNAME)-objs))
+
+ if_ath_hal.h: $(HAL)/ah.h
+ $(TOP)/scripts/if_ath_hal_generator.pl $< $@
+--- a/net80211/ieee80211_acl.c
++++ b/net80211/ieee80211_acl.c
+@@ -281,16 +281,6 @@ acl_getpolicy(struct ieee80211vap *vap)
+ return as->as_policy;
+ }
+
+-/*
+- * Module glue.
+- */
+-
+-MODULE_AUTHOR("Errno Consulting, Sam Leffler");
+-MODULE_DESCRIPTION("802.11 wireless support: MAC-based ACL policy");
+-#ifdef MODULE_LICENSE
+-MODULE_LICENSE("Dual BSD/GPL");
+-#endif
+-
+ static const struct ieee80211_aclator mac = {
+ .iac_name = "mac",
+ .iac_attach = acl_attach,
+@@ -303,6 +293,18 @@ static const struct ieee80211_aclator ma
+ .iac_getpolicy = acl_getpolicy,
+ };
+
++#include "module.h"
++/*
++ * Module glue.
++ */
++
++MODULE_AUTHOR("Errno Consulting, Sam Leffler");
++MODULE_DESCRIPTION("802.11 wireless support: MAC-based ACL policy");
++#ifdef MODULE_LICENSE
++MODULE_LICENSE("Dual BSD/GPL");
++#endif
++
++
+ static int __init
+ init_ieee80211_acl(void)
+ {
+--- a/net80211/ieee80211_crypto_ccmp.c
++++ b/net80211/ieee80211_crypto_ccmp.c
+@@ -686,6 +686,8 @@ ccmp_decrypt(struct ieee80211_key *key,
+ }
+ #undef CCMP_DECRYPT
+
++#include "module.h"
++
+ /*
+ * Module glue.
+ */
+--- a/net80211/ieee80211_crypto_tkip.c
++++ b/net80211/ieee80211_crypto_tkip.c
+@@ -1046,6 +1046,8 @@ tkip_decrypt(struct tkip_ctx *ctx, struc
+ return 1;
+ }
+
++#include "module.h"
++
+ /*
+ * Module glue.
+ */
+--- a/net80211/ieee80211_crypto_wep.c
++++ b/net80211/ieee80211_crypto_wep.c
+@@ -497,6 +497,8 @@ wep_decrypt(struct ieee80211_key *key, s
+ * Module glue.
+ */
+
++#include "module.h"
++
+ MODULE_AUTHOR("Errno Consulting, Sam Leffler");
+ MODULE_DESCRIPTION("802.11 wireless support: WEP cipher");
+ #ifdef MODULE_LICENSE
+--- a/net80211/ieee80211_linux.c
++++ b/net80211/ieee80211_linux.c
+@@ -1015,6 +1015,10 @@ static struct notifier_block ieee80211_e
+ static char *version = RELEASE_VERSION;
+ static char *dev_info = "wlan";
+
++extern void ieee80211_auth_setup(void);
++
++#include "module.h"
++
+ MODULE_AUTHOR("Errno Consulting, Sam Leffler");
+ MODULE_DESCRIPTION("802.11 wireless LAN protocol support");
+ #ifdef MODULE_VERSION
+@@ -1024,8 +1028,6 @@ MODULE_VERSION(RELEASE_VERSION);
+ MODULE_LICENSE("Dual BSD/GPL");
+ #endif
+
+-extern void ieee80211_auth_setup(void);
+-
+ static int __init
+ init_wlan(void)
+ {
+--- a/net80211/ieee80211_scan_ap.c
++++ b/net80211/ieee80211_scan_ap.c
+@@ -763,15 +763,6 @@ action_tasklet(IEEE80211_TQUEUE_ARG data
+ (*ss->ss_ops->scan_default)(vap, &as->as_selbss);
+ }
+
+-/*
+- * Module glue.
+- */
+-MODULE_AUTHOR("Errno Consulting, Sam Leffler");
+-MODULE_DESCRIPTION("802.11 wireless support: default ap scanner");
+-#ifdef MODULE_LICENSE
+-MODULE_LICENSE("Dual BSD/GPL");
+-#endif
+-
+ static const struct ieee80211_scanner ap_default = {
+ .scan_name = "default",
+ .scan_attach = ap_attach,
+@@ -789,6 +780,16 @@ static const struct ieee80211_scanner ap
+ .scan_default = ap_default_action,
+ };
+
++#include "module.h"
++
++/*
++ * Module glue.
++ */
++MODULE_AUTHOR("Errno Consulting, Sam Leffler");
++MODULE_DESCRIPTION("802.11 wireless support: default ap scanner");
++#ifdef MODULE_LICENSE
++MODULE_LICENSE("Dual BSD/GPL");
++#endif
+
+ static int __init
+ init_scanner_ap(void)
+--- a/net80211/ieee80211_scan_sta.c
++++ b/net80211/ieee80211_scan_sta.c
+@@ -1208,6 +1208,8 @@ action_tasklet(IEEE80211_TQUEUE_ARG data
+ ieee80211_start_scan(vap, ss->ss_flags, ss->ss_duration, ss->ss_nssid, ss->ss_ssid);
+ }
+
++#include "module.h"
++
+ /*
+ * Module glue.
+ */
+@@ -1217,6 +1219,7 @@ MODULE_DESCRIPTION("802.11 wireless supp
+ MODULE_LICENSE("Dual BSD/GPL");
+ #endif
+
++
+ static int __init
+ init_scanner_sta(void)
+ {
+--- a/net80211/ieee80211_xauth.c
++++ b/net80211/ieee80211_xauth.c
+@@ -65,15 +65,6 @@
+ #include <net80211/ieee80211_var.h>
+
+ /*
+- * Module glue.
+- */
+-MODULE_AUTHOR("Errno Consulting, Sam Leffler");
+-MODULE_DESCRIPTION("802.11 wireless support: external (user mode) authenticator");
+-#ifdef MODULE_LICENSE
+-MODULE_LICENSE("Dual BSD/GPL");
+-#endif
+-
+-/*
+ * One module handles everything for now. May want
+ * to split things up for embedded applications.
+ */
+@@ -85,6 +76,18 @@ static const struct ieee80211_authentica
+ .ia_node_leave = NULL,
+ };
+
++#include "module.h"
++
++/*
++ * Module glue.
++ */
++MODULE_AUTHOR("Errno Consulting, Sam Leffler");
++MODULE_DESCRIPTION("802.11 wireless support: external (user mode) authenticator");
++#ifdef MODULE_LICENSE
++MODULE_LICENSE("Dual BSD/GPL");
++#endif
++
++
+ static int __init
+ init_ieee80211_xauth(void)
+ {
+--- a/net80211/Makefile
++++ b/net80211/Makefile
+@@ -40,7 +40,11 @@
+ # Makefile for the 802.11 WLAN modules.
+ #
+ obj := $(firstword $(obj) $(SUBDIRS) .)
+-TOP = $(obj)/..
++
++include $(TOP)/Makefile.inc
++
++ifeq ($(SINGLE_MODULE),)
++
+ #
+ # There is one authenticator mechanism: an in-kernel implementation
+ # (wlan_xauth).
+@@ -59,29 +63,8 @@ MOD_INSTALL := wlan.o wlan_wep.o wlan_tk
+
+ obj-m += $(MOD_INSTALL)
+
+-wlan-objs := if_media.o \
+- ieee80211_skb.o \
+- ieee80211.o ieee80211_beacon.o ieee80211_crypto.o \
+- ieee80211_crypto_none.o ieee80211_input.o ieee80211_node.o \
+- ieee80211_output.o ieee80211_power.o ieee80211_proto.o \
+- ieee80211_scan.o ieee80211_wireless.o ieee80211_linux.o \
+- ieee80211_monitor.o ieee80211_rate.o
+-wlan_wep-objs := ieee80211_crypto_wep.o
+-wlan_tkip-objs := ieee80211_crypto_tkip.o
+-wlan_ccmp-objs := ieee80211_crypto_ccmp.o
+-wlan_acl-objs := ieee80211_acl.o
+-wlan_xauth-objs := ieee80211_xauth.o
+-wlan_scan_sta-objs :=ieee80211_scan_sta.o
+-wlan_scan_ap-objs := ieee80211_scan_ap.o
+-
+-include $(TOP)/Makefile.inc
+-
+ INCS += -I$(TOP) -I$(ATH_HAL) -I$(HAL)
+
+-EXTRA_CFLAGS+=$(INCS) $(COPTS) -DOPT_AH_H=\"public/$(TARGET).opt_ah.h\"
+-
+--include $(TOPDIR)/Rules.make
+-
+ all:
+ $(MAKE) -C $(KERNELPATH) SUBDIRS=$(shell pwd) modules
+
+@@ -108,8 +91,28 @@ install:
+ f=`basename $$i .o`; \
+ install -m 0644 $$f.$(KMODSUF) $(DESTDIR)/$(KMODPATH); \
+ done
++else
++all:
++endif
++
++wlan-objs := if_media.o \
++ ieee80211_skb.o \
++ ieee80211.o ieee80211_beacon.o ieee80211_crypto.o \
++ ieee80211_crypto_none.o ieee80211_input.o ieee80211_node.o \
++ ieee80211_output.o ieee80211_power.o ieee80211_proto.o \
++ ieee80211_scan.o ieee80211_wireless.o ieee80211_linux.o \
++ ieee80211_monitor.o ieee80211_rate.o
++wlan_wep-objs := ieee80211_crypto_wep.o
++wlan_tkip-objs := ieee80211_crypto_tkip.o
++wlan_ccmp-objs := ieee80211_crypto_ccmp.o
++wlan_acl-objs := ieee80211_acl.o
++wlan_xauth-objs := ieee80211_xauth.o
++wlan_scan_sta-objs :=ieee80211_scan_sta.o
++wlan_scan_ap-objs := ieee80211_scan_ap.o
++
++
++EXTRA_CFLAGS+=$(INCS) $(COPTS) -DOPT_AH_H=\"public/$(TARGET).opt_ah.h\"
++
++-include $(TOPDIR)/Rules.make
++
+
+-clean:
+- -rm -f *~ *.o *.ko *.mod.c
+- -rm -f .depend .version .*.o.flags .*.o.d .*.o.cmd .*.ko.cmd
+- -rm -rf .tmp_versions
+--- /dev/null
++++ b/net80211/module.h
+@@ -0,0 +1,19 @@
++#ifdef SINGLE_MODULE
++
++#undef static
++#define static
++#undef module_init
++#undef module_exit
++#define module_init(...)
++#define module_exit(...)
++
++#undef MODULE_AUTHOR
++#undef MODULE_LICENSE
++#undef MODULE_VERSION
++#undef MODULE_DESCRIPTION
++#define MODULE_AUTHOR(...)
++#define MODULE_LICENSE(...)
++#define MODULE_VERSION(...)
++#define MODULE_DESCRIPTION(...)
++
++#endif
+--- a/ath/if_ath.c
++++ b/ath/if_ath.c
+@@ -13777,3 +13777,5 @@ cleanup_ath_buf(struct ath_softc *sc, st
+ return bf;
+ }
+
++
++
+--- a/net80211/ieee80211.c
++++ b/net80211/ieee80211.c
+@@ -42,6 +42,7 @@
+ #include <linux/config.h>
+ #endif
+ #include <linux/version.h>
++#include <linux/init.h>
+ #include <linux/module.h>
+ #include <linux/skbuff.h>
+ #include <linux/netdevice.h>
+@@ -2014,3 +2015,65 @@ ieee80211_build_sc_ie(struct ieee80211co
+ int ath_debug_global = 0;
+ EXPORT_SYMBOL(ath_debug_global);
+
++#ifdef SINGLE_MODULE
++typedef void (*initfunc)(void);
++
++extern void init_ieee80211_acl(void);
++extern void init_crypto_ccmp(void);
++extern void init_crypto_tkip(void);
++extern void init_crypto_wep(void);
++extern void init_wlan(void);
++extern void init_scanner_ap(void);
++extern void init_scanner_sta(void);
++extern void init_ieee80211_xauth(void);
++
++extern void exit_ieee80211_acl(void);
++extern void exit_crypto_ccmp(void);
++extern void exit_crypto_tkip(void);
++extern void exit_crypto_wep(void);
++extern void exit_wlan(void);
++extern void exit_scanner_ap(void);
++extern void exit_scanner_sta(void);
++extern void exit_ieee80211_xauth(void);
++
++static __initdata initfunc net80211_init[] = {
++ init_wlan,
++ init_ieee80211_acl,
++ init_crypto_ccmp,
++ init_crypto_tkip,
++ init_crypto_wep,
++ init_ieee80211_xauth,
++ init_scanner_ap,
++ init_scanner_sta,
++};
++
++static __exitdata initfunc net80211_exit[] = {
++ exit_crypto_ccmp,
++ exit_crypto_tkip,
++ exit_crypto_wep,
++ exit_scanner_ap,
++ exit_scanner_sta,
++ exit_ieee80211_xauth,
++ exit_ieee80211_acl,
++ exit_wlan,
++};
++
++void net80211_init_module(void)
++{
++ int i;
++ for (i = 0; i < sizeof(net80211_init)/sizeof(net80211_init[0]); i++) {
++ if (net80211_init[i])
++ net80211_init[i]();
++ }
++}
++
++void net80211_exit_module(void)
++{
++ int i;
++ for (i = 0; i < sizeof(net80211_exit)/sizeof(net80211_exit[0]); i++) {
++ if (net80211_exit[i])
++ net80211_exit[i]();
++ }
++}
++
++#endif
+--- a/ath/if_ath_ahb.c
++++ b/ath/if_ath_ahb.c
+@@ -447,10 +447,18 @@ MODULE_SUPPORTED_DEVICE("Atheros WLAN ca
+ MODULE_LICENSE("Dual BSD/GPL");
+ #endif
+
++#ifdef SINGLE_MODULE
++RC_DECLARE
++#endif
++
+ static int __init
+ init_ath_ahb(void)
+ {
+ printk(KERN_INFO "%s: %s\n", dev_info, version);
++#ifdef SINGLE_MODULE
++ net80211_init_module();
++ RC_INIT
++#endif
+ platform_driver_register(&ahb_wmac_driver);
+ ath_sysctl_register();
+
+@@ -463,6 +471,10 @@ exit_ath_ahb(void)
+ {
+ ath_sysctl_unregister();
+ platform_driver_unregister(&ahb_wmac_driver);
++#ifdef SINGLE_MODULE
++ RC_EXIT
++ net80211_exit_module();
++#endif
+ printk(KERN_INFO "%s: driver unloaded\n", dev_info);
+ }
+ module_exit(exit_ath_ahb);
+--- a/ath/if_ath_pci.c
++++ b/ath/if_ath_pci.c
+@@ -415,11 +415,19 @@ MODULE_SUPPORTED_DEVICE("Atheros WLAN ca
+ MODULE_LICENSE("Dual BSD/GPL");
+ #endif
+
++#ifdef SINGLE_MODULE
++RC_DECLARE
++#endif
++
+ static int __init
+ init_ath_pci(void)
+ {
+ printk(KERN_INFO "%s: %s\n", dev_info, version);
+
++#ifdef SINGLE_MODULE
++ net80211_init_module();
++ RC_INIT
++#endif
+ if (pci_register_driver(&ath_pci_driver) < 0) {
+ printk(KERN_ERR "%s: No devices found, driver not installed.\n", dev_info);
+ return (-ENODEV);
+@@ -434,6 +442,10 @@ exit_ath_pci(void)
+ {
+ ath_sysctl_unregister();
+ pci_unregister_driver(&ath_pci_driver);
++#ifdef SINGLE_MODULE
++ RC_EXIT
++ net80211_exit_module();
++#endif
+
+ printk(KERN_INFO "%s: driver unloaded\n", dev_info);
+ }
+--- a/ath_rate/minstrel/Makefile
++++ b/ath_rate/minstrel/Makefile
+@@ -39,9 +39,7 @@
+ # Makefile for the Atheros Rate Control Support.
+ #
+ obj := $(firstword $(obj) $(SUBDIRS) .)
+-TOP = $(obj)/../..
+
+-obj-m += ath_rate_minstrel.o
+ ath_rate_minstrel-objs := minstrel.o
+
+ include $(TOP)/Makefile.inc
+@@ -50,6 +48,10 @@ INCS += -I$(TOP) -I$(ATH) -I$(ATH_HAL) -
+
+ EXTRA_CFLAGS+= $(INCS) $(COPTS) -DOPT_AH_H=\"public/$(TARGET).opt_ah.h\"
+
++ifeq ($(SINGLE_MODULE),)
++
++obj-m += ath_rate_minstrel.o
++
+ -include $(TOPDIR)/Rules.make
+
+ all:
+@@ -59,10 +61,9 @@ install:
+ test -d $(DESTDIR)/$(KMODPATH) || mkdir -p $(DESTDIR)/$(KMODPATH)
+ install -m 0644 ath_rate_minstrel.$(KMODSUF) $(DESTDIR)/$(KMODPATH)
+
+-clean:
+- -rm -f *~ *.o *.ko *.mod.c
+- -rm -f .depend .version .*.o.flags .*.o.d .*.o.cmd .*.ko.cmd
+- -rm -rf .tmp_versions
+-
+ ath_rate_minstrel.o: $(ath_rate_minstrel-objs)
+ $(LD) $(LDOPTS) -o ath_rate_minstrel.$(KMODSUF) -r $(ath_rate_minstrel-objs)
++else
++all:
++install:
++endif
+--- a/ath_rate/minstrel/minstrel.c
++++ b/ath_rate/minstrel/minstrel.c
+@@ -945,6 +945,8 @@ static struct ieee80211_rate_ops ath_rat
+ .dynamic_proc_register = ath_rate_dynamic_proc_register,
+ };
+
++#include <net80211/module.h>
++
+ MODULE_AUTHOR("John Bicket/Derek Smithies");
+ MODULE_DESCRIPTION("Minstrel Rate bit-rate selection algorithm for Atheros devices");
+ #ifdef MODULE_VERSION
+--- a/net80211/ieee80211_var.h
++++ b/net80211/ieee80211_var.h
+@@ -47,6 +47,7 @@
+ #include <net80211/ieee80211_power.h>
+ #include <net80211/ieee80211_proto.h>
+ #include <net80211/ieee80211_scan.h>
++#include "symbol.h"
+
+ /* NB:
+ * - Atheros chips use 6 bits when power is specified in whole dBm units, with
+@@ -741,6 +742,8 @@ void ieee80211_dfs_action(struct ieee802
+ void ieee80211_expire_channel_excl_restrictions(struct ieee80211com *);
+ void ieee80211_setpuregbasicrates(struct ieee80211_rateset *rs);
+ int ieee80211_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd);
++void net80211_init_module(void);
++void net80211_exit_module(void);
+
+ /*
+ * Iterate through ic_channels to enumerate all distinct ic_ieee channel numbers.
+--- a/net80211/ieee80211_linux.h
++++ b/net80211/ieee80211_linux.h
+@@ -521,7 +521,10 @@ extern struct sk_buff * ieee80211_getmgt
+ #define IF_DRAIN(_q) skb_queue_drain(_q)
+ extern void skb_queue_drain(struct sk_buff_head *q);
+
+-#ifndef __MOD_INC_USE_COUNT
++#ifdef SINGLE_MODULE
++#define _MOD_DEC_USE(_m) do {} while(0)
++#define _MOD_INC_USE(_m, _err) do {} while(0)
++#elif !defined(__MOD_INC_USE_COUNT)
+ #define _MOD_INC_USE(_m, _err) \
+ if (!try_module_get(_m)) { \
+ printk(KERN_WARNING "%s: try_module_get failed\n", \
+--- a/ath_rate/sample/Makefile
++++ b/ath_rate/sample/Makefile
+@@ -39,9 +39,7 @@
+ # Makefile for the Atheros Rate Control Support.
+ #
+ obj := $(firstword $(obj) $(SUBDIRS) .)
+-TOP = $(obj)/../..
+
+-obj-m += ath_rate_sample.o
+ ath_rate_sample-objs := sample.o
+
+ include $(TOP)/Makefile.inc
+@@ -50,6 +48,9 @@ INCS += -I$(TOP) -I$(ATH) -I$(ATH_HAL) -
+
+ EXTRA_CFLAGS+= $(INCS) $(COPTS) -DOPT_AH_H=\"public/$(TARGET).opt_ah.h\"
+
++ifeq ($(SINGLE_MODULE),)
++obj-m += ath_rate_sample.o
++
+ -include $(TOPDIR)/Rules.make
+
+ all:
+@@ -59,10 +60,9 @@ install:
+ test -d $(DESTDIR)/$(KMODPATH) || mkdir -p $(DESTDIR)/$(KMODPATH)
+ install -m 0644 ath_rate_sample.$(KMODSUF) $(DESTDIR)/$(KMODPATH)
+
+-clean:
+- -rm -f *~ *.o *.ko *.mod.c
+- -rm -f .depend .version .*.o.flags .*.o.d .*.o.cmd .*.ko.cmd
+- -rm -rf .tmp_versions
+-
+ ath_rate_sample.o: $(ath_rate_sample-objs)
+ $(LD) $(LDOPTS) -o ath_rate_sample.$(KMODSUF) -r $(ath_rate_sample-objs)
++else
++all:
++install:
++endif
+--- a/Makefile
++++ b/Makefile
+@@ -41,7 +41,7 @@
+ #
+
+ obj := $(firstword $(obj) $(SUBDIRS) .)
+-TOP = $(obj)
++export TOP:=$(if $(wildcard $(firstword $(SUBDIRS))/Makefile.inc),$(firstword $(SUBDIRS)),$(CURDIR))
+
+ ifneq (svnversion.h,$(MAKECMDGOALS))
+ include $(TOP)/Makefile.inc
+@@ -54,7 +54,7 @@ all: modules tools
+ modules: configcheck svnversion.h
+ ifdef LINUX24
+ for i in $(obj-y); do \
+- $(MAKE) -C $$i || exit 1; \
++ $(MAKE) -C $$i TOP="$(TOP)" || exit 1; \
+ done
+ else
+ $(MAKE) -C $(KERNELPATH) SUBDIRS=$(shell pwd) modules
+@@ -89,7 +89,7 @@ install-modules: modules
+ sh scripts/find-madwifi-modules.sh -r $(KERNELRELEASE) $(DESTDIR)
+
+ for i in $(obj-y); do \
+- $(MAKE) -C $$i install || exit 1; \
++ $(MAKE) -C $$i install TOP="$(TOP)" || exit 1; \
+ done
+ ifeq ($(DESTDIR),)
+ (export KMODPATH=$(KMODPATH); /sbin/depmod -ae $(KERNELRELEASE))
+@@ -114,12 +114,21 @@ reinstall-tools: uninstall-tools install
+ reinstall-modules: uninstall-modules install-modules
+
+ clean:
+- for i in $(obj-y); do \
+- $(MAKE) -C $$i clean; \
+- done
+- -$(MAKE) -C $(TOOLS) clean
+- rm -rf .tmp_versions
++ -find $(obj-y) -name '*~' \
++ -or -name '*.o' \
++ -or -name '*.o.d' \
++ -or -name '*.o.cmd' \
++ -or -name '*.o.flags' \
++ -or -name '*.ko' \
++ -or -name '*.ko.cmd' \
++ -or -name '*.mod.c' \
++ -or -name '.depend' \
++ -or -name '.version' \
++ -or -name '.symvers' | \
++ xargs -r rm -f
+ rm -f *.symvers svnversion.h
++ rm -rf .tmp_versions
++ make -C tools clean
+
+ info:
+ @echo "The following settings will be used for compilation:"
+@@ -135,18 +144,6 @@ info:
+ @echo "KMODPATH : $(KMODPATH)"
+ @echo "KMODSUF : $(KMODSUF)"
+
+-sanitycheck:
+- @echo -n "Checking requirements... "
+-
+- @# check if specified rate control is available
+- @if [ ! -d $(ATH_RATE) ]; then \
+- echo "FAILED"; \
+- echo "Selected rate control $(ATH_RATE) not available."; \
+- exit 1; \
+- fi
+-
+- @echo "ok."
+-
+ .PHONY: release
+ release:
+ sh scripts/make-release.bash
+@@ -155,7 +152,7 @@ release:
+ unload:
+ bash scripts/madwifi-unload
+
+-configcheck: sanitycheck
++configcheck:
+ @echo -n "Checking kernel configuration... "
+
+ @# check version of kernel
+--- a/Makefile.inc
++++ b/Makefile.inc
+@@ -68,6 +68,9 @@ endif
+ export KERNELPATH
+ endif
+
++# build net80211 and ath_ahb/ath_pci into a single module
++export SINGLE_MODULE=1
++
+ # KERNELRELEASE is the target kernel's version. It's always taken from
+ # the kernel build tree. Kernel Makefile doesn't always know the exact
+ # kernel version (especially for vendor stock kernels), so we get it
+@@ -100,6 +103,7 @@ export ARCH
+ include $(TOP)/ath_hal/ah_target.inc
+ export TARGET
+ COPTS += -DTARGET='"$(TARGET)"'
++COPTS += -DCONFIG_ATHEROS_RATE_DEFAULT='"$(firstword $(ATH_RATE))"'
+
+ # KMODPATH nominates the directory where the modules will be
+ # installed to
+@@ -141,7 +145,7 @@ ATH= $(TOP)/ath
+ #
+ # Path to the rate control algorithms.
+ #
+-ATH_RATE= $(TOP)/ath_rate
++ATH_RATE= minstrel
+ #
+ # Path to the userspace utilities.
+ #
+--- a/ath_rate/sample/sample.c
++++ b/ath_rate/sample/sample.c
+@@ -991,6 +991,8 @@ static struct ieee80211_rate_ops ath_rat
+ .dynamic_proc_register = ath_rate_dynamic_proc_register,
+ };
+
++#include <net80211/module.h>
++
+ MODULE_AUTHOR("John Bicket");
+ MODULE_DESCRIPTION("SampleRate bit-rate selection algorithm for Atheros devices");
+ #ifdef MODULE_VERSION
+@@ -1000,18 +1002,17 @@ MODULE_VERSION(RELEASE_VERSION);
+ MODULE_LICENSE("Dual BSD/GPL");
+ #endif
+
+-static int __init
+-init_ath_rate_sample(void)
++static int __init ath_rate_sample_init(void)
+ {
+ printk(KERN_INFO "%s: %s\n", dev_info, version);
+ return ieee80211_rate_register(&ath_rate_ops);
+ }
+-module_init(init_ath_rate_sample);
++module_init(ath_rate_sample_init);
+
+ static void __exit
+-exit_ath_rate_sample(void)
++ath_rate_sample_exit(void)
+ {
+ ieee80211_rate_unregister(&ath_rate_ops);
+ printk(KERN_INFO "%s: unloaded\n", dev_info);
+ }
+-module_exit(exit_ath_rate_sample);
++module_exit(ath_rate_sample_exit);
+--- a/net80211/if_media.h
++++ b/net80211/if_media.h
+@@ -42,6 +42,7 @@
+ #define _NET_IF_MEDIA_H_
+
+ #include <net80211/ieee80211_linux.h>
++#include "symbol.h"
+
+ /*
+ * Prototypes and definitions for BSD/OS-compatible network interface
+--- /dev/null
++++ b/net80211/symbol.h
+@@ -0,0 +1,4 @@
++#ifdef SINGLE_MODULE
++#undef EXPORT_SYMBOL
++#define EXPORT_SYMBOL(...)
++#endif
+--- a/ath_rate/Makefile
++++ b/ath_rate/Makefile
+@@ -1,7 +1,7 @@
+ obj := $(firstword $(obj) $(SUBDIRS) .)
+ TOP = $(obj)/..
+
+-obj-y := amrr/ onoe/ sample/ minstrel/
++obj-y := sample/ minstrel/
+
+ include $(TOP)/Makefile.inc
+