aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorVasanthakumar Thiagarajan <vasanth@atheros.com>2010-04-15 17:39:29 -0400
committerJohn W. Linville <linville@tuxdriver.com>2010-04-16 15:43:45 -0400
commit994089db034059f4b545ddef9fab466091894071 (patch)
treecfd7f40be615d8efd7e44c346ad8b78e0f148152 /drivers
parentb622a720b45def8dce816244a83b82992da4fe20 (diff)
ath9k_hw: Fill descriptor abstrations for AR9003
Signed-off-by: Vasanthakumar Thiagarajan <vasanth@atheros.com> Signed-off-by: Felix Fietkau <nbd@openwrt.org> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9003_mac.c234
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9003_mac.h20
-rw-r--r--drivers/net/wireless/ath/ath9k/mac.h7
3 files changed, 254 insertions, 7 deletions
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_mac.c b/drivers/net/wireless/ath/ath9k/ar9003_mac.c
index cb93d2375e8d..1a8c1ba538b4 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_mac.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_mac.c
@@ -168,23 +168,169 @@ static bool ar9003_hw_get_isr(struct ath_hw *ah, enum ath9k_int *masked)
168 return true; 168 return true;
169} 169}
170 170
171static u16 ar9003_calc_ptr_chksum(struct ar9003_txc *ads)
172{
173 int checksum;
174
175 checksum = ads->info + ads->link
176 + ads->data0 + ads->ctl3
177 + ads->data1 + ads->ctl5
178 + ads->data2 + ads->ctl7
179 + ads->data3 + ads->ctl9;
180
181 return ((checksum & 0xffff) + (checksum >> 16)) & AR_TxPtrChkSum;
182}
183
171static void ar9003_hw_fill_txdesc(struct ath_hw *ah, void *ds, u32 seglen, 184static void ar9003_hw_fill_txdesc(struct ath_hw *ah, void *ds, u32 seglen,
172 bool is_firstseg, bool is_lastseg, 185 bool is_firstseg, bool is_lastseg,
173 const void *ds0, dma_addr_t buf_addr, 186 const void *ds0, dma_addr_t buf_addr,
174 unsigned int qcu) 187 unsigned int qcu)
175{ 188{
189 struct ar9003_txc *ads = (struct ar9003_txc *) ds;
190 unsigned int descid = 0;
191
192 ads->info = (ATHEROS_VENDOR_ID << AR_DescId_S) |
193 (1 << AR_TxRxDesc_S) |
194 (1 << AR_CtrlStat_S) |
195 (qcu << AR_TxQcuNum_S) | 0x17;
196
197 ads->data0 = buf_addr;
198 ads->data1 = 0;
199 ads->data2 = 0;
200 ads->data3 = 0;
201
202 ads->ctl3 = (seglen << AR_BufLen_S);
203 ads->ctl3 &= AR_BufLen;
204
205 /* Fill in pointer checksum and descriptor id */
206 ads->ctl10 = ar9003_calc_ptr_chksum(ads);
207 ads->ctl10 |= (descid << AR_TxDescId_S);
208
209 if (is_firstseg) {
210 ads->ctl12 |= (is_lastseg ? 0 : AR_TxMore);
211 } else if (is_lastseg) {
212 ads->ctl11 = 0;
213 ads->ctl12 = 0;
214 ads->ctl13 = AR9003TXC_CONST(ds0)->ctl13;
215 ads->ctl14 = AR9003TXC_CONST(ds0)->ctl14;
216 } else {
217 /* XXX Intermediate descriptor in a multi-descriptor frame.*/
218 ads->ctl11 = 0;
219 ads->ctl12 = AR_TxMore;
220 ads->ctl13 = 0;
221 ads->ctl14 = 0;
222 }
176} 223}
177 224
178static int ar9003_hw_proc_txdesc(struct ath_hw *ah, void *ds, 225static int ar9003_hw_proc_txdesc(struct ath_hw *ah, void *ds,
179 struct ath_tx_status *ts) 226 struct ath_tx_status *ts)
180{ 227{
228 struct ar9003_txs *ads;
229
230 ads = &ah->ts_ring[ah->ts_tail];
231
232 if ((ads->status8 & AR_TxDone) == 0)
233 return -EINPROGRESS;
234
235 ah->ts_tail = (ah->ts_tail + 1) % ah->ts_size;
236
237 if ((MS(ads->ds_info, AR_DescId) != ATHEROS_VENDOR_ID) ||
238 (MS(ads->ds_info, AR_TxRxDesc) != 1)) {
239 ath_print(ath9k_hw_common(ah), ATH_DBG_XMIT,
240 "Tx Descriptor error %x\n", ads->ds_info);
241 memset(ads, 0, sizeof(*ads));
242 return -EIO;
243 }
244
245 ts->qid = MS(ads->ds_info, AR_TxQcuNum);
246 ts->desc_id = MS(ads->status1, AR_TxDescId);
247 ts->ts_seqnum = MS(ads->status8, AR_SeqNum);
248 ts->ts_tstamp = ads->status4;
249 ts->ts_status = 0;
250 ts->ts_flags = 0;
251
252 if (ads->status3 & AR_ExcessiveRetries)
253 ts->ts_status |= ATH9K_TXERR_XRETRY;
254 if (ads->status3 & AR_Filtered)
255 ts->ts_status |= ATH9K_TXERR_FILT;
256 if (ads->status3 & AR_FIFOUnderrun) {
257 ts->ts_status |= ATH9K_TXERR_FIFO;
258 ath9k_hw_updatetxtriglevel(ah, true);
259 }
260 if (ads->status8 & AR_TxOpExceeded)
261 ts->ts_status |= ATH9K_TXERR_XTXOP;
262 if (ads->status3 & AR_TxTimerExpired)
263 ts->ts_status |= ATH9K_TXERR_TIMER_EXPIRED;
264
265 if (ads->status3 & AR_DescCfgErr)
266 ts->ts_flags |= ATH9K_TX_DESC_CFG_ERR;
267 if (ads->status3 & AR_TxDataUnderrun) {
268 ts->ts_flags |= ATH9K_TX_DATA_UNDERRUN;
269 ath9k_hw_updatetxtriglevel(ah, true);
270 }
271 if (ads->status3 & AR_TxDelimUnderrun) {
272 ts->ts_flags |= ATH9K_TX_DELIM_UNDERRUN;
273 ath9k_hw_updatetxtriglevel(ah, true);
274 }
275 if (ads->status2 & AR_TxBaStatus) {
276 ts->ts_flags |= ATH9K_TX_BA;
277 ts->ba_low = ads->status5;
278 ts->ba_high = ads->status6;
279 }
280
281 ts->ts_rateindex = MS(ads->status8, AR_FinalTxIdx);
282
283 ts->ts_rssi = MS(ads->status7, AR_TxRSSICombined);
284 ts->ts_rssi_ctl0 = MS(ads->status2, AR_TxRSSIAnt00);
285 ts->ts_rssi_ctl1 = MS(ads->status2, AR_TxRSSIAnt01);
286 ts->ts_rssi_ctl2 = MS(ads->status2, AR_TxRSSIAnt02);
287 ts->ts_rssi_ext0 = MS(ads->status7, AR_TxRSSIAnt10);
288 ts->ts_rssi_ext1 = MS(ads->status7, AR_TxRSSIAnt11);
289 ts->ts_rssi_ext2 = MS(ads->status7, AR_TxRSSIAnt12);
290 ts->ts_shortretry = MS(ads->status3, AR_RTSFailCnt);
291 ts->ts_longretry = MS(ads->status3, AR_DataFailCnt);
292 ts->ts_virtcol = MS(ads->status3, AR_VirtRetryCnt);
293 ts->ts_antenna = 0;
294
295 ts->tid = MS(ads->status8, AR_TxTid);
296
297 memset(ads, 0, sizeof(*ads));
298
181 return 0; 299 return 0;
182} 300}
301
183static void ar9003_hw_set11n_txdesc(struct ath_hw *ah, void *ds, 302static void ar9003_hw_set11n_txdesc(struct ath_hw *ah, void *ds,
184 u32 pktLen, enum ath9k_pkt_type type, u32 txPower, 303 u32 pktlen, enum ath9k_pkt_type type, u32 txpower,
185 u32 keyIx, enum ath9k_key_type keyType, u32 flags) 304 u32 keyIx, enum ath9k_key_type keyType, u32 flags)
186{ 305{
187 306 struct ar9003_txc *ads = (struct ar9003_txc *) ds;
307
308 txpower += ah->txpower_indexoffset;
309 if (txpower > 63)
310 txpower = 63;
311
312 ads->ctl11 = (pktlen & AR_FrameLen)
313 | (flags & ATH9K_TXDESC_VMF ? AR_VirtMoreFrag : 0)
314 | SM(txpower, AR_XmitPower)
315 | (flags & ATH9K_TXDESC_VEOL ? AR_VEOL : 0)
316 | (flags & ATH9K_TXDESC_CLRDMASK ? AR_ClrDestMask : 0)
317 | (keyIx != ATH9K_TXKEYIX_INVALID ? AR_DestIdxValid : 0)
318 | (flags & ATH9K_TXDESC_LOWRXCHAIN ? AR_LowRxChain : 0);
319
320 ads->ctl12 =
321 (keyIx != ATH9K_TXKEYIX_INVALID ? SM(keyIx, AR_DestIdx) : 0)
322 | SM(type, AR_FrameType)
323 | (flags & ATH9K_TXDESC_NOACK ? AR_NoAck : 0)
324 | (flags & ATH9K_TXDESC_EXT_ONLY ? AR_ExtOnly : 0)
325 | (flags & ATH9K_TXDESC_EXT_AND_CTL ? AR_ExtAndCtl : 0);
326
327 ads->ctl17 = SM(keyType, AR_EncrType);
328 ads->ctl18 = 0;
329 ads->ctl19 = AR_Not_Sounding;
330
331 ads->ctl20 = 0;
332 ads->ctl21 = 0;
333 ads->ctl22 = 0;
188} 334}
189 335
190static void ar9003_hw_set11n_ratescenario(struct ath_hw *ah, void *ds, 336static void ar9003_hw_set11n_ratescenario(struct ath_hw *ah, void *ds,
@@ -194,41 +340,119 @@ static void ar9003_hw_set11n_ratescenario(struct ath_hw *ah, void *ds,
194 struct ath9k_11n_rate_series series[], 340 struct ath9k_11n_rate_series series[],
195 u32 nseries, u32 flags) 341 u32 nseries, u32 flags)
196{ 342{
343 struct ar9003_txc *ads = (struct ar9003_txc *) ds;
344 struct ar9003_txc *last_ads = (struct ar9003_txc *) lastds;
345 u_int32_t ctl11;
346
347 if (flags & (ATH9K_TXDESC_RTSENA | ATH9K_TXDESC_CTSENA)) {
348 ctl11 = ads->ctl11;
349
350 if (flags & ATH9K_TXDESC_RTSENA) {
351 ctl11 &= ~AR_CTSEnable;
352 ctl11 |= AR_RTSEnable;
353 } else {
354 ctl11 &= ~AR_RTSEnable;
355 ctl11 |= AR_CTSEnable;
356 }
357
358 ads->ctl11 = ctl11;
359 } else {
360 ads->ctl11 = (ads->ctl11 & ~(AR_RTSEnable | AR_CTSEnable));
361 }
197 362
363 ads->ctl13 = set11nTries(series, 0)
364 | set11nTries(series, 1)
365 | set11nTries(series, 2)
366 | set11nTries(series, 3)
367 | (durUpdateEn ? AR_DurUpdateEna : 0)
368 | SM(0, AR_BurstDur);
369
370 ads->ctl14 = set11nRate(series, 0)
371 | set11nRate(series, 1)
372 | set11nRate(series, 2)
373 | set11nRate(series, 3);
374
375 ads->ctl15 = set11nPktDurRTSCTS(series, 0)
376 | set11nPktDurRTSCTS(series, 1);
377
378 ads->ctl16 = set11nPktDurRTSCTS(series, 2)
379 | set11nPktDurRTSCTS(series, 3);
380
381 ads->ctl18 = set11nRateFlags(series, 0)
382 | set11nRateFlags(series, 1)
383 | set11nRateFlags(series, 2)
384 | set11nRateFlags(series, 3)
385 | SM(rtsctsRate, AR_RTSCTSRate);
386 ads->ctl19 = AR_Not_Sounding;
387
388 last_ads->ctl13 = ads->ctl13;
389 last_ads->ctl14 = ads->ctl14;
198} 390}
199 391
200static void ar9003_hw_set11n_aggr_first(struct ath_hw *ah, void *ds, 392static void ar9003_hw_set11n_aggr_first(struct ath_hw *ah, void *ds,
201 u32 aggrLen) 393 u32 aggrLen)
202{ 394{
395 struct ar9003_txc *ads = (struct ar9003_txc *) ds;
396
397 ads->ctl12 |= (AR_IsAggr | AR_MoreAggr);
203 398
399 ads->ctl17 &= ~AR_AggrLen;
400 ads->ctl17 |= SM(aggrLen, AR_AggrLen);
204} 401}
205 402
206static void ar9003_hw_set11n_aggr_middle(struct ath_hw *ah, void *ds, 403static void ar9003_hw_set11n_aggr_middle(struct ath_hw *ah, void *ds,
207 u32 numDelims) 404 u32 numDelims)
208{ 405{
209 406 struct ar9003_txc *ads = (struct ar9003_txc *) ds;
407 unsigned int ctl17;
408
409 ads->ctl12 |= (AR_IsAggr | AR_MoreAggr);
410
411 /*
412 * We use a stack variable to manipulate ctl6 to reduce uncached
413 * read modify, modfiy, write.
414 */
415 ctl17 = ads->ctl17;
416 ctl17 &= ~AR_PadDelim;
417 ctl17 |= SM(numDelims, AR_PadDelim);
418 ads->ctl17 = ctl17;
210} 419}
211 420
212static void ar9003_hw_set11n_aggr_last(struct ath_hw *ah, void *ds) 421static void ar9003_hw_set11n_aggr_last(struct ath_hw *ah, void *ds)
213{ 422{
423 struct ar9003_txc *ads = (struct ar9003_txc *) ds;
214 424
425 ads->ctl12 |= AR_IsAggr;
426 ads->ctl12 &= ~AR_MoreAggr;
427 ads->ctl17 &= ~AR_PadDelim;
215} 428}
216 429
217static void ar9003_hw_clr11n_aggr(struct ath_hw *ah, void *ds) 430static void ar9003_hw_clr11n_aggr(struct ath_hw *ah, void *ds)
218{ 431{
432 struct ar9003_txc *ads = (struct ar9003_txc *) ds;
219 433
434 ads->ctl12 &= (~AR_IsAggr & ~AR_MoreAggr);
220} 435}
221 436
222static void ar9003_hw_set11n_burstduration(struct ath_hw *ah, void *ds, 437static void ar9003_hw_set11n_burstduration(struct ath_hw *ah, void *ds,
223 u32 burstDuration) 438 u32 burstDuration)
224{ 439{
440 struct ar9003_txc *ads = (struct ar9003_txc *) ds;
441
442 ads->ctl13 &= ~AR_BurstDur;
443 ads->ctl13 |= SM(burstDuration, AR_BurstDur);
225 444
226} 445}
227 446
228static void ar9003_hw_set11n_virtualmorefrag(struct ath_hw *ah, void *ds, 447static void ar9003_hw_set11n_virtualmorefrag(struct ath_hw *ah, void *ds,
229 u32 vmf) 448 u32 vmf)
230{ 449{
450 struct ar9003_txc *ads = (struct ar9003_txc *) ds;
231 451
452 if (vmf)
453 ads->ctl11 |= AR_VirtMoreFrag;
454 else
455 ads->ctl11 &= ~AR_VirtMoreFrag;
232} 456}
233 457
234void ar9003_hw_attach_mac_ops(struct ath_hw *hw) 458void ar9003_hw_attach_mac_ops(struct ath_hw *hw)
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_mac.h b/drivers/net/wireless/ath/ath9k/ar9003_mac.h
index ef7999636ea0..f17558b14539 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_mac.h
+++ b/drivers/net/wireless/ath/ath9k/ar9003_mac.h
@@ -20,7 +20,25 @@
20#define AR_DescId 0xffff0000 20#define AR_DescId 0xffff0000
21#define AR_DescId_S 16 21#define AR_DescId_S 16
22#define AR_CtrlStat 0x00004000 22#define AR_CtrlStat 0x00004000
23#define AR_CtrlStat_S 14
23#define AR_TxRxDesc 0x00008000 24#define AR_TxRxDesc 0x00008000
25#define AR_TxRxDesc_S 15
26#define AR_TxQcuNum 0x00000f00
27#define AR_TxQcuNum_S 8
28
29#define AR_BufLen 0x0fff0000
30#define AR_BufLen_S 16
31
32#define AR_TxDescId 0xffff0000
33#define AR_TxDescId_S 16
34#define AR_TxPtrChkSum 0x0000ffff
35
36#define AR_TxTid 0xf0000000
37#define AR_TxTid_S 28
38
39#define AR_LowRxChain 0x00004000
40
41#define AR_Not_Sounding 0x20000000
24 42
25#define MAP_ISR_S2_CST 6 43#define MAP_ISR_S2_CST 6
26#define MAP_ISR_S2_GTT 6 44#define MAP_ISR_S2_GTT 6
@@ -30,6 +48,8 @@
30#define MAP_ISR_S2_DTIM 7 48#define MAP_ISR_S2_DTIM 7
31#define MAP_ISR_S2_TSFOOR 4 49#define MAP_ISR_S2_TSFOOR 4
32 50
51#define AR9003TXC_CONST(_ds) ((const struct ar9003_txc *) _ds)
52
33struct ar9003_rxs { 53struct ar9003_rxs {
34 u32 ds_info; 54 u32 ds_info;
35 u32 status1; 55 u32 status1;
diff --git a/drivers/net/wireless/ath/ath9k/mac.h b/drivers/net/wireless/ath/ath9k/mac.h
index eb430c471c5c..b591dc27c325 100644
--- a/drivers/net/wireless/ath/ath9k/mac.h
+++ b/drivers/net/wireless/ath/ath9k/mac.h
@@ -116,7 +116,10 @@ struct ath_tx_status {
116 int8_t ts_rssi_ext0; 116 int8_t ts_rssi_ext0;
117 int8_t ts_rssi_ext1; 117 int8_t ts_rssi_ext1;
118 int8_t ts_rssi_ext2; 118 int8_t ts_rssi_ext2;
119 u8 pad[3]; 119 u8 qid;
120 u16 desc_id;
121 u8 tid;
122 u8 pad[2];
120 u32 ba_low; 123 u32 ba_low;
121 u32 ba_high; 124 u32 ba_high;
122 u32 evm0; 125 u32 evm0;
@@ -260,7 +263,7 @@ struct ath_desc {
260#define ATH9K_TXDESC_EXT_AND_CTL 0x0080 263#define ATH9K_TXDESC_EXT_AND_CTL 0x0080
261#define ATH9K_TXDESC_VMF 0x0100 264#define ATH9K_TXDESC_VMF 0x0100
262#define ATH9K_TXDESC_FRAG_IS_ON 0x0200 265#define ATH9K_TXDESC_FRAG_IS_ON 0x0200
263#define ATH9K_TXDESC_CAB 0x0400 266#define ATH9K_TXDESC_LOWRXCHAIN 0x0400
264 267
265#define ATH9K_RXDESC_INTREQ 0x0020 268#define ATH9K_RXDESC_INTREQ 0x0020
266 269