aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless
diff options
context:
space:
mode:
authorIvo van Doorn <IvDoorn@gmail.com>2011-04-18 09:35:12 -0400
committerJohn W. Linville <linville@tuxdriver.com>2011-04-19 15:40:07 -0400
commit0ed7b3c04434788ef03d267190c5e9e6e3f8e9ce (patch)
tree4dc8a139189b2988dfa69637685c3f1ba2b2db7e /drivers/net/wireless
parente7dee444263a103a9a2ac5fd5d0b5e9dc177d57c (diff)
rt2x00: Implement get_antenna and set_antenna callback functions
Implement the get_antenna and set_antenna callback functions, which will allow clients to control the antenna for all non-11n hardware (Antenna handling in rt2800 is still a bit magical, so we can't use the set_antenna for those drivers yet). To best support the set_antenna callback some modifications are needed in the diversity handling. We should never look at the default antenna settings to determine if software diversity is enabled. Instead we should set the diversity flag when possible, which will allow the link_tuner to automatically pick up the tuning. Signed-off-by: Ivo van Doorn <IvDoorn@gmail.com> Acked-by: Gertjan van Wingerde <gwingerde@gmail.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless')
-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