xref: /illumos-gate/usr/src/uts/common/io/xge/drv/xgell.h (revision 1f5207b7604fb44407eb4342aff613f7c4508508)
1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License (the "License").
6  * You may not use this file except in compliance with the License.
7  *
8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9  * or http://www.opensolaris.org/os/licensing.
10  * See the License for the specific language governing permissions
11  * and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL HEADER in each
14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15  * If applicable, add the following below this CDDL HEADER, with the
16  * fields enclosed by brackets "[]" replaced with your own identifying
17  * information: Portions Copyright [yyyy] [name of copyright owner]
18  *
19  * CDDL HEADER END
20  */
21 
22 /*
23  * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
24  * Use is subject to license terms.
25  */
26 
27 /*
28  *  Copyright (c) 2002-2005 Neterion, Inc.
29  *  All right Reserved.
30  *
31  *  FileName :    xgell.h
32  *
33  *  Description:  Link Layer driver declaration
34  *
35  */
36 
37 #ifndef _SYS_XGELL_H
38 #define	_SYS_XGELL_H
39 
40 #include <sys/types.h>
41 #include <sys/errno.h>
42 #include <sys/param.h>
43 #include <sys/stropts.h>
44 #include <sys/stream.h>
45 #include <sys/strsubr.h>
46 #include <sys/kmem.h>
47 #include <sys/conf.h>
48 #include <sys/devops.h>
49 #include <sys/ksynch.h>
50 #include <sys/stat.h>
51 #include <sys/modctl.h>
52 #include <sys/debug.h>
53 #include <sys/pci.h>
54 #include <sys/ethernet.h>
55 #include <sys/vlan.h>
56 #include <sys/dlpi.h>
57 #include <sys/taskq.h>
58 #include <sys/cyclic.h>
59 
60 #include <sys/pattr.h>
61 #include <sys/strsun.h>
62 
63 #include <sys/mac_provider.h>
64 #include <sys/mac_ether.h>
65 
66 #ifdef __cplusplus
67 extern "C" {
68 #endif
69 
70 #define	XGELL_DESC		"Xframe I/II 10Gb Ethernet"
71 #define	XGELL_IFNAME		"xge"
72 
73 #include <xgehal.h>
74 
75 /*
76  * The definition of XGELL_RX_BUFFER_RECYCLE_CACHE is an experimental value.
77  * With this value, the lock contention between xgell_rx_buffer_recycle()
78  * and xgell_rx_1b_compl() is reduced to great extent. And multiple rx rings
79  * alleviate the lock contention further since each rx ring has its own mutex.
80  */
81 #define	XGELL_RX_BUFFER_RECYCLE_CACHE	XGE_HAL_RING_RXDS_PER_BLOCK(1) * 2
82 #define	MSG_SIZE	64
83 
84 /*
85  * These default values can be overridden by vaules in xge.conf.
86  * In xge.conf user has to specify actual (not percentages) values.
87  */
88 #define	XGELL_RX_BUFFER_TOTAL		XGE_HAL_RING_RXDS_PER_BLOCK(1) * 6
89 #define	XGELL_RX_BUFFER_POST_HIWAT	XGE_HAL_RING_RXDS_PER_BLOCK(1) * 5
90 
91 /*
92  * Multiple rings configuration
93  */
94 #define	XGELL_RX_RING_MAIN			0
95 #define	XGELL_TX_RING_MAIN			0
96 
97 #define	XGELL_RX_RING_NUM_MIN			1
98 #define	XGELL_TX_RING_NUM_MIN			1
99 #define	XGELL_RX_RING_NUM_MAX			8
100 #define	XGELL_TX_RING_NUM_MAX			1 /* TODO */
101 #define	XGELL_RX_RING_NUM_DEFAULT		XGELL_RX_RING_NUM_MAX
102 #define	XGELL_TX_RING_NUM_DEFAULT		XGELL_TX_RING_NUM_MAX
103 
104 #define	XGELL_MINTR_NUM_MIN			1
105 #define	XGELL_MINTR_NUM_MAX			\
106 	(XGELL_RX_RING_NUM_MAX + XGELL_TX_RING_NUM_MAX + 1)
107 #define	XGELL_MINTR_NUM_DEFAULT			XGELL_MINTR_NUM_MAX
108 
109 #define	XGELL_CONF_GROUP_POLICY_BASIC		0
110 #define	XGELL_CONF_GROUP_POLICY_VIRT		1
111 #define	XGELL_CONF_GROUP_POLICY_PERF		2
112 #if 0
113 #if defined(__sparc)
114 #define	XGELL_CONF_GROUP_POLICY_DEFAULT		XGELL_CONF_GROUP_POLICY_PERF
115 #else
116 #define	XGELL_CONF_GROUP_POLICY_DEFAULT		XGELL_CONF_GROUP_POLICY_VIRT
117 #endif
118 #else
119 /*
120  * The _PERF configuration enable a fat group of all rx rings, as approachs
121  * better fanout performance of the primary interface.
122  */
123 #define	XGELL_CONF_GROUP_POLICY_DEFAULT		XGELL_CONF_GROUP_POLICY_PERF
124 #endif
125 
126 #define	XGELL_TX_LEVEL_LOW	8
127 #define	XGELL_TX_LEVEL_HIGH	32
128 #define	XGELL_TX_LEVEL_CHECK	3
129 #define	XGELL_MAX_RING_DEFAULT	8
130 #define	XGELL_MAX_FIFO_DEFAULT	1
131 
132 /* Control driver to copy or DMA inbound/outbound packets */
133 #if defined(__sparc)
134 #define	XGELL_RX_DMA_LOWAT			256
135 #define	XGELL_TX_DMA_LOWAT			512
136 #else
137 #define	XGELL_RX_DMA_LOWAT			256
138 #define	XGELL_TX_DMA_LOWAT			128
139 #endif
140 
141 /*
142  * Try to collapse up to XGELL_RX_PKT_BURST packets into single mblk
143  * sequence before mac_rx() is called.
144  */
145 #define	XGELL_RX_PKT_BURST			32
146 
147 /* About 1s */
148 #define	XGE_DEV_POLL_TICKS			drv_usectohz(1000000)
149 
150 #define	XGELL_LSO_MAXLEN			65535
151 #define	XGELL_CONF_ENABLE_BY_DEFAULT		1
152 #define	XGELL_CONF_DISABLE_BY_DEFAULT		0
153 
154 /* LRO configuration */
155 #define	XGE_HAL_DEFAULT_LRO_SG_SIZE		2 /* <=2 LRO fix not required */
156 #define	XGE_HAL_DEFAULT_LRO_FRM_LEN		65535
157 
158 /*
159  * Default values for tunables used in HAL. Please refer to xgehal-config.h
160  * for more details.
161  */
162 #define	XGE_HAL_DEFAULT_USE_HARDCODE		-1
163 
164 /* Bimodal adaptive schema defaults - ENABLED */
165 #define	XGE_HAL_DEFAULT_BIMODAL_INTERRUPTS	-1
166 #define	XGE_HAL_DEFAULT_BIMODAL_TIMER_LO_US	24
167 #define	XGE_HAL_DEFAULT_BIMODAL_TIMER_HI_US	256
168 
169 /* Interrupt moderation/utilization defaults */
170 #define	XGE_HAL_DEFAULT_TX_URANGE_A		5
171 #define	XGE_HAL_DEFAULT_TX_URANGE_B		15
172 #define	XGE_HAL_DEFAULT_TX_URANGE_C		30
173 #define	XGE_HAL_DEFAULT_TX_UFC_A		15
174 #define	XGE_HAL_DEFAULT_TX_UFC_B		30
175 #define	XGE_HAL_DEFAULT_TX_UFC_C		45
176 #define	XGE_HAL_DEFAULT_TX_UFC_D		60
177 #define	XGE_HAL_DEFAULT_TX_TIMER_CI_EN		1
178 #define	XGE_HAL_DEFAULT_TX_TIMER_AC_EN		1
179 #define	XGE_HAL_DEFAULT_TX_TIMER_VAL		10000
180 #define	XGE_HAL_DEFAULT_INDICATE_MAX_PKTS_B	512 /* bimodal */
181 #define	XGE_HAL_DEFAULT_INDICATE_MAX_PKTS_N	256 /* normal UFC */
182 #define	XGE_HAL_DEFAULT_RX_URANGE_A		10
183 #define	XGE_HAL_DEFAULT_RX_URANGE_B		30
184 #define	XGE_HAL_DEFAULT_RX_URANGE_C		50
185 #define	XGE_HAL_DEFAULT_RX_UFC_A		1
186 #define	XGE_HAL_DEFAULT_RX_UFC_B_J		2
187 #define	XGE_HAL_DEFAULT_RX_UFC_B_N		8
188 #define	XGE_HAL_DEFAULT_RX_UFC_C_J		4
189 #define	XGE_HAL_DEFAULT_RX_UFC_C_N		16
190 #define	XGE_HAL_DEFAULT_RX_UFC_D		32
191 #define	XGE_HAL_DEFAULT_RX_TIMER_AC_EN		1
192 #define	XGE_HAL_DEFAULT_RX_TIMER_VAL		384
193 
194 #define	XGE_HAL_DEFAULT_FIFO_QUEUE_LENGTH_A	1024
195 #define	XGE_HAL_DEFAULT_FIFO_QUEUE_LENGTH_J	2048
196 #define	XGE_HAL_DEFAULT_FIFO_QUEUE_LENGTH_N	4096
197 #define	XGE_HAL_DEFAULT_FIFO_QUEUE_INTR		0
198 #define	XGE_HAL_DEFAULT_FIFO_RESERVE_THRESHOLD	0
199 #define	XGE_HAL_DEFAULT_FIFO_MEMBLOCK_SIZE	PAGESIZE
200 
201 /*
202  * This will force HAL to allocate extra copied buffer per TXDL which
203  * size calculated by formula:
204  *
205  *      (ALIGNMENT_SIZE * ALIGNED_FRAGS)
206  */
207 #define	XGE_HAL_DEFAULT_FIFO_ALIGNMENT_SIZE	4096
208 #define	XGE_HAL_DEFAULT_FIFO_MAX_ALIGNED_FRAGS	1
209 #if defined(__sparc)
210 #define	XGE_HAL_DEFAULT_FIFO_FRAGS		64
211 #else
212 #define	XGE_HAL_DEFAULT_FIFO_FRAGS		128
213 #endif
214 #define	XGE_HAL_DEFAULT_FIFO_FRAGS_THRESHOLD	18
215 
216 #define	XGE_HAL_DEFAULT_RING_QUEUE_BLOCKS	2
217 #define	XGE_HAL_RING_QUEUE_BUFFER_MODE_DEFAULT	1
218 #define	XGE_HAL_DEFAULT_BACKOFF_INTERVAL_US	64
219 #define	XGE_HAL_DEFAULT_RING_PRIORITY		0
220 #define	XGE_HAL_DEFAULT_RING_MEMBLOCK_SIZE	PAGESIZE
221 
222 #define	XGE_HAL_DEFAULT_RING_NUM		8
223 #define	XGE_HAL_DEFAULT_TMAC_UTIL_PERIOD	5
224 #define	XGE_HAL_DEFAULT_RMAC_UTIL_PERIOD	5
225 #define	XGE_HAL_DEFAULT_RMAC_HIGH_PTIME		65535
226 #define	XGE_HAL_DEFAULT_MC_PAUSE_THRESHOLD_Q0Q3	187
227 #define	XGE_HAL_DEFAULT_MC_PAUSE_THRESHOLD_Q4Q7	187
228 #define	XGE_HAL_DEFAULT_RMAC_PAUSE_GEN_EN	1
229 #define	XGE_HAL_DEFAULT_RMAC_PAUSE_GEN_DIS	0
230 #define	XGE_HAL_DEFAULT_RMAC_PAUSE_RCV_EN	1
231 #define	XGE_HAL_DEFAULT_RMAC_PAUSE_RCV_DIS	0
232 #define	XGE_HAL_DEFAULT_INITIAL_MTU		XGE_HAL_DEFAULT_MTU /* 1500 */
233 #define	XGE_HAL_DEFAULT_ISR_POLLING_CNT		0
234 #define	XGE_HAL_DEFAULT_LATENCY_TIMER		255
235 #define	XGE_HAL_DEFAULT_SHARED_SPLITS		0
236 #define	XGE_HAL_DEFAULT_STATS_REFRESH_TIME	1
237 
238 #if defined(__sparc)
239 #define	XGE_HAL_DEFAULT_MMRB_COUNT		XGE_HAL_MAX_MMRB_COUNT
240 #define	XGE_HAL_DEFAULT_SPLIT_TRANSACTION	XGE_HAL_EIGHT_SPLIT_TRANSACTION
241 #else
242 #define	XGE_HAL_DEFAULT_MMRB_COUNT		1 /* 1k */
243 #define	XGE_HAL_DEFAULT_SPLIT_TRANSACTION	XGE_HAL_TWO_SPLIT_TRANSACTION
244 #endif
245 
246 /*
247  * Default the size of buffers allocated for ndd interface functions
248  */
249 #define	XGELL_STATS_BUFSIZE			8192
250 #define	XGELL_PCICONF_BUFSIZE			2048
251 #define	XGELL_ABOUT_BUFSIZE			512
252 #define	XGELL_IOCTL_BUFSIZE			64
253 #define	XGELL_DEVCONF_BUFSIZE			8192
254 
255 /*
256  * Multiple mac address definitions
257  *
258  * We'll use whole MAC Addresses Configuration Memory for unicast addresses,
259  * since current multicast implementation in HAL is by enabling promise mode.
260  */
261 #define	XGE_RX_MULTI_MAC_ADDRESSES_MAX		8 /* per ring group */
262 
263 typedef struct {
264 	int rx_pkt_burst;
265 	int rx_buffer_total;
266 	int rx_buffer_post_hiwat;
267 	int rx_dma_lowat;
268 	int tx_dma_lowat;
269 	int lso_enable;
270 	int msix_enable;
271 	int grouping;
272 } xgell_config_t;
273 
274 typedef struct xgell_multi_mac xgell_multi_mac_t;
275 typedef struct xgell_rx_ring xgell_rx_ring_t;
276 typedef struct xgell_tx_ring xgell_tx_ring_t;
277 typedef struct xgelldev xgelldev_t;
278 
279 typedef struct xgell_rx_buffer_t {
280 	struct xgell_rx_buffer_t *next;
281 	void			*vaddr;
282 	dma_addr_t		dma_addr;
283 	ddi_dma_handle_t	dma_handle;
284 	ddi_acc_handle_t	dma_acch;
285 	xgell_rx_ring_t		*ring;
286 	frtn_t			frtn;
287 } xgell_rx_buffer_t;
288 
289 /* Buffer pool for one rx ring */
290 typedef struct xgell_rx_buffer_pool_t {
291 	uint_t			total;		/* total buffers */
292 	uint_t			size;		/* buffer size */
293 	xgell_rx_buffer_t	*head;		/* header pointer */
294 	uint_t			free;		/* free buffers */
295 	uint_t			post;		/* posted buffers */
296 	uint_t			post_hiwat;	/* hiwat to stop post */
297 	spinlock_t		pool_lock;	/* buffer pool lock */
298 	boolean_t		live;		/* pool status */
299 	xgell_rx_buffer_t	*recycle_head;	/* recycle list's head */
300 	xgell_rx_buffer_t	*recycle_tail;	/* recycle list's tail */
301 	uint_t			recycle;	/* # of rx buffers recycled */
302 	spinlock_t		recycle_lock;	/* buffer recycle lock */
303 } xgell_rx_buffer_pool_t;
304 
305 struct xgell_multi_mac {
306 	int			naddr;		/* total supported addresses */
307 	int			naddrfree;	/* free addresses slots */
308 	ether_addr_t		mac_addr[XGE_RX_MULTI_MAC_ADDRESSES_MAX];
309 	boolean_t		mac_addr_set[XGE_RX_MULTI_MAC_ADDRESSES_MAX];
310 };
311 
312 typedef uint_t (*intr_func_t)(caddr_t, caddr_t);
313 
314 typedef struct xgell_intr {
315 	uint_t			index;
316 	ddi_intr_handle_t	*handle;	/* DDI interrupt handle */
317 	intr_func_t		*function;	/* interrupt function */
318 	caddr_t			arg;		/* interrupt source */
319 } xgell_intr_t;
320 
321 struct xgell_rx_ring {
322 	int			index;
323 	boolean_t		live;		/* ring active status */
324 	xge_hal_channel_h	channelh;	/* hardware channel */
325 	xgelldev_t		*lldev;		/* driver device */
326 	mac_ring_handle_t	ring_handle;	/* call back ring handle */
327 	mac_group_handle_t	group_handle;	/* call back group handle */
328 	uint64_t		ring_gen_num;
329 
330 	xgell_multi_mac_t	mmac;		/* per group multiple addrs */
331 	xgell_rx_buffer_pool_t	bf_pool;	/* per ring buffer pool */
332 	uint64_t		rx_pkts;	/* total received packets */
333 	uint64_t		rx_bytes;	/* total received bytes */
334 	int			poll_bytes;	/* bytes to be polled up */
335 	int			polled_bytes;	/* total polled bytes */
336 	mblk_t			*poll_mp;	/* polled messages */
337 
338 	spinlock_t		ring_lock;	/* per ring lock */
339 };
340 
341 struct xgell_tx_ring {
342 	int			index;
343 	boolean_t		live;		/* ring active status */
344 	xge_hal_channel_h	channelh;	/* hardware channel */
345 	xgelldev_t		*lldev;		/* driver device */
346 	mac_ring_handle_t	ring_handle;	/* call back ring handle */
347 	uint64_t		tx_pkts;	/* packets sent */
348 	uint64_t		tx_bytes;	/* bytes sent though the ring */
349 
350 	boolean_t		need_resched;
351 };
352 
353 struct xgelldev {
354 	volatile int		is_initialized;
355 	volatile int		in_reset;
356 	kmutex_t		genlock;
357 	mac_handle_t		mh;
358 	int			instance;
359 	dev_info_t		*dev_info;
360 	xge_hal_device_h	devh;
361 	caddr_t			ndp;
362 	timeout_id_t		timeout_id;
363 
364 	int			init_rx_rings;
365 	int			init_tx_rings;
366 	int			init_rx_groups;
367 
368 	int			live_rx_rings;
369 	int			live_tx_rings;
370 	xgell_rx_ring_t		rx_ring[XGELL_RX_RING_NUM_DEFAULT];
371 	xgell_tx_ring_t		tx_ring[XGELL_TX_RING_NUM_DEFAULT];
372 
373 	int			tx_copied_max;
374 
375 	xgell_intr_t		intrs[XGELL_MINTR_NUM_DEFAULT];
376 
377 	ddi_intr_handle_t	*intr_table;
378 	uint_t			intr_table_size;
379 	int			intr_type;
380 	int			intr_cnt;
381 	uint_t			intr_pri;
382 	int			intr_cap;
383 
384 	xgell_config_t		config;
385 };
386 
387 typedef struct {
388 	mblk_t			*mblk;
389 	ddi_dma_handle_t	dma_handles[XGE_HAL_DEFAULT_FIFO_FRAGS];
390 	int			handle_cnt;
391 } xgell_txd_priv_t;
392 
393 typedef struct {
394 	xgell_rx_buffer_t	*rx_buffer;
395 } xgell_rxd_priv_t;
396 
397 int xgell_device_alloc(xge_hal_device_h devh, dev_info_t *dev_info,
398     xgelldev_t **lldev_out);
399 
400 void xgell_device_free(xgelldev_t *lldev);
401 
402 int xgell_device_register(xgelldev_t *lldev, xgell_config_t *config);
403 
404 int xgell_device_unregister(xgelldev_t *lldev);
405 
406 void xgell_callback_link_up(void *userdata);
407 
408 void xgell_callback_link_down(void *userdata);
409 
410 int xgell_onerr_reset(xgelldev_t *lldev);
411 
412 void xge_device_poll_now(void *data);
413 
414 int xge_add_intrs(xgelldev_t *lldev);
415 
416 int xge_enable_intrs(xgelldev_t *lldev);
417 
418 void xge_disable_intrs(xgelldev_t *lldev);
419 
420 void xge_rem_intrs(xgelldev_t *lldev);
421 
422 int xgell_rx_ring_stat(mac_ring_driver_t rh, uint_t stat, uint64_t *val);
423 
424 int xgell_tx_ring_stat(mac_ring_driver_t rh, uint_t stat, uint64_t *val);
425 
426 #ifdef __cplusplus
427 }
428 #endif
429 
430 #endif /* _SYS_XGELL_H */
431