aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/net/wireless/rt2x00/rt2400pci.c2
-rw-r--r--drivers/net/wireless/rt2x00/rt2500pci.c2
-rw-r--r--drivers/net/wireless/rt2x00/rt2500usb.c2
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00.h2
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00config.c45
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00link.c10
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00mac.c65
-rw-r--r--drivers/net/wireless/rt2x00/rt61pci.c2
-rw-r--r--drivers/net/wireless/rt2x00/rt73usb.c2
9 files changed, 103 insertions, 29 deletions
diff --git a/drivers/net/wireless/rt2x00/rt2400pci.c b/drivers/net/wireless/rt2x00/rt2400pci.c
index bbe76f79b62e..937f9e8bf05f 100644
--- a/drivers/net/wireless/rt2x00/rt2400pci.c
+++ b/drivers/net/wireless/rt2x00/rt2400pci.c
@@ -1720,6 +1720,8 @@ static const struct ieee80211_ops rt2400pci_mac80211_ops = {
1720 .tx_last_beacon = rt2400pci_tx_last_beacon, 1720 .tx_last_beacon = rt2400pci_tx_last_beacon,
1721 .rfkill_poll = rt2x00mac_rfkill_poll, 1721 .rfkill_poll = rt2x00mac_rfkill_poll,
1722 .flush = rt2x00mac_flush, 1722 .flush = rt2x00mac_flush,
1723 .set_antenna = rt2x00mac_set_antenna,
1724 .get_antenna = rt2x00mac_get_antenna,
1723 .get_ringparam = rt2x00mac_get_ringparam, 1725 .get_ringparam = rt2x00mac_get_ringparam,
1724}; 1726};
1725 1727
diff --git a/drivers/net/wireless/rt2x00/rt2500pci.c b/drivers/net/wireless/rt2x00/rt2500pci.c
index 6f489968e7a4..d27d7b8ba3b6 100644
--- a/drivers/net/wireless/rt2x00/rt2500pci.c
+++ b/drivers/net/wireless/rt2x00/rt2500pci.c
@@ -2013,6 +2013,8 @@ static const struct ieee80211_ops rt2500pci_mac80211_ops = {
2013 .tx_last_beacon = rt2500pci_tx_last_beacon, 2013 .tx_last_beacon = rt2500pci_tx_last_beacon,
2014 .rfkill_poll = rt2x00mac_rfkill_poll, 2014 .rfkill_poll = rt2x00mac_rfkill_poll,
2015 .flush = rt2x00mac_flush, 2015 .flush = rt2x00mac_flush,
2016 .set_antenna = rt2x00mac_set_antenna,
2017 .get_antenna = rt2x00mac_get_antenna,
2016 .get_ringparam = rt2x00mac_get_ringparam, 2018 .get_ringparam = rt2x00mac_get_ringparam,
2017}; 2019};
2018 2020
diff --git a/drivers/net/wireless/rt2x00/rt2500usb.c b/drivers/net/wireless/rt2x00/rt2500usb.c
index 5ef338671d73..b21f81231a09 100644
--- a/drivers/net/wireless/rt2x00/rt2500usb.c
+++ b/drivers/net/wireless/rt2x00/rt2500usb.c
@@ -1823,6 +1823,8 @@ static const struct ieee80211_ops rt2500usb_mac80211_ops = {
1823 .conf_tx = rt2x00mac_conf_tx, 1823 .conf_tx = rt2x00mac_conf_tx,
1824 .rfkill_poll = rt2x00mac_rfkill_poll, 1824 .rfkill_poll = rt2x00mac_rfkill_poll,
1825 .flush = rt2x00mac_flush, 1825 .flush = rt2x00mac_flush,
1826 .set_antenna = rt2x00mac_set_antenna,
1827 .get_antenna = rt2x00mac_get_antenna,
1826 .get_ringparam = rt2x00mac_get_ringparam, 1828 .get_ringparam = rt2x00mac_get_ringparam,
1827}; 1829};
1828 1830
diff --git a/drivers/net/wireless/rt2x00/rt2x00.h b/drivers/net/wireless/rt2x00/rt2x00.h
index f1d8f55d3ca8..acf561f7cde3 100644
--- a/drivers/net/wireless/rt2x00/rt2x00.h
+++ b/drivers/net/wireless/rt2x00/rt2x00.h
@@ -1254,6 +1254,8 @@ int rt2x00mac_conf_tx(struct ieee80211_hw *hw, u16 queue,
1254 const struct ieee80211_tx_queue_params *params); 1254 const struct ieee80211_tx_queue_params *params);
1255void rt2x00mac_rfkill_poll(struct ieee80211_hw *hw); 1255void rt2x00mac_rfkill_poll(struct ieee80211_hw *hw);
1256void rt2x00mac_flush(struct ieee80211_hw *hw, bool drop); 1256void rt2x00mac_flush(struct ieee80211_hw *hw, bool drop);
1257int rt2x00mac_set_antenna(struct ieee80211_hw *hw, u32 tx_ant, u32 rx_ant);
1258int rt2x00mac_get_antenna(struct ieee80211_hw *hw, u32 *tx_ant, u32 *rx_ant);
1257void rt2x00mac_get_ringparam(struct ieee80211_hw *hw, 1259void rt2x00mac_get_ringparam(struct ieee80211_hw *hw,
1258 u32 *tx, u32 *tx_max, u32 *rx, u32 *rx_max); 1260 u32 *tx, u32 *tx_max, u32 *rx, u32 *rx_max);
1259 1261
diff --git a/drivers/net/wireless/rt2x00/rt2x00config.c b/drivers/net/wireless/rt2x00/rt2x00config.c
index f70a2b45d430..2a313b6d378d 100644
--- a/drivers/net/wireless/rt2x00/rt2x00config.c
+++ b/drivers/net/wireless/rt2x00/rt2x00config.c
@@ -109,15 +109,6 @@ void rt2x00lib_config_erp(struct rt2x00_dev *rt2x00dev,
109 rt2x00dev->ops->lib->config_erp(rt2x00dev, &erp, changed); 109 rt2x00dev->ops->lib->config_erp(rt2x00dev, &erp, changed);
110} 110}
111 111
112static inline
113enum antenna rt2x00lib_config_antenna_check(enum antenna current_ant,
114 enum antenna default_ant)
115{
116 if (current_ant != ANTENNA_SW_DIVERSITY)
117 return current_ant;
118 return (default_ant != ANTENNA_SW_DIVERSITY) ? default_ant : ANTENNA_B;
119}
120
121void rt2x00lib_config_antenna(struct rt2x00_dev *rt2x00dev, 112void rt2x00lib_config_antenna(struct rt2x00_dev *rt2x00dev,
122 struct antenna_setup config) 113 struct antenna_setup config)
123{ 114{
@@ -126,19 +117,35 @@ void rt2x00lib_config_antenna(struct rt2x00_dev *rt2x00dev,
126 struct antenna_setup *active = &rt2x00dev->link.ant.active; 117 struct antenna_setup *active = &rt2x00dev->link.ant.active;
127 118
128 /* 119 /*
129 * Failsafe: Make sure we are not sending the 120 * When the caller tries to send the SW diversity,
130 * ANTENNA_SW_DIVERSITY state to the driver. 121 * we must update the ANTENNA_RX_DIVERSITY flag to
131 * If that happens, fallback to hardware defaults, 122 * enable the antenna diversity in the link tuner.
132 * or our own default. 123 *
124 * Secondly, we must guarentee we never send the
125 * software antenna diversity command to the driver.
133 */ 126 */
134 if (!(ant->flags & ANTENNA_RX_DIVERSITY)) 127 if (!(ant->flags & ANTENNA_RX_DIVERSITY)) {
135 config.rx = rt2x00lib_config_antenna_check(config.rx, def->rx); 128 if (config.rx == ANTENNA_SW_DIVERSITY) {
136 else if (config.rx == ANTENNA_SW_DIVERSITY) 129 ant->flags |= ANTENNA_RX_DIVERSITY;
130
131 if (def->rx == ANTENNA_SW_DIVERSITY)
132 config.rx = ANTENNA_B;
133 else
134 config.rx = def->rx;
135 }
136 } else if (config.rx == ANTENNA_SW_DIVERSITY)
137 config.rx = active->rx; 137 config.rx = active->rx;
138 138
139 if (!(ant->flags & ANTENNA_TX_DIVERSITY)) 139 if (!(ant->flags & ANTENNA_TX_DIVERSITY)) {
140 config.tx = rt2x00lib_config_antenna_check(config.tx, def->tx); 140 if (config.tx == ANTENNA_SW_DIVERSITY) {
141 else if (config.tx == ANTENNA_SW_DIVERSITY) 141 ant->flags |= ANTENNA_TX_DIVERSITY;
142
143 if (def->tx == ANTENNA_SW_DIVERSITY)
144 config.tx = ANTENNA_B;
145 else
146 config.tx = def->tx;
147 }
148 } else if (config.tx == ANTENNA_SW_DIVERSITY)
142 config.tx = active->tx; 149 config.tx = active->tx;
143 150
144 /* 151 /*
diff --git a/drivers/net/wireless/rt2x00/rt2x00link.c b/drivers/net/wireless/rt2x00/rt2x00link.c
index ba0bb766e59e..fa55399be192 100644
--- a/drivers/net/wireless/rt2x00/rt2x00link.c
+++ b/drivers/net/wireless/rt2x00/rt2x00link.c
@@ -192,17 +192,7 @@ static bool rt2x00lib_antenna_diversity(struct rt2x00_dev *rt2x00dev)
192 /* 192 /*
193 * Determine if software diversity is enabled for 193 * Determine if software diversity is enabled for
194 * either the TX or RX antenna (or both). 194 * either the TX or RX antenna (or both).
195 * Always perform this check since within the link
196 * tuner interval the configuration might have changed.
197 */ 195 */
198 ant->flags &= ~ANTENNA_RX_DIVERSITY;
199 ant->flags &= ~ANTENNA_TX_DIVERSITY;
200
201 if (rt2x00dev->default_ant.rx == ANTENNA_SW_DIVERSITY)
202 ant->flags |= ANTENNA_RX_DIVERSITY;
203 if (rt2x00dev->default_ant.tx == ANTENNA_SW_DIVERSITY)
204 ant->flags |= ANTENNA_TX_DIVERSITY;
205
206 if (!(ant->flags & ANTENNA_RX_DIVERSITY) && 196 if (!(ant->flags & ANTENNA_RX_DIVERSITY) &&
207 !(ant->flags & ANTENNA_TX_DIVERSITY)) { 197 !(ant->flags & ANTENNA_TX_DIVERSITY)) {
208 ant->flags = 0; 198 ant->flags = 0;
diff --git a/drivers/net/wireless/rt2x00/rt2x00mac.c b/drivers/net/wireless/rt2x00/rt2x00mac.c
index 6d1d38329e52..93bec140e598 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)
738} 738}
739EXPORT_SYMBOL_GPL(rt2x00mac_flush); 739EXPORT_SYMBOL_GPL(rt2x00mac_flush);
740 740
741int rt2x00mac_set_antenna(struct ieee80211_hw *hw, u32 tx_ant, u32 rx_ant)
742{
743 struct rt2x00_dev *rt2x00dev = hw->priv;
744 struct link_ant *ant = &rt2x00dev->link.ant;
745 struct antenna_setup *def = &rt2x00dev->default_ant;
746 struct antenna_setup setup;
747
748 // The antenna value is not supposed to be 0,
749 // or exceed the maximum number of antenna's.
750 if (!tx_ant || (tx_ant & ~3) || !rx_ant || (rx_ant & ~3))
751 return -EINVAL;
752
753 // When the client tried to configure the antenna to or from
754 // diversity mode, we must reset the default antenna as well
755 // as that controls the diversity switch.
756 if (ant->flags & ANTENNA_TX_DIVERSITY && tx_ant != 3)
757 ant->flags &= ~ANTENNA_TX_DIVERSITY;
758 if (ant->flags & ANTENNA_RX_DIVERSITY && rx_ant != 3)
759 ant->flags &= ~ANTENNA_RX_DIVERSITY;
760
761 // If diversity is being enabled, check if we need hardware
762 // or software diversity. In the latter case, reset the value,
763 // and make sure we update the antenna flags to have the
764 // link tuner pick up the diversity tuning.
765 if (tx_ant == 3 && def->tx == ANTENNA_SW_DIVERSITY) {
766 tx_ant = ANTENNA_SW_DIVERSITY;
767 ant->flags |= ANTENNA_TX_DIVERSITY;
768 }
769
770 if (rx_ant == 3 && def->rx == ANTENNA_SW_DIVERSITY) {
771 rx_ant = ANTENNA_SW_DIVERSITY;
772 ant->flags |= ANTENNA_RX_DIVERSITY;
773 }
774
775 setup.tx = tx_ant;
776 setup.rx = rx_ant;
777
778 rt2x00lib_config_antenna(rt2x00dev, setup);
779
780 return 0;
781}
782EXPORT_SYMBOL_GPL(rt2x00mac_set_antenna);
783
784int rt2x00mac_get_antenna(struct ieee80211_hw *hw, u32 *tx_ant, u32 *rx_ant)
785{
786 struct rt2x00_dev *rt2x00dev = hw->priv;
787 struct link_ant *ant = &rt2x00dev->link.ant;
788 struct antenna_setup *active = &rt2x00dev->link.ant.active;
789
790 // When software diversity is active, we must report this to the
791 // client and not the current active antenna state.
792 if (ant->flags & ANTENNA_TX_DIVERSITY)
793 *tx_ant = ANTENNA_HW_DIVERSITY;
794 else
795 *tx_ant = active->tx;
796
797 if (ant->flags & ANTENNA_RX_DIVERSITY)
798 *rx_ant = ANTENNA_HW_DIVERSITY;
799 else
800 *rx_ant = active->rx;
801
802 return 0;
803}
804EXPORT_SYMBOL_GPL(rt2x00mac_get_antenna);
805
741void rt2x00mac_get_ringparam(struct ieee80211_hw *hw, 806void rt2x00mac_get_ringparam(struct ieee80211_hw *hw,
742 u32 *tx, u32 *tx_max, u32 *rx, u32 *rx_max) 807 u32 *tx, u32 *tx_max, u32 *rx, u32 *rx_max)
743{ 808{
diff --git a/drivers/net/wireless/rt2x00/rt61pci.c b/drivers/net/wireless/rt2x00/rt61pci.c
index eb5403108394..9d35ec16a3a5 100644
--- a/drivers/net/wireless/rt2x00/rt61pci.c
+++ b/drivers/net/wireless/rt2x00/rt61pci.c
@@ -2979,6 +2979,8 @@ static const struct ieee80211_ops rt61pci_mac80211_ops = {
2979 .get_tsf = rt61pci_get_tsf, 2979 .get_tsf = rt61pci_get_tsf,
2980 .rfkill_poll = rt2x00mac_rfkill_poll, 2980 .rfkill_poll = rt2x00mac_rfkill_poll,
2981 .flush = rt2x00mac_flush, 2981 .flush = rt2x00mac_flush,
2982 .set_antenna = rt2x00mac_set_antenna,
2983 .get_antenna = rt2x00mac_get_antenna,
2982 .get_ringparam = rt2x00mac_get_ringparam, 2984 .get_ringparam = rt2x00mac_get_ringparam,
2983}; 2985};
2984 2986
diff --git a/drivers/net/wireless/rt2x00/rt73usb.c b/drivers/net/wireless/rt2x00/rt73usb.c
index bf7fea4cb961..a6ce7d6cbdfa 100644
--- a/drivers/net/wireless/rt2x00/rt73usb.c
+++ b/drivers/net/wireless/rt2x00/rt73usb.c
@@ -2310,6 +2310,8 @@ static const struct ieee80211_ops rt73usb_mac80211_ops = {
2310 .get_tsf = rt73usb_get_tsf, 2310 .get_tsf = rt73usb_get_tsf,
2311 .rfkill_poll = rt2x00mac_rfkill_poll, 2311 .rfkill_poll = rt2x00mac_rfkill_poll,
2312 .flush = rt2x00mac_flush, 2312 .flush = rt2x00mac_flush,
2313 .set_antenna = rt2x00mac_set_antenna,
2314 .get_antenna = rt2x00mac_get_antenna,
2313 .get_ringparam = rt2x00mac_get_ringparam, 2315 .get_ringparam = rt2x00mac_get_ringparam,
2314}; 2316};
2315 2317