summaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/rt2x00/rt2x00.h
diff options
context:
space:
mode:
authorIvo van Doorn <ivdoorn@gmail.com>2007-10-13 16:26:36 +0200
committerDavid S. Miller <davem@davemloft.net>2008-01-28 15:02:53 -0800
commit69f81a2cac860cf183eb9ef7787525c3552d4612 (patch)
treeb149e55f1e21df8edf33046e662ce8f00834f1ac /drivers/net/wireless/rt2x00/rt2x00.h
parent8de8c5162b157884aa4855564cbfd9ec9119c819 (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.h87
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;
}
/*