From: Felix Fietkau Date: Fri, 8 May 2009 19:25:31 +0000 (+0000) Subject: madwifi: clean up handling of various timings such as slot time, ack timeout, eifs... X-Git-Tag: reboot~23655 X-Git-Url: https://git.librecmc.org/?a=commitdiff_plain;h=5bc30de4e7959b9e9639ba2db93e9c09f88072e5;p=oweals%2Fopenwrt.git madwifi: clean up handling of various timings such as slot time, ack timeout, eifs time, etc. SVN-Revision: 15713 --- diff --git a/package/madwifi/Makefile b/package/madwifi/Makefile index f143f94e6e..8db820e5aa 100644 --- a/package/madwifi/Makefile +++ b/package/madwifi/Makefile @@ -151,7 +151,7 @@ ifeq ($(findstring PCI,$(BUS)),PCI) MADWIFI_AUTOLOAD+= ath_pci endif -MADWIFI_APPLETS:=80211stats athchans athctrl athkey athstats wlanconfig ath_info +MADWIFI_APPLETS:=80211stats athchans athkey athstats wlanconfig ath_info ifdef CONFIG_MADWIFI_DEBUG MADWIFI_APPLETS += athdebug 80211debug endif diff --git a/package/madwifi/files/lib/wifi/madwifi.sh b/package/madwifi/files/lib/wifi/madwifi.sh index a3cf4d75e1..1e5b0db4e9 100755 --- a/package/madwifi/files/lib/wifi/madwifi.sh +++ b/package/madwifi/files/lib/wifi/madwifi.sh @@ -219,9 +219,7 @@ enable_atheros() { [ -n "$antrx" ] && sysctl -w dev."$device".rxantenna="$antrx" >&- [ -n "$anttx" ] && sysctl -w dev."$device".txantenna="$anttx" >&- [ -n "$softled" ] && sysctl -w dev."$device".softled="$softled" >&- - - config_get distance "$device" distance - [ -n "$distance" ] && athctrl -i "$device" -d "$distance" >&- + [ -n "$distance" ] && sysctl -w dev."$device".distance="$distance" >&- config_get rate "$vif" rate [ -n "$rate" ] && iwconfig "$ifname" rate "${rate%%.*}" diff --git a/package/madwifi/patches/424-timing.patch b/package/madwifi/patches/424-timing.patch new file mode 100644 index 0000000000..47d08deefa --- /dev/null +++ b/package/madwifi/patches/424-timing.patch @@ -0,0 +1,730 @@ +--- a/ath/if_ath.c ++++ b/ath/if_ath.c +@@ -382,6 +382,7 @@ static u_int32_t ath_set_clamped_maxtxpo + 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); ++static void ath_set_timing(struct ath_softc *sc); + + /* calibrate every 30 secs in steady state but check every second at first. */ + static int ath_calinterval = ATH_SHORT_CALINTERVAL; +@@ -1185,6 +1186,7 @@ ath_attach(u_int16_t devid, struct net_d + sc->sc_intmit = -1; + sc->sc_noise_immunity = -1; + sc->sc_ofdm_weak_det = -1; ++ sc->sc_coverage = 7; /* 2100 meters */ + + return 0; + bad3: +@@ -2672,6 +2674,7 @@ ath_init(struct net_device *dev) + */ + ath_chan_change(sc, ic->ic_curchan); + ath_set_ack_bitrate(sc, sc->sc_ackrate); ++ ath_set_timing(sc); + dev->flags |= IFF_RUNNING; /* we are ready to go */ + ieee80211_start_running(ic); /* start all VAPs */ + #ifdef ATH_TX99_DIAG +@@ -4483,17 +4486,52 @@ ath_mode_init(struct net_device *dev) + * Set the slot time based on the current setting. + */ + static void +-ath_settiming(struct ath_softc *sc) ++ath_set_timing(struct ath_softc *sc) + { ++ struct ieee80211com *ic = &sc->sc_ic; + struct ath_hal *ah = sc->sc_ah; +- u_int offset = getTimingOffset(sc); ++ struct ath_timings *t = &sc->sc_timings; ++ u_int offset = 9; ++ ++ t->sifs = 16; ++ if (IEEE80211_IS_CHAN_ANYG(ic->ic_curchan)) { ++ offset = 20; ++ if (ic->ic_flags & IEEE80211_F_SHSLOT) ++ offset = 9; ++ } else if (IEEE80211_IS_CHAN_A(ic->ic_curchan)) { ++ offset = 9; ++ } ++ ++ if (IEEE80211_IS_CHAN_TURBO(ic->ic_curchan)) { ++ offset = 6; ++ t->sifs = 8; ++ } else if (IEEE80211_IS_CHAN_HALF(ic->ic_curchan)) { ++ offset = 13; ++ t->sifs = 32; ++ } else if (IEEE80211_IS_CHAN_QUARTER(ic->ic_curchan)) { ++ offset = 21; ++ t->sifs = 64; ++ } ++ ++ t->slot = offset + sc->sc_coverage; ++ t->ack = t->slot * 2 + 3; ++ t->cts = t->slot * 2 + 3; + + if (sc->sc_slottimeconf > 0) +- ath_hal_setslottime(ah, offset + sc->sc_slottimeconf); ++ t->slot = sc->sc_slottimeconf; + if (sc->sc_acktimeconf > 0) +- ath_hal_setacktimeout(ah, 2 * offset + sc->sc_acktimeconf); ++ t->ack = sc->sc_acktimeconf; + if (sc->sc_ctstimeconf > 0) +- ath_hal_setctstimeout(ah, 2 * offset + sc->sc_ctstimeconf); ++ t->cts = sc->sc_ctstimeconf; ++ ++ t->difs = 2 * t->sifs + t->slot; ++ t->eifs = t->sifs + t->difs + 3; ++ ++ ath_hal_setslottime(ah, t->slot); ++ ath_hal_setacktimeout(ah, t->ack); ++ ath_hal_setctstimeout(ah, t->cts); ++ ath_hal_seteifstime(ah, t->eifs); ++ + sc->sc_updateslot = OK; + } + +@@ -4515,7 +4553,7 @@ ath_updateslot(struct net_device *dev) + if (ic->ic_opmode == IEEE80211_M_HOSTAP) + sc->sc_updateslot = UPDATE; + else if (dev->flags & IFF_RUNNING) +- ath_settiming(sc); ++ ath_set_timing(sc); + } + + #ifdef ATH_SUPERG_DYNTURBO +@@ -5359,7 +5397,7 @@ ath_beacon_send(struct ath_softc *sc, in + sc->sc_updateslot = COMMIT; /* commit next beacon */ + sc->sc_slotupdate = slot; + } else if ((sc->sc_updateslot == COMMIT) && (sc->sc_slotupdate == slot)) +- ath_settiming(sc); /* commit change to hardware */ ++ ath_set_timing(sc); /* commit change to hardware */ + + if (bfaddr != 0) { + /* +@@ -9429,7 +9467,8 @@ ath_set_coverageclass(struct ieee80211co + { + struct ath_softc *sc = ic->ic_dev->priv; + +- ath_hal_setcoverageclass(sc->sc_ah, ic->ic_coverageclass, 0); ++ sc->sc_coverage = ic->ic_coverageclass * 3; ++ ath_set_timing(sc); + + return; + } +@@ -10950,6 +10989,7 @@ enum { + ATH_OFDM_WEAK_DET = 29, + ATH_CHANBW = 30, + ATH_OUTDOOR = 31, ++ ATH_DISTANCE = 32, + }; + + /* +@@ -11162,21 +11202,31 @@ ATH_SYSCTL_DECL(ath_sysctl_halparam, ctl + sc->sc_slottimeconf = val; + else + sc->sc_slottimeconf = 0; +- ath_settiming(sc); ++ ath_set_timing(sc); + break; + case ATH_ACKTIMEOUT: + if (val > 0) + sc->sc_acktimeconf = val; + else + sc->sc_acktimeconf = 0; +- ath_settiming(sc); ++ ath_set_timing(sc); + break; + case ATH_CTSTIMEOUT: + if (val > 0) + sc->sc_ctstimeconf = val; + else + sc->sc_ctstimeconf = 0; +- ath_settiming(sc); ++ ath_set_timing(sc); ++ break; ++ case ATH_DISTANCE: ++ if (val > 0) { ++ sc->sc_coverage = ((val - 1) / 300) + 1; ++ ic->ic_coverageclass = ((sc->sc_coverage - 1) / 3) + 1; ++ } else { ++ sc->sc_coverage = 0; ++ ic->ic_coverageclass = 0; ++ } ++ ath_set_timing(sc); + break; + case ATH_SOFTLED: + if (val != sc->sc_softled) { +@@ -11332,6 +11382,9 @@ ATH_SYSCTL_DECL(ath_sysctl_halparam, ctl + case ATH_CHANBW: + val = sc->sc_chanbw ?: 20; + break; ++ case ATH_DISTANCE: ++ val = sc->sc_coverage * 300; ++ break; + case ATH_SLOTTIME: + val = ath_hal_getslottime(ah); + break; +@@ -11453,6 +11506,12 @@ static const ctl_table ath_sysctl_templa + .extra2 = (void *)ATH_CTSTIMEOUT, + }, + { .ctl_name = CTL_AUTO, ++ .procname = "distance", ++ .mode = 0644, ++ .proc_handler = ath_sysctl_halparam, ++ .extra2 = (void *)ATH_DISTANCE, ++ }, ++ { .ctl_name = CTL_AUTO, + .procname = "softled", + .mode = 0644, + .proc_handler = ath_sysctl_halparam, +--- a/ath/if_ath_hal.h ++++ b/ath/if_ath_hal.h +@@ -284,6 +284,17 @@ static inline u_int ath_hal_getslottime( + return ret; + } + ++static inline u_int ath_hal_geteifstime(struct ath_hal *ah) ++{ ++ u_int ret; ++ ATH_HAL_LOCK_IRQ(ah->ah_sc); ++ ath_hal_set_function(__func__); ++ ret = ah->ah_getEifsTime(ah); ++ ath_hal_set_function(NULL); ++ ATH_HAL_UNLOCK_IRQ(ah->ah_sc); ++ return ret; ++} ++ + static inline void ath_hal_beaconinit(struct ath_hal *ah, u_int32_t nexttbtt, + u_int32_t intval) + { +@@ -841,6 +852,17 @@ static inline HAL_BOOL ath_hal_setslotti + return ret; + } + ++static inline HAL_BOOL ath_hal_seteifstime(struct ath_hal *ah, u_int a1) ++{ ++ HAL_BOOL ret; ++ ATH_HAL_LOCK_IRQ(ah->ah_sc); ++ ath_hal_set_function(__func__); ++ ret = ah->ah_setEifsTime(ah, a1); ++ ath_hal_set_function(NULL); ++ ATH_HAL_UNLOCK_IRQ(ah->ah_sc); ++ return ret; ++} ++ + static inline void ath_hal_setledstate(struct ath_hal *ah, HAL_LED_STATE a1) + { + ATH_HAL_LOCK_IRQ(ah->ah_sc); +--- a/ath/if_athvar.h ++++ b/ath/if_athvar.h +@@ -613,6 +613,15 @@ struct ath_rp { + int rp_analyzed; + }; + ++struct ath_timings { ++ u_int slot; ++ u_int ack; ++ u_int cts; ++ u_int sifs; ++ u_int difs; ++ u_int eifs; ++}; ++ + struct ath_softc { + struct ieee80211com sc_ic; /* NB: must be first */ + struct net_device *sc_dev; +@@ -838,6 +847,8 @@ struct ath_softc { + * detected radars */ + u_int32_t sc_nexttbtt; + u_int64_t sc_last_tsf; ++ u_int sc_coverage; ++ struct ath_timings sc_timings; + }; + + typedef void (*ath_callback) (struct ath_softc *); +@@ -945,49 +956,76 @@ int ar_device(int devid); + DEV_NAME(_v->iv_ic->ic_dev)) + + void ath_radar_detected(struct ath_softc *sc, const char* message); +-static inline u_int getTimingOffset(struct ath_softc *sc) +-{ +- struct ieee80211com *ic = &sc->sc_ic; +- u_int usec = 9; +- if (IEEE80211_IS_CHAN_ANYG(ic->ic_curchan)) { +- usec = 20; +- if (ic->ic_flags & IEEE80211_F_SHSLOT) +- usec = 9; +- } else if (IEEE80211_IS_CHAN_A(ic->ic_curchan)) +- usec = 9; +- +- if (IEEE80211_IS_CHAN_TURBO(ic->ic_curchan)) +- usec = 6; +- +- if (IEEE80211_IS_CHAN_HALF(ic->ic_curchan)) +- usec = 13; +- else if (IEEE80211_IS_CHAN_QUARTER(ic->ic_curchan)) +- usec = 21; +- return usec; +-} + +-static inline void ath_get_timings(struct ath_softc *sc, u_int *t_slot, u_int *t_sifs, u_int *t_difs) +-{ +- struct ieee80211_channel *c = sc->sc_ic.ic_curchan; ++#ifndef MIN ++#define MIN(a,b) ((a) < (b) ? (a) : (b)) ++#endif ++#ifndef MAX ++#define MAX(a,b) ((a) > (b) ? (a) : (b)) ++#endif + +- *t_slot = getTimingOffset(sc) + sc->sc_slottimeconf; + +- if (IEEE80211_IS_CHAN_HALF(c)) { +- *t_sifs = 32; +- *t_difs = 56; +- } else if (IEEE80211_IS_CHAN_QUARTER(c)) { +- *t_sifs = 64; +- *t_difs = 112; +- } else if (IEEE80211_IS_CHAN_TURBO(c)) { +- *t_sifs = 8; +- *t_difs = 28; +- } else { +- *t_sifs = 16; +- *t_difs = 28; +- } ++/* Calculate the transmit duration of a frame. */ ++static inline unsigned ++calc_usecs_unicast_packet(struct ath_softc *sc, int length, ++ int rix, int short_retries, int long_retries) ++{ ++ const HAL_RATE_TABLE *rt = sc->sc_currates; ++ struct ieee80211com *ic = &sc->sc_ic; ++ struct ath_timings *t = &sc->sc_timings; ++ unsigned int x = 0, tt = 0; ++ unsigned int cix = rt->info[rix].controlRate; ++ int rts = 0, cts = 0; ++ int cw = ATH_DEFAULT_CWMIN; ++ ++ KASSERT(rt != NULL, ("no rate table, mode %u", sc->sc_curmode)); ++ ++ if (!rt->info[rix].rateKbps) { ++ printk(KERN_WARNING "rix %d (%d) bad ratekbps %d mode %u\n", ++ rix, rt->info[rix].dot11Rate, ++ rt->info[rix].rateKbps, ++ sc->sc_curmode); ++ return 0; ++ } ++ ++ if ((ic->ic_flags & IEEE80211_F_USEPROT) && ++ (rt->info[rix].phy == IEEE80211_T_OFDM)) { ++ ++ if (ic->ic_protmode == IEEE80211_PROT_RTSCTS) ++ rts = 1; ++ else if (ic->ic_protmode == IEEE80211_PROT_CTSONLY) ++ cts = 1; ++ ++ cix = rt->info[sc->sc_protrix].controlRate; ++ } ++ ++ if ((rts || cts) && rt->info[cix].rateKbps) { ++ int ctsrate = rt->info[cix].rateCode; ++ int ctsduration = 0; ++ ++ ctsrate |= rt->info[cix].shortPreamble; ++ if (rts) /* SIFS + CTS */ ++ ctsduration += rt->info[cix].spAckDuration; ++ ++ ctsduration += ath_hal_computetxtime(sc->sc_ah, ++ rt, length, rix, AH_TRUE); ++ ++ if (cts) /* SIFS + ACK */ ++ ctsduration += rt->info[cix].spAckDuration; ++ ++ tt += (short_retries + 1) * ctsduration; ++ } ++ tt += t->difs; ++ tt += (long_retries + 1) * (t->sifs + rt->info[rix].spAckDuration); ++ tt += (long_retries + 1) * ath_hal_computetxtime(sc->sc_ah, rt, length, ++ rix, AH_TRUE); ++ for (x = 0; x <= short_retries + long_retries; x++) { ++ cw = MIN(ATH_DEFAULT_CWMAX, (cw + 1) * 2); ++ tt += (t->slot * cw / 2); ++ } ++ return tt; + } + +- + struct ath_hw_detect { + const char *vendor_name; + const char *card_name; +--- a/ath_rate/minstrel/minstrel.c ++++ b/ath_rate/minstrel/minstrel.c +@@ -170,85 +170,6 @@ rate_to_ndx(struct minstrel_node *sn, in + return -1; + } + +-/* Calculate the transmit duration of a frame. */ +-static unsigned +-calc_usecs_unicast_packet(struct ath_softc *sc, int length, +- int rix, int short_retries, int long_retries) +-{ +- const HAL_RATE_TABLE *rt = sc->sc_currates; +- struct ieee80211com *ic = &sc->sc_ic; +- unsigned t_slot = 20; +- unsigned t_difs = 50; +- unsigned t_sifs = 10; +- unsigned int x = 0, tt = 0; +- unsigned int cix = rt->info[rix].controlRate; +- int rts = 0, cts = 0; +- int cw = ATH_DEFAULT_CWMIN; +- +- KASSERT(rt != NULL, ("no rate table, mode %u", sc->sc_curmode)); +- +- if (!rt->info[rix].rateKbps) { +- printk(KERN_WARNING "rix %d (%d) bad ratekbps %d mode %u\n", +- rix, rt->info[rix].dot11Rate, +- rt->info[rix].rateKbps, +- sc->sc_curmode); +- return 0; +- } +- +- ath_get_timings(sc, &t_slot, &t_sifs, &t_difs); +- if ((ic->ic_flags & IEEE80211_F_USEPROT) && +- (rt->info[rix].phy == IEEE80211_T_OFDM)) { +- if (ic->ic_protmode == IEEE80211_PROT_RTSCTS) +- rts = 1; +- else if (ic->ic_protmode == IEEE80211_PROT_CTSONLY) +- cts = 1; +- +- cix = rt->info[sc->sc_protrix].controlRate; +- } +- +-#if 0 +- if (length > ic->ic_rtsthreshold) +- rts = 1; +-#endif +- +- if (rts || cts) { +- int ctsrate = rt->info[cix].rateCode; +- int ctsduration = 0; +- +- if (!rt->info[cix].rateKbps) { +-#if 0 +- printk(KERN_WARNING "cix %d (%d) bad ratekbps %d mode %u\n", +- cix, rt->info[cix].dot11Rate, +- rt->info[cix].rateKbps, +- sc->sc_curmode); +-#endif +- return 0; +- } +- +- +- ctsrate |= rt->info[cix].shortPreamble; +- if (rts) /* SIFS + CTS */ +- ctsduration += rt->info[cix].spAckDuration; +- +- ctsduration += ath_hal_computetxtime(sc->sc_ah, +- rt, length, rix, AH_TRUE); +- +- if (cts) /* SIFS + ACK */ +- ctsduration += rt->info[cix].spAckDuration; +- +- tt += (short_retries + 1) * ctsduration; +- } +- tt += t_difs; +- tt += (long_retries + 1) * (t_sifs + rt->info[rix].spAckDuration); +- tt += (long_retries + 1) * ath_hal_computetxtime(sc->sc_ah, rt, length, +- rix, AH_TRUE); +- for (x = 0; x <= short_retries + long_retries; x++) { +- cw = MIN(ATH_DEFAULT_CWMAX, (cw + 1) * 2); +- tt += (t_slot * cw / 2); +- } +- return tt; +-} +- + static void + ath_rate_node_init(struct ath_softc *sc, struct ath_node *an) + { +--- a/ath_rate/sample/sample.c ++++ b/ath_rate/sample/sample.c +@@ -137,92 +137,6 @@ rate_to_ndx(struct sample_node *sn, int + return -1; + } + +-/* +- * Calculate the transmit duration of a frame. +- */ +-static unsigned +-calc_usecs_unicast_packet(struct ath_softc *sc, int length, +- int rix, int short_retries, int long_retries) +-{ +- const HAL_RATE_TABLE *rt = sc->sc_currates; +- int rts, cts; +- +- unsigned t_slot; +- unsigned t_difs; +- unsigned t_sifs; +- struct ieee80211com *ic = &sc->sc_ic; +- unsigned int tt = 0; +- unsigned int x; +- unsigned int cw = ATH_DEFAULT_CWMIN; +- unsigned int cix = rt->info[rix].controlRate; +- KASSERT(rt != NULL, ("no rate table, mode %u", sc->sc_curmode)); +- +- if (!rt->info[rix].rateKbps) { +- printk(KERN_WARNING "rix %u (%u) bad ratekbps %u mode %u\n", +- rix, rt->info[rix].dot11Rate, +- rt->info[rix].rateKbps, +- sc->sc_curmode); +- +- return 0; +- } +- +- cix = rt->info[rix].controlRate; +- /* +- * XXX getting mac/phy level timings should be fixed for turbo +- * rates, and there is probably a way to get this from the +- * hal... +- */ +- ath_get_timings(sc, &t_slot, &t_sifs, &t_difs); +- rts = cts = 0; +- +- if ((ic->ic_flags & IEEE80211_F_USEPROT) && +- rt->info[rix].phy == IEEE80211_T_OFDM) { +- if (ic->ic_protmode == IEEE80211_PROT_RTSCTS) +- rts = 1; +- else if (ic->ic_protmode == IEEE80211_PROT_CTSONLY) +- cts = 1; +- +- cix = rt->info[sc->sc_protrix].controlRate; +- } +- +- if (0 /*length > ic->ic_rtsthreshold */) +- rts = 1; +- +- if (rts || cts) { +- int ctsrate; +- int ctsduration = 0; +- +- if (!rt->info[cix].rateKbps) { +- printk(KERN_WARNING "cix %u (%u) bad ratekbps %u mode %u\n", +- cix, rt->info[cix].dot11Rate, +- rt->info[cix].rateKbps, +- sc->sc_curmode); +- return 0; +- } +- +- +- ctsrate = rt->info[cix].rateCode | rt->info[cix].shortPreamble; +- if (rts) /* SIFS + CTS */ +- ctsduration += rt->info[cix].spAckDuration; +- +- ctsduration += ath_hal_computetxtime(sc->sc_ah, +- rt, length, rix, AH_TRUE); +- +- if (cts) /* SIFS + ACK */ +- ctsduration += rt->info[cix].spAckDuration; +- +- tt += (short_retries + 1) * ctsduration; +- } +- tt += t_difs; +- tt += (long_retries+1)*(t_sifs + rt->info[rix].spAckDuration); +- tt += (long_retries+1)*ath_hal_computetxtime(sc->sc_ah, rt, length, +- rix, AH_TRUE); +- for (x = 0; x <= short_retries + long_retries; x++) { +- cw = MIN(ATH_DEFAULT_CWMAX, (cw + 1) * 2); +- tt += (t_slot * cw / 2); +- } +- return tt; +-} + + static void + 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 + case IEEE80211_PARAM_COVERAGE_CLASS: + if (value <= IEEE80211_COVERAGE_CLASS_MAX) { + ic->ic_coverageclass = value; ++ ic->ic_set_coverageclass(ic); + if (IS_UP_AUTO(vap)) + ieee80211_new_state(vap, IEEE80211_S_SCAN, 0); + retv = 0; +--- a/net80211/ieee80211_var.h ++++ b/net80211/ieee80211_var.h +@@ -94,7 +94,7 @@ + + #define IEEE80211_BGSCAN_TRIGGER_INTVL 20 /* min trigger interval for thresh based bgscan (secs) */ + +-#define IEEE80211_COVERAGE_CLASS_MAX 31 /* max coverage class */ ++#define IEEE80211_COVERAGE_CLASS_MAX 255 /* max coverage class */ + #define IEEE80211_REGCLASSIDS_MAX 10 /* max regclass id list */ + + #define IEEE80211_PS_SLEEP 0x1 /* STA is in power saving mode */ +--- a/tools/Makefile ++++ b/tools/Makefile +@@ -50,7 +50,7 @@ all: compile + + DEBUG = -DAR_DEBUG + +-ALLPROGS= athstats 80211stats athkey athchans athctrl \ ++ALLPROGS= athstats 80211stats athkey athchans \ + athdebug 80211debug wlanconfig ath_info + + OBJS= $(patsubst %,%.o,$(ALLPROGS)) +--- a/tools/athctrl.c ++++ /dev/null +@@ -1,133 +0,0 @@ +-/*- +- * Copyright (c) 2002-2004 Gunter Burchardt, Local-Web AG +- * All rights reserved. +- * +- * Redistribution and use in source and binary forms, with or without +- * modification, are permitted provided that the following conditions +- * are met: +- * 1. Redistributions of source code must retain the above copyright +- * notice, this list of conditions and the following disclaimer, +- * without modification. +- * 2. Redistributions in binary form must reproduce at minimum a disclaimer +- * similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any +- * redistribution must be conditioned upon including a substantially +- * similar Disclaimer requirement for further binary redistribution. +- * 3. Neither the names of the above-listed copyright holders nor the names +- * of any contributors may be used to endorse or promote products derived +- * from this software without specific prior written permission. +- * +- * Alternatively, this software may be distributed under the terms of the +- * GNU General Public License ("GPL") version 2 as published by the Free +- * Software Foundation. +- * +- * NO WARRANTY +- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +- * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +- * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY +- * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL +- * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, +- * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER +- * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF +- * THE POSSIBILITY OF SUCH DAMAGES. +- * +- * $Id: athctrl.c 2394 2007-05-30 01:41:18Z mtaylor $ +- */ +- +-/* +- * Simple Atheros-specific tool to inspect and set atheros specific values +- * athctrl [-i interface] [-d distance] +- * (default interface is wifi0). +- */ +-#include +-#include +- +-#include +- +-#include +-#include +-#include +-#include +- +-#include +-#include "do_multi.h" +- +-static int +-setsysctrl(const char *dev, const char *control , u_long value) +-{ +- char buffer[256]; +- FILE * fd; +- +- snprintf(buffer, sizeof(buffer), "/proc/sys/dev/%s/%s", dev, control); +- fd = fopen(buffer, "w"); +- if (fd != NULL) { +- fprintf(fd, "%li", value); +- fclose(fd); +- } else +- fprintf(stderr, "Could not open %s for writing!\n", buffer); +- +- return 0; +-} +- +-static void usage(void) +-{ +- fprintf(stderr, +- "Atheros driver control\n" +- "Copyright (c) 2002-2004 Gunter Burchardt, Local-Web AG\n" +- "\n" +- "usage: athctrl [-i interface] [-d distance]\n" +- "\n" +- "options:\n" +- " -h show this usage\n" +- " -i interface (default interface is wifi0)\n" +- " -d specify the maximum distance of a sta or the distance\n" +- " of the master\n"); +- +- exit(1); +-} +- +-int +-CMD(athctrl)(int argc, char *argv[]) +-{ +- char device[IFNAMSIZ + 1]; +- int distance = -1; +- int c; +- +- strncpy(device, "wifi0", sizeof (device)); +- +- for (;;) { +- c = getopt(argc, argv, "d:i:h"); +- if (c < 0) +- break; +- switch (c) { +- case 'h': +- usage(); +- break; +- case 'd': +- distance = atoi(optarg); +- break; +- case 'i': +- strncpy(device, optarg, sizeof (device)); +- break; +- default: +- usage(); +- break; +- } +- } +- +- if (distance >= 0) { +- int slottime = (distance / 300) + ((distance % 300) ? 1 : 0); +- int acktimeout = slottime * 2 + 3; +- int ctstimeout = slottime * 2 + 3; +- +- printf("Setting distance on interface %s to %i meters\n", +- device, distance); +- setsysctrl(device, "slottime", slottime); +- setsysctrl(device, "acktimeout", acktimeout); +- setsysctrl(device, "ctstimeout", ctstimeout); +- } else +- usage(); +- return 0; +-} +--- a/tools/do_multi.c ++++ b/tools/do_multi.c +@@ -18,8 +18,6 @@ main(int argc, char *argv[]) + ret = a80211stats_init(argc, argv); + if(strcmp(progname, "athchans") == 0) + ret = athchans_init(argc, argv); +- if(strcmp(progname, "athctrl") == 0) +- ret = athctrl_init(argc, argv); + #ifdef AR_DEBUG + if(strcmp(progname, "athdebug") == 0) + ret = athdebug_init(argc, argv); +--- a/tools/do_multi.h ++++ b/tools/do_multi.h +@@ -2,7 +2,6 @@ + int a80211debug_init(int argc, char *argv[]); + int a80211stats_init(int argc, char *argv[]); + int athchans_init(int argc, char *argv[]); +-int athctrl_init(int argc, char *argv[]); + int athdebug_init(int argc, char *argv[]); + int athkey_init(int argc, char *argv[]); + int athstats_init(int argc, char *argv[]);