merge madwifi all changes from trunk to 8.09
authorFelix Fietkau <nbd@openwrt.org>
Thu, 24 Sep 2009 12:07:18 +0000 (12:07 +0000)
committerFelix Fietkau <nbd@openwrt.org>
Thu, 24 Sep 2009 12:07:18 +0000 (12:07 +0000)
SVN-Revision: 17696

14 files changed:
package/madwifi/Config.in
package/madwifi/Makefile
package/madwifi/patches/414-txpower.patch
package/madwifi/patches/415-chan_switch.patch
package/madwifi/patches/417-beacon_txpower.patch
package/madwifi/patches/421-channel_handling.patch
package/madwifi/patches/424-timing.patch
package/madwifi/patches/430-use_netdev_priv.patch
package/madwifi/patches/432-netdev_ops.patch
package/madwifi/patches/446-single_module.patch [new file with mode: 0644]
package/madwifi/patches/447-sta_reconnect.patch [new file with mode: 0644]
package/madwifi/patches/448-beacon_handling_fixes.patch [new file with mode: 0644]
package/madwifi/patches/449-fix_txbuf_leak.patch [new file with mode: 0644]
package/madwifi/patches/450-calibration.patch [new file with mode: 0644]

index 3ae86cc..7f1e36d 100644 (file)
@@ -13,17 +13,14 @@ config MADWIFI_COMPRESSION
        help
          Enables Atheros Super A/G Hardware Compression Engine.
 
-choice
-       prompt "Madwifi version"
+config MADWIFI_SINGLE_MODULE
+       bool "Combine driver and net80211 into a single module"
        depends on PACKAGE_kmod-madwifi
-       default MADWIFI_STABLE
+       default y
        help
-         This option allows you to select the version of MadWifi to be built.
-
-config MADWIFI_STABLE
-       bool "Use the OpenWrt stable version of madwifi"
-
-endchoice
+         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"
@@ -41,38 +38,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 fcde633..980bf3b 100644 (file)
@@ -12,7 +12,7 @@ PKG_NAME:=madwifi
 
 PKG_REV:=3314
 PKG_VERSION:=r$(PKG_REV)
-PKG_RELEASE:=2.2
+PKG_RELEASE:=2.3
 
 PKG_SOURCE_PROTO:=svn
 PKG_SOURCE_VERSION:=$(PKG_REV)
@@ -108,6 +108,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) \
@@ -118,9 +121,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 \
@@ -130,7 +137,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)
@@ -183,14 +191,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" \
 
 define Build/Prepare/HAL
        rm -rf $(PKG_BUILD_DIR)/tmp
index af5a04b..6b33b8b 100644 (file)
@@ -38,7 +38,7 @@
                        IEEE80211_KEYIX_NONE);
 --- a/net80211/ieee80211_var.h
 +++ b/net80211/ieee80211_var.h
-@@ -343,8 +343,9 @@ struct ieee80211com {
+@@ -343,8 +343,8 @@ struct ieee80211com {
        u_int16_t ic_holdover;                  /* PM hold over duration */
        u_int16_t ic_bmissthreshold;            /* beacon miss threshold (# beacons) */
        unsigned long ic_bmiss_guard;           /* when to cease ignoring bmiss (jiffies) */
 -      u_int16_t ic_newtxpowlimit;             /* tx power limit to change to (in 0.5 dBm) */
 +      u_int16_t ic_txpowlimit;                /* configured global tx power limit (in 0.5 dBm) */
 +      u_int16_t ic_max_txpower;                       /* global hardware tx power limit */
-+      u_int16_t ic_cur_txpower;                       /* current tx power */
        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 */
 --- a/net80211/ieee80211_wireless.c
 +++ b/net80211/ieee80211_wireless.c
-@@ -920,17 +920,23 @@ ieee80211_ioctl_giwrange(struct net_devi
+@@ -908,6 +908,21 @@ ieee80211_ioctl_giwessid(struct net_devi
+       return 0;
+ }
++static u16
++ieee80211_get_maxtxpow(struct ieee80211com *ic)
++{
++      u_int16_t txp = IEEE80211_TXPOWER_MAX;
++
++      if (ic->ic_bsschan && (ic->ic_bsschan != IEEE80211_CHAN_ANYC))
++              txp = min(txp, (u16) ic->ic_bsschan->ic_maxpower);
++
++      if (ic->ic_max_txpower > 0)
++              txp = min(txp, ic->ic_max_txpower);
++
++      return txp;
++}
++
++
+ static int
+ ieee80211_ioctl_giwrange(struct net_device *dev, struct iw_request_info *info,
+       struct iw_point *data, char *extra)
+@@ -920,17 +935,21 @@ ieee80211_ioctl_giwrange(struct net_devi
        u_int8_t reported[IEEE80211_CHAN_BYTES];        /* XXX stack usage? */
        int i, r;
        int step = 0;
@@ -61,9 +82,7 @@
        data->length = sizeof(struct iw_range);
        memset(range, 0, sizeof(struct iw_range));
  
-+      power = ic->ic_max_txpower;
-+      if (ic->ic_bsschan && (ic->ic_bsschan != IEEE80211_CHAN_ANYC))
-+              power = min(power, (u_int16_t) ic->ic_bsschan->ic_maxpower);
++      power = ieee80211_get_maxtxpow(ic);
 +
        /* txpower (128 values, but will print out only IW_MAX_TXPOWER) */
 -      range->num_txpower = (ic->ic_txpowlimit >= 8) ? IW_MAX_TXPOWER : ic->ic_txpowlimit;
@@ -79,7 +98,7 @@
                        - (IW_MAX_TXPOWER - i - 1) * step;
  
        range->txpower_capa = IW_TXPOW_DBM;
-@@ -1379,13 +1385,11 @@ ieee80211_ioctl_siwtxpow(struct net_devi
+@@ -1379,13 +1398,11 @@ ieee80211_ioctl_siwtxpow(struct net_devi
        int fixed, disabled;
  
        fixed = (ic->ic_flags & IEEE80211_F_TXPOW_FIXED);
                        goto done;
                }
                return 0;
-@@ -1396,30 +1400,12 @@ ieee80211_ioctl_siwtxpow(struct net_devi
+@@ -1396,30 +1413,12 @@ ieee80211_ioctl_siwtxpow(struct net_devi
                        return -EOPNOTSUPP;
                if (rrq->flags != IW_TXPOW_DBM)
                        return -EINVAL;
                ic->ic_flags &= ~IEEE80211_F_TXPOW_FIXED;
        }
  done:
-@@ -1588,9 +1574,22 @@ ieee80211_ioctl_giwtxpow(struct net_devi
+@@ -1588,9 +1587,18 @@ ieee80211_ioctl_giwtxpow(struct net_devi
  {
        struct ieee80211vap *vap = dev->priv;
        struct ieee80211com *ic = vap->iv_ic;
 -      rrq->fixed = (ic->ic_flags & IEEE80211_F_TXPOW_FIXED) != 0;
 +      unsigned int power = ic->ic_txpowlimit;
 +      struct ieee80211_channel *c;
-+      u_int16_t txp = ic->ic_max_txpower;
++      u_int16_t txp;
 +
-+      if (ic->ic_bsschan && (ic->ic_bsschan != IEEE80211_CHAN_ANYC)) {
-+              txp = min(txp, (u16) ic->ic_bsschan->ic_maxpower);
-+      } else if (ic->ic_cur_txpower > 0) {
-+              txp = min(txp, ic->ic_cur_txpower);
-+      }
++      txp = ieee80211_get_maxtxpow(ic);
 +      if (ic->ic_flags & IEEE80211_F_TXPOW_FIXED) {
 +              txp = min(txp, ic->ic_txpowlimit);
 +              rrq->fixed = 1;
 -      if (new_clamped_maxtxpower != prev_clamped_maxtxpower)
 -              ath_hal_settxpowlimit(ah, new_clamped_maxtxpower);
 +      ath_set_clamped_maxtxpower(sc, ic->ic_txpowlimit);
-+      ic->ic_cur_txpower = ath_get_clamped_maxtxpower(sc);
++      ic->ic_max_txpower = ath_get_clamped_maxtxpower(sc);
  }
  
  #ifdef ATH_SUPERG_XR
index 8505064..6dc5da8 100644 (file)
  
                /* Don't allow to change to channel with radar found */
                if (c->ic_flags & IEEE80211_CHAN_RADAR)
-@@ -4625,7 +4597,13 @@ static void
+@@ -4634,7 +4606,13 @@ static void
  pre_announced_chanswitch(struct net_device *dev, u_int32_t channel, u_int32_t tbtt) {
        struct ieee80211vap *vap = dev->priv;
        struct ieee80211com *ic = vap->iv_ic;
index 5a336f8..8a59c12 100644 (file)
@@ -48,7 +48,7 @@
        struct ieee80211_node *iv_bss;                  /* information for this node */
 --- a/net80211/ieee80211_wireless.c
 +++ b/net80211/ieee80211_wireless.c
-@@ -2862,6 +2862,9 @@ ieee80211_ioctl_setparam(struct net_devi
+@@ -2871,6 +2871,9 @@ ieee80211_ioctl_setparam(struct net_devi
        case IEEE80211_PARAM_PROBEREQ:
                vap->iv_no_probereq = !value;
                break;
@@ -58,7 +58,7 @@
  #ifdef ATH_REVERSE_ENGINEERING
        case IEEE80211_PARAM_DUMPREGS:
                ieee80211_dump_registers(dev, info, w, extra);
-@@ -3227,6 +3230,9 @@ ieee80211_ioctl_getparam(struct net_devi
+@@ -3236,6 +3239,9 @@ ieee80211_ioctl_getparam(struct net_devi
        case IEEE80211_PARAM_PROBEREQ:
                param[0] = !vap->iv_no_probereq;
                break;
@@ -68,7 +68,7 @@
        default:
                return -EOPNOTSUPP;
        }
-@@ -5801,6 +5807,10 @@ static const struct iw_priv_args ieee802
+@@ -5810,6 +5816,10 @@ static const struct iw_priv_args ieee802
         IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "probereq"},
        { IEEE80211_PARAM_PROBEREQ,
         0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "get_probereq"},
index 69d96cb..e5302c1 100644 (file)
        u_int16_t ic_modecaps;                  /* set of mode capabilities */
        u_int16_t ic_curmode;                   /* current mode */
        u_int16_t ic_lintval;                   /* beacon interval */
-@@ -715,6 +713,7 @@ MALLOC_DECLARE(M_80211_VAP);
+@@ -714,6 +712,7 @@ MALLOC_DECLARE(M_80211_VAP);
  
  int ieee80211_ifattach(struct ieee80211com *);
  void ieee80211_ifdetach(struct ieee80211com *);
  int ieee80211_vap_setup(struct ieee80211com *, struct net_device *,
        const char *, int, int, struct ieee80211vap *);
  int ieee80211_vap_attach(struct ieee80211vap *, ifm_change_cb_t, ifm_stat_cb_t);
-@@ -794,6 +793,23 @@ ieee80211_anyhdrspace(struct ieee80211co
+@@ -793,6 +792,23 @@ ieee80211_anyhdrspace(struct ieee80211co
        return size;
  }
  
        if ((ic->ic_flags & IEEE80211_F_USEPROT) &&
 --- a/net80211/ieee80211_wireless.c
 +++ b/net80211/ieee80211_wireless.c
-@@ -2133,7 +2133,7 @@ ieee80211_ioctl_setmode(struct net_devic
+@@ -2142,7 +2142,7 @@ ieee80211_ioctl_setmode(struct net_devic
  
                vap->iv_des_mode = mode;
                if (IS_UP_AUTO(vap))
  
                retv = 0;
        }
-@@ -4081,46 +4081,60 @@ ieee80211_ioctl_getchanlist(struct net_d
+@@ -4090,46 +4090,60 @@ ieee80211_ioctl_getchanlist(struct net_d
        return 0;
  }
  
index 3d1d6e0..4dfa3c9 100644 (file)
  ath_rate_node_init(struct ath_softc *sc, struct ath_node *an)
 --- a/net80211/ieee80211_wireless.c
 +++ b/net80211/ieee80211_wireless.c
-@@ -2736,6 +2736,7 @@ ieee80211_ioctl_setparam(struct net_devi
+@@ -2745,6 +2745,7 @@ ieee80211_ioctl_setparam(struct net_devi
        case IEEE80211_PARAM_COVERAGE_CLASS:
                if (value <= IEEE80211_COVERAGE_CLASS_MAX) {
                        ic->ic_coverageclass = value;
index 6a66233..ad2b6d4 100644 (file)
  
        if (vap->iv_opmode == IEEE80211_M_WDS)
                return -EOPNOTSUPP;
-@@ -884,7 +884,7 @@ static int
+@@ -899,7 +899,7 @@ static int
  ieee80211_ioctl_giwrange(struct net_device *dev, struct iw_request_info *info,
        struct iw_point *data, char *extra)
  {
        struct ieee80211com *ic = vap->iv_ic;
        struct ieee80211_node *ni = vap->iv_bss;
        struct iw_range *range = (struct iw_range *) extra;
-@@ -1034,7 +1034,7 @@ ieee80211_ioctl_setspy(struct net_device
+@@ -1047,7 +1047,7 @@ ieee80211_ioctl_setspy(struct net_device
        struct iw_point *data, char *extra)
  {
        /* save the list of node addresses */
        struct sockaddr address[IW_MAX_SPY];
        unsigned int number = data->length;
        int i;
-@@ -1072,7 +1072,7 @@ ieee80211_ioctl_getspy(struct net_device
+@@ -1085,7 +1085,7 @@ ieee80211_ioctl_getspy(struct net_device
         * locate nodes by mac (ieee80211_find_node()),
         * copy out rssi, set updated flag appropriately
         */
        struct ieee80211_node_table *nt = &vap->iv_ic->ic_sta;
        struct ieee80211_node *ni;
        struct ieee80211com *ic = vap->iv_ic;
-@@ -1120,7 +1120,7 @@ static int
+@@ -1133,7 +1133,7 @@ static int
  ieee80211_ioctl_setthrspy(struct net_device *dev, struct iw_request_info *info,
        struct iw_point *data, char *extra)
  {
        struct iw_thrspy threshold;
  
        if (data->length != 1)
-@@ -1157,7 +1157,7 @@ static int
+@@ -1170,7 +1170,7 @@ static int
  ieee80211_ioctl_getthrspy(struct net_device *dev, struct iw_request_info *info,
        struct iw_point *data, char *extra)
  {
        struct ieee80211com *ic = vap->iv_ic;
        struct iw_thrspy *threshold;
  
-@@ -1178,7 +1178,7 @@ static int
+@@ -1191,7 +1191,7 @@ static int
  ieee80211_ioctl_siwmode(struct net_device *dev, struct iw_request_info *info,
        __u32 *mode, char *extra)
  {
        struct ifmediareq imr;
        int valid = 0;
  
-@@ -1203,7 +1203,7 @@ static int
+@@ -1216,7 +1216,7 @@ static int
  ieee80211_ioctl_giwmode(struct net_device *dev,       struct iw_request_info *info,
        __u32 *mode, char *extra)
  {
        struct ifmediareq imr;
  
        memset(&imr, 0, sizeof(imr));
-@@ -1226,7 +1226,7 @@ static int
+@@ -1239,7 +1239,7 @@ static int
  ieee80211_ioctl_siwpower(struct net_device *dev, struct iw_request_info *info,
        struct iw_param *wrq, char *extra)
  {
        struct ieee80211com *ic = vap->iv_ic;
  
        /* XXX: These values, flags, and caps do not seem to be used elsewhere 
-@@ -1265,7 +1265,7 @@ static int
+@@ -1278,7 +1278,7 @@ static int
  ieee80211_ioctl_giwpower(struct net_device *dev, struct iw_request_info *info,
        struct iw_param *rrq, char *extra)
  {
        struct ieee80211com *ic = vap->iv_ic;
  
        rrq->disabled = (ic->ic_flags & IEEE80211_F_PMGTON) == 0;
-@@ -1289,7 +1289,7 @@ static int
+@@ -1302,7 +1302,7 @@ static int
  ieee80211_ioctl_siwretry(struct net_device *dev, struct iw_request_info *info,
        struct iw_param *rrq, char *extra)
  {
        struct ieee80211com *ic = vap->iv_ic;
  
        if (rrq->disabled) {
-@@ -1321,7 +1321,7 @@ static int
+@@ -1334,7 +1334,7 @@ static int
  ieee80211_ioctl_giwretry(struct net_device *dev, struct iw_request_info *info,
        struct iw_param *rrq, char *extra)
  {
  
        rrq->disabled = (vap->iv_flags & IEEE80211_F_SWRETRY) == 0;
        if (!rrq->disabled) {
-@@ -1352,7 +1352,7 @@ static int
+@@ -1365,7 +1365,7 @@ static int
  ieee80211_ioctl_siwtxpow(struct net_device *dev, struct iw_request_info *info,
        struct iw_param *rrq, char *extra)
  {
        struct ieee80211com *ic = vap->iv_ic;
        int fixed, disabled;
  
-@@ -1389,7 +1389,7 @@ ieee80211_get_txcont(struct net_device *
+@@ -1402,7 +1402,7 @@ ieee80211_get_txcont(struct net_device *
                struct iw_request_info *info, void *w, char *extra)
  {
        int *params = (int*) extra;
        struct ieee80211com *ic = vap->iv_ic;
        params[0] = ic->ic_get_txcont(ic);
        return 0;
-@@ -1400,7 +1400,7 @@ ieee80211_get_dfs_cac_time(struct net_de
+@@ -1413,7 +1413,7 @@ ieee80211_get_dfs_cac_time(struct net_de
                struct iw_request_info *info, void *w, char *extra)
  {
        int *params = (int*) extra;
        struct ieee80211com *ic = vap->iv_ic;
        params[0] = ic->ic_get_dfs_cac_time(ic);
        return 0;
-@@ -1411,7 +1411,7 @@ ieee80211_get_dfs_excl_period(struct net
+@@ -1424,7 +1424,7 @@ ieee80211_get_dfs_excl_period(struct net
                struct iw_request_info *info, void *w, char *extra)
  {
        int *params = (int*) extra;
        struct ieee80211com *ic = vap->iv_ic;
        params[0] = ic->ic_get_dfs_excl_period(ic);
        return 0;
-@@ -1421,7 +1421,7 @@ ieee80211_set_dfs_cac_time(struct net_de
+@@ -1434,7 +1434,7 @@ ieee80211_set_dfs_cac_time(struct net_de
                struct iw_request_info *info, void *w, char *extra)
  {
        int *params = (int*) extra;
        struct ieee80211com *ic = vap->iv_ic;
        ic->ic_set_dfs_cac_time(ic, params[1]);
        return 0;
-@@ -1431,7 +1431,7 @@ ieee80211_set_dfs_excl_period  (struct n
+@@ -1444,7 +1444,7 @@ ieee80211_set_dfs_excl_period  (struct n
                struct iw_request_info *info, void *w, char *extra)
  {
        int *params = (int*) extra;
        struct ieee80211com *ic = vap->iv_ic;
        ic->ic_set_dfs_excl_period(ic, params[1]);
        return 0;
-@@ -1442,7 +1442,7 @@ ieee80211_get_dfs_testmode(struct net_de
+@@ -1455,7 +1455,7 @@ ieee80211_get_dfs_testmode(struct net_de
                struct iw_request_info *info, void *w, char *extra)
  {
        int *params = (int*) extra;
        struct ieee80211com *ic = vap->iv_ic;
        params[0] = ic->ic_get_dfs_testmode(ic);
        return 0;
-@@ -1453,7 +1453,7 @@ ieee80211_get_txcont_rate(struct net_dev
+@@ -1466,7 +1466,7 @@ ieee80211_get_txcont_rate(struct net_dev
                struct iw_request_info *info, void *w, char *extra)
  {
        int *params = (int*) extra;
        struct ieee80211com *ic = vap->iv_ic;
        params[0] = ic->ic_get_txcont_rate(ic);
        return 0;
-@@ -1464,7 +1464,7 @@ ieee80211_set_txcont(struct net_device *
+@@ -1477,7 +1477,7 @@ ieee80211_set_txcont(struct net_device *
                void *w, char *extra)
  {
        int *params = (int*) extra;
        struct ieee80211com *ic = vap->iv_ic;
        ic->ic_set_txcont(ic, params[1]);
        return 0;
-@@ -1475,7 +1475,7 @@ ieee80211_set_dfs_testmode(struct net_de
+@@ -1488,7 +1488,7 @@ ieee80211_set_dfs_testmode(struct net_de
                struct iw_request_info *info, void *w, char *extra)
  {
        int *params = (int*) extra;
        struct ieee80211com *ic = vap->iv_ic;
        ic->ic_set_dfs_testmode(ic, params[1]);
        return 0;
-@@ -1486,7 +1486,7 @@ ieee80211_set_txcont_rate(struct net_dev
+@@ -1499,7 +1499,7 @@ ieee80211_set_txcont_rate(struct net_dev
                struct iw_request_info *info, void *w, char *extra)
  {
        int *params = (int*) extra;
        struct ieee80211com *ic = vap->iv_ic;
        ic->ic_set_txcont_rate(ic, params[1]);
        return 0;
-@@ -1497,7 +1497,7 @@ ieee80211_set_txcont_power(struct net_de
+@@ -1510,7 +1510,7 @@ ieee80211_set_txcont_power(struct net_de
                struct iw_request_info *info, void *w, char *extra)
  {
        int *params = (int*) extra;
        struct ieee80211com *ic = vap->iv_ic;
        ic->ic_set_txcont_power(ic, params[1]);
        return 0;
-@@ -1508,7 +1508,7 @@ ieee80211_get_txcont_power(struct net_de
+@@ -1521,7 +1521,7 @@ ieee80211_get_txcont_power(struct net_de
                struct iw_request_info *info, void *w, char *extra)
  {
        int *params = (int*) extra;
        struct ieee80211com *ic = vap->iv_ic;
        params[0] = ic->ic_get_txcont_power(ic);
        return 0;
-@@ -1520,7 +1520,7 @@ ieee80211_ioctl_hal_map(struct net_devic
+@@ -1533,7 +1533,7 @@ ieee80211_ioctl_hal_map(struct net_devic
         void *w, char *extra)
  {
         int *params = (int*) extra;
         struct ieee80211com *ic = vap->iv_ic;
         params[0] = ic->ic_dump_hal_map(ic);
         return 0;
-@@ -1532,7 +1532,7 @@ ieee80211_ioctl_radar(struct net_device 
+@@ -1545,7 +1545,7 @@ ieee80211_ioctl_radar(struct net_device 
        void *w, char *extra)
  {
        int *params = (int*) extra;
        struct ieee80211com *ic = vap->iv_ic;
        if (!(ic->ic_flags & IEEE80211_F_DOTH))
                return 0;
-@@ -1544,7 +1544,7 @@ static int
+@@ -1557,7 +1557,7 @@ static int
  ieee80211_ioctl_giwtxpow(struct net_device *dev, struct iw_request_info *info,
        struct iw_param *rrq, char *extra)
  {
        struct ieee80211com *ic = vap->iv_ic;
        unsigned int power = ic->ic_txpowlimit;
        struct ieee80211_channel *c;
-@@ -1572,7 +1572,7 @@ static int
+@@ -1581,7 +1581,7 @@ static int
  ieee80211_dump_registers(struct net_device *dev, struct iw_request_info *info, void *w, char *extra)
  {
        unsigned int *params = (unsigned int*) extra;
        struct ieee80211com *ic = vap->iv_ic;
        switch (params[1]) {
        case 2:
-@@ -1595,7 +1595,7 @@ static int
+@@ -1604,7 +1604,7 @@ static int
  ieee80211_ioctl_writereg(struct net_device *dev, struct iw_request_info *info, void *w, char *extra)
  {
        unsigned int *params = (unsigned int*) extra;
        struct ieee80211com *ic = vap->iv_ic;
        return ic->ic_write_register(ic, params[0], params[1]);
  }
-@@ -1606,7 +1606,7 @@ static int
+@@ -1615,7 +1615,7 @@ static int
  ieee80211_ioctl_readreg(struct net_device *dev, struct iw_request_info *info, void *w, char *extra)
  {
        unsigned int *params = (unsigned int*) extra;
        struct ieee80211com *ic = vap->iv_ic;
        return ic->ic_read_register(ic, params[0], &params[0]);
  }
-@@ -1642,7 +1642,7 @@ static int
+@@ -1651,7 +1651,7 @@ static int
  ieee80211_ioctl_iwaplist(struct net_device *dev, struct iw_request_info *info,
        struct iw_point *data, char *extra)
  {
        struct ieee80211com *ic = vap->iv_ic;
        struct waplistreq req;          /* XXX off stack */
  
-@@ -1664,7 +1664,7 @@ static int
+@@ -1673,7 +1673,7 @@ static int
  ieee80211_ioctl_siwscan(struct net_device *dev,       struct iw_request_info *info,
        struct iw_point *data, char *extra)
  {
  
        /*
         * XXX don't permit a scan to be started unless we
-@@ -1988,7 +1988,7 @@ static int
+@@ -1997,7 +1997,7 @@ static int
  ieee80211_ioctl_giwscan(struct net_device *dev,       struct iw_request_info *info,
        struct iw_point *data, char *extra)
  {
        struct ieee80211com *ic = vap->iv_ic;
        struct iwscanreq req;
        int res = 0;
-@@ -2089,7 +2089,7 @@ static int
+@@ -2098,7 +2098,7 @@ static int
  ieee80211_ioctl_setmode(struct net_device *dev, struct iw_request_info *info,
        struct iw_point *wri, char *extra)
  {
        struct ieee80211com *ic = vap->iv_ic;
        struct ifreq ifr;
        char s[6];              /* big enough for ``11adt'' */
-@@ -2213,10 +2213,10 @@ ieee80211_setathcap(struct ieee80211vap 
+@@ -2222,10 +2222,10 @@ ieee80211_setathcap(struct ieee80211vap 
  static int
  ieee80211_set_turbo(struct net_device *dev, int flag)
  {
        int nvap = 0;
  
        TAILQ_FOREACH(tmpvap, &ic->ic_vaps, iv_next)
-@@ -2237,7 +2237,7 @@ static int
+@@ -2246,7 +2246,7 @@ static int
  ieee80211_ioctl_setparam(struct net_device *dev, struct iw_request_info *info,
        void *w, char *extra)
  {
        struct ieee80211com *ic = vap->iv_ic;
        struct ieee80211_rsnparms *rsn = &vap->iv_bss->ni_rsn;
        unsigned int *i = (unsigned int *) extra;
-@@ -2917,7 +2917,7 @@ static int
+@@ -2926,7 +2926,7 @@ static int
  ieee80211_ioctl_getmode(struct net_device *dev, struct iw_request_info *info,
        struct iw_point *wri, char *extra)
  {
        struct ieee80211com *ic = vap->iv_ic;
        struct ifmediareq imr;
  
-@@ -2955,7 +2955,7 @@ static int
+@@ -2964,7 +2964,7 @@ static int
  ieee80211_ioctl_getparam(struct net_device *dev, struct iw_request_info *info,
        void *w, char *extra)
  {
        struct ieee80211com *ic = vap->iv_ic;
        struct ieee80211_rsnparms *rsn = &vap->iv_bss->ni_rsn;
        unsigned int *param = (unsigned int *) extra;
-@@ -3300,7 +3300,7 @@ static int
+@@ -3309,7 +3309,7 @@ static int
  ieee80211_ioctl_setoptie(struct net_device *dev, struct iw_request_info *info,
        struct iw_point *wri, char *extra)
  {
        void *ie;
  
        /*
-@@ -3334,7 +3334,7 @@ static int
+@@ -3343,7 +3343,7 @@ static int
  ieee80211_ioctl_getoptie(struct net_device *dev, struct iw_request_info *info,
        struct iw_point *wri, char *extra)
  {
  
        if (vap->iv_opt_ie == NULL) {
                wri->length = 0;
-@@ -3398,7 +3398,7 @@ ieee80211_ioctl_setappiebuf(struct net_d
+@@ -3407,7 +3407,7 @@ ieee80211_ioctl_setappiebuf(struct net_d
        struct iw_request_info *info,
        struct iw_point *data, char *extra)
  {
        struct ieee80211req_getset_appiebuf *iebuf =
                (struct ieee80211req_getset_appiebuf *)extra;
        enum ieee80211_opmode chk_opmode;
-@@ -3440,7 +3440,7 @@ static int
+@@ -3449,7 +3449,7 @@ static int
  ieee80211_ioctl_getappiebuf(struct net_device *dev, struct iw_request_info *info,
        struct iw_point *data, char *extra)
  {
        struct ieee80211req_getset_appiebuf *iebuf =
                (struct ieee80211req_getset_appiebuf *)extra;
        int max_iebuf_len;
-@@ -3481,7 +3481,7 @@ static int
+@@ -3490,7 +3490,7 @@ static int
  ieee80211_ioctl_setfilter(struct net_device *dev, struct iw_request_info *info,
        void *w, char *extra)
  {
        struct ieee80211req_set_filter *app_filter = (struct ieee80211req_set_filter *)extra;
  
        if ((extra == NULL) || (app_filter->app_filterype & ~IEEE80211_FILTER_TYPE_ALL))
-@@ -3496,7 +3496,7 @@ static int
+@@ -3505,7 +3505,7 @@ static int
  ieee80211_ioctl_setkey(struct net_device *dev, struct iw_request_info *info,
        void *w, char *extra)
  {
        struct ieee80211com *ic = vap->iv_ic;
        struct ieee80211req_key *ik = (struct ieee80211req_key *)extra;
        struct ieee80211_node *ni;
-@@ -3579,7 +3579,7 @@ ieee80211_ioctl_setkey(struct net_device
+@@ -3588,7 +3588,7 @@ ieee80211_ioctl_setkey(struct net_device
  static int
  ieee80211_ioctl_getkey(struct net_device *dev, struct iwreq *iwr)
  {
        struct ieee80211com *ic = vap->iv_ic;
        struct ieee80211_node *ni;
        struct ieee80211req_key ik;
-@@ -3640,7 +3640,7 @@ static int
+@@ -3649,7 +3649,7 @@ static int
  ieee80211_ioctl_delkey(struct net_device *dev, struct iw_request_info *info,
        void *w, char *extra)
  {
        struct ieee80211com *ic = vap->iv_ic;
        struct ieee80211req_del_key *dk = (struct ieee80211req_del_key *)extra;
        ieee80211_keyix_t kix;
-@@ -3714,7 +3714,7 @@ static int
+@@ -3723,7 +3723,7 @@ static int
  ieee80211_ioctl_setmlme(struct net_device *dev, struct iw_request_info *info,
        void *w, char *extra)
  {
        struct ieee80211com *ic = vap->iv_ic;
        struct ieee80211req_mlme *mlme = (struct ieee80211req_mlme *)extra;
        struct ieee80211_node *ni;
-@@ -3817,7 +3817,7 @@ static int
+@@ -3826,7 +3826,7 @@ static int
  ieee80211_ioctl_wdsaddmac(struct net_device *dev, struct iw_request_info *info,
        void *w, char *extra)
  {
        struct sockaddr *sa = (struct sockaddr *)extra;
        struct ieee80211com *ic = vap->iv_ic;
        struct ieee80211vap *avp;
-@@ -3846,7 +3846,7 @@ static int
+@@ -3855,7 +3855,7 @@ static int
  ieee80211_ioctl_wdssetmac(struct net_device *dev, struct iw_request_info *info,
        void *w, char *extra)
  {
        struct sockaddr *sa = (struct sockaddr *)extra;
  
        if (vap->iv_opmode != IEEE80211_M_WDS)
-@@ -3913,7 +3913,7 @@ ieee80211_ioctl_setscanlist(struct net_d
+@@ -3922,7 +3922,7 @@ ieee80211_ioctl_setscanlist(struct net_d
        struct iw_request_info *info,
        struct iw_point *data, char *extra)
  {
        struct ieee80211com *ic = vap->iv_ic;
        char *s, *next;
        int val = 1;
-@@ -3988,7 +3988,7 @@ static int
+@@ -3997,7 +3997,7 @@ static int
  ieee80211_ioctl_addmac(struct net_device *dev, struct iw_request_info *info,
        void *w, char *extra)
  {
        struct sockaddr *sa = (struct sockaddr *)extra;
        const struct ieee80211_aclator *acl = vap->iv_acl;
  
-@@ -4006,7 +4006,7 @@ static int
+@@ -4015,7 +4015,7 @@ static int
  ieee80211_ioctl_delmac(struct net_device *dev, struct iw_request_info *info,
        void *w, char *extra)
  {
        struct sockaddr *sa = (struct sockaddr *)extra;
        const struct ieee80211_aclator *acl = vap->iv_acl;
  
-@@ -4024,7 +4024,7 @@ static int
+@@ -4033,7 +4033,7 @@ static int
  ieee80211_ioctl_setchanlist(struct net_device *dev,
        struct iw_request_info *info, void *w, char *extra)
  {
        struct ieee80211com *ic = vap->iv_ic;
        struct ieee80211req_chanlist *list =
                (struct ieee80211req_chanlist *)extra;
-@@ -4075,7 +4075,7 @@ static int
+@@ -4084,7 +4084,7 @@ static int
  ieee80211_ioctl_getchanlist(struct net_device *dev,
        struct iw_request_info *info, void *w, char *extra)
  {
        struct ieee80211com *ic = vap->iv_ic;
  
        memcpy(extra, ic->ic_chan_active, sizeof(ic->ic_chan_active));
-@@ -4096,7 +4096,7 @@ static int
+@@ -4105,7 +4105,7 @@ static int
  ieee80211_ioctl_getchaninfo(struct net_device *dev,
                            struct iw_request_info *info, void *w, char *extra)
  {
        struct ieee80211com *ic = vap->iv_ic;
        struct ieee80211req_chaninfo *chans =
            (struct ieee80211req_chaninfo *)extra;
-@@ -4143,7 +4143,7 @@ static int
+@@ -4152,7 +4152,7 @@ static int
  ieee80211_ioctl_setwmmparams(struct net_device *dev,
        struct iw_request_info *info, void *w, char *extra)
  {
        unsigned int *param = (unsigned int *) extra;
        unsigned int ac = (param[1] < WME_NUM_AC) ? param[1] : WME_AC_BE;
        unsigned int bss = param[2];
-@@ -4231,7 +4231,7 @@ static int
+@@ -4240,7 +4240,7 @@ static int
  ieee80211_ioctl_getwmmparams(struct net_device *dev,
        struct iw_request_info *info, void *w, char *extra)
  {
        unsigned int *param = (unsigned int *) extra;
        unsigned int ac = (param[1] < WME_NUM_AC) ? param[1] : WME_AC_BE;
        struct ieee80211_wme_state *wme = &vap->iv_ic->ic_wme;
-@@ -4266,7 +4266,7 @@ ieee80211_ioctl_getwmmparams(struct net_
+@@ -4275,7 +4275,7 @@ ieee80211_ioctl_getwmmparams(struct net_
  static int
  ieee80211_ioctl_getwpaie(struct net_device *dev, struct iwreq *iwr)
  {
        struct ieee80211com *ic = vap->iv_ic;
        struct ieee80211_node *ni;
        struct ieee80211req_wpaie wpaie;
-@@ -4300,7 +4300,7 @@ ieee80211_ioctl_getwpaie(struct net_devi
+@@ -4309,7 +4309,7 @@ ieee80211_ioctl_getwpaie(struct net_devi
  static int
  ieee80211_ioctl_getstastats(struct net_device *dev, struct iwreq *iwr)
  {
        struct ieee80211com *ic = vap->iv_ic;
        struct ieee80211_node *ni;
        u_int8_t macaddr[IEEE80211_ADDR_LEN];
-@@ -4419,7 +4419,7 @@ get_scan_result(void *arg, const struct 
+@@ -4428,7 +4428,7 @@ get_scan_result(void *arg, const struct 
  static int
  ieee80211_ioctl_getscanresults(struct net_device *dev, struct iwreq *iwr)
  {
        struct ieee80211com *ic = vap->iv_ic;
        struct scanreq req;
        int error;
-@@ -4582,7 +4582,7 @@ get_sta_info(void *arg, struct ieee80211
+@@ -4591,7 +4591,7 @@ get_sta_info(void *arg, struct ieee80211
  static int
  ieee80211_ioctl_getstainfo(struct net_device *dev, struct iwreq *iwr)
  {
        struct ieee80211com *ic = vap->iv_ic;
        struct stainforeq req;
        int error;
-@@ -4616,7 +4616,7 @@ ieee80211_ioctl_getstainfo(struct net_de
+@@ -4625,7 +4625,7 @@ ieee80211_ioctl_getstainfo(struct net_de
  
  static void
  pre_announced_chanswitch(struct net_device *dev, u_int32_t channel, u_int32_t tbtt) {
        struct ieee80211com *ic = vap->iv_ic;
        struct ieee80211vap *avp;
  
-@@ -4634,7 +4634,7 @@ static int
+@@ -4643,7 +4643,7 @@ static int
  ieee80211_ioctl_chanswitch(struct net_device *dev, struct iw_request_info *info,
        void *w, char *extra)
  {
        struct ieee80211com *ic = vap->iv_ic;
        unsigned int *param = (unsigned int *) extra;
  
-@@ -4679,7 +4679,7 @@ static int
+@@ -4688,7 +4688,7 @@ static int
  ieee80211_ioctl_giwgenie(struct net_device *dev,
        struct iw_request_info *info, struct iw_point *out, char *buf)
  {
  
        if (out->length < vap->iv_opt_ie_len)
                return -E2BIG;
-@@ -5212,7 +5212,7 @@ static int
+@@ -5221,7 +5221,7 @@ static int
  ieee80211_ioctl_giwencodeext(struct net_device *dev,
        struct iw_request_info *info, struct iw_point *erq, char *extra)
  {
        struct iw_encode_ext *ext;
        struct ieee80211_key *wk;
        ieee80211_keyix_t kix;
-@@ -5272,7 +5272,7 @@ static int
+@@ -5281,7 +5281,7 @@ static int
  ieee80211_ioctl_siwencodeext(struct net_device *dev,
        struct iw_request_info *info, struct iw_point *erq, char *extra)
  {
        struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
        struct ieee80211req_key kr;
        ieee80211_keyix_t kix;
-@@ -5948,7 +5948,7 @@ static struct iw_handler_def ieee80211_i
+@@ -5957,7 +5957,7 @@ static struct iw_handler_def ieee80211_i
  static int
  ieee80211_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
  {
index f9286ff..372000f 100644 (file)
@@ -88,7 +88,7 @@ http://madwifi-project.org/changeset/4005
  int
  ieee80211_vap_setup(struct ieee80211com *ic, struct net_device *dev,
        const char *name, int opmode, int flags, struct ieee80211vap *master)
-@@ -470,12 +482,17 @@ ieee80211_vap_setup(struct ieee80211com 
+@@ -470,16 +482,21 @@ ieee80211_vap_setup(struct ieee80211com 
                } else
                        strncpy(dev->name, name, sizeof(dev->name));
        }
@@ -100,12 +100,16 @@ http://madwifi-project.org/changeset/4005
        dev->hard_start_xmit = ieee80211_hardstart;
        dev->set_multicast_list = ieee80211_set_multicast_list;
 +      dev->do_ioctl = ieee80211_ioctl;
-+#else
-+      dev->netdev_ops = &ieee80211_netdev_ops;
-+#endif
  #if 0
        dev->set_mac_address = ieee80211_set_mac_address;
  #endif
+       dev->change_mtu = ieee80211_change_mtu;
++#else
++      dev->netdev_ops = &ieee80211_netdev_ops;
++#endif
+       dev->tx_queue_len = 0;                  /* NB: bypass queuing */
+       dev->hard_header_len = parent->hard_header_len;
+       /*
 @@ -1823,7 +1840,11 @@ ieee80211_set_multicast_list(struct net_
        IEEE80211_UNLOCK_IRQ(ic);
  
@@ -137,7 +141,7 @@ http://madwifi-project.org/changeset/4005
        case NETDEV_CHANGENAME:
 --- a/net80211/ieee80211_var.h
 +++ b/net80211/ieee80211_var.h
-@@ -740,6 +740,7 @@ void ieee80211_build_sc_ie(struct ieee80
+@@ -739,6 +739,7 @@ void ieee80211_build_sc_ie(struct ieee80
  void ieee80211_dfs_action(struct ieee80211com *);
  void ieee80211_expire_channel_excl_restrictions(struct ieee80211com *);
  void ieee80211_setpuregbasicrates(struct ieee80211_rateset *rs);
@@ -147,7 +151,7 @@ http://madwifi-project.org/changeset/4005
   * Iterate through ic_channels to enumerate all distinct ic_ieee channel numbers.
 --- a/net80211/ieee80211_wireless.c
 +++ b/net80211/ieee80211_wireless.c
-@@ -5945,7 +5945,7 @@ static struct iw_handler_def ieee80211_i
+@@ -5954,7 +5954,7 @@ static struct iw_handler_def ieee80211_i
  /*
   * Handle private ioctl requests.
   */
@@ -156,7 +160,7 @@ http://madwifi-project.org/changeset/4005
  ieee80211_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
  {
        struct ieee80211vap *vap = netdev_priv(dev);
-@@ -6035,7 +6035,6 @@ ieee80211_ioctl_vattach(struct ieee80211
+@@ -6044,7 +6044,6 @@ ieee80211_ioctl_vattach(struct ieee80211
  {
        struct net_device *dev = vap->iv_dev;
  
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..ed02ae8
--- /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
+@@ -13780,3 +13780,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 
+@@ -740,6 +741,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
diff --git a/package/madwifi/patches/447-sta_reconnect.patch b/package/madwifi/patches/447-sta_reconnect.patch
new file mode 100644 (file)
index 0000000..e6f019e
--- /dev/null
@@ -0,0 +1,33 @@
+--- a/net80211/ieee80211_node.c
++++ b/net80211/ieee80211_node.c
+@@ -647,8 +647,11 @@ ieee80211_sta_join1(struct ieee80211_nod
+               (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)
++      if (obss != NULL) {
++              if (obss->ni_table)
++                      ieee80211_node_leave(obss);
+               ieee80211_unref_node(&obss);
++      }
+       ic->ic_bsschan = selbs->ni_chan;
+       ic->ic_curchan = ic->ic_bsschan;
+       ic->ic_curmode = ieee80211_chan2mode(ic->ic_curchan);
+--- a/net80211/ieee80211_proto.c
++++ b/net80211/ieee80211_proto.c
+@@ -1512,14 +1512,13 @@ __ieee80211_newstate(struct ieee80211vap
+                       if (arg != 0)
+                               ieee80211_scan_assoc_fail(ic,
+                                       vap->iv_bss->ni_macaddr, arg);
++                      ieee80211_node_leave(vap->iv_bss);
+                       if (ic->ic_roaming == IEEE80211_ROAMING_AUTO)
+                               ieee80211_check_scan(vap,
+                                       IEEE80211_SCAN_ACTIVE,
+                                       IEEE80211_SCAN_FOREVER,
+                                       vap->iv_des_nssid, vap->iv_des_ssid,
+                                       NULL);
+-                      else
+-                              ieee80211_node_leave(vap->iv_bss);
+                       break;
+               case IEEE80211_S_RUN:           /* beacon miss */
+                       if (vap->iv_opmode == IEEE80211_M_STA) {
diff --git a/package/madwifi/patches/448-beacon_handling_fixes.patch b/package/madwifi/patches/448-beacon_handling_fixes.patch
new file mode 100644 (file)
index 0000000..7fe1251
--- /dev/null
@@ -0,0 +1,151 @@
+--- a/ath/if_ath.c
++++ b/ath/if_ath.c
+@@ -512,7 +512,7 @@ MODULE_PARM_DESC(ieee80211_debug, "Load-
+  * and use the higher bits as the index of the VAP.
+  */
+ #define ATH_SET_VAP_BSSID_MASK(bssid_mask)                            \
+-      ((bssid_mask)[0] &= ~(((ath_maxvaps-1) << 2) | 0x02))
++      ((bssid_mask)[0] &= ~(((ATH_MAXVAPS_MAX-1) << 2) | 0x02))
+ #define ATH_GET_VAP_ID(bssid)                   ((bssid)[0] >> 2)
+ #define ATH_SET_VAP_BSSID(bssid, id)                                  \
+               do {                                                    \
+@@ -604,8 +604,8 @@ ath_attach(u_int16_t devid, struct net_d
+       /* Allocate space for dynamically determined maximum VAP count */
+       sc->sc_bslot = 
+-              kmalloc(ath_maxvaps * sizeof(struct ieee80211vap*), GFP_KERNEL);
+-      memset(sc->sc_bslot, 0, ath_maxvaps * sizeof(struct ieee80211vap*));
++              kmalloc(ATH_MAXVAPS_MAX * sizeof(struct ieee80211vap*), GFP_KERNEL);
++      memset(sc->sc_bslot, 0, ATH_MAXVAPS_MAX * sizeof(struct ieee80211vap*));
+       /*
+        * Cache line size is used to size and align various
+@@ -1349,11 +1349,8 @@ ath_vap_create(struct ieee80211com *ic, 
+               return NULL;
+       }
+-      if (sc->sc_nvaps >= ath_maxvaps) {
+-              EPRINTF(sc, "Too many virtual APs (%d already exist).\n", 
+-                              sc->sc_nvaps);
+-              return NULL;
+-      }
++      if ((sc->sc_nvaps >= ath_maxvaps) && (ath_maxvaps < ATH_MAXVAPS_MAX))
++              ath_maxvaps++;
+       dev = alloc_etherdev(sizeof(struct ath_vap) + sc->sc_rc->arc_vap_space);
+       if (dev == NULL) {
+@@ -1451,11 +1448,11 @@ ath_vap_create(struct ieee80211com *ic, 
+               /* Assign the VAP to a beacon xmit slot.  As
+                * above, this cannot fail to find one. */
+               avp->av_bslot = 0;
+-              for (slot = 0; slot < ath_maxvaps; slot++)
++              for (slot = 0; slot < ATH_MAXVAPS_MAX; slot++)
+                       if (sc->sc_bslot[slot] == NULL) {
+                               /* XXX: Hack, space out slots to better
+                                * deal with misses. */
+-                              if (slot + 1 < ath_maxvaps &&
++                              if (slot + 1 < ATH_MAXVAPS_DEFAULT &&
+                                   sc->sc_bslot[slot+1] == NULL) {
+                                       avp->av_bslot = slot + 1;
+                                       break;
+@@ -1463,11 +1460,16 @@ ath_vap_create(struct ieee80211com *ic, 
+                               avp->av_bslot = slot;
+                               /* NB: keep looking for a double slot */
+                       }
+-              KASSERT(sc->sc_bslot[avp->av_bslot] == NULL,
+-                      ("beacon slot %u not empty?", avp->av_bslot));
++
++              /* No beacon slot found? */
++              if (sc->sc_bslot[avp->av_bslot]) {
++                      free_netdev(dev);
++                      return NULL;
++              }
+               sc->sc_bslot[avp->av_bslot] = vap;
+               sc->sc_nbcnvaps++;
++#if 0
+               if ((opmode == IEEE80211_M_HOSTAP) && (sc->sc_hastsfadd)) {
+                       /*
+                        * Multiple VAPs are to transmit beacons and we
+@@ -1485,6 +1487,9 @@ ath_vap_create(struct ieee80211com *ic, 
+                               sc->sc_stagbeacons = 1;
+                       }
+               }
++#else
++              sc->sc_stagbeacons = sc->sc_hastsfadd;
++#endif
+               DPRINTF(sc, ATH_DEBUG_BEACON, "sc->sc_stagbeacons %sabled\n", 
+                               (sc->sc_stagbeacons ? "en" : "dis"));
+       }
+@@ -4968,7 +4973,7 @@ ath_beacon_alloc_internal(struct ath_sof
+                * has a timestamp in one beacon interval while the
+                * others get a timestamp aligned to the next interval.
+                */
+-              tuadjust = (ni->ni_intval * (ath_maxvaps - avp->av_bslot)) / ath_maxvaps;
++              tuadjust = (ni->ni_intval * (ATH_MAXVAPS_DEFAULT - avp->av_bslot)) / ATH_MAXVAPS_DEFAULT;
+               tsfadjust = cpu_to_le64(tuadjust << 10);        /* TU->TSF */
+               DPRINTF(sc, ATH_DEBUG_BEACON,
+@@ -5358,21 +5363,40 @@ ath_beacon_send(struct ath_softc *sc, in
+        */
+       if (sc->sc_stagbeacons) {               /* staggered beacons */
+               struct ieee80211com *ic = &sc->sc_ic;
++              u_int32_t *bflink = NULL;
+               u_int32_t tsftu;
+               tsftu = hw_tsf >> 10; /* NB: 64 -> 32: See note far above. */
+-              slot = ((tsftu % ic->ic_lintval) * ath_maxvaps) / ic->ic_lintval;
+-              vap = sc->sc_bslot[(slot + 1) % ath_maxvaps];
++              slot = ((tsftu % ic->ic_lintval) * ATH_MAXVAPS_DEFAULT) / ic->ic_lintval;
+               DPRINTF(sc, ATH_DEBUG_BEACON_PROC,
+                       "Slot %d [tsf %llu tsftu %llu intval %u] vap %p\n",
+                       slot, (unsigned long long)hw_tsf, 
+                       (unsigned long long)tsftu, ic->ic_lintval, vap);
+               bfaddr = 0;
+-              if (vap != NULL) {
++              while (slot < ATH_MAXVAPS_MAX) {
++                      vap = sc->sc_bslot[slot];
++                      if (vap == NULL)
++                              goto next;
++
+                       bf = ath_beacon_generate(sc, vap, needmark);
+-                      if (bf != NULL)
++                      if (bf == NULL)
++                              break;
++
++                      if (bflink != NULL)
++#ifdef AH_NEED_DESC_SWAP
++                              *bflink = cpu_to_le32(bf->bf_daddr);
++#else
++                              *bflink = bf->bf_daddr;
++#endif
++                      else
+                               bfaddr = bf->bf_daddr;
++
++                      bflink = &bf->bf_desc->ds_link;
++next:
++                      slot += ATH_MAXVAPS_DEFAULT;
+               }
++              if (bflink != NULL)
++                      *bflink = 0;            /* link of last frame */
+       } else {                                /* burst'd beacons */
+               u_int32_t *bflink = NULL;
+@@ -5567,7 +5591,7 @@ ath_beacon_config(struct ath_softc *sc, 
+               /* NB: the beacon interval is kept internally in TUs */
+               intval = ic->ic_lintval & HAL_BEACON_PERIOD;
+               if (sc->sc_stagbeacons)
+-                      intval /= ath_maxvaps;  /* for staggered beacons */
++                      intval /= ATH_MAXVAPS_DEFAULT;  /* for staggered beacons */
+               if ((sc->sc_nostabeacons) &&
+                   (vap->iv_opmode == IEEE80211_M_HOSTAP))
+                       reset_tsf = 1;
+@@ -5889,7 +5913,7 @@ ath_desc_alloc(struct ath_softc *sc)
+       /* XXX allocate beacon state together with VAP */
+       error = ath_descdma_setup(sc, &sc->sc_bdma, &sc->sc_bbuf,
+-                      "beacon", ath_maxvaps, 1);
++                      "beacon", ATH_MAXVAPS_MAX, 1);
+       if (error != 0) {
+               ath_descdma_cleanup(sc, &sc->sc_txdma, &sc->sc_txbuf,
+                       BUS_DMA_TODEVICE);
diff --git a/package/madwifi/patches/449-fix_txbuf_leak.patch b/package/madwifi/patches/449-fix_txbuf_leak.patch
new file mode 100644 (file)
index 0000000..9fd5ecb
--- /dev/null
@@ -0,0 +1,10 @@
+--- a/ath/if_ath.c
++++ b/ath/if_ath.c
+@@ -3725,6 +3725,7 @@ ff_bypass:
+        */
+       skb = ieee80211_encap(ni, skb, &framecnt);
+       if (skb == NULL) {
++              STAILQ_INSERT_TAIL(&bf_head, bf, bf_list);
+               DPRINTF(sc, ATH_DEBUG_XMIT,
+                       "Dropping; encapsulation failure\n");
+               sc->sc_stats.ast_tx_encap++;
diff --git a/package/madwifi/patches/450-calibration.patch b/package/madwifi/patches/450-calibration.patch
new file mode 100644 (file)
index 0000000..76ff7a7
--- /dev/null
@@ -0,0 +1,177 @@
+--- a/ath/if_ath.c
++++ b/ath/if_ath.c
+@@ -396,7 +396,6 @@ static int tpc = 1;
+ static int maxvaps = -1;
+ static int xchanmode = -1;
+ #include "ath_wprobe.c"
+-static int beacon_cal = 1;
+ static const struct ath_hw_detect generic_hw_info = {
+       .vendor_name = "Unknown",
+@@ -431,7 +430,6 @@ static struct notifier_block ath_event_b
+ };
+ #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,52))
+-MODULE_PARM(beacon_cal, "i");
+ MODULE_PARM(maxvaps, "i");
+ MODULE_PARM(xchanmode, "i");
+ MODULE_PARM(rfkill, "i");
+@@ -443,7 +441,6 @@ MODULE_PARM(autocreate, "s");
+ MODULE_PARM(ratectl, "s");
+ #else
+ #include <linux/moduleparam.h>
+-module_param(beacon_cal, int, 0600);
+ module_param(maxvaps, int, 0600);
+ module_param(xchanmode, int, 0600);
+ module_param(rfkill, int, 0600);
+@@ -837,6 +834,7 @@ ath_attach(u_int16_t devid, struct net_d
+               error = EIO;
+               goto bad2;
+       }
++      sc->sc_cal_interval = ath_calinterval;
+       init_timer(&sc->sc_cal_ch);
+       sc->sc_cal_ch.function = ath_calibrate;
+       sc->sc_cal_ch.data = (unsigned long) dev;
+@@ -2765,8 +2763,7 @@ ath_stop_locked(struct net_device *dev)
+               }
+               if (!sc->sc_invalid) {
+                       del_timer_sync(&sc->sc_dfs_cac_timer);
+-                      if (!sc->sc_beacon_cal)
+-                              del_timer_sync(&sc->sc_cal_ch);
++                      del_timer_sync(&sc->sc_cal_ch);
+               }
+               ath_draintxq(sc);
+               if (!sc->sc_invalid) {
+@@ -2791,10 +2788,9 @@ static void ath_set_beacon_cal(struct at
+       if (val) {
+               del_timer_sync(&sc->sc_cal_ch);
+       } else {
+-              sc->sc_cal_ch.expires = jiffies + (ath_calinterval * HZ);
+-              add_timer(&sc->sc_cal_ch);
++              mod_timer(&sc->sc_cal_ch, jiffies + (sc->sc_cal_interval * HZ));
+       }
+-      sc->sc_beacon_cal = !!val && beacon_cal;
++      sc->sc_beacon_cal = !!val;
+ }
+ /*
+@@ -3036,7 +3032,7 @@ ath_reset(struct net_device *dev)
+        * XXX: starting the calibration too early seems to lead to
+        * problems with the beacons.
+        */
+-      sc->sc_lastcal = jiffies;
++      sc->sc_nextcal = jiffies + msecs_to_jiffies(sc->sc_cal_interval * 1000);
+       /*
+        * Convert to a HAL channel description with the flags
+@@ -5477,10 +5473,9 @@ next:
+                       "Invoking ath_hal_txstart with sc_bhalq: %d\n",
+                       sc->sc_bhalq);
+               ath_hal_txstart(ah, sc->sc_bhalq);
+-              if (sc->sc_beacon_cal && (jiffies > sc->sc_lastcal + (ath_calinterval * HZ))) {
+-                      sc->sc_cal_ch.expires = jiffies + msecs_to_jiffies(10);
+-                      add_timer(&sc->sc_cal_ch);
+-              }
++              if (sc->sc_beacon_cal && ((sc->sc_bmisscount == 3) ||
++                  (jiffies > sc->sc_nextcal)))
++                      mod_timer(&sc->sc_cal_ch, jiffies + 1);
+               sc->sc_stats.ast_be_xmit++;             /* XXX per-VAP? */
+       }
+@@ -9161,6 +9156,7 @@ ath_startrecv(struct ath_softc *sc)
+               dev->mtu, sc->sc_cachelsz, sc->sc_rxbufsize);
+       sc->sc_rxlink = NULL;
++      ath_set_beacon_cal(sc, IEEE80211_IS_MODE_BEACON(sc->sc_ic.ic_opmode));
+       STAILQ_FOREACH(bf, &sc->sc_rxbuf, bf_list) {
+               int error = ath_rxbuf_init(sc, bf);
+               ATH_RXBUF_RESET(bf);
+@@ -9377,7 +9373,7 @@ ath_chan_set(struct ath_softc *sc, struc
+                               jiffies + (sc->sc_dfs_cac_period * HZ));
+                       /* This is a good time to start a calibration */
+-                      ath_set_beacon_cal(sc, 1);
++                      mod_timer(&sc->sc_cal_ch, jiffies + 1);
+               }
+               /*
+                * re configure beacons when it is a turbo mode switch.
+@@ -9471,25 +9467,23 @@ ath_calibrate(unsigned long arg)
+       if (isIQdone == AH_TRUE) {
+               /* Unless user has overridden calibration interval,
+                * upgrade to less frequent calibration */
+-              if (ath_calinterval == ATH_SHORT_CALINTERVAL)
+-                      ath_calinterval = ATH_LONG_CALINTERVAL;
++              if (sc->sc_cal_interval == ATH_SHORT_CALINTERVAL)
++                      sc->sc_cal_interval = ATH_LONG_CALINTERVAL;
+       }
+       else {
+               /* Unless user has overridden calibration interval,
+                * downgrade to more frequent calibration */
+-              if (ath_calinterval == ATH_LONG_CALINTERVAL)
+-                      ath_calinterval = ATH_SHORT_CALINTERVAL;
++              if (sc->sc_cal_interval == ATH_LONG_CALINTERVAL)
++                      sc->sc_cal_interval = ATH_SHORT_CALINTERVAL;
+       }
+       DPRINTF(sc, ATH_DEBUG_CALIBRATE, "Channel %u/%x -- IQ %s.\n",
+               sc->sc_curchan.channel, sc->sc_curchan.channelFlags,
+               isIQdone ? "done" : "not done");
+-      sc->sc_lastcal = jiffies;
+-      if (!sc->sc_beacon_cal) {
+-              sc->sc_cal_ch.expires = jiffies + (ath_calinterval * HZ);
+-              add_timer(&sc->sc_cal_ch);
+-      }
++      sc->sc_nextcal = jiffies + msecs_to_jiffies(sc->sc_cal_interval * 1000);
++      if (!sc->sc_beacon_cal)
++              mod_timer(&sc->sc_cal_ch, sc->sc_nextcal);
+ }
+ static void
+@@ -9597,9 +9591,6 @@ ath_newstate(struct ieee80211vap *vap, e
+               ieee80211_state_name[vap->iv_state],
+               ieee80211_state_name[nstate]);
+-      if (!sc->sc_beacon_cal)
+-              del_timer(&sc->sc_cal_ch);              /* periodic calibration timer */
+-
+       ath_hal_setledstate(ah, leds[nstate]);  /* set LED */
+       netif_stop_queue(dev);                  /* before we do anything else */
+@@ -9821,10 +9812,7 @@ ath_newstate(struct ieee80211vap *vap, e
+                               IEEE80211_IS_MODE_DFS_MASTER(vap->iv_opmode)) {
+                       DPRINTF(sc, ATH_DEBUG_STATE | ATH_DEBUG_DOTH, 
+                               "VAP -> DFSWAIT_PENDING \n");
+-                      /* start calibration timer with a really small value 
+-                       * 1/10 sec */
+-                      if (!sc->sc_beacon_cal)
+-                              mod_timer(&sc->sc_cal_ch, jiffies + (HZ/10));
++                      mod_timer(&sc->sc_cal_ch, jiffies + 1);
+                       /* wake the receiver */
+                       netif_wake_queue(dev);
+                       /* don't do the other usual stuff... */
+@@ -9866,12 +9854,6 @@ done:
+       /* Invoke the parent method to complete the work. */
+       error = avp->av_newstate(vap, nstate, arg);
+-      /* Finally, start any timers. */
+-      if (nstate == IEEE80211_S_RUN && !sc->sc_beacon_cal) {
+-              /* start periodic recalibration timer */
+-              mod_timer(&sc->sc_cal_ch, jiffies + (ath_calinterval * HZ));
+-      }
+-
+ #ifdef ATH_SUPERG_XR
+       if (vap->iv_flags & IEEE80211_F_XR &&
+               nstate == IEEE80211_S_RUN)
+--- a/ath/if_athvar.h
++++ b/ath/if_athvar.h
+@@ -834,7 +834,8 @@ struct ath_softc {
+       struct ieee80211_channel *sc_last_chan;
+       int sc_beacon_cal;                      /* use beacon timer for calibration */
+-      u_int64_t sc_lastcal;                   /* last time the calibration was performed */
++      u_int64_t sc_nextcal;                   /* last time the calibration was performed */
++      int sc_cal_interval;                    /* current calibration interval */
+       struct timer_list sc_cal_ch;            /* calibration timer */
+       HAL_NODE_STATS sc_halstats;             /* station-mode rssi stats */