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

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

/*
 * 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 {
	struct	le		*le_nextp;	/* next in a linked list */
	volatile	struct	lanceregs	*le_regsp;	/* chip regs */
	u_int	le_flags;			/* misc. flags */
	dev_info_t	*le_dip;	/* associated dev_info */
	struct	ether_addr	le_ouraddr;	/* individual address */

	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 */
	u_int	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 */

	u_long	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 */

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

	queue_t	*le_ipq;		/* ip read queue */

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

	ulong_t	le_ipackets;		/* # packets received */
	ulong_t	le_ierrors;		/* # total input errors */
	ulong_t	le_opackets;		/* # packets sent */
	ulong_t	le_oerrors;		/* # total output errors */
	ulong_t	le_collisions;		/* # collisions */
	ulong_t	le_defer;		/* # defers */
	ulong_t	le_fram;		/* # receive framming errors */
	ulong_t	le_crc;			/* # receive crc errors */
	ulong_t	le_oflo;		/* # receiver overflows */
	ulong_t	le_uflo;		/* # transmit underflows */
	ulong_t	le_missed;		/* # receive missed */
	ulong_t	le_tlcol;		/* # transmit late collisions */
	ulong_t	le_trtry;		/* # transmit retry failures */
	ulong_t	le_tnocar;		/* # loss of carrier errors */
	ulong_t	le_inits;		/* # driver inits */
	ulong_t	le_notmds;		/* # out of tmds occurences */
	ulong_t	le_notbufs;		/* # out of buffers for xmit */
	ulong_t	le_norbufs;		/* # out of buffers for receive */
	ulong_t	le_nocanput;		/* # input canput() returned false */
	ulong_t	le_allocbfail;		/* # esballoc/allocb failed */
};

/* 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 */
	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 */

	struct	qebuf	*qe_tbufp[QEC_QMDMAX];	/* qebuf associated with TMD */
	struct	qebuf	*qe_rbufp[QEC_QMDMAX];	/* qebuf associated with RMD */
	mblk_t 	*qe_tmblkp[QEC_QMDMAX];		/* qebuf associated with TMD */

	caddr_t	qe_buflim;		/* buffers limit address */
	struct	qebuf	**qe_buftab;	/* buffer pointer stack (fifo) */
	int	qe_bufi;		/* index of buffer ptr stack top */
	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;

	/*
	 * DDI dma handle, kernel virtual base,
	 * and io virtual base addresses of buffer area.
	 */
	ddi_dma_handle_t	qe_bufhandle;
	u_long			qe_bufkbase;
	u_long			qe_bufiobase;

#ifndef	MPSAS
	kstat_t	*qe_ksp;	/* kstat pointer */
#endif	MPSAS
	u_long	qe_ipackets;	/* # packets received */
	u_long	qe_ierrors;	/* # total input errors */
	u_long	qe_opackets;	/* # packets sent */
	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 */

/*
 * 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;
/*
 * HME Device Channel instance state information.
 *
 * Each instance is dynamically allocated on first attach.
 */
struct	hme {
	struct	hme		*hme_nextp;	/* next in a linked list */
	dev_info_t		*hme_dip;	/* associated dev_info */
	int			hme_asicrev;
	int			hme_mifpoll_enable;
	int			hme_frame_enable;
	int			hme_lance_mode_enable;
	int			hme_rxcv_enable;
	int			hme_burstsizes; /* binary encoded val */
	int			hme_64bit_xfer;	/* 64-bit Sbus xfers */
	int			hme_phyad;
	int			hme_autoneg;
	caddr_t			hme_g_nd;	/* head of the */
						/* named dispatch table */
	hmeparam_t		hme_param_arr[HME_PARAM_CNT];
	int			hme_transceiver;  /* current PHY in use */
	int			hme_link_pulse_disabled;
	u_short			hme_bmcr;	/* PHY control register */
	u_short			hme_bmsr;	/* PHY status register */
	u_short			hme_idr1;	/* PHY IDR1 register */
	u_short			hme_idr2;	/* PHY IDR2 register */
	u_short			hme_anar;	/* PHY ANAR register */
	u_short			hme_anlpar;	/* PHY ANLPAR register */
	u_short			hme_aner;	/* PHY ANER register */
	int			hme_mode;	/* auto/forced mode */
	int			hme_linkup;	/* link status */
	int			hme_forcespeed; /* speed in forced mode */
	int			hme_tryspeed;	/* speed in auto mode */
	int			hme_fdx;	/* full-duplex mode */
	int			hme_pace_count;	/* pacing pkt 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;
	int			hme_timerid;
	int			hme_polling_on;
	int			hme_mifpoll_data;
	int			hme_mifpoll_flag;
	struct	ether_addr	hme_factaddr;	/* factory mac address */
	struct	ether_addr	hme_ouraddr;	/* individual address */
	u_int			hme_addrflags;	/* address flags */
	u_int			hme_flags;	/* misc. flags */
	u_int			hme_wantw;	/* xmit: out of resources */
	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;		/* protect xmit-side fields */
	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_ipq;		/* ip read queue */
#ifdef COMMON_DDI_REG
	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 */
	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;
};
/* 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 */
