mirror of
https://github.com/proski/madwifi
synced 2024-11-21 22:11:32 +03:00
Move slot-time, CTS/RTS, and ACK timeout calculations into the driver. Corrected logic for the relationships between slot time and cts timeout and ack timeout have been added and the athctrl now delegates to the driver instead.
You can override: - slottime - ctstimeout - acktimeout acktimeout and ctstimeout will be selected from the first available of: 1) the explicitly specified override value [if present] 2) a value derived from an explicitly specified slottime [if present] 3) the HALs default behavior / standard settings for the PHY mode Setting the distance is shorthand for updating the slottime, and both cts and ack timeout values based upon the usual equations for air propagation, speed of light, etc..etc.. git-svn-id: http://madwifi-project.org/svn/madwifi/trunk@3508 0192ed92-7a03-0410-a25b-9323aeb14dbd
This commit is contained in:
parent
cee1c3f7f9
commit
afadc9b41d
217
ath/if_ath.c
217
ath/if_ath.c
@ -148,6 +148,8 @@ static void ath_key_update_begin(struct ieee80211vap *);
|
||||
static void ath_key_update_end(struct ieee80211vap *);
|
||||
static void ath_mode_init(struct net_device *);
|
||||
static void ath_setslottime(struct ath_softc *);
|
||||
static void ath_setctstimeout(struct ath_softc *);
|
||||
static void ath_setacktimeout(struct ath_softc *);
|
||||
static void ath_updateslot(struct net_device *);
|
||||
static int ath_beaconq_setup(struct ath_softc *);
|
||||
static int ath_beacon_alloc(struct ath_softc *, struct ieee80211_node *);
|
||||
@ -4231,10 +4233,61 @@ ath_mode_init(struct net_device *dev)
|
||||
rfilt, mfilt[0], mfilt[1]);
|
||||
}
|
||||
|
||||
static inline int
|
||||
ath_slottime2timeout(struct ath_softc *sc, int slottime)
|
||||
{
|
||||
/* HAL seems to use a constant of 8 for OFDM overhead and 18 for
|
||||
* CCK overhead.
|
||||
*
|
||||
* XXX: Update based on emperical evidence (potentially save 15us per timeout)
|
||||
*/
|
||||
if (((sc->sc_curchan.channelFlags & IEEE80211_CHAN_A) == IEEE80211_CHAN_A) ||
|
||||
(((sc->sc_curchan.channelFlags & IEEE80211_CHAN_108G) == IEEE80211_CHAN_108G) &&
|
||||
(sc->sc_ic.ic_flags & IEEE80211_F_SHSLOT)))
|
||||
{
|
||||
/* short slot time - 802.11a, and 802.11g turbo in turbo mode with short slot time */
|
||||
return (slottime * 2) + 8;
|
||||
}
|
||||
|
||||
/* constant for CCK mib processing time */
|
||||
return (slottime * 2) + 18;
|
||||
}
|
||||
|
||||
#ifndef MAX
|
||||
# define MAX(a, b) (((a) > (b))? (a) : (b))
|
||||
#endif
|
||||
|
||||
static inline int
|
||||
ath_default_ctsack_timeout(struct ath_softc *sc)
|
||||
{
|
||||
struct ath_hal *ah = sc->sc_ah;
|
||||
|
||||
int slottime = sc->sc_slottimeconf;
|
||||
if (slottime <= 0)
|
||||
slottime = ath_hal_getslottime(ah);
|
||||
|
||||
return ath_slottime2timeout(sc, slottime);
|
||||
}
|
||||
|
||||
static inline int
|
||||
ath_getslottime(struct ath_softc *sc) {
|
||||
return ath_hal_getslottime(sc->sc_ah);
|
||||
}
|
||||
|
||||
static inline int
|
||||
ath_getacktimeout(struct ath_softc *sc) {
|
||||
return ath_hal_getacktimeout(sc->sc_ah);
|
||||
}
|
||||
|
||||
static inline int
|
||||
ath_getctstimeout(struct ath_softc *sc) {
|
||||
return ath_hal_getctstimeout(sc->sc_ah);
|
||||
}
|
||||
|
||||
/*
|
||||
* Set the slot time based on the current setting.
|
||||
*/
|
||||
static void
|
||||
static inline void
|
||||
ath_setslottime(struct ath_softc *sc)
|
||||
{
|
||||
struct ieee80211com *ic = &sc->sc_ic;
|
||||
@ -4242,11 +4295,43 @@ ath_setslottime(struct ath_softc *sc)
|
||||
|
||||
if (sc->sc_slottimeconf > 0) /* manual override */
|
||||
ath_hal_setslottime(ah, sc->sc_slottimeconf);
|
||||
else if (sc->sc_dturbo || (sc->sc_curchan.privFlags & CHANNEL_ST))
|
||||
ath_hal_setslottime(ah, HAL_SLOT_TIME_6);
|
||||
else if (ic->ic_flags & IEEE80211_F_SHSLOT)
|
||||
ath_hal_setslottime(ah, HAL_SLOT_TIME_9);
|
||||
else
|
||||
ath_hal_setslottime(ah, HAL_SLOT_TIME_20);
|
||||
sc->sc_updateslot = OK;
|
||||
ath_setacktimeout(sc);
|
||||
ath_setctstimeout(sc);
|
||||
}
|
||||
|
||||
/*
|
||||
* Set the ACK timeout based on the current setting.
|
||||
*/
|
||||
static void
|
||||
ath_setacktimeout(struct ath_softc *sc)
|
||||
{
|
||||
struct ath_hal *ah = sc->sc_ah;
|
||||
|
||||
if (sc->sc_acktimeoutconf > 0) /* manual override */
|
||||
ath_hal_setacktimeout(ah, sc->sc_acktimeoutconf);
|
||||
else
|
||||
ath_hal_setacktimeout(ah, ath_default_ctsack_timeout(sc));
|
||||
}
|
||||
|
||||
/*
|
||||
* Set the CTS timeout based on the current setting.
|
||||
*/
|
||||
static void
|
||||
ath_setctstimeout(struct ath_softc *sc)
|
||||
{
|
||||
struct ath_hal *ah = sc->sc_ah;
|
||||
|
||||
if (sc->sc_ctstimeoutconf > 0) /* manual override */
|
||||
ath_hal_setctstimeout(ah, sc->sc_ctstimeoutconf);
|
||||
else
|
||||
ath_hal_setctstimeout(ah, ath_default_ctsack_timeout(sc));
|
||||
}
|
||||
|
||||
/*
|
||||
@ -10545,8 +10630,71 @@ enum {
|
||||
ATH_RADAR_IGNORED = 25,
|
||||
ATH_MAXVAPS = 26,
|
||||
ATH_INTMIT = 27,
|
||||
ATH_DISTANCE = 28,
|
||||
};
|
||||
|
||||
static inline int
|
||||
ath_ccatime(struct ath_softc *sc)
|
||||
{
|
||||
if (((sc->sc_curchan.channelFlags & IEEE80211_CHAN_PUREG) ==
|
||||
IEEE80211_CHAN_PUREG) &&
|
||||
(sc->sc_ic.ic_flags & IEEE80211_F_SHSLOT))
|
||||
return CCA_PUREG;
|
||||
if ((sc->sc_curchan.channelFlags & IEEE80211_CHAN_A) ==
|
||||
IEEE80211_CHAN_A)
|
||||
return CCA_A;
|
||||
|
||||
return CCA_BG;
|
||||
}
|
||||
|
||||
static inline int
|
||||
ath_estimate_max_distance(struct ath_softc *sc)
|
||||
{
|
||||
/* Prefer overrided, ask HAL if not overridden */
|
||||
int slottime = sc->sc_slottimeconf;
|
||||
if (slottime <= 0)
|
||||
slottime = ath_hal_getslottime(sc->sc_ah);
|
||||
/* NB: We ignore MAC overhead. this function is reverse operation of
|
||||
* ath_distance2slottime, and assumes slottime is CCA + 2x air propagation. */
|
||||
return (slottime - ath_ccatime(sc)) * 150;
|
||||
}
|
||||
|
||||
static inline int
|
||||
ath_distance2slottime(struct ath_softc *sc, int distance)
|
||||
{
|
||||
|
||||
/* Allowance for air propagation (roundtrip time) should be at least
|
||||
* 5us per the standards.
|
||||
*
|
||||
* So let's set a minimum distance to accomodate this:
|
||||
*
|
||||
* roundtrip time = ( ( distance / speed_of_light ) * 2 )
|
||||
*
|
||||
* distance = ( (time * 300 ) / 2) or ((5 * 300) / 2) = 750 m
|
||||
*/
|
||||
int rtdist = distance * 2;
|
||||
int aAirPropagation = (rtdist / 300) + !!(rtdist % 300);
|
||||
if (aAirPropagation < 5) {
|
||||
aAirPropagation = 5;
|
||||
}
|
||||
/* NB: We ignore MAC processing delays... no clue */
|
||||
return ath_ccatime(sc) + aAirPropagation;
|
||||
}
|
||||
|
||||
static inline int
|
||||
ath_distance2timeout(struct ath_softc *sc, int distance)
|
||||
{
|
||||
/* HAL uses a constant of twice slot time plus 18us.
|
||||
* The 18us covers rxtx turnaround, MIB processing, etc.
|
||||
* but the athctrl used to return 2slot+3 so the extra 15us of
|
||||
* timeout is probably just being very careful or taking something into
|
||||
* account that I can't find in the specs.
|
||||
*
|
||||
* XXX: Update based on emperical evidence (potentially save 15us per timeout)
|
||||
*/
|
||||
return ath_slottime2timeout(sc, ath_distance2slottime(sc, distance));
|
||||
}
|
||||
|
||||
static int
|
||||
ATH_SYSCTL_DECL(ath_sysctl_halparam, ctl, write, filp, buffer, lenp, ppos)
|
||||
{
|
||||
@ -10575,25 +10723,75 @@ ATH_SYSCTL_DECL(ath_sysctl_halparam, ctl, write, filp, buffer, lenp, ppos)
|
||||
lenp, ppos);
|
||||
if (ret == 0) {
|
||||
switch ((long)ctl->extra2) {
|
||||
case ATH_DISTANCE:
|
||||
if(val > 0) {
|
||||
sc->sc_slottimeconf = ath_distance2slottime(sc, val);
|
||||
sc->sc_acktimeoutconf = ath_distance2timeout(sc, val);
|
||||
sc->sc_ctstimeoutconf = ath_distance2timeout(sc, val);
|
||||
ath_setslottime(sc);
|
||||
}
|
||||
else {
|
||||
/* disable manual overrides */
|
||||
sc->sc_slottimeconf = 0;
|
||||
sc->sc_ctstimeoutconf = 0;
|
||||
sc->sc_acktimeoutconf = 0;
|
||||
ath_setslottime(sc);
|
||||
}
|
||||
/* Likely changed by the function */
|
||||
val = ath_estimate_max_distance(sc);
|
||||
break;
|
||||
case ATH_SLOTTIME:
|
||||
if (val > 0) {
|
||||
if (!ath_hal_setslottime(ah, val))
|
||||
ret = -EINVAL;
|
||||
else
|
||||
else {
|
||||
int old = sc->sc_slottimeconf;
|
||||
sc->sc_slottimeconf = val;
|
||||
/* overridden slot time invalidates
|
||||
* previous overridden ack/cts
|
||||
* timeouts if it is longer! */
|
||||
if (old && old < sc->sc_slottimeconf) {
|
||||
sc->sc_ctstimeoutconf = 0;
|
||||
sc->sc_acktimeoutconf = 0;
|
||||
ath_setacktimeout(sc);
|
||||
ath_setctstimeout(sc);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
/* disable manual override */
|
||||
sc->sc_slottimeconf = 0;
|
||||
ath_setslottime(sc);
|
||||
}
|
||||
/* Likely changed by the function */
|
||||
val = ath_getslottime(sc);
|
||||
break;
|
||||
case ATH_ACKTIMEOUT:
|
||||
if (val > 0) {
|
||||
if (!ath_hal_setacktimeout(ah, val))
|
||||
ret = -EINVAL;
|
||||
else
|
||||
sc->sc_acktimeoutconf = val;
|
||||
} else {
|
||||
/* disable manual overrider */
|
||||
sc->sc_acktimeoutconf = 0;
|
||||
ath_setacktimeout(sc);
|
||||
}
|
||||
/* Likely changed by the function */
|
||||
val = ath_getacktimeout(sc);
|
||||
break;
|
||||
case ATH_CTSTIMEOUT:
|
||||
if (val > 0) {
|
||||
if (!ath_hal_setctstimeout(ah, val))
|
||||
ret = -EINVAL;
|
||||
else
|
||||
sc->sc_ctstimeoutconf = val;
|
||||
} else {
|
||||
/* disable manual overrides */
|
||||
sc->sc_ctstimeoutconf = 0;
|
||||
ath_setctstimeout(sc);
|
||||
}
|
||||
/* Likely changed by the function */
|
||||
val = ath_getctstimeout(sc);
|
||||
break;
|
||||
case ATH_SOFTLED:
|
||||
if (val != sc->sc_softled) {
|
||||
@ -10757,14 +10955,17 @@ ATH_SYSCTL_DECL(ath_sysctl_halparam, ctl, write, filp, buffer, lenp, ppos)
|
||||
}
|
||||
} else {
|
||||
switch ((long)ctl->extra2) {
|
||||
case ATH_DISTANCE:
|
||||
val = ath_estimate_max_distance(sc);
|
||||
break;
|
||||
case ATH_SLOTTIME:
|
||||
val = ath_hal_getslottime(ah);
|
||||
val = ath_getslottime(sc);
|
||||
break;
|
||||
case ATH_ACKTIMEOUT:
|
||||
val = ath_hal_getacktimeout(ah);
|
||||
val = ath_getacktimeout(sc);
|
||||
break;
|
||||
case ATH_CTSTIMEOUT:
|
||||
val = ath_hal_getctstimeout(ah);
|
||||
val = ath_getctstimeout(sc);
|
||||
break;
|
||||
case ATH_SOFTLED:
|
||||
val = sc->sc_softled;
|
||||
@ -10836,6 +11037,12 @@ static int mincalibrate = 1; /* once a second */
|
||||
static int maxint = 0x7fffffff; /* 32-bit big */
|
||||
|
||||
static const ctl_table ath_sysctl_template[] = {
|
||||
{ .ctl_name = CTL_AUTO,
|
||||
.procname = "distance",
|
||||
.mode = 0644,
|
||||
.proc_handler = ath_sysctl_halparam,
|
||||
.extra2 = (void *)ATH_DISTANCE,
|
||||
},
|
||||
{ .ctl_name = CTL_AUTO,
|
||||
.procname = "slottime",
|
||||
.mode = 0644,
|
||||
|
@ -295,6 +295,12 @@ static inline struct net_device *_alloc_netdev(int sizeof_priv, const char *mask
|
||||
#define GRP_POLL_PERIOD_NO_XR_STA_MAX 100
|
||||
#define GRP_POLL_PERIOD_XR_STA_MAX 30
|
||||
|
||||
enum {
|
||||
CCA_BG = 15,
|
||||
CCA_A = 4,
|
||||
CCA_PUREG = 4, /* pure G */
|
||||
};
|
||||
|
||||
/*
|
||||
* Percentage of the configured poll periodicity
|
||||
*/
|
||||
@ -335,7 +341,6 @@ static inline struct net_device *_alloc_netdev(int sizeof_priv, const char *mask
|
||||
#define MIN_REGISTER_ADDRESS 0x0000 /* PCI register addresses are taken as releative to the appropriate BAR */
|
||||
#define MAX_REGISTER_ADDRESS 0xc000 /* AR5212/AR5213 seems to have a 48k address range */
|
||||
#define MAX_REGISTER_NAME_LEN 32 /* Maximum length of register nicknames in debug output */
|
||||
#define UNKNOWN_NAME "(unknown)" /* Name used when reading/listing undocumented registers */
|
||||
#endif /* #ifdef ATH_REVERSE_ENGINEERING */
|
||||
/*
|
||||
* Convert from net80211 layer values to Ath layer values. Hopefully this will
|
||||
@ -800,6 +805,8 @@ struct ath_softc {
|
||||
u_int32_t sc_dturbo_bw_turbo; /* bandwidth threshold */
|
||||
#endif
|
||||
u_int sc_slottimeconf; /* manual override for slottime */
|
||||
u_int sc_acktimeoutconf; /* manual override for ack timeout */
|
||||
u_int sc_ctstimeoutconf; /* manual override for cts timeout */
|
||||
|
||||
struct timer_list sc_dfs_excl_timer; /* mark expiration timer task */
|
||||
struct timer_list sc_dfs_cac_timer; /* dfs wait timer */
|
||||
|
@ -117,15 +117,9 @@ main(int argc, char *argv[])
|
||||
}
|
||||
|
||||
if (distance >= 0) {
|
||||
int slottime = 9 + (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);
|
||||
setsysctrl(device, "distance", distance);
|
||||
} else
|
||||
usage();
|
||||
return 0;
|
||||
|
Loading…
Reference in New Issue
Block a user