xref: /netbsd-src/sys/arch/sgimips/hpc/sqvar.h (revision 445478ce67313306a14029085ead88fe078a0ccb)
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