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 __FBSDID("$FreeBSD$"); 20 21 #include <stdio.h> 22 #include <stdlib.h> 23 #include <unistd.h> 24 #include <fcntl.h> 25 #include <errno.h> 26 #include <string.h> 27 28 #include <sys/types.h> 29 #include <sys/alq.h> 30 #include <sys/endian.h> 31 32 #include <dev/ath/if_ath_alq.h> 33 #include <dev/ath/ath_hal/ar5416/ar5416desc.h> 34 35 #include "ar5416_ds.h" 36 37 #define MS(_v, _f) ( ((_v) & (_f)) >> _f##_S ) 38 #define MF(_v, _f) ( !! ((_v) & (_f))) 39 40 static void 41 ar5416_decode_txstatus(struct if_ath_alq_payload *a) 42 { 43 struct ar5416_desc txs; 44 static uint64_t tx_tsf = 0; 45 46 /* XXX assumes txs is smaller than PAYLOAD_LEN! */ 47 memcpy(&txs, &a->payload, sizeof(struct ar5416_desc)); 48 49 if (MF(txs.u.tx.status[9], AR_TxDone) == 0) 50 return; 51 52 printf("[%u] [%llu] TXSTATUS: TxDone=%d, TS=0x%08x (delta %d)\n", 53 (unsigned int) be32toh(a->hdr.tstamp), 54 (unsigned long long) be64toh(a->hdr.threadid), 55 MF(txs.u.tx.status[9], AR_TxDone), 56 txs.u.tx.status[2], 57 txs.u.tx.status[2] - tx_tsf); 58 59 tx_tsf = txs.u.tx.status[2]; 60 61 #if 0 62 /* ds_txstatus0 */ 63 printf(" RX RSSI 0 [%d %d %d]\n", 64 MS(txs.u.tx.status[0], AR_TxRSSIAnt00), 65 MS(txs.u.tx.status[0], AR_TxRSSIAnt01), 66 MS(txs.u.tx.status[0], AR_TxRSSIAnt02)); 67 printf(" BA Valid=%d\n", 68 MF(txs.u.tx.status[0], AR_TxBaStatus)); 69 70 /* ds_txstatus1 */ 71 printf(" Frmok=%d, xretries=%d, fifounderrun=%d, filt=%d\n", 72 MF(txs.u.tx.status[1], AR_FrmXmitOK), 73 MF(txs.u.tx.status[1], AR_ExcessiveRetries), 74 MF(txs.u.tx.status[1], AR_FIFOUnderrun), 75 MF(txs.u.tx.status[1], AR_Filtered)); 76 printf(" DelimUnderrun=%d, DataUnderun=%d, DescCfgErr=%d," 77 " TxTimerExceeded=%d\n", 78 MF(txs.u.tx.status[1], AR_TxDelimUnderrun), 79 MF(txs.u.tx.status[1], AR_TxDataUnderrun), 80 MF(txs.u.tx.status[1], AR_DescCfgErr), 81 MF(txs.u.tx.status[1], AR_TxTimerExpired)); 82 83 printf(" RTScnt=%d, FailCnt=%d, VRetryCnt=%d\n", 84 MS(txs.u.tx.status[1], AR_RTSFailCnt), 85 MS(txs.u.tx.status[1], AR_DataFailCnt), 86 MS(txs.u.tx.status[1], AR_VirtRetryCnt)); 87 88 /* ds_txstatus2 */ 89 printf(" TxTimestamp=0x%08x\n", txs.u.tx.status[2]); 90 91 /* ds_txstatus3 */ 92 /* ds_txstatus4 */ 93 printf(" BALow=0x%08x\n", txs.u.tx.status[3]); 94 printf(" BAHigh=0x%08x\n", txs.u.tx.status[4]); 95 96 /* ds_txstatus5 */ 97 printf(" RX RSSI 1 [%d %d %d] Comb=%d\n", 98 MS(txs.u.tx.status[5], AR_TxRSSIAnt10), 99 MS(txs.u.tx.status[5], AR_TxRSSIAnt11), 100 MS(txs.u.tx.status[5], AR_TxRSSIAnt12), 101 MS(txs.u.tx.status[5], AR_TxRSSICombined)); 102 103 /* ds_txstatus6 */ 104 /* ds_txstatus7 */ 105 /* ds_txstatus8 */ 106 printf(" TxEVM[0]=0x%08x, TxEVM[1]=0x%08x, TxEVM[2]=0x%08x\n", 107 txs.u.tx.status[6], 108 txs.u.tx.status[7], 109 txs.u.tx.status[8]); 110 111 /* ds_txstatus9 */ 112 printf(" TxDone=%d, SeqNum=0x%04x, TxOpExceeded=%d, FinalTsIdx=%d\n", 113 MF(txs.u.tx.status[9], AR_TxDone), 114 MS(txs.u.tx.status[9], AR_SeqNum), 115 MF(txs.u.tx.status[9], AR_TxOpExceeded), 116 MS(txs.u.tx.status[9], AR_FinalTxIdx)); 117 printf(" PowerMgmt=%d, TxTid=%d\n", 118 MF(txs.u.tx.status[9], AR_PowerMgmt), 119 MS(txs.u.tx.status[9], AR_TxTid)); 120 121 printf("\n ------\n"); 122 #endif 123 } 124 125 static void 126 ar5416_decode_txdesc(struct if_ath_alq_payload *a) 127 { 128 struct ar5416_desc txc; 129 130 /* XXX assumes txs is smaller than PAYLOAD_LEN! */ 131 memcpy(&txc, &a->payload, sizeof(struct ar5416_desc)); 132 133 printf("[%u] [%llu] TXD\n", 134 (unsigned int) be32toh(a->hdr.tstamp), 135 (unsigned long long) be64toh(a->hdr.threadid)); 136 137 #if 0 138 printf(" link=0x%08x, data=0x%08x\n", 139 txc.ds_link, 140 txc.ds_data); 141 142 /* ds_ctl0 */ 143 printf(" Frame Len=%d, VMF=%d\n", 144 txc.ds_ctl0 & AR_FrameLen, 145 MF(txc.ds_ctl0, AR_VirtMoreFrag)); 146 printf(" TX power0=%d, RtsEna=%d, Veol=%d, ClrDstMask=%d\n", 147 MS(txc.ds_ctl0, AR_XmitPower), 148 MF(txc.ds_ctl0, AR_RTSEnable), 149 MF(txc.ds_ctl0, AR_VEOL), 150 MF(txc.ds_ctl0, AR_ClrDestMask)); 151 printf(" TxIntrReq=%d, DestIdxValid=%d, CtsEnable=%d\n", 152 MF(txc.ds_ctl0, AR_TxIntrReq), 153 MF(txc.ds_ctl0, AR_DestIdxValid), 154 MF(txc.ds_ctl0, AR_CTSEnable)); 155 156 /* ds_ctl1 */ 157 printf(" BufLen=%d, TxMore=%d, DestIdx=%d," 158 " FrType=0x%x\n", 159 txc.ds_ctl1 & AR_BufLen, 160 MF(txc.ds_ctl1, AR_TxMore), 161 MS(txc.ds_ctl1, AR_DestIdx), 162 MS(txc.ds_ctl1, AR_FrameType)); 163 printf(" NoAck=%d, InsertTs=%d, CorruptFcs=%d, ExtOnly=%d," 164 " ExtAndCtl=%d\n", 165 MF(txc.ds_ctl1, AR_NoAck), 166 MF(txc.ds_ctl1, AR_InsertTS), 167 MF(txc.ds_ctl1, AR_CorruptFCS), 168 MF(txc.ds_ctl1, AR_ExtOnly), 169 MF(txc.ds_ctl1, AR_ExtAndCtl)); 170 printf(" MoreAggr=%d, IsAggr=%d, MoreRifs=%d\n", 171 MF(txc.ds_ctl1, AR_MoreAggr), 172 MF(txc.ds_ctl1, AR_IsAggr), 173 MF(txc.ds_ctl1, AR_MoreRifs)); 174 175 /* ds_ctl2 */ 176 printf(" DurUpEna=%d, Burstdur=0x%04x\n", 177 MF(txc.ds_ctl2, AR_DurUpdateEn), 178 MS(txc.ds_ctl2, AR_BurstDur)); 179 printf(" Try0=%d, Try1=%d, Try2=%d, Try3=%d\n", 180 MS(txc.ds_ctl2, AR_XmitDataTries0), 181 MS(txc.ds_ctl2, AR_XmitDataTries1), 182 MS(txc.ds_ctl2, AR_XmitDataTries2), 183 MS(txc.ds_ctl2, AR_XmitDataTries3)); 184 185 /* ds_ctl3 */ 186 printf(" rate0=0x%02x, rate1=0x%02x, rate2=0x%02x, rate3=0x%02x\n", 187 MS(txc.ds_ctl3, AR_XmitRate0), 188 MS(txc.ds_ctl3, AR_XmitRate1), 189 MS(txc.ds_ctl3, AR_XmitRate2), 190 MS(txc.ds_ctl3, AR_XmitRate3)); 191 192 /* ds_ctl4 */ 193 printf(" try 0: PktDur=%d, RTS/CTS ena=%d\n", 194 MS(txc.ds_ctl4, AR_PacketDur0), 195 MF(txc.ds_ctl4, AR_RTSCTSQual0)); 196 printf(" try 1: PktDur=%d, RTS/CTS ena=%d\n", 197 MS(txc.ds_ctl4, AR_PacketDur1), 198 MF(txc.ds_ctl4, AR_RTSCTSQual1)); 199 200 /* ds_ctl5 */ 201 printf(" try 2: PktDur=%d, RTS/CTS ena=%d\n", 202 MS(txc.ds_ctl5, AR_PacketDur2), 203 MF(txc.ds_ctl5, AR_RTSCTSQual2)); 204 printf(" try 3: PktDur=%d, RTS/CTS ena=%d\n", 205 MS(txc.ds_ctl5, AR_PacketDur3), 206 MF(txc.ds_ctl5, AR_RTSCTSQual3)); 207 208 /* ds_ctl6 */ 209 printf(" AggrLen=%d, PadDelim=%d, EncrType=%d\n", 210 MS(txc.ds_ctl6, AR_AggrLen), 211 MS(txc.ds_ctl6, AR_PadDelim), 212 MS(txc.ds_ctl6, AR_EncrType)); 213 214 /* ds_ctl7 */ 215 printf(" try 0: chainMask=0x%x, GI=%d, 2040=%d, STBC=%d\n", 216 MS(txc.ds_ctl7, AR_ChainSel0), 217 MF(txc.ds_ctl7, AR_GI0), 218 MF(txc.ds_ctl7, AR_2040_0), 219 MF(txc.ds_ctl7, AR_STBC0)); 220 printf(" try 1: chainMask=0x%x, GI=%d, 2040=%d, STBC=%d\n", 221 MS(txc.ds_ctl7, AR_ChainSel1), 222 MF(txc.ds_ctl7, AR_GI1), 223 MF(txc.ds_ctl7, AR_2040_1), 224 MF(txc.ds_ctl7, AR_STBC1)); 225 printf(" try 2: chainMask=0x%x, GI=%d, 2040=%d, STBC=%d\n", 226 MS(txc.ds_ctl7, AR_ChainSel2), 227 MF(txc.ds_ctl7, AR_GI2), 228 MF(txc.ds_ctl7, AR_2040_2), 229 MF(txc.ds_ctl7, AR_STBC2)); 230 printf(" try 3: chainMask=0x%x, GI=%d, 2040=%d, STBC=%d\n", 231 MS(txc.ds_ctl7, AR_ChainSel3), 232 MF(txc.ds_ctl7, AR_GI3), 233 MF(txc.ds_ctl7, AR_2040_3), 234 MF(txc.ds_ctl7, AR_STBC3)); 235 236 /* ds_ctl8 */ 237 printf(" try 0: ant=0x%08x\n", txc.ds_ctl8 & AR_AntCtl0); 238 239 /* ds_ctl9 */ 240 printf(" try 1: TxPower=%d, ant=0x%08x\n", 241 MS(txc.ds_ctl9, AR_XmitPower1), 242 txc.ds_ctl9 & AR_AntCtl1); 243 244 /* ds_ctl10 */ 245 printf(" try 2: TxPower=%d, ant=0x%08x\n", 246 MS(txc.ds_ctl10, AR_XmitPower2), 247 txc.ds_ctl10 & AR_AntCtl2); 248 249 /* ds_ctl11 */ 250 printf(" try 3: TxPower=%d, ant=0x%08x\n", 251 MS(txc.ds_ctl11, AR_XmitPower3), 252 txc.ds_ctl11 & AR_AntCtl3); 253 254 printf("\n ------ \n"); 255 #endif 256 } 257 258 static void 259 ar5416_decode_rxstatus(struct if_ath_alq_payload *a) 260 { 261 struct ar5416_desc rxs; 262 static uint64_t rx_tsf = 0; 263 264 /* XXX assumes rxs is smaller than PAYLOAD_LEN! */ 265 memcpy(&rxs, &a->payload, sizeof(struct ar5416_desc)); 266 267 if (MF(rxs.ds_rxstatus8, AR_RxDone) == 0) 268 return; 269 270 printf("[%u] [%llu] RXSTATUS: RxDone=%d, TS=0x%08x (delta %d)\n", 271 (unsigned int) be32toh(a->hdr.tstamp), 272 (unsigned long long) be64toh(a->hdr.threadid), 273 MF(rxs.ds_rxstatus8, AR_RxDone), 274 rxs.ds_rxstatus2, 275 rxs.ds_rxstatus2 - rx_tsf); 276 277 rx_tsf = rxs.ds_rxstatus2; 278 279 #if 0 280 printf(" link=0x%08x, data=0x%08x, ctl0=0x%08x, ctl2=0x%08x\n", 281 rxs.ds_link, 282 rxs.ds_data, 283 rxs.ds_ctl0, 284 rxs.ds_ctl1); 285 286 /* status0 */ 287 /* 288 * XXX TODO: For AR9285, the chain 1 and chain 2 RSSI values 289 * acutally contain the RX mixer configuration 290 */ 291 printf(" RSSICtl[0]=%d, RSSICtl[1]=%d, RSSICtl[2]=%d\n", 292 MS(rxs.ds_rxstatus0, AR_RxRSSIAnt00), 293 MS(rxs.ds_rxstatus0, AR_RxRSSIAnt01), 294 MS(rxs.ds_rxstatus0, AR_RxRSSIAnt02)); 295 296 /* status1 */ 297 printf(" DataLen=%d, RxMore=%d, NumDelim=%d\n", 298 rxs.ds_rxstatus1 & AR_DataLen, 299 MF(rxs.ds_rxstatus1, AR_RxMore), 300 MS(rxs.ds_rxstatus1, AR_NumDelim)); 301 302 /* status2 */ 303 printf(" RxTimestamp=0x%08x\n", rxs.ds_rxstatus2); 304 305 /* status3 - RxRate however is for Owl 2.0 */ 306 printf(" GI=%d, 2040=%d, RxRate=0x%02x, DupFrame=%d, RxAnt=0x%08x\n", 307 MF(rxs.ds_rxstatus3, AR_GI), 308 MF(rxs.ds_rxstatus3, AR_2040), 309 MS(rxs.ds_rxstatus0, AR_RxRate), 310 MF(rxs.ds_rxstatus3, AR_DupFrame), 311 MS(rxs.ds_rxstatus3, AR_RxAntenna)); 312 313 /* status4 */ 314 printf(" RSSIExt[0]=%d, RSSIExt[1]=%d, RSSIExt[2]=%d, RSSIComb=%d\n", 315 MS(rxs.ds_rxstatus4, AR_RxRSSIAnt10), 316 MS(rxs.ds_rxstatus4, AR_RxRSSIAnt11), 317 MS(rxs.ds_rxstatus4, AR_RxRSSIAnt12), 318 MS(rxs.ds_rxstatus4, AR_RxRSSICombined)); 319 320 /* status5 */ 321 /* status6 */ 322 /* status7 */ 323 printf(" RxEvm0=0x%08x, RxEvm1=0x%08x, RxEvm2=0x%08x\n", 324 rxs.ds_rxstatus5, 325 rxs.ds_rxstatus6, 326 rxs.ds_rxstatus7); 327 328 /* status8 */ 329 printf(" RxDone=%d, RxFrameOk=%d, CrcErr=%d, DecryptCrcErr=%d\n", 330 MF(rxs.ds_rxstatus8, AR_RxDone), 331 MF(rxs.ds_rxstatus8, AR_RxFrameOK), 332 MF(rxs.ds_rxstatus8, AR_CRCErr), 333 MF(rxs.ds_rxstatus8, AR_DecryptCRCErr)); 334 printf(" PhyErr=%d, MichaelErr=%d, PreDelimCRCErr=%d, KeyIdxValid=%d\n", 335 MF(rxs.ds_rxstatus8, AR_PHYErr), 336 MF(rxs.ds_rxstatus8, AR_MichaelErr), 337 MF(rxs.ds_rxstatus8, AR_PreDelimCRCErr), 338 MF(rxs.ds_rxstatus8, AR_RxKeyIdxValid)); 339 340 /* If PHY error, print that out. Otherwise, the key index */ 341 if (MF(rxs.ds_rxstatus8, AR_PHYErr)) 342 printf(" PhyErrCode=0x%02x\n", 343 MS(rxs.ds_rxstatus8, AR_PHYErrCode)); 344 else 345 printf(" KeyIdx=0x%02x\n", 346 MS(rxs.ds_rxstatus8, AR_KeyIdx)); 347 348 printf(" RxMoreAggr=%d, RxAggr=%d, PostDelimCRCErr=%d, HiRxChain=%d\n", 349 MF(rxs.ds_rxstatus8, AR_RxMoreAggr), 350 MF(rxs.ds_rxstatus8, AR_RxAggr), 351 MF(rxs.ds_rxstatus8, AR_PostDelimCRCErr), 352 MF(rxs.ds_rxstatus8, AR_HiRxChain)); 353 printf(" KeyMiss=%d\n", 354 MF(rxs.ds_rxstatus8, AR_KeyMiss)); 355 356 printf("\n ------\n"); 357 #endif 358 } 359 360 static void 361 ath_tdma_beacon_state(struct if_ath_alq_payload *a) 362 { 363 struct if_ath_alq_tdma_beacon_state t; 364 static uint64_t last_beacon_tx = 0; 365 366 memcpy(&t, &a->payload, sizeof(t)); 367 368 printf("[%u] [%llu] BEACON: RX TSF=%llu Beacon TSF=%llu (%d)\n", 369 (unsigned int) be32toh(a->hdr.tstamp), 370 (unsigned long long) be64toh(a->hdr.threadid), 371 (unsigned long long) be64toh(t.rx_tsf), 372 (unsigned long long) be64toh(t.beacon_tsf), 373 be64toh(t.beacon_tsf) - last_beacon_tx); 374 375 last_beacon_tx = be64toh(t.beacon_tsf); 376 } 377 378 static void 379 ath_tdma_timer_config(struct if_ath_alq_payload *a) 380 { 381 struct if_ath_alq_tdma_timer_config t; 382 383 memcpy(&t, &a->payload, sizeof(t)); 384 } 385 386 static void 387 ath_tdma_slot_calc(struct if_ath_alq_payload *a) 388 { 389 struct if_ath_alq_tdma_slot_calc t; 390 391 memcpy(&t, &a->payload, sizeof(t)); 392 printf("[%u] [%llu] SLOTCALC: NEXTTBTT=%llu nextslot=%llu tsfdelta=%d avg (%d/%d)\n", 393 (unsigned int) be32toh(a->hdr.tstamp), 394 (unsigned long long) be64toh(a->hdr.threadid), 395 (unsigned long long) be64toh(t.nexttbtt), 396 (unsigned long long) be64toh(t.next_slot), 397 (int) be32toh(t.tsfdelta), 398 (int) be32toh(t.avg_plus), 399 (int) be32toh(t.avg_minus)); 400 } 401 402 static void 403 ath_tdma_tsf_adjust(struct if_ath_alq_payload *a) 404 { 405 struct if_ath_alq_tdma_tsf_adjust t; 406 407 memcpy(&t, &a->payload, sizeof(t)); 408 printf("[%u] [%llu] TSFADJUST: TSF64 was %llu, adj=%d, now %llu\n", 409 (unsigned int) be32toh(a->hdr.tstamp), 410 (unsigned long long) be64toh(a->hdr.threadid), 411 (unsigned long long) be64toh(t.tsf64_old), 412 (int) be32toh(t.tsfdelta), 413 (unsigned long long) be64toh(t.tsf64_new)); 414 } 415 416 static void 417 ath_tdma_timer_set(struct if_ath_alq_payload *a) 418 { 419 struct if_ath_alq_tdma_timer_set t; 420 421 memcpy(&t, &a->payload, sizeof(t)); 422 printf("[%u] [%llu] TIMERSET: bt_intval=%d nexttbtt=%d nextdba=%d nextswba=%d nextatim=%d flags=0x%x tdmadbaprep=%d tdmaswbaprep=%d\n", 423 (unsigned int) be32toh(a->hdr.tstamp), 424 (unsigned long long) be64toh(a->hdr.threadid), 425 be32toh(t.bt_intval), 426 be32toh(t.bt_nexttbtt), 427 be32toh(t.bt_nextdba), 428 be32toh(t.bt_nextswba), 429 be32toh(t.bt_nextatim), 430 be32toh(t.bt_flags), 431 be32toh(t.sc_tdmadbaprep), 432 be32toh(t.sc_tdmaswbaprep)); 433 } 434 435 void 436 ar5416_alq_payload(struct if_ath_alq_payload *a) 437 { 438 439 switch (be16toh(a->hdr.op)) { 440 case ATH_ALQ_EDMA_TXSTATUS: /* TXSTATUS */ 441 ar5416_decode_txstatus(a); 442 break; 443 case ATH_ALQ_EDMA_RXSTATUS: /* RXSTATUS */ 444 ar5416_decode_rxstatus(a); 445 break; 446 case ATH_ALQ_EDMA_TXDESC: /* TXDESC */ 447 ar5416_decode_txdesc(a); 448 break; 449 case ATH_ALQ_TDMA_BEACON_STATE: 450 ath_tdma_beacon_state(a); 451 break; 452 case ATH_ALQ_TDMA_TIMER_CONFIG: 453 ath_tdma_timer_config(a); 454 break; 455 case ATH_ALQ_TDMA_SLOT_CALC: 456 ath_tdma_slot_calc(a); 457 break; 458 case ATH_ALQ_TDMA_TSF_ADJUST: 459 ath_tdma_tsf_adjust(a); 460 break; 461 case ATH_ALQ_TDMA_TIMER_SET: 462 ath_tdma_timer_set(a); 463 break; 464 default: 465 printf("[%d] [%lld] op: %d; len %d\n", 466 be32toh(a->hdr.tstamp), 467 be64toh(a->hdr.threadid), 468 be16toh(a->hdr.op), be16toh(a->hdr.len)); 469 } 470 } 471