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 */
|