Skip to content

Commit 2f7fe87

Browse files
Felix Fietkaulinvjw
authored andcommitted
ath5k: implement multi-rate retry support, fix tx status reporting
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> Signed-off-by: John W. Linville <linville@tuxdriver.com>
1 parent 870abdf commit 2f7fe87

File tree

3 files changed

+95
-26
lines changed

3 files changed

+95
-26
lines changed

drivers/net/wireless/ath5k/ath5k.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -431,7 +431,9 @@ struct ath5k_tx_status {
431431
u16 ts_seqnum;
432432
u16 ts_tstamp;
433433
u8 ts_status;
434-
u8 ts_rate;
434+
u8 ts_rate[4];
435+
u8 ts_retry[4];
436+
u8 ts_final_idx;
435437
s8 ts_rssi;
436438
u8 ts_shortretry;
437439
u8 ts_longretry;

drivers/net/wireless/ath5k/base.c

Lines changed: 45 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -541,6 +541,12 @@ ath5k_pci_probe(struct pci_dev *pdev,
541541
goto err_irq;
542542
}
543543

544+
/* set up multi-rate retry capabilities */
545+
if (sc->ah->ah_version == AR5K_AR5212) {
546+
hw->max_altrates = 3;
547+
hw->max_altrate_tries = 11;
548+
}
549+
544550
/* Finish private driver data initialization */
545551
ret = ath5k_attach(pdev, hw);
546552
if (ret)
@@ -1173,7 +1179,9 @@ ath5k_txbuf_setup(struct ath5k_softc *sc, struct ath5k_buf *bf)
11731179
struct sk_buff *skb = bf->skb;
11741180
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
11751181
unsigned int pktlen, flags, keyidx = AR5K_TXKEYIX_INVALID;
1176-
int ret;
1182+
struct ieee80211_rate *rate;
1183+
unsigned int mrr_rate[3], mrr_tries[3];
1184+
int i, ret;
11771185

11781186
flags = AR5K_TXDESC_INTREQ | AR5K_TXDESC_CLRDMASK;
11791187

@@ -1198,6 +1206,22 @@ ath5k_txbuf_setup(struct ath5k_softc *sc, struct ath5k_buf *bf)
11981206
if (ret)
11991207
goto err_unmap;
12001208

1209+
memset(mrr_rate, 0, sizeof(mrr_rate));
1210+
memset(mrr_tries, 0, sizeof(mrr_tries));
1211+
for (i = 0; i < 3; i++) {
1212+
rate = ieee80211_get_alt_retry_rate(sc->hw, info, i);
1213+
if (!rate)
1214+
break;
1215+
1216+
mrr_rate[i] = rate->hw_value;
1217+
mrr_tries[i] = info->control.retries[i].limit;
1218+
}
1219+
1220+
ah->ah_setup_mrr_tx_desc(ah, ds,
1221+
mrr_rate[0], mrr_tries[0],
1222+
mrr_rate[1], mrr_tries[1],
1223+
mrr_rate[2], mrr_tries[2]);
1224+
12011225
ds->ds_link = 0;
12021226
ds->ds_data = bf->skbaddr;
12031227

@@ -1814,7 +1838,7 @@ ath5k_tx_processq(struct ath5k_softc *sc, struct ath5k_txq *txq)
18141838
struct ath5k_desc *ds;
18151839
struct sk_buff *skb;
18161840
struct ieee80211_tx_info *info;
1817-
int ret;
1841+
int i, ret;
18181842

18191843
spin_lock(&txq->lock);
18201844
list_for_each_entry_safe(bf, bf0, &txq->q, list) {
@@ -1836,7 +1860,25 @@ ath5k_tx_processq(struct ath5k_softc *sc, struct ath5k_txq *txq)
18361860
pci_unmap_single(sc->pdev, bf->skbaddr, skb->len,
18371861
PCI_DMA_TODEVICE);
18381862

1839-
info->status.retry_count = ts.ts_shortretry + ts.ts_longretry / 6;
1863+
memset(&info->status, 0, sizeof(info->status));
1864+
info->tx_rate_idx = ath5k_hw_to_driver_rix(sc,
1865+
ts.ts_rate[ts.ts_final_idx]);
1866+
info->status.retry_count = ts.ts_longretry;
1867+
1868+
for (i = 0; i < 4; i++) {
1869+
struct ieee80211_tx_altrate *r =
1870+
&info->status.retries[i];
1871+
1872+
if (ts.ts_rate[i]) {
1873+
r->rate_idx = ath5k_hw_to_driver_rix(sc, ts.ts_rate[i]);
1874+
r->limit = ts.ts_retry[i];
1875+
} else {
1876+
r->rate_idx = -1;
1877+
r->limit = 0;
1878+
}
1879+
}
1880+
1881+
info->status.excessive_retries = 0;
18401882
if (unlikely(ts.ts_status)) {
18411883
sc->ll_stats.dot11ACKFailureCount++;
18421884
if (ts.ts_status & AR5K_TXERR_XRETRY)

drivers/net/wireless/ath5k/desc.c

Lines changed: 47 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -318,6 +318,15 @@ ath5k_hw_setup_mrr_tx_desc(struct ath5k_hw *ah, struct ath5k_desc *desc,
318318
return 0;
319319
}
320320

321+
/* no mrr support for cards older than 5212 */
322+
static int
323+
ath5k_hw_setup_no_mrr(struct ath5k_hw *ah, struct ath5k_desc *desc,
324+
unsigned int tx_rate1, u_int tx_tries1, u_int tx_rate2,
325+
u_int tx_tries2, unsigned int tx_rate3, u_int tx_tries3)
326+
{
327+
return 0;
328+
}
329+
321330
/*
322331
* Proccess the tx status descriptor on 5210/5211
323332
*/
@@ -352,8 +361,10 @@ static int ath5k_hw_proc_2word_tx_status(struct ath5k_hw *ah,
352361
AR5K_DESC_TX_STATUS1_ACK_SIG_STRENGTH);
353362
ts->ts_antenna = 1;
354363
ts->ts_status = 0;
355-
ts->ts_rate = AR5K_REG_MS(tx_ctl->tx_control_0,
364+
ts->ts_rate[0] = AR5K_REG_MS(tx_ctl->tx_control_0,
356365
AR5K_2W_TX_DESC_CTL0_XMIT_RATE);
366+
ts->ts_retry[0] = ts->ts_longretry;
367+
ts->ts_final_idx = 0;
357368

358369
if (!(tx_status->tx_status_0 & AR5K_DESC_TX_STATUS0_FRAME_XMIT_OK)) {
359370
if (tx_status->tx_status_0 &
@@ -405,29 +416,43 @@ static int ath5k_hw_proc_4word_tx_status(struct ath5k_hw *ah,
405416
AR5K_DESC_TX_STATUS1_XMIT_ANTENNA) ? 2 : 1;
406417
ts->ts_status = 0;
407418

408-
switch (AR5K_REG_MS(tx_status->tx_status_1,
409-
AR5K_DESC_TX_STATUS1_FINAL_TS_INDEX)) {
410-
case 0:
411-
ts->ts_rate = tx_ctl->tx_control_3 &
412-
AR5K_4W_TX_DESC_CTL3_XMIT_RATE0;
413-
break;
419+
ts->ts_final_idx = AR5K_REG_MS(tx_status->tx_status_1,
420+
AR5K_DESC_TX_STATUS1_FINAL_TS_INDEX);
421+
422+
/* The longretry counter has the number of un-acked retries
423+
* for the final rate. To get the total number of retries
424+
* we have to add the retry counters for the other rates
425+
* as well
426+
*/
427+
ts->ts_retry[ts->ts_final_idx] = ts->ts_longretry;
428+
switch (ts->ts_final_idx) {
429+
case 3:
430+
ts->ts_rate[3] = AR5K_REG_MS(tx_ctl->tx_control_3,
431+
AR5K_4W_TX_DESC_CTL3_XMIT_RATE3);
432+
433+
ts->ts_retry[2] = AR5K_REG_MS(tx_ctl->tx_control_2,
434+
AR5K_4W_TX_DESC_CTL2_XMIT_TRIES2);
435+
ts->ts_longretry += ts->ts_retry[2];
436+
/* fall through */
437+
case 2:
438+
ts->ts_rate[2] = AR5K_REG_MS(tx_ctl->tx_control_3,
439+
AR5K_4W_TX_DESC_CTL3_XMIT_RATE2);
440+
441+
ts->ts_retry[1] = AR5K_REG_MS(tx_ctl->tx_control_2,
442+
AR5K_4W_TX_DESC_CTL2_XMIT_TRIES1);
443+
ts->ts_longretry += ts->ts_retry[1];
444+
/* fall through */
414445
case 1:
415-
ts->ts_rate = AR5K_REG_MS(tx_ctl->tx_control_3,
446+
ts->ts_rate[1] = AR5K_REG_MS(tx_ctl->tx_control_3,
416447
AR5K_4W_TX_DESC_CTL3_XMIT_RATE1);
417-
ts->ts_longretry += AR5K_REG_MS(tx_ctl->tx_control_2,
448+
449+
ts->ts_retry[0] = AR5K_REG_MS(tx_ctl->tx_control_2,
418450
AR5K_4W_TX_DESC_CTL2_XMIT_TRIES1);
419-
break;
420-
case 2:
421-
ts->ts_rate = AR5K_REG_MS(tx_ctl->tx_control_3,
422-
AR5K_4W_TX_DESC_CTL3_XMIT_RATE2);
423-
ts->ts_longretry += AR5K_REG_MS(tx_ctl->tx_control_2,
424-
AR5K_4W_TX_DESC_CTL2_XMIT_TRIES2);
425-
break;
426-
case 3:
427-
ts->ts_rate = AR5K_REG_MS(tx_ctl->tx_control_3,
428-
AR5K_4W_TX_DESC_CTL3_XMIT_RATE3);
429-
ts->ts_longretry += AR5K_REG_MS(tx_ctl->tx_control_2,
430-
AR5K_4W_TX_DESC_CTL2_XMIT_TRIES3);
451+
ts->ts_longretry += ts->ts_retry[0];
452+
/* fall through */
453+
case 0:
454+
ts->ts_rate[0] = tx_ctl->tx_control_3 &
455+
AR5K_4W_TX_DESC_CTL3_XMIT_RATE0;
431456
break;
432457
}
433458

@@ -653,7 +678,7 @@ int ath5k_hw_init_desc_functions(struct ath5k_hw *ah)
653678
} else {
654679
ah->ah_setup_rx_desc = ath5k_hw_setup_rx_desc;
655680
ah->ah_setup_tx_desc = ath5k_hw_setup_2word_tx_desc;
656-
ah->ah_setup_mrr_tx_desc = ath5k_hw_setup_mrr_tx_desc;
681+
ah->ah_setup_mrr_tx_desc = ath5k_hw_setup_no_mrr;
657682
ah->ah_proc_tx_desc = ath5k_hw_proc_2word_tx_status;
658683
}
659684

0 commit comments

Comments
 (0)