From: Felix Fietkau <nbd@openwrt.org>
To: linux-wireless <linux-wireless@vger.kernel.org>
Cc: Johannes Berg <johannes@sipsolutions.net>,
Derek Smithies <derek@indranet.co.nz>,
Nick Kossifidis <mickflemm@gmail.com>,
"Luis R. Rodriguez" <mcgrof@gmail.com>
Subject: [PATCH 3/4] ath5k: implement multi-rate retry support, fix tx status reporting
Date: Sun, 05 Oct 2008 18:05:48 +0200 [thread overview]
Message-ID: <48E8E5DC.3070806@openwrt.org> (raw)
In-Reply-To: <48E8E588.30001@openwrt.org>
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
@@ -530,6 +530,12 @@
goto err_irq;
}
+ /* set up multi-rate retry capabilities */
+ if (sc->ah->ah_version == AR5K_AR5212) {
+ hw->max_altrates = 3;
+ hw->max_altrate_tries = 11;
+ }
+
/* Finish private driver data initialization */
ret = ath5k_attach(pdev, hw);
if (ret)
@@ -1149,7 +1155,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 +1182,22 @@
if (ret)
goto err_unmap;
+ memset(mrr_rate, 0, sizeof(mrr_rate));
+ memset(mrr_tries, 0, sizeof(mrr_tries));
+ for (i = 0; i < 3; i++) {
+ rate = ieee80211_get_alt_retry_rate(sc->hw, info, i);
+ if (!rate)
+ break;
+
+ mrr_rate[i] = rate->hw_value;
+ mrr_tries[i] = info->control.retries[i].limit;
+ }
+
+ 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 +1814,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 +1836,25 @@
pci_unmap_single(sc->pdev, bf->skbaddr, skb->len,
PCI_DMA_TODEVICE);
- info->status.retry_count = ts.ts_shortretry + ts.ts_longretry / 6;
+ memset(&info->status, 0, sizeof(info->status));
+ 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;
+ }
+ }
+
+ info->status.excessive_retries = 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;
next prev parent reply other threads:[~2008-10-05 16:06 UTC|newest]
Thread overview: 11+ messages / expand[flat|nested] mbox.gz Atom feed top
2008-10-05 16:00 [PATCH 0/4] multi-rate retry and the 'minstrel' rate control for mac80211 Felix Fietkau
2008-10-05 16:02 ` [PATCH 1/4] mac80211: free up 2 bytes in skb->cb Felix Fietkau
2008-10-05 16:04 ` [PATCH 2/4] mac80211: add multi-rate retry support Felix Fietkau
2008-10-05 16:05 ` Felix Fietkau [this message]
2008-10-05 16:07 ` [PATCH 4/4] mac80211: add the 'minstrel' rate control algorithm Felix Fietkau
2008-10-06 21:49 ` [PATCH 2/4] mac80211: add multi-rate retry support Johannes Berg
2008-10-07 17:13 ` Felix Fietkau
2008-10-07 17:27 ` Johannes Berg
2008-10-07 17:56 ` Felix Fietkau
2008-10-07 18:01 ` Johannes Berg
2008-10-06 15:10 ` [PATCH 0/4] multi-rate retry and the 'minstrel' rate control for mac80211 Johannes Berg
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=48E8E5DC.3070806@openwrt.org \
--to=nbd@openwrt.org \
--cc=derek@indranet.co.nz \
--cc=johannes@sipsolutions.net \
--cc=linux-wireless@vger.kernel.org \
--cc=mcgrof@gmail.com \
--cc=mickflemm@gmail.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.