xref: /illumos-gate/usr/src/uts/common/io/iprb/iprb.h (revision 66582b606a8194f7f3ba5b3a3a6dca5b0d346361)
1 /*
2  * This file and its contents are supplied under the terms of the
3  * Common Development and Distribution License ("CDDL"), version 1.0.
4  * You may only use this file in accordance with the terms of version
5  * 1.0 of the CDDL.
6  *
7  * A full copy of the text of the CDDL should have accompanied this
8  * source.  A copy of the CDDL is also available via the Internet at
9  * http://www.illumos.org/license/CDDL.
10  */
11 
12 /*
13  * Copyright 2014 Nexenta Systems, Inc.  All rights reserved.
14  */
15 
16 #ifndef _IPRB_H
17 #define	_IPRB_H
18 
19 /*
20  * iprb - Intel Pro/100B Ethernet Driver
21  */
22 
23 /*
24  * Tunables.
25  */
26 #define	NUM_TX		128	/* outstanding tx queue */
27 #define	NUM_RX		128	/* outstanding rx queue */
28 
29 /* timeouts for the rx and tx watchdogs (nsec) */
30 #define	RX_WATCHDOG	(15 * NANOSEC)
31 #define	TX_WATCHDOG	(15 * NANOSEC)
32 
33 /*
34  * Driver structures.
35  */
36 typedef struct {
37 	ddi_acc_handle_t	acch;
38 	ddi_dma_handle_t	dmah;
39 	caddr_t			vaddr;
40 	uint32_t		paddr;
41 } iprb_dma_t;
42 
43 typedef struct iprb_mcast {
44 	list_node_t		node;
45 	uint8_t			addr[6];
46 } iprb_mcast_t;
47 
48 typedef struct iprb {
49 	dev_info_t		*dip;
50 	ddi_acc_handle_t	pcih;
51 	ddi_acc_handle_t	regsh;
52 	caddr_t			regs;
53 
54 	uint16_t		devid;
55 	uint8_t			revid;
56 
57 	mac_handle_t		mach;
58 	mii_handle_t		miih;
59 
60 	ddi_intr_handle_t	intrh;
61 
62 	ddi_periodic_t		perh;
63 
64 	kmutex_t		culock;
65 	kmutex_t		rulock;
66 
67 	uint8_t			factaddr[6];
68 	uint8_t			curraddr[6];
69 
70 	int			nmcast;
71 	list_t			mcast;
72 	boolean_t		promisc;
73 	iprb_dma_t		cmds[NUM_TX];
74 	iprb_dma_t		rxb[NUM_RX];
75 	iprb_dma_t		stats;
76 	hrtime_t		stats_time;
77 
78 	uint16_t		cmd_head;
79 	uint16_t		cmd_last;
80 	uint16_t		cmd_tail;
81 	uint16_t		cmd_count;
82 
83 	uint16_t		rx_index;
84 	uint16_t		rx_last;
85 	hrtime_t		rx_wdog;
86 	hrtime_t		rx_timeout;
87 	hrtime_t		tx_wdog;
88 	hrtime_t		tx_timeout;
89 
90 	uint16_t		eeprom_bits;
91 
92 	boolean_t		running;
93 	boolean_t		suspended;
94 	boolean_t		wantw;
95 	boolean_t		rxhangbug;
96 	boolean_t		resumebug;
97 	boolean_t		is557;
98 	boolean_t		canpause;
99 	boolean_t		canmwi;
100 
101 	/*
102 	 * Statistics
103 	 */
104 	uint64_t		ipackets;
105 	uint64_t		rbytes;
106 	uint64_t		multircv;
107 	uint64_t		brdcstrcv;
108 	uint64_t		opackets;
109 	uint64_t		obytes;
110 	uint64_t		multixmt;
111 	uint64_t		brdcstxmt;
112 	uint64_t		ex_coll;
113 	uint64_t		late_coll;
114 	uint64_t		uflo;
115 	uint64_t		defer_xmt;
116 	uint64_t		one_coll;
117 	uint64_t		multi_coll;
118 	uint64_t		collisions;
119 	uint64_t		fcs_errs;
120 	uint64_t		align_errs;
121 	uint64_t		norcvbuf;
122 	uint64_t		oflo;
123 	uint64_t		runt;
124 	uint64_t		nocarrier;
125 	uint64_t		toolong;
126 	uint64_t		macxmt_errs;
127 	uint64_t		macrcv_errs;
128 } iprb_t;
129 
130 /*
131  * Idenfication values.
132  */
133 #define	REV_82557	1
134 #define	REV_82558_A4	4
135 #define	REV_82558_B0	5
136 #define	REV_82559_A0	8
137 #define	REV_82559S_A	9
138 #define	REV_82550	12
139 #define	REV_82550_C	13
140 #define	REV_82551_E	14
141 #define	REV_82551_F	15
142 #define	REV_82551_10	16
143 
144 /*
145  * Device registers.
146  */
147 #define	CSR_STATE	0x00
148 #define	CSR_STS		0x01
149 #define	CSR_CMD		0x02
150 #define	CSR_INTCTL	0x03
151 #define	CSR_GEN_PTR	0x04
152 #define	CSR_PORT	0x08
153 #define	CSR_EECTL	0x0e
154 #define	CSR_MDICTL	0x10
155 
156 #define	STATE_CUS	0xc0	/* CU state (mask) */
157 #define	STATE_CUS_IDLE	0x00	/* CU idle */
158 #define	STATE_CUS_SUSP	0x40	/* CU suspended */
159 #define	STATE_CUS_LPQA	0x80	/* LPQ active */
160 #define	STATE_CUS_HQPA	0xc0	/* HQP active */
161 #define	STATE_RUS	0x3c	/* RU state (mask) */
162 #define	STATE_RUS_IDLE	0x00	/* RU idle */
163 #define	STATE_RUS_SUSP	0x04	/* RU suspended */
164 #define	STATE_RUS_NORES	0x08	/* RU no resources */
165 #define	STATE_RUS_READY	0x10	/* RU ready */
166 
167 #define	STS_FCP		0x01	/* flow control pause */
168 #define	STS_RSVD	0x02	/* reserved bit */
169 #define	STS_SWI		0x04	/* software interrupt */
170 #define	STS_MDI		0x08	/* MDI read/write done */
171 #define	STS_RNR		0x10	/* RU not ready */
172 #define	STS_CNA		0x20	/* CU state change */
173 #define	STS_FR		0x40	/* frame receive */
174 #define	STS_CX		0x80	/* cmd exec done */
175 
176 #define	CMD_CUC		0xf0	/* CU command (mask) */
177 #define	CUC_NOP		0x00	/* no operation */
178 #define	CUC_START	0x10	/* start CU */
179 #define	CUC_RESUME	0x20	/* resume CU */
180 #define	CUC_STATSBASE	0x40	/* load statistics address */
181 #define	CUC_STATS	0x50	/* dump statistics */
182 #define	CUC_CUBASE	0x60	/* load CU base address */
183 #define	CUC_STATS_RST	0x70	/* dump statistics and reset */
184 #define	CUC_SRES	0xa0	/* static resume CU */
185 #define	CMD_RUC		0x07	/* RU command (mask) */
186 #define	RUC_NOP		0x00	/* no operation */
187 #define	RUC_START	0x01	/* start RU */
188 #define	RUC_RESUME	0x02	/* resume RU */
189 #define	RUC_DMAREDIR	0x03	/* receive DMA redirect */
190 #define	RUC_ABORT	0x40	/* abort RU */
191 #define	RUC_HDRSZ	0x50	/* load header data size */
192 #define	RUC_RUBASE	0x60	/* load RU base address */
193 
194 #define	INTCTL_MASK	0x01	/* disable all interrupts */
195 #define	INTCTL_SI	0x02	/* generate software interrupt */
196 #define	INTCTL_FCP	0x04	/* flow control pause */
197 #define	INTCTL_ER	0x08	/* early receive */
198 #define	INTCTL_RNR	0x10	/* RU not ready */
199 #define	INTCTL_CNA	0x20	/* CU state change */
200 #define	INTCTL_FR	0x40	/* frame receive */
201 #define	INTCTL_CX	0x80	/* cmd exec done */
202 
203 #define	PORT_SW_RESET	0x00
204 #define	PORT_SELF_TEST	0x01
205 #define	PORT_SEL_RESET	0x02
206 
207 #define	EEPROM_EEDO	0x0008	/* data out */
208 #define	EEPROM_EEDI	0x0004	/* data in */
209 #define	EEPROM_EECS	0x0002	/* chip select */
210 #define	EEPROM_EESK	0x0001	/* clock */
211 
212 #define	EEPROM_OP_RD	0x06
213 #define	EEPROM_OP_WR	0x05
214 #define	EEPROM_OP_WE	0x13	/* write enable */
215 #define	EEPROM_OP_WD	0x13	/* write disable */
216 
217 #define	MDI_IE		0x20000000	/* interrupt enable */
218 #define	MDI_R		0x10000000	/* ready */
219 #define	MDI_OP_RD	0x08000000	/* read */
220 #define	MDI_OP_WR	0x04000000	/* write */
221 #define	MDI_PHYAD_SHIFT	21
222 #define	MDI_REGAD_SHIFT	16
223 
224 #define	GET8(ip, offset)					\
225 	ddi_get8(ip->regsh, (void *)(ip->regs + (offset)))
226 #define	GET16(ip, offset)					\
227 	ddi_get16(ip->regsh, (void *)(ip->regs + (offset)))
228 #define	GET32(ip, offset)					\
229 	ddi_get32(ip->regsh, (void *)(ip->regs + (offset)))
230 #define	PUT8(ip, offset, val)						\
231 	ddi_put8(ip->regsh, (void *)(ip->regs + (offset)), (val))
232 #define	PUT16(ip, offset, val)						\
233 	ddi_put16(ip->regsh, (void *)(ip->regs + (offset)), (val))
234 #define	PUT32(ip, offset, val)						\
235 	ddi_put32(ip->regsh, (void *)(ip->regs + (offset)), (val))
236 
237 
238 #define	PUTDMA8(d, off, val)					\
239 	ddi_put8(d->acch, (void *)(d->vaddr + (off)), LE_8(val))
240 #define	PUTDMA16(d, off, val)						\
241 	ddi_put16(d->acch, (void *)(d->vaddr + (off)), LE_16(val))
242 #define	PUTDMA32(d, off, val)						\
243 	ddi_put32(d->acch, (void *)(d->vaddr + (off)), LE_32(val))
244 #define	GETDMA8(d, off)						\
245 	LE_8(ddi_get8(d->acch, (void *)(d->vaddr + (off))))
246 #define	GETDMA16(d, off)					\
247 	LE_16(ddi_get16(d->acch, (void *)(d->vaddr + (off))))
248 #define	GETDMA32(d, off)					\
249 	LE_32(ddi_get32(d->acch, (void *)(d->vaddr + (off))))
250 #define	SYNCDMA(d, off, size, dir)			\
251 	(void) ddi_dma_sync(d->dmah, off, size, dir)
252 
253 /*
254  * Command block offsets.
255  */
256 #define	CB_STS_OFFSET		0
257 #define	CB_CMD_OFFSET		2
258 #define	CB_LNK_OFFSET		4
259 #define	CB_SIZE			2048	/* size of cmd blk */
260 
261 #define	CB_IAS_ADR_OFFSET	8
262 
263 #define	CB_MCS_CNT_OFFSET	8
264 #define	CB_MCS_ADR_OFFSET	10
265 #define	CB_MCS_CNT_MAX		((CB_SIZE - CB_MCS_ADR_OFFSET) / 6)
266 
267 #define	CB_UCODE_OFFSET		8
268 
269 #define	CB_CONFIG_OFFSET	8
270 
271 #define	CB_TX_TBD_OFFSET	8
272 #define	CB_TX_COUNT_OFFSET	12
273 #define	CB_TX_EOF		0x8000
274 #define	CB_TX_THRESH_OFFSET	14
275 #define	CB_TX_NUMBER_OFFSET	15
276 #define	CB_TX_DATA_OFFSET	16
277 
278 #define	PUTCB8(cb, o, v)	PUTDMA8(cb, o, v)
279 #define	PUTCB16(cb, o, v)	PUTDMA16(cb, o, v)
280 #define	PUTCB32(cb, o, v)	PUTDMA32(cb, o, v)
281 #define	PUTCBEA(cb, o, enet)						\
282 	ddi_rep_put8(cb->acch, enet, (void *)(cb->vaddr + (o)), 6,	\
283 	DDI_DEV_AUTOINCR);
284 #define	GETCB8(cb, o)		GETDMA8(cb, o)
285 #define	GETCB16(cb, o)		GETDMA16(cb, o)
286 #define	GETCB32(cb, o)		GETDMA32(cb, o)
287 #define	SYNCCB(cb, o, s, dir)	SYNCDMA(cb, o, s, dir)
288 /*
289  * CB status bits.
290  */
291 #define	CB_STS_OK		0x2000
292 #define	CB_STS_C		0x8000
293 
294 /*
295  * Commands.
296  */
297 #define	CB_CMD_NOP		0x0
298 #define	CB_CMD_IAS		0x1
299 #define	CB_CMD_CONFIG		0x2
300 #define	CB_CMD_MCS		0x3
301 #define	CB_CMD_TX		0x4
302 #define	CB_CMD_UCODE		0x5
303 /* and flags to go with */
304 #define	CB_CMD_SF		0x0008	/* simple/flex */
305 #define	CB_CMD_I		0x2000	/* generate an interrupt */
306 #define	CB_CMD_S		0x4000	/* suspend on completion */
307 #define	CB_CMD_EL		0x8000	/* end of list */
308 
309 /*
310  * RFD offsets.
311  */
312 #define	GETRFD16(r, o)		GETDMA16(r, o)
313 #define	PUTRFD16(r, o, v)	PUTDMA16(r, o, v)
314 #define	PUTRFD32(r, o, v)	PUTDMA32(r, o, v)
315 #define	SYNCRFD(r, o, s, dir)	SYNCDMA(r, o, s, dir)
316 
317 #define	RFD_STS_OFFSET		0x00
318 #define	RFD_CTL_OFFSET		0x02
319 #define	RFD_LNK_OFFSET		0x04
320 #define	RFD_CNT_OFFSET		0x0c	/* bytes received */
321 #define	RFD_SIZ_OFFSET		0x0e	/* size of packet area */
322 #define	RFD_PKT_OFFSET		0x10
323 #define	RFD_SIZE		2048
324 
325 #define	RFD_CTL_EL		0x8000
326 #define	RFD_CTL_S		0x4000
327 #define	RFD_CTL_H		0x0010
328 #define	RFD_CTL_SF		0x0008
329 
330 #define	RFD_STS_C		0x8000
331 #define	RFD_STS_OK		0x2000
332 #define	RFD_STS_FCS		0x0800
333 #define	RFD_STS_ALIGN		0x0400
334 #define	RFD_STS_TOOBIG		0x0200
335 #define	RFD_STS_DMAOFLO		0x0100
336 #define	RFD_STS_TOOSHORT	0x0080
337 #define	RFD_STS_802		0x0020
338 #define	RFD_STS_RXERR		0x0010
339 #define	RFD_STS_NOMATCH		0x0004
340 #define	RFD_STS_IAMATCH		0x0002
341 #define	RFD_STS_COLL_TCO	0x0001
342 #define	RFD_STS_ERRS		0x0d90
343 
344 #define	RFD_CNT_EOF		0x8000
345 #define	RFD_CNT_F		0x4000
346 
347 /*
348  * Stats offsets.
349  */
350 #define	STATS_TX_GOOD_OFFSET	0
351 #define	STATS_TX_MAXCOL_OFFSET	4
352 #define	STATS_TX_LATECOL_OFFSET	8
353 #define	STATS_TX_UFLO_OFFSET	16
354 #define	STATS_TX_DEFER_OFFSET	20
355 #define	STATS_TX_ONECOL_OFFSET	24
356 #define	STATS_TX_MULTCOL_OFFSET	28
357 #define	STATS_TX_TOTCOL_OFFSET	32
358 #define	STATS_RX_GOOD_OFFSET	36
359 #define	STATS_RX_FCS_OFFSET	40
360 #define	STATS_RX_ALIGN_OFFSET	44
361 #define	STATS_RX_NOBUF_OFFSET	48
362 #define	STATS_RX_OFLO_OFFSET	52
363 #define	STATS_RX_COL_OFFSET	56
364 #define	STATS_RX_SHORT_OFFSET	60
365 #define	STATS_DONE_OFFSET	64
366 #define	STATS_SIZE		68
367 #define	STATS_DONE		0xa005
368 #define	STATS_RST_DONE		0xa007
369 
370 #define	SYNCSTATS(sp, o, s, dir)	SYNCDMA(sp, o, s, dir)
371 #define	PUTSTAT(sp, o, v)		PUTDMA32(sp, o, v)
372 #define	GETSTAT(sp, o)			GETDMA32(sp, o)
373 
374 #endif /* _IPRB_H */
375