Add some hooks into the driver to attach, detach and record EDMA descriptor
events. This is primarily for the TX EDMA and TX EDMA completion. I haven't yet tied it into the EDMA RX path or the legacy TX/RX path. Things that I don't quite like: * Make the pointer type 'void' in ath_softc and have if_ath_alq*() return a malloc'ed buffer. That would remove the need to include if_ath_alq.h in if_athvar.h. * The sysctl setup needs to be cleaned up.
This commit is contained in:
parent
2a2441c9fa
commit
b69b0dcc24
@ -115,6 +115,10 @@ __FBSDID("$FreeBSD$");
|
|||||||
#include <dev/ath/ath_tx99/ath_tx99.h>
|
#include <dev/ath/ath_tx99/ath_tx99.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef ATH_DEBUG_ALQ
|
||||||
|
#include <dev/ath/if_ath_alq.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Calculate the receive filter according to the
|
* Calculate the receive filter according to the
|
||||||
* operating mode and state:
|
* operating mode and state:
|
||||||
|
@ -117,6 +117,10 @@ __FBSDID("$FreeBSD$");
|
|||||||
|
|
||||||
#include <dev/ath/if_ath_rx_edma.h>
|
#include <dev/ath/if_ath_rx_edma.h>
|
||||||
|
|
||||||
|
#ifdef ATH_DEBUG_ALQ
|
||||||
|
#include <dev/ath/if_ath_alq.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* some general macros
|
* some general macros
|
||||||
*/
|
*/
|
||||||
@ -357,7 +361,12 @@ ath_edma_recv_proc_queue(struct ath_softc *sc, HAL_RX_QUEUE qtype,
|
|||||||
#ifdef ATH_DEBUG
|
#ifdef ATH_DEBUG
|
||||||
if (sc->sc_debug & ATH_DEBUG_RECV_DESC)
|
if (sc->sc_debug & ATH_DEBUG_RECV_DESC)
|
||||||
ath_printrxbuf(sc, bf, 0, bf->bf_rxstatus == HAL_OK);
|
ath_printrxbuf(sc, bf, 0, bf->bf_rxstatus == HAL_OK);
|
||||||
#endif
|
#endif /* ATH_DEBUG */
|
||||||
|
#ifdef ATH_DEBUG_ALQ
|
||||||
|
if (if_ath_alq_checkdebug(&sc->sc_alq, ATH_ALQ_EDMA_RXSTATUS))
|
||||||
|
if_ath_alq_post(&sc->sc_alq, ATH_ALQ_EDMA_RXSTATUS,
|
||||||
|
sc->sc_rx_statuslen, (char *) ds);
|
||||||
|
#endif /* ATH_DEBUG */
|
||||||
if (bf->bf_rxstatus == HAL_EINPROGRESS)
|
if (bf->bf_rxstatus == HAL_EINPROGRESS)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -501,6 +501,57 @@ ath_sysctl_forcebstuck(SYSCTL_HANDLER_ARGS)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int
|
||||||
|
ath_sysctl_alq_log(SYSCTL_HANDLER_ARGS)
|
||||||
|
{
|
||||||
|
struct ath_softc *sc = arg1;
|
||||||
|
int error, enable;
|
||||||
|
|
||||||
|
enable = (sc->sc_alq.sc_alq_isactive);
|
||||||
|
|
||||||
|
error = sysctl_handle_int(oidp, &enable, 0, req);
|
||||||
|
if (error || !req->newptr)
|
||||||
|
return (error);
|
||||||
|
else if (enable)
|
||||||
|
error = if_ath_alq_start(&sc->sc_alq);
|
||||||
|
else
|
||||||
|
error = if_ath_alq_stop(&sc->sc_alq);
|
||||||
|
return (error);
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef ATH_DEBUG
|
||||||
|
/*
|
||||||
|
* Attach the ALQ debugging if required.
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
ath_sysctl_alq_attach(struct ath_softc *sc)
|
||||||
|
{
|
||||||
|
struct sysctl_oid *tree = device_get_sysctl_tree(sc->sc_dev);
|
||||||
|
struct sysctl_ctx_list *ctx = device_get_sysctl_ctx(sc->sc_dev);
|
||||||
|
struct sysctl_oid_list *child = SYSCTL_CHILDREN(tree);
|
||||||
|
|
||||||
|
tree = SYSCTL_ADD_NODE(ctx, child, OID_AUTO, "alq", CTLFLAG_RD,
|
||||||
|
NULL, "Atheros ALQ logging parameters");
|
||||||
|
child = SYSCTL_CHILDREN(tree);
|
||||||
|
|
||||||
|
SYSCTL_ADD_STRING(ctx, child, OID_AUTO, "filename",
|
||||||
|
CTLFLAG_RW, sc->sc_alq.sc_alq_filename, 0, "ALQ filename");
|
||||||
|
|
||||||
|
SYSCTL_ADD_PROC(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
|
||||||
|
"enable", CTLTYPE_INT | CTLFLAG_RW, sc, 0,
|
||||||
|
ath_sysctl_alq_log, "I", "");
|
||||||
|
|
||||||
|
SYSCTL_ADD_UINT(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
|
||||||
|
"debugmask", CTLFLAG_RW, &sc->sc_alq.sc_alq_debug, 0,
|
||||||
|
"ALQ debug mask");
|
||||||
|
|
||||||
|
SYSCTL_ADD_UINT(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
|
||||||
|
"numlost", CTLFLAG_RW, &sc->sc_alq.sc_alq_numlost, 0,
|
||||||
|
"number lost");
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
void
|
void
|
||||||
ath_sysctlattach(struct ath_softc *sc)
|
ath_sysctlattach(struct ath_softc *sc)
|
||||||
{
|
{
|
||||||
@ -655,6 +706,10 @@ ath_sysctlattach(struct ath_softc *sc)
|
|||||||
ath_sysctl_setcca, "I", "enable CCA control");
|
ath_sysctl_setcca, "I", "enable CCA control");
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef ATH_DEBUG
|
||||||
|
ath_sysctl_alq_attach(sc);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
|
@ -101,6 +101,10 @@ __FBSDID("$FreeBSD$");
|
|||||||
#include <dev/ath/if_ath_tx.h>
|
#include <dev/ath/if_ath_tx.h>
|
||||||
#include <dev/ath/if_ath_tx_ht.h>
|
#include <dev/ath/if_ath_tx_ht.h>
|
||||||
|
|
||||||
|
#ifdef ATH_DEBUG_ALQ
|
||||||
|
#include <dev/ath/if_ath_alq.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* How many retries to perform in software
|
* How many retries to perform in software
|
||||||
*/
|
*/
|
||||||
|
@ -117,6 +117,10 @@ __FBSDID("$FreeBSD$");
|
|||||||
|
|
||||||
#include <dev/ath/if_ath_tx_edma.h>
|
#include <dev/ath/if_ath_tx_edma.h>
|
||||||
|
|
||||||
|
#ifdef ATH_DEBUG_ALQ
|
||||||
|
#include <dev/ath/if_ath_alq.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* some general macros
|
* some general macros
|
||||||
*/
|
*/
|
||||||
@ -132,6 +136,37 @@ MALLOC_DECLARE(M_ATHDEV);
|
|||||||
|
|
||||||
static void ath_edma_tx_processq(struct ath_softc *sc, int dosched);
|
static void ath_edma_tx_processq(struct ath_softc *sc, int dosched);
|
||||||
|
|
||||||
|
#ifdef ATH_DEBUG_ALQ
|
||||||
|
static void
|
||||||
|
ath_edma_tx_alq_post(struct ath_softc *sc, struct ath_buf *bf_first)
|
||||||
|
{
|
||||||
|
struct ath_buf *bf;
|
||||||
|
int i, n;
|
||||||
|
const char *ds;
|
||||||
|
|
||||||
|
/* XXX we should skip out early if debugging isn't enabled! */
|
||||||
|
bf = bf_first;
|
||||||
|
|
||||||
|
while (bf != NULL) {
|
||||||
|
/* XXX assume nmaps = 4! */
|
||||||
|
/* XXX should ensure bf_nseg > 0! */
|
||||||
|
if (bf->bf_nseg == 0)
|
||||||
|
break;
|
||||||
|
n = ((bf->bf_nseg - 1) / 4) + 1;
|
||||||
|
for (i = 0, ds = (const char *) bf->bf_desc;
|
||||||
|
i < n;
|
||||||
|
i++, ds += sc->sc_tx_desclen) {
|
||||||
|
if_ath_alq_post(&sc->sc_alq,
|
||||||
|
ATH_ALQ_EDMA_TXDESC,
|
||||||
|
96,
|
||||||
|
ds);
|
||||||
|
}
|
||||||
|
|
||||||
|
bf = bf->bf_next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif /* ATH_DEBUG_ALQ */
|
||||||
|
|
||||||
static void
|
static void
|
||||||
ath_edma_tx_fifo_fill(struct ath_softc *sc, struct ath_txq *txq)
|
ath_edma_tx_fifo_fill(struct ath_softc *sc, struct ath_txq *txq)
|
||||||
{
|
{
|
||||||
@ -149,7 +184,11 @@ ath_edma_tx_fifo_fill(struct ath_softc *sc, struct ath_txq *txq)
|
|||||||
#ifdef ATH_DEBUG
|
#ifdef ATH_DEBUG
|
||||||
if (sc->sc_debug & ATH_DEBUG_XMIT_DESC)
|
if (sc->sc_debug & ATH_DEBUG_XMIT_DESC)
|
||||||
ath_printtxbuf(sc, bf, txq->axq_qnum, i, 0);
|
ath_printtxbuf(sc, bf, txq->axq_qnum, i, 0);
|
||||||
#endif
|
#endif/* ATH_DEBUG */
|
||||||
|
#ifdef ATH_DEBUG_ALQ
|
||||||
|
if (if_ath_alq_checkdebug(&sc->sc_alq, ATH_ALQ_EDMA_TXDESC))
|
||||||
|
ath_edma_tx_alq_post(sc, bf);
|
||||||
|
#endif /* ATH_DEBUG_ALQ */
|
||||||
txq->axq_fifo_depth++;
|
txq->axq_fifo_depth++;
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
@ -163,10 +202,6 @@ ath_edma_tx_fifo_fill(struct ath_softc *sc, struct ath_txq *txq)
|
|||||||
*
|
*
|
||||||
* This should only be called as part of the chip reset path, as it
|
* This should only be called as part of the chip reset path, as it
|
||||||
* assumes the FIFO is currently empty.
|
* assumes the FIFO is currently empty.
|
||||||
*
|
|
||||||
* TODO: verify that a cold/warm reset does clear the TX FIFO, so
|
|
||||||
* writing in a partially-filled FIFO will not cause double-entries
|
|
||||||
* to appear.
|
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
ath_edma_dma_restart(struct ath_softc *sc, struct ath_txq *txq)
|
ath_edma_dma_restart(struct ath_softc *sc, struct ath_txq *txq)
|
||||||
@ -222,7 +257,11 @@ ath_edma_xmit_handoff_hw(struct ath_softc *sc, struct ath_txq *txq,
|
|||||||
#ifdef ATH_DEBUG
|
#ifdef ATH_DEBUG
|
||||||
if (sc->sc_debug & ATH_DEBUG_XMIT_DESC)
|
if (sc->sc_debug & ATH_DEBUG_XMIT_DESC)
|
||||||
ath_printtxbuf(sc, bf, txq->axq_qnum, 0, 0);
|
ath_printtxbuf(sc, bf, txq->axq_qnum, 0, 0);
|
||||||
#endif /* ATH_DEBUG */
|
#endif /* ATH_DEBUG */
|
||||||
|
#ifdef ATH_DEBUG_ALQ
|
||||||
|
if (if_ath_alq_checkdebug(&sc->sc_alq, ATH_ALQ_EDMA_TXDESC))
|
||||||
|
ath_edma_tx_alq_post(sc, bf);
|
||||||
|
#endif /* ATH_DEBUG_ALQ */
|
||||||
ath_hal_puttxbuf(ah, txq->axq_qnum, bf->bf_daddr);
|
ath_hal_puttxbuf(ah, txq->axq_qnum, bf->bf_daddr);
|
||||||
txq->axq_fifo_depth++;
|
txq->axq_fifo_depth++;
|
||||||
ath_hal_txstart(ah, txq->axq_qnum);
|
ath_hal_txstart(ah, txq->axq_qnum);
|
||||||
@ -368,7 +407,6 @@ ath_edma_dma_txsetup(struct ath_softc *sc)
|
|||||||
ath_edma_setup_txfifo(sc, i);
|
ath_edma_setup_txfifo(sc, i);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -489,6 +527,13 @@ ath_edma_tx_processq(struct ath_softc *sc, int dosched)
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef ATH_DEBUG_ALQ
|
||||||
|
if (if_ath_alq_checkdebug(&sc->sc_alq, ATH_ALQ_EDMA_TXSTATUS))
|
||||||
|
if_ath_alq_post(&sc->sc_alq, ATH_ALQ_EDMA_TXSTATUS,
|
||||||
|
sc->sc_tx_statuslen,
|
||||||
|
(char *) txstatus);
|
||||||
|
#endif /* ATH_DEBUG_ALQ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* At this point we have a valid status descriptor.
|
* At this point we have a valid status descriptor.
|
||||||
* The QID and descriptor ID (which currently isn't set)
|
* The QID and descriptor ID (which currently isn't set)
|
||||||
|
@ -42,6 +42,9 @@
|
|||||||
#include <net80211/ieee80211_radiotap.h>
|
#include <net80211/ieee80211_radiotap.h>
|
||||||
#include <dev/ath/if_athioctl.h>
|
#include <dev/ath/if_athioctl.h>
|
||||||
#include <dev/ath/if_athrate.h>
|
#include <dev/ath/if_athrate.h>
|
||||||
|
#ifdef ATH_DEBUG_ALQ
|
||||||
|
#include <dev/ath/if_ath_alq.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#define ATH_TIMEOUT 1000
|
#define ATH_TIMEOUT 1000
|
||||||
|
|
||||||
@ -770,6 +773,11 @@ struct ath_softc {
|
|||||||
int sc_dodfs; /* Whether to enable DFS rx filter bits */
|
int sc_dodfs; /* Whether to enable DFS rx filter bits */
|
||||||
struct task sc_dfstask; /* DFS processing task */
|
struct task sc_dfstask; /* DFS processing task */
|
||||||
|
|
||||||
|
/* ALQ */
|
||||||
|
#ifdef ATH_DEBUG
|
||||||
|
struct if_ath_alq sc_alq;
|
||||||
|
#endif
|
||||||
|
|
||||||
/* TX AMPDU handling */
|
/* TX AMPDU handling */
|
||||||
int (*sc_addba_request)(struct ieee80211_node *,
|
int (*sc_addba_request)(struct ieee80211_node *,
|
||||||
struct ieee80211_tx_ampdu *, int, int, int);
|
struct ieee80211_tx_ampdu *, int, int, int);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user