mac80211: change rate control API to allow multi-rate retry
Subsystems (2)
RFC PATCH 1/1 mac80211: change rate control API to allow multi-rate retry
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.
include/net/mac80211.h +25 -4
@@ -292,6 +292,20 @@#define IEEE80211_TX_INFO_DRIVER_DATA_PTRS \ (IEEE80211_TX_INFO_DRIVER_DATA_SIZE / sizeof(void *)) +/* maximum number of alternate rate retry stages */ +#define IEEE80211_TX_MAX_ALTRATE 3 + +/** +* struct ieee80211_tx_altrate - alternate rate selection/status +* +* @rate_idx: rate index to attempt to send with +* @limit: number of retries before fallback +*/ +struct ieee80211_tx_altrate { +s8 rate_idx; +u8 limit; +}; +/** * struct ieee80211_tx_info - skb transmit information *
@@ -335,14 +349,16 @@struct ieee80211_key_conf *hw_key;struct ieee80211_sta *sta;unsigned long jiffies; -s8 rts_cts_rate_idx, alt_retry_rate_idx; +s8 rts_cts_rate_idx;u8 retry_limit;u8 icv_len;u8 iv_len; +struct ieee80211_tx_altrate retries[IEEE80211_TX_MAX_ALTRATE ]; } control;struct {u64 ampdu_ack_map;int ack_signal; +struct ieee80211_tx_altrate retries[IEEE80211_TX_MAX_ALTRATE +1 ];u8 retry_count;bool excessive_retries;u8 ampdu_ack_len;
@@ -828,6 +844,9 @@* within &struct ieee80211_vif. * @sta_data_size: size (in bytes) of the drv_priv data area * within &struct ieee80211_sta. +* +* @max_altrates: maximum number of alternate rate retry stages +* @max_altrate_tries: maximum number of tries for each stage */ struct ieee80211_hw {struct ieee80211_conf conf;
@@ -844,6 +863,8 @@u16 ampdu_queues;u16 max_listen_interval;s8 max_signal; +u8 max_altrates; +u8 max_altrate_tries; };struct ieee80211_hw *wiphy_to_hw (struct wiphy *wiphy);
@@ -900,11 +921,11 @@static inline struct ieee80211_rate *ieee80211_get_alt_retry_rate (const struct ieee80211_hw *hw, -const struct ieee80211_tx_info *c) +const struct ieee80211_tx_info *c,int idx) { -if (c->control.alt_retry_rate_idx <0 ) +if (c->control.retries[idx].rate_idx <0 )return NULL ; -return &hw->wiphy->bands[c->band]->bitrates[c->control.alt_retry_rate_idx]; +return &hw->wiphy->bands[c->band]->bitrates[c->control.retries[idx].rate_idx]; }/**
drivers/net/wireless/b43/xmit.c +1 -1
@@ -208,7 +208,7 @@ txrate =ieee80211_get_tx_rate (dev->wl->hw, info); rate = txrate ? txrate->hw_value :B43_CCK_RATE_1MB ; rate_ofdm =b43_is_ofdm_rate (rate); - fbrate =ieee80211_get_alt_retry_rate (dev->wl->hw, info) ? : txrate; + fbrate =ieee80211_get_alt_retry_rate (dev->wl->hw, info,0 ) ? : txrate; rate_fb = fbrate->hw_value; rate_fb_ofdm =b43_is_ofdm_rate (rate_fb);
drivers/net/wireless/b43legacy/xmit.c +1 -1
@@ -210,7 +210,7 @@ rate = tx_rate->hw_value; rate_ofdm =b43legacy_is_ofdm_rate (rate); - rate_fb =ieee80211_get_alt_retry_rate (dev->wl->hw, info) ? : tx_rate; + rate_fb =ieee80211_get_alt_retry_rate (dev->wl->hw, info,0 ) ? : tx_rate; rate_fb_ofdm =b43legacy_is_ofdm_rate (rate_fb->hw_value); txhdr->mac_frame_ctl = wlhdr->frame_control;
drivers/net/wireless/rtl8180_dev.c +2 -2
@@ -292,8 +292,8 @@ entry->plcp_len =cpu_to_le16 (plcp_len); entry->tx_buf =cpu_to_le32 (mapping); entry->frame_len =cpu_to_le32 (skb->len); - entry->flags2 = info->control.alt_retry_rate_idx >=0 ? -ieee80211_get_alt_retry_rate (dev, info)->bitrate <<4 :0 ; + entry->flags2 = info->control.retries[0 ].rate_idx >=0 ? +ieee80211_get_alt_retry_rate (dev, info,0 )->bitrate <<4 :0 ; entry->retry_limit = info->control.retry_limit; entry->flags =cpu_to_le32 (tx_flags);__skb_queue_tail (&ring->queue, skb);
net/mac80211/tx.c +7 -6
@@ -454,15 +454,16 @@if (unlikely (rsel.probe_idx >=0 )) { info->flags |=IEEE80211_TX_CTL_RATE_CTRL_PROBE ; tx->flags |=IEEE80211_TX_PROBE_LAST_FRAG ; - info->control.alt_retry_rate_idx = tx->rate_idx; + info->control.retries[0 ].rate_idx = tx->rate_idx; + info->control.retries[0 ].limit = tx->local->hw.max_altrate_tries; tx->rate_idx = rsel.probe_idx; - }else - info->control.alt_retry_rate_idx =-1 ; + }else if (info->control.retries[0 ].limit ==0 ) + info->control.retries[0 ].rate_idx =-1 ;if (unlikely (tx->rate_idx <0 ))return TX_DROP ; }else - info->control.alt_retry_rate_idx =-1 ; + info->control.retries[0 ].rate_idx =-1 ;if (tx->sdata->bss_conf.use_cts_prot && (tx->flags &IEEE80211_TX_FRAGMENTED ) && (rsel.nonerp_idx >=0 )) {
@@ -521,7 +522,7 @@* frames. * TODO: The last fragment could still use multiple retry * rates. */ - info->control.alt_retry_rate_idx =-1 ; + info->control.retries[0 ].rate_idx =-1 ; }/* Use CTS protection for unicast frames sent using extended rates if
@@ -551,7 +552,7 @@int idx;/* Do not use multiple retry rates when using RTS/CTS */ - info->control.alt_retry_rate_idx =-1 ; + info->control.retries[0 ].rate_idx =-1 ;/* Use min(data rate, max base rate) as CTS/RTS rate */ rate = &sband->bitrates[tx->rate_idx];
Johannes Berg
maintainerQuoted 19 lines · Felix Fietkau
include/net/mac80211.h +14
-0+/* maximum number of alternate rate retry stages */ +#define IEEE80211_TX_MAX_ALTRATE 3 + +/** +* struct ieee80211_tx_altrate - alternate rate selection/status +* +* @rate_idx: rate index to attempt to send with +* @limit: number of retries before fallback +*/ +struct ieee80211_tx_altrate { +s8 rate_idx; +u8 limit; +}; +/** * struct ieee80211_tx_info - skb transmit information *
include/net/mac80211.h line 356
Quoted 9 lines
include/net/mac80211.h +2
-1@@ -335,14 +349,16 @@struct ieee80211_key_conf *hw_key;struct ieee80211_sta *sta;unsigned long jiffies; -s8 rts_cts_rate_idx, alt_retry_rate_idx; +s8 rts_cts_rate_idx;u8 retry_limit;u8 icv_len;u8 iv_len; +struct ieee80211_tx_altrate retries[IEEE80211_TX_MAX_ALTRATE ];
If I'm counting correctly, that struct is now 2 bytes too large, you can cut out retry_limit I'd think by updating drivers to use retries[0].limit though. And iv/icv length can both be removed and added into the key_conf I think.
johannes
Quoted 4 lines · Johannes Berg
If I'm counting correctly, that struct is now 2 bytes too large, you can cut out
retry_limitI'd think by updating drivers to use retries[0].limit though. And iv/icv length can both be removed and added into thekey_confI think.
I'm still using retry_limit as maximum number of retries for the primary rate. The retries[] array only specifies the settings for the alternate rates. If it's only two bytes, then I'll just move over icv_len and iv_len.
- Felix
Johannes Berg
maintainerQuoted 7 lines · Felix Fietkau
Quoted 4 lines · Johannes Berg
If I'm counting correctly, that struct is now 2 bytes too large, you can cut out
retry_limitI'd think by updating drivers to use retries[0].limit though. And iv/icv length can both be removed and added into thekey_confI think.I'm still using
retry_limitas maximum number of retries for the primary rate.
Ah, ok, sure. I guess I thought we were moving to having it all in the array.
Quoted 2 lines
The retries[] array only specifies the settings for the alternate rates. If it's only two bytes, then I'll just move over
icv_lenandiv_len.
I think it's only two bytes, but you can just build a 64-bit config and check that you don't get a build_bug_on :)
johannes