xref: /netbsd-src/sys/arch/mips/adm5120/dev/if_admswvar.h (revision aec6f0cf2ee0e8ce1a23f9d46109cdee745ca66f)
1*aec6f0cfSskrll /* $NetBSD: if_admswvar.h,v 1.9 2022/09/29 07:00:46 skrll Exp $ */
2320845ddSdyoung 
3320845ddSdyoung /*-
4320845ddSdyoung  * Copyright (c) 2007 Ruslan Ermilov and Vsevolod Lobko.
5320845ddSdyoung  * All rights reserved.
6320845ddSdyoung  *
7320845ddSdyoung  * Redistribution and use in source and binary forms, with or
8320845ddSdyoung  * without modification, are permitted provided that the following
9320845ddSdyoung  * conditions are met:
10320845ddSdyoung  * 1. Redistributions of source code must retain the above copyright
11320845ddSdyoung  *    notice, this list of conditions and the following disclaimer.
12320845ddSdyoung  * 2. Redistributions in binary form must reproduce the above
13320845ddSdyoung  *    copyright notice, this list of conditions and the following
14320845ddSdyoung  *    disclaimer in the documentation and/or other materials provided
15320845ddSdyoung  *    with the distribution.
16320845ddSdyoung  * 3. The names of the authors may not be used to endorse or promote
17320845ddSdyoung  *    products derived from this software without specific prior
18320845ddSdyoung  *    written permission.
19320845ddSdyoung  *
20320845ddSdyoung  * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY
21320845ddSdyoung  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
22320845ddSdyoung  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
23320845ddSdyoung  * PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHORS
24320845ddSdyoung  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
25320845ddSdyoung  * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
26320845ddSdyoung  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
27320845ddSdyoung  * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28320845ddSdyoung  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
29320845ddSdyoung  * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
30320845ddSdyoung  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
31320845ddSdyoung  * OF SUCH DAMAGE.
32320845ddSdyoung  */
33320845ddSdyoung #ifndef	_IF_ADMSWVAR_H_
34320845ddSdyoung #define	_IF_ADMSWVAR_H_
35320845ddSdyoung 
3672d26a2dSrin #include <sys/cdefs.h>
37*aec6f0cfSskrll __KERNEL_RCSID(0, "$NetBSD: if_admswvar.h,v 1.9 2022/09/29 07:00:46 skrll Exp $");
3872d26a2dSrin 
39320845ddSdyoung #include <sys/param.h>
40b6185cbdSmatt #include <sys/bus.h>
41320845ddSdyoung #include <sys/callout.h>
42320845ddSdyoung #include <sys/device.h>
43b6185cbdSmatt #include <sys/endian.h>
44b6185cbdSmatt #include <sys/errno.h>
45b6185cbdSmatt #include <sys/intr.h>
46b6185cbdSmatt #include <sys/ioctl.h>
47b6185cbdSmatt #include <sys/kernel.h>
48b6185cbdSmatt #include <sys/mbuf.h>
49b6185cbdSmatt #include <sys/socket.h>
50b6185cbdSmatt #include <sys/systm.h>
51320845ddSdyoung #include <sys/wdog.h>
52320845ddSdyoung 
53320845ddSdyoung #include <uvm/uvm_extern.h>		/* for PAGE_SIZE */
54320845ddSdyoung 
55320845ddSdyoung #include <net/if.h>
56320845ddSdyoung #include <net/if_dl.h>
57320845ddSdyoung #include <net/if_media.h>
58320845ddSdyoung #include <net/if_ether.h>
59320845ddSdyoung 
60320845ddSdyoung #include <dev/mii/mii.h>
61320845ddSdyoung #include <dev/mii/miivar.h>
62320845ddSdyoung 
63320845ddSdyoung #include <dev/sysmon/sysmonvar.h>
64320845ddSdyoung 
65320845ddSdyoung #include <mips/adm5120/include/adm5120reg.h>
66320845ddSdyoung #include <mips/adm5120/include/adm5120var.h>
67320845ddSdyoung #include <mips/adm5120/include/adm5120_obiovar.h>
68320845ddSdyoung 
69320845ddSdyoung #include <mips/adm5120/dev/if_admswreg.h>
70320845ddSdyoung 
71320845ddSdyoung #define	ADMSW_EVENT_COUNTERS
72320845ddSdyoung 
73320845ddSdyoung #define	MAC_BUFLEN	0x07ff
74320845ddSdyoung 
75320845ddSdyoung #define	ADMSW_NTXHDESC	4
76320845ddSdyoung #define	ADMSW_NRXHDESC	32
77320845ddSdyoung #define	ADMSW_NTXLDESC	32
78320845ddSdyoung #define	ADMSW_NRXLDESC	32
79320845ddSdyoung 
80320845ddSdyoung #define	ADMSW_NTXHDESC_MASK	(ADMSW_NTXHDESC - 1)
81320845ddSdyoung #define	ADMSW_NRXHDESC_MASK	(ADMSW_NRXHDESC - 1)
82320845ddSdyoung #define	ADMSW_NTXLDESC_MASK	(ADMSW_NTXLDESC - 1)
83320845ddSdyoung #define	ADMSW_NRXLDESC_MASK	(ADMSW_NRXLDESC - 1)
84320845ddSdyoung 
85320845ddSdyoung #define	ADMSW_NEXTTXH(x)	(((x) + 1) & ADMSW_NTXHDESC_MASK)
86320845ddSdyoung #define	ADMSW_NEXTRXH(x)	(((x) + 1) & ADMSW_NRXHDESC_MASK)
87320845ddSdyoung #define	ADMSW_NEXTTXL(x)	(((x) + 1) & ADMSW_NTXLDESC_MASK)
88320845ddSdyoung #define	ADMSW_NEXTRXL(x)	(((x) + 1) & ADMSW_NRXLDESC_MASK)
89320845ddSdyoung 
90320845ddSdyoung struct admsw_control_data {
91320845ddSdyoung 	/* The transmit descriptors. */
92320845ddSdyoung 	struct admsw_desc acd_txhdescs[ADMSW_NTXHDESC];
93320845ddSdyoung 
94320845ddSdyoung 	/* The receive descriptors. */
95320845ddSdyoung 	struct admsw_desc acd_rxhdescs[ADMSW_NRXHDESC];
96320845ddSdyoung 
97320845ddSdyoung 	/* The transmit descriptors. */
98320845ddSdyoung 	struct admsw_desc acd_txldescs[ADMSW_NTXLDESC];
99320845ddSdyoung 
100320845ddSdyoung 	/* The receive descriptors. */
101320845ddSdyoung 	struct admsw_desc acd_rxldescs[ADMSW_NRXLDESC];
102320845ddSdyoung };
103320845ddSdyoung 
104320845ddSdyoung #define	ADMSW_CDOFF(x)		offsetof(struct admsw_control_data, x)
105320845ddSdyoung #define	ADMSW_CDTXHOFF(x)	ADMSW_CDOFF(acd_txhdescs[(x)])
106320845ddSdyoung #define	ADMSW_CDTXLOFF(x)	ADMSW_CDOFF(acd_txldescs[(x)])
107320845ddSdyoung #define	ADMSW_CDRXHOFF(x)	ADMSW_CDOFF(acd_rxhdescs[(x)])
108320845ddSdyoung #define	ADMSW_CDRXLOFF(x)	ADMSW_CDOFF(acd_rxldescs[(x)])
109320845ddSdyoung 
110320845ddSdyoung struct admsw_descsoft {
111320845ddSdyoung 	struct mbuf *ds_mbuf;
112320845ddSdyoung 	bus_dmamap_t ds_dmamap;
113320845ddSdyoung };
114320845ddSdyoung 
115320845ddSdyoung /*
116320845ddSdyoung  * Software state per device.
117320845ddSdyoung  */
118320845ddSdyoung struct admsw_softc {
119cbab9cadSchs 	device_t sc_dev;		/* generic device information */
120320845ddSdyoung 	uint8_t		sc_enaddr[ETHER_ADDR_LEN];
121320845ddSdyoung 	bus_dma_tag_t sc_dmat;		/* bus DMA tag */
122320845ddSdyoung 	bus_space_tag_t sc_st;		/* bus space tag */
123320845ddSdyoung 	bus_space_handle_t sc_ioh;	/* MAC space handle */
124320845ddSdyoung 	struct sysmon_wdog	sc_smw;
125320845ddSdyoung 	struct ifmedia sc_ifmedia[SW_DEVS];
126320845ddSdyoung 	int ndevs;			/* number of IFF_RUNNING interfaces */
127320845ddSdyoung 	struct ethercom sc_ethercom[SW_DEVS];	/* Ethernet common data */
128320845ddSdyoung 	void *sc_sdhook;		/* shutdown hook */
129320845ddSdyoung 	void *sc_ih;			/* interrupt cookie */
130320845ddSdyoung 	struct admsw_descsoft sc_txhsoft[ADMSW_NTXHDESC];
131320845ddSdyoung 	struct admsw_descsoft sc_rxhsoft[ADMSW_NRXHDESC];
132320845ddSdyoung 	struct admsw_descsoft sc_txlsoft[ADMSW_NTXLDESC];
133320845ddSdyoung 	struct admsw_descsoft sc_rxlsoft[ADMSW_NRXLDESC];
134320845ddSdyoung 	bus_dmamap_t sc_cddmamap;	/* control data DMA map */
135320845ddSdyoung #define	sc_cddma	sc_cddmamap->dm_segs[0].ds_addr
136320845ddSdyoung 	struct admsw_control_data *sc_control_data;
137320845ddSdyoung #define	sc_txhdescs	sc_control_data->acd_txhdescs
138320845ddSdyoung #define	sc_rxhdescs	sc_control_data->acd_rxhdescs
139320845ddSdyoung #define	sc_txldescs	sc_control_data->acd_txldescs
140320845ddSdyoung #define	sc_rxldescs	sc_control_data->acd_rxldescs
141320845ddSdyoung 
142320845ddSdyoung 	int sc_txfree;			/* number of free Tx descriptors */
143320845ddSdyoung 	int sc_txnext;			/* next Tx descriptor to use */
144320845ddSdyoung 	int sc_txdirty;			/* first dirty Tx descriptor */
145320845ddSdyoung 
146320845ddSdyoung 	int sc_rxptr;			/* next ready Rx descriptor */
147320845ddSdyoung 
148320845ddSdyoung #ifdef ADMSW_EVENT_COUNTERS
149320845ddSdyoung 	struct evcnt sc_ev_txstall;	/* Tx stalled */
150320845ddSdyoung 	struct evcnt sc_ev_rxstall;	/* Rx stalled */
151320845ddSdyoung 	struct evcnt sc_ev_txintr;	/* Tx interrupts */
152320845ddSdyoung 	struct evcnt sc_ev_rxintr;	/* Rx interrupts */
153320845ddSdyoung #if 1
154320845ddSdyoung 	struct evcnt sc_ev_rxsync;	/* Rx syncs */
155320845ddSdyoung #endif
156320845ddSdyoung #endif
157320845ddSdyoung 
158320845ddSdyoung };
159320845ddSdyoung 
160320845ddSdyoung #define	ADMSW_CDTXHADDR(sc, x)	((sc)->sc_cddma + ADMSW_CDTXHOFF((x)))
161320845ddSdyoung #define	ADMSW_CDTXLADDR(sc, x)	((sc)->sc_cddma + ADMSW_CDTXLOFF((x)))
162320845ddSdyoung #define	ADMSW_CDRXHADDR(sc, x)	((sc)->sc_cddma + ADMSW_CDRXHOFF((x)))
163320845ddSdyoung #define	ADMSW_CDRXLADDR(sc, x)	((sc)->sc_cddma + ADMSW_CDRXLOFF((x)))
164320845ddSdyoung 
165320845ddSdyoung #define	ADMSW_CDTXHSYNC(sc, x, ops)					\
166320845ddSdyoung 	bus_dmamap_sync((sc)->sc_dmat, (sc)->sc_cddmamap,		\
167320845ddSdyoung 	    ADMSW_CDTXHOFF((x)), sizeof(struct admsw_desc), (ops))
168320845ddSdyoung 
169320845ddSdyoung #define	ADMSW_CDTXLSYNC(sc, x, ops)					\
170320845ddSdyoung 	bus_dmamap_sync((sc)->sc_dmat, (sc)->sc_cddmamap,		\
171320845ddSdyoung 	    ADMSW_CDTXLOFF((x)), sizeof(struct admsw_desc), (ops))
172320845ddSdyoung 
173320845ddSdyoung #define	ADMSW_CDRXHSYNC(sc, x, ops)					\
174320845ddSdyoung 	bus_dmamap_sync((sc)->sc_dmat, (sc)->sc_cddmamap,		\
175320845ddSdyoung 	    ADMSW_CDRXHOFF((x)), sizeof(struct admsw_desc), (ops))
176320845ddSdyoung 
177320845ddSdyoung #define	ADMSW_CDRXLSYNC(sc, x, ops)					\
178320845ddSdyoung 	bus_dmamap_sync((sc)->sc_dmat, (sc)->sc_cddmamap,		\
179320845ddSdyoung 	    ADMSW_CDRXLOFF((x)), sizeof(struct admsw_desc), (ops))
180320845ddSdyoung 
181320845ddSdyoung #define	ADMSW_INIT_RXHDESC(sc, x)				\
182320845ddSdyoung do {								\
183320845ddSdyoung 	struct admsw_descsoft *__ds = &(sc)->sc_rxhsoft[(x)];	\
184320845ddSdyoung 	struct admsw_desc *__desc = &(sc)->sc_rxhdescs[(x)];	\
185320845ddSdyoung 	struct mbuf *__m = __ds->ds_mbuf;			\
186320845ddSdyoung 								\
187320845ddSdyoung 	__m->m_data = __m->m_ext.ext_buf + 2;			\
188320845ddSdyoung 	__desc->data = __ds->ds_dmamap->dm_segs[0].ds_addr + 2;	\
189320845ddSdyoung 	__desc->cntl = 0;					\
190d1579b2dSriastradh 	__desc->len = uimin(MCLBYTES - 2, MAC_BUFLEN - 2);	\
191320845ddSdyoung 	__desc->status = 0;					\
192320845ddSdyoung 	if ((x) == ADMSW_NRXHDESC - 1)				\
193320845ddSdyoung 		__desc->data |= ADM5120_DMA_RINGEND;		\
194320845ddSdyoung 	__desc->data |= ADM5120_DMA_OWN;			\
195320845ddSdyoung 	ADMSW_CDRXHSYNC((sc), (x), BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE); \
196320845ddSdyoung } while (0)
197320845ddSdyoung 
198320845ddSdyoung #define	ADMSW_INIT_RXLDESC(sc, x)				\
199320845ddSdyoung do {								\
200320845ddSdyoung 	struct admsw_descsoft *__ds = &(sc)->sc_rxlsoft[(x)];	\
201320845ddSdyoung 	struct admsw_desc *__desc = &(sc)->sc_rxldescs[(x)];	\
202320845ddSdyoung 	struct mbuf *__m = __ds->ds_mbuf;			\
203320845ddSdyoung 								\
204320845ddSdyoung 	__m->m_data = __m->m_ext.ext_buf + 2;			\
205320845ddSdyoung 	__desc->data = __ds->ds_dmamap->dm_segs[0].ds_addr + 2;	\
206320845ddSdyoung 	__desc->cntl = 0;					\
207d1579b2dSriastradh 	__desc->len = uimin(MCLBYTES - 2, MAC_BUFLEN - 2);	\
208320845ddSdyoung 	__desc->status = 0;					\
209320845ddSdyoung 	if ((x) == ADMSW_NRXLDESC - 1)				\
210320845ddSdyoung 		__desc->data |= ADM5120_DMA_RINGEND;		\
211320845ddSdyoung 	__desc->data |= ADM5120_DMA_OWN;			\
212320845ddSdyoung 	ADMSW_CDRXLSYNC((sc), (x), BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE); \
213320845ddSdyoung } while (0)
214320845ddSdyoung 
215320845ddSdyoung void admwdog_attach(struct admsw_softc *);
216320845ddSdyoung 
217320845ddSdyoung #endif /* _IF_ADMSWVAR_H_ */
218