Mon Apr 13 21:22:34 2015 UTC ()
Missed a spot: rnd.h -> rndsource.h.


(riastradh)
diff -r1.50 -r1.51 src/sys/arch/sgimips/mace/if_mec.c

cvs diff -r1.50 -r1.51 src/sys/arch/sgimips/mace/if_mec.c (switch to unified diff)

--- src/sys/arch/sgimips/mace/if_mec.c 2014/08/10 16:44:34 1.50
+++ src/sys/arch/sgimips/mace/if_mec.c 2015/04/13 21:22:34 1.51
@@ -1,1078 +1,1078 @@ @@ -1,1078 +1,1078 @@
1/* $NetBSD: if_mec.c,v 1.50 2014/08/10 16:44:34 tls Exp $ */ 1/* $NetBSD: if_mec.c,v 1.51 2015/04/13 21:22:34 riastradh Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 2004, 2008 Izumi Tsutsui. All rights reserved. 4 * Copyright (c) 2004, 2008 Izumi Tsutsui. All rights reserved.
5 * 5 *
6 * Redistribution and use in source and binary forms, with or without 6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions 7 * modification, are permitted provided that the following conditions
8 * are met: 8 * are met:
9 * 1. Redistributions of source code must retain the above copyright 9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer. 10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright 11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the 12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution. 13 * documentation and/or other materials provided with the distribution.
14 * 14 *
15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
16 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 16 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
17 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 17 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
18 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 18 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
19 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 19 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
20 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 20 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 21 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
22 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
24 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25 */ 25 */
26 26
27/* 27/*
28 * Copyright (c) 2003 Christopher SEKIYA 28 * Copyright (c) 2003 Christopher SEKIYA
29 * All rights reserved. 29 * All rights reserved.
30 * 30 *
31 * Redistribution and use in source and binary forms, with or without 31 * Redistribution and use in source and binary forms, with or without
32 * modification, are permitted provided that the following conditions 32 * modification, are permitted provided that the following conditions
33 * are met: 33 * are met:
34 * 1. Redistributions of source code must retain the above copyright 34 * 1. Redistributions of source code must retain the above copyright
35 * notice, this list of conditions and the following disclaimer. 35 * notice, this list of conditions and the following disclaimer.
36 * 2. Redistributions in binary form must reproduce the above copyright 36 * 2. Redistributions in binary form must reproduce the above copyright
37 * notice, this list of conditions and the following disclaimer in the 37 * notice, this list of conditions and the following disclaimer in the
38 * documentation and/or other materials provided with the distribution. 38 * documentation and/or other materials provided with the distribution.
39 * 3. All advertising materials mentioning features or use of this software 39 * 3. All advertising materials mentioning features or use of this software
40 * must display the following acknowledgement: 40 * must display the following acknowledgement:
41 * This product includes software developed for the 41 * This product includes software developed for the
42 * NetBSD Project. See http://www.NetBSD.org/ for 42 * NetBSD Project. See http://www.NetBSD.org/ for
43 * information about NetBSD. 43 * information about NetBSD.
44 * 4. The name of the author may not be used to endorse or promote products 44 * 4. The name of the author may not be used to endorse or promote products
45 * derived from this software without specific prior written permission. 45 * derived from this software without specific prior written permission.
46 * 46 *
47 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 47 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
48 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 48 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
49 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 49 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
50 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 50 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
51 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 51 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
52 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 52 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
53 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 53 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
54 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 54 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
55 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 55 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
56 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 56 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
57 */ 57 */
58 58
59/* 59/*
60 * MACE MAC-110 Ethernet driver 60 * MACE MAC-110 Ethernet driver
61 */ 61 */
62 62
63#include <sys/cdefs.h> 63#include <sys/cdefs.h>
64__KERNEL_RCSID(0, "$NetBSD: if_mec.c,v 1.50 2014/08/10 16:44:34 tls Exp $"); 64__KERNEL_RCSID(0, "$NetBSD: if_mec.c,v 1.51 2015/04/13 21:22:34 riastradh Exp $");
65 65
66#include "opt_ddb.h" 66#include "opt_ddb.h"
67 67
68#include <sys/param.h> 68#include <sys/param.h>
69#include <sys/systm.h> 69#include <sys/systm.h>
70#include <sys/device.h> 70#include <sys/device.h>
71#include <sys/callout.h> 71#include <sys/callout.h>
72#include <sys/mbuf.h> 72#include <sys/mbuf.h>
73#include <sys/malloc.h> 73#include <sys/malloc.h>
74#include <sys/kernel.h> 74#include <sys/kernel.h>
75#include <sys/socket.h> 75#include <sys/socket.h>
76#include <sys/ioctl.h> 76#include <sys/ioctl.h>
77#include <sys/errno.h> 77#include <sys/errno.h>
78 78
79#include <sys/rnd.h> 79#include <sys/rndsource.h>
80 80
81#include <net/if.h> 81#include <net/if.h>
82#include <net/if_dl.h> 82#include <net/if_dl.h>
83#include <net/if_media.h> 83#include <net/if_media.h>
84#include <net/if_ether.h> 84#include <net/if_ether.h>
85 85
86#include <netinet/in.h> 86#include <netinet/in.h>
87#include <netinet/in_systm.h> 87#include <netinet/in_systm.h>
88#include <netinet/ip.h> 88#include <netinet/ip.h>
89#include <netinet/tcp.h> 89#include <netinet/tcp.h>
90#include <netinet/udp.h> 90#include <netinet/udp.h>
91 91
92#include <net/bpf.h> 92#include <net/bpf.h>
93 93
94#include <sys/bus.h> 94#include <sys/bus.h>
95#include <machine/intr.h> 95#include <machine/intr.h>
96#include <machine/machtype.h> 96#include <machine/machtype.h>
97 97
98#include <dev/mii/mii.h> 98#include <dev/mii/mii.h>
99#include <dev/mii/miivar.h> 99#include <dev/mii/miivar.h>
100 100
101#include <sgimips/mace/macevar.h> 101#include <sgimips/mace/macevar.h>
102#include <sgimips/mace/if_mecreg.h> 102#include <sgimips/mace/if_mecreg.h>
103 103
104#include <dev/arcbios/arcbios.h> 104#include <dev/arcbios/arcbios.h>
105#include <dev/arcbios/arcbiosvar.h> 105#include <dev/arcbios/arcbiosvar.h>
106 106
107/* #define MEC_DEBUG */ 107/* #define MEC_DEBUG */
108 108
109#ifdef MEC_DEBUG 109#ifdef MEC_DEBUG
110#define MEC_DEBUG_RESET 0x01 110#define MEC_DEBUG_RESET 0x01
111#define MEC_DEBUG_START 0x02 111#define MEC_DEBUG_START 0x02
112#define MEC_DEBUG_STOP 0x04 112#define MEC_DEBUG_STOP 0x04
113#define MEC_DEBUG_INTR 0x08 113#define MEC_DEBUG_INTR 0x08
114#define MEC_DEBUG_RXINTR 0x10 114#define MEC_DEBUG_RXINTR 0x10
115#define MEC_DEBUG_TXINTR 0x20 115#define MEC_DEBUG_TXINTR 0x20
116#define MEC_DEBUG_TXSEGS 0x40 116#define MEC_DEBUG_TXSEGS 0x40
117uint32_t mec_debug = 0; 117uint32_t mec_debug = 0;
118#define DPRINTF(x, y) if (mec_debug & (x)) printf y 118#define DPRINTF(x, y) if (mec_debug & (x)) printf y
119#else 119#else
120#define DPRINTF(x, y) /* nothing */ 120#define DPRINTF(x, y) /* nothing */
121#endif 121#endif
122 122
123/* #define MEC_EVENT_COUNTERS */ 123/* #define MEC_EVENT_COUNTERS */
124 124
125#ifdef MEC_EVENT_COUNTERS 125#ifdef MEC_EVENT_COUNTERS
126#define MEC_EVCNT_INCR(ev) (ev)->ev_count++ 126#define MEC_EVCNT_INCR(ev) (ev)->ev_count++
127#else 127#else
128#define MEC_EVCNT_INCR(ev) do {} while (/* CONSTCOND */ 0) 128#define MEC_EVCNT_INCR(ev) do {} while (/* CONSTCOND */ 0)
129#endif 129#endif
130 130
131/* 131/*
132 * Transmit descriptor list size 132 * Transmit descriptor list size
133 */ 133 */
134#define MEC_NTXDESC 64 134#define MEC_NTXDESC 64
135#define MEC_NTXDESC_MASK (MEC_NTXDESC - 1) 135#define MEC_NTXDESC_MASK (MEC_NTXDESC - 1)
136#define MEC_NEXTTX(x) (((x) + 1) & MEC_NTXDESC_MASK) 136#define MEC_NEXTTX(x) (((x) + 1) & MEC_NTXDESC_MASK)
137#define MEC_NTXDESC_RSVD 4 137#define MEC_NTXDESC_RSVD 4
138#define MEC_NTXDESC_INTR 8 138#define MEC_NTXDESC_INTR 8
139 139
140/* 140/*
141 * software state for TX 141 * software state for TX
142 */ 142 */
143struct mec_txsoft { 143struct mec_txsoft {
144 struct mbuf *txs_mbuf; /* head of our mbuf chain */ 144 struct mbuf *txs_mbuf; /* head of our mbuf chain */
145 bus_dmamap_t txs_dmamap; /* our DMA map */ 145 bus_dmamap_t txs_dmamap; /* our DMA map */
146 uint32_t txs_flags; 146 uint32_t txs_flags;
147#define MEC_TXS_BUFLEN_MASK 0x0000007f /* data len in txd_buf */ 147#define MEC_TXS_BUFLEN_MASK 0x0000007f /* data len in txd_buf */
148#define MEC_TXS_TXDPTR 0x00000080 /* concat txd_ptr is used */ 148#define MEC_TXS_TXDPTR 0x00000080 /* concat txd_ptr is used */
149}; 149};
150 150
151/* 151/*
152 * Transmit buffer descriptor 152 * Transmit buffer descriptor
153 */ 153 */
154#define MEC_TXDESCSIZE 128 154#define MEC_TXDESCSIZE 128
155#define MEC_NTXPTR 3 155#define MEC_NTXPTR 3
156#define MEC_TXD_BUFOFFSET sizeof(uint64_t) 156#define MEC_TXD_BUFOFFSET sizeof(uint64_t)
157#define MEC_TXD_BUFOFFSET1 \ 157#define MEC_TXD_BUFOFFSET1 \
158 (sizeof(uint64_t) + sizeof(uint64_t) * MEC_NTXPTR) 158 (sizeof(uint64_t) + sizeof(uint64_t) * MEC_NTXPTR)
159#define MEC_TXD_BUFSIZE (MEC_TXDESCSIZE - MEC_TXD_BUFOFFSET) 159#define MEC_TXD_BUFSIZE (MEC_TXDESCSIZE - MEC_TXD_BUFOFFSET)
160#define MEC_TXD_BUFSIZE1 (MEC_TXDESCSIZE - MEC_TXD_BUFOFFSET1) 160#define MEC_TXD_BUFSIZE1 (MEC_TXDESCSIZE - MEC_TXD_BUFOFFSET1)
161#define MEC_TXD_BUFSTART(len) (MEC_TXD_BUFSIZE - (len)) 161#define MEC_TXD_BUFSTART(len) (MEC_TXD_BUFSIZE - (len))
162#define MEC_TXD_ALIGN 8 162#define MEC_TXD_ALIGN 8
163#define MEC_TXD_ALIGNMASK (MEC_TXD_ALIGN - 1) 163#define MEC_TXD_ALIGNMASK (MEC_TXD_ALIGN - 1)
164#define MEC_TXD_ROUNDUP(addr) \ 164#define MEC_TXD_ROUNDUP(addr) \
165 (((addr) + MEC_TXD_ALIGNMASK) & ~(uint64_t)MEC_TXD_ALIGNMASK) 165 (((addr) + MEC_TXD_ALIGNMASK) & ~(uint64_t)MEC_TXD_ALIGNMASK)
166#define MEC_NTXSEG 16 166#define MEC_NTXSEG 16
167 167
168struct mec_txdesc { 168struct mec_txdesc {
169 volatile uint64_t txd_cmd; 169 volatile uint64_t txd_cmd;
170#define MEC_TXCMD_DATALEN 0x000000000000ffff /* data length */ 170#define MEC_TXCMD_DATALEN 0x000000000000ffff /* data length */
171#define MEC_TXCMD_BUFSTART 0x00000000007f0000 /* start byte offset */ 171#define MEC_TXCMD_BUFSTART 0x00000000007f0000 /* start byte offset */
172#define TXCMD_BUFSTART(x) ((x) << 16) 172#define TXCMD_BUFSTART(x) ((x) << 16)
173#define MEC_TXCMD_TERMDMA 0x0000000000800000 /* stop DMA on abort */ 173#define MEC_TXCMD_TERMDMA 0x0000000000800000 /* stop DMA on abort */
174#define MEC_TXCMD_TXINT 0x0000000001000000 /* INT after TX done */ 174#define MEC_TXCMD_TXINT 0x0000000001000000 /* INT after TX done */
175#define MEC_TXCMD_PTR1 0x0000000002000000 /* valid 1st txd_ptr */ 175#define MEC_TXCMD_PTR1 0x0000000002000000 /* valid 1st txd_ptr */
176#define MEC_TXCMD_PTR2 0x0000000004000000 /* valid 2nd txd_ptr */ 176#define MEC_TXCMD_PTR2 0x0000000004000000 /* valid 2nd txd_ptr */
177#define MEC_TXCMD_PTR3 0x0000000008000000 /* valid 3rd txd_ptr */ 177#define MEC_TXCMD_PTR3 0x0000000008000000 /* valid 3rd txd_ptr */
178#define MEC_TXCMD_UNUSED 0xfffffffff0000000ULL /* should be zero */ 178#define MEC_TXCMD_UNUSED 0xfffffffff0000000ULL /* should be zero */
179 179
180#define txd_stat txd_cmd 180#define txd_stat txd_cmd
181#define MEC_TXSTAT_LEN 0x000000000000ffff /* TX length */ 181#define MEC_TXSTAT_LEN 0x000000000000ffff /* TX length */
182#define MEC_TXSTAT_COLCNT 0x00000000000f0000 /* collision count */ 182#define MEC_TXSTAT_COLCNT 0x00000000000f0000 /* collision count */
183#define MEC_TXSTAT_COLCNT_SHIFT 16 183#define MEC_TXSTAT_COLCNT_SHIFT 16
184#define MEC_TXSTAT_LATE_COL 0x0000000000100000 /* late collision */ 184#define MEC_TXSTAT_LATE_COL 0x0000000000100000 /* late collision */
185#define MEC_TXSTAT_CRCERROR 0x0000000000200000 /* */ 185#define MEC_TXSTAT_CRCERROR 0x0000000000200000 /* */
186#define MEC_TXSTAT_DEFERRED 0x0000000000400000 /* */ 186#define MEC_TXSTAT_DEFERRED 0x0000000000400000 /* */
187#define MEC_TXSTAT_SUCCESS 0x0000000000800000 /* TX complete */ 187#define MEC_TXSTAT_SUCCESS 0x0000000000800000 /* TX complete */
188#define MEC_TXSTAT_TOOBIG 0x0000000001000000 /* */ 188#define MEC_TXSTAT_TOOBIG 0x0000000001000000 /* */
189#define MEC_TXSTAT_UNDERRUN 0x0000000002000000 /* */ 189#define MEC_TXSTAT_UNDERRUN 0x0000000002000000 /* */
190#define MEC_TXSTAT_COLLISIONS 0x0000000004000000 /* */ 190#define MEC_TXSTAT_COLLISIONS 0x0000000004000000 /* */
191#define MEC_TXSTAT_EXDEFERRAL 0x0000000008000000 /* */ 191#define MEC_TXSTAT_EXDEFERRAL 0x0000000008000000 /* */
192#define MEC_TXSTAT_COLLIDED 0x0000000010000000 /* */ 192#define MEC_TXSTAT_COLLIDED 0x0000000010000000 /* */
193#define MEC_TXSTAT_UNUSED 0x7fffffffe0000000ULL /* should be zero */ 193#define MEC_TXSTAT_UNUSED 0x7fffffffe0000000ULL /* should be zero */
194#define MEC_TXSTAT_SENT 0x8000000000000000ULL /* packet sent */ 194#define MEC_TXSTAT_SENT 0x8000000000000000ULL /* packet sent */
195 195
196 union { 196 union {
197 uint64_t txptr[MEC_NTXPTR]; 197 uint64_t txptr[MEC_NTXPTR];
198#define MEC_TXPTR_UNUSED2 0x0000000000000007 /* should be zero */ 198#define MEC_TXPTR_UNUSED2 0x0000000000000007 /* should be zero */
199#define MEC_TXPTR_DMAADDR 0x00000000fffffff8 /* TX DMA address */ 199#define MEC_TXPTR_DMAADDR 0x00000000fffffff8 /* TX DMA address */
200#define MEC_TXPTR_LEN 0x0000ffff00000000ULL /* buffer length */ 200#define MEC_TXPTR_LEN 0x0000ffff00000000ULL /* buffer length */
201#define TXPTR_LEN(x) ((uint64_t)(x) << 32) 201#define TXPTR_LEN(x) ((uint64_t)(x) << 32)
202#define MEC_TXPTR_UNUSED1 0xffff000000000000ULL /* should be zero */ 202#define MEC_TXPTR_UNUSED1 0xffff000000000000ULL /* should be zero */
203 203
204 uint8_t txbuf[MEC_TXD_BUFSIZE]; 204 uint8_t txbuf[MEC_TXD_BUFSIZE];
205 } txd_data; 205 } txd_data;
206#define txd_ptr txd_data.txptr 206#define txd_ptr txd_data.txptr
207#define txd_buf txd_data.txbuf 207#define txd_buf txd_data.txbuf
208}; 208};
209 209
210/* 210/*
211 * Receive buffer size 211 * Receive buffer size
212 */ 212 */
213#define MEC_NRXDESC 16 213#define MEC_NRXDESC 16
214#define MEC_NRXDESC_MASK (MEC_NRXDESC - 1) 214#define MEC_NRXDESC_MASK (MEC_NRXDESC - 1)
215#define MEC_NEXTRX(x) (((x) + 1) & MEC_NRXDESC_MASK) 215#define MEC_NEXTRX(x) (((x) + 1) & MEC_NRXDESC_MASK)
216 216
217/* 217/*
218 * Receive buffer description 218 * Receive buffer description
219 */ 219 */
220#define MEC_RXDESCSIZE 4096 /* umm, should be 4kbyte aligned */ 220#define MEC_RXDESCSIZE 4096 /* umm, should be 4kbyte aligned */
221#define MEC_RXD_NRXPAD 3 221#define MEC_RXD_NRXPAD 3
222#define MEC_RXD_DMAOFFSET (1 + MEC_RXD_NRXPAD) 222#define MEC_RXD_DMAOFFSET (1 + MEC_RXD_NRXPAD)
223#define MEC_RXD_BUFOFFSET (MEC_RXD_DMAOFFSET * sizeof(uint64_t)) 223#define MEC_RXD_BUFOFFSET (MEC_RXD_DMAOFFSET * sizeof(uint64_t))
224#define MEC_RXD_BUFSIZE (MEC_RXDESCSIZE - MEC_RXD_BUFOFFSET) 224#define MEC_RXD_BUFSIZE (MEC_RXDESCSIZE - MEC_RXD_BUFOFFSET)
225 225
226struct mec_rxdesc { 226struct mec_rxdesc {
227 volatile uint64_t rxd_stat; 227 volatile uint64_t rxd_stat;
228#define MEC_RXSTAT_LEN 0x000000000000ffff /* data length */ 228#define MEC_RXSTAT_LEN 0x000000000000ffff /* data length */
229#define MEC_RXSTAT_VIOLATION 0x0000000000010000 /* code violation (?) */ 229#define MEC_RXSTAT_VIOLATION 0x0000000000010000 /* code violation (?) */
230#define MEC_RXSTAT_UNUSED2 0x0000000000020000 /* unknown (?) */ 230#define MEC_RXSTAT_UNUSED2 0x0000000000020000 /* unknown (?) */
231#define MEC_RXSTAT_CRCERROR 0x0000000000040000 /* CRC error */ 231#define MEC_RXSTAT_CRCERROR 0x0000000000040000 /* CRC error */
232#define MEC_RXSTAT_MULTICAST 0x0000000000080000 /* multicast packet */ 232#define MEC_RXSTAT_MULTICAST 0x0000000000080000 /* multicast packet */
233#define MEC_RXSTAT_BROADCAST 0x0000000000100000 /* broadcast packet */ 233#define MEC_RXSTAT_BROADCAST 0x0000000000100000 /* broadcast packet */
234#define MEC_RXSTAT_INVALID 0x0000000000200000 /* invalid preamble */ 234#define MEC_RXSTAT_INVALID 0x0000000000200000 /* invalid preamble */
235#define MEC_RXSTAT_LONGEVENT 0x0000000000400000 /* long packet */ 235#define MEC_RXSTAT_LONGEVENT 0x0000000000400000 /* long packet */
236#define MEC_RXSTAT_BADPACKET 0x0000000000800000 /* bad packet */ 236#define MEC_RXSTAT_BADPACKET 0x0000000000800000 /* bad packet */
237#define MEC_RXSTAT_CAREVENT 0x0000000001000000 /* carrier event */ 237#define MEC_RXSTAT_CAREVENT 0x0000000001000000 /* carrier event */
238#define MEC_RXSTAT_MATCHMCAST 0x0000000002000000 /* match multicast */ 238#define MEC_RXSTAT_MATCHMCAST 0x0000000002000000 /* match multicast */
239#define MEC_RXSTAT_MATCHMAC 0x0000000004000000 /* match MAC */ 239#define MEC_RXSTAT_MATCHMAC 0x0000000004000000 /* match MAC */
240#define MEC_RXSTAT_SEQNUM 0x00000000f8000000 /* sequence number */ 240#define MEC_RXSTAT_SEQNUM 0x00000000f8000000 /* sequence number */
241#define MEC_RXSTAT_CKSUM 0x0000ffff00000000ULL /* IP checksum */ 241#define MEC_RXSTAT_CKSUM 0x0000ffff00000000ULL /* IP checksum */
242#define RXSTAT_CKSUM(x) (((uint64_t)(x) & MEC_RXSTAT_CKSUM) >> 32) 242#define RXSTAT_CKSUM(x) (((uint64_t)(x) & MEC_RXSTAT_CKSUM) >> 32)
243#define MEC_RXSTAT_UNUSED1 0x7fff000000000000ULL /* should be zero */ 243#define MEC_RXSTAT_UNUSED1 0x7fff000000000000ULL /* should be zero */
244#define MEC_RXSTAT_RECEIVED 0x8000000000000000ULL /* set to 1 on RX */ 244#define MEC_RXSTAT_RECEIVED 0x8000000000000000ULL /* set to 1 on RX */
245 uint64_t rxd_pad1[MEC_RXD_NRXPAD]; 245 uint64_t rxd_pad1[MEC_RXD_NRXPAD];
246 uint8_t rxd_buf[MEC_RXD_BUFSIZE]; 246 uint8_t rxd_buf[MEC_RXD_BUFSIZE];
247}; 247};
248 248
249/* 249/*
250 * control structures for DMA ops 250 * control structures for DMA ops
251 */ 251 */
252struct mec_control_data { 252struct mec_control_data {
253 /* 253 /*
254 * TX descriptors and buffers 254 * TX descriptors and buffers
255 */ 255 */
256 struct mec_txdesc mcd_txdesc[MEC_NTXDESC]; 256 struct mec_txdesc mcd_txdesc[MEC_NTXDESC];
257 257
258 /* 258 /*
259 * RX descriptors and buffers 259 * RX descriptors and buffers
260 */ 260 */
261 struct mec_rxdesc mcd_rxdesc[MEC_NRXDESC]; 261 struct mec_rxdesc mcd_rxdesc[MEC_NRXDESC];
262}; 262};
263 263
264/* 264/*
265 * It _seems_ there are some restrictions on descriptor address: 265 * It _seems_ there are some restrictions on descriptor address:
266 * 266 *
267 * - Base address of txdescs should be 8kbyte aligned 267 * - Base address of txdescs should be 8kbyte aligned
268 * - Each txdesc should be 128byte aligned 268 * - Each txdesc should be 128byte aligned
269 * - Each rxdesc should be 4kbyte aligned 269 * - Each rxdesc should be 4kbyte aligned
270 * 270 *
271 * So we should specify 8k align to allocalte txdescs. 271 * So we should specify 8k align to allocalte txdescs.
272 * In this case, sizeof(struct mec_txdesc) * MEC_NTXDESC is 8192 272 * In this case, sizeof(struct mec_txdesc) * MEC_NTXDESC is 8192
273 * so rxdescs are also allocated at 4kbyte aligned. 273 * so rxdescs are also allocated at 4kbyte aligned.
274 */ 274 */
275#define MEC_CONTROL_DATA_ALIGN (8 * 1024) 275#define MEC_CONTROL_DATA_ALIGN (8 * 1024)
276 276
277#define MEC_CDOFF(x) offsetof(struct mec_control_data, x) 277#define MEC_CDOFF(x) offsetof(struct mec_control_data, x)
278#define MEC_CDTXOFF(x) MEC_CDOFF(mcd_txdesc[(x)]) 278#define MEC_CDTXOFF(x) MEC_CDOFF(mcd_txdesc[(x)])
279#define MEC_CDRXOFF(x) MEC_CDOFF(mcd_rxdesc[(x)]) 279#define MEC_CDRXOFF(x) MEC_CDOFF(mcd_rxdesc[(x)])
280 280
281/* 281/*
282 * software state per device 282 * software state per device
283 */ 283 */
284struct mec_softc { 284struct mec_softc {
285 device_t sc_dev; /* generic device structures */ 285 device_t sc_dev; /* generic device structures */
286 286
287 bus_space_tag_t sc_st; /* bus_space tag */ 287 bus_space_tag_t sc_st; /* bus_space tag */
288 bus_space_handle_t sc_sh; /* bus_space handle */ 288 bus_space_handle_t sc_sh; /* bus_space handle */
289 bus_dma_tag_t sc_dmat; /* bus_dma tag */ 289 bus_dma_tag_t sc_dmat; /* bus_dma tag */
290 290
291 struct ethercom sc_ethercom; /* Ethernet common part */ 291 struct ethercom sc_ethercom; /* Ethernet common part */
292 292
293 struct mii_data sc_mii; /* MII/media information */ 293 struct mii_data sc_mii; /* MII/media information */
294 int sc_phyaddr; /* MII address */ 294 int sc_phyaddr; /* MII address */
295 struct callout sc_tick_ch; /* tick callout */ 295 struct callout sc_tick_ch; /* tick callout */
296 296
297 uint8_t sc_enaddr[ETHER_ADDR_LEN]; /* MAC address */ 297 uint8_t sc_enaddr[ETHER_ADDR_LEN]; /* MAC address */
298 298
299 bus_dmamap_t sc_cddmamap; /* bus_dma map for control data */ 299 bus_dmamap_t sc_cddmamap; /* bus_dma map for control data */
300#define sc_cddma sc_cddmamap->dm_segs[0].ds_addr 300#define sc_cddma sc_cddmamap->dm_segs[0].ds_addr
301 301
302 /* pointer to allocated control data */ 302 /* pointer to allocated control data */
303 struct mec_control_data *sc_control_data; 303 struct mec_control_data *sc_control_data;
304#define sc_txdesc sc_control_data->mcd_txdesc 304#define sc_txdesc sc_control_data->mcd_txdesc
305#define sc_rxdesc sc_control_data->mcd_rxdesc 305#define sc_rxdesc sc_control_data->mcd_rxdesc
306 306
307 /* software state for TX descs */ 307 /* software state for TX descs */
308 struct mec_txsoft sc_txsoft[MEC_NTXDESC]; 308 struct mec_txsoft sc_txsoft[MEC_NTXDESC];
309 309
310 int sc_txpending; /* number of TX requests pending */ 310 int sc_txpending; /* number of TX requests pending */
311 int sc_txdirty; /* first dirty TX descriptor */ 311 int sc_txdirty; /* first dirty TX descriptor */
312 int sc_txlast; /* last used TX descriptor */ 312 int sc_txlast; /* last used TX descriptor */
313 313
314 int sc_rxptr; /* next ready RX buffer */ 314 int sc_rxptr; /* next ready RX buffer */
315 315
316 krndsource_t sc_rnd_source; /* random source */ 316 krndsource_t sc_rnd_source; /* random source */
317#ifdef MEC_EVENT_COUNTERS 317#ifdef MEC_EVENT_COUNTERS
318 struct evcnt sc_ev_txpkts; /* TX packets queued total */ 318 struct evcnt sc_ev_txpkts; /* TX packets queued total */
319 struct evcnt sc_ev_txdpad; /* TX packets padded in txdesc buf */ 319 struct evcnt sc_ev_txdpad; /* TX packets padded in txdesc buf */
320 struct evcnt sc_ev_txdbuf; /* TX packets copied to txdesc buf */ 320 struct evcnt sc_ev_txdbuf; /* TX packets copied to txdesc buf */
321 struct evcnt sc_ev_txptr1; /* TX packets using concat ptr1 */ 321 struct evcnt sc_ev_txptr1; /* TX packets using concat ptr1 */
322 struct evcnt sc_ev_txptr1a; /* TX packets w/ptr1 ~160bytes */ 322 struct evcnt sc_ev_txptr1a; /* TX packets w/ptr1 ~160bytes */
323 struct evcnt sc_ev_txptr1b; /* TX packets w/ptr1 ~256bytes */ 323 struct evcnt sc_ev_txptr1b; /* TX packets w/ptr1 ~256bytes */
324 struct evcnt sc_ev_txptr1c; /* TX packets w/ptr1 ~512bytes */ 324 struct evcnt sc_ev_txptr1c; /* TX packets w/ptr1 ~512bytes */
325 struct evcnt sc_ev_txptr1d; /* TX packets w/ptr1 ~1024bytes */ 325 struct evcnt sc_ev_txptr1d; /* TX packets w/ptr1 ~1024bytes */
326 struct evcnt sc_ev_txptr1e; /* TX packets w/ptr1 >1024bytes */ 326 struct evcnt sc_ev_txptr1e; /* TX packets w/ptr1 >1024bytes */
327 struct evcnt sc_ev_txptr2; /* TX packets using concat ptr1,2 */ 327 struct evcnt sc_ev_txptr2; /* TX packets using concat ptr1,2 */
328 struct evcnt sc_ev_txptr2a; /* TX packets w/ptr2 ~160bytes */ 328 struct evcnt sc_ev_txptr2a; /* TX packets w/ptr2 ~160bytes */
329 struct evcnt sc_ev_txptr2b; /* TX packets w/ptr2 ~256bytes */ 329 struct evcnt sc_ev_txptr2b; /* TX packets w/ptr2 ~256bytes */
330 struct evcnt sc_ev_txptr2c; /* TX packets w/ptr2 ~512bytes */ 330 struct evcnt sc_ev_txptr2c; /* TX packets w/ptr2 ~512bytes */
331 struct evcnt sc_ev_txptr2d; /* TX packets w/ptr2 ~1024bytes */ 331 struct evcnt sc_ev_txptr2d; /* TX packets w/ptr2 ~1024bytes */
332 struct evcnt sc_ev_txptr2e; /* TX packets w/ptr2 >1024bytes */ 332 struct evcnt sc_ev_txptr2e; /* TX packets w/ptr2 >1024bytes */
333 struct evcnt sc_ev_txptr3; /* TX packets using concat ptr1,2,3 */ 333 struct evcnt sc_ev_txptr3; /* TX packets using concat ptr1,2,3 */
334 struct evcnt sc_ev_txptr3a; /* TX packets w/ptr3 ~160bytes */ 334 struct evcnt sc_ev_txptr3a; /* TX packets w/ptr3 ~160bytes */
335 struct evcnt sc_ev_txptr3b; /* TX packets w/ptr3 ~256bytes */ 335 struct evcnt sc_ev_txptr3b; /* TX packets w/ptr3 ~256bytes */
336 struct evcnt sc_ev_txptr3c; /* TX packets w/ptr3 ~512bytes */ 336 struct evcnt sc_ev_txptr3c; /* TX packets w/ptr3 ~512bytes */
337 struct evcnt sc_ev_txptr3d; /* TX packets w/ptr3 ~1024bytes */ 337 struct evcnt sc_ev_txptr3d; /* TX packets w/ptr3 ~1024bytes */
338 struct evcnt sc_ev_txptr3e; /* TX packets w/ptr3 >1024bytes */ 338 struct evcnt sc_ev_txptr3e; /* TX packets w/ptr3 >1024bytes */
339 struct evcnt sc_ev_txmbuf; /* TX packets copied to new mbufs */ 339 struct evcnt sc_ev_txmbuf; /* TX packets copied to new mbufs */
340 struct evcnt sc_ev_txmbufa; /* TX packets w/mbuf ~160bytes */ 340 struct evcnt sc_ev_txmbufa; /* TX packets w/mbuf ~160bytes */
341 struct evcnt sc_ev_txmbufb; /* TX packets w/mbuf ~256bytes */ 341 struct evcnt sc_ev_txmbufb; /* TX packets w/mbuf ~256bytes */
342 struct evcnt sc_ev_txmbufc; /* TX packets w/mbuf ~512bytes */ 342 struct evcnt sc_ev_txmbufc; /* TX packets w/mbuf ~512bytes */
343 struct evcnt sc_ev_txmbufd; /* TX packets w/mbuf ~1024bytes */ 343 struct evcnt sc_ev_txmbufd; /* TX packets w/mbuf ~1024bytes */
344 struct evcnt sc_ev_txmbufe; /* TX packets w/mbuf >1024bytes */ 344 struct evcnt sc_ev_txmbufe; /* TX packets w/mbuf >1024bytes */
345 struct evcnt sc_ev_txptrs; /* TX packets using ptrs total */ 345 struct evcnt sc_ev_txptrs; /* TX packets using ptrs total */
346 struct evcnt sc_ev_txptrc0; /* TX packets w/ptrs no hdr chain */ 346 struct evcnt sc_ev_txptrc0; /* TX packets w/ptrs no hdr chain */
347 struct evcnt sc_ev_txptrc1; /* TX packets w/ptrs 1 hdr chain */ 347 struct evcnt sc_ev_txptrc1; /* TX packets w/ptrs 1 hdr chain */
348 struct evcnt sc_ev_txptrc2; /* TX packets w/ptrs 2 hdr chains */ 348 struct evcnt sc_ev_txptrc2; /* TX packets w/ptrs 2 hdr chains */
349 struct evcnt sc_ev_txptrc3; /* TX packets w/ptrs 3 hdr chains */ 349 struct evcnt sc_ev_txptrc3; /* TX packets w/ptrs 3 hdr chains */
350 struct evcnt sc_ev_txptrc4; /* TX packets w/ptrs 4 hdr chains */ 350 struct evcnt sc_ev_txptrc4; /* TX packets w/ptrs 4 hdr chains */
351 struct evcnt sc_ev_txptrc5; /* TX packets w/ptrs 5 hdr chains */ 351 struct evcnt sc_ev_txptrc5; /* TX packets w/ptrs 5 hdr chains */
352 struct evcnt sc_ev_txptrc6; /* TX packets w/ptrs >5 hdr chains */ 352 struct evcnt sc_ev_txptrc6; /* TX packets w/ptrs >5 hdr chains */
353 struct evcnt sc_ev_txptrh0; /* TX packets w/ptrs ~8bytes hdr */ 353 struct evcnt sc_ev_txptrh0; /* TX packets w/ptrs ~8bytes hdr */
354 struct evcnt sc_ev_txptrh1; /* TX packets w/ptrs ~16bytes hdr */ 354 struct evcnt sc_ev_txptrh1; /* TX packets w/ptrs ~16bytes hdr */
355 struct evcnt sc_ev_txptrh2; /* TX packets w/ptrs ~32bytes hdr */ 355 struct evcnt sc_ev_txptrh2; /* TX packets w/ptrs ~32bytes hdr */
356 struct evcnt sc_ev_txptrh3; /* TX packets w/ptrs ~64bytes hdr */ 356 struct evcnt sc_ev_txptrh3; /* TX packets w/ptrs ~64bytes hdr */
357 struct evcnt sc_ev_txptrh4; /* TX packets w/ptrs ~80bytes hdr */ 357 struct evcnt sc_ev_txptrh4; /* TX packets w/ptrs ~80bytes hdr */
358 struct evcnt sc_ev_txptrh5; /* TX packets w/ptrs ~96bytes hdr */ 358 struct evcnt sc_ev_txptrh5; /* TX packets w/ptrs ~96bytes hdr */
359 struct evcnt sc_ev_txdstall; /* TX stalled due to no txdesc */ 359 struct evcnt sc_ev_txdstall; /* TX stalled due to no txdesc */
360 struct evcnt sc_ev_txempty; /* TX empty interrupts */ 360 struct evcnt sc_ev_txempty; /* TX empty interrupts */
361 struct evcnt sc_ev_txsent; /* TX sent interrupts */ 361 struct evcnt sc_ev_txsent; /* TX sent interrupts */
362#endif 362#endif
363}; 363};
364 364
365#define MEC_CDTXADDR(sc, x) ((sc)->sc_cddma + MEC_CDTXOFF(x)) 365#define MEC_CDTXADDR(sc, x) ((sc)->sc_cddma + MEC_CDTXOFF(x))
366#define MEC_CDRXADDR(sc, x) ((sc)->sc_cddma + MEC_CDRXOFF(x)) 366#define MEC_CDRXADDR(sc, x) ((sc)->sc_cddma + MEC_CDRXOFF(x))
367 367
368#define MEC_TXDESCSYNC(sc, x, ops) \ 368#define MEC_TXDESCSYNC(sc, x, ops) \
369 bus_dmamap_sync((sc)->sc_dmat, (sc)->sc_cddmamap, \ 369 bus_dmamap_sync((sc)->sc_dmat, (sc)->sc_cddmamap, \
370 MEC_CDTXOFF(x), MEC_TXDESCSIZE, (ops)) 370 MEC_CDTXOFF(x), MEC_TXDESCSIZE, (ops))
371#define MEC_TXCMDSYNC(sc, x, ops) \ 371#define MEC_TXCMDSYNC(sc, x, ops) \
372 bus_dmamap_sync((sc)->sc_dmat, (sc)->sc_cddmamap, \ 372 bus_dmamap_sync((sc)->sc_dmat, (sc)->sc_cddmamap, \
373 MEC_CDTXOFF(x), sizeof(uint64_t), (ops)) 373 MEC_CDTXOFF(x), sizeof(uint64_t), (ops))
374 374
375#define MEC_RXSTATSYNC(sc, x, ops) \ 375#define MEC_RXSTATSYNC(sc, x, ops) \
376 bus_dmamap_sync((sc)->sc_dmat, (sc)->sc_cddmamap, \ 376 bus_dmamap_sync((sc)->sc_dmat, (sc)->sc_cddmamap, \
377 MEC_CDRXOFF(x), sizeof(uint64_t), (ops)) 377 MEC_CDRXOFF(x), sizeof(uint64_t), (ops))
378#define MEC_RXBUFSYNC(sc, x, len, ops) \ 378#define MEC_RXBUFSYNC(sc, x, len, ops) \
379 bus_dmamap_sync((sc)->sc_dmat, (sc)->sc_cddmamap, \ 379 bus_dmamap_sync((sc)->sc_dmat, (sc)->sc_cddmamap, \
380 MEC_CDRXOFF(x) + MEC_RXD_BUFOFFSET, \ 380 MEC_CDRXOFF(x) + MEC_RXD_BUFOFFSET, \
381 MEC_ETHER_ALIGN + (len), (ops)) 381 MEC_ETHER_ALIGN + (len), (ops))
382 382
383/* XXX these values should be moved to <net/if_ether.h> ? */ 383/* XXX these values should be moved to <net/if_ether.h> ? */
384#define ETHER_PAD_LEN (ETHER_MIN_LEN - ETHER_CRC_LEN) 384#define ETHER_PAD_LEN (ETHER_MIN_LEN - ETHER_CRC_LEN)
385#define MEC_ETHER_ALIGN 2 385#define MEC_ETHER_ALIGN 2
386 386
387static int mec_match(device_t, cfdata_t, void *); 387static int mec_match(device_t, cfdata_t, void *);
388static void mec_attach(device_t, device_t, void *); 388static void mec_attach(device_t, device_t, void *);
389 389
390static int mec_mii_readreg(device_t, int, int); 390static int mec_mii_readreg(device_t, int, int);
391static void mec_mii_writereg(device_t, int, int, int); 391static void mec_mii_writereg(device_t, int, int, int);
392static int mec_mii_wait(struct mec_softc *); 392static int mec_mii_wait(struct mec_softc *);
393static void mec_statchg(struct ifnet *); 393static void mec_statchg(struct ifnet *);
394 394
395static int mec_init(struct ifnet * ifp); 395static int mec_init(struct ifnet * ifp);
396static void mec_start(struct ifnet *); 396static void mec_start(struct ifnet *);
397static void mec_watchdog(struct ifnet *); 397static void mec_watchdog(struct ifnet *);
398static void mec_tick(void *); 398static void mec_tick(void *);
399static int mec_ioctl(struct ifnet *, u_long, void *); 399static int mec_ioctl(struct ifnet *, u_long, void *);
400static void mec_reset(struct mec_softc *); 400static void mec_reset(struct mec_softc *);
401static void mec_setfilter(struct mec_softc *); 401static void mec_setfilter(struct mec_softc *);
402static int mec_intr(void *arg); 402static int mec_intr(void *arg);
403static void mec_stop(struct ifnet *, int); 403static void mec_stop(struct ifnet *, int);
404static void mec_rxintr(struct mec_softc *); 404static void mec_rxintr(struct mec_softc *);
405static void mec_rxcsum(struct mec_softc *, struct mbuf *, uint16_t, 405static void mec_rxcsum(struct mec_softc *, struct mbuf *, uint16_t,
406 uint32_t); 406 uint32_t);
407static void mec_txintr(struct mec_softc *, uint32_t); 407static void mec_txintr(struct mec_softc *, uint32_t);
408static bool mec_shutdown(device_t, int); 408static bool mec_shutdown(device_t, int);
409 409
410CFATTACH_DECL_NEW(mec, sizeof(struct mec_softc), 410CFATTACH_DECL_NEW(mec, sizeof(struct mec_softc),
411 mec_match, mec_attach, NULL, NULL); 411 mec_match, mec_attach, NULL, NULL);
412 412
413static int mec_matched = 0; 413static int mec_matched = 0;
414 414
415static int 415static int
416mec_match(device_t parent, cfdata_t cf, void *aux) 416mec_match(device_t parent, cfdata_t cf, void *aux)
417{ 417{
418 418
419 /* allow only one device */ 419 /* allow only one device */
420 if (mec_matched) 420 if (mec_matched)
421 return 0; 421 return 0;
422 422
423 mec_matched = 1; 423 mec_matched = 1;
424 return 1; 424 return 1;
425} 425}
426 426
427static void 427static void
428mec_attach(device_t parent, device_t self, void *aux) 428mec_attach(device_t parent, device_t self, void *aux)
429{ 429{
430 struct mec_softc *sc = device_private(self); 430 struct mec_softc *sc = device_private(self);
431 struct mace_attach_args *maa = aux; 431 struct mace_attach_args *maa = aux;
432 struct ifnet *ifp = &sc->sc_ethercom.ec_if; 432 struct ifnet *ifp = &sc->sc_ethercom.ec_if;
433 uint64_t address, command; 433 uint64_t address, command;
434 const char *macaddr; 434 const char *macaddr;
435 struct mii_softc *child; 435 struct mii_softc *child;
436 bus_dma_segment_t seg; 436 bus_dma_segment_t seg;
437 int i, err, rseg; 437 int i, err, rseg;
438 bool mac_is_fake; 438 bool mac_is_fake;
439 439
440 sc->sc_dev = self; 440 sc->sc_dev = self;
441 sc->sc_st = maa->maa_st; 441 sc->sc_st = maa->maa_st;
442 if (bus_space_subregion(sc->sc_st, maa->maa_sh, 442 if (bus_space_subregion(sc->sc_st, maa->maa_sh,
443 maa->maa_offset, 0, &sc->sc_sh) != 0) { 443 maa->maa_offset, 0, &sc->sc_sh) != 0) {
444 aprint_error(": can't map i/o space\n"); 444 aprint_error(": can't map i/o space\n");
445 return; 445 return;
446 } 446 }
447 447
448 /* set up DMA structures */ 448 /* set up DMA structures */
449 sc->sc_dmat = maa->maa_dmat; 449 sc->sc_dmat = maa->maa_dmat;
450 450
451 /* 451 /*
452 * Allocate the control data structures, and create and load the 452 * Allocate the control data structures, and create and load the
453 * DMA map for it. 453 * DMA map for it.
454 */ 454 */
455 if ((err = bus_dmamem_alloc(sc->sc_dmat, 455 if ((err = bus_dmamem_alloc(sc->sc_dmat,
456 sizeof(struct mec_control_data), MEC_CONTROL_DATA_ALIGN, 0, 456 sizeof(struct mec_control_data), MEC_CONTROL_DATA_ALIGN, 0,
457 &seg, 1, &rseg, BUS_DMA_NOWAIT)) != 0) { 457 &seg, 1, &rseg, BUS_DMA_NOWAIT)) != 0) {
458 aprint_error(": unable to allocate control data, error = %d\n", 458 aprint_error(": unable to allocate control data, error = %d\n",
459 err); 459 err);
460 goto fail_0; 460 goto fail_0;
461 } 461 }
462 /* 462 /*
463 * XXX needs re-think... 463 * XXX needs re-think...
464 * control data structures contain whole RX data buffer, so 464 * control data structures contain whole RX data buffer, so
465 * BUS_DMA_COHERENT (which disables cache) may cause some performance 465 * BUS_DMA_COHERENT (which disables cache) may cause some performance
466 * issue on copying data from the RX buffer to mbuf on normal memory, 466 * issue on copying data from the RX buffer to mbuf on normal memory,
467 * though we have to make sure all bus_dmamap_sync(9) ops are called 467 * though we have to make sure all bus_dmamap_sync(9) ops are called
468 * properly in that case. 468 * properly in that case.
469 */ 469 */
470 if ((err = bus_dmamem_map(sc->sc_dmat, &seg, rseg, 470 if ((err = bus_dmamem_map(sc->sc_dmat, &seg, rseg,
471 sizeof(struct mec_control_data), 471 sizeof(struct mec_control_data),
472 (void **)&sc->sc_control_data, /*BUS_DMA_COHERENT*/ 0)) != 0) { 472 (void **)&sc->sc_control_data, /*BUS_DMA_COHERENT*/ 0)) != 0) {
473 aprint_error(": unable to map control data, error = %d\n", err); 473 aprint_error(": unable to map control data, error = %d\n", err);
474 goto fail_1; 474 goto fail_1;
475 } 475 }
476 memset(sc->sc_control_data, 0, sizeof(struct mec_control_data)); 476 memset(sc->sc_control_data, 0, sizeof(struct mec_control_data));
477 477
478 if ((err = bus_dmamap_create(sc->sc_dmat, 478 if ((err = bus_dmamap_create(sc->sc_dmat,
479 sizeof(struct mec_control_data), 1, 479 sizeof(struct mec_control_data), 1,
480 sizeof(struct mec_control_data), 0, 0, &sc->sc_cddmamap)) != 0) { 480 sizeof(struct mec_control_data), 0, 0, &sc->sc_cddmamap)) != 0) {
481 aprint_error(": unable to create control data DMA map," 481 aprint_error(": unable to create control data DMA map,"
482 " error = %d\n", err); 482 " error = %d\n", err);
483 goto fail_2; 483 goto fail_2;
484 } 484 }
485 if ((err = bus_dmamap_load(sc->sc_dmat, sc->sc_cddmamap, 485 if ((err = bus_dmamap_load(sc->sc_dmat, sc->sc_cddmamap,
486 sc->sc_control_data, sizeof(struct mec_control_data), NULL, 486 sc->sc_control_data, sizeof(struct mec_control_data), NULL,
487 BUS_DMA_NOWAIT)) != 0) { 487 BUS_DMA_NOWAIT)) != 0) {
488 aprint_error(": unable to load control data DMA map," 488 aprint_error(": unable to load control data DMA map,"
489 " error = %d\n", err); 489 " error = %d\n", err);
490 goto fail_3; 490 goto fail_3;
491 } 491 }
492 492
493 /* create TX buffer DMA maps */ 493 /* create TX buffer DMA maps */
494 for (i = 0; i < MEC_NTXDESC; i++) { 494 for (i = 0; i < MEC_NTXDESC; i++) {
495 if ((err = bus_dmamap_create(sc->sc_dmat, 495 if ((err = bus_dmamap_create(sc->sc_dmat,
496 MCLBYTES, MEC_NTXSEG, MCLBYTES, PAGE_SIZE, 0, 496 MCLBYTES, MEC_NTXSEG, MCLBYTES, PAGE_SIZE, 0,
497 &sc->sc_txsoft[i].txs_dmamap)) != 0) { 497 &sc->sc_txsoft[i].txs_dmamap)) != 0) {
498 aprint_error(": unable to create tx DMA map %d," 498 aprint_error(": unable to create tx DMA map %d,"
499 " error = %d\n", i, err); 499 " error = %d\n", i, err);
500 goto fail_4; 500 goto fail_4;
501 } 501 }
502 } 502 }
503 503
504 callout_init(&sc->sc_tick_ch, 0); 504 callout_init(&sc->sc_tick_ch, 0);
505 505
506 /* get Ethernet address from ARCBIOS */ 506 /* get Ethernet address from ARCBIOS */
507 if ((macaddr = arcbios_GetEnvironmentVariable("eaddr")) == NULL) { 507 if ((macaddr = arcbios_GetEnvironmentVariable("eaddr")) == NULL) {
508 aprint_error(": unable to get MAC address!\n"); 508 aprint_error(": unable to get MAC address!\n");
509 goto fail_4; 509 goto fail_4;
510 } 510 }
511 /* 511 /*
512 * On some machines the DS2502 chip storing the serial number/ 512 * On some machines the DS2502 chip storing the serial number/
513 * mac address is on the pci riser board - if this board is 513 * mac address is on the pci riser board - if this board is
514 * missing, ARCBIOS will not know a good ethernet address (but 514 * missing, ARCBIOS will not know a good ethernet address (but
515 * otherwise the machine will work fine). 515 * otherwise the machine will work fine).
516 */ 516 */
517 mac_is_fake = false; 517 mac_is_fake = false;
518 if (strcmp(macaddr, "ff:ff:ff:ff:ff:ff") == 0) { 518 if (strcmp(macaddr, "ff:ff:ff:ff:ff:ff") == 0) {
519 uint32_t ui = 0; 519 uint32_t ui = 0;
520 const char * netaddr = 520 const char * netaddr =
521 arcbios_GetEnvironmentVariable("netaddr"); 521 arcbios_GetEnvironmentVariable("netaddr");
522 522
523 /* 523 /*
524 * Create a MAC address by abusing the "netaddr" env var 524 * Create a MAC address by abusing the "netaddr" env var
525 */ 525 */
526 sc->sc_enaddr[0] = 0xf2; 526 sc->sc_enaddr[0] = 0xf2;
527 sc->sc_enaddr[1] = 0x0b; 527 sc->sc_enaddr[1] = 0x0b;
528 sc->sc_enaddr[2] = 0xa4; 528 sc->sc_enaddr[2] = 0xa4;
529 if (netaddr) { 529 if (netaddr) {
530 mac_is_fake = true; 530 mac_is_fake = true;
531 while (*netaddr) { 531 while (*netaddr) {
532 int v = 0; 532 int v = 0;
533 while (*netaddr && *netaddr != '.') { 533 while (*netaddr && *netaddr != '.') {
534 if (*netaddr >= '0' && *netaddr <= '9') 534 if (*netaddr >= '0' && *netaddr <= '9')
535 v = v*10 + (*netaddr - '0'); 535 v = v*10 + (*netaddr - '0');
536 netaddr++; 536 netaddr++;
537 } 537 }
538 ui <<= 8; 538 ui <<= 8;
539 ui |= v; 539 ui |= v;
540 if (*netaddr == '.') 540 if (*netaddr == '.')
541 netaddr++; 541 netaddr++;
542 } 542 }
543 } 543 }
544 memcpy(sc->sc_enaddr+3, ((uint8_t *)&ui)+1, 3); 544 memcpy(sc->sc_enaddr+3, ((uint8_t *)&ui)+1, 3);
545 } 545 }
546 if (!mac_is_fake) 546 if (!mac_is_fake)
547 ether_aton_r(sc->sc_enaddr, sizeof(sc->sc_enaddr), macaddr); 547 ether_aton_r(sc->sc_enaddr, sizeof(sc->sc_enaddr), macaddr);
548 548
549 /* set the Ethernet address */ 549 /* set the Ethernet address */
550 address = 0; 550 address = 0;
551 for (i = 0; i < ETHER_ADDR_LEN; i++) { 551 for (i = 0; i < ETHER_ADDR_LEN; i++) {
552 address = address << 8; 552 address = address << 8;
553 address |= sc->sc_enaddr[i]; 553 address |= sc->sc_enaddr[i];
554 } 554 }
555 bus_space_write_8(sc->sc_st, sc->sc_sh, MEC_STATION, address); 555 bus_space_write_8(sc->sc_st, sc->sc_sh, MEC_STATION, address);
556 556
557 /* reset device */ 557 /* reset device */
558 mec_reset(sc); 558 mec_reset(sc);
559 559
560 command = bus_space_read_8(sc->sc_st, sc->sc_sh, MEC_MAC_CONTROL); 560 command = bus_space_read_8(sc->sc_st, sc->sc_sh, MEC_MAC_CONTROL);
561 561
562 aprint_normal(": MAC-110 Ethernet, rev %u\n", 562 aprint_normal(": MAC-110 Ethernet, rev %u\n",
563 (u_int)((command & MEC_MAC_REVISION) >> MEC_MAC_REVISION_SHIFT)); 563 (u_int)((command & MEC_MAC_REVISION) >> MEC_MAC_REVISION_SHIFT));
564 564
565 if (mac_is_fake) 565 if (mac_is_fake)
566 aprint_normal_dev(self, 566 aprint_normal_dev(self,
567 "could not get ethernet address from firmware" 567 "could not get ethernet address from firmware"
568 " - generated one from the \"netaddr\" environment" 568 " - generated one from the \"netaddr\" environment"
569 " variable\n"); 569 " variable\n");
570 aprint_normal_dev(self, "Ethernet address %s\n", 570 aprint_normal_dev(self, "Ethernet address %s\n",
571 ether_sprintf(sc->sc_enaddr)); 571 ether_sprintf(sc->sc_enaddr));
572 572
573 /* Done, now attach everything */ 573 /* Done, now attach everything */
574 574
575 sc->sc_mii.mii_ifp = ifp; 575 sc->sc_mii.mii_ifp = ifp;
576 sc->sc_mii.mii_readreg = mec_mii_readreg; 576 sc->sc_mii.mii_readreg = mec_mii_readreg;
577 sc->sc_mii.mii_writereg = mec_mii_writereg; 577 sc->sc_mii.mii_writereg = mec_mii_writereg;
578 sc->sc_mii.mii_statchg = mec_statchg; 578 sc->sc_mii.mii_statchg = mec_statchg;
579 579
580 /* Set up PHY properties */ 580 /* Set up PHY properties */
581 sc->sc_ethercom.ec_mii = &sc->sc_mii; 581 sc->sc_ethercom.ec_mii = &sc->sc_mii;
582 ifmedia_init(&sc->sc_mii.mii_media, 0, ether_mediachange, 582 ifmedia_init(&sc->sc_mii.mii_media, 0, ether_mediachange,
583 ether_mediastatus); 583 ether_mediastatus);
584 mii_attach(self, &sc->sc_mii, 0xffffffff, MII_PHY_ANY, 584 mii_attach(self, &sc->sc_mii, 0xffffffff, MII_PHY_ANY,
585 MII_OFFSET_ANY, 0); 585 MII_OFFSET_ANY, 0);
586 586
587 child = LIST_FIRST(&sc->sc_mii.mii_phys); 587 child = LIST_FIRST(&sc->sc_mii.mii_phys);
588 if (child == NULL) { 588 if (child == NULL) {
589 /* No PHY attached */ 589 /* No PHY attached */
590 ifmedia_add(&sc->sc_mii.mii_media, IFM_ETHER | IFM_MANUAL, 590 ifmedia_add(&sc->sc_mii.mii_media, IFM_ETHER | IFM_MANUAL,
591 0, NULL); 591 0, NULL);
592 ifmedia_set(&sc->sc_mii.mii_media, IFM_ETHER | IFM_MANUAL); 592 ifmedia_set(&sc->sc_mii.mii_media, IFM_ETHER | IFM_MANUAL);
593 } else { 593 } else {
594 ifmedia_set(&sc->sc_mii.mii_media, IFM_ETHER | IFM_AUTO); 594 ifmedia_set(&sc->sc_mii.mii_media, IFM_ETHER | IFM_AUTO);
595 sc->sc_phyaddr = child->mii_phy; 595 sc->sc_phyaddr = child->mii_phy;
596 } 596 }
597 597
598 strcpy(ifp->if_xname, device_xname(self)); 598 strcpy(ifp->if_xname, device_xname(self));
599 ifp->if_softc = sc; 599 ifp->if_softc = sc;
600 ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; 600 ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
601 ifp->if_ioctl = mec_ioctl; 601 ifp->if_ioctl = mec_ioctl;
602 ifp->if_start = mec_start; 602 ifp->if_start = mec_start;
603 ifp->if_watchdog = mec_watchdog; 603 ifp->if_watchdog = mec_watchdog;
604 ifp->if_init = mec_init; 604 ifp->if_init = mec_init;
605 ifp->if_stop = mec_stop; 605 ifp->if_stop = mec_stop;
606 ifp->if_mtu = ETHERMTU; 606 ifp->if_mtu = ETHERMTU;
607 IFQ_SET_READY(&ifp->if_snd); 607 IFQ_SET_READY(&ifp->if_snd);
608 608
609 /* mec has dumb RX cksum support */ 609 /* mec has dumb RX cksum support */
610 ifp->if_capabilities = IFCAP_CSUM_TCPv4_Rx | IFCAP_CSUM_UDPv4_Rx; 610 ifp->if_capabilities = IFCAP_CSUM_TCPv4_Rx | IFCAP_CSUM_UDPv4_Rx;
611 611
612 /* We can support 802.1Q VLAN-sized frames. */ 612 /* We can support 802.1Q VLAN-sized frames. */
613 sc->sc_ethercom.ec_capabilities |= ETHERCAP_VLAN_MTU; 613 sc->sc_ethercom.ec_capabilities |= ETHERCAP_VLAN_MTU;
614 614
615 /* attach the interface */ 615 /* attach the interface */
616 if_attach(ifp); 616 if_attach(ifp);
617 ether_ifattach(ifp, sc->sc_enaddr); 617 ether_ifattach(ifp, sc->sc_enaddr);
618 618
619 /* establish interrupt */ 619 /* establish interrupt */
620 cpu_intr_establish(maa->maa_intr, maa->maa_intrmask, mec_intr, sc); 620 cpu_intr_establish(maa->maa_intr, maa->maa_intrmask, mec_intr, sc);
621 621
622 rnd_attach_source(&sc->sc_rnd_source, device_xname(self), 622 rnd_attach_source(&sc->sc_rnd_source, device_xname(self),
623 RND_TYPE_NET, RND_FLAG_DEFAULT); 623 RND_TYPE_NET, RND_FLAG_DEFAULT);
624 624
625#ifdef MEC_EVENT_COUNTERS 625#ifdef MEC_EVENT_COUNTERS
626 evcnt_attach_dynamic(&sc->sc_ev_txpkts , EVCNT_TYPE_MISC, 626 evcnt_attach_dynamic(&sc->sc_ev_txpkts , EVCNT_TYPE_MISC,
627 NULL, device_xname(self), "TX pkts queued total"); 627 NULL, device_xname(self), "TX pkts queued total");
628 evcnt_attach_dynamic(&sc->sc_ev_txdpad , EVCNT_TYPE_MISC, 628 evcnt_attach_dynamic(&sc->sc_ev_txdpad , EVCNT_TYPE_MISC,
629 NULL, device_xname(self), "TX pkts padded in txdesc buf"); 629 NULL, device_xname(self), "TX pkts padded in txdesc buf");
630 evcnt_attach_dynamic(&sc->sc_ev_txdbuf , EVCNT_TYPE_MISC, 630 evcnt_attach_dynamic(&sc->sc_ev_txdbuf , EVCNT_TYPE_MISC,
631 NULL, device_xname(self), "TX pkts copied to txdesc buf"); 631 NULL, device_xname(self), "TX pkts copied to txdesc buf");
632 evcnt_attach_dynamic(&sc->sc_ev_txptr1 , EVCNT_TYPE_MISC, 632 evcnt_attach_dynamic(&sc->sc_ev_txptr1 , EVCNT_TYPE_MISC,
633 NULL, device_xname(self), "TX pkts using concat ptr1"); 633 NULL, device_xname(self), "TX pkts using concat ptr1");
634 evcnt_attach_dynamic(&sc->sc_ev_txptr1a , EVCNT_TYPE_MISC, 634 evcnt_attach_dynamic(&sc->sc_ev_txptr1a , EVCNT_TYPE_MISC,
635 NULL, device_xname(self), "TX pkts w/ptr1 ~160bytes"); 635 NULL, device_xname(self), "TX pkts w/ptr1 ~160bytes");
636 evcnt_attach_dynamic(&sc->sc_ev_txptr1b , EVCNT_TYPE_MISC, 636 evcnt_attach_dynamic(&sc->sc_ev_txptr1b , EVCNT_TYPE_MISC,
637 NULL, device_xname(self), "TX pkts w/ptr1 ~256bytes"); 637 NULL, device_xname(self), "TX pkts w/ptr1 ~256bytes");
638 evcnt_attach_dynamic(&sc->sc_ev_txptr1c , EVCNT_TYPE_MISC, 638 evcnt_attach_dynamic(&sc->sc_ev_txptr1c , EVCNT_TYPE_MISC,
639 NULL, device_xname(self), "TX pkts w/ptr1 ~512bytes"); 639 NULL, device_xname(self), "TX pkts w/ptr1 ~512bytes");
640 evcnt_attach_dynamic(&sc->sc_ev_txptr1d , EVCNT_TYPE_MISC, 640 evcnt_attach_dynamic(&sc->sc_ev_txptr1d , EVCNT_TYPE_MISC,
641 NULL, device_xname(self), "TX pkts w/ptr1 ~1024bytes"); 641 NULL, device_xname(self), "TX pkts w/ptr1 ~1024bytes");
642 evcnt_attach_dynamic(&sc->sc_ev_txptr1e , EVCNT_TYPE_MISC, 642 evcnt_attach_dynamic(&sc->sc_ev_txptr1e , EVCNT_TYPE_MISC,
643 NULL, device_xname(self), "TX pkts w/ptr1 >1024bytes"); 643 NULL, device_xname(self), "TX pkts w/ptr1 >1024bytes");
644 evcnt_attach_dynamic(&sc->sc_ev_txptr2 , EVCNT_TYPE_MISC, 644 evcnt_attach_dynamic(&sc->sc_ev_txptr2 , EVCNT_TYPE_MISC,
645 NULL, device_xname(self), "TX pkts using concat ptr1,2"); 645 NULL, device_xname(self), "TX pkts using concat ptr1,2");
646 evcnt_attach_dynamic(&sc->sc_ev_txptr2a , EVCNT_TYPE_MISC, 646 evcnt_attach_dynamic(&sc->sc_ev_txptr2a , EVCNT_TYPE_MISC,
647 NULL, device_xname(self), "TX pkts w/ptr2 ~160bytes"); 647 NULL, device_xname(self), "TX pkts w/ptr2 ~160bytes");
648 evcnt_attach_dynamic(&sc->sc_ev_txptr2b , EVCNT_TYPE_MISC, 648 evcnt_attach_dynamic(&sc->sc_ev_txptr2b , EVCNT_TYPE_MISC,
649 NULL, device_xname(self), "TX pkts w/ptr2 ~256bytes"); 649 NULL, device_xname(self), "TX pkts w/ptr2 ~256bytes");
650 evcnt_attach_dynamic(&sc->sc_ev_txptr2c , EVCNT_TYPE_MISC, 650 evcnt_attach_dynamic(&sc->sc_ev_txptr2c , EVCNT_TYPE_MISC,
651 NULL, device_xname(self), "TX pkts w/ptr2 ~512bytes"); 651 NULL, device_xname(self), "TX pkts w/ptr2 ~512bytes");
652 evcnt_attach_dynamic(&sc->sc_ev_txptr2d , EVCNT_TYPE_MISC, 652 evcnt_attach_dynamic(&sc->sc_ev_txptr2d , EVCNT_TYPE_MISC,
653 NULL, device_xname(self), "TX pkts w/ptr2 ~1024bytes"); 653 NULL, device_xname(self), "TX pkts w/ptr2 ~1024bytes");
654 evcnt_attach_dynamic(&sc->sc_ev_txptr2e , EVCNT_TYPE_MISC, 654 evcnt_attach_dynamic(&sc->sc_ev_txptr2e , EVCNT_TYPE_MISC,
655 NULL, device_xname(self), "TX pkts w/ptr2 >1024bytes"); 655 NULL, device_xname(self), "TX pkts w/ptr2 >1024bytes");
656 evcnt_attach_dynamic(&sc->sc_ev_txptr3 , EVCNT_TYPE_MISC, 656 evcnt_attach_dynamic(&sc->sc_ev_txptr3 , EVCNT_TYPE_MISC,
657 NULL, device_xname(self), "TX pkts using concat ptr1,2,3"); 657 NULL, device_xname(self), "TX pkts using concat ptr1,2,3");
658 evcnt_attach_dynamic(&sc->sc_ev_txptr3a , EVCNT_TYPE_MISC, 658 evcnt_attach_dynamic(&sc->sc_ev_txptr3a , EVCNT_TYPE_MISC,
659 NULL, device_xname(self), "TX pkts w/ptr3 ~160bytes"); 659 NULL, device_xname(self), "TX pkts w/ptr3 ~160bytes");
660 evcnt_attach_dynamic(&sc->sc_ev_txptr3b , EVCNT_TYPE_MISC, 660 evcnt_attach_dynamic(&sc->sc_ev_txptr3b , EVCNT_TYPE_MISC,
661 NULL, device_xname(self), "TX pkts w/ptr3 ~256bytes"); 661 NULL, device_xname(self), "TX pkts w/ptr3 ~256bytes");
662 evcnt_attach_dynamic(&sc->sc_ev_txptr3c , EVCNT_TYPE_MISC, 662 evcnt_attach_dynamic(&sc->sc_ev_txptr3c , EVCNT_TYPE_MISC,
663 NULL, device_xname(self), "TX pkts w/ptr3 ~512bytes"); 663 NULL, device_xname(self), "TX pkts w/ptr3 ~512bytes");
664 evcnt_attach_dynamic(&sc->sc_ev_txptr3d , EVCNT_TYPE_MISC, 664 evcnt_attach_dynamic(&sc->sc_ev_txptr3d , EVCNT_TYPE_MISC,
665 NULL, device_xname(self), "TX pkts w/ptr3 ~1024bytes"); 665 NULL, device_xname(self), "TX pkts w/ptr3 ~1024bytes");
666 evcnt_attach_dynamic(&sc->sc_ev_txptr3e , EVCNT_TYPE_MISC, 666 evcnt_attach_dynamic(&sc->sc_ev_txptr3e , EVCNT_TYPE_MISC,
667 NULL, device_xname(self), "TX pkts w/ptr3 >1024bytes"); 667 NULL, device_xname(self), "TX pkts w/ptr3 >1024bytes");
668 evcnt_attach_dynamic(&sc->sc_ev_txmbuf , EVCNT_TYPE_MISC, 668 evcnt_attach_dynamic(&sc->sc_ev_txmbuf , EVCNT_TYPE_MISC,
669 NULL, device_xname(self), "TX pkts copied to new mbufs"); 669 NULL, device_xname(self), "TX pkts copied to new mbufs");
670 evcnt_attach_dynamic(&sc->sc_ev_txmbufa , EVCNT_TYPE_MISC, 670 evcnt_attach_dynamic(&sc->sc_ev_txmbufa , EVCNT_TYPE_MISC,
671 NULL, device_xname(self), "TX pkts w/mbuf ~160bytes"); 671 NULL, device_xname(self), "TX pkts w/mbuf ~160bytes");
672 evcnt_attach_dynamic(&sc->sc_ev_txmbufb , EVCNT_TYPE_MISC, 672 evcnt_attach_dynamic(&sc->sc_ev_txmbufb , EVCNT_TYPE_MISC,
673 NULL, device_xname(self), "TX pkts w/mbuf ~256bytes"); 673 NULL, device_xname(self), "TX pkts w/mbuf ~256bytes");
674 evcnt_attach_dynamic(&sc->sc_ev_txmbufc , EVCNT_TYPE_MISC, 674 evcnt_attach_dynamic(&sc->sc_ev_txmbufc , EVCNT_TYPE_MISC,
675 NULL, device_xname(self), "TX pkts w/mbuf ~512bytes"); 675 NULL, device_xname(self), "TX pkts w/mbuf ~512bytes");
676 evcnt_attach_dynamic(&sc->sc_ev_txmbufd , EVCNT_TYPE_MISC, 676 evcnt_attach_dynamic(&sc->sc_ev_txmbufd , EVCNT_TYPE_MISC,
677 NULL, device_xname(self), "TX pkts w/mbuf ~1024bytes"); 677 NULL, device_xname(self), "TX pkts w/mbuf ~1024bytes");
678 evcnt_attach_dynamic(&sc->sc_ev_txmbufe , EVCNT_TYPE_MISC, 678 evcnt_attach_dynamic(&sc->sc_ev_txmbufe , EVCNT_TYPE_MISC,
679 NULL, device_xname(self), "TX pkts w/mbuf >1024bytes"); 679 NULL, device_xname(self), "TX pkts w/mbuf >1024bytes");
680 evcnt_attach_dynamic(&sc->sc_ev_txptrs , EVCNT_TYPE_MISC, 680 evcnt_attach_dynamic(&sc->sc_ev_txptrs , EVCNT_TYPE_MISC,
681 NULL, device_xname(self), "TX pkts using ptrs total"); 681 NULL, device_xname(self), "TX pkts using ptrs total");
682 evcnt_attach_dynamic(&sc->sc_ev_txptrc0 , EVCNT_TYPE_MISC, 682 evcnt_attach_dynamic(&sc->sc_ev_txptrc0 , EVCNT_TYPE_MISC,
683 NULL, device_xname(self), "TX pkts w/ptrs no hdr chain"); 683 NULL, device_xname(self), "TX pkts w/ptrs no hdr chain");
684 evcnt_attach_dynamic(&sc->sc_ev_txptrc1 , EVCNT_TYPE_MISC, 684 evcnt_attach_dynamic(&sc->sc_ev_txptrc1 , EVCNT_TYPE_MISC,
685 NULL, device_xname(self), "TX pkts w/ptrs 1 hdr chain"); 685 NULL, device_xname(self), "TX pkts w/ptrs 1 hdr chain");
686 evcnt_attach_dynamic(&sc->sc_ev_txptrc2 , EVCNT_TYPE_MISC, 686 evcnt_attach_dynamic(&sc->sc_ev_txptrc2 , EVCNT_TYPE_MISC,
687 NULL, device_xname(self), "TX pkts w/ptrs 2 hdr chains"); 687 NULL, device_xname(self), "TX pkts w/ptrs 2 hdr chains");
688 evcnt_attach_dynamic(&sc->sc_ev_txptrc3 , EVCNT_TYPE_MISC, 688 evcnt_attach_dynamic(&sc->sc_ev_txptrc3 , EVCNT_TYPE_MISC,
689 NULL, device_xname(self), "TX pkts w/ptrs 3 hdr chains"); 689 NULL, device_xname(self), "TX pkts w/ptrs 3 hdr chains");
690 evcnt_attach_dynamic(&sc->sc_ev_txptrc4 , EVCNT_TYPE_MISC, 690 evcnt_attach_dynamic(&sc->sc_ev_txptrc4 , EVCNT_TYPE_MISC,
691 NULL, device_xname(self), "TX pkts w/ptrs 4 hdr chains"); 691 NULL, device_xname(self), "TX pkts w/ptrs 4 hdr chains");
692 evcnt_attach_dynamic(&sc->sc_ev_txptrc5 , EVCNT_TYPE_MISC, 692 evcnt_attach_dynamic(&sc->sc_ev_txptrc5 , EVCNT_TYPE_MISC,
693 NULL, device_xname(self), "TX pkts w/ptrs 5 hdr chains"); 693 NULL, device_xname(self), "TX pkts w/ptrs 5 hdr chains");
694 evcnt_attach_dynamic(&sc->sc_ev_txptrc6 , EVCNT_TYPE_MISC, 694 evcnt_attach_dynamic(&sc->sc_ev_txptrc6 , EVCNT_TYPE_MISC,
695 NULL, device_xname(self), "TX pkts w/ptrs >5 hdr chains"); 695 NULL, device_xname(self), "TX pkts w/ptrs >5 hdr chains");
696 evcnt_attach_dynamic(&sc->sc_ev_txptrh0 , EVCNT_TYPE_MISC, 696 evcnt_attach_dynamic(&sc->sc_ev_txptrh0 , EVCNT_TYPE_MISC,
697 NULL, device_xname(self), "TX pkts w/ptrs ~8bytes hdr"); 697 NULL, device_xname(self), "TX pkts w/ptrs ~8bytes hdr");
698 evcnt_attach_dynamic(&sc->sc_ev_txptrh1 , EVCNT_TYPE_MISC, 698 evcnt_attach_dynamic(&sc->sc_ev_txptrh1 , EVCNT_TYPE_MISC,
699 NULL, device_xname(self), "TX pkts w/ptrs ~16bytes hdr"); 699 NULL, device_xname(self), "TX pkts w/ptrs ~16bytes hdr");
700 evcnt_attach_dynamic(&sc->sc_ev_txptrh2 , EVCNT_TYPE_MISC, 700 evcnt_attach_dynamic(&sc->sc_ev_txptrh2 , EVCNT_TYPE_MISC,
701 NULL, device_xname(self), "TX pkts w/ptrs ~32bytes hdr"); 701 NULL, device_xname(self), "TX pkts w/ptrs ~32bytes hdr");
702 evcnt_attach_dynamic(&sc->sc_ev_txptrh3 , EVCNT_TYPE_MISC, 702 evcnt_attach_dynamic(&sc->sc_ev_txptrh3 , EVCNT_TYPE_MISC,
703 NULL, device_xname(self), "TX pkts w/ptrs ~64bytes hdr"); 703 NULL, device_xname(self), "TX pkts w/ptrs ~64bytes hdr");
704 evcnt_attach_dynamic(&sc->sc_ev_txptrh4 , EVCNT_TYPE_MISC, 704 evcnt_attach_dynamic(&sc->sc_ev_txptrh4 , EVCNT_TYPE_MISC,
705 NULL, device_xname(self), "TX pkts w/ptrs ~80bytes hdr"); 705 NULL, device_xname(self), "TX pkts w/ptrs ~80bytes hdr");
706 evcnt_attach_dynamic(&sc->sc_ev_txptrh5 , EVCNT_TYPE_MISC, 706 evcnt_attach_dynamic(&sc->sc_ev_txptrh5 , EVCNT_TYPE_MISC,
707 NULL, device_xname(self), "TX pkts w/ptrs ~96bytes hdr"); 707 NULL, device_xname(self), "TX pkts w/ptrs ~96bytes hdr");
708 evcnt_attach_dynamic(&sc->sc_ev_txdstall , EVCNT_TYPE_MISC, 708 evcnt_attach_dynamic(&sc->sc_ev_txdstall , EVCNT_TYPE_MISC,
709 NULL, device_xname(self), "TX stalled due to no txdesc"); 709 NULL, device_xname(self), "TX stalled due to no txdesc");
710 evcnt_attach_dynamic(&sc->sc_ev_txempty , EVCNT_TYPE_MISC, 710 evcnt_attach_dynamic(&sc->sc_ev_txempty , EVCNT_TYPE_MISC,
711 NULL, device_xname(self), "TX empty interrupts"); 711 NULL, device_xname(self), "TX empty interrupts");
712 evcnt_attach_dynamic(&sc->sc_ev_txsent , EVCNT_TYPE_MISC, 712 evcnt_attach_dynamic(&sc->sc_ev_txsent , EVCNT_TYPE_MISC,
713 NULL, device_xname(self), "TX sent interrupts"); 713 NULL, device_xname(self), "TX sent interrupts");
714#endif 714#endif
715 715
716 /* set shutdown hook to reset interface on powerdown */ 716 /* set shutdown hook to reset interface on powerdown */
717 if (pmf_device_register1(self, NULL, NULL, mec_shutdown)) 717 if (pmf_device_register1(self, NULL, NULL, mec_shutdown))
718 pmf_class_network_register(self, ifp); 718 pmf_class_network_register(self, ifp);
719 else 719 else
720 aprint_error_dev(self, "couldn't establish power handler\n"); 720 aprint_error_dev(self, "couldn't establish power handler\n");
721 721
722 return; 722 return;
723 723
724 /* 724 /*
725 * Free any resources we've allocated during the failed attach 725 * Free any resources we've allocated during the failed attach
726 * attempt. Do this in reverse order and fall though. 726 * attempt. Do this in reverse order and fall though.
727 */ 727 */
728 fail_4: 728 fail_4:
729 for (i = 0; i < MEC_NTXDESC; i++) { 729 for (i = 0; i < MEC_NTXDESC; i++) {
730 if (sc->sc_txsoft[i].txs_dmamap != NULL) 730 if (sc->sc_txsoft[i].txs_dmamap != NULL)
731 bus_dmamap_destroy(sc->sc_dmat, 731 bus_dmamap_destroy(sc->sc_dmat,
732 sc->sc_txsoft[i].txs_dmamap); 732 sc->sc_txsoft[i].txs_dmamap);
733 } 733 }
734 bus_dmamap_unload(sc->sc_dmat, sc->sc_cddmamap); 734 bus_dmamap_unload(sc->sc_dmat, sc->sc_cddmamap);
735 fail_3: 735 fail_3:
736 bus_dmamap_destroy(sc->sc_dmat, sc->sc_cddmamap); 736 bus_dmamap_destroy(sc->sc_dmat, sc->sc_cddmamap);
737 fail_2: 737 fail_2:
738 bus_dmamem_unmap(sc->sc_dmat, (void *)sc->sc_control_data, 738 bus_dmamem_unmap(sc->sc_dmat, (void *)sc->sc_control_data,
739 sizeof(struct mec_control_data)); 739 sizeof(struct mec_control_data));
740 fail_1: 740 fail_1:
741 bus_dmamem_free(sc->sc_dmat, &seg, rseg); 741 bus_dmamem_free(sc->sc_dmat, &seg, rseg);
742 fail_0: 742 fail_0:
743 return; 743 return;
744} 744}
745 745
746static int 746static int
747mec_mii_readreg(device_t self, int phy, int reg) 747mec_mii_readreg(device_t self, int phy, int reg)
748{ 748{
749 struct mec_softc *sc = device_private(self); 749 struct mec_softc *sc = device_private(self);
750 bus_space_tag_t st = sc->sc_st; 750 bus_space_tag_t st = sc->sc_st;
751 bus_space_handle_t sh = sc->sc_sh; 751 bus_space_handle_t sh = sc->sc_sh;
752 uint64_t val; 752 uint64_t val;
753 int i; 753 int i;
754 754
755 if (mec_mii_wait(sc) != 0) 755 if (mec_mii_wait(sc) != 0)
756 return 0; 756 return 0;
757 757
758 bus_space_write_8(st, sh, MEC_PHY_ADDRESS, 758 bus_space_write_8(st, sh, MEC_PHY_ADDRESS,
759 (phy << MEC_PHY_ADDR_DEVSHIFT) | (reg & MEC_PHY_ADDR_REGISTER)); 759 (phy << MEC_PHY_ADDR_DEVSHIFT) | (reg & MEC_PHY_ADDR_REGISTER));
760 delay(25); 760 delay(25);
761 bus_space_write_8(st, sh, MEC_PHY_READ_INITIATE, 1); 761 bus_space_write_8(st, sh, MEC_PHY_READ_INITIATE, 1);
762 delay(25); 762 delay(25);
763 mec_mii_wait(sc); 763 mec_mii_wait(sc);
764 764
765 for (i = 0; i < 20; i++) { 765 for (i = 0; i < 20; i++) {
766 delay(30); 766 delay(30);
767 767
768 val = bus_space_read_8(st, sh, MEC_PHY_DATA); 768 val = bus_space_read_8(st, sh, MEC_PHY_DATA);
769 769
770 if ((val & MEC_PHY_DATA_BUSY) == 0) 770 if ((val & MEC_PHY_DATA_BUSY) == 0)
771 return val & MEC_PHY_DATA_VALUE; 771 return val & MEC_PHY_DATA_VALUE;
772 } 772 }
773 return 0; 773 return 0;
774} 774}
775 775
776static void 776static void
777mec_mii_writereg(device_t self, int phy, int reg, int val) 777mec_mii_writereg(device_t self, int phy, int reg, int val)
778{ 778{
779 struct mec_softc *sc = device_private(self); 779 struct mec_softc *sc = device_private(self);
780 bus_space_tag_t st = sc->sc_st; 780 bus_space_tag_t st = sc->sc_st;
781 bus_space_handle_t sh = sc->sc_sh; 781 bus_space_handle_t sh = sc->sc_sh;
782 782
783 if (mec_mii_wait(sc) != 0) { 783 if (mec_mii_wait(sc) != 0) {
784 printf("timed out writing %x: %x\n", reg, val); 784 printf("timed out writing %x: %x\n", reg, val);
785 return; 785 return;
786 } 786 }
787 787
788 bus_space_write_8(st, sh, MEC_PHY_ADDRESS, 788 bus_space_write_8(st, sh, MEC_PHY_ADDRESS,
789 (phy << MEC_PHY_ADDR_DEVSHIFT) | (reg & MEC_PHY_ADDR_REGISTER)); 789 (phy << MEC_PHY_ADDR_DEVSHIFT) | (reg & MEC_PHY_ADDR_REGISTER));
790 790
791 delay(60); 791 delay(60);
792 792
793 bus_space_write_8(st, sh, MEC_PHY_DATA, val & MEC_PHY_DATA_VALUE); 793 bus_space_write_8(st, sh, MEC_PHY_DATA, val & MEC_PHY_DATA_VALUE);
794 794
795 delay(60); 795 delay(60);
796 796
797 mec_mii_wait(sc); 797 mec_mii_wait(sc);
798} 798}
799 799
800static int 800static int
801mec_mii_wait(struct mec_softc *sc) 801mec_mii_wait(struct mec_softc *sc)
802{ 802{
803 uint32_t busy; 803 uint32_t busy;
804 int i, s; 804 int i, s;
805 805
806 for (i = 0; i < 100; i++) { 806 for (i = 0; i < 100; i++) {
807 delay(30); 807 delay(30);
808 808
809 s = splhigh(); 809 s = splhigh();
810 busy = bus_space_read_8(sc->sc_st, sc->sc_sh, MEC_PHY_DATA); 810 busy = bus_space_read_8(sc->sc_st, sc->sc_sh, MEC_PHY_DATA);
811 splx(s); 811 splx(s);
812 812
813 if ((busy & MEC_PHY_DATA_BUSY) == 0) 813 if ((busy & MEC_PHY_DATA_BUSY) == 0)
814 return 0; 814 return 0;
815#if 0 815#if 0
816 if (busy == 0xffff) /* XXX ? */ 816 if (busy == 0xffff) /* XXX ? */
817 return 0; 817 return 0;
818#endif 818#endif
819 } 819 }
820 820
821 printf("%s: MII timed out\n", device_xname(sc->sc_dev)); 821 printf("%s: MII timed out\n", device_xname(sc->sc_dev));
822 return 1; 822 return 1;
823} 823}
824 824
825static void 825static void
826mec_statchg(struct ifnet *ifp) 826mec_statchg(struct ifnet *ifp)
827{ 827{
828 struct mec_softc *sc = ifp->if_softc; 828 struct mec_softc *sc = ifp->if_softc;
829 bus_space_tag_t st = sc->sc_st; 829 bus_space_tag_t st = sc->sc_st;
830 bus_space_handle_t sh = sc->sc_sh; 830 bus_space_handle_t sh = sc->sc_sh;
831 uint32_t control; 831 uint32_t control;
832 832
833 control = bus_space_read_8(st, sh, MEC_MAC_CONTROL); 833 control = bus_space_read_8(st, sh, MEC_MAC_CONTROL);
834 control &= ~(MEC_MAC_IPGT | MEC_MAC_IPGR1 | MEC_MAC_IPGR2 | 834 control &= ~(MEC_MAC_IPGT | MEC_MAC_IPGR1 | MEC_MAC_IPGR2 |
835 MEC_MAC_FULL_DUPLEX | MEC_MAC_SPEED_SELECT); 835 MEC_MAC_FULL_DUPLEX | MEC_MAC_SPEED_SELECT);
836 836
837 /* must also set IPG here for duplex stuff ... */ 837 /* must also set IPG here for duplex stuff ... */
838 if ((sc->sc_mii.mii_media_active & IFM_FDX) != 0) { 838 if ((sc->sc_mii.mii_media_active & IFM_FDX) != 0) {
839 control |= MEC_MAC_FULL_DUPLEX; 839 control |= MEC_MAC_FULL_DUPLEX;
840 } else { 840 } else {
841 /* set IPG */ 841 /* set IPG */
842 control |= MEC_MAC_IPG_DEFAULT; 842 control |= MEC_MAC_IPG_DEFAULT;
843 } 843 }
844 844
845 bus_space_write_8(st, sh, MEC_MAC_CONTROL, control); 845 bus_space_write_8(st, sh, MEC_MAC_CONTROL, control);
846} 846}
847 847
848static int 848static int
849mec_init(struct ifnet *ifp) 849mec_init(struct ifnet *ifp)
850{ 850{
851 struct mec_softc *sc = ifp->if_softc; 851 struct mec_softc *sc = ifp->if_softc;
852 bus_space_tag_t st = sc->sc_st; 852 bus_space_tag_t st = sc->sc_st;
853 bus_space_handle_t sh = sc->sc_sh; 853 bus_space_handle_t sh = sc->sc_sh;
854 struct mec_rxdesc *rxd; 854 struct mec_rxdesc *rxd;
855 int i, rc; 855 int i, rc;
856 856
857 /* cancel any pending I/O */ 857 /* cancel any pending I/O */
858 mec_stop(ifp, 0); 858 mec_stop(ifp, 0);
859 859
860 /* reset device */ 860 /* reset device */
861 mec_reset(sc); 861 mec_reset(sc);
862 862
863 /* setup filter for multicast or promisc mode */ 863 /* setup filter for multicast or promisc mode */
864 mec_setfilter(sc); 864 mec_setfilter(sc);
865 865
866 /* set the TX ring pointer to the base address */ 866 /* set the TX ring pointer to the base address */
867 bus_space_write_8(st, sh, MEC_TX_RING_BASE, MEC_CDTXADDR(sc, 0)); 867 bus_space_write_8(st, sh, MEC_TX_RING_BASE, MEC_CDTXADDR(sc, 0));
868 868
869 sc->sc_txpending = 0; 869 sc->sc_txpending = 0;
870 sc->sc_txdirty = 0; 870 sc->sc_txdirty = 0;
871 sc->sc_txlast = MEC_NTXDESC - 1; 871 sc->sc_txlast = MEC_NTXDESC - 1;
872 872
873 /* put RX buffers into FIFO */ 873 /* put RX buffers into FIFO */
874 for (i = 0; i < MEC_NRXDESC; i++) { 874 for (i = 0; i < MEC_NRXDESC; i++) {
875 rxd = &sc->sc_rxdesc[i]; 875 rxd = &sc->sc_rxdesc[i];
876 rxd->rxd_stat = 0; 876 rxd->rxd_stat = 0;
877 MEC_RXSTATSYNC(sc, i, BUS_DMASYNC_PREREAD); 877 MEC_RXSTATSYNC(sc, i, BUS_DMASYNC_PREREAD);
878 MEC_RXBUFSYNC(sc, i, ETHER_MAX_LEN, BUS_DMASYNC_PREREAD); 878 MEC_RXBUFSYNC(sc, i, ETHER_MAX_LEN, BUS_DMASYNC_PREREAD);
879 bus_space_write_8(st, sh, MEC_MCL_RX_FIFO, MEC_CDRXADDR(sc, i)); 879 bus_space_write_8(st, sh, MEC_MCL_RX_FIFO, MEC_CDRXADDR(sc, i));
880 } 880 }
881 sc->sc_rxptr = 0; 881 sc->sc_rxptr = 0;
882 882
883#if 0 /* XXX no info */ 883#if 0 /* XXX no info */
884 bus_space_write_8(st, sh, MEC_TIMER, 0); 884 bus_space_write_8(st, sh, MEC_TIMER, 0);
885#endif 885#endif
886 886
887 /* 887 /*
888 * MEC_DMA_TX_INT_ENABLE will be set later otherwise it causes 888 * MEC_DMA_TX_INT_ENABLE will be set later otherwise it causes
889 * spurious interrupts when TX buffers are empty 889 * spurious interrupts when TX buffers are empty
890 */ 890 */
891 bus_space_write_8(st, sh, MEC_DMA_CONTROL, 891 bus_space_write_8(st, sh, MEC_DMA_CONTROL,
892 (MEC_RXD_DMAOFFSET << MEC_DMA_RX_DMA_OFFSET_SHIFT) | 892 (MEC_RXD_DMAOFFSET << MEC_DMA_RX_DMA_OFFSET_SHIFT) |
893 (MEC_NRXDESC << MEC_DMA_RX_INT_THRESH_SHIFT) | 893 (MEC_NRXDESC << MEC_DMA_RX_INT_THRESH_SHIFT) |
894 MEC_DMA_TX_DMA_ENABLE | /* MEC_DMA_TX_INT_ENABLE | */ 894 MEC_DMA_TX_DMA_ENABLE | /* MEC_DMA_TX_INT_ENABLE | */
895 MEC_DMA_RX_DMA_ENABLE | MEC_DMA_RX_INT_ENABLE); 895 MEC_DMA_RX_DMA_ENABLE | MEC_DMA_RX_INT_ENABLE);
896 896
897 callout_reset(&sc->sc_tick_ch, hz, mec_tick, sc); 897 callout_reset(&sc->sc_tick_ch, hz, mec_tick, sc);
898 898
899 if ((rc = ether_mediachange(ifp)) != 0) 899 if ((rc = ether_mediachange(ifp)) != 0)
900 return rc; 900 return rc;
901 901
902 ifp->if_flags |= IFF_RUNNING; 902 ifp->if_flags |= IFF_RUNNING;
903 ifp->if_flags &= ~IFF_OACTIVE; 903 ifp->if_flags &= ~IFF_OACTIVE;
904 mec_start(ifp); 904 mec_start(ifp);
905 905
906 return 0; 906 return 0;
907} 907}
908 908
909static void 909static void
910mec_reset(struct mec_softc *sc) 910mec_reset(struct mec_softc *sc)
911{ 911{
912 bus_space_tag_t st = sc->sc_st; 912 bus_space_tag_t st = sc->sc_st;
913 bus_space_handle_t sh = sc->sc_sh; 913 bus_space_handle_t sh = sc->sc_sh;
914 uint64_t control; 914 uint64_t control;
915 915
916 /* stop DMA first */ 916 /* stop DMA first */
917 bus_space_write_8(st, sh, MEC_DMA_CONTROL, 0); 917 bus_space_write_8(st, sh, MEC_DMA_CONTROL, 0);
918 918
919 /* reset chip */ 919 /* reset chip */
920 bus_space_write_8(st, sh, MEC_MAC_CONTROL, MEC_MAC_CORE_RESET); 920 bus_space_write_8(st, sh, MEC_MAC_CONTROL, MEC_MAC_CORE_RESET);
921 delay(1000); 921 delay(1000);
922 bus_space_write_8(st, sh, MEC_MAC_CONTROL, 0); 922 bus_space_write_8(st, sh, MEC_MAC_CONTROL, 0);
923 delay(1000); 923 delay(1000);
924 924
925 /* Default to 100/half and let auto-negotiation work its magic */ 925 /* Default to 100/half and let auto-negotiation work its magic */
926 control = MEC_MAC_SPEED_SELECT | MEC_MAC_FILTER_MATCHMULTI | 926 control = MEC_MAC_SPEED_SELECT | MEC_MAC_FILTER_MATCHMULTI |
927 MEC_MAC_IPG_DEFAULT; 927 MEC_MAC_IPG_DEFAULT;
928 928
929 bus_space_write_8(st, sh, MEC_MAC_CONTROL, control); 929 bus_space_write_8(st, sh, MEC_MAC_CONTROL, control);
930 /* stop DMA again for sanity */ 930 /* stop DMA again for sanity */
931 bus_space_write_8(st, sh, MEC_DMA_CONTROL, 0); 931 bus_space_write_8(st, sh, MEC_DMA_CONTROL, 0);
932 932
933 DPRINTF(MEC_DEBUG_RESET, ("mec: control now %llx\n", 933 DPRINTF(MEC_DEBUG_RESET, ("mec: control now %llx\n",
934 bus_space_read_8(st, sh, MEC_MAC_CONTROL))); 934 bus_space_read_8(st, sh, MEC_MAC_CONTROL)));
935} 935}
936 936
937static void 937static void
938mec_start(struct ifnet *ifp) 938mec_start(struct ifnet *ifp)
939{ 939{
940 struct mec_softc *sc = ifp->if_softc; 940 struct mec_softc *sc = ifp->if_softc;
941 struct mbuf *m0, *m; 941 struct mbuf *m0, *m;
942 struct mec_txdesc *txd; 942 struct mec_txdesc *txd;
943 struct mec_txsoft *txs; 943 struct mec_txsoft *txs;
944 bus_dmamap_t dmamap; 944 bus_dmamap_t dmamap;
945 bus_space_tag_t st = sc->sc_st; 945 bus_space_tag_t st = sc->sc_st;
946 bus_space_handle_t sh = sc->sc_sh; 946 bus_space_handle_t sh = sc->sc_sh;
947 int error, firsttx, nexttx, opending; 947 int error, firsttx, nexttx, opending;
948 int len, bufoff, buflen, nsegs, align, resid, pseg, nptr, slen, i; 948 int len, bufoff, buflen, nsegs, align, resid, pseg, nptr, slen, i;
949 uint32_t txdcmd; 949 uint32_t txdcmd;
950 950
951 if ((ifp->if_flags & (IFF_RUNNING|IFF_OACTIVE)) != IFF_RUNNING) 951 if ((ifp->if_flags & (IFF_RUNNING|IFF_OACTIVE)) != IFF_RUNNING)
952 return; 952 return;
953 953
954 /* 954 /*
955 * Remember the previous txpending and the first transmit descriptor. 955 * Remember the previous txpending and the first transmit descriptor.
956 */ 956 */
957 opending = sc->sc_txpending; 957 opending = sc->sc_txpending;
958 firsttx = MEC_NEXTTX(sc->sc_txlast); 958 firsttx = MEC_NEXTTX(sc->sc_txlast);
959 959
960 DPRINTF(MEC_DEBUG_START, 960 DPRINTF(MEC_DEBUG_START,
961 ("%s: opending = %d, firsttx = %d\n", __func__, opending, firsttx)); 961 ("%s: opending = %d, firsttx = %d\n", __func__, opending, firsttx));
962 962
963 while (sc->sc_txpending < MEC_NTXDESC - 1) { 963 while (sc->sc_txpending < MEC_NTXDESC - 1) {
964 /* Grab a packet off the queue. */ 964 /* Grab a packet off the queue. */
965 IFQ_POLL(&ifp->if_snd, m0); 965 IFQ_POLL(&ifp->if_snd, m0);
966 if (m0 == NULL) 966 if (m0 == NULL)
967 break; 967 break;
968 m = NULL; 968 m = NULL;
969 969
970 /* 970 /*
971 * Get the next available transmit descriptor. 971 * Get the next available transmit descriptor.
972 */ 972 */
973 nexttx = MEC_NEXTTX(sc->sc_txlast); 973 nexttx = MEC_NEXTTX(sc->sc_txlast);
974 txd = &sc->sc_txdesc[nexttx]; 974 txd = &sc->sc_txdesc[nexttx];
975 txs = &sc->sc_txsoft[nexttx]; 975 txs = &sc->sc_txsoft[nexttx];
976 dmamap = txs->txs_dmamap; 976 dmamap = txs->txs_dmamap;
977 txs->txs_flags = 0; 977 txs->txs_flags = 0;
978 978
979 buflen = 0; 979 buflen = 0;
980 bufoff = 0; 980 bufoff = 0;
981 resid = 0; 981 resid = 0;
982 nptr = 0; /* XXX gcc */ 982 nptr = 0; /* XXX gcc */
983 pseg = 0; /* XXX gcc */ 983 pseg = 0; /* XXX gcc */
984 984
985 len = m0->m_pkthdr.len; 985 len = m0->m_pkthdr.len;
986 986
987 DPRINTF(MEC_DEBUG_START, 987 DPRINTF(MEC_DEBUG_START,
988 ("%s: len = %d, nexttx = %d, txpending = %d\n", 988 ("%s: len = %d, nexttx = %d, txpending = %d\n",
989 __func__, len, nexttx, sc->sc_txpending)); 989 __func__, len, nexttx, sc->sc_txpending));
990 990
991 if (len <= MEC_TXD_BUFSIZE) { 991 if (len <= MEC_TXD_BUFSIZE) {
992 /* 992 /*
993 * If a TX packet will fit into small txdesc buffer, 993 * If a TX packet will fit into small txdesc buffer,
994 * just copy it into there. Maybe it's faster than 994 * just copy it into there. Maybe it's faster than
995 * checking alignment and calling bus_dma(9) etc. 995 * checking alignment and calling bus_dma(9) etc.
996 */ 996 */
997 DPRINTF(MEC_DEBUG_START, ("%s: short packet\n", 997 DPRINTF(MEC_DEBUG_START, ("%s: short packet\n",
998 __func__)); 998 __func__));
999 IFQ_DEQUEUE(&ifp->if_snd, m0); 999 IFQ_DEQUEUE(&ifp->if_snd, m0);
1000 1000
1001 /* 1001 /*
1002 * I don't know if MEC chip does auto padding, 1002 * I don't know if MEC chip does auto padding,
1003 * but do it manually for safety. 1003 * but do it manually for safety.
1004 */ 1004 */
1005 if (len < ETHER_PAD_LEN) { 1005 if (len < ETHER_PAD_LEN) {
1006 MEC_EVCNT_INCR(&sc->sc_ev_txdpad); 1006 MEC_EVCNT_INCR(&sc->sc_ev_txdpad);
1007 bufoff = MEC_TXD_BUFSTART(ETHER_PAD_LEN); 1007 bufoff = MEC_TXD_BUFSTART(ETHER_PAD_LEN);
1008 m_copydata(m0, 0, len, txd->txd_buf + bufoff); 1008 m_copydata(m0, 0, len, txd->txd_buf + bufoff);
1009 memset(txd->txd_buf + bufoff + len, 0, 1009 memset(txd->txd_buf + bufoff + len, 0,
1010 ETHER_PAD_LEN - len); 1010 ETHER_PAD_LEN - len);
1011 len = buflen = ETHER_PAD_LEN; 1011 len = buflen = ETHER_PAD_LEN;
1012 } else { 1012 } else {
1013 MEC_EVCNT_INCR(&sc->sc_ev_txdbuf); 1013 MEC_EVCNT_INCR(&sc->sc_ev_txdbuf);
1014 bufoff = MEC_TXD_BUFSTART(len); 1014 bufoff = MEC_TXD_BUFSTART(len);
1015 m_copydata(m0, 0, len, txd->txd_buf + bufoff); 1015 m_copydata(m0, 0, len, txd->txd_buf + bufoff);
1016 buflen = len; 1016 buflen = len;
1017 } 1017 }
1018 } else { 1018 } else {
1019 /* 1019 /*
1020 * If the packet won't fit the static buffer in txdesc, 1020 * If the packet won't fit the static buffer in txdesc,
1021 * we have to use the concatenate pointers to handle it. 1021 * we have to use the concatenate pointers to handle it.
1022 */ 1022 */
1023 DPRINTF(MEC_DEBUG_START, ("%s: long packet\n", 1023 DPRINTF(MEC_DEBUG_START, ("%s: long packet\n",
1024 __func__)); 1024 __func__));
1025 txs->txs_flags = MEC_TXS_TXDPTR; 1025 txs->txs_flags = MEC_TXS_TXDPTR;
1026 1026
1027 /* 1027 /*
1028 * Call bus_dmamap_load_mbuf(9) first to see 1028 * Call bus_dmamap_load_mbuf(9) first to see
1029 * how many chains the TX mbuf has. 1029 * how many chains the TX mbuf has.
1030 */ 1030 */
1031 error = bus_dmamap_load_mbuf(sc->sc_dmat, dmamap, m0, 1031 error = bus_dmamap_load_mbuf(sc->sc_dmat, dmamap, m0,
1032 BUS_DMA_WRITE | BUS_DMA_NOWAIT); 1032 BUS_DMA_WRITE | BUS_DMA_NOWAIT);
1033 if (error == 0) { 1033 if (error == 0) {
1034 /* 1034 /*
1035 * Check chains which might contain headers. 1035 * Check chains which might contain headers.
1036 * They might be so much fragmented and 1036 * They might be so much fragmented and
1037 * it's better to copy them into txdesc buffer 1037 * it's better to copy them into txdesc buffer
1038 * since they would be small enough. 1038 * since they would be small enough.
1039 */ 1039 */
1040 nsegs = dmamap->dm_nsegs; 1040 nsegs = dmamap->dm_nsegs;
1041 for (pseg = 0; pseg < nsegs; pseg++) { 1041 for (pseg = 0; pseg < nsegs; pseg++) {
1042 slen = dmamap->dm_segs[pseg].ds_len; 1042 slen = dmamap->dm_segs[pseg].ds_len;
1043 if (buflen + slen > 1043 if (buflen + slen >
1044 MEC_TXD_BUFSIZE1 - MEC_TXD_ALIGN) 1044 MEC_TXD_BUFSIZE1 - MEC_TXD_ALIGN)
1045 break; 1045 break;
1046 buflen += slen; 1046 buflen += slen;
1047 } 1047 }
1048 /* 1048 /*
1049 * Check if the rest chains can be fit into 1049 * Check if the rest chains can be fit into
1050 * the concatinate pointers. 1050 * the concatinate pointers.
1051 */ 1051 */
1052 align = dmamap->dm_segs[pseg].ds_addr & 1052 align = dmamap->dm_segs[pseg].ds_addr &
1053 MEC_TXD_ALIGNMASK; 1053 MEC_TXD_ALIGNMASK;
1054 if (align > 0) { 1054 if (align > 0) {
1055 /* 1055 /*
1056 * If the first chain isn't uint64_t 1056 * If the first chain isn't uint64_t
1057 * aligned, append the unaligned part 1057 * aligned, append the unaligned part
1058 * into txdesc buffer too. 1058 * into txdesc buffer too.
1059 */ 1059 */
1060 resid = MEC_TXD_ALIGN - align; 1060 resid = MEC_TXD_ALIGN - align;
1061 buflen += resid; 1061 buflen += resid;
1062 for (; pseg < nsegs; pseg++) { 1062 for (; pseg < nsegs; pseg++) {
1063 slen = 1063 slen =
1064 dmamap->dm_segs[pseg].ds_len; 1064 dmamap->dm_segs[pseg].ds_len;
1065 if (slen > resid) 1065 if (slen > resid)
1066 break; 1066 break;
1067 resid -= slen; 1067 resid -= slen;
1068 } 1068 }
1069 } else if (pseg == 0) { 1069 } else if (pseg == 0) {
1070 /* 1070 /*
1071 * In this case, the first chain is 1071 * In this case, the first chain is
1072 * uint64_t aligned but it's too long 1072 * uint64_t aligned but it's too long
1073 * to put into txdesc buf. 1073 * to put into txdesc buf.
1074 * We have to put some data into 1074 * We have to put some data into
1075 * txdesc buf even in this case, 1075 * txdesc buf even in this case,
1076 * so put MEC_TXD_ALIGN bytes there. 1076 * so put MEC_TXD_ALIGN bytes there.
1077 */ 1077 */
1078 buflen = resid = MEC_TXD_ALIGN; 1078 buflen = resid = MEC_TXD_ALIGN;