1139749Simp/*-
2117632Sharti * Copyright (c) 2003
3117632Sharti *	Fraunhofer Institute for Open Communication Systems (FhG Fokus).
4117632Sharti * 	All rights reserved.
5117632Sharti *
6117632Sharti * Redistribution and use in source and binary forms, with or without
7117632Sharti * modification, are permitted provided that the following conditions
8117632Sharti * are met:
9117632Sharti * 1. Redistributions of source code must retain the above copyright
10117632Sharti *    notice, this list of conditions and the following disclaimer.
11117632Sharti * 2. Redistributions in binary form must reproduce the above copyright
12117632Sharti *    notice, this list of conditions and the following disclaimer in the
13117632Sharti *    documentation and/or other materials provided with the distribution.
14117632Sharti *
15117632Sharti * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16117632Sharti * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17117632Sharti * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18117632Sharti * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19117632Sharti * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20117632Sharti * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21117632Sharti * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22117632Sharti * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23117632Sharti * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24117632Sharti * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25117632Sharti * SUCH DAMAGE.
26117632Sharti *
27117632Sharti * Author: Hartmut Brandt <harti@freebsd.org>
28117632Sharti *
29117632Sharti * $FreeBSD$
30117632Sharti *
31117632Sharti * Driver for IDT77252 (ABR) based cards like ProSum's.
32117632Sharti */
33117632Sharti
34117632Sharti/* legal values are 0, 1, 2 and 8 */
35117632Sharti#define	PATM_VPI_BITS	2
36117632Sharti#define	PATM_CFG_VPI	IDT_CFG_VP2
37117632Sharti
38117632Sharti/* receive status queue size */
39117632Sharti#define	PATM_RSQ_SIZE		512
40117632Sharti#define	PATM_CFQ_RSQ_SIZE	IDT_CFG_RXQ512
41117632Sharti
42117632Sharti/* alignment for SQ memory */
43117632Sharti#define	PATM_SQ_ALIGNMENT	8192
44117632Sharti
45117632Sharti#define	PATM_PROATM_NAME_OFFSET	060
46117632Sharti#define	PATM_PROATM_NAME	"PROATM"
47117632Sharti#define	PATM_PROATM_MAC_OFFSET	044
48117632Sharti#define	PATM_IDT_MAC_OFFSET	0154
49117632Sharti
50117632Sharti/* maximum number of packets on UBR queue */
51117632Sharti#define	PATM_DLFT_MAXQ		1000
52117632Sharti
53117632Sharti/* maximum number of packets on other queues. This should depend on the
54117632Sharti * traffic contract. */
55117632Sharti#define	PATM_TX_IFQLEN		100
56117632Sharti
57117632Sharti/*
58117632Sharti * Maximum number of DMA maps we allocate. This is the minimum that can be
59117632Sharti * set larger via a sysctl.
60117632Sharti * Starting number of DMA maps.
61117632Sharti * Step for growing.
62117632Sharti */
63117632Sharti#define	PATM_CFG_TXMAPS_MAX	1024
64117632Sharti#define	PATM_CFG_TXMAPS_INIT	128
65117632Sharti#define	PATM_CFG_TXMAPS_STEP	128
66117632Sharti
67117632Sharti/* percents of TST slots to keep for non-CBR traffic */
68117632Sharti#define	PATM_TST_RESERVE	2
69117632Sharti
70117632Sharti/*
71117632Sharti * Structure to hold TX DMA maps
72117632Sharti */
73117632Shartistruct patm_txmap {
74117632Sharti	SLIST_ENTRY(patm_txmap) link;
75117632Sharti	bus_dmamap_t	map;
76117632Sharti};
77117632Sharti
78117632Sharti/*
79117632Sharti * Receive buffers.
80117632Sharti *
81117632Sharti * We manage our own external mbufs for small receive buffers for two reasons:
82117632Sharti * the card may consume a rather large number of buffers. Mapping each buffer
83117632Sharti * would consume a lot of iospace on sparc64. Also the card allows us to set
84117632Sharti * a 32-bit handle for identification of the buffers. On a 64-bit system this
85117632Sharti * requires us to use a mapping between buffers and handles.
86117632Sharti *
87117632Sharti * For large buffers we use mbuf clusters directly. We track these by using
88117632Sharti * an array of pointers (lbufs) to special structs and a free list of these
89117632Sharti * structs.
90117632Sharti *
91117632Sharti * For AAL0 cell we use FBQ2 and make the 1 cell long.
92117632Sharti */
93117632Sharti/*
94117632Sharti * Define the small buffer chunk so that we have at least 16 byte free
95117632Sharti * at the end of the chunk and that there is an integral number of chunks
96117632Sharti * in a page.
97117632Sharti */
98117632Sharti#define	SMBUF_PAGE_SIZE		16384	/* 16k pages */
99117632Sharti#define	SMBUF_MAX_PAGES		64	/* maximum number of pages */
100117632Sharti#define	SMBUF_CHUNK_SIZE	256	/* 256 bytes per chunk */
101117632Sharti#define	SMBUF_CELLS		5
102117632Sharti#define	SMBUF_SIZE		(SMBUF_CELLS * 48)
103117632Sharti#define	SMBUF_THRESHOLD		9	/* 9/16 of queue size */
104117632Sharti#define	SMBUF_NI_THRESH		3
105117632Sharti#define	SMBUF_CI_THRESH		1
106117632Sharti
107117632Sharti#define	VMBUF_PAGE_SIZE		16384	/* 16k pages */
108117632Sharti#define	VMBUF_MAX_PAGES		16	/* maximum number of pages */
109117632Sharti#define	VMBUF_CHUNK_SIZE	64	/* 64 bytes per chunk */
110117632Sharti#define	VMBUF_CELLS		1
111117632Sharti#define	VMBUF_SIZE		(VMBUF_CELLS * 48)
112117632Sharti#define	VMBUF_THRESHOLD		15	/* 15/16 of size */
113117632Sharti
114117632Sharti#define	SMBUF_OFFSET	(SMBUF_CHUNK_SIZE - 8 - SMBUF_SIZE)
115117632Sharti#define	VMBUF_OFFSET	0
116117632Sharti
117117632Sharti#define	MBUF_SHANDLE	0x00000000
118117632Sharti#define	MBUF_LHANDLE	0x80000000
119117632Sharti#define	MBUF_VHANDLE	0x40000000
120117632Sharti#define	MBUF_HMASK	0x3fffffff
121117632Sharti
122117632Sharti/*
123117632Sharti * Large buffers
124117632Sharti *
125117632Sharti * The problem with these is the maximum count. When the card assembles
126117632Sharti * a AAL5 pdu it moves a buffer from the FBQ to the VC. This frees space
127117632Sharti * in the FBQ, put the buffer may pend on the card for an unlimited amount
128117632Sharti * of time (we don't idle connections). This means that the upper limit
129117632Sharti * on buffers on the card may be (no-of-open-vcs + FBQ_SIZE). Because
130117632Sharti * this is far too much, make this a tuneable. We could also make
131117632Sharti * this dynamic by allocating pages of several lbufs at once during run time.
132117632Sharti */
133117632Sharti#define	LMBUF_MAX		(IDT_FBQ_SIZE * 2)
134117632Sharti#define	LMBUF_CELLS		(MCLBYTES / 48)	/* 42 cells = 2048 byte */
135117632Sharti#define	LMBUF_SIZE		(LMBUF_CELLS * 48)
136117632Sharti#define	LMBUF_THRESHOLD		9	/* 9/16 of queue size */
137117632Sharti#define	LMBUF_OFFSET		(MCLBYTES - LMBUF_SIZE)
138117632Sharti#define	LMBUF_NI_THRESH		3
139117632Sharti#define	LMBUF_CI_THRESH		1
140117632Sharti
141117632Sharti#define	LMBUF_HANDLE		0x80000000
142117632Sharti
143117632Shartistruct lmbuf {
144117632Sharti	SLIST_ENTRY(lmbuf)	link;	/* free list link */
145117632Sharti	bus_dmamap_t		map;	/* DMA map */
146117632Sharti	u_int			handle;	/* this is the handle index */
147117632Sharti	struct mbuf		*m;	/* the current mbuf */
148117632Sharti	bus_addr_t		phy;	/* phy addr */
149117632Sharti};
150117632Sharti
151117632Sharti#define	PATM_CID(SC, VPI, VCI)	\
152147256Sbrooks    (((VPI) << IFP2IFATM((SC)->ifp)->mib.vci_bits) | (VCI))
153117632Sharti
154117632Sharti/*
155117632Sharti * Internal driver statistics
156117632Sharti */
157117632Shartistruct patm_stats {
158117632Sharti	uint32_t	raw_cells;
159117632Sharti	uint32_t	raw_no_vcc;
160117632Sharti	uint32_t	raw_no_buf;
161117632Sharti	uint32_t	tx_qfull;
162117632Sharti	uint32_t	tx_out_of_tbds;
163117632Sharti	uint32_t	tx_out_of_maps;
164117632Sharti	uint32_t	tx_load_err;
165117632Sharti};
166117632Sharti
167117632Sharti/*
168117632Sharti * These are allocated as DMA able memory
169117632Sharti */
170117632Shartistruct patm_scd {
171117632Sharti	struct idt_tbd	scq[IDT_SCQ_SIZE];
172117632Sharti	LIST_ENTRY(patm_scd) link;	/* all active SCDs */
173117632Sharti	uint32_t	sram;		/* SRAM address */
174117632Sharti	bus_addr_t	phy;		/* physical address */
175117632Sharti	bus_dmamap_t	map;		/* DMA map */
176117632Sharti	u_int		tail;		/* next free entry for host */
177117632Sharti	int		space;		/* number of free entries (minus one) */
178117632Sharti	u_int		slots;		/* CBR slots allocated */
179117632Sharti	uint8_t		tag;		/* next tag for TSI */
180117632Sharti	uint8_t		last_tag;	/* last tag checked in interrupt */
181117632Sharti	uint8_t		num_on_card;	/* number of PDUs on tx queue */
182117632Sharti	uint8_t		lacr;		/* LogACR value */
183117632Sharti	uint8_t		init_er;	/* LogER value */
184117632Sharti	struct ifqueue	q;		/* queue of packets */
185117632Sharti	struct mbuf	*on_card[IDT_TSQE_TAG_SPACE];
186117632Sharti};
187117632Sharti
188117632Sharti/*
189117632Sharti * Per-VCC data
190117632Sharti */
191117632Shartistruct patm_vcc {
192117632Sharti	struct atmio_vcc vcc;		/* caller's parameters */
193117632Sharti	void		*rxhand;	/* NATM handle */
194117632Sharti	u_int		vflags;		/* open and other flags */
195117632Sharti	uint32_t	ipackets;	/* packets received */
196117632Sharti	uint32_t	opackets;	/* packets sent */
197117632Sharti	uint64_t	ibytes;		/* bytes received */
198117632Sharti	uint64_t	obytes;		/* bytes sent */
199118601Sharti
200117632Sharti	struct mbuf	*chain;		/* currently received chain */
201117632Sharti	struct mbuf	*last;		/* end of chain */
202117632Sharti	u_int		cid;		/* index */
203117632Sharti	u_int		cps;		/* last ABR cps */
204117632Sharti	struct patm_scd	*scd;
205117632Sharti};
206117632Sharti#define	PATM_VCC_TX_OPEN	0x0001
207117632Sharti#define	PATM_VCC_RX_OPEN	0x0002
208117632Sharti#define	PATM_VCC_TX_CLOSING	0x0004
209117632Sharti#define	PATM_VCC_RX_CLOSING	0x0008
210117632Sharti#define	PATM_VCC_OPEN		0x000f	/* all the above */
211117632Sharti
212117632Sharti#define	PATM_RAW_CELL		0x0000	/* 53 byte cells */
213117632Sharti#define	PATM_RAW_NOHEC		0x0100	/* 52 byte cells */
214117632Sharti#define	PATM_RAW_CS		0x0200	/* 64 byte cell stream */
215117632Sharti#define	PATM_RAW_FORMAT		0x0300	/* format mask */
216117632Sharti
217117632Sharti/*
218117632Sharti * Per adapter data
219117632Sharti */
220117632Shartistruct patm_softc {
221147256Sbrooks	struct ifnet		*ifp;		/* common ATM stuff */
222117632Sharti	struct mtx		mtx;		/* lock */
223117632Sharti	struct ifmedia		media;		/* media */
224117632Sharti	device_t		dev;		/* device */
225117632Sharti	struct resource *	memres;		/* memory resource */
226117632Sharti	bus_space_handle_t	memh;		/* handle */
227117632Sharti	bus_space_tag_t		memt;		/* ... and tag */
228117632Sharti	int			irqid;		/* resource id */
229117632Sharti	struct resource *	irqres;		/* resource */
230117632Sharti	void *			ih;		/* interrupt handle */
231117632Sharti	struct utopia		utopia;		/* phy state */
232117632Sharti	const struct idt_mmap	*mmap;		/* SRAM memory map */
233117632Sharti	u_int			flags;		/* see below */
234117632Sharti	u_int			revision;	/* chip revision */
235117632Sharti
236117632Sharti	/* DMAable status queue memory */
237117632Sharti	size_t			sq_size;	/* size of memory area */
238117632Sharti	bus_dma_tag_t		sq_tag;		/* DMA tag */
239117632Sharti	bus_dmamap_t		sq_map;		/* map */
240117632Sharti
241117632Sharti	bus_addr_t		tsq_phy;	/* phys addr. */
242117632Sharti	struct idt_tsqe		*tsq;		/* transmit status queue */
243117632Sharti	struct idt_tsqe		*tsq_next;	/* last processed entry */
244117632Sharti	struct idt_rsqe		*rsq;		/* receive status queue */
245117632Sharti	bus_addr_t		rsq_phy;	/* phys addr. */
246117632Sharti	u_int			rsq_last;	/* last processed entry */
247117632Sharti	struct idt_rawhnd	*rawhnd;	/* raw cell handle */
248117632Sharti	bus_addr_t		rawhnd_phy;	/* phys addr. */
249117632Sharti
250117632Sharti	/* TST */
251117632Sharti	u_int			tst_state;	/* active TST and others */
252117632Sharti	u_int			tst_jump[2];	/* address of the jumps */
253117632Sharti	u_int			tst_base[2];	/* base address of TST */
254117632Sharti	u_int			*tst_soft;	/* soft TST */
255117632Sharti	struct mtx		tst_lock;
256117632Sharti	struct callout		tst_callout;
257117632Sharti	u_int			tst_free;	/* free slots */
258117632Sharti	u_int			tst_reserve;	/* non-CBR reserve */
259298955Spfg	u_int			bwrem;		/* remaining bandwidth */
260117632Sharti
261117632Sharti	/* sysctl support */
262117632Sharti	struct sysctl_ctx_list	sysctl_ctx;
263117632Sharti	struct sysctl_oid	*sysctl_tree;
264117632Sharti
265117632Sharti	/* EEPROM contents */
266117632Sharti	uint8_t			eeprom[256];
267117632Sharti
268117632Sharti	/* large buffer mapping */
269117632Sharti	bus_dma_tag_t		lbuf_tag;	/* DMA tag */
270117632Sharti	u_int			lbuf_max;	/* maximum number */
271117632Sharti	struct lmbuf		*lbufs;		/* array for indexing */
272117632Sharti	SLIST_HEAD(,lmbuf)	lbuf_free_list;	/* free list */
273117632Sharti
274117632Sharti	/* small buffer handling */
275117632Sharti	bus_dma_tag_t		sbuf_tag;	/* DMA tag */
276117632Sharti	struct mbpool		*sbuf_pool;	/* pool */
277117632Sharti	struct mbpool		*vbuf_pool;	/* pool */
278117632Sharti
279117632Sharti	/* raw cell queue */
280117632Sharti	struct lmbuf		*rawh;		/* current header buf */
281117632Sharti	u_int			rawi;		/* cell index into buffer */
282117632Sharti
283117632Sharti	/* statistics */
284117632Sharti	struct patm_stats	stats;		/* statistics */
285117632Sharti
286117632Sharti	/* Vccs */
287117632Sharti	struct patm_vcc		**vccs;		/* channel pointer array */
288117632Sharti	u_int			vccs_open;	/* number of open channels */
289117632Sharti	uma_zone_t		vcc_zone;
290117632Sharti	struct cv		vcc_cv;
291117632Sharti
292117632Sharti	/* SCDs */
293117632Sharti	uint32_t		scd_free;	/* SRAM of first free SCD */
294117632Sharti	bus_dma_tag_t		scd_tag;
295117632Sharti	struct patm_scd		*scd0;
296117632Sharti	LIST_HEAD(, patm_scd)	scd_list;	/* list of all active SCDs */
297117632Sharti
298117632Sharti	/* Tx */
299117632Sharti	bus_dma_tag_t		tx_tag;		/* for transmission */
300117632Sharti	SLIST_HEAD(, patm_txmap) tx_maps_free;	/* free maps */
301117632Sharti	u_int			tx_nmaps;	/* allocated maps */
302117632Sharti	u_int			tx_maxmaps;	/* maximum number */
303117632Sharti	struct uma_zone		*tx_mapzone;	/* zone for maps */
304117632Sharti
305117632Sharti#ifdef PATM_DEBUG
306117632Sharti	/* debugging */
307117632Sharti	u_int			debug;
308117632Sharti#endif
309117632Sharti};
310117632Sharti
311117632Sharti/* flags */
312117632Sharti#define	PATM_25M	0x0001		/* 25MBit card */
313117632Sharti#define	PATM_SBUFW	0x0002		/* warned */
314117632Sharti#define	PATM_VBUFW	0x0004		/* warned */
315117632Sharti#define	PATM_UNASS	0x0010		/* unassigned cells */
316117632Sharti
317117632Sharti#define	PATM_CLR	0x0007		/* clear on stop */
318117632Sharti
319117632Sharti/* tst - uses unused fields */
320117632Sharti#define	TST_BOTH	0x03000000
321117632Sharti#define	TST_CH0		0x01000000
322117632Sharti#define	TST_CH1		0x02000000
323117632Sharti/* tst_state */
324117632Sharti#define	TST_ACT1	0x0001		/* active TST */
325117632Sharti#define	TST_PENDING	0x0002		/* need update */
326117632Sharti#define	TST_WAIT	0x0004		/* wait fo jump */
327117632Sharti
328147256Sbrooks#define	patm_printf(SC, ...)	if_printf((SC)->ifp, __VA_ARGS__);
329117632Sharti
330117632Sharti#ifdef PATM_DEBUG
331117632Sharti/*
332117632Sharti * Debugging
333117632Sharti */
334117632Shartienum {
335117632Sharti	DBG_ATTACH	= 0x0001,	/* attaching the card */
336117632Sharti	DBG_INTR	= 0x0002,	/* interrupts */
337117632Sharti	DBG_REG		= 0x0004,	/* register access */
338117632Sharti	DBG_SRAM	= 0x0008,	/* SRAM access */
339117632Sharti	DBG_PHY		= 0x0010,	/* PHY access */
340117632Sharti	DBG_IOCTL	= 0x0020,	/* ioctl */
341117632Sharti	DBG_FREEQ	= 0x0040,	/* free bufq supply */
342117632Sharti	DBG_VCC		= 0x0080,	/* open/close */
343117632Sharti	DBG_TX		= 0x0100,	/* transmission */
344117632Sharti	DBG_TST		= 0x0200,	/* TST */
345117632Sharti
346117632Sharti	DBG_ALL		= 0xffff
347117632Sharti};
348117632Sharti
349117632Sharti#define	patm_debug(SC, FLAG, ...) do {					\
350117632Sharti	if((SC)->debug & DBG_##FLAG) { 					\
351147256Sbrooks		if_printf((SC)->ifp, "%s: ", __func__);	\
352117632Sharti		printf(__VA_ARGS__);					\
353117632Sharti		printf("\n");						\
354117632Sharti	}								\
355117632Sharti    } while (0)
356117632Sharti#else
357117632Sharti
358117632Sharti#define patm_debug(SC, FLAG, ...) do { } while (0)
359117632Sharti
360117632Sharti#endif
361117632Sharti
362117632Sharti/* start output */
363117632Shartivoid patm_start(struct ifnet *);
364117632Sharti
365117632Sharti/* ioctl handler */
366117632Shartiint patm_ioctl(struct ifnet *, u_long, caddr_t);
367117632Sharti
368117632Sharti/* start the interface */
369117632Shartivoid patm_init(void *);
370117632Sharti
371117632Sharti/* start the interface with the lock held */
372117632Shartivoid patm_initialize(struct patm_softc *);
373117632Sharti
374117632Sharti/* stop the interface */
375117632Shartivoid patm_stop(struct patm_softc *);
376117632Sharti
377117632Sharti/* software reset of interface */
378117632Shartivoid patm_reset(struct patm_softc *);
379117632Sharti
380117632Sharti/* interrupt handler */
381117632Shartivoid patm_intr(void *);
382117632Sharti
383117632Sharti/* check RSQ */
384117632Shartivoid patm_intr_rsq(struct patm_softc *sc);
385117632Sharti
386118601Sharti/* enable the vcc */
387118601Shartivoid patm_load_vc(struct patm_softc *sc, struct patm_vcc *vcc, int reload);
388118601Sharti
389117632Sharti/* close the given vcc for transmission */
390117632Shartivoid patm_tx_vcc_close(struct patm_softc *, struct patm_vcc *);
391117632Sharti
392117632Sharti/* close the given vcc for receive */
393117632Shartivoid patm_rx_vcc_close(struct patm_softc *, struct patm_vcc *);
394117632Sharti
395117632Sharti/* transmission side finally closed */
396117632Shartivoid patm_tx_vcc_closed(struct patm_softc *, struct patm_vcc *);
397117632Sharti
398117632Sharti/* receive side finally closed */
399117632Shartivoid patm_rx_vcc_closed(struct patm_softc *, struct patm_vcc *);
400117632Sharti
401117632Sharti/* vcc closed */
402117632Shartivoid patm_vcc_closed(struct patm_softc *, struct patm_vcc *);
403117632Sharti
404117632Sharti/* check if we can open this one */
405117632Shartiint patm_tx_vcc_can_open(struct patm_softc *, struct patm_vcc *);
406117632Sharti
407117632Sharti/* check if we can open this one */
408117632Shartiint patm_rx_vcc_can_open(struct patm_softc *, struct patm_vcc *);
409117632Sharti
410117632Sharti/* open it */
411117632Shartivoid patm_tx_vcc_open(struct patm_softc *, struct patm_vcc *);
412117632Sharti
413117632Sharti/* open it */
414117632Shartivoid patm_rx_vcc_open(struct patm_softc *, struct patm_vcc *);
415117632Sharti
416117632Sharti/* receive packet */
417117632Shartivoid patm_rx(struct patm_softc *, struct idt_rsqe *);
418117632Sharti
419117632Sharti/* packet transmitted */
420117632Shartivoid patm_tx(struct patm_softc *, u_int, u_int);
421117632Sharti
422117632Sharti/* VBR connection went idle */
423117632Shartivoid patm_tx_idle(struct patm_softc *, u_int);
424117632Sharti
425117632Sharti/* allocate an SCQ */
426117632Shartistruct patm_scd *patm_scd_alloc(struct patm_softc *);
427117632Sharti
428117632Sharti/* free an SCD */
429117632Shartivoid patm_scd_free(struct patm_softc *sc, struct patm_scd *scd);
430117632Sharti
431117632Sharti/* setup SCD in SRAM */
432117632Shartivoid patm_scd_setup(struct patm_softc *sc, struct patm_scd *scd);
433117632Sharti
434117632Sharti/* setup TCT entry in SRAM */
435117632Shartivoid patm_tct_setup(struct patm_softc *, struct patm_scd *, struct patm_vcc *);
436117632Sharti
437117632Sharti/* free a large buffer */
438117632Shartivoid patm_lbuf_free(struct patm_softc *sc, struct lmbuf *b);
439117632Sharti
440117632Sharti/* Process the raw cell at the given address */
441117632Shartivoid patm_rx_raw(struct patm_softc *sc, u_char *cell);
442117632Sharti
443117632Sharti/* load a one segment DMA map */
444117632Shartivoid patm_load_callback(void *, bus_dma_segment_t *, int, int);
445117632Sharti
446117632Sharti/* network operation register access */
447117632Shartistatic __inline uint32_t
448117632Shartipatm_nor_read(struct patm_softc *sc, u_int reg)
449117632Sharti{
450117632Sharti	uint32_t val;
451117632Sharti
452117632Sharti	val = bus_space_read_4(sc->memt, sc->memh, reg);
453117632Sharti	patm_debug(sc, REG, "reg(0x%x)=%04x", reg, val);
454117632Sharti	return (val);
455117632Sharti}
456117632Shartistatic __inline void
457117632Shartipatm_nor_write(struct patm_softc *sc, u_int reg, uint32_t val)
458117632Sharti{
459117632Sharti
460117632Sharti	patm_debug(sc, REG, "reg(0x%x)=%04x", reg, val);
461117632Sharti	bus_space_write_4(sc->memt, sc->memh, reg, val);
462117632Sharti}
463117632Sharti
464117632Sharti/* Execute command */
465117632Shartistatic __inline void
466117632Shartipatm_cmd_wait(struct patm_softc *sc)
467117632Sharti{
468117632Sharti	while (patm_nor_read(sc, IDT_NOR_STAT) & IDT_STAT_CMDBZ)
469117632Sharti		;
470117632Sharti}
471117632Shartistatic __inline void
472117632Shartipatm_cmd_exec(struct patm_softc *sc, uint32_t cmd)
473117632Sharti{
474117632Sharti	patm_cmd_wait(sc);
475117632Sharti	patm_nor_write(sc, IDT_NOR_CMD, cmd);
476117632Sharti}
477117632Sharti
478117632Sharti/* Read/write SRAM at the given word address. */
479117632Shartistatic __inline uint32_t
480117632Shartipatm_sram_read(struct patm_softc *sc, u_int addr)
481117632Sharti{
482117632Sharti	uint32_t val;
483117632Sharti
484117632Sharti	patm_cmd_exec(sc, IDT_MKCMD_RSRAM(addr));
485117632Sharti	patm_cmd_wait(sc);
486117632Sharti	val = patm_nor_read(sc, IDT_NOR_D0);
487117632Sharti	patm_debug(sc, SRAM, "read %04x=%08x", addr, val);
488117632Sharti	return (val);
489117632Sharti}
490117632Shartistatic __inline void
491117632Shartipatm_sram_write(struct patm_softc *sc, u_int addr, uint32_t val)
492117632Sharti{
493117632Sharti	patm_debug(sc, SRAM, "write %04x=%08x", addr, val);
494117632Sharti	patm_cmd_wait(sc);
495117632Sharti	patm_nor_write(sc, IDT_NOR_D0, val);
496117632Sharti	patm_cmd_exec(sc, IDT_MKCMD_WSRAM(addr, 0));
497117632Sharti}
498117632Shartistatic __inline void
499117632Shartipatm_sram_write4(struct patm_softc *sc, u_int addr, uint32_t v0, uint32_t v1,
500117632Sharti    uint32_t v2, uint32_t v3)
501117632Sharti{
502117632Sharti	patm_debug(sc, SRAM, "write %04x=%08x,%08x,%08x,%08x",
503117632Sharti	    addr, v0, v1, v2, v3);
504117632Sharti	patm_cmd_wait(sc);
505117632Sharti	patm_nor_write(sc, IDT_NOR_D0, v0);
506117632Sharti	patm_nor_write(sc, IDT_NOR_D1, v1);
507117632Sharti	patm_nor_write(sc, IDT_NOR_D2, v2);
508117632Sharti	patm_nor_write(sc, IDT_NOR_D3, v3);
509117632Sharti	patm_cmd_exec(sc, IDT_MKCMD_WSRAM(addr, 3));
510117632Sharti}
511117632Sharti
512117632Sharti#define	LEGAL_VPI(SC, VPI) \
513147256Sbrooks	(((VPI) & ~((1 << IFP2IFATM((SC)->ifp)->mib.vpi_bits) - 1)) == 0)
514117632Sharti#define	LEGAL_VCI(SC, VCI) \
515147256Sbrooks	(((VCI) & ~((1 << IFP2IFATM((SC)->ifp)->mib.vci_bits) - 1)) == 0)
516117632Sharti
517117632Shartiextern const uint32_t patm_rtables155[];
518117632Shartiextern const uint32_t patm_rtables25[];
519117632Shartiextern const u_int patm_rtables_size;
520117632Shartiextern const u_int patm_rtables_ntab;
521