1/*
2 * Copyright (c) 2012 Adrian Chadd <adrian@FreeBSD.org>
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#include <sys/cdefs.h>
18__FBSDID("$FreeBSD$");
19
20#include <stdio.h>
21#include <stdlib.h>
22#include <unistd.h>
23#include <fcntl.h>
24#include <errno.h>
25#include <string.h>
26
27#include <sys/types.h>
28#include <sys/alq.h>
29#include <sys/endian.h>
30
31#include <dev/ath/if_ath_alq.h>
32#include <ar9300/ar9300desc.h>
33
34#include "ar9300_ds.h"
35
36/* XXX should break this out into if_athvar.h */
37
38#define	MS(_v, _f)	( ((_v) & (_f)) >> _f##_S )
39#define	MF(_v, _f) ( !! ((_v) & (_f)))
40
41static uint32_t last_ts = 0;
42
43void
44ath_alq_print_edma_tx_fifo_push(struct if_ath_alq_payload *a)
45{
46	struct if_ath_alq_tx_fifo_push p;
47
48	memcpy(&p, &a->payload, sizeof(p));
49	printf("[%u.%06u] [%llu] TXPUSH txq=%d, nframes=%d, fifodepth=%d, frmcount=%d\n",
50	    (unsigned int) be32toh(a->hdr.tstamp_sec),
51	    (unsigned int) be32toh(a->hdr.tstamp_usec),
52	    (unsigned long long) be64toh(a->hdr.threadid),
53	    be32toh(p.txq),
54	    be32toh(p.nframes),
55	    be32toh(p.fifo_depth),
56	    be32toh(p.frame_cnt));
57}
58
59static void
60ar9300_decode_txstatus(struct if_ath_alq_payload *a)
61{
62	struct ar9300_txs txs;
63
64	/* XXX assumes txs is smaller than PAYLOAD_LEN! */
65	memcpy(&txs, &a->payload, sizeof(struct ar9300_txs));
66
67	printf("[%u.%06u] [%llu] TXSTATUS TxTimestamp=%u (%u), DescId=0x%04x, QCU=%d\n",
68	    (unsigned int) be32toh(a->hdr.tstamp_sec),
69	    (unsigned int) be32toh(a->hdr.tstamp_usec),
70	    (unsigned long long) be64toh(a->hdr.threadid),
71	    txs.status4,
72	    txs.status4 - last_ts,
73	    (unsigned int) MS(txs.status1, AR_tx_desc_id),
74	    (unsigned int) MS(txs.ds_info, AR_tx_qcu_num));
75	printf("    DescId=0x%08x\n", txs.status1);
76
77	last_ts = txs.status4;
78
79	printf("    DescLen=%d, TxQcuNum=%d, CtrlStat=%d, DescId=0x%04x\n",
80	    txs.ds_info & 0xff,
81	    MS(txs.ds_info, AR_tx_qcu_num),
82	    MS(txs.ds_info, AR_ctrl_stat),
83	    MS(txs.ds_info, AR_desc_id));
84
85	printf("    TxTimestamp: %u\n", txs.status4);
86
87	printf("    TxDone=%d, SeqNo=%d, TxOpExceed=%d, TXBFStatus=%d\n",
88	    MF(txs.status8, AR_tx_done),
89	    MS(txs.status8, AR_seq_num),
90	    MF(txs.status8, AR_tx_op_exceeded),
91	    MS(txs.status8, AR_TXBFStatus));
92
93	printf("    TXBfMismatch=%d, BFStreamMiss=%d, FinalTxIdx=%d\n",
94	    MF(txs.status8, AR_tx_bf_bw_mismatch),
95	    MF(txs.status8, AR_tx_bf_stream_miss),
96	    MS(txs.status8, AR_final_tx_idx));
97
98	printf("    TxBfDestMiss=%d, TxBfExpired=%d, PwrMgmt=%d, Tid=%d,"
99	    " FastTsBit=%d\n",
100	    MF(txs.status8, AR_tx_bf_dest_miss),
101	    MF(txs.status8, AR_tx_bf_expired),
102	    MF(txs.status8, AR_power_mgmt),
103	    MS(txs.status8, AR_tx_tid),
104	    MF(txs.status8, AR_tx_fast_ts));
105
106	printf("    Frmok=%d, xretries=%d, fifounderrun=%d, filt=%d\n",
107	    MF(txs.status3, AR_frm_xmit_ok),
108	    MF(txs.status3, AR_excessive_retries),
109	    MF(txs.status3, AR_fifounderrun),
110	    MF(txs.status3, AR_filtered));
111	printf("    DelimUnderrun=%d, DataUnderun=%d, DescCfgErr=%d,"
112	    " TxTimerExceeded=%d\n",
113	    MF(txs.status3, AR_tx_delim_underrun),
114	    MF(txs.status3, AR_tx_data_underrun),
115	    MF(txs.status3, AR_desc_cfg_err),
116	    MF(txs.status3, AR_tx_timer_expired));
117
118	printf("    RTScnt=%d, FailCnt=%d, VRetryCnt=%d\n",
119	    MS(txs.status3, AR_rts_fail_cnt),
120	    MS(txs.status3, AR_data_fail_cnt),
121	    MS(txs.status3, AR_virt_retry_cnt));
122
123
124
125	printf("    RX RSSI 0 [%d %d %d]\n",
126	    MS(txs.status2, AR_tx_rssi_ant00),
127	    MS(txs.status2, AR_tx_rssi_ant01),
128	    MS(txs.status2, AR_tx_rssi_ant02));
129
130	printf("    RX RSSI 1 [%d %d %d] Comb=%d\n",
131	    MS(txs.status7, AR_tx_rssi_ant10),
132	    MS(txs.status7, AR_tx_rssi_ant11),
133	    MS(txs.status7, AR_tx_rssi_ant12),
134	    MS(txs.status7, AR_tx_rssi_combined));
135
136	printf("    BA Valid=%d\n",
137	    MF(txs.status2, AR_tx_ba_status));
138
139	printf("    BALow=0x%08x\n", txs.status5);
140	printf("    BAHigh=0x%08x\n", txs.status6);
141
142	printf("\n ------ \n");
143}
144
145/*
146 * Note - these are rounded up to 128 bytes; but we
147 * only use 96 bytes from it.
148 */
149static void
150ar9300_decode_txdesc(struct if_ath_alq_payload *a)
151{
152	struct ar9300_txc txc;
153
154	/* XXX assumes txs is smaller than PAYLOAD_LEN! */
155	memcpy(&txc, &a->payload, 96);
156
157	printf("[%u.%06u] [%llu] TXD DescId=0x%04x\n",
158	    (unsigned int) be32toh(a->hdr.tstamp_sec),
159	    (unsigned int) be32toh(a->hdr.tstamp_usec),
160	    (unsigned long long) be64toh(a->hdr.threadid),
161	    (unsigned int) MS(txc.ds_ctl10, AR_tx_desc_id));
162
163	printf("  DescLen=%d, TxQcuNum=%d, CtrlStat=%d, DescId=0x%04x\n",
164	    txc.ds_info & 0xff,
165	    MS(txc.ds_info, AR_tx_qcu_num),
166	    MS(txc.ds_info, AR_ctrl_stat),
167	    MS(txc.ds_info, AR_desc_id));
168
169	/* link */
170	printf("    Link 0x%08x\n", txc.ds_link);
171
172	/* data0 */
173	printf("    Data0 0x%08x Len %d\n",
174	    txc.ds_data0,
175	    MS(txc.ds_ctl3, AR_buf_len));
176
177	/* data1 */
178	printf("    Data1 0x%08x Len %d\n",
179	    txc.ds_data1,
180	    MS(txc.ds_ctl5, AR_buf_len));
181
182	/* data2 */
183	printf("    Data2 0x%08x Len %d\n",
184	    txc.ds_data2,
185	    MS(txc.ds_ctl7, AR_buf_len));
186
187	/* data3 */
188	printf("    Data3 0x%08x Len %d\n",
189	    txc.ds_data3,
190	    MS(txc.ds_ctl9, AR_buf_len));
191
192
193	/* ctl10 */
194	printf("    Desc ID=0x%04x, Chksum=0x%04x (ctl10=0x%08x)\n",
195	    MS(txc.ds_ctl10, AR_tx_desc_id),
196	    txc.ds_ctl10 & AR_tx_ptr_chk_sum,
197	    txc.ds_ctl10);
198
199	/* ctl11 */
200	printf("    Frame Len=%d, VMF=%d, LowRxChain=%d, TxClrRetry=%d\n",
201	     txc.ds_ctl11 & AR_frame_len,
202	    MF(txc.ds_ctl11, AR_virt_more_frag),
203	    MF(txc.ds_ctl11, AR_low_rx_chain),
204	    MF(txc.ds_ctl11, AR_tx_clear_retry));
205	printf("    TX power 0 = %d, RtsEna=%d, Veol=%d, ClrDstMask=%d\n",
206	    MS(txc.ds_ctl11, AR_xmit_power0),
207	    MF(txc.ds_ctl11, AR_rts_enable),
208	    MF(txc.ds_ctl11, AR_veol),
209	    MF(txc.ds_ctl11, AR_clr_dest_mask));
210	printf("    TxIntrReq=%d, DestIdxValid=%d, CtsEnable=%d\n",
211	    MF(txc.ds_ctl11, AR_tx_intr_req),
212	    MF(txc.ds_ctl11, AR_dest_idx_valid),
213	    MF(txc.ds_ctl11, AR_cts_enable));
214
215	/* ctl12 */
216	printf("    Paprd Chain Mask=0x%x, TxMore=%d, DestIdx=%d,"
217	    " FrType=0x%x\n",
218	    MS(txc.ds_ctl12, AR_paprd_chain_mask),
219	    MF(txc.ds_ctl12, AR_tx_more),
220	    MS(txc.ds_ctl12, AR_dest_idx),
221	    MS(txc.ds_ctl12, AR_frame_type));
222	printf("    NoAck=%d, InsertTs=%d, CorruptFcs=%d, ExtOnly=%d,"
223	    " ExtAndCtl=%d\n",
224	    MF(txc.ds_ctl12, AR_no_ack),
225	    MF(txc.ds_ctl12, AR_insert_ts),
226	    MF(txc.ds_ctl12, AR_corrupt_fcs),
227	    MF(txc.ds_ctl12, AR_ext_only),
228	    MF(txc.ds_ctl12, AR_ext_and_ctl));
229	printf("    IsAggr=%d, MoreRifs=%d, LocMode=%d\n",
230	    MF(txc.ds_ctl12, AR_is_aggr),
231	    MF(txc.ds_ctl12, AR_more_rifs),
232	    MF(txc.ds_ctl12, AR_loc_mode));
233
234
235	/* ctl13 */
236	printf("    DurUpEna=%d, Burstdur=0x%04x\n",
237	    MF(txc.ds_ctl13, AR_dur_update_ena),
238	    MS(txc.ds_ctl13, AR_burst_dur));
239	printf("    Try0=%d, Try1=%d, Try2=%d, Try3=%d\n",
240	    MS(txc.ds_ctl13, AR_xmit_data_tries0),
241	    MS(txc.ds_ctl13, AR_xmit_data_tries1),
242	    MS(txc.ds_ctl13, AR_xmit_data_tries2),
243	    MS(txc.ds_ctl13, AR_xmit_data_tries3));
244
245	/* ctl14 */
246	printf("    rate0=0x%02x, rate1=0x%02x, rate2=0x%02x, rate3=0x%02x\n",
247	    MS(txc.ds_ctl14, AR_xmit_rate0),
248	    MS(txc.ds_ctl14, AR_xmit_rate1),
249	    MS(txc.ds_ctl14, AR_xmit_rate2),
250	    MS(txc.ds_ctl14, AR_xmit_rate3));
251
252	/* ctl15 */
253	printf("    try 0: PktDur=%d, RTS/CTS ena=%d\n",
254	    MS(txc.ds_ctl15, AR_packet_dur0),
255	    MF(txc.ds_ctl15, AR_rts_cts_qual0));
256	printf("    try 1: PktDur=%d, RTS/CTS ena=%d\n",
257	    MS(txc.ds_ctl15, AR_packet_dur1),
258	    MF(txc.ds_ctl15, AR_rts_cts_qual1));
259
260	/* ctl16 */
261	printf("    try 2: PktDur=%d, RTS/CTS ena=%d\n",
262	    MS(txc.ds_ctl16, AR_packet_dur2),
263	    MF(txc.ds_ctl16, AR_rts_cts_qual2));
264	printf("    try 3: PktDur=%d, RTS/CTS ena=%d\n",
265	    MS(txc.ds_ctl16, AR_packet_dur3),
266	    MF(txc.ds_ctl16, AR_rts_cts_qual3));
267
268	/* ctl17 */
269	printf("    AggrLen=%d, PadDelim=%d, EncrType=%d, TxDcApStaSel=%d\n",
270	    MS(txc.ds_ctl17, AR_aggr_len),
271	    MS(txc.ds_ctl17, AR_pad_delim),
272	    MS(txc.ds_ctl17, AR_encr_type),
273	    MF(txc.ds_ctl17, AR_tx_dc_ap_sta_sel));
274	printf("    Calib=%d LDPC=%d\n",
275	    MF(txc.ds_ctl17, AR_calibrating),
276	    MF(txc.ds_ctl17, AR_ldpc));
277
278	/* ctl18 */
279	printf("    try 0: chainMask=0x%x, GI=%d, 2040=%d, STBC=%d\n",
280	    MS(txc.ds_ctl18, AR_chain_sel0),
281	    MF(txc.ds_ctl18, AR_gi0),
282	    MF(txc.ds_ctl18, AR_2040_0),
283	    MF(txc.ds_ctl18, AR_stbc0));
284	printf("    try 1: chainMask=0x%x, GI=%d, 2040=%d, STBC=%d\n",
285	    MS(txc.ds_ctl18, AR_chain_sel1),
286	    MF(txc.ds_ctl18, AR_gi1),
287	    MF(txc.ds_ctl18, AR_2040_1),
288	    MF(txc.ds_ctl18, AR_stbc1));
289	printf("    try 2: chainMask=0x%x, GI=%d, 2040=%d, STBC=%d\n",
290	    MS(txc.ds_ctl18, AR_chain_sel2),
291	    MF(txc.ds_ctl18, AR_gi2),
292	    MF(txc.ds_ctl18, AR_2040_2),
293	    MF(txc.ds_ctl18, AR_stbc2));
294	printf("    try 3: chainMask=0x%x, GI=%d, 2040=%d, STBC=%d\n",
295	    MS(txc.ds_ctl18, AR_chain_sel3),
296	    MF(txc.ds_ctl18, AR_gi3),
297	    MF(txc.ds_ctl18, AR_2040_3),
298	    MF(txc.ds_ctl18, AR_stbc3));
299
300	/* ctl19 */
301	printf("    NotSounding=%d\n",
302	    MF(txc.ds_ctl19, AR_not_sounding));
303
304	printf("    try 0: ant=0x%08x, antsel=%d, ness=%d\n",
305	    txc.ds_ctl19 &  AR_tx_ant0,
306	    MF(txc.ds_ctl19, AR_tx_ant_sel0),
307	    MS(txc.ds_ctl19, AR_ness));
308
309	/* ctl20 */
310	printf("    try 1: TxPower=%d, ant=0x%08x, antsel=%d, ness=%d\n",
311	    MS(txc.ds_ctl20, AR_xmit_power1),
312	    txc.ds_ctl20 &  AR_tx_ant1,
313	    MF(txc.ds_ctl20, AR_tx_ant_sel1),
314	    MS(txc.ds_ctl20, AR_ness1));
315
316	/* ctl21 */
317	printf("    try 2: TxPower=%d, ant=0x%08x, antsel=%d, ness=%d\n",
318	    MS(txc.ds_ctl21, AR_xmit_power2),
319	    txc.ds_ctl21 &  AR_tx_ant2,
320	    MF(txc.ds_ctl21, AR_tx_ant_sel2),
321	    MS(txc.ds_ctl21, AR_ness2));
322
323	/* ctl22 */
324	printf("    try 3: TxPower=%d, ant=0x%08x, antsel=%d, ness=%d\n",
325	    MS(txc.ds_ctl22, AR_xmit_power3),
326	    txc.ds_ctl22 &  AR_tx_ant3,
327	    MF(txc.ds_ctl22, AR_tx_ant_sel3),
328	    MS(txc.ds_ctl22, AR_ness3));
329
330	printf("\n ------ \n");
331}
332
333static void
334ar9300_decode_rxstatus(struct if_ath_alq_payload *a)
335{
336	struct ar9300_rxs rxs;
337
338	/* XXX assumes rxs is smaller than PAYLOAD_LEN! */
339	memcpy(&rxs, &a->payload, sizeof(struct ar9300_rxs));
340
341	printf("[%u.%06u] [%llu] RXSTATUS RxTimestamp: %u (%d)\n",
342	    (unsigned int) be32toh(a->hdr.tstamp_sec),
343	    (unsigned int) be32toh(a->hdr.tstamp_usec),
344	    (unsigned long long) be64toh(a->hdr.threadid),
345	    rxs.status3,
346	    rxs.status3 - last_ts);
347
348	/* status1 */
349	/* .. and status5 */
350	printf("    RSSI %d/%d/%d / %d/%d/%d; combined: %d; rate=0x%02x\n",
351	    MS(rxs.status1, AR_rx_rssi_ant00),
352	    MS(rxs.status1, AR_rx_rssi_ant01),
353	    MS(rxs.status1, AR_rx_rssi_ant02),
354	    MS(rxs.status5, AR_rx_rssi_ant10),
355	    MS(rxs.status5, AR_rx_rssi_ant11),
356	    MS(rxs.status5, AR_rx_rssi_ant12),
357	    MS(rxs.status5, AR_rx_rssi_combined),
358	    MS(rxs.status1, AR_rx_rate));
359
360	/* status2 */
361	printf("    Len: %d; more=%d, delim=%d, upload=%d\n",
362	    MS(rxs.status2, AR_data_len),
363	    MF(rxs.status2, AR_rx_more),
364	    MS(rxs.status2, AR_num_delim),
365	    MS(rxs.status2, AR_hw_upload_data));
366
367	/* status3 */
368	printf("    RX timestamp: %u\n", rxs.status3);
369	last_ts = rxs.status3;
370
371	/* status4 */
372	printf("    GI: %d, 2040: %d, parallel40: %d, stbc=%d\n",
373	    MF(rxs.status4, AR_gi),
374	    MF(rxs.status4, AR_2040),
375	    MF(rxs.status4, AR_parallel40),
376	    MF(rxs.status4, AR_rx_stbc));
377	printf("    Not sounding: %d, ness: %d, upload_valid: %d\n",
378	    MF(rxs.status4, AR_rx_not_sounding),
379	    MS(rxs.status4, AR_rx_ness),
380	    MS(rxs.status4, AR_hw_upload_data_valid));
381	printf("    RX antenna: 0x%08x\n",
382	    MS(rxs.status4, AR_rx_antenna));
383
384	/* EVM */
385	/* status6 - 9 */
386	printf("    EVM: 0x%08x; 0x%08x; 0x%08x; 0x%08x\n",
387	    rxs.status6,
388	    rxs.status7,
389	    rxs.status8,
390	    rxs.status9);
391
392	/* status10 - ? */
393
394	/* status11 */
395	printf("    RX done: %d, RX frame ok: %d, CRC error: %d\n",
396	    MF(rxs.status11, AR_rx_done),
397	    MF(rxs.status11, AR_rx_frame_ok),
398	    MF(rxs.status11, AR_crc_err));
399	printf("    Decrypt CRC err: %d, PHY err: %d, MIC err: %d\n",
400	    MF(rxs.status11, AR_decrypt_crc_err),
401	    MF(rxs.status11, AR_phyerr),
402	    MF(rxs.status11, AR_michael_err));
403	printf("    Pre delim CRC err: %d, uAPSD Trig: %d\n",
404	    MF(rxs.status11, AR_pre_delim_crc_err),
405	    MF(rxs.status11, AR_apsd_trig));
406	printf("    RXKeyIdxValid: %d, KeyIdx: %d, PHY error: %d\n",
407	    MF(rxs.status11, AR_rx_key_idx_valid),
408	    MS(rxs.status11, AR_key_idx),
409	    MS(rxs.status11, AR_phy_err_code));
410	printf("    RX more Aggr: %d, RX aggr %d, post delim CRC err: %d\n",
411	    MF(rxs.status11, AR_rx_more_aggr),
412	    MF(rxs.status11, AR_rx_aggr),
413	    MF(rxs.status11, AR_post_delim_crc_err));
414	printf("    hw upload data type: %d; position bit: %d\n",
415	    MS(rxs.status11, AR_hw_upload_data_type),
416	    MF(rxs.status11, AR_position_bit));
417	printf("    Hi RX chain: %d, RxFirstAggr: %d, DecryptBusy: %d, KeyMiss: %d\n",
418	    MF(rxs.status11, AR_hi_rx_chain),
419	    MF(rxs.status11, AR_rx_first_aggr),
420	    MF(rxs.status11, AR_decrypt_busy_err),
421	    MF(rxs.status11, AR_key_miss));
422}
423
424void
425ar9300_alq_payload(struct if_ath_alq_payload *a)
426{
427
428		switch (be16toh(a->hdr.op)) {
429			case ATH_ALQ_EDMA_TXSTATUS:	/* TXSTATUS */
430				ar9300_decode_txstatus(a);
431				break;
432			case ATH_ALQ_EDMA_RXSTATUS:	/* RXSTATUS */
433				ar9300_decode_rxstatus(a);
434				break;
435			case ATH_ALQ_EDMA_TXDESC:	/* TXDESC */
436				ar9300_decode_txdesc(a);
437				break;
438			default:
439				printf("[%d.%06d] [%lld] op: %d; len %d\n",
440				    be32toh(a->hdr.tstamp_sec),
441				    be32toh(a->hdr.tstamp_usec),
442				    be64toh(a->hdr.threadid),
443				    be16toh(a->hdr.op), be16toh(a->hdr.len));
444		}
445}
446