Merge remote-tracking branch 'origin/master'
[unleashed/lotheac.git] / usr / src / uts / common / io / elxl / elxl.h
blob466eddea025153e8d427431a260e3a411835f2cc
1 /*
2 * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
3 * Use is subject to license terms.
4 */
6 /*
7 * Copyright (c) 1998 The NetBSD Foundation, Inc.
8 * All rights reserved.
10 * This code is derived from software contributed to The NetBSD Foundation
11 * by Frank van der Linden.
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.
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.
36 #ifndef ELXL_H
37 #define ELXL_H
40 * This file defines the registers specific to the EtherLink XL family
41 * of NICs.
44 #define REG_CMD_STAT 0x0e /* Write command, read status */
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
74 * Defines for the interrupt status register
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
88 #define INT_WATCHED \
89 (INT_HOST_ERROR | INT_STATS | INT_DN_COMPLETE | INT_UP_COMPLETE)
93 * Flat address space registers (outside the windows)
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
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 */
142 * Window 0. Eeprom access.
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
153 * Window 2.
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 */
163 * Window 3.
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 */
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.
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.
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 */
196 * Window 4 registers.
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
206 * Window 4, offset 8 is defined for MII/PHY access for EtherLink XL
207 * cards.
209 #define W4_PHYSMGMT 0x08
210 #define PHYSMGMT_CLK 0x0001
211 #define PHYSMGMT_DATA 0x0002
212 #define PHYSMGMT_DIR 0x0004
215 * Counter in window 4 for packets with a bad start-of-stream delimiter/
217 #define W4_BADSSD 0x0c
220 * Upper bits of 20-bit byte counters.
222 #define W4_UBYTESOK 0x0d
225 * W6 registers, used for statistics
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
241 * Receive filter bits for use with CMD_SET_FILTER.
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 */
250 * Window 7 registers. These are different for 90x and 90xB than
251 * for the EtherLink III / Fast EtherLink cards.
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
262 * The Internal Config register is different on 90xB cards. The
263 * different masks / shifts are defined here.
267 * Lower 16 bits.
269 #define CONFIG_TXLARGE 0x4000
270 #define CONFIG_TXLARGE_SHIFT 14
272 #define CONFIG_RXLARGE 0x8000
273 #define CONFIG_RXLARGE_SHIFT 15
276 * Upper 16 bits.
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
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
293 #define CONFIG_AUTOSEL 0x0100
294 #define CONFIG_AUTOSEL_SHIFT 8
296 #define CONFIG_DISABLEROM 0x0200
297 #define CONFIG_DISABLEROM_SHIFT 9
300 * ID of internal PHY.
303 #define INTPHY_ID 24
306 * Fragment header as laid out in memory for DMA access.
309 #define EX_FR_LENMASK 0x00001fff /* mask for length in fr_len field */
310 #define EX_FR_LAST 0x80000000 /* indicates last fragment */
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.
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
333 * Type 0 Download Packet Descriptor (DPD). We don't use the other
334 * type, since it isn't supported by older 90x ASICs.
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;
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 */
350 #define DPD_DMADDR(s, t) \
351 ((s)->sc_dpddma + ((char *)((t)->tx_dpd) - (char *)((s)->sc_dpd)))
354 * Frame Start Header bitfields.
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 */
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.
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 */
378 * upd_pktstatus bitfields.
379 * The *CKSUMERR fields are only valid if the matching *CHECKED field
380 * is set.
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 */
399 #define EX_UPD_ERR 0x001f4000 /* Errors we check for */
400 #define EX_UPD_ERR_VLAN 0x000f0000 /* same for 802.1q */
402 #define EX_UPD_CKSUMERR 0x0e000000 /* any IP checksum error */
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.
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
416 #define EX_NTX 256
417 #define EX_NRX 128
418 #define EX_BUFSZ 1536
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;
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;
445 * Higher level linked list of upload packet descriptors.
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;
456 * Ethernet software status per interface.
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;
464 ddi_acc_handle_t ex_pcih;
465 ddi_acc_handle_t ex_regsh;
466 caddr_t ex_regsva;
468 kmutex_t ex_txlock;
469 kmutex_t ex_intrlock;
471 ddi_intr_handle_t ex_intrh;
473 uint8_t ex_curraddr[6];
474 uint8_t ex_factaddr[6];
475 boolean_t ex_promisc;
476 unsigned ex_mccount;
478 boolean_t ex_running;
479 boolean_t ex_suspended;
481 ex_ring_t ex_rxring;
482 ex_ring_t ex_txring;
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;
495 * Kstats.
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;
522 uint_t ex_conf; /* config flags */
524 #define CONF_INTPHY 0x0001 /* has internal PHY at address 24 */
525 #define CONF_90XB 0x0002 /* is 90xB */
527 } elxl_t;
529 #define WAIT_CMD(sc) \
531 int stat; \
532 do { \
533 stat = GET16(REG_CMD_STAT); \
534 } while ((stat & STAT_CMD_IN_PROGRESS) && (stat != 0xffff)); \
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)
550 #define SET16(off, val) PUT16(off, GET16(off) | val)
551 #define CLR16(off, val) PUT16(off, GET16(off) & ~(val))
553 #define PUT_CMD(x) PUT16(REG_CMD_STAT, (x))
554 #define SET_WIN(x) PUT16(REG_CMD_STAT, CMD_SELECT_WINDOW | (x))
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)
559 #endif /* ELXL_H */