summaryrefslogtreecommitdiff
path: root/usr/src/uts/common/io/sfe/sfe_util.h
blob: 6c8ca8fea401d719e2d5767472b3f8effea6b381 (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
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
/*
 *  sfe_util.h: header to support the gem layer used by Masa Murayama
 *
 * Copyright (c) 2002-2008 Masayuki Murayama.  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. Neither the name of the author nor the names of its contributors may be
 *    used to endorse or promote products derived from this software without
 *    specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 THE
 * COPYRIGHT OWNER OR CONTRIBUTORS 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.
 */

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

#ifndef _SFE_UTIL_H_
#define	_SFE_UTIL_H_
#include <sys/mac_provider.h>
#include <sys/mac_ether.h>

/*
 * Useful macros and typedefs
 */

#define	GEM_NAME_LEN	32

#define	GEM_TX_TIMEOUT		(drv_usectohz(5*1000000))
#define	GEM_TX_TIMEOUT_INTERVAL	(drv_usectohz(1*1000000))
#define	GEM_LINK_WATCH_INTERVAL	(drv_usectohz(1*1000000))	/* 1 sec */

/* general return code */
#define	GEM_SUCCESS	0
#define	GEM_FAILURE	(-1)

/* return code of gem_tx_done */
#define	INTR_RESTART_TX	0x80000000

typedef	int32_t		seqnum_t;

/*
 * I/O instructions
 */
#define	OUTB(dp, p, v)	\
	ddi_put8((dp)->regs_handle, \
		(void *)((caddr_t)((dp)->base_addr) + (p)), v)
#define	OUTW(dp, p, v)	\
	ddi_put16((dp)->regs_handle, \
		(void *)((caddr_t)((dp)->base_addr) + (p)), v)
#define	OUTL(dp, p, v)  \
	ddi_put32((dp)->regs_handle, \
	    (void *)((caddr_t)((dp)->base_addr) + (p)), v)
#define	OUTLINL(dp, p, v) \
	ddi_put32((dp)->regs_handle, \
	    (void *)((caddr_t)((dp)->base_addr) + (p)), v); \
	(void) INL((dp), (p))
#define	INB(dp, p)	\
	ddi_get8((dp)->regs_handle, \
		(void *)(((caddr_t)(dp)->base_addr) + (p)))
#define	INW(dp, p)	\
	ddi_get16((dp)->regs_handle, \
		(void *)(((caddr_t)(dp)->base_addr) + (p)))
#define	INL(dp, p)	\
	ddi_get32((dp)->regs_handle, \
		(void *)(((caddr_t)(dp)->base_addr) + (p)))

struct gem_stats {
	uint32_t	intr;

	uint32_t	crc;
	uint32_t	errrcv;
	uint32_t	overflow;
	uint32_t	frame;
	uint32_t	missed;
	uint32_t	runt;
	uint32_t	frame_too_long;
	uint32_t	norcvbuf;
	uint32_t	sqe;

	uint32_t	collisions;
	uint32_t	first_coll;
	uint32_t	multi_coll;
	uint32_t	excoll;
	uint32_t	xmit_internal_err;
	uint32_t	nocarrier;
	uint32_t	defer;
	uint32_t	errxmt;
	uint32_t	underflow;
	uint32_t	xmtlatecoll;
	uint32_t	noxmtbuf;
	uint32_t	jabber;

	uint64_t	rbytes;
	uint64_t	obytes;
	uint64_t	rpackets;
	uint64_t	opackets;
	uint32_t	rbcast;
	uint32_t	obcast;
	uint32_t	rmcast;
	uint32_t	omcast;
	uint32_t	rcv_internal_err;
};
#define	GEM_MAXTXSEGS		4
#define	GEM_MAXRXSEGS		1

#define	GEM_MAXTXFRAGS		8
#define	GEM_MAXRXFRAGS		4
/* TX buffer management */
struct txbuf {
	struct txbuf		*txb_next;

	/* pointer to original mblk */
	mblk_t			*txb_mp;

	/* dma mapping for current packet */
	ddi_dma_cookie_t	txb_dmacookie[GEM_MAXTXFRAGS];
	uint_t			txb_nfrags;

	/* bounce buffer management */
	ddi_dma_handle_t	txb_bdh;
	ddi_acc_handle_t	txb_bah;
	caddr_t			txb_buf;	/* vaddr of bounce buffer */
	uint64_t		txb_buf_dma;	/* paddr of bounce buffer */

	/* timeout management */
	clock_t			txb_stime;

	/* Hardware descriptor info */
	seqnum_t		txb_desc;
	int			txb_ndescs;
	uint64_t		txb_flag;
};


/* RX buffer management */
struct rxbuf {
	/* Hardware independent section */
	struct rxbuf		*rxb_next;
	struct gem_dev		*rxb_devp;

	/* dma mapping management */
	ddi_dma_handle_t	rxb_dh;
	caddr_t			rxb_buf;
	size_t			rxb_buf_len;
	ddi_dma_cookie_t	rxb_dmacookie[GEM_MAXRXFRAGS];
	uint_t			rxb_nfrags;

	/* bounce buffer management */
	ddi_acc_handle_t	rxb_bah;
};

struct mcast_addr {
	struct ether_addr	addr;
	uint32_t		hash;
};

#define	GEM_MAXMC		64
#define	GEM_MCALLOC		(sizeof (struct mcast_addr) * GEM_MAXMC)

#define	SUB(x, y)		((seqnum_t)((x) - (y)))
#define	SLOT(seqnum, size)	(((unsigned int)(seqnum)) & ((size)-1))

/*
 * mac soft state
 */
struct gem_dev {
	dev_info_t		*dip;
	mac_handle_t		mh;
	char			name[GEM_NAME_LEN];
	void			*base_addr;
	ddi_acc_handle_t	regs_handle;
	ddi_iblock_cookie_t	iblock_cookie;

	/* MAC address information */
	struct ether_addr	cur_addr;
	struct ether_addr	dev_addr;

	/* Descriptor rings, io area */
	ddi_dma_handle_t	desc_dma_handle;
	ddi_acc_handle_t	desc_acc_handle;
	caddr_t			rx_ring;
	caddr_t			tx_ring;
	caddr_t			io_area;
	/* caddr_t			rx_buf; */

	uint64_t		rx_ring_dma;
	uint64_t		tx_ring_dma;
	uint64_t		io_area_dma;

	/* RX slot ring management */
	kmutex_t		intrlock;
	boolean_t		intr_busy;
	seqnum_t		rx_active_head;
	seqnum_t		rx_active_tail;
	mac_resource_handle_t	mac_rx_ring_ha;
	/* Rx buffer management */
	struct rxbuf		*rx_buf_head;
	struct rxbuf		*rx_buf_tail;
	struct rxbuf		*rx_buf_freelist;
	int			rx_buf_allocated;
	int			rx_buf_freecnt;
	int			rx_buf_len;

	/* TX descriptor ring management */
	seqnum_t		tx_desc_head;
	seqnum_t		tx_desc_tail;
	seqnum_t		tx_desc_intr;

	/* TX buffur ring management */
	kmutex_t		xmitlock;
	kcondvar_t		tx_drain_cv;
	seqnum_t		tx_active_head;
	seqnum_t		tx_active_tail;
	seqnum_t		tx_softq_head;
	seqnum_t		tx_softq_tail;
	seqnum_t		tx_free_head;
	seqnum_t		tx_free_tail;
	int			tx_max_packets;

	/* TX buffer resource management */
	struct txbuf		*tx_buf;
	seqnum_t		tx_slots_base;

	/* TX state management */
	int			tx_busy;
	int			tx_reclaim_busy;
	clock_t			tx_blocked;

	/* NIC state */
	volatile boolean_t	mac_active;	/* tx and rx are running */
	volatile int		nic_state;	/* logical driver state */
#define	NIC_STATE_STOPPED	0
#define	NIC_STATE_INITIALIZED	1
#define	NIC_STATE_ONLINE	2
	volatile boolean_t	mac_suspended;

	/* robustness: timer and watchdog */
	volatile timeout_id_t	timeout_id;


	/* MII management */
	boolean_t		anadv_autoneg:1;
	boolean_t		anadv_1000fdx:1;
	boolean_t		anadv_1000hdx:1;
	boolean_t		anadv_100t4:1;
	boolean_t		anadv_100fdx:1;
	boolean_t		anadv_100hdx:1;
	boolean_t		anadv_10fdx:1;
	boolean_t		anadv_10hdx:1;
	boolean_t		anadv_flow_control:2;
	boolean_t		mii_advert_ro:1;

	boolean_t		full_duplex:1;
	int			speed:3;
#define		GEM_SPD_10	0
#define		GEM_SPD_100	1
#define		GEM_SPD_1000	2
#define		GEM_SPD_NUM	3
	unsigned int		flow_control:2;
#define		FLOW_CONTROL_NONE	0
#define		FLOW_CONTROL_SYMMETRIC	1
#define		FLOW_CONTROL_TX_PAUSE	2
#define		FLOW_CONTROL_RX_PAUSE	3

	boolean_t		mii_supress_msg:1;

	uint32_t		mii_phy_id;
	uint16_t		mii_status;
	uint16_t		mii_advert;
	uint16_t		mii_lpable;
	uint16_t		mii_exp;
	uint16_t		mii_ctl1000;
	uint16_t		mii_stat1000;
	uint16_t		mii_xstatus;
	int8_t			mii_phy_addr;	/* must be signed */

	uint8_t			mii_state;
#define		MII_STATE_UNKNOWN		0
#define		MII_STATE_RESETTING		1
#define		MII_STATE_AUTONEGOTIATING	2
#define		MII_STATE_AN_DONE		3
#define		MII_STATE_MEDIA_SETUP		4
#define		MII_STATE_LINKUP		5
#define		MII_STATE_LINKDOWN		6

	clock_t			mii_last_check;	/* in tick */
	clock_t			mii_timer;	/* in tick */
#define		MII_RESET_TIMEOUT	drv_usectohz(1000*1000)
#define		MII_AN_TIMEOUT		drv_usectohz(5000*1000)
#define		MII_LINKDOWN_TIMEOUT	drv_usectohz(10000*1000)
	clock_t			mii_interval;	/* in tick */
	clock_t			linkup_delay;	/* in tick */

	volatile timeout_id_t	link_watcher_id;

	ddi_softintr_t		soft_id;

	/* multcast list management */
	int16_t			mc_count;
	int16_t			mc_count_req;
	struct mcast_addr	*mc_list;
	uint32_t		rxmode;
#define		RXMODE_PROMISC		0x01
#define		RXMODE_ALLMULTI_REQ	0x02
#define		RXMODE_MULTI_OVF	0x04
#define		RXMODE_ENABLE		0x08
#define		RXMODE_ALLMULTI		(RXMODE_ALLMULTI_REQ | RXMODE_MULTI_OVF)
#define		RXMODE_BITS	\
			"\020"	\
			"\004ENABLE"	\
			"\003MULTI_OVF"	\
			"\002ALLMULTI_REQ"	\
			"\001PROMISC"

	/* statistcs */
	struct gem_stats		stats;

	/* pointer to local structure */
	void			*private;
	int			priv_size;

	/* polling mode */
	int			poll_pkt_delay;	/* in number of packets */

	/* descriptor area */
	int			tx_desc_size;
	int			rx_desc_size;

	/* configuration */
	struct gem_conf {
		/* name */
		char	gc_name[GEM_NAME_LEN];

		/* specification on tx and rx dma engine */
		long	gc_tx_buf_align;
		int	gc_tx_max_frags;
		int	gc_tx_max_descs_per_pkt;
		int	gc_tx_buf_size;
		int	gc_tx_buf_limit;
		int	gc_tx_desc_unit_shift;
		int	gc_tx_ring_size;
		int	gc_tx_ring_limit;
		int	gc_tx_copy_thresh;
		boolean_t gc_tx_auto_pad;
		boolean_t gc_tx_desc_write_oo;

		long	gc_rx_buf_align;
		int	gc_rx_max_frags;
		int	gc_rx_desc_unit_shift;
		int	gc_rx_ring_size;
		int	gc_rx_copy_thresh;
		int	gc_rx_buf_max;
		int	gc_rx_header_len;

		int	gc_io_area_size;

		/* memory mapping attributes */
		struct ddi_device_acc_attr	gc_dev_attr;
		struct ddi_device_acc_attr	gc_buf_attr;
		struct ddi_device_acc_attr	gc_desc_attr;

		/* dma attributes */
		ddi_dma_attr_t		gc_dma_attr_desc;
		ddi_dma_attr_t		gc_dma_attr_txbuf;
		ddi_dma_attr_t		gc_dma_attr_rxbuf;

		/* tx time out parameters */
		clock_t	gc_tx_timeout;
		clock_t	gc_tx_timeout_interval;

		/* auto negotiation capability */
		int		gc_flow_control;

		/* MII mode */
		int	gc_mii_mode;
#define		GEM_MODE_100BASETX	0
#define		GEM_MODE_1000BASET	1
#define		GEM_MODE_1000BASETX	2

		/* MII link state watch parameters */
		clock_t	gc_mii_linkdown_timeout;
		clock_t	gc_mii_link_watch_interval;
		clock_t	gc_mii_reset_timeout;

		clock_t	gc_mii_an_watch_interval;
		clock_t	gc_mii_an_timeout;
		clock_t	gc_mii_an_wait;
		clock_t	gc_mii_an_delay;

		/* MII configuration */
		int	gc_mii_addr_min;
		int	gc_mii_linkdown_action;
		int	gc_mii_linkdown_timeout_action;
#define		MII_ACTION_NONE		0
#define		MII_ACTION_RESET	1
#define		MII_ACTION_RSA		2
		boolean_t	gc_mii_dont_reset;
		boolean_t	gc_mii_an_oneshot;
		boolean_t	gc_mii_hw_link_detection;
		boolean_t	gc_mii_stop_mac_on_linkdown;

		/* I/O methods */

		/* mac operation */
		int	(*gc_attach_chip)(struct gem_dev *dp);
		int	(*gc_reset_chip)(struct gem_dev *dp);
		int	(*gc_init_chip)(struct gem_dev *dp);
		int	(*gc_start_chip)(struct gem_dev *dp);
		int	(*gc_stop_chip)(struct gem_dev *dp);
		uint32_t (*gc_multicast_hash)(struct gem_dev *dp, uint8_t *);
		int	(*gc_set_rx_filter)(struct gem_dev *dp);
		int	(*gc_set_media)(struct gem_dev *dp);
		int	(*gc_get_stats)(struct gem_dev *dp);
		uint_t	(*gc_interrupt)(struct gem_dev *dp);

		/* descriptor operation */
		int	(*gc_tx_desc_write)(struct gem_dev *dp, int slot,
				ddi_dma_cookie_t *dmacookie,
				int frags, uint64_t flag);
#define			GEM_TXFLAG_INTR		0x00000001ull
#define			GEM_TXFLAG_TCP		0x00000002ull
#define				GEM_TXFLAG_TCP_SHIFT		1ull
#define			GEM_TXFLAG_UDP		0x00000004ull
#define				GEM_TXFLAG_UDP_SHIFT		2ull
#define			GEM_TXFLAG_IPv4		0x00000008ull
#define				GEM_TXFLAG_IPv4_SHIFT		3ull
#define			GEM_TXFLAG_IPv6		0x00000010ull
#define				GEM_TXFLAG_IPv6_SHIFT		4ull
#define			GEM_TXFLAG_HEAD		0x00000020ull
#define			GEM_TXFLAG_TAIL		0x00000040ull
#define			GEM_TXFLAG_SWVTAG	0x00000080ull
#define			GEM_TXFLAG_PRIVATE	0x0000ff00ull
#define				GEM_TXFLAG_PRIVATE_SHIFT	8ull
#define				GEM_TXFLAG_PRIVATE_MASK	0xffull
#define			GEM_TXFLAG_VID		0x0fff0000ull
#define				GEM_TXFLAG_VID_SHIFT		16ull
#define				GEM_TXFLAG_VID_MASK		0xfffull
#define			GEM_TXFLAG_CFI		0x10000000ull
#define			GEM_TXFLAG_PRI		0xe0000000ull
#define				GEM_TXFLAG_PRI_SHIFT		29ull
#define				GEM_TXFLAG_PRI_MASK		0x7ull
#define			GEM_TXFLAG_VTAG		0xffff0000ull
#define				GEM_TXFLAG_VTAG_SHIFT		16ull
#define			GEM_TXFLAG_HCKSTART	0x000000ff00000000ull
#define				GEM_TXFLAG_HCKSTART_SHIFT	32ull
#define			GEM_TXFLAG_HCKSTUFF	0x0000ff0000000000ull
#define				GEM_TXFLAG_HCKSTUFF_SHIFT	40ull
#define			GEM_TXFLAG_TCPHLEN	0x0000ff0000000000ull
#define				GEM_TXFLAG_TCPHLEN_SHIFT	40ull
#define			GEM_TXFLAG_MSS		0xffff000000000000ull
#define				GEM_TXFLAG_MSS_SHIFT	48ull

		void (*gc_tx_start) (struct gem_dev *dp, int slot, int frags);
		void	(*gc_rx_desc_write)(struct gem_dev *dp, int slot,
			    ddi_dma_cookie_t *dmacookie, int frags);
		void	(*gc_rx_start)(struct gem_dev *dp, int slot, int frags);

		uint_t	(*gc_tx_desc_stat)
			(struct gem_dev *dp, int slot, int descs);
#define			GEM_TX_DONE	0x00010000
#define			GEM_TX_ERR	0x00020000


		uint64_t (*gc_rx_desc_stat)
				(struct gem_dev *dp, int slot, int frags);

#define			GEM_RX_CKSUM		0xffff000000000000ull
#define			GEM_RX_CKSUM_SHIFT	48
#define			GEM_RX_PRI		0x0000e00000000000ull
#define			GEM_RX_PRI_SHIFT	45
#define			GEM_RX_CFI		0x0000100000000000ull
#define			GEM_RX_VID		0x00000fff00000000ull
#define			GEM_RX_VID_SHIFT	32
#define			GEM_RX_VTAG		0x0000ffff00000000ull
#define			GEM_RX_VTAG_SHIFT	32

#define			GEM_RX_CKSUM_IPv6	0x00080000ul
#define			GEM_RX_CKSUM_IPv6_SHIFT	19
#define			GEM_RX_CKSUM_IPv4	0x00040000ul
#define			GEM_RX_CKSUM_IPv4_SHIFT	18
#define			GEM_RX_CKSUM_UDP	0x00020000ul
#define			GEM_RX_CKSUM_UDP_SHIFT	17
#define			GEM_RX_CKSUM_TCP	0x00010000ul
#define			GEM_RX_CKSUM_TCP_SHIFT	16
#define			GEM_RX_ERR		0x00008000ul
#define			GEM_RX_DONE		0x00004000ul
#define			GEM_RX_LEN		0x00003ffful	/* 16KB - 1 */

		void	(*gc_tx_desc_init)(struct gem_dev *dp, int slot);
		void	(*gc_rx_desc_init)(struct gem_dev *dp, int slot);
		void	(*gc_tx_desc_clean)(struct gem_dev *dp, int slot);
		void	(*gc_rx_desc_clean)(struct gem_dev *dp, int slot);

		/* mii operations */
		int	(*gc_mii_probe)(struct gem_dev *dp);
		int	(*gc_mii_init)(struct gem_dev *dp);
		int	(*gc_mii_config)(struct gem_dev *dp);
		void	(*gc_mii_sync)(struct gem_dev *dp);
		uint16_t (*gc_mii_read)(struct gem_dev *dp, uint_t reg);
		void (*gc_mii_write)(struct gem_dev *dp,
			uint_t reg, uint16_t val);
		void (*gc_mii_tune_phy)(struct gem_dev *dp);

		/* packet in/out operation for copy-style  */
		void (*gc_put_packet)(struct gem_dev *dp,
			mblk_t *, void *, size_t);
		mblk_t	*(*gc_get_packet)(struct gem_dev *dp,
			struct rxbuf *, size_t);
		int	gc_nports;

		/* hw checksum */
		uint32_t	gc_hck_rx_start;
	} gc;

	uint32_t	misc_flag;
#define		GEM_LSO			0x00000400
#define		GEM_CTRL_PKT		0x00000200
#define		GEM_SOFTINTR		0x00000100
#define		GEM_POLL_RXONLY		0x00000080
#define		GEM_VLAN_HARD		0x00000040
#define		GEM_VLAN_SOFT		0x00000020
#define		GEM_VLAN		(GEM_VLAN_HARD | GEM_VLAN_SOFT)
#define		GEM_CKSUM_HEADER_IPv4	0x00000010
#define		GEM_CKSUM_PARTIAL	0x00000008
#define		GEM_CKSUM_FULL_IPv6	0x00000004
#define		GEM_CKSUM_FULL_IPv4	0x00000002
#define		GEM_NOINTR		0x00000001

	volatile timeout_id_t	intr_watcher_id;

	uint_t	mtu;

	/* performance tuning parameters */
	uint_t	txthr;		/* tx fifo threshoold */
	uint_t	txmaxdma;	/* tx max dma burst size */
	uint_t	rxthr;		/* rx fifo threshoold */
	uint_t	rxmaxdma;	/* tx max dma burst size */

	/* kstat stuff */
	kstat_t	*ksp;

	/* multiple port device support */
	struct	gem_dev	*next;	/* pointer to next port on the same device */
	int		port;

	/* ndd stuff */
	caddr_t	nd_data_p;
	caddr_t	nd_arg_p;

#ifdef GEM_DEBUG_LEVEL
	int	tx_cnt;
#endif
};

/*
 * Exported functions
 */
boolean_t gem_get_mac_addr_conf(struct gem_dev *);
int gem_mii_probe_default(struct gem_dev *);
int gem_mii_config_default(struct gem_dev *);
boolean_t gem_mii_link_check(struct gem_dev *dp);
uint16_t gem_mii_read(struct gem_dev *, uint_t);
void gem_mii_write(struct gem_dev *, uint_t, uint16_t);
int gem_reclaim_txbuf(struct gem_dev *dp);
int gem_restart_nic(struct gem_dev *dp, uint_t flags);
#define	GEM_RESTART_NOWAIT	0x00000002
#define	GEM_RESTART_KEEP_BUF	0x00000001
boolean_t gem_tx_done(struct gem_dev *);
int gem_receive(struct gem_dev *);
int gem_receive_copy(struct gem_dev *);
struct gem_dev *gem_do_attach(dev_info_t *, int,
		struct gem_conf *, void *, ddi_acc_handle_t *, void *, int);

mblk_t *gem_send_common(struct gem_dev *, mblk_t *, uint32_t);
#define	GEM_SEND_COPY	0x00008000
#define	GEM_SEND_CTRL	0x000000ff	/* private flags for control packets */
#define	GEM_SEND_VTAG	0xffff0000
#define	GEM_SEND_VTAG_SHIFT	16

mblk_t *gem_get_packet_default(struct gem_dev *, struct rxbuf *, size_t);

uint32_t gem_ether_crc_le(const uint8_t *addr, int len);
uint32_t gem_ether_crc_be(const uint8_t *addr, int len);
int gem_do_detach(dev_info_t *);

int gem_getlongprop_buf(dev_t dev, dev_info_t *dip,
	int flags, char *name, void *buf, int *lenp);
int gem_getprop(dev_t dev, dev_info_t *dip,
	int flags, char *name, int defvalue);

struct rxbuf *gem_get_rxbuf(struct gem_dev *, int);

void gem_rx_desc_dma_sync(struct gem_dev *, int, int, int);
void gem_tx_desc_dma_sync(struct gem_dev *, int, int, int);

int gem_resume(dev_info_t *);
int gem_suspend(dev_info_t *);
uint8_t gem_search_pci_cap(dev_info_t *dip, ddi_acc_handle_t, uint8_t);
int gem_pci_set_power_state(dev_info_t *, ddi_acc_handle_t, uint_t);
int gem_pci_regs_map_setup(dev_info_t *, uint32_t, uint32_t,
	struct ddi_device_acc_attr *, caddr_t *, ddi_acc_handle_t *);
void gem_mod_init(struct dev_ops *, char *);
void gem_mod_fini(struct dev_ops *);

#define	GEM_GET_DEV(dip) \
	((struct gem_dev *)(ddi_get_driver_private(dip)))
#endif /* _SFE_UTIL_H_ */