xref: /illumos-gate/usr/src/uts/common/io/elxl/elxl.h (revision 69b3e104)
1 /*
2  * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
3  * Use is subject to license terms.
4  */
5 
6 /*
7  * Copyright (c) 1998 The NetBSD Foundation, Inc.
8  * All rights reserved.
9  *
10  * This code is derived from software contributed to The NetBSD Foundation
11  * by Frank van der Linden.
12  *
13  * Redistribution and use in source and binary forms, with or without
14  * modification, are permitted provided that the following conditions
15  * are met:
16  * 1. Redistributions of source code must retain the above copyright
17  *    notice, this list of conditions and the following disclaimer.
18  * 2. Redistributions in binary form must reproduce the above copyright
19  *    notice, this list of conditions and the following disclaimer in the
20  *    documentation and/or other materials provided with the distribution.
21  *
22  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
23  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
24  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
25  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
26  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
27  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
28  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
29  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
30  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
31  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
32  * POSSIBILITY OF SUCH DAMAGE.
33  */
34 
35 
36 #ifndef ELXL_H
37 #define	ELXL_H
38 
39 /*
40  * This file defines the registers specific to the EtherLink XL family
41  * of NICs.
42  */
43 
44 #define	REG_CMD_STAT		0x0e	/* Write command, read status */
45 
46 #define	CMD_GLOBAL_RESET	0x0000
47 #define	CMD_SELECT_WINDOW	0x0800
48 #define	CMD_BNC_ENABLE		0x1000	/* enable 10BASE2 DC-DC converter */
49 #define	CMD_RX_DISABLE		0x1800
50 #define	CMD_RX_ENABLE		0x2000
51 #define	CMD_RX_RESET		0x2800
52 #define	CMD_UP_STALL		0x3000
53 #define	CMD_UP_UNSTALL		0x3001
54 #define	CMD_DN_STALL		0x3002
55 #define	CMD_DN_UNSTALL		0x3003
56 #define	CMD_TX_ENABLE		0x4800
57 #define	CMD_TX_DISABLE		0x5000
58 #define	CMD_TX_RESET		0x5800
59 #define	CMD_INT_REQ		0x6000
60 #define	CMD_INT_ACK		0x6800
61 #define	CMD_INT_ENABLE		0x7000
62 #define	CMD_IND_ENABLE		0x7800
63 #define	CMD_SET_FILTER		0x8000
64 #define	CMD_SET_RXEARLY		0x8800
65 #define	CMD_SET_TXSTART		0x9800
66 #define	CMD_STATS_ENABLE	0xa800
67 #define	CMD_STATS_DISABLE	0xb000
68 #define	CMD_BNC_DISABLE		0xb800	/* disable 10BASE2 DC-DC converter */
69 #define	CMD_SET_TXRECLAIM	0xc000
70 #define	CMD_CLEAR_HASHBIT	0xc800
71 #define	CMD_SET_HASHBIT		0xcc00
72 
73 /*
74  * Defines for the interrupt status register
75  */
76 #define	INT_LATCH		0x0001
77 #define	INT_HOST_ERROR		0x0002
78 #define	INT_TX_COMPLETE		0x0004
79 #define	INT_RX_COMPLETE		0x0010
80 #define	INT_RX_EARLY		0x0020
81 #define	INT_REQUESTED		0x0040
82 #define	INT_STATS		0x0080
83 #define	INT_LINK		0x0100	/* NB: most NICs don't implement it! */
84 #define	INT_DN_COMPLETE		0x0200
85 #define	INT_UP_COMPLETE		0x0400
86 #define	STAT_CMD_IN_PROGRESS	0x1000
87 
88 #define	INT_WATCHED							\
89 	(INT_HOST_ERROR | INT_STATS | INT_DN_COMPLETE | INT_UP_COMPLETE)
90 
91 
92 /*
93  * Flat address space registers (outside the windows)
94  */
95 
96 #define	REG_TXPKTID		0x18	/* 90xB only */
97 #define	REG_TIMER		0x1a
98 #define	REG_TXSTATUS		0x1b
99 #define	TXSTATUS_RECLAIM_ERR	0x02
100 #define	TXSTATUS_STATUS_OFLOW	0x04	/* bad news! */
101 #define	TXSTATUS_MAXCOLLISIONS	0x08
102 #define	TXSTATUS_UNDERRUN	0x10
103 #define	TXSTATUS_JABBER		0x20
104 #define	TXSTATUS_INT_REQ	0x40
105 #define	TXSTATUS_COMPLETE	0x80
106 #define	TXSTATUS_ERRS		0x32
107 
108 #define	REG_INTSTATUSAUTO	0x1e
109 #define	REG_DMACTRL		0x20
110 #define	DMACTRL_DNCMPLREQ	0x00000002
111 #define	DMACTRL_DNSTALLED	0x00000004
112 #define	DMACTRL_UPCOMPLETE	0x00000008
113 #define	DMACTRL_DNCOMPLETE	0x00000010
114 #define	DMACTRL_UPRXEAREN	0x00000020
115 #define	DMACTRL_ARNCNTDN	0x00000040
116 #define	DMACTRL_DNINPROG	0x00000080
117 #define	DMACTRL_CNTSPEED	0x00000100
118 #define	DMACTRL_CNTDNMODE	0x00000200
119 #define	DMACTRL_ALTSEQDIS	0x00010000
120 #define	DMACTRL_DEFEATMWI	0x00100000
121 #define	DMACTRL_DEFEATMRL	0x00200000
122 #define	DMACTRL_UPOVERDIS	0x00400000
123 #define	DMACTRL_TARGABORT	0x40000000
124 #define	DMACTRL_MSTRABORT	0x80000000
125 #define	REG_DNLISTPTR		0x24
126 #define	REG_DNBURSTTHRESH	0x2a	/* 90xB only */
127 #define	REG_DNPRIOTHRESH	0x2c	/* 90xB only */
128 #define	REG_DNPOLL		0x2d	/* 90xB only */
129 #define	REG_TXFREETHRESH	0x2f	/* 90x only */
130 #define	REG_UPPKTSTATUS		0x30
131 #define	REG_FREETIMER		0x34
132 #define	REG_COUNTDOWN		0x36
133 #define	REG_UPLISTPTR		0x38
134 #define	REG_UPPRIOTHRESH	0x3c	/* 90xB only */
135 #define	REG_UPPOLL		0x3d	/* 90xB only */
136 #define	REG_UPBURSTTHRESH	0x3e	/* 90xB only */
137 #define	REG_REALTIMECNT		0x40	/* 90xB only */
138 #define	REG_DNMAXBURST		0x78	/* 90xB only */
139 #define	REG_UPMAXBURST		0x7a	/* 90xB only */
140 
141 /*
142  * Window 0.  Eeprom access.
143  */
144 #define	W0_MFG_ID		0x00
145 #define	W0_EE_CMD		0x0a
146 #define	EE_CMD_ADDR		0x001f
147 #define	EE_CMD_WRITE_EN		0x0000
148 #define	EE_CMD_READ		0x0080
149 #define	EE_CMD_READ8		0x0200
150 #define	EE_CMD_BUSY		0x8000
151 #define	W0_EE_DATA		0x0c
152 /*
153  * Window 2.
154  */
155 #define	W2_STATION_ADDRESS	0x00
156 #define	W2_STATION_MASK		0x06
157 #define	W2_RESET_OPTIONS	0x0c		/* Reset options (90xB only) */
158 #define	W2_RESET_OPT_LEDPOLAR	0x0010	/* invert LED polarity */
159 #define	W2_RESET_OPT_PHYPOWER	0x4000	/* turn on PHY power */
160 
161 
162 /*
163  * Window 3.
164  */
165 #define	W3_INTERNAL_CONFIG	0x00	/* 32 bits */
166 #define	W3_MAX_PKT_SIZE		0x04	/* 90xB only */
167 #define	W3_MAC_CONTROL		0x06
168 #define	MAC_CONTROL_FDX		0x0020
169 #define	MAC_CONTROL_ALLOW_LARGE	0x0040
170 #define	MAC_CONTROL_FLOW_EN	0x0100	/* 90xB only */
171 #define	MAC_CONTROL_VLT_EN	0x0200	/* 90xB only */
172 
173 /*
174  * This is reset options for the other cards, media options for
175  * the 90xB NICs. Reset options are in a separate register for
176  * the 90xB.
177  *
178  * Note that these bit values are also the same as the
179  * W3_RESET_OPTIONS media selection bits on 90x NICs, which
180  * conviently occupies the same register, and pretty much is
181  * the same thing.  There are some differences in the upper bits,
182  * but we don't care about those.
183  */
184 #define	W3_MEDIAOPT		0x08
185 #define	MEDIAOPT_100T4		0x0001
186 #define	MEDIAOPT_100TX		0x0002
187 #define	MEDIAOPT_100FX		0x0004
188 #define	MEDIAOPT_10T		0x0008
189 #define	MEDIAOPT_BNC		0x0010
190 #define	MEDIAOPT_AUI		0x0020
191 #define	MEDIAOPT_MII		0x0040
192 #define	MEDIAOPT_10FL		0x0080
193 #define	MEDIAOPT_MASK		0x00ff	/* excludes 10BASEFL */
194 
195 /*
196  * Window 4 registers.
197  */
198 #define	W4_MEDIASTAT		0xa
199 #define	MEDIASTAT_SQE_EN	0x0008
200 #define	MEDIASTAT_JABGUARD_EN	0x0040
201 #define	MEDIASTAT_LINKBEAT_EN	0x0080
202 #define	MEDIASTAT_LINKDETECT	0x0800
203 #define	MEDIASTAT_AUI_DIS	0x8000
204 
205 /*
206  * Window 4, offset 8 is defined for MII/PHY access for EtherLink XL
207  * cards.
208  */
209 #define	W4_PHYSMGMT		0x08
210 #define	PHYSMGMT_CLK		0x0001
211 #define	PHYSMGMT_DATA		0x0002
212 #define	PHYSMGMT_DIR		0x0004
213 
214 /*
215  * Counter in window 4 for packets with a bad start-of-stream delimiter/
216  */
217 #define	W4_BADSSD		0x0c
218 
219 /*
220  * Upper bits of 20-bit byte counters.
221  */
222 #define	W4_UBYTESOK		0x0d
223 
224 /*
225  * W6 registers, used for statistics
226  */
227 #define	W6_TX_BYTES		0x0c
228 #define	W6_RX_BYTES		0x0a
229 #define	W6_UPPER_FRAMES		0x09
230 #define	W6_DEFER		0x08
231 #define	W6_RX_FRAMES		0x07
232 #define	W6_TX_FRAMES		0x06
233 #define	W6_RX_OVERRUNS		0x05
234 #define	W6_TX_LATE_COL		0x04
235 #define	W6_SINGLE_COL		0x03
236 #define	W6_MULT_COL		0x02
237 #define	W6_SQE_ERRORS		0x01
238 #define	W6_NO_CARRIER		0x00
239 
240 /*
241  * Receive filter bits for use with CMD_SET_FILTER.
242  */
243 #define	FILTER_UNICAST		0x01
244 #define	FILTER_ALLMULTI		0x02
245 #define	FILTER_ALLBCAST		0x04
246 #define	FILTER_PROMISC		0x08
247 #define	FILTER_MULTIHASH	0x10	/* only on 90xB */
248 
249 /*
250  * Window 7 registers. These are different for 90x and 90xB than
251  * for the EtherLink III / Fast EtherLink cards.
252  */
253 
254 #define	W7_VLANMASK	0x00	/* 90xB only */
255 #define	W7_VLANTYPE	0x04	/* 90xB only */
256 #define	W7_TIMER	0x0a	/* 90x only */
257 #define	W7_TX_STATUS	0x0b	/* 90x only */
258 #define	W7_POWEREVENT	0x0c	/* 90xB only */
259 #define	W7_INTSTATUS	0x0e
260 
261 /*
262  * The Internal Config register is different on 90xB cards. The
263  * different masks / shifts are defined here.
264  */
265 
266 /*
267  * Lower 16 bits.
268  */
269 #define	CONFIG_TXLARGE		0x4000
270 #define	CONFIG_TXLARGE_SHIFT	14
271 
272 #define	CONFIG_RXLARGE		0x8000
273 #define	CONFIG_RXLARGE_SHIFT	15
274 
275 /*
276  * Upper 16 bits.
277  */
278 #define	XCVR_SEL_10T		0x00000000U
279 #define	XCVR_SEL_AUI		0x00100000U
280 #define	XCVR_SEL_BNC		0x00300000U
281 #define	XCVR_SEL_100TX		0x00400000U	/* 3com says don't use this! */
282 #define	XCVR_SEL_100FX		0x00500000U
283 #define	XCVR_SEL_MII		0x00600000U
284 #define	XCVR_SEL_AUTO		0x00800000U
285 #define	XCVR_SEL_MASK		0x00f00000U
286 
287 #define	RAM_PARTITION_5_3	0x00000000U
288 #define	RAM_PARTITION_3_1	0x00010000U
289 #define	RAM_PARTITION_1_1	0x00020000U
290 #define	RAM_PARTITION_3_5	0x00030000U
291 #define	RAM_PARTITION_MASK	0x00030000U
292 
293 #define	CONFIG_AUTOSEL		0x0100
294 #define	CONFIG_AUTOSEL_SHIFT	8
295 
296 #define	CONFIG_DISABLEROM	0x0200
297 #define	CONFIG_DISABLEROM_SHIFT	9
298 
299 /*
300  * ID of internal PHY.
301  */
302 
303 #define	INTPHY_ID		24
304 
305 /*
306  * Fragment header as laid out in memory for DMA access.
307  */
308 
309 #define	EX_FR_LENMASK	0x00001fff	/* mask for length in fr_len field */
310 #define	EX_FR_LAST	0x80000000	/* indicates last fragment */
311 
312 /*
313  * 3Com NICs have separate structures for packet upload (receive) and
314  * download (transmit) descriptors.  However, the structures for the
315  * "legacy" transmit format are nearly identical except for the fact
316  * that the third field is named differently and the bit fields are
317  * different.  To maximize code reuse, we use a single type to cover
318  * both uses.  Note that for receive we can arrange these in a loop,
319  * but not for transmit.  Note also that for simplicity, we only use
320  * the "type 0" legacy DPD format -- the features offered by the newer
321  * type 1 format are not something we need.
322  */
323 typedef struct ex_pd {
324 	uint32_t	pd_link;
325 	uint32_t	pd_shared;
326 	uint32_t	pd_addr;
327 	uint32_t	pd_len;
328 } ex_pd_t;
329 #define	pd_fsh		pd_shared
330 #define	pd_status	pd_shared
331 
332 /*
333  * Type 0 Download Packet Descriptor (DPD).  We don't use the other
334  * type, since it isn't supported by older 90x ASICs.
335  */
336 struct ex_dpd {
337 	uint32_t dpd_nextptr;		/* prt to next fragheader */
338 	uint32_t dpd_fsh;		/* frame start header */
339 	uint32_t dpd_addr;
340 	uint32_t dpd_len;
341 };
342 
343 struct ex_upd {
344 	uint32_t upd_nextptr;
345 	uint32_t upd_pktstatus;
346 	uint32_t upd_addr;	/* phys addr of frag */
347 	uint32_t upd_len;	/* length of frag */
348 };
349 
350 #define	DPD_DMADDR(s, t) \
351 	((s)->sc_dpddma + ((char *)((t)->tx_dpd) - (char *)((s)->sc_dpd)))
352 
353 /*
354  * Frame Start Header bitfields.
355  */
356 
357 #define	EX_DPD_DNIND	0x80000000	/* intr on download done */
358 #define	EX_DPD_TXIND	0x00008000	/* intr on tx done */
359 #define	EX_DPD_NOCRC	0x00002000	/* no CRC append */
360 
361 /*
362  * Lower 12 bits are the tx length for the 90x family. The 90xB
363  * assumes that the tx length is the sum of all frame lengths,
364  * and uses the bits as below. It also defines some more bits in
365  * the upper part.
366  */
367 #define	EX_DPD_EMPTY	0x20000000	/* no data in this DPD */
368 #define	EX_DPD_UPDEFEAT	0x10000000	/* don't round tx lengths up */
369 #define	EX_DPD_UDPCKSUM	0x08000000	/* do hardware UDP checksum */
370 #define	EX_DPD_TCPCKSUM	0x04000000	/* do hardware TCP checksum */
371 #define	EX_DPD_IPCKSUM	0x02000000	/* do hardware IP checksum */
372 #define	EX_DPD_DNCMPLT	0x01000000	/* packet has been downloaded */
373 #define	EX_DPD_IDMASK	0x000003fc	/* mask for packet id */
374 #define	EX_DPD_IDSHIFT	2
375 #define	EX_DPD_RNDMASK	0x00000003	/* mask for rounding */
376 					/* 0 -> dword, 2 -> word, 1,3 -> none */
377 /*
378  * upd_pktstatus bitfields.
379  * The *CKSUMERR fields are only valid if the matching *CHECKED field
380  * is set.
381  */
382 #define	EX_UPD_PKTLENMASK	0x00001fff	/* 12:0 -> packet length */
383 #define	EX_UPD_ERROR		0x00004000	/* rcv error */
384 #define	EX_UPD_COMPLETE		0x00008000	/* rcv complete */
385 #define	EX_UPD_OVERRUN		0x00010000	/* rcv overrun */
386 #define	EX_UPD_RUNT		0x00020000	/* pkt < 60 bytes */
387 #define	EX_UPD_ALIGNERR		0x00040000	/* alignment error */
388 #define	EX_UPD_CRCERR		0x00080000	/* CRC error */
389 #define	EX_UPD_OVERSIZED	0x00100000	/* oversize frame */
390 #define	EX_UPD_DRIBBLEBITS	0x00800000	/* pkt had dribble bits */
391 #define	EX_UPD_OVERFLOW		0x01000000	/* insufficient space for pkt */
392 #define	EX_UPD_IPCKSUMERR	0x02000000	/* IP cksum error (90xB) */
393 #define	EX_UPD_TCPCKSUMERR	0x04000000	/* TCP cksum error (90xB) */
394 #define	EX_UPD_UDPCKSUMERR	0x08000000	/* UDP cksum error (90xB) */
395 #define	EX_UPD_IPCHECKED	0x20000000	/* IP cksum done */
396 #define	EX_UPD_TCPCHECKED	0x40000000	/* TCP cksum done */
397 #define	EX_UPD_UDPCHECKED	0x80000000	/* UDP cksum done */
398 
399 #define	EX_UPD_ERR		0x001f4000	/* Errors we check for */
400 #define	EX_UPD_ERR_VLAN		0x000f0000	/* same for 802.1q */
401 
402 #define	EX_UPD_CKSUMERR		0x0e000000	/* any IP checksum error */
403 
404 /*
405  * EEPROM offsets.  These are 16-bit word addresses.  There are a lot of
406  * other things in here, but we only care about the OEM address.
407  */
408 #define	EE_3COM_ADDR_0		0x00
409 #define	EE_3COM_ADDR_1		0x01
410 #define	EE_3COM_ADDR_2		0x02
411 #define	EE_OEM_ADDR_0		0x0a
412 #define	EE_OEM_ADDR_1		0x0b
413 #define	EE_OEM_ADDR_2		0x0c
414 #define	EE_CAPABILITIES		0x10
415 
416 #define	EX_NTX		256
417 #define	EX_NRX		128
418 #define	EX_BUFSZ	1536
419 
420 typedef struct ex_desc {
421 	struct ex_desc		*ed_next;
422 	struct ex_desc		*ed_prev;
423 	ddi_dma_handle_t	ed_dmah;
424 	ddi_acc_handle_t	ed_acch;
425 	caddr_t			ed_buf;
426 	uint32_t		ed_bufaddr;
427 	uint32_t		ed_descaddr;
428 	uint32_t		ed_off;		/* offset of pd */
429 	ex_pd_t			*ed_pd;
430 } ex_desc_t;
431 
432 typedef struct ex_ring {
433 	int			r_count;
434 	int			r_avail;
435 	ddi_dma_handle_t	r_dmah;
436 	ddi_acc_handle_t	r_acch;
437 	uint32_t		r_paddr;
438 	ex_pd_t			*r_pd;
439 	ex_desc_t		*r_desc;
440 	ex_desc_t		*r_head;
441 	ex_desc_t		*r_tail;
442 } ex_ring_t;
443 
444 /*
445  * Higher level linked list of upload packet descriptors.
446  */
447 struct ex_rxdesc {
448 	ddi_dma_handle_t	rx_dmah;
449 	ddi_acc_handle_t	rx_acch;
450 	caddr_t			rx_buf;
451 	uint32_t		rx_paddr;
452 	struct ex_upd		*rx_upd;
453 };
454 
455 /*
456  * Ethernet software status per interface.
457  */
458 typedef struct ex_softc {
459 	dev_info_t		*ex_dip;
460 	mac_handle_t		ex_mach;
461 	mii_handle_t		ex_miih;
462 	ddi_periodic_t		ex_linkcheck;
463 
464 	ddi_acc_handle_t	ex_pcih;
465 	ddi_acc_handle_t	ex_regsh;
466 	caddr_t			ex_regsva;
467 
468 	kmutex_t		ex_txlock;
469 	kmutex_t		ex_intrlock;
470 
471 	ddi_intr_handle_t	ex_intrh;
472 
473 	uint8_t			ex_curraddr[6];
474 	uint8_t			ex_factaddr[6];
475 	boolean_t		ex_promisc;
476 	unsigned		ex_mccount;
477 
478 	boolean_t		ex_running;
479 	boolean_t		ex_suspended;
480 
481 	ex_ring_t		ex_rxring;
482 	ex_ring_t		ex_txring;
483 
484 	uint32_t		ex_xcvr;
485 	uint32_t		ex_speed;
486 	link_duplex_t		ex_duplex;
487 	boolean_t		ex_fdx;
488 	link_state_t		ex_link;
489 	boolean_t		ex_mii_active;
490 	uint32_t		ex_mediaopt;
491 	char			ex_medias[128];
492 	uint16_t		ex_capab;
493 
494 	/*
495 	 * Kstats.
496 	 */
497 	uint64_t		ex_ipackets;
498 	uint64_t		ex_opackets;
499 	uint64_t		ex_ibytes;
500 	uint64_t		ex_obytes;
501 	uint64_t		ex_brdcstrcv;
502 	uint64_t		ex_multircv;
503 	uint64_t		ex_brdcstxmt;
504 	uint64_t		ex_multixmt;
505 	unsigned		ex_toolong;
506 	unsigned		ex_runt;
507 	unsigned		ex_oflo;
508 	unsigned		ex_fcs;
509 	unsigned		ex_align;
510 	unsigned		ex_allocbfail;
511 	unsigned		ex_txerr;
512 	unsigned		ex_uflo;
513 	unsigned		ex_jabber;
514 	unsigned		ex_excoll;
515 	unsigned		ex_sqe;
516 	unsigned		ex_nocarrier;
517 	unsigned		ex_multcol;
518 	unsigned		ex_defer;
519 	unsigned		ex_latecol;
520 	unsigned		ex_singlecol;
521 
522 	uint_t			ex_conf;	/* config flags */
523 
524 #define	CONF_INTPHY		0x0001	/* has internal PHY at address 24 */
525 #define	CONF_90XB		0x0002	/* is 90xB */
526 
527 } elxl_t;
528 
529 #define	WAIT_CMD(sc) \
530 	{ \
531 		int stat; \
532 		do { \
533 			stat = GET16(REG_CMD_STAT); \
534 		} while ((stat & STAT_CMD_IN_PROGRESS) && (stat != 0xffff)); \
535 	}
536 
537 #define	GET8(off)	\
538 	ddi_get8(sc->ex_regsh, (void *)(sc->ex_regsva + (off)))
539 #define	GET16(off)	\
540 	ddi_get16(sc->ex_regsh, (void *)(sc->ex_regsva + (off)))
541 #define	GET32(off)	\
542 	ddi_get32(sc->ex_regsh, (void *)(sc->ex_regsva + (off)))
543 #define	PUT8(off, val)	\
544 	ddi_put8(sc->ex_regsh, (void *)(sc->ex_regsva + (off)), val)
545 #define	PUT16(off, val)	\
546 	ddi_put16(sc->ex_regsh, (void *)(sc->ex_regsva + (off)), val)
547 #define	PUT32(off, val)	\
548 	ddi_put32(sc->ex_regsh, (void *)(sc->ex_regsva + (off)), val)
549 
550 #define	SET16(off, val)	PUT16(off, GET16(off) | val)
551 #define	CLR16(off, val)	PUT16(off, GET16(off) & ~(val))
552 
553 #define	PUT_CMD(x)	PUT16(REG_CMD_STAT, (x))
554 #define	SET_WIN(x)	PUT16(REG_CMD_STAT, CMD_SELECT_WINDOW | (x))
555 
556 #define	PUT_PD(ring, member, val)	ddi_put32(ring->r_acch, &member, (val))
557 #define	GET_PD(ring, member)		ddi_get32(ring->r_acch, &member)
558 
559 #endif	/* ELXL_H */
560