Annotation of sys/dev/pci/if_casvar.h, Revision 1.1.1.1
1.1 nbrk 1: /* $OpenBSD: if_casvar.h,v 1.4 2007/04/15 16:31:30 kettenis Exp $ */
2:
3: /*
4: *
5: * Copyright (C) 2007 Mark Kettenis.
6: * Copyright (C) 2001 Eduardo Horvath.
7: * All rights reserved.
8: *
9: *
10: * Redistribution and use in source and binary forms, with or without
11: * modification, are permitted provided that the following conditions
12: * are met:
13: * 1. Redistributions of source code must retain the above copyright
14: * notice, this list of conditions and the following disclaimer.
15: * 2. Redistributions in binary form must reproduce the above copyright
16: * notice, this list of conditions and the following disclaimer in the
17: * documentation and/or other materials provided with the distribution.
18: *
19: * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND
20: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22: * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE
23: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29: * SUCH DAMAGE.
30: *
31: */
32:
33: #ifndef _IF_CASVAR_H
34: #define _IF_CASVAR_H
35:
36: #include <sys/queue.h>
37: #include <sys/timeout.h>
38:
39: /*
40: * Misc. definitions for Sun Cassini ethernet controllers.
41: */
42:
43: /*
44: * Preferred page size. Cassini has a configurable page size, but
45: * needs at least 8k to handle jumbo frames. This happens to be the
46: * default anyway.
47: */
48: #define CAS_PAGE_SIZE 8192
49:
50: /*
51: * Transmit descriptor ring size. This is arbitrary, but allocate
52: * enough descriptors for 64 pending transmissions and 16 segments
53: * per packet.
54: */
55: #define CAS_NTXSEGS 16
56:
57: #define CAS_TXQUEUELEN 64
58: #define CAS_NTXDESC (CAS_TXQUEUELEN * CAS_NTXSEGS)
59: #define CAS_NTXDESC_MASK (CAS_NTXDESC - 1)
60: #define CAS_NEXTTX(x) ((x + 1) & CAS_NTXDESC_MASK)
61:
62: struct cas_sxd {
63: struct mbuf *sd_mbuf;
64: bus_dmamap_t sd_map;
65: };
66:
67: /*
68: * Receive descriptor ring size. We have one Rx buffer per incoming
69: * packet, so this logic is a little simpler.
70: */
71: #define CAS_NRXDESC 128
72: #define CAS_NRXDESC_MASK (CAS_NRXDESC - 1)
73:
74: /*
75: * Receive completion ring size.
76: */
77: #define CAS_NRXCOMP 256
78: #define CAS_NRXCOMP_MASK (CAS_NRXCOMP - 1)
79: #define CAS_NEXTRX(x) ((x + 1) & CAS_NRXCOMP_MASK)
80:
81: /*
82: * Control structures are DMA'd to the Cassini chip. We allocate them in
83: * a single clump that maps to a single DMA segment to make several things
84: * easier.
85: */
86: struct cas_control_data {
87: /*
88: * The transmit descriptors.
89: */
90: struct cas_desc ccd_txdescs[CAS_NTXDESC];
91:
92: /*
93: * The receive completions.
94: */
95: struct cas_comp ccd_rxcomps[CAS_NRXCOMP];
96:
97: /*
98: * The receive descriptors.
99: */
100: struct cas_desc ccd_rxdescs[CAS_NRXDESC];
101: };
102:
103: #define CAS_CDOFF(x) offsetof(struct cas_control_data, x)
104: #define CAS_CDTXOFF(x) CAS_CDOFF(ccd_txdescs[(x)])
105: #define CAS_CDRXOFF(x) CAS_CDOFF(ccd_rxdescs[(x)])
106: #define CAS_CDRXCOFF(x) CAS_CDOFF(ccd_rxcomps[(x)])
107:
108: /*
109: * Software state for receive jobs.
110: */
111: struct cas_rxsoft {
112: bus_dmamap_t rxs_dmamap; /* our DMA map */
113: bus_dma_segment_t rxs_dmaseg; /* our DMA segment */
114: caddr_t rxs_kva;
115: };
116:
117: /*
118: * Software state per device.
119: */
120: struct cas_softc {
121: struct device sc_dev; /* generic device information */
122: struct arpcom sc_arpcom; /* ethernet common data */
123: struct mii_data sc_mii; /* MII media control */
124: #define sc_media sc_mii.mii_media/* shorthand */
125: struct timeout sc_tick_ch; /* tick callout */
126:
127: bus_space_tag_t sc_memt;
128: bus_space_handle_t sc_memh;
129: void *sc_ih;
130:
131: bus_dma_tag_t sc_dmatag; /* bus dma tag */
132: bus_dmamap_t sc_dmamap; /* bus dma handle */
133: int sc_burst; /* DVMA burst size in effect */
134: int sc_phys[2]; /* MII instance -> PHY map */
135:
136: int sc_if_flags;
137:
138: int sc_mif_config; /* Selected MII reg setting */
139:
140: /*
141: * Ring buffer DMA stuff.
142: */
143: bus_dma_segment_t sc_cdseg; /* control data memory */
144: int sc_cdnseg; /* number of segments */
145: bus_dmamap_t sc_cddmamap; /* control data DMA map */
146: #define sc_cddma sc_cddmamap->dm_segs[0].ds_addr
147:
148: /*
149: * Software state for transmit and receive descriptors.
150: */
151: struct cas_sxd sc_txd[CAS_NTXDESC];
152: u_int32_t sc_tx_cnt, sc_tx_prod, sc_tx_cons;
153:
154: struct cas_rxsoft sc_rxsoft[CAS_NRXDESC];
155:
156: /*
157: * Control data structures.
158: */
159: struct cas_control_data *sc_control_data;
160: #define sc_txdescs sc_control_data->ccd_txdescs
161: #define sc_rxdescs sc_control_data->ccd_rxdescs
162: #define sc_rxcomps sc_control_data->ccd_rxcomps
163:
164: int sc_rxptr; /* next ready RX descriptor/descsoft */
165: int sc_rxfifosize;
166: int sc_rxdptr;
167:
168: /* ========== */
169: int sc_inited;
170: int sc_debug;
171: void *sc_sh; /* shutdownhook cookie */
172: };
173:
174: #define CAS_DMA_READ(v) letoh64(v)
175: #define CAS_DMA_WRITE(v) htole64(v)
176:
177: /*
178: * This macro returns the current media entry for *non-MII* media.
179: */
180: #define CAS_CURRENT_MEDIA(sc) \
181: (IFM_SUBTYPE((sc)->sc_mii.mii_media.ifm_cur->ifm_media) != IFM_AUTO ? \
182: (sc)->sc_mii.mii_media.ifm_cur : (sc)->sc_nway_active)
183:
184: /*
185: * This macro determines if a change to media-related OPMODE bits requires
186: * a chip reset.
187: */
188: #define CAS_MEDIA_NEEDSRESET(sc, newbits) \
189: (((sc)->sc_opmode & OPMODE_MEDIA_BITS) != \
190: ((newbits) & OPMODE_MEDIA_BITS))
191:
192: #define CAS_CDTXADDR(sc, x) ((sc)->sc_cddma + CAS_CDTXOFF((x)))
193: #define CAS_CDRXADDR(sc, x) ((sc)->sc_cddma + CAS_CDRXOFF((x)))
194: #define CAS_CDRXCADDR(sc, x) ((sc)->sc_cddma + CAS_CDRXCOFF((x)))
195:
196: #define CAS_CDTXSYNC(sc, x, n, ops) \
197: do { \
198: int __x, __n; \
199: \
200: __x = (x); \
201: __n = (n); \
202: \
203: /* If it will wrap around, sync to the end of the ring. */ \
204: if ((__x + __n) > CAS_NTXDESC) { \
205: bus_dmamap_sync((sc)->sc_dmatag, (sc)->sc_cddmamap, \
206: CAS_CDTXOFF(__x), sizeof(struct cas_desc) * \
207: (CAS_NTXDESC - __x), (ops)); \
208: __n -= (CAS_NTXDESC - __x); \
209: __x = 0; \
210: } \
211: \
212: /* Now sync whatever is left. */ \
213: bus_dmamap_sync((sc)->sc_dmatag, (sc)->sc_cddmamap, \
214: CAS_CDTXOFF(__x), sizeof(struct cas_desc) * __n, (ops)); \
215: } while (0)
216:
217: #define CAS_CDRXSYNC(sc, x, ops) \
218: bus_dmamap_sync((sc)->sc_dmatag, (sc)->sc_cddmamap, \
219: CAS_CDRXOFF((x)), sizeof(struct cas_desc), (ops))
220:
221: #define CAS_CDRXCSYNC(sc, x, ops) \
222: bus_dmamap_sync((sc)->sc_dmatag, (sc)->sc_cddmamap, \
223: CAS_CDRXCOFF((x)), sizeof(struct cas_desc), (ops))
224:
225: #define CAS_INIT_RXDESC(sc, d, s) \
226: do { \
227: struct cas_rxsoft *__rxs = &sc->sc_rxsoft[(s)]; \
228: struct cas_desc *__rxd = &sc->sc_rxdescs[(d)]; \
229: \
230: __rxd->cd_addr = \
231: CAS_DMA_WRITE(__rxs->rxs_dmamap->dm_segs[0].ds_addr); \
232: __rxd->cd_flags = \
233: CAS_DMA_WRITE((s)); \
234: CAS_CDRXSYNC((sc), (d), BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE); \
235: } while (0)
236:
237: #endif
CVSweb