1/*
2 * Copyright (c) 2012 Adrian Chadd <adrian@FreeBSD.org>
3 * All Rights Reserved.
4 *
5 * Permission to use, copy, modify, and/or distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above
7 * copyright notice and this permission notice appear in all copies.
8 *
9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16 */
17
18#include <sys/cdefs.h>
19#include <stdio.h>
20#include <stdlib.h>
21#include <unistd.h>
22#include <fcntl.h>
23#include <errno.h>
24#include <string.h>
25
26#include <sys/types.h>
27#include <sys/alq.h>
28#include <sys/endian.h>
29
30#include <dev/ath/if_ath_alq.h>
31#include <dev/ath/ath_hal/ar5212/ar5212desc.h>
32
33#include "ar5212_ds.h"
34
35#define	MS(_v, _f)	( ((_v) & (_f)) >> _f##_S )
36#define	MF(_v, _f) ( !! ((_v) & (_f)))
37
38static void
39ar5212_decode_txstatus(struct if_ath_alq_payload *a)
40{
41	struct ar5212_desc txs;
42
43	/* XXX assumes txs is smaller than PAYLOAD_LEN! */
44	memcpy(&txs, &a->payload, sizeof(struct ar5212_desc));
45
46	printf("[%u.%06u] [%llu] TXSTATUS: TxDone=%d, TS=0x%08x\n\n",
47	    (unsigned int) be32toh(a->hdr.tstamp_sec),
48	    (unsigned int) be32toh(a->hdr.tstamp_usec),
49	    (unsigned long long) be64toh(a->hdr.threadid),
50	    MF(txs.u.tx.status1, AR_Done),
51	    MS(txs.u.tx.status0, AR_SendTimestamp));
52
53	/* ds_txstatus0 */
54	printf("    Frmok=%d, xretries=%d, fifounderrun=%d, filt=%d\n",
55	    MF(txs.u.tx.status0, AR_FrmXmitOK),
56	    MF(txs.u.tx.status0, AR_ExcessiveRetries),
57	    MF(txs.u.tx.status0, AR_FIFOUnderrun),
58	    MF(txs.u.tx.status0, AR_Filtered));
59	printf("    RTScnt=%d, FailCnt=%d, VCollCnt=%d\n",
60	    MS(txs.u.tx.status0, AR_RTSFailCnt),
61	    MS(txs.u.tx.status0, AR_DataFailCnt),
62	    MS(txs.u.tx.status0, AR_VirtCollCnt));
63	printf("    SndTimestamp=0x%04x\n",
64	    MS(txs.u.tx.status0, AR_SendTimestamp));
65
66	/* ds_txstatus1 */
67	printf("    Done=%d, SeqNum=0x%04x, AckRSSI=%d, FinalTSI=%d\n",
68	    MF(txs.u.tx.status1, AR_Done),
69	    MS(txs.u.tx.status1, AR_SeqNum),
70	    MS(txs.u.tx.status1, AR_AckSigStrength),
71	    MS(txs.u.tx.status1, AR_FinalTSIndex));
72	printf("    CompSuccess=%d, XmitAntenna=%d\n",
73	    MF(txs.u.tx.status1, AR_CompSuccess),
74	    MF(txs.u.tx.status1, AR_XmitAtenna));
75
76	printf("\n ------\n");
77}
78
79static void
80ar5212_decode_txdesc(struct if_ath_alq_payload *a)
81{
82	struct ar5212_desc txc;
83
84	/* XXX assumes txs is smaller than PAYLOAD_LEN! */
85	memcpy(&txc, &a->payload, sizeof(struct ar5212_desc));
86
87	printf("[%u.%06u] [%llu] TXD\n",
88	    (unsigned int) be32toh(a->hdr.tstamp_sec),
89	    (unsigned int) be32toh(a->hdr.tstamp_usec),
90	    (unsigned long long) be64toh(a->hdr.threadid));
91
92	printf("  link=0x%08x, data=0x%08x\n",
93	    txc.ds_link,
94	    txc.ds_data);
95
96	/* ds_ctl0 */
97	printf("    Frame Len=%d\n", txc.ds_ctl0 & AR_FrameLen);
98	printf("    TX power0=%d, RtsEna=%d, Veol=%d, ClrDstMask=%d AntModeXmit=0x%02x\n",
99	    MS(txc.ds_ctl0, AR_XmitPower),
100	    MF(txc.ds_ctl0, AR_RTSCTSEnable),
101	    MF(txc.ds_ctl0, AR_VEOL),
102	    MF(txc.ds_ctl0, AR_ClearDestMask),
103	    MF(txc.ds_ctl0, AR_AntModeXmit));
104	printf("    TxIntrReq=%d, DestIdxValid=%d, CtsEnable=%d\n",
105	    MF(txc.ds_ctl0, AR_TxInterReq),
106	    MF(txc.ds_ctl0, AR_DestIdxValid),
107	    MF(txc.ds_ctl0, AR_CTSEnable));
108
109	/* ds_ctl1 */
110	printf("    BufLen=%d, TxMore=%d, DestIdx=%d,"
111	    " FrType=0x%x\n",
112	    txc.ds_ctl1 & AR_BufLen,
113	    MF(txc.ds_ctl1, AR_More),
114	    MS(txc.ds_ctl1, AR_DestIdx),
115	    MS(txc.ds_ctl1, AR_FrmType));
116	printf("    NoAck=%d, CompProc=%d, CompIVLen=%d, CompICVLen=%d\n",
117	    MF(txc.ds_ctl1, AR_NoAck),
118	    MS(txc.ds_ctl1, AR_CompProc),
119	    MS(txc.ds_ctl1, AR_CompIVLen),
120	    MS(txc.ds_ctl1, AR_CompICVLen));
121
122	/* ds_ctl2 */
123	printf("    DurUpEna=%d, Burstdur=0x%04x\n",
124	    MF(txc.ds_ctl2, AR_DurUpdateEna),
125	    MS(txc.ds_ctl2, AR_RTSCTSDuration));
126	printf("    Try0=%d, Try1=%d, Try2=%d, Try3=%d\n",
127	    MS(txc.ds_ctl2, AR_XmitDataTries0),
128	    MS(txc.ds_ctl2, AR_XmitDataTries1),
129	    MS(txc.ds_ctl2, AR_XmitDataTries2),
130	    MS(txc.ds_ctl2, AR_XmitDataTries3));
131
132	/* ds_ctl3 */
133	printf("    rate0=0x%02x, rate1=0x%02x, rate2=0x%02x, rate3=0x%02x\n",
134	    MS(txc.ds_ctl3, AR_XmitRate0),
135	    MS(txc.ds_ctl3, AR_XmitRate1),
136	    MS(txc.ds_ctl3, AR_XmitRate2),
137	    MS(txc.ds_ctl3, AR_XmitRate3));
138	printf("    RtsCtsRate=0x%02x\n",
139	    MS(txc.ds_ctl3, AR_RTSCTSRate));
140
141	printf("\n ------ \n");
142}
143
144static void
145ar5212_decode_rxstatus(struct if_ath_alq_payload *a)
146{
147	struct ar5212_desc rxs;
148
149	/* XXX assumes rxs is smaller than PAYLOAD_LEN! */
150	memcpy(&rxs, &a->payload, sizeof(struct ar5212_desc));
151
152	printf("[%u.%06u] [%llu] RXSTATUS: RxOK=%d TS=0x%08x\n",
153	    (unsigned int) be32toh(a->hdr.tstamp_sec),
154	    (unsigned int) be32toh(a->hdr.tstamp_usec),
155	    (unsigned long long) be64toh(a->hdr.threadid),
156	    MF(rxs.ds_rxstatus1, AR_Done),
157	    MS(rxs.ds_rxstatus1, AR_RcvTimestamp));
158
159	printf("  link=0x%08x, data=0x%08x, ctl0=0x%08x, ctl2=0x%08x\n",
160	    rxs.ds_link,
161	    rxs.ds_data,
162	    rxs.ds_ctl0,
163	    rxs.ds_ctl1);
164
165	/* ds_rxstatus0 */
166	printf("  DataLen=%d, ArMore=%d, DecompCrcError=%d, RcvRate=0x%02x\n",
167	    rxs.ds_rxstatus0 & AR_DataLen,
168	    MF(rxs.ds_rxstatus0, AR_More),
169	    MF(rxs.ds_rxstatus0, AR_DecompCRCErr),
170	    MS(rxs.ds_rxstatus0, AR_RcvRate));
171	printf("  RSSI=%d, RcvAntenna=0x%x\n",
172	    MS(rxs.ds_rxstatus0, AR_RcvSigStrength),
173	    MS(rxs.ds_rxstatus0, AR_RcvAntenna));
174
175	/* ds_rxstatus1 */
176	printf("  RxDone=%d, RxFrameOk=%d, CrcErr=%d, DecryptCrcErr=%d\n",
177	    MF(rxs.ds_rxstatus1, AR_Done),
178	    MF(rxs.ds_rxstatus1, AR_FrmRcvOK),
179	    MF(rxs.ds_rxstatus1, AR_CRCErr),
180	    MF(rxs.ds_rxstatus1, AR_DecryptCRCErr));
181	printf("  PhyErr=%d, MichaelErr=%d, KeyIdxValid=%d\n",
182	    MF(rxs.ds_rxstatus1, AR_PHYErr),
183	    MF(rxs.ds_rxstatus1, AR_MichaelErr),
184	    MF(rxs.ds_rxstatus1, AR_KeyIdxValid));
185
186	/* If PHY error, print that out. Otherwise, the key index */
187	if (MF(rxs.ds_rxstatus1, AR_PHYErr))
188		printf("  PhyErrCode=0x%02x\n",
189		    MS(rxs.ds_rxstatus1, AR_PHYErrCode));
190	else
191		printf("  KeyIdx=0x%02x\n",
192		    MS(rxs.ds_rxstatus1, AR_KeyIdx));
193
194	printf("  KeyMiss=%d\n",
195	    MF(rxs.ds_rxstatus1, AR_KeyCacheMiss));
196
197	printf("  Timetamp: 0x%05x\n",
198	    MS(rxs.ds_rxstatus1, AR_RcvTimestamp));
199
200	printf("\n ------\n");
201}
202
203void
204ar5212_alq_payload(struct if_ath_alq_payload *a)
205{
206
207		switch (be16toh(a->hdr.op)) {
208			case ATH_ALQ_EDMA_TXSTATUS:	/* TXSTATUS */
209				ar5212_decode_txstatus(a);
210				break;
211			case ATH_ALQ_EDMA_RXSTATUS:	/* RXSTATUS */
212				ar5212_decode_rxstatus(a);
213				break;
214			case ATH_ALQ_EDMA_TXDESC:	/* TXDESC */
215				ar5212_decode_txdesc(a);
216				break;
217			default:
218				printf("[%d.%06d] [%lld] op: %d; len %d\n",
219				    be32toh(a->hdr.tstamp_sec),
220				    be32toh(a->hdr.tstamp_usec),
221				    be64toh(a->hdr.threadid),
222				    be16toh(a->hdr.op), be16toh(a->hdr.len));
223		}
224}
225