1 /*        $NetBSD: dp83932var.h,v 1.13 2021/02/20 09:36:31 rin Exp $  */
2 
3 /*-
4  * Copyright (c) 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.
9  *
10  * Redistribution and use in source and binary forms, with or without
11  * modification, are permitted provided that the following conditions
12  * are met:
13  * 1. Redistributions of source code must retain the above copyright
14  *    notice, this list of conditions and the following disclaimer.
15  * 2. Redistributions in binary form must reproduce the above copyright
16  *    notice, this list of conditions and the following disclaimer in the
17  *    documentation and/or other materials provided with the distribution.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29  * POSSIBILITY OF SUCH DAMAGE.
30  */
31 
32 #ifndef _DEV_IC_DP83932VAR_H_
33 #define   _DEV_IC_DP83932VAR_H_
34 
35 /*
36  * Data structure definitions for the National Semiconductor DP83932
37  * Systems-Oriented Network Interface Controller (SONIC).
38  */
39 
40 /*
41  * NOTE: The control data for the SONIC must not cross a 64k boundary,
42  * so we have to be careful about how we size things.
43  *
44  * Also, since the SONIC is only a 10Mb/s chip, and systems on which
45  * it is present tend to be low on memory, we try to keep the data
46  * structure sizes small.
47  */
48 
49 /*
50  * Transmit descriptor list size.
51  */
52 #define   SONIC_NTXDESC                 32
53 #define   SONIC_NTXDESC_MASK  (SONIC_NTXDESC - 1)
54 #define   SONIC_NEXTTX(x)               (((x) + 1) & SONIC_NTXDESC_MASK)
55 
56 /*
57  * Receive descriptor list size.
58  */
59 #define   SONIC_NRXDESC                 32
60 #define   SONIC_NRXDESC_MASK  (SONIC_NRXDESC - 1)
61 #define   SONIC_NEXTRX(x)               (((x) + 1) & SONIC_NRXDESC_MASK)
62 #define   SONIC_PREVRX(x)               (((x) - 1) & SONIC_NRXDESC_MASK)
63 #define   SONIC_RXSEQ_TO_DESC(x)        ((x) & SONIC_NRXDESC_MASK)
64 
65 /*
66  * Number of CAM entries.
67  */
68 #define   SONIC_NCAMENT                 16
69 
70 /*
71  * Control structures are DMA'd to the SONIC chip.  We allocate them in
72  * a single clump that maps to a single DMA segment to make several things
73  * easier.
74  */
75 struct sonic_control_data16 {
76           /*
77            * The transmit descriptors.
78            */
79           struct sonic_tda16 scd_txdescs[SONIC_NTXDESC];
80 
81           /*
82            * The receive descriptors.
83            */
84           struct sonic_rda16 scd_rxdescs[SONIC_NRXDESC];
85 
86           /*
87            * The receive resource descriptors.
88            */
89           struct sonic_rra16 scd_rxbufs[SONIC_NRXDESC];
90 
91           /*
92            * The CAM descriptors.
93            */
94           struct sonic_cda16 scd_cam[SONIC_NCAMENT];
95           uint16_t scd_camenable;
96 };
97 
98 #define   SONIC_CDOFF16(x)    offsetof(struct sonic_control_data16, x)
99 #define   SONIC_CDTXOFF16(x)  SONIC_CDOFF16(scd_txdescs[(x)])
100 #define   SONIC_CDRXOFF16(x)  SONIC_CDOFF16(scd_rxdescs[(x)])
101 #define   SONIC_CDRROFF16(x)  SONIC_CDOFF16(scd_rxbufs[(x)])
102 #define   SONIC_CDCAMOFF16    SONIC_CDOFF16(scd_cam)
103 #define   SONIC_CDCAMSIZE16   \
104           (sizeof(struct sonic_cda16) * SONIC_NCAMENT + sizeof(uint16_t))
105 
106 struct sonic_control_data32 {
107           /*
108            * The transmit descriptors.
109            */
110           struct sonic_tda32 scd_txdescs[SONIC_NTXDESC];
111 
112           /*
113            * The receive descriptors.
114            */
115           struct sonic_rda32 scd_rxdescs[SONIC_NRXDESC];
116 
117           /*
118            * The receive resource descriptors.
119            */
120           struct sonic_rra32 scd_rxbufs[SONIC_NRXDESC];
121 
122           /*
123            * The CAM descriptors.
124            */
125           struct sonic_cda32 scd_cam[SONIC_NCAMENT];
126           uint32_t scd_camenable;
127 };
128 
129 #define   SONIC_CDOFF32(x)    offsetof(struct sonic_control_data32, x)
130 #define   SONIC_CDTXOFF32(x)  SONIC_CDOFF32(scd_txdescs[(x)])
131 #define   SONIC_CDRXOFF32(x)  SONIC_CDOFF32(scd_rxdescs[(x)])
132 #define   SONIC_CDRROFF32(x)  SONIC_CDOFF32(scd_rxbufs[(x)])
133 #define   SONIC_CDCAMOFF32    SONIC_CDOFF32(scd_cam)
134 #define   SONIC_CDCAMSIZE32   \
135           (sizeof(struct sonic_cda32) * SONIC_NCAMENT + sizeof(uint32_t))
136 
137 /*
138  * Software state for transmit and receive descriptors.
139  */
140 struct sonic_descsoft {
141           struct mbuf *ds_mbuf;                   /* head of mbuf chain */
142           bus_dmamap_t ds_dmamap;                 /* our DMA map */
143 };
144 
145 /*
146  * Software state per device.
147  */
148 struct sonic_softc {
149           device_t sc_dev;              /* generic device information */
150           bus_space_tag_t sc_st;                  /* bus space tag */
151           bus_space_handle_t sc_sh;     /* bus space handle */
152           bus_dma_tag_t sc_dmat;                  /* bus DMA tag */
153           struct ethercom sc_ethercom;  /* ethernet common data */
154 
155           int sc_32bit;                           /* use 32-bit mode */
156           int sc_bigendian;             /* BMODE -> Vcc */
157 
158           /* Our register map. */
159           bus_addr_t sc_regmap[SONIC_NREGS];
160 
161           bus_dmamap_t sc_cddmamap;     /* control data DMA map */
162 #define   sc_cddma  sc_cddmamap->dm_segs[0].ds_addr
163           bus_dmamap_t sc_nulldmamap;   /* DMA map for the pad buffer */
164 #define sc_nulldma     sc_nulldmamap->dm_segs[0].ds_addr
165 
166           /*
167            * Software state for transmit and receive descriptors.
168            */
169           struct sonic_descsoft sc_txsoft[SONIC_NTXDESC];
170           struct sonic_descsoft sc_rxsoft[SONIC_NRXDESC];
171 
172           /*
173            * Control data structures.
174            */
175           union {
176                     struct sonic_control_data16 *cdun_16;
177                     struct sonic_control_data32 *cdun_32;
178           } sc_cdun;
179 #define   sc_cdata16          sc_cdun.cdun_16
180 #define   sc_cdata32          sc_cdun.cdun_32
181 
182 #define   sc_tda16  sc_cdun.cdun_16->scd_txdescs
183 #define   sc_rda16  sc_cdun.cdun_16->scd_rxdescs
184 #define   sc_rra16  sc_cdun.cdun_16->scd_rxbufs
185 #define   sc_cda16  sc_cdun.cdun_16->scd_cam
186 #define   sc_cdaenable16      sc_cdun.cdun_16->scd_camenable
187 
188 #define   sc_tda32  sc_cdun.cdun_32->scd_txdescs
189 #define   sc_rda32  sc_cdun.cdun_32->scd_rxdescs
190 #define   sc_rra32  sc_cdun.cdun_32->scd_rxbufs
191 #define   sc_cda32  sc_cdun.cdun_32->scd_cam
192 #define   sc_cdaenable32      sc_cdun.cdun_32->scd_camenable
193 
194           int       sc_txpending;                 /* number of Tx requests pending */
195           int       sc_txdirty;                   /* first dirty Tx descriptor */
196           int       sc_txlast;                    /* last used Tx descriptor */
197 
198           int       sc_rxptr;           /* next ready Rx descriptor */
199 
200           uint16_t sc_imr;              /* prototype IMR */
201           uint16_t sc_dcr;              /* prototype DCR */
202           uint16_t sc_dcr2;             /* prototype DCR2 */
203 
204           krndsource_t sc_rndsource;    /* random source */
205 };
206 
207 #define   CSR_READ(sc, reg)                                                     \
208           bus_space_read_2((sc)->sc_st, (sc)->sc_sh,                            \
209               (sc)->sc_regmap[(reg)])
210 
211 #define   CSR_WRITE(sc, reg, val)                                                         \
212           bus_space_write_2((sc)->sc_st, (sc)->sc_sh,                           \
213               (sc)->sc_regmap[(reg)], (val))
214 
215 #define   SONIC_CDTXADDR16(sc, x)                                                         \
216           ((sc)->sc_cddma + SONIC_CDTXOFF16((x)))
217 
218 #define   SONIC_CDTXADDR32(sc, x)                                                         \
219           ((sc)->sc_cddma + SONIC_CDTXOFF32((x)))
220 
221 #define   SONIC_CDTXADDR(sc, x)                                                           \
222           ((sc)->sc_32bit ? SONIC_CDTXADDR32((sc), (x)) :                       \
223               SONIC_CDTXADDR16((sc), (x)))
224 
225 #define   SONIC_CDRXADDR16(sc, x)                                                         \
226           ((sc)->sc_cddma + SONIC_CDRXOFF16((x)))
227 
228 #define   SONIC_CDRXADDR32(sc, x)                                                         \
229           ((sc)->sc_cddma + SONIC_CDRXOFF32((x)))
230 
231 #define   SONIC_CDRXADDR(sc, x)                                                           \
232           ((sc)->sc_32bit ? SONIC_CDRXADDR32((sc), (x)) :                       \
233               SONIC_CDRXADDR16((sc), (x)))
234 
235 #define   SONIC_CDRRADDR(sc, x)                                                           \
236           ((sc)->sc_cddma +                                                     \
237            ((sc)->sc_32bit ? SONIC_CDRROFF32((x)) : SONIC_CDRROFF16((x))))
238 
239 #define   SONIC_CDCAMADDR(sc)                                                   \
240           ((sc)->sc_cddma +                                                     \
241            ((sc)->sc_32bit ? SONIC_CDCAMOFF32 : SONIC_CDCAMOFF16))
242 
243 #define   SONIC_CDTXSYNC16(sc, x, ops)                                          \
244           bus_dmamap_sync((sc)->sc_dmat, (sc)->sc_cddmamap,           \
245               SONIC_CDTXOFF16((x)), sizeof(struct sonic_tda16), (ops))
246 
247 #define   SONIC_CDTXSYNC32(sc, x, ops)                                          \
248           bus_dmamap_sync((sc)->sc_dmat, (sc)->sc_cddmamap,           \
249               SONIC_CDTXOFF32((x)), sizeof(struct sonic_tda32), (ops))
250 
251 #define   SONIC_CDRXSYNC16(sc, x, ops)                                          \
252           bus_dmamap_sync((sc)->sc_dmat, (sc)->sc_cddmamap,           \
253               SONIC_CDRXOFF16((x)), sizeof(struct sonic_rda16), (ops))
254 
255 #define   SONIC_CDRXSYNC32(sc, x, ops)                                          \
256           bus_dmamap_sync((sc)->sc_dmat, (sc)->sc_cddmamap,           \
257               SONIC_CDRXOFF32((x)), sizeof(struct sonic_rda32), (ops))
258 
259 #define   SONIC_CDRRSYNC16(sc, x, ops)                                          \
260           bus_dmamap_sync((sc)->sc_dmat, (sc)->sc_cddmamap,           \
261               SONIC_CDRROFF16((x)), sizeof(struct sonic_rra16), (ops))
262 
263 #define   SONIC_CDRRSYNC32(sc, x, ops)                                          \
264           bus_dmamap_sync((sc)->sc_dmat, (sc)->sc_cddmamap,           \
265               SONIC_CDRROFF32((x)), sizeof(struct sonic_rra32), (ops))
266 
267 #define   SONIC_CDCAMSYNC(sc, ops)                                              \
268 do {                                                                                      \
269           if ((sc)->sc_32bit)                                                   \
270                     bus_dmamap_sync((sc)->sc_dmat, (sc)->sc_cddmamap, \
271                         SONIC_CDCAMOFF32, SONIC_CDCAMSIZE32,                    \
272                         (ops));                                                           \
273           else                                                                            \
274                     bus_dmamap_sync((sc)->sc_dmat, (sc)->sc_cddmamap, \
275                         SONIC_CDCAMOFF16, SONIC_CDCAMSIZE16,                    \
276                         (ops));                                                           \
277 } while (/*CONSTCOND*/0)
278 
279 #define   SONIC_INIT_RXDESC(sc, x)                                              \
280 do {                                                                                      \
281           struct sonic_descsoft *__ds = &(sc)->sc_rxsoft[(x)];                  \
282           struct mbuf *__m = __ds->ds_mbuf;                                     \
283                                                                                           \
284           if ((sc)->sc_32bit) {                                                           \
285                     /*                                                                    \
286                      * Unfortuantely, in 32-bit mode, the Rx buffer must        \
287                      * be 32-bit aligned.                                                 \
288                      */                                                                   \
289                     struct sonic_rda32 *__rda = &(sc)->sc_rda32[(x)]; \
290                     struct sonic_rda32 *__prda =                                \
291                         &(sc)->sc_rda32[SONIC_PREVRX((x))];                     \
292                     struct sonic_rra32 *__rra = &(sc)->sc_rra32[(x)]; \
293                                                                                           \
294                     __m->m_data = __m->m_ext.ext_buf;                           \
295                                                                                           \
296                     __rra->rra_ptr1 =                                           \
297                         __ds->ds_dmamap->dm_segs[0].ds_addr >> 16;              \
298                     __rra->rra_ptr0 =                                           \
299                         __ds->ds_dmamap->dm_segs[0].ds_addr & 0xffff; \
300                     __rra->rra_wc1 = 0;                                         \
301                     __rra->rra_wc0 = (ETHER_MAX_LEN + 6) / 2;                   \
302                                                                                           \
303                     __rda->rda_link =                                           \
304                         (SONIC_CDRXADDR32((sc), SONIC_NEXTRX((x))) & 0xffff) |\
305                         RDA_LINK_EOL;                                           \
306                     __rda->rda_inuse = 1;                                                 \
307                                                                                           \
308                     __prda->rda_link = SONIC_CDRXADDR32((sc), (x));             \
309                                                                                           \
310                     SONIC_CDRRSYNC32((sc), (x), BUS_DMASYNC_PREWRITE);          \
311                     SONIC_CDRXSYNC32((sc), (x),                                 \
312                         BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);              \
313                     SONIC_CDRXSYNC32((sc), SONIC_PREVRX(x),                     \
314                         BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);              \
315           } else {                                                              \
316                     /*                                                                    \
317                      * In 16-bit mode, we scoot the packet forward 2 bytes      \
318                      * so that the payload after the Ethernet header is         \
319                      * suitably aligned.                                                  \
320                      */                                                                   \
321                     struct sonic_rda16 *__rda = &(sc)->sc_rda16[(x)]; \
322                     struct sonic_rda16 *__prda =                                \
323                         &(sc)->sc_rda16[SONIC_PREVRX((x))];                     \
324                     struct sonic_rra16 *__rra = &(sc)->sc_rra16[(x)]; \
325                                                                                           \
326                     __m->m_data = __m->m_ext.ext_buf + 2;                       \
327                                                                                           \
328                     __rra->rra_ptr1 =                                           \
329                         __ds->ds_dmamap->dm_segs[0].ds_addr >> 16;              \
330                     __rra->rra_ptr0 =                                           \
331                         (__ds->ds_dmamap->dm_segs[0].ds_addr + 2) & 0xffff;     \
332                     __rra->rra_wc1 = 0;                                         \
333                     __rra->rra_wc0 = (ETHER_MAX_LEN + 2) / 2;                   \
334                                                                                           \
335                     __rda->rda_link =                                           \
336                         (SONIC_CDRXADDR16((sc), SONIC_NEXTRX((x))) & 0xffff) |\
337                         RDA_LINK_EOL;                                           \
338                     __rda->rda_inuse = 1;                                                 \
339                                                                                           \
340                     __prda->rda_link = SONIC_CDRXADDR16((sc), (x));             \
341                                                                                           \
342                     SONIC_CDRRSYNC16((sc), (x), BUS_DMASYNC_PREWRITE);          \
343                     SONIC_CDRXSYNC16((sc), (x),                                 \
344                         BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);              \
345                     SONIC_CDRXSYNC16((sc), SONIC_PREVRX(x),                     \
346                         BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);              \
347           }                                                                               \
348 } while (/*CONSTCOND*/0)
349 
350 static __inline uint16_t __unused
htosonic16(struct sonic_softc * sc,uint16_t val)351 htosonic16(struct sonic_softc *sc, uint16_t val)
352 {
353 
354           if (sc->sc_bigendian)
355                     return (htobe16(val));
356           return (htole16(val));
357 }
358 
359 static __inline uint16_t __unused
sonic16toh(struct sonic_softc * sc,uint16_t val)360 sonic16toh(struct sonic_softc *sc, uint16_t val)
361 {
362 
363           if (sc->sc_bigendian)
364                     return (be16toh(val));
365           return (le16toh(val));
366 }
367 
368 static __inline uint32_t __unused
htosonic32(struct sonic_softc * sc,uint32_t val)369 htosonic32(struct sonic_softc *sc, uint32_t val)
370 {
371 
372           if (sc->sc_bigendian)
373                     return (htobe32(val));
374           return (htole32(val));
375 }
376 
377 static __inline uint32_t __unused
sonic32toh(struct sonic_softc * sc,uint32_t val)378 sonic32toh(struct sonic_softc *sc, uint32_t val)
379 {
380 
381           if (sc->sc_bigendian)
382                     return (be32toh(val));
383           return (le32toh(val));
384 }
385 
386 #ifdef _KERNEL
387 void      sonic_attach(struct sonic_softc *, const uint8_t *);
388 int       sonic_intr(void *);
389 #endif /* _KERNEL */
390 
391 #endif /* _DEV_IC_DP83932VAR_H_ */
392