if_hatmvar.h revision 121729
1116491Sharti/*
2116491Sharti * Copyright (c) 2001-2003
3116491Sharti *	Fraunhofer Institute for Open Communication Systems (FhG Fokus).
4116491Sharti * 	All rights reserved.
5116491Sharti *
6116491Sharti * Redistribution and use in source and binary forms, with or without
7116491Sharti * modification, are permitted provided that the following conditions
8116491Sharti * are met:
9116491Sharti * 1. Redistributions of source code must retain the above copyright
10116491Sharti *    notice, this list of conditions and the following disclaimer.
11116491Sharti * 2. Redistributions in binary form must reproduce the above copyright
12116491Sharti *    notice, this list of conditions and the following disclaimer in the
13116491Sharti *    documentation and/or other materials provided with the distribution.
14116491Sharti *
15116491Sharti * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16116491Sharti * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17116491Sharti * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18116491Sharti * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19116491Sharti * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20116491Sharti * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21116491Sharti * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22116491Sharti * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23116491Sharti * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24116491Sharti * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25116491Sharti * SUCH DAMAGE.
26116491Sharti *
27116491Sharti * Author: Hartmut Brandt <harti@freebsd.org>
28116491Sharti *
29116491Sharti * $FreeBSD: head/sys/dev/hatm/if_hatmvar.h 121729 2003-10-30 10:43:52Z harti $
30116491Sharti *
31116491Sharti * Fore HE driver for NATM
32116491Sharti */
33116491Sharti
34116491Sharti/*
35116491Sharti * Debug statistics of the HE driver
36116491Sharti */
37116491Shartistruct istats {
38116491Sharti	uint32_t	tdprq_full;
39116491Sharti	uint32_t	hbuf_error;
40116491Sharti	uint32_t	crc_error;
41116491Sharti	uint32_t	len_error;
42116491Sharti	uint32_t	flow_closed;
43116491Sharti	uint32_t	flow_drop;
44116491Sharti	uint32_t	tpd_no_mem;
45116491Sharti	uint32_t	rx_seg;
46116491Sharti	uint32_t	empty_hbuf;
47116491Sharti	uint32_t	short_aal5;
48116491Sharti	uint32_t	badlen_aal5;
49116491Sharti	uint32_t	bug_bad_isw;
50116491Sharti	uint32_t	bug_no_irq_upd;
51116491Sharti	uint32_t	itype_tbrq;
52116491Sharti	uint32_t	itype_tpd;
53116491Sharti	uint32_t	itype_rbps;
54116491Sharti	uint32_t	itype_rbpl;
55116491Sharti	uint32_t	itype_rbrq;
56116491Sharti	uint32_t	itype_rbrqt;
57116491Sharti	uint32_t	itype_unknown;
58116491Sharti	uint32_t	itype_phys;
59116491Sharti	uint32_t	itype_err;
60116491Sharti	uint32_t	defrag;
61118169Sharti	uint32_t	mcc;
62118169Sharti	uint32_t	oec;
63118169Sharti	uint32_t	dcc;
64118169Sharti	uint32_t	cec;
65121676Sharti	uint32_t	no_rcv_mbuf;
66116491Sharti};
67116491Sharti
68116491Sharti/* Card memory layout parameters */
69116491Sharti#define HE_CONFIG_MEM_LAYOUT {						\
70116491Sharti	{			/* 155 */				\
71116491Sharti	  20,			/* cells_per_row */			\
72116491Sharti	  1024,			/* bytes_per_row */			\
73116491Sharti	  512,			/* r0_numrows */			\
74116491Sharti	  1018,			/* tx_numrows */			\
75116491Sharti	  512,			/* r1_numrows */			\
76116491Sharti	  6,			/* r0_startrow */			\
77116491Sharti	  2			/* cells_per_lbuf */			\
78116491Sharti	}, {			/* 622 */				\
79116491Sharti	  40,			/* cells_per_row */			\
80116491Sharti	  2048,			/* bytes_per_row */			\
81116491Sharti	  256,			/* r0_numrows */			\
82116491Sharti	  512,			/* tx_numrows */			\
83116491Sharti	  256,			/* r1_numrows */			\
84116491Sharti	  0,			/* r0_startrow */			\
85116491Sharti	  4			/* cells_per_lbuf */			\
86116491Sharti	}								\
87116491Sharti}
88116491Sharti
89116491Sharti/*********************************************************************/
90116491Shartistruct hatm_softc;
91116491Sharti
92116491Sharti/*
93116491Sharti * A chunk of DMA-able memory
94116491Sharti */
95116491Shartistruct dmamem {
96116491Sharti	u_int		size;		/* in bytes */
97116491Sharti	u_int		align;		/* alignement */
98116491Sharti	bus_dma_tag_t	tag;		/* DMA tag */
99116491Sharti	void		*base;		/* the memory */
100116491Sharti	bus_addr_t	paddr;		/* physical address */
101116491Sharti	bus_dmamap_t	map;		/* the MAP */
102116491Sharti};
103116491Sharti
104116491Sharti/*
105116491Sharti * RBP (Receive Buffer Pool) queue entry and queue.
106116491Sharti */
107116491Shartistruct herbp {
108116491Sharti	u_int		size;		/* RBP number of entries (power of two) */
109116491Sharti	u_int		thresh;		/* interrupt treshold */
110116491Sharti	uint32_t	bsize;		/* buffer size in bytes */
111116491Sharti	u_int		offset;		/* free space at start for small bufs */
112116491Sharti	uint32_t	mask;		/* mask for index */
113116491Sharti	struct dmamem	mem;		/* the queue area */
114116491Sharti	struct he_rbpen	*rbp;
115116491Sharti	uint32_t	head, tail;	/* head and tail */
116116491Sharti};
117116491Sharti
118116491Sharti/*
119116491Sharti * RBRQ (Receive Buffer Return Queue) entry and queue.
120116491Sharti */
121116491Shartistruct herbrq {
122116491Sharti	u_int		size;		/* number of entries */
123116491Sharti	u_int		thresh;		/* interrupt threshold */
124116491Sharti	u_int		tout;		/* timeout value */
125116491Sharti	u_int		pcnt;		/* packet count threshold */
126116491Sharti	struct dmamem	mem;		/* memory */
127116491Sharti	struct he_rbrqen *rbrq;
128116491Sharti	uint32_t	head;		/* driver end */
129116491Sharti};
130116491Sharti
131116491Sharti/*
132116491Sharti * TPDRQ (Transmit Packet Descriptor Ready Queue) entry and queue
133116491Sharti */
134116491Shartistruct hetpdrq {
135116491Sharti	u_int		size;		/* number of entries */
136116491Sharti	struct dmamem	mem;		/* memory */
137116491Sharti	struct he_tpdrqen *tpdrq;
138116491Sharti	u_int		head;		/* head (copy of adapter) */
139116491Sharti	u_int		tail;		/* written back to adapter */
140116491Sharti};
141116491Sharti
142116491Sharti/*
143116491Sharti * TBRQ (Transmit Buffer Return Queue) entry and queue
144116491Sharti */
145116491Shartistruct hetbrq {
146116491Sharti	u_int		size;		/* number of entries */
147116491Sharti	u_int		thresh;		/* interrupt threshold */
148116491Sharti	struct dmamem	mem;		/* memory */
149116491Sharti	struct he_tbrqen *tbrq;
150116491Sharti	u_int		head;		/* adapter end */
151116491Sharti};
152116491Sharti
153116491Sharti/*==================================================================*/
154116491Sharti
155116491Sharti/*
156116491Sharti * TPDs are 32 byte and must be aligned on 64 byte boundaries. That means,
157116491Sharti * that half of the space is free. We use this space to plug in a link for
158116491Sharti * the list of free TPDs. Note, that the m_act member of the mbufs contain
159116491Sharti * a pointer to the dmamap.
160116491Sharti *
161116491Sharti * The maximum number of TDPs is the size of the common transmit packet
162116491Sharti * descriptor ready queue plus the sizes of the transmit buffer return queues
163116491Sharti * (currently only queue 0). We allocate and map these TPD when initializing
164116491Sharti * the card. We also allocate on DMA map for each TPD. Only the map in the
165116491Sharti * last TPD of a packets is used when a packet is transmitted.
166116491Sharti * This is signalled by having the mbuf member of this TPD non-zero and
167116491Sharti * pointing to the mbuf.
168116491Sharti */
169116491Sharti#define HE_TPD_SIZE		64
170116491Shartistruct tpd {
171116491Sharti	struct he_tpd		tpd;	/* at beginning */
172116491Sharti	SLIST_ENTRY(tpd)	link;	/* free cid list link */
173116491Sharti	struct mbuf		*mbuf;	/* the buf chain */
174116491Sharti	bus_dmamap_t		map;	/* map */
175116491Sharti	uint32_t		cid;	/* CID */
176116491Sharti	uint16_t		no;	/* number of this tpd */
177116491Sharti};
178116491ShartiSLIST_HEAD(tpd_list, tpd);
179116491Sharti
180116491Sharti#define TPD_SET_USED(SC, I) do {				\
181116491Sharti	(SC)->tpd_used[(I) / 8] |= (1 << ((I) % 8));		\
182116491Sharti    } while (0)
183116491Sharti
184116491Sharti#define TPD_CLR_USED(SC, I) do {				\
185116491Sharti	(SC)->tpd_used[(I) / 8] &= ~(1 << ((I) % 8));		\
186116491Sharti    } while (0)
187116491Sharti
188116491Sharti#define TPD_TST_USED(SC, I) ((SC)->tpd_used[(I) / 8] & (1 << ((I) % 8)))
189116491Sharti
190116491Sharti#define TPD_ADDR(SC, I) ((struct tpd *)((char *)sc->tpds.base +	\
191116491Sharti    (I) * HE_TPD_SIZE))
192116491Sharti
193116491Sharti/*==================================================================*/
194116491Sharti
195116491Sharti/*
196116491Sharti * External MBUFs. The card needs a lot of mbufs in the pools for high
197116491Sharti * performance. The problem with using mbufs directly is that we would need
198116491Sharti * a dmamap for each of the mbufs. This can exhaust iommu space on the sparc
199116491Sharti * and it eats also a lot of processing time. So we use external mbufs
200116491Sharti * for the small buffers and clusters for the large buffers.
201116491Sharti * For receive group 0 we use 5 ATM cells, for group 1 one (52 byte) ATM
202116491Sharti * cell. The mbuf storage is allocated pagewise and one dmamap is used per
203116491Sharti * page.
204116491Sharti *
205116491Sharti * The handle we give to the card for the small buffers is a word combined
206116491Sharti * of the page number and the number of the chunk in the page. This restricts
207116491Sharti * the number of chunks per page to 256 (8 bit) and the number of pages to
208116491Sharti * 65536 (16 bits).
209116491Sharti *
210116491Sharti * A chunk may be in one of three states: free, on the card and floating around
211116491Sharti * in the system. If it is free, it is on one of the two free lists and
212116491Sharti * start with a struct mbufx_free. Each page has a bitmap that tracks where
213116491Sharti * its chunks are.
214116491Sharti *
215116491Sharti * For large buffers we use mbuf clusters. Here we have two problems: we need
216116491Sharti * to track the buffers on the card (in the case we want to stop it) and
217116491Sharti * we need to map the 64bit mbuf address to a 26bit handle for 64-bit machines.
218116491Sharti * The card uses the buffers in the order we give it to the card. Therefor
219116491Sharti * we can use a private array holding pointers to the mbufs as a circular
220116491Sharti * queue for both tasks. This is done with the lbufs member of softc. The
221116491Sharti * handle for these buffer is the lbufs index ored with a flag.
222116491Sharti */
223121680Sharti
224121680Sharti/* data space in each external mbuf */
225116491Sharti#define MBUF0_SIZE	(5 * 48)	/* 240 */
226121680Sharti#define MBUF1_SIZE	(52)		/* 1 raw cell */
227116491Sharti
228121680Sharti/* size of the buffer. Must fit data, offset and header */
229116491Sharti#define MBUF0_CHUNK	256		/* 16 free bytes */
230116491Sharti#define MBUF1_CHUNK	96		/* 44 free bytes */
231121680Sharti
232121680Sharti/* start of actual data in buffer */
233116491Sharti#define MBUF0_OFFSET	0
234121680Sharti#define MBUF1_OFFSET	16
235121680Sharti
236116491Sharti#define MBUFL_OFFSET	16		/* two pointers for HARP */
237116491Sharti
238116491Sharti#define MBUF_ALLOC_SIZE	(PAGE_SIZE)
239116491Sharti
240116491Sharti/* each allocated page has one of these structures at its very end. */
241116491Shartistruct mbuf_page_hdr {
242116491Sharti	uint16_t	nchunks;	/* chunks on this page */
243116491Sharti	bus_dmamap_t	map;		/* the DMA MAP */
244116491Sharti	uint32_t	phys;		/* physical base address */
245116491Sharti	uint32_t	hdroff;		/* chunk header offset */
246116491Sharti	uint32_t	chunksize;	/* chunk size */
247121729Sharti	u_int		pool;		/* pool number */
248116491Sharti};
249116491Shartistruct mbuf_page {
250116491Sharti	char	storage[MBUF_ALLOC_SIZE - sizeof(struct mbuf_page_hdr)];
251116491Sharti	struct mbuf_page_hdr	hdr;
252116491Sharti};
253116491Sharti
254116491Sharti/* numbers per page */
255116491Sharti#define MBUF0_PER_PAGE	((MBUF_ALLOC_SIZE - sizeof(struct mbuf_page_hdr)) / \
256116491Sharti    MBUF0_CHUNK)
257116491Sharti#define MBUF1_PER_PAGE	((MBUF_ALLOC_SIZE - sizeof(struct mbuf_page_hdr)) / \
258116491Sharti    MBUF1_CHUNK)
259116491Sharti
260121680Sharti/*
261121680Sharti * Convert to/from handles
262121680Sharti */
263121680Sharti/* small buffers */
264116491Sharti#define MBUF_MAKE_HANDLE(PAGENO, CHUNKNO) \
265121680Sharti	((((PAGENO) << 10) | (CHUNKNO)) << HE_REGS_RBRQ_ADDR)
266121680Sharti#define	MBUF_MAKE_LHANDLE(INDEX) \
267121680Sharti	(MBUF_LARGE_FLAG | ((INDEX) << HE_REGS_RBRQ_ADDR))
268116491Sharti
269121680Sharti/* large buffers */
270121680Sharti#define MBUF_PARSE_HANDLE(HANDLE, PAGENO, CHUNKNO) do {			\
271121680Sharti	(CHUNKNO) = ((HANDLE) >> HE_REGS_RBRQ_ADDR) & 0x3ff;		\
272121680Sharti	(PAGENO) = (((HANDLE) >> 10) >> HE_REGS_RBRQ_ADDR) & 0x3fff;	\
273116491Sharti    } while (0)
274121680Sharti#define	MBUF_PARSE_LHANDLE(HANDLE, INDEX) do {				\
275121680Sharti	(INDEX) = ((HANDLE) >> HE_REGS_RBRQ_ADDR) & 0xffffff;		\
276121680Sharti    } while (0)
277116491Sharti
278121680Sharti#define MBUF_LARGE_FLAG	0x80000000
279116491Sharti
280121729Sharti/* chunks have the following structure at the end (8 byte) */
281116491Shartistruct mbuf_chunk_hdr {
282121729Sharti	uint16_t	pageno;
283121729Sharti	uint8_t		chunkno;
284121729Sharti	uint8_t		flags;
285121729Sharti	u_int		ref_cnt;
286116491Sharti};
287121729Sharti#define	MBUF_CARD	0x01	/* buffer is on card */
288121729Sharti#define	MBUF_USED	0x02	/* buffer is somewhere in the system */
289116491Sharti
290116491Sharti#define MBUFX_STORAGE_SIZE(X) (MBUF##X##_CHUNK	\
291116491Sharti    - sizeof(struct mbuf_chunk_hdr))
292116491Sharti
293116491Shartistruct mbuf0_chunk {
294116491Sharti	char			storage[MBUFX_STORAGE_SIZE(0)];
295116491Sharti	struct mbuf_chunk_hdr	hdr;
296116491Sharti};
297116491Sharti
298116491Shartistruct mbuf1_chunk {
299116491Sharti	char			storage[MBUFX_STORAGE_SIZE(1)];
300116491Sharti	struct mbuf_chunk_hdr	hdr;
301116491Sharti};
302116491Sharti
303116491Shartistruct mbufx_free {
304121675Sharti	struct mbufx_free	*link;
305116491Sharti};
306116491Sharti
307116491Sharti/*==================================================================*/
308116491Sharti
309116491Sharti/*
310116491Sharti * Interrupt queue
311116491Sharti */
312116491Shartistruct heirq {
313116491Sharti	u_int		size;	/* number of entries */
314116491Sharti	u_int		thresh;	/* re-interrupt threshold */
315116491Sharti	u_int		line;	/* interrupt line to use */
316116491Sharti	struct dmamem	mem;	/* interrupt queues */
317116491Sharti	uint32_t *	irq;	/* interrupt queue */
318116491Sharti	uint32_t 	head;	/* head index */
319116491Sharti	uint32_t *	tailp;	/* pointer to tail */
320116491Sharti	struct hatm_softc *sc;	/* back pointer */
321116491Sharti	u_int		group;	/* interrupt group */
322116491Sharti};
323116491Sharti
324116491Sharti/*
325116491Sharti * This structure describes all information for a VCC open on the card.
326116491Sharti * The array of these structures is indexed by the compressed connection ID
327118205Sharti * (CID). This structure must begin with the atmio_vcc.
328116491Sharti */
329116491Shartistruct hevcc {
330118205Sharti	struct atmio_vcc param;		/* traffic parameters */
331118205Sharti	void *		rxhand;		/* NATM protocol block */
332116491Sharti	u_int		vflags;		/* private flags */
333118205Sharti	uint32_t	ipackets;
334118205Sharti	uint32_t	opackets;
335118205Sharti	uint32_t	ibytes;
336118205Sharti	uint32_t	obytes;
337118205Sharti
338116491Sharti	u_int		rc;		/* rate control group for CBR */
339116491Sharti	struct mbuf *	chain;		/* partial received PDU */
340116491Sharti	struct mbuf *	last;		/* last mbuf in chain */
341116491Sharti	u_int		ntpds;		/* number of active TPDs */
342116491Sharti};
343116491Sharti#define HE_VCC_OPEN		0x000f0000
344116491Sharti#define HE_VCC_RX_OPEN		0x00010000
345116491Sharti#define HE_VCC_RX_CLOSING	0x00020000
346116491Sharti#define HE_VCC_TX_OPEN		0x00040000
347116491Sharti#define HE_VCC_TX_CLOSING	0x00080000
348116491Sharti#define HE_VCC_FLOW_CTRL	0x00100000
349116491Sharti
350116491Sharti/*
351116491Sharti * CBR rate groups
352116491Sharti */
353116491Shartistruct herg {
354116491Sharti	u_int	refcnt;		/* how many connections reference this group */
355116491Sharti	u_int	rate;		/* the value */
356116491Sharti};
357116491Sharti
358116491Sharti/*
359116491Sharti * Softc
360116491Sharti */
361116491Shartistruct hatm_softc {
362116491Sharti	struct ifatm		ifatm;		/* common ATM stuff */
363116491Sharti	struct mtx		mtx;		/* lock */
364116491Sharti	struct ifmedia		media;		/* media */
365116491Sharti	device_t		dev;		/* device */
366116491Sharti	int			memid;		/* resoure id for memory */
367116491Sharti	struct resource *	memres;		/* memory resource */
368116491Sharti	bus_space_handle_t	memh;		/* handle */
369116491Sharti	bus_space_tag_t		memt;		/* ... and tag */
370116491Sharti	bus_dma_tag_t		parent_tag;	/* global restriction */
371116491Sharti	struct cv		vcc_cv;		/* condition variable */
372116491Sharti	int			irqid;		/* resource id */
373116491Sharti	struct resource *	irqres;		/* resource */
374116491Sharti	void *			ih;		/* interrupt handle */
375116491Sharti	struct utopia		utopia;		/* utopia state */
376116491Sharti
377116491Sharti	/* rest has to be reset by stop */
378116491Sharti	int			he622;		/* this is a HE622 */
379116491Sharti	int			pci64;		/* 64bit bus */
380116491Sharti	char			prod_id[HE_EEPROM_PROD_ID_LEN + 1];
381116491Sharti	char			rev[HE_EEPROM_REV_LEN + 1];
382116491Sharti	struct heirq		irq_0;		/* interrupt queues 0 */
383116491Sharti
384116491Sharti	/* generic network controller state */
385116491Sharti	u_int			cells_per_row;
386116491Sharti	u_int			bytes_per_row;
387116491Sharti	u_int			r0_numrows;
388116491Sharti	u_int			tx_numrows;
389116491Sharti	u_int			r1_numrows;
390116491Sharti	u_int			r0_startrow;
391116491Sharti	u_int			tx_startrow;
392116491Sharti	u_int			r1_startrow;
393116491Sharti	u_int			cells_per_lbuf;
394116491Sharti	u_int			r0_numbuffs;
395116491Sharti	u_int			r1_numbuffs;
396116491Sharti	u_int			tx_numbuffs;
397116491Sharti
398116491Sharti	/* HSP */
399116491Sharti	struct he_hsp		*hsp;
400116491Sharti	struct dmamem		hsp_mem;
401116491Sharti
402116491Sharti	/*** TX ***/
403116491Sharti	struct hetbrq		tbrq;		/* TBRQ 0 */
404116491Sharti	struct hetpdrq		tpdrq;		/* TPDRQ */
405116491Sharti	struct tpd_list		tpd_free;	/* Free TPDs */
406116491Sharti	u_int			tpd_nfree;	/* number of free TPDs */
407116491Sharti	u_int			tpd_total;	/* total TPDs */
408116491Sharti	uint8_t			*tpd_used;	/* bitmap of used TPDs */
409116491Sharti	struct dmamem		tpds;		/* TPD memory */
410116491Sharti	bus_dma_tag_t		tx_tag;		/* DMA tag for all tx mbufs */
411116491Sharti
412116491Sharti	/*** RX ***/
413116491Sharti	/* receive/transmit groups */
414116491Sharti	struct herbp		rbp_s0;		/* RBPS0 */
415116491Sharti	struct herbp		rbp_l0;		/* RBPL0 */
416116491Sharti	struct herbp		rbp_s1;		/* RBPS1 */
417116491Sharti	struct herbrq		rbrq_0;		/* RBRQ0 */
418116491Sharti	struct herbrq		rbrq_1;		/* RBRQ1 */
419116491Sharti
420116491Sharti	/* list of external mbuf storage */
421116491Sharti	bus_dma_tag_t		mbuf_tag;
422116491Sharti	struct mbuf_page	**mbuf_pages;
423116491Sharti	u_int			mbuf_npages;
424121685Sharti	u_int			mbuf_max_pages;
425121675Sharti	struct mbufx_free	*mbuf_list[2];
426116491Sharti
427116491Sharti	/* mbuf cluster tracking and mapping for group 0 */
428116491Sharti	struct mbuf		**lbufs;	/* mbufs */
429116491Sharti	bus_dmamap_t		*rmaps;		/* DMA maps */
430116491Sharti	u_int			lbufs_size;
431116491Sharti	u_int			lbufs_next;
432116491Sharti
433116491Sharti	/* VCCs */
434116491Sharti	struct hevcc		*vccs[HE_MAX_VCCS];
435116491Sharti	u_int			cbr_bw;		/* BW allocated to CBR */
436116491Sharti	u_int			max_tpd;	/* per VCC */
437116491Sharti	u_int			open_vccs;
438116491Sharti	uma_zone_t		vcc_zone;
439116491Sharti
440116491Sharti	/* rate groups */
441116491Sharti	struct herg		rate_ctrl[HE_REGN_CS_STPER];
442116491Sharti
443116491Sharti	/* memory offsets */
444116491Sharti	u_int			tsrb, tsrc, tsrd;
445116491Sharti	u_int			rsrb;
446116491Sharti
447116491Sharti	struct cv		cv_rcclose;	/* condition variable */
448116491Sharti	uint32_t		rate_grid[16][16]; /* our copy */
449116491Sharti
450116491Sharti	/* sysctl support */
451116491Sharti	struct sysctl_ctx_list	sysctl_ctx;
452116491Sharti	struct sysctl_oid	*sysctl_tree;
453116491Sharti
454116491Sharti	/* internal statistics */
455116491Sharti	struct istats		istats;
456116491Sharti
457116491Sharti#ifdef HATM_DEBUG
458116491Sharti	/* debugging */
459116491Sharti	u_int			debug;
460116491Sharti#endif
461116491Sharti};
462116491Sharti
463116491Sharti#define READ4(SC,OFF)	bus_space_read_4(SC->memt, SC->memh, (OFF))
464116491Sharti#define READ2(SC,OFF)	bus_space_read_2(SC->memt, SC->memh, (OFF))
465116491Sharti#define READ1(SC,OFF)	bus_space_read_1(SC->memt, SC->memh, (OFF))
466116491Sharti
467116491Sharti#define WRITE4(SC,OFF,VAL) bus_space_write_4(SC->memt, SC->memh, (OFF), (VAL))
468116491Sharti#define WRITE2(SC,OFF,VAL) bus_space_write_2(SC->memt, SC->memh, (OFF), (VAL))
469116491Sharti#define WRITE1(SC,OFF,VAL) bus_space_write_1(SC->memt, SC->memh, (OFF), (VAL))
470116491Sharti
471116491Sharti#define BARRIER_R(SC) bus_space_barrier(SC->memt, SC->memh, 0, HE_REGO_END, \
472116491Sharti	BUS_SPACE_BARRIER_READ)
473116491Sharti#define BARRIER_W(SC) bus_space_barrier(SC->memt, SC->memh, 0, HE_REGO_END, \
474116491Sharti	BUS_SPACE_BARRIER_WRITE)
475116491Sharti#define BARRIER_RW(SC) bus_space_barrier(SC->memt, SC->memh, 0, HE_REGO_END, \
476116491Sharti	BUS_SPACE_BARRIER_READ | BUS_SPACE_BARRIER_WRITE)
477116491Sharti
478116491Sharti#define READ_SUNI(SC,OFF) READ4(SC, HE_REGO_SUNI + 4 * (OFF))
479116491Sharti#define WRITE_SUNI(SC,OFF,VAL) WRITE4(SC, HE_REGO_SUNI + 4 * (OFF), (VAL))
480116491Sharti
481116491Sharti#define READ_LB4(SC,OFF)						\
482116491Sharti    ({									\
483116491Sharti	WRITE4(SC, HE_REGO_LB_MEM_ADDR, (OFF));				\
484116491Sharti	WRITE4(SC, HE_REGO_LB_MEM_ACCESS,				\
485116491Sharti	    (HE_REGM_LB_MEM_HNDSHK | HE_REGM_LB_MEM_READ));		\
486116491Sharti	while((READ4(SC, HE_REGO_LB_MEM_ACCESS) & HE_REGM_LB_MEM_HNDSHK))\
487116491Sharti		;							\
488116491Sharti	READ4(SC, HE_REGO_LB_MEM_DATA);					\
489116491Sharti    })
490116491Sharti#define WRITE_LB4(SC,OFF,VAL)						\
491116491Sharti    do {								\
492116491Sharti	WRITE4(SC, HE_REGO_LB_MEM_ADDR, (OFF));				\
493116491Sharti	WRITE4(SC, HE_REGO_LB_MEM_DATA, (VAL));				\
494116491Sharti	WRITE4(SC, HE_REGO_LB_MEM_ACCESS,				\
495116491Sharti	    (HE_REGM_LB_MEM_HNDSHK | HE_REGM_LB_MEM_WRITE));		\
496116491Sharti	while((READ4(SC, HE_REGO_LB_MEM_ACCESS) & HE_REGM_LB_MEM_HNDSHK))\
497116491Sharti		;							\
498116491Sharti    } while(0)
499116491Sharti
500116491Sharti#define WRITE_MEM4(SC,OFF,VAL,SPACE)					\
501116491Sharti    do {								\
502116491Sharti	WRITE4(SC, HE_REGO_CON_DAT, (VAL));				\
503116491Sharti	WRITE4(SC, HE_REGO_CON_CTL,					\
504116491Sharti	    (SPACE | HE_REGM_CON_WE | HE_REGM_CON_STATUS | (OFF)));	\
505116491Sharti	while((READ4(SC, HE_REGO_CON_CTL) & HE_REGM_CON_STATUS) != 0)	\
506116491Sharti		;							\
507116491Sharti    } while(0)
508116491Sharti
509116491Sharti#define READ_MEM4(SC,OFF,SPACE)					\
510116491Sharti    ({									\
511116491Sharti	WRITE4(SC, HE_REGO_CON_CTL,					\
512116491Sharti	    (SPACE | HE_REGM_CON_STATUS | (OFF)));			\
513116491Sharti	while((READ4(SC, HE_REGO_CON_CTL) & HE_REGM_CON_STATUS) != 0)	\
514116491Sharti		;							\
515116491Sharti	READ4(SC, HE_REGO_CON_DAT);					\
516116491Sharti    })
517116491Sharti
518116491Sharti#define WRITE_TCM4(SC,OFF,VAL) WRITE_MEM4(SC,(OFF),(VAL),HE_REGM_CON_TCM)
519116491Sharti#define WRITE_RCM4(SC,OFF,VAL) WRITE_MEM4(SC,(OFF),(VAL),HE_REGM_CON_RCM)
520116491Sharti#define WRITE_MBOX4(SC,OFF,VAL) WRITE_MEM4(SC,(OFF),(VAL),HE_REGM_CON_MBOX)
521116491Sharti
522116491Sharti#define READ_TCM4(SC,OFF) READ_MEM4(SC,(OFF),HE_REGM_CON_TCM)
523116491Sharti#define READ_RCM4(SC,OFF) READ_MEM4(SC,(OFF),HE_REGM_CON_RCM)
524116491Sharti#define READ_MBOX4(SC,OFF) READ_MEM4(SC,(OFF),HE_REGM_CON_MBOX)
525116491Sharti
526116491Sharti#define WRITE_TCM(SC,OFF,BYTES,VAL) 					\
527116491Sharti	WRITE_MEM4(SC,(OFF) | ((~(BYTES) & 0xf) << HE_REGS_CON_DIS),	\
528116491Sharti	    (VAL), HE_REGM_CON_TCM)
529116491Sharti#define WRITE_RCM(SC,OFF,BYTES,VAL) 					\
530116491Sharti	WRITE_MEM4(SC,(OFF) | ((~(BYTES) & 0xf) << HE_REGS_CON_DIS),	\
531116491Sharti	    (VAL), HE_REGM_CON_RCM)
532116491Sharti
533116491Sharti#define READ_TSR(SC,CID,NR)						\
534116491Sharti    ({									\
535116491Sharti	uint32_t _v;							\
536116491Sharti	if((NR) <= 7) {							\
537116491Sharti		_v = READ_TCM4(SC, HE_REGO_TSRA(0,CID,NR));		\
538116491Sharti	} else if((NR) <= 11) {						\
539116491Sharti		_v = READ_TCM4(SC, HE_REGO_TSRB((SC)->tsrb,CID,(NR-8)));\
540116491Sharti	} else if((NR) <= 13) {						\
541116491Sharti		_v = READ_TCM4(SC, HE_REGO_TSRC((SC)->tsrc,CID,(NR-12)));\
542116491Sharti	} else {							\
543116491Sharti		_v = READ_TCM4(SC, HE_REGO_TSRD((SC)->tsrd,CID));	\
544116491Sharti	}								\
545116491Sharti	_v;								\
546116491Sharti    })
547116491Sharti
548116491Sharti#define WRITE_TSR(SC,CID,NR,BEN,VAL)					\
549116491Sharti    do {								\
550116491Sharti	if((NR) <= 7) {							\
551116491Sharti		WRITE_TCM(SC, HE_REGO_TSRA(0,CID,NR),BEN,VAL);		\
552116491Sharti	} else if((NR) <= 11) {						\
553116491Sharti		WRITE_TCM(SC, HE_REGO_TSRB((SC)->tsrb,CID,(NR-8)),BEN,VAL);\
554116491Sharti	} else if((NR) <= 13) {						\
555116491Sharti		WRITE_TCM(SC, HE_REGO_TSRC((SC)->tsrc,CID,(NR-12)),BEN,VAL);\
556116491Sharti	} else {							\
557116491Sharti		WRITE_TCM(SC, HE_REGO_TSRD((SC)->tsrd,CID),BEN,VAL);	\
558116491Sharti	}								\
559116491Sharti    } while(0)
560116491Sharti
561116491Sharti#define READ_RSR(SC,CID,NR)						\
562116491Sharti    ({									\
563116491Sharti	uint32_t _v;							\
564116491Sharti	if((NR) <= 7) {							\
565116491Sharti		_v = READ_RCM4(SC, HE_REGO_RSRA(0,CID,NR));		\
566116491Sharti	} else {							\
567116491Sharti		_v = READ_RCM4(SC, HE_REGO_RSRB((SC)->rsrb,CID,(NR-8)));\
568116491Sharti	}								\
569116491Sharti	_v;								\
570116491Sharti    })
571116491Sharti
572116491Sharti#define WRITE_RSR(SC,CID,NR,BEN,VAL)					\
573116491Sharti    do {								\
574116491Sharti	if((NR) <= 7) {							\
575116491Sharti		WRITE_RCM(SC, HE_REGO_RSRA(0,CID,NR),BEN,VAL);		\
576116491Sharti	} else {							\
577116491Sharti		WRITE_RCM(SC, HE_REGO_RSRB((SC)->rsrb,CID,(NR-8)),BEN,VAL);\
578116491Sharti	}								\
579116491Sharti    } while(0)
580116491Sharti
581116491Sharti#ifdef HATM_DEBUG
582116491Sharti#define DBG(SC, FL, PRINT) do {						\
583116491Sharti	if((SC)->debug & DBG_##FL) { 					\
584116491Sharti		if_printf(&(SC)->ifatm.ifnet, "%s: ", __func__);	\
585116491Sharti		printf PRINT;						\
586116491Sharti		printf("\n");						\
587116491Sharti	}								\
588116491Sharti    } while (0)
589116491Sharti
590116491Shartienum {
591121681Sharti	DBG_DUMMY	= 0x0001,	/* default value for -DHATM_DEBUG */
592121681Sharti	DBG_RX		= 0x0002,
593121681Sharti	DBG_TX		= 0x0004,
594121681Sharti	DBG_VCC		= 0x0008,
595121681Sharti	DBG_IOCTL	= 0x0010,
596121681Sharti	DBG_ATTACH	= 0x0020,
597121681Sharti	DBG_INTR	= 0x0040,
598121681Sharti	DBG_DMA		= 0x0080,
599121681Sharti	DBG_DMAH	= 0x0100,
600121681Sharti	DBG_DUMP	= 0x0200,
601116491Sharti
602121681Sharti	DBG_ALL		= 0x03ff
603116491Sharti};
604116491Sharti
605116491Sharti#else
606116491Sharti#define DBG(SC, FL, PRINT)
607116491Sharti#endif
608116491Sharti
609116491Shartiu_int hatm_cps2atmf(uint32_t);
610116491Shartiu_int hatm_atmf2cps(uint32_t);
611116491Sharti
612116491Shartivoid hatm_intr(void *);
613116491Shartiint hatm_ioctl(struct ifnet *, u_long, caddr_t);
614116491Shartivoid hatm_initialize(struct hatm_softc *);
615116491Shartivoid hatm_stop(struct hatm_softc *sc);
616116491Shartivoid hatm_start(struct ifnet *);
617116491Sharti
618116491Shartivoid hatm_rx(struct hatm_softc *sc, u_int cid, u_int flags, struct mbuf *m,
619116491Sharti    u_int len);
620116491Shartivoid hatm_tx_complete(struct hatm_softc *sc, struct tpd *tpd, uint32_t);
621116491Sharti
622116491Shartiint hatm_tx_vcc_can_open(struct hatm_softc *sc, u_int cid, struct hevcc *);
623116491Shartivoid hatm_tx_vcc_open(struct hatm_softc *sc, u_int cid);
624116491Shartivoid hatm_rx_vcc_open(struct hatm_softc *sc, u_int cid);
625116491Shartivoid hatm_tx_vcc_close(struct hatm_softc *sc, u_int cid);
626116491Shartivoid hatm_rx_vcc_close(struct hatm_softc *sc, u_int cid);
627116491Shartivoid hatm_tx_vcc_closed(struct hatm_softc *sc, u_int cid);
628116491Shartivoid hatm_vcc_closed(struct hatm_softc *sc, u_int cid);
629118598Shartivoid hatm_load_vc(struct hatm_softc *sc, u_int cid, int reopen);
630121729Sharti
631121729Shartivoid hatm_ext_free(struct mbufx_free **, struct mbufx_free *);
632