#ifndef _MIPS_ATHEROS_DEV_AEVAR_H_
#define _MIPS_ATHEROS_DEV_AEVAR_H_
#include <sys/queue.h>
#include <sys/callout.h>
#include <sys/rndsource.h>
#define AE_NTXSEGS 16
#define AE_TXQUEUELEN 64
#define AE_NTXDESC (AE_TXQUEUELEN * AE_NTXSEGS)
#define AE_NTXDESC_MASK (AE_NTXDESC - 1)
#define AE_NEXTTX(x) ((x + 1) & AE_NTXDESC_MASK)
#define AE_NRXDESC 64
#define AE_NRXDESC_MASK (AE_NRXDESC - 1)
#define AE_NEXTRX(x) ((x + 1) & AE_NRXDESC_MASK)
struct ae_control_data {
struct ae_desc acd_txdescs[AE_NTXDESC];
struct ae_desc acd_rxdescs[AE_NRXDESC];
};
#define AE_CDOFF(x) offsetof(struct ae_control_data, x)
#define AE_CDTXOFF(x) AE_CDOFF(acd_txdescs[(x)])
#define AE_CDRXOFF(x) AE_CDOFF(acd_rxdescs[(x)])
struct ae_txsoft {
struct mbuf *txs_mbuf;
bus_dmamap_t txs_dmamap;
int txs_firstdesc;
int txs_lastdesc;
int txs_ndescs;
SIMPLEQ_ENTRY(ae_txsoft) txs_q;
};
SIMPLEQ_HEAD(ae_txsq, ae_txsoft);
struct ae_rxsoft {
struct mbuf *rxs_mbuf;
bus_dmamap_t rxs_dmamap;
};
struct ae_softc;
struct ae_stats {
u_long ts_tx_uf;
u_long ts_tx_to;
u_long ts_tx_ec;
u_long ts_tx_lc;
};
#ifndef _STANDALONE
struct ae_softc {
device_t sc_dev;
bus_space_tag_t sc_st;
bus_space_handle_t sc_sh;
bus_size_t sc_size;
bus_dma_tag_t sc_dmat;
void *sc_ih;
int sc_cirq;
int sc_mirq;
struct ethercom sc_ethercom;
void *sc_sdhook;
void *sc_powerhook;
struct ae_stats sc_stats;
int sc_flags;
struct mii_data sc_mii;
int sc_txthresh;
void (*sc_tick)(void *);
struct callout sc_tick_callout;
u_int32_t sc_inten;
u_int32_t sc_rxint_mask;
u_int32_t sc_txint_mask;
bus_dma_segment_t sc_cdseg;
int sc_cdnseg;
bus_dmamap_t sc_cddmamap;
#define sc_cddma sc_cddmamap->dm_segs[0].ds_addr
struct ae_txsoft sc_txsoft[AE_TXQUEUELEN];
struct ae_rxsoft sc_rxsoft[AE_NRXDESC];
struct ae_control_data *sc_control_data;
#define sc_txdescs sc_control_data->acd_txdescs
#define sc_rxdescs sc_control_data->acd_rxdescs
#define sc_setup_desc sc_control_data->acd_setup_desc
int sc_txfree;
int sc_txnext;
struct ae_txsq sc_txfreeq;
struct ae_txsq sc_txdirtyq;
u_short sc_if_flags;
int sc_rxptr;
krndsource_t sc_rnd_source;
};
#endif
#define AE_ATTACHED 0x00000800
#define AE_ENABLED 0x00001000
#define AE_IS_ENABLED(sc) ((sc)->sc_flags & AE_ENABLED)
#define AE_CURRENT_MEDIA(sc) ((sc)->sc_mii.mii_media.ifm_cur)
#define TULIP_MEDIA_NEEDSRESET(sc, newbits) \
(((sc)->sc_opmode & OPMODE_MEDIA_BITS) != \
((newbits) & OPMODE_MEDIA_BITS))
#define AE_CDTXADDR(sc, x) ((sc)->sc_cddma + AE_CDTXOFF((x)))
#define AE_CDRXADDR(sc, x) ((sc)->sc_cddma + AE_CDRXOFF((x)))
#define AE_CDTXSYNC(sc, x, n, ops) \
do { \
int __x, __n; \
\
__x = (x); \
__n = (n); \
\
\
if ((__x + __n) > AE_NTXDESC) { \
bus_dmamap_sync((sc)->sc_dmat, (sc)->sc_cddmamap, \
AE_CDTXOFF(__x), sizeof(struct ae_desc) * \
(AE_NTXDESC - __x), (ops)); \
__n -= (AE_NTXDESC - __x); \
__x = 0; \
} \
\
\
bus_dmamap_sync((sc)->sc_dmat, (sc)->sc_cddmamap, \
AE_CDTXOFF(__x), sizeof(struct ae_desc) * __n, (ops)); \
} while (0)
#define AE_CDRXSYNC(sc, x, ops) \
bus_dmamap_sync((sc)->sc_dmat, (sc)->sc_cddmamap, \
AE_CDRXOFF((x)), sizeof(struct ae_desc), (ops))
#define AE_INIT_RXDESC(sc, x) \
do { \
struct ae_rxsoft *__rxs = &sc->sc_rxsoft[(x)]; \
struct ae_desc *__rxd = &sc->sc_rxdescs[(x)]; \
struct mbuf *__m = __rxs->rxs_mbuf; \
\
__m->m_data = __m->m_ext.ext_buf; \
__rxd->ad_bufaddr1 = \
(__rxs->rxs_dmamap->dm_segs[0].ds_addr); \
__rxd->ad_bufaddr2 = \
AE_CDRXADDR((sc), AE_NEXTRX((x))); \
__rxd->ad_ctl = \
((((__m->m_ext.ext_size - 1) & ~0x3U) \
<< ADCTL_SIZE1_SHIFT) | \
((x) == (AE_NRXDESC - 1) ? ADCTL_ER : 0)); \
__rxd->ad_status = ADSTAT_OWN|ADSTAT_Rx_FS|ADSTAT_Rx_LS; \
AE_CDRXSYNC((sc), (x), BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE); \
} while (0)
#define AE_READ(sc, reg) \
bus_space_read_4((sc)->sc_st, (sc)->sc_sh, (reg))
#define AE_WRITE(sc, reg, val) \
bus_space_write_4((sc)->sc_st, (sc)->sc_sh, (reg), (val))
#define AE_SET(sc, reg, mask) \
AE_WRITE((sc), (reg), AE_READ((sc), (reg)) | (mask))
#define AE_CLR(sc, reg, mask) \
AE_WRITE((sc), (reg), AE_READ((sc), (reg)) & ~(mask))
#define AE_ISSET(sc, reg, mask) \
(AE_READ((sc), (reg)) & (mask))
#define AE_BARRIER(sc) \
bus_space_barrier((sc)->sc_st, (sc)->sc_sh, 0, (sc)->sc_size, \
BUS_SPACE_BARRIER_WRITE)
#endif