#ifndef _DEV_IC_SMC83C170VAR_H_
#define _DEV_IC_SMC83C170VAR_H_
#include <sys/callout.h>
#define EPIC_NTXDESC 128
#define EPIC_NTXDESC_MASK (EPIC_NTXDESC - 1)
#define EPIC_NEXTTX(x) ((x + 1) & EPIC_NTXDESC_MASK)
#define EPIC_NRXDESC 64
#define EPIC_NRXDESC_MASK (EPIC_NRXDESC - 1)
#define EPIC_NEXTRX(x) ((x + 1) & EPIC_NRXDESC_MASK)
struct epic_control_data {
struct epic_txdesc ecd_txdescs[EPIC_NTXDESC];
struct epic_rxdesc ecd_rxdescs[EPIC_NRXDESC];
struct epic_fraglist ecd_txfrags[EPIC_NTXDESC];
};
#define EPIC_CDOFF(x) offsetof(struct epic_control_data, x)
#define EPIC_CDTXOFF(x) EPIC_CDOFF(ecd_txdescs[(x)])
#define EPIC_CDRXOFF(x) EPIC_CDOFF(ecd_rxdescs[(x)])
#define EPIC_CDFLOFF(x) EPIC_CDOFF(ecd_txfrags[(x)])
struct epic_descsoft {
struct mbuf *ds_mbuf;
bus_dmamap_t ds_dmamap;
};
struct epic_softc {
device_t sc_dev;
bus_space_tag_t sc_st;
bus_space_handle_t sc_sh;
bus_dma_tag_t sc_dmat;
struct ethercom sc_ethercom;
int sc_hwflags;
#define EPIC_HAS_BNC 0x01
#define EPIC_HAS_MII_FIBER 0x02
#define EPIC_DUPLEXLED_ON_694 0x04
struct mii_data sc_mii;
struct callout sc_mii_callout;
bus_dmamap_t sc_cddmamap;
#define sc_cddma sc_cddmamap->dm_segs[0].ds_addr
bus_dmamap_t sc_nulldmamap;
#define sc_nulldma sc_nulldmamap->dm_segs[0].ds_addr
struct epic_descsoft sc_txsoft[EPIC_NTXDESC];
struct epic_descsoft sc_rxsoft[EPIC_NRXDESC];
struct epic_control_data *sc_control_data;
int sc_txpending;
int sc_txdirty;
int sc_txlast;
int sc_rxptr;
u_int sc_serinst;
};
#define EPIC_CDTXADDR(sc, x) ((sc)->sc_cddma + EPIC_CDTXOFF((x)))
#define EPIC_CDRXADDR(sc, x) ((sc)->sc_cddma + EPIC_CDRXOFF((x)))
#define EPIC_CDFLADDR(sc, x) ((sc)->sc_cddma + EPIC_CDFLOFF((x)))
#define EPIC_CDTX(sc, x) (&(sc)->sc_control_data->ecd_txdescs[(x)])
#define EPIC_CDRX(sc, x) (&(sc)->sc_control_data->ecd_rxdescs[(x)])
#define EPIC_CDFL(sc, x) (&(sc)->sc_control_data->ecd_txfrags[(x)])
#define EPIC_DSTX(sc, x) (&(sc)->sc_txsoft[(x)])
#define EPIC_DSRX(sc, x) (&(sc)->sc_rxsoft[(x)])
#define EPIC_CDTXSYNC(sc, x, ops) \
bus_dmamap_sync((sc)->sc_dmat, (sc)->sc_cddmamap, \
EPIC_CDTXOFF((x)), sizeof(struct epic_txdesc), (ops))
#define EPIC_CDRXSYNC(sc, x, ops) \
bus_dmamap_sync((sc)->sc_dmat, (sc)->sc_cddmamap, \
EPIC_CDRXOFF((x)), sizeof(struct epic_rxdesc), (ops))
#define EPIC_CDFLSYNC(sc, x, ops) \
bus_dmamap_sync((sc)->sc_dmat, (sc)->sc_cddmamap, \
EPIC_CDFLOFF((x)), sizeof(struct epic_fraglist), (ops))
#define EPIC_INIT_RXDESC(sc, x) \
do { \
struct epic_descsoft *__ds = EPIC_DSRX((sc), (x)); \
struct epic_rxdesc *__rxd = EPIC_CDRX((sc), (x)); \
struct mbuf *__m = __ds->ds_mbuf; \
\
\
__m->m_data = __m->m_ext.ext_buf + 2; \
__rxd->er_bufaddr = __ds->ds_dmamap->dm_segs[0].ds_addr + 2; \
__rxd->er_control = RXCTL_BUFLENGTH(__m->m_ext.ext_size - 2); \
__rxd->er_nextdesc = EPIC_CDRXADDR((sc), EPIC_NEXTRX((x))); \
__rxd->er_rxstatus = ER_RXSTAT_OWNER; \
EPIC_CDRXSYNC((sc), (x), BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE); \
} while ( 0)
#ifdef _KERNEL
void epic_attach(struct epic_softc *);
int epic_intr(void *);
#endif
#endif