* [PATCH 0/3]: multi-rate retry support for mac80211/ath5k
@ 2008-09-30 11:20 Felix Fietkau
2008-09-30 11:22 ` [PATCH 1/3] mac80211: free up 2 bytes in skb->cb Felix Fietkau
0 siblings, 1 reply; 6+ messages in thread
From: Felix Fietkau @ 2008-09-30 11:20 UTC (permalink / raw)
To: linux-wireless; +Cc: Johannes Berg
Hi,
This is the updated series of my previous mac80211/ath5k patches,
split up for easier review.
- Felix
^ permalink raw reply [flat|nested] 6+ messages in thread
* [PATCH 1/3] mac80211: free up 2 bytes in skb->cb
2008-09-30 11:20 [PATCH 0/3]: multi-rate retry support for mac80211/ath5k Felix Fietkau
@ 2008-09-30 11:22 ` Felix Fietkau
2008-09-30 11:24 ` [PATCH 2/3] mac80211: add multi-rate retry support Felix Fietkau
2008-09-30 18:44 ` [PATCH 1/3] mac80211: free up 2 bytes in skb->cb Johannes Berg
0 siblings, 2 replies; 6+ messages in thread
From: Felix Fietkau @ 2008-09-30 11:22 UTC (permalink / raw)
To: linux-wireless; +Cc: Johannes Berg
Free up 2 bytes in skb->cb to be used for multi-rate retry.
Move iv_len and icv_len initialization into key alloc.
Signed-off-by: Felix Fietkau <nbd@openwrt.org>
--- a/include/net/mac80211.h
+++ b/include/net/mac80211.h
@@ -337,8 +337,6 @@
unsigned long jiffies;
s8 rts_cts_rate_idx, alt_retry_rate_idx;
u8 retry_limit;
- u8 icv_len;
- u8 iv_len;
} control;
struct {
u64 ampdu_ack_map;
@@ -635,6 +633,8 @@
*/
struct ieee80211_key_conf {
enum ieee80211_key_alg alg;
+ u8 icv_len;
+ u8 iv_len;
u8 hw_key_idx;
u8 flags;
s8 keyidx;
--- a/drivers/net/wireless/b43/xmit.c
+++ b/drivers/net/wireless/b43/xmit.c
@@ -252,7 +252,7 @@
}
/* Hardware appends ICV. */
- plcp_fragment_len += info->control.icv_len;
+ plcp_fragment_len += info->control.hw_key->icv_len;
key_idx = b43_kidx_to_fw(dev, key_idx);
mac_ctl |= (key_idx << B43_TXH_MAC_KEYIDX_SHIFT) &
@@ -260,7 +260,7 @@
mac_ctl |= (key->algorithm << B43_TXH_MAC_KEYALG_SHIFT) &
B43_TXH_MAC_KEYALG;
wlhdr_len = ieee80211_hdrlen(fctl);
- iv_len = min((size_t) info->control.iv_len,
+ iv_len = min((size_t) info->control.hw_key->iv_len,
ARRAY_SIZE(txhdr->iv));
memcpy(txhdr->iv, ((u8 *) wlhdr) + wlhdr_len, iv_len);
}
--- a/drivers/net/wireless/b43legacy/xmit.c
+++ b/drivers/net/wireless/b43legacy/xmit.c
@@ -243,7 +243,7 @@
if (key->enabled) {
/* Hardware appends ICV. */
- plcp_fragment_len += info->control.icv_len;
+ plcp_fragment_len += info->control.hw_key->icv_len;
key_idx = b43legacy_kidx_to_fw(dev, key_idx);
mac_ctl |= (key_idx << B43legacy_TX4_MAC_KEYIDX_SHIFT) &
@@ -252,7 +252,7 @@
B43legacy_TX4_MAC_KEYALG_SHIFT) &
B43legacy_TX4_MAC_KEYALG;
wlhdr_len = ieee80211_hdrlen(wlhdr->frame_control);
- iv_len = min((size_t)info->control.iv_len,
+ iv_len = min((size_t)info->control.hw_key->iv_len,
ARRAY_SIZE(txhdr->iv));
memcpy(txhdr->iv, ((u8 *)wlhdr) + wlhdr_len, iv_len);
} else {
--- a/net/mac80211/wep.c
+++ b/net/mac80211/wep.c
@@ -313,9 +313,6 @@
{
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
- info->control.iv_len = WEP_IV_LEN;
- info->control.icv_len = WEP_ICV_LEN;
-
if (!(tx->key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE)) {
if (ieee80211_wep_encrypt(tx->local, skb, tx->key))
return -1;
--- a/net/mac80211/wpa.c
+++ b/net/mac80211/wpa.c
@@ -152,9 +152,6 @@
int len, tail;
u8 *pos;
- info->control.icv_len = TKIP_ICV_LEN;
- info->control.iv_len = TKIP_IV_LEN;
-
if ((tx->key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE) &&
!(tx->key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_IV)) {
/* hwaccel - with no need for preallocated room for IV/ICV */
@@ -374,9 +371,6 @@
u8 *pos, *pn;
int i;
- info->control.icv_len = CCMP_MIC_LEN;
- info->control.iv_len = CCMP_HDR_LEN;
-
if ((tx->key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE) &&
!(tx->key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_IV)) {
/* hwaccel - with no need for preallocated room for CCMP "
--- a/drivers/net/wireless/ath5k/base.c
+++ b/drivers/net/wireless/ath5k/base.c
@@ -1164,7 +1164,7 @@
if (info->control.hw_key) {
keyidx = info->control.hw_key->hw_key_idx;
- pktlen += info->control.icv_len;
+ pktlen += info->control.hw_key->icv_len;
}
ret = ah->ah_setup_tx_desc(ah, ds, pktlen,
ieee80211_get_hdrlen_from_skb(skb), AR5K_PKT_TYPE_NORMAL,
--- a/drivers/net/wireless/ath9k/xmit.c
+++ b/drivers/net/wireless/ath9k/xmit.c
@@ -237,7 +237,7 @@
if (tx_info->control.hw_key) {
txctl->keyix = tx_info->control.hw_key->hw_key_idx;
- txctl->frmlen += tx_info->control.icv_len;
+ txctl->frmlen += tx_info->control.hw_key->icv_len;
if (tx_info->control.hw_key->alg == ALG_WEP)
txctl->keytype = ATH9K_KEY_TYPE_WEP;
--- a/drivers/net/wireless/rt2x00/rt2x00crypto.c
+++ b/drivers/net/wireless/rt2x00/rt2x00crypto.c
@@ -56,10 +56,10 @@
* note that these lengths should only be added when
* mac80211 does not generate it.
*/
- overhead += tx_info->control.icv_len;
+ overhead += key->icv_len;
if (!(key->flags & IEEE80211_KEY_FLAG_GENERATE_IV))
- overhead += tx_info->control.iv_len;
+ overhead += key->iv_len;
if (!(key->flags & IEEE80211_KEY_FLAG_GENERATE_MMIC)) {
if (key->alg == ALG_TKIP)
--- a/drivers/net/wireless/rt2x00/rt2x00queue.c
+++ b/drivers/net/wireless/rt2x00/rt2x00queue.c
@@ -374,7 +374,7 @@
struct queue_entry *entry = rt2x00queue_get_entry(queue, Q_INDEX);
struct txentry_desc txdesc;
struct skb_frame_desc *skbdesc;
- unsigned int iv_len = IEEE80211_SKB_CB(skb)->control.iv_len;
+ unsigned int iv_len;
if (unlikely(rt2x00queue_full(queue)))
return -EINVAL;
@@ -410,8 +410,11 @@
* the frame so we can provide it to the driver seperately.
*/
if (test_bit(ENTRY_TXD_ENCRYPT, &txdesc.flags) &&
- !test_bit(ENTRY_TXD_ENCRYPT_IV, &txdesc.flags))
+ !test_bit(ENTRY_TXD_ENCRYPT_IV, &txdesc.flags) &&
+ (IEEE80211_SKB_CB(skb)->control.hw_key != NULL)) {
+ iv_len = IEEE80211_SKB_CB(skb)->control.hw_key->iv_len;
rt2x00crypto_tx_remove_iv(skb, iv_len);
+ }
/*
* It could be possible that the queue was corrupted and this
--- a/net/mac80211/key.c
+++ b/net/mac80211/key.c
@@ -281,6 +281,20 @@
key->conf.alg = alg;
key->conf.keyidx = idx;
key->conf.keylen = key_len;
+ switch (alg) {
+ case ALG_WEP:
+ key->conf.iv_len = WEP_IV_LEN;
+ key->conf.icv_len = WEP_ICV_LEN;
+ break;
+ case ALG_TKIP:
+ key->conf.iv_len = TKIP_IV_LEN;
+ key->conf.icv_len = TKIP_ICV_LEN;
+ break;
+ case ALG_CCMP:
+ key->conf.iv_len = CCMP_HDR_LEN;
+ key->conf.icv_len = CCMP_MIC_LEN;
+ break;
+ }
memcpy(key->conf.key, key_data, key_len);
INIT_LIST_HEAD(&key->list);
INIT_LIST_HEAD(&key->todo);
^ permalink raw reply [flat|nested] 6+ messages in thread
* [PATCH 2/3] mac80211: add multi-rate retry support
2008-09-30 11:22 ` [PATCH 1/3] mac80211: free up 2 bytes in skb->cb Felix Fietkau
@ 2008-09-30 11:24 ` Felix Fietkau
2008-09-30 11:25 ` [PATCH 3/3] ath5k: implement multi-rate retry support and fix tx status reporting Felix Fietkau
2008-09-30 18:46 ` [PATCH 2/3] mac80211: add multi-rate retry support Johannes Berg
2008-09-30 18:44 ` [PATCH 1/3] mac80211: free up 2 bytes in skb->cb Johannes Berg
1 sibling, 2 replies; 6+ messages in thread
From: Felix Fietkau @ 2008-09-30 11:24 UTC (permalink / raw)
To: linux-wireless; +Cc: Johannes Berg
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>
--- a/include/net/mac80211.h
+++ b/include/net/mac80211.h
@@ -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,12 +349,14 @@
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;
+ 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];
}
/**
--- a/drivers/net/wireless/b43/xmit.c
+++ b/drivers/net/wireless/b43/xmit.c
@@ -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);
--- a/drivers/net/wireless/b43legacy/xmit.c
+++ b/drivers/net/wireless/b43legacy/xmit.c
@@ -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;
--- a/drivers/net/wireless/rtl8180_dev.c
+++ b/drivers/net/wireless/rtl8180_dev.c
@@ -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);
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
@@ -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];
^ permalink raw reply [flat|nested] 6+ messages in thread
* [PATCH 3/3] ath5k: implement multi-rate retry support and fix tx status reporting
2008-09-30 11:24 ` [PATCH 2/3] mac80211: add multi-rate retry support Felix Fietkau
@ 2008-09-30 11:25 ` Felix Fietkau
2008-09-30 18:46 ` [PATCH 2/3] mac80211: add multi-rate retry support Johannes Berg
1 sibling, 0 replies; 6+ messages in thread
From: Felix Fietkau @ 2008-09-30 11:25 UTC (permalink / raw)
To: linux-wireless; +Cc: Johannes Berg
Clean up the tx status reporting, fix retry counters (short retries are
virtual collisions, not actual retries). Implement multi-rate retry
support.
This also fixes strong throughput fluctuations with rc80211_pid
Signed-off-by: Felix Fietkau <nbd@openwrt.org>
--- a/drivers/net/wireless/ath5k/base.c
+++ b/drivers/net/wireless/ath5k/base.c
@@ -583,6 +583,11 @@
}
}
+ /* set up multi-rate retry capabilities */
+ if (sc->ah->ah_version == AR5K_AR5212) {
+ hw->max_altrates = 3;
+ hw->max_altrate_tries = 15;
+ }
/* ready to process interrupts */
__clear_bit(ATH_STAT_INVALID, sc->status);
@@ -1149,7 +1154,9 @@
struct sk_buff *skb = bf->skb;
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
unsigned int pktlen, flags, keyidx = AR5K_TXKEYIX_INVALID;
- int ret;
+ struct ieee80211_rate *rate;
+ unsigned int mrr_rate[3], mrr_tries[3];
+ int i, ret;
flags = AR5K_TXDESC_INTREQ | AR5K_TXDESC_CLRDMASK;
@@ -1174,6 +1181,21 @@
if (ret)
goto err_unmap;
+ for (i = 0; i < 3; i++) {
+ rate = ieee80211_get_alt_retry_rate(sc->hw, info, i);
+ if (rate) {
+ mrr_rate[i] = rate->hw_value;
+ mrr_tries[i] = info->control.retries[i].limit;
+ } else {
+ mrr_rate[i] = 0;
+ mrr_tries[i] = 0;
+ }
+ }
+ ah->ah_setup_mrr_tx_desc(ah, ds,
+ mrr_rate[0], mrr_tries[0],
+ mrr_rate[1], mrr_tries[1],
+ mrr_rate[2], mrr_tries[2]);
+
ds->ds_link = 0;
ds->ds_data = bf->skbaddr;
@@ -1790,7 +1812,7 @@
struct ath5k_desc *ds;
struct sk_buff *skb;
struct ieee80211_tx_info *info;
- int ret;
+ int i, ret;
spin_lock(&txq->lock);
list_for_each_entry_safe(bf, bf0, &txq->q, list) {
@@ -1812,7 +1834,23 @@
pci_unmap_single(sc->pdev, bf->skbaddr, skb->len,
PCI_DMA_TODEVICE);
- info->status.retry_count = ts.ts_shortretry + ts.ts_longretry / 6;
+ info->tx_rate_idx = ath5k_hw_to_driver_rix(sc,
+ ts.ts_rate[ts.ts_final_idx]);
+ info->status.retry_count = ts.ts_longretry;
+
+ for (i = 0; i < 4; i++) {
+ struct ieee80211_tx_altrate *r =
+ &info->status.retries[i];
+
+ if (ts.ts_rate[i]) {
+ r->rate_idx = ath5k_hw_to_driver_rix(sc, ts.ts_rate[i]);
+ r->limit = ts.ts_retry[i];
+ } else {
+ r->rate_idx = -1;
+ r->limit = 0;
+ }
+ }
+
if (unlikely(ts.ts_status)) {
sc->ll_stats.dot11ACKFailureCount++;
if (ts.ts_status & AR5K_TXERR_XRETRY)
--- a/drivers/net/wireless/ath5k/desc.c
+++ b/drivers/net/wireless/ath5k/desc.c
@@ -318,6 +318,15 @@
return 0;
}
+/* no mrr support for cards older than 5212 */
+static int
+ath5k_hw_setup_no_mrr(struct ath5k_hw *ah, struct ath5k_desc *desc,
+ unsigned int tx_rate1, u_int tx_tries1, u_int tx_rate2,
+ u_int tx_tries2, unsigned int tx_rate3, u_int tx_tries3)
+{
+ return 0;
+}
+
/*
* Proccess the tx status descriptor on 5210/5211
*/
@@ -352,8 +361,10 @@
AR5K_DESC_TX_STATUS1_ACK_SIG_STRENGTH);
ts->ts_antenna = 1;
ts->ts_status = 0;
- ts->ts_rate = AR5K_REG_MS(tx_ctl->tx_control_0,
+ ts->ts_rate[0] = AR5K_REG_MS(tx_ctl->tx_control_0,
AR5K_2W_TX_DESC_CTL0_XMIT_RATE);
+ ts->ts_retry[0] = ts->ts_longretry;
+ ts->ts_final_idx = 0;
if (!(tx_status->tx_status_0 & AR5K_DESC_TX_STATUS0_FRAME_XMIT_OK)) {
if (tx_status->tx_status_0 &
@@ -405,29 +416,43 @@
AR5K_DESC_TX_STATUS1_XMIT_ANTENNA) ? 2 : 1;
ts->ts_status = 0;
- switch (AR5K_REG_MS(tx_status->tx_status_1,
- AR5K_DESC_TX_STATUS1_FINAL_TS_INDEX)) {
- case 0:
- ts->ts_rate = tx_ctl->tx_control_3 &
- AR5K_4W_TX_DESC_CTL3_XMIT_RATE0;
- break;
+ ts->ts_final_idx = AR5K_REG_MS(tx_status->tx_status_1,
+ AR5K_DESC_TX_STATUS1_FINAL_TS_INDEX);
+
+ /* The longretry counter has the number of un-acked retries
+ * for the final rate. To get the total number of retries
+ * we have to add the retry counters for the other rates
+ * as well
+ */
+ ts->ts_retry[ts->ts_final_idx] = ts->ts_longretry;
+ switch (ts->ts_final_idx) {
+ case 3:
+ ts->ts_rate[3] = AR5K_REG_MS(tx_ctl->tx_control_3,
+ AR5K_4W_TX_DESC_CTL3_XMIT_RATE3);
+
+ ts->ts_retry[2] = AR5K_REG_MS(tx_ctl->tx_control_2,
+ AR5K_4W_TX_DESC_CTL2_XMIT_TRIES2);
+ ts->ts_longretry += ts->ts_retry[2];
+ /* fall through */
+ case 2:
+ ts->ts_rate[2] = AR5K_REG_MS(tx_ctl->tx_control_3,
+ AR5K_4W_TX_DESC_CTL3_XMIT_RATE2);
+
+ ts->ts_retry[1] = AR5K_REG_MS(tx_ctl->tx_control_2,
+ AR5K_4W_TX_DESC_CTL2_XMIT_TRIES1);
+ ts->ts_longretry += ts->ts_retry[1];
+ /* fall through */
case 1:
- ts->ts_rate = AR5K_REG_MS(tx_ctl->tx_control_3,
+ ts->ts_rate[1] = AR5K_REG_MS(tx_ctl->tx_control_3,
AR5K_4W_TX_DESC_CTL3_XMIT_RATE1);
- ts->ts_longretry += AR5K_REG_MS(tx_ctl->tx_control_2,
+
+ ts->ts_retry[0] = AR5K_REG_MS(tx_ctl->tx_control_2,
AR5K_4W_TX_DESC_CTL2_XMIT_TRIES1);
- break;
- case 2:
- ts->ts_rate = AR5K_REG_MS(tx_ctl->tx_control_3,
- AR5K_4W_TX_DESC_CTL3_XMIT_RATE2);
- ts->ts_longretry += AR5K_REG_MS(tx_ctl->tx_control_2,
- AR5K_4W_TX_DESC_CTL2_XMIT_TRIES2);
- break;
- case 3:
- ts->ts_rate = AR5K_REG_MS(tx_ctl->tx_control_3,
- AR5K_4W_TX_DESC_CTL3_XMIT_RATE3);
- ts->ts_longretry += AR5K_REG_MS(tx_ctl->tx_control_2,
- AR5K_4W_TX_DESC_CTL2_XMIT_TRIES3);
+ ts->ts_longretry += ts->ts_retry[0];
+ /* fall through */
+ case 0:
+ ts->ts_rate[0] = tx_ctl->tx_control_3 &
+ AR5K_4W_TX_DESC_CTL3_XMIT_RATE0;
break;
}
@@ -653,7 +678,7 @@
} else {
ah->ah_setup_rx_desc = ath5k_hw_setup_rx_desc;
ah->ah_setup_tx_desc = ath5k_hw_setup_2word_tx_desc;
- ah->ah_setup_mrr_tx_desc = ath5k_hw_setup_mrr_tx_desc;
+ ah->ah_setup_mrr_tx_desc = ath5k_hw_setup_no_mrr;
ah->ah_proc_tx_desc = ath5k_hw_proc_2word_tx_status;
}
--- a/drivers/net/wireless/ath5k/ath5k.h
+++ b/drivers/net/wireless/ath5k/ath5k.h
@@ -418,7 +418,9 @@
u16 ts_seqnum;
u16 ts_tstamp;
u8 ts_status;
- u8 ts_rate;
+ u8 ts_rate[4];
+ u8 ts_retry[4];
+ u8 ts_final_idx;
s8 ts_rssi;
u8 ts_shortretry;
u8 ts_longretry;
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH 1/3] mac80211: free up 2 bytes in skb->cb
2008-09-30 11:22 ` [PATCH 1/3] mac80211: free up 2 bytes in skb->cb Felix Fietkau
2008-09-30 11:24 ` [PATCH 2/3] mac80211: add multi-rate retry support Felix Fietkau
@ 2008-09-30 18:44 ` Johannes Berg
1 sibling, 0 replies; 6+ messages in thread
From: Johannes Berg @ 2008-09-30 18:44 UTC (permalink / raw)
To: Felix Fietkau; +Cc: linux-wireless
[-- Attachment #1: Type: text/plain, Size: 6397 bytes --]
On Tue, 2008-09-30 at 13:22 +0200, Felix Fietkau wrote:
> Free up 2 bytes in skb->cb to be used for multi-rate retry.
> Move iv_len and icv_len initialization into key alloc.
>
> Signed-off-by: Felix Fietkau <nbd@openwrt.org>
The mac80211 changes look good to me, the driver stuff I cannot really
judge.
>
> --- a/include/net/mac80211.h
> +++ b/include/net/mac80211.h
> @@ -337,8 +337,6 @@
> unsigned long jiffies;
> s8 rts_cts_rate_idx, alt_retry_rate_idx;
> u8 retry_limit;
> - u8 icv_len;
> - u8 iv_len;
> } control;
> struct {
> u64 ampdu_ack_map;
> @@ -635,6 +633,8 @@
> */
> struct ieee80211_key_conf {
> enum ieee80211_key_alg alg;
> + u8 icv_len;
> + u8 iv_len;
> u8 hw_key_idx;
> u8 flags;
> s8 keyidx;
> --- a/drivers/net/wireless/b43/xmit.c
> +++ b/drivers/net/wireless/b43/xmit.c
> @@ -252,7 +252,7 @@
> }
>
> /* Hardware appends ICV. */
> - plcp_fragment_len += info->control.icv_len;
> + plcp_fragment_len += info->control.hw_key->icv_len;
>
> key_idx = b43_kidx_to_fw(dev, key_idx);
> mac_ctl |= (key_idx << B43_TXH_MAC_KEYIDX_SHIFT) &
> @@ -260,7 +260,7 @@
> mac_ctl |= (key->algorithm << B43_TXH_MAC_KEYALG_SHIFT) &
> B43_TXH_MAC_KEYALG;
> wlhdr_len = ieee80211_hdrlen(fctl);
> - iv_len = min((size_t) info->control.iv_len,
> + iv_len = min((size_t) info->control.hw_key->iv_len,
> ARRAY_SIZE(txhdr->iv));
> memcpy(txhdr->iv, ((u8 *) wlhdr) + wlhdr_len, iv_len);
> }
> --- a/drivers/net/wireless/b43legacy/xmit.c
> +++ b/drivers/net/wireless/b43legacy/xmit.c
> @@ -243,7 +243,7 @@
>
> if (key->enabled) {
> /* Hardware appends ICV. */
> - plcp_fragment_len += info->control.icv_len;
> + plcp_fragment_len += info->control.hw_key->icv_len;
>
> key_idx = b43legacy_kidx_to_fw(dev, key_idx);
> mac_ctl |= (key_idx << B43legacy_TX4_MAC_KEYIDX_SHIFT) &
> @@ -252,7 +252,7 @@
> B43legacy_TX4_MAC_KEYALG_SHIFT) &
> B43legacy_TX4_MAC_KEYALG;
> wlhdr_len = ieee80211_hdrlen(wlhdr->frame_control);
> - iv_len = min((size_t)info->control.iv_len,
> + iv_len = min((size_t)info->control.hw_key->iv_len,
> ARRAY_SIZE(txhdr->iv));
> memcpy(txhdr->iv, ((u8 *)wlhdr) + wlhdr_len, iv_len);
> } else {
> --- a/net/mac80211/wep.c
> +++ b/net/mac80211/wep.c
> @@ -313,9 +313,6 @@
> {
> struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
>
> - info->control.iv_len = WEP_IV_LEN;
> - info->control.icv_len = WEP_ICV_LEN;
> -
> if (!(tx->key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE)) {
> if (ieee80211_wep_encrypt(tx->local, skb, tx->key))
> return -1;
> --- a/net/mac80211/wpa.c
> +++ b/net/mac80211/wpa.c
> @@ -152,9 +152,6 @@
> int len, tail;
> u8 *pos;
>
> - info->control.icv_len = TKIP_ICV_LEN;
> - info->control.iv_len = TKIP_IV_LEN;
> -
> if ((tx->key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE) &&
> !(tx->key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_IV)) {
> /* hwaccel - with no need for preallocated room for IV/ICV */
> @@ -374,9 +371,6 @@
> u8 *pos, *pn;
> int i;
>
> - info->control.icv_len = CCMP_MIC_LEN;
> - info->control.iv_len = CCMP_HDR_LEN;
> -
> if ((tx->key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE) &&
> !(tx->key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_IV)) {
> /* hwaccel - with no need for preallocated room for CCMP "
> --- a/drivers/net/wireless/ath5k/base.c
> +++ b/drivers/net/wireless/ath5k/base.c
> @@ -1164,7 +1164,7 @@
>
> if (info->control.hw_key) {
> keyidx = info->control.hw_key->hw_key_idx;
> - pktlen += info->control.icv_len;
> + pktlen += info->control.hw_key->icv_len;
> }
> ret = ah->ah_setup_tx_desc(ah, ds, pktlen,
> ieee80211_get_hdrlen_from_skb(skb), AR5K_PKT_TYPE_NORMAL,
> --- a/drivers/net/wireless/ath9k/xmit.c
> +++ b/drivers/net/wireless/ath9k/xmit.c
> @@ -237,7 +237,7 @@
>
> if (tx_info->control.hw_key) {
> txctl->keyix = tx_info->control.hw_key->hw_key_idx;
> - txctl->frmlen += tx_info->control.icv_len;
> + txctl->frmlen += tx_info->control.hw_key->icv_len;
>
> if (tx_info->control.hw_key->alg == ALG_WEP)
> txctl->keytype = ATH9K_KEY_TYPE_WEP;
> --- a/drivers/net/wireless/rt2x00/rt2x00crypto.c
> +++ b/drivers/net/wireless/rt2x00/rt2x00crypto.c
> @@ -56,10 +56,10 @@
> * note that these lengths should only be added when
> * mac80211 does not generate it.
> */
> - overhead += tx_info->control.icv_len;
> + overhead += key->icv_len;
>
> if (!(key->flags & IEEE80211_KEY_FLAG_GENERATE_IV))
> - overhead += tx_info->control.iv_len;
> + overhead += key->iv_len;
>
> if (!(key->flags & IEEE80211_KEY_FLAG_GENERATE_MMIC)) {
> if (key->alg == ALG_TKIP)
> --- a/drivers/net/wireless/rt2x00/rt2x00queue.c
> +++ b/drivers/net/wireless/rt2x00/rt2x00queue.c
> @@ -374,7 +374,7 @@
> struct queue_entry *entry = rt2x00queue_get_entry(queue, Q_INDEX);
> struct txentry_desc txdesc;
> struct skb_frame_desc *skbdesc;
> - unsigned int iv_len = IEEE80211_SKB_CB(skb)->control.iv_len;
> + unsigned int iv_len;
>
> if (unlikely(rt2x00queue_full(queue)))
> return -EINVAL;
> @@ -410,8 +410,11 @@
> * the frame so we can provide it to the driver seperately.
> */
> if (test_bit(ENTRY_TXD_ENCRYPT, &txdesc.flags) &&
> - !test_bit(ENTRY_TXD_ENCRYPT_IV, &txdesc.flags))
> + !test_bit(ENTRY_TXD_ENCRYPT_IV, &txdesc.flags) &&
> + (IEEE80211_SKB_CB(skb)->control.hw_key != NULL)) {
> + iv_len = IEEE80211_SKB_CB(skb)->control.hw_key->iv_len;
> rt2x00crypto_tx_remove_iv(skb, iv_len);
> + }
>
> /*
> * It could be possible that the queue was corrupted and this
> --- a/net/mac80211/key.c
> +++ b/net/mac80211/key.c
> @@ -281,6 +281,20 @@
> key->conf.alg = alg;
> key->conf.keyidx = idx;
> key->conf.keylen = key_len;
> + switch (alg) {
> + case ALG_WEP:
> + key->conf.iv_len = WEP_IV_LEN;
> + key->conf.icv_len = WEP_ICV_LEN;
> + break;
> + case ALG_TKIP:
> + key->conf.iv_len = TKIP_IV_LEN;
> + key->conf.icv_len = TKIP_ICV_LEN;
> + break;
> + case ALG_CCMP:
> + key->conf.iv_len = CCMP_HDR_LEN;
> + key->conf.icv_len = CCMP_MIC_LEN;
> + break;
> + }
> memcpy(key->conf.key, key_data, key_len);
> INIT_LIST_HEAD(&key->list);
> INIT_LIST_HEAD(&key->todo);
>
[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 836 bytes --]
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH 2/3] mac80211: add multi-rate retry support
2008-09-30 11:24 ` [PATCH 2/3] mac80211: add multi-rate retry support Felix Fietkau
2008-09-30 11:25 ` [PATCH 3/3] ath5k: implement multi-rate retry support and fix tx status reporting Felix Fietkau
@ 2008-09-30 18:46 ` Johannes Berg
1 sibling, 0 replies; 6+ messages in thread
From: Johannes Berg @ 2008-09-30 18:46 UTC (permalink / raw)
To: Felix Fietkau; +Cc: linux-wireless
[-- Attachment #1: Type: text/plain, Size: 457 bytes --]
On Tue, 2008-09-30 at 13:24 +0200, Felix Fietkau wrote:
> 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>
Would be good to look at all the drivers and see whether they currently
use the retry rate (set max to 1) or not (set max to 0) I think.
johannes
[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 836 bytes --]
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2008-09-30 18:46 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2008-09-30 11:20 [PATCH 0/3]: multi-rate retry support for mac80211/ath5k Felix Fietkau
2008-09-30 11:22 ` [PATCH 1/3] mac80211: free up 2 bytes in skb->cb Felix Fietkau
2008-09-30 11:24 ` [PATCH 2/3] mac80211: add multi-rate retry support Felix Fietkau
2008-09-30 11:25 ` [PATCH 3/3] ath5k: implement multi-rate retry support and fix tx status reporting Felix Fietkau
2008-09-30 18:46 ` [PATCH 2/3] mac80211: add multi-rate retry support Johannes Berg
2008-09-30 18:44 ` [PATCH 1/3] mac80211: free up 2 bytes in skb->cb Johannes Berg
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).