add the new compat-wireless for 2.6.27 + multi-rate retry and minstrel patches, renam...
[openwrt/svn-archive/archive.git] / package / mac80211 / patches / 250-ath5k_mrr.patch
1 Clean up the tx status reporting, fix retry counters (short retries are
2 virtual collisions, not actual retries). Implement multi-rate retry
3 support.
4 This also fixes strong throughput fluctuations with rc80211_pid
5
6 Signed-off-by: Felix Fietkau <nbd@openwrt.org>
7
8 --- a/drivers/net/wireless/ath5k/base.c
9 +++ b/drivers/net/wireless/ath5k/base.c
10 @@ -530,6 +530,12 @@
11 goto err_irq;
12 }
13
14 + /* set up multi-rate retry capabilities */
15 + if (sc->ah->ah_version == AR5K_AR5212) {
16 + hw->max_altrates = 3;
17 + hw->max_altrate_tries = 11;
18 + }
19 +
20 /* Finish private driver data initialization */
21 ret = ath5k_attach(pdev, hw);
22 if (ret)
23 @@ -1149,7 +1155,9 @@
24 struct sk_buff *skb = bf->skb;
25 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
26 unsigned int pktlen, flags, keyidx = AR5K_TXKEYIX_INVALID;
27 - int ret;
28 + struct ieee80211_rate *rate;
29 + unsigned int mrr_rate[3], mrr_tries[3];
30 + int i, ret;
31
32 flags = AR5K_TXDESC_INTREQ | AR5K_TXDESC_CLRDMASK;
33
34 @@ -1174,6 +1182,22 @@
35 if (ret)
36 goto err_unmap;
37
38 + memset(mrr_rate, 0, sizeof(mrr_rate));
39 + memset(mrr_tries, 0, sizeof(mrr_tries));
40 + for (i = 0; i < 3; i++) {
41 + rate = ieee80211_get_alt_retry_rate(sc->hw, info, i);
42 + if (!rate)
43 + break;
44 +
45 + mrr_rate[i] = rate->hw_value;
46 + mrr_tries[i] = info->control.retries[i].limit;
47 + }
48 +
49 + ah->ah_setup_mrr_tx_desc(ah, ds,
50 + mrr_rate[0], mrr_tries[0],
51 + mrr_rate[1], mrr_tries[1],
52 + mrr_rate[2], mrr_tries[2]);
53 +
54 ds->ds_link = 0;
55 ds->ds_data = bf->skbaddr;
56
57 @@ -1790,7 +1814,7 @@
58 struct ath5k_desc *ds;
59 struct sk_buff *skb;
60 struct ieee80211_tx_info *info;
61 - int ret;
62 + int i, ret;
63
64 spin_lock(&txq->lock);
65 list_for_each_entry_safe(bf, bf0, &txq->q, list) {
66 @@ -1812,7 +1836,25 @@
67 pci_unmap_single(sc->pdev, bf->skbaddr, skb->len,
68 PCI_DMA_TODEVICE);
69
70 - info->status.retry_count = ts.ts_shortretry + ts.ts_longretry / 6;
71 + memset(&info->status, 0, sizeof(info->status));
72 + info->tx_rate_idx = ath5k_hw_to_driver_rix(sc,
73 + ts.ts_rate[ts.ts_final_idx]);
74 + info->status.retry_count = ts.ts_longretry;
75 +
76 + for (i = 0; i < 4; i++) {
77 + struct ieee80211_tx_altrate *r =
78 + &info->status.retries[i];
79 +
80 + if (ts.ts_rate[i]) {
81 + r->rate_idx = ath5k_hw_to_driver_rix(sc, ts.ts_rate[i]);
82 + r->limit = ts.ts_retry[i];
83 + } else {
84 + r->rate_idx = -1;
85 + r->limit = 0;
86 + }
87 + }
88 +
89 + info->status.excessive_retries = 0;
90 if (unlikely(ts.ts_status)) {
91 sc->ll_stats.dot11ACKFailureCount++;
92 if (ts.ts_status & AR5K_TXERR_XRETRY)
93 --- a/drivers/net/wireless/ath5k/desc.c
94 +++ b/drivers/net/wireless/ath5k/desc.c
95 @@ -318,6 +318,15 @@
96 return 0;
97 }
98
99 +/* no mrr support for cards older than 5212 */
100 +static int
101 +ath5k_hw_setup_no_mrr(struct ath5k_hw *ah, struct ath5k_desc *desc,
102 + unsigned int tx_rate1, u_int tx_tries1, u_int tx_rate2,
103 + u_int tx_tries2, unsigned int tx_rate3, u_int tx_tries3)
104 +{
105 + return 0;
106 +}
107 +
108 /*
109 * Proccess the tx status descriptor on 5210/5211
110 */
111 @@ -352,8 +361,10 @@
112 AR5K_DESC_TX_STATUS1_ACK_SIG_STRENGTH);
113 ts->ts_antenna = 1;
114 ts->ts_status = 0;
115 - ts->ts_rate = AR5K_REG_MS(tx_ctl->tx_control_0,
116 + ts->ts_rate[0] = AR5K_REG_MS(tx_ctl->tx_control_0,
117 AR5K_2W_TX_DESC_CTL0_XMIT_RATE);
118 + ts->ts_retry[0] = ts->ts_longretry;
119 + ts->ts_final_idx = 0;
120
121 if (!(tx_status->tx_status_0 & AR5K_DESC_TX_STATUS0_FRAME_XMIT_OK)) {
122 if (tx_status->tx_status_0 &
123 @@ -405,29 +416,43 @@
124 AR5K_DESC_TX_STATUS1_XMIT_ANTENNA) ? 2 : 1;
125 ts->ts_status = 0;
126
127 - switch (AR5K_REG_MS(tx_status->tx_status_1,
128 - AR5K_DESC_TX_STATUS1_FINAL_TS_INDEX)) {
129 - case 0:
130 - ts->ts_rate = tx_ctl->tx_control_3 &
131 - AR5K_4W_TX_DESC_CTL3_XMIT_RATE0;
132 - break;
133 + ts->ts_final_idx = AR5K_REG_MS(tx_status->tx_status_1,
134 + AR5K_DESC_TX_STATUS1_FINAL_TS_INDEX);
135 +
136 + /* The longretry counter has the number of un-acked retries
137 + * for the final rate. To get the total number of retries
138 + * we have to add the retry counters for the other rates
139 + * as well
140 + */
141 + ts->ts_retry[ts->ts_final_idx] = ts->ts_longretry;
142 + switch (ts->ts_final_idx) {
143 + case 3:
144 + ts->ts_rate[3] = AR5K_REG_MS(tx_ctl->tx_control_3,
145 + AR5K_4W_TX_DESC_CTL3_XMIT_RATE3);
146 +
147 + ts->ts_retry[2] = AR5K_REG_MS(tx_ctl->tx_control_2,
148 + AR5K_4W_TX_DESC_CTL2_XMIT_TRIES2);
149 + ts->ts_longretry += ts->ts_retry[2];
150 + /* fall through */
151 + case 2:
152 + ts->ts_rate[2] = AR5K_REG_MS(tx_ctl->tx_control_3,
153 + AR5K_4W_TX_DESC_CTL3_XMIT_RATE2);
154 +
155 + ts->ts_retry[1] = AR5K_REG_MS(tx_ctl->tx_control_2,
156 + AR5K_4W_TX_DESC_CTL2_XMIT_TRIES1);
157 + ts->ts_longretry += ts->ts_retry[1];
158 + /* fall through */
159 case 1:
160 - ts->ts_rate = AR5K_REG_MS(tx_ctl->tx_control_3,
161 + ts->ts_rate[1] = AR5K_REG_MS(tx_ctl->tx_control_3,
162 AR5K_4W_TX_DESC_CTL3_XMIT_RATE1);
163 - ts->ts_longretry += AR5K_REG_MS(tx_ctl->tx_control_2,
164 +
165 + ts->ts_retry[0] = AR5K_REG_MS(tx_ctl->tx_control_2,
166 AR5K_4W_TX_DESC_CTL2_XMIT_TRIES1);
167 - break;
168 - case 2:
169 - ts->ts_rate = AR5K_REG_MS(tx_ctl->tx_control_3,
170 - AR5K_4W_TX_DESC_CTL3_XMIT_RATE2);
171 - ts->ts_longretry += AR5K_REG_MS(tx_ctl->tx_control_2,
172 - AR5K_4W_TX_DESC_CTL2_XMIT_TRIES2);
173 - break;
174 - case 3:
175 - ts->ts_rate = AR5K_REG_MS(tx_ctl->tx_control_3,
176 - AR5K_4W_TX_DESC_CTL3_XMIT_RATE3);
177 - ts->ts_longretry += AR5K_REG_MS(tx_ctl->tx_control_2,
178 - AR5K_4W_TX_DESC_CTL2_XMIT_TRIES3);
179 + ts->ts_longretry += ts->ts_retry[0];
180 + /* fall through */
181 + case 0:
182 + ts->ts_rate[0] = tx_ctl->tx_control_3 &
183 + AR5K_4W_TX_DESC_CTL3_XMIT_RATE0;
184 break;
185 }
186
187 @@ -653,7 +678,7 @@
188 } else {
189 ah->ah_setup_rx_desc = ath5k_hw_setup_rx_desc;
190 ah->ah_setup_tx_desc = ath5k_hw_setup_2word_tx_desc;
191 - ah->ah_setup_mrr_tx_desc = ath5k_hw_setup_mrr_tx_desc;
192 + ah->ah_setup_mrr_tx_desc = ath5k_hw_setup_no_mrr;
193 ah->ah_proc_tx_desc = ath5k_hw_proc_2word_tx_status;
194 }
195
196 --- a/drivers/net/wireless/ath5k/ath5k.h
197 +++ b/drivers/net/wireless/ath5k/ath5k.h
198 @@ -418,7 +418,9 @@
199 u16 ts_seqnum;
200 u16 ts_tstamp;
201 u8 ts_status;
202 - u8 ts_rate;
203 + u8 ts_rate[4];
204 + u8 ts_retry[4];
205 + u8 ts_final_idx;
206 s8 ts_rssi;
207 u8 ts_shortretry;
208 u8 ts_longretry;