summaryrefslogtreecommitdiff
path: root/usr/src/uts/common/sys/nxge/nxge_rxdma.h
blob: 885f051cef59503f7874c6407ea2c5e8452f7952 (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
/*
 * CDDL HEADER START
 *
 * The contents of this file are subject to the terms of the
 * Common Development and Distribution License (the "License").
 * You may not use this file except in compliance with the License.
 *
 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
 * or http://www.opensolaris.org/os/licensing.
 * See the License for the specific language governing permissions
 * and limitations under the License.
 *
 * When distributing Covered Code, include this CDDL HEADER in each
 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
 * If applicable, add the following below this CDDL HEADER, with the
 * fields enclosed by brackets "[]" replaced with your own identifying
 * information: Portions Copyright [yyyy] [name of copyright owner]
 *
 * CDDL HEADER END
 */

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

#ifndef	_SYS_NXGE_NXGE_RXDMA_H
#define	_SYS_NXGE_NXGE_RXDMA_H

#ifdef	__cplusplus
extern "C" {
#endif

#include <sys/nxge/nxge_rxdma_hw.h>
#include <npi_rxdma.h>

#define	RXDMA_CK_DIV_DEFAULT		7500 	/* 25 usec */
/*
 * Hardware RDC designer: 8 cache lines during Atlas bringup.
 */
#define	RXDMA_RED_LESS_BYTES		(8 * 64) /* 8 cache line */
#define	RXDMA_RED_LESS_ENTRIES		(RXDMA_RED_LESS_BYTES/8)
#define	RXDMA_RED_WINDOW_DEFAULT	0
#define	RXDMA_RED_THRES_DEFAULT		0

#define	RXDMA_RCR_PTHRES_DEFAULT	0x20
#define	RXDMA_RCR_TO_DEFAULT		0x8

/*
 * hardware workarounds: kick 16 (was 8 before)
 */
#define	NXGE_RXDMA_POST_BATCH		16

#define	RXBUF_START_ADDR(a, index, bsize)	((a & (index * bsize))
#define	RXBUF_OFFSET_FROM_START(a, start)	(start - a)
#define	RXBUF_64B_ALIGNED		64

#define	NXGE_RXBUF_EXTRA		34
/*
 * Receive buffer thresholds and buffer types
 */
#define	NXGE_RX_BCOPY_SCALE	8	/* use 1/8 as lowest granularity */
typedef enum  {
	NXGE_RX_COPY_ALL = 0,		/* do bcopy on every packet	 */
	NXGE_RX_COPY_1,			/* bcopy on 1/8 of buffer posted */
	NXGE_RX_COPY_2,			/* bcopy on 2/8 of buffer posted */
	NXGE_RX_COPY_3,			/* bcopy on 3/8 of buffer posted */
	NXGE_RX_COPY_4,			/* bcopy on 4/8 of buffer posted */
	NXGE_RX_COPY_5,			/* bcopy on 5/8 of buffer posted */
	NXGE_RX_COPY_6,			/* bcopy on 6/8 of buffer posted */
	NXGE_RX_COPY_7,			/* bcopy on 7/8 of buffer posted */
	NXGE_RX_COPY_NONE		/* don't do bcopy at all	 */
} nxge_rxbuf_threshold_t;

typedef enum  {
	NXGE_RBR_TYPE0 = RCR_PKTBUFSZ_0,  /* bcopy buffer size 0 (small) */
	NXGE_RBR_TYPE1 = RCR_PKTBUFSZ_1,  /* bcopy buffer size 1 (medium) */
	NXGE_RBR_TYPE2 = RCR_PKTBUFSZ_2	  /* bcopy buffer size 2 (large) */
} nxge_rxbuf_type_t;

typedef	struct _rdc_errlog {
	rdmc_par_err_log_t	pre_par;
	rdmc_par_err_log_t	sha_par;
	uint8_t			compl_err_type;
} rdc_errlog_t;

/*
 * Receive  Statistics.
 */
typedef struct _nxge_rx_ring_stats_t {
	uint64_t	ipackets;
	uint64_t	ibytes;
	uint32_t	ierrors;
	uint32_t	multircv;
	uint32_t	brdcstrcv;
	uint32_t	norcvbuf;

	uint32_t	rx_inits;
	uint32_t	rx_jumbo_pkts;
	uint32_t	rx_multi_pkts;
	uint32_t	rx_mtu_pkts;
	uint32_t	rx_no_buf;

	/*
	 * Receive buffer management statistics.
	 */
	uint32_t	rx_new_pages;
	uint32_t	rx_new_mtu_pgs;
	uint32_t	rx_new_nxt_pgs;
	uint32_t	rx_reused_pgs;
	uint32_t	rx_mtu_drops;
	uint32_t	rx_nxt_drops;

	/*
	 * Error event stats.
	 */
	uint32_t	rx_rbr_tmout;
	uint32_t	pkt_too_long_err;
	uint32_t	l2_err;
	uint32_t	l4_cksum_err;
	uint32_t	fflp_soft_err;
	uint32_t	zcp_soft_err;
	uint32_t	rcr_unknown_err;
	uint32_t	dcf_err;
	uint32_t 	rbr_tmout;
	uint32_t 	rsp_cnt_err;
	uint32_t 	byte_en_err;
	uint32_t 	byte_en_bus;
	uint32_t 	rsp_dat_err;
	uint32_t 	rcr_ack_err;
	uint32_t 	dc_fifo_err;
	uint32_t 	rcr_sha_par;
	uint32_t 	rbr_pre_par;
	uint32_t 	port_drop_pkt;
	uint32_t 	wred_drop;
	uint32_t 	rbr_pre_empty;
	uint32_t 	rcr_shadow_full;
	uint32_t 	config_err;
	uint32_t 	rcrincon;
	uint32_t 	rcrfull;
	uint32_t 	rbr_empty;
	uint32_t 	rbrfull;
	uint32_t 	rbrlogpage;
	uint32_t 	cfiglogpage;
	uint32_t 	rcrto;
	uint32_t 	rcrthres;
	uint32_t 	mex;
	rdc_errlog_t	errlog;
} nxge_rx_ring_stats_t, *p_nxge_rx_ring_stats_t;

typedef struct _nxge_rdc_sys_stats {
	uint32_t	pre_par;
	uint32_t	sha_par;
	uint32_t	id_mismatch;
	uint32_t	ipp_eop_err;
	uint32_t	zcp_eop_err;
} nxge_rdc_sys_stats_t, *p_nxge_rdc_sys_stats_t;

/*
 * Software reserved buffer offset
 */
typedef struct _nxge_rxbuf_off_hdr_t {
	uint32_t		index;
} nxge_rxbuf_off_hdr_t, *p_nxge_rxbuf_off_hdr_t;


typedef struct _rx_msg_t {
	nxge_os_dma_common_t	buf_dma;
	nxge_os_mutex_t 	lock;
	struct _nxge_t		*nxgep;
	struct _rx_rbr_ring_t	*rx_rbr_p;
	boolean_t 		spare_in_use;
	boolean_t 		free;
	uint32_t 		ref_cnt;
#ifdef RXBUFF_USE_SEPARATE_UP_CNTR
	uint32_t 		pass_up_cnt;
	boolean_t 		release;
#endif
	nxge_os_frtn_t 		freeb;
	size_t 			bytes_arrived;
	size_t 			bytes_expected;
	size_t 			block_size;
	uint32_t		block_index;
	uint32_t 		pkt_buf_size;
	uint32_t 		pkt_buf_size_code;
	uint32_t 		max_pkt_bufs;
	uint32_t		cur_usage_cnt;
	uint32_t		max_usage_cnt;
	uchar_t			*buffer;
	uint32_t 		pri;
	uint32_t 		shifted_addr;
	boolean_t		use_buf_pool;
	p_mblk_t 		rx_mblk_p;
	boolean_t		rx_use_bcopy;
} rx_msg_t, *p_rx_msg_t;

typedef struct _rx_dma_handle_t {
	nxge_os_dma_handle_t	dma_handle;	/* DMA handle	*/
	nxge_os_acc_handle_t	acc_handle;	/* DMA memory handle */
	npi_handle_t		npi_handle;
} rx_dma_handle_t, *p_rx_dma_handle_t;


/* Receive Completion Ring */
typedef struct _rx_rcr_ring_t {
	nxge_os_dma_common_t	rcr_desc;

	struct _nxge_t		*nxgep;

	p_nxge_rx_ring_stats_t	rdc_stats;

	boolean_t		poll_flag;	/* B_TRUE, if polling mode */

	rcrcfig_a_t		rcr_cfga;
	rcrcfig_b_t		rcr_cfgb;

	nxge_os_mutex_t 	lock;
	uint16_t		index;
	uint16_t		rdc;
	boolean_t		full_hdr_flag;	 /* 1: 18 bytes header */
	uint16_t		sw_priv_hdr_len; /* 0 - 192 bytes (SW) */
	uint32_t 		comp_size;	 /* # of RCR entries */
	uint64_t		rcr_addr;
	uint_t 			comp_wrap_mask;
	uint_t 			comp_rd_index;
	uint_t 			comp_wt_index;

	p_rcr_entry_t		rcr_desc_first_p;
	p_rcr_entry_t		rcr_desc_first_pp;
	p_rcr_entry_t		rcr_desc_last_p;
	p_rcr_entry_t		rcr_desc_last_pp;

	p_rcr_entry_t		rcr_desc_rd_head_p;	/* software next read */
	p_rcr_entry_t		rcr_desc_rd_head_pp;

	uint64_t		rcr_tail_pp;
	uint64_t		rcr_head_pp;
	struct _rx_rbr_ring_t	*rx_rbr_p;
	uint32_t		intr_timeout;
	uint32_t		intr_threshold;
	uint64_t		max_receive_pkts;
	mac_ring_handle_t	rcr_mac_handle;
	uint64_t		rcr_gen_num;
	uint32_t		rcvd_pkt_bytes; /* Received bytes of a packet */
	p_nxge_ldv_t		ldvp;
	p_nxge_ldg_t		ldgp;
	boolean_t		started;
} rx_rcr_ring_t, *p_rx_rcr_ring_t;



/* Buffer index information */
typedef struct _rxbuf_index_info_t {
	uint32_t buf_index;
	uint32_t start_index;
	uint32_t buf_size;
	uint64_t dvma_addr;
	uint64_t kaddr;
} rxbuf_index_info_t, *p_rxbuf_index_info_t;

/*
 * Buffer index information
 */
typedef struct _rxring_info_t {
	uint32_t hint[RCR_N_PKTBUF_SZ];
	uint32_t block_size_mask;
	uint16_t max_iterations;
	rxbuf_index_info_t buffer[NXGE_DMA_BLOCK];
} rxring_info_t, *p_rxring_info_t;


typedef enum {
	RBR_POSTING = 1,	/* We may post rx buffers. */
	RBR_UNMAPPING,		/* We are in the process of unmapping. */
	RBR_UNMAPPED		/* The ring is unmapped. */
} rbr_state_t;


/* Receive Buffer Block Ring */
typedef struct _rx_rbr_ring_t {
	nxge_os_dma_common_t	rbr_desc;
	p_rx_msg_t 		*rx_msg_ring;
	p_nxge_dma_common_t 	*dma_bufp;
	rbr_cfig_a_t		rbr_cfga;
	rbr_cfig_b_t		rbr_cfgb;
	rbr_kick_t		rbr_kick;
	log_page_vld_t		page_valid;
	log_page_mask_t		page_mask_1;
	log_page_mask_t		page_mask_2;
	log_page_value_t	page_value_1;
	log_page_value_t	page_value_2;
	log_page_relo_t		page_reloc_1;
	log_page_relo_t		page_reloc_2;
	log_page_hdl_t		page_hdl;

	boolean_t		cfg_set;

	nxge_os_mutex_t		lock;
	nxge_os_mutex_t		post_lock;
	uint16_t		index;
	struct _nxge_t		*nxgep;
	uint16_t		rdc;
	uint16_t		rdc_grp_id;
	uint_t 			rbr_max_size;
	uint64_t		rbr_addr;
	uint_t 			rbr_wrap_mask;
	uint_t 			rbb_max;
	uint_t 			rbb_added;
	uint_t			block_size;
	uint_t			num_blocks;
	uint_t			tnblocks;
	uint_t			pkt_buf_size0;
	uint_t			pkt_buf_size0_bytes;
	uint_t			npi_pkt_buf_size0;
	uint_t			pkt_buf_size1;
	uint_t			pkt_buf_size1_bytes;
	uint_t			npi_pkt_buf_size1;
	uint_t			pkt_buf_size2;
	uint_t			pkt_buf_size2_bytes;
	uint_t			npi_pkt_buf_size2;

	uint32_t		*rbr_desc_vp;

	p_rx_rcr_ring_t		rx_rcr_p;

	uint_t 			rbr_wr_index;
	uint_t 			rbr_rd_index;

	rxring_info_t  *ring_info;
#if	defined(sun4v) && defined(NIU_LP_WORKAROUND)
	uint64_t		hv_rx_buf_base_ioaddr_pp;
	uint64_t		hv_rx_buf_ioaddr_size;
	uint64_t		hv_rx_cntl_base_ioaddr_pp;
	uint64_t		hv_rx_cntl_ioaddr_size;
	boolean_t		hv_set;
#endif
	uint_t 			rbr_consumed;
	uint_t 			rbr_threshold_hi;
	uint_t 			rbr_threshold_lo;
	nxge_rxbuf_type_t	rbr_bufsize_type;
	boolean_t		rbr_use_bcopy;

	/*
	 * <rbr_ref_cnt> is a count of those receive buffers which
	 * have been loaned to the kernel.  We will not free this
	 * ring until the reference count reaches zero (0).
	 */
	uint32_t		rbr_ref_cnt;
	rbr_state_t		rbr_state; /* POSTING, etc */
	/*
	 * Receive buffer allocation types:
	 *   ddi_dma_mem_alloc(), contig_mem_alloc(), kmem_alloc()
	 */
	buf_alloc_type_t	rbr_alloc_type;
} rx_rbr_ring_t, *p_rx_rbr_ring_t;

/* Receive Mailbox */
typedef struct _rx_mbox_t {
	nxge_os_dma_common_t	rx_mbox;
	rxdma_cfig1_t		rx_cfg1;
	rxdma_cfig2_t		rx_cfg2;
	uint64_t		mbox_addr;
	boolean_t		cfg_set;

	nxge_os_mutex_t 	lock;
	uint16_t		index;
	struct _nxge_t		*nxgep;
	uint16_t		rdc;
} rx_mbox_t, *p_rx_mbox_t;


typedef struct _rx_rbr_rings_t {
	p_rx_rbr_ring_t 	*rbr_rings;
	uint32_t		ndmas;
	boolean_t		rxbuf_allocated;
} rx_rbr_rings_t, *p_rx_rbr_rings_t;

typedef struct _rx_rcr_rings_t {
	p_rx_rcr_ring_t 	*rcr_rings;
	uint32_t		ndmas;
	boolean_t		cntl_buf_allocated;
} rx_rcr_rings_t, *p_rx_rcr_rings_t;

typedef struct _rx_mbox_areas_t {
	p_rx_mbox_t 		*rxmbox_areas;
	uint32_t		ndmas;
	boolean_t		mbox_allocated;
} rx_mbox_areas_t, *p_rx_mbox_areas_t;

/*
 * Global register definitions per chip and they are initialized
 * using the function zero control registers.
 * .
 */

typedef struct _rxdma_globals {
	boolean_t		mode32;
	uint16_t		rxdma_ck_div_cnt;
	uint16_t		rxdma_red_ran_init;
	uint32_t		rxdma_eing_timeout;
} rxdma_globals_t, *p_rxdma_globals;


/*
 * Receive DMA Prototypes.
 */
nxge_status_t nxge_init_rxdma_channels(p_nxge_t);
void nxge_uninit_rxdma_channels(p_nxge_t);

nxge_status_t nxge_init_rxdma_channel(p_nxge_t, int);
void nxge_uninit_rxdma_channel(p_nxge_t, int);

nxge_status_t nxge_init_rxdma_channel_rcrflush(p_nxge_t, uint8_t);
nxge_status_t nxge_reset_rxdma_channel(p_nxge_t, uint16_t);
nxge_status_t nxge_init_rxdma_channel_cntl_stat(p_nxge_t,
	uint16_t, p_rx_dma_ctl_stat_t);
nxge_status_t nxge_enable_rxdma_channel(p_nxge_t,
	uint16_t, p_rx_rbr_ring_t, p_rx_rcr_ring_t,
	p_rx_mbox_t);
nxge_status_t nxge_init_rxdma_channel_event_mask(p_nxge_t,
		uint16_t, p_rx_dma_ent_msk_t);

nxge_status_t nxge_rxdma_hw_mode(p_nxge_t, boolean_t);
void nxge_hw_start_rx(p_nxge_t);
void nxge_fixup_rxdma_rings(p_nxge_t);
nxge_status_t nxge_dump_rxdma_channel(p_nxge_t, uint8_t);

void nxge_rxdma_fix_channel(p_nxge_t, uint16_t);

mblk_t *nxge_rx_poll(void *, int);
int nxge_enable_poll(void *);
int nxge_disable_poll(void *);

void nxge_rxdma_regs_dump_channels(p_nxge_t);
nxge_status_t nxge_rxdma_handle_sys_errors(p_nxge_t);
void nxge_rxdma_inject_err(p_nxge_t, uint32_t, uint8_t);

extern nxge_status_t nxge_alloc_rx_mem_pool(p_nxge_t);
extern nxge_status_t nxge_alloc_rxb(p_nxge_t nxgep, int channel);
extern void nxge_free_rxb(p_nxge_t nxgep, int channel);

int nxge_get_rxring_index(p_nxge_t, int, int);

#ifdef	__cplusplus
}
#endif

#endif	/* _SYS_NXGE_NXGE_RXDMA_H */