summaryrefslogtreecommitdiff
path: root/usr/src/uts/common/sys/fibre-channel/fca/qlge/qlge.h
blob: 414336bc0fdb808ea57215494dd26b101413face (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
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
/*
 * 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 QLogic Corporation. All rights reserved.
 */

#ifndef _QLGE_H
#define	_QLGE_H

#ifdef __cplusplus
extern "C" {
#endif

#include <sys/ddi.h>
#include <sys/sunddi.h>
#include <sys/sunmdi.h>
#include <sys/modctl.h>
#include <sys/pci.h>
#include <sys/dlpi.h>
#include <sys/sdt.h>
#include <sys/mac_provider.h>
#include <sys/mac.h>
#include <sys/mac_flow.h>
#include <sys/mac_ether.h>
#include <sys/vlan.h>
#include <sys/netlb.h>
#include <sys/kmem.h>
#include <sys/file.h>
#include <sys/proc.h>
#include <sys/callb.h>
#include <sys/disp.h>
#include <sys/strsun.h>
#include <sys/ethernet.h>
#include <sys/miiregs.h>
#include <sys/kstat.h>
#include <sys/byteorder.h>
#include <sys/ddifm.h>
#include <sys/fm/protocol.h>
#include <sys/fm/util.h>
#include <sys/fm/io/ddi.h>

#include <qlge_hw.h>
#include <qlge_dbg.h>
#include <qlge_open.h>

#define	ADAPTER_NAME		"qlge"

/*
 * Local Macro Definitions.
 */
#ifdef  TRUE
#undef  TRUE
#endif
#define	TRUE	1

#ifdef  FALSE
#undef  FALSE
#endif
#define	FALSE	0

/* #define QLGE_TRACK_BUFFER_USAGE */
/*
 * byte order, sparc is big endian, x86 is little endian,
 * but PCI is little endian only
 */
#ifdef sparc
#define	cpu_to_le64(x)	BSWAP_64(x)
#define	cpu_to_le32(x)	BSWAP_32(x)
#define	cpu_to_le16(x)	BSWAP_16(x)
#define	le64_to_cpu(x)	cpu_to_le64(x)
#define	le32_to_cpu(x)	cpu_to_le32(x)
#define	le16_to_cpu(x)	cpu_to_le16(x)
#else
#define	cpu_to_le64(x)	(x)
#define	cpu_to_le32(x)	(x)
#define	cpu_to_le16(x)	(x)
#define	le64_to_cpu(x)	(x)
#define	le32_to_cpu(x)	(x)
#define	le16_to_cpu(x)	(x)
#endif

/*
 * Macros to help code, maintain, etc.
 */

#define	LSB(x)			(uint8_t)(x)
#define	MSB(x)			(uint8_t)((uint16_t)(x) >> 8)

#define	MSW(x)			(uint16_t)((uint32_t)(x) >> 16)
#define	LSW(x)			(uint16_t)(x)

#define	MS32(x)			(uint32_t)((uint32_t)(x) >> 32)
#define	LS32(x)			(uint32_t)(x)

#define	MSW_LSB(x)		(uint8_t)(LSB(MSW(x)))
#define	MSW_MSB(x)		(uint8_t)(MSB(MSW(x)))

#define	LSD(x)			(uint32_t)(x)
#define	MSD(x)			(uint32_t)((uint64_t)(x) >> 32)

#define	SHORT_TO_LONG(a, b)	(uint32_t)((uint16_t)b << 16 | (uint16_t)a)
#define	CHAR_TO_SHORT(a, b)	(uint16_t)((uint8_t)b << 8 | (uint8_t)a)

#define	SWAP_ENDIAN_16(x)	((LSB(x) << 8) | MSB(x))

#define	SWAP_ENDIAN_32(x)	((SWAP_ENDIAN_16(LSW(x)) << 16) | \
				    SWAP_ENDIAN_16(MSW(x)))

#define	SWAP_ENDIAN_64(x)	((SWAP_ENDIAN_32(LS32(x)) << 32) | \
				    SWAP_ENDIAN_32(MS32(x)))

#define	QL_MIN(x, y)		((x < y) ? x : y)

#define	CARRIER_ON(qlge)	mac_link_update((qlge)->mh, LINK_STATE_UP)
#define	CARRIER_OFF(qlge)	mac_link_update((qlge)->mh, LINK_STATE_DOWN)

/*
 * qlge local function return status codes
 */
#define	QL_ERROR		1
#define	QL_SUCCESS		0
/*
 * Solaris version compatibility definitions.
 */
#define	QL_GET_LBOLT(timer)	timer = ddi_get_lbolt()
#define	QL_DMA_XFER_COUNTER	(uint64_t)0xffffffff
#define	QL_DRIVER_NAME(dip)	ddi_driver_name(ddi_get_parent(dip))

#define	MINOR_NODE_FLAG		8

/*
 * Host adapter default definitions.
 */

/* Timeout timer counts in seconds (must greater than 1 second). */
#define	USEC_PER_TICK		drv_hztousec(1)
#define	TICKS_PER_SEC		drv_usectohz(1000000)
#define	QL_ONE_SEC_DELAY	1000000
#define	QL_ONE_MSEC_DELAY	1000
#define	TX_TIMEOUT		3*TICKS_PER_SEC
/*
 * DMA attributes definitions.
 */
#define	QL_DMA_LOW_ADDRESS		(uint64_t)0
#define	QL_DMA_HIGH_64BIT_ADDRESS	(uint64_t)0xffffffffffffffffull
#define	QL_DMA_HIGH_32BIT_ADDRESS	(uint64_t)0xffffffff
#define	QL_DMA_ADDRESS_ALIGNMENT	(uint64_t)8
#define	QL_DMA_ALIGN_8_BYTE_BOUNDARY	(uint64_t)BIT_3
#define	QL_DMA_RING_ADDRESS_ALIGNMENT	(uint64_t)64
#define	QL_DMA_ALIGN_64_BYTE_BOUNDARY	(uint64_t)BIT_6
#define	QL_DMA_BURSTSIZES		0xfff
#define	QL_DMA_MIN_XFER_SIZE		1
#define	QL_DMA_MAX_XFER_SIZE		(uint64_t)0xffffffff
#define	QL_DMA_SEGMENT_BOUNDARY		(uint64_t)0xffffffff
#define	QL_DMA_GRANULARITY		1
#define	QL_DMA_XFER_FLAGS		0
#define	QL_MAX_COOKIES			16

/*
 * ISP PCI Configuration.
 */
#define	QL_INTR_INTERVAL	128	/* default interrupt interval 128us */
#define	QL_INTR_PKTS		8	/* default packet count threshold 8us */

/* GLD */
#define	QL_STREAM_OPS(dev_ops, attach, detach)	\
	DDI_DEFINE_STREAM_OPS(dev_ops, nulldev, nulldev, attach, detach, \
	    nodev, NULL, D_MP, NULL, ql_quiesce)

#define	QL_GET_DEV(dip)		((qlge_t *)(ddi_get_driver_private(dip)))
#define	RESUME_TX(tx_ring)		mac_tx_update(tx_ring->qlge->mh);
#define	RX_UPSTREAM(rx_ring, mp)	mac_rx(rx_ring->qlge->mh, \
					    rx_ring->qlge->handle, mp);

/* GLD DMA */
extern ddi_device_acc_attr_t ql_dev_acc_attr;
extern ddi_device_acc_attr_t ql_desc_acc_attr;
extern ddi_device_acc_attr_t ql_buf_acc_attr;

struct dma_info {
	void		 *vaddr;
	ddi_dma_handle_t dma_handle;
	ddi_acc_handle_t acc_handle;
	uint64_t	 dma_addr;
	size_t		 mem_len; /* allocated size */
	offset_t	 offset;  /* relative to handle	*/
};

/*
 * Sync a DMA area described by a dma_info
 */
#define	DMA_SYNC(area, flag)	((void) ddi_dma_sync((area).dma_handle,	\
				    (area).offset, (area).mem_len, (flag)))

/*
 * Find the (kernel virtual) address of block of memory
 * described by a dma_info
 */
#define	DMA_VPTR(area)		((area).vaddr)

/*
 * Zero a block of memory described by a dma_info
 */
#define	DMA_ZERO(area)		bzero(DMA_VPTR(area), (area).mem_len)

#define	MAX_SG_ELEMENTS		16
#define	QL_MAX_TX_DMA_HANDLES	MAX_SG_ELEMENTS
#define	TOTAL_SG_ELEMENTS	(MAX_SG_ELEMENTS + TX_DESC_PER_IOCB)

/*
 * ISP PCI Configuration.
 */

/* Initialize steps */
#define	INIT_SOFTSTATE_ALLOC 		BIT_0
#define	INIT_REGS_SETUP			BIT_1
#define	INIT_DOORBELL_REGS_SETUP	BIT_2
#define	INIT_MAC_ALLOC			BIT_3
#define	INIT_PCI_CONFIG_SETUP   	BIT_4
#define	INIT_SETUP_RINGS		BIT_5
#define	INIT_MEMORY_ALLOC		BIT_6
#define	INIT_INTR_ALLOC			BIT_7
#define	INIT_ADD_INTERRUPT		BIT_8
#define	INIT_LOCKS_CREATED		BIT_9
#define	INIT_ADD_SOFT_INTERRUPT		BIT_10
#define	INIT_MUTEX			BIT_11
#define	ADAPTER_INIT			BIT_12
#define	INIT_MAC_REGISTERED		BIT_13
#define	INIT_KSTATS			BIT_14
#define	INIT_FM				BIT_15
#define	INIT_ADAPTER_UP			BIT_16
#define	INIT_ALLOC_RX_BUF		BIT_17
#define	INIT_INTR_ENABLED		BIT_18


#define	LS_64BITS(x)	(uint32_t)(0xffffffff & ((uint64_t)x))
#define	MS_64BITS(x)	(uint32_t)(0xffffffff & (((uint64_t)x)>>16>>16))

typedef uint64_t dma_addr_t;
extern int ql_quiesce(dev_info_t *dip);

/*
 * LSO can support up to 65535 bytes of data, but can not be sent in one IOCB
 * which only has 8 TX OALs, additional OALs must be applied separately.
 */
#define	QL_LSO_MAX		65535 /* Maximum supported LSO data Length */

enum tx_mode_t {
	USE_DMA,
	USE_COPY
};

#define	QL_MAX_COPY_LENGTH	256

#define	MAX_FRAGMENTS_IN_IOCB	7

#ifndef VLAN_ID_MASK
#define	VLAN_ID_MASK		0x0fffu
#endif
#ifndef VLAN_TAGSZ
#define	VLAN_TAGSZ		4
#endif

#ifndef	ETHERTYPE_VLAN
#define	ETHERTYPE_VLAN		0x8100
#endif

#ifndef	MBLKL
#define	MBLKL(mp)	((uintptr_t)(mp)->b_wptr - (uintptr_t)(mp)->b_rptr)
#endif
/*
 * Checksum Offload
 */
#define	TCP_CKSUM_OFFSET	16
#define	UDP_CKSUM_OFFSET	6
#define	IPPROTO_IPv6OVERv4	41

/*
 * Driver must be in one of these states
 */
enum mac_state {
	QL_MAC_INIT,		/* in the initialization stage */
	QL_MAC_ATTACHED,	/* driver attached */
	QL_MAC_STARTED,		/* interrupt enabled, driver is ready */
	QL_MAC_BRINGDOWN,	/* in the bring down process */
	QL_MAC_STOPPED,		/* stoped, no more interrupts */
	QL_MAC_DETACH,		/* to be detached */
	QL_MAC_SUSPENDED
};

/*
 * Soft Request Flag
 */
#define	NEED_HW_RESET	BIT_0	/* need hardware reset */
#define	NEED_MPI_RESET	BIT_1	/* need MPI RISC reset */

/*
 * (Internal) return values from ioctl subroutines
 */
enum ioc_reply {
	IOC_INVAL = -1,			/* bad, NAK with EINVAL	*/
	IOC_DONE,			/* OK, reply sent	*/
	IOC_ACK,			/* OK, just send ACK	*/
	IOC_REPLY,			/* OK, just send reply	*/
	IOC_RESTART_ACK,		/* OK, restart & ACK	*/
	IOC_RESTART_REPLY		/* OK, restart & reply	*/
};

/*
 * Link Speed,in Mbps
 */
#define	SPEED_10		10
#define	SPEED_100		100
#define	SPEED_1000		1000
#define	SPEED_10G		10000

/*
 * Multicast List
 */
typedef struct {
	struct ether_addr	addr;
	unsigned char		reserved[2];
} ql_multicast_addr;

#define	MAX_MULTICAST_LIST_SIZE	128

typedef struct {
	struct ether_addr	addr;		/* in canonical form	*/
	boolean_t		set;		/* B_TRUE => valid	*/
} qlge_mac_addr_t;

#define	MAX_UNICAST_LIST_SIZE	128

/*
 * Device kstate structure.
 */
enum {
	QL_KSTAT_CHIP = 0,
	QL_KSTAT_LINK,
	QL_KSTAT_REG,
	QL_KSTAT_COUNT
};

/*
 * Register Bit Set/Reset
 */
enum {
	BIT_SET = 0,
	BIT_RESET
};

/*
 * Flash Image Search State
 */
enum {	STOP_SEARCH,		/* Image address bad, no more search */
	CONTINUE_SEARCH,	/* Image address ok, continue search */
	LAST_IMAGE_FOUND	/* Found last image and FLTDS address */
};

/*
 * Loop Back Modes
 */
enum {	QLGE_LOOP_NONE,
	QLGE_LOOP_INTERNAL_PARALLEL,
	QLGE_LOOP_INTERNAL_SERIAL,
	QLGE_LOOP_EXTERNAL_PHY
};

/* for soft state routine */
typedef struct {
	offset_t	index;
	char		*name;
} ql_ksindex_t;

struct bq_desc {
	struct		dma_info bd_dma;
	struct		bq_desc *next;
	struct		rx_ring *rx_ring;
	mblk_t		*mp;
	frtn_t		rx_recycle;	/* recycle function - called after mp */
					/* is to be freed by OS */
	uint16_t	index;
	uint16_t	free_buf;	/* Set to indicate the buffer is */
					/* being freed, new one should not */
					/* be allocated */
	uint32_t	upl_inuse;	/* buffer in use by upper layers */
};

#define	VM_PAGE_SIZE		4096

#define	QLGE_POLL_ALL		-1

#define	SMALL_BUFFER_SIZE	512
#define	LARGE_BUFFER_SIZE	4096

#define	MAX_TX_WAIT_COUNT	1000
#define	MAX_RX_WAIT_COUNT	25	/* 25 second */

#define	MIN_BUFFERS_ARM_COUNT	16
#define	MIN_BUFFERS_FREE_COUNT	32	/* If free buffer count go over this */
					/* value, arm the chip */
/* if less than 16 free lrg buf nodes in the free list, then */
/* rx has to use copy method to send packets upstream */
#define	RX_COPY_MODE_THRESHOLD	(MIN_BUFFERS_ARM_COUNT/4)
/* if there are more than TX_STOP_THRESHOLD free tx buffers, try to send it */
#define	TX_STOP_THRESHOLD	16
#define	TX_RESUME_THRESHOLD	8

struct tx_ring_desc {
	struct ob_mac_iocb_req *queue_entry;	/* tx descriptor of this */
	struct dma_info		dma_mem_area;	/* tx buffer */
	ddi_dma_handle_t	tx_dma_handle[QL_MAX_TX_DMA_HANDLES];
	int			tx_dma_handle_used;
	enum tx_mode_t		tx_type;	/* map mode or copy mode */
	mblk_t			*mp;		/* requested sending packet */
	uint32_t		index;
	caddr_t			copy_buffer;
	uint64_t		copy_buffer_dma_addr;
	struct dma_info		oal_dma;	/* oal is premapped */
	uint64_t		oal_dma_addr;	/* oal dma address premapped */
	uint32_t		tx_bytes;
	void			*oal;
};

struct tx_ring {
	struct qlge		*qlge;
	struct dma_info		wqicb_dma;
	uint16_t		cq_id;		/* completion (rx) queue for */
						/* tx completions */
	uint8_t			wq_id;
	uint32_t		wq_size;
	uint32_t		wq_len;
	kmutex_t		tx_lock;
	struct dma_info		wq_dma;
	volatile uint32_t	tx_free_count;
	uint32_t		tx_mode;
	boolean_t		queue_stopped;	/* Tx no resource */
	uint32_t		*prod_idx_db_reg;
	uint16_t		prod_idx;
	uint32_t		*valid_db_reg;	/* PCI doorbell mem area + 4 */
	struct tx_ring_desc	*wq_desc;
				/* shadow copy of consumer idx */
	uint32_t		*cnsmr_idx_sh_reg;
				/* dma-shadow copy consumer */
	uint64_t		cnsmr_idx_sh_reg_dma;
	uint32_t		defer;	/* tx no resource */
	uint64_t		obytes;
	uint64_t		opackets;
	uint32_t		errxmt;
	uint64_t		brdcstxmt;
	uint64_t		multixmt;
	uint64_t		tx_fail_dma_bind;
	uint64_t		tx_no_dma_handle;
	uint64_t		tx_no_dma_cookie;

	enum mac_state		mac_flags;
};

struct bq_element {
uint32_t addr_lo;
uint32_t addr_hi;
};

/*
 * Type of inbound queue.
 */
enum {
	DEFAULT_Q = 2,		/* Handles slow queue and chip/MPI events. */
	TX_Q = 3,		/* Handles outbound completions. */
	RX_Q = 4,		/* Handles inbound completions. */
};

struct rx_ring {
	struct dma_info		cqicb_dma;

	/* GLD required flags */
	uint64_t		ring_gen_num;
	/* statistics */
	uint64_t		rx_packets;
	uint64_t		rx_bytes;
	uint32_t		frame_too_long;
	uint32_t		frame_too_short;
	uint32_t		fcs_err;
	uint32_t		rx_packets_dropped_no_buffer;
	uint32_t		rx_pkt_dropped_mac_unenabled;
	volatile uint32_t	rx_indicate;

	/* miscellaneous */
	int			type; /* DEFAULT_Q, TX_Q, RX_Q */
	kmutex_t		rx_lock;
	uint32_t		irq;
	struct qlge		*qlge;
	uint32_t		cpu;	/* Which CPU this should run on. */
	enum mac_state		mac_flags;
	/* completion queue */
	struct dma_info		cq_dma;	/* virtual addr and phy addr */
	uint32_t		cq_size;
	uint32_t		cq_len;
	uint16_t		cq_id;
	off_t			prod_idx_sh_reg_offset;
	volatile uint32_t	*prod_idx_sh_reg;	/* Shadowed prod reg */
	uint64_t		prod_idx_sh_reg_dma;	/* Physical address */
	uint32_t		*cnsmr_idx_db_reg;	/* PCI db mem area 0 */
	uint32_t		cnsmr_idx;		/* current sw idx */
	struct net_rsp_iocb	*curr_entry;	/* next entry on queue */
	uint32_t		*valid_db_reg;	/* PCI doorbell mem area + 4 */

	/* large buffer queue */
	uint32_t 		lbq_len;		/* entry count */
	uint32_t		lbq_size;		/* size in bytes */
	uint32_t		lbq_buf_size;
	struct dma_info		lbq_dma;		/* lbq dma info */
	uint64_t		*lbq_base_indirect;
	uint64_t		lbq_base_indirect_dma;
	kmutex_t 		lbq_lock;
	struct bq_desc		**lbuf_in_use;
	volatile uint32_t	lbuf_in_use_count;
	struct bq_desc		**lbuf_free;
	volatile uint32_t	lbuf_free_count;	/* free lbuf desc cnt */
	uint32_t		*lbq_prod_idx_db_reg; /* PCI db mem area+0x18 */
	uint32_t		lbq_prod_idx;	/* current sw prod idx */
	uint32_t		lbq_curr_idx;	/* next entry we expect */
	uint32_t		lbq_free_tail;	/* free tail */
	uint32_t		lbq_free_head;	/* free head */
	uint32_t		lbq_use_tail;	/* inuse tail */
	uint32_t		lbq_use_head;	/* inuse head */

	struct bq_desc		*lbq_desc;

	/* small buffer queue */
	uint32_t		sbq_len;		/* entry count */
	uint32_t		sbq_size;	/* size in bytes of queue */
	uint32_t		sbq_buf_size;
	struct dma_info		sbq_dma; 		/* sbq dma info */
	uint64_t		*sbq_base_indirect;
	uint64_t		sbq_base_indirect_dma;
	kmutex_t		sbq_lock;
	struct bq_desc		**sbuf_in_use;
	volatile uint32_t	sbuf_in_use_count;
	struct bq_desc		**sbuf_free;
	volatile uint32_t	sbuf_free_count; /* free buffer desc cnt */
	uint32_t		*sbq_prod_idx_db_reg; /* PCI db mem area+0x1c */
	uint32_t		sbq_prod_idx;	/* current sw prod idx */
	uint32_t		sbq_curr_idx;	/* next entry we expect */
	uint32_t		sbq_free_tail;	/* free tail */
	uint32_t		sbq_free_head;	/* free head */
	uint32_t		sbq_use_tail;	/* inuse tail */
	uint32_t		sbq_use_head;	/* inuse head */
	struct bq_desc		*sbq_desc;
	/* for test purpose */
	uint32_t		rx_failed_sbq_allocs;
	uint32_t		rx_failed_lbq_allocs;
	uint32_t		sbuf_copy_count;
	uint32_t		lbuf_copy_count;

#ifdef QLGE_PERFORMANCE
	uint32_t		hist[8];
#endif
};

struct intr_ctx {
	struct	qlge		*qlge;
	uint32_t		intr;
	uint32_t		hooked;
	uint32_t		intr_en_mask;
	uint32_t		intr_dis_mask;
	uint32_t		intr_read_mask;
				/*
				 * It's incremented for
				 * each irq handler that is scheduled.
				 * When each handler finishes it
				 * decrements irq_cnt and enables
				 * interrupts if it's zero.
				 */
	uint32_t		irq_cnt;
	uint_t			(*handler)(caddr_t, caddr_t);
};

struct tx_buf_desc {
	uint64_t		addr;
	uint32_t		len;
#define	TX_DESC_LEN_MASK	0x000fffff
#define	TX_DESC_C		0x40000000
#define	TX_DESC_E		0x80000000
};

typedef struct qlge {
	/*
	 * Solaris adapter configuration data
	 */
	dev_info_t		*dip;
	int			instance;
	ddi_acc_handle_t	dev_handle;
	caddr_t			iobase;
	ddi_acc_handle_t	dev_doorbell_reg_handle;
	caddr_t			doorbell_reg_iobase;
	pci_cfg_t		pci_cfg;
	ddi_acc_handle_t	pci_handle;
	uint32_t		page_size;
	uint32_t		sequence;
	struct intr_ctx		intr_ctx[MAX_RX_RINGS];
	struct dma_info		ricb_dma;
	/* fault management capabilities */
	int			fm_capabilities;
	boolean_t		fm_enable;
	enum mac_state		mac_flags;

	volatile uint32_t	cfg_flags;

#define	CFG_JUMBLE_PACKET		BIT_1
#define	CFG_RX_COPY_MODE		BIT_2
#define	CFG_SUPPORT_MULTICAST		BIT_3
#define	CFG_HW_UNABLE_PSEUDO_HDR_CKSUM	BIT_4
#define	CFG_CKSUM_HEADER_IPv4		BIT_5
#define	CFG_CKSUM_PARTIAL		BIT_6
#define	CFG_CKSUM_FULL_IPv4		BIT_7
#define	CFG_CKSUM_FULL_IPv6		BIT_8
#define	CFG_LSO				BIT_9
#define	CFG_SUPPORT_SCATTER_GATHER	BIT_10
#define	CFG_ENABLE_SPLIT_HEADER		BIT_11
#define	CFG_ENABLE_EXTENDED_LOGGING	BIT_15
	uint32_t			chksum_cap;
	volatile uint32_t		flags;
#define	CFG_CHIP_8100			BIT_16

#define	CFG_IST(qlge, cfgflags)		(qlge->cfg_flags & cfgflags)

	/* For Shadow Registers, used by adapter to write to host memory */
	struct dma_info		host_copy_shadow_dma_attr;
	/*
	 * Extra 2x8 bytes memory saving large/small buf queue base address
	 * for each CQICB and read by chip, new request since 8100
	 */
	struct dma_info		buf_q_ptr_base_addr_dma_attr;
	/*
	 * Debugging
	 */
	uint32_t		ql_dbgprnt;
	/*
	 * GLD
	 */
	mac_handle_t		mh;
	mac_resource_handle_t	handle;
	ql_stats_t		stats;
	kstat_t			*ql_kstats[QL_KSTAT_COUNT];
	/*
	 * mutex
	 */
	kmutex_t		gen_mutex;	/* general adapter mutex */
	kmutex_t		hw_mutex;	/* common hw(nvram)access */

	/*
	 * Generic timer
	 */
	timeout_id_t		ql_timer_timeout_id;
	clock_t			ql_timer_ticks;

	/*
	 * Interrupt
	 */
	int			intr_type;
	/* for legacy interrupt */
	ddi_iblock_cookie_t	iblock_cookie;
	/* for MSI and Fixed interrupts */
	ddi_intr_handle_t	*htable;	/* For array of interrupts */
	int			intr_cnt; /* # of intrs actually allocated */
	uint_t			intr_pri;	/* Interrupt priority */
	int			intr_cap;	/* Interrupt capabilities */
	size_t			intr_size;	/* size of the allocated  */
						/* interrupt handlers */
	/* Power management context. */
	uint8_t			power_level;
#define	LOW_POWER_LEVEL		(BIT_1 | BIT_0)
#define	MAX_POWER_LEVEL		0

	/*
	 * General NIC
	 */
	uint32_t		xgmac_sem_mask;
	uint32_t		xgmac_sem_bits;
	uint32_t		func_number;
	uint32_t		fn0_net;	/* network function 0 port */
	uint32_t		fn1_net;	/* network function 1 port */

	uint32_t		mtu;
	uint32_t		max_frame_size;
	uint32_t		port_link_state;
	uint32_t		speed;
	uint16_t		link_type;
	uint32_t		duplex;
	uint32_t		pause;	/* flow-control mode */
	uint32_t		loop_back_mode;
	uint32_t		lso_enable;
	uint32_t		dcbx_enable;	/* dcbx mode */
	/*
	 * PCI status
	 */
	uint16_t		vendor_id;
	uint16_t		device_id;

	/*
	 * Multicast list
	 */
	uint32_t		multicast_list_count;
	ql_multicast_addr	multicast_list[MAX_MULTICAST_LIST_SIZE];
	boolean_t		multicast_promisc;
	/*
	 * MAC address information
	 */
	struct ether_addr	dev_addr; /* ethernet address read from nvram */
	qlge_mac_addr_t		unicst_addr[MAX_UNICAST_LIST_SIZE];
	uint32_t		unicst_total; /* total unicst addresses */
	uint32_t		unicst_avail;
	/*
	 * Soft Interrupt handlers
	 */
	/* soft interrupt handle for MPI interrupt */
	ddi_softint_handle_t	mpi_event_intr_hdl;
	/* soft interrupt handle for asic reset */
	ddi_softint_handle_t	asic_reset_intr_hdl;
	/* soft interrupt handle for mpi reset */
	ddi_softint_handle_t	mpi_reset_intr_hdl;
	/*
	 * IOCTL
	 */
	/* new ioctl admin flags to work around the 1024 max data copy in&out */
	caddr_t			ioctl_buf_ptr;
	uint32_t		ioctl_buf_lenth;
	uint16_t		expected_trans_times;
	uint32_t		ioctl_total_length;
	uint32_t		ioctl_transferred_bytes;
	ql_mpi_coredump_t	ql_mpi_coredump;
	/*
	 * Mailbox lock and flags
	 */
	boolean_t		fw_init_complete;
	kmutex_t		mbx_mutex;
	boolean_t		mbx_wait_completion;
	kcondvar_t		cv_mbx_intr;
	mbx_data_t 		received_mbx_cmds;
	uint_t			max_read_mbx;
	firmware_version_info_t		fw_version_info;
	phy_firmware_version_info_t	phy_version_info;
	port_cfg_info_t			port_cfg_info;
	struct dma_info			ioctl_buf_dma_attr;

	/*
	 * Flash
	 */
	uint32_t		flash_fltds_addr;
	uint32_t		flash_flt_fdt_index;
	uint32_t		flash_fdt_addr;
	uint32_t		flash_fdt_size;
	uint32_t		flash_flt_nic_config_table_index;
	uint32_t		flash_nic_config_table_addr;
	uint32_t		flash_nic_config_table_size;
	uint32_t		flash_vpd_addr;
	ql_flash_info_t		flash_info;
	ql_fltds_t		fltds;
	ql_flt_t		flt;
	uint16_t		flash_len;	/* size of Flash memory */
	ql_nic_config_t		nic_config;
	flash_desc_t		fdesc;
	/*
	 * TX / RX
	 */
	clock_t			last_tx_time;
	boolean_t		rx_copy;
	uint16_t		rx_coalesce_usecs;
	uint16_t		rx_max_coalesced_frames;
	uint16_t		tx_coalesce_usecs;
	uint16_t		tx_max_coalesced_frames;
	uint32_t		payload_copy_thresh;

	uint32_t		xg_sem_mask;

	uint32_t		ip_hdr_offset;
	uint32_t		selected_tx_ring;

	struct rx_ring		rx_ring[MAX_RX_RINGS];
	struct tx_ring		tx_ring[MAX_TX_RINGS];
	uint32_t		rx_polls[MAX_RX_RINGS];
	uint32_t		rx_interrupts[MAX_RX_RINGS];

	int 			tx_ring_size;
	int 			rx_ring_size;
	uint32_t		rx_copy_threshold;
	uint32_t		rx_ring_count;
	uint32_t		rss_ring_count;
	uint32_t		tx_ring_first_cq_id;
	uint32_t		tx_ring_count;
	uint32_t		isr_stride;
#ifdef QLGE_TRACK_BUFFER_USAGE
	/* Count no of times the buffers fell below 32 */
	uint32_t		rx_sb_low_count[MAX_RX_RINGS];
	uint32_t		rx_lb_low_count[MAX_RX_RINGS];
	uint32_t		cq_low_count[MAX_RX_RINGS];
#endif
} qlge_t;


/*
 * Reconfiguring the network devices requires the net_config privilege
 * in Solaris 10+.
 */
extern int secpolicy_net_config(const cred_t *, boolean_t);

/*
 * Global Function Prototypes in qlge_dbg.c source file.
 */
extern int ql_fw_dump(qlge_t *);
extern uint8_t ql_get8(qlge_t *, uint32_t);
extern uint16_t ql_get16(qlge_t *, uint32_t);
extern uint32_t ql_get32(qlge_t *, uint32_t);
extern void ql_put8(qlge_t *, uint32_t, uint8_t);
extern void ql_put16(qlge_t *, uint32_t, uint16_t);
extern void ql_put32(qlge_t *, uint32_t, uint32_t);
extern uint32_t ql_read_reg(qlge_t *, uint32_t);
extern void ql_write_reg(qlge_t *, uint32_t, uint32_t);
extern void ql_dump_all_contrl_regs(qlge_t *);
extern int ql_wait_reg_bit(qlge_t *, uint32_t, uint32_t, int, uint32_t);
extern void ql_dump_pci_config(qlge_t *);
extern void ql_dump_host_pci_regs(qlge_t *);
extern void ql_dump_req_pkt(qlge_t *, struct ob_mac_iocb_req *, void *, int);
extern void ql_dump_cqicb(qlge_t *, struct cqicb_t *);
extern void ql_dump_wqicb(qlge_t *, struct wqicb_t *);
extern void ql_gld3_init(qlge_t *, mac_register_t *);
enum ioc_reply ql_chip_ioctl(qlge_t *, queue_t *, mblk_t *);
enum ioc_reply ql_loop_ioctl(qlge_t *, queue_t *, mblk_t *, struct iocblk *);
extern int ql_8xxx_binary_core_dump(qlge_t *, ql_mpi_coredump_t *);
/*
 * Global Data in qlge.c source file.
 */
extern void qlge_delay(clock_t usecs);
extern int ql_sem_spinlock(qlge_t *, uint32_t);
extern void ql_sem_unlock(qlge_t *, uint32_t);
extern int ql_sem_lock(qlge_t *, uint32_t, uint32_t);
extern int ql_init_misc_registers(qlge_t *);
extern int ql_init_mem_resources(qlge_t *);
extern int ql_do_start(qlge_t *);
extern int ql_do_stop(qlge_t *);
extern int ql_add_to_multicast_list(qlge_t *, uint8_t *ep);
extern int ql_remove_from_multicast_list(qlge_t *, uint8_t *);
extern void ql_set_promiscuous(qlge_t *, int);
extern void ql_get_hw_stats(qlge_t *);
extern int ql_send_common(struct tx_ring *, mblk_t *);
extern void ql_wake_asic_reset_soft_intr(qlge_t *);
extern void ql_write_doorbell_reg(qlge_t *, uint32_t *, uint32_t);
extern uint32_t ql_read_doorbell_reg(qlge_t *, uint32_t *);
extern int ql_set_mac_addr_reg(qlge_t *, uint8_t *, uint32_t, uint16_t);
extern int ql_read_xgmac_reg(qlge_t *, uint32_t, uint32_t *);
extern void ql_enable_completion_interrupt(qlge_t *, uint32_t);
extern mblk_t *ql_ring_rx_poll(void *, int);
extern void ql_disable_completion_interrupt(qlge_t *qlge, uint32_t intr);
extern mblk_t *ql_ring_tx(void *arg, mblk_t *mp);
extern uint8_t ql_tx_hashing(qlge_t *qlge, caddr_t bp);
extern void ql_atomic_set_32(volatile uint32_t *target, uint32_t newval);
extern uint32_t ql_atomic_read_32(volatile uint32_t *target);
extern void ql_restart_timer(qlge_t *qlge);
extern int ql_route_initialize(qlge_t *);
/*
 * Global Function Prototypes in qlge_flash.c source file.
 */
extern int ql_sem_flash_lock(qlge_t *);
extern void ql_sem_flash_unlock(qlge_t *);
extern int qlge_load_flash(qlge_t *, uint8_t *, uint32_t, uint32_t);
extern int qlge_dump_fcode(qlge_t *, uint8_t *, uint32_t, uint32_t);
extern int ql_flash_vpd(qlge_t *qlge, uint8_t *buf);
extern int ql_get_flash_params(qlge_t *qlge);
/*
 * Global Function Prototypes in qlge_mpi.c source file.
 */
extern void ql_do_mpi_intr(qlge_t *qlge);
extern int ql_reset_mpi_risc(qlge_t *);
extern int ql_get_fw_state(qlge_t *, uint32_t *);
extern int qlge_get_link_status(qlge_t *, struct qlnic_link_status_info *);
extern int ql_mbx_test(qlge_t *qlge);
extern int ql_mbx_test2(qlge_t *qlge);
extern int ql_get_port_cfg(qlge_t *qlge);
extern int ql_set_mpi_port_config(qlge_t *qlge, port_cfg_info_t new_cfg);
extern int ql_set_loop_back_mode(qlge_t *qlge);
extern int ql_set_pause_mode(qlge_t *qlge);
extern int ql_get_LED_config(qlge_t *);
extern int ql_dump_sfp(qlge_t *, void *bp, int mode);
extern int ql_set_IDC_Req(qlge_t *, uint8_t dest_functions, uint8_t timeout);
extern void ql_write_flash_test(qlge_t *qlge, uint32_t testAddr);
extern void ql_write_flash_test2(qlge_t *qlge, uint32_t testAddr);
extern int ql_get_firmware_version(qlge_t *,
    struct qlnic_mpi_version_info *);
extern int ql_read_processor_data(qlge_t *, uint32_t, uint32_t *);
extern int ql_write_processor_data(qlge_t *, uint32_t, uint32_t);
extern int ql_read_risc_ram(qlge_t *, uint32_t, uint64_t, uint32_t);
extern int ql_trigger_system_error_event(qlge_t *qlge);

extern void ql_core_dump(qlge_t *);
extern void ql_dump_crash_record(qlge_t *);
extern void ql_dump_buf(char *, uint8_t *, uint8_t, uint32_t);
extern void ql_printf(const char *, ...);

/*
 * Global Function Prototypes in qlge_gld.c source file.
 */
extern int ql_unicst_set(qlge_t *qlge, const uint8_t *macaddr, int slot);

/*
 * Global Function Prototypes in qlge_fm.c source file.
 */
extern void ql_fm_ereport(qlge_t *qlge, char *detail);
extern int ql_fm_check_acc_handle(ddi_acc_handle_t handle);
extern int ql_fm_check_dma_handle(ddi_dma_handle_t handle);


#ifdef __cplusplus
}
#endif

#endif /* _QLGE_H */