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