diff options
author | Felix Fietkau <nbd@openwrt.org> | 2008-10-05 12:04:24 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2008-10-06 18:14:57 -0400 |
commit | 870abdf67170daa9f1022e55a35c469239fcc74c (patch) | |
tree | 5ca00db880d71149eea2cdaeb67ed20f5281071d | |
parent | 76708dee382a69b2f9d0e50f413f99fefb2dc509 (diff) |
mac80211: add multi-rate retry support
This patch adjusts the rate control API to allow multi-rate retry
if supported by the driver. The ieee80211_hw struct specifies how
many alternate rate selections the driver supports.
Signed-off-by: Felix Fietkau <nbd@openwrt.org>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
-rw-r--r-- | drivers/net/wireless/b43/main.c | 1 | ||||
-rw-r--r-- | drivers/net/wireless/b43/xmit.c | 2 | ||||
-rw-r--r-- | drivers/net/wireless/b43legacy/main.c | 1 | ||||
-rw-r--r-- | drivers/net/wireless/b43legacy/xmit.c | 2 | ||||
-rw-r--r-- | drivers/net/wireless/rtl8180_dev.c | 5 | ||||
-rw-r--r-- | include/net/mac80211.h | 29 | ||||
-rw-r--r-- | net/mac80211/tx.c | 13 |
7 files changed, 39 insertions, 14 deletions
diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c index 3bf74e236ab..14c44df584d 100644 --- a/drivers/net/wireless/b43/main.c +++ b/drivers/net/wireless/b43/main.c | |||
@@ -4588,6 +4588,7 @@ static int b43_wireless_init(struct ssb_device *dev) | |||
4588 | BIT(NL80211_IFTYPE_ADHOC); | 4588 | BIT(NL80211_IFTYPE_ADHOC); |
4589 | 4589 | ||
4590 | hw->queues = b43_modparam_qos ? 4 : 1; | 4590 | hw->queues = b43_modparam_qos ? 4 : 1; |
4591 | hw->max_altrates = 1; | ||
4591 | SET_IEEE80211_DEV(hw, dev->dev); | 4592 | SET_IEEE80211_DEV(hw, dev->dev); |
4592 | if (is_valid_ether_addr(sprom->et1mac)) | 4593 | if (is_valid_ether_addr(sprom->et1mac)) |
4593 | SET_IEEE80211_PERM_ADDR(hw, sprom->et1mac); | 4594 | SET_IEEE80211_PERM_ADDR(hw, sprom->et1mac); |
diff --git a/drivers/net/wireless/b43/xmit.c b/drivers/net/wireless/b43/xmit.c index e0749c0074c..2fabcf8f047 100644 --- a/drivers/net/wireless/b43/xmit.c +++ b/drivers/net/wireless/b43/xmit.c | |||
@@ -208,7 +208,7 @@ int b43_generate_txhdr(struct b43_wldev *dev, | |||
208 | txrate = ieee80211_get_tx_rate(dev->wl->hw, info); | 208 | txrate = ieee80211_get_tx_rate(dev->wl->hw, info); |
209 | rate = txrate ? txrate->hw_value : B43_CCK_RATE_1MB; | 209 | rate = txrate ? txrate->hw_value : B43_CCK_RATE_1MB; |
210 | rate_ofdm = b43_is_ofdm_rate(rate); | 210 | rate_ofdm = b43_is_ofdm_rate(rate); |
211 | fbrate = ieee80211_get_alt_retry_rate(dev->wl->hw, info) ? : txrate; | 211 | fbrate = ieee80211_get_alt_retry_rate(dev->wl->hw, info, 0) ? : txrate; |
212 | rate_fb = fbrate->hw_value; | 212 | rate_fb = fbrate->hw_value; |
213 | rate_fb_ofdm = b43_is_ofdm_rate(rate_fb); | 213 | rate_fb_ofdm = b43_is_ofdm_rate(rate_fb); |
214 | 214 | ||
diff --git a/drivers/net/wireless/b43legacy/main.c b/drivers/net/wireless/b43legacy/main.c index 9fb1421cbec..c66d57560e7 100644 --- a/drivers/net/wireless/b43legacy/main.c +++ b/drivers/net/wireless/b43legacy/main.c | |||
@@ -3710,6 +3710,7 @@ static int b43legacy_wireless_init(struct ssb_device *dev) | |||
3710 | BIT(NL80211_IFTYPE_WDS) | | 3710 | BIT(NL80211_IFTYPE_WDS) | |
3711 | BIT(NL80211_IFTYPE_ADHOC); | 3711 | BIT(NL80211_IFTYPE_ADHOC); |
3712 | hw->queues = 1; /* FIXME: hardware has more queues */ | 3712 | hw->queues = 1; /* FIXME: hardware has more queues */ |
3713 | hw->max_altrates = 1; | ||
3713 | SET_IEEE80211_DEV(hw, dev->dev); | 3714 | SET_IEEE80211_DEV(hw, dev->dev); |
3714 | if (is_valid_ether_addr(sprom->et1mac)) | 3715 | if (is_valid_ether_addr(sprom->et1mac)) |
3715 | SET_IEEE80211_PERM_ADDR(hw, sprom->et1mac); | 3716 | SET_IEEE80211_PERM_ADDR(hw, sprom->et1mac); |
diff --git a/drivers/net/wireless/b43legacy/xmit.c b/drivers/net/wireless/b43legacy/xmit.c index a894169411c..65e83378160 100644 --- a/drivers/net/wireless/b43legacy/xmit.c +++ b/drivers/net/wireless/b43legacy/xmit.c | |||
@@ -210,7 +210,7 @@ static int generate_txhdr_fw3(struct b43legacy_wldev *dev, | |||
210 | 210 | ||
211 | rate = tx_rate->hw_value; | 211 | rate = tx_rate->hw_value; |
212 | rate_ofdm = b43legacy_is_ofdm_rate(rate); | 212 | rate_ofdm = b43legacy_is_ofdm_rate(rate); |
213 | rate_fb = ieee80211_get_alt_retry_rate(dev->wl->hw, info) ? : tx_rate; | 213 | rate_fb = ieee80211_get_alt_retry_rate(dev->wl->hw, info, 0) ? : tx_rate; |
214 | rate_fb_ofdm = b43legacy_is_ofdm_rate(rate_fb->hw_value); | 214 | rate_fb_ofdm = b43legacy_is_ofdm_rate(rate_fb->hw_value); |
215 | 215 | ||
216 | txhdr->mac_frame_ctl = wlhdr->frame_control; | 216 | txhdr->mac_frame_ctl = wlhdr->frame_control; |
diff --git a/drivers/net/wireless/rtl8180_dev.c b/drivers/net/wireless/rtl8180_dev.c index abcd641c54b..df7e78ee8a8 100644 --- a/drivers/net/wireless/rtl8180_dev.c +++ b/drivers/net/wireless/rtl8180_dev.c | |||
@@ -292,8 +292,8 @@ static int rtl8180_tx(struct ieee80211_hw *dev, struct sk_buff *skb) | |||
292 | entry->plcp_len = cpu_to_le16(plcp_len); | 292 | entry->plcp_len = cpu_to_le16(plcp_len); |
293 | entry->tx_buf = cpu_to_le32(mapping); | 293 | entry->tx_buf = cpu_to_le32(mapping); |
294 | entry->frame_len = cpu_to_le32(skb->len); | 294 | entry->frame_len = cpu_to_le32(skb->len); |
295 | entry->flags2 = info->control.alt_retry_rate_idx >= 0 ? | 295 | entry->flags2 = info->control.retries[0].rate_idx >= 0 ? |
296 | ieee80211_get_alt_retry_rate(dev, info)->bitrate << 4 : 0; | 296 | ieee80211_get_alt_retry_rate(dev, info, 0)->bitrate << 4 : 0; |
297 | entry->retry_limit = info->control.retry_limit; | 297 | entry->retry_limit = info->control.retry_limit; |
298 | entry->flags = cpu_to_le32(tx_flags); | 298 | entry->flags = cpu_to_le32(tx_flags); |
299 | __skb_queue_tail(&ring->queue, skb); | 299 | __skb_queue_tail(&ring->queue, skb); |
@@ -855,6 +855,7 @@ static int __devinit rtl8180_probe(struct pci_dev *pdev, | |||
855 | priv = dev->priv; | 855 | priv = dev->priv; |
856 | priv->pdev = pdev; | 856 | priv->pdev = pdev; |
857 | 857 | ||
858 | dev->max_altrates = 1; | ||
858 | SET_IEEE80211_DEV(dev, &pdev->dev); | 859 | SET_IEEE80211_DEV(dev, &pdev->dev); |
859 | pci_set_drvdata(pdev, dev); | 860 | pci_set_drvdata(pdev, dev); |
860 | 861 | ||
diff --git a/include/net/mac80211.h b/include/net/mac80211.h index feb3be81dfa..5617a1613c9 100644 --- a/include/net/mac80211.h +++ b/include/net/mac80211.h | |||
@@ -292,6 +292,20 @@ enum mac80211_tx_control_flags { | |||
292 | #define IEEE80211_TX_INFO_DRIVER_DATA_PTRS \ | 292 | #define IEEE80211_TX_INFO_DRIVER_DATA_PTRS \ |
293 | (IEEE80211_TX_INFO_DRIVER_DATA_SIZE / sizeof(void *)) | 293 | (IEEE80211_TX_INFO_DRIVER_DATA_SIZE / sizeof(void *)) |
294 | 294 | ||
295 | /* maximum number of alternate rate retry stages */ | ||
296 | #define IEEE80211_TX_MAX_ALTRATE 3 | ||
297 | |||
298 | /** | ||
299 | * struct ieee80211_tx_altrate - alternate rate selection/status | ||
300 | * | ||
301 | * @rate_idx: rate index to attempt to send with | ||
302 | * @limit: number of retries before fallback | ||
303 | */ | ||
304 | struct ieee80211_tx_altrate { | ||
305 | s8 rate_idx; | ||
306 | u8 limit; | ||
307 | }; | ||
308 | |||
295 | /** | 309 | /** |
296 | * struct ieee80211_tx_info - skb transmit information | 310 | * struct ieee80211_tx_info - skb transmit information |
297 | * | 311 | * |
@@ -335,12 +349,14 @@ struct ieee80211_tx_info { | |||
335 | struct ieee80211_key_conf *hw_key; | 349 | struct ieee80211_key_conf *hw_key; |
336 | struct ieee80211_sta *sta; | 350 | struct ieee80211_sta *sta; |
337 | unsigned long jiffies; | 351 | unsigned long jiffies; |
338 | s8 rts_cts_rate_idx, alt_retry_rate_idx; | 352 | s8 rts_cts_rate_idx; |
339 | u8 retry_limit; | 353 | u8 retry_limit; |
354 | struct ieee80211_tx_altrate retries[IEEE80211_TX_MAX_ALTRATE]; | ||
340 | } control; | 355 | } control; |
341 | struct { | 356 | struct { |
342 | u64 ampdu_ack_map; | 357 | u64 ampdu_ack_map; |
343 | int ack_signal; | 358 | int ack_signal; |
359 | struct ieee80211_tx_altrate retries[IEEE80211_TX_MAX_ALTRATE + 1]; | ||
344 | u8 retry_count; | 360 | u8 retry_count; |
345 | bool excessive_retries; | 361 | bool excessive_retries; |
346 | u8 ampdu_ack_len; | 362 | u8 ampdu_ack_len; |
@@ -828,6 +844,9 @@ enum ieee80211_hw_flags { | |||
828 | * within &struct ieee80211_vif. | 844 | * within &struct ieee80211_vif. |
829 | * @sta_data_size: size (in bytes) of the drv_priv data area | 845 | * @sta_data_size: size (in bytes) of the drv_priv data area |
830 | * within &struct ieee80211_sta. | 846 | * within &struct ieee80211_sta. |
847 | * | ||
848 | * @max_altrates: maximum number of alternate rate retry stages | ||
849 | * @max_altrate_tries: maximum number of tries for each stage | ||
831 | */ | 850 | */ |
832 | struct ieee80211_hw { | 851 | struct ieee80211_hw { |
833 | struct ieee80211_conf conf; | 852 | struct ieee80211_conf conf; |
@@ -844,6 +863,8 @@ struct ieee80211_hw { | |||
844 | u16 ampdu_queues; | 863 | u16 ampdu_queues; |
845 | u16 max_listen_interval; | 864 | u16 max_listen_interval; |
846 | s8 max_signal; | 865 | s8 max_signal; |
866 | u8 max_altrates; | ||
867 | u8 max_altrate_tries; | ||
847 | }; | 868 | }; |
848 | 869 | ||
849 | struct ieee80211_hw *wiphy_to_hw(struct wiphy *wiphy); | 870 | struct ieee80211_hw *wiphy_to_hw(struct wiphy *wiphy); |
@@ -900,11 +921,11 @@ ieee80211_get_rts_cts_rate(const struct ieee80211_hw *hw, | |||
900 | 921 | ||
901 | static inline struct ieee80211_rate * | 922 | static inline struct ieee80211_rate * |
902 | ieee80211_get_alt_retry_rate(const struct ieee80211_hw *hw, | 923 | ieee80211_get_alt_retry_rate(const struct ieee80211_hw *hw, |
903 | const struct ieee80211_tx_info *c) | 924 | const struct ieee80211_tx_info *c, int idx) |
904 | { | 925 | { |
905 | if (c->control.alt_retry_rate_idx < 0) | 926 | if (c->control.retries[idx].rate_idx < 0) |
906 | return NULL; | 927 | return NULL; |
907 | return &hw->wiphy->bands[c->band]->bitrates[c->control.alt_retry_rate_idx]; | 928 | return &hw->wiphy->bands[c->band]->bitrates[c->control.retries[idx].rate_idx]; |
908 | } | 929 | } |
909 | 930 | ||
910 | /** | 931 | /** |
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c index d7153bbcdb2..1460537faf3 100644 --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c | |||
@@ -454,15 +454,16 @@ ieee80211_tx_h_rate_ctrl(struct ieee80211_tx_data *tx) | |||
454 | if (unlikely(rsel.probe_idx >= 0)) { | 454 | if (unlikely(rsel.probe_idx >= 0)) { |
455 | info->flags |= IEEE80211_TX_CTL_RATE_CTRL_PROBE; | 455 | info->flags |= IEEE80211_TX_CTL_RATE_CTRL_PROBE; |
456 | tx->flags |= IEEE80211_TX_PROBE_LAST_FRAG; | 456 | tx->flags |= IEEE80211_TX_PROBE_LAST_FRAG; |
457 | info->control.alt_retry_rate_idx = tx->rate_idx; | 457 | info->control.retries[0].rate_idx = tx->rate_idx; |
458 | info->control.retries[0].limit = tx->local->hw.max_altrate_tries; | ||
458 | tx->rate_idx = rsel.probe_idx; | 459 | tx->rate_idx = rsel.probe_idx; |
459 | } else | 460 | } else if (info->control.retries[0].limit == 0) |
460 | info->control.alt_retry_rate_idx = -1; | 461 | info->control.retries[0].rate_idx = -1; |
461 | 462 | ||
462 | if (unlikely(tx->rate_idx < 0)) | 463 | if (unlikely(tx->rate_idx < 0)) |
463 | return TX_DROP; | 464 | return TX_DROP; |
464 | } else | 465 | } else |
465 | info->control.alt_retry_rate_idx = -1; | 466 | info->control.retries[0].rate_idx = -1; |
466 | 467 | ||
467 | if (tx->sdata->bss_conf.use_cts_prot && | 468 | if (tx->sdata->bss_conf.use_cts_prot && |
468 | (tx->flags & IEEE80211_TX_FRAGMENTED) && (rsel.nonerp_idx >= 0)) { | 469 | (tx->flags & IEEE80211_TX_FRAGMENTED) && (rsel.nonerp_idx >= 0)) { |
@@ -521,7 +522,7 @@ ieee80211_tx_h_misc(struct ieee80211_tx_data *tx) | |||
521 | * frames. | 522 | * frames. |
522 | * TODO: The last fragment could still use multiple retry | 523 | * TODO: The last fragment could still use multiple retry |
523 | * rates. */ | 524 | * rates. */ |
524 | info->control.alt_retry_rate_idx = -1; | 525 | info->control.retries[0].rate_idx = -1; |
525 | } | 526 | } |
526 | 527 | ||
527 | /* Use CTS protection for unicast frames sent using extended rates if | 528 | /* Use CTS protection for unicast frames sent using extended rates if |
@@ -551,7 +552,7 @@ ieee80211_tx_h_misc(struct ieee80211_tx_data *tx) | |||
551 | int idx; | 552 | int idx; |
552 | 553 | ||
553 | /* Do not use multiple retry rates when using RTS/CTS */ | 554 | /* Do not use multiple retry rates when using RTS/CTS */ |
554 | info->control.alt_retry_rate_idx = -1; | 555 | info->control.retries[0].rate_idx = -1; |
555 | 556 | ||
556 | /* Use min(data rate, max base rate) as CTS/RTS rate */ | 557 | /* Use min(data rate, max base rate) as CTS/RTS rate */ |
557 | rate = &sband->bitrates[tx->rate_idx]; | 558 | rate = &sband->bitrates[tx->rate_idx]; |