summaryrefslogtreecommitdiff
path: root/usr/src/uts/common/io/iprb/iprb.h
blob: 8d31e3a4d63c050da95c69e6a85c8e8ff825ff09 (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
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
/*
 * This file and its contents are supplied under the terms of the
 * Common Development and Distribution License ("CDDL"), version 1.0.
 * You may only use this file in accordance with the terms of version
 * 1.0 of the CDDL.
 *
 * A full copy of the text of the CDDL should have accompanied this
 * source.  A copy of the CDDL is also available via the Internet at
 * http://www.illumos.org/license/CDDL.
 */

/*
 * Copyright 2014 Nexenta Systems, Inc.  All rights reserved.
 */

#ifndef _IPRB_H
#define	_IPRB_H

/*
 * iprb - Intel Pro/100B Ethernet Driver
 */

/*
 * Tunables.
 */
#define	NUM_TX		128	/* outstanding tx queue */
#define	NUM_RX		128	/* outstanding rx queue */

/* timeouts for the rx and tx watchdogs (nsec) */
#define	RX_WATCHDOG	(15 * NANOSEC)
#define	TX_WATCHDOG	(15 * NANOSEC)

/*
 * Driver structures.
 */
typedef struct {
	ddi_acc_handle_t	acch;
	ddi_dma_handle_t	dmah;
	caddr_t			vaddr;
	uint32_t		paddr;
} iprb_dma_t;

typedef struct iprb_mcast {
	list_node_t		node;
	uint8_t			addr[6];
} iprb_mcast_t;

typedef struct iprb {
	dev_info_t		*dip;
	ddi_acc_handle_t	pcih;
	ddi_acc_handle_t	regsh;
	caddr_t			regs;

	uint16_t		devid;
	uint8_t			revid;

	mac_handle_t		mach;
	mii_handle_t		miih;

	ddi_intr_handle_t	intrh;

	ddi_periodic_t		perh;

	kmutex_t		culock;
	kmutex_t		rulock;

	uint8_t			factaddr[6];
	uint8_t			curraddr[6];

	int			nmcast;
	list_t			mcast;
	boolean_t		promisc;
	iprb_dma_t		cmds[NUM_TX];
	iprb_dma_t		rxb[NUM_RX];
	iprb_dma_t		stats;
	hrtime_t		stats_time;

	uint16_t		cmd_head;
	uint16_t		cmd_last;
	uint16_t		cmd_tail;
	uint16_t		cmd_count;

	uint16_t		rx_index;
	uint16_t		rx_last;
	hrtime_t		rx_wdog;
	hrtime_t		rx_timeout;
	hrtime_t		tx_wdog;
	hrtime_t		tx_timeout;

	uint16_t		eeprom_bits;

	boolean_t		running;
	boolean_t		suspended;
	boolean_t		wantw;
	boolean_t		rxhangbug;
	boolean_t		resumebug;
	boolean_t		is557;
	boolean_t		canpause;
	boolean_t		canmwi;

	/*
	 * Statistics
	 */
	uint64_t		ipackets;
	uint64_t		rbytes;
	uint64_t		multircv;
	uint64_t		brdcstrcv;
	uint64_t		opackets;
	uint64_t		obytes;
	uint64_t		multixmt;
	uint64_t		brdcstxmt;
	uint64_t		ex_coll;
	uint64_t		late_coll;
	uint64_t		uflo;
	uint64_t		defer_xmt;
	uint64_t		one_coll;
	uint64_t		multi_coll;
	uint64_t		collisions;
	uint64_t		fcs_errs;
	uint64_t		align_errs;
	uint64_t		norcvbuf;
	uint64_t		oflo;
	uint64_t		runt;
	uint64_t		nocarrier;
	uint64_t		toolong;
	uint64_t		macxmt_errs;
	uint64_t		macrcv_errs;
} iprb_t;

/*
 * Idenfication values.
 */
#define	REV_82557	1
#define	REV_82558_A4	4
#define	REV_82558_B0	5
#define	REV_82559_A0	8
#define	REV_82559S_A	9
#define	REV_82550	12
#define	REV_82550_C	13
#define	REV_82551_E	14
#define	REV_82551_F	15
#define	REV_82551_10	16

/*
 * Device registers.
 */
#define	CSR_STATE	0x00
#define	CSR_STS		0x01
#define	CSR_CMD		0x02
#define	CSR_INTCTL	0x03
#define	CSR_GEN_PTR	0x04
#define	CSR_PORT	0x08
#define	CSR_EECTL	0x0e
#define	CSR_MDICTL	0x10

#define	STATE_CUS	0xc0	/* CU state (mask) */
#define	STATE_CUS_IDLE	0x00	/* CU idle */
#define	STATE_CUS_SUSP	0x40	/* CU suspended */
#define	STATE_CUS_LPQA	0x80	/* LPQ active */
#define	STATE_CUS_HQPA	0xc0	/* HQP active */
#define	STATE_RUS	0x3c	/* RU state (mask) */
#define	STATE_RUS_IDLE	0x00	/* RU idle */
#define	STATE_RUS_SUSP	0x04	/* RU suspended */
#define	STATE_RUS_NORES	0x08	/* RU no resources */
#define	STATE_RUS_READY	0x10	/* RU ready */

#define	STS_FCP		0x01	/* flow control pause */
#define	STS_RSVD	0x02	/* reserved bit */
#define	STS_SWI		0x04	/* software interrupt */
#define	STS_MDI		0x08	/* MDI read/write done */
#define	STS_RNR		0x10	/* RU not ready */
#define	STS_CNA		0x20	/* CU state change */
#define	STS_FR		0x40	/* frame receive */
#define	STS_CX		0x80	/* cmd exec done */

#define	CMD_CUC		0xf0	/* CU command (mask) */
#define	CUC_NOP		0x00	/* no operation */
#define	CUC_START	0x10	/* start CU */
#define	CUC_RESUME	0x20	/* resume CU */
#define	CUC_STATSBASE	0x40	/* load statistics address */
#define	CUC_STATS	0x50	/* dump statistics */
#define	CUC_CUBASE	0x60	/* load CU base address */
#define	CUC_STATS_RST	0x70	/* dump statistics and reset */
#define	CUC_SRES	0xa0	/* static resume CU */
#define	CMD_RUC		0x07	/* RU command (mask) */
#define	RUC_NOP		0x00	/* no operation */
#define	RUC_START	0x01	/* start RU */
#define	RUC_RESUME	0x02	/* resume RU */
#define	RUC_DMAREDIR	0x03	/* receive DMA redirect */
#define	RUC_ABORT	0x40	/* abort RU */
#define	RUC_HDRSZ	0x50	/* load header data size */
#define	RUC_RUBASE	0x60	/* load RU base address */

#define	INTCTL_MASK	0x01	/* disable all interrupts */
#define	INTCTL_SI	0x02	/* generate software interrupt */
#define	INTCTL_FCP	0x04	/* flow control pause */
#define	INTCTL_ER	0x08	/* early receive */
#define	INTCTL_RNR	0x10	/* RU not ready */
#define	INTCTL_CNA	0x20	/* CU state change */
#define	INTCTL_FR	0x40	/* frame receive */
#define	INTCTL_CX	0x80	/* cmd exec done */

#define	PORT_SW_RESET	0x00
#define	PORT_SELF_TEST	0x01
#define	PORT_SEL_RESET	0x02

#define	EEPROM_EEDO	0x0008	/* data out */
#define	EEPROM_EEDI	0x0004	/* data in */
#define	EEPROM_EECS	0x0002	/* chip select */
#define	EEPROM_EESK	0x0001	/* clock */

#define	EEPROM_OP_RD	0x06
#define	EEPROM_OP_WR	0x05
#define	EEPROM_OP_WE	0x13	/* write enable */
#define	EEPROM_OP_WD	0x13	/* write disable */

#define	MDI_IE		0x20000000	/* interrupt enable */
#define	MDI_R		0x10000000	/* ready */
#define	MDI_OP_RD	0x08000000	/* read */
#define	MDI_OP_WR	0x04000000	/* write */
#define	MDI_PHYAD_SHIFT	21
#define	MDI_REGAD_SHIFT	16

#define	GET8(ip, offset)					\
	ddi_get8(ip->regsh, (void *)(ip->regs + (offset)))
#define	GET16(ip, offset)					\
	ddi_get16(ip->regsh, (void *)(ip->regs + (offset)))
#define	GET32(ip, offset)					\
	ddi_get32(ip->regsh, (void *)(ip->regs + (offset)))
#define	PUT8(ip, offset, val)						\
	ddi_put8(ip->regsh, (void *)(ip->regs + (offset)), (val))
#define	PUT16(ip, offset, val)						\
	ddi_put16(ip->regsh, (void *)(ip->regs + (offset)), (val))
#define	PUT32(ip, offset, val)						\
	ddi_put32(ip->regsh, (void *)(ip->regs + (offset)), (val))


#define	PUTDMA8(d, off, val)					\
	ddi_put8(d->acch, (void *)(d->vaddr + (off)), LE_8(val))
#define	PUTDMA16(d, off, val)						\
	ddi_put16(d->acch, (void *)(d->vaddr + (off)), LE_16(val))
#define	PUTDMA32(d, off, val)						\
	ddi_put32(d->acch, (void *)(d->vaddr + (off)), LE_32(val))
#define	GETDMA8(d, off)						\
	LE_8(ddi_get8(d->acch, (void *)(d->vaddr + (off))))
#define	GETDMA16(d, off)					\
	LE_16(ddi_get16(d->acch, (void *)(d->vaddr + (off))))
#define	GETDMA32(d, off)					\
	LE_32(ddi_get32(d->acch, (void *)(d->vaddr + (off))))
#define	SYNCDMA(d, off, size, dir)			\
	(void) ddi_dma_sync(d->dmah, off, size, dir)

/*
 * Command block offsets.
 */
#define	CB_STS_OFFSET		0
#define	CB_CMD_OFFSET		2
#define	CB_LNK_OFFSET		4
#define	CB_SIZE			2048	/* size of cmd blk */

#define	CB_IAS_ADR_OFFSET	8

#define	CB_MCS_CNT_OFFSET	8
#define	CB_MCS_ADR_OFFSET	10
#define	CB_MCS_CNT_MAX		((CB_SIZE - CB_MCS_ADR_OFFSET) / 6)

#define	CB_UCODE_OFFSET		8

#define	CB_CONFIG_OFFSET	8

#define	CB_TX_TBD_OFFSET	8
#define	CB_TX_COUNT_OFFSET	12
#define	CB_TX_EOF		0x8000
#define	CB_TX_THRESH_OFFSET	14
#define	CB_TX_NUMBER_OFFSET	15
#define	CB_TX_DATA_OFFSET	16

#define	PUTCB8(cb, o, v)	PUTDMA8(cb, o, v)
#define	PUTCB16(cb, o, v)	PUTDMA16(cb, o, v)
#define	PUTCB32(cb, o, v)	PUTDMA32(cb, o, v)
#define	PUTCBEA(cb, o, enet)						\
	ddi_rep_put8(cb->acch, enet, (void *)(cb->vaddr + (o)), 6,	\
	DDI_DEV_AUTOINCR);
#define	GETCB8(cb, o)		GETDMA8(cb, o)
#define	GETCB16(cb, o)		GETDMA16(cb, o)
#define	GETCB32(cb, o)		GETDMA32(cb, o)
#define	SYNCCB(cb, o, s, dir)	SYNCDMA(cb, o, s, dir)
/*
 * CB status bits.
 */
#define	CB_STS_OK		0x2000
#define	CB_STS_C		0x8000

/*
 * Commands.
 */
#define	CB_CMD_NOP		0x0
#define	CB_CMD_IAS		0x1
#define	CB_CMD_CONFIG		0x2
#define	CB_CMD_MCS		0x3
#define	CB_CMD_TX		0x4
#define	CB_CMD_UCODE		0x5
/* and flags to go with */
#define	CB_CMD_SF		0x0008	/* simple/flex */
#define	CB_CMD_I		0x2000	/* generate an interrupt */
#define	CB_CMD_S		0x4000	/* suspend on completion */
#define	CB_CMD_EL		0x8000	/* end of list */

/*
 * RFD offsets.
 */
#define	GETRFD16(r, o)		GETDMA16(r, o)
#define	PUTRFD16(r, o, v)	PUTDMA16(r, o, v)
#define	PUTRFD32(r, o, v)	PUTDMA32(r, o, v)
#define	SYNCRFD(r, o, s, dir)	SYNCDMA(r, o, s, dir)

#define	RFD_STS_OFFSET		0x00
#define	RFD_CTL_OFFSET		0x02
#define	RFD_LNK_OFFSET		0x04
#define	RFD_CNT_OFFSET		0x0c	/* bytes received */
#define	RFD_SIZ_OFFSET		0x0e	/* size of packet area */
#define	RFD_PKT_OFFSET		0x10
#define	RFD_SIZE		2048

#define	RFD_CTL_EL		0x8000
#define	RFD_CTL_S		0x4000
#define	RFD_CTL_H		0x0010
#define	RFD_CTL_SF		0x0008

#define	RFD_STS_C		0x8000
#define	RFD_STS_OK		0x2000
#define	RFD_STS_FCS		0x0800
#define	RFD_STS_ALIGN		0x0400
#define	RFD_STS_TOOBIG		0x0200
#define	RFD_STS_DMAOFLO		0x0100
#define	RFD_STS_TOOSHORT	0x0080
#define	RFD_STS_802		0x0020
#define	RFD_STS_RXERR		0x0010
#define	RFD_STS_NOMATCH		0x0004
#define	RFD_STS_IAMATCH		0x0002
#define	RFD_STS_COLL_TCO	0x0001
#define	RFD_STS_ERRS		0x0d90

#define	RFD_CNT_EOF		0x8000
#define	RFD_CNT_F		0x4000

/*
 * Stats offsets.
 */
#define	STATS_TX_GOOD_OFFSET	0
#define	STATS_TX_MAXCOL_OFFSET	4
#define	STATS_TX_LATECOL_OFFSET	8
#define	STATS_TX_UFLO_OFFSET	16
#define	STATS_TX_DEFER_OFFSET	20
#define	STATS_TX_ONECOL_OFFSET	24
#define	STATS_TX_MULTCOL_OFFSET	28
#define	STATS_TX_TOTCOL_OFFSET	32
#define	STATS_RX_GOOD_OFFSET	36
#define	STATS_RX_FCS_OFFSET	40
#define	STATS_RX_ALIGN_OFFSET	44
#define	STATS_RX_NOBUF_OFFSET	48
#define	STATS_RX_OFLO_OFFSET	52
#define	STATS_RX_COL_OFFSET	56
#define	STATS_RX_SHORT_OFFSET	60
#define	STATS_DONE_OFFSET	64
#define	STATS_SIZE		68
#define	STATS_DONE		0xa005
#define	STATS_RST_DONE		0xa007

#define	SYNCSTATS(sp, o, s, dir)	SYNCDMA(sp, o, s, dir)
#define	PUTSTAT(sp, o, v)		PUTDMA32(sp, o, v)
#define	GETSTAT(sp, o)			GETDMA32(sp, o)

#endif /* _IPRB_H */