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