#ifndef _DEV_IC_TULIPVAR_H_
#define _DEV_IC_TULIPVAR_H_
#include <sys/queue.h>
#include <sys/callout.h>
#include <sys/rndsource.h>
#define TULIP_NTXSEGS 16
#define TULIP_TXQUEUELEN 64
#define TULIP_NTXDESC (TULIP_TXQUEUELEN * TULIP_NTXSEGS)
#define TULIP_NTXDESC_MASK (TULIP_NTXDESC - 1)
#define TULIP_NEXTTX(x) ((x + 1) & TULIP_NTXDESC_MASK)
#define TULIP_NRXDESC 64
#define TULIP_NRXDESC_MASK (TULIP_NRXDESC - 1)
#define TULIP_NEXTRX(x) ((x + 1) & TULIP_NRXDESC_MASK)
struct tulip_control_data {
struct tulip_desc tcd_txdescs[TULIP_NTXDESC];
struct tulip_desc tcd_rxdescs[TULIP_NRXDESC];
uint32_t tcd_setup_packet[TULIP_SETUP_PACKET_LEN / sizeof(uint32_t)];
};
#define TULIP_CDOFF(x) offsetof(struct tulip_control_data, x)
#define TULIP_CDTXOFF(x) TULIP_CDOFF(tcd_txdescs[(x)])
#define TULIP_CDRXOFF(x) TULIP_CDOFF(tcd_rxdescs[(x)])
#define TULIP_CDSPOFF TULIP_CDOFF(tcd_setup_packet)
struct tulip_txsoft {
struct mbuf *txs_mbuf;
bus_dmamap_t txs_dmamap;
int txs_firstdesc;
int txs_lastdesc;
int txs_ndescs;
SIMPLEQ_ENTRY(tulip_txsoft) txs_q;
};
SIMPLEQ_HEAD(tulip_txsq, tulip_txsoft);
struct tulip_rxsoft {
struct mbuf *rxs_mbuf;
bus_dmamap_t rxs_dmamap;
};
typedef enum {
TULIP_CHIP_INVALID = 0,
TULIP_CHIP_DE425 = 1,
TULIP_CHIP_21040 = 2,
TULIP_CHIP_21041 = 3,
TULIP_CHIP_21140 = 4,
TULIP_CHIP_21140A = 5,
TULIP_CHIP_21142 = 6,
TULIP_CHIP_21143 = 7,
TULIP_CHIP_82C168 = 8,
TULIP_CHIP_82C169 = 9,
TULIP_CHIP_82C115 = 10,
TULIP_CHIP_MX98713 = 11,
TULIP_CHIP_MX98713A = 12,
TULIP_CHIP_MX98715 = 13,
TULIP_CHIP_MX98715A = 14,
TULIP_CHIP_MX98715AEC_X = 15,
TULIP_CHIP_MX98725 = 16,
TULIP_CHIP_WB89C840F = 17,
TULIP_CHIP_DM9102 = 18,
TULIP_CHIP_DM9102A = 19,
TULIP_CHIP_AL981 = 20,
TULIP_CHIP_AN983 = 21,
TULIP_CHIP_AN985 = 22,
TULIP_CHIP_AX88140 = 23,
TULIP_CHIP_AX88141 = 24,
TULIP_CHIP_X3201_3 = 25,
TULIP_CHIP_RS7112 = 26
} tulip_chip_t;
#define TULIP_CHIP_NAMES \
{ \
NULL, \
"DE-425", \
"DECchip 21040", \
"DECchip 21041", \
"DECchip 21140", \
"DECchip 21140A", \
"DECchip 21142", \
"DECchip 21143", \
"Lite-On 82C168", \
"Lite-On 82C169", \
"Lite-On 82C115", \
"Macronix MX98713", \
"Macronix MX98713A", \
"Macronix MX98715", \
"Macronix MX98715A", \
"Macronix MX98715AEC-x", \
"Macronix MX98725", \
"Winbond 89C840F", \
"Davicom DM9102", \
"Davicom DM9102A", \
"ADMtek AL981", \
"ADMtek AN983", \
"ADMtek AN985", \
"ASIX AX88140", \
"ASIX AX88141", \
"Xircom X3201-3", \
"Conexant RS7112", \
}
struct tulip_softc;
struct tulip_mediasw {
void (*tmsw_init)(struct tulip_softc *);
void (*tmsw_get)(struct tulip_softc *, struct ifmediareq *);
int (*tmsw_set)(struct tulip_softc *);
};
struct tulip_txthresh_tab {
uint32_t txth_opmode;
const char *txth_name;
};
#define TLP_TXTHRESH_TAB_10 { \
{ OPMODE_TR_72, "72 bytes" }, \
{ OPMODE_TR_96, "96 bytes" }, \
{ OPMODE_TR_128, "128 bytes" }, \
{ OPMODE_TR_160, "160 bytes" }, \
{ 0, NULL }, \
}
#define TLP_TXTHRESH_TAB_10_100 { \
{ OPMODE_TR_72, "72/128 bytes" }, \
{ OPMODE_TR_96, "96/256 bytes" }, \
{ OPMODE_TR_128, "128/512 bytes" }, \
{ OPMODE_TR_160, "160/1024 bytes" }, \
{ OPMODE_SF, "store and forward mode" }, \
{ 0, NULL }, \
}
#define TXTH_72 0
#define TXTH_96 1
#define TXTH_128 2
#define TXTH_160 3
#define TXTH_SF 4
#define TLP_TXTHRESH_TAB_DM9102 { \
{ OPMODE_TR_72, "72/128 bytes" }, \
{ OPMODE_TR_96, "96/256 bytes" }, \
{ OPMODE_TR_128, "128/512 bytes" }, \
{ OPMODE_SF, "store and forward mode" }, \
{ 0, NULL }, \
}
#define TXTH_DM9102_72 0
#define TXTH_DM9102_96 1
#define TXTH_DM9102_128 2
#define TXTH_DM9102_SF 3
#define TLP_TXTHRESH_TAB_WINB { \
{ 0, "store and forward mode" }, \
{ 0, NULL }, \
}
#define TXTH_WINB_SF 0
struct tulip_sia_media {
uint32_t tsm_siaconn;
uint32_t tsm_siatxrx;
uint32_t tsm_siagen;
};
struct tulip_21x4x_media {
int tm_type;
const char *tm_name;
void (*tm_get)(struct tulip_softc *, struct ifmediareq *);
int (*tm_set)(struct tulip_softc *);
int tm_phyno;
int tm_gp_length;
int tm_gp_offset;
int tm_reset_length;
int tm_reset_offset;
uint32_t tm_opmode;
uint32_t tm_gpctl;
uint32_t tm_gpdata;
uint32_t tm_actmask;
uint32_t tm_actdata;
struct tulip_sia_media tm_sia;
#define tm_siaconn tm_sia.tsm_siaconn
#define tm_siatxrx tm_sia.tsm_siatxrx
#define tm_siagen tm_sia.tsm_siagen
};
struct tulip_srom_to_ifmedia {
uint8_t tsti_srom;
int tsti_subtype;
int tsti_options;
const char *tsti_name;
uint32_t tsti_opmode;
uint32_t tsti_sia_cap;
struct tulip_sia_media tsti_21040;
struct tulip_sia_media tsti_21041;
struct tulip_sia_media tsti_21142;
};
struct tulip_stats {
u_long ts_tx_uf;
u_long ts_tx_to;
u_long ts_tx_ec;
u_long ts_tx_lc;
};
#ifndef _STANDALONE
struct tulip_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;
struct tulip_stats sc_stats;
uint8_t *sc_srom;
int sc_srom_addrbits;
const struct tulip_mediasw *sc_mediasw;
mii_bitbang_ops_t sc_bitbang_ops;
int sc_nway_ticks;
struct ifmedia_entry *sc_nway_active;
struct callout sc_nway_callout;
tulip_chip_t sc_chip;
int sc_rev;
int sc_flags;
char sc_name[32];
uint32_t sc_cacheline;
uint32_t sc_maxburst;
int sc_devno;
struct mii_data sc_mii;
const struct tulip_txthresh_tab *sc_txth;
int sc_txthresh;
uint8_t sc_gp_dir;
int sc_media_seen;
int sc_tlp_minst;
uint32_t sc_sia_cap;
void (*sc_reset)(struct tulip_softc *);
void (*sc_preinit)(struct tulip_softc *);
void (*sc_filter_setup)(struct tulip_softc *);
void (*sc_statchg)(struct ifnet *);
void (*sc_tick)(void *);
struct callout sc_tick_callout;
int (*sc_enable)(struct tulip_softc *);
void (*sc_disable)(struct tulip_softc *);
void (*sc_power)(struct tulip_softc *, int);
int sc_regshift;
uint32_t sc_busmode;
uint32_t sc_opmode;
uint32_t sc_inten;
uint32_t sc_rxint_mask;
uint32_t sc_txint_mask;
uint32_t sc_filtmode;
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 tulip_txsoft sc_txsoft[TULIP_TXQUEUELEN];
struct tulip_rxsoft sc_rxsoft[TULIP_NRXDESC];
struct tulip_control_data *sc_control_data;
#define sc_txdescs sc_control_data->tcd_txdescs
#define sc_rxdescs sc_control_data->tcd_rxdescs
#define sc_setup_desc sc_control_data->tcd_setup_desc
int sc_txfree;
int sc_txnext;
int sc_ntxsegs;
uint32_t sc_tdctl_ch;
uint32_t sc_tdctl_er;
uint32_t sc_setup_fsls;
struct tulip_txsq sc_txfreeq;
struct tulip_txsq sc_txdirtyq;
u_short sc_if_flags;
int sc_rxptr;
krndsource_t sc_rnd_source;
};
#endif
#define TULIPF_WANT_SETUP 0x00000001
#define TULIPF_DOING_SETUP 0x00000002
#define TULIPF_HAS_MII 0x00000004
#define TULIPF_IC_FS 0x00000008
#define TULIPF_MRL 0x00000010
#define TULIPF_MRM 0x00000020
#define TULIPF_MWI 0x00000040
#define TULIPF_AUTOPOLL 0x00000080
#define TULIPF_LINK_UP 0x00000100
#define TULIPF_LINK_VALID 0x00000200
#define TULIPF_DOINGAUTO 0x00000400
#define TULIPF_ATTACHED 0x00000800
#define TULIPF_ENABLED 0x00001000
#define TULIPF_BLE 0x00002000
#define TULIPF_DBO 0x00004000
#define TULIPF_VPC 0x00008000
#define TULIP_IS_ENABLED(sc) ((sc)->sc_flags & TULIPF_ENABLED)
#define TULIP_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 TULIP_CDTXADDR(sc, x) ((sc)->sc_cddma + TULIP_CDTXOFF((x)))
#define TULIP_CDRXADDR(sc, x) ((sc)->sc_cddma + TULIP_CDRXOFF((x)))
#define TULIP_CDSPADDR(sc) ((sc)->sc_cddma + TULIP_CDSPOFF)
#define TULIP_CDSP(sc) ((sc)->sc_control_data->tcd_setup_packet)
#define TULIP_CDTXSYNC(sc, x, n, ops) \
do { \
int __x, __n; \
\
__x = (x); \
__n = (n); \
\
\
if ((__x + __n) > TULIP_NTXDESC) { \
bus_dmamap_sync((sc)->sc_dmat, (sc)->sc_cddmamap, \
TULIP_CDTXOFF(__x), sizeof(struct tulip_desc) * \
(TULIP_NTXDESC - __x), (ops)); \
__n -= (TULIP_NTXDESC - __x); \
__x = 0; \
} \
\
\
bus_dmamap_sync((sc)->sc_dmat, (sc)->sc_cddmamap, \
TULIP_CDTXOFF(__x), sizeof(struct tulip_desc) * __n, (ops)); \
} while (0)
#define TULIP_CDRXSYNC(sc, x, ops) \
bus_dmamap_sync((sc)->sc_dmat, (sc)->sc_cddmamap, \
TULIP_CDRXOFF((x)), sizeof(struct tulip_desc), (ops))
#define TULIP_CDSPSYNC(sc, ops) \
bus_dmamap_sync((sc)->sc_dmat, (sc)->sc_cddmamap, \
TULIP_CDSPOFF, TULIP_SETUP_PACKET_LEN, (ops))
#define TULIP_INIT_RXDESC(sc, x) \
do { \
struct tulip_rxsoft *__rxs = &sc->sc_rxsoft[(x)]; \
struct tulip_desc *__rxd = &sc->sc_rxdescs[(x)]; \
struct mbuf *__m = __rxs->rxs_mbuf; \
\
__m->m_data = __m->m_ext.ext_buf; \
__rxd->td_bufaddr1 = \
htole32(__rxs->rxs_dmamap->dm_segs[0].ds_addr); \
__rxd->td_bufaddr2 = \
htole32(TULIP_CDRXADDR((sc), TULIP_NEXTRX((x)))); \
__rxd->td_ctl = \
htole32((((__m->m_ext.ext_size - 1) & ~0x3U) \
<< TDCTL_SIZE1_SHIFT) | (sc)->sc_tdctl_ch | \
((x) == (TULIP_NRXDESC - 1) ? sc->sc_tdctl_er : 0)); \
__rxd->td_status = htole32(TDSTAT_OWN|TDSTAT_Rx_FS|TDSTAT_Rx_LS); \
TULIP_CDRXSYNC((sc), (x), BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE); \
} while (0)
#define TULIP_CSR_OFFSET(sc, csr) \
(TULIP_CSR_INDEX(csr) << (sc)->sc_regshift)
#define TULIP_READ(sc, reg) \
bus_space_read_4((sc)->sc_st, (sc)->sc_sh, \
TULIP_CSR_OFFSET((sc), (reg)))
#define TULIP_WRITE(sc, reg, val) \
bus_space_write_4((sc)->sc_st, (sc)->sc_sh, \
TULIP_CSR_OFFSET((sc), (reg)), (val))
#define TULIP_SET(sc, reg, mask) \
TULIP_WRITE((sc), (reg), TULIP_READ((sc), (reg)) | (mask))
#define TULIP_CLR(sc, reg, mask) \
TULIP_WRITE((sc), (reg), TULIP_READ((sc), (reg)) & ~(mask))
#define TULIP_ISSET(sc, reg, mask) \
(TULIP_READ((sc), (reg)) & (mask))
#define TULIP_SP_FIELD_C(a, b) ((b) << 8 | (a))
#define TULIP_SP_FIELD(x, f) TULIP_SP_FIELD_C((x)[f * 2], (x)[f * 2 + 1])
#ifdef _KERNEL
extern const struct tulip_mediasw tlp_21040_mediasw;
extern const struct tulip_mediasw tlp_21040_tp_mediasw;
extern const struct tulip_mediasw tlp_21040_auibnc_mediasw;
extern const struct tulip_mediasw tlp_21041_mediasw;
extern const struct tulip_mediasw tlp_2114x_isv_mediasw;
extern const struct tulip_mediasw tlp_sio_mii_mediasw;
extern const struct tulip_mediasw tlp_pnic_mediasw;
extern const struct tulip_mediasw tlp_pmac_mediasw;
extern const struct tulip_mediasw tlp_al981_mediasw;
extern const struct tulip_mediasw tlp_an985_mediasw;
extern const struct tulip_mediasw tlp_dm9102_mediasw;
extern const struct tulip_mediasw tlp_asix_mediasw;
extern const struct tulip_mediasw tlp_rs7112_mediasw;
int tlp_attach(struct tulip_softc *, const uint8_t *);
int tlp_activate(device_t, enum devact);
int tlp_detach(struct tulip_softc *);
int tlp_intr(void *);
int tlp_read_srom(struct tulip_softc *);
int tlp_srom_crcok(const uint8_t *);
int tlp_isv_srom(const uint8_t *);
int tlp_isv_srom_enaddr(struct tulip_softc *, uint8_t *);
int tlp_parse_old_srom(struct tulip_softc *, uint8_t *);
void tlp_reset(struct tulip_softc *);
void tlp_idle(struct tulip_softc *, uint32_t);
int tlp_mediachange(struct ifnet *);
void tlp_mediastatus(struct ifnet *, struct ifmediareq *);
void tlp_21140_gpio_get(struct tulip_softc *sc, struct ifmediareq *ifmr);
int tlp_21140_gpio_set(struct tulip_softc *sc);
const char *tlp_chip_name(tulip_chip_t);
#endif
#endif