summaryrefslogtreecommitdiff
path: root/drivers/net/wireless/rt2x00/rt2x00mac.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/rt2x00/rt2x00mac.c')
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00mac.c65
1 files changed, 65 insertions, 0 deletions
diff --git a/drivers/net/wireless/rt2x00/rt2x00mac.c b/drivers/net/wireless/rt2x00/rt2x00mac.c
index 6d1d383..93bec14 100644
--- a/drivers/net/wireless/rt2x00/rt2x00mac.c
+++ b/drivers/net/wireless/rt2x00/rt2x00mac.c
@@ -738,6 +738,71 @@ void rt2x00mac_flush(struct ieee80211_hw *hw, bool drop)
}
EXPORT_SYMBOL_GPL(rt2x00mac_flush);
+int rt2x00mac_set_antenna(struct ieee80211_hw *hw, u32 tx_ant, u32 rx_ant)
+{
+ struct rt2x00_dev *rt2x00dev = hw->priv;
+ struct link_ant *ant = &rt2x00dev->link.ant;
+ struct antenna_setup *def = &rt2x00dev->default_ant;
+ struct antenna_setup setup;
+
+ // The antenna value is not supposed to be 0,
+ // or exceed the maximum number of antenna's.
+ if (!tx_ant || (tx_ant & ~3) || !rx_ant || (rx_ant & ~3))
+ return -EINVAL;
+
+ // When the client tried to configure the antenna to or from
+ // diversity mode, we must reset the default antenna as well
+ // as that controls the diversity switch.
+ if (ant->flags & ANTENNA_TX_DIVERSITY && tx_ant != 3)
+ ant->flags &= ~ANTENNA_TX_DIVERSITY;
+ if (ant->flags & ANTENNA_RX_DIVERSITY && rx_ant != 3)
+ ant->flags &= ~ANTENNA_RX_DIVERSITY;
+
+ // If diversity is being enabled, check if we need hardware
+ // or software diversity. In the latter case, reset the value,
+ // and make sure we update the antenna flags to have the
+ // link tuner pick up the diversity tuning.
+ if (tx_ant == 3 && def->tx == ANTENNA_SW_DIVERSITY) {
+ tx_ant = ANTENNA_SW_DIVERSITY;
+ ant->flags |= ANTENNA_TX_DIVERSITY;
+ }
+
+ if (rx_ant == 3 && def->rx == ANTENNA_SW_DIVERSITY) {
+ rx_ant = ANTENNA_SW_DIVERSITY;
+ ant->flags |= ANTENNA_RX_DIVERSITY;
+ }
+
+ setup.tx = tx_ant;
+ setup.rx = rx_ant;
+
+ rt2x00lib_config_antenna(rt2x00dev, setup);
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(rt2x00mac_set_antenna);
+
+int rt2x00mac_get_antenna(struct ieee80211_hw *hw, u32 *tx_ant, u32 *rx_ant)
+{
+ struct rt2x00_dev *rt2x00dev = hw->priv;
+ struct link_ant *ant = &rt2x00dev->link.ant;
+ struct antenna_setup *active = &rt2x00dev->link.ant.active;
+
+ // When software diversity is active, we must report this to the
+ // client and not the current active antenna state.
+ if (ant->flags & ANTENNA_TX_DIVERSITY)
+ *tx_ant = ANTENNA_HW_DIVERSITY;
+ else
+ *tx_ant = active->tx;
+
+ if (ant->flags & ANTENNA_RX_DIVERSITY)
+ *rx_ant = ANTENNA_HW_DIVERSITY;
+ else
+ *rx_ant = active->rx;
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(rt2x00mac_get_antenna);
+
void rt2x00mac_get_ringparam(struct ieee80211_hw *hw,
u32 *tx, u32 *tx_max, u32 *rx, u32 *rx_max)
{