if_patmvar.h revision 147256
1183840Sraj/*-
2183840Sraj * Copyright (c) 2003
3183840Sraj *	Fraunhofer Institute for Open Communication Systems (FhG Fokus).
4183840Sraj * 	All rights reserved.
5183840Sraj *
6183840Sraj * Redistribution and use in source and binary forms, with or without
7183840Sraj * modification, are permitted provided that the following conditions
8183840Sraj * are met:
9183840Sraj * 1. Redistributions of source code must retain the above copyright
10183840Sraj *    notice, this list of conditions and the following disclaimer.
11183840Sraj * 2. Redistributions in binary form must reproduce the above copyright
12183840Sraj *    notice, this list of conditions and the following disclaimer in the
13183840Sraj *    documentation and/or other materials provided with the distribution.
14183840Sraj *
15183840Sraj * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16183840Sraj * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17183840Sraj * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18183840Sraj * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19183840Sraj * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20183840Sraj * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21183840Sraj * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22183840Sraj * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23183840Sraj * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24183840Sraj * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25183840Sraj * SUCH DAMAGE.
26183840Sraj *
27183840Sraj * Author: Hartmut Brandt <harti@freebsd.org>
28183840Sraj *
29183840Sraj * $FreeBSD: head/sys/dev/patm/if_patmvar.h 147256 2005-06-10 16:49:24Z brooks $
30183840Sraj *
31183840Sraj * Driver for IDT77252 (ABR) based cards like ProSum's.
32183840Sraj */
33183840Sraj
34183840Sraj/* legal values are 0, 1, 2 and 8 */
35183840Sraj#define	PATM_VPI_BITS	2
36183840Sraj#define	PATM_CFG_VPI	IDT_CFG_VP2
37183840Sraj
38218427Smarcel/* receive status queue size */
39183840Sraj#define	PATM_RSQ_SIZE		512
40183840Sraj#define	PATM_CFQ_RSQ_SIZE	IDT_CFG_RXQ512
41183840Sraj
42183840Sraj/* alignment for SQ memory */
43183840Sraj#define	PATM_SQ_ALIGNMENT	8192
44209131Sraj
45209131Sraj#define	PATM_PROATM_NAME_OFFSET	060
46209131Sraj#define	PATM_PROATM_NAME	"PROATM"
47183840Sraj#define	PATM_PROATM_MAC_OFFSET	044
48183840Sraj#define	PATM_IDT_MAC_OFFSET	0154
49183840Sraj
50183840Sraj/* maximum number of packets on UBR queue */
51183840Sraj#define	PATM_DLFT_MAXQ		1000
52183840Sraj
53183840Sraj/* maximum number of packets on other queues. This should depend on the
54183840Sraj * traffic contract. */
55183840Sraj#define	PATM_TX_IFQLEN		100
56183840Sraj
57183840Sraj/*
58183840Sraj * Maximum number of DMA maps we allocate. This is the minimum that can be
59183840Sraj * set larger via a sysctl.
60183840Sraj * Starting number of DMA maps.
61183840Sraj * Step for growing.
62183840Sraj */
63183840Sraj#define	PATM_CFG_TXMAPS_MAX	1024
64183840Sraj#define	PATM_CFG_TXMAPS_INIT	128
65183840Sraj#define	PATM_CFG_TXMAPS_STEP	128
66183840Sraj
67183840Sraj/* percents of TST slots to keep for non-CBR traffic */
68183840Sraj#define	PATM_TST_RESERVE	2
69183840Sraj
70183840Sraj/*
71183840Sraj * Structure to hold TX DMA maps
72183840Sraj */
73183840Srajstruct patm_txmap {
74183840Sraj	SLIST_ENTRY(patm_txmap) link;
75183840Sraj	bus_dmamap_t	map;
76183840Sraj};
77183840Sraj
78183840Sraj/*
79183840Sraj * Receive buffers.
80183840Sraj *
81183840Sraj * We manage our own external mbufs for small receive buffers for two reasons:
82183840Sraj * the card may consume a rather large number of buffers. Mapping each buffer
83261410Sian * would consume a lot of iospace on sparc64. Also the card allows us to set
84261410Sian * a 32-bit handle for identification of the buffers. On a 64-bit system this
85261410Sian * requires us to use a mapping between buffers and handles.
86209131Sraj *
87209131Sraj * For large buffers we use mbuf clusters directly. We track these by using
88209131Sraj * an array of pointers (lbufs) to special structs and a free list of these
89183840Sraj * structs.
90183840Sraj *
91183840Sraj * For AAL0 cell we use FBQ2 and make the 1 cell long.
92183840Sraj */
93183840Sraj/*
94183840Sraj * Define the small buffer chunk so that we have at least 16 byte free
95183840Sraj * at the end of the chunk and that there is an integral number of chunks
96183840Sraj * in a page.
97183840Sraj */
98183840Sraj#define	SMBUF_PAGE_SIZE		16384	/* 16k pages */
99183840Sraj#define	SMBUF_MAX_PAGES		64	/* maximum number of pages */
100183840Sraj#define	SMBUF_CHUNK_SIZE	256	/* 256 bytes per chunk */
101183840Sraj#define	SMBUF_CELLS		5
102183840Sraj#define	SMBUF_SIZE		(SMBUF_CELLS * 48)
103183840Sraj#define	SMBUF_THRESHOLD		9	/* 9/16 of queue size */
104183840Sraj#define	SMBUF_NI_THRESH		3
105183840Sraj#define	SMBUF_CI_THRESH		1
106183840Sraj
107183840Sraj#define	VMBUF_PAGE_SIZE		16384	/* 16k pages */
108183840Sraj#define	VMBUF_MAX_PAGES		16	/* maximum number of pages */
109183840Sraj#define	VMBUF_CHUNK_SIZE	64	/* 64 bytes per chunk */
110183840Sraj#define	VMBUF_CELLS		1
111238873Shrs#define	VMBUF_SIZE		(VMBUF_CELLS * 48)
112238873Shrs#define	VMBUF_THRESHOLD		15	/* 15/16 of size */
113238873Shrs
114191140Sraj#define	SMBUF_OFFSET	(SMBUF_CHUNK_SIZE - 8 - SMBUF_SIZE)
115183840Sraj#define	VMBUF_OFFSET	0
116183840Sraj
117191140Sraj#define	MBUF_SHANDLE	0x00000000
118183840Sraj#define	MBUF_LHANDLE	0x80000000
119183840Sraj#define	MBUF_VHANDLE	0x40000000
120183840Sraj#define	MBUF_HMASK	0x3fffffff
121183840Sraj
122183840Sraj/*
123183840Sraj * Large buffers
124183840Sraj *
125183840Sraj * The problem with these is the maximum count. When the card assembles
126183840Sraj * a AAL5 pdu it moves a buffer from the FBQ to the VC. This frees space
127183840Sraj * in the FBQ, put the buffer may pend on the card for an unlimited amount
128183840Sraj * of time (we don't idle connections). This means that the upper limit
129183840Sraj * on buffers on the card may be (no-of-open-vcs + FBQ_SIZE). Because
130183840Sraj * this is far too much, make this a tuneable. We could also make
131183840Sraj * this dynamic by allocating pages of several lbufs at once during run time.
132183840Sraj */
133183840Sraj#define	LMBUF_MAX		(IDT_FBQ_SIZE * 2)
134183840Sraj#define	LMBUF_CELLS		(MCLBYTES / 48)	/* 42 cells = 2048 byte */
135183840Sraj#define	LMBUF_SIZE		(LMBUF_CELLS * 48)
136183840Sraj#define	LMBUF_THRESHOLD		9	/* 9/16 of queue size */
137183840Sraj#define	LMBUF_OFFSET		(MCLBYTES - LMBUF_SIZE)
138183840Sraj#define	LMBUF_NI_THRESH		3
139183840Sraj#define	LMBUF_CI_THRESH		1
140183840Sraj
141183840Sraj#define	LMBUF_HANDLE		0x80000000
142183840Sraj
143183840Srajstruct lmbuf {
144183840Sraj	SLIST_ENTRY(lmbuf)	link;	/* free list link */
145183840Sraj	bus_dmamap_t		map;	/* DMA map */
146183840Sraj	u_int			handle;	/* this is the handle index */
147183840Sraj	struct mbuf		*m;	/* the current mbuf */
148183840Sraj	bus_addr_t		phy;	/* phy addr */
149209131Sraj};
150183840Sraj
151183840Sraj#define	PATM_CID(SC, VPI, VCI)	\
152218427Smarcel    (((VPI) << IFP2IFATM((SC)->ifp)->mib.vci_bits) | (VCI))
153183840Sraj
154218427Smarcel/*
155218427Smarcel * Internal driver statistics
156183840Sraj */
157218427Smarcelstruct patm_stats {
158183840Sraj	uint32_t	raw_cells;
159218427Smarcel	uint32_t	raw_no_vcc;
160218427Smarcel	uint32_t	raw_no_buf;
161218427Smarcel	uint32_t	tx_qfull;
162218427Smarcel	uint32_t	tx_out_of_tbds;
163183840Sraj	uint32_t	tx_out_of_maps;
164218427Smarcel	uint32_t	tx_load_err;
165183840Sraj};
166218427Smarcel
167218427Smarcel/*
168218427Smarcel * These are allocated as DMA able memory
169218427Smarcel */
170183840Srajstruct patm_scd {
171183840Sraj	struct idt_tbd	scq[IDT_SCQ_SIZE];
172218427Smarcel	LIST_ENTRY(patm_scd) link;	/* all active SCDs */
173183840Sraj	uint32_t	sram;		/* SRAM address */
174218427Smarcel	bus_addr_t	phy;		/* physical address */
175218427Smarcel	bus_dmamap_t	map;		/* DMA map */
176218427Smarcel	u_int		tail;		/* next free entry for host */
177218427Smarcel	int		space;		/* number of free entries (minus one) */
178183840Sraj	u_int		slots;		/* CBR slots allocated */
179218427Smarcel	uint8_t		tag;		/* next tag for TSI */
180183840Sraj	uint8_t		last_tag;	/* last tag checked in interrupt */
181218427Smarcel	uint8_t		num_on_card;	/* number of PDUs on tx queue */
182218427Smarcel	uint8_t		lacr;		/* LogACR value */
183218427Smarcel	uint8_t		init_er;	/* LogER value */
184183840Sraj	struct ifqueue	q;		/* queue of packets */
185183840Sraj	struct mbuf	*on_card[IDT_TSQE_TAG_SPACE];
186183840Sraj};
187183840Sraj
188183840Sraj/*
189183840Sraj * Per-VCC data
190183840Sraj */
191183840Srajstruct patm_vcc {
192183840Sraj	struct atmio_vcc vcc;		/* caller's parameters */
193183840Sraj	void		*rxhand;	/* NATM handle */
194183840Sraj	u_int		vflags;		/* open and other flags */
195183840Sraj	uint32_t	ipackets;	/* packets received */
196183840Sraj	uint32_t	opackets;	/* packets sent */
197183840Sraj	uint64_t	ibytes;		/* bytes received */
198183840Sraj	uint64_t	obytes;		/* bytes sent */
199183840Sraj
200183840Sraj	struct mbuf	*chain;		/* currently received chain */
201183840Sraj	struct mbuf	*last;		/* end of chain */
202183840Sraj	u_int		cid;		/* index */
203183840Sraj	u_int		cps;		/* last ABR cps */
204183840Sraj	struct patm_scd	*scd;
205183840Sraj};
206183840Sraj#define	PATM_VCC_TX_OPEN	0x0001
207183840Sraj#define	PATM_VCC_RX_OPEN	0x0002
208183840Sraj#define	PATM_VCC_TX_CLOSING	0x0004
209183840Sraj#define	PATM_VCC_RX_CLOSING	0x0008
210183840Sraj#define	PATM_VCC_OPEN		0x000f	/* all the above */
211183840Sraj
212183840Sraj#define	PATM_RAW_CELL		0x0000	/* 53 byte cells */
213183840Sraj#define	PATM_RAW_NOHEC		0x0100	/* 52 byte cells */
214183840Sraj#define	PATM_RAW_CS		0x0200	/* 64 byte cell stream */
215183840Sraj#define	PATM_RAW_FORMAT		0x0300	/* format mask */
216183840Sraj
217183840Sraj/*
218183840Sraj * Per adapter data
219183840Sraj */
220183840Srajstruct patm_softc {
221183840Sraj	struct ifnet		*ifp;		/* common ATM stuff */
222183840Sraj	struct mtx		mtx;		/* lock */
223183840Sraj	struct ifmedia		media;		/* media */
224183840Sraj	device_t		dev;		/* device */
225183840Sraj	struct resource *	memres;		/* memory resource */
226183840Sraj	bus_space_handle_t	memh;		/* handle */
227183840Sraj	bus_space_tag_t		memt;		/* ... and tag */
228183840Sraj	int			irqid;		/* resource id */
229183840Sraj	struct resource *	irqres;		/* resource */
230183840Sraj	void *			ih;		/* interrupt handle */
231183840Sraj	struct utopia		utopia;		/* phy state */
232183840Sraj	const struct idt_mmap	*mmap;		/* SRAM memory map */
233183840Sraj	u_int			flags;		/* see below */
234183840Sraj	u_int			revision;	/* chip revision */
235183840Sraj
236183840Sraj	/* DMAable status queue memory */
237183840Sraj	size_t			sq_size;	/* size of memory area */
238183840Sraj	bus_dma_tag_t		sq_tag;		/* DMA tag */
239183840Sraj	bus_dmamap_t		sq_map;		/* map */
240183840Sraj
241183840Sraj	bus_addr_t		tsq_phy;	/* phys addr. */
242183840Sraj	struct idt_tsqe		*tsq;		/* transmit status queue */
243183840Sraj	struct idt_tsqe		*tsq_next;	/* last processed entry */
244183840Sraj	struct idt_rsqe		*rsq;		/* receive status queue */
245183840Sraj	bus_addr_t		rsq_phy;	/* phys addr. */
246183840Sraj	u_int			rsq_last;	/* last processed entry */
247183840Sraj	struct idt_rawhnd	*rawhnd;	/* raw cell handle */
248183840Sraj	bus_addr_t		rawhnd_phy;	/* phys addr. */
249183840Sraj
250183840Sraj	/* TST */
251183840Sraj	u_int			tst_state;	/* active TST and others */
252183840Sraj	u_int			tst_jump[2];	/* address of the jumps */
253183840Sraj	u_int			tst_base[2];	/* base address of TST */
254183840Sraj	u_int			*tst_soft;	/* soft TST */
255183840Sraj	struct mtx		tst_lock;
256183840Sraj	struct callout		tst_callout;
257183840Sraj	u_int			tst_free;	/* free slots */
258183840Sraj	u_int			tst_reserve;	/* non-CBR reserve */
259183840Sraj	u_int			bwrem;		/* remaining bandwith */
260183840Sraj
261183840Sraj	/* sysctl support */
262183840Sraj	struct sysctl_ctx_list	sysctl_ctx;
263183840Sraj	struct sysctl_oid	*sysctl_tree;
264183840Sraj
265183840Sraj	/* EEPROM contents */
266183840Sraj	uint8_t			eeprom[256];
267183840Sraj
268183840Sraj	/* large buffer mapping */
269183840Sraj	bus_dma_tag_t		lbuf_tag;	/* DMA tag */
270183840Sraj	u_int			lbuf_max;	/* maximum number */
271183840Sraj	struct lmbuf		*lbufs;		/* array for indexing */
272183840Sraj	SLIST_HEAD(,lmbuf)	lbuf_free_list;	/* free list */
273183840Sraj
274183840Sraj	/* small buffer handling */
275183840Sraj	bus_dma_tag_t		sbuf_tag;	/* DMA tag */
276183840Sraj	struct mbpool		*sbuf_pool;	/* pool */
277183840Sraj	struct mbpool		*vbuf_pool;	/* pool */
278183840Sraj
279183840Sraj	/* raw cell queue */
280183840Sraj	struct lmbuf		*rawh;		/* current header buf */
281183840Sraj	u_int			rawi;		/* cell index into buffer */
282183840Sraj
283183840Sraj	/* statistics */
284183840Sraj	struct patm_stats	stats;		/* statistics */
285183840Sraj
286183840Sraj	/* Vccs */
287183840Sraj	struct patm_vcc		**vccs;		/* channel pointer array */
288183840Sraj	u_int			vccs_open;	/* number of open channels */
289183840Sraj	uma_zone_t		vcc_zone;
290183840Sraj	struct cv		vcc_cv;
291183840Sraj
292183840Sraj	/* SCDs */
293183840Sraj	uint32_t		scd_free;	/* SRAM of first free SCD */
294183840Sraj	bus_dma_tag_t		scd_tag;
295183840Sraj	struct patm_scd		*scd0;
296183840Sraj	LIST_HEAD(, patm_scd)	scd_list;	/* list of all active SCDs */
297183840Sraj
298183840Sraj	/* Tx */
299183840Sraj	bus_dma_tag_t		tx_tag;		/* for transmission */
300183840Sraj	SLIST_HEAD(, patm_txmap) tx_maps_free;	/* free maps */
301183840Sraj	u_int			tx_nmaps;	/* allocated maps */
302183840Sraj	u_int			tx_maxmaps;	/* maximum number */
303183840Sraj	struct uma_zone		*tx_mapzone;	/* zone for maps */
304183840Sraj
305183840Sraj#ifdef PATM_DEBUG
306183840Sraj	/* debugging */
307183840Sraj	u_int			debug;
308183840Sraj#endif
309183840Sraj};
310183840Sraj
311183840Sraj/* flags */
312183840Sraj#define	PATM_25M	0x0001		/* 25MBit card */
313183840Sraj#define	PATM_SBUFW	0x0002		/* warned */
314#define	PATM_VBUFW	0x0004		/* warned */
315#define	PATM_UNASS	0x0010		/* unassigned cells */
316
317#define	PATM_CLR	0x0007		/* clear on stop */
318
319/* tst - uses unused fields */
320#define	TST_BOTH	0x03000000
321#define	TST_CH0		0x01000000
322#define	TST_CH1		0x02000000
323/* tst_state */
324#define	TST_ACT1	0x0001		/* active TST */
325#define	TST_PENDING	0x0002		/* need update */
326#define	TST_WAIT	0x0004		/* wait fo jump */
327
328#define	patm_printf(SC, ...)	if_printf((SC)->ifp, __VA_ARGS__);
329
330#ifdef PATM_DEBUG
331/*
332 * Debugging
333 */
334enum {
335	DBG_ATTACH	= 0x0001,	/* attaching the card */
336	DBG_INTR	= 0x0002,	/* interrupts */
337	DBG_REG		= 0x0004,	/* register access */
338	DBG_SRAM	= 0x0008,	/* SRAM access */
339	DBG_PHY		= 0x0010,	/* PHY access */
340	DBG_IOCTL	= 0x0020,	/* ioctl */
341	DBG_FREEQ	= 0x0040,	/* free bufq supply */
342	DBG_VCC		= 0x0080,	/* open/close */
343	DBG_TX		= 0x0100,	/* transmission */
344	DBG_TST		= 0x0200,	/* TST */
345
346	DBG_ALL		= 0xffff
347};
348
349#define	patm_debug(SC, FLAG, ...) do {					\
350	if((SC)->debug & DBG_##FLAG) { 					\
351		if_printf((SC)->ifp, "%s: ", __func__);	\
352		printf(__VA_ARGS__);					\
353		printf("\n");						\
354	}								\
355    } while (0)
356#else
357
358#define patm_debug(SC, FLAG, ...) do { } while (0)
359
360#endif
361
362/* start output */
363void patm_start(struct ifnet *);
364
365/* ioctl handler */
366int patm_ioctl(struct ifnet *, u_long, caddr_t);
367
368/* start the interface */
369void patm_init(void *);
370
371/* start the interface with the lock held */
372void patm_initialize(struct patm_softc *);
373
374/* stop the interface */
375void patm_stop(struct patm_softc *);
376
377/* software reset of interface */
378void patm_reset(struct patm_softc *);
379
380/* interrupt handler */
381void patm_intr(void *);
382
383/* check RSQ */
384void patm_intr_rsq(struct patm_softc *sc);
385
386/* enable the vcc */
387void patm_load_vc(struct patm_softc *sc, struct patm_vcc *vcc, int reload);
388
389/* close the given vcc for transmission */
390void patm_tx_vcc_close(struct patm_softc *, struct patm_vcc *);
391
392/* close the given vcc for receive */
393void patm_rx_vcc_close(struct patm_softc *, struct patm_vcc *);
394
395/* transmission side finally closed */
396void patm_tx_vcc_closed(struct patm_softc *, struct patm_vcc *);
397
398/* receive side finally closed */
399void patm_rx_vcc_closed(struct patm_softc *, struct patm_vcc *);
400
401/* vcc closed */
402void patm_vcc_closed(struct patm_softc *, struct patm_vcc *);
403
404/* check if we can open this one */
405int patm_tx_vcc_can_open(struct patm_softc *, struct patm_vcc *);
406
407/* check if we can open this one */
408int patm_rx_vcc_can_open(struct patm_softc *, struct patm_vcc *);
409
410/* open it */
411void patm_tx_vcc_open(struct patm_softc *, struct patm_vcc *);
412
413/* open it */
414void patm_rx_vcc_open(struct patm_softc *, struct patm_vcc *);
415
416/* receive packet */
417void patm_rx(struct patm_softc *, struct idt_rsqe *);
418
419/* packet transmitted */
420void patm_tx(struct patm_softc *, u_int, u_int);
421
422/* VBR connection went idle */
423void patm_tx_idle(struct patm_softc *, u_int);
424
425/* allocate an SCQ */
426struct patm_scd *patm_scd_alloc(struct patm_softc *);
427
428/* free an SCD */
429void patm_scd_free(struct patm_softc *sc, struct patm_scd *scd);
430
431/* setup SCD in SRAM */
432void patm_scd_setup(struct patm_softc *sc, struct patm_scd *scd);
433
434/* setup TCT entry in SRAM */
435void patm_tct_setup(struct patm_softc *, struct patm_scd *, struct patm_vcc *);
436
437/* free a large buffer */
438void patm_lbuf_free(struct patm_softc *sc, struct lmbuf *b);
439
440/* Process the raw cell at the given address */
441void patm_rx_raw(struct patm_softc *sc, u_char *cell);
442
443/* load a one segment DMA map */
444void patm_load_callback(void *, bus_dma_segment_t *, int, int);
445
446/* network operation register access */
447static __inline uint32_t
448patm_nor_read(struct patm_softc *sc, u_int reg)
449{
450	uint32_t val;
451
452	val = bus_space_read_4(sc->memt, sc->memh, reg);
453	patm_debug(sc, REG, "reg(0x%x)=%04x", reg, val);
454	return (val);
455}
456static __inline void
457patm_nor_write(struct patm_softc *sc, u_int reg, uint32_t val)
458{
459
460	patm_debug(sc, REG, "reg(0x%x)=%04x", reg, val);
461	bus_space_write_4(sc->memt, sc->memh, reg, val);
462}
463
464/* Execute command */
465static __inline void
466patm_cmd_wait(struct patm_softc *sc)
467{
468	while (patm_nor_read(sc, IDT_NOR_STAT) & IDT_STAT_CMDBZ)
469		;
470}
471static __inline void
472patm_cmd_exec(struct patm_softc *sc, uint32_t cmd)
473{
474	patm_cmd_wait(sc);
475	patm_nor_write(sc, IDT_NOR_CMD, cmd);
476}
477
478/* Read/write SRAM at the given word address. */
479static __inline uint32_t
480patm_sram_read(struct patm_softc *sc, u_int addr)
481{
482	uint32_t val;
483
484	patm_cmd_exec(sc, IDT_MKCMD_RSRAM(addr));
485	patm_cmd_wait(sc);
486	val = patm_nor_read(sc, IDT_NOR_D0);
487	patm_debug(sc, SRAM, "read %04x=%08x", addr, val);
488	return (val);
489}
490static __inline void
491patm_sram_write(struct patm_softc *sc, u_int addr, uint32_t val)
492{
493	patm_debug(sc, SRAM, "write %04x=%08x", addr, val);
494	patm_cmd_wait(sc);
495	patm_nor_write(sc, IDT_NOR_D0, val);
496	patm_cmd_exec(sc, IDT_MKCMD_WSRAM(addr, 0));
497}
498static __inline void
499patm_sram_write4(struct patm_softc *sc, u_int addr, uint32_t v0, uint32_t v1,
500    uint32_t v2, uint32_t v3)
501{
502	patm_debug(sc, SRAM, "write %04x=%08x,%08x,%08x,%08x",
503	    addr, v0, v1, v2, v3);
504	patm_cmd_wait(sc);
505	patm_nor_write(sc, IDT_NOR_D0, v0);
506	patm_nor_write(sc, IDT_NOR_D1, v1);
507	patm_nor_write(sc, IDT_NOR_D2, v2);
508	patm_nor_write(sc, IDT_NOR_D3, v3);
509	patm_cmd_exec(sc, IDT_MKCMD_WSRAM(addr, 3));
510}
511
512#define	LEGAL_VPI(SC, VPI) \
513	(((VPI) & ~((1 << IFP2IFATM((SC)->ifp)->mib.vpi_bits) - 1)) == 0)
514#define	LEGAL_VCI(SC, VCI) \
515	(((VCI) & ~((1 << IFP2IFATM((SC)->ifp)->mib.vci_bits) - 1)) == 0)
516
517extern const uint32_t patm_rtables155[];
518extern const uint32_t patm_rtables25[];
519extern const u_int patm_rtables_size;
520extern const u_int patm_rtables_ntab;
521