madwifi: add patch for building all modules (except for the HAL) into a single module...
authorFelix Fietkau <nbd@openwrt.org>
Wed, 19 Aug 2009 15:13:00 +0000 (15:13 +0000)
committerFelix Fietkau <nbd@openwrt.org>
Wed, 19 Aug 2009 15:13:00 +0000 (15:13 +0000)
removes support for onoe and amrr - I don't think anybody needs these anymore

SVN-Revision: 17314

package/madwifi/Config.in
package/madwifi/Makefile
package/madwifi/patches/446-single_module.patch [new file with mode: 0644]

index 23cc433..802e52a 100644 (file)
@@ -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
index 250c6fd..632b77f 100644 (file)
@@ -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 (file)
index 0000000..2ad9af8
--- /dev/null
@@ -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