summaryrefslogtreecommitdiff
path: root/usr/src/uts/common/io/vr/vr.h
blob: 29b0144272d6d3731b672f62a08710b9db7fac28 (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
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
/*
 * CDDL HEADER START
 *
 * The contents of this file are subject to the terms of the
 * Common Development and Distribution License (the "License").
 * You may not use this file except in compliance with the License.
 *
 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
 * or http://www.opensolaris.org/os/licensing.
 * See the License for the specific language governing permissions
 * and limitations under the License.
 *
 * When distributing Covered Code, include this CDDL HEADER in each
 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
 * If applicable, add the following below this CDDL HEADER, with the
 * fields enclosed by brackets "[]" replaced with your own identifying
 * information: Portions Copyright [yyyy] [name of copyright owner]
 *
 * CDDL HEADER END
 */

/*
 * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
 * Use is subject to license terms.
 */

#ifndef _VR_H
#define	_VR_H

#ifdef __cplusplus
	extern "C" {
#endif

/*
 * Number of descriptor entries for each ring. The no. of descriptors is bound
 * to 4K per ring (256 entries a 16 bytes).
 */
#define	VR_TX_N_DESC		128
#define	VR_RX_N_DESC		256

/*
 * The number of TX interrupts to "schedule" on the ring.
 */
#define	VR_TX_INTRS_RING	3

/*
 * The the periodic check interval of 2 seconds, in nano seconds
 */
#define	VR_CHECK_INTERVAL	(2000 * 1000 * 1000)

/*
 * The number of TX checks that must pass without progress before we decide
 * to reset the adapter.
 */
#define	VR_MAXTXCHECKS		12

/*
 * All possible interrupts with the unwanted commented.
 */
#define	VR_ICR0_CFG	(VR_ICR0_RX_DONE	| \
			    VR_ICR0_TX_DONE	| \
			    VR_ICR0_RX_ERR	| \
			    VR_ICR0_TX_ERR	| \
			    VR_ICR0_TX_BUF_UFLOW| \
			    VR_ICR0_RX_LINKERR	| \
			    VR_ICR0_BUSERR	| \
			    /* VR_ICR0_STATSMAX	| */ \
			    /* VR_ICR0_RX_EARLY	| */ \
			    VR_ICR0_TX_FIFO_UFLOW	| \
			    VR_ICR0_RX_FIFO_OFLOW	| \
			    VR_ICR0_RX_DROPPED	| \
			    VR_ICR0_RX_NOBUF  	| \
			    VR_ICR0_TX_ABORT	| \
			    VR_ICR0_LINKSTATUS	| \
			    VR_ICR0_GENERAL)

#define	VR_ICR1_CFG	(/* VR_ICR1_TIMER0	| */ \
			    /* VR_ICR1_TIMER1	| */ \
			    /* VR_ICR1_PHYEVENT	| */ \
			    /* VR_ICR1_TDERR	| */ \
			    /* VR_ICR1_SSRCI	| */ \
			    /* VR_ICR1_UINTR_SET| */ \
			    /* VR_ICR1_UINTR_CLR| */ \
			    /* VR_ICR1_PWEI */)

/*
 * Our definitions of RX and TX errors.
 */
#define	VR_ISR_TX_ERR_BITS	(VR_ICR0_TX_ERR | \
					VR_ICR0_TX_BUF_UFLOW | \
					VR_ICR0_TX_FIFO_UFLOW | \
					VR_ICR0_TX_ABORT)

#define	VR_ISR_RX_ERR_BITS	(VR_ICR0_RX_ERR | \
					VR_ICR0_RX_LINKERR | \
					VR_ICR0_RX_FIFO_OFLOW | \
					VR_ICR0_RX_DROPPED | \
					VR_ICR0_RX_NOBUF)

#define	VR_ISR_SYS_ERR_BITS	(VR_ICR0_BUSERR)

#define	VR_ISR_ERR_BITS		(VR_ISR_TX_ERR_BITS | \
					VR_ISR_RX_ERR_BITS | \
					VR_ISR_SYS_ERR_BITS)
#define	VR_TX_MAX_INTR_DISTANCE \
			(VR_TX_N_DESC / VR_TX_INTRS_RING)


#define	MODULENAME		"vr"	/* Our name */
#define	VR_SLOPSZ		2
#define	VR_MAX_PKTSZ		(ETHERMAX + ETHERFCSL + VLAN_TAGSZ + VR_SLOPSZ)
#define	VR_DMABUFSZ		(VR_MAX_PKTSZ)
#define	VR_MMI_WAITINCR		(10)
#define	VR_MMI_WAITMAX		(10000)
#define	VR_CAM_SZ		(32)

/*
 * PCI identification for the Rhine's.
 */
#define	VR_PCI_VIA_VENID		0x1106
#define	VR_PCI_DEVID_RHINE		0x3043
#define	VR_PCI_DEVID_RHINE_IIIM		0x3053
#define	VR_PCI_DEVID_RHINE_II2		0x3065
#define	VR_PCI_DEVID_RHINE_III		0x3106
#define	VR_PCI_DEVID_RHINE_II		0x6100

#define	VR_PCI_REVID_VT86C100A_E	0x04
#define	VR_PCI_REVID_VT6102_A		0x40
#define	VR_PCI_REVID_VT6102_C		0x42
#define	VR_PCI_REVID_VT6105_A0		0x80
#define	VR_PCI_REVID_VT6105_B0		0x83
#define	VR_PCI_REVID_VT6105_LOM		0x8A
#define	VR_PCI_REVID_VT6107_A0		0x8C
#define	VR_PCI_REVID_VT6107_A1		0x8D
#define	VR_PCI_REVID_VT6105M_A0		0x90
#define	VR_PCI_REVID_VT6105M_B1		0x94

/*
 * Feature bits for the different cards.
 */
#define	VR_FEATURE_NONE			(0)
#define	VR_FEATURE_RX_PAUSE_CAP		(1 << 0) /* can receive pauses */
#define	VR_FEATURE_TX_PAUSE_CAP		(1 << 1) /* can transmit pauses */
#define	VR_FEATURE_MRDLNMULTIPLE	(1 << 2) /* can read mult cache lines */
#define	VR_FEATURE_TXCHKSUM		(1 << 3) /* can do TX TCP checksum */
#define	VR_FEATURE_RXCHKSUM		(1 << 4) /* can do RX TCP checksum */
#define	VR_FEATURE_CAMSUPPORT		(1 << 5) /* has a CAM filter */
#define	VR_FEATURE_VLANTAGGING		(1 << 6) /* can do VLAN tagging */
#define	VR_FEATURE_MIBCOUNTER		(1 << 7) /* has a MIB counter */

/*
 * Bug bits for the different cards.
 */
#define	VR_BUG_NONE			(0)
#define	VR_BUG_TXALIGN			(1 << 0) /* needs aligned TX */
#define	VR_BUG_NEEDMODE10T		(1 << 1) /* chip needs mode10t secret */
#define	VR_BUG_NEEDMIION		(1 << 2) /* chip needs miion secret */
#define	VR_BUG_NEEDMODE2PCEROPT		(1 << 3) /* chip needs pceropt */
#define	VR_BUG_NO_TXQUEUEING		(1 << 4) /* chip cannot queue tx */
#define	VR_BUG_NO_MEMIO			(1 << 5) /* chip cannot memory space */
#define	VR_BUG_MIIPOLLSTOP		(1 << 6) /* special to stop polling */

#define	VR_GET8(acc, p)		\
		ddi_get8((acc)->hdl,	\
		    (uint8_t *)((void *)((acc)->addr + (p))))
#define	VR_GET16(acc, p)	\
		ddi_get16((acc)->hdl,	\
		    (uint16_t *)((void *)((acc)->addr + (p))))
#define	VR_GET32(acc, p)	\
		ddi_get32((acc)->hdl,	\
		    (uint32_t *)((void *)((acc)->addr + (p))))

#define	VR_PUT8(acc, p, v)	\
		ddi_put8((acc)->hdl,	\
		    (uint8_t *)((void *)((acc)->addr + (p))), v)
#define	VR_PUT16(acc, p, v)	\
		ddi_put16((acc)->hdl,	\
		    (uint16_t *)((void *)((acc)->addr + (p))), v)
#define	VR_PUT32(acc, p, v)	\
		ddi_put32((acc)->hdl,	\
		    (uint32_t *)((void *)((acc)->addr + (p))), v)

/*
 * Clear bit b in register r.
 */
#define	VR_CLRBIT8(acc, r, b)			\
		VR_PUT8(acc, r, VR_GET8(acc, r) & ~(b))
#define	VR_CLRBIT16(acc, r, b)			\
		VR_PUT16(acc, r, VR_GET16(acc, r) & ~(b))
#define	VR_CLRBIT32(acc, r, b)			\
		VR_PUT32(acc, r, VR_GET32(acc, r) & ~(b))

/*
 * Set bit b in register r.
 */
#define	VR_SETBIT8(acc, r, b)			\
		VR_PUT8(acc, r, (VR_GET8(acc, r) | (b)))
#define	VR_SETBIT16(acc, r, b)			\
		VR_PUT16(acc, r, (VR_GET16(acc, r) | (b)))
#define	VR_SETBIT32(acc, r, b)			\
		VR_PUT32(acc, r, (VR_GET32(acc, r) | (b)))

/*
 * Set bits b in register r to value v.
 */
#define	VR_SETBITS8(acc, r, b, v)			\
		VR_PUT8(acc, r, (VR_GET8(acc, r) & ~(b)) | (v))
#define	VR_SETBITS16(acc, r, b, v)			\
		VR_PUT16(acc, r, (VR_GET16(acc, r) & ~(b)) | (v))
#define	VR_SETBITS32(acc, r, b, v)			\
		VR_PUT32(acc, r, (VR_GET32(acc, r) & ~(b)) | (v))

/*
 * The descriptor as used by the MAC.
 */
typedef struct {
	uint32_t stat0;
	uint32_t stat1;
	uint32_t data;
	uint32_t next;
} vr_chip_desc_t;

/*
 * A structure describing an DMA object.
 */
typedef struct data_dma {
	ddi_dma_handle_t	handle;
	ddi_acc_handle_t	acchdl;
	uint32_t		paddr;
	char			*buf;
	size_t			bufsz;
} vr_data_dma_t;

/*
 * A descriptor as used by the host.
 */
typedef struct vr_desc {
	vr_chip_desc_t		*cdesc;
	uint32_t		paddr;		/* paddr of cdesc */
	uint32_t		offset;		/* offset to paddr */
	struct vr_desc		*next;
	vr_data_dma_t		dmabuf;
} vr_desc_t;

typedef struct vr_ring {
	vr_desc_t		*desc;
	vr_chip_desc_t		*cdesc;
	uint32_t		cdesc_paddr;
	ddi_dma_handle_t	handle;
	ddi_acc_handle_t	acchdl;
} vr_ring_t;

typedef struct {
	kmutex_t		lock;
	uint32_t		ndesc;
	uint32_t		nfree;
	uint32_t		stallticks;
	uint32_t		resched;
	uint32_t		intr_distance;
	vr_desc_t		*ring;
	vr_desc_t		*wp;			/* write pointer */
	vr_desc_t		*cp;			/* claim pointer */
} vr_tx_t;

typedef struct {
	uint32_t		ndesc;
	vr_desc_t		*ring;
	vr_desc_t		*rp;			/* read pointer */
} vr_rx_t;

typedef enum {
	VR_LINK_STATE_UNKNOWN = LINK_STATE_UNKNOWN,
	VR_LINK_STATE_DOWN = LINK_STATE_DOWN,
	VR_LINK_STATE_UP = LINK_STATE_UP
} vr_link_state_t;

typedef enum {
	VR_LINK_SPEED_UNKNOWN,
	VR_LINK_SPEED_10MBS,
	VR_LINK_SPEED_100MBS
} vr_link_speed_t;

typedef enum {
	VR_LINK_DUPLEX_UNKNOWN = LINK_DUPLEX_UNKNOWN,
	VR_LINK_DUPLEX_FULL = LINK_DUPLEX_FULL,
	VR_LINK_DUPLEX_HALF = LINK_DUPLEX_HALF
} vr_link_duplex_t;

typedef enum {
	VR_LINK_AUTONEG_UNKNOWN,
	VR_LINK_AUTONEG_OFF,
	VR_LINK_AUTONEG_ON
} vr_link_autoneg_t;

/*
 * Pause variations.
 */
typedef enum {
	VR_PAUSE_UNKNOWN,
	VR_PAUSE_NONE = LINK_FLOWCTRL_NONE,
	VR_PAUSE_TRANSMIT = LINK_FLOWCTRL_TX,
	VR_PAUSE_RECEIVE = LINK_FLOWCTRL_RX,
	VR_PAUSE_BIDIRECTIONAL = LINK_FLOWCTRL_BI
} vr_link_flowctrl_t;

/*
 * Type of medium attachement unit.
 */
typedef enum {
	VR_MAU_UNKNOWN = XCVR_UNDEFINED,
	VR_MAU_NONE = XCVR_NONE,
	VR_MAU_10 = XCVR_10,
	VR_MAU_100T4 = XCVR_100T4,
	VR_MAU_100X = XCVR_100X,
	VR_MAU_100T2 = XCVR_100T2,
	VR_MAU_1000X = XCVR_1000X,
	VR_MAU_1000T = XCVR_1000T
} vr_mau_t;

typedef struct {
	vr_link_state_t		state;
	vr_link_speed_t		speed;
	vr_link_duplex_t	duplex;
	vr_link_flowctrl_t	flowctrl;
	vr_mau_t		mau;
} vr_link_t;

typedef enum {
	CHIPSTATE_UNKNOWN,
	CHIPSTATE_INITIALIZED,
	CHIPSTATE_RUNNING,
	CHIPSTATE_STOPPED,
	CHIPSTATE_SLEEPING,
	CHIPSTATE_SUSPENDED,
	CHIPSTATE_SUSPENDED_RUNNING,
	CHIPSTATE_ERROR
} vr_chip_state_t;

typedef struct {
	uint16_t	control;
	uint16_t	status;
	uint16_t	identh;
	uint16_t	identl;
	uint16_t	anadv;
	uint16_t	lpable;
	uint16_t	anexp;
} mii_t;

/*
 * A structure defining the various types of cards and their habits.
 */
typedef struct {
	uint8_t		revmin;
	uint8_t		revmax;
	char		name[128];
	uint32_t	bugs;
	uint32_t	features;
} chip_info_t;

/*
 * A structure describing the card.
 */
typedef struct {
	uint16_t		vendor;
	uint16_t		device;
	uint8_t			revision;
	vr_chip_state_t		state;
	mii_t			mii;
	vr_link_t		link;
	chip_info_t		info;
	uint32_t		phyaddr;
} vr_chip_t;

/*
 * Operational parameters.
 */
typedef struct {
	uint16_t		anadv_en;
	uint16_t		an_phymask;
	uint16_t		an_macmask;
	vr_link_autoneg_t	an_en;
	uint32_t		mtu;
} vr_param_t;

typedef enum {
	VR_SUCCESS = 0,
	VR_FAILURE = 1
} vr_result_t;

typedef struct {
	uint64_t	ether_stat_align_errors;
	uint64_t	ether_stat_carrier_errors;
	uint64_t	ether_stat_ex_collisions;
	uint64_t	ether_stat_fcs_errors;
	uint64_t	ether_stat_first_collisions;
	uint64_t	ether_stat_macrcv_errors;
	uint64_t	ether_stat_macxmt_errors;
	uint64_t	ether_stat_multi_collisions;
	uint64_t	ether_stat_toolong_errors;
	uint64_t	ether_stat_tooshort_errors;
	uint64_t	ether_stat_tx_late_collisions;
	uint64_t	ether_stat_defer_xmts;
	uint64_t	mac_stat_brdcstrcv;
	uint64_t	mac_stat_brdcstxmt;
	uint64_t	mac_stat_multixmt;
	uint64_t	mac_stat_collisions;
	uint64_t	mac_stat_ierrors;
	uint64_t	mac_stat_ipackets;
	uint64_t	mac_stat_multircv;
	uint64_t	mac_stat_norcvbuf;
	uint64_t	mac_stat_noxmtbuf;
	uint64_t	mac_stat_obytes;
	uint64_t	mac_stat_opackets;
	uint64_t	mac_stat_rbytes;
	uint64_t	mac_stat_underflows;
	uint64_t	mac_stat_overflows;
	uint64_t	cyclics;
	uint64_t	txchecks;
	uint64_t	intr_claimed;
	uint64_t	intr_unclaimed;
	uint64_t	linkchanges;
	uint64_t	txcpybytes;
	uint64_t	txmapbytes;
	uint64_t	rxcpybytes;
	uint64_t	rxmapbytes;
	uint64_t	txreclaim0;
	uint64_t	txreclaims;
	uint32_t	txstalls;
	uint32_t	resets;
	uint32_t	allocbfail;
} vr_stats_t;

/*
 * Access attributes for the card.
 */
typedef struct {
	ddi_acc_handle_t	hdl;
	caddr_t			addr;
	pci_regspec_t		reg;
} vr_acc_t;

/*
 * Instance state structure.
 */
typedef struct {
	kmutex_t		oplock;
	dev_info_t		*devinfo;
	uint8_t			vendor_ether_addr [ETHERADDRL];
	char			ifname[12];
	mac_handle_t		machdl;
	ddi_intr_handle_t	intr_hdl;
	uint_t			intr_pri;
	kmutex_t		intrlock;
	vr_chip_t		chip;
	vr_ring_t		txring;
	vr_ring_t		rxring;
	vr_rx_t			rx;
	vr_tx_t			tx;
	ddi_periodic_t		periodic_id;
	int			nsets;
	vr_acc_t		*regset;
	vr_acc_t		*acc_mem;
	vr_acc_t		*acc_io;
	vr_acc_t		*acc_cfg;
	vr_acc_t		*acc_reg;
	vr_param_t		param;
	vr_stats_t		stats;
	struct kstat		*ksp;
	vr_param_t		defaults;
	uint32_t		promisc;
	uint32_t		mhash0;
	uint32_t		mhash1;
	uint32_t		mcount;
	uint32_t		reset;
} vr_t;

/*
 * Function prototypes.
 */
int			vr_mac_getstat(void *arg, uint_t stat, uint64_t *val);
int			vr_mac_start(void *vrp);
void			vr_mac_stop(void *vrp);
int			vr_mac_set_promisc(void *vrp, boolean_t promiscflag);
int			vr_mac_set_multicast(void *vrp, boolean_t add,
			    const uint8_t *mca);
int			vr_mac_set_ether_addr(void *vrp,
			    const uint8_t *macaddr);
mblk_t			*vr_mac_tx_enqueue_list(void *p, mblk_t *mp);
int			vr_mac_getprop(void *arg, const char *pr_name,
			    mac_prop_id_t pr_num, uint_t pr_valsize,
			    void *pr_val);
int			vr_mac_setprop(void *arg, const char *pr_name,
			    mac_prop_id_t pr_num,
			    uint_t pr_valsize, const void *pr_val);
void			vr_mac_propinfo(void *arg, const char *pr_name,
			    mac_prop_id_t pr_num, mac_prop_info_handle_t prh);
uint_t			vr_intr(caddr_t arg1, caddr_t arg2);
#ifdef __cplusplus
}
#endif
#endif	/* _VR_H */