summaryrefslogtreecommitdiff
path: root/sys/dev/ic/rtl81x9var.h
blob: f2e9e7a18df307f55ce2febd63ac455e4ba2652c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
/*	$NetBSD: rtl81x9var.h,v 1.58 2020/09/21 06:57:00 msaitoh Exp $	*/

/*
 * Copyright (c) 1997, 1998
 *	Bill Paul <wpaul@ctr.columbia.edu>.  All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. All advertising materials mentioning features or use of this software
 *    must display the following acknowledgement:
 *	This product includes software developed by Bill Paul.
 * 4. Neither the name of the author nor the names of any co-contributors
 *    may be used to endorse or promote products derived from this software
 *    without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY Bill Paul AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL Bill Paul OR THE VOICES IN HIS HEAD
 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
 * THE POSSIBILITY OF SUCH DAMAGE.
 *
 *	FreeBSD Id: if_rlreg.h,v 1.9 1999/06/20 18:56:09 wpaul Exp
 */

#include <sys/rndsource.h>

#define RTK_ETHER_ALIGN	2
#define RTK_RXSTAT_LEN	4

#ifdef __NO_STRICT_ALIGNMENT
/*
 * XXX According to PR kern/33763, some 8168 and variants can't DMA
 * XXX RX packet data into unaligned buffer. This means such chips will
 * XXX never work on !__NO_STRICT_ALIGNMENT hosts without copying buffer.
 */
#define RE_ETHER_ALIGN	0
#else
#define RE_ETHER_ALIGN	2
#endif

struct rtk_type {
	uint16_t		rtk_vid;
	uint16_t		rtk_did;
	int			rtk_basetype;
#define RTK_8129		1
#define RTK_8139		2
#define RTK_8139CPLUS		3
#define RTK_8169		4
#define RTK_8168		5
#define RTK_8101E		6
	const char		*rtk_name;
};

struct rtk_mii_frame {
	uint8_t			mii_stdelim;
	uint8_t			mii_opcode;
	uint8_t			mii_phyaddr;
	uint8_t			mii_regaddr;
	uint8_t			mii_turnaround;
	uint16_t		mii_data;
};

/*
 * MII constants
 */
#define RTK_MII_STARTDELIM	0x01
#define RTK_MII_READOP		0x02
#define RTK_MII_WRITEOP		0x01
#define RTK_MII_TURNAROUND	0x02


/*
 * The RealTek doesn't use a fragment-based descriptor mechanism.
 * Instead, there are only four register sets, each or which represents
 * one 'descriptor.' Basically, each TX descriptor is just a contiguous
 * packet buffer (32-bit aligned!) and we place the buffer addresses in
 * the registers so the chip knows where they are.
 *
 * We can sort of kludge together the same kind of buffer management
 * used in previous drivers, but we have to do buffer copies almost all
 * the time, so it doesn't really buy us much.
 *
 * For reception, there's just one large buffer where the chip stores
 * all received packets.
 */

#ifdef dreamcast
/*
 * XXX dreamcast has only 32KB DMA'able memory on its PCI bridge.
 * XXX Maybe this should be handled by prop_dictionary, or
 * XXX some other new API which returns available DMA resources.
 */
#define RTK_RX_BUF_SZ		RTK_RXBUF_16
#else
#define RTK_RX_BUF_SZ		RTK_RXBUF_64
#endif
#define RTK_RXBUFLEN		RTK_RXBUF_LEN(RTK_RX_BUF_SZ)
#define RTK_TX_LIST_CNT		4

/*
 * The 8139C+ and 8169 gigE chips support descriptor-based TX
 * and RX. In fact, they even support TCP large send. Descriptors
 * must be allocated in contiguous blocks that are aligned on a
 * 256-byte boundary. The RX rings can hold a maximum of 64 descriptors.
 * The TX rings can hold upto 64 descriptors on 8139C+, and
 * 1024 descriptors on 8169 gigE chips.
 */
#define RE_RING_ALIGN		256

/*
 * Size of descriptors and TX queue.
 * These numbers must be power of two to simplify RE_NEXT_*() macro.
 */
#define RE_RX_DESC_CNT		64
#define RE_TX_DESC_CNT_8139	64
#define RE_TX_DESC_CNT_8169	1024
#define RE_TX_QLEN		64

#define RE_NTXDESC_RSVD		4

struct re_rxsoft {
	struct mbuf		*rxs_mbuf;
	bus_dmamap_t		rxs_dmamap;
};

struct re_txq {
	struct mbuf *txq_mbuf;
	bus_dmamap_t txq_dmamap;
	int txq_descidx;
	int txq_nsegs;
};

struct re_list_data {
	struct re_txq		re_txq[RE_TX_QLEN];
	int			re_txq_considx;
	int			re_txq_prodidx;
	int			re_txq_free;

	bus_dmamap_t		re_tx_list_map;
	struct re_desc		*re_tx_list;
	int			re_tx_free;	/* # of free descriptors */
	int			re_tx_nextfree; /* next descriptor to use */
	int			re_tx_desc_cnt; /* # of descriptors */
	bus_dma_segment_t	re_tx_listseg;
	int			re_tx_listnseg;

	struct re_rxsoft	re_rxsoft[RE_RX_DESC_CNT];
	bus_dmamap_t		re_rx_list_map;
	struct re_desc		*re_rx_list;
	int			re_rx_prodidx;
	bus_dma_segment_t	re_rx_listseg;
	int			re_rx_listnseg;
};

struct rtk_tx_desc {
	SIMPLEQ_ENTRY(rtk_tx_desc) txd_q;
	struct mbuf		*txd_mbuf;
	bus_dmamap_t		txd_dmamap;
	bus_addr_t		txd_txaddr;
	bus_addr_t		txd_txstat;
};

struct rtk_softc {
	device_t		sc_dev;
	struct ethercom		ethercom;	/* interface info */
	struct mii_data		mii;
	uint32_t		sc_hwrev;
	struct callout		rtk_tick_ch;	/* tick callout */
	bus_space_tag_t		rtk_btag;	/* bus space tag */
	bus_space_handle_t	rtk_bhandle;	/* bus space handle */
	bus_size_t		rtk_bsize;	/* bus space mapping size */
	u_int			sc_quirk;	/* chip quirks */
#define RTKQ_8129		0x00000001	/* 8129 */
#define RTKQ_8139CPLUS		0x00000002	/* 8139C+ */
#define RTKQ_8169NONS		0x00000004	/* old non-single 8169 */
#define RTKQ_PCIE		0x00000008	/* PCIe variants */
#define RTKQ_MACLDPS		0x00000010	/* has LDPS register */
#define RTKQ_DESCV2		0x00000020	/* has V2 TX/RX descriptor */
#define RTKQ_NOJUMBO		0x00000040	/* no jumbo MTU support */
#define RTKQ_NOEECMD		0x00000080	/* unusable EEPROM command */
#define RTKQ_MACSTAT		0x00000100	/* set MACSTAT_DIS on init */
#define RTKQ_CMDSTOP		0x00000200	/* set STOPREQ on stop */
#define RTKQ_PHYWAKE_PM		0x00000400	/* wake PHY from power down */
#define RTKQ_RXDV_GATED		0x00000800
#define RTKQ_IM_HW		0x00001000	/* HW interrupt mitigation */
#define RTKQ_TXRXEN_LATER	0x00002000	/* TX/RX enable timing */

	bus_dma_tag_t		sc_dmat;

	bus_dma_segment_t	sc_dmaseg;	/* for rtk(4) */
	int			sc_dmanseg;	/* for rtk(4) */

	bus_dmamap_t		recv_dmamap;	/* for rtk(4) */
	uint8_t			*rtk_rx_buf;

	struct rtk_tx_desc	rtk_tx_descs[RTK_TX_LIST_CNT];
	SIMPLEQ_HEAD(, rtk_tx_desc) rtk_tx_free;
	SIMPLEQ_HEAD(, rtk_tx_desc) rtk_tx_dirty;

	struct re_list_data	re_ldata;
	struct mbuf		*re_head;
	struct mbuf		*re_tail;
	uint32_t		re_rxlenmask;
	int			re_testmode;

	int			sc_flags;	/* misc flags */
#define RTK_ATTACHED 0x00000001 /* attach has succeeded */
#define RTK_ENABLED  0x00000002 /* chip is enabled	*/
#define RTK_IS_ENABLED(sc)	((sc)->sc_flags & RTK_ENABLED)

	int			sc_txthresh;	/* Early tx threshold */
	int			sc_rev;		/* MII revision */

	/* Power management hooks. */
	int	(*sc_enable)	(struct rtk_softc *);
	void	(*sc_disable)	(struct rtk_softc *);

	krndsource_t     rnd_source;
};

#define RE_TX_DESC_CNT(sc)	((sc)->re_ldata.re_tx_desc_cnt)
#define RE_TX_LIST_SZ(sc)	(RE_TX_DESC_CNT(sc) * sizeof(struct re_desc))
#define RE_NEXT_TX_DESC(sc, x)	(((x) + 1) & (RE_TX_DESC_CNT(sc) - 1))

#define RE_RX_LIST_SZ		(RE_RX_DESC_CNT * sizeof(struct re_desc))
#define RE_NEXT_RX_DESC(sc, x)	(((x) + 1) & (RE_RX_DESC_CNT - 1))

#define RE_NEXT_TXQ(sc, x)	(((x) + 1) & (RE_TX_QLEN - 1))

#define RE_TXDESCSYNC(sc, idx, ops)					\
	bus_dmamap_sync((sc)->sc_dmat,					\
	    (sc)->re_ldata.re_tx_list_map,				\
	    sizeof(struct re_desc) * (idx),				\
	    sizeof(struct re_desc),					\
	    (ops))
#define RE_RXDESCSYNC(sc, idx, ops)					\
	bus_dmamap_sync((sc)->sc_dmat,					\
	    (sc)->re_ldata.re_rx_list_map,				\
	    sizeof(struct re_desc) * (idx),				\
	    sizeof(struct re_desc),					\
	    (ops))

/*
 * re(4) hardware ip4csum-tx could be mangled with 28 byte or less IP packets
 */
#define RE_IP4CSUMTX_MINLEN	28
#define RE_IP4CSUMTX_PADLEN	(ETHER_HDR_LEN + RE_IP4CSUMTX_MINLEN)
/*
 * XXX
 * We are allocating pad DMA buffer after RX DMA descs for now
 * because RE_TX_LIST_SZ(sc) always occupies whole page but
 * RE_RX_LIST_SZ is less than PAGE_SIZE so there is some unused region.
 */
#define RE_RX_DMAMEM_SZ		(RE_RX_LIST_SZ + RE_IP4CSUMTX_PADLEN)
#define RE_TXPADOFF		RE_RX_LIST_SZ
#define RE_TXPADDADDR(sc)	\
	((sc)->re_ldata.re_rx_list_map->dm_segs[0].ds_addr + RE_TXPADOFF)


#define RTK_TXTH_MAX	RTK_TXTH_1536

/*
 * register space access macros
 */
#define CSR_WRITE_4(sc, reg, val)	\
	bus_space_write_4(sc->rtk_btag, sc->rtk_bhandle, reg, val)
#define CSR_WRITE_2(sc, reg, val)	\
	bus_space_write_2(sc->rtk_btag, sc->rtk_bhandle, reg, val)
#define CSR_WRITE_1(sc, reg, val)	\
	bus_space_write_1(sc->rtk_btag, sc->rtk_bhandle, reg, val)

#define CSR_READ_4(sc, reg)		\
	bus_space_read_4(sc->rtk_btag, sc->rtk_bhandle, reg)
#define CSR_READ_2(sc, reg)		\
	bus_space_read_2(sc->rtk_btag, sc->rtk_bhandle, reg)
#define CSR_READ_1(sc, reg)		\
	bus_space_read_1(sc->rtk_btag, sc->rtk_bhandle, reg)

#define RTK_TIMEOUT		1000

/*
 * PCI low memory base and low I/O base registers
 */

#define RTK_PCI_LOIO		0x10
#define RTK_PCI_LOMEM		0x14

#ifdef _KERNEL
uint16_t rtk_read_eeprom(struct rtk_softc *, int, int);
void	rtk_setmulti(struct rtk_softc *);
void	rtk_attach(struct rtk_softc *);
int	rtk_detach(struct rtk_softc *);
int	rtk_activate(device_t, enum devact);
int	rtk_intr(void *);
#endif /* _KERNEL */