xref: /illumos-gate/usr/src/uts/common/io/chxge/sge.h (revision 2d6eb4a5)
1*d39a76e7Sxw /*
2*d39a76e7Sxw  * CDDL HEADER START
3*d39a76e7Sxw  *
4*d39a76e7Sxw  * The contents of this file are subject to the terms of the
5*d39a76e7Sxw  * Common Development and Distribution License (the "License").
6*d39a76e7Sxw  * You may not use this file except in compliance with the License.
7*d39a76e7Sxw  *
8*d39a76e7Sxw  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9*d39a76e7Sxw  * or http://www.opensolaris.org/os/licensing.
10*d39a76e7Sxw  * See the License for the specific language governing permissions
11*d39a76e7Sxw  * and limitations under the License.
12*d39a76e7Sxw  *
13*d39a76e7Sxw  * When distributing Covered Code, include this CDDL HEADER in each
14*d39a76e7Sxw  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15*d39a76e7Sxw  * If applicable, add the following below this CDDL HEADER, with the
16*d39a76e7Sxw  * fields enclosed by brackets "[]" replaced with your own identifying
17*d39a76e7Sxw  * information: Portions Copyright [yyyy] [name of copyright owner]
18*d39a76e7Sxw  *
19*d39a76e7Sxw  * CDDL HEADER END
20*d39a76e7Sxw  */
21*d39a76e7Sxw 
22*d39a76e7Sxw /*
23*d39a76e7Sxw  * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
24*d39a76e7Sxw  * Use is subject to license terms.
25*d39a76e7Sxw  */
26*d39a76e7Sxw 
27*d39a76e7Sxw /*
28*d39a76e7Sxw  * This file is part of the Chelsio T1 Ethernet driver.
29*d39a76e7Sxw  *
30*d39a76e7Sxw  * Copyright (C) 2003-2005 Chelsio Communications.  All rights reserved.
31*d39a76e7Sxw  */
32*d39a76e7Sxw 
33*d39a76e7Sxw #ifndef _CHELSIO_SGE_H
34*d39a76e7Sxw #define	_CHELSIO_SGE_H
35*d39a76e7Sxw 
36*d39a76e7Sxw #ifdef __cplusplus
37*d39a76e7Sxw extern "C" {
38*d39a76e7Sxw #endif
39*d39a76e7Sxw 
40*d39a76e7Sxw #include <sys/types.h>
41*d39a76e7Sxw 
42*d39a76e7Sxw #include "osdep.h"
43*d39a76e7Sxw 
44*d39a76e7Sxw #define	MBLK_MAX 8
45*d39a76e7Sxw 
46*d39a76e7Sxw #define	spin_lock mutex_enter
47*d39a76e7Sxw #define	spin_unlock mutex_exit
48*d39a76e7Sxw #define	atomic_sub(a, b) atomic_add_32(b, -(a))
49*d39a76e7Sxw #define	atomic_add(a, b) atomic_add_32(b, (a))
50*d39a76e7Sxw #define	atomic_read(a) (a)
51*d39a76e7Sxw #define	atomic_set(a, b) (*(a) = b)
52*d39a76e7Sxw #define	spinlock_t kmutex_t
53*d39a76e7Sxw #define	dma_addr_t uint64_t
54*d39a76e7Sxw #define	wmb() membar_producer()
55*d39a76e7Sxw #define	doorbell_pio(sge, cmd) sge_ring_doorbell(sge, cmd)
56*d39a76e7Sxw #define	skb_reserve(skb, offset) (skb->b_rptr += offset)
57*d39a76e7Sxw #define	__skb_pull(skb, len) (skb->b_rptr += len)
58*d39a76e7Sxw #define	skb_put(skb, len) ((skb)->b_wptr  = (skb)->b_rptr + (len))
59*d39a76e7Sxw #define	skb_pull(skb, len) (skb->b_rptr += len)
60*d39a76e7Sxw #define	unlikely(a) (a)
61*d39a76e7Sxw #define	likely(a) (a)
62*d39a76e7Sxw #define	SKB_DATA_ALIGN(X) (((X) + (sizeof (long)-1)) & ~(sizeof (long)-1))
63*d39a76e7Sxw #define	t1_is_T1B(adap) adapter_matches_type(adap, CHBT_TERM_T1, TERM_T1B)
64*d39a76e7Sxw #define	t1_is_T1C(adap) adapter_matches_type(adap, CHBT_TERM_T1, TERM_T1C)
65*d39a76e7Sxw 
66*d39a76e7Sxw #define	SGE_SM_BUF_SZ(sa)	(sa->ch_sm_buf_sz)
67*d39a76e7Sxw #define	SGE_BG_BUF_SZ(sa)	(sa->ch_bg_buf_sz)
68*d39a76e7Sxw 
69*d39a76e7Sxw #define	SGE_CMDQ_N		2
70*d39a76e7Sxw #define	SGE_FREELQ_N		2
71*d39a76e7Sxw #ifdef CONFIG_CHELSIO_T1_OFFLOAD
72*d39a76e7Sxw #define	SGE_CMDQ0_E_N		4096
73*d39a76e7Sxw #define	SGE_CMDQ1_E_N		128
74*d39a76e7Sxw #define	SGE_FREELQ0_E_N		2048
75*d39a76e7Sxw #define	SGE_FREELQ1_E_N		1024
76*d39a76e7Sxw #define	SGE_RESPQ_E_N		7168    /* |CMDQ0| + |FREELQ0| + |FREELQ1| */
77*d39a76e7Sxw #else
78*d39a76e7Sxw #define	SGE_CMDQ0_E_N		2048
79*d39a76e7Sxw #define	SGE_CMDQ1_E_N		128
80*d39a76e7Sxw #define	SGE_FREELQ0_E_N		4096
81*d39a76e7Sxw #define	SGE_FREELQ1_E_N		1024
82*d39a76e7Sxw #define	SGE_RESPQ_E_N		7168    /* |CMDQ0| + |FREELQ0| + |FREELQ1| */
83*d39a76e7Sxw #endif  /* CONFIG_CHELSIO_T1_OFFLOAD */
84*d39a76e7Sxw #define	SGE_BATCH_THRESH	16
85*d39a76e7Sxw #define	SGE_INTR_BUCKETSIZE	100
86*d39a76e7Sxw #define	SGE_INTR_MAXBUCKETS	11
87*d39a76e7Sxw #define	SGE_INTRTIMER0		1
88*d39a76e7Sxw #define	SGE_INTRTIMER1		30
89*d39a76e7Sxw #define	SGE_INTRTIMER_NRES	10000
90*d39a76e7Sxw #define	SGE_RX_COPY_THRESHOLD	256
91*d39a76e7Sxw #define	SGE_RX_OFFSET		2
92*d39a76e7Sxw #ifdef CONFIG_CHELSIO_T1_OFFLOAD
93*d39a76e7Sxw #define	SGE_RX_SM_BUF_SIZE(sa)	1536
94*d39a76e7Sxw #else
95*d39a76e7Sxw #define	SGE_RX_SM_BUF_SIZE(sa)	(sa->ch_sm_buf_sz)
96*d39a76e7Sxw #endif
97*d39a76e7Sxw 
98*d39a76e7Sxw /*
99*d39a76e7Sxw  * CPL5 Defines
100*d39a76e7Sxw  */
101*d39a76e7Sxw #define	FLITSTOBYTES    8
102*d39a76e7Sxw 
103*d39a76e7Sxw #define	CPL_FORMAT_0_SIZE 8
104*d39a76e7Sxw #define	CPL_FORMAT_1_SIZE 16
105*d39a76e7Sxw #define	CPL_FORMAT_2_SIZE 24
106*d39a76e7Sxw #define	CPL_FORMAT_3_SIZE 32
107*d39a76e7Sxw #define	CPL_FORMAT_4_SIZE 40
108*d39a76e7Sxw #define	CPL_FORMAT_5_SIZE 48
109*d39a76e7Sxw 
110*d39a76e7Sxw #define	TID_MASK 0xffffff
111*d39a76e7Sxw 
112*d39a76e7Sxw #define	SZ_CPL_RX_PKT CPL_FORMAT_0_SIZE
113*d39a76e7Sxw 
114*d39a76e7Sxw #if BYTE_ORDER == BIG_ENDIAN
115*d39a76e7Sxw 
116*d39a76e7Sxw typedef struct {
117*d39a76e7Sxw 	u32 AddrLow;
118*d39a76e7Sxw 	u32 GenerationBit: 1;
119*d39a76e7Sxw 	u32 BufferLength: 31;
120*d39a76e7Sxw 	u32 RespQueueSelector: 4;
121*d39a76e7Sxw 	u32 ResponseTokens: 12;
122*d39a76e7Sxw 	u32 CmdId: 8;
123*d39a76e7Sxw 	u32 Reserved: 3;
124*d39a76e7Sxw 	u32 TokenValid: 1;
125*d39a76e7Sxw 	u32 Eop: 1;
126*d39a76e7Sxw 	u32 Sop: 1;
127*d39a76e7Sxw 	u32 DataValid: 1;
128*d39a76e7Sxw 	u32 GenerationBit2: 1;
129*d39a76e7Sxw 	u32 AddrHigh;
130*d39a76e7Sxw } CmdQueueEntry;
131*d39a76e7Sxw 
132*d39a76e7Sxw 
133*d39a76e7Sxw #elif BYTE_ORDER == LITTLE_ENDIAN
134*d39a76e7Sxw 
135*d39a76e7Sxw 
136*d39a76e7Sxw typedef struct {
137*d39a76e7Sxw 	u32 BufferLength: 31;
138*d39a76e7Sxw 	u32 GenerationBit: 1;
139*d39a76e7Sxw 	u32 AddrLow;
140*d39a76e7Sxw 	u32 AddrHigh;
141*d39a76e7Sxw 	u32 GenerationBit2: 1;
142*d39a76e7Sxw 	u32 DataValid: 1;
143*d39a76e7Sxw 	u32 Sop: 1;
144*d39a76e7Sxw 	u32 Eop: 1;
145*d39a76e7Sxw 	u32 TokenValid: 1;
146*d39a76e7Sxw 	u32 Reserved: 3;
147*d39a76e7Sxw 	u32 CmdId: 8;
148*d39a76e7Sxw 	u32 ResponseTokens: 12;
149*d39a76e7Sxw 	u32 RespQueueSelector: 4;
150*d39a76e7Sxw } CmdQueueEntry;
151*d39a76e7Sxw 
152*d39a76e7Sxw #endif
153*d39a76e7Sxw 
154*d39a76e7Sxw 
155*d39a76e7Sxw typedef CmdQueueEntry cmdQ_e;
156*d39a76e7Sxw 
157*d39a76e7Sxw #if BYTE_ORDER == BIG_ENDIAN
158*d39a76e7Sxw 
159*d39a76e7Sxw typedef struct {
160*d39a76e7Sxw 	u32 Qsleeping: 4;
161*d39a76e7Sxw 	u32 Cmdq1CreditReturn: 5;
162*d39a76e7Sxw 	u32 Cmdq1DmaComplete: 5;
163*d39a76e7Sxw 	u32 Cmdq0CreditReturn: 5;
164*d39a76e7Sxw 	u32 Cmdq0DmaComplete: 5;
165*d39a76e7Sxw 	u32 FreelistQid: 2;
166*d39a76e7Sxw 	u32 CreditValid: 1;
167*d39a76e7Sxw 	u32 DataValid: 1;
168*d39a76e7Sxw 	u32 Offload: 1;
169*d39a76e7Sxw 	u32 Eop: 1;
170*d39a76e7Sxw 	u32 Sop: 1;
171*d39a76e7Sxw 	u32 GenerationBit: 1;
172*d39a76e7Sxw 	u32 BufferLength;
173*d39a76e7Sxw } ResponseQueueEntry;
174*d39a76e7Sxw 
175*d39a76e7Sxw 
176*d39a76e7Sxw #elif BYTE_ORDER == LITTLE_ENDIAN
177*d39a76e7Sxw 
178*d39a76e7Sxw 
179*d39a76e7Sxw typedef struct {
180*d39a76e7Sxw 	u32 BufferLength;
181*d39a76e7Sxw 	u32 GenerationBit: 1;
182*d39a76e7Sxw 	u32 Sop: 1;
183*d39a76e7Sxw 	u32 Eop: 1;
184*d39a76e7Sxw 	u32 Offload: 1;
185*d39a76e7Sxw 	u32 DataValid: 1;
186*d39a76e7Sxw 	u32 CreditValid: 1;
187*d39a76e7Sxw 	u32 FreelistQid: 2;
188*d39a76e7Sxw 	u32 Cmdq0DmaComplete: 5;
189*d39a76e7Sxw 	u32 Cmdq0CreditReturn: 5;
190*d39a76e7Sxw 	u32 Cmdq1DmaComplete: 5;
191*d39a76e7Sxw 	u32 Cmdq1CreditReturn: 5;
192*d39a76e7Sxw 	u32 Qsleeping: 4;
193*d39a76e7Sxw } ResponseQueueEntry;
194*d39a76e7Sxw 
195*d39a76e7Sxw #endif
196*d39a76e7Sxw 
197*d39a76e7Sxw typedef ResponseQueueEntry respQ_e;
198*d39a76e7Sxw 
199*d39a76e7Sxw #if BYTE_ORDER == BIG_ENDIAN
200*d39a76e7Sxw 
201*d39a76e7Sxw 
202*d39a76e7Sxw typedef struct {
203*d39a76e7Sxw 	u32 AddrLow;
204*d39a76e7Sxw 	u32 GenerationBit: 1;
205*d39a76e7Sxw 	u32 BufferLength: 31;
206*d39a76e7Sxw 	u32 Reserved: 31;
207*d39a76e7Sxw 	u32 GenerationBit2: 1;
208*d39a76e7Sxw 	u32 AddrHigh;
209*d39a76e7Sxw } FLQueueEntry;
210*d39a76e7Sxw 
211*d39a76e7Sxw 
212*d39a76e7Sxw #elif BYTE_ORDER == LITTLE_ENDIAN
213*d39a76e7Sxw 
214*d39a76e7Sxw 
215*d39a76e7Sxw typedef struct {
216*d39a76e7Sxw 	u32 BufferLength: 31;
217*d39a76e7Sxw 	u32 GenerationBit: 1;
218*d39a76e7Sxw 	u32 AddrLow;
219*d39a76e7Sxw 	u32 AddrHigh;
220*d39a76e7Sxw 	u32 GenerationBit2: 1;
221*d39a76e7Sxw 	u32 Reserved: 31;
222*d39a76e7Sxw } FLQueueEntry;
223*d39a76e7Sxw 
224*d39a76e7Sxw 
225*d39a76e7Sxw #endif
226*d39a76e7Sxw 
227*d39a76e7Sxw typedef FLQueueEntry freelQ_e;
228*d39a76e7Sxw 
229*d39a76e7Sxw /*
230*d39a76e7Sxw  * Command QUEUE meta entry format.
231*d39a76e7Sxw  */
232*d39a76e7Sxw typedef struct cmdQ_ce {
233*d39a76e7Sxw 	void *ce_mp;		/* head mblk of pkt */
234*d39a76e7Sxw 	free_dh_t *ce_dh;	/* ddi dma handle */
235*d39a76e7Sxw 	uint_t ce_flg;		/* flag 0 - NIC descriptor; 1 - TOE */
236*d39a76e7Sxw 	uint_t ce_len;		/* length of mblk component */
237*d39a76e7Sxw 	uint64_t ce_pa;		/* physical address */
238*d39a76e7Sxw } cmdQ_ce_t;
239*d39a76e7Sxw 
240*d39a76e7Sxw /*
241*d39a76e7Sxw  * command queue control structure
242*d39a76e7Sxw  */
243*d39a76e7Sxw typedef struct cmdQ {
244*d39a76e7Sxw 	u32 cq_credits;		/* # available descriptors for Xmit */
245*d39a76e7Sxw 	u32 cq_asleep;		/* HW DMA Fetch status */
246*d39a76e7Sxw 	u32 cq_pio_pidx;	/* Variable updated on Doorbell */
247*d39a76e7Sxw 	u32 cq_entries_n;	/* # entries for Xmit */
248*d39a76e7Sxw 	u32 cq_pidx;		/* producer index (SW) */
249*d39a76e7Sxw 	u32 cq_complete;		/* Shadow consumer index (HW) */
250*d39a76e7Sxw 	u32 cq_cidx;		/* consumer index (HW) */
251*d39a76e7Sxw 	u32 cq_genbit;		/* current generation (=valid) bit */
252*d39a76e7Sxw 	cmdQ_e *cq_entries;
253*d39a76e7Sxw 	cmdQ_ce_t *cq_centries;
254*d39a76e7Sxw 	spinlock_t cq_qlock;
255*d39a76e7Sxw 	uint64_t cq_pa;		/* may not be needed */
256*d39a76e7Sxw 	ulong_t cq_dh;
257*d39a76e7Sxw 	ulong_t cq_ah;		/* may not be needed */
258*d39a76e7Sxw } cmdQ_t;
259*d39a76e7Sxw 
260*d39a76e7Sxw /*
261*d39a76e7Sxw  * free list queue control structure
262*d39a76e7Sxw  */
263*d39a76e7Sxw typedef struct freelQ {
264*d39a76e7Sxw 	u32 fq_id;	/* 0 queue 0, 1 queue 1 */
265*d39a76e7Sxw 	u32 fq_credits;	/* # available RX buffer descriptors */
266*d39a76e7Sxw 	u32 fq_entries_n;	/* # RX buffer descriptors */
267*d39a76e7Sxw 	u32 fq_pidx;	    /* producer index (SW) */
268*d39a76e7Sxw 	u32 fq_cidx;	    /* consumer index (HW) */
269*d39a76e7Sxw 	u32 fq_genbit;	  /* current generation (=valid) bit */
270*d39a76e7Sxw 	u32 fq_rx_buffer_size;  /* size buffer on this freelist */
271*d39a76e7Sxw 	freelQ_e *fq_entries;   /* HW freelist descriptor Q */
272*d39a76e7Sxw 	struct freelQ_ce *fq_centries;  /* SW freelist conext descriptor Q */
273*d39a76e7Sxw 	uint64_t fq_pa;	 /* may not be needed */
274*d39a76e7Sxw 	ulong_t fq_dh;
275*d39a76e7Sxw 	ulong_t fq_ah;
276*d39a76e7Sxw 	u32 fq_pause_on_thresh;
277*d39a76e7Sxw 	u32 fq_pause_off_thresh;
278*d39a76e7Sxw } freelQ_t;
279*d39a76e7Sxw 
280*d39a76e7Sxw /*
281*d39a76e7Sxw  * response queue control structure
282*d39a76e7Sxw  */
283*d39a76e7Sxw typedef struct respQ {
284*d39a76e7Sxw 	u32 rq_credits;	 /* # avail response Q entries */
285*d39a76e7Sxw 	u32 rq_credits_pend;    /* # not yet returned entries */
286*d39a76e7Sxw 	u32 rq_credits_thresh;  /* return threshold */
287*d39a76e7Sxw 	u32 rq_entries_n;	/* # response Q descriptors */
288*d39a76e7Sxw 	u32 rq_pidx;	    /* producer index (HW) */
289*d39a76e7Sxw 	u32 rq_cidx;	    /* consumer index (SW) */
290*d39a76e7Sxw 	u32 rq_genbit;	  /* current generation(=valid) bit */
291*d39a76e7Sxw 	respQ_e *rq_entries;    /* HW response Q */
292*d39a76e7Sxw 	uint64_t rq_pa;	 /* may not be needed */
293*d39a76e7Sxw 	ulong_t rq_dh;
294*d39a76e7Sxw 	ulong_t rq_ah;
295*d39a76e7Sxw } reapQ_t;
296*d39a76e7Sxw 
297*d39a76e7Sxw struct sge_intr_counts {
298*d39a76e7Sxw 	uint32_t respQ_empty;		/* # times respQ empty */
299*d39a76e7Sxw 	uint32_t respQ_overflow;	/* # respQ overflow (fatal) */
300*d39a76e7Sxw 	uint32_t freelistQ_empty;	/* # times freelist empty */
301*d39a76e7Sxw 	uint32_t pkt_too_big;		/* packet too large (fatal) */
302*d39a76e7Sxw 	uint32_t pkt_mismatch;
303*d39a76e7Sxw 	uint32_t cmdQ_full[2];		/* not HW intr, host cmdQ[] full */
304*d39a76e7Sxw 	uint32_t tx_reclaims[2];
305*d39a76e7Sxw 	uint32_t tx_msg_pullups;	/* # of tx pkt coelescing events */
306*d39a76e7Sxw 	uint32_t tx_hdr_pullups;	/* # of tx hdr coelescing events */
307*d39a76e7Sxw 	uint32_t tx_tcp_ip_frag;	/* # of ip fragmentes for tcp data */
308*d39a76e7Sxw 	uint32_t tx_udp_ip_frag;	/* # of ip fragmentes for udp data */
309*d39a76e7Sxw 	uint32_t tx_soft_cksums;	/* # of Software checksums done. */
310*d39a76e7Sxw 	uint32_t tx_need_cpl_space;	/* # of allocs for cpl header */
311*d39a76e7Sxw 	uint32_t tx_multi_mblks;	/* # of Multi mblk packets */
312*d39a76e7Sxw 	uint32_t tx_no_dvma1;		/* # of dvma mapping failures */
313*d39a76e7Sxw 	uint32_t tx_no_dvma2;		/* # of dvma mapping failures */
314*d39a76e7Sxw 	uint32_t tx_no_dma1;		/* # of dma mapping failures */
315*d39a76e7Sxw 	uint32_t tx_no_dma2;		/* # of dma mapping failures */
316*d39a76e7Sxw 	uint32_t rx_cmdq0;		/* # of Qsleeping CMDQ0's */
317*d39a76e7Sxw 	uint32_t rx_cmdq1;		/* # of Qsleeping CMDQ1's */
318*d39a76e7Sxw 	uint32_t rx_flq0;		/* # of Qsleeping FL0's */
319*d39a76e7Sxw 	uint32_t rx_flq1;		/* # of Qsleeping FL1's */
320*d39a76e7Sxw 	uint32_t rx_flq0_sz;		/* size of freelist-0 buffers */
321*d39a76e7Sxw 	uint32_t rx_flq1_sz;		/* size of freelist-1 buffers */
322*d39a76e7Sxw 	uint32_t rx_pkt_drops;		/* # intentionally dropped packets */
323*d39a76e7Sxw 	uint32_t rx_pkt_copied;		/* # times packets copied by sge */
324*d39a76e7Sxw 	uint32_t rx_pause_on;		/* # of system pause on's required. */
325*d39a76e7Sxw 	uint32_t rx_pause_off;		/* # of system pauses off's required. */
326*d39a76e7Sxw 	uint32_t rx_pause_ms;		/* micro seconds while paused */
327*d39a76e7Sxw 	uint32_t rx_pause_spike;	/* maximum time paused */
328*d39a76e7Sxw 	uint32_t rx_fl_credits;		/* Current free list credit usage. */
329*d39a76e7Sxw 	uint32_t rx_flbuf_fails;	/* # of freelist buf alloc fails. */
330*d39a76e7Sxw 	uint32_t rx_flbuf_allocs;	/* # of freelist buf allocs. */
331*d39a76e7Sxw 	uint32_t rx_badEopSop;		/* # of times bad Eop/Sop received */
332*d39a76e7Sxw 	uint32_t rx_flq0_cnt;	/* # of times free list Q 0 entry used */
333*d39a76e7Sxw 	uint32_t rx_flq1_cnt;	/* # of times free list Q 1 entry used */
334*d39a76e7Sxw 	uint32_t arp_sent;		/* # times arp packet sent */
335*d39a76e7Sxw #ifdef SUN_KSTATS
336*d39a76e7Sxw 	uint32_t tx_doorbells;
337*d39a76e7Sxw 	uint32_t intr_doorbells;
338*d39a76e7Sxw 	uint32_t intr1_doorbells;
339*d39a76e7Sxw 	uint32_t sleep_cnt;
340*d39a76e7Sxw 	uint32_t pe_allocb_cnt;
341*d39a76e7Sxw 	uint32_t tx_descs[MBLK_MAX];
342*d39a76e7Sxw #endif
343*d39a76e7Sxw };
344*d39a76e7Sxw 
345*d39a76e7Sxw #ifdef SUN_KSTATS
346*d39a76e7Sxw typedef struct sge_intr_counts *p_ch_stats_t;
347*d39a76e7Sxw 
348*d39a76e7Sxw /*
349*d39a76e7Sxw  * Driver maintained kernel statistics.
350*d39a76e7Sxw  */
351*d39a76e7Sxw typedef struct _ch_kstat_t {
352*d39a76e7Sxw 	/*
353*d39a76e7Sxw 	 * Link Input/Output stats
354*d39a76e7Sxw 	 */
355*d39a76e7Sxw 	kstat_named_t respQ_empty;	/* # times respQ empty */
356*d39a76e7Sxw 	kstat_named_t respQ_overflow;	/* # respQ overflow (fatal) */
357*d39a76e7Sxw 	kstat_named_t freelistQ_empty;	/* # times freelist empty */
358*d39a76e7Sxw 	kstat_named_t pkt_too_big;	/* packet too large (fatal) */
359*d39a76e7Sxw 	kstat_named_t pkt_mismatch;
360*d39a76e7Sxw 	kstat_named_t cmdQ_full[2];	/* not HW intr, host cmdQ[] full */
361*d39a76e7Sxw 	kstat_named_t tx_reclaims[2];	/* # of tx reclaims called */
362*d39a76e7Sxw 	kstat_named_t tx_msg_pullups;	/* # of tx pkt coelescing events */
363*d39a76e7Sxw 	kstat_named_t tx_hdr_pullups;	/* # of tx hdr coelescing events */
364*d39a76e7Sxw 	kstat_named_t tx_tcp_ip_frag;	/* # of ip fragmentes for tcp data */
365*d39a76e7Sxw 	kstat_named_t tx_udp_ip_frag;	/* # of ip fragmentes for udp data */
366*d39a76e7Sxw 	kstat_named_t tx_soft_cksums;	/* # of Software checksums done. */
367*d39a76e7Sxw 	kstat_named_t tx_need_cpl_space;	/* # of allocs for cpl header */
368*d39a76e7Sxw 	kstat_named_t tx_multi_mblks;	/* # of multi fragment packets */
369*d39a76e7Sxw 	kstat_named_t tx_no_dvma1;	/* # of dvma mapping failures */
370*d39a76e7Sxw 	kstat_named_t tx_no_dvma2;	/* # of dvma mapping failures */
371*d39a76e7Sxw 	kstat_named_t tx_no_dma1;	/* # of dma mapping failures */
372*d39a76e7Sxw 	kstat_named_t tx_no_dma2;	/* # of dma mapping failures */
373*d39a76e7Sxw 	kstat_named_t rx_cmdq0;		/* # times Qsleeping cmdq0 */
374*d39a76e7Sxw 	kstat_named_t rx_cmdq1;		/* # times Qsleeping cmdq1 */
375*d39a76e7Sxw 	kstat_named_t rx_flq0;		/* # times Qsleeping flq0 */
376*d39a76e7Sxw 	kstat_named_t rx_flq0_sz;	/* size of freelist-0 buffers */
377*d39a76e7Sxw 	kstat_named_t rx_flq1;		/* # times Qsleeping flq1 */
378*d39a76e7Sxw 	kstat_named_t rx_flq1_sz;	/* size of freelist-1 buffers */
379*d39a76e7Sxw 	kstat_named_t rx_pkt_drops;	/* # times packets dropped by sge */
380*d39a76e7Sxw 	kstat_named_t rx_pkt_copied;	/* # intentionally copied packets */
381*d39a76e7Sxw 	kstat_named_t rx_pause_on;	/* # of system pause on's required. */
382*d39a76e7Sxw 	kstat_named_t rx_pause_off;	/* # of system pauses off's required. */
383*d39a76e7Sxw 	kstat_named_t rx_pause_ms;	/* micro seconds while paused. */
384*d39a76e7Sxw 	kstat_named_t rx_pause_spike;	/* maximum time paused. */
385*d39a76e7Sxw 	kstat_named_t rx_fl_credits;	/* Current free list credit usage. */
386*d39a76e7Sxw 	kstat_named_t rx_flbuf_fails;	/* # of freelist buf alloc fails. */
387*d39a76e7Sxw 	kstat_named_t rx_flbuf_allocs;	/* # of freelist buf allocs. */
388*d39a76e7Sxw 	kstat_named_t rx_badEopSop;	/* # of times bad Eop/Sop received */
389*d39a76e7Sxw 	kstat_named_t rx_flq0_cnt; /* # of times free list Q 0 entry used */
390*d39a76e7Sxw 	kstat_named_t rx_flq1_cnt; /* # of times free list Q 1 entry used */
391*d39a76e7Sxw 	kstat_named_t arp_sent;		/* # times arp packet sent */
392*d39a76e7Sxw 
393*d39a76e7Sxw 	kstat_named_t tx_doorbells;
394*d39a76e7Sxw 	kstat_named_t intr_doorbells;
395*d39a76e7Sxw 	kstat_named_t intr1_doorbells;
396*d39a76e7Sxw 	kstat_named_t sleep_cnt;
397*d39a76e7Sxw 	kstat_named_t pe_allocb_cnt;
398*d39a76e7Sxw 	kstat_named_t tx_descs[MBLK_MAX];
399*d39a76e7Sxw } ch_kstat_t;
400*d39a76e7Sxw typedef ch_kstat_t *p_ch_kstat_t;
401*d39a76e7Sxw #endif
402*d39a76e7Sxw 
403*d39a76e7Sxw typedef struct _pesge {
404*d39a76e7Sxw 	peobj *obj;			/* adapter backpointer */
405*d39a76e7Sxw 	struct freelQ freelQ[2];	/* freelist Q(s) */
406*d39a76e7Sxw 	struct respQ respQ;		/* response Q instatiation */
407*d39a76e7Sxw 	uint32_t rx_pkt_pad;		/* RX padding for T2 packets (hw) */
408*d39a76e7Sxw 	uint32_t rx_offset;		/* RX padding for T1 packets (sw) */
409*d39a76e7Sxw 	uint32_t jumbo_fl;		/* jumbo freelist Q index */
410*d39a76e7Sxw 	uint32_t intrtimer[SGE_INTR_MAXBUCKETS];	/* timer values */
411*d39a76e7Sxw 	uint32_t currIndex;		/* current index into intrtimer[] */
412*d39a76e7Sxw 	uint32_t intrtimer_nres;	/* no resource interrupt timer value */
413*d39a76e7Sxw 	uint32_t sge_control;		/* shadow content of sge control reg */
414*d39a76e7Sxw 	struct sge_intr_counts intr_cnt;
415*d39a76e7Sxw #ifdef SUN_KSTATS
416*d39a76e7Sxw 	p_kstat_t ksp;
417*d39a76e7Sxw #endif
418*d39a76e7Sxw 	ch_cyclic_t espi_wa_cyclic;
419*d39a76e7Sxw 	uint32_t ptimeout;
420*d39a76e7Sxw 	void *pskb;
421*d39a76e7Sxw 	struct cmdQ cmdQ[2];	    /* command Q(s) */
422*d39a76e7Sxw 	int do_udp_csum;
423*d39a76e7Sxw 	int do_tcp_csum;
424*d39a76e7Sxw } _pesge;
425*d39a76e7Sxw 
426*d39a76e7Sxw /*
427*d39a76e7Sxw  * ce_flg flag values
428*d39a76e7Sxw  */
429*d39a76e7Sxw #define	DH_DMA  1
430*d39a76e7Sxw #define	DH_DVMA 2
431*d39a76e7Sxw #define	DH_TOE  3
432*d39a76e7Sxw #define	DH_ARP  8
433*d39a76e7Sxw 
434*d39a76e7Sxw typedef struct freelQ_ce {
435*d39a76e7Sxw 	void *fe_mp;		/* head mblk of pkt */
436*d39a76e7Sxw 	ulong_t fe_dh;		/* ddi dma handle */
437*d39a76e7Sxw 	uint_t  fe_len;		/* length of mblk component */
438*d39a76e7Sxw 	uint64_t fe_pa;		/* physical address */
439*d39a76e7Sxw } freelQ_ce_t;
440*d39a76e7Sxw 
441*d39a76e7Sxw pesge *t1_sge_create(ch_t *, struct sge_params *);
442*d39a76e7Sxw 
443*d39a76e7Sxw extern int  t1_sge_destroy(pesge* sge);
444*d39a76e7Sxw extern int  sge_data_out(pesge*, int,  mblk_t *, cmdQ_ce_t *, int, uint32_t);
445*d39a76e7Sxw extern int  sge_data_in(pesge *);
446*d39a76e7Sxw extern int  sge_start(pesge*);
447*d39a76e7Sxw extern int  sge_stop(pesge *);
448*d39a76e7Sxw extern int t1_sge_configure(pesge *sge, struct sge_params *p);
449*d39a76e7Sxw 
450*d39a76e7Sxw extern int  t1_sge_intr_error_handler(pesge*);
451*d39a76e7Sxw extern int  t1_sge_intr_enable(pesge*);
452*d39a76e7Sxw extern int  t1_sge_intr_disable(pesge*);
453*d39a76e7Sxw extern int  t1_sge_intr_clear(pesge*);
454*d39a76e7Sxw extern u32  t1_sge_get_ptimeout(ch_t *);
455*d39a76e7Sxw extern void t1_sge_set_ptimeout(ch_t *, u32);
456*d39a76e7Sxw 
457*d39a76e7Sxw extern struct sge_intr_counts *sge_get_stat(pesge *);
458*d39a76e7Sxw extern void sge_add_fake_arp(pesge *, void *);
459*d39a76e7Sxw 
460*d39a76e7Sxw /*
461*d39a76e7Sxw  * Default SGE settings
462*d39a76e7Sxw  */
463*d39a76e7Sxw #define	SGE_CMDQ0_CNT	(512)
464*d39a76e7Sxw #define	SGE_FLQ0_CNT	(512)
465*d39a76e7Sxw #define	SGE_RESPQ_CNT	(1024)
466*d39a76e7Sxw 
467*d39a76e7Sxw /*
468*d39a76e7Sxw  * the structures below were taken from cpl5_cmd.h. It turns out that there
469*d39a76e7Sxw  * is a number of   #includes    that causes build problems. For now, we're
470*d39a76e7Sxw  * putting a private copy here. When the sge code is made common, then this
471*d39a76e7Sxw  * problem will need to be resolved.
472*d39a76e7Sxw  */
473*d39a76e7Sxw 
474*d39a76e7Sxw typedef uint8_t  __u8;
475*d39a76e7Sxw typedef uint32_t __u32;
476*d39a76e7Sxw typedef uint16_t __u16;
477*d39a76e7Sxw 
478*d39a76e7Sxw union opcode_tid {
479*d39a76e7Sxw     __u32 opcode_tid;
480*d39a76e7Sxw     __u8 opcode;
481*d39a76e7Sxw };
482*d39a76e7Sxw 
483*d39a76e7Sxw /*
484*d39a76e7Sxw  * We want this header's alignment to be no more stringent than 2-byte aligned.
485*d39a76e7Sxw  * All fields are u8 or u16 except for the length.  However that field is not
486*d39a76e7Sxw  * used so we break it into 2 16-bit parts to easily meet our alignment needs.
487*d39a76e7Sxw  */
488*d39a76e7Sxw struct cpl_tx_pkt {
489*d39a76e7Sxw     __u8 opcode;
490*d39a76e7Sxw #if BYTE_ORDER == BIG_ENDIAN
491*d39a76e7Sxw     __u8 rsvd:1;
492*d39a76e7Sxw     __u8 vlan_valid:1;
493*d39a76e7Sxw     __u8 l4_csum_dis:1;
494*d39a76e7Sxw     __u8 ip_csum_dis:1;
495*d39a76e7Sxw     __u8 iff:4;
496*d39a76e7Sxw #else
497*d39a76e7Sxw     __u8 iff:4;
498*d39a76e7Sxw     __u8 ip_csum_dis:1;
499*d39a76e7Sxw     __u8 l4_csum_dis:1;
500*d39a76e7Sxw     __u8 vlan_valid:1;
501*d39a76e7Sxw     __u8 rsvd:1;
502*d39a76e7Sxw #endif
503*d39a76e7Sxw     __u16 vlan;
504*d39a76e7Sxw     __u16 len_hi;
505*d39a76e7Sxw     __u16 len_lo;
506*d39a76e7Sxw };
507*d39a76e7Sxw 
508*d39a76e7Sxw #define	CPL_TX_PKT 0xb2
509*d39a76e7Sxw #define	SZ_CPL_TX_PKT CPL_FORMAT_0_SIZE
510*d39a76e7Sxw 
511*d39a76e7Sxw struct cpl_rx_data {
512*d39a76e7Sxw     union opcode_tid ot;
513*d39a76e7Sxw     __u32 len;
514*d39a76e7Sxw     __u32 seq;
515*d39a76e7Sxw     __u16 urg;
516*d39a76e7Sxw     __u8  rsvd;
517*d39a76e7Sxw     __u8  status;
518*d39a76e7Sxw };
519*d39a76e7Sxw 
520*d39a76e7Sxw struct cpl_rx_pkt {
521*d39a76e7Sxw     __u8 opcode;
522*d39a76e7Sxw #if BYTE_ORDER == LITTLE_ENDIAN
523*d39a76e7Sxw     __u8 iff:4;
524*d39a76e7Sxw     __u8 csum_valid:1;
525*d39a76e7Sxw     __u8 bad_pkt:1;
526*d39a76e7Sxw     __u8 vlan_valid:1;
527*d39a76e7Sxw     __u8 rsvd:1;
528*d39a76e7Sxw #else
529*d39a76e7Sxw     __u8 rsvd:1;
530*d39a76e7Sxw     __u8 vlan_valid:1;
531*d39a76e7Sxw     __u8 bad_pkt:1;
532*d39a76e7Sxw     __u8 csum_valid:1;
533*d39a76e7Sxw     __u8 iff:4;
534*d39a76e7Sxw #endif
535*d39a76e7Sxw     __u16 csum;
536*d39a76e7Sxw     __u16 vlan;
537*d39a76e7Sxw     __u16 len;
538*d39a76e7Sxw };
539*d39a76e7Sxw 
540*d39a76e7Sxw #ifdef __cplusplus
541*d39a76e7Sxw }
542*d39a76e7Sxw #endif
543*d39a76e7Sxw 
544*d39a76e7Sxw #endif /* _CHELSIO_SGE_H */
545