diff options
Diffstat (limited to 'package/madwifi/patches/389-autochannel.patch')
-rw-r--r-- | package/madwifi/patches/389-autochannel.patch | 249 |
1 files changed, 0 insertions, 249 deletions
diff --git a/package/madwifi/patches/389-autochannel.patch b/package/madwifi/patches/389-autochannel.patch deleted file mode 100644 index 548f09e7d6..0000000000 --- a/package/madwifi/patches/389-autochannel.patch +++ /dev/null @@ -1,249 +0,0 @@ ---- a/ath/if_ath.c -+++ b/ath/if_ath.c -@@ -384,6 +384,7 @@ static u_int32_t ath_get_real_maxtxpower - - static void ath_poll_disable(struct net_device *dev); - static void ath_poll_enable(struct net_device *dev); -+static void ath_fetch_idle_time(struct ath_softc *sc); - - /* calibrate every 30 secs in steady state but check every second at first. */ - static int ath_calinterval = ATH_SHORT_CALINTERVAL; -@@ -2581,6 +2582,7 @@ ath_init(struct net_device *dev) - * be followed by initialization of the appropriate bits - * and then setup of the interrupt mask. - */ -+ ath_fetch_idle_time(sc); - sc->sc_curchan.channel = ic->ic_curchan->ic_freq; - sc->sc_curchan.channelFlags = ath_chan2flags(ic->ic_curchan); - if (!ath_hal_reset(ah, sc->sc_opmode, &sc->sc_curchan, AH_FALSE, &status)) { -@@ -2914,6 +2916,48 @@ ath_hw_check_atim(struct ath_softc *sc, - return 0; - } - -+#define AR5K_MIBC 0x0040 -+#define AR5K_MIBC_FREEZE (1 << 1) -+#define AR5K_TXFC 0x80ec -+#define AR5K_RXFC 0x80f0 -+#define AR5K_RXCLEAR 0x80f4 -+#define AR5K_CYCLES 0x80f8 -+static void -+ath_fetch_idle_time(struct ath_softc *sc) -+{ -+ struct ieee80211com *ic = &sc->sc_ic; -+ struct ath_hal *ah = sc->sc_ah; -+ u_int32_t cc, rx; -+ u_int32_t time = 0; -+ -+ if (sc->sc_ah->ah_macType < 5212) -+ return; -+ -+ if (!ic->ic_curchan || (ic->ic_curchan == IEEE80211_CHAN_ANYC)) -+ return; -+ -+ OS_REG_WRITE(ah, AR5K_MIBC, AR5K_MIBC_FREEZE); -+ rx = OS_REG_READ(ah, AR5K_RXCLEAR); -+ cc = OS_REG_READ(ah, AR5K_CYCLES); -+ -+ if (!cc) -+ return; -+ -+ if (rx > cc) -+ return; /* should not happen */ -+ -+ if (sc->sc_last_chan) -+ sc->sc_last_chan->ic_idletime = 100 * (cc - rx) / cc; -+ sc->sc_last_chan = ic->ic_curchan; -+ -+ OS_REG_WRITE(ah, AR5K_RXCLEAR, 0); -+ OS_REG_WRITE(ah, AR5K_CYCLES, 0); -+ OS_REG_WRITE(ah, AR5K_TXFC, 0); -+ OS_REG_WRITE(ah, AR5K_RXFC, 0); -+ OS_REG_WRITE(ah, AR5K_MIBC, 0); -+} -+#undef AR5K_RXCLEAR -+#undef AR5K_CYCLES - - /* - * Reset the hardware w/o losing operational state. This is -@@ -2941,6 +2985,7 @@ ath_reset(struct net_device *dev) - * Convert to a HAL channel description with the flags - * constrained to reflect the current operating mode. - */ -+ ath_fetch_idle_time(sc); - c = ic->ic_curchan; - sc->sc_curchan.channel = c->ic_freq; - sc->sc_curchan.channelFlags = ath_chan2flags(c); -@@ -9023,6 +9068,7 @@ ath_chan_set(struct ath_softc *sc, struc - u_int8_t channel_change_required = 0; - struct timeval tv; - -+ - /* - * Convert to a HAL channel description with - * the flags constrained to reflect the current -@@ -9031,6 +9077,14 @@ ath_chan_set(struct ath_softc *sc, struc - memset(&hchan, 0, sizeof(HAL_CHANNEL)); - hchan.channel = chan->ic_freq; - hchan.channelFlags = ath_chan2flags(chan); -+ -+ /* don't do duplicate channel changes, but do -+ * store the available idle time */ -+ ath_fetch_idle_time(sc); -+ if ((sc->sc_curchan.channel == hchan.channel) && -+ (sc->sc_curchan.channelFlags == hchan.channelFlags)) -+ return 0; -+ - KASSERT(hchan.channel != 0, - ("bogus channel %u/0x%x", hchan.channel, hchan.channelFlags)); - do_gettimeofday(&tv); ---- a/ath/if_athvar.h -+++ b/ath/if_athvar.h -@@ -774,6 +774,7 @@ struct ath_softc { - struct ieee80211vap **sc_bslot; /* beacon xmit slots */ - int sc_bnext; /* next slot for beacon xmit */ - -+ 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 */ - struct timer_list sc_cal_ch; /* calibration timer */ ---- a/net80211/_ieee80211.h -+++ b/net80211/_ieee80211.h -@@ -148,6 +148,7 @@ struct ieee80211_channel { - int8_t ic_maxpower; /* maximum tx power in dBm */ - int8_t ic_minpower; /* minimum tx power in dBm */ - u_int8_t ic_scanflags; -+ u_int8_t ic_idletime; /* phy idle time in % */ - }; - - #define IEEE80211_CHAN_MAX 255 ---- a/net80211/ieee80211_scan_ap.c -+++ b/net80211/ieee80211_scan_ap.c -@@ -417,6 +417,19 @@ pc_cmp_rssi(struct ap_state *as, struct - - /* This function must be invoked with locks acquired */ - static int -+pc_cmp_idletime(struct ieee80211_channel *a, -+ struct ieee80211_channel *b) -+{ -+ if (!a->ic_idletime || !b->ic_idletime) -+ return 0; -+ -+ /* a is better than b (return < 0) when a has more idle time than b */ -+ return b->ic_idletime - a->ic_idletime; -+} -+ -+ -+/* This function must be invoked with locks acquired */ -+static int - pc_cmp_samechan(struct ieee80211com *ic, struct ieee80211_channel *a, - struct ieee80211_channel *b) - { -@@ -451,6 +464,7 @@ pc_cmp(const void *_a, const void *_b) - - EVALUATE_CRITERION(radar, a, b); - EVALUATE_CRITERION(keepmode, params, a, b); -+ EVALUATE_CRITERION(idletime, a, b); - EVALUATE_CRITERION(sc, ic, a, b); - /* XXX: rssi useless? pick_channel evaluates it anyway */ - EVALUATE_CRITERION(rssi, params->ss->ss_priv, a, b); -@@ -519,16 +533,9 @@ pick_channel(struct ieee80211_scan_state - #endif - - best = NULL; -- best_rssi = 0xff; /* If signal is bigger than 0xff, we'd be melting. */ - - for (i = 0; i < ss_last; i++) { - c = &chans[i]; -- benefit = best_rssi - as->as_maxrssi[c->chan->ic_ieee]; -- sta_assoc = ic->ic_sta_assoc; -- -- /* Don't switch... */ -- if (benefit <= 0) -- continue; - - /* Verify channel is not marked for non-occupancy */ - if (IEEE80211_IS_CHAN_RADAR(c->chan)) -@@ -546,31 +553,8 @@ pick_channel(struct ieee80211_scan_state - break; - } - -- if (sta_assoc != 0) { -- int sl = ic->ic_cn_total - -- ic->ic_chan_nodes[c->chan->ic_ieee]; /* count */ -- if (ic->ic_sc_algorithm == IEEE80211_SC_LOOSE) { -- int sl_max = ic->ic_sc_sldg * benefit; -- sl = 1000 * sl / sta_assoc; /* permil */ -- IEEE80211_DPRINTF(vap, IEEE80211_MSG_SCAN, -- "%s: chan %d, dB gained: %d, " -- "STAs lost: %d permil (max %d)\n", -- __func__, c->chan->ic_ieee, -- benefit, sl, sl_max); -- if (sl > sl_max) -- continue; -- } else if (((ic->ic_sc_algorithm == -- IEEE80211_SC_TIGHT) || -- (ic->ic_sc_algorithm == -- IEEE80211_SC_STRICT)) && -- (sl > 0)) { -- /* Break the loop as the subsequent chans -- * won't be better. */ -- break; -- } -- } - best = c->chan; -- best_rssi = as->as_maxrssi[best->ic_ieee]; -+ break; - } - - if (best != NULL) { -@@ -599,6 +583,9 @@ ap_end(struct ieee80211_scan_state *ss, - ("wrong opmode %u", vap->iv_opmode)); - - ic = vap->iv_ic; -+ -+ /* record stats for the channel that was scanned last */ -+ ic->ic_set_channel(ic); - bestchan = pick_channel(ss, vap, flags); - if (bestchan == NULL) { - if (ss->ss_last > 0) { ---- a/net80211/ieee80211_scan.c -+++ b/net80211/ieee80211_scan.c -@@ -1002,20 +1002,34 @@ ieee80211_scan_add_channels(struct ieee8 - { - struct ieee80211_channel *c, *cg; - u_int modeflags; -+ int has_non_turbo = 0; - int i; - - KASSERT(mode < ARRAY_SIZE(chanflags), ("Unexpected mode %u", mode)); - modeflags = chanflags[mode]; - for (i = 0; i < ic->ic_nchans; i++) { - c = &ic->ic_channels[i]; -+ if (c->ic_flags & (IEEE80211_CHAN_TURBO | IEEE80211_CHAN_STURBO)) -+ continue; -+ -+ has_non_turbo = 1; -+ break; -+ } -+ for (i = 0; i < ic->ic_nchans; i++) { -+ c = &ic->ic_channels[i]; - if (c == NULL || isclr(ic->ic_chan_active, c->ic_ieee)) - continue; - if (c->ic_scanflags & IEEE80211_NOSCAN_SET) - continue; -- if (modeflags && -- ((c->ic_flags & IEEE80211_CHAN_ALLTURBO) != -- (modeflags & IEEE80211_CHAN_ALLTURBO))) -- continue; -+ if (modeflags) { -+ if ((c->ic_flags & IEEE80211_CHAN_ALLTURBO) != -+ (modeflags & IEEE80211_CHAN_ALLTURBO)) -+ continue; -+ } else if (has_non_turbo) { -+ if ((ss->ss_vap->iv_opmode == IEEE80211_M_HOSTAP) && -+ (c->ic_flags & (IEEE80211_CHAN_TURBO | IEEE80211_CHAN_STURBO))) -+ continue; -+ } - if (mode == IEEE80211_MODE_AUTO) { - /* - * XXX special-case 11b/g channels so we select |