blob: 466eddea025153e8d427431a260e3a411835f2cc [file] [log] [blame]
Garrett D'Amore69b3e102010-02-19 13:29:31 -08001/*
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 */
323typedef 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 */
336struct 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
343struct 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
420typedef 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
432typedef 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 */
447struct 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 */
458typedef 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 */