diff options
author | Ivo van Doorn <ivdoorn@gmail.com> | 2007-10-13 16:26:36 +0200 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2008-01-28 15:02:53 -0800 |
commit | 69f81a2cac860cf183eb9ef7787525c3552d4612 (patch) | |
tree | b149e55f1e21df8edf33046e662ce8f00834f1ac /drivers/net/wireless/rt2x00/rt2x00.h | |
parent | 8de8c5162b157884aa4855564cbfd9ec9119c819 (diff) |
[PATCH] rt2x00: Implement SW diversity
When mac80211 indicates that the default antenna setup
should be used _and_ that this default setup is SW_DIVERSITY.
This requires sampling and storing the RSSI per antenna
and check once every 2 seconds to determine if the RSSI
has changed significantly. Once this is the case we should sample
the other antenna for a short period and evaluate if
we need to swap antenna or not.
Signed-off-by: Ivo van Doorn <IvDoorn@gmail.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/wireless/rt2x00/rt2x00.h')
-rw-r--r-- | drivers/net/wireless/rt2x00/rt2x00.h | 87 |
1 files changed, 72 insertions, 15 deletions
diff --git a/drivers/net/wireless/rt2x00/rt2x00.h b/drivers/net/wireless/rt2x00/rt2x00.h index d6f0a72b7a0..e7533e2ccd2 100644 --- a/drivers/net/wireless/rt2x00/rt2x00.h +++ b/drivers/net/wireless/rt2x00/rt2x00.h @@ -241,6 +241,43 @@ struct link_qual { }; /* + * Antenna settings about the currently active link. + */ +struct link_ant { + /* + * Antenna flags + */ + unsigned int flags; +#define ANTENNA_RX_DIVERSITY 0x00000001 +#define ANTENNA_TX_DIVERSITY 0x00000002 +#define ANTENNA_MODE_SAMPLE 0x00000004 + + /* + * Currently active TX/RX antenna setup. + * When software diversity is used, this will indicate + * which antenna is actually used at this time. + */ + struct antenna_setup active; + + /* + * RSSI information for the different antenna's. + * These statistics are used to determine when + * to switch antenna when using software diversity. + * + * rssi[0] -> Antenna A RSSI + * rssi[1] -> Antenna B RSSI + */ + int rssi_history[2]; + + /* + * Current RSSI average of the currently active antenna. + * Similar to the avg_rssi in the link_qual structure + * this value is updated by using the walking average. + */ + int rssi_ant; +}; + +/* * To optimize the quality of the link we need to store * the quality of received frames and periodically * optimize the link. @@ -259,11 +296,9 @@ struct link { struct link_qual qual; /* - * Currently active TX/RX antenna setup. - * When software diversity is used, this will indicate - * which antenna is actually used at this time. + * TX/RX antenna setup. */ - struct antenna_setup active_ant; + struct link_ant ant; /* * Active VGC level @@ -277,25 +312,47 @@ struct link { }; /* - * Update the rssi using the walking average approach. + * Small helper macro to work with moving/walking averages. */ -static inline void rt2x00_update_link_rssi(struct link *link, int rssi) -{ - if (link->qual.avg_rssi) - rssi = ((link->qual.avg_rssi * 7) + rssi) / 8; - link->qual.avg_rssi = rssi; -} +#define MOVING_AVERAGE(__avg, __val, __samples) \ + ( (((__avg) * ((__samples) - 1)) + (__val)) / (__samples) ) + +/* + * When we lack RSSI information return something less then -80 to + * tell the driver to tune the device to maximum sensitivity. + */ +#define DEFAULT_RSSI ( -128 ) /* - * When the avg_rssi is unset or no frames have been received), - * we need to return the default value which needs to be less - * than -80 so the device will select the maximum sensitivity. + * Link quality access functions. */ static inline int rt2x00_get_link_rssi(struct link *link) { if (link->qual.avg_rssi && link->qual.rx_success) return link->qual.avg_rssi; - return -128; + return DEFAULT_RSSI; +} + +static inline int rt2x00_get_link_ant_rssi(struct link *link) +{ + if (link->ant.rssi_ant && link->qual.rx_success) + return link->ant.rssi_ant; + return DEFAULT_RSSI; +} + +static inline int rt2x00_get_link_ant_rssi_history(struct link *link, + enum antenna ant) +{ + if (link->ant.rssi_history[ant - ANTENNA_A]) + return link->ant.rssi_history[ant - ANTENNA_A]; + return DEFAULT_RSSI; +} + +static inline int rt2x00_update_ant_rssi(struct link *link, int rssi) +{ + int old_rssi = link->ant.rssi_history[link->ant.active.rx - ANTENNA_A]; + link->ant.rssi_history[link->ant.active.rx - ANTENNA_A] = rssi; + return old_rssi; } /* |