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