aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/rt2x00
diff options
context:
space:
mode:
authorHelmut Schaa <helmut.schaa@googlemail.com>2010-06-29 15:38:12 -0400
committerJohn W. Linville <linville@tuxdriver.com>2010-06-30 15:00:48 -0400
commit1df90809f79b765fd4e8868c2b182d948f198a17 (patch)
tree2f7d7165d30b6f87f76c25389b4c0e96f9d7066c /drivers/net/wireless/rt2x00
parentf35376a44f7655bcb9a9abea1fbffcde1b80be55 (diff)
rt2x00: Implement tx mpdu aggregation
In order to implement tx mpdu aggregation we only have to implement the ampdu_action callback such that mac80211 allows negotiation of blockack sessions. The hardware will handle everything on its own as long as the ampdu flag in the TXWI struct is set up correctly and we translate the tx status correctly. For now, refuse requests to start rx aggregation. Signed-off-by: Helmut Schaa <helmut.schaa@googlemail.com> Signed-off-by: Ivo van Doorn <IvDoorn@gmail.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/rt2x00')
-rw-r--r--drivers/net/wireless/rt2x00/rt2800lib.c34
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00dev.c15
2 files changed, 48 insertions, 1 deletions
diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c
index 14c361ae87be..14ff706419e4 100644
--- a/drivers/net/wireless/rt2x00/rt2800lib.c
+++ b/drivers/net/wireless/rt2x00/rt2800lib.c
@@ -2499,7 +2499,8 @@ int rt2800_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
2499 IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING | 2499 IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING |
2500 IEEE80211_HW_SIGNAL_DBM | 2500 IEEE80211_HW_SIGNAL_DBM |
2501 IEEE80211_HW_SUPPORTS_PS | 2501 IEEE80211_HW_SUPPORTS_PS |
2502 IEEE80211_HW_PS_NULLFUNC_STACK; 2502 IEEE80211_HW_PS_NULLFUNC_STACK |
2503 IEEE80211_HW_AMPDU_AGGREGATION;
2503 2504
2504 SET_IEEE80211_DEV(rt2x00dev->hw, rt2x00dev->dev); 2505 SET_IEEE80211_DEV(rt2x00dev->hw, rt2x00dev->dev);
2505 SET_IEEE80211_PERM_ADDR(rt2x00dev->hw, 2506 SET_IEEE80211_PERM_ADDR(rt2x00dev->hw,
@@ -2751,6 +2752,36 @@ static u64 rt2800_get_tsf(struct ieee80211_hw *hw)
2751 return tsf; 2752 return tsf;
2752} 2753}
2753 2754
2755static int rt2800_ampdu_action(struct ieee80211_hw *hw,
2756 struct ieee80211_vif *vif,
2757 enum ieee80211_ampdu_mlme_action action,
2758 struct ieee80211_sta *sta,
2759 u16 tid, u16 *ssn)
2760{
2761 struct rt2x00_dev *rt2x00dev = hw->priv;
2762 int ret = 0;
2763
2764 switch (action) {
2765 case IEEE80211_AMPDU_RX_START:
2766 case IEEE80211_AMPDU_RX_STOP:
2767 /* we don't support RX aggregation yet */
2768 ret = -ENOTSUPP;
2769 break;
2770 case IEEE80211_AMPDU_TX_START:
2771 ieee80211_start_tx_ba_cb_irqsafe(vif, sta->addr, tid);
2772 break;
2773 case IEEE80211_AMPDU_TX_STOP:
2774 ieee80211_stop_tx_ba_cb_irqsafe(vif, sta->addr, tid);
2775 break;
2776 case IEEE80211_AMPDU_TX_OPERATIONAL:
2777 break;
2778 default:
2779 WARNING(rt2x00dev, "Unknown AMPDU action\n");
2780 }
2781
2782 return ret;
2783}
2784
2754const struct ieee80211_ops rt2800_mac80211_ops = { 2785const struct ieee80211_ops rt2800_mac80211_ops = {
2755 .tx = rt2x00mac_tx, 2786 .tx = rt2x00mac_tx,
2756 .start = rt2x00mac_start, 2787 .start = rt2x00mac_start,
@@ -2768,6 +2799,7 @@ const struct ieee80211_ops rt2800_mac80211_ops = {
2768 .conf_tx = rt2800_conf_tx, 2799 .conf_tx = rt2800_conf_tx,
2769 .get_tsf = rt2800_get_tsf, 2800 .get_tsf = rt2800_get_tsf,
2770 .rfkill_poll = rt2x00mac_rfkill_poll, 2801 .rfkill_poll = rt2x00mac_rfkill_poll,
2802 .ampdu_action = rt2800_ampdu_action,
2771}; 2803};
2772EXPORT_SYMBOL_GPL(rt2800_mac80211_ops); 2804EXPORT_SYMBOL_GPL(rt2800_mac80211_ops);
2773 2805
diff --git a/drivers/net/wireless/rt2x00/rt2x00dev.c b/drivers/net/wireless/rt2x00/rt2x00dev.c
index 339cc84bf4fb..a914855099b7 100644
--- a/drivers/net/wireless/rt2x00/rt2x00dev.c
+++ b/drivers/net/wireless/rt2x00/rt2x00dev.c
@@ -286,6 +286,21 @@ void rt2x00lib_txdone(struct queue_entry *entry,
286 rt2x00dev->low_level_stats.dot11ACKFailureCount++; 286 rt2x00dev->low_level_stats.dot11ACKFailureCount++;
287 } 287 }
288 288
289 /*
290 * Every single frame has it's own tx status, hence report
291 * every frame as ampdu of size 1.
292 *
293 * TODO: if we can find out how many frames were aggregated
294 * by the hw we could provide the real ampdu_len to mac80211
295 * which would allow the rc algorithm to better decide on
296 * which rates are suitable.
297 */
298 if (tx_info->flags & IEEE80211_TX_CTL_AMPDU) {
299 tx_info->flags |= IEEE80211_TX_STAT_AMPDU;
300 tx_info->status.ampdu_len = 1;
301 tx_info->status.ampdu_ack_len = success ? 1 : 0;
302 }
303
289 if (rate_flags & IEEE80211_TX_RC_USE_RTS_CTS) { 304 if (rate_flags & IEEE80211_TX_RC_USE_RTS_CTS) {
290 if (success) 305 if (success)
291 rt2x00dev->low_level_stats.dot11RTSSuccessCount++; 306 rt2x00dev->low_level_stats.dot11RTSSuccessCount++;