Skip to content

Commit 870abdf

Browse files
Felix Fietkaulinvjw
authored andcommitted
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>
1 parent 76708de commit 870abdf

File tree

7 files changed

+39
-14
lines changed

7 files changed

+39
-14
lines changed

drivers/net/wireless/b43/main.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4588,6 +4588,7 @@ static int b43_wireless_init(struct ssb_device *dev)
45884588
BIT(NL80211_IFTYPE_ADHOC);
45894589

45904590
hw->queues = b43_modparam_qos ? 4 : 1;
4591+
hw->max_altrates = 1;
45914592
SET_IEEE80211_DEV(hw, dev->dev);
45924593
if (is_valid_ether_addr(sprom->et1mac))
45934594
SET_IEEE80211_PERM_ADDR(hw, sprom->et1mac);

drivers/net/wireless/b43/xmit.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -208,7 +208,7 @@ int b43_generate_txhdr(struct b43_wldev *dev,
208208
txrate = ieee80211_get_tx_rate(dev->wl->hw, info);
209209
rate = txrate ? txrate->hw_value : B43_CCK_RATE_1MB;
210210
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;
212212
rate_fb = fbrate->hw_value;
213213
rate_fb_ofdm = b43_is_ofdm_rate(rate_fb);
214214

drivers/net/wireless/b43legacy/main.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3710,6 +3710,7 @@ static int b43legacy_wireless_init(struct ssb_device *dev)
37103710
BIT(NL80211_IFTYPE_WDS) |
37113711
BIT(NL80211_IFTYPE_ADHOC);
37123712
hw->queues = 1; /* FIXME: hardware has more queues */
3713+
hw->max_altrates = 1;
37133714
SET_IEEE80211_DEV(hw, dev->dev);
37143715
if (is_valid_ether_addr(sprom->et1mac))
37153716
SET_IEEE80211_PERM_ADDR(hw, sprom->et1mac);

drivers/net/wireless/b43legacy/xmit.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -210,7 +210,7 @@ static int generate_txhdr_fw3(struct b43legacy_wldev *dev,
210210

211211
rate = tx_rate->hw_value;
212212
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;
214214
rate_fb_ofdm = b43legacy_is_ofdm_rate(rate_fb->hw_value);
215215

216216
txhdr->mac_frame_ctl = wlhdr->frame_control;

drivers/net/wireless/rtl8180_dev.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -292,8 +292,8 @@ static int rtl8180_tx(struct ieee80211_hw *dev, struct sk_buff *skb)
292292
entry->plcp_len = cpu_to_le16(plcp_len);
293293
entry->tx_buf = cpu_to_le32(mapping);
294294
entry->frame_len = cpu_to_le32(skb->len);
295-
entry->flags2 = info->control.alt_retry_rate_idx >= 0 ?
296-
ieee80211_get_alt_retry_rate(dev, info)->bitrate << 4 : 0;
295+
entry->flags2 = info->control.retries[0].rate_idx >= 0 ?
296+
ieee80211_get_alt_retry_rate(dev, info, 0)->bitrate << 4 : 0;
297297
entry->retry_limit = info->control.retry_limit;
298298
entry->flags = cpu_to_le32(tx_flags);
299299
__skb_queue_tail(&ring->queue, skb);
@@ -855,6 +855,7 @@ static int __devinit rtl8180_probe(struct pci_dev *pdev,
855855
priv = dev->priv;
856856
priv->pdev = pdev;
857857

858+
dev->max_altrates = 1;
858859
SET_IEEE80211_DEV(dev, &pdev->dev);
859860
pci_set_drvdata(pdev, dev);
860861

include/net/mac80211.h

Lines changed: 25 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -292,6 +292,20 @@ enum mac80211_tx_control_flags {
292292
#define IEEE80211_TX_INFO_DRIVER_DATA_PTRS \
293293
(IEEE80211_TX_INFO_DRIVER_DATA_SIZE / sizeof(void *))
294294

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+
295309
/**
296310
* struct ieee80211_tx_info - skb transmit information
297311
*
@@ -335,12 +349,14 @@ struct ieee80211_tx_info {
335349
struct ieee80211_key_conf *hw_key;
336350
struct ieee80211_sta *sta;
337351
unsigned long jiffies;
338-
s8 rts_cts_rate_idx, alt_retry_rate_idx;
352+
s8 rts_cts_rate_idx;
339353
u8 retry_limit;
354+
struct ieee80211_tx_altrate retries[IEEE80211_TX_MAX_ALTRATE];
340355
} control;
341356
struct {
342357
u64 ampdu_ack_map;
343358
int ack_signal;
359+
struct ieee80211_tx_altrate retries[IEEE80211_TX_MAX_ALTRATE + 1];
344360
u8 retry_count;
345361
bool excessive_retries;
346362
u8 ampdu_ack_len;
@@ -828,6 +844,9 @@ enum ieee80211_hw_flags {
828844
* within &struct ieee80211_vif.
829845
* @sta_data_size: size (in bytes) of the drv_priv data area
830846
* 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
831850
*/
832851
struct ieee80211_hw {
833852
struct ieee80211_conf conf;
@@ -844,6 +863,8 @@ struct ieee80211_hw {
844863
u16 ampdu_queues;
845864
u16 max_listen_interval;
846865
s8 max_signal;
866+
u8 max_altrates;
867+
u8 max_altrate_tries;
847868
};
848869

849870
struct ieee80211_hw *wiphy_to_hw(struct wiphy *wiphy);
@@ -900,11 +921,11 @@ ieee80211_get_rts_cts_rate(const struct ieee80211_hw *hw,
900921

901922
static inline struct ieee80211_rate *
902923
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)
904925
{
905-
if (c->control.alt_retry_rate_idx < 0)
926+
if (c->control.retries[idx].rate_idx < 0)
906927
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];
908929
}
909930

910931
/**

net/mac80211/tx.c

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -454,15 +454,16 @@ ieee80211_tx_h_rate_ctrl(struct ieee80211_tx_data *tx)
454454
if (unlikely(rsel.probe_idx >= 0)) {
455455
info->flags |= IEEE80211_TX_CTL_RATE_CTRL_PROBE;
456456
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;
458459
tx->rate_idx = rsel.probe_idx;
459-
} else
460-
info->control.alt_retry_rate_idx = -1;
460+
} else if (info->control.retries[0].limit == 0)
461+
info->control.retries[0].rate_idx = -1;
461462

462463
if (unlikely(tx->rate_idx < 0))
463464
return TX_DROP;
464465
} else
465-
info->control.alt_retry_rate_idx = -1;
466+
info->control.retries[0].rate_idx = -1;
466467

467468
if (tx->sdata->bss_conf.use_cts_prot &&
468469
(tx->flags & IEEE80211_TX_FRAGMENTED) && (rsel.nonerp_idx >= 0)) {
@@ -521,7 +522,7 @@ ieee80211_tx_h_misc(struct ieee80211_tx_data *tx)
521522
* frames.
522523
* TODO: The last fragment could still use multiple retry
523524
* rates. */
524-
info->control.alt_retry_rate_idx = -1;
525+
info->control.retries[0].rate_idx = -1;
525526
}
526527

527528
/* Use CTS protection for unicast frames sent using extended rates if
@@ -551,7 +552,7 @@ ieee80211_tx_h_misc(struct ieee80211_tx_data *tx)
551552
int idx;
552553

553554
/* 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;
555556

556557
/* Use min(data rate, max base rate) as CTS/RTS rate */
557558
rate = &sband->bitrates[tx->rate_idx];

0 commit comments

Comments
 (0)