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