summaryrefslogtreecommitdiff
path: root/usr/src/uts/common/io/xge/drv/xgell.h
blob: 39c6447ebf44d2af890a1b0bdc1ec166b39f061a (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
/*
 * 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.
 */

/*
 *  Copyright (c) 2002-2005 Neterion, Inc.
 *  All right Reserved.
 *
 *  FileName :    xgell.h
 *
 *  Description:  Link Layer driver declaration
 *
 */

#ifndef _SYS_XGELL_H
#define	_SYS_XGELL_H

#include <sys/types.h>
#include <sys/errno.h>
#include <sys/param.h>
#include <sys/stropts.h>
#include <sys/stream.h>
#include <sys/strsubr.h>
#include <sys/kmem.h>
#include <sys/conf.h>
#include <sys/devops.h>
#include <sys/ksynch.h>
#include <sys/stat.h>
#include <sys/modctl.h>
#include <sys/debug.h>
#include <sys/pci.h>
#include <sys/ethernet.h>
#include <sys/vlan.h>
#include <sys/dlpi.h>
#include <sys/taskq.h>
#include <sys/cyclic.h>

#include <sys/pattr.h>
#include <sys/strsun.h>

#include <sys/mac_provider.h>
#include <sys/mac_ether.h>

#ifdef __cplusplus
extern "C" {
#endif

#define	XGELL_DESC		"Xframe I/II 10Gb Ethernet"
#define	XGELL_IFNAME		"xge"

#include <xgehal.h>

/*
 * The definition of XGELL_RX_BUFFER_RECYCLE_CACHE is an experimental value.
 * With this value, the lock contention between xgell_rx_buffer_recycle()
 * and xgell_rx_1b_compl() is reduced to great extent. And multiple rx rings
 * alleviate the lock contention further since each rx ring has its own mutex.
 */
#define	XGELL_RX_BUFFER_RECYCLE_CACHE	XGE_HAL_RING_RXDS_PER_BLOCK(1) * 2
#define	MSG_SIZE	64

/*
 * These default values can be overridden by vaules in xge.conf.
 * In xge.conf user has to specify actual (not percentages) values.
 */
#define	XGELL_RX_BUFFER_TOTAL		XGE_HAL_RING_RXDS_PER_BLOCK(1) * 6
#define	XGELL_RX_BUFFER_POST_HIWAT	XGE_HAL_RING_RXDS_PER_BLOCK(1) * 5

/*
 * Multiple rings configuration
 */
#define	XGELL_RX_RING_MAIN			0
#define	XGELL_TX_RING_MAIN			0

#define	XGELL_RX_RING_NUM_MIN			1
#define	XGELL_TX_RING_NUM_MIN			1
#define	XGELL_RX_RING_NUM_MAX			8
#define	XGELL_TX_RING_NUM_MAX			1 /* TODO */
#define	XGELL_RX_RING_NUM_DEFAULT		XGELL_RX_RING_NUM_MAX
#define	XGELL_TX_RING_NUM_DEFAULT		XGELL_TX_RING_NUM_MAX

#define	XGELL_MINTR_NUM_MIN			1
#define	XGELL_MINTR_NUM_MAX			\
	(XGELL_RX_RING_NUM_MAX + XGELL_TX_RING_NUM_MAX + 1)
#define	XGELL_MINTR_NUM_DEFAULT			XGELL_MINTR_NUM_MAX

#define	XGELL_CONF_GROUP_POLICY_BASIC		0
#define	XGELL_CONF_GROUP_POLICY_VIRT		1
#define	XGELL_CONF_GROUP_POLICY_PERF		2
#if 0
#if defined(__sparc)
#define	XGELL_CONF_GROUP_POLICY_DEFAULT		XGELL_CONF_GROUP_POLICY_PERF
#else
#define	XGELL_CONF_GROUP_POLICY_DEFAULT		XGELL_CONF_GROUP_POLICY_VIRT
#endif
#else
/*
 * The _PERF configuration enable a fat group of all rx rings, as approachs
 * better fanout performance of the primary interface.
 */
#define	XGELL_CONF_GROUP_POLICY_DEFAULT		XGELL_CONF_GROUP_POLICY_PERF
#endif

#define	XGELL_TX_LEVEL_LOW	8
#define	XGELL_TX_LEVEL_HIGH	32
#define	XGELL_TX_LEVEL_CHECK	3
#define	XGELL_MAX_RING_DEFAULT	8
#define	XGELL_MAX_FIFO_DEFAULT	1

/* Control driver to copy or DMA inbound/outbound packets */
#if defined(__sparc)
#define	XGELL_RX_DMA_LOWAT			256
#define	XGELL_TX_DMA_LOWAT			512
#else
#define	XGELL_RX_DMA_LOWAT			256
#define	XGELL_TX_DMA_LOWAT			128
#endif

/*
 * Try to collapse up to XGELL_RX_PKT_BURST packets into single mblk
 * sequence before mac_rx() is called.
 */
#define	XGELL_RX_PKT_BURST			32

/* About 1s */
#define	XGE_DEV_POLL_TICKS			drv_usectohz(1000000)

#define	XGELL_LSO_MAXLEN			65535
#define	XGELL_CONF_ENABLE_BY_DEFAULT		1
#define	XGELL_CONF_DISABLE_BY_DEFAULT		0

/* LRO configuration */
#define	XGE_HAL_DEFAULT_LRO_SG_SIZE		2 /* <=2 LRO fix not required */
#define	XGE_HAL_DEFAULT_LRO_FRM_LEN		65535

/*
 * Default values for tunables used in HAL. Please refer to xgehal-config.h
 * for more details.
 */
#define	XGE_HAL_DEFAULT_USE_HARDCODE		-1

/* Bimodal adaptive schema defaults - ENABLED */
#define	XGE_HAL_DEFAULT_BIMODAL_INTERRUPTS	-1
#define	XGE_HAL_DEFAULT_BIMODAL_TIMER_LO_US	24
#define	XGE_HAL_DEFAULT_BIMODAL_TIMER_HI_US	256

/* Interrupt moderation/utilization defaults */
#define	XGE_HAL_DEFAULT_TX_URANGE_A		5
#define	XGE_HAL_DEFAULT_TX_URANGE_B		15
#define	XGE_HAL_DEFAULT_TX_URANGE_C		30
#define	XGE_HAL_DEFAULT_TX_UFC_A		15
#define	XGE_HAL_DEFAULT_TX_UFC_B		30
#define	XGE_HAL_DEFAULT_TX_UFC_C		45
#define	XGE_HAL_DEFAULT_TX_UFC_D		60
#define	XGE_HAL_DEFAULT_TX_TIMER_CI_EN		1
#define	XGE_HAL_DEFAULT_TX_TIMER_AC_EN		1
#define	XGE_HAL_DEFAULT_TX_TIMER_VAL		10000
#define	XGE_HAL_DEFAULT_INDICATE_MAX_PKTS_B	512 /* bimodal */
#define	XGE_HAL_DEFAULT_INDICATE_MAX_PKTS_N	256 /* normal UFC */
#define	XGE_HAL_DEFAULT_RX_URANGE_A		10
#define	XGE_HAL_DEFAULT_RX_URANGE_B		30
#define	XGE_HAL_DEFAULT_RX_URANGE_C		50
#define	XGE_HAL_DEFAULT_RX_UFC_A		1
#define	XGE_HAL_DEFAULT_RX_UFC_B_J		2
#define	XGE_HAL_DEFAULT_RX_UFC_B_N		8
#define	XGE_HAL_DEFAULT_RX_UFC_C_J		4
#define	XGE_HAL_DEFAULT_RX_UFC_C_N		16
#define	XGE_HAL_DEFAULT_RX_UFC_D		32
#define	XGE_HAL_DEFAULT_RX_TIMER_AC_EN		1
#define	XGE_HAL_DEFAULT_RX_TIMER_VAL		384

#define	XGE_HAL_DEFAULT_FIFO_QUEUE_LENGTH_A	1024
#define	XGE_HAL_DEFAULT_FIFO_QUEUE_LENGTH_J	2048
#define	XGE_HAL_DEFAULT_FIFO_QUEUE_LENGTH_N	4096
#define	XGE_HAL_DEFAULT_FIFO_QUEUE_INTR		0
#define	XGE_HAL_DEFAULT_FIFO_RESERVE_THRESHOLD	0
#define	XGE_HAL_DEFAULT_FIFO_MEMBLOCK_SIZE	PAGESIZE

/*
 * This will force HAL to allocate extra copied buffer per TXDL which
 * size calculated by formula:
 *
 *      (ALIGNMENT_SIZE * ALIGNED_FRAGS)
 */
#define	XGE_HAL_DEFAULT_FIFO_ALIGNMENT_SIZE	4096
#define	XGE_HAL_DEFAULT_FIFO_MAX_ALIGNED_FRAGS	1
#if defined(__sparc)
#define	XGE_HAL_DEFAULT_FIFO_FRAGS		64
#else
#define	XGE_HAL_DEFAULT_FIFO_FRAGS		128
#endif
#define	XGE_HAL_DEFAULT_FIFO_FRAGS_THRESHOLD	18

#define	XGE_HAL_DEFAULT_RING_QUEUE_BLOCKS	2
#define	XGE_HAL_RING_QUEUE_BUFFER_MODE_DEFAULT	1
#define	XGE_HAL_DEFAULT_BACKOFF_INTERVAL_US	64
#define	XGE_HAL_DEFAULT_RING_PRIORITY		0
#define	XGE_HAL_DEFAULT_RING_MEMBLOCK_SIZE	PAGESIZE

#define	XGE_HAL_DEFAULT_RING_NUM		8
#define	XGE_HAL_DEFAULT_TMAC_UTIL_PERIOD	5
#define	XGE_HAL_DEFAULT_RMAC_UTIL_PERIOD	5
#define	XGE_HAL_DEFAULT_RMAC_HIGH_PTIME		65535
#define	XGE_HAL_DEFAULT_MC_PAUSE_THRESHOLD_Q0Q3	187
#define	XGE_HAL_DEFAULT_MC_PAUSE_THRESHOLD_Q4Q7	187
#define	XGE_HAL_DEFAULT_RMAC_PAUSE_GEN_EN	1
#define	XGE_HAL_DEFAULT_RMAC_PAUSE_GEN_DIS	0
#define	XGE_HAL_DEFAULT_RMAC_PAUSE_RCV_EN	1
#define	XGE_HAL_DEFAULT_RMAC_PAUSE_RCV_DIS	0
#define	XGE_HAL_DEFAULT_INITIAL_MTU		XGE_HAL_DEFAULT_MTU /* 1500 */
#define	XGE_HAL_DEFAULT_ISR_POLLING_CNT		0
#define	XGE_HAL_DEFAULT_LATENCY_TIMER		255
#define	XGE_HAL_DEFAULT_SHARED_SPLITS		0
#define	XGE_HAL_DEFAULT_STATS_REFRESH_TIME	1

#if defined(__sparc)
#define	XGE_HAL_DEFAULT_MMRB_COUNT		XGE_HAL_MAX_MMRB_COUNT
#define	XGE_HAL_DEFAULT_SPLIT_TRANSACTION	XGE_HAL_EIGHT_SPLIT_TRANSACTION
#else
#define	XGE_HAL_DEFAULT_MMRB_COUNT		1 /* 1k */
#define	XGE_HAL_DEFAULT_SPLIT_TRANSACTION	XGE_HAL_TWO_SPLIT_TRANSACTION
#endif

/*
 * Default the size of buffers allocated for ndd interface functions
 */
#define	XGELL_STATS_BUFSIZE			8192
#define	XGELL_PCICONF_BUFSIZE			2048
#define	XGELL_ABOUT_BUFSIZE			512
#define	XGELL_IOCTL_BUFSIZE			64
#define	XGELL_DEVCONF_BUFSIZE			8192

/*
 * Multiple mac address definitions
 *
 * We'll use whole MAC Addresses Configuration Memory for unicast addresses,
 * since current multicast implementation in HAL is by enabling promise mode.
 */
#define	XGE_RX_MULTI_MAC_ADDRESSES_MAX		8 /* per ring group */

typedef struct {
	int rx_pkt_burst;
	int rx_buffer_total;
	int rx_buffer_post_hiwat;
	int rx_dma_lowat;
	int tx_dma_lowat;
	int lso_enable;
	int msix_enable;
	int grouping;
} xgell_config_t;

typedef struct xgell_multi_mac xgell_multi_mac_t;
typedef struct xgell_rx_ring xgell_rx_ring_t;
typedef struct xgell_tx_ring xgell_tx_ring_t;
typedef struct xgelldev xgelldev_t;

typedef struct xgell_rx_buffer_t {
	struct xgell_rx_buffer_t *next;
	void			*vaddr;
	dma_addr_t		dma_addr;
	ddi_dma_handle_t	dma_handle;
	ddi_acc_handle_t	dma_acch;
	xgell_rx_ring_t		*ring;
	frtn_t			frtn;
} xgell_rx_buffer_t;

/* Buffer pool for one rx ring */
typedef struct xgell_rx_buffer_pool_t {
	uint_t			total;		/* total buffers */
	uint_t			size;		/* buffer size */
	xgell_rx_buffer_t	*head;		/* header pointer */
	uint_t			free;		/* free buffers */
	uint_t			post;		/* posted buffers */
	uint_t			post_hiwat;	/* hiwat to stop post */
	spinlock_t		pool_lock;	/* buffer pool lock */
	boolean_t		live;		/* pool status */
	xgell_rx_buffer_t	*recycle_head;	/* recycle list's head */
	xgell_rx_buffer_t	*recycle_tail;	/* recycle list's tail */
	uint_t			recycle;	/* # of rx buffers recycled */
	spinlock_t		recycle_lock;	/* buffer recycle lock */
} xgell_rx_buffer_pool_t;

struct xgell_multi_mac {
	int			naddr;		/* total supported addresses */
	int			naddrfree;	/* free addresses slots */
	ether_addr_t		mac_addr[XGE_RX_MULTI_MAC_ADDRESSES_MAX];
	boolean_t		mac_addr_set[XGE_RX_MULTI_MAC_ADDRESSES_MAX];
};

typedef uint_t (*intr_func_t)(caddr_t, caddr_t);

typedef struct xgell_intr {
	uint_t			index;
	ddi_intr_handle_t	*handle;	/* DDI interrupt handle */
	intr_func_t		*function;	/* interrupt function */
	caddr_t			arg;		/* interrupt source */
} xgell_intr_t;

struct xgell_rx_ring {
	int			index;
	boolean_t		live;		/* ring active status */
	xge_hal_channel_h	channelh;	/* hardware channel */
	xgelldev_t		*lldev;		/* driver device */
	mac_ring_handle_t	ring_handle;	/* call back ring handle */
	mac_group_handle_t	group_handle;	/* call back group handle */
	uint64_t		ring_gen_num;

	xgell_multi_mac_t	mmac;		/* per group multiple addrs */
	xgell_rx_buffer_pool_t	bf_pool;	/* per ring buffer pool */
	uint64_t		rx_pkts;	/* total received packets */
	uint64_t		rx_bytes;	/* total received bytes */
	int			poll_bytes;	/* bytes to be polled up */
	int			polled_bytes;	/* total polled bytes */
	mblk_t			*poll_mp;	/* polled messages */

	spinlock_t		ring_lock;	/* per ring lock */
};

struct xgell_tx_ring {
	int			index;
	boolean_t		live;		/* ring active status */
	xge_hal_channel_h	channelh;	/* hardware channel */
	xgelldev_t		*lldev;		/* driver device */
	mac_ring_handle_t	ring_handle;	/* call back ring handle */
	uint64_t		tx_pkts;	/* packets sent */
	uint64_t		tx_bytes;	/* bytes sent though the ring */

	boolean_t		need_resched;
};

struct xgelldev {
	volatile int		is_initialized;
	volatile int		in_reset;
	kmutex_t		genlock;
	mac_handle_t		mh;
	int			instance;
	dev_info_t		*dev_info;
	xge_hal_device_h	devh;
	caddr_t			ndp;
	timeout_id_t		timeout_id;

	int			init_rx_rings;
	int			init_tx_rings;
	int			init_rx_groups;

	int			live_rx_rings;
	int			live_tx_rings;
	xgell_rx_ring_t		rx_ring[XGELL_RX_RING_NUM_DEFAULT];
	xgell_tx_ring_t		tx_ring[XGELL_TX_RING_NUM_DEFAULT];

	int			tx_copied_max;

	xgell_intr_t		intrs[XGELL_MINTR_NUM_DEFAULT];

	ddi_intr_handle_t	*intr_table;
	uint_t			intr_table_size;
	int			intr_type;
	int			intr_cnt;
	uint_t			intr_pri;
	int			intr_cap;

	xgell_config_t		config;
};

typedef struct {
	mblk_t			*mblk;
	ddi_dma_handle_t	dma_handles[XGE_HAL_DEFAULT_FIFO_FRAGS];
	int			handle_cnt;
} xgell_txd_priv_t;

typedef struct {
	xgell_rx_buffer_t	*rx_buffer;
} xgell_rxd_priv_t;

int xgell_device_alloc(xge_hal_device_h devh, dev_info_t *dev_info,
    xgelldev_t **lldev_out);

void xgell_device_free(xgelldev_t *lldev);

int xgell_device_register(xgelldev_t *lldev, xgell_config_t *config);

int xgell_device_unregister(xgelldev_t *lldev);

void xgell_callback_link_up(void *userdata);

void xgell_callback_link_down(void *userdata);

int xgell_onerr_reset(xgelldev_t *lldev);

void xge_device_poll_now(void *data);

int xge_add_intrs(xgelldev_t *lldev);

int xge_enable_intrs(xgelldev_t *lldev);

void xge_disable_intrs(xgelldev_t *lldev);

void xge_rem_intrs(xgelldev_t *lldev);

int xgell_rx_ring_stat(mac_ring_driver_t rh, uint_t stat, uint64_t *val);

int xgell_tx_ring_stat(mac_ring_driver_t rh, uint_t stat, uint64_t *val);

#ifdef __cplusplus
}
#endif

#endif /* _SYS_XGELL_H */