Annotation of src/sys/dev/pci/if_sip.c, Revision 1.71
1.71 ! thorpej 1: /* $NetBSD: if_sip.c,v 1.70 2002/09/27 20:40:15 thorpej Exp $ */
1.28 thorpej 2:
3: /*-
1.45 thorpej 4: * Copyright (c) 2001, 2002 The NetBSD Foundation, Inc.
1.28 thorpej 5: * All rights reserved.
6: *
7: * This code is derived from software contributed to The NetBSD Foundation
8: * by Jason R. Thorpe.
9: *
10: * Redistribution and use in source and binary forms, with or without
11: * modification, are permitted provided that the following conditions
12: * are met:
13: * 1. Redistributions of source code must retain the above copyright
14: * notice, this list of conditions and the following disclaimer.
15: * 2. Redistributions in binary form must reproduce the above copyright
16: * notice, this list of conditions and the following disclaimer in the
17: * documentation and/or other materials provided with the distribution.
18: * 3. All advertising materials mentioning features or use of this software
19: * must display the following acknowledgement:
20: * This product includes software developed by the NetBSD
21: * Foundation, Inc. and its contributors.
22: * 4. Neither the name of The NetBSD Foundation nor the names of its
23: * contributors may be used to endorse or promote products derived
24: * from this software without specific prior written permission.
25: *
26: * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
27: * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
28: * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
29: * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
30: * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
31: * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
32: * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
33: * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
34: * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
35: * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
36: * POSSIBILITY OF SUCH DAMAGE.
37: */
1.1 thorpej 38:
39: /*-
40: * Copyright (c) 1999 Network Computer, Inc.
41: * All rights reserved.
42: *
43: * Redistribution and use in source and binary forms, with or without
44: * modification, are permitted provided that the following conditions
45: * are met:
46: * 1. Redistributions of source code must retain the above copyright
47: * notice, this list of conditions and the following disclaimer.
48: * 2. Redistributions in binary form must reproduce the above copyright
49: * notice, this list of conditions and the following disclaimer in the
50: * documentation and/or other materials provided with the distribution.
51: * 3. Neither the name of Network Computer, Inc. nor the names of its
52: * contributors may be used to endorse or promote products derived
53: * from this software without specific prior written permission.
54: *
55: * THIS SOFTWARE IS PROVIDED BY NETWORK COMPUTER, INC. AND CONTRIBUTORS
56: * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
57: * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
58: * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
59: * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
60: * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
61: * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
62: * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
63: * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
64: * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
65: * POSSIBILITY OF SUCH DAMAGE.
66: */
67:
68: /*
1.29 thorpej 69: * Device driver for the Silicon Integrated Systems SiS 900,
70: * SiS 7016 10/100, National Semiconductor DP83815 10/100, and
71: * National Semiconductor DP83820 10/100/1000 PCI Ethernet
72: * controllers.
1.1 thorpej 73: *
1.32 thorpej 74: * Originally written to support the SiS 900 by Jason R. Thorpe for
75: * Network Computer, Inc.
1.29 thorpej 76: *
77: * TODO:
78: *
1.58 thorpej 79: * - Reduce the Rx interrupt load.
1.1 thorpej 80: */
1.43 lukem 81:
82: #include <sys/cdefs.h>
1.71 ! thorpej 83: __KERNEL_RCSID(0, "$NetBSD: if_sip.c,v 1.70 2002/09/27 20:40:15 thorpej Exp $");
1.1 thorpej 84:
85: #include "bpfilter.h"
1.65 itojun 86: #include "rnd.h"
1.1 thorpej 87:
88: #include <sys/param.h>
89: #include <sys/systm.h>
1.9 thorpej 90: #include <sys/callout.h>
1.1 thorpej 91: #include <sys/mbuf.h>
92: #include <sys/malloc.h>
93: #include <sys/kernel.h>
94: #include <sys/socket.h>
95: #include <sys/ioctl.h>
96: #include <sys/errno.h>
97: #include <sys/device.h>
98: #include <sys/queue.h>
99:
1.12 mrg 100: #include <uvm/uvm_extern.h> /* for PAGE_SIZE */
1.1 thorpej 101:
1.65 itojun 102: #if NRND > 0
103: #include <sys/rnd.h>
104: #endif
105:
1.1 thorpej 106: #include <net/if.h>
107: #include <net/if_dl.h>
108: #include <net/if_media.h>
109: #include <net/if_ether.h>
110:
111: #if NBPFILTER > 0
112: #include <net/bpf.h>
113: #endif
114:
115: #include <machine/bus.h>
116: #include <machine/intr.h>
1.14 tsutsui 117: #include <machine/endian.h>
1.1 thorpej 118:
1.15 thorpej 119: #include <dev/mii/mii.h>
1.1 thorpej 120: #include <dev/mii/miivar.h>
1.29 thorpej 121: #ifdef DP83820
122: #include <dev/mii/mii_bitbang.h>
123: #endif /* DP83820 */
1.1 thorpej 124:
125: #include <dev/pci/pcireg.h>
126: #include <dev/pci/pcivar.h>
127: #include <dev/pci/pcidevs.h>
128:
129: #include <dev/pci/if_sipreg.h>
130:
1.29 thorpej 131: #ifdef DP83820 /* DP83820 Gigabit Ethernet */
132: #define SIP_DECL(x) __CONCAT(gsip_,x)
133: #else /* SiS900 and DP83815 */
1.28 thorpej 134: #define SIP_DECL(x) __CONCAT(sip_,x)
1.29 thorpej 135: #endif
136:
1.28 thorpej 137: #define SIP_STR(x) __STRING(SIP_DECL(x))
138:
1.1 thorpej 139: /*
140: * Transmit descriptor list size. This is arbitrary, but allocate
1.30 thorpej 141: * enough descriptors for 128 pending transmissions, and 8 segments
1.1 thorpej 142: * per packet. This MUST work out to a power of 2.
143: */
1.52 thorpej 144: #define SIP_NTXSEGS 16
145: #define SIP_NTXSEGS_ALLOC 8
1.1 thorpej 146:
1.30 thorpej 147: #define SIP_TXQUEUELEN 256
1.52 thorpej 148: #define SIP_NTXDESC (SIP_TXQUEUELEN * SIP_NTXSEGS_ALLOC)
1.1 thorpej 149: #define SIP_NTXDESC_MASK (SIP_NTXDESC - 1)
150: #define SIP_NEXTTX(x) (((x) + 1) & SIP_NTXDESC_MASK)
151:
1.46 thorpej 152: #if defined(DP83020)
153: #define TX_DMAMAP_SIZE ETHER_MAX_LEN_JUMBO
154: #else
155: #define TX_DMAMAP_SIZE MCLBYTES
156: #endif
157:
1.1 thorpej 158: /*
159: * Receive descriptor list size. We have one Rx buffer per incoming
160: * packet, so this logic is a little simpler.
1.36 thorpej 161: *
162: * Actually, on the DP83820, we allow the packet to consume more than
163: * one buffer, in order to support jumbo Ethernet frames. In that
164: * case, a packet may consume up to 5 buffers (assuming a 2048 byte
165: * mbuf cluster). 256 receive buffers is only 51 maximum size packets,
166: * so we'd better be quick about handling receive interrupts.
1.1 thorpej 167: */
1.36 thorpej 168: #if defined(DP83820)
169: #define SIP_NRXDESC 256
170: #else
1.30 thorpej 171: #define SIP_NRXDESC 128
1.36 thorpej 172: #endif /* DP83820 */
1.1 thorpej 173: #define SIP_NRXDESC_MASK (SIP_NRXDESC - 1)
174: #define SIP_NEXTRX(x) (((x) + 1) & SIP_NRXDESC_MASK)
175:
176: /*
177: * Control structures are DMA'd to the SiS900 chip. We allocate them in
178: * a single clump that maps to a single DMA segment to make several things
179: * easier.
180: */
181: struct sip_control_data {
182: /*
183: * The transmit descriptors.
184: */
185: struct sip_desc scd_txdescs[SIP_NTXDESC];
186:
187: /*
188: * The receive descriptors.
189: */
190: struct sip_desc scd_rxdescs[SIP_NRXDESC];
191: };
192:
193: #define SIP_CDOFF(x) offsetof(struct sip_control_data, x)
194: #define SIP_CDTXOFF(x) SIP_CDOFF(scd_txdescs[(x)])
195: #define SIP_CDRXOFF(x) SIP_CDOFF(scd_rxdescs[(x)])
196:
197: /*
198: * Software state for transmit jobs.
199: */
200: struct sip_txsoft {
201: struct mbuf *txs_mbuf; /* head of our mbuf chain */
202: bus_dmamap_t txs_dmamap; /* our DMA map */
203: int txs_firstdesc; /* first descriptor in packet */
204: int txs_lastdesc; /* last descriptor in packet */
205: SIMPLEQ_ENTRY(sip_txsoft) txs_q;
206: };
207:
208: SIMPLEQ_HEAD(sip_txsq, sip_txsoft);
209:
210: /*
211: * Software state for receive jobs.
212: */
213: struct sip_rxsoft {
214: struct mbuf *rxs_mbuf; /* head of our mbuf chain */
215: bus_dmamap_t rxs_dmamap; /* our DMA map */
216: };
217:
218: /*
219: * Software state per device.
220: */
221: struct sip_softc {
222: struct device sc_dev; /* generic device information */
223: bus_space_tag_t sc_st; /* bus space tag */
224: bus_space_handle_t sc_sh; /* bus space handle */
225: bus_dma_tag_t sc_dmat; /* bus DMA tag */
226: struct ethercom sc_ethercom; /* ethernet common data */
227: void *sc_sdhook; /* shutdown hook */
1.15 thorpej 228:
229: const struct sip_product *sc_model; /* which model are we? */
1.45 thorpej 230: int sc_rev; /* chip revision */
1.1 thorpej 231:
232: void *sc_ih; /* interrupt cookie */
233:
234: struct mii_data sc_mii; /* MII/media information */
235:
1.9 thorpej 236: struct callout sc_tick_ch; /* tick callout */
237:
1.1 thorpej 238: bus_dmamap_t sc_cddmamap; /* control data DMA map */
239: #define sc_cddma sc_cddmamap->dm_segs[0].ds_addr
240:
241: /*
242: * Software state for transmit and receive descriptors.
243: */
244: struct sip_txsoft sc_txsoft[SIP_TXQUEUELEN];
245: struct sip_rxsoft sc_rxsoft[SIP_NRXDESC];
246:
247: /*
248: * Control data structures.
249: */
250: struct sip_control_data *sc_control_data;
251: #define sc_txdescs sc_control_data->scd_txdescs
252: #define sc_rxdescs sc_control_data->scd_rxdescs
253:
1.30 thorpej 254: #ifdef SIP_EVENT_COUNTERS
255: /*
256: * Event counters.
257: */
258: struct evcnt sc_ev_txsstall; /* Tx stalled due to no txs */
259: struct evcnt sc_ev_txdstall; /* Tx stalled due to no txd */
1.56 thorpej 260: struct evcnt sc_ev_txforceintr; /* Tx interrupts forced */
261: struct evcnt sc_ev_txdintr; /* Tx descriptor interrupts */
262: struct evcnt sc_ev_txiintr; /* Tx idle interrupts */
1.30 thorpej 263: struct evcnt sc_ev_rxintr; /* Rx interrupts */
1.62 thorpej 264: struct evcnt sc_ev_hiberr; /* HIBERR interrupts */
1.31 thorpej 265: #ifdef DP83820
266: struct evcnt sc_ev_rxipsum; /* IP checksums checked in-bound */
267: struct evcnt sc_ev_rxtcpsum; /* TCP checksums checked in-bound */
268: struct evcnt sc_ev_rxudpsum; /* UDP checksums checked in-boudn */
269: struct evcnt sc_ev_txipsum; /* IP checksums comp. out-bound */
270: struct evcnt sc_ev_txtcpsum; /* TCP checksums comp. out-bound */
271: struct evcnt sc_ev_txudpsum; /* UDP checksums comp. out-bound */
272: #endif /* DP83820 */
1.30 thorpej 273: #endif /* SIP_EVENT_COUNTERS */
274:
1.1 thorpej 275: u_int32_t sc_txcfg; /* prototype TXCFG register */
276: u_int32_t sc_rxcfg; /* prototype RXCFG register */
277: u_int32_t sc_imr; /* prototype IMR register */
278: u_int32_t sc_rfcr; /* prototype RFCR register */
279:
1.29 thorpej 280: u_int32_t sc_cfg; /* prototype CFG register */
281:
282: #ifdef DP83820
283: u_int32_t sc_gpior; /* prototype GPIOR register */
284: #endif /* DP83820 */
285:
1.1 thorpej 286: u_int32_t sc_tx_fill_thresh; /* transmit fill threshold */
287: u_int32_t sc_tx_drain_thresh; /* transmit drain threshold */
288:
289: u_int32_t sc_rx_drain_thresh; /* receive drain threshold */
290:
291: int sc_flags; /* misc. flags; see below */
292:
293: int sc_txfree; /* number of free Tx descriptors */
294: int sc_txnext; /* next ready Tx descriptor */
1.56 thorpej 295: int sc_txwin; /* Tx descriptors since last intr */
1.1 thorpej 296:
297: struct sip_txsq sc_txfreeq; /* free Tx descsofts */
298: struct sip_txsq sc_txdirtyq; /* dirty Tx descsofts */
299:
300: int sc_rxptr; /* next ready Rx descriptor/descsoft */
1.36 thorpej 301: #if defined(DP83820)
302: int sc_rxdiscard;
303: int sc_rxlen;
304: struct mbuf *sc_rxhead;
305: struct mbuf *sc_rxtail;
306: struct mbuf **sc_rxtailp;
307: #endif /* DP83820 */
1.65 itojun 308:
309: #if NRND > 0
310: rndsource_element_t rnd_source; /* random source */
311: #endif
1.1 thorpej 312: };
313:
314: /* sc_flags */
315: #define SIPF_PAUSED 0x00000001 /* paused (802.3x flow control) */
316:
1.36 thorpej 317: #ifdef DP83820
318: #define SIP_RXCHAIN_RESET(sc) \
319: do { \
320: (sc)->sc_rxtailp = &(sc)->sc_rxhead; \
321: *(sc)->sc_rxtailp = NULL; \
322: (sc)->sc_rxlen = 0; \
323: } while (/*CONSTCOND*/0)
324:
325: #define SIP_RXCHAIN_LINK(sc, m) \
326: do { \
1.40 thorpej 327: *(sc)->sc_rxtailp = (sc)->sc_rxtail = (m); \
1.36 thorpej 328: (sc)->sc_rxtailp = &(m)->m_next; \
329: } while (/*CONSTCOND*/0)
330: #endif /* DP83820 */
331:
1.30 thorpej 332: #ifdef SIP_EVENT_COUNTERS
333: #define SIP_EVCNT_INCR(ev) (ev)->ev_count++
334: #else
335: #define SIP_EVCNT_INCR(ev) /* nothing */
336: #endif
337:
1.1 thorpej 338: #define SIP_CDTXADDR(sc, x) ((sc)->sc_cddma + SIP_CDTXOFF((x)))
339: #define SIP_CDRXADDR(sc, x) ((sc)->sc_cddma + SIP_CDRXOFF((x)))
340:
341: #define SIP_CDTXSYNC(sc, x, n, ops) \
342: do { \
343: int __x, __n; \
344: \
345: __x = (x); \
346: __n = (n); \
347: \
348: /* If it will wrap around, sync to the end of the ring. */ \
349: if ((__x + __n) > SIP_NTXDESC) { \
350: bus_dmamap_sync((sc)->sc_dmat, (sc)->sc_cddmamap, \
351: SIP_CDTXOFF(__x), sizeof(struct sip_desc) * \
352: (SIP_NTXDESC - __x), (ops)); \
353: __n -= (SIP_NTXDESC - __x); \
354: __x = 0; \
355: } \
356: \
357: /* Now sync whatever is left. */ \
358: bus_dmamap_sync((sc)->sc_dmat, (sc)->sc_cddmamap, \
359: SIP_CDTXOFF(__x), sizeof(struct sip_desc) * __n, (ops)); \
360: } while (0)
361:
362: #define SIP_CDRXSYNC(sc, x, ops) \
363: bus_dmamap_sync((sc)->sc_dmat, (sc)->sc_cddmamap, \
364: SIP_CDRXOFF((x)), sizeof(struct sip_desc), (ops))
365:
1.31 thorpej 366: #ifdef DP83820
367: #define SIP_INIT_RXDESC_EXTSTS __sipd->sipd_extsts = 0;
1.36 thorpej 368: #define SIP_RXBUF_LEN (MCLBYTES - 4)
1.31 thorpej 369: #else
370: #define SIP_INIT_RXDESC_EXTSTS /* nothing */
1.36 thorpej 371: #define SIP_RXBUF_LEN (MCLBYTES - 1) /* field width */
1.31 thorpej 372: #endif
1.1 thorpej 373: #define SIP_INIT_RXDESC(sc, x) \
374: do { \
375: struct sip_rxsoft *__rxs = &(sc)->sc_rxsoft[(x)]; \
376: struct sip_desc *__sipd = &(sc)->sc_rxdescs[(x)]; \
377: \
1.36 thorpej 378: __sipd->sipd_link = \
379: htole32(SIP_CDRXADDR((sc), SIP_NEXTRX((x)))); \
380: __sipd->sipd_bufptr = \
381: htole32(__rxs->rxs_dmamap->dm_segs[0].ds_addr); \
1.14 tsutsui 382: __sipd->sipd_cmdsts = htole32(CMDSTS_INTR | \
1.36 thorpej 383: (SIP_RXBUF_LEN & CMDSTS_SIZE_MASK)); \
1.31 thorpej 384: SIP_INIT_RXDESC_EXTSTS \
1.1 thorpej 385: SIP_CDRXSYNC((sc), (x), BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE); \
386: } while (0)
387:
1.45 thorpej 388: #define SIP_CHIP_VERS(sc, v, p, r) \
389: ((sc)->sc_model->sip_vendor == (v) && \
390: (sc)->sc_model->sip_product == (p) && \
391: (sc)->sc_rev == (r))
392:
393: #define SIP_CHIP_MODEL(sc, v, p) \
394: ((sc)->sc_model->sip_vendor == (v) && \
395: (sc)->sc_model->sip_product == (p))
396:
397: #if !defined(DP83820)
398: #define SIP_SIS900_REV(sc, rev) \
399: SIP_CHIP_VERS((sc), PCI_VENDOR_SIS, PCI_PRODUCT_SIS_900, (rev))
400: #endif
401:
1.14 tsutsui 402: #define SIP_TIMEOUT 1000
403:
1.28 thorpej 404: void SIP_DECL(start)(struct ifnet *);
405: void SIP_DECL(watchdog)(struct ifnet *);
406: int SIP_DECL(ioctl)(struct ifnet *, u_long, caddr_t);
407: int SIP_DECL(init)(struct ifnet *);
408: void SIP_DECL(stop)(struct ifnet *, int);
1.1 thorpej 409:
1.28 thorpej 410: void SIP_DECL(shutdown)(void *);
1.1 thorpej 411:
1.28 thorpej 412: void SIP_DECL(reset)(struct sip_softc *);
413: void SIP_DECL(rxdrain)(struct sip_softc *);
414: int SIP_DECL(add_rxbuf)(struct sip_softc *, int);
415: void SIP_DECL(read_eeprom)(struct sip_softc *, int, int, u_int16_t *);
416: void SIP_DECL(tick)(void *);
1.1 thorpej 417:
1.29 thorpej 418: #if !defined(DP83820)
1.28 thorpej 419: void SIP_DECL(sis900_set_filter)(struct sip_softc *);
1.29 thorpej 420: #endif /* ! DP83820 */
1.28 thorpej 421: void SIP_DECL(dp83815_set_filter)(struct sip_softc *);
1.15 thorpej 422:
1.29 thorpej 423: #if defined(DP83820)
1.44 thorpej 424: void SIP_DECL(dp83820_read_macaddr)(struct sip_softc *,
425: const struct pci_attach_args *, u_int8_t *);
1.29 thorpej 426: #else
1.44 thorpej 427: void SIP_DECL(sis900_read_macaddr)(struct sip_softc *,
428: const struct pci_attach_args *, u_int8_t *);
429: void SIP_DECL(dp83815_read_macaddr)(struct sip_softc *,
430: const struct pci_attach_args *, u_int8_t *);
1.29 thorpej 431: #endif /* DP83820 */
1.25 briggs 432:
1.28 thorpej 433: int SIP_DECL(intr)(void *);
434: void SIP_DECL(txintr)(struct sip_softc *);
435: void SIP_DECL(rxintr)(struct sip_softc *);
1.1 thorpej 436:
1.29 thorpej 437: #if defined(DP83820)
438: int SIP_DECL(dp83820_mii_readreg)(struct device *, int, int);
439: void SIP_DECL(dp83820_mii_writereg)(struct device *, int, int, int);
440: void SIP_DECL(dp83820_mii_statchg)(struct device *);
441: #else
1.28 thorpej 442: int SIP_DECL(sis900_mii_readreg)(struct device *, int, int);
443: void SIP_DECL(sis900_mii_writereg)(struct device *, int, int, int);
444: void SIP_DECL(sis900_mii_statchg)(struct device *);
1.15 thorpej 445:
1.28 thorpej 446: int SIP_DECL(dp83815_mii_readreg)(struct device *, int, int);
447: void SIP_DECL(dp83815_mii_writereg)(struct device *, int, int, int);
448: void SIP_DECL(dp83815_mii_statchg)(struct device *);
1.29 thorpej 449: #endif /* DP83820 */
1.1 thorpej 450:
1.28 thorpej 451: int SIP_DECL(mediachange)(struct ifnet *);
452: void SIP_DECL(mediastatus)(struct ifnet *, struct ifmediareq *);
1.1 thorpej 453:
1.28 thorpej 454: int SIP_DECL(match)(struct device *, struct cfdata *, void *);
455: void SIP_DECL(attach)(struct device *, struct device *, void *);
1.1 thorpej 456:
1.28 thorpej 457: int SIP_DECL(copy_small) = 0;
1.2 thorpej 458:
1.71 ! thorpej 459: #ifdef DP83820
! 460: CFATTACH_DECL(gsip, sizeof(struct sip_softc),
! 461: gsip_match, gsip_attach, NULL, NULL)
! 462: #else
! 463: CFATTACH_DECL(sip, sizeof(struct sip_softc),
! 464: sip_match, sip_attach, NULL, NULL)
! 465: #endif
1.1 thorpej 466:
1.15 thorpej 467: /*
468: * Descriptions of the variants of the SiS900.
469: */
470: struct sip_variant {
1.28 thorpej 471: int (*sipv_mii_readreg)(struct device *, int, int);
472: void (*sipv_mii_writereg)(struct device *, int, int, int);
473: void (*sipv_mii_statchg)(struct device *);
474: void (*sipv_set_filter)(struct sip_softc *);
1.44 thorpej 475: void (*sipv_read_macaddr)(struct sip_softc *,
476: const struct pci_attach_args *, u_int8_t *);
1.15 thorpej 477: };
478:
1.29 thorpej 479: #if defined(DP83820)
480: u_int32_t SIP_DECL(dp83820_mii_bitbang_read)(struct device *);
481: void SIP_DECL(dp83820_mii_bitbang_write)(struct device *, u_int32_t);
482:
483: const struct mii_bitbang_ops SIP_DECL(dp83820_mii_bitbang_ops) = {
484: SIP_DECL(dp83820_mii_bitbang_read),
485: SIP_DECL(dp83820_mii_bitbang_write),
486: {
487: EROMAR_MDIO, /* MII_BIT_MDO */
488: EROMAR_MDIO, /* MII_BIT_MDI */
489: EROMAR_MDC, /* MII_BIT_MDC */
490: EROMAR_MDDIR, /* MII_BIT_DIR_HOST_PHY */
491: 0, /* MII_BIT_DIR_PHY_HOST */
492: }
493: };
494: #endif /* DP83820 */
495:
496: #if defined(DP83820)
497: const struct sip_variant SIP_DECL(variant_dp83820) = {
498: SIP_DECL(dp83820_mii_readreg),
499: SIP_DECL(dp83820_mii_writereg),
500: SIP_DECL(dp83820_mii_statchg),
501: SIP_DECL(dp83815_set_filter),
502: SIP_DECL(dp83820_read_macaddr),
503: };
504: #else
1.28 thorpej 505: const struct sip_variant SIP_DECL(variant_sis900) = {
506: SIP_DECL(sis900_mii_readreg),
507: SIP_DECL(sis900_mii_writereg),
508: SIP_DECL(sis900_mii_statchg),
509: SIP_DECL(sis900_set_filter),
510: SIP_DECL(sis900_read_macaddr),
1.15 thorpej 511: };
512:
1.28 thorpej 513: const struct sip_variant SIP_DECL(variant_dp83815) = {
514: SIP_DECL(dp83815_mii_readreg),
515: SIP_DECL(dp83815_mii_writereg),
516: SIP_DECL(dp83815_mii_statchg),
517: SIP_DECL(dp83815_set_filter),
518: SIP_DECL(dp83815_read_macaddr),
1.15 thorpej 519: };
1.29 thorpej 520: #endif /* DP83820 */
1.15 thorpej 521:
522: /*
523: * Devices supported by this driver.
524: */
525: const struct sip_product {
526: pci_vendor_id_t sip_vendor;
527: pci_product_id_t sip_product;
528: const char *sip_name;
529: const struct sip_variant *sip_variant;
1.28 thorpej 530: } SIP_DECL(products)[] = {
1.29 thorpej 531: #if defined(DP83820)
532: { PCI_VENDOR_NS, PCI_PRODUCT_NS_DP83820,
533: "NatSemi DP83820 Gigabit Ethernet",
534: &SIP_DECL(variant_dp83820) },
535: #else
1.15 thorpej 536: { PCI_VENDOR_SIS, PCI_PRODUCT_SIS_900,
537: "SiS 900 10/100 Ethernet",
1.28 thorpej 538: &SIP_DECL(variant_sis900) },
1.15 thorpej 539: { PCI_VENDOR_SIS, PCI_PRODUCT_SIS_7016,
540: "SiS 7016 10/100 Ethernet",
1.28 thorpej 541: &SIP_DECL(variant_sis900) },
1.15 thorpej 542:
543: { PCI_VENDOR_NS, PCI_PRODUCT_NS_DP83815,
544: "NatSemi DP83815 10/100 Ethernet",
1.28 thorpej 545: &SIP_DECL(variant_dp83815) },
1.29 thorpej 546: #endif /* DP83820 */
1.15 thorpej 547:
548: { 0, 0,
549: NULL,
550: NULL },
551: };
552:
1.28 thorpej 553: static const struct sip_product *
1.29 thorpej 554: SIP_DECL(lookup)(const struct pci_attach_args *pa)
1.1 thorpej 555: {
556: const struct sip_product *sip;
557:
1.29 thorpej 558: for (sip = SIP_DECL(products); sip->sip_name != NULL; sip++) {
1.1 thorpej 559: if (PCI_VENDOR(pa->pa_id) == sip->sip_vendor &&
560: PCI_PRODUCT(pa->pa_id) == sip->sip_product)
561: return (sip);
562: }
563: return (NULL);
564: }
565:
1.60 thorpej 566: #ifdef DP83820
567: /*
568: * I really hate stupid hardware vendors. There's a bit in the EEPROM
569: * which indicates if the card can do 64-bit data transfers. Unfortunately,
570: * several vendors of 32-bit cards fail to clear this bit in the EEPROM,
571: * which means we try to use 64-bit data transfers on those cards if we
572: * happen to be plugged into a 32-bit slot.
573: *
574: * What we do is use this table of cards known to be 64-bit cards. If
575: * you have a 64-bit card who's subsystem ID is not listed in this table,
576: * send the output of "pcictl dump ..." of the device to me so that your
577: * card will use the 64-bit data path when plugged into a 64-bit slot.
578: *
579: * -- Jason R. Thorpe <thorpej@netbsd.org>
580: * June 30, 2002
581: */
582: static int
583: SIP_DECL(check_64bit)(const struct pci_attach_args *pa)
584: {
585: static const struct {
586: pci_vendor_id_t c64_vendor;
587: pci_product_id_t c64_product;
588: } card64[] = {
589: /* Asante GigaNIX */
590: { 0x128a, 0x0002 },
1.61 thorpej 591:
592: /* Accton EN1407-T, Planex GN-1000TE */
593: { 0x1113, 0x1407 },
1.60 thorpej 594:
1.69 thorpej 595: /* Netgear GA-621 */
596: { 0x1385, 0x621a },
597:
1.60 thorpej 598: { 0, 0}
599: };
600: pcireg_t subsys;
601: int i;
602:
603: subsys = pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_SUBSYS_ID_REG);
604:
605: for (i = 0; card64[i].c64_vendor != 0; i++) {
606: if (PCI_VENDOR(subsys) == card64[i].c64_vendor &&
607: PCI_PRODUCT(subsys) == card64[i].c64_product)
608: return (1);
609: }
610:
611: return (0);
612: }
613: #endif /* DP83820 */
614:
1.1 thorpej 615: int
1.29 thorpej 616: SIP_DECL(match)(struct device *parent, struct cfdata *cf, void *aux)
1.1 thorpej 617: {
618: struct pci_attach_args *pa = aux;
619:
1.29 thorpej 620: if (SIP_DECL(lookup)(pa) != NULL)
1.1 thorpej 621: return (1);
622:
623: return (0);
624: }
625:
626: void
1.29 thorpej 627: SIP_DECL(attach)(struct device *parent, struct device *self, void *aux)
1.1 thorpej 628: {
629: struct sip_softc *sc = (struct sip_softc *) self;
630: struct pci_attach_args *pa = aux;
631: struct ifnet *ifp = &sc->sc_ethercom.ec_if;
632: pci_chipset_tag_t pc = pa->pa_pc;
633: pci_intr_handle_t ih;
634: const char *intrstr = NULL;
635: bus_space_tag_t iot, memt;
636: bus_space_handle_t ioh, memh;
637: bus_dma_segment_t seg;
638: int ioh_valid, memh_valid;
639: int i, rseg, error;
640: const struct sip_product *sip;
641: pcireg_t pmode;
1.14 tsutsui 642: u_int8_t enaddr[ETHER_ADDR_LEN];
1.10 mycroft 643: int pmreg;
1.29 thorpej 644: #ifdef DP83820
645: pcireg_t memtype;
646: u_int32_t reg;
647: #endif /* DP83820 */
1.1 thorpej 648:
1.9 thorpej 649: callout_init(&sc->sc_tick_ch);
650:
1.28 thorpej 651: sip = SIP_DECL(lookup)(pa);
1.1 thorpej 652: if (sip == NULL) {
653: printf("\n");
1.28 thorpej 654: panic(SIP_STR(attach) ": impossible");
1.1 thorpej 655: }
1.45 thorpej 656: sc->sc_rev = PCI_REVISION(pa->pa_class);
1.1 thorpej 657:
1.50 briggs 658: printf(": %s, rev %#02x\n", sip->sip_name, sc->sc_rev);
1.1 thorpej 659:
1.15 thorpej 660: sc->sc_model = sip;
1.5 thorpej 661:
1.1 thorpej 662: /*
1.46 thorpej 663: * XXX Work-around broken PXE firmware on some boards.
664: *
665: * The DP83815 shares an address decoder with the MEM BAR
666: * and the ROM BAR. Make sure the ROM BAR is disabled,
667: * so that memory mapped access works.
668: */
669: pci_conf_write(pa->pa_pc, pa->pa_tag, PCI_MAPREG_ROM,
670: pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_MAPREG_ROM) &
671: ~PCI_MAPREG_ROM_ENABLE);
672:
673: /*
1.1 thorpej 674: * Map the device.
675: */
676: ioh_valid = (pci_mapreg_map(pa, SIP_PCI_CFGIOA,
677: PCI_MAPREG_TYPE_IO, 0,
678: &iot, &ioh, NULL, NULL) == 0);
1.29 thorpej 679: #ifdef DP83820
680: memtype = pci_mapreg_type(pa->pa_pc, pa->pa_tag, SIP_PCI_CFGMA);
681: switch (memtype) {
682: case PCI_MAPREG_TYPE_MEM | PCI_MAPREG_MEM_TYPE_32BIT:
683: case PCI_MAPREG_TYPE_MEM | PCI_MAPREG_MEM_TYPE_64BIT:
684: memh_valid = (pci_mapreg_map(pa, SIP_PCI_CFGMA,
685: memtype, 0, &memt, &memh, NULL, NULL) == 0);
686: break;
687: default:
688: memh_valid = 0;
689: }
690: #else
1.1 thorpej 691: memh_valid = (pci_mapreg_map(pa, SIP_PCI_CFGMA,
692: PCI_MAPREG_TYPE_MEM|PCI_MAPREG_MEM_TYPE_32BIT, 0,
693: &memt, &memh, NULL, NULL) == 0);
1.29 thorpej 694: #endif /* DP83820 */
695:
1.1 thorpej 696: if (memh_valid) {
697: sc->sc_st = memt;
698: sc->sc_sh = memh;
699: } else if (ioh_valid) {
700: sc->sc_st = iot;
701: sc->sc_sh = ioh;
702: } else {
703: printf("%s: unable to map device registers\n",
704: sc->sc_dev.dv_xname);
705: return;
706: }
707:
708: sc->sc_dmat = pa->pa_dmat;
709:
1.48 thorpej 710: /*
711: * Make sure bus mastering is enabled. Also make sure
712: * Write/Invalidate is enabled if we're allowed to use it.
713: */
714: pmreg = pci_conf_read(pc, pa->pa_tag, PCI_COMMAND_STATUS_REG);
715: if (pa->pa_flags & PCI_FLAGS_MWI_OKAY)
716: pmreg |= PCI_COMMAND_INVALIDATE_ENABLE;
1.1 thorpej 717: pci_conf_write(pc, pa->pa_tag, PCI_COMMAND_STATUS_REG,
1.48 thorpej 718: pmreg | PCI_COMMAND_MASTER_ENABLE);
1.1 thorpej 719:
720: /* Get it out of power save mode if needed. */
1.10 mycroft 721: if (pci_get_capability(pc, pa->pa_tag, PCI_CAP_PWRMGMT, &pmreg, 0)) {
722: pmode = pci_conf_read(pc, pa->pa_tag, pmreg + 4) & 0x3;
1.1 thorpej 723: if (pmode == 3) {
724: /*
725: * The card has lost all configuration data in
726: * this state, so punt.
727: */
728: printf("%s: unable to wake up from power state D3\n",
729: sc->sc_dev.dv_xname);
730: return;
731: }
732: if (pmode != 0) {
733: printf("%s: waking up from power state D%d\n",
734: sc->sc_dev.dv_xname, pmode);
1.10 mycroft 735: pci_conf_write(pc, pa->pa_tag, pmreg + 4, 0);
1.1 thorpej 736: }
737: }
738:
739: /*
740: * Map and establish our interrupt.
741: */
1.23 sommerfe 742: if (pci_intr_map(pa, &ih)) {
1.1 thorpej 743: printf("%s: unable to map interrupt\n", sc->sc_dev.dv_xname);
744: return;
745: }
746: intrstr = pci_intr_string(pc, ih);
1.29 thorpej 747: sc->sc_ih = pci_intr_establish(pc, ih, IPL_NET, SIP_DECL(intr), sc);
1.1 thorpej 748: if (sc->sc_ih == NULL) {
749: printf("%s: unable to establish interrupt",
750: sc->sc_dev.dv_xname);
751: if (intrstr != NULL)
752: printf(" at %s", intrstr);
753: printf("\n");
754: return;
755: }
756: printf("%s: interrupting at %s\n", sc->sc_dev.dv_xname, intrstr);
757:
758: SIMPLEQ_INIT(&sc->sc_txfreeq);
759: SIMPLEQ_INIT(&sc->sc_txdirtyq);
760:
761: /*
762: * Allocate the control data structures, and create and load the
763: * DMA map for it.
764: */
765: if ((error = bus_dmamem_alloc(sc->sc_dmat,
766: sizeof(struct sip_control_data), PAGE_SIZE, 0, &seg, 1, &rseg,
767: 0)) != 0) {
768: printf("%s: unable to allocate control data, error = %d\n",
769: sc->sc_dev.dv_xname, error);
770: goto fail_0;
771: }
772:
773: if ((error = bus_dmamem_map(sc->sc_dmat, &seg, rseg,
774: sizeof(struct sip_control_data), (caddr_t *)&sc->sc_control_data,
775: BUS_DMA_COHERENT)) != 0) {
776: printf("%s: unable to map control data, error = %d\n",
777: sc->sc_dev.dv_xname, error);
778: goto fail_1;
779: }
780:
781: if ((error = bus_dmamap_create(sc->sc_dmat,
782: sizeof(struct sip_control_data), 1,
783: sizeof(struct sip_control_data), 0, 0, &sc->sc_cddmamap)) != 0) {
784: printf("%s: unable to create control data DMA map, "
785: "error = %d\n", sc->sc_dev.dv_xname, error);
786: goto fail_2;
787: }
788:
789: if ((error = bus_dmamap_load(sc->sc_dmat, sc->sc_cddmamap,
790: sc->sc_control_data, sizeof(struct sip_control_data), NULL,
791: 0)) != 0) {
792: printf("%s: unable to load control data DMA map, error = %d\n",
793: sc->sc_dev.dv_xname, error);
794: goto fail_3;
795: }
796:
797: /*
798: * Create the transmit buffer DMA maps.
799: */
800: for (i = 0; i < SIP_TXQUEUELEN; i++) {
1.46 thorpej 801: if ((error = bus_dmamap_create(sc->sc_dmat, TX_DMAMAP_SIZE,
1.1 thorpej 802: SIP_NTXSEGS, MCLBYTES, 0, 0,
803: &sc->sc_txsoft[i].txs_dmamap)) != 0) {
804: printf("%s: unable to create tx DMA map %d, "
805: "error = %d\n", sc->sc_dev.dv_xname, i, error);
806: goto fail_4;
807: }
808: }
809:
810: /*
811: * Create the receive buffer DMA maps.
812: */
813: for (i = 0; i < SIP_NRXDESC; i++) {
814: if ((error = bus_dmamap_create(sc->sc_dmat, MCLBYTES, 1,
815: MCLBYTES, 0, 0, &sc->sc_rxsoft[i].rxs_dmamap)) != 0) {
816: printf("%s: unable to create rx DMA map %d, "
817: "error = %d\n", sc->sc_dev.dv_xname, i, error);
818: goto fail_5;
819: }
1.2 thorpej 820: sc->sc_rxsoft[i].rxs_mbuf = NULL;
1.1 thorpej 821: }
822:
823: /*
824: * Reset the chip to a known state.
825: */
1.29 thorpej 826: SIP_DECL(reset)(sc);
1.1 thorpej 827:
828: /*
1.29 thorpej 829: * Read the Ethernet address from the EEPROM. This might
830: * also fetch other stuff from the EEPROM and stash it
831: * in the softc.
1.1 thorpej 832: */
1.29 thorpej 833: sc->sc_cfg = 0;
1.45 thorpej 834: #if !defined(DP83820)
835: if (SIP_SIS900_REV(sc,SIS_REV_635) ||
836: SIP_SIS900_REV(sc,SIS_REV_900B))
837: sc->sc_cfg |= (CFG_PESEL | CFG_RNDCNT);
838: #endif
839:
1.44 thorpej 840: (*sip->sip_variant->sipv_read_macaddr)(sc, pa, enaddr);
1.1 thorpej 841:
842: printf("%s: Ethernet address %s\n", sc->sc_dev.dv_xname,
1.14 tsutsui 843: ether_sprintf(enaddr));
1.1 thorpej 844:
845: /*
1.29 thorpej 846: * Initialize the configuration register: aggressive PCI
847: * bus request algorithm, default backoff, default OW timer,
848: * default parity error detection.
849: *
850: * NOTE: "Big endian mode" is useless on the SiS900 and
851: * friends -- it affects packet data, not descriptors.
852: */
853: #ifdef DP83820
1.55 thorpej 854: /*
1.59 thorpej 855: * Cause the chip to load configuration data from the EEPROM.
1.55 thorpej 856: */
1.59 thorpej 857: bus_space_write_4(sc->sc_st, sc->sc_sh, SIP_PTSCR, PTSCR_EELOAD_EN);
858: for (i = 0; i < 10000; i++) {
859: delay(10);
860: if ((bus_space_read_4(sc->sc_st, sc->sc_sh, SIP_PTSCR) &
861: PTSCR_EELOAD_EN) == 0)
862: break;
863: }
864: if (bus_space_read_4(sc->sc_st, sc->sc_sh, SIP_PTSCR) &
865: PTSCR_EELOAD_EN) {
866: printf("%s: timeout loading configuration from EEPROM\n",
867: sc->sc_dev.dv_xname);
868: return;
869: }
1.55 thorpej 870:
1.69 thorpej 871: sc->sc_gpior = bus_space_read_4(sc->sc_st, sc->sc_sh, SIP_GPIOR);
872:
1.29 thorpej 873: reg = bus_space_read_4(sc->sc_st, sc->sc_sh, SIP_CFG);
874: if (reg & CFG_PCI64_DET) {
1.60 thorpej 875: printf("%s: 64-bit PCI slot detected", sc->sc_dev.dv_xname);
876: /*
877: * Check to see if this card is 64-bit. If so, enable 64-bit
878: * data transfers.
879: *
880: * We can't use the DATA64_EN bit in the EEPROM, because
881: * vendors of 32-bit cards fail to clear that bit in many
882: * cases (yet the card still detects that it's in a 64-bit
883: * slot; go figure).
884: */
885: if (SIP_DECL(check_64bit)(pa)) {
1.59 thorpej 886: sc->sc_cfg |= CFG_DATA64_EN;
1.60 thorpej 887: printf(", using 64-bit data transfers");
888: }
889: printf("\n");
1.59 thorpej 890: }
891:
892: /*
893: * XXX Need some PCI flags indicating support for
894: * XXX 64-bit addressing.
895: */
896: #if 0
897: if (reg & CFG_M64ADDR)
898: sc->sc_cfg |= CFG_M64ADDR;
899: if (reg & CFG_T64ADDR)
900: sc->sc_cfg |= CFG_T64ADDR;
901: #endif
1.55 thorpej 902:
1.59 thorpej 903: if (reg & (CFG_TBI_EN|CFG_EXT_125)) {
1.29 thorpej 904: const char *sep = "";
905: printf("%s: using ", sc->sc_dev.dv_xname);
1.59 thorpej 906: if (reg & CFG_EXT_125) {
907: sc->sc_cfg |= CFG_EXT_125;
1.29 thorpej 908: printf("%s125MHz clock", sep);
909: sep = ", ";
910: }
1.59 thorpej 911: if (reg & CFG_TBI_EN) {
912: sc->sc_cfg |= CFG_TBI_EN;
1.29 thorpej 913: printf("%sten-bit interface", sep);
914: sep = ", ";
915: }
916: printf("\n");
917: }
1.59 thorpej 918: if ((pa->pa_flags & PCI_FLAGS_MRM_OKAY) == 0 ||
919: (reg & CFG_MRM_DIS) != 0)
1.29 thorpej 920: sc->sc_cfg |= CFG_MRM_DIS;
1.59 thorpej 921: if ((pa->pa_flags & PCI_FLAGS_MWI_OKAY) == 0 ||
922: (reg & CFG_MWI_DIS) != 0)
1.29 thorpej 923: sc->sc_cfg |= CFG_MWI_DIS;
924:
925: /*
926: * Use the extended descriptor format on the DP83820. This
927: * gives us an interface to VLAN tagging and IPv4/TCP/UDP
928: * checksumming.
929: */
930: sc->sc_cfg |= CFG_EXTSTS_EN;
931: #endif /* DP83820 */
932:
933: /*
1.1 thorpej 934: * Initialize our media structures and probe the MII.
935: */
936: sc->sc_mii.mii_ifp = ifp;
1.15 thorpej 937: sc->sc_mii.mii_readreg = sip->sip_variant->sipv_mii_readreg;
938: sc->sc_mii.mii_writereg = sip->sip_variant->sipv_mii_writereg;
939: sc->sc_mii.mii_statchg = sip->sip_variant->sipv_mii_statchg;
1.29 thorpej 940: ifmedia_init(&sc->sc_mii.mii_media, 0, SIP_DECL(mediachange),
941: SIP_DECL(mediastatus));
1.63 thorpej 942:
1.6 thorpej 943: mii_attach(&sc->sc_dev, &sc->sc_mii, 0xffffffff, MII_PHY_ANY,
1.7 thorpej 944: MII_OFFSET_ANY, 0);
1.1 thorpej 945: if (LIST_FIRST(&sc->sc_mii.mii_phys) == NULL) {
946: ifmedia_add(&sc->sc_mii.mii_media, IFM_ETHER|IFM_NONE, 0, NULL);
947: ifmedia_set(&sc->sc_mii.mii_media, IFM_ETHER|IFM_NONE);
948: } else
949: ifmedia_set(&sc->sc_mii.mii_media, IFM_ETHER|IFM_AUTO);
950:
951: ifp = &sc->sc_ethercom.ec_if;
952: strcpy(ifp->if_xname, sc->sc_dev.dv_xname);
953: ifp->if_softc = sc;
954: ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
1.28 thorpej 955: ifp->if_ioctl = SIP_DECL(ioctl);
956: ifp->if_start = SIP_DECL(start);
957: ifp->if_watchdog = SIP_DECL(watchdog);
958: ifp->if_init = SIP_DECL(init);
959: ifp->if_stop = SIP_DECL(stop);
1.21 thorpej 960: IFQ_SET_READY(&ifp->if_snd);
1.1 thorpej 961:
962: /*
1.29 thorpej 963: * We can support 802.1Q VLAN-sized frames.
964: */
965: sc->sc_ethercom.ec_capabilities |= ETHERCAP_VLAN_MTU;
966:
967: #ifdef DP83820
968: /*
1.36 thorpej 969: * And the DP83820 can do VLAN tagging in hardware, and
970: * support the jumbo Ethernet MTU.
1.29 thorpej 971: */
1.36 thorpej 972: sc->sc_ethercom.ec_capabilities |=
973: ETHERCAP_VLAN_HWTAGGING | ETHERCAP_JUMBO_MTU;
1.31 thorpej 974:
975: /*
976: * The DP83820 can do IPv4, TCPv4, and UDPv4 checksums
977: * in hardware.
978: */
979: ifp->if_capabilities |= IFCAP_CSUM_IPv4 | IFCAP_CSUM_TCPv4 |
980: IFCAP_CSUM_UDPv4;
1.29 thorpej 981: #endif /* DP83820 */
982:
983: /*
1.1 thorpej 984: * Attach the interface.
985: */
986: if_attach(ifp);
1.14 tsutsui 987: ether_ifattach(ifp, enaddr);
1.65 itojun 988: #if NRND > 0
989: rnd_attach_source(&sc->rnd_source, sc->sc_dev.dv_xname,
990: RND_TYPE_NET, 0);
991: #endif
1.1 thorpej 992:
1.46 thorpej 993: /*
994: * The number of bytes that must be available in
995: * the Tx FIFO before the bus master can DMA more
996: * data into the FIFO.
997: */
998: sc->sc_tx_fill_thresh = 64 / 32;
999:
1000: /*
1001: * Start at a drain threshold of 512 bytes. We will
1002: * increase it if a DMA underrun occurs.
1003: *
1004: * XXX The minimum value of this variable should be
1005: * tuned. We may be able to improve performance
1006: * by starting with a lower value. That, however,
1007: * may trash the first few outgoing packets if the
1008: * PCI bus is saturated.
1009: */
1.53 tron 1010: sc->sc_tx_drain_thresh = 1504 / 32;
1.46 thorpej 1011:
1012: /*
1.47 thorpej 1013: * Initialize the Rx FIFO drain threshold.
1014: *
1.46 thorpej 1015: * This is in units of 8 bytes.
1016: *
1017: * We should never set this value lower than 2; 14 bytes are
1018: * required to filter the packet.
1019: */
1.47 thorpej 1020: sc->sc_rx_drain_thresh = 128 / 8;
1.46 thorpej 1021:
1.30 thorpej 1022: #ifdef SIP_EVENT_COUNTERS
1023: /*
1024: * Attach event counters.
1025: */
1026: evcnt_attach_dynamic(&sc->sc_ev_txsstall, EVCNT_TYPE_MISC,
1027: NULL, sc->sc_dev.dv_xname, "txsstall");
1028: evcnt_attach_dynamic(&sc->sc_ev_txdstall, EVCNT_TYPE_MISC,
1029: NULL, sc->sc_dev.dv_xname, "txdstall");
1.56 thorpej 1030: evcnt_attach_dynamic(&sc->sc_ev_txforceintr, EVCNT_TYPE_INTR,
1031: NULL, sc->sc_dev.dv_xname, "txforceintr");
1032: evcnt_attach_dynamic(&sc->sc_ev_txdintr, EVCNT_TYPE_INTR,
1033: NULL, sc->sc_dev.dv_xname, "txdintr");
1034: evcnt_attach_dynamic(&sc->sc_ev_txiintr, EVCNT_TYPE_INTR,
1035: NULL, sc->sc_dev.dv_xname, "txiintr");
1.30 thorpej 1036: evcnt_attach_dynamic(&sc->sc_ev_rxintr, EVCNT_TYPE_INTR,
1037: NULL, sc->sc_dev.dv_xname, "rxintr");
1.62 thorpej 1038: evcnt_attach_dynamic(&sc->sc_ev_hiberr, EVCNT_TYPE_INTR,
1039: NULL, sc->sc_dev.dv_xname, "hiberr");
1.31 thorpej 1040: #ifdef DP83820
1041: evcnt_attach_dynamic(&sc->sc_ev_rxipsum, EVCNT_TYPE_MISC,
1042: NULL, sc->sc_dev.dv_xname, "rxipsum");
1043: evcnt_attach_dynamic(&sc->sc_ev_rxtcpsum, EVCNT_TYPE_MISC,
1044: NULL, sc->sc_dev.dv_xname, "rxtcpsum");
1045: evcnt_attach_dynamic(&sc->sc_ev_rxudpsum, EVCNT_TYPE_MISC,
1046: NULL, sc->sc_dev.dv_xname, "rxudpsum");
1047: evcnt_attach_dynamic(&sc->sc_ev_txipsum, EVCNT_TYPE_MISC,
1048: NULL, sc->sc_dev.dv_xname, "txipsum");
1049: evcnt_attach_dynamic(&sc->sc_ev_txtcpsum, EVCNT_TYPE_MISC,
1050: NULL, sc->sc_dev.dv_xname, "txtcpsum");
1051: evcnt_attach_dynamic(&sc->sc_ev_txudpsum, EVCNT_TYPE_MISC,
1052: NULL, sc->sc_dev.dv_xname, "txudpsum");
1053: #endif /* DP83820 */
1.30 thorpej 1054: #endif /* SIP_EVENT_COUNTERS */
1055:
1.1 thorpej 1056: /*
1057: * Make sure the interface is shutdown during reboot.
1058: */
1.28 thorpej 1059: sc->sc_sdhook = shutdownhook_establish(SIP_DECL(shutdown), sc);
1.1 thorpej 1060: if (sc->sc_sdhook == NULL)
1061: printf("%s: WARNING: unable to establish shutdown hook\n",
1062: sc->sc_dev.dv_xname);
1063: return;
1064:
1065: /*
1066: * Free any resources we've allocated during the failed attach
1067: * attempt. Do this in reverse order and fall through.
1068: */
1069: fail_5:
1070: for (i = 0; i < SIP_NRXDESC; i++) {
1071: if (sc->sc_rxsoft[i].rxs_dmamap != NULL)
1072: bus_dmamap_destroy(sc->sc_dmat,
1073: sc->sc_rxsoft[i].rxs_dmamap);
1074: }
1075: fail_4:
1076: for (i = 0; i < SIP_TXQUEUELEN; i++) {
1077: if (sc->sc_txsoft[i].txs_dmamap != NULL)
1078: bus_dmamap_destroy(sc->sc_dmat,
1079: sc->sc_txsoft[i].txs_dmamap);
1080: }
1081: bus_dmamap_unload(sc->sc_dmat, sc->sc_cddmamap);
1082: fail_3:
1083: bus_dmamap_destroy(sc->sc_dmat, sc->sc_cddmamap);
1084: fail_2:
1085: bus_dmamem_unmap(sc->sc_dmat, (caddr_t)sc->sc_control_data,
1086: sizeof(struct sip_control_data));
1087: fail_1:
1088: bus_dmamem_free(sc->sc_dmat, &seg, rseg);
1089: fail_0:
1090: return;
1091: }
1092:
1093: /*
1094: * sip_shutdown:
1095: *
1096: * Make sure the interface is stopped at reboot time.
1097: */
1098: void
1.28 thorpej 1099: SIP_DECL(shutdown)(void *arg)
1.1 thorpej 1100: {
1101: struct sip_softc *sc = arg;
1102:
1.28 thorpej 1103: SIP_DECL(stop)(&sc->sc_ethercom.ec_if, 1);
1.1 thorpej 1104: }
1105:
1106: /*
1107: * sip_start: [ifnet interface function]
1108: *
1109: * Start packet transmission on the interface.
1110: */
1111: void
1.28 thorpej 1112: SIP_DECL(start)(struct ifnet *ifp)
1.1 thorpej 1113: {
1114: struct sip_softc *sc = ifp->if_softc;
1115: struct mbuf *m0, *m;
1116: struct sip_txsoft *txs;
1117: bus_dmamap_t dmamap;
1.57 thorpej 1118: int error, nexttx, lasttx, seg;
1119: int ofree = sc->sc_txfree;
1120: #if 0
1121: int firsttx = sc->sc_txnext;
1122: #endif
1.31 thorpej 1123: #ifdef DP83820
1124: u_int32_t extsts;
1125: #endif
1.1 thorpej 1126:
1127: /*
1128: * If we've been told to pause, don't transmit any more packets.
1129: */
1130: if (sc->sc_flags & SIPF_PAUSED)
1131: ifp->if_flags |= IFF_OACTIVE;
1132:
1133: if ((ifp->if_flags & (IFF_RUNNING|IFF_OACTIVE)) != IFF_RUNNING)
1134: return;
1135:
1136: /*
1137: * Loop through the send queue, setting up transmit descriptors
1138: * until we drain the queue, or use up all available transmit
1139: * descriptors.
1140: */
1.30 thorpej 1141: for (;;) {
1142: /* Get a work queue entry. */
1143: if ((txs = SIMPLEQ_FIRST(&sc->sc_txfreeq)) == NULL) {
1144: SIP_EVCNT_INCR(&sc->sc_ev_txsstall);
1145: break;
1146: }
1147:
1.1 thorpej 1148: /*
1149: * Grab a packet off the queue.
1150: */
1.21 thorpej 1151: IFQ_POLL(&ifp->if_snd, m0);
1.1 thorpej 1152: if (m0 == NULL)
1153: break;
1.36 thorpej 1154: #ifndef DP83820
1.22 thorpej 1155: m = NULL;
1.36 thorpej 1156: #endif
1.1 thorpej 1157:
1158: dmamap = txs->txs_dmamap;
1159:
1.36 thorpej 1160: #ifdef DP83820
1161: /*
1162: * Load the DMA map. If this fails, the packet either
1163: * didn't fit in the allotted number of segments, or we
1164: * were short on resources. For the too-many-segments
1165: * case, we simply report an error and drop the packet,
1166: * since we can't sanely copy a jumbo packet to a single
1167: * buffer.
1168: */
1169: error = bus_dmamap_load_mbuf(sc->sc_dmat, dmamap, m0,
1.41 thorpej 1170: BUS_DMA_WRITE|BUS_DMA_NOWAIT);
1.36 thorpej 1171: if (error) {
1172: if (error == EFBIG) {
1173: printf("%s: Tx packet consumes too many "
1174: "DMA segments, dropping...\n",
1175: sc->sc_dev.dv_xname);
1176: IFQ_DEQUEUE(&ifp->if_snd, m0);
1177: m_freem(m0);
1178: continue;
1179: }
1180: /*
1181: * Short on resources, just stop for now.
1182: */
1183: break;
1184: }
1185: #else /* DP83820 */
1.1 thorpej 1186: /*
1187: * Load the DMA map. If this fails, the packet either
1188: * didn't fit in the alloted number of segments, or we
1189: * were short on resources. In this case, we'll copy
1190: * and try again.
1191: */
1192: if (bus_dmamap_load_mbuf(sc->sc_dmat, dmamap, m0,
1.41 thorpej 1193: BUS_DMA_WRITE|BUS_DMA_NOWAIT) != 0) {
1.1 thorpej 1194: MGETHDR(m, M_DONTWAIT, MT_DATA);
1195: if (m == NULL) {
1196: printf("%s: unable to allocate Tx mbuf\n",
1197: sc->sc_dev.dv_xname);
1198: break;
1199: }
1200: if (m0->m_pkthdr.len > MHLEN) {
1201: MCLGET(m, M_DONTWAIT);
1202: if ((m->m_flags & M_EXT) == 0) {
1203: printf("%s: unable to allocate Tx "
1204: "cluster\n", sc->sc_dev.dv_xname);
1205: m_freem(m);
1206: break;
1207: }
1208: }
1209: m_copydata(m0, 0, m0->m_pkthdr.len, mtod(m, caddr_t));
1210: m->m_pkthdr.len = m->m_len = m0->m_pkthdr.len;
1211: error = bus_dmamap_load_mbuf(sc->sc_dmat, dmamap,
1.41 thorpej 1212: m, BUS_DMA_WRITE|BUS_DMA_NOWAIT);
1.1 thorpej 1213: if (error) {
1214: printf("%s: unable to load Tx buffer, "
1215: "error = %d\n", sc->sc_dev.dv_xname, error);
1216: break;
1217: }
1218: }
1.36 thorpej 1219: #endif /* DP83820 */
1.21 thorpej 1220:
1.1 thorpej 1221: /*
1222: * Ensure we have enough descriptors free to describe
1.30 thorpej 1223: * the packet. Note, we always reserve one descriptor
1224: * at the end of the ring as a termination point, to
1225: * prevent wrap-around.
1.1 thorpej 1226: */
1.30 thorpej 1227: if (dmamap->dm_nsegs > (sc->sc_txfree - 1)) {
1.1 thorpej 1228: /*
1229: * Not enough free descriptors to transmit this
1230: * packet. We haven't committed anything yet,
1231: * so just unload the DMA map, put the packet
1232: * back on the queue, and punt. Notify the upper
1233: * layer that there are not more slots left.
1234: *
1235: * XXX We could allocate an mbuf and copy, but
1236: * XXX is it worth it?
1237: */
1238: ifp->if_flags |= IFF_OACTIVE;
1239: bus_dmamap_unload(sc->sc_dmat, dmamap);
1.36 thorpej 1240: #ifndef DP83820
1.22 thorpej 1241: if (m != NULL)
1242: m_freem(m);
1.36 thorpej 1243: #endif
1.30 thorpej 1244: SIP_EVCNT_INCR(&sc->sc_ev_txdstall);
1.1 thorpej 1245: break;
1.22 thorpej 1246: }
1247:
1248: IFQ_DEQUEUE(&ifp->if_snd, m0);
1.36 thorpej 1249: #ifndef DP83820
1.22 thorpej 1250: if (m != NULL) {
1251: m_freem(m0);
1252: m0 = m;
1.1 thorpej 1253: }
1.36 thorpej 1254: #endif
1.1 thorpej 1255:
1256: /*
1257: * WE ARE NOW COMMITTED TO TRANSMITTING THE PACKET.
1258: */
1259:
1260: /* Sync the DMA map. */
1261: bus_dmamap_sync(sc->sc_dmat, dmamap, 0, dmamap->dm_mapsize,
1262: BUS_DMASYNC_PREWRITE);
1263:
1264: /*
1265: * Initialize the transmit descriptors.
1266: */
1267: for (nexttx = sc->sc_txnext, seg = 0;
1268: seg < dmamap->dm_nsegs;
1269: seg++, nexttx = SIP_NEXTTX(nexttx)) {
1270: /*
1271: * If this is the first descriptor we're
1272: * enqueueing, don't set the OWN bit just
1273: * yet. That could cause a race condition.
1274: * We'll do it below.
1275: */
1276: sc->sc_txdescs[nexttx].sipd_bufptr =
1.14 tsutsui 1277: htole32(dmamap->dm_segs[seg].ds_addr);
1.1 thorpej 1278: sc->sc_txdescs[nexttx].sipd_cmdsts =
1.57 thorpej 1279: htole32((nexttx == sc->sc_txnext ? 0 : CMDSTS_OWN) |
1.14 tsutsui 1280: CMDSTS_MORE | dmamap->dm_segs[seg].ds_len);
1.29 thorpej 1281: #ifdef DP83820
1282: sc->sc_txdescs[nexttx].sipd_extsts = 0;
1283: #endif /* DP83820 */
1.1 thorpej 1284: lasttx = nexttx;
1285: }
1286:
1287: /* Clear the MORE bit on the last segment. */
1.14 tsutsui 1288: sc->sc_txdescs[lasttx].sipd_cmdsts &= htole32(~CMDSTS_MORE);
1.1 thorpej 1289:
1.56 thorpej 1290: /*
1291: * If we're in the interrupt delay window, delay the
1292: * interrupt.
1293: */
1294: if (++sc->sc_txwin >= (SIP_TXQUEUELEN * 2 / 3)) {
1295: SIP_EVCNT_INCR(&sc->sc_ev_txforceintr);
1296: sc->sc_txdescs[lasttx].sipd_cmdsts |=
1297: htole32(CMDSTS_INTR);
1298: sc->sc_txwin = 0;
1299: }
1300:
1.29 thorpej 1301: #ifdef DP83820
1302: /*
1303: * If VLANs are enabled and the packet has a VLAN tag, set
1304: * up the descriptor to encapsulate the packet for us.
1.31 thorpej 1305: *
1306: * This apparently has to be on the last descriptor of
1307: * the packet.
1.29 thorpej 1308: */
1309: if (sc->sc_ethercom.ec_nvlans != 0 &&
1310: (m = m_aux_find(m0, AF_LINK, ETHERTYPE_VLAN)) != NULL) {
1311: sc->sc_txdescs[lasttx].sipd_extsts |=
1312: htole32(EXTSTS_VPKT |
1313: htons(*mtod(m, int *) & EXTSTS_VTCI));
1314: }
1.31 thorpej 1315:
1316: /*
1317: * If the upper-layer has requested IPv4/TCPv4/UDPv4
1318: * checksumming, set up the descriptor to do this work
1319: * for us.
1320: *
1321: * This apparently has to be on the first descriptor of
1322: * the packet.
1323: *
1324: * Byte-swap constants so the compiler can optimize.
1325: */
1326: extsts = 0;
1327: if (m0->m_pkthdr.csum_flags & M_CSUM_IPv4) {
1328: KDASSERT(ifp->if_capenable & IFCAP_CSUM_IPv4);
1329: SIP_EVCNT_INCR(&sc->sc_ev_txipsum);
1330: extsts |= htole32(EXTSTS_IPPKT);
1331: }
1332: if (m0->m_pkthdr.csum_flags & M_CSUM_TCPv4) {
1333: KDASSERT(ifp->if_capenable & IFCAP_CSUM_TCPv4);
1334: SIP_EVCNT_INCR(&sc->sc_ev_txtcpsum);
1335: extsts |= htole32(EXTSTS_TCPPKT);
1336: } else if (m0->m_pkthdr.csum_flags & M_CSUM_UDPv4) {
1337: KDASSERT(ifp->if_capenable & IFCAP_CSUM_UDPv4);
1338: SIP_EVCNT_INCR(&sc->sc_ev_txudpsum);
1339: extsts |= htole32(EXTSTS_UDPPKT);
1340: }
1341: sc->sc_txdescs[sc->sc_txnext].sipd_extsts |= extsts;
1.29 thorpej 1342: #endif /* DP83820 */
1343:
1.1 thorpej 1344: /* Sync the descriptors we're using. */
1345: SIP_CDTXSYNC(sc, sc->sc_txnext, dmamap->dm_nsegs,
1346: BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
1347:
1348: /*
1.57 thorpej 1349: * The entire packet is set up. Give the first descrptor
1350: * to the chip now.
1351: */
1352: sc->sc_txdescs[sc->sc_txnext].sipd_cmdsts |=
1353: htole32(CMDSTS_OWN);
1354: SIP_CDTXSYNC(sc, sc->sc_txnext, 1,
1355: BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
1356:
1357: /*
1.1 thorpej 1358: * Store a pointer to the packet so we can free it later,
1359: * and remember what txdirty will be once the packet is
1360: * done.
1361: */
1362: txs->txs_mbuf = m0;
1363: txs->txs_firstdesc = sc->sc_txnext;
1364: txs->txs_lastdesc = lasttx;
1365:
1366: /* Advance the tx pointer. */
1367: sc->sc_txfree -= dmamap->dm_nsegs;
1368: sc->sc_txnext = nexttx;
1369:
1.54 lukem 1370: SIMPLEQ_REMOVE_HEAD(&sc->sc_txfreeq, txs_q);
1.1 thorpej 1371: SIMPLEQ_INSERT_TAIL(&sc->sc_txdirtyq, txs, txs_q);
1372:
1373: #if NBPFILTER > 0
1374: /*
1375: * Pass the packet to any BPF listeners.
1376: */
1377: if (ifp->if_bpf)
1378: bpf_mtap(ifp->if_bpf, m0);
1379: #endif /* NBPFILTER > 0 */
1380: }
1381:
1382: if (txs == NULL || sc->sc_txfree == 0) {
1383: /* No more slots left; notify upper layer. */
1384: ifp->if_flags |= IFF_OACTIVE;
1385: }
1386:
1387: if (sc->sc_txfree != ofree) {
1.30 thorpej 1388: /*
1389: * Start the transmit process. Note, the manual says
1390: * that if there are no pending transmissions in the
1391: * chip's internal queue (indicated by TXE being clear),
1392: * then the driver software must set the TXDP to the
1393: * first descriptor to be transmitted. However, if we
1394: * do this, it causes serious performance degredation on
1395: * the DP83820 under load, not setting TXDP doesn't seem
1396: * to adversely affect the SiS 900 or DP83815.
1397: *
1398: * Well, I guess it wouldn't be the first time a manual
1399: * has lied -- and they could be speaking of the NULL-
1400: * terminated descriptor list case, rather than OWN-
1401: * terminated rings.
1402: */
1403: #if 0
1.1 thorpej 1404: if ((bus_space_read_4(sc->sc_st, sc->sc_sh, SIP_CR) &
1405: CR_TXE) == 0) {
1406: bus_space_write_4(sc->sc_st, sc->sc_sh, SIP_TXDP,
1407: SIP_CDTXADDR(sc, firsttx));
1408: bus_space_write_4(sc->sc_st, sc->sc_sh, SIP_CR, CR_TXE);
1409: }
1.30 thorpej 1410: #else
1411: bus_space_write_4(sc->sc_st, sc->sc_sh, SIP_CR, CR_TXE);
1412: #endif
1.1 thorpej 1413:
1414: /* Set a watchdog timer in case the chip flakes out. */
1415: ifp->if_timer = 5;
1416: }
1417: }
1418:
1419: /*
1420: * sip_watchdog: [ifnet interface function]
1421: *
1422: * Watchdog timer handler.
1423: */
1424: void
1.28 thorpej 1425: SIP_DECL(watchdog)(struct ifnet *ifp)
1.1 thorpej 1426: {
1427: struct sip_softc *sc = ifp->if_softc;
1428:
1429: /*
1430: * The chip seems to ignore the CMDSTS_INTR bit sometimes!
1431: * If we get a timeout, try and sweep up transmit descriptors.
1432: * If we manage to sweep them all up, ignore the lack of
1433: * interrupt.
1434: */
1.28 thorpej 1435: SIP_DECL(txintr)(sc);
1.1 thorpej 1436:
1437: if (sc->sc_txfree != SIP_NTXDESC) {
1438: printf("%s: device timeout\n", sc->sc_dev.dv_xname);
1439: ifp->if_oerrors++;
1440:
1441: /* Reset the interface. */
1.28 thorpej 1442: (void) SIP_DECL(init)(ifp);
1.1 thorpej 1443: } else if (ifp->if_flags & IFF_DEBUG)
1444: printf("%s: recovered from device timeout\n",
1445: sc->sc_dev.dv_xname);
1446:
1447: /* Try to get more packets going. */
1.28 thorpej 1448: SIP_DECL(start)(ifp);
1.1 thorpej 1449: }
1450:
1451: /*
1452: * sip_ioctl: [ifnet interface function]
1453: *
1454: * Handle control requests from the operator.
1455: */
1456: int
1.28 thorpej 1457: SIP_DECL(ioctl)(struct ifnet *ifp, u_long cmd, caddr_t data)
1.1 thorpej 1458: {
1459: struct sip_softc *sc = ifp->if_softc;
1460: struct ifreq *ifr = (struct ifreq *)data;
1.17 thorpej 1461: int s, error;
1.1 thorpej 1462:
1463: s = splnet();
1464:
1465: switch (cmd) {
1.17 thorpej 1466: case SIOCSIFMEDIA:
1467: case SIOCGIFMEDIA:
1468: error = ifmedia_ioctl(ifp, ifr, &sc->sc_mii.mii_media, cmd);
1.1 thorpej 1469: break;
1470:
1.17 thorpej 1471: default:
1472: error = ether_ioctl(ifp, cmd, data);
1.1 thorpej 1473: if (error == ENETRESET) {
1474: /*
1475: * Multicast list has changed; set the hardware filter
1476: * accordingly.
1477: */
1.15 thorpej 1478: (*sc->sc_model->sip_variant->sipv_set_filter)(sc);
1.1 thorpej 1479: error = 0;
1480: }
1481: break;
1482: }
1483:
1484: /* Try to get more packets going. */
1.28 thorpej 1485: SIP_DECL(start)(ifp);
1.1 thorpej 1486:
1487: splx(s);
1488: return (error);
1489: }
1490:
1491: /*
1492: * sip_intr:
1493: *
1494: * Interrupt service routine.
1495: */
1496: int
1.28 thorpej 1497: SIP_DECL(intr)(void *arg)
1.1 thorpej 1498: {
1499: struct sip_softc *sc = arg;
1500: struct ifnet *ifp = &sc->sc_ethercom.ec_if;
1501: u_int32_t isr;
1502: int handled = 0;
1503:
1504: for (;;) {
1505: /* Reading clears interrupt. */
1506: isr = bus_space_read_4(sc->sc_st, sc->sc_sh, SIP_ISR);
1507: if ((isr & sc->sc_imr) == 0)
1508: break;
1.65 itojun 1509:
1510: #if NRND > 0
1.66 itojun 1511: if (RND_ENABLED(&sc->rnd_source))
1512: rnd_add_uint32(&sc->rnd_source, isr);
1.65 itojun 1513: #endif
1.1 thorpej 1514:
1515: handled = 1;
1516:
1517: if (isr & (ISR_RXORN|ISR_RXIDLE|ISR_RXDESC)) {
1.30 thorpej 1518: SIP_EVCNT_INCR(&sc->sc_ev_rxintr);
1519:
1.1 thorpej 1520: /* Grab any new packets. */
1.28 thorpej 1521: SIP_DECL(rxintr)(sc);
1.1 thorpej 1522:
1523: if (isr & ISR_RXORN) {
1524: printf("%s: receive FIFO overrun\n",
1525: sc->sc_dev.dv_xname);
1526:
1527: /* XXX adjust rx_drain_thresh? */
1528: }
1529:
1530: if (isr & ISR_RXIDLE) {
1531: printf("%s: receive ring overrun\n",
1532: sc->sc_dev.dv_xname);
1533:
1534: /* Get the receive process going again. */
1535: bus_space_write_4(sc->sc_st, sc->sc_sh,
1536: SIP_RXDP, SIP_CDRXADDR(sc, sc->sc_rxptr));
1537: bus_space_write_4(sc->sc_st, sc->sc_sh,
1538: SIP_CR, CR_RXE);
1539: }
1540: }
1541:
1.56 thorpej 1542: if (isr & (ISR_TXURN|ISR_TXDESC|ISR_TXIDLE)) {
1543: #ifdef SIP_EVENT_COUNTERS
1544: if (isr & ISR_TXDESC)
1545: SIP_EVCNT_INCR(&sc->sc_ev_txdintr);
1546: else if (isr & ISR_TXIDLE)
1547: SIP_EVCNT_INCR(&sc->sc_ev_txiintr);
1548: #endif
1.30 thorpej 1549:
1.1 thorpej 1550: /* Sweep up transmit descriptors. */
1.28 thorpej 1551: SIP_DECL(txintr)(sc);
1.1 thorpej 1552:
1553: if (isr & ISR_TXURN) {
1554: u_int32_t thresh;
1555:
1556: printf("%s: transmit FIFO underrun",
1557: sc->sc_dev.dv_xname);
1558:
1559: thresh = sc->sc_tx_drain_thresh + 1;
1560: if (thresh <= TXCFG_DRTH &&
1561: (thresh * 32) <= (SIP_TXFIFO_SIZE -
1562: (sc->sc_tx_fill_thresh * 32))) {
1563: printf("; increasing Tx drain "
1564: "threshold to %u bytes\n",
1565: thresh * 32);
1566: sc->sc_tx_drain_thresh = thresh;
1.28 thorpej 1567: (void) SIP_DECL(init)(ifp);
1.1 thorpej 1568: } else {
1.28 thorpej 1569: (void) SIP_DECL(init)(ifp);
1.1 thorpej 1570: printf("\n");
1571: }
1572: }
1573: }
1574:
1.29 thorpej 1575: #if !defined(DP83820)
1.1 thorpej 1576: if (sc->sc_imr & (ISR_PAUSE_END|ISR_PAUSE_ST)) {
1577: if (isr & ISR_PAUSE_ST) {
1578: sc->sc_flags |= SIPF_PAUSED;
1579: ifp->if_flags |= IFF_OACTIVE;
1580: }
1581: if (isr & ISR_PAUSE_END) {
1582: sc->sc_flags &= ~SIPF_PAUSED;
1583: ifp->if_flags &= ~IFF_OACTIVE;
1584: }
1585: }
1.29 thorpej 1586: #endif /* ! DP83820 */
1.1 thorpej 1587:
1588: if (isr & ISR_HIBERR) {
1.62 thorpej 1589: int want_init = 0;
1590:
1591: SIP_EVCNT_INCR(&sc->sc_ev_hiberr);
1592:
1.1 thorpej 1593: #define PRINTERR(bit, str) \
1.62 thorpej 1594: do { \
1.68 itojun 1595: if ((isr & (bit)) != 0) { \
1596: if ((ifp->if_flags & IFF_DEBUG) != 0) \
1597: printf("%s: %s\n", \
1598: sc->sc_dev.dv_xname, str); \
1.62 thorpej 1599: want_init = 1; \
1600: } \
1601: } while (/*CONSTCOND*/0)
1602:
1.1 thorpej 1603: PRINTERR(ISR_DPERR, "parity error");
1604: PRINTERR(ISR_SSERR, "system error");
1605: PRINTERR(ISR_RMABT, "master abort");
1606: PRINTERR(ISR_RTABT, "target abort");
1607: PRINTERR(ISR_RXSOVR, "receive status FIFO overrun");
1.62 thorpej 1608: /*
1609: * Ignore:
1610: * Tx reset complete
1611: * Rx reset complete
1612: */
1613: if (want_init)
1614: (void) SIP_DECL(init)(ifp);
1.1 thorpej 1615: #undef PRINTERR
1616: }
1617: }
1618:
1619: /* Try to get more packets going. */
1.28 thorpej 1620: SIP_DECL(start)(ifp);
1.1 thorpej 1621:
1622: return (handled);
1623: }
1624:
1625: /*
1626: * sip_txintr:
1627: *
1628: * Helper; handle transmit interrupts.
1629: */
1630: void
1.28 thorpej 1631: SIP_DECL(txintr)(struct sip_softc *sc)
1.1 thorpej 1632: {
1633: struct ifnet *ifp = &sc->sc_ethercom.ec_if;
1634: struct sip_txsoft *txs;
1635: u_int32_t cmdsts;
1636:
1637: if ((sc->sc_flags & SIPF_PAUSED) == 0)
1638: ifp->if_flags &= ~IFF_OACTIVE;
1639:
1640: /*
1641: * Go through our Tx list and free mbufs for those
1642: * frames which have been transmitted.
1643: */
1644: while ((txs = SIMPLEQ_FIRST(&sc->sc_txdirtyq)) != NULL) {
1645: SIP_CDTXSYNC(sc, txs->txs_firstdesc, txs->txs_dmamap->dm_nsegs,
1646: BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE);
1647:
1.14 tsutsui 1648: cmdsts = le32toh(sc->sc_txdescs[txs->txs_lastdesc].sipd_cmdsts);
1.1 thorpej 1649: if (cmdsts & CMDSTS_OWN)
1650: break;
1651:
1.54 lukem 1652: SIMPLEQ_REMOVE_HEAD(&sc->sc_txdirtyq, txs_q);
1.1 thorpej 1653:
1654: sc->sc_txfree += txs->txs_dmamap->dm_nsegs;
1655:
1656: bus_dmamap_sync(sc->sc_dmat, txs->txs_dmamap,
1657: 0, txs->txs_dmamap->dm_mapsize, BUS_DMASYNC_POSTWRITE);
1658: bus_dmamap_unload(sc->sc_dmat, txs->txs_dmamap);
1659: m_freem(txs->txs_mbuf);
1660: txs->txs_mbuf = NULL;
1661:
1662: SIMPLEQ_INSERT_TAIL(&sc->sc_txfreeq, txs, txs_q);
1663:
1664: /*
1665: * Check for errors and collisions.
1666: */
1667: if (cmdsts &
1668: (CMDSTS_Tx_TXA|CMDSTS_Tx_TFU|CMDSTS_Tx_ED|CMDSTS_Tx_EC)) {
1.34 simonb 1669: ifp->if_oerrors++;
1670: if (cmdsts & CMDSTS_Tx_EC)
1671: ifp->if_collisions += 16;
1.1 thorpej 1672: if (ifp->if_flags & IFF_DEBUG) {
1.34 simonb 1673: if (cmdsts & CMDSTS_Tx_ED)
1.1 thorpej 1674: printf("%s: excessive deferral\n",
1675: sc->sc_dev.dv_xname);
1.34 simonb 1676: if (cmdsts & CMDSTS_Tx_EC)
1.1 thorpej 1677: printf("%s: excessive collisions\n",
1678: sc->sc_dev.dv_xname);
1679: }
1680: } else {
1681: /* Packet was transmitted successfully. */
1682: ifp->if_opackets++;
1683: ifp->if_collisions += CMDSTS_COLLISIONS(cmdsts);
1684: }
1685: }
1686:
1687: /*
1688: * If there are no more pending transmissions, cancel the watchdog
1689: * timer.
1690: */
1.56 thorpej 1691: if (txs == NULL) {
1.1 thorpej 1692: ifp->if_timer = 0;
1.56 thorpej 1693: sc->sc_txwin = 0;
1694: }
1.1 thorpej 1695: }
1696:
1.35 thorpej 1697: #if defined(DP83820)
1.1 thorpej 1698: /*
1699: * sip_rxintr:
1700: *
1701: * Helper; handle receive interrupts.
1702: */
1703: void
1.28 thorpej 1704: SIP_DECL(rxintr)(struct sip_softc *sc)
1.1 thorpej 1705: {
1706: struct ifnet *ifp = &sc->sc_ethercom.ec_if;
1707: struct sip_rxsoft *rxs;
1.36 thorpej 1708: struct mbuf *m, *tailm;
1.35 thorpej 1709: u_int32_t cmdsts, extsts;
1.1 thorpej 1710: int i, len;
1711:
1712: for (i = sc->sc_rxptr;; i = SIP_NEXTRX(i)) {
1713: rxs = &sc->sc_rxsoft[i];
1714:
1715: SIP_CDRXSYNC(sc, i, BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE);
1716:
1.14 tsutsui 1717: cmdsts = le32toh(sc->sc_rxdescs[i].sipd_cmdsts);
1.29 thorpej 1718: extsts = le32toh(sc->sc_rxdescs[i].sipd_extsts);
1.1 thorpej 1719:
1720: /*
1721: * NOTE: OWN is set if owned by _consumer_. We're the
1722: * consumer of the receive ring, so if the bit is clear,
1723: * we have processed all of the packets.
1724: */
1725: if ((cmdsts & CMDSTS_OWN) == 0) {
1726: /*
1727: * We have processed all of the receive buffers.
1728: */
1729: break;
1730: }
1731:
1.36 thorpej 1732: if (__predict_false(sc->sc_rxdiscard)) {
1733: SIP_INIT_RXDESC(sc, i);
1734: if ((cmdsts & CMDSTS_MORE) == 0) {
1735: /* Reset our state. */
1736: sc->sc_rxdiscard = 0;
1737: }
1738: continue;
1739: }
1740:
1741: bus_dmamap_sync(sc->sc_dmat, rxs->rxs_dmamap, 0,
1742: rxs->rxs_dmamap->dm_mapsize, BUS_DMASYNC_POSTREAD);
1743:
1744: m = rxs->rxs_mbuf;
1745:
1746: /*
1747: * Add a new receive buffer to the ring.
1748: */
1749: if (SIP_DECL(add_rxbuf)(sc, i) != 0) {
1750: /*
1751: * Failed, throw away what we've done so
1752: * far, and discard the rest of the packet.
1753: */
1754: ifp->if_ierrors++;
1755: bus_dmamap_sync(sc->sc_dmat, rxs->rxs_dmamap, 0,
1756: rxs->rxs_dmamap->dm_mapsize, BUS_DMASYNC_PREREAD);
1757: SIP_INIT_RXDESC(sc, i);
1758: if (cmdsts & CMDSTS_MORE)
1759: sc->sc_rxdiscard = 1;
1760: if (sc->sc_rxhead != NULL)
1761: m_freem(sc->sc_rxhead);
1762: SIP_RXCHAIN_RESET(sc);
1763: continue;
1764: }
1765:
1766: SIP_RXCHAIN_LINK(sc, m);
1767:
1768: /*
1769: * If this is not the end of the packet, keep
1770: * looking.
1771: */
1772: if (cmdsts & CMDSTS_MORE) {
1773: sc->sc_rxlen += m->m_len;
1774: continue;
1775: }
1776:
1.1 thorpej 1777: /*
1.36 thorpej 1778: * Okay, we have the entire packet now...
1779: */
1780: *sc->sc_rxtailp = NULL;
1781: m = sc->sc_rxhead;
1782: tailm = sc->sc_rxtail;
1783:
1784: SIP_RXCHAIN_RESET(sc);
1785:
1786: /*
1787: * If an error occurred, update stats and drop the packet.
1.1 thorpej 1788: */
1.36 thorpej 1789: if (cmdsts & (CMDSTS_Rx_RXA|CMDSTS_Rx_RUNT|
1.1 thorpej 1790: CMDSTS_Rx_ISE|CMDSTS_Rx_CRCE|CMDSTS_Rx_FAE)) {
1791: ifp->if_ierrors++;
1792: if ((cmdsts & CMDSTS_Rx_RXA) != 0 &&
1793: (cmdsts & CMDSTS_Rx_RXO) == 0) {
1794: /* Receive overrun handled elsewhere. */
1795: printf("%s: receive descriptor error\n",
1796: sc->sc_dev.dv_xname);
1797: }
1798: #define PRINTERR(bit, str) \
1.67 itojun 1799: if ((ifp->if_flags & IFF_DEBUG) != 0 && \
1800: (cmdsts & (bit)) != 0) \
1.1 thorpej 1801: printf("%s: %s\n", sc->sc_dev.dv_xname, str)
1802: PRINTERR(CMDSTS_Rx_RUNT, "runt packet");
1803: PRINTERR(CMDSTS_Rx_ISE, "invalid symbol error");
1804: PRINTERR(CMDSTS_Rx_CRCE, "CRC error");
1805: PRINTERR(CMDSTS_Rx_FAE, "frame alignment error");
1806: #undef PRINTERR
1.36 thorpej 1807: m_freem(m);
1.1 thorpej 1808: continue;
1809: }
1810:
1811: /*
1.40 thorpej 1812: * No errors.
1.36 thorpej 1813: *
1814: * Note, the DP83820 includes the CRC with
1815: * every packet.
1.1 thorpej 1816: */
1.18 thorpej 1817: len = CMDSTS_SIZE(cmdsts);
1.36 thorpej 1818: tailm->m_len = len - sc->sc_rxlen;
1.1 thorpej 1819:
1820: /*
1.2 thorpej 1821: * If the packet is small enough to fit in a
1822: * single header mbuf, allocate one and copy
1823: * the data into it. This greatly reduces
1824: * memory consumption when we receive lots
1825: * of small packets.
1.1 thorpej 1826: */
1.36 thorpej 1827: if (SIP_DECL(copy_small) != 0 && len <= (MHLEN - 2)) {
1828: struct mbuf *nm;
1829: MGETHDR(nm, M_DONTWAIT, MT_DATA);
1830: if (nm == NULL) {
1.2 thorpej 1831: ifp->if_ierrors++;
1.36 thorpej 1832: m_freem(m);
1.2 thorpej 1833: continue;
1834: }
1.36 thorpej 1835: nm->m_data += 2;
1836: nm->m_pkthdr.len = nm->m_len = len;
1837: m_copydata(m, 0, len, mtod(nm, caddr_t));
1838: m_freem(m);
1839: m = nm;
1.1 thorpej 1840: }
1.36 thorpej 1841: #ifndef __NO_STRICT_ALIGNMENT
1842: else {
1843: /*
1844: * The DP83820's receive buffers must be 4-byte
1845: * aligned. But this means that the data after
1846: * the Ethernet header is misaligned. To compensate,
1847: * we have artificially shortened the buffer size
1848: * in the descriptor, and we do an overlapping copy
1849: * of the data two bytes further in (in the first
1850: * buffer of the chain only).
1851: */
1852: memmove(mtod(m, caddr_t) + 2, mtod(m, caddr_t),
1853: m->m_len);
1854: m->m_data += 2;
1.1 thorpej 1855: }
1.36 thorpej 1856: #endif /* ! __NO_STRICT_ALIGNMENT */
1.1 thorpej 1857:
1.29 thorpej 1858: /*
1859: * If VLANs are enabled, VLAN packets have been unwrapped
1860: * for us. Associate the tag with the packet.
1861: */
1862: if (sc->sc_ethercom.ec_nvlans != 0 &&
1863: (extsts & EXTSTS_VPKT) != 0) {
1864: struct mbuf *vtag;
1865:
1866: vtag = m_aux_add(m, AF_LINK, ETHERTYPE_VLAN);
1867: if (vtag == NULL) {
1.40 thorpej 1868: ifp->if_ierrors++;
1.29 thorpej 1869: printf("%s: unable to allocate VLAN tag\n",
1870: sc->sc_dev.dv_xname);
1871: m_freem(m);
1872: continue;
1873: }
1874:
1875: *mtod(vtag, int *) = ntohs(extsts & EXTSTS_VTCI);
1876: vtag->m_len = sizeof(int);
1877: }
1.31 thorpej 1878:
1879: /*
1880: * Set the incoming checksum information for the
1881: * packet.
1882: */
1883: if ((extsts & EXTSTS_IPPKT) != 0) {
1884: SIP_EVCNT_INCR(&sc->sc_ev_rxipsum);
1885: m->m_pkthdr.csum_flags |= M_CSUM_IPv4;
1886: if (extsts & EXTSTS_Rx_IPERR)
1887: m->m_pkthdr.csum_flags |= M_CSUM_IPv4_BAD;
1888: if (extsts & EXTSTS_TCPPKT) {
1889: SIP_EVCNT_INCR(&sc->sc_ev_rxtcpsum);
1890: m->m_pkthdr.csum_flags |= M_CSUM_TCPv4;
1891: if (extsts & EXTSTS_Rx_TCPERR)
1892: m->m_pkthdr.csum_flags |=
1893: M_CSUM_TCP_UDP_BAD;
1894: } else if (extsts & EXTSTS_UDPPKT) {
1895: SIP_EVCNT_INCR(&sc->sc_ev_rxudpsum);
1896: m->m_pkthdr.csum_flags |= M_CSUM_UDPv4;
1897: if (extsts & EXTSTS_Rx_UDPERR)
1898: m->m_pkthdr.csum_flags |=
1899: M_CSUM_TCP_UDP_BAD;
1900: }
1901: }
1.40 thorpej 1902:
1903: ifp->if_ipackets++;
1904: m->m_flags |= M_HASFCS;
1905: m->m_pkthdr.rcvif = ifp;
1906: m->m_pkthdr.len = len;
1907:
1908: #if NBPFILTER > 0
1909: /*
1910: * Pass this up to any BPF listeners, but only
1911: * pass if up the stack if it's for us.
1912: */
1913: if (ifp->if_bpf)
1914: bpf_mtap(ifp->if_bpf, m);
1915: #endif /* NBPFILTER > 0 */
1.29 thorpej 1916:
1.1 thorpej 1917: /* Pass it on. */
1918: (*ifp->if_input)(ifp, m);
1919: }
1920:
1921: /* Update the receive pointer. */
1922: sc->sc_rxptr = i;
1923: }
1.35 thorpej 1924: #else /* ! DP83820 */
1925: /*
1926: * sip_rxintr:
1927: *
1928: * Helper; handle receive interrupts.
1929: */
1930: void
1931: SIP_DECL(rxintr)(struct sip_softc *sc)
1932: {
1933: struct ifnet *ifp = &sc->sc_ethercom.ec_if;
1934: struct sip_rxsoft *rxs;
1935: struct mbuf *m;
1936: u_int32_t cmdsts;
1937: int i, len;
1938:
1939: for (i = sc->sc_rxptr;; i = SIP_NEXTRX(i)) {
1940: rxs = &sc->sc_rxsoft[i];
1941:
1942: SIP_CDRXSYNC(sc, i, BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE);
1943:
1944: cmdsts = le32toh(sc->sc_rxdescs[i].sipd_cmdsts);
1945:
1946: /*
1947: * NOTE: OWN is set if owned by _consumer_. We're the
1948: * consumer of the receive ring, so if the bit is clear,
1949: * we have processed all of the packets.
1950: */
1951: if ((cmdsts & CMDSTS_OWN) == 0) {
1952: /*
1953: * We have processed all of the receive buffers.
1954: */
1955: break;
1956: }
1957:
1958: /*
1959: * If any collisions were seen on the wire, count one.
1960: */
1961: if (cmdsts & CMDSTS_Rx_COL)
1962: ifp->if_collisions++;
1963:
1964: /*
1965: * If an error occurred, update stats, clear the status
1966: * word, and leave the packet buffer in place. It will
1967: * simply be reused the next time the ring comes around.
1968: */
1.36 thorpej 1969: if (cmdsts & (CMDSTS_Rx_RXA|CMDSTS_Rx_RUNT|
1.35 thorpej 1970: CMDSTS_Rx_ISE|CMDSTS_Rx_CRCE|CMDSTS_Rx_FAE)) {
1971: ifp->if_ierrors++;
1972: if ((cmdsts & CMDSTS_Rx_RXA) != 0 &&
1973: (cmdsts & CMDSTS_Rx_RXO) == 0) {
1974: /* Receive overrun handled elsewhere. */
1975: printf("%s: receive descriptor error\n",
1976: sc->sc_dev.dv_xname);
1977: }
1978: #define PRINTERR(bit, str) \
1.67 itojun 1979: if ((ifp->if_flags & IFF_DEBUG) != 0 && \
1980: (cmdsts & (bit)) != 0) \
1.35 thorpej 1981: printf("%s: %s\n", sc->sc_dev.dv_xname, str)
1982: PRINTERR(CMDSTS_Rx_RUNT, "runt packet");
1983: PRINTERR(CMDSTS_Rx_ISE, "invalid symbol error");
1984: PRINTERR(CMDSTS_Rx_CRCE, "CRC error");
1985: PRINTERR(CMDSTS_Rx_FAE, "frame alignment error");
1986: #undef PRINTERR
1987: SIP_INIT_RXDESC(sc, i);
1988: continue;
1989: }
1990:
1991: bus_dmamap_sync(sc->sc_dmat, rxs->rxs_dmamap, 0,
1992: rxs->rxs_dmamap->dm_mapsize, BUS_DMASYNC_POSTREAD);
1993:
1994: /*
1995: * No errors; receive the packet. Note, the SiS 900
1996: * includes the CRC with every packet.
1997: */
1998: len = CMDSTS_SIZE(cmdsts);
1999:
2000: #ifdef __NO_STRICT_ALIGNMENT
2001: /*
2002: * If the packet is small enough to fit in a
2003: * single header mbuf, allocate one and copy
2004: * the data into it. This greatly reduces
2005: * memory consumption when we receive lots
2006: * of small packets.
2007: *
2008: * Otherwise, we add a new buffer to the receive
2009: * chain. If this fails, we drop the packet and
2010: * recycle the old buffer.
2011: */
2012: if (SIP_DECL(copy_small) != 0 && len <= MHLEN) {
2013: MGETHDR(m, M_DONTWAIT, MT_DATA);
2014: if (m == NULL)
2015: goto dropit;
2016: memcpy(mtod(m, caddr_t),
2017: mtod(rxs->rxs_mbuf, caddr_t), len);
2018: SIP_INIT_RXDESC(sc, i);
2019: bus_dmamap_sync(sc->sc_dmat, rxs->rxs_dmamap, 0,
2020: rxs->rxs_dmamap->dm_mapsize,
2021: BUS_DMASYNC_PREREAD);
2022: } else {
2023: m = rxs->rxs_mbuf;
2024: if (SIP_DECL(add_rxbuf)(sc, i) != 0) {
2025: dropit:
2026: ifp->if_ierrors++;
2027: SIP_INIT_RXDESC(sc, i);
2028: bus_dmamap_sync(sc->sc_dmat,
2029: rxs->rxs_dmamap, 0,
2030: rxs->rxs_dmamap->dm_mapsize,
2031: BUS_DMASYNC_PREREAD);
2032: continue;
2033: }
2034: }
2035: #else
2036: /*
2037: * The SiS 900's receive buffers must be 4-byte aligned.
2038: * But this means that the data after the Ethernet header
2039: * is misaligned. We must allocate a new buffer and
2040: * copy the data, shifted forward 2 bytes.
2041: */
2042: MGETHDR(m, M_DONTWAIT, MT_DATA);
2043: if (m == NULL) {
2044: dropit:
2045: ifp->if_ierrors++;
2046: SIP_INIT_RXDESC(sc, i);
2047: bus_dmamap_sync(sc->sc_dmat, rxs->rxs_dmamap, 0,
2048: rxs->rxs_dmamap->dm_mapsize, BUS_DMASYNC_PREREAD);
2049: continue;
2050: }
2051: if (len > (MHLEN - 2)) {
2052: MCLGET(m, M_DONTWAIT);
2053: if ((m->m_flags & M_EXT) == 0) {
2054: m_freem(m);
2055: goto dropit;
2056: }
2057: }
2058: m->m_data += 2;
2059:
2060: /*
2061: * Note that we use clusters for incoming frames, so the
2062: * buffer is virtually contiguous.
2063: */
2064: memcpy(mtod(m, caddr_t), mtod(rxs->rxs_mbuf, caddr_t), len);
2065:
2066: /* Allow the receive descriptor to continue using its mbuf. */
2067: SIP_INIT_RXDESC(sc, i);
2068: bus_dmamap_sync(sc->sc_dmat, rxs->rxs_dmamap, 0,
2069: rxs->rxs_dmamap->dm_mapsize, BUS_DMASYNC_PREREAD);
2070: #endif /* __NO_STRICT_ALIGNMENT */
2071:
2072: ifp->if_ipackets++;
2073: m->m_flags |= M_HASFCS;
2074: m->m_pkthdr.rcvif = ifp;
2075: m->m_pkthdr.len = m->m_len = len;
2076:
2077: #if NBPFILTER > 0
2078: /*
2079: * Pass this up to any BPF listeners, but only
2080: * pass if up the stack if it's for us.
2081: */
2082: if (ifp->if_bpf)
2083: bpf_mtap(ifp->if_bpf, m);
2084: #endif /* NBPFILTER > 0 */
2085:
2086: /* Pass it on. */
2087: (*ifp->if_input)(ifp, m);
2088: }
2089:
2090: /* Update the receive pointer. */
2091: sc->sc_rxptr = i;
2092: }
2093: #endif /* DP83820 */
1.1 thorpej 2094:
2095: /*
2096: * sip_tick:
2097: *
2098: * One second timer, used to tick the MII.
2099: */
2100: void
1.28 thorpej 2101: SIP_DECL(tick)(void *arg)
1.1 thorpej 2102: {
2103: struct sip_softc *sc = arg;
2104: int s;
2105:
2106: s = splnet();
2107: mii_tick(&sc->sc_mii);
2108: splx(s);
2109:
1.29 thorpej 2110: callout_reset(&sc->sc_tick_ch, hz, SIP_DECL(tick), sc);
1.1 thorpej 2111: }
2112:
2113: /*
2114: * sip_reset:
2115: *
2116: * Perform a soft reset on the SiS 900.
2117: */
2118: void
1.28 thorpej 2119: SIP_DECL(reset)(struct sip_softc *sc)
1.1 thorpej 2120: {
2121: bus_space_tag_t st = sc->sc_st;
2122: bus_space_handle_t sh = sc->sc_sh;
2123: int i;
2124:
1.45 thorpej 2125: bus_space_write_4(st, sh, SIP_IER, 0);
2126: bus_space_write_4(st, sh, SIP_IMR, 0);
2127: bus_space_write_4(st, sh, SIP_RFCR, 0);
1.1 thorpej 2128: bus_space_write_4(st, sh, SIP_CR, CR_RST);
2129:
1.14 tsutsui 2130: for (i = 0; i < SIP_TIMEOUT; i++) {
2131: if ((bus_space_read_4(st, sh, SIP_CR) & CR_RST) == 0)
2132: break;
1.1 thorpej 2133: delay(2);
2134: }
2135:
1.14 tsutsui 2136: if (i == SIP_TIMEOUT)
2137: printf("%s: reset failed to complete\n", sc->sc_dev.dv_xname);
2138:
2139: delay(1000);
1.29 thorpej 2140:
2141: #ifdef DP83820
2142: /*
2143: * Set the general purpose I/O bits. Do it here in case we
2144: * need to have GPIO set up to talk to the media interface.
2145: */
2146: bus_space_write_4(st, sh, SIP_GPIOR, sc->sc_gpior);
2147: delay(1000);
2148: #endif /* DP83820 */
1.1 thorpej 2149: }
2150:
2151: /*
1.17 thorpej 2152: * sip_init: [ ifnet interface function ]
1.1 thorpej 2153: *
2154: * Initialize the interface. Must be called at splnet().
2155: */
1.2 thorpej 2156: int
1.28 thorpej 2157: SIP_DECL(init)(struct ifnet *ifp)
1.1 thorpej 2158: {
1.17 thorpej 2159: struct sip_softc *sc = ifp->if_softc;
1.1 thorpej 2160: bus_space_tag_t st = sc->sc_st;
2161: bus_space_handle_t sh = sc->sc_sh;
2162: struct sip_txsoft *txs;
1.2 thorpej 2163: struct sip_rxsoft *rxs;
1.1 thorpej 2164: struct sip_desc *sipd;
1.29 thorpej 2165: u_int32_t reg;
1.2 thorpej 2166: int i, error = 0;
1.1 thorpej 2167:
2168: /*
2169: * Cancel any pending I/O.
2170: */
1.28 thorpej 2171: SIP_DECL(stop)(ifp, 0);
1.1 thorpej 2172:
2173: /*
2174: * Reset the chip to a known state.
2175: */
1.28 thorpej 2176: SIP_DECL(reset)(sc);
1.1 thorpej 2177:
1.29 thorpej 2178: #if !defined(DP83820)
1.45 thorpej 2179: if (SIP_CHIP_MODEL(sc, PCI_VENDOR_NS, PCI_PRODUCT_NS_DP83815)) {
1.25 briggs 2180: /*
2181: * DP83815 manual, page 78:
2182: * 4.4 Recommended Registers Configuration
2183: * For optimum performance of the DP83815, version noted
2184: * as DP83815CVNG (SRR = 203h), the listed register
2185: * modifications must be followed in sequence...
2186: *
2187: * It's not clear if this should be 302h or 203h because that
2188: * chip name is listed as SRR 302h in the description of the
1.26 briggs 2189: * SRR register. However, my revision 302h DP83815 on the
2190: * Netgear FA311 purchased in 02/2001 needs these settings
2191: * to avoid tons of errors in AcceptPerfectMatch (non-
2192: * IFF_PROMISC) mode. I do not know if other revisions need
2193: * this set or not. [briggs -- 09 March 2001]
2194: *
2195: * Note that only the low-order 12 bits of 0xe4 are documented
2196: * and that this sets reserved bits in that register.
1.25 briggs 2197: */
1.29 thorpej 2198: reg = bus_space_read_4(st, sh, SIP_NS_SRR);
2199: if (reg == 0x302) {
1.25 briggs 2200: bus_space_write_4(st, sh, 0x00cc, 0x0001);
2201: bus_space_write_4(st, sh, 0x00e4, 0x189C);
2202: bus_space_write_4(st, sh, 0x00fc, 0x0000);
2203: bus_space_write_4(st, sh, 0x00f4, 0x5040);
2204: bus_space_write_4(st, sh, 0x00f8, 0x008c);
2205: }
2206: }
1.29 thorpej 2207: #endif /* ! DP83820 */
1.25 briggs 2208:
1.1 thorpej 2209: /*
2210: * Initialize the transmit descriptor ring.
2211: */
2212: for (i = 0; i < SIP_NTXDESC; i++) {
2213: sipd = &sc->sc_txdescs[i];
2214: memset(sipd, 0, sizeof(struct sip_desc));
1.14 tsutsui 2215: sipd->sipd_link = htole32(SIP_CDTXADDR(sc, SIP_NEXTTX(i)));
1.1 thorpej 2216: }
2217: SIP_CDTXSYNC(sc, 0, SIP_NTXDESC,
2218: BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
2219: sc->sc_txfree = SIP_NTXDESC;
2220: sc->sc_txnext = 0;
1.56 thorpej 2221: sc->sc_txwin = 0;
1.1 thorpej 2222:
2223: /*
2224: * Initialize the transmit job descriptors.
2225: */
2226: SIMPLEQ_INIT(&sc->sc_txfreeq);
2227: SIMPLEQ_INIT(&sc->sc_txdirtyq);
2228: for (i = 0; i < SIP_TXQUEUELEN; i++) {
2229: txs = &sc->sc_txsoft[i];
2230: txs->txs_mbuf = NULL;
2231: SIMPLEQ_INSERT_TAIL(&sc->sc_txfreeq, txs, txs_q);
2232: }
2233:
2234: /*
2235: * Initialize the receive descriptor and receive job
1.2 thorpej 2236: * descriptor rings.
1.1 thorpej 2237: */
1.2 thorpej 2238: for (i = 0; i < SIP_NRXDESC; i++) {
2239: rxs = &sc->sc_rxsoft[i];
2240: if (rxs->rxs_mbuf == NULL) {
1.28 thorpej 2241: if ((error = SIP_DECL(add_rxbuf)(sc, i)) != 0) {
1.2 thorpej 2242: printf("%s: unable to allocate or map rx "
2243: "buffer %d, error = %d\n",
2244: sc->sc_dev.dv_xname, i, error);
2245: /*
2246: * XXX Should attempt to run with fewer receive
2247: * XXX buffers instead of just failing.
2248: */
1.28 thorpej 2249: SIP_DECL(rxdrain)(sc);
1.2 thorpej 2250: goto out;
2251: }
1.42 thorpej 2252: } else
2253: SIP_INIT_RXDESC(sc, i);
1.2 thorpej 2254: }
1.1 thorpej 2255: sc->sc_rxptr = 0;
1.36 thorpej 2256: #ifdef DP83820
2257: sc->sc_rxdiscard = 0;
2258: SIP_RXCHAIN_RESET(sc);
2259: #endif /* DP83820 */
1.1 thorpej 2260:
2261: /*
1.29 thorpej 2262: * Set the configuration register; it's already initialized
2263: * in sip_attach().
1.1 thorpej 2264: */
1.29 thorpej 2265: bus_space_write_4(st, sh, SIP_CFG, sc->sc_cfg);
1.1 thorpej 2266:
2267: /*
2268: * Initialize the prototype TXCFG register.
2269: */
1.45 thorpej 2270: #if defined(DP83820)
2271: sc->sc_txcfg = TXCFG_MXDMA_512;
2272: sc->sc_rxcfg = RXCFG_MXDMA_512;
2273: #else
2274: if ((SIP_SIS900_REV(sc, SIS_REV_635) ||
2275: SIP_SIS900_REV(sc, SIS_REV_900B)) &&
2276: (bus_space_read_4(sc->sc_st, sc->sc_sh, SIP_CFG) & CFG_EDBMASTEN)) {
2277: sc->sc_txcfg = TXCFG_MXDMA_64;
2278: sc->sc_rxcfg = RXCFG_MXDMA_64;
2279: } else {
2280: sc->sc_txcfg = TXCFG_MXDMA_512;
2281: sc->sc_rxcfg = RXCFG_MXDMA_512;
2282: }
2283: #endif /* DP83820 */
2284:
2285: sc->sc_txcfg |= TXCFG_ATP |
1.1 thorpej 2286: (sc->sc_tx_fill_thresh << TXCFG_FLTH_SHIFT) |
2287: sc->sc_tx_drain_thresh;
2288: bus_space_write_4(st, sh, SIP_TXCFG, sc->sc_txcfg);
2289:
2290: /*
2291: * Initialize the receive drain threshold if we have never
2292: * done so.
2293: */
2294: if (sc->sc_rx_drain_thresh == 0) {
2295: /*
2296: * XXX This value should be tuned. This is set to the
2297: * maximum of 248 bytes, and we may be able to improve
2298: * performance by decreasing it (although we should never
2299: * set this value lower than 2; 14 bytes are required to
2300: * filter the packet).
2301: */
2302: sc->sc_rx_drain_thresh = RXCFG_DRTH >> RXCFG_DRTH_SHIFT;
2303: }
2304:
2305: /*
2306: * Initialize the prototype RXCFG register.
2307: */
1.45 thorpej 2308: sc->sc_rxcfg |= (sc->sc_rx_drain_thresh << RXCFG_DRTH_SHIFT);
1.1 thorpej 2309: bus_space_write_4(st, sh, SIP_RXCFG, sc->sc_rxcfg);
2310:
1.29 thorpej 2311: #ifdef DP83820
2312: /*
2313: * Initialize the VLAN/IP receive control register.
1.31 thorpej 2314: * We enable checksum computation on all incoming
2315: * packets, and do not reject packets w/ bad checksums.
1.29 thorpej 2316: */
2317: reg = 0;
1.31 thorpej 2318: if (ifp->if_capenable &
2319: (IFCAP_CSUM_IPv4|IFCAP_CSUM_TCPv4|IFCAP_CSUM_UDPv4))
2320: reg |= VRCR_IPEN;
1.29 thorpej 2321: if (sc->sc_ethercom.ec_nvlans != 0)
2322: reg |= VRCR_VTDEN|VRCR_VTREN;
2323: bus_space_write_4(st, sh, SIP_VRCR, reg);
2324:
2325: /*
2326: * Initialize the VLAN/IP transmit control register.
1.31 thorpej 2327: * We enable outgoing checksum computation on a
2328: * per-packet basis.
1.29 thorpej 2329: */
2330: reg = 0;
1.31 thorpej 2331: if (ifp->if_capenable &
2332: (IFCAP_CSUM_IPv4|IFCAP_CSUM_TCPv4|IFCAP_CSUM_UDPv4))
2333: reg |= VTCR_PPCHK;
1.29 thorpej 2334: if (sc->sc_ethercom.ec_nvlans != 0)
2335: reg |= VTCR_VPPTI;
2336: bus_space_write_4(st, sh, SIP_VTCR, reg);
2337:
2338: /*
2339: * If we're using VLANs, initialize the VLAN data register.
2340: * To understand why we bswap the VLAN Ethertype, see section
2341: * 4.2.36 of the DP83820 manual.
2342: */
2343: if (sc->sc_ethercom.ec_nvlans != 0)
2344: bus_space_write_4(st, sh, SIP_VDR, bswap16(ETHERTYPE_VLAN));
2345: #endif /* DP83820 */
2346:
1.1 thorpej 2347: /*
2348: * Give the transmit and receive rings to the chip.
2349: */
2350: bus_space_write_4(st, sh, SIP_TXDP, SIP_CDTXADDR(sc, sc->sc_txnext));
2351: bus_space_write_4(st, sh, SIP_RXDP, SIP_CDRXADDR(sc, sc->sc_rxptr));
2352:
2353: /*
2354: * Initialize the interrupt mask.
2355: */
2356: sc->sc_imr = ISR_DPERR|ISR_SSERR|ISR_RMABT|ISR_RTABT|ISR_RXSOVR|
1.56 thorpej 2357: ISR_TXURN|ISR_TXDESC|ISR_TXIDLE|ISR_RXORN|ISR_RXIDLE|ISR_RXDESC;
1.1 thorpej 2358: bus_space_write_4(st, sh, SIP_IMR, sc->sc_imr);
2359:
1.45 thorpej 2360: /* Set up the receive filter. */
2361: (*sc->sc_model->sip_variant->sipv_set_filter)(sc);
2362:
1.1 thorpej 2363: /*
2364: * Set the current media. Do this after initializing the prototype
2365: * IMR, since sip_mii_statchg() modifies the IMR for 802.3x flow
2366: * control.
2367: */
2368: mii_mediachg(&sc->sc_mii);
2369:
2370: /*
2371: * Enable interrupts.
2372: */
2373: bus_space_write_4(st, sh, SIP_IER, IER_IE);
2374:
2375: /*
2376: * Start the transmit and receive processes.
2377: */
2378: bus_space_write_4(st, sh, SIP_CR, CR_RXE | CR_TXE);
2379:
2380: /*
2381: * Start the one second MII clock.
2382: */
1.29 thorpej 2383: callout_reset(&sc->sc_tick_ch, hz, SIP_DECL(tick), sc);
1.1 thorpej 2384:
2385: /*
2386: * ...all done!
2387: */
2388: ifp->if_flags |= IFF_RUNNING;
2389: ifp->if_flags &= ~IFF_OACTIVE;
1.2 thorpej 2390:
2391: out:
2392: if (error)
2393: printf("%s: interface not running\n", sc->sc_dev.dv_xname);
2394: return (error);
2395: }
2396:
2397: /*
2398: * sip_drain:
2399: *
2400: * Drain the receive queue.
2401: */
2402: void
1.28 thorpej 2403: SIP_DECL(rxdrain)(struct sip_softc *sc)
1.2 thorpej 2404: {
2405: struct sip_rxsoft *rxs;
2406: int i;
2407:
2408: for (i = 0; i < SIP_NRXDESC; i++) {
2409: rxs = &sc->sc_rxsoft[i];
2410: if (rxs->rxs_mbuf != NULL) {
2411: bus_dmamap_unload(sc->sc_dmat, rxs->rxs_dmamap);
2412: m_freem(rxs->rxs_mbuf);
2413: rxs->rxs_mbuf = NULL;
2414: }
2415: }
1.1 thorpej 2416: }
2417:
2418: /*
1.17 thorpej 2419: * sip_stop: [ ifnet interface function ]
1.1 thorpej 2420: *
2421: * Stop transmission on the interface.
2422: */
2423: void
1.28 thorpej 2424: SIP_DECL(stop)(struct ifnet *ifp, int disable)
1.1 thorpej 2425: {
1.17 thorpej 2426: struct sip_softc *sc = ifp->if_softc;
1.1 thorpej 2427: bus_space_tag_t st = sc->sc_st;
2428: bus_space_handle_t sh = sc->sc_sh;
2429: struct sip_txsoft *txs;
2430: u_int32_t cmdsts = 0; /* DEBUG */
2431:
2432: /*
2433: * Stop the one second clock.
2434: */
1.9 thorpej 2435: callout_stop(&sc->sc_tick_ch);
1.4 thorpej 2436:
2437: /* Down the MII. */
2438: mii_down(&sc->sc_mii);
1.1 thorpej 2439:
2440: /*
2441: * Disable interrupts.
2442: */
2443: bus_space_write_4(st, sh, SIP_IER, 0);
2444:
2445: /*
2446: * Stop receiver and transmitter.
2447: */
2448: bus_space_write_4(st, sh, SIP_CR, CR_RXD | CR_TXD);
2449:
2450: /*
2451: * Release any queued transmit buffers.
2452: */
2453: while ((txs = SIMPLEQ_FIRST(&sc->sc_txdirtyq)) != NULL) {
2454: if ((ifp->if_flags & IFF_DEBUG) != 0 &&
2455: SIMPLEQ_NEXT(txs, txs_q) == NULL &&
1.14 tsutsui 2456: (le32toh(sc->sc_txdescs[txs->txs_lastdesc].sipd_cmdsts) &
1.1 thorpej 2457: CMDSTS_INTR) == 0)
2458: printf("%s: sip_stop: last descriptor does not "
2459: "have INTR bit set\n", sc->sc_dev.dv_xname);
1.54 lukem 2460: SIMPLEQ_REMOVE_HEAD(&sc->sc_txdirtyq, txs_q);
1.1 thorpej 2461: #ifdef DIAGNOSTIC
2462: if (txs->txs_mbuf == NULL) {
2463: printf("%s: dirty txsoft with no mbuf chain\n",
2464: sc->sc_dev.dv_xname);
2465: panic("sip_stop");
2466: }
2467: #endif
2468: cmdsts |= /* DEBUG */
1.14 tsutsui 2469: le32toh(sc->sc_txdescs[txs->txs_lastdesc].sipd_cmdsts);
1.1 thorpej 2470: bus_dmamap_unload(sc->sc_dmat, txs->txs_dmamap);
2471: m_freem(txs->txs_mbuf);
2472: txs->txs_mbuf = NULL;
2473: SIMPLEQ_INSERT_TAIL(&sc->sc_txfreeq, txs, txs_q);
1.2 thorpej 2474: }
2475:
1.17 thorpej 2476: if (disable)
1.28 thorpej 2477: SIP_DECL(rxdrain)(sc);
1.1 thorpej 2478:
2479: /*
2480: * Mark the interface down and cancel the watchdog timer.
2481: */
2482: ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE);
2483: ifp->if_timer = 0;
2484:
2485: if ((ifp->if_flags & IFF_DEBUG) != 0 &&
2486: (cmdsts & CMDSTS_INTR) == 0 && sc->sc_txfree != SIP_NTXDESC)
2487: printf("%s: sip_stop: no INTR bits set in dirty tx "
2488: "descriptors\n", sc->sc_dev.dv_xname);
2489: }
2490:
2491: /*
2492: * sip_read_eeprom:
2493: *
2494: * Read data from the serial EEPROM.
2495: */
2496: void
1.28 thorpej 2497: SIP_DECL(read_eeprom)(struct sip_softc *sc, int word, int wordcnt,
2498: u_int16_t *data)
1.1 thorpej 2499: {
2500: bus_space_tag_t st = sc->sc_st;
2501: bus_space_handle_t sh = sc->sc_sh;
2502: u_int16_t reg;
2503: int i, x;
2504:
2505: for (i = 0; i < wordcnt; i++) {
2506: /* Send CHIP SELECT. */
2507: reg = EROMAR_EECS;
2508: bus_space_write_4(st, sh, SIP_EROMAR, reg);
2509:
2510: /* Shift in the READ opcode. */
2511: for (x = 3; x > 0; x--) {
2512: if (SIP_EEPROM_OPC_READ & (1 << (x - 1)))
2513: reg |= EROMAR_EEDI;
2514: else
2515: reg &= ~EROMAR_EEDI;
2516: bus_space_write_4(st, sh, SIP_EROMAR, reg);
2517: bus_space_write_4(st, sh, SIP_EROMAR,
2518: reg | EROMAR_EESK);
2519: delay(4);
2520: bus_space_write_4(st, sh, SIP_EROMAR, reg);
2521: delay(4);
2522: }
2523:
2524: /* Shift in address. */
2525: for (x = 6; x > 0; x--) {
2526: if ((word + i) & (1 << (x - 1)))
2527: reg |= EROMAR_EEDI;
2528: else
2529: reg &= ~EROMAR_EEDI;
2530: bus_space_write_4(st, sh, SIP_EROMAR, reg);
2531: bus_space_write_4(st, sh, SIP_EROMAR,
2532: reg | EROMAR_EESK);
2533: delay(4);
2534: bus_space_write_4(st, sh, SIP_EROMAR, reg);
2535: delay(4);
2536: }
2537:
2538: /* Shift out data. */
2539: reg = EROMAR_EECS;
2540: data[i] = 0;
2541: for (x = 16; x > 0; x--) {
2542: bus_space_write_4(st, sh, SIP_EROMAR,
2543: reg | EROMAR_EESK);
2544: delay(4);
2545: if (bus_space_read_4(st, sh, SIP_EROMAR) & EROMAR_EEDO)
2546: data[i] |= (1 << (x - 1));
2547: bus_space_write_4(st, sh, SIP_EROMAR, reg);
1.13 tsutsui 2548: delay(4);
1.1 thorpej 2549: }
2550:
2551: /* Clear CHIP SELECT. */
2552: bus_space_write_4(st, sh, SIP_EROMAR, 0);
2553: delay(4);
2554: }
2555: }
2556:
2557: /*
2558: * sip_add_rxbuf:
2559: *
2560: * Add a receive buffer to the indicated descriptor.
2561: */
2562: int
1.28 thorpej 2563: SIP_DECL(add_rxbuf)(struct sip_softc *sc, int idx)
1.1 thorpej 2564: {
2565: struct sip_rxsoft *rxs = &sc->sc_rxsoft[idx];
2566: struct mbuf *m;
2567: int error;
2568:
2569: MGETHDR(m, M_DONTWAIT, MT_DATA);
2570: if (m == NULL)
2571: return (ENOBUFS);
2572:
2573: MCLGET(m, M_DONTWAIT);
2574: if ((m->m_flags & M_EXT) == 0) {
2575: m_freem(m);
2576: return (ENOBUFS);
2577: }
1.36 thorpej 2578:
2579: #if defined(DP83820)
2580: m->m_len = SIP_RXBUF_LEN;
2581: #endif /* DP83820 */
1.1 thorpej 2582:
2583: if (rxs->rxs_mbuf != NULL)
2584: bus_dmamap_unload(sc->sc_dmat, rxs->rxs_dmamap);
2585:
2586: rxs->rxs_mbuf = m;
2587:
2588: error = bus_dmamap_load(sc->sc_dmat, rxs->rxs_dmamap,
1.41 thorpej 2589: m->m_ext.ext_buf, m->m_ext.ext_size, NULL,
2590: BUS_DMA_READ|BUS_DMA_NOWAIT);
1.1 thorpej 2591: if (error) {
2592: printf("%s: can't load rx DMA map %d, error = %d\n",
2593: sc->sc_dev.dv_xname, idx, error);
2594: panic("sip_add_rxbuf"); /* XXX */
2595: }
2596:
2597: bus_dmamap_sync(sc->sc_dmat, rxs->rxs_dmamap, 0,
2598: rxs->rxs_dmamap->dm_mapsize, BUS_DMASYNC_PREREAD);
2599:
2600: SIP_INIT_RXDESC(sc, idx);
2601:
2602: return (0);
2603: }
2604:
1.29 thorpej 2605: #if !defined(DP83820)
1.1 thorpej 2606: /*
1.15 thorpej 2607: * sip_sis900_set_filter:
1.1 thorpej 2608: *
2609: * Set up the receive filter.
2610: */
2611: void
1.28 thorpej 2612: SIP_DECL(sis900_set_filter)(struct sip_softc *sc)
1.1 thorpej 2613: {
2614: bus_space_tag_t st = sc->sc_st;
2615: bus_space_handle_t sh = sc->sc_sh;
2616: struct ethercom *ec = &sc->sc_ethercom;
2617: struct ifnet *ifp = &sc->sc_ethercom.ec_if;
2618: struct ether_multi *enm;
1.11 thorpej 2619: u_int8_t *cp;
1.1 thorpej 2620: struct ether_multistep step;
1.45 thorpej 2621: u_int32_t crc, mchash[16];
1.1 thorpej 2622:
2623: /*
2624: * Initialize the prototype RFCR.
2625: */
2626: sc->sc_rfcr = RFCR_RFEN;
2627: if (ifp->if_flags & IFF_BROADCAST)
2628: sc->sc_rfcr |= RFCR_AAB;
2629: if (ifp->if_flags & IFF_PROMISC) {
2630: sc->sc_rfcr |= RFCR_AAP;
2631: goto allmulti;
2632: }
2633:
2634: /*
2635: * Set up the multicast address filter by passing all multicast
2636: * addresses through a CRC generator, and then using the high-order
2637: * 6 bits as an index into the 128 bit multicast hash table (only
2638: * the lower 16 bits of each 32 bit multicast hash register are
2639: * valid). The high order bits select the register, while the
2640: * rest of the bits select the bit within the register.
2641: */
2642:
2643: memset(mchash, 0, sizeof(mchash));
2644:
2645: ETHER_FIRST_MULTI(step, ec, enm);
2646: while (enm != NULL) {
1.37 thorpej 2647: if (memcmp(enm->enm_addrlo, enm->enm_addrhi, ETHER_ADDR_LEN)) {
1.1 thorpej 2648: /*
2649: * We must listen to a range of multicast addresses.
2650: * For now, just accept all multicasts, rather than
2651: * trying to set only those filter bits needed to match
2652: * the range. (At this time, the only use of address
2653: * ranges is for IP multicast routing, for which the
2654: * range is big enough to require all bits set.)
2655: */
2656: goto allmulti;
2657: }
2658:
1.45 thorpej 2659: crc = ether_crc32_be(enm->enm_addrlo, ETHER_ADDR_LEN);
1.11 thorpej 2660:
1.45 thorpej 2661: if (SIP_SIS900_REV(sc, SIS_REV_635) ||
2662: SIP_SIS900_REV(sc, SIS_REV_900B)) {
2663: /* Just want the 8 most significant bits. */
2664: crc >>= 24;
2665: } else {
2666: /* Just want the 7 most significant bits. */
2667: crc >>= 25;
2668: }
1.1 thorpej 2669:
2670: /* Set the corresponding bit in the hash table. */
2671: mchash[crc >> 4] |= 1 << (crc & 0xf);
2672:
2673: ETHER_NEXT_MULTI(step, enm);
2674: }
2675:
2676: ifp->if_flags &= ~IFF_ALLMULTI;
2677: goto setit;
2678:
2679: allmulti:
2680: ifp->if_flags |= IFF_ALLMULTI;
2681: sc->sc_rfcr |= RFCR_AAM;
2682:
2683: setit:
2684: #define FILTER_EMIT(addr, data) \
2685: bus_space_write_4(st, sh, SIP_RFCR, (addr)); \
1.14 tsutsui 2686: delay(1); \
2687: bus_space_write_4(st, sh, SIP_RFDR, (data)); \
2688: delay(1)
1.1 thorpej 2689:
2690: /*
2691: * Disable receive filter, and program the node address.
2692: */
2693: cp = LLADDR(ifp->if_sadl);
2694: FILTER_EMIT(RFCR_RFADDR_NODE0, (cp[1] << 8) | cp[0]);
2695: FILTER_EMIT(RFCR_RFADDR_NODE2, (cp[3] << 8) | cp[2]);
2696: FILTER_EMIT(RFCR_RFADDR_NODE4, (cp[5] << 8) | cp[4]);
2697:
2698: if ((ifp->if_flags & IFF_ALLMULTI) == 0) {
2699: /*
2700: * Program the multicast hash table.
2701: */
2702: FILTER_EMIT(RFCR_RFADDR_MC0, mchash[0]);
2703: FILTER_EMIT(RFCR_RFADDR_MC1, mchash[1]);
2704: FILTER_EMIT(RFCR_RFADDR_MC2, mchash[2]);
2705: FILTER_EMIT(RFCR_RFADDR_MC3, mchash[3]);
2706: FILTER_EMIT(RFCR_RFADDR_MC4, mchash[4]);
2707: FILTER_EMIT(RFCR_RFADDR_MC5, mchash[5]);
2708: FILTER_EMIT(RFCR_RFADDR_MC6, mchash[6]);
2709: FILTER_EMIT(RFCR_RFADDR_MC7, mchash[7]);
1.45 thorpej 2710: if (SIP_SIS900_REV(sc, SIS_REV_635) ||
2711: SIP_SIS900_REV(sc, SIS_REV_900B)) {
2712: FILTER_EMIT(RFCR_RFADDR_MC8, mchash[8]);
2713: FILTER_EMIT(RFCR_RFADDR_MC9, mchash[9]);
2714: FILTER_EMIT(RFCR_RFADDR_MC10, mchash[10]);
2715: FILTER_EMIT(RFCR_RFADDR_MC11, mchash[11]);
2716: FILTER_EMIT(RFCR_RFADDR_MC12, mchash[12]);
2717: FILTER_EMIT(RFCR_RFADDR_MC13, mchash[13]);
2718: FILTER_EMIT(RFCR_RFADDR_MC14, mchash[14]);
2719: FILTER_EMIT(RFCR_RFADDR_MC15, mchash[15]);
2720: }
1.1 thorpej 2721: }
2722: #undef FILTER_EMIT
2723:
2724: /*
2725: * Re-enable the receiver filter.
2726: */
2727: bus_space_write_4(st, sh, SIP_RFCR, sc->sc_rfcr);
2728: }
1.29 thorpej 2729: #endif /* ! DP83820 */
1.1 thorpej 2730:
2731: /*
1.15 thorpej 2732: * sip_dp83815_set_filter:
2733: *
2734: * Set up the receive filter.
2735: */
2736: void
1.28 thorpej 2737: SIP_DECL(dp83815_set_filter)(struct sip_softc *sc)
1.15 thorpej 2738: {
2739: bus_space_tag_t st = sc->sc_st;
2740: bus_space_handle_t sh = sc->sc_sh;
2741: struct ethercom *ec = &sc->sc_ethercom;
2742: struct ifnet *ifp = &sc->sc_ethercom.ec_if;
2743: struct ether_multi *enm;
2744: u_int8_t *cp;
2745: struct ether_multistep step;
1.29 thorpej 2746: u_int32_t crc, hash, slot, bit;
2747: #ifdef DP83820
2748: #define MCHASH_NWORDS 128
2749: #else
2750: #define MCHASH_NWORDS 32
2751: #endif /* DP83820 */
2752: u_int16_t mchash[MCHASH_NWORDS];
1.15 thorpej 2753: int i;
2754:
2755: /*
2756: * Initialize the prototype RFCR.
1.27 briggs 2757: * Enable the receive filter, and accept on
2758: * Perfect (destination address) Match
1.26 briggs 2759: * If IFF_BROADCAST, also accept all broadcast packets.
2760: * If IFF_PROMISC, accept all unicast packets (and later, set
2761: * IFF_ALLMULTI and accept all multicast, too).
1.15 thorpej 2762: */
1.27 briggs 2763: sc->sc_rfcr = RFCR_RFEN | RFCR_APM;
1.15 thorpej 2764: if (ifp->if_flags & IFF_BROADCAST)
2765: sc->sc_rfcr |= RFCR_AAB;
2766: if (ifp->if_flags & IFF_PROMISC) {
2767: sc->sc_rfcr |= RFCR_AAP;
2768: goto allmulti;
2769: }
2770:
1.29 thorpej 2771: #ifdef DP83820
1.15 thorpej 2772: /*
1.29 thorpej 2773: * Set up the DP83820 multicast address filter by passing all multicast
2774: * addresses through a CRC generator, and then using the high-order
2775: * 11 bits as an index into the 2048 bit multicast hash table. The
2776: * high-order 7 bits select the slot, while the low-order 4 bits
2777: * select the bit within the slot. Note that only the low 16-bits
2778: * of each filter word are used, and there are 128 filter words.
2779: */
2780: #else
2781: /*
2782: * Set up the DP83815 multicast address filter by passing all multicast
1.15 thorpej 2783: * addresses through a CRC generator, and then using the high-order
2784: * 9 bits as an index into the 512 bit multicast hash table. The
1.29 thorpej 2785: * high-order 5 bits select the slot, while the low-order 4 bits
1.15 thorpej 2786: * select the bit within the slot. Note that only the low 16-bits
1.29 thorpej 2787: * of each filter word are used, and there are 32 filter words.
1.15 thorpej 2788: */
1.29 thorpej 2789: #endif /* DP83820 */
1.15 thorpej 2790:
2791: memset(mchash, 0, sizeof(mchash));
2792:
1.26 briggs 2793: ifp->if_flags &= ~IFF_ALLMULTI;
1.15 thorpej 2794: ETHER_FIRST_MULTI(step, ec, enm);
1.38 thorpej 2795: if (enm == NULL)
2796: goto setit;
2797: while (enm != NULL) {
1.39 thorpej 2798: if (memcmp(enm->enm_addrlo, enm->enm_addrhi, ETHER_ADDR_LEN)) {
1.15 thorpej 2799: /*
2800: * We must listen to a range of multicast addresses.
2801: * For now, just accept all multicasts, rather than
2802: * trying to set only those filter bits needed to match
2803: * the range. (At this time, the only use of address
2804: * ranges is for IP multicast routing, for which the
2805: * range is big enough to require all bits set.)
2806: */
1.38 thorpej 2807: goto allmulti;
2808: }
1.26 briggs 2809:
1.38 thorpej 2810: crc = ether_crc32_be(enm->enm_addrlo, ETHER_ADDR_LEN);
1.29 thorpej 2811:
1.49 is 2812: #ifdef DP83820
1.38 thorpej 2813: /* Just want the 11 most significant bits. */
2814: hash = crc >> 21;
1.29 thorpej 2815: #else
1.38 thorpej 2816: /* Just want the 9 most significant bits. */
2817: hash = crc >> 23;
1.29 thorpej 2818: #endif /* DP83820 */
1.49 is 2819:
1.38 thorpej 2820: slot = hash >> 4;
2821: bit = hash & 0xf;
1.15 thorpej 2822:
1.38 thorpej 2823: /* Set the corresponding bit in the hash table. */
2824: mchash[slot] |= 1 << bit;
1.15 thorpej 2825:
1.38 thorpej 2826: ETHER_NEXT_MULTI(step, enm);
1.15 thorpej 2827: }
1.38 thorpej 2828: sc->sc_rfcr |= RFCR_MHEN;
1.15 thorpej 2829: goto setit;
2830:
2831: allmulti:
2832: ifp->if_flags |= IFF_ALLMULTI;
2833: sc->sc_rfcr |= RFCR_AAM;
2834:
2835: setit:
2836: #define FILTER_EMIT(addr, data) \
2837: bus_space_write_4(st, sh, SIP_RFCR, (addr)); \
2838: delay(1); \
2839: bus_space_write_4(st, sh, SIP_RFDR, (data)); \
1.39 thorpej 2840: delay(1)
1.15 thorpej 2841:
2842: /*
2843: * Disable receive filter, and program the node address.
2844: */
2845: cp = LLADDR(ifp->if_sadl);
1.26 briggs 2846: FILTER_EMIT(RFCR_NS_RFADDR_PMATCH0, (cp[1] << 8) | cp[0]);
2847: FILTER_EMIT(RFCR_NS_RFADDR_PMATCH2, (cp[3] << 8) | cp[2]);
2848: FILTER_EMIT(RFCR_NS_RFADDR_PMATCH4, (cp[5] << 8) | cp[4]);
1.15 thorpej 2849:
2850: if ((ifp->if_flags & IFF_ALLMULTI) == 0) {
2851: /*
2852: * Program the multicast hash table.
2853: */
1.39 thorpej 2854: for (i = 0; i < MCHASH_NWORDS; i++) {
1.15 thorpej 2855: FILTER_EMIT(RFCR_NS_RFADDR_FILTMEM + (i * 2),
1.29 thorpej 2856: mchash[i]);
1.39 thorpej 2857: }
1.15 thorpej 2858: }
2859: #undef FILTER_EMIT
1.29 thorpej 2860: #undef MCHASH_NWORDS
1.15 thorpej 2861:
2862: /*
2863: * Re-enable the receiver filter.
2864: */
2865: bus_space_write_4(st, sh, SIP_RFCR, sc->sc_rfcr);
1.29 thorpej 2866: }
2867:
2868: #if defined(DP83820)
2869: /*
2870: * sip_dp83820_mii_readreg: [mii interface function]
2871: *
2872: * Read a PHY register on the MII of the DP83820.
2873: */
2874: int
2875: SIP_DECL(dp83820_mii_readreg)(struct device *self, int phy, int reg)
2876: {
1.63 thorpej 2877: struct sip_softc *sc = (void *) self;
2878:
2879: if (sc->sc_cfg & CFG_TBI_EN) {
2880: bus_addr_t tbireg;
2881: int rv;
2882:
2883: if (phy != 0)
2884: return (0);
2885:
2886: switch (reg) {
2887: case MII_BMCR: tbireg = SIP_TBICR; break;
2888: case MII_BMSR: tbireg = SIP_TBISR; break;
2889: case MII_ANAR: tbireg = SIP_TANAR; break;
2890: case MII_ANLPAR: tbireg = SIP_TANLPAR; break;
2891: case MII_ANER: tbireg = SIP_TANER; break;
1.64 thorpej 2892: case MII_EXTSR:
2893: /*
2894: * Don't even bother reading the TESR register.
2895: * The manual documents that the device has
2896: * 1000baseX full/half capability, but the
2897: * register itself seems read back 0 on some
2898: * boards. Just hard-code the result.
2899: */
2900: return (EXTSR_1000XFDX|EXTSR_1000XHDX);
2901:
1.63 thorpej 2902: default:
2903: return (0);
2904: }
2905:
2906: rv = bus_space_read_4(sc->sc_st, sc->sc_sh, tbireg) & 0xffff;
2907: if (tbireg == SIP_TBISR) {
2908: /* LINK and ACOMP are switched! */
2909: int val = rv;
2910:
2911: rv = 0;
2912: if (val & TBISR_MR_LINK_STATUS)
2913: rv |= BMSR_LINK;
2914: if (val & TBISR_MR_AN_COMPLETE)
2915: rv |= BMSR_ACOMP;
1.64 thorpej 2916:
2917: /*
2918: * The manual claims this register reads back 0
2919: * on hard and soft reset. But we want to let
2920: * the gentbi driver know that we support auto-
2921: * negotiation, so hard-code this bit in the
2922: * result.
2923: */
1.69 thorpej 2924: rv |= BMSR_ANEG | BMSR_EXTSTAT;
1.63 thorpej 2925: }
2926:
2927: return (rv);
2928: }
1.29 thorpej 2929:
2930: return (mii_bitbang_readreg(self, &SIP_DECL(dp83820_mii_bitbang_ops),
2931: phy, reg));
2932: }
2933:
2934: /*
2935: * sip_dp83820_mii_writereg: [mii interface function]
2936: *
2937: * Write a PHY register on the MII of the DP83820.
2938: */
2939: void
2940: SIP_DECL(dp83820_mii_writereg)(struct device *self, int phy, int reg, int val)
2941: {
1.63 thorpej 2942: struct sip_softc *sc = (void *) self;
2943:
2944: if (sc->sc_cfg & CFG_TBI_EN) {
2945: bus_addr_t tbireg;
2946:
2947: if (phy != 0)
2948: return;
2949:
2950: switch (reg) {
2951: case MII_BMCR: tbireg = SIP_TBICR; break;
2952: case MII_ANAR: tbireg = SIP_TANAR; break;
2953: case MII_ANLPAR: tbireg = SIP_TANLPAR; break;
2954: default:
2955: return;
2956: }
2957:
2958: bus_space_write_4(sc->sc_st, sc->sc_sh, tbireg, val);
2959: return;
2960: }
1.29 thorpej 2961:
2962: mii_bitbang_writereg(self, &SIP_DECL(dp83820_mii_bitbang_ops),
2963: phy, reg, val);
2964: }
2965:
2966: /*
2967: * sip_dp83815_mii_statchg: [mii interface function]
2968: *
2969: * Callback from MII layer when media changes.
2970: */
2971: void
2972: SIP_DECL(dp83820_mii_statchg)(struct device *self)
2973: {
2974: struct sip_softc *sc = (struct sip_softc *) self;
2975: u_int32_t cfg;
2976:
2977: /*
2978: * Update TXCFG for full-duplex operation.
2979: */
2980: if ((sc->sc_mii.mii_media_active & IFM_FDX) != 0)
2981: sc->sc_txcfg |= (TXCFG_CSI | TXCFG_HBI);
2982: else
2983: sc->sc_txcfg &= ~(TXCFG_CSI | TXCFG_HBI);
2984:
2985: /*
2986: * Update RXCFG for full-duplex or loopback.
2987: */
2988: if ((sc->sc_mii.mii_media_active & IFM_FDX) != 0 ||
2989: IFM_SUBTYPE(sc->sc_mii.mii_media_active) == IFM_LOOP)
2990: sc->sc_rxcfg |= RXCFG_ATX;
2991: else
2992: sc->sc_rxcfg &= ~RXCFG_ATX;
2993:
2994: /*
2995: * Update CFG for MII/GMII.
2996: */
2997: if (sc->sc_ethercom.ec_if.if_baudrate == IF_Mbps(1000))
2998: cfg = sc->sc_cfg | CFG_MODE_1000;
2999: else
3000: cfg = sc->sc_cfg;
3001:
3002: /*
3003: * XXX 802.3x flow control.
3004: */
3005:
3006: bus_space_write_4(sc->sc_st, sc->sc_sh, SIP_CFG, cfg);
3007: bus_space_write_4(sc->sc_st, sc->sc_sh, SIP_TXCFG, sc->sc_txcfg);
3008: bus_space_write_4(sc->sc_st, sc->sc_sh, SIP_RXCFG, sc->sc_rxcfg);
1.15 thorpej 3009: }
3010:
3011: /*
1.29 thorpej 3012: * sip_dp83820_mii_bitbang_read: [mii bit-bang interface function]
3013: *
3014: * Read the MII serial port for the MII bit-bang module.
3015: */
3016: u_int32_t
3017: SIP_DECL(dp83820_mii_bitbang_read)(struct device *self)
3018: {
3019: struct sip_softc *sc = (void *) self;
3020:
3021: return (bus_space_read_4(sc->sc_st, sc->sc_sh, SIP_EROMAR));
3022: }
3023:
3024: /*
3025: * sip_dp83820_mii_bitbang_write: [mii big-bang interface function]
3026: *
3027: * Write the MII serial port for the MII bit-bang module.
3028: */
3029: void
3030: SIP_DECL(dp83820_mii_bitbang_write)(struct device *self, u_int32_t val)
3031: {
3032: struct sip_softc *sc = (void *) self;
3033:
3034: bus_space_write_4(sc->sc_st, sc->sc_sh, SIP_EROMAR, val);
3035: }
3036: #else /* ! DP83820 */
3037: /*
1.15 thorpej 3038: * sip_sis900_mii_readreg: [mii interface function]
1.1 thorpej 3039: *
3040: * Read a PHY register on the MII.
3041: */
3042: int
1.28 thorpej 3043: SIP_DECL(sis900_mii_readreg)(struct device *self, int phy, int reg)
1.1 thorpej 3044: {
3045: struct sip_softc *sc = (struct sip_softc *) self;
3046: u_int32_t enphy;
3047:
3048: /*
3049: * The SiS 900 has only an internal PHY on the MII. Only allow
3050: * MII address 0.
3051: */
1.45 thorpej 3052: if (sc->sc_model->sip_product == PCI_PRODUCT_SIS_900 &&
3053: sc->sc_rev < SIS_REV_635 && phy != 0)
1.1 thorpej 3054: return (0);
3055:
3056: bus_space_write_4(sc->sc_st, sc->sc_sh, SIP_ENPHY,
1.5 thorpej 3057: (phy << ENPHY_PHYADDR_SHIFT) | (reg << ENPHY_REGADDR_SHIFT) |
3058: ENPHY_RWCMD | ENPHY_ACCESS);
1.1 thorpej 3059: do {
3060: enphy = bus_space_read_4(sc->sc_st, sc->sc_sh, SIP_ENPHY);
3061: } while (enphy & ENPHY_ACCESS);
3062: return ((enphy & ENPHY_PHYDATA) >> ENPHY_DATA_SHIFT);
3063: }
3064:
3065: /*
1.15 thorpej 3066: * sip_sis900_mii_writereg: [mii interface function]
1.1 thorpej 3067: *
3068: * Write a PHY register on the MII.
3069: */
3070: void
1.28 thorpej 3071: SIP_DECL(sis900_mii_writereg)(struct device *self, int phy, int reg, int val)
1.1 thorpej 3072: {
3073: struct sip_softc *sc = (struct sip_softc *) self;
3074: u_int32_t enphy;
3075:
3076: /*
3077: * The SiS 900 has only an internal PHY on the MII. Only allow
3078: * MII address 0.
3079: */
1.45 thorpej 3080: if (sc->sc_model->sip_product == PCI_PRODUCT_SIS_900 &&
3081: sc->sc_rev < SIS_REV_635 && phy != 0)
1.1 thorpej 3082: return;
3083:
3084: bus_space_write_4(sc->sc_st, sc->sc_sh, SIP_ENPHY,
1.5 thorpej 3085: (val << ENPHY_DATA_SHIFT) | (phy << ENPHY_PHYADDR_SHIFT) |
3086: (reg << ENPHY_REGADDR_SHIFT) | ENPHY_ACCESS);
1.1 thorpej 3087: do {
3088: enphy = bus_space_read_4(sc->sc_st, sc->sc_sh, SIP_ENPHY);
3089: } while (enphy & ENPHY_ACCESS);
3090: }
3091:
3092: /*
1.15 thorpej 3093: * sip_sis900_mii_statchg: [mii interface function]
1.1 thorpej 3094: *
3095: * Callback from MII layer when media changes.
3096: */
3097: void
1.28 thorpej 3098: SIP_DECL(sis900_mii_statchg)(struct device *self)
1.1 thorpej 3099: {
3100: struct sip_softc *sc = (struct sip_softc *) self;
3101: u_int32_t flowctl;
3102:
3103: /*
3104: * Update TXCFG for full-duplex operation.
3105: */
3106: if ((sc->sc_mii.mii_media_active & IFM_FDX) != 0)
3107: sc->sc_txcfg |= (TXCFG_CSI | TXCFG_HBI);
3108: else
3109: sc->sc_txcfg &= ~(TXCFG_CSI | TXCFG_HBI);
3110:
3111: /*
3112: * Update RXCFG for full-duplex or loopback.
3113: */
3114: if ((sc->sc_mii.mii_media_active & IFM_FDX) != 0 ||
3115: IFM_SUBTYPE(sc->sc_mii.mii_media_active) == IFM_LOOP)
3116: sc->sc_rxcfg |= RXCFG_ATX;
3117: else
3118: sc->sc_rxcfg &= ~RXCFG_ATX;
3119:
3120: /*
3121: * Update IMR for use of 802.3x flow control.
3122: */
3123: if ((sc->sc_mii.mii_media_active & IFM_FLOW) != 0) {
3124: sc->sc_imr |= (ISR_PAUSE_END|ISR_PAUSE_ST);
3125: flowctl = FLOWCTL_FLOWEN;
3126: } else {
3127: sc->sc_imr &= ~(ISR_PAUSE_END|ISR_PAUSE_ST);
3128: flowctl = 0;
3129: }
3130:
3131: bus_space_write_4(sc->sc_st, sc->sc_sh, SIP_TXCFG, sc->sc_txcfg);
3132: bus_space_write_4(sc->sc_st, sc->sc_sh, SIP_RXCFG, sc->sc_rxcfg);
3133: bus_space_write_4(sc->sc_st, sc->sc_sh, SIP_IMR, sc->sc_imr);
3134: bus_space_write_4(sc->sc_st, sc->sc_sh, SIP_FLOWCTL, flowctl);
1.15 thorpej 3135: }
3136:
3137: /*
3138: * sip_dp83815_mii_readreg: [mii interface function]
3139: *
3140: * Read a PHY register on the MII.
3141: */
3142: int
1.28 thorpej 3143: SIP_DECL(dp83815_mii_readreg)(struct device *self, int phy, int reg)
1.15 thorpej 3144: {
3145: struct sip_softc *sc = (struct sip_softc *) self;
3146: u_int32_t val;
3147:
3148: /*
3149: * The DP83815 only has an internal PHY. Only allow
3150: * MII address 0.
3151: */
3152: if (phy != 0)
3153: return (0);
3154:
3155: /*
3156: * Apparently, after a reset, the DP83815 can take a while
3157: * to respond. During this recovery period, the BMSR returns
3158: * a value of 0. Catch this -- it's not supposed to happen
3159: * (the BMSR has some hardcoded-to-1 bits), and wait for the
3160: * PHY to come back to life.
3161: *
3162: * This works out because the BMSR is the first register
3163: * read during the PHY probe process.
3164: */
3165: do {
3166: val = bus_space_read_4(sc->sc_st, sc->sc_sh, SIP_NS_PHY(reg));
3167: } while (reg == MII_BMSR && val == 0);
3168:
3169: return (val & 0xffff);
3170: }
3171:
3172: /*
3173: * sip_dp83815_mii_writereg: [mii interface function]
3174: *
3175: * Write a PHY register to the MII.
3176: */
3177: void
1.28 thorpej 3178: SIP_DECL(dp83815_mii_writereg)(struct device *self, int phy, int reg, int val)
1.15 thorpej 3179: {
3180: struct sip_softc *sc = (struct sip_softc *) self;
3181:
3182: /*
3183: * The DP83815 only has an internal PHY. Only allow
3184: * MII address 0.
3185: */
3186: if (phy != 0)
3187: return;
3188:
3189: bus_space_write_4(sc->sc_st, sc->sc_sh, SIP_NS_PHY(reg), val);
3190: }
3191:
3192: /*
3193: * sip_dp83815_mii_statchg: [mii interface function]
3194: *
3195: * Callback from MII layer when media changes.
3196: */
3197: void
1.28 thorpej 3198: SIP_DECL(dp83815_mii_statchg)(struct device *self)
1.15 thorpej 3199: {
3200: struct sip_softc *sc = (struct sip_softc *) self;
3201:
3202: /*
3203: * Update TXCFG for full-duplex operation.
3204: */
3205: if ((sc->sc_mii.mii_media_active & IFM_FDX) != 0)
3206: sc->sc_txcfg |= (TXCFG_CSI | TXCFG_HBI);
3207: else
3208: sc->sc_txcfg &= ~(TXCFG_CSI | TXCFG_HBI);
3209:
3210: /*
3211: * Update RXCFG for full-duplex or loopback.
3212: */
3213: if ((sc->sc_mii.mii_media_active & IFM_FDX) != 0 ||
3214: IFM_SUBTYPE(sc->sc_mii.mii_media_active) == IFM_LOOP)
3215: sc->sc_rxcfg |= RXCFG_ATX;
3216: else
3217: sc->sc_rxcfg &= ~RXCFG_ATX;
3218:
3219: /*
3220: * XXX 802.3x flow control.
3221: */
3222:
3223: bus_space_write_4(sc->sc_st, sc->sc_sh, SIP_TXCFG, sc->sc_txcfg);
3224: bus_space_write_4(sc->sc_st, sc->sc_sh, SIP_RXCFG, sc->sc_rxcfg);
1.25 briggs 3225: }
1.29 thorpej 3226: #endif /* DP83820 */
3227:
3228: #if defined(DP83820)
3229: void
1.44 thorpej 3230: SIP_DECL(dp83820_read_macaddr)(struct sip_softc *sc,
3231: const struct pci_attach_args *pa, u_int8_t *enaddr)
1.29 thorpej 3232: {
3233: u_int16_t eeprom_data[SIP_DP83820_EEPROM_LENGTH / 2];
3234: u_int8_t cksum, *e, match;
3235: int i;
3236:
3237: /*
3238: * EEPROM data format for the DP83820 can be found in
3239: * the DP83820 manual, section 4.2.4.
3240: */
1.25 briggs 3241:
1.29 thorpej 3242: SIP_DECL(read_eeprom)(sc, 0,
3243: sizeof(eeprom_data) / sizeof(eeprom_data[0]), eeprom_data);
3244:
3245: match = eeprom_data[SIP_DP83820_EEPROM_CHECKSUM / 2] >> 8;
3246: match = ~(match - 1);
3247:
3248: cksum = 0x55;
3249: e = (u_int8_t *) eeprom_data;
3250: for (i = 0; i < SIP_DP83820_EEPROM_CHECKSUM; i++)
3251: cksum += *e++;
3252:
3253: if (cksum != match)
3254: printf("%s: Checksum (%x) mismatch (%x)",
3255: sc->sc_dev.dv_xname, cksum, match);
3256:
3257: enaddr[0] = eeprom_data[SIP_DP83820_EEPROM_PMATCH2 / 2] & 0xff;
3258: enaddr[1] = eeprom_data[SIP_DP83820_EEPROM_PMATCH2 / 2] >> 8;
3259: enaddr[2] = eeprom_data[SIP_DP83820_EEPROM_PMATCH1 / 2] & 0xff;
3260: enaddr[3] = eeprom_data[SIP_DP83820_EEPROM_PMATCH1 / 2] >> 8;
3261: enaddr[4] = eeprom_data[SIP_DP83820_EEPROM_PMATCH0 / 2] & 0xff;
3262: enaddr[5] = eeprom_data[SIP_DP83820_EEPROM_PMATCH0 / 2] >> 8;
3263: }
3264: #else /* ! DP83820 */
1.25 briggs 3265: void
1.44 thorpej 3266: SIP_DECL(sis900_read_macaddr)(struct sip_softc *sc,
3267: const struct pci_attach_args *pa, u_int8_t *enaddr)
1.25 briggs 3268: {
3269: u_int16_t myea[ETHER_ADDR_LEN / 2];
3270:
1.50 briggs 3271: switch (sc->sc_rev) {
1.44 thorpej 3272: case SIS_REV_630S:
3273: case SIS_REV_630E:
3274: case SIS_REV_630EA1:
1.51 briggs 3275: case SIS_REV_630ET:
1.45 thorpej 3276: case SIS_REV_635:
1.44 thorpej 3277: /*
3278: * The MAC address for the on-board Ethernet of
3279: * the SiS 630 chipset is in the NVRAM. Kick
3280: * the chip into re-loading it from NVRAM, and
3281: * read the MAC address out of the filter registers.
3282: */
3283: bus_space_write_4(sc->sc_st, sc->sc_sh, SIP_CR, CR_RLD);
3284:
3285: bus_space_write_4(sc->sc_st, sc->sc_sh, SIP_RFCR,
3286: RFCR_RFADDR_NODE0);
3287: myea[0] = bus_space_read_4(sc->sc_st, sc->sc_sh, SIP_RFDR) &
3288: 0xffff;
3289:
3290: bus_space_write_4(sc->sc_st, sc->sc_sh, SIP_RFCR,
3291: RFCR_RFADDR_NODE2);
3292: myea[1] = bus_space_read_4(sc->sc_st, sc->sc_sh, SIP_RFDR) &
3293: 0xffff;
3294:
3295: bus_space_write_4(sc->sc_st, sc->sc_sh, SIP_RFCR,
3296: RFCR_RFADDR_NODE4);
3297: myea[2] = bus_space_read_4(sc->sc_st, sc->sc_sh, SIP_RFDR) &
3298: 0xffff;
3299: break;
3300:
3301: default:
3302: SIP_DECL(read_eeprom)(sc, SIP_EEPROM_ETHERNET_ID0 >> 1,
3303: sizeof(myea) / sizeof(myea[0]), myea);
3304: }
1.25 briggs 3305:
3306: enaddr[0] = myea[0] & 0xff;
3307: enaddr[1] = myea[0] >> 8;
3308: enaddr[2] = myea[1] & 0xff;
3309: enaddr[3] = myea[1] >> 8;
3310: enaddr[4] = myea[2] & 0xff;
3311: enaddr[5] = myea[2] >> 8;
3312: }
3313:
1.29 thorpej 3314: /* Table and macro to bit-reverse an octet. */
3315: static const u_int8_t bbr4[] = {0,8,4,12,2,10,6,14,1,9,5,13,3,11,7,15};
1.25 briggs 3316: #define bbr(v) ((bbr4[(v)&0xf] << 4) | bbr4[((v)>>4) & 0xf])
3317:
3318: void
1.44 thorpej 3319: SIP_DECL(dp83815_read_macaddr)(struct sip_softc *sc,
3320: const struct pci_attach_args *pa, u_int8_t *enaddr)
1.25 briggs 3321: {
3322: u_int16_t eeprom_data[SIP_DP83815_EEPROM_LENGTH / 2], *ea;
3323: u_int8_t cksum, *e, match;
3324: int i;
3325:
1.29 thorpej 3326: SIP_DECL(read_eeprom)(sc, 0, sizeof(eeprom_data) /
3327: sizeof(eeprom_data[0]), eeprom_data);
1.25 briggs 3328:
3329: match = eeprom_data[SIP_DP83815_EEPROM_CHECKSUM/2] >> 8;
3330: match = ~(match - 1);
3331:
3332: cksum = 0x55;
3333: e = (u_int8_t *) eeprom_data;
3334: for (i=0 ; i<SIP_DP83815_EEPROM_CHECKSUM ; i++) {
3335: cksum += *e++;
3336: }
3337: if (cksum != match) {
3338: printf("%s: Checksum (%x) mismatch (%x)",
3339: sc->sc_dev.dv_xname, cksum, match);
3340: }
3341:
3342: /*
3343: * Unrolled because it makes slightly more sense this way.
3344: * The DP83815 stores the MAC address in bit 0 of word 6
3345: * through bit 15 of word 8.
3346: */
3347: ea = &eeprom_data[6];
3348: enaddr[0] = ((*ea & 0x1) << 7);
3349: ea++;
3350: enaddr[0] |= ((*ea & 0xFE00) >> 9);
3351: enaddr[1] = ((*ea & 0x1FE) >> 1);
3352: enaddr[2] = ((*ea & 0x1) << 7);
3353: ea++;
3354: enaddr[2] |= ((*ea & 0xFE00) >> 9);
3355: enaddr[3] = ((*ea & 0x1FE) >> 1);
3356: enaddr[4] = ((*ea & 0x1) << 7);
3357: ea++;
3358: enaddr[4] |= ((*ea & 0xFE00) >> 9);
3359: enaddr[5] = ((*ea & 0x1FE) >> 1);
3360:
3361: /*
3362: * In case that's not weird enough, we also need to reverse
3363: * the bits in each byte. This all actually makes more sense
3364: * if you think about the EEPROM storage as an array of bits
3365: * being shifted into bytes, but that's not how we're looking
3366: * at it here...
3367: */
1.28 thorpej 3368: for (i = 0; i < 6 ;i++)
1.25 briggs 3369: enaddr[i] = bbr(enaddr[i]);
1.1 thorpej 3370: }
1.29 thorpej 3371: #endif /* DP83820 */
1.1 thorpej 3372:
3373: /*
3374: * sip_mediastatus: [ifmedia interface function]
3375: *
3376: * Get the current interface media status.
3377: */
3378: void
1.28 thorpej 3379: SIP_DECL(mediastatus)(struct ifnet *ifp, struct ifmediareq *ifmr)
1.1 thorpej 3380: {
3381: struct sip_softc *sc = ifp->if_softc;
3382:
3383: mii_pollstat(&sc->sc_mii);
3384: ifmr->ifm_status = sc->sc_mii.mii_media_status;
3385: ifmr->ifm_active = sc->sc_mii.mii_media_active;
3386: }
3387:
3388: /*
3389: * sip_mediachange: [ifmedia interface function]
3390: *
3391: * Set hardware to newly-selected media.
3392: */
3393: int
1.28 thorpej 3394: SIP_DECL(mediachange)(struct ifnet *ifp)
1.1 thorpej 3395: {
3396: struct sip_softc *sc = ifp->if_softc;
3397:
3398: if (ifp->if_flags & IFF_UP)
3399: mii_mediachg(&sc->sc_mii);
3400: return (0);
3401: }
CVSweb <webmaster@jp.NetBSD.org>