aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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++;