1*445478ceSriastradh /* $NetBSD: sqvar.h,v 1.15 2015/04/13 21:18:42 riastradh Exp $ */
25885656eSthorpej
35885656eSthorpej /*
45885656eSthorpej * Copyright (c) 2001 Rafal K. Boni
55885656eSthorpej * All rights reserved.
65885656eSthorpej *
75885656eSthorpej * Redistribution and use in source and binary forms, with or without
85885656eSthorpej * modification, are permitted provided that the following conditions
95885656eSthorpej * are met:
105885656eSthorpej * 1. Redistributions of source code must retain the above copyright
115885656eSthorpej * notice, this list of conditions and the following disclaimer.
125885656eSthorpej * 2. Redistributions in binary form must reproduce the above copyright
135885656eSthorpej * notice, this list of conditions and the following disclaimer in the
145885656eSthorpej * documentation and/or other materials provided with the distribution.
155885656eSthorpej * 3. The name of the author may not be used to endorse or promote products
165885656eSthorpej * derived from this software without specific prior written permission.
175885656eSthorpej *
185885656eSthorpej * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
195885656eSthorpej * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
205885656eSthorpej * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
215885656eSthorpej * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
225885656eSthorpej * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
235885656eSthorpej * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
245885656eSthorpej * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
255885656eSthorpej * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
265885656eSthorpej * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
275885656eSthorpej * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
285885656eSthorpej */
295885656eSthorpej
305885656eSthorpej #ifndef _ARCH_SGIMIPS_HPC_SQVAR_H_
315885656eSthorpej #define _ARCH_SGIMIPS_HPC_SQVAR_H_
325885656eSthorpej
335885656eSthorpej #include <sys/queue.h>
345885656eSthorpej #include <sys/callout.h>
355885656eSthorpej
36*445478ceSriastradh #include <sys/rndsource.h>
375885656eSthorpej
385885656eSthorpej #include <sgimips/hpc/hpcvar.h>
395885656eSthorpej #include <sgimips/hpc/hpcreg.h>
405885656eSthorpej
415885656eSthorpej /* Note, these must be powers of two for the magic NEXT/PREV macros to work */
425cf01464Srumble #define SQ_NRXDESC 64
435cf01464Srumble #define SQ_NTXDESC 64
445885656eSthorpej
455885656eSthorpej #define SQ_NRXDESC_MASK (SQ_NRXDESC - 1)
465885656eSthorpej #define SQ_NEXTRX(x) ((x + 1) & SQ_NRXDESC_MASK)
475885656eSthorpej #define SQ_PREVRX(x) ((x - 1) & SQ_NRXDESC_MASK)
485885656eSthorpej
495885656eSthorpej #define SQ_NTXDESC_MASK (SQ_NTXDESC - 1)
505885656eSthorpej #define SQ_NEXTTX(x) ((x + 1) & SQ_NTXDESC_MASK)
515885656eSthorpej #define SQ_PREVTX(x) ((x - 1) & SQ_NTXDESC_MASK)
525885656eSthorpej
535885656eSthorpej /*
545885656eSthorpej * We pack all DMA control structures into one container so we can alloc just
555885656eSthorpej * one chunk of DMA-safe memory and pack them into it. Otherwise, we'd have to
565885656eSthorpej * allocate a page for each descriptor, since the bus_dmamem_alloc() interface
575885656eSthorpej * does not allow us to allocate smaller chunks.
585885656eSthorpej */
595885656eSthorpej struct sq_control {
605885656eSthorpej /* Receive descriptors */
615885656eSthorpej struct hpc_dma_desc rx_desc[SQ_NRXDESC];
625885656eSthorpej
635885656eSthorpej /* Transmit descriptors */
645885656eSthorpej struct hpc_dma_desc tx_desc[SQ_NTXDESC];
655885656eSthorpej };
665885656eSthorpej
675885656eSthorpej #define SQ_CDOFF(x) offsetof(struct sq_control, x)
685885656eSthorpej #define SQ_CDTXOFF(x) SQ_CDOFF(tx_desc[(x)])
695885656eSthorpej #define SQ_CDRXOFF(x) SQ_CDOFF(rx_desc[(x)])
705885656eSthorpej
710859a760Sthorpej #define SQ_TYPE_8003 0
720859a760Sthorpej #define SQ_TYPE_80C03 1
730859a760Sthorpej
74e8374114Srumble /* Trace Actions */
75e8374114Srumble #define SQ_RESET 1
76e8374114Srumble #define SQ_ADD_TO_DMA 2
77e8374114Srumble #define SQ_START_DMA 3
78e8374114Srumble #define SQ_DONE_DMA 4
79e8374114Srumble #define SQ_RESTART_DMA 5
80e8374114Srumble #define SQ_TXINTR_ENTER 6
81e8374114Srumble #define SQ_TXINTR_EXIT 7
82e8374114Srumble #define SQ_TXINTR_BUSY 8
83e8374114Srumble #define SQ_IOCTL 9
84e8374114Srumble #define SQ_ENQUEUE 10
85e8374114Srumble
86e8374114Srumble struct sq_action_trace {
87e8374114Srumble int action;
88e8374114Srumble int line;
89e8374114Srumble int bufno;
90e8374114Srumble int status;
91e8374114Srumble int freebuf;
92e8374114Srumble };
93e8374114Srumble
94e8374114Srumble #define SQ_TRACEBUF_SIZE 100
95e8374114Srumble
96e8374114Srumble #define SQ_TRACE(act, sc, buf, stat) do { \
97e8374114Srumble (sc)->sq_trace[(sc)->sq_trace_idx].action = (act); \
98e8374114Srumble (sc)->sq_trace[(sc)->sq_trace_idx].line = __LINE__; \
99e8374114Srumble (sc)->sq_trace[(sc)->sq_trace_idx].bufno = (buf); \
100e8374114Srumble (sc)->sq_trace[(sc)->sq_trace_idx].status = (stat); \
101e8374114Srumble (sc)->sq_trace[(sc)->sq_trace_idx].freebuf = (sc)->sc_nfreetx; \
102e8374114Srumble if (++(sc)->sq_trace_idx == SQ_TRACEBUF_SIZE) \
103e8374114Srumble (sc)->sq_trace_idx = 0; \
104fde2c776Stsutsui } while (/* CONSTCOND */0)
105e8374114Srumble
1065885656eSthorpej struct sq_softc {
10758b06e5fStsutsui device_t sc_dev;
1085885656eSthorpej
1095885656eSthorpej /* HPC registers */
1105885656eSthorpej bus_space_tag_t sc_hpct;
1115885656eSthorpej bus_space_handle_t sc_hpch;
1125885656eSthorpej
1135885656eSthorpej
1145885656eSthorpej /* HPC external ethernet registers: aka Seeq 8003 registers */
1155885656eSthorpej bus_space_tag_t sc_regt;
1165885656eSthorpej bus_space_handle_t sc_regh;
1175885656eSthorpej
1185885656eSthorpej bus_dma_tag_t sc_dmat;
1195885656eSthorpej
1205885656eSthorpej struct ethercom sc_ethercom;
121fde2c776Stsutsui uint8_t sc_enaddr[ETHER_ADDR_LEN];
1225885656eSthorpej
1230859a760Sthorpej int sc_type;
1240859a760Sthorpej
1255885656eSthorpej struct sq_control* sc_control;
1265885656eSthorpej #define sc_rxdesc sc_control->rx_desc
1275885656eSthorpej #define sc_txdesc sc_control->tx_desc
1285885656eSthorpej
1295885656eSthorpej /* DMA structures for control data (DMA RX/TX descriptors) */
1305885656eSthorpej int sc_ncdseg;
1315885656eSthorpej bus_dma_segment_t sc_cdseg;
1325885656eSthorpej bus_dmamap_t sc_cdmap;
1335885656eSthorpej #define sc_cddma sc_cdmap->dm_segs[0].ds_addr
1345885656eSthorpej
1355885656eSthorpej int sc_nextrx;
1365885656eSthorpej
1375885656eSthorpej /* DMA structures for RX packet data */
1385885656eSthorpej bus_dma_segment_t sc_rxseg[SQ_NRXDESC];
1395885656eSthorpej bus_dmamap_t sc_rxmap[SQ_NRXDESC];
1405885656eSthorpej struct mbuf* sc_rxmbuf[SQ_NRXDESC];
1415885656eSthorpej
1425885656eSthorpej int sc_nexttx;
1435885656eSthorpej int sc_prevtx;
1445885656eSthorpej int sc_nfreetx;
1455885656eSthorpej
1465885656eSthorpej /* DMA structures for TX packet data */
1475885656eSthorpej bus_dma_segment_t sc_txseg[SQ_NTXDESC];
1485885656eSthorpej bus_dmamap_t sc_txmap[SQ_NTXDESC];
1495885656eSthorpej struct mbuf* sc_txmbuf[SQ_NTXDESC];
1505885656eSthorpej
151f016e292Stsutsui uint8_t sc_rxcmd; /* prototype rxcmd */
1520859a760Sthorpej
153ab8f2fbcSrafal struct evcnt sq_intrcnt; /* count interrupts */
154ab8f2fbcSrafal
1553afd44cfStls krndsource_t rnd_source; /* random source */
156a072684cSsekiya struct hpc_values *hpc_regs; /* HPC register definitions */
157e8374114Srumble
158e8374114Srumble int sq_trace_idx;
159e8374114Srumble struct sq_action_trace sq_trace[SQ_TRACEBUF_SIZE];
1605885656eSthorpej };
1615885656eSthorpej
1625885656eSthorpej #define SQ_CDTXADDR(sc, x) ((sc)->sc_cddma + SQ_CDTXOFF((x)))
1635885656eSthorpej #define SQ_CDRXADDR(sc, x) ((sc)->sc_cddma + SQ_CDRXOFF((x)))
1645885656eSthorpej
165a072684cSsekiya static inline void
SQ_CDTXSYNC(struct sq_softc * sc,int __x,int __n,int ops)166a072684cSsekiya SQ_CDTXSYNC(struct sq_softc *sc, int __x, int __n, int ops)
167a072684cSsekiya {
168a072684cSsekiya /* If it will wrap around, sync to the end of the ring. */
169a072684cSsekiya if ((__x + __n) > SQ_NTXDESC) {
170a072684cSsekiya bus_dmamap_sync((sc)->sc_dmat, (sc)->sc_cdmap,
171a072684cSsekiya SQ_CDTXOFF(__x), sizeof(struct hpc_dma_desc) *
172a072684cSsekiya (SQ_NTXDESC - __x), (ops));
173a072684cSsekiya __n -= (SQ_NTXDESC - __x);
174a072684cSsekiya __x = 0;
175a072684cSsekiya }
176a072684cSsekiya
177a072684cSsekiya /* Now sync whatever is left. */
178a072684cSsekiya bus_dmamap_sync((sc)->sc_dmat, (sc)->sc_cdmap,
179a072684cSsekiya SQ_CDTXOFF(__x), sizeof(struct hpc_dma_desc) * __n, (ops));
180a072684cSsekiya }
1815885656eSthorpej
1825885656eSthorpej #define SQ_CDRXSYNC(sc, x, ops) \
1835885656eSthorpej bus_dmamap_sync((sc)->sc_dmat, (sc)->sc_cdmap, \
1845885656eSthorpej SQ_CDRXOFF((x)), sizeof(struct hpc_dma_desc), (ops))
1855885656eSthorpej
186a072684cSsekiya static inline void
SQ_INIT_RXDESC(struct sq_softc * sc,unsigned int x)187a072684cSsekiya SQ_INIT_RXDESC(struct sq_softc *sc, unsigned int x)
188a072684cSsekiya {
189a072684cSsekiya struct hpc_dma_desc* __rxd = &(sc)->sc_rxdesc[(x)];
190a072684cSsekiya struct mbuf *__m = (sc)->sc_rxmbuf[(x)];
191a072684cSsekiya
192a072684cSsekiya __m->m_data = __m->m_ext.ext_buf;
193a072684cSsekiya if (sc->hpc_regs->revision == 3) {
194a072684cSsekiya __rxd->hpc3_hdd_bufptr =
195a072684cSsekiya (sc)->sc_rxmap[(x)]->dm_segs[0].ds_addr;
196801f5271Srumble __rxd->hpc3_hdd_ctl = __m->m_ext.ext_size | HPC3_HDD_CTL_OWN |
197801f5271Srumble HPC3_HDD_CTL_INTR | HPC3_HDD_CTL_EOPACKET |
198801f5271Srumble ((x) == (SQ_NRXDESC - 1) ? HPC3_HDD_CTL_EOCHAIN : 0);
199a072684cSsekiya } else {
200fde2c776Stsutsui __rxd->hpc1_hdd_bufptr =
201fde2c776Stsutsui (sc)->sc_rxmap[(x)]->dm_segs[0].ds_addr |
202fde2c776Stsutsui ((x) == (SQ_NRXDESC - 1) ? HPC1_HDD_CTL_EOCHAIN : 0);
203a072684cSsekiya __rxd->hpc1_hdd_ctl = __m->m_ext.ext_size | HPC1_HDD_CTL_OWN |
204a072684cSsekiya HPC1_HDD_CTL_INTR | HPC1_HDD_CTL_EOPACKET;
205a072684cSsekiya }
206a072684cSsekiya __rxd->hdd_descptr = SQ_CDRXADDR((sc), SQ_NEXTRX((x)));
207a072684cSsekiya SQ_CDRXSYNC((sc), (x), BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
208a072684cSsekiya }
2095885656eSthorpej
2105885656eSthorpej #endif /* _ARCH_SGIMIPS_HPC_SQVAR_H_ */
211