1 | /* $NetBSD: i82557var.h,v 1.52 2015/04/13 16:33:24 riastradh Exp $ */ |
2 | |
3 | /*- |
4 | * Copyright (c) 1997, 1998, 1999, 2001 The NetBSD Foundation, Inc. |
5 | * All rights reserved. |
6 | * |
7 | * This code is derived from software contributed to The NetBSD Foundation |
8 | * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility, |
9 | * NASA Ames Research Center. |
10 | * |
11 | * Redistribution and use in source and binary forms, with or without |
12 | * modification, are permitted provided that the following conditions |
13 | * are met: |
14 | * 1. Redistributions of source code must retain the above copyright |
15 | * notice, this list of conditions and the following disclaimer. |
16 | * 2. Redistributions in binary form must reproduce the above copyright |
17 | * notice, this list of conditions and the following disclaimer in the |
18 | * documentation and/or other materials provided with the distribution. |
19 | * |
20 | * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS |
21 | * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED |
22 | * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
23 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS |
24 | * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
25 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
26 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
27 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
28 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
29 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
30 | * POSSIBILITY OF SUCH DAMAGE. |
31 | */ |
32 | |
33 | /* |
34 | * Copyright (c) 1995, David Greenman |
35 | * All rights reserved. |
36 | * |
37 | * Redistribution and use in source and binary forms, with or without |
38 | * modification, are permitted provided that the following conditions |
39 | * are met: |
40 | * 1. Redistributions of source code must retain the above copyright |
41 | * notice unmodified, this list of conditions, and the following |
42 | * disclaimer. |
43 | * 2. Redistributions in binary form must reproduce the above copyright |
44 | * notice, this list of conditions and the following disclaimer in the |
45 | * documentation and/or other materials provided with the distribution. |
46 | * |
47 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND |
48 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
49 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
50 | * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE |
51 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
52 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS |
53 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
54 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
55 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY |
56 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
57 | * SUCH DAMAGE. |
58 | * |
59 | * Id: if_fxpvar.h,v 1.4 1997/11/29 08:11:01 davidg Exp |
60 | */ |
61 | |
62 | #include <sys/callout.h> |
63 | #include <sys/rndsource.h> |
64 | |
65 | /* |
66 | * Misc. definitions for the Intel i82557 fast Ethernet controller |
67 | * driver. |
68 | */ |
69 | |
70 | /* |
71 | * Transmit descriptor list size. |
72 | */ |
73 | #define FXP_NTXCB 256 |
74 | #define FXP_NTXCB_MASK (FXP_NTXCB - 1) |
75 | #define FXP_NEXTTX(x) ((x + 1) & FXP_NTXCB_MASK) |
76 | #define FXP_NTXSEG 16 |
77 | #define FXP_IPCB_NTXSEG (FXP_NTXSEG - 1) |
78 | |
79 | /* |
80 | * Number of receive frame area buffers. These are large, so |
81 | * choose wisely. |
82 | */ |
83 | #define FXP_NRFABUFS 128 |
84 | |
85 | /* |
86 | * Maximum number of seconds that the receiver can be idle before we |
87 | * assume it's dead and attempt to reset it by reprogramming the |
88 | * multicast filter. This is part of a work-around for a bug in the |
89 | * NIC. See fxp_stats_update(). |
90 | */ |
91 | #define FXP_MAX_RX_IDLE 15 |
92 | |
93 | /* |
94 | * Misc. DMA'd data structures are allocated in a single clump, that |
95 | * maps to a single DMA segment, to make several things easier (computing |
96 | * offsets, setting up DMA maps, etc.) |
97 | */ |
98 | struct fxp_control_data { |
99 | /* |
100 | * The transmit control blocks and transmit buffer descriptors. |
101 | * We arrange them like this so that everything is all lined |
102 | * up to use the extended TxCB feature. |
103 | */ |
104 | struct fxp_txdesc { |
105 | struct fxp_cb_tx txd_txcb; |
106 | union { |
107 | struct fxp_ipcb txdu_ipcb; |
108 | struct fxp_tbd txdu_tbd[FXP_NTXSEG]; |
109 | } txd_u; |
110 | } fcd_txdescs[FXP_NTXCB]; |
111 | |
112 | /* |
113 | * The configuration CB. |
114 | */ |
115 | struct fxp_cb_config fcd_configcb; |
116 | |
117 | /* |
118 | * The Individual Address CB. |
119 | */ |
120 | struct fxp_cb_ias fcd_iascb; |
121 | |
122 | /* |
123 | * The multicast setup CB. |
124 | */ |
125 | struct fxp_cb_mcs fcd_mcscb; |
126 | |
127 | /* |
128 | * The microcode setup CB. |
129 | */ |
130 | struct fxp_cb_ucode fcd_ucode; |
131 | |
132 | /* |
133 | * The NIC statistics. |
134 | */ |
135 | struct fxp_stats fcd_stats; |
136 | |
137 | /* |
138 | * TX pad buffer for ip4csum-tx bug workaround. |
139 | */ |
140 | uint8_t fcd_txpad[FXP_IP4CSUMTX_PADLEN]; |
141 | }; |
142 | |
143 | #define txd_tbd txd_u.txdu_tbd |
144 | |
145 | #define FXP_CDOFF(x) offsetof(struct fxp_control_data, x) |
146 | #define FXP_CDTXOFF(x) FXP_CDOFF(fcd_txdescs[(x)].txd_txcb) |
147 | #define FXP_CDTBDOFF(x) FXP_CDOFF(fcd_txdescs[(x)].txd_tbd) |
148 | #define FXP_CDCONFIGOFF FXP_CDOFF(fcd_configcb) |
149 | #define FXP_CDIASOFF FXP_CDOFF(fcd_iascb) |
150 | #define FXP_CDMCSOFF FXP_CDOFF(fcd_mcscb) |
151 | #define FXP_CDUCODEOFF FXP_CDOFF(fcd_ucode) |
152 | #define FXP_CDSTATSOFF FXP_CDOFF(fcd_stats) |
153 | #define FXP_CDTXPADOFF FXP_CDOFF(fcd_txpad) |
154 | |
155 | /* |
156 | * Software state for transmit descriptors. |
157 | */ |
158 | struct fxp_txsoft { |
159 | struct mbuf *txs_mbuf; /* head of mbuf chain */ |
160 | bus_dmamap_t txs_dmamap; /* our DMA map */ |
161 | }; |
162 | |
163 | /* |
164 | * Software state per device. |
165 | */ |
166 | struct fxp_softc { |
167 | device_t sc_dev; |
168 | bus_space_tag_t sc_st; /* bus space tag */ |
169 | bus_space_handle_t sc_sh; /* bus space handle */ |
170 | bus_size_t sc_size; /* bus space size */ |
171 | bus_dma_tag_t sc_dmat; /* bus dma tag */ |
172 | struct ethercom sc_ethercom; /* ethernet common part */ |
173 | void *sc_ih; /* interrupt handler cookie */ |
174 | |
175 | struct mii_data sc_mii; /* MII/media information */ |
176 | struct callout sc_callout; /* MII callout */ |
177 | |
178 | /* |
179 | * We create a single DMA map that maps all data structure |
180 | * overhead, except for RFAs, which are mapped by the |
181 | * fxp_rxdesc DMA map on a per-mbuf basis. |
182 | */ |
183 | bus_dmamap_t sc_dmamap; |
184 | #define sc_cddma sc_dmamap->dm_segs[0].ds_addr |
185 | |
186 | /* |
187 | * Software state for transmit descriptors. |
188 | */ |
189 | struct fxp_txsoft sc_txsoft[FXP_NTXCB]; |
190 | |
191 | int sc_rfa_size; /* size of the RFA structure */ |
192 | struct ifqueue sc_rxq; /* receive buffer queue */ |
193 | bus_dmamap_t sc_rxmaps[FXP_NRFABUFS]; /* free receive buffer DMA maps */ |
194 | int sc_rxfree; /* free map index */ |
195 | int sc_rxidle; /* # of seconds RX has been idle */ |
196 | uint16_t sc_txcmd; /* transmit command (LITTLE ENDIAN) */ |
197 | |
198 | /* |
199 | * Control data structures. |
200 | */ |
201 | struct fxp_control_data *sc_control_data; |
202 | |
203 | #ifdef FXP_EVENT_COUNTERS |
204 | struct evcnt sc_ev_txstall; /* Tx stalled */ |
205 | struct evcnt sc_ev_txintr; /* Tx interrupts */ |
206 | struct evcnt sc_ev_rxintr; /* Rx interrupts */ |
207 | struct evcnt sc_ev_txpause; /* Tx PAUSE frames */ |
208 | struct evcnt sc_ev_rxpause; /* Rx PAUSE frames */ |
209 | #endif /* FXP_EVENT_COUNTERS */ |
210 | |
211 | bus_dma_segment_t sc_cdseg; /* control dma segment */ |
212 | int sc_cdnseg; |
213 | |
214 | int sc_rev; /* chip revision */ |
215 | int sc_flags; /* misc. flags */ |
216 | |
217 | #define FXPF_MII 0x0001 /* device uses MII */ |
218 | #define FXPF_ATTACHED 0x0002 /* attach has succeeded */ |
219 | #define FXPF_WANTINIT 0x0004 /* want a re-init */ |
220 | #define FXPF_HAS_RESUME_BUG 0x0008 /* has the resume bug */ |
221 | #define FXPF_MWI 0x0010 /* enable PCI MWI */ |
222 | #define FXPF_READ_ALIGN 0x0020 /* align read access w/ cacheline */ |
223 | #define FXPF_WRITE_ALIGN 0x0040 /* end write on cacheline */ |
224 | #define FXPF_EXT_TXCB 0x0080 /* has extended TxCB */ |
225 | #define FXPF_UCODE_LOADED 0x0100 /* microcode is loaded */ |
226 | #define FXPF_EXT_RFA 0x0200 /* has extended RFD and IPCB (82550) */ |
227 | #define FXPF_RECV_WORKAROUND 0x0800 /* receiver lock-up workaround */ |
228 | #define FXPF_FC 0x1000 /* has flow control */ |
229 | #define FXPF_82559_RXCSUM 0x2000 /* has 82559 compat RX checksum */ |
230 | |
231 | int sc_int_delay; /* interrupt delay */ |
232 | int sc_bundle_max; /* max packet bundle */ |
233 | |
234 | int sc_txpending; /* number of TX requests pending */ |
235 | int sc_txdirty; /* first dirty TX descriptor */ |
236 | int sc_txlast; /* last used TX descriptor */ |
237 | |
238 | int phy_primary_device; /* device type of primary PHY */ |
239 | |
240 | int sc_enabled; /* boolean; power enabled on interface */ |
241 | int (*sc_enable)(struct fxp_softc *); |
242 | void (*sc_disable)(struct fxp_softc *); |
243 | |
244 | int sc_eeprom_size; /* log2 size of EEPROM */ |
245 | krndsource_t rnd_source; /* random source */ |
246 | }; |
247 | |
248 | #ifdef FXP_EVENT_COUNTERS |
249 | #define FXP_EVCNT_INCR(ev) (ev)->ev_count++ |
250 | #else |
251 | #define FXP_EVCNT_INCR(ev) /* nothing */ |
252 | #endif |
253 | |
254 | #define FXP_RXMAP_GET(sc) ((sc)->sc_rxmaps[(sc)->sc_rxfree++]) |
255 | #define FXP_RXMAP_PUT(sc, map) (sc)->sc_rxmaps[--(sc)->sc_rxfree] = (map) |
256 | |
257 | #define FXP_CDTXADDR(sc, x) ((sc)->sc_cddma + FXP_CDTXOFF((x))) |
258 | #define FXP_CDTBDADDR(sc, x) ((sc)->sc_cddma + FXP_CDTBDOFF((x))) |
259 | #define FXP_CDTXPADADDR(sc) ((sc)->sc_cddma + FXP_CDTXPADOFF) |
260 | |
261 | #define FXP_CDTX(sc, x) (&(sc)->sc_control_data->fcd_txdescs[(x)]) |
262 | |
263 | #define FXP_DSTX(sc, x) (&(sc)->sc_txsoft[(x)]) |
264 | |
265 | #define FXP_CDTXSYNC(sc, x, ops) \ |
266 | bus_dmamap_sync((sc)->sc_dmat, (sc)->sc_dmamap, \ |
267 | FXP_CDTXOFF((x)), sizeof(struct fxp_txdesc), (ops)) |
268 | |
269 | #define FXP_CDCONFIGSYNC(sc, ops) \ |
270 | bus_dmamap_sync((sc)->sc_dmat, (sc)->sc_dmamap, \ |
271 | FXP_CDCONFIGOFF, sizeof(struct fxp_cb_config), (ops)) |
272 | |
273 | #define FXP_CDIASSYNC(sc, ops) \ |
274 | bus_dmamap_sync((sc)->sc_dmat, (sc)->sc_dmamap, \ |
275 | FXP_CDIASOFF, sizeof(struct fxp_cb_ias), (ops)) |
276 | |
277 | #define FXP_CDMCSSYNC(sc, ops) \ |
278 | bus_dmamap_sync((sc)->sc_dmat, (sc)->sc_dmamap, \ |
279 | FXP_CDMCSOFF, sizeof(struct fxp_cb_mcs), (ops)) |
280 | |
281 | #define FXP_CDUCODESYNC(sc, ops) \ |
282 | bus_dmamap_sync((sc)->sc_dmat, (sc)->sc_dmamap, \ |
283 | FXP_CDUCODEOFF, sizeof(struct fxp_cb_ucode), (ops)) |
284 | |
285 | #define FXP_CDSTATSSYNC(sc, ops) \ |
286 | bus_dmamap_sync((sc)->sc_dmat, (sc)->sc_dmamap, \ |
287 | FXP_CDSTATSOFF, sizeof(struct fxp_stats), (ops)) |
288 | |
289 | #define FXP_RXBUFSIZE(sc, m) ((m)->m_ext.ext_size - \ |
290 | (sc->sc_rfa_size + \ |
291 | RFA_ALIGNMENT_FUDGE)) |
292 | |
293 | #define FXP_RFASYNC(sc, m, ops) \ |
294 | bus_dmamap_sync((sc)->sc_dmat, M_GETCTX((m), bus_dmamap_t), \ |
295 | RFA_ALIGNMENT_FUDGE, (sc)->sc_rfa_size, (ops)) |
296 | |
297 | #define FXP_RXBUFSYNC(sc, m, ops) \ |
298 | bus_dmamap_sync((sc)->sc_dmat, M_GETCTX((m), bus_dmamap_t), \ |
299 | RFA_ALIGNMENT_FUDGE + (sc)->sc_rfa_size, \ |
300 | FXP_RXBUFSIZE((sc), (m)), (ops)) |
301 | |
302 | #define FXP_MTORFA(m) (struct fxp_rfa *)((m)->m_ext.ext_buf + \ |
303 | RFA_ALIGNMENT_FUDGE) |
304 | |
305 | #define FXP_INIT_RFABUF(sc, m) \ |
306 | do { \ |
307 | bus_dmamap_t __rxmap = M_GETCTX((m), bus_dmamap_t); \ |
308 | struct mbuf *__p_m; \ |
309 | struct fxp_rfa *__rfa, *__p_rfa; \ |
310 | uint32_t __v; \ |
311 | \ |
312 | (m)->m_data = (m)->m_ext.ext_buf + (sc)->sc_rfa_size + \ |
313 | RFA_ALIGNMENT_FUDGE; \ |
314 | \ |
315 | __rfa = FXP_MTORFA((m)); \ |
316 | __rfa->size = htole16(FXP_RXBUFSIZE((sc), (m))); \ |
317 | /* BIG_ENDIAN: no need to swap to store 0 */ \ |
318 | __rfa->rfa_status = 0; \ |
319 | __rfa->rfa_control = \ |
320 | htole16(FXP_RFA_CONTROL_EL | FXP_RFA_CONTROL_S); \ |
321 | /* BIG_ENDIAN: no need to swap to store 0 */ \ |
322 | __rfa->actual_size = 0; \ |
323 | \ |
324 | /* NOTE: the RFA is misaligned, so we must copy. */ \ |
325 | /* BIG_ENDIAN: no need to swap to store 0xffffffff */ \ |
326 | __v = 0xffffffff; \ |
327 | memcpy(__UNVOLATILE(&__rfa->link_addr), &__v, sizeof(__v)); \ |
328 | memcpy(__UNVOLATILE(&__rfa->rbd_addr), &__v, sizeof(__v)); \ |
329 | \ |
330 | FXP_RFASYNC((sc), (m), \ |
331 | BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE); \ |
332 | \ |
333 | FXP_RXBUFSYNC((sc), (m), BUS_DMASYNC_PREREAD); \ |
334 | \ |
335 | if ((__p_m = (sc)->sc_rxq.ifq_tail) != NULL) { \ |
336 | __p_rfa = FXP_MTORFA(__p_m); \ |
337 | __v = htole32(__rxmap->dm_segs[0].ds_addr + \ |
338 | RFA_ALIGNMENT_FUDGE); \ |
339 | FXP_RFASYNC((sc), __p_m, \ |
340 | BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE); \ |
341 | memcpy(__UNVOLATILE(&__p_rfa->link_addr), &__v, \ |
342 | sizeof(__v)); \ |
343 | __p_rfa->rfa_control &= htole16(~(FXP_RFA_CONTROL_EL| \ |
344 | FXP_RFA_CONTROL_S)); \ |
345 | FXP_RFASYNC((sc), __p_m, \ |
346 | BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE); \ |
347 | } \ |
348 | IF_ENQUEUE(&(sc)->sc_rxq, (m)); \ |
349 | } while (0) |
350 | |
351 | /* Macros to ease CSR access. */ |
352 | #define CSR_READ_1(sc, reg) \ |
353 | bus_space_read_1((sc)->sc_st, (sc)->sc_sh, (reg)) |
354 | #define CSR_READ_2(sc, reg) \ |
355 | bus_space_read_2((sc)->sc_st, (sc)->sc_sh, (reg)) |
356 | #define CSR_READ_4(sc, reg) \ |
357 | bus_space_read_4((sc)->sc_st, (sc)->sc_sh, (reg)) |
358 | #define CSR_WRITE_1(sc, reg, val) \ |
359 | bus_space_write_1((sc)->sc_st, (sc)->sc_sh, (reg), (val)) |
360 | #define CSR_WRITE_2(sc, reg, val) \ |
361 | bus_space_write_2((sc)->sc_st, (sc)->sc_sh, (reg), (val)) |
362 | #define CSR_WRITE_4(sc, reg, val) \ |
363 | bus_space_write_4((sc)->sc_st, (sc)->sc_sh, (reg), (val)) |
364 | |
365 | void fxp_attach(struct fxp_softc *); |
366 | int fxp_activate(device_t, enum devact); |
367 | int fxp_detach(struct fxp_softc *, int); |
368 | int fxp_intr(void *); |
369 | |
370 | int fxp_enable(struct fxp_softc*); |
371 | void fxp_disable(struct fxp_softc*); |
372 | |