/*
 * Copyright (c) 1990-1992, by Sun Microsystems, Inc.
 */

/*
 * @(#)if-solaris8.h for ifstatus v1.3 06 JAN 2001 Rob Thomas robt@cymru.com
 * Updated 06 JAN 2001 by Rob Thomas robt@cymru.com
 * Now supports the Solaris 8 hme drivers.
 */

#include <sys/t_lock.h>
#include <sys/ddipropdefs.h>
#include <sys/mutex.h>
#include <sys/kstat.h>
#include <sys/dditypes.h>

#define NET_TRUNK_MAXSIZE       16

typedef struct hme_stats {
        uint32_t hme_ipackets;
        uint32_t hme_ierrors;
        uint32_t hme_opackets;
        uint32_t hme_oerrors;
        uint32_t hme_coll;
        uint32_t hme_defer;
        uint32_t hme_fram;
        uint32_t hme_crc;
        uint32_t hme_sqerr;
        uint32_t hme_cvc;
        uint32_t hme_lenerr;
        uint32_t hme_ifspeed;
        uint32_t hme_buff;
        uint32_t hme_oflo;
        uint32_t hme_uflo;
        uint32_t hme_missed;
        uint32_t hme_tlcol;
        uint32_t hme_trtry;
        uint32_t hme_fstcol;
        uint32_t hme_tnocar;
        uint32_t hme_inits;
        uint32_t hme_nocanput;
        uint32_t hme_allocbfail;
        uint32_t hme_runt;
        uint32_t hme_jab;
        uint32_t hme_babl;
        uint32_t hme_tmder;
        uint32_t hme_txlaterr;
        uint32_t hme_rxlaterr;
        uint32_t hme_slvparerr;
        uint32_t hme_txparerr;
        uint32_t hme_rxparerr;
        uint32_t hme_slverrack;
        uint32_t hme_txerrack;
        uint32_t hme_rxerrack;
        uint32_t hme_txtagerr;
        uint32_t hme_rxtagerr;
        uint32_t hme_eoperr;
        uint32_t hme_notmds;
        uint32_t hme_notbufs;
        uint32_t hme_norbufs;
        uint32_t hme_clsn;

        /*
         * MIB II variables
         */
        uint32_t hme_rcvbytes;          /* # bytes received */
        uint32_t hme_xmtbytes;          /* # bytes transmitted */
        uint32_t hme_multircv;          /* # multicast packets received */
        uint32_t hme_multixmt;          /* # multicast packets for xmit */
        uint32_t hme_brdcstrcv;         /* # broadcast packets received */
        uint32_t hme_brdcstxmt;         /* # broadcast packets for xmit */
        uint32_t hme_norcvbuf;          /* # rcv packets discarded */
        uint32_t hme_noxmtbuf;          /* # xmit packets discarded */

        uint32_t hme_phy_inits;
        uint32_t hme_tx_inits;
        uint32_t hme_rx_inits;

        /*
         * PSARC 1997/198 : 64bit kstats
         */
        uint64_t hme_ipackets64;
        uint64_t hme_opackets64;
        uint64_t hme_rbytes64;
        uint64_t hme_obytes64;

        /*
         * PSARC 1997/247 : RFC 1643
         */
        uint32_t hme_align_errors;
        uint32_t hme_fcs_errors;
        uint32_t hme_multi_collisions;
        uint32_t hme_sqe_errors;
        uint32_t hme_defer_xmts;
        uint32_t hme_ex_collisions;
        uint32_t hme_macxmt_errors;
        uint32_t hme_carrier_errors;
        uint32_t hme_toolong_errors;
        uint32_t hme_macrcv_errors;
        /*
         * cksum flags
         */
        uint32_t hme_tcpcksum_errors;
        uint32_t hme_hwcksum_errors;

} hme_stats_t;

typedef struct hmetrunk_s {
        struct hme              *tr_members[NET_TRUNK_MAXSIZE];
        struct hme              *trunk_head;
        kmutex_t                tr_lock;        /* protect this structure */
        uint_t                  tr_trunksize;   /* Save the trunk size here */
        uint_t                  tr_mask;        /* value to & index with */
        uint_t                  tr_policy;      /* policy */
        uint_t                  tr_robin;       /* last index in round robin */
        struct hme_stats        tr_stats;       /* aggregate statistics */
        struct hmetrunk_s       *nextp;         /* Next trunk */
        int                     tr_alternate[NET_TRUNK_MAXSIZE];
        uint_t                  tr_nextalternate;
} hmetrunk_t;

/*
 * dev_info: 	The main device information structure this is intended to be
 *		opaque to drivers and drivers should use ddi functions to
 *		access *all* driver accessible fields.
 *
 * devi_parent_data includes property lists (interrupts, registers, etc.)
 * devi_driver_data includes whatever the driver wants to place there.
 */

struct dev_info  {

	struct dev_info *devi_parent;	/* my parent node in tree	*/
	struct dev_info *devi_child;	/* my child list head		*/
	struct dev_info *devi_sibling;	/* next element on my level	*/

	char	*devi_name;		/* device name			*/
	char	*devi_addr;		/* address part of name		*/
	int	devi_nodeid;		/* device nodeid		*/
	int	devi_instance;		/* device instance number	*/

	struct dev_ops *devi_ops;	/* driver operations		*/

	caddr_t	devi_parent_data;	/* parent private data		*/
	caddr_t	devi_driver_data;	/* driver private data		*/

	ddi_prop_t *devi_drv_prop_ptr;	/* head of driver prop list */
	ddi_prop_t *devi_sys_prop_ptr;	/* head of system prop list */

	struct ddi_minor_data *devi_minor;	/* head of minor list */
	struct dev_info *devi_next;	/* Next instance of this device */
	kmutex_t devi_lock;		/* Protects per-devinfo data */

	/* logical parents for busop primitives	 */

	struct dev_info *devi_bus_map_fault;	/* bus_map_fault parent */
	struct dev_info *devi_bus_dma_map;	/* bus_dma_map parent */
	struct dev_info *devi_bus_dma_ctl;	/* bus_dma_ctl parent */
	struct dev_info	*devi_bus_ctl;		/* bus_ctl parent */

	void	*devi_pm_info;		/* private power management stuff */

	/* some device driver statistical info may go here */
};

/*
 * ie.h header for STREAMS Intel 82586 Ethernet Driver.
 *
 * Per-Device instance state information.
 *
 * Each instance is dynamically allocated on first attach.
 */
struct	ie {
	struct	ie		*ie_nextp;	/* next in a linked list */
	dev_info_t		*ie_dip;	/* associated dev_info */
	struct	ether_addr	ie_ouraddr;	/* individual address */
	u_int			ie_flags;	/* misc. flags */
	u_int			ie_wantw;	/* xmit: out of resources */
	u_int			ie_jamtime;	/* last jammed time in secs */
	int			ie_dogid;	/* id returned from timeout() */
	struct iecb		*ie_cbsyncp;	/* synchronous command block */

	caddr_t		ie_cb_base;	/* control block base address */
	u_int		ie_cb_size;	/* control block size in bytes */

	kmutex_t	ie_buflock;	/* protect per-device buffer pool */
	kmutex_t	ie_devlock;	/* protect other per-device data */

	volatile	struct iescp	*ie_scp;	/* SCP pointer */
	volatile	struct ieiscp	*ie_iscp;	/* ISCP pointer */
	volatile	struct iescb	*ie_scbp;	/* SCB pointer */
	volatile	caddr_t	ie_csr;		/* control & status register */
	volatile	caddr_t	ie_iocache;	/* IC cache xmit/recv lines */
	volatile	caddr_t	ie_ram;		/* RAM on 3E or IORAM on */
						/* Sun4/4XX */

	/* Receive Frame Descriptors */
	struct ierfd	*ie_rfdring;	/* rfd ring start */
	struct ierfd	*ie_rfdlim;	/* one past end of ring */
	volatile struct ierfd	*ie_rfdhd;	/* rfd pointed to by scb */
	volatile struct ierfd	*ie_rfdtl;	/* last rfd (for reclaiming) */

	/* Receive Buffer Descriptors */
	struct ierbd	*ie_rbdring;	/* rbd ring start */
	struct ierbd	*ie_rbdlim;	/* one past end of ring */
	struct ierbd	*ie_rbdhd;	/* first rbd pointed to by first rfd */
	struct ierbd	*ie_rbdtl;	/* last rbd (for reclaim purpose) */

	/* Transmit and Receive Buffers */
	struct  iebuf	*ie_bufbase;	/* buffers base address */
	struct	iebuf	**ie_buftab;	/* buffer pointer stack (filo) */
	u_int	ie_bufi;		/* index of top of the above stack */
	struct  iebuf	**ie_rbp;	/* iebuf associated with rbd */
	struct  iebuf	**ie_tbp;	/* iebuf associated with tbd */
	mblk_t  **ie_tmblk;		/* streams msg associated with tbd */

	/* Transmit Frame Descriptors */
	struct ietcb	*ie_tcbring;	/* tcb ring start */
	struct ietcb	*ie_tcblim;	/* one past end of ring */
	struct ietcb	*ie_tcbtl;	/* last tcb to transmit */
	struct ietcb	*ie_tcbclaimed;	/* last tcb claimed */

	/* Transmit Buffer Descriptors */
	struct ietbd	*ie_tbdring;	/* tbd ring start */
	struct ietbd	*ie_tbdlim;	/* one past end of ring */

	ddi_dma_handle_t ie_dscpthandle;	/* iopb dma handle */
	ddi_dma_handle_t ie_bufhandle;		/* bufs dma handle */

	ulong_t	ie_ipackets;		/* # packets received */
	ulong_t	ie_ierrors;		/* # total input errors */
	ulong_t	ie_opackets;		/* # packets sent */
	ulong_t	ie_oerrors;		/* # total output errors */
	ulong_t	ie_collisions;		/* # collisions */
	ulong_t	ie_xmiturun;		/* # transmit underrun */
	ulong_t	ie_defer;		/* # defers */
	ulong_t	ie_heart;		/* # hearts */
	ulong_t	ie_crc;			/* # receive crc errors */
	ulong_t	ie_align;		/* # alignment errors */
	ulong_t	ie_recvorun;		/* # receive overrun */
	ulong_t	ie_discard;		/* # discarded packets */
	ulong_t	ie_oflo;		/* # receiver overflows */
	ulong_t	ie_uflo;		/* # transmit underflows */
	ulong_t	ie_missed;		/* # receive missed */
	ulong_t	ie_tlcol;		/* # transmit late collisions */
	ulong_t	ie_trtry;		/* # transmit retry failures */
	ulong_t	ie_tnocar;		/* # loss of carrier errors */
	ulong_t	ie_tnocts;		/* # loss of clear to send */
	ulong_t	ie_tbuff;		/* # BUFF set in tmd */
	ulong_t	ie_tsync;		/* # out of synch OWN bit occurences */
	ulong_t	ie_inits;		/* # driver inits */
	ulong_t	ie_notcbs;		/* # out of tcbs occurences */
	ulong_t	ie_notbufs;		/* # out of buffers for xmit */
	ulong_t	ie_norbufs;		/* # out of buffers for receive */
	ulong_t	ie_runotready;		/* # receive unit not ready */
	ulong_t	ie_nocanput;		/* # input canput() returned false */
	ulong_t	ie_allocbfail;		/* # esballoc/allocb failed */
	ulong_t	ie_loaned;		/* # receive biffer loaned */
	ulong_t	ie_dogreset;		/* # reset by iedog() */
};

/* flags */
#define	IERUNNING	0x01	/* chip is initialized */
#define	IESLAVE		0x02	/* slave device (no DMA) */
#define	IEPROMISC	0x04	/* promiscuous mode enabled */

/*
 * le.h header for LANCE Ethernet Driver.
 *
 * Per-Device instance state information.
 *
 * Each instance is dynamically allocated on first attach.
 */
struct	le {
        uint_t  loc_flag;
        struct  le              *le_nextp;      /* next in a linked list */
        volatile        struct  lanceregs       *le_regsp;      /* chip regs */
        uint_t  le_flags;                       /* misc. flags */
        dev_info_t      *le_dip;        /* associated dev_info */
        struct  ether_addr      le_ouraddr;     /* individual address */
        ddi_iblock_cookie_t     le_cookie;      /* cookie from ddi_add_intr */

        kmutex_t        le_xmitlock;            /* protect xmit-side fields */
        kmutex_t        le_intrlock;            /* protect intr-side fields */
        kmutex_t        le_buflock;             /* protect private buffers */

        struct  lance_init_block *le_ibp;       /* chip init block */

        struct  lmd     *le_rmdp;       /* receive descriptor ring start */
        struct  lmd     *le_rmdlimp;    /* receive descriptor ring end */
        int     le_nrmdp2;              /* log(2) # receive descriptors */
        int     le_nrmds;               /* # receive descriptors */
        struct  lmd     *le_tmdp;       /* transmit descriptor ring start */
        struct  lmd     *le_tmdlimp;    /* transmit descriptor ring end */
        int     le_ntmdp2;              /* log(2) # transmit descriptors */
        int     le_ntmds;               /* # transmit descriptors */
        volatile        struct  lmd     *le_rnextp;     /* next chip rmd */
        volatile        struct  lmd     *le_tnextp;     /* next free tmd */
        volatile        struct  lmd     *le_tcurp;      /* next reclaim tmd */
        uint_t  le_wantw;                       /* xmit: out of resources */

        struct  lebuf   *le_tbufp[128]; /* xmit completion tbufs */
        mblk_t  *le_tmblkp[128];        /* xmit completion msgs */
        struct  lebuf   *le_rbufp[128]; /* lebuf associated with RMD */

        uintptr_t       le_membase;     /* base address of slave card memory */
        int     le_memsize;             /* size of slave card memory in bytes */
        int     (*le_init)();           /* device-specific initialize */
        int     (*le_intr)();           /* device-specific interrupt */
        caddr_t le_arg;                 /* device-specific arg */

        int     le_nbufs;               /* # buffers */
        caddr_t le_bufbase;             /* buffers base address */
        caddr_t le_buflim;              /* buffers limit address */
        struct  lebuf   **le_buftab;    /* buffer pointer stack (fifo) */
        int     le_bufi;                /* index of buffer ptr stack top */

        int     le_tpe;                 /* =1 => tpe selected */
        int     le_autosel;             /* =1 => auto-selection enabled */
        int     le_oopkts;              /* old le_opackets */
        int     le_intr_flag;           /* initialization flag for leintr() */
                                        /* bug 1204247 */

        /*
         * DDI dma handle, kernel virtual base,
         * and io virtual base of IOPB area.
         */
        ddi_dma_handle_t        le_iopbhandle;
        uintptr_t               le_iopbkbase;
        uintptr_t               le_iopbiobase;

        queue_t *le_ipq;                /* IPv4 read queue */
        queue_t *le_ip6q;               /* IPv6 read queue */

        /*
         * DDI dma handle, kernel virtual base,
         * and io virtual base addresses of buffer area.
         */
        ddi_dma_handle_t        le_bufhandle;
        uintptr_t               le_bufkbase;
        uintptr_t               le_bufiobase;

        kstat_t *le_intrstats;          /* interrupt statistics */
        kstat_t *le_ksp;                /* kstat pointer */
        uint32_t le_ipackets;           /* # packets received */
        uint32_t le_ierrors;            /* # total input errors */
        uint32_t le_opackets;           /* # packets sent */
        uint32_t le_oerrors;            /* # total output errors */
        uint32_t le_collisions;         /* # collisions */
        uint32_t le_defer;              /* # defers */
        uint32_t le_fram;               /* # receive framing errors */
        uint32_t le_crc;                /* # receive crc errors */
        uint32_t le_oflo;               /* # receiver overflows */
        uint32_t le_uflo;               /* # transmit underflows */
        uint32_t le_missed;             /* # receive missed */
        uint32_t le_tlcol;              /* # transmit late collisions */
        uint32_t le_trtry;              /* # transmit retry failures */
        uint32_t le_tnocar;             /* # loss of carrier errors */
        uint32_t le_inits;              /* # driver inits */
        uint32_t le_notmds;             /* # out of tmds occurences */
        uint32_t le_notbufs;            /* # out of buffers for xmit */
        uint32_t le_norbufs;            /* # out of buffers for receive */
        uint32_t le_nocanput;           /* # input canput() returned false */
        uint32_t le_allocbfail;         /* # esballoc/allocb failed */
        timeout_id_t le_timeout_id;     /* watchdog timeout id */
        int le_tx_lbolt;                /* time of last tx interrupt */
        int le_rx_lbolt;                /* time of last rx interrupt */
        uint32_t *le_dma2_tcsr;         /* pointer to dma2 tst_csr */

        /*
         * MIB II variables
         */
        uint32_t le_rcvbytes;           /* # bytes received */
        uint32_t le_xmtbytes;           /* # bytes transmitted */
        uint32_t le_multircv;           /* # multicast packets received */
        uint32_t le_multixmt;           /* # multicast packets for xmit */
        uint32_t le_brdcstrcv;          /* # broadcast packets received */
        uint32_t le_brdcstxmt;          /* # broadcast packets for xmit */
        uint32_t le_norcvbuf;           /* # rcv packets discarded */
        uint32_t le_noxmtbuf;           /* # xmit packets discarded */
};

/* flags */
#define	LERUNNING	0x01	/* chip is initialized */
#define	LESLAVE		0x02	/* slave device (no DMA) */
#define	LEPROMISC	0x04	/* promiscuous mode enabled */
#define	LESUN4C		0x08	/* this system is a sun4c */
#define	LESUSPENDED	0x10	/* suspended interface */

/*
 * Declarations and definitions specific to the
 * Quad Ethernet Device (QED) Driver.
 *
 * QED Per-Channel instance state information.
 *
 * Each instance is dynamically allocated on first attach.
 */
#define QEC_QMDMAX      (256)                   /* # Tx/Rx ring entries */

struct	qe {
	struct	qe		*qe_nextp;	/* next in a linked list */
	dev_info_t		*qe_dip;	/* associated dev_info */
	struct	ether_addr	qe_ouraddr;	/* individual address */
	int			qe_chan;	/* channel no */
	int			qe_timerid;	/* Timer Id */
	int			qe_once;	/* attempt since last check */
	int			qe_ihang;	/* Port Hang Flag */
	u_int			qe_flags;	/* misc. flags */
	u_int			qe_wantw;	/* xmit: out of resources */
	ddi_iblock_cookie_t	qe_cookie;	/* cookie from ddi_add_intr */

	volatile struct	qecm_chan	*qe_chanregp;	/* QEC chan regs */
	volatile struct	mace		*qe_maceregp;	/* MACE regs */

	kmutex_t	qe_xmitlock;		/* protect xmit-side fields */
	kmutex_t	qe_intrlock;		/* protect intr-side fields */
	kmutex_t	qe_buflock;		/* protect private buffers */

	struct	qmd	*qe_rmdp;	/* receive descriptor ring start */
	struct	qmd	*qe_rmdlimp;	/* receive descriptor ring end */
	struct	qmd	*qe_tmdp;	/* transmit descriptor ring start */
	struct	qmd	*qe_tmdlimp;	/* transmit descriptor ring end */
	volatile	struct	qmd	*qe_rnextp;	/* next chip rmd */
	volatile	struct	qmd	*qe_rlastp;	/* last free rmd */
	volatile	struct	qmd	*qe_tnextp;	/* next free tmd */
	volatile	struct	qmd	*qe_tcurp;	/* next tmd to reclm */

	mblk_t 	*qe_tmblkp[QEC_QMDMAX];		/* qebuf associated with TMD */
	mblk_t 	*qe_rmblkp[QEC_QMDMAX];		/* qebuf associated with RMD */

	queue_t	*qe_ipq;		/* ip read queue */

	/*
	 * DDI dma handle, kernel virtual base,
	 * and io virtual base of IOPB area.
	 */
	ddi_dma_handle_t	qe_iopbhandle;
	u_long			qe_iopbkbase;
	u_long			qe_iopbiobase;

	/*
	 * these are handles for the dvma resources reserved
	 * by dvma_reserve
	 */
	ddi_dma_handle_t	qe_dvmarh;	/* dvma recv handle */
	ddi_dma_handle_t	qe_dvmaxh;	/* dvma xmit handle */

	/*
	 * these are used if dvma reserve fails, and we have to fall
	 * back on the older ddi_dma_addr_setup routines
	 */
	ddi_dma_handle_t	*qe_dmarh;
	ddi_dma_handle_t	*qe_dmaxh;

	kstat_t	*qe_ksp;	/* kstat pointer */

	u_long	qe_ipackets;	/* # packets received */
	u_long	qe_iipackets;	/* # packets received */
	u_long	qe_ierrors;	/* # total input errors */
	u_long	qe_opackets;	/* # packets sent */
	u_long	qe_oopackets;	/* # packets sent @ last check */
	u_long	qe_oerrors;	/* # total output errors */
	u_long	qe_txcoll;	/* # xmit collisions */
	u_long	qe_rxcoll;	/* # recv collisions */
	u_long	qe_defer;	/* # excessive defers */
	u_long	qe_fram;	/* # recv framing errors */
	u_long	qe_crc;		/* # recv crc errors */
	u_long	qe_buff;	/* # recv packet sizes > buffer size */
	u_long	qe_drop;	/* # recv packets dropped */
	u_long	qe_oflo;	/* # recv overflow */
	u_long	qe_uflo;	/* # xmit underflow */
	u_long	qe_missed;	/* # recv missed */
	u_long	qe_tlcol;	/* # xmit late collision */
	u_long	qe_trtry;	/* # xmit retry failures */
	u_long	qe_tnocar;	/* # loss of carrier errors */
	u_long	qe_inits;	/* # driver inits */
	u_long	qe_nocanput;	/* # canput() failures */
	u_long	qe_allocbfail;	/* # allocb() failures */
	u_long	qe_runt;	/* # recv runt packets */
	u_long	qe_jab;		/* # mace jabber errors */
	u_long	qe_babl;	/* # mace babble errors */
	u_long	qe_tmder;	/* # chained tx desc. errors */
	u_long	qe_laterr;	/* # sbus tx late error */
	u_long	qe_parerr;	/* # sbus tx parity errors */
	u_long	qe_errack;	/* # sbus tx error acks */
	u_long	qe_notmds;	/* # out of tmds */
	u_long	qe_notbufs;	/* # out of xmit buffers */
	u_long	qe_norbufs;	/* # out of recv buffers */
	u_long	qe_clsn;	/* # recv late collisions */

};

/* flags */
#define	QERUNNING	0x01	/* chip is initialized */
#define	QEPROMISC	0x02	/* promiscuous mode enabled */
#define	QESUN4C		0x04	/* this system is a sun4c */
#define	QEDMA		0x08	/* this is true when using the */
				/* the ddi_dma kind of interfaces */
#define	QESUSPENDED	0x10	/* suspended interface */
#define	QESTOP		0x20    /* Stopped Interface */

/*
 * The transmit and receiver Descriptor Rings are organized as "wrap-around
 * descriptors of programmable size.
*/
#define	HME_TMDMAX	(256)	/* Transmit descriptor ring size */
#define	HME_RMDMAX	(256)	/* Receive descriptor ring size */

#define	HME_PARAM_CNT	29

/* Named Dispatch Parameter Management Structure */
typedef struct hmeparam_s {
	u_long hme_param_min;
	u_long hme_param_max;
	u_long hme_param_val;
	char   *hme_param_name;
} hmeparam_t;

struct	hmesave {
	u_long	hme_starts;
	u_long	hme_opackets;
};

/*
 * HME Device Channel instance state information.
 *
 * Each instance is dynamically allocated on first attach.
 * FILE:  if-solaris8.h
 */
struct	hme {
	struct	hme		*hme_nextp;	/* next in a linked list */
	dev_info_t		*dip;	/* associated dev_info */
	int			instance;
	ulong_t			pagesize;

	/*
	 * xcvr information
	 */

	uint16_t			xcvr_dev_id;
	uint16_t			xcvr_dev_rev;
	uint16_t			hme_idr1;
	uint16_t			hme_idr2;
	uint16_t			hme_anar;
	uint16_t			hme_anlpar;
	uint16_t			hme_aner;

	uint_t			promisc_cnt;
	int			hme_mifpoll_enable;
	int			hme_frame_enable;
	int			hme_lance_mode_enable;
	int			hme_rxcv_enable;

	uint_t			hme_burstsizes;
	uint32_t		hme_config;

	int			hme_phy_retries;
	int			hme_phy_failure;

	int			hme_64bit_xfer;
	int			hme_phyad;
	int			hme_autoneg;

	caddr_t			hme_g_nd;
	
	hmeparam_t		hme_param_arr[HME_PARAM_CNT];
	int			hme_transceiver;
	int			hme_link_pulse_disabled;
	uint16_t		hme_bmcr;
	uint16_t		hme_bmsr;
	int			hme_mode;
	int			hme_linkup;
	int			hme_xcvr_state;
	int			hme_forcespeed;
	int			hme_tryspeed;
	int			hme_fdx;
	int			hme_pace_count;

	int			hme_macfdx;
	int			hme_linkcheck;
	int			hme_linkup_msg;
	int			hme_force_linkdown;
	int			hme_nlasttries;
	int			hme_ntries;
	int			hme_delay;
	int			hme_linkup_10;
	int			hme_linkup_cnt;
	timeout_id_t		hme_timerid;
	int			hme_cheerio_mode;
	int			hme_polling_on;
	int			hme_mifpoll_data;
	int			hme_mifpoll_flag;

	ushort_t		hme_disabled;

	struct	ether_addr	hme_factaddr;
	struct	ether_addr	hme_ouraddr;
	uint32_t		hme_addrflags;
	uint32_t		hme_flags;
	uint32_t		hme_wantw;

	volatile struct hme_global      *hme_globregp;  /* HME global regs */
        volatile struct hme_etx         *hme_etxregp;   /* HME ETX regs */
        volatile struct hme_erx         *hme_erxregp;   /* HME ERX regs */
        volatile struct hme_bmac        *hme_bmacregp;  /* BigMAC registers */
        volatile struct hme_mif         *hme_mifregp;   /* HME transceiver */

	kmutex_t	hme_xmitlock;
	kmutex_t	hme_intrlock;		/* protect intr-side fields */
	kmutex_t	hme_linklock;		/* protect link-side fields */
	ddi_iblock_cookie_t	hme_cookie;	/* interrupt cookie */

        struct  hme_rmd *hme_rmdp;      /* receive descriptor ring start */
        struct  hme_rmd *hme_rmdlimp;   /* receive descriptor ring end */
        struct  hme_tmd *hme_tmdp;      /* transmit descriptor ring start */
        struct  hme_tmd *hme_tmdlimp;   /* transmit descriptor ring end */
        volatile struct hme_rmd *hme_rnextp;    /* next chip rmd */
        volatile struct hme_rmd *hme_rlastp;    /* last free rmd */
        volatile struct hme_tmd *hme_tnextp;    /* next free tmd */
        volatile struct hme_tmd *hme_tcurp;     /* next tmd to reclaim (used) */

	mblk_t	*hme_tmblkp[HME_TMDMAX];	/* hmebuf associated with TMD */
	mblk_t	*hme_rmblkp[HME_RMDMAX];	/* hmebuf associated with RMD */

	queue_t	*hme_ip4q;		/* IPv4 read queue */
	queue_t	*hme_ip6q;		/* IPv4 read queue */

#ifdef	COMMON_DDI_REG
	ddi_device_acc_attr_t	hme_dev_attr;
	ddi_acc_handle_t	hme_globregh;   /* HME global regs */
	ddi_acc_handle_t	hme_etxregh;    /* HME ETX regs */
	ddi_acc_handle_t	hme_erxregh;    /* HME ERX regs */
	ddi_acc_handle_t	hme_bmacregh;   /* BigMAC registers */
	ddi_acc_handle_t	hme_mifregh;    /* HME transceiver */
	ddi_dma_cookie_t	hme_md_c;	/* trmd dma cookie */
	ddi_acc_handle_t	hme_mdm_h;	/* trmd memory handle */
	ddi_dma_handle_t	hme_md_h;	/* trmdp dma handle */
#endif
	/*
	 * DDI dma handle, kernel virtual base,
	 * and io virtual base of IOPB area.
	 */
	ddi_dma_handle_t	hme_iopbhandle;
	u_long			hme_iopbkbase;
	u_long			hme_iopbiobase;

	/*
	 * these are handles for the dvma resources reserved
	 * by dvma_reserve
	 */
	ddi_dma_handle_t	hme_dvmarh;	/* dvma recv handle */
	ddi_dma_handle_t	hme_dvmaxh;	/* dvma xmit handle */

	/*
	 * these are used if dvma reserve fails, and we have to fall
	 * back on the older ddi_dma_addr_setup routines
	 */
	ddi_dma_handle_t	*hme_dmarh;
	ddi_dma_handle_t	*hme_dmaxh;

	kstat_t	*hme_ksp;	/* kstat pointer */
	kstat_t	*hme_intrstats;	/* kstat interrupt counter */

	u_long	hme_ipackets;
	u_long	hme_ierrors;
	u_long	hme_opackets;
	u_long	hme_oerrors;
	u_long	hme_coll;
	u_long	hme_defer;
	u_long	hme_fram;
	u_long	hme_crc;
	u_long	hme_sqerr;
	u_long	hme_cvc;
	u_long	hme_lenerr;
	u_long	hme_drop;
	u_long	hme_buff;
	u_long	hme_oflo;
	u_long	hme_uflo;
	u_long	hme_missed;
	u_long	hme_tlcol;
	u_long	hme_trtry;
	u_long	hme_fstcol;
	u_long	hme_tnocar;
	u_long	hme_inits;
	u_long	hme_nocanput;
	u_long	hme_allocbfail;
	u_long	hme_runt;
	u_long	hme_jab;
	u_long	hme_babl;
	u_long	hme_tmder;
	u_long	hme_txlaterr;
	u_long	hme_rxlaterr;
	u_long	hme_slvparerr;
	u_long	hme_txparerr;
	u_long	hme_rxparerr;
	u_long	hme_slverrack;
	u_long	hme_txerrack;
	u_long	hme_rxerrack;
	u_long	hme_txtagerr;
	u_long	hme_rxtagerr;
	u_long	hme_eoperr;
	u_long	hme_notmds;
	u_long	hme_notbufs;
	u_long	hme_norbufs;
	u_long	hme_clsn;

	/* check if transmitter is hung */
	u_long	hme_starts;
	u_long	hme_txhung;
	struct hmesave hmesave;

	/*
	 * MIB II variables
	 */
	ulong_t hme_rcvbytes;		/* # bytes received */
	ulong_t hme_xmtbytes;		/* # bytes transmitted */
	ulong_t hme_multircv;		/* # multicast packets received */
	ulong_t hme_multixmt;		/* # multicast packets for xmit */
	ulong_t hme_brdcstrcv;		/* # broadcast packets received */
	ulong_t hme_brdcstxmt;		/* # broadcast packets for xmit */
	ulong_t hme_norcvbuf;		/* # rcv packets discarded */
	ulong_t hme_noxmtbuf;		/* # xmit packets discarded */
};

/* flags */
#define	HMERUNNING	0x01	/* chip is initialized */
#define	HMEPROMISC	0x02	/* promiscuous mode enabled */
#define	HMESUN4C	0x04	/* this system is a sun4c */
#define	HMESUSPENDED	0x08	/* suspended interface */
#define	HMEINITIALIZED	0x10	/* interface initialized */
#define	HMENOTIMEOUTS	0x20	/* disallow timeout rescheduling */

struct	qfe {
	struct	hme		*hme_nextp;	/* next in a linked list */
	dev_info_t		*hme_dip;	/* associated dev_info */
	int			hme_id;
#ifdef  QFETRUNK
        hmetrunk_t              *hme_trunkp;    /* trunk ptr, if trunked */
#endif
#ifdef RX_DRAIN_QUEUE
        mblk_t **rx_dq;
        uint_t rx_dq_size;       /* Size of the receive drain queue. */
        uint_t rx_dq_wr_index;
        uint_t rx_dq_rd_index;
        uint_t rx_dq_rd_pending;
        kthread_t *rx_dq_thread;
        kmutex_t rx_dq_mutex;
        kcondvar_t rx_dq_cv;
#endif
        uint_t                  hme_asicrev;
	uint_t			hme_promisc_cnt;/* Promiscuous streams open */

	/*
	 * xcvr information
	 */

	uint16_t			xcvr_dev_id;
	uint16_t			xcvr_dev_rev;
	uint16_t			hme_idr1;
	uint16_t			hme_idr2;
	uint16_t			hme_anar;
	uint16_t			hme_anlpar;
	uint16_t			hme_aner;

	uint_t			promisc_cnt;
	int			hme_mifpoll_enable;
	int			hme_frame_enable;
	int			hme_lance_mode_enable;
	int			hme_rxcv_enable;

	uint_t			hme_burstsizes;
	uint32_t		hme_config;

	int			hme_phy_retries;
	int			hme_phy_failure;

	int			hme_64bit_xfer;
	int			hme_phyad;
	int			hme_autoneg;

	caddr_t			hme_g_nd;
	
	hmeparam_t		hme_param_arr[HME_PARAM_CNT];
	int			hme_transceiver;
	int			hme_link_pulse_disabled;
	uint16_t		hme_bmcr;
	uint16_t		hme_bmsr;
	int			hme_mode;
	int			hme_linkup;
	int			hme_xcvr_state;
	int			hme_forcespeed;
	int			hme_tryspeed;
	int			hme_fdx;
	int			hme_pace_count;

	int			hme_macfdx;
	int			hme_linkcheck;
	int			hme_linkup_msg;
	int			hme_force_linkdown;
	int			hme_nlasttries;
	int			hme_ntries;
	int			hme_delay;
	int			hme_linkup_10;
	int			hme_linkup_cnt;
	timeout_id_t		hme_timerid;
	int			hme_cheerio_mode;
	int			hme_polling_on;
	int			hme_mifpoll_data;
	int			hme_mifpoll_flag;

	ushort_t		hme_disabled;

	struct	ether_addr	hme_factaddr;
	struct	ether_addr	hme_ouraddr;
	uint32_t		hme_addrflags;
	uint32_t		hme_flags;
	uint32_t		hme_wantw;

	volatile struct hme_global      *hme_globregp;  /* HME global regs */
        volatile struct hme_etx         *hme_etxregp;   /* HME ETX regs */
        volatile struct hme_erx         *hme_erxregp;   /* HME ERX regs */
        volatile struct hme_bmac        *hme_bmacregp;  /* BigMAC registers */
        volatile struct hme_mif         *hme_mifregp;   /* HME transceiver */

	kmutex_t	hme_xmitlock;
	kmutex_t	hme_intrlock;		/* protect intr-side fields */
	kmutex_t	hme_linklock;		/* protect link-side fields */
	ddi_iblock_cookie_t	hme_cookie;	/* interrupt cookie */

        struct  hme_rmd *hme_rmdp;      /* receive descriptor ring start */
        struct  hme_rmd *hme_rmdlimp;   /* receive descriptor ring end */
        struct  hme_tmd *hme_tmdp;      /* transmit descriptor ring start */
        struct  hme_tmd *hme_tmdlimp;   /* transmit descriptor ring end */
        volatile struct hme_rmd *hme_rnextp;    /* next chip rmd */
        volatile struct hme_rmd *hme_rlastp;    /* last free rmd */
        volatile struct hme_tmd *hme_tnextp;    /* next free tmd */
        volatile struct hme_tmd *hme_tcurp;     /* next tmd to reclaim (used) */

	mblk_t	*hme_tmblkp[HME_TMDMAX];	/* hmebuf associated with TMD */
	mblk_t	*hme_rmblkp[HME_RMDMAX];	/* hmebuf associated with RMD */

	queue_t	*hme_ip4q;		/* IPv4 read queue */
	queue_t	*hme_ip6q;		/* IPv4 read queue */

#ifdef	COMMON_DDI_REG
	ddi_device_acc_attr_t	hme_dev_attr;
	ddi_acc_handle_t	hme_globregh;   /* HME global regs */
	ddi_acc_handle_t	hme_etxregh;    /* HME ETX regs */
	ddi_acc_handle_t	hme_erxregh;    /* HME ERX regs */
	ddi_acc_handle_t	hme_bmacregh;   /* BigMAC registers */
	ddi_acc_handle_t	hme_mifregh;    /* HME transceiver */
	ddi_dma_cookie_t	hme_md_c;	/* trmd dma cookie */
	ddi_acc_handle_t	hme_mdm_h;	/* trmd memory handle */
	ddi_dma_handle_t	hme_md_h;	/* trmdp dma handle */
#endif
	/*
	 * DDI dma handle, kernel virtual base,
	 * and io virtual base of IOPB area.
	 */
	ddi_dma_handle_t	hme_iopbhandle;
	u_long			hme_iopbkbase;
	u_long			hme_iopbiobase;

	/*
	 * these are handles for the dvma resources reserved
	 * by dvma_reserve
	 */
	ddi_dma_handle_t	hme_dvmarh;	/* dvma recv handle */
	ddi_dma_handle_t	hme_dvmaxh;	/* dvma xmit handle */

	/*
	 * these are used if dvma reserve fails, and we have to fall
	 * back on the older ddi_dma_addr_setup routines
	 */
	ddi_dma_handle_t	*hme_dmarh;
	ddi_dma_handle_t	*hme_dmaxh;

	kstat_t	*hme_ksp;	/* kstat pointer */
	kstat_t	*hme_intrstats;	/* kstat interrupt counter */

	u_long	hme_ipackets;
	u_long	hme_ierrors;
	u_long	hme_opackets;
	u_long	hme_oerrors;
	u_long	hme_coll;
	u_long	hme_defer;
	u_long	hme_fram;
	u_long	hme_crc;
	u_long	hme_sqerr;
	u_long	hme_cvc;
	u_long	hme_lenerr;
	u_long	hme_drop;
	u_long	hme_buff;
	u_long	hme_oflo;
	u_long	hme_uflo;
	u_long	hme_missed;
	u_long	hme_tlcol;
	u_long	hme_trtry;
	u_long	hme_fstcol;
	u_long	hme_tnocar;
	u_long	hme_inits;
	u_long	hme_nocanput;
	u_long	hme_allocbfail;
	u_long	hme_runt;
	u_long	hme_jab;
	u_long	hme_babl;
	u_long	hme_tmder;
	u_long	hme_txlaterr;
	u_long	hme_rxlaterr;
	u_long	hme_slvparerr;
	u_long	hme_txparerr;
	u_long	hme_rxparerr;
	u_long	hme_slverrack;
	u_long	hme_txerrack;
	u_long	hme_rxerrack;
	u_long	hme_txtagerr;
	u_long	hme_rxtagerr;
	u_long	hme_eoperr;
	u_long	hme_notmds;
	u_long	hme_notbufs;
	u_long	hme_norbufs;
	u_long	hme_clsn;

	/* check if transmitter is hung */
	u_long	hme_starts;
	u_long	hme_txhung;
	struct hmesave hmesave;

	/*
	 * MIB II variables
	 */
	ulong_t hme_rcvbytes;		/* # bytes received */
	ulong_t hme_xmtbytes;		/* # bytes transmitted */
	ulong_t hme_multircv;		/* # multicast packets received */
	ulong_t hme_multixmt;		/* # multicast packets for xmit */
	ulong_t hme_brdcstrcv;		/* # broadcast packets received */
	ulong_t hme_brdcstxmt;		/* # broadcast packets for xmit */
	ulong_t hme_norcvbuf;		/* # rcv packets discarded */
	ulong_t hme_noxmtbuf;		/* # xmit packets discarded */
};
